[monkey-bubble: 195/753] Removed; they are already in libcompat, but now all code which was still



commit 5d7a5385f0283329cdba332708701a800c4348ae
Author: Martin Baulig <baulig suse de>
Date:   Wed Apr 25 22:28:40 2001 +0000

    Removed; they are already in libcompat, but now all code which was still
    
    2001-04-26  Martin Baulig  <baulig suse de>
    
    	* gnome-app-util.[ch], gnome-dialog-util.[ch], gnome-dialog.[ch],
    	gnome-messagebox.[ch], gnome-propertybox.[ch], gnome-scores.[ch]:
    	Removed; they are already in libcompat, but now all code which was
    	still using them is fixed.

 .cvsignore                                      |   37 +
 ChangeLog                                       |   54 +
 Makefile.am                                     |    7 +
 acconfig.h                                      |    6 +
 autogen.sh                                      |   52 +
 configure.in                                    |   94 +
 demos/.cvsignore                                |   10 +
 demos/ChangeLog                                 |   20 +
 demos/Makefile.am                               |   41 +
 demos/animator_demo.c                           |   75 +
 demos/dock_demo.c                               |  194 +
 demos/mdi_demo.c                                |  215 +
 demos/stock_demo.c                              | 1179 +++
 demos/test-file-saver.c                         |   53 +
 demos/test-recently-used.c                      |  202 +
 demos/winhints_demo.c                           |  421 +
 doc/.cvsignore                                  |    2 +
 doc/ChangeLog                                   |    5 +
 doc/Makefile.am                                 |    1 +
 doc/Porting-1.0-2.0.txt                         |  276 +
 glade/glade-gnome.c                             | 2121 +++++
 images/.cvsignore                               |    3 +
 images/Makefile.am                              |   10 +
 images/gnome-default-dlg.png                    |  Bin 0 -> 2923 bytes
 images/gnome-error.png                          |  Bin 0 -> 2684 bytes
 images/gnome-info.png                           |  Bin 0 -> 3504 bytes
 images/gnome-question.png                       |  Bin 0 -> 1302 bytes
 images/gnome-warning.png                        |  Bin 0 -> 1968 bytes
 libgnomeui/.cvsignore                           |   38 +
 libgnomeui/AUTHORS                              |   24 +
 libgnomeui/ChangeLog                            | 3308 ++++++++
 libgnomeui/ChangeLog-19990928                   | 9823 +++++++++++++++++++++++
 libgnomeui/DEPENDS.libgnomeui                   |    6 +
 libgnomeui/Makefile.am                          |  262 +
 libgnomeui/TODO                                 |  103 +
 libgnomeui/gnome-about.c                        | 1229 +++
 libgnomeui/gnome-about.h                        |  125 +
 libgnomeui/gnome-animator.c                     | 1453 ++++
 libgnomeui/gnome-animator.h                     |  202 +
 libgnomeui/gnome-app-helper.c                   | 2672 ++++++
 libgnomeui/gnome-app-helper.h                   |  742 ++
 libgnomeui/gnome-app.c                          |  865 ++
 libgnomeui/gnome-app.h                          |  174 +
 libgnomeui/gnome-appbar.c                       |  759 ++
 libgnomeui/gnome-appbar.h                       |  138 +
 libgnomeui/gnome-boxed.defs                     |   12 +
 libgnomeui/gnome-canvas-init.c                  |  227 +
 libgnomeui/gnome-canvas-init.h                  |   38 +
 libgnomeui/gnome-client.c                       | 2694 +++++++
 libgnomeui/gnome-client.h                       |  453 ++
 libgnomeui/gnome-color-picker.c                 | 1115 +++
 libgnomeui/gnome-color-picker.h                 |  113 +
 libgnomeui/gnome-cursors.c                      |  971 +++
 libgnomeui/gnome-cursors.h                      |   89 +
 libgnomeui/gnome-dateedit.c                     |  929 +++
 libgnomeui/gnome-dateedit.h                     |   95 +
 libgnomeui/gnome-ditem-edit.c                   | 1485 ++++
 libgnomeui/gnome-ditem-edit.h                   |  139 +
 libgnomeui/gnome-dock-band.c                    | 1981 +++++
 libgnomeui/gnome-dock-band.h                    |  162 +
 libgnomeui/gnome-dock-item.c                    | 1420 ++++
 libgnomeui/gnome-dock-item.h                    |  165 +
 libgnomeui/gnome-dock-layout.c                  |  642 ++
 libgnomeui/gnome-dock-layout.h                  |  143 +
 libgnomeui/gnome-dock.c                         | 1616 ++++
 libgnomeui/gnome-dock.h                         |  140 +
 libgnomeui/gnome-druid-page-edge.c              |  737 ++
 libgnomeui/gnome-druid-page-edge.h              |  122 +
 libgnomeui/gnome-druid-page-standard.c          |  543 ++
 libgnomeui/gnome-druid-page-standard.h          |   96 +
 libgnomeui/gnome-druid-page.c                   |  381 +
 libgnomeui/gnome-druid-page.h                   |   85 +
 libgnomeui/gnome-druid.c                        |  899 +++
 libgnomeui/gnome-druid.h                        |   89 +
 libgnomeui/gnome-entry.c                        |  390 +
 libgnomeui/gnome-entry.h                        |   78 +
 libgnomeui/gnome-file-saver.c                   |  718 ++
 libgnomeui/gnome-file-saver.h                   |   75 +
 libgnomeui/gnome-file-selector-dialog.h         |  101 +
 libgnomeui/gnome-file-selector.c                | 1022 +++
 libgnomeui/gnome-file-selector.h                |   83 +
 libgnomeui/gnome-font-picker.c                  |  988 +++
 libgnomeui/gnome-font-picker.h                  |  119 +
 libgnomeui/gnome-gconf-ui.c                     |  577 ++
 libgnomeui/gnome-gconf-ui.h                     |   87 +
 libgnomeui/gnome-gconf.c                        |  577 ++
 libgnomeui/gnome-gconf.h                        |   87 +
 libgnomeui/gnome-helpsys.c                      | 1433 ++++
 libgnomeui/gnome-helpsys.h                      |  129 +
 libgnomeui/gnome-href.c                         |  508 ++
 libgnomeui/gnome-href.h                         |   84 +
 libgnomeui/gnome-ice.c                          |  144 +
 libgnomeui/gnome-ice.h                          |   44 +
 libgnomeui/gnome-icon-item.c                    | 1169 +++
 libgnomeui/gnome-icon-item.h                    |  130 +
 libgnomeui/gnome-icon-list.c                    | 2617 ++++++
 libgnomeui/gnome-icon-list.h                    |  179 +
 libgnomeui/gnome-icon-text.c                    |  311 +
 libgnomeui/gnome-icon-text.h                    |   61 +
 libgnomeui/gnome-less.c                         |  823 ++
 libgnomeui/gnome-less.h                         |  128 +
 libgnomeui/gnome-macros.h                       |   74 +
 libgnomeui/gnome-mdi-child.c                    |  378 +
 libgnomeui/gnome-mdi-child.h                    |  101 +
 libgnomeui/gnome-mdi-generic-child.c            |  487 ++
 libgnomeui/gnome-mdi-generic-child.h            |  111 +
 libgnomeui/gnome-mdi-session.c                  |  536 ++
 libgnomeui/gnome-mdi-session.h                  |   57 +
 libgnomeui/gnome-mdi.c                          | 2553 ++++++
 libgnomeui/gnome-mdi.h                          |  193 +
 libgnomeui/gnome-mdiP.h                         |  137 +
 libgnomeui/gnome-paper-selector.c               | 1058 +++
 libgnomeui/gnome-paper-selector.h               |  110 +
 libgnomeui/gnome-pixmap.c                       | 1443 ++++
 libgnomeui/gnome-pixmap.h                       |  145 +
 libgnomeui/gnome-popup-help.c                   |  510 ++
 libgnomeui/gnome-popup-help.h                   |   48 +
 libgnomeui/gnome-popup-menu.c                   |  525 ++
 libgnomeui/gnome-popup-menu.h                   |   65 +
 libgnomeui/gnome-pouch.c                        |  916 +++
 libgnomeui/gnome-pouch.h                        |   82 +
 libgnomeui/gnome-pouchP.h                       |   70 +
 libgnomeui/gnome-preferences.c                  |  938 +++
 libgnomeui/gnome-preferences.h                  |  147 +
 libgnomeui/gnome-recently-used.c                | 1124 +++
 libgnomeui/gnome-recently-used.h                |  112 +
 libgnomeui/gnome-remote-bootstrap.c             |  178 +
 libgnomeui/gnome-rexec-server.c                 |   89 +
 libgnomeui/gnome-rexec-server.oafinfo           |    5 +
 libgnomeui/gnome-roo.c                          | 1320 +++
 libgnomeui/gnome-roo.h                          |   79 +
 libgnomeui/gnome-scores.c                       |  587 --
 libgnomeui/gnome-scores.h                       |  178 -
 libgnomeui/gnome-selector.c                     | 2287 ++++++
 libgnomeui/gnome-selector.h                     |  358 +
 libgnomeui/gnome-selectorP.h                    |  100 +
 libgnomeui/gnome-stock-ids.c                    |  185 +
 libgnomeui/gnome-stock-ids.h                    |  378 +
 libgnomeui/gnome-stock.c                        | 1518 ++++
 libgnomeui/gnome-stock.h                        |  515 ++
 libgnomeui/gnome-textfu.c                       | 1394 ++++
 libgnomeui/gnome-textfu.h                       |  139 +
 libgnomeui/gnome-types.h                        |   53 +
 libgnomeui/gnome-ui-init.c                      |  569 ++
 libgnomeui/gnome-ui-init.h                      |   51 +
 libgnomeui/gnome-uidefs.h                       |  107 +
 libgnomeui/gnome-unit-spinner.c                 |  360 +
 libgnomeui/gnome-unit-spinner.h                 |   73 +
 libgnomeui/gnome-vfs-util.c                     |  290 +
 libgnomeui/gnome-vfs-util.h                     |   71 +
 libgnomeui/gnome-window.c                       |  164 +
 libgnomeui/gnome-window.h                       |   43 +
 libgnomeui/gnome-winhints.c                     |  749 ++
 libgnomeui/gnome-winhints.h                     |  196 +
 libgnomeui/gnome.defs                           |  289 +
 libgnomeui/gnome_segv.c                         |  199 +
 libgnomeui/gnometypebuiltins.h                  |   30 +
 libgnomeui/gnometypebuiltins_evals.c            |  249 +
 libgnomeui/gnometypebuiltins_ids.c              |   54 +
 libgnomeui/gnometypebuiltins_vars.c             |   28 +
 libgnomeui/gnometypes.c                         |   47 +
 libgnomeui/gtk-clock.c                          |  246 +
 libgnomeui/gtk-clock.h                          |   86 +
 libgnomeui/gtkdial.c                            |  904 +++
 libgnomeui/gtkdial.h                            |   93 +
 libgnomeui/gtkpixmapmenuitem.c                  |  350 +
 libgnomeui/gtkpixmapmenuitem.h                  |   85 +
 libgnomeui/gtkrc                                |   66 +
 libgnomeui/gtkrc.el                             |   72 +
 libgnomeui/gtkrc.eo                             |   72 +
 libgnomeui/gtkrc.he                             |   76 +
 libgnomeui/gtkrc.hy                             |   73 +
 libgnomeui/gtkrc.iso88592                       |   75 +
 libgnomeui/gtkrc.iso88595                       |   75 +
 libgnomeui/gtkrc.ja                             |   74 +
 libgnomeui/gtkrc.ka_GE.georgianacademy          |   78 +
 libgnomeui/gtkrc.ka_GE.georgianps               |   78 +
 libgnomeui/gtkrc.ko                             |   81 +
 libgnomeui/gtkrc.ru                             |   68 +
 libgnomeui/gtkrc.th                             |   79 +
 libgnomeui/gtkrc.tr                             |   72 +
 libgnomeui/gtkrc.uk                             |   75 +
 libgnomeui/gtkrc.vi_VN.tcvn                     |   76 +
 libgnomeui/gtkrc.vi_VN.viscii                   |   76 +
 libgnomeui/gtkrc.zh_CN                          |   72 +
 libgnomeui/gtkrc.zh_TW.Big5                     |   73 +
 libgnomeui/landscape.xpm                        |   36 +
 libgnomeui/libgnomeui-2.0.pc.in                 |   11 +
 libgnomeui/libgnomeui.h                         |   98 +
 libgnomeui/libgnomeui.schemas                   |   42 +
 libgnomeui/libgnomeuiP.h                        |   51 +
 libgnomeui/oafgnome.c                           |  521 ++
 libgnomeui/oafgnome.h                           |   35 +
 libgnomeui/pixmaps/.cvsignore                   |    5 +
 libgnomeui/pixmaps/Makefile.am                  |  106 +
 libgnomeui/pixmaps/calculator-font.png          |  Bin 0 -> 1449 bytes
 libgnomeui/pixmaps/copyright.txt                |   14 +
 libgnomeui/pixmaps/stock_add.png                |  Bin 0 -> 505 bytes
 libgnomeui/pixmaps/stock_align_center.png       |  Bin 0 -> 259 bytes
 libgnomeui/pixmaps/stock_align_justify.png      |  Bin 0 -> 283 bytes
 libgnomeui/pixmaps/stock_align_left.png         |  Bin 0 -> 260 bytes
 libgnomeui/pixmaps/stock_align_right.png        |  Bin 0 -> 260 bytes
 libgnomeui/pixmaps/stock_attach.png             |  Bin 0 -> 169 bytes
 libgnomeui/pixmaps/stock_book_blue.png          |  Bin 0 -> 572 bytes
 libgnomeui/pixmaps/stock_book_green.png         |  Bin 0 -> 562 bytes
 libgnomeui/pixmaps/stock_book_open.png          |  Bin 0 -> 589 bytes
 libgnomeui/pixmaps/stock_book_red.png           |  Bin 0 -> 567 bytes
 libgnomeui/pixmaps/stock_book_yellow.png        |  Bin 0 -> 571 bytes
 libgnomeui/pixmaps/stock_bottom.png             |  Bin 0 -> 540 bytes
 libgnomeui/pixmaps/stock_button_apply.png       |  Bin 0 -> 452 bytes
 libgnomeui/pixmaps/stock_button_cancel.png      |  Bin 0 -> 454 bytes
 libgnomeui/pixmaps/stock_button_close.png       |  Bin 0 -> 286 bytes
 libgnomeui/pixmaps/stock_button_no.png          |  Bin 0 -> 847 bytes
 libgnomeui/pixmaps/stock_button_ok.png          |  Bin 0 -> 661 bytes
 libgnomeui/pixmaps/stock_button_yes.png         |  Bin 0 -> 806 bytes
 libgnomeui/pixmaps/stock_cdrom.png              |  Bin 0 -> 806 bytes
 libgnomeui/pixmaps/stock_clear.png              |  Bin 0 -> 791 bytes
 libgnomeui/pixmaps/stock_close.png              |  Bin 0 -> 290 bytes
 libgnomeui/pixmaps/stock_colorselector.png      |  Bin 0 -> 592 bytes
 libgnomeui/pixmaps/stock_convert.png            |  Bin 0 -> 619 bytes
 libgnomeui/pixmaps/stock_copy.png               |  Bin 0 -> 603 bytes
 libgnomeui/pixmaps/stock_cut.png                |  Bin 0 -> 291 bytes
 libgnomeui/pixmaps/stock_down_arrow.png         |  Bin 0 -> 448 bytes
 libgnomeui/pixmaps/stock_exec.png               |  Bin 0 -> 672 bytes
 libgnomeui/pixmaps/stock_exit.png               |  Bin 0 -> 413 bytes
 libgnomeui/pixmaps/stock_first.png              |  Bin 0 -> 591 bytes
 libgnomeui/pixmaps/stock_font.png               |  Bin 0 -> 648 bytes
 libgnomeui/pixmaps/stock_help.png               |  Bin 0 -> 480 bytes
 libgnomeui/pixmaps/stock_home.png               |  Bin 0 -> 555 bytes
 libgnomeui/pixmaps/stock_index.png              |  Bin 0 -> 554 bytes
 libgnomeui/pixmaps/stock_jump_to.png            |  Bin 0 -> 611 bytes
 libgnomeui/pixmaps/stock_last.png               |  Bin 0 -> 576 bytes
 libgnomeui/pixmaps/stock_left_arrow.png         |  Bin 0 -> 566 bytes
 libgnomeui/pixmaps/stock_line_in.png            |  Bin 0 -> 403 bytes
 libgnomeui/pixmaps/stock_mail.png               |  Bin 0 -> 803 bytes
 libgnomeui/pixmaps/stock_mail_compose.png       |  Bin 0 -> 841 bytes
 libgnomeui/pixmaps/stock_mail_forward.png       |  Bin 0 -> 883 bytes
 libgnomeui/pixmaps/stock_mail_receive.png       |  Bin 0 -> 929 bytes
 libgnomeui/pixmaps/stock_mail_reply.png         |  Bin 0 -> 914 bytes
 libgnomeui/pixmaps/stock_mail_send.png          |  Bin 0 -> 948 bytes
 libgnomeui/pixmaps/stock_menu_about.png         |  Bin 0 -> 641 bytes
 libgnomeui/pixmaps/stock_menu_blank.png         |  Bin 0 -> 253 bytes
 libgnomeui/pixmaps/stock_mic.png                |  Bin 0 -> 391 bytes
 libgnomeui/pixmaps/stock_midi.png               |  Bin 0 -> 629 bytes
 libgnomeui/pixmaps/stock_multiple_file.png      |  Bin 0 -> 1843 bytes
 libgnomeui/pixmaps/stock_new.png                |  Bin 0 -> 771 bytes
 libgnomeui/pixmaps/stock_not.png                |  Bin 0 -> 331 bytes
 libgnomeui/pixmaps/stock_open.png               |  Bin 0 -> 393 bytes
 libgnomeui/pixmaps/stock_paste.png              |  Bin 0 -> 803 bytes
 libgnomeui/pixmaps/stock_preferences.png        |  Bin 0 -> 764 bytes
 libgnomeui/pixmaps/stock_print.png              |  Bin 0 -> 965 bytes
 libgnomeui/pixmaps/stock_properties.png         |  Bin 0 -> 932 bytes
 libgnomeui/pixmaps/stock_redo.png               |  Bin 0 -> 354 bytes
 libgnomeui/pixmaps/stock_refresh.png            |  Bin 0 -> 440 bytes
 libgnomeui/pixmaps/stock_remove.png             |  Bin 0 -> 531 bytes
 libgnomeui/pixmaps/stock_revert.png             |  Bin 0 -> 879 bytes
 libgnomeui/pixmaps/stock_right_arrow.png        |  Bin 0 -> 551 bytes
 libgnomeui/pixmaps/stock_save.png               |  Bin 0 -> 849 bytes
 libgnomeui/pixmaps/stock_save_as.png            |  Bin 0 -> 879 bytes
 libgnomeui/pixmaps/stock_scores.png             |  Bin 0 -> 311 bytes
 libgnomeui/pixmaps/stock_search.png             |  Bin 0 -> 945 bytes
 libgnomeui/pixmaps/stock_search_replace.png     |  Bin 0 -> 1004 bytes
 libgnomeui/pixmaps/stock_spellcheck.png         |  Bin 0 -> 403 bytes
 libgnomeui/pixmaps/stock_stop.png               |  Bin 0 -> 850 bytes
 libgnomeui/pixmaps/stock_table_borders.png      |  Bin 0 -> 135 bytes
 libgnomeui/pixmaps/stock_table_fill.png         |  Bin 0 -> 601 bytes
 libgnomeui/pixmaps/stock_text_bold.png          |  Bin 0 -> 278 bytes
 libgnomeui/pixmaps/stock_text_bulleted_list.png |  Bin 0 -> 142 bytes
 libgnomeui/pixmaps/stock_text_indent.png        |  Bin 0 -> 208 bytes
 libgnomeui/pixmaps/stock_text_italic.png        |  Bin 0 -> 277 bytes
 libgnomeui/pixmaps/stock_text_numbered_list.png |  Bin 0 -> 173 bytes
 libgnomeui/pixmaps/stock_text_strikeout.png     |  Bin 0 -> 289 bytes
 libgnomeui/pixmaps/stock_text_underline.png     |  Bin 0 -> 270 bytes
 libgnomeui/pixmaps/stock_text_unindent.png      |  Bin 0 -> 227 bytes
 libgnomeui/pixmaps/stock_timer.png              |  Bin 0 -> 893 bytes
 libgnomeui/pixmaps/stock_timer_stopped.png      |  Bin 0 -> 963 bytes
 libgnomeui/pixmaps/stock_top.png                |  Bin 0 -> 455 bytes
 libgnomeui/pixmaps/stock_trash.png              |  Bin 0 -> 704 bytes
 libgnomeui/pixmaps/stock_trash_full.png         |  Bin 0 -> 992 bytes
 libgnomeui/pixmaps/stock_undelete.png           |  Bin 0 -> 857 bytes
 libgnomeui/pixmaps/stock_undo.png               |  Bin 0 -> 351 bytes
 libgnomeui/pixmaps/stock_up_arrow.png           |  Bin 0 -> 384 bytes
 libgnomeui/pixmaps/stock_volume.png             |  Bin 0 -> 447 bytes
 libgnomeui/portrait.xpm                         |   46 +
 libgnomeui/wap-textfu.c                         | 3625 +++++++++
 libgnomeui/wap-textfu.h                         |  231 +
 message-of-doom                                 |   24 +
 po/.cvsignore                                   |   11 +
 po/ChangeLog                                    |    6 +
 po/POTFILES.in                                  |   38 +
 po/nn.po                                        | 1501 ++++
 po/no.po                                        | 1494 ++++
 292 files changed, 92401 insertions(+), 765 deletions(-)
---
diff --git a/.cvsignore b/.cvsignore
new file mode 100644
index 0000000..40fea57
--- /dev/null
+++ b/.cvsignore
@@ -0,0 +1,37 @@
+Makefile
+Makefile.in
+aclocal.m4
+confdefs.h
+config.cache
+config.guess
+config.h
+config.log
+config.status
+config.sub
+configure
+configure.scan
+libtool
+ltconfig
+ltmain.sh
+stamp-h
+stamp-h.in
+stamp.h
+version.h
+gnomeConf.sh
+config.h.in
+.exrc
+gnome-bug
+gnome-config
+install-sh
+missing
+mkinstalldirs
+INSTALL
+intl
+ABOUT-NLS
+COPYING
+gnome-libs.spec
+.lclintrc
+libvfs
+compatConf.sh
+libgnomeui-2-martin-*.tar.gz
+.using-gnome-libs-package
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..e69de29
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..537d016
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,54 @@
+2001-04-21  Kjartan Maraas  <kmaraas gnome org>
+
+	* configure.in: Added nn and no to ALL_LINGUAS.
+	
+2001-04-19  Michael Meeks  <michael ximian com>
+
+	* *.[ch]:
+
+	s/\#include[ \t]*<libgnomebase\/gnome-defs.h>//;
+	s/BEGIN_GNOME_DECLS/G_BEGIN_DECLS/g;
+	s/END_GNOME_DECLS/G_END_DECLS/g;
+	
+2001-04-19  Michael Meeks  <michael ximian com>
+
+	* configure.in: add GTK_VERSION.
+
+2001-04-11  Martin Baulig  <baulig suse de>
+
+	* docs/: New directory.
+
+2001-04-11  Martin Baulig  <baulig suse de>
+
+	* libgnomeui/: This has now been copied over in CVS. There's a
+	GNOME_LIBS_MODULE_SPLIT tag which refers to the latest version
+	in gnome-libs.
+
+	* images/: New directory. Copied here from gnome-libs. There's a
+	GNOME_LIBS_MODULE_SPLIT tag which refers to the latest version
+	in gnome-libs.
+
+2001-03-24  Martin Baulig  <baulig suse de>
+
+	* configure.in: Removed the REBUILD alias.
+
+	* configure.in (GNOME_MAKETYPES, GNOME_MAKEENUMS): Check
+	for the `gnome-maketypes.awk' and `gnome-makeenums.pl'
+	scripts which are installed by libgnome-2 and AC_SUBST them.
+
+	* demos/: New directory. This was copied here from
+	gnome-libs/demos with the full CVS history.
+
+	* Makefile.am (SUBDIRS): Added demos.
+
+2001-03-24  Martin Baulig  <baulig suse de>
+
+	* configure.in: Set package name to `libgnomeui-2'.
+
+2001-03-05  Martin Baulig  <baulig suse de>
+
+	* configure.in: Depend on libgnomecanvas and libxml.
+
+	* configure.in: Set package name to `libgnomeui-2-martin' and
+	version number to 1.96.0.
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..2ab2b42
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,7 @@
+SUBDIRS = libgnomeui images demos doc po intl
+
+gnomeincludedir=$(includedir)/gnome/$(GNOME_INTERFACE_VERSION)
+gnomeinclude_HEADERS = gnome.h
+
+EXTRA_DIST = message-of-doom
+
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..e69de29
diff --git a/README b/README
new file mode 100644
index 0000000..e69de29
diff --git a/acconfig.h b/acconfig.h
new file mode 100644
index 0000000..1f5dfd6
--- /dev/null
+++ b/acconfig.h
@@ -0,0 +1,6 @@
+#undef HAVE_LIBSM
+#undef ENABLE_NLS
+#undef HAVE_CATGETS
+#undef HAVE_GETTEXT
+#undef HAVE_LC_MESSAGES
+#undef HAVE_STPCPY
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..dbd9faf
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+# Run this to generate all the initial makefiles, etc.
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+if test -z "$CERTIFIED_GNOMIE"; then
+# If you can't figure out how to set this envar, please don't come on IRC
+# whining incessantly about how your apps are broken.
+  cat $srcdir/message-of-doom
+  exit 1
+fi
+
+PKG_NAME="libgnomeui"
+
+(test -f $srcdir/configure.in \
+  && test -f $srcdir/autogen.sh \
+  && test -d $srcdir/libgnomeui) || {
+    echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
+    echo " top-level $PKG_NAME directory"
+    exit 1
+}
+
+DIE=0
+
+rm -f .using-gnome-libs-package
+
+# This is a bit complicated here since we can't use gnome-config yet.
+# It'll be easier after switching to pkg-config since we can then
+# use pkg-config to find the gnome-autogen.sh script.
+
+gnome_autogen=
+gnome_datadir=
+
+ifs_save="$IFS"; IFS=":"
+for dir in $PATH ; do
+  test -z "$dir" && dir=.
+  if test -f $dir/gnome-autogen.sh ; then
+    gnome_autogen="$dir/gnome-autogen.sh"
+    gnome_datadir=`echo $dir | sed -e 's,/bin$,/share,'`
+    break
+  fi
+done
+IFS="$ifs_save"
+
+if test -z "$gnome_autogen" ; then
+  echo "You need to install the gnome-common module and make"
+  echo "sure the gnome-autogen.sh script is in your \$PATH."
+  exit 1
+fi
+
+GNOME_DATADIR="$gnome_datadir" USE_GNOME2_MACROS=1 . $gnome_autogen
diff --git a/configure.in b/configure.in
new file mode 100644
index 0000000..7d95dd2
--- /dev/null
+++ b/configure.in
@@ -0,0 +1,94 @@
+AC_INIT(libgnomeui)
+
+AM_CONFIG_HEADER(config.h)
+AM_INIT_AUTOMAKE(libgnomeui-2, 1.96.0)
+
+AM_MAINTAINER_MODE
+
+if test -z "$CERTIFIED_GNOMIE"; then
+  cat $srcdir/message-of-doom
+  exit 1
+fi
+
+GNOME_COMMON_INIT
+GNOME_PLATFORM_GNOME_2(yes, force)
+
+AC_ISC_POSIX
+AC_PROG_CC
+AC_STDC_HEADERS
+AC_ARG_PROGRAM
+AM_PROG_LIBTOOL
+AM_PROG_LEX
+AC_PROG_YACC
+AC_PATH_PROGS(PATH_TO_XRDB, "xrdb")
+
+GNOME_COMPILE_WARNINGS
+
+dnl utility conditional
+AM_CONDITIONAL(FALSE, test "x" = "y")
+
+ALL_LINGUAS="nn no"
+AM_GNOME2_GETTEXT
+
+AC_SUBST(CFLAGS)
+AC_SUBST(CPPFLAGS)
+AC_SUBST(LDFLAGS)
+
+GNOME_COMPILE_WARNINGS(maximum)
+
+AC_PATH_PROG(GNOME_MAKETYPES, gnome-maketypes.awk)
+AC_PATH_PROG(GNOME_MAKEENUMS, gnome-makeenums.pl)
+if test -z "$GNOME_MAKETYPES" || test -z "$GNOME_MAKEENUMS" ; then
+  AC_MSG_ERROR([
+*** Cannot find the gnome-maketypes.awk and gnome-makeenums.pl scripts
+*** which are installed from libgnome-2
+])
+fi
+
+dnl Utility conditional
+AM_CONDITIONAL(FALSE, test x = y)
+
+dnl
+dnl Start of pkg-config checks
+dnl
+GNOME_PKGCONFIG_CHECK_MODULES(LIBGNOMECANVAS, libgnomecanvas-2.0:1.96.0)
+AC_SUBST(LIBGNOMECANVAS_CFLAGS)
+AC_SUBST(LIBGNOMECANVAS_LIBS)
+
+dnl AC_SUBST GTK+ version
+GTK_VERSION=`$PKG_CONFIG --modversion gtk+`
+AC_SUBST(GTK_VERSION)
+
+dnl GNOME_PKGCONFIG_CHECK_MODULES(LIBBONOBO, libbonobo-2.0:1.96.0)
+dnl AC_SUBST(LIBBONOBO_CFLAGS)
+dnl AC_SUBST(LIBBONOBO_LIBS)
+
+AC_CHECK_LIB(popt, poptStrippedArgv,, AC_MSG_ERROR([popt 1.5 or newer is required to build
+gnome-libs. You can download the latest version from ftp://people.redhat.com/sopwith/popt/]))
+
+AC_CHECK_HEADERS(dlfcn.h dl.h utmp.h locale.h mcheck.h unistd.h)
+
+dnl This is installed from GTK+ 2.0's gdk-pixbuf
+AC_PATH_PROG(MAKE_INLINE_PIXBUF, make-inline-pixbuf)
+test -z "$MAKE_INLINE_PIXBUF" && AC_MSG_ERROR([
+*** You need the make-inline-pixbuf tool which is installed
+*** from GTK+ 2.0's gdk-pixbuf.
+***
+*** Either the location where you installed your GTK+ 2.0 is
+*** not in your PATH or something is screwed up with your
+*** GTK+ 2.0 installation
+])
+
+AC_OUTPUT([
+Makefile
+po/Makefile.in
+intl/Makefile
+libgnomeui/Makefile
+libgnomeui/libgnomeui-2.0.pc
+libgnomeui/pixmaps/Makefile
+images/Makefile
+demos/Makefile
+doc/Makefile
+])
+
+cat $srcdir/message-of-doom
\ No newline at end of file
diff --git a/demos/.cvsignore b/demos/.cvsignore
new file mode 100644
index 0000000..29bdeeb
--- /dev/null
+++ b/demos/.cvsignore
@@ -0,0 +1,10 @@
+Makefile.in
+Makefile
+.deps
+.libs
+selector_demo
+stock_demo
+winhints_demo
+dock_demo
+animator_demo
+mdi_demo
diff --git a/demos/ChangeLog b/demos/ChangeLog
new file mode 100644
index 0000000..e492d6c
--- /dev/null
+++ b/demos/ChangeLog
@@ -0,0 +1,20 @@
+2001-02-26  Martin Baulig  <baulig suse de>
+
+	* selector_demo.c: Added example for the new pixmap selector mode
+	of the GnomeIconEntry.
+
+2001-02-26  Martin Baulig  <baulig suse de>
+
+	* stock_demo.c: There is no gnome_stock_new_with_icon_at_size()
+	any more.
+
+	* stock_demo.c: Tagged as `before-martin-reverted-it'.
+
+2000-12-08  Martin Baulig  <baulig suse de>
+
+	* animator_demo.c, dock_demo.c, mdi_demo.c, stock_demo.c,
+	selector_demo.c, winhints_demo.c: Moved here from libgnomeui.
+
+	* test-file-saver.c, test-recently-used.c: Moved here from
+	libgnomeui.
+
diff --git a/demos/Makefile.am b/demos/Makefile.am
new file mode 100644
index 0000000..143e4ca
--- /dev/null
+++ b/demos/Makefile.am
@@ -0,0 +1,41 @@
+INCLUDES = \
+	-I$(top_builddir)				\
+	-I$(top_srcdir)					\
+	-I$(top_srcdir)/intl				\
+	-I$(top_builddir)/intl				\
+	-I$(top_srcdir)/libgnomeui			\
+	$(WARN_CFLAGS)					\
+	$(LIBGNOMECANVAS_CFLAGS)			\
+        -DGNOMEUILIBDIR=\""$(libdir)"\" 		\
+        -DGNOMEUIDATADIR=\""$(datadir)"\" 		\
+        -DGNOMEUIPIXMAPDIR=\""$(datadir)/pixmaps"\"	\
+        -DGNOMEUIBINDIR=\""$(bindir)"\" 		\
+        -DGNOMEUILOCALSTATEDIR=\""$(localstatedir)"\" 	\
+        -DGNOMEUILOCALEDIR=\""$(gnomelocaledir)"\" 	\
+	-DG_LOG_DOMAIN=\"GnomeUI\"			\
+	-DVERSION=\"$(VERSION)\"
+
+LDADD =	\
+	$(top_builddir)/libgnomeui/libgnomeui-2.la \
+	$(INTLLIBS)
+
+noinst_PROGRAMS = \
+	selector_demo		\
+	stock_demo		\
+	winhints_demo		\
+	dock_demo 		\
+	animator_demo		\
+	mdi_demo
+
+selector_demo_SOURCES = selector_demo.c
+
+stock_demo_SOURCES = stock_demo.c
+
+winhints_demo_SOURCES = winhints_demo.c
+
+animator_demo_SOURCES = animator_demo.c
+
+dock_demo_SOURCES = dock_demo.c
+
+mdi_demo_SOURCES = mdi_demo.c
+
diff --git a/demos/animator_demo.c b/demos/animator_demo.c
new file mode 100644
index 0000000..d6013a7
--- /dev/null
+++ b/demos/animator_demo.c
@@ -0,0 +1,75 @@
+#include <config.h>
+#include <gnome.h>
+
+#define ANIMFILE "mailcheck/email.png"
+/* #define ANIMFILE "gnome-ppp-animation-large.png" */
+
+static void quit_cb (GtkWidget * widget, void *data);
+static void toggle_start_stop_cb (GtkWidget * widget, void *data);
+
+static void
+quit_cb (GtkWidget * widget, void *data)
+{
+  gtk_main_quit ();
+}
+
+static void
+toggle_start_stop_cb (GtkWidget * widget, gpointer data)
+{
+  GtkWidget *tmp;
+  GnomeAnimatorStatus status;
+
+  tmp = (GtkWidget *) data;
+
+  status = gnome_animator_get_status (GNOME_ANIMATOR (tmp));
+  if (status == GNOME_ANIMATOR_STATUS_STOPPED)
+    gnome_animator_start (GNOME_ANIMATOR (tmp));
+  else
+    gnome_animator_stop (GNOME_ANIMATOR (tmp));
+}
+
+int
+main (int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *button;
+  GtkWidget *animator;
+  GdkPixbuf *pixbuf;
+  char *s;
+
+  gnome_program_init ("gnome-animator", VERSION, &libgnomeui_module_info,
+		      argc, argv, NULL);
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_widget_realize (window);
+  gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+		      GTK_SIGNAL_FUNC (quit_cb), NULL);
+
+  s = gnome_program_locate_file (gnome_program_get (),
+				 GNOME_FILE_DOMAIN_PIXMAP,
+				 ANIMFILE, TRUE, NULL);
+  pixbuf = gdk_pixbuf_new_from_file (s, NULL);
+  g_free (s);
+  animator = gnome_animator_new_with_size (48, 48);
+  gnome_animator_append_frames_from_pixbuf (GNOME_ANIMATOR (animator),
+					    pixbuf, 0, 0, 150, 48);
+  gdk_pixbuf_unref (pixbuf);
+/*  gnome_animator_set_range (GNOME_ANIMATOR (animator), 1, 21); */
+  gnome_animator_set_loop_type (GNOME_ANIMATOR (animator),
+				GNOME_ANIMATOR_LOOP_RESTART);
+  gnome_animator_set_playback_speed (GNOME_ANIMATOR (animator), 5.0);
+
+  button = gtk_button_new ();
+  gtk_container_add (GTK_CONTAINER (button), animator);
+  gtk_signal_connect (GTK_OBJECT (button), "clicked",
+		      GTK_SIGNAL_FUNC (toggle_start_stop_cb), animator);
+
+  gtk_container_add (GTK_CONTAINER (window), button);
+  gtk_widget_show_all (window);
+
+  gnome_animator_start (GNOME_ANIMATOR (animator));
+
+  gtk_main ();
+
+  return 0;
+}
diff --git a/demos/dock_demo.c b/demos/dock_demo.c
new file mode 100644
index 0000000..e9fd754
--- /dev/null
+++ b/demos/dock_demo.c
@@ -0,0 +1,194 @@
+#include <gnome.h>
+
+#include "gnome-dock.h"
+
+static GtkWidget *app;
+static GtkWidget *dock;
+static GtkWidget *dock_items[6];
+static GtkWidget *toolbars[6];
+static GtkWidget *drawing_area;
+static GtkWidget *client_frame;
+
+static GnomeUIInfo toolbar_infos[6][10] = {
+  { { GNOME_APP_UI_ITEM, "New", "Create a new file", NULL, NULL, NULL,
+      GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_NEW, 0, 0, NULL },
+    { GNOME_APP_UI_ITEM, "Open", "Open an existing file", NULL, NULL, NULL,
+      GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_OPEN, 0, 0, NULL },
+    { GNOME_APP_UI_ITEM, "Save", "Save the current file", NULL, NULL, NULL,
+      GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_SAVE, 0, 0, NULL },
+    { GNOME_APP_UI_ITEM, "Save as", "Save the current file with a new name", NULL, NULL, NULL,
+      GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_SAVE_AS, 0, 0, NULL },
+    GNOMEUIINFO_END },
+
+  { { GNOME_APP_UI_ITEM, "Close", "Close the current file", NULL, NULL, NULL,
+      GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_CLOSE, 0, 0, NULL },
+    { GNOME_APP_UI_ITEM, "Exit", "Exit the program", NULL, NULL, NULL,
+      GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_EXIT, 0, 0, NULL },
+    GNOMEUIINFO_END },
+
+  { { GNOME_APP_UI_ITEM, "Undo", "Undo the last operation", NULL, NULL, NULL,
+      GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_UNDO, 0, 0, NULL },
+    { GNOME_APP_UI_ITEM, "_Redo", "Redo the last undo-ed operation", NULL, NULL, NULL,
+      GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_REDO, 0, 0, NULL },
+    GNOMEUIINFO_END },
+
+  { { GNOME_APP_UI_ITEM, "Cut", "Cut the selection to the clipboard", NULL, NULL, NULL,
+      GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_CUT, 0, 0, NULL },
+    { GNOME_APP_UI_ITEM, "Copy", "Copy the selection to the clipboard", NULL, NULL, NULL,
+      GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_COPY, 0, 0, NULL },
+    { GNOME_APP_UI_ITEM, "Paste", "Paste the contents of the clipboard", NULL, NULL, NULL,
+      GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_PASTE, 0, 0, NULL },
+    GNOMEUIINFO_END },
+
+  { { GNOME_APP_UI_ITEM, "First", "Go to the first item", NULL, NULL, NULL,
+      GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_FIRST, 0, 0, NULL },
+    { GNOME_APP_UI_ITEM, "Last", "Go to the last item", NULL, NULL, NULL,
+      GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_LAST, 0, 0, NULL },
+    GNOMEUIINFO_END },
+  { { GNOME_APP_UI_ITEM, "First", "Go to the first item", NULL, NULL, NULL,
+      GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_FIRST, 0, 0, NULL },
+    { GNOME_APP_UI_ITEM, "Last", "Go to the last item", NULL, NULL, NULL,
+      GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_LAST, 0, 0, NULL },
+    GNOMEUIINFO_END }
+
+};
+
+static void delete_callback (GtkWidget *w)
+{
+  gchar *layout_string;
+  GnomeDockLayout *layout;
+
+  layout = gnome_dock_get_layout (GNOME_DOCK (dock));
+  layout_string = gnome_dock_layout_create_string (layout);
+  gnome_config_set_string ("Dock/Placement", layout_string);
+  gnome_config_sync ();
+
+  gtk_object_unref (GTK_OBJECT (layout));
+
+  gtk_main_quit ();
+}
+
+static void layout_changed_callback (GtkWidget *w)
+{
+  puts ("Layout changed");
+}
+
+static void
+do_ui_signal_connect (GnomeUIInfo *uiinfo, const char *signal_name, GnomeUIBuilderData *uibdata)
+{
+}
+
+int
+main (int argc, char **argv)
+{
+  GnomeUIBuilderData uibdata;
+  GnomeDockLayout *layout;
+  int i;
+
+  /* I am having troubles with CVS gnome-libs today, so let's do
+     things by hand.  */
+
+  gnome_program_init ("dock_demo", "1.0", &libgnomeui_module_info,
+		      argc, argv, NULL);
+
+  app = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title (GTK_WINDOW (app), "Test!");
+  gtk_window_set_default_size (GTK_WINDOW (app), 400, 400);
+
+  dock = gnome_dock_new ();
+  gtk_container_add (GTK_CONTAINER (app), dock);
+
+  uibdata.connect_func = do_ui_signal_connect;
+  uibdata.data = NULL;
+  uibdata.is_interp = FALSE;
+  uibdata.relay_func = NULL;
+  uibdata.destroy_func = NULL;
+
+  gnome_config_push_prefix ("/DockTest/");
+
+  layout = gnome_dock_layout_new ();
+
+  for (i = 0; i < 6; i++)
+    {
+      toolbars[i] = gtk_toolbar_new (GTK_ORIENTATION_HORIZONTAL,
+                                     GTK_TOOLBAR_ICONS);
+      gtk_container_set_border_width (GTK_CONTAINER (toolbars[i]), 1);
+
+      gnome_app_fill_toolbar_custom (GTK_TOOLBAR (toolbars[i]),
+                                     toolbar_infos[i],
+                                     &uibdata,
+                                     NULL);
+
+      if (i == 0)
+        dock_items[i] = gnome_dock_item_new ("SomeBar",
+                                             GNOME_DOCK_ITEM_BEH_EXCLUSIVE
+                                             | GNOME_DOCK_ITEM_BEH_NEVER_VERTICAL);
+      else if (i == 1)
+        dock_items[i] = gnome_dock_item_new ("LockedBar",
+                                             GNOME_DOCK_ITEM_BEH_LOCKED);
+      else
+        {
+          gchar *name;
+
+          name = g_strdup_printf ("AnotherBar%d", i);
+          dock_items[i] = gnome_dock_item_new (name,
+                                               GNOME_DOCK_ITEM_BEH_NORMAL);
+        }
+
+      gtk_container_set_border_width (GTK_CONTAINER (dock_items[i]), 1);
+      gtk_container_add (GTK_CONTAINER (dock_items[i]), toolbars[i]);
+
+      if (i < 3)
+        gnome_dock_layout_add_item (layout,
+                                    GNOME_DOCK_ITEM (dock_items[i]),
+                                    GNOME_DOCK_TOP,
+                                    i, 0, 0);
+      else
+        gnome_dock_layout_add_item (layout,
+                                    GNOME_DOCK_ITEM (dock_items[i]),
+                                    GNOME_DOCK_BOTTOM,
+                                    i - 4, 0, 0);
+
+      gtk_widget_show (toolbars[i]);
+      gtk_widget_show (dock_items[i]);
+    }
+
+  {
+    gchar *layout_string;
+
+    layout_string = gnome_config_get_string ("Dock/Placement");
+    gnome_dock_layout_parse_string (GNOME_DOCK_LAYOUT (layout),
+                                    layout_string);
+    g_free (layout_string);
+  }
+
+  gnome_dock_layout_add_to_dock (GNOME_DOCK_LAYOUT (layout),
+                                 GNOME_DOCK (dock));
+
+  gtk_object_unref (GTK_OBJECT(layout));
+
+  client_frame = gtk_frame_new (NULL);
+  gtk_frame_set_shadow_type(GTK_FRAME (client_frame), GTK_SHADOW_IN);
+  drawing_area = gtk_drawing_area_new();
+
+  gtk_signal_connect (GTK_OBJECT (app),
+                      "delete_event",
+                      GTK_SIGNAL_FUNC (delete_callback),
+                      NULL);
+
+  gtk_signal_connect (GTK_OBJECT (dock),
+                      "layout_changed",
+                      GTK_SIGNAL_FUNC (layout_changed_callback),
+                      NULL);
+
+  gnome_dock_set_client_area (GNOME_DOCK (dock), client_frame);
+  gtk_widget_show (client_frame);
+  gtk_widget_show (drawing_area);
+  gtk_widget_show (dock);
+
+  gtk_widget_show (app);
+  gtk_main ();
+
+  return 0;
+}
+
diff --git a/demos/mdi_demo.c b/demos/mdi_demo.c
new file mode 100644
index 0000000..20fcac3
--- /dev/null
+++ b/demos/mdi_demo.c
@@ -0,0 +1,215 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+#include <gnome.h>
+
+static GnomeMDI *mdi;
+static gint child_counter = 1;
+
+#define COUNTER_KEY "counter"
+
+static void
+exit_cb(GtkWidget *w, gpointer user_data)
+{
+	gtk_main_quit();
+}
+
+static void
+mode_cb(GtkWidget *w, gpointer user_data)
+{
+	gpointer real_user_data;
+	GnomeMDIMode mode;
+
+	real_user_data = gtk_object_get_data(GTK_OBJECT(w), GNOMEUIINFO_KEY_UIDATA);
+	mode = GPOINTER_TO_INT(real_user_data);
+	gnome_mdi_set_mode(mdi, mode);
+}
+
+static GtkWidget *
+view_creator(GnomeMDIChild *child, gpointer user_data)
+{
+	GtkWidget *label;
+
+	label = gtk_label_new(gnome_mdi_child_get_name(child));
+	
+	return label;
+}
+
+static gchar *
+child_config(GnomeMDIChild *child, gpointer user_data)
+{
+	gchar *conf;
+	guint *counter;
+
+	counter = gtk_object_get_data(GTK_OBJECT(child), COUNTER_KEY);
+	if(counter)
+		conf = g_strdup_printf("%d", *counter);
+	else
+		conf = NULL;
+
+	return conf;
+}
+
+static void
+add_view_cb(GtkWidget *w, gpointer user_data)
+{
+	GtkWidget *view;
+
+	view = gnome_mdi_get_active_view(mdi);
+	if(!view)
+		return;
+	gnome_mdi_add_view(mdi, gnome_mdi_get_child_from_view(view));
+}
+
+static void
+remove_view_cb(GtkWidget *w, gpointer user_data)
+{
+	GtkWidget *view;
+
+	view = gnome_mdi_get_active_view(mdi);
+	if(!view)
+		return;
+	gnome_mdi_remove_view(mdi, view);
+}
+
+static void
+increase_cb(GtkWidget *w, gpointer user_data)
+{
+	GtkWidget *view;
+	GnomeMDIChild *child;
+	const GList *view_node;
+	gint *counter;
+	gchar *name;
+
+	view = gnome_mdi_get_active_view(mdi);
+	if(!view)
+		return;
+	child = gnome_mdi_get_child_from_view(view);
+	counter = gtk_object_get_data(GTK_OBJECT(child), COUNTER_KEY);
+	(*counter) = child_counter++;
+	name = g_strdup_printf("Child #%d", *counter);
+	gnome_mdi_child_set_name(child, name);
+	g_free(name);
+	view_node = gnome_mdi_child_get_views(child);
+	while(view_node) {
+		view = view_node->data;
+		gtk_label_set(GTK_LABEL(view), gnome_mdi_child_get_name(child));
+		view_node = view_node->next;
+	}
+}
+
+GnomeUIInfo real_child_menu[] =
+{
+	GNOMEUIINFO_ITEM("Add view", NULL, add_view_cb, NULL),
+	GNOMEUIINFO_ITEM("Remove view", NULL, remove_view_cb, NULL),
+	GNOMEUIINFO_SEPARATOR,
+	GNOMEUIINFO_ITEM("Increase counter", NULL, increase_cb, NULL),
+	GNOMEUIINFO_END
+};
+
+static GnomeUIInfo child_menu[] =
+{
+	GNOMEUIINFO_SUBTREE("Child", real_child_menu),
+	GNOMEUIINFO_END
+};
+
+static GnomeUIInfo child_toolbar[] =
+{
+	GNOMEUIINFO_ITEM_NONE(N_("Child Item 1"),
+						  N_("Hint for item 1"),
+						  NULL),
+	GNOMEUIINFO_ITEM_NONE(N_("Child Item 2"),
+						  N_("Hint for item 2"),
+						  NULL),
+	GNOMEUIINFO_END
+};
+
+static void
+add_child_cb(GtkWidget *w, gpointer user_data)
+{
+	GnomeMDIGenericChild *child;
+	gchar *name;
+	gint *counter;
+
+	name = g_strdup_printf("Child #%d", child_counter);
+	child = gnome_mdi_generic_child_new(name);
+	gnome_mdi_generic_child_set_view_creator(child, view_creator, NULL);
+	gnome_mdi_generic_child_set_config_func(child, child_config, NULL);
+	gnome_mdi_child_set_menu_template(GNOME_MDI_CHILD(child), child_menu);
+	gnome_mdi_child_set_toolbar_template(GNOME_MDI_CHILD(child), child_toolbar);
+	gnome_mdi_child_set_toolbar_position(GNOME_MDI_CHILD(child), GNOME_DOCK_ITEM_BEH_NORMAL,
+										 GNOME_DOCK_TOP, 1, 1, 0);
+	counter = g_malloc(sizeof(gint));
+	*counter = child_counter++;
+	gtk_object_set_data(GTK_OBJECT(child), COUNTER_KEY, counter);
+	g_free(name);
+	gnome_mdi_add_child(mdi, GNOME_MDI_CHILD(child));
+	gnome_mdi_add_view(mdi, GNOME_MDI_CHILD(child));
+}
+
+static void
+remove_child_cb(GtkWidget *w, gpointer user_data)
+{
+	GtkWidget *view;
+
+	view = gnome_mdi_get_active_view(mdi);
+	if(!view)
+		return;
+	gnome_mdi_remove_child(mdi, gnome_mdi_get_child_from_view(view));
+}
+
+GnomeUIInfo empty_menu[] =
+{
+	GNOMEUIINFO_END
+};
+
+GnomeUIInfo mode_list [] = 
+{
+	GNOMEUIINFO_RADIOITEM_DATA("Toplevel", NULL, mode_cb, GINT_TO_POINTER(GNOME_MDI_TOPLEVEL), NULL),
+	GNOMEUIINFO_RADIOITEM_DATA("Notebook", NULL, mode_cb, GINT_TO_POINTER(GNOME_MDI_NOTEBOOK), NULL),
+	GNOMEUIINFO_RADIOITEM_DATA("Window-in-Window", NULL, mode_cb, GINT_TO_POINTER(GNOME_MDI_WIW), NULL),
+	GNOMEUIINFO_RADIOITEM_DATA("Modal", NULL, mode_cb, GINT_TO_POINTER(GNOME_MDI_MODAL), NULL),
+	GNOMEUIINFO_END
+};
+
+GnomeUIInfo mode_menu[] =
+{
+	GNOMEUIINFO_RADIOLIST(mode_list),
+	GNOMEUIINFO_END
+};
+
+GnomeUIInfo mdi_menu[] =
+{
+	GNOMEUIINFO_ITEM("Add child", NULL, add_child_cb, NULL),
+	GNOMEUIINFO_ITEM("Remove child", NULL, remove_child_cb, NULL),
+	GNOMEUIINFO_SEPARATOR,
+	GNOMEUIINFO_SUBTREE("Mode", mode_menu),
+	GNOMEUIINFO_SEPARATOR,
+	GNOMEUIINFO_MENU_EXIT_ITEM(exit_cb, NULL),
+	GNOMEUIINFO_END
+};
+
+GnomeUIInfo main_menu[] =
+{
+	GNOMEUIINFO_SUBTREE("MDI", mdi_menu),
+	GNOMEUIINFO_SUBTREE("Children", empty_menu),
+	GNOMEUIINFO_END
+};
+
+int
+main(int argc, char **argv)
+{
+  gnome_program_init ("mdi_demo", "2.0", &libgnomeui_module_info,
+					  argc, argv, NULL);
+
+  mdi = gnome_mdi_new("MDIDemo", "MDI Demo");
+  gnome_mdi_set_mode(mdi, GNOME_MDI_TOPLEVEL);
+  gnome_mdi_set_menubar_template(mdi, main_menu);
+  gnome_mdi_set_child_menu_path(mdi, "MDI");
+  gnome_mdi_set_child_list_path(mdi, "Children/");
+  gtk_signal_connect(GTK_OBJECT(mdi), "destroy",
+					 GTK_SIGNAL_FUNC(exit_cb), NULL);
+  gnome_mdi_open_toplevel(mdi);
+
+  gtk_main ();
+
+  return 0;
+}
diff --git a/demos/stock_demo.c b/demos/stock_demo.c
new file mode 100644
index 0000000..ae7561c
--- /dev/null
+++ b/demos/stock_demo.c
@@ -0,0 +1,1179 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#include <config.h>
+#include <gnome.h>
+#include <string.h>
+
+
+/*
+ * message box demo
+ */
+
+static void
+message_dlg_clicked(GtkWidget *widget, int button,gpointer data)
+{
+	if (button == 0) /* Yes */
+		gtk_main_quit();
+	else /* No */
+		gnome_dialog_close(GNOME_DIALOG(widget));
+}
+
+static gboolean
+message_dlg(GtkWidget *widget, gpointer data)
+{
+	static GtkWidget *box = NULL;
+
+	if (box == NULL) {
+	  box = gnome_message_box_new ("Really quit?",
+				       GNOME_MESSAGE_BOX_QUESTION,
+				       GNOME_STOCK_BUTTON_YES,
+				       GNOME_STOCK_BUTTON_NO,
+				       NULL);
+	  gtk_signal_connect (GTK_OBJECT (box), "clicked",
+			      GTK_SIGNAL_FUNC (message_dlg_clicked), NULL);
+
+	  gtk_window_set_modal (GTK_WINDOW(box),TRUE);
+	  gnome_dialog_close_hides(GNOME_DIALOG(box), TRUE);
+	}
+	gtk_widget_show (box);
+	return TRUE;
+}
+
+
+
+/*
+ * property box demo
+ */
+
+static void
+prop_apply(GtkWidget *box, int n)
+{
+	char s[256];
+
+	if (n != -1) {
+		g_snprintf(s, sizeof(s), "Applied changed on page #%d", n + 1);
+		gtk_widget_show(gnome_message_box_new(s, "info",
+				GNOME_STOCK_BUTTON_OK, NULL));
+	}
+}
+
+
+static void
+prop_dlg(GtkWidget *widget, gpointer data)
+{
+	GnomePropertyBox *box;
+	GtkWidget *w, *label;
+
+	box = GNOME_PROPERTY_BOX(gnome_property_box_new());
+	w = gtk_button_new_with_label("Click me (Page #1)");
+	gtk_signal_connect_object(GTK_OBJECT(w), "clicked",
+				  GTK_SIGNAL_FUNC(gnome_property_box_changed),
+				  GTK_OBJECT(box));
+	gtk_widget_show(w);
+	label = gtk_label_new("Page #1");
+	gtk_widget_show(label);
+	gnome_property_box_append_page(box, w, label);
+	w = gtk_button_new_with_label("Click me (Page #2)");
+	gtk_widget_show(w);
+	gtk_signal_connect_object(GTK_OBJECT(w), "clicked",
+				  GTK_SIGNAL_FUNC(gnome_property_box_changed),
+				  GTK_OBJECT(box));
+	label = gtk_label_new("Page #2");
+	gtk_widget_show(label);
+	gnome_property_box_append_page(box, w, label);
+	gtk_signal_connect(GTK_OBJECT(box), "apply",
+			   (GtkSignalFunc)prop_apply, NULL);
+	gtk_widget_show(GTK_WIDGET(box));
+}
+
+
+
+/*
+ * main window
+ */
+
+static GtkWidget *menu_items[20], *frame;
+
+extern void gnome_stock_menu_accel_dlg(char *);
+
+static GtkWidget *
+create_menu(GtkWidget *window)
+{
+	GtkWidget *menubar, *w, *menu;
+	GtkAccelGroup *accel;
+	int i = 0;
+	guchar key;
+	guint8 mod;
+
+	accel = gtk_accel_group_new();
+	menubar = gtk_menu_bar_new();
+	gtk_widget_show(menubar);
+
+	menu = gtk_menu_new();
+
+	w = gnome_stock_menu_item(GNOME_STOCK_MENU_NEW, _("New..."));
+	gtk_widget_show(w);
+	if (gnome_stock_menu_accel(GNOME_STOCK_MENU_NEW, &key, &mod))
+		gtk_widget_add_accelerator(w, "activate",  accel, key, mod, 0);
+
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), w);
+	menu_items[i++] = w;
+
+	w = gnome_stock_menu_item(GNOME_STOCK_MENU_OPEN, _("Open..."));
+	gtk_widget_show(w);
+	if (gnome_stock_menu_accel(GNOME_STOCK_MENU_OPEN, &key, &mod))
+		gtk_widget_add_accelerator(w, "activate",  accel, key, mod, 0);
+
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), w);
+	menu_items[i++] = w;
+
+	w = gnome_stock_menu_item(GNOME_STOCK_MENU_SAVE, _("Save"));
+	gtk_widget_show(w);
+	if (gnome_stock_menu_accel(GNOME_STOCK_MENU_SAVE, &key, &mod))
+		gtk_widget_add_accelerator(w, "activate",  accel, key, mod, 0);
+
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), w);
+	menu_items[i++] = w;
+
+	w = gnome_stock_menu_item(GNOME_STOCK_MENU_SAVE_AS, _("Save as..."));
+	gtk_widget_show(w);
+	if (gnome_stock_menu_accel(GNOME_STOCK_MENU_SAVE_AS, &key, &mod))
+		gtk_widget_add_accelerator(w, "activate",  accel, key, mod, 0);
+
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), w);
+	menu_items[i++] = w;
+
+	w = gnome_stock_menu_item(GNOME_STOCK_MENU_CLOSE, _("Close"));
+	gtk_widget_show(w);
+	if (gnome_stock_menu_accel(GNOME_STOCK_MENU_CLOSE, &key, &mod))
+		gtk_widget_add_accelerator(w, "activate",  accel, key, mod, 0);
+
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), w);
+	menu_items[i++] = w;
+
+	w = gtk_menu_item_new();
+	gtk_widget_show(w);
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), w);
+
+	w = gnome_stock_menu_item(GNOME_STOCK_MENU_PRINT, _("Print..."));
+	gtk_widget_show(w);
+	if (gnome_stock_menu_accel(GNOME_STOCK_MENU_PRINT, &key, &mod))
+		gtk_widget_add_accelerator(w, "activate",  accel, key, mod, 0);
+
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), w);
+	menu_items[i++] = w;
+
+	w = gnome_stock_menu_item(GNOME_STOCK_MENU_BLANK, _("Setup Page..."));
+	gtk_widget_show(w);
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), w);
+	menu_items[i++] = w;
+
+	w = gtk_menu_item_new();
+	gtk_widget_show(w);
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), w);
+
+	w = gnome_stock_menu_item(GNOME_STOCK_MENU_QUIT, _("Quit"));
+	gtk_widget_show(w);
+	if (gnome_stock_menu_accel(GNOME_STOCK_MENU_QUIT, &key, &mod))
+		gtk_widget_add_accelerator(w, "activate",  accel, key, mod, 0);
+
+	gtk_signal_connect_object(GTK_OBJECT(w), "activate",
+				  (GtkSignalFunc)message_dlg,
+				  GTK_OBJECT(window));
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), w);
+	menu_items[i++] = w;
+
+	w = gtk_menu_item_new_with_label(_("File"));
+	gtk_widget_show(w);
+	gtk_menu_item_set_submenu(GTK_MENU_ITEM(w), menu);
+	gtk_menu_bar_append(GTK_MENU_BAR(menubar), w);
+	
+	menu = gtk_menu_new();
+
+	w = gnome_stock_menu_item(GNOME_STOCK_MENU_UNDO, _("Undo"));
+	gtk_widget_show(w);
+	if (gnome_stock_menu_accel(GNOME_STOCK_MENU_UNDO, &key, &mod))
+		gtk_widget_add_accelerator(w, "activate",  accel, key, mod, 0);
+
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), w);
+	menu_items[i++] = w;
+
+	w = gnome_stock_menu_item(GNOME_STOCK_MENU_REDO, _("Redo"));
+	gtk_widget_show(w);
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), w);
+	menu_items[i++] = w;
+
+	w = gtk_menu_item_new();
+	gtk_widget_show(w);
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), w);
+
+	w = gnome_stock_menu_item(GNOME_STOCK_MENU_BLANK, _("Delete"));
+	gtk_widget_show(w);
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), w);
+	menu_items[i++] = w;
+
+	w = gnome_stock_menu_item(GNOME_STOCK_MENU_CUT, _("Cut"));
+	gtk_widget_show(w);
+	if (gnome_stock_menu_accel(GNOME_STOCK_MENU_CUT, &key, &mod))
+		gtk_widget_add_accelerator(w, "activate",  accel, key, mod, 0);
+
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), w);
+	menu_items[i++] = w;
+
+	w = gnome_stock_menu_item(GNOME_STOCK_MENU_COPY, _("Copy"));
+	gtk_widget_show(w);
+	if (gnome_stock_menu_accel(GNOME_STOCK_MENU_COPY, &key, &mod))
+		gtk_widget_add_accelerator(w, "activate",  accel, key, mod, 0);
+
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), w);
+	menu_items[i++] = w;
+
+	w = gnome_stock_menu_item(GNOME_STOCK_MENU_PASTE, _("Paste"));
+	gtk_widget_show(w);
+	if (gnome_stock_menu_accel(GNOME_STOCK_MENU_PASTE, &key, &mod))
+		gtk_widget_add_accelerator(w, "activate",  accel, key, mod, 0);
+
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), w);
+	menu_items[i++] = w;
+
+	w = gtk_menu_item_new();
+	gtk_widget_show(w);
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), w);
+
+	w = gnome_stock_menu_item(GNOME_STOCK_MENU_PROP, _("Properties..."));
+	gtk_widget_show(w);
+	if (gnome_stock_menu_accel(GNOME_STOCK_MENU_PROP, &key, &mod))
+		gtk_widget_add_accelerator(w, "activate",  accel, key, mod, 0);
+
+	gtk_signal_connect(GTK_OBJECT(w), "activate",
+			   GTK_SIGNAL_FUNC(prop_dlg), NULL);
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), w);
+	menu_items[i++] = w;
+
+	w = gnome_stock_menu_item(GNOME_STOCK_MENU_PREF, _("Preferences..."));
+	gtk_widget_show(w);
+	if (gnome_stock_menu_accel(GNOME_STOCK_MENU_PREF, &key, &mod))
+		gtk_widget_add_accelerator(w, "activate",  accel, key, mod, 0);
+
+	gtk_signal_connect_object(GTK_OBJECT(w), "activate",
+				  GTK_SIGNAL_FUNC(gnome_stock_menu_accel_dlg),
+				  NULL);
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), w);
+	menu_items[i++] = w;
+
+	w = gtk_menu_item_new();
+	gtk_widget_show(w);
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), w);
+
+	w = gnome_stock_menu_item(GNOME_STOCK_MENU_SCORES, _("Scores..."));
+	gtk_widget_show(w);
+	if (gnome_stock_menu_accel(GNOME_STOCK_MENU_SCORES, &key, &mod))
+		gtk_widget_add_accelerator(w, "activate",  accel, key, mod, 0);
+
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), w);
+	menu_items[i++] = w;
+
+	w = gtk_menu_item_new_with_label(_("Edit"));
+	gtk_widget_show(w);
+	gtk_menu_item_set_submenu(GTK_MENU_ITEM(w), menu);
+	gtk_menu_item_right_justify(GTK_MENU_ITEM(w));
+	gtk_menu_bar_append(GTK_MENU_BAR(menubar), w);
+
+	menu = gtk_menu_new();
+
+	w = gnome_stock_menu_item(GNOME_STOCK_MENU_ABOUT, _("About"));
+	gtk_widget_show(w);
+	if (gnome_stock_menu_accel(GNOME_STOCK_MENU_ABOUT, &key, &mod))
+		gtk_widget_add_accelerator(w, "activate",  accel, key, mod, 0);
+
+	gtk_menu_shell_append(GTK_MENU_SHELL(menu), w);
+	menu_items[i++] = w;
+
+	w = gtk_menu_item_new_with_label(_("Help"));
+	gtk_widget_show(w);
+	gtk_menu_item_set_submenu(GTK_MENU_ITEM(w), menu);
+/*  	gtk_menu_item_right_justify(GTK_MENU_ITEM(w)); */
+	gtk_menu_bar_append(GTK_MENU_BAR(menubar), w);
+
+	menu_items[i] = NULL;
+	/* g_print("%d menu items\n", i); */
+	gtk_window_add_accel_group(GTK_WINDOW(window), accel);
+
+	return menubar;
+}
+
+
+
+typedef struct _TbItems TbItems;
+struct _TbItems {
+	const char *icon;
+	GtkWidget *widget; /* will be filled in */
+};
+
+static TbItems tb_items[] = {
+	{GNOME_STOCK_PIXMAP_NEW, NULL},
+	{GNOME_STOCK_PIXMAP_SAVE, NULL},
+	{GNOME_STOCK_PIXMAP_SAVE_AS, NULL},
+	{GNOME_STOCK_PIXMAP_OPEN, NULL},
+	{GNOME_STOCK_PIXMAP_CUT, NULL},
+	{GNOME_STOCK_PIXMAP_COPY, NULL},
+	{GNOME_STOCK_PIXMAP_PASTE, NULL},
+#define TB_PROP 7
+	{GNOME_STOCK_PIXMAP_PROPERTIES, NULL},
+	{NULL, NULL}
+};
+
+static GtkWidget *
+create_toolbar(GtkWidget *window)
+{
+	GtkWidget *toolbar;
+	TbItems *t;
+
+	toolbar = gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL,
+				  GTK_TOOLBAR_BOTH);
+
+	for (t = &tb_items[0]; t->icon; t++) {
+		t->widget = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
+						    t->icon,
+						    NULL,
+						    NULL,
+						    gnome_stock_new_with_icon(t->icon),
+						    NULL, NULL);
+	}
+	gtk_signal_connect(GTK_OBJECT(tb_items[TB_PROP].widget), "clicked",
+				      (GtkSignalFunc)prop_dlg, NULL);
+
+	return toolbar;
+}
+
+
+
+static void
+tb_sens(GtkWidget *w, gpointer *data)
+{
+	TbItems *t;
+	GtkWidget **m;
+
+	gtk_widget_set_sensitive(frame, TRUE);
+	for (t = tb_items; t->icon; t++) {
+		gtk_widget_set_sensitive(t->widget, TRUE);
+	}
+	for (m = menu_items; *m; m++) {
+		gtk_widget_set_sensitive(*m, TRUE);
+	}
+}
+
+
+
+static void
+tb_insens(GtkWidget *w, gpointer *data)
+{
+	TbItems *t;
+	GtkWidget **m;
+
+	gtk_widget_set_sensitive(frame, FALSE);
+	for (t = tb_items; t->icon; t++) {
+		gtk_widget_set_sensitive(t->widget, FALSE);
+	}
+	for (m = menu_items; *m; m++) {
+		gtk_widget_set_sensitive(*m, FALSE);
+	}
+}
+
+
+
+#if USE_NEW_GNOME_STOCK
+static void
+toggle_button(GtkWidget *button, GnomeStock *w)
+{
+	if (!w) return;
+	if (!w->icon) return;
+	if (0 == strcmp(w->icon, GNOME_STOCK_PIXMAP_TIMER))
+		gnome_stock_set_icon(w, GNOME_STOCK_PIXMAP_TIMER_STOP);
+	else
+		gnome_stock_set_icon(w, GNOME_STOCK_PIXMAP_TIMER);
+}
+#else /* °USE_NEW_GNOME_STOCK */
+static void
+toggle_button(GtkWidget *button, GnomeStock *w)
+{
+	if (!w) return;
+	if (!w->icon) return;
+	if (0 == strcmp(w->icon, GNOME_STOCK_PIXMAP_TIMER))
+		gnome_stock_set_icon(w, GNOME_STOCK_PIXMAP_TIMER_STOP);
+	else
+		gnome_stock_set_icon(w, GNOME_STOCK_PIXMAP_TIMER);
+}
+#endif /* !USE_NEW_GNOME_STOCK */
+
+
+
+#undef USE_BUTTON
+
+
+static void
+fill_table(GtkWidget *window, GtkTable *table)
+{
+	GtkWidget *w, *button;
+	gint row, column;
+
+	row = column = 0;
+
+	w = GTK_WIDGET(gnome_stock_new_with_icon(GNOME_STOCK_PIXMAP_HELP));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = gtk_label_new("Help");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_SEARCH));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_SEARCH));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Search");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_SRCHRPL));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_SRCHRPL));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Search/Replace");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_CLOSE));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = gtk_label_new("Close");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_PRINT));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = gtk_label_new("Print");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_PREFERENCES));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = gtk_label_new("Preferences");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_UNDO));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = gtk_label_new("Undo");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_REDO));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = gtk_label_new("Redo");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_REVERT));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_REVERT));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Revert");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_SPELLCHECK));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_SPELLCHECK));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Spellchecker");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column = 0; row += 3;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_BACK));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_BACK));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Backward");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_FORWARD));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_FORWARD));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Forward");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_FIRST));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_FIRST));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("First");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_LAST));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_LAST));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Last");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_UP));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_UP));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Up");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_DOWN));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_DOWN));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Down");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_TOP));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_TOP));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Top");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_BOTTOM));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_BOTTOM));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Bottom");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_EXEC));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_EXEC));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Exec");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	row += 3;
+	column = 0;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_ALIGN_LEFT));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_ALIGN_LEFT));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Left");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_ALIGN_RIGHT));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_ALIGN_RIGHT));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Right");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_ALIGN_CENTER));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_ALIGN_CENTER));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Center");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_ALIGN_JUSTIFY));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_ALIGN_JUSTIFY));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Justify");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	row += 3;
+	column = 0;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_HOME));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_HOME));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Home");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_STOP));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_STOP));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Stop");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_REFRESH));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_REFRESH));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Refresh");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_INDEX));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_INDEX));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Index");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_MIC));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_MIC));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Microphone");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_VOLUME));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_VOLUME));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Volume");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_LINE_IN));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_LINE_IN));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Line In");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+        column++;
+        w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_CDROM));
+        gtk_widget_show(w);
+        gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+        w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_CDROM));
+        gtk_widget_show(w);
+        gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+        w = gtk_label_new("CD Rom");
+        gtk_widget_show(w);
+        gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_FONT));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_FONT));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Font");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column = 0; row += 3;
+	button = gtk_button_new();
+	gtk_widget_show(button);
+	w = gnome_stock_new_with_icon(GNOME_STOCK_PIXMAP_TIMER_STOP);
+	gtk_widget_show(w);
+	gtk_container_add(GTK_CONTAINER(button), w);
+	gtk_table_attach_defaults(table, button, column, column + 1, row, row + 1);
+	gtk_signal_connect(GTK_OBJECT(button), "clicked",
+			   GTK_SIGNAL_FUNC(toggle_button), w);
+
+	button = gtk_toggle_button_new();
+	gtk_widget_show(button);
+	w = gnome_stock_new_with_icon(GNOME_STOCK_PIXMAP_TIMER);
+	gtk_widget_show(w);
+	gtk_container_add(GTK_CONTAINER(button), w);
+	gtk_table_attach_defaults(table, button, column, column + 1, row + 1, row + 3);
+	gtk_signal_connect(GTK_OBJECT(button), "clicked",
+			   GTK_SIGNAL_FUNC(toggle_button), w);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_MAIL));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_MAIL));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Mail");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_MAIL_NEW));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_MAIL_NEW));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("New Mail");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_MAIL_SND));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_MAIL_SND));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Send Mail");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_MAIL_RCV));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_MAIL_RCV));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Receive Mail");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_MAIL_RPL));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_MAIL_RPL));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Reply to Mail");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_MAIL_FWD));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_MAIL_FWD));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Forward Mail");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_ATTACH));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_ATTACH));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Attach");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_CONVERT));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_CONVERT));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Convert");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_JUMP_TO));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_JUMP_TO));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Jump To");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column = 0; row += 3;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_BOOK_RED));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_BOOK_RED));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Book Red");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_BOOK_GREEN));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_BOOK_GREEN));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Book Green");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_BOOK_BLUE));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_BOOK_BLUE));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Book Blue");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_BOOK_YELLOW));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_BOOK_YELLOW));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Book Yellow");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_BOOK_OPEN));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_BOOK_OPEN));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Book Open");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_TRASH));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_TRASH));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Trash");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_UNDELETE));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_UNDELETE));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Undelete");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_PIXMAP_TRASH_FULL));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon( GNOME_STOCK_MENU_TRASH_FULL));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+	w = gtk_label_new("Trash Full");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 2, row + 3);
+
+#undef COMPARE_TO_IMLIB
+#undef TRY_ENLARGE
+
+#define FILENAME "gnome-audio2.png"
+#ifndef COMPARE_TO_IMLIB
+	column++;
+#else
+	row += 3;
+	column = 0;
+#endif
+	w = GTK_WIDGET(gnome_stock_new_with_icon( FILENAME));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 2);
+	w = gtk_label_new(FILENAME);
+	gtk_widget_show(w);
+#ifdef TRY_ENLARGE
+	gtk_table_attach_defaults(table, w, column, column + 3, row + 2, row + 3);
+#else
+	gtk_table_attach_defaults(table, w, column, column + 2, row + 2, row + 3);
+#endif
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon(FILENAME));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_stock_new_with_icon(FILENAME));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+#ifdef TRY_ENLARGE
+	/* XXX. yikes, that might crash */
+	column++;
+	w = GTK_WIDGET(gnome_stock_new_with_icon(FILENAME));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 2);
+#endif
+#ifdef COMPARE_TO_IMLIB
+#define FILENAME2 (gnome_pixmap_file(FILENAME))
+	column++;
+	w = GTK_WIDGET(gnome_pixmap_new_from_file(FILENAME2));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 2);
+	w = gtk_label_new(FILENAME " via Imlib");
+	gtk_widget_show(w);
+#ifdef TRY_ENLARGE
+	gtk_table_attach_defaults(table, w, column, column + 3, row + 2, row + 3);
+#else
+	gtk_table_attach_defaults(table, w, column, column + 2, row + 2, row + 3);
+#endif
+	column++;
+	w = GTK_WIDGET(gnome_pixmap_new_from_file_at_size(FILENAME2, 24, 24));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = GTK_WIDGET(gnome_pixmap_new_from_file_at_size(FILENAME2, 16, 16));
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+#ifdef TRY_ENLARGE
+	column++;
+	w = gnome_pixmap_new_from_file_at_size(FILENAME2, 64, 64);
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 2);
+#endif
+#undef FILENAME2
+#endif /* COMPARE_TO_IMLIB */
+#undef FILENAME
+
+#ifdef USE_BUTTON
+	column++;
+	w = gnome_pixmap_new_from_file(gnome_pixmap_file("gnome-unknown.png"));
+	w = gnome_pixmap_button(w, "Test");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row, row + 1);
+	w = gnome_pixmap_new_from_file(gnome_pixmap_file("gnome-unknown.png"));
+	w = gnome_pixmap_button(w, "Test #2");
+	gtk_widget_set_sensitive(w, FALSE);
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, column, column + 1, row + 1, row + 2);
+#endif /* USE_BUTTON */
+
+	gtk_table_set_col_spacings(table, 10);
+	gtk_table_set_row_spacing(table, 2, 10);
+	gtk_table_set_row_spacing(table, 5, 10);
+	gtk_table_set_row_spacing(table, 8, 10);
+}
+
+
+
+int
+main(int argc, char **argv)
+{
+	GtkWidget *window, *hbox, *vbox, *table, *w;
+
+	gnome_program_init("stock_demo", VERSION, &libgnomeui_module_info,
+			   argc, argv, NULL);
+
+	textdomain(PACKAGE);
+
+	window = gnome_app_new("Gnome Stock Test", "Gnome Stock Test");
+	gtk_window_set_wmclass(GTK_WINDOW(window), "stock_test",
+			       "GnomeStockTest");
+
+	gtk_signal_connect(GTK_OBJECT(window), "delete_event",
+			   GTK_SIGNAL_FUNC(message_dlg), NULL);
+	gtk_signal_connect(GTK_OBJECT(window), "destroy",
+			   GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
+	
+	vbox = gtk_vbox_new(FALSE, 0);
+	gtk_widget_show(vbox);
+	w = gtk_label_new("Click on `Cancel' to disable the toolbar and menu items\n"
+			  "Click on `OK' to enable the toolbar and menu items\n"
+			  "Select Edit->Properties or the Properties toolbar button\n"
+			  "to open a GnomePropertyBox\n"
+			  "Select Edit->Preferences to open the Menu Accelerator Configuration Dialog\n"
+			  "Select File->Quit or the Close button to get an example message box and the\n"
+			  "opportunity to exit this app");
+	gtk_widget_show(w);
+	gtk_box_pack_start(GTK_BOX(vbox), w, TRUE, TRUE, 2);
+
+	frame = gtk_frame_new("Other Icons");
+	gtk_widget_show(frame);
+	gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 2);
+	table = gtk_table_new(1, 1, FALSE);
+	gtk_widget_show(table);
+	gtk_container_add(GTK_CONTAINER(frame), table);
+	fill_table(window, GTK_TABLE(table));
+
+	hbox = gtk_hbutton_box_new();
+	gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);
+	gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
+	gtk_widget_show(hbox);
+	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
+
+	w = gnome_stock_button(GNOME_STOCK_BUTTON_YES);
+	gtk_widget_show(w);
+	gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 3);
+
+	w = gnome_stock_button(GNOME_STOCK_BUTTON_NO);
+	gtk_widget_show(w);
+	gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 3);
+
+	w = gnome_stock_button(GNOME_STOCK_BUTTON_PREV);
+	gtk_widget_show(w);
+	gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 3);
+
+	w = gnome_stock_button(GNOME_STOCK_BUTTON_NEXT);
+	gtk_widget_show(w);
+	gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 3);
+
+	w = gnome_stock_button(GNOME_STOCK_BUTTON_FONT);
+	gtk_widget_show(w);
+	gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 3);
+
+	hbox = gtk_hbutton_box_new();
+	gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);
+	gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
+	gtk_widget_show(hbox);
+	gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
+
+	w = gnome_stock_button(GNOME_STOCK_BUTTON_OK);
+	gtk_widget_show(w);
+	gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 3);
+	gtk_signal_connect(GTK_OBJECT(w), "clicked",
+			   (GtkSignalFunc)tb_sens, NULL);
+
+	w = gnome_stock_button(GNOME_STOCK_BUTTON_APPLY);
+	gtk_widget_show(w);
+	gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 3);
+	gtk_widget_set_sensitive(w, FALSE);
+
+	w = gnome_stock_button(GNOME_STOCK_BUTTON_CANCEL);
+	gtk_widget_show(w);
+	gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 3);
+	gtk_signal_connect(GTK_OBJECT(w), "clicked",
+			   (GtkSignalFunc)tb_insens, NULL);
+
+	w = gnome_stock_button(GNOME_STOCK_BUTTON_HELP);
+	gtk_widget_show(w);
+	gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 3);
+
+	w = gnome_stock_button(GNOME_STOCK_BUTTON_CLOSE);
+	gtk_widget_show(w);
+	gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 3);
+	gtk_signal_connect_object(GTK_OBJECT(w), "clicked",
+				  (GtkSignalFunc)message_dlg,
+				  NULL);
+
+	gnome_app_set_contents(GNOME_APP(window), vbox);
+	gnome_app_set_menus(GNOME_APP(window),
+			    GTK_MENU_BAR(create_menu(window)));
+	gnome_app_set_toolbar(GNOME_APP(window),
+			      GTK_TOOLBAR(create_toolbar(window)));
+	gtk_widget_show(window);
+	gtk_main();
+	return 0;
+}
+
diff --git a/demos/test-file-saver.c b/demos/test-file-saver.c
new file mode 100644
index 0000000..976da5a
--- /dev/null
+++ b/demos/test-file-saver.c
@@ -0,0 +1,53 @@
+/*  -*- Mode: C; c-set-style: linux; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* GNOME GUI Library - test-file-saver.c
+ * Copyright (C) 2000  Red Hat Inc.,
+ * All rights reserved.
+ *
+ * Author: Havoc Pennington <hp redhat com>
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+#include "gnome-file-saver.h"
+#include "libgnomeui.h"
+
+int
+main(int argc, char** argv)
+{
+        GtkWidget *fs;
+  
+        gnome_program_init("test-file-saver", "0.1",
+                           argc, argv, GNOMEUI_INIT, GNOME_GCONF_INIT,
+                           NULL);
+
+        fs = gnome_file_saver_new("Save a File", "document-saver");
+
+        gnome_file_saver_add_mime_type(GNOME_FILE_SAVER(fs),
+                                       "text/plain");
+
+        gnome_file_saver_add_mime_type(GNOME_FILE_SAVER(fs),
+                                       "text/html");
+
+        gnome_file_saver_add_mime_type(GNOME_FILE_SAVER(fs),
+                                       "image/gif");
+        
+        gtk_widget_show(fs);
+        
+        gtk_main();
+
+        return 0;
+}
diff --git a/demos/test-recently-used.c b/demos/test-recently-used.c
new file mode 100644
index 0000000..389889f
--- /dev/null
+++ b/demos/test-recently-used.c
@@ -0,0 +1,202 @@
+/*  -*- Mode: C; c-set-style: linux; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* GNOME GUI Library - test-recently-used.c
+ * Copyright (C) 2000  Red Hat Inc.,
+ * All rights reserved.
+ *
+ * Author: Havoc Pennington <hp redhat com>
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+#include "gnome-recently-used.h"
+#include <gnome.h>
+
+static GnomeRecentlyUsed *ru = NULL;
+static GHashTable* doc_to_menuitem = NULL;
+
+static void
+add_clicked(GtkWidget* button, GtkWidget *entry)
+{
+        gchar* text;
+
+        text = gtk_editable_get_chars(GTK_EDITABLE (entry), 0, -1);
+
+        gnome_recently_used_add_simple(ru,
+                                       "echo 'hello'",
+                                       text,
+                                       NULL, NULL, NULL, NULL);
+        g_free(text);
+}
+
+static void
+add_to_menu(GtkWidget* menu, GnomeRecentDocument *doc)
+{
+        GtkWidget *mi;
+        const gchar* name;
+        GtkWidget *label;
+        
+        name = gnome_recent_document_peek(doc, "menu-text");
+
+        label = gtk_label_new(name);
+        mi = gtk_menu_item_new();
+
+        gtk_container_add(GTK_CONTAINER(mi), label);
+        
+        /* ref for the menu item */
+        gnome_recent_document_ref(doc);
+        gtk_object_set_data_full(GTK_OBJECT(mi), "doc", 
+                                 doc,
+                                 (GtkDestroyNotify)gnome_recent_document_unref);
+
+        gtk_object_set_data(GTK_OBJECT(mi), "label", label);
+        
+        gtk_widget_show_all(mi);
+
+        g_hash_table_insert(doc_to_menuitem, doc, mi);
+        
+        /* FIXME actually we'd want to sort by time... */
+        gtk_menu_shell_append(GTK_MENU_SHELL (menu), mi);
+}
+
+static void
+item_removed(GnomeRecentlyUsed* recently_used, GnomeRecentDocument* doc, gpointer user_data)
+{
+        /*UNUSED GtkWidget *menu = user_data; */
+        GtkWidget *mi;
+
+        mi = g_hash_table_lookup(doc_to_menuitem, doc);
+
+        /* removed before we even heard about it */
+        if (mi == NULL)
+                return;
+        else {
+                g_hash_table_remove(doc_to_menuitem, doc);
+                gtk_widget_destroy(mi);
+        }
+}
+
+static void
+item_added(GnomeRecentlyUsed* recently_used, GnomeRecentDocument* doc, gpointer user_data)
+{
+        GtkWidget *menu = user_data;
+
+        add_to_menu(menu, doc);
+}
+
+static void
+item_changed(GnomeRecentlyUsed* recently_used, GnomeRecentDocument* doc, gpointer user_data)
+{
+        /*UNUSED GtkWidget *menu = user_data; */
+        const gchar* name;
+        GtkWidget *mi;
+        
+        name = gnome_recent_document_peek(doc, "menu-text");
+
+        mi = g_hash_table_lookup(doc_to_menuitem, doc);
+
+        if (mi == NULL)
+                return; /* changed before we heard about it */
+        
+        gtk_label_set_text(gtk_object_get_data(GTK_OBJECT(mi), "label"),
+                           name);
+}
+
+int
+main(int argc, char** argv)
+{
+        GtkWidget *window;
+        GtkWidget *menu;
+        GtkWidget *vbox;
+        GtkWidget *entry;
+        GtkWidget *button;
+        GtkWidget *option;
+        GSList *list;
+        GSList *iter;
+        
+        gnome_program_init("test-recently-used", "0.1",
+                           argc, argv, GNOMEUI_INIT, GNOME_GCONF_INIT,
+                           NULL);
+
+        doc_to_menuitem = g_hash_table_new(NULL, NULL);
+        
+        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+        vbox = gtk_vbox_new(FALSE, 6);
+
+        gtk_container_add(GTK_CONTAINER(window), vbox);
+        
+        entry = gtk_entry_new();
+
+        gtk_box_pack_start(GTK_BOX(vbox), entry,
+                           FALSE, FALSE, 0);
+
+        button = gtk_button_new_with_label("Add");
+
+        gtk_signal_connect(GTK_OBJECT(button), "clicked",
+                           GTK_SIGNAL_FUNC(add_clicked),
+                           entry);
+        
+        gtk_box_pack_start(GTK_BOX(vbox), button,
+                           FALSE, FALSE, 0);
+
+        option = gtk_option_menu_new();
+
+        gtk_box_pack_start(GTK_BOX(vbox), option,
+                           FALSE, FALSE, 0);
+        
+        menu = gtk_menu_new();
+
+        ru = gnome_recently_used_new();
+
+        gtk_signal_connect(GTK_OBJECT(ru),
+                           "document_added",
+                           GTK_SIGNAL_FUNC(item_added),
+                           menu);
+
+        gtk_signal_connect(GTK_OBJECT(ru),
+                           "document_removed",
+                           GTK_SIGNAL_FUNC(item_removed),
+                           menu);
+
+        gtk_signal_connect(GTK_OBJECT(ru),
+                           "document_changed",
+                           GTK_SIGNAL_FUNC(item_changed),
+                           menu);
+
+        
+        list = gnome_recently_used_get_all(ru);
+
+        iter = list;
+
+        while (iter != NULL) {
+                GnomeRecentDocument *doc = iter->data;
+
+                add_to_menu(menu, doc);
+
+                iter = g_slist_next(iter);
+        }
+        
+        g_slist_free(list);
+        
+        gtk_option_menu_set_menu(GTK_OPTION_MENU(option), menu);
+
+        gtk_widget_show_all(window);
+        
+        gtk_main();
+
+        return 0;
+}
diff --git a/demos/winhints_demo.c b/demos/winhints_demo.c
new file mode 100644
index 0000000..d55a595
--- /dev/null
+++ b/demos/winhints_demo.c
@@ -0,0 +1,421 @@
+#include <config.h>
+#include <gnome.h>
+#include <gdk/gdkx.h>
+#include "gnome-winhints.h"
+
+
+void layers_cb (GtkWidget *widget, void *data);
+void about_cb (GtkWidget *widget, void *data);
+void state_cb (GtkWidget *widget, void *data);
+void skip_cb (GtkWidget *widget, void *data);
+void protocols_cb (GtkWidget *widget, void *data);
+void workspace_cb (GtkWidget *widget, void *data);
+void quit_cb (GtkWidget *widget, void *data);
+static GList* get_workspaces(void);
+static void prepare_app(void);
+
+GtkWidget *app;
+GtkWidget *lbox, *wsbox;
+GtkWidget *allwsbut;
+GList *ws_list;
+GtkWidget *minbut, *maxvbut, *maxhbut, *hidbut, *rollbut, *dockbut;
+GtkWidget *sfocbut, *smenubut, *sbarbut, *fixedbut, *ignorebut;
+
+int main(int argc, char *argv[])
+{
+  gnome_program_init ("winhints-test", VERSION, &libgnomeui_module_info,
+		      argc, argv, NULL);
+  
+  prepare_app ();
+  
+  gtk_main ();
+  
+  return 0;
+}
+
+static void prepare_app(void)
+{
+  GtkWidget *vb,*vb1, *hb, *hb1, *mvb;
+  GtkWidget *sw;
+  GtkWidget *frame;
+  GtkWidget *item;
+  GtkWidget *button;
+  GtkWidget *apic, *label;
+  GList *tmp_list;
+  
+  
+  app = gnome_app_new (_("wmhints-test"), _("winhints-test"));
+  gtk_widget_realize (app);
+  gtk_signal_connect (GTK_OBJECT (app), "delete_event",
+                      GTK_SIGNAL_FUNC (quit_cb),
+                      NULL);
+  
+  /* this must be called after the app widget is realized */
+
+  gnome_win_hints_init();
+  if (!gnome_win_hints_wm_exists())
+    fprintf(stderr, "Your WM does not support GNOME extended hints\n");
+  
+  mvb=gtk_vbox_new(FALSE, 0);
+  gnome_app_set_contents ( GNOME_APP (app), mvb);
+  gtk_widget_show (mvb);
+  gtk_widget_realize(app);
+
+  hb=gtk_hbox_new(TRUE, 0);
+  gtk_box_pack_start(GTK_BOX(mvb), hb, FALSE, FALSE, 0);
+  gtk_widget_show (hb);
+
+  vb =gtk_vbox_new(FALSE,0);
+  gtk_box_pack_start(GTK_BOX(hb), vb, FALSE, FALSE, 0);
+  gtk_widget_show(vb);
+
+  frame=gtk_frame_new(_("Layer:"));
+  gtk_box_pack_start(GTK_BOX(vb), frame, FALSE, FALSE, 0);
+  gtk_container_set_border_width(GTK_CONTAINER(frame), 5);
+  gtk_widget_show(frame);
+
+  vb1 =gtk_vbox_new(FALSE,0);
+  gtk_container_add(GTK_CONTAINER(frame), vb1);
+  gtk_container_set_border_width(GTK_CONTAINER(vb1), 5);
+  gtk_widget_show(vb1);
+
+  sw = gtk_scrolled_window_new(NULL, NULL);
+  gtk_widget_set_usize(sw, 100, 100);
+  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC,
+                                 GTK_POLICY_AUTOMATIC);
+  gtk_box_pack_start(GTK_BOX(vb1), sw, FALSE, FALSE, 0);
+  gtk_widget_show(sw);
+
+  lbox = gtk_list_new();
+  gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw), lbox);
+  gtk_widget_show(lbox);
+
+  tmp_list=NULL;
+  
+  item = gtk_list_item_new_with_label( _("Above Dock"));
+  tmp_list=g_list_prepend(tmp_list, item);
+  gtk_object_set_data(GTK_OBJECT(item), "layer", "10");
+  gtk_widget_show(item);
+  item = gtk_list_item_new_with_label( _("Dock"));
+  tmp_list=g_list_prepend(tmp_list, item);
+  gtk_object_set_data(GTK_OBJECT(item), "layer", "8");
+  gtk_widget_show(item);
+  item = gtk_list_item_new_with_label( _("On Top"));
+  tmp_list=g_list_prepend(tmp_list, item);
+  gtk_object_set_data(GTK_OBJECT(item), "layer", "6");
+  gtk_widget_show(item);
+  item = gtk_list_item_new_with_label( _("Normal"));
+  tmp_list=g_list_prepend(tmp_list, item);
+  gtk_object_set_data(GTK_OBJECT(item), "layer", "4");
+  gtk_widget_show(item);
+  item = gtk_list_item_new_with_label( _("Below"));
+  tmp_list=g_list_prepend(tmp_list, item);
+  gtk_object_set_data(GTK_OBJECT(item), "layer", "2");
+  gtk_widget_show(item);
+  item = gtk_list_item_new_with_label( _("Desktop"));
+  tmp_list=g_list_prepend(tmp_list, item);
+  gtk_object_set_data(GTK_OBJECT(item), "layer", "0");
+  gtk_widget_show(item);
+
+  gtk_list_insert_items(GTK_LIST(lbox), tmp_list, -1);
+  gtk_list_select_item(GTK_LIST(lbox), 2);
+  
+  button = gtk_button_new_with_label(_("Set Layer"));
+  gtk_box_pack_start(GTK_BOX(vb1), button, FALSE, FALSE, 2);
+  gtk_signal_connect(GTK_OBJECT(button), "clicked",
+                     GTK_SIGNAL_FUNC(layers_cb), lbox);
+  gtk_widget_show(button);
+
+
+  frame=gtk_frame_new(_("Workspaces:"));
+  gtk_box_pack_start(GTK_BOX(vb), frame, FALSE, FALSE, 0);
+  gtk_container_set_border_width(GTK_CONTAINER(frame), 5);
+  gtk_widget_show(frame);
+  
+  vb1 =gtk_vbox_new(FALSE,0);
+  gtk_container_add(GTK_CONTAINER(frame), vb1);
+  gtk_container_set_border_width(GTK_CONTAINER(vb1), 5);
+  gtk_widget_show(vb1);
+
+  sw = gtk_scrolled_window_new(NULL, NULL);
+  gtk_widget_set_usize(sw, 100, 100);
+  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC,
+                                 GTK_POLICY_AUTOMATIC);
+  gtk_box_pack_start(GTK_BOX(vb1), sw, FALSE, FALSE, 0);
+  gtk_widget_show(sw);
+
+  wsbox = gtk_list_new();
+  gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw), wsbox);
+  gtk_list_append_items(GTK_LIST(wsbox), get_workspaces());
+  gtk_widget_show(wsbox);
+
+  allwsbut = gtk_check_button_new_with_label(_("Sticky"));
+  gtk_box_pack_start(GTK_BOX(vb1), allwsbut, FALSE, FALSE, 0);
+  gtk_widget_show(allwsbut);
+
+  button = gtk_button_new_with_label(_("Set Workspace"));
+  gtk_box_pack_start(GTK_BOX(vb1), button, FALSE, FALSE, 0);
+  gtk_signal_connect(GTK_OBJECT(button), "clicked",
+                     GTK_SIGNAL_FUNC(workspace_cb), lbox);
+  gtk_widget_show(button);
+
+  vb =gtk_vbox_new(FALSE,0);
+  gtk_box_pack_start(GTK_BOX(hb), vb, TRUE, TRUE, 0);
+  gtk_widget_show(vb);
+
+  frame=gtk_frame_new(_("State Toggles:"));
+  gtk_box_pack_start(GTK_BOX(vb), frame, FALSE, TRUE, 0);
+  gtk_container_set_border_width(GTK_CONTAINER(frame), 5);
+  gtk_widget_show(frame);
+
+  vb1 =gtk_vbox_new(FALSE,0);
+  gtk_container_add(GTK_CONTAINER(frame), vb1);
+  gtk_container_set_border_width(GTK_CONTAINER(vb1), 5);
+  gtk_widget_show(vb1);
+
+  minbut = gtk_check_button_new_with_label(_("Minimized"));
+  gtk_box_pack_start(GTK_BOX(vb1), minbut, FALSE, FALSE, 0);
+  gtk_widget_show(minbut);
+
+  maxvbut = gtk_check_button_new_with_label(_("Maximized Vertical"));
+  gtk_box_pack_start(GTK_BOX(vb1), maxvbut, FALSE, FALSE, 0);
+  gtk_widget_show(maxvbut);
+
+  maxhbut = gtk_check_button_new_with_label(_("Maximized Horizontal"));
+  gtk_box_pack_start(GTK_BOX(vb1), maxhbut, FALSE, FALSE, 0);
+  gtk_widget_show(maxhbut);
+
+  hidbut = gtk_check_button_new_with_label(_("Hidden"));
+  gtk_box_pack_start(GTK_BOX(vb1), hidbut, FALSE, FALSE, 0);
+  gtk_widget_show(hidbut);
+
+  rollbut = gtk_check_button_new_with_label(_("Shaded"));
+  gtk_box_pack_start(GTK_BOX(vb1), rollbut, FALSE, FALSE, 0);
+  gtk_widget_show(rollbut);
+
+  fixedbut = gtk_check_button_new_with_label(_("Fixed Position"));
+  gtk_box_pack_start(GTK_BOX(vb1), fixedbut, FALSE, FALSE, 0);
+  gtk_widget_show(fixedbut);
+
+  ignorebut = gtk_check_button_new_with_label(_("Ignore on Arrange"));
+  gtk_box_pack_start(GTK_BOX(vb1), ignorebut, FALSE, FALSE, 0);
+  gtk_widget_show(ignorebut);
+  
+  button = gtk_button_new_with_label(_("Set State"));
+  gtk_box_pack_start(GTK_BOX(vb1), button, FALSE, FALSE, 0);
+  gtk_signal_connect(GTK_OBJECT(button), "clicked",
+                     GTK_SIGNAL_FUNC(state_cb), lbox);
+  gtk_widget_show(button);
+
+  frame=gtk_frame_new(_("Skip Toggles:"));
+  gtk_box_pack_start(GTK_BOX(vb), frame, FALSE, FALSE, 0);
+  gtk_container_set_border_width(GTK_CONTAINER(frame), 5);
+  gtk_widget_show(frame);
+
+  vb1 =gtk_vbox_new(FALSE,0);
+  gtk_container_add(GTK_CONTAINER(frame), vb1);
+  gtk_container_set_border_width(GTK_CONTAINER(vb1), 5);
+  gtk_widget_show(vb1);
+
+  sfocbut = gtk_check_button_new_with_label(_("Skip Focus"));
+  gtk_box_pack_start(GTK_BOX(vb1), sfocbut, FALSE, FALSE, 0);
+  gtk_widget_show(sfocbut);
+
+  smenubut = gtk_check_button_new_with_label(_("Skip Window Menu"));
+  gtk_box_pack_start(GTK_BOX(vb1), smenubut, FALSE, FALSE, 0);
+  gtk_widget_show(smenubut);
+
+  sbarbut = gtk_check_button_new_with_label(_("Skip Taskbar / WinList"));
+  gtk_box_pack_start(GTK_BOX(vb1), sbarbut, FALSE, FALSE, 0);
+  gtk_widget_show(sbarbut);
+
+  button = gtk_button_new_with_label(_("Set Skip"));
+  gtk_box_pack_start(GTK_BOX(vb1), button, FALSE, FALSE, 0);
+  gtk_signal_connect(GTK_OBJECT(button), "clicked",
+                     GTK_SIGNAL_FUNC(skip_cb), lbox);
+  gtk_widget_show(button);
+
+  hb1 = gtk_hbox_new(FALSE, 0);
+  gtk_box_pack_start(GTK_BOX(mvb), hb1, FALSE, FALSE, 0);
+  gtk_widget_show(hb1);
+
+  button = gtk_button_new();
+  gtk_box_pack_end(GTK_BOX(hb1), button, FALSE, FALSE, 0);
+  gtk_signal_connect(GTK_OBJECT(button), "clicked",
+                     GTK_SIGNAL_FUNC(about_cb), lbox);
+  gtk_widget_show(button);
+
+  hb = gtk_hbox_new(FALSE, 0);
+  gtk_container_set_border_width(GTK_CONTAINER(hb), 5);
+  gtk_container_add(GTK_CONTAINER(button), hb);
+  gtk_widget_show(hb);
+
+  apic = gnome_stock_new_with_icon (GNOME_STOCK_PIXMAP_HELP);
+  gtk_box_pack_start(GTK_BOX(hb), apic, FALSE, FALSE, 0);
+  gtk_widget_show(apic);
+
+  label = gtk_label_new(_("About"));
+  gtk_box_pack_end(GTK_BOX(hb), label, FALSE, FALSE, 5);
+  gtk_widget_show(label);
+  
+  button = gnome_stock_button(GNOME_STOCK_BUTTON_CLOSE);
+  gtk_box_pack_end(GTK_BOX(hb1), button, FALSE, FALSE, 0);
+  gtk_signal_connect(GTK_OBJECT(button), "clicked",
+                     GTK_SIGNAL_FUNC(quit_cb), lbox);
+  gtk_widget_show(button);
+    
+  gtk_widget_show (app);
+}
+
+void layers_cb (GtkWidget *widget, void *data)
+{
+  GtkWidget *list;
+  GnomeWinLayer new_layer;
+  
+  list = (GtkWidget*)data;
+  if((GTK_LIST(list)->selection) == NULL)
+    {
+      return;
+    }
+  switch(atoi(gtk_object_get_data(GTK_OBJECT(GTK_LIST(list)->selection->data), "layer")))
+    {
+     case 0:
+      new_layer = WIN_LAYER_DESKTOP;
+      break;
+     case 2:
+      new_layer = WIN_LAYER_BELOW;
+      break;
+     case 4:
+      new_layer = WIN_LAYER_NORMAL;
+      break;
+     case 6:
+      new_layer = WIN_LAYER_NORMAL;
+      break;
+     case 8:
+      new_layer = WIN_LAYER_ONTOP;
+      break;
+     case 10:
+      new_layer = WIN_LAYER_DOCK;
+      break;
+     default:
+      new_layer = WIN_LAYER_NORMAL;
+    }
+  
+  gnome_win_hints_set_layer(GTK_WIDGET(app), new_layer);
+  
+  return;
+}
+
+void quit_cb (GtkWidget *widget, void *data)
+{
+  gtk_main_quit ();
+  return;
+}
+
+void workspace_cb (GtkWidget *widget, void *data)
+{
+  char *tmpbuf;
+  gint ws;
+  
+  /* set all workspaces - state change */
+  if(GTK_TOGGLE_BUTTON(allwsbut)->active)
+    gnome_win_hints_set_state(GTK_WIDGET(app), WIN_STATE_STICKY);
+  else
+    gnome_win_hints_set_state(GTK_WIDGET(app), 0);
+  
+  /* change workspace to selection */
+  if(GTK_LIST(wsbox)->selection == NULL)
+    return;
+  tmpbuf = gtk_object_get_data(GTK_OBJECT(GTK_LIST(wsbox)->selection->data), "ws");
+  ws = atoi(tmpbuf);
+  gnome_win_hints_set_workspace(GTK_WIDGET(app), ws);
+  if(GTK_TOGGLE_BUTTON(allwsbut)->active)
+    gnome_win_hints_set_state(GTK_WIDGET(app), WIN_STATE_STICKY);
+  else
+    gnome_win_hints_set_state(GTK_WIDGET(app), 0);
+  
+  return;
+}
+
+static GList *get_workspaces(void)
+{
+  GList *tmp_list, *tmp_list2, *ptr;
+  gint i;
+  GtkWidget *item;
+  char tmpbuf[1024];
+  
+  tmp_list2 = NULL;
+  tmp_list = gnome_win_hints_get_workspace_names();
+  
+  ptr = tmp_list;
+  i = 0;
+  while(ptr)
+    {
+      item = gtk_list_item_new_with_label(ptr->data);
+      gtk_widget_show(item);
+      g_snprintf(tmpbuf, sizeof(tmpbuf), "%d", i++);
+      gtk_object_set_data(GTK_OBJECT(item), "ws", g_strdup(tmpbuf));
+      tmp_list2 = g_list_append(tmp_list2, item);
+      ptr = ptr->next;
+    }
+  return tmp_list2;
+}
+
+void state_cb (GtkWidget *widget, void *data)
+{
+  GnomeWinState state;
+  
+  state = 0;
+  
+  if(GTK_TOGGLE_BUTTON(minbut)->active)
+    state |=  WIN_STATE_MINIMIZED;
+  if(GTK_TOGGLE_BUTTON(maxvbut)->active)
+    state |= WIN_STATE_MAXIMIZED_VERT;
+  if(GTK_TOGGLE_BUTTON(maxhbut)->active)
+    state |= WIN_STATE_MAXIMIZED_HORIZ;
+  if(GTK_TOGGLE_BUTTON(hidbut)->active)
+    state |= WIN_STATE_HIDDEN;
+  if(GTK_TOGGLE_BUTTON(rollbut)->active)
+    state |= WIN_STATE_SHADED;
+  if(GTK_TOGGLE_BUTTON(fixedbut)->active)
+    state |= WIN_STATE_FIXED_POSITION;
+  if(GTK_TOGGLE_BUTTON(ignorebut)->active)
+    state |= WIN_STATE_ARRANGE_IGNORE;
+  
+  gnome_win_hints_set_state(GTK_WIDGET(app), state);
+  
+  return;
+}
+
+void skip_cb (GtkWidget *widget, void *data)
+{
+  GnomeWinHints skip;
+
+  skip = 0;
+  if (GTK_TOGGLE_BUTTON(sfocbut)->active)
+    skip |= WIN_HINTS_SKIP_FOCUS;
+  if (GTK_TOGGLE_BUTTON(smenubut)->active)
+    skip |= WIN_HINTS_SKIP_WINLIST;
+  if (GTK_TOGGLE_BUTTON(sbarbut)->active)
+    skip |= WIN_HINTS_SKIP_TASKBAR;
+  
+  gnome_win_hints_set_hints(GTK_WIDGET(app), skip);
+  return;
+}
+
+void about_cb(GtkWidget *widget, gpointer data)
+{
+  GtkWidget *about;
+  const gchar *authors[] = {"Max Watson", NULL};
+
+  about = gnome_about_new (_("WIN_HINTS Test"), "0.1",
+                           _("Copyright (C) 1998"),
+                           authors,
+                           _("Simple test app to check how the WIN_HINTS work.\n"
+                             "And to test the gnome_win_hints_* functions for errors. :)"),
+                           NULL);
+  gtk_widget_show (about);
+
+  return;
+}
+
diff --git a/doc/.cvsignore b/doc/.cvsignore
new file mode 100644
index 0000000..3dda729
--- /dev/null
+++ b/doc/.cvsignore
@@ -0,0 +1,2 @@
+Makefile.in
+Makefile
diff --git a/doc/ChangeLog b/doc/ChangeLog
new file mode 100644
index 0000000..394bbef
--- /dev/null
+++ b/doc/ChangeLog
@@ -0,0 +1,5 @@
+2001-04-11  Martin Baulig  <baulig suse de>
+
+	* Porting-1.0-2.0.txt: New file. Copied here from
+	gnome-libs/devel-docs/.
+
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..b34f3fc
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1 @@
+EXTRA_DIST = Porting-1.0-2.0.txt
diff --git a/doc/Porting-1.0-2.0.txt b/doc/Porting-1.0-2.0.txt
new file mode 100644
index 0000000..bac2091
--- /dev/null
+++ b/doc/Porting-1.0-2.0.txt
@@ -0,0 +1,276 @@
+		Porting GNOME 1.0 Applications to GNOME 2.0
+
+
+[this document is still work-in-progress.]
+
+Notation
+========
+
+* MODIFIED
+
+  The file/widget/feature has been modified in a source incompatible way,
+  but it is possible to reuse old code without completely rewriting it
+  (compatibility layer exists, fixable by scripts, ....)
+
+* CHANGED API
+
+  The API of this file/widget/feature has completely changed; it is not
+  possible to reuse old code without rewriting at least large parts of it.
+
+* ADDED FUNCTIONALITY
+
+  There is some added functionality over GNOME 1.x.
+
+* OBSOLETE
+
+  The file/widget/feature is obsolete and it has been moved to libcompat.
+
+* REMOVED
+
+  The file/widget/feature has been completely removed, it is not in libcompat.
+  This normally means that it is easier to fix code which was using this than
+  to provide a compatibility layer.
+
+* NEW
+
+  The file/widget/feature is completely new in GNOME 2.0.
+
+* UNKNOWN
+
+  I don't know what's up with this.
+
+
+How to prepare your GNOME 1.0 Applications for GNOME 2.0
+========================================================
+
+There are some things which you can do in your GNOME 1.0 Application
+to make it easier to port them to GNOME 2.0 while still keeping
+compatible with the GNOME 1.x platform.
+
+We will add some new functions to the stable version of gnome-libs
+after GNOME 1.4 which will help you to archive this. The most important
+thing is to use accessor functions rather than accessing widget data
+directly whereever it's possible. These new functions will help you
+doing this.
+
+* GnomeEntry - MODIFIED
+
+  - this is isn't a GtkCombo any longer, but a GnomeSelector.
+
+  The following functions have been removed:
+
+  - gnome_entry_gtk_entry()
+
+    GnomeEntry isn't a GtkCombo/GtkEntry anymore; use
+    gnome_entry_get_text() and gnome_entry_set_text() to access
+    the entry text.
+
+  - gnome_entry_construct() - you can now use g_object_new() etc.
+
+  The following functions are deprecated:
+
+  - gnome_entry_get_history_id, gnome_entry_set_history_id
+    gnome_entry_get_history_id, gnome_entry_set_max_saved
+    gnome_entry_get_max_saved, gnome_entry_prepend_history
+    gnome_entry_append_history, gnome_entry_load_history
+    gnome_entry_save_history, gnome_entry_clear_history
+
+    Use the corresponding functions in GnomeSelector.
+
+  The following new functions have been added:
+
+  - gnome_entry_get_text(), gnome_entry_set_text()
+
+  These functions will be added to the stable gnome-libs after GNOME 1.4;
+  in all existing code. To prepare things in GNOME 1.x:
+
+  - use gnome_entry_get/set_text() rather than gnome_entry_gtk_entry()
+
+  - try not to access any of the 'changed', 'history_id', 'items' and
+    'max_saved' fields in the GnomeEntry directly, they will be private
+    in GNOME 2.0.
+
+* GnomeFileEntry - OBSOLETE
+
+  - this has been replaced by GnomeFileSelector.
+
+* GnomeIconEntry - MODIFIED + ADDED FUNCTIONALITY
+
+  - this is now derived from GnomeFileSelector instead of GtkVBox.
+  - previously, the difference between GnomeIconEntry and GnomePixmapEntry
+    was that you could specify the size of the preview in a GnomePixmapEntry;
+    this functionality has been moved into GnomeIconEntry so that
+    GnomePixmapEntry is now obsolete.
+
+  The following functions have been removed:
+
+  - gnome_icon_entry_construct() - you can now use g_object_new() etc.
+  - gnome_icon_entry_gnome_file_entry(): use parent class
+  - gnome_icon_entry_gnome_entry (): use parent class
+  - gnome_icon_entry_gtk_entry (): don't suck things out of this directly
+
+  The following functions are deprecated:
+
+  - gnome_icon_entry_set_pixmap_subdir(): Fixme, Fixme.
+  - gnome_icon_entry_set_icon(): use gnome_selector_set_uri().
+
+  The following new functions have been added:
+
+  - gnome_icon_entry_get_icon_selector ()
+  - gnome_icon_entry_set_preview_size (): formerly in GnomePixmapEntry.
+
+  Other source incompatible changes:
+
+  - `fentry', `pickbutton', `pick_dialog', `pick_dialog_dir' have been
+    removed from the GnomeIconEntry instance struct.
+
+* GnomePixmapEntry - OBSOLETE
+
+  - this has been obsoleted by GnomeIconEntry.
+
+  - we can implement this in libcompat, but I don't think this is necessary;
+    all you need to do to get a pixmap entry is something like
+
+    pentry = g_object_new (gnome_icon_entry_get_type (),
+			   "preview_x", 200, "preview_y", 200,
+			   "is_pixmap_entry", TRUE,
+			   NULL);
+
+    and it will look and behave like the old GnomePixmapEntry.
+
+    [FIXME: We may want to rename GnomeIconEntry -> GnomePixmapEntry.]
+
+* GnomeCalculator - REMOVED
+
+  - this has been moved to libcompat for the moment; it should go somewhere
+    else, but not in libgnomeui.
+
+* GnomeNumberEntry - REMOVED
+
+  - this was using GnomeCalculator and has been moved to libcompat as well.
+
+* GnomeProcBar - REMOVED
+
+  - this was only used in GTop and some applets; it has been moved into GTop.
+  - the three applets will be moved into GTop as well to share some code with
+    it for GNOME 2.0.
+
+* gnome-properties, gnome-property-entries - REMOVED
+
+  - this was only used in GTop and some applets; it is totally obsolete due
+    to GConf.
+
+* GnomeAbout - ADDED FUNCTIONALITY
+
+  - some things have been added; it doesn't look finished to me.
+
+* GnomeAnimator - UNKNOWN
+
+  - I think this should be removed from libgnomeui.
+
+* GnomeAppBar - MODIFIED
+
+  The following functions have been renamed:
+
+  - gnome_appbar_set_progress() -> gnome_appbar_set_progress_percentage().
+
+  The following new functions have been added:
+
+  - gnome_appbar_get_status()
+
+  Other source incompatible changes:
+
+  - all fields have been removed from the GnomeAppBar instance struct.
+
+* gnome-dentry-edit - OBSOLETE
+
+* gnome-dns - OBSOLETE
+
+* gnome-guru - OBSOLETE
+
+* gnome-spell - OBSOLETE
+
+* gnome-startup - OBSOLETE
+
+* gtkcauldron - OBSOLETE
+
+* gnome-druid-page-start, gnome-druid-page-finish: OBSOLETE
+
+* gtk-ted - REMOVED
+
+* gnome-font-selector - OBSOLETE
+
+* gnome-color-picker - MODIFIED
+
+  The following functions have been added:
+
+  - gnome_color_picker_get_dither ()
+  - gnome_color_picker_get_use_alpha ()
+  - gnome_color_picker_get_title ()
+ 
+  - all fields have been removed from the GnomeColorPicker instance struct.
+
+* gnome-date-edit - MODIFIED
+
+  - all fields have been removed from the GnomeDateEdit instance struct.
+
+  The following functions have been renamed:
+
+  - gnome_date_edit_get_date() -> gnome_date_edit_get_time()
+
+  The following functions have been added:
+
+  - gnome_date_edit_get_initial_time()
+
+- gnome-font-picker - MODIFIED
+
+  - private fields have been removed from the GnomeFontPicker instance struct.
+
+  The following functions have been added:
+
+  - gnome_font_picker_get_font_name()
+
+- gnome-href - MODIFIED
+
+  - all fields have been removed from the GnomeHRef instance struct.
+
+  The following functions have been renamed:
+
+  - gnome_href_get_label() -> gnome_href_get_text()
+  - gnome_href_set_label() -> gnome_href_set_text()
+
+- gnome-icon-list - MODIFIED and ADDED FUNCTIONALITY
+
+  - all fields have been removed from the GnomeIconList instance struct.
+
+  The following functions have a different API:
+
+  - gnome_icon_list_new() - removed `GtkAdjustment *adj' argument
+  - gnome_icon_list_unselect_all() - removed `GdkEvent *event' and
+  `gpointer keep' arguments.
+
+  The following functions have been removed:
+
+  - gnome_icon_list_new_flags()
+  - gnome_icon_list_set_hadjustment()
+  - gnome_icon_list_set_vadjustment()
+  - gnome_icon_list_insert_imlib()
+  - gnome_icon_list_append_imlib()
+
+  The following new functions have been added:
+
+  - gnome_icon_list_insert_pixbuf()
+  - gnome_icon_list_append_pixbuf()
+  - gnome_icon_list_get_selection_mode()
+  - gnome_icon_list_get_selectinon()
+  - gnome_icon_list_get_icon_filename()
+  - gnome_icon_list_find_icon_from_filename()
+
+* gnome-icon-sel - OBSOLETE
+
+  Use GnomeIconSelector.
+
+
+Last changed Feb 25, 2001.
+Martin Baulig <baulig suse de>
+George Lebl <jirka 5z com>
diff --git a/glade/glade-gnome.c b/glade/glade-gnome.c
new file mode 100644
index 0000000..fe51172
--- /dev/null
+++ b/glade/glade-gnome.c
@@ -0,0 +1,2121 @@
+/* -*- Mode: C; c-basic-offset: 8 -*-
+ * libglade - a library for building interfaces from XML files at runtime
+ * Copyright (C) 1998-2001  James Henstridge <james daa com au>
+ * Copyright (C) 1999 Miguel de Icaza (miguel gnu org)
+ *
+ * glade-gnome.c: support for gnome widgets in libglade.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA  02111-1307, USA.
+ */
+
+/* this file is only built if GNOME support is enabled */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <glade/glade.h>
+#include <glade/glade-build.h>
+#include <glade/glade-private.h>
+
+#include <gnome.h>
+
+#ifndef ENABLE_NLS
+/* a slight optimisation when gettext is off */
+#define glade_xml_gettext(xml, msgid) (msgid)
+#endif
+#undef _
+#define _(msgid) (glade_xml_gettext(xml, msgid))
+
+static const char *get_stock_name (const char *stock_name);
+static gboolean get_stock_uiinfo (const char *stock_name, GnomeUIInfo *info);
+
+static void
+page_mapped (GtkWidget *page, GtkAccelGroup *accel_group)
+{
+	GtkWidget *dialog = gtk_widget_get_toplevel (GTK_WIDGET (page));
+
+	gtk_window_add_accel_group (GTK_WINDOW (dialog), accel_group);
+}
+
+static void
+page_unmapped (GtkWidget *page, GtkAccelGroup *accel_group)
+{
+	GtkWidget *dialog = gtk_widget_get_toplevel (GTK_WIDGET (page));
+
+	gtk_window_remove_accel_group (GTK_WINDOW (dialog), accel_group);
+}
+
+static void page_setup_signals (GtkWidget *page, GtkAccelGroup *accel)
+{
+	gtk_accel_group_ref(accel);
+	gtk_signal_connect_full (GTK_OBJECT (page),
+			    "map",
+			    GTK_SIGNAL_FUNC (page_mapped), NULL, 
+			    accel, (GtkDestroyNotify)gtk_accel_group_unref,
+			    FALSE, FALSE);
+	gtk_accel_group_ref(accel);
+	gtk_signal_connect_full (GTK_OBJECT (page),
+			    "unmap",
+			    GTK_SIGNAL_FUNC (page_unmapped), NULL,
+			    accel, (GtkDestroyNotify)gtk_accel_group_unref,
+			    FALSE, FALSE);
+}
+
+/* -- routines to build the children for containers -- */
+
+static void
+button_build_children (GladeXML *xml, GtkWidget *w, GladeWidgetInfo *info,
+		       const char *longname)
+{
+	GtkWidget *child = glade_xml_build_widget(xml,
+			(GladeWidgetInfo *)info->children->data, longname);
+	guint key = glade_xml_get_parent_accel(xml);
+
+	gtk_container_add(GTK_CONTAINER(w), child);
+	if (key)
+		gtk_widget_add_accelerator(w, "clicked",
+					   glade_xml_ensure_accel(xml),
+					   key, GDK_MOD1_MASK, 0);
+}
+
+static void
+gnomedialog_build_children(GladeXML *xml, GtkWidget *w, GladeWidgetInfo *info,
+			    const char *longname)
+{
+	GList *tmp;
+	char *vboxname;
+
+	vboxname = g_strconcat (longname, ".", info->name, NULL);
+
+	/* all dialog children are inside the main vbox */
+	for (tmp = ((GladeWidgetInfo *)info->children->data)->children;
+	     tmp; tmp = tmp->next) {
+		GladeWidgetInfo *cinfo = tmp->data;
+		GtkWidget *child;
+		GList *tmp2;
+		gboolean is_action_area = FALSE;
+		gboolean expand = TRUE, fill = TRUE, start = TRUE;
+		gint padding = 0;
+
+		for (tmp2 = cinfo->attributes; tmp2; tmp2 = tmp2->next) {
+			GladeAttribute *attr = tmp2->data;
+			if (!strcmp(attr->name, "child_name") &&
+			    !strcmp(attr->value, "GnomeDialog:action_area")) {
+				is_action_area = TRUE;
+				break;
+			}
+		}
+
+		if (is_action_area) {
+			char *parent_name;
+
+			parent_name = g_strconcat(vboxname, ".", cinfo->name,
+						  NULL);
+
+			/* this is the action area -- here we add the buttons*/
+			for (tmp2 = cinfo->children; tmp2; tmp2 = tmp2->next) {
+				GladeWidgetInfo *ccinfo = tmp2->data;
+				const char *stock, *string = NULL, *label=NULL;
+				GList *tmp3;
+
+				for (tmp3 = ccinfo->attributes;
+				     tmp3; tmp3 = tmp3->next) {
+					GladeAttribute *attr = tmp3->data;
+					if (!strcmp(attr->name,
+						    "stock_button")) {
+						string = attr->value;
+						break;
+					} else if (!strcmp(attr->name,
+							   "label"))
+						label = attr->value;
+					
+				}
+				if (!string)
+					stock = _(label);
+				else {
+					stock = get_stock_name(string);
+					if (!stock) stock = string;
+				}
+				gnome_dialog_append_button(GNOME_DIALOG(w),
+							   stock);
+				/* connect signal handlers, etc ... */
+				child = g_list_last(
+					GNOME_DIALOG(w)->buttons)->data;
+				glade_xml_set_common_params(xml, child,
+							    ccinfo,
+							    parent_name);
+			}
+			g_free(parent_name);
+			continue;
+		}
+
+		child = glade_xml_build_widget(xml, cinfo, vboxname);
+		for (tmp2 = cinfo->child_attributes; tmp2; tmp2 = tmp2->next) {
+			GladeAttribute *attr = tmp2->data;
+
+			switch(attr->name[0]) {
+			case 'e':
+				if (!strcmp(attr->name, "expand"))
+					expand = attr->value[0] == 'T';
+				break;
+			case 'f':
+				if (!strcmp(attr->name, "fill"))
+					fill = attr->value[0] == 'T';
+				break;
+			case 'p':
+				if (!strcmp(attr->name, "padding"))
+					padding = strtol(attr->value, NULL, 0);
+				else if (!strcmp(attr->name, "pack"))
+					start = strcmp(attr->value,
+						       "GTK_PACK_START") == 0;
+				break;
+			}
+		}
+		if (start)
+			gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(w)->vbox),
+					   child, expand, fill, padding);
+		else
+			gtk_box_pack_end(GTK_BOX(GNOME_DIALOG(w)->vbox),
+					 child, expand, fill, padding);
+	}
+	g_free(vboxname);
+}
+
+static void
+messagebox_build_children(GladeXML *xml, GtkWidget *w, GladeWidgetInfo *info,
+			    const char *longname)
+{
+	GList *tmp;
+	GladeWidgetInfo *cinfo;
+	GtkWidget *child;
+
+	/* the message box contains a vbox which contains a hbuttonbox ... */
+	cinfo = ((GladeWidgetInfo *)info->children->data)->children->data;
+	/* the children of the hbuttonbox are the buttons ... */
+	for (tmp = cinfo->children; tmp; tmp = tmp->next) {
+		GList *tmp2;
+		const char *stock, *string = NULL;
+
+		cinfo = tmp->data;
+		for (tmp2 = cinfo->attributes; tmp2; tmp2 = tmp2->next) {
+			GladeAttribute *attr = tmp2->data;
+			if (!strcmp(attr->name, "stock_button") ||
+			    !strcmp(attr->name, "stock_pixmap")) {
+				string = attr->value;
+				break;
+			}
+		}
+		stock = get_stock_name(string);
+		if (!stock) stock = string;
+		gnome_dialog_append_button(GNOME_DIALOG(w), stock);
+		child = g_list_last(GNOME_DIALOG(w)->buttons)->data;
+		glade_xml_set_common_params(xml, child, cinfo,
+					    longname);
+	}
+}
+
+static void
+app_build_children(GladeXML *xml, GtkWidget *w, GladeWidgetInfo *info,
+		   const char *longname)
+{
+	GList *tmp;
+
+	for (tmp = info->children; tmp; tmp = tmp->next) {
+		GladeWidgetInfo *cinfo = tmp->data;
+		GList *tmp2;
+		gboolean is_dock = FALSE, is_appbar = FALSE;
+		GtkWidget *child;
+
+		for (tmp2 = cinfo->attributes; tmp2; tmp2 = tmp2->next) {
+			GladeAttribute *attr = tmp2->data;
+			if (!strcmp(attr->name, "child_name")) {
+				is_dock   = !strcmp(attr->value,
+						    "GnomeApp:dock");
+				is_appbar = !strcmp(attr->value,
+						    "GnomeApp:appbar");
+				break;
+			}
+		}
+		if (is_dock) {
+			/* the dock has already been created */
+			glade_xml_set_common_params(xml,
+				GTK_WIDGET(gnome_app_get_dock(GNOME_APP(w))),
+				cinfo, longname);
+		} else if (is_appbar) {
+			child = glade_xml_build_widget(xml, cinfo, longname);
+			gnome_app_set_statusbar(GNOME_APP(w), child);
+		} else {
+			child = glade_xml_build_widget(xml, cinfo, longname);
+			gtk_container_add(GTK_CONTAINER(w), child);
+		}
+	}
+}
+
+static void
+dock_build_children(GladeXML *xml, GtkWidget *w, GladeWidgetInfo *info,
+		   const char *longname)
+{
+	GList *tmp;
+	GnomeApp *app = NULL;
+
+	if (w->parent && w->parent && GNOME_IS_APP(w->parent->parent))
+		app = GNOME_APP(w->parent->parent);
+
+	for (tmp = info->children; tmp; tmp = tmp->next) {
+		GladeWidgetInfo *cinfo = tmp->data;
+		GList *tmp2;
+		gboolean is_contents = FALSE;
+		GtkWidget *child;
+
+		for (tmp2 = cinfo->attributes; tmp2; tmp2 = tmp2->next) {
+			GladeAttribute *attr = tmp2->data;
+			if (!strcmp(attr->name, "child_name")) {
+				is_contents = !strcmp(attr->value,
+						      "GnomeDock:contents");
+				break;
+			}
+		}
+		if (is_contents) {
+			child = glade_xml_build_widget(xml, cinfo, longname);
+			gnome_dock_set_client_area(GNOME_DOCK(w), child);
+		} else {
+			/* a dock item */
+			GnomeDockPlacement placement = GNOME_DOCK_TOP;
+			guint band = 0, offset = 0;
+			gint position = 0;
+
+			child = glade_xml_build_widget(xml, cinfo, longname);
+			for (tmp2 = cinfo->attributes; tmp2; tmp2=tmp2->next) {
+				GladeAttribute *attr = tmp2->data;
+
+				if (!strcmp(attr->name, "placement"))
+					placement = glade_enum_from_string(
+						GTK_TYPE_GNOME_DOCK_PLACEMENT,
+						attr->value);
+				else if (!strcmp(attr->name, "band"))
+					band = strtoul(attr->value, NULL, 0);
+				else if (!strcmp(attr->name, "position"))
+					position = strtol(attr->value, NULL,0);
+				else if (!strcmp(attr->name, "offset"))
+					offset = strtoul(attr->value, NULL, 0);
+			}
+			if (app)
+				gnome_app_add_dock_item(app,
+					GNOME_DOCK_ITEM(child), placement,
+					band, position, offset);
+			else
+				gnome_dock_add_item(GNOME_DOCK(w),
+					GNOME_DOCK_ITEM(child), placement,
+					band, position, offset, FALSE);
+		}
+	}
+}
+
+static void
+menuitem_build_children (GladeXML *xml, GtkWidget *w, GladeWidgetInfo *info,
+                         const char *longname)
+{
+        GtkWidget *menu;
+        if (!info->children) return;
+        menu = glade_xml_build_widget(xml, info->children->data, longname);
+        gtk_menu_item_set_submenu(GTK_MENU_ITEM(w), menu);
+	/* weird things happen if menu is initially visible */
+        gtk_widget_hide(menu);
+}
+
+static void
+toolbar_build_children (GladeXML *xml, GtkWidget *w, GladeWidgetInfo *info,
+			const char *longname)
+{
+	GList *tmp;
+
+	for (tmp = info->children; tmp; tmp = tmp->next) {
+		GladeWidgetInfo *cinfo = tmp->data;
+		GtkWidget *child;
+		GList *tmp2;
+		gboolean is_button = FALSE;
+		gchar *group_name = NULL;
+
+		for (tmp2 = cinfo->child_attributes; tmp2; tmp2 = tmp2->next) {
+			GladeAttribute *attr = tmp2->data;
+			if (!strcmp(attr->name, "new_group") &&
+			    attr->value[0] == 'T')
+				gtk_toolbar_append_space(GTK_TOOLBAR(w));
+		}
+		
+		/* check to see if this is a special Toolbar:button or just
+		 * a standard widget we are adding to the toolbar */
+		for (tmp2 = cinfo->attributes; tmp2; tmp2 = tmp2->next) {
+			GladeAttribute *attr = tmp2->data;
+			if (!strcmp(attr->name, "child_name"))
+				is_button = !strcmp(attr->value,
+						    "Toolbar:button");
+			else if (!strcmp(attr->name, "group"))
+				group_name = attr->value;
+		}
+		if (is_button) {
+			char *label = NULL, *icon = NULL, *stock = NULL;
+			gboolean active = FALSE;
+			GtkWidget *iconw = NULL;
+
+			for (tmp2 = cinfo->attributes; tmp2; tmp2=tmp2->next) {
+				GladeAttribute *attr = tmp2->data;
+
+				if (!strcmp(attr->name, "label")) {
+					label = attr->value;
+				} else if (!strcmp(attr->name, "icon")) {
+					if (icon) g_free(icon);
+					stock = NULL;
+					icon = glade_xml_relative_file(xml,
+								attr->value);
+				} else if (!strcmp(attr->name,"stock_pixmap")){
+					if (icon) g_free(icon);
+					icon = NULL;
+					stock = attr->value;
+				} else if (!strcmp(attr->name, "active")) {
+					active = (attr->value[0] == 'T');
+				}
+			}
+			if (stock) {
+				iconw = gnome_stock_new_with_icon(
+						get_stock_name(stock));
+			} else if (icon) {
+				GdkPixmap *pix;
+				GdkBitmap *mask = NULL;
+				pix = gdk_pixmap_colormap_create_from_xpm(NULL,
+					gtk_widget_get_colormap(w), &mask,
+					NULL, icon);
+				g_free(icon);
+				if (pix)
+					iconw = gtk_pixmap_new(pix, mask);
+				else
+					iconw = gtk_type_new(
+						gtk_pixmap_get_type());
+				if (pix) gdk_pixmap_unref(pix);
+				if (mask) gdk_bitmap_unref(mask);
+			}
+			if (!strcmp(cinfo->class, "GtkToggleButton")) {
+				child = gtk_toolbar_append_element(
+					GTK_TOOLBAR(w),
+					GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
+					_(label), NULL, NULL, iconw, NULL,
+					NULL);
+				gtk_toggle_button_set_active(
+					GTK_TOGGLE_BUTTON(child), active);
+			} else if (!strcmp(cinfo->class, "GtkRadioButton")) {
+				child = gtk_toolbar_append_element(
+					GTK_TOOLBAR(w),
+					GTK_TOOLBAR_CHILD_RADIOBUTTON, NULL,
+					_(label), NULL, NULL, iconw, NULL,
+					NULL);
+
+				if (group_name) {
+					GSList *group =
+						g_hash_table_lookup(
+						    xml->priv->radio_groups,
+						    group_name);
+
+					gtk_radio_button_set_group(
+						GTK_RADIO_BUTTON(child),
+						group);
+					if (!group)
+						group_name =
+							g_strdup(group_name);
+					g_hash_table_insert(
+						xml->priv->radio_groups,
+						group_name,
+						gtk_radio_button_group(
+						    GTK_RADIO_BUTTON(child)));
+				}
+
+			} else
+				child = gtk_toolbar_append_item(GTK_TOOLBAR(w),
+					_(label), NULL, NULL, iconw, NULL,
+					NULL);
+			glade_xml_set_common_params(xml, child, cinfo,
+						    longname);
+		} else {
+			child = glade_xml_build_widget(xml, cinfo, longname);
+			gtk_toolbar_append_widget(GTK_TOOLBAR(w), child,
+						  NULL, NULL);
+		}
+	}
+}
+
+static void
+menushell_build_children (GladeXML *xml, GtkWidget *w, GladeWidgetInfo *info,
+			  const char *longname)
+{
+	GList *tmp;
+	gint childnum = -1;
+	GnomeUIInfo infos[2] = {
+		{ GNOME_APP_UI_ITEM },
+		GNOMEUIINFO_END
+	};
+	GtkAccelGroup *uline = NULL;
+
+	if (strcmp(info->class, "GtkMenuBar") != 0) {
+		uline = gtk_menu_ensure_uline_accel_group(GTK_MENU(w));
+		glade_xml_push_uline_accel(xml, uline);
+	}
+
+	for (tmp = info->children; tmp; tmp = tmp->next) {
+		GladeWidgetInfo *cinfo = tmp->data;
+		GList *tmp2;
+		GtkWidget *child;
+		gchar *stock_name = NULL;
+
+		childnum++;
+		for (tmp2 = cinfo->attributes; tmp2; tmp2 = tmp2->next) {
+			GladeAttribute *attr = tmp2->data;
+
+			if (!strcmp(attr->name, "stock_item")) {
+				stock_name = attr->value;
+				break;
+			}
+		}
+		if (!stock_name) {
+			/* this is a normal menu item */
+			child = glade_xml_build_widget(xml, cinfo, longname);
+			gtk_menu_shell_append(GTK_MENU_SHELL(w), child);
+			continue;
+		}
+		/* load the template GnomeUIInfo for this item */
+		if (!get_stock_uiinfo(stock_name, &infos[0])) {
+			/* failure ... */
+			if (!strncmp(stock_name, "GNOMEUIINFO_", 12))
+				stock_name += 12;
+			child = gtk_menu_item_new_with_label(stock_name);
+			glade_xml_set_common_params(xml, child, cinfo,
+						    longname);
+			gtk_menu_shell_append(GTK_MENU_SHELL(w), child);
+			continue;
+		}
+		/* we now have the template for this item.  Now fill it in */
+		for (tmp2 = cinfo->attributes; tmp2; tmp2 = tmp2->next) {
+			GladeAttribute *attr = tmp2->data;
+
+			if (!strcmp(attr->name, "label"))
+				infos[0].label = _(attr->value);
+			else if (!strcmp(attr->name, "tooltip"))
+				infos[0].hint = _(attr->value);
+		}
+		gnome_app_fill_menu(GTK_MENU_SHELL(w), infos,
+				    glade_xml_ensure_accel(xml), TRUE,
+				    childnum);
+		child = infos[0].widget;
+		gtk_menu_item_remove_submenu(GTK_MENU_ITEM(child));
+		glade_xml_set_common_params(xml, child, cinfo,
+					    longname);
+	}
+	if (uline)
+		glade_xml_pop_uline_accel(xml);
+	if (strcmp(info->class, "GtkMenuBar") != 0 &&
+	    gnome_preferences_get_menus_have_tearoff()) {
+		GtkWidget *tearoff = gtk_tearoff_menu_item_new();
+
+		gtk_menu_prepend(GTK_MENU(w), tearoff);
+		gtk_widget_show(tearoff);
+	}
+}
+
+static void
+entry_build_children (GladeXML *xml, GtkWidget *w,
+		      GladeWidgetInfo *info, const char *longname)
+{
+	GList *tmp;
+	GladeWidgetInfo *cinfo = NULL;
+	GtkEntry *entry;
+
+	for (tmp = info->children; tmp; tmp = tmp->next) {
+		GList *tmp2;
+		gchar *child_name = NULL;
+		cinfo = tmp->data;
+		for (tmp2 = cinfo->attributes; tmp2; tmp2 = tmp2->next) {
+			GladeAttribute *attr = tmp2->data;
+			if (!strcmp(attr->name, "child_name")) {
+				child_name = attr->value;
+				break;
+			}
+		}
+		if (child_name && !strcmp(child_name, "GnomeEntry:entry"))
+			break;
+	}
+	if (!tmp)
+		return;
+	if (GNOME_IS_ENTRY(w))
+		entry = GTK_ENTRY(gnome_entry_gtk_entry(GNOME_ENTRY(w)));
+	else if (GNOME_IS_FILE_ENTRY(w))
+		entry = GTK_ENTRY(gnome_file_entry_gtk_entry(GNOME_FILE_ENTRY(w)));
+	else if (GNOME_IS_NUMBER_ENTRY(w))
+		entry = GTK_ENTRY(gnome_number_entry_gtk_entry(GNOME_NUMBER_ENTRY(w)));
+	else
+		return;
+
+	for (tmp = cinfo->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+		if (!strcmp(attr->name, "editable"))
+			gtk_entry_set_editable(entry, attr->value[0] == 'T');
+		else if (!strcmp(attr->name, "text_visible"))
+			gtk_entry_set_visibility(entry, attr->value[0] == 'T');
+		else if (!strcmp(attr->name, "text_max_length"))
+			gtk_entry_set_max_length(entry, strtol(attr->value,
+							       NULL, 0));
+		else if (!strcmp(attr->name, "text"))
+			gtk_entry_set_text(entry, attr->value);
+	}
+	glade_xml_set_common_params(xml, GTK_WIDGET(entry), cinfo, longname);
+}
+
+static void
+pixmap_entry_build_children (GladeXML *xml, GtkWidget *w,
+			     GladeWidgetInfo *info, const char *longname)
+{
+	GList *tmp;
+	GladeWidgetInfo *cinfo = NULL;
+	GnomeFileEntry *entry;
+	GnomeEntry *gentry;
+
+	for (tmp = info->children; tmp; tmp = tmp->next) {
+		GList *tmp2;
+		gchar *child_name = NULL;
+		cinfo = tmp->data;
+		for (tmp2 = cinfo->attributes; tmp2; tmp2 = tmp2->next) {
+			GladeAttribute *attr = tmp2->data;
+			if (!strcmp(attr->name, "child_name")) {
+				child_name = attr->value;
+				break;
+			}
+		}
+		if (child_name && !strcmp(child_name,
+					  "GnomePixmapEntry:file-entry"))
+			break;
+	}
+	if (!tmp)
+		return;
+	entry = GNOME_FILE_ENTRY(gnome_pixmap_entry_gnome_file_entry(
+						GNOME_PIXMAP_ENTRY(w)));
+	gentry = GNOME_ENTRY(gnome_pixmap_entry_gnome_entry(
+						GNOME_PIXMAP_ENTRY(w)));
+
+	for (tmp = cinfo->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+		if (!strcmp(attr->name, "history_id"))
+			gnome_entry_set_history_id(gentry, attr->value);
+		else if (!strcmp(attr->name, "max_saved"))
+			gnome_entry_set_max_saved(gentry, strtol(attr->value,
+								 NULL, 0));
+		else if (!strcmp(attr->name, "title"))
+			gnome_file_entry_set_title(entry, attr->value);
+		else if (!strcmp(attr->name, "directory"))
+			gnome_file_entry_set_directory(entry,
+						       attr->value[0] == 'T');
+		else if (!strcmp(attr->name, "modal"))
+			gnome_file_entry_set_modal(entry, attr->value[0]=='T');
+	}
+	glade_xml_set_common_params(xml, GTK_WIDGET(entry), cinfo, longname);
+}
+
+static void
+druid_build_children(GladeXML *xml, GtkWidget *w,
+		     GladeWidgetInfo *info, const char *longname)
+{
+	GList *tmp;
+
+	for (tmp = info->children; tmp; tmp = tmp->next) {
+		GladeWidgetInfo *cinfo = tmp->data;
+		GtkAccelGroup *accel;
+		GtkWidget *child;
+
+		accel = glade_xml_push_accel(xml);
+		child = glade_xml_build_widget(xml, cinfo, longname);
+		page_setup_signals(child, accel);
+		glade_xml_pop_accel(xml);
+
+		gnome_druid_append_page(GNOME_DRUID(w),
+					GNOME_DRUID_PAGE(child));
+		if (tmp->prev == NULL)
+			gnome_druid_set_page(GNOME_DRUID(w),
+					     GNOME_DRUID_PAGE(child));
+	}
+}
+
+static void
+druidpage_build_children(GladeXML *xml, GtkWidget *w,
+			 GladeWidgetInfo *info, const char *longname)
+{
+	GladeWidgetInfo *cinfo = info->children->data;
+	GtkWidget *vbox= GNOME_DRUID_PAGE_STANDARD(w)->vbox;
+
+	glade_xml_set_common_params(xml, vbox, cinfo, longname);
+}
+
+static void
+pbox_change_page(GtkWidget *child, GtkNotebook *notebook)
+{
+	gint page = gtk_notebook_page_num(notebook, child);
+
+	gtk_notebook_set_page(notebook, page);
+}
+
+
+static void
+propbox_build_children (GladeXML *xml, GtkWidget *w, GladeWidgetInfo *info,
+			const char *longname)
+{
+	/*
+	 * the notebook tabs are listed after the pages, and have
+	 * child_name set to Notebook:tab.  We store pages in a GList
+	 * while waiting for tabs
+	 */
+
+	GList *pages = NULL;
+	GladeWidgetInfo *ninfo = info->children->data;
+	GList *tmp;
+
+	for (tmp = ninfo->children; tmp; tmp = tmp->next) {
+		GladeWidgetInfo *cinfo = tmp->data;
+		GtkWidget *child;
+		GList *tmp2;
+		GladeAttribute *attr = NULL;
+		GtkAccelGroup *accel;
+
+		accel = glade_xml_push_accel(xml);
+		child = glade_xml_build_widget (xml,cinfo,longname);
+		page_setup_signals(child, accel);
+		glade_xml_pop_accel(xml);
+		for (tmp2 = cinfo->attributes; tmp2; tmp2 = tmp2->next) {
+			attr = tmp2->data;
+			if (!strcmp(attr->name, "child_name"))
+				break;
+		}
+		if (tmp2 == NULL || strcmp(attr->value, "Notebook:tab") != 0)
+			pages = g_list_append (pages, child);
+		else {
+			GtkWidget *page;
+			guint key = glade_xml_get_parent_accel(xml);
+
+			if (pages) {
+				page = pages->data;
+				pages = g_list_remove (pages, page);
+			} else {
+				page = gtk_label_new("Unknown page");
+				gtk_widget_show(page);
+			}
+			gnome_property_box_append_page (GNOME_PROPERTY_BOX(w),
+							page, child);
+			if (key) {
+				gtk_widget_add_accelerator(page, "grab_focus",
+					     glade_xml_ensure_accel(xml),
+					     key, GDK_MOD1_MASK, 0);
+				gtk_signal_connect(GTK_OBJECT(page),
+					"grab_focus",
+					GTK_SIGNAL_FUNC(pbox_change_page),
+					GNOME_PROPERTY_BOX(w)->notebook);
+			}
+		}
+	}
+}
+
+/* -- routines to build widgets -- */
+
+/* this is for the GnomeStockButton widget ... */
+/* Keep these sorted */
+typedef struct {
+        const char *extension;
+        const char *mapping;
+} gnome_map_t;
+
+static const gnome_map_t gnome_stock_button_mapping [] = {
+        { "APPLY",  GNOME_STOCK_BUTTON_APPLY  },
+        { "CANCEL", GNOME_STOCK_BUTTON_CANCEL },
+        { "CLOSE",  GNOME_STOCK_BUTTON_CLOSE  },
+        { "DOWN",   GNOME_STOCK_BUTTON_DOWN   },
+        { "FONT",   GNOME_STOCK_BUTTON_FONT   },
+        { "HELP",   GNOME_STOCK_BUTTON_HELP   },
+        { "NEXT",   GNOME_STOCK_BUTTON_NEXT   },
+        { "NO",     GNOME_STOCK_BUTTON_NO     },
+        { "OK",     GNOME_STOCK_BUTTON_OK     },
+        { "PREV",   GNOME_STOCK_BUTTON_PREV   },
+        { "UP",     GNOME_STOCK_BUTTON_UP     },
+        { "YES",    GNOME_STOCK_BUTTON_YES    },
+};
+static const gnome_map_t gnome_stock_pixmap_mapping [] = {
+	{ "ABOUT", GNOME_STOCK_PIXMAP_ABOUT },
+	{ "ADD", GNOME_STOCK_PIXMAP_ADD },
+	{ "ALIGN_CENTER", GNOME_STOCK_PIXMAP_ALIGN_CENTER },
+	{ "ALIGN_JUSTIFY", GNOME_STOCK_PIXMAP_ALIGN_JUSTIFY },
+	{ "ALIGN_LEFT", GNOME_STOCK_PIXMAP_ALIGN_LEFT },
+	{ "ALIGN_RIGHT", GNOME_STOCK_PIXMAP_ALIGN_RIGHT },
+	{ "ATTACH", GNOME_STOCK_PIXMAP_ATTACH },
+	{ "BACK", GNOME_STOCK_PIXMAP_BACK },
+	{ "BOOK_BLUE", GNOME_STOCK_PIXMAP_BOOK_BLUE },
+	{ "BOOK_GREEN", GNOME_STOCK_PIXMAP_BOOK_GREEN },
+	{ "BOOK_OPEN", GNOME_STOCK_PIXMAP_BOOK_OPEN },
+	{ "BOOK_RED", GNOME_STOCK_PIXMAP_BOOK_RED },
+	{ "BOOK_YELLOW", GNOME_STOCK_PIXMAP_BOOK_YELLOW },
+	{ "BOTTOM", GNOME_STOCK_PIXMAP_BOTTOM },
+	{ "CDROM", GNOME_STOCK_PIXMAP_CDROM },
+	{ "CLEAR", GNOME_STOCK_PIXMAP_CLEAR },
+	{ "CLOSE", GNOME_STOCK_PIXMAP_CLOSE },
+	{ "COLORSELECTOR", GNOME_STOCK_PIXMAP_COLORSELECTOR },
+	{ "CONVERT", GNOME_STOCK_PIXMAP_CONVERT },
+	{ "COPY", GNOME_STOCK_PIXMAP_COPY },
+	{ "CUT", GNOME_STOCK_PIXMAP_CUT },
+	{ "DISABLED", GNOME_STOCK_PIXMAP_DISABLED },
+	{ "DOWN", GNOME_STOCK_PIXMAP_DOWN },
+	{ "EXEC", GNOME_STOCK_PIXMAP_EXEC },
+	{ "EXIT", GNOME_STOCK_PIXMAP_QUIT },
+	{ "FIRST", GNOME_STOCK_PIXMAP_FIRST },
+	{ "FOCUSED", GNOME_STOCK_PIXMAP_FOCUSED },
+	{ "FONT", GNOME_STOCK_PIXMAP_FONT },
+	{ "FORWARD", GNOME_STOCK_PIXMAP_FORWARD },
+	{ "HELP", GNOME_STOCK_PIXMAP_HELP },
+	{ "HOME", GNOME_STOCK_PIXMAP_HOME },
+	{ "INDEX", GNOME_STOCK_PIXMAP_INDEX },
+	{ "JUMP_TO", GNOME_STOCK_PIXMAP_JUMP_TO },
+	{ "LAST", GNOME_STOCK_PIXMAP_LAST },
+	{ "LINE_IN", GNOME_STOCK_PIXMAP_LINE_IN },
+	{ "MAIL", GNOME_STOCK_PIXMAP_MAIL },
+	{ "MAIL_FWD", GNOME_STOCK_PIXMAP_MAIL_FWD },
+	{ "MAIL_NEW", GNOME_STOCK_PIXMAP_MAIL_NEW },
+	{ "MAIL_RCV", GNOME_STOCK_PIXMAP_MAIL_RCV },
+	{ "MAIL_RPL", GNOME_STOCK_PIXMAP_MAIL_RPL },
+	{ "MAIL_SND", GNOME_STOCK_PIXMAP_MAIL_SND },
+	{ "MIC", GNOME_STOCK_PIXMAP_MIC },
+#ifdef GNOME_STOCK_PIXMAP_MIDI
+	{ "MIDI", GNOME_STOCK_PIXMAP_MIDI },
+#endif
+	{ "MULTIPLE", GNOME_STOCK_PIXMAP_MULTIPLE },
+	{ "NEW", GNOME_STOCK_PIXMAP_NEW },
+	{ "NOT", GNOME_STOCK_PIXMAP_NOT },
+	{ "OPEN", GNOME_STOCK_PIXMAP_OPEN },
+	{ "PASTE", GNOME_STOCK_PIXMAP_PASTE },
+	{ "PREFERENCES", GNOME_STOCK_PIXMAP_PREFERENCES },
+	{ "PRINT", GNOME_STOCK_PIXMAP_PRINT },
+	{ "PROPERTIES", GNOME_STOCK_PIXMAP_PROPERTIES },
+	{ "QUIT", GNOME_STOCK_PIXMAP_QUIT },
+	{ "REDO", GNOME_STOCK_PIXMAP_REDO },
+	{ "REFRESH", GNOME_STOCK_PIXMAP_REFRESH },
+	{ "REGULAR", GNOME_STOCK_PIXMAP_REGULAR },
+	{ "REMOVE", GNOME_STOCK_PIXMAP_REMOVE },
+	{ "REVERT", GNOME_STOCK_PIXMAP_REVERT },
+	{ "SAVE", GNOME_STOCK_PIXMAP_SAVE },
+	{ "SAVE_AS", GNOME_STOCK_PIXMAP_SAVE_AS },
+	{ "SCORES", GNOME_STOCK_PIXMAP_SCORES },
+	{ "SEARCH", GNOME_STOCK_PIXMAP_SEARCH },
+	{ "SPELLCHECK", GNOME_STOCK_PIXMAP_SPELLCHECK },
+	{ "SRCHRPL", GNOME_STOCK_PIXMAP_SRCHRPL },
+	{ "STOP", GNOME_STOCK_PIXMAP_STOP },
+	{ "TABLE_BORDERS", GNOME_STOCK_PIXMAP_TABLE_BORDERS },
+	{ "TABLE_FILL", GNOME_STOCK_PIXMAP_TABLE_FILL },
+	{ "TEXT_BOLD", GNOME_STOCK_PIXMAP_TEXT_BOLD },
+	{ "TEXT_BULLETED_LIST", GNOME_STOCK_PIXMAP_TEXT_BULLETED_LIST },
+	{ "TEXT_INDENT", GNOME_STOCK_PIXMAP_TEXT_INDENT },
+	{ "TEXT_ITALIC", GNOME_STOCK_PIXMAP_TEXT_ITALIC },
+	{ "TEXT_NUMBERED_LIST", GNOME_STOCK_PIXMAP_TEXT_NUMBERED_LIST },
+	{ "TEXT_STRIKEOUT", GNOME_STOCK_PIXMAP_TEXT_STRIKEOUT },
+	{ "TEXT_UNDERLINE", GNOME_STOCK_PIXMAP_TEXT_UNDERLINE },
+	{ "TEXT_UNINDENT", GNOME_STOCK_PIXMAP_TEXT_UNINDENT },
+	{ "TIMER", GNOME_STOCK_PIXMAP_TIMER },
+	{ "TIMER_STOP", GNOME_STOCK_PIXMAP_TIMER_STOP },
+	{ "TOP", GNOME_STOCK_PIXMAP_TOP },
+	{ "TRASH", GNOME_STOCK_PIXMAP_TRASH },
+	{ "TRASH_FULL", GNOME_STOCK_PIXMAP_TRASH_FULL },
+	{ "UNDELETE", GNOME_STOCK_PIXMAP_UNDELETE },
+	{ "UNDO", GNOME_STOCK_PIXMAP_UNDO },
+	{ "UP", GNOME_STOCK_PIXMAP_UP },
+	{ "VOLUME", GNOME_STOCK_PIXMAP_VOLUME },
+};
+static const gnome_map_t gnome_stock_menu_mapping [] = {
+	{ "ABOUT", GNOME_STOCK_MENU_ABOUT },
+	{ "ALIGN_CENTER", GNOME_STOCK_MENU_ALIGN_CENTER },
+	{ "ALIGN_JUSTIFY", GNOME_STOCK_MENU_ALIGN_JUSTIFY },
+	{ "ALIGN_LEFT", GNOME_STOCK_MENU_ALIGN_LEFT },
+	{ "ALIGN_RIGHT", GNOME_STOCK_MENU_ALIGN_RIGHT },
+	{ "ATTACH", GNOME_STOCK_MENU_ATTACH },
+	{ "BACK", GNOME_STOCK_MENU_BACK },
+	{ "BLANK", GNOME_STOCK_MENU_BLANK },
+	{ "BOOK_BLUE", GNOME_STOCK_MENU_BOOK_BLUE },
+	{ "BOOK_GREEN", GNOME_STOCK_MENU_BOOK_GREEN },
+	{ "BOOK_OPEN", GNOME_STOCK_MENU_BOOK_OPEN },
+	{ "BOOK_RED", GNOME_STOCK_MENU_BOOK_RED },
+	{ "BOOK_YELLOW", GNOME_STOCK_MENU_BOOK_YELLOW },
+	{ "BOTTOM", GNOME_STOCK_MENU_BOTTOM },
+	{ "CDROM", GNOME_STOCK_MENU_CDROM },
+	{ "CLOSE", GNOME_STOCK_MENU_CLOSE },
+	{ "CONVERT", GNOME_STOCK_MENU_CONVERT },
+	{ "COPY", GNOME_STOCK_MENU_COPY },
+	{ "CUT", GNOME_STOCK_MENU_CUT },
+	{ "DOWN", GNOME_STOCK_MENU_DOWN },
+	{ "EXEC", GNOME_STOCK_MENU_EXEC },
+	{ "EXIT", GNOME_STOCK_MENU_QUIT },
+	{ "FIRST", GNOME_STOCK_MENU_FIRST },
+	{ "FONT", GNOME_STOCK_MENU_FONT },
+	{ "FORWARD", GNOME_STOCK_MENU_FORWARD },
+	{ "HOME", GNOME_STOCK_MENU_HOME },
+	{ "INDEX", GNOME_STOCK_MENU_INDEX },
+	{ "JUMP_TO", GNOME_STOCK_MENU_JUMP_TO },
+	{ "LAST", GNOME_STOCK_MENU_LAST },
+	{ "LINE_IN", GNOME_STOCK_MENU_LINE_IN },
+	{ "MAIL", GNOME_STOCK_MENU_MAIL },
+	{ "MAIL_FWD", GNOME_STOCK_MENU_MAIL_FWD },
+	{ "MAIL_NEW", GNOME_STOCK_MENU_MAIL_NEW },
+	{ "MAIL_RCV", GNOME_STOCK_MENU_MAIL_RCV },
+	{ "MAIL_RPL", GNOME_STOCK_MENU_MAIL_RPL },
+	{ "MAIL_SND", GNOME_STOCK_MENU_MAIL_SND },
+	{ "MIC", GNOME_STOCK_MENU_MIC },
+#ifdef GNOME_STOCK_MENU_MIDI
+	{ "MIDI", GNOME_STOCK_MENU_MIDI },
+#endif
+	{ "NEW", GNOME_STOCK_MENU_NEW },
+	{ "OPEN", GNOME_STOCK_MENU_OPEN },
+	{ "PASTE", GNOME_STOCK_MENU_PASTE },
+	{ "PREF", GNOME_STOCK_MENU_PREF },
+	{ "PRINT", GNOME_STOCK_MENU_PRINT },
+	{ "PROP", GNOME_STOCK_MENU_PROP },
+	{ "QUIT", GNOME_STOCK_MENU_QUIT },
+	{ "REDO", GNOME_STOCK_MENU_REDO },
+	{ "REFRESH", GNOME_STOCK_MENU_REFRESH },
+	{ "REVERT", GNOME_STOCK_MENU_REVERT },
+	{ "SAVE", GNOME_STOCK_MENU_SAVE },
+	{ "SAVE_AS", GNOME_STOCK_MENU_SAVE_AS },
+	{ "SCORES", GNOME_STOCK_MENU_SCORES },
+	{ "SEARCH", GNOME_STOCK_MENU_SEARCH },
+	{ "SPELLCHECK", GNOME_STOCK_MENU_SPELLCHECK },
+	{ "SRCHRPL", GNOME_STOCK_MENU_SRCHRPL },
+	{ "STOP", GNOME_STOCK_MENU_STOP },
+	{ "TEXT_BOLD", GNOME_STOCK_MENU_TEXT_BOLD },
+	{ "TEXT_ITALIC", GNOME_STOCK_MENU_TEXT_ITALIC },
+	{ "TEXT_STRIKEOUT", GNOME_STOCK_MENU_TEXT_STRIKEOUT },
+	{ "TEXT_UNDERLINE", GNOME_STOCK_MENU_TEXT_UNDERLINE },
+	{ "TIMER", GNOME_STOCK_MENU_TIMER },
+	{ "TIMER_STOP", GNOME_STOCK_MENU_TIMER_STOP },
+	{ "TOP", GNOME_STOCK_MENU_TOP },
+	{ "TRASH", GNOME_STOCK_MENU_TRASH },
+	{ "TRASH_FULL", GNOME_STOCK_MENU_TRASH_FULL },
+	{ "UNDELETE", GNOME_STOCK_MENU_UNDELETE },
+	{ "UNDO", GNOME_STOCK_MENU_UNDO },
+	{ "UP", GNOME_STOCK_MENU_UP },
+	{ "VOLUME", GNOME_STOCK_MENU_VOLUME },
+};
+
+typedef struct {
+        const char *extension;
+        GnomeUIInfo data;
+} gnomeuiinfo_map_t;
+
+static GnomeUIInfo tmptree[] = {
+	GNOMEUIINFO_END
+};
+
+static const gnomeuiinfo_map_t gnome_uiinfo_mapping[] = {
+	{ "ABOUT_ITEM", GNOMEUIINFO_MENU_ABOUT_ITEM(NULL, NULL) },
+	{ "CLEAR_ITEM", GNOMEUIINFO_MENU_CLEAR_ITEM(NULL, NULL) },
+	{ "CLOSE_ITEM", GNOMEUIINFO_MENU_CLOSE_ITEM(NULL, NULL) },
+	{ "CLOSE_WINDOW_ITEM", GNOMEUIINFO_MENU_CLOSE_WINDOW_ITEM(NULL,NULL) },
+	{ "COPY_ITEM", GNOMEUIINFO_MENU_COPY_ITEM(NULL, NULL) },
+	{ "CUT_ITEM", GNOMEUIINFO_MENU_CUT_ITEM(NULL, NULL) },
+	{ "EDIT_TREE", GNOMEUIINFO_MENU_EDIT_TREE(tmptree) },
+	{ "END_GAME_ITEM", GNOMEUIINFO_MENU_END_GAME_ITEM(NULL, NULL) },
+	{ "EXIT_ITEM", GNOMEUIINFO_MENU_EXIT_ITEM(NULL, NULL) },
+	{ "FILES_TREE", GNOMEUIINFO_MENU_FILES_TREE(tmptree) },
+	{ "FILE_TREE", GNOMEUIINFO_MENU_FILE_TREE(tmptree) },
+	{ "FIND_AGAIN_ITEM", GNOMEUIINFO_MENU_FIND_AGAIN_ITEM(NULL, NULL) },
+	{ "FIND_ITEM", GNOMEUIINFO_MENU_FIND_ITEM(NULL, NULL) },
+	{ "GAME_TREE", GNOMEUIINFO_MENU_GAME_TREE(tmptree) },
+	{ "HELP_TREE", GNOMEUIINFO_MENU_HELP_TREE(tmptree) },
+	{ "HINT_ITEM", GNOMEUIINFO_MENU_HINT_ITEM(NULL, NULL) },
+	{ "NEW_GAME_ITEM", GNOMEUIINFO_MENU_NEW_GAME_ITEM(NULL, NULL) },
+	{ "NEW_ITEM", GNOMEUIINFO_MENU_NEW_ITEM(NULL, NULL, NULL, NULL) },
+	{ "NEW_SUBTREE", GNOMEUIINFO_MENU_NEW_SUBTREE(tmptree) },
+	{ "NEW_WINDOW_ITEM", GNOMEUIINFO_MENU_NEW_WINDOW_ITEM(NULL, NULL) },
+	{ "OPEN_ITEM", GNOMEUIINFO_MENU_OPEN_ITEM(NULL, NULL) },
+	{ "PASTE_ITEM", GNOMEUIINFO_MENU_PASTE_ITEM(NULL, NULL) },
+	{ "PAUSE_GAME_ITEM", GNOMEUIINFO_MENU_PAUSE_GAME_ITEM(NULL, NULL) },
+	{ "PREFERENCES_ITEM", GNOMEUIINFO_MENU_PREFERENCES_ITEM(NULL, NULL) },
+	{ "PRINT_ITEM", GNOMEUIINFO_MENU_PRINT_ITEM(NULL, NULL) },
+	{ "PRINT_SETUP_ITEM", GNOMEUIINFO_MENU_PRINT_SETUP_ITEM(NULL, NULL) },
+	{ "PROPERTIES_ITEM", GNOMEUIINFO_MENU_PROPERTIES_ITEM(NULL, NULL) },
+	{ "REDO_ITEM", GNOMEUIINFO_MENU_REDO_ITEM(NULL, NULL) },
+	{ "REDO_MOVE_ITEM", GNOMEUIINFO_MENU_REDO_MOVE_ITEM(NULL, NULL) },
+	{ "REPLACE_ITEM", GNOMEUIINFO_MENU_REPLACE_ITEM(NULL, NULL) },
+	{ "RESTART_GAME_ITEM", GNOMEUIINFO_MENU_RESTART_GAME_ITEM(NULL,NULL) },
+	{ "REVERT_ITEM", GNOMEUIINFO_MENU_REVERT_ITEM(NULL, NULL) },
+	{ "SAVE_AS_ITEM", GNOMEUIINFO_MENU_SAVE_AS_ITEM(NULL, NULL) },
+	{ "SAVE_ITEM", GNOMEUIINFO_MENU_SAVE_ITEM(NULL, NULL) },
+	{ "SCORES_ITEM", GNOMEUIINFO_MENU_SCORES_ITEM(NULL, NULL) },
+	{ "SELECT_ALL_ITEM", GNOMEUIINFO_MENU_SELECT_ALL_ITEM(NULL, NULL) },
+	{ "SETTINGS_TREE", GNOMEUIINFO_MENU_SETTINGS_TREE(tmptree) },
+	{ "UNDO_ITEM", GNOMEUIINFO_MENU_UNDO_ITEM(NULL, NULL) },
+	{ "UNDO_MOVE_ITEM", GNOMEUIINFO_MENU_UNDO_MOVE_ITEM(NULL, NULL) },
+	{ "VIEW_TREE", GNOMEUIINFO_MENU_VIEW_TREE(tmptree) },
+	{ "WINDOWS_TREE", GNOMEUIINFO_MENU_WINDOWS_TREE(tmptree) },
+};
+
+static int
+stock_compare (const void *a, const void *b)
+{
+        const gnome_map_t *ga = a;
+        const gnome_map_t *gb = b;
+
+        return strcmp (ga->extension, gb->extension);
+}
+
+static const char *
+get_stock_name (const char *stock_name)
+{
+        const int blen = strlen ("GNOME_STOCK_BUTTON_");
+	const int plen = strlen ("GNOME_STOCK_PIXMAP_");
+	const int mlen = strlen ("GNOME_STOCK_MENU_");
+	gnome_map_t *v;
+	gnome_map_t base;
+
+	/* check for NULL pointer */
+	if (stock_name == NULL)
+		return GNOME_STOCK_MENU_BLANK;
+        /* If an error happens, return this */
+        if (!strncmp (stock_name, "GNOME_STOCK_BUTTON_", blen)) {
+		base.extension = stock_name + blen;
+		v = bsearch (
+			     &base,
+			     gnome_stock_button_mapping,
+			     sizeof(gnome_stock_button_mapping) /
+			       sizeof(gnome_map_t),
+			     sizeof (gnome_stock_button_mapping [0]),
+			     stock_compare);
+		if (v)
+			return v->mapping;
+		else
+			return NULL;
+	} else if (!strncmp (stock_name, "GNOME_STOCK_PIXMAP_", plen)) {
+		base.extension = stock_name + plen;
+		v = bsearch (
+			     &base,
+			     gnome_stock_pixmap_mapping,
+			     sizeof(gnome_stock_pixmap_mapping) /
+			       sizeof(gnome_map_t),
+			     sizeof (gnome_stock_pixmap_mapping [0]),
+			     stock_compare);
+		if (v)
+			return v->mapping;
+		else
+			return NULL;
+	} else if (!strncmp (stock_name, "GNOME_STOCK_MENU_", mlen)) {
+		base.extension = stock_name + mlen;
+		v = bsearch (
+			     &base,
+			     gnome_stock_menu_mapping,
+			     sizeof(gnome_stock_menu_mapping) /
+			       sizeof(gnome_map_t),
+			     sizeof (gnome_stock_menu_mapping [0]),
+			     stock_compare);
+		if (v)
+			return v->mapping;
+		else
+			return NULL;
+	}
+	return NULL;
+}
+
+static gboolean
+get_stock_uiinfo (const char *stock_name, GnomeUIInfo *info)
+{
+        const int len = strlen ("GNOMEUIINFO_MENU_");
+	gnomeuiinfo_map_t *v;
+	gnomeuiinfo_map_t base;
+
+        /* If an error happens, return this */
+        if (!strncmp (stock_name, "GNOMEUIINFO_MENU_", len)) {
+		base.extension = stock_name + len;
+		v = bsearch (
+			     &base,
+			     gnome_uiinfo_mapping,
+			     sizeof(gnome_uiinfo_mapping) /
+			     sizeof(gnomeuiinfo_map_t),
+			     sizeof (gnome_uiinfo_mapping [0]),
+			     stock_compare);
+		if (v) {
+			*info = v->data;
+			return TRUE;
+		} else
+			return FALSE;
+	}
+	return FALSE;
+}
+
+static GtkWidget *
+stock_button_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+        GtkWidget *button;
+	GList *tmp;
+        char *string = NULL;
+        char *stock = NULL;
+  
+        /*
+         * This should really be a container, but GLADE is weird in this
+	 * respect.
+         * If the label property is set for this widget, insert a label.
+         * Otherwise, allow a widget to be packed
+         */
+        for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+
+                if (!strcmp(attr->name, "label")) {
+                        string = attr->value;
+                        stock = NULL;
+                } else if (!strcmp(attr->name, "stock_button")) {
+                        stock = attr->value;
+                        string = NULL;
+                }
+        }
+        if (string != NULL) {
+		guint key;
+                button = gtk_button_new_with_label("");
+		key = gtk_label_parse_uline(GTK_LABEL(GTK_BIN(button)->child),
+					    string[0] ? _(string) : "");
+		if (key)
+			gtk_widget_add_accelerator(button, "clicked",
+						   glade_xml_ensure_accel(xml),
+						   key, GDK_MOD1_MASK, 0);
+        } else if (stock != NULL) {
+		const char *tmp = get_stock_name(stock);
+		if (tmp)
+			button = gnome_stock_button(tmp);
+		else
+			button = gtk_button_new_with_label(stock);
+        } else
+                button = gtk_button_new();
+
+        return button;
+}
+
+static GtkWidget *
+color_picker_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *wid = gnome_color_picker_new();
+	GList *tmp;
+
+        for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+		
+		if (!strcmp(attr->name, "dither"))
+			gnome_color_picker_set_dither(GNOME_COLOR_PICKER(wid),
+						      attr->value[0] == 'T');
+		else if (!strcmp(attr->name, "use_alpha"))
+			gnome_color_picker_set_use_alpha(
+				GNOME_COLOR_PICKER(wid), attr->value[0]=='T');
+		else if (!strcmp(attr->name, "title"))
+			gnome_color_picker_set_title(GNOME_COLOR_PICKER(wid),
+						     _(attr->value));
+	}
+	return wid;
+}
+
+static GtkWidget *
+font_picker_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *wid = gnome_font_picker_new();
+	GList *tmp;
+	gboolean use_font = FALSE;
+	gint use_font_size = 14;
+
+        for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+		
+		if (!strcmp(attr->name, "title"))
+			gnome_font_picker_set_title(GNOME_FONT_PICKER(wid),
+						    _(attr->value));
+		else if (!strcmp(attr->name, "preview_text"))
+			gnome_font_picker_set_preview_text(
+				GNOME_FONT_PICKER(wid), attr->value);
+		else if (!strcmp(attr->name, "mode"))
+			gnome_font_picker_set_mode(GNOME_FONT_PICKER(wid),
+				glade_enum_from_string(
+					GTK_TYPE_GNOME_FONT_PICKER_MODE,
+					attr->value));
+		else if (!strcmp(attr->name, "show_size"))
+			gnome_font_picker_fi_set_show_size(
+				GNOME_FONT_PICKER(wid), attr->value[0] == 'T');
+		else if (!strcmp(attr->name, "use_font"))
+			use_font = (attr->value[0] == 'T');
+		else if (!strcmp(attr->name, "use_font_size"))
+			use_font_size = strtol(attr->value, NULL, 0);
+	}
+	gnome_font_picker_fi_set_use_font_in_label(GNOME_FONT_PICKER(wid),
+						   use_font,
+						   use_font_size);
+	return wid;
+}
+
+static GtkWidget *
+iconentry_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *wid;
+	GList *tmp;
+	gchar *hid = NULL, *title = NULL;
+	gint saved = -1;
+
+	for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+		if (!strcmp(attr->name, "title"))
+			title = attr->value;
+		else if (!strcmp(attr->name, "history_id"))
+			hid = attr->value;
+		else if (!strcmp(attr->name, "max_saved"))
+			saved = strtol(attr->value, NULL, 0);
+	}
+	wid = gnome_icon_entry_new(hid, title);
+	if (saved > 0)
+		gnome_entry_set_max_saved(
+			GNOME_ENTRY(gnome_icon_entry_gnome_entry(
+					 GNOME_ICON_ENTRY(wid))),
+			saved);
+	return wid;
+}
+
+
+static GtkWidget *
+href_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *wid;
+	GList *tmp;
+	gchar *url = "", *label = NULL;
+
+        for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+		
+		if (!strcmp(attr->name, "url"))
+			url = attr->value;
+		else if (!strcmp(attr->name, "label"))
+			label = attr->value;
+	}
+	wid = gnome_href_new(url, _(label));
+	return wid;
+}
+
+static GtkWidget *
+entry_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *wid;
+	GList *tmp;
+	gchar *history_id = NULL;
+	gint max_saved = 10;
+
+        for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+		
+		if (!strcmp(attr->name, "history_id"))
+			history_id = attr->value;
+		else if (!strcmp(attr->name, "max_saved"))
+			max_saved = strtol(attr->value, NULL, 0);
+	}
+	wid = gnome_entry_new(history_id);
+	gnome_entry_set_max_saved(GNOME_ENTRY(wid), max_saved);
+	return wid;
+}
+
+static GtkWidget *
+file_entry_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *wid;
+	GList *tmp;
+	gchar *history_id = NULL, *title = NULL;
+	gboolean directory = FALSE, modal = FALSE;
+
+        for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+		
+		if (!strcmp(attr->name, "history_id"))
+			history_id = attr->value;
+		else if (!strcmp(attr->name, "title"))
+			title = attr->value;
+		else if (!strcmp(attr->name, "directory"))
+			directory = (attr->value[0] == 'T');
+		else if (!strcmp(attr->name, "modal"))
+			modal = (attr->value[0] == 'T');
+	}
+	wid = gnome_file_entry_new(history_id, _(title));
+	gnome_file_entry_set_directory(GNOME_FILE_ENTRY(wid), directory);
+	gnome_file_entry_set_modal(GNOME_FILE_ENTRY(wid), modal);
+	return wid;
+}
+
+static GtkWidget *
+number_entry_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *wid;
+	GList *tmp;
+	gchar *history_id = NULL, *title = NULL;
+	gint saved = 10;
+
+        for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+		
+		if (!strcmp(attr->name, "history_id"))
+			history_id = attr->value;
+		else if (!strcmp(attr->name, "max_saved"))
+			saved = strtol(attr->value, NULL, 0);
+		else if (!strcmp(attr->name, "title"))
+			title = attr->value;
+	}
+	wid = gnome_number_entry_new(history_id, title);
+	if (saved > 0)
+		gnome_entry_set_max_saved(
+			GNOME_ENTRY(gnome_number_entry_gnome_entry(
+					 GNOME_NUMBER_ENTRY(wid))),
+			saved);
+	return wid;
+}
+
+static GtkWidget *
+pixmap_entry_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *wid;
+	GList *tmp;
+	gboolean preview = TRUE;
+
+        for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+		
+		if (!strcmp(attr->name, "history_id"))
+			preview = attr->value[0] == 'T'; 
+	}
+	wid = gnome_pixmap_entry_new(NULL, NULL, preview);
+	return wid;
+}
+
+static GtkWidget *
+date_edit_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *wid;
+	GList *tmp;
+	GnomeDateEditFlags flags = 0;
+	gint low = 7, high = 19;
+
+	for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+
+		if (!strcmp(attr->name, "show_time")) {
+			if (attr->value[0] == 'T')
+				flags |= GNOME_DATE_EDIT_SHOW_TIME;
+		} else if (!strcmp(attr->name, "use_24_format")) {
+			if (attr->value[0] == 'T')
+				flags |= GNOME_DATE_EDIT_24_HR;
+		} else if (!strcmp(attr->name, "week_start_monday")) {
+			if (attr->value[0] == 'T')
+				flags |= GNOME_DATE_EDIT_WEEK_STARTS_ON_MONDAY;
+		} else if (!strcmp(attr->name, "lower_hour"))
+			low = strtol(attr->value, NULL, 0);
+		else if (!strcmp(attr->name, "upper_hour"))
+			high = strtol(attr->value, NULL, 0);
+	}
+	wid = gnome_date_edit_new_flags(time(NULL), flags);
+	gnome_date_edit_set_popup_range(GNOME_DATE_EDIT(wid), low, high);
+	return wid;
+}
+
+static GtkWidget *
+clock_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *wid;
+	GList *tmp;
+	GtkClockType ctype = GTK_CLOCK_REALTIME;
+	gchar *format = NULL;
+	time_t seconds = 0;
+	gint interval = 60;
+
+        for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+		
+		if (!strcmp(attr->name, "type"))
+			ctype = glade_enum_from_string(GTK_TYPE_CLOCK_TYPE,
+						       attr->value);
+		else if (!strcmp(attr->name, "format"))
+			format = attr->value;
+		else if (!strcmp(attr->name, "seconds"))
+			seconds = strtol(attr->value, NULL, 0);
+		else if (!strcmp(attr->name, "interval"))
+			interval = strtol(attr->value, NULL, 0);
+	}
+	wid = gtk_clock_new(ctype);
+	gtk_clock_set_format(GTK_CLOCK(wid), _(format));
+	gtk_clock_set_seconds(GTK_CLOCK(wid), seconds);
+	gtk_clock_set_update_interval(GTK_CLOCK(wid), interval);
+	return wid;
+}
+
+static GtkWidget *
+animator_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *wid = gtk_type_new(gnome_animator_get_type());
+
+	return wid;
+}
+
+static GtkWidget *
+less_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *wid = gnome_less_new();
+	GList *tmp;
+
+        for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+		
+		if (!strcmp(attr->name, "font"))
+			gnome_less_set_font(GNOME_LESS(wid),
+					    gdk_font_load(attr->value));
+	}
+	return wid;
+}
+
+static GtkWidget *
+calculator_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	return gnome_calculator_new();
+}
+
+static GtkWidget *
+paper_selector_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	return gnome_paper_selector_new();
+}
+
+static GtkWidget *
+spell_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	return gnome_spell_new();
+}
+
+static GtkWidget *
+dial_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *wid = gtk_dial_new(glade_get_adjustment(info));
+	GList *tmp;
+
+        for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+
+		if (!strcmp(attr->name, "view_only"))
+			gtk_dial_set_view_only(GTK_DIAL(wid),
+					       attr->value[0] == 'T');
+		else if (!strcmp(attr->name, "update_policy"))
+			gtk_dial_set_update_policy(GTK_DIAL(wid),
+				glade_enum_from_string(GTK_TYPE_UPDATE_TYPE,
+						       attr->value));
+	}
+	return wid;
+}
+
+static GtkWidget *
+canvas_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *wid;
+	GList *tmp;
+	gboolean aa = FALSE;
+	gdouble sx1 = 0, sy1 = 0, sx2 = 100, sy2 = 100;
+	gdouble pixels_per_unit = 1;
+
+	for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+
+		if (!strcmp(attr->name, "anti_aliased"))
+			aa = attr->value[0] == 'T';
+		else if (!strcmp(attr->name, "scroll_x1"))
+			sx1 = g_strtod(attr->value, NULL);
+		else if (!strcmp(attr->name, "scroll_y1"))
+			sy1 = g_strtod(attr->value, NULL);
+		else if (!strcmp(attr->name, "scroll_x2"))
+			sx2 = g_strtod(attr->value, NULL);
+		else if (!strcmp(attr->name, "scroll_y2"))
+			sy2 = g_strtod(attr->value, NULL);
+		else if (!strcmp(attr->name, "pixels_per_unit"))
+			pixels_per_unit = g_strtod(attr->value, NULL);
+	}
+	if (aa) {
+		gtk_widget_push_colormap(gdk_rgb_get_cmap());
+		gtk_widget_push_visual(gdk_rgb_get_visual());
+		wid = gnome_canvas_new_aa();
+	} else {
+		gtk_widget_push_colormap(gdk_imlib_get_colormap());
+		gtk_widget_push_visual(gdk_imlib_get_visual());
+		wid = gnome_canvas_new();
+	}
+	gtk_widget_pop_visual();
+	gtk_widget_pop_colormap();
+	gnome_canvas_set_scroll_region(GNOME_CANVAS(wid), sx1, sy1, sx2, sy2);
+	gnome_canvas_set_pixels_per_unit(GNOME_CANVAS(wid), pixels_per_unit);
+	return wid;
+}
+
+static GtkWidget *
+iconlist_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *wid;
+	GList *tmp;
+	guint icon_width = 78;
+	GtkSelectionMode mode = GTK_SELECTION_SINGLE;
+	int row_spacing = 4, col_spacing = 2, text_spacing = 2;
+	int flags = 0;
+
+	for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+
+		if (!strcmp(attr->name, "icon_width"))
+			icon_width = strtoul(attr->value, NULL, 0);
+		else if (!strcmp(attr->name, "selection_mode"))
+			mode = glade_enum_from_string(GTK_TYPE_SELECTION_MODE,
+						      attr->value);
+		else if (!strcmp(attr->name, "row_spacing"))
+			row_spacing = strtol(attr->value, NULL, 0);
+		else if (!strcmp(attr->name, "column_spacing"))
+			col_spacing = strtol(attr->value, NULL, 0);
+		else if (!strcmp(attr->name, "text_spacing"))
+			text_spacing = strtol(attr->value, NULL, 0);
+		else if (!strcmp(attr->name, "text_editable")) {
+			if (attr->value[0] == 'T')
+				flags |= GNOME_ICON_LIST_IS_EDITABLE;
+		} else if (!strcmp(attr->name, "text_static")) {
+			if (attr->value[0] == 'T')
+				flags |= GNOME_ICON_LIST_STATIC_TEXT;
+		}
+	}
+	wid = gnome_icon_list_new_flags(icon_width, NULL, flags);
+	gnome_icon_list_set_selection_mode(GNOME_ICON_LIST(wid), mode);
+	gnome_icon_list_set_row_spacing(GNOME_ICON_LIST(wid), row_spacing);
+	gnome_icon_list_set_col_spacing(GNOME_ICON_LIST(wid), col_spacing);
+	gnome_icon_list_set_text_spacing(GNOME_ICON_LIST(wid), text_spacing);
+	return wid;
+}
+
+static GtkWidget *
+iconsel_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	return gnome_icon_selection_new();
+}
+
+static GtkWidget *
+pixmap_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *wid;
+	GList *tmp;
+	gchar *filename = NULL;
+
+	for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+
+		if (!strcmp(attr->name, "filename")) {
+			g_free(filename);
+			filename = glade_xml_relative_file(xml, attr->value);
+		}
+	}
+	if (filename)
+		wid = gnome_pixmap_new_from_file(filename);
+	else
+		wid = gtk_type_new(gnome_pixmap_get_type());
+	g_free(filename);
+	return wid;
+}
+
+static GtkWidget *
+appbar_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *wid;
+	GList *tmp;
+	gboolean has_progress = TRUE, has_status = TRUE;
+
+	for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+
+		if (!strcmp(attr->name, "has_progress"))
+			has_progress = attr->value[0] == 'T';
+		else if (!strcmp(attr->name, "has_status"))
+			has_status = attr->value[0] == 'T';
+	}
+	wid = gnome_appbar_new(has_progress, has_status,
+			       GNOME_PREFERENCES_USER);
+	return wid;
+}
+
+static GtkWidget *
+dock_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *wid = gnome_dock_new();
+	GList *tmp;
+
+	for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+
+		if (!strcmp(attr->name, "allow_floating"))
+			gnome_dock_allow_floating_items(GNOME_DOCK(wid),
+							attr->value[0] == 'T');
+	}
+
+	return wid;
+}
+
+static GtkWidget *
+dockitem_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *wid;
+	GList *tmp;
+	GnomeDockItemBehavior behaviour = GNOME_DOCK_ITEM_BEH_NORMAL;
+	GtkShadowType shadow_type = GTK_SHADOW_OUT;
+	
+	for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+
+		switch (attr->name[0]) {
+		case 'e':
+			if (!strcmp(attr->name, "exclusive"))
+				if (attr->value[0] == 'T')
+					behaviour |= GNOME_DOCK_ITEM_BEH_EXCLUSIVE;
+			break;
+		case 'l':
+			if (!strcmp(attr->name, "locked"))
+				if (attr->value[0] == 'T')
+					behaviour |= GNOME_DOCK_ITEM_BEH_LOCKED;
+			break;
+		case 'n':
+			if (!strcmp(attr->name, "never_floating")) {
+				if (attr->value[0] == 'T')
+					behaviour |= GNOME_DOCK_ITEM_BEH_NEVER_FLOATING;
+			} else if (!strcmp(attr->name, "never_vertical")) {
+				if (attr->value[0] == 'T')
+					behaviour |= GNOME_DOCK_ITEM_BEH_NEVER_VERTICAL;
+			} else if (!strcmp(attr->name, "never_horizontal")) {
+				if (attr->value[0] == 'T')
+					behaviour |= GNOME_DOCK_ITEM_BEH_NEVER_HORIZONTAL;
+			}
+			break;
+		case 's':
+			if (!strcmp(attr->name, "shadow_type"))
+				shadow_type = glade_enum_from_string(
+						GTK_TYPE_SHADOW_TYPE,
+						attr->value);
+			break;
+		}
+	}
+	wid = gnome_dock_item_new(info->name, behaviour);
+	gnome_dock_item_set_shadow_type(GNOME_DOCK_ITEM(wid), shadow_type);
+	return wid;
+}
+
+static GtkWidget *
+menubar_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *wid = gtk_menu_bar_new();
+
+	/* a kludge to remove the menu bar border if we are being packed in
+	 * a dock item */
+	if (!strcmp(info->parent->class, "GnomeDockItem"))
+		gtk_menu_bar_set_shadow_type(GTK_MENU_BAR(wid),
+					     GTK_SHADOW_NONE);
+	return wid;
+}
+
+static GtkWidget *
+menu_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	return gtk_menu_new();
+}
+
+static GtkWidget *
+pixmapmenuitem_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	/* This needs to be rewritten to handle the GNOMEUIINFO_* macros.
+	 * For now, we have something that is useable, but not perfect */
+	GtkWidget *wid;
+	GList *tmp;
+	char *label = NULL;
+	const char *stock_icon = NULL, *user_icon = NULL;
+	gboolean right = FALSE;
+
+	for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+
+		if (!strcmp(attr->name, "label"))
+			label = attr->value;
+		else if (!strcmp(attr->name, "stock_icon"))
+			stock_icon = get_stock_name(attr->value);
+		else if (!strcmp(attr->name, "right_justify"))
+			right = attr->value[0] == 'T';
+		else if (!strcmp(attr->name, "icon"))
+			user_icon = attr->value;
+	}
+	wid = gtk_pixmap_menu_item_new();
+	if (label) {
+		GtkAccelGroup *accel;
+		guint key;
+		GtkWidget *lwid = gtk_accel_label_new("");
+
+		gtk_accel_label_set_accel_widget(GTK_ACCEL_LABEL(lwid), wid);
+		gtk_misc_set_alignment(GTK_MISC(lwid), 0.0, 0.5);
+		key = gtk_label_parse_uline(GTK_LABEL(lwid), _(label));
+		if (key) {
+			accel = glade_xml_get_uline_accel(xml);
+			if (accel)
+				gtk_widget_add_accelerator(wid,
+							   "activate_item",
+							   accel, key, 0,
+							   0);
+			else {
+				/* not inside a GtkMenu -- must be on menubar*/
+				accel = glade_xml_ensure_accel(xml);
+				gtk_widget_add_accelerator(wid,
+							   "activate_item",
+							   accel, key,
+							   GDK_MOD1_MASK, 0);
+			}
+		}
+		gtk_container_add(GTK_CONTAINER(wid), lwid);
+		gtk_widget_show(lwid);
+	}
+	if (stock_icon) {
+		GtkWidget *iconw = gnome_stock_new_with_icon(stock_icon);
+		gtk_pixmap_menu_item_set_pixmap(GTK_PIXMAP_MENU_ITEM(wid),
+						iconw);
+		gtk_widget_show(iconw);
+	} else if (user_icon) {
+		gchar *iconfile = glade_xml_relative_file(xml, user_icon);
+		GtkWidget *iconw = gnome_pixmap_new_from_file(iconfile);
+
+		g_free(iconfile);
+		gtk_pixmap_menu_item_set_pixmap(GTK_PIXMAP_MENU_ITEM(wid),
+						iconw);
+		gtk_widget_show(iconw);
+	}
+	if (right)
+		gtk_menu_item_right_justify(GTK_MENU_ITEM(wid));
+	return wid;
+}
+
+static GtkWidget *
+toolbar_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *tool;
+	GList *tmp;
+	GtkOrientation orient = GTK_ORIENTATION_HORIZONTAL;
+	GtkToolbarSpaceStyle spaces = GTK_TOOLBAR_SPACE_EMPTY;
+	int space_size = 5;
+	gboolean tooltips = TRUE;
+
+	for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+
+		switch (attr->name[0]) {
+		case 'o':
+			if (!strcmp(attr->name, "orientation"))
+				orient = glade_enum_from_string(
+					GTK_TYPE_ORIENTATION, attr->value);
+			break;
+		case 's':
+			if (!strcmp(attr->name, "space_size"))
+				space_size = strtol(attr->value, NULL, 0);
+			else if (!strcmp(attr->name, "space_style"))
+				spaces = glade_enum_from_string(
+					GTK_TYPE_TOOLBAR_SPACE_STYLE,
+					attr->value);
+			break;
+		case 't':
+			if (!strcmp(attr->name, "tooltips"))
+				tooltips = attr->value[0] == 'T';
+			break;
+		}
+	}
+	tool = gtk_toolbar_new(orient,
+			       gnome_preferences_get_toolbar_labels()?
+			       GTK_TOOLBAR_BOTH : GTK_TOOLBAR_ICONS);
+	gtk_toolbar_set_space_size(GTK_TOOLBAR(tool), space_size);
+	gtk_toolbar_set_space_style(GTK_TOOLBAR(tool), spaces);
+	gtk_toolbar_set_tooltips(GTK_TOOLBAR(tool), tooltips);
+
+	gtk_toolbar_set_button_relief(GTK_TOOLBAR(tool),
+		gnome_preferences_get_toolbar_relief_btn()?GTK_RELIEF_NORMAL:
+				      GTK_RELIEF_NONE);
+	return tool;
+}
+
+static GtkWidget *
+about_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *wid;
+	GList *tmp;
+	gchar *title = gnome_app_id, *version = gnome_app_version;
+	gchar *copyright = NULL;
+	gchar **authors = NULL;
+	gchar *comments = NULL, *logo = NULL;
+
+        for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+
+		if (!strcmp(attr->name, "copyright"))
+			copyright = attr->value;
+		else if (!strcmp(attr->name, "authors")) {
+			if (authors) g_strfreev(authors);
+			authors = g_strsplit(attr->value, "\n", 0);
+		} else if (!strcmp(attr->name, "comments"))
+			comments = attr->value;
+		else if (!strcmp(attr->name, "logo"))
+			logo = attr->value;
+	}
+	wid = gnome_about_new(title, version, _(copyright),
+			      (const gchar **)authors, _(comments), logo);
+	if (authors) g_strfreev(authors);
+
+	glade_xml_set_window_props(GTK_WINDOW(wid), info);
+	glade_xml_set_toplevel(xml, GTK_WINDOW(wid));
+
+	return wid;
+}
+
+static GtkWidget *
+gnomedialog_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *win;
+	GList *tmp;
+	gboolean auto_close = FALSE, hide_on_close = FALSE;
+	gchar *title = NULL;
+
+	for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+
+		switch (attr->name[0]) {
+		case 'a':
+			if (!strcmp(attr->name, "auto_close"))
+				auto_close = attr->value[0] == 'T';
+			break;
+		case 'h':
+			if (!strcmp(attr->name, "hide_on_close"))
+				hide_on_close = attr->value[0] == 'T';
+		case 't':
+			if (!strcmp(attr->name, "title"))
+				title = attr->value;
+			break;
+		}
+	}
+	win = gnome_dialog_new(_(title), NULL);
+	gnome_dialog_set_close(GNOME_DIALOG(win), auto_close);
+	gnome_dialog_close_hides(GNOME_DIALOG(win), hide_on_close);
+
+	glade_xml_set_window_props(GTK_WINDOW(win), info);
+	glade_xml_set_toplevel(xml, GTK_WINDOW(win));
+
+	return win;
+}
+
+static GtkWidget *
+messagebox_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *win;
+	GList *tmp;
+	gchar *typename = GNOME_MESSAGE_BOX_GENERIC, *message = NULL;
+
+	for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+
+		switch (attr->name[0]) {
+		case 'm':
+			if (!strcmp(attr->name, "message"))
+				message = attr->value;
+			else if (!strcmp(attr->name, "message_box_type")) {
+				gchar *str = attr->value;
+				if (strncmp(str, "GNOME_MESSAGE_BOX_", 18))
+					break;
+				str += 18;
+				if (!strcmp(str, "INFO"))
+					typename = GNOME_MESSAGE_BOX_INFO;
+				else if (!strcmp(str, "WARNING"))
+					typename = GNOME_MESSAGE_BOX_WARNING;
+				else if (!strcmp(str, "ERROR"))
+					typename = GNOME_MESSAGE_BOX_ERROR;
+				else if (!strcmp(str, "QUESTION"))
+					typename = GNOME_MESSAGE_BOX_QUESTION;
+				else if (!strcmp(str, "GENERIC"))
+					typename = GNOME_MESSAGE_BOX_GENERIC;
+			}
+			break;
+		}
+	}
+	/* create the message box with no buttons */
+	win = gnome_message_box_new(_(message), typename, NULL);
+
+	glade_xml_set_window_props(GTK_WINDOW(win), info);
+	glade_xml_set_toplevel(xml, GTK_WINDOW(win));
+
+	return win;
+}
+
+static GtkWidget *
+app_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *win;
+	GList *tmp;
+	gchar *title = NULL;
+	gboolean enable_layout = TRUE;
+
+	for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+
+		switch (attr->name[0]) {
+		case 'e':
+			if (!strcmp(attr->name, "enable_layout_config"))
+				enable_layout = attr->value[0] == 'T';
+			break;
+		case 't':
+			if (!strcmp(attr->name, "title"))
+				title = attr->value;
+			break;
+		}
+	}
+	win = gnome_app_new(gnome_app_id, _(title));
+	gnome_app_enable_layout_config(GNOME_APP(win), enable_layout);
+
+	glade_xml_set_window_props(GTK_WINDOW(win), info);
+	glade_xml_set_toplevel(xml, GTK_WINDOW(win));
+
+	return win;
+}
+
+static GtkWidget *
+propbox_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *pbox = gnome_property_box_new();
+
+	glade_xml_set_window_props(GTK_WINDOW(pbox), info);
+	glade_xml_set_toplevel(xml, GTK_WINDOW(pbox));
+	return pbox;
+}
+
+static GtkWidget *
+druid_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	return gnome_druid_new();
+}
+
+static GdkColor *
+parse_colour(GtkWidget *wid, const gchar *tuple) {
+	static GdkColor colour;
+	gchar *tmp;
+
+	colour.red = strtoul(tuple, &tmp, 0) * 256;
+	tmp++;
+	colour.green = strtoul(tmp, &tmp, 0) * 256;
+	tmp++;
+	colour.blue = strtoul(tmp, &tmp, 0) * 256;
+	if (gdk_color_alloc(gtk_widget_get_colormap(wid), &colour))
+		return &colour;
+	else
+		return NULL;
+}
+
+static GtkWidget *
+druidpagestart_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *wid = gnome_druid_page_start_new();
+	GnomeDruidPageStart *page = GNOME_DRUID_PAGE_START(wid);
+	GList *tmp;
+
+	for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+
+		if (!strcmp(attr->name, "title"))
+			gnome_druid_page_start_set_title(page, _(attr->value));
+		else if (!strcmp(attr->name, "text"))
+			gnome_druid_page_start_set_text(page, _(attr->value));
+		else if (!strcmp(attr->name, "title_color"))
+			gnome_druid_page_start_set_title_color(page,
+					parse_colour(wid, attr->value));
+		else if (!strcmp(attr->name, "text_color"))
+			gnome_druid_page_start_set_text_color(page,
+					parse_colour(wid, attr->value));
+		else if (!strcmp(attr->name, "background_color"))
+			gnome_druid_page_start_set_bg_color(page,
+					parse_colour(wid, attr->value));
+		else if (!strcmp(attr->name, "logo_background_color"))
+			gnome_druid_page_start_set_logo_bg_color(page,
+					parse_colour(wid, attr->value));
+		else if (!strcmp(attr->name, "textbox_color"))
+			gnome_druid_page_start_set_textbox_color(page,
+					parse_colour(wid, attr->value));
+		else if (!strcmp(attr->name, "logo_image")) {
+			gchar *image =glade_xml_relative_file(xml,attr->value);
+			gnome_druid_page_start_set_logo(page,
+					gdk_imlib_load_image(image));
+			g_free(image);
+		} else if (!strcmp(attr->name, "watermark_image")) {
+			gchar *image =glade_xml_relative_file(xml,attr->value);
+			gnome_druid_page_start_set_watermark(page,
+					gdk_imlib_load_image(image));
+			g_free(image);
+		}
+	}
+	return wid;
+}
+
+static GtkWidget *
+druidpagefinish_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *wid = gnome_druid_page_finish_new();
+	GnomeDruidPageFinish *page = GNOME_DRUID_PAGE_FINISH(wid);
+	GList *tmp;
+
+	for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+
+		if (!strcmp(attr->name, "title"))
+			gnome_druid_page_finish_set_title(page,_(attr->value));
+		else if (!strcmp(attr->name, "text"))
+			gnome_druid_page_finish_set_text(page, _(attr->value));
+		else if (!strcmp(attr->name, "title_color"))
+			gnome_druid_page_finish_set_title_color(page,
+					parse_colour(wid, attr->value));
+		else if (!strcmp(attr->name, "text_color"))
+			gnome_druid_page_finish_set_text_color(page,
+					parse_colour(wid, attr->value));
+		else if (!strcmp(attr->name, "background_color"))
+			gnome_druid_page_finish_set_bg_color(page,
+					parse_colour(wid, attr->value));
+		else if (!strcmp(attr->name, "logo_background_color"))
+			gnome_druid_page_finish_set_logo_bg_color(page,
+					parse_colour(wid, attr->value));
+		else if (!strcmp(attr->name, "textbox_color"))
+			gnome_druid_page_finish_set_textbox_color(page,
+					parse_colour(wid, attr->value));
+		else if (!strcmp(attr->name, "logo_image")) {
+			gchar *image =glade_xml_relative_file(xml,attr->value);
+			gnome_druid_page_finish_set_logo(page,
+					gdk_imlib_load_image(image));
+			g_free(image);
+		} else if (!strcmp(attr->name, "watermark_image")) {
+			gchar *image =glade_xml_relative_file(xml,attr->value);
+			gnome_druid_page_finish_set_watermark(page,
+					gdk_imlib_load_image(image));
+			g_free(image);
+		}
+	}
+	return wid;
+}
+
+static GtkWidget *
+druidpagestandard_new(GladeXML *xml, GladeWidgetInfo *info)
+{
+	GtkWidget *wid = gnome_druid_page_standard_new();
+	GnomeDruidPageStandard *page = GNOME_DRUID_PAGE_STANDARD(wid);
+	GList *tmp;
+
+	for (tmp = info->attributes; tmp; tmp = tmp->next) {
+		GladeAttribute *attr = tmp->data;
+
+		if (!strcmp(attr->name, "title"))
+			gnome_druid_page_standard_set_title(page,
+							    _(attr->value));
+		else if (!strcmp(attr->name, "title_color"))
+			gnome_druid_page_standard_set_title_color(page,
+					parse_colour(wid, attr->value));
+		else if (!strcmp(attr->name, "background_color"))
+			gnome_druid_page_standard_set_bg_color(page,
+					parse_colour(wid, attr->value));
+		else if (!strcmp(attr->name, "logo_background_color"))
+			gnome_druid_page_standard_set_logo_bg_color(page,
+					parse_colour(wid, attr->value));
+		else if (!strcmp(attr->name, "logo_image")) {
+			gchar *image =glade_xml_relative_file(xml,attr->value);
+			gnome_druid_page_standard_set_logo(page,
+					gdk_imlib_load_image(image));
+			g_free(image);
+		}
+	}
+	return wid;
+}
+
+
+/* -- routines to initialise these widgets with libglade -- */
+
+static const GladeWidgetBuildData widget_data [] = {
+	{ "GtkButton",          stock_button_new,   button_build_children},
+
+	{ "GnomeColorPicker",   color_picker_new,   NULL },
+	{ "GnomeFontPicker",    font_picker_new,    NULL },
+	{ "GnomeIconEntry",     iconentry_new,      NULL },
+	{ "GnomeHRef",          href_new,           NULL },
+	{ "GnomeEntry",         entry_new,          entry_build_children },
+	{ "GnomeFileEntry",     file_entry_new,     entry_build_children },
+	{ "GnomeNumberEntry",   number_entry_new,   entry_build_children },
+	{ "GnomePixmapEntry",   pixmap_entry_new,pixmap_entry_build_children },
+	{ "GnomeDateEdit",      date_edit_new,      NULL },
+	{ "GtkClock",           clock_new,          NULL },
+	{ "GnomeAnimator",      animator_new,       NULL },
+	{ "GnomeLess",          less_new,           NULL },
+	{ "GnomeCalculator",    calculator_new,     NULL },
+	{ "GnomePaperSelector", paper_selector_new, NULL },
+	{ "GnomeSpell",         spell_new,          NULL },
+	{ "GtkDial",            dial_new,           NULL },
+	{ "GnomeCanvas",        canvas_new,         NULL },
+	{ "GnomeIconList",      iconlist_new,       NULL },
+	{ "GnomeIconSelection", iconsel_new,        NULL },
+	{ "GnomePixmap",        pixmap_new,         NULL },
+	{ "GnomeAppBar",        appbar_new,         NULL },
+
+	{ "GnomeDock",          dock_new,           dock_build_children},
+	{ "GnomeDockItem",      dockitem_new,   glade_standard_build_children},
+	{ "GtkToolbar",         toolbar_new,        toolbar_build_children},
+	{ "GtkMenuBar",         menubar_new,        menushell_build_children},
+	{ "GtkMenu",            menu_new,           menushell_build_children},
+	{ "GtkPixmapMenuItem",  pixmapmenuitem_new, menuitem_build_children},
+
+	{ "GnomeAbout",         about_new,          NULL },
+	{ "GnomeDialog",        gnomedialog_new,   gnomedialog_build_children},
+	{ "GnomeMessageBox",    messagebox_new,     messagebox_build_children},
+	{ "GnomeApp",           app_new,            app_build_children},
+	{ "GnomePropertyBox",   propbox_new,        propbox_build_children},
+
+	{ "GnomeDruid",         druid_new,          druid_build_children},
+	{ "GnomeDruidPageStart",druidpagestart_new, NULL },
+	{ "GnomeDruidPageFinish", druidpagefinish_new, NULL },
+	{ "GnomeDruidPageStandard", druidpagestandard_new,
+	  druidpage_build_children},
+	{ NULL, NULL, NULL }
+};
+
+void glade_init_gnome_widgets(void)
+{
+	glade_register_widgets(widget_data);
+}
+
+/**
+ * glade_gnome_init
+ *
+ * This function performs initialisation of glade, similar to what glade_init
+ * does (in fact it calls glade_init for you).  The difference is that it
+ * also initialises the GNOME widget building routines.
+ *
+ * As well as calling this initialisation function, GNOME programs should
+ * also link with the libglade-gnome library, which contains all the
+ * GNOME libglade stuff.
+ */
+void glade_gnome_init(void)
+{
+	static gboolean initialised = FALSE;
+
+	if (initialised) return;
+	initialised = TRUE;
+	glade_init();
+	glade_init_gnome_widgets();
+}
diff --git a/images/.cvsignore b/images/.cvsignore
new file mode 100644
index 0000000..7fab481
--- /dev/null
+++ b/images/.cvsignore
@@ -0,0 +1,3 @@
+.cvsignore
+Makefile
+Makefile.in
\ No newline at end of file
diff --git a/images/Makefile.am b/images/Makefile.am
new file mode 100644
index 0000000..197ec15
--- /dev/null
+++ b/images/Makefile.am
@@ -0,0 +1,10 @@
+pixmapdir = $(datadir)/pixmaps
+
+pixmap_DATA = \
+	gnome-info.png		\
+	gnome-error.png		\
+	gnome-question.png	\
+	gnome-warning.png	\
+	gnome-default-dlg.png
+
+EXTRA_DIST=$(pixmap_DATA)
diff --git a/images/gnome-default-dlg.png b/images/gnome-default-dlg.png
new file mode 100644
index 0000000..20dda29
Binary files /dev/null and b/images/gnome-default-dlg.png differ
diff --git a/images/gnome-error.png b/images/gnome-error.png
new file mode 100644
index 0000000..cc7830e
Binary files /dev/null and b/images/gnome-error.png differ
diff --git a/images/gnome-info.png b/images/gnome-info.png
new file mode 100644
index 0000000..757e599
Binary files /dev/null and b/images/gnome-info.png differ
diff --git a/images/gnome-question.png b/images/gnome-question.png
new file mode 100644
index 0000000..2afbc7a
Binary files /dev/null and b/images/gnome-question.png differ
diff --git a/images/gnome-warning.png b/images/gnome-warning.png
new file mode 100644
index 0000000..d6f2306
Binary files /dev/null and b/images/gnome-warning.png differ
diff --git a/libgnomeui/.cvsignore b/libgnomeui/.cvsignore
new file mode 100644
index 0000000..3ee9b28
--- /dev/null
+++ b/libgnomeui/.cvsignore
@@ -0,0 +1,38 @@
+*.la
+*.lo
+.deps
+.libs
+Makefile
+Makefile.in
+_libs
+gnome_segv
+so_locations
+.exrc
+winhints_demo
+stock_demo
+selector_demo
+ted_demo
+animator_demo
+dock_demo
+test-recently-used
+test-file-saver
+mdi_demo
+gnome.defs
+gnometypebuiltins.h
+gnometypebuiltins_evals.c
+gnometypebuiltins_ids.c
+gnometypebuiltins_vars.c
+gnome-unknown-stubs.c
+gnome-unknown-skels.c
+gnome-unknown-common.c
+gnome-unknown.h
+gnome-corba-rexec-stubs.c
+gnome-corba-rexec-skels.c
+gnome-corba-rexec-common.c
+gnome-corba-rexec.h
+gnome-remote-bootstrap
+gnome-rexec-server
+gnomemarshal.h
+gnomemarshal.c
+stamp-gnomemarshal.h
+libgnomeui-2.0.pc
diff --git a/libgnomeui/AUTHORS b/libgnomeui/AUTHORS
new file mode 100644
index 0000000..072aa0e
--- /dev/null
+++ b/libgnomeui/AUTHORS
@@ -0,0 +1,24 @@
+Cesar Miquel <miguel df uba ar>
+Horacio J. Peña <horape compendium com ar>
+Ettore Perazzoli <ettore comm2000 it>
+Miguel de Icaza <miguel nuclecu unam mx>
+Federico Mena <federico nuclecu unam mx>
+Chris Toshok <toshok hungry com>
+Elliot Lee <sopwith redhat com>
+Marc Ewing <marc redhat com>
+Jaka Mocnik <jaka mocnik kiss uni-lj si>
+Justin Maurer <justin openprojects net>
+Havoc Pennington <hp pobox com>
+Andrew Veliath <andrewtv usa net>
+George Lebl <jirka 5z com>
+Carsten Schaar <nhadcasc fs-maphy uni-hannover de>
+Jay Painter <jpaint serv net>
+Ian Main <imain gimp org>
+David Abilleira Freijeiro <odaf nexo es>
+James Henstridge <james daa com au>
+Tom Tromey <tromey cygnus com>
+Dirk Lutjens <dirk luedi oche de>
+Jonathan Blandford <jrb redhat com>
+Mark Crichton <mcrichto purdue edu>
+Stuart Parmenter <pavlov pavlov net>
+
diff --git a/libgnomeui/ChangeLog b/libgnomeui/ChangeLog
new file mode 100644
index 0000000..339dad4
--- /dev/null
+++ b/libgnomeui/ChangeLog
@@ -0,0 +1,3308 @@
+2001-04-26  Martin Baulig  <baulig suse de>
+
+	* gnome-app-util.[ch], gnome-dialog-util.[ch], gnome-dialog.[ch],
+	gnome-messagebox.[ch], gnome-propertybox.[ch], gnome-scores.[ch]:
+	Removed; they are already in libcompat, but now all code which was
+	still using them is fixed.
+
+2001-04-26  Martin Baulig  <baulig suse de>
+
+	* libgnomeui.h: Don't Include gnome-app-helper.h,
+	gnome-dialog.h, gnome-dialog-util.h, gnome-messagebox.h,
+	gnome-propertybox.h and gnome-scores.h.
+
+2001-04-26  Martin Baulig  <baulig suse de>
+
+	* gnome-stock.c: Comment out everything which was using code from
+	gnome-messagebox.[ch] and gnome-propertybox.[ch].
+
+2001-04-25  Martin Baulig  <baulig suse de>
+
+	* gnome-about.[ch]: Use GtkDialog, not GnomeDialog.
+	(GnomeAbout, GnomeAbout): Derive from GtkDialog, not GnomeDialog.
+
+	* gnome-client.[ch]: Likewise.
+	(gnome_client_save_any_dialog, gnome_client_save_error_dialog): Take
+	a GtkDialog as argument, not a GnomeDialog.
+
+	* gnome-helpsys.c, gnome-href.c, gnome-icon-entry.c, gnome_segv.c: Use
+	GtkDialog, not GnomeDialog.
+
+	* gnome-window.c (gnome_window_set_icon, gnome_window_set_icon_from_file):
+	Moved here from gnome-app-util.c.
+
+2001-04-25  Martin Baulig  <baulig suse de>
+
+	* gnome-app-helper.[ch], gnome-app-util.[ch], gnome-cursors.[ch],
+	gnome-dialog-util.[ch], gnome-dialog.[ch], gnome-dock*.[ch],
+	gnome-messagebox.[ch], gnome-preferences.[ch], gnome-propertybox.[ch],
+	gnome-scores.[ch], gnome-stock.[ch], gtkpixmapmenuitem.[ch]:
+	Copied all these files to libcompat/libgnomeui/; they're still here for
+	a while so that we won't break compilation here.
+
+2001-04-25  Martin Baulig  <baulig suse de>
+
+	* gnome-dock*.[ch]: Attention! These files have been moved to libbonoboui
+	and renamed to bonobo-dock*.[ch]. We'll provide a compatibility wrapper with
+	#defines in libgnomecompat soon, but at the moment I don't want to break the
+	build here since libbonoboui doesn't work yet.
+	If you do any changes in these files here, your work will be lost !
+
+2001-04-24  Martin Baulig  <baulig suse de>
+
+	* gnome-dock-item.c, gnome-dock-layout.c: Don't use gnome-macros.h.
+
+	* gnome-dock-item.c (gnome_dock_item_grab_pointer): Use gdk_cursor_new().
+	instead of gnome_stock_cursor_new().
+
+2001-04-24  Martin Baulig  <baulig suse de>
+
+	* gnome-init.c: Reflect latests GnomeProgram API changes.
+
+2001-04-19  Michael Meeks  <michael ximian com>
+
+	* gnome-init.c (libgnomeui_constructor): setup the properties to
+	be the same as the code that sets them - using the defines.
+
+2001-04-19  Michael Meeks  <michael ximian com>
+
+	* libgnomeui.h: add gnome-canvas-init.h
+
+	* gnome-canvas-init.h: add.
+
+	* Makefile.am: add gnome-canvas-init.[ch]
+
+2001-04-18  Martin Baulig  <baulig suse de>
+
+	* gnome-init.c (libbonoboui_module_init): Added libbonoboui initialization here;
+	no "real" code here yet.
+	(libgnomeui_module_requirements): Added libbonobo.
+
+2001-04-18  Martin Baulig  <baulig suse de>
+
+	* gnome-icon-entry.c: Comment out gnome_uri_list_extract_filenames() to make
+	it compile [FIXME].
+
+2001-04-17  Martin Baulig  <baulig suse de>
+
+	* gnome-init.c: Started to use GnomeProgram properties.
+
+2001-04-17  Martin Baulig  <baulig suse de>
+
+	* Makefile.am: Don't compile gnome-gconf.c and oafgnome.c.
+
+	* gnome-app-helper.c (gnome_gconf_get_gnome_libs_settings_relative):
+	#define this to NULL (FIXME).
+
+	* gnome-gconf.h (gnome_gconf_module_info): Removed external declaration; this
+	is in libgnome now.
+	(GNOME_GCONF_INIT): Removed.
+	(gnome_get_gconf_client): Made this a macro which uses
+	gnome_program_get_gconf_client (gnome_program_get ()).
+
+2001-04-15  Martin Baulig  <baulig suse de>
+
+	* libgnomeuiP.h (gnome_i18n_get_language_list, gnome_i18n_get_preferred_language):
+	Provide external declarations for these functions here [FIXME: broken].
+
+2001-04-15  Martin Baulig  <baulig suse de>
+
+	* gnome-i18nP.h: Removed; #include <libgnomebase/gnome-i18n.h> instead.
+
+2001-04-14  Martin Baulig  <baulig suse de>
+
+	* gnome-init.h (gtk_module_info): Removed external declaration.
+	(LIBGNOMEUI_INIT): Removed #define.
+
+	* gnome-init.c (libgnome_module_requires): Added libgnomecanvas_module_info.
+	(gtk_module_info): Removed GTK+ init code; this is already in libgnomecanvas.
+	(BUILD_UNUSED_LEGACY_CODE): Removed all code which was #ifdef'ed out by this.
+
+2001-04-11  Martin Baulig  <baulig suse de>
+
+	* gnome-helpsys.c (gnome_help_view_find_help_id): Use
+	gnome_program_locate_file() instead of gnome_datadir_file().
+	(gnome_help_path_resolve, gnome_help_app_topics): Use
+	gnome_program_locate_file() instead of gnome_help_file().
+
+	* gnome-init.c (libgnomeui_rc_parse): Use gnome_program_locate_file()
+	instead of gnome_datadir_file().
+
+	* gnome-icon-selector.c (gnome_icon_selector_add_defaults): Use
+	gnome_program_locate_file() to get a list of all pixmap dirs.
+
+	* gnome-about.c (gnome_about_load_logo): Use
+	gnome_program_locate_file() instead of gnome_pixmap_file().
+	* gnome-app-helper.c (create_pixmap): Likewise.
+	* gnome-app-util.c (gnome_window_set_icon_from_file): Likewise.
+	* gnome-stock.c (gnome_stock_pixmap_entry_get_gdk_pixbuf): Likewise.
+
+2001-04-11  Martin Baulig  <baulig suse de>
+
+	* gnome-messagebox.c: For images which we install in ../images/,
+	use an absolute filename using GNOMEUIPIXMAPDIR.
+
+Sun Mar 25 15:26:29 2001  George Lebl <jirka 5z com>
+
+	* gnome-icon-item.c: use the editable interface to get the values
+	  instead of grabbing it directly of the structure, however added
+	  FIXME's since that needs to be tested and verified
+
+Sun Mar 25 03:04:13 2001  George Lebl <jirka 5z com>
+
+	* gnome-app-helper.c, gnome-file-saver.c, gnome-gconf.c,
+	  gnome-recently-used.c, gnome-selector.c:  GConfClient
+	  is no longer a GtkObject, so use g_object_* methods on
+	  it and not gtk_object_
+
+Sun Mar 25 02:13:43 2001  George Lebl <jirka 5z com>
+
+	* gnome-app-helper.c: gconf_client is now a GObject, not GtkObject
+
+	* gnome-dock-band.c, gnome-dock-item.c, gnome-dock.c,
+	  gnome-druid-page.c, gnome-druid.c: synthesizing GDK_EXPOSE events
+	  apparently no longer works, what's more all this expose stuff is
+	  now handled by GtkContainer itself, so remove the redundant code
+	  and call the parent handler from expose functions that are left
+
+	* gnome-dock-item.c:  First check if "is_floating" property exists
+	  before settings it
+
+	* gnome-init.c:  the gtk module require libgnome module, the
+	  libgnomeui module requires the client and gconf modules
+
+Sat Mar 24 23:55:06 2001  George Lebl <jirka 5z com>
+
+	* gnome-animator.c: include string.h to fix 64bitness
+
+	* wap-textfu.c: fix a couple of uninitialized warnings
+
+2001-03-24  Martin Baulig  <baulig suse de>
+
+	* gnome-boxed.defs (GnomeCanvasPoints): Removed.
+	(GnomeSelectorAsyncHandle): This is refcounted and has
+	no init function.
+
+2001-03-24  Martin Baulig  <baulig suse de>
+
+	* maketypes.awk, makeenums.pl: Removed, we now use
+	gnome-maketypes.awk and gnome-makeenums.pl which gets
+	installed by libgnome-2.
+
+2001-03-24  Martin Baulig  <baulig suse de>
+
+	* gnome-app-helper.c (setup_uline_accel): Commented out
+	for the moment [FIXME: fix this].
+
+	* gnome-i18nP.h: New file. Copied from libgnome-2.
+	[FIXME: We really need to find a solution for this; glib has
+	its own, gtk+ has its own, ....]
+
+2001-03-21  Martin Baulig  <baulig suse de>
+
+	The canvas is now in its own libgnomecanvas-2 top-level module.
+
+	* gnome-canvas*.[ch]: Removed, moved to the new libgnomecanvas-2
+	module.
+
+2001-03-20  Martin Baulig  <baulig suse de>
+
+	* libgnomeui.h (GNOMEUI_INIT): Don't #define this here.
+
+	* gnome-init.c (GNOMEUI_INIT): Moved #define here and don't
+	#include "libgnomeui.h".
+
+2001-03-14  Martin Baulig  <baulig suse de>
+
+	* libgnomeui.h: #include "libgnomeui/gnome-icon-selector.h" instead
+	of gnome-icon-sel.h.
+
+	* gnome-icon-sel.[ch]: Moved to libcompat.
+
+2001-02-26  Martin Baulig  <baulig suse de>
+
+	* gnome-icon-entry.c (PROP_IS_PIXMAP_ENTRY): New boolean construction
+	only property. If this is true, the widget will have the look&feel of
+	the old GnomePixmapEntry.
+
+2001-02-26  Martin Baulig  <baulig suse de>
+
+	* gnome-selector.c (PROP_WANT_DEFAULT_BEHAVIOUR): New boolean property.
+	If it's set, then each of the GnomeSelector subclasses will show its
+	default behaviour, ie. whether it'll have a "Browse" button etc.
+	The default for this property is TRUE so that you can now do a
+	g_object_new (GNOME_TYPE_ICON_ENTRY, ....) and get an object which
+	actually looks like a GnomeIconEntry.
+
+	If you want to set any of PROP_ENTRY_WIDGET, PROP_SELECTOR_WIDGET,
+	PROP_BROWSE_DIALOG, PROP_USE_DEFAULT_ENTRY_WIDGET,
+	PROP_USE_DEFAULT_SELECTOR_WIDGET, PROP_USE_DEFAULT_BROWSE_DIALOG,
+	PROP_WANT_BROWSE_BUTTON, PROP_WANT_CLEAR_BUTTON or
+	PROP_WANT_DEFAULT_BUTTON in g_object_new(), you need to set
+	PROP_WANT_DEFAULT_BEHAVIOUR to FALSE to have this take effect.
+
+2001-02-26  Martin Baulig  <baulig suse de>
+
+	For GnomeSelector and its subclasses, you can now use g_object_new()
+	to create a new instance.
+
+	* gnome-selector.h (GnomeSelectorClass): Added `do_construct' method.
+	(gnome_selector_construct): Removed.
+	(gnome_selector_do_construct): New function, only for subclasses.
+
+	* gnome-selector.c (PROP_ENTRY_WIDGET, PROP_SELECTOR_WIDGET,
+	PROP_BROWSE_DIALOG, PROP_USE_DEFAULT_ENTRY_WIDGET,
+	PROP_USE_DEFAULT_SELECTOR_WIDGET, PROP_USE_DEFAULT_BROWSE_DIALOG,
+	PROP_WANT_BROWSE_BUTTON, PROP_WANT_CLEAR_BUTTON,
+	PROP_WANT_DEFAULT_BUTTON, PROP_AUTO_SAVE_HISTORY, PROP_AUTO_SAVE_ALL):
+	New construction only properties.
+	(PROP_DIALOG_TITLE, PROP_HISTORY_ID): Made these construction, but not
+	construction only properties.
+	(gnome_selector_class_init): Connect gnome_selector_constructor() to
+	the GObject's `constructor' method and do_construct_handler() to the
+	GnomeSelector's `do_construct' method.
+
+	* gnome-entry.h (gnome_entry_new_flags): Removed.
+	(gnome_entry_construct, gnome_entry_construct_full): Removed.
+
+	* gnome-file-selector.h (gnome_file_selector_new): Removed `flags'
+	argument.
+	(gnome_file_selector_new_custom, gnome_file_selector_construct):
+	Removed.
+
+	* gnome-icon-selector.h (gnome_icon_selector_new): Removed `flags'
+	argument.
+	(gnome_icon_selector_new_custom, gnome_icon_selector_construct):
+	Removed.
+
+	* gnome-icon-entry.h (gnome_icon_entry_construct): Removed.
+	(gnome_icon_entry_construct_full): Removed.
+
+2001-02-26  Martin Baulig  <baulig suse de>
+
+	* gnome-stock.c: Back to the API described below.
+
+	* gnome-stock.h
+	(GnomeStockPixmapEntryWidget, GnomeStockPixmapEntryGPixmap): Removed.
+	(GnomeStockPixmapEntryImlib): Renamed to GnomeStockPixmapEntryPixbuf.
+	(GnomeStockPixmapEntryImlibScaled): Renamed
+	to GnomeStockPixmapEntryPixbufScaled.
+
+	(GnomeStockPixmapEntryAny): Removed `width' and `height' fields;
+	added `ref_count' and `pixbuf'.
+
+	(gnome_stock_pixmap_register, gnome_stock_pixmap_change,
+	gnome_stock_pixmap_checkfor, gnome_stock_transparent_window,
+	gnome_stock_pixmap_gdk): Replaced `const char *subtype' argument
+	with `GtkStateType state'.
+
+	* gnome-stock.h: Put this back to the API of GNOME 1.x.
+	- reverted to the state of gnome-libs stable.
+	- removed USE_NEW_GNOME_STOCK conditional; only use the
+	USE_NEW_GNOME_STOCK code.
+
+	* gnome-stock.[ch]: Tagged them as `before-martin-reverted-it'.
+
+2001-02-25  Martin Baulig  <baulig suse de>
+
+	* gnome-entry.[ch]: Move all deprecated functions to libcompat.
+	* gnome-icon-entry.[ch]: Likewise.
+	* gnome-appbar.[ch]: Likewise.
+
+2001-02-23  Martin Baulig  <baulig suse de>
+
+	* gnome-entry.c (gnome_entry_set_text, gnome_entry_get_text):
+	New convenience functions; we need to add them to gnome-libs stable
+	shortly after GNOME 1.4 as well so that people can start to smoothly
+	migrate their apps to the new API.
+
+2001-02-23  Martin Baulig  <baulig suse de>
+
+	* libgnomeui-2.0.pc.in: New file.
+	* Makefile.am: Install pkg-config file.
+
+2001-02-23  Martin Baulig  <baulig suse de>
+
+	* gnome-calculator.[ch], gnome-number-entry.[ch]: Moved to
+	libcompat for the moment. This should be anywhere, but not in
+	libgnomeui; GnomeCalculator should be a Bonobo component.
+
+2001-02-23  Martin Baulig  <baulig suse de>
+
+	* gnome-pixmap-entry.[ch]: Moved to libcompat. This has been
+	obsoleted by GnomeIconEntry.
+
+2001-02-23  Martin Baulig  <baulig suse de>
+
+	* gnome-icon-entry.c (gnome_icon_entry_set_preview_size):
+	New function; inspired by gnome_pixmap_entry_set_preview_size().
+	Added "preview_x" and "preview_y" properties.
+
+2001-02-23  Martin Baulig  <baulig suse de>
+
+	* gnome-file-entry.[ch]: Moved to libcompat. This has been replaced
+	by GnomeFileSelector.
+
+	* gnome-gconf.c (gnome_file_entry_get/set): Removed.
+	(gnome_icon_entry_get/set): Removed.
+	(gnome_pixmap_entry_get/set): Removed.
+	(gnome_entry_get/set): Removed.
+
+2001-02-23  Martin Baulig  <baulig suse de>
+
+	* gnome-canvas.h (GnomeCanvas): Removed `cc' field, GdkColorContext
+	no longer exists in GTK+.
+
+	* gnome-canvas.c (gnome_canvas_get_color): Use gdk_rgb_find_color()
+	instead of gdk_color_context_get_pixels().
+	(gnome_canvas_get_color_pixel): Likewise.
+
+	* gnome-canvas-line.c (gnome_canvas_line_get/set_property):
+	Use gdk_rgb_find_color() instead of gdk_color_context_query_color().
+
+	* gnome-canvas-polygon.c (gnome_canvas_polygon_get/set_property):
+	Use gdk_rgb_find_color() instead of gdk_color_context_query_color().
+	(get_color_value): Likewise.
+
+	* gnome-canvas-rect-ellipse.c (gnome_canvas_re_get/set_property):
+	Use gdk_rgb_find_color() instead of gdk_color_context_query_color().
+	(get_color_value): Likewise.
+
+	* gnome-canvas-text.c (gnome_canvas_text_get/set_property):
+	Use gdk_rgb_find_color() instead of gdk_color_context_query_color().
+
+2001-02-23  Martin Baulig  <baulig suse de>
+
+	* Makefile.am (INCLUDES): Added $(PANGO_CFLAGS).
+	(libgnomeui_2_la_LDFLAGS, LDADD): Added $(PANGO_LIBS).
+
+	* gnome-init.c (gtk_pre_args_parse): Comment out setting
+	of `gtk_debug_flags' which has gone from GTK+.
+
+2001-01-15  Darin Adler  <darin eazel com>
+
+	* gnome-canvas.h: Fixed comment that was "improved" back
+	in June 1999 to say the coordinates are world coordinates, when they
+	are actually canvas coordinates (code and Havoc's book both say so).
+
+	* gnome-init.c: (gnome_register_options):
+	Mark names of sections of the popt table with _() for translation.
+	(gnome_init_with_popt_table): Use a _("%s options") template for
+	the main option section by default. This is better than what we had
+	before, translation-wise, bug not perfect. A real fix should change
+	the API of gnome_init_with_popt_table so that the entire
+	"xxx options" string would be localized in the main program.
+
+2001-02-06  Alexander Larsson  <alexl redhat com>
+
+	* gnome-canvas-text.[ch]:
+	Pango port of gnome-canvas-text. Death to SuckFont, use the pango
+	freetype module instead.
+
+2001-02-15  Darin Adler  <darin eazel com>
+
+	* gnome-init.c: (gnome_register_options): Use N_, not
+	_, for the popt table names. 
+	(gnome_init_with_popt_table): Remove g_free that screws up the
+	popt option section.
+
+2001-01-29  John Harper  <jsh eazel com>
+
+	* gnome-client.c (client_save_yourself_callback): commented out
+	the code that sets client->save_successfull (sic) to false if
+	the "save_yourself" signal wasn't emitted.
+
+	Since the KDE session manager actually cares about the
+	`success' field of the SaveYourselfDone message (unlike
+	gnome-session, which totally ignores it), the original logic
+	had the effect of making KDE unable to shutdown when any GNOME
+	apps that haven't connected to the "save_yourself" signal are
+	running.
+
+	Perhaps a better fix would be to set success = False only if
+	"save_session" wasn't emitted _and_ there are functions
+	connected to this signal. But since it makes no difference to
+	gnome-session I'll leave it for now..
+
+2001-01-05  John Harper  <jsh eazel com>
+
+	* gnome-canvas.c (gnome_canvas_focus_in,
+	gnome_canvas_focus_out): added code to set and unset the
+	HAS_FOCUS flag (which all focusable widgets should do). Without
+	this patch the canvas (and thus the focused canvas item) will
+	not receive focus out events
+
+2000-12-29  Jaka Mocnik  <jaka gnu org>
+
+	* gnome-mdi.[ch] (gnome_mdi_get_children, gnome_mdi_get_windows):
+	new public functions for retrieving the list of children/windows.
+	(gnome_mdi_get_*): constified return arguments where deemed
+	appropriate.
+
+2000-12-28  Martin Baulig  <baulig suse de>
+
+	* gnome-selector.h (gnome_selector_get_history_id): New function.
+	(gnome_selector_set_history_id): New function.
+	(GnomeSelector): Added "get_selection_mode" signal.
+	
+	* gnome-selector.c (PROP_DIALOG_TITLE, PROP_HISTORY_ID,
+	PROP_SELECTION_MODE): New properties.
+
+	* gnome-icon-list.c (gnome_icon_list_get_selection_mode):
+	New function.
+
+2000-12-28  Martin Baulig  <baulig suse de>
+
+	* gnome-color-picker.c: GtkArg -> GParam.
+
+	* gnome-icon-item.c (ItiPrivate): Removed
+	"use_broken_event_handling".
+
+	* gnome-icon-list.c (gil_set_arg, gil_get_arg): Removed; this
+	was unused.
+
+2000-12-20  Martin Baulig  <baulig suse de>
+
+	* gnome-canvas-rect-ellipse.c: GtkArg -> GParam.
+
+	* gnome-canvas-polygon.c: GtkArg -> GParam.
+
+	* gnome-canvas-lines.c: GtkArg -> GParam.
+
+2000-12-20  Martin Baulig  <baulig suse de>
+
+	* gnome-canvas-image.[ch]: Removed.  This has been obsolated by
+	gnome-canvas-pixbuf.c and wasn't even compiled for a longer time.
+
+Sun Dec 17 14:28:05 2000  George Lebl <jirka 5z com>
+
+	* gnome-calculator.c: attach INV button in the same way as other
+	  buttons
+
+2000-12-15  Martin Baulig  <baulig suse de>
+
+	* gnome-canvas.c (gnome_canvas_item_class_init): Added "parent"
+	property to the GnomeCanvasItem.
+
+2000-12-15  Martin Baulig  <baulig suse de>
+
+	The big "while it is raining outside" cleanup to make it
+	work with the latest glib/gtk+ API:
+
+	- moved GtkArg to GParam.
+	- removed all calls to gtk_object_class_add_signals().
+	- reflect latest GtkNotebook changes.
+
+	* gnome-animator.c, gnome-app.c, gnome-appbar.c,
+	gnome-calculator.c, gnome-canvas-pixbuf.c, gnome-canvas-text.c,
+	gnome-canvas-widget.c, gnome-canvas.c, gnome-client.c,
+	gnome-color-picker.c, gnome-dateedit.c, gnome-dialog.c,
+	gnome-ditem-edit.c, gnome-dock-band.c, gnome-dock-item.c,
+	gnome-dock.c, gnome-druid-page.c, gnome-druid.c, gnome-entry.c,
+	gnome-file-entry.c, gnome-font-picker.c, gnome-helpsys.c,
+	gnome-href.c, gnome-icon-item.c, gnome-icon-list.c, gnome-mdi.c,
+	gnome-paper-selector.c, gnome-pixmap.c, gnome-pouch.c,
+	gnome-propertybox.c, gnome-recently-used.c, gnome-roo.c,
+	gnome-selector.c, gnome-textfu.c, wap-textfu.c: here.
+
+	* gnome-canvas.h (gnome_canvas_newv): Removed.
+	(gnome_canvas_constructv): Removed.
+
+2000-12-13  Martin Baulig  <baulig suse de>
+
+	* gnome-selector.h (GnomeSelector): Merged the "clear" and
+	"clear_default" signals into one "clear" signal with a `list_id'
+	argument; added `list_id' argument to the "update_uri_list"
+	signal; changed the `defaulpt' argument of the "get_uri_list"
+	signal to a `list_id' argument; added new "add_uri_list" signal;
+	merged the "add_file" and "add_file_default" signals into one
+	"add_file" signal with a `list_id' argument; did the same for the
+	"add_directory" and "add_uri" signals.
+	(gnome_selector_add_file): Changed the `gboolean defaultp' argument
+	into `guint list_id'.
+	(gnome_selector_add_directory): Likewise.
+	(gnome_selector_add_uri): Likewise.
+	(gnome_selector_get_uri_list): Likewise.
+	(gnome_selector_clear): Likewise.
+	(gnome_selector_update_uri_list): Added `guint list_id' argument.
+	(gnome_selector_add_uri_list): New function.
+	(gnome_selector_set_uri_list): Removed.
+	(gnome_selector_set_to_defaults): Removed.
+
+	* gnome-selectorP.h (_gnome_selector_register_list): New function.
+        (_gnome_selector_unregister_list): New function.
+	(_gnome_selector_get_list_by_id): New function.
+	(_gnome_selector_deep_copy_slist): New function.
+	(_gnome_selector_deep_free_slist): New function.
+
+	* gnome-selector.c: All handling with the lists now takes place here
+	and not in the subclasses.
+
+2000-12-08  Martin Baulig  <baulig suse de>
+
+	* animator_demo.c, dock_demo.c, mdi_demo.c, stock_demo.c,
+	selector_demo.c, winhints_demo.c: Moved to ../demos/.
+
+	* test-file-saver.c, test-recently-used.c: Moved to
+	../demos/.
+
+2000-12-08  Martin Baulig  <baulig suse de>
+
+	* gnome-selectorP.h: Move everything but the prototypes of the
+	functions which are useful for subclasses into gnome-selector.c.
+	This mean that gnome-selectorP.h is now a semi-private header file;
+	you may need to include it if you want to write your own
+	GnomeSelector subclass.
+
+2000-12-08  Martin Baulig  <baulig suse de>
+
+	* gnome-selector.h (GnomeSelector): The argument of the
+	"set_selection_mode" signal is a GtkSelectionMode, not a gint.
+
+	* gnome-selector.h (GnomeSelector): Renamed "get_filename" signal
+	to "get_uri" and "set_filename" signal to "set_uri".
+	(gnome_selector_get_filename): Renamed to gnome_selector_get_uri().
+	(gnome_selector_set_filename): Renamed to gnome_selector_set_uri().
+
+	* gnome-selector.h (GnomeSelector): Renamed "update_file_list" signal
+	to "update_uri_list"; removed `directory_listp' argument from the
+	"get_file_list" signal and renamed it to "get_uri_list".
+	(gnome_selector_get_file_list): Removed `directory_listp' and renamed
+	to gnome_selector_get_uri_list().
+	(gnome_selector_set_file_list): Removed `directory_listp' and renamed
+	to gnome_selector_set_uri_list().
+	(gnome_selector_update_file_list): Renamed to
+	gnome_selector_update_uri_list().
+
+	* gnome-selectorP.h (GnomeSelectorPrivate): Removed
+	`gconf_dir_list_key', `gconf_file_list_key', `default_dir_list',
+	`default_file_list', `dir_list', `file_list' and added
+	`gconf_uri_list_key', `gconf_default_uri_list_key',
+	`default_uri_list', `uri_list'.
+
+Wed Dec 06 22:16:29 2000  George Lebl <jirka 5z com>
+
+	* gnome-app-helper.c, gnome-gconf.c, gnome-mdi-child.c: Cleanup,
+	  setup the gconf client data for the dockitems so that we don't crash
+	  on destroy.  I've realized there are severe problems in the
+	  GnomeUIInfo code wrt the new signal stuff and some unexplained
+	  crashes.  Fun.
+
+Wed Dec 06 20:35:48 2000  George Lebl <jirka 5z com>
+
+	* gnome-mdi.[ch], gnome-mdi-child.[ch], gnome-mdiP.h,
+	  gnome-mdi-generic-child.[ch]:  fix yesterday's braindamages and
+	  make signals actually work on the MDI, us ehte boilerplate on these
+	  and some cleanup.  The virtual pointers in the child are now not
+	  defined by the generic child typedef, since the pointers in the
+	  class structure should NOT include the data pointers.  Plus it is
+	  a style issue that they should be explicit types rather then
+	  typedefs.
+
+2000-12-06  Martin Baulig  <baulig suse de>
+
+	* gnome-selector.h (GnomeSelector): Added "add_uri" and
+	"add_uri_default" signals.
+	(gnome_selector_add_uri): New function.
+
+	* gnome-vfs-util.c (file_read_callback): If result == GNOME_VFS_OK,
+	but bytes_read == 0, we're at the end of the file.
+
+2000-12-06  Martin Baulig  <baulig suse de>
+
+	* gnome-selector.c: Asyncify the "set_filename" signal and the
+	gnome_selector_set_filename() function.
+
+	* gnome-entry.c (set_entry_text_handler): `gentry->_priv->entry'
+	may be NULL if we don't have the default entry widget.
+
+2000-12-06  Martin Baulig  <baulig suse de>
+
+	* gnome-canvas.c (gnome_canvas_get_color): The 7th argument of
+	gdk_color_context_get_pixels() is now a gulong.
+	(gnome_canvas_get_color_pixel): Likewise.
+
+	* wap-textfu.h: #include <libxml/parser.h> instead of
+	<gnome-xml/parser.h>
+
+Wed Dec 06 04:49:27 2000  George Lebl <jirka 5z com>
+
+	* gnome-mdi.c: correctly get default return values for emitting
+	  signals by using g_signal_emitv directly.  Also fix a precondition
+	  on remove_view.
+
+Wed Dec 06 02:57:06 2000  George Lebl <jirka 5z com>
+
+	* gnome-animator.c: check for nulls.  If no current frame draw black.
+
+Wed Dec 06 01:55:24 2000  George Lebl <jirka 5z com>
+
+	* gnome-animamtor.c, gnome-canvas.c, gnome-dock-band.c, 
+	  gnome-dock-item.c, gnome-dock.c, gnome-druid-page.c,
+	  gnome-druid.c, gnome-roo.c, gnome-textfu.c, gtkpixmapmenuitem.c,
+	  wap-textfu.c:  There is no draw signal/method anymore, it's
+	  all handled by exposes now so all the draw stuff is now gone.
+
+2000-12-05  Martin Baulig  <baulig suse de>
+
+	* gnome-selectorP.h (_gnome_selector_async_handle_removed): Renamed
+	to _gnome_selector_async_handle_destroy().
+	(_gnome_selector_async_handle_removed): New internal function, does
+	the opposite of _gnome_selector_async_handle_add().
+	(_gnome_selector_async_handle_completed): Don't call the callback
+	function here, only mark the async handler as completed and call
+	_gnome_selector_async_handle_destroy() if there are no pending sub-
+	operations.
+
+2000-12-04  Martin Baulig  <baulig suse de>
+
+	Started to make GnomeSelector fully asynchronous.
+
+	* gnome-boxed.defs (GnomeSelectorAsyncHandle): Added.
+
+	* gnome-selector.h (GnomeSelectorAsyncHandle): New type.
+	(GnomeSelectorAsyncType, GnomeSelectorAsyncFunc): New types.
+	(GnomeSelector): Changed the return type of the "check_filename"
+	and "check_directory" signals to void; added additional
+	GnomeSelectorAsyncHandle parameter to the "check_filename",
+	"check_directory", "add_file" and "add_file_default", "add_directory"
+	and "add_directory_default" signals; removed the "do_add_*" signals.
+	(gnome_selector_check_filename, gnome_selector_check_directory,
+	gnome_selector_add_file, gnome_selector_add_directory): Changed return
+	type to void; added three new arguments for async handling.
+	(gnome_selector_prepend_file, gnome_selector_append_file,
+	gnome_selector_prepend_director, gnome_selector_append_directory):
+	Removed.
+	(gnome_selector_cancel_async_operation): New global function.
+	(gnome_selector_async_handle_ref, gnome_selector_async_handle_unref):
+	New global functions.
+
+	* gnome-selectorP.h (GnomeSelectorPrivate): Added `async_ops' field.
+	(_gnome_selector_async_handle_get, _gnome_selector_async_handle_add):
+	New internal functions.
+	(_gnome_selector_async_handle_completed): New internal function.
+	(_gnome_selector_async_handle_remove): Likewise.
+	(_gnome_selector_async_handle_set_error): Likewise.
+
+	* gnome-icon-entry.c (set_filename_handler): Comment out call to
+	gnome_selector_check_filename [FIXME].
+
+	* gnome-vfs-util.c (file_read_callback): Ignore GNOME_VFS_OK since
+	this may be called multiple times; on GNOME_VFS_ERROR_EOF, get the
+	pixbuf and call load_done(GNOME_VFS_OK).
+
+Sun Dec 03 16:37:42 2000  George Lebl <jirka 5z com>
+
+	* gnome-calculator.c:  Add a bunch of xcalc like shortcuts
+
+2000-12-03  Martin Baulig  <baulig suse de>
+
+	* Makefile.am (INCLUDES): Added $(WARN_CFLAGS).
+
+	* libgnomeuiP.h (gnome_type_init): Added external declaration.
+
+2000-12-01  Martin Baulig  <baulig suse de>
+
+	A bunch of changes to make if work with the latest libraries
+	again; some of them contain FIXMEs so if someone is feeling boring
+	sometimes ....
+
+	* gnomemarshal.list, gnomemarshal-main.c: New files.
+	* libgnomeuiP.h: New file.
+
+	- removed all signal marshalling functions and use the new
+	glib-genmarshal tool to autogen them.
+
+	- gdk_pixbuf_new_from_file() now takes an additional GError **
+	argument [FIXME: We should find a good way to deal with such
+	error conditions].
+
+	- the GObject's "set_param" signal has a changed prototype; it now
+	takes a `const GConfValue *' instead of a `GConfValue *'.
+
+	- gnome_client_notify_add() - the prototype of the callback function
+	has changed.
+
+	- GtkEditable has changed a lot; I #ifdef'ed most of this stuff out,
+	someone with a clue must have a look at this.
+
+	* gnome-boxed.defs (GdkImlibImage): Removed.
+	(GnomeCanvasPoints): Added copy/free functions.
+
+	* maketypes.awk, gnometypes.c: Merged the boxed stuff from GTK+.
+
+Sat Nov 04 22:14:02 2000  George Lebl <jirka 5z com>
+
+	* merge some patches from stable, here are the entries:
+	2000-10-12  Ettore Perazzoli  <ettore helixcode com>
+
+		* gnome-dock-item.c: New args "preferred_width" and
+		  "preferred_height".
+		(gnome_dock_item_class_init): Set them up.
+		(gnome_dock_item_get_arg): Handle them.
+		(check_guint_arg): New helper function.
+		(get_preferred_width): New helper function.
+		(get_preferred_height): New helper function.
+
+		* gnome-dock-band.c (check_guint_arg): New helper function
+		  to get a guint arg only if it exists.
+		(gnome_dock_band_size_request): Calculate the
+		  max_preferred_width by checking the "preferred_width" or
+		  "preferred_height" arg through `check_guint_arg'.
+		(size_allocate_small): Changed the policy a bit so that we
+		  allocate the max_preferred_width if possible.
+
+	2000-09-24  Jody Goldberg <jgoldberg home com>
+
+		* gnome-dock-item.c (gnome_dock_item_set_floating) : New
+		  function.  set the is_floating argument of the child
+		  if the child supports it.
+		(gnome_dock_item_detach) : Use it here.
+		(gnome_dock_item_attach) : Use it here.
+		(gnome_dock_item_remove) : Use it here.
+
+	2000-09-23  Jody Goldberg <jgoldberg home com>
+
+		* gnome-dock-item.c (gnome_dock_item_set_orientation) : Do
+		  not hard code the use of gtktoolbar. any widget that has
+		  an 'orientation' argument will do.
+		(gnome_dock_item_add) : Ditto.
+
+2000-10-15  Chema Celorio  <chema celorio com>
+ 
+ 	* gnome-window.c (gnome_window_toplevel_set_title): new file &
+ 	function. apps should use it to set the tile, so that we can
+ 	have a unform way of setting the window properties (only the
+ 	title for now)
+ 	* gnome-window.h: new file
+ 
+2000-10-15  Martin Baulig  <baulig suse de>
+
+	* gnome-gconf.c: Reflect latest GConf API changes.
+	* gnome-app-helper.c: Likewise.
+	* gnome-selector.c: Likewise.
+
+2000-10-03  Martin Baulig  <baulig suse de>
+
+	* gnome-ditem-edit.c (fill_easy_page): Connect to the "changed" signal
+	of the GnomeSelector rather than using the no longer existant
+	gnome_icon_entry_gtk_entry().
+
+2000-10-03  Martin Baulig  <baulig suse de>
+
+	* gnome-icon-entry.h (GnomeIconEntry): Derive from GnomeFileSelector.
+	(gnome_icon_entry_construct_full): New function.
+	(gnome_icon_entry_get_icon_selector): New function.
+	(gnome_icon_entry_get_filename): This function is now deprecated; use
+	the GnomeSelector functions instead.
+	(gnome_icon_entry_set_filename): Likewise.
+	(gnome_icon_entry_set_pixmap_subdir): This function is now deprecated.
+	(gnome_icon_entry_set_browse_dialog_title): Removed.
+	(gnome_icon_entry_set_history_id): Removed.
+	(gnome_icon_entry_pick_dialog): Removed.
+ 	(gnome_icon_entry_set_icon): Removed.
+	(gnome_icon_entry_gnome_file_entry): Removed.
+	(gnome_icon_entry_gnome_entry): Removed.
+	(gnome_icon_entry_gtk_entry): Removed.
+
+	* gnome-icon-entry.c: Totally rewrote this file from scratch.
+	(ientry_directory_filter_func): This checks whether it's a valid
+	image file [NOTE: when this is invoked from "add_file" signal handler,
+	we already have the GnomeVFSFileInfo so this won't block; that's why
+	it's better to set a filter on the GnomeFileSelector instead of
+	overriding the "check_filename" handle.]
+	(gnome_icon_entry_construct_full): Create a GnomeVFSDirectoryFilter
+	which uses the ientry_directory_filter_func() and call
+	gnome_file_selector_add_filter() on it.
+
+2000-10-03  Martin Baulig  <baulig suse de>
+
+	* gnome-entry.h (GnomeEntry): Derive this from GnomeSelector and
+	exclude all deprecated functions is GNOME_EXCLUDE_DEPRECATED is
+	defined.
+	(gnome_entry_gtk_entry): This function is now deprecated.
+	(gnome_entry_set_history_id): Likewise.
+	(gnome_entry_get_history_id): Likewise.
+	(gnome_entry_prepend_history): Deprecated; use the corresponding
+	GnomeSelector function instead.
+	(gnome_entry_append_history): Likewise.
+	(gnome_entry_load_history): Likewise.
+	(gnome_entry_clear_history): Likewise.
+	(gnome_entry_save_history): Likewise.
+
+	* gnome-entry.c (gnome_entry_new_flags): New function.
+	(gnome_entry_construct_full): New function.
+
+2000-09-30  Martin Baulig  <baulig suse de>
+
+	* gnome-stock.c: Switch to inline pixbufs.
+	(default_entries_data): Removed "width" and "height".
+	(stock_pixmaps): Use gdk_pixbuf_new_from_inline() with the
+	inline pixbufs from pixmaps/gnome-stock-pixbufs.h.
+
+	* pixmaps/copyright.txt: New file. This will be inserted at
+	the head of the generated gnome-stock-pixbufs.h.
+	* pixmaps/Makefile.am: Create gnome-stock-pixbufs.h from the
+	PNG images using GTK+ 2.0's make-inline-pixbuf script.
+
+2000-09-28  Martin Baulig  <baulig suse de>
+
+	* gnome-font-selector.[ch]: Moved to libcompat.
+
+Thu Sep 28 03:35:44 2000  George Lebl <jirka 5z com>
+
+	* gnome-client.c, gnome-init.c, gnome_segv.c: use g_getenv
+	  instead of getenv.
+
+2000-09-25  Iain Holmes  <iain helixcode com>
+
+	* gnome-propertybox.c (dialog_clicked_cb): Check all the pages for a 
+	change, as opposed to just the current one.
+	Use the GNOME_CLASS_BOILERPLATE macro for the type creation.
+
+2000-09-24  Iain Holmes  <iain helixcode com>
+
+	* gnome-recently-used.c: fix glaring compile errors/warnings :)
+
+	* test-recently-used.c (item_changed): Change gnome_recent_document_get
+	to gnome_recent_document_peek.
+	(add_to_menu): Same.
+
+Sun Sep 24 04:24:34 2000  George Lebl <jirka 5z com>
+
+	* gnome-canvas-pixmap.c: fix glaring compile errors/warnings
+
+	* gnome-recently-used.c: Use GParam.  Separate the construction
+	  into neccessary and lazy part.  The lazy part is the actual
+	  loading of data.  This way we can do the parameter setting
+	  in a minorly saner way, thus fixing problems with
+	  improperly made objects, AND the ability to change app_specific
+	  later (or twice) without leaks (though that's not really useful).
+
+2000-09-24  Iain Holmes  <iain helixcode com>
+
+	* gnome-canvas-pixbuf.c: Add an ANCHOR argument, like GnomeCanvasImage
+	has.
+
+Sat Sep 23 17:34:17 2000  George Lebl <jirka 5z com>
+
+	* gnome-calculator.c: use the gnome_i18n_push/pop_c_numeric_locale
+
+	* gnome-font-picker.c, gnome-popup-help.c: include gnome-i18nP.h
+	  and not gnome-i18n.h
+
+Mon Sep 18 20:16:45 2000  George Lebl <jirka 5z com>
+
+	* gnome-recently-used.[ch]: use boilerplates, minor cleanup,
+	  some precondition checks.  Add the maximum number of documents,
+	  implemented simplistically, when adding check if there is more
+	  then the <key-prefix>/MaximumSize (or 30 by default), and remove
+	  the oldest entries until there is this.  This really doesn't
+	  need to be perfect, a simple solution is better here I think.
+	  Also rename gnome_recent_document_get to gnome_recent_document_peek
+
+Mon Sep 18 19:02:34 2000  George Lebl <jirka 5z com>
+
+	* gnome-dateedit.c: use the boilerplate macros and switch to GParam
+
+2000-09-16  Martin Baulig  <baulig suse de>
+
+	* gnome-gconf.c: Very quick hack just to make it compile.
+
+2000-09-16  Martin Baulig  <baulig suse de>
+
+	* gnome-selector.h (GnomeSelector):
+	- renamed the "do_add" signal to "do_add_file".
+	- added "do_add_file_default", "do_add_directory" and
+	"do_add_directory_default" signals.
+	- added "get_file_list" signal.
+
+	* gnome-selector.c:
+	(add_file_handler): Renamed to `do_add_file_handler' and use
+	the "do_add_file" signal instead of the "add_file" one.
+	(add_file_default_handler): Likewise.
+	(add_directory_handler): Likewise.
+	(add_directory_default_handler): Likewise.
+	(update_file_list_handler): Removed.
+	(get_file_list_handler): New; implemnt "get_file_list" handler.
+
+	* gnome-selectorP.h (GnomeSelectorPrivate): Removed `total_list'
+	and `default_total_list' fields.
+
+	* gnome-file-selector.c (update_file_list_handler): Removed.
+	(add_directory_async_handler): Call the parent handler of the
+	"do_add_directory" signal.
+
+2000-09-16  Martin Baulig  <baulig suse de>
+
+	* gnome-file-selector.c: Use the boilerplate macros.
+
+2000-09-16  Martin Baulig  <baulig suse de>
+
+	* gnome-file-selector.c: Started to asyncify this file.
+	(gnome_file_selector_add_filter): New function; this lets you
+	specify a GnomeVFSDirectoryFilter which is used when adding
+	files etc.
+	(gnome_file_selector_clear_filter): New function; removes the
+	filter again.
+	(add_file_handler): Implement handler for the "add_file" signal
+	of the GnomeFileSelector; call gnome_vfs_async_get_file_info()
+	with `add_file_async_cb' as async callback function.
+	(add_file_async_cb): New static function;
+	- if the URI is a directory, gnome_selector_add_directory() it.
+	- otherwise, apply the filter to it and, if it passes, emit the
+	"do_add" signal.
+	(add_directory_handler): Implement handler for the "add_directory"
+	signal; call gnome_vfs_async_load_directory_uri() on it with
+	`add_directory_async_cb' as async callback function.
+	(add_directory_async_cb): New static function; apply the filter
+	to each of the files and emit the "add_file" signal for those who
+	pass it [FIXME: at this point we already have the GnomeVFSFileInfo
+	for the files, so basically we can filter here and emit "do_add"
+	directly  ....?].
+	(activate_entry_handler): Just call gnome_selector_add_file();
+	this should "do the right thing" even if it's actually a directory
+	[FIXME: should we better async get the file info here and then
+	distinguish between files and directories?].
+	(check_filename_handler): If a filter is set, use it. Note
+	that this is still a synchronous operation (because of the
+	return value) and may block.
+	(check_directory_handler): This is a synchronous operation
+	as well and thus may block.
+
+2000-09-11  Martin Baulig  <baulig suse de>
+
+	* gnome-file-selector.h (GnomeFileSelector): Derive from GnomeEntry.
+
+	* gnome-file-selector.c (GnomeFileSelectorPrivate): Removed the
+	`combo' and `entry' fields.
+	(get_entry_text_handler, set_entry_text_handler): Removed.
+	(history_changed_handler): Removed.
+	(entry_activated_cb): Moved all its functionality into the
+	`activate_entry_handler' and then removed this function.
+	(gnome_file_selector_construct): Don't create the entry widget here
+	but pass GNOME_SELECTOR_DEFAULT_ENTRY_WIDGET down to the parent class.
+
+2000-09-16  Martin Baulig  <baulig suse de>
+
+	* gnome-selector.h (GnomeSelector):
+	- Added `position' argument to the "add", "add_default",
+	"add_directory" and "add_directory_default" signals; this is
+	0 for the start of the list, -1 for the end of it or any position
+	in the middle.
+	- Added "do_load" and "stop_loading" signals which are supposed
+	to invoke asynchronous operations.
+	(gnome_selector_add_file, gnome_selector_add_directory): New
+	functions which allow you to insert a file or directory at an
+	arbitrary position.
+	(gnome_selector_prepend_file,gnome_selector_append_file): Call
+	gnome_selector_add_file() with apropriate arguments.
+	(gnome_selector_prepend_directory,gnome_selector_append_directory):
+	Call gnome_selector_add_directory() with apropriate arguments.
+	(gnome_selector_add_file): Just emit the ADD_FILE/
+	ADD_FILE_DEFAULT signal here.
+	(gnome_selector_add_directory): Just emit the ADD_DIRECTORY/
+	ADD_DIRECTORY_DEFAULT signal here.
+
+Fri Sep 15 18:49:34 2000  George Lebl <jirka 5z com>
+
+	* gnome-animator.c, gnome-helpsys.c, gnome-selector.c: don't set
+	  parent_class again, it's set in get_type in the boilerplates
+
+	* gnome-ditem-edit.c: use boilerplates, remove PanelApplet type
+	  from the default set of types.  1) it's not supported natively
+	  by gnome-libs, and 2) it may go away in 2.0 panel, depending
+	  on how these things will be handled
+
+Thu Sep 14 19:44:26 2000  George Lebl <jirka 5z com>
+
+	* gnome-app.c: use GParam
+
+	* gnome-helpsys.c: use g_object_set/new since we now use GParam here
+
+Thu Sep 14 18:45:54 2000  George Lebl <jirka 5z com>
+
+	* gnome-file-entry.c, gnome-icon-entry.c, gnome-textfu.c: use
+	  g_path_get_dirname instead of g_dirname
+
+2000-09-14  Martin Baulig  <baulig suse de>
+
+	* gnome-vfs-util.h (GnomeGdkPixbufLoadHandle): Renamed to
+	GnomeGdkPixbufAsyncHandle.
+	(GnomeGdkPixbufLoadCallback): Added GnomeGdkPixbufAsyncHandle
+	argument.
+	(GnomeGdkPixbufDoneCallback): New callback typedef.
+	(gnome_gdk_pixbuf_new_from_uri_async): Added
+	GnomeGdkPixbufDoneCallback callback function argument which
+	is called when we're done reading the pixbuf.
+
+Wed Sep 13 21:42:25 2000  George Lebl <jirka 5z com>
+
+	* gnome-helpsys.c: make it compile
+
+Wed Sep 13 00:45:34 2000  George Lebl <jirka 5z com>
+
+	* gnome-helpsys.c: Switch to GParam, some reformatting, a hack
+	  for getting style/priority right with the GParam (they need to
+	  be set in unison).  Also used the boilerplate macros
+
+2000-09-12  Martin Baulig  <baulig suse de>
+
+	* gnome-selector.c: Switch to GParam and use the boilerplate
+	macros.
+
+2000-09-12  Martin Baulig  <baulig suse de>
+
+	* selector-demo.c: Added GnomeIconEntry.
+
+2000-09-12  Martin Baulig  <baulig suse de>
+
+	* gnome-selector.h (GnomeSelector): Added "get_filename" signal.
+	(gnome_selector_get_filename): New function.
+	(gnome_selector_set_filename): Allow the filename to be NULL.
+
+	* gnome-selector.c (gnome_selector_class_init): Added the missing
+	"changed" signal.
+	(get_filename_handler): Default is to use "get_entry_text".
+	(set_filename_handler): Allow the filename to be NULL.
+
+2000-09-11  Martin Baulig  <baulig suse de>
+
+	* gnome-icon-selector.c (icon_selected_cb): New callback function;
+	emits the "selection_changed" signal on the GnomeSelector.
+	(gnome_icon_selector_construct): Connect the `icon_selected_cb' to
+	the "select_icon" and "unselect_icon" signals of the GnomeIconList.
+
+	* gnome-selector.h (GnomeSelector): Added "selection_changed" signal.
+
+Sun Sep 10 19:47:07 2000  George Lebl <jirka 5z com>
+
+	* gnome-href.[ch]: Switch to GParam, and bunches of reformatting
+	  to more match standard gnome style.
+
+	* gnome-animator.c: use PARAM_ instead of ARG_ for the enum and
+	  match up the names and remove an unused enum value.
+
+Sun Sep 10 03:29:56 2000  George Lebl <jirka 5z com>
+
+	* gnome-dateedit.c:  Make sure that input to gtkcalendar is legal
+	  to avoid warnings.  Also use gtk_widget_size_request for the
+	  calendar to make sure that the size is always querried.
+
+	* gnome-druid.c:  When going to the next page find the next
+	  visible page, rather then just any old next page.
+
+2000-09-06  Martin Baulig  <baulig suse de>
+
+	* gnome-selector.c: Removed all references to actual files and
+	directories; both the file and directory lists may contain arbitrary
+	text entries which don't need to be actual file or directory names.
+	This is very important to allow us to subclass GnomeSelector for things
+	which aren't files or directories; for instance a GnomeNumberSelector.
+	(check_filename_handler, check_directory_handler): Always return TRUE.
+	(set_filename_handler): Call gnome_selector_check_filename() rather than
+	actually checking whether it's a regular file.
+	(add_file_handler, add_file_default_handler): Likewise.
+	(_add_directory_handler): Removed; such things belong into
+	gnome-file-selector.c.
+	(add_directory_handler, add_directory_default_handler): Call
+	gnome_selector_check_directory() and add it to the directory list on
+	success; don't attempt to actually readdir() the directory.
+
+	* gnome-file-selector.c: This now contains the gnome-vfs code to
+	deal with files and directories.
+	(add_directory_handler, add_directory_default_handler): Added; call
+	_add_directory_handler() with appropriate `defaultp' argument.
+	(_add_directory_handler): Added.
+
+	* gnome-icon-selector.c (append_an_icon): Use
+	gnome_gdk_pixbuf_new_from_uri() instead of gdk_pixbuf_new_from_file().
+
+2000-09-06  Martin Baulig  <baulig suse de>
+
+	* gnome-vfs-util.[ch]: New files.
+	These three functions are shamelessy stolen from Nautilus; they
+	use gnome-vfs to load the pixbuf so the URI doesn't need to be
+	a local file.
+	(gnome_gdk_pixbuf_new_from_uri): New function.
+	(gnome_gdk_pixbuf_new_from_uri_async): New function.
+	(gnome_gdk_pixbuf_new_from_uri_cancel): New function.
+
+2000-09-05  Martin Baulig  <baulig suse de>
+
+	* Makefile.am (gnome_headers): Removed duplicate gnome-textfu.h.
+
+2000-09-05  Martin Baulig  <baulig suse de>
+
+	* gnome-about.c (gnome_about_get_type): Removed since we now use
+	the boilerplate macros.
+
+Sat Sep 02 02:31:03 2000  Iain Holmes <terrorist gegl org>
+
+	* gnome-about.c (gnome_about_init): Allocate the _priv structure.
+	Neatened all the functions up. Fix memory leaks. Removed needs
+	for AboutInfo structure.
+
+	* gnome-animator.c: Added GParams.
+
+	* gtk-clock.c (gtk_clock_new): Calls gtk_clock_construct.
+
+	* stock-demo.c: Help menu not right justified.
+
+	* gnome-app.c (gnome_app_set_help_view_orientation): Something wrong
+	with the callback, so use the dock-items orientation value instead.
+
+	* gnome-helpsys.c: Use wap-textfu instead of textfu.
+	(help_view_select_help_cb): Removed grab, set cursor to WHATISIT,
+	removed sanity check. Fixed a leak too.
+
+	* wap-textfu.[ch]: Replacements for gnome-textfu. Need renamed once
+	they work to gnome-textfu.[ch].
+
+Sat Sep 02 03:25:46 2000  George Lebl <jirka 5z com>
+
+	* gnome-druid.c: Eek, yet more minor fixes.  close_on_cancel
+	  now works properly.  Also kill the window when the druid
+	  is destroyed so that we don't require the caller to actually
+	  keep an extra pointer around.  This is just sugar, things like
+	  this are allowed.
+
+Sat Sep 02 03:12:20 2000  George Lebl <jirka 5z com>
+
+	* gnome-druid.c: improve docs for append/prepend/insert
+
+Sat Sep 02 01:57:10 2000  George Lebl <jirka 5z com>
+
+	* gnome-druid.[ch]: Add some sugar API.  Normally a druid is inside
+	  a window, so there is now a gnome_druid_new_with_window function
+	  which does this and a few other minor things for you.  Also
+	  document the _new function.
+
+	* gnome-helpsys.c: Eek, forgot to commit this earlier.  This uses
+	  GError for the gnome_url functions now.
+
+Fri Sep 01 03:33:09 2000  George Lebl <jirka 5z com>
+
+	* *.h:  All _get_type functions are now G_GNUC_CONST to make
+	  things just a tad better optimized on gcc.
+
+Fri Sep 01 02:58:58 2000  George Lebl <jirka 5z com>
+
+	* gnome-animator.c: fix memory leaks, remove old FIXMEs and minor
+	  cleanup
+
+	* gnome-druid.c: Make sure the non-visible button is never the
+	  default one.
+
+Thu Aug 31 15:21:38 2000  George Lebl <jirka 5z com>
+
+	* gnome-icon-sel.[ch]: use the new gnome-macros stuff and general
+	  minor cleanup
+
+Wed Aug 30 21:59:43 2000  George Lebl <jirka 5z com>
+
+	* gnome-animator.c, gnome-cursors.c, gnome-textfu.c: make
+	  dependencies more fine grained then <gnome.h>
+
+	* gnome-textfu.c, gnome-animator.c, gnome-app.c: minor cleanups,
+	  use gnome-macros.h
+
+	* gnome-druid-page-edge.[ch], gnome-druid-page-standard.[ch]:
+	  add an argument so that we can add the toplevel watermark like
+	  rp3 has.  Plus a couple of docs added/updated.
+
+2000-08-30  Federico Mena Quintero  <federico helixcode com>
+
+	* gnome-dock-item.c (gnome_dock_item_size_allocate): Fix unsigned
+	vs. signed confusion, as always.
+
+Wed Aug 30 04:34:07 2000  George Lebl <jirka 5z com>
+
+	* gnome-href.[ch]: use the gnome-macros.h macros
+
+Wed Aug 30 04:06:22 2000  George Lebl <jirka 5z com>
+
+	* gnome-druid-page-edge.c, gnome-druid-page-standard.c:  Be anal
+	  and use (double) instead of gfloat and use it in all the places
+	  where doubles are set on the canvas.  Also never show the logoframe
+	  when no logo is set.
+
+Wed Aug 30 03:51:08 2000  George Lebl <jirka 5z com>
+
+	* gnome-druid.c: in size_allocate/size_request, use the border_width
+	  of the container as the actual border width.
+
+	* gnome-macros.h, Makefile.am, gnome-about.[ch],
+	  gnome-calculator.[ch], gnome-less.[ch], gnome-druid.c,
+	  gnome-druid-page.c, gnome-druid-page-edge.c,
+	  gnome-druid-page-standard.c:
+	  Steal ideas from nautilus about the standard boilerplate macros,
+	  and use them in a few objects.  These promote consistent
+	  implementation of the _get_type functions, the presence of
+	  parent_class, always checking for implementation of a method before
+	  dereferencing it, and most of all prevent typos.  Just to prove a
+	  point, one such typo/problem was fixed in GnomeLess.  Also while
+	  I was at it I made these files only include the neccessary headers
+	  instead of <gnome.h>, to make more fine grained dependencies to
+	  speed the build up and prevent unneccessary rebuilds.
+
+Fri Aug 25 02:14:34 2000  George Lebl <jirka 5z com>
+
+	* gnome-druid-page.[ch], gnome-druid-page-standard.[ch],
+	  gnome-druid-page-edge.[ch]:  Remove my brain damanges of last
+	  commit while keeping the fixes.  The canvas moved back into the
+	  widgets, the sidebar_shown thing was eliminated.  The thin blue
+	  lines on standard pages are gone as well.
+
+Thu Aug 24 03:29:46 2000  George Lebl <jirka 5z com>
+
+	* Makefile.am: a bit of makefile cleanup
+
+Thu Aug 24 02:23:51 2000  George Lebl <jirka 5z com>
+
+	* gnome-animator.c: fix compile errors
+
+	* gnome-app-helper.c: put in FIXMEs and comment out the gnome_help
+	  stuff as that's now in compatlib and thus not used in libgnomeui
+
+	* gnome-druid-page.[ch], gnome-druid-page-edge.[ch],
+	  gnome-druid-page-standard.[ch]:  Try to unify/clean up code more.
+	  Add an option to hide the sidebar.  Make it possible to make
+	  a page use antialiased canvas optionally.  Move vanvas creation
+	  to GnomeDruidPage.  Other minor cleanups and doc fixes.
+
+	* gnome-druid.c: fix final removing of children
+
+	* gnome-icon-entry.c, gnome-icon-sel.c, gnome_segv.c:
+	  s/g_path_basename/g_path_get_basename/ (/me smacks self)
+
+	* gnome-roo.c, mdi_demo.c: warning fixes
+
+Tue Aug 22 19:15:15 2000  George Lebl <jirka 5z com>
+
+	* gnome-druid*.[ch]: Minor cleanups, fix memory leaks on pages,
+	  use "fontset" only, add more precondition checks, make text
+	  always be valid.  Probably doesn't compile, I'll fix it up later
+	  or martin will.  (Not that gnome-libs really compiles now anyway)
+
+Sun Aug 13 17:07:15 2000  George Lebl <jirka 5z com>
+
+	* gnome-animator.c: Add REVERT and RETAIN modes of animation.
+
+2000-08-07  Karl Eichwalder  <ke suse de>
+
+	* gnome-ditem-edit.c (fill_dnd_page): Beautify string.
+
+2000-08-06  Martin Baulig  <baulig suse de>
+
+	Added a default directory and file list to the GnomeSelector; this
+	has two benefits: first of all, you can have a "Default..." button
+	and when you click on it the file and directory lists are restored
+	to the original. The second thing is that we can save and later load
+	the current file and directory lists (for instance, when you click
+	on "Browse..." and use the browse dialog to add things).
+
+	* gnome-selector.h (GNOME_SELECTOR_AUTO_SAVE_HISTORY): New flag.
+	(GNOME_SELECTOR_AUTO_SAVE_ALL): New flag; if set, both the file
+	and directory list are saved using GConf.
+	(GNOME_SELECTOR_WANT_DEFAULT_BUTTON): New flag; if set, a "Default"
+	button is created which sets file and directory list to the defaults
+	when clicked.
+	(GNOME_SELECTOR_USER_FLAGS): #define this to be a mask of flags which
+	can be set in the _new() functions (G_S_AUTO_SAVE_HISTORY etc.).
+	(GnomeSelectorClass): Added `clear_default', `add_file_default' and
+	`add_directory_default' signals.
+	(gnome_selector_prepend_file): Added `defaultp' argument.
+	(gnome_selector_append_file): Likewise.
+	(gnome_selector_get_file_list): Likewise.
+	(gnome_selector_set_file_list): Likewise.
+	(gnome_selector_clear): Likewise.
+	(gnome_selector_prepend_directory): Likewise.
+	(gnome_selector_append_directory): Likewise.
+	(gnome_selector_get_directory_list): Likewise.
+	(gnome_selector_set_directory_list): Likewise.
+	(gnome_selector_set_to_defaults): New function.
+
+	* gnome-file-selector.h (gnome_file_selector_new): Added `flags'
+	argument.
+	* gnome-icon-selector.h (gnome_icon_selector_new): Likewise.
+
+2000-08-06  Martin Baulig  <baulig suse de>
+
+	* gnome-selector.c: Support history loading and saving.
+	(gnome_selector_get_history_id, gnome_selector_set_history_id):
+	Removed; it makes not much sense to change this after the widget
+	has been created.
+
+Fri Aug 04 05:28:14 2000  George Lebl <jirka 5z com>
+
+	* gnome-helpsys.[ch]:  Add a way to get at the GtkTooltips
+	  object used in gnome_widget_set_tooltip and add some precondition
+	  checks.
+
+Fri Aug 04 05:08:26 2000  George Lebl <jirka 5z com>
+
+	* gnome-helpsys.[ch]:  In the grand tradition of most probably
+	  non-compiling code, I'll make it compile when I get to my machine.
+	  I added private poiner and moved all the crap in there and done
+	  a tiny bit of cleanup and tried to understand what this beast
+	  does.
+
+2000-08-03  Martin Baulig  <baulig suse de>
+
+	You can now use a customize entry widget in the GnomeSelector.
+
+	* gnome-selector.c (gnome_selector_construct): Added `entry_widget'
+	argument and added `GNOME_SELECTOR_DEFAULT_ENTRY_WIDGET' enumeration
+	value to the flags.
+	(GnomeSelectorClass): Added `get_entry_text', `set_entry_text',
+	`activate_entry' and `history_changed' signals.
+	(gnome_selector_get/set_entry_text): New functions.
+	(gnome_selector_activate_entry): New function.
+	(gnome_selector_get/set_history_id): New functions.
+	(gnome_selector_get/set_history_length): New functions.
+	(gnome_selector_append/prepend_history): New functions.
+	(gnome_selector_get/set_history): New functions.
+	(gnome_selector_load/save_history): New functions.
+	(gnome_selector_clear_history): New function.
+
+	* gnome-file-selector.c: Use a GtkCombo as default entry widget.
+
+	* gnome-icon-selector.c: Derive from GnomeFileSelector.
+
+2000-08-02  Martin Baulig  <baulig suse de>
+
+	* gnome-icon-list.c (gnome_icon_list_insert_pixbuf): Added
+	`image_filename' argument.
+	(gnome_icon_list_append_pixbuf): Likewise.
+	(gnome_icon_list_get_icon_filename): New function.
+	(gnome_icon_list_find_icon_from_filename): New function.
+
+	* gnome-icon-sel.c: Use gnome_icon_list_get_icon_filename()
+	instead of gnome_icon_list_get/set_icon_data().
+	* gnome-icon-selector.c: Likewise.
+
+2000-08-01  Martin Baulig  <baulig suse de>
+
+	Moved all deprecated files (i.e the ones that were linked into
+	libgnomeui-1-compat and not into libgnomeui) into their own
+	subdirectory (../libcompat).
+
+	Hey, new you can do a `ls' here and you won't get confused by all
+	this old crap any longer .... :-)
+
+	* gnome-dentry-edit.c, gnome-dentry-edit.h, gnome-dns.c,
+	gnome-dns.h, gnome-druid-page-finish.c, gnome-druid-page-finish.h,
+	gnome-druid-page-start.c, gnome-druid-page-start.h, gnome-guru.c,
+	gnome-guru.h, gnome-procbar.c, gnome-procbar.h, gnome-properties.c,
+	gnome-properties.h, gnome-property-entries.c, gnome-property-entries.h,
+	gnome-spell.c, gnome-spell.h, gnome-startup.c, gnome-startup.h,
+	gnomeui10-compat.c, gnomeui10-compat.h, gtkcauldron.c, gtkcauldron.h:
+	Moved to ../libcompat/.
+
+2000-08-01  Martin Baulig  <baulig suse de>
+
+	* gnome-stock.c (GnomeStockPixmapEntryPixbufScaled): Inserted
+	`ref_count' field so we can cast it to GnomeStockPixmapEntryAny
+	without getting a core dump.
+
+2000-07-31  Martin Baulig  <baulig suse de>
+
+	* gnome-icon-selector.c (gnome_icon_selector_add_defaults): New.
+
+	* gnome-icon-list.h (GnomeIconList): Made the `selection' and
+	`icons' fields private and added the necessary accessor functions.
+	(gnome_icon_list_get_num_icons): New function.
+	(gnome_icon_list_get_selection): New function.
+
+	* gnome-icon-list.c (gnome_icon_list_unselect_all): Removed the
+	"for internal use only" arguments.
+
+2000-07-31  Martin Baulig  <baulig suse de>
+
+	* gnome-canvas-line.c (gnome_canvas_line_destroy): Destroy may run
+	multiple times nowadays.
+	* gnome-canvas-polygon.c (gnome_canvas_polygon_destroy): Likewise.
+	* gnome-canvas-rect-ellipse.c (gnome_canvas_re_destroy): Likewise.
+	* gnome-canvas-text.c (gnome_canvas_text_destroy): Likewise.
+
+2000-07-31  Martin Baulig  <baulig suse de>
+
+	* gnome-icon-list.c (gnome_icon_list_new): Removed the adjustment
+	argument and undeprecated this function.
+	(gnome_icon_list_new_flags): Removed.
+
+2000-07-29  Martin Baulig  <baulig suse de>
+
+	* gnome-init.c (libgnomeui_post_args_parse): Call glade_gnome_init().
+
+	* Makefile.am (libgnomeui_2_la_SOURCES): Added gnome-glade.c.
+
+	* gnome-glade.c: Copied here from libglade/glade/glade-gnome.c
+	and modified for gnome-libs HEAD (the file was copied directly
+	in CVS to preserve its histroy, so don't be surprised if there's
+	no log message).
+
+2000-07-27  Martin Baulig  <baulig suse de>
+
+	* gnome-canvas.c (gnome_canvas_destroy): Destroy may run
+	multiple times nowadays.
+
+	* gnome-icon-list.c (gnome_icon_list_clear): This needs to
+	mark the icon list as dirty.
+
+2000-07-27  Martin Baulig  <baulig suse de>
+
+	* gnome-canvas-pixbuf.c (gnome_canvas_pixbuf_destroy): Destroy
+	may run multiple times nowadays.
+	* gnome-icon-item.c (iti_destroy): Likewise.
+
+2000-07-26  Martin Baulig  <baulig suse de>
+
+	* gnome-icon-list.c: Use the normal canvas/layout scrolling
+	methods here. [FIXME: This widget can use some loving.]
+	(gnome_icon_list_set_hadjustment): Removed.
+	(gnome_icon_list_set_vadjustment): Removed.
+
+	* gnome-canvas.c: Fix scrolling for the new GtkLayout.
+	(DISPLAY_X1, DISPLAY_Y1): Removed since it's always zero.
+	(gnome_canvas_size_allocate): Use the layout's adjustments
+	in the call to scroll_to() rather than DISPLAY_X1/Y1.
+	(paint): Use the layout's adjustments to compute draw_x1 and
+	draw_y1 rather than DISPLAY_X1/Y1.
+
+	* gnome-less.c: Reflect latest GtkTextBuffer changes.
+
+2000-07-25  Martin Baulig  <baulig suse de>
+
+	* gnome-icon-list.c (gil_place_icon): Correctly halign the
+	icons at the middle of their labels.
+
+2000-07-25  Martin Baulig  <baulig suse de>
+
+	Added new GnomeSelector widget. We'll subclass this for
+	files, directories, icons, pixmaps and so on.
+
+	* gnome-icon-selector.[ch]: New files.
+	* gnome-file-selector.[ch]: New files.
+	* gnome-selectorP.h: New file.
+
+	* gnome-selector.[ch]: New files.
+	* selector-demo.c: New demo.
+
+2000-07-25  Martin Baulig  <baulig suse de>
+
+	* gnome-entry.[ch]: "privatized" it, added necessary accessor
+	functions for the now hidden members and added GtkArg stuff.
+
+	* gnome-procbar.[ch]: Marked this as deprecated and moved
+	it into the compat library.
+
+2000-07-19  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi*.[ch]: "privatized" all structures. code cleanup.
+	added necessary accessor functions for the now hidden members.
+	fixed all the code to (hopefully) work with the above changes.
+	* gnome-pouch.[ch]: likewise.
+	* gnome-roo.[ch]: likewise.
+	* gnome-pouchP.h: new file. contains private parts ;) of the
+	GnomePouch and GnomeRoo widgets.
+	* Makefile.am: added gnome-pouchP.h to libgnomeui_2_la_SOURCES.
+	* mdi-demo.c: fixed to use the accessor functions instead of
+	directly accessing the members.
+
+Tue Jul 18 00:46:14 2000  George Lebl <jirka 5z com>
+
+	* gnome-gconf.c:  don't ref/sink, and use gconf_client_get_default
+	  instead of _new
+
+Mon Jul 17 23:49:58 2000  George Lebl <jirka 5z com>
+
+	* gnome-less.[ch]:  Port to the new text widget.  deprecate the font
+	  functions and replace them with new ones which are 1) saner 2)
+	  compatible with the new text widget.  Add a way to set width to
+	  a specified amount of columns.  Derive the widget from HBox rather
+	  then VBox to kill one level of wigetry.  Add append versions of all
+	  the show functions.  Make the text widget pointers public.
+
+2000-07-16  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-appbar.[ch] (gnome_appbar_get_status): new accessor function.
+	* gnome-app-util.c (gnome_app_activate_statusbar): use
+	gnome_appbar_get_status().
+	
+Fri Jul 14 17:10:54 2000  George Lebl <jirka 5z com>
+
+	* *.c: fixup the destroy/finalize handlers.  Make sure destroy
+	  handlers can be called multiple times and move freeing of
+	  private structure to finalize.  Also all unref stuff is supposed
+	  to be in the destroy handler and not finalize according to gtk
+	  docs.
+
+	* gnome-icon-list.c: Make the typedefs standard and make the
+	  private structure standard.
+
+Fri Jul 14 05:39:40 2000  George Lebl <jirka 5z com>
+
+	* gnome-messagebox.c: handle a case where no buttons were added.
+	  This makes gnome_segv work again, woohoo!
+
+Fri Jul 14 05:33:16 2000  George Lebl <jirka 5z com>
+
+	* gnome-about.c, gnome-animator.c, gnome-animator.h, gnome-app.c,
+	  gnome-appbar.c, gnome-calculator.c, gnome-client.c,
+	  gnome-color-picker.c, gnome-dateedit.c, gnome-dentry-edit.c,
+	  gnome-dialog.c, gnome-ditem-edit.c, gnome-dock-band.c,
+	  gnome-dock-item.c, gnome-dock-layout.c, gnome-dock.c,
+	  gnome-druid-page-edge.c, gnome-druid-page-finish.c,
+	  gnome-druid-page-standard.c, gnome-druid-page-start.c,
+	  gnome-druid-page.c, gnome-druid.c, gnome-entry.c:
+	  Move freeing of private structure into finalize, and make sure
+	  the default destroy handler can be called multiple times as
+	  gtk2.0 will do this to us.
+Fri Jul 14 04:14:50 2000  George Lebl <jirka 5z com>
+
+	* gnome-cursors.c: allocate data for gdk_bitmap_create_from_data
+	  using g_malloc and free it after use to avoid leaks.
+
+Fri Jul 14 01:43:06 2000  George Lebl <jirka 5z com>
+
+	* gnome-helpsys.h: The url context is a pointer now
+
+	* libgnomeui.h, libgnomeui-compat-1.0.h: more header cleanup
+
+Fri Jul 14 01:00:44 2000  George Lebl <jirka 5z com>
+
+	* Makefile.am:  Move gnome-canvas-image.[ch] out of the build as it
+	  depends on imlib and imlib appears not to compile with gtk/glib 2.0
+	  anyway.
+
+	* gnome-dialog.[ch]:  doh! I left in the private stuff in the header.
+	  correct for that.  make the buttons list public, it is used outside
+	  of gnome-dialog.  Since this widget will get some GtkDialog action
+	  later, the api doesn't need to be anal for now.
+
+	* gnome-file-saver.[ch]: Add a private structure, and correct the
+	  signal signature, though the signal doesn't seem to get emitted
+	  ever
+
+	* gnome-procbar.[ch]:  Add a private structure and remove the
+	  incredibly ugly single letter defines to make the code more
+	  readable.  Stop leaking colors by allocating, freeing them
+	  correctly.  Add a construct function which does what new_flags
+	  does.  The new/construct functions COPY the colors argument now
+	  instead of just keeping a reference to it (that was ugly).  The
+	  callback pointer has a full prototype now.
+
+	* gnome-propertybox.h: add a gpointer reserved field for a future
+	  possible private pointer.
+
+	* gnome-recently-used.[ch]: add a private structure, return a pointer
+	  from the document ref function
+
+	* gnome-unit-spinner.[ch]:  Add a construct method, and correct
+	  setting the adj_unit
+
+	* libgnomeui-compat-1.0.h, libgnomeui.h:  Move the headers which
+	  are actually in the compat lib to the compat header
+	
+
+Thu Jul 13 19:12:38 2000  George Lebl <jirka 5z com>
+
+	* gnome-appbar.[ch]:  Add a private pointer and structure and move
+	  privates in there.  Also make _set_progress a deprecated function
+	  and added _set_progress_percentage to make the naming be more correct
+
+	* gnome-date-edit.[ch]:  Add a private structure, use typedefs in the
+	  standard way, add an accessor for initial_time as it's now a
+	  private member, and rename _get_date to _get_time (_get_date is
+	  still there as a part of the deprecated API), do the GtkArg
+	  dance, use gtk_widget_get_child_requisition instead of
+	  gtk_widget_size_request, fix some documentation and add a
+	  _construct method
+
+Wed Jul 12 16:59:10 2000  George Lebl <jirka 5z com>
+
+	* gnome-file-entry.h, gnome-icon-entry.h: hide deprecated functions
+	  behind #ifndef GNOME_EXCLUDE_DEPRECATED
+
+	* gnome-font-picker.[ch]:  Add accessor for title, use a private
+	  pointer, add GtkArg stuff, plus some cleanup
+
+	* libgnomeui.h: since gnome-properties.h and gnome-property-entries.h
+	  are 1) unmaintained 2) marked deprecated, hide them with
+	  #ifndef GNOME_EXCLUDE_DEPRECATED
+
+Wed Jul 12 15:56:58 2000  George Lebl <jirka 5z com>
+
+	* gnome-helpsys.c: minor documentation fix
+
+	* gnome-href.h: surround deprecated stuff by #ifndef
+	  GNOME_EXCLUDE_DEPRECATED
+
+	* gnome-icon-item.[ch]:  return const char * when it's
+	  an internal string
+
+	* gnome-paper-selector.[ch]:  Use a private pointer and
+	  a private structure
+
+Wed Jul 12 02:47:22 2000  George Lebl <jirka 5z com>
+
+	* gnome-app-helper.[ch], gnome-client.[ch], gnome-ditem-edit.c,
+	  gnome-font-picker.[ch], gnome-helpsys.c, gnome-paper-selector.c,
+	  oafgnome.c:  Do the const dance.  Fix warnings caused by const
+	  changes in libgnome.  Add some const returns where appropriate.
+
+2000-07-09  Karl Eichwalder  <ke suse de>
+
+	* gnome_segv.c (main): Fix message string typo.
+
+2000-07-07  Chema Celorio  <chema celorio com>
+ 
+ 	* gnome_segv.c: add a "DEBUG" button to the segv dialog if the program
+ 	pointed by the enviromental variable "GNOME_DEBUGGER" is
+
+Tue Jul 04 01:44:21 2000  George Lebl <jirka 5z com>
+
+	* gnome-color-picker.c:  Excorcise imlib reference from a label :)
+
+	* gnome-scores.[ch]:  Add and use a private pointer.  Allow setting
+	  logo multiple times.  Add a _construct method.  Add a
+	  _display_with_pixmap function to use a pixmap logo rather then just
+	  a title.
+
+2000-07-03  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-druid-page-standard.c: add finalize function.  Move
+	free()ing to it. 
+
+Tue Jun 27 00:04:35 2000  George Lebl <jirka 5z com>
+
+	* gnome-druid*.[ch]: Added private pointers to everything and moved
+	  the privates into it
+
+	* gnome-druid-page*.c: Mark the fonts translatable and add -*-*
+	  instead of iso8859-1 encoding
+
+	* gnome-font-picker.c: Mark the default font translatable and add
+	  -*-* instead of iso8859-1 encoding and also mark the default text
+	  for translation
+
+Mon Jun 26 13:31:01 2000  George Lebl <jirka 5z com>
+
+	* gnome-animator.[ch]:  Remove dependence on knowing internals of
+	  GdkPixbufFrame and merge the fields into our own frame structure.
+	  Also fix the gdk-pixbuf-animation -> gnome-animator loading.
+	  However the GdkPixbufFrameAction still remains to be implemented
+
+Sun Jun 25 23:50:22 2000  George Lebl <jirka 5z com>
+
+	* gnome-about.[ch]: Add a private structure.  This widget still needs
+	  to be cleaned up
+
+	* gnome-app.c: dup the app id string in the GtkArg get
+
+	* gnome-color-picker.[ch]: Use a private structure for privates. 
+	  Dup the title string on GtkArg get
+
+	* gnome-dialog.[ch]: Use a private structure for privates.
+
+	* gnome-pixmap-entry.c, gnome-file-entry.c, gnome-pixmap.c:
+	  use GTK_TYPE_STRING for string arguments
+
+	* gnome-href.[ch]: dup string on argument get
+
+	* gnome-icon-entry.c: make history_id and browse_dialog_title
+	  readable arguments and use GTK_TYPE_STRING
+
+	* gnome-messagebox.[ch]: use a private structure for privates
+
+Sun Jun 25 18:15:36 2000  George Lebl <jirka 5z com>
+
+	* gnome-calculator.[ch]: put privates into a private structure.  Add
+	  an accessor for the internal string representation
+
+	* gnome-number-entry.c: use the gnome-calculator accessors instead of
+	  looking directly into the structure
+
+	* gnome-icon-sel.[ch]: put privates into a private structure
+
+	* gnome-less.[ch]: put privates into a private structure, also mark
+	  the fixed font set for translation
+
+	* gnome-number-entry.[ch]: use private structure for private members,
+	  change finalize into destroy
+
+Sun Jun 25 17:35:07 2000  George Lebl <jirka 5z com>
+
+	* gnome-ditem-entry.[ch]: Put private members into a private
+	  structure
+
+Sun Jun 25 17:16:24 2000  George Lebl <jirka 5z com>
+
+	* gnome-href.[ch]: use a private structure for privates, also
+	  make returns be (const gchar *) since the return should not
+	  be freed or modified.
+
+Sun Jun 25 17:00:17 2000  George Lebl <jirka 5z com>
+
+	* gnome-app.[ch], gnome-dock*.[ch]:  Add a private pointer even
+	  though nothing is private yet, this should be done.
+
+	* gnome-dock-layout.c:  In the destroy handler, call the parent
+	  destroy handler for the object.
+
+	* gnome-entry.[ch]:  Move private data into a private structure,
+	  also add an accessor for the max_saved integer
+
+	* gnome-file-entry.[ch]:  Move private data into a private
+	  structure, also add an accessor for the is_modal and
+	  directory_entry bools.  Rename _set_directory to
+	  _set_directory_entry to avoid confusion, but keep the old
+	  method for compatibility.  Change finalize into destroy
+	  and NULL freed data.
+
+	* gnome-gconf.c (gnome_gconf_gtk_range_set) fix warning
+
+	* gnome-mdi.c, gnome-pouch.c, gnome-roo.c:  Don't define
+	  GNOME_ENABLE_DEBUG by hand here.  This is done in configure.
+
+Tue Jun 20 14:11:17 2000  George Lebl <jirka 5z com>
+
+	* gnome-dock*.[ch]: remove the dock hiding patch as it seems to not
+	  be looked upon favorably (especially by Ettore and it's his widget
+	  thingie).  Thus reverting until discussed further.
+
+Mon Jun 19 22:17:01 2000  George Lebl <jirka 5z com>
+
+	* gnome-dock-item.[ch]: add a hidden state, add a signal
+	  "dock_toggle_state", write and use wrappers for all the signals.
+	  Actually emit the detach signal.  When a user clicks on the handle
+	  hide the dock item
+
+	* gnome-dock.c: catch the dock_toggle_state and emit layout changed
+	  signal
+
+	* gnome-dock-layout.[ch]: load and save the hidden state
+
+2000-06-15  Jody Goldberg <jgoldberg home com>
+
+	* gnome-calculator.c (set_result) : setlocale returns a static buffer.
+	  Copy it to safety.  Set the locale AFTER storing the current
+	  setting.
+	(add_digit) : Ditto.
+	(negate_val) : Ditto.
+
+Mon Jun 12 16:57:50 2000  George Lebl <jirka 5z com>
+
+	* gnome-dialog-util.c: fix a memory leak.  Free the info structure
+	  by using the destroy notify of the signal connection rather then
+	  in the clicked handler as that is not always called (like when
+	  the dialog is closed by the wm)
+
+Thu Jun 01 02:47:22 2000  George Lebl <jirka 5z com>
+
+	* gnome-color-picker.[ch]: add accessors for attributes, and add
+	  GtkArg stuff
+
+2000-05-31  Jon K Hellan  <hellan acm org>
+
+	* gnome-messagebox.c (gnome_message_box_construct,
+	gnome_message_box_new): Set keyboard focus to default button.
+
+2000-05-27  Julian Missig  <julian linuxpower org>
+
+	* gnome-paper-selector.h: SELECTOR, not SELECTER.
+
+2000-05-26  Ian Peters  <itp gnu org>
+
+	* gnome-app.h: uncommented GNOME_APP_CLASS and GNOME_IS_APP_CLASS --
+	they should be there
+
+Sat May 27 11:42:02 2000  George Lebl <jirka 5z com>
+
+	* gnome-href.c: Allow draging the link off the button
+
+Sat May 27 01:13:20 2000  George Lebl <jirka 5z com>
+
+	* dock_demo.c, gnome-file-saver.c, gnome-helpsys.c
+	  gnome-mdi-child.h, gnome-mdi-generic-child.c, gnome-preferences.[ch],
+	  gnome-roo.c, gnome_segv.c, mdi_demo.c, oafgnome.c,
+	  test-recently-used.c:  Fix warnings.
+
+	* gnome-animator.c:  Fix warnings.  Fix an unitialized value problem.
+
+	* gnome-color-picker.c: Add drag and drop for colors.
+
+Mon May 22  Martijn van Beers  <martijn earthling net>
+
+	* gnome-gconf.c (gnome_gconf_color_picker_get): actually save the
+	                                                alpha
+	  (gnome_gconf_gnome_icon_entry_set): don't use the gtk entry
+	                                      anymore, but set the icon
+					      directly, so the icon gets set
+
+Mon May 22  Martijn van Beers  <martijn earthling net>
+
+	* gnome-gconf.c (gnome_gconf_*_set): added a value != check
+	  (gnome_gconf_spin_button_get): initialize retval
+	  (gnome_gconf_gtk_radio_button_set): fix ending condition in for loop
+	  (gnome_gconf_gtk_range_*): allow GCONF_VALUE_INT
+	  (gnome_gconf_color_picker_get): save alpha
+	  (gnome_gconf_color_picker_set): implement
+
+Sat May 20 14:50:59 2000  George Lebl <jirka 5z com>
+
+	* gnome-stock.[ch]: the GdkPixbuf getting routine is renamed to
+	  gnome_stock_entry_get_gdk_pixbuf.  This is 1) because polluting
+	  other namespaces is bad 2) because the function does not create
+	  a new pixbuf, but returns an existing one with the refcount
+	  incremented.
+
+	* gnome-entry.[ch]: implemented gnome_entry_clear_history
+
+Sat May 20  Martijn van Beers  <martijn earthling net>
+
+	* (every GtkObject).h: make sure every object has GNOME_TYPE_
+	  and GNOME_IS_*_CLASS macros, and format them consistently
+	  with each other and gtk+
+
+Fri May 19 18:56:48 2000  George Lebl <jirka 5z com>
+
+	* gnome-stock.[ch]: added refcount to the entries to make wrapping
+	  possible and fix the creation of new pixmaps from the data, so that
+	  the stock pixmaps now actually work.
+
+Thu May 18 20:31:16 2000  George Lebl <jirka 5z com>
+
+	* gnome-ditem-edit.[ch]: fix api naming.  the child1,child2 are now
+	  functions (should ease wrappers) and there's a child3 accessor.
+	  new_notebook now refs/sinks the object, and when the notebook dies
+	  it unrefs it.  This is much saner behaviour and the notebook thus
+	  basically "takes ownership" of the ditem-edit
+
+Thu May 18  Martijn van Beers  <martijn earthling net>
+
+	* Makefile.am:
+	  - use $(LIBART_CFLAGS) instead of @LIBART_CFLAGS@ like everything
+	    else
+	  - ditto for LIBART_LIBS
+	  - use LDADD instead of creating an identical target_LDADD for
+	    all of gnome_segv, test_file_saver, test_recently_used,
+	    stock_demo, winhints_demo, animator_demo, dock_demo and
+	    mdi_demo
+
+	* .cvsignore: add test-recently-used, test-file-saver and mdi_demo
+
+Wed May 17 14:05:14 2000  George Lebl <jirka 5z com>
+
+	* gnome-href.[ch]: interface sanitation.  Make get/set_label
+	  deprecated and use get/set_text.  label seems to refer to GtkLabel
+	  while text is much more clear.  The old methods are still there but
+	  give a warning.
+
+Wed May 17 12:59:39 2000  George Lebl <jirka 5z com>
+
+	* gtk-clock.[ch]: add a construct method
+
+Sat May 13 11:56:35 2000  George Lebl <jirka 5z com>
+
+	* gnome-scores.c (gnome_scores_new): make the strftime buffer 256
+	  chars, stop cutting the last character, also if strftime fails,
+	  we need to reset the buffer to something sane.
+
+2000-05-10  Karl Eichwalder  <ke suse de>
+
+	* Makefile.am (gnometypebuiltins.h, gnometypebuiltins_vars.c,
+	gnometypebuiltins_ids.c): Add LC_COLLATE=C to avoid NLS nuisances
+	while calling awk.
+
+Mon May 08 17:21:33 2000  George Lebl <jirka 5z com>
+
+	* gnome-icon-entry.c: when an absolute path is passed to
+	  set_pixmap_subdir the standard pixmap path will not be prepended
+
+Sun May 07 17:52:27 2000  Iain Holmes <ih csd abdn ac uk>
+
+	* gnome-font-picker.c (gnome_font_picker_label_set_font_from_label):
+	Apply Patch from Charles Kerr fixing memory leak.
+
+Sat May 06 16:52:27 2000  George Lebl <jirka 5z com>
+
+	* gnome-calculator.c (set_result) (add_digit) (negate_val):
+	  setlocale to "C" and then back to original whenever we are reading
+	  and writing floats.  this is because we can't deal with strings
+	  of any locale yet.
+
+Fri May 05 19:23:20 2000  George Lebl <jirka 5z com>
+
+	* gnome-about.c: make an error dialog if gnome_url_show fails
+
+	* gnome-href.c: make an error dialog if gnome_url_show fails also fix
+	  the includes
+
+	* gnome-helpsys.c: minor doc fix and use the new gnome_url_show_full
+	  routine with the error argument.
+
+	* Makefile.am: add @LIBART_LIBS@ for the test and demo programs
+
+Sun Apr 30 02:12:53 2000  George Lebl <jirka 5z com>
+
+	* animator_demo.c (main): fix warnings
+
+	* gnome-animator.c (prepare_aux_pixmaps) (paint)
+	  (gnome_animator_append_frame_from_pixbuf_)
+	  (gnome_animator_append_frames_from_pixbuf): Make this compile with
+	  newest gdk-pixbuf.  It however can't possibly work due to usage
+	  of unused variables, see all the FIXMEs.
+
+	* gnome-calculator.[ch]:  Fixup Federico's patch.  fix clear/reset
+	  as in gnome-libs-1-0, fix no_func crash.  Add an accessor for
+	  the accelerator group.  Mark all fields in the structure as
+	  private.  Add pointer to the drg button and set it's state
+	  properly on reset.
+
+	* gnome-canvas-pixbuf.c (gnome_canvas_pixbuf_draw)
+	  (gnome_canvas_pixbuf_render):  Make this compile with newest
+	  gdk-pixbuf
+
+	* gnome-cursors.c (build_cursor_table): fix const warning
+
+	* gnome-helpsys.c (gnome_help_view_process_event):  fix warning
+
+	* gnome-recently-used.c:  fix warning
+
+2000-04-28  ERDI Gergo  <cactus cactus rulez org>
+
+	* gnome-about.c (gnome_about_load_logo): Applied Jason Leach's
+	patch to handle absolute filenames for the added logo
+
+2000-04-19  Federico Mena Quintero  <federico helixcode com>
+
+	* gnome-calculator.c: Keep around a pixmap and a reference count
+	for the calculator's font.  It is no longer a GnomePixmap, which
+	did not make any sense.
+	(gnome_calculator_init): gc->display is now a drawing area.
+	Create it with the proper visual and colormap.  Also, do not
+	connect to the realize signal of the calculator.  Call ref_font()
+	instead.
+	(gnome_calculator_destroy): Call unref_font().  Now we don't leak
+	the font.  Wheee!
+	(ref_font): New function to load/ref the calculator's font pixmap.
+	(unref_font): New function to unref/destroy the font pixmap.
+	(gnome_calculator_realized): Removed function.
+	(display_expose): New handler for the calculator's display expose
+	event.
+	(do_error): Queue a draw of the display.
+	(set_result): Likewise.
+	(add_digit): Likewise.
+	(negate_val): Likewise.
+	(store_m): Likewise.
+	(sum_m): Likewise.
+
+2000-04-20  ERDI Gergo  <cactus cactus rulez org>
+
+	* gnome-color-picker.c (gnome_color_picker_init): gdk_pixbuf API changes
+
+	* gnome-pixmap.c (saturate_and_pixelate): ditto
+	(paint_with_pixbuf): ditto
+
+2000-04-18  ERDI Gergo  <cactus cactus rulez org>
+
+	* gnome-about.c (gnome_about_load_logo): Determing the size of the
+	logo used some elements of the GdkPixbuf struct directly. Bad
+	Cactus, no cookie!
+	* gnome-icon-sel.c: gdk_pixbuf API changes
+
+	* gnome-canvas-pixbuf.c: ditto
+
+	* gnome-stock.c (stock_pixmaps): ditto, plus included
+	gnome-preferences.h to get rid of a warning
+
+Wed Apr 19 05:29:24 2000  George Lebl <jirka 5z com>
+
+	* gnome-winhints.c: add preconditions all over the place
+
+Wed Apr 19 05:21:25 2000  George Lebl <jirka 5z com>
+
+	* gnome-scores.[ch]: gnome_scores_display will return a pointer to
+	  the widget if something was displayed.  Also put the docs from
+	  the header file into the gtk-doc format
+
+Wed Apr 19 05:05:20 2000  George Lebl <jirka 5z com>
+
+	* gnome-file-entry.[ch]: add _set_filename method, and added a bunch
+	  of extra arguments
+
+Wed Apr 19 04:49:54 2000  George Lebl <jirka 5z com>
+
+	* gnome-file-entry.c: use GtkArg system, use G_DIR_SEPARATOR, and
+	  minor cleanup
+
+Wed Apr 19 04:36:15 2000  George Lebl <jirka 5z com>
+
+	* gnome-href.c: use GtkArg system and small doc updates
+
+Tue Mar 28 20:41:46 2000  George Lebl <jirka 5z com>
+
+	* gnome-number-entry.[ch]: add a _set_number method to complement
+	  the _get_number method.
+
+Thu Mar 23 19:21:39 2000  George Lebl <jirka 5z com>
+
+	* gnome-pixmap.c: Add gtk-arg
+
+2000-03-17  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c: various small fixes.
+	* gnome-pouch.c, gnome-roo.c: shuffled the way signals get
+	emitted; removed default signal handler for GnomePouch::close-child.
+	* Makefile.am: as mdi_demo source was committed, build it.
+
+Wed, 15 Mar 2000 14:03:46 +0100 Paolo Molaro <lupus linuxcare com>
+
+	* gnome-font-picker.c: avoid checking all the memory for '-'.
+	  Is this code going to stay in gnome-libs? It needs a big cleanup.
+
+2000-03-13  Elliot Lee  <sopwith redhat com>
+	* gnome-stock.c: Fix gnome_stock_or_ordinary_button for the ordinary button case.
+	* Makefile.am: Until mdi_demo.c is committed, remove usage thereof
+
+2000-03-13  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-pouch.[ch]: new files; a Window-in-Window style MDI container
+	widget.
+	* gnome-roo.[ch]: new files; a child window for Window-in-Window style
+	MDI. The child window decorations are rather ugly, as I'm a pretty bad
+	designer. Any improvements are very welcome.
+	* gnome-mdi.h: new enum GNOME_MDI_WIW; describes WiW MDI mode.
+	* gnome-mdi.[ch] (gnome_mdi_new): return a GnomeMDI * instead of
+	GtkObject *.
+	(gnome_mdi_get_view_menu_info): new function; return menu GnomeUIInfo
+	of a view if the menu is set.
+	(gnome_mdi_get_view_toolbar_info): new function; return toolbar
+ 	GnomeUIInfo of a view if the toolbar is set.
+	(gnome_mdi_get_child_toolbar_info): new function; return child's
+	toolbar GnomeUIInfo of a given GnomeApp.
+	(*): implemented the WiW mode. I suppose it's still full of bugs
+	that I've overlooked.
+	* gnome-mdi-child.h (GnomeMDIChildConfigFunc): returns a const
+	gchar *.
+	(gnome_mdi_child_add_toolbar): moved to gnome-mdiP.h.
+	* mdi_demo.c: a testing app for GnomeMDI.
+	* Makefile.am: integrated the above.
+
+Sat Mar 04 21:35:08 2000  George Lebl <jirka 5z com>
+
+	* gnome-pixmap-entry.c: fix destructor to call parent destructor
+
+Sat Mar 04 20:52:26 2000  George Lebl <jirka 5z com>
+
+	* gnome-ditem-edit.c,gnome-dentry-edit.c: use the new _set_filename
+	  method of the icon entry rather then the old _set_icon.
+
+	* gnome-icon-entry.c: correct destroy binding, set parent_class to
+	  the vbox class not hbox. correct the top of file comment
+
+	* gnome-pixmap-entry.c: argumentize, make private members truly
+	  private and add accessors to preview and preview_sw
+
+2000-03-01  Cody Russell  <bratsche dfw net>
+	* gnome-ditem-edit.c: Fixed a couple typos; gtk_entry -> GTK_ENTRY
+
+Fri Feb 25 03:29:15 2000  George Lebl <jirka 5z com>
+
+	* gnome-icon-entry.[ch]: made the interface sane, made privates
+	  really private by using a private struct, which means we'll be
+	  able to change the ugly "entry" based implementation later.
+	  added gtk argument support, added set_filename and deprecated
+	  set_icon.  Mark the other deprecated methods so.  added
+	  _pick_dialog and "browse" signal.  If a .desktop is dropped on
+	  the thing, it will try to extract a filename from there.
+
+	* gnome-ditem-edit.c: clear the three entires for the languages
+	  entry when setting a new ditem
+
+2000-02-24  ERDI Gergo  <cactus cactus rulez org>
+
+	* gnome-about.c (gnome_about_fill_options): New function to set
+	user-settable values using GConf and gtkrc
+	(gnome_about_item_cb): Since gnome_canvas_item_pixbuf has no
+	fill_color_rgba value, the underline color is passed to the callback
+
+2000-02-19  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* oafgnome.c (rcmd_handle_connecting): use ri->in_buf->str as an
+	argument to strstr() instead of aline: since we'll be doing pointer
+	arithmetics later, this matters.
+	(rcmd_activator): append langs_buf instead of display_buf twice.
+	(rcmd_run): create and free ri->in_buf and set ri->cmd to remote_cmd.
+	* gnome-remote-bootstrap.c (handle_commands): pass g_strsplit()
+	parameters in proper order.
+	(relay_output): fflush() stdout.
+	
+Fri Feb 18 17:30:58 2000  George Lebl <jirka 5z com>
+
+	* gnome-app-helper.c,gnome-stock.c: use the gnome-properties instead
+	  of a hardcoded gnome_config path, it needs a control-center change
+	  which hopefully jacob is commiting right now
+
+Fri Feb 18 13:07:33 2000  George Lebl <jirka 5z com>
+
+	* gnome-calculator.c:  applied patch from "W. Adam Foran"
+	  <waforan pathcom com> to fix a segfault
+
+2000-02-18  Anders Carlsson  <andersca gnu org>
+
+	* gnome-stock.c: Reduce padding for gnome-stock buttons
+	from 7 pixels to 2. Looks much nicer this way.
+
+2000-02-15  Rusty Conover <rconover zootweb com>
+
+	* gnome-font-picker.c (gnome_font_picker_set_font_name): Added
+	call to gnome_font_picker_update_font_info() so that if the widget
+	is in GNOME_FONT_PICKER_MODE_FONT_INFO the widget gets properly
+	updated with the current font.  Before you could set the font name
+	it would appear in the dialog but not on the visable widget.
+	
+Sun Feb 13 23:21:19 2000  George Lebl <jirka 5z com>
+
+	* gnome-calculator.c: apply patch from "W. Adam Foran"
+	  <waforan pathcom com> to add precedence to the calculator
+	  widget.
+
+2000-02-09  Iain Holmes  <ih csd abdn ac uk>
+
+	* gnome-cursors.c: Started adding gconf to support theming things.
+
+2000-02-07  Elliot Lee  <sopwith redhat com>
+
+	* gnome-helpsys.[ch]: Add gnome_help_view_set_visibility (to
+	determine whether the widget is shown or not), and some
+	convenience callbacks to allow doing 'help on this' from a menu
+	item.
+
+	* gnome-init.[ch]: Add LIBGNOMEUI_PARAM_DEFAULT_ICON.
+	* gnome-app-util.[ch]: Add gnome_window_set_icon() and gnome_window_set_icon_from_file().
+
+	* gnome-app.c: Use LIBGNOMEUI_PARAM_DEFAULT_ICON if available, to
+	set a default icon for GnomeApp windows.
+
+Sat Feb 05 18:29:26 2000  George Lebl <jirka 5z com>
+
+	* gnome-file-entry.[ch]: use gboolean in places of int for bools
+
+2000-02-05  Cody Russell  <bratsche dfw net>
+	* gnome-animator.[ch]: Rewrote much of GnomeAnimator in order to
+	use GdkPixbuf instead of GdkImlib. Much of this is untested, and
+	I'm still hacking away on it.
+
+	* animator_demo.c: Rewritten.
+
+	* Makefile.am: Re-enable GnomeAnimator and animator_demo.
+
+2000-02-01  Iain Holmes  <ih csd abdn ac uk>
+
+	* gnome-dateedit.c (select_clicked): Changed to use 
+	gnome_stock_cursor_new.
+
+	* gnome-dock-item.c (gnome_dock_item_grab_pointer): Same.
+
+	* gnome-href.c (gnome_href_realize): Same.
+
+	* gnome-icon-item.c (iti_start_selecting): Same.
+
+	* gnome-mdi.c (book_motion): Same.
+
+2000-01-31  Havoc Pennington  <hp redhat com>
+
+	* gnome-gconf.c (gnome_gconf_get_gnome_libs_settings_relative):
+	Function to make a key relative to the
+	/apps/gnome-settings/<appname> directory
+	(gnome_gconf_get_app_settings_relative): make a key relative to
+	/apps/<appname>
+	(gnome_gconf_post_args_parse): add gnome-libs settings dir to our
+	GConfClient
+
+	* gnome-app.c (gnome_app_add_toolbar): Use gnome_app_setup_toolbar
+
+	* gnome-app-helper.c (gnome_app_setup_toolbar): Function to set up
+	toolbar preferences, uses GConf for some preferences now instead
+	of gnome-preferences	
+	
+2000-01-31  Havoc Pennington  <hp redhat com>
+
+	* gnome-messagebox.c (gnome_message_box_construct): turn on line
+	wrap for message boxes
+
+	* gnome-gconf.c (gnome_default_gconf_client_error_handler): Set up
+	the default error handler dialog to display GConf errors that
+	aren't explicitly handled.
+
+2000-01-31  Havoc Pennington  <hp redhat com>
+
+	* gtkpixmapmenuitem.h (struct _GtkPixmapMenuItemClass): new class
+	fields to track the number of GtkPixmapMenuItem that actually have
+	pixmaps; if none, then we drop the toggle size to that of a
+	standard menu item. Basically this means that now if you turn off
+	pixmaps there isn't a big gap on the left of your menus.
+
+	* gtkpixmapmenuitem.c (gtk_pixmap_menu_item_init): remove
+	pointless set of toggle_size field in menu item instance
+	(gtk_pixmap_menu_item_class_init): don't set the menu item class
+	toggle size until we actually get a pixmap
+	(gtk_pixmap_menu_item_class_init): init new class fields
+
+Sun Jan 30 16:58:54 2000  George Lebl <jirka 5z com>
+
+	* gnome-dentry-edit.c: properly cast dentry->exec
+
+2000-01-30  Havoc Pennington  <hp pobox com>
+
+	* gnome-gconf.c (gnome_gconf_post_args_parse): Add the
+	"/desktop/gnome" gconf dir
+
+	* gnome-app-helper.c (create_pixmap): remove the window argument,
+	since gnome-stock is no longer this lame
+	(create_menu_item): Call setup_pixmap_menu_item
+	(setup_pixmap_menu_item): new function sets up a pixmap menu item
+	to respond appropriately to changes in whether menu icons should
+	be displayed	
+
+	* libgnomeui.h (GNOMEUI_INIT): Add GConf to the default
+	initialization, include gnome-gconf.h	
+	
+Sun Jan 30 15:44:35 2000  George Lebl <jirka 5z com>
+
+	* gnome-dentry-edit.c: use gnome_config_assemble_vector instead of
+	  g_flatten_vector to fix bug #1372
+
+2000-01-30  Havoc Pennington  <hp pobox com>
+
+	* gnome-file-saver.c (gnome_file_saver_init): use
+	gnome_get_gconf_client()
+
+	* gnome-recently-used.c (gnome_recently_used_construct): Use new
+	name gnome_get_gconf_client()
+
+	* gnome-gconf.c (gnome_gconf_client_get): Rename to
+	gnome_get_gconf_client()
+
+2000-01-30  Havoc Pennington  <hp pobox com>
+
+	* gnome-dialog.c (gnome_dialog_run_real): Create a new GMainLoop
+	to avoid problems with quitting the wrong mainloop with
+	gtk_main()/gtk_main_quit()
+
+	* gnome-recently-used.c (gnome_recently_used_get_all): Sort the
+	returned list of recently used documents
+
+2000-01-30  Iain Holmes  <ih csd abdn ac uk>
+
+	* gnome-cursors.[ch]: Added a GNOME_STOCK_CURSOR_XTERM type cursor.
+	Removed all the extra spaces from some cursors.
+
+2000-01-30  Havoc Pennington  <hp pobox com>
+
+	* gnome-pixmap.c (clear_provided_state_image): Apply patch 
+	from Peter Wainwright to free the mask as well as the pixbuf,
+	closes bug 5687
+
+2000-01-28  Havoc Pennington  <hp redhat com>
+
+	* gtkpixmapmenuitem.c (gtk_pixmap_menu_item_set_pixmap): The
+	mapping/realizing here was a bit wrong.
+
+2000-01-28  Havoc Pennington  <hp redhat com>
+
+	* gnome-number-entry.c (browse_clicked): set transient parent, 
+	bug 2497
+
+	* gnome-font-picker.c (gnome_font_picker_clicked): set transient
+	parent, fixes 2497 
+	
+	* gnome-color-picker.c (gnome_color_picker_clicked): Set transient
+	parent, per bug 2497
+
+2000-01-28  Havoc Pennington  <hp redhat com>
+
+	* gnome-propertybox.c (dialog_clicked_cb): merge fix to bug 4378
+	from stable branch (handle empty property boxes)
+
+2000-01-26  Iain Holmes  <ih csd abdn ac uk>
+
+	* gnome-cursors.c: Another new cursor - Pointer with ? beside it.
+
+2000-01-25  Iain Holmes  <ih csd abdn ac uk>
+
+	* gnome-cursors.[ch]: Added new cursors for resize arrows and the like.
+	Changed the default cursor to something pleasing.
+
+Sun Jan 23 16:54:39 2000  George Lebl <jirka 5z com>
+
+	* gnome-less.[ch]: mark all fields as private and add an accessor
+	  for the text field.  Also add a bunch of preconditions.  Remove
+	  an unused variable.
+
+Sun Jan 23 14:05:55 2000  George Lebl <jirka 5z com>
+
+	* gnome-dialog-util.c: add inline docs
+
+Sat Jan 22 16:22:25 2000  George Lebl <jirka 5z com>
+
+	* gnome-icon-sel.[ch]: marked all fields as private and add accessors
+	  to the two internal widgets. plus a small int->gboolean change
+
+	* gnome-icon-entry.c: don't use private fields of gnome-icon-sel,
+	  and use the accessor to get the icon list.
+
+Sat Jan 22 15:35:29 2000  George Lebl <jirka 5z com>
+
+	* gnome-href.[ch]: add a constructor method.  Also make the
+	  parameter names consistent with the header by using href instead
+	  of self in the .c file
+
+Sat Jan 22 13:51:51 2000  George Lebl <jirka 5z com>
+
+	* gnome-messagebox.[ch]: add a _construct method and use it in _new and
+	  _newv.  This fixes some out of sync code.  Also add documentation
+	  for _get_label and mark the label field in the header as
+	  /*< private >*/
+
+	* gnome-entry.[ch]: add a _construct method
+
+	* gnome-icon-entry.[ch]: add a _construct method and use
+	  file_entry_construct inside it
+
+	* gnome-pixmap-entry.c: use file_entry_construct method here which
+	  fixes a problem of history never being loaded here
+
+	* gnome-file-entry.c: call gnome_entry_construct inside it's own
+	  _construct method
+
+	* gnome-dialog.h: s/gint/gboolean/, these were actually already
+	  gboolean in the .c file.
+
+	* gnome-number-entry.[ch]: add a _construct method and fix the
+	  same problem that pixmap-entry had
+
+2000-01-20  ERDI Gergo  <cactus cactus rulez org>
+
+	* gnome-about.c (gnome_about_parse_name): Cleaned parse code to
+	use strchr()
+
+	* stock_demo.c: const char* in _TbItems removes compiler warning
+
+Thu Jan 20 00:08:47 2000  George Lebl <jirka 5z com>
+
+	* gnome-ditem-edit.c: actually ref the ditem in set_ditem.  When
+	  editting a directory type entry, desensitize the widgets that
+	  make no sense.  The type combo doesn't include directory when
+	  the set ditem file isn't a directory.  If the ditem type isn't
+	  one of the standard types we know, add it to the combo box.
+
+2000-01-18  ERDI Gergo  <cactus cactus rulez org>
+
+	* gnome-about.c (gnome_about_item_cb): Changed URL underlining
+	code to match the the color of the text
+	(gnome_about_fill_info, gnome_about_parse_name): author name
+	parsing to get clickable e-mails (idea by Iain Holmes)
+
+Tue Jan 18 00:56:46 2000  George Lebl <jirka 5z com>
+
+	* gnome-pixmap-entry.[ch]: fixup the pixmap entry to actually not
+	  even create the preview box if the do_preview is false.  This makes
+	  it not check the file for being a real image if the preview
+	  is off.
+
+2000-01-17  Havoc Pennington  <hp redhat com>
+
+	* gnome-stock.c (gnome_stock_pixmap_gdk):
+	s/gdk_pixbuf_render_pixbuf/gdk_pixbuf_render_pixbuf_and_mask
+
+	* gnome-calculator.c (gnome_calculator_realized): ditto
+
+	* gnome-init.c (libgnomeui_pixbuf_image_loader): ditto
+	
+2000-01-16  Iain Holmes  <ih csd abdn ac uk>
+
+	* gnome-about.c: Draw a line under clickable URLs
+
+2000-01-16  Iain Holmes  <ih csd abdn ac uk>
+
+	* gnome-cursors.c: Removed the g_print statement.
+
+Mon Jan 17 01:38:21 2000  George Lebl <jirka 5z com>
+
+	* gnome-calculator.c: don't reduce stack on unary functions, a patch
+	  from "W. Adam Foran" <waforan pathcom com>
+
+Sun Jan 16 02:45:10 2000  George Lebl <jirka 5z com>
+
+	* gnome-ditem-edit.[ch]: update for the new gnome-ditem stuff and make
+	  it store a ref to any ditem is loads so that information not
+	  updated in the gui is not lost.  Also add a whole bunch of
+	  preconditions to public methods, fix the header define, added
+	  accessors for new widgets, and fixed the ordering in the
+	  translations list
+
+2000-01-16  Havoc Pennington  <hp pobox com>
+
+	* gnome-pixmap.c (gnome_pixmap_get_draw_vals): new function 
+	to get the draw vals
+
+2000-01-15  ERDI Gergo  <cactus cactus rulez org>
+
+	* Removed numerous compile-time warnings
+
+2000-01-15  Havoc Pennington  <hp pobox com>
+
+	* gnome-stock.c (gnome_stock_set_icon): set main pixbuf in
+	addition to the individual states.	
+
+2000-01-15  Havoc Pennington  <hp pobox com>
+
+	* gnome-mdi.c (set_active_view): fix printf format warning
+
+	* gnome-dialog.c (gnome_dialog_button_clicked): remove unused
+	variable
+
+	* gnome-pixmap.h: remove the "internal functions" since we no
+	longer use any of them	
+
+	* gnome-stock.c (gnome_stock_pixmap_gdk): gdk_pixbuf_render_pixmap
+
+	* gnome-init.c (libgnomeui_pixbuf_image_loader): 
+	gdk_pixbuf_render_pixmap
+
+	* gnome-calculator.c (gnome_calculator_realized): replace
+	gnome_pixbuf_render with gdk_pixbuf_render_pixmap
+
+	* gnome-stock.c (gnome_stock_set_icon): sync with
+	gnome_pixmap_set_state_pixbufs rename
+
+	* gnome-druid.c (gnome_druid_size_request): add cast to remove
+	warning
+	(gnome_druid_paint): delete prototype, never defined
+
+	* gnome-pixmap.c (gnome_pixmap_set_state_pixbufs): rename from
+	gnome_pixmap_set_pixbufs_at_state for clarity
+
+	* gnome-messagebox.c: include gnomelib-init isntead of
+	gnomelib-init2
+	
+	* gnome-client.c (gnome_client_pre_args_parse): const on the
+	module info
+	(gnome_client_post_args_parse): ditto
+
+	* gnome-pixmap.c: There was massive cut-and-paste fest in here;
+	clean it all up.  Also, remove gnome_pixbuf_render since we have
+	one of these in gdk-pixbuf now.
+	(gnome_pixmap_size_request): implement size request so we can
+	lazily calculate size information instead of updating the 
+	requisition all the darn time
+	(set_pixbuf): don't calculate any pixbufs/masks etc. since 
+	it's all done lazily now
+	(gnome_pixmap_set_draw_vals): queue a redraw if necessary
+
+	* gnome-pixmap.h: split the data members so that generated 
+	images are always clearly separated from non-generated images,
+	this is the only way to get predictable, consistent behavior.
+
+	* gnome-pixmap.c: nuke all the crufty unused code at the bottom
+
+	* gnome-pixmap.h: s/GnomePixmapDraw/GnomePixmapDrawMode/g
+
+	* gnome-pixmap.c (gnome_pixmap_set_pixbuf): if width/height are
+	-1, it's necessary to reset the scaled image
+	(gnome_pixmap_set_pixbufs_at_state): call set_pixbuf_size()
+	instead of manually calculating the requisition
+	
+Sat Jan 15 00:04:00 2000  George Lebl <jirka 5z com>
+
+	* gnome-helpsys.c: fix gnome_help_view_get_arg by initializing the
+	  help_view pointer
+	  fix a whole bunch of potentially quite dangerous uninitialized
+	  values
+	  add two g_assert_not_reached into places which would have caused
+	  a segfault if reached
+
+	* gnome-init.c: fix an uninitialized local variable problem
+
+	* gnome-textfu.c: fix several potentially quite dangerous 
+	  uninitialized values and assumptions
+
+2000-01-15  Havoc Pennington  <hp pobox com>
+
+	* Makefile.am (test_recently_used_LDADD): Test program for
+	recently used object; object itself isn't in the library yet.
+
+2000-01-14  Iain Holmes  <ih csd abdn ac uk>
+
+	* gnome-about.[ch]: Changed gnome_about_new_url to 
+	gnome_about_new_with_url.
+
+	* gnome-cursors.c: Removed the extra cursors that weren't needed.
+	
+2000-01-14  Iain Holmes  <ih csd abdn ac uk>
+
+	* gnome-cursors.c: Changed the white value to be full white, changed
+	the background and foreground's round on some of the cursors. Changed 
+	the eggtimers foreground colour to yellow.
+
+2000-01-14  ERDI Gergo  <cactus cactus rulez org>
+
+	* gnome-cursors.c: Changed the cursor foreground/background WHITE
+	color to white instead of yellow (there was an offset bug in the
+	R/G/B values). Corrected height of PointingHand cursor.
+
+2000-01-13  Havoc Pennington  <hp redhat com>
+
+	* gnome-gconf.c: fix the version of liboafgnome we require.
+
+        * Makefile.am: add initial file save dialog stuff, not to the 
+	lib but as a test prog. just a prototype; may use James Cape version
+        instead.
+	
+	* libgnomeui.h: emacs magic
+
+	* gnome-gconf.c (gnome_gconf_post_args_parse): ref/sink the global
+	GConfClient. Also, fix indentation.
+
+2000-01-12  Havoc Pennington  <hp redhat com>
+
+	* gnome-app-helper.c: delete obsolete comment
+
+2000-01-13  Elliot Lee  <sopwith redhat com>
+
+	* gnome-helpsys.c: Make use of textfu, and start work on 'point for popup help'.
+	* gnome-helpsys.h: Change API slightly, plus reorder structure.
+
+	* gnome-textfu.[ch]: Implement a simple text display widget for
+	use in popup help. Still lacking the proper tag set, and for some
+	reason it's not getting the button press/release events.
+
+2000-01-13  ERDI Gergo  <cactus cactus rulez org>
+
+	* gnome-cursors.c (gnome_stock_cursor_new): Fixed the GDK crash
+	when a cursor gets requested several times
+
+Wed Jan 12 15:51:18 2000  ERDI Gergo  <cactus cactus rulez org>
+
+	* gnome-about.h: Added rewrite notice
+
+	* gnome-about.c (gnome_about_draw, gnome_about_calc_size):
+	Compile-time option to show/hide URLs
+
+2000-01-12  Iain Holmes  <ih csd abdn ac uk>
+
+	* gnome-cursors.c: Fixed a typo that meant cursor zoom-in was being
+	registered twice, instead of zoom-out.
+
+2000-01-12  Havoc Pennington  <hp pobox com>
+
+	* gnome-gconf.c (gnome_gconf_client_get): Add a global
+	GConfClient, and init stuff for creating it and setting up 
+	GConf. Not yet added to GNOMEUI_INIT macro; wondering 
+	if we want this stuff for _every_ gnome app. Probably we do.
+
+2000-01-11  Havoc Pennington  <hp pobox com>
+
+	* gnome-messagebox.c (gnome_message_box_new): 
+	Format title as "Error (Gnumeric)" rather than 
+	"Error: Gnumeric"
+
+2000-01-12  Martijn van Beers  <martijn earthling net>
+
+        * gnome-gconf.[ch]: added get/set functions for
+        Gnome(File|Icon|Pixmap)?Entry
+
+2000-01-11  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-gconf.c (gnome_gconf_gnome_color_picker_get): added new
+	function.  Home for food.
+
+2000-01-11  Havoc Pennington  <hp redhat com>
+
+	* gnome-messagebox.c (gnome_message_box_new): Use human readable
+	name in the message box title.
+	(gnome_message_box_set_default, gnome_message_box_set_modal): 
+	Removed, now obsolete
+
+2000-01-10  Havoc Pennington  <hp redhat com>
+
+	* gnome-ditem-edit.c: Finish this up; it compiles; haven't tried
+	it out.
+
+2000-01-12  Martijn van Beers  <martijn earthling net>
+
+        * gnome-gconf.[ch]: added get/set functions for GtkSpinButton
+
+2000-01-11  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-gconf.h: added more functions.
+
+2000-01-11  Iain Holmes  <ih csd abdn ac uk>
+
+	* gnome-about.c: (gnome_about_item_cb): Changed the cursors to use the
+	gnome-cursor stuff, and to return to the default cursor instead of
+	the GDK_LEFT_PTR when you leave the url.
+
+2000-01-10  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-gconf.[ch]: New module.  Lets you
+	convert GtkWidget <-> GConfValue.  Will be useful in a number of
+	places.
+
+2000-01-10  ERDI Gergo  <cactus cactus rulez org>
+
+	* gnome-about.c (gnome_about_fill_info): The fonts defined by the
+	current GTK+ style are now honored
+
+2000-01-10  Havoc Pennington  <hp redhat com>
+
+	* gnome-about.c (gnome_about_construct): push visual/cmap when
+	creating the canvas so we can render gdkpixbuf to it reliably
+
+2000-01-10  ERDI Gergo  <cactus cactus rulez org>
+
+	* gnome-about.[ch] : Complete rewrite using the GnomeCanvas, a new
+	constructor (gnome_about_new_url) allows the easy inclusion of
+	URLs for both the project and individual authors.
+
+2000-01-07  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-pixmap.c: use the new gdk-pixbuf scaling functions.
+	* gnome-pixmap.h: use the new gdk-pixbuf scaling functions.
+	* gnome-stock.c (gdk_pixbuf_new_from_stock_pixmap_entry): use the
+	new gdk-pixbuf scaling functions.
+
+2000-01-07  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c (app_book_delete_event, app_toplevel_delete_event):
+	fixed a bug that kept a deleted empty toplevel in windows list,
+	causing occasional warnings & segfaults.
+	
+2000-01-06  Elliot Lee  <sopwith redhat com>
+
+	* gnome-icon-list.[ch]: Port to gdk-pixbuf. Switch from a linked list to an array for storing the icons (faster!)
+	* gnome-icon-entry.[ch], gnome-icon-sel.[ch]: Port to gdk-pixbuf.
+
+	* gnome-canvas-pixbuf.[ch]: Pull updates from gdk-pixbuf module.
+
+	* gnome-druid.c: When going to a new page, unmap the old one unconditionally.
+
+Wed Jan 05 23:41:20 2000  George Lebl <jirka 5z com>
+
+	* gnome-client.[ch]: the save_yourself signal has a return value but
+	  the gtk_signal_emit wasn't catching it.  So get it and ignore it
+	  to avoid segfaults and warnings.
+
+2000-01-05  ERDI Gergo  <cactus cactus rulez org>
+
+	* gnome-about.c: Removed all the hardcoded layout constants and
+	used #define's instead. Next step is a complete rewrite using
+	GnomeCanvas.
+
+Sat Jan 01 18:58:12 2000  George Lebl <jirka 5z com>
+
+	* gnome-dentry-edit.c: use LC_MESSAGES category instead of LC_ALL
+	  for the message translations of the dentry fields
+
+Wed Dec 29 16:53:35 1999  George Lebl <jirka 5z com>
+
+	* oafgnome.c: add include for unistd.h and fcntl.h to make this
+	  actually compile
+
+1999-12-26  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi-child.[ch] (gnome_mdi_child_set_toolbar_template):
+	new function for setting child's toolbar template.
+	(gnome_mdi_child_set_toolbar_position): set default values for
+	toolbar insertion.
+	(gnome_mdi_child_add_toolbar): adds a toolbar to an app using
+	default values stored in the child.
+	* gnome-mdi.c (gnome_mdi_view_changed): take care of child's
+	toolbar.
+	(book_button_release): a fix to get the [view|child]_changed signal
+	emitted when a page is dropped on the notebook.
+	* gnome-mdiP.h: add a new #define for child's toolbar UIInfo key
+	and its name.
+	* gnome-mdi.h: indentation improvements.
+
+1999-12-25  Ettore Perazzoli  <ettore gnu org>
+
+	[From Morten Welinder <terra diku dk>]
+	* gnome-app.c (gnome_app_destroy): Unref the dock layout if not
+	NULL.
+
+1999-12-21  Iain Holmes  <ih csd abdn ac uk>
+
+	* gnome-helpsys.c (gnome_help_app_topics): Removed extra loop 
+	iterator, to prevent a crash.
+	(gnome-help_path_resolve): Same.
+
+1999-12-21  Havoc Pennington  <hp redhat com>
+
+	* oafgnome.c (rcmd_activator): make it compile
+
+	* gnome-preferences.h: take load/save custom out of the header
+	(this hasn't compiled for ages, don't know why no one noticed).
+
+	* gnome-stock.h, gnome-stock.c: emacs magic
+
+	* gnome-pixmap.c, gnome-pixmap.h: Add copyright notices and file
+	magic. comment cleanup
+
+	* gnome-ditem-edit.h, gnome-ditem-edit.c: mostly cut-and-paste 
+	from gnome-dentry-edit, not testable until we get the icon list.
+	
+Tue Dec 21 02:06:25 1999  George Lebl <jirka 5z com>
+
+	* gnome-calculator.[ch]: make the get_result be a function rather
+	  then a macro to make bindings easier
+
+1999-12-20  Elliot Lee  <sopwith redhat com>
+	* *.h: Shuffle structure elements around.
+	* gtkpixmapmenuitem.c: Import fix from gnome-libs-1-0
+	* oafgnome.c, gnome-remote-bootstrap.c: Pass $LANG
+
+1999-12-20  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.[ch]: major source compatibilty mayhem;
+	(gnome_mdi_remove_view, gnome_mdi_remove_child): drop the force
+	parameter. always respect the return from the corresponding
+	signal handler.
+	(gnome_mdi_new_toplevel): new function.
+	(gnome_mdi_app_create, gnome_mdi_view_changed): new default signal
+	handlers. both these signals now RUN_FIRST.
+	(gnome_mdi_update_child): not public any more.
+	lots of fixes and simplifications of the code;
+	* gnome-mdi-child.c: #include<gnome-mdiP.h> and use the new
+	functions
+	* gnome-mdi-session.c: #include<gnome-mdiP.h>
+	(restore_window_child): show the window _after_ it has been messed
+	with.
+	* gnome-mdiP.h: a private header with stuff shared between all
+	gnome-mdi-* modules.
+	* Makefile.am: put gnome-mdiP.h in libgnomeui_la_SOURCES as this
+	does not install it.
+
+1999-12-15  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c (gnome_mdi_get_child_menu_info): fix a typo in
+	documentation comment.
+
+1999-12-15  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-druid.c (gnome_druid_insert_page): only map the page if
+	it's the only page. otherwise, unmap it.  This should let us add
+	pages to an already mapped druid.
+
+1999-12-14  Havoc Pennington  <hp redhat com>
+
+	* libgnomeui.schemas: schemas file for UI Preferences.
+
+	* libgnomeui.h: GNOME_EXCLUDE_DEPRECATED on gnome-preferences.h
+
+	* gnome-preferences.h: Comment that says this stuff is deprecated.
+
+	* gnome-preferences.c: Move GnomePreferences struct back into .c
+	file; with GConf, it should not be public.
+
+1999-12-13  Havoc Pennington  <hp redhat com>
+
+	* gnome-cursors.c (gnome_stock_cursor_new): support standard X
+	cursors (you can make a stock cursor that specifies their color).
+
+1999-12-13  Havoc Pennington  <hp redhat com>
+
+	* gnome-cursors.c: New module, stock cursors from Iain Holmes.
+
+Sun Dec 12 10:57:40 1999  George Lebl <jirka 5z com>
+
+	* gnome-calculator.c: check for number on stack AFTER we reduce
+	  stack, this fixes a segfault where reduce_stack actually did
+	  reduce the stack. Fixes bug #4330
+
+1999-12-12  James Henstridge  <james daa com au>
+
+	* libgnomeui.h: include gnome-unit-spinner.h.
+
+	* Makefile.am (EXTRA_DIST): added portrait.xpm and landscape.xpm
+	pixmaps for the new gnome-paper-selector.
+	(libgnomeui_la_SOURCES): added gnome-unit-spinner.c
+	(gnome_headers): added gnome-unit-spinner.h
+
+	* portrait.xpm, landscape.xpm: image files for the new paper selector.
+	
+	* gnome-paper-selector.[ch]: new paper selector.  It should be source
+	source compatible with the old one, but you would probably want to
+	modify your code to take advantage of the newer features.
+	
+	* gnome-unit-spinner.[ch]: new widget.  A GtkSpinButton type widget
+	that understands different units.
+
+1999-12-07  Martin Baulig  <martin home-of-linux org>
+
+	* Makefile.am: Removed all HistoryDB stuff.
+
+	* libgnomeui.h: Don't include "gnome-compat.h" which does no longer
+	exist.
+
+1999-12-05  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-dialog.c (gnome_dialog_button_clicked): no need for saving
+	click_closes as gnome_dialog_clicked() takes care of this.
+	* Makefile.am: changed all references to gdk-pixbuf/src to
+	gdk-pixbuf/gdk-pixbuf.
+	
+1999-12-04  Elliot Lee  <sopwith redhat com>
+
+	* gtkpixmapmenuitem.c: Fix size_request/size_allocate - was HORRIBLY broken before.
+
+1999-12-01  Havoc Pennington  <hp pobox com>
+
+	* gnome-canvas-pixbuf.h, gnome-canvas-pixbuf.c: Copy latest
+	version from gdk-pixbuf.  gdk-pixbuf has the master copy; do not
+	modify this libgnomeui copy.
+
+	* gnome-dialog.c (gnome_dialog_clicked): New function, 
+	emits the "clicked" signal
+
+Mon Nov 29 09:17:02 1999  Dietmar Maurer  <dm vlsivie tuwien ac at>
+
+	* gnome-app-helper.c: use GNOME_APP_PIXMAP_NONE instead of the
+          blank stock pixmap for configurable items.
+
+1999-11-28  Havoc Pennington  <hp pobox com>
+
+	* gnome-pixmap.h: include gdk-pixbuf before gnome-defs, seems to
+	be required for some reason. 
+	
+        The below is all still wrong; if you have a gdk-pixbuf installed
+	it will probably use the wrong one.
+	
+	* gnome-pixmap.c: angle
+
+	* gnome-color-picker.h: angle brackets
+
+	* gnome-icon-entry.c: <gdk-pixbuf/gdk-pixbuf.h>
+
+	* gnome-canvas-pixbuf.c: angle brackets
+
+	* gnome-calculator.c: angle brackets
+
+	* Makefile.am (INCLUDES): Put $(top_srcdir)/gdk-pixbuf at the top
+	of the include list; remove $(top_srcdir)/src from the search path.
+
+	* gnome-pixmap.h: put gdk-pixbuf/gdk-pixbuf.h in angle brackets
+
+1999-11-24  Elliot Lee  <sopwith redhat com>
+
+	* gnome-app.c (gnome_app_add_dock_item): emit the "layout_changed" signal even if adding the dock item to app->layout.
+
+1999-11-23  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-druid-page-edge.c (gnome_druid_page_edge_new): new
+	widget.  Moved gnome_druid_page_edge_finish/start away, and moved
+	their functionality into a single widget.
+	(gnome_druid_page_edge_prepare): add a GNOME_EDGE_OTHER.
+
+1999-11-22  Jonathan Blandford  <jrb redhat com>
+
+	* Makefile.am: add gnome-canvas-pixbuf.  Retool the compat library
+	a bunch.
+
+Thu Nov 18 11:20:01 1999  George Lebl <jirka 5z com>
+
+	* gnome-entry-edit.c: when syncing display with a dentry, clear
+	  the translations list first. Fixes bug #3652.
+
+1999-11-15  Elliot Lee  <sopwith redhat com>
+
+	* gnome-app-helper.[ch]: Const correctness.
+	* gnome-popup-menu.[ch]: Add gnome_popup_menu_append() and gnome_widget_add_popup_items().
+
+1999-11-13  Jacob Berkman  <jberkman andrew cmu edu>
+
+	* gnome_segv.c (main): use g_basename() instead of
+	g_filename_pointer
+
+1999-11-11  Jacob Berkman  <jberkman andrew cmu edu>
+
+	* gnome_segv.c (main): correctly detect if gnome-session
+	crashed when gnome-session was run with a full path (ie from
+	gdm2).   Disable SM on bug-buddy if gnome-session crashed,
+	and pass parameters to bug-buddy via command line options,
+	and not through the environment.
+
+Wed Nov 10 20:15:10 1999  George Lebl <jirka 5z com>
+
+	* gnome-propertybox.c: use GPOINTER_TO_INT to cast from pointer
+	  to int. in _set_modified method use the same assert checks as in
+	  the _changed method.
+
+1999-11-09  Elliot Lee  <sopwith redhat com>
+	* gnome-helpsys.[ch]: gnome_widget_set_tooltip()
+	* gnome-popup-menu.[ch]: It works for all widgets (no_window widgets require extra care & feeding :)
+
+	* gnome-app-helper.[ch]: Add GNOME_APP_UI_INCLUDE type to include another GnomeUIInfo table inline.
+
+	* gnome-init.[ch]: Add LIBGNOMEUI_PARAM_DISPLAY.
+
+	* gnome-dock-item.[ch]: Add an orientation_changed signal.
+	* gnome-helpsys.[ch]: New implementation.
+	* gnome-app-helper.c: Use helpsys API function for reading the topic list and displaying help.
+	* gnome-app.[ch]: Add gnome_app_set_help_view().
+
+1999-11-04  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-druid.c (gnome_druid_init): patch from boc to give the
+	next button the focus.
+
+1999-11-04  Federico Mena Quintero  <federico redhat com>
+
+	* gnome-app-helper.c: Patch from Eric Gillespie,
+	Jr. (epg pobox com).  The About item should not have ellipsis.
+
+1999-11-03  Federico Mena Quintero  <federico redhat com>
+
+	* gnome-canvas.c (gnome_canvas_item_get_bounds): Fixed ordering of
+	bounding vertices.  Now we *do* return the correct bounding box.
+
+1999-11-03  Federico Mena Quintero  <federico redhat com>
+
+	* gnome-canvas.c (gnome_canvas_init): Fixed long-standing problem
+	with the canvas->pick_event not being properly initialized.  This
+	caused spurious EnterNotify events to be sent to items right after
+	the canvas was created and the mouse had never been inside it.
+
+1999-11-02  Kjartan Maraas  <kmaraas online no>
+
+	* gnome-druid-page-standard.c: #include <config.h>
+	* gnome-druid-page-start.c: ditto.
+	* gnome-druid-page-finish.c: ditto.
+	* gnome-druid-page.c: ditto.
+	* gnome-druid.c: ditto.
+	* gnome-stock.c (gnome_pixmap_button): Marked label creation
+	with _() to make buttons translatable.
+
+1999-10-26  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c (gnome_mdi_remove_view): if a registered object exists,
+	destroy an empty GnomeApp even if it is the last one.
+
+1999-10-22  Jonathan Blandford  <jrb redhat com>
+
+	* Makefile.am (libgnomeui10compatinclude_HEADERS): add this.
+
+1999-10-21  Federico Mena Quintero  <federico redhat com>
+
+	* gnome-canvas.c (gnome_canvas_set_pixels_per_unit): Clear the
+	redraw area to avoid creating enormous microtile arrays when we
+	zoom repeatedly.
+
+1999-10-20  Elliot Lee  <sopwith redhat com>
+
+	* gnome-init.c: Fix the memory leak AND avoid the bug from the first fix.
+
+Mon Oct 18 21:51:43 1999  George Lebl  <jirka 5z com>
+
+	* gnome-app-util.c: use gnome_request_dialog directly instead
+	  of using old deprecated functions
+
+1999-10-18  Jonathan Blandford  <jrb redhat com>
+
+	* Makefile.am (libgnomeui10compat_a_SOURCES): beginnings of the
+	compat library.  I'm not 100% sure I set this up correctly,
+	though.
+	* gtk-ted*: Blown away!!!
+
+1999-10-11  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-messagebox.c (gnome_message_box_new): add a label field to
+	GnomeMessagebox.  Removed gnome_message_box_set_{modal,default}.
+
+1999-11-18  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-pixmap.c (paint_with_pixbuf): now have all the composite
+	stuff done.  Still need to document et al., but the end is in
+	sight.
+	(generate_state): added docs.  Added a DARK_FACTOR to insensitive pixbufs.
+
+1999-11-16  Havoc Pennington  <hp pobox com>
+
+	* gnome-pixmap-entry.c (refresh_preview): Fix call to gnome_pixmap_set_pixbuf()
+
+	* gnome-init.c (libgnomeui_pixbuf_image_loader): Fix
+	gnome_pixbuf_render() here. I have the bad feeling this breaks
+	things badly unless we always use the GdkRGB visual/cmap
+
+	* gnome-about.c (gnome_about_construct): fix to match new
+	gnome_pixbuf_render() API
+	(gnome_about_construct): Use GdkRGB visual/cmap for now
+
+	* libgnomeui.h: comment out icon stuff, and druid-page-finish
+
+	* gnome-pixmap.c (gnome_pixmap_set_pixbuf): Ref new pixbuf before clearing.
+
+Thu Nov 11 00:08:14 1999  George Lebl <jirka 5z com>
+
+	* gnome-calculator.c: support more then 2 accelerators per key
+	  and use ',' for decimal point
+
+	* gnome-icon-entry.c: added a changed signal, I couldn't actually
+	  compile and test this but the change is so minial it should
+	  just work
+
+1999-11-09  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-color-picker.c (render): gdk_pixmapified.
+
+	* winhints_demo.c (prepare_app): gdk_pixmapified.
+
+1999-11-09  Havoc Pennington  <hp pobox com>
+
+	* gnome-pixmap.c (match_representation_to_mode): New function
+	converts pixbuf->pixmap or vice-versa if you set pixbuf in pixmap
+	mode or vice-versa.
+
+1999-11-08  Havoc Pennington  <hp pobox com>
+
+	* gnome-pixmap.c (gnome_pixbuf_scale): fix no-scaling-needed case
+	to work properly. Some other bug fixes
+
+	* gnome-stock.c (stock_pixmaps): specify that the rgb data has no
+	alpha for now (since it doesn't)
+
+	* gnome-init.c (gtk_post_args_parse): gdk_rgb_init()
+
+	* gnome-pixmap.c (resize_to_fit): fix typo, s/PIXMAP/PIXBUF/
+	(paint_with_pixbuf): Um, actually draw the pixbuf.
+
+	* gnome-stock.c (gnome_stock_init): Set the pixmap mode here, not 
+	in specific constructors.
+
+Sat Nov 06 13:12:11 1999  George Lebl <jirka 5z com>
+
+	* gnome-calculator.c: count active widgets and after we destroy
+	  the last one, kill our font pixmap, also don't use the
+	  unconditional pixmap file routine as we want to check if the
+	  file exists or not
+
+1999-11-05  Havoc Pennington  <hp pobox com>
+
+	* gnome-pixmap.c (gnome_pixmap_set_mode): implemented
+
+	* Makefile.am: Comment out property entries, they use the color
+	picker.
+	comment out dentry editor, it uses icon entry.
+
+	* gnome-init.c (libgnomeui_post_args_parse): Don't init imlib
+	(libgnomeui_pixbuf_image_loader): Replaces libgnomeui_imlib_image_loader
+
+	* Makefile.am: Comment color picker out
+	comment out gnome-druid for now too
+	comment out icon list
+	comment out icon selector
+	comment out icon entry
+
+	* gnome-pixmap-entry.c: Port to gdk-pixbuf
+	(setup_preview): port to gdk-pixbuf
+
+	* gnome-pixmap.c (gnome_pixbuf_build_insensitive): init width and
+	height variables
+
+	* gnome-app-helper.c (create_pixmap): fix cast on xpm data to
+	match const char**
+
+	* gnome-pixmap.c (gnome_pixmap_new_from_xpm_d_at_size): const on
+	the xpm_data
+	(gnome_pixmap_new_from_xpm_d): ditto
+
+	* gnome-messagebox.c (gnome_message_box_newv): Port to new GnomePixmap
+	(gnome_message_box_new): Port to new GnomePixmap
+
+	* gnome-pixmap.c (set_pixmaps): Allow pixmaps/masks to be NULL for "unset"
+	(set_pixbufs): Ditto
+	(set_pixbuf): Ditto
+	(gnome_pixmap_clear): New function to clear all pixmaps
+
+	* gnome-druid.c (gnome_druid_init): port to gdk-pixbuf
+
+	* gnome-app-helper.c (create_pixmap): Use
+	gnome_stock_new_with_icon() instead of gnome_stock_pixmap_widget()
+
+	* gnome-icon-entry.c (entry_changed): port to gdk-pixbuf
+
+	* gnome-pixmap.c (gnome_pixbuf_scale): If new w/h are the same as
+	old w/h just use memcpy() instead of scaling.	
+	(gnome_pixmap_set_pixbuf_at_size): New function
+	(gnome_pixmap_set_pixbuf): New function
+	(set_pixbuf): New function, used by set_pixbufs and above two
+	functions. Also implements automatic mask generation.
+
+	* gnome-pixmap.h: add a little comment about not using GnomePixmap
+	as an image loader.
+
+	* gnome-druid.h: include gnome-defs.h
+
+	* gnome-druid-page.h: include gnome-defs.h
+
+	* gnome-druid.c: Don't include gnome.h
+
+	* libgnomeui.h: Comment out animator, canvas image, canvas load
+	headers for now.
+
+	* Makefile.am: Comment out gnome-canvas-load.c
+	(INCLUDES): Remove GDK_IMLIB_CFLAGS
+
+	* gnome-canvas-load.h: Delete header contents; they aren't needed
+	with gdk-pixbuf	
+
+	* Makefile.am: Comment out gnome-canvas-image.c for now
+
+	* gnome-calculator.c (gnome_calculator_realized): port to
+	gdk-pixbuf; was using GnomePixmap just to load an image (please
+	people, could we be ANY MORE BROKEN in a million years? GnomeAbout
+	and GnomeAnimator were doing the same thing)
+	(put_led_font): Port to gdk-pixbuf, and don't draw with the image
+	if we failed to load it.
+
+	Note that GnomeCalculator is still broken because the font pixmap
+	is leaked if you destroy all the outstanding GnomeCalculator
+	widgets. Should probably use a GdkPixbuf as the representation
+	instead of creating a pixmap, and render from client side. Then
+	refcount the GdkPixbuf.
+
+	* Makefile.am: Comment out gnome-animator.c for now
+
+	* gnome-animator.c
+	(gnome_animator_append_frame_from_gnome_pixmap): Deleted this
+	function. It makes no sense, doesn't work with new GnomePixmap,
+	and was marked experimental.
+	(free_all_frames): port to gdk-pixbuf
+	(gnome_animator_append_frame_from_imlib_at_size): Removed
+	(gnome_animator_append_frame_from_imlib): Removed
+	(gnome_animator_append_frames_from_imlib_at_size): Removed
+	(gnome_animator_append_frames_from_imlib): Removed
+
+	* gnome-about.c (gnome_about_construct): port to gdk-pixbuf
+
+	* gnome-pixmap.c (gnome_pixbuf_render): Render a pixbuf to pixmap/mask
+
+	* gnome-stock.c (gnome_pixmap_button): Remove some weird pixmap 
+	registration stuff that no longer works and I don't understand the 
+	purpose of.
+	(gnome_pixmap_button): Unref the pixmap if it isn't placed in the
+	button due to user preferences. Long-standing mem leak.
+	(gnome_stock_pixmap_gdk): Port to gdk-pixbuf
+	(gnome_stock_transparent_window): port to gdk-pixbuf
+
+	* gnome-stock.h: rename gnome_stock_pixmap_checkfor() to
+	gnome_stock_pixmap_lookup()
+
+	* gnome-stock.c: Rewrite the stock pixmap hash. We now store
+	entries for all 5 states, and we do a single lookup to get all
+	five states at once. Also, the GnomeStock widget now simply gets a 
+	reference to the GdkPixbuf stored in the hash. We also free memory
+	associated with unscaled pixbufs, filenames, etc. once we have the
+	final pixbuf cached.
+	(gnome_stock_new): Set GNOME_PIXMAP_KEEP_PIXBUF mode since we are
+	usually using a pixbuf shared with other GnomeStock widgets.	
+	(gnome_stock_set_icon): Implement
+	(gnome_stock_pixmap_register): Don't return success/failure, that
+	makes no sense (it always succeeded anyway)
+	(gnome_stock_pixmap_change): Ditto
+
+	* gnome-stock.h: Replace all "subtype" string arguments with
+	GtkStateType enum arguments. 
+
+1999-11-04  Havoc Pennington  <hp pobox com>
+
+	* gnome-stock.c: Remove GnomeStockPixmapEntryWidget and 
+	GnomeStockPixmapEntryGPixmap; these no longer make any sense.
+
+	* gnome-stock.h: GnomeStockPixmapEntry made opaque, all struct
+	contents moved to gnome-stock.c. Added new constructors and
+	destructors for creating a GnomeStockPixmapEntry.
+	
+	* gnome-stock.c: Removed functions I removed from the header last
+	week (deprecated stuff that had been spewing warnings or not
+	compiled at all).
+	
+	* gnome-stock.h: GnomeStockPixmapEntryRGB,
+	GnomeStockPixmapEntryRGBScaled added to replace Imlib versions
+	
+	* gnome-pixmap.c (gnome_pixbuf_scale): Add this here; it's
+	scale_down originally in gnome-stock.c. We no longer handle 
+	the magic alpha color, and we do handle full alpha.
+
+	* gnome-stock.c (gnome_stock_set_icon): Don't return success or
+	failure; if the icon doesn't exist, spew warnings.
+	(gnome_stock_set_icon_at_size): ditto
+	(gnome_stock_new_with_icon): don't check return val from set_icon
+	(gnome_stock_set_icon): Check whether the new icon is the same as
+	the old right at the start of the function.
+	(scale_down): mostly moved to gnome-pixmap.c as gnome_pixbuf_scale()	
+	
+1999-10-25  Havoc Pennington  <hp pobox com>
+
+	* gnome-pixmap.c: set parent_class to NULL 
+
+	* gnome-stock.h: Further enhance the gnome-stock header. Remove
+	all functions that spew "don't use me" when used; group things
+	logically; add new _at_size() constructor and mutator for the
+	GnomeStock widget.
+
+	* gnome-pixmap.h, gnome-pixmap.c: Rewrite. Now supports a
+	different pixmap for every state, so we can migrate this
+	functionality out of GnomeStock. Also, uses gdk-pixbuf instead of
+	Imlib, and on Owen's recommendation does not use a shaped window.
+	Also, now derives from GtkMisc so you can set alignment, etc.
+	Compat functions not yet in place. Doesn't compile either,
+	untested and depends on some nonexistent GdkPixbuf stuff.
+	
+	* gnome-stock.c: Delete all the stuff that wasn't being compiled 
+	due to the USE_NEW_GNOME_STOCK #define
+
+	* gnome-stock.h: Don't define USE_NEW_GNOME_STOCK, unconditionally
+	compile the new stuff, delete the old stuff. 
+	Move all GNOME_STOCK_* string constant macros to gnome-stock-ids.h
+	Delete large comment at the top, it was outdated.
+	Delete Imlib entry types (need compat for these)
+	Make xpm_data in the XPM entry type const 
+	Delete all the regular/disabled/focus fields in GnomeStock widget
+	
+	* gnome-stock-ids.h: New file to unclutter gnome-stock.h
+	
+1999-10-10  Havoc Pennington  <hp pobox com>
+
+	* gnome-less.c: Remove the stupid popup menu, breaks binary
+	compatibility.
+	(gnome_less_fixed_font): This was deprecated about a year ago, 
+	removed.
+	(gnome_less_set_font): reformat
+
+1999-10-08  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi-session.c (restore_window): take care of the case when
+	there are no children to restore: merely open a new, empty toplevel
+	window.
+
+1999-10-07  Elliot Lee  <sopwith redhat com>
+
+	* animator_demo.c, dock_demo.c, gnome-app-helper.c,
+ 	gnome-client.[ch], gnome-entry.c, gnome-init.[ch]: Use new init
+ 	system
+	* gnome-dateedit.c: Fix warning, include ctype.h for isdigit().
+	* gnome-dentry-edit.c, gnome-icon-entry.c, gnome-icon-sel.c: Avoid using deprecated functions.
+	* makeenums.pl: Skip files with / DEPRECATED / in them.
+	* gnome-dns.h, gnome-font-selector.h, gnome-guru.h, gnome-less.h,
+ 	gnome-preferences.h, gnome-properties.h, gnome-property-entries.h,
+ 	gnome-spell.h, gnome-startup.h, gtk-ted.h, gtkcauldron.h: Add deprecated marking so
+ 	makeenums.pl will skip this
+	* gnometypebuiltins*.[ch]: Rebuild
+	* libgnomeui.h: Exclude all deprecated stuff. Add defines for backwards source compat to new system.
+
diff --git a/libgnomeui/ChangeLog-19990928 b/libgnomeui/ChangeLog-19990928
new file mode 100644
index 0000000..f4a488a
--- /dev/null
+++ b/libgnomeui/ChangeLog-19990928
@@ -0,0 +1,9823 @@
+1999-09-28  Elliot Lee  <sopwith redhat com>
+	* gnome-init.c (gnome_segv_handle): Only dump core if $GNOME_DUMP_CORE is set.
+	  Pass the app version to gnome_segv.
+	* gnome_segv.c: add more items to the URL that is given to the user (app
+	version, 
+
+1999-10-06  Jacob Berkman  <jberkman andrew cmu edu>
+
+	* gnome_segv.c (main): add a hook for the soon-to-be available
+	bug-buddy program
+
+Tue Oct  5 02:35:47 1999  Owen Taylor  <otaylor redhat com>
+ 
+ 	* gnome-init.c (initialize_gtk_signal_relay): Free value
+ 	returned from gnome-config.
+ 
+1999-10-05  Russell Steinthal  <rms39 columbia edu>
+	* gnome-dateedit.c (gnome_date_edit_get_date): Improve handling of
+	invalid times: don't segfault when there is no colon in a time,
+	default omitted trailing time fields (i.e. allow 8 for 8:00:00).
+	Allow entry of seconds.
+
+1999-10-03  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-dock.c (drag_floating): Realize, map and queue_resize the
+	new child manually.
+
+	* gnome-dock-band.c (gnome_dock_band_remove): Do
+	`gtk_widget_unparent' on the removed widget instead of just
+	NULLing the `parent' member.  This way refcounting on the
+	GnomeDockBand children should be done right.  Many many thanks to
+	Morten who detected there was a leak somewhere in the GnomeDock*
+	widgets.  (And some curses to the author who had even put a
+	`FIXME' comment in that code and forgot to correct it. ;-))
+
+1999-09-30  Miguel de Icaza  <miguel gnu org>
+
+	* gnome-icon-entry.c (show_icon_selection): Replace getcwd with
+	g_get_current_dir here too.
+	(show_icon_selection): ditto.
+
+	* gnome-file-entry.c (gnome_file_entry_get_full_path): Use
+	g_get_current_dir here. 
+
+1999-09-28  Elliot Lee  <sopwith redhat com>
+	* gnome-dock-item.c: If an item is really small, don't subtract
+	  DRAG_HANDLE_SIZE from it to make its size < 0.
+
+1999-09-28  Havoc Pennington  <hp pobox com>
+
+	* gnome-init.c (gnome_segv_handle): Improve the "can't display
+	error dialog" error message.
+
+1999-09-27  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-mdi-session.c (gnome_mdi_save_state): Call
+	gnome_config_sync () when we're done.
+
+1999-09-26  Martin Baulig  <martin home-of-linux org>
+
+	* gtkdial.c (gtk_dial_set_percentage, gtk_dial_set_value): Allow
+ 	you to set the upper limit as well (use <= instead of <).
+
+1999-09-24  Morten Welinder  <terra diku dk>
+
+	* gnome-dock-layout.c (gnome_dock_layout_destroy): Don't walk and
+ 	muck with the same list simultaneously.
+	(remove_item): Handle remove of first item also.
+
+1999-09-24  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-mdi-session.c (view_window_func): Return NULL unless
+	the widget is realized.
+
+Fri Sep 24 01:24:40 1999  Tim Janik  <timj gtk org>
+
+	* gnome-canvas.c (gnome_canvas_new_aa): make the AA canvas warning a
+	message, so --g-fatal-warnings remains usefull (bug#2234).
+
+1999-09-23  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-procbar.c: Added g_return_if_fail () at places where this
+	would cause a crash otherwise.
+
+1999-09-09  Vincent Renardias <vincent ldsol com>
+
+	* gnome_segv.c: i18n the URL of the Crash page too.
+	  Added a comment for translators too.
+
+1999-09-22  Federico Mena Quintero  <federico redhat com>
+
+	* gnome-canvas.c (do_update): Moved updated functionality to here.
+	(idle_handler): Do GDK_THREADS_ENTER/LEAVE() here, and call do_update().
+	(gnome_canvas_update_now): Call do_update(), not idle_handler().
+
+	Patch from Owen Taylor (otaylor redhat com) to fix deadlock when
+	using threads.
+
+1999-09-20  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-propertybox.c (gnome_property_box_init): Set the `OK'
+	button as the default one, and do not set it insensitive anymore.
+	(set_sensitive): Do not change sensitivity of the `OK' button
+	anymore.
+	(dialog_clicked_cb): Check the dirty flag for the current page.
+	If the page is not dirty, just close instead of applying and
+	closing: this makes sure the old behavior is preserved even if now
+	OK is no longer insensitive when the page is not dirty.
+
+1999-09-20  Federico Mena Quintero  <federico redhat com>
+
+	* gnome-canvas-rect-ellipse.c (gnome_canvas_re_unrealize): Set the
+	gc fields to NULL after unrefing them.  Thanks to Damon Chaplin
+	for pointing this out.
+
+	* gnome-canvas-text.c (gnome_canvas_text_unrealize): Likewise.
+
+	* gnome-canvas-polygon.c (gnome_canvas_polygon_unrealize): Likewise.
+
+	* gnome-canvas-line.c (gnome_canvas_line_unrealize): Likewise.
+
+	* gnome-canvas-image.c (gnome_canvas_image_unrealize): Likewise.
+
+1999-09-19  Owen Taylor  <otaylor redhat com>
+
+	* gnome-dock-band.c: Don't size-allocate non-visible
+	children, since we don't size-request them. This will
+	avoid problems with warnings since otherwise we
+	will allocating the children with junk allocations.
+
+1999-09-20  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-appbar.c (gnome_appbar_construct): Put alignment back in
+	so that the label is still left-aligned.
+
+1999-09-19  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-appbar.c (gnome_appbar_construct): Set horizontal usize on
+	the label to 1, so that it does not stupidly change size when the
+	text is larger than the available space.
+
+1999-09-19  Havoc Pennington  <hp pobox com>
+
+	* gnome-animator.c (prepare_aux_pixmaps): only create pixmaps
+	if we are realized
+	(size_allocate): Don't do the gdk_window_clear_area() calls
+	unless we are realized
+	(paint): Create backing store here if necessary... bad hack,
+	need realize/unrealize eventually
+
+	Bug reported by Damon Chaplin
+
+	* gnome-dateedit.c (gnome_date_edit_set_popup_range): Regenerate
+	the popup
+	(gnome_date_edit_set_flags): Use ~ instead of ! for bitwise
+	negation. 
+	(gnome_date_edit_set_flags): Set new flags at the beginning 
+	of the function
+
+	All three bugs reported by Damon Chaplin
+	
+	* gnome-font-picker.c (gnome_font_picker_init): Set a default
+	for use_font_in_label_size, bug reported by Damon Chaplin
+
+1999-09-18  Federico Mena Quintero  <federico redhat com>
+
+	* gnome-canvas.c (scroll_to): Fixed little off-by-one error in
+	size computation.
+
+1999-09-17  Federico Mena Quintero  <federico redhat com>
+
+	* gnome-canvas.c (gnome_canvas_expose): Process exposures
+	immediately.  This makes scrolling a lot nicer.
+
+	* gnome-dock.c (gnome_dock_add_floating_item): Do realization,
+	mapping, and redraw queueing the right way.
+	(gnome_dock_set_client_area): Likewise.
+
+	* gnome-dock-band.c (gnome_dock_band_insert): Likewise.
+
+	* gnome-app.c (gnome_app_set_contents): Do all the proper checks
+	with respect to the dock's new client area.  Also, connect a
+	signal handler to the parent_set signal of the contents.
+	(contents_parent_set): Set the app->contents to NULL when the
+	contents are unparented.  This fixes a bug where the app would
+	keep a dangling pointer to the contents when they were removed.
+
+	Note that GnomeDock has an inconsistency with the way the other
+	GtkContainers work; it should barf if its client area is not NULL
+	instead of unparenting it when you try to set a new client area.
+
+	* gnome_segv.c (main): Const correctness for the args variable.
+	If you want this abominable little program to go in, at least make
+	sure it builds cleanly!
+
+1999-09-17  Havoc Pennington  <hp pobox com>
+
+	* gnome-dateedit.h, gnome-dateedit.c: Revert the new consistent
+	function names. This patch should be applied, but not in the
+	stable branch just before 1.0.50 because it's forward
+	incompatible. It can go in after we branch the development
+	gnome-libs.
+
+1999-09-17  Havoc Pennington  <hp pobox com>
+
+	* gnome_segv.c (main): If the crashing process is called
+	"gnome-session," tell the user that they are totally hosed and 
+	should save docs in all apps.
+
+1999-09-17  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-dateedit.c (gnome_date_edit_set_date): New function, same
+	as `gnome_date_edit_set_time()'.
+	(gnome_date_edit_get_time): New function, same as
+	`gnome_date_edit_get_date()'.
+
+1999-09-17  Havoc Pennington  <hp pobox com>
+
+	* gnome_segv.c (main): Don't connect to session manager.
+
+1999-09-17  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-dock.c (gnome_dock_draw): Draw all the floating children
+	as well.
+	(drag_check): Added snap factor for dock detaching.
+	(drag_new): Make sure the offset for the new child is not
+	negative.
+
+1999-09-14  Federico Mena Quintero  <federico redhat com>
+
+	* gnome-canvas-text.c (gnome_canvas_text_init): Do not load a
+	default fontset.  This is fantastically inefficient, since we have
+	to pull the whole big fontset from the server even if we never use
+	it again and replace it immediately with the user-specified font.
+	(gnome_canvas_suck_font): Take into account the fact that the font
+	may be NULL.
+	(get_bounds_item_relative): Likewise.
+	(gnome_canvas_text_draw): Likewise.
+	(gnome_canvas_text_render): Likewise.
+	(gnome_canvas_text_point): Likewise.
+	(gnome_canvas_text_set_arg): Do not try to load a default font if
+	loading the user-specified one fails.
+	(gnome_canvas_text_destroy): Free the sucked font.
+
+1999-09-13  Karl Eichwalder  <ke suse de>
+
+	* winhints_demo.c (about_cb): Add missing \n.
+
+1999-09-13  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c (top_add_view, gnome_mdi_add_view,
+	gnome_mdi_add_toplevel_view): show view prior to setting it an
+	app content.
+	
+1999-09-13  Federico Mena Quintero  <federico redhat com>
+
+	* gnome-canvas-image.c (recalc_if_needed): Only render the image's
+	pixmap if the final width and height are not zero.
+	(gnome_canvas_image_draw): Take into account the fact that we may
+	not have a pixmap at all.
+
+1999-09-11  Roberto Zunino <zunino cli di unipi it>
+
+	* gnome-dns.c: Do not cache 0.0.0.0 results (ie, not found).
+	Do not abuse gdk_input_add.
+
+1999-09-06  Miguel de Icaza  <miguel gnu org>
+
+	* gnome-canvas.c (gnome_canvas_new_aa): Only warn one time about
+	the buginess of the Canvas.
+
+1999-09-10  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-color-picker.c (key_pressed): Provide a way to cancel a
+	color picker dialog by pressing escape.
+
+	* gnome-init.c (gnome_segv_handle): Use abort instead of exit().
+
+1999-09-07  Havoc Pennington  <hp pobox com>
+
+        * gnome-app-helper.h (GnomeUIInfo): Change pixmap_info to
+	gconstpointer. Closes bug 1864.
+	
+	* gnome-app-helper.c (create_pixmap): Take a const argument.
+
+1999-09-07  Elliot Lee  <sopwith redhat com>
+	* gnome-font-selector.c: Don't use X in class_init()...
+
+1999-09-06  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c (gnome_mdi_remove_child): in MODAL mode automatically
+	activate another child if it exists.
+
+1999-09-05  Tim Gerla  <timg means net>
+
+	* gtkdial.c: Started docs
+	* gnome-dns.c: Typo fixes
+
+1999-09-05    <jrb redhat com>
+
+	* gnome-druid-page-finish.c
+	(gnome_druid_page_finish_set_watermark): fix typo (thanks Damon).
+
+1999-09-04  Tim Gerla  <timg means net>
+
+	* gnome-pixmap-entry.c (gnome_pixmap_entry_new): Docs
+	* gnome-spell.c: Doc updates
+	* gnome-href.c: Doc updates
+
+1999-09-04  Tim Gerla 	<timg means net>
+
+	* gnome-color-picker.c: Doc updates
+	* gnome-number-entry.c: More docs
+
+1999-09-03  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-druid-page-finish.c
+	(gnome_druid_page_finish_new_with_vals): don't call gnome_druid_page_finish_new
+	(gnome_druid_page_finish_construct): new policy for watermarks.
+
+	* gnome-druid-page-start.c
+	(gnome_druid_page_start_configure_size): new policy for watermark images.
+	(gnome_druid_page_start_new_with_vals): don't call
+	gnome_druid_page_start_new.
+
+1999-09-02  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-druid-page-standard.c
+	(gnome_druid_page_standard_set_bg_color): set the color of the
+	outside frame.
+
+	* gnome-druid-page.c (gnome_druid_page_paint): Add paint
+	function.  Now redraw problem is gone.
+
+1999-09-01  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-druid.c (gnome_druid_insert_page): Make the first page in
+	the list be shown.
+	(gnome_druid_remove): If a page is deleted, and it is being shown,
+	show the next page.
+	(gnome_druid_insert_page): if a child is added, and the druid is
+	mapped, then map the child to.  Same with realization.
+
+	* gnome-druid-page-standard.c
+	(gnome_druid_page_standard_configure_size): show internal widgets.
+
+1999-08-31  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c (book_create): show notebook before adding it to
+	the gnome-app in case the former will be mapped.
+	(set_active_view): fixed a bug that caused active_child not to get
+	properly set on rare occasions.
+	(gnome_mdi_remove_view): a fix similar to the above.
+
+1999-08-30  Federico Mena Quintero  <federico redhat com>
+
+	* gnome-file-entry.c (gnome_file_entry_get_full_path): Use
+	getcwd() correctly.  This really needs to be done in a portable
+	fashion.  Do tilde expansion, because this thing is supposed to
+	return valid pathnames.
+	(tilde_expand): Stole function from mc/src/utilunix.c to do tilde
+	expansion, glib-ified it.
+
+1999-08-30  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-list.c (gnome_icon_list_append_imlib): Made text const.
+
+	* gnome-canvas.c (gnome_canvas_get_color): Make spec argument take
+	a const char *.
+
+Sun Aug 29 01:14:35 1999  George Lebl  <jirka 5z com>
+
+	* gnome-winhints.c,gnome-init.c: take out implicit initialization
+	  of the atoms, and do it only when we need it. Also replaced all
+	  CARD32 by long since this was being done by the preprocessor
+	  anyway, and made all local Atom variables static.
+
+1999-08-28  Havoc Pennington  <hp pobox com>
+
+	* TODO: Long-overdue TODO update.
+
+Sat Aug 28 10:32:53 1999  George Lebl  <jirka 5z com>
+
+	* gnome-dentry-edit.c: fix warnings
+
+1999-08-28  Karl Eichwalder  <ke suse de>
+
+	* winhints_demo.c (about_cb): Avoid too long lines.
+
+1999-08-27  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-procbar.c (gnome_proc_bar_construct): New function. 
+
+	* gnome-pixmap-entry.c (gnome_pixmap_entry_construct): New function.
+
+	* gnome-dock-item.c (gnome_dock_item_construct): New function.
+
+	* gnome-file-entry.c (gnome_file_entry_construct): New function,
+	per request from Guillaume.
+
+Fri Aug 27 15:41:48 1999  George Lebl  <jirka 5z com>
+
+	* gnome-dentry-edit.c: use the new gnome-dentry interface for 
+	  getting the i18n lists
+
+Fri Aug 27 10:30:10 1999  George Lebl  <jirka 5z com>
+
+	* gnome-dentry-edit.[ch]: add a way to edit the translations of
+	  name and comment on the advanced page
+
+1999-08-26  Federico Mena Quintero  <federico redhat com>
+
+	* gnome-canvas-util.c (gnome_canvas_update_svp): Free the old
+	svp.  BUGFIX:  GNOME bug tracker #1991.
+
+1999-08-25  Havoc Pennington  <hp pobox com>
+
+	* gnome_segv.c (main): Translate usage string,
+	enhance the error message.
+
+	* gnome-init.c (gnome_init_cb): Set flag if we should
+	--disable-crash-dialog; install the signal handler 
+	based on the flag.
+	(gnome_options): Add --disable-crash-dialog option
+	(gnome_segv_handle): Give up after 10 segfaults; 
+	try to release grabs before popping up the dialog.
+
+1999-08-23  Herbert Valerio Riedel  <hvr hvrlab dhs org>
+
+	* gnome-procbar.[ch] (gnome_proc_bar_set_values): made val[] const
+
+	* gtk-ted.[ch], gnome-spell.[ch], gnome-popup-help.[ch], 
+	gnome-pixmap-entry.[ch], gnome-number-entry.[ch], gnome-mdi.[ch],
+	gnome-mdi-generic-child.[ch], gnome-mdi-child.[ch], gnome-entry.[ch],
+	gnome-icon-text.[ch], gnome-icon-entry.[ch], gnome-druid-page-start.[ch],
+	gnome-druid-page-standard.[ch], gnome-druid-page-finish.[ch], 
+	gnome-client.[ch]: marked some more char* args const
+
+1999-08-22  Herbert Valerio Riedel  <hvr hvrlab dhs org>
+
+	* gnome-icon-entry.c (gnome_icon_entry_new): added missing GNOME_ENTRY
+	* gnome-properties.c: added <string.h>
+	* gtkpixmapmenuitem.h, gtkcauldron.h, gtkdial.h, 
+	gnome-druid-page-start.h, gnome-paper-selector.h,
+	gnome-druid-page-standard.h, gnome-druid.h, gnome-druid-page-finish.h, 
+	gnome-druid-page.h: extern "C" replaced by ..._GNOME_DECLS
+	* gnome-canvas-load.[ch], gnome-app-helper.[ch], gnome-app.[ch], 
+	gtk-clock.[ch], gnome-file-entry.[ch], gnome-paper-selector.[ch]: 
+	marked some char* args const
+	* gnome-font-selector.c: strcmp() args casted to (char*)
+	
+1999-08-22  Havoc Pennington  <hp pobox com>
+
+	* gnome-icon-sel.c (gnome_icon_selection_show_icons): Check
+	for destroyed or stop_loading on every iteration, instead of 
+	after all events are expired; should fix bug 1883.
+
+1999-08-22  Havoc Pennington  <hp pobox com>
+
+	* gnome-icon-entry.c (gnome_icon_entry_new): Load the entry's
+	history. Doh. We maybe should have a construct() method for
+	GnomeEntry. Added "keep in sync" comment. Fixes bug 1701, fix from
+	Chris Gonnerman <chris gonnerman usa net>
+
+	* gnome-entry.c (gnome_entry_new): Add comment about syncing.
+
+	* gnome-file-entry.c (gnome_file_entry_new): Add comment about
+	syncing these functions.
+	
+1999-08-22  Havoc Pennington  <hp pobox com>
+
+	* gnome-icon-list.c (gnome_icon_list_thaw): Show the item on 
+	thaw, even if the dirty flag is not set (so it works if you 
+	freeze then thaw without ever changing anything). Fix from 
+	David Meybohm <dm89754 ucf edu> closes bug 1833.
+
+1999-08-22  Havoc Pennington  <hp pobox com>
+
+	* gnome-icon-sel.c (gnome_icon_selection_show_icons): Patch from 
+	David Meybohm <dm89754 ucf edu> fixes multiple-progress-bar bug
+	(happened when changing directories during loading). Closes bug 
+	1832.
+
+Sat Aug 21 12:47:28 1999  George Lebl  <jirka 5z com>
+
+	* gnome-pixmap.c: fix docs for gnome_pixmap_load_file_at_size
+
+Sat Aug 21 12:45:09 1999  George Lebl  <jirka 5z com>
+
+	* gnome-pixmap.c: pretty up the inline docs and divide
+	  Description and Returns
+
+	* gnome-scores.c: add the "/**" comments, but without any
+	  descriptions
+
+Sat Aug 21 12:19:53 1999  George Lebl  <jirka 5z com>
+
+	* gnome-dock.c: document gnome_dock_add_from_layout
+
+	* gnome-doct.c,gnome-dock-layout.c: add #'s for crossreferencing
+
+Sat Aug 21 11:54:16 1999  George Lebl  <jirka 5z com>
+
+	* gnome-procbar.c: completely document the API
+
+Sat Aug 21 11:31:07 1999  George Lebl  <jirka 5z com>
+
+	* gnome-dentry-edit.[ch]: there was a typo in the object, and
+	  there was a call named gnome_dentry_get_dentry, which is the
+	  wrong naming, it should be gnome_dentry_edit_get_dentry, so
+	  I added the latter one and left in the first one for compatibility
+	  but marked it as "not to be used". Also updated other parts of
+	  the documentation
+
+Sat Aug 21 11:18:47 1999  George Lebl  <jirka 5z com>
+
+	* gnome-dialog.c: the # is used to crosslink not the &, and
+	  add a return type description to newv
+
+Sat Aug 21 11:13:54 1999  George Lebl  <jirka 5z com>
+
+	* gnome-client.c: touched up docs for
+	  gnome_client_get_global_config_prefix, still this file has
+	  a bunch of things that need fixing in the docs
+
+Sat Aug 21 11:06:57 1999  George Lebl  <jirka 5z com>
+
+	* gnome-app.c: fix so that documentation for gnome_app_add_dock_item
+	  is actually read
+
+1999-08-19  Federico Mena Quintero  <federico redhat com>
+
+	* gnome-animator.c (free_all_frames): Don't free the mask, since
+	it has already been freed by imlib.
+	(gnome_animator_append_frames_from_imlib_at_size): Likewise.
+
+	* gnome-canvas-image.c (free_pixmap_and_mask): Sigh.  Tell imlib
+	to *only* free the pixmap, not the mask as well.  When you tell
+	imlib to free a pixmap, it will also free its associated mask.  Is
+	that broken, or what?
+
+1999-08-19  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-druid.c (gnome_druid_size_allocate): Patch from damon to
+	put the child in the right place.
+	(gnome_druid_expose): Now I have achieved further enlightenment in
+	the ways of writing a GtkContainer.
+	(gnome_druid_draw): Thanks Owen/HP.  Further Container-hood.
+
+1999-08-19  Havoc Pennington  <hp pobox com>
+
+	* gnome-icon-entry.c (show_icon_selection): Patch from 
+	David Meybohm <dm89754 ucf edu> fixes a race condition
+	segfault (set iconsel as user data before any possibility
+	we might ask for user data)
+
+1999-08-18  Havoc Pennington  <hp pobox com>
+
+	* gnome-entry.c (gnome_entry_init): Set combo case-insensitive.
+	Closes bug 1939.
+
+1999-08-18  Havoc Pennington  <hp pobox com>
+
+	* gnome-font-picker.c (gnome_font_picker_label_use_font_in_label): 
+	If we can't load the font, then don't set it. Fixes bug
+	1625.
+	
+1999-08-17  Havoc Pennington  <hp pobox com>
+
+	* gnome-canvas.h: Mark new_aa() experimental
+
+	* gnome-dialog-util.h: request_string_dialog() is 
+	deprecated.
+
+	* gnome-messagebox.h: Couple deprecated routines in here...
+
+	* gnome-propertybox.h: Deprecate couple of these
+
+	* libgnomeui.h: Deprecate/experimentalize some stuff
+
+1999-08-17  Tim P. Gerla  <timg means net>
+
+	* gnome-less.c: Add documentation
+
+1999-08-17  Federico Mena Quintero  <federico redhat com>
+
+	* gnome-canvas-line.c (gnome_canvas_line_set_arg): Typo fix; do
+	set the gc foreground if the canvas is not AA.
+
+	* gnome-canvas-text.c (gnome_canvas_text_set_arg): Likewise.
+
+1999-08-17  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-popup-help.c (helpwindow_destroy_callback): remove
+	debugging statements.
+
+	* gnome-druid.c (gnome_druid_remove): many changes to make us act
+	as a nicer container.
+
+1999-08-16  Havoc Pennington  <hp pobox com>
+
+	* gnome-druid.c (gnome_druid_destroy): chain up to parent's
+	destroy method
+
+1999-08-16  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-druid-page-standard.c (gnome_druid_page_standard_init):
+	cleaned up the druid a little.
+
+1999-08-13  Federico Mena Quintero  <federico redhat com>
+
+	* gnome-icon-list.c (gil_button_press): Do not rubberband-select
+	if we are already selecting.
+
+	* gnome-icon-item.c (gnome_icon_text_item_select): If the icon
+	text item gets unselected while it is being edited, ask for
+	acceptance with iti_edition_accept() instead of blindly accepting
+	the current string.
+
+1999-08-11  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.c (selection_one_icon_event): Reset the
+	edit_pending and select_pending flags before starting to process a
+	button press.
+	(selection_many_icon_event): Likewise.
+
+1999-08-10  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.c (do_select_many): Added an argument to specify
+	whether it should actually use the event in the emission.
+	(selection_many_icon_event): I am such a doofus.  Fixed delayed
+	computation for icons that are already selected.  This fixes DnD
+	and menus everywhere else.
+
+1999-08-08  Chris Lahey  <clahey umich edu>
+
+	* gnome-canvas-widget.c (gnome_canvas_widget_set_arg): Made it so
+	that if an argument is already set to the value given, it doesn't
+	change it or go through an update step.
+
+1999-08-06  Morten Welinder  <terra diku dk>
+
+       * gnome-canvas.c (shutdown_transients): Plug leak.
+
+1999-08-04  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-pixmap-entry.c (ensure_update): New function to ensure
+	that a pixmap entry is not in the wait queue for updates.
+	(gnome_pixmap_entry_get_filename): Fixed a race condition where
+	this function would return an incorrect NULL if the client called
+	it before the pixmap entry update timer expires.  This would make
+	the panel crash.
+
+1999-08-04  Morten Welinder  <terra diku dk>
+
+	* gnome-stock.c (gnome_stock_destroy): Unref pixmaps.
+
+1999-08-04  Larry Ewing  <lewing gimp org>
+
+	* gnome-canvas.c (gnome_canvas_item_affine_relative): BUGFIX: make sure
+	that we properly set the GNOME_CANVAS_ITEM_AFFINE_FULL flag when 
+	appropriate.
+
+1999-07-31  Tom Tromey  <tromey cygnus com>
+
+	* gnome-client.c (gnome_client_request_save): Don't prompt for
+	logout.  This is now handled in the session manager.
+
+1999-07-31    <dmg csg uwaterloo ca>
+
+	* gnome-file-entry.c: Updated the comments in the functions to
+	make them more explicit.
+
+1999-07-28  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.c (gnome_icon_list_remove): Use icon->selected,
+	not icon->text->selected.  Consider GTK_SELECTION_EXTENDED as
+	well.
+	(select_icon): Likewise.
+	(unselect_icon): Consider GTK_SELECTION_EXTENDED as well.
+	(sync_selection): HOW DID THIS EVER WORK!?  This has to sync the
+	gil->selection, not the list of icons itself.  It seems that no
+	one ever inserted or deleted icons, just appended them.
+	(icon_new_from_imlib): Do not use broken event handling for the
+	icon text item.
+	(selection_one_icon_event): Turn on editing in the icon text item
+	if appropriate.  Adjusted for sane event handling; this makes the
+	code simpler as well.  Ref/unref the text item since it may be
+	destroyed by one of the signal handlers.
+	(selection_many_icon_event): Likewise.
+
+	* gnome-icon-item.c (iti_event): Added an object argument called
+	use_broken_event_handling.  The event model of the icon text item
+	was wrong in old versions; it should not make itself editable, but
+	let the client request it instead.  The icon list now turns off
+	this flag, but old clients can have the expected behavior (much to
+	their pain).
+	(gnome_icon_text_item_start_editing): New function to let the user
+	start the editing state of the icon text item.
+	(gnome_icon_text_item_configure): Documented the is_editable flag
+	as deprecated.  Old clients may still make use of it.
+
+Wed Jul 28 03:14:49 1999  George Lebl  <jirka 5z com>
+
+	* gnome-pixmap-entry.c: fix typo in the inline docs
+
+1999-07-23  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c: Updated all documentation comments.  All
+	functions in gnome-canvas.c now have correct and complete
+	documentation.
+
+	* gnome-canvas-rect-ellipse.c (gnome_canvas_re_set_arg):
+	ARG_*_COLOR_GDK only take the pixel value into account, not the
+	color->{red,green,blue} values.
+
+	* gnome-canvas-polygon.c (gnome_canvas_polygon_set_arg): Likewise.
+
+	* gnome-canvas-line.c (gnome_canvas_line_set_arg): Likewise.
+
+	* gnome-canvas-text.c (gnome_canvas_text_set_arg): Likewise.
+
+1999-07-23  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-dock-item.c (gnome_dock_item_button_changed): Removed
+	unused variables.
+	(gnome_dock_item_motion): Likewise.
+	(gnome_dock_item_motion): Likewise.
+	(gnome_dock_item_delete_event): Likewise.
+
+	* gnome-dock-layout.c (gnome_dock_layout_class_init): Initialize
+	`parent_class'.
+
+	* gnome-dock.c (gnome_dock_size_request): Removed unused
+	variable.
+	(get_docked_item_by_name): Likewise.
+	(drag_begin_foreach_func): Removed useless declaration.
+
+	* gnome-dock.c: Fixed a two bugs reported by Ben Hendrickson
+	<bhendrickson usa net>.
+	(get_docked_item_by_name): Return the correct placement, and
+	iterate correctly.
+
+1999-07-22  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c (child_list_menu_create, child_list_menu_add_item):
+	append instead of prepending the item: this way the ordering is the
+	same as in notebook tabs.
+	(gnome_mdi_set_mode): when changing to modal mode preserve the
+	non-active views.
+
+1999-07-20  Federico Mena Quintero  <federico evilplan org>
+
+	* gnome-icon-list.c (icon_is_in_area): I'm a doofus.  Fix the
+	same-coordinates comparison.
+
+1999-07-18  Miguel de Icaza  <miguel gnu org>
+
+	* gnome-icon-list.c: Reverted all the changes that made gil->adj
+	and gil->hadj private.  There was existing code that depended on that.
+
+1999-07-19  Matt Wilson  <msw redhat com>
+
+	* gnome-icon-list.c (gnome_icon_list_icon_is_visible): check
+	the top bound (y1) as well as the bottom bound (y2)
+
+1999-07-19  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-popup-help.c: add some docs.
+
+1999-07-17  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-animator.c (gnome_animator_advance): Use `g_warning()'
+	instead of `g_error()' if the GnomeAnimatorLoopType is unknown.
+
+1999-07-16  Havoc Pennington  <hp pobox com>
+
+	* gnome_segv.c (main): Cleanup; use message box, have only one
+	button, improve message, don't segfault if called improperly.
+	(main): Now there's an URL explaining what the crash means.
+
+	* gnome-init.c (gnome_segv_handle): Always exit, don't check
+	gnome_segv return value; handle any signal, not just segv (though
+	for now the handler isn't installed for other signals, we probably
+	want sigbus and sigfpe eventually).
+
+1999-07-14  Havoc Pennington <hp pobox com>
+
+	* gnome-client.c: Docs, docs
+
+1999-07-13  Yukihiro Nakai   <nacai iname com>
+
+	* gtkrc.ja: fixed.
+
+1999-07-12  Raja R Harinath  <harinath cs umn edu>
+
+	* libgnomeui.h: Include rest of `gnome-druid-page*.h' headers.
+	* gnome-druid.h: Include "libgnome/gnome-druid-page.h" instead of
+	"gnome-druid-page.h".
+
+Mon Jul 12 06:20:39 1999  George Lebl  <jirka 5z com>
+
+	* gnome-dentry-edit.c: add inline docs
+
+1999-07-11  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-app-helper.c (gnome_app_find_menu_pos): translate parts of
+	the path on the fly to mend at least some of the localization issues.
+
+1999-07-10  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c (app_set_view): fixed a problem with
+	GNOME_MDI_ITEM_COUNT_KEY not being set to NULL when it should be.
+	removed some unused variables.
+
+1999-07-09  Miguel de Icaza  <miguel gnu org>
+
+	* gnome-font-picker.c (gnome_font_picker_label_use_font_in_label):
+	Add fallback mechanism for the case where the font is not defined.
+
+Fri Jul 09 06:57:07 1999  George Lebl  <jirka 5z com>
+
+	* gnome-calculator.c: add inline docs
+
+	* gnome-entry.c: fixup inline docs
+
+	* gnome-icon-entry.c: fixup inline docs
+
+Wed Jul 07 07:42:23 1999  George Lebl  <jirka 5z com>
+
+	* gnome-calculator.c: correctly fix "leading zero/string of zeros"
+	  problems, fix double digit problem, and correct return types of
+	  signal handlers
+
+Tue Jul  6 18:36:35 1999  Tim Janik  <timj gtk org>
+
+	* gnome-canvas-image.c: added ::pixbuf argument for aa canvas that
+	takes over a newly allocated ArtPixBuf to display.
+
+1999-07-05 Akira Higuchi <a-higuti math sci hokudai ac jp>
+
+	* gnome-icon-text.h:
+	* gnome-icon-item.c (iti_paint_text):
+	* gnome-icon-item.c (iti_idx_from_x_y):
+	* gnome-icon-text.c (free_row):
+	* gnome-icon-text.c (gnome_icon_layout_text):
+	* gnome-icon-text.c (gnome_icon_paint_text): Use wide characters
+	internally so that we handle character boundaries correctly for
+	multi-byte strings.
+
+	* gnome-icon-item.c (iti_idx_from_x_y): Avoid SIGSEGV when
+	icon text is empty.
+
+	* gnome-icon-item.c (gnome_icon_text_item_configure): Use
+	get_default_font() if fontname is NULL. This fixes the problem
+	that gmc consumes memory.
+
+Mon Jul  5 23:48:30 1999  Tim Janik  <timj gtk org>
+
+        * gnome-canvas-image.c (recalc_if_needed): only adjust image->pixmap
+        if we have an imlib image.
+
+        * gnome-canvas-image.c (gnome_canvas_image_update): if we don't have
+        image->im, try to feature pure ArtPixBuf instead (raph).
+
+Mon Jul  5 20:11:01 1999  Tim Janik  <timj gtk org>
+
+	* gnome-canvas.[hc]: added gnome_canvas_get_color_pixel() to retrive
+	the pixel value for a GdkColor.
+
+	* gnome-canvas-line.c:
+	* gnome-canvas-text.c:
+        * gnome-canvas-polygon.c:
+        * gnome-canvas-rect-ellipse.c: support ::fill_color, ::fill_color_rgba,
+	::fill_color_gdk, ::outline_color, ::outline_color_rgba and
+	::outline_color_gdk for non-aa as for aa canvas. don't segfault upon
+	NULL pointer passing, but assume no-fill and black in that case.
+	always request an update on the canvas items if a color changed.
+	keep the fill_color (sometimes fill_rgba) values uptodate, so
+	querying *_color_rgba returns valid results.
+
+1999-07-05  Miguel de Icaza  <miguel gnu org>
+
+	* gnome-about.c: Make the inter-line skip, it is not required
+	(descent+ascent has all the information we need).
+
+1999-07-04  Miguel de Icaza  <miguel gnu org>
+
+	* gnome-client.c: small fix for api docs.
+
+	* gnome-canvas.h: Fixed names.
+
+	* gnome-animator.h: Made the protypes use the same names.
+
+	* gnome-about.c: Fixed inline api docs.
+
+	* gnome-preferences.c: Fixed inline api docs.
+
+1999-06-30  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.h: The last argument to gnome_icon_list_new()
+	had effectively the same type as the one declared in the .c file,
+	but it was inconsistently declared.  Fixed it.
+
+1999-06-30  Cody Russell <bratsche dfw net>
+
+	* gnome-animator.c: Added last line to while() loop in
+	free_all_frames(). It was getting caught in an infinite loop in
+	some circumstances when the GnomeAnimator object was destroyed
+	before.
+
+1999-06-29  Akira Higuchi <a-higuti math sci hokudai ac jp>
+
+	* gnome-icon-item.c (iti_edition_accept): Don't allocate
+	iti->text if iti->editing is False. This fixes the bug #1311.
+
+	* gnome-less.c: (gnome_less_set_fixed_font): Correct the default
+	fontset pattern. A comma was missing.
+
+1999-06-29    <jrb redhat com>
+
+	* gnome-druid-page.c: Wrote more documentation.
+
+	* gnome-druid.c: Finished embedded documentation.
+
+1999-06-26  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-text.c: Finished all documentation comments.  The
+	icon text item is fully documented now.
+
+1999-06-25  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-item.c: Updated all documentation comments.  The icon
+	text item is fully documented now.
+
+	* gnome-icon-list.c: Updated the documentation comments.  The icon
+	list is fully documented now.
+
+1999-06-24    <jrb redhat com>
+
+	* gnome-druid*.[ch]:  Added gnome-druid to gnome-libs.
+
+1999-06-24  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-dock.c (gnome_dock_size_allocate): set minimum child
+	allocation width or height to 1 instead of 0. prevents some Gdk
+	segfaults.
+
+1999-06-24  Pablo Saratxaga <srtxg chanae alphanet ch>
+
+	* Added gtkrc.* files for all encodings I know of. Still missing is
+	to modify the Makefile.am so that at install time the gtkrc.iso88592,
+	gtkrc.iso88595 are hardlinked/copyied into the gtkrc.$LANG for
+	the various languages using them.
+
+1999-06-23  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.c (selection_many_icon_event): Sigh, we did need
+	selection_pending flags after all.  Added them to the private
+	structure as well.
+
+Wed Jun 23 14:48:29 1999  Raph Levien  <raph gimp org>
+
+	* Makefile.am: Reverted Pablo Saratxaga's changes. I'm not sure
+	what the right thing to do is, but hardlinking gtkrc files doesn't
+	seem to be it. In any case, it breaks my build, so I'm reverting.
+
+1999-06-23  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.[ch]: Moved all the private fields of the
+	GnomeIconList structure to a private structure in
+	gnome-icon-list.c.  Changed all the functions to use this instead.
+
+	* gnome-icon-list.c (gil_button_press): Sanitized for correct
+	behavior.  Unselect all icons if no modifier key is pressed.
+	(Icon): Now the Icon structure keeps a bit that indicates whether
+	it is selected, and another bit for temporary storage of the
+	selection.  The preserve_selection list in the icon list structure
+	is gone.  Wheee!
+	(update_drag_selection): Make use of the selected and tmp_selected
+	fields in the Icon structure.
+	(gil_icon_to_index): g_assert_not_reached() instead of returning
+	zero.
+
+	* gnome-icon-item.c (gnome_icon_text_item_configure): Added some
+	more sanity checks.  Make the iti->width be the specified width.
+	(ItiPrivate): Moved the private fields of the GnomeIconTextItem
+	structure to this new structure.  Replaced the old fields with
+	padding to preserve binary compatibility.
+	(iti_init): Create the private structure here.
+	(iti_update): Changed all the functions to *properly* queue
+	updates and then changed iti_update() to update the stuff that is
+	needed and then queue a redraw properly.  This is the way canvas
+	items should work.
+	Improved documentation comments.
+
+	* gnome-icon-item.h: Remove unnecessary #includes.  Improved
+	comments a bit.
+
+	* gnome-canvas.c (gnome_canvas_new_aa): Added a loud warning about
+	not using the AA canvas until it is debugged.
+	(gnome_canvas_item_update): Unset the GNOME_CANVAS_ITEM_NEED_*
+	flags here.
+	(gnome_canvas_group_update): Call the group's parent class update
+	method.
+
+	* gnome-canvas.h: Improved comments a bit.
+
+1999-06-23  Pablo Saratxaga <srtxg chanae alphanet ch>
+	* added gtkrc.* files for all languages/encodings I know
+
+1999-06-21  Raph Levien  <raph acm org>
+
+	* gnome-canvas-util.c (gnome_canvas_render_svp): Duuh, I had RGB
+	reversed (as BGR) in the compositing code.
+
+1999-06-20  Michael Zucchi  <mzucchi zedzone mmc com au>
+
+	* Makefile.am (INCLUDES): Added AUDIOFILE/ESD_CFLAGS to includes,
+	so that they can be installed in a different prefix.
+
+1999-06-17  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-text.c: Reverted Elliot's unportable changes.
+	Please do not perform Soptimizations(tm) on the canvas code.
+	* gnome-canvas-rect-ellipse.c: Likewise.
+	* gnome-canvas-line.c: Likewise.
+	* gnome-canvas-image.c: Likewise.
+	* gnome-canvas-util.c: Likewise.
+	* gnome-canvas-widget.c: Likewise.
+
+1999-06-21  Raph Levien  <raph acm org>
+
+	* gnome-canvas-util.c (gnome_canvas_render_svp): Duuh, I had RGB
+	reversed (as BGR) in the compositing code.
+
+1999-06-20  Michael Zucchi  <mzucchi zedzone mmc com au>
+
+	* Makefile.am (INCLUDES): Added AUDIOFILE/ESD_CFLAGS to includes,
+	so that they can be installed in a different prefix.
+
+1999-06-17  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-text.c: Reverted Elliot's unportable changes.
+	Please do not perform Soptimizations(tm) on the canvas code.
+	* gnome-canvas-rect-ellipse.c: Likewise.
+	* gnome-canvas-line.c: Likewise.
+	* gnome-canvas-image.c: Likewise.
+	* gnome-canvas-util.c: Likewise.
+	* gnome-canvas-widget.c: Likewise.
+
+	* gnome-icon-list.[ch]: Moved all the private fields of the
+	GnomeIconList structure to a private structure in
+	gnome-icon-list.c.  Changed all the functions to use this instead.
+
+1999-06-01  Robert Brady  <rwb197 ecs soton ac uk>
+
+	* gnome-calc.c: Stoped it from being possible to enter arbritrarily
+	strings of zeroes.
+
+1999-06-17  Elliot Lee  <sopwith redhat com>
+
+	* gnome-canvas*.c: Use hypot(x, y) instead of sqrt(x*x + y*y)
+
+1999-06-15  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c (copy_ui_info_tree, free_ui_info_tree): fixed a bug
+	that prevented stock subtrees from being copied or freed.
+
+1999-06-14  Elliot Lee  <sopwith redhat com>
+
+	* gnome-dialog.c: Fix for bug #1453:
+The following patch fixes a problem with gnome-dialog.
+If the no buttons are requested the buttonbox doesn´t get initalized
+when using language bindings as the buttonbox is only initalized
+explicitly in the C part. Moving the code around a bit fixes this.
+	Report & patch from <jan ifm uni-hamburg de>.
+
+	Tested with test-gnome.
+
+1999-06-13  Robert Brady  <rwb197 ecs soton ac uk>
+
+	* gnome-calculator.c (c_fact): fix factorial bug (for real this
+ 	time).
+
+Sun Jun 13 01:54:58 1999  Raph Levien  <raph gimp org>
+
+	* gnome-canvas-polygon.c (gnome_canvas_polygon_[sg]et_arg): added
+	ARG_OUTLINE_COLOR_RGBA, which was missing.
+
+1999-06-12  Jeff Garzik  <jgarzik pobox com>
+
+	* gnome-about.c:
+	Filled out inline API docs, a little bit 'o doc reformatting.
+
+	* gnome-preferences.c:
+	Added API doc stubs, documented maybe 1/3 of them.
+	Normalized several function declarations.
+
+1999-06-10  Raja R Harinath  <harinath cs umn edu>
+
+	* gnome-popup-menu.c:
+	Include <gtk/gtk.h> instead of individual subheaders.
+
+1999-06-10  Tuomas J. Lukka <lukka iki fi>
+
+	* gnome-popup-menu.c: remove reference to gtkfeatures.h
+
+1999-06-10  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-properties.h: Fix includes.
+	* gnome-procbar.h: Likewise.
+	* gnome-procbar.c: Likewise.
+	* gnome-property-entries.h: Likewise.
+	* gnome-spell.c: Likewise.  Fix i18n includes as well.
+
+	* gnome-properties.c: Fix includes and i18n includes.
+	(gnome_property_object_register): Use gettext() here, not _().
+
+	* gnome-property-entries.c: Fix includes and i18n includes.
+	(_property_entry_font_select_cb): Use gettext() here, not _().
+	(gnome_property_entry_colors): Likewise.
+
+	* gnome-canvas-util.c (gnome_canvas_join_gdk_to_art): Barf if
+	passed an invalid value.
+	(gnome_canvas_cap_gdk_to_art): Likewise.
+
+Wed Jun  9 19:20:41 1999  Raph Levien  <raph gimp org>
+
+	* gnome-canvas-polygon.c (gnome_canvas_polygon_update): Joins
+	and caps are round in aa case, as they have always been for
+	xlib.
+
+	* gnome-canvas-util.h:
+	* gnome-canvas-util.c: Added gnome_canvas_join_gdk_to_art and
+	gnome_canvas_cap_gdk_to_art convenience functions.
+
+	* gnome-canvas-line.c (gnome_canvas_line_update): Now passes
+	line join and cap options through to libart.
+
+1999-06-08  Ettore Perazzoli  <ettore comm2000 it>
+
+	Applied patch from Damon Chaplin to handle resizing of floating
+	dock items properly.
+	* gnome-dock.c (gnome_dock_size_request): Request size for all the
+	floating children too.
+	(gnome_dock_size_allocate): Allocate size for all the floating
+	children too.
+
+Wed Jun  2 22:14:02 1999  Raph Levien  <raph gimp org>
+
+	* gnome-canvas-util.c (gnome_canvas_render_svp): Correct alpha
+	compositing of partially transparent svp's over solid backgrounds.
+
+1999-06-02  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-app.c (gnome_app_set_menus): Apply suggestion from Damon
+	for controlling the border width.
+
+	* gtk-clock.c (gtk_clock_stop): Remove timeout here.  Thanks to
+	Damon for pointing this out.
+
+1999-06-01  Akira Higuchi <a-higuti math sci hokudai ac jp>
+
+	* libgnomeui/gnome-canvas-text.c:
+	* libgnomeui/gnome-icon-item.c:
+	* libgnomeui/gnome-less.c: Replace some gdk_font_load() calls with
+	gdk_fontset_load.    Use a more open fontset rule to load the fonts.
+
+1999-05-31  Nat Friedman  <nat gnome-support com>
+
+	* gnome-popup-menu.c: Include gtk/gtkcompat.h.
+
+1999-05-29  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-list.c (gnome_icon_list_new_flags): Fixed the format
+	of the file, to get proper documentation.
+
+1999-05-24  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-init.c (gnome_add_gtk_arg_callback): Replace #ifdef
+	GTK_CHECK... with #if.
+	* gnome-popup-menu.c (gnome_popup_menu_get_accel_group): ditto.
+
+	Thanks to Morten Welinder for pointing this out.
+
+1999-05-27  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-util.c (gnome_canvas_get_miter_points): Fixed M_PI
+	-> -M_PI typo.  Thanks to Roger Fearick (fearick physci uct ac za)
+	for reporting this.
+
+1999-05-27  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-list.c (gnome_icon_list_remove): Optimization: only
+	reset last_clicked if it was the icon we just removed.
+
+Thu May 27 00:02:39 1999  George Lebl  <jirka 5z com>
+
+	* gnome-icon-sel.c: slighly ugly semi-fix for a memory leak there
+	  is something else that is also leaking, this only does part of the
+	  job, and it should really be handeled elsewhere me thinks
+
+1999-05-26  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-list.c (gnome_icon_list_clear): Reset last_clicked
+	and last_selected here.
+	(gnome_icon_list_remove): Keep last_clicked and last_selected
+	within the range of icons.
+
+1999-05-26  Tim Janik <timj couch wilmington net>
+
+	* gnome-app-helper.c (setup_uline_accel): only setup a global
+	ALT bound accelerator if we are dealing with menu bar items.
+
+1999-05-25  James Henstridge  <james daa com au>
+
+	* gnome-canvas-line.c (gnome_canvas_line_point): when a new set of
+	points is assigned to the line, the arrow head polygons are
+	deleted, and an update is requested (implemented through an idle
+	function).  If GnomeCanvasItem::point is emitted before the update
+	handler executes, a seg fault will occur if the line has arrows.
+	This patch fixes this by calling reconfigure_arrows() if the arrow
+	coordinate arrays are NULL when they shouldn't be.
+
+1999-05-24  David KAELBLING <drk sgi com>
+
+	* gtkcauldron.c (gtk_dialog_cauldron_parse): Assing to parent, do
+	not compare
+
+1999-05-24  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (gnome_canvas_item_shutdown): Free the
+	transformation matrix if it exists.  Thanks to Morten Welinder for
+	reporting this.
+
+1999-05-18  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-image.c (gnome_canvas_image_set_arg): Queue an
+	update when the image's anchor point changes.  I don't think Raph
+	ever tested this.
+
+1999-05-16  Robert Brady <rwb197 ecs soton ac uk>
+
+	* gnome-calculator.c (c_fact): The second fixes the calculator
+	widget so it can do factorials of almost-integer numbers (thereby
+	letting people do 2, square root, square, factorial). This
+	resolves bug #1267.
+
+	* gnome-spell.c: Avoid infinite loop.
+
+1999-05-07  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-dock-band.c (gnome_dock_band_draw): Made static.
+
+Mon May 03 01:02:11 1999  George Lebl  <jirka 5z com>
+
+	* gnome-propertybox.c: add two more g_return_if_fail's to at least
+	  warn of no current page on the notebook (this can happen somehow)
+
+1999-04-25  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (gnome_canvas_expose): Build a microtile array
+	from the expose area directly, instead of going through
+	gnome_canvas_request_redraw().  This ensures that we'll repaint
+	off-screen areas if requested.
+
+1999-04-22  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (add_idle): New function to centralize adding of
+	the idle handlers.
+	(remove_idle): New function to centralize the removal of idle
+	handlers.
+	(gnome_canvas_update_now): Use remove_idle().  Do not call
+	gdk_flush().
+	(gnome_canvas_request_update): Use add_idle().
+	(gnome_canvas_request_redraw_uta): Use add_idle().
+	(idle_handler): Reset the canvas->idle_id to zero.
+
+1999-04-26  Raja R Harinath  <harinath cs umn edu>
+
+	* gnome-mdi-generic-child.h (GNOME_IS_MDI_MDI_CHILD): Remove.  Is
+	now in gnome-compat.h.
+
+1999-04-26  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-about.c (gnome_destroy_about): Release gai as well.
+
+1999-04-23  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* libgnomeui.h: include gnome-compat.h
+
+	* gnome-compat.h: New file for compatibility source code
+	functions.
+
+Sat Apr 24 14:04:26 1999  George Lebl  <jirka 5z com>
+
+	* gnome-dentry-edit.c: when syncing a dentry to the display,
+	  null fields which have been freed if they are emptied
+
+1999-04-23  Ettore Perazzoli  <ettore comm2000 it>
+
+	* animator_demo.c (main): Removed Tux animation.
+
+	* gnome-animator.c: Removed some unused variables.
+	(draw_background_pixmap): Don't draw anything if `widget->window'
+	is NULL.
+	(gnome_animator_new_with_size): Set the requisition directly
+	instead of using `gtk_widget_set_usize()'.
+
+	* gnome-dock.c (gnome_dock_add_floating_item): Removed a couple of
+	useless casts.
+	(gnome_dock_add_floating_item): Do not remove the item from its
+	parent.
+
+	* gnome-dock-item.c (gnome_dock_item_map): If we are floating,
+	call `gnome_dock_item_detach()' properly to do the floating setup.
+	(gnome_dock_item_size_allocate): Applied patch from Damon Chaplin
+	<damon karuna freeserve co uk> to fix handling of the child's
+	requisition.
+
+1999-04-21  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-dock-item.c (gnome_dock_item_destroy): Release di->name on
+	the destroy handler.  Memory leak spotted by Morten Welinder again.
+
+1999-04-20  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gtk-clock.c (gtk_clock_new): Bug fix from Damon Chaplin,
+	clock->type was never initialized.
+
+1999-04-21  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi-generic-child.h: fixed a typo. GNOME_IS_MDI_GENERIC_CHILD()
+	seems better than GNOME_IS_MDI_MDI_CHILD().
+	* gnome-mdi-generic-child.c, gnome-mdi.c, gnome-mdi-session.*:
+	some documentation fixes.
+
+1999-04-18  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-item.c (gnome_icon_text_item_stop_editing): Make sure
+	iti_stop_editing is never called if we are not editing.  Fixes gmc
+	bug #1065
+
+1999-04-08  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-init.c (gnome_add_gtk_arg_callback): Use the macro correctly.
+
+	* gnome-popup-menu.c (gnome_popup_menu_get_accel_group): Only use
+	GTK 1.2.1 features if we have GTK 1.2.1
+
+	* gnome-app-helper.c (create_help_entries): g_free temporary
+	variable.
+
+Mon Apr 05 00:58:12 1999  George Lebl  <jirka 5z com>
+
+	* gnome-icon-sel.c: avoid segfault if the browse dialog is closed
+	  before a directory is fully read, also catch destructions while
+	  in the show loop. and I removed the "update on every 5th" thing
+	  and it updates the progressbar on every image (the saving was
+	  insignificant as far as I meassured it)
+
+	* gnome-icon-entry.c: stop the showing of icons when one of the
+	  buttons to avoid segs
+
+Fri Apr  2 21:03:56 1999  ape spacetec no  (Asbjorn Pettersen)
+
+	* gnome-less.c (gnome_less_show_command):
+	* gnome-app-helper.c (create_help_entries): Open file in TEXT mode.
+	This is for the OS/2 version.
+
+1999-03-31  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-color-picker.c (gnome_color_picker_init): Use the Imlib
+	visual for the drawing area.
+
+1999-03-29  Owen Taylor  <otaylor redhat com>
+
+	[ Fix applied until Raster gets back and we find a better
+	  solution - Miguel ]
+
+	* gnome-pixmap.c (finish_load): Temporary fix.
+
+	The problems people have been having with *Bad Window*
+	errors and pixmap themes seem to be occurring because
+	of mistakes in the way that gnome-pixmap is handling
+	Imlib images. (Well, actually, they are occurring because
+	of mistakes in the design of imlib...)
+
+	To be specific, gnome-pixmap widget calls
+	gdk_imlib_move_pixmap() and gdk_imlib_move_mask(), then
+	gdk_imlib_destroy_image().
+
+	If no caching is enabled, then this works pretty
+	much as expected - the pixmaps and masks are dissociated
+	from the image and the imlib data structures are cleaned
+	up.
+
+	If caching is enabled, then bad things happen. move_pixmap()
+	and move_mask() leave the pixmaps in the cache; the
+	destroy_image() drops the refcount of the pixmaps to
+	zero, and when the cache gets full, the pixmaps are
+	destroyed.
+
+	The following patch fixes things up, but is a rather
+	inefficient, since it puts every pixmap in GNOME through
+	a extra copy. I'm not really sure how to do this
+	better - I'll ask Raster about it when he gets back
+	from Germany.
+
+1999-03-28  Felix Bellaby <felix pooh u-net com>
+
+	* gnome-client.c (save_yourself_callback): timeout wait for pointer
+	grab to be released (before gsm issues a warning!).
+
+1999-03-25  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (emit_event): Ref/unref the item while its event
+	signal is being emitted.  Do not propagate further if the item is
+	destroyed.
+
+	* gnome-canvas.c (emit_event): Remember the item's parent before
+	emitting the event signal, because the item may be destroyed
+	during emission.  This fixes an Important Bug(tm).
+
+1999-03-24  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-popup-menu.c (gnome_popup_menu_new): Unref the accel group
+	instead of attaching it.
+	(gnome_popup_menu_new_with_accelgroup): Check that the accelgroup
+	is not NULL.  Also, set the accelgroup once we create the menu.
+	(gnome_popup_menu_get_accel_group): Fetch the accelgroup
+	correctly.
+	This whole patch is courtesy of Tim Janik (timj gimp org).
+
+Tue Mar 23 19:33:52 1999  George Lebl  <jirka 5z com>
+
+	* gnome-font-selector.c: stuff that got allocated with g_malloc needs
+	  to be g_free'd and vice versa
+
+1999-03-24  Felix Bellaby <felix pooh u-net com>
+
+	* gnome-client.c (gnome_client_request_save): confirm before logout.
+	(gnome_client_save_dialog_show): show window before setting hints.
+	Tidy up runtime warnings in various functions.
+
+1999-03-22  Pavel Machek  <pavel ucw cz>
+
+	* gnome-winhints.c (gnome_win_hints_init): g_return_if_fails()
+	added to make core more robust
+
+Sun Mar 21 01:01:48 1999  George Lebl  <jirka 5z com>
+
+	* gnome-{icon,pixmap,number}-entry.c: added argument checks everywhere
+	  and the destroy signal is void
+
+	* gnome-pixmap-entry.c: on destroy, null the last_preview, just in
+	  case
+
+	* gnome-icon-item.c: (gnome_icon_text_item_configure) if the text is
+	  static, cast it to (char *) to avoid warning, but this is somewhat
+	  evil, so should it or should it not be const in the first place
+
+	* gnome-pixmap.c: added some argument checks and in size_request,
+	  setting the requisition of the widget directly is wrong I guess,
+	  plus it's redundant
+
+	* gtkdial.c: comment warning fix
+
+	* winhints_demo.c: changed () to (void) to avoid warnings
+
+1999-03-18  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* Makefile.am (libgnomeui_la_LDFLAGS): Updated library version number.
+
+Wed Mar 17 00:25:53 1999  Tim Janik  <timj gtk org>
+
+	* gnome-app-helper.[hc]: added gnome_accelerators_sync() to flush
+	the accelerator config file.
+
+	* gnome-app-helper.c: added compatibility code so apps will at least run
+	with Gtk+1.2.0.
+
+	* gnome-init.c (gnome_add_gtk_arg_callback): don't call
+	gtk_item_factory_parse_rc() if we don't have gtk+1.2.1, issue
+	a warning in this case (as per quartic's request).
+
+Tue Mar 16 13:56:08 1999  Tim Janik  <timj gtk org>
+
+	* gnome-app-helper.c (create_menu_item): install a gtk_main_quit()
+	hook, that will save the accelerator paths upon exit of the
+	toplevel gtk_main() loop.
+
+	* gnome-init.c (gnome_add_gtk_arg_callback): parse item factory
+	accelerator paths from ~/.gnome/accels/<app-id> after gtk is
+	initialized.
+
+	* gnome-app-helper.c (create_help_entries): lock accelerators
+	right away since we don't feature them at all for help item.
+
+	* gnome-app.c (gnome_app_destroy): unref the accel_group.
+
+	* gnome-app-helper.c:
+	(gnome_app_fill_menu*): install accelerators sanely, set the
+	accel_group on newly created menus.
+	(create_menu_item): add the item to its shell and show it.
+	(create_radio_menu_items):
+	(gnome_app_fill_menu_custom): rely on create_menu_item() to add the
+	item to the shell.
+	(create_help_entries): setup the underline accelerator directly if desired.
+	(gnome_app_fill_menu_custom): feature uline_accels on submenus.
+	(create_menu_item): lock acclerators if we don't have a accel_group.
+	(gnome_app_create_menus_custom): add the menu bar to the app before creating
+	the sub menus.
+
+1999-03-15  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (gnome_canvas_item_get_bounds): Applied patch
+	from Richard Hult <rhult hem2 passagen se>; I had goofed up with
+	min/max coordinate computation.
+
+	* gnome-dialog-util.c (request_dialog): Set the entry to be the
+	focused widget.
+
+1999-03-15  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.c (gil_destroy): In addition to removing the
+	timer, reset the timer_tag variable.
+
+Mon Mar 15 04:48:10 1999  George Lebl  <jirka 5z com>
+
+	* gnome-icon-list.c: remove timeout when widget is destroyed,
+	  the posibility is remote, but still possible
+
+	* gnome-pixmap-entry.c: when entry is destroyed dequeue the entry
+	  to be updated in timeout to avert possible crash
+
+1999-03-14  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-app-helper.c: Removed ellipsis from the "New Window" and
+	"Close Window" entries, and made their names more descriptive.
+
+1999-03-13  Richard Hult <rhult hem2 passagen se>
+
+	* gnome-icon-list.c (icon_event): Ignore button clicks above 3 in
+	the button release and button press event handlers.
+
+1999-03-12  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-item.c (iti_paint_text): Nice offset adjustments.
+
+1999-03-09  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (gnome_canvas_item_get_bounds): Un-transform the
+	bounding box so that it is returned in the coordinate system of
+	the item's parent.
+
+1999-03-09  Owen Taylor  <otaylor redhat com>
+
+	* gnome-messagebox.c (gnome_message_box_new): Adjust the
+	padding around message boxes for a more attractive
+	appearance.
+
+1999-03-09  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-dock-item.c (draw_textured_frame): Actually make use of
+	the clip parameter.  No more flicker on repeated exposures of the
+	handle.
+
+	* gnome-dock-item.c (gnome_dock_item_paint): Eliminate flicker
+	by only painting the handle if the expose area intersects it.
+
+1999-03-09  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-item.c (iti_event): Only start selecting with mouse
+	button-1.  This should fix bug #482
+	(iti_event): Add check here too (Patch from Richard Hult).
+
+Mon Mar 08 21:55:09 1999  George Lebl  <jirka 5z com>
+
+	* gnome-icon-sel.c: don't use g_is_image_filename, but use
+	  gnome_mime_type
+
+Mon Mar 08 21:43:19 1999  George Lebl  <jirka 5z com>
+
+	* gnome-icon-list.c: in SINGLE mode, don't unselect on
+	  GDK_[23]BUTTON_PRESS, to allow the app to get double/tripple
+	  clicks in SINGLE mode
+
+	* gnome-icon-entry.c: fixed a leak in setting the icon, and added
+	  dragging, so that we may drag the icon from the preview button
+
+	* gnome-pixmap-entry.c: added way to drag the image from the
+	  preview frame
+
+	* gnome-icon-sel.c: (gnome_icon_selection_show_icons) just quit
+	  if file_list is NULL, we might just have come to an empty
+	  directory
+
+1999-03-07  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-color-picker.c (render): added a check if cp is realized,
+	since otherwise da->style->bg_gc[*]==NULL caused a segfault in
+	background capplet. it seems to work allright now.
+
+1999-03-06  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-util.c: Added documentation for the functions that
+	were missing it.
+
+1999-03-04  Raja R Harinath  <harinath cs umn edu>
+
+	* gnome-canvas-util.h (gnome_canvas_points_unref):
+	Fix typo -- rename from `gnome_canvas_point_unref'.
+
+1999-02-28  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-property-entries.c (_property_entry_font_entry_cb):
+	Send the changed signal to `cb_data->object->user_data' not
+	to `cb_data->object'.
+
+1999-02-27  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-canvas-util.c (gnome_canvas_points_free): Add ref/unref
+
+1999-02-26  Sergey Panov <sipan mit edu>
+
+        * gnome-canvas-text.c(gnome_canvas_text_set_arg): removed
+        g_assert that was left there by mistake.
+
+Fri Feb 26 15:39:58 1999  George Lebl  <jirka 5z com>
+
+	* gnome-icon-entry.c: fix problem with chooser dialog when the
+	  directory stopped existing, it will go into the default directory
+	  now
+
+1999-02-27  Changwoo Ryu  <cwryu adam kaist ac kr>
+
+	* gtkrc.ja, gtkrc.ko: Removed default style, as gtk+ already has
+	the default gtkrc's.
+
+1999-02-26  Sergey Panov <sipan mit edu>
+
+        * gnome-app-helper.c, gnome-app-helper.h: make "_New"
+        subtree menu item translatable
+
+	* gnome-canvas-text.c(gnome_canvas_text_set_arg): more
+	protection against font==NULL when "fontset" is used.
+
+1999-02-25  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-app-helper.c (gnome_app_fill_menu_custom): added a quick
+	assertion to catch an error I was having.
+
+1999-02-26  Changwoo Ryu  <cwryu adam kaist ac kr>
+
+	* gtkrc.ko: Fixed a typo.
+
+1999-02-24  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-entry.c (gnome_icon_entry_get_filename): This had
+	some precedence problem.
+
+1999-02-24  Owen Taylor  <otaylor redhat com>
+
+	* gnome-animator.c gnome-app-util.c gnome-canvas.c
+	  gnome-icon-list.c gnome-pixmap-entry.c gnome-procbar.[ch]
+	  gtk-clock.c gtkdial.c:
+
+	Added in calls to GDK_THREADS_ENTER/LEAVE around timeouts and
+	idles so that libgnomeui can be called from a threaded
+	GTK+ application. (Should have no effect on non-threaded
+	applications)
+
+Wed Feb 24 15:23:28 1999  George Lebl  <jirka 5z com>
+
+	* gnome-icon-entry.c: get rid of last remaints of gtk pixmap code
+
+1999-02-23  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-scores.c (gnome_scores_set_logo_pixmap): Kill gtk-pixmap
+	and use gnome-pixmap here as well.
+
+	* gnome-icon-entry.c (entry_changed): Use gnome-pixmap instead of
+	gtk-pixmap here
+	(setup_preview): Kill gtk-pixmap here too.
+
+	* gnome-messagebox.c (gnome_message_box_new): Justify labels to
+	the left.
+
+	* gnome-init.c (gnome_add_gtk_arg_callback): Add a hack to allow
+	using --gtk-debug-objects (this is required as we create GTK
+	objects before gtk_init is called).
+	(gnome_init_with_popt_table): Do this before parsing argument.s
+
+Tue Feb 23 00:31:53 1999  George Lebl  <jirka 5z com>
+
+	* gnome-pixmap.c: fix for the new requisition stuff so that
+	  set_usize works properly, use gdk_imlib_move_{image,mask} instead
+	  of the copy variety to save some time, and add some documentation
+	  to the functions that were missing it.
+
+	* gnome-pixmap-entry.[ch]: actually guarantee that disk isn't touched
+	  more then once a second when typing, fix a memory leak and cache
+	  the last image that was previewed, so that we don't load the same
+	  image over and over
+
+Sun Feb 21 19:06:51 1999  Maciej Stachowiak  <mstachow alum mit edu>
+
+	* gnome-winhints.c (gnome_win_hints_get_workspace): This code was
+ 	on crack, it was getting the _WIN_HINTS property instead of
+ 	_WIN_WORKSPACE.
+
+1999-02-21  Nuno Ferreira  <nmrf rnl ist utl pt>
+
+	* Makefile.am (gnome_segv_LDADD): Use libgnomeui.la without the
+	path from the topdir so that AM_MAKEFLAGS=-j4 works.
+	(ted_demo_LDADD, stock_demo_LDADD, winhints_demo_LDADD,
+	animator_demo_LDADD, dock_demo_LDADD): Likewise.
+
+Sun Feb 21 04:36:54 1999  George Lebl  <jirka 5z com>
+
+	* gnome-winhints.c: don't use CARD32's for format 32 hints, Xlib sends
+	  them as longs and those can be 64bit on alpha
+
+1999-02-20  Stuart Parmenter <pavlov pavlov net>
+
+	* gnome-calculator.c: Accept keypad input.
+
+1999-02-18  Sergey Panov <sipan mit edu>
+
+        * Makefile.am: Makefile will now be installing gtkrc.ru
+
+1999-02-17  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-color-picker.c (gnome_color_picker_init): Changed the shadow.
+	(render): now draws a stipple when insensitive
+	(render): let's remove the commment... S-:
+	(render): use the right visual
+
+1999-02-17  Sergey Panov  <sipan mit edu>
+
+        * gnome-canvas-text.c (gnome_canvas_text_set_arg): fontset
+        can be used now to configure font of the canvas text.
+        * gnome-canvas-text.h: Updated list of object arguments
+
+1999-02-16  Ulrich Drepper  <drepper cygnus com>
+
+	* libgnomeui/gnome-about.c (gnome_about_display_comments): Use
+	strtok_r instead of strtok.
+	* libgnomeui/gnome-dateedit.c (gnome_date_edit_get_date): Likewise.
+	* libgnomeui/gnome-spell.c (gnome_spell_fill_info): Likewise.
+
+1999-02-17  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-dock-item.c (gnome_dock_item_button_changed): Do not add a
+ 	GTK+ grab.
+	(gnome_dock_item_button_changed): Do not remove the GTK+ grab.
+	(gnome_dock_item_remove): Likewise.
+	(gnome_dock_item_map_event): Removed.
+
+	* gnome-dock-item.c (gnome_dock_item_size_request): Avoid calling
+ 	gtk_widget_size_request with `requisition' == `widget->requisition'.
+	* gnome-dock.c (size_request_v): Likewise.
+	(size_request_h): Likewise.
+	(gnome_dock_size_request): Likewise.
+
+1999-02-15  Elliot Lee  <sopwith redhat com>
+
+	* gnome-init.c: Don't give sound events for widgets
+	that are not visible. Don't give sound events for
+	objects with the "gnome_disable_sound_events" property
+	set.
+
+Sun Feb 14 22:12:48 1999  George Lebl  <jirka 5z com>
+
+	* gnome-icon-entry.c: don't let the file entry expand verticaly when the
+	  window gets resized
+
+1999-02-14  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-dentry-edit.c (fill_easy_page): The terminal toggle should
+	be anchored to the left.  It is very disconcerting to have it move
+	around when the user resizes the window.
+
+1999-02-14 Sergey Panov <sipan mit edu>
+
+	* gnome-dentry-edit.c(label_new)The proper label alignment is not
+	to the left, but to the right, where entries are.
+
+1999-02-14 Sergey Panov <sipan mit edu>
+
+	* gnome-dentry-edit.c(fill_easy_page,make_page) Get terminal
+	toggle widget to align correctly -- it was not centered, but
+	glued to the icon widget. Achived what, I think, Federico
+	tried to do but by other means.
+
+Fri Feb 12 20:59:53 PST 1999 Jay Painter <jpaint serv net>
+
+	* gnome-app.c applied patch from Ettore Perazzoli to fix
+	segmentation faults when a gnome-app is shown/hidden multiple
+	times.
+
+1999-02-12  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-dentry-edit.c (make_page): Use uniform padding for the
+	table.
+	(table_attach_entry): Use better options to pack stuff in the
+	table.
+	(table_attach_label): Likewise.
+	(label_new): Convenience function to create a label with the
+	proper alignment.
+	(fill_easy_page): Align the labels correctly.  Also, use better
+	packing options for the icon and terminal toggle widgets.
+	(fill_advanced_page): Use label_new().
+
+1999-02-12  Jeff Garzik  <jgarzik pobox com>
+
+	* gnome-app-helper.c:
+	Document a few API functions.
+
+	* gnome-dns.c:
+	API doc cleanups.
+	(gnome_dns_lookup): Documented return val now matches code.
+
+1999-02-11 Sergey Panov <sipan mit edu>
+
+	* gnome-app-helper.c (install_menuitem_hint_to_statusbar,
+	install_menuitem_hint_to_appbar,create_toolbar_item,
+	create_menu_item,gnome_app_helper_gettext): much cleaner solution
+	of the hints and labels translation problem. Not a problem any
+	more
+
+	* gnome-app-helper.h: redefined D_ macro and defined new macro L_
+	D_ is using dgettext only, while L_ uses gnome_app_helper_gettext
+	function which tries to use gettext and, if fails, uses dgettext
+
+1999-02-11  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-popup-menu.c (gnome_popup_menu_do_popup): Do not
+	g_return_if_fail (event != NULL), since we *can* take null
+	events.  Thanks to Timo Sirainen <aaaaaa sicom fi> for reporting
+	this.
+
+1999-02-11 Sergey Panov <sipan mit edu>
+
+	* gnome-app-helper.c (install_menuitem_hint_to_statusbar,
+	install_menuitem_hint_to_appbar): hints were not translated
+        at all. Now we look for them first using gettext then, if failed,
+        with dgettext.
+        (create_menu_item): simplified Miguels fix for lalels. Now there
+        is no special cases, but will use the same procedure as for hints.
+
+1999-02-11 The Rasterman <raster redhat com>
+
+	* gnome-winhints.h: added WIN_HINTS_DO_NOT_COVER to hints enum
+
+1999-02-11  Arturo Espinosa <arturo nuclecu unam mx>
+
+	* gnome-stock.c:
+		(gnome_stock_pixmap): case for TYPE_FILE was missing.
+		(create_pixmap_from_file): new function for missing case.
+
+
+1999-02-11  Felix Bellaby <felix pooh u-net com>
+
+	* gnome-client.c: replace "Priority" with "_GSM_Priority" throughout.
+
+1999-02-10  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-paper-selector.c (paper_size_system): Use GnomePaper and
+	GnomeUnit names instead of Paper an Unit.
+
+1999-02-10  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.c: Indentation fixes.
+
+1999-02-11  James Henstridge  <james daa com au>
+
+	* gnome-icon-list.c(gnome_icon_list_set_hadjustment): When a
+	horizontal adjustment is given for the GnomeIconList, set the values
+	in the adjustment so that page_size = lower-upper, since the icon
+	list doesn't scroll horizontally.
+	(gil_destroy): unref the horizontal adjustment if we have one.
+
+1999-02-10  Felix Bellaby <felix pooh u-net com>
+
+	* gnome-client.c (client_set_restart_command, client_set_clone_command,
+	client_save_yourself_callback): fix implementation of the config
+	prefix so that it is based on the global config prefix as documented.
+
+1999-02-10  James Henstridge  <james daa com au>
+
+	* gnome-icon-list.c: added an implementation for the
+	gtk_widget_set_scroll_adjustments interface.  Rather than creating a
+	new signal, I have overriden GtkLayout's set_scroll_adjustment signal.
+	This keeps binary compatibility and allows you to pack a GnomeIconList
+	into a GtkScrolledWindow and get the correct behaviour again.
+
+	* gnome-app-util.c: The gnome_app_progress_* functions would sometimes
+	cause a segfault.  There was code to make sure that stale progress
+	keys would get destroyed when the associated GnomeApp got destroyed.
+	If you cleaned up the key with gnome_app_progress_done, then a segfault
+	would occur when the GnomeApp got destroyed.  Now the cleanup
+	signal handler's id is saved and the handler is removed when the key
+	is destroyed.
+
+Tue Feb 09 18:51:08 1999  George Lebl  <jirka 5z com>
+
+	* gnome-pixmap-entry.c: fix this up, don't look up pixmaps more then
+	  once a second if the entry is changing, plus scale the preview in
+	  the file browser properly
+
+1999-02-09  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.c (gil_button_press): Do nothing if the button
+	is different from 1.
+
+1999-02-09  Chris Lahey  <clahey umich edu>
+
+	* gnome-paper-selector.h, gnome-paper-selector.c: Added
+	gnome_paper_selector_set functions.  These are neccessary and thus
+	constitute a bug fix.
+
+1999-02-08  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-dock.c (drag_snap): New function: contains the code from
+ 	`drag_motion()'.  This does not change anything in the behavior,
+ 	but makes it more simple to implement outline movement later.
+
+	* gnome-dock-item.c (gnome_dock_item_delete_event): Do nothing for
+	now.
+
+1999-02-07  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-app.c (gnome_app_realize): Removed.
+	(gnome_app_show): Same as the removed `gnome_app_realize', but
+ 	invoke the parent class' `show' method (instead of the `realize'
+ 	method) before returning.
+	(gnome_app_class_init): Install `gnome_app_show' as the `show'
+ 	method.
+
+1999-02-07  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-dock.c (drag_new): Avoid re-grabbing the pointer, as
+ 	suggested by Jaka.
+	(drag_new): No longer subtract the drag offsets from the current
+ 	coordinates.
+	(drag_to): Likewise.
+	(drag_floating): Likewise.
+
+	* gnome-dock-item.c (gnome_dock_item_grab_pointer): Do not return
+ 	until the grab is successful.
+	(gnome_dock_item_init): Do not initialize `grab_on_map_event'
+ 	anymore.
+	(gnome_dock_item_button_changed): Likewise.
+	(gnome_dock_item_map_event): Do not attempt a grab anymore.
+	(gnome_dock_item_motion): Subtract the drag offset from the new
+ 	coordinates before emitting them.
+
+	* gnome-dock-item.h (struct _GnomeDockItem): Member
+	`grab_on_map_event' removed.
+
+1999-02-07  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-pixmap-entry.c (gnome_pixmap_entry_get_filename): Test for
+	a GnomePixmap, not a GtkPixmap.  This code sucks, btw.
+	(entry_changed): Likewise, and it also sucks, btw.
+
+1999-02-05  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-dock-item.c (gnome_dock_item_motion): Retrieve the pointer
+ 	position in a sane way.
+
+	* gnome-dock.c: Reverted Jaka's changes of 1999-02-04.
+	(drag_motion): If everything fails, move the item on its own band
+ 	according to the current pointer position instead of just doing
+ 	nothing.
+	(drag_check): Removed `NEW_BAND_SNAP' hack.  Use the
+ 	`drag_allocation' instead of the `allocation' of the band for
+ 	doing the comparisons.  Check against the band only if
+ 	`new_for_drag' is false.  If we are in the upper/leftmost half and
+ 	dragging into the band fails, try to create a new band.
+	(drag_new): Set `new_for_drag' in the new band to TRUE.
+
+	* gnome-dock-band.c (gnome_dock_band_drag_begin): Copy the current
+ 	allocation into `drag_allocation'.
+	(gnome_dock_band_init): Initialize `max_space_requisition',
+ 	`tot_offsets' and `new_for_drag'.  Set `drag_allocation' to { -1,
+ 	-1, 0, 0 }.
+	(gnome_dock_band_drag_end): Set `new_for_drag' to FALSE.
+
+	* gnome-dock-band.h (struct _GnomeDockBand): New members
+ 	`drag_allocation' and `new_for_drag'.
+
+1999-02-05  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-messagebox.c (gnome_message_box_new): Use
+	gnome-default-dlg.png, not gnome-default.png (there was a file
+	clash with gnome-core).
+
+1999-02-05  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-app.c (gnome_app_set_statusbar_custom): New function taking
+	both a container and a statusbar widget.
+
+Thu Feb 04 22:56:28 1999  George Lebl  <jirka 5z com>
+
+	* gnome-dentry-edit.c: use set_icon method of icon entry as setting
+	  the text of the entry now doesn't work (this was probably an
+	  unwanted side effect of it's recent makeover)
+
+	* gnome-icon-entry.c: accept NULL for the set_icon method
+
+Thu Feb 04 22:45:45 1999  George Lebl  <jirka 5z com>
+
+	* gnome-icon-entry.c: switch order of two functions to avoid
+	  warning
+
+Thu Feb 04 19:10:38 1999  George Lebl  <jirka 5z com>
+
+	* gnome-file-entry.c: follow documented behaviour and only
+	  use modal file dialog if it has been requested with the
+	  set_modal method
+
+1999-02-04  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-dateedit.c (gnome_date_edit_new_flags):
+	(gnome_date_edit_set_flags): Changed int to GnomeDateEditFlags,
+	per James Henstridge's request.
+
+1999-02-05  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-dock.c (drag_check): fixed (hopefully) the docking
+	policy.
+
+1999-02-04  Jeff Garzik  <jgarzik pobox com>
+
+	* gnome-font-picker.[ch]:
+	- Added API docs.
+	- (gnome_font_picker_set_title): Made const-correct.
+	- Cast properly with GNOME_FONT_PICKER macro.
+	- Protect public functions with g_return_if_fail calls.
+	- Reformatted source a bit.
+	- Mark some internal function implementations static, as their
+	  prototypes were already marked this way.
+	- Add button mode enum value GNOME_FONT_PICKER_MODE_UNKNOWN for
+	  cases when no other mode is applicable.  (used only in error
+	  return values)
+
+1999-02-04  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-dateedit.c (create_children): Set the proper flags for the
+	Gtk calendar.
+	(gnome_date_edit_new_flags): New function to create a date edit
+	widget with flags.
+	(gnome_date_edit_new): Use gnome_date_edit_new_flags().
+	(gnome_date_edit_forall): Handle the internal widgets properly.
+	(gnome_date_edit_set_flags): New function to change the flags in
+	the date edit widget.
+
+	* gnome-dateedit.h (GnomeDateEditFlags): New enumeration with
+	configuration options for the date edit widget.
+
+1999-02-04  Jeff Garzik  <jgarzik pobox com>
+
+	* gnome-color-picker.[ch]:
+	- Added API docs.
+	- Corrected a few casts.
+	- Use Glib types where appropriate.
+
+	* gnome-entry.[ch]:
+	Added API documentation.
+	Added 'max_saved' setting and gnome_entry_set_max_saved() func.
+	Folded gnome_entry_{prepend,append}_history() guts into a single
+	static func.
+	Made const-correct.
+	Replaced 'int' with 'gboolean' where appropriate.
+	Converted other types to Glib types.
+
+1999-02-03  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-icon-entry.c (gnome_icon_entry_set_icon): another little
+	bug fix.
+
+	* gnome-icon-entry.c (entry_changed): oops.  Dumb oneliner,
+	cut'n'paste error.
+
+1999-02-02  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-icon-entry.c: Massive changes.  It now works (fingers
+	crossed.)  Only current issue is that selecting garbage silently
+	reverts.  This should be an easy fix, but it is an easy fix
+	tomorrow, as I need some food.
+
+	* gnome-entry.c (gnome_entry_new): gtk_combo_disable_active of all
+	gnome-entries.  Return should "activate" like a normal entry,
+	dammit.
+
+	* gnome-file-entry.c (browse_dialog_ok): we emit the "activate"
+	signal of the file entry.  This lets us know for sure when a file
+	is entered.  Unless I'm missing something, there's no really good
+	API for finding when someone has changed a file name.
+
+1999-02-02  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.c (gnome_icon_list_clear): Free the selection
+	list.  I wonder how anything ever worked without this.  After 1.0
+	I promise to rewrite the icon list in a sane way that does not
+	imitate GtkCList.
+
+1999-02-01  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-messagebox.c (gnome_message_box_new): Use
+	gnome_unconditional_pixmap_file instead of gnome_pixmap_file.
+
+1999-02-01  Tomas Ogren  <stric ing umu se>
+
+	* gnome-app-helper.c: Added a missing comma in menu_names struct
+
+1999-02-01  Felix Bellaby <felix pooh u-net com>
+
+	* gnome-client.c (client_set_clone_command, client_parse_function,
+	 gnome_client_set_clone_command, gnome_real_client_connect): fix
+	failure to propogate changes in the restart command over to the
+	clone command (when no clone command has been set).
+	(master_client_disconnect): avoid NULL client_grab_widget values.
+
+1999-01-31  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (gnome_canvas_destroy): Call
+	shutdown_transients() to remove the idle handler, since it may be
+	present if an item requested an update and the canvas is destroyed
+	before it is even realized.
+
+1999-01-30  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-app-helper.c (create_menu_item): Crude special case for
+	this.
+
+1999-01-28  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-app-helper.c, gnome-app-helper.h: New approach.  We now
+	have a new constant: GNOME_APP_UI_SUBTREE_STOCK which means that
+	the text string we provide is included in the gnome-libs catalog
+
+1999-01-27  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-pixmap-entry.c (entry_changed): Use GNOME pixmap here to
+	avoid problems in multidepth visuals.
+	(setup_preview): Here too.
+
+1999-01-27  Jeff Garzik  <jgarzik pobox com>
+
+	* gnome-popup-help.c:
+	Correct g_malloc call to avoid using sizeof with an array idx.
+
+1999-01-27  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-dock-band.c (gnome_dock_band_unmap): new function.
+	now a dock band can be properly hidden.
+	* gnome-dock.c (gnome_dock_unmap): new function.
+	(unmap_widget, unmap_band_list, unmap_widget_foreach): new
+	helper functions.
+	now a dock can be properly hidden.
+
+1999-01-27  Jeff Garzik  <jgarzik pobox com>
+
+	* gnome-app-helper.c, gnome-init.c, gnome-spell.c:
+	Use autoconf incantation to include alloca.h properly.
+
+	* gnome-less.c:
+	Replace static const with a #define, Sun CC breaks if an array
+	is sized with a variable (yes, even a const one... grrr).
+
+1999-01-27  Felix Bellaby <felix pooh u-net com>
+
+	* gnome-client.c (save_yourself_callback) wait for any pointer grab
+	to be released before grabbing gtk input.
+	(gnome_client_save_dialog_show): set win_hints to LAYER_OVER_DOCK.
+	(gnome_client_setpriority): #ifdef out SMLIB dependent code (patch
+	by Frederic Devernay <devernay istar fr>).
+	* gnome-init.c (gnome_init_with_popt_table) initialize win_hints code.
+	* gnome-winhints.h: acknowledge change to gnome-init.c in comment.
+
+1999-01-27  Andrew T. Veliath  <andrewtv usa net>
+
+	* gnome-app-helper.[ch]: Add gnome_app_fill_{menu,toolbar}_with_data
+	functions to match gnome_app_create...with_data versions.
+
+1999-01-27  Raja R Harinath  <harinath cs umn edu>
+
+	* Makefile.am (INCLUDES): Use G_LOG_DOMAIN of "GnomeUI".
+	Suggested by Tim Janik <timj gtk org>.
+
+1999-01-26  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-icon-entry.c (gnome_icon_entry_set_icon): added new
+	function to get around the old braindead way of setting the icon.
+
+	* gnome-dialog.c (gnome_dialog_set_parent): Commented the below
+	change.
+
+	* gnome-file-entry.c (browse_clicked): This now will set it's file
+	dialog to be modal.  In addition, it does the equivilent of the
+	gnome_dialog_parent_set.  HOWEVER, gnome_dialog_parent_set only
+	acts upon gnome_dialogs, so I had to copy the code ):
+
+	* gnome-icon-entry.c (gnome_icon_entry_init): Now it looks
+	better.  If anyone wanted to make it even cooler, it might be good
+	to have it inherit from gtk_button, instead of hbox.
+	(show_icon_selection): Also, before I forget, make it
+	modal/set_parent if the parent is modal etc.
+
+
+1999-01-26  Radek Doulik  <rodo aquarius>
+
+	* gnome-app-helper.h: added some casts to (GdkModifierType) to
+	avoid compiler warnings
+
+1999-01-25  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-preferences.c (gnome_preferences_load_custom): Fix.  Put
+	the Cache information in the right configuration section.
+
+1999-01-25  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-init.c (gnome_init_cb): use the setting for "images".
+
+Mon Jan 25 11:08:46 1999  George Lebl  <jirka 5z com>
+
+	* gnome-dialog.[ch]: remove the default migration patch as it's
+	  now in cvs and it was a hack anyhow, I don't break binary
+	  compatibility now since I changed the flag in the structure to
+	  "gpointer padding"
+
+1999-01-25  Havoc Pennington  <hp pobox com>
+
+	* gnome-propertybox.h, gnome-propertybox.c: Rename
+	gnome_property_box_set_state() to
+	gnome_property_box_set_modified();
+	leave old name for compatibility.
+
+1999-01-25  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-popup-menu.c (popup_connect_func): Do not test for the
+	callback being NULL here, since it may not work for modal popup menus.
+	(popup_marshal_func): Test for the callback being NULL here.
+	Misc. indentation fixes.  Please keep indentation consistent if
+	you modify a file!
+
+1999-01-25  Nat Friedman  <nat nat org>
+
+	* gnome-dentry-edit.c (gnome_dentry_get_name_entry): New function
+ 	to provide access to the Name GtkEntry widget.
+	(gnome_dentry_get_comment_entry): Likewise.
+	(gnome_dentry_get_exec_entry): Likewise.
+	(gnome_dentry_get_tryexec_entry): Likewise.
+	(gnome_dentry_get_doc_entry): Likewise.
+	(gnome_dentry_get_icon_entry): Likewise.
+	* gnome-dentry-edit.h: Prototypes for the above.
+
+1999-01-24  Tomas Ogren  <stric ing umu se>
+
+	* gnome-dock-band.c (gnome_dock_band_get_orientation):
+	fixed initialization of band_child->real_offset to 0 to get rid
+	of an UMR...
+
+1999-01-23  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-init.c (gnome_init_cb): If gdk_imlib_set_cache_info has
+	been called before, then we do not reset it to the value set in
+	disable_imlib_cache.
+
+1999-01-23  The Rasterman <raster redhat com>
+
+	* gnome-init.c: disable setting of cache - this is the most evil
+	thing I've ever seen. There is an imlib perefercnes (imlib_config)
+	program to dojust this for every setting of imlib - and overriding
+	it like this is not just bad coding but bad policy since now a
+	users preferences dont count anymore.
+
+1999-01-23  Felix Bellaby <felix pooh u-net com>
+
+	* gnome-client.c, gnome-client.h (gnome_client_set_priority):
+	API to set runlevel for gnome-session manager.
+
+1999-01-21  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-list.c (gnome_icon_list_new_flags): New function.
+	Adds support for the text not being allocated on every icon
+	insertion.
+
+	* gnome-icon-item.c (font_load): WEEE!  Major cpu resource hog
+	found.  I was loading the same font over and over assuming Gdk had
+	some sort of internal hash.  Well, it does not.
+
+	Load it once only.
+
+	(gnome_icon_text_item_configure): Support for static text.  This
+	means that the text does not need to be strdup()ed.
+
+Thu Jan 21 14:31:46 1999  George Lebl  <jirka 5z com>
+
+	* gnome-entry.c: fixed segfaults with gnome-entry, when an
+	  actual history item was used
+
+1999-01-21  Sebastian Wilhelmi  <wilhelmi ira uka de>
+
+	* Makefile.am (INCLUDES): s%$(datadir)/locale%$(gnomelocaledir)%
+
+	* gnome-client.c (gnome_client_object_init): use g_get_user_name
+	instead of doing it the hard way.
+
+1999-01-18  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-canvas-line.c (gnome_canvas_line_draw): Remove warning
+	just inserted by Elliot, as the leak does not exist.
+
+1999-01-20  Carsten Schaar  <nhadcasc fs-maphy uni-hannover de>
+
+	* gnome-client.c: Added translation domain to table of options.
+
+	* gnome-init.c: Likewise
+
+1999-01-20  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-item.c (iti_edition_accept): Layout the text after we
+	stopped editing.
+
+	* gnome-icon-list.c (gil_get_icons_in_region): Return an empty
+	list if the rectangle is empty.  Also, return the list in sorted
+	order.
+	(gil_mark_region): Make it a little less inefficient by not
+	searching through the icons-in-region list, but traversing it only
+	once instead.  This whole function could be made to run in linear
+	time if it used a selection mechanism like that in
+	mc/gnome/gdesktop.c (it is still doing a g_list_find() for each
+	element in the preserve_selection list).  Selection needs fixing,
+	anyway, because it is inconsistent with the way icons are selected
+	in the desktop (which is done the right way).
+	(gnome_icon_list_get_icon_at): Call the ::point() method of the
+	items directly so that we can get an ideal "point-inside" test.
+
+	* gnome-canvas.c (gnome_canvas_get_item_at): New public function
+	to fetch the item at the specified coordinates.
+
+1999-01-19  Nat Friedman  <nat nat org>
+
+	* gnome-popup-menu.c (gnome_popup_new_with_accelgroup):
+ 	gnome_popup_menu_new has been renamed to
+ 	gnome_popup_menu_new_with_accelgroup, and now allows the user to
+ 	specify the accelgroup for the popup menu.  It no longer clears
+ 	the accelerators for the menus, and now operates on the provided
+ 	uiinfo array instead of making a copy.  This is consistent with
+ 	the behavior of the other gnome menu functions.
+
+	(gnome_popup_menu_new): This now creates a new accelgroup and
+ 	calls into gnome_popup_menu_new_with_accelgroup.  The accelgroup
+ 	is attached to the returned menu widget.
+
+	(gnome_popup_menu_get_accel_group): A new function to get the
+	accelgroup created in gnome_popup_menu_new.
+
+	All of the API documentation has been moved into this file from
+ 	gnome-popup-menu.h and has been modified to conform to the API
+ 	commenting style.
+
+1999-01-19  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.c (gil_realize): Set the icon list's background
+	to style->base[GTK_STATE_NORMAL] to be consistent with Gtk lists.
+	We actually change the style instead of just the window background
+	because that is what the canvas wants.  Yes, I need to add
+	background color support to the canvas.
+
+1999-01-19  Felix Bellaby <felix pooh u-net com>
+
+	* gnome-client.c (save_yourself_callback): Handle SM spec 7.2
+	messages specially to cover bug in xsm and speed start up.
+	Release active grabs to avoid deadlocks on widget grab.
+	(master_client_[dis]connect): use new functions in gdk.
+	(gnome_client_init): initialise ice using gnome-ice.c code.
+	(gnome_client_connect): pass client as ICE context so gnome-ice.c
+	can handle io error disconnections.
+	(gnome_process_ice_messages): replaced by code in gnome-ice.c.
+	(gnome_client_request_interaction_internal): append keys so that
+	the interact requests are handled in FIFO order.
+
+	* gnome-client.h (GnomeClientState): state for SM spec 7.2 SaveYourself
+
+	* gnome-ice.c (process_ice_messages): close the ice connection
+	and disconnect the GnomeClient following an io error.
+	(new_ice_connection): use watch_data to reference the gdk_input_id.
+	(gnome_ice_io_error_handler): replaces the default ICE handler
+	so we can close the connection instead of doing an exit(1).
+	(gnome_ice_init): install the new io error handler.
+
+
+1999-01-19  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (shutdown_transients): Remove the idle handler
+	also if the canvas->need_update flag is turned on.  But leave the
+	need_update flag as it is, for if the canvas is mapped again.
+
+1999-01-19  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-app-helper.h (GNOMEUIINFO_RADIOITEM): hmm,
+	has this _EVER_ worked?  does anyone use it?  There seems to be a
+	typo with it.
+
+1999-01-18  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-item.c (iti_start_selecting): Use an I-beam cursor
+	while selecting.
+
+	* gnome-icon-item.h (GnomeIconTextItemClass): Added
+	"selection_started" and "selection_stopped" signals.  These are
+	required when the user of the icon text item handles grabs on its
+	own.
+
+	* gnome-icon-item.c (iti_start_selecting): Emit the
+	selection_started signal.
+	(iti_stop_selecting): Emit the selection_stopped signal.
+
+1999-01-17  Nat Friedman  <nat nat org>
+
+	* gnome-preferences.c (STATUSBAR_METER_ON_RIGHT): New property
+ 	string macro.
+	(gnome_preferences_load_custom): Load the statusbar_meter_on_right
+ 	property.
+	(gnome_preferences_save_custom): Save the statusbar_meter_on_right
+ 	property.
+	(gnome_preferences_get_statusbar_meter_on_right): New function.
+	(gnome_preferences_set_statusbar_meter_on_right): Likewise.
+
+	* gnome-preferences.h: Added the statusbar_meter_on_right field to
+ 	GnomePreferences.  Added prototypes for
+ 	gnome_preferences_get_statusbar_meter_on_right and
+ 	gnome_preferences_set_statusbar_meter_on_right.
+
+	* gnome-appbar.c (gnome_appbar_construct): Use the
+ 	gnome_preferences_get_statusbar_meter_on_right() function to
+ 	determine the position of the progress meter.
+
+1999-01-17  Jeff Garzik  <jgarzik pobox com>
+
+        * gnome-app-helper.c:
+        s/gtk_check_menu_item_set_state/gtk_check_menu_item_set_active/
+
+        * gnome-canvas-line.c:
+        Kill uninit-var warnings.  NOTE: FIXME in this area (not mine)
+
+        * gnome-icon-sel.c, gtkcauldron.c:
+        s/strdup/g_strdup/ to remove cast and silence ANSI warning.
+
+        * gnome-property-entries.c:
+        s/gtk_container_border_width/gtk_container_set_border_width/
+
+        * gtk-ted.c:
+        Handle default case in switch.
+
+        * gtkcauldron.c, gtkcauldron.h:
+        Made a few functions const-correct.
+        Fixed a few bugs in existing code where g_malloc()'d data was
+        freed with free().
+
+1999-01-17  Seth Alves  <alves hungry com>
+
+	* gnome-stock.h (GNOME_STOCK_MENU_FONT): moved colorselector add
+	text_numbered_list text_indent text_bulleted_list table_fill
+	table_borders remove clear text_unindent stock pixmaps
+	from gnome-icons into libgnomeui
+
+1999-01-17  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-entry.c (gnome_entry_save_history): Fixed this routine to
+	not overwrite memory it does not own.
+	(gnome_entry_destroy): Append manually the item, as otherwise we
+	will invoke the handlers that do not know we are being destroyed
+
+	* gnome-file-entry.c (browse_clicked): If there is a grab
+	currently, we need to take the grab.
+
+Sat Jan 16 21:47:03 1999  George Lebl  <jirka 5z com>
+
+	* gnome-calculator.c: on C/CE just clear the current display
+	  not the stack, this is not 100% correct but close
+
+1999-01-15  Chris Lahey  <clahey umich edu>
+
+	* gnome-popup-menu.c (gnome_popup_menu_new): Altered this so that
+	it would clear out the menu accelerators and ac_mods (in a copy
+	of the GnomeUIInfos.)
+
+	* gnome-app-helper.h, gnome-app-helper.c
+	(gnome_app_ui_configure_configurable): Made this a public
+	interface so that gnome-popup-menu.c could use it.
+
+	* gnome-about.c (gnome_about_display_comments): Killed a blatant
+	memory leak.
+
+1999-01-15  Szekeres István <szekeres cyberspace mht bme hu>
+	* gtk-clock.c: the widget is now destroyed correctly.
+
+1999-01-15  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c (gnome_mdi_remove_child): set parent to NULL just
+	before unreferencing.
+
+1999-01-14  Felix Bellaby <felix pooh u-net com>
+
+	* gnome-client.c (client_set_ghash): do not set null properties.
+
+1999-01-13  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.h (GnomeIconList): Added a total_height field
+	that holds the maximum of the height of all the icon rows and the
+	window height.
+
+	* gnome-icon-list.c (scroll_timeout): Do not allow auto-scrolling
+	to go past the end of the icon list.
+	(gnome_icon_list_set_vadjustment): Connect to the "changed" signal
+	of the adjustment as well, to notice when the whole adjustment
+	changes (this happens on gil_scrollbar_adjust()).
+	(gil_scrollbar_adjust): Compute the gil->total_height.
+	(gil_mark_region): Do not paint the selection rectangle past the
+	gil->total_height.  This makes the icon list not look amateurish
+	anymore.
+
+	* gnome-canvas-image.c (gnome_canvas_image_update): Check whether
+	image->im is NULL and do not crash if it is.  Thanks to Erik
+	Andersen <andersen xmission com> for pointing this out.
+
+1999-01-13  Felix Bellaby <felix pooh u-net com>
+
+	* gnome-client.c (master_client_clean_up): disconnect the master
+	client at exit of app to prevent io errors on session manager side.
+
+1999-01-12  Manish Vachharajani <mvachhar vger rutgers edu>
+
+	* gnome-ice.c (new_ice_connection): Set FD_CLOEXEC on
+	ice connection descriptors
+
+1999-01-12  Chris Lahey  <clahey umich edu>
+
+	* gnome-app-helper.h, gnome-app-helper.c
+	(gnome_app_ui_configure_configurable): Added configurable
+	keybindings for menu items.  Items are configured by adding to
+	~/.gnome/Gnome in the [Menus] section.  The menu items available
+	for keybinding configuration are listed in gnome_app_helper.c
+	(menu_names).  The defaults are listed in gnome_app_helper.c
+	(menu_defaults).
+
+	Configuration consists of two (key, value) pairs for each menu
+	item.  The first is Menu-*-accelerator-key which is assigned a
+	value equal to the ASCII value of the key you want to bind to.
+	The second is Menu-*-ac-mods which is assigned the GdkModifierType
+	(in decimal) of the set of modifiers you want your keybinding to
+	take.  For this, Shift=1, Control=2, and Alt=4, and you can add.
+	See gtk+/gdk/gdktypes.h (GdkModifierType) for more info on
+	ac-mods.
+
+	* gnome.defs: This seems to be checked in for some reason, even
+	though it's autogenned.  I suppose I'll commit the changes to it.
+
+1999-01-12  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-init.c (initialize_gtk_signal_relay): Fix as posted by
+	Peter Housel (housel home com) to the mailing list (missing
+	terminating NULL).
+
+1999-01-11  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-rect-ellipse.c (gnome_canvas_re_set_arg):
+	Initialize the colorp variable when setting the colors.
+
+	* gnome-canvas-line.c (gnome_canvas_line_set_arg): Likewise.
+
+	* gnome-canvas-text.c (gnome_canvas_text_set_arg): Likewise.
+
+1999-01-11  Changwoo Ryu  <cwryu adam kaist ac kr>
+
+	* Makefile.am (gtkrc_DATA): Added gtkrc.ja and gtkrc.ko.
+
+1998-10-11  James Henstridge  <james daa com au>
+
+	* gnome-canvas.c (pick_current_item): set subwindow to NULL before
+	emitting the GDK_{LEAVE,ENTER}_NOTIFY events.  In some cases the
+	value would point at garbage, which caused problems for my
+	python bindings.  It should have no effect on other programs.
+	This fix was sent to me by Chi-Deok Hwang <cdhwang sr hei co kr>
+
+Sun Jan 10 23:33:10 1999  Raph Levien  <raph gimp org>
+
+	* gnome-canvas-image.c (gnome_canvas_image_update): made it (more)
+	correctly support the case where the image width/height are not
+	equal to the imlib image width/height.
+
+1999-01-11  Changwoo Ryu  <cwryu adam kaist ac kr>
+
+	* gtkrc.ko: New file.  gtkrc for Korean users.
+
+	* gnome-init.c (gnome_rc_parse): Use gtk_rc_add_default_file()
+	instead of gtk_rc_parse().
+
+1999-01-10  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-properties.c (gnome_property_object_register):
+	Call gtk_object_ref () on the newly created label so it won't
+	get destroyed together with the GnomePropertyBox.
+
+1999-01-10  Nat Friedman  <nat nat org>
+
+	* gnome-uidefs.h (GNOME_KEY_NAME_REDO_MOVE): New macro.
+	(GNOME_KEY_MOD_REDO_MOVE): Likewise.
+	(GNOME_KEY_NAME_UNDO_MOVE): Likewise.
+	(GNOME_KEY_MOD_UNDO_MOVE): Likewise.
+	(GNOME_KEY_NAME_PAUSE_GAME): Likewise.
+	(GNOME_KEY_MOD_PAUSE_GAME): Likewise.
+	(GNOME_KEY_NAME_NEW_GAME): Likewise.
+	(GNOME_KEY_MOD_NEW_GAME): Likewise.
+
+	* gnome-app-helper.h (GNOMEUIINFO_SUBTREE_HINT): New macro.
+	(GNOMEUIINFO_MENU_PAUSE_GAME_ITEM): Likewise
+	(GNOMEUIINFO_MENU_NEW_GAME_ITEM): Likewise
+	(GNOMEUIINFO_MENU_END_GAME_ITEM): Likewise
+	(GNOMEUIINFO_MENU_GAME_TREE): Likewise.
+
+1999-01-09  Nat Friedman  <nat nat org>
+
+	* gnome-app-helper.h
+	(GNOMEUIINFO_MENU_RESTART_GAME_ITEM): New macro
+	(GNOMEUIINFO_MENU_RESTART_UNDO_MOVE_ITEM): Likewise
+	(GNOMEUIINFO_MENU_RESTART_HINT_ITEM): Likewise
+	(GNOMEUIINFO_MENU_RESTART_SCORES_ITEM): Likewise
+
+1999-01-10  Dave Camp (campd oit edu)
+
+	* gnome-dateedit.c: Hides the calendar widget on signal
+         "day_selected_double_click" instead of "day_selected".
+
+
+Sat Jan 09 01:42:15 1999  George Lebl  <jirka 5z com>
+
+	* gnome-dialog.[ch]: do the Motif thing with default buttons
+	  so that we are more consistent. it tracks the default button
+	  if you use tab to switch focus on buttons
+
+1999-01-08  Nat Friedman  <nat nat org>
+
+	* gnome-app-helper.h (GNOMEUIINFO_MENU_PREFERENCES_ITEM): Added
+ 	accelerator.
+	(GNOMEUIINFO_MENU_PROPERTIES_ITEM): Likewise.
+
+1999-01-08  Nat Friedman  <nat nat org>
+
+	* gnome-app-helper.h (GNOMEUIINFO_MENU_SELECT_ALL_ITEM): New entry.
+
+	* gnome-uidefs.h (GNOME_KEY_NAME_SELECT_ALL): New entry.
+
+	* gnome-app-helper.h (GNOMEUIINFO_MENU_CLOSE_WINDOW_ITEM): New entry.
+	(GNOMEUIINFO_MENU_NEW_WINDOW_ITEM): Likewise.
+
+	* gnome-uidefs.h (GNOME_KEY_MOD_SAVE): Changed it back to C-s.
+	(GNOME_KEY_NAME_NEW_WINDOW): New entries.
+	(GNOME_KEY_NAME_CLOSE_WINDOW): Likewise.
+
+Fri Jan 08 17:10:49 1999  George Lebl  <jirka 5z com>
+
+	* gnome-init.c: removed all the autosync stuff
+
+	* gnome-entry.c: actually saving was done on destroy only so
+	  added a per file sync there (we don't want to sync everything,
+	  since the app should control when it's data get synced, to be
+	  able to roll back changes)
+
+1999-01-08  Havoc Pennington  <hp pobox com>
+
+	* gnome-dialog.c: Add documentation.
+
+Fri Jan  8 12:42:20 1999  Owen Taylor  <otaylor redhat com>
+
+	* gnome-stock.c (gnome_stock_paint): Don't create
+	  excess new masks. (Is this the last GNOME stock
+	  leak?)
+
+	* gnome-stock.c (lookup): Fix memory leak when lookup fails.
+
+Fri Jan 08 05:35:55 1999  George Lebl  <jirka 5z com>
+
+	* gnome-stock.c: fix a memory leak when destroying the widget,
+	  some of the states may not have been entered yet so some of the
+	  pixmaps might still be floating, so we just _destroy them
+	  when we destroy the widget, this is the normal behaviour for
+	  gtk containers anyway
+
+Fri Jan 08 02:35:24 1999  George Lebl  <jirka 5z com>
+
+	* gnome-dock-item.c: fixed gnome_dock_item_handle_size_request,
+	  it was setting the requisition to handle size instead of just
+	  adding the handle size ...
+
+1999-01-08  Nat Friedman  <nat nat org>
+
+	* gnome-appbar.c (gnome_appbar_construct): Moved the status bar to
+ 	the left side and the progress meter to the right side.
+
+	* gnome-uidefs.h: Include gdk/gdkkeysyms.h.
+
+1999-01-08  Nat Friedman  <nat nat org>
+
+	* gnome-app-helper.h (GNOMEUIINFO_MENU_FIND_AGAIN_ITEM): New menu
+ 	item.
+
+	* gnome-uidefs.h: Changed to a new set of hotkeys.
+
+1999-01-07  Nat Friedman  <nat nat org>
+
+	* gnome-app-helper.h Changed the Options menu to Settings.
+
+1999-01-07  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-entry.c (gnome_entry_save_history): changed a bit.  Now
+	it's a little tiny bit more efficient, and no longer will save
+	duplicate fields.
+	(check_for_duplicates): new function.
+
+1999-01-07  Chris Lahey  <clahey umich edu>
+
+	* gnome-paper-selector.h, gnome-paper-selector.c
+	(gnome_paper_selector_get_width, gnome_paper_selector_get_height):
+	Changed it so that these always returned values in units.  Also
+	added functions to return the margin values.
+
+1999-01-07  Nat Friedman  <nat nat org>
+
+	* gnome-uidefs.h: Replaced (GDK_CONTROL_MASK||GDK_SHIFT_MASK) with (GDK_CONTROL_MASK|GDK_SHIFT_MASK) throughout.
+
+Wed Jan 06 22:32:03 1999  George Lebl  <jirka 5z com>
+
+	* gnome-app-helper.h: fix properties/preferences stock icons
+
+1999-01-07  Nat Friedman  <nat nat org>
+
+	* gnome-app-helper.h Added GNOME_MENU_OPTIONS_STRING and _PATH.
+
+1999-01-07  Nat Friedman  <nat nat org>
+
+	* gnome-app-helper.h (GNOMEUIINFO_MENU_OPTIONS_TREE): New standard
+ 	menu.
+
+Wed Jan 06 21:36:16 1999  George Lebl  <jirka 5z com>
+
+	* gnome-uidefs.h,gnome-app-helper.h: added Find and Replace items
+	  and default keybindings for those
+
+1999-01-07  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-app.c (gnome_app_set_statusbar): okay -- lets try again.
+	The old spacing wasn't liked so it's now down to 0 pixels.
+
+Wed Jan 06 21:13:54 1999  George Lebl  <jirka 5z com>
+
+	* gnome-app-helper.h: Added strings for use in menu path
+	  for inserting,deleting,mdi,etc..., and added a standard
+	  "File_s" toplevel menu
+
+1999-01-07  Nat Friedman  <nat nat org>
+
+	* gnome-app-helper.h (GNOMEUIINFO_MENU_PRINT_ITEM): Corrected a
+ 	typo.
+	(GNOMEUIINFO_MENU_ABOUT_ITEM): Another typo.
+
+1999-01-06  Nat Friedman  <nat nat org>
+
+	* gnome-uidefs.h
+ 	(GNOME_KEY_NAME_PRINT), (GNOME_KEY_MOD_PRINT_SETUP): Added
+ 	standard hotkeys for printing.
+
+	* gnome-app-helper.h (GNOMEUIINFO_MENU_PRINT_ITEM),
+	(GNOMEUIINFO_MENU_PRINT_SETUP_ITEM): Use the new standard hotkeys.
+
+1999-01-06  Nat Friedman  <nat nat org>
+
+	* gnome-app-helper.h (GNOMEUIINFO_MENU_NEW_ITEM): Add another
+ 	parameter for the menu item description.
+	(GNOMEUIINFO_MENU_UNDO_ITEM): Removed an extra parameter.
+
+	Also changed "document" to "file" in all the menu item
+ 	descriptions.
+
+1999-01-06  Nat Friedman  <nat nat org>
+
+	* gnome-app-helper.h: Added the little tool-tips-like descriptions
+ 	of each standard menu item's function.  Cleaned the macros up a
+ 	bit and grouped them according to the menu in which they belong.
+
+Wed Jan 06 18:03:59 1999  George Lebl  <jirka 5z com>
+
+	* gnome-app-helper.c: cast data to (gpointer) on the new macros,
+	  and add a standard "_Print" and "Print S_etup..." items
+
+Wed Jan 06 17:45:06 1999  George Lebl  <jirka 5z com>
+
+	* gnome-app-helper.h: changed the NEW_ITEM macros, as by the
+	  syleguide they need to specify a type, so they need a custom
+	  label passed
+
+Wed Jan 06 17:25:26 1999  George Lebl  <jirka 5z com>
+
+	* gnome-stock.h: fix a typo in menu stock defines
+
+Wed Jan 06 16:40:29 1999  George Lebl  <jirka 5z com>
+
+	* gnome-app-helper.h: added some defines to make adding
+	  standard items easier
+
+1999-01-06  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-app.c (gnome_app_set_statusbar): Changed beveling.  Now
+	it's GTK_SHADOW_NONE.  I also changed the spacing to be 4 pixels.
+	It'd be good if all applicable apps used this spacing, as well as
+	the statusbar.  There are a lot of inconsistent apps out there...
+
+1999-01-06  Carsten Schaar  <nhadcasc fs-maphy uni-hannover de>
+
+	* gnome-client.c (gnome_client_get_flags): New function.  Returns
+ 	the client's flags.
+	(client_parse_func): Removed the setting of the master_client's
+ 	previous_id.
+	(gnome_client_connect): Sets the previous_id to the id, that was
+ 	tried to connect to the session manager.
+
+	* gnome-client.h (gnome_client_get_flags): New declaration.
+
+1999-01-05  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-dentry-edit.c (gnome_dentry_edit_new_notebook): Text change
+
+Tue Jan 05 02:12:52 1999  George Lebl  <jirka 5z com>
+
+	* gnome-pixmap-entry.c,gnome-icon-entry.c: accept drops of
+	  files on the image previews
+
+Mon Jan 04 02:19:49 1999  George Lebl  <jirka 5z com>
+
+	* gnome-icon-sel.c: when scaling icons, makes sure they're at least
+	  1 pixel tall, wide.
+
+Mon Jan 04 01:10:14 1999  George Lebl  <jirka 5z com>
+
+	* gnome-icon-list.c: when appending or inserting imlib image
+	  do a sanity check for NULL
+
+	* gnome-icon-sel.c: if we can't clone the image, just ignore it
+
+Sun Jan 03 17:57:52 1999  George Lebl  <jirka 5z com>
+
+	* gnome-file-entry.c: actually accept file drops of text/uri-list
+	  there is still a problem of multiple files being dropped, I
+	  just pick out the first one, is this the right solution?
+
+1999-01-03  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-dock.[ch]: removed all traces of struct _GnomeDockChild.
+	use GnomeDockBands directly instead, as drag_allocation is no
+	longer needed.
+
+Sat Jan  2 15:00:19 1999  Raph Levien  <raph gimp org>
+
+	* gnome-canvas-line.c: Minor tweaks and tunes. The set_arg
+	updates are more consistent, the width of the line is now
+	set based on the items'affine transformation rather than
+	the global pixels_per_unit.
+
+Fri Jan  1 13:13:04 1999  Raph Levien  <raph gimp org>
+
+	* gnome-canvas.c (gnome_canvas_group_get_arg): fixed a bug
+	spotted by Centove: getting GROUP_ARG_Y was getting the X
+	value.
+
+1999-01-02  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-dock-item.c (gnome_dock_item_motion): don't subtract
+	item->dragoff_? from pointer coordinates before emiting signal
+	as this confuses gnome-dock.c/drag_check().
+	* gnome-dock.c (drag_new, drag_to, drag_floating): subtract
+	item->dragoff_? from pointer coordinates here instead in the
+	above function.
+	(drag_check): a small fix to handling drags in new bands.
+	use band's current allocation and NOT its drag_allocation.
+	this seems fine and properly handles new bands.
+	#if 0'ed out all references to GnomeDockChild members
+	new_for_drag and drag_allocation.
+
+1999-01-02  Jeff Garzik  <jgarzik pobox com>
+
+	* gnome-app-helper.c:
+	Corrected g_strncmp_ignore_char doc comments, and made it
+	static to this module.
+
+1999-01-02  Chris Lahey  <clahey umich edu>
+
+	* gnome-app-helper.c (gnome_app_find_menu_pos): Added
+	g_strncmp_ignore_char and used it to ignore '_' in menu paths.
+	This also required adding a variable stripped_path_length, the
+	length of the given path without the '_'s.
+
+1999-01-02  Jeff Garzik  <jgarzik pobox com>
+
+	* gnome-calculator.c, gnome-canvas-util.c,
+	  gnome_segv.c, gtkdial.c:
+	Include _xxx_SOURCE define for 'gcc -ansi -pedantic'.
+
+1999-01-01  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi-session.c (gnome_mdi_save_state): fixed a bug
+	with different key names used when saving and restoring.
+
+Thu Dec 31 23:39:37 1998  Raph Levien  <raph gimp org>
+
+	This is a big giant commit for the antialiased canvas.
+
+	* gnome-canvas-image.c:
+	* gnome-canvas-image.h:
+	* gnome-canvas-line.c:
+	* gnome-canvas-line.h:
+	* gnome-canvas-polygon.c:
+	* gnome-canvas-polygon.h:
+	* gnome-canvas-rect-ellipse.c:
+	* gnome-canvas-rect-ellipse.h:
+	* gnome-canvas-text.c:
+	* gnome-canvas-text.h:
+	* gnome-canvas-util.c:
+	* gnome-canvas-util.h:
+	* gnome-canvas.c:
+	* gnome-canvas.h: Added antialiased rendering and per-item
+	affine transformations.
+
+Thu Dec 31 18:50:44 1998  George Lebl  <jirka 5z com>
+
+	* gnome-calculator.c,gnome_icon_list.c: fix two memory leaks
+	  related to g_list_remove_link
+
+Thu Dec 31 17:58:26 1998  George Lebl  <jirka 5z com>
+
+	* dock_demo.c: just a warning fix
+
+	* gnome-ice.c: add a prototype for new_ice_connection to avoid
+	  a warning mess
+
+	* gnome-icon-text.c: avoid ambigous else by using {,}'s
+
+	* gnome-pixmap.c: avoid const warning
+
+Thu Dec 31 17:37:31 1998  George Lebl  <jirka 5z com>
+
+	* gnome-about.c: actually connect the destroy handler
+
+1998-12-29  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-app-helper.c (do_ui_signal_connect): moved setting
+	object data to create_menu_item(), so that data is set even
+	with custom connect functions.
+
+1998-12-21  Jay Painter <jpaint serv net>
+	* gnome-ice.c: added an internal hash to map ICE connections
+	to GnomeIceInternal structures which keep state information
+	on ICE connections so their gdk_add_input callbacks can be
+	added/removed correctly.
+
+1998-12-18  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-procbar.c (gnome_proc_bar_draw): Calculate total field
+	here and make it work with vertical procbars.
+	(gnome_proc_bar_set_values): Always redraw the procbar not just
+	if the values have changed.
+
+	* gnome-procbar.c (gnome_proc_bar_draw): New static function.
+	(gnome_proc_bar_set_values): Save values in pb->last even if
+	the widget is not realized. Moved actual drawing code into
+	gnome_proc_bar_draw ().
+	(gnome_proc_bar_start): Call the callback here, not only add
+	a timeout for it.
+	(gnome_proc_bar_configure): Call gnome_proc_bar_draw () if the
+	widget is already realized. This fixes the bug that the procbar
+	was displaying garbage until the timeout was run the first time.
+
+1998-12-17  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-app-helper.c (gnome_app_find_menu_pos): consider the
+	position after the tear off item to be the topmost one.
+
+1998-12-17  Andrew T. Veliath  <andrewtv usa net>
+
+	* gnome-app-helper.c (gnome_app_fill_menu_custom): Prepend a
+	tearoff if preferences tell us to.
+	(gnome_app_find_menu_pos): When checking if menu item is a
+	separator, ignore tear off menu items.
+
+	* gnome-preferences.[ch]: Add preference for menus_have_tearoff.
+
+1998-12-17  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-app.c (gnome_app_realize): Simply show the dock, instead
+ 	of showing_all.
+	(gnome_app_set_contents): Show the contents.
+	(gnome_app_set_menus): Show the dock item.  Put the dock item into
+ 	a new dock band.  The menubar now goes into band 0 (instead of
+ 	band -1).
+	(gnome_app_add_toolbar): Put the dock item into a new dock band.
+  	The toolbar now goes into band 1 (instead of band 0).
+
+1998-12-17  Andrew T. Veliath  <andrewtv usa net>
+
+	* gnome-app.c (gnome_app_set_menus): Make menubar relief agree
+	with with toolbar relief (relief on the dock item, around
+	handles).
+
+Wed Dec 16 17:53:48 1998  Raph Levien  <raph gimp org>
+
+	So far, no changes that affect canvas users or xlib custom items.
+
+	* gnome-canvas-util.h:
+	* gnome-canvas-util.c: Added a number of routines that are helpful
+	for aa rendering.
+
+	* gnome-canvas-rect-ellipse.c: re-enabled the rendering.
+
+	* gnome-canvas.c: Provided default implementatoin of ::update ()
+
+Thu Dec 17  Felix Bellaby  <felix pooh u-net com>
+	* gnome-client.c (gnome_client_connect, gnome_client_set_id): remove
+	some code left over from old config file nameing scheme.
+
+Wed Dec 16 11:51:23 1998  Raph Levien  <raph gimp org>
+
+	* gnome-canvas-rect-ellipse.c (gnome_canvas_re_render): Added
+	alphagamma arg to rendering calls.
+
+1998-12-29  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-properties.c (gnome_property_object_register): Only create
+ 	the label if not already done.
+
+1998-12-29  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-procbar.c (gnome_proc_bar_destroy): New static function.
+	(gnome_proc_bar_class_init): Added `destroy' handler.
+	(gnome_proc_bar_start): Remove old timeout handler first.
+
+Mon Dec 28 20:56:18 1998  George Lebl  <jirka 5z com>
+
+	* gnome-dentry.c: use the same function for breaking strings
+	  as gnome-config does.
+
+Sun Dec 27 21:47:41 1998 Gregory McLean <gregm comstar net>
+
+	* gnome-stock.[c|h] : added a stock cdrom icon that I found in
+	one of larry ewing's galleries. (With his blessing).
+	* pixmaps/stock_cdrom.png: added this.
+
+1998-12-27  Tuomas Kuosmanen  <tigert fun112 koivukyla hoas fi>
+
+	* Replaced the offending-to-some-ethnic-groups Yes/No -buttons
+	with hopefully nicer looking red/green circles (streetlights _are_
+	universal, right? :)
+
+1998-12-23  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-app-helper.c (gnome_app_remove_menu[s|range]):
+	if the item widget is a GtkAccelLabel, set its accel_widget
+	to NULL, thus unreferencing the item properly.
+	(gnome_app_find_menu_pos): trash the outdated checking for
+	gtkhbox since gtkpixmapmenuitem replaced it.
+	* gnome-mdi.c (app_set_view): set accel_widget to NULL.
+
+Mon Dec 21 01:27:23 1998  George Lebl  <jirka 5z com>
+
+	* gnome-icon-entry.c: accept double click on the icon list for
+	  selection of the icon (someone please test this!)
+
+	* gnome-icon-sel.c: just remove an outdated fixme comment
+
+1998-12-21  James Henstridge  <james daa com au>
+
+	* gnome-app-helper.c (gnome_app_remove_menu{s,_range}): don't
+	destroy widgets after calling gtk_container_remove on them.
+	The widgets should be automatically destroyed when their reference
+	count is decremented.
+
+1998-12-18  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-sel.c (gnome_icon_selection_init): Put a frame around
+	the icon list to make it look better.
+
+1998-12-18  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-procbar.c (gnome_proc_bar_draw): Calculate total field
+	here and make it work with vertical procbars.
+	(gnome_proc_bar_set_values): Always redraw the procbar not just
+	if the values have changed.
+
+	* gnome-procbar.c (gnome_proc_bar_draw): New static function.
+	(gnome_proc_bar_set_values): Save values in pb->last even if
+	the widget is not realized. Moved actual drawing code into
+	gnome_proc_bar_draw ().
+	(gnome_proc_bar_start): Call the callback here, not only add
+	a timeout for it.
+	(gnome_proc_bar_configure): Call gnome_proc_bar_draw () if the
+	widget is already realized. This fixes the bug that the procbar
+	was displaying garbage until the timeout was run the first time.
+
+1998-12-18  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c (app_set_view): enhance removing of menus and
+	explicitly destroy the widget after removing it from the
+	menu shell. I guess this has to do with menu refcounting.
+	* gnome-app-helper.c(gnome_app_remove_menus,
+	gnome_app_remove_menu_range): optimize menu removal; explicitly
+	destroy removed widgets. small fix to make removal of first
+	item work properly with tearoff menus.
+
+1998-12-17  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.c (gnome_icon_list_freeze): Hide the root of the
+	canvas while the list is frozen.  This way the user does not see
+	icons loading at the upper left corner.
+	(gnome_icon_list_thaw): Show the canvas root again.
+
+	* gnome-icon-sel.c (append_an_icon): Do not destroy the image that
+	we insert in the icon list.  This is actually not the correct
+	solution.  Imlib needs to provide ref() and unref() functions for
+	its images.
+
+1998-12-17  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-app-helper.c (gnome_app_find_menu_pos): consider the
+	position after the tear off item to be the topmost one.
+
+1998-12-17  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-list.c (icon_event): Propagate button-3 events to the
+	container.
+
+1998-12-17  Andrew T. Veliath  <andrewtv usa net>
+
+	* gnome-app-helper.c (gnome_app_fill_menu_custom): Prepend a
+	tearoff if preferences tell us to.
+	(gnome_app_find_menu_pos): When checking if menu item is a
+	separator, ignore tear off menu items.
+
+	* gnome-preferences.[ch]: Add preference for menus_have_tearoff.
+
+1998-12-17  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-app.c (gnome_app_realize): Simply show the dock, instead
+	of showing_all.
+	(gnome_app_set_contents): Show the contents.
+	(gnome_app_set_menus): Show the dock item.  Put the dock item into a
+	new dock band.  The menubar now goes into
+	band 0 (instead of band -1).
+	(gnome_app_add_toolbar): Put the dock item into a new dock band.
+	The toolbar now goes into band 1 (instead of band 0).
+
+1998-12-17  Andrew T. Veliath  <andrewtv usa net>
+
+	* gnome-app.c (gnome_app_set_menus): Make menubar relief agree
+	with with toolbar relief (relief on the dock item, around
+	handles).
+
+Thu Dec 17  Felix Bellaby  <felix pooh u-net com>
+	* gnome-client.c (gnome_client_connect, gnome_client_set_id): remove
+	some code left over from old config file naming scheme.
+
+1998-12-17  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c: added checks for all returns of
+	gnome_app_find_menu_pos, although the programmer should take
+	of using proper paths!
+
+1998-12-17  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-popup-menu.c (gnome_popup_menu_do_popup_modal): REmoved
+	bogus assert.
+
+1998-12-16  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-number-entry.c (calc_dialog_destroyed): Fix signal
+	signature.
+
+	* gnome-init.c (relay_gtk_signal): Return a value.
+
+Wed Dec 16 17:53:48 1998  Raph Levien  <raph gimp org>
+
+	So far, no changes that affect canvas users or xlib custom items.
+
+	* gnome-canvas-util.h:
+	* gnome-canvas-util.c: Added a number of routines that are helpful
+	for aa rendering.
+
+	* gnome-canvas-rect-ellipse.c: re-enabled the rendering.
+
+Wed Dec 16 11:51:23 1998  Raph Levien  <raph gimp org>
+
+	* gnome-canvas-rect-ellipse.c (gnome_canvas_re_render): Added
+	alphagamma arg to rendering calls.
+
+1998-12-31  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-canvas-rect-ellipse.c (gnome_canvas_re_destroy): Release
+	the outline_svp and the fill_svp.
+
+1998-12-30  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-app.c: Remove gnome_app_add().  You cannot just override
+	container::add() with something else for GnomeApp.
+
+1998-12-30  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-app.c (gnome_app_class_init): make container_add work for
+	gnome-apps.
+
+1998-12-29  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-list.c (icon_event): Emit the selection event always,
+	so that we can get the menu poped up.
+
+1998-12-29  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-app-helper.c (do_ui_signal_connect): moved setting
+	object data to create_menu_item(), so that data is set even
+	with custom connect functions.
+
+1998-12-29  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-properties.c (gnome_property_object_register): Only create
+ 	the label if not already done.
+
+1998-12-29  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-procbar.c (gnome_proc_bar_destroy): New static function.
+	(gnome_proc_bar_class_init): Added `destroy' handler.
+	(gnome_proc_bar_start): Remove old timeout handler first.
+
+Mon Dec 28 20:56:18 1998  George Lebl  <jirka 5z com>
+
+	* gnome-dentry.c: use the same function for breaking strings
+	  as gnome-config does.
+
+Sun Dec 27 21:47:41 1998 Gregory McLean <gregm comstar net>
+
+	* gnome-stock.[c|h] : added a stock cdrom icon that I found in
+	one of larry ewing's galleries. (With his blessing).
+	* pixmaps/stock_cdrom.png: added this.
+
+1998-12-27  Tuomas Kuosmanen  <tigert fun112 koivukyla hoas fi>
+
+	* Replaced the offending-to-some-ethnic-groups Yes/No -buttons
+	with hopefully nicer looking red/green circles (streetlights _are_
+	universal, right? :)
+
+1998-12-23  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-app-helper.c (gnome_app_remove_menu[s|range]):
+	if the item widget is a GtkAccelLabel, set its accel_widget
+	to NULL, thus unreferencing the item properly.
+	(gnome_app_find_menu_pos): trash the outdated checking for
+	gtkhbox since gtkpixmapmenuitem replaced it.
+	* gnome-mdi.c (app_set_view): set accel_widget to NULL.
+
+Mon Dec 21 01:27:23 1998  George Lebl  <jirka 5z com>
+
+	* gnome-icon-entry.c: accept double click on the icon list for
+	  selection of the icon (someone please test this!)
+
+	* gnome-icon-sel.c: just remove an outdated fixme comment
+
+1998-12-21  James Henstridge  <james daa com au>
+
+	* gnome-app-helper.c (gnome_app_remove_menu{s,_range}): don't
+	destroy widgets after calling gtk_container_remove on them.
+	The widgets should be automatically destroyed when their reference
+	count is decremented.
+
+1998-12-18  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-sel.c (gnome_icon_selection_init): Put a frame around
+	the icon list to make it look better.
+
+1998-12-18  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-procbar.c (gnome_proc_bar_draw): Calculate total field
+	here and make it work with vertical procbars.
+	(gnome_proc_bar_set_values): Always redraw the procbar not just
+	if the values have changed.
+
+	* gnome-procbar.c (gnome_proc_bar_draw): New static function.
+	(gnome_proc_bar_set_values): Save values in pb->last even if
+	the widget is not realized. Moved actual drawing code into
+	gnome_proc_bar_draw ().
+	(gnome_proc_bar_start): Call the callback here, not only add
+	a timeout for it.
+	(gnome_proc_bar_configure): Call gnome_proc_bar_draw () if the
+	widget is already realized. This fixes the bug that the procbar
+	was displaying garbage until the timeout was run the first time.
+
+1998-12-18  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c (app_set_view): enhance removing of menus and
+	explicitly destroy the widget after removing it from the
+	menu shell. I guess this has to do with menu refcounting.
+	* gnome-app-helper.c(gnome_app_remove_menus,
+	gnome_app_remove_menu_range): optimize menu removal; explicitly
+	destroy removed widgets. small fix to make removal of first
+	item work properly with tearoff menus.
+
+1998-12-17  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.c (gnome_icon_list_freeze): Hide the root of the
+	canvas while the list is frozen.  This way the user does not see
+	icons loading at the upper left corner.
+	(gnome_icon_list_thaw): Show the canvas root again.
+
+	* gnome-icon-sel.c (append_an_icon): Do not destroy the image that
+	we insert in the icon list.  This is actually not the correct
+	solution.  Imlib needs to provide ref() and unref() functions for
+	its images.
+
+1998-12-17  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-app-helper.c (gnome_app_find_menu_pos): consider the
+	position after the tear off item to be the topmost one.
+
+1998-12-17  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-list.c (icon_event): Propagate button-3 events to the
+	container.
+
+1998-12-17  Andrew T. Veliath  <andrewtv usa net>
+
+	* gnome-app-helper.c (gnome_app_fill_menu_custom): Prepend a
+	tearoff if preferences tell us to.
+	(gnome_app_find_menu_pos): When checking if menu item is a
+	separator, ignore tear off menu items.
+
+	* gnome-preferences.[ch]: Add preference for menus_have_tearoff.
+
+1998-12-17  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-app.c (gnome_app_realize): Simply show the dock, instead
+	of showing_all.
+	(gnome_app_set_contents): Show the contents.
+	(gnome_app_set_menus): Show the dock item.  Put the dock item into a
+	new dock band.  The menubar now goes into
+	band 0 (instead of band -1).
+	(gnome_app_add_toolbar): Put the dock item into a new dock band.
+	The toolbar now goes into band 1 (instead of band 0).
+
+1998-12-17  Andrew T. Veliath  <andrewtv usa net>
+
+	* gnome-app.c (gnome_app_set_menus): Make menubar relief agree
+	with with toolbar relief (relief on the dock item, around
+	handles).
+
+Thu Dec 17  Felix Bellaby  <felix pooh u-net com>
+	* gnome-client.c (gnome_client_connect, gnome_client_set_id): remove
+	some code left over from old config file naming scheme.
+
+1998-12-17  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c: added checks for all returns of
+	gnome_app_find_menu_pos, although the programmer should take
+	of using proper paths!
+
+1998-12-17  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-popup-menu.c (gnome_popup_menu_do_popup_modal): REmoved
+	bogus assert.
+
+1998-12-16  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-number-entry.c (calc_dialog_destroyed): Fix signal
+	signature.
+
+	* gnome-init.c (relay_gtk_signal): Return a value.
+
+Wed Dec 16 17:53:48 1998  Raph Levien  <raph gimp org>
+
+	So far, no changes that affect canvas users or xlib custom items.
+
+	* gnome-canvas-util.h:
+	* gnome-canvas-util.c: Added a number of routines that are helpful
+	for aa rendering.
+
+	* gnome-canvas-rect-ellipse.c: re-enabled the rendering.
+
+Wed Dec 16 11:51:23 1998  Raph Levien  <raph gimp org>
+
+	* gnome-canvas-rect-ellipse.c (gnome_canvas_re_render): Added
+	alphagamma arg to rendering calls.
+
+1998-12-16  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.[ch]: Misc. updates to accomodate the new rendering
+	and propagation model.
+	* gnome-canvas-rect-ellipse.c: Likewise.
+	* gnome-canvas-image.c: Likewise.
+	* gnome-canvas-text.c: Likewise.
+	* gnome-canvas-line.c: Likewise.
+	* gnome-canvas-polygon.c: Likewise.
+	* gnome-canvas-widget.c: Likewise.
+	* gnome-icon-item.c: Likewise.
+
+1998-12-16  Yukihiro Nakai <Nakai abricot co jp>
+
+	* Added gtkrc.ja. The original gtkrc is not good for
+	the multi-byte users.
+
+1998-12-16  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-dock-item.c (gnome_dock_item_detach): Set the "transient
+	for" hint properly.
+        (gnome_dock_item_map_event): Do the `dock_item_detach()' hack
+ 	only if we are actually floating.
+
+1998-12-16  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-dock-item.c (gnome_dock_item_realize): set transient for
+	the floating window so that it gets minimized with the dock-item's
+	toplevel (usually a GnomeApp).
+
+1998-12-15  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-rootwin.[ch]: Removed this before the freeze.
+
+1998-12-15  Havoc Pennington  <hp pobox com>
+
+	* gnome-popup-menu.c (gnome_popup_menu_new): Set global variable
+	for use by connect function.
+	(popup_connect_func): Attach a pointer to the toplevel menu shell
+	to each menu item.
+	(popup_marshal_func): Get pointer to toplevel shell, instead of
+	immediate parent.
+
+1998-12-15  Havoc Pennington  <hp pobox com>
+
+	* gnome-dock-item.h: Change GNOME_DOCK_ITEM_BEH_NEVER_DETACH
+	to GNOME_DOCK_ITEM_BEH_NEVER_FLOATING for Ettore; add
+	GNOME_DOCK_ITEM_BEH_LOCKED.
+
+	* gnome-dock-item.c: Reflect name changes and new flag.
+
+	* gnome-app.c (gnome_app_set_toolbar): GNOME_DOCK_ITEM_BEH_LOCKED
+	instead of NEVER_DETACH
+	(gnome_app_set_menus): Same
+
+	* dock_demo.c (main): Same
+
+1998-12-15  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c: clone apps layout whenever possible.
+	(gnome_mdi_set_mode): optimized things a bit. also
+	preserve the layout of the active app.
+	* gnome-dock.c (gnome_dock_size_allocate): keep
+	dock->client_area in sync with client_area's allocation
+	or initialize it to proper values if there is no client_area.
+	(drag_begin): no longer need to set values to dock->client_rect, as
+	it is always kept in sync with client_area's allocation, also we
+	don't SIGSEGV anymore if no client_area is set.
+	(drag_floating): prevent a SIGSEGV if there is no client_area.
+
+1998-12-15  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-init.c: Do not use imlib private data, use the new
+	exported routines instead.
+
+1998-12-15  Martin Baulig  <baulig merkur uni-trier de>
+
+	* pixmaps/Makefile.am (CLEANFILES): Add $(BUILT_SOURCES) here.
+
+Tue Dec 15  Felix Bellaby  <felix pooh u-net com>
+	* gnome-client.c (gnome_dlient_set_config_prefix): new function
+	for use by clients like the panel that use special config names.
+	* gnome-client.h: extra docs plus new function
+
+1998-12-15  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-app.c (gnome_app_get_dock): New function.
+	(gnome_app_add_dock_item): New function.
+	(gnome_app_add_docked): Rewritten by means of
+ 	`gnome_app_add_dock_item()'.
+
+	* gnome-dock.c (gnome_dock_init): Initialize
+	`floating_items_allowed' to TRUE.
+	(gnome_dock_allow_floating_items): New function.
+        (drag_motion): Do not detach if floating items are
+	not allowed.
+
+	* gnome-dock.h (struct _GnomeDock): New member
+ 	`floating_items_allowed'.
+
+	* gnome-dock-band.h: Marked as immature.
+
+	* gnome-dock.h: Marked as immature.
+
+	* gnome-dock-item.h: Marked as immature.
+
+	* gnome-app.c (gnome_app_get_dock_item_by_name): New function.
+
+	* gnome-dock-item.c (gnome_dock_item_get_child): New function.
+
+	* gnome-app.c (gnome_app_set_menus):
+ 	s/get_menubar_detachable/get_toolbar_detachable.
+
+1998-12-15  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-app.c (gnome_app_set_*): removed "layout_changed" signal
+	emissions after calling gnome_dock_add_item().
+	* gnome-dock.c (gnome_dock_add_item, gnome_dock_add_floating_item):
+	emit "layout_changed" signal.
+
+1998-12-15  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-procbar.c (gnome_proc_bar_set_orient): New function.
+
+1998-12-14  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-app-helper.c (gnome_app_install_appbar_menu_hints): Remove
+	C++ comments.
+
+1998-12-15  Jeff Garzik  <jgarzik pobox com>
+
+	* gnome-spell.[ch], gtkspell.[ch]:
+	Renamed gtkspell to gnome-spell, internationalized, doc'd.
+
+1998-12-15  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-app.c (gnome_app_set_*bar): for setting things after the
+	layout is gone, use insertion directly into dock.
+	* gnome-dock.[ch]: fixed functions to have GnomeDockItem* instead
+	of GtkWidget* as a parameter (like layout functions).
+	(gnome_dock_add_item): put offset behind position.
+	* gnome-mdi-session.c: save layouts of the windows, but don't
+	restore them as we have no method to properly do that yet.
+	* gnome-mdi.[ch], gnome-mdi-child.h, gnome-mdi-generic-child.h,
+	gnome-mdi-session.h: some bug fixes and some cosmetics.
+
+1998-12-14  Havoc Pennington  <hp pobox com>
+
+	* gnome-app.c (gnome_app_set_toolbar): Honor preferences by
+	setting behavior to NEVER_DETACH if user wants.
+	(gnome_app_set_menus): Same.
+
+	Maybe this should be done for add_docked too?
+
+	* gnome-dock-item.c: If we are BEH_NEVER_DETACH, don't draw
+	the handle box and don't allow movement. Ettore, not sure this
+	was the right flag; I used a GNOME_DOCK_ITEM_DETACHABLE macro
+	so I can add a different flag if needed.
+	(gnome_dock_item_size_request): If we are not detachable,
+	don't consider handle size.
+	(gnome_dock_item_size_allocate): If we aren't detachable,
+	give all space to child.
+	(gnome_dock_item_paint): If not detachable, don't draw
+	handle
+	(gnome_dock_item_button_changed): If not detachable,
+	ignore button presses.
+
+
+	* dock_demo.c: Add a NEVER_DETACH toolbar.
+
+1998-12-15  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-app.c (gnome_app_enable_layout_config): New function.
+
+1998-12-14  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-app.h (GNOME_APP_MENUBAR_NAME, GNOME_APP_TOOLBAR_NAME):
+	New public #defines.
+
+	* gnome-app.c (gnome_app_init): Create the layout.
+	(gnome_app_set_menus): Add the menu to the layout instead of
+ 	putting it into the dock directly.
+	(gnome_app_set_toolbar): Likewise.
+	(layout_changed): New private function.  If `enable_layout_config'
+	is TRUE, it updates the layout configuration via gnome-config.
+	(gnome_app_realize): New function.  Save the dock configuration if
+	`enable_layout_config' is TRUE.  Connect the "layout_change"
+	signal of the dock to `layout_changed()'.
+	(gnome_app_init): Install it.
+	(write_layout_config): New helper function.
+	(read_layout_config): New helper function.
+	(gnome_app_add_docked): New function.
+	(gnome_app_add_toolbar): New function.
+
+	* gnome-dock-layout.c (gnome_dock_layout_new): Return a
+	`GnomeDockLayout *' instead of `GtkObject *'.
+
+	* gnome-app.h: Reorganized with the following members: `name',
+ 	`prefix', `dock', `statusbar', `vbox', `menubar', `accel_group',
+ 	`contents'.  New member `auto_config_layout' to automagically
+ 	handle layout configurations.
+
+	* gnome-app.c (gnome_app_init): Do not initialize `pos_menubar'
+	and `pos_toolbar' anymore.
+	(gnome_app_toolbar_set_position): Removed.
+	(gnome_app_menu_set_position): Removed.
+
+	* gnome-app.h: Removed `pos_menubar' and `pos_toolbar' members.
+
+	* gnome-dock.c (gnome_dock_class_init): Add handler for the
+	"layout_changed" signal.
+	(drag_end): Emit "layout_changed".
+	(gnome_dock_add_from_layout): New function.
+	(gnome_dock_get_client_area): New function.
+
+	* gnome-dock.h (struct _GnomeDockClass): Added `layout_changed'
+ 	member.
+
+	* gnome-app.h (GnomeAppWidgetPositionType): Removed.
+
+	* gnome-app.c (get_orientation): Removed.
+
+	* gnome-dock-item.c (gnome_dock_item_get_floating_position): New
+ 	function.
+	(gnome_dock_item_map): If floating, do not map widget->window.
+
+	* gnome-dock.c (drag_floating): Grab the pointer after calling
+ 	`gnome_dock_item_detach()'.
+	(connect_drag_signals): New helper function.
+	(gnome_dock_add_item): Use it.
+	(gnome_dock_add_floating_item): Use it.
+
+	* gnome-dock-item.c (gnome_dock_item_init): Initialize `float_x'
+	and `float_y'.
+	(gnome_dock_item_detach): Set `float_x' and `float_y'.  Do not
+	move the window if the widget is not realized yet.  Do not grab
+	the pointer anymore.
+	(gnome_dock_item_realize): If floating, detach.
+	(gnome_dock_item_drag_floating): Update `float_x' and `float_y'.
+
+	* gnome-dock-item.h (struct _GnomeDockItem): New members
+	`float_x', `float_y' holding the position of the floating window.
+
+	* gnome-dock-layout.c (item_compare_func): Don't order floating
+ 	items.
+	(gnome_dock_layout_add): Renamed to `gnome_dock_layout_add_item'.
+	(gnome_dock_layout_add_floating_item): New function.
+
+	* gnome-dock.c (gnome_dock_add_floating_item): New function.
+
+	* gnome-dock-layout.h (struct _GnomeDockLayoutItem): Added union
+ 	`position' to store positions for docked and floating items
+ 	differently.  All the functions updated to handle it.
+
+	* gnome-dock.h (enum GnomeDockPositionType): Renamed to
+ 	`GnomeDockPlacement'.
+
+	* gnome-dock-item.c (gnome_dock_item_map_event): If
+ 	`grab_on_map_event' is set, call `gnome_dock_item_detach()' at the
+ 	current pointer position.
+	(gnome_dock_item_motion): Removed unused `snap_x', `snap_y'
+ 	variables and `gdk_window_get_pointer()' call.
+	(gnome_dock_item_size_request): Return real size even when
+ 	floating.
+
+1998-12-14  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.c (gil_get_items_per_line): Fetch the widget
+	width from the allocation, not the canvas.
+	(gil_mark_region): Likewise.
+
+	* gnome-canvas.c: Removed the gnome_canvas_set_size() function.
+	People can use gtk_widget_set_usize() now.  Also, removed
+	gnome_canvas_size_request().
+
+	* gnome-canvas.h (GnomeCanvas): Removed the width and height
+	fields, since they were the size of the allocation anyways.
+
+Mon Dec 14 10:19:59 1998  Owen Taylor  <otaylor redhat com>
+
+	* gnome-canvas.c: Add idle handlers at GTK_PRIORITY_INTERNAL,
+	so they trigger gtk_events_pending().
+
+Sun Dec 13 20:50:06 1998  George Lebl  <jirka 5z com>
+
+	* gnome-client.c: fix typo interaction_key -> interaction_keys
+
+1998-12-13  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-init.c 	(gnome_init_cb): Change of strategy.  Pixmaps are
+	not cached, but images are.
+
+Mon Dec 14  Felix Bellaby  <felix pooh u-net com>
+
+	* gnome-client.c (gnome_dlient_get_config_prefix): change the prefix
+	after each Save Yourself to avoid cuorrupting past saves.
+	* gnome-client.h: extra docs for obscure bits of the protocol.
+
+1998-12-14  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-app.c: Removed some `#if 0'ed stuff.
+	(DEFAULT_TOOLBAR_NAME, DEFAULT_MENUBAR_NAME): New string
+ 	constants.
+	(gnome_app_set_menus): Give the menubar the `DEFAULT_MENUBAR_NAME'.
+	(gnome_app_set_toolbar): Give the toolbar the
+	`DEFAULT_TOOLBAR_NAME'.  If not using toolbar reliefs, set the
+	dock item's border width to 1.
+
+	* dock_demo.c: Demonstrate usage of GnomeDockLayout by saving the
+	dock configuration on exit, and reloading it a startup.
+
+	* gnome-dock.h: Changed order of the `GnomeDockPositionType' so
+	that numbering goes clockwise.
+
+	* gnome-dock.c (drag_new): Return value made gboolean: return TRUE
+ 	iff successfull.
+	(drag_to): Likewise.
+	(drag_floating): Likewise.
+	(drag_check): Return a value according to what the `drag_*'
+ 	functions returned.
+        (gnome_dock_get_item_by_name): New function.
+	(get_docked_item_by_name): New helper function.
+	(get_floating_item_by_name): New helper function.
+ 	(gnome_dock_get_layout): New function to get the layout.
+	(layout_add_floating, layout_add_bands): New private helper
+ 	functions.
+	(gnome_dock_add_item): When creating the new band, orient it
+ 	appropriately.
+
+	* gnome-dock-layout.c, gnome-dock-layout.h: New files to handle
+	the docking layout.
+
+	* gnome-dock-item.c: Removed unused `GHOST_HEIGHT' and
+ 	`CHILDLESS_SIZE' constants.
+	(gnome_dock_item_init): Set the container's border width to 1.
+	(gnome_dock_item_size_request): Request space only for the handle.
+	(gnome_dock_item_detach): Size_allocate after reparenting, not
+ 	before.
+	(gnome_dock_item_size_request_with_child): New function.
+	(gnome_dock_item_init): Do not force a border width anymore.
+ 	(gnome_dock_item_new): New parameter `name'.
+
+	* gnome-dock-item.h (struct _GnomeDockItem): New member `name',
+ 	name of the item.  Member `child_detached' renamed to
+ 	`is_floating'.
+
+	* gnome-dock.c, gnome-dock.h: Occurrences of the words "detached"
+ 	and "undocked" replaced with "floating" for consistence.
+	* gnome-dock-item.c, gnome-dock-item.h: Likewise.
+
+	* gnome-dock-band.c (calc_prev_and_foll_space): Also consider the
+ 	extra allocated space as empty, reusable space.
+	(gnome_dock_band_layout_add): New function.
+
+	* gnome-dock.c (drag_floating): New parameters `rel_x', `rel_y'.
+  	Detach only if the pointer is outside all the docking areas.  (To
+	be fixed.)
+	(drag_motion): Pass `rel_x' and `rel_y' to `drag_floating'.
+
+1998-12-13  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	(gnome_init_cb): Remove the hack mentioned below.
+	A better bug fix is now available in Imlib.
+
+1998-12-13  Jeff Garzik  <jgarzik pobox com>
+
+	* gnome-init.c:
+	Created BROKEN_AXP_IMLIB define to eliminate BadMatch problems
+	on Alpha, with every single GNOME app that uses imlib.
+	FIXME: This is a hack that masks the real problem (whatever it is)
+
+1998-12-13  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-procbar.[ch]: New files. Added the GnomeProcBar that is
+ 	used in GTop and the cpumemusage applet here.
+
+1998-12-13  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-app-util.c (gnome_app_activate_statusbar): new private
+	function: raises the app, sets focus to statusbar and activate it.
+	(gnome_app_error_bar, gnome_app_message_bar, gnome_app_reply_bar):
+	activate the statusbar.
+
+1998-12-13  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-property-entries.c (gnome_property_entry_colors): New
+	function. See gtop/procview.c and gtop/graph.c for an usage
+	example.
+
+	* gnome-properties.h: Marked as immature.
+	* gnome-property-entries.h: Marked as immature.
+
+1998-12-13  Andrew T. Veliath  <andrewtv usa net>
+
+	* gnome-preferences.[ch]: Resurrect {menubar,toolbar}_handlebox as
+	{menubar,toolbar}_detachable, which should eventually cause the
+	gnome-dock in gnome-app not to have a handle (not functional yet).
+
+	* gnome-app.c, dock_demo.c:
+	s/container_border_width/container_set_border_width/
+
+	* gnome-app.c (gnome_app_set_menus): Set menubar dock item's
+	border width to 0.
+
+Sat Dec 12  Felix Bellaby  <felix pooh u-net com>
+
+	* gnome-client.c (gnome_client_parse_func): set program property so
+	that non-glibc systems meet SM spec requirements.
+	(grab_widget): grab widget for gtk events during session save.
+
+1998-12-12  James Henstridge  <james daa com au>
+
+	* gnome-href.c: small cosmetic change for this widget.  Now the cursor
+	is the hand cursor, as in netscape.
+
+1998-12-12  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c (set_page_by_widget): don't touch GtkNotebook's
+	members, only use public functions.
+	(book_create): don't explicitly realize GtkNotebook.
+	(app_create): likewise for GnomeApps. this probably remained from
+	the old DnD protocol.
+	(app_set_view): only queue a resize for the parent menushell once.
+	(gnome_mdi_set_tab_pos): removed. this should only be set on a
+	per-user (via ui-properties) and not per-app basis.
+	* gnome-mdi.h (gnome_mdi_set_tab_pos): removed.
+
+Fri Dec 11 21:45:32 1998 Gregory McLean <gregm comstar net>
+
+	* *.[c|h] : FSF address update.. (Had the old Mass Ave addy)
+
+1998-12-11  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-preferences.c: Control the imlib cache from here.
+
+	* gnome-init.c: Acknowledge the setting from gnome-preferences to
+	the imlib cache.
+
+Fri Dec 11 21:36:48 1998  Felix Bellaby  <felix pooh u-net com>
+
+	* gnome-client.[ch] (gnome_client_save_any_dialog): more interact API
+	(gnome_client_save_error_dialog): more interact API
+
+Fri Dec 11 03:16:17 1998  Owen Taylor  <otaylor redhat com>
+
+	* gnome-icon-item.c (gnome_icon_text_item_stop_editing):
+	New function.
+
+	* gnome-icon-item.c (iti_idx_from_x_y): Fix to
+	position computation for click location.
+
+	* gnome-icon-item.[ch]: Start editing text on release,
+	not click.
+
+	* gnome-icon-item.[ch]: Keep an explicit flag to
+	tell if we are selecting. editable->have_selection is
+	something else.
+
+	* gnome-icon-list.c (icon_new_from_imlib): connect_after
+	to the presses on the text, so that the initial
+	press on text selects, not edits.
+
+1998-12-10  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.c (gil_button_release): Convert the button
+	release coordinates to world coordinates before calling
+	gil_mark_region().
+
+1998-12-10  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.[ch]: gnome_mdi_active_*() become
+	gnome_mdi_get_active_*().
+	* gnome-mdi.c (book_button_release): raise the app with the
+	destination notebook. some documentation fixes.
+	(gnome_mdi_set_active_view): remove all the focus stuff.
+
+1998-12-09  Dave Camp  <campd oit edu>
+	* gnome-dateedit.c (select_clicked): Fixed the problem where
+	the first time the Calendar button was pushed it didn't place
+	itself right.  Also made it select the correct date in the
+	calendar widget
+	(create_children): Put the gtk_widget_show on the calender
+	back here.
+
+1998-12-10  Andrew T. Veliath  <andrewtv usa net>
+
+	* gnome-app-helper.c, gnome-app.c (gnome_app_set_menus):
+	(gnome_app_set_toolbar): Have gnome dock item adhere to gnome
+	preferences toolbar and menubar relief styles.
+
+	* gnome-preferences.[ch]: Updates and cleanups.
+
+	{toolbar,menubar}_handlebox preferences removed; obsoleted by
+	gnome-dock integration.
+
+	Renamed toolbar_relief to toolbar_relief_btn.  Renamed
+	toolbar_flat to toolbar_relief, inverting the logic for
+	consistency with menubar relief.
+
+1998-12-10  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c (book_button_release): fixed some weird code that
+	caused mayhem when the last page of a notebook was being dragged
+	away. did I do this? ;)
+	(set_active_view): update mdi->active_window.
+
+1998-12-09  Dave Camp  <campd oit edu>
+        * gnome-dateedit.c (select_clicked):
+
+        Shows the pop-up calendar widget.
+
+        Synchnonizes the pop-up calendar with the date in the entrybox
+        (create_children): Took out gtk_widget_show on the calendar, as
+        is is now showed in select_clicked.
+
+1998-12-08  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-list.c (gil_place_icon): Center images in the icon
+	list.
+	(gil_unselect_all): Unselect all of the icons on left button
+	click.
+
+1998-12-09  Ettore Perazzoli  <ettore comm2000 it>
+
+	* dock_demo.c (main): Updated calls to `gnome_dock_add_item()'.
+	Set a default window size instead of forcing a minimum size.
+
+	* gnome-app.c: #Include "libgnomeui/gnome-dock.h".
+	(gnome_app_init): Create `dock' and `vbox', and make `dock' child
+ 	of `vbox'.
+	(gnome_app_configure_positions): `#if 0'ed out.
+	(gnome_app_menu_set_position): Deprecated.
+	(gnome_app_toolbar_set_position): Deprecated.
+	(gnome_app_set_contents): Set `contents' as the `dock''s
+ 	`client_area'.
+	(make_button_menubar): `#if 0'ed out.
+	(configure_toolbar): `#if 0'ed out.
+	(make_button_toolbar): `#if 0'ed out.
+	(gnome_app_rightclick_menubar): `#if 0'ed out.
+	(gnome_app_reparent_handle_box): `#if 0'ed out.
+	(gnome_app_rightclick_toolbar): `#if 0'ed out.
+	(gnome_app_setpos_activate_menubar): `#if 0'ed out.
+	(gnome_app_setpos_activate_toolbar): `#if 0'ed out.
+	(gnome_app_set_menus): Add the bar to the `GnomeDock'.  Removed
+ 	right-click menu and position handling.
+	(gnome_app_set_toolbar): Likewise with the toolbar.
+
+	* gnome-dock.c (gnome_dock_set_client_area): If we already have a
+ 	`client_area', unparent it.  Passing NULL as `widget' now removes
+ 	the `client_area'.
+	(gnome_dock_add_item): Replaced `return's with `break's in switch.
+  	New parameter `in_new_band'.  If TRUE, it always adds a new band
+ 	to the specified edge.
+ 	(gnome_dock_add): Updated to the new `gnome_dock_add_item()'.
+	(gnome_dock_forall): New function, implementing the `forall'
+ 	GtkContainer method.
+	(gnome_dock_class_init): Install it.
+	(gnome_dock_destroy): Now useless, removed.
+	(drag_floating): Add the widget to the `undocked_children' list.
+	(gnome_dock_remove): Handle the case when the child is a detached
+ 	item.
+	(gnome_dock_map): Handle detached children.
+
+	* gnome-app.h (struct _GnomeApp): New member `dock'.  `table'
+	replaced by `vbox'.
+
+1998-12-09  Jeff Garzik  <jgarzik pobox com>
+
+	* gnome-init.c (gnome_init_cb):
+	Added null-ptr-deref sanity checks.
+	Bugfix for trigger stuff to handle absent trigger list.
+
+	* gnome-mdi.[ch]:
+	(gnome_mdi_set_child_menu_path, gnome_mdi_set_child_list_path):
+	Make path arg const-correct.
+
+1998-12-09  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi-child.c (gnome_mdi_child_set_label): left-justify
+	the label. it looks better this way.
+
+1998-12-09  Carsten Schaar  <nhadcasc fs-maphy uni-hannover de>
+
+	* gnome-client.c (client_set_state): New function.
+	(client_save_yourself_possibly_done): Handle the case, that a
+ 	'SaveYourselfPhase2' request is rejected.
+	(gnome_client_class_init): Run the 'die' default handler last.
+	(gnome_client_request_interaction_internal): Handle the case, that
+ 	a 'InteractRequest' is rejected.
+
+	* gnome-client.h (enum GnomeClientState): Added additional states.
+	(struct _GnomeClient): Removed phase.
+
+1998-12-08  Tim P. Gerla  <timg means net>
+
+	* gnome-paper-selector.c: Added some padding around the dialog.
+
+1998-12-08  Herbert Valerio Riedel  <hvr hvrlab ml org>
+
+	* gtk-ted.c: fixed some cast-warnings
+	* gnome-stock.c: fixed some cast-warnings
+	* gnome-mdi.c: added #include <string.h> for memcpy()
+	* gnome-href.c: added #include <string.h> for strlen()
+	* gnome-font-selector.[ch]: enforced use of const-ness and
+       	glib-typedefs
+	* gnome-dns.c: GINT_TO_POINTER() instead of a mere (gpointer)
+	(gnome_dns_callback): same
+	* gnome-appbar.c: added #include <string.h> for strlen()
+	* gnome-init.c: added #include <esd.h> if HAVE_ESD
+
+1998-12-08  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gtkcauldron.c (get_gnome_number_entry_result): Make static.
+	(get_gnome_file_entry_result): same.
+
+1998-12-08  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c (book_switch_page): only call app_set_view() if the
+	new current page's child differs from active_view.
+	(gnome_mdi_set_mode): open a toplevel if there was one open before,
+	even without any children.
+	* gnome-app-helper.c (gnome_app_install_statusbar_menu_hints,
+	gnome_app_install_appbar_menu_hints): handle GNOME_APP_UI_RADIOITEMS
+	and don't try to set callback for GNOME_APP_UI_HELP entry.
+
+1998-12-08  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-dock-band.h: Removed unused enum that caused
+	`makeenums.pl' to complain.
+
+1998-12-08  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.[ch]: scratched custom functions for creating
+	menubar/toolbar. use app_created signal instead to customize
+	each GnomeApp at your will if the GnomeUIInfo templates don't
+	do it for you. also moved GNOME_MDI_*_INFO_KEYs back to
+	gnome-mdi.c and added functions to retrieve the UIInfo arrays
+	from GnomeApps to prevent a temptation of the users to try and
+	set some of their own data with this key.
+	* gnome-mdi-session.c: added documentation.
+	* gnome-app-helper.c (gnome_app_install_menu_hints): new function
+	that tries to install menu hints depending on type of app->statubar.
+
+1998-12-08  Andrew T. Veliath  <andrewtv usa net>
+
+	* gnome-app.c, gnome-app-helper.[ch]: Update for integrated
+	GtkToolbar space style functionality (obsoletes
+	gnome_app_toolbar_configure; removed).
+
+1998-12-08  Ettore Perazzoli  <ettore comm2000 it>
+
+	* libgnomeui.h: #Include "libgnomeui/gnome-dock.h"
+ 	"libgnomeui/gnome-dock-band.h" and "libgnomeui/gnome-dock-item.h".
+
+	* dock_demo.c: New file: temporary demo for the GnomeDock*
+ 	widgets.
+
+	* gnome-dock.c, gnome-dock.h: New files implementing the GnomeDock
+	widget.
+
+	* gnome-dock-band.c, gnome-dock-band.h: New files implementing the
+	GnomeDockBand widget.
+
+	* gnome-dock-item.c, gnome-dock-item.h: New files implementing the
+	GnomeDockItem widget.
+
+1998-12-07  Havoc Pennington  <hp pobox com>
+
+	* gnome-app-helper.c (gnome_app_install_appbar_menu_hints):
+	Function which connects the hints in a UIInfo menu struct to
+	some GnomeAppBar.
+	(gnome_app_install_statusbar_menu_hints): Same for
+	GtkStatusbar.
+
+1998-12-08  James Henstridge  <james daa com au>
+
+	* gnome-mdi-generic-child.c: added documentation for this widget.
+
+1998-12-07  Havoc Pennington  <hp pobox com>
+
+	* gnome-dialog.h, gnome-dialog.c
+	(gnome_dialog_run_and_hide): removed.
+	(gnome_dialog_set_destroy): removed.
+	(gnome_dialog_run_modal): removed.
+	(gnome_dialog_run_and_destroy): removed.
+	(gnome_dialog_set_modal): removed.
+	(struct _GnomeDialog): Remove 'parent' member since
+	GtkWindow has one now.
+
+	* gnome-dialog.c (gnome_dialog_set_parent): Call
+	gtk_window_set_transient_for() to attach dialog to its parent.
+	Nearly all dialogs should call gnome_dialog_set_parent() now!
+
+1998-12-08  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi-child.[ch], gnome-mdi-generic-child.[ch]:
+	some cosmetic fixes. added almost all documentation.
+	* gnome-mdi.c: some doc fixes.
+
+Sun Dec  6 22:40:23 1998  Raph Levien  <raph gimp org>
+
+	* gnome-canvas.h:
+	* gnome-canvas.c: Added basic support for antialiased rendering.
+	It's overeager to repaint (for example, any time an item gets
+	translated, the entire bounding box gets repainted). There is
+	no support yet for affine transformations or clip paths. However,
+	I feel that the basic concept is sound.
+
+	* gnome-canvas-rect-ellipse.h:
+	* gnome-canvas-rect-ellipse.c: I am using the rect-ellipse item as
+	the basic testbed for adding antialiased rendering. It's certainly
+	not perfect yet, but it basically works in the test-gnome demo.
+
+1998-12-07  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c: slight indentation changes. added documentation
+	to public functions.
+
+1998-12-05  Jeff Garzik  <jgarzik pobox com>
+
+	* gnome-href.[ch]:
+	Made const-correct.
+	Added API docs.
+	Small formatting cleanups (judicious use of blank lines).
+	gnome_href_new() returns NULL if url arg is NULL.  (this is
+	implied with gnome_href_set_url checks)
+
+1998-12-03  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-about.c (gnome_about_new): I got a bit carried away.
+
+1998-12-04  Jaka Mocnik <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.h: removed GNOME_MDI_REDRAW enum.
+	* gnome-mdi.c (gnome_mdi_set_mode): fixed a bug that caused
+	a toplevel window to be opened during the initial call.
+	(gnome_mdi_add_toplevel_view): make it do what you want it
+	to (One Of The Few, Pink Floyd, Final Cut, 1983) ;).
+	* gnome-mdi-session.h: changed typedef GnomeMDIChildCreate to
+	GnomeMDIChildCreator - it sounds better ;).
+	* gnome-mdi-session.c (gnome_mdi_save_state): properly save
+	window origins. fixed window ids to REALLY be the pointers
+	to GnomeApps. session saving should now work for all modes.
+	(widget_parent_func): removed. use view_window_func instead.
+	(window_list_func): removed.
+
+1998-12-03  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c: Indentation fixes.  Also, the main canvas module
+	now has full documentation!  Wheee!
+
+1998-12-02  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-about.c (gnome_about_new): Add checks.
+
+Wed Dec  2 12:51:54 1998  Raph Levien  <raph gimp org>
+
+	* gnome-canvas.h:
+	* gnome-canvas.c (gnome_canvas_request_redraw): This is the
+	microtile patch. Added gnome_canvas_request_redraw_uta, and
+	it all works with microtiles now.
+
+1998-12-02  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-properties.c: Added new GnomeProperty code here.
+
+	* gnome-property-entries.[ch]: New files. Makes it more easy
+	to create commonly used property entries like font properties etc.
+
+1998-12-01  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.c (gil_button_press): Grab the rectangle
+	selection item to grab the mouse.
+	(gil_button_release): Ungrab the item and thus the mouse.
+	(gil_button_press): Use a nice stipple pattern for the selection
+	rectangle.
+	(gil_mark_region): Do not look amateurish; make the selection
+	rectangle only extend to the borders of the window.
+	(gnome_icon_list_thaw): Do not allow thaws if the freeze counter
+	is <= zero.
+	Reverted all gil->frozen > 0 tests.
+
+1998-12-01  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-list.c (gil_mark_region): New routine.  Expand the
+	selection on the timeout handler as well.  This makes the banding
+	selection in the GnomeIconList much nicer when the mouse is
+	outside of the window.
+
+1998-12-01  Justin Maurer  <justin openprojects net>
+
+	* gnome-paper-selector.[ch]: i f'ed up. checking in old versions.
+	starting again.
+
+1998-12-01  Jeff Garzik  <jgarzik pobox com>
+
+	* gnome-app-helper.[ch]:
+	Updated API docs a bit.
+
+	(gnome_app_fill_menu, gnome_app_fill_menu_custom):
+	Changed insert_shortcuts to a gboolean.
+	Reformatted surrounding comments to fit in 80 columns.
+
+1998-12-01  Dietmar Maurer  <dm vlsivie tuwien ac at>
+
+	* gnome-app-helper.[ch]: use the new gtk_pixmap_menu_item.
+	Removed indent_missing_pixmap parameter, since correct
+	indentation is handled by gtk_pixmap_menu_item.
+	create_pixmap_and_label replaced by create_label.
+
+	* gtkpixmapmenuitem.c: added new remove function.
+
+1998-12-01  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c, gnome-mdi-child.[ch], gnome-mdi-generic-child.[ch]
+	gnome-mdi-session.c: applied James Henstridge's interp modifications
+	to make creating bindings for other languages easier.
+
+1998-11-30  Justin Maurer  <justin openprojects net>
+
+	* gnome-paper-selector: merge old code with new, add in seth's
+	changes. sloppy. will test more.
+
+1998-11-30  Jonathan Blandford  <jrb aware-of-vacuity labs redhat com>
+
+	* gnome-popup-help.c (gnome_popup_help_place_window): quick buglet fix
+
+1998-11-29  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.h: Removed obsolete comment about
+	gnome_icon_list_new_thawed().
+
+	* gnome-icon-list.c: All the assertions that checked for the
+	number of icons in the ilist were wrong.  Fixed them.
+
+1998-11-29  Justin Maurer  <justin openprojects net>
+
+	* gnome-app-helper.c: voila! done. small scattered bugfixes.
+
+1998-11-29  Carsten Schaar  <nhadcasc fs-maphy uni-hannover de>
+
+	* gnome-client.c (client_save_yourself_possibly_done): New function.
+	(client_save_phase_2_callback): Uses new function.
+	(client_save_yourself_callback): Likewise.
+	(gnome_interaction_key_return): Likewise.
+
+1998-11-29  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c, gnome-mdi-child.[ch], gnome-mdi-generic-child.[ch]:
+	changed all occurences of set_book_label to set_label.
+	* gnome-mdi.c (child_list_menu_*): use set_label function
+	to provide menu item labels as well as notebook page labels!
+
+1998-11-29  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-sel.c (gnome_icon_selection_init): Fix to the new
+	behaviour of GnomeIconList.
+
+	* gnome-icon-list.c: Frozen tests are now done by comparing the
+	sign, not comparing different than zero.
+	(gil_init): IconList no longer starts in frozen state by popular demand.
+
+1998-11-29  Havoc Pennington  <hp pobox com>
+
+	* gnome-guru.c: add a cast or two to remove compiler
+	warnings.
+
+1998-11-29  Raja R Harinath  <harinath cs umn edu>
+
+	* gnome-app-helper.c (create_menu_item): Don't put unprotected
+	newlines in strings.  It is not portable.
+	(create_radio_menu_items): Likewise.
+	(create_help_entries): Likewise.
+	(create_toolbar_item): Likewise.
+	(create_radio_toolbar_items): Likewise.
+	(gnome_app_remove_menus): Likewise.
+	(gnome_app_insert_menus_custom): Likewise.
+
+Sat Nov 28 21:30:09 1998  George Lebl  <jirka 5z com>
+
+	* gnome-icon-sel.c: use GnomeIconList instead of CList, fixed
+	  minor possible leak with non-shown icons, and made _clear
+	  take an extra parameter as a boolean wheather the non shown
+	  icons are also cleared or not. Also documented the widget's
+	  functions
+
+	* gnome-icon-entry.c: fixed a small assumption about internals
+	  of icon-sel and documented the functions in icon-entry
+
+	* gnome-pixmap.c: do gtk_widget_combine_mask instead of the gdk
+	  function, this fixes pixmap problems with themes in case an
+	  x window is used
+
+1998-11-28  Justin Maurer  <justin openprojects net>
+
+	* gnome-app-helper.h: removed GNOMEUIINFO_SUBTREE_ITEM_STOCK macro
+	(redundant). removed right justification stuff.
+
+	* gnome-app-helper.c: removed right justification stuff. cleaned up
+	code.
+	(create_help_entries): takes one less argument now.
+	(create_radio_menu_items): same.
+
+1998-11-28  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-propertybox.c (gnome_property_box_append_page): Add checks
+	to the entry points.
+	(gnome_property_box_set_state): New function, lets you unsensitize
+	the properybox.
+	(gnome_property_box_changed): Check input parameters.
+
+	API document GnomePropertyBox.
+
+	* gnome-icon-list.c: (gnome_icon_list_new_thawed); New method to
+	create an IconList which starts up life in thawed state.
+
+1998-11-28  Stuart Parmenter  <pavlov pavlov net>
+
+	* *.c
+	s/gtk_container_border_width/gtk_container_set_border_width/
+	s/gtk_window_position/gtk_window_set_position/
+	s/gtk_notebook_current_page/gtk_notebook_get_current_page/
+
+	* gnome-dialog.c:
+        make sure that we initialize the action_area if the buttons args are
+	null.  Martin: this isn't how you had just changed things, but this
+	breaks Balsa the way you have it.
+
+1998-11-28  Carsten Schaar  <nhadcasc fs-maphy uni-hannover de>
+
+	* gnome-client.c (client_set_value): New function.
+	(client_set_string): Renamed from 'client_set_prop_from_string'.
+	(client_set_gchar): Renamed from 'client_set_prop_from_gchar'.
+	(client_set_array): Renamed from 'client_set_prop_from_array'.
+	(client_set_array_with_arg): Renamed from
+ 	'client_set_prop_from_array_with_arg'.
+	(client_unset): Renamed from 'client_unset_prop'.
+	(client_set_ghash): New function.
+	(client_set_prop_from_glist): Removed.
+
+	* gnome-client.h (struct _GnomeClient): Changed int-typed boolean
+ 	members to gboolean.  Removed 'number_of_interact_requests' and
+ 	replaced it with 'interaction_keys'. Member 'number_of_...'
+  	renamed to 'save_yourself_emitted'. Made 'enviroment' of type
+ 	'GHashTable' instead of 'GList'.
+
+1998-11-26  Carsten Schaar  <nhadcasc fs-maphy uni-hannover de>
+
+	* gnome-client.c (interaction_key_find_by_tag): New function.
+  	Searchs a interaction key with a given tag.
+	(struct _InteractionKey): Renamed '_GnomeInteractData'.
+	(interaction_key_destroy): Renamed 'gnome_interaction_destroy'.
+	(interaction_key_destroy_if_possible): Renamed
+ 	'gnome_interact_remove'.
+	(interaction_key_new): New function.
+	(interaction_key_use): Renamed 'gnome_invoke_interact_function'.
+
+1998-11-28  Herbert Valerio Riedel  <hvr hvrlab ml org>
+
+	* gtkspell.c, gnome-color-picker.c: added #include <gtk/gtkcompat.h>
+	because of the recent renaming in gtk+
+
+1998-11-28  Dietmar Maurer  <dm vlsivie tuwien ac at>
+
+	* gtkpixmapmenuitem.[ch]: new widget for menu_items with pixmaps. See
+	  gtkpixmapmenuitem.h for a short description. Please can someone
+	  change gnome-app-helper to use this new widget (makes
+	  indent_missing_pixmaps obsolete)
+
+1998-11-27  Tom Tromey  <tromey cygnus com>
+
+	* gnome-app-helper.h (GNOMEUIINFO_ITEM): Fixed typo (inserted
+	newline after backslash).
+
+1998-11-27  Justin Maurer  <justin openprojects net>
+
+	* gnome-app-helper.c: Added GNOMEUIINFO_SUBTREE_ITEM_STOCK macro. Added
+	GNOMEUIINFO_SUBTREE_STOCK macro (currently broken). Cleaned up comments.
+
+1998-11-27  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-properties.[ch]: Scratched it. Please do not remove this
+	two files from CVS and the Makefile.am at the moment since I want
+	to add some functions here.
+
+1998-11-27  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-dialog.c (gnome_dialog_init): Don't create separator and
+ 	action area here so it won't be shown if the dialog contains no
+	buttons at all.
+ 	(gnome_dialog_init_action_area): New static function to create
+ 	separator and action area.
+	(gnome_dialog_append_button*): Call gnome_dialog_init_action_area.
+
+	* gnome-dialog.c (gnome_dialog_append_button_with_pixmap):
+	New function to add arbitrary button with a pixmap, if the
+	pixmap is NULL this is equivalent to gnome_dialog_append_button.
+	(gnome_dialog_append_buttons_with_pixmaps): New function to
+	add multiple buttons with pixmaps. This is basically what
+	gnome_dialog_append_buttonsv does for ordinary buttons.
+
+1998-11-27  bertrand  <Bertrand Guiheneuf inria fr>
+
+	* gnome-canvas-line.c (gnome_canvas_line_draw): use the new parameter
+	in item_to_canvas to know the actual number of points drawn.
+
+1998-11-27  bertrand  <Bertrand Guiheneuf inria fr>
+
+	* gnome-canvas-line.c (item_to_canvas): Don't draw twice the same point
+	speeds up a lot when line contains a lot of points and the zoom factor
+	is very small.
+
+Fri Nov 27 00:34:44 1998  George Lebl  <jirka 5z com>
+
+	* gnome-pixmap.c: check the visuals and if imlib and gdk visuals
+	  are the same, morph ourselves into a GTK_NO_WINDOW widget and
+	  work more like gtkpixmap
+
+	* gnome-stock.c: combine_mask only needs to be called if gnomepixmap
+	  is a window widget otherwise it spits out a warning
+
+1998-11-27  Jeff Garzik  <jgarzik pobox com>
+
+	* gnome-dialog-util: (gnome_question_dialog*, gnome_ok_cancel*):
+	NULL callbacks now supported.
+
+	* gnome-geometry.c:
+	Added API docs.
+
+	* gnome-calculator.c, gnome-client.c, gnome-dateedit.c,
+	gnome-entry.c, gnome-font-picker.c, gnome-font-selector.c,
+	gnome-geometry.c, gnome-init.c, gnome-mdi-session.c,
+	gnome-scores.c, gnome-stock.c, gtk-ted.c,
+	gtkdial.c, gtkspell.c, stock_demo.c, ted_demo.c,
+	winhints_demo.c:
+
+        Replaced sprintf calls with g_snprintf.
+        Updated a couple hardcoded length values to instead use sizeof().
+
+Thu Nov 26 21:20:10 1998  George Lebl  <jirka 5z com>
+
+	* gnome-pixmap-entry.c: added inline docs
+
+1998-11-26  James Henstridge  <james daa com au>
+
+	* gnometypes.c: added ability to register new boxed types.  This
+	is encapsulated in the function gnome_type_register_boxed, which
+	maybe should be moved to GTK.
+
+	* gnome-boxed.defs: added definitions of GdkImlibImage and
+	GnomeCanvasPoints, so type id's will be generated for them.
+
+	* gnome-canvas-image.c, gnome-canvas-line.c,
+	gnome-canvas-polygon.c, gnome-canvas-rect-ellipse.c,
+	gnome-canvas-text.c: changed occurences of GTK_TYPE_POINTER to
+	GTK_TYPE_GDK_IMLIB_IMAGE or GTK_TYPE_GNOME_CANVAS_POINTS where
+	appropriate.  Also changed the type for the stipples from
+	GTK_TYPE_BOXED to GTK_TYPE_GDK_WINDOW.
+
+	* gnome-font-picker.c: changed the argument to the font_set
+	signal from GTK_TYPE_POINTER to GTK_TYPE_STRING.
+
+	* gnome-icon-list.c: changed argument to (un)select_icon signals
+	from GTK_TYPE_POINTER to GTK_TYPE_GDK_EVENT.
+
+1998-11-26  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gtk-ted.c (gtk_ted_init): Buglette fix.
+
+Thu Nov 26 19:09:46 1998  George Lebl  <jirka 5z com>
+
+	* gnome-file-entry.c: add inline documentation
+
+1998-11-26  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-entry.c (show_icon_selection): Fixed spacing.
+
+	* gnome-file-entry.c (gnome_file_entry_get_full_path): Fixed spacing.
+
+1998-11-26  Jeff Garzik  <jgarzik pobox com>
+
+	* gnome-dialog-util.[ch]: new, more generic function
+	  gnome_request_dialog().
+
+	  This replaces the now-deprecated
+	  gnome_request_string_dialog(),
+	  gnome_request_string_dialog_parented(),
+	  gnome_request_password_dialog(), and
+	  gnome_request_password_dialog_parent().
+
+1998-11-26  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi-session.c: make it respect latest changes to GnomeMDI.
+
+1998-11-26  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi-generic-child.[ch]: new object to allow simple
+	use of GnomeMDI without subclassing GnomeMDIChild.
+	* gnome-mdi-child.h (struct _GnomeMDIChildClass): converted
+	signals to "virtual" functions. they made no sense as signals
+	since all of them return allocated memory.
+	(gnome_mdi_child_new): removed. GnomeMDIChild is now an abstract
+	class.
+	* gnome-mdi-child.c (gnome_mdi_child_new): removed
+	(gnome_mdi_child_class_init): removed all signals, simply
+	set proper default values for "virtual" function pointers instead.
+	* gnome-mdi.[ch]: converted create_menus and create_toolbar from
+	signals to ordinary function members of GnomeMDI: now you have
+	to set them with gnome_mdi_set_[tool|menu]bar_creator() functions
+	instead of connecting handlers with gtk_signal_connect(). this will
+	probably _BREAK_ each and every app using GnomeMDI. sorry! ;)
+	(gnome_mdi_set_menu_template): is now gnome_mdi_set_menubar_template()
+	* gnome-mdi.c (set_page_by_widget): check page != NULL instead of
+	page_num == -1. I know they should be the same, but this somehow
+	makes me more confident ;)
+
+Thu Nov 26 02:53:44 1998  George Lebl  <jirka 5z com>
+
+	* gnome-{file,icon,pixmap}-entry.c: use the new g_file_test
+	  function instead of custom ones, reduces codesize by 44 lines
+	  yay! :)
+
+Thu Nov 26 01:56:38 1998  George Lebl  <jirka 5z com>
+
+	* gnome-pixmap-entry.c: actually make preview work with the new
+	  scrolled window stuff by destroying the viewport not just the
+	  widget
+
+Thu Nov 26 01:13:51 1998  George Lebl  <jirka 5z com>
+
+	* gnome-icon-entry.c: use the browse_dialog_title of the file entry
+	  for the icon selection
+
+Thu Nov 26 00:43:48 1998  George Lebl  <jirka 5z com>
+
+	* gnome-dentry-edit.[ch]: now use icon_entry for the icon
+	  selection, also an important change is a slight api change
+	  for more consistency, _new doesn't take any argument, it will
+	  just create two pages for any kind of use, there is a function
+	  that acts like the onld _new, _new_notebook
+
+1998-11-25  Carsten Schaar  <nhadcasc fs-maphy uni-hannover de>
+
+	* gnome-client.[ch] (gnome_client_set_restart_style):
+	(gnome_real_client_connect):
+	(gnome_client_request_save):
+	(client_save_yourself_callback):
+	(gnome_client_request_interaction_internal):
+	(enum GnomeInteractStyle):
+	(enum GnomeDialogType):
+	(enum GnomeSaveStyle):
+	(enum GnomeRestartStyle): Removed the enum's dependence on XSM
+ 	definitions.  'gnome-client.h' does not depend on 'SMlib.h'
+ 	anymore.
+ 	(gnome_interaction_key_return): Changed int-typed boolean arg to
+ 	gboolean.
+
+	* gnome-client.h (struct _GnomeClient): Renamed member 'save_type'
+ 	in 'save_style'.
+
+1998-11-25  Raja R Harinath  <harinath cs umn edu>
+
+	* gnome-client.c (gnome_client_new_without_connection):
+	Use `gnome_app_id' to initialize client->program.
+
+1998-11-25  Havoc Pennington  <hp pobox com>
+
+	* gnome-dialog.c (gnome_dialog_run): Monitor destroy events, and
+	don't manipulate destroyed dialogs.
+	(gnome_dialog_run_and_destroy):	Deprecated.
+	(gnome_dialog_run_and_hide):    Deprecated.
+	(gnome_dialog_run_modal):       Deprecated.
+
+1998-11-25  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c: Removed unused function "dummy".
+
+1998-11-25  Dietmar Maurer  <dm vlsivie tuwien ac at>
+
+	* gnome-app-helper.c (gnome_app_configure_toolbar)
+	only replace [hv]separators, not all GTK_TOOLBAR_CHILD_WIDGETs!
+
+1998-11-25  James Henstridge  <james daa com au>
+
+	* gtkcauldron.h (constants): Altered the values of a few of the
+	constants (previously GTK_CAULDRON_SPACE15 & GTK_CAULDRON_IGNOREESCAPE
+	was non zero).
+
+1998-11-24  Carsten Schaar  <nhadcasc fs-maphy uni-hannover de>
+
+	* gnome-client.c (struct _GnomeInteraceData): Made 'in_use' and
+ 	'interp' of type 'gboolean'.
+
+1998-11-24  James Henstridge  <james daa com au>
+
+	* gnome-icon-item.c (iti_paint_text): Do not dereference null pointer.
+
+1998-11-24  Andrew T. Veliath  <andrewtv usa net>
+
+	* gnome-app.c (gnome_app_set_toolbar):
+	gnome-app-helper.c (gnome_app_fill_toolbar_custom): Listen to
+	toolbar labels setting.
+
+	* gnome-preferences.[ch] (prefs =): Add toolbar labels option,
+	default to use labels.
+
+	* gnome-app-helper.h: Add gnome_app_configure_toolbar public
+	prototype below gnome_app_fill_toolbar_custom.
+
+	* gnome-app-helper.c (gnome_app_fill_{menu,toolbar}_custom):
+	Configure any gnome app preferences which can be set here as well.
+
+	* gnome-app-helper.c (gnome_app_configure_toolbar):
+	gnome_app_configure_toolbar_separators from gnome-app.c moved to
+	public function here.  Useful for toolbars created with
+	gnome_app_fill_toolbar.
+	(create_toolbar_item): Listen to toolbar orientation for
+	separators at creation time.
+
+	* gnome-app.c (gnome_app_configure_positions): Call
+	gnome_app_configure_toolbar gnome-app-helper function instead of
+	gnome_app_configure_toolbar_separators.
+
+1998-11-24  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (gnome_canvas_destroy): Free the color context
+	when the canvas is destroyed.
+
+1998-11-24  Carsten Schaar  <nhadcasc fs-maphy uni-hannover de>
+
+	* gnome-client.c: Removed definition of
+ 	'gnome_client_new_default'.
+
+	* gnome-client.h: Removed declaration of
+ 	'gnome_client_new_default'.
+
+Tue Nov 24 01:56:28 1998  George Lebl  <jirka 5z com>
+
+	* gnome-icon-entry.[ch]: new files, new widget for handeling
+	  of picking an icon, basically somewhat like pixmap-entry,
+	  but uses a picker button similiar to what was in dentry-edit,
+	  but this will allow both typing of a filename in a file selection
+	  widget for those keyboard people like me or picking an icon
+	  out of a list
+
+	* Makefile.am,libgnomeui.h: update for the above
+
+1998-11-24  Carsten Schaar  <nhadcasc fs-maphy uni-hannover de>
+
+	* gnome-client.c (gnome_client_init): Changed error handling
+ 	slightly.  No aborts directly, if the master_client can't be
+ 	created.
+	(gnome_master_client): Removed assertion.
+	(client_parse_func): Changed error handling slightly.  If a
+ 	'--sm-client-id' and a '--sm-cloned-id' option is given, the
+ 	'cloned_id' is now always taken from the '--sm-cloned-id'.
+	(gnome_client_object_init): Free 'pwd' after using it.
+
+Mon Nov 23 23:55:41 1998  Owen Taylor  <otaylor redhat com>
+
+	* libgnomeui.h Makefile.am gtk{-plug,-socket,layout}.{c,h}
+	gnome-canvas.h:	Moved Plug/Socket and Layout widgets to GTK+.
+
+1998-11-23  Andrew T. Veliath  <andrewtv usa net>
+
+	* gnome-app.c (gnome_app_configure_toolbar_separators): Combined
+	version of the h/vseparator replacement code to be smaller.  Also
+	changed to work directly on a GtkToolbar to be more generic.
+
+1998-11-23  Jeff Garzik  <jgarzik pobox com>
+
+	* gnome-client.[ch]: (gnome_client_request_save):
+	  Changed int-typed boolean args to gbooleans.
+	* gnome-canvas.c, gnome-client.c: Added API doc stubs.
+	* gnome-calculator.[ch]: Changed gnome_calculator_clear() reset arg
+	  from a gint to a gboolean, reformatted a bit, and added const'ness.
+	  No gnome apps appear to depend on this function.
+
+	  Added API docs to gnome-calculator.
+
+1998-11-23  Havoc Pennington  <hp pobox com>
+
+	* gnome-appbar.c: Improve the docs a bit (mostly insignificant,
+	one mistake fixed).
+
+1998-11-23  Jeff Garzik  <jgarzik pobox com>
+
+	* gnome-animator.c, gnome-app.c, gnome-appbar.c: Documented.
+	* gnome-app-helper.c, gnome-app-util.c: added doc stubs, some docs.
+
+Mon Nov 23 02:19:09 PST 1998 Manish Singh <yosh gimp org>
+
+	* libgnomeui/gnome-font-selector.c
+	* libgnomeui/gnome-pixmap-entry.c
+	* libgnomeui/gtkcauldron.c
+	* libgnomeui/gtkspell.c
+	* libgnomeui/winhints_demo.c: use gtk_scrolled_window_add_with_viewport
+
+Mon Nov 23 01:25:26 PST 1998 Manish Singh <yosh gimp org>
+
+	* gnome-pixmap.c: remove reference to GTK_BASIC, it's gone now
+
+1998-11-22  Jay Painter <jpaint serv net>
+
+	* gnome-font-picker.c: fixed a dumb bug where the
+	gnome_font_picker_dialog_destroy would end up calling
+	g_free(gfp->preview_text), double-freeing the the memory
+	and killing the next call to malloc()
+
+1998-11-22  Andrew T. Veliath  <andrewtv usa net>
+
+	* gnome-app-helper.c (create_toolbar_item): Do not create line
+	separators if prefs has toolbar lines option off.
+
+	* gnome-preferences.[ch]: Add toolbar_flat and toolbar_lines
+	preferences.  Default is set to have non-flat toolbars and toolbar
+	lines.
+
+	* gnome-app.c (gnome_app_configure_toolbar_[hv]separators): Always
+	attempt separator reconfiguration, if possible.
+	(gnome_app_set_toolbar): Adjust for flat toolbar in prefs, and
+	adjust border width slightly larger in the original case of relief
+	overlapping buttons without relief where the handlebox seems
+	broken. Set space size to GNOME_PAD if we are not using toolbar
+	lines.
+
+Sun Nov 22 03:40:33 1998  George Lebl  <jirka 5z com>
+
+	* gnome-number-entry.c: when the dialog exists update the info,
+	  also made some cleanup here
+
+	* gnome-color-picker.c: when dialog exists update it to the current
+	  value
+
+	* gnome-file-entry.c: add directory browsing capability
+	  (set_directory)
+
+Sun Nov 22 02:41:12 1998  George Lebl  <jirka 5z com>
+
+	* gnome-font-picker.c: raise the window on click if one exists
+	  already, so that if it was obscured, the user doesn't get
+	  confused
+
+Sun Nov 22 01:11:26 1998  George Lebl  <jirka 5z com>
+
+	* gnome-pixmap-entry.[ch]: added a simple preview for the pixmaps
+	  to the file selection dialog
+
+	* gnome-file-entry.h: added comment about browse_clicked signal
+
+Sat Nov 21 22:57:15 1998  George Lebl  <jirka 5z com>
+
+	* gnome-calculator.c: don't reset the calculator on realize, just
+	  write the current number as it might have been already set, and
+	  check for realized before trying to write the font
+
+	* gnome-number-entry.[ch]: get rid of problems with multiple
+	  dialogs and non-modalness of the dialog as in the previous
+	  cases (only one dialog, destroy on entry destroy)
+
+Sat Nov 21 19:08:01 1998  George Lebl  <jirka 5z com>
+
+	* gnome-color-picker.c: catch destroy event on the dialog, don't
+	  start a new dialog when one was started already, kill a couple
+	  of redundunt functions (destroy_cs,cancel)
+
+1998-11-21  Andrew T. Veliath  <andrewtv usa net>
+
+	* gnome-app.c (gnome_app_configure_toolbar_hseparators): New
+	function; reconfigures vseparators to horizontal.
+	(gnome_app_configure_toolbar_vseparators): New function;
+	reconfigures hseparators to vseparators.
+	(gnome_app_configure_positions): Reconfigure toolbar separators to
+	given orientation. Changed separator length to GNOME_PAD * 2 (also
+	in gnome-app-helper.c: create_toolbar_item).  Ideally, this should
+	be calculated as a fraction of toolbar button_maxw/button_maxh.
+
+	* gnome-app-helper.c (gnome_app_create_menus_custom): Move menu
+	relief setting code to gnome_app.c (gnome_app_set_menus).
+	(gnome_app_create_toolbar_custom): Move space size setting to
+	gnome_app.c (gnome_app_set_toolbar) with change: if toolbar has
+	relieved buttons, use GNOME_PAD as space size, else use
+	GNOME_PAD_SMALL.
+	(create_toolbar_item): Use multiple of GNOME_PAD instead of
+	GNOME_PAD_BIG for separator height.
+
+	* gnome-preferences.c (gnome_preferences_load_custom): Toolbar
+	button relief default changed to "=false" to match
+	GnomePreferences structure default.
+
+	* gnome-app-helper.c (gnome_app_create_menus_custom): If menubar
+	relief is set to none, set menu bar shadow type to GTK_SHADOW_NONE.
+	(gnome_app_create_toolbar_custom): Remove the extra pad to toolbar
+	added previously, it's not needed now that handle box doesn't have a
+	relief in the case where it overlapped.
+
+	* gnome-preferences.c (prefs =): Add default for menubar_relief as
+	TRUE (i.e. unchanged behavior).  Add define for MENUBAR_RELIEF_KEY.
+	(gnome_preferences_load_custom): Load for menubar relief.
+	(gnome_preferences_save_custom): Save for menubar relief.
+	(gnome_preferences_{get,set}_menubar_relief): New functions.
+
+	* gnome-preferences.h: Add menubar_relief to GnomePreferences.
+	Add prototypes for gnome_preferences_{get,set}_menubar_relief.
+
+	* gnome-app.c (gnome_app_set_toolbar): If toolbar relief is set to
+	none and we are using a detachable toolbar, set handle box shadow
+	type to GTK_SHADOW_NONE.
+
+	* gnome-app-helper.c (create_toolbar_item): Insert a vseparator
+	with spaces if relief is set to none, rather than just a space.
+	(gnome_app_create_toolbar_custom): Set toolbar space size to
+	GNOME_PAD.  If relief is set to none, set border width of toolbar
+	to max (3, GNOME_PAD_SMALL / 2).
+
+Fri Nov 20 01:48:01 1998  George Lebl  <jirka 5z com>
+
+	* gnome-mdi.c: fix warnings about casting by using the G*_TO_*
+	  macros
+
+	* gnome-pixmap-entry.[ch]: add a get_filename function which
+	  returns a file only if it was able to load it as a pixmap with
+	  imlib. it also doesn't try to read directories as images anymore
+
+Fri Nov 20 00:21:45 1998  George Lebl  <jirka 5z com>
+
+	* gnome-segv.c: made button_click and delete_event static as to
+	  get rid of a warning
+
+	* gnome-file-entry.[ch]: added browse_clicked signal, which will
+	  be used in pixmap entry for modifying the file selection dialog,
+	  also made the set_default_path run the path through realpath
+	  to get rid of weird things in paths
+
+	* gnome-pixmap-entry.[ch]: a new widget that uses the file entry
+	  and can include a preview of the image that was picked, in the
+	  future it will have a file selection widget that is a lot like
+	  the electric eyes one
+
+1998-11-20  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-popup-help.c (popup_pre_callback): Now Cut and Copy are
+	disabled if there is no selection.
+
+1998-11-20  Evan Lawrence <evan worldpath net>
+
+	* gnome-app-helper.[ch]: Added a gnome_app_remove_menu_range
+	  function, that allows you to specify a path to a menu to remove,
+	  plus an offset from that menu to begin removing items at -
+	  useful for recent documents in the file menu, see gEdit for
+	  an example.
+
+Fri Nov 20 00:24:00 1998  Jeff Garzik  <jgarzik pobox com>
+
+	* gnome-icon-list.c: fixed doc string after CVS conflict
+	* gnome-about.c: added API docs
+
+	Beginning of libgnomeui doc landing.
+
+Thu Nov 19 20:37:10 1998  George Lebl  <jirka 5z com>
+
+	* gnome-file-entry.[ch]: added default paths and made modality
+	  optional, also added a utility function for getting the
+	  filename
+
+1998-11-19  Havoc Pennington <hp pobox com>
+
+	* gnome-appbar.h, gnome-appbar.c: Add a function to get at the
+	GtkProgress.
+	* gnome-preferences.c: Change dialog default to "center of
+	screen," this emulates KDE and is nicer anyway. Change toolbar
+	default to no button relief.
+
+1998-11-19  Jonathan Blandford  <jrb redhat com>
+
+	* gnome-popup-help.c (gnome_widget_add_help_with_uidata): we don't
+	actually want to not add help if we have no window, we just don't
+	wan't to subscribe to events.
+
+Wen Nov 18 1998  Tim Gerla   <timg means net>
+
+        * gnome-uidefs.h: Fixed another bug. :P
+
+Wed Nov 18 17:12:07 1998  Raph Levien  <raph gimp org>
+
+	* Makefile.am: added links to libart_lgpl
+	* gnome-canvas.c: minimal dependency on libart
+
+Wen Nov 18 04:57 PM 1998  Tim Gerla   <timg means net>
+
+        * gnome-uidefs.h: Fixed to really be GnomeUIInfo compatible.
+
+Wen Nov 18 03:26 PM 1998  Tim Gerla   <timg means net>
+
+        * gnome-uidefs.h: Added some keybindings.
+
+1998-11-18  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-rect-ellipse.c (set_stipple): Only do
+	gdk_gc_set_stipple if the stipple pixmap is not NULL.  Otherwise,
+	just use gdk_gc_set_fill() to set the fill mode to GDK_SOLID.
+
+	* gnome-canvas-line.c (set_stipple): Likewise.
+
+	* gnome-canvas-polygon.c (set_stipple): Likewise.
+
+	* gnome-canvas-text.c (set_stipple): Likewise.
+
+1998-11-18  Tuomas Kuosmanen  <tigert fun112 koivukyla hoas fi>
+
+	* gnome-stock.[c,h], stock_demo.c, pixmaps/stock_index.png
+	I updated the index stock-icon, and added stock icons for
+	alignment (left, right, center, justify) - (I thought I added
+	Changelog entries for these already!?) - index is meant for
+	the Help Browser for example, alignment stuff for
+	gnumeric and all editors/wordprocessors/whatever.
+
+1998-11-17  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c: got rid of all the DnD stuff and implemented my own
+	method for dragging notebook pages around. it works much better now
+	and doesn't confuse the children any more.
+	* gnome-mdi.h (struct _GnomeMDI): new mebers signal_id and in_drag
+	to serve the above changes ;).
+
+1998-11-16  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.c: Applied patch by Samuel Solon
+	<ssolon usa net> to make the icon list have hadjustment and
+	vadjustment object arguments, to act in the same way as GtkCList.
+	You now have to insert the GnomeIconList inside a
+	GtkScrolledWindow.
+
+Sat Nov 14 14:55:48 1998  John Ellis  <johne bellatlantic net>
+
+	* gone-icon-sel.c(gnome_icon_selection_init): Add scrolled window
+	for the clist of icons.
+
+Fri Nov 13 11:29:22 1998  Owen Taylor  <otaylor redhat com>
+
+	* gnome-rootwin.c: Include gdkx.h not gdkprivate.h
+
+1998-11-11  Havoc Pennington  <hp pobox com>
+
+	* gnome-geometry.c (gnome_geometry_string): Use
+	gdk_window_get_root_origin().
+
+1998-11-10  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-popup-menu.c (popup_connect_func): Only connect to the
+	signal if the callback is not NULL.
+	(gnome_popup_menu_do_popup): If the event is NULL, use button 0
+	and GDK_CURRENT_TIME to pop up the menu.
+	(gnome_popup_menu_do_popup_modal): New public function to run a
+	popup menu modally, and return the index of the selected item.
+
+	* gnome-app-helper.c (do_ui_signal_connect): Only connect to the
+	signal if the callback is not NULL.
+
+Wed Nov  4 11:31:57 1998  Owen Taylor  <otaylor redhat com>
+
+	* gtk-socket.c (gtk_socket_filter_func): Call
+	gdk_window_destroy_notify() on a DestroyNotify, so
+	that the window gets removed from the XID table.
+
+1998-11-09  Jeff Garzik  <jgarzik pobox com>
+
+        * libgnomeui/Makefile.am,
+          libgnomeui/gnome-dateedit.c, libgnomeui/gtkcalendar.c,
+          libgnomeui/gtkcalendar.h, libgnomeui/libgnomeui.h:
+
+                Removed gtkcalendar module.
+
+1998-11-09  Jonathan Blandford  <jrb aware-of-vacuity labs redhat com>
+
+	* gnome-popup-help.c (gnome_popup_help_expose): added theme'd
+	drawing code back to the popup-window.
+
+1998-11-08  Havoc Pennington  <hp pobox com>
+
+	* gnome-canvas.c (gnome_canvas_group_draw):
+	In determining whether to redraw each child, the group was
+	comparing its own bounds to the redraw area on each iteration,
+	ignoring the child's bounds. So all children were redrawn in every
+	case. Fixed this typo from hell after staying up all night trying
+	to figure out why my app was so slow.
+
+1998-11-07  Jeff Garzik  <jgarzik pobox com>
+
+	* Makefile.am, libgnomeui.h: removed gnome-lamp.[ch]
+	* stock_demo.c: removed ifdef'd gnome_lamp widget code
+	* winhints_demo.c: made authors var const-correct
+	* gnome-lamp.[ch]: removed (general consensus considers
+	  gnome-lamp unused and ugly)
+
+1998-11-05  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-item.[ch] (gnome_icon_text_item_get_text): New public
+	function to query the text from the icon item.
+
+	* gnome-icon-list.c (text_changed): Use gnome_icon_text_item_get_text().
+
+1998-11-05  Chris Lahey  <clahey umich edu>
+
+	* pixmaps/Makefile.am (stock_images):
+	* gnome-stock.c:
+	* gnome-stock.h: Added GNOME_STOCK_PIXMAP_INDEX, a small pile of
+	documents.
+
+	* pixmaps/stock_index.png: Added this file.  The image for
+	GNOME_STOCK_PIXMAP_INDEX.
+
+	* gnome-app.c (gnome_app_set_toolbar): Removed an incorrect #ifdef
+	to get flat toolbars to work.
+
+1998-11-05  Felix Bellaby <felix pooh u-net com>
+
+	* gnome-client.c (options): Added CBFLAGS to make connection to
+	master_client.
+
+1998-11-04  Raja R Harinath  <harinath cs umn edu>
+
+	* gnome-net.c (make_inetaddr): Use memset/memcpy rather than
+	bzero/bcopy.
+	(gnomesupport.h): Include.
+	(max_sockets): Specify `int' type.
+
+1998-11-01  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gtkcauldron.c: Make private functions static.
+
+1998-11-04  Havoc Pennington  <hp pobox com>
+
+	* gnome-guru.c, gnome-guru.h: New widget, a simple-minded wizard
+	widget.
+	* gtkrc: Add a style for the title of each page in the GnomeGuru.
+	It only works with the standalone guru though, not the
+	guru-in-a-dialog. See test-gnome for demo. weird.
+	* libgnomeui.h, Makefile.am: added.
+	* gnome-icon-sel.c: The type of parent_class was wrong.
+
+1998-11-04  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-item.h (GnomeIconTextItemClass): Added an
+	"editing_started" signal, too.
+
+	* gnome-icon-item.c (iti_class_init): Create the new signal.
+	(iti_start_editing): Emit the editing_started signal.
+
+	* gnome-icon-item.h (GnomeIconTextItemClass): Added an
+	"editing_stopped" signal.  It is emitted when the user presses
+	enter or esc and thus finishes editing the item.
+
+	* gnome-icon-item.c (iti_class_init): Create the new signal.
+	(iti_stop_editing): Emit the editing_stoppled signal.
+
+1998-11-03  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c: Updates to the TO-DO list.
+
+1998-11-03  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi-child.[ch] (gnome_mdi_active_window): return active_window
+	member.
+
+1998-11-02  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi-child.[ch]: added "set_book_label" signal, giving the user
+	some control over the notebook labels. see source and header for some
+	comments on the handler.
+	* gnome-mdi.c (book_add_view, gnome_mdi_update_child): emit
+	"set_book_label" signal to obtain or update the notebook label.
+
+1998-11-01  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	Wheee!  Now we have stippling capabilities in the canvas.
+
+	* gnome-canvas.h (GnomeCanvas): Added fields for the offsets of
+	the temporary drawing pixmap.  This is needed by
+	gnome_canvas_set_stipple_origin().
+
+	* gnome-canvas.[ch] (gnome_canvas_set_stipple_origin): New public
+	function to set the stipple origin of an item's gc.  For use only
+	by item implementations.
+
+	* gnome-canvas.c (paint): Set the draw_xofs and draw_yofs fields
+	of the canvas.
+
+	* gnome-canvas-rect-ellipse.h (GnomeCanvasRE): Added fields for
+	the fill and outline stipple patterns.
+
+	* gnome-canvas-rect-ellipse.c (gnome_canvas_re_class_init): Added
+	the arguments for stippling.
+	(set_stipple): New convenience function to set the stipple pattern
+	of a gc.
+	(gnome_canvas_re_set_arg): Set the fill/outline stipple arguments.
+	(gnome_canvas_re_get_arg): Query the fill/outline stipple
+	arguments.
+	(gnome_canvas_re_reconfigure): Reset the stipples.
+	(gnome_canvas_rect_draw): Set the origin of the stipple patterns
+	as appropriate.
+	(gnome_canvas_ellipse_draw): Likewise.
+	(gnome_canvas_re_destroy): Unref the stipple bitmaps.
+
+	* gnome-canvas-text.h (GnomeCanvasText): Added a stipple field.
+
+	* gnome-canvas-text.c (gnome_canvas_text_class_init): Register the
+	fill_stipple argument.
+	(gnome_canvas_text_destroy): Unref the stipple bitmap.
+	(set_stipple): New convenience function to set the stipple pattern.
+	(gnome_canvas_text_set_arg): Set the fill_stipple argument.
+	(gnome_canvas_text_get_arg): Query the fill_stipple argument.
+	(gnome_canvas_text_draw): Set the stipple origin as appropriate.
+
+	* gnome-canvas-line.h (GnomeCanvasLine): Added a stipple field.
+	Also, removed the arrow_gc field, since it was never used for
+	drawing.
+
+	* gnome-canvas-line.c (gnome_canvas_line_class_init): Add the
+	fill_stipple argument.
+	(gnome_canvas_line_destroy): Unref the stipple if it exists.
+	(set_stipple): New function to set the stipple pattern on the
+	line's gcs.
+	(gnome_canvas_line_set_arg): Set the stipple argument.
+	(gnome_canvas_line_get_arg): Query the stipple argument.
+	(gnome_canvas_line_draw): Set the stipple origin as appropriate.
+
+	* gnome-canvas-polygon.h (GnomeCanvasPolygon): Added fields for
+	fill and outline stipples.
+
+	* gnome-canvas-polygon.c (gnome_canvas_polygon_class_init): Added
+	the arguments for stippling.
+	(set_stipple): New convenience function to set the stipple pattern
+	of a gc.
+	(gnome_canvas_polygon_set_arg): Set the fill/outline stipple arguments.
+	(gnome_canvas_polygon_get_arg): Query the fill/outline stipple
+	arguments.
+	(gnome_canvas_polygon_reconfigure): Reset the stipples.
+	(gnome_canvas_polygon_draw): Set the origin of the stipple patterns
+	as appropriate.
+	(gnome_canvas_polygon_destroy): Unref the stipple bitmaps.
+
+1998-10-30  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-app-helper.c (create_radio_menu_items): Now returns the
+	updated `pos' parameter, since the functions that call it need it.
+	(create_help_entries): Likewise.
+	(gnome_app_fill_menu_custom): Update the position from
+	create_help_entries() and create_radio_menu_items().
+
+1998-10-29  Seth Alves  <alves hungry com>
+
+	* gnome-paper-selector.c (set_widgets_from_paper): pulled common
+	code into a subroutine
+	(gnome_paper_selector_init): added widgets for margin sizes
+
+1998-10-29    <jrb redhat com>
+
+	* gnome-popup-help.c (gnome_widget_add_help_with_uidata): added some more
+	sanity checking.
+	(gnome_popup_help_place_window): removed print statements too
+
+1998-10-29  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-popup-menu.c (gnome_popup_menu_attach): Use
+	gtk_widget_add_events() instead of set_events() -- this lets us
+	operate even on realized widgets.
+
+1998-10-29    <jrb aware-of-vacuity labs redhat com>
+
+	* gtk-socket.c: Remove #define DEBUG_PLUGSOCKET
+
+1998-10-28  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-app-helper.c (create_menu_item): i8l_label must be a
+	string, not a GtkWidget *.
+
+	* gnome-about.c (gnome_about_calc_size): Made static.
+	(gnome_destroy_about): Likewise.
+
+	* gnome-app.c (locations): Made const.
+
+	* gnome-mdi.c (target_table): Made const.
+
+	* gnome-client.c (arguments parser): Made const.
+
+	* gnome-init.c (our_gtk_options our_gtk_parser): Made const.
+
+	* makeenums.pl (parse_entries): Output the arrays of enumerations
+	as const.
+
+	* gnome-calculator.c (buttons): Made the buttons array const so
+	that it can be shared.
+
+	* gnome-lamp.c: Made the lamp data and enl_mappings const so that
+	they can be shared.
+
+	* gnome-stock.c (entries_data default_accel_hash): Made the list
+	of entries const so that it can be shared between processes.
+
+1998-10-28  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.[ch] (gnome_mdi_register, gnome_mdi_unregister):
+	changed parameter from GtkWidget*  to GtkObject*.
+
+1998-10-27  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-item.c (get_bounds): New internal function to compute
+	the bounding box of the icon text item.
+	(recompute_bounding_box): Use get_bounds().
+	(gnome_icon_text_item_get_type): The object initialization
+	function did nothing, so removed it and use NULL instead.
+	(iti_bounds): Use get_bounds() and return the correct bounds.
+
+1998-10-27  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-item.c (iti_bounds): Realize the item if we are asked
+	for the bounds before realization.  Federico, this fixes the
+	problem you had without having to connect to the realize signal
+	(which should be very expensive in terms of memory use for every
+	icon).
+
+	(iti_realize): Remove unused Window
+	parameter.
+
+Mon Oct 26 16:53:04 1998  Owen Taylor  <otaylor redhat com>
+
+	* gnome-stock.c: Use gtk_widget_shape_combine_mask() instead
+	of gdk_window_", so theme switching doesn't remove
+	shape.
+
+1998-10-25  Kjartan Maraas  <kmaraas fib hl no>
+
+	* gnome-font-picker.c: Removed #include "gnome-font-picker-ico.h"
+	to make it compile again
+
+1998-10-24  David Abilleira  <odaf nexo es>
+
+	* gnome-font-picker.c: Now it uses GNOME_STOCK_PIXMAP_FONT instead of
+        the one in gnome-font-picer-ico.png
+
+	* gnome-font-picker-ico.png: Removed
+	* gnome-font-picker-ico.h: Removed
+
+1998-10-24  Martin Baulig  <martin home-of-linux org>
+
+	* pixmaps/Makefile.am: Make `gnome-stock-imlib.h' depend upon
+	the Makefile.am so it will be rebuild if you add new files.
+
+Sat Oct 24 13:09:50 CEST 1998  Eckehard Berns  <eb berns i-s-o net>
+
+	* pixmaps/stock_font.png: new stock icon
+	* pixmaps/Makefile.am: added stock_font.png
+	* gnome-stock.[ch]: added defines for stock_font.png (icon, menu and
+	button)
+	* stock_demo.c: added sample stock_font icons and button
+
+1998-10-23  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-list.c (icon_event): Mark the events as processed
+	when calling toggle_icon.
+
+1998-10-22  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-list.c (icon_event): Fixed the handling of clicking.
+
+1998-10-23  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-item.c (iti_get_width): Handle the case where iti->ti
+	has not been created yet.
+	(recompute_bounding_box): Likewise.
+
+1998-10-22  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-popup-help.c (gnome_popup_help_size_window): Use
+	"traditional" drawing functions until Gtk-themes is all over the
+	place.
+
+Mon Oct 19 19:33:18 1998  Owen Taylor  <otaylor redhat com>
+
+	* gtk-socket.c (gtk_window_remove_embedded_xid): Added
+	some code for marking embedded windows so theme
+	switching can work properly. As soon as themes
+	are merged, this will be moved to GTK+.
+
+1998-10-22  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-item.c (recompute_bounding_box): Use item relative
+	cordinates, to support groups.
+	(iti_paint_text): Same.
+
+1998-10-21    <jrb redhat com>
+
+	* gnome-popup-help.c: Added popup help.  Everyone should use
+	this.
+
+	* libgnomeui.h: added the popup stuff.
+
+	* Makefile.am: added the popup-help stuff.
+
+1998-10-21  David Abilleira  <odaf nexo es>
+
+	* gnome-font-picker.h: removed "extern C" which is redundant with
+        BEGIN_GNOME_DCLS
+
+        * gnome-color-selector.c: Now it creates a modal dialog box only when
+        there is another modal window yet.
+
+1998-10-20  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-item.c: Add width_changed signal to icon-text-item.
+
+	* gnome-icon-list.c: (toggle_icon): Make sure we emit a signal
+	with the correct index.
+	(icon_event): Generate events for button-2 and 3
+
+	* gnome-icon-list.c (gnome_icon_list_icon_is_visible): Fix wrong
+	return value.
+
+1998-10-19  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-list.c (icon_event): call toggle_icon on double click
+	events.
+
+1998-10-15  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-list.c (gnome_icon_list_new): Fix merge  mistake.
+
+1998-10-19  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c: I am an idiot.  I did not think anyone would
+	ever override the canvas event handlers, so I was happily
+	returning FALSE from all of them.
+	(gnome_canvas_button): Return the appropriate value from
+	emit_event().
+	(gnome_canvas_motion): Likewise.
+	(gnome_canvas_key): Likewise.
+	(gnome_canvas_focus_in): Likewise.
+	(gnome_canvas_focus_out): Likewise.
+	(gnome_canvas_crossing): Return the appropriate value from
+	pick_current_item().
+
+	(emit_event): Now it returns a boolean value that indicates
+	whether the event was handled by someone or not.
+	(pick_current_item): Likewise.
+
+1998-10-19  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c (book_drop): something seems to have been screwed
+	up during owen's last commit. fixed now.
+
+1998-10-18  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (gnome_canvas_init): Set the GTK_CAN_FOCUS flag
+	in the widget.
+
+	* gnome-color-picker.c (gnome_color_picker_set_title): Set the
+	title of the color selection dialog if it exists.
+
+	* gnome-init.c (our_gtk_options): Fixed spelling in the option
+	descriptions.
+
+	* gnome-canvas.c (gnome_canvas_item_grab_focus): Set the
+	ev.focus_change.window field to the canvas's bin window.
+	(emit_event): Rearranged some of the focusing tests.
+
+Mon Oct 19 11:57:51 1998  Owen Taylor  <otaylor redhat com>
+
+	* gnome-mdi.c: Change "drag_data_received" callback
+	to have proper signature.
+
+1998-10-19  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.[ch]: removed dnd_type member and g_free()ing
+	of it, since owen's changes made it redundant.
+
+Sun Oct 18 18:59:33 1998  Owen Taylor  <otaylor gtk org>
+
+	* gnome-mdi.[ch] gnome-color-selector.c gnome-file-entry.c:
+	Adapted to the new GTK+ DND API.
+
+	* gnome-stock.[ch]: Added new function
+	gnome_stock-pixmap_gdk() to get a stock pixmap as
+	a GdkPixmap/GdkMask.
+
+	* gtk-socket.[ch]: Changes to enable DND proxying to
+	the embedded plug.
+
+1998-10-17  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-stock.c: Removed `BUTTON_DEFBRD_WIDTH' and
+	`BUTTON_DEFBRD_HEIGHT' constants.
+
+	* gnome-uidefs.h: Removed `GNOME_BUTTON_WIDTH' and
+ 	`GNOME_BUTTON_HEIGHT' constants.  These are not used by any
+ 	application AFAIK.
+
+	* gnome-stock.c (gnome_pixmap_button): Do not force the button
+ 	size anymore.
+
+	* gnome-dialog.c (gnome_dialog_append_button): Use
+ 	`GTK_WIDGET_SET_FLAGS()' instead of `gnome_button_can_default()'
+	to set the `GTK_CAN_DEFAULT' flag.
+
+	* gnome-stock.c (gnome_button_can_default): Do nothing.  Just spit
+	out a warning, saying that this function is now deprecated.
+
+1998-10-16    <jrb aware-of-vacuity labs redhat com>
+
+	* gnome-messagebox.h: changed comment to redirect user to the
+	right code.
+
+1998-10-16  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (emit_event): Emit events for hidden items as
+	well -- they need to get a LeaveNotify, at least.
+
+1998-10-16  Havoc Pennington  <hp pobox com>
+
+	* gnome-icon-list.c (gil_button_press): If there's already a
+	gil->sel_rect (i.e. we are already rubberbanding) don't create a
+	second rubberband if the user clicks one of the other mouse
+	buttons. Clicking another button now ends the select due to the
+	button release event.
+
+1998-10-15  Mark Galassi  <rosalia cygnus com>
+
+	* Makefile.am (gnome_headers): fixed a typo: a \ was missing after
+	gnome-font-picker.h, thus causing several
+	$(prefix)/include/libgnomeui/*.h files to not be installed.
+
+1998-10-15  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (gnome_canvas_item_hide):
+	(gnome_canvas_item_show): The canvas needs to repick the current
+	item when an item is shown/hidden.
+
+1998-10-15  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-list.c (gnome_icon_list_new): Thanks to Havoc for
+	spotting this one-line bug.  I was leaking an icon-list and
+	returning an incorrectly created icon list widget.
+
+Thu Oct 15 03:33:21 CEST 1998  Eckehard Berns  <eb berns i-s-o net>
+
+	* pixmaps/Makefile.am pixmaps/stock_attach.png: added attach pixmap.
+	* gnome-stock.[ch]: added defines for attach pixmap.
+	* stock_demo.c: added sample attach pixmap.
+
+1998-10-14  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (gnome_canvas_item_show):
+	(gnome_canvas_item_hide): New public functions to hide/show items
+	in the canvas.  We have a new visibility flag for canvas items.
+	(gnome_canvas_item_init): New private initialization function --
+	makes items start as visible by default.
+	(redraw_if_visible): New convenience function to queue a redraw of
+	an item only if it is visible.  It is used in the places that used
+	to always queue a redraw.
+	(gnome_canvas_item_grab): Return GrabNotViewable if the item is
+	not visible.
+	(gnome_canvas_group_draw): Only draw visible items.
+	(gnome_canvas_group_point): Test only visible children.
+	(gnome_canvas_group_bounds): Only test visible children.
+	(pick_current_item): Only pick if the root is visible.
+	(emit_event): Only emit if the item is visible.
+	(paint): Only draw the root if it is visible.
+
+1998-10-14  Havoc Pennington  <hp pobox com>
+
+	* gnome-icon-list.h: BEGIN_GNOME_DECLS, END_GNOME_DECLS so C++
+	programs will link.
+
+1998-10-14  David Abilleira  <odaf nexo es>
+
+	* gnome-font-picker.[ch] New widget for selecting a font from a
+	simple to use button. This is equivalent to gnome-color-picker but to
+	select fonts.
+
+	* gnome-font-picker-ico.png and .h. Default ico to show inside
+	the button. At this moment header file generation is not
+	automated because I don't want to modify Makefile.am until I
+	know which is the right place to put the icon
+
+	* libgnomeui.h: Added gnome-font-picker.h to the list of headers.
+
+	* Makefile.am: Added gnome-font-picker.[ch] to the sources.
+
+1998-10-14  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-polygon.[ch]: New polygon item for the canvas.  I
+	need it for Gnomecal, so I finally got around to implementing this.
+
+	* gnome-canvas.c: Update the TODO list; we now have a polygon item.
+
+	* libgnomeui.h: Added gnome-canvas-polygon.h to the list of headers.
+
+	* Makefile.am: Added gnome-canvas-polygon.[ch] to the list of sources.
+
+1998-10-14  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-item.c (gnome_icon_text_item_select): When we are
+	unselected, cancel any pending editing facility on the item.
+
+1998-10-13  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	(gnome_icon_list_icon_is_visible):  Small name function name
+	change, for compatibility with the older code.  Somehow it got
+	dropped.
+
+	* gnome-icon-list.c (gnome_icon_list_get_items_per_line): Export
+	this routine.
+
+	* gnome-icon-item.c (iti_unrealize): Only call iti_stop_editing if
+	an editing was in course.
+	(iti_realize): account for the fact that we can be realized before
+	being configured (ie, the canvas is already visible).
+	(gnome_icon_text_item_configure): If the item has been realized do
+	the icon computations.
+
+	* gnome-icon-list.c (gnome_icon_list_set_separators): Implemented
+	missing routine.
+
+	(gnome_icon_list_new): As we depend on Imlib for drawing icons,
+	always use the Imlib visual.
+
+1998-10-13  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-line.c (gnome_canvas_line_init): Now by default
+	lines start in width_pixels mode turned off, to be consistent with
+	rectangles and ellipses.
+
+1998-10-13  Havoc Pennington  <hp pobox com>
+
+	* gnome-canvas.h, gnome-canvas.c (gnome_canvas_world_to_window):
+	New function, inverse of gnome_canvas_window_to_world.
+
+1998-10-13  Havoc Pennington  <hp pobox com>
+
+	* gnome-icon-list.h, gnome-icon-list.c: Add
+	gnome_icon_list_construct function, and use it in _new.
+
+1998-10-13  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c (gnome_mdi_open_toplevel): restrict MDI
+	to a single toplevel when in modal mode.
+	* gnome-mdi.[ch] (gnome_mdi_set_window_view): removed:
+	gnome_mdi_set_active_view does precisely that and even more!
+	* gnome-mdi-session.c (gnome_mdi_restore_state): replaced
+	gnome_mdi_set_window_view() with gnome_mdi_set_active_view()
+	and removed a hash table lookup for the app since mdi retrieves
+	it from the view.
+
+1998-10-13  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-app-helper.c (create_menu_item): When the label is the
+	empty string, don't call gettext on it. This is required since
+	gettext maps the empty string to the header lines at the beginning
+ 	of the .pot files.
+
+1998-10-12  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-list.c, gnome-icon-list.h: New implementations of the
+	GnomeIconList.  This GnomeIconList is derived from the GnomeCanvas
+	and has some nice features:  inline name edition of filenames and
+	banding selection of icons as well as a flicker free display.
+
+	The icon list API is fully documented with the proposed commenting
+	style.
+
+	The downside is that the constructor API has changed, I will
+	shortly fix the code on CVS to work with the new API.
+
+	* gnome-icon-item.c, gnome-icon-item.h: New files.  Canvas items
+	that implement text editing in a width-constrained region.  They
+	use a GtkEntry as a hidden backend to handle most of the nasty
+	details of input editing.  This means the edition features of them
+	are very complete.
+
+	* gnome-icon-text.c, gnome-icon-text.h:  Routines used to layout
+	wrapped text for tooltips and icons is now on their own file.
+	Fully documented as well.
+
+1998-10-12  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (gnome_canvas_window_to_world): New public
+	function that takes in window coordinates (relative to the
+	GTK_LAYOUT (canvas)->bin_window) and converts them to world
+	coordinates.  This is what everyone needs :-)
+	(emit_event): Made it use gnome_canvas_window_to_world().
+
+1998-10-12  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.h: remove GNOME_MDI_MS from GnomeMDIMode enums.
+	(gnome_mdi_open_toplevel): new function.
+	* gnome-mdi.c: removed all conditional code depending on
+	GNOME_MDI_MS.
+	(gnome_mdi_open_toplevel): new function.
+	(gnome_mdi_init): set initial mode to the one selected in
+	look and feel properties.
+	(gnome_mdi_set_mode): fix to accomodate the previous change.
+	(gnome_mdi_add_view, gnome_mdi_add_toplevel_view): fixed to
+	open a new toplevel if there isn't one.
+
+1998-10-09  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-text.c (gnome_canvas_text_draw): Fixed stupid bug,
+	do not try to draw empty lines.
+
+	* gnome-canvas-text.c (gnome_canvas_text_bounds): Fixed a little
+	y1->x1 confusion.
+
+1998-10-08  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-mdi-session.h: Fixup includes.
+
+	* gnome-mdi-session.c: Fixup includes.
+
+1998-10-08  Raja R Harinath  <harinath cs umn edu>
+
+	* gtkcauldron.h: Remove `#pragma }'.
+
+1998-10-08  The Rasterman <raster redhat com>
+	* gnome-winhints.[ch]: moved to standard method of #defines in gtk+
+	and gnome by using enum's and all capitals. added extra support.
+	Cleaned up code. aded "check for a gnome compliant wm" code and
+	put this all into winhints_demo.c - currently onle E 0.15 in CVS
+	supports all of this. I hope other WM's will catch on soon.
+
+1998-10-08  James Henstridge  <james daa com au>
+
+	* gnome-href.[ch]:  Added a simple widget for embedding hyperlinks
+	into a GUI.  This uses my gnome-url code in libgnome.
+	* gtkrc:  Added some lines to make href text blue.
+
+1998-10-05  Raja R Harinath  <harinath cs umn edu>
+
+	Changes to parallel `gtk+'.
+	* Makefile.am (libgnomeuiinclude_HEADERS): Move non-generated
+	headers ...
+	(gnome_headers): ... here.
+	(gnome.defs): Depend on $(gnome_headers).
+	(auto-files, auto-files-1): Remove rules.
+	(BUILT_SOURCES): List generated files.
+
+1998-10-04  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-line.h: Added a comment for the line_style argument.
+
+	* gnome-canvas-line.c (gnome_canvas_line_set_arg): Actually set
+	the line_style.
+
+1998-10-04  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-canvas.c (emit_event): Small bug fix:  do not reinitialize
+	the item to be used.
+
+Sat Oct  3 23:46:51 EDT 1998 Gregory McLean <gregm comstar net>
+
+	* gnome-canvas.c (gnome_canvas_item_get_bounds):
+	Fixed a whoops in here that was causeing crashes
+	GNOME_CANVAS_ITEM_CLASS (item)->bounds should actually be
+	GNOME_CANVAS_ITEM_CLASS (item->object.klass)->bounds (though
+	yosh says it really should be (item)->klass) :)
+
+	* gnome-canvas-line.h (GnomeCanvasLine): I found myself needing
+	to have some dashed lines as items, it looked like a fairly trival
+	change so I added a GdkLineStyle member to GnomeCanvasLine.
+
+	* gnome-canvas-line.c: Added a line_style arg for drawing dashed
+	lines (gdk can do it so all we are doing is using that functionality)
+	Nothing looks like it broke.
+
+1998-10-03  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (gnome_canvas_item_get_bounds): New public
+	function used to query an item for its bounding box.
+	(gnome_canvas_group_bounds): New function that iterates over all
+	the children in the group and adds up their bounds.
+
+	* gnome-canvas.h (GnomeCanvasItem): Added a "bounds" method used
+	to query the item for its bounding box.
+
+	* gnome-canvas-rect-ellipse.c (gnome_canvas_re_bounds): New
+	function that implements the "bounds" method for rectangle and
+	ellipse items.
+
+	* gnome-canvas-image.c (gnome_canvas_image_bounds): New function
+	that implements the "bounds" method for image items.
+
+	* gnome-canvas-text.c (gnome_canvas_text_bounds): New function
+	that implements the "bounds" method for text items.
+
+	* gnome-canvas-line.c (get_bounds): Moved most of the stuff in
+	recalc_bounds() to this function.  This function only calculates
+	the line's bounds in world coordinates.
+	(recalc_bounds): Use the get_bounds() function.
+	(gnome_canvas_line_bounds): New function that implements the
+	"bounds" method for line items.
+
+	* gnome-canvas-widget.c (gnome_canvas_widget_bounds): New function
+	that implements the "bounds" method for widget items.
+
+1998-10-03  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-client.c (gnome_client_get_config_prefix): Use
+	`program_invocation_short_name' if `client->program' is NULL.
+
+1998-10-02  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gtklayout.c (gtk_layout_move): Provide a default value.
+
+	* gnome-canvas.c (gnome_canvas_realize): Added
+	GDK_FOCUS_CHANGE_MASK to the events the canvas gets.
+	(gnome_canvas_item_shutdown): clear the focus is the killed item
+	had it.
+	(gnome_canvas_focus_in, gnome_canvas_focus_out,
+	gnome_canvas_item_grab_focus): New functions to implement focus in
+	a canvas.
+
+	* gnome-canvas.h: Add new flag.  GNOME_CANVAS_ITEM_CAN_FOCUS.
+	GnomeCanvas: New field:  focused_item.
+
+Fri Oct  2 09:21:47 CEST 1998  Eckehard Berns  <eb berns i-s-o net>
+
+	* gnome-stock.c (create_pixmap_from_imlib_scaled): free the scaled_down
+	data.
+
+1998-10-01  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gtklayout.c (gtk_layout_gravity_works): Destroy the windows
+	created for the test.
+	(gtk_layout_gravity_works): Initialize event mask
+
+1998-09-30  Havoc Pennington  <hp pobox com>
+
+	* gnome-color-picker.h, gnome-color-picker.c: Type fix-fest for
+	the benefit of C++.
+	(struct _GnomeColorPicker): Store stuff as gdouble.
+	(struct _GnomeColorPickerClass): color_set emits a guint;
+	should be gushort, but there is no GTK_VALUE_USHORT for some
+	reason.
+	(gnome_color_picker_set_i8, gnome_color_picker_get_i8): Use
+	guint8; remove range checking.
+	(gnome_color_picker_set_i16, gnome_color_picker_set_i16): Use
+	gushort; remove range checking (FIXME may need to check range on
+	some platforms? Gives a warning on Intel if check.)
+	(gnome_color_picker_get_d, gnome_color_picker_set_d): Use gdouble.
+	(gnome_color_picker_set_dither, gnome_color_picker_user_alpha):
+	Use gboolean.
+	(gnome_color_picker_set_title): const on the char*
+	(gnome_color_picker_class_init): color_set args are guint.
+	(cs_ok_clicked): Use gushort and gdouble.
+	(gnome_color_picker_clicked): gdouble
+	(gnome_color_picker_marshal_signal_1): GTK_VALUE_UINT
+
+Wed Sep 30 17:09:01 1998  John Ellis  <johne bellatlantic net>
+
+	* pixmaps/stock_up_arrow.png, stock_down_arrow.png, stock_top.png,
+	stock_bottom.png, stock_exec.png: New stock images.
+	* pixmaps/Makefile.am: Added above files.
+	* gnome-stock.[ch]: Added references to above images.
+
+1998-09-30  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-animator.c: Turned `GnomeAnimator' into a windowless
+ 	widget.
+	(struct _GnomeAnimatorPrivate): New field `area'.
+	(realize): Removed function.
+	(state_or_style_changed): New function.
+	(style_set): New function.
+	(state_changed): New function.
+	(init): Set the `GTK_NO_WINDOW' widget flag.  Do not handle
+ 	parent's signals anymore; install `style_set()' and
+ 	`state_changed()' in the widget class description instead.
+	(draw_background_pixmap): Use the new `area' field in
+ 	`GnomeAnimatorPrivate' to set the tile/stipple origin.
+	(size_allocate): Clear the parent widget's window area.  Set
+ 	`area' in the private part.
+	(paint, draw): Updated to draw in the parent's window.
+	(setup_window_and_style): Removed.
+	(gnome_animator_new_with_size): Do not touch the widget's window.
+	(expose): Redraw only the part that is being exposed.
+
+	* gnome-animator.c
+	(gnome_animator_append_frames_from_imlib_at_size): Made a lot
+ 	faster by rendering the GdkImlibImage once, and copying areas from
+ 	the generated Pixmap.  Refuse to append frames
+ 	(and return FALSE) if the width of the image is not a multiple of
+ 	`x_unit'.
+
+Wed Sep 30 01:52:39 PDT 1998 Manish Singh <yosh gimp org>
+
+	* gnome-animator.h: whitespace changes so makeenums.pl doesn't barf
+
+1998-09-29  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-animator.h (struct _GnomeAnimator): Removed `frames'
+ 	field.  Type of `playback_speed' changed to gdouble.
+	(gnome_animator_get_playback_speed): Return value changed to
+ 	gdouble.
+
+	* gnome-animator.c: Updated to use GdkPixmaps instead of
+ 	GdkImages, and a linked list instead of a dynamic array.
+	(struct _GnomeAnimatorFrame): Added `width', `height', `prev' and
+ 	`next' fields.  `image' field replaced by a `pixmap' field.
+	(struct _GnomeAnimatorPrivate): `timeout_id' moved here from
+ 	`struct _GnomeAnimator'.  New fields `first_frame', `last_frame'
+ 	and `current_frame'.
+	(init): Initialize new fields in `GnomeAnimator' and
+ 	`GnomeAnimatorPrivate'.
+	(free_all_frames): Free the linked list.
+	(paint): Use the `current_frame' field in `GnomeAnimatorPrivate'
+ 	to get the current frame; updated to draw a GdkPixmap instead of a
+ 	GdkImage.
+	(append_frame): Updated to use the linked list.
+	(gnome_animator_append_frame_from_imlib_at_size): Create a
+ 	GdkPixmap, not a GdkImage.  Set the new `width' and `height'
+ 	fields.
+	(gnome_animator_stop): Take `timeout_id' from
+ 	`GnomeAnimatorPrivate'.
+	(gnome_animator_advance): Warn, with `g_error()', if the
+ 	GnomeAnimatorLoopType is unknown.
+	(gnome_animator_goto_frame): Updated to use the linked list.
+	(gnome_animator_append_frame_from_gnome_pixmap): Take the frame's
+ 	pixmap from the GnomePixmap widget by simply referencing it.  Set
+ 	`width' and `height' in the new frame according to the pixmap's
+ 	size.
+
+1998-09-29  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-mdi.c (gnome_mdi_get_view_from_window): New function.
+	(gnome_mdi_set_window_view): New function. This sets the active
+	view of a window without giving focus to that window.
+	* gnome-mdi.h: Add prototypes.
+
+	* gnome-mdi-session.c: We now save and restore window positions,
+	the active view of each window and the active window.
+
+1998-09-29  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-text.c (gnome_canvas_text_class_init): Added two
+	new object arguments, text_width and text_height.  These are used
+	to query the rendered size of the text.
+	(gnome_canvas_text_get_arg): Process the new arguments.
+
+	* gnome-animator.c: Include only the necessary files.
+
+	* gnome-winhints.h: Include only the necessary files.
+
+1998-09-29  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-mdi-session.[ch]: New files.
+	(GnomeMDIChildCreate): New typedef. This is a pointer to a function
+	which parses the config string and creates a new GnomeMDIChild.
+	(gnome_mdi_save_state): Call this function when saving state with
+	the GnomeMDI object and the name of the config section to use.
+	(gnome_mdi_restore_state): Call this function with the GnomeMDI
+	object, the name of the config section and a (GnomeMDIChildCreate)
+	function pointer.
+
+	* gnome-mdi.c (gnome_mdi_add_toplevel_view): New function. Same as
+	`gnome_mdi_add_view', but when using GNOME_MDI_NOTEBOOK we add the
+	view to a newly created toplevel window.
+	* gnome-mdi.h (gnome_mdi_add_toplevel_view): Added prototype.
+
+	* gnome-mdi-child.c: Added new signal `get_config_string'. This
+	should be used in subclasses to return a config string representing
+	the object which can be used to recreate it when restarting from
+	the session manager.
+	* gnome-mdi-child.h (GnomeMDIChildClass): Added new signal handler
+	function `get_config_string'.
+
+	* libgnomeui.h: Include `gnome-mdi-session.h'.
+	* Makefile.am (libgnomeui_la_SOURCES): Added `gnome-mdi-session.c'.
+	(libgnomeuiinclude_HEADERS): Added `gnome-mdi-session.h'.
+
+1998-09-29  Havoc Pennington  <hp pobox com>
+
+	* gnome-dialog.c: Oops, fix a couple screwups in the last commit.
+	* gnome-messagebox.c: Use gtk_window_set_modal
+	* gnome-dialog-util.c: ditto
+	* stock_demo.c: ditto.
+
+1998-09-29  Havoc Pennington  <hp pobox com>
+
+	* gnome-dialog.c, gnome-dialog.h: Replace dialog's modality
+	facilities with the ones from GtkWindow. Since GtkWindow's were
+	exactly the same nothing should break (unless you accessed the
+	modal flag directly and then you deserve breakage). Also blew away
+	that log stuff on the bottom, for better or worse.
+	(struct _GnomeDialog): Nuke modal field.
+	(gnome_dialog_init): Don't init the modal field.
+	(gnome_dialog_set_modal): Call gtk_window_set_modal and spew
+	irritating warning to stop using this function.
+	(gnome_dialog_run_modal): Use gtk_window_set_modal
+	(gnome_dialog_run): Use GTK_WINDOW(dialog)->modal and
+	gtk_window_set_modal.
+	(gnome_dialog_close_real): Don't remove grab, GtkWindow does it on
+	hide.
+	(gnome_dialog_show): Don't add grab.
+
+1998-09-28  Havoc Pennington  <hp pobox com>
+
+	* gnome-animator.c, gnome-animator.h: Misspell private, so C++
+	doesn't complain.
+
+1998-09-28  Ettore Perazzoli  <ettore comm2000 it>
+
+	* Makefile.am (libgnomeui_la_SOURCES): Added `gnome-animator.c'.
+	(libgnomeuiinclude_HEADERS): Added `gnome-animator.h'.
+	(noinst_PROGRAMS): Added `animator_demo'.
+	(animator_demo_SOURCES, animator_demo_LDADD): New variables for
+	compiling `animator_demo'.
+
+	* libgnomeui.h: #Include "gnome-animator.h".
+
+	* animator_demo.c: New file: simple demo for `GnomeAnimator'.  It
+ 	currently requires some images from `gnome-core'...  I'll have to
+ 	fix this.
+
+	* gnome-animator.c, gnome-animator.h: New files: new
+ 	`GnomeAnimator' widget.
+
+1998-09-27  Havoc Pennington  <hp pobox com>
+
+	* gnome-actionarea.h, gnome-actionarea.c: Removed.
+	* Makefile.am, libgnomeui.h: Changed accordingly.
+
+1998-09-27  Raja R Harinath  <harinath cs umn edu>
+
+	`automake' 1.3b and older have a bug with handling continuation
+	lines inside conditionals.
+	* Makefile.am (gtkcal_headers): Don't use continuation lines.
+	(gtkcal_sources): Likewise.
+	(EXTRA_libgnomeui_la_SOURCES): List gtkcalendar.[ch].
+
+1998-09-28  Ettore Perazzoli  <ettore comm2000 it>
+
+	* gnome-messagebox.c (gnome_message_box_new): Fixed some memory
+ 	leaks.
+
+1998-09-27  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-scores.c (gnome_scores_set_colors,
+	gnome_socres_set_def_color, gnome_scores_new): Use unsigned ints
+	here.
+
+	* gnome-preferences.c (gnome_preferences_set_button_layout):
+	Unsigned int warning fix.
+
+	* gnome-properties.c
+	(gnome_property_configurator_request_foreach): Unsigned int
+	warning fix.
+
+	* gnome-init.h: New file.  Move gnome-init declarations here.
+
+	* gnome-dns.c (struct): Use guint32 for the tag
+
+	* gnome-color-selector.c (color_dropped): Use usngined int
+
+	* gnome-dentry-edit.c: Include <string.h>
+
+Sun Sep 27 16:54:33 CEST 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock.[ch]: still fiddling with this f**king background
+	colors. changed GnomeStock structure.
+	* gnome-stock.c (create_pixmap_from_imlib_scaled): check via
+	gnome_config if we want imlib's or out own resizing.
+	(build_disabled_pixmap): check via gnome_config how the disabled pixmap
+	should be built.
+	* gnome-pixmap.[ch] (gnome_pixmap_new_from_rgb_d_shaped_at_size,
+	gnome_pixmap_load_rgb_d_shaped_at_size): new functions.
+	* gnome-app-helper.c (create_pixmap_and_label): check via gnome_config
+	if we want icons in menus to keep consistance with
+	gnome_stock_menu_item.
+
+1998-09-27  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (gnome_canvas_item_reparent): Added all the usual
+	sanity checks, plus the extra checks pertaining to reparenting --
+	both items must be in the same canvas, and the new parent cannot
+	be the item itself or an inferior of the item.  Added proper
+	redrawing requests and mark the canvas as needing a repick.  Also,
+	recalculate the item's bounds.
+
+1998-09-27  Michael Lausch  <mla gams at>
+
+	* gnome-canvas.c (gnome_canvas_item_reparent): new function. Moves
+	a canvas_item from one canvas_item_group to another.
+
+1998-09-24  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-popup-menu.c (popup_marshal_func): Fixed stupid bug in the
+	marshaller; I was using args[0] instead of the actual object.
+
+Wed Sep 23 17:04:05 CEST 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock.[ch]: expanded the functionality of
+	gnome_stock_pixmap_widget to load GnomeStock widgets from files.
+	(gnome_stock_pixmap_widget_at_size): new function. Loads a GnomeStock
+	widget from a file and scales it using antializing.
+	* stock_demo.c: added an example how to use the new functionality.
+
+1998-09-21  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-line.c (gnome_canvas_line_set_arg): Avoid
+	unnecessary reconfiguration, recalculation of bounds, and arrow
+	polygon recomputation.
+
+	* gnome-canvas-text.c (gnome_canvas_text_set_arg): Avoid
+	unnecessary item reconfiguration and recalculation of bounds.
+
+	* gnome-canvas-rect-ellipse.c (get_color_arg): New function to
+	avoid a bit of duplicated code in gnome_canvas_re_get_arg().
+	(set_outline_gc_width): Now the outline GC's line width is
+	calculated here.
+	(gnome_canvas_re_set_arg): Optimizations to avoid unnecessary
+	item reconfiguration and recalculation of bounds.
+
+	* gnome-app-helper.c (create_menu_item): Set separators as
+	insensitive so that they cannot be selected.
+	(create_pixmap): Look for pixmap files in the standard pixmap
+	paths.  This was accidentally removed during the rewrite of
+	GnomeAppHelper - my bad :-(
+
+1998-09-21  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.[ch]: added view_changed signal, similar to child_changed.
+	* gnome-mdi.c (app_set_view): update active_view and active_child to
+	hold new values before emitting child_changed and/or view_changed
+	signals and pass old child/view as signal handler arguments. this
+	seems saner since the appropriate gnome-app is already updated to
+	match the new view.
+
+1998-09-20  Raja R Harinath  <harinath cs umn edu>
+
+	* pixmaps/Makefile.am (stock_images): New variable.  Lists all the
+	stock images.
+	(EXTRA_DIST): Add $(stock_images).
+	(BUILT_SOURCES): Add `gnome-stock-imlib.h'.
+	(gnome-stock-imlib.h): Don't use wildcards, use $(stock_images).
+
+	* Makefile.am (libgnomeui_la_SOURCES):
+	Remove `pixmaps/gnome-stock-imlib.h'.
+
+Sun Sep 20 18:40:44 1998  John Ellis  <johne bellatlantic net>
+
+	* pixmaps/calculator-font.xpm: Changed to png
+	* pixmaps/Makefile.am: Changed reference to above.
+	* gnome-calculator.c: Changed to use the png file.
+	* Makefile.am: Changed gnome-stock-imlib.h to
+	pixmaps/gnome-stock-imlib.h
+
+Mon Sep 21 00:03:03 CEST 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock.c: removed some compiler warnings.
+	GnomeStock is now a bit smarter concerning the background color for
+	transparency and disabled pixmaps (for those of you who play
+	around with the gtk styles).
+
+Sun Sep 20 15:26:41 CEST 1998  Eckehard Berns  <eb berns prima de>
+
+	* pixmaps/: use PNG images instead of XPMs.
+	* puxmaps/Makefile.am: updated to use PNGs.
+
+Sat Sep 19 19:37:13 CEST 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock.c (gnome_stock_paint): added gtk_widget_queue_draw
+	* gnome-stock.[ch]: added menu versions of the timer icons
+
+Sat Sep 19 17:24:58 CEST 1998  Eckehard Berns  <eb berns prima de>
+
+	* pixmaps/Makefile.am: removed xpm2rgb which needs a Display.
+	use ../../tools/convertrgb/convertrgb to build gnome-stock-imlib.h
+
+Sat Sep 19 12:47:35 CEST 1998  Eckehard Berns  <eb berns prima de>
+
+	* pixmaps/xpm2rgb.c pixmaps/stock_*.xpm: new files
+	* pixmaps/Makefile.am: added generation of gnome-stock-imlib.h
+	* gnome-stock.c: include pixmaps/gnome-stock-imlib.h
+
+1998-09-18  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-popup-menu.c (gnome_popup_menu_new): New public function
+	to create a popup menu from a GnomeUIInfo array.
+	(gnome_popup_menu_attach): New public function to attach a popup
+	menu to a widget -- the popup menu can be called by pressing mouse
+	button 3 over the widget.  The menu can be shared between multiple
+	widgets and it will be destroyed when the last widget it is
+	attached to is destroyed.
+	(gnome_popup_menu_do_popup): New public function to explicitly
+	popup a menu.
+
+	* gnome-app-helper.c (do_ui_signal_connect): Use
+	gtk_signal_connect_full() instead of gtk_signal_connect_interp(),
+	since the latter is obsolete (but works anyway...).
+
+	* stock_demo.c:
+	* gnome-stock.c:
+	* gnome-number-entry.c:
+	* gnome-init.c:
+	* gnome-dialog.h:
+	* gnome-dialog.c:
+	* gnome-dentry-edit.c:
+	* gnome-client.c (gnome_client_init):
+	* gnome-calculator.c:
+	* gnome-app.c:
+	* libgnomeui.h: Removed occurrences of #ifdef GTK_HAVE_FEATURES_1_1_0.
+	We require it, anyways.
+
+	* Makefile.am: Moved all the conditional canvas files into the
+	main list of sources -- they are always compiled now.
+
+1998-09-17  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* Makefile.am: Renamed gnome-popupmenu.[ch] to gnome-popup-menu.[ch].
+
+1998-09-18  Sebastian Wilhelmi  <wilhelmi ira uka de>
+
+	* libgnomeui.h: corrected gnome-popupmenu.h to gnome-popup-menu.h and
+	the same (but here this is only a typo, not a bug ;-) in
+	gnome-popup-menu.h and gnome-popup-menu.c
+
+1998-09-18  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-app-helper.c (create_pixmap): If no pixmap has been
+	provide, behave like GNOME_APP_PIXMAP_NONE.
+
+1998-09-17  Martin Baulig  <baulig merkur uni-trier de>
+
+	* gnome-app-helper.c (do_ui_signal_connect): Store both `uiinfo->user_data'
+	(GNOMEUIINFO_KEY_UIDATA) and `uibdata->data' (GNOMEUIINFO_KEY_UIBDATA) in
+	the widget using gtk_object_set_data().
+
+1998-09-17  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-app-helper.[ch] (gnome_app_fill_menu_*): added a gint pos
+	argument in order to reimplement broken menu insertion functions.
+	(gnome_app_insert_menus_custom): use gnome_app_fill_menus_custom().
+	(gnome_app_find_menu_pos): fixed to work with Federico's changes.
+
+1998-09-16  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-app-helper.c (gnome_app_fill_menu_custom): More function
+	arguments sanity checks.
+	(gnome_app_create_menus): Likewise.
+	(gnome_app_create_menus_interp): Likewise.
+	(gnome_app_create_menus_with_data): Likewise.
+	(gnome_app_create_menus_custom): Likewise.
+	(setup_accelerator): Added an argument for the signal name.
+	(gnome_app_fill_toolbar gnome_app_fill_toolbar_custom): New public
+	functions to fill toolbars from a GnomeUIInfo array.
+	(gnome_app_create_toolbar):
+	(gnome_app_create_toolbar_interp):
+	(gnome_app_create_toolbar_with_data):
+	(gnome_app_create_toolbar_custom): Make these functions use the
+	new fill_toolbar ones.
+	Removed the old #ifdef'ed functions.
+
+1998-09-16  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-app-helper.c (gnome_app_fill_menu
+	gnome_app_fill_menu_custom): New public functions that are a
+	rewrite of the menu creation code in GnomeAppHelper.  These are
+	saner versions with additional goodies, like working accelerators,
+	underlined shortcuts, sanity checks, etc.
+	(gnome_app_create_menus):
+	(gnome_app_create_menus_interp):
+	(gnome_app_create_menus_with_data):
+	(gnome_app_create_menus_custom): Made these functions use the new
+	fill_menu code.
+	The toolbar code still needs sanitizing; will do that tomorrow.
+
+	* gnome-app-helper.h: Beautification and documentation of the
+	header file.
+	(GnomeUISignalConnectFunc): Removed the app parameter to functions
+	of this type, as it is not needed or used.  Please make the
+	appropriate changes to your language bindings and such.
+
+	* gnome-app-helper.c: Added a little TODO list.
+
+	* gnome-popupmenu.c: #ifdef'ed out the function bodies, since
+	gnome-popupmenu is completely broken and needs rewriting.
+
+	* gnome-canvas.c: Updates to the TODO list.
+
+	* gnome-preferences.c (gnome_preferences_get_menus_have_icons
+	gnome_preferences_set_menus_have_icons): New public functions to
+	get/set whether menu items have icons in them.
+	(gnome_preferences_load): Load the menus_have_icons parameter.
+	(gnome_preferences_save): Save the menus_have_icons parameter.
+
+	* gnome-rootwin.c (gnome_rootwin_expose): Return FALSE.
+
+	* gnome-app.c: Added g_return_* sanity checks where they were missing.
+	(gnome_app_set_contents): Fix the case where contents == NULL.
+
+	* gnome-app.h: Added some comments/documentation.
+	(struct _GnomeApp) Added an accel_group field -- this is the accel
+	group where the window's hotkeys live.
+
+	* gnome-app.c (gnome_app_init): Create the app window's accel
+	group and attach it.
+
+	* gnome-app.c (get_orientation): Added a small warning if the
+	orientation is not matched.
+
+Tue Sep 15 11:22:24 1998  Owen Taylor  <otaylor redhat com>
+
+	* gtk-socket.c (gtk_socket_realize): Add a gdk_flush()
+	so that our newly created window is guaranteed to
+	already have SubstructureRedirect when another app
+	gets the XID.
+
+1998-09-14  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c (gnome_mdi_remove_view): fixed view removal to
+	update the menubar correctly.
+
+Sat Sep 12 13:50:29 1998 Paul Sheer <psheer obsidian co za>
+
+	* gtkcauldron.c: Added inline labels: specified as text between
+	an `(' and a `)' with no space between the `(' and the first
+	text character.
+
+	* gtkcauldron.c: Added scrollable frames: specify with the v and
+	h options to the `]' of a frame. Eg `]v' or `]vh' or ']h'. See
+	README.gtkcauldron for more details.
+
+1998-09-12 Francisco Bustamante <pancho nuclecu unam mx>
+
+	* gnome-app-helper.c (gnome_app_do_menu_creation): added check for
+	NULL moreinfo pointer in a GNOME_APP_UI_SUBTREE case.
+
+1998-09-12  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c, gnome-mdi-child.c: changed some GTK_TYPE_POINTERs
+	in parameters passed to gtk_signal_new() to gtk_widget_get_type()
+	calls.
+
+1998-09-11  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi-child.c (gnome_mdi_child_set_name): moved the
+	gnome_mdi_rename_child()'s functionality here.
+	* gnome-mdi.c (gnome_mdi_rename_child): removed.
+	(child_list_activated_cb, gnome_mdi_set_active_view): moved
+	much of the former to the latter.
+	(app_set_view, app_create): when uisng GnomeUIInfo templates to
+	create menus and the toolbar, the MDI menus and toolbar are now
+	set up with a gnome_app_create_*_with_data() call so that relevant
+	callbacks are passed a pointer to the MDI as data. in a similar
+	manner the child specific menus' callbacks are passed a pointer to
+	the child.
+
+1998-09-09  Havoc Pennington  <hp pobox com>
+
+	* gnome-gtk-utils.h: Cleanup. Added copyright (FSF? I guess so.)
+	Added GNOME_BEGIN_DECLS (took me an hour to figure out that was
+	causing gnome-- breakage). Made include guards consistent with
+	other headers.
+
+1998-09-09  Raja R Harinath  <harinath cs umn edu>
+
+	* gnome-dentry-edit.c: Protect inclusion of `gnomesupport.h' with
+	NEED_GNOMESUPPORT_H.
+
+Tue Sep  8 22:54:31 1998  Tom Tromey  <tromey cygnus com>
+
+	* gnome-dentry-edit.c: Include gnomesupport.h for strndup.
+
+1998-09-06  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-mdi.c (gnome_mdi_set_mode, rootwin_drop): Make the newly
+	created windows have the same size the current view had before.
+
+	* gnome-mdi.h (gnome_mdi_active_view): New function.
+	(gnome_mdi_set_active_view): New function.
+
+	* gnome-mdi.c: Renamed static `gnome_mdi_set_active_view()'
+ 	to `set_active_view()' and added new global function
+ 	`gnome_mdi_set_active_view()'.
+
+Fri Sep 04 17:53:41 1998  George Lebl  <jirka 5z com>
+
+	* gnome-color-picker.c: initialize use_alpha
+
+1998-09-03  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-font-selector.c (gnome_font_select_with_default): New
+	function. Same as gnome_font_select () but let you give a
+	default font.
+
+Thu Sep  3 05:47:19 1998  Tim Janik  <timj gtk org>
+
+	* gnome-icon-list.c (gnome_icon_list_forall): provide a _forall
+	implementation instead of _foreach.
+
+1998-09-02  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (gnome_canvas_root): Changed the return type to
+	GnomeCanvasGroup, as it is more convenient that way.
+
+	* gnome-color-picker.[ch]: New color picker that is a real
+	widget.  GnomeColorSelector is now deprecated.
+
+	* gnome-color-selector.c (gnome_color_selector_new): Added message
+	of deprecation.
+
+	* libgnomeui.h: Added gnome-color-picker.h to the list of headers.
+
+	* Makefile.am: Added gnome-color-picker.[ch] to the sources.
+
+1998-09-02  Martin Baulig  <martin home-of-linux org>
+
+	* gnome-mdi.c (gnome_mdi_rename_child): New function. This is
+	required to set the correct name in the menu item.
+
+1998-09-01  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-app-helper.c (gnome_create_toolbar_with_data,
+	gnome_create_toolbar_custom): New routines to reuse the toolbar
+	creation code without having the toolbar be attached by default.
+
+1998-08-28  Havoc Pennington  <hp pobox com>
+
+	* gtklayout.c (gtk_layout_move): Fix infinite loop (add
+	g_list_next on each iteration).
+
+1998-08-25  Havoc Pennington  <hp pobox com>
+
+	* gnome-canvas.h (gnome_canvas_item_set_valist): New function
+	takes a va_list as argument.
+	* gnome-canvas.c (gnome_canvas_item_set): Implement in terms of
+	set_valist.
+
+Wed Aug 26 00:50:27 1998  Tom Tromey  <tromey cygnus com>
+
+	* gnome-app.c (gnome_app_reparent_handle_box): Declare to avoid
+	warnings.
+
+	* gnome-propertybox.c (gnome_property_box_init): Changed calls to
+	reflect typo fix.
+	* gnome-preferences.h: Declare
+	gnome_preferences_get_property_box_apply,
+	gnome_preferences_set_property_box_button_apply.
+	* gnome-preferences.c (gnome_preferences_get_property_box_apply):
+	Renamed to fix typo.
+
+1998-08-25  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	Fixed a bug waiting to happen on my previous change: Specifically,
+	UI-properties would have been the only victim (change of the style
+	of a gnome-propertybox while using it).
+
+	* gnome-propertybox.c (gnome_property_box_init): Implement support
+	for OK/CANCEL/HELP vs OK/APPLY/CLOSE/HELP modes.
+
+	* gnome-preferences.c (gnome_preferences_load): Activate the code
+	for the preference dialog box configuration.
+
+1998-08-24  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gtkcauldron.c (gtk_dialog_cauldron_parse): Use
+	gtk_window_position on the created dialog box.
+
+Mon Aug 24 22:51:50 1998  Owen Taylor  <otaylor redhat com>
+
+	* gtk-socket.c (gtk_socket_realize): Use
+	gtk_widget_get_parent_window() to get the parent window.
+
+Mon Aug 24 19:01:02 1998  Owen Taylor  <otaylor redhat com>
+
+	* gtk-socket.c (gtk_socket_size_request/allocate): Don't
+	need to assert that the widget->window != NULL.
+
+Mon Aug 24 23:43:47 CEST 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock-imlib.h: added convert and jump_to icons
+	* gnome-stock.h: added defines for the new icons
+	* gnome-stock.c: added entries for the new icons
+	added some `const's and (char *) typecasts to let gnome-stock
+	compile without warnings with -Wall
+	* stock_demo.c: added convert and jump_to icons
+
+1998-08-24  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-app.c (gnome_app_rightclick_menubar,
+	gnome_app_rightclick_toolbar):  Make the handleboxes reparent on
+	double click.
+
+Mon Aug 24 07:53:53 1998  Tim Janik  <timj gtk org>
+
+	* gnome-canvas.c (gnome_canvas_item_construct): added a
+ 	const gchar *first_arg_name, to the prototype which is required by
+	gtk_object_args_collect(). pass va_list by value. unfortunately this
+ 	change is source incompatible ;(
+	(gnome_canvas_item_new): added first_arg_name, to pass to
+	gnome_canvas_item_construct, source compatile change.
+	(gnome_canvas_item_set): added first_arg_name, to pass to
+	gtk_object_args_collect. pass va_list by value.
+
+	* gnome-net.c (gnome_net_printf): use g_strdup_vprintf() instead of
+	g_vprintf().
+
+1998-08-21  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c: Fixed the new compiler warnings.
+
+1998-08-21  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gtkcauldron.c (gtk_cauldron_button_exit): Used gtk_main_quit for
+	terminating the dialog instead of destroying the window, as the
+	code expects the window to be valid after the cauldron main
+	loop.
+	(gtk_dialog_cauldron_parse): Hook to the delete_event instead of
+	destroy (as we do the destroy always after gtk_main).
+
+Fri Aug 21 18:28:43 1998  Jonathan Blandford  <jrb redhat com>
+	* gtk-plug.[ch]:
+	(gtk_plug_construct): New function.
+
+Thu Aug 20 19:06:19 1998  Tom Tromey  <tromey cygnus com>
+
+	* gnome-dentry-edit.c: Include <ctype.h>.
+	(gnome_dentry_edit_split): New function.
+	(gnome_dentry_edit_sync_dentry): Use it.
+
+Thu Aug 20 19:22:47 1998  Owen Taylor  <otaylor redhat com>
+
+	* gtk-socket.c (gtk_socket_claim_focus): Yet another fix
+	for when the plug window hasn't appeared yet.
+
+Thu Aug 20 18:40:38 1998  Owen Taylor  <otaylor redhat com>
+
+	* winhints_demo.c gnome-wmhints.[ch]: Removed
+	excess header file includes from gnome-wmhints.h,
+	fixed a few things so the result compiles.
+
+1998-08-20  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c: Updates to the to-do list.
+
+	* gnome-canvas-text.c (gnome_canvas_text_class_init): Added
+	clip_width, clip_height, clip, x_offset, and y_offset arguments.
+	These are used to define an optional clip rectangle and offset
+	distance for the text.  Please see the comments in
+	gnome-canvas-text.h for an explanation of these.
+	(split_into_lines): Added support for multiline text; this
+	function splits the text into an array of lines.
+	(gnome_canvas_text_draw): Changed to draw
+	multiline/justified/clipped text.
+	(gnome_canvas_text_point): Modified to calculate the distance to
+	multiline clipped text.
+
+Thu Aug 20 15:44:22 1998  Owen Taylor  <otaylor redhat com>
+
+	* gtk-socket.c (gtk_socket_filter_func): Small
+	improvement to CreateNotify handling.
+
+Thu Aug 20 15:23:58 1998  Owen Taylor  <otaylor redhat com>
+
+	* gtk-socket.c (gtk_socket_filter_func): We seem to
+	be getting ConfigureRequests before CreateNotify when
+	our plug window is added, so we need to handle them.
+
+Wed Aug 19 18:21:24 1998  Owen Taylor  <otaylor redhat com>
+
+	* gtk-socket.c: Don't process focus requests when we don't have
+	have a plug.
+
+Wed Aug 19 13:33:31 EDT 1998 The Rasterman <raster redhat com>
+	* gnome-rootwin.c - removed lots of unecessary event mask entries for
+	the root window widget - made it have dummy (do nothing) draw and
+	expose handlers. Now it works correctly with themes.
+
+1998-08-18  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-propertybox.c (gnome_property_box_append_page): Wonder why
+	this routine was tagged as deprecated.  Make it legal to use
+	again.
+
+1998-08-18  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-line.c (gnome_canvas_line_get_arg):
+	* gnome-canvas-text.c (gnome_canvas_text_get_arg):
+	* gnome-canvas-rect-ellipse.c (gnome_canvas_re_get_arg): Return a
+	malloc()ed color for the color arguments.
+
+Tue Aug 18 06:41:47 1998  Tim Janik  <timj gtk org>
+
+	* gnome-init.c (our_gtk_options): added --gtk-module, and a few
+	descriptions.
+	(our_gtk_parse_func): fix for the flag name lookup in g_strconcat(),
+	which was referring to the option name off-by-one.
+
+1998-08-17  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-line.c (gnome_canvas_line_get_arg): Made the
+	fill_color_gdk argument read/write.
+
+	* gnome-canvas-text.c (gnome_canvas_text_get_arg): Made the
+	font_gdk and fill_color_gdk arguments read/write.
+
+	* gnome-canvas-rect-ellipse.c (gnome_canvas_re_get_arg): Made the
+	fill_color_gdk and outline_color_gdk arguments read/write.
+
+1998-08-14  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-text.c (gnome_canvas_text_class_init): The font
+	argument should be of type GTK_TYPE_GDK_FONT.
+
+Wed Aug 12 18:33:15 EDT 1998 Gregory McLean <gregm comstar net>
+
+	* gnome-app-helper.c: Adjusted the GNOME_PIXMAP_FILENAME
+	stuff to do a gnome_pixmap_file() on the file name passed in
+	otherwise you wind up doing all sorts of silly stuff to maintain
+	good code.. Anyone have a better soultion?
+
+Wed Aug 12 14:48:24 1998  Owen Taylor  <otaylor redhat com>
+
+	* gnome-stock-imlib.h: Made all gnome stock pixmaps
+	  const. (Makes >100k more memory shared between gnome apps)
+
+Wed Aug 12 18:01:30 CEST 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock.[ch]: 1st go at a rewrite of the gnome stock widget.
+	Because of a new widget (GnomeStock) some apps might get minor
+	problems. The majority of the apps should work though.
+
+Tue Aug 11 23:35:58 1998  Jonathan Blandford <jrb mit edu>
+	* gnome-app.c: added GTK_SHRINK to the x/y options.
+
+1998-08-11  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (gnome_canvas_item_grab): Set the
+	canvas->current_item to the grabbed item to force events to go to
+	it.
+
+	* gnome-canvas-widget.h:
+	* gnome-canvas-line.h:
+	* gnome-canvas-image.h:
+	* gnome-canvas-text.h:
+	* gnome-canvas-rect-ellipse.h:
+	* gnome-canvas.h: Documentation fixes and additions.  Added
+	descriptions of object arguments.
+
+1998-08-10  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-rect-ellipse.c (gnome_canvas_re_set_arg): Added
+	fill_color_gdk and outline_color_gdk arguments.  The argument's
+	value is a pointer to an already-allocated GdkColor.
+
+	* gnome-canvas-text.c (gnome_canvas_text_set_arg): Added font_gdk
+	and fill_color_gdk arguments.  The argument values are a pointer
+	to a GdkFont and an already-allocated GdkColor, respectively.
+
+	* gnome-canvas-line.c (gnome_canvas_line_set_arg): Added
+	fill_color_gdk argument.
+
+Sun Aug 09 14:37:58 1998  George Lebl  <jirka 5z com>
+
+	* gnome-about.c: draw the pixmap with the correct clip mask
+
+1998-08-07  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-rect-ellipse.c (gnome_canvas_re_reconfigure):
+	* gnome-canvas-text.c (gnome_canvas_text_reconfigure):
+	* gnome-canvas-image.c (gnome_canvas_image_reconfigure):
+	* gnome-canvas-line.c (gnome_canvas_line_reconfigure):
+	* gnome-canvas-widget.c (gnome_canvas_widget_reconfigure): Call
+	the parent class reconfigure method at the start of the overriden
+	method.
+
+1998-08-06  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-preferences.[ch]: added MDI preferences.
+	* gnome-mdi.h: changed the GnomeMDIMode enums a bit: this requires
+	recompiling any apps using MDI.
+	* gnome-mdi.c: take UI properties into account.
+
+1998-08-05  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-line.c:
+	* gnome-canvas-image.c:
+	* gnome-canvas-text.c:
+	* gnome-canvas-rect-ellipse.c: Call the parent class
+	realize/unrealize/map/unmap methods in the overriden methods.
+
+Wed Aug  5 23:08:53 CEST 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock*: added tigert's undelete icon, changed yes/no buttons,
+	added prev/next button with images from back forward.
+
+Wed Aug  5 12:47:01 1998  Owen Taylor  <otaylor redhat com>
+
+	* gnome-stock.c (gnome_stock_pixmap_widget_realize): A widget
+	  is not allowed to changed it's requisition during the
+	  realize() method. Moved initial pixmap setting into
+	  new(). (Past changes have eliminated the need to
+	  have everything realized first.) This should keep
+	  gtk_vbox_size_allocate() from getting confused. But
+	  the entire widget needs to be rewritten from scratch,
+	  as a bin instead of the current GtkVBox hack.
+
+	* gnome-app-helper.c (gnome_app_do_menu_creation): Removed
+	  unecessary realize().
+
+1998-08-05  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gtklayout.c (gtk_layout_size_allocate): Move_resize the
+	bin_window, not just resize it.  This is for when we have parents
+	that do funky size allocation, because the bin_window may not act
+	as expected as it has the gravity bits set.
+
+Wed Aug  5 11:19:56 1998  Owen Taylor  <otaylor redhat com>
+
+	* gnome-dialog.c (gnome_dialog_destroy): Don't remove
+	  the accelerator group - GTK+ handles it for us.
+
+	* gnome-app.c gnome-app-helper.c: Added gtk-1.1 code to check
+	  if AccelGroup is already attached before attaching it
+	  again.
+
+1998-08-04  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gtkcauldron.c: Fixup includes.
+	(user_callbacks): Made static.
+	Fixed for Gtk-1.1.  Could someone please test that it runs?  I
+	only fixed it for compilation.
+
+	* gtkcauldron.h: Fixup includes.
+
+	* libgnomeui.h: #include "gnome-number-entry.h"
+
+	* gnome-canvas.c (gnome_canvas_button):
+	(gnome_canvas_motion):
+	(gnome_canvas_expose):
+	(gnome_canvas_key):
+	(gnome_canvas_crossing): Only do stuff if the event window is the
+	same as the canvas->layout.bin_window.
+
+	* gnome-canvas-widget.[ch]: New widget item type for GnomeCanvas.
+	It still needs to be debugged.
+
+	* Makefile.am: Added gnome-canvas-widget to the sources.
+
+	* libgnomeui.h: Added gnome-canvas-widget.h to the list of headers.
+
+	* gnome-canvas-image.c (gnome_canvas_image_set_arg): Take the
+	absolute value of the width/height arguments.
+
+1998-08-03  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (gnome_canvas_draw): Use the zoom offsets when
+	calculating coordinates.
+	(gnome_canvas_expose): Likewise.
+	(paint): Likewise.
+	(gnome_canvas_set_scroll_region): Likewise.
+	(gnome_canvas_set_pixels_per_unit): Likewise.
+	(pick_current_item): Likewise.
+	(window_to_world): Likewise.
+	(scroll_to): New internal function to scroll the canvas to a new
+	position.  It takes care of adjusting the scroll offset and zoom
+	offset to keep as much as possible of the canvas scrolling region
+	in view.
+	(gnome_canvas_scroll_to): Use the new scroll_to function.
+	(gnome_canvas_set_pixels_per_unit): Likewise.
+	(gnome_canvas_set_scroll_region): Likewise.
+	(gnome_canvas_size_allocate): Reset the adjustment page_size and
+	page_increment.
+
+	* gnome-canvas.h (struct _GnomeCanvas): New fields zoom_xofs and
+	zoom_yofs.  These are used to track the inset offsets to use when
+	the canvas is zoomed out.
+
+1998-08-03  Jaka Mocnik <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.h: new GnomeMDI member tab_pos: stores the desired tab
+	position of MDI notebook widgets.
+	* gnome-mdi.c (gnome_mdi_set_tab_pos): sets the desired tab position
+	for MDI notebook widgets.
+	(book_create): set the desired tab position of created notebook widgets.
+
+1998-08-02  Raja R Harinath  <harinath cs umn edu>
+
+	* Makefile.am (gnome.defs): Simplify rule by using `cd $srcdir'
+	before doing any of the stuff.
+	(gnometypebuiltins{.h,_vars.c,_ids.c,_evals.c}: Likewise.
+	* makeenums.pl (parse_entries): `srcdir' is now not passed in the
+	environment.
+
+1998-07-31  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (gnome_canvas_set_scroll_region):
+	(gnome_canvas_set_pixels_per_unit): Use gtk_layout_freeze/thaw().
+	(DISPLAY_X1): Use the layout->xoffset value instead of the
+	adjustment value.
+	(DISPLAY_Y1): Likewise.
+	(gnome_canvas_get_scroll_region): New public function to query the
+	scrolling limits of the canvas.
+
+	* gtklayout.c (gtk_layout_freeze):
+	(gtk_layout_thaw): Added public freeze/thaw functions for
+	GtkLayout.  These disable/enable moving and repainting of the
+	bin_window of the layout, respectively.
+	(gtk_layout_position_children): New private function to reposition
+	all the children in the layout.
+	(gtk_layout_adjustment_changed): Don't do anything but update the
+	offsets if it is frozen.  Use gtk_layout_position_children().
+
+	* gtklayout.h (struct _GtkLayout): Added frozen field.
+
+1998-07-31  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+        * gnome-mdi-child.h: GnomeMDIChild now has a pointer to his
+	parent MDI [if it exists].
+	* gnome-mdi.[ch] (gnome_mdi_update_child): new public function.
+	for now all it updates are the children's names.
+	* gnome-mdi.c (gnome_mdi_add_child, gnome_mdi_remove_child):
+	take care of updating the child's parent pointer.
+	(find_page_by_widget): new private convenience function.
+	* gnome-mdi-child.c (gnome_mdi_child_set_name): call
+	gnome_mdi_update_child().
+
+1998-07-30  Mark Crichton  <crichton expert cc purdue edu>
+
+	* gnome-popupmenu.c (gnome_app_create_popup_menus_custom):
+	The old reparent there was a bad thing.  Changed to a
+	container_add.  Mem leak still exists,will be fixed soon.
+	(gnome_app_create_popup_menus): Changed #if to #ifdef so
+	code would actually compile correctly.
+
+	Popup menu code is now "stable" for general testing now.  If
+	anyone can fix thebad display-ish bug I'm having, I'd appreciate
+	leads.
+
+1998-07-30  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-init.c: Fixup includes.
+
+	* gnome-canvas.c (gnome_canvas_scroll_to): Re-added the
+	gnome_canvas_scroll_to() function.  It changes the scroll offset
+	by emitting the proper signals, and takes care of all the gritty
+	details.
+	(gnome_canvas_get_scroll_offsets): New public function to query
+	the scroll offsets of the canvas.
+
+1998-07-30  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	OK, some semi-major changes.  The canvas is now a descendant of
+	GtkLayout, which does smooth scrolling a la Mozilla (so that
+	subwindows of the window you are scrolling do not trail behind
+	when you scroll).
+
+	There are some problems left with setting the adjustments to
+	reasonable values when the canvas is zoomed in; I will be fixing
+	that shortly.
+
+	Please read the changes below to see what needs to be done for
+	stuff derived from the canvas.
+
+	* gtklayout.[ch]: Added the supercool GtkLayout container to the
+	source tree.
+
+	* gtklayout.c (gtk_layout_adjustment_changed): Do not do any
+	window-related operations if the widget is not mapped.
+
+	* Makefile.am: Added gtklayout.[ch] to the sources.
+
+	* libgnomeui.h: Added gtklayout.h to the list of headers.
+
+	* gnome-canvas.[ch]: The GnomeCanvas widget now descends from
+	GtkLayout.  Made the necessary changes to the Gtk-related
+	functions to make this happen.
+
+	* gnome-canvas.h (struct _GnomeCanvas): Removed the bg_pixel and
+	bg_set fields.  Also, removed the display_x1 and display_y1 fields
+	-- these can now be queried from the
+	canvas->layout.hadjustment->value and vadjustment fields.
+
+	* gnome-canvas.h: Removed the gnome_canvas_scroll_to() function.
+	The scroll offset can now be set using the parent layout's
+	adjustments.
+
+	* gnome-canvas.h (struct _GnomeCanvas): Removed the visual and
+	colormap fields.
+
+	* gnome-canvas.h: gnome_canvas_new() now takes zero arguments --
+	it will use the proper Gtk visual and colormap (settable by using
+	gtk_widget_push_visual() and gtk_widget_push_colormap()).
+
+	* gnome-canvas.h: Removed the gnome_canvas_construct() function.
+
+	* gnome-canvas.c (gnome_canvas_construct): Removed this function
+	and moved the useful parts to gnome_canvas_init().
+	(gnome_canvas_new): Now just creates the object and returns it as
+	is -- now all initialization can be done in gnome_canvas_init().
+
+	* gnome-canvas-rect-ellipse.c (gnome_canvas_re_realize): Use the
+	canvas->layout.bin_window.
+	* gnome-canvas-text.c (gnome_canvas_text_realize): Likewise.
+	* gnome-canvas-image.c (gnome_canvas_image_realize): Likewise.
+
+1998-07-29  Raja R Harinath  <harinath cs umn edu>
+
+	* Makefile.am (EXTRA_DIST): Add `gnome.defs', make{types,enums}
+	scripts, and gnometypebuiltins_{vars,ids,evals}.c.
+
+1998-07-29  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-line.c (gnome_canvas_line_set_arg): When re-setting
+	the coordinates of the line, drop the arrowhead polygons if they
+	exist, as they need to be regenerated.
+
+	* gnome-canvas-line.c (reconfigure_arrows): Do not do anything if
+	the line does not have any points at all.
+	(recalc_bounds): Only grow the bounds to include the arrows if the
+	arrows have been defined yet.
+
+	* gnome-canvas-line.c (reconfigure_arrows): Do not scale the
+	arrows when the width of the line is specified in (unchanging)
+	pixels, to be consistent with the rest of the canvas.
+	(gnome_canvas_line_point): Adjust the effective width of the line
+	for the distance-to-point calculation so that even lines that are
+	logically less than one pixel thick can be picked up.
+
+1998-07-29  Havoc Pennington  <hp pobox com>
+
+	* gnome-icon-list.h, gnome-icon-list.c: Put const on char* args.
+
+1998-07-28  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-line.c (gnome_canvas_line_draw): Draw the
+	arrowheads if they exist.
+	(reconfigure_arrows): New function used to recompute the arrowhead
+	polygons.
+
+	* gnome-canvas-line.c (recalc_bounds): Doh.  Call
+	gnome_canvas_group_child_bounds() to notify the line's parent of
+	the changed bounds.
+
+	Added standard Gtk functions for querying object arguments:
+
+	* gnome-canvas.c (gnome_canvas_group_get_arg): New function.
+	* gnome-canvas-rect-ellipse.c (gnome_canvas_re_get_arg): New function.
+	* gnome-canvas-text.c (gnome_canvas_text_get_arg): New function.
+	* gnome-canvas-line.c (gnome_canvas_line_get_arg): New function.
+
+	* gnome-canvas.c (gnome_canvas_request_redraw): Do not do anything
+	if the widget is not drawable.
+
+1998-07-27  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-line.c (gnome_canvas_line_destroy): Doh, forgot to
+	assign line.
+
+	* gnome-canvas.c (item_post_create_setup): Moved
+	realization/mapping from here to group_add().
+	(group_remove): Unmap/unrealize the child here as well.  This is
+	in preparation for the reparent functions of the canvas.
+
+	* gnome-canvas.h: Added realized and mapped flags for items.
+	Sigh, I thought I would not be needing them.
+
+	* gnome-canvas.c (gnome_canvas_item_shutdown): Only
+	unmap/unrealize the item if appropriate.
+
+	* gnome-canvas.c (gnome_canvas_group_realize):
+	(gnome_canvas_group_unrealize):
+	(gnome_canvas_group_map):
+	(gnome_canvas_group_unmap): Use the realized/mapped flags to see
+	which children to operate on.
+
+	* gnome-canvas.c (gnome_canvas_item_shutdown): Unmap/unrealize the
+	item before unparenting it.
+	(group_remove): Rewrote for sanity's sake.
+	(gnome_canvas_item_shutdown): Reset the canvas current_item and
+	new_current_item to null.
+	(gnome_canvas_group_destroy): Proper destruction of the list of
+	children.
+
+1998-07-27  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-app-helper.c (gnome_app_find_menu_pos): fixed a bug with
+	multiple items with same prefixes in a menu.
+
+Sun Jul 26 13:31:27 1998  Tom Tromey  <tromey cygnus com>
+
+	Some `-Wall -Wmissing-declarations' fixes:
+	* gnome-scores.c (gnome_scores_new): Changed type of `buttons' to
+	match gnome_dialog_constructv prototype.
+	* gnome-popupmenu.c (gnome_app_create_popup_menus_custom): Removed
+	unused variables.
+	* gnome-lamp.c (type_hash): Now static.
+	* gnome-init.c: Include libgnomeui/libgnomeui.h.
+	(gnome_init): Protect segv code with USE_SEGV_HANDLE.
+	(gnome_segv_handle): Likewise.
+	* gnome-icon-sel.c: Include <string.h>.
+	* gnome-entry.c (gnome_entry_load_history): Removed unused
+	variable.
+	(gnome_entry_save_history): Likewise.
+	* gnome-dns.c (gnome_dns_server_req): Now static.
+	(gnome_dns_create_server): Likewise.
+	(gnome_dns_callback): Likewise.
+	* gnome-dialog-util.c: Include gnome-dialog-util.h.
+	* gnome-client.c (client_set_prop_from_array_with_arg): Added cast
+	to avoid warning.
+	* gnome-app-helper.c (gnome_app_add_radio_menu_entries): Always
+	return a value.
+	(gnome_app_add_help_menu_entries): Likewise.
+	(gnome_app_insert_menus_custom): Removed unused variable.
+	* gnome-appbar.c: Include libgnomeui/gnome-preferences.h.
+	* gnome-app.c: Include libgnomeui/gnome-preferences.h.
+
+1998-07-27  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.[ch]: removed some unused variables and functions and
+	fixed some things that I forgot during the previous commit.
+	Thanks go to Tom Tromey for pointing things out and sending a patch.
+
+1998-07-26  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-app.c: don't use GTK_SHRINK flag when attaching toolbar,
+	menubar or statusbar. it seems nicer if these don't shrink when
+	the GnomeApp itself is shrunk.
+	* gnome-mdi.h: changed GNOME_MDI_* mode flags to enums.
+	* gnome-mdi.c (book_create): make the notebook scrollable: this fixes
+	the problem with lots of children in notebook mode.
+	(app_create): allow growing and shrinking of GnomeApps.
+	(gnome_mdi_get_app_from_view, gnome_mdi_get_child_from_view):
+	convenience functions for getting the GnomeMDIChild or GnomeApp data
+	from an associated view.
+	* gnome-mdi-child.h: removed VIEW_GET_* macros. they have been obsoleted
+	by the gnome_mdi_get_*_from_view() functions.
+	* gnome-mdi.[ch] (gnome_mdi_register, gnome_mdi_unregister): these
+	functions should make life easier if an application opens windows
+	that should "keep the app alive" even if there are no MDI windows
+	open. any such windows should be registered with the MDI: as long
+	as there is a window registered, the MDI will not destroy itself
+	(even if the last of the MDI windows is closed). balsa's Mailbox List
+	window comes to mind as an example.
+
+Fri Jul 24 19:54:43 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-scores.c (gnome_scores_new): Use construct to set
+	the title and buttons.
+
+        * gnome-app-util.c: Switch to parented dialogs.
+
+	* gnome-dialog-util.h, gnome-dialog-util.c: Added "parented"
+	versions of these. The old versions are not really necessary
+	anymore because you can just pass NULL for parent, but they
+	save typing I guess.
+
+	* gnome-preferences.h: New functions for dialog position, whether
+ 	to attempt dialog-over-parent centering, whether dialogs are
+ 	TOPLEVEL or DIALOG.
+
+	* gnome-dialog.c (gnome_dialog_newv): Remove unused variable.
+	(gnome_dialog_set_parent): New function, allows setting a parent
+	the dialog should be centered over.
+
+Sat Jul 25 02:51:12 1998  Simon Kagedal  <simon sdf se>
+
+ 	* gnome-scores.c, gnome-scores.h:
+ 	made the GnomeScore dialog inherit from GnomeDialog
+ 	instead of GtkWindow
+
+1998-07-24  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (emit_event): When there is a grabbed item, the
+	event should also be propagated upwards in the item hierarchy, not
+	just when the current item is actually the grabbed item.
+	(is_descendant): New function that returns whether an item is a
+	descendant of some parent group.
+
+	* gnome-canvas-line.c (gnome_canvas_line_point): Fixed effective
+	width calculation.  Doh.
+
+	* gnome-canvas-util.c (gnome_canvas_polygon_to_point): Fixed typo
+	(y -> py).
+
+	* gnome-canvas-line.c (gnome_canvas_line_translate): Implemented
+	translate method.
+	(recalc_bounds): Doh.  Fixed off-by-one error when growing
+	bounding box.
+
+	* gnome-canvas-util.c (gnome_canvas_get_miter_points): Fixed typo
+	(x2 -> x3).
+
+	* gnome-canvas-line.c (gnome_canvas_line_point): When on the last
+	edge, projecting the butt points depends on whether we are using
+	GDK_CAP_PROJECTING.
+
+Fri Jul 24 02:34:31 1998  John Ellis  <johne bellatlantic net>
+
+	* gnome-dentry-edit.c:
+	(gnome_dentry_edit_sync_display): now update icon select dialog too.
+	(static void gnome_dentry_edit_sync_dentry): if text fields are blank,
+	set the corresponding dentry pointer NULL to avoid blank entries in
+	the .desktop files.
+	(gnome_dentry_edit_set_icon): now no icon sets the dentry->icon pointer
+	NULL instead of "", like the above this avoids blank entries.
+
+Thu Jul 23 00:59:23 CEST 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock: added `first' and `last' icons from gnomecard.
+
+1998-07-22  Havoc Pennington  <hp pobox com>
+
+	* gnome-stock.h: #include "gnome-pixmap.h" rather than
+  	<libgnomeui/gnome-pixmap.h>
+
+	* gnome-pixmap.h: #include gnome-defs.h so that this file
+	can be included without the rest of libgnomeui (e.g. in
+	gnome--)
+
+1998-07-21  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-line.c (gnome_canvas_line_point): Finished
+	implementing distance-to-point method.  It is a bit buggy, I will
+	test it tomorrow.
+
+	* gnome-canvas-util.c (gnome_canvas_get_miter_points): New public
+	function to calculate the butt points of a line segment.
+	(gnome_canvas_polygon_to_point): New public function to compute
+	the distance between a polygon and a point.
+
+	* gnome-canvas-line.c (recalc_bounds): We can only calculate
+	mitered points up to (line->num_points - 3).
+	(gnome_canvas_line_draw): Use pointer arithmetic instead of
+	calculating indices explicitly.
+	(recalc_bounds): Likewise.
+
+Mon Jul 20 22:41:29 1998  John Ellis  <johne bellatlantic net>
+
+	* gnome-dentry-edit.c (gnome_dentry_edit_sync_display): fix segfault
+	when dentry->exec should be empty, but isn't. hmm...
+	(gnome_dentry_edit_set_icon): fix when clearing by setting it "".
+
+Mon Jul 20 17:30:12 1998  Tom Tromey  <tromey cygnus com>
+
+	* gnome-client.c (gnome_client_init): Only reallocate buffer if
+	errno is ERANGE.
+
+Sun Jul 19 23:07:38 1998  George Lebl  <jirka 5z com>
+
+	* gnome-propertybox.c: fix the {set,get}_data calls, they now use
+	  the proper object
+
+1998-07-19  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (gnome_canvas_item_construct
+	gnome_canvas_item_constructv): Removed the unused type parameter.
+
+	* gnome-canvas-line.c (recalc_bounds): Implemented the
+	bounds-calculation routine.
+
+	* gnome-canvas-util.c (gnome_canvas_get_miter_points): New public
+	function to compute the miter points of a line's corner.
+
+	* gnome-canvas-line.c (gnome_canvas_line_destroy): Free line
+	structure's fields properly.
+	(gnome_canvas_line_draw): Optimization: use a static array of
+	points instead of allocating one, when possible.
+
+Sun Jul 19 22:54:12 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-canvas.h, gnome-canvas-c: Added
+	gnome_canvas_item_construct,
+	gnome_canvas_item_constructv
+
+Sun Jul 19 18:06:38 1998  Tom Tromey  <tromey cygnus com>
+
+	Reverted change of July 7:
+	* gnome-client.c (gnome_client_save): Removed.
+	(gnome_client_restart_session): Removed.
+	* gnome-client.h (gnome_client_save,
+	gnome_client_restart_session): Removed.
+
+1998-07-19  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (gnome_canvas_item_raise
+	gnome_canvas_item_lower): Do not accept values less than 1.
+	(gnome_canvas_item_raise_to_top
+	gnome_canvas_item_lower_to_bottom): New public functions to
+	raise/lower an item to the top/bottom of its parent's z-order,
+	respectively.
+
+	* gnome-canvas-rect-ellipse.c (gnome_canvas_rect_draw
+	gnome_canvas_ellipse_draw): Made a little optimization when
+	converting item coordinates to canvas pixel coordinates.
+
+	* Makefile.am: Added gnome-canvas-line and gnome-canvas-util to the
+	sources.
+
+	* gnome-canvas.c (gnome_canvas_item_new gnome_canvas_item_newv):
+	Removed the canvas parameter passed to these functions.  It is not
+	needed, as we can extract the canvas from the parent item parameter.
+
+1998-07-19  Havoc Pennington <hp pobox com>
+
+	* gnome-appbar.h, gnome-appbar.c: Add construct function.
+
+Sat Jul 18 20:25:28 1998  George Lebl  <jirka 5z com>
+
+	* gnome-propertybox.[ch]: cleaned up the way the notebook
+	  page "dirty" flags are handeled, now one should just use
+	  gtk_notebook functions on the ->notebook item in the
+	  struct
+
+Sat Jul 18 20:26:40 1998  John Ellis  <johne bellatlantic net>
+
+        * gnome-dentry-edit.c (gnome_dentry_edit_load_file): changed
+        gnome_desktop_entry_load to unconditional.
+
+Sat Jul 18 12:42:09 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-dialog.c (gnome_dialog_constructv): Use append_button,
+	not append_buttons without NULL termination.
+	(gnome_dialog_construct): Same.
+	(gnome_dialog_new): Reverted last change. Use the construct
+ 	function rather than cut-and-pasting it.
+
+1998-07-18  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.[ch] (gnome_mdi_find_child): made the function
+	public.
+	* gnome-mdi.c: added some g_return_if_*() checks in all the
+	public functions and removed some ancient parts of code that
+	did nothing.
+
+1998-07-17  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* Added gnome-canvas-line.[ch] to the build process.
+
+Fri Jul 17 14:48:14 1998  John Ellis  <johne bellatlantic net>
+
+	* libgnomeui.h:
+        * Makefile.am: Added gnome-dentry-edit.[ch] and
+	gnome-icon-sel.[ch] so they can be used in gmenu. They have been
+	collecting dust, so it's about time :)
+
+1998-07-16  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-line.[ch]: Beginnings of a polyline/curve item for
+	the canvas.  It is not in the compilation process yet.
+
+	* gnome-canvas-util.[ch]: New files with miscellaneous public
+	utility functions for the canvas.
+
+	* gnome-canvas-rect-ellipse.c (gnome_canvas_rect_draw): Fixed
+	off-by-one error when painting unfilled rectangles.  Stupid X
+	weird semantics.
+	(gnome_canvas_ellipse_draw): Likewise for ellipses.  Gotta hate X.
+
+Thu Jul 16 23:14:00 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-about.h, gnome-about.c (gnome_about_new):
+ 	const-correctness.
+	(gnome_about_construct): new function.
+
+1998-07-15  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-image.c (gnome_canvas_image_set_arg): Do not reset
+	the width and height when the image is changed.  This makes
+	updating an existing image easier.
+	(gnome_canvas_image_destroy): Oops, the parent class destroy
+	method was not being called.
+
+	* gnome-canvas.c (gnome_canvas_item_grab): Test the return value
+	of gdk_pointer_grab() before actually setting the grabbed item in
+	the canvas structure.
+	(gnome_canvas_item_raise gnome_canvas_item_lower): New public
+	functions used to raise and lower items in their parent's z-order.
+
+Wed Jul 15 22:31:58 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-popupmenu.h, gnome-popupmenu.c (__GNOME_POPUPMENU_H__):
+ 	added include guards, and LGPL. The author needs to put in the
+	copyright owner, I didn't want to assume FSF.
+
+        * gnome-appbar.c (entry_insert_text_cb): Don't use
+	gtk_editable_get_position with Gtk 1.0
+
+1998-07-15  Raja R Harinath  <harinath cs umn edu>
+
+	* gnome-popupmenu.c (gnome_app_create_popup_menus): Declare `void'
+	return type.
+	(gnome_app_create_popup_menus_custom): Likewise.
+	* gnome-popupmenu.h: Coressponding changes.  Also add
+	{BEGIN,END}_GNOME_DECLS gaurds.
+
+Wed Jul 15 19:14:44 1998  Havoc Pennington  <hp pobox com>
+
+	* TODO: Updated.
+
+1998-07-15  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.h (GnomeCanvas): New field, grabbed_item, points to
+	the item that holds the active pointer grab.
+
+	* gnome-canvas.c (gnome_canvas_item_grab
+	gnome_canvas_item_ungrab): New public functions; perform a mouse
+	grab on the specified item.  These are pretty much like
+	XGrabPointer() and XUngrabPointer(), respectively.
+
+	* gnome-canvas.c (emit_event): If there is a grabbed item, check
+	that it is the current item for emission.
+
+	* gnome-canvas.c (shutdown_transients): New function, remove the
+	idle handler and ungrab the mouse.
+
+	* gnome-canvas.c (gnome_canvas_unmap): Use shutdown_transients().
+	* gnome-canvas.c (gnome_canvas_unrealize): Likewise.
+
+	* gnome-canvas-image.h (GnomeCanvasImage): New need_recalc flag --
+	specifies whether we need to rescale the image when needed.
+
+	* gnome-canvas-image.c (gnome_canvas_image_reconfigure): Just turn
+	on the need_recalc flag, do not actually do the rescaling work here.
+
+	* gnome-canvas-image.c (recalc_if_needed): Rescale the image and
+	fetch the pixmap/mask if needed.
+
+	* gnome-canvas-image.c (gnome_canvas_image_draw): Use recalc_if_needed().
+	* gnome-canvas-image.c (gnome_canvas_image_point): Likewise.
+
+	* gnome-canvas-rect-ellipse.c (gnome_canvas_re_set_arg): Do not
+	recalc bounds unnecessarily.
+	* gnome-canvas-image.c (gnome_canvas_image_set_arg): Likewise.
+
+	* gnome-canvas.c (gnome_canvas_construct): Ref/sink root item.
+	(group_add): Ref/sink item.
+	(group_remove): Unref item.
+	(gnome_canvas_destroy): Unref root item.
+
+Tue Jul 14 22:47:33 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-app.h, gnome-app.c, gnome-dialog.h, gnome-dialog.c:
+	Added "construct" functions. The gnome-dialog one takes a va_list
+	which is kind of weird; if there's a good alternative I'd like
+	to use it instead.
+
+1998-07-13  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (paint): Fixed off-by-one bug in the rectangle
+	coordinates comparison.
+	(gnome_canvas_new): Use the construct function.
+	(gnome_canvas_construct): New public function; constructor useful
+	for derived classes and language bindings.
+
+	The canvas no longer supports unattached item sets, since the
+	application can take care of a list of arbitrary items by itself.
+	Only hierarchical groups are supported now.
+
+	(gnome_canvas_group_new): Removed this function.
+	(group_add): Made static and renamed from gnome_canvas_group_add.
+	(group_remove): Made static and renamed from gnome_canvas_group_remove.
+
+1998-07-13  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c (gnome_mdi_add_view): check if view has been successfully
+	added to the child.
+	* gnome-mdi-child.c (gnome_mdi_child_add_view): check if view has been
+	successfully created.
+
+Sun Jul 12 22:57:55 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-app-util.c: Implementations for interactive appbar
+	and appbar progress bar.
+	* gnome-app-util.h: Change set_progress to use gdouble rather
+	than gfloat.
+	* gnome-appbar.h, gnome-appbar.c: Try implementing interactive
+	minibuffer with a GtkEntry hack. It doesn't work so good; think of
+	it as a prototype.
+	* gnome-types.h: GnomePreferencesType enum
+	* gnome-dialog-util.c: Use set_modal instead of grab_add for modal
+	dialogs; this fixes a bug (the "modal" dialogs weren't).
+
+Fri Jul 10 10:19:38 1998  Tim Janik  <timj gtk org>
+
+	* gnome-app-helper.c (gnome_app_do_menu_creation):
+	* gnome-stock.c (gnome_stock_menu_item):
+	create GtkAccelLabel if GTK_HAVE_ACCEL_GROUP, so accelerators are
+	visible.
+
+Fri Jul 10 08:08:45 1998  Tim Janik  <timj gtk org>
+
+	* gnome-canvas.c:
+ 	(gnome_canvas_item_new):
+	(gnome_canvas_item_set): adapted the argument collection and setting
+ 	code to work with the recent gtk changes.
+
+1998-07-09  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.[ch]: GnomeMDI's create_menubar and create_toolbar
+	signal handlers now receive additional parameter that holds a
+	pointer to the corresponding GnomeApp widget. This should be
+	useful when, say, calling gnome_stock_pixmap_widget(app, ...)
+	in these handlers.
+	* gnome-mdi.c (rootwin_drop): open the new GnomeApp at the
+	position of the mouse pointer.
+
+1998-07-08  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (gnome_canvas_scroll_to): New public function to
+	set the top-left display coordinates of the canvas.
+
+1998-07-07  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (gnome_canvas_group_point): Fixed * and /
+	confusion when coverting coordinates.
+
+	* gnome-canvas-image.c (dist_to_mask): New function, calculates
+	the distance in pixels from a point to a mask.  The point is
+	considered to be "inside" the mask if it is on a white pixel.
+
+	* gnome-canvas.c (emit_event): Convert event coordinates to world
+	coordinates before emitting.
+
+	* gnome-canvas-image.c: Scale the image properly; it wasn't working.
+
+	* gnome-canvas-image.h (GnomeCanvasImage): New fields cwidth and
+	cheight.  These represent the rendered size of the image in pixels.
+
+1998-07-07  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c: fixed updating of active_view and active_child
+	throughout the code.
+	* gnome-mdi.h: made the GNOME_MDI_*_INFO_KEYs public. these allows
+	users to get access of the copies of menu and toolbar templates.
+
+1998-07-06  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas-image.[ch]: New imlib image type for the canvas.
+
+	* libgnomeui.h:
+	* Makefile.am: Added gnome-canvas-image.[ch].
+
+	* gnome-canvas-rect-ellipse.c (gnome_canvas_re_realize):
+	* gnome-canvas-text.c (gnome_canvas_text_realize): Call the
+	reconfigure method instead of the explicit function.
+
+	* gnome-canvas.c (gnome_canvas_item_move): Take care of incomplete
+	item type implementations by warning about unimplemented method.
+	(gnome_canvas_group_draw): Test for presence of draw method.
+	(gnome_canvas_group_point): Test for presence of point method, and
+	use an initialized point_item in case the method is incompletely
+	implemented.
+	(gnome_canvas_update_now): Now we flush the X queue here to ensure
+	repaint.
+
+	* gnome-canvas-text.c (gnome_canvas_text_translate): Implemented
+	translate method for text items.
+
+Tue Jul  7 00:03:21 1998  John Ellis  <johne bellatlantic net>
+
+	* gnome-dentry-edit.c (gnome_dentry_get_dentry): fixed segfault.
+	(gnome_dentry_edit_set_icon): icons now display when changed.
+	* gnome-icon-sel.[ch] (gnome_icon_selection_show_icons): new
+	function, call this after adding all directories so the progress
+	bar updates correctly.
+
+Mon Jul  6 22:46:58 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-appbar.h, gnome-appbar.c: A tentative start at this
+	widget inspired by Mozilla; eventually it will be a lot nicer
+	hopefully.
+        * gnome-app-util.h, gnome-app-util.c (gnome_app_set_status,
+	gnome_app_push_status, gnome_app_pop_status): Removed functions.
+	(gnome_app_progress_update): renamed to set_progress
+	* gnome-app-util.c: Changed to use AppBar
+	* libgnomeui.h, Makefile.am: Add gnome-appbar.[ch]
+	* gnome-app.c: #ifdef GTK_RELIEF_NONE around toolbar relief stuff.
+	* gnome-preferences.c: I mispelled the menubar handlebox config
+	key.
+
+1998-07-06  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-app-helper.c (gnome_app_find_menu_pos): can look for separators.
+	* gnome-mdi.c: some bugfixes.
+
+Sun Jul  5 18:12:24 1998  Tom Tromey  <tromey cygnus com>
+
+	* gnome-client.c (master_environment): Removed DISPLAY, HOME,
+	PATH, LD_LIBRARY_PATH.
+
+1998-07-06  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.[ch]: added child_changed signal and did some extensive
+	code clean-up ;).
+
+1998-07-06  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-app-helper.c (gnome_app_find_menu_pos): added a
+	check if submenu is not NULL.
+	* gnome-mdi.[ch]: removed child_menu_label and all related
+	functions. now all children items are inserted where
+	child_list_path points.
+
+1998-07-05  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (gnome_canvas_update_now): New public function
+	that tells the canvas to redraw itself immediately, instead of
+	waiting for the idle loop.
+
+	* gnome-canvas-text.c: New text item for the canvas, still not finished.
+
+	* libgnomeui.h:
+	* Makefile.am: Added gnome-canvas-text.[ch].
+
+1998-07-05  Changwoo Ryu  <cwryu adam kaist ac kr>
+
+	* gnome-mdi.c (app_create): Fixed a typo.
+
+1998-07-04  Changwoo Ryu  <cwryu adam kaist ac kr>
+
+	* gnome-app-helper.h (GNOMEUIINFO_JUSTIFY_RIGHT): Fixed a wrong
+	order of GnomeUIInfo fields, which caused a compile error.
+
+1998-07-03  Chris Lahey  <clahey umich edu>
+
+	* libgnomeui.h: Check for GDK_HAVE_FULL_CROSSING_EVENT before
+	including gnome-canvas.h and gnome-canvas-rect-ellipse.h.
+
+Fri Jul  3 16:51:31 CDT 1998  Richard Hestilow  <hestgray ionet net>
+
+	* gnome-app.c (gnome_app_set_toolbar) : Added check for
+	Gtk+ support of relief features. (GTK_HAVE_RELIEF_STYLE)
+
+Mon Jun 29 14:10:48 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-preferences.h, gnome-preferences.c
+	(gnome_preferences_get_toolbar_relief,
+	gnome_preferences_set_toolbar_relief): Whether the toolbar buttons
+	have the beveled edge.
+	* gnome-app.c (gnome_app_set_toolbar): Turn off the toolbar button
+	relief if user requested it.
+	* gnome-preferences.c (gnome_preferences_load): Oops, forgot to
+	push a new prefix for the GnomeApp stuff, it was being saved under
+	Dialog prefs.
+	* gnome-dialog.h, gnome-dialog.c (gnome_dialog_run_and_die):
+	Renamed to run_and_destroy - run_and_die was cute at 2 am, but
+	probably not a good name. ;-)
+
+1998-07-02  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gtk-socket.h, gtk-plug.h: Fix prototypes
+
+1998-07-02  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* Makefile.am (INCLUDES): Cosmetic cleanups.
+
+	* gnome-canvas.c (gnome_canvas_destroy): Use canvas_parent_class,
+	not item_parent_class on the destroy method.
+
+Thu Jul  2 14:12:14 CEST 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock*: new icons by tigert.
+	stock_demo.c: added search-replace sample icons
+
+1998-07-02  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.c: the child-specific menu callbacks no longer
+	get their GnomeMDIChild pointer passed as user data.
+	gnome_mdi_get_active_view() (or mdi->active_view) and
+	VIEW_GET_CHILD() macro should be used to get the pointer
+	to the GnomeMDIChild in callbacks.
+
+1998-07-02  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (gnome_canvas_item_shutdown): Implemented
+	shutdown method, mostly stolen from GtkWidget.
+	(gnome_canvas_item_set): Request redraw and repick.
+	(gnome_canvas_item_setv): likewise
+	(gnome_canvas_item_move): likewise
+
+	Implemented reference counting for items.  It is still missing in
+	several places.
+
+1998-07-01  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c (gnome_canvas_group_child_bounds): Now can either
+	add an item's bounds to the group's bounds, or rebuild the entire
+	group's bounds recursively.
+	(gnome_canvas_item_w2i): New function to convert from world
+	coordinates to item coordinates.
+
+	* gnome-canvas.c (gnome_canvas_group_translate): Implemented
+	translate method.
+
+	* gnome-canvas-rect-ellipse.c (recalc_bounds): Whoops, we were
+	doing everything in world coordinates.  Now it takes item
+	coordinates into account.
+	(gnome_canvas_re_translate): Implemented translate method.
+	(recalc_bounds): Don't forget to notify parent that our bounds changed.
+
+1998-07-01  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-app-helper.[ch]: changed
+	"typedef struct _GnomeUIBuilderData *GnomeUIBuilderData" to
+	"typedef struct _GnomeUIBuilderData GnomeUIBuilderData" and
+	patched the functions using this. This will probably break some
+	apps, but changes are trivial. It seems more consistent this way.
+
+Tue Jun 30 22:02:34 PDT 1998 Manish Singh <yosh gimp org>
+
+	* Makefile.am: added back in the optional gnome-canvas sources
+	so they get installed too
+
+1998-06-30  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c:
+	* gnome-canvas.h:
+	* gnome-canvas-rect-ellipse.c:
+	* gnome-canvas-rect-ellipse.h: Here is the new canvas that uses
+	GtkObjects for the canvas items.  It supports a hierarchical
+	organization of items, and arbitrary item sets as well.  This is
+	still a work in progress.  Please see the test-gnome demo for
+	information on how to use this beast.
+
+Tue Jun 30 16:13:19 1998  Tom Tromey  <tromey cygnus com>
+
+	* gnome-color-selector.c: Include <stdio.h>.
+	* gnome-stock.c: Include libgnome/gnome-i18nP.h.
+	* gnome-mdi.c: Include libgnome/gnome-i18nP.h.
+	* gnome-dateedit.c: Include libgnome/gnome-i18nP.h, <stdio.h>.
+	* gtk-ted.c: Include libgnome/libgnomeP.h.
+	* gnome-startup.c: Include libgnome/libgnomeP.h.
+	* gnome-pixmap.c: Include libgnome/libgnomeP.h.
+	* gnome-number-entry.c: Include libgnome/libgnomeP.h.
+	* gnome-init.c: Include libgnome/libgnomeP.h.
+	* gnome-font-selector.c: Include libgnome/libgnomeP.h.
+	* gnome-entry.c: Include libgnome/libgnomeP.h.
+	* gnome-dentry-edit.c: Include libgnome/libgnomeP.h.
+	* gnome-client.c: Include libgnome/libgnomeP.h.
+	* gnome-calculator.c: Include libgnome/libgnomeP.h.
+
+1998-06-30  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-app-helper.[ch]: Modified menu and toolbar creation functions
+	to support GNOME_APP_UI_BUILDER_DATA items that supply GnomeUIBuilderData
+	structure to use with the following entries until the end of the current
+	GnomeUIInfo array or next GNOME_APP_UI_BUILDER_DATA item. BuilderData
+	structures supplied in this manner do not affect subtrees [initial structures
+	created by or supplied to appropriate gnome_app_helper__create_*() calls are
+	used for this] or other GnomeUIInfo arrays at the same level.
+
+Tue Jun 30 17:14:31 1998	Jonathan Blandford <jrb redhat com>
+	* gnome-app-helper.c: Modified gnome_app_add_radio_menu_entries()
+	to handle separators.
+
+1998-06-29  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.[ch]: dnd types now differ for each process using MDI.
+	this prevents false impression that dragging a notebook page from
+	MDI of one process to MDI of another will work.
+
+1998-06-29  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-entry.c: Remove the prefix_list get/set stuff.
+
+1998-06-29  Nuno Ferreira <nmrf rnl ist utl pt>
+
+	* gnome-file-entry.c: Include config.h, do not include
+	libgnomeui/libgnomeui.h, instead include libgnome/gnome-i18nP.h
+
+Mon Jun 29 03:04:30 1998  Havoc Pennington  <hp pobox com>
+
+	* TODO: Updated a little.
+
+Mon Jun 29 02:58:15 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-preferences.h, gnome-preferences.c
+	(gnome_preferences_get_toolbar_handlebox,
+	gnome_preferences_set_toolbar_handlebox,
+	gnome_preferences_get_menubar_handlebox,
+	gnome_preferences_set_menubar_handlebox): New functions.
+
+	* gnome-app.c (gnome_app_set_menus): Obey preferences for
+	handlebox.
+	(gnome_app_set_toolbar): Obey handlebox prefs.
+
+Mon Jun 29 02:52:10 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-dialog.h, gnome-dialog.c (gnome_dialog_run): Take out the
+	hide stuff.
+	(gnome_dialog_run_and_hide): Do what gnome_dialog_run used to do.
+	(gnome_dialog_run_and_die):  Run and then destroy the dialog.
+	(gnome_dialog_button_connect_object): Someone requested this.
+
+
+Sun Jun 28 10:50:01 1998  Tom Tromey  <tromey cygnus com>
+
+	* libgnomeui.h: Include libgnome/gnome-parse.h, so libgnomeui.h
+	can be included without first including libgnome.h.
+
+Mon Jun 29 00:35:47 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-app-util.h, gnome-app-util.c: Implementation for all
+	functions except interactive statusbar stuff. However,
+	ui-properties doesn't allow you to turn on interactive statusbar
+	yet, so all the functions should be usable if possibly buggy.
+	Also, many of the functions changed to return the dialog created.
+	* gnome-app.c: Initialize the statusbar member to NULL.
+	* gnome-preferences.h, gnome-preferences.c: Add statusbar
+ 	vs. dialog options.
+	* libgnomeui.h: Add gnome-app-util.h
+	* Makefile.am: Add gnome-app-util.h, gnome-app-util.c
+
+1998-06-28  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-app.c (make_button_toolbar): i18n strings marked;  Added
+	code that still does not work for configuring toolbar settings (we
+	should configure pictures/text-pictures/text-only/tooltips).
+
+	* gnome-client.c (gnome_client_new_default): Until someone
+	documents what is the procedure to use the new client stuff, I am
+	removing this warning, as it apparently does the right thing.
+
+1998-06-28  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi-child.[ch]: removed declaration of non-existing
+	gnome_mdi_get_views() and removed some other stale stuff.
+
+1998-06-28  Carsten Schaar  <nhadcasc fs-maphy uni-hannover de>
+
+	* gnome-scores.c: Included 'gnome-i18nP.h' instead of 'gnome-i18n.h'.
+
+1998-06-24  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-init.c: Add a new argument handled by Gtk+.  Reindent.
+
+1998-06-23  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.[ch]: new member child_menu_label and function
+	for setting it, so MDI doesn't always display Children.
+
+Sun Jun 21 15:09:04 CEST 1998  Eckehard Berns  <eb berns pirma de>
+
+	* gnome-pixmap.[ch] (gnome_pixmap_new_from_imlib): new function
+	(gnome_pixmap_new_from_imlib_at_size): new function
+	(gnome_pixmap_load_imlib): new function
+	(gnome_pixmap_load_imlib_at_size): new function
+	(finish_load): changed to accept `int destroy', which determines
+	whether the GdkImlibImage should be destroyed or not.
+
+	The new functions make it possible to pass valid GdkImlibImages for
+	GnomePixmap creations/updates.
+
+1998-06-20  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.c: Fixed bug where it would crash if you clicked
+	on an empty icon list.  Thanks to James Henstridge
+	<james quoll daa com au> for the patch.
+
+Thu Jun 18 23:52:04 1998  George Lebl  <jirka 5z com>
+
+	* gnome-init.c: set up config autosyncing during gnome_init
+
+	* gnome-entry.c: don't sync every time we want to do a set,
+	  we can realy on the autosync to do it for us, this should
+	  reduce cpuusage.
+
+1998-06-18  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-number-entry.c: Fixup includes.
+
+1998-06-18  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-app-helper.c: changed gnome_app_add_[radio|help]_menu_entries() to
+	return new pos so that insertion works properly.
+
+Thu Jun 18 02:47:26 1998  George Lebl  <jirka 5z com>
+
+	* gnome-number-entry.[ch]: new entry type modeled after file
+	  entry, but for numbers. has a "browse" dialog with a
+	  calculator.
+
+	* gnome-calculator.[ch]: add some new functions for more control
+
+Thu Jun 18 00:40:27 1998  George Lebl  <jirka 5z com>
+
+	* gnome-entry.c: use the new gnome_config prefix list functions
+	  so that gnome_entry doesn't interfere with app's prefix stack
+
+Tue Jun 16 15:35:01 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-dentry-edit.h, gnome-dentry-edit.c, gnome-icon-sel.h,
+	gnome-icon-sel.c: New files.
+	* gnome-pixmap.h, gnome-pixmap.c (gnome_pixmap_new_from_file,
+	gnome_pixmap_new_from_file_at_size, load_file,
+	gnome_pixmap_load_file, gnome_pixmap_load_file_at_size):
+	const char * for filename arguments.
+
+Sun Jun 14 13:46:09 1998  Tom Tromey  <tromey cygnus com>
+
+	* Makefile.am (INCLUDES): Look in intl source and build
+	directories.
+
+Sat Jun 13 16:46:18 1998  Tom Tromey  <tromey cygnus com>
+
+	* gnome-client.c (arguments): Fixed typo.
+
+1998-06-12  Carsten Schaar  <nhadcasc fs-maphy uni-hannover de>
+
+	* gnome-client.c: (array_insert_arg): Removed.
+	(master_environment): New array.  Lists all environment variables,
+ 	that will set automatically to the master client.
+	(gnome_client_init): Sets the environment variables listed in
+ 	'master_environment' and the current_directory now.
+	(gnome_client_set_current_directory): Sets only one environment
+ 	variable instead of all.
+	(client_set_prop_from_string): Include the trailing '\0' character
+ 	when sending strings.
+
+	* gnome-client.h: Changed declaration of
+ 	'gnome_client_set_environment'.  This function now only sets one
+ 	environment variable and not the hole environment.
+	(struct _GnomeClient): member environment now of type GList.
+
+1998-06-10  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-calculator.c:
+	* gnome-properties.c: #include <config.h>
+
+	* gnome-pixmap.[ch]: Removed the *old* gnome_pixmap_* functions
+	that predated the GnomePixmap widget.
+
+Wed Jun 10 21:19:25 EDT 1998 Gregory McLean <gregm comstar net>
+
+	* gnome-dialog-util.c : #include <config.h> (seeing as
+	we went through all the trouble of detcecting all this stuff...
+
+1998-06-10  Raja R Harinath  <harinath cs umn edu>
+
+	* Makefile.am (EXTRA_libgnomeui_la_SOURCES): Add gnome-canva-*
+	here.  These files are conditionally built.
+
+Wed Jun 10 14:19:39 EDT 1998 Gregory McLean <gregm comstar net>
+
+	* gnome-canvas-* stuff gets automaticly turned on and off
+	  depending on which gtk you build against. As I'm not an auto*
+	  guru I'm fairly sure its not bullet proof but it works for me.
+
+Wed Jun 10 13:07:09 EDT 1998 Gregory McLean <gregm comstar net>
+
+	* Wheee libgnomeui now compiles (with the exception of the
+	  canvas stuff) under 1.0.x again. It also compiles under 1.1
+	  for thoose of you that like to bleed. Please please if you
+	  add code that _requires_ gtk 1.1 shield it with HAVE_DEVGTK
+	  so us boring folks can continue to get stuff done.
+
+Wed Jun 10 00:45:36 1998  Tom Tromey  <tromey cygnus com>
+
+	* gnome-init.c (our_gtk_options): Added help separator entry.
+
+Mon Jun  8 20:11:52 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-dateedit.c: #include <stdlib.h> for atoi.
+	(day_selected): use g_snprintf, sprintf was undeclared.
+
+	* gnome-mdi-child.c (gnome_mdi_child_destroy): Use g_free, free
+	was undeclared.
+	(gnome_mdi_child_set_name): Use g_strdup, g_free.
+
+	* gnome-mdi-child.h: Declare gnom_mdi_child_get_type()
+
+	* gnome-mdi.c: #include "libgnome/gnome-util.h"
+	Removed a bunch of unused variables.
+	(app_set_title): Use g_copy_strings in place of strcat
+	(app_set_active_view): Slight rewrites for "assignment in
+	conditional" warning.
+	(top_add_view): Same.
+	(gnome_mdi_add_child): Use return_val_if_fail, for checks.
+	(gnome_mdi_remove_child): Same, and a couple unused variables.
+
+	* gnome-stock.c (gnome_pixmap_button): Use g_snprintf, fixes
+	warning about undeclared sprintf.
+
+	* gtkdial.c: Use return_val_if_fail when function returns
+	something. Removed a couple of unused variables.
+
+Mon Jun  8 19:27:17 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-less.h, gnome-less.c: Changed error handling; rather than
+	have the widget report errors, return FALSE from show functions if
+	there is an error and set errno if applicable.
+	(gnome_less_show_file): add return value.
+	(gnome_less_show_command): add return value.
+	(gnome_less_show_filestream): add return value. Use fgets instead
+	of fread because a book I have here says fread isn't portable. (?)
+	(gnome_less_show_fd): New function, for file descriptors.
+	(gnome_less_write_file): New function, writes contents to a
+	filename.
+	(gnome_less_write_fd): New, for file descriptor.
+	(gnome_less_set_font): Put in header, no longer static. Set
+	arbitrary font.
+	(gnome_less_set_fixed_font): allow turning fixed font on and off.
+	(gnome_less_reshow): Reshow contents with current font, etc.
+	(gnome_less_fixed_font): Deprecated warning.
+
+Mon Jun  8 19:22:03 1998  Havoc Pennington  <hp pobox com>
+
+	 * gnome-app-helper.h (GNOMEUIINFO_JUSTIFY_RIGHT): New macro for a
+	 struct with everything 0/NULL and type
+	 GNOME_APP_UI_JUSTIFY_RIGHT. I hope this is right.
+
+Mon Jun  8 19:19:24 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-dialog.h: #include <gtk/gtkaccelgroup.h>
+
+Mon Jun  8 19:10:24 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-geometry.h, gnome-geometry.c (gnome_geometry_string):
+	New function gets a geometry string which describes a GdkWindow.
+	Code comes from gnomecal.
+	(gnome_parse_geometry): Use the glib types instead of standard C
+	types, since I had to include gdk anyway for GdkWindow. Also, fix
+	spelling of a variable name.
+
+1998-06-08 Arturo Espinosa Aldama <arturo nuclecu unam mx>
+
+	* gnome-app-helper.c (gnome_app_do_menu_creation): The support for
+	pixmapped menus was broken (if you tried to put menus with pixmaps
+	of your own, you got warnings). This patch fixes it.
+
+1998-06-08  Chris Lahey  <clahey umich edu>
+
+	* gnome-less.h:
+	* gnome-dns.c: Included stdio.h so that it would compile
+	correctly.
+
+1998-06-08  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gtkdial.[ch]: added view_only member and gtk_dial_set_view_only()
+	function that makes gtkdial not respond to mouse events in case
+	it is only used as display.
+
+1998-06-05  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-list.c (draw_rounded_box): Now we show marked files
+	with a rounded box instead of a box.
+
+Sun Jun 07 17:24:15 1998  George Lebl  <jirka 5z com>
+
+	* gnome-mdi.h,gnome-mdi-child.h: fix the cplusplus stuff,and
+	  make it use GNOME_(BEGIN|END)_DECLS
+
+1998-06-07  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-mdi.[ch]: a configurable MDI object.
+	see gnome-hello/gnome-hello-7-mdi.c or gnome-utils/ghex for an
+	example of its use.
+ 	* gnome-mdi-child.[ch]: an MDI child object
+	* libgnomeui.h: includes above headers
+	* Makefile.am: changed to include above sources in libgnomeui
+
+1998-06-07  Carsten Schaar  <nhadcasc fs-maphy uni-hannover de>
+
+	* gnome-client.c: Inclueded 'stdarg.h'.
+	(gnome_client_object_init): Preset 'static_args'.
+	(gnome_client_add_static_arg): New function.  Enables one to set
+ 	some command line options, which will always be added to the clone
+ 	and restart command.
+	(gnome_real_client_destroy): Free 'static_args'.
+	(client_set_prop_from_array_with_arg): Includes static arguments
+ 	into the command line, before sending them to the session manager.
+	(client_set_prop_from_glist): New function. Sets properties from a
+ 	list of string (Not yet used).
+
+	* gnome-init.c: Included 'libgnomeui/gnome-client.h'. New variable
+ 	'client'.
+	(our_gtk_parse_func): Adds the parsed gtk command line options as
+ 	static arguments to the master client.
+
+	* gnome-client.h: Added 'gnome_client_add_static_arg' declaration.
+	(struct _GnomeClient): Added member 'static_args'.
+
+1998-06-06  Carsten Schaar  <nhadcasc fs-maphy uni-hannover de>
+
+	* gnome-init.c (gnome_init): Added 'gnome_client_init' call.
+
+	* gnome-client.c: New variable 'gnome_client_auto_connect_master',
+ 	'cloned_client', 'sm_cloned_id_arg_name' and
+ 	'cloned_id'. 'default_client' renamed to 'master_client'. Replaec
+ 	'array_free' with 'gnome_string_array_free'.
+ 	(gnome_client_object_init): Renamed 'gnome_client_init' function.
+	(master_client_connect): Renamed 'default_client_connect'
+ 	function.
+	(master_client_disconnect): Renamed 'default_client_disconnect'
+ 	function.
+	(gnome_client_init): Renamed 'default_client_init' function.
+	(arguments): Added 'sm-cloned-id' and 'sm-disable' option.
+	(client_set_prop_from_array_with_arg): New function.  Sets a
+ 	property from a string array and adds a additional command to the
+ 	commandline.
+	(gnome_master_client): New function.
+	(gnome_cloned_client): New function.
+	(gnome_client_new_default): Added warning message.
+	(client_parse_func): Added setting of restart and clone command.  Connecting to session manager when receiving ARGP_KEY_FINI.
+	(gnome_client_disable_master_connection): New function.
+
+	* gnome-client.h: New 'gnome_client_disable_master_connection',
+ 	'gnome_master_client' and 'gnome_cloned_client' declaration.
+
+Thu Jun  4 14:53:55 CEST 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-lamp.h: new function gnome_lamp_set_window_type.
+
+	* gnome-lamp.c (gnome_lamp_set_window_type): new function to set the
+	wm hints for lamps/beacons.
+	(gnome_lamp_set_win_app_state): new static function to set the
+	WIN_APP_STATE window property. This is an implementation of raster's
+	proposal as found in the E sources (gnome.c).
+
+1998-06-03  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* libgnomeui.h:
+	* Makefile.am:
+	* gtkdial.[ch]: moved gtkdial from gnome-admin/gxsnmp/widgets
+ 	to libgnomeui.
+
+1998-06-02  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* libgnomeui.h:
+	* Makefile.am: Removed the canvas stuff from these files, for the
+	upcoming release which will use gtk-1.0.4.  The canvas needs the
+	development branch of Gtk.
+
+1998-06-02  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-app-helper.c (gnome_app_find_menu_pos): set *pos to 0 if
+	path is emtpy and check whether menuitem's child is NULL in order
+	not to SIGSEGV at separators in menus. Also added a call to
+	gtk_widget_queue_resize() on the parent widget at the end of
+	insertion or removal!
+
+1998-06-01  Seth Alves  <alves twitch hungry com>
+
+	* gnome-app-helper.c (gnome_app_find_menu_pos): if path is empty,
+	return parant, rather than fail
+
+Tue Jun  2 00:50:56 CEST 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-lamp.c: added sequence support.
+
+Mon Jun  1 17:48:28 CEST 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-lamp.c (gnome_lamp_set_pixmap_color): use imlib's best color
+	match for color calculation in colormap modes.
+
+1998-06-01  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-app-helper.[ch]: added gnome_app_remove_menus() and
+	gnome_app_insert_menus_* routines. For the time being they
+	dont set or remove accelerators, since I had no idea how to
+	handle this - especially removal.
+
+1998-05-31  Carsten Schaar  <nhadcasc fs-maphy uni-hannover de>
+
+	* gnome-about.c: Include "libgnome/gnome-i18nP.h" instead of
+ 	"libgnome/gnome-i18n.h".
+
+	* gnome-client.h: Added 'gnome_client_get_config_prefix' and
+ 	'gnome_client_get_global_config_prefix' declarations.
+	(struct _GnomeClient): New member 'config_prefix' and
+ 	'global_config_prefix'.
+
+	* gnome-client.c: Added 'program_invocation_short_name'
+ 	declaration.  Added 'client_unset_config_prefix' declaration.
+	(gnome_client_get_type): Changed return value of
+ 	'gnome_client_get_type' to 'GtkType'.
+	(gnome_client_init): Preset '[global_]config_prefix'.
+	(gnome_real_client_destroy): Released '[global_]config_prefix'.
+	(gnome_client_connect): Added some calls to unset config prefix.
+	(gnome_client_set_program): Likewise.
+	(gnome_client_set_id): Likewise.
+	(gnome_client_get_previous_id): Added check, if the client
+ 	parameter really is client.
+	(gnome_client_get_config_prefix): New function.  Calculates a
+ 	config prefix depending on program name and client id.
+	(gnome_client_get_global_config_prefix): New function.  Calculates a
+ 	config prefix depending on program name.
+	(client_unset_config_prefix): New function.
+
+1998-05-27  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-app-helper.h: added new GnomeUIInfoType
+	GNOME_APP_UI_JUSTIFY_RIGHT that notifies app-helper routines that
+	all the menu items from now on should be right justified. This
+	should prove useful for adding help menu to the menubar.
+
+	* gnome-app-helper.c (gnome_app_do_menu_creation): take care
+	of handling GNOME_APP_UI_JUSTIFY_RIGHT GnomeUIInfoType.
+
+1998-05-27  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-canvas.c gnome-canvas.h: The GnomeCanvas widget!  This is
+	still not finished and is not ready for general consumption.  I
+	need it on cvs to hack on it a bit while being at the Linux Expo :-)
+
+	* gnome-canvas-rect-ellipse.c: Rectangle and ellipse primitives
+	for the canvas; still not finished.
+
+	* Makefile.am: Added the canvas files to the listing.
+
+1998-05-25  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-list.c (relayout_icon), gnome-icon-list.h: add
+	desired_text_width.
+
+1998-05-25  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.c (gnome_icon_layout_text): I must be stupid or
+	something.  Fixed the bug that caused the ".\n." effect; it was
+	the same bug that put separators on the new row instead of on the
+	row they split.
+
+Mon, 25 May 1998 10:55:37 +0200 Paolo Molaro <lupus debian org>
+
+	* gtkspell.[ch]: spell-check widget using ispell.
+
+Sat May 25  1:58:00 1998  Cesar Miquel  <miquel df uba ar>
+
+	* gnome-about.c Applied a patch provided by Changwoo Ryu
+	<cwryu adam kaist ac kr> that makes the gnome_about_new's
+	"logo" argument more convenient to use. It:
+
+ 		1) Uses gdk_imlib.  Goodbye, xpm.
+		2) Find the logo file in the pixmap
+		   directory (by gnome_pixmap_file).
+
+Sat May 23 21:55:41 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-dialog.c (gnome_dialog_run_modal): Don't call set_modal,
+	leave the dialog in the same state we came to it. Don't call
+	close_hides, leave close behavior up to the caller. Connect a
+	handler to the "close" signal which refuses to close the dialog
+	unless a button has been clicked. Thus -1 will never be
+	returned. Remove signal handlers when a button is clicked. Call
+	gtk_main_quit() when a button is clicked to avoid piling up
+	gtk_main's and cause the function to actually return. Call
+	gtk_widget_show on the dialog if it has not yet been shown. Use a
+	define instead of -1 for invalid button.
+	(gnome_dialog_set_modal): Make it work if the widget has already
+	been shown.
+
+	* gnome-dialog.h: Updated a couple of comments.
+	(GnomeDialogButton): Removed unused typedef.
+
+
+Fri May 22 23:26:11 1998  Tom Tromey  <tromey cygnus com>
+
+	Some -Wall fixes:
+	* ted_demo.c (main): Return 0.
+	* gtkcalendar.c (gtk_calendar_header_button): Removed unused
+	decl.
+	* gtk-ted.c (gtk_ted_add): Removed unused variable.
+	(parent_class): Removed.
+	* gnome-client.c (gnome_client_new_without_connection): Removed
+	unused variable.
+	* gnome-about.c (gnome_about_repaint): Removed unused variable.
+	(gnome_about_display_comments): Removed unused label.
+	(gnome_fill_info): Removed unused variables.
+	(gnome_about_new): Likewise.
+	* gnome-net.c (net_socket_new): Removed unused variable.
+	* gnome-init.c: Include gnome-preferences.h.
+	* gnome-font-selector.c (gnome_font_selector_get_selected):
+	Removed unused variables.
+	(text_points_callback): Commented out for now.
+	* gnome-geometry.c (gnome_parse_geometry): Removed unused
+	variable.
+	* gnome-dns.c (gnome_dns_create_server): Removed unused variable.
+	(server_init_cnt): Removed.
+	* gnome-dialog.c (gnome_dialog_run_modal): Use
+	g_return_val_if_fail.  Removed unused variable.
+	* gnome-color-selector.c (gnome_color_selector_get_button): Use
+	g_return_val_if_fail.
+	* gnome-app.c (gnome_app_class_init): Removed unused variable.
+	(gnome_app_add): Commented out.
+
+1998-05-22  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-init.c (our_gtk_parse_func): Use gtk_rc_set_image_loader
+	only for Gtk 1.1 compilations.  This allows people to compile
+	parts of gnome with Gtk 1.0.
+
+1998-05-21  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gtkcalendar.c (gtk_calendar_thaw): Remove warnings
+	Make the internal color names static.
+
+	* gnome-stock.c (gnome_stock_transparent_window): New routine for
+	creating toplevel shaped popup windows from the stock icons.
+	These are used to make DnD icons easily availble to applications
+	that need them.
+
+	New icons: imlib_not and imlib_multiple_file: The "can not drop
+	here" and the "various files are being dragged".
+
+Thu May 21 18:43:14 CEST 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock.c (build_disabled_pixmap): destroy the GC when done
+
+	* gnome-lamp.[ch]: new files. Proposal for the basic implementation of
+	lamps/beacons.
+
+1998-05-21  John Ellis  <johne bellatlantic net>
+
+	* gnome-pixmap.h: changed char *data in
+	gnome_pixmap_new_from_rgb_d_at_size to unsigned char *data.
+	* gnome-pixmap.c: added missing definition of
+	GtkWidget *gnome_pixmap_new_from_rgb_d_at_size(...).
+
+1998-05-20  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.c (gnome_icon_paint_text): Added justification
+	parameter.  This is generally useful to have.  It is also required
+	for when the icon list is in GNOME_ICON_LIST_TEXT_RIGHT mode.
+	(draw_icon): Use the proper justification for text.
+	(ilist_signals): Strange, this baby did not have a type (guint).
+
+Wed May 20 17:30:19 CEST 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-pixmap.[ch] (gnome_pixmap_new_from_gnome_pixmap): new
+	function. I need that to get a copy of a pixmap to work with.
+
+	* gnome-stock.c (gnome_pixmap_button): added check for GnomePixmap to
+	build a GnomeStockPixmapWidget to get the functionality to gray it out
+	if it's unsensitive.
+
+	* gnome-stock.[ch]: added GNOME_STOCK_PIXMAP_TYPE_GPIXMAP to be able
+	to use GnomePixmaps as stock pixmaps.
+	(gnome_pixmap_button): added check for ButtonsUseLabels (don't know if
+	this is usefull though).
+
+	* gnome-dialog.c (gnome_dialog_append_button): use
+	gnome_button_can_default.
+
+1998-05-20  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.c (relayout_icon): New function; recals the text
+	layout info field of an icon.
+	(reassign_max): Recomputes the max pixmap/text width/height of the ilist.
+	(finish_recalc): Calculates the max icon width/height of the ilist.
+	(recalc_max_icon_size_1): Reimplemented in terms of the three
+	functions above.
+	(recalc_max_icon_size): Reimplmented in term of the three
+	functions above.
+
+	* gnome-icon-list.h (GnomeIconList): New fields that store the max
+	text width/height.  They are needed for the new text layout stuff.
+
+	* gnome-icon-list.h (GnomeIconTextInfo): Renamed structure.
+
+	* gnome-icon-list.c (gnome_icon_layout_text): Rewrote function to
+	handle separators/max_width/confine parameters.
+
+	* gnome-icon-list.c (gnome_icon_paint_text): Now it only takes the
+	upper-left position where to paint the text block.
+
+	* gnome-icon-list.c (draw_icon): Fixed to calculate text position correctly.
+
+1998-05-19  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-icon-list.c (get_icon_num_from_xy): properly return
+	on_spacing=TRUE and *num=-1 when a column without an icon in last
+	row is clicked.
+	(adjust_scrollbars): now properly adjusts scrollbars when the
+	viewed area expands beyond icon list's width or height due to
+	some change.
+
+Tue May 19 21:38:15 CEST 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock.c (gnome_pixmap_button): New function. Returns a button
+	with a pixmap and label. Added default size to the created button.
+	(gnome_stock_menu_item): Use gnome_config_get_bool.
+	(gnome_pixmap_button): Likewise.
+
+	* gnome-stock.[ch]: added some `const' to `char *'s.
+
+1998-05-18  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.c (gnome_icon_layout_text): Now we can configure
+	the separators and confinement status of the wrapped text.
+
+	* gnome-icon-list.h: Added prototype for gnome_icon_list_append_imlib.
+
+	* gnome-icon-list.c (sync_selection): Removed warnings by using the
+	GPOINTER_TO_INT and GINT_TO_POINTER macros.
+	(gnome_icon_list_set_separators): New function; lets you set the
+	characters where it is fine to split the icon text rows.
+
+1998-05-18  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-client.c (gnome_client_class_init): Use GTK_RUN_LAST for
+	the save_yourself signal
+
+	* gnome-icon-list.c (gnome_icon_paint_text,
+	gnome_icon_layout_text, gnome_icon_text_info_free): moved from
+	gmc's gtrans.c code here.  Some more code reuse.
+	(gnome_icon_layout_text): The split routine should be improved to
+	split on various other characters to give us a better layout than
+	we currently have.
+
+	Implemented icons with wrapped text.
+
+Sun May 17 16:00:21 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-dialog.h, gnome-dialog.c (gnome_dialog_editable_enters):
+	New function, call this if your dialog contains an editable to
+	keep the editable from disabling the Return keyboard shortcut
+	(assuming you don't want to disable it).
+	* gnome-dialog-util.c (request_dialog): Use the new function.
+
+Sun May 17 12:01:55 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-preferences.h, gnome-preferences.c: Use access functions
+	instead of global struct.
+	* gnome-dialog.c: Use the access functions.
+
+Sun May 17 02:29:14 1998  Havoc Pennington  <hp pobox com>
+
+	* Makefile.am, libgnomeui.h: Include gnome-preferences. Cross
+	fingers.
+	* gnome-dialog.c: Don't put libgnomeui/ in front of #includes. Use
+	gnome-preferences setting for button position.
+	* gnome-init.c (gnome_init): gnome_preferences_load()
+	* gnome-preferences.c: Add trailing slash to section names;
+	gnome-config is a little finicky about this. Use array instead of
+	defines for possible button style options.
+	(gnome_preferences_load): Use a loop to load
+	the styles, instead of a long if-else thing.
+	(gnome_preferences_save): Implemented just the dialog button
+	styles part.
+
+Sat May 16 16:02:38 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-actionarea.c: Add annoying warning. I am deleting this
+	in a week or so.
+	* gnome-color-selector.c: Added "FIXME no copyright". Use
+	g_return_if_fail throughout instead of g_assert, for consistency
+	with rest of lib.
+	* gnome-dateedit.c: Add some g_return_if_fail checks.
+	* gnome-pixmap.c: g_return_if_fail
+	* gnome-properties.c: #include gnome-config, don't #include
+	action-area. Add a couple g_return_if_fail checks.
+	(gnome_property_configurator_setup): Don't show the property box
+ 	in setup; it needs to be shown *after* the pages are added to
+ 	it. This makes desktop-properties come up much more nicely.
+	(gnome_property_configurator_destroy): Don't destroy the property
+ 	box in _destroy(); it destroys itself on close.
+
+Sat May 16 02:12:43 1998  Tom Tromey  <tromey cygnus com>
+
+	* gnome-preferences.c (gnome_preferences_load): Removed useless
+	prefix push/pop.
+	(UI_APPNAME): Changed value to start with "Gnome".
+	(GENERAL): Likewise.
+	(DIALOGS): Likewise.
+	(_PROPERTY_BOX_BUTTONS): Removed leading "/".
+	(DIALOG_BUTTONS_STYLE_KEY): Likewise.
+	* gnome-stock.c (stock_button_from_entry): Use Gnome and not
+	GnomeStock as file name in config key.
+	(gnome_stock_menu_item): Likewise.
+	(accel_hash): Likewise.
+	(gnome_stock_menu_accel_dlg): Likewise.
+
+1998-05-15  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-dateedit.c: Add support for 12/24 hour format.
+
+1998-05-15  Federico Mena  <federico nuclecu unam mx>
+
+	* gnome-icon-list.c (gnome_icon_list_init): Connect to the
+	"changed" signal of the adjustments as well, otherwise we will not
+	reset stuff properly when clearing the icon list.
+
+1998-05-15  Jaka Mocnik <jaka mocnik kiss uni-lj si>
+
+	* gnome-icon-list.c (gnome_icon_list_button_press): pressing non-left mouse button
+	on a selected icon now calls toggle_icon() immediately and not upon button release.
+	* gnome-icon-list.c (toggle_icon): changed behavior so that only left mouse button
+	can SHIFT- or CTRL-select and that pressing a non-left button on a selected icon does
+	not unselect other selected icons. this seems more appropriate to me.
+	* gnome-icon-list.c: changed all initializations of last_selected member from -1 to 0.
+	This prevents segfaults when SHIFT-selecting before any icons have been selected.
+
+Thu May 14 12:31:28 CEST 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-dialog.c (gnome_dialog_close): changed type of close_handled
+	to gint.
+
+1998-05-14  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-list.c: Added dirty flag to the gnome icon list
+
+Wed May 13 00:16:35 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-dialog-util.h, gnome-dialog-util.c: Return the created
+ 	dialog. This makes the functions much more useful. I was thinking
+ 	they should be maximally opaque, but went a little overboard
+ 	I guess.
+	* testgnome.c: Well, that was short-lived. Someone else did it
+	already. Yay!
+
+1998-05-11  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-list.c (gnome_icon_list_unselect_all): New function.
+
+Tue May 12 00:33:10 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-preferences.h, gnome-preferences.c: Hmm, I didn't think
+	about that earlier attempt much. This should work a little better.
+	* testgnome.c: Barest skeletal start.
+
+Sat May  9 15:55:48 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-dialog-util.h, gnome-dialog-util.c: gnome-app-util had
+	some internal functions to quickly pop up some common dialogs;
+	so I put them here for anyone to use. Probably bloat, if they
+	weren't used in gnome-app-util anyway.
+	* gnome-app-util.c: #include without the libgnomeui prefix.
+	 Remove most of the code and put it in gnome-dialog-util.c.
+	* gnome-types.h: New file, for now has a couple of function
+ 	pointer typedefs used in the above stuff.
+	* gnome-app-util.h: Changed to use gnome-types.h
+	* TODO: Updated.
+	* Makefile.am, libgnomeui.h: Include new files.
+
+1998-05-09  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-client.c (default_client_init): Use the new macro
+	GTK_HAVE_SIGNAL_INIT
+
+1998-05-08  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gtkcalendar.c (gtk_calendar_thaw): Added freeze/thaw
+	functionality.
+
+Fri May  8 10:06:01 1998  Tom Tromey  <tromey cygnus com>
+
+	* gnome-client.c (default_client_init): Call gtk_type_init and
+	gtk_signal_init.
+
+Thu May  7 21:46:24 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-dialog.c: Take out debug printfs.
+
+1998-05-07  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-icon-list.c: Changed required for gmc icon view.
+	(icon_new_from_imlib): New routine, this is now used internally to
+	create an icon from an Imlib image.
+	(gnome_icon_list_append_imlib): New routine: add icons from an
+	Imlib created image.
+	(gnome_icon_list_append): Modified, load the file and call
+	gnome_icon_list_append_imlib.
+	(toggle_icon): Implemented the Windows-like selection scheme.
+
+Thu May  7 19:13:33 1998  Havoc Pennington  <hp pobox com>
+
+	* Makefile.am, libgnomeui.h: Add gnome-less
+	* gnome-less.h, gnome-less.c: Set default width to 80 columns
+	when the font is changed.
+	* TODO: Check this item off.
+	* gnome-preferences.h: Fiddled around, not important.
+
+Thu May  7 15:47:21 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-about.c (gnome_about_new): Use set_close instead of
+	deprecated set_destroy.
+
+Wed May 06 23:00:55 1998  George Lebl  <jirka 5z com>
+
+	* stock_demo.c: it's now possible to get rid of the damn
+	  "really quit" window, without actually quitting
+
+Wed May 06 22:42:40 1998  George Lebl  <jirka 5z com>
+
+	* gnome-dialog.c: emitting the close signal passed a NULL
+	  where a pointer to retval was supposed to be producing
+	  a segfault
+
+Wed May  6 18:54:54 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-dialog.h, gnome-dialog.c: Recommit of April 30 changes;
+	difference is using a new "close" signal instead of delete_event.
+	However, the "close" signal marshaller segfaults for now.
+	* gnome-messagebox.c, gnome-propertybox.c: Use new gnome-dialog
+	stuff.
+	* gnome-uidefs.h: GNOME_YES, GNOME_NO to make button handling
+	more readable; also for use with gnome-app-util
+	* stock-demo.c: Use new dialog stuff; try to use "close" signal
+	just to expose the bug.
+	* TODO: Updated.
+	* gnome-app-util.h, gnome-app-util.c: Started on the
+	dialog/statusbar abstraction; status bar part doesn't work
+	yet.
+	* gnome-preferences.h: Define sections and keys for use in
+	libgnomeui global preferences.
+
+Wed May  6 01:29:33 1998  Jaka Mocnik  <jaka mocnik kiss uni-lj si>
+
+	* gnome-app.[ch]: added gnome_app_set_statusbar() function
+	which simply allows for insertion of another widget in the
+	bottom row of the table.
+
+Sun May  3 10:56:50 1998  Tom Tromey  <tromey cygnus com>
+
+	* gnome-ice.c (ice_tag): Removed.
+	(new_ice_connection): Always call gdk_input_add.
+
+Fri May  1 02:52:27 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-dialog.h, gnome-dialog.c: Revert to 1.3 and 1.7
+	respectively, before any accelerator/destroy changes.
+	* gnome-propertybox.c: Revert to 1.8 accordingly.
+
+Fri May  1 02:04:06 1998  Havoc Pennington  <hp pobox com>
+
+        * gnome-dialog.c (gnome_dialog_clicked): Revert to old destroy
+ 	behavior.
+
+	* gnome-dialog.c (gnome_dialog_key_pressed): Return TRUE if the
+ 	event was handled (???). Mostly it shouldn't really make a
+ 	difference though, for this function. Disable Escape functionality
+ 	for now.
+
+Thu Apr 30 23:13:31 1998  George Lebl  <jirka 5z com>
+
+	* gnome-calculator.[ch]: added an accelerator table and
+	  accelerators since too many people complained about it.
+	  it doesn't work for the numpad which is kind of weird
+
+Thu Apr 30 21:31:43 1998  Tom Tromey  <tromey cygnus com>
+
+	* gnome-client.c (client_set_prop_from_string): Don't include
+	trailing \0 in length.
+	(client_set_prop_from_array): Likewise.
+
+Thu Apr 30 23:25:19 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-dialog.h (struct _GnomeDialog): New member,
+	GtkAcceleratorTable * accelerators
+	* gnome-dialog.h (gnome_dialog_set_accelerator): New function, EZ
+ 	way to connect an accelerator to a button.
+	* gnome-dialog.h (gnome_dialog_close): New function. Emits
+	delete_event, hides then destroys only if delete_event isn't
+	handled.
+	* gnome-propertybox.c (just_close): Use gnome_dialog_close.
+	* gnome-dialog.c: Use gnome-uidefs rather than custom
+	button/border sizes. Implement new gnome-dialog.h interfaces.
+	* gnome-dialog.c (gnome_dialog_key_pressed): New function,
+	gnome_dialog_close if GDK_Escape is pressed, otherwise
+	call parent's key_press_event handler.
+	* gnome-dialog.c (gnome_dialog_class_init):
+	widget_class->key_press_event = gnome_dialog_key_pressed;
+	* gnome-dialog.c (gnome_dialog_init): Create accelerator table.
+	* gnome-dialog.c (gnome_dialog_button_clicked): Use
+	gnome_dialog_closed() to self destruct.
+	* gnome-dialog.c (gnome_dialog_destroy): Unref accelerator table.
+
+Thu Apr 30 21:31:43 1998  Tom Tromey  <tromey cygnus com>
+
+	* gnome-client.c (client_parse_func): Set previous_id for client.
+
+1998-04-30  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gtkcalendar.c: return meaningful values from most routines.
+
+Thu Apr 30 11:45:38 CEST 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-app-helper.c (gnome_app_create_menus_custom,
+	gnome_app_do_toolbar_creation): if GnomeApp gets a new accelerator
+	table, add it to the window.
+
+Thu Apr 30 01:27:52 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-appsmenu.h, gnome-appsmenu.c: Removed.
+
+1998-04-30  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-geometry.c (get_number): Handle the case +-10.
+
+Thu Apr 30 00:48:54 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-less.h, gnome-less.c: Added simple widget to display a
+ 	file or command output. GtkText wrapper. Not included in Makefile
+	due to feature freeze.
+	* gnome-uidefs.h: Added GNOME_BUTTON_WIDTH, GNOME_BUTTON_HEIGHT.
+	Shouldn't break anything.
+
+1998-04-30  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-color-selector.c (gnome_color_selector_button_clicked):
+	Use correct visual and colormap for color selector.
+
+1998-04-29  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-pixmap.c (finish_load): Hide the old window and show the
+	new one if the widget is mapped.  Otherwise reloading a new pixmap
+	won't work right.
+
+Wed Apr 29 21:16:28 CEST 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-dialog.c (gnome_dialog_append_buttons): changed signal_connect
+	for button to signal_connect_after.
+
+1998-04-29  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-geometry.c (gnome_parse_geometry): Add preconditions;
+	Support 'X' and '=' as XParseGeometry does.
+
+1998-04-28  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-geometry.c: New file, provides X geometry string parsing.
+
+1998-04-28  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-propertybox.c (global_apply): Use correct types for the
+	parameters passed to gtk_signal_emit().
+
+	* gnome-propertybox.h (struct _GnomePropertyBoxClass): Fixed
+	prototypes for the signal handlers (they take a gint parameter as well).
+
+Sun Apr 26 15:40:48 CEST 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock: supplied `About' icon for use in buttons
+
+Sun Apr 26 00:18:02 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-dialog.c (gnome_dialog_init): Pack the dialog's vbox
+	with expand set to TRUE.
+
+1998-04-22  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-file-entry.c (gnome_file_entry_init): Undo the emission of
+	a signal on content change, as GtkText already emitted "changed".
+
+Sat Apr 25 14:04:55 CEST 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock{.c,-imlib.h}: fixed apply/ok stock buttons, added trash
+	and trash_full to the list of stock menu items.
+
+Fri Apr 24 16:32:33 1998  Owen Taylor  <otaylor gtk org>
+
+	* gtk-socket.c: Re-fixed destroy handling on the socket
+	so that it can be destroyed correctly _and_ notifies
+	the child correctly of the destruction.
+
+Thu Apr 23 20:50:56 1998  George Lebl  <jirka 5z com>
+
+	* gtk-socket.c: fixed destroy handeling on the socket,
+	  before it only worked if you destroyed the plug, if
+	  you destroyed the socket it just messed up
+
+1998-04-23  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-dialog.c (gnome_dialog_new): Actually set the window
+	title; it was just being ignored.
+
+Fri Apr 24 01:32:21 CEST 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock: added new icons by tigert
+
+	* gnome-stock.c (stock_button_from_entry): added support for normal
+	stock icons in stock buttons
+
+Wed Apr 22 19:29:49 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-dialog.h: Added better comments.
+	* gnome-dialog.c (gnome_dialog_button_connect): New function.
+
+1998-04-22  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-calculator.c (gnome_calculator_class_init): Register the
+	signals.
+
+	* gnome-file-entry.c (gnome_file_entry_init): Added emission of a
+	signal when the information on the entry changes.
+
+Wed Apr 22 16:47:49 CEST 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock: added new icons by tigert
+
+1998-04-21  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-calculator.c (gnome_calculator_init): Add padding to
+	calculator buttons.
+
+	* gtkcalendar.c (gtk_calendar_select_day): Call
+	gtk_calendar_compute_days every time when selecting a day and a
+	month.
+
+Tue Apr 21 14:26:22 1998  George Lebl  <jirka 5z com>
+
+	* gnome-calcualtor.c: spelling error in comment
+
+Tue Apr 21 00:04:28 1998  George Lebl  <jirka 5z com>
+
+	* gnome-calculator.c: use function call finite and stop
+	  NAN's. this should help portability
+
+1998-04-20  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-calculator.c (gnome_calculator_init): Added
+	internationalization.
+
+	* gnome-app-helper.h (GNOMEUIINFO_ITEM_STOCK): New macro, this one
+	uses STOCK pixmaps.
+
+Sun Apr 19 17:34:22 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-appsmenu.c: Cleanup and rearranging, generalized some
+	functions to think about moving them to gnome-util.
+	* gnome-appsmenu.h: Fixed a typo.
+
+Sat Apr 18 16:32:09 1998  George Lebl  <jirka 5z com>
+
+	* gnome-calculator.c: catch SIGFPE's and set error, this
+	  catches all the errors (intel doesn't give SIGFPE's
+	  enough, and alpha SIGFPE's all over the place)
+
+Fri Apr 17 19:42:54 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-appsmenu.h: #define GNOME_APPS_MENU_DENTRY_DIR_EXTENSION
+
+	* gnome-appsmenu.c: Saving works now, mostly. Successfully loaded
+	system menu, saved in .gnome, reloaded, displayed.
+	(GNOME_APPS_MENU_DEBUG_PRINT): debugging macro
+	(g_extract_file): New, reverse of g_concat_dir_and_file (may move
+	to gnome-util along with get_extension, is_dotfile?).
+	(dentry_save_func): Implemented.
+	(is_dotfile): Oops, didn't stop at first path separator. Fixed.
+	(gnome_apps_menu_new_from_file): optimized to immediately ignore
+	backup files.
+	(gnome_apps_menu_save): Made to work, previously it saved the
+ 	.directory file in the wrong directory and got confused. Still
+ 	does symlinks wrong I think (like ftw(), potentially traverses
+ 	them twice.)
+
+Fri Apr 17 15:49:02 1998  George Lebl  <jirka 5z com>
+
+	* gnome-calcualtor.c: fix the +/- button to actually
+	  change the sign.
+
+Fri Apr 17 16:03:36 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-appsmenu.h (GnomeAppsMenu): rearranged order of items
+	in struct (put bit flags together)
+	(GnomeAppsMenuSetupFunc): Changed required behavior - can now
+	take NULL arguments and ignore them.
+
+	* gnome-appsmenu.c: Implemented vtable instead of function
+	lookup, meaning small changes throughout.
+	(gnome_apps_menu_check): Check presence of vtable.
+	(find_class): Took out this function, not needed with vtables.
+	(dentry_setup_func): Changed to use new SetupFunc semantics.
+	(dentry_save_func): New function, just a stub.
+	(gnome_apps_menu_new_from_file): new function.
+	(gnome_apps_menu_load): destroy empty menu, and return NULL,
+	rather than return an empty menu.
+	(gnome_apps_menu_save): Removed use of ftw(). Get name of
+ 	directory AppsMenu and create a matching filesystem
+ 	directory. Delete empty filesystem directories. Delete old backup
+ 	files. Still doesn't work, some kind of memory corruption, and
+ 	likely fails on symlinks or other weird situations.
+	(gnome_apps_menu_new): Init vtable.
+
+1998-04-17  Arturo Espinosa  <arturo nuclecu unam mx>
+
+	* gtkcalendar.[hc]: display option GTK_CALENDAR_NO_MONTH_CHANGE to
+	avoid undesired month changings.
+
+1998-04-17  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-dateedit.c (gnome_date_edit_new): Now gets a show_time
+	flag that indicates show the time part (or just the date).
+	(gnome_date_edit_init): Fix cut&paste typo when showing time_entry.
+
+1998-04-16  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-dateedit.c (gnome_date_edit_set_time): Print the date correctly.
+
+Thu Apr 16 00:18:13 1998  George Lebl  <jirka 5z com>
+
+	* gnome-calculator.[ch]: added error handeling,
+	  some workarounds to alpha's SIGFPE problem, and
+	  added a result_changed signal.
+
+Thu Apr 16 02:06:07 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-appsmenu.h, gnome-appsmenu.c: Renamed "variety" to
+	"class" throughout, for clarity. Starting on using a vtable
+	instead of whatever dumb thing I was doing.
+	(GnomeAppsMenuGtkMenuItemFunc): Replaced by
+	GnomeAppsMenuSetupFunc, this is more versatile and works
+	with GtkTree or whatever as well. Uses of GtkMenuItemFunc
+	changed appropriately.
+	(gnome_apps_menu_setup): Calls setup function.
+	(gnome_apps_menu_save, gnome_apps_menu_save_default): new
+	functions, started implementing them.
+
+Wed Apr 15 18:03:36 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-appsmenu.h: Updated comments.
+
+	* gnome-appsmenu.c: Moved things around and fixed comments to make
+ 	file clearer.
+	(gtk_menu_item_new_from_apps_menu): Fixed bug which assumed menu
+ 	was of homogeneous type (because the particular variety's function
+ 	did the recursion rather than the generic function).
+	(gtk_menu_new_from_apps_menu): ignore the root node, rather than
+ 	creating a one-item menu with the root node on it. Remaining bug:
+ 	Child menus show up on my screen before I call _show() on the root
+ 	menu. I do not understand this.
+
+1998-04-15  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-dateedit.c (gnome_date_edit_init): The "Calendar" button
+	is now prettier.
+
+	* gnome-dateedit.c (select_clicked): The date editor widget now
+	has a real popup for the calendar, and generally does the calendar
+	stuff in a saner way.
+
+Wed Apr 15 00:57:30 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-appsmenu.c: I got a working panel-like menu out of
+ 	share/apps, so that's progress. Many rough edges remain. Changes:
+ 	use G_DISABLE_CHECKS; implemented function to create GtkMenuItem
+ 	from the menu structure, complete with pixmaps; took out some
+ 	unused code
+
+	* gnome-appsmenu.h (GNOME_APPS_MENU_IS_DENTRY): Removed unused
+ 	macros for identifying .desktop-based menus, according to new "no
+ 	special cases" policy.
+
+1998-04-15  Arturo Espinosa Aldama  <arturo nuclecu unam mx>
+
+	* gtkcalendar.c (gtk_calendar_size_allocate): just an if to
+	avoid a warning when not using the header window.
+
+	* gtkcalendar.c (gtk_calendar_select_day): another if for added
+	functionality: gtk_calendar_select_day (my_widget, 0) now eliminates
+	any selected day in the calendar. This was already possible, but
+	generated a warning.
+
+1998-04-14  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-dateedit.c (day_selected): Use gtk_calendar_get_date ().
+
+	* gtkcalendar.c (gtk_calendar_size_request): In libdate, months
+	are indexed in [1, 12].  Make the calculation of the max month
+	width know about this.
+	(gtk_calendar_get_date): Added gtk_calendar_get_date() function to
+	avoid the user having to access the widget's fields.
+
+	* gtkcalendar.h: Added prototype for gtk_calendar_get_date().
+
+	* gnome-dateedit.c (select_clicked): Add 1900 to the tm_year field
+	of the struct tm.  The calendar was getting the wrong year.
+	(day_selected): Synchronize calendar month and displayed month.
+	(gnome_date_edit_get_date): We have to test for >= 1900, not just >.
+	(gnome_date_edit_set_time): Add 1900 to tm_year.
+
+	* gnome-dateedit.c (gnome_date_edit_class_init): Initialize signal
+	handlers.
+	(gnome_date_edit_init): Changed flags passed to
+	gtk_box_pack_start() to make the widget look nicer when resized.
+
+	* gnome-dateedit.h: Fixed the declarations for the class signals.
+
+Tue Apr 14 16:35:40 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-appsmenu.h (gnome_apps_menu_new): Now has
+	arguments.
+	* gnome-appsmenu.c: Added lots of debugging stuff to
+	check invariants. Broke gnome_apps_menu_load() apart
+	into lots of little functions and it seems to work now.
+
+Tue Apr 14 00:34:54 1998  George Lebl  <jirka 5z com>
+
+	* gnome-calculator.c: added parenthesis and factorial,
+	  which means that except for error handeling it's
+	  almost complete
+
+Mon Apr 13 22:48:11 1998  George Lebl  <jirka 5z com>
+
+	* gnome-calculator.c: added conversions DEG/RAD/GRAD
+
+Mon Apr 13 22:17:02 1998  George Lebl  <jirka 5z com>
+
+	* Makefile.am: added pixmap subdir
+
+	* pixmaps/Makefile.am: install calcualtor-font.xpm
+
+	* gnome-calculator.[ch]: reduce object size by not
+	  including the font pixmap and redone how buttons are
+	  made
+
+Tue Apr 14 10:27:25 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-appsmenu.h, gnome-appsmenu.c: Fixed many little glitches,
+	after first compilation attempt. Compiles, doesn't work. Copyright
+	changed to FSF.
+
+Mon Apr 13 00:43:32 1998  George Lebl  <jirka 5z com>
+
+	* gnome-calculator.c: fixed display
+
+Sun Apr 12 23:43:11 1998  George Lebl  <jirka 5z com>
+
+	* gnome-calculator.c: added e and PI buttons and made
+	  the display have more digits after .
+
+Sun Apr 12 23:28:02 1998  George Lebl  <jirka 5z com>
+
+	* gnome-calcualtor.c: DEG/RAD/GRAD modeswitching button
+	  added
+
+Sun Apr 12 23:01:24 1998  George Lebl  <jirka 5z com>
+
+	* gnome-calculator.[ch]: now has pretty font display,
+	  reduced the number of digits to 12 and added
+	  memory functions.
+
+	* pixmaps/calculator-font.xpm: the font for the
+	  calculator display
+
+Sun Apr 12 19:29:52 1998  George Lebl  <jirka 5z com>
+
+	* gnome-calculator.[ch]: killed a few bugs, seems to
+	  kind of work now
+
+Sun Apr 12 17:24:39 1998  George Lebl  <jirka 5z com>
+
+	* gnome-calculator.[ch]: added the beginnings of a
+	  double precision calculator widget modeled after
+	  xcalc
+
+	* libgnomeui.h, Makefile.am: added gnome-calculator
+	  references
+
+Sat Apr 11 14:20:26 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-appsmenu.h, gnome-appsmenu.c: Began implementing
+	load and menu creation functions. .directory support.
+	* gnome-appsmenu.h (gtk_menu_item_new_from_apps_menu): New
+	function.
+
+Sat Apr 11 11:35:24 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-appsmenu.h, gnome-appsmenu.c
+	(gnome_apps_menu_load_system, gnome_apps_menu_load_default):
+	Two new functions.
+	(GnomeAppsMenuVariety): moved from .h to .c
+	(gnome_apps_menu_variety_new): also moved
+
+1998-04-10  Carsten Schaar  <nhadcasc fs-maphy uni-hannover de>
+
+	* gnome-app-helper.h (GnomeUIInfoType): New type, extracted from
+ 	GnomeUIInfo, to make access to this type easier when using C++.
+	(GnomeUIPixmapType): likewise
+	(GnomeUIInfo): Use GnomeUIInfoType and GnomeUIPixmapType.
+	(GNOMEUIINFO_END): Use expicit type casts to GnomeUIPixmapType and
+ 	GdkModifierType to prevent C++ from generating compiler warnings.
+	(GNOMEUIINFO_SEPARATOR): likewise
+	(GNOMEUIINFO_ITEM): likewise
+	(GNOMEUIINFO_ITEM_DATA): likewise
+	(GNOMEUIINFO_TOGGLEITEM): likewise
+	(GNOMEUIINFO_TOGGLEITEM_DATA): likewise
+	(GNOMEUIINFO_HELP): likewise
+	(GNOMEUIINFO_RADIOLIST): likewise
+	(GNOMEUIINFO_RADIOITEM): likewise
+	(GNOMEUIINFO_RADIOITEM_DATA): likewise
+
+Fri Apr 10 00:14:03 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-appsmenu.h (gnome_apps_menu_variety_new):
+	New function.
+	* gnome-appsmenu.c: Continued implementation. Variety
+	registration is done, load and GtkMenu creation isn't.
+
+Thu Apr  9 23:25:29 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-appsmenu.h: Added basic menu-manipulation functions.
+	* gnome-appsmenu.c: New file, began implementation.
+	Doesn't work yet.
+
+Thu Apr  9 22:12:49 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-appsmenu.h: New interface, not yet implemented.
+
+Wed Apr  8 19:17:18 1998  Havoc Pennington  <hp pobox com>
+
+	* gnome-dialog.c, gnome-messagebox.c: Use gnome-uidefs.h
+	* libgnomeui.h: #include gnome-uidefs.h
+	* gnome-uidefs.h: New file.
+
+1998-04-07  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gtk-ted.c (lift_me): I never thought that
+	gtk_signal_emit_stop_by_name was so easy to use :-).
+	This means, GtkTed is now back to functional for GUI editing.
+
+	(gtk_ted_setup_layout): Handle the case where the widgets do no
+	longer exist in the code, but the layout file still has
+	information on them.
+
+	(gtk_ted_init_divisions): New routine, now when editing an
+	existing dialog box, the correct number of control rows/columns
+	are created.
+
+Mon Apr  6 13:10:43 CDT 1998 Havoc Pennington  <hp pobox com>
+
+	* gnome-about.h (GnomeAboutButton): typedef removed.
+	* gnome-about.h (GNOME_ABOUT_BUTTON_WIDTH,
+	GNOME_ABOUT_BUTTON_HEIGHT): defines removed.
+	* gnome-about.h, gnome-about.c: GnomeAbout now derives from
+	GnomeDialog.
+	* gnome-about.c: Unused signal enum removed.
+	* gnome-about.c (parent_class): Unused global variable
+	removed.
+	* gnome-about.c: Removed button-creating code, since
+	GnomeDialog handles it.
+	* gnome-about.c (gnome_about_button_clicked): Callback
+	removed, GnomeDialog handles it.
+	* gnome-about.c: Removed border-width code; use default
+	border from GnomeDialog.
+	* gnome-about.c (gnome_destroy_about): Fixed memory leak;
+	function freed uninitialized tmp variable rather than
+	gai->names. Removed tmp declaration.
+	* libgnomeui.h: #include <libgnomeui/gnome-dialog.h>
+	* gnome-net.h: use BEGIN_GNOME_DECLS
+	* gnome-net.c (gnome_net_gets): changed if (errno = EAGAIN)
+	to if (errno == EAGAIN).
+	* gnome-about.c, gnome-net.c, gnome-scores.c,
+	gnome-propertybox.c: #include specific headers, not <gnome.h>
+	* gnome-propertybox.c, gnome-messagebox.c, gnome-dialog.c:
+	Removed i18n defines; will use new private header.
+	* gnome-actionarea.h: Added a "deprecated" comment.
+	* gnome-dialog.h, gnome-dialog.c (gnome_dialog_set_sensitive):
+	New function to set button sensitivity.
+	* gnome-propertybox.h, gnome-propertybox.c: Now derives from
+	GnomeDialog.
+	* gnome-propertybox.c (GNOME_PAD): Removed this #define.
+	* gnome-propertybox.c (dialog_clicked_cb): new function.
+	* gnome-propertybox.c: Changed signature of previous button
+	callbacks. They are now called from dialog_clicked_cb, so
+	they have no button argument.
+	* gnome-propertybox.c (gnome_property_box_init): Don't set
+	up button box or vbox, since GnomeDialog now handles that.
+	* gnome-propertybox.c (global_apply): return if
+	property_box->items == NULL. Initialize variable 'item' to
+	NULL, to make -Wall happy.
+	* gnome-dialog.c (gnome_dialog_button_clicked): Since
+	PropertyBox destroyed itself when this function emitted
+	"clicked", and this function then tried to look at a
+	GnomeDialog struct member, there was a bug. Fixed.
+	* gnome-propertybox.c (gnome_property_box_init): Don't do
+	the 3D frame, since GnomeDialog handles it.
+	* gnome-dialog.c (gnome_dialog_init): Added a nice 3D bevel
+	to the edge of the dialog, like gnome-propertybox had.
+
+1998-04-06  Marc Ewing  <marc redhat com>
+
+	* gtk-socket.[ch]: change "id" parameter name to "wid"
+	  so as not to conflict with objc reserved word (again).
+
+Mon Apr 06 00:57:23 1998  George Lebl  <jirka 5z com>
+
+	* gtk-{plug,socket}.[ch]: updated to owen's
+	  plugsocket v0.2
+
+Fri Apr  3 23:29:11 1998  Havoc Pennington <hp pobox com>
+
+	* gnome-messagebox.c, gnome-messagebox.h: Now derived from
+	gnome-dialog.
+	* Makefile.am (libgnomeui_la_SOURCES): Added gnome-dialog.c.
+	(libgnomeuiinclude_HEADERS): Added gnome-dialog.h.
+	* gnome-dialog.c, gnome-dialog.h: New files.
+
+1998-04-03  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-dateedit.c: #include <string.h>
+	Removed unused global variable parent_class.
+
+	* gnome-dateedit.h: Add prototype for gnome_date_edit_get_type().
+
+1998-04-03  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-dateedit.c (fill_time_popup): Make the top boundary inclusive
+
+1998-04-02  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gtkcalendar.[ch]: Update to latest version from gcalendar cvs module.
+
+1998-04-01  Arturo Espinosa  <arturo nuclecu unam mx>
+
+	* gtkcalendar.c (gtk_calendar_select_month,
+	gtk_calendar_select_day): Don't paint unless the widget is drawable!
+
+1998-04-01  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-dateedit.c, gnome-dateedit.h: New widget for editing a
+	date/time.
+
+	* gtkcalendar.c (gtk_calendar_class_init): Declare signal
+	"day_selected";
+	(gtk_calendar_marshall_date): Marshaller for new signal.
+	(gtk_calendar_main_button): when a click happens in a day, emit
+	the signal day_changed.
+
+1998-04-01  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gtkcalendar.[ch]: Updated to latest version from gcalendar
+	module.
+
+1998-03-31  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gtkcalendar.c: Added Shawn's and Cesar's calendar widget to the
+	gnome-libs.
+
+1998-03-30  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.c (gnome_icon_list_moveto): Finished
+	implementing moveto routine.  It only supports vertical alignment,
+	as the icon list tries to display only whole columns and thus
+	disable horizontal scrolling.
+
+	* gnome-icon-list.h: New function gnome_icon_list_get_icon_at().
+	Returns the index of the icon that is under the specified
+	coordinates, or -1 if the coordinates are over white space.
+
+	* gnome-icon-list.c: Added missing functionality regarding
+	selecting/unselecting of icons.
+
+1998-03-27  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.c (draw_icon): Only try to set the masks if the pixmap exists.
+	(get_icon_num_from_xy): Fixed a couple of off-by-one errors.
+
+Sat Mar 28 18:12:33 CET 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock{,-imlib}.[ch], stock_demo.c: Added more of tigert's
+	pixmaps.
+
+1998-03-27  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.c (draw_icons_area): Only paint icons within
+	exposure area width.
+	(adjust_scrollbars): Use better values for step_increment in adjustments.
+
+1998-03-27  Carsten Schaar  <nhadcasc fs-maphy uni-hannover de>
+
+	* gnome_segv.c: included "config.h"
+	(main): Added i18n.
+
+1998-03-26  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-icon-list.h: New files gnome-icon-list.[ch].  This
+	provides the GnomeIconList widget.  It is an icon list widget with
+	several display modes.  It has an API very similar to the
+	GtkCList, so using it should be easy.  It will be used on the file
+	manager for the iconic view, for an icon selector property box,
+	etc.  It is still not finished and it has bugs, but you can start
+	playing with it now.  There is a small example program on
+	http://www.nuclecu.unam.mx/~federico/test-ilist.c
+
+	* libgnomeui.h: Added gnome-icon-list.h to the includes.
+
+	* Makefile.am: Added gnome-icon-list.[ch] to the rules.
+
+Thu Mar 26 13:29:18 1998  Radek Doulik  <gis academy cas cz>
+
+	* gnome-client.c (gnome_client_flush): check HAVE_LIBSM, hope I don't
+	break something
+
+Wed Mar 25 01:30:00 CET 1998  Eckeherad Berns  <eb berns prima de>
+
+	* stock_demo.c: use the "Really quit?" message box for real.
+
+	* gnome-stock.c: minor i18n fix for clist titles.
+
+Tue Mar 24 23:06:44 CET 1998  Eckeherad Berns  <eb berns prima de>
+
+	* gnome-messagebox.c (gnome_message_box_init): applied patch from
+	robert havoc pennington <rhpennin midway uchicago edu> with some
+	sanity checks and use of gnome_pixmap_file
+
+Tue Mar 24 22:32:11 CET 1998  Eckeherad Berns  <eb berns prima de>
+
+	* gnome-propertybox.c: applied patch from Havoc Pennington
+	<hp pobox com>
+
+Tue Mar 24 19:24:23 CET 1998  Eckeherad Berns  <eb berns prima de>
+
+	* gnome-messagebox.c (gnome_message_box_new): use
+	gnome_pixmap_new_from_file for pixmap loading
+
+	We will have to supply some pixmaps for the gnome message box. I
+	couldn't find any "bomp.{xpm,png}".
+
+Tue Mar 24 19:24:23 CET 1998  Eckeherad Berns  <eb berns prima de>
+
+	* gnome-app-helper.c (gnome_app_do_ui_accelerator_setup): use
+	gtk_widget_install_accelerator to make the accelerators visible in
+	the menu
+
+Tue Mar 24 19:16:55 CET 1998  Eckeherad Berns  <eb berns prima de>
+
+	* stock_demo.c, gnome-stock.c: use GnomePropertyBox's own signals.
+
+	* gnome-propertybox.c: fix some box-packing (to allow window resizing).
+	(just_close): fix "delete_event" (segfaulted if someone realy catched
+	the signal)
+
+Tue Mar 24 01:07:14 1998  Tom Tromey  <tromey cygnus com>
+
+	* stock_demo.c (message_dlg): New function to test
+	gnome-messagebox.  (This could be moved elsewhere; it is just a
+	hack.)
+
+	* gnome-propertybox.c (gnome_property_box_new): Buttons now kept
+	in a button box.
+	* gnome-messagebox.c (gnome_message_box_new): Buttons now kept in
+	a button box.
+	(GNOME_PAD): Define.
+
+Sun Mar 23 02:24:44 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock.c: fixed some segfaults when clicking on empty
+	accelerators.
+
+Sun Mar 23 00:09:49 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock.c: Added config dialog for menu accelerators. This might
+	not be the proper place, but I didn't know where else to put it.
+
+	* stock_demo.c: Choosing preferences opens the accel config dlg.
+
+Sun Mar 22 19:16:58 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock.[ch]: Added gnome_stock_menu_accel_parse.
+
+	* gnome-stock.c: Added parsing of default accelerators in rc
+	GnomeStock.
+
+Sun Mar 22 16:04:00 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock.[ch]: Added gnome_stock_menu_accel
+
+	* stock_demo.c: Use gnome_stock_menu_accel. Include GnomePropertyBox
+	sample.
+
+Sun Mar 22 10:26:09 1998  Radek Doulik  <rodo aquarius>
+
+	* gnome-propertybox.c (just_close): send delete_event to property
+	box instead of widget_destroy
+
+Sun Mar 22 00:07:06 1998  Tom Tromey  <tromey cygnus com>
+
+	* gnome-propertybox.c (global_apply): Emit apply signal with page
+	number of -1 after all pages applied.
+
+Sat Mar 21 00:45:10 1998  Tom Tromey  <tromey cygnus com>
+
+	* gnome-properties.c (apply_page): New function.
+	(gnome_property_configurator_setup): Connect apply_page to "apply"
+	signal on property box.
+	(gnome_property_configurator_request): Removed.
+
+	* gnome-properties.h (GnomePropertyConfigurator): Replaced
+	notebook with property_box.
+
+	* gnome-propertybox.c (gnome_property_box_new): Actually pack
+	widgets into frame.
+	(gnome_property_box_init): Initalize `items'.
+
+	* libgnomeui.h: Include gnome-propertybox.h.
+	* gnome-propertybox.h: New file.
+	* gnome-propertybox.c: New file.
+	* Makefile.am (libgnomeui_la_SOURCES): Added gnome-propertybox.c.
+	(libgnomeuiinclude_HEADERS): Added gnome-propertybox.h.
+
+	* gnome-messagebox.c: Changed all names from gnome_messagebox_* to
+	gnome_message_box_*.  The latter mathches Gtk style, and works
+	better with gnome.defs/gen-typeinfo.
+
+	Somewhat modified patch from Havoc Pennington:
+	* gnome-messagebox.c (gnome_messagebox_new): Initialize buttons
+	element to NULL, not to a new list.  Call va_end.
+	(gnome_messagebox_set_default): Use g_list_nth.
+	(gnome_messagebox_button_clicked): Now static.
+
+Fri Mar 20 23:02:46 1998  Tom Tromey  <tromey cygnus com>
+
+	* gnome-messagebox.c (gnome_messagebox_new): Use
+	gnome_stock_or_ordinary_button.
+
+	* gnome-stock.h (gnome_stock_or_ordinary_button): Declare.
+	Updated copyright.
+	* gnome-stock.c (stock_button_from_entry): New function.
+	(gnome_stock_button): Use it.
+	(gnome_stock_or_ordinary_button): New function.
+	Updated copyright.
+
+1998-03-20  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-file-entry.c (realize): Added drop support to gnome
+	file-entries.  Now you can drag files from mc to the file entries
+	and guess what happens :-)
+
+Fri Mar 20 00:01:47 1998  Tom Tromey  <tromey cygnus com>
+
+	* gtk-plug.h: Changed `()' to `(void)'.
+	* gtk-clock.h: Renamed `clock' arguments to `gclock' to avoid
+	clash with ANSI function.
+	* gtk-socket.h: Renamed `socket' argument to `gsocket' to avoid
+	clash with Unix system call.
+
+Thu Mar 19 18:02:04 1998  Tom Tromey  <tromey cygnus com>
+
+	* gnome-init.c (our_gtk_parse_func): Allocate two slots for every
+	slot in argv.
+
+1998-03-19  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-app.c (gnome_app_add): Add support for gtk_container_add
+	to GnomeApp widget.
+
+1998-03-20  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock-imlib.h: added timer and timer_stopped icons. At least
+	two apps already use timer buttons: gtt and gtop.
+
+	* gnome-stock.[ch]: Added gnome_stock_pixmap_widget_set_icon. See
+	stock_demo.c for an example.
+
+	* stock_demo.c: added an example for the use of ..._set_icon.
+
+1998-03-19  Marc Ewing  <marc redhat com>
+
+	* gtk-socket.{c,h}: change "id" parameter name to "wid"
+	  so as not to conflict with objc reserved word.
+
+Wed Mar 18 20:40:43 1998  Tom Tromey  <tromey cygnus com>
+
+	* gnome-stock.c (NOT_ALWAYS_SHADE): Renamed to fix typo.
+	(_default_entries_data): Added `label' field.
+	(entries_data): Added label info to each element.
+	(stock_pixmaps): Copy label into hash entry.
+	(gnome_stock_menu_item): Fail if text is NULL.
+	(gnome_stock_button): Look up label in entry.
+
+	* gnome-stock.h: Added `label' field to each GnomeStockPixmapEntry
+	structure.
+
+1998-03-18  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-file-entry.h: New files gnome-file-entry.[ch].  This is a
+	combo box widget with an extra "Browse" button to enter file
+	names.  All places in Gnome where an entry widget is being used to
+	get a filename should use the GnomeFileEntry widget instead.
+
+	* libgnomeui.h: Added gnome-file-entry.h to the includes.
+
+	* Makefile.am: Added gnome-file-entry.[ch] to the file lists.
+
+Tue Mar 17 22:45:47 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock/stock_demo: added "Save As" icon.
+
+Tue Mar 17 22:28:47 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock.h: added dummy variable to include N_("blah")s for
+	i18n.
+
+	* gnome-stock.c (gnome_stock_button): use dgettext, not gettext.
+
+1998-03-17  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-app-helper.c (gnome_app_do_menu_creation): The activate
+	signal should not be connected to subtree items --- you don't want
+	to call a subtree structure when the user clicks on a submenu, right?
+
+1998-03-16  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-app-helper.h: Removed the explicit values from the type
+	enum and removed the GNOME_APP_UI_LAST value (never used).
+	Added #ifndef GNOME_APP_HELPER_H... stuff.
+
+1998-03-16  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock/stock_demo: Added undo stock icon. Added some more
+	stock icons to the list of converted menu icons.
+
+	* gnome-stock-xpm-h: removed -- fully switched to imlib rgbs.
+
+1998-03-16  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock*.[ch]: Added new icons for yes/no buttons. Added a
+	quick and durty scale_down function to convert the toolbar icons for
+	the menus. Hope it works on all mashines. Removed external reference
+	to gnome_stock_pixmap - use gnome_stock_pixmap_widget instead.
+
+	* gnome-pixmap.[ch]: Added gnome_pixmap_new_from_rgb_d_shaped to
+	support imlib's shape_color for gnome-stock.
+
+1998-03-13  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-rootwin.h: New widget GnomeRootWin.  This is a widget that
+	corresponds to the root window of the screen.  Yes, I know it is
+	weird.  However, it provides a nice Gtk abstraction for the root
+	window.  The immediate use of this will be to drop objects from
+	the file manager into the root window.  Some hacking is still
+	needed in this widget to make it work exactly like normal GtkWindows.
+
+	* libgnomeui.h: Added #include "libgnomeui/gnome-rootwin.h".
+
+	* Makefile.am: Added gnome-rootwin.[ch] to the list of files.
+
+1998-03-12  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-pixmap.c (gnome_pixmap_draw): Doh.  I don't know how to
+	subtract.  Fixed offsetting, again.
+
+Thu Mar 12 15:50:27 1998  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gtk-ted.c (gtk_ted_set_spacings): Set the spacings for each line
+	with a hacky widget on every line.
+
+1998-03-12  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-pixmap.c: Added warnings of "don't use me" to all the
+	obsolete functions.
+	(gnome_pixmap_draw): Added proper widget draw function.  We need a
+	special draw function because a GnomePixmap's window may not be as
+	big as its allocation.
+	(paint): New function that actually paints the stuff.
+	(gnome_pixmap_expose): Use the paint() function.
+
+Tue Mar 10 22:27:31 1998  Tom Tromey  <tromey cygnus com>
+
+	* gnome-client.c (gnome_client_flush): New function.
+	(gnome_client_disconnect): Flush client.
+	* gnome-client.h (gnome_client_flush): Declare.
+
+	* gnome-client.c (gnome_client_set_restart_command): Don't insert
+	--sm-client-id option if restart_command is NULL.
+	(gnome_real_client_connect): Likewise.
+
+Tue Mar 10 15:01:05 1998  Federico Mena <federico nuclecu unam mx>
+
+	* gnome-color-selector.c (gnome_color_selector_new): Use the
+	proper visuals for the color selectors.
+
+Mon Mar  9 23:59:41 1998  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gtk-ted.c (gtk_ted_load_layout): Remove gracious printf.
+
+1998-03-09  Raja R Harinath  <harinath cs umn edu>
+
+	* gnome-init.c (gnome_init): Only set `program_invocation_name'
+	and `program_invocation_short_name' if they are not already set.
+
+Mon Mar  9 23:21:22 1998  Eckehard Berns  <eb berns prima de>
+
+	* stock_demo.c: added stock icon properties,
+	added descriptions for `other icons'
+
+	* gnome-stock*: changed other icons to look like tigert's and added
+	a preferences stock icon.
+
+Mon Mar  9 17:37:44 1998  Tom Tromey  <tromey cygnus com>
+
+	* gnome-init.c (gnome_init): Set program_invocation_short_name.
+
+Mon Mar  9 17:37:17 1998  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-init.c (gnome_init): Initialize the
+	program_invocation_name.  Wonder if this fixes stuff for people?
+
+Sun Mar  8 17:59:38 1998  Tom Tromey  <tromey cygnus com>
+
+	* Makefile.am (INCLUDES): Added @SUPPORTINCS  
+	(ted_demo_LDADD): Added @LIBSUPPORT  
+	(stock_demo_LDADD): Likewise.
+
+Sat Mar  7 01:21:57 1998  Tom Tromey  <tromey cygnus com>
+
+	* gnome-client.c (gnome_client_new_without_connection): Don't look
+	for magic argument.
+	(default_client_connect): Use sm_client_id_prop.
+	(default_client_disconnect): Likewise.
+	(array_has_sm_client_id_arg): Removed.
+	(array_insert_sm_client_id_arg): Now static.
+	(gnome_client_set_clone_command): Duplicate RestartCommand if
+	clone command is freed.
+	(gnome_real_client_connect): Only add magic option to duplicate of
+	restart command.
+	(gnome_client_set_restart_command): Likewise.
+	(array_copy): Now static.
+	(array_init_from_arg): Likewise.
+	(array_free): Likewise.
+	(array_remove_sm_client_id_arg): Removed.
+
+	* stock_demo.c (main): Use new form of gnome_init.
+	* ted_demo.c (main): Use new form of gnome_init.
+
+Fri Mar  6 21:46:37 1998  Tom Tromey  <tromey cygnus com>
+
+	* gnome-client.c (gnome_get_default_client): Removed.
+	(gnome_client_new_default): New function.
+	(default_client_init): Renamed, now static.
+	(arguments): New static.
+	(parser): Likewise.
+	(client_parse_func): New function.
+	(gnome_client_new): Changed interface.
+	(gnome_client_new_without_connection): Likewise.
+
+	* gnome-init.c (gnome_init): Pass argv[0], not *argv[0], to
+	gnome_rc_parse.
+
+Sat Mar  8 02:35:33 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock-{imlib,xpm}.h: foolishly tried to make remaning stock
+	icons look like tigert's pixmaps.
+
+	* gnome-stock.c: changed_size fields (20x20 -> 24x24) for affected icons
+
+Sat Mar  7 16:40:08 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock.c (create_pixmap_from_data): use
+	gnome_pixmap_new_from_xpm_d_at_size.
+
+	* gnome-stock.h: added new stock icons: print, search, back, forward.
+
+	* gnome-stock-{imlib,xpm}.h: added tigert's icons.
+
+	* stock_demo.c: included new icons
+
+Fri Mar  6 18:06:32 1998  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock{,-imlib,-xpm}.[ch]: reorganized pixmaps.
+	./pixmaps/ isn't needed any longer
+
+Wed Mar  4 00:14:01 1998  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gtk-ted.c (gtk_ted_new_layout): create widgets with an argument
+	that specifies where the layout is stored.
+
+1998-03-03  Raja R Harinath  <harinath cs umn edu>
+
+	* gnome-about.c (gnome_about_new): Uses /* */ comments, not //.
+
+1998-03-01  Eckehard Berns  <eb berns prima de>
+
+	* gnome-pixmap.c (gnome_pixmap_expose): I have to draw the pixmap on
+	every expose :-(
+
+1998-03-01  Eckehard Berns  <eb berns prima de>
+
+	* gnome-pixmap.c: fixed GnomePixmaps positioning.
+
+	* gnome-stock.c (..._size_request): request size of current pixmap
+	if there is one.
+
+	* gnome-stock-{imlib,xpm}.h: added/changed those nasty stock button
+	pixmaps to other nasty pixmaps (when will someone with at least a
+	minimum of some drawing skill replace my ugly pixmaps?)
+
+Sun Mar  1 00:23:29 1998  Tom Tromey  <tromey cygnus com>
+
+	* gnome-about.c (gnome_about_display_comments): Simplified
+	paragraph splitting.  Don't crash if comments is empty string.
+	Don't leak memory if malloc fails.
+
+Sat Feb 28 17:27:41 1998  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-app.c (gnome_app_new): Set app->name to appname.  Do not
+	know how this got to the current state.
+
+1998-02-27  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-pixmap.c (gnome_pixmap_expose): Repaint only the exposed area.
+	(gnome_pixmap_size_allocate): Center the pixmap's window on its allocation.
+	(setup_window_and_style): Center the window on the widget's allocation.
+
+1998-02-26 Arturo Espinosa  <arturo nuclecu unam mx>
+
+        * gnome-scores.c: Set window policy for the score dialog so that it
+	                  doesn't shrink nor grow.
+
+1998-02-26 Arturo Espinosa  <arturo nuclecu unam mx>
+
+        * gnome-scores.c: The scores dialog now uses a stock button for OK.
+
+1998-02-26  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-stock.c (build_disabled_pixmap): The style that provides
+	the GC for painting should come from the pixmap, not from the
+	window, to avoid BadMatch problems.  Also, the visual and colormap
+	should come from there.  Eliminated the window argument, as it is
+	no longer needed.
+	I still have a problem, though.  The widget needs to be realized
+	to pick its style (for the gc).  So I realize it if it is not
+	realized yet --- this will create a toplevel window if the widget
+	has not been parented yet, and looks extremely ugly, and doesn't
+	work.
+	(build_disabled_pixmap): OK, I now use a color context to paint
+	the stipple, so realization is not needed.
+	(build_disabled_pixmap): Removed unused variable style.
+
+1998-02-26  Eckehard Berns  <eb berns prima de>
+
+	* gnome-stock.[ch]: made gnome-stock use gnome-pixmap.
+
+Thu Feb 26 18:07:40 1998  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-about.c: Undefine _ when compiling to avoid clash with
+	i18n definition.
+
+1998-02-26 Arturo Espinosa  <arturo nuclecu unam mx>
+
+        * gnome-stock.[ch]: New tb_scores pixmap for the games.
+
+        * gnome-about.c (gnome_about_new): Now uses a stock button for OK.
+
+1998-02-25  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-app-helper.c (gnome_app_add_radio_toolbar_entries): Use
+	the GnomePixmap widget.
+	(gnome_app_do_toolbar_creation): Likewise.
+
+1998-02-25  Raja R Harinath  <harinath cs umn edu>
+
+	* gnome-app.c (gnome_app_new): Use "" instead of NULL.  Friendler
+	to systems where `strlen(NULL)' is broken.
+
+1998-02-24  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-pixmap.c (gnome_pixmap_init): GnomePixmap is a GTK_BASIC
+	widget.
+
+1998-02-23  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-pixmap.c (load_file): New internal function that takes
+	care of file loading and widget setup.
+	(gnome_pixmap_load_file): Changed to use load_file() internally.
+	(gnome_pixmap_load_file_at_size): New function to load an image
+	file and resize it to the specified size.  For example, this is
+	useful to have a single icon size for the panel and just specify
+	the size one will use (full size for the launchers, half size for
+	menu items, etc.).
+	(gnome_pixmap_new_from_xpm_d): New function, creates pixmap from
+	XPM data in memory.
+	(gnome_pixmap_new_from_xpm_d_at_size): Likewise.
+	(gnome_pixmap_load_xpm_d): Likewise.
+	(gnome_pixmap_load_xpm_d_at_size): Likewise!
+	(gnome_pixmap_new_from_rgb_d): New function, creates pixmap from
+	RGB plus (optional) Alpha data in memory.
+	(gnome_pixmap_new_from_rgb_d_at_size): Likewise.
+	(gnome_pixmap_load_rgb_d): Likewise.
+	(gnome_pixmap_load_rgb_d_at_size): Likewise, you know it!
+	(finish_load): New misc. internal function that does all the
+	boilerplate image loading finalization.
+	(load_file): Modified to use finish_load().
+	(load_xpm_d): New internal function.
+	(load_rgb_d): Likewise.
+
+	* gnome-app-helper.c (gnome_app_do_toolbar_creation): Use
+	gnome_pixmap_new_from_file() widget instead of
+	gnome_create_pixmap_widget().  I did not replace the
+	g_c_p_widget_d() call because GnomePixmap does not support
+	creating pixmaps from xpm data yet.
+
+	* gnome-pixmap.c:
+	* gnome-pixmap.h: New GnomePixmap widget!  It was created to
+	replace the ugly gnome_create_pixmap_*() functions.  Now you can
+	simply do something like:
+
+		GtkWidget *gpixmap;
+		gpixmap = gnome_pixmap_new_from_file ("hello.jpg");
+		gtk_container_add (container, gpixmap);
+		gtk_widget_show (gpixmap);
+
+	And that's it.  The GnomePixmap widget takes care of all the
+	visuals/colormaps/other_icky_X_stuff.
+
+	GnomePixmap uses gdk_imlib for its work, so now gdk_imlib is a
+	required component of Gnome.  Please install it if you have not
+	done it yet; it is a very cool thing to have.
+
+	During the next hours, I will be converting most of Gnome to use
+	the new GnomePixmap widget instead of the old
+	gnome_creat_pixmap_*() functions.
+
+	* gnome-init.c (gnome_init): Added gdk_imlib_init() to the GnomeUI
+	initialization procedure.
+
+1998-02-23  Carsten Schaar  <nhadcasc fs-maphy uni-hannover de>
+
+	* gnome-client.c (gnome_default_client_init): New function.
+	Creates a new client without connection to a session manager.
+	This client is called the 'default client'. (Not used yet)
+	(default_client_connect): New callback function.  This callback is
+	registered to the connect signal of the default client and sets
+	the SM_CLIENT_ID property to the gdk client leader window.
+	(default_client_disconnect): New callback function.  Removes
+	SM_CLIENT_ID property.
+	(gnome_get_default_client): New function.
+
+	* gnome-app-helper.h: Removed comma in pixmap_type.
+
+1998-02-20  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-entry.c (entry_activated): Now the GnomeEntry pushes a
+	history item if the entry field was activated (via return key, for
+	example).  We do proper checks to see if it is not an empty string
+	and such (in which case a history item does not need to be pushed).
+
+	* gnome-entry.h: Added changed field.  This is set to true if the
+	entry field has changed but it has not been put into the history
+	list.  False otherwise.
+
+	* Gnome-entry.c: First usable version of the GnomeEntry widget.
+
+	* gnome-startup.c:
+	* gnome-client.c: Added #include <string.h>
+
+	* libgnomeui.h: Added gnome-entry.h to the includes list.
+
+	* Makefile.am: Added gnome-entry.{c,h}
+
+	* gnome-entry.c:
+	* gnome-entry.h: New GnomeËntry widget -- entry field with
+	automagic history saving.
+
+	* ted_demo.c (main): Added app_id "ted_demo".
+
+	* stock_demo.c (main): Added app_id "stock_demo".
+
+	* gnome-init.c (gnome_init): Added app_id parameter to this
+	function.  Changes to the rest of Gnome are in progress.
+
+1998-02-19  Carsten Schaar <nhadcasc fs-maphy uni-hannover de>
+
+	* gnome-session.c: Removed. Was replaced by gnome-client.
+
+	* gnome-session.h: same as above.
+
+Wed Feb 18 13:52:00 PST 1998  Christoph Toshok  <toshok hungry com>
+
+	* gnome-app-helper.c (gnome_app_do_menu_creation): If any items in
+	a menu have GNOME_APP_PIXMAP_STOCK, use gnome_stock_menu_item for
+	all of them, so the left side of the labels line up.
+	(gnome_app_do_toolbar_creation): Use gnome_stock_pixmap_widget_new
+	to create the toolbar button.
+
+Wed Feb 18 17:03:13 KST 1998  Changwoo Ryu  <cwryu adam kaist ac kr>
+
+	* gnome-about.c (gnome_destroy_about): Fixed refcounting.
+	(gnome_fill_info, gnome_about_new): Fixed I18N problem.  (but a
+	dirty hack, it uses ONLY the fonts from gtkrc.).
+	* gtkrc: Moved GnomeAbout styles to here.
+
+1998-02-16  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-init.c (gnome_init): At last!  The horribly broken
+	gnome_colors goes to hell now that we have imlib and the
+	GdkColorContext :-)
+
+	* libgnomeui.h: Removed gnome-colors include.
+
+Tue Feb 17 00:16:49 KST 1998  Changwoo Ryu  <cwryu adam kaist ac kr>
+
+	* gnome-messagebox.c (gnome_messagebox_button_clicked): Fixed
+	buttonnumber counting.
+
+	* gnome-scores.[ch]: Fixed i18n problem.  All color/font settings
+	are in gtkrc.
+	(gnome_scores_set_logo_label_title): New function
+	(gnome_scores_set_current_player): New function.
+	* gnome-scores.c (gnome_scores_display): Use the above new
+	functions.
+
+	* gtkrc: New file, the global gtk+ rc file of GNOME.
+	* Makefile.am: Added gtkrc.
+
+1998-02-17  Eckehard Berns <eb berns prima de>
+
+	* gnome-stock.[ch]: added width/height fields to the
+	GnomeStock...Entry structs to make sure a size_request gets the
+	correct values.
+
+Tue Feb 17 00:16:49 KST 1998  Changwoo Ryu  <cwryu adam kaist ac kr>
+
+
+	* gnome-scores.c (gnome_scores_set_color): gtk_style_unref() new
+	GtkStyle after gtk_widget_set_style.
+	(gnome_scores_set_logo_label): Likewise.
+	* gnome-about.c (gnome_about_new): Likewise.
+	* gnome-font-selector.c (text_resize_text_widget): Likewise.
+
+
+Mon Feb 16 11:53:14 KST 1998  Changwoo Ryu  <cwryu adam kaist ac kr>
+
+	* gnome-client.h: Include <gtk/gtkobject.h>.
+
+Sun Feb 15 21:22:33 1998  Tom Tromey  <tromey cygnus com>
+
+	* libgnomeui.h: Include gnome-startup.h.
+	* Makefile.am (libgnomeui_la_SOURCES): Include gnome-startup.c.
+	(libgnomeuiinclude_HEADERS): Include gnome-startup.h.
+	* gnome-startup.c: New file.
+	* gnome-startup.h: New file.
+
+	* gnome-client.c (gnome_client_init): Initialize previous_id.
+	(gnome_real_client_destroy): Free previous_id if required.
+	(gnome_client_new_without_connection): Set previous_id.
+	(gnome_client_get_previous_id): New function.
+	* gnome-client.h (struct _GnomeClient): Added previous_id member.
+	(gnome_client_get_previous_id): Declare.
+
+	* gnome-client.h: Corrected comment.
+
+Sat Feb 14 17:15:18 1998  Tom Tromey  <tromey cygnus com>
+
+	* gnome-scores.h (test): Removed declaration.
+
+	* gnome-client.h: Removed RCS "Id" line.
+
+1998-02-15  Carsten Schaar  <nhadcasc fs-maphy uni-hannover de>
+
+	* gnome-client.h: Two arguments were named 'id'.  This broke
+	the objectiv-c interface, so I named them 'client_id' and
+	'user_id'.
+
+1998-02-14  Christoph Toshok <toshok hungry com>
+
+	* gnome-app-helper.c (gnome_app_create_menus_with_data): new
+	function, to handle the (common) case of creating an entire menu
+	system with the same callback data.
+	(gnome_app_create_toolbar_with_data): analogous addition for
+	toolbars.
+	(gnome_app_do_menu_create): add data parameter, which is passed in
+	by both gnome_app_create_menus_with_dat and
+	gnome_app_create_menus, and which is passed on to
+	gtk_signal_connect.  Also, add handling for new menuinfo type,
+	GNOME_APP_MENU_SEPARATOR.
+	(gnome_app_do_toolbar_create): analogous change for toolbars.
+	* gnome-app-helper.h: wrap with BEGIN_GNOME_DECLS/END_GNOME_DECLS
+	and add GNOME_APP_MENU_HELP enum.
+
+1998-02-14  Carsten Schaar  <nhadcasc fs-maphy uni-hannover de>
+
+	* libgnomeui.h: includes the new session management
+	support header file 'gnome-client.h' instead of the old one
+	'gnome-session.h'
+
+	* Makefile.am (libgnomeui_la_SOURCES): replaced 'gnome-session.c'
+	with 'gnome-client.c'
+	(libgnomeuiinclude_HEADERS): replaced 'gnome-session.h' with
+	'gnome-client.h'
+	(ted_demo_LDADD): added '$(INTLLIBS)'
+	(stock_demo_LDADD): added '$(INTLLIBS)'
+
+	* gnome-client.h: new file
+
+	* gnome-client.c: new file
+
+1998-02-13  Federico Mena Quintero  <federico nuclecu unam mx>
+
+	* gnome-about.c (gnome_fill_info): Made gdk_color_alloc() use the
+	widget default colormap instead of the system colormap.  This is
+	actually not the right way to do it; the about box should do all
+	color allocation via a GdkColorContext.  The cc structure should
+	reside in the GnomeAboutClass so that all about boxes can share it.
+
+	* gnome-stock.c (gnome_stock_pixmap_widget_state_changed): Added
+	gtk_widget_ref() when a new pixmap is created, because later they
+	may get gtk_container_remove()d.
+	(gnome_stock_pixmap_widget_size_request): Bad hack: if the pixmap
+	window is NULL, we return a default size.  The gnome-stock
+	architecture has to be rewritten, I think.  Please see my
+	forthcoming post to gnome-list for a proposal on how to do this.
+
+	* gnome-app.c: indentation fixes.
+
+	* gnome-stock.c (build_hash_key): Made routine use g_copy_strings().
+
+Fri Feb 13 19:03:21 1998  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gtk-ted.c (gtk_ted_parse_pos): Initialize flags to zero before
+	doing the parsing.
+
+Fri Feb 13 18:23:02 1998  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gnome-messagebox.c: Message boxes now take a variable number of
+	arguments instead of having 3 options at most.
+
+Fri Feb 13 18:09:46 1998  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gtk-ted.c (gtk_ted_update_position): More refcouting joy.
+
+Fri Feb 13 11:45:12 1998  Nuno Ferreira <nmrf rnl ist utl pt>
+
+	* gnome-app.c (gnome_app_configure_positions): use app->toolbar
+	when dealing with the toolbar, not app->menubar.
+
+Wed Feb 11 15:06:05 1998  Miguel de Icaza  <miguel nuclecu unam mx>
+
+	* gtk-ted.c (gtk_ted_widget_drop
+	gtk_ted_prepare_editable_widget): refcouting fixes
diff --git a/libgnomeui/DEPENDS.libgnomeui b/libgnomeui/DEPENDS.libgnomeui
new file mode 100644
index 0000000..b1739e7
--- /dev/null
+++ b/libgnomeui/DEPENDS.libgnomeui
@@ -0,0 +1,6 @@
+libglib
+libgdk
+libgtk
+libgnome
+liboaf
+libart_lgpl
diff --git a/libgnomeui/Makefile.am b/libgnomeui/Makefile.am
new file mode 100644
index 0000000..e843342
--- /dev/null
+++ b/libgnomeui/Makefile.am
@@ -0,0 +1,262 @@
+## Process this file with automake to produce Makefile.in
+
+SUBDIRS = pixmaps
+
+LIB_VERSION=0:0:0
+LIB_VERSION_NUM=0.0.0
+
+#
+# The targets
+#
+bin_PROGRAMS    = gnome_segv gnome-remote-bootstrap
+lib_LTLIBRARIES = libgnomeui-2.la
+
+#
+# Install location for header files
+#
+libgnomeuiincludedir = $(includedir)/gnome/$(GNOME_INTERFACE_VERSION)/libgnomeui
+
+INCLUDES = \
+	-I$(top_builddir)				\
+	-I$(top_srcdir)					\
+	-I$(top_srcdir)/intl				\
+	-I$(top_builddir)/intl				\
+        -DGNOMEUILIBDIR=\""$(libdir)"\" 		\
+        -DGNOMEUIDATADIR=\""$(datadir)"\" 		\
+        -DGNOMEUIPIXMAPDIR=\""$(datadir)/pixmaps"\"	\
+        -DGNOMEUIBINDIR=\""$(bindir)"\" 		\
+        -DGNOMEUILOCALSTATEDIR=\""$(localstatedir)"\" 	\
+        -DGNOMEUILOCALEDIR=\""$(gnomelocaledir)"\" 	\
+	-DG_LOG_DOMAIN=\"GnomeUI\"			\
+	$(WARN_CFLAGS)					\
+	$(LIBGNOMECANVAS_CFLAGS)			\
+	-DGTK_VERSION=\""$(GTK_VERSION)"\"		\
+	-DVERSION=\"$(VERSION)\"
+
+EXTRA_HEADERS = 
+
+noinst_HEADERS = \
+	libgnomeuiP.h
+
+libgnomeui_2_la_SOURCES = \
+	gnome-about.c			\
+	gnome-animator.c		\
+	gnome-app.c			\
+	gnome-appbar.c			\
+	gnome-app-helper.c		\
+	gnome-canvas-init.c		\
+	gnome-client.c			\
+	gnome-color-picker.c		\
+	gnome-cursors.c			\
+	gnome-dateedit.c		\
+	gnome-ditem-edit.c		\
+	gnome-dock.c			\
+	gnome-dock-band.c		\
+	gnome-dock-item.c		\
+	gnome-dock-layout.c		\
+	gnome-druid.c			\
+	gnome-druid-page.c		\
+	gnome-druid-page-edge.c		\
+	gnome-druid-page-standard.c	\
+	gnome-geometry.c		\
+	gnome-entry.c			\
+	gnome-selector.c		\
+	gnome-selectorP.h		\
+	gnome-icon-selector.c		\
+	gnome-file-selector.c		\
+        gnome-font-picker.c		\
+	gnome-helpsys.c			\
+	gnome-href.c			\
+	gnome-ice.c			\
+	gnome-icon-entry.c		\
+	gnome-init.c			\
+	gnome-less.c			\
+	gnome-mdi.c			\
+	gnome-mdiP.h			\
+	gnome-mdi-child.c		\
+	gnome-mdi-generic-child.c       \
+	gnome-mdi-session.c		\
+	gnome-pixmap.c			\
+	gnome-popup-menu.c		\
+	gnome-popup-help.c		\
+	gnome-pouch.c			\
+	gnome-pouchP.h			\
+	gnome-preferences.c		\
+	gnome-roo.c			\
+	gnome-stock.c			\
+	gnome-stock-ids.c		\
+        gnome-winhints.c		\
+        gnome-paper-selector.c		\
+	gnome-unit-spinner.c		\
+	gnometypes.c			\
+	gtk-clock.c			\
+	gtkdial.c			\
+	gtkpixmapmenuitem.c		\
+	gnome-icon-list.c		\
+	gnome-icon-item.c		\
+	gnome-icon-text.c		\
+	gnome-vfs-util.c		\
+	gnome-textfu.c			\
+	gnome-window.c			\
+	gnomemarshal-main.c		\
+	wap-textfu.c			\
+	$(noinst_HEADERS)
+
+## this lists all the non-generated headers
+gnome_headers = \
+	gnome-about.h			\
+        gnome-animator.h		\
+	gnome-app.h			\
+	gnome-appbar.h			\
+	gnome-app-helper.h		\
+	gnome-canvas-init.h		\
+	gnome-client.h			\
+	gnome-color-picker.h		\
+	gnome-cursors.h			\
+	gnome-dateedit.h		\
+	gnome-ditem-edit.h		\
+	gnome-dock.h			\
+	gnome-dock-band.h		\
+	gnome-dock-item.h		\
+	gnome-dock-layout.h		\
+	gnome-druid.h			\
+	gnome-druid-page.h		\
+	gnome-druid-page-edge.h		\
+	gnome-druid-page-standard.h	\
+	gnome-entry.h			\
+	gnome-file-selector.h		\
+        gnome-font-picker.h		\
+	gnome-gconf.h			\
+	gnome-geometry.h		\
+	gnome-helpsys.h			\
+	gnome-href.h			\
+	gnome-ice.h			\
+	gnome-icon-entry.h		\
+	gnome-icon-item.h		\
+	gnome-icon-list.h		\
+	gnome-icon-selector.h		\
+	gnome-icon-text.h		\
+	gnome-init.h			\
+	gnome-less.h			\
+	gnome-macros.h			\
+	gnome-mdi.h			\
+	gnome-mdi-child.h		\
+	gnome-mdi-generic-child.h	\
+	gnome-mdi-session.h		\
+	gnome-popup-menu.h		\
+	gnome-popup-help.h		\
+	gnome-pouch.h			\
+        gnome-paper-selector.h		\
+	gnome-preferences.h		\
+	gnome-pixmap.h			\
+	gnome-roo.h			\
+	gnome-selector.h		\
+	gnome-stock.h			\
+	gnome-stock-ids.h		\
+	gnome-types.h			\
+	gnome-uidefs.h			\
+	gnome-unit-spinner.h		\
+        gnome-winhints.h		\
+	gtkdial.h			\
+	gtk-clock.h			\
+	gtkpixmapmenuitem.h		\
+	libgnomeui.h			\
+	gnome-vfs-util.h		\
+	gnome-textfu.h			\
+	gnome-window.h			\
+	wap-textfu.h			\
+	oafgnome.h
+
+libgnomeuiinclude_HEADERS =		\
+	$(gnome_headers)		\
+	gnometypebuiltins.h
+
+gnome_remote_bootstrap_SOURCES=gnome-remote-bootstrap.c
+
+BUILT_SOURCES = \
+	gnometypebuiltins.h		\
+	gnometypebuiltins_evals.c	\
+	gnometypebuiltins_ids.c		\
+	gnometypebuiltins_vars.c	\
+	gnomemarshal.h			\
+	gnomemarshal.c
+
+# generate gnome.defs file from gnome-boxed.defs and *.h
+gnome.defs: $(GNOME_MAKEENUMS) gnome-boxed.defs $(gnome_headers)
+	cd $(srcdir) \
+	&& $(GNOME_MAKEENUMS) defs $(gnome_headers) > gd.tmp \
+	&& cat gnome-boxed.defs >> gd.tmp \
+	&& mv gd.tmp gnome.defs
+
+# generate type identifier header (GTK_TYPE_WIDGET_FLAGS)
+gnometypebuiltins.h: gnome.defs $(GNOME_MAKETYPES)
+	cd $(srcdir) \
+	&& LC_COLLATE=C $(GNOME_MAKETYPES) gnome.defs macros > gtb.tmp \
+	&& mv gtb.tmp gnometypebuiltins.h
+
+# generate type identifier variables (GTK_TYPE_WIDGET_FLAGS)
+gnometypebuiltins_vars.c: gnome.defs $(GNOME_MAKETYPES)
+	cd $(srcdir) \
+	&& LC_COLLATE=C $(GNOME_MAKETYPES) gnome.defs variables > gtbv.tmp \
+	&& mv gtbv.tmp gnometypebuiltins_vars.c
+
+# generate type entries for type-id registration
+gnometypebuiltins_ids.c: gnome.defs $(GNOME_MAKETYPES)
+	cd $(srcdir) \
+	&& LC_COLLATE=C $(GNOME_MAKETYPES) gnome.defs entries > gtbi.tmp \
+	&& mv gtbi.tmp gnometypebuiltins_ids.c
+
+# generate enum value arrays
+gnometypebuiltins_evals.c: $(GNOME_MAKEENUMS) gnome.defs
+	cd $(srcdir) \
+	&& $(GNOME_MAKEENUMS) arrays $(gnome_headers) > gtbe.tmp \
+	&& mv gtbe.tmp gnometypebuiltins_evals.c
+
+stamp-gnomemarshal.h: gnomemarshal.list
+	cd $(srcdir) \
+	&& glib-genmarshal --prefix=gnome_marshal gnomemarshal.list --header >> xgen-gmh \
+	&& (cmp -s xgen-gmh gnomemarshal.h || cp xgen-gmh gnomemarshal.h) \
+	&& rm -f xgen-gmh xgen-gmh~ \
+	&& echo timestamp > $(@F)
+
+gnomemarshal.h gnomemarshal.c: stamp-gnomemarshal.h
+	cd $(srcdir) \
+	&& glib-genmarshal --prefix=gnome_marshal gnomemarshal.list --body >> xgen-gmc \
+	&& cp xgen-gmc gnomemarshal.c \
+	&& rm -f xgen-gmc xgen-gmc~
+
+#######################
+
+gnome_segv_SOURCES = gnome_segv.c
+
+gtkrcdir = $(datadir)
+gtkrc_DATA = gtkrc gtkrc.el gtkrc.eo gtkrc.he gtkrc.hy gtkrc.ja \
+	gtkrc.ko gtkrc.ru gtkrc.tr gtkrc.th gtkrc.uk \
+	gtkrc.iso88592 gtkrc.iso88595 gtkrc.zh_CN gtkrc.zh_TW.Big5 \
+	gtkrc.ka_GE.georgianacademy gtkrc.ka_GE.georgianps \
+	gtkrc.vi_VN.tcvn gtkrc.vi_VN.viscii
+
+EXTRA_DIST =					\
+	$(gtkrc_DATA)				\
+	AUTHORS					\
+	gnome.defs 				\
+	gnomemarshal.list			\
+	gnome-boxed.defs			\
+	gnometypebuiltins_vars.c		\
+	gnometypebuiltins_ids.c			\
+	gnometypebuiltins_evals.c		\
+	portrait.xpm				\
+	landscape.xpm				\
+	libgnomeui-2.0.pc.in
+
+libgnomeui_2_la_LDFLAGS = \
+	-version-info $(LIB_VERSION)
+
+libgnomeui_2_la_LIBADD = \
+	$(LIBGNOMECANVAS_LIBS)
+
+LDADD = \
+	libgnomeui-2.la
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libgnomeui-2.0.pc
diff --git a/libgnomeui/TODO b/libgnomeui/TODO
new file mode 100644
index 0000000..0cceb13
--- /dev/null
+++ b/libgnomeui/TODO
@@ -0,0 +1,103 @@
+Todo and wishlist for libgnomeui. Please feel free to add, remove, or comment.
+You might sync the list to web-devel-2/content/news/status/libs.html 
+if you change stuff.
+
+In all cases, if it becomes apparent that the change would break lots of 
+stuff, we will have to not change it in this version though we may 
+deprecate something.
+
+An overall goal is to ask hard questions about how useful things are 
+and reduce some bloat. Also improve elegance and add more truly useful
+functionality.
+
+ * There are far too many image-display widgets. We have: GtkPixmap, 
+   GnomeStock, GnomePixmap, GtkImage, GnomeStockPixmapWidget, etc.
+   Should be fewer widgets with more features per widget. i.e. enhance
+   GnomePixmap to handle the GnomeStock case, at a minimum
+
+ * Fold in gdk-pixbuf dependency; remove Imlib
+
+ * Fold in Bonobo dependency
+
+ * Fold in gnome-vfs (move into place or add as dependency?)
+
+ * GnomeFileSelection using Bonobo and gnome-vfs
+
+ * Add/use Nat's new Bonobo-friendly menu stuff
+
+ * Remove at least one keybindings-configurability hack; maybe
+   add a good keybindings-configurability feature
+
+ * Remove GtkCauldron (replaced by libglade)
+
+ * Integrate with GnomePrint (i.e. make sure canvas can print,
+   make sure print-related widgets are in gnome-print)
+
+ * Font selection widgets that work with gnome-print (GnomeFont)
+
+ * Make canvas able to display GnomeFont
+
+ * Sync to GTK+ 1.4 and glib 1.4 (hopefully not too hard...)
+
+ * libunicode, Pango, etc. should be integrated and put into use.
+
+ * Color selection enhancement (perhaps in GTK, though GTK can't do 
+   a "custom palette" if we want that since it lacks the config 
+   database)
+
+ * Fix antialiased canvas
+
+ * Make libgnorba display-independent, and some other enhancements
+   as Elliot the CORBA dude sees fit
+
+ * Add a context help thing (like Windows' "What's this", or GtkTipsQuery)
+
+ * Fix up gnome_init() with something more extensible/customizable
+
+ * Remove or fully implement gnome-app-util.h
+
+ * Remove gnome-dns.h? I think there's another library that may be better.
+   For that matter gnome-vfs may handle this problem.
+
+ * Remove obsolete gnome-font-selector, replaced by GtkFontSelection
+
+ * Remove GnomeGuru, replaced by GnomeDruid
+
+ * Remove gnome-pixmap-entry (I think, maybe I mean GnomeIconSel, one 
+   of these things is deprecated IIRC)
+
+ * Remove gnome-less (too pointless) 
+
+ * Remove gnome-number-entry (ditto)
+
+ * Remove gnome-preferences.[hc] ?
+
+ * Remove gnome-properties.[hc] ? 
+
+ * Remove gnome-property-entries.[hc] ?
+
+ * Remove gnome-spell
+
+ * Remove gnome-startup if possible
+
+ * Remove gtk-ted
+
+ * Consider a new property box, addressing some problems:
+    - shouldn't be required to have a notebook if there's only 
+      one page
+    - should have try/revert like the control center
+
+ * We need stock icons for try/revert
+
+ * update gnome-winhints to reflect new window manager spec
+
+ * Use AbiWord centerDialog function in gnome_dialog_set_parent(),
+   it's nicer than the dumb thing GnomeDialog does
+
+ * Add object arguments to all GtkObject's in the library
+
+ * Add gnome-popup-menu and gnome-popup-help menu creation variants
+   that leave the user_data in the GnomeUIInfo struct
+
+ * Fix bugs!
+
diff --git a/libgnomeui/gnome-about.c b/libgnomeui/gnome-about.c
new file mode 100644
index 0000000..b265ffb
--- /dev/null
+++ b/libgnomeui/gnome-about.c
@@ -0,0 +1,1229 @@
+/* -*- Mode: C; c-set-style: linux indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Copyright (C) 1998 Cesar Miquel <miquel df uba ar>
+ * Based in gnome-about, copyright (C) 1998 Horacio J. Peña
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#include <config.h>
+#include "gnome-macros.h"
+
+#include "gnome-about.h"
+#include <libgnome/gnome-util.h>
+#include <libgnome/gnome-i18n.h>
+#include <libgnome/gnome-url.h>
+#include <libgnome/libgnome-init.h>
+#include <libgnomecanvas/gnome-canvas.h>
+#include <libgnomecanvas/gnome-canvas-line.h>
+#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
+#include <libgnomecanvas/gnome-canvas-text.h>
+#include <libgnomecanvas/gnome-canvas-pixbuf.h>
+#include <libgnomecanvas/gnome-canvas-util.h>
+#include <bonobo/bonobo-config-database.h>
+#include "gnome-cursors.h"
+#include "gnome-stock.h"
+#include <string.h>
+#include <gtk/gtk.h>
+
+#define GNOME_ABOUT_DEFAULT_WIDTH               100
+#define GNOME_ABOUT_MAX_WIDTH                   600
+#define BASE_LINE_SKIP                          0
+
+/* Layout */
+#define GNOME_ABOUT_PADDING_X 1
+#define GNOME_ABOUT_PADDING_Y 1
+
+#define GNOME_ABOUT_LOGO_PADDING_X 2
+#define GNOME_ABOUT_LOGO_PADDING_Y 0
+
+#define GNOME_ABOUT_TITLE_PADDING_X 1
+#define GNOME_ABOUT_TITLE_PADDING_Y 1
+#define GNOME_ABOUT_TITLE_PADDING_UP 6
+#define GNOME_ABOUT_TITLE_PADDING_DOWN 7
+
+#define GNOME_ABOUT_TITLE_URL_PADDING_UP 2
+#define GNOME_ABOUT_TITLE_URL_PADDING_DOWN 4
+
+#define GNOME_ABOUT_CONTENT_PADDING_X GNOME_ABOUT_TITLE_PADDING_X
+#define GNOME_ABOUT_CONTENT_PADDING_Y 1
+#define GNOME_ABOUT_CONTENT_SPACING 2
+#define GNOME_ABOUT_CONTENT_INDENT 3
+
+#define GNOME_ABOUT_COPYRIGHT_PADDING_UP 2
+#define GNOME_ABOUT_COPYRIGHT_PADDING_DOWN 4
+
+#define GNOME_ABOUT_AUTHORS_PADDING_Y 3
+#define GNOME_ABOUT_AUTHORS_INDENT 10
+#define GNOME_ABOUT_AUTHORS_URL_INDENT 10
+
+#define GNOME_ABOUT_COMMENTS_INDENT 3
+
+/* Options */
+#define GNOME_ABOUT_SHOW_URLS (priv->show_urls)
+#define GNOME_ABOUT_SHOW_LOGO (priv->show_logo)
+
+struct _GnomeAboutPrivate {
+	gchar *title; /* Program title */
+	gchar *url; /* Homepage URL */
+	gchar *copyright; /* Copyright */
+
+	/* Contact info */
+	GList *names, *author_urls, *author_emails;
+
+	gchar *comments;
+	GdkPixbuf *logo;
+
+	gint16 logo_width;
+	gint16 logo_height;
+	gint16 title_width;
+	gint16 title_height;
+	gint16 width;
+	gint16 height;
+
+	/* Colours */
+	GdkColor *title_fg;
+	GdkColor *title_bg;
+	GdkColor *contents_fg;
+	GdkColor *contents_bg;
+
+	gboolean show_urls;
+	gboolean show_logo;
+
+	/* Fonts */
+	GdkFont *font_title;
+	GdkFont *font_url;
+	GdkFont *font_copyright;
+	GdkFont *font_author;
+	GdkFont *font_names;
+	GdkFont *font_names_url;
+	GdkFont *font_comments;
+};
+
+static void gnome_about_class_init (GnomeAboutClass *klass);
+static void gnome_about_init       (GnomeAbout      *about);
+static void gnome_about_destroy    (GtkObject       *object);
+static void gnome_about_finalize   (GObject         *object);
+
+static void gnome_about_calc_size (GnomeAboutPrivate *priv);
+
+static void gnome_about_draw (GnomeCanvas *canvas, GnomeAboutPrivate *priv);
+
+static void gnome_about_load_logo (GnomeAboutPrivate *priv, const gchar *logo);
+
+static void gnome_about_display_comments (GnomeCanvasGroup *group,
+					  GdkFont *font,
+					  GdkColor *color,
+					  gdouble x, gdouble y, gdouble w,
+					  const gchar *comments);
+
+static gint gnome_about_item_cb (GnomeCanvasItem *item, GdkEvent
+				 *event, gpointer data);
+static void gnome_about_parse_name (gchar **name, gchar **email);
+
+static void gnome_about_fill_options (GtkWidget *widget,
+				      GnomeAboutPrivate *priv);
+
+/**
+ * gnome_about_get_type
+ *
+ * Returns the GtkType for the GnomeAbout widget.
+ **/
+/* here the get_type will be defined */
+GNOME_CLASS_BOILERPLATE (GnomeAbout, gnome_about,
+			 GtkDialog, gtk_dialog)
+
+static void
+gnome_about_class_init (GnomeAboutClass *klass)
+{
+	GtkObjectClass *object_class;
+	GObjectClass *gobject_class;
+
+	object_class = (GtkObjectClass *) klass;
+	gobject_class = (GObjectClass *) klass;
+
+	object_class->destroy = gnome_about_destroy;
+	gobject_class->finalize = gnome_about_finalize;
+}
+
+static void
+gnome_about_init (GnomeAbout *about)
+{
+	about->_priv = g_new0 (GnomeAboutPrivate, 1);
+}
+
+
+static void
+gnome_about_draw (GnomeCanvas *canvas, 
+		  GnomeAboutPrivate *priv)
+{
+	GnomeCanvasGroup *root;
+	GnomeCanvasItem *item, *item_email;
+	gdouble x, y, x2, y2, h, w;
+	GList *name, *name_url = 0, *name_email;
+	gchar *tmp;
+
+	root = gnome_canvas_root(canvas);
+
+	x = GNOME_ABOUT_PADDING_X;
+	y = GNOME_ABOUT_PADDING_Y;
+
+	/* Logo */
+	if (priv->logo && GNOME_ABOUT_SHOW_LOGO) {
+		y += GNOME_ABOUT_LOGO_PADDING_Y;
+		x = (priv->width - priv->logo_width) / 2;
+		item = gnome_canvas_item_new (root,
+					      gnome_canvas_pixbuf_get_type (), 
+					      "pixbuf", priv->logo, 
+					      "x", x, 
+					      "x_set", TRUE, 
+					      "y", y,
+					      "y_set", TRUE, NULL);
+		if (priv->url) {
+			gtk_signal_connect (GTK_OBJECT(item), "event",
+					    (GtkSignalFunc) gnome_about_item_cb,
+					    NULL);
+			gtk_object_set_data (GTK_OBJECT(item), "url",
+					     priv->url);
+		}
+		y += priv->logo_height + GNOME_ABOUT_LOGO_PADDING_Y;
+	}
+	
+	/* Draw the title */
+	if (priv->title) {
+		/* Title background */
+		x = GNOME_ABOUT_PADDING_X + GNOME_ABOUT_TITLE_PADDING_X;
+		y += GNOME_ABOUT_TITLE_PADDING_Y;
+		h = priv->title_height;
+		x2 = priv->width - (GNOME_ABOUT_TITLE_PADDING_X +
+				    GNOME_ABOUT_PADDING_X) - 1;
+		y2 = y + h - 1;
+		gnome_canvas_item_new (root,
+				       gnome_canvas_rect_get_type(),
+				       "x1", x,
+				       "y1", y,
+				       "x2", x2,
+				       "y2", y2,
+				       "fill_color_gdk", priv->title_bg,
+				       NULL);
+
+		/* Title text */
+		x += priv->width / 2;
+		y += GNOME_ABOUT_TITLE_PADDING_UP;
+		item = gnome_canvas_item_new (root,
+					      gnome_canvas_text_get_type(),
+					      "x", x,
+					      "y", y,
+					      "anchor", GTK_ANCHOR_NORTH,
+					      "fill_color_gdk", priv->title_fg,
+					      "text", priv->title,
+					      "font_gdk", priv->font_title,
+					      NULL);
+		if (priv->url) {
+			gtk_signal_connect(GTK_OBJECT(item), "event",
+					   (GtkSignalFunc) gnome_about_item_cb,
+					   priv->title_fg);
+			gtk_object_set_data(GTK_OBJECT(item), "url", priv->url);
+		}
+
+		y += priv->font_title->ascent + priv->font_title->descent +
+			GNOME_ABOUT_TITLE_PADDING_DOWN;
+		if (GNOME_ABOUT_SHOW_URLS && priv->url) {
+			y += GNOME_ABOUT_TITLE_URL_PADDING_UP;
+			item = gnome_canvas_item_new (root,
+						      gnome_canvas_text_get_type(),
+						      "x", x,
+						      "y", y,
+						      "anchor", GTK_ANCHOR_NORTH,
+						      "fill_color_gdk", priv->title_fg,
+						      "text", priv->url,
+						      "font_gdk", priv->font_url,
+						      NULL);
+			gtk_signal_connect(GTK_OBJECT(item), "event",
+					   (GtkSignalFunc)gnome_about_item_cb,
+					   priv->title_fg);
+			gtk_object_set_data(GTK_OBJECT(item), "url", priv->url);
+			y += priv->font_url->ascent +
+				priv->font_url->descent +
+				GNOME_ABOUT_TITLE_URL_PADDING_DOWN;		
+		}
+		x = GNOME_ABOUT_PADDING_X;
+		y += GNOME_ABOUT_TITLE_PADDING_Y;
+	}
+	
+	/* Contents */
+	if (priv->copyright || priv->names || priv->comments) {
+		x = GNOME_ABOUT_PADDING_X + GNOME_ABOUT_CONTENT_PADDING_X;
+		y += GNOME_ABOUT_CONTENT_PADDING_Y;
+		x2 = priv->width - (GNOME_ABOUT_CONTENT_PADDING_X +
+				    GNOME_ABOUT_PADDING_X) - 1;
+		y2 = priv->height - (GNOME_ABOUT_CONTENT_PADDING_Y +
+				     GNOME_ABOUT_PADDING_Y) - 1;
+		gnome_canvas_item_new(root,
+				      gnome_canvas_rect_get_type(),
+				      "x1", x,
+				      "y1", y,
+				      "x2", x2,
+				      "y2", y2,
+				      "fill_color_gdk", priv->contents_bg,
+				      NULL);
+	}
+	
+	/* Copyright message */
+	if (priv->copyright) {
+		x = GNOME_ABOUT_PADDING_X +
+			GNOME_ABOUT_CONTENT_PADDING_X +
+			GNOME_ABOUT_CONTENT_INDENT;
+		y += GNOME_ABOUT_CONTENT_SPACING +
+			GNOME_ABOUT_COPYRIGHT_PADDING_UP;
+		gnome_canvas_item_new (root,
+				       gnome_canvas_text_get_type(),
+				       "x", x,
+				       "y", y,
+				       "anchor", GTK_ANCHOR_NORTH_WEST,
+				       "fill_color_gdk", priv->contents_fg,
+				       "text", priv->copyright,
+				       "font_gdk", priv->font_copyright,
+				       NULL);
+
+		y += priv->font_copyright->ascent +
+			priv->font_copyright->descent +
+			GNOME_ABOUT_COPYRIGHT_PADDING_DOWN;
+	}
+
+	/* Authors header */
+	if (priv->names) {
+		y += GNOME_ABOUT_CONTENT_SPACING;
+		x = GNOME_ABOUT_PADDING_X +
+			GNOME_ABOUT_CONTENT_PADDING_X +
+			GNOME_ABOUT_CONTENT_INDENT;
+		if (g_list_length (priv->names) == 1)
+			gnome_canvas_item_new (root,
+					       gnome_canvas_text_get_type(),
+					       "x", x,
+					       "y", y,
+					       "anchor", GTK_ANCHOR_NORTH_WEST,
+					       "fill_color_gdk", priv->contents_fg,
+					       "text", _("Author:"),
+					       "font_gdk", priv->font_author,
+					       NULL);
+		else
+			gnome_canvas_item_new (root,
+					       gnome_canvas_text_get_type(),
+					       "x", x,
+					       "y", y,
+					       "anchor", GTK_ANCHOR_NORTH_WEST,
+					       "fill_color_gdk", priv->contents_fg,
+					       "text", _("Authors:"),
+					       "font_gdk", priv->font_author,
+					       NULL);
+	}
+	x += gdk_string_measure (priv->font_author, _("Authors:")) +
+		GNOME_ABOUT_AUTHORS_INDENT;
+
+	/* Authors list */
+	name = g_list_first (priv->names);
+	name_email = g_list_first (priv->author_emails);
+	if (priv->author_urls)
+	    name_url = g_list_first (priv->author_urls);
+
+	while (name) {
+		h = priv->font_names->descent + priv->font_names->ascent;
+		w = gdk_string_measure(priv->font_names, (gchar*) name->data) +
+			gdk_string_measure(priv->font_names, " ");
+
+		item = gnome_canvas_item_new (root,
+					      gnome_canvas_text_get_type(),
+					      "x", x,
+					      "y", y,
+					      "anchor", GTK_ANCHOR_NORTH_WEST,
+					      "fill_color_gdk", priv->contents_fg,
+					      "text", (gchar*) name->data,
+					      "font_gdk", priv->font_names,
+					      NULL);
+
+		if (name_email->data) {
+			x2 = x + w;
+			tmp = g_strdup_printf("<%s>", (gchar*) name_email->data);
+			item_email = gnome_canvas_item_new (root,
+							    gnome_canvas_text_get_type(),
+							    "x", x2,
+							    "y", y,
+							    "anchor", GTK_ANCHOR_NORTH_WEST,
+							    "fill_color_gdk", priv->contents_fg,
+							    "text", tmp,
+							    "font_gdk", priv->font_names,
+							    NULL);
+
+			tmp = g_strdup_printf("mailto:%s";, (gchar*) name_email->data);
+			gtk_signal_connect (GTK_OBJECT (item_email), "event",
+					    (GtkSignalFunc) gnome_about_item_cb,
+					    priv->contents_fg);
+			gtk_object_set_data_full (GTK_OBJECT (item_email),
+						  "url", tmp,
+						  (GtkDestroyNotify) g_free);
+		}
+		
+		y += h + BASE_LINE_SKIP;
+		name = name->next;
+		name_email = name_email->next;
+
+		if (name_url) {
+			if (name_url->data) {
+				gtk_signal_connect (GTK_OBJECT(item), "event",
+						    (GtkSignalFunc) gnome_about_item_cb,
+						    priv->contents_fg);
+				gtk_object_set_data(GTK_OBJECT(item),
+						    "url", 
+						    (gchar*)name_url->data);
+
+				if (GNOME_ABOUT_SHOW_URLS) {
+					x += GNOME_ABOUT_AUTHORS_URL_INDENT;
+					h = priv->font_names_url->descent + 
+						priv->font_names->ascent;
+
+					item = gnome_canvas_item_new (root,
+								      gnome_canvas_text_get_type(),
+								      "x", x,
+								      "y", y,
+								      "anchor", GTK_ANCHOR_NORTH_WEST,
+								      "fill_color_gdk", priv->contents_fg,
+								      "text", (gchar*) name_url->data,
+								      "font_gdk", priv->font_names_url,
+								      NULL);
+					gtk_signal_connect( GTK_OBJECT(item), 
+							    "event",
+							    (GtkSignalFunc) gnome_about_item_cb,
+							    priv->contents_fg);
+					gtk_object_set_data(GTK_OBJECT(item),
+							    "url", 
+							    (gchar*)name_url->data);
+					y += h + BASE_LINE_SKIP;
+					x -= GNOME_ABOUT_AUTHORS_URL_INDENT;
+				}
+			}
+			name_url = name_url->next;
+		}
+	}
+	
+	if (priv->comments) {
+		y += GNOME_ABOUT_CONTENT_SPACING;
+		x = GNOME_ABOUT_PADDING_X +
+			GNOME_ABOUT_CONTENT_PADDING_X +
+			GNOME_ABOUT_CONTENT_INDENT +
+			GNOME_ABOUT_COMMENTS_INDENT;
+		w = priv->width - (2 * (GNOME_ABOUT_PADDING_X +
+					GNOME_ABOUT_CONTENT_PADDING_X) +
+				   GNOME_ABOUT_CONTENT_INDENT +
+				   GNOME_ABOUT_PADDING_Y);
+		gnome_about_display_comments(root, priv->font_comments,
+					     priv->contents_fg, x, y,
+					     w, priv->comments);
+	}
+
+	gnome_canvas_set_scroll_region(GNOME_CANVAS(canvas), 0, 0, priv->width,
+				       priv->height);
+	gtk_widget_set_usize(GTK_WIDGET(canvas), priv->width, priv->height);
+}
+
+static void
+gnome_about_display_comments (GnomeCanvasGroup *group,
+			      GdkFont *font,
+			      GdkColor *color,
+			      gdouble x, gdouble y, gdouble w,
+			      const gchar *comments)
+{
+	char *tok, *p1, *p2, *p3, c;
+	char *buffer;
+	gdouble ypos, width;
+	int done;
+	GList *par, *tmp;
+	char *tokp;
+
+	width = w - 16;
+	if (comments == NULL)
+		return;
+
+	/* we need a buffer because strtok will modify the string! */
+	/* strtok is a cool but dangerous function. */
+	buffer = g_strdup(comments);
+
+	ypos = y;
+
+	/* Make a list with each paragraph */
+	par = (GList *)NULL;
+
+	for (tok = strtok_r (buffer, "\n", &tokp); tok;
+	     tok = strtok_r (NULL, "\n", &tokp)) {
+		par = g_list_append (par, g_strdup(tok));
+	}
+
+	/* Print each paragraph */
+	tmp = par;
+	while (tmp != NULL) {
+		done = FALSE;
+		p1 = p2 = tmp->data;
+		while (!done) {
+			c = *p1; *p1 = 0;
+			while (gdk_string_measure(font, p2) < width && c != 0) {
+				*p1 = c;
+				p1++;
+				c = *p1;
+				*p1 = 0;
+			}
+			switch (c) {
+			case ' ':
+				p1++;
+				gnome_canvas_item_new (group,
+						       gnome_canvas_text_get_type(),
+						       "x", x,
+						       "y", ypos,
+						       "anchor", GTK_ANCHOR_NORTH_WEST,
+						       "fill_color_gdk",
+						       color,
+						       "text", p2,
+						       "font_gdk", font,
+						       NULL);
+				
+				break;
+			case '\0':
+				done = TRUE;
+				gnome_canvas_item_new (group,
+						       gnome_canvas_text_get_type(),
+						       "x", x,
+						       "y", ypos,
+						       "anchor", GTK_ANCHOR_NORTH_WEST,
+						       "fill_color_gdk",
+						       color,
+						       "text", p2,
+						       "font_gdk", font,
+						       NULL);
+				break;
+			default:
+				p3 = p1;
+				while (*p1 != ' ' && p1 > p2)
+					p1--;
+				if (p1 == p2) {
+					gnome_canvas_item_new (group,
+							       gnome_canvas_text_get_type(),
+							       "x", x,
+							       "y", ypos,
+							       "anchor", GTK_ANCHOR_NORTH_WEST,
+							       "fill_color_gdk",
+							       color,
+							       "text", p2,
+							       "font_gdk", font,
+							       NULL);
+
+					*p3 = c;
+					p1 = p3;
+					break;
+				} else {
+					*p3 = c;
+					*p1 = 0;
+					p1++;
+					gnome_canvas_item_new (group,
+							       gnome_canvas_text_get_type(),
+							       "x", x,
+							       "y", ypos,
+							       "anchor", GTK_ANCHOR_NORTH_WEST,
+							       "fill_color_gdk",
+							       color,
+							       "text", p2,
+							       "font_gdk", font,
+							       NULL);
+				}
+				break;
+			}
+			ypos += font->descent + font->ascent;
+			p2 = p1;
+		}
+		tmp = tmp->next;
+		ypos += BASE_LINE_SKIP;	/* Skip a bit */
+	}
+
+	/* Free list memory */
+	g_list_foreach(par, (GFunc)g_free, NULL);
+	g_list_free (par);
+	g_free (buffer);
+
+	return;
+}
+
+
+/* ----------------------------------------------------------------------
+   NAME:	gnome_about_calc_size
+   DESCRIPTION:	Calculates size of window
+   ---------------------------------------------------------------------- */
+
+static void
+gnome_about_calc_size (GnomeAboutPrivate *priv)
+{
+	GList *name, *email = NULL;
+	GList *urls = NULL;
+	gint num_pars, i, h, w, len[5], tmpl, pw;
+	gint title_h;
+	const gchar *p;
+	gfloat maxlen;
+	
+	w = GNOME_ABOUT_DEFAULT_WIDTH;
+	h = GNOME_ABOUT_PADDING_Y;
+
+	pw = 0; /* Maximum of title and content padding */
+
+	len[0] = 0;
+	len[1] = 0;
+	title_h = 0;
+	if (priv->title) {
+		h += GNOME_ABOUT_TITLE_PADDING_Y;
+		len[0] = gdk_string_measure (priv->font_title,
+					     priv->title);
+		title_h += (priv->font_title->descent + 
+			    GNOME_ABOUT_TITLE_PADDING_DOWN) +
+			(priv->font_title->ascent + 
+			 GNOME_ABOUT_TITLE_PADDING_UP);
+
+		h += GNOME_ABOUT_TITLE_PADDING_Y;
+		pw = GNOME_ABOUT_TITLE_PADDING_X;
+		if (GNOME_ABOUT_SHOW_URLS && priv->url) {
+			title_h += priv->font_url->ascent +
+				GNOME_ABOUT_TITLE_URL_PADDING_UP +
+				priv->font_url->descent +
+				GNOME_ABOUT_TITLE_URL_PADDING_DOWN;
+			len[1] = gdk_string_measure (priv->font_url, 
+						     priv->url);
+		}
+	}
+	priv->title_height = title_h;
+	h += title_h;
+
+	if (priv->copyright || priv->names || priv->comments)
+	{
+		h += 2 * GNOME_ABOUT_CONTENT_PADDING_Y;
+		pw = MAX(pw, GNOME_ABOUT_CONTENT_PADDING_X);
+	}
+
+	len[2] = 0;
+	if (priv->copyright) {
+		h += priv->font_copyright->descent +
+			priv->font_copyright->ascent +
+			GNOME_ABOUT_COPYRIGHT_PADDING_UP +
+			GNOME_ABOUT_COPYRIGHT_PADDING_DOWN +
+			GNOME_ABOUT_CONTENT_SPACING;
+		len[2] = gdk_string_measure (priv->font_copyright, 
+					     priv->copyright);
+	}
+
+	len[3] = 0;
+	len[4] = 0;
+	if (priv->names) {
+		name = g_list_first (priv->names);
+		if (priv->author_emails)
+			email = g_list_first (priv->author_emails);
+		if (GNOME_ABOUT_SHOW_URLS && priv->author_urls)
+			urls = g_list_first (priv->author_urls);
+		while (name) {
+			tmpl = gdk_string_measure (priv->font_names, name->data);
+			if (email)
+				if (email->data) {
+					tmpl += gdk_string_measure(
+						priv->font_names, " ");
+					tmpl += gdk_string_measure(
+						priv->font_names,
+						(gchar*)email->data);
+				}
+			if (tmpl > len[3])
+				len[3] = tmpl;
+			h += (priv->font_names->descent +
+			      priv->font_names->ascent) +
+				BASE_LINE_SKIP;
+
+			if (GNOME_ABOUT_SHOW_URLS && urls) {
+				if (urls->data) {
+					tmpl = gdk_string_measure (priv->font_names_url, urls->data);
+					if (tmpl > len[4])
+						len[4] = tmpl;
+					h += (priv->font_names_url->descent +
+					      priv->font_names_url->ascent) + BASE_LINE_SKIP;
+				}
+				urls = urls->next;
+			}
+			name = name->next;
+			if (email)
+				email = email->next;
+		}
+		tmpl = gdk_string_measure (priv->font_names, _("Authors: "));
+		len[3] += tmpl +
+			GNOME_ABOUT_PADDING_X +
+			GNOME_ABOUT_CONTENT_PADDING_X +
+			GNOME_ABOUT_CONTENT_INDENT +
+			GNOME_ABOUT_AUTHORS_INDENT;
+		h += GNOME_ABOUT_AUTHORS_PADDING_Y +
+			GNOME_ABOUT_CONTENT_SPACING;
+	}
+	
+	maxlen = (gfloat) w;
+	for (i = 0; i < 5; i++)
+		if (len[i] > maxlen)
+			maxlen = (gfloat) len[i];
+	
+	w = (int) (maxlen * 1.2);
+	if (w > GNOME_ABOUT_MAX_WIDTH)
+		w = GNOME_ABOUT_MAX_WIDTH;
+
+	if (priv->comments) {
+		h += GNOME_ABOUT_CONTENT_SPACING;
+		num_pars = 1;
+		p = priv->comments;
+		while (*p != '\0') {
+			if (*p == '\n')
+				num_pars++;
+			p++;
+		}
+		
+		i = gdk_string_measure (priv->font_comments, priv->comments);
+		i /= w - 16;
+		i += 1 + num_pars;;
+		h += i * (priv->font_comments->descent + priv->font_comments->ascent);
+	}
+
+	priv->width = w + 2 * (GNOME_ABOUT_PADDING_X + pw);
+	priv->height = h + GNOME_ABOUT_PADDING_Y;
+
+	priv->height += 4 + priv->logo_height;
+	priv->width = MAX (priv->width, (priv->logo_width + 2 *
+					 (GNOME_ABOUT_PADDING_X +
+					  GNOME_ABOUT_LOGO_PADDING_X)));
+	
+	return;
+}
+
+static void
+gnome_about_load_logo(GnomeAboutPrivate *priv, 
+		      const gchar *logo)
+{
+	gchar *filename;
+
+	if (logo && GNOME_ABOUT_SHOW_LOGO) {
+		if (g_path_is_absolute (logo) && g_file_test (logo, G_FILE_TEST_EXISTS))
+			filename = g_strdup (logo);
+		else
+			filename = gnome_program_locate_file
+				(gnome_program_get (),
+				 GNOME_FILE_DOMAIN_PIXMAP,
+				 logo, TRUE, NULL);
+		
+		if (filename != NULL) {
+			GdkPixbuf *pixbuf;
+			GError *error;
+
+			error = NULL;
+			pixbuf = gdk_pixbuf_new_from_file(filename, &error);
+			if (error != NULL) {
+				g_warning (G_STRLOC ": cannot load `%s': %s",
+					   filename, error->message);
+				g_error_free (error);
+			}
+
+			if (pixbuf != NULL) {
+				priv->logo = pixbuf;
+				priv->logo_width = gdk_pixbuf_get_width (pixbuf);
+				priv->logo_height = gdk_pixbuf_get_height (pixbuf);
+				
+			}
+			
+			g_free (filename);
+		}
+	}
+}
+
+/* ----------------------------------------------------------------------
+   NAME:	gnome_fill_info
+   DESCRIPTION:	
+   ---------------------------------------------------------------------- */
+
+static void
+gnome_about_fill_info (GtkWidget *widget,
+		       GnomeAboutPrivate *priv,
+		       const gchar *title,
+		       const gchar *version,
+		       const gchar *url,
+		       const gchar *copyright,
+		       const gchar **authors,
+		       const gchar **author_urls,
+		       const gchar *comments,
+		       const gchar *logo)
+{
+	int author_num = 0, i;
+
+	/* Fill options */
+	gnome_about_fill_options (widget, priv);
+
+	/* Load logo */
+	gnome_about_load_logo (priv, logo);
+	
+	/* fill struct */
+	if (title)
+		priv->title = g_strconcat (title, " ", 
+					   version ? version : "", NULL);
+	else
+		priv->title = NULL;
+	
+	if (url)
+		priv->url = g_strdup (url);
+	else
+		priv->url = NULL;
+	
+	if (copyright)
+		priv->copyright = g_strdup (copyright);
+	else
+		priv->copyright = NULL;
+
+	if (comments)
+		priv->comments = g_strdup (comments);
+	else
+		priv->comments = NULL;
+
+	if (authors && authors[0]) {
+		gchar *name, *email;
+		while (*authors) {
+			name = g_strdup (*authors);
+			gnome_about_parse_name (&name, &email);
+			
+			priv->names = g_list_append (priv->names, name);
+			priv->author_emails = g_list_append (priv->author_emails, 
+							     email);
+			
+			authors++;
+			author_num++;
+		}
+	}
+
+	priv->author_urls = NULL;
+	if (author_urls) {
+		for (i = 0; i < author_num; i++, author_urls++) {
+			priv->author_urls = g_list_append (priv->author_urls,
+							 g_strdup (*author_urls));
+		}
+	}
+
+        /* Calculate width of window */
+	gnome_about_calc_size (priv);
+}
+
+static void gnome_about_fill_options (GtkWidget *widget,
+				      GnomeAboutPrivate *priv)
+{
+	GtkStyle *style;
+    
+	Bonobo_ConfigDatabase cd = gnome_program_get_config_database (gnome_program_get ());
+
+	g_return_if_fail (priv != NULL);
+
+	/* Read GConf options */
+	priv->show_urls = bonobo_config_get_boolean (cd, "/about/show_urls", NULL);
+	priv->show_logo = bonobo_config_get_boolean (cd, "/about/show_logo", NULL);
+	
+	/* Create fonts and get colors*/
+	/* FIXME: dirty hack, but it solves i18n problem without rewriting the
+	   drawing code..  */
+  	GTK_WIDGET_SET_FLAGS(widget, GTK_RC_STYLE); 
+	style = gtk_style_ref (widget->style);
+	gtk_widget_ensure_style (widget);
+
+	gtk_widget_set_name (widget, "Title");
+	priv->font_title = gdk_font_ref (widget->style->font);
+	priv->title_bg = gdk_color_copy (&widget->style->bg[GTK_STATE_NORMAL]);
+	g_print ("title:RGB, %d, %d, %d\n", priv->title_bg->red,
+		 priv->title_bg->green, priv->title_bg->blue);
+	priv->title_fg = gdk_color_copy (&widget->style->fg[GTK_STATE_NORMAL]);
+	gdk_color_alloc (gtk_widget_get_default_colormap (), priv->title_bg);
+	gdk_color_alloc (gtk_widget_get_default_colormap (), priv->title_fg);
+
+	
+	gtk_widget_set_name (widget, "TitleUrl");
+	gtk_widget_ensure_style (widget);
+	priv->font_url = gdk_font_ref (widget->style->font);
+	
+	gtk_widget_set_name (widget, "Copyright");
+	priv->font_copyright = gdk_font_ref (widget->style->font);
+	
+	gtk_widget_set_name (widget, "Author");
+	priv->font_author = gdk_font_ref (widget->style->font);
+
+	gtk_widget_set_name (widget, "Names");
+	priv->font_names = gdk_font_ref (widget->style->font);
+
+	gtk_widget_set_name (widget, "NamesUrl");
+	priv->font_names_url = gdk_font_ref (widget->style->font);
+	
+	gtk_widget_set_name (widget, "Comments");
+	priv->font_comments = gdk_font_ref (widget->style->font);
+	priv->contents_bg = gdk_color_copy (&widget->style->bg[GTK_STATE_NORMAL]);
+	priv->contents_fg = gdk_color_copy (&widget->style->fg[GTK_STATE_NORMAL]);
+	gdk_color_alloc (gtk_widget_get_default_colormap (), priv->contents_bg);
+	gdk_color_alloc (gtk_widget_get_default_colormap (), priv->contents_fg);
+	
+	gtk_widget_set_style (widget, style);
+	gtk_style_unref (style);
+
+}
+
+/* ----------------------------------------------------------------------
+   NAME:	gnome_about_destroy
+   DESCRIPTION:	
+   ---------------------------------------------------------------------- */
+
+static void
+gnome_about_destroy (GtkObject *object)
+{
+	GnomeAbout *self = GNOME_ABOUT(object);
+
+	/* remember, destroy can be run multiple times! */
+
+	if(self->_priv) {
+		/* Free memory used for title, copyright and comments */
+		g_free (self->_priv->title);
+		g_free (self->_priv->copyright);
+		g_free (self->_priv->comments);
+
+		/* Free GUI's. */
+		gdk_font_unref (self->_priv->font_title);
+		gdk_font_unref (self->_priv->font_url);
+		gdk_font_unref (self->_priv->font_copyright);
+		gdk_font_unref (self->_priv->font_author);
+		gdk_font_unref (self->_priv->font_names);
+		gdk_font_unref (self->_priv->font_comments);
+
+		/* Free colors */
+		gdk_color_free (self->_priv->title_fg);
+		gdk_color_free (self->_priv->title_bg);
+		gdk_color_free (self->_priv->contents_fg);
+		gdk_color_free (self->_priv->contents_bg);
+
+
+		/* Free memory used for authors */
+		g_list_foreach (self->_priv->names, (GFunc) g_free, NULL);
+		g_list_free (self->_priv->names);
+	}
+	
+	g_free (self->_priv);
+	self->_priv = NULL;
+
+	GNOME_CALL_PARENT_HANDLER (GTK_OBJECT_CLASS, destroy, (object));
+}
+
+static void
+gnome_about_finalize (GObject *object)
+{
+	GNOME_CALL_PARENT_HANDLER (G_OBJECT_CLASS, finalize, (object));
+}
+
+/**
+ * gnome_about_new
+ * @title: Name of app.
+ * @version: version number
+ * @copyright: copyright string
+ * @authors: %NULL terminated list of authors
+ * @comments: Other comments
+ * @logo: a logo pixmap file.
+ *
+ * Creates a new GNOME About dialog.  @title, @version,
+ * @copyright, and @authors are displayed first, in that order.
+ * @comments is typically the location for multiple lines of text, if
+ * necessary.  (Separate with "\n".)  @logo is the filename of a
+ * optional pixmap to be displayed in the dialog, typically a product or
+ * company logo of some sort; set to %NULL if no logo file is available.
+ *
+ * Returns:
+ * &GtkWidget pointer to new dialog
+ **/
+
+GtkWidget*
+gnome_about_new (const gchar *title,
+		 const gchar *version,
+		 const gchar *copyright,
+		 const gchar **authors,
+		 const gchar *comments,
+		 const gchar *logo)
+{
+    return gnome_about_new_with_url (title, version, NULL, copyright,
+				     authors, NULL, comments, logo);
+}
+
+/**
+ * gnome_about_new_with_url
+ * @title: Name of app.
+ * @version: version number
+ * @url: Application URL
+ * @copyright: copyright string
+ * @authors: %NULL terminated list of authors
+ * @author_urls: %NULL terminated list of URLs associated with the authors
+ * @comments: Other comments
+ * @logo: a logo pixmap file.
+ *
+ * Creates a new GNOME About dialog.  @title, @version,
+ * @copyright, and @authors are displayed first, in that order.
+ * @comments is typically the location for multiple lines of text, if
+ * necessary.  (Separate with "\n".)  @logo is the filename of a
+ * optional pixmap to be displayed in the dialog, typically a product or
+ * company logo of some sort; set to %NULL if no logo file is available.
+ * The @url argument specifies a URL to load if the user clicks on
+ * either the title or the logo. Pass %NULL if no URL is available.
+ *
+ * The @author_urls is a list of URLs you'd like to be associated with
+ * the authors. It must be either %NULL or exactly as long as @authors.
+ *
+ * Returns:
+ * &GtkWidget pointer to new dialog
+ **/
+
+GtkWidget*
+gnome_about_new_with_url (const gchar *title,
+			  const gchar *version,
+			  const gchar *url,
+			  const gchar *copyright,
+			  const gchar **authors,
+			  const gchar **author_urls,
+			  const gchar *comments,
+			  const gchar *logo)
+{
+    GnomeAbout *about;
+    
+    if (!title) title = "";
+    if (!version) version = "";
+    if (!copyright) copyright = "";
+/*	g_return_val_if_fail (authors != NULL, NULL);*/
+    if (!comments) comments = "";
+    
+    about = gtk_type_new (gnome_about_get_type());
+    
+    gnome_about_construct(about, title, version, url, copyright,
+			  authors, author_urls, comments, logo);
+    
+    return GTK_WIDGET (about);
+}
+
+/**
+ * gnome_about_construct
+ * @about: Pointer to new GNOME about object
+ * @title: Name of app.
+ * @version: version number
+ * @url: Application URL
+ * @copyright: copyright string
+ * @authors: %NULL terminated list of authors
+ * @author_urls: %NULL terminated list of URLs associated with the authors
+ * @comments: Other comments
+ * @logo: a logo pixmap file.
+ *
+ * Constructs a new GNOME About dialog, given an object
+ * @about newly created via the Gtk type system.  @title, @version,
+ * @copyright, and @authors are displayed first, in that order.
+ * @comments is typically the location for multiple lines of text, if
+ * necessary.  (Separate with "\n".)  @logo is the filename of a
+ * optional pixmap to be displayed in the dialog, typically a product or
+ * company logo of some sort; set to %NULL if no logo file is available.
+ * The @url argument specifies a URL to load if the user clicks on
+ * either the title or the logo. Pass %NULL if no URL is available.
+ *
+ * The @author_urls is a list of URLs you'd like to be associated with
+ * the authors. It must be either %NULL or exactly as long as @authors.
+ *
+ * Note:
+ * Only for use by bindings to languages other than C; don't use
+ * in applications.
+ *
+ */
+void
+gnome_about_construct (GnomeAbout *about,
+		       const gchar *title,
+		       const gchar *version,
+		       const gchar *url,
+		       const gchar *copyright,
+		       const gchar **authors,
+		       const gchar **author_urls,
+		       const gchar *comments,
+		       const gchar *logo)
+{
+	GtkWidget *frame;
+	GtkWidget *canvas;
+	
+	gtk_window_set_title (GTK_WINDOW(about), _("About"));
+	gtk_window_set_policy (GTK_WINDOW(about), FALSE, FALSE, TRUE);
+
+	/* x = (gdk_screen_width ()  - w) / 2; */
+	/* y = (gdk_screen_height () - h) / 2;    */
+	/* gtk_widget_set_uposition ( GTK_WIDGET (about), x, y); */
+
+	frame = gtk_frame_new (NULL);
+	gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
+	gtk_container_set_border_width (GTK_CONTAINER (frame), 4);
+	gtk_container_add(GTK_CONTAINER (GTK_DIALOG(about)->vbox),
+			  GTK_WIDGET(frame));
+	gtk_widget_show (frame);
+
+        gtk_widget_push_colormap(gdk_rgb_get_cmap());
+	canvas = gnome_canvas_new ();
+        gtk_widget_pop_colormap();
+	gtk_container_add (GTK_CONTAINER(frame), canvas);
+
+	/* Fill the GnomeAboutPriv structure */
+	gnome_about_fill_info (GTK_WIDGET (about),
+			       about->_priv,
+			       title, version, url,
+			       copyright,
+			       authors, author_urls,
+			       comments,
+			       logo);
+
+	gnome_about_draw (GNOME_CANVAS(canvas), about->_priv);
+	gtk_widget_show (canvas);
+
+	gtk_dialog_add_button (GTK_DIALOG (about),
+			       GTK_STOCK_BUTTON_OK,
+			       GTK_RESPONSE_OK);
+}
+
+static gint
+gnome_about_item_cb(GnomeCanvasItem *item, GdkEvent *event,
+		    gpointer data)
+{
+	
+	gchar *url = gtk_object_get_data(GTK_OBJECT(item), "url");
+	GdkCursor *cursor;
+	GdkWindow *window = GTK_WIDGET(item->canvas)->window;
+	static GnomeCanvasItem *underline = NULL;
+
+	if (!url)
+		return 0;
+	
+	
+	switch (event->type) {
+	case GDK_ENTER_NOTIFY:
+		if (url) {
+			if (underline == NULL) {
+				gdouble x1, x2, y1, y2;
+				GnomeCanvasPoints *points;
+				GdkColor *color = (GdkColor*)data;
+				
+				if (color) {
+					points = gnome_canvas_points_new (2);
+					
+					gnome_canvas_item_get_bounds (item, &x1, &y1, &x2, &y2);
+					
+					points->coords[0] = x1;
+					points->coords[1] = y2;
+					points->coords[2] = x2;
+					points->coords[3] = y2;
+					
+					underline = gnome_canvas_item_new (gnome_canvas_root (item->canvas),
+									   gnome_canvas_line_get_type (),
+									   "points", points,
+									   "fill_color_gdk", color,
+									   NULL);
+					gnome_canvas_points_unref (points);
+				}
+			}
+			cursor = gnome_stock_cursor_new (GNOME_STOCK_CURSOR_POINTING_HAND); 
+			gdk_window_set_cursor(window, cursor);
+			gdk_cursor_destroy(cursor);
+		}
+		break;
+	case GDK_LEAVE_NOTIFY:
+		if (url) {
+			if (underline != NULL) {
+				gtk_object_destroy (GTK_OBJECT (underline));
+				underline = NULL;
+			}
+			gdk_window_set_cursor(window, NULL);
+		}
+		break;
+	case GDK_BUTTON_PRESS:
+		if (url) {
+			if(!gnome_url_show(url)) {
+				GtkWidget *dialog;
+
+				dialog = gtk_message_dialog_new (NULL, 0,
+								 GTK_MESSAGE_ERROR,
+								 GTK_BUTTONS_OK,
+								 _("Error occured while "
+								   "trying to launch the "
+								   "URL handler.\n"
+								   "Please check the "
+								   "settings in the "
+								   "Control Center if they "
+								   "are correct."));
+
+				gtk_dialog_run (GTK_DIALOG (dialog));
+			}
+		}
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static void
+gnome_about_parse_name(gchar **name, gchar **email)
+{
+	int closed_bracket = 0;
+	int at_num = 0;
+	gchar *buffer, *name_buf = *name;
+	int buffer_len = 0;
+	gchar *email_start = 0;
+	
+	buffer = g_new(gchar, strlen(*name));
+
+	for (name_buf = strchr(*name, '<'); name_buf;
+	     name_buf = strchr(name_buf++, '<')) {
+		email_start = name_buf;
+		closed_bracket = at_num = 0;
+		name_buf++;
+		
+		for (buffer_len = 0; *name_buf; name_buf++, buffer_len++) {
+			if (*name_buf == '>') {
+				closed_bracket = 1;
+				break;
+			}
+			if (*name_buf == '<') {
+				name_buf--;
+				break;
+			}
+			if (*name_buf == '@')
+				at_num++;
+			
+			buffer[buffer_len] = *name_buf;
+		}
+	}
+	
+	buffer[buffer_len] = '\0';
+	if (closed_bracket && at_num == 1) {
+		*email = buffer;
+		*email_start = '\0';
+		return;
+	}
+
+	g_free(buffer);
+	*email = NULL;
+}
+
diff --git a/libgnomeui/gnome-about.h b/libgnomeui/gnome-about.h
new file mode 100644
index 0000000..9468fe9
--- /dev/null
+++ b/libgnomeui/gnome-about.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+/* 
+ * "About..." Widget
+ *
+ * AUTHOR:
+ * Cesar Miquel <miquel df uba ar>
+ * REWRITTEN BY:
+ * Gergõ Érdi <cactus cactus rulez org>
+ *
+ * DESCRIPTION:
+ *	A very specialized widget to display "About this program"-like
+ * boxes.
+ */
+
+#ifndef __GNOME_ABOUT_H__
+#define __GNOME_ABOUT_H__
+
+
+#include <gtk/gtkdialog.h>
+
+G_BEGIN_DECLS
+
+#define GNOME_TYPE_ABOUT            (gnome_about_get_type ())
+#define GNOME_ABOUT(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_ABOUT, GnomeAbout))
+#define GNOME_ABOUT_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_ABOUT, GnomeAboutClass))
+#define GNOME_IS_ABOUT(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_ABOUT))
+#define GNOME_IS_ABOUT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_ABOUT))
+#define GNOME_ABOUT_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_ABOUT, GnomeAboutClass))
+
+
+typedef struct _GnomeAbout        GnomeAbout;
+typedef struct _GnomeAboutPrivate GnomeAboutPrivate;
+typedef struct _GnomeAboutClass   GnomeAboutClass;
+
+struct _GnomeAbout
+{
+  GtkDialog dialog;
+
+  /*< private >*/
+  GnomeAboutPrivate *_priv;
+};
+
+struct _GnomeAboutClass
+{
+  GtkDialogClass parent_class;
+};
+
+
+GtkType    gnome_about_get_type       (void) G_GNUC_CONST;
+/* Main routine that creates the widget 
+ *
+ * USAGE:
+ *
+ *	const gchar *authors[] = {"author1", "author2", ..., NULL};
+ *        (note: not having the 'const' will cause a warning during compile.)
+ * 
+ *	GtkWidget *about = gnome_about_new ( _("GnoApp"), "1.2b",
+ *				_("Copyright FSF (C) 1998"),
+ *				authors,
+ *				"Comment line 1\nLine 2",
+ *				"/usr/local/share/pixmaps/gnoapp-logo.xpm");
+ *	gtk_widget_show (about);		
+ */
+
+GtkWidget* gnome_about_new	(const gchar	*title, /* Name of the application. */
+				 const gchar	*version, /* Version. */
+				 const gchar	*copyright, /* Copyright notice (one
+						       line.) */
+				 const gchar	**authors, /* NULL terminated list of
+						      authors. */
+				 const gchar	*comments, /* Other comments. */
+				 const gchar	*logo /* A logo pixmap file. */
+				 );
+
+GtkWidget* gnome_about_new_with_url	(const gchar *title, /* Name of the application. */
+					 const gchar *version, /* Version. */
+					 const gchar *url, /* Application URL */
+					 const gchar *copyright, /* Copyright notice (one line.) */
+					 const gchar **authors, /* NULL terminated list of authors. */
+					 const gchar **author_urls, /* NULL terminated list of author URLs */
+					 const gchar *comments, /* Other comments. */
+					 const gchar *logo /* A logo pixmap file. */
+					 );
+
+/* Only for use by bindings to languages other than C; don't use
+   in applications. */
+void
+gnome_about_construct (GnomeAbout *about,
+		       const gchar *title,
+		       const gchar *version,
+		       const gchar *url,
+		       const gchar *copyright,
+		       const gchar **authors,
+		       const gchar **author_urls,
+		       const gchar *comments,
+		       const gchar *logo);
+G_END_DECLS
+
+#endif /* __GNOME_ABOUT_H__ */
+
+
diff --git a/libgnomeui/gnome-animator.c b/libgnomeui/gnome-animator.c
new file mode 100644
index 0000000..a4486b3
--- /dev/null
+++ b/libgnomeui/gnome-animator.c
@@ -0,0 +1,1453 @@
+/* GNOME GUI Library
+ * Copyright (C) 1998, 1999 the Free Software Foundation
+ * All rights reserved
+ *
+ * Authors: Cody Russell  (bratsche dfw net)
+ *          Ettore Perazzoli (ettore comm2000 it)
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#include <config.h>
+#include <string.h>
+#include "gnome-macros.h"
+#include <gobject/gparam.h>
+#include <gtk/gtkmain.h>
+#include "gnome-animator.h"
+#include <libgnome/gnome-i18n.h>
+
+enum {
+  PROP_0,
+  PROP_LOOP_TYPE,
+  PROP_DIRECTION,
+  PROP_NUM_FRAMES,
+  PROP_CURRENT_FRAME,
+  PROP_STATUS,
+  PROP_SPEED
+};
+
+struct _GnomeAnimatorPrivate
+{
+  GdkRectangle area;
+  guint timeout_id;
+
+  GdkPixmap *offscreen_pixmap;
+  GdkPixbuf *background_pixbuf;
+
+  GnomeAnimatorFrame *first_frame;
+  GnomeAnimatorFrame *last_frame;
+  GnomeAnimatorFrame *current_frame;
+};
+
+struct _GnomeAnimatorFrame
+{
+  int frame_num;
+
+  /* The pixbuf with this frame's image data */
+  GdkPixbuf *pixbuf;
+
+  /* Offsets for overlaying onto the animation's area */
+  int x_offset;
+  int y_offset;
+
+  /* Overlay mode */
+  GdkPixbufFrameAction action;
+
+  GdkBitmap *mask;
+  guint32 interval;
+  GnomeAnimatorFrame *next;
+  GnomeAnimatorFrame *prev;
+};
+
+static void gnome_animator_class_init (GnomeAnimatorClass * class);
+static void gnome_animator_init (GnomeAnimator * animator);
+static void destroy (GtkObject * object);
+static void finalize (GObject * object);
+static void set_property (GObject * object, 
+			  guint param_id,
+			  const GValue * value,
+			  GParamSpec * pspec);
+static void get_property (GObject * object,
+			  guint param_id,
+			  GValue *value,
+			  GParamSpec * pspec);
+static void realize (GtkWidget * widget);
+static void unrealize (GtkWidget * widget);
+static void prepare_aux_pixmaps (GnomeAnimator * animator);
+static void draw_background_pixbuf (GnomeAnimator * animator);
+static void draw (GtkWidget * widget, GdkRectangle * area);
+static gint expose (GtkWidget * widget, GdkEventExpose * event);
+static void size_allocate (GtkWidget * widget, GtkAllocation * allocation);
+static void update (GnomeAnimator * animator);
+/*UNUSED
+static void state_or_style_changed (GnomeAnimator * animator);
+static void state_changed (GtkWidget * widget, GtkStateType previous_state);
+static void style_set (GtkWidget * widget, GtkStyle * previous_style);
+*/
+static GnomeAnimatorFrame *append_frame (GnomeAnimator * animator);
+static void free_frame (GnomeAnimatorFrame *frame);
+static gint timer_cb (gpointer data);
+
+GNOME_CLASS_BOILERPLATE (GnomeAnimator, gnome_animator,
+			 GtkMisc, gtk_misc)
+
+static void
+gnome_animator_init (GnomeAnimator * animator)
+{
+  GTK_WIDGET_SET_FLAGS (animator, GTK_NO_WINDOW);
+
+  animator->frame_num = 0;
+  animator->status = GNOME_ANIMATOR_STATUS_STOPPED;
+  animator->loop_type = GNOME_ANIMATOR_LOOP_RESTART;
+  animator->playback_direction = GNOME_ANIMATOR_DIRECTION_FORWARD;
+
+  animator->_priv = g_new0 (GnomeAnimatorPrivate, 1);
+}
+
+static void
+gnome_animator_class_init (GnomeAnimatorClass * class)
+{
+  GtkObjectClass *object_class;
+  GObjectClass *gobject_class;
+  GtkWidgetClass *widget_class;
+
+  object_class = (GtkObjectClass *) class;
+  gobject_class = (GObjectClass *) class;
+  widget_class = (GtkWidgetClass *) class;
+
+  g_object_class_install_property (gobject_class,
+				PROP_LOOP_TYPE,
+				g_param_spec_enum ("loop_type",
+						   _("Loop type"),
+						   _("The type of loop the GnomeAnimator uses"),
+						   GTK_TYPE_ENUM,
+						   GNOME_ANIMATOR_LOOP_NONE,
+						   (G_PARAM_READABLE |
+						    G_PARAM_WRITABLE)));
+  g_object_class_install_property (gobject_class,
+				PROP_DIRECTION,
+				g_param_spec_enum ("direction",
+						   _("Direction"),
+						   _("Animation direction"),
+						   GTK_TYPE_ENUM,
+						   GNOME_ANIMATOR_DIRECTION_FORWARD,
+						   (G_PARAM_READABLE |
+						    G_PARAM_WRITABLE)));
+  g_object_class_install_property (gobject_class,
+				PROP_NUM_FRAMES,
+				g_param_spec_uint ("num_frames",
+						   _("Number of frames"),
+						   _("Total number of frames in animation"),
+						   0,
+						   0,
+						   0,
+						   G_PARAM_READABLE));
+  g_object_class_install_property (gobject_class,
+				PROP_CURRENT_FRAME,
+				g_param_spec_uint ("current_frame",
+						   _("Current frame"),
+						   _("Current frame number"),
+						   0,
+						   0,
+						   0,
+						   G_PARAM_READABLE));
+  g_object_class_install_property (gobject_class,
+				PROP_STATUS,
+				g_param_spec_enum ("status",
+						   _("Animation status"),
+						   _("Animation status"),
+						   GTK_TYPE_ENUM,
+						   GNOME_ANIMATOR_STATUS_STOPPED,
+						   (G_PARAM_READABLE |
+						    G_PARAM_WRITABLE)));
+  g_object_class_install_property (gobject_class,
+				PROP_SPEED,
+				g_param_spec_double ("speed",
+						     _("Speed"),
+						     _("Animation speed"),
+						     0.0,
+						     1000.0,
+						     1.0,
+						     (G_PARAM_READABLE |
+						      G_PARAM_WRITABLE )));
+
+  widget_class->expose_event = expose;
+  widget_class->size_allocate = size_allocate;
+  widget_class->realize = realize;
+  widget_class->unrealize = unrealize;
+
+  object_class->destroy = destroy;
+  gobject_class->finalize = finalize;
+  gobject_class->set_property = set_property;
+  gobject_class->get_property = get_property;
+}
+
+static void
+destroy (GtkObject * object)
+{
+	GnomeAnimator *self = GNOME_ANIMATOR (object);
+	GnomeAnimatorFrame *frame;
+
+	/* remember, destroy can be run multiple times! */
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GNOME_IS_ANIMATOR (object));
+
+	if (self->_priv->offscreen_pixmap != NULL) {
+		gdk_pixmap_unref (self->_priv->offscreen_pixmap);
+		self->_priv->offscreen_pixmap = NULL;
+	}
+
+	if (self->_priv->background_pixbuf != NULL) {
+		gdk_pixbuf_unref (self->_priv->background_pixbuf);
+		self->_priv->background_pixbuf = NULL;
+	}
+
+	/* free all frames */
+	frame = self->_priv->first_frame;
+	while (frame != NULL) {
+		GnomeAnimatorFrame *next = frame->next;
+		free_frame (frame);
+		frame = next;
+	}
+	self->_priv->first_frame = NULL;
+	self->_priv->last_frame = NULL;
+	self->_priv->current_frame = NULL;
+
+	GNOME_CALL_PARENT_HANDLER (GTK_OBJECT_CLASS, destroy, (object));
+}
+
+static void
+finalize (GObject * object)
+{
+	GnomeAnimator *self;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GNOME_IS_ANIMATOR (object));
+
+	self = GNOME_ANIMATOR(object);
+
+	g_free(self->_priv);
+	self->_priv = NULL;
+
+	GNOME_CALL_PARENT_HANDLER (G_OBJECT_CLASS, finalize, (object));
+}
+
+static void
+set_property (GObject * object,
+	      guint param_id,
+	      const GValue * value,
+	      GParamSpec * pspec)
+{
+  GnomeAnimator *animator;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GNOME_IS_ANIMATOR (object));
+
+  animator = GNOME_ANIMATOR (object);
+  switch (param_id) {
+  case PROP_LOOP_TYPE:
+    gnome_animator_set_loop_type (animator, g_value_get_enum (value));
+    break;
+
+  case PROP_DIRECTION:
+    gnome_animator_set_playback_direction (animator,
+					   g_value_get_enum (value));
+    break;
+
+  case PROP_CURRENT_FRAME:
+    gnome_animator_goto_frame (animator, g_value_get_uint (value));
+    break;
+
+  case PROP_STATUS: {
+    GnomeAnimatorStatus status = g_value_get_enum (value);
+    if (status == GNOME_ANIMATOR_STATUS_RUNNING)
+      gnome_animator_start (animator);
+    else
+      gnome_animator_stop (animator);
+    
+    break;
+  }
+
+  case PROP_SPEED:
+    gnome_animator_set_playback_speed (animator, g_value_get_double (value));
+    break;
+
+  default:
+    break;
+  }
+}
+
+
+static void
+get_property (GObject * object,
+	      guint param_id,
+	      GValue * value,
+	      GParamSpec * pspec)
+{
+  GnomeAnimator *animator;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GNOME_IS_ANIMATOR (object));
+
+  animator = GNOME_ANIMATOR (object);
+
+  switch (param_id) {
+  case PROP_LOOP_TYPE:
+    g_value_set_enum (value, animator->loop_type);
+    break;
+
+  case PROP_DIRECTION:
+    g_value_set_enum (value, animator->playback_direction);
+    break;
+
+  case PROP_NUM_FRAMES:
+    g_value_set_uint (value, animator->n_frames);
+    break;
+
+  case PROP_CURRENT_FRAME:
+    g_value_set_uint (value, animator->frame_num);
+    break;
+
+  case PROP_STATUS:
+    g_value_set_enum (value, animator->status);
+    break;
+
+  case PROP_SPEED:
+    g_value_set_double (value, animator->playback_speed);
+    break;
+  }
+}
+    
+static void
+realize (GtkWidget * widget)
+{
+	GnomeAnimator *self = GNOME_ANIMATOR (widget);
+
+	GNOME_CALL_PARENT_HANDLER (GTK_WIDGET_CLASS, realize, (widget));
+
+	prepare_aux_pixmaps (self);
+	draw_background_pixbuf (self);
+}
+
+static void
+unrealize (GtkWidget * widget)
+{
+	GnomeAnimator *self = GNOME_ANIMATOR (widget);
+
+	GNOME_CALL_PARENT_HANDLER (GTK_WIDGET_CLASS, unrealize, (widget));
+
+	if (self->_priv->offscreen_pixmap != NULL) {
+		gdk_pixmap_unref (self->_priv->offscreen_pixmap);
+		self->_priv->offscreen_pixmap = NULL;
+	}
+
+	if (self->_priv->background_pixbuf != NULL) {
+		gdk_pixbuf_unref (self->_priv->background_pixbuf);
+		self->_priv->background_pixbuf = NULL;
+	}
+}
+
+static void
+size_allocate (GtkWidget * widget, GtkAllocation * allocation)
+{
+  GnomeAnimator *animator;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GNOME_IS_ANIMATOR (widget));
+  g_return_if_fail (allocation != NULL);
+
+  animator = GNOME_ANIMATOR (widget);
+
+  if (GTK_WIDGET_REALIZED (widget))
+    {
+      g_print ("size_allocate(): realized!\n");
+      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))
+    gdk_window_clear_area (widget->window,
+			   widget->allocation.x, widget->allocation.y,
+			   widget->allocation.width,
+			   widget->allocation.height);
+
+  animator->_priv->area.x = widget->allocation.x +
+    (widget->allocation.width - widget->requisition.width) / 2;
+  animator->_priv->area.y = widget->allocation.y +
+    (widget->allocation.height - widget->requisition.height) / 2;
+  animator->_priv->area.width = widget->requisition.width;
+  animator->_priv->area.height = widget->requisition.height;
+
+  prepare_aux_pixmaps (animator);
+  draw_background_pixbuf (animator);
+
+  update (animator);
+}
+
+
+/* Create the offscreen and background pixmaps if they do not exist,
+   or resize them in case the widget's size has changed.  */
+static void
+prepare_aux_pixmaps (GnomeAnimator * animator)
+{
+  GtkWidget *widget = GTK_WIDGET (animator);
+  GnomeAnimatorPrivate *_priv = animator->_priv;
+  gint old_width, old_height;
+
+  if (_priv->offscreen_pixmap != NULL)
+    gdk_window_get_size (_priv->offscreen_pixmap, &old_width, &old_height);
+  else
+    old_width = old_height = 0;
+
+  if ((widget->requisition.width != (guint16) old_width)
+      && (widget->requisition.height != (guint16) old_height))
+    {
+      GdkVisual *visual = gtk_widget_get_visual (widget);
+
+      if (_priv->offscreen_pixmap != NULL)
+	{
+	  gdk_pixmap_unref (_priv->offscreen_pixmap);
+	  _priv->offscreen_pixmap = NULL;
+	}
+
+      if (_priv->background_pixbuf != NULL)
+	{
+	  gdk_pixbuf_unref (_priv->background_pixbuf);
+	  _priv->background_pixbuf = NULL;
+	}
+
+      if (widget->requisition.width > 0 &&
+	  widget->requisition.height > 0 && GTK_WIDGET_REALIZED (widget))
+	{
+	  _priv->offscreen_pixmap = gdk_pixmap_new (widget->window,
+						    widget->requisition.
+						    width,
+						    widget->requisition.
+						    height, visual->depth);
+
+	  _priv->background_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+						     FALSE,
+						     8,
+						     widget->requisition.
+						     width,
+						     widget->requisition.
+						     height);
+	}
+    }
+}
+
+/*
+ * Clear background_pixbuf then draw the next frame into it.
+ */
+static void
+draw_background_pixbuf (GnomeAnimator * animator)
+{
+  GnomeAnimatorPrivate *_priv = animator->_priv;
+  GtkWidget *widget;
+  GdkPixmap *pixmap;
+
+  widget = GTK_WIDGET (animator);
+
+  if (_priv->background_pixbuf != NULL && widget->window != NULL)
+    {
+      GdkVisual *visual;
+      GdkColormap *colormap;
+      GtkStyle *style;
+      guint state;
+      GdkGC *gc;
+
+      style = gtk_widget_get_style (widget->parent);
+      state = GTK_WIDGET_STATE (widget->parent);
+      gc = gdk_gc_new (widget->window);
+      gdk_gc_copy (gc, style->bg_gc[state]);
+
+      if (style->bg_pixmap[state] != NULL)
+	{
+	  gdk_gc_set_tile (gc, style->bg_pixmap[state]);
+	  gdk_gc_set_fill (gc, GDK_TILED);
+	}
+      else
+	gdk_gc_set_fill (gc, GDK_SOLID);
+
+      gdk_gc_set_ts_origin (gc,
+			    -animator->_priv->area.x,
+			    -animator->_priv->area.y);
+
+      visual = gtk_widget_get_visual (widget);
+
+      pixmap = gdk_pixmap_new (widget->window,
+			       widget->requisition.width,
+			       widget->requisition.height, visual->depth);
+      colormap = gdk_rgb_get_cmap ();
+
+      gdk_draw_rectangle (pixmap,
+			  gc,
+			  TRUE,
+			  0, 0,
+			  widget->requisition.width,
+			  widget->requisition.height);
+
+      animator->_priv->background_pixbuf =
+	gdk_pixbuf_get_from_drawable (animator->_priv->background_pixbuf,
+				      pixmap,
+				      colormap,
+				      0, 0,
+				      0, 0,
+				      widget->requisition.width,
+				      widget->requisition.height);
+
+      gdk_gc_destroy (gc);
+    }
+}
+
+
+static GdkPixbuf *
+get_current_frame (GnomeAnimator *animator, int *x_offset, int *y_offset)
+{
+	GnomeAnimatorFrame *frame, *framei;
+	GdkPixbuf *pixbuf;
+	guchar *pixels;
+	int rowstride;
+
+	*x_offset = 0;
+	*y_offset = 0;
+
+	if (animator->_priv->current_frame == NULL)
+		return NULL;
+
+	frame = animator->_priv->current_frame;
+	if(frame->prev == NULL ||
+	   frame->prev->action == GDK_PIXBUF_FRAME_DISPOSE) {
+		*x_offset = frame->x_offset;
+		*y_offset = frame->y_offset;
+
+		return gdk_pixbuf_ref (frame->pixbuf);
+	}
+
+	/* This not incredibly efficent and is done for each frame,
+	 * sometime in the future someone should make this efficent
+	 * I guess but I doubt it will ever be a problem */
+
+	pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8,
+				 animator->_priv->area.width,
+				 animator->_priv->area.height);
+
+	pixels = gdk_pixbuf_get_pixels (pixbuf);
+	rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+
+	memset(pixels, 0, rowstride * animator->_priv->area.height);
+
+	framei = frame->prev;
+	while (framei->prev != NULL) {
+		if (framei->action == GDK_PIXBUF_FRAME_DISPOSE)
+			break;
+		framei = frame->prev;
+	}
+
+	while (frame != framei) {
+		if (framei->action != GDK_PIXBUF_FRAME_REVERT)
+			gdk_pixbuf_composite(framei->pixbuf,
+					     pixbuf,
+					     framei->x_offset,
+					     framei->y_offset,
+					     gdk_pixbuf_get_width(framei->pixbuf),
+					     gdk_pixbuf_get_height(framei->pixbuf),
+					     0, 0, 1, 1,
+					     GDK_INTERP_NEAREST,
+					     255);
+
+		framei = framei->next;
+	}
+
+	gdk_pixbuf_composite(frame->pixbuf,
+			     pixbuf,
+			     frame->x_offset,
+			     frame->y_offset,
+			     gdk_pixbuf_get_width(frame->pixbuf),
+			     gdk_pixbuf_get_height(frame->pixbuf),
+			     0, 0, 1, 1,
+			     GDK_INTERP_NEAREST,
+			     255);
+
+	return pixbuf;
+}
+
+/*
+ * Call draw_background_pixbuf(), then draw background_pixbuf onto
+ * the window.
+ */
+static void
+paint (GnomeAnimator * animator, GdkRectangle * area)
+{
+  GnomeAnimatorPrivate *_priv;
+  GdkPixbuf *draw_source;
+  GtkMisc *misc;
+  GtkWidget *widget;
+  gint top_clip, bottom_clip, left_clip, right_clip;
+  gint width, height;
+  gint x_off, y_off;
+
+  g_return_if_fail (GTK_WIDGET_DRAWABLE (animator));
+
+  widget = GTK_WIDGET (animator);
+  misc = GTK_MISC (animator);
+  _priv = animator->_priv;
+
+  draw_source = get_current_frame (animator, &x_off, &y_off);
+
+  if (draw_source == NULL) {
+	  gdk_draw_rectangle (widget->window,
+			      widget->style->black_gc,
+			      TRUE,
+			      0, 0,
+			      widget->allocation.width,
+			      widget->allocation.height);
+	  return;
+  }
+
+  width = gdk_pixbuf_get_width (draw_source);
+  height = gdk_pixbuf_get_height (draw_source);
+
+  left_clip = (x_off < area->x) ? area->x - x_off : 0;
+  top_clip = (y_off < area->y) ? area->y - y_off : 0;
+  if (x_off + width > area->x + area->width)
+    right_clip = x_off + width - (area->x + area->width);
+  else
+    right_clip = 0;
+  if (y_off + height > area->y + area->height)
+    bottom_clip = y_off + height - (area->y + area->height);
+  else
+    bottom_clip = 0;
+  if (right_clip + left_clip >= width || top_clip + bottom_clip >= height)
+    return;
+
+  if (animator->n_frames > 0 && _priv->offscreen_pixmap != NULL)
+    {
+      GnomeAnimatorFrame *frame;
+
+      /*FIXME: deal with mask for other then _DISPOSE modes */
+      frame = _priv->current_frame;
+
+      /* Update the window using double buffering to make the
+         animation as smooth as possible.  */
+
+      /* Copy the background into the offscreen pixmap.  */
+      gdk_pixbuf_render_to_drawable (_priv->background_pixbuf,
+				     _priv->offscreen_pixmap,
+				     widget->style->black_gc,
+				     area->x - _priv->area.x,
+				     area->y - _priv->area.y,
+				     area->x - _priv->area.x,
+				     area->y - _priv->area.y,
+				     area->width,
+				     area->height,
+				     GDK_RGB_DITHER_NORMAL, area->x, area->y);
+
+      /* Draw the (shaped) frame into the offscreen pixmap.  */
+      if (animator->mode == GNOME_ANIMATOR_SIMPLE ||
+	  !gdk_pixbuf_get_has_alpha (draw_source))
+	{
+	  if (frame->mask)
+	    {
+	      gdk_gc_set_clip_mask (widget->style->black_gc, frame->mask);
+	      gdk_gc_set_clip_origin (widget->style->black_gc, x_off,	/* frame->x_offset */
+				      y_off);	/* frame->y_offset */
+	    }
+
+	  gdk_pixbuf_render_to_drawable (draw_source,
+					 _priv->offscreen_pixmap,
+					 widget->style->black_gc,
+					 left_clip, top_clip,
+					 x_off + left_clip, y_off + top_clip,
+					 width - left_clip - right_clip,
+					 height - top_clip - bottom_clip,
+					 GDK_RGB_DITHER_NORMAL, 0, 0);
+	  if (frame->mask)
+	    {
+	      gdk_gc_set_clip_mask (widget->style->black_gc, NULL);
+	      gdk_gc_set_clip_origin (widget->style->black_gc, 0, 0);
+	    }
+
+	  /* Copy the offscreen pixmap into the window.  */
+	  gdk_draw_pixmap (widget->window,
+			   widget->style->black_gc,
+			   _priv->offscreen_pixmap,
+			   area->x - _priv->area.x,
+			   area->y - _priv->area.y, area->x, area->y,
+			   area->width, area->height);
+	}
+      else if (animator->mode == GNOME_ANIMATOR_COLOR)
+	{
+	  GdkPixbuf *dest_source;
+	  gint i, j, rowstride, dest_rowstride;
+	  gint r, g, b;
+	  gchar *dest_pixels, *c, *a, *original_pixels;
+
+	  dest_source = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+					FALSE,
+					gdk_pixbuf_get_bits_per_sample
+					(draw_source),
+					width - left_clip - right_clip,
+					height - top_clip - bottom_clip);
+	  gdk_gc_set_clip_mask (widget->style->black_gc, frame->mask);
+	  gdk_gc_set_clip_origin (widget->style->black_gc, x_off, y_off);
+
+	  r = widget->style->bg[GTK_WIDGET_STATE (widget)].red >> 8;
+	  g = widget->style->bg[GTK_WIDGET_STATE (widget)].green >> 8;
+	  b = widget->style->bg[GTK_WIDGET_STATE (widget)].blue >> 8;
+	  dest_rowstride = gdk_pixbuf_get_rowstride (dest_source);
+	  dest_pixels = gdk_pixbuf_get_pixels (dest_source);
+	  rowstride = gdk_pixbuf_get_rowstride (draw_source);
+	  original_pixels = gdk_pixbuf_get_pixels (draw_source);
+	  for (i = 0; i < height; i++)
+	    {
+	      for (j = 0; j < width; j++)
+		{
+		  c =
+		    original_pixels + (i + top_clip) * rowstride + (j +
+								    left_clip)
+		    * 4;
+		  a = c + 3;
+		  *(dest_pixels + i * dest_rowstride + j * 3) =
+		    r + (((*c - r) * (*a) + 0x80) >> 8);
+		  c++;
+		  *(dest_pixels + i * dest_rowstride + j * 3 + 1) =
+		    g + (((*c - g) * (*a) + 0x80) >> 8);
+		  c++;
+		  *(dest_pixels + i * dest_rowstride + j * 3 + 2) =
+		    b + (((*c - b) * (*a) + 0x80) >> 8);
+		}
+	    }
+
+	  gdk_pixbuf_render_to_drawable (dest_source,
+					 _priv->offscreen_pixmap,
+					 widget->style->black_gc,
+					 0, 0,
+					 x_off + left_clip, y_off + top_clip,
+					 width, height,
+					 GDK_RGB_DITHER_NORMAL, 0, 0);
+	  gdk_gc_set_clip_mask (widget->style->black_gc, NULL);
+	  gdk_gc_set_clip_origin (widget->style->black_gc, 0, 0);
+
+	  gdk_pixbuf_unref (dest_source);
+
+	  gdk_draw_pixmap (widget->window,
+			   widget->style->black_gc,
+			   _priv->offscreen_pixmap,
+			   area->x - _priv->area.x,
+			   area->y - _priv->area.y, area->x, area->y,
+			   area->width, area->height);
+	}
+    }
+  else
+    gdk_window_clear_area (widget->window,
+			   area->x, area->y, area->width, area->height);
+
+  gdk_pixbuf_unref (draw_source);
+}
+
+static gint
+expose (GtkWidget * widget, GdkEventExpose * event)
+{
+  GnomeAnimator *animator;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GNOME_IS_ANIMATOR (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  animator = GNOME_ANIMATOR (widget);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    draw (GTK_WIDGET (animator), &event->area);
+
+  return FALSE;
+}
+
+static void
+draw (GtkWidget * widget, GdkRectangle * area)
+{
+  GnomeAnimator *animator;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GNOME_IS_ANIMATOR (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_REALIZED (widget))
+    {
+      GdkRectangle p_area;
+
+      animator = GNOME_ANIMATOR (widget);
+
+      if (gdk_rectangle_intersect (area, &animator->_priv->area, &p_area))
+	paint (animator, &p_area);
+
+      gdk_flush ();
+    }
+}
+
+static void
+update (GnomeAnimator * animator)
+{
+  GtkWidget *widget = GTK_WIDGET (animator);
+
+  if (GTK_WIDGET_REALIZED (widget))
+    {
+      if (animator->n_frames > 0)
+	gtk_widget_queue_draw (widget);
+      else
+	gdk_window_clear_area (widget->window,
+			       widget->allocation.x,
+			       widget->allocation.y,
+			       widget->allocation.width,
+			       widget->allocation.height);
+    }
+}
+
+/* UNUSED
+static void
+state_or_style_changed (GnomeAnimator * animator)
+{
+  prepare_aux_pixmaps (animator);
+  draw_background_pixbuf (animator);
+}
+
+static void
+state_changed (GtkWidget * widget, GtkStateType previous_state)
+{
+  g_assert (GNOME_IS_ANIMATOR (widget));
+  state_or_style_changed (GNOME_ANIMATOR (widget));
+}
+
+static void
+style_set (GtkWidget * widget, GtkStyle * previous_style)
+{
+  g_assert (GNOME_IS_ANIMATOR (widget));
+  state_or_style_changed (GNOME_ANIMATOR (widget));
+}
+*/
+
+static void
+free_frame (GnomeAnimatorFrame *frame)
+{
+	if (frame->pixbuf != NULL)
+		gdk_pixbuf_unref (frame->pixbuf);
+	frame->pixbuf = NULL;
+	g_free(frame);
+}
+
+static GnomeAnimatorFrame *
+append_frame (GnomeAnimator * animator)
+{
+  GnomeAnimatorPrivate *_priv = animator->_priv;
+  GnomeAnimatorFrame *new_frame;
+
+  new_frame = g_new0 (GnomeAnimatorFrame, 1);
+
+  if (animator->high_range == animator->n_frames)
+    animator->high_range++;
+
+  if (_priv->first_frame == NULL)
+    {
+      _priv->first_frame =
+	      _priv->last_frame =
+	      _priv->current_frame =
+	      new_frame;
+      new_frame->prev = NULL;
+    }
+  else
+    {
+      _priv->last_frame->next = new_frame;
+      new_frame->prev = _priv->last_frame;
+      _priv->last_frame = new_frame;
+    }
+
+  new_frame->frame_num = animator->n_frames;
+  new_frame->next = 0;
+  animator->n_frames++;
+
+  return new_frame;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static gint
+timer_cb (gpointer data)
+{
+  GnomeAnimator *animator;
+
+  GDK_THREADS_ENTER ();
+
+  animator = GNOME_ANIMATOR (data);
+  if (animator->status != GNOME_ANIMATOR_STATUS_STOPPED)
+    gnome_animator_advance (animator, 1);
+
+  GDK_THREADS_LEAVE ();
+
+  return FALSE;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* Public interface.  */
+
+/*
+ * FIXME:  I think we should get rid of this function and set
+ *         the size with gtk_widget_set_usize().
+ */
+GtkWidget *
+gnome_animator_new_with_size (guint width, guint height)
+{
+  GnomeAnimator *animator;
+  GtkWidget *widget;
+
+  animator = gtk_type_new (gnome_animator_get_type ());
+  widget = GTK_WIDGET (animator);
+
+  widget->requisition.width = width;
+  widget->requisition.height = height;
+
+  if (GTK_WIDGET_VISIBLE (widget))
+    gtk_widget_queue_resize (widget);
+
+  return widget;
+}
+
+/**
+ * gnome_animator_set_loop_type
+ * @animator: Animator widget to be updated
+ * @loop_type: Type of animation loop desired
+ *
+ * Description: Sets desired animation loop type.  Available loop
+ * types are %GNOME_ANIMATOR_LOOP_NONE (play animation once only),
+ * %GNOME_ANIMATOR_LOOP_RESTART (play animation over and over again),
+ * and %GNOME_ANIMATOR_LOOP_PING_PONG (play animation over and over
+ * again, reversing the playing direction every time.)
+ **/
+
+void
+gnome_animator_set_loop_type (GnomeAnimator * animator,
+			      GnomeAnimatorLoopType loop_type)
+{
+  g_return_if_fail (animator != NULL);
+  g_return_if_fail (GNOME_IS_ANIMATOR (animator));
+
+  animator->loop_type = loop_type;
+}
+
+/**
+ * gnome_animator_get_loop_type
+ * @animator: Animator widget to be queried
+ *
+ * Description: Obtains current animator loop type.  Available loop
+ * types are %GNOME_ANIMATOR_LOOP_NONE (play animation once only),
+ * %GNOME_ANIMATOR_LOOP_RESTART (play animation over and over again),
+ * and %GNOME_ANIMATOR_LOOP_PING_PONG (play animation over and over
+ * again, reversing the playing direction every time.)
+ *
+ * Returns: Loop type.
+ **/
+
+GnomeAnimatorLoopType gnome_animator_get_loop_type (GnomeAnimator * animator)
+{
+  g_print ("gnome_animator_get_loop_type()\n");
+
+  g_return_val_if_fail (animator != NULL, GNOME_ANIMATOR_LOOP_NONE);
+
+  return animator->loop_type;
+}
+
+/**
+ * gnome_animator_set_playback_direction
+ * @animator: Animator widget to be updated
+ * @playback_direction: Direction animation should be played.
+ *
+ * Description: Sets direction (forwards or backwards) to play the
+ * animation.  If @playback_direction is a positive number, the
+ * animation is played from the first to the last frame.  If
+ * @playback_direction is negative, the animation is played from the
+ * last to the first frame.
+ **/
+
+void
+gnome_animator_set_playback_direction (GnomeAnimator * animator,
+				       GnomeAnimatorDirection direction)
+{
+  g_return_if_fail (animator != NULL);
+
+  animator->playback_direction = direction;
+}
+
+/*
+ * gnome_animator_get_playback_direction
+ * @animator: Animator widget to be updated
+ *
+ * Description: Returns the current playing direction (forwards or
+ * backwards) for the animation.  If the returned value is a positive
+ * number, the animation is played from the first to the last frame.
+ * If it is negative, the animation is played from the last to the
+ * first frame.
+ *
+ * Returns: Positive or negative number indicating direction.
+ */
+
+GnomeAnimatorDirection
+gnome_animator_get_playback_direction (GnomeAnimator * animator)
+{
+  g_return_val_if_fail (animator != NULL, 0);
+
+  return animator->playback_direction;
+}
+
+/*
+ * Begin pixbuf loading code.
+ */
+
+gboolean
+gnome_animator_append_frame_from_pixbuf_at_size (GnomeAnimator * animator,
+						 GdkPixbuf * pixbuf,
+						 gint x_offset,
+						 gint y_offset,
+						 guint32 interval,
+						 guint width, guint height)
+{
+  GnomeAnimatorFrame *new_frame;
+
+  g_return_val_if_fail (animator != NULL, FALSE);
+  g_return_val_if_fail (pixbuf != NULL, FALSE);
+
+  if (width == 0)
+    width = gdk_pixbuf_get_width (pixbuf);
+  if (height == 0)
+    height = gdk_pixbuf_get_height (pixbuf);
+
+  new_frame = append_frame (animator);
+
+  new_frame->pixbuf = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (pixbuf),
+				      TRUE,
+				      gdk_pixbuf_get_bits_per_sample
+				      (pixbuf), width, height);
+  gdk_pixbuf_copy_area (pixbuf, x_offset, y_offset, width, height,
+			new_frame->pixbuf, 0, 0);
+  new_frame->x_offset = x_offset;
+  new_frame->y_offset = y_offset;
+  new_frame->interval = interval;
+  new_frame->action = GDK_PIXBUF_FRAME_DISPOSE;
+  animator->n_frames++;
+
+  return TRUE;
+}
+
+gboolean
+gnome_animator_append_frames_from_pixbuf_at_size (GnomeAnimator * animator,
+						  GdkPixbuf * pixbuf,
+						  gint x_offset,
+						  gint y_offset,
+						  guint32 interval,
+						  gint x_unit,
+						  guint width, guint height)
+{
+  guint num_frames, i, offs;
+
+  if (width == 0)
+    width = x_unit;
+  if (height == 0)
+    height = gdk_pixbuf_get_height (pixbuf);
+
+  num_frames = gdk_pixbuf_get_width (pixbuf) / x_unit;
+
+  for (i = offs = 0; i < num_frames; i++, offs += width)
+    {
+      GnomeAnimatorFrame *frame;
+
+      frame = append_frame (animator);
+      frame->pixbuf = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (pixbuf),
+				      TRUE,
+				      gdk_pixbuf_get_bits_per_sample
+				      (pixbuf), width, height);
+      gdk_pixbuf_copy_area (pixbuf, offs, y_offset, width, height,
+			    frame->pixbuf, 0, 0);
+      frame->x_offset = x_offset;
+      frame->y_offset = y_offset;
+      frame->interval = interval;
+      frame->action = GDK_PIXBUF_FRAME_DISPOSE;
+    }
+
+  return TRUE;
+}
+
+gboolean
+gnome_animator_append_frames_from_pixbuf (GnomeAnimator * animator,
+					  GdkPixbuf * pixbuf,
+					  gint x_offset,
+					  gint y_offset,
+					  guint32 interval, gint x_unit)
+{
+  return gnome_animator_append_frames_from_pixbuf_at_size (animator,
+							   pixbuf,
+							   x_offset,
+							   y_offset,
+							   interval,
+							   x_unit, 0, 0);
+}
+
+gboolean
+gnome_animator_append_frames_from_pixbuf_animation (GnomeAnimator * animator,
+						    GdkPixbufAnimation * pixbuf)
+{
+  GList *li;
+
+  g_return_val_if_fail (animator != NULL, FALSE);
+  g_return_val_if_fail (pixbuf != NULL, FALSE);
+
+  for(li = gdk_pixbuf_animation_get_frames(pixbuf); li != NULL; li = li->next)
+    {
+      GnomeAnimatorFrame *frame;
+      GdkPixbufFrame *pixbuf_frame = li->data;
+
+      frame = append_frame (animator);
+      frame->pixbuf = gdk_pixbuf_frame_get_pixbuf(pixbuf_frame);
+      gdk_pixbuf_ref (frame->pixbuf);
+      frame->x_offset = gdk_pixbuf_frame_get_x_offset(pixbuf_frame);
+      frame->y_offset = gdk_pixbuf_frame_get_y_offset(pixbuf_frame);
+      frame->interval = gdk_pixbuf_frame_get_delay_time(pixbuf_frame);
+      frame->action = gdk_pixbuf_frame_get_action(pixbuf_frame);
+    }
+
+  return TRUE;
+}
+
+/**
+ * gnome_animator_start
+ * @animator: Animator widget to be started
+ *
+ * Description:  Initiate display of animated frames.
+ **/
+
+void
+gnome_animator_start (GnomeAnimator * animator)
+{
+  g_return_if_fail (animator != NULL);
+
+  if (animator->n_frames > 0)
+    {
+      animator->status = GNOME_ANIMATOR_STATUS_RUNNING;
+
+      /* This forces the animator to start playback.  */
+      gnome_animator_advance (animator, 0);
+    }
+}
+
+/**
+ * gnome_animator_stop
+ * @animator: Animator widget to be stopped
+ *
+ * Description:  Halts display of animated frames.  The current frame
+ * in the animation will remain in the animator widget.
+ **/
+
+void
+gnome_animator_stop (GnomeAnimator * animator)
+{
+  g_return_if_fail (animator != NULL);
+
+  if (animator->status == GNOME_ANIMATOR_STATUS_RUNNING)
+    gtk_timeout_remove (animator->_priv->timeout_id);
+  animator->status = GNOME_ANIMATOR_STATUS_STOPPED;
+}
+
+/**
+ * gnome_animator_advance
+ * @animator: Animator widget to be updated
+ * @num: Number of frames to advance by
+ *
+ * Description: Advance the animator @num frames.  If @num is
+ * positive, use the specified @playback_direction; if it is negative,
+ * go in the opposite direction.  After the call, the animator is in
+ * the same state it would be if it had actually executed the specified
+ * number of iterations. 
+ *
+ * Returns:  %TRUE if the animator is now stopped.
+ **/
+
+gboolean
+gnome_animator_advance (GnomeAnimator * animator, gint num)
+{
+  gboolean stop;
+  guint new_frame;
+
+  g_return_val_if_fail (animator != NULL, FALSE);
+
+  if (num == 0)
+    {
+      stop = (animator->status == GNOME_ANIMATOR_STATUS_STOPPED);
+      new_frame = animator->frame_num;
+    }
+  else
+    {
+      if (animator->playback_direction == GNOME_ANIMATOR_DIRECTION_BACKWARD)
+	num = -num;
+
+      if ((num < 0 && animator->frame_num >= (guint) - num) ||
+	  (num > 0 && (guint) num < animator->n_frames - animator->frame_num))
+	{
+	  new_frame = animator->frame_num + num;
+	  stop = FALSE;
+	}
+      else
+	{
+	  /* We are overflowing the frame list: handle the various loop
+	     types.  */
+	  switch (animator->loop_type)
+	    {
+	    case GNOME_ANIMATOR_LOOP_NONE:
+	      if (num < 0)
+		new_frame = 0;
+	      else
+		new_frame = animator->n_frames - 1;
+	      if (
+		  (num < 0
+		   && animator->playback_direction ==
+		   GNOME_ANIMATOR_DIRECTION_FORWARD) || (num > 0
+							 && animator->
+							 playback_direction ==
+							 GNOME_ANIMATOR_DIRECTION_BACKWARD))
+		stop = FALSE;
+	      else
+		stop = TRUE;
+	      break;
+
+	    case GNOME_ANIMATOR_LOOP_RESTART:
+	      if (num > 0)
+		new_frame = ((num - (animator->n_frames -
+				     animator->frame_num)) %
+			     animator->n_frames);
+	      else
+		new_frame =
+		  (animator->n_frames - 1 -
+		   ((-num - (animator->frame_num + 1)) % animator->n_frames));
+	      stop = FALSE;
+	      break;
+
+	    case GNOME_ANIMATOR_LOOP_PING_PONG:
+	      {
+		guint num1;
+		gboolean back;
+
+		if (num > animator->n_frames)
+		  num1 = num - (animator->n_frames - 1 - animator->frame_num);
+		else
+		  num1 = -num - animator->frame_num;
+
+		back = (((num1 / (animator->n_frames - 1)) % 2) == 0);
+		if (num < 0)
+		  back = !back;
+
+		if (back)
+		  {
+		    new_frame = (animator->n_frames - 1 -
+				 (num1 % (animator->n_frames - 1)));
+		    animator->playback_direction =
+		      GNOME_ANIMATOR_DIRECTION_BACKWARD;
+		  }
+		else
+		  {
+		    new_frame = num1 % (animator->n_frames - 1);
+		    animator->playback_direction =
+		      GNOME_ANIMATOR_DIRECTION_FORWARD;
+		  }
+	      }
+
+	      stop = FALSE;
+	      break;
+
+	    default:
+	      g_warning ("Unknown GnomeAnimatorLoopType %d",
+			 animator->loop_type);
+	      stop = TRUE;
+	      new_frame = animator->frame_num;
+	      break;
+	    }
+	}
+    }
+
+  if (stop)
+    gnome_animator_stop (animator);
+
+  gnome_animator_goto_frame (animator, new_frame);
+
+  return stop;
+}
+
+/**
+ * gnome_animator_goto_frame
+ * @animator: Animator widget to be updated
+ * @frame_number: Frame number to be made current
+ *
+ * Description: Jump to the specified @frame_number and display it.
+ **/
+
+void
+gnome_animator_goto_frame (GnomeAnimator * animator, guint frame_number)
+{
+  GnomeAnimatorPrivate *_priv;
+  GnomeAnimatorFrame *frame;
+  gint dist1;
+  guint dist2;
+  guint i;
+
+  g_return_if_fail (animator != NULL);
+  g_return_if_fail (frame_number < animator->n_frames);
+
+  _priv = animator->_priv;
+
+  /* Try to be smart and minimize the number of steps spent walking on
+     the linked list.  */
+
+  dist1 = frame_number - animator->frame_num;
+  dist2 = animator->n_frames - 1 - frame_number;
+
+  if (frame_number < (guint) ABS (dist1) && frame_number < dist2)
+    {
+      frame = _priv->first_frame;
+      for (i = 0; i < frame_number; i++)
+	frame = frame->next;
+    }
+  else if (dist2 < (guint) ABS (dist1))
+    {
+      frame = _priv->last_frame;
+      for (i = 0; i < dist2; i++)
+	frame = frame->prev;
+    }
+  else
+    {
+      frame = _priv->current_frame;
+      if (dist1 > 0)
+	for (i = 0; i < (guint) dist1; i++)
+	  frame = frame->next;
+      else
+	for (i = 0; i < (guint) - dist1; i++)
+	  frame = frame->prev;
+    }
+
+  animator->frame_num = frame_number;
+  _priv->current_frame = frame;
+
+  update (animator);
+
+  if (animator->status == GNOME_ANIMATOR_STATUS_RUNNING)
+    {
+      guint32 interval;
+
+      if (_priv->timeout_id != 0)
+	gtk_timeout_remove (_priv->timeout_id);
+
+      interval = (guint32) ((double) frame->interval /
+			    animator->playback_speed + 0.5);
+
+      _priv->timeout_id = gtk_timeout_add (interval,
+					   timer_cb, (gpointer) animator);
+    }
+}
+
+/**
+ * gnome_animator_get_current_frame_number
+ * @animator: Animator widget to be queried
+ *
+ * Description:  Obtains current frame number from animator widget.
+ *
+ * Returns: Current frame number.
+ **/
+
+guint
+gnome_animator_get_current_frame_number (GnomeAnimator * animator)
+{
+  g_return_val_if_fail (animator != NULL, 0);
+
+  return animator->frame_num;
+}
+
+/**
+ * gnome_animator_get_status
+ * @animator: Animator widget to be queried
+ *
+ * Description:  Obtains current status from animator widget.  Possible
+ * return values include %GNOME_ANIMATOR_STATUS_STOPPED and
+ * %GNOME_ANIMATOR_STATUS_RUNNING.
+ *
+ * Returns: Status constant.
+ **/
+
+GnomeAnimatorStatus
+gnome_animator_get_status (GnomeAnimator * animator)
+{
+  g_return_val_if_fail (animator != NULL, GNOME_ANIMATOR_STATUS_STOPPED);
+
+  return animator->status;
+}
+
+/**
+ * gnome_animator_set_playback_speed
+ * @animator: Animator widget to be updated
+ * @speed: Rate multiplier for playback speed
+ *
+ * Description: Sets the playback speed.  The delay between every
+ * frame is divided by this value before being used.  As a
+ * consequence, higher values give higher playback speeds.
+ **/
+
+void
+gnome_animator_set_playback_speed (GnomeAnimator * animator, double speed)
+{
+  g_return_if_fail (animator != NULL);
+  g_return_if_fail (speed > 0.0);
+
+  animator->playback_speed = speed;
+}
+
+/**
+ * gnome_animator_get_playback_speed
+ * @animator: Animator widget to be queried
+ *
+ * Description: Returns the current playback speed.
+ *
+ * Returns: &double indicating the playback speed.
+ **/
+
+gdouble
+gnome_animator_get_playback_speed (GnomeAnimator * animator)
+{
+  g_return_val_if_fail (animator != NULL, -1.0);
+
+  return animator->playback_speed;
+}
+
+void
+gnome_animator_set_range (GnomeAnimator * animator, guint low, guint high)
+{
+  g_return_if_fail (animator != NULL);
+  g_return_if_fail (high < animator->n_frames);
+  g_return_if_fail (low < high);
+
+  animator->low_range = low;
+  animator->high_range = high;
+}
diff --git a/libgnomeui/gnome-animator.h b/libgnomeui/gnome-animator.h
new file mode 100644
index 0000000..ead9763
--- /dev/null
+++ b/libgnomeui/gnome-animator.h
@@ -0,0 +1,202 @@
+/* GNOME GUI Library
+ * Copyright (C) 1998, 1999 the Free Software Foundation
+ * All rights reserved
+ *
+ * Authors: Cody Russell  (bratsche dfw net)
+ *          Ettore Perazzoli (ettore comm2000 it)
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#ifndef _GNOME_ANIMATOR_H
+#define _GNOME_ANIMATOR_H
+
+#include <gdk/gdk.h>
+#include <gtk/gtkwidget.h>
+
+#include "gnome-pixmap.h"
+
+G_BEGIN_DECLS
+
+#define GNOME_TYPE_ANIMATOR            (gnome_animator_get_type())
+#define GNOME_ANIMATOR(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_ANIMATOR, GnomeAnimator))
+#define GNOME_ANIMATOR_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_ANIMATOR, GnomeAnimatorClass))
+#define GNOME_IS_ANIMATOR(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_ANIMATOR))
+#define GNOME_IS_ANIMATOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_ANIMATOR))
+#define GNOME_ANIMATOR_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_ANIMATOR, GnomeAnimatorClass))
+
+/* Current animator status.  */
+typedef enum
+{
+  GNOME_ANIMATOR_STATUS_STOPPED,
+  GNOME_ANIMATOR_STATUS_RUNNING
+} GnomeAnimatorStatus;
+
+typedef enum
+{
+  GNOME_ANIMATOR_SIMPLE,
+  GNOME_ANIMATOR_COLOR
+} GnomeAnimatorDrawMode;
+
+typedef enum
+{
+  GNOME_ANIMATOR_DIRECTION_FORWARD,
+  GNOME_ANIMATOR_DIRECTION_BACKWARD
+} GnomeAnimatorDirection;
+
+/* Looping type. The behavior depends upon the playback direction.
+ *    NONE:      Do not loop the animation. Stop once it has completed one
+ *               cycle.
+ *    RESTART:   Once the cycle has completed, restart it.
+ *    PING_PONG: After the cycle has completed, reverse the direction
+ *               of playback.
+ */
+typedef enum
+{
+  GNOME_ANIMATOR_LOOP_NONE,
+  GNOME_ANIMATOR_LOOP_RESTART,
+  GNOME_ANIMATOR_LOOP_PING_PONG
+} GnomeAnimatorLoopType;
+
+typedef struct _GnomeAnimator GnomeAnimator;
+typedef struct _GnomeAnimatorClass GnomeAnimatorClass;
+
+/* Private stuff.  */
+typedef struct _GnomeAnimatorFrame GnomeAnimatorFrame;
+typedef struct _GnomeAnimatorPrivate GnomeAnimatorPrivate;
+
+struct _GnomeAnimator
+{
+  GtkMisc misc;
+
+  guint frame_num;
+  guint n_frames;
+  guint low_range;
+  guint high_range;
+  GnomeAnimatorStatus status;
+  GnomeAnimatorLoopType loop_type;
+  GnomeAnimatorDirection playback_direction;
+  gdouble playback_speed;
+  GnomeAnimatorDrawMode mode;
+
+  /*< private >*/
+  GnomeAnimatorPrivate *_priv;
+};
+
+struct _GnomeAnimatorClass
+{
+  GtkMiscClass parent_class;
+};
+
+GtkType gnome_animator_get_type (void) G_GNUC_CONST;
+GtkWidget *gnome_animator_new_with_size (guint width, guint height);
+
+void gnome_animator_set_loop_type (GnomeAnimator * animator,
+				   GnomeAnimatorLoopType loop_type);
+GnomeAnimatorLoopType gnome_animator_get_loop_type (GnomeAnimator * animator);
+void gnome_animator_set_playback_direction (GnomeAnimator * animator,
+					    GnomeAnimatorDirection direction);
+GnomeAnimatorDirection gnome_animator_get_playback_direction (GnomeAnimator *
+							      animator);
+
+/* Append a frame from `pixbuf', rendering it at the specified size.  */
+gboolean gnome_animator_append_frame_from_pixbuf_at_size (GnomeAnimator *
+							  animator,
+							  GdkPixbuf * pixbuf,
+							  gint x_offset,
+							  gint y_offset,
+							  guint32 interval,
+							  guint width,
+							  guint height);
+
+/* Append a frame from `pixbuf', rendering it at its natural size.  */
+gboolean gnome_animator_append_frame_from_pixbuf (GnomeAnimator * animator,
+						  GdkPixbuf * pixbuf,
+						  gint x_offset,
+						  gint y_offset,
+						  guint32 interval);
+
+/* Crop `pixbuf' into frames `x_unit' pixels wide, and append them as
+ * frames to the animator with the specified `interval' and offsets.
+ * Each frame is rendered at the specified size. If `pixbuf' is an
+ * animated pixbuf, `x_unit' and `interval' will be ignored and the
+ * frames will be appended as they are stored in the pixbuf.
+ */
+gboolean gnome_animator_append_frames_from_pixbuf_at_size (GnomeAnimator *
+							   animator,
+							   GdkPixbuf * pixbuf,
+							   gint x_offset,
+							   gint y_offset,
+							   guint32 interval,
+							   gint x_unit,
+							   guint width,
+							   guint height);
+
+/* Crop `pixbuf' into frames `x_unit' pixels wide, and append them as
+ * frames to the animator with the specified `interval' and offsets.
+ * Each frame is rendered at its natural size. If `pixbuf' is an animated
+ * pixbuf, `x_unit' and `interval' will be ignored and the frames will be
+ * appended as they are stored in the pixbuf.
+ */
+gboolean gnome_animator_append_frames_from_pixbuf (GnomeAnimator * animator,
+						   GdkPixbuf * pixbuf,
+						   gint x_offset,
+						   gint y_offset,
+						   guint32 interval,
+						   gint x_unit);
+
+/* Append frames from a GdkPixbufAnimation */
+gboolean
+gnome_animator_append_frames_from_pixbuf_animation (GnomeAnimator * animator,
+						    GdkPixbufAnimation * pixbuf);
+
+/* Start and stop playback in the GTK loop. */
+void gnome_animator_start (GnomeAnimator * animator);
+void gnome_animator_stop (GnomeAnimator * animator);
+
+/* Advance the animation by `num' frames.  A positive value uses the
+   specified playback direction; a negative one goes in the opposite
+   direction.  If the loop type is `GNOME_ANIMATOR_LOOP_NONE' and the
+   value causes the frame counter to overflow, `FALSE' is returned and
+   the animator is stopped; otherwise, `TRUE' is returned.  */
+gboolean gnome_animator_advance (GnomeAnimator * animator, gint num);
+
+/* Set the number of current frame.  The result is immediately
+   visible.  */
+void gnome_animator_goto_frame (GnomeAnimator * animator, guint frame_number);
+
+/* Get the total number of frames. */
+guint gnome_animator_get_total_frames (GnomeAnimator * animator);
+
+/* Get the number of current frame.  */
+guint gnome_animator_get_current_frame_number (GnomeAnimator * animator);
+
+/* Get the animator status.  */
+GnomeAnimatorStatus gnome_animator_get_status (GnomeAnimator * animator);
+
+/* Set/get speed factor (the higher, the faster: the `interval' value
+   is divided by this factor before being used).  Default is 1.0.  */
+void gnome_animator_set_playback_speed (GnomeAnimator * animator,
+					gdouble speed);
+gdouble gnome_animator_get_playback_speed (GnomeAnimator * animator);
+void gnome_animator_set_range (GnomeAnimator * animator,
+			       guint low, guint high);
+
+G_END_DECLS
+
+#endif /* _GNOME_ANIMATOR_H */
diff --git a/libgnomeui/gnome-app-helper.c b/libgnomeui/gnome-app-helper.c
new file mode 100644
index 0000000..4782c1c
--- /dev/null
+++ b/libgnomeui/gnome-app-helper.c
@@ -0,0 +1,2672 @@
+/* Copyright (C) 1998 Red Hat Software, Miguel de Icaza, Federico Mena, 
+ * Chris Toshok.
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+/*
+ * Originally by Elliot Lee, with hacking by Chris Toshok for *_data, Marc 
+ * Ewing added menu support, toggle and radio support, and I don't know what 
+ * you other people did :) menu insertion/removal functions by Jaka Mocnik.
+ * Small fixes and documentation by Justin Maurer.
+ *
+ * Major cleanups and rearrangements by Federico Mena and Justin Maurer.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+#include <libgnome/libgnome.h>
+
+#include <libgnome/gnome-util.h>
+#include <libgnome/gnome-config.h>
+#include "gnome-helpsys.h"
+#include "gnome-gconf.h"
+
+/* Note that this file must include gnome-i18n, and not gnome-i18nP, so that 
+ * _() is the same as the one seen by the application.  This is moderately 
+ * bogus; we should just call gettext() directly here.
+ */
+
+#include <libgnome/gnome-i18n.h>
+#include "gnome-app.h"
+#include "gnome-app-helper.h"
+#include "gnome-uidefs.h"
+#include "gnome-stock.h"
+#include "gnome-pixmap.h"
+#include "gnome-preferences.h"
+#include "gnome-stock.h"
+#include "gtkpixmapmenuitem.h"
+
+extern const gchar *gnome_user_accels_dir;
+
+/* keys used for get/set_data */
+const char *gnome_app_helper_gconf_client = "gnome-app-helper-gconf-client";
+const char *gnome_app_helper_menu_hint = "gnome-app-helper:menu-hint";
+const char *gnome_app_helper_pixmap_type = "gnome-app-helper-pixmap-type";
+const char *gnome_app_helper_pixmap_info = "gnome-app-helper-pixmap-info";
+const char *apphelper_statusbar_hint = "apphelper_statusbar_hint";
+const char *apphelper_appbar_hint = "apphelper_appbar_hint";
+const char *GtkMenu_uline_accel_group = "GtkMenu-uline-accel-group";
+
+/* prototypes */
+static gint g_strncmp_ignore_char( const gchar *first, const gchar *second,
+				   gint length, gchar ignored );
+
+
+#ifdef NEVER_DEFINED
+static const char strings [] = {
+	N_("_File"),
+	N_("_File/"),
+	N_("_Edit"),
+	N_("_Edit/"),
+	N_("_View"),
+	N_("_View/"),
+	N_("_Settings"),
+	N_("_Settings/"),
+        N_("_New"),
+	N_("_New/"),
+	N_("Fi_les"),
+	N_("Fi_les/"),
+	N_("_Windows"),
+	N_("_Game"), 
+	N_("_Help"), 
+	N_("_Windows/")
+};
+
+#endif
+
+static GnomeUIInfo menu_defaults[] = {
+        /* New */
+        { GNOME_APP_UI_ITEM, NULL, NULL,
+          NULL, NULL, NULL,
+          GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_NEW,
+          GNOME_KEY_NAME_NEW, GNOME_KEY_MOD_NEW, NULL },
+        /* Open */
+        { GNOME_APP_UI_ITEM, N_("_Open..."), N_("Open a file"),
+          NULL, NULL, NULL,
+          GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_OPEN,
+          GNOME_KEY_NAME_OPEN, GNOME_KEY_MOD_OPEN, NULL },
+	/* Save */
+        { GNOME_APP_UI_ITEM, N_("_Save"), N_("Save the current file"),
+          NULL, NULL, NULL,
+          GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_SAVE,
+          GNOME_KEY_NAME_SAVE, GNOME_KEY_MOD_SAVE, NULL },
+	/* Save As */
+        { GNOME_APP_UI_ITEM, N_("Save _As..."),
+          N_("Save the current file with a different name"),
+          NULL, NULL, NULL,
+	  GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_SAVE_AS,
+          GNOME_KEY_NAME_SAVE_AS, GNOME_KEY_MOD_SAVE_AS, NULL },
+	/* Revert */
+        { GNOME_APP_UI_ITEM, N_("_Revert"),
+          N_("Revert to a saved version of the file"),
+          NULL, NULL, NULL,
+          GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_REVERT,
+          0,  (GdkModifierType) 0, NULL },
+	/* Print */
+        { GNOME_APP_UI_ITEM, N_("_Print"), N_("Print the current file"),
+          NULL, NULL, NULL,
+          GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_PRINT,
+          GNOME_KEY_NAME_PRINT,  GNOME_KEY_MOD_PRINT, NULL },
+	/* Print Setup */
+        { GNOME_APP_UI_ITEM, N_("Print S_etup..."),
+          N_("Setup the page settings for your current printer"),
+          NULL, NULL,
+	  NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_PRINT,
+          GNOME_KEY_NAME_PRINT_SETUP,  GNOME_KEY_MOD_PRINT_SETUP, NULL },
+	/* Close */
+        { GNOME_APP_UI_ITEM, N_("_Close"), N_("Close the current file"),
+          NULL, NULL, NULL,
+          GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_CLOSE,
+          GNOME_KEY_NAME_CLOSE, GNOME_KEY_MOD_CLOSE, NULL },
+	/* Exit */
+        { GNOME_APP_UI_ITEM, N_("E_xit"), N_("Exit the program"),
+          NULL, NULL, NULL, GNOME_APP_PIXMAP_STOCK,
+	  GNOME_STOCK_MENU_EXIT, GNOME_KEY_NAME_EXIT, GNOME_KEY_MOD_EXIT,
+	    NULL },
+	/*
+	 * The "Edit" menu
+	 */
+	/* Cut */
+        { GNOME_APP_UI_ITEM, N_("C_ut"), N_("Cut the selection"),
+          NULL, NULL, NULL,
+          GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_CUT,
+          GNOME_KEY_NAME_CUT, GNOME_KEY_MOD_CUT, NULL },
+	/* 10 */
+	/* Copy */
+        { GNOME_APP_UI_ITEM, N_("_Copy"), N_("Copy the selection"),
+          NULL, NULL, NULL,
+          GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_COPY,
+          GNOME_KEY_NAME_COPY, GNOME_KEY_MOD_COPY, NULL },
+	/* Paste */
+        { GNOME_APP_UI_ITEM, N_("_Paste"), N_("Paste the clipboard"),
+          NULL, NULL, NULL,
+          GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_PASTE,
+          GNOME_KEY_NAME_PASTE, GNOME_KEY_MOD_PASTE, NULL },
+	/* Clear */
+        { GNOME_APP_UI_ITEM, N_("C_lear"), N_("Clear the selection"),
+          NULL, NULL, NULL,
+          GNOME_APP_PIXMAP_NONE, NULL,
+          GNOME_KEY_NAME_CLEAR, GNOME_KEY_MOD_CLEAR, NULL },
+	/* Undo */
+        { GNOME_APP_UI_ITEM, N_("_Undo"), N_("Undo the last action"),
+          NULL, NULL, NULL,
+          GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_UNDO,
+          GNOME_KEY_NAME_UNDO, GNOME_KEY_MOD_UNDO, NULL },
+	/* Redo */
+        { GNOME_APP_UI_ITEM, N_("_Redo"), N_("Redo the undone action"),
+          NULL, NULL, NULL,
+          GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_REDO,
+          GNOME_KEY_NAME_REDO, GNOME_KEY_MOD_REDO, NULL },
+	/* Find */
+        { GNOME_APP_UI_ITEM, N_("_Find..."),  N_("Search for a string"),
+          NULL, NULL, NULL,
+          GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_SEARCH,
+          GNOME_KEY_NAME_FIND, GNOME_KEY_MOD_FIND, NULL },
+	/* Find Again */
+        { GNOME_APP_UI_ITEM, N_("Find _Again"),
+          N_("Search again for the same string"),
+          NULL, NULL, NULL,
+          GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_SEARCH,
+          GNOME_KEY_NAME_FIND_AGAIN, GNOME_KEY_MOD_FIND_AGAIN, NULL },
+	/* Replace */
+        { GNOME_APP_UI_ITEM, N_("_Replace..."), N_("Replace a string"),
+          NULL, NULL, NULL,
+          GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_SRCHRPL,
+          GNOME_KEY_NAME_REPLACE, GNOME_KEY_MOD_REPLACE, NULL },
+	/* Properties */
+        { GNOME_APP_UI_ITEM, N_("_Properties..."),
+          N_("Modify the file's properties"),
+          NULL, NULL, NULL,
+	  GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_PROP,
+          0,  (GdkModifierType) 0, NULL },
+	/*
+	 * The Settings menu
+	 */
+	/* Settings */
+        { GNOME_APP_UI_ITEM, N_("_Preferences..."),
+          N_("Configure the application"),
+          NULL, NULL,
+	  NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_PREF,
+          0,  (GdkModifierType) 0, NULL },
+	/* 20 */
+	/*
+	 * And the "Help" menu
+	 */
+	/* About */
+        { GNOME_APP_UI_ITEM, N_("_About"),
+          N_("About this application"), NULL, NULL,
+	  NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_ABOUT,
+          0,  (GdkModifierType) 0, NULL },
+	{ GNOME_APP_UI_ITEM, N_("_Select All"),
+          N_("Select everything"),
+          NULL, NULL, NULL,
+          GNOME_APP_PIXMAP_NONE, NULL,
+          GNOME_KEY_NAME_SELECT_ALL, GNOME_KEY_MOD_SELECT_ALL, NULL },
+
+	/*
+	 * Window menu
+	 */
+        { GNOME_APP_UI_ITEM, N_("Create New _Window"),
+          N_("Create a new window"),
+          NULL, NULL, NULL,
+          GNOME_APP_PIXMAP_NONE, NULL,
+          GNOME_KEY_NAME_NEW_WINDOW, GNOME_KEY_MOD_NEW_WINDOW, NULL },
+        { GNOME_APP_UI_ITEM, N_("_Close This Window"),
+          N_("Close the current window"),
+          NULL, NULL, NULL,
+          GNOME_APP_PIXMAP_NONE, NULL,
+          GNOME_KEY_NAME_CLOSE_WINDOW, GNOME_KEY_MOD_CLOSE_WINDOW, NULL },
+
+	/*
+	 * The "Game" menu
+	 */
+        { GNOME_APP_UI_ITEM, N_("_New game"),
+          N_("Start a new game"),
+	  NULL, NULL, NULL,
+          GNOME_APP_PIXMAP_NONE, NULL,
+          GNOME_KEY_NAME_NEW_GAME,  GNOME_KEY_MOD_NEW_GAME, NULL },
+        { GNOME_APP_UI_ITEM, N_("_Pause game"),
+          N_("Pause the game"), 
+	  NULL, NULL, NULL,
+	  GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_TIMER_STOP,
+          GNOME_KEY_NAME_PAUSE_GAME,  GNOME_KEY_MOD_PAUSE_GAME, NULL },
+        { GNOME_APP_UI_ITEM, N_("_Restart game"),
+          N_("Restart the game"),
+	  NULL, NULL, NULL,
+          GNOME_APP_PIXMAP_NONE, NULL,
+          0,  0, NULL },
+        { GNOME_APP_UI_ITEM, N_("_Undo move"),
+          N_("Undo the last move"),
+	  NULL, NULL, NULL,
+	  GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_UNDO,
+          GNOME_KEY_NAME_UNDO_MOVE,  GNOME_KEY_MOD_UNDO_MOVE, NULL },
+        { GNOME_APP_UI_ITEM, N_("_Redo move"),
+          N_("Redo the undone move"),
+	  NULL, NULL, NULL,
+	  GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_REDO,
+          GNOME_KEY_NAME_REDO_MOVE,  GNOME_KEY_MOD_REDO_MOVE, NULL },
+        { GNOME_APP_UI_ITEM, N_("_Hint"),
+          N_("Get a hint for your next move"),
+	  NULL, NULL, NULL,
+          GNOME_APP_PIXMAP_NONE, NULL,
+          0,  0, NULL },
+	/* 30 */
+        { GNOME_APP_UI_ITEM, N_("_Scores..."),
+          N_("View the scores"),
+	  NULL, NULL, NULL,
+	  GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_SCORES,
+          0,  (GdkModifierType) 0, NULL },
+        { GNOME_APP_UI_ITEM, N_("_End game"),
+          N_("End the current game"),
+	  NULL, NULL, NULL,
+          GNOME_APP_PIXMAP_NONE, NULL,
+          0,  (GdkModifierType) 0, NULL }
+};
+
+static gchar *menu_names[] =
+{
+  /* 0 */
+  "new",
+  "open",
+  "save",
+  "save-as",
+  "revert",
+  "print",
+  "print-setup",
+  "close",
+  "exit",
+  "cut",
+  /* 10 */
+  "copy",
+  "paste",
+  "clear",
+  "undo",
+  "redo",
+  "find",
+  "find-again",
+  "replace",
+  "properties",
+  "preferences",
+  /* 20 */
+  "about",
+  "select-all",
+  "new-window",
+  "close-window",
+  "new-game",
+  "pause-game",
+  "restart-game",
+  "undo-move",
+  "redo-move",
+  "hint",
+  /* 30 */
+  "scores",
+  "end-game"
+};
+
+
+/* Creates a pixmap appropriate for items.  */
+
+static GtkWidget *
+create_pixmap (GnomeUIPixmapType pixmap_type, gconstpointer pixmap_info)
+{
+	GtkWidget *pixmap;
+	char *name;
+
+	pixmap = NULL;
+
+	switch (pixmap_type) {
+	case GNOME_APP_PIXMAP_STOCK:
+		pixmap = gnome_stock_new_with_icon (pixmap_info);
+		break;
+
+	case GNOME_APP_PIXMAP_DATA:
+		if (pixmap_info)
+			pixmap = gnome_pixmap_new_from_xpm_d ((const char**)pixmap_info);
+
+		break;
+
+	case GNOME_APP_PIXMAP_NONE:
+		break;
+
+	case GNOME_APP_PIXMAP_FILENAME:
+		name = gnome_program_locate_file (gnome_program_get (),
+						  GNOME_FILE_DOMAIN_PIXMAP,
+						  pixmap_info, TRUE, NULL);
+		
+		if (!name)
+			g_warning ("Could not find GNOME pixmap file %s", 
+					(char *) pixmap_info);
+		else {
+			pixmap = gnome_pixmap_new_from_file (name);
+			g_free (name);
+		}
+
+		break;
+
+	default:
+		g_assert_not_reached ();
+		g_warning("Invalid pixmap_type %d", (int) pixmap_type); 
+	}
+
+	return pixmap;
+}
+
+static void
+showing_pixmaps_changed_notify(GConfClient            *client,
+                               guint                   cnxn_id,
+			       GConfEntry             *entry,
+                               gpointer                user_data)
+{
+        gboolean new_setting = TRUE;
+        GtkWidget *w = user_data;
+        GtkPixmapMenuItem *mi = GTK_PIXMAP_MENU_ITEM(w);
+	GConfValue *value;
+
+	value = gconf_entry_get_value (entry);
+
+        if (value && value->type == GCONF_VALUE_BOOL) {
+                new_setting = gconf_value_get_bool(value);
+        }
+
+        if (new_setting && (mi->pixmap == NULL)) {
+                GtkWidget *pixmap;
+                GnomeUIPixmapType pixmap_type;
+                gconstpointer pixmap_info;
+
+                pixmap_type = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(mi),
+                                                                  gnome_app_helper_pixmap_type));
+                pixmap_info = gtk_object_get_data(GTK_OBJECT(mi),
+                                                  gnome_app_helper_pixmap_info);
+
+                pixmap = create_pixmap(pixmap_type, pixmap_info);
+
+                gtk_widget_show(pixmap);
+                
+                gtk_pixmap_menu_item_set_pixmap(GTK_PIXMAP_MENU_ITEM(mi),
+                                                pixmap);
+                
+        } else if (!new_setting && (mi->pixmap != NULL)) {
+                gtk_container_remove(GTK_CONTAINER(mi), mi->pixmap);
+        }
+}
+
+/* Note that this function is also used for toolbars, don't assume
+   obj is a menu item */
+static void
+remove_notify_cb(GtkObject *obj, gpointer data)
+{
+        guint notify_id;
+        GConfClient *conf;
+        
+        notify_id = GPOINTER_TO_INT(data);
+
+        conf = gtk_object_get_data(obj, gnome_app_helper_gconf_client);
+
+        gconf_client_notify_remove(conf, notify_id);
+}
+
+static void
+setup_pixmap_menu_item(GtkWidget *mi, GnomeUIPixmapType pixmap_type,
+                       gconstpointer pixmap_info)
+{
+        guint notify_id;
+        GConfClient *conf;
+        
+        g_return_if_fail(GTK_IS_PIXMAP_MENU_ITEM(mi));
+
+        gtk_object_set_data(GTK_OBJECT(mi), gnome_app_helper_pixmap_type,
+                            GINT_TO_POINTER(pixmap_type));
+
+        gtk_object_set_data(GTK_OBJECT(mi), gnome_app_helper_pixmap_info,
+                            (gpointer)pixmap_info);
+
+        
+        conf = gconf_client_get_default();
+
+        g_object_ref (G_OBJECT (conf));
+        gtk_object_set_data_full(GTK_OBJECT(mi), gnome_app_helper_gconf_client,
+                                 conf, (GtkDestroyNotify)g_object_unref);
+
+        if (gconf_client_get_bool(conf,
+                                  "/desktop/gnome/menus/show-icons",
+                                  NULL)) {
+                GtkWidget *pixmap;
+
+                pixmap = create_pixmap(pixmap_type, pixmap_info);
+
+                gtk_widget_show(pixmap);
+                
+                gtk_pixmap_menu_item_set_pixmap(GTK_PIXMAP_MENU_ITEM(mi),
+                                                pixmap);
+        }
+
+        notify_id = gconf_client_notify_add(conf,
+                                            "/desktop/gnome/menus/show-icons",
+                                            showing_pixmaps_changed_notify,
+                                            mi, NULL, NULL);
+
+        gtk_signal_connect(GTK_OBJECT(mi), "destroy",
+                           GTK_SIGNAL_FUNC(remove_notify_cb),
+			   GINT_TO_POINTER(notify_id));
+}
+
+/* Creates  a menu item label. It will also return the underlined 
+ * letter's keyval if keyval is not NULL. */
+static GtkWidget *
+create_label (const char *label_text, guint *keyval)
+{
+	guint kv;
+	GtkWidget *label;
+
+	label = gtk_accel_label_new (label_text);
+
+	kv = gtk_label_parse_uline (GTK_LABEL (label), label_text);
+	if (keyval)
+		*keyval = kv;
+
+	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+	gtk_widget_show (label);
+
+	return label;
+}
+
+/* Creates the accelerator for the specified uiinfo item's hotkey */
+static void
+setup_accelerator (GtkAccelGroup *accel_group, GnomeUIInfo *uiinfo, 
+		char *signal_name, int accel_flags)
+{
+	if (uiinfo->accelerator_key != 0)
+		gtk_widget_add_accelerator (uiinfo->widget, signal_name, 
+					    accel_group, uiinfo->accelerator_key, 
+					    uiinfo->ac_mods, accel_flags);
+}
+
+#ifndef	GTK_CHECK_VERSION
+GtkAccelGroup*
+gtk_menu_ensure_uline_accel_group (GtkMenu *menu)
+{
+  GtkAccelGroup *accel_group;
+
+  g_return_val_if_fail (GTK_IS_MENU (menu), NULL);
+
+  accel_group = gtk_object_get_data (GTK_OBJECT (menu),
+				     GtkMenu_uline_accel_group);
+  if (!accel_group)
+    {
+      accel_group = gtk_accel_group_new ();
+      gtk_accel_group_attach (accel_group, GTK_OBJECT (menu));
+      gtk_object_set_data_full (GTK_OBJECT (menu),
+				GtkMenu_uline_accel_group,
+				accel_group,
+				(GtkDestroyNotify) gtk_accel_group_unref);
+    }
+
+  return accel_group;
+}
+void
+gtk_item_factory_add_foreign (GtkWidget      *accel_widget,
+			      const gchar    *full_path,
+			      GtkAccelGroup  *accel_group,
+			      guint           keyval,
+			      GdkModifierType modifiers)
+{
+  if (accel_group)
+    gtk_widget_add_accelerator (accel_widget,
+				"activate",
+				accel_group,
+				keyval,
+				modifiers,
+				GTK_ACCEL_VISIBLE);
+}
+#endif
+
+/* Creates the accelerators for the underlined letter in a menu item's label. 
+ * The keyval is what gtk_label_parse_uline() returned.  If accel_group is not 
+ * NULL, then the keyval will be put with MOD1 as modifier in it (i.e. for 
+ * Alt-F in the _File menu).
+ */
+static void
+setup_uline_accel (GtkMenuShell  *menu_shell,
+		   GtkAccelGroup *accel_group,
+		   GtkWidget     *menu_item,
+		   guint          keyval)
+{
+#if 0 /* FIXME FIXME FIXME */
+	if (keyval != GDK_VoidSymbol) {
+		if (GTK_IS_MENU (menu_shell))
+			gtk_widget_add_accelerator (menu_item,
+						    "activate_item",
+						    gtk_menu_ensure_uline_accel_group (GTK_MENU (menu_shell)),
+						    keyval, 0,
+						    0);
+		if (GTK_IS_MENU_BAR (menu_shell) && accel_group)
+			gtk_widget_add_accelerator (menu_item,
+						    "activate_item", 
+						    accel_group,
+						    keyval, GDK_MOD1_MASK,
+						    0);
+	}
+#endif
+}
+
+/* Callback to display hint in the statusbar when a menu item is 
+ * activated. For GtkStatusbar.
+ */
+
+static void
+put_hint_in_statusbar(GtkWidget* menuitem, gpointer data)
+{
+	gchar* hint = gtk_object_get_data(GTK_OBJECT(menuitem),
+					  apphelper_statusbar_hint);
+	GtkWidget* bar = data;
+	guint id;
+	
+	g_return_if_fail (hint != NULL);
+	g_return_if_fail (bar != NULL);
+	g_return_if_fail (GTK_IS_STATUSBAR(bar));
+	
+	id = gtk_statusbar_get_context_id(GTK_STATUSBAR(bar),
+					  gnome_app_helper_menu_hint);
+	
+	gtk_statusbar_push(GTK_STATUSBAR(bar),id,hint);
+}
+
+/* Callback to remove hint when the menu item is deactivated.
+ * For GtkStatusbar.
+ */
+static void
+remove_hint_from_statusbar(GtkWidget* menuitem, gpointer data)
+{
+	GtkWidget* bar = data;
+	guint id;
+	
+	g_return_if_fail (bar != NULL);
+	g_return_if_fail (GTK_IS_STATUSBAR(bar));
+	
+	id = gtk_statusbar_get_context_id(GTK_STATUSBAR(bar),
+					  gnome_app_helper_menu_hint);
+	
+	gtk_statusbar_pop(GTK_STATUSBAR(bar), id);
+}
+
+/* Install a hint for a menu item
+ */
+static void
+install_menuitem_hint_to_statusbar(GnomeUIInfo* uiinfo, GtkStatusbar* bar)
+{
+  g_return_if_fail (uiinfo != NULL);
+  g_return_if_fail (uiinfo->widget != NULL);
+  g_return_if_fail (GTK_IS_MENU_ITEM(uiinfo->widget));
+
+  /* This is mildly fragile; if someone destroys the appbar
+     but not the menu, chaos will ensue. */
+
+  if (uiinfo->hint)
+    {
+      gtk_object_set_data (GTK_OBJECT(uiinfo->widget),
+                           apphelper_statusbar_hint,
+                           (gpointer)L_(uiinfo->hint));
+
+      gtk_signal_connect (GTK_OBJECT (uiinfo->widget),
+                          "select",
+                          GTK_SIGNAL_FUNC(put_hint_in_statusbar),
+                          bar);
+      
+      gtk_signal_connect (GTK_OBJECT (uiinfo->widget),
+                          "deselect",
+                          GTK_SIGNAL_FUNC(remove_hint_from_statusbar),
+                          bar);
+    }
+}        
+
+/**
+ * gnome_app_install_statusbar_menu_hints
+ * @bar: Pointer to Gtk+ status bar object
+ * @uiinfo: Gnome UI info for the menu to be changed
+ *
+ * Description:
+ * Install menu hints for the given status bar.
+ */
+
+void 
+gnome_app_install_statusbar_menu_hints (GtkStatusbar* bar,
+                                        GnomeUIInfo* uiinfo)
+{
+	g_return_if_fail (bar != NULL);
+	g_return_if_fail (uiinfo != NULL);
+	g_return_if_fail (GTK_IS_STATUSBAR (bar));
+	
+	
+	while (uiinfo->type != GNOME_APP_UI_ENDOFINFO)
+	{
+		switch (uiinfo->type) {
+		case GNOME_APP_UI_INCLUDE:
+			gnome_app_install_statusbar_menu_hints(bar, uiinfo->moreinfo);
+			break;
+
+		case GNOME_APP_UI_SUBTREE:
+		case GNOME_APP_UI_SUBTREE_STOCK:
+			gnome_app_install_statusbar_menu_hints(bar, uiinfo->moreinfo);
+			
+		case GNOME_APP_UI_ITEM:
+		case GNOME_APP_UI_TOGGLEITEM:
+		case GNOME_APP_UI_SEPARATOR:
+			install_menuitem_hint_to_statusbar(uiinfo, bar);
+			break;
+		case GNOME_APP_UI_RADIOITEMS:
+			gnome_app_install_statusbar_menu_hints(bar, uiinfo->moreinfo);
+			break;
+		default:
+			;
+			break;
+		}
+		
+		++uiinfo;
+	}
+}
+
+
+/* Callback to display hint in the statusbar when a menu item is 
+ * activated. For GnomeAppBar.
+ */
+
+static void
+put_hint_in_appbar(GtkWidget* menuitem, gpointer data)
+{
+  gchar* hint = gtk_object_get_data (GTK_OBJECT(menuitem),
+                                     "apphelper_appbar_hint");
+  GtkWidget* bar = data;
+
+  g_return_if_fail (hint != NULL);
+  g_return_if_fail (bar != NULL);
+  g_return_if_fail (GNOME_IS_APPBAR(bar));
+
+  gnome_appbar_set_status (GNOME_APPBAR(bar), hint);
+}
+
+/* Callback to remove hint when the menu item is deactivated.
+ * For GnomeAppBar.
+ */
+static void
+remove_hint_from_appbar(GtkWidget* menuitem, gpointer data)
+{
+  GtkWidget* bar = data;
+
+  g_return_if_fail (bar != NULL);
+  g_return_if_fail (GNOME_IS_APPBAR(bar));
+
+  gnome_appbar_refresh (GNOME_APPBAR(bar));
+}
+
+/* Install a hint for a menu item
+ */
+static void
+install_menuitem_hint_to_appbar(GnomeUIInfo* uiinfo, GnomeAppBar* bar)
+{
+  g_return_if_fail (uiinfo != NULL);
+  g_return_if_fail (uiinfo->widget != NULL);
+  g_return_if_fail (GTK_IS_MENU_ITEM(uiinfo->widget));
+
+  /* This is mildly fragile; if someone destroys the appbar
+     but not the menu, chaos will ensue. */
+
+  if (uiinfo->hint)
+    {
+      gtk_object_set_data (GTK_OBJECT(uiinfo->widget),
+                           apphelper_appbar_hint,
+                           (gpointer)L_(uiinfo->hint));
+
+      gtk_signal_connect (GTK_OBJECT (uiinfo->widget),
+                          "select",
+                          GTK_SIGNAL_FUNC(put_hint_in_appbar),
+                          bar);
+      
+      gtk_signal_connect (GTK_OBJECT (uiinfo->widget),
+                          "deselect",
+                          GTK_SIGNAL_FUNC(remove_hint_from_appbar),
+                          bar);
+    }
+}
+
+
+/**
+ * gnome_app_ui_configure_configurable
+ * @uiinfo: Pointer to GNOME UI menu/toolbar info
+ * 
+ * Description:
+ * Configure all user-configurable elements in the given UI info 
+ * structure.  This includes loading and setting previously-set options from
+ * GNOME config files.
+ */
+
+void
+gnome_app_ui_configure_configurable (GnomeUIInfo* uiinfo)
+{
+  if (uiinfo->type == GNOME_APP_UI_ITEM_CONFIGURABLE)
+  {
+        GnomeUIInfoConfigurableTypes type = (GnomeUIInfoConfigurableTypes) uiinfo->accelerator_key;
+	
+	gboolean accelerator_key_def;
+	gchar *accelerator_key_string;
+	gint accelerator_key;
+	
+	gboolean ac_mods_def;
+	gchar *ac_mods_string;
+	gint ac_mods;
+	
+	if ( type != GNOME_APP_CONFIGURABLE_ITEM_NEW ) {
+#if 0
+	        gboolean label_def;
+		gchar *label_string;
+		gchar *label;
+	        gboolean hint_def;
+		gchar *hint_string;
+		gchar *hint;
+		
+		label_string = g_strdup_sprintf( "/Gnome/Menus/Menu-%s-label", menu_names[(int) type] );
+		label = gnome_config_get_string_with_default( label_string, &label_def);
+		if ( label_def )
+		  uiinfo->label = label;
+		else
+		  {
+#endif
+		    uiinfo->label = menu_defaults[(int) type].label;
+#if 0
+		    g_free( label );
+		  }
+		g_free( label_string );
+
+		hint_string = g_strdup_sprintf( "/Gnome/Menus/Menu-%s-hint", menu_names[(int) type] );
+		hint = gnome_config_get_string_with_default( hint_string, &hint_def);
+		if ( hint_def )
+		  uiinfo->hint = hint;
+		else
+		  {
+#endif
+		    uiinfo->hint = menu_defaults[(int) type].hint;
+#if 0
+		    g_free( hint );
+		  }
+		g_free( hint_string );
+#endif
+	}
+	uiinfo->pixmap_type = menu_defaults[(int) type].pixmap_type;
+	uiinfo->pixmap_info = menu_defaults[(int) type].pixmap_info;
+
+	accelerator_key_string = g_strdup_printf( "/Gnome/Menus/Menu-%s-accelerator-key", menu_names[(int) type] );
+	accelerator_key = gnome_config_get_int_with_default( accelerator_key_string, &accelerator_key_def);
+	if ( accelerator_key_def )
+	  uiinfo->accelerator_key = menu_defaults[(int) type].accelerator_key;
+	else
+	  uiinfo->accelerator_key = accelerator_key;
+	g_free( accelerator_key_string );
+	
+	ac_mods_string = g_strdup_printf( "/Gnome/Menus/Menu-%s-ac-mods", menu_names[(int) type] );
+	ac_mods = gnome_config_get_int_with_default( ac_mods_string, &ac_mods_def);
+	if ( ac_mods_def )
+	  uiinfo->ac_mods = menu_defaults[(int) type].ac_mods;
+	else
+	  uiinfo->ac_mods = (GdkModifierType) ac_mods;
+	g_free( ac_mods_string );
+
+	
+	uiinfo->type = GNOME_APP_UI_ITEM;
+  }
+}
+
+
+/**
+ * gnome_app_install_appbar_menu_hints
+ * @appbar: Pointer to GNOME app bar object.
+ * @uiinfo: GNOME UI info for menu
+ *
+ * Description:
+ * Install menu hints for the given GNOME app bar object.
+ */
+
+void
+gnome_app_install_appbar_menu_hints (GnomeAppBar* appbar,
+                                     GnomeUIInfo* uiinfo)
+{
+	g_return_if_fail (appbar != NULL);
+	g_return_if_fail (uiinfo != NULL);
+	g_return_if_fail (GNOME_IS_APPBAR (appbar));
+	
+	
+	while (uiinfo->type != GNOME_APP_UI_ENDOFINFO)
+	{
+		
+		/* Translate configurable menu items to normal menu items. */
+		
+		if ( uiinfo->type == GNOME_APP_UI_ITEM_CONFIGURABLE ) {
+			gnome_app_ui_configure_configurable( uiinfo );
+		}
+		switch (uiinfo->type) {
+		case GNOME_APP_UI_INCLUDE:
+			gnome_app_install_appbar_menu_hints(appbar, uiinfo->moreinfo);
+			break;
+
+		case GNOME_APP_UI_SUBTREE:
+		case GNOME_APP_UI_SUBTREE_STOCK:
+			gnome_app_install_appbar_menu_hints(appbar, uiinfo->moreinfo);
+			
+		case GNOME_APP_UI_ITEM:
+		case GNOME_APP_UI_TOGGLEITEM:
+		case GNOME_APP_UI_SEPARATOR:
+			install_menuitem_hint_to_appbar(uiinfo, appbar);
+			break;
+		case GNOME_APP_UI_RADIOITEMS:
+			gnome_app_install_appbar_menu_hints(appbar, uiinfo->moreinfo);
+			break;
+		default:
+			; 
+			break;
+		}
+		
+		++uiinfo;
+	}
+}
+
+
+/**
+ * gnome_app_install_menu_hints
+ * @app: Pointer to GNOME app object
+ * @uiinfo: GNOME UI menu for which hints will be set
+ *
+ * Description:
+ * Set menu hints for the GNOME app object's attached status bar.
+ */
+
+void
+gnome_app_install_menu_hints (GnomeApp *app,
+                              GnomeUIInfo *uiinfo) {
+  g_return_if_fail (app != NULL);
+  g_return_if_fail (uiinfo != NULL);
+  g_return_if_fail (app->statusbar != NULL);
+  g_return_if_fail (GNOME_IS_APP (app));
+
+  if(GNOME_IS_APPBAR(app->statusbar))
+    gnome_app_install_appbar_menu_hints(GNOME_APPBAR(app->statusbar), uiinfo);
+  else if(GTK_IS_STATUSBAR(app->statusbar))
+    gnome_app_install_statusbar_menu_hints(GTK_STATUSBAR(app->statusbar), uiinfo);
+}
+
+static gint
+gnome_save_accels (gpointer data)
+{
+	gchar *file_name;
+
+	file_name = g_concat_dir_and_file (gnome_user_accels_dir, gnome_program_get_name(gnome_program_get()));
+	gtk_item_factory_dump_rc (file_name, NULL, TRUE);
+	g_free (file_name);
+
+	return TRUE;
+}
+
+void
+gnome_accelerators_sync (void)
+{
+  gnome_save_accels (NULL);
+}
+
+/* Creates a menu item appropriate for the SEPARATOR, ITEM, TOGGLEITEM, or 
+ * SUBTREE types.  If the item is inside a radio group, then a pointer to the 
+ * group's list must be specified as well (*radio_group must be NULL for the 
+ * first item!).  This function does *not* create the submenu of a subtree 
+ * menu item.
+ */
+static void
+create_menu_item (GtkMenuShell       *menu_shell,
+		  GnomeUIInfo        *uiinfo,
+		  int                 is_radio,
+		  GSList            **radio_group,
+		  GnomeUIBuilderData *uibdata,
+		  GtkAccelGroup      *accel_group,
+		  gboolean	      uline_accels,
+		  gint		      pos)
+{
+	GtkWidget *label;
+	guint keyval;
+	int type;
+	
+	/* Translate configurable menu items to normal menu items. */
+
+	if (uiinfo->type == GNOME_APP_UI_ITEM_CONFIGURABLE)
+	        gnome_app_ui_configure_configurable( uiinfo );
+
+	/* Create the menu item */
+
+	switch (uiinfo->type) {
+	case GNOME_APP_UI_SEPARATOR:
+	        uiinfo->widget = gtk_menu_item_new ();
+		break;
+	case GNOME_APP_UI_ITEM:
+	case GNOME_APP_UI_SUBTREE:
+	case GNOME_APP_UI_SUBTREE_STOCK:
+		if (is_radio) {
+			uiinfo->widget = gtk_radio_menu_item_new (*radio_group);
+			*radio_group = gtk_radio_menu_item_group
+				(GTK_RADIO_MENU_ITEM (uiinfo->widget));
+		} else {
+
+		        /* Create the pixmap */
+
+		        /* FIXME: this should later allow for on-the-fly configuration of 
+			 * whether pixmaps are displayed or not ???
+			 */
+
+		        if ((uiinfo->pixmap_type != GNOME_APP_PIXMAP_NONE) &&
+			    gnome_preferences_get_menus_have_icons()) {
+			        uiinfo->widget = gtk_pixmap_menu_item_new ();
+
+                                setup_pixmap_menu_item(uiinfo->widget,
+                                                       uiinfo->pixmap_type, 
+                                                       uiinfo->pixmap_info);
+			} else
+			        uiinfo->widget = gtk_menu_item_new ();
+		}
+		break;
+
+	case GNOME_APP_UI_TOGGLEITEM:
+		uiinfo->widget = gtk_check_menu_item_new ();
+		break;
+
+	default:
+		g_warning ("Invalid GnomeUIInfo type %d passed to "
+				"create_menu_item()", (int) uiinfo->type);
+		return;
+	}
+
+	if (!accel_group)
+		gtk_widget_lock_accelerators (uiinfo->widget);
+
+	gtk_widget_show (uiinfo->widget);
+	gtk_menu_shell_insert (menu_shell, uiinfo->widget, pos);
+
+	/* If it is a separator, set it as insensitive so that it cannot be 
+	 * selected, and return -- there is nothing left to do.
+	 */
+
+	if (uiinfo->type == GNOME_APP_UI_SEPARATOR) {
+		gtk_widget_set_sensitive (uiinfo->widget, FALSE);
+		return;
+	}
+
+	/* Create the contents of the menu item */
+
+	/* Don't use gettext on the empty string since gettext will map
+	 * the empty string to the header at the beginning of the .pot file. */
+
+	label = create_label ( uiinfo->label [0] == '\0'?
+			       "":(uiinfo->type == GNOME_APP_UI_SUBTREE_STOCK ?
+				   D_(uiinfo->label):L_(uiinfo->label)),
+			       &keyval);
+
+	gtk_container_add (GTK_CONTAINER (uiinfo->widget), label);
+
+	gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (label), 
+					  uiinfo->widget);
+	
+	/* setup underline accelerators
+	 */
+	if (uline_accels)
+		setup_uline_accel (menu_shell,
+				   accel_group,
+				   uiinfo->widget,
+				   keyval);
+
+	/* install global accelerator
+	 */
+	{
+		static guint save_accels_id = 0;
+		GString *gstring;
+		GtkWidget *widget;
+		
+		/* build up the menu item path */
+		gstring = g_string_new ("");
+		widget = uiinfo->widget;
+		while (widget) {
+			if (GTK_IS_MENU_ITEM (widget)) {
+				GtkWidget *child = GTK_BIN (widget)->child;
+				
+				if (GTK_IS_LABEL (child)) {
+					g_string_prepend (gstring, GTK_LABEL (child)->label);
+					g_string_prepend_c (gstring, '/');
+				}
+				widget = widget->parent;
+			} else if (GTK_IS_MENU (widget)) {
+				widget = gtk_menu_get_attach_widget (GTK_MENU (widget));
+				if (widget == NULL) {
+					g_string_prepend (gstring, "/-Orphan");
+					widget = NULL;
+				}
+			} else
+				widget = widget->parent;
+		}
+		g_string_prepend_c (gstring, '>');
+		g_string_prepend (gstring, gnome_program_get_name(gnome_program_get()));
+		g_string_prepend_c (gstring, '<');
+
+		/* g_print ("######## menu item path: %s\n", gstring->str); */
+		
+		/* the item factory cares about installing the correct accelerator */
+		
+		gtk_item_factory_add_foreign (uiinfo->widget,
+					      gstring->str,
+					      accel_group,
+					      uiinfo->accelerator_key,
+					      uiinfo->ac_mods);
+		g_string_free (gstring, TRUE);
+
+		if (!save_accels_id)
+			save_accels_id = gtk_quit_add (1, gnome_save_accels, NULL);
+	}
+	
+	/* Set toggle information, if appropriate */
+	
+	if ((uiinfo->type == GNOME_APP_UI_TOGGLEITEM) || is_radio) {
+		gtk_check_menu_item_set_show_toggle
+			(GTK_CHECK_MENU_ITEM(uiinfo->widget), TRUE);
+		gtk_check_menu_item_set_active
+			(GTK_CHECK_MENU_ITEM (uiinfo->widget), FALSE);
+	}
+	
+	/* Connect to the signal and set user data */
+	
+	type = uiinfo->type;
+	if (type == GNOME_APP_UI_SUBTREE_STOCK)
+		type = GNOME_APP_UI_SUBTREE;
+	
+	if (type != GNOME_APP_UI_SUBTREE) {
+	        gtk_object_set_data (GTK_OBJECT (uiinfo->widget),
+				     GNOMEUIINFO_KEY_UIDATA,
+				     uiinfo->user_data);
+
+		gtk_object_set_data (GTK_OBJECT (uiinfo->widget),
+				     GNOMEUIINFO_KEY_UIBDATA,
+				     uibdata->data);
+
+		(* uibdata->connect_func) (uiinfo, "activate", uibdata);
+	}
+}
+
+/* Creates a group of radio menu items.  Returns the updated position parameter. */
+static int
+create_radio_menu_items (GtkMenuShell *menu_shell, GnomeUIInfo *uiinfo, 
+		GnomeUIBuilderData *uibdata, GtkAccelGroup *accel_group, 
+		gint pos)
+{
+	GSList *group;
+
+	group = NULL;
+
+	for (; uiinfo->type != GNOME_APP_UI_ENDOFINFO; uiinfo++)
+		switch (uiinfo->type) {
+		case GNOME_APP_UI_BUILDER_DATA:
+			uibdata = uiinfo->moreinfo;
+			break;
+
+		case GNOME_APP_UI_ITEM:
+			create_menu_item (menu_shell, uiinfo, TRUE,
+					  &group, uibdata, 
+					  accel_group, FALSE, pos);
+			pos++;
+			break;
+
+		default:
+			g_warning ("GnomeUIInfo element type %d is not valid "
+					"inside a menu radio item group",
+				   (int) uiinfo->type);
+		}
+
+	return pos;
+}
+
+/* Creates the menu entries for help topics.  Returns the updated position 
+ * value. */
+static int
+create_help_entries (GtkMenuShell *menu_shell, GnomeUIInfo *uiinfo, gint pos)
+{
+	GSList *topics, *cur;
+
+	uiinfo->widget = NULL; /* No relevant widget, as we may have created 
+				  several of them */
+
+	if (!uiinfo->moreinfo) {
+		g_warning ("GnomeUIInfo->moreinfo cannot be NULL for "
+				"GNOME_APP_UI_HELP");
+		return pos;
+	}
+
+	/* #warning FIXME: this needs to use helpsys!!!! */
+	topics = NULL;
+	/* topics = gnome_help_app_topics ((const char *)uiinfo->moreinfo);*/
+
+	for (cur = topics; cur && cur->next; cur = cur->next->next)
+	  {
+	    GtkWidget *item;
+	    GtkWidget *label;
+	    guint keyval;
+
+	    item = gtk_menu_item_new ();
+	    label = create_label (cur->data, &keyval);
+	    g_free(cur->data);
+
+	    gtk_container_add (GTK_CONTAINER (item), label);
+	    setup_uline_accel (menu_shell, NULL, item, keyval);
+	    gtk_widget_lock_accelerators (item);
+
+	    /* #warning FIXME: this needs to use helpsys!!!! */
+	    /*
+	    gtk_signal_connect_full (GTK_OBJECT (item), "activate",
+				     (GtkSignalFunc) gnome_help_view_display_callback, NULL,
+				     cur->next->data, g_free,
+				     FALSE, FALSE);
+				     */
+
+	    gtk_menu_shell_insert (menu_shell, item, pos);
+	    pos++;
+
+	    gtk_widget_show (item);
+
+	  }
+	g_slist_free(topics);
+
+	return pos;
+}
+
+/* Performs signal connection as appropriate for interpreters or native bindings */
+static void
+do_ui_signal_connect (GnomeUIInfo *uiinfo, const char *signal_name, 
+		GnomeUIBuilderData *uibdata)
+{
+	if (uibdata->is_interp)
+		gtk_signal_connect_full (GTK_OBJECT (uiinfo->widget), 
+				signal_name, NULL, uibdata->relay_func, 
+				uibdata->data ? 
+				uibdata->data : uiinfo->user_data,
+				uibdata->destroy_func, FALSE, FALSE);
+	
+	else if (uiinfo->moreinfo)
+		gtk_signal_connect (GTK_OBJECT (uiinfo->widget), 
+				signal_name, uiinfo->moreinfo, uibdata->data ? 
+				uibdata->data : uiinfo->user_data);
+}
+
+
+/**
+ * gnome_app_fill_menu
+ * @menu_shell:
+ * @uiinfo:
+ * @accel_group:
+ * @uline_accels:
+ * @pos:
+ *
+ * Description:
+ * Fills the specified menu shell with items created from the specified
+ * info, inserting them from the item no. pos on.
+ * The accel group will be used as the accel group for all newly created
+ * sub menus and serves as the global accel group for all menu item
+ * hotkeys. If it is passed as NULL, global hotkeys will be disabled.
+ * The uline_accels argument determines whether underline accelerators
+ * will be featured from the menu item labels.
+ **/
+
+void
+gnome_app_fill_menu (GtkMenuShell  *menu_shell,
+		     GnomeUIInfo   *uiinfo, 
+		     GtkAccelGroup *accel_group,
+		     gboolean       uline_accels,
+		     gint           pos)
+{
+	GnomeUIBuilderData uibdata;
+
+	g_return_if_fail (menu_shell != NULL);
+	g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell));
+	g_return_if_fail (uiinfo != NULL);
+	g_return_if_fail (pos >= 0);
+	
+	uibdata.connect_func =  do_ui_signal_connect;
+	uibdata.data = NULL;
+	uibdata.is_interp = FALSE;
+	uibdata.relay_func = NULL;
+	uibdata.destroy_func = NULL;
+
+	gnome_app_fill_menu_custom (menu_shell, uiinfo, &uibdata,
+				    accel_group, uline_accels,
+				    pos);
+	return;
+}
+
+
+/**
+ * gnome_app_fill_menu_with_data
+ * @menu_shell:
+ * @uiinfo:
+ * @accel_group:
+ * @uline_accels:
+ * @pos:
+ * @user_data:
+ *
+ * Description:
+ **/
+
+void
+gnome_app_fill_menu_with_data (GtkMenuShell  *menu_shell,
+			       GnomeUIInfo   *uiinfo, 
+			       GtkAccelGroup *accel_group,
+			       gboolean       uline_accels,
+			       gint	      pos,
+			       gpointer       user_data)
+{
+	GnomeUIBuilderData uibdata;
+
+	g_return_if_fail (menu_shell != NULL);
+	g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell));
+	g_return_if_fail (uiinfo != NULL);
+
+	uibdata.connect_func = do_ui_signal_connect;
+	uibdata.data = user_data;
+	uibdata.is_interp = FALSE;
+	uibdata.relay_func = NULL;
+	uibdata.destroy_func = NULL;
+
+	gnome_app_fill_menu_custom (menu_shell, uiinfo, &uibdata,
+				    accel_group, uline_accels,
+				    pos);
+}
+
+
+/**
+ * gnome_app_fill_menu_custom
+ * @menu_shell:
+ * @uiinfo:
+ * @uibdata:
+ * @accel_group:
+ * @uline_accels:
+ * @pos:
+ *
+ * Description:
+ * Fills the specified menu shell with items created from the specified
+ * info, inserting them from item no. pos on and using the specified
+ * builder data -- this is intended for language bindings.
+ * The accel group will be used as the accel group for all newly created
+ * sub menus and serves as the global accel group for all menu item
+ * hotkeys. If it is passed as NULL, global hotkeys will be disabled.
+ * The uline_accels argument determines whether underline accelerators
+ * will be featured from the menu item labels.
+ **/
+
+void
+gnome_app_fill_menu_custom (GtkMenuShell       *menu_shell,
+			    GnomeUIInfo        *uiinfo, 
+			    GnomeUIBuilderData *uibdata,
+			    GtkAccelGroup      *accel_group, 
+			    gboolean            uline_accels,
+			    gint                pos)
+{
+	GnomeUIBuilderData *orig_uibdata;
+
+	g_return_if_fail (menu_shell != NULL);
+	g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell));
+	g_return_if_fail (uiinfo != NULL);
+	g_return_if_fail (uibdata != NULL);
+	g_return_if_fail (pos >= 0);
+
+	/* Store a pointer to the original uibdata so that we can use it for 
+	 * the subtrees */
+
+	orig_uibdata = uibdata;
+
+	for (; uiinfo->type != GNOME_APP_UI_ENDOFINFO; uiinfo++)
+		switch (uiinfo->type) {
+		case GNOME_APP_UI_BUILDER_DATA:
+			/* Set the builder data for subsequent entries in the 
+			 * current uiinfo array */
+			uibdata = uiinfo->moreinfo;
+			break;
+
+		case GNOME_APP_UI_HELP:
+			/* Create entries for the help topics */
+			pos = create_help_entries (menu_shell, uiinfo, pos);
+			break;
+
+		case GNOME_APP_UI_RADIOITEMS:
+			/* Create the radio item group */
+			pos = create_radio_menu_items (menu_shell, 
+					uiinfo->moreinfo, uibdata, accel_group, 
+					pos);
+			break;
+
+		case GNOME_APP_UI_SEPARATOR:
+		case GNOME_APP_UI_ITEM:
+		case GNOME_APP_UI_ITEM_CONFIGURABLE:
+		case GNOME_APP_UI_TOGGLEITEM:
+		case GNOME_APP_UI_SUBTREE:
+		case GNOME_APP_UI_SUBTREE_STOCK:
+			if (uiinfo->type == GNOME_APP_UI_SUBTREE_STOCK)
+				create_menu_item (menu_shell, uiinfo, FALSE,
+						  NULL, uibdata, 
+						  accel_group, uline_accels,
+						  pos);
+			else
+				create_menu_item (menu_shell, uiinfo, FALSE,
+						  NULL, uibdata, 
+						  accel_group, uline_accels,
+						  pos);
+			
+			if (uiinfo->type == GNOME_APP_UI_SUBTREE ||
+			    uiinfo->type == GNOME_APP_UI_SUBTREE_STOCK) {
+				/* Create the subtree for this item */
+
+				GtkWidget *menu;
+				GtkWidget *tearoff;
+
+				menu = gtk_menu_new ();
+				gtk_menu_item_set_submenu
+					(GTK_MENU_ITEM(uiinfo->widget), menu);
+				gtk_menu_set_accel_group (GTK_MENU (menu), accel_group);
+				gnome_app_fill_menu_custom
+					(GTK_MENU_SHELL (menu), 
+					 uiinfo->moreinfo, orig_uibdata, 
+					 accel_group, uline_accels, 0);
+				if (gnome_preferences_get_menus_have_tearoff ()) {
+					tearoff = gtk_tearoff_menu_item_new ();
+					gtk_widget_show (tearoff);
+					gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), tearoff);
+				}
+			}
+			pos++;
+			break;
+
+		case GNOME_APP_UI_INCLUDE:
+		        gnome_app_fill_menu_custom
+			  (menu_shell, 
+			   uiinfo->moreinfo, orig_uibdata,
+			   accel_group, uline_accels, pos);
+			break;
+
+		default:
+			g_warning ("Invalid GnomeUIInfo element type %d\n", 
+					(int) uiinfo->type);
+		}
+
+	/* Make the end item contain a pointer to the parent menu shell */
+
+	uiinfo->widget = GTK_WIDGET (menu_shell);
+
+	/* Configure menu to gnome preferences, if possible.
+	 * (sync to gnome-app.c:gnome_app_set_menus) */
+	if (!gnome_preferences_get_menubar_relief () && GTK_IS_MENU_BAR (menu_shell))
+		gtk_menu_bar_set_shadow_type (GTK_MENU_BAR (menu_shell), GTK_SHADOW_NONE);
+}
+
+
+/**
+ * gnome_app_create_menus
+ * @app: Pointer to GNOME app object.
+ * @uiinfo:
+ *
+ * Description:
+ * Constructs a menu bar and attaches it to the specified application
+ * window.
+ **/
+
+void
+gnome_app_create_menus (GnomeApp *app, GnomeUIInfo *uiinfo)
+{
+	GnomeUIBuilderData uibdata;
+
+	g_return_if_fail (app != NULL);
+	g_return_if_fail (GNOME_IS_APP (app));
+	g_return_if_fail (uiinfo != NULL);
+
+	uibdata.connect_func = do_ui_signal_connect;
+	uibdata.data = NULL;
+	uibdata.is_interp = FALSE;
+	uibdata.relay_func = NULL;
+	uibdata.destroy_func = NULL;
+
+	gnome_app_create_menus_custom (app, uiinfo, &uibdata);
+}
+
+
+/**
+ * gnome_app_create_menus_interp
+ * @app: Pointer to GNOME app object.
+ * @uiinfo:
+ * @relay_func:
+ * @data:
+ * @destroy_func:
+ *
+ * Description:
+ **/
+
+void
+gnome_app_create_menus_interp (GnomeApp *app, GnomeUIInfo *uiinfo, 
+		GtkCallbackMarshal relay_func, gpointer data, 
+		GtkDestroyNotify destroy_func)
+{
+	GnomeUIBuilderData uibdata;
+
+	g_return_if_fail (app != NULL);
+	g_return_if_fail (GNOME_IS_APP (app));
+	g_return_if_fail (uiinfo != NULL);
+
+	uibdata.connect_func = do_ui_signal_connect;
+	uibdata.data = data;
+	uibdata.is_interp = TRUE;
+	uibdata.relay_func = relay_func;
+	uibdata.destroy_func = destroy_func;
+
+	gnome_app_create_menus_custom (app, uiinfo, &uibdata);
+}
+
+
+/**
+ * gnome_app_create_menus_with_data
+ * @app: Pointer to GNOME app object.
+ * @uiinfo:
+ * @user_data:
+ *
+ * Description:
+ **/
+
+void
+gnome_app_create_menus_with_data (GnomeApp *app, GnomeUIInfo *uiinfo,
+				  gpointer user_data)
+{
+	GnomeUIBuilderData uibdata;
+
+	g_return_if_fail (app != NULL);
+	g_return_if_fail (GNOME_IS_APP (app));
+	g_return_if_fail (uiinfo != NULL);
+
+	uibdata.connect_func = do_ui_signal_connect;
+	uibdata.data = user_data;
+	uibdata.is_interp = FALSE;
+	uibdata.relay_func = NULL;
+	uibdata.destroy_func = NULL;
+
+	gnome_app_create_menus_custom (app, uiinfo, &uibdata);
+}
+
+static void
+gnome_app_set_tearoff_menu_titles(GnomeApp *app, GnomeUIInfo *uiinfo,
+				  char *above)
+{
+	int i;
+	char *ctmp = NULL, *ctmp2;
+
+	g_return_if_fail(above);
+	
+	for(i = 0; uiinfo[i].type != GNOME_APP_UI_ENDOFINFO; i++) {
+		int type;
+		
+		type = uiinfo[i].type;
+
+		if(type == GNOME_APP_UI_INCLUDE)
+		  {
+		    gnome_app_set_tearoff_menu_titles (app, uiinfo[i].moreinfo, above);
+		    continue;
+		  }
+
+		if (type == GNOME_APP_UI_SUBTREE_STOCK)
+			type = GNOME_APP_UI_SUBTREE;
+				
+		if(type != GNOME_APP_UI_SUBTREE
+		   || !uiinfo[i].widget)
+			continue;
+
+		if(!ctmp)
+			ctmp = g_alloca(strlen(above) + sizeof(" : ") + strlen(uiinfo[i].label)
+					+ 75 /* eek! Hope noone uses huge menu item names! */);
+		strcpy(ctmp, above);
+		strcat(ctmp, " : ");
+		strcat(ctmp, uiinfo[i].label);
+		
+		ctmp2 = ctmp;
+		while((ctmp2 = strchr(ctmp2, '_')))
+			g_memmove(ctmp2, ctmp2+1, strlen(ctmp2+1)+1);
+
+		gtk_menu_set_title(GTK_MENU(GTK_MENU_ITEM(uiinfo[i].widget)->submenu), ctmp);
+
+		gnome_app_set_tearoff_menu_titles(app, uiinfo[i].moreinfo, ctmp);
+	}
+}
+
+
+/**
+ * gnome_app_create_menus_custom
+ * @app: Pointer to GNOME app object.
+ * @uiinfo:
+ * @uibdata:
+ *
+ * Description:
+ **/
+
+void
+gnome_app_create_menus_custom (GnomeApp *app, GnomeUIInfo *uiinfo, 
+			       GnomeUIBuilderData *uibdata)
+{
+	GtkWidget *menubar;
+
+	g_return_if_fail (app != NULL);
+	g_return_if_fail (GNOME_IS_APP (app));
+	g_return_if_fail (uiinfo != NULL);
+	g_return_if_fail (uibdata != NULL);
+
+	menubar = gtk_menu_bar_new ();
+	gnome_app_set_menus (app, GTK_MENU_BAR (menubar));
+	gnome_app_fill_menu_custom (GTK_MENU_SHELL (menubar), uiinfo, uibdata, 
+				    app->accel_group, TRUE, 0);
+
+	if (gnome_preferences_get_menus_have_tearoff ()) {
+		gchar *app_name;
+
+		app_name = GTK_WINDOW (app)->title;
+		if (!app_name)
+			app_name = GNOME_APP (app)->name;
+		gnome_app_set_tearoff_menu_titles (app, uiinfo, app_name);
+	}
+}
+
+/* Creates a toolbar item appropriate for the SEPARATOR, ITEM, or TOGGLEITEM 
+ * types.  If the item is inside a radio group, then a pointer to the group's 
+ * trailing widget must be specified as well (*radio_group must be NULL for 
+ * the first item!).
+ */
+static void
+create_toolbar_item (GtkToolbar *toolbar, GnomeUIInfo *uiinfo, int is_radio, 
+		GtkWidget **radio_group, GnomeUIBuilderData *uibdata, 
+		GtkAccelGroup *accel_group)
+{
+	GtkWidget *pixmap;
+	GtkToolbarChildType type;
+
+	switch (uiinfo->type) {
+	case GNOME_APP_UI_SEPARATOR:
+		gtk_toolbar_append_space (toolbar);
+		uiinfo->widget = NULL; /* no meaningful widget for a space */
+		break;
+
+	case GNOME_APP_UI_ITEM:
+	case GNOME_APP_UI_TOGGLEITEM:
+		/* Create the icon */
+
+		pixmap = create_pixmap (uiinfo->pixmap_type, uiinfo->pixmap_info);
+
+		/* Create the toolbar item */
+
+		if (is_radio)
+			type = GTK_TOOLBAR_CHILD_RADIOBUTTON;
+		else if (uiinfo->type == GNOME_APP_UI_ITEM)
+			type = GTK_TOOLBAR_CHILD_BUTTON;
+		else
+			type = GTK_TOOLBAR_CHILD_TOGGLEBUTTON;
+
+		uiinfo->widget =
+			gtk_toolbar_append_element (toolbar,
+						    type,
+						    is_radio ? 
+						    *radio_group : NULL,
+						    L_(uiinfo->label),
+						    L_(uiinfo->hint),
+						    NULL,
+						    pixmap,
+						    NULL,
+						    NULL);
+
+		if (is_radio)
+			*radio_group = uiinfo->widget;
+
+		break;
+
+	default:
+		g_warning ("Invalid GnomeUIInfo type %d passed to "
+			   "create_toolbar_item()", (int) uiinfo->type);
+		return;
+	}
+
+	if (uiinfo->type == GNOME_APP_UI_SEPARATOR)
+		return; /* nothing more to do */
+
+	/* Set the accelerator and connect to the signal */
+
+	if (is_radio || (uiinfo->type == GNOME_APP_UI_TOGGLEITEM)) {
+		setup_accelerator (accel_group, uiinfo, "toggled", 0);
+		(* uibdata->connect_func) (uiinfo, "toggled", uibdata);
+	} else {
+		setup_accelerator (accel_group, uiinfo, "clicked", 0);
+		(* uibdata->connect_func) (uiinfo, "clicked", uibdata);
+	}
+}
+
+static void
+create_radio_toolbar_items (GtkToolbar *toolbar, GnomeUIInfo *uiinfo, 
+		GnomeUIBuilderData *uibdata, GtkAccelGroup *accel_group)
+{
+	GtkWidget *group;
+	gpointer orig_uibdata = uibdata;
+
+	group = NULL;
+
+	for (; uiinfo->type != GNOME_APP_UI_ENDOFINFO; uiinfo++)
+		switch (uiinfo->type) {
+		case GNOME_APP_UI_BUILDER_DATA:
+			uibdata = uiinfo->moreinfo;
+			break;
+
+		case GNOME_APP_UI_ITEM:
+			create_toolbar_item (toolbar, uiinfo, TRUE, &group, 
+					uibdata, accel_group);
+			break;
+
+		case GNOME_APP_UI_INCLUDE:
+		        create_radio_toolbar_items (toolbar, uiinfo->moreinfo, orig_uibdata, accel_group);
+		        break;
+
+		default:
+			g_warning ("GnomeUIInfo element type %d is not valid "
+				   "inside a toolbar radio item group",
+				   (int) uiinfo->type);
+		}
+}
+
+
+/**
+ * gnome_app_fill_toolbar
+ * @toolbar:
+ * @uiinfo:
+ * @accel_group:
+ *
+ * Description:
+ **/
+
+void
+gnome_app_fill_toolbar (GtkToolbar *toolbar, GnomeUIInfo *uiinfo, 
+		GtkAccelGroup *accel_group)
+{
+	GnomeUIBuilderData uibdata;
+
+	g_return_if_fail (toolbar != NULL);
+	g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
+	g_return_if_fail (uiinfo != NULL);
+
+	uibdata.connect_func = do_ui_signal_connect;
+	uibdata.data = NULL;
+	uibdata.is_interp = FALSE;
+	uibdata.relay_func = NULL;
+	uibdata.destroy_func = NULL;
+
+	gnome_app_fill_toolbar_custom (toolbar, uiinfo, &uibdata, accel_group);
+}
+
+
+/**
+ * gnome_app_fill_toolbar_with_data
+ * @toolbar:
+ * @uiinfo:
+ * @accel_group:
+ * @user_data:
+ *
+ * Description:
+ **/
+
+void
+gnome_app_fill_toolbar_with_data (GtkToolbar *toolbar, GnomeUIInfo *uiinfo, 
+				  GtkAccelGroup *accel_group, gpointer user_data)
+{
+	GnomeUIBuilderData uibdata;
+
+	g_return_if_fail (toolbar != NULL);
+	g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
+	g_return_if_fail (uiinfo != NULL);
+
+	uibdata.connect_func = do_ui_signal_connect;
+	uibdata.data = user_data;
+	uibdata.is_interp = FALSE;
+	uibdata.relay_func = NULL;
+	uibdata.destroy_func = NULL;
+
+	gnome_app_fill_toolbar_custom (toolbar, uiinfo, &uibdata, accel_group);
+}
+
+
+/**
+ * gnome_app_fill_toolbar_custom
+ * @toolbar:
+ * @uiinfo:
+ * @uibdata:
+ * @accel_group:
+ *
+ * Description:
+ **/
+
+void
+gnome_app_fill_toolbar_custom (GtkToolbar *toolbar, GnomeUIInfo *uiinfo, 
+		GnomeUIBuilderData *uibdata, GtkAccelGroup *accel_group)
+{
+	g_return_if_fail (toolbar != NULL);
+	g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
+	g_return_if_fail (uiinfo != NULL);
+	g_return_if_fail (uibdata != NULL);
+
+	for (; uiinfo->type != GNOME_APP_UI_ENDOFINFO; uiinfo++)
+		switch (uiinfo->type) {
+		case GNOME_APP_UI_INCLUDE:
+		        gnome_app_fill_toolbar_custom (toolbar, uiinfo->moreinfo, uibdata, accel_group);
+		        break;
+
+		case GNOME_APP_UI_BUILDER_DATA:
+			/* Set the builder data for subsequent entries in the 
+			 * current uiinfo array */
+			uibdata = uiinfo->moreinfo;
+			break;
+
+		case GNOME_APP_UI_RADIOITEMS:
+			/* Create the radio item group */
+			create_radio_toolbar_items (toolbar, uiinfo->moreinfo, 
+					uibdata, accel_group);
+			break;
+
+		case GNOME_APP_UI_SEPARATOR:
+		case GNOME_APP_UI_ITEM:
+		case GNOME_APP_UI_TOGGLEITEM:
+			create_toolbar_item (toolbar, uiinfo, FALSE, NULL, 
+					uibdata, accel_group);
+			break;
+
+		default:
+			g_warning ("Invalid GnomeUIInfo element type %d\n", 
+					(int) uiinfo->type);
+		}
+
+	/* Make the end item contain a pointer to the parent toolbar */
+
+	uiinfo->widget = GTK_WIDGET (toolbar);
+
+        gnome_app_setup_toolbar(toolbar, NULL);
+}
+
+/**
+ * gnome_app_create_toolbar
+ * @app: Pointer to GNOME app object.
+ * @uiinfo:
+ *
+ * Description:
+ * Constructs a toolbar and attaches it to the specified application
+ * window.
+ **/
+
+void
+gnome_app_create_toolbar (GnomeApp *app, GnomeUIInfo *uiinfo)
+{
+	GnomeUIBuilderData uibdata;
+
+	g_return_if_fail (app != NULL);
+	g_return_if_fail (GNOME_IS_APP (app));
+	g_return_if_fail (uiinfo != NULL);
+
+	uibdata.connect_func = do_ui_signal_connect;
+	uibdata.data = NULL;
+	uibdata.is_interp = FALSE;
+	uibdata.relay_func = NULL;
+	uibdata.destroy_func = NULL;
+
+	gnome_app_create_toolbar_custom (app, uiinfo, &uibdata);
+}
+
+/**
+ * gnome_app_create_toolbar_interp
+ * @app: Pointer to GNOME app object.
+ * @uiinfo:
+ * @relay_func:
+ * @data:
+ * @destroy_func:
+ *
+ * Description:
+ * Constructs a toolbar and attaches it to the specified application
+ * window -- this version is intended for language bindings.
+ **/
+
+void
+gnome_app_create_toolbar_interp (GnomeApp *app, GnomeUIInfo *uiinfo,
+				 GtkCallbackMarshal relay_func, gpointer data,
+				 GtkDestroyNotify destroy_func)
+{
+	GnomeUIBuilderData uibdata;
+
+	g_return_if_fail (app != NULL);
+	g_return_if_fail (GNOME_IS_APP (app));
+	g_return_if_fail (uiinfo != NULL);
+
+	uibdata.connect_func = do_ui_signal_connect;
+	uibdata.data = data;
+	uibdata.is_interp = TRUE;
+	uibdata.relay_func = relay_func;
+	uibdata.destroy_func = destroy_func;
+
+	gnome_app_create_toolbar_custom (app, uiinfo, &uibdata);
+}
+
+/**
+ * gnome_app_create_toolbar_with_data
+ * @app: Pointer to GNOME app object.
+ * @uiinfo:
+ * @user_data:
+ *
+ * Description:
+ * Constructs a toolbar, sets all the user data pointers to
+ * @user_data, and attaches it to @app.
+ **/
+
+void
+gnome_app_create_toolbar_with_data (GnomeApp *app, GnomeUIInfo *uiinfo, 
+		gpointer user_data)
+{
+	GnomeUIBuilderData uibdata;
+
+	g_return_if_fail (app != NULL);
+	g_return_if_fail (GNOME_IS_APP (app));
+	g_return_if_fail (uiinfo != NULL);
+
+	uibdata.connect_func = do_ui_signal_connect;
+	uibdata.data = user_data;
+	uibdata.is_interp = FALSE;
+	uibdata.relay_func = NULL;
+	uibdata.destroy_func = NULL;
+
+	gnome_app_create_toolbar_custom (app, uiinfo, &uibdata);
+}
+
+/**
+ * gnome_app_create_toolbar_custom
+ * @app: Pointer to GNOME app object.
+ * @uiinfo:
+ * @uibdata:
+ *
+ * Description:
+ * Constructs a toolbar and attaches it to the @app window,
+ * using @uibdata builder data -- intended for language bindings.
+ **/
+
+void
+gnome_app_create_toolbar_custom (GnomeApp *app, GnomeUIInfo *uiinfo, GnomeUIBuilderData *uibdata)
+{
+	GtkWidget *toolbar;
+
+	g_return_if_fail (app != NULL);
+	g_return_if_fail (GNOME_IS_APP (app));
+	g_return_if_fail (uiinfo != NULL);
+	g_return_if_fail (uibdata != NULL);
+
+	toolbar = gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_BOTH);
+	gnome_app_fill_toolbar_custom(GTK_TOOLBAR (toolbar), uiinfo, uibdata, 
+			app->accel_group);
+	gnome_app_set_toolbar (app, GTK_TOOLBAR (toolbar));
+}
+
+/**
+ * g_strncmp_ignore_char
+ * @first: The first string to compare
+ * @second: The second string to compare
+ * @length: The length of the first string to consider (the length of
+ *          which string you're considering matters because this
+ *          includes copies of the ignored character) 
+ * @ignored: The character to ignore
+ *
+ * Description:
+ * Does a strcmp, only considering the first length characters of
+ * first, and ignoring the ignored character in both strings.
+ * Returns -1 if first comes before second in lexicographical order,
+ * Returns 0 if they're equivalent, and
+ * Returns 1 if the second comes before the first in lexicographical order.
+ **/
+
+static gint
+g_strncmp_ignore_char( const gchar *first, const gchar *second, gint length, gchar ignored )
+{
+        gint i, j;
+	for ( i = 0, j = 0; i < length; i++, j++ )
+	{
+                while ( first[i] == ignored && i < length ) i++;
+		while ( second[j] == ignored ) j++;
+		if ( i == length )
+		        return 0;
+		if ( first[i] < second[j] )
+		        return -1; 
+		if ( first[i] > second[j] )
+		        return 1;
+	}
+	return 0;
+}
+
+/* menu insertion/removal functions
+ * <jaka mocnik kiss uni-lj si>
+ *
+ * the path argument should be in the form "File/.../.../Something". "" will 
+ * insert the item as the first one in the menubar "File/" will insert it as 
+ * the first one in the File menu "File/Settings" will insert it after the 
+ * Setting item in the File menu use of "File/<Separator>" should be obvious. 
+ * However this stops after the first separator. I hope this explains use of 
+ * the insert/remove functions well enough.
+ */
+
+/**
+ * gnome_app_find_menu_pos
+ * @parent: Root menu shell widget containing menu items to be searched
+ * @path: Specifies the target menu item by menu path
+ * @pos: (output) returned item position
+ *
+ * Description:
+ * finds menu item described by path starting
+ * in the GtkMenuShell top and returns its parent GtkMenuShell and the
+ * position after this item in pos:  gtk_menu_shell_insert(p, w, pos)
+ * would then insert widget w in GtkMenuShell p right after the menu item
+ * described by path.
+ **/
+
+GtkWidget *
+gnome_app_find_menu_pos (GtkWidget *parent, const gchar *path, gint *pos)
+{
+	GtkBin *item;
+	gchar *label = NULL;
+	GList *children;
+	gchar *name_end;
+	gchar *part;
+	const gchar *transl;
+	gint p;
+	int  path_len;
+	int  stripped_path_len;
+	
+	g_return_val_if_fail (parent != NULL, NULL);
+	g_return_val_if_fail (path != NULL, NULL);
+	g_return_val_if_fail (pos != NULL, NULL);
+
+	children = GTK_MENU_SHELL (parent)->children;
+	
+	name_end = strchr(path, '/');
+	if(name_end == NULL)
+		path_len = strlen(path);
+	else
+		path_len = name_end - path;
+
+	if (path_len == 0) {
+
+	        if (children && GTK_IS_TEAROFF_MENU_ITEM(children->data))
+		        /* consider the position after the tear off item as the topmost one. */
+			*pos = 1;
+		else
+			*pos = 0;
+		return parent;
+	}
+
+	/* this ugly thing should fix the localization problems */
+	part = g_malloc(path_len + 1);
+	if(!part)
+	        return NULL;
+	strncpy(part, path, path_len);
+	part[path_len] = '\0';
+	transl = L_(part);
+	path_len = strlen(transl);
+
+	stripped_path_len = path_len;
+	for ( p = 0; p < path_len; p++ )
+	        if( transl[p] == '_' )
+		        stripped_path_len--;
+		
+	p = 0;
+
+	while (children){
+		item = GTK_BIN (children->data);
+		children = children->next;
+		label = NULL;
+		p++;
+		
+		if (GTK_IS_TEAROFF_MENU_ITEM(item))
+			label = NULL;
+		else if (!item->child)          /* this is a separator, right? */
+			label = "<Separator>";
+		else if (GTK_IS_LABEL (item->child))  /* a simple item with a label */
+			label = GTK_LABEL (item->child)->label;
+		else
+			label = NULL; /* something that we just can't handle */
+		if (label && (stripped_path_len == strlen (label)) &&
+		    (g_strncmp_ignore_char (transl, label, path_len, '_') == 0)){
+			if (name_end == NULL) {
+				*pos = p;
+				g_free(part);
+				return parent;
+			}
+			else if (GTK_MENU_ITEM (item)->submenu) {
+			        g_free(part);
+				return gnome_app_find_menu_pos
+					(GTK_MENU_ITEM (item)->submenu, 
+					 (gchar *)(name_end + 1), pos);
+			}
+			else {
+			        g_free(part);
+				return NULL;
+			}
+		}
+	}
+	
+	g_free(part);
+	return NULL;
+}
+
+
+/**
+ * gnome_app_remove_menus
+ * @app: Pointer to GNOME app object.
+ * @path:
+ * @items:
+ *
+ * Description: removes num items from the existing app's menu structure
+ * beginning with item described by path
+ **/
+
+void
+gnome_app_remove_menus(GnomeApp *app, const gchar *path, gint items)
+{
+	GtkWidget *parent, *child;
+	GList *children;
+	gint pos;
+	
+	g_return_if_fail (app != NULL);
+	g_return_if_fail (GNOME_IS_APP(app));
+	
+	/* find the first item (which is actually at position pos-1) to 
+	 * remove */
+	parent = gnome_app_find_menu_pos(app->menubar, path, &pos);
+	
+	/* in case of path ".../" remove the first item */
+  if(path[strlen(path) - 1] == '/')
+    pos++;
+	
+	if( parent == NULL ) {
+		g_warning("gnome_app_remove_menus: couldn't find first item to"
+			  " remove!");
+		return;
+	}
+	
+	/* remove items */
+	children = g_list_nth(GTK_MENU_SHELL(parent)->children, pos - 1);
+	while(children && items > 0) {
+		child = GTK_WIDGET(children->data);
+		children = children->next;
+    /* if this item contains a gtkaccellabel, we have to set its
+       accel_widget to NULL so that the item gets unrefed. */
+    if(GTK_IS_ACCEL_LABEL(GTK_BIN(child)->child))
+      gtk_accel_label_set_accel_widget(GTK_ACCEL_LABEL(GTK_BIN(child)->child), NULL);
+
+		gtk_container_remove(GTK_CONTAINER(parent), child);
+		items--;
+	}
+	
+	gtk_widget_queue_resize(parent);
+}
+
+
+/**
+ * gnome_app_remove_menu_range
+ * @app: Pointer to GNOME app object.
+ * @path:
+ * @start:
+ * @items:
+ *
+ * Description:
+ * Same as the gnome_app_remove_menus, except it removes the specified number
+ * of @items from the existing app's menu structure begining with item described
+ * by path, plus the number specified by @start - very useful for adding and
+ * removing Recent document items in the File menu.
+ **/
+
+void
+gnome_app_remove_menu_range (GnomeApp *app, const gchar *path, gint start, gint items)
+{
+	GtkWidget *parent, *child;
+	GList *children;
+	gint pos;
+	
+	g_return_if_fail (app != NULL);
+	g_return_if_fail (GNOME_IS_APP (app));
+
+	/* find the first item (which is actually at position pos-1) to remove */
+	parent = gnome_app_find_menu_pos (app->menubar, path, &pos);
+
+	/* in case of path ".../" remove the first item */
+	if (path [strlen (path) - 1] == '/')
+		pos++;
+
+	pos += start;
+  
+	if (parent == NULL){
+		g_warning("gnome_app_remove_menus: couldn't find first item to remove!");
+		return;
+	}
+
+	/* remove items */
+	children = g_list_nth (GTK_MENU_SHELL (parent)->children, pos - 1);
+	while (children && items > 0) {
+		child = GTK_WIDGET (children->data);
+		children = children->next;
+		/*
+		 * if this item contains a gtkaccellabel, we have to set its
+		 * accel_widget to NULL so that the item gets unrefed.
+		 */
+		if (GTK_IS_ACCEL_LABEL (GTK_BIN (child)->child))
+			gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (GTK_BIN (child)->child), NULL);
+		gtk_container_remove (GTK_CONTAINER (parent), child);
+		items--;
+	}
+
+	gtk_widget_queue_resize(parent);
+}
+
+/**
+ * gnome_app_insert_menus_custom
+ * @app: Pointer to GNOME app object.
+ * @path:
+ * @uiinfo:
+ * @uibdata:
+ *
+ * Description: inserts menus described by @uiinfo in existing app's menu
+ * structure right after the item described by @path.
+ **/
+
+void
+gnome_app_insert_menus_custom (GnomeApp *app, const gchar *path, 
+		GnomeUIInfo *uiinfo, GnomeUIBuilderData *uibdata)
+{
+	GtkWidget *parent;
+	gint pos;
+	
+	g_return_if_fail (app != NULL);
+	g_return_if_fail (GNOME_IS_APP(app));
+	g_return_if_fail (app->menubar != NULL);
+	
+	/* find the parent menushell and position for insertion of menus */
+	parent = gnome_app_find_menu_pos(app->menubar, path, &pos);
+	if(parent == NULL) {
+		g_warning("gnome_app_insert_menus_custom: couldn't find "
+			  "insertion point for menus!");
+		return;
+	}
+	
+	/* create menus and insert them */
+	gnome_app_fill_menu_custom (GTK_MENU_SHELL (parent), uiinfo, uibdata, 
+			app->accel_group, TRUE, pos);
+}
+
+
+/**
+ * gnome_app_insert_menus
+ * @app: Pointer to GNOME app object.
+ * @path:
+ * @menuinfo:
+ *
+ * Description:
+ **/
+
+void
+gnome_app_insert_menus (GnomeApp *app,
+			const gchar *path,
+			GnomeUIInfo *menuinfo)
+{
+	GnomeUIBuilderData uidata =
+	{
+		do_ui_signal_connect,
+		NULL, FALSE, NULL, NULL
+	};
+	
+	gnome_app_insert_menus_custom (app, path, menuinfo, &uidata);
+}
+
+
+/**
+ * gnome_app_insert_menus_with_data
+ * @app: Pointer to GNOME app object.
+ * @path:
+ * @menuinfo:
+ * @data:
+ *
+ * Description:
+ **/
+
+void
+gnome_app_insert_menus_with_data (GnomeApp *app, const gchar *path, 
+		GnomeUIInfo *menuinfo, gpointer data)
+{
+	GnomeUIBuilderData uidata =
+	{
+		do_ui_signal_connect,
+		NULL, FALSE, NULL, NULL
+	};
+	
+	uidata.data = data;
+	
+	gnome_app_insert_menus_custom (app, path, menuinfo, &uidata);
+}
+
+
+/**
+ * gnome_app_insert_menus_interp
+ * @app: Pointer to GNOME app object.
+ * @path:
+ * @menuinfo:
+ * @relay_func:
+ * @data:
+ * @destroy_func:
+ *
+ * Description:
+ **/
+
+void
+gnome_app_insert_menus_interp (GnomeApp *app, const gchar *path, 
+		GnomeUIInfo *menuinfo, GtkCallbackMarshal relay_func, 
+		gpointer data, GtkDestroyNotify destroy_func)
+{
+	GnomeUIBuilderData uidata =
+	{
+		do_ui_signal_connect,
+		NULL, FALSE, NULL, NULL
+	};
+	
+	uidata.data = data;
+	uidata.is_interp = TRUE;
+	uidata.relay_func = relay_func;
+	uidata.destroy_func = destroy_func;
+	
+	gnome_app_insert_menus_custom(app, path, menuinfo, &uidata);
+}
+
+#ifdef ENABLE_NLS
+const gchar *
+gnome_app_helper_gettext (const gchar *str)
+{
+	char *s;
+
+        s = gettext (str);
+	if ( s == str )
+	        s = dgettext (PACKAGE, str);
+
+	return s;
+}
+#endif
+
+static void
+set_bevels(GnomeDockItem *dock_item, gboolean bevels)
+{
+        if (bevels) {
+                gtk_container_set_border_width (GTK_CONTAINER (dock_item), 1);
+                gnome_dock_item_set_shadow_type (GNOME_DOCK_ITEM (dock_item),
+                                                 GTK_SHADOW_OUT);
+        } else {
+                gtk_container_set_border_width (GTK_CONTAINER (dock_item), 0);
+                gnome_dock_item_set_shadow_type (GNOME_DOCK_ITEM (dock_item),
+                                                 GTK_SHADOW_NONE);
+        }
+}
+
+static void
+dockitem_bevels_changed_notify(GConfClient            *client,
+                               guint                   cnxn_id,
+			       GConfEntry             *entry,
+                               gpointer                user_data)
+{
+        gboolean bevels = TRUE;
+        GtkWidget *w = user_data;
+        GnomeDockItem *dock_item = GNOME_DOCK_ITEM(w);
+	GConfValue *value = gconf_entry_get_value (entry);
+
+        if (value &&
+            value->type == GCONF_VALUE_BOOL) {
+                bevels = gconf_value_get_bool(value);
+        }
+
+        set_bevels(dock_item, bevels);
+}
+
+static void
+set_separators(GtkToolbar *toolbar, gboolean separators)
+{
+        if (separators) {
+                gtk_toolbar_set_space_style (toolbar, GTK_TOOLBAR_SPACE_LINE);
+                gtk_toolbar_set_space_size (toolbar, GNOME_PAD_SMALL * 2);
+        } else {
+                gtk_toolbar_set_space_style (toolbar, GTK_TOOLBAR_SPACE_EMPTY);
+                gtk_toolbar_set_space_size (toolbar, GNOME_PAD_SMALL);
+        }
+}
+
+static void
+toolbar_separators_changed_notify(GConfClient            *client,
+                                  guint                   cnxn_id,
+				  GConfEntry             *entry,
+                                  gpointer                user_data)
+{
+        gboolean separators = TRUE;
+        GtkWidget *w = user_data;
+        GtkToolbar *toolbar = GTK_TOOLBAR(w);
+	GConfValue *value = gconf_entry_get_value (entry);
+
+        if (value &&
+            value->type == GCONF_VALUE_BOOL) {
+                separators = gconf_value_get_bool(value);
+        }
+
+        set_separators(toolbar, separators);
+}
+
+static GConfEnumStringPair toolbar_reliefs[] = {
+        { GTK_RELIEF_NORMAL, "normal" },
+        { GTK_RELIEF_NONE, "none" },
+        { GTK_RELIEF_HALF, "half" }
+};
+
+static void
+toolbar_relief_changed_notify(GConfClient            *client,
+                              guint                   cnxn_id,
+			      GConfEntry             *entry,
+                              gpointer                user_data)
+{
+        GtkReliefStyle style = GTK_RELIEF_NONE;
+        GtkWidget *w = user_data;
+        GtkToolbar *toolbar = GTK_TOOLBAR(w);
+	GConfValue *value = gconf_entry_get_value (entry);
+
+        if (value &&
+            value->type == GCONF_VALUE_STRING &&
+            gconf_value_get_string(value) != NULL) {
+                gconf_string_to_enum(toolbar_reliefs,
+                                     gconf_value_get_string(value),
+                                     (gint*)&style);
+        }
+
+        gtk_toolbar_set_button_relief(toolbar, style);
+}
+
+static GConfEnumStringPair toolbar_styles[] = {
+        { GTK_TOOLBAR_TEXT, "text" },
+        { GTK_TOOLBAR_ICONS, "icons" },
+        { GTK_TOOLBAR_BOTH, "both" }
+};
+
+static void
+per_app_toolbar_style_changed_notify(GConfClient            *client,
+                                     guint                   cnxn_id,
+				     GConfEntry             *entry,
+                                     gpointer                user_data)
+{
+        GtkToolbarStyle style = GTK_TOOLBAR_BOTH;
+        GtkWidget *w = user_data;
+        GtkToolbar *toolbar = GTK_TOOLBAR(w);
+        gboolean got_it = FALSE;
+	GConfValue *value = gconf_entry_get_value (entry);
+
+        if (value &&
+            value->type == GCONF_VALUE_STRING &&
+            gconf_value_get_string(value) != NULL) {
+
+                if (gconf_string_to_enum(toolbar_styles,
+                                         gconf_value_get_string(value),
+                                         (gint*)&style)) {
+                        got_it = TRUE;
+                }
+        }
+
+        /* Fall back to global setting */
+        if (!got_it) {
+                gchar *str;
+
+                str = gconf_client_get_string(client,
+                                              "/desktop/gnome/toolbars/style",
+                                              NULL);
+
+                if (str) {
+                        gconf_string_to_enum(toolbar_styles,
+                                             str,
+                                             (gint*)&style);
+                        
+                        g_free(str);
+                }
+        }
+        
+        gtk_toolbar_set_style(toolbar, style);
+}
+
+/* FIXME FIXME FIXME */
+#define gnome_gconf_get_gnome_libs_settings_relative(p) NULL
+
+static void
+toolbar_style_changed_notify(GConfClient            *client,
+                             guint                   cnxn_id,
+			     GConfEntry             *entry,
+                             gpointer                user_data)
+{
+        GtkToolbarStyle style = GTK_TOOLBAR_BOTH;
+        GtkWidget *w = user_data;
+        GtkToolbar *toolbar = GTK_TOOLBAR(w);
+        gchar *per_app_key;
+        gchar *str;
+        gboolean got_it = FALSE;
+	GConfValue *value;
+
+        /* Check for app-specific override */
+        per_app_key = gnome_gconf_get_gnome_libs_settings_relative("toolbar-style");
+        str = gconf_client_get_string(client, per_app_key, NULL);
+        g_free(per_app_key);
+
+        if (str) {
+                if (gconf_string_to_enum(toolbar_styles,
+                                         str,
+                                         (gint*)&style)) {
+                        got_it = TRUE;
+                }
+                g_free(str);
+        }
+
+	value = gconf_entry_get_value (entry);
+
+        /* If no per-app setting use this new global setting */
+        if (!got_it &&
+            value &&
+            value->type == GCONF_VALUE_STRING &&
+            gconf_value_get_string(value) != NULL) {
+                gconf_string_to_enum(toolbar_styles,
+                                     gconf_value_get_string(value),
+                                     (gint*)&style);
+        }
+
+        gtk_toolbar_set_style(toolbar, style);
+}
+
+/**
+ * gnome_app_setup_toolbar
+ * @toolbar: Pointer to #GtkToolbar widget
+ * @dock_item: Pointer to a #GnomeDockItem the toolbar is inside, or NULL for none
+ *
+ * Description:
+ * Sets up a toolbar to use GNOME user preferences
+ **/
+
+void
+gnome_app_setup_toolbar (GtkToolbar *toolbar,
+                         GnomeDockItem *dock_item)
+{
+        GConfClient *conf;
+
+        conf = gconf_client_get_default();
+
+        g_object_ref (G_OBJECT (conf));
+        gtk_object_set_data_full(GTK_OBJECT(toolbar), gnome_app_helper_gconf_client,
+                                 conf, (GtkDestroyNotify)g_object_unref);
+        
+        /* Attach GConf settings */
+
+        if (dock_item != NULL) { /* Dock item bevel */
+                gboolean bevels = TRUE;
+                guint notify_id;
+
+		g_object_ref (G_OBJECT (conf));
+		gtk_object_set_data_full(GTK_OBJECT(dock_item), gnome_app_helper_gconf_client,
+					 conf, (GtkDestroyNotify)g_object_unref);
+                
+                bevels = gconf_client_get_bool(conf,
+                                               "/desktop/gnome/toolbars/bevels",
+                                               NULL);
+                
+                notify_id = gconf_client_notify_add(conf,
+                                                    "/desktop/gnome/toolbars/bevels",
+                                                    dockitem_bevels_changed_notify,
+                                                    dock_item, NULL, NULL);
+                
+                gtk_signal_connect(GTK_OBJECT(dock_item), "destroy",
+                                   GTK_SIGNAL_FUNC(remove_notify_cb),
+				   GINT_TO_POINTER(notify_id));
+
+                set_bevels(dock_item, bevels);
+        }
+        
+        { /* Toolbar line separators */
+                gboolean separators = TRUE;
+                guint notify_id;
+                
+                separators = gconf_client_get_bool(conf,
+                                                   "/desktop/gnome/toolbars/separators",
+                                                   NULL);
+                
+                notify_id = gconf_client_notify_add(conf,
+                                                    "/desktop/gnome/toolbars/separators",
+                                                    toolbar_separators_changed_notify,
+                                                    toolbar, NULL, NULL);
+
+                gtk_signal_connect(GTK_OBJECT(toolbar), "destroy",
+                                   GTK_SIGNAL_FUNC(remove_notify_cb),
+				   GINT_TO_POINTER(notify_id));
+
+                set_separators(toolbar, separators);
+        }
+        
+        { /* Toolbar button relief */
+                GtkReliefStyle relief_style = GTK_RELIEF_NONE;
+                guint notify_id;
+                gchar *str;
+                
+                str = gconf_client_get_string(conf,
+                                              "/desktop/gnome/toolbars/relief",
+                                              NULL);
+
+                if (str != NULL) {
+                        gconf_string_to_enum(toolbar_reliefs,
+                                             str,
+                                             (gint*)&relief_style);
+                        g_free(str);
+                }
+                
+                notify_id = gconf_client_notify_add(conf,
+                                                    "/desktop/gnome/toolbars/relief",
+                                                    toolbar_relief_changed_notify,
+                                                    toolbar, NULL, NULL);
+
+                gtk_signal_connect(GTK_OBJECT(toolbar), "destroy",
+                                   GTK_SIGNAL_FUNC(remove_notify_cb),
+				   GINT_TO_POINTER(notify_id));
+
+                gtk_toolbar_set_button_relief (toolbar, relief_style);
+        }
+        
+        { /* Toolbar Style */
+                /* This one is a lot more complex because
+                   we have a per-app setting that overrides
+                   the default global setting */
+                
+                GtkToolbarStyle toolbar_style = GTK_TOOLBAR_BOTH;
+                guint notify_id;
+                gchar *str;
+                gchar *per_app_key;
+                gboolean got_it = FALSE;
+
+                /* Try per-app key */
+                per_app_key = gnome_gconf_get_gnome_libs_settings_relative("toolbar-style");
+
+                str = gconf_client_get_string(conf,
+                                              per_app_key,
+                                              NULL);
+                
+                if (str &&
+                    gconf_string_to_enum(toolbar_styles,
+                                         str,
+                                         (gint*)&toolbar_style)) {
+                        got_it = TRUE;
+                }
+
+                g_free(str);
+
+                /* Try global default */
+                if (!got_it) {
+                        str = gconf_client_get_string(conf,
+                                                      "/desktop/gnome/toolbars/style",
+                                                      NULL);
+
+                        if (str != NULL) {
+                                gconf_string_to_enum(toolbar_styles,
+                                                     str,
+                                                     (gint*)&toolbar_style);
+                                g_free(str);
+                        }
+                }
+                
+                notify_id = gconf_client_notify_add(conf,
+                                                    "/desktop/gnome/toolbars/style",
+                                                    toolbar_style_changed_notify,
+                                                    toolbar, NULL, NULL);
+
+                gtk_signal_connect(GTK_OBJECT(toolbar), "destroy",
+                                   GTK_SIGNAL_FUNC(remove_notify_cb),
+				   GINT_TO_POINTER(notify_id));
+
+                notify_id = gconf_client_notify_add(conf,
+                                                    per_app_key,
+                                                    per_app_toolbar_style_changed_notify,
+                                                    toolbar, NULL, NULL);
+
+                gtk_signal_connect(GTK_OBJECT(toolbar), "destroy",
+                                   GTK_SIGNAL_FUNC(remove_notify_cb),
+				   GINT_TO_POINTER(notify_id));
+                
+                g_free(per_app_key);
+                
+                gtk_toolbar_set_style (toolbar, toolbar_style);
+        }
+}
+
diff --git a/libgnomeui/gnome-app-helper.h b/libgnomeui/gnome-app-helper.h
new file mode 100644
index 0000000..227ad9a
--- /dev/null
+++ b/libgnomeui/gnome-app-helper.h
@@ -0,0 +1,742 @@
+/*
+ * Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
+ * Copyright (C) 1998, 1999 Miguel de Icaza, Federico Mena, Chris Toshok.
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+/*
+ * Originally by Elliot Lee, with hacking by Chris Toshok for *_data,
+ * Marc Ewing added menu support, toggle and radio support, and I
+ * don't know what you other people did :) menu insertion/removal
+ * functions by Jaka Mocnik.  Standard menu items by George Lebl and
+ * Nat Friedman.
+ *
+ * Some subtree hackage (and possibly various justification hacks) by Justin 
+ * Maurer.
+ *
+ * Major cleanups and rearrangements by Federico Mena and Justin Maurer.  */
+
+#ifndef GNOME_APP_HELPER_H
+#define GNOME_APP_HELPER_H
+
+#include <gtk/gtkstatusbar.h>
+
+#include <libgnomeui/gnome-appbar.h>
+#include <libgnomeui/gnome-app.h>
+
+G_BEGIN_DECLS
+
+/* This module lets you easily create menus and toolbars for your 
+ * applications. You basically define a hierarchy of arrays of GnomeUIInfo 
+ * structures, and you later call the provided functions to create menu bars 
+ * or tool bars.
+ */
+
+/* These values identify the item type that a particular GnomeUIInfo structure 
+ * specifies */
+typedef enum {
+	GNOME_APP_UI_ENDOFINFO,		/* No more items, use it at the end of 
+					   an array */
+	GNOME_APP_UI_ITEM,		/* Normal item, or radio item if it is 
+					   inside a radioitems group */
+	GNOME_APP_UI_TOGGLEITEM,	/* Toggle (check box) item */
+	GNOME_APP_UI_RADIOITEMS,	/* Radio item group */
+	GNOME_APP_UI_SUBTREE,		/* Item that defines a 
+					   subtree/submenu */
+	GNOME_APP_UI_SEPARATOR,		/* Separator line (menus) or blank 
+					   space (toolbars) */
+	GNOME_APP_UI_HELP,		/* Create a list of help topics, 
+					   used in the Help menu */
+	GNOME_APP_UI_BUILDER_DATA,	/* Specifies the builder data for the 
+					   following entries, see code for 
+					   further info */
+	GNOME_APP_UI_ITEM_CONFIGURABLE, /* A configurable menu item. */
+	/* one should be careful when using 
+	 * gnome_app_create_*_[custom|interp|with_data]() functions with 
+	 * GnomeUIInfo arrays containing GNOME_APP_UI_BUILDER_DATA items since 
+	 * their GnomeUIBuilderData structures completely override the ones 
+	 * generated or supplied by the above functions. */
+	GNOME_APP_UI_SUBTREE_STOCK,	/* Item that defines a 
+					   subtree/submenu, same as GNOME_APP_UI_SUBTREE,
+					   but the texts should be looked up in the
+					   gnome-libs catalog
+					*/
+	GNOME_APP_UI_INCLUDE            /* almost like SUBTREE, but inserts items into the current menu/whatever. instead of
+					   making a submenu */
+} GnomeUIInfoType;
+
+/* If you insert a value into this enum it'll break configurations all
+   over the place.  Only append.  You should also append a matching
+   item in the default types near the top of gnome-app-helper.c */
+typedef enum {
+        /* 0 */
+        GNOME_APP_CONFIGURABLE_ITEM_NEW,
+        GNOME_APP_CONFIGURABLE_ITEM_OPEN,
+        GNOME_APP_CONFIGURABLE_ITEM_SAVE,
+        GNOME_APP_CONFIGURABLE_ITEM_SAVE_AS,
+        GNOME_APP_CONFIGURABLE_ITEM_REVERT,
+        GNOME_APP_CONFIGURABLE_ITEM_PRINT,
+        GNOME_APP_CONFIGURABLE_ITEM_PRINT_SETUP,
+        GNOME_APP_CONFIGURABLE_ITEM_CLOSE,
+        GNOME_APP_CONFIGURABLE_ITEM_EXIT,
+        GNOME_APP_CONFIGURABLE_ITEM_CUT,
+	/* 10 */
+        GNOME_APP_CONFIGURABLE_ITEM_COPY,
+        GNOME_APP_CONFIGURABLE_ITEM_PASTE,
+        GNOME_APP_CONFIGURABLE_ITEM_CLEAR,
+        GNOME_APP_CONFIGURABLE_ITEM_UNDO,
+        GNOME_APP_CONFIGURABLE_ITEM_REDO,
+        GNOME_APP_CONFIGURABLE_ITEM_FIND,
+        GNOME_APP_CONFIGURABLE_ITEM_FIND_AGAIN,
+        GNOME_APP_CONFIGURABLE_ITEM_REPLACE,
+        GNOME_APP_CONFIGURABLE_ITEM_PROPERTIES,
+        GNOME_APP_CONFIGURABLE_ITEM_PREFERENCES,
+	/* 20 */
+        GNOME_APP_CONFIGURABLE_ITEM_ABOUT,
+	GNOME_APP_CONFIGURABLE_ITEM_SELECT_ALL,
+	GNOME_APP_CONFIGURABLE_ITEM_NEW_WINDOW,
+	GNOME_APP_CONFIGURABLE_ITEM_CLOSE_WINDOW,
+	GNOME_APP_CONFIGURABLE_ITEM_NEW_GAME,
+	GNOME_APP_CONFIGURABLE_ITEM_PAUSE_GAME,
+	GNOME_APP_CONFIGURABLE_ITEM_RESTART_GAME,
+	GNOME_APP_CONFIGURABLE_ITEM_UNDO_MOVE,
+	GNOME_APP_CONFIGURABLE_ITEM_REDO_MOVE,
+	GNOME_APP_CONFIGURABLE_ITEM_HINT,
+	/* 30 */
+	GNOME_APP_CONFIGURABLE_ITEM_SCORES,
+	GNOME_APP_CONFIGURABLE_ITEM_END_GAME
+} GnomeUIInfoConfigurableTypes;
+
+
+/* These values identify the type of pixmap used in an item */
+typedef enum {
+	GNOME_APP_PIXMAP_NONE,		/* No pixmap specified */
+	GNOME_APP_PIXMAP_STOCK,		/* Use a stock pixmap (GnomeStock) */
+	GNOME_APP_PIXMAP_DATA,		/* Use a pixmap from inline xpm data */
+	GNOME_APP_PIXMAP_FILENAME	/* Use a pixmap from the specified 
+					   filename */
+} GnomeUIPixmapType;
+
+/* This is the structure that defines an item in a menu bar or toolbar.  The 
+ * idea is to create an array of such structures with the information needed 
+ * to create menus or toolbars.  The most convenient way to create such a 
+ * structure is to use the GNOMEUIINFO_* macros provided below. */
+typedef struct {
+	GnomeUIInfoType type;		/* Type of item */
+	gchar *label;			/* String to use in the label */
+	gchar *hint;			/* For toolbar items, the tooltip. For 
+					   menu items, the status bar message */
+	gpointer moreinfo;		/* For an item, toggleitem, or 
+					   radioitem, this is a pointer to the 
+					   function to call when the item is 
+					   activated. For a subtree, a pointer 
+					   to another array of GnomeUIInfo 
+					   structures. For a radioitem lead 
+					   entry, a pointer to an array of 
+					   GnomeUIInfo structures for the radio 
+					   item group. For a help item, 
+					   specifies the help node to load 
+					   (i.e. the application's identifier) 
+					   or NULL for the main program's name.
+					   For builder data, points to the 
+					   GnomeUIBuilderData structure for 
+					   the following items */
+	gpointer user_data;		/* Data pointer to pass to callbacks */
+	gpointer unused_data;		/* Reserved for future expansion, 
+					   should be NULL */
+	GnomeUIPixmapType pixmap_type;	/* Type of pixmap for the item */
+	gconstpointer pixmap_info;      /* Pointer to the pixmap information:
+					 *
+					 * For GNOME_APP_PIXMAP_STOCK, a 
+					 * pointer to the stock icon name.
+					 *
+					 * For GNOME_APP_PIXMAP_DATA, a 
+					 * pointer to the inline xpm data.
+					 *
+					 * For GNOME_APP_PIXMAP_FILENAME, a 
+					 * pointer to the filename string.
+					 */
+	guint accelerator_key;		/* Accelerator key, or 0 for none */
+	GdkModifierType ac_mods;	/* Mask of modifier keys for the 
+					   accelerator */
+
+	GtkWidget *widget;		/* Filled in by gnome_app_create*, you 
+					   can use this to tweak the widgets 
+					   once they have been created */
+} GnomeUIInfo;
+
+/* Callback data */
+
+#define GNOMEUIINFO_KEY_UIDATA		"uidata"
+#define GNOMEUIINFO_KEY_UIBDATA		"uibdata"
+
+/* Handy GnomeUIInfo macros */
+
+/* Used to terminate an array of GnomeUIInfo structures */
+#define GNOMEUIINFO_END			{ GNOME_APP_UI_ENDOFINFO, NULL, NULL, NULL, NULL, NULL,		\
+					  (GnomeUIPixmapType) 0, NULL, 0, (GdkModifierType) 0, NULL }
+
+/* Insert a separator line (on a menu) or a blank space (on a toolbar) */
+#define GNOMEUIINFO_SEPARATOR		{ GNOME_APP_UI_SEPARATOR, NULL, NULL, NULL, NULL, NULL,		\
+					  (GnomeUIPixmapType) 0, NULL, 0, (GdkModifierType) 0, NULL }
+
+/* Insert an item with an inline xpm icon */
+#define GNOMEUIINFO_ITEM(label, tooltip, callback, xpm_data) \
+	{ GNOME_APP_UI_ITEM, label, tooltip, (gpointer)callback, NULL, NULL, \
+		GNOME_APP_PIXMAP_DATA, xpm_data, 0, (GdkModifierType) 0, NULL}
+
+/* Insert an item with a stock icon */
+#define GNOMEUIINFO_ITEM_STOCK(label, tooltip, callback, stock_id) \
+	{ GNOME_APP_UI_ITEM, label, tooltip, (gpointer)callback, NULL, NULL, \
+		GNOME_APP_PIXMAP_STOCK, stock_id, 0, (GdkModifierType) 0, NULL }
+
+/* Insert an item with no icon */
+#define GNOMEUIINFO_ITEM_NONE(label, tooltip, callback) \
+	{ GNOME_APP_UI_ITEM, label, tooltip, (gpointer)callback, NULL, NULL, \
+		GNOME_APP_PIXMAP_NONE, NULL, 0, (GdkModifierType) 0, NULL }
+
+/* Insert an item with an inline xpm icon and a user data pointer */
+#define GNOMEUIINFO_ITEM_DATA(label, tooltip, callback, user_data, xpm_data) \
+	{ GNOME_APP_UI_ITEM, label, tooltip, (gpointer)callback, user_data, NULL, \
+		GNOME_APP_PIXMAP_DATA, xpm_data, 0, (GdkModifierType) 0, NULL }
+
+/* Insert a toggle item (check box) with an inline xpm icon */
+#define GNOMEUIINFO_TOGGLEITEM(label, tooltip, callback, xpm_data) \
+	{ GNOME_APP_UI_TOGGLEITEM, label, tooltip, (gpointer)callback, NULL, NULL, \
+		GNOME_APP_PIXMAP_DATA, xpm_data, 0, (GdkModifierType) 0, NULL }
+
+/* Insert a toggle item (check box) with an inline xpm icon and a user data pointer */
+#define GNOMEUIINFO_TOGGLEITEM_DATA(label, tooltip, callback, user_data, xpm_data)		\
+					{ GNOME_APP_UI_TOGGLEITEM, label, tooltip, (gpointer)callback,	\
+					  user_data, NULL, GNOME_APP_PIXMAP_DATA, xpm_data,	\
+					  0, (GdkModifierType) 0, NULL }
+
+/* Insert all the help topics based on the application's id */
+#define GNOMEUIINFO_HELP(app_name) \
+	{ GNOME_APP_UI_HELP, NULL, NULL, app_name, NULL, NULL, \
+		(GnomeUIPixmapType) 0, NULL, 0,	(GdkModifierType) 0, NULL }
+
+/* Insert a subtree (submenu) */
+#define GNOMEUIINFO_SUBTREE(label, tree) \
+	{ GNOME_APP_UI_SUBTREE, label, NULL, tree, NULL, NULL, \
+		(GnomeUIPixmapType) 0, NULL, 0,	(GdkModifierType) 0, NULL }
+
+/* Insert a subtree with a hint */
+#define GNOMEUIINFO_SUBTREE_HINT(label, hint, tree) \
+	{ GNOME_APP_UI_SUBTREE, label, hint, tree, NULL, NULL, \
+		(GnomeUIPixmapType) 0, NULL, 0,	(GdkModifierType) 0, NULL }
+
+/* Insert a subtree (submenu) with a stock icon */
+#define GNOMEUIINFO_SUBTREE_STOCK(label, tree, stock_id) \
+	{ GNOME_APP_UI_SUBTREE, label, NULL, tree, NULL, NULL, \
+		GNOME_APP_PIXMAP_STOCK, stock_id, 0, (GdkModifierType) 0, NULL }
+
+#define GNOMEUIINFO_INCLUDE(tree) \
+	{ GNOME_APP_UI_INCLUDE, NULL, NULL, tree, NULL, NULL, \
+		(GnomeUIPixmapType) 0, NULL, 0,	(GdkModifierType) 0, NULL }
+
+/* Insert a list of radio items */
+#define GNOMEUIINFO_RADIOLIST(list) \
+	{ GNOME_APP_UI_RADIOITEMS, NULL, NULL, list, NULL, NULL, \
+		(GnomeUIPixmapType) 0, NULL, 0,	(GdkModifierType) 0, NULL }
+
+/* Insert a radio item with an inline xpm icon */
+#define GNOMEUIINFO_RADIOITEM(label, tooltip, callback, xpm_data) \
+	{ GNOME_APP_UI_ITEM, label, tooltip, (gpointer)callback, NULL, NULL, \
+		GNOME_APP_PIXMAP_DATA, xpm_data, 0, (GdkModifierType) 0, NULL }
+
+/* Insert a radio item with an inline xpm icon and a user data pointer */
+#define GNOMEUIINFO_RADIOITEM_DATA(label, tooltip, callback, user_data, xpm_data)		\
+					{ GNOME_APP_UI_ITEM, label, tooltip, (gpointer)callback,	\
+					  user_data, NULL, GNOME_APP_PIXMAP_DATA, xpm_data,	\
+					  0, (GdkModifierType) 0, NULL }
+					  
+/*
+ * Stock menu item macros for some common menu items.  Please see
+ * gnome-libs/devel-docs/suggestions.txt about GNOME menu standards.
+ */
+
+/*
+ * The 'File' menu
+ */
+
+/*
+ * Note: New item requires to to specify what is new, so you need
+ * to specify the document type, so you need to supply the label
+ * as well (it should start with "_New ")
+ */
+#define GNOMEUIINFO_MENU_NEW_ITEM(label, tip, cb, data)                     \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, label, tip,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_NEW, (GdkModifierType) 0, NULL }
+
+/* If you have more then one New type, use this tree */
+#define GNOMEUIINFO_MENU_NEW_SUBTREE(tree)                                  \
+        { GNOME_APP_UI_SUBTREE_STOCK, N_("_New"), NULL, tree, NULL, NULL,   \
+          GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_NEW,                     \
+          GNOME_KEY_NAME_NEW, GNOME_KEY_MOD_NEW, NULL }
+
+#define GNOMEUIINFO_MENU_OPEN_ITEM(cb, data)                                \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_OPEN, (GdkModifierType) 0, NULL }
+
+#define GNOMEUIINFO_MENU_SAVE_ITEM(cb, data)                                \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_SAVE, (GdkModifierType) 0, NULL }
+
+#define GNOMEUIINFO_MENU_SAVE_AS_ITEM(cb, data)                             \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_SAVE_AS, (GdkModifierType) 0, NULL }
+
+#define GNOMEUIINFO_MENU_REVERT_ITEM(cb, data)                              \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_REVERT, (GdkModifierType) 0, NULL }
+
+#define GNOMEUIINFO_MENU_PRINT_ITEM(cb, data)                               \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_PRINT, (GdkModifierType) 0, NULL }
+
+#define GNOMEUIINFO_MENU_PRINT_SETUP_ITEM(cb, data)                         \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_PRINT_SETUP, (GdkModifierType) 0, NULL }
+
+#define GNOMEUIINFO_MENU_CLOSE_ITEM(cb, data)                               \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_CLOSE, (GdkModifierType) 0, NULL }
+
+#define GNOMEUIINFO_MENU_EXIT_ITEM(cb, data)                                \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_EXIT, (GdkModifierType) 0, NULL }
+/*
+ * The "Edit" menu
+ */
+
+#define GNOMEUIINFO_MENU_CUT_ITEM(cb, data)                                 \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_CUT, (GdkModifierType) 0, NULL }
+
+#define GNOMEUIINFO_MENU_COPY_ITEM(cb, data)                                \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_COPY, (GdkModifierType) 0, NULL }
+
+#define GNOMEUIINFO_MENU_PASTE_ITEM(cb, data)                               \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_PASTE, (GdkModifierType) 0, NULL }
+
+#define GNOMEUIINFO_MENU_SELECT_ALL_ITEM(cb, data)                          \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_SELECT_ALL, (GdkModifierType) 0, NULL }
+
+#define GNOMEUIINFO_MENU_CLEAR_ITEM(cb, data)                               \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_CLEAR, (GdkModifierType) 0, NULL }
+
+#define GNOMEUIINFO_MENU_UNDO_ITEM(cb, data)                                \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_UNDO, (GdkModifierType) 0, NULL }
+
+#define GNOMEUIINFO_MENU_REDO_ITEM(cb, data)                                \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_REDO, (GdkModifierType) 0, NULL }
+
+#define GNOMEUIINFO_MENU_FIND_ITEM(cb, data)                                \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_FIND, (GdkModifierType) 0, NULL }
+
+#define GNOMEUIINFO_MENU_FIND_AGAIN_ITEM(cb, data)                          \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_FIND_AGAIN, (GdkModifierType) 0, NULL }
+
+#define GNOMEUIINFO_MENU_REPLACE_ITEM(cb, data)                             \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_REPLACE, (GdkModifierType) 0, NULL }
+
+#define GNOMEUIINFO_MENU_PROPERTIES_ITEM(cb, data)                          \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_PROPERTIES, (GdkModifierType) 0, NULL }
+
+/*
+ * The Settings menu
+ */
+#define GNOMEUIINFO_MENU_PREFERENCES_ITEM(cb, data)                         \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_PREFERENCES, (GdkModifierType) 0, NULL }
+
+/*
+ * The Windows menu
+ */
+#define GNOMEUIINFO_MENU_NEW_WINDOW_ITEM(cb, data)                          \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_NEW_WINDOW, (GdkModifierType) 0, NULL }
+
+#define GNOMEUIINFO_MENU_CLOSE_WINDOW_ITEM(cb, data)                        \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_CLOSE_WINDOW, (GdkModifierType) 0, NULL }
+
+/*
+ * And the "Help" menu
+ */
+#define GNOMEUIINFO_MENU_ABOUT_ITEM(cb, data)                               \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_ABOUT, (GdkModifierType) 0, NULL }
+
+/* 
+ * The "Game" menu
+ */
+
+#define GNOMEUIINFO_MENU_NEW_GAME_ITEM(cb, data)                            \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_NEW_GAME, (GdkModifierType) 0, NULL }
+	  
+#define GNOMEUIINFO_MENU_PAUSE_GAME_ITEM(cb, data)                          \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_PAUSE_GAME, (GdkModifierType) 0, NULL }
+	  
+#define GNOMEUIINFO_MENU_RESTART_GAME_ITEM(cb, data)                        \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_RESTART_GAME, (GdkModifierType) 0, NULL }
+	  
+#define GNOMEUIINFO_MENU_UNDO_MOVE_ITEM(cb, data)                           \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_UNDO_MOVE, (GdkModifierType) 0, NULL }
+	  
+#define GNOMEUIINFO_MENU_REDO_MOVE_ITEM(cb, data)                           \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_REDO_MOVE, (GdkModifierType) 0, NULL }
+	  
+#define GNOMEUIINFO_MENU_HINT_ITEM(cb, data)                                \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_HINT, (GdkModifierType) 0, NULL }
+	  
+#define GNOMEUIINFO_MENU_SCORES_ITEM(cb, data)                              \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_SCORES, (GdkModifierType) 0, NULL }
+	  
+#define GNOMEUIINFO_MENU_END_GAME_ITEM(cb, data)                            \
+        { GNOME_APP_UI_ITEM_CONFIGURABLE, NULL, NULL,                       \
+          (gpointer)cb, (gpointer)(data), NULL,                             \
+          GNOME_APP_PIXMAP_NONE, NULL,                                      \
+          GNOME_APP_CONFIGURABLE_ITEM_END_GAME, (GdkModifierType) 0, NULL }
+
+const gchar * gnome_app_helper_gettext (const gchar *string);
+
+#ifdef ENABLE_NLS
+#define D_(x) dgettext (PACKAGE, x)
+#define L_(x) gnome_app_helper_gettext(x)
+#else
+#define D_(x) x
+#define L_(x) x
+#endif
+
+/* Some standard menus */
+#define GNOMEUIINFO_MENU_FILE_TREE(tree) \
+	{ GNOME_APP_UI_SUBTREE_STOCK, N_("_File"), NULL, tree, NULL, NULL, \
+		(GnomeUIPixmapType) 0, NULL, 0,	(GdkModifierType) 0, NULL }
+#define GNOMEUIINFO_MENU_EDIT_TREE(tree) \
+	{ GNOME_APP_UI_SUBTREE_STOCK, N_("_Edit"), NULL, tree, NULL, NULL, \
+		(GnomeUIPixmapType) 0, NULL, 0,	(GdkModifierType) 0, NULL }
+#define GNOMEUIINFO_MENU_VIEW_TREE(tree) \
+	{ GNOME_APP_UI_SUBTREE_STOCK, N_("_View"), NULL, tree, NULL, NULL, \
+		(GnomeUIPixmapType) 0, NULL, 0,	(GdkModifierType) 0, NULL }
+#define GNOMEUIINFO_MENU_SETTINGS_TREE(tree) \
+	{ GNOME_APP_UI_SUBTREE_STOCK, N_("_Settings"), NULL, tree, NULL, NULL, \
+		(GnomeUIPixmapType) 0, NULL, 0,	(GdkModifierType) 0, NULL }
+#define GNOMEUIINFO_MENU_FILES_TREE(tree) \
+	{ GNOME_APP_UI_SUBTREE_STOCK, N_("Fi_les"), NULL, tree, NULL, NULL, \
+		(GnomeUIPixmapType) 0, NULL, 0,	(GdkModifierType) 0, NULL }
+#define GNOMEUIINFO_MENU_WINDOWS_TREE(tree) \
+	{ GNOME_APP_UI_SUBTREE_STOCK, N_("_Windows"), NULL, tree, NULL, NULL, \
+		(GnomeUIPixmapType) 0, NULL, 0,	(GdkModifierType) 0, NULL }
+#define GNOMEUIINFO_MENU_HELP_TREE(tree) \
+	{ GNOME_APP_UI_SUBTREE_STOCK, N_("_Help"), NULL, tree, NULL, NULL, \
+		(GnomeUIPixmapType) 0, NULL, 0,	(GdkModifierType) 0, NULL }
+#define GNOMEUIINFO_MENU_GAME_TREE(tree) \
+	{ GNOME_APP_UI_SUBTREE_STOCK, N_("_Game"), NULL, tree, NULL, NULL, \
+		(GnomeUIPixmapType) 0, NULL, 0,	(GdkModifierType) 0, NULL }
+		
+/*these are strings to be used for paths when working with the menus stuff*/
+#define GNOME_MENU_FILE_STRING D_("_File")
+#define GNOME_MENU_FILE_PATH D_("_File/")
+#define GNOME_MENU_EDIT_STRING D_("_Edit")
+#define GNOME_MENU_EDIT_PATH D_("_Edit/")
+#define GNOME_MENU_VIEW_STRING D_("_View")
+#define GNOME_MENU_VIEW_PATH D_("_View/")
+#define GNOME_MENU_SETTINGS_STRING D_("_Settings")
+#define GNOME_MENU_SETTINGS_PATH D_("_Settings/")
+#define GNOME_MENU_NEW_STRING D_("_New")
+#define GNOME_MENU_NEW_PATH D_("_New/")
+#define GNOME_MENU_FILES_STRING D_("Fi_les")
+#define GNOME_MENU_FILES_PATH D_("Fi_les/")
+#define GNOME_MENU_WINDOWS_STRING D_("_Windows")
+#define GNOME_MENU_WINDOWS_PATH D_("_Windows/")
+
+
+/* Types useful to language bindings */
+    
+typedef struct _GnomeUIBuilderData GnomeUIBuilderData;
+
+typedef void (* GnomeUISignalConnectFunc) (GnomeUIInfo        *uiinfo,
+					   const char         *signal_name,
+					   GnomeUIBuilderData *uibdata);
+
+struct _GnomeUIBuilderData {
+	GnomeUISignalConnectFunc connect_func;	/* Function that connects to the item's signals */
+	gpointer data;				/* User data pointer */
+	gboolean is_interp;			/* Should use gtk_signal_connect_interp or normal gtk_signal_connect? */
+	GtkCallbackMarshal relay_func;		/* Marshaller function for language bindings */
+	GtkDestroyNotify destroy_func;		/* Destroy notification function for language bindings */
+};
+
+/* Flush the accelerator definitions into the application specific
+ * configuration file ~/.gnome/accels/<app-id>.
+ */
+void gnome_accelerators_sync (void);
+     
+
+/* Fills the specified menu shell with items created from the specified
+ * info, inserting them from the item no. pos on.
+ * The accel group will be used as the accel group for all newly created
+ * sub menus and serves as the global accel group for all menu item
+ * hotkeys. If it is passed as NULL, global hotkeys will be disabled.
+ * The uline_accels argument determines whether underline accelerators
+ * will be featured from the menu item labels.
+ */
+void gnome_app_fill_menu (GtkMenuShell	*menu_shell,
+			  GnomeUIInfo	*uiinfo,
+			  GtkAccelGroup	*accel_group,
+			  gboolean	 uline_accels,
+			  gint		 pos);
+
+/* Same as gnome_app_fill_menu, but sets all the user data pointers to
+ * the specified value.
+ */
+void gnome_app_fill_menu_with_data (GtkMenuShell	*menu_shell,
+				    GnomeUIInfo		*uiinfo,
+				    GtkAccelGroup	*accel_group,
+				    gboolean		 uline_accels,
+				    gint		 pos,
+				    gpointer		 user_data);
+
+/* Fills the specified menu shell with items created from the specified
+ * info, inserting them from item no. pos on and using the specified
+ * builder data -- this is intended for language bindings.
+ * The accel group will be used as the accel group for all newly created
+ * sub menus and serves as the global accel group for all menu item
+ * hotkeys. If it is passed as NULL, global hotkeys will be disabled.
+ * The uline_accels argument determines whether underline accelerators
+ * will be featured from the menu item labels.
+ */
+void gnome_app_fill_menu_custom (GtkMenuShell	    *menu_shell,
+				 GnomeUIInfo	    *uiinfo,
+				 GnomeUIBuilderData *uibdata,
+				 GtkAccelGroup	    *accel_group,
+				 gboolean	     uline_accels,
+				 gint		     pos);
+
+/* Converts GNOME_APP_UI_ITEM_CONFIGURABLE menu GnomeUIInfos to the
+   corresponding standard GNOME_APP_UI_ITEMs.  gnome_app_create_menus
+   calls this for you, but if you need to alter something afterwards,
+   you can call this function first.  The main reason for this being a
+   public interface is so that it can be called from
+   gnome_popup_menu_new which clears a copy of the passed
+   GnomeUIInofs. */
+void gnome_app_ui_configure_configurable (GnomeUIInfo* uiinfo);
+
+
+/* Constructs a menu bar and attaches it to the specified application window */
+void gnome_app_create_menus (GnomeApp *app, GnomeUIInfo *uiinfo);
+
+/* Constructs a menu bar and attaches it to the specified application window -- this version is
+ * intended for language bindings.
+ */
+void gnome_app_create_menus_interp (GnomeApp *app, GnomeUIInfo *uiinfo,
+				    GtkCallbackMarshal relay_func, gpointer data,
+				    GtkDestroyNotify destroy_func);
+
+/* Constructs a menu bar, sets all the user data pointers to the specified value, and attaches it to
+ * the specified application window.
+ */
+void gnome_app_create_menus_with_data (GnomeApp *app, GnomeUIInfo *uiinfo, gpointer user_data);
+
+/* Constructs a menu bar and attaches it to the specified application window, using the
+ * specified builder data -- intended for language bindings.
+ */
+void gnome_app_create_menus_custom (GnomeApp *app, GnomeUIInfo *uiinfo, GnomeUIBuilderData *uibdata);
+
+/* Fills the specified toolbar with buttons created from the specified info.  If accel_group is not
+ * NULL, then the items' accelerator keys are put into it.
+ */
+void gnome_app_fill_toolbar (GtkToolbar *toolbar, GnomeUIInfo *uiinfo, GtkAccelGroup *accel_group);
+
+/* Same as gnome_app_fill_toolbar, but sets all the user data pointers
+ * to the specified value.
+ */
+void gnome_app_fill_toolbar_with_data (GtkToolbar *toolbar, GnomeUIInfo *uiinfo,
+				       GtkAccelGroup *accel_group, gpointer user_data);
+
+/* Fills the specified toolbar with buttons created from the specified info, using the specified
+ * builder data -- this is intended for language bindings.  If accel_group is not NULL, then the
+ * items' accelerator keys are put into it.
+ */
+void gnome_app_fill_toolbar_custom (GtkToolbar *toolbar, GnomeUIInfo *uiinfo, GnomeUIBuilderData *uibdata,
+				    GtkAccelGroup *accel_group);
+
+/* Constructs a toolbar and attaches it to the specified application window */
+void gnome_app_create_toolbar (GnomeApp *app, GnomeUIInfo *uiinfo);
+
+/* Constructs a toolbar and attaches it to the specified application window -- this version is
+ * intended for language bindings.
+ */
+void gnome_app_create_toolbar_interp (GnomeApp *app, GnomeUIInfo *uiinfo,
+				      GtkCallbackMarshal relay_func, gpointer data,
+				      GtkDestroyNotify destroy_func);
+
+/* Constructs a toolbar, sets all the user data pointers to the specified value, and attaches it to
+ * the specified application window.
+ */
+void gnome_app_create_toolbar_with_data (GnomeApp *app, GnomeUIInfo *uiinfo, gpointer user_data);
+
+/* Constructs a toolbar and attaches it to the specified application window, using the specified
+ * builder data -- intended for language bindings.
+ */
+void gnome_app_create_toolbar_custom (GnomeApp *app, GnomeUIInfo *uiinfo, GnomeUIBuilderData *uibdata);
+
+/* finds menu item described by path (see below for details) starting in the GtkMenuShell top
+ * and returns its parent GtkMenuShell and the position after this item in pos:
+ * gtk_menu_shell_insert(p, w, pos) would then insert widget w in GtkMenuShell p right after
+ * the menu item described by path.
+ * the path argument should be in the form "File/.../.../Something".
+ * "" will insert the item as the first one in the menubar
+ * "File/" will insert it as the first one in the File menu
+ * "File/Settings" will insert it after the Setting item in the File menu
+ * use of  "File/<Separator>" should be obvious. however this stops after the first separator.
+ */
+GtkWidget *gnome_app_find_menu_pos (GtkWidget *parent, const gchar *path, gint *pos);
+
+/* removes num items from the existing app's menu structure begining with item described
+ * by path
+ */
+void gnome_app_remove_menus (GnomeApp *app, const gchar *path, gint items);
+
+/* Same as the above, except it removes the specified number of items 
+ * from the existing app's menu structure begining with item described by path,
+ * plus the number specified by start - very useful for adding and removing Recent
+ * document items in the File menu.
+ */
+void gnome_app_remove_menu_range (GnomeApp *app, const gchar *path, gint start, gint items);
+
+/* inserts menus described by uiinfo in existing app's menu structure right after the item described by path.
+ */
+void gnome_app_insert_menus_custom (GnomeApp *app, const gchar *path, GnomeUIInfo *menuinfo, GnomeUIBuilderData *uibdata);
+
+/* FIXME: what does it do? */
+void gnome_app_insert_menus (GnomeApp *app, const gchar *path, GnomeUIInfo *menuinfo);
+
+/* FIXME: what does it do? */
+void gnome_app_insert_menus_with_data (GnomeApp *app, const gchar *path, GnomeUIInfo *menuinfo, gpointer data);
+
+/* FIXME: what does it do? */
+void gnome_app_insert_menus_interp (GnomeApp *app, const gchar *path, GnomeUIInfo *menuinfo,
+				    GtkCallbackMarshal relay_func, gpointer data,
+				    GtkDestroyNotify destroy_func);
+
+
+/* Activate the menu item hints, displaying in the given appbar.
+   This can't be automatic since we can't reliably find the 
+   appbar. */
+void gnome_app_install_appbar_menu_hints    (GnomeAppBar* appbar,
+                                             GnomeUIInfo* uiinfo);
+
+void gnome_app_install_statusbar_menu_hints (GtkStatusbar* bar,
+                                             GnomeUIInfo* uiinfo);
+
+/* really? why can't it be automatic? */
+void gnome_app_install_menu_hints           (GnomeApp *app,
+                                             GnomeUIInfo *uinfo);
+
+void gnome_app_setup_toolbar                (GtkToolbar *toolbar,
+                                             GnomeDockItem *dock_item);
+
+G_END_DECLS
+
+#endif
diff --git a/libgnomeui/gnome-app.c b/libgnomeui/gnome-app.c
new file mode 100644
index 0000000..32e8e15
--- /dev/null
+++ b/libgnomeui/gnome-app.c
@@ -0,0 +1,865 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Red Hat Software, The Free
+ * Software Foundation, Miguel de Icaza, Federico Menu, Chris Toshok.
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.  */
+/*
+  @NOTATION@
+ */
+
+/*
+ * Originally by Elliot Lee,
+ *
+ * improvements and rearrangement by Miguel,
+ * and I don't know what you other people did :)
+ *
+ * Even more changes by Federico Mena.
+ *
+ * Toolbar separators and configurable relief by Andrew Veliath.
+ *
+ * Modified by Ettore Perazzoli to support GnomeDock.
+ *
+ */
+
+#include "config.h"
+#include "gnome-macros.h"
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include <libgnome/gnome-program.h>
+
+#include <libgnome/gnome-i18n.h>
+#include <libgnome/gnome-util.h>
+#include <libgnome/gnome-config.h>
+#include "gnome-uidefs.h"
+#include "gnome-preferences.h"
+#include "gnome-dock.h"
+#include "gnome-init.h"
+#include "gnome-helpsys.h"
+#include "gnome-window.h"
+
+#include "gnome-app.h"
+
+#define LAYOUT_CONFIG_PATH      "Placement/Dock"
+
+struct _GnomeAppPrivate
+{
+	int dummy;
+	/* Nothing right now, needs to get filled with the private things */
+	/* XXX: When stuff is added, uncomment the allocation in the
+	 * gnome_app_init function! */
+};
+
+
+static void gnome_app_class_init  (GnomeAppClass *class);
+static void gnome_app_init        (GnomeApp      *app);
+static void gnome_app_destroy     (GtkObject     *object);
+static void gnome_app_finalize    (GObject       *object);
+static void gnome_app_show        (GtkWidget     *widget);
+static void gnome_app_get_property   (GObject       *object,
+				   guint          param_id,
+				   GValue        *value,
+				   GParamSpec    *pspec);
+static void gnome_app_set_property   (GObject       *object,
+				   guint          param_id,
+				   const GValue  *value,
+				   GParamSpec    *pspec);
+
+static gchar *read_layout_config  (GnomeApp      *app);
+static void   write_layout_config (GnomeApp      *app,
+				   GnomeDockLayout *layout);
+static void   layout_changed      (GtkWidget     *widget,
+				   gpointer       data);
+
+/* define _get_type and parent_class */
+GNOME_CLASS_BOILERPLATE (GnomeApp, gnome_app,
+			 GtkWindow, gtk_window)
+
+static gchar *
+read_layout_config (GnomeApp *app)
+{
+	gchar *s;
+
+	gnome_config_push_prefix (app->prefix);
+	s = gnome_config_get_string (LAYOUT_CONFIG_PATH);
+	gnome_config_pop_prefix ();
+
+	return s;
+}
+
+static void
+write_layout_config (GnomeApp *app, GnomeDockLayout *layout)
+{
+	gchar *s;
+
+	s = gnome_dock_layout_create_string (layout);
+	gnome_config_push_prefix (app->prefix);
+	gnome_config_set_string (LAYOUT_CONFIG_PATH, s);
+	gnome_config_pop_prefix ();
+	gnome_config_sync ();
+
+	g_free (s);
+}
+
+enum {
+	PROP_0,
+	PROP_APP_ID
+};
+
+static void
+gnome_app_class_init (GnomeAppClass *class)
+{
+	GtkObjectClass *object_class;
+	GObjectClass *gobject_class;
+	GtkWidgetClass *widget_class;
+
+	gobject_class = (GObjectClass *) class;
+	object_class = (GtkObjectClass *) class;
+	widget_class = (GtkWidgetClass *) class;
+
+	gobject_class->finalize = gnome_app_finalize;
+	gobject_class->set_property = gnome_app_set_property;
+	gobject_class->get_property = gnome_app_get_property;
+
+	object_class->destroy = gnome_app_destroy;
+
+	widget_class->show = gnome_app_show;
+
+	g_object_class_install_property (gobject_class,
+				      PROP_APP_ID,
+				      g_param_spec_string ("app_id",
+							   _("App ID"),
+							   _("The application ID string"),
+							   NULL,
+							   (G_PARAM_READABLE |
+							    G_PARAM_WRITABLE)));
+}
+
+static void
+gnome_app_set_property (GObject       *object,
+		     guint          param_id,
+		     const GValue  *value,
+		     GParamSpec    *pspec)
+{
+	GnomeApp *app = GNOME_APP (object);
+
+	switch(param_id) {
+	case PROP_APP_ID:
+		g_free (app->name);
+		app->name = g_value_dup_string (value);
+		g_free (app->prefix);
+		app->prefix = g_strconcat("/", app->name, "/", NULL);
+		break;
+	}
+}
+
+static void
+gnome_app_get_property (GObject       *object,
+		     guint          param_id,
+		     GValue        *value,
+		     GParamSpec    *pspec)
+{
+	GnomeApp *app = GNOME_APP (object);
+
+	switch(param_id) {
+	case PROP_APP_ID:
+		g_value_set_string (value, app->name);
+		break;
+	}
+}
+
+static void
+gnome_app_init (GnomeApp *app)
+{
+	const char *str = NULL;
+	GValue value = { 0, };
+
+	app->_priv = NULL;
+	/* XXX: when there is some private stuff enable this
+	app->_priv = g_new0(GnomeAppPrivate, 1);
+	*/
+
+	app->name = NULL;
+	app->prefix = NULL;
+
+	app->accel_group = gtk_accel_group_new ();
+	gtk_window_add_accel_group (GTK_WINDOW (app), app->accel_group);
+	
+	app->vbox = gtk_vbox_new (FALSE, 0);
+	gtk_container_add (GTK_CONTAINER (app), app->vbox);
+
+	app->dock = gnome_dock_new ();
+	gtk_box_pack_start (GTK_BOX (app->vbox), app->dock,
+			    TRUE, TRUE, 0);
+
+	gtk_signal_connect (GTK_OBJECT (app->dock),
+			    "layout_changed",
+			    GTK_SIGNAL_FUNC (layout_changed),
+			    (gpointer) app);
+
+	app->layout = gnome_dock_layout_new ();
+
+	app->enable_layout_config = TRUE;
+	g_value_init (&value, G_TYPE_STRING);
+	g_object_get_property (G_OBJECT (gnome_program_get ()),
+			       LIBGNOMEUI_PARAM_DEFAULT_ICON, &value);
+	str = g_value_get_string (&value);
+	if (str != NULL)
+		gnome_window_set_icon_from_file (GTK_WINDOW (app), str, FALSE);
+	g_value_unset (&value);
+}
+
+static void
+gnome_app_show (GtkWidget *widget)
+{
+	GnomeApp *app;
+
+	app = GNOME_APP (widget);
+
+	if (app->layout != NULL) {
+		if (app->enable_layout_config) {
+			gchar *s;
+
+			/* Override the layout with the user's saved
+			   configuration.  */
+			s = read_layout_config (app);
+			gnome_dock_layout_parse_string (app->layout, s);
+			g_free (s);
+		}
+
+		gnome_dock_add_from_layout (GNOME_DOCK (app->dock),
+					    app->layout);
+
+		if (app->enable_layout_config)
+			write_layout_config (app, app->layout);
+
+		gtk_object_unref (GTK_OBJECT (app->layout));
+		app->layout = NULL;
+	}
+			
+	gtk_widget_show (app->vbox);
+	gtk_widget_show (app->dock);
+
+	GNOME_CALL_PARENT_HANDLER (GTK_WIDGET_CLASS, show, (widget));
+}
+
+static void
+layout_changed (GtkWidget *w, gpointer data)
+{
+	GnomeApp *app;
+
+	g_return_if_fail (GNOME_IS_APP (data));
+	g_return_if_fail (GNOME_IS_DOCK (w));
+
+	app = GNOME_APP (data);
+
+	if (app->enable_layout_config) {
+		GnomeDockLayout *layout;
+
+		layout = gnome_dock_get_layout (GNOME_DOCK (app->dock));
+		write_layout_config (app, layout);
+		gtk_object_unref (GTK_OBJECT (layout));
+	}
+}
+
+/**
+ * gnome_app_new
+ * @appname: Name of program, using in file names and paths.
+ * @title: Window title for application.
+ *
+ * Description:
+ * Create a new (empty) application window.  You must specify the
+ * application's name (used internally as an identifier).
+ * @title can be left as NULL, in which case the window's title will
+ * not be set.
+ *
+ * Returns: Pointer to new GNOME app object.
+ **/
+
+GtkWidget *
+gnome_app_new (const gchar *appname, const gchar *title)
+{
+	GtkObject *app;
+
+	g_return_val_if_fail (appname != NULL, NULL);
+
+	if (title != NULL) {
+		app = g_object_new (gnome_app_get_type (),
+				    "app_id", appname,
+				    NULL);
+		gtk_object_set (GTK_OBJECT (app),
+				"title", title,
+				NULL);
+	} else {
+		app = g_object_new (gnome_app_get_type (),
+				    "app_id", appname,
+				    NULL);
+	}
+	return GTK_WIDGET (app);
+}
+
+/**
+ * gnome_app_construct
+ * @app: Pointer to newly-created GNOME app object.
+ * @appname: Name of program, using in file names and paths.
+ * @title: Window title for application.
+ *
+ * Description:
+ * Constructor for language bindings; you don't normally need this.
+ **/
+
+void 
+gnome_app_construct (GnomeApp *app, const gchar *appname, const gchar *title)
+{
+	g_return_if_fail (appname != NULL);
+
+	if (title != NULL) {
+		g_object_set (G_OBJECT (app),
+			      "app_id", appname,
+			      NULL);
+		gtk_object_set (GTK_OBJECT (app),
+				"title", title,
+				NULL);
+	} else {
+		g_object_set (G_OBJECT (app),
+			      "app_id", appname,
+			      NULL);
+	}
+}
+
+static void
+gnome_app_destroy (GtkObject *object)
+{
+	GnomeApp *app;
+
+	/* remember, destroy can be run multiple times! */
+	
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GNOME_IS_APP (object));
+
+	app = GNOME_APP (object);
+
+	g_free (app->name);
+	app->name = NULL;
+	g_free (app->prefix);
+	app->prefix = NULL;
+
+	if (app->accel_group != NULL) {
+		gtk_accel_group_unref (app->accel_group);
+		app->accel_group = NULL;
+	}
+
+	if (app->layout != NULL) {
+		gtk_object_unref (GTK_OBJECT (app->layout));
+		app->layout = NULL;
+	}
+
+	GNOME_CALL_PARENT_HANDLER (GTK_OBJECT_CLASS, destroy, (object));
+}
+
+static void
+gnome_app_finalize (GObject *object)
+{
+	GnomeApp *app;
+	
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GNOME_IS_APP (object));
+
+	app = GNOME_APP (object);
+
+	/* Free private data */
+	g_free(app->_priv);
+	app->_priv = NULL;
+
+	GNOME_CALL_PARENT_HANDLER (G_OBJECT_CLASS, finalize, (object));
+}
+
+/* Callback for an app's contents' parent_set signal.  We set the app->contents
+ * to NULL and detach the signal.
+ */
+static void
+contents_parent_set (GtkWidget *widget, GtkWidget *previous_parent, gpointer data)
+{
+	GnomeApp *app;
+
+	app = GNOME_APP (data);
+
+	g_assert (previous_parent == app->dock);
+
+	gtk_signal_disconnect_by_func (GTK_OBJECT (widget),
+				       GTK_SIGNAL_FUNC (contents_parent_set),
+				       data);
+
+	app->contents = NULL;
+}
+
+/**
+ * gnome_app_set_contents
+ * @app: Pointer to GNOME app object.
+ * @contents: Widget to be application content area.
+ *
+ * Description:
+ * Sets the content area of the GNOME app's main window.
+ **/
+void
+gnome_app_set_contents (GnomeApp *app, GtkWidget *contents)
+{
+	GtkWidget *new_contents;
+
+	g_return_if_fail (app != NULL);
+	g_return_if_fail (GNOME_IS_APP(app));
+	g_return_if_fail (app->dock != NULL);
+	g_return_if_fail (contents != NULL);
+	g_return_if_fail (GTK_IS_WIDGET (contents));
+
+	gnome_dock_set_client_area (GNOME_DOCK (app->dock), contents);
+
+	/* Re-fetch it in case it did not change */
+	new_contents = gnome_dock_get_client_area (GNOME_DOCK (app->dock));
+
+	if (new_contents == contents && new_contents != app->contents) {
+		gtk_widget_show (new_contents);
+		gtk_signal_connect (GTK_OBJECT (new_contents), "parent_set",
+				    GTK_SIGNAL_FUNC (contents_parent_set),
+				    app);
+
+		app->contents = new_contents;
+	}
+}
+
+/**
+ * gnome_app_set_menus
+ * @app: Pointer to GNOME app object.
+ * @menubar: Menu bar widget for main app window.
+ *
+ * Description:
+ * Sets the menu bar of the application window.
+ **/
+
+void
+gnome_app_set_menus (GnomeApp *app, GtkMenuBar *menubar)
+{
+	GtkWidget *dock_item;
+	GtkAccelGroup *ag;
+	GnomeDockItemBehavior behavior;
+
+	g_return_if_fail(app != NULL);
+	g_return_if_fail(GNOME_IS_APP(app));
+	g_return_if_fail(app->menubar == NULL);
+	g_return_if_fail(menubar != NULL);
+	g_return_if_fail(GTK_IS_MENU_BAR(menubar));
+
+	behavior = (GNOME_DOCK_ITEM_BEH_EXCLUSIVE
+		    | GNOME_DOCK_ITEM_BEH_NEVER_VERTICAL);
+	
+	if (!gnome_preferences_get_menubar_detachable())
+		behavior |= GNOME_DOCK_ITEM_BEH_LOCKED;
+
+	dock_item = gnome_dock_item_new (GNOME_APP_MENUBAR_NAME,
+					 behavior);
+	gtk_container_add (GTK_CONTAINER (dock_item), GTK_WIDGET (menubar));
+
+	app->menubar = GTK_WIDGET (menubar);
+
+	/* To have menubar relief agree with the toolbar (and have the relief
+	 * outside of smaller handles), substitute the dock item's relief for
+	 * the menubar's relief, but don't change the size of the menubar in
+	 * the process. */
+	gtk_menu_bar_set_shadow_type (GTK_MENU_BAR (app->menubar),
+				      GTK_SHADOW_NONE);
+	if (gnome_preferences_get_menubar_relief ()) {
+		guint border_width;
+		
+		gtk_container_set_border_width (GTK_CONTAINER (dock_item), 2);
+		border_width = GTK_CONTAINER (app->menubar)->border_width;
+		if (border_width >= 2)
+			border_width -= 2;
+		gtk_container_set_border_width (GTK_CONTAINER (app->menubar),
+						border_width);
+	} else
+		gnome_dock_item_set_shadow_type (GNOME_DOCK_ITEM (dock_item),
+						 GTK_SHADOW_NONE);
+
+	if (app->layout != NULL)
+		gnome_dock_layout_add_item (app->layout,
+					    GNOME_DOCK_ITEM (dock_item),
+					    GNOME_DOCK_TOP,
+					    0, 0, 0);
+	else
+		gnome_dock_add_item(GNOME_DOCK(app->dock),
+				    GNOME_DOCK_ITEM (dock_item),
+				    GNOME_DOCK_TOP,
+				    0, 0, 0, TRUE);
+
+	gtk_widget_show (GTK_WIDGET (menubar));
+	gtk_widget_show (GTK_WIDGET (dock_item));
+
+	ag = gtk_object_get_data(GTK_OBJECT(app), "GtkAccelGroup");
+	if (ag && !g_slist_find(gtk_accel_groups_from_object (GTK_OBJECT (app)), ag))
+	        gtk_window_add_accel_group(GTK_WINDOW(app), ag);
+}
+
+
+/**
+ * gnome_app_set_statusbar
+ * @app: Pointer to GNOME app object
+ * @statusbar: Statusbar widget for main app window
+ *
+ * Description:
+ * Sets the status bar of the application window.
+ **/
+
+void
+gnome_app_set_statusbar (GnomeApp *app,
+		         GtkWidget *statusbar)
+{
+	GtkWidget *hbox;
+
+	g_return_if_fail(app != NULL);
+	g_return_if_fail(GNOME_IS_APP(app));
+	g_return_if_fail(statusbar != NULL);
+	g_return_if_fail(app->statusbar == NULL);
+
+	app->statusbar = GTK_WIDGET(statusbar);
+	gtk_widget_show(app->statusbar);
+
+	hbox = gtk_hbox_new(FALSE, 0);
+	gtk_container_set_border_width(GTK_CONTAINER(hbox), 0);
+	gtk_box_pack_start(GTK_BOX(hbox), statusbar, TRUE, TRUE, 0);
+	gtk_widget_show(hbox);
+
+	gtk_box_pack_start (GTK_BOX (app->vbox), hbox, FALSE, FALSE, 0);
+}
+
+/**
+ * gnome_app_set_statusbar_custom
+ * @app: Pointer to GNOME app object
+ * @container: container widget containing the statusbar
+ * @statusbar: Statusbar widget for main app window
+ *
+ * Description:
+ * Sets the status bar of the application window, but use @container
+ * as its container.
+ *
+ **/
+
+void
+gnome_app_set_statusbar_custom (GnomeApp *app,
+				GtkWidget *container,
+				GtkWidget *statusbar)
+{
+	g_return_if_fail(app != NULL);
+	g_return_if_fail(GNOME_IS_APP(app));
+	g_return_if_fail(container != NULL);
+	g_return_if_fail(GTK_IS_CONTAINER(container));
+	g_return_if_fail(statusbar != NULL);
+	g_return_if_fail(app->statusbar == NULL);
+
+	app->statusbar = GTK_WIDGET(statusbar);
+
+	gtk_box_pack_start (GTK_BOX (app->vbox), container, FALSE, FALSE, 0);
+}
+
+/**
+ * gnome_app_add_toolbar:
+ * @app: A &GnomeApp widget
+ * @toolbar: Toolbar to be added to @app's dock
+ * @name: Name for the dock item that will contain @toolbar
+ * @behavior: Behavior for the new dock item
+ * @placement: Placement for the new dock item
+ * @band_num: Number of the band where the dock item should be placed
+ * @band_position: Position of the new dock item in band @band_num
+ * @offset: Offset from the previous dock item in the band; if there is
+ * no previous item, offset from the beginning of the band.
+ *
+ * Create a new &GnomeDockItem widget containing @toolbar, and add it
+ * to @app's dock with the specified layout information.  Notice that,
+ * if automatic layout configuration is enabled, the layout is
+ * overridden by the saved configuration, if any.
+ **/
+void
+gnome_app_add_toolbar (GnomeApp *app,
+		       GtkToolbar *toolbar,
+		       const gchar *name,
+		       GnomeDockItemBehavior behavior,
+		       GnomeDockPlacement placement,
+		       gint band_num,
+		       gint band_position,
+		       gint offset)
+{
+
+	GtkWidget *dock_item;
+	GtkAccelGroup *ag;
+
+	g_return_if_fail(app != NULL);
+	g_return_if_fail(GNOME_IS_APP(app));
+	g_return_if_fail(toolbar != NULL);
+
+	dock_item = gnome_dock_item_new (name, behavior);
+
+	gtk_container_set_border_width (GTK_CONTAINER (toolbar), 1);
+	gtk_container_add (GTK_CONTAINER (dock_item), GTK_WIDGET (toolbar));
+
+	if(app->layout)
+		gnome_dock_layout_add_item (app->layout,
+					    GNOME_DOCK_ITEM (dock_item),
+					    placement,
+					    band_num,
+					    band_position,
+					    offset);
+	else
+		gnome_dock_add_item (GNOME_DOCK(app->dock),
+				     GNOME_DOCK_ITEM (dock_item),
+				     placement,
+				     band_num,
+				     band_position,
+				     offset,
+				     TRUE);
+
+
+	gnome_app_setup_toolbar(toolbar, GNOME_DOCK_ITEM(dock_item));
+	
+	gtk_widget_show (GTK_WIDGET (toolbar));
+	gtk_widget_show (GTK_WIDGET (dock_item));
+
+	ag = gtk_object_get_data(GTK_OBJECT(app), "GtkAccelGroup");
+	if (ag && !g_slist_find(gtk_accel_groups_from_object (GTK_OBJECT (app)), ag))
+	        gtk_window_add_accel_group(GTK_WINDOW(app), ag);
+}
+
+/**
+ * gnome_app_set_toolbar
+ * @app: Pointer to GNOME app object.
+ * @toolbar: Toolbar widget for main app window.
+ *
+ * Description:
+ * Sets the main toolbar of the application window.
+ **/
+
+void
+gnome_app_set_toolbar (GnomeApp *app,
+		       GtkToolbar *toolbar)
+{
+	GnomeDockItemBehavior behavior;
+
+	/* Making dock items containing toolbars use
+	   `GNOME_DOCK_ITEM_BEH_EXCLUSIVE' is not really a
+	   requirement.  We only do this for backwards compatibility.  */
+	behavior = GNOME_DOCK_ITEM_BEH_EXCLUSIVE;
+	
+	if (!gnome_preferences_get_toolbar_detachable())
+		behavior |= GNOME_DOCK_ITEM_BEH_LOCKED;
+	
+	gnome_app_add_toolbar (app, toolbar,
+			       GNOME_APP_TOOLBAR_NAME,
+			       behavior,
+			       GNOME_DOCK_TOP,
+			       1, 0, 0);
+}
+
+
+/**
+ * gnome_app_add_dock_item:
+ * @app: A &GnomeApp widget
+ * @item: Dock item to be added to @app's dock.
+ * @placement: Placement for the dock item
+ * @band_num: Number of the band where the dock item should be placed
+ * @band_position: Position of the dock item in band @band_num
+ * @offset: Offset from the previous dock item in the band; if there is
+ * no previous item, offset from the beginning of the band.
+ * 
+ * Add @item according to the specified layout information.  Notice
+ * that, if automatic layout configuration is enabled, the layout is
+ * overridden by the saved configuration, if any.
+ **/
+void
+gnome_app_add_dock_item (GnomeApp *app,
+			 GnomeDockItem *item,
+			 GnomeDockPlacement placement,
+			 gint band_num,
+			 gint band_position,
+			 gint offset)
+{
+	if (app->layout)
+		gnome_dock_layout_add_item (app->layout,
+					    GNOME_DOCK_ITEM (item),
+					    placement,
+					    band_num,
+					    band_position,
+					    offset);
+	else
+		gnome_dock_add_item (GNOME_DOCK(app->dock),
+				     GNOME_DOCK_ITEM( item),
+				     placement,
+				     band_num,
+				     band_position,
+				     offset,
+				     FALSE);
+
+	gtk_signal_emit_by_name (GTK_OBJECT (app->dock),
+				 "layout_changed",
+				 (gpointer) app);
+}
+
+/**
+ * gnome_app_add_docked:
+ * @app: A &GnomeApp widget
+ * @widget: Widget to be added to the &GnomeApp
+ * @name: Name for the new dock item
+ * @behavior: Behavior for the new dock item
+ * @placement: Placement for the new dock item
+ * @band_num: Number of the band where the dock item should be placed
+ * @band_position: Position of the new dock item in band @band_num
+ * @offset: Offset from the previous dock item in the band; if there is
+ * no previous item, offset from the beginning of the band.
+ *
+ * Returns: The dock item used to contain the widget.
+ * 
+ * Add @widget as a dock item according to the specified layout
+ * information.  Notice that, if automatic layout configuration is
+ * enabled, the layout is overridden by the saved configuration, if
+ * any.
+ **/
+GtkWidget *
+gnome_app_add_docked (GnomeApp *app,
+		      GtkWidget *widget,
+		      const gchar *name,
+		      GnomeDockItemBehavior behavior,
+		      GnomeDockPlacement placement,
+		      gint band_num,
+		      gint band_position,
+		      gint offset)
+{
+	GtkWidget *item;
+
+	item = gnome_dock_item_new (name, behavior);
+	gtk_container_add (GTK_CONTAINER (item), widget);
+	gnome_app_add_dock_item (app, GNOME_DOCK_ITEM (item),
+				 placement, band_num, band_position, offset);
+
+	return item;
+}
+
+/**
+ * gnome_app_enable_layout_config:
+ * @app: A &GnomeApp widget
+ * @enable: Boolean specifying whether automatic configuration saving
+ * is enabled
+ * 
+ * Specify whether @app should automatically save the dock's
+ * layout configuration via gnome-config whenever it changes or not.
+ **/
+void
+gnome_app_enable_layout_config (GnomeApp *app, gboolean enable)
+{
+	app->enable_layout_config = enable;
+}
+
+/**
+ * gnome_app_get_dock_item_by_name:
+ * @app: A &GnomeApp widget
+ * @name: Name of the dock item to retrieve
+ * 
+ * Retrieve the dock item whose name matches @name.
+ * 
+ * Return value: The retrieved dock item.
+ **/
+GnomeDockItem *
+gnome_app_get_dock_item_by_name (GnomeApp *app,
+				 const gchar *name)
+{
+	GnomeDockItem *item;
+
+	item = gnome_dock_get_item_by_name (GNOME_DOCK (app->dock), name,
+					    NULL, NULL, NULL, NULL);
+
+	if (item == NULL && app->layout != NULL) {
+		GnomeDockLayoutItem *i;
+
+		i = gnome_dock_layout_get_item_by_name (app->layout,
+							name);
+		if (i == NULL)
+			return NULL;
+
+		return i->item;
+	} else {
+		return item;
+	}
+}
+
+/**
+ * gnome_app_get_dock:
+ * @app: A &GnomeApp widget
+ * 
+ * Retrieves the &GnomeDock widget contained in the &GnomeApp.
+ * 
+ * Returns: The &GnomeDock widget.
+ **/
+GnomeDock *
+gnome_app_get_dock (GnomeApp *app)
+{
+	return GNOME_DOCK (app->dock);
+}
+
+static void
+gnome_app_set_help_view_orientation(GtkWidget *dock_item, GtkOrientation new_orientation, GnomeHelpView *help_view)
+{
+	/* 2000-09-01: Something wrong with new_orientation:
+	   It is always 0. IH */
+	gnome_help_view_set_orientation(help_view, 
+					GNOME_DOCK_ITEM (dock_item)->orientation);
+}
+
+/**
+ * gnome_app_add_help_view:
+ * @app: A &GnomeApp widget
+ * @help_view: A &GnomeHelpView widget
+ *
+ * Sets the &GnomeHelpView widget for a particular &GnomeApp toplevel.
+ * If 'help_view' is NULL, creates a help view using reasonable default settings.
+ */
+void
+gnome_app_set_help_view (GnomeApp *app, GtkWidget *help_view)
+{
+	GtkWidget *item;
+	gpointer td;
+	g_return_if_fail(GNOME_IS_APP(app));
+
+	td = gtk_object_get_data((GtkObject *)app, GNOME_APP_HELP_VIEW_NAME);
+
+	if(td)
+		return;
+
+	if(help_view == NULL)
+		help_view = gnome_help_view_new(GTK_WIDGET(app),
+						GNOME_HELP_POPUP,
+						G_PRIORITY_LOW);
+
+	gtk_widget_show(help_view);
+
+	item = gnome_dock_item_new (GNOME_APP_HELP_VIEW_NAME, 
+				    GNOME_DOCK_ITEM_BEH_EXCLUSIVE);
+	gtk_container_add (GTK_CONTAINER (item), help_view);
+	gnome_app_add_dock_item (app, GNOME_DOCK_ITEM (item),
+				 GNOME_DOCK_BOTTOM, 0, 0, 0);
+	gtk_signal_connect_while_alive(GTK_OBJECT(item), "orientation_changed",
+				       GTK_SIGNAL_FUNC(gnome_app_set_help_view_orientation), 
+				       help_view, GTK_OBJECT(help_view));
+}
diff --git a/libgnomeui/gnome-app.h b/libgnomeui/gnome-app.h
new file mode 100644
index 0000000..f615f28
--- /dev/null
+++ b/libgnomeui/gnome-app.h
@@ -0,0 +1,174 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Red Hat Software, The Free
+ * Software Foundation, Miguel de Icaza, Federico Menu, Chris Toshok.
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.  */
+/*
+  @NOTATION@
+ */
+
+/*
+ *
+ * Originally by Elliot Lee,
+ *
+ * improvements and rearrangement by Miguel,
+ * and I don't know what you other people did :)
+ *
+ * Even more changes by Federico Mena.
+ */
+
+#ifndef GNOME_APP_H
+#define GNOME_APP_H
+
+#include <gtk/gtkmenubar.h>
+#include <gtk/gtktoolbar.h>
+#include <gtk/gtkwindow.h>
+
+
+#include "gnome-dock.h"
+
+G_BEGIN_DECLS
+
+#define GNOME_APP_MENUBAR_NAME "Menubar"
+#define GNOME_APP_TOOLBAR_NAME "Toolbar"
+
+
+#define GNOME_TYPE_APP            (gnome_app_get_type ())
+#define GNOME_APP(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_APP, GnomeApp))
+#define GNOME_APP_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_APP, GnomeAppClass))
+#define GNOME_IS_APP(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_APP))
+#define GNOME_IS_APP_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_APP))
+#define GNOME_APP_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_APP, GnomeAppClass))
+
+
+typedef struct _GnomeApp        GnomeApp;
+typedef struct _GnomeAppPrivate GnomeAppPrivate;
+typedef struct _GnomeAppClass   GnomeAppClass;
+
+struct _GnomeApp {
+	GtkWindow parent_object;
+
+	/* Application name. */
+	gchar *name;
+
+	/* Prefix for gnome-config (used to save the layout).  */
+	gchar *prefix;
+
+        /* The dock.  */
+        GtkWidget *dock;
+
+	/* The status bar.  */
+        GtkWidget *statusbar;
+
+	/* The vbox widget that ties them.  */
+	GtkWidget *vbox;
+
+	/* The menubar.  This is a pointer to a widget contained into
+           the dock.  */
+	GtkWidget *menubar;
+
+	/* The contents.  This is a pointer to dock->client_area.  */
+	GtkWidget *contents;
+
+	/* Dock layout.  */
+	GnomeDockLayout *layout;
+
+	/* Main accelerator group for this window (hotkeys live here).  */
+	GtkAccelGroup *accel_group;
+
+	/* If TRUE, the application uses gnome-config to retrieve and
+           save the docking configuration automagically.  */
+	gboolean enable_layout_config : 1;
+
+	/*< private >*/
+	GnomeAppPrivate *_priv;
+};
+
+struct _GnomeAppClass {
+	GtkWindowClass parent_class;
+};
+
+
+/* Standard Gtk function */
+GtkType gnome_app_get_type (void) G_GNUC_CONST;
+
+/* Create a new (empty) application window.  You must specify the application's name (used
+ * internally as an identifier).  The window title can be left as NULL, in which case the window's
+ * title will not be set.
+ */
+GtkWidget *gnome_app_new (const gchar *appname, const gchar *title);
+
+/* Constructor for language bindings; you don't normally need this. */
+void gnome_app_construct (GnomeApp *app, const gchar *appname, const gchar *title);
+
+/* Sets the menu bar of the application window */
+void gnome_app_set_menus (GnomeApp *app, GtkMenuBar *menubar);
+
+/* Sets the main toolbar of the application window */
+void gnome_app_set_toolbar (GnomeApp *app, GtkToolbar *toolbar);
+
+/* Sets the status bar of the application window */
+void gnome_app_set_statusbar (GnomeApp *app, GtkWidget *statusbar);
+
+/* Sets the status bar of the application window, but uses the given
+ * container widget rather than creating a new one. */
+void gnome_app_set_statusbar_custom (GnomeApp *app,
+				     GtkWidget *container,
+				     GtkWidget *statusbar);
+
+/* Sets the content area of the application window */
+void gnome_app_set_contents (GnomeApp *app, GtkWidget *contents);
+
+void gnome_app_add_toolbar (GnomeApp *app,
+			    GtkToolbar *toolbar,
+			    const gchar *name,
+			    GnomeDockItemBehavior behavior,
+			    GnomeDockPlacement placement,
+			    gint band_num,
+			    gint band_position,
+			    gint offset);
+
+GtkWidget *gnome_app_add_docked (GnomeApp *app,
+				 GtkWidget *widget,
+				 const gchar *name,
+				 GnomeDockItemBehavior behavior,
+				 GnomeDockPlacement placement,
+				 gint band_num,
+				 gint band_position,
+				 gint offset);
+
+void gnome_app_add_dock_item (GnomeApp *app,
+			      GnomeDockItem *item,
+			      GnomeDockPlacement placement,
+			      gint band_num,
+			      gint band_position,
+			      gint offset);
+
+void gnome_app_enable_layout_config (GnomeApp *app, gboolean enable);
+
+GnomeDock *gnome_app_get_dock (GnomeApp *app);
+
+GnomeDockItem *gnome_app_get_dock_item_by_name (GnomeApp *app,
+						const gchar *name);
+void gnome_app_set_help_view (GnomeApp *app,
+			      GtkWidget *help_view);
+G_END_DECLS
+
+#endif /* GNOME_APP_H */
diff --git a/libgnomeui/gnome-appbar.c b/libgnomeui/gnome-appbar.c
new file mode 100644
index 0000000..846a7d7
--- /dev/null
+++ b/libgnomeui/gnome-appbar.c
@@ -0,0 +1,759 @@
+/* gnome-appbar.h: statusbar/progress/minibuffer widget for Gnome apps
+ * 
+ * This version by Havoc Pennington
+ * Based on MozStatusbar widget, by Chris Toshok
+ * In turn based on GtkStatusbar widget, from Gtk+,
+ * Copyright (C) 1995-1998 Peter Mattis, Spencer Kimball and Josh MacDonald
+ * GtkStatusbar Copyright (C) 1998 Shawn T. Amundson
+ * All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#include "config.h"
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+
+#include <string.h> /* for strlen */
+
+#include "gnome-appbar.h"
+
+#include <libgnome/gnome-util.h>
+#include <libgnome/gnome-i18n.h>
+#include <libgnomeui/gnome-preferences.h>
+
+#include "gnome-uidefs.h"
+
+#ifndef GNOME_ENABLE_DEBUG
+#define GNOME_ENABLE_DEBUG /* to be sure */
+#endif
+
+struct _GnomeAppBarPrivate
+{
+  /* Private; there's no guarantee on the type of these in the
+     future. Statusbar could be a label, entry, GtkStatusbar, or
+     something else; progress could be a label or progress bar; it's
+     all up in the air for now. */
+  GtkWidget * progress;
+  GtkWidget * status;
+  gchar * prompt; /* The text of a prompt, if any. */
+
+  /* Keep it simple; no contexts. 
+     if (status_stack) display_top_of_stack;
+     else if (default_status) display_default;
+     else display_nothing;      */
+  /* Also private by the way */
+  GSList * status_stack;
+  gchar  * default_status;
+
+  gint16 editable_start; /* The first editable position in the interactive
+			  buffer. */
+  gboolean interactive : 1; /* This means status is an entry rather than a
+			       label, for the moment. */
+};
+
+
+static void gnome_appbar_class_init               (GnomeAppBarClass *class);
+static void gnome_appbar_init                     (GnomeAppBar      *ab);
+static void gnome_appbar_destroy                  (GtkObject        *object);
+static void gnome_appbar_finalize                 (GObject          *object);
+     
+static GtkContainerClass *parent_class;
+
+enum {
+  USER_RESPONSE,
+  CLEAR_PROMPT,
+  LAST_SIGNAL
+};
+
+static gint appbar_signals[LAST_SIGNAL] = { 0 };
+
+guint      
+gnome_appbar_get_type ()
+{
+  static guint ab_type = 0;
+
+  if (!ab_type)
+    {
+      GtkTypeInfo ab_info =
+      {
+        "GnomeAppBar",
+        sizeof (GnomeAppBar),
+        sizeof (GnomeAppBarClass),
+        (GtkClassInitFunc) gnome_appbar_class_init,
+        (GtkObjectInitFunc) gnome_appbar_init,
+        NULL,
+        NULL,
+	NULL
+      };
+
+      ab_type = gtk_type_unique (gtk_hbox_get_type (), &ab_info);
+    }
+
+  return ab_type;
+}
+
+static void
+gnome_appbar_class_init (GnomeAppBarClass *class)
+{
+  GtkObjectClass *object_class;
+  GObjectClass *gobject_class;
+  GtkWidgetClass *widget_class;
+  GtkContainerClass *container_class;
+
+  object_class = (GtkObjectClass *) class;
+  gobject_class = (GObjectClass *) class;
+  widget_class = (GtkWidgetClass *) class;
+  container_class = (GtkContainerClass *) class;
+
+  appbar_signals[USER_RESPONSE] =
+    gtk_signal_new ("user_response",
+		    GTK_RUN_LAST,
+		    GTK_CLASS_TYPE (object_class),
+		    GTK_SIGNAL_OFFSET (GnomeAppBarClass, user_response),
+		    gtk_signal_default_marshaller,
+		    GTK_TYPE_NONE, 0);
+
+  appbar_signals[CLEAR_PROMPT] =
+    gtk_signal_new ("clear_prompt",
+		    GTK_RUN_LAST,
+		    GTK_CLASS_TYPE (object_class),
+		    GTK_SIGNAL_OFFSET (GnomeAppBarClass, clear_prompt),
+		    gtk_signal_default_marshaller,
+		    GTK_TYPE_NONE, 0);
+
+  parent_class = gtk_type_class (gtk_hbox_get_type ());
+  
+  class->user_response = NULL;
+  class->clear_prompt  = NULL; /* maybe should have a handler
+				  and the clear_prompt function
+				  just emits. */
+  object_class->destroy = gnome_appbar_destroy;
+  gobject_class->finalize = gnome_appbar_finalize;
+}
+
+static GSList * 
+stringstack_push(GSList * stringstack, const gchar * s)
+{
+  return g_slist_prepend(stringstack, g_strdup(s));
+}
+
+static GSList *
+stringstack_pop(GSList * stringstack)
+{
+  /* Could be optimized */
+  if (stringstack) {
+    g_free(stringstack->data);
+    return g_slist_remove(stringstack, stringstack->data);
+  }
+  else return NULL;
+}
+
+static const gchar *
+stringstack_top(GSList * stringstack)
+{
+  if (stringstack) return stringstack->data;
+  else return NULL;
+}
+
+static void
+stringstack_free(GSList * stringstack)
+{
+  GSList * tmp = stringstack;
+  while (tmp) {
+    g_free(tmp->data);
+    tmp = g_slist_next(tmp);
+  }
+  g_slist_free(stringstack);
+}
+
+static void
+entry_delete_text_cb(GtkWidget * entry, gint start, 
+		     gint stop, GnomeAppBar * ab)
+{
+  g_return_if_fail(GNOME_IS_APPBAR(ab));
+  g_return_if_fail(GTK_IS_ENTRY(entry));
+  g_return_if_fail(ab->_priv->interactive);
+
+  if (ab->_priv->prompt == NULL) return; /* not prompting, so don't 
+				     interfere. */
+#ifdef GNOME_ENABLE_DEBUG
+    g_print("Start is %d, stop is %d, start of editable is %d\n", 
+	    start, stop, ab->_priv->editable_start);
+#endif
+  
+  if (start < ab->_priv->editable_start) {
+    /* Block the signal, since it's trying to delete text
+       that shouldn't be deleted. */
+    gtk_signal_emit_stop_by_name(GTK_OBJECT(entry), "delete_text");
+    gdk_beep();
+  }
+}
+static void 
+entry_insert_text_cb  (GtkEditable    *entry,
+		       const gchar    *text,
+		       gint            length,
+		       gint           *position,
+		       GnomeAppBar * ab)
+{
+  gint pos; 
+
+  if (ab->_priv->prompt == NULL) return; /* not prompting, so don't 
+				     interfere. */
+
+  pos = gtk_editable_get_position(entry);
+
+#ifdef GNOME_ENABLE_DEBUG
+    g_print("Position is %d, start of editable is %d\n", 
+	    pos, ab->_priv->editable_start);
+#endif
+
+  if (pos < ab->_priv->editable_start) {
+
+    /*    gtk_editable_set_position(entry, ab->_priv->editable_start); */
+    gtk_signal_emit_stop_by_name(GTK_OBJECT(entry), "insert_text");
+    /*    gtk_signal_emit_by_name(GTK_OBJECT(entry), "insert_text",
+			    text, length, position); */
+  }
+}
+
+static gint
+entry_key_press_cb(GtkWidget * entry, GdkEventKey * e, GnomeAppBar * ab)
+{
+  /* This should be some kind of configurable binding
+      or accelerator, probably. */
+  if ( (e->keyval == GDK_g) && 
+       (e->state & GDK_CONTROL_MASK) ) {
+    /* Cancel */
+    gnome_appbar_clear_prompt(ab);
+    return TRUE; /* Override other handlers */
+  }
+  else return FALSE; /* let entry handle it. */
+}
+
+static void
+entry_activate_cb(GtkWidget * entry, GnomeAppBar * ab)
+{
+  gtk_signal_emit(GTK_OBJECT(ab), appbar_signals[USER_RESPONSE]);
+}
+
+static void
+gnome_appbar_init (GnomeAppBar *ab)
+{
+  ab->_priv                 = g_new0(GnomeAppBarPrivate, 1);
+  ab->_priv->default_status = NULL;
+  ab->_priv->status_stack   = NULL;
+  ab->_priv->editable_start = 0;
+  ab->_priv->prompt         = NULL;
+}
+
+
+/**
+ * gnome_appbar_new
+ * @has_progress: %TRUE if appbar needs progress bar widget, %FALSE if not
+ * @has_status: %TRUE if appbar needs status bar widget, %FALSE if not
+ * @interactivity: Level of user activity required
+ *
+ * Description:
+ * Create a new GNOME application status bar.  If @has_progress is
+ * %TRUE, a small progress bar widget will be created, and placed on the
+ * left side of the appbar.  If @has_status is %TRUE, a status bar,
+ * possibly an editable one, is created.
+ *
+ * @interactivity determines whether the appbar is an interactive
+ * "minibuffer" or just a status bar.  If it is set to
+ * %GNOME_PREFERENCES_NEVER, it is never interactive.  If it is set to
+ * %GNOME_PREFERENCES_USER we respect user preferences from
+ * ui-properties. If it's %GNOME_PREFERENCES_ALWAYS we are interactive
+ * whether the user likes it or not. Basically, if your app supports
+ * both interactive and not (for example, if you use the
+ * gnome-app-util interfaces), you should use
+ * %GNOME_PREFERENCES_USER. Otherwise, use the setting you
+ * support. Please note that "interactive" mode is not functional now;
+ * GtkEntry is inadequate and so a custom widget will be written
+ * eventually.
+ *
+ *
+ * Returns:  Pointer to new GNOME appbar widget.
+ **/
+
+GtkWidget* 
+gnome_appbar_new (gboolean has_progress,
+		  gboolean has_status,
+		  GnomePreferencesType interactivity)
+{
+  GnomeAppBar * ab = gtk_type_new (gnome_appbar_get_type ());
+
+  gnome_appbar_construct(ab, has_progress, has_status, interactivity);
+
+  return GTK_WIDGET(ab);
+}
+
+
+/**
+ * gnome_appbar_construct
+ * @ab: Pointer to GNOME appbar object.
+ * @has_progress: %TRUE if appbar needs progress bar widget.
+ * @has_status: %TRUE if appbar needs status bar widget.
+ * @interactivity: See gnome_appbar_new() explanation.
+ *
+ * Description:
+ * For use to bindings in languages other than C. Don't use.
+ **/
+
+void
+gnome_appbar_construct(GnomeAppBar * ab,
+		       gboolean has_progress,
+		       gboolean has_status,
+		       GnomePreferencesType interactivity)
+{
+  GtkBox *box;
+
+  /* These checks are kind of gross because an unfinished object will
+     be returned from _new instead of NULL */
+
+  /* Can't be interactive if there's no status bar */
+  g_return_if_fail( ((has_status == FALSE) && 
+		     (interactivity == GNOME_PREFERENCES_NEVER)) ||
+		    (has_status == TRUE)); 
+
+  box = GTK_BOX (ab);
+
+  box->spacing = GNOME_PAD_SMALL;
+  box->homogeneous = FALSE;
+
+  if (has_progress)
+    ab->_priv->progress = gtk_progress_bar_new();
+  else
+    ab->_priv->progress = NULL;
+
+  /*
+   * If the progress meter goes on the right then we place it after we
+   * create the status line.
+   */
+  if (has_progress && !gnome_preferences_get_statusbar_meter_on_right ())
+    gtk_box_pack_start (box, ab->_priv->progress, FALSE, FALSE, 0);
+
+  if ( has_status ) {
+    if ( (interactivity == GNOME_PREFERENCES_ALWAYS) ||
+	 ( (interactivity == GNOME_PREFERENCES_USER) &&
+	   gnome_preferences_get_statusbar_interactive()) ) {
+      ab->_priv->interactive = TRUE;
+   
+      ab->_priv->status = gtk_entry_new();
+
+      gtk_signal_connect (GTK_OBJECT(ab->_priv->status), "delete_text",
+			  GTK_SIGNAL_FUNC(entry_delete_text_cb),
+			  ab);
+      gtk_signal_connect (GTK_OBJECT(ab->_priv->status), "insert_text",
+			  GTK_SIGNAL_FUNC(entry_insert_text_cb),
+			  ab);
+      gtk_signal_connect_after(GTK_OBJECT(ab->_priv->status), "key_press_event",
+			       GTK_SIGNAL_FUNC(entry_key_press_cb),
+			       ab);
+      gtk_signal_connect(GTK_OBJECT(ab->_priv->status), "activate",
+			 GTK_SIGNAL_FUNC(entry_activate_cb),
+			 ab);
+
+      /* no prompt now */
+      gtk_entry_set_editable(GTK_ENTRY(ab->_priv->status), FALSE);
+
+      gtk_box_pack_start (box, ab->_priv->status, TRUE, TRUE, 0);
+    }
+    else {
+      GtkWidget * frame;
+      
+      ab->_priv->interactive = FALSE;
+
+      frame = gtk_frame_new (NULL);
+      gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
+      
+      ab->_priv->status = gtk_label_new ("");
+      gtk_misc_set_alignment (GTK_MISC (ab->_priv->status), 0.0, 0.0);
+      gtk_widget_set_usize (ab->_priv->status, 1, -1);
+      
+      gtk_box_pack_start (box, frame, TRUE, TRUE, 0);
+      gtk_container_add (GTK_CONTAINER(frame), ab->_priv->status);
+      
+      gtk_widget_show (frame);
+    }
+  }
+  else {
+    ab->_priv->status = NULL;
+    ab->_priv->interactive = FALSE;
+  }
+
+  if (has_progress && gnome_preferences_get_statusbar_meter_on_right ())
+    gtk_box_pack_start (box, ab->_priv->progress, FALSE, FALSE, 0);
+
+  if (ab->_priv->status) gtk_widget_show (ab->_priv->status);
+  if (ab->_priv->progress) gtk_widget_show(ab->_priv->progress);
+}
+
+
+/**
+ * gnome_appbar_set_prompt
+ * @appbar: Pointer to GNOME appbar object.
+ * @prompt: Text of the prompt message.
+ * @modal: If %TRUE, grabs input.
+ *
+ * Description:
+ * Put a prompt in the appbar and wait for a response. When the
+ * user responds or cancels, a user_response signal is emitted.
+ **/
+
+void
+gnome_appbar_set_prompt (GnomeAppBar * appbar, 
+			 const gchar * prompt,
+			 gboolean modal)
+{
+  g_return_if_fail(appbar != NULL);
+  g_return_if_fail(prompt != NULL);
+  g_return_if_fail(appbar->_priv->interactive);
+
+  /* Remove anything old. */
+  if (appbar->_priv->prompt) {
+    gnome_appbar_clear_prompt(appbar);
+  }
+
+  appbar->_priv->prompt = g_strconcat(prompt, "  ", NULL);
+
+  if (modal) gtk_grab_add(appbar->_priv->status);
+
+  gnome_appbar_refresh(appbar);
+}
+
+
+/**
+ * gnome_appbar_clear_prompt
+ * @appbar: Pointer to GNOME appbar object
+ *
+ * Description:
+ * Remove any prompt.
+ **/
+
+void       
+gnome_appbar_clear_prompt    (GnomeAppBar * appbar)
+{
+  g_return_if_fail(appbar != NULL);
+  g_return_if_fail(appbar->_priv->interactive);
+
+  /* This isn't really right; most of Gtk would only emit here,
+     and then have a clear_prompt_real as default handler. */
+  
+  g_free(appbar->_priv->prompt);
+  appbar->_priv->prompt = NULL;
+
+  gnome_appbar_refresh(appbar);
+
+  gtk_signal_emit(GTK_OBJECT(appbar), 
+		  appbar_signals[CLEAR_PROMPT]);  
+}
+
+
+/**
+ * gnome_appbar_get_response
+ * @appbar: Pointer to GNOME appbar object
+ *
+ * Description:
+ * Get the response to the prompt, if any. Result must be g_free'd.
+ *
+ * Returns:
+ * Text from appbar entry widget, as entered by user.
+ **/
+
+gchar *    
+gnome_appbar_get_response    (GnomeAppBar * appbar)
+{
+  g_return_val_if_fail(appbar != NULL, NULL);
+  g_return_val_if_fail(appbar->_priv->interactive, NULL);
+  g_return_val_if_fail(appbar->_priv->prompt != NULL, NULL);
+  
+  /* This returns an allocated string. */
+  return gtk_editable_get_chars(GTK_EDITABLE(appbar->_priv->status),
+				appbar->_priv->editable_start, 
+				GTK_ENTRY(appbar->_priv->status)->text_length);
+} 
+
+
+/**
+ * gnome_appbar_refresh
+ * @appbar: Pointer to GNOME appbar object
+ *
+ * Description:
+ * Reflect the current state of stack/default. Useful to force a
+ * set_status to disappear.
+ **/
+
+void 
+gnome_appbar_refresh           (GnomeAppBar * appbar)
+{
+  g_return_if_fail(appbar != NULL);
+  g_return_if_fail(GNOME_IS_APPBAR(appbar));
+  
+  if (appbar->_priv->prompt) {
+    g_return_if_fail(appbar->_priv->interactive); /* Just a consistency check */
+    gtk_entry_set_editable(GTK_ENTRY(appbar->_priv->status), TRUE);
+    /* Allow insert_text to work, so we can set the prompt. */
+    appbar->_priv->editable_start = 0;
+    gtk_entry_set_text(GTK_ENTRY(appbar->_priv->status), appbar->_priv->prompt);
+    /* This has to be after setting the text. */
+    appbar->_priv->editable_start = strlen(appbar->_priv->prompt);   
+    gtk_entry_set_position(GTK_ENTRY(appbar->_priv->status), 
+			   appbar->_priv->editable_start);
+    gtk_widget_grab_focus(appbar->_priv->status);
+  }
+  else {
+    if (appbar->_priv->interactive) {
+      appbar->_priv->editable_start = 0;
+      gtk_entry_set_editable(GTK_ENTRY(appbar->_priv->status), FALSE);
+      gtk_grab_remove(appbar->_priv->status); /* In case */
+    }
+
+    if (appbar->_priv->status_stack)
+      gnome_appbar_set_status(appbar, stringstack_top(appbar->_priv->status_stack));
+    else if (appbar->_priv->default_status)
+      gnome_appbar_set_status(appbar, appbar->_priv->default_status);
+    else 
+      gnome_appbar_set_status(appbar, "");
+  }
+}
+
+
+/**
+ * gnome_appbar_set_status
+ * @appbar: Pointer to GNOME appbar object.
+ * @status: Text to which status label will be set.
+ *
+ * Description:
+ * Sets the status label without changing widget state; next set or push
+ * will destroy this permanently. 
+ **/
+
+void       
+gnome_appbar_set_status       (GnomeAppBar * appbar,
+			       const gchar * status)
+{
+  g_return_if_fail(appbar != NULL);
+  g_return_if_fail(status != NULL);
+  g_return_if_fail(GNOME_IS_APPBAR(appbar));
+
+  if (appbar->_priv->interactive) 
+    gtk_entry_set_text(GTK_ENTRY(appbar->_priv->status), status);
+  else
+    gtk_label_set_text(GTK_LABEL(appbar->_priv->status), status);
+}
+
+
+/**
+ * gnome_appbar_set_default
+ * @appbar: Pointer to GNOME appbar object
+ * @default_status: Text for status label
+ *
+ * Description:
+ * What to show when showing nothing else; defaults to nothing.
+ **/
+
+void	   
+gnome_appbar_set_default      (GnomeAppBar * appbar,
+			       const gchar * default_status)
+{
+  g_return_if_fail(appbar != NULL);
+  g_return_if_fail(default_status != NULL);
+  g_return_if_fail(GNOME_IS_APPBAR(appbar));
+  
+  /* g_free handles NULL */
+  g_free(appbar->_priv->default_status);
+  appbar->_priv->default_status = g_strdup(default_status);
+  gnome_appbar_refresh(appbar);
+}
+
+
+/**
+ * gnome_appbar_push
+ * @appbar: Pointer to GNOME appbar object
+ * @status: Text of status message.
+ *
+ * Description:
+ * Push a new status message onto the status bar stack, and
+ * display it.
+ **/
+
+void       
+gnome_appbar_push             (GnomeAppBar * appbar,
+			       const gchar * status)
+{
+  g_return_if_fail(appbar != NULL);
+  g_return_if_fail(status != NULL);
+  g_return_if_fail(GNOME_IS_APPBAR(appbar));
+
+  appbar->_priv->status_stack = stringstack_push(appbar->_priv->status_stack, status);
+  gnome_appbar_refresh(appbar);
+}
+
+
+/**
+ * gnome_appbar_pop
+ * @appbar: Pointer to GNOME appbar object
+ *
+ * Description:
+ * Remove current status message, and display previous status
+ * message, if any.  It is OK to call this with an empty stack.
+ **/
+
+void       
+gnome_appbar_pop              (GnomeAppBar * appbar)
+{
+  g_return_if_fail(appbar != NULL);
+  g_return_if_fail(GNOME_IS_APPBAR(appbar));
+  
+  appbar->_priv->status_stack = stringstack_pop(appbar->_priv->status_stack);
+  gnome_appbar_refresh(appbar);
+}
+
+
+/**
+ * gnome_appbar_clear_stack
+ * @appbar: Pointer to GNOME appbar object
+ *
+ * Description:
+ * Remove all status messages from appbar, and display default status
+ * message (if present).
+ **/
+
+void       
+gnome_appbar_clear_stack      (GnomeAppBar * appbar)
+{
+  g_return_if_fail(appbar != NULL);
+  g_return_if_fail(GNOME_IS_APPBAR(appbar));
+
+  stringstack_free(appbar->_priv->status_stack);
+  appbar->_priv->status_stack = NULL;
+  gnome_appbar_refresh(appbar);
+}
+
+
+/**
+ * gnome_appbar_set_progress_precentage
+ * @appbar: Pointer to GNOME appbar object
+ * @percentage: Percentage to which progress bar should be set.
+ *
+ * Description:
+ * Sets progress bar to the given percentage.
+ **/
+
+void
+gnome_appbar_set_progress_percentage(GnomeAppBar *appbar,
+				     gfloat percentage)
+{
+  g_return_if_fail (appbar != NULL);
+  g_return_if_fail (appbar->_priv->progress != NULL);
+  g_return_if_fail (GNOME_IS_APPBAR(appbar));
+
+  gtk_progress_bar_update(GTK_PROGRESS_BAR(appbar->_priv->progress), percentage);
+}
+
+
+/**
+ * gnome_appbar_get_progress
+ * @appbar: Pointer to GNOME appbar object
+ *
+ * Description:
+ * Returns &GtkProgress widget pointer, so that the progress bar may be
+ * manipulated further.
+ *
+ * Returns:
+ * Pointer to appbar's progress bar object. May be NULL if the appbar
+ * has no progress object.
+ **/
+
+GtkProgress* 
+gnome_appbar_get_progress    (GnomeAppBar * appbar)
+{
+  g_return_val_if_fail(appbar != NULL, NULL);
+  g_return_val_if_fail(GNOME_IS_APPBAR(appbar), NULL);
+  g_return_val_if_fail(appbar->_priv->progress != NULL, NULL);
+
+  return GTK_PROGRESS(appbar->_priv->progress);
+}
+
+/**
+ * gnome_appbar_get_status
+ * @appbar: Pointer to GNOME appbar object
+ *
+ * Description:
+ * Returns the statusbar widget.
+ *
+ * Returns:
+ * A pointer to the statusbar widget.
+ **/
+GtkWidget *
+gnome_appbar_get_status    (GnomeAppBar * appbar)
+{
+  g_return_val_if_fail(appbar != NULL, NULL);
+  g_return_val_if_fail(GNOME_IS_APPBAR(appbar), NULL);
+
+  return (appbar->_priv->status);
+}
+
+static void
+gnome_appbar_destroy (GtkObject *object)
+{
+  GnomeAppBar *ab;
+  GnomeAppBarClass *class;
+
+  /* remember, destroy can be run multiple times! */
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GNOME_IS_APPBAR (object));
+
+  ab = GNOME_APPBAR (object);
+  class = GNOME_APPBAR_GET_CLASS (ab);
+
+  if(ab->_priv->status_stack) {
+	  stringstack_free(ab->_priv->status_stack);
+	  ab->_priv->status_stack = NULL;
+  }
+
+  /* g_free checks if these are NULL */
+  g_free(ab->_priv->default_status);
+  ab->_priv->default_status = NULL;;
+  g_free(ab->_priv->prompt);
+  ab->_priv->prompt = NULL;
+
+  if(GTK_OBJECT_CLASS (parent_class)->destroy)
+	  GTK_OBJECT_CLASS (parent_class)->destroy (object);
+}
+
+static void
+gnome_appbar_finalize (GObject *object)
+{
+  GnomeAppBar *ab;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GNOME_IS_APPBAR (object));
+
+  ab = GNOME_APPBAR (object);
+
+  g_free(ab->_priv);
+  ab->_priv = NULL;
+
+  if(G_OBJECT_CLASS (parent_class)->finalize)
+	  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
diff --git a/libgnomeui/gnome-appbar.h b/libgnomeui/gnome-appbar.h
new file mode 100644
index 0000000..8334c7d
--- /dev/null
+++ b/libgnomeui/gnome-appbar.h
@@ -0,0 +1,138 @@
+/* gnome-appbar.h: statusbar/progress/minibuffer widget for Gnome apps
+ * 
+ * This version by Havoc Pennington
+ * Based on MozStatusbar widget, by Chris Toshok
+ * In turn based on GtkStatusbar widget, from Gtk+,
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ * GtkStatusbar Copyright (C) 1998 Shawn T. Amundson
+ * All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#ifndef __GNOME_APPBAR_H__
+#define __GNOME_APPBAR_H__
+
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkprogress.h>
+
+
+#include "gnome-types.h"
+
+G_BEGIN_DECLS
+
+#define GNOME_TYPE_APPBAR            (gnome_appbar_get_type ())
+#define GNOME_APPBAR(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_APPBAR, GnomeAppBar))
+#define GNOME_APPBAR_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_APPBAR, GnomeAppBarClass))
+#define GNOME_IS_APPBAR(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_APPBAR))
+#define GNOME_IS_APPBAR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_APPBAR))
+#define GNOME_APPBAR_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_APPBAR, GnomeAppBarClass))
+
+/* Used in gnome-app-util to determine the capabilities of the appbar */
+#define GNOME_APPBAR_HAS_STATUS(appbar) (gnome_appbar_get_status(GNOME_APPBAR(appbar)) != NULL)
+#define GNOME_APPBAR_HAS_PROGRESS(appbar) (gnome_appbar_get_progress(GNOME_APPBAR(appbar)) != NULL)
+
+typedef struct _GnomeAppBar        GnomeAppBar;
+typedef struct _GnomeAppBarPrivate GnomeAppBarPrivate;
+typedef struct _GnomeAppBarClass   GnomeAppBarClass;
+typedef struct _GnomeAppBarMsg     GnomeAppBarMsg;
+
+struct _GnomeAppBar
+{
+  GtkHBox parent_widget;
+
+  /*< private >*/
+  GnomeAppBarPrivate *_priv;
+};
+
+struct _GnomeAppBarClass
+{
+  GtkHBoxClass parent_class;
+
+  /* Emitted when the user hits enter after a prompt. */
+  void (* user_response) (GnomeAppBar * ab);
+  /* Emitted when the prompt is cleared. */
+  void (* clear_prompt)  (GnomeAppBar * ab);
+};
+
+#define GNOME_APPBAR_INTERACTIVE(ab) ((ab) ? (ab)->interactive : FALSE)
+
+guint      gnome_appbar_get_type     	(void) G_GNUC_CONST;
+
+GtkWidget* gnome_appbar_new          	(gboolean has_progress, 
+					 gboolean has_status,
+					 GnomePreferencesType interactivity);
+
+/* Sets the status label without changing widget state; next set or push
+   will destroy this permanently. */
+void       gnome_appbar_set_status       (GnomeAppBar * appbar,
+					  const gchar * status);
+
+/* get the statusbar */
+GtkWidget* gnome_appbar_get_status       (GnomeAppBar * appbar);
+
+/* What to show when showing nothing else; defaults to nothing */
+void	   gnome_appbar_set_default      (GnomeAppBar * appbar,
+					  const gchar * default_status);
+
+void       gnome_appbar_push             (GnomeAppBar * appbar,
+					  const gchar * status);
+/* OK to call on empty stack */
+void       gnome_appbar_pop              (GnomeAppBar * appbar);
+
+/* Nuke the stack. */
+void       gnome_appbar_clear_stack      (GnomeAppBar * appbar);
+
+/* Sugar function to set the percentage of the progressbar. */
+void	     gnome_appbar_set_progress_percentage	  (GnomeAppBar *appbar,
+							   gfloat percentage);
+/* use GtkProgress functions on returned value */
+GtkProgress* gnome_appbar_get_progress    (GnomeAppBar * appbar);
+
+/* Reflect the current state of stack/default. Useful to force a set_status
+   to disappear. */
+void       gnome_appbar_refresh         (GnomeAppBar * appbar);
+
+/* Put a prompt in the appbar and wait for a response. When the 
+   user responds or cancels, a user_response signal is emitted. */
+void       gnome_appbar_set_prompt          (GnomeAppBar * appbar,
+					     const gchar * prompt,
+					     gboolean modal);
+/* Remove any prompt */
+void       gnome_appbar_clear_prompt    (GnomeAppBar * appbar);
+
+/* Get the response to the prompt, if any. Result must be g_free'd. */
+gchar *    gnome_appbar_get_response    (GnomeAppBar * appbar);
+
+
+/* For use to bindings in languages other than C. Don't use. */
+void       gnome_appbar_construct(GnomeAppBar * ab,
+				  gboolean has_progress,
+				  gboolean has_status,
+				  GnomePreferencesType interactivity);
+
+G_END_DECLS
+
+#endif /* __GNOME_APPBAR_H__ */
+
+
+
+
+
+
+
diff --git a/libgnomeui/gnome-boxed.defs b/libgnomeui/gnome-boxed.defs
new file mode 100644
index 0000000..7d7ca3c
--- /dev/null
+++ b/libgnomeui/gnome-boxed.defs
@@ -0,0 +1,12 @@
+; -*- scheme -*-
+
+; These definitions here cause the creation of some new GTK_TYPE_* ids
+; The code doesn't benefit most C programs directly, but is very useful
+; for language bindings.
+
+(define-boxed GnomeSelectorAsyncHandle
+  #f
+  gnome_selector_async_handle_ref
+  gnome_selector_async_handle_unref
+  #t
+)
diff --git a/libgnomeui/gnome-canvas-init.c b/libgnomeui/gnome-canvas-init.c
new file mode 100644
index 0000000..cdf32dd
--- /dev/null
+++ b/libgnomeui/gnome-canvas-init.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 1999, 2000 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#include <config.h>
+#include <gobject/genums.h>
+#include <gobject/gboxed.h>
+#include <gtk/gtk.h>
+
+#include <libgnomecanvas/libgnomecanvas.h>
+#include <libgnome/libgnome.h>
+
+static void
+add_gtk_arg_callback (poptContext con, enum poptCallbackReason reason,
+		      const struct poptOption * opt,
+		      const char * arg, void * data);
+
+static void
+gtk_pre_args_parse (GnomeProgram *program, GnomeModuleInfo *mod_info);
+
+static void
+gtk_post_args_parse (GnomeProgram *program, GnomeModuleInfo *mod_info);
+
+static struct poptOption gtk_options [] = {
+	{ NULL, '\0', POPT_ARG_CALLBACK|POPT_CBFLAG_PRE,
+	  &add_gtk_arg_callback, 0, NULL, NULL },
+
+	{ NULL, '\0', POPT_ARG_INTL_DOMAIN, PACKAGE, 0, NULL, NULL },
+
+	{ "gdk-debug", '\0', POPT_ARG_STRING, NULL, 0,
+	  N_("Gdk debugging flags to set"), N_("FLAGS")},
+
+	{ "gdk-no-debug", '\0', POPT_ARG_STRING, NULL, 0,
+	  N_("Gdk debugging flags to unset"), N_("FLAGS")},
+
+	{ "display", '\0', POPT_ARG_STRING, NULL, 0,
+	  N_("X display to use"), N_("DISPLAY")},
+
+	{ "sync", '\0', POPT_ARG_NONE, NULL, 0,
+	  N_("Make X calls synchronous"), NULL},
+
+	{ "no-xshm", '\0', POPT_ARG_NONE, NULL, 0,
+	  N_("Don't use X shared memory extension"), NULL},
+
+	{ "name", '\0', POPT_ARG_STRING, NULL, 0,
+	  N_("Program name as used by the window manager"), N_("NAME")},
+
+	{ "class", '\0', POPT_ARG_STRING, NULL, 0,
+	  N_("Program class as used by the window manager"), N_("CLASS")},
+
+	{ "gxid_host", '\0', POPT_ARG_STRING, NULL, 0,
+	  NULL, N_("HOST")},
+
+	{ "gxid_port", '\0', POPT_ARG_STRING, NULL, 0,
+	  NULL, N_("PORT")},
+
+	{ "xim-preedit", '\0', POPT_ARG_STRING, NULL, 0,
+	  NULL, N_("STYLE")},
+
+	{ "xim-status", '\0', POPT_ARG_STRING, NULL, 0,
+	  NULL, N_("STYLE")},
+
+	{ "gtk-debug", '\0', POPT_ARG_STRING, NULL, 0,
+	  N_("Gtk+ debugging flags to set"), N_("FLAGS")},
+
+	{ "gtk-no-debug", '\0', POPT_ARG_STRING, NULL, 0,
+	  N_("Gtk+ debugging flags to unset"), N_("FLAGS")},
+
+	{ "g-fatal-warnings", '\0', POPT_ARG_NONE, NULL, 0,
+	  N_("Make all warnings fatal"), NULL},
+
+	{ "gtk-module", '\0', POPT_ARG_STRING, NULL, 0,
+	  N_("Load an additional Gtk module"), N_("MODULE")},
+
+	{ NULL, '\0', 0, NULL, 0}
+};
+
+static GnomeModuleRequirement gtk_requirements [] = {
+	/* We require libgnome setup to be run first as it
+	 * initializes the type system and some other stuff. */
+	{ VERSION, &libgnome_module_info } ,
+	{ NULL, NULL }
+};
+
+GnomeModuleInfo gtk_module_info = {
+	"gtk", GTK_VERSION, "GTK+",
+	gtk_requirements,
+	gtk_pre_args_parse, gtk_post_args_parse, NULL,
+	NULL,
+	NULL, NULL, NULL
+};
+
+static void
+libgnomecanvas_pre_args_parse (GnomeProgram *program,
+			       GnomeModuleInfo *mod_info);
+
+static GnomeModuleRequirement libgnomecanvas_requirements [] = {
+	{ GTK_VERSION, &gtk_module_info },
+	{ NULL, NULL }
+};
+
+GnomeModuleInfo libgnomecanvas_module_info = {
+	"libgnomecanvas", VERSION, "GNOME Canvas",
+	libgnomecanvas_requirements,
+	libgnomecanvas_pre_args_parse, NULL, NULL,
+	NULL,
+	NULL, NULL, NULL
+};
+
+typedef struct {
+	GPtrArray *gtk_args;
+} gnome_gtk_init_info;
+
+static void
+gtk_pre_args_parse (GnomeProgram *program, GnomeModuleInfo *mod_info)
+{
+	struct poptOption *options, *ptr;
+	gnome_gtk_init_info *init_info = g_new0 (gnome_gtk_init_info, 1);
+	guint count = 1;
+
+	for (ptr = gtk_options;
+	     (ptr->argInfo != POPT_ARG_NONE) || (ptr->descrip != NULL);
+	     ptr++)
+		count++;
+
+	options = g_memdup (gtk_options, sizeof (struct poptOption) * count);
+	options->descrip = (const char *) init_info;
+
+	init_info->gtk_args = g_ptr_array_new ();
+
+	mod_info->options = options;
+}
+
+static void
+gtk_post_args_parse (GnomeProgram *program, GnomeModuleInfo *mod_info)
+{
+	gnome_gtk_init_info *init_info;
+	int final_argc;
+	char **final_argv;
+
+	g_message (G_STRLOC);
+
+	init_info = (gnome_gtk_init_info *) mod_info->options [0].descrip;
+
+	g_ptr_array_add (init_info->gtk_args, NULL);
+
+	final_argc = init_info->gtk_args->len - 1;
+	final_argv = g_memdup (init_info->gtk_args->pdata,
+			       sizeof (char *) * init_info->gtk_args->len);
+
+	gtk_init (&final_argc, &final_argv);
+
+	gdk_rgb_init();
+
+	g_free (mod_info->options);
+	mod_info->options = NULL;
+
+	g_ptr_array_free (init_info->gtk_args, TRUE);
+	g_free (init_info);
+}
+
+static void
+add_gtk_arg_callback (poptContext con, enum poptCallbackReason reason,
+		      const struct poptOption * opt,
+		      const char * arg, void * data)
+{
+	gnome_gtk_init_info *init_info = data;
+	char *newstr;
+
+	g_message (G_STRLOC ": %p", data);
+
+	switch (reason) {
+	case POPT_CALLBACK_REASON_PRE:
+		/* Note that the value of argv[0] passed to main() may be
+		 * different from the value that this passes to gtk
+		 */
+		g_ptr_array_add (init_info->gtk_args,
+				 (char *) g_strdup (poptGetInvocationName (con)));
+		break;
+		
+	case POPT_CALLBACK_REASON_OPTION:
+		switch (opt->argInfo) {
+		case POPT_ARG_STRING:
+		case POPT_ARG_INT:
+		case POPT_ARG_LONG:
+			newstr = g_strconcat ("--", opt->longName, "=", arg, NULL);
+			break;
+		default:
+			newstr = g_strconcat ("--", opt->longName, NULL);
+			break;
+		}
+
+		g_ptr_array_add (init_info->gtk_args, newstr);
+		/* XXX gnome-client tie-in */
+		break;
+	default:
+		break;
+	}
+}
+
+static void
+libgnomecanvas_pre_args_parse (GnomeProgram *program,
+			       GnomeModuleInfo *mod_info)
+{
+	libgnomecanvas_init ();
+}
diff --git a/libgnomeui/gnome-canvas-init.h b/libgnomeui/gnome-canvas-init.h
new file mode 100644
index 0000000..a9404f4
--- /dev/null
+++ b/libgnomeui/gnome-canvas-init.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#ifndef GNOME_CANVAS_INIT_H
+#define GNOME_CANVAS_INIT_H
+
+#include <libgnome/gnome-program.h>
+
+G_BEGIN_DECLS
+
+extern GnomeModuleInfo gtk_module_info;
+extern GnomeModuleInfo libgnomecanvas_module_info;
+
+G_END_DECLS
+
+#endif
diff --git a/libgnomeui/gnome-client.c b/libgnomeui/gnome-client.c
new file mode 100644
index 0000000..b9ce3c5
--- /dev/null
+++ b/libgnomeui/gnome-client.c
@@ -0,0 +1,2694 @@
+/* gnome-client.c - GNOME session management client support
+ *
+ * Copyright (C) 1998, 1999 Carsten Schaar
+ * All rights reserved.
+ *
+ * Author: Carsten Schaar <nhadcasc fs-maphy uni-hannover de>
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#include <config.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <pwd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <errno.h>
+
+#include <libgnome/gnome-i18n.h>
+#include "gnome-client.h"
+#include "gnome-stock.h"
+#include "gnome-uidefs.h"
+#include "gnome-ice.h"
+#include "gnome-winhints.h"
+#include <gtk/gtk.h>
+#include <gdk/gdkprivate.h>
+#include <X11/Xatom.h>
+
+#include <libgnomeuiP.h>
+
+extern char *program_invocation_name;
+extern char *program_invocation_short_name;
+
+#ifdef HAVE_LIBSM
+#include <X11/SM/SMlib.h>
+#endif /* HAVE_LIBSM */
+
+static GtkWidget *client_grab_widget = NULL;
+
+enum {
+  SAVE_YOURSELF,
+  DIE,
+  SAVE_COMPLETE,
+  SHUTDOWN_CANCELLED,
+  CONNECT,
+  DISCONNECT,
+  LAST_SIGNAL
+};
+
+static void gnome_client_class_init              (GnomeClientClass *klass);
+static void gnome_client_object_init             (GnomeClient      *client);
+
+static void gnome_real_client_destroy            (GtkObject        *object);
+static void gnome_real_client_save_complete      (GnomeClient      *client);
+static void gnome_real_client_shutdown_cancelled (GnomeClient      *client);
+static void gnome_real_client_connect            (GnomeClient      *client,
+						  gint              restarted);
+static void gnome_real_client_disconnect         (GnomeClient      *client);
+static void master_client_connect (GnomeClient *client,
+				   gint         restarted,
+				   gpointer     client_data);
+static void master_client_disconnect (GnomeClient *client,
+				      gpointer     client_data);
+
+
+static void   client_unset_config_prefix    (GnomeClient *client);
+
+static gchar** array_init_from_arg           (gint argc, 
+					      gchar *argv[]);
+
+static GtkObjectClass *parent_class = NULL;
+static gint client_signals[LAST_SIGNAL] = { 0 };
+
+static const char *sm_client_id_arg_name G_GNUC_UNUSED = "--sm-client-id";
+static const char *sm_config_prefix_arg_name G_GNUC_UNUSED = "--sm-config-prefix";
+
+/* The master client.  */
+static GnomeClient *master_client= NULL;
+
+static gboolean master_client_restored= FALSE;
+
+/*****************************************************************************/
+/* Managing the interaction keys. */
+
+/* The following function handle the interaction keys.  Each time an
+   application requests interaction an interaction key is created.  If
+   the session manager decides, that a client may interact now, the
+   application is given the according interaction key.  No other
+   interaction may take place, until the application returns the
+   application key.  */
+
+#ifdef HAVE_LIBSM
+
+typedef struct _InteractionKey InteractionKey;
+
+
+struct _InteractionKey
+{
+  gint                   tag;
+  GnomeClient           *client;
+  GnomeDialogType        dialog_type;
+  gboolean               in_use;
+  gboolean               interp;
+  GnomeInteractFunction  function;
+  gpointer               data;
+  GtkDestroyNotify       destroy;
+};
+
+
+/* List of all existing interaction keys.  */
+static GList *interact_functions = NULL;
+
+
+static InteractionKey *
+interaction_key_new (GnomeClient           *client,
+		     GnomeDialogType        dialog_type,
+		     gboolean               interp,
+		     GnomeInteractFunction  function,
+		     gpointer               data,
+		     GtkDestroyNotify       destroy)
+{
+  static gint tag= 1;
+  
+  InteractionKey *key= g_new (InteractionKey, 1);
+  
+  if (key)
+    {
+      key->tag        = tag++;
+      key->client     = client;
+      key->dialog_type= dialog_type;
+      key->in_use     = FALSE;
+      key->interp     = interp;
+      key->function   = function;
+      key->data       = data;
+      key->destroy    = destroy;
+
+      interact_functions= g_list_append (interact_functions, key);
+    }
+
+  return key;
+}
+
+
+static void
+interaction_key_destroy (InteractionKey *key)
+{
+  interact_functions= g_list_remove (interact_functions, key);
+  
+  if (key->destroy)
+    (key->destroy) (key->data);
+
+  g_free (key);
+}
+
+
+static void
+interaction_key_destroy_if_possible (InteractionKey *key)
+{
+  if (key->in_use)
+    key->client = NULL;
+  else
+    interaction_key_destroy (key);
+}
+
+
+static InteractionKey *
+interaction_key_find_by_tag (gint tag)
+{  
+  InteractionKey *key;
+  GList          *tmp= interact_functions;
+  
+  while (tmp)
+    {
+      key= (InteractionKey *) tmp->data;
+
+      if (key->tag == tag)
+	return key;
+            
+      tmp= tmp->next;
+    }
+
+  return NULL;
+}
+
+
+static void
+interaction_key_use (InteractionKey *key)
+{  
+  key->in_use= TRUE;
+
+  if (!key->interp)
+    key->function (key->client, key->tag, key->dialog_type, key->data);
+  else
+    {
+      GtkArg args[4];
+
+      args[0].name          = NULL;
+      args[0].type          = GTK_TYPE_NONE;
+
+      args[1].name          = NULL;
+      args[1].type          = GTK_TYPE_OBJECT;
+      args[1].d.pointer_data= &key->client;
+      
+      args[2].name          = NULL;
+      args[2].type          = GTK_TYPE_INT;
+      args[2].d.pointer_data= &key->tag;
+
+      args[3].name          = "GnomeDialogType";
+      args[3].type          = GNOME_TYPE_DIALOG_TYPE;
+      args[3].d.pointer_data= &key->dialog_type;
+
+      ((GtkCallbackMarshal)key->function) (NULL, key->data, 3, args);
+    }
+}
+
+#endif /* HAVE_LIBSM */
+
+
+/*****************************************************************************/
+/* Helper functions, that set session management properties.  */
+
+/* The following functions are used to set and unset session
+   management properties of a special type.  */
+
+#ifdef HAVE_LIBSM
+
+
+static void
+client_set_value (GnomeClient *client, 
+		  gchar       *name,
+		  char        *type,
+		  int          num_vals,
+		  SmPropValue *vals)
+{
+  SmProp *proplist[1];
+  SmProp prop;
+  
+  prop.name = name;
+  prop.type = type;
+  prop.num_vals = num_vals;
+  prop.vals = vals;
+
+  proplist[0]= &prop;  
+  SmcSetProperties ((SmcConn) client->smc_conn, 1, proplist);  
+}
+
+
+static void
+client_set_string (GnomeClient *client, gchar *name, gchar *value)
+{
+  SmPropValue val;
+
+  g_return_if_fail (name);
+
+  if (!GNOME_CLIENT_CONNECTED (client) || (value == NULL))
+    return;  
+
+  val.length = strlen (value)+1;
+  val.value  = value;
+
+  client_set_value (client, name, SmARRAY8, 1, &val);
+}
+
+
+static void
+client_set_gchar (GnomeClient *client, gchar *name, gchar value)
+{
+  SmPropValue val;
+
+  g_return_if_fail (name);
+
+  if (!GNOME_CLIENT_CONNECTED (client))
+    return;  
+
+  val.length = 1;
+  val.value  = &value;
+
+  client_set_value (client, name, SmCARD8, 1, &val);
+}
+
+
+static void
+client_set_ghash0 (gchar *key, gchar *value, SmPropValue **vals)
+{
+  (*vals)->length= strlen (key);
+  (*vals)->value = key;
+  (*vals)++;
+
+  (*vals)->length= strlen (value);
+  (*vals)->value = value;
+  (*vals)++;  
+}
+
+static void
+client_set_ghash (GnomeClient *client, gchar *name, GHashTable *table)
+{
+  gint    argc;
+  SmPropValue *vals;
+  SmPropValue *tmp;
+
+  g_return_if_fail (name);
+  g_return_if_fail (table);
+
+  if (!GNOME_CLIENT_CONNECTED (client))
+    return;
+  
+  argc = g_hash_table_size (table);
+
+  if (argc == 0) 
+    return;
+  
+  /* Now initialize the 'vals' array.  */
+  vals = g_new (SmPropValue, argc);
+  tmp = vals;
+  
+  g_hash_table_foreach (table, (GHFunc) client_set_ghash0, &tmp);
+  
+  client_set_value (client, name, SmLISTofARRAY8, argc, vals);
+
+  g_free (vals);
+  
+};
+
+
+static void
+client_set_array (GnomeClient *client, gchar *name, gchar *array[])
+{
+  gint    argc;
+  gchar **ptr;
+  gint    i;
+
+  SmPropValue *vals;
+  
+  g_return_if_fail (name);
+
+  if (!GNOME_CLIENT_CONNECTED (client) || (array == NULL))
+    return;
+
+  /* We count the number of elements in our array.  */
+  for (ptr = array, argc = 0; *ptr ; ptr++, argc++) /* LOOP */;
+
+  /* Now initialize the 'vals' array.  */
+  vals = g_new (SmPropValue, argc);
+  for (ptr = array, i = 0 ; i < argc ; ptr++, i++)
+    {
+      vals[i].length = strlen (*ptr);
+      vals[i].value  = *ptr;
+    }
+
+  client_set_value (client, name, SmLISTofARRAY8, argc, vals);
+
+  g_free (vals);
+}		   
+
+static void
+client_set_clone_command (GnomeClient *client)
+{
+  GList  *list;
+  gint    argc;
+  gchar **ptr;
+  gint    i = 0;
+
+  SmPropValue *vals;
+  
+  if (!GNOME_CLIENT_CONNECTED (client))
+    return;
+
+  ptr=client->clone_command ? client->clone_command : client->restart_command;
+
+  if (!ptr)
+    return;
+
+  for (argc = 0; *ptr ; ptr++) argc++;
+
+  /* Add space for static arguments and config prefix. */
+  argc += g_list_length (client->static_args) + 2;
+
+  vals = g_new (SmPropValue, argc);
+
+  ptr=client->clone_command ? client->clone_command : client->restart_command;
+
+  vals[i].length = strlen (*ptr);
+  vals[i++].value  = *ptr++;
+
+  if (client->config_prefix)
+    {
+      vals[i].length = strlen (sm_config_prefix_arg_name);
+      vals[i++].value = (char *) sm_config_prefix_arg_name;
+      vals[i].length = strlen (client->config_prefix);
+      vals[i++].value = client->config_prefix;
+    }
+
+  for (list = client->static_args; list; list= g_list_next (list))
+    {
+      vals[i].length= strlen ((gchar *)list->data);
+      vals[i++].value = (gchar *)list->data;
+    }
+
+  while (*ptr)
+    {
+      vals[i].length = strlen (*ptr);
+      vals[i++].value  = *ptr++;
+    }
+
+  client_set_value (client, SmCloneCommand, SmLISTofARRAY8, i, vals);
+  
+  g_free (vals);
+}		   
+
+static void
+client_set_restart_command (GnomeClient *client)
+{
+  GList  *list;
+  gint    argc;
+  gchar **ptr;
+  gint    i = 0;
+
+  SmPropValue *vals;
+  
+  if (!GNOME_CLIENT_CONNECTED (client) || (client->restart_command == NULL))
+    return;
+
+  for (ptr = client->restart_command, argc = 0; *ptr ; ptr++) argc++;
+
+  /* Add space for static arguments, config prefix and client id. */
+  argc += g_list_length (client->static_args) + 4;
+
+  vals = g_new (SmPropValue, argc);
+
+  ptr = client->restart_command;
+
+  vals[i].length = strlen (*ptr);
+  vals[i++].value  = *ptr++;
+
+  if (client->config_prefix)
+    {
+      vals[i].length = strlen (sm_config_prefix_arg_name);
+      vals[i++].value = (char *) sm_config_prefix_arg_name;
+      vals[i].length = strlen (client->config_prefix);
+      vals[i++].value = client->config_prefix;
+    }
+  vals[i].length = strlen (sm_client_id_arg_name);
+  vals[i++].value = (char *) sm_client_id_arg_name;
+  vals[i].length = strlen (client->client_id);
+  vals[i++].value = client->client_id;
+
+  for (list = client->static_args; list; list = g_list_next (list))
+    {
+      vals[i].length= strlen ((gchar *)list->data);
+      vals[i++].value = (gchar *)list->data;
+    }
+
+  while (*ptr)
+    {
+      vals[i].length = strlen (*ptr);
+      vals[i++].value  = *ptr++;
+    }
+
+  client_set_value (client, SmRestartCommand, SmLISTofARRAY8, i, vals);
+  
+  g_free (vals);
+}		   
+
+static void
+client_unset (GnomeClient *client, gchar *name)
+{
+  g_return_if_fail (name  != NULL);
+
+  if (GNOME_CLIENT_CONNECTED (client))
+    SmcDeleteProperties ((SmcConn) client->smc_conn, 1, &name);
+}
+
+#endif /* HAVE_LIBSM */
+
+static void
+client_set_state (GnomeClient *client, GnomeClientState state)
+{
+  client->state= state;
+}
+
+
+/*****************************************************************************/
+/* Callback functions  */
+
+/* The following functions are callback functions (and helper
+   functions).  They are registered in 'gnome_client_connect',
+   'gnome_interaction_key_return' and
+   'gnome_client_request_interaction_internal',
+   'client_save_yourself_callback'.  */
+
+#ifdef HAVE_LIBSM
+
+
+static void 
+client_save_phase_2_callback (SmcConn smc_conn, SmPointer client_data);
+
+static void
+client_save_yourself_possibly_done (GnomeClient *client)
+{
+  if (client->interaction_keys)
+    return;
+  
+  if ((client->state == GNOME_CLIENT_SAVING_PHASE_1) &&
+      client->save_phase_2_requested)
+    {
+      Status status;
+      
+      status= SmcRequestSaveYourselfPhase2 ((SmcConn) client->smc_conn,
+					    client_save_phase_2_callback,
+					    (SmPointer) client);
+
+      if (status)
+	client_set_state (client, GNOME_CLIENT_WAITING_FOR_PHASE_2);
+    }
+
+  if ((client->state == GNOME_CLIENT_SAVING_PHASE_1) ||
+      (client->state == GNOME_CLIENT_SAVING_PHASE_2))
+    {
+      SmcSaveYourselfDone ((SmcConn) client->smc_conn,
+			   client->save_successfull);
+      
+      if (client->shutdown)
+	client_set_state (client, GNOME_CLIENT_FROZEN);
+      else
+	client_set_state (client, GNOME_CLIENT_IDLE);
+    }
+}
+
+
+static void 
+client_save_phase_2_callback (SmcConn smc_conn, SmPointer client_data)
+{
+  GnomeClient *client= (GnomeClient*) client_data;
+  gboolean ret;
+
+  client_set_state (client, GNOME_CLIENT_SAVING_PHASE_2);
+ 
+  gtk_signal_emit (GTK_OBJECT (client), client_signals[SAVE_YOURSELF],
+		   2,
+		   client->save_style,
+		   client->shutdown,
+		   client->interact_style,
+		   client->fast,
+		   &ret);
+
+  client_save_yourself_possibly_done (client);
+}
+
+static gint
+end_wait (gpointer data)
+{
+  gboolean *waiting = (gboolean*)data;
+  *waiting = FALSE;
+  return 0;
+}
+
+static void
+client_save_yourself_callback (SmcConn   smc_conn,
+			       SmPointer client_data,
+			       int       save_style,
+			       Bool      shutdown,
+			       int       interact_style,
+			       Bool      fast)
+{
+  GnomeClient *client= (GnomeClient*) client_data;
+  gchar *name, *prefix;
+  int fd, len;
+  gboolean ret;
+
+  if (!client_grab_widget)
+    client_grab_widget = gtk_widget_new (gtk_widget_get_type(), NULL);
+
+  /* The first SaveYourself after registering for the first time
+   * is a special case (SM specs 7.2).
+   *
+   * This SaveYourself seems to be included in the protocol to
+   * ask the client to specify its initial SmProperties since 
+   * there is little point saving a copy of the initial state.
+   *
+   * A bug in xsm means that it does not send us a SaveComplete 
+   * in response to this initial SaveYourself. Therefore, we 
+   * must not set a grab because it would never be released.
+   * Indeed, even telling the app that this SaveYourself has
+   * arrived is hazardous as the app may take its own steps
+   * to freeze its WM state while waiting for the SaveComplete.
+   *
+   * Fortunately, we have already set the SmProperties during
+   * gnome_client_connect so there is little lost in simply
+   * returning immediately.
+   *
+   * Apps which really want to save their initial states can 
+   * do so safely using gnome_client_save_yourself_request. */
+
+  if (client->state == GNOME_CLIENT_REGISTERING)
+    {
+      client_set_state (client, GNOME_CLIENT_IDLE);
+
+      /* Double check that this is a section 7.2 SaveYourself: */
+      
+      if (save_style == SmSaveLocal && 
+	  interact_style == SmInteractStyleNone &&
+	  !shutdown && !fast)
+	{
+	  /* The protocol requires this even if xsm ignores it. */
+	  SmcSaveYourselfDone ((SmcConn) client->smc_conn, TRUE);
+	  return;
+	}
+    }
+
+  switch (save_style)
+    {
+    case SmSaveGlobal:
+      client->save_style= GNOME_SAVE_GLOBAL;
+      break;
+      
+    case SmSaveLocal:
+      client->save_style= GNOME_SAVE_LOCAL;
+      break;
+      
+    case SmSaveBoth:
+    default:
+      client->save_style= GNOME_SAVE_BOTH;
+      break;
+    }
+  client->shutdown= shutdown;
+  switch (interact_style)
+    {
+    case SmInteractStyleErrors:
+      client->interact_style= GNOME_INTERACT_ERRORS;
+      break;
+      
+    case SmInteractStyleAny:
+      client->interact_style= GNOME_INTERACT_ANY;
+      break;
+      
+    case SmInteractStyleNone:
+    default:
+      client->interact_style= GNOME_INTERACT_NONE;
+      break;
+    }
+  client->fast = fast;
+
+  client->save_phase_2_requested= FALSE;
+  client->save_successfull      = TRUE;
+  client->save_yourself_emitted = FALSE;
+
+  client_set_state (client, GNOME_CLIENT_SAVING_PHASE_1);
+
+  if (gdk_pointer_is_grabbed())
+    {
+      gboolean waiting = TRUE;
+      gint id = gtk_timeout_add (4000, end_wait, &waiting);
+
+      while (gdk_pointer_is_grabbed() && waiting)
+	gtk_main_iteration();
+      gtk_timeout_remove (id);
+    }
+
+  /* Check that we did not receive a shutdown cancelled while waiting 
+   * for the grab to be released. The grab should prevent it but ... */
+  if (client->state != GNOME_CLIENT_SAVING_PHASE_1)
+    return;
+
+  gdk_pointer_ungrab (GDK_CURRENT_TIME);
+  gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+  gtk_grab_add (client_grab_widget);
+
+  name = g_strdup (gnome_client_get_global_config_prefix(client));
+  name[strlen (name) - 1] = '\0';
+
+  prefix = g_strconcat (name, "-XXXXX", "/", NULL);
+  g_free (name);
+  len = strlen (prefix);
+
+  name = gnome_config_get_real_path (prefix);
+  g_free (prefix);
+
+  name [strlen (name) - 1] = 'X';
+  fd = mkstemp (name);
+
+  if (fd != -1)
+    {
+      unlink (name);
+      close (fd);
+      client->config_prefix = g_strconcat (name+strlen(name) - len, "/", NULL);
+
+      if (client == master_client)
+	{
+	  /* The config prefix has been changed, so it cannot be used
+             anymore to restore a saved session.  */
+	  master_client_restored= FALSE;
+	}
+    }
+  g_free (name);
+
+  client_set_clone_command (client);
+  client_set_restart_command (client);
+
+  gtk_signal_emit (GTK_OBJECT (client), 
+		   client_signals[SAVE_YOURSELF],
+		   1, 
+		   client->save_style, 
+		   shutdown, 
+		   client->interact_style, 
+		   fast,
+		   &ret);
+
+#ifdef BREAK_KDE_SESSION_MANAGER
+  /* <jsh> The KDE session manager actually cares about the `success'
+     field of the SaveYourselfDone message (unlike gnome-session, which
+     totally ignores it. Hence the code below has the effect of making
+     KDE unable to shutdown when any GNOME apps are running that haven't
+     connected to the "save_yourself" signal. */
+
+  if (!client->save_yourself_emitted)
+    client->save_successfull= FALSE;
+#endif
+
+  client_save_yourself_possibly_done (client);
+}
+
+
+static void
+client_die_callback (SmcConn smc_conn, SmPointer client_data)
+{
+  GnomeClient *client= (GnomeClient*) client_data;
+
+  if (client_grab_widget)
+    gtk_grab_remove (client_grab_widget);
+
+  gtk_signal_emit (GTK_OBJECT (client), client_signals[DIE]);
+}
+
+
+static void
+client_save_complete_callback (SmcConn smc_conn, SmPointer client_data)
+{
+  GnomeClient *client = (GnomeClient*) client_data;
+
+  if (client_grab_widget)
+    gtk_grab_remove (client_grab_widget);
+
+  gtk_signal_emit (GTK_OBJECT (client), client_signals[SAVE_COMPLETE]);
+}
+
+
+static void
+client_shutdown_cancelled_callback (SmcConn smc_conn, SmPointer client_data)
+{
+  GnomeClient *client= (GnomeClient*) client_data;
+
+  if (client_grab_widget)
+    gtk_grab_remove (client_grab_widget);
+
+  gtk_signal_emit (GTK_OBJECT (client), client_signals[SHUTDOWN_CANCELLED]);
+}
+
+
+static void 
+client_interact_callback (SmcConn smc_conn, SmPointer client_data)
+{
+  GnomeClient *client= (GnomeClient *) client_data;
+
+  if (client->interaction_keys)
+    {
+      GSList         *tmp= client->interaction_keys;
+      InteractionKey *key= (InteractionKey *) tmp->data;
+      
+      client->interaction_keys= g_slist_remove (tmp, tmp->data);
+      
+      interaction_key_use (key);
+    }
+  else
+    {
+      /* This branch should never be executed.  But if it is executed,
+         we just finish interacting.  */
+      SmcInteractDone ((SmcConn) client->smc_conn, FALSE);
+    }
+}
+
+
+#endif /* HAVE_LIBSM */
+
+
+/*****************************************************************************/
+/* Managing the master client */
+
+/* The following environment variables will be set on the master
+   client, if they are defined the programs environment.  The array
+   must end with a NULL entry.
+   For now we have no entries.  You might think that saving DISPLAY,
+   or HOME, or something like that would be right.  It isn't.  We
+   definitely want to inherit these values from the user's (possibly
+   changing) environment.  */
+static char* master_environment[]=
+{
+  NULL
+};
+
+/********* gnome_client module */
+
+/* Forward declaration for our module functions.  */
+static void client_parse_func (poptContext ctx,
+			       enum poptCallbackReason reason,
+			       const struct poptOption *opt,
+			       const char *arg, void *data);
+static void gnome_client_pre_args_parse(GnomeProgram *app, GnomeModuleInfo *mod_info);
+static void gnome_client_post_args_parse(GnomeProgram *app, GnomeModuleInfo *mod_info);
+
+/* Command-line arguments understood by this module.  */
+enum { ARG_SM_CLIENT_ID=1, ARG_SM_CONFIG_PREFIX, ARG_SM_DISABLE };
+static const struct poptOption options[] = {
+  {NULL, '\0', POPT_ARG_INTL_DOMAIN, PACKAGE, 0, NULL, NULL},
+
+  {NULL, '\0', POPT_ARG_CALLBACK | POPT_CBFLAG_PRE | POPT_CBFLAG_POST, 
+   client_parse_func, 0, NULL, NULL},
+
+  {"sm-client-id", '\0', POPT_ARG_STRING, NULL, ARG_SM_CLIENT_ID, 
+   N_("Specify session management ID"), N_("ID")},
+
+  {"sm-config-prefix", '\0', POPT_ARG_STRING, NULL, ARG_SM_CONFIG_PREFIX, 
+   N_("Specify prefix of saved configuration"), N_("PREFIX")},
+
+  {"sm-disable", '\0', POPT_ARG_NONE, NULL, ARG_SM_DISABLE, 
+   N_("Disable connection to session manager"), NULL},
+
+  {NULL, '\0', 0, NULL, 0}
+};
+
+extern GnomeModuleInfo gtk_module_info;
+static GnomeModuleRequirement gnome_client_requirements[] = {
+  { "1.2.5", &gtk_module_info },
+  { NULL, NULL }
+};
+
+GnomeModuleInfo gnome_client_module_info = {
+  "gnome-client", VERSION, N_("Session management"),
+  gnome_client_requirements, NULL,
+  gnome_client_pre_args_parse, gnome_client_post_args_parse,
+  (struct poptOption *)options,
+  NULL, NULL, NULL, NULL
+};
+
+/* Parse command-line arguments we recognize.  */
+static void
+client_parse_func (poptContext ctx,
+		   enum poptCallbackReason reason,
+		   const struct poptOption *opt,
+		   const char *arg, void *data)
+{
+  switch (reason) {
+  case POPT_CALLBACK_REASON_OPTION:
+    switch (opt->val) {
+    case ARG_SM_CLIENT_ID:
+      gnome_client_set_id (master_client, arg);
+      break;
+    case ARG_SM_DISABLE:
+      gnome_client_disable_master_connection ();
+      break;
+    case ARG_SM_CONFIG_PREFIX:
+      if(master_client->config_prefix)
+	g_free(master_client->config_prefix);
+      master_client->config_prefix= g_strdup (arg);
+      master_client_restored = TRUE;    
+      break;
+    }
+    break;
+  default:
+    break;
+  }
+}
+
+
+static void
+gnome_client_pre_args_parse(GnomeProgram *app, GnomeModuleInfo *mod_info)
+{
+  int i;
+  char *cwd;
+
+  /* Make sure the Gtk+ type system is initialized.  */
+  gtk_type_init (G_TYPE_DEBUG_NONE);
+  gnome_type_init ();
+
+  /* Create the master client.  */
+  master_client = gnome_client_new_without_connection ();
+  /* Connect the master client's default signals.  */
+  gtk_signal_connect (GTK_OBJECT (master_client), "connect",
+		      GTK_SIGNAL_FUNC (master_client_connect), NULL);
+  gtk_signal_connect (GTK_OBJECT (master_client), "disconnect",
+		      GTK_SIGNAL_FUNC (master_client_disconnect), NULL);
+
+  /* Initialise ICE */
+  gnome_ice_init ();
+
+  /* Set the master client's environment.  */
+  for (i= 0; master_environment[i]; i++)
+    {
+      const char *value= g_getenv (master_environment[i]);
+	      
+      if (value)
+	gnome_client_set_environment (master_client,
+				      master_environment[i],
+				      value);
+    }
+
+  cwd = g_get_current_dir();
+  if (cwd != NULL)
+    {
+      gnome_client_set_current_directory (master_client, cwd);
+      g_free (cwd);
+    }
+
+  g_object_set (G_OBJECT (app), GNOME_CLIENT_PARAM_SM_CONNECT, TRUE, NULL);
+
+  /* needed on non-glibc systems: */
+  gnome_client_set_program (master_client, program_invocation_name);
+  /* Argument parsing is starting.  We set the restart and the
+     clone command to a default value, so other functions can use
+     the master client while parsing the command line.  */
+  gnome_client_set_restart_command (master_client, 1, 
+				    &master_client->program);
+}
+
+static void
+gnome_client_post_args_parse(GnomeProgram *app, GnomeModuleInfo *mod_info)
+{
+  gboolean do_connect = TRUE;
+  GValue value = { 0, };
+
+  g_value_init (&value, G_TYPE_BOOLEAN);
+  g_object_get_property (G_OBJECT (app), GNOME_CLIENT_PARAM_SM_CONNECT, &value);
+  do_connect = g_value_get_boolean (&value);
+  g_value_unset (&value);
+
+  /* We're done, so we can connect to the session manager now.  */
+  if (do_connect)
+    gnome_client_connect (master_client);
+}
+
+/**
+ * gnome_client_disable_master_connection
+ *
+ * Description: Don't connect the master client to the session manager. Usually 
+ * invoked by users when they pass the --sm-disable argument to a Gnome application.
+ **/
+
+void         
+gnome_client_disable_master_connection (void)
+{
+    g_object_set (G_OBJECT (gnome_program_get()),
+		  GNOME_CLIENT_PARAM_SM_CONNECT, FALSE, NULL);
+}
+
+/* Called at exit to ensure the ice connection is closed cleanly
+ * This avoids io errors on the session manager side */
+static void  
+master_client_clean_up (void)
+{
+  if (master_client && GNOME_CLIENT_CONNECTED (master_client))
+      gnome_client_disconnect (master_client);
+}
+
+static void
+master_client_connect (GnomeClient *client,
+		       gint         restarted,
+		       gpointer     client_data)
+{
+  gdk_set_sm_client_id (gnome_client_get_id (client));
+
+  g_atexit (master_client_clean_up);
+}
+
+static void
+master_client_disconnect (GnomeClient *client,
+			  gpointer client_data)
+{
+  if(client_grab_widget && gtk_grab_get_current() == client_grab_widget)
+    gtk_grab_remove(client_grab_widget);
+
+  gdk_set_sm_client_id (NULL);
+}
+
+/**
+ * gnome_master_client
+ *
+ * Description: 
+ * Get the master session management client.  This master client gets
+   a client id, that may be specified by the '--sm-client-id' command
+   line option.  A master client will be generated by 'gnome-init'.
+   If possible the master client will contact the session manager
+   after command-line parsing is finished (unless
+   'gnome_client_disable_master_connection' was called).  The master
+   client will also set the SM_CLIENT_ID property on the client leader
+   window of your application.  
+
+   Additionally, the master client gets some static arguments set
+   automatically (see 'gnome_client_add_static_arg' for static
+   arguments): 'gnome_init' passes all the command line options which 
+   are recognised by gtk as static arguments to the master client.
+ * Returns:  Pointer to the master client
+ **/
+
+GnomeClient*
+gnome_master_client (void)
+{
+  return master_client;
+}
+
+
+/*****************************************************************************/
+/* GTK-class managing functions */
+
+GtkType
+gnome_client_get_type (void)
+{
+  static GtkType client_type = 0;
+  
+  if (!client_type)
+    {
+      GtkTypeInfo client_info =
+      {
+	"GnomeClient",
+	sizeof (GnomeClient),
+	sizeof (GnomeClientClass),
+	(GtkClassInitFunc) gnome_client_class_init,
+	(GtkObjectInitFunc) gnome_client_object_init,
+	NULL,
+	NULL,
+	NULL
+      };
+
+      client_type = gtk_type_unique (gtk_object_get_type (), &client_info);
+    }
+  
+  return client_type;
+}
+
+static void
+gnome_client_class_init (GnomeClientClass *klass)
+{
+  GtkObjectClass *object_class = (GtkObjectClass*) klass;
+  
+  parent_class = gtk_type_class (gtk_object_get_type ());
+  
+  
+  client_signals[SAVE_YOURSELF] =
+    gtk_signal_new ("save_yourself",
+		    GTK_RUN_LAST,
+		    GTK_CLASS_TYPE (object_class),
+		    GTK_SIGNAL_OFFSET (GnomeClientClass, save_yourself),
+		    gnome_marshal_BOOLEAN__INT_ENUM_BOOLEAN_ENUM_BOOLEAN,
+		    GTK_TYPE_BOOL, 5,
+		    GTK_TYPE_INT,
+		    GNOME_TYPE_SAVE_STYLE,
+		    GTK_TYPE_BOOL,
+		    GNOME_TYPE_INTERACT_STYLE,
+		    GTK_TYPE_BOOL);
+  client_signals[DIE] =
+    gtk_signal_new ("die",
+		    GTK_RUN_LAST,
+		    GTK_CLASS_TYPE (object_class),
+		    GTK_SIGNAL_OFFSET (GnomeClientClass, die),
+		    gtk_signal_default_marshaller,
+		    GTK_TYPE_NONE, 0);
+  client_signals[SAVE_COMPLETE] =
+    gtk_signal_new ("save_complete",
+		    GTK_RUN_FIRST,
+		    GTK_CLASS_TYPE (object_class),
+		    GTK_SIGNAL_OFFSET (GnomeClientClass, save_complete),
+		    gtk_signal_default_marshaller,
+		    GTK_TYPE_NONE, 0);
+  client_signals[SHUTDOWN_CANCELLED] =
+    gtk_signal_new ("shutdown_cancelled",
+		    GTK_RUN_FIRST,
+		    GTK_CLASS_TYPE (object_class),
+		    GTK_SIGNAL_OFFSET (GnomeClientClass, shutdown_cancelled),
+		    gtk_signal_default_marshaller,
+		    GTK_TYPE_NONE, 0);
+  client_signals[CONNECT] =
+    gtk_signal_new ("connect",
+		    GTK_RUN_FIRST,
+		    GTK_CLASS_TYPE (object_class),
+		    GTK_SIGNAL_OFFSET (GnomeClientClass, connect),
+		    gtk_marshal_VOID__BOOLEAN,
+		    GTK_TYPE_NONE, 1,
+		    GTK_TYPE_BOOL);
+  client_signals[DISCONNECT] =
+    gtk_signal_new ("disconnect",
+		    GTK_RUN_FIRST,
+		    GTK_CLASS_TYPE (object_class),
+		    GTK_SIGNAL_OFFSET (GnomeClientClass, disconnect),
+		    gtk_signal_default_marshaller,
+		    GTK_TYPE_NONE, 0);
+  
+  
+  object_class->destroy = gnome_real_client_destroy;
+  
+  klass->save_yourself      = NULL;
+  klass->die                = gnome_client_disconnect;
+  klass->save_complete      = gnome_real_client_save_complete;
+  klass->shutdown_cancelled = gnome_real_client_shutdown_cancelled;
+  klass->connect            = gnome_real_client_connect;
+  klass->disconnect         = gnome_real_client_disconnect;
+}
+
+static void
+gnome_client_object_init (GnomeClient *client)
+{
+  client->smc_conn          = NULL;
+  client->client_id         = NULL;
+  client->previous_id       = NULL;
+  client->input_id          = 0;
+  client->config_prefix       = NULL;
+  client->global_config_prefix= NULL;
+
+  client->static_args       = NULL;
+
+  /* Preset some default values.  */
+  client->clone_command     = NULL;
+  client->current_directory = NULL;
+  client->discard_command   = NULL;
+  client->environment       = g_hash_table_new (g_str_hash, g_str_equal);
+  
+  client->process_id        = getpid ();
+
+  client->program           = NULL;
+  client->resign_command    = NULL;
+  client->restart_command   = NULL;
+
+  client->restart_style     = -1;
+  
+  client->shutdown_command  = NULL;
+  
+  client->user_id= g_strdup (g_get_user_name ());
+
+  client->state                       = GNOME_CLIENT_DISCONNECTED;
+  client->interaction_keys            = NULL;
+}
+
+static gboolean
+environment_entry_remove (gchar *key, gchar *value, gpointer data)
+{
+  g_free (key);
+  g_free (value);
+  
+  return TRUE;
+}
+
+static void
+gnome_real_client_destroy (GtkObject *object)
+{
+  GnomeClient *client;
+
+  /* remember, destroy can be run multiple times! */
+  
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (object));
+  
+  client = GNOME_CLIENT (object);
+  
+  if (GNOME_CLIENT_CONNECTED (client))
+    gnome_client_disconnect (client);
+
+  g_free (client->client_id);
+  client->client_id = NULL;
+  g_free (client->previous_id);
+  client->previous_id = NULL;
+  g_free (client->config_prefix);
+  client->config_prefix = NULL;
+  g_free (client->global_config_prefix);
+  client->global_config_prefix = NULL;
+
+  if(client->static_args) {
+	  g_list_foreach (client->static_args, (GFunc)g_free, NULL);
+	  g_list_free    (client->static_args);
+	  client->static_args = NULL;
+  }
+
+  g_strfreev (client->clone_command);
+  client->clone_command = NULL;
+  g_free     (client->current_directory);
+  client->current_directory = NULL;
+  g_strfreev (client->discard_command);
+  client->discard_command = NULL;
+
+  if(client->environment) {
+	  g_hash_table_foreach_remove (client->environment, 
+				       (GHRFunc)environment_entry_remove, NULL);
+	  g_hash_table_destroy        (client->environment);
+	  client->environment = NULL;
+  }
+
+  g_free     (client->program);
+  client->program = NULL;
+  g_strfreev (client->resign_command);
+  client->resign_command = NULL;
+  g_strfreev (client->restart_command);
+  client->restart_command = NULL;
+  g_strfreev (client->shutdown_command);
+  client->shutdown_command = NULL;
+  g_free     (client->user_id);
+  client->user_id = NULL;
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+/*****************************************************************************/
+/* 'gnome_client' public member functions */
+
+
+/**
+ * gnome_client_new
+ *
+ * Description: Allocates memory for a new GNOME session management
+ * client object.  After allocating, the client tries to connect to a
+ * session manager. You probably want to use
+ * <function>gnome_master_client()</function> instead.
+ *
+ * Returns: Pointer to a newly allocated GNOME session management
+ * client object.
+ **/
+
+GnomeClient *
+gnome_client_new (void)
+{
+  GnomeClient *client;
+  
+  client= gnome_client_new_without_connection ();
+  
+  gnome_client_connect (client);
+
+  return client;
+}
+
+
+/**
+ * gnome_client_new_without_connection
+ *
+ * Description: Allocates memory for a new GNOME session management
+ * client object. You probably want to use
+ * <function>gnome_master_client()</function> instead.
+ *
+ * Returns: Pointer to a newly allocated GNOME session management
+ * client object.
+ **/
+
+GnomeClient *
+gnome_client_new_without_connection (void)
+{
+  GnomeClient *client;
+
+  client= gtk_type_new (gnome_client_get_type ());
+
+  /* Preset the CloneCommand, RestartCommand and Program properties.
+     FIXME: having a default would be cool, but it is probably hard to
+     get this to interact correctly with the distributed command-line
+     parsing.  */
+  client->clone_command   = NULL;
+  client->restart_command = NULL;
+
+  /* Non-glibc systems do not get this set on the master_client until 
+     client_parse_func but this is not a problem.
+     The SM specs require explictly require that this is the value: */
+  client->program = g_strdup (program_invocation_name);
+
+  return client;
+}
+
+
+/**
+ * gnome_client_flush
+ * @client: Pointer to GNOME session client object.
+ *
+ * Description:
+ * This will force the underlying connection to the session manager to
+ * be flushed.  This is useful if you have some pending changes that
+ * you want to make sure get committed.
+ **/
+
+void
+gnome_client_flush (GnomeClient *client)
+{
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+
+#ifdef HAVE_LIBSM
+  if (GNOME_CLIENT_CONNECTED (client)) {
+    IceConn conn = SmcGetIceConnection ((SmcConn) client->smc_conn);
+    IceFlush (conn);
+  }
+#endif
+}
+
+/*****************************************************************************/
+
+#define ERROR_STRING_LENGTH 256
+
+
+/**
+ * gnome_client_connect
+ * @client: Pointer to GNOME session client object.
+ *
+ * Description: Causes the client to connect to the session manager.
+ * Usually happens automatically; no need to call this function.
+ **/
+
+void
+gnome_client_connect (GnomeClient *client)
+{
+#ifdef HAVE_LIBSM
+  SmcCallbacks      callbacks;
+  gchar            *client_id;
+#endif /* HAVE_LIBSM */
+
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+
+#ifdef HAVE_LIBSM
+  if (GNOME_CLIENT_CONNECTED (client))
+    return;
+
+  callbacks.save_yourself.callback      = client_save_yourself_callback;
+  callbacks.die.callback                = client_die_callback;
+  callbacks.save_complete.callback      = client_save_complete_callback;
+  callbacks.shutdown_cancelled.callback = client_shutdown_cancelled_callback;
+
+  callbacks.save_yourself.client_data = 
+    callbacks.die.client_data =
+    callbacks.save_complete.client_data =
+    callbacks.shutdown_cancelled.client_data = (SmPointer) client;
+
+  if (g_getenv ("SESSION_MANAGER"))
+    {
+      gchar error_string_ret[ERROR_STRING_LENGTH] = "";
+      
+      client->smc_conn= (gpointer)
+	SmcOpenConnection (NULL, client, 
+			   SmProtoMajor, SmProtoMinor,
+			   SmcSaveYourselfProcMask | SmcDieProcMask |
+			   SmcSaveCompleteProcMask | 
+			   SmcShutdownCancelledProcMask,
+			   &callbacks,
+			   client->client_id, &client_id,
+			   ERROR_STRING_LENGTH, error_string_ret);
+      
+      if (error_string_ret[0])
+	g_warning ("While connecting to session manager:\n%s.",
+		   error_string_ret);
+    }
+
+  if (GNOME_CLIENT_CONNECTED (client))
+    {
+      gint    restarted= FALSE;
+
+      g_free (client->previous_id);
+      client->previous_id= client->client_id;
+      client->client_id= client_id;
+      
+      restarted= (client->previous_id && 
+		  !strcmp (client->previous_id, client_id));
+      
+      client_set_state (client, (restarted ? 
+				 GNOME_CLIENT_IDLE : 
+				 GNOME_CLIENT_REGISTERING));
+
+      /* Let all the world know, that we have a connection to a
+         session manager.  */
+      gtk_signal_emit (GTK_OBJECT (client), client_signals[CONNECT], 
+		       restarted);
+    }
+#endif /* HAVE_LIBSM */
+}
+
+
+
+/**
+ * gnome_client_disconnect
+ * @client: Pointer to GNOME session client object.
+ *
+ * Description: Disconnect the client from the session manager.
+ **/
+
+void
+gnome_client_disconnect (GnomeClient *client)
+{
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+
+  if (GNOME_CLIENT_CONNECTED (client))
+    {
+      gnome_client_flush (client);
+      gtk_signal_emit (GTK_OBJECT (client), client_signals[DISCONNECT]);
+    }
+}
+
+/*****************************************************************************/
+
+/**
+ * gnome_client_get_flags:
+ * @client: Pointer to GNOME session client object.
+ * 
+ * Description:
+ *
+ * Returns some flags, that give additional information about this
+ * client.  Right now, the following flags are supported:
+ * 
+ * - GNOME_CLIENT_IS_CONNECTED: The client is connected to a session
+ *   manager (It's the same information like using *
+ *   GNOME_CLIENT_CONNECTED).
+ *  
+ * - GNOME_CLIENT_RESTARTED: The client has been restarted, i. e. it
+ *   has been running with the same client id before.
+ *    
+ * - GNOME_CLIENT_RESTORED: This flag is only used for the master
+ *   client.  It indicates, that there may be a configuraion file from
+ *   which the clients state should be restored (using the
+ *   gnome_client_get_config_prefix call).
+ **/
+   
+GnomeClientFlags
+gnome_client_get_flags (GnomeClient *client)
+{
+  GnomeClientFlags flags= 0;
+  
+  g_return_val_if_fail (client != NULL, 0);
+  g_return_val_if_fail (GNOME_IS_CLIENT (client), 0);
+
+  /* To not break binary compability with existing code, the
+     GnomeClient struct has not been changed.  So the flags have to be
+     calculated every time.  */
+
+  if (GNOME_CLIENT_CONNECTED (client))
+    {
+      flags |= GNOME_CLIENT_IS_CONNECTED;
+
+      if (client->previous_id && 
+	  !strcmp (client->previous_id, client->client_id))
+	flags |= GNOME_CLIENT_RESTARTED;
+      
+      if (master_client_restored && (client == master_client))
+	flags |= GNOME_CLIENT_RESTORED;
+    }
+
+  return flags;
+}
+
+
+/*****************************************************************************/
+
+/**
+ * gnome_client_set_clone_command
+ * @client: Pointer to GNOME session client object.
+ * @argc: number of strings in the argv vector
+ * @argv[]: argument strings, suitable for use with <function>execv()</function>
+ *
+ * Description: Set a command the session manager can use to create a new instance of the application.
+ **/
+
+void 
+gnome_client_set_clone_command (GnomeClient *client, 
+				gint argc, gchar *argv[])
+{
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+
+  /* Whenever clone_command == NULL then restart_command is used instead */
+  g_strfreev (client->clone_command);
+  client->clone_command = array_init_from_arg (argc, argv);
+
+#ifdef HAVE_LIBSM
+  client_set_clone_command (client);
+#endif /* HAVE_LIBSM */
+}
+
+/**
+ * gnome_client_set_current_directory
+ * @client: Pointer to GNOME session client object.
+ * @dir: Directory path
+ *
+ * Description: Set the directory to be in when running shutdown, discard, restart, etc. commands.
+ **/
+
+void 
+gnome_client_set_current_directory (GnomeClient *client,
+				    const gchar *dir)
+{
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+  
+  g_free (client->current_directory);
+  
+  if (dir)
+    {
+      client->current_directory= g_strdup (dir);
+#ifdef HAVE_LIBSM
+      client_set_string (client, SmCurrentDirectory, 
+				  client->current_directory);
+#endif /* HAVE_LIBSM */
+    }
+  else
+    {
+      client->current_directory= NULL;
+#ifdef HAVE_LIBSM
+      client_unset (client, SmCurrentDirectory);
+#endif /* HAVE_LIBSM */
+    }
+}
+
+
+
+/**
+ * gnome_client_set_discard_command
+ * @client: Pointer to GNOME session client object.
+ * @argc: Number of strings in argv
+ * @argv[]: Vector of strings such as those passed to <function>execv()</function>
+ *
+ * Description: Provides a command to run when a client is removed
+ * from the session. It might delete session-specific config files for
+ * example.  Executing the discard command on the local host should
+ * delete the information saved as part of the session save that was
+ * in progress when the discard command was set. For example:
+
+<example>
+     gchar *prefix = gnome_client_get_config_prefix (client);
+     gchar *argv[] = { "rm", "-r", NULL };
+     argv[2] = gnome_config_get_real_path (prefix);
+     gnome_client_set_discard_command (client, 3, argv);
+</example>
+ **/
+
+void 
+gnome_client_set_discard_command (GnomeClient *client,
+				  gint argc, gchar *argv[])
+{
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+
+  if (argv == NULL)
+    {
+      g_return_if_fail (argc == 0);
+      
+      g_strfreev (client->discard_command);
+      client->discard_command= NULL;
+#ifdef HAVE_LIBSM
+      client_unset (client, SmDiscardCommand);
+#endif /* HAVE_LIBSM */
+    }
+  else
+    {
+      g_strfreev (client->discard_command);
+      client->discard_command = array_init_from_arg (argc, argv);
+      
+#ifdef HAVE_LIBSM
+      client_set_array (client, SmDiscardCommand, 
+				  client->discard_command);
+#endif /* HAVE_LIBSM */
+    }
+}
+
+
+
+/**
+ * gnome_client_set_environment
+ * @client: Pointer to GNOME session client object.
+ * @name: Name of the environment variable
+ * @value: Value of the environment variable
+ *
+ * Description: Set an environment variable to be placed in the
+ * client's environment prior to running restart, shutdown, discard, etc. commands.
+ **/
+
+void 
+gnome_client_set_environment (GnomeClient *client,
+			      const gchar *name,
+			      const gchar *value)
+{
+  gchar *old_name;
+  gchar *old_value;
+  
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+  g_return_if_fail (name != NULL);
+
+  if (g_hash_table_lookup_extended (client->environment,
+				    name, 
+				    (gpointer *) &old_name, 
+				    (gpointer *) &old_value))
+    {
+      if (value)
+	{
+	  g_hash_table_insert (client->environment, old_name, 
+			       g_strdup (value));
+	  g_free (old_value);
+	}
+      else
+	{
+	  g_hash_table_remove (client->environment, name);
+	  g_free (old_name);
+	  g_free (old_value);
+	}
+    }
+  else if (value)
+    {
+      g_hash_table_insert (client->environment, 
+			   g_strdup (name), 
+			   g_strdup (value));
+    }
+  
+#ifdef HAVE_LIBSM
+  client_set_ghash (client, SmEnvironment, client->environment);
+#endif /* HAVE_LIBSM */
+}
+
+
+
+/**
+ * gnome_client_set_process_id
+ * @client: Pointer to GNOME session client object.
+ * @pid: PID to set as the client's PID
+ *
+ * Description: The client should tell the session manager the result
+ * of <function>getpid()</function>. However, Gnome does this
+ * automatically; so you don't need this function.
+ **/
+
+void 
+gnome_client_set_process_id (GnomeClient *client, pid_t pid)
+{
+  gchar str_pid[32];
+  
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+
+  client->process_id= pid;
+  
+  g_snprintf (str_pid, sizeof(str_pid), "%d", client->process_id);
+
+#ifdef HAVE_LIBSM
+  client_set_string (client, SmProcessID, str_pid);
+#endif /* HAVE_LIBSM */
+}
+
+
+
+/**
+ * gnome_client_set_program
+ * @client: Pointer to GNOME session client object.
+ * @program: name of the program
+ *
+ * Description: Used to tell the session manager the name of your program. Set automatically;
+ * this function isn't needed.
+ **/
+
+void 
+gnome_client_set_program (GnomeClient *client, 
+			  const gchar *program)
+{
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+
+  /* The Program property is required, so you must not unset it.  */
+  g_return_if_fail (program != NULL);
+  
+  g_free (client->program);
+  
+  client->program= g_strdup (program);
+
+  client_unset_config_prefix (client);  
+
+#ifdef HAVE_LIBSM
+  client_set_string (client, SmProgram, client->program);
+#endif /* HAVE_LIBSM */
+}
+
+
+
+/**
+ * gnome_client_set_resign_command
+ * @client: Pointer to GNOME session client object.
+ * @argc: number of strings in argv
+ * @argv[]: <function>execv()</function>-style command to undo the effects of the client.
+ *
+ * Description: Some clients can be "undone," removing their effects and deleting any 
+ * saved state. For example, xmodmap could register a resign command to undo the keymap 
+ * changes it saved.
+ * 
+ * Used by clients that use the GNOME_RESTART_ANYWAY restart style to
+ * to undo their effects (these clients usually perform initialisation
+ * functions and leave effects behind after they die).  The resign
+ * command combines the effects of a shutdown command and a discard
+ * command. It is executed when the user decides that the client
+ * should cease to be restarted.
+ **/
+
+void 
+gnome_client_set_resign_command (GnomeClient *client,
+				 gint argc, gchar *argv[])
+{
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+
+  if (argv == NULL)
+    {
+      g_return_if_fail (argc == 0);
+      
+      g_strfreev (client->resign_command);
+      client->resign_command= NULL;
+
+#ifdef HAVE_LIBSM
+      client_unset (client, SmResignCommand);
+#endif /* HAVE_LIBSM */
+    }
+  else
+    {
+      g_strfreev (client->resign_command);
+      client->resign_command = array_init_from_arg (argc, argv);
+  
+#ifdef HAVE_LIBSM
+      client_set_array (client, SmResignCommand, client->resign_command);
+#endif /* HAVE_LIBSM */
+    }
+}
+
+
+
+/**
+ * gnome_client_set_restart_command
+ * @client: Pointer to GNOME session client object.
+ * @argc: number of strings in argv
+ * @argv: argument vector to <function>execv()</function> to restart the client
+ *
+ * Description: When clients crash or the user logs out and back in,
+   they are restarted.  * This command should perform the restart.  *
+   Executing the restart command on the local host should reproduce
+   the state of the client at the time of the session save as closely
+   as possible. Saving config info under the
+   gnome_client_get_config_prefix is generally useful.
+ **/
+
+void 
+gnome_client_set_restart_command (GnomeClient *client,
+				  gint argc, gchar *argv[])
+{
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+  
+  /* The RestartCommand property is required, so you must not unset
+     it.  */
+  g_return_if_fail (argc != 0);
+  g_return_if_fail (argv != NULL);
+
+  g_strfreev (client->restart_command);
+  client->restart_command = array_init_from_arg (argc, argv);
+
+#ifdef HAVE_LIBSM
+  client_set_restart_command (client);
+#endif /* HAVE_LIBSM */
+}
+
+/**
+ * gnome_client_set_priority
+ * @client: Pointer to GNOME session client object.
+ * @priority: Position of client in session start up ordering.
+ *
+ * Description: 
+ *
+ * The gnome-session manager restarts clients in order of their
+ * priorities in a similar way to the start up ordering in SysV.
+ * This function allows the app to suggest a position in this
+ * ordering. The value should be between 0 and 99. A default
+ * value of 50 is assigned to apps that do not provide a value. 
+ * The user may assign a different priority.
+ **/
+
+void 
+gnome_client_set_priority (GnomeClient *client, guint priority)
+{
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+
+#ifdef HAVE_LIBSM
+  if (priority > 99)
+    priority = 99;
+
+  client_set_gchar (client, "_GSM_Priority", (gchar) priority);
+#endif
+}
+
+/**
+ * gnome_client_set_restart_style
+ * @client: Pointer to GNOME session client object.
+ * @style: When to restart the client
+ *
+ * Description: GNOME_RESTART_IF_RUNNING causes the client to be
+ * restarted in the next session if it was running when the previous
+ * session exited. Restart is done via the restart command you
+ * set. GNOME_RESTART_ANYWAY means the client will be restarted even
+ * if the user exits the client before logging
+ * out. GNOME_RESTART_IMMEDIATELY restarts the client immediately
+ * anytime it crashes or is exited.
+ **/
+
+void 
+gnome_client_set_restart_style (GnomeClient *client,
+				GnomeRestartStyle style)
+{
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+
+  switch (style)
+    {
+    case GNOME_RESTART_IF_RUNNING:
+#ifdef HAVE_LIBSM
+      client_set_gchar (client, SmRestartStyleHint, SmRestartIfRunning);
+      break;
+#endif /* HAVE_LIBSM */
+      
+    case GNOME_RESTART_ANYWAY:
+#ifdef HAVE_LIBSM
+      client_set_gchar (client, SmRestartStyleHint, SmRestartAnyway);
+      break;
+#endif /* HAVE_LIBSM */
+
+    case GNOME_RESTART_IMMEDIATELY:
+#ifdef HAVE_LIBSM
+      client_set_gchar (client, SmRestartStyleHint, SmRestartImmediately);
+      break;
+#endif /* HAVE_LIBSM */
+
+    case GNOME_RESTART_NEVER:
+#ifdef HAVE_LIBSM
+      client_set_gchar (client, SmRestartStyleHint, SmRestartNever);
+#endif /* HAVE_LIBSM */
+      break;
+
+    default:
+      g_assert_not_reached ();
+      return;
+    }
+
+  client->restart_style= style;
+}
+
+
+
+/**
+ * gnome_client_set_shutdown_command
+ * @client: Pointer to GNOME session client object.
+ * @argc: number of strings in argv
+ * @argv[]: command to shutdown the client if the client isn't running
+ *
+ * Description: GNOME_RESTART_ANYWAY clients can set this command to run 
+ * when the user logs out but the client is no longer running.
+ *
+ * Used by clients that use the GNOME_RESTART_ANYWAY restart style to
+ * to undo their effects (these clients usually perform initialisation
+ * functions and leave effects behind after they die).  The shutdown
+ * command simply undoes the effects of the client. It is executed
+ * during a normal logout.
+ **/
+
+void 
+gnome_client_set_shutdown_command (GnomeClient *client,
+				   gint argc, gchar *argv[])
+{
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+  
+  if (argv == NULL)
+    {
+      g_return_if_fail (argc == 0);
+      
+      g_strfreev (client->shutdown_command);
+      client->shutdown_command = NULL;
+#ifdef HAVE_LIBSM
+      client_unset (client, SmShutdownCommand);
+#endif /* HAVE_LIBSM */
+    }
+  else
+    {
+      g_strfreev (client->shutdown_command);
+      client->shutdown_command = array_init_from_arg (argc, argv);
+
+#ifdef HAVE_LIBSM
+      client_set_array (client, SmShutdownCommand, 
+				  client->shutdown_command);
+#endif /* HAVE_LIBSM */
+    }
+}
+
+
+
+/**
+ * gnome_client_set_user_id
+ * @client: Pointer to GNOME session client object.
+ * @id: Username
+ *
+ * Description: Tell the session manager the user's login name. Gnome
+ * does this automatically; no need to call the function.
+ **/
+
+void 
+gnome_client_set_user_id (GnomeClient *client,
+			  const gchar       *id)
+{
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+
+  /* The UserID property is required, so you must not unset it.  */
+  g_return_if_fail (id != NULL);
+  
+  g_free (client->user_id);
+  
+  client->user_id= g_strdup (id);
+#ifdef HAVE_LIBSM
+  client_set_string (client, SmUserID, client->user_id);
+#endif /* HAVE_LIBSM */
+}
+
+
+
+/**
+ * gnome_client_add_static_arg
+ * @client: Pointer to GNOME session client object.
+ * @...: NULL-terminated list of arguments to add to the restart command
+ *
+ * Description: You can add arguments to your restart command argv
+   with this function. This function provides an alternative way of
+   adding new arguments to the restart command. The arguments are
+   placed before the arguments specified by
+   'gnome_client_set_restart_command' and after the arguments
+   recognised by gtk specified by the user on the original command
+   line.
+ **/
+
+void
+gnome_client_add_static_arg (GnomeClient *client, ...)
+{
+  va_list  args;
+  gchar   *str;
+  
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+
+  va_start (args, client);
+  str= va_arg (args, gchar*);
+  while (str)
+    {
+      client->static_args= g_list_append (client->static_args, g_strdup(str));
+      str= va_arg (args, gchar*);
+    }
+  va_end (args);
+}
+
+/*****************************************************************************/
+
+
+/**
+ * gnome_client_set_id
+ * @client: Pointer to GNOME session client object.
+ * @id: Session management ID
+ *
+ * Description: Set the client's session management ID; must be done
+ * before connecting to the session manager. Frankly I have no idea
+ * why you'd do this.
+ **/
+
+void
+gnome_client_set_id (GnomeClient *client, const gchar *id)
+{
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+  g_return_if_fail (!GNOME_CLIENT_CONNECTED (client));
+
+  g_return_if_fail (id != NULL);
+
+  g_free (client->client_id);
+  client->client_id= g_strdup (id);
+}
+
+
+
+/**
+ * gnome_client_get_id
+ * @client: Pointer to GNOME session client object.
+ *
+ * Description: Returns session management ID
+ *
+ * Returns:  Session management ID for this client; NULL if not connected to a session manager.
+ **/
+
+const gchar *
+gnome_client_get_id (GnomeClient *client)
+{
+  g_return_val_if_fail (client != NULL, NULL);
+  g_return_val_if_fail (GNOME_IS_CLIENT (client), NULL);
+  
+  return client->client_id;
+}
+
+/**
+ * gnome_client_get_previous_id
+ * @client: Pointer to GNOME session client object.
+ *
+ * Description: Get the previous session management ID (from previous session)
+ *
+ * Returns: Pointer to the session management ID the client had in the last
+ * session, or NULL if it wasn't in a previous session.
+ **/
+
+const gchar *
+gnome_client_get_previous_id (GnomeClient *client)
+{
+  g_return_val_if_fail (client != NULL, NULL);
+  g_return_val_if_fail (GNOME_IS_CLIENT (client), NULL);
+
+  return client->previous_id;
+}
+
+/**
+ * gnome_client_get_config_prefix
+ * @client: Pointer to GNOME session client object.
+ *
+ * Description: Get the config prefix for a client. This config prefix
+ * provides a suitable place to store any details about the state of
+ * the client which can not be described using the app's command line
+ * arguments (as set in the restart command). You may push the
+ * returned value using 'gnome_config_push_prefix' and read or write
+ *  any values you require.
+ *
+ * Returns: Config prefix.
+ **/
+
+const gchar *
+gnome_client_get_config_prefix (GnomeClient *client)
+{
+  if (!client || !GNOME_IS_CLIENT (client))
+      client = master_client;
+
+  if (!client || !GNOME_IS_CLIENT (client))
+      return gnome_client_get_global_config_prefix (client);
+
+  if (!client->config_prefix)
+    client->config_prefix = (char *)gnome_client_get_global_config_prefix (client);
+
+  return client->config_prefix;
+}
+
+static gchar* config_prefix = NULL;
+
+/**
+ * gnome_client_set_global_config_prefix
+ * @client: Pointer to GNOME session client object.
+ * @prefix: Prefix for saving the global configuration
+ *
+ * Description:  Set the value used for the global config prefix. The config prefixes 
+   returned by gnome_client_get_config_prefix are formed by extending
+   this prefix with an unique identifier.
+   
+   The global config prefix defaults to a name based on the name of
+   the executable. This function allows you to set it to a different
+   value. It should be called BEFORE retrieving the config prefix for
+   the first time. Later calls will be ignored.
+
+   For example, setting a global config prefix of "/app.d/session/"
+   would ensure that all your session save files or directories would
+   be gathered together into the app.d directory.
+ **/
+
+void
+gnome_client_set_global_config_prefix (GnomeClient *client, const gchar* prefix)
+{
+  if (client == NULL)
+    {
+      config_prefix= g_strdup (prefix);
+      return;
+    }
+
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+      
+  client->global_config_prefix = g_strdup (prefix);
+}
+
+/**
+ * gnome_client_get_global_config_prefix
+ * @client: Pointer to GNOME session client object.
+ *
+ * Description: Get the config prefix that will be returned by
+ * #gnome_client_get_config_prefix() for clients
+ * which have NOT been restarted or cloned (i.e. for clients started
+ * by the user without `--sm-' options). This config prefix may be
+ * used to write the user's preferred config for these "new" clients.
+ *
+ * You could also use this prefix as a place to store and retrieve
+ * config details that you wish to apply to ALL instances of the
+ * app. However, this practice limits the users freedom to configure
+ * each instance in a different way so it should be used with caution.
+ *
+ * Returns:  The config prefix as a newly allocated string
+ **/
+
+const gchar *
+gnome_client_get_global_config_prefix (GnomeClient *client)
+{
+  if (client == NULL)
+    {
+      if (!config_prefix)
+	config_prefix= g_strconcat ("/", program_invocation_short_name, "/",
+				       NULL);
+
+      return config_prefix;
+    }
+
+  g_return_val_if_fail (GNOME_IS_CLIENT (client), NULL);
+  
+  if (!client->global_config_prefix)
+    {
+      char *name;
+      name= strrchr (client->program, '/');
+
+      name= name ? (name+1) : client->program;
+            
+      client->global_config_prefix= g_strconcat ("/", name, "/", NULL);
+    }
+
+  return client->global_config_prefix;
+}
+
+static void
+client_unset_config_prefix (GnomeClient *client)
+{
+  g_free (client->config_prefix);
+  client->config_prefix= NULL;
+  g_free (client->global_config_prefix);
+  client->global_config_prefix= NULL;
+} 
+  
+
+/*****************************************************************************/
+
+static void
+gnome_real_client_save_complete (GnomeClient *client)
+{
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+  
+  client_set_state (client, GNOME_CLIENT_IDLE);
+}
+
+/* The following function is executed, after receiving a SHUTDOWN
+ * CANCELLED message from the session manager.  It is executed before
+ * the function connected to the 'shutdown_cancelled' signal are
+ * called */
+
+static void
+gnome_real_client_shutdown_cancelled (GnomeClient *client)
+{
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+
+#ifdef HAVE_LIBSM
+  if ((client->state == GNOME_CLIENT_SAVING_PHASE_1) ||
+      (client->state == GNOME_CLIENT_WAITING_FOR_PHASE_2) ||
+      (client->state == GNOME_CLIENT_SAVING_PHASE_2))
+    SmcSaveYourselfDone ((SmcConn) client->smc_conn, False);
+
+  client_set_state (client, GNOME_CLIENT_IDLE);
+  
+  /* Free all interation keys but the one in use.  */
+  while (client->interaction_keys)
+    {
+      GSList *tmp= client->interaction_keys;
+      
+      interaction_key_destroy_if_possible ((InteractionKey *) tmp->data);
+
+      client->interaction_keys= g_slist_remove (tmp, tmp->data);
+    }
+#endif /* HAVE_LIBSM */
+}
+
+static void
+gnome_real_client_connect (GnomeClient *client,
+			   gint         restarted)
+{  
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+  
+#ifdef HAVE_LIBSM
+  /* We now set all non empty properties.  */
+  client_set_string (client, SmCurrentDirectory, client->current_directory);
+  client_set_array (client, SmDiscardCommand, client->discard_command);
+  client_set_ghash (client, SmEnvironment, client->environment);
+  {
+    gchar str_pid[32];
+    
+    g_snprintf (str_pid, sizeof(str_pid), "%d", client->process_id);
+    client_set_string (client, SmProcessID, str_pid);
+  }
+  client_set_string (client, SmProgram, client->program);
+  client_set_array (client, SmResignCommand, client->resign_command);
+
+  client_set_clone_command (client);
+  client_set_restart_command (client);
+
+  switch (client->restart_style)
+    {
+    case GNOME_RESTART_IF_RUNNING:
+      client_set_gchar (client, SmRestartStyleHint, SmRestartIfRunning);
+      break;
+      
+    case GNOME_RESTART_ANYWAY:
+      client_set_gchar (client, SmRestartStyleHint, SmRestartAnyway);
+      break;
+
+    case GNOME_RESTART_IMMEDIATELY:
+      client_set_gchar (client, SmRestartStyleHint, SmRestartImmediately);
+      break;
+
+    case GNOME_RESTART_NEVER:
+      client_set_gchar (client, SmRestartStyleHint, SmRestartNever);
+      break;
+
+    default:
+      break;
+    }
+
+  client_set_array (client, SmShutdownCommand, client->shutdown_command);
+  client_set_string (client, SmUserID, client->user_id);
+#endif /* HAVE_LIBSM */
+}
+
+
+static void
+gnome_real_client_disconnect (GnomeClient *client)
+{
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+  
+#ifdef HAVE_LIBSM
+  if (GNOME_CLIENT_CONNECTED (client))
+    {
+      SmcCloseConnection ((SmcConn) client->smc_conn, 0, NULL);
+      client->smc_conn = NULL;
+    }
+  
+  client_set_state (client, GNOME_CLIENT_DISCONNECTED);
+
+  /* Free all interation keys but the one in use.  */
+  while (client->interaction_keys)
+    {
+      GSList *tmp= client->interaction_keys;
+      
+      interaction_key_destroy_if_possible ((InteractionKey *) tmp->data);
+
+      client->interaction_keys= g_slist_remove (tmp, tmp->data);
+    }
+
+#endif /* HAVE_LIBSM */
+}
+
+/*****************************************************************************/
+
+static void
+gnome_client_request_interaction_internal (GnomeClient           *client,
+					   GnomeDialogType        dialog_type,
+					   gboolean               interp,
+					   GnomeInteractFunction  function,
+					   gpointer               data,
+					   GtkDestroyNotify       destroy) 
+{
+#ifdef HAVE_LIBSM
+  Status          status;
+  InteractionKey *key;
+  int             _dialog_type;
+#endif
+  
+  /* Convert GnomeDialogType into XSM library values */
+  switch (dialog_type)
+    {
+    case GNOME_DIALOG_ERROR:
+#ifdef HAVE_LIBSM
+      _dialog_type= SmDialogError;
+#endif
+      break;
+      
+    case GNOME_DIALOG_NORMAL:
+#ifdef HAVE_LIBSM
+      _dialog_type= SmDialogError;
+#endif
+      break;
+      
+    default:
+      g_assert_not_reached ();
+      return;
+    }
+
+#ifdef HAVE_LIBSM
+  
+  key= interaction_key_new (client, dialog_type, interp,
+			    function, data, destroy);
+  
+  g_return_if_fail (key);
+  
+  status= SmcInteractRequest ((SmcConn) client->smc_conn, _dialog_type, 
+			      client_interact_callback, (SmPointer) client);
+  
+  if (status)
+    {
+        client->interaction_keys = g_slist_append (client->interaction_keys, 
+						   key);
+    }
+  else
+    {
+      interaction_key_destroy (key);
+    }
+#endif /* HAVE_LIBSM */
+}
+
+static void
+gnome_client_save_dialog_show (GnomeClient *client, gint key,
+			       GnomeDialogType type, gpointer data)
+{
+  GtkDialog* dialog = GTK_DIALOG (data);
+  gboolean shutdown_cancelled;
+
+  if (client->shutdown) 
+    gtk_dialog_add_button (dialog, _("Cancel Logout"), GTK_RESPONSE_CANCEL);
+  gtk_widget_show_all (GTK_WIDGET (dialog));
+  /* These are SYSTEM modal dialogs so map them above everything else */
+  gnome_win_hints_set_layer (GTK_WIDGET (dialog), WIN_LAYER_ABOVE_DOCK);
+  shutdown_cancelled = (gtk_dialog_run (dialog) == GTK_RESPONSE_CANCEL);
+  gnome_interaction_key_return (key, shutdown_cancelled);
+}
+
+/**
+ * gnome_client_save_any_dialog
+ * @client: Pointer to GNOME session client object.
+ * @dialog: Pointer to GNOME dialog widget.
+ *
+ * Description:
+ * May be called during a "save_youself" handler to request that a 
+ * (modal) dialog is presented to the user. The session manager decides 
+ * when the dialog is shown but it will not be shown it unless the 
+ * interact_style == GNOME_INTERACT_ANY. A "Cancel Logout" button 
+ * will be added during a shutdown.
+ **/
+void         
+gnome_client_save_any_dialog (GnomeClient *client, GtkDialog *dialog)
+{
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (dialog != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+  g_return_if_fail (GTK_IS_DIALOG (dialog));
+
+  if (client->interact_style == GNOME_INTERACT_ANY)
+      gnome_client_request_interaction (client, 
+					GNOME_DIALOG_NORMAL, 
+					gnome_client_save_dialog_show,
+					(gpointer) dialog);
+}
+
+/**
+ * gnome_client_save_error_dialog
+ * @client: Pointer to GNOME session client object.
+ * @dialog: Pointer to GNOME dialog widget.
+ *
+ * Description:
+ * May be called during a "save_youself" handler when an error has occured 
+ * during the save. The session manager decides when the dialog is shown 
+ * but it will not be shown when the interact_style == GNOME_INTERACT_NONE.
+ * A "Cancel Logout" button will be added during a shutdown.
+ **/
+
+void         
+gnome_client_save_error_dialog (GnomeClient *client, GtkDialog *dialog)
+{
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (dialog != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+  g_return_if_fail (GTK_IS_DIALOG (dialog));
+
+  if (client->interact_style != GNOME_INTERACT_NONE)
+    gnome_client_request_interaction (client, 
+				      GNOME_DIALOG_ERROR, 
+				      gnome_client_save_dialog_show,
+				      (gpointer) dialog);
+}
+
+/**
+ * gnome_client_request_interaction
+ * @client: Pointer to GNOME session client object.
+ * @dialog_type: What sort of dialog to create
+ * @function: Callback to invoke to perform the interaction
+ * @data: callback data
+ *
+ * Description: Use the following functions, if you want to interact
+ * with the user during a "save_yourself" handler without being
+ * restricted to using the dialog based commands
+ * gnome_client_save_[any/error]_dialog.  If and when the session
+ * manager decides that it's the app's turn to interact then 'func'
+ * will be called with the specified arguments and a unique
+ * 'GnomeInteractionKey'. The session manager will block other clients
+ * from interacting until this key is returned with
+ * 'gnome_interaction_key_return'.
+ **/
+
+void
+gnome_client_request_interaction (GnomeClient *client,
+				  GnomeDialogType dialog_type,
+				  GnomeInteractFunction function,
+				  gpointer data)
+{
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+
+  g_return_if_fail ((client->state == GNOME_CLIENT_SAVING_PHASE_1) ||
+		    (client->state == GNOME_CLIENT_SAVING_PHASE_2));
+
+  g_return_if_fail ((client->interact_style != GNOME_INTERACT_NONE) &&
+		    ((client->interact_style == GNOME_INTERACT_ANY) ||
+		     (dialog_type == GNOME_DIALOG_ERROR)));
+  
+  gnome_client_request_interaction_internal (client, dialog_type, 
+					     FALSE, function, data, NULL);  
+}
+
+
+/**
+ * gnome_client_request_interaction_interp
+ * @client: Pointer to GNOME session client object.
+ * @dialog_type: Type of dialog to show
+ * @function: callback to perform the interaction
+ * @data: callback data
+ * @destroy: function to destroy callback data
+ *
+ * Description: Used when you need to destroy the callback data after the interaction.
+ **/
+
+void
+gnome_client_request_interaction_interp (GnomeClient *client,
+					 GnomeDialogType dialog_type,
+					 GtkCallbackMarshal function,
+					 gpointer data,
+					 GtkDestroyNotify destroy)
+{
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+
+  g_return_if_fail ((client->state == GNOME_CLIENT_SAVING_PHASE_1) ||
+		    (client->state == GNOME_CLIENT_SAVING_PHASE_2));
+
+  g_return_if_fail ((client->interact_style != GNOME_INTERACT_NONE) &&
+		    ((client->interact_style == GNOME_INTERACT_ANY) ||
+		     (dialog_type == GNOME_DIALOG_ERROR)));
+  
+  gnome_client_request_interaction_internal (client, dialog_type, 
+					     TRUE,
+					     (GnomeInteractFunction)function, 
+					     data, destroy);
+}
+
+
+/*****************************************************************************/
+
+
+/**
+ * gnome_client_request_phase_2
+ * @client: Pointer to GNOME session client object.
+ *
+ * Description:  Request the session managaer to emit the "save_yourself" signal for 
+   a second time after all the clients in the session have ceased 
+   interacting with the user and entered an idle state. This might be 
+   useful if your app manages other apps and requires that they are in 
+   an idle state before saving its final data.
+ **/
+
+void
+gnome_client_request_phase_2 (GnomeClient *client)
+{
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+
+  /* Check if we are in save phase one */
+  g_return_if_fail (client->state == GNOME_CLIENT_SAVING_PHASE_1);
+
+  client->save_phase_2_requested= TRUE;
+}
+
+
+/**
+ * gnome_client_request_save
+ * @client: Pointer to GNOME session client object.
+ * @save_style: Save style to request
+ * @shutdown: Whether to log out of the session
+ * @interact_style: whether to allow user interaction
+ * @fast: minimize activity to save ASAP
+ * @global: request that all other apps in the session also save
+ *
+ * Description: Request the session manager to save the session in
+ * some way. The arguments correspond with the arguments passed to the
+ * "save_yourself" signal handler.
+ *
+ * The save_style indicates whether the save should affect data
+ * accessible to other users (GNOME_SAVE_GLOBAL) or only the state
+ * visible to the current user (GNOME_SAVE_LOCAL) or both. Setting
+ * shutdown to TRUE will initiate a logout. The interact_style
+ * specifies which kinds of interaction will be available. Setting
+ * fast to TRUE will limit the save to setting the session manager
+ * properties plus any essential data.  Setting the value of global to
+ * TRUE will request that all the other apps in the session do a save
+ * as well. A global save is mandatory when doing a shutdown.
+ *
+ **/
+
+void
+gnome_client_request_save (GnomeClient	       *client,
+			   GnomeSaveStyle	save_style,
+			   gboolean		shutdown,
+			   GnomeInteractStyle	interact_style,
+			   gboolean		fast,
+			   gboolean		global)
+{
+#ifdef HAVE_LIBSM
+  int _save_style;
+  int _interact_style;
+#endif
+  
+  g_return_if_fail (client != NULL);
+  g_return_if_fail (GNOME_IS_CLIENT (client));
+
+  switch (save_style)
+    {
+    case GNOME_SAVE_GLOBAL:
+#ifdef HAVE_LIBSM
+      _save_style= SmSaveGlobal;
+      break;
+#endif
+      
+    case GNOME_SAVE_LOCAL:
+#ifdef HAVE_LIBSM
+      _save_style= SmSaveLocal;
+      break;
+#endif
+      
+    case GNOME_SAVE_BOTH:
+#ifdef HAVE_LIBSM
+      _save_style= SmSaveBoth;
+#endif
+      break;
+      
+    default:
+      g_assert_not_reached ();
+      return;
+    }
+
+  switch (interact_style)
+    {
+    case GNOME_INTERACT_NONE:
+#ifdef HAVE_LIBSM
+      _interact_style= SmInteractStyleNone;
+      break;
+#endif
+      
+    case GNOME_INTERACT_ERRORS:
+#ifdef HAVE_LIBSM
+      _interact_style= SmInteractStyleErrors;
+      break;
+#endif
+      
+    case GNOME_INTERACT_ANY:
+#ifdef HAVE_LIBSM
+      _interact_style= SmInteractStyleAny;
+#endif
+      break;
+      
+    default:
+      g_assert_not_reached ();
+      return;
+    }
+
+  if (GNOME_CLIENT_CONNECTED (client))
+    {
+#ifdef HAVE_LIBSM
+      if (shutdown)
+	{
+	  gnome_triggers_do("Session shutdown", NULL,
+			    "gnome", "logout", NULL);
+	}
+      SmcRequestSaveYourself ((SmcConn) client->smc_conn, _save_style,
+			      shutdown, _interact_style,
+			      fast, global);            
+#endif HAVE_LIBSM
+    }
+  else 
+    {
+      gboolean ret;
+      gtk_signal_emit (GTK_OBJECT (client), client_signals[SAVE_YOURSELF],
+		       1, save_style, shutdown, interact_style, fast, &ret);
+      if (shutdown) 
+	gtk_signal_emit (GTK_OBJECT (client), client_signals[DIE]);
+    }
+}
+
+/*****************************************************************************/
+/* 'InteractionKey' stuff */
+
+
+/**
+ * gnome_interaction_key_return
+ * @key: Key passed to interaction callback
+ * @cancel_shutdown: if TRUE then cancel the shutdown
+ *
+ * Description: Used in interaction callback to tell the session manager
+ * you're done interacting
+ **/
+
+void
+gnome_interaction_key_return (gint     tag,
+			      gboolean cancel_shutdown)
+{
+#ifdef HAVE_LIBSM
+  InteractionKey *key;
+  GnomeClient    *client;
+
+  key= interaction_key_find_by_tag (tag);
+  g_return_if_fail (key);
+
+  client= key->client;
+  
+  interaction_key_destroy (key);
+
+  /* The case that 'client != NULL' should only occur, if the
+     connection to the session manager was closed, while we where
+     interacting or we received a SHUTDOWN_CANCELLED while
+     interacting.  */
+  if (client == NULL)
+    return;
+  
+  client->interaction_keys= g_slist_remove (client->interaction_keys, key);
+  
+  if (cancel_shutdown && !client->shutdown)
+    cancel_shutdown= FALSE;
+  
+  SmcInteractDone ((SmcConn) client->smc_conn, cancel_shutdown);
+  
+  client_save_yourself_possibly_done (client);
+#endif /* HAVE_LIBSM */
+}
+
+/*****************************************************************************/
+/* array helping functions - these function should be replaced by g_lists */
+
+static gchar **
+array_init_from_arg (gint argc, gchar *argv[])
+{
+  gchar **array;
+  int i;
+
+  if (argv == NULL)
+    {
+      g_return_val_if_fail (argc == 0, NULL);
+      
+      return NULL;
+    }
+  else
+    {
+      /* Now initialize the array.  */
+      array = g_new (gchar *, argc + 1);
+
+      for(i = 0; i < argc; i++)
+	array[i] = g_strdup(argv[i]);
+      
+      array[i] = NULL;
+    }
+
+  return array;
+}
diff --git a/libgnomeui/gnome-client.h b/libgnomeui/gnome-client.h
new file mode 100644
index 0000000..cbdd740
--- /dev/null
+++ b/libgnomeui/gnome-client.h
@@ -0,0 +1,453 @@
+/* gnome-client.h - GNOME session management client support
+ *
+ * Copyright (C) 1998 Carsten Schaar
+ * All rights reserved
+ *
+ * Author: Carsten Schaar <nhadcasc fs-maphy uni-hannover de>
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#ifndef GNOME_CLIENT_H
+#define GNOME_CLIENT_H
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <gtk/gtkobject.h>
+#include <gtk/gtkdialog.h>
+
+#include <libgnome/gnome-program.h>
+
+G_BEGIN_DECLS
+
+#define GNOME_TYPE_CLIENT            (gnome_client_get_type ())
+#define GNOME_CLIENT(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_CLIENT, GnomeClient))
+#define GNOME_CLIENT_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_CLIENT, GnomeClientClass))
+#define GNOME_IS_CLIENT(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_CLIENT))
+#define GNOME_IS_CLIENT_CLASS(klass) (GTK_CHECK_CLASS_TYPE (((klass), GNOME_TYPE_CLIENT))
+#define GNOME_CLIENT_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_CLIENT, GnomeClientClass))
+
+#define GNOME_CLIENT_CONNECTED(obj) (GNOME_CLIENT (obj)->smc_conn)
+
+typedef struct _GnomeClient      GnomeClient;
+typedef struct _GnomeClientClass GnomeClientClass;
+
+
+typedef enum
+{
+  GNOME_INTERACT_NONE,
+  GNOME_INTERACT_ERRORS,
+  GNOME_INTERACT_ANY
+} GnomeInteractStyle;
+
+typedef enum
+{
+  GNOME_DIALOG_ERROR,
+  GNOME_DIALOG_NORMAL
+} GnomeDialogType;
+
+typedef enum
+{
+  /* update structure when adding an enum */
+  GNOME_SAVE_GLOBAL,
+  GNOME_SAVE_LOCAL,
+  GNOME_SAVE_BOTH
+} GnomeSaveStyle;
+
+typedef enum
+{
+  /* update structure when adding an enum */
+  GNOME_RESTART_IF_RUNNING,
+  GNOME_RESTART_ANYWAY,
+  GNOME_RESTART_IMMEDIATELY,
+  GNOME_RESTART_NEVER
+} GnomeRestartStyle;
+
+typedef enum
+{
+  /* update structure when adding an enum */
+  GNOME_CLIENT_IDLE,
+  GNOME_CLIENT_SAVING_PHASE_1,
+  GNOME_CLIENT_WAITING_FOR_PHASE_2,
+  GNOME_CLIENT_SAVING_PHASE_2,
+  GNOME_CLIENT_FROZEN,
+  GNOME_CLIENT_DISCONNECTED,
+  GNOME_CLIENT_REGISTERING
+} GnomeClientState;
+
+typedef enum
+{
+  GNOME_CLIENT_IS_CONNECTED= 1 << 0,
+  GNOME_CLIENT_RESTARTED   = 1 << 1,
+  GNOME_CLIENT_RESTORED    = 1 << 2
+} GnomeClientFlags;
+
+
+typedef void (*GnomeInteractFunction) (GnomeClient     *client,
+				       gint             key,
+				       GnomeDialogType  dialog_type,
+				       gpointer         data);
+
+struct _GnomeClient
+{
+  GtkObject           object;
+
+  /* general information about the connection to the session manager */
+  gpointer            smc_conn;
+
+  /* client id of this client */
+  gchar              *client_id;
+
+  /* Previous client id of this client.  */
+  gchar		     *previous_id;
+
+  /* Prefix for per save configuration files.  */
+  gchar              *config_prefix;
+
+  /* Prefix for app configuration files.  */
+  gchar              *global_config_prefix;
+
+  /* Static command line options.  */
+  GList              *static_args;
+
+  /* The following properties are predefined in the X session
+     management protocol.  The entries marked with a 'x' are required
+     by the session management protocol.  The entries marked with a
+     's' are set automatically when creating a new gnome client.  */
+  gchar             **clone_command;        /*[xs]*/
+  gchar              *current_directory;    /*[  ]*/
+  gchar             **discard_command;      /*[  ]*/
+  GHashTable         *environment;          /*[  ]*/
+  pid_t               process_id;           /*[ s]*/
+  gchar              *program;              /*[xs]*/
+  gchar             **resign_command;       /*[  ]*/
+  gchar             **restart_command;      /*[xs]*/
+  GnomeRestartStyle   restart_style;        /*[  ]*/
+  gchar             **shutdown_command;     /*[  ]*/
+  gchar              *user_id;              /*[xs]*/
+
+  GSList             *interaction_keys;
+
+
+  gint                input_id;
+
+  /* values sent with the last SaveYourself message */
+  GnomeSaveStyle      save_style : 2;
+  GnomeInteractStyle  interact_style : 2;
+
+  /* other internal state information */
+  GnomeClientState    state : 3;
+
+  gboolean            shutdown : 1;
+  gboolean            fast : 1;
+  gboolean            save_phase_2_requested : 1;
+  gboolean            save_successfull : 1;
+  gboolean            save_yourself_emitted : 1;
+};
+
+
+struct _GnomeClientClass
+{
+  GtkObjectClass parent_class;
+
+  gboolean (* save_yourself)  (GnomeClient        *client,
+			       gint                phase,
+			       GnomeSaveStyle      save_style,
+			       gint                shutdown,
+			       GnomeInteractStyle  interact_style,
+			       gint                fast);
+  void (* die)                (GnomeClient        *client);
+  void (* save_complete)      (GnomeClient        *client);
+  void (* shutdown_cancelled) (GnomeClient        *client);
+
+  void (* connect)            (GnomeClient        *client,
+			       gint                restarted);
+  void (* disconnect)         (GnomeClient        *client);
+};
+
+extern GnomeModuleInfo gnome_client_module_info;
+#define GNOME_CLIENT_INIT GNOME_PARAM_MODULE,&gnome_client_module_info
+#define GNOME_CLIENT_PARAM_SM_CONNECT "B:libgnomeui/gnome-client/sm_connect"
+
+/* For internal use by the gnome-libs: */
+guint        gnome_client_get_type (void) G_GNUC_CONST;
+
+/* Get the master session management client.  This master client gets
+   a client id, that may be specified by the '--sm-client-id' command
+   line option.  A master client will be generated by 'gnome-init'.
+   If possible the master client will contact the session manager
+   after command-line parsing is finished (unless
+   'gnome_client_disable_master_connection' was called).  The master
+   client will also set the SM_CLIENT_ID property on the client leader
+   window of your application.  
+
+   Additionally, the master client gets some static arguments set
+   automatically (see 'gnome_client_add_static_arg' for static
+   arguments): 'gnome_init' passes all the command line options which 
+   are recognised by gtk as static arguments to the master client. */
+GnomeClient *gnome_master_client 	         (void);
+
+/* Get the config prefix for a client. This config prefix provides a
+   suitable place to store any details about the state of the client 
+   which can not be described using the app's command line arguments (as
+   set in the restart command). You may push the returned value using
+   'gnome_config_push_prefix' and read or write any values you require. */
+const gchar*       gnome_client_get_config_prefix        (GnomeClient *client);
+
+/* Get the config prefix that will be returned by the previous function
+   for clients which have NOT been restarted or cloned (i.e. for clients 
+   started by the user without `--sm-' options). This config prefix may be
+   used to write the user's preferred config for these "new" clients.
+
+   You could also use this prefix as a place to store and retrieve config
+   details that you wish to apply to ALL instances of the app. However, 
+   this practice limits the users freedom to configure each instance in
+   a different way so it should be used with caution. */
+const gchar*       gnome_client_get_global_config_prefix (GnomeClient *client);
+
+/* Set the value used for the global config prefix. The config prefixes 
+   returned by gnome_client_get_config_prefix are formed by extending
+   this prefix with an unique identifier.
+   
+   The global config prefix defaults to a name based on the name of
+   the executable. This function allows you to set it to a different
+   value. It should be called BEFORE retrieving the config prefix for
+   the first time. Later calls will be ignored.
+
+   For example, setting a global config prefix of "/app.d/session/"
+   would ensure that all your session save files or directories would
+   be gathered together into the app.d directory. */
+void         gnome_client_set_global_config_prefix (GnomeClient *client,
+						    const gchar* prefix);
+
+/* Returns some flags, that give additional information about this
+   client.  Right now, the following flags are supported:
+  
+   - GNOME_CLIENT_IS_CONNECTED: The client is connected to a session
+     manager (It's the same information like using
+     GNOME_CLIENT_CONNECTED).
+   
+   - GNOME_CLIENT_RESTARTED: The client has been restarted, i. e. it
+     has been running with the same client id before.
+     
+   - GNOME_CLIENT_RESTORED: This flag is only used for the master
+     client.  It indicates, that there may be a configuraion file from
+     which the clients state should be restored (using the
+     gnome_client_get_config_prefix call).  */
+   
+GnomeClientFlags gnome_client_get_flags            (GnomeClient *client);
+
+/* The following functions are used to set or unset the session
+   management properties that are used by the session manager to determine 
+   how to handle the app. If you want to unset an array property, you 
+   have to specify a NULL argv, if you want to unset a string property 
+   you have to specify NULL as parameter.
+
+   The `--sm-' options are automatically added as the first arguments
+   to the restart and clone commands and you should not try to set them. */
+
+/* The session manager usually only restarts clients which were running
+   when the session was last saved. You can set the restart style to make
+   the manager restart the client:
+   -  at the start of every session (GNOME_RESTART_ANYWAY) or 
+   -  whenever the client dies (GNOME_RESTART_IMMEDIATELY) or 
+   -  never (GNOME_RESTART_NEVER). */
+void         gnome_client_set_restart_style      (GnomeClient *client,
+						  GnomeRestartStyle style);
+
+/* The gnome-session manager includes an extension to the protocol which
+   allows the order in which clients are started up to be organised into
+   a number of run levels. This function may be used to inform the
+   gnome-session manager of where this client should appear in this
+   run level ordering. The priority runs from 0 (started first) to 99
+   (started last) and defaults to 50. Users may override the value
+   that is suggested to gnome-session by calling this function. */
+void         gnome_client_set_priority      (GnomeClient *client,
+					     guint priority);
+
+/* Executing the restart command on the local host should reproduce
+   the state of the client at the time of the session save as closely
+   as possible. Saving config info under the gnome_client_get_config_prefix
+   is generally useful. */
+void         gnome_client_set_restart_command    (GnomeClient *client,
+						  gint argc, gchar *argv[]);
+
+/* This function provides an alternative way of adding new arguments
+   to the restart command. The arguments are placed before the arguments
+   specified by 'gnome_client_set_restart_command' and after the arguments
+   recognised by gtk specified by the user on the original command line. */
+void         gnome_client_add_static_arg (GnomeClient *client, ...);
+
+/* Executing the discard command on the local host should delete the
+   information saved as part of the session save that was in progress
+   when the discard command was set. For example:
+
+     gchar *prefix = gnome_client_get_config_prefix (client);
+     gchar *argv[] = { "rm", "-r", NULL };
+     argv[2] = gnome_config_get_real_path (prefix);
+     gnome_client_set_discard_command (client, 3, argv); */
+void         gnome_client_set_discard_command    (GnomeClient *client,
+						  gint argc, gchar *argv[]);
+
+/* These two commands are used by clients that use the GNOME_RESTART_ANYWAY
+   restart style to to undo their effects (these clients usually perform 
+   initialisation functions and leave effects behind after they die).
+   The shutdown command simply undoes the effects of the client. It is 
+   executed during a normal logout. The resign command combines the effects 
+   of a shutdown command and a discard command. It is executed when the user
+   decides that the client should cease to be restarted. */
+void         gnome_client_set_resign_command     (GnomeClient *client,
+						  gint argc, gchar *argv[]);
+void         gnome_client_set_shutdown_command   (GnomeClient *client,
+						  gint argc, gchar *argv[]);
+
+/* All the preceeding session manager commands are executed in the directory 
+   and environment set up by these two commands: */
+void         gnome_client_set_current_directory  (GnomeClient *client,
+						  const gchar *dir);
+void         gnome_client_set_environment        (GnomeClient *client,
+						  const gchar *name,
+						  const gchar *value);
+
+/* These four values are set automatically to the values required by the 
+   session manager and you should not need to change them. The clone
+   command is directly copied from the restart command. */
+void         gnome_client_set_clone_command      (GnomeClient *client, 
+						  gint argc, gchar *argv[]);
+void         gnome_client_set_process_id         (GnomeClient *client, 
+						  pid_t pid);
+void         gnome_client_set_program            (GnomeClient *client, 
+						  const gchar *program);
+void         gnome_client_set_user_id            (GnomeClient *client,
+						  const gchar *user_id);
+
+/* The following function may be called during a "save_youself" handler
+   to request that a (modal) dialog is presented to the user. The session 
+   manager decides when the dialog is shown and it will not be shown
+   unless the interact_style == GNOME_INTERACT_ANY. A "Cancel Logout"
+   button will be added during a shutdown. */
+void         gnome_client_save_any_dialog       (GnomeClient *client,
+					         GtkDialog   *dialog);
+
+/* The following function may be called during a "save_youself" handler
+   when an error has occured during the save. The session manager decides 
+   when the dialog is shown and it will not be shown when the interact_style
+   == GNOME_INTERACT_NONE.  A "Cancel Logout" button will be added 
+   during a shutdown. */
+void         gnome_client_save_error_dialog      (GnomeClient *client,
+					          GtkDialog   *dialog);
+
+/* Request the session managaer to emit the "save_yourself" signal for 
+   a second time after all the clients in the session have ceased 
+   interacting with the user and entered an idle state. This might be 
+   useful if your app manages other apps and requires that they are in 
+   an idle state before saving its final data. */
+void         gnome_client_request_phase_2        (GnomeClient *client);
+
+/* Request the session manager to save the session in some way. The
+   arguments correspond with the arguments passed to the "save_yourself"
+   signal handler.
+
+   The save_style indicates whether the save should affect data accessible 
+   to other users (GNOME_SAVE_GLOBAL) or only the state visible to 
+   the current user (GNOME_SAVE_LOCAL) or both. Setting shutdown to 
+   TRUE will initiate a logout. The interact_style specifies which kinds 
+   of interaction will be available. Setting fast to TRUE will limit the 
+   save to setting the session manager properties plus any essential data. 
+   Setting the value of global to TRUE will request that all the other 
+   apps in the session do a save as well. A global save is mandatory when 
+   doing a shutdown. */
+void	     gnome_client_request_save (GnomeClient	       *client,
+				        GnomeSaveStyle		save_style,
+				        gboolean		shutdown,
+				        GnomeInteractStyle	interact_style,
+				        gboolean		fast,
+				        gboolean		global);
+
+/* Flush the underlying connection to the session manager.  This is 
+   useful if you have some pending changes that you want to make sure 
+   get committed.  */
+void         gnome_client_flush (GnomeClient *client);
+
+/* Normally the master client is connected to the session manager
+   automatically, when calling 'gnome_init'.  One can disable this
+   automatic connect by calling this function. Using this function
+   should definitely be an exception.  */
+void         gnome_client_disable_master_connection (void);
+
+/* Create a new session management client and try to connect to a
+   session manager. This is useful if you are acting as a proxy for
+   other executables that do not communicate with session manager.  */
+GnomeClient *gnome_client_new                    (void);
+
+/* Create a new session management client.  */
+GnomeClient *gnome_client_new_without_connection (void);
+
+/* Try to connect to a session manager.  If the client was created
+   with a valid session management client id, we will try to connect
+   to the manager with this old id.  If the connection was successfull,
+   the "connect" signal will be emitted, after some default properties
+   have been sent to the session manager.  */
+void         gnome_client_connect                (GnomeClient *client);
+
+/* Disconnect from the session manager.  After disconnecting, the
+   "disconnect" signal will be emitted. */
+void         gnome_client_disconnect             (GnomeClient *client);
+
+/* Set the client id.  This is only possible, if the client is not
+   connected to a session manager.  */
+void         gnome_client_set_id                 (GnomeClient *client,
+						  const gchar *client_id);
+
+/* Get the client id of a session management client object.  If this
+   object has never been connected to a session manager and a client
+   id hasn't been set, this function return 'NULL'.  */
+const gchar*       gnome_client_get_id                 (GnomeClient *client);
+
+/* Get the client id from the last session.  If this client was not
+   recreated from a previous session, returns NULL. The session 
+   manager tries to maintain the same id from one session to another. */
+const gchar*       gnome_client_get_previous_id        (GnomeClient *client);
+
+/* Use the following functions, if you want to interact with the user
+   during a "save_yourself" handler without being restricted to using 
+   the dialog based commands gnome_client_save_[any/error]_dialog.  
+   If and when the session manager decides that it's the app's turn to 
+   interact then 'func' will be called with the specified arguments and 
+   a unique 'GnomeInteractionKey'. The session manager will block other 
+   clients from interacting until this key is returned with 
+   'gnome_interaction_key_return'.  */
+void         gnome_client_request_interaction    (GnomeClient *client,
+						  GnomeDialogType dialog,
+						  GnomeInteractFunction func,
+						  gpointer client_data);
+
+void         gnome_client_request_interaction_interp (GnomeClient *client,
+						      GnomeDialogType dialog,
+						      GtkCallbackMarshal func,
+						      gpointer data,
+						      GtkDestroyNotify destroy);
+
+/* 'gnome_interaction_key_return' is used to tell gnome, that you are
+   finished with interaction */
+void         gnome_interaction_key_return        (gint     key,
+						  gboolean cancel_shutdown);
+
+G_END_DECLS
+
+#endif /* GNOME_CLIENT_H */
diff --git a/libgnomeui/gnome-color-picker.c b/libgnomeui/gnome-color-picker.c
new file mode 100644
index 0000000..6029ffb
--- /dev/null
+++ b/libgnomeui/gnome-color-picker.c
@@ -0,0 +1,1115 @@
+/*
+ * Copyright (C) 1998, 1999 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+/* Color picker button for GNOME
+ *
+ * Author: Federico Mena <federico nuclecu unam mx>
+ */
+
+#include <config.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkalignment.h>
+#include <gtk/gtkcolorsel.h>
+#include <gtk/gtkcolorseldialog.h>
+#include <gtk/gtkdnd.h>
+#include <gtk/gtkdrawingarea.h>
+#include <gtk/gtkframe.h>
+#include <gtk/gtksignal.h>
+#include <gtk/gtkcompat.h>
+#include "gnome-color-picker.h"
+#include <libgnome/gnome-i18n.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtkbutton.h>
+
+#include <libgnomeuiP.h>
+
+/* These are the dimensions of the color sample in the color picker */
+#define COLOR_PICKER_WIDTH  20
+#define COLOR_PICKER_HEIGHT 12
+#define COLOR_PICKER_PAD    1
+
+/* Size of checks and gray levels for alpha compositing checkerboard*/
+#define CHECK_SIZE  4
+#define CHECK_DARK  (1.0 / 3.0)
+#define CHECK_LIGHT (2.0 / 3.0)
+
+struct _GnomeColorPickerPrivate {
+	GdkPixbuf *pixbuf;	/* Pixbuf for rendering dithered sample */
+	GdkGC *gc;		/* GC for drawing */
+
+	GtkWidget *drawing_area;/* Drawing area for color sample */
+	GtkWidget *cs_dialog;	/* Color selection dialog */
+
+	gchar *title;		/* Title for the color selection window */
+
+	gdouble r, g, b, a;	/* Red, green, blue, and alpha values */
+
+	guint dither : 1;	/* Dither or just paint a solid color? */
+	guint use_alpha : 1;	/* Use alpha or not */
+};
+
+enum {
+	PROP_0,
+	PROP_DITHER,
+	PROP_USE_ALPHA,
+	PROP_TITLE,
+	PROP_RED,
+	PROP_GREEN,
+	PROP_BLUE,
+	PROP_ALPHA,
+	PROP_COLOR,
+	PROP_COLOR_GDK,
+	PROP_COLOR_RGBA
+};
+
+enum {
+	COLOR_SET,
+	LAST_SIGNAL
+};
+
+static void gnome_color_picker_class_init (GnomeColorPickerClass *class);
+static void gnome_color_picker_init       (GnomeColorPicker      *cp);
+static void gnome_color_picker_destroy    (GtkObject             *object);
+static void gnome_color_picker_finalize   (GObject               *object);
+static void gnome_color_picker_clicked    (GtkButton             *button);
+static void gnome_color_picker_state_changed (GtkWidget *widget, GtkStateType previous_state);
+static void gnome_color_picker_realize (GtkWidget *widget);
+static void gnome_color_picker_style_set (GtkWidget *widget, GtkStyle *previous_style);
+static void drag_data_get		(GtkWidget          *widget,
+					 GdkDragContext     *context,
+					 GtkSelectionData   *selection_data,
+					 guint               info,
+					 guint               time,
+					 GnomeColorPicker   *cpicker);
+static void drag_data_received		(GtkWidget        *widget,
+					 GdkDragContext   *context,
+					 gint              x,
+					 gint              y,
+					 GtkSelectionData *selection_data,
+					 guint             info,
+					 guint32           time,
+					 GnomeColorPicker *cpicker);
+static void gnome_color_picker_set_property (GObject            *object,
+					     guint               param_id,
+					     const GValue       *value,
+					     GParamSpec         *pspec);
+static void gnome_color_picker_get_property (GObject            *object,
+					     guint               param_id,
+					     GValue             *value,
+					     GParamSpec         *pspec);
+
+
+static guint color_picker_signals[LAST_SIGNAL] = { 0 };
+
+static GtkButtonClass *parent_class;
+
+static GtkTargetEntry drop_types[] = { { "application/x-color", 0, 0 } };
+
+GtkType
+gnome_color_picker_get_type (void)
+{
+	static GtkType cp_type = 0;
+
+	if (!cp_type) {
+		GtkTypeInfo cp_info = {
+			"GnomeColorPicker",
+			sizeof (GnomeColorPicker),
+			sizeof (GnomeColorPickerClass),
+			(GtkClassInitFunc) gnome_color_picker_class_init,
+			(GtkObjectInitFunc) gnome_color_picker_init,
+			NULL, /* reserved_1 */
+			NULL, /* reserved_2 */
+			(GtkClassInitFunc) NULL
+		};
+
+		cp_type = gtk_type_unique (gtk_button_get_type (), &cp_info);
+	}
+
+	return cp_type;
+}
+
+static void
+gnome_color_picker_class_init (GnomeColorPickerClass *class)
+{
+	GtkObjectClass *object_class;
+	GObjectClass *gobject_class;
+	GtkWidgetClass *widget_class;
+	GtkButtonClass *button_class;
+
+	object_class = (GtkObjectClass *) class;
+	gobject_class = (GObjectClass *) class;
+	button_class = (GtkButtonClass *) class;
+	widget_class = (GtkWidgetClass *) class;
+	parent_class = gtk_type_class (gtk_button_get_type ());
+
+	color_picker_signals[COLOR_SET] =
+		gtk_signal_new ("color_set",
+				GTK_RUN_FIRST,
+				GTK_CLASS_TYPE (object_class),
+				GTK_SIGNAL_OFFSET (GnomeColorPickerClass, color_set),
+				gnome_marshal_VOID__UINT_UINT_UINT_UINT,
+				GTK_TYPE_NONE, 4,
+				GTK_TYPE_UINT,
+				GTK_TYPE_UINT,
+				GTK_TYPE_UINT,
+				GTK_TYPE_UINT);
+
+	gobject_class->get_property = gnome_color_picker_get_property;
+	gobject_class->set_property = gnome_color_picker_set_property;
+
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_DITHER,
+                 g_param_spec_boolean ("dither", NULL, NULL,
+				       TRUE,
+				       (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_USE_ALPHA,
+                 g_param_spec_boolean ("use_alpha", NULL, NULL,
+				       FALSE,
+				       (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_TITLE,
+                 g_param_spec_string ("title", NULL, NULL,
+				      NULL,
+				      (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_RED,
+                 g_param_spec_uint ("red", NULL, NULL,
+				    0, 255, 0,
+				    (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_GREEN,
+                 g_param_spec_uint ("green", NULL, NULL,
+				    0, 255, 0,
+				    (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_BLUE,
+                 g_param_spec_uint ("blue", NULL, NULL,
+				    0, 255, 0,
+				    (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_ALPHA,
+                 g_param_spec_uint ("alpha", NULL, NULL,
+				    0, 255, 0,
+				    (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+
+	object_class->destroy = gnome_color_picker_destroy;
+	gobject_class->finalize = gnome_color_picker_finalize;
+	widget_class->state_changed = gnome_color_picker_state_changed;
+	widget_class->realize = gnome_color_picker_realize;
+	widget_class->style_set = gnome_color_picker_style_set;
+	button_class->clicked = gnome_color_picker_clicked;
+
+	class->color_set = NULL;
+}
+
+/* Renders the pixmap for the case of dithered or use_alpha */
+static void
+render_dither (GnomeColorPicker *cp)
+{
+	gint dark_r, dark_g, dark_b;
+	gint light_r, light_g, light_b;
+	gint i, j, rowstride;
+	gint c1[3], c2[3];
+	guchar *pixels;
+	guint8 insensitive_r = 0;
+	guint8 insensitive_g = 0;
+	guint8 insensitive_b = 0;
+
+	/* Compute dark and light check colors */
+
+	insensitive_r = GTK_WIDGET(cp)->style->bg[GTK_STATE_INSENSITIVE].red >> 8;
+	insensitive_g = GTK_WIDGET(cp)->style->bg[GTK_STATE_INSENSITIVE].green >> 8;
+	insensitive_b = GTK_WIDGET(cp)->style->bg[GTK_STATE_INSENSITIVE].blue >> 8;
+
+	if (cp->_priv->use_alpha) {
+		dark_r = (int) ((CHECK_DARK + (cp->_priv->r - CHECK_DARK) * cp->_priv->a) * 255.0 + 0.5);
+		dark_g = (int) ((CHECK_DARK + (cp->_priv->g - CHECK_DARK) * cp->_priv->a) * 255.0 + 0.5);
+		dark_b = (int) ((CHECK_DARK + (cp->_priv->b - CHECK_DARK) * cp->_priv->a) * 255.0 + 0.5);
+
+		light_r = (int) ((CHECK_LIGHT + (cp->_priv->r - CHECK_LIGHT) * cp->_priv->a) * 255.0 + 0.5);
+		light_g = (int) ((CHECK_LIGHT + (cp->_priv->g - CHECK_LIGHT) * cp->_priv->a) * 255.0 + 0.5);
+		light_b = (int) ((CHECK_LIGHT + (cp->_priv->b - CHECK_LIGHT) * cp->_priv->a) * 255.0 + 0.5);
+	} else {
+		dark_r = light_r = (int) (cp->_priv->r * 255.0 + 0.5);
+		dark_g = light_g = (int) (cp->_priv->g * 255.0 + 0.5);
+		dark_b = light_b = (int) (cp->_priv->b * 255.0 + 0.5);
+	}
+
+	/* Fill image buffer */
+
+	pixels = gdk_pixbuf_get_pixels (cp->_priv->pixbuf);
+	rowstride = gdk_pixbuf_get_rowstride (cp->_priv->pixbuf);
+	for (j = 0; j < COLOR_PICKER_HEIGHT; j++) {
+		if ((j / CHECK_SIZE) & 1) {
+			c1[0] = dark_r;
+			c1[1] = dark_g;
+			c1[2] = dark_b;
+
+			c2[0] = light_r;
+			c2[1] = light_g;
+			c2[2] = light_b;
+		} else {
+			c1[0] = light_r;
+			c1[1] = light_g;
+			c1[2] = light_b;
+
+			c2[0] = dark_r;
+			c2[1] = dark_g;
+			c2[2] = dark_b;
+		}
+
+		for (i = 0; i < COLOR_PICKER_WIDTH; i++) {
+			if (!GTK_WIDGET_SENSITIVE (GTK_WIDGET (cp)) && (i+j)%2) {
+				*(pixels + j * rowstride + i * 3) = insensitive_r;
+				*(pixels + j * rowstride + i * 3 + 1) = insensitive_g;
+				*(pixels + j * rowstride + i * 3 + 2) = insensitive_b;
+			} else if ((i / CHECK_SIZE) & 1) {
+				*(pixels + j * rowstride + i * 3) = c1[0];
+				*(pixels + j * rowstride + i * 3 + 1) = c1[1];
+				*(pixels + j * rowstride + i * 3 + 2) = c1[2];
+			} else {
+				*(pixels + j * rowstride + i * 3) = c2[0];
+				*(pixels + j * rowstride + i * 3 + 1) = c2[1];
+				*(pixels + j * rowstride + i * 3 + 2) = c2[2];
+			}
+		}
+	}
+	if (cp->_priv->drawing_area->window)
+		gdk_pixbuf_render_to_drawable (cp->_priv->pixbuf,
+					       cp->_priv->drawing_area->window,
+					       cp->_priv->gc,
+					       0, 0, 0, 0,
+					       COLOR_PICKER_WIDTH,
+					       COLOR_PICKER_HEIGHT,
+					       GDK_RGB_DITHER_MAX,
+					       0, 0);
+}
+
+/* Renders the pixmap with the contents of the color sample */
+static void
+render (GnomeColorPicker *cp)
+{
+	if (cp->_priv->dither || cp->_priv->use_alpha)
+		render_dither (cp);
+	else {
+		gint i, j, rowstride;
+		guint8 insensitive_r = 0;
+		guint8 insensitive_g = 0;
+		guint8 insensitive_b = 0;
+		guchar *pixels;
+
+		pixels = gdk_pixbuf_get_pixels (cp->_priv->pixbuf);
+		rowstride = gdk_pixbuf_get_rowstride (cp->_priv->pixbuf);
+		insensitive_r = GTK_WIDGET (cp)->style->bg[GTK_STATE_INSENSITIVE].red >> 8;
+		insensitive_g = GTK_WIDGET (cp)->style->bg[GTK_STATE_INSENSITIVE].green >> 8;
+		insensitive_b = GTK_WIDGET (cp)->style->bg[GTK_STATE_INSENSITIVE].blue >> 8;
+
+		for (i = 0; i < COLOR_PICKER_WIDTH; i++) {
+			for (j = 0; j < COLOR_PICKER_HEIGHT; j++) {
+				if (!GTK_WIDGET_SENSITIVE (GTK_WIDGET (cp)) && (i+j)%2) {
+					*(pixels + j * rowstride + i * 3) = insensitive_r;
+					*(pixels + j * rowstride + i * 3 + 1) = insensitive_g;
+					*(pixels + j * rowstride + i * 3 + 2) = insensitive_b;
+				} else {
+					*(pixels + j * rowstride + i * 3) = cp->_priv->r * 255.0 + 0.5;
+					*(pixels + j * rowstride + i * 3 + 1) = cp->_priv->g * 255.0 + 0.5;
+					*(pixels + j * rowstride + i * 3 + 2) = cp->_priv->b * 255.0 + 0.5;
+				}
+			}
+		}
+	}
+}
+
+/* Handle exposure events for the color picker's drawing area */
+static gint
+expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer data)
+{
+	GnomeColorPicker *cp;
+
+	cp = GNOME_COLOR_PICKER (data);
+	if (cp->_priv->gc == NULL)
+		cp->_priv->gc = gdk_gc_new (widget->window);
+
+	gdk_pixbuf_render_to_drawable (cp->_priv->pixbuf,
+				       widget->window,
+				       cp->_priv->gc,
+				       event->area.x,
+				       event->area.y,
+				       event->area.x,
+				       event->area.y,
+				       event->area.width,
+				       event->area.height,
+				       GDK_RGB_DITHER_MAX,
+				       event->area.x,
+				       event->area.y);
+	return FALSE;
+}
+static void
+gnome_color_picker_realize (GtkWidget *widget)
+{
+	GnomeColorPicker *cp = GNOME_COLOR_PICKER (widget);
+
+	if (GTK_WIDGET_CLASS(parent_class)->realize)
+		GTK_WIDGET_CLASS (parent_class)->realize (widget);
+	render (cp);
+}
+static void
+gnome_color_picker_style_set (GtkWidget *widget, GtkStyle *previous_style)
+{
+	if (GTK_WIDGET_CLASS(parent_class)->style_set)
+		GTK_WIDGET_CLASS (parent_class)->style_set (widget, previous_style);
+	if (GTK_WIDGET_REALIZED (widget))
+		render (GNOME_COLOR_PICKER (widget));
+}
+
+static void
+gnome_color_picker_state_changed (GtkWidget *widget, GtkStateType previous_state)
+{
+	if (widget->state == GTK_STATE_INSENSITIVE || previous_state == GTK_STATE_INSENSITIVE)
+		render (GNOME_COLOR_PICKER (widget));
+}
+
+static void
+drag_data_received (GtkWidget        *widget,
+		    GdkDragContext   *context,
+		    gint              x,
+		    gint              y,
+		    GtkSelectionData *selection_data,
+		    guint             info,
+		    guint32           time,
+		    GnomeColorPicker *cpicker)
+{
+	guint16 *dropped;
+
+	g_return_if_fail (cpicker != NULL);
+	g_return_if_fail (GNOME_IS_COLOR_PICKER (cpicker));
+
+	if (selection_data->length < 0)
+		return;
+
+	if ((selection_data->format != 16) || 
+	    (selection_data->length != 8)) {
+		g_warning (_("Received invalid color data\n"));
+		return;
+	}
+
+
+	dropped = (guint16 *)selection_data->data;
+
+	gnome_color_picker_set_i16(cpicker, dropped[0], dropped[1],
+				   dropped[2], dropped[3]);
+}
+
+static void  
+drag_data_get  (GtkWidget          *widget,
+		GdkDragContext     *context,
+		GtkSelectionData   *selection_data,
+		guint               info,
+		guint               time,
+		GnomeColorPicker   *cpicker)
+{
+	gushort r, g, b, a;
+	guint16 dropped[4];
+
+	gnome_color_picker_get_i16(cpicker, &r, &g, &b, &a);
+
+	dropped[0] = r;
+	dropped[1] = g;
+	dropped[2] = b;
+	dropped[3] = a;
+
+	gtk_selection_data_set (selection_data,
+				selection_data->target,
+				16/*fromat*/, (guchar *)dropped, 8/*length*/);
+}
+
+static void
+gnome_color_picker_init (GnomeColorPicker *cp)
+{
+	GtkWidget *alignment;
+	GtkWidget *frame;
+	/* Create the widgets */
+
+	cp->_priv = g_new0(GnomeColorPickerPrivate, 1);
+
+	alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
+	gtk_container_set_border_width (GTK_CONTAINER (alignment), COLOR_PICKER_PAD);
+	gtk_container_add (GTK_CONTAINER (cp), alignment);
+	gtk_widget_show (alignment);
+
+	frame = gtk_frame_new (NULL);
+	gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_OUT);
+	gtk_container_add (GTK_CONTAINER (alignment), frame);
+	gtk_widget_show (frame);
+
+	gtk_widget_push_colormap (gdk_rgb_get_cmap ());
+
+	cp->_priv->drawing_area = gtk_drawing_area_new ();
+
+	gtk_drawing_area_size (GTK_DRAWING_AREA (cp->_priv->drawing_area), COLOR_PICKER_WIDTH, COLOR_PICKER_HEIGHT);
+	gtk_signal_connect (GTK_OBJECT (cp->_priv->drawing_area), "expose_event",
+			    (GtkSignalFunc) expose_event,
+			    cp);
+	gtk_container_add (GTK_CONTAINER (frame), cp->_priv->drawing_area);
+	gtk_widget_show (cp->_priv->drawing_area);
+
+	cp->_priv->title = g_strdup (_("Pick a color")); /* default title */
+
+	/* Create the buffer for the image so that we can create an image.  Also create the
+	 * picker's pixmap.
+	 */
+
+	cp->_priv->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, COLOR_PICKER_WIDTH, COLOR_PICKER_HEIGHT);
+
+	cp->_priv->gc = NULL;
+	gtk_widget_pop_colormap ();
+
+	/* Start with opaque black, dither on, alpha disabled */
+
+	cp->_priv->r = 0.0;
+	cp->_priv->g = 0.0;
+	cp->_priv->b = 0.0;
+	cp->_priv->a = 1.0;
+	cp->_priv->dither = TRUE;
+	cp->_priv->use_alpha = FALSE;
+
+	gtk_drag_dest_set (GTK_WIDGET (cp),
+			   GTK_DEST_DEFAULT_MOTION |
+			   GTK_DEST_DEFAULT_HIGHLIGHT |
+			   GTK_DEST_DEFAULT_DROP,
+			   drop_types, 1, GDK_ACTION_COPY);
+	gtk_drag_source_set (GTK_WIDGET(cp),
+			     GDK_BUTTON1_MASK|GDK_BUTTON3_MASK,
+			     drop_types, 1,
+			     GDK_ACTION_COPY);
+	gtk_signal_connect (GTK_OBJECT (cp),
+			    "drag_data_received",
+			    GTK_SIGNAL_FUNC (drag_data_received), cp);
+	gtk_signal_connect (GTK_OBJECT (cp),
+			    "drag_data_get",
+			    GTK_SIGNAL_FUNC (drag_data_get), cp);
+}
+
+static void
+gnome_color_picker_destroy (GtkObject *object)
+{
+	GnomeColorPicker *cp;
+
+	/* remember, destroy can be run multiple times! */
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GNOME_IS_COLOR_PICKER (object));
+
+	cp = GNOME_COLOR_PICKER (object);
+
+	if(cp->_priv->pixbuf)
+		gdk_pixbuf_unref (cp->_priv->pixbuf);
+	cp->_priv->pixbuf = NULL;
+	if(cp->_priv->gc)
+		gdk_gc_destroy (cp->_priv->gc);
+	cp->_priv->gc = NULL;
+
+	if (cp->_priv->cs_dialog)
+		gtk_widget_destroy (cp->_priv->cs_dialog);
+	cp->_priv->cs_dialog = NULL;
+
+	g_free (cp->_priv->title);
+	cp->_priv->title = NULL;
+
+	if (GTK_OBJECT_CLASS (parent_class)->destroy)
+		(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gnome_color_picker_finalize (GObject *object)
+{
+	GnomeColorPicker *cp;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GNOME_IS_COLOR_PICKER (object));
+
+	cp = GNOME_COLOR_PICKER (object);
+
+	g_free (cp->_priv);
+	cp->_priv = NULL;
+
+	if (G_OBJECT_CLASS (parent_class)->finalize)
+		(* G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+
+/**
+ * gnome_color_picker_new
+ *
+ * Creates a new GNOME color picker widget. This returns a widget in the form of a small button
+ * containing a swatch representing the current selected color. When the button is clicked,
+ * a color-selection dialog will open, allowing the user to select a color. The swatch will be
+ * updated to reflect the new color when the user finishes.
+ *
+ * Returns:
+ * Pointer to new GNOME color picker widget.
+ */
+
+GtkWidget *
+gnome_color_picker_new (void)
+{
+	return GTK_WIDGET (gtk_type_new (gnome_color_picker_get_type ()));
+}
+
+/* Callback used when the color selection dialog is destroyed */
+static gboolean
+cs_destroy (GtkWidget *widget, gpointer data)
+{
+	GnomeColorPicker *cp;
+
+	cp = GNOME_COLOR_PICKER (data);
+
+	cp->_priv->cs_dialog = NULL;
+
+	return FALSE;
+}
+
+/* Callback for when the OK button in the color selection dialog is clicked */
+static void
+cs_ok_clicked (GtkWidget *widget, gpointer data)
+{
+	GnomeColorPicker *cp;
+	gdouble color[4];
+	gushort r, g, b, a;
+
+	cp = GNOME_COLOR_PICKER (data);
+
+	gtk_color_selection_get_color (GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (cp->_priv->cs_dialog)->colorsel),
+				       color);
+	gtk_widget_destroy (cp->_priv->cs_dialog);
+
+	cp->_priv->r = color[0];
+	cp->_priv->g = color[1];
+	cp->_priv->b = color[2];
+	cp->_priv->a = cp->_priv->use_alpha ? color[3] : 1.0;
+
+	render (cp);
+	gtk_widget_draw (cp->_priv->drawing_area, NULL);
+
+	/* Notify the world that the color was set */
+
+	gnome_color_picker_get_i16 (cp, &r, &g, &b, &a);
+	gtk_signal_emit (GTK_OBJECT (cp), color_picker_signals[COLOR_SET],
+			 r, g, b, a);
+}
+
+static int
+key_pressed (GtkWidget *widget, GdkEventKey *event, GnomeColorPicker *cp)
+{
+	if (event->keyval == GDK_Escape){
+		gtk_button_clicked (GTK_BUTTON (GTK_COLOR_SELECTION_DIALOG (widget)->cancel_button));
+		return 1;
+	}
+	return 0;
+}
+
+static void
+gnome_color_picker_clicked (GtkButton *button)
+{
+	GnomeColorPicker *cp;
+	GtkColorSelectionDialog *csd;
+	gdouble color[4];
+
+	g_return_if_fail (button != NULL);
+	g_return_if_fail (GNOME_IS_COLOR_PICKER (button));
+
+	cp = GNOME_COLOR_PICKER (button);
+
+	/*if dialog already exists, make sure it's shown and raised*/
+	if(cp->_priv->cs_dialog) {
+		csd = GTK_COLOR_SELECTION_DIALOG (cp->_priv->cs_dialog);
+		gtk_widget_show (cp->_priv->cs_dialog);
+		if (cp->_priv->cs_dialog->window)
+			gdk_window_raise(cp->_priv->cs_dialog->window);
+	} else {
+		/* Create the dialog and connects its buttons */
+                GtkWidget *parent;
+
+                parent = gtk_widget_get_toplevel(GTK_WIDGET(cp));
+                
+		cp->_priv->cs_dialog = gtk_color_selection_dialog_new (cp->_priv->title);
+
+                if (parent)
+                        gtk_window_set_transient_for(GTK_WINDOW(cp->_priv->cs_dialog),
+                                                     GTK_WINDOW(parent));
+                
+		csd = GTK_COLOR_SELECTION_DIALOG (cp->_priv->cs_dialog);
+		gtk_signal_connect (GTK_OBJECT (cp->_priv->cs_dialog), "destroy",
+				    (GtkSignalFunc) cs_destroy,
+				    cp);
+
+		gtk_signal_connect (GTK_OBJECT (cp->_priv->cs_dialog), "key_press_event",
+				    (GtkSignalFunc) key_pressed, cp);
+		gtk_signal_connect (GTK_OBJECT (csd->ok_button), "clicked",
+				    (GtkSignalFunc) cs_ok_clicked,
+				    cp);
+
+		gtk_signal_connect_object (GTK_OBJECT (csd->cancel_button), "clicked",
+					   (GtkSignalFunc) gtk_widget_destroy,
+					   GTK_OBJECT(cp->_priv->cs_dialog));
+
+		/* FIXME: do something about the help button */
+
+		gtk_window_set_position (GTK_WINDOW (cp->_priv->cs_dialog), GTK_WIN_POS_MOUSE);
+
+		/* If there is a grabed window, set new dialog as modal */
+		if (gtk_grab_get_current())
+			gtk_window_set_modal(GTK_WINDOW(cp->_priv->cs_dialog),TRUE);
+	}
+	gtk_color_selection_set_has_opacity_control (GTK_COLOR_SELECTION (csd->colorsel),
+						     cp->_priv->use_alpha);
+
+	color[0] = cp->_priv->r;
+	color[1] = cp->_priv->g;
+	color[2] = cp->_priv->b;
+	color[3] = cp->_priv->use_alpha ? cp->_priv->a : 1.0;
+
+	/* Hack: we set the color twice so that GtkColorSelection will remember its history */
+	gtk_color_selection_set_color (GTK_COLOR_SELECTION (csd->colorsel), color);
+	gtk_color_selection_set_color (GTK_COLOR_SELECTION (csd->colorsel), color);
+
+	gtk_widget_show (cp->_priv->cs_dialog);
+}
+
+
+/**
+ * gnome_color_picker_set_d
+ * @cp: Pointer to GNOME color picker widget.
+ * @r: Red color component, values are in [0.0, 1.0]
+ * @g: Green color component, values are in [0.0, 1.0]
+ * @b: Blue color component, values are in [0.0, 1.0]
+ * @a: Alpha component, values are in [0.0, 1.0]
+ *
+ * Description:
+ * Set color shown in the color picker widget using floating point values.
+ */
+
+void
+gnome_color_picker_set_d (GnomeColorPicker *cp, gdouble r, gdouble g, gdouble b, gdouble a)
+{
+	g_return_if_fail (cp != NULL);
+	g_return_if_fail (GNOME_IS_COLOR_PICKER (cp));
+	g_return_if_fail ((r >=	0.0) &&	(r <= 1.0));
+	g_return_if_fail ((g >=	0.0) &&	(g <= 1.0));
+	g_return_if_fail ((b >=	0.0) && (b <= 1.0));
+	g_return_if_fail ((a >=	0.0) && (a <= 1.0));
+
+	cp->_priv->r = r;
+	cp->_priv->g = g;
+	cp->_priv->b = b;
+	cp->_priv->a = a;
+
+	render (cp);
+	gtk_widget_draw (cp->_priv->drawing_area, NULL);
+}
+
+
+/**
+ * gnome_color_picker_get_d
+ * @cp: Pointer to GNOME color picker widget.
+ * @r: Output location of red color component, values are in [0.0, 1.0]
+ * @g: Output location of green color component, values are in [0.0, 1.0]
+ * @b: Output location of blue color component, values are in [0.0, 1.0]
+ * @a: Output location of alpha color component, values are in [0.0, 1.0]
+ *
+ * Description:
+ * Retrieve color currently selected in the color picker widget in the form of floating point values.
+ */
+
+void
+gnome_color_picker_get_d (GnomeColorPicker *cp, gdouble *r, gdouble *g, gdouble *b, gdouble *a)
+{
+	g_return_if_fail (cp != NULL);
+	g_return_if_fail (GNOME_IS_COLOR_PICKER (cp));
+
+	if (r)
+		*r = cp->_priv->r;
+
+	if (g)
+		*g = cp->_priv->g;
+
+	if (b)
+		*b = cp->_priv->b;
+
+	if (a)
+		*a = cp->_priv->a;
+}
+
+
+/**
+ * gnome_color_picker_set_i8
+ * @cp: Pointer to GNOME color picker widget.
+ * @r: Red color component, values are in [0, 255]
+ * @g: Green color component, values are in [0, 255]
+ * @b: Blue color component, values are in [0, 255]
+ * @a: Alpha component, values are in [0, 255]
+ *
+ * Description:
+ * Set color shown in the color picker widget using 8-bit integer values.
+ */
+
+void
+gnome_color_picker_set_i8 (GnomeColorPicker *cp, guint8 r, guint8 g, guint8 b, guint8 a)
+{
+	g_return_if_fail (cp != NULL);
+	g_return_if_fail (GNOME_IS_COLOR_PICKER (cp));
+	/* Don't check range of r,g,b,a since it's a 8 bit unsigned type. */
+
+	cp->_priv->r = r / 255.0;
+	cp->_priv->g = g / 255.0;
+	cp->_priv->b = b / 255.0;
+	cp->_priv->a = a / 255.0;
+
+	render (cp);
+	gtk_widget_draw (cp->_priv->drawing_area, NULL);
+}
+
+
+/**
+ * gnome_color_picker_get_i8
+ * @cp: Pointer to GNOME color picker widget.
+ * @r: Output location of red color component, values are in [0, 255]
+ * @g: Output location of green color component, values are in [0, 255]
+ * @b: Output location of blue color component, values are in [0, 255]
+ * @a: Output location of alpha color component, values are in [0, 255]
+ *
+ * Description:
+ * Retrieve color currently selected in the color picker widget in the form of 8-bit integer values.
+ */
+
+void
+gnome_color_picker_get_i8 (GnomeColorPicker *cp, guint8 *r, guint8 *g, guint8 *b, guint8 *a)
+{
+	g_return_if_fail (cp != NULL);
+	g_return_if_fail (GNOME_IS_COLOR_PICKER (cp));
+
+	if (r)
+		*r = (guint8) (cp->_priv->r * 255.0 + 0.5);
+
+	if (g)
+		*g = (guint8) (cp->_priv->g * 255.0 + 0.5);
+
+	if (b)
+		*b = (guint8) (cp->_priv->b * 255.0 + 0.5);
+
+	if (a)
+		*a = (guint8) (cp->_priv->a * 255.0 + 0.5);
+}
+
+
+/**
+ * gnome_color_picker_set_i16
+ * @cp: Pointer to GNOME color picker widget.
+ * @r: Red color component, values are in [0, 65535]
+ * @g: Green color component, values are in [0, 65535]
+ * @b: Blue color component, values are in [0, 65535]
+ * @a: Alpha component, values are in [0, 65535]
+ *
+ * Description:
+ * Set color shown in the color picker widget using 16-bit integer values.
+ */
+
+void
+gnome_color_picker_set_i16 (GnomeColorPicker *cp, gushort r, gushort g, gushort b, gushort a)
+{
+	g_return_if_fail (cp != NULL);
+	g_return_if_fail (GNOME_IS_COLOR_PICKER (cp));
+	/* Don't check range of r,g,b,a since it's a 16 bit unsigned type. */
+
+	cp->_priv->r = r / 65535.0;
+	cp->_priv->g = g / 65535.0;
+	cp->_priv->b = b / 65535.0;
+	cp->_priv->a = a / 65535.0;
+
+	render (cp);
+	gtk_widget_draw (cp->_priv->drawing_area, NULL);
+}
+
+
+/**
+ * gnome_color_picker_get_i16
+ * @cp: Pointer to GNOME color picker widget.
+ * @r: Output location of red color component, values are in [0, 65535]
+ * @g: Output location of green color component, values are in [0, 65535]
+ * @b: Output location of blue color component, values are in [0, 65535]
+ * @a: Output location of alpha color component, values are in [0, 65535]
+ *
+ * Description:
+ * Retrieve color currently selected in the color picker widget in the form of 16-bit integer values.
+ */
+
+void
+gnome_color_picker_get_i16 (GnomeColorPicker *cp, gushort *r, gushort *g, gushort *b, gushort *a)
+{
+	g_return_if_fail (cp != NULL);
+	g_return_if_fail (GNOME_IS_COLOR_PICKER (cp));
+
+	if (r)
+		*r = (gushort) (cp->_priv->r * 65535.0 + 0.5);
+
+	if (g)
+		*g = (gushort) (cp->_priv->g * 65535.0 + 0.5);
+
+	if (b)
+		*b = (gushort) (cp->_priv->b * 65535.0 + 0.5);
+
+	if (a)
+		*a = (gushort) (cp->_priv->a * 65535.0 + 0.5);
+}
+
+
+/**
+ * gnome_color_picker_set_dither
+ * @cp: Pointer to GNOME color picker widget.
+ * @dither: %TRUE if color sample should be dithered, %FALSE if not.
+ *
+ * Description:
+ * Sets whether the picker should dither the color sample or just paint
+ * a solid rectangle.
+ */
+
+void
+gnome_color_picker_set_dither (GnomeColorPicker *cp, gboolean dither)
+{
+	g_return_if_fail (cp != NULL);
+	g_return_if_fail (GNOME_IS_COLOR_PICKER (cp));
+
+	cp->_priv->dither = dither ? TRUE : FALSE;
+
+	render (cp);
+	gtk_widget_draw (cp->_priv->drawing_area, NULL);
+}
+
+
+/**
+ * gnome_color_picker_get_dither
+ * @cp: Pointer to GNOME color picker widget.
+ *
+ * Description:
+ * Does the picker dither the color sample or just paint
+ * a solid rectangle.
+ *
+ * Returns: %TRUE if color sample is dithered, %FALSE if not.
+ */
+
+gboolean
+gnome_color_picker_get_dither (GnomeColorPicker *cp)
+{
+	g_return_val_if_fail (cp != NULL, FALSE);
+	g_return_val_if_fail (GNOME_IS_COLOR_PICKER (cp), FALSE);
+
+	return cp->_priv->dither ? TRUE : FALSE;
+}
+
+
+/**
+ * gnome_color_picker_set_use_alpha
+ * @cp: Pointer to GNOME color picker widget.
+ * @use_alpha: %TRUE if color sample should use alpha channel, %FALSE if not.
+ *
+ * Description:
+ * Sets whether or not the picker should use the alpha channel.
+ */
+
+void
+gnome_color_picker_set_use_alpha (GnomeColorPicker *cp, gboolean use_alpha)
+{
+	g_return_if_fail (cp != NULL);
+	g_return_if_fail (GNOME_IS_COLOR_PICKER (cp));
+
+	cp->_priv->use_alpha = use_alpha ? TRUE : FALSE;
+
+	render (cp);
+	gtk_widget_draw (cp->_priv->drawing_area, NULL);
+}
+
+/**
+ * gnome_color_picker_get_use_alpha
+ * @cp: Pointer to GNOME color picker widget.
+ *
+ * Description:  Does the picker use the alpha channel?
+ *
+ * Returns:  %TRUE if color sample uses alpha channel, %FALSE if not.
+ */
+
+gboolean
+gnome_color_picker_get_use_alpha (GnomeColorPicker *cp)
+{
+	g_return_val_if_fail (cp != NULL, FALSE);
+	g_return_val_if_fail (GNOME_IS_COLOR_PICKER (cp), FALSE);
+
+	return cp->_priv->use_alpha ? TRUE : FALSE;
+}
+
+
+/**
+ * gnome_color_picker_set_title
+ * @cp: Pointer to GNOME color picker widget.
+ * @title: String containing new window title.
+ *
+ * Description:
+ * Sets the title for the color selection dialog.
+ */
+
+void
+gnome_color_picker_set_title (GnomeColorPicker *cp, const gchar *title)
+{
+	g_return_if_fail (cp != NULL);
+	g_return_if_fail (GNOME_IS_COLOR_PICKER (cp));
+	g_return_if_fail (title != NULL);
+
+	g_free (cp->_priv->title);
+	cp->_priv->title = g_strdup (title);
+
+	if (cp->_priv->cs_dialog)
+		gtk_window_set_title (GTK_WINDOW (cp->_priv->cs_dialog), cp->_priv->title);
+}
+
+/**
+ * gnome_color_picker_get_title
+ * @cp: Pointer to GNOME color picker widget.
+ *
+ * Description:
+ * Gets the title of the color selection dialog.
+ *
+ * Returns:  An internal string, do not free the return value
+ */
+
+const char *
+gnome_color_picker_get_title (GnomeColorPicker *cp)
+{
+	g_return_val_if_fail (cp != NULL, NULL);
+	g_return_val_if_fail (GNOME_IS_COLOR_PICKER (cp), NULL);
+
+	return cp->_priv->title;
+}
+
+static void
+gnome_color_picker_set_property (GObject            *object,
+				 guint               param_id,
+				 const GValue       *value,
+				 GParamSpec         *pspec)
+{
+	GnomeColorPicker *self;
+	gushort r, g, b, a;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GNOME_IS_COLOR_PICKER (object));
+
+	self = GNOME_COLOR_PICKER (object);
+
+	switch (param_id) {
+	case PROP_DITHER:
+		gnome_color_picker_set_dither(self, g_value_get_boolean (value));
+		break;
+	case PROP_USE_ALPHA:
+		gnome_color_picker_set_use_alpha(self, g_value_get_boolean (value));
+		break;
+	case PROP_TITLE:
+		gnome_color_picker_set_title(self, g_value_get_string (value));
+		break;
+	case PROP_RED:
+		gnome_color_picker_get_i16(self, &r, &g, &b, &a);
+		gnome_color_picker_set_i16(self,
+					   g_value_get_uint (value), g, b, a);
+		break;
+	case PROP_GREEN:
+		gnome_color_picker_get_i16(self, &r, &g, &b, &a);
+		gnome_color_picker_set_i16(self,
+					   r, g_value_get_uint (value), b, a);
+		break;
+	case PROP_BLUE:
+		gnome_color_picker_get_i16(self, &r, &g, &b, &a);
+		gnome_color_picker_set_i16(self,
+					   r, g, g_value_get_uint (value), a);
+		break;
+	case PROP_ALPHA:
+		gnome_color_picker_get_i16(self, &r, &g, &b, &a);
+		gnome_color_picker_set_i16(self,
+					   r, g, b, g_value_get_uint (value));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+}
+
+static void
+gnome_color_picker_get_property (GObject            *object,
+				 guint               param_id,
+				 GValue             *value,
+				 GParamSpec         *pspec)
+{
+	GnomeColorPicker *self;
+	gushort val;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GNOME_IS_COLOR_PICKER (object));
+
+	self = GNOME_COLOR_PICKER (object);
+
+	switch (param_id) {
+	case PROP_DITHER:
+		g_value_set_boolean (value, gnome_color_picker_get_dither(self));
+		break;
+	case PROP_USE_ALPHA:
+		g_value_set_boolean (value, gnome_color_picker_get_use_alpha(self));
+		break;
+	case PROP_TITLE:
+		g_value_set_string (value, self->_priv->title);
+		break;
+	case PROP_RED:
+		gnome_color_picker_get_i16(self, &val, NULL, NULL, NULL);
+		g_value_set_uint (value, val);
+		break;
+	case PROP_GREEN:
+		gnome_color_picker_get_i16(self, NULL, &val, NULL, NULL);
+		g_value_set_uint (value, val);
+		break;
+	case PROP_BLUE:
+		gnome_color_picker_get_i16(self, NULL, NULL, &val, NULL);
+		g_value_set_uint (value, val);
+		break;
+	case PROP_ALPHA:
+		gnome_color_picker_get_i16(self, NULL, NULL, NULL, &val);
+		g_value_set_uint (value, val);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+}
diff --git a/libgnomeui/gnome-color-picker.h b/libgnomeui/gnome-color-picker.h
new file mode 100644
index 0000000..f08a721
--- /dev/null
+++ b/libgnomeui/gnome-color-picker.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 1998, 1999 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+/* Color picker button for GNOME
+ *
+ * Author: Federico Mena <federico nuclecu unam mx>
+ */
+
+#ifndef GNOME_COLOR_PICKER_H
+#define GNOME_COLOR_PICKER_H
+
+
+#include <gtk/gtkbutton.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+G_BEGIN_DECLS
+
+
+/* The GnomeColorPicker widget is a simple color picker in a button.  The button displays a sample
+ * of the currently selected color.  When the user clicks on the button, a color selection dialog
+ * pops up.  The color picker emits the "color_changed" signal when the color is set
+ *
+ * By default, the color picker does dithering when drawing the color sample box.  This can be
+ * disabled for cases where it is useful to see the allocated color without dithering.
+ */
+
+#define GNOME_TYPE_COLOR_PICKER            (gnome_color_picker_get_type ())
+#define GNOME_COLOR_PICKER(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_COLOR_PICKER, GnomeColorPicker))
+#define GNOME_COLOR_PICKER_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_COLOR_PICKER, GnomeColorPickerClass))
+#define GNOME_IS_COLOR_PICKER(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_COLOR_PICKER))
+#define GNOME_IS_COLOR_PICKER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_COLOR_PICKER))
+#define GNOME_COLOR_PICKER_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_COLOR_PICKER, GnomeColorPickerClass))
+
+
+typedef struct _GnomeColorPicker        GnomeColorPicker;
+typedef struct _GnomeColorPickerPrivate GnomeColorPickerPrivate;
+typedef struct _GnomeColorPickerClass   GnomeColorPickerClass;
+
+struct _GnomeColorPicker {
+	GtkButton button;
+
+	/*< private >*/
+	GnomeColorPickerPrivate *_priv;
+};
+
+struct _GnomeColorPickerClass {
+	GtkButtonClass parent_class;
+
+	/* Signal that is emitted when the color is set.  The rgba values
+	 * are in the [0, 65535] range.  If you need a different color
+	 * format, use the provided functions to get the values from the
+	 * color picker.
+	 */
+        /*  (should be gushort, but Gtk can't marshal that.) */
+	void (* color_set) (GnomeColorPicker *cp, guint r, guint g, guint b, guint a);
+};
+
+
+/* Standard Gtk function */
+GtkType gnome_color_picker_get_type (void) G_GNUC_CONST;
+
+/* Creates a new color picker widget */
+GtkWidget *gnome_color_picker_new (void);
+
+/* Set/get the color in the picker.  Values are in [0.0, 1.0] */
+void gnome_color_picker_set_d (GnomeColorPicker *cp, gdouble r, gdouble g, gdouble b, gdouble a);
+void gnome_color_picker_get_d (GnomeColorPicker *cp, gdouble *r, gdouble *g, gdouble *b, gdouble *a);
+
+/* Set/get the color in the picker.  Values are in [0, 255] */
+void gnome_color_picker_set_i8 (GnomeColorPicker *cp, guint8 r, guint8 g, guint8 b, guint8 a);
+void gnome_color_picker_get_i8 (GnomeColorPicker *cp, guint8 *r, guint8 *g, guint8 *b, guint8 *a);
+
+/* Set/get the color in the picker.  Values are in [0, 65535] */
+void gnome_color_picker_set_i16 (GnomeColorPicker *cp, gushort r, gushort g, gushort b, gushort a);
+void gnome_color_picker_get_i16 (GnomeColorPicker *cp, gushort *r, gushort *g, gushort *b, gushort *a);
+
+/* Sets whether the picker should dither the color sample or just paint a solid rectangle */
+void gnome_color_picker_set_dither (GnomeColorPicker *cp, gboolean dither);
+gboolean gnome_color_picker_get_dither (GnomeColorPicker *cp);
+
+/* Sets whether the picker should use the alpha channel or not */
+void gnome_color_picker_set_use_alpha (GnomeColorPicker *cp, gboolean use_alpha);
+gboolean gnome_color_picker_get_use_alpha (GnomeColorPicker *cp);
+
+/* Sets the title for the color selection dialog */
+void gnome_color_picker_set_title (GnomeColorPicker *cp, const gchar *title);
+const char * gnome_color_picker_get_title (GnomeColorPicker *cp);
+
+
+G_END_DECLS
+
+#endif
diff --git a/libgnomeui/gnome-cursors.c b/libgnomeui/gnome-cursors.c
new file mode 100644
index 0000000..3dd7d11
--- /dev/null
+++ b/libgnomeui/gnome-cursors.c
@@ -0,0 +1,971 @@
+/* -*- Mode: C; c-set-style: linux indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gnome-cursors.c - Stock GNOME cursors
+   
+   Copyright (C) 1999 Iain Holmes
+   All rights reserved.
+   Contains code by Miguel de Icaza
+   
+   The Gnome 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.
+   
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+/*
+  @NOTATION@
+*/
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include "gnome-gconf.h"
+
+#include <gconf/gconf-client.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gdk/gdkx.h>
+
+#ifdef NEED_GNOMESUPPORT_H
+#  include "gnomesupport.h"
+#endif
+
+#include "gnome-cursors.h"
+#include <unistd.h>
+#include <ctype.h>
+
+static GHashTable *cursortable = NULL;
+
+/*
+ * XPM data
+ */
+
+
+static const char * blank_xpm[] = {
+	"8 1 1 1",
+	"     c None",
+	"        "
+};
+
+static char * default_arrow_xpm[] = {
+"8 14 3 2",
+"  	c None",
+". 	c #000000",
+"+ 	c #FFFFFF",
+"..      ",
+".+.     ",
+".++.    ",
+".+++.   ",
+".++++.  ",
+".+++++. ",
+".++++...",
+".++++.  ",
+".+..+.  ",
+".+. .+. ",
+"..  .+. ",
+"     .+.",
+"     .+.",
+"      . "};
+
+static const char * egg_timer1_xpm[] = {
+"16 16 3 1",
+"       c None",
+".      c #000000",
+"+      c #FFFFFF",
+"   ..........   ",
+"   .        .   ",
+"   .    .   .   ",
+"    ....+.+.    ",
+"    .+..+.+.    ",
+"     ..+.+.     ",
+"     .+....     ",
+"      .+ .      ",
+"      . +.      ",
+"     . .  .     ",
+"     .  + .     ",
+"    . ++.  .    ",
+"    .  +   .    ",
+"   .  +.++  .   ",
+"   . +++.+  .   ",
+"   ..........   "};
+
+static const char * pointing_hand_xpm[] = {
+"16 19 3 1",
+"       c None",
+".      c #000000",
+"+      c #FFFFFF",
+"    ..          ",
+"   .++.         ",
+"   .++.         ",
+"   .++.         ",
+"   .++...       ",
+"   .++.++.      ",
+"   .++.++...    ",
+" . .++.++.++... ",
+".+..++.++.++.++.",
+".++.++.++.++.++.",
+".++.++.++.++.++.",
+".++.++.++.++.++.",
+" .+++++++++++++.",
+" .+++++++++++++.",
+"  .++++++++++++.",
+"  .++++++++++++.",
+"  .+++++++++++. ",
+"   .+++++++++.  ",
+"    .........   "};
+
+static const char * cursor_zoom_in_xpm[] = {
+"32 32 2 1",
+"       c None",
+".      c #000000",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"        ......                  ",
+"       ..     ..                ",
+"      ..       ..               ",
+"      .         .               ",
+"     .    ...    .              ",
+"     .    ...    .              ",
+"     .  .......  .              ",
+"     .  .......  .              ",
+"     .    ...    .              ",
+"      .   ...   ..              ",
+"      ..       . .              ",
+"       ..     . . .             ",
+"        ........ . .            ",
+"         .....  . . .           ",
+"                 . . .          ",
+"                  . . .         ",
+"                   . . .        ",
+"                    . . .       ",
+"                     .   .      ",
+"                      .  .      ",
+"                       ..       ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                "};
+
+static const char * cursor_zoom_out_xpm[] = {
+"32 32 2 1",
+"       c None",
+".      c #000000",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"        ......                  ",
+"       ..     ..                ",
+"      ..       ..               ",
+"      .         .               ",
+"     .           .              ",
+"     .           .              ",
+"     .  .......  .              ",
+"     .  .......  .              ",
+"     .           .              ",
+"      .         ..              ",
+"      ..       . .              ",
+"       ..     . . .             ",
+"        ........ . .            ",
+"         .....  . . .           ",
+"                 . . .          ",
+"                  . . .         ",
+"                   . . .        ",
+"                    . . .       ",
+"                     .   .      ",
+"                      .  .      ",
+"                       ..       ",
+"                                ",
+"                                ",
+"                                ",
+"                                ",
+"                                "};
+
+
+#define hand_closed_data_width 20
+#define hand_closed_data_height 20
+static const char hand_closed_data_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x80, 0x3f, 0x00,
+   0x80, 0xff, 0x00, 0x80, 0xff, 0x00, 0xb0, 0xff, 0x00, 0xf0, 0xff, 0x00,
+   0xe0, 0xff, 0x00, 0xe0, 0x7f, 0x00, 0xc0, 0x7f, 0x00, 0x80, 0x3f, 0x00,
+   0x00, 0x3f, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+/* Made with Gimp */
+#define hand_closed_mask_width 20
+#define hand_closed_mask_height 20
+static const char hand_closed_mask_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x80, 0x3f, 0x00, 0xc0, 0xff, 0x00,
+   0xc0, 0xff, 0x01, 0xf0, 0xff, 0x01, 0xf8, 0xff, 0x01, 0xf8, 0xff, 0x01,
+   0xf0, 0xff, 0x01, 0xf0, 0xff, 0x00, 0xe0, 0xff, 0x00, 0xc0, 0x7f, 0x00,
+   0x80, 0x7f, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+#define hand_open_data_width 20
+#define hand_open_data_height 20
+static const char hand_open_data_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
+   0x60, 0x36, 0x00, 0x60, 0x36, 0x00, 0xc0, 0x36, 0x01, 0xc0, 0xb6, 0x01,
+   0x80, 0xbf, 0x01, 0x98, 0xff, 0x01, 0xb8, 0xff, 0x00, 0xf0, 0xff, 0x00,
+   0xe0, 0xff, 0x00, 0xe0, 0x7f, 0x00, 0xc0, 0x7f, 0x00, 0x80, 0x3f, 0x00,
+   0x00, 0x3f, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+#define hand_open_mask_width 20
+#define hand_open_mask_height 20
+static const char hand_open_mask_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x60, 0x3f, 0x00,
+   0xf0, 0x7f, 0x00, 0xf0, 0x7f, 0x01, 0xe0, 0xff, 0x03, 0xe0, 0xff, 0x03,
+   0xd8, 0xff, 0x03, 0xfc, 0xff, 0x03, 0xfc, 0xff, 0x01, 0xf8, 0xff, 0x01,
+   0xf0, 0xff, 0x01, 0xf0, 0xff, 0x00, 0xe0, 0xff, 0x00, 0xc0, 0x7f, 0x00,
+   0x80, 0x7f, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+static char * horiz_xpm[] = {
+"16 8 3 2",
+"  	c None",
+". 	c #000000",
+"+ 	c #FFFFFF",
+"   ...  ...     ",
+"  .+.    .+.    ",
+" .++......++.   ",
+".++++++++++++.  ",
+".++++++++++++.  ",
+" .++......++.   ",
+"  .+.    .+.    ",
+"   ...  ...     "};
+
+static char * vert_xpm[] = {
+"8 14 3 2",
+"  	c None",
+". 	c #000000",
+"+ 	c #FFFFFF",
+"   ..   ",
+"  .++.  ",
+" .++++. ",
+".++++++.",
+"...++...",
+". .++. .",
+"  .++.  ",
+"  .++.  ",
+". .++. .",
+"...++...",
+".++++++.",
+" .++++. ",
+"  .++.  ",
+"   ..   "};
+
+static char * ne_sw_xpm[] = {
+"16 12 3 2",
+"  	c None",
+". 	c #000000",
+"+ 	c #FFFFFF",
+"       ....     ",
+"      .++++.    ",
+"     . .+++.    ",
+"      .++++.    ",
+"     .+++.+.    ",
+"  . .+++. .     ",
+" . .+++. .      ",
+".+.+++.         ",
+".++++.          ",
+".+++. .         ",
+".++++.          ",
+" ....           "};
+
+static char * nw_se_xpm[] = {
+"16 12 3 2",
+"  	c None",
+". 	c #000000",
+"+ 	c #FFFFFF",
+" ....           ",
+".++++.          ",
+".+++. .         ",
+".++++.          ",
+".+.+++.         ",
+" . .+++. .      ",
+"  . .+++. .     ",
+"     .+++.+.    ",
+"      .++++.    ",
+"     . .+++.    ",
+"      .++++.    ",
+"       ....     "};
+
+static char * nsew_xpm[] = {
+"24 18 3 2",
+"  	c None",
+". 	c #000000",
+"+ 	c #FFFFFF",
+"        ..              ",
+"       .++.             ",
+"      .++++.            ",
+"     .++++++.           ",
+"     .+.++.+.           ",
+"   .. .++++. ..         ",
+"  .++. .++. .++.        ",
+" .++.+.++++.+.++.       ",
+".++++++++++++++++.      ",
+".++++++++++++++++.      ",
+" .++.+.++++.+.++.       ",
+"  .++. .++. .++.        ",
+"   .. .++++. ..         ",
+"     .+.++.+.           ",
+"     .++++++.           ",
+"      .++++.            ",
+"       .++.             ",
+"        ..              "};
+
+static char * corners_xpm[] = {
+"16 12 3 2",
+"  	c None",
+". 	c #000000",
+"+ 	c #FFFFFF",
+" ....  ....     ",
+".++++..++++.    ",
+".+++....+++.    ",
+".++++..++++.    ",
+".+.++++++.+.    ",
+" ...++++...     ",
+" ...++++...     ",
+".+.++++++.+.    ",
+".++++..++++.    ",
+".+++....+++.    ",
+".++++..++++.    ",
+" ....  ....     "};
+
+static char * bar_xpm[] = {
+"8 16 3 2",
+"  	c None",
+". 	c #000000",
+"+ 	c #FFFFFF",
+" .. ..  ",
+".++.++. ",
+" .+++.  ",
+"  .+.   ",
+"  .+.   ",
+"  .+.   ",
+"  .+.   ",
+"  .+.   ",
+"  .+.   ",
+"  .+.   ",
+"  .+.   ",
+"  .+.   ",
+"  .+.   ",
+" .+++.  ",
+".++.++. ",
+" .. ..  "};
+
+static char * question_xpm[] = {
+"24 24 3 2",
+"  	c None",
+". 	c #000000",
+"+ 	c #FFFFFF",
+"..          ......      ",
+".+.        .++++++.     ",
+".++.      .++....++.    ",
+".+++.    .++.    .++.   ",
+".++++.   .+.      .+.   ",
+".+++++.  .+.      .+.   ",
+".++++... .+.      .+.   ",
+".++++.    .       .+.   ",
+".+..+.            .+.   ",
+".+. .+.          .++.   ",
+"..  .+.      ....++.    ",
+"     .+.    .+++++.     ",
+"     .+.    .++...      ",
+"      .     .+.         ",
+"            .+.         ",
+"            .+.         ",
+"             .          ",
+"                        ",
+"             .          ",
+"            .+.         ",
+"            .+.         ",
+"             .          ",
+"                        ",
+"                        "};
+
+#define WHITE { 0x0000, 0xffff, 0xffff, 0xffff }
+#define BLACK { 0x0000, 0x0000, 0x0000, 0x0000 }
+
+
+static GnomeStockCursor default_cursors[] = {
+        {
+                GNOME_STOCK_CURSOR_DEFAULT, /* name */
+                default_arrow_xpm, /* cursor_data */
+                NULL,     /* xbm mask */
+                NULL, NULL, /* bitmap/mask */
+                WHITE, /* foreground */
+                BLACK, /* background */
+                0, 0,     /* hotspot */
+                -1, -1,   /* w x h */
+                0,        /* alpha */
+                GNOME_CURSOR_XPM /* type */
+        },
+        {
+                GNOME_STOCK_CURSOR_BLANK, /* name */
+                blank_xpm, /* cursor_data */
+                NULL, /* xbm mask */
+                NULL, NULL, /* bitmap/mask */
+                WHITE, /* foreground */
+                BLACK, /* background */
+                0, 0,     /* hotspot */
+                -1, -1,   /* w x h */
+                0,        /* alpha */
+                GNOME_CURSOR_XPM /* type */
+        },
+        {
+                GNOME_STOCK_CURSOR_POINTING_HAND, /* name */
+                pointing_hand_xpm, /* cursor_data */
+                NULL, /* xbm mask */
+                NULL, NULL, /* bitmap/mask */
+                WHITE, /* foreground */
+                BLACK, /* background */
+                5, 0,     /* hotspot */
+                -1, -1,   /* w x h */
+                0,        /* alpha */
+                GNOME_CURSOR_XPM /* type */
+        },
+        {
+                GNOME_STOCK_CURSOR_HAND_OPEN, /* name */
+                (gchar*)hand_open_data_bits, /* cursor_data */
+                (gchar*)hand_open_mask_bits,
+                NULL, NULL, /* bitmap/mask */
+                WHITE, /* foreground */
+                BLACK, /* background */
+                10, 10,     /* hotspot */
+                hand_open_data_width, hand_open_data_height,   /* w x h */
+                0,        /* alpha */
+                GNOME_CURSOR_XBM /* type */
+        },
+        {
+                GNOME_STOCK_CURSOR_HAND_CLOSE, /* name */
+                (gchar*)hand_closed_data_bits, /* cursor_data */
+                (gchar*)hand_closed_mask_bits,
+                NULL, NULL, /* bitmap/mask */
+                WHITE, /* foreground */
+                BLACK, /* background */
+                10, 10,     /* hotspot */
+                hand_closed_data_width, hand_closed_data_height,   /* w x h */
+                0,        /* alpha */
+                GNOME_CURSOR_XBM /* type */
+        },
+        {
+                GNOME_STOCK_CURSOR_ZOOM_IN, /* name */
+                cursor_zoom_in_xpm, /* cursor_data */
+                NULL, /* xbm mask */
+                NULL, NULL, /* bitmap/mask */
+                BLACK, /* foreground */
+                WHITE, /* background */
+                10, 10,     /* hotspot */
+                -1, -1,   /* w x h */
+                0,        /* alpha */
+                GNOME_CURSOR_XPM /* type */
+        },
+        {
+                GNOME_STOCK_CURSOR_ZOOM_OUT, /* name */
+                cursor_zoom_out_xpm, /* cursor_data */
+                NULL, /* xbm mask */
+                NULL, NULL, /* bitmap/mask */
+                BLACK, /* foreground */
+                WHITE, /* background */
+                10, 10,     /* hotspot */
+                -1, -1,   /* w x h */
+                0,        /* alpha */
+                GNOME_CURSOR_XPM /* type */
+        },
+        {
+                GNOME_STOCK_CURSOR_EGG_1, /* name */
+                egg_timer1_xpm, /* cursor_data */
+                NULL, /* xbm mask */
+                NULL, NULL, /* bitmap/mask */
+                {0x0, 0xFFFF, 0xFFFF, 0x0}, /* foreground */
+                BLACK, /* background */
+                8, 8,     /* hotspot */
+                -1, -1,   /* w x h */
+                0,        /* alpha */
+                GNOME_CURSOR_XPM /* type */
+        },
+	{
+		GNOME_STOCK_CURSOR_HORIZONTAL, /* name */
+		horiz_xpm, /* cursor_data */
+		NULL, /* xbm_mask */
+		NULL, NULL, /* bitmap/mask */
+		WHITE, /* foreground */
+		BLACK, /* background */
+		6, 3,  /* hotspot */
+		-1, -1,/* w x h */
+		0,     /* alpha */
+		GNOME_CURSOR_XPM /* type */
+	},
+	{
+		GNOME_STOCK_CURSOR_VERTICAL, /* name */
+		vert_xpm, /* cursor_data */
+		NULL, /* xbm_mask */
+		NULL, NULL, /* bitmap/mask */
+		WHITE, /* foreground */
+		BLACK, /* background */
+		3, 6,  /* hotspot */
+		-1, -1,/* w x h */
+		0,     /* alpha */
+		GNOME_CURSOR_XPM /* type */
+	},
+	{
+		GNOME_STOCK_CURSOR_NE_SW, /* name */
+		ne_sw_xpm, /* cursor_data */
+		NULL, /* xbm_mask */
+		NULL, NULL, /* bitmap/mask */
+		WHITE, /* foreground */
+		BLACK, /* background */
+		5, 5,  /* hotspot */
+		-1, -1,/* w x h */
+		0,     /* alpha */
+		GNOME_CURSOR_XPM /* type */
+	},
+	{
+		GNOME_STOCK_CURSOR_NW_SE, /* name */
+		nw_se_xpm, /* cursor_data */
+		NULL, /* xbm_mask */
+		NULL, NULL, /* bitmap/mask */
+		WHITE, /* foreground */
+		BLACK, /* background */
+		5, 5,  /* hotspot */
+		-1, -1,/* w x h */
+		0,     /* alpha */
+		GNOME_CURSOR_XPM /* type */
+	},
+	{
+		GNOME_STOCK_CURSOR_FLEUR, /* name */
+		nsew_xpm, /* cursor_data */
+		NULL, /* xbm_mask */
+		NULL, NULL, /* bitmap/mask */
+		WHITE, /* foreground */
+		BLACK, /* background */
+		8, 8,  /* hotspot */
+		-1, -1,/* w x h */
+		0,     /* alpha */
+		GNOME_CURSOR_XPM /* type */
+	},
+	{
+		GNOME_STOCK_CURSOR_CORNERS, /* name */
+		corners_xpm, /* cursor_data */
+		NULL, /* xbm_mask */
+		NULL, NULL, /* bitmap/mask */
+		WHITE, /* foreground */
+		BLACK, /* background */
+		5, 5,  /* hotspot */
+		-1, -1,/* w x h */
+		0,     /* alpha */
+		GNOME_CURSOR_XPM /* type */
+	},
+	{
+		GNOME_STOCK_CURSOR_WHATISIT, /* name */
+		question_xpm, /* cursor_data */
+		NULL, /* xbm_mask */
+		NULL, NULL, /* bitmap/mask */
+		WHITE, /* foreground */
+		BLACK, /* background */
+		0, 0,  /* hotspot */
+		-1, -1, /* w x h */
+		0,     /* alpha */
+		GNOME_CURSOR_XPM /* type */
+	},
+	{
+		GNOME_STOCK_CURSOR_XTERM, /* name */
+		bar_xpm, /* cursor_data */
+		NULL, /* xbm_mask */
+		NULL, NULL, /* bitmap/mask */
+		WHITE, /* foreground */
+		BLACK, /* background */
+		3, 7,  /* hotspot */
+		-1, -1,/* w x h */
+		0,     /* alpha */
+		GNOME_CURSOR_XPM /* type */
+	}
+};
+
+static const gint num_default_cursors = sizeof(default_cursors)/sizeof(GnomeStockCursor);
+
+
+static void
+build_cursor_table (void)
+{
+	int i;
+	GError *err = NULL;
+	GConfClient *client;
+
+        g_assert (cursortable == NULL);
+
+	/* Get the main gnome gconf client */
+        client = gconf_client_get_default (); 
+
+	cursortable = g_hash_table_new (g_str_hash, g_str_equal);
+	
+	for (i = 0; i < num_default_cursors; i++){
+		const char *name = default_cursors[i].cursorname;
+		char *key, *cursorstr;
+
+		/* Build key */
+		key = g_strconcat ("/desktop/gnome/cursors/", name, NULL);
+		cursorstr = gconf_client_get_string (client, key, &err);
+		if (cursorstr) {
+			gnome_stock_cursor_register (&default_cursors[i]);
+		} else {
+			gnome_stock_cursor_register (&default_cursors[i]);
+		}
+
+		if (err) {
+			g_warning (err->message);
+			g_error_free (err);
+		}
+		
+		g_free (key);
+		g_free (cursorstr);
+	}
+}
+
+
+/**
+ * create_bitmap_and_mask_from_xpm:
+ * @bitmap: Bitmap to hold the cursor bitmap.
+ * @mask: Bitmap to hold mask.
+ * @xpm: XPM data.
+ *
+ * Originally written by Miguel de Icaza.
+ * Modified by Iain Holmes.
+ */
+static void
+create_bitmap_and_mask_from_xpm (GdkBitmap **bitmap,
+				 GdkBitmap **mask,
+				 const char **xpm)
+{
+	int height, width, colors;
+	char *pixmap_buffer;
+	char *mask_buffer;
+	int x, y, pix, yofs;
+	int transparent_color, black_color;
+	
+	sscanf (xpm [0], "%d %d %d %d", &width, &height, &colors, &pix);
+	
+ 	g_assert (width%8 == 0);
+	pixmap_buffer = (char*) g_malloc (sizeof (char) * (width * height/8));
+	mask_buffer = (char*) g_malloc (sizeof (char) * (width * height/8));
+	
+	if (!pixmap_buffer || !mask_buffer)
+		return;
+	
+	g_assert (colors <= 3);
+	
+	transparent_color = ' ';
+	black_color = '.';
+	
+	yofs = colors + 1;
+	for (y = 0; y < height; y++){
+		for (x = 0; x < width;){
+			char value = 0, maskv = 0;
+			
+			for (pix = 0; pix < 8; pix++, x++){
+				if (xpm [y + yofs][x] != transparent_color){
+					maskv |= 1 << pix;
+					
+					if (xpm [y + yofs][x] != black_color){
+						value |= 1 << pix;
+					}
+				}
+			}
+			pixmap_buffer [(y * (width/8) + x/8)-1] = value;
+			mask_buffer [(y * (width/8) + x/8)-1] = maskv;
+		}
+	}
+	*bitmap = gdk_bitmap_create_from_data (NULL, pixmap_buffer, width, height);
+	*mask   = gdk_bitmap_create_from_data (NULL, mask_buffer, width, height);
+
+	g_free(pixmap_buffer);
+	g_free(mask_buffer);
+}
+
+
+#define MAXIMUM(x,y) ((x) > (y) ? (x) : (y))
+#define MINIMUM(x,y) ((x) < (y) ? (x) : (y))
+
+/* Take RGB and desaturate it. */
+static unsigned int
+threshold (unsigned int r,
+	   unsigned int g,
+	   unsigned int b)
+{
+	int max, min;
+	
+	max = MAXIMUM(r, g);
+	max = MAXIMUM(max, b);
+	min = MINIMUM(b, g);
+	min = MINIMUM(min, r);
+	
+	return (max + min) / 2;
+}
+
+
+/**
+ * gnome_cursor_create_from_pixbuf:
+ * @pixbuf: #GdkPixbuf containing the image.
+ * @bitmap: Return for the image bitmap.
+ * @mask: Return for the image mask.
+ * @width: Return for the image width.
+ * @height: Return for the image height.
+ *
+ * Creates a bitmap and mask from a #GdkPixbuf.
+ */
+static void
+gnome_cursor_create_from_pixbuf (GdkPixbuf *pixbuf,
+                                 guchar alpha_threshold,
+				 GdkBitmap **bitmap,
+				 GdkBitmap **mask)
+{
+	int w, h, has_alpha;
+	int x, y;
+	unsigned char *pixel;
+	unsigned int r, g, b, a = 255;
+	unsigned char *pmap, *bmap;
+	
+	has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
+	pixel = gdk_pixbuf_get_pixels (pixbuf);
+
+        w = gdk_pixbuf_get_width(pixbuf);
+        h = gdk_pixbuf_get_height(pixbuf);
+        
+	g_assert (w%8 == 0);
+	pmap = (char*) g_malloc (sizeof (char) * (w * h / 8));
+	bmap = (char*) g_malloc (sizeof (char) * (w * h / 8));
+	
+	for (y = 0; y < h; y++) {
+                for (x = 0; x < w;) {
+                        int pix;
+                        unsigned char value = 0, maskv = 0;
+			
+                        for (pix = 0; pix < 8; pix++, x++) {
+
+                                r = *(pixel++);
+                                g = *(pixel++);
+                                b = *(pixel++);
+                                if (has_alpha)
+                                        a = *(pixel++);
+				
+                                if (a >= 127) {
+                                        maskv |= 1 << pix;
+					
+                                        /* threshold should be a #define */
+                                        if (threshold (r, g, b) >= alpha_threshold) {
+                                                value |= 1 << pix;
+                                        }
+                                }
+                        }
+                        pmap[(y * (w / 8) + x / 8 - 1)] = value;
+                        bmap[(y * (w / 8) + x / 8 - 1)] = maskv;
+                }
+	}
+	
+	*bitmap = gdk_bitmap_create_from_data (NULL, pmap, w, h);
+	*mask = gdk_bitmap_create_from_data (NULL, bmap, w, h);
+
+	g_free(pmap);
+	g_free(bmap);
+}
+
+
+/**
+ * gnome_stock_cursor_new:
+ * @cursorname: The name of the cursor to be set
+ *
+ * Returns a #GdkCursor of the requested cursor or %NULL on error.
+ * @cursorname is the name of a gnome stock cursor; either one you've
+ * registered or one of the stock definitions
+ * (GNOME_STOCK_CURSOR_DEFAULT, etc.)
+ *
+ * Returns: A new #GdkCursor or %NULL on failure.  */
+GdkCursor*
+gnome_stock_cursor_new (const char *cursorname)
+{
+	GnomeStockCursor *cursor = NULL;
+	GdkCursor *gdk_cursor;
+        GdkBitmap *pmap = NULL;
+        GdkBitmap *mask = NULL;
+
+        /* FIXME if GdkCursor had a refcount we could cache that
+           instead of the pixmap/bitmap */
+        
+	if (!cursortable)
+		build_cursor_table ();
+	
+	cursor = g_hash_table_lookup (cursortable, cursorname);
+	
+	if (cursor == NULL) {
+		g_warning ("Unknown cursor %s", cursorname);
+		return NULL;
+	}
+
+        if (cursor->type != GNOME_CURSOR_STANDARD && cursor->pmap == NULL)
+	{
+                switch (cursor->type) {
+                case GNOME_CURSOR_XBM:
+                        pmap = gdk_bitmap_create_from_data (NULL,
+                                                            cursor->cursor_data,
+                                                            cursor->width,
+                                                            cursor->height);
+                        mask = gdk_bitmap_create_from_data (NULL,
+                                                            cursor->xbm_mask_bits,
+                                                            cursor->width,
+                                                            cursor->height);
+                        break;
+                        
+                case GNOME_CURSOR_XPM:
+                        create_bitmap_and_mask_from_xpm (&pmap, &mask, 
+                                                         (const char **)cursor->cursor_data);
+                        break;
+                
+                case GNOME_CURSOR_FILE:
+                {
+                        GdkPixbuf *pixbuf;
+			GError *error;
+
+			error = NULL;
+			pixbuf = gdk_pixbuf_new_from_file (cursor->cursor_data,
+							   &error);
+			if (error != NULL) {
+				g_warning (G_STRLOC ": can't load %s: %s",
+					   (gchar *) cursor->cursor_data,
+					   error->message);
+				g_error_free (error);
+				return NULL;
+			}
+
+                        gnome_cursor_create_from_pixbuf (pixbuf,
+                                                         cursor->alpha_threshhold,
+                                                         &pmap, &mask);
+                        gdk_pixbuf_unref (pixbuf);
+                }
+                break;
+              
+                case GNOME_CURSOR_GDK_PIXBUF:
+                        gnome_cursor_create_from_pixbuf ((GdkPixbuf*) cursor->cursor_data,
+                                                         cursor->alpha_threshhold,
+                                                         &pmap, &mask);
+                        break;
+                
+                default:
+                        g_warning ("Invalid GnomeCursorType");
+                        return NULL;
+                }
+        }
+
+	if (pmap && mask)
+	{
+		cursor->pmap = pmap;
+		cursor->mask = mask;
+	}
+	
+
+        if (cursor->type != GNOME_CURSOR_STANDARD) {
+                if (!cursor->pmap)
+                        return NULL;
+                else
+		{
+                        gdk_cursor = gdk_cursor_new_from_pixmap (cursor->pmap, 
+                                                                 cursor->mask,
+                                                                 &cursor->foreground,
+                                                                 &cursor->background,
+                                                                 cursor->hotspot_x, 
+                                                                 cursor->hotspot_y);
+                }
+        } else {
+                return gdk_cursor_new(GPOINTER_TO_INT(cursor->cursor_data));
+        }
+	
+	return gdk_cursor;
+}
+
+
+/**
+ * gnome_stock_cursor_register:
+ * @cursor: #GnomeStockCursor describing the cursor to register.
+ *
+ * The #GnomeStockCursor is not copied and must not be freed.  */
+void
+gnome_stock_cursor_register (GnomeStockCursor *cursor)
+{
+	GnomeStockCursor *old_cursor;
+        
+	if (!cursortable)
+		build_cursor_table ();
+
+        g_return_if_fail (cursor != NULL);
+        g_return_if_fail (cursor->pmap == NULL);
+        g_return_if_fail (cursor->mask == NULL);
+        
+	/* Check if the cursorname is unique */
+	old_cursor = g_hash_table_lookup (cursortable, cursor->cursorname);
+        
+	if (old_cursor) {
+		g_warning ("Cursor name %s is already registered.", 
+			   cursor->cursorname);
+		return;
+	}
+
+	g_hash_table_insert (cursortable, (gpointer)cursor->cursorname, cursor);
+}
+
+/**
+ * gnome_stock_cursor_lookup_entry:
+ * @cursorname: cursor name to look up in the list of registered cursors.
+ *
+ * The returned #GnomeStockCursor is not copied and must not be freed.  */
+GnomeStockCursor*
+gnome_stock_cursor_lookup_entry(const char *cursorname)
+{
+	if (!cursortable)
+		build_cursor_table ();
+	
+	return g_hash_table_lookup (cursortable, cursorname);
+}
+
+
+/**
+ * gnome_stock_cursor_unregister:
+ * @cursorname: Name of cursor to unregister.
+ *
+ * Unregisters a cursor and frees all memory associated with it.
+ */
+void
+gnome_stock_cursor_unregister (const char *cursorname)
+{
+	GnomeStockCursor *cursor;
+
+        g_return_if_fail (cursortable != NULL);
+
+	cursor = g_hash_table_lookup (cursortable, cursorname);
+	g_return_if_fail (cursor != NULL);
+	
+	g_hash_table_remove (cursortable, cursorname);
+
+        gdk_bitmap_unref(cursor->pmap);
+        gdk_bitmap_unref(cursor->mask);
+}
+
+
+
+/*
+ * The original idea was to have a stack of cursors for each GdkWindow,
+ * with push/pop. However this can't be sanely implemented
+ * without reference counting on the cursors.
+ */
diff --git a/libgnomeui/gnome-cursors.h b/libgnomeui/gnome-cursors.h
new file mode 100644
index 0000000..94d8c0e
--- /dev/null
+++ b/libgnomeui/gnome-cursors.h
@@ -0,0 +1,89 @@
+/* -*- Mode: C; c-set-style: linux indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gnome-cursors.h - Stock GNOME cursors
+
+   Copyright (C) 1999 Iain Holmes
+   All rights reserved.
+
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+*/
+/*
+  @NOTATION@
+*/
+
+#ifndef GNOME_CURSORS_H
+#define GNOME_CURSORS_H
+
+#include <gdk/gdk.h>
+
+typedef enum  {
+	/* Update bitfield size in struct when adding enums */
+	GNOME_CURSOR_FILE,
+	GNOME_CURSOR_XBM,
+	GNOME_CURSOR_XPM,
+	GNOME_CURSOR_GDK_PIXBUF,
+	GNOME_CURSOR_STANDARD
+} GnomeStockCursorType;
+
+typedef struct _GnomeStockCursor GnomeStockCursor;
+
+struct _GnomeStockCursor { /* The new one */
+	const char *cursorname;
+	gconstpointer cursor_data;
+	gchar *xbm_mask_bits;
+	GdkBitmap *pmap, *mask;
+
+	GdkColor foreground, background;
+	gint16 hotspot_x, hotspot_y;
+	gint16 width, height;
+	guchar alpha_threshhold;
+	GnomeStockCursorType type : 4;
+};
+
+void       gnome_stock_cursor_register   (GnomeStockCursor *cursor);
+
+/* This returns a pointer to the internal GnomeStockCursor,
+   which should not be modified. */
+GnomeStockCursor*
+           gnome_stock_cursor_lookup_entry(const char *srcname);
+                                          
+void       gnome_stock_cursor_unregister  (const char *cursorname);
+
+/* Use gdk_cursor_destroy() to destroy the returned value */
+GdkCursor *gnome_stock_cursor_new         (const char *cursorname);
+
+
+/* Set the cursor on a window with gdk_window_set_cursor(),
+ * tnen destroy it with gdk_cursor_destroy()
+ */
+
+#define GNOME_STOCK_CURSOR_DEFAULT "gnome-default-arrow"
+#define GNOME_STOCK_CURSOR_BLANK "gnome-blank"
+#define GNOME_STOCK_CURSOR_HAND_OPEN "gnome-hand-open"
+#define GNOME_STOCK_CURSOR_HAND_CLOSE "gnome-hand-close"
+#define GNOME_STOCK_CURSOR_ZOOM_IN "gnome-zoom-in"
+#define GNOME_STOCK_CURSOR_ZOOM_OUT "gnome-zoom-out"
+#define GNOME_STOCK_CURSOR_EGG_1 "gnome-egg-timer-1"
+#define GNOME_STOCK_CURSOR_POINTING_HAND "gnome-pointing-hand"
+#define GNOME_STOCK_CURSOR_HORIZONTAL "gnome-horizontal-arrow"
+#define GNOME_STOCK_CURSOR_VERTICAL "gnome-vertical-arrow"
+#define GNOME_STOCK_CURSOR_NE_SW "gnome-northeast-southwest"
+#define GNOME_STOCK_CURSOR_NW_SE "gnome-northwest-southeast"
+#define GNOME_STOCK_CURSOR_FLEUR "gnome-fleur"
+#define GNOME_STOCK_CURSOR_CORNERS "gnome-corner-arrow"
+#define GNOME_STOCK_CURSOR_WHATISIT "gnome-what-is-it"
+#define GNOME_STOCK_CURSOR_XTERM "gnome-xterm"
+
+#endif /* GNOME_CURSORS_H */
diff --git a/libgnomeui/gnome-dateedit.c b/libgnomeui/gnome-dateedit.c
new file mode 100644
index 0000000..bf2df82
--- /dev/null
+++ b/libgnomeui/gnome-dateedit.c
@@ -0,0 +1,929 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+/*
+ * Date editor widget
+ *
+ * Author: Miguel de Icaza
+ */
+#include <config.h>
+#include "gnome-macros.h"
+
+#include <string.h>
+#include <stdlib.h> /* atoi */
+#include <ctype.h> /* isdigit */
+#include <stdio.h>
+#include <time.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+#include "gnome-dateedit.h"
+#include "gnome-cursors.h"
+#include <libgnome/gnome-i18n.h>
+#include <libgnomeui/gnome-stock.h>
+
+struct _GnomeDateEditPrivate {
+	GtkWidget *date_entry;
+	GtkWidget *date_button;
+	
+	GtkWidget *time_entry;
+	GtkWidget *time_popup;
+
+	GtkWidget *cal_label;
+	GtkWidget *cal_popup;
+	GtkWidget *calendar;
+
+	time_t    initial_time;
+
+	int       lower_hour;
+	int       upper_hour;
+	
+	int       flags;
+};
+
+enum {
+	DATE_CHANGED,
+	TIME_CHANGED,
+	LAST_SIGNAL
+};
+
+enum {
+	PROP_0,
+	PROP_TIME,
+	PROP_DATEEDIT_FLAGS,
+	PROP_LOWER_HOUR,
+	PROP_UPPER_HOUR,
+	PROP_INITIAL_TIME
+};
+
+static gint date_edit_signals [LAST_SIGNAL] = { 0 };
+
+
+static void gnome_date_edit_init         (GnomeDateEdit      *gde);
+static void gnome_date_edit_class_init   (GnomeDateEditClass *class);
+static void gnome_date_edit_destroy      (GtkObject          *object);
+static void gnome_date_edit_finalize     (GObject            *object);
+static void gnome_date_edit_forall       (GtkContainer       *container,
+					  gboolean	      include_internals,
+					  GtkCallback	      callback,
+					  gpointer	      callbabck_data);
+static void gnome_date_edit_set_property    (GObject            *object,
+					  guint               param_id,
+					  const GValue       *value,
+					  GParamSpec         *pspec);
+static void gnome_date_edit_get_property    (GObject            *object,
+					  guint               param_id,
+					  GValue             *value,
+					  GParamSpec         *pspec);
+
+/**
+ * gnome_date_edit_get_type:
+ *
+ * Returns the GtkType for the GnomeDateEdit widget
+ */
+/* The following macro defines the get_type */
+GNOME_CLASS_BOILERPLATE(GnomeDateEdit, gnome_date_edit,
+			GtkHBox, gtk_hbox)
+
+static void
+hide_popup (GnomeDateEdit *gde)
+{
+	gtk_widget_hide (gde->_priv->cal_popup);
+	gtk_grab_remove (gde->_priv->cal_popup);
+	gdk_pointer_ungrab (GDK_CURRENT_TIME);
+}
+
+static void
+day_selected (GtkCalendar *calendar, GnomeDateEdit *gde)
+{
+	char buffer [40];
+	gint year, month, day;
+
+	gtk_calendar_get_date (calendar, &year, &month, &day);
+
+	/* FIXME: internationalize this - strftime()*/
+	g_snprintf (buffer, sizeof(buffer), "%d/%d/%d", month + 1, day, year);
+	gtk_entry_set_text (GTK_ENTRY (gde->_priv->date_entry), buffer);
+	gtk_signal_emit (GTK_OBJECT (gde), date_edit_signals [DATE_CHANGED]);
+}
+
+static void
+day_selected_double_click (GtkCalendar *calendar, GnomeDateEdit *gde)
+{
+	hide_popup (gde);
+}
+
+static gint
+delete_popup (GtkWidget *widget, gpointer data)
+{
+	GnomeDateEdit *gde;
+
+	gde = data;
+	hide_popup (gde);
+
+	return TRUE;
+}
+
+static gint
+key_press_popup (GtkWidget *widget, GdkEventKey *event, gpointer data)
+{
+	GnomeDateEdit *gde;
+
+	if (event->keyval != GDK_Escape)
+		return FALSE;
+
+	gde = data;
+	gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "key_press_event");
+	hide_popup (gde);
+
+	return TRUE;
+}
+
+/* This function is yanked from gtkcombo.c */
+static gint
+button_press_popup (GtkWidget *widget, GdkEventButton *event, gpointer data)
+{
+	GnomeDateEdit *gde;
+	GtkWidget *child;
+
+	gde = data;
+
+	child = gtk_get_event_widget ((GdkEvent *) event);
+
+	/* We don't ask for button press events on the grab widget, so
+	 *  if an event is reported directly to the grab widget, it must
+	 *  be on a window outside the application (and thus we remove
+	 *  the popup window). Otherwise, we check if the widget is a child
+	 *  of the grab widget, and only remove the popup window if it
+	 *  is not.
+	 */
+	if (child != widget) {
+		while (child) {
+			if (child == widget)
+				return FALSE;
+			child = child->parent;
+		}
+	}
+
+	hide_popup (gde);
+
+	return TRUE;
+}
+
+static void
+position_popup (GnomeDateEdit *gde)
+{
+	gint x, y;
+	gint bwidth, bheight;
+	GtkRequisition req;
+
+	gtk_widget_size_request (gde->_priv->cal_popup, &req);
+
+	gdk_window_get_origin (gde->_priv->date_button->window, &x, &y);
+	gdk_window_get_size (gde->_priv->date_button->window, &bwidth, &bheight);
+
+	x += bwidth - req.width;
+	y += bheight;
+
+	if (x < 0)
+		x = 0;
+
+	if (y < 0)
+		y = 0;
+
+	gtk_widget_set_uposition (gde->_priv->cal_popup, x, y);
+}
+
+static void
+select_clicked (GtkWidget *widget, GnomeDateEdit *gde)
+{
+	struct tm mtm = {0};
+	GdkCursor *cursor;
+
+        /* This code is pretty much just copied from gtk_date_edit_get_date */
+      	sscanf (gtk_entry_get_text (GTK_ENTRY (gde->_priv->date_entry)), "%d/%d/%d",
+		&mtm.tm_mon, &mtm.tm_mday, &mtm.tm_year); /* FIXME: internationalize this - strptime()*/
+
+	mtm.tm_mon = CLAMP (mtm.tm_mon, 1, 12);
+	mtm.tm_mday = CLAMP (mtm.tm_mday, 1, 31);
+        
+        mtm.tm_mon--;
+
+	/* Hope the user does not actually mean years early in the A.D. days...
+	 * This date widget will obviously not work for a history program :-)
+	 */
+	if (mtm.tm_year >= 1900)
+		mtm.tm_year -= 1900;
+
+	gtk_calendar_select_month (GTK_CALENDAR (gde->_priv->calendar), mtm.tm_mon, 1900 + mtm.tm_year);
+        gtk_calendar_select_day (GTK_CALENDAR (gde->_priv->calendar), mtm.tm_mday);
+
+        position_popup (gde);
+       
+	gtk_widget_show (gde->_priv->cal_popup);
+	gtk_widget_grab_focus (gde->_priv->cal_popup);
+	gtk_grab_add (gde->_priv->cal_popup);
+
+
+	cursor = gnome_stock_cursor_new (GNOME_STOCK_CURSOR_DEFAULT);
+
+	gdk_pointer_grab (gde->_priv->cal_popup->window, TRUE,
+			  (GDK_BUTTON_PRESS_MASK
+			   | GDK_BUTTON_RELEASE_MASK
+			   | GDK_POINTER_MOTION_MASK),
+			  NULL, cursor, GDK_CURRENT_TIME);
+
+	gdk_cursor_destroy (cursor);
+}
+
+typedef struct {
+	char *hour;
+	GnomeDateEdit *gde;
+} hour_info_t;
+
+static void
+set_time (GtkWidget *widget, hour_info_t *hit)
+{
+	gtk_entry_set_text (GTK_ENTRY (hit->gde->_priv->time_entry), hit->hour);
+	gtk_signal_emit (GTK_OBJECT (hit->gde), date_edit_signals [TIME_CHANGED]);
+}
+
+static void
+free_resources (GtkWidget *widget, hour_info_t *hit)
+{
+	g_free (hit->hour);
+	g_free (hit);
+}
+
+static void
+fill_time_popup (GtkWidget *widget, GnomeDateEdit *gde)
+{
+	GtkWidget *menu;
+	struct tm *mtm;
+	time_t current_time;
+	int i, j;
+
+	if (gde->_priv->lower_hour > gde->_priv->upper_hour)
+		return;
+
+	menu = gtk_menu_new ();
+	gtk_option_menu_set_menu (GTK_OPTION_MENU (gde->_priv->time_popup), menu);
+
+	time (&current_time);
+	mtm = localtime (&current_time);
+	
+	for (i = gde->_priv->lower_hour; i <= gde->_priv->upper_hour; i++){
+		GtkWidget *item, *submenu;
+		hour_info_t *hit;
+		char buffer [40];
+
+		mtm->tm_hour = i;
+		mtm->tm_min  = 0;
+		hit = g_new (hour_info_t, 1);
+
+		if (gde->_priv->flags & GNOME_DATE_EDIT_24_HR)
+			strftime (buffer, sizeof (buffer), "%H:00", mtm);
+		else
+			strftime (buffer, sizeof (buffer), "%I:00 %p ", mtm);
+		hit->hour = g_strdup (buffer);
+		hit->gde  = gde;
+
+		item = gtk_menu_item_new_with_label (buffer);
+		gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+#if 0
+		gtk_signal_connect (GTK_OBJECT (item), "activate",
+				    GTK_SIGNAL_FUNC (set_time), hit);
+#endif
+		gtk_signal_connect (GTK_OBJECT (item), "destroy",
+				    GTK_SIGNAL_FUNC (free_resources), hit);
+		gtk_widget_show (item);
+
+		submenu = gtk_menu_new ();
+		gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu);
+		for (j = 0; j < 60; j += 15){
+			GtkWidget *mins;
+
+			mtm->tm_min = j;
+			hit = g_new (hour_info_t, 1);
+			if (gde->_priv->flags & GNOME_DATE_EDIT_24_HR)
+				strftime (buffer, sizeof (buffer), "%H:%M", mtm);
+			else
+				strftime (buffer, sizeof (buffer), "%I:%M %p", mtm);
+			hit->hour = g_strdup (buffer);
+			hit->gde  = gde;
+
+			mins = gtk_menu_item_new_with_label (buffer);
+			gtk_menu_shell_append (GTK_MENU_SHELL (submenu), mins);
+			gtk_signal_connect (GTK_OBJECT (mins), "activate",
+					    GTK_SIGNAL_FUNC (set_time), hit);
+			gtk_signal_connect (GTK_OBJECT (item), "destroy",
+					    GTK_SIGNAL_FUNC (free_resources), hit);
+			gtk_widget_show (mins);
+		}
+	}
+}
+
+static void
+gnome_date_edit_class_init (GnomeDateEditClass *class)
+{
+	GtkObjectClass *object_class = (GtkObjectClass *) class;
+	GObjectClass *gobject_class = (GObjectClass *) class;
+	GtkContainerClass *container_class = (GtkContainerClass *) class;
+
+	object_class = (GtkObjectClass*) class;
+
+	g_object_class_install_property (gobject_class,
+				      PROP_TIME,
+				      g_param_spec_ulong ("time",
+							  _("Time"),
+							  _("The time currently"
+							    "selected"),
+							  0, G_MAXULONG,
+							  0,
+						          (G_PARAM_READABLE |
+							   G_PARAM_WRITABLE)));
+	/* FIXME: Not sure G_TYPE_FLAGS is right here, perhaps we
+	 * need a new type, Also think of a better name then "dateedit_flags" */
+	g_object_class_install_property (gobject_class,
+				      PROP_DATEEDIT_FLAGS,
+				      g_param_spec_flags ("dateedit_flags",
+							  _("DateEdit Flags"),
+							  _("Flags for how "
+							    "DateEdit looks"),
+							  G_TYPE_FLAGS,
+							  GNOME_DATE_EDIT_SHOW_TIME,
+						          (G_PARAM_READABLE |
+							   G_PARAM_WRITABLE)));
+	g_object_class_install_property (gobject_class,
+				      PROP_LOWER_HOUR,
+				      g_param_spec_int ("lower_hour",
+							_("Lower Hour"),
+							_("Lower hour in "
+							  "the time popup "
+							  "selector"),
+							0, 24,
+							7,
+							(G_PARAM_READABLE |
+							 G_PARAM_WRITABLE)));
+	g_object_class_install_property (gobject_class,
+				      PROP_UPPER_HOUR,
+				      g_param_spec_int ("upper_hour",
+							_("Upper Hour"),
+							_("Upper hour in "
+							  "the time popup "
+							  "selector"),
+							0, 24,
+							19,
+							(G_PARAM_READABLE |
+							 G_PARAM_WRITABLE)));
+	g_object_class_install_property (gobject_class,
+				      PROP_INITIAL_TIME,
+				      g_param_spec_ulong ("initial_time",
+							  _("Initial Time"),
+							  _("The initial time"),
+							  0, G_MAXULONG,
+							  0,
+						          (G_PARAM_READABLE |
+							   G_PARAM_WRITABLE)));
+	
+	date_edit_signals [TIME_CHANGED] =
+		gtk_signal_new ("time_changed",
+				GTK_RUN_FIRST, GTK_CLASS_TYPE (object_class),
+				GTK_SIGNAL_OFFSET (GnomeDateEditClass,
+						   time_changed),
+				gtk_signal_default_marshaller,
+				GTK_TYPE_NONE, 0);
+	
+	date_edit_signals [DATE_CHANGED] =
+		gtk_signal_new ("date_changed",
+				GTK_RUN_FIRST, GTK_CLASS_TYPE (object_class),
+				GTK_SIGNAL_OFFSET (GnomeDateEditClass,
+						   date_changed),
+				gtk_signal_default_marshaller,
+				GTK_TYPE_NONE, 0);
+	
+	container_class->forall = gnome_date_edit_forall;
+
+	object_class->destroy = gnome_date_edit_destroy;
+
+	gobject_class->finalize = gnome_date_edit_finalize;
+	gobject_class->get_property = gnome_date_edit_get_property;
+	gobject_class->set_property = gnome_date_edit_set_property;
+
+	class->date_changed = NULL;
+	class->time_changed = NULL;
+}
+
+static void
+gnome_date_edit_init (GnomeDateEdit *gde)
+{
+	gde->_priv = g_new0(GnomeDateEditPrivate, 1);
+	gde->_priv->lower_hour = 7;
+	gde->_priv->upper_hour = 19;
+	gde->_priv->flags = GNOME_DATE_EDIT_SHOW_TIME;
+}
+
+static void
+gnome_date_edit_destroy (GtkObject *object)
+{
+	GnomeDateEdit *gde;
+
+	/* remember, destroy can be run multiple times! */
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GNOME_IS_DATE_EDIT (object));
+
+	gde = GNOME_DATE_EDIT (object);
+
+	if(gde->_priv->cal_popup)
+		gtk_widget_destroy (gde->_priv->cal_popup);
+	gde->_priv->cal_popup = NULL;
+
+	GNOME_CALL_PARENT_HANDLER (GTK_OBJECT_CLASS, destroy, (object));
+}
+
+static void
+gnome_date_edit_finalize (GObject *object)
+{
+	GnomeDateEdit *gde;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GNOME_IS_DATE_EDIT (object));
+
+	gde = GNOME_DATE_EDIT (object);
+
+	g_free(gde->_priv);
+	gde->_priv = NULL;
+
+	GNOME_CALL_PARENT_HANDLER (G_OBJECT_CLASS, finalize, (object));
+}
+
+static void
+gnome_date_edit_forall (GtkContainer *container, gboolean include_internals,
+			GtkCallback callback, gpointer callback_data)
+{
+	g_return_if_fail (container != NULL);
+	g_return_if_fail (GNOME_IS_DATE_EDIT (container));
+	g_return_if_fail (callback != NULL);
+
+	/* Let GtkBox handle things only if the internal widgets need to be
+	 * poked.
+	 */
+	if (include_internals)
+		GNOME_CALL_PARENT_HANDLER (GTK_CONTAINER_CLASS, forall,
+					   (container,
+					    include_internals,
+					    callback,
+					    callback_data));
+}
+
+static void
+gnome_date_edit_set_property (GObject            *object,
+			   guint               param_id,
+			   const GValue       *value,
+			   GParamSpec         *pspec)
+{
+	GnomeDateEdit *self;
+
+	self = GNOME_DATE_EDIT (object);
+
+	switch (param_id) {
+	case PROP_TIME:
+		gnome_date_edit_set_time(self, g_value_get_ulong (value));
+		break;
+	case PROP_DATEEDIT_FLAGS:
+		gnome_date_edit_set_flags(self, g_value_get_flags (value));
+		break;
+	case PROP_LOWER_HOUR:
+		gnome_date_edit_set_popup_range(self, g_value_get_int (value),
+						self->_priv->upper_hour);
+		break;
+	case PROP_UPPER_HOUR:
+		gnome_date_edit_set_popup_range(self, self->_priv->lower_hour,
+						g_value_get_int (value));
+		break;
+
+	default:
+		break;
+	}
+}
+
+static void
+gnome_date_edit_get_property (GObject            *object,
+			   guint               param_id,
+			   GValue             *value,
+			   GParamSpec         *pspec)
+{
+	GnomeDateEdit *self;
+
+	self = GNOME_DATE_EDIT (object);
+
+	switch (param_id) {
+	case PROP_TIME:
+		g_value_set_ulong (value,
+				   gnome_date_edit_get_time(self));
+		break;
+	case PROP_DATEEDIT_FLAGS:
+		g_value_set_flags (value, self->_priv->flags);
+		break;
+	case PROP_LOWER_HOUR:
+		g_value_set_int (value, self->_priv->lower_hour);
+		break;
+	case PROP_UPPER_HOUR:
+		g_value_set_int (value, self->_priv->upper_hour);
+		break;
+	case PROP_INITIAL_TIME:
+		g_value_set_ulong (value, self->_priv->initial_time);
+		break;
+	default:
+		break;
+	}
+}
+
+/**
+ * gnome_date_edit_set_time:
+ * @gde: the GnomeDateEdit widget
+ * @the_time: The time and date that should be set on the widget
+ *
+ * Description:  Changes the displayed date and time in the GnomeDateEdit
+ * widget to be the one represented by @the_time.  If @the_time is 0
+ * then current time is used.
+ */
+void
+gnome_date_edit_set_time (GnomeDateEdit *gde, time_t the_time)
+{
+	struct tm *mytm;
+	char buffer [40];
+
+	g_return_if_fail(gde != NULL);
+
+	if (the_time == 0)
+		the_time = time (NULL);
+	gde->_priv->initial_time = the_time;
+
+	mytm = localtime (&the_time);
+
+	/* Set the date */
+	g_snprintf (buffer, sizeof(buffer), "%d/%d/%d",
+		    mytm->tm_mon + 1,
+		    mytm->tm_mday,
+		    1900 + mytm->tm_year);
+	gtk_entry_set_text (GTK_ENTRY (gde->_priv->date_entry), buffer);
+
+	/* Set the time */
+	if (gde->_priv->flags & GNOME_DATE_EDIT_24_HR)
+		strftime (buffer, sizeof (buffer), "%H:%M", mytm);
+	else
+		strftime (buffer, sizeof (buffer), "%I:%M %p", mytm);
+	gtk_entry_set_text (GTK_ENTRY (gde->_priv->time_entry), buffer);
+}
+
+/**
+ * gnome_date_edit_set_popup_range:
+ * @gde: The GnomeDateEdit widget
+ * @low_hour: low boundary for the time-range display popup.
+ * @up_hour:  upper boundary for the time-range display popup.
+ *
+ * Sets the range of times that will be provide by the time popup
+ * selectors.
+ */
+void
+gnome_date_edit_set_popup_range (GnomeDateEdit *gde, int low_hour, int up_hour)
+{
+        g_return_if_fail (gde != NULL);
+	g_return_if_fail (low_hour >= 0 && low_hour <= 24);
+	g_return_if_fail (up_hour >= 0 && up_hour <= 24);
+
+	gde->_priv->lower_hour = low_hour;
+	gde->_priv->upper_hour = up_hour;
+
+        fill_time_popup(NULL, gde);
+}
+
+static void
+create_children (GnomeDateEdit *gde)
+{
+	GtkWidget *frame;
+	GtkWidget *hbox;
+	GtkWidget *arrow;
+
+	gde->_priv->date_entry  = gtk_entry_new ();
+	gtk_widget_set_usize (gde->_priv->date_entry, 90, 0);
+	gtk_box_pack_start (GTK_BOX (gde), gde->_priv->date_entry, TRUE, TRUE, 0);
+	gtk_widget_show (gde->_priv->date_entry);
+	
+	gde->_priv->date_button = gtk_button_new ();
+	gtk_signal_connect (GTK_OBJECT (gde->_priv->date_button), "clicked",
+			    GTK_SIGNAL_FUNC (select_clicked), gde);
+	gtk_box_pack_start (GTK_BOX (gde), gde->_priv->date_button, FALSE, FALSE, 0);
+
+	hbox = gtk_hbox_new (FALSE, 3);
+	gtk_container_add (GTK_CONTAINER (gde->_priv->date_button), hbox);
+	gtk_widget_show (hbox);
+
+	/* Calendar label, only shown if the date editor has a time field */
+
+	gde->_priv->cal_label = gtk_label_new (_("Calendar"));
+	gtk_misc_set_alignment (GTK_MISC (gde->_priv->cal_label), 0.0, 0.5);
+	gtk_box_pack_start (GTK_BOX (hbox), gde->_priv->cal_label, TRUE, TRUE, 0);
+	if (gde->_priv->flags & GNOME_DATE_EDIT_SHOW_TIME)
+		gtk_widget_show (gde->_priv->cal_label);
+
+	arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT);
+	gtk_box_pack_start (GTK_BOX (hbox), arrow, FALSE, FALSE, 0);
+	gtk_widget_show (arrow);
+
+	gtk_widget_show (gde->_priv->date_button);
+
+	gde->_priv->time_entry = gtk_entry_new_with_max_length (12);
+	gtk_widget_set_usize (gde->_priv->time_entry, 88, 0);
+	gtk_box_pack_start (GTK_BOX (gde), gde->_priv->time_entry, TRUE, TRUE, 0);
+
+	gde->_priv->time_popup = gtk_option_menu_new ();
+	gtk_box_pack_start (GTK_BOX (gde), gde->_priv->time_popup, FALSE, FALSE, 0);
+
+	/* We do not create the popup menu with the hour range until we are
+	 * realized, so that it uses the values that the user might supply in a
+	 * future call to gnome_date_edit_set_popup_range
+	 */
+	gtk_signal_connect (GTK_OBJECT (gde), "realize",
+			    GTK_SIGNAL_FUNC (fill_time_popup), gde);
+
+	if (gde->_priv->flags & GNOME_DATE_EDIT_SHOW_TIME) {
+		gtk_widget_show (gde->_priv->time_entry);
+		gtk_widget_show (gde->_priv->time_popup);
+	}
+
+	gde->_priv->cal_popup = gtk_window_new (GTK_WINDOW_POPUP);
+	gtk_widget_set_events (gde->_priv->cal_popup,
+			       gtk_widget_get_events (gde->_priv->cal_popup) | GDK_KEY_PRESS_MASK);
+	gtk_signal_connect (GTK_OBJECT (gde->_priv->cal_popup), "delete_event",
+			    (GtkSignalFunc) delete_popup,
+			    gde);
+	gtk_signal_connect (GTK_OBJECT (gde->_priv->cal_popup), "key_press_event",
+			    (GtkSignalFunc) key_press_popup,
+			    gde);
+	gtk_signal_connect (GTK_OBJECT (gde->_priv->cal_popup), "button_press_event",
+			    (GtkSignalFunc) button_press_popup,
+			    gde);
+	gtk_window_set_policy (GTK_WINDOW (gde->_priv->cal_popup), FALSE, FALSE, TRUE);
+
+	frame = gtk_frame_new (NULL);
+	gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
+	gtk_container_add (GTK_CONTAINER (gde->_priv->cal_popup), frame);
+	gtk_widget_show (frame);
+
+	gde->_priv->calendar = gtk_calendar_new ();
+	gtk_calendar_display_options (GTK_CALENDAR (gde->_priv->calendar),
+				      (GTK_CALENDAR_SHOW_DAY_NAMES
+				       | GTK_CALENDAR_SHOW_HEADING
+				       | ((gde->_priv->flags & GNOME_DATE_EDIT_WEEK_STARTS_ON_MONDAY)
+					  ? GTK_CALENDAR_WEEK_START_MONDAY : 0)));
+	gtk_signal_connect (GTK_OBJECT (gde->_priv->calendar), "day_selected",
+			    GTK_SIGNAL_FUNC (day_selected), gde);
+	gtk_signal_connect (GTK_OBJECT (gde->_priv->calendar), "day_selected_double_click",
+			    GTK_SIGNAL_FUNC (day_selected_double_click), gde);
+	gtk_container_add (GTK_CONTAINER (frame), gde->_priv->calendar);
+        gtk_widget_show (gde->_priv->calendar);
+}
+
+/**
+ * gnome_date_edit_new:
+ * @the_time: date and time to be displayed on the widget
+ * @show_time: whether time should be displayed
+ * @use_24_format: whether 24-hour format is desired for the time display.
+ *
+ * Description: Creates a new #GnomeDateEdit widget which can be used
+ * to provide an easy to use way for entering dates and times.
+ * If @the_time is 0 then current time is used.
+ * 
+ * Returns: a new #GnomeDateEdit widget.
+ */
+GtkWidget *
+gnome_date_edit_new (time_t the_time, gboolean show_time, gboolean use_24_format)
+{
+	return gnome_date_edit_new_flags (the_time,
+					  ((show_time ? GNOME_DATE_EDIT_SHOW_TIME : 0)
+					   | (use_24_format ? GNOME_DATE_EDIT_24_HR : 0)));
+}
+
+/**
+ * gnome_date_edit_new_flags:
+ * @the_time: The initial time for the date editor.
+ * @flags: A bitmask of GnomeDateEditFlags values.
+ * 
+ * Description:  Creates a new #GnomeDateEdit widget with the
+ * specified flags. If @the_time is 0 then current time is used.
+ * 
+ * Returns: the newly-created date editor widget.
+ **/
+GtkWidget *
+gnome_date_edit_new_flags (time_t the_time, GnomeDateEditFlags flags)
+{
+	GnomeDateEdit *gde;
+
+	gde = gtk_type_new (gnome_date_edit_get_type ());
+
+	gnome_date_edit_construct(gde, the_time, flags);
+
+	return GTK_WIDGET (gde);
+}
+
+/**
+ * gnome_date_edit_construct:
+ * @gde: The #GnomeDateEdit object to construct
+ * @the_time: The initial time for the date editor.
+ * @flags: A bitmask of GnomeDateEditFlags values.
+ * 
+ * Description:  For language bindings and subclassing only
+ **/
+void
+gnome_date_edit_construct (GnomeDateEdit *gde, time_t the_time, GnomeDateEditFlags flags)
+{
+	gde->_priv->flags = flags;
+	create_children (gde);
+	gnome_date_edit_set_time (gde, the_time);
+}
+
+/**
+ * gnome_date_edit_get_time:
+ * @gde: The GnomeDateEdit widget
+ *
+ * Returns the time entered in the GnomeDateEdit widget
+ */
+time_t
+gnome_date_edit_get_time (GnomeDateEdit *gde)
+{
+	struct tm tm = {0};
+	char *str, *flags = NULL;
+
+	/* Assert, because we're just hosed if it's NULL */
+	g_assert(gde != NULL);
+	g_assert(GNOME_IS_DATE_EDIT(gde));
+	
+	sscanf (gtk_entry_get_text (GTK_ENTRY (gde->_priv->date_entry)), "%d/%d/%d",
+		&tm.tm_mon, &tm.tm_mday, &tm.tm_year); /* FIXME: internationalize this - strptime()*/
+
+	tm.tm_mon = CLAMP (tm.tm_mon, 1, 12);
+	tm.tm_mday = CLAMP (tm.tm_mday, 1, 31);
+
+	tm.tm_mon--;
+
+	/* Hope the user does not actually mean years early in the A.D. days...
+	 * This date widget will obviously not work for a history program :-)
+	 */
+	if (tm.tm_year >= 1900)
+		tm.tm_year -= 1900;
+
+	if (gde->_priv->flags & GNOME_DATE_EDIT_SHOW_TIME) {
+		char *tokp, *temp;
+
+		str = g_strdup (gtk_entry_get_text (GTK_ENTRY (gde->_priv->time_entry)));
+		temp = strtok_r (str, ": ", &tokp);
+		if (temp) {
+			tm.tm_hour = atoi (temp);
+			temp = strtok_r (NULL, ": ", &tokp);
+			if (temp) {
+				if (isdigit (*temp)) {
+					tm.tm_min = atoi (temp);
+					flags = strtok_r (NULL, ": ", &tokp);
+					if (flags && isdigit (*flags)) {
+						tm.tm_sec = atoi (flags);
+						flags = strtok_r (NULL, ": ", &tokp);
+					}
+				} else
+					flags = temp;
+			}
+		}
+
+		if (flags && (strcasecmp (flags, "PM") == 0)){
+			if (tm.tm_hour < 12)
+				tm.tm_hour += 12;
+		}
+		g_free (str);
+	}
+
+	tm.tm_isdst = -1;
+
+	return mktime (&tm);
+}
+
+#ifndef GNOME_EXCLUDE_DEPRECATED_SOURCE
+
+/**
+ * gnome_date_edit_get_date:
+ * @gde: The GnomeDateEdit widget
+ *
+ * Deprecated, use #gnome_date_edit_get_time
+ */
+time_t
+gnome_date_edit_get_date (GnomeDateEdit *gde)
+{
+	g_warning(_("gnome_date_edit_get_date deprecated, use gnome_date_edit_get_time"));
+	return gnome_date_edit_get_time(gde);
+}
+
+#endif /* not GNOME_EXCLUDE_DEPRECATED_SOURCE */
+
+
+/**
+ * gnome_date_edit_set_flags:
+ * @gde: The date editor widget whose flags should be changed.
+ * @flags: The new bitmask of GnomeDateEditFlags values.
+ * 
+ * Changes the display flags on an existing date editor widget.
+ **/
+void
+gnome_date_edit_set_flags (GnomeDateEdit *gde, GnomeDateEditFlags flags)
+{
+        GnomeDateEditFlags old_flags;
+        
+	g_return_if_fail (gde != NULL);
+	g_return_if_fail (GNOME_IS_DATE_EDIT (gde));
+
+        old_flags = gde->_priv->flags;
+        gde->_priv->flags = flags;
+        
+	if ((flags & GNOME_DATE_EDIT_SHOW_TIME) != (old_flags & GNOME_DATE_EDIT_SHOW_TIME)) {
+		if (flags & GNOME_DATE_EDIT_SHOW_TIME) {
+			gtk_widget_show (gde->_priv->cal_label);
+			gtk_widget_show (gde->_priv->time_entry);
+			gtk_widget_show (gde->_priv->time_popup);
+		} else {
+			gtk_widget_hide (gde->_priv->cal_label);
+			gtk_widget_hide (gde->_priv->time_entry);
+			gtk_widget_hide (gde->_priv->time_popup);
+		}
+	}
+
+	if ((flags & GNOME_DATE_EDIT_24_HR) != (old_flags & GNOME_DATE_EDIT_24_HR))
+		fill_time_popup (GTK_WIDGET (gde), gde); /* This will destroy the old menu properly */
+
+	if ((flags & GNOME_DATE_EDIT_WEEK_STARTS_ON_MONDAY)
+	    != (old_flags & GNOME_DATE_EDIT_WEEK_STARTS_ON_MONDAY)) {
+		if (flags & GNOME_DATE_EDIT_WEEK_STARTS_ON_MONDAY)
+			gtk_calendar_display_options (GTK_CALENDAR (gde->_priv->calendar),
+						      (GTK_CALENDAR (gde->_priv->calendar)->display_flags
+						       | GTK_CALENDAR_WEEK_START_MONDAY));
+		else
+			gtk_calendar_display_options (GTK_CALENDAR (gde->_priv->calendar),
+						      (GTK_CALENDAR (gde->_priv->calendar)->display_flags
+						       & ~GTK_CALENDAR_WEEK_START_MONDAY));
+	}
+}
+
+/**
+ * gnome_date_edit_get_flags:
+ * @gde: The date editor whose flags should be queried.
+ * 
+ * Queries the display flags on a date editor widget.
+ * 
+ * Return value: The current display flags for the specified date editor widget.
+ **/
+int
+gnome_date_edit_get_flags (GnomeDateEdit *gde)
+{
+	g_return_val_if_fail (gde != NULL, 0);
+	g_return_val_if_fail (GNOME_IS_DATE_EDIT (gde), 0);
+
+	return gde->_priv->flags;
+}
+
+/**
+ * gnome_date_edit_get_initial_time:
+ * @gde: The date editor whose initial time should be queried
+ * 
+ * Description:  Queries the initial time that was set using the
+ * #gnome_date_edit_set_time or during creation
+ * 
+ * Returns:  The initial time in seconds (standard time_t format)
+ **/
+time_t
+gnome_date_edit_get_initial_time (GnomeDateEdit *gde)
+{
+	g_return_val_if_fail (gde != NULL, 0);
+	g_return_val_if_fail (GNOME_IS_DATE_EDIT (gde), 0);
+
+	return gde->_priv->initial_time;
+}
diff --git a/libgnomeui/gnome-dateedit.h b/libgnomeui/gnome-dateedit.h
new file mode 100644
index 0000000..df2e45d
--- /dev/null
+++ b/libgnomeui/gnome-dateedit.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#ifndef __GNOME_DATE_EDIT_H_
+#define __GNOME_DATE_EDIT_H_ 
+
+#include <gtk/gtkhbox.h>
+
+ 
+G_BEGIN_DECLS
+
+
+typedef enum {
+	GNOME_DATE_EDIT_SHOW_TIME             = 1 << 0,
+	GNOME_DATE_EDIT_24_HR                 = 1 << 1,
+	GNOME_DATE_EDIT_WEEK_STARTS_ON_MONDAY = 1 << 2
+} GnomeDateEditFlags;
+
+
+#define GNOME_TYPE_DATE_EDIT            (gnome_date_edit_get_type ())
+#define GNOME_DATE_EDIT(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_DATE_EDIT, GnomeDateEdit))
+#define GNOME_DATE_EDIT_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_DATE_EDIT, GnomeDateEditClass))
+#define GNOME_IS_DATE_EDIT(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_DATE_EDIT))
+#define GNOME_IS_DATE_EDIT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_DATE_EDIT))
+#define GNOME_DATE_EDIT_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_DATE_EDIT, GnomeDateEditClass))
+
+typedef struct _GnomeDateEdit        GnomeDateEdit;
+typedef struct _GnomeDateEditPrivate GnomeDateEditPrivate;
+typedef struct _GnomeDateEditClass   GnomeDateEditClass;
+
+struct _GnomeDateEdit {
+	GtkHBox hbox;
+
+	/*< private >*/
+	GnomeDateEditPrivate *_priv;
+};
+
+struct _GnomeDateEditClass {
+	GtkHBoxClass parent_class;
+
+	void (*date_changed) (GnomeDateEdit *gde);
+	void (*time_changed) (GnomeDateEdit *gde);
+};
+
+guint     gnome_date_edit_get_type        (void) G_GNUC_CONST;
+GtkWidget *gnome_date_edit_new            (time_t the_time,
+					   gboolean show_time,
+					   gboolean use_24_format);
+GtkWidget *gnome_date_edit_new_flags      (time_t the_time,
+					   GnomeDateEditFlags flags);
+
+/* Note that everything that can be achieved with gnome_date_edit_new can
+ * be achieved with gnome_date_edit_new_flags, so that's why this call 
+ * is like the _new_flags call */
+void      gnome_date_edit_construct	  (GnomeDateEdit *gde,
+					   time_t the_time,
+					   GnomeDateEditFlags flags);
+
+void      gnome_date_edit_set_time        (GnomeDateEdit *gde, time_t the_time);
+time_t    gnome_date_edit_get_time        (GnomeDateEdit *gde);
+void      gnome_date_edit_set_popup_range (GnomeDateEdit *gde, int low_hour, int up_hour);
+void      gnome_date_edit_set_flags       (GnomeDateEdit *gde, GnomeDateEditFlags flags);
+int       gnome_date_edit_get_flags       (GnomeDateEdit *gde);
+
+time_t    gnome_date_edit_get_initial_time(GnomeDateEdit *gde);
+
+#ifndef GNOME_EXCLUDE_DEPRECATED
+time_t    gnome_date_edit_get_date        (GnomeDateEdit *gde);
+#endif /* GNOME_EXCLUDE_DEPRECATED */
+
+G_END_DECLS
+
+#endif
diff --git a/libgnomeui/gnome-ditem-edit.c b/libgnomeui/gnome-ditem-edit.c
new file mode 100644
index 0000000..97f2246
--- /dev/null
+++ b/libgnomeui/gnome-ditem-edit.c
@@ -0,0 +1,1485 @@
+/*  -*- Mode: C; c-set-style: linux; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+
+   Copyright (C) 1999 Free Software Foundation
+    
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   GnomeDItemEdit Developers: Havoc Pennington, based on code by John Ellis
+*/
+/*
+  @NOTATION@
+*/
+
+#include <config.h>
+#include "gnome-macros.h"
+
+#include <ctype.h>
+#include <string.h>
+#include "gnome-ditem-edit.h"
+
+#ifdef NEED_GNOMESUPPORT_H
+# include "gnomesupport.h"
+#endif
+#include <libgnome/gnome-i18n.h>
+
+#include "gnome-stock.h"
+#include "gnome-uidefs.h"
+#include "gnome-pixmap.h"
+#include "gnome-icon-entry.h"
+#include "libgnomeuiP.h"
+
+struct _GnomeDItemEditPrivate {
+	/* use the accessors or just use new_notebook */
+        GtkWidget *child1; /* basic */
+        GtkWidget *child2; /* DND */
+        GtkWidget *child3; /* Advanced */
+
+        /* Remaining fields are private - if you need them, 
+           please add an accessor function. */
+  
+	/* we keep a ditem around, since we can never have absolutely
+	   everything in the display so we load a file, or get a ditem,
+	   sync the display and ref the ditem */
+	GnomeDesktopItem *ditem;
+
+        GtkWidget *name_entry;
+        GtkWidget *comment_entry;
+        GtkWidget *exec_entry;
+        GtkWidget *tryexec_entry;
+        GtkWidget *doc_entry;
+        GtkWidget *wmtitles_entry;
+
+        GtkWidget *simple_dnd_toggle;
+
+        GtkWidget *file_drop_entry;
+        GtkWidget *single_file_drop_toggle;
+
+        GtkWidget *url_drop_entry;
+        GtkWidget *single_url_drop_toggle;
+
+        GtkWidget *type_combo;
+
+        GtkWidget *terminal_button;  
+
+        GtkWidget *icon_entry;
+  
+        GtkWidget *translations;
+        GtkWidget *transl_lang_entry;
+        GtkWidget *transl_name_entry;
+        GtkWidget *transl_comment_entry;
+
+	/* we store this so we can set sensitive the
+	   drag and drop stuff, no point in an accessor */
+        GtkWidget *dndtable;
+};
+
+static void gnome_ditem_edit_class_init   (GnomeDItemEditClass *klass);
+static void gnome_ditem_edit_init         (GnomeDItemEdit      *messagebox);
+
+static void gnome_ditem_edit_destroy      (GtkObject           *object);
+static void gnome_ditem_edit_finalize     (GObject             *object);
+
+static void gnome_ditem_edit_sync_display (GnomeDItemEdit      *dee,
+					   GnomeDesktopItem    *ditem);
+
+static void gnome_ditem_edit_sync_ditem   (GnomeDItemEdit      *dee,
+					   GnomeDesktopItem    *ditem);
+
+static void gnome_ditem_edit_changed      (GnomeDItemEdit      *dee);
+static void gnome_ditem_edit_icon_changed (GnomeDItemEdit      *dee);
+static void gnome_ditem_edit_name_changed (GnomeDItemEdit      *dee);
+
+enum {
+        CHANGED,
+        ICON_CHANGED,
+        NAME_CHANGED,
+        LAST_SIGNAL
+};
+
+static gint ditem_edit_signals[LAST_SIGNAL] = { 0 };
+
+/* The following defines the get_type */
+/* FIXME: this should become a GObject when GObject gets signals !!! */
+GNOME_CLASS_BOILERPLATE (GnomeDItemEdit, gnome_ditem_edit,
+			 GtkObject, gtk_object)
+
+static void
+gnome_ditem_edit_class_init (GnomeDItemEditClass *klass)
+{
+        GtkObjectClass *object_class;
+        GObjectClass *gobject_class;
+        GnomeDItemEditClass * ditem_edit_class;
+
+        ditem_edit_class = (GnomeDItemEditClass*) klass;
+
+        object_class = (GtkObjectClass*) klass;
+        gobject_class = (GObjectClass*) klass;
+
+        ditem_edit_signals[CHANGED] =
+                gtk_signal_new ("changed",
+                                GTK_RUN_LAST,
+                                GTK_CLASS_TYPE (object_class),
+                                GTK_SIGNAL_OFFSET (GnomeDItemEditClass, changed),
+                                gtk_signal_default_marshaller,
+                                GTK_TYPE_NONE, 0);
+
+        ditem_edit_signals[ICON_CHANGED] =
+                gtk_signal_new ("icon_changed",
+                                GTK_RUN_LAST,
+                                GTK_CLASS_TYPE (object_class),
+                                GTK_SIGNAL_OFFSET (GnomeDItemEditClass, 
+                                                   icon_changed),
+                                gtk_signal_default_marshaller,
+                                GTK_TYPE_NONE, 0);
+
+        ditem_edit_signals[NAME_CHANGED] =
+                gtk_signal_new ("name_changed",
+                                GTK_RUN_LAST,
+                                GTK_CLASS_TYPE (object_class),
+                                GTK_SIGNAL_OFFSET (GnomeDItemEditClass, 
+                                                   name_changed),
+                                gtk_signal_default_marshaller,
+                                GTK_TYPE_NONE, 0);
+
+        object_class->destroy = gnome_ditem_edit_destroy;
+        gobject_class->finalize = gnome_ditem_edit_finalize;
+        ditem_edit_class->changed = NULL;
+}
+
+static void 
+table_attach_entry(GtkTable * table, GtkWidget * w,
+		   gint l, gint r, gint t, gint b)
+{
+        gtk_table_attach(table, w, l, r, t, b,
+                         GTK_EXPAND | GTK_FILL | GTK_SHRINK,
+                         GTK_FILL,
+                         0, 0);
+}
+
+static void
+table_attach_label(GtkTable * table, GtkWidget * w,
+		   gint l, gint r, gint t, gint b)
+{
+        gtk_table_attach(table, w, l, r, t, b,
+                         GTK_FILL,
+                         GTK_FILL,
+                         0, 0);
+}
+
+static void 
+table_attach_list(GtkTable * table, GtkWidget * w,
+		  gint l, gint r, gint t, gint b)
+{
+        gtk_table_attach(table, w, l, r, t, b,
+                         GTK_EXPAND | GTK_FILL | GTK_SHRINK,
+                         GTK_EXPAND | GTK_FILL | GTK_SHRINK,
+                         0, 0);
+}
+
+static GtkWidget *
+label_new (char *text)
+{
+        GtkWidget *label;
+
+        label = gtk_label_new (text);
+        gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+        return label;
+}
+
+static void
+fill_easy_page(GnomeDItemEdit * dee, GtkWidget * table)
+{
+        GtkWidget *label;
+        GList *types = NULL;
+        GtkWidget *hbox;
+        GtkWidget *align;
+
+        label = label_new(_("Name:"));
+        table_attach_label(GTK_TABLE(table), label, 0, 1, 0, 1);
+
+        dee->_priv->name_entry = gtk_entry_new();
+        table_attach_entry(GTK_TABLE(table),dee->_priv->name_entry, 1, 2, 0, 1);
+        gtk_signal_connect_object_while_alive(GTK_OBJECT(dee->_priv->name_entry), "changed",
+                                              GTK_SIGNAL_FUNC(gnome_ditem_edit_changed),
+                                              GTK_OBJECT(dee));
+        gtk_signal_connect_object_while_alive(GTK_OBJECT(dee->_priv->name_entry), "changed",
+                                              GTK_SIGNAL_FUNC(gnome_ditem_edit_name_changed),
+                                              GTK_OBJECT(dee));
+
+
+        label = label_new(_("Comment:"));
+        table_attach_label(GTK_TABLE(table),label, 0, 1, 1, 2);
+
+        dee->_priv->comment_entry = gtk_entry_new();
+        table_attach_entry(GTK_TABLE(table),dee->_priv->comment_entry, 1, 2, 1, 2);
+        gtk_signal_connect_object_while_alive(GTK_OBJECT(dee->_priv->comment_entry), "changed",
+                                              GTK_SIGNAL_FUNC(gnome_ditem_edit_changed),
+                                              GTK_OBJECT(dee));
+
+
+        label = label_new(_("Command:"));
+        table_attach_label(GTK_TABLE(table),label, 0, 1, 2, 3);
+
+        dee->_priv->exec_entry = gtk_entry_new();
+        table_attach_entry(GTK_TABLE(table),dee->_priv->exec_entry, 1, 2, 2, 3);
+        gtk_signal_connect_object_while_alive(GTK_OBJECT(dee->_priv->exec_entry), "changed",
+                                              GTK_SIGNAL_FUNC(gnome_ditem_edit_changed),
+                                              GTK_OBJECT(dee));
+
+
+        label = label_new(_("Type:"));
+        table_attach_label(GTK_TABLE(table), label, 0, 1, 3, 4);
+
+        types = g_list_prepend (types, "Directory");
+        types = g_list_prepend (types, "URL");
+        types = g_list_prepend (types, "Application");
+        dee->_priv->type_combo = gtk_combo_new();
+        gtk_combo_set_popdown_strings(GTK_COMBO(dee->_priv->type_combo), types);
+        g_list_free(types);
+        gtk_combo_set_value_in_list(GTK_COMBO(dee->_priv->type_combo), 
+                                    FALSE, TRUE);
+        table_attach_entry(GTK_TABLE(table),dee->_priv->type_combo, 1, 2, 3, 4);
+        gtk_signal_connect_object_while_alive(GTK_OBJECT(GTK_COMBO(dee->_priv->type_combo)->entry), 
+                                              "changed",
+                                              GTK_SIGNAL_FUNC(gnome_ditem_edit_changed),
+                                              GTK_OBJECT(dee));
+
+        label = label_new(_("Icon:"));
+        table_attach_label(GTK_TABLE(table), label, 0, 1, 4, 5);
+
+        hbox = gtk_hbox_new(FALSE, GNOME_PAD_BIG);
+        gtk_table_attach(GTK_TABLE(table), hbox,
+                         1, 2, 4, 5,
+                         GTK_EXPAND | GTK_FILL,
+                         0,
+                         0, 0);
+
+        dee->_priv->icon_entry = gnome_icon_entry_new("icon",_("Choose an icon"));
+        gtk_signal_connect_object_while_alive(GTK_OBJECT(dee->_priv->icon_entry),"changed",
+                                              GTK_SIGNAL_FUNC(gnome_ditem_edit_changed),
+                                              GTK_OBJECT(dee));
+        gtk_signal_connect_object_while_alive(GTK_OBJECT(dee->_priv->icon_entry),"changed",
+                                              GTK_SIGNAL_FUNC(gnome_ditem_edit_icon_changed),
+                                              GTK_OBJECT(dee));
+        gtk_box_pack_start(GTK_BOX(hbox), dee->_priv->icon_entry, FALSE, FALSE, 0);
+
+        align = gtk_alignment_new(0.0, 0.5, 0.0, 0.0);
+        gtk_box_pack_start(GTK_BOX(hbox), align, FALSE, FALSE, 0);
+
+        dee->_priv->terminal_button = gtk_check_button_new_with_label (_("Run in Terminal"));
+        gtk_signal_connect_object(GTK_OBJECT(dee->_priv->terminal_button), 
+                                  "clicked",
+                                  GTK_SIGNAL_FUNC(gnome_ditem_edit_changed),
+                                  GTK_OBJECT(dee));
+        gtk_container_add(GTK_CONTAINER(align), dee->_priv->terminal_button);
+}
+
+static void
+simple_drag_and_drop_toggled(GtkToggleButton *tb, GnomeDItemEdit *dee)
+{
+	if(tb->active) {
+		gtk_widget_set_sensitive(dee->_priv->dndtable,FALSE);
+	} else {
+		gtk_widget_set_sensitive(dee->_priv->dndtable,TRUE);
+	}
+	gnome_ditem_edit_changed(dee);
+}
+
+static void
+fill_dnd_page(GnomeDItemEdit * dee, GtkWidget * bigtable)
+{
+        GtkWidget *label;
+        GtkWidget *table;
+
+        dee->_priv->simple_dnd_toggle =
+		gtk_check_button_new_with_label (_("Simple drag and drop"));
+        gtk_signal_connect(GTK_OBJECT(dee->_priv->simple_dnd_toggle), 
+			   "toggled",
+			   GTK_SIGNAL_FUNC(simple_drag_and_drop_toggled),
+			   dee);
+        gtk_table_attach(GTK_TABLE(bigtable), dee->_priv->simple_dnd_toggle,
+                         0, 2, 0, 1,
+                         GTK_EXPAND | GTK_FILL,
+                         0,
+                         0, 0);
+
+	table = dee->_priv->dndtable = gtk_table_new (5, 2, FALSE);
+        gtk_container_set_border_width (GTK_CONTAINER (table), GNOME_PAD_SMALL);
+        gtk_table_set_row_spacings (GTK_TABLE (table), GNOME_PAD_SMALL);
+        gtk_table_set_col_spacings (GTK_TABLE (table), GNOME_PAD_SMALL);
+
+        gtk_table_attach(GTK_TABLE(bigtable), table,
+                         0, 2, 1, 2,
+                         GTK_EXPAND | GTK_FILL,
+                         GTK_EXPAND | GTK_FILL,
+                         0, 0);
+
+        label = label_new(_("In the following commands you should use %s in "
+			    "the spot where the\nfilename/URL should be "
+			    "substituted.  If you leave the field blank\n"
+			    "drops will not be accepted.  If this application "
+			    "can accept\nmultiple files or URLs as arguments "
+			    "after its command name check the box above."));
+        gtk_table_attach(GTK_TABLE(table), label,
+                         0, 2, 1, 2,
+			 0,
+                         0,
+                         0, 0);
+
+        label = label_new(_("Command for file drops:"));
+        table_attach_label(GTK_TABLE(table),label, 0, 1, 2, 3);
+
+        dee->_priv->file_drop_entry = gtk_entry_new();
+        table_attach_entry(GTK_TABLE(table),dee->_priv->file_drop_entry, 1, 2, 2, 3);
+        gtk_signal_connect_object_while_alive(GTK_OBJECT(dee->_priv->file_drop_entry), "changed",
+                                              GTK_SIGNAL_FUNC(gnome_ditem_edit_changed),
+                                              GTK_OBJECT(dee));
+
+        dee->_priv->single_file_drop_toggle =
+		gtk_check_button_new_with_label (_("Drop one file at a time "
+						   "only."));
+        gtk_signal_connect_object(GTK_OBJECT(dee->_priv->single_file_drop_toggle), 
+                                  "clicked",
+                                  GTK_SIGNAL_FUNC(gnome_ditem_edit_changed),
+                                  GTK_OBJECT(dee));
+        gtk_table_attach(GTK_TABLE(table), dee->_priv->single_file_drop_toggle,
+                         1, 2, 3, 4,
+                         GTK_EXPAND | GTK_FILL,
+                         0,
+                         0, 0);
+
+        label = label_new(_("Command for URL drops:"));
+        table_attach_label(GTK_TABLE(table),label, 0, 1, 4, 5);
+
+        dee->_priv->url_drop_entry = gtk_entry_new();
+        table_attach_entry(GTK_TABLE(table),dee->_priv->url_drop_entry, 1, 2, 4, 5);
+        gtk_signal_connect_object_while_alive(GTK_OBJECT(dee->_priv->url_drop_entry), "changed",
+                                              GTK_SIGNAL_FUNC(gnome_ditem_edit_changed),
+                                              GTK_OBJECT(dee));
+
+        dee->_priv->single_url_drop_toggle =
+		gtk_check_button_new_with_label (_("Drop one URL at a time "
+						   "only."));
+        gtk_signal_connect_object(GTK_OBJECT(dee->_priv->single_url_drop_toggle), 
+                                  "clicked",
+                                  GTK_SIGNAL_FUNC(gnome_ditem_edit_changed),
+                                  GTK_OBJECT(dee));
+        gtk_table_attach(GTK_TABLE(table), dee->_priv->single_url_drop_toggle,
+                         1, 2, 5, 6,
+                         GTK_EXPAND | GTK_FILL,
+                         0,
+                         0, 0);
+}
+
+static void
+set_list_width(GtkWidget *clist, const char * const text[])
+{
+        int i;
+        int cols = GTK_CLIST(clist)->columns;
+        GtkCList *cl = GTK_CLIST(clist);
+        for(i=0;i<cols;i++) {
+                int w = gdk_string_width(clist->style->font,text[i]);
+                if(cl->column[i].width < w)
+                        gtk_clist_set_column_width(cl,i,w);
+        }
+}
+
+static void
+translations_select_row(GtkCList *cl, int row, int column,
+			GdkEvent *event, GnomeDItemEdit *dee)
+{
+        char *lang;
+        char *name;
+        char *comment;
+        gtk_clist_get_text(cl,row,0,&lang);
+        gtk_clist_get_text(cl,row,1,&name);
+        gtk_clist_get_text(cl,row,2,&comment);
+	
+        gtk_entry_set_text(GTK_ENTRY(dee->_priv->transl_lang_entry), lang);
+        gtk_entry_set_text(GTK_ENTRY(dee->_priv->transl_name_entry), name);
+        gtk_entry_set_text(GTK_ENTRY(dee->_priv->transl_comment_entry), comment);
+}
+
+static void
+translations_add(GtkWidget *button, GnomeDItemEdit *dee)
+{
+        int i;
+        const char *lang;
+        const char *name;
+        const char *comment;
+        const char *text[3];
+        const GList *language_list;
+        const char *curlang;
+        GtkCList *cl = GTK_CLIST(dee->_priv->translations);
+
+        lang = gtk_entry_get_text(GTK_ENTRY(dee->_priv->transl_lang_entry));
+        name = gtk_entry_get_text(GTK_ENTRY(dee->_priv->transl_name_entry));
+        comment = gtk_entry_get_text(GTK_ENTRY(dee->_priv->transl_comment_entry));
+  
+        g_assert(lang && name && comment);
+	
+        lang = g_strstrip(g_strdup(lang));
+	
+        /*we are setting the current language so set the easy page entries*/
+        /*FIXME: do the opposite as well!, but that's not that crucial*/
+        language_list = gnome_i18n_get_language_list("LC_ALL");
+        curlang = language_list ? language_list->data : NULL;
+        if ((curlang && strcmp(curlang,lang)==0) ||
+            ((!curlang || strcmp(curlang,"C")==0) && !*lang)) {
+                gtk_entry_set_text(GTK_ENTRY(dee->_priv->name_entry),name);
+                gtk_entry_set_text(GTK_ENTRY(dee->_priv->comment_entry),comment);
+        }
+
+        for (i=0;i<cl->rows;i++) {
+                char *s;
+                gtk_clist_get_text(cl,i,0,&s);
+                if (strcmp(lang,s)==0) {
+                        gtk_clist_set_text(cl,i,1,name);
+                        gtk_clist_set_text(cl,i,2,comment);
+                        text[0] = s;
+                        text[1] = name;
+                        text[2] = comment;
+                        set_list_width (GTK_WIDGET(cl), text);
+                        gtk_signal_emit (GTK_OBJECT(dee),
+                                         ditem_edit_signals[CHANGED], NULL);
+                        return;
+                }
+        }
+        text[0]=lang;
+        text[1]=name;
+        text[2]=comment;
+        set_list_width(GTK_WIDGET(cl),text);
+        gtk_clist_append(cl,(char**)text);
+        gtk_signal_emit(GTK_OBJECT(dee), ditem_edit_signals[CHANGED], NULL);
+}
+
+static void
+translations_remove(GtkWidget *button, GnomeDItemEdit *dee)
+{
+        GtkCList *cl = GTK_CLIST(dee->_priv->translations);
+        if(cl->selection == NULL)
+                return;
+        gtk_clist_remove(cl,GPOINTER_TO_INT(cl->selection->data));
+        gtk_signal_emit(GTK_OBJECT(dee), ditem_edit_signals[CHANGED], NULL);
+}
+
+static void
+fill_advanced_page(GnomeDItemEdit * dee, GtkWidget * page)
+{
+        GtkWidget * label;
+        GtkWidget * button;
+        GtkWidget * box;
+        const char *transl[3];
+
+        label = label_new(_("Try this before using:"));
+        table_attach_label(GTK_TABLE(page),label, 0, 1, 0, 1);
+
+        dee->_priv->tryexec_entry = gtk_entry_new();
+        table_attach_entry(GTK_TABLE(page),dee->_priv->tryexec_entry, 1, 2, 0, 1);
+        gtk_signal_connect_object(GTK_OBJECT(dee->_priv->tryexec_entry), 
+                                  "changed",
+                                  GTK_SIGNAL_FUNC(gnome_ditem_edit_changed),
+                                  GTK_OBJECT(dee));
+
+        label = label_new(_("Documentation:"));
+        table_attach_label(GTK_TABLE(page),label, 0, 1, 1, 2);
+
+        dee->_priv->doc_entry = gtk_entry_new_with_max_length(255);
+        table_attach_entry(GTK_TABLE(page),dee->_priv->doc_entry, 1, 2, 1, 2);
+        gtk_signal_connect_object(GTK_OBJECT(dee->_priv->doc_entry), 
+                                  "changed",
+                                  GTK_SIGNAL_FUNC(gnome_ditem_edit_changed),
+                                  GTK_OBJECT(dee));
+
+        label = label_new(_("Window titles to wait for (comma separated):"));
+        table_attach_label(GTK_TABLE(page),label, 0, 2, 2, 3);
+
+        dee->_priv->wmtitles_entry = gtk_entry_new_with_max_length(255);
+        table_attach_entry(GTK_TABLE(page),dee->_priv->wmtitles_entry, 0, 2, 3, 4);
+        gtk_signal_connect_object(GTK_OBJECT(dee->_priv->wmtitles_entry), 
+                                  "changed",
+                                  GTK_SIGNAL_FUNC(gnome_ditem_edit_changed),
+                                  GTK_OBJECT(dee));
+
+        label = gtk_label_new(_("Name/Comment translations:"));
+        table_attach_label(GTK_TABLE(page),label, 0, 2, 4, 5);
+  
+        transl[0] = _("Language");
+        transl[1] = _("Name");
+        transl[2] = _("Comment");
+        dee->_priv->translations = gtk_clist_new_with_titles(3,(char**)transl);
+        set_list_width(dee->_priv->translations,transl);
+        box = gtk_scrolled_window_new(NULL,NULL);
+        gtk_widget_set_usize(box,0,120);
+        gtk_container_add(GTK_CONTAINER(box),dee->_priv->translations);
+        table_attach_list(GTK_TABLE(page),box, 0, 2, 5, 6);
+        gtk_clist_column_titles_passive(GTK_CLIST(dee->_priv->translations));
+        gtk_signal_connect(GTK_OBJECT(dee->_priv->translations),"select_row",
+                           GTK_SIGNAL_FUNC(translations_select_row),
+                           dee);
+
+        box = gtk_hbox_new(FALSE,GNOME_PAD_SMALL);
+        table_attach_entry(GTK_TABLE(page),box, 0, 2, 6, 7);
+  
+        dee->_priv->transl_lang_entry = gtk_entry_new();
+        gtk_box_pack_start(GTK_BOX(box),dee->_priv->transl_lang_entry,FALSE,FALSE,0);
+        gtk_widget_set_usize(dee->_priv->transl_lang_entry,50,0);
+
+        dee->_priv->transl_name_entry = gtk_entry_new();
+        gtk_box_pack_start(GTK_BOX(box),dee->_priv->transl_name_entry,TRUE,TRUE,0);
+
+        dee->_priv->transl_comment_entry = gtk_entry_new();
+        gtk_box_pack_start(GTK_BOX(box),dee->_priv->transl_comment_entry,TRUE,TRUE,0);
+
+        box = gtk_hbox_new(FALSE,GNOME_PAD_SMALL);
+        table_attach_entry(GTK_TABLE(page),box, 0, 2, 7, 8);
+  
+        button = gtk_button_new_with_label(_("Add/Set"));
+        gtk_box_pack_start(GTK_BOX(box),button,FALSE,FALSE,0);
+        gtk_signal_connect(GTK_OBJECT(button),"clicked",
+                           GTK_SIGNAL_FUNC(translations_add),
+                           dee);
+        button = gtk_button_new_with_label(_("Remove"));
+        gtk_box_pack_start(GTK_BOX(box),button,FALSE,FALSE,0);
+        gtk_signal_connect(GTK_OBJECT(button),"clicked",
+                           GTK_SIGNAL_FUNC(translations_remove),
+                           dee);
+}
+
+static GtkWidget *
+make_page(void)
+{
+        GtkWidget * frame, * page;
+
+        frame = gtk_frame_new (NULL);
+        gtk_container_set_border_width (GTK_CONTAINER(frame), GNOME_PAD_SMALL);
+
+        page = gtk_table_new (5, 2, FALSE);
+        gtk_container_set_border_width (GTK_CONTAINER (page), GNOME_PAD_SMALL);
+        gtk_table_set_row_spacings (GTK_TABLE (page), GNOME_PAD_SMALL);
+        gtk_table_set_col_spacings (GTK_TABLE (page), GNOME_PAD_SMALL);
+
+        gtk_container_add (GTK_CONTAINER (frame), page);
+
+        return frame;
+} 
+
+static void
+gnome_ditem_edit_init (GnomeDItemEdit *dee)
+{
+	dee->_priv = g_new0(GnomeDItemEditPrivate, 1);
+
+        dee->_priv->child1 = make_page();
+        fill_easy_page(dee, GTK_BIN(dee->_priv->child1)->child);
+        gtk_widget_show_all(dee->_priv->child1);
+
+        dee->_priv->child2 = make_page();
+        fill_dnd_page(dee, GTK_BIN(dee->_priv->child2)->child);
+        gtk_widget_show_all(dee->_priv->child2);
+
+        dee->_priv->child3 = make_page();
+        fill_advanced_page(dee, GTK_BIN(dee->_priv->child3)->child);
+        gtk_widget_show_all(dee->_priv->child3);
+}
+
+
+/**
+ * gnome_ditem_edit_new
+ *
+ * Description: Creates a new #GnomeDItemEdit object. The object is not
+ * a widget, but just an object which creates some widgets which you have
+ * to add to a notebook. Use the #gnome_ditem_edit_new_notebook to add
+ * pages to the notebook.  If you use this, make sure to take care of
+ * the refcounts of this object correctly.  You should ref/sink it when
+ * you create it and you should also unref it when your dialog dies.
+ *
+ * Returns: Newly-created #GnomeDItemEdit object.
+ */
+GtkObject *
+gnome_ditem_edit_new (void)
+{
+        GnomeDItemEdit * dee;
+
+        dee = gtk_type_new(gnome_ditem_edit_get_type());
+
+        return GTK_OBJECT (dee);
+}
+
+/**
+ * gnome_ditem_edit_child1
+ * @dee: #GnomeDItemEdit object to work with
+ *
+ * Description: Get the widget pointer to the first page.  This
+ * is the "basic" page.
+ *
+ * Returns: a pointer to a widget
+ */
+GtkWidget *
+gnome_ditem_edit_child1(GnomeDItemEdit  *dee)
+{
+        g_return_val_if_fail(dee != NULL, NULL);
+        g_return_val_if_fail(GNOME_IS_DITEM_EDIT(dee), NULL);
+
+	return dee->_priv->child1;
+}
+
+/**
+ * gnome_ditem_edit_child2
+ * @dee: #GnomeDItemEdit object to work with
+ *
+ * Description: Get the widget pointer to the second page.  This is the
+ * "Drag and Drop" page.
+ *
+ * Returns: a pointer to a widget
+ */
+GtkWidget *
+gnome_ditem_edit_child2(GnomeDItemEdit  *dee)
+{
+        g_return_val_if_fail(dee != NULL, NULL);
+        g_return_val_if_fail(GNOME_IS_DITEM_EDIT(dee), NULL);
+
+	return dee->_priv->child2;
+}
+
+/**
+ * gnome_ditem_edit_child3
+ * @dee: #GnomeDItemEdit object to work with
+ *
+ * Description: Get the widget pointer to the third page.  This is the
+ * "advanced" page.
+ *
+ * Returns: a pointer to a widget
+ */
+GtkWidget *
+gnome_ditem_edit_child3(GnomeDItemEdit  *dee)
+{
+        g_return_val_if_fail(dee != NULL, NULL);
+        g_return_val_if_fail(GNOME_IS_DITEM_EDIT(dee), NULL);
+
+	return dee->_priv->child3;
+}
+
+
+/**
+ * gnome_ditem_edit_new_notebook
+ * @notebook: notebook to add the pages to
+ *
+ * Description: Creates a new #GnomeDItemEdit object and adds it's pages
+ * to the @notebook specified in the parameter.  The object is reffed and
+ * sunk.  When the notebook dies it will be unreffed.  In effect, the notebook
+ * takes ownership of the #GnomeDItemEdit.
+ *
+ * Returns: Newly-created #GnomeDItemEdit object.
+ */
+GtkObject *
+gnome_ditem_edit_new_notebook (GtkNotebook *notebook)
+{
+        GnomeDItemEdit * dee;
+
+        g_return_val_if_fail(notebook != NULL, NULL);
+        g_return_val_if_fail(GTK_IS_NOTEBOOK(notebook), NULL);
+  
+        dee = GNOME_DITEM_EDIT(gnome_ditem_edit_new());
+
+	gtk_object_ref(GTK_OBJECT(dee));
+	gtk_object_sink(GTK_OBJECT(dee));
+
+        gtk_notebook_append_page (GTK_NOTEBOOK(notebook), 
+                                  dee->_priv->child1, 
+                                  gtk_label_new(_("Basic")));
+
+        gtk_notebook_append_page (GTK_NOTEBOOK(notebook), 
+                                  dee->_priv->child2, 
+                                  gtk_label_new(_("Drag and Drop")));
+
+        gtk_notebook_append_page (GTK_NOTEBOOK(notebook), 
+                                  dee->_priv->child3, 
+                                  gtk_label_new(_("Advanced")));
+
+        /* Destroy self with the notebook. */
+        gtk_signal_connect_object_while_alive(GTK_OBJECT(notebook), "destroy",
+					      GTK_SIGNAL_FUNC(gtk_object_unref),
+					      GTK_OBJECT(dee));
+
+        return GTK_OBJECT (dee);
+}
+
+static void
+gnome_ditem_edit_destroy (GtkObject *object)
+{
+        GnomeDItemEdit *de;
+
+        g_return_if_fail (object != NULL);
+        g_return_if_fail (GNOME_IS_DITEM_EDIT (object));
+
+	/* remember, destroy can be run multiple times! */
+
+        de = GNOME_DITEM_EDIT (object);
+
+	if (de->_priv->ditem != NULL)
+		gnome_desktop_item_unref (de->_priv->ditem);
+	de->_priv->ditem = NULL; /* just for sanity */
+
+	GNOME_CALL_PARENT_HANDLER (GTK_OBJECT_CLASS, destroy, (object));
+}
+
+static void
+gnome_ditem_edit_finalize (GObject *object)
+{
+        GnomeDItemEdit *de;
+
+        g_return_if_fail (object != NULL);
+        g_return_if_fail (GNOME_IS_DITEM_EDIT (object));
+
+        de = GNOME_DITEM_EDIT (object);
+
+	g_free(de->_priv);
+	de->_priv = NULL;
+
+	GNOME_CALL_PARENT_HANDLER (G_OBJECT_CLASS, finalize, (object));
+}
+
+/* set sensitive for directory/other type of a ditem */
+static void
+gnome_ditem_set_directory_sensitive(GnomeDItemEdit *dee,
+				    gboolean is_directory)
+{
+	gtk_widget_set_sensitive(dee->_priv->exec_entry, !is_directory);
+	gtk_widget_set_sensitive(dee->_priv->type_combo, !is_directory);
+	gtk_widget_set_sensitive(dee->_priv->terminal_button, !is_directory);
+	gtk_widget_set_sensitive(dee->_priv->tryexec_entry, !is_directory);
+	gtk_widget_set_sensitive(dee->_priv->wmtitles_entry, !is_directory);
+	gtk_widget_set_sensitive(dee->_priv->simple_dnd_toggle, !is_directory);
+	gtk_widget_set_sensitive(dee->_priv->dndtable, !is_directory);
+}
+
+/* Conform display to ditem */
+static void
+gnome_ditem_edit_sync_display(GnomeDItemEdit *dee,
+                              GnomeDesktopItem *ditem)
+{
+        GSList *i18n_list,*li;
+        const gchar* cs;
+        
+        g_return_if_fail(dee != NULL);
+        g_return_if_fail(GNOME_IS_DITEM_EDIT(dee));
+        g_return_if_fail(ditem != NULL);
+
+        cs = gnome_desktop_item_get_type(ditem);
+	if(cs && strcmp(cs,"Directory")==0) {
+		GList *types = NULL;
+		gnome_ditem_set_directory_sensitive(dee, TRUE);
+		types = g_list_prepend(types, "Directory");
+		gtk_combo_set_popdown_strings(GTK_COMBO(dee->_priv->type_combo),
+					      types);
+		g_list_free(types);
+	} else {
+		GList *types = NULL;
+		gnome_ditem_set_directory_sensitive(dee, FALSE);
+		types = g_list_prepend(types, "URL");
+		types = g_list_prepend(types, "PanelApplet");
+		types = g_list_prepend(types, "Application");
+		if(cs &&
+		   strcmp(cs,"URL") != 0 &&
+		   strcmp(cs,"PanelApplet") != 0 &&
+		   strcmp(cs,"Application") != 0)
+			types = g_list_prepend(types, (char *)cs);
+		gtk_combo_set_popdown_strings(GTK_COMBO(dee->_priv->type_combo),
+					      types);
+		g_list_free(types);
+	}
+
+        cs = gnome_desktop_item_get_local_name(ditem);
+        gtk_entry_set_text(GTK_ENTRY(dee->_priv->name_entry), 
+                           cs ? cs : "");
+
+        cs = gnome_desktop_item_get_local_comment(ditem);
+        gtk_entry_set_text(GTK_ENTRY(dee->_priv->comment_entry),
+                           cs ? cs : "");
+
+        cs = gnome_desktop_item_get_command(ditem);
+        gtk_entry_set_text(GTK_ENTRY(dee->_priv->exec_entry), cs ? cs : "");
+
+        cs = gnome_desktop_item_get_attribute(ditem, "TryExec");
+        gtk_entry_set_text(GTK_ENTRY(dee->_priv->tryexec_entry), 
+                           cs ? cs : "");
+
+        cs = gnome_desktop_item_get_icon_path(ditem);
+        gnome_selector_set_uri(GNOME_SELECTOR(dee->_priv->icon_entry),
+                               NULL, cs, NULL, NULL);
+
+        cs = gnome_desktop_item_get_attribute(ditem, "DocPath"); /* FIXME check name */
+        gtk_entry_set_text(GTK_ENTRY(dee->_priv->doc_entry), 
+                           cs ? cs : "");
+
+        cs = gnome_desktop_item_get_attribute(ditem, "WMTitles");
+        gtk_entry_set_text(GTK_ENTRY(dee->_priv->wmtitles_entry), 
+                           cs ? cs : "");
+
+        cs = gnome_desktop_item_get_type(ditem);
+        gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(dee->_priv->type_combo)->entry),
+                           cs ? cs : "");
+
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dee->_priv->terminal_button),
+                                     gnome_desktop_item_get_flags(ditem) &
+				      GNOME_DESKTOP_ITEM_RUN_IN_TERMINAL);
+
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dee->_priv->simple_dnd_toggle),
+                                     gnome_desktop_item_get_flags(ditem) &
+				      GNOME_DESKTOP_ITEM_OLD_STYLE_DROP);
+
+        cs = gnome_desktop_item_get_attribute(ditem, "FileDropExec");
+        gtk_entry_set_text(GTK_ENTRY(dee->_priv->file_drop_entry), 
+                           cs ? cs : "");
+
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dee->_priv->single_file_drop_toggle),
+                                     gnome_desktop_item_get_flags(ditem) &
+				      GNOME_DESKTOP_ITEM_SINGLE_FILE_DROP_ONLY);
+	
+        cs = gnome_desktop_item_get_attribute(ditem, "URLDropExec");
+        gtk_entry_set_text(GTK_ENTRY(dee->_priv->url_drop_entry), 
+                           cs ? cs : "");
+
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dee->_priv->single_url_drop_toggle),
+                                     gnome_desktop_item_get_flags(ditem) &
+				      GNOME_DESKTOP_ITEM_SINGLE_URL_DROP_ONLY);
+  
+        /*set the names and comments from our i18n list*/
+        gtk_clist_clear (GTK_CLIST(dee->_priv->translations));
+        i18n_list = gnome_desktop_item_get_languages(ditem);
+        for (li=i18n_list; li; li=li->next) {
+                const char *text[3];
+                const gchar* lang = li->data;
+                cs = lang;
+                text[0] = cs ? cs : "";
+                cs = gnome_desktop_item_get_name(ditem, lang);
+                text[1] = cs ? cs : "";
+                cs = gnome_desktop_item_get_comment(ditem, lang);
+                text[2] = cs ? cs : "";
+                set_list_width (dee->_priv->translations,text);
+                gtk_clist_append (GTK_CLIST(dee->_priv->translations),(char**)text);
+        }
+        g_slist_free(i18n_list);
+
+	/* clear the entries for add/remove */
+        gtk_entry_set_text(GTK_ENTRY(dee->_priv->transl_lang_entry), "");
+        gtk_entry_set_text(GTK_ENTRY(dee->_priv->transl_name_entry), "");
+        gtk_entry_set_text(GTK_ENTRY(dee->_priv->transl_comment_entry), "");
+}
+
+/* Conform ditem to display */
+static void
+gnome_ditem_edit_sync_ditem(GnomeDItemEdit *dee,
+                            GnomeDesktopItem *ditem)
+{
+        const gchar * text;
+        int i;
+        const gchar* lang;
+        gint curflags;
+        
+        g_return_if_fail(dee != NULL);
+        g_return_if_fail(GNOME_IS_DITEM_EDIT(dee));
+        g_return_if_fail(ditem != NULL);
+
+        lang = gnome_i18n_get_preferred_language();
+        
+        text = gtk_entry_get_text(GTK_ENTRY(dee->_priv->name_entry));
+        gnome_desktop_item_set_name(ditem, lang, text);
+
+        text = gtk_entry_get_text(GTK_ENTRY(dee->_priv->comment_entry));
+        gnome_desktop_item_set_comment(ditem, lang, text);
+
+        text = gtk_entry_get_text(GTK_ENTRY(dee->_priv->exec_entry));
+        gnome_desktop_item_set_command(ditem, text);
+
+        text = gtk_entry_get_text(GTK_ENTRY(dee->_priv->tryexec_entry));
+        gnome_desktop_item_set_attribute(ditem, "TryExec", text);
+  
+        text = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(dee->_priv->type_combo)->entry));
+        gnome_desktop_item_set_type(ditem, text);
+  
+        gnome_desktop_item_set_icon_path(ditem,
+                                         gnome_selector_get_uri(GNOME_SELECTOR(dee->_priv->icon_entry)));
+
+        text = gtk_entry_get_text(GTK_ENTRY(dee->_priv->doc_entry));
+        gnome_desktop_item_set_attribute(ditem, "DocPath", text);
+
+        text = gtk_entry_get_text(GTK_ENTRY(dee->_priv->wmtitles_entry));
+        gnome_desktop_item_set_attribute(ditem, "WMTitles", text);
+
+        curflags = gnome_desktop_item_get_flags(ditem);
+        if (GTK_TOGGLE_BUTTON(dee->_priv->terminal_button)->active)
+                curflags |= GNOME_DESKTOP_ITEM_RUN_IN_TERMINAL;
+        else
+                curflags &= ~GNOME_DESKTOP_ITEM_RUN_IN_TERMINAL;
+        gnome_desktop_item_set_flags(ditem, curflags);
+
+        curflags = gnome_desktop_item_get_flags(ditem);
+        if (GTK_TOGGLE_BUTTON(dee->_priv->simple_dnd_toggle)->active)
+                curflags |= GNOME_DESKTOP_ITEM_OLD_STYLE_DROP;
+        else
+                curflags &= ~GNOME_DESKTOP_ITEM_OLD_STYLE_DROP;
+        gnome_desktop_item_set_flags(ditem, curflags);
+
+        text = gtk_entry_get_text(GTK_ENTRY(dee->_priv->file_drop_entry));
+        gnome_desktop_item_set_attribute(ditem, "FileDropExec", text);
+
+        curflags = gnome_desktop_item_get_flags(ditem);
+        if (GTK_TOGGLE_BUTTON(dee->_priv->single_file_drop_toggle)->active)
+                curflags |= GNOME_DESKTOP_ITEM_SINGLE_FILE_DROP_ONLY;
+        else
+                curflags &= ~GNOME_DESKTOP_ITEM_SINGLE_FILE_DROP_ONLY;
+        gnome_desktop_item_set_flags(ditem, curflags);
+
+        text = gtk_entry_get_text(GTK_ENTRY(dee->_priv->url_drop_entry));
+        gnome_desktop_item_set_attribute(ditem, "URLDropExec", text);
+
+        curflags = gnome_desktop_item_get_flags(ditem);
+        if (GTK_TOGGLE_BUTTON(dee->_priv->single_url_drop_toggle)->active)
+                curflags |= GNOME_DESKTOP_ITEM_SINGLE_URL_DROP_ONLY;
+        else
+                curflags &= ~GNOME_DESKTOP_ITEM_SINGLE_URL_DROP_ONLY;
+        gnome_desktop_item_set_flags(ditem, curflags);
+        
+	gnome_desktop_item_clear_name(ditem);
+	gnome_desktop_item_clear_comment(ditem);
+        for(i=0;i<GTK_CLIST(dee->_priv->translations)->rows;i++) {
+                const char *lang,*name,*comment;
+                gtk_clist_get_text(GTK_CLIST(dee->_priv->translations),i,0,(gchar**)&lang);
+                gtk_clist_get_text(GTK_CLIST(dee->_priv->translations),i,1,(gchar**)&name);
+                gtk_clist_get_text(GTK_CLIST(dee->_priv->translations),i,2,(gchar**)&comment);
+                if(!*lang) lang = NULL;
+                if(!*name) name = NULL;
+                if(!*comment) comment = NULL;
+                if(!name && !comment)
+                        continue;
+
+                if (lang == NULL)
+                        lang = gnome_i18n_get_preferred_language();
+
+                g_assert(lang != NULL);
+                
+                gnome_desktop_item_set_name(ditem, lang, name);
+                gnome_desktop_item_set_comment(ditem, lang, comment);
+        }
+}
+
+/**
+ * gnome_ditem_edit_load_file
+ * @dee: #GnomeDItemEdit object to work with
+ * @path: file to load into the editting areas
+ *
+ * Description: Load a .desktop file and update the editting areas
+ * of the object accordingly.
+ *
+ * Returns:
+ */
+void
+gnome_ditem_edit_load_file(GnomeDItemEdit *dee,
+                           const gchar *path)
+{
+        GnomeDesktopItem * newentry;
+
+        g_return_if_fail(dee != NULL);
+        g_return_if_fail(GNOME_IS_DITEM_EDIT(dee));
+        g_return_if_fail(path != NULL);
+
+        newentry = gnome_desktop_item_new_from_file(path, 0);
+
+        if (newentry) {
+		if(dee->_priv->ditem)
+			gnome_desktop_item_unref(dee->_priv->ditem);
+		dee->_priv->ditem = newentry;
+                gnome_ditem_edit_sync_display(dee, newentry);
+        } else {
+                g_warning("Failed to load file into GnomeDItemEdit");
+                return;
+        }
+}
+
+/**
+ * gnome_ditem_edit_set_ditem
+ * @dee: #GnomeDItemEdit object to work with
+ * @ditem: #GnomeDesktopItem to use
+ *
+ * Description: Unref the existing item, and replace it with
+ * this one.  This doesn't make a copy, it just refs the the passed
+ * item.  It them updates the display to reflect the new item.
+ * It will not make any modifications to this ditem, but you shouldn't
+ * modify it either.  If you need to modify the item independently,
+ * make a copy, call this function and then unref the copy (this function
+ * will make it's own reference so it won't kill it but transfer
+ * ownership here)
+ *
+ * Returns:
+ */
+void
+gnome_ditem_edit_set_ditem(GnomeDItemEdit *dee,
+                           GnomeDesktopItem *ditem)
+{
+        g_return_if_fail(dee != NULL);
+        g_return_if_fail(GNOME_IS_DITEM_EDIT(dee));
+        g_return_if_fail(ditem != NULL);
+
+	if(dee->_priv->ditem)
+		gnome_desktop_item_unref(dee->_priv->ditem);
+	dee->_priv->ditem = ditem;
+
+	gnome_desktop_item_ref(dee->_priv->ditem);
+
+        gnome_ditem_edit_sync_display(dee, dee->_priv->ditem);
+}
+
+/**
+ * gnome_ditem_edit_get_ditem
+ * @dee: #GnomeDItemEdit object to work with
+ *
+ * Description: Get the current status of the editting areas
+ * as a #GnomeDesktopItem structure.  It always gives a completely
+ * newly allocated #GnomeDesktopItem structure.  If a copy of an
+ * internal or previously set item is made it is always converted
+ * to a gnome type of a desktop item.
+ *
+ * Returns: a newly allocated #GnomeDesktopItem structure.
+ */
+GnomeDesktopItem *
+gnome_ditem_edit_get_ditem(GnomeDItemEdit *dee)
+{
+        GnomeDesktopItem * ditem;
+
+        g_return_val_if_fail(dee != NULL, NULL);
+        g_return_val_if_fail(GNOME_IS_DITEM_EDIT(dee), NULL);
+
+	if(dee->_priv->ditem) {
+		ditem = gnome_desktop_item_copy(dee->_priv->ditem);
+		gnome_desktop_item_set_format(ditem, GNOME_DESKTOP_ITEM_GNOME);
+	} else
+		ditem = gnome_desktop_item_new();
+	gnome_ditem_edit_sync_ditem(dee, ditem);
+        return ditem;
+}
+
+/**
+ * gnome_ditem_edit_clear
+ * @dee: #GnomeDItemEdit object to work with
+ *
+ * Description: Clear the editting areas.  And unref any
+ * stored #GnomeDesktopItem.
+ *
+ * Returns:
+ */
+void
+gnome_ditem_edit_clear(GnomeDItemEdit *dee)
+{
+	GList *types = NULL;
+
+        g_return_if_fail(dee != NULL);
+        g_return_if_fail(GNOME_IS_DITEM_EDIT(dee));
+
+	if(dee->_priv->ditem)
+		gnome_desktop_item_unref(dee->_priv->ditem);
+	dee->_priv->ditem = NULL;
+
+        gtk_entry_set_text(GTK_ENTRY(dee->_priv->name_entry), "");
+        gtk_entry_set_text(GTK_ENTRY(dee->_priv->comment_entry),"");
+        gtk_entry_set_text(GTK_ENTRY(dee->_priv->exec_entry), "");  
+        gtk_entry_set_text(GTK_ENTRY(dee->_priv->tryexec_entry), "");
+        gtk_entry_set_text(GTK_ENTRY(dee->_priv->doc_entry), "");
+        gnome_selector_set_uri(GNOME_SELECTOR(dee->_priv->icon_entry), NULL,
+                               "", NULL, NULL);
+        gtk_entry_set_text(GTK_ENTRY(dee->_priv->transl_lang_entry), "");
+        gtk_entry_set_text(GTK_ENTRY(dee->_priv->transl_name_entry), "");
+        gtk_entry_set_text(GTK_ENTRY(dee->_priv->transl_comment_entry), "");
+        gtk_clist_clear(GTK_CLIST(dee->_priv->translations));
+
+	/* set everything to non-directory type which means any type */
+	gnome_ditem_set_directory_sensitive(dee, FALSE);
+
+	/* put all our possibilities here */
+	types = g_list_prepend(types, "Application");
+	types = g_list_prepend(types, "PanelApplet");
+	types = g_list_prepend(types, "URL");
+	types = g_list_prepend(types, "Directory");
+	gtk_combo_set_popdown_strings(GTK_COMBO(dee->_priv->type_combo),
+				      types);
+	g_list_free(types);
+}
+
+static void
+gnome_ditem_edit_changed(GnomeDItemEdit *dee)
+{
+        gtk_signal_emit(GTK_OBJECT(dee), ditem_edit_signals[CHANGED], NULL);
+}
+
+static void
+gnome_ditem_edit_icon_changed(GnomeDItemEdit *dee)
+{
+        gtk_signal_emit(GTK_OBJECT(dee), ditem_edit_signals[ICON_CHANGED], NULL);
+}
+
+static void
+gnome_ditem_edit_name_changed(GnomeDItemEdit *dee)
+{
+        gtk_signal_emit(GTK_OBJECT(dee), ditem_edit_signals[NAME_CHANGED], NULL);
+}
+
+/**
+ * gnome_ditem_edit_get_icon
+ * @dee: #GnomeDItemEdit object to work with
+ *
+ * Description: Get the icon filename. The icon is entered into a
+ * #GnomeIconEntry, so the semantics of this call are the same as
+ * for #gnome_icon_entry_get_filename
+ *
+ * Returns: a newly allocated string with the filename of the icon
+ */
+gchar *
+gnome_ditem_edit_get_icon(GnomeDItemEdit *dee)
+{
+        g_return_val_if_fail(dee != NULL, NULL);
+        g_return_val_if_fail(GNOME_IS_DITEM_EDIT(dee), NULL);
+ 
+        return gnome_selector_get_uri(GNOME_SELECTOR(dee->_priv->icon_entry));
+}
+
+/**
+ * gnome_ditem_edit_get_name
+ * @dee: #GnomeDItemEdit object to work with
+ *
+ * Description: Get the Name field from the ditem for the current language.
+ *
+ * Returns: a newly allocated string with the name of the ditem
+ */
+gchar *
+gnome_ditem_edit_get_name (GnomeDItemEdit *dee)
+{
+        const char * name;
+
+        g_return_val_if_fail(dee != NULL, NULL);
+        g_return_val_if_fail(GNOME_IS_DITEM_EDIT(dee), NULL);
+
+        name = gtk_entry_get_text(GTK_ENTRY(dee->_priv->name_entry));
+        return g_strdup(name);
+}
+
+/**
+ * gnome_ditem_edit_get_name_entry
+ * @dee: #GnomeDItemEdit object to work with
+ *
+ * Description: Get the entry widget (a #GtkEntry) for the Name field.
+ * Note that the name is only valid for this current language.
+ *
+ * Returns: a pointer to a #GtkEntry widget used for the Name field
+ */
+GtkWidget *
+gnome_ditem_edit_get_name_entry (GnomeDItemEdit *dee)
+{
+        g_return_val_if_fail(dee != NULL, NULL);
+        g_return_val_if_fail(GNOME_IS_DITEM_EDIT(dee), NULL);
+
+        return dee->_priv->name_entry;
+}
+
+/**
+ * gnome_ditem_edit_get_comment_entry
+ * @dee: #GnomeDItemEdit object to work with
+ *
+ * Description: Get the entry widget (a #GtkEntry) for the Comment field.
+ * Note that the comment is only valid for this current language.
+ *
+ * Returns: a pointer to a #GtkEntry widget used for the Comment field
+ */
+GtkWidget *
+gnome_ditem_edit_get_comment_entry (GnomeDItemEdit *dee)
+{
+        g_return_val_if_fail(dee != NULL, NULL);
+        g_return_val_if_fail(GNOME_IS_DITEM_EDIT(dee), NULL);
+
+        return dee->_priv->comment_entry;
+}
+
+/**
+ * gnome_ditem_edit_get_exec_entry
+ * @dee: #GnomeDItemEdit object to work with
+ *
+ * Description: Get the entry widget (a #GtkEntry) for the Command
+ * (exec) field.
+ *
+ * Returns: a pointer to a #GtkEntry widget used for the Command (exec) field
+ */
+GtkWidget *
+gnome_ditem_edit_get_exec_entry (GnomeDItemEdit *dee)
+{
+        g_return_val_if_fail(dee != NULL, NULL);
+        g_return_val_if_fail(GNOME_IS_DITEM_EDIT(dee), NULL);
+
+        return dee->_priv->exec_entry;
+}
+
+/**
+ * gnome_ditem_edit_get_tryexec_entry
+ * @dee: #GnomeDItemEdit object to work with
+ *
+ * Description: Get the entry widget (a #GtkEntry) for the TryExec field.
+ *
+ * Returns: a pointer to a #GtkEntry widget used for the TryExec field
+ */
+GtkWidget *
+gnome_ditem_edit_get_tryexec_entry (GnomeDItemEdit *dee)
+{
+        g_return_val_if_fail(dee != NULL, NULL);
+        g_return_val_if_fail(GNOME_IS_DITEM_EDIT(dee), NULL);
+
+        return dee->_priv->tryexec_entry;
+}
+
+/**
+ * gnome_ditem_edit_get_doc_entry
+ * @dee: #GnomeDItemEdit object to work with
+ *
+ * Description: Get the entry widget (a #GtkEntry) for the
+ * Documentation field.
+ *
+ * Returns: a pointer to a #GtkEntry widget used for the
+ * Documentation field
+ */
+GtkWidget *
+gnome_ditem_edit_get_doc_entry (GnomeDItemEdit *dee)
+{
+        g_return_val_if_fail(dee != NULL, NULL);
+        g_return_val_if_fail(GNOME_IS_DITEM_EDIT(dee), NULL);
+
+        return dee->_priv->doc_entry;
+}
+
+/**
+ * gnome_ditem_edit_get_icon_entry
+ * @dee: #GnomeDItemEdit object to work with
+ *
+ * Description: Get the icon entry widget (a #GnomeIconEntry)
+ * for the icon field.
+ *
+ * Returns: a pointer to a #GnomeIconEntry widget
+ */
+GtkWidget *
+gnome_ditem_edit_get_icon_entry (GnomeDItemEdit *dee)
+{
+        g_return_val_if_fail(dee != NULL, NULL);
+        g_return_val_if_fail(GNOME_IS_DITEM_EDIT(dee), NULL);
+
+        return dee->_priv->icon_entry;
+}
+
+/**
+ * gnome_ditem_edit_get_wmtitles_entry
+ * @dee: #GnomeDItemEdit object to work with
+ *
+ * Description: Get the entry widget (a #GtkEntry) for
+ * the comma separated list of titles to watch when launching
+ * an application
+ *
+ * Returns: a pointer to a #GtkEntry widget
+ */
+GtkWidget *
+gnome_ditem_edit_get_wmtitles_entry (GnomeDItemEdit *dee)
+{
+        g_return_val_if_fail(dee != NULL, NULL);
+        g_return_val_if_fail(GNOME_IS_DITEM_EDIT(dee), NULL);
+
+        return dee->_priv->wmtitles_entry;
+}
+
+/**
+ * gnome_ditem_edit_get_simple_dnd_toggle
+ * @dee: #GnomeDItemEdit object to work with
+ *
+ * Description: Get the check button widget (a #GtkCheckButton)
+ * that sets the GNOME_DESKTOP_ITEM_OLD_STYLE_DROP flag for the
+ * #GnomeDesktopItem.
+ *
+ * Returns: a pointer to a #GtkCheckButton
+ */
+GtkWidget *
+gnome_ditem_edit_get_simple_dnd_toggle(GnomeDItemEdit *dee)
+{
+        g_return_val_if_fail(dee != NULL, NULL);
+        g_return_val_if_fail(GNOME_IS_DITEM_EDIT(dee), NULL);
+
+	return dee->_priv->simple_dnd_toggle;
+}
+
+/**
+ * gnome_ditem_edit_get_file_drop_entry
+ * @dee: #GnomeDItemEdit object to work with
+ *
+ * Description: Get the entry widget (a #GtkEntry) for the
+ * FileDropExec field
+ *
+ * Returns: a pointer to a #GtkEntry widget
+ */
+GtkWidget *
+gnome_ditem_edit_get_file_drop_entry(GnomeDItemEdit  *dee)
+{
+        g_return_val_if_fail(dee != NULL, NULL);
+        g_return_val_if_fail(GNOME_IS_DITEM_EDIT(dee), NULL);
+
+	return dee->_priv->file_drop_entry;
+}
+
+/**
+ * gnome_ditem_edit_get_single_file_drop_toggle
+ * @dee: #GnomeDItemEdit object to work with
+ *
+ * Description: Get the check button widget (a #GtkCheckButton) for the
+ * SingleFileDropOnly field
+ *
+ * Returns: a pointer to a #GtkCheckButton widget
+ */
+GtkWidget *
+gnome_ditem_edit_get_single_file_drop_toggle(GnomeDItemEdit *dee)
+{
+        g_return_val_if_fail(dee != NULL, NULL);
+        g_return_val_if_fail(GNOME_IS_DITEM_EDIT(dee), NULL);
+
+	return dee->_priv->single_file_drop_toggle;
+}
+
+/**
+ * gnome_ditem_edit_get_url_drop_entry
+ * @dee: #GnomeDItemEdit object to work with
+ *
+ * Description: Get the entry widget (a #GtkEntry) for the
+ * URLDropExec field
+ *
+ * Returns: a pointer to a #GtkEntry widget
+ */
+GtkWidget *
+gnome_ditem_edit_get_url_drop_entry(GnomeDItemEdit  *dee)
+{
+        g_return_val_if_fail(dee != NULL, NULL);
+        g_return_val_if_fail(GNOME_IS_DITEM_EDIT(dee), NULL);
+
+	return dee->_priv->url_drop_entry;
+}
+
+/**
+ * gnome_ditem_edit_get_single_file_drop_toggle
+ * @dee: #GnomeDItemEdit object to work with
+ *
+ * Description: Get the check button widget (a #GtkCheckButton) for the
+ * SingleURLDropOnly field
+ *
+ * Returns: a pointer to a #GtkCheckButton widget
+ */
+GtkWidget *
+gnome_ditem_edit_get_single_url_drop_toggle(GnomeDItemEdit *dee)
+{
+        g_return_val_if_fail(dee != NULL, NULL);
+        g_return_val_if_fail(GNOME_IS_DITEM_EDIT(dee), NULL);
+
+	return dee->_priv->single_url_drop_toggle;
+}
+
+
+#ifdef TEST_DITEM_EDIT
+
+#include <libgnomeui.h>
+
+static void
+changed_callback(GnomeDItemEdit *dee, gpointer data)
+{
+        g_print("Changed!\n");
+        fflush(stdout);
+}
+
+static void
+icon_changed_callback(GnomeDItemEdit *dee, gpointer data)
+{
+        g_print("Icon changed!\n");
+        fflush(stdout);
+}
+
+static void
+name_changed_callback(GnomeDItemEdit *dee, gpointer data)
+{
+        g_print("Name changed!\n");
+        fflush(stdout);
+}
+
+int
+main(int argc, char * argv[])
+{
+        GtkWidget * app;
+        GtkWidget * notebook;
+        GtkObject * dee;
+
+        argp_program_version = VERSION;
+
+        gnome_init ("testing ditem edit", NULL, argc, argv, 0, 0);
+
+        app = gnome_app_new("testing ditem edit", "Testing");
+
+        notebook = gtk_notebook_new();
+
+        gnome_app_set_contents(GNOME_APP(app), notebook);
+
+        dee = gnome_ditem_edit_new(GTK_NOTEBOOK(notebook));
+
+        gnome_ditem_edit_load_file(GNOME_DITEM_EDIT(dee),
+                                   "/usr/local/share/gnome/apps/grun.desktop");
+
+#ifdef GNOME_ENABLE_DEBUG
+        g_print("Dialog (main): %p\n", GNOME_DITEM_EDIT(dee)->icon_dialog);
+#endif
+
+        gtk_signal_connect_object(GTK_OBJECT(app), "delete_event", 
+                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
+                                  GTK_OBJECT(app));
+
+        gtk_signal_connect(GTK_OBJECT(app), "destroy",
+                           GTK_SIGNAL_FUNC(gtk_main_quit),
+                           NULL);
+
+        gtk_signal_connect(GTK_OBJECT(dee), "changed",
+                           GTK_SIGNAL_FUNC(changed_callback),
+                           NULL);
+
+        gtk_signal_connect(GTK_OBJECT(dee), "icon_changed",
+                           GTK_SIGNAL_FUNC(icon_changed_callback),
+                           NULL);
+
+        gtk_signal_connect(GTK_OBJECT(dee), "name_changed",
+                           GTK_SIGNAL_FUNC(name_changed_callback),
+                           NULL);
+
+#ifdef GNOME_ENABLE_DEBUG
+        g_print("Dialog (main 2): %p\n", GNOME_DITEM_EDIT(dee)->icon_dialog);
+#endif
+
+        gtk_widget_show(notebook);
+        gtk_widget_show(app);
+
+#ifdef GNOME_ENABLE_DEBUG
+        g_print("Dialog (main 3): %p\n", GNOME_DITEM_EDIT(dee)->icon_dialog);
+#endif
+
+        gtk_main();
+
+        return 0;
+}
+
+#endif
+
diff --git a/libgnomeui/gnome-ditem-edit.h b/libgnomeui/gnome-ditem-edit.h
new file mode 100644
index 0000000..d9559f2
--- /dev/null
+++ b/libgnomeui/gnome-ditem-edit.h
@@ -0,0 +1,139 @@
+/*  -*- Mode: C; c-set-style: linux; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+
+   Copyright (C) 1999 Free Software Foundation
+   All rights reserved.
+    
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   GnomeDItemEdit Developers: Havoc Pennington, based on code by John Ellis
+*/
+/*
+  @NOTATION@
+*/
+
+/******************** NOTE: this is an object, not a widget.
+ ********************       You must supply a GtkNotebook.
+ The reason for this is that you might want this in a property box, 
+ or in your own notebook. Look at the test program at the bottom 
+ of gnome-dentry-edit.c for a usage example.
+ */
+
+#ifndef GNOME_DITEM_EDIT_H
+#define GNOME_DITEM_EDIT_H
+
+#include <gtk/gtk.h>
+
+#include <libgnome/gnome-ditem.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GnomeDItemEdit        GnomeDItemEdit;
+typedef struct _GnomeDItemEditPrivate GnomeDItemEditPrivate;
+typedef struct _GnomeDItemEditClass   GnomeDItemEditClass;
+
+#define GNOME_TYPE_DITEM_EDIT            (gnome_ditem_edit_get_type ())
+#define GNOME_DITEM_EDIT(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_DITEM_EDIT, GnomeDItemEdit))
+#define GNOME_DITEM_EDIT_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_DITEM_EDIT, GnomeDItemEditClass))
+#define GNOME_IS_DITEM_EDIT(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_DITEM_EDIT))
+#define GNOME_IS_DITEM_EDIT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_DITEM_EDIT))
+#define GNOME_DITEM_EDIT_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_DITEM_EDIT, GnomeDItemEditClass))
+
+struct _GnomeDItemEdit {
+        GtkObject object;
+  
+	/*< private >*/
+	GnomeDItemEditPrivate *_priv;
+};
+
+struct _GnomeDItemEditClass {
+        GtkObjectClass parent_class;
+
+        /* Any information changed */
+        void (* changed)         (GnomeDItemEdit * gee);
+        /* These two more specific signals are provided since they 
+           will likely require a display update */
+        /* The icon in particular has changed. */
+        void (* icon_changed)    (GnomeDItemEdit * gee);
+        /* The name of the item has changed. */
+        void (* name_changed)    (GnomeDItemEdit * gee);
+};
+
+guint             gnome_ditem_edit_get_type     (void) G_GNUC_CONST;
+
+/*create a new ditem and get the children using the below functions 
+  or use the utility new_notebook below*/
+GtkObject *       gnome_ditem_edit_new          (void);
+
+/* the main page */
+GtkWidget *       gnome_ditem_edit_child1	(GnomeDItemEdit  *dee);
+/* the DND page */
+GtkWidget *       gnome_ditem_edit_child2	(GnomeDItemEdit  *dee);
+/* the advanced page */
+GtkWidget *       gnome_ditem_edit_child3	(GnomeDItemEdit  *dee);
+
+/* Create a new edit in this notebook - appends two pages to the 
+   notebook. */
+GtkObject *       gnome_ditem_edit_new_notebook (GtkNotebook      *notebook);
+void              gnome_ditem_edit_clear        (GnomeDItemEdit   *dee);
+
+
+
+/* The GnomeDItemEdit does not store a ditem, and it does not keep
+   track of the location field of GnomeDesktopItem which will always
+   be NULL. */
+
+/* Make the display reflect ditem at path */
+void              gnome_ditem_edit_load_file    (GnomeDItemEdit   *dee,
+                                                 const gchar      *path);
+
+/* Copy the contents of this ditem into the display */
+void              gnome_ditem_edit_set_ditem    (GnomeDItemEdit   *dee,
+                                                 GnomeDesktopItem *ditem);
+
+/* Generate a ditem based on the contents of the display */
+GnomeDesktopItem *gnome_ditem_edit_get_ditem    (GnomeDItemEdit   *dee);
+
+
+
+/* Return an allocated string, you need to g_free it. */
+gchar *           gnome_ditem_edit_get_icon     (GnomeDItemEdit   *dee);
+gchar *           gnome_ditem_edit_get_name     (GnomeDItemEdit   *dee);
+
+
+
+/* These are accessor functions for the widgets that make up the
+   GnomeDItemEdit editting areas. */
+GtkWidget *       gnome_ditem_edit_get_name_entry    (GnomeDItemEdit   *dee);
+GtkWidget *       gnome_ditem_edit_get_comment_entry (GnomeDItemEdit   *dee);
+GtkWidget *       gnome_ditem_edit_get_exec_entry    (GnomeDItemEdit   *dee);
+GtkWidget *       gnome_ditem_edit_get_tryexec_entry (GnomeDItemEdit   *dee);
+GtkWidget *       gnome_ditem_edit_get_doc_entry     (GnomeDItemEdit   *dee);
+GtkWidget *       gnome_ditem_edit_get_icon_entry    (GnomeDItemEdit   *dee);
+GtkWidget *       gnome_ditem_edit_get_wmtitles_entry(GnomeDItemEdit   *dee);
+
+GtkWidget *       gnome_ditem_edit_get_simple_dnd_toggle(GnomeDItemEdit *dee);
+GtkWidget *       gnome_ditem_edit_get_file_drop_entry(GnomeDItemEdit  *dee);
+GtkWidget *       gnome_ditem_edit_get_single_file_drop_toggle(GnomeDItemEdit *dee);
+GtkWidget *       gnome_ditem_edit_get_url_drop_entry(GnomeDItemEdit  *dee);
+GtkWidget *       gnome_ditem_edit_get_single_url_drop_toggle(GnomeDItemEdit *dee);
+
+G_END_DECLS
+   
+#endif /* GNOME_DITEM_EDIT_H */
+
+
+
+
diff --git a/libgnomeui/gnome-dock-band.c b/libgnomeui/gnome-dock-band.c
new file mode 100644
index 0000000..b6907c2
--- /dev/null
+++ b/libgnomeui/gnome-dock-band.c
@@ -0,0 +1,1981 @@
+/*
+ * !!! MASTER CAUTION !!!!
+ *
+ * These files have been moved to libbonoboui and renamed to bonobo-dock*.[ch].
+ * We'll provide a compatibility wrapper with #defines in libgnomecompat soon, but
+ * at the moment I don't want to break the build here since libbonoboui doesn't work yet.
+ *
+ * If you do any changes in these files here, your work will be lost !
+ */
+
+/* gnome-dock-band.c
+
+   Copyright (C) 1998 Free Software Foundation
+
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Ettore Perazzoli <ettore comm2000 it>
+*/
+
+#include <gtk/gtk.h>
+
+#include "gnome-dock.h"
+#include "gnome-dock-band.h"
+#include "gnome-dock-item.h"
+
+
+
+#define noGNOME_DOCK_BAND_DEBUG
+
+/* FIXME: To be removed.  */
+#if defined GNOME_DOCK_BAND_DEBUG && defined __GNUC__
+#define DEBUG(x)                                        \
+  do                                                    \
+    {                                                   \
+      printf ("%s.%d: ", __FUNCTION__, __LINE__);       \
+      printf x;                                         \
+      putchar ('\n');                                   \
+    }                                                   \
+  while (0)
+#else
+#define DEBUG(x)
+#endif
+
+
+
+struct _GnomeDockBandPrivate
+{
+	int dummy;
+	/* Nothing right now, needs to get filled with the private things */
+	/* XXX: When stuff is added, uncomment the allocation in the
+	 * gnome_dock_band_init function! */
+};
+
+
+
+static void     gnome_dock_band_class_init    (GnomeDockBandClass *class);
+
+static void     gnome_dock_band_init          (GnomeDockBand *app);
+
+static void     gnome_dock_band_size_request  (GtkWidget *widget,
+                                               GtkRequisition *requisition);
+
+static void     gnome_dock_band_size_allocate (GtkWidget *widget,
+                                               GtkAllocation *allocation);
+
+static void     gnome_dock_band_map           (GtkWidget *widget);
+static void     gnome_dock_band_unmap         (GtkWidget *widget);
+
+static void     gnome_dock_band_add           (GtkContainer *container,
+                                               GtkWidget *child);
+
+static void     gnome_dock_band_remove        (GtkContainer *container,
+                                               GtkWidget *widget);
+
+static void     gnome_dock_band_forall        (GtkContainer *container,
+                                               gboolean include_internals,
+                                               GtkCallback callback,
+                                               gpointer callback_data);
+
+static void     gnome_dock_band_destroy       (GtkObject *object);
+static void     gnome_dock_band_finalize      (GObject *object);
+
+static void     size_allocate_child           (GnomeDockBand *band,
+                                               GnomeDockBandChild *child,
+                                               guint space,
+                                               GtkAllocation *child_allocation);
+
+static void     size_allocate_small           (GnomeDockBand *band,
+                                               GtkAllocation *allocation,
+                                               guint space,
+                                               guint requested_space);
+
+static gboolean docking_allowed               (GnomeDockBand *band,
+                                               GnomeDockItem *item);
+
+static GList   *find_child                    (GnomeDockBand *band,
+                                               GtkWidget *child);
+
+static GList   *prev_if_floating              (GnomeDockBand *band,
+                                               GList *c);
+
+static GList   *next_if_floating              (GnomeDockBand *band,
+                                               GList *c);
+
+static GList   *prev_not_floating             (GnomeDockBand *band,
+                                               GList *c);
+
+static GList   *next_not_floating             (GnomeDockBand *band,
+                                               GList *c);
+
+static void     calc_prev_and_foll_space      (GnomeDockBand *band);
+
+static guint    attempt_move_backward         (GnomeDockBand *band,
+                                               GList *child,
+                                               guint amount);
+
+static guint    attempt_move_forward          (GnomeDockBand *band,
+                                               GList *child,
+                                               guint amount);
+
+static gboolean dock_nonempty                 (GnomeDockBand *band,
+                                               GnomeDockItem *item,
+                                               GList *where,
+                                               gint x, gint y);
+
+static gboolean dock_empty                    (GnomeDockBand *band,
+                                               GnomeDockItem *item,
+                                               GList *where,
+                                               gint x, gint y);
+
+static gboolean dock_empty_right              (GnomeDockBand *band,
+                                               GnomeDockItem *item,
+                                               GList *where,
+                                               gint x, gint y);
+
+static gboolean check_guint_arg               (GObject *object,
+					       const gchar *name,
+					       guint *value_return);
+
+
+static GtkContainerClass *parent_class = NULL;
+
+
+
+static void
+gnome_dock_band_class_init (GnomeDockBandClass *class)
+{
+  GtkObjectClass *object_class;
+  GObjectClass *gobject_class;
+  GtkWidgetClass *widget_class;
+  GtkContainerClass *container_class;
+
+  object_class = (GtkObjectClass *) class;
+  gobject_class = (GObjectClass *) class;
+  widget_class = (GtkWidgetClass *) class;
+  container_class = (GtkContainerClass *) class;
+
+  parent_class = gtk_type_class (gtk_container_get_type ());
+
+  object_class->destroy = gnome_dock_band_destroy;
+  gobject_class->finalize = gnome_dock_band_finalize;
+
+  widget_class->map = gnome_dock_band_map;
+  widget_class->unmap = gnome_dock_band_unmap;
+  widget_class->size_request = gnome_dock_band_size_request;
+  widget_class->size_allocate = gnome_dock_band_size_allocate;
+
+  container_class->add = gnome_dock_band_add;
+  container_class->remove = gnome_dock_band_remove;
+  container_class->forall = gnome_dock_band_forall;
+}
+
+static void
+gnome_dock_band_init (GnomeDockBand *band)
+{
+  GTK_WIDGET_SET_FLAGS (band, GTK_NO_WINDOW);
+
+  band->_priv = NULL;
+  /* XXX: when there is some private stuff enable this
+  band->_priv = g_new0(GnomeDockBandPrivate, 1);
+  */
+
+  band->orientation = GTK_ORIENTATION_HORIZONTAL;
+
+  band->children = NULL;
+  band->num_children = 0;
+
+  band->floating_child = NULL;
+
+  band->doing_drag = FALSE;
+
+  band->max_space_requisition = 0;
+  band->tot_offsets = 0;
+
+  band->drag_allocation.x = band->drag_allocation.y = -1;
+  band->drag_allocation.width = band->drag_allocation.height = 0;
+
+  band->new_for_drag = FALSE;
+}
+
+
+
+static void
+gnome_dock_band_size_request (GtkWidget *widget,
+                              GtkRequisition *requisition)
+{
+  GnomeDockBand *band;
+  GList *lp;
+
+  DEBUG (("entering function"));
+
+  band = GNOME_DOCK_BAND (widget);
+
+  band->max_space_requisition = 0;
+  band->tot_offsets = 0;
+
+  requisition->width = 0;
+  requisition->height = 0;
+
+  for (lp = band->children; lp != NULL; lp = lp->next)
+    {
+      GnomeDockBandChild *c = lp->data;
+
+      if (GTK_WIDGET_VISIBLE (c->widget))
+        {
+          GtkRequisition req;
+
+	  req.width = req.height = 0;
+
+          if (GNOME_IS_DOCK_ITEM (c->widget))
+            gnome_dock_item_handle_size_request(GNOME_DOCK_ITEM (c->widget),
+                                                &req);
+	  else
+	    gtk_widget_size_request (c->widget, &req);
+
+          if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+	    {
+	      gboolean has_preferred_width;
+	      guint preferred_width;
+
+	      has_preferred_width = check_guint_arg (G_OBJECT (c->widget),
+						     "preferred_width",
+						     &preferred_width);
+
+	      if (has_preferred_width)
+		c->max_space_requisition = MAX (preferred_width, req.width);
+	      else
+		c->max_space_requisition = req.width;
+	    }
+          else
+	    {
+	      gboolean has_preferred_height;
+	      guint preferred_height;
+
+	      has_preferred_height = check_guint_arg (G_OBJECT (c->widget),
+						      "preferred_height",
+						      &preferred_height);
+
+	      if (has_preferred_height)
+		c->max_space_requisition = MAX (preferred_height, req.height);
+	      else
+		c->max_space_requisition = req.height;
+	    }
+
+          band->max_space_requisition += c->max_space_requisition;
+
+          if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+            {
+              requisition->height = MAX (requisition->height, req.height);
+              requisition->width += req.width;
+            }
+          else
+            {
+              requisition->width = MAX (requisition->width, req.width);
+              requisition->height += req.height;
+            }
+
+          c->widget->requisition = req;
+          band->tot_offsets += c->offset;
+        }
+    }
+
+  widget->requisition = *requisition;
+}
+
+
+
+static void
+size_allocate_child (GnomeDockBand *band,
+                     GnomeDockBandChild *child,
+                     guint space,
+                     GtkAllocation *child_allocation)
+{
+  GtkWidget *band_widget;
+
+  band_widget = GTK_WIDGET (band);
+  if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+    {
+      child_allocation->x += child->real_offset;
+      child_allocation->width = space;
+      child_allocation->height = band_widget->allocation.height;
+      DEBUG (("horizontal %d %d %d %d real_offset %d",
+              child_allocation->x, child_allocation->y,
+              child_allocation->width, child_allocation->height,
+              child->real_offset));
+      gtk_widget_size_allocate (child->widget, child_allocation);
+      child_allocation->x += child_allocation->width;
+    }
+  else
+    {
+      child_allocation->y += child->real_offset;
+      child_allocation->width = band_widget->allocation.width;
+      child_allocation->height = space;
+      DEBUG (("vertical %d %d %d %d real_offset %d",
+              child_allocation->x, child_allocation->y,
+              child_allocation->width, child_allocation->height,
+              child->real_offset));
+      gtk_widget_size_allocate (child->widget, child_allocation);
+      child_allocation->y += child_allocation->height;
+    }
+}
+
+/* The allocated space is smaller than the space needed to show all
+   the items completely.  */
+static void
+size_allocate_small (GnomeDockBand *band,
+                     GtkAllocation *allocation,
+                     guint space,
+                     guint requested_space)
+{
+  GtkAllocation child_allocation;
+  GList *lp;
+  guint max_space_requisition;
+
+  DEBUG (("entering function"));
+
+  child_allocation.x = allocation->x;
+  child_allocation.y = allocation->y;
+
+  max_space_requisition = band->max_space_requisition;
+
+  for (lp = band->children; lp != NULL; lp = lp->next)
+    {
+      GnomeDockBandChild *child;
+
+      child = lp->data;
+
+      if (GTK_WIDGET_VISIBLE (child->widget))
+        {
+	  guint child_requested_space;
+
+	  child->real_offset = 0;
+
+	  if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+	    child_requested_space = child->widget->requisition.width;
+	  else
+	    child_requested_space = child->widget->requisition.height;
+
+	  if (space < child->max_space_requisition
+	      || (space - child->max_space_requisition
+		  < requested_space - child_requested_space))
+	    break;
+	  
+	  space -= child->max_space_requisition;
+	  requested_space -= child_requested_space;
+	  max_space_requisition -= child->max_space_requisition;
+	  
+	  size_allocate_child (band, child,
+			       child->max_space_requisition,
+			       &child_allocation);
+	}
+    }
+
+  if (lp != NULL)
+    {
+      GnomeDockBandChild *child;
+      guint child_space, child_requested_space;
+
+      child = lp->data;
+
+      if (GTK_WIDGET_VISIBLE (child->widget))
+        {
+	  child->real_offset = 0;
+
+	  if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+	    child_requested_space = child->widget->requisition.width;
+	  else
+	    child_requested_space = child->widget->requisition.height;
+	  
+	  requested_space -= child_requested_space;
+	  child_space = space - requested_space;
+	  space -= child_space;
+	  
+	  size_allocate_child (band, child,
+			       child_space,
+			       &child_allocation);
+	}
+
+      lp = lp->next;
+    }
+
+  for (; lp != NULL; lp = lp->next)
+    {
+      GnomeDockBandChild *child;
+
+      child = lp->data;
+
+      if (GTK_WIDGET_VISIBLE (child->widget))
+        {
+	  child->real_offset = 0;
+	  child->real_offset = 0;
+
+	  if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+	    size_allocate_child (band, child,
+				 child->widget->requisition.width,
+				 &child_allocation);
+	  else
+	    size_allocate_child (band, child,
+				 child->widget->requisition.height,
+				 &child_allocation);
+	}
+    }
+}
+
+/* The allocation is enough to show all the items completely, but not
+   to satisfy all the requested offsets.  */
+static void
+size_allocate_medium (GnomeDockBand *band,
+                      GtkAllocation *allocation,
+                      guint space,
+                      guint requested_space)
+{
+  GtkAllocation child_allocation;
+  GList *lp;
+  gfloat factor;
+
+  DEBUG (("entering function"));
+
+  child_allocation.x = allocation->x;
+  child_allocation.y = allocation->y;
+
+  factor = (1.0 - ((float) (band->max_space_requisition + band->tot_offsets
+                            - space)
+                   / (float) band->tot_offsets));
+
+  /* Shrink the offsets proportionally.  */
+  for (lp = band->children; lp != NULL; lp = lp->next)
+    {
+      GnomeDockBandChild *child;
+
+      child = lp->data;
+
+      if (GTK_WIDGET_VISIBLE (child->widget))
+        {
+	  child->real_offset = (guint) ((float) child->offset * factor + .5);
+	  
+	  size_allocate_child (band, child,
+			       child->max_space_requisition,
+			       &child_allocation);
+	}
+    }
+}
+
+/* The allocation is enough to show all the items completely, with the
+   requested offsets.  */
+static void
+size_allocate_large (GnomeDockBand *band,
+                     GtkAllocation *allocation,
+                     guint space,
+                     guint requested_space)
+{
+  GtkAllocation child_allocation;
+  GList *lp;
+
+  DEBUG (("entering function"));
+
+  child_allocation.x = allocation->x;
+  child_allocation.y = allocation->y;
+
+  for (lp = band->children; lp != NULL; lp = lp->next)
+    {
+      GnomeDockBandChild *child;
+
+      child = lp->data;
+
+      if (GTK_WIDGET_VISIBLE (child->widget))
+        {
+	  child->real_offset = child->offset;
+
+	  size_allocate_child (band, child,
+			       child->max_space_requisition,
+			       &child_allocation);
+	}
+    }
+}
+
+static void
+gnome_dock_band_size_allocate (GtkWidget *widget,
+                               GtkAllocation *allocation)
+{
+  GnomeDockBand *band;
+  guint space, requested_space;
+
+  band = GNOME_DOCK_BAND (widget);
+
+  widget->allocation = *allocation;
+
+  /* Check if we have a single exclusive item.  If so, allocate the
+     whole space to it.  */
+  if (band->num_children == 1)
+    {
+      GnomeDockBandChild *c;
+
+      c = (GnomeDockBandChild *) band->children->data;
+      if (GNOME_IS_DOCK_ITEM (c->widget) && GTK_WIDGET_VISIBLE (c->widget))
+        {
+          GnomeDockItemBehavior behavior;
+          GnomeDockItem *item;
+
+          item = GNOME_DOCK_ITEM (c->widget);
+          behavior = gnome_dock_item_get_behavior (item);
+          if (behavior & GNOME_DOCK_ITEM_BEH_EXCLUSIVE)
+            {
+              gtk_widget_size_allocate (c->widget, allocation);
+              return;
+            }
+        }
+    }
+
+  if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+    {
+      space = allocation->width;
+      requested_space = widget->requisition.width;
+    }
+  else
+    {
+      space = allocation->height;
+      requested_space = widget->requisition.height;
+    }
+
+  if (space <= band->max_space_requisition)
+    size_allocate_small (band, allocation, space, requested_space);
+  else if (space < band->max_space_requisition + band->tot_offsets)
+    size_allocate_medium (band, allocation, space, requested_space);
+  else
+    size_allocate_large (band, allocation, space, requested_space);
+
+  calc_prev_and_foll_space (band);
+}
+
+
+
+static void
+gnome_dock_band_map (GtkWidget *widget)
+{
+  GnomeDockBand *band = GNOME_DOCK_BAND (widget);
+  GList *lp;
+
+  g_return_if_fail(widget != NULL);
+  g_return_if_fail(GNOME_IS_DOCK_BAND(widget));
+
+  if (GTK_WIDGET_CLASS (parent_class)->map != NULL)
+    (* GTK_WIDGET_CLASS (parent_class)->map) (widget);
+
+  for (lp = band->children; lp != NULL; lp = lp->next)
+    {
+      GnomeDockBandChild *c;
+
+      c = lp->data;
+      if (GTK_WIDGET_VISIBLE (c->widget) && ! GTK_WIDGET_MAPPED (c->widget))
+        gtk_widget_map (c->widget);
+    }
+}
+
+static void
+gnome_dock_band_unmap (GtkWidget *widget)
+{
+  GnomeDockBand *band = GNOME_DOCK_BAND (widget);
+  GList *lp;
+
+  g_return_if_fail(widget != NULL);
+  g_return_if_fail(GNOME_IS_DOCK_BAND(widget));
+
+  if (GTK_WIDGET_CLASS (parent_class)->unmap != NULL)
+    (* GTK_WIDGET_CLASS (parent_class)->unmap) (widget);
+
+  for (lp = band->children; lp != NULL; lp = lp->next)
+    {
+      GnomeDockBandChild *c;
+
+      c = lp->data;
+      if (GTK_WIDGET_VISIBLE (c->widget) && GTK_WIDGET_MAPPED (c->widget))
+        gtk_widget_unmap (c->widget);
+    }
+}
+
+
+/* GtkContainer methods.  */
+
+static void
+gnome_dock_band_add (GtkContainer *container, GtkWidget *child)
+{
+  GnomeDockBand *band = GNOME_DOCK_BAND (container);
+
+  g_return_if_fail (gnome_dock_band_prepend (band, child, 0));
+}
+
+static void
+gnome_dock_band_remove (GtkContainer *container, GtkWidget *widget)
+{
+  GnomeDockBand *band;
+  GList *child;
+
+  band = GNOME_DOCK_BAND (container);
+  if (band->num_children == 0)
+    return;
+
+  child = find_child (band, widget);
+  if (child != NULL)
+    {
+      gboolean was_visible;
+
+      if (child == band->floating_child)
+        band->floating_child = NULL;
+
+      was_visible = GTK_WIDGET_VISIBLE (widget);
+      gtk_widget_unparent (widget);
+
+      band->children = g_list_remove_link (band->children, child);
+      g_free (child->data);
+      g_list_free (child);
+
+      if (band->doing_drag)
+        {
+          GList *p;
+
+          for (p = band->children; p != NULL; p = p->next)
+            {
+              GnomeDockBandChild *c;
+
+              c = (GnomeDockBandChild *) p->data;
+              c->offset = c->real_offset = c->drag_offset;
+            }
+        }
+
+      gtk_widget_queue_resize (GTK_WIDGET (band));
+
+      band->num_children--;
+      DEBUG (("now num_children = %d", band->num_children));
+    }
+}
+
+static void
+gnome_dock_band_forall (GtkContainer *container,
+                        gboolean include_internals,
+                        GtkCallback callback,
+                        gpointer callback_data)
+{
+  GnomeDockBand *band;
+  GnomeDockBandChild *child;
+  GList *children;
+
+  band = GNOME_DOCK_BAND (container);
+
+  children = band->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+      (* callback) (child->widget, callback_data);
+    }
+}
+
+static void
+gnome_dock_band_destroy (GtkObject *object)
+{
+  /* remember, destroy can be run multiple times! */
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gnome_dock_band_finalize (GObject *object)
+{
+  GnomeDockBand *self = GNOME_DOCK_BAND (object);
+
+  g_free (self->_priv);
+  self->_priv = NULL;
+
+  if (G_OBJECT_CLASS (parent_class)->finalize)
+    (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+
+/* Utility functions.  */
+
+static gboolean
+docking_allowed (GnomeDockBand *band, GnomeDockItem *item)
+{
+  GnomeDockItemBehavior behavior;
+  GnomeDockBandChild *c;
+
+  if (band->num_children == 0)
+    return TRUE;
+
+  behavior = gnome_dock_item_get_behavior (item);
+
+  if (behavior & GNOME_DOCK_ITEM_BEH_EXCLUSIVE)
+    return FALSE;
+
+  c = (GnomeDockBandChild *) band->children->data;
+  if (GNOME_IS_DOCK_ITEM (c->widget))
+    {
+      behavior = gnome_dock_item_get_behavior (GNOME_DOCK_ITEM (c->widget));
+      if (behavior & GNOME_DOCK_ITEM_BEH_EXCLUSIVE)
+          return c->widget == GTK_WIDGET (item);
+    }
+
+  return TRUE;
+}
+
+static GList *
+find_child (GnomeDockBand *band, GtkWidget *child)
+{
+  GList *children;
+
+  children = band->children;
+
+  while (children != NULL)
+    {
+      GnomeDockBandChild *c;
+
+      c = (GnomeDockBandChild *) children->data;
+      if (c->widget == child)
+        return children;
+
+      children = children->next;
+    }
+
+  return NULL;
+}
+
+static GList *
+next_if_floating (GnomeDockBand *band, GList *c)
+{
+  if (c != NULL && c == band->floating_child)
+    return c->next;
+  else
+    return c;
+}
+
+static GList *
+prev_if_floating (GnomeDockBand *band, GList *c)
+{
+  if (c != NULL && c == band->floating_child)
+    return c->prev;
+  else
+    return c;
+}
+
+static GList *
+next_not_floating (GnomeDockBand *band, GList *c)
+{
+  if (c == NULL)
+    return NULL;
+  else
+    return next_if_floating (band, c->next);
+}
+
+static GList *
+prev_not_floating (GnomeDockBand *band, GList *c)
+{
+  if (c == NULL)
+    return NULL;
+  else
+    return prev_if_floating (band, c->prev);
+}
+
+
+
+static GList *
+find_where (GnomeDockBand *band, gint offset, gboolean *is_empty)
+{
+  guint count;                  /* FIXME: used for debugging only */
+  gint offs;
+  GList *lp;
+
+  if (offset < 0)
+    offset = 0;
+
+  offs = 0;
+  count = 0;                    /* FIXME */
+  for (lp = band->children; lp != NULL; lp = lp->next)
+    {
+      GnomeDockBandChild *child;
+
+      child = lp->data;
+
+      if (lp == band->floating_child)
+        {
+          if (lp->next == NULL)
+            {
+              DEBUG (("empty last %d", count));
+              *is_empty = TRUE;
+
+              return lp == band->floating_child ? lp->prev : lp;
+            }
+          DEBUG (("%d: is floating or dragged.", count++));
+          continue;
+        }
+
+      DEBUG (("%d: Checking for x %d, width %d, offs %d (%d)",
+              count, child->drag_allocation.x,
+              child->drag_allocation.width, offs, offset));
+
+      if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+        {
+          if (offset >= offs && offset <= child->drag_allocation.x)
+            {
+              *is_empty = TRUE;
+              DEBUG (("empty %d (allocation.x %d)",
+                      count, child->drag_allocation.x));
+
+              return prev_if_floating (band, lp->prev);
+            }
+
+          offs = child->drag_allocation.x + child->drag_allocation.width;
+          if (offset > child->drag_allocation.x && offset < offs)
+            {
+              *is_empty = FALSE;
+              DEBUG (("%d", count));
+              return lp->prev;
+            }
+        }
+      else
+        {
+          if (offset >= offs && offset <= child->drag_allocation.y)
+            {
+              *is_empty = TRUE;
+              DEBUG (("empty %d (allocation.y %d)",
+                      count, child->drag_allocation.y));
+
+              return prev_if_floating (band, lp->prev);
+            }
+
+          offs = child->drag_allocation.y + child->drag_allocation.height;
+          if (offset > child->drag_allocation.y && offset < offs)
+            {
+              *is_empty = FALSE;
+              DEBUG (("%d", count));
+              return lp->prev;
+            }
+        }
+
+      if (lp->next == NULL)
+        {
+          DEBUG (("empty last %d", count));
+          *is_empty = TRUE;
+          return lp;
+        }
+
+      count++;                  /* FIXME */
+    }
+
+  DEBUG (("nothing done."));
+
+  /* Make compiler happy.  */
+  *is_empty = TRUE;
+  return lp;
+}
+
+
+
+static void
+calc_prev_and_foll_space (GnomeDockBand *band)
+{
+  GtkWidget *widget;
+  GList *lp;
+
+  if (band->children == NULL)
+    return;
+
+  widget = GTK_WIDGET (band);
+
+  lp = next_if_floating (band, band->children);
+  if (lp != NULL)
+    {
+      GnomeDockBandChild *c;
+      guint prev_space, foll_space;
+
+      prev_space = 0;
+
+      while (1)
+        {
+          GList *next;
+
+          c = lp->data;
+          prev_space += c->real_offset;
+          c->prev_space = prev_space;
+
+          if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+            prev_space += (c->widget->allocation.width
+                           - c->widget->requisition.width);
+          else
+            prev_space += (c->widget->allocation.height
+                           - c->widget->requisition.height);
+
+          next = next_not_floating (band, lp);
+          if (next == NULL)
+            break;
+
+          lp = next;
+        }
+
+      if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+        foll_space = (widget->allocation.x + widget->allocation.width
+                      - (c->widget->allocation.x
+                         + c->widget->requisition.width));
+      else
+        foll_space = (widget->allocation.y + widget->allocation.height
+                      - (c->widget->allocation.y
+                         + c->widget->requisition.height));
+
+      DEBUG(("foll_space %d", foll_space));
+
+      for (; lp != NULL; lp = prev_not_floating (band, lp))
+        {
+          c = lp->data;
+          if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+            foll_space += (c->widget->allocation.width
+                           - c->widget->requisition.width);
+          else
+            foll_space += (c->widget->allocation.height
+                           - c->widget->requisition.height);
+          c->foll_space = foll_space;
+
+          foll_space += c->real_offset;
+
+        }
+    }
+}
+
+
+
+static guint
+attempt_move_backward (GnomeDockBand *band, GList *child, guint amount)
+{
+  GList *lp;
+  guint effective_amount;
+
+  effective_amount = 0;
+
+  for (lp = prev_if_floating (band, child);
+       lp != NULL && amount > 0;
+       lp = prev_not_floating (band, lp))
+    {
+      GnomeDockBandChild *c;
+
+      c = lp->data;
+
+      if (c->drag_offset > amount)
+        {
+          c->real_offset = c->drag_offset - amount;
+          effective_amount += amount;
+          amount = 0;
+        }
+      else
+        {
+          c->real_offset = 0;
+          effective_amount += c->drag_offset;
+          amount -= c->drag_offset;
+        }
+      c->offset = c->real_offset;
+    }
+
+  return effective_amount;
+}
+
+static guint
+attempt_move_forward (GnomeDockBand *band, GList *child, guint requirement)
+{
+  GList *lp;
+  guint effective_amount;
+
+  effective_amount = 0;
+  for (lp = next_if_floating (band, child);
+       lp != NULL && requirement > 0;
+       lp = next_not_floating (band, lp))
+    {
+      GnomeDockBandChild *c;
+
+      c = lp->data;
+
+      DEBUG (("requirement = %d", requirement));
+      if (c->drag_offset > requirement)
+        {
+          c->real_offset = c->drag_offset - requirement;
+          effective_amount += requirement;
+          requirement = 0;
+        }
+      else
+        {
+          c->real_offset = 0;
+          effective_amount += c->drag_offset;
+          requirement -= c->drag_offset;
+        }
+      c->offset = c->real_offset;
+    }
+
+  return effective_amount;
+}
+
+
+
+static void
+reparent_if_needed (GnomeDockBand *band,
+                    GnomeDockItem *item,
+                    gint x, gint y)
+{
+  if (GTK_WIDGET (item)->parent != GTK_WIDGET (band))
+    {
+      gnome_dock_item_attach (item, GTK_WIDGET (band), x, y);
+
+      /* Reparenting causes the new floating child to be the first
+         item on the child list (see the `remove' method).  */
+      band->floating_child = band->children;
+
+      /* Reparenting will remove the grab, so we need to redo it.  */
+      gnome_dock_item_grab_pointer (item);
+    }
+}
+
+static gboolean
+dock_nonempty (GnomeDockBand *band,
+               GnomeDockItem *item,
+               GList *where,
+               gint x, gint y)
+{
+  GnomeDockBandChild *c, *floating_child;
+  GtkOrientation orig_item_orientation;
+  GtkRequisition item_requisition;
+  GList *lp, *next;
+  guint amount;
+  guint requirement;
+
+  DEBUG (("entering function"));
+
+  if (! docking_allowed (band, item))
+    return FALSE;
+
+  if (where == NULL)
+    lp = band->children;
+  else
+    lp = next_not_floating (band, where);
+
+  c = lp->data;
+
+  orig_item_orientation = gnome_dock_item_get_orientation (item);
+  if (orig_item_orientation != band->orientation
+      && ! gnome_dock_item_set_orientation (item, band->orientation))
+    return FALSE;
+
+  gnome_dock_item_handle_size_request (item, &item_requisition);
+  if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+    requirement = item_requisition.width;
+  else
+    requirement = item_requisition.height;
+
+  if (c->drag_prev_space + c->drag_foll_space < requirement)
+    {
+      DEBUG (("not enough space %d %d",
+              c->drag_prev_space + c->drag_foll_space,
+              requirement));
+
+      /* Restore original orientation.  */
+      if (orig_item_orientation != band->orientation)
+        gnome_dock_item_set_orientation (item, orig_item_orientation);
+
+      return FALSE;
+    }
+
+  gtk_widget_size_request (GTK_WIDGET (item), &item_requisition);
+  if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+    requirement = item_requisition.width;
+  else
+    requirement = item_requisition.height;
+
+  if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+    amount = c->drag_allocation.x + c->drag_allocation.width - x;
+  else
+    amount = c->drag_allocation.y + c->drag_allocation.height - y;
+
+  DEBUG (("amount %d requirement %d", amount, requirement));
+  amount = attempt_move_backward (band, lp, amount);
+
+  if (requirement < amount)
+    requirement = 0;
+  else
+    {
+      requirement -= amount;
+      next = next_not_floating (band, lp);
+      if (next != NULL)
+        attempt_move_forward (band, next, requirement);
+    }
+
+  if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+    reparent_if_needed (band, item, x, GTK_WIDGET (band)->allocation.y);
+  else
+    reparent_if_needed (band, item, GTK_WIDGET (band)->allocation.x, y);
+
+  floating_child = band->floating_child->data;
+  floating_child->offset = floating_child->real_offset = 0;
+
+  if (band->floating_child->prev != lp)
+    {
+      DEBUG (("moving"));
+      band->children = g_list_remove_link (band->children,
+                                           band->floating_child);
+      band->floating_child->next = lp->next;
+      if (band->floating_child->next != NULL)
+        band->floating_child->next->prev = band->floating_child;
+      band->floating_child->prev = lp;
+      lp->next = band->floating_child;
+    }
+
+  gtk_widget_queue_resize (floating_child->widget);
+
+  return TRUE;
+}
+
+static gboolean
+dock_empty (GnomeDockBand *band,
+            GnomeDockItem *item,
+            GList *where,
+            gint x, gint y)
+{
+  GnomeDockBandChild *floating_child;
+  GnomeDockBandChild *c1, *c2;
+  GtkOrientation orig_item_orientation;
+  GtkRequisition item_requisition;
+  GList *lp;
+  guint new_offset;
+  GtkWidget *item_widget;
+
+  DEBUG (("entering function"));
+
+  if (! docking_allowed (band, item))
+    return FALSE;
+
+  if (where != NULL)
+    {
+      lp = next_not_floating (band, where);
+
+      if (lp == NULL)
+        /* Extreme right is a special case.  */
+        return dock_empty_right (band, item, where, x, y);
+
+      c1 = where->data;
+    }
+  else
+    {
+      c1 = NULL;
+      lp = next_if_floating (band, band->children);
+
+      if (lp == NULL)
+        {
+          /* Only one floating element.  Easy.  */
+          GnomeDockBandChild *c;
+
+          if (! gnome_dock_item_set_orientation (item, band->orientation))
+            return FALSE;
+
+          if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+            reparent_if_needed (band, item,
+                                x, GTK_WIDGET (band)->allocation.y);
+          else
+            reparent_if_needed (band, item,
+                                GTK_WIDGET (band)->allocation.x, y);
+
+          c = band->floating_child->data;
+
+          if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+            c->real_offset = x - GTK_WIDGET (band)->allocation.x;
+          else
+            c->real_offset = y - GTK_WIDGET (band)->allocation.y;
+          c->offset = c->real_offset;
+
+          DEBUG (("simple case offset %d", c->offset));
+
+          gtk_widget_queue_resize (c->widget);
+
+          return TRUE;
+        }
+    }
+
+  c2 = lp->data;
+
+  item_widget = GTK_WIDGET (item);
+
+  orig_item_orientation = gnome_dock_item_get_orientation (item);
+  if (! gnome_dock_item_set_orientation (item, band->orientation))
+    return FALSE;
+
+  /* Check whether there is enough space for the widget.  */
+  {
+    gint space;
+
+    if (c1 != NULL)
+      space = c1->drag_foll_space;
+    else
+      {
+        space = c2->real_offset + c2->drag_foll_space;
+        if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+          space += c2->widget->allocation.width - c2->widget->requisition.width;
+        else
+          space += c2->widget->allocation.height - c2->widget->requisition.height;
+      }
+
+    gnome_dock_item_handle_size_request (item, &item_requisition);
+    if (space < (band->orientation == GTK_ORIENTATION_HORIZONTAL
+                 ? item_requisition.width
+                 : item_requisition.height))
+      {
+        DEBUG (("not enough space %d", space));
+
+        /* Restore original orientation.  */
+        if (orig_item_orientation != band->orientation)
+          gnome_dock_item_set_orientation (item, orig_item_orientation);
+
+        return FALSE;
+      }
+
+  }
+
+  gtk_widget_size_request (item_widget, &item_requisition);
+
+  if (c1 == NULL)
+    {
+      if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+        new_offset = x - GTK_WIDGET (band)->allocation.x;
+      else
+        new_offset = y - GTK_WIDGET (band)->allocation.y;
+    }
+  else
+    {
+      if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+        new_offset = x - (c1->drag_allocation.x + c1->drag_allocation.width);
+      else
+        new_offset = y - (c1->drag_allocation.y + c1->drag_allocation.height);
+    }
+
+  DEBUG (("new_offset %d", new_offset));
+
+  if (c2->drag_offset >= (new_offset
+                          + (band->orientation == GTK_ORIENTATION_HORIZONTAL
+                             ? item_requisition.width
+                             : item_requisition.height)))
+    {
+      c2->real_offset = (c2->drag_offset
+                         - (new_offset
+                            + (band->orientation == GTK_ORIENTATION_HORIZONTAL
+                               ? item_requisition.width
+                               : item_requisition.height)));
+      c2->offset = c2->real_offset;
+    }
+  else
+    {
+      guint requisition;
+      GList *lp1;
+
+      requisition = new_offset + (band->orientation == GTK_ORIENTATION_HORIZONTAL
+                                  ? item_requisition.width
+                                  : item_requisition.height);
+
+      DEBUG (("Moving forward %d!", requisition));
+
+      for (lp1 = lp; lp1 != NULL && requisition > 0; )
+        {
+          GnomeDockBandChild *tmp = lp1->data;
+          GList *lp1next;
+
+          if (tmp->drag_offset > requisition)
+            {
+              tmp->real_offset = tmp->drag_offset - requisition;
+              requisition = 0;
+            }
+          else
+            {
+              requisition -= tmp->drag_offset;
+              tmp->real_offset = 0;
+            }
+          tmp->offset = tmp->real_offset;
+
+          DEBUG (("Offset %d (drag %d)", tmp->real_offset, tmp->drag_offset));
+          lp1next = next_not_floating (band, lp1);
+          if (lp1next == NULL)
+            {
+              if (tmp->drag_foll_space > requisition)
+                requisition = 0;
+              else
+                requisition -= tmp->drag_foll_space;
+            }
+
+          lp1 = lp1next;
+        }
+
+      if (requisition > 0)
+        new_offset -= requisition;
+    }
+
+  if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+    reparent_if_needed (band, item, x, GTK_WIDGET (band)->allocation.y);
+  else
+    reparent_if_needed (band, item, GTK_WIDGET (band)->allocation.x, y);
+
+  floating_child = (GnomeDockBandChild *) band->floating_child->data;
+  floating_child->real_offset = floating_child->offset = new_offset;
+
+  band->children = g_list_remove_link (band->children, band->floating_child);
+
+  if (where == NULL)
+    {
+      band->floating_child->next = band->children;
+      band->children->prev = band->floating_child;
+      band->children = band->floating_child;
+    }
+  else
+    {
+      band->floating_child->next = where->next;
+      band->floating_child->prev = where;
+      if (where->next != NULL)
+        where->next->prev = band->floating_child;
+      where->next = band->floating_child;
+    }
+
+  gtk_widget_queue_resize (((GnomeDockBandChild *) band->floating_child->data)->widget);
+
+  return TRUE;
+}
+
+static gboolean
+dock_empty_right (GnomeDockBand *band,
+                  GnomeDockItem *item,
+                  GList *where,
+                  gint x, gint y)
+{
+  GnomeDockBandChild *c, *floating_child;
+  GtkOrientation orig_item_orientation;
+  GtkRequisition item_requisition;
+  GtkWidget *item_widget;
+  gint new_offset;
+
+  g_return_val_if_fail (next_not_floating (band, where) == NULL, FALSE);
+  g_return_val_if_fail (band->floating_child != where, FALSE);
+
+  DEBUG (("entering function"));
+
+  if (! docking_allowed (band, item))
+    return FALSE;
+
+  item_widget = GTK_WIDGET (item);
+
+  c = where->data;
+
+  orig_item_orientation = gnome_dock_item_get_orientation (item);
+  if (orig_item_orientation != band->orientation
+      && ! gnome_dock_item_set_orientation (item, band->orientation))
+    return FALSE;
+
+  gnome_dock_item_handle_size_request (item, &item_requisition);
+  if (c->drag_prev_space + c->drag_foll_space
+      < (guint) (band->orientation == GTK_ORIENTATION_HORIZONTAL
+                 ? item_requisition.width
+                 : item_requisition.height))
+    {
+      DEBUG (("not enough space %d ", c->drag_prev_space+ c->drag_foll_space));
+
+      /* Restore original orientation.  */
+      if (orig_item_orientation != band->orientation)
+        gnome_dock_item_set_orientation (item, orig_item_orientation);
+
+      return FALSE;
+    }
+
+  gtk_widget_size_request (item_widget, &item_requisition);
+
+  if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+    new_offset = x - (c->widget->allocation.x + c->widget->allocation.width);
+  else
+    new_offset = y - (c->widget->allocation.y + c->widget->allocation.height);
+
+  DEBUG (("x %d y %d new_offset %d width %d foll_space %d",
+          x, y, new_offset, item_widget->allocation.width,
+          c->drag_foll_space));
+
+  if ((guint) (new_offset
+               + (band->orientation == GTK_ORIENTATION_HORIZONTAL
+                  ? item_requisition.width
+                  : item_requisition.height)) > c->drag_foll_space)
+    {
+      gint excess = (new_offset
+                     + (band->orientation == GTK_ORIENTATION_HORIZONTAL
+                        ? item_requisition.width
+                        : item_requisition.height)
+                     - c->drag_foll_space);
+
+      DEBUG (("excess %d new_offset %d", excess, new_offset));
+      if (excess < new_offset)
+        new_offset -= excess;
+      else
+        {
+          attempt_move_backward (band, where, excess - new_offset);
+          new_offset = 0;
+        }
+    }
+
+  if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+    reparent_if_needed (band, item,
+                        x, GTK_WIDGET (band)->allocation.y);
+  else
+    reparent_if_needed (band, item,
+                        GTK_WIDGET (band)->allocation.x, y);
+
+  floating_child = band->floating_child->data;
+  floating_child->offset = floating_child->real_offset = new_offset;
+
+  band->children = g_list_remove_link (band->children, band->floating_child);
+  where->next = band->floating_child;
+  band->floating_child->prev = where;
+
+  gtk_widget_queue_resize (floating_child->widget);
+
+  return TRUE;
+}
+
+/* Helper function.  */
+
+static gboolean
+check_guint_arg (GObject *object,
+		 const gchar *name,
+		 guint *value_return)
+{
+  GParamSpec *pspec;
+
+  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), name);
+  if (pspec != NULL) {
+    GValue value = { 0, };
+
+    g_value_init (&value, G_TYPE_UINT);
+    g_object_get_property (G_OBJECT (object), name, &value);
+    *value_return = g_value_get_uint (&value);
+    g_value_unset (&value);
+
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+
+
+/* Exported interface.  */
+
+/**
+ * gnome_dock_band_new:
+ *
+ * Description: Create a new GnomeDockBand widget.
+ *
+ * Returns: The new GnomeDockBand widget.
+ **/
+GtkWidget *
+gnome_dock_band_new (void)
+{
+  GnomeDockBand *band;
+  GtkWidget *widget;
+
+  band = gtk_type_new (gnome_dock_band_get_type ());
+  widget = GTK_WIDGET (band);
+
+  if (GTK_WIDGET_VISIBLE (widget))
+    gtk_widget_queue_resize (widget);
+
+  return widget;
+}
+
+GtkType
+gnome_dock_band_get_type (void)
+{
+  static GtkType band_type = 0;
+
+  if (band_type == 0)
+    {
+      GtkTypeInfo band_info =
+      {
+	"GnomeDockBand",
+	sizeof (GnomeDockBand),
+	sizeof (GnomeDockBandClass),
+	(GtkClassInitFunc) gnome_dock_band_class_init,
+	(GtkObjectInitFunc) gnome_dock_band_init,
+        /* reserved_1 */ NULL,
+	/* reserved_2 */ NULL,
+	(GtkClassInitFunc) NULL,
+      };
+
+      band_type = gtk_type_unique (gtk_container_get_type (), &band_info);
+    }
+
+  return band_type;
+}
+
+/**
+ * gnome_dock_band_set_orientation:
+ * @band: A GnomeDockBand widget
+ * @orientation: New orientation for @band
+ *
+ * Description: Set the orientation for @band.
+ **/
+void
+gnome_dock_band_set_orientation (GnomeDockBand *band,
+                                 GtkOrientation orientation)
+{
+  g_return_if_fail (orientation == GTK_ORIENTATION_HORIZONTAL
+                    || orientation == GTK_ORIENTATION_VERTICAL);
+
+  band->orientation = orientation;
+}
+
+/**
+ * gnome_dock_band_get_orientation:
+ * @band: A GnomeDockBand widget
+ *
+ * Description: Retrieve the orientation of the specified @band.
+ *
+ * Returns: The orientation of @band.
+ **/
+GtkOrientation
+gnome_dock_band_get_orientation (GnomeDockBand *band)
+{
+  return band->orientation;
+}
+
+/**
+ * gnome_dock_band_insert:
+ * @band: A GnomeDockBand widget
+ * @child: The widget to be added to @band
+ * @offset: Offset from the previous item
+ * @position: Position within the @band
+ *
+ * Description: Add @child to @band at the specified @position, with
+ * the specified @offset from the previous item (or from the beginning
+ * of the band, if this is the first item).
+ *
+ * Returns: %TRUE if successful, %FALSE if the operation fails.
+ **/
+gboolean
+gnome_dock_band_insert (GnomeDockBand *band,
+                        GtkWidget *child,
+                        guint offset,
+                        gint position)
+{
+  GnomeDockBandChild *band_child;
+
+  DEBUG (("%08x", (unsigned int) band));
+
+  if (GNOME_IS_DOCK_ITEM (child)
+      && !docking_allowed (band, GNOME_DOCK_ITEM (child)))
+    return FALSE;
+
+  if (position < 0 || position > (gint) band->num_children)
+    position = band->num_children;
+
+  band_child = g_new (GnomeDockBandChild, 1);
+  band_child->widget = child;
+  band_child->offset = offset;
+  band_child->real_offset = 0;
+
+  if (position == 0)
+    band->children = g_list_prepend (band->children, band_child);
+  else if ((guint) position == band->num_children)
+    band->children = g_list_append (band->children, band_child);
+  else
+    {
+      GList *p;
+
+      p = g_list_nth (band->children, position);
+      g_list_prepend (p, band_child);
+    }
+
+  if (GNOME_IS_DOCK_ITEM (child)
+      && ! gnome_dock_item_set_orientation (GNOME_DOCK_ITEM (child),
+                                            band->orientation))
+      return FALSE;
+
+  gtk_widget_set_parent (child, GTK_WIDGET (band));
+
+  if (GTK_WIDGET_REALIZED (child->parent))
+    gtk_widget_realize (child);
+
+  if (GTK_WIDGET_VISIBLE (child->parent) && GTK_WIDGET_VISIBLE (child))
+    {
+      if (GTK_WIDGET_MAPPED (child->parent))
+	gtk_widget_map (child);
+
+      gtk_widget_queue_resize (child);
+    }
+
+  band->num_children++;
+  DEBUG (("now num_children = %d", band->num_children));
+
+  return TRUE;
+}
+
+void
+gnome_dock_band_move_child (GnomeDockBand *band,
+                            GList *old_child,
+                            guint new_num)
+{
+  GList *children;
+  GList *lp;
+
+  children = band->children;
+
+  lp = old_child;
+
+  children = g_list_remove_link (children, lp);
+
+  children = g_list_insert (children, lp->data, new_num);
+
+  g_list_free (lp);
+
+  band->children = children;
+
+  /* FIXME */
+  gtk_widget_queue_resize (GTK_WIDGET (band));
+}
+
+/**
+ * gnome_dock_band_prepend:
+ * @band: A GnomeDockBand widget
+ * @child: A widget to be added to @band
+ * @offset: Offset (in pixels) from the beginning of the band
+ *
+ * Description: Add @child to @band with the specified @offset as the
+ * first element.
+ *
+ * Returns: %TRUE if successful, %FALSE if the operation fails.
+ **/
+gboolean
+gnome_dock_band_prepend (GnomeDockBand *band,
+                         GtkWidget *child,
+                         guint offset)
+{
+  return gnome_dock_band_insert (band, child, offset, 0);
+}
+
+/**
+ * gnome_dock_band_append:
+ * @band: A GnomeDockBand widget
+ * @child: A widget to be added to @band
+ * @offset: Offset (in pixels) from the last item of the band
+ *
+ * Description: Add @child to @band with the specified @offset as the
+ * last element.
+ *
+ * Returns: %TRUE if successful, %FALSE if the operation fails.
+ **/
+gboolean
+gnome_dock_band_append (GnomeDockBand *band,
+                        GtkWidget *child,
+                        guint offset)
+{
+  return gnome_dock_band_insert (band, child, offset, -1);
+}
+
+/**
+ * gnome_dock_band_set_child_offset:
+ * @band: A GnomeDockBand widget
+ * @child: Child of @band whose offset must be changed
+ * @offset: New offset value for @child
+ *
+ * Description: Set the offset for the specified @child of @band.
+ **/
+void
+gnome_dock_band_set_child_offset (GnomeDockBand *band,
+                                  GtkWidget *child,
+                                  guint offset)
+{
+  GList *p;
+
+  p = find_child (band, child);
+  if (p != NULL)
+    {
+      GnomeDockBandChild *c;
+
+      c = (GnomeDockBandChild *) p->data;
+      c->offset = offset;
+      gtk_widget_queue_resize (c->widget);
+    }
+}
+
+/**
+ * gnome_dock_band_get_child_offset:
+ * @band: A GnomeDockBand widget
+ * @child: Child of @band whose offset must be retrieved
+ *
+ * Description: Retrieve the offset of @child in @band.
+ *
+ * Returns: The offset of @child.
+ **/
+guint
+gnome_dock_band_get_child_offset (GnomeDockBand *band,
+                                  GtkWidget *child)
+{
+  GList *p;
+
+  p = find_child (band, child);
+  if (p != NULL)
+    {
+      GnomeDockBandChild *c;
+
+      c = (GnomeDockBandChild *) p->data;
+      return c->offset;
+    }
+
+  return 0;
+}
+
+/**
+ * gnome_dock_band_get_num_children:
+ * @band: A GnomeDockBand widget
+ *
+ * Description: Retrieve the number of children in @band.
+ *
+ * Returns: The number of children in @band.
+ **/
+guint
+gnome_dock_band_get_num_children (GnomeDockBand *band)
+{
+  return band->num_children;
+}
+
+
+
+/* Private interface.  */
+
+void
+gnome_dock_band_drag_begin (GnomeDockBand *band, GnomeDockItem *item)
+{
+  GList *lp;
+  GtkWidget *floating_widget;
+  GtkWidget *item_widget;
+  guint extra_offset = 0;
+
+  DEBUG (("entering function"));
+
+  item_widget = GTK_WIDGET (item);
+  floating_widget = NULL;
+
+  for (lp = band->children; lp != NULL;)
+    {
+      GnomeDockBandChild *c;
+
+      c = lp->data;
+
+      c->drag_allocation = c->widget->allocation;
+      c->drag_offset = c->real_offset + extra_offset;
+      c->drag_prev_space = c->prev_space;
+      c->drag_foll_space = c->foll_space;
+
+      c->offset = c->real_offset;
+
+      if (c->widget == item_widget)
+        {
+          band->floating_child = lp;
+          floating_widget = item_widget;
+          if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+            extra_offset = c->widget->allocation.width + c->real_offset;
+          else
+            extra_offset = c->widget->allocation.height + c->real_offset;
+        }
+      else
+        extra_offset = 0;
+
+      if (lp->next == NULL)
+        break;
+
+      lp = lp->next;
+    }
+
+  if (floating_widget != NULL)
+    {
+      for (lp = band->floating_child->prev; lp != NULL; lp = lp->prev)
+        {
+          GnomeDockBandChild *c;
+
+          c = lp->data;
+          if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+            c->drag_foll_space += item_widget->requisition.width;
+          else
+            c->drag_foll_space += item_widget->requisition.height;
+        }
+      for (lp = band->floating_child->next; lp != NULL; lp = lp->next)
+        {
+          GnomeDockBandChild *c;
+
+          c = lp->data;
+          if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+            c->drag_prev_space += item_widget->requisition.width;
+          else
+            c->drag_prev_space += item_widget->requisition.height;
+        }
+    }
+
+  band->doing_drag = TRUE;
+  band->drag_allocation = GTK_WIDGET (band)->allocation;
+}
+
+gboolean
+gnome_dock_band_drag_to (GnomeDockBand *band,
+                         GnomeDockItem *item,
+                         gint x, gint y)
+{
+  GtkAllocation *allocation;
+  GList *where;
+  gboolean is_empty;
+
+  g_return_val_if_fail (band->doing_drag, FALSE);
+
+  DEBUG (("%d %d", x, y));
+
+  allocation = & GTK_WIDGET (band)->allocation;
+
+  if (band->orientation == GTK_ORIENTATION_HORIZONTAL)
+    {
+      if (x < allocation->x)
+        x = allocation->x;
+      if (x >= allocation->x + allocation->width)
+        x = allocation->x + allocation->width - 1;
+      where = find_where (band, x, &is_empty);
+    }
+  else
+    {
+      if (y < allocation->y)
+        y = allocation->y;
+      if (y >= allocation->y + allocation->height)
+        y = allocation->y + allocation->height - 1;
+      where = find_where (band, y, &is_empty);
+    }
+
+  {
+    GList *p;
+
+    for (p = next_if_floating (band, band->children);
+         p != NULL;
+         p = next_not_floating (band, p))
+      {
+        GnomeDockBandChild *c = p->data;
+
+        c->real_offset = c->offset = c->drag_offset;
+      }
+  }
+
+  if (is_empty)
+    return dock_empty (band, item, where, x, y);
+  else
+    return dock_nonempty (band, item, where, x, y);
+}
+
+void
+gnome_dock_band_drag_end (GnomeDockBand *band, GnomeDockItem *item)
+{
+  g_return_if_fail (band->doing_drag);
+
+  DEBUG (("entering function"));
+
+  if (band->floating_child != NULL)
+    {
+      GnomeDockBandChild *f;
+
+      /* Minimal sanity check.  */
+      f = (GnomeDockBandChild *) band->floating_child->data;
+      g_return_if_fail (f->widget == GTK_WIDGET (item));
+
+      gtk_widget_queue_resize (f->widget);
+      band->floating_child = NULL;
+    }
+
+  band->doing_drag = FALSE;
+  band->new_for_drag = FALSE;
+}
+
+
+
+/**
+ * gnome_dock_band_get_item_by_name:
+ * @band: A GnomeDockBand widget
+ * @name: Name of the child to be retrieved
+ * @position_return: Pointer to a variable holding the position of
+ * the named child
+ * @offset_return:  Pointer to a variable holding the offset of the
+ * named child
+ *
+ * Description: Retrieve a named item from @band, and return its
+ * position and offset in * position_return and @offset_return.
+ *
+ * Return value: The child whose name is @name, or %NULL if no child
+ * of @band has such name.
+ **/
+GnomeDockItem *
+gnome_dock_band_get_item_by_name (GnomeDockBand *band,
+                                  const char *name,
+                                  guint *position_return,
+                                  guint *offset_return)
+{
+  guint pos;
+  GList *lp;
+
+  for (lp = band->children, pos = 0; lp != NULL; lp = lp->next, pos++)
+    {
+      GnomeDockBandChild *c;
+
+      c = lp->data;
+      if (GNOME_IS_DOCK_ITEM (c->widget))
+        {
+          GnomeDockItem *item;
+
+          item = GNOME_DOCK_ITEM (c->widget);
+          if (strcmp (item->name, name) == 0)
+            {
+              if (position_return != NULL)
+                *position_return = pos;
+              if (offset_return != NULL)
+                *offset_return = c->offset;
+              return item;
+            }
+        }
+    }
+
+  return NULL;
+}
+
+
+
+void
+gnome_dock_band_layout_add (GnomeDockBand *band,
+                            GnomeDockLayout *layout,
+                            GnomeDockPlacement placement,
+                            guint band_num)
+{
+  guint child_num;
+  GList *lp;
+
+  for (lp = band->children, child_num = 0;
+       lp != NULL;
+       lp = lp->next, child_num++)
+    {
+      GnomeDockBandChild *child;
+      GtkWidget *item;
+
+      child = lp->data;
+      item = child->widget;
+
+      if (GNOME_IS_DOCK_ITEM (item))
+        gnome_dock_layout_add_item (layout,
+                                    GNOME_DOCK_ITEM (item),
+                                    placement, band_num,
+                                    child_num, child->offset);
+    }
+}
diff --git a/libgnomeui/gnome-dock-band.h b/libgnomeui/gnome-dock-band.h
new file mode 100644
index 0000000..f08a0f3
--- /dev/null
+++ b/libgnomeui/gnome-dock-band.h
@@ -0,0 +1,162 @@
+/*
+ * !!! MASTER CAUTION !!!!
+ *
+ * These files have been moved to libbonoboui and renamed to bonobo-dock*.[ch].
+ * We'll provide a compatibility wrapper with #defines in libgnomecompat soon, but
+ * at the moment I don't want to break the build here since libbonoboui doesn't work yet.
+ *
+ * If you do any changes in these files here, your work will be lost !
+ */
+
+/* WARNING ____ IMMATURE API ____ liable to change */
+
+/* gnome-dock-band.h
+
+   Copyright (C) 1998 Free Software Foundation
+   All rights reserved.
+
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Ettore Perazzoli <ettore comm2000 it>
+*/
+/*
+  @NOTATION@
+*/
+
+#ifndef _GNOME_DOCK_BAND_H
+#define _GNOME_DOCK_BAND_H
+
+
+
+G_BEGIN_DECLS
+
+#define GNOME_TYPE_DOCK_BAND            (gnome_dock_band_get_type ())
+#define GNOME_DOCK_BAND(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_DOCK_BAND, GnomeDockBand))
+#define GNOME_DOCK_BAND_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_DOCK_BAND, GnomeDockBandClass))
+#define GNOME_IS_DOCK_BAND(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_DOCK_BAND))
+#define GNOME_IS_DOCK_BAND_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_DOCK_BAND))
+#define GNOME_DOCK_BAND_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_DOCK_BAND, GnomeDockBandClass))
+
+typedef struct _GnomeDockBand GnomeDockBand;
+typedef struct _GnomeDockBandPrivate GnomeDockBandPrivate;
+typedef struct _GnomeDockBandClass GnomeDockBandClass;
+typedef struct _GnomeDockBandChild GnomeDockBandChild;
+
+#include "gnome-dock.h"
+#include "gnome-dock-item.h"
+#include "gnome-dock-layout.h"
+
+struct _GnomeDockBand
+{
+  GtkContainer container;
+
+  GList *children;              /* GnomeDockBandChild */
+
+  GList *floating_child;        /* GnomeDockBandChild */
+
+  /* This used to remember the allocation before the drag begin: it is
+     necessary to do so because we actually decide what docking action
+     happens depending on it, instead of using the current allocation
+     (which might be constantly changing while the user drags things
+     around).  */
+  GtkAllocation drag_allocation;
+
+  guint tot_offsets;
+
+  guint max_space_requisition : 16;
+  guint num_children : 8;
+  guint new_for_drag : 1;
+  gboolean doing_drag : 1;
+  GtkOrientation orientation : 1;
+
+  /*< private >*/
+  GnomeDockBandPrivate *_priv;
+};
+
+struct _GnomeDockBandClass
+{
+  GtkContainerClass parent_class;
+};
+
+struct _GnomeDockBandChild
+{
+  GtkWidget *widget;
+
+  GtkAllocation drag_allocation;
+
+  /* Maximum (requested) offset from the previous child.  */
+  guint16 offset;
+
+  /* Actual offset.  */
+  guint16 real_offset;
+
+  guint16 drag_offset;
+
+  guint16 prev_space, foll_space;
+  guint16 drag_prev_space, drag_foll_space;
+
+  guint16 max_space_requisition;
+};
+
+GtkWidget     *gnome_dock_band_new              (void);
+guint          gnome_dock_band_get_type         (void) G_GNUC_CONST;
+   
+void           gnome_dock_band_set_orientation  (GnomeDockBand *band,
+                                                 GtkOrientation orientation);
+GtkOrientation gnome_dock_band_get_orientation  (GnomeDockBand *band);
+   
+gboolean       gnome_dock_band_insert           (GnomeDockBand *band,
+                                                 GtkWidget *child,
+                                                 guint offset,
+                                                 gint position);
+gboolean       gnome_dock_band_prepend          (GnomeDockBand *band,
+                                                 GtkWidget *child,
+                                                 guint offset);
+gboolean       gnome_dock_band_append           (GnomeDockBand *band,
+                                                 GtkWidget *child,
+                                                 guint offset);
+    
+void           gnome_dock_band_set_child_offset (GnomeDockBand *band,
+                                                 GtkWidget *child,
+                                                 guint offset);
+guint          gnome_dock_band_get_child_offset (GnomeDockBand *band,
+                                                 GtkWidget *child); 
+void           gnome_dock_band_move_child       (GnomeDockBand *band,
+                                                 GList *old_child,
+                                                 guint new_num);
+   
+guint          gnome_dock_band_get_num_children (GnomeDockBand *band);
+    
+void           gnome_dock_band_drag_begin       (GnomeDockBand *band,
+                                                 GnomeDockItem *item);
+gboolean       gnome_dock_band_drag_to          (GnomeDockBand *band,
+                                                 GnomeDockItem *item,
+                                                 gint x, gint y);
+void           gnome_dock_band_drag_end         (GnomeDockBand *band,
+                                                 GnomeDockItem *item);
+   
+GnomeDockItem *gnome_dock_band_get_item_by_name (GnomeDockBand *band,
+                                                 const char *name,
+                                                 guint *position_return,
+                                                 guint *offset_return);
+
+void           gnome_dock_band_layout_add       (GnomeDockBand *band,
+                                                 GnomeDockLayout *layout,
+                                                 GnomeDockPlacement placement,
+                                                 guint band_num);
+G_END_DECLS
+
+#endif
diff --git a/libgnomeui/gnome-dock-item.c b/libgnomeui/gnome-dock-item.c
new file mode 100644
index 0000000..aa68c7e
--- /dev/null
+++ b/libgnomeui/gnome-dock-item.c
@@ -0,0 +1,1420 @@
+/*
+ * !!! MASTER CAUTION !!!!
+ *
+ * These files have been moved to libbonoboui and renamed to bonobo-dock*.[ch].
+ * We'll provide a compatibility wrapper with #defines in libgnomecompat soon, but
+ * at the moment I don't want to break the build here since libbonoboui doesn't work yet.
+ *
+ * If you do any changes in these files here, your work will be lost !
+ */
+
+/* gnome-dock-item.c
+ *
+ * Copyright (C) 1998 Ettore Perazzoli
+ * Copyright (C) 1998 Elliot Lee
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald 
+ * All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#include <gdk/gdkx.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtksignal.h>
+#include <gtk/gtktoolbar.h>
+#include <gtk/gtkwindow.h>
+
+#include "gnome-dock-item.h"
+#include <libgnome/gnome-i18n.h>
+
+struct _GnomeDockItemPrivate
+{
+	int dummy;
+	/* Nothing right now, needs to get filled with the private things */
+	/* XXX: When stuff is added, uncomment the allocation in the
+	 * gnome_dock_item_init function! */
+};
+
+
+enum {
+  PROP_0,
+  PROP_SHADOW,
+  PROP_ORIENTATION,
+  PROP_PREFERRED_WIDTH,
+  PROP_PREFERRED_HEIGHT
+};
+
+#define DRAG_HANDLE_SIZE 10
+
+enum {
+  DOCK_DRAG_BEGIN,
+  DOCK_DRAG_END,
+  DOCK_DRAG_MOTION,
+  DOCK_DETACH,
+  ORIENTATION_CHANGED,
+  LAST_SIGNAL
+};
+
+
+static guint     get_preferred_width   (GnomeDockItem *item);
+static guint     get_preferred_height  (GnomeDockItem *item);
+
+static void gnome_dock_item_class_init     (GnomeDockItemClass *klass);
+static void gnome_dock_item_init           (GnomeDockItem      *dock_item);
+static void gnome_dock_item_set_property   (GObject            *object,
+					    guint               param_id,
+					    const GValue       *value,
+					    GParamSpec         *pspec);
+static void gnome_dock_item_get_property   (GObject            *object,
+					    guint               param_id,
+					    GValue             *value,
+					    GParamSpec         *pspec);
+static void gnome_dock_item_destroy        (GtkObject         *object);
+static void gnome_dock_item_finalize       (GObject           *object);
+static void gnome_dock_item_map            (GtkWidget         *widget);
+static void gnome_dock_item_unmap          (GtkWidget         *widget);
+static void gnome_dock_item_realize        (GtkWidget         *widget);
+static void gnome_dock_item_unrealize      (GtkWidget         *widget);
+static void gnome_dock_item_style_set      (GtkWidget         *widget,
+                                            GtkStyle          *previous_style);
+static void gnome_dock_item_size_request   (GtkWidget         *widget,
+                                            GtkRequisition    *requisition);
+static void gnome_dock_item_size_allocate  (GtkWidget         *widget,
+                                            GtkAllocation     *real_allocation);
+static void gnome_dock_item_add            (GtkContainer      *container,
+                                            GtkWidget         *widget);
+static void gnome_dock_item_remove         (GtkContainer      *container,
+                                            GtkWidget         *widget);
+static void gnome_dock_item_paint          (GtkWidget         *widget,
+                                            GdkEventExpose    *event);
+static gint gnome_dock_item_expose         (GtkWidget         *widget,
+                                            GdkEventExpose    *event);
+static gint gnome_dock_item_button_changed (GtkWidget         *widget,
+                                            GdkEventButton    *event);
+static gint gnome_dock_item_motion         (GtkWidget         *widget,
+                                            GdkEventMotion    *event);
+static gint gnome_dock_item_delete_event   (GtkWidget         *widget,
+                                            GdkEventAny       *event);
+
+
+static GtkBinClass *parent_class;
+static guint        dock_item_signals[LAST_SIGNAL] = { 0 };
+
+
+/* Helper functions.  */
+
+static gboolean
+check_guint_arg (GObject *object,
+		 const gchar *name,
+		 guint *value_return)
+{
+  GParamSpec *pspec;
+
+  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), name);
+  if (pspec != NULL) {
+    GValue value = { 0, };
+
+    g_value_init (&value, G_TYPE_UINT);
+    g_object_get_property (G_OBJECT (object), name, &value);
+    *value_return = g_value_get_uint (&value);
+    g_value_unset (&value);
+
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+static guint
+get_preferred_width (GnomeDockItem *dock_item)
+{
+  GtkWidget *child;
+  guint preferred_width;
+
+  child = GTK_BIN (dock_item)->child;
+
+  if (! check_guint_arg (G_OBJECT (child), "preferred_width", &preferred_width))
+    {
+      GtkRequisition child_requisition;
+  
+      gtk_widget_get_child_requisition (child, &child_requisition);
+      preferred_width = child_requisition.width;
+    }
+
+  if (dock_item->orientation == GTK_ORIENTATION_HORIZONTAL)
+    preferred_width += GNOME_DOCK_ITEM_NOT_LOCKED (dock_item) ? DRAG_HANDLE_SIZE : 0;
+
+  preferred_width += GTK_CONTAINER (dock_item)->border_width * 2;
+
+  return preferred_width;
+}
+
+static guint
+get_preferred_height (GnomeDockItem *dock_item)
+{
+  GtkWidget *child;
+  guint preferred_height;
+
+  child = GTK_BIN (dock_item)->child;
+
+  if (! check_guint_arg (G_OBJECT (child), "preferred_height", &preferred_height))
+    {
+      GtkRequisition child_requisition;
+  
+      gtk_widget_get_child_requisition (child, &child_requisition);
+      preferred_height = child_requisition.height;
+    }
+
+  if (dock_item->orientation == GTK_ORIENTATION_VERTICAL)
+    preferred_height += GNOME_DOCK_ITEM_NOT_LOCKED (dock_item) ? DRAG_HANDLE_SIZE : 0;
+
+  preferred_height += GTK_CONTAINER (dock_item)->border_width * 2;
+
+  return preferred_height;
+}
+
+
+guint
+gnome_dock_item_get_type (void)
+{
+  static guint dock_item_type = 0;
+
+  if (!dock_item_type)
+    {
+      GtkTypeInfo dock_item_info =
+      {
+	"GnomeDockItem",
+	sizeof (GnomeDockItem),
+	sizeof (GnomeDockItemClass),
+	(GtkClassInitFunc) gnome_dock_item_class_init,
+	(GtkObjectInitFunc) gnome_dock_item_init,
+	/* reserved_1 */ NULL,
+        /* reserved_2 */ NULL,
+        (GtkClassInitFunc) NULL,
+      };
+
+      dock_item_type = gtk_type_unique (gtk_bin_get_type (), &dock_item_info);
+    }
+
+  return dock_item_type;
+}
+
+static void
+gnome_dock_item_class_init (GnomeDockItemClass *class)
+{
+  GtkObjectClass *object_class;
+  GObjectClass *gobject_class;
+  GtkWidgetClass *widget_class;
+  GtkContainerClass *container_class;
+
+  object_class = (GtkObjectClass *) class;
+  gobject_class = (GObjectClass *) class;
+  widget_class = (GtkWidgetClass *) class;
+  container_class = (GtkContainerClass *) class;
+
+  parent_class = gtk_type_class (gtk_bin_get_type ());
+
+  gobject_class->set_property = gnome_dock_item_set_property;
+  gobject_class->get_property = gnome_dock_item_get_property;
+  
+  g_object_class_install_property (gobject_class,
+				   PROP_SHADOW,
+				   g_param_spec_enum ("shadow",
+						      _("Shadow type"),
+						      _("Shadow type"),
+						      GTK_TYPE_SHADOW_TYPE,
+						      GTK_SHADOW_OUT,
+						      (G_PARAM_READABLE |
+						       G_PARAM_WRITABLE)));
+  g_object_class_install_property (gobject_class,
+				   PROP_ORIENTATION,
+				   g_param_spec_enum ("orientation",
+						      _("Orientation"),
+						      _("Orientation"),
+						      GTK_TYPE_ORIENTATION,
+						      GTK_ORIENTATION_HORIZONTAL,
+						      (G_PARAM_READABLE |
+						       G_PARAM_WRITABLE)));
+  g_object_class_install_property (gobject_class,
+				   PROP_PREFERRED_WIDTH,
+				   g_param_spec_uint ("preferred_width",
+						      _("Preferred width"),
+						      _("Preferred width"),
+						      0, G_MAXINT, 0,
+						      (G_PARAM_READABLE |
+						       G_PARAM_WRITABLE)));
+  g_object_class_install_property (gobject_class,
+				   PROP_PREFERRED_HEIGHT,
+				   g_param_spec_uint ("preferred_height",
+						      _("Preferred height"),
+						      _("Preferred height"),
+						      0, G_MAXINT, 0,
+						      (G_PARAM_READABLE |
+						       G_PARAM_WRITABLE)));
+
+  dock_item_signals[DOCK_DRAG_BEGIN] =
+    gtk_signal_new ("dock_drag_begin",
+                    GTK_RUN_LAST,
+		    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (GnomeDockItemClass, dock_drag_begin),
+                    gtk_marshal_NONE__NONE,
+                    GTK_TYPE_NONE, 0);
+
+  dock_item_signals[DOCK_DRAG_MOTION] =
+    gtk_signal_new ("dock_drag_motion",
+                    GTK_RUN_LAST,
+		    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (GnomeDockItemClass, dock_drag_motion),
+                    gtk_marshal_NONE__INT_INT,
+                    GTK_TYPE_NONE, 2,
+                    GTK_TYPE_INT,
+                    GTK_TYPE_INT);
+
+  dock_item_signals[DOCK_DRAG_END] =
+    gtk_signal_new ("dock_drag_end",
+                    GTK_RUN_LAST,
+		    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (GnomeDockItemClass, dock_drag_end),
+                    gtk_marshal_NONE__NONE,
+                    GTK_TYPE_NONE, 0);
+
+  dock_item_signals[DOCK_DETACH] =
+    gtk_signal_new ("dock_detach",
+                    GTK_RUN_LAST,
+		    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (GnomeDockItemClass, dock_detach),
+                    gtk_marshal_NONE__NONE,
+                    GTK_TYPE_NONE, 0);
+
+  dock_item_signals[ORIENTATION_CHANGED] =
+    gtk_signal_new ("orientation_changed",
+		    GTK_RUN_LAST,
+		    GTK_CLASS_TYPE (object_class),
+		    GTK_SIGNAL_OFFSET (GnomeDockItemClass, orientation_changed),
+		    gtk_marshal_VOID__ENUM,
+		    GTK_TYPE_NONE, 0, GTK_TYPE_ENUM);
+
+  
+  object_class->destroy = gnome_dock_item_destroy;
+  gobject_class->finalize = gnome_dock_item_finalize;
+
+  widget_class->map = gnome_dock_item_map;
+  widget_class->unmap = gnome_dock_item_unmap;
+  widget_class->realize = gnome_dock_item_realize;
+  widget_class->unrealize = gnome_dock_item_unrealize;
+  widget_class->style_set = gnome_dock_item_style_set;
+  widget_class->size_request = gnome_dock_item_size_request;
+  widget_class->size_allocate = gnome_dock_item_size_allocate;
+  widget_class->expose_event = gnome_dock_item_expose;
+  widget_class->button_press_event = gnome_dock_item_button_changed;
+  widget_class->button_release_event = gnome_dock_item_button_changed;
+  widget_class->motion_notify_event = gnome_dock_item_motion;
+  widget_class->delete_event = gnome_dock_item_delete_event;
+
+  container_class->add = gnome_dock_item_add;
+  container_class->remove = gnome_dock_item_remove;
+}
+
+static void
+gnome_dock_item_init (GnomeDockItem *dock_item)
+{
+  GTK_WIDGET_UNSET_FLAGS (dock_item, GTK_NO_WINDOW);
+
+  dock_item->_priv = NULL;
+  /* XXX: when there is some private stuff enable this
+  dock_item->_priv = g_new0(GnomeDockItemPrivate, 1);
+  */
+
+  dock_item->bin_window = NULL;
+  dock_item->float_window = NULL;
+  dock_item->shadow_type = GTK_SHADOW_OUT;
+
+  dock_item->orientation = GTK_ORIENTATION_HORIZONTAL;
+  dock_item->behavior = GNOME_DOCK_ITEM_BEH_NORMAL;
+
+  dock_item->float_window_mapped = FALSE;
+  dock_item->is_floating = FALSE;
+  dock_item->in_drag = FALSE;
+
+  dock_item->dragoff_x = 0;
+  dock_item->dragoff_y = 0;
+
+  dock_item->float_x = 0;
+  dock_item->float_y = 0;
+}
+
+static void
+gnome_dock_item_set_property (GObject            *object,
+			      guint               param_id,
+			      const GValue       *value,
+			      GParamSpec         *pspec)
+{
+  GnomeDockItem *dock_item;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GNOME_IS_DOCK_ITEM (object));
+
+  dock_item = GNOME_DOCK_ITEM (object);
+
+  switch (param_id)
+    {
+    case PROP_SHADOW:
+      gnome_dock_item_set_shadow_type (dock_item, g_value_get_enum (value));
+      break;
+    case PROP_ORIENTATION:
+      gnome_dock_item_set_orientation (dock_item, g_value_get_enum (value));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+      break;
+    }
+}
+
+static void
+gnome_dock_item_get_property (GObject            *object,
+			      guint               param_id,
+			      GValue             *value,
+			      GParamSpec         *pspec)
+{
+  GnomeDockItem *dock_item;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GNOME_IS_DOCK_ITEM (object));
+
+  dock_item = GNOME_DOCK_ITEM (object);
+
+  switch (param_id)
+    {
+    case PROP_SHADOW:
+      g_value_set_enum (value, gnome_dock_item_get_shadow_type (dock_item));
+      break;
+    case PROP_ORIENTATION:
+      g_value_set_enum (value, gnome_dock_item_get_orientation (dock_item));
+      break;
+    case PROP_PREFERRED_HEIGHT:
+      g_value_set_uint (value, get_preferred_height (dock_item));
+      break;
+    case PROP_PREFERRED_WIDTH:
+      g_value_set_uint (value, get_preferred_width (dock_item));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+      break;
+    }
+}
+
+static void
+gnome_dock_item_destroy (GtkObject *object)
+{
+  GnomeDockItem *di;
+
+  /* remember, destroy can be run multiple times! */
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GNOME_IS_DOCK_ITEM (object));
+
+  di = GNOME_DOCK_ITEM (object);
+
+  g_free (di->name);
+  di->name = NULL;
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gnome_dock_item_finalize (GObject *object)
+{
+  GnomeDockItem *di;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GNOME_IS_DOCK_ITEM (object));
+
+  di = GNOME_DOCK_ITEM (object);
+
+  /* Free the private structure */
+  g_free (di->_priv);
+  di->_priv = NULL;
+
+  if (G_OBJECT_CLASS (parent_class)->finalize)
+    (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+static void
+gnome_dock_item_map (GtkWidget *widget)
+{
+  GtkBin *bin;
+  GnomeDockItem *di;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GNOME_IS_DOCK_ITEM (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
+
+  bin = GTK_BIN (widget);
+  di = GNOME_DOCK_ITEM (widget);
+
+  gdk_window_show (di->bin_window);
+  if (! di->is_floating)
+    gdk_window_show (widget->window);
+
+  if (di->is_floating && !di->float_window_mapped)
+    gnome_dock_item_detach (di, di->float_x, di->float_y);
+
+  if (bin->child
+      && GTK_WIDGET_VISIBLE (bin->child)
+      && !GTK_WIDGET_MAPPED (bin->child))
+    gtk_widget_map (bin->child);
+}
+
+static void
+gnome_dock_item_unmap (GtkWidget *widget)
+{
+  GnomeDockItem *di;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GNOME_IS_DOCK_ITEM (widget));
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
+
+  di = GNOME_DOCK_ITEM (widget);
+
+  gdk_window_hide (widget->window);
+  if (di->float_window_mapped)
+    {
+      gdk_window_hide (di->float_window);
+      di->float_window_mapped = FALSE;
+    }
+}
+
+static void
+gnome_dock_item_realize (GtkWidget *widget)
+{
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+  GnomeDockItem *di;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GNOME_IS_DOCK_ITEM (widget));
+
+  di = GNOME_DOCK_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 = (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 (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
+  gdk_window_set_user_data (widget->window, widget);
+
+  attributes.x = 0;
+  attributes.y = 0;
+  attributes.width = widget->allocation.width;
+  attributes.height = widget->allocation.height;
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.event_mask |= (gtk_widget_get_events (widget) |
+			    GDK_EXPOSURE_MASK |
+			    GDK_BUTTON1_MOTION_MASK |
+			    GDK_POINTER_MOTION_HINT_MASK |
+			    GDK_BUTTON_PRESS_MASK |
+			    GDK_BUTTON_RELEASE_MASK);
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+  di->bin_window = gdk_window_new (widget->window, &attributes, attributes_mask);
+  gdk_window_set_user_data (di->bin_window, widget);
+  if (GTK_BIN (di)->child)
+    gtk_widget_set_parent_window (GTK_BIN (di)->child, di->bin_window);
+  
+  attributes.x = 0;
+  attributes.y = 0;
+  attributes.width = widget->requisition.width;
+  attributes.height = widget->requisition.height;
+  attributes.window_type = GDK_WINDOW_TOPLEVEL;
+  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_KEY_PRESS_MASK |
+			   GDK_ENTER_NOTIFY_MASK |
+			   GDK_LEAVE_NOTIFY_MASK |
+			   GDK_FOCUS_CHANGE_MASK |
+			   GDK_STRUCTURE_MASK);
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+  di->float_window = gdk_window_new (NULL, &attributes, attributes_mask);
+  gdk_window_set_transient_for(di->float_window, gdk_window_get_toplevel(widget->window));
+  gdk_window_set_user_data (di->float_window, widget);
+  gdk_window_set_decorations (di->float_window, 0);
+  
+  widget->style = gtk_style_attach (widget->style, widget->window);
+  gtk_style_set_background (widget->style, widget->window, GTK_WIDGET_STATE (di));
+  gtk_style_set_background (widget->style, di->bin_window, GTK_WIDGET_STATE (di));
+  gtk_style_set_background (widget->style, di->float_window, GTK_WIDGET_STATE (di));
+  gdk_window_set_back_pixmap (widget->window, NULL, TRUE);
+
+  if (di->is_floating)
+    gnome_dock_item_detach (di, di->float_x, di->float_y);
+}
+
+static void
+gnome_dock_item_unrealize (GtkWidget *widget)
+{
+  GnomeDockItem *di;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GNOME_IS_DOCK_ITEM (widget));
+
+  di = GNOME_DOCK_ITEM (widget);
+
+  gdk_window_set_user_data (di->bin_window, NULL);
+  gdk_window_destroy (di->bin_window);
+  di->bin_window = NULL;
+  gdk_window_set_user_data (di->float_window, NULL);
+  gdk_window_destroy (di->float_window);
+  di->float_window = NULL;
+
+  if (GTK_WIDGET_CLASS (parent_class)->unrealize)
+    (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
+}
+
+static void
+gnome_dock_item_style_set (GtkWidget *widget,
+                           GtkStyle  *previous_style)
+{
+  GnomeDockItem *di;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GNOME_IS_DOCK_ITEM (widget));
+
+  di = GNOME_DOCK_ITEM (widget);
+
+  if (GTK_WIDGET_REALIZED (widget) &&
+      !GTK_WIDGET_NO_WINDOW (widget))
+    {
+      gtk_style_set_background (widget->style, widget->window,
+                                widget->state);
+      gtk_style_set_background (widget->style, di->bin_window, widget->state);
+      gtk_style_set_background (widget->style, di->float_window, widget->state);
+      if (GTK_WIDGET_DRAWABLE (widget))
+	gdk_window_clear (widget->window);
+    }
+}
+
+static void
+gnome_dock_item_size_request (GtkWidget      *widget,
+                              GtkRequisition *requisition)
+{
+  GtkBin *bin;
+  GnomeDockItem *dock_item;
+  GtkRequisition child_requisition;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GNOME_IS_DOCK_ITEM (widget));
+  g_return_if_fail (requisition != NULL);
+
+  bin = GTK_BIN (widget);
+  dock_item = GNOME_DOCK_ITEM (widget);
+
+  /* If our child is not visible, we still request its size, since
+     we won't have any useful hint for our size otherwise.  */
+  if (bin->child != NULL)
+    gtk_widget_size_request (bin->child, &child_requisition);
+  else
+    {
+      child_requisition.width = 0;
+      child_requisition.height = 0;
+    }
+
+  if (dock_item->orientation == GTK_ORIENTATION_HORIZONTAL)
+    {
+      requisition->width = 
+        GNOME_DOCK_ITEM_NOT_LOCKED (dock_item) ? DRAG_HANDLE_SIZE : 0;
+      if (bin->child != NULL)
+        {
+          requisition->width += child_requisition.width;
+          requisition->height = child_requisition.height;
+        }
+      else
+        requisition->height = 0;
+    }
+  else
+    {
+      requisition->height = 
+        GNOME_DOCK_ITEM_NOT_LOCKED (dock_item) ? DRAG_HANDLE_SIZE : 0;
+      if (bin->child != NULL)
+        {
+          requisition->width = child_requisition.width;
+          requisition->height += child_requisition.height;
+        }
+      else
+        requisition->width = 0;
+    }
+
+  requisition->width += GTK_CONTAINER (widget)->border_width * 2;
+  requisition->height += GTK_CONTAINER (widget)->border_width * 2;
+}
+
+static void
+gnome_dock_item_size_allocate (GtkWidget     *widget,
+                               GtkAllocation *allocation)
+{
+  GtkBin *bin;
+  GnomeDockItem *di;
+  
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GNOME_IS_DOCK_ITEM (widget));
+  g_return_if_fail (allocation != NULL);
+  
+  bin = GTK_BIN (widget);
+  di = GNOME_DOCK_ITEM (widget);
+
+  widget->allocation = *allocation;
+
+  if (GTK_WIDGET_REALIZED (widget))
+    gdk_window_move_resize (widget->window,
+                            widget->allocation.x,
+                            widget->allocation.y,
+                            widget->allocation.width,
+                            widget->allocation.height);
+
+  if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
+    {
+      GtkWidget *child;
+      GtkAllocation child_allocation;
+      int border_width;
+
+      child = bin->child;
+      border_width = GTK_CONTAINER (widget)->border_width;
+
+      child_allocation.x = border_width;
+      child_allocation.y = border_width;
+
+      if (GNOME_DOCK_ITEM_NOT_LOCKED(di))
+        {
+          if (di->orientation == GTK_ORIENTATION_HORIZONTAL)
+            child_allocation.x += DRAG_HANDLE_SIZE;
+          else
+            child_allocation.y += DRAG_HANDLE_SIZE;
+        }
+
+      if (di->is_floating)
+	{
+          GtkRequisition child_requisition;
+	  guint float_width;
+	  guint float_height;
+
+	  gtk_widget_get_child_requisition (child, &child_requisition);
+
+          child_allocation.width = child_requisition.width;
+          child_allocation.height = child_requisition.height;
+
+	  float_width = child_allocation.width + 2 * border_width;
+	  float_height = child_allocation.height + 2 * border_width;
+	  
+	  if (di->orientation == GTK_ORIENTATION_HORIZONTAL)
+	    float_width += DRAG_HANDLE_SIZE;
+	  else
+	    float_height += DRAG_HANDLE_SIZE;
+
+	  if (GTK_WIDGET_REALIZED (di))
+	    {
+	      gdk_window_resize (di->float_window,
+				 float_width,
+				 float_height);
+	      gdk_window_move_resize (di->bin_window,
+				      0,
+				      0,
+				      float_width,
+				      float_height);
+	    }
+	}
+      else
+	{
+	  child_allocation.width = MAX (1, (int) widget->allocation.width - 2 * border_width);
+	  child_allocation.height = MAX (1, (int) widget->allocation.height - 2 * border_width);
+
+          if (GNOME_DOCK_ITEM_NOT_LOCKED (di))
+            {
+              if (di->orientation == GTK_ORIENTATION_HORIZONTAL)
+		child_allocation.width = MAX ((int) child_allocation.width - DRAG_HANDLE_SIZE, 1);
+              else
+		child_allocation.height = MAX ((int) child_allocation.height - DRAG_HANDLE_SIZE, 1);
+            }
+
+	  if (GTK_WIDGET_REALIZED (di))
+	    gdk_window_move_resize (di->bin_window,
+				    0,
+				    0,
+				    widget->allocation.width,
+				    widget->allocation.height);
+	}
+
+      gtk_widget_size_allocate (bin->child, &child_allocation);
+    }
+}
+
+static void
+draw_textured_frame (GtkWidget *widget, GdkWindow *window, GdkRectangle *rect, GtkShadowType shadow,
+		     GdkRectangle *clip)
+{
+  gtk_paint_handle(widget->style, window, GTK_STATE_NORMAL, shadow,
+                   clip, widget, "dockitem",
+                   rect->x, rect->y, rect->width, rect->height, 
+                   GTK_ORIENTATION_VERTICAL);
+}
+
+static void
+gnome_dock_item_paint (GtkWidget      *widget,
+                       GdkEventExpose *event)
+{
+  GtkBin *bin;
+  GnomeDockItem *di;
+  guint width;
+  guint height;
+  guint border_width;
+  GdkRectangle rect;
+  gint drag_handle_size = DRAG_HANDLE_SIZE;
+
+  if (!GNOME_DOCK_ITEM_NOT_LOCKED (widget))
+    drag_handle_size = 0;
+
+  bin = GTK_BIN (widget);
+  di = GNOME_DOCK_ITEM (widget);
+
+  border_width = GTK_CONTAINER (di)->border_width;
+
+  if (di->is_floating)
+    {
+      width = bin->child->allocation.width + 2 * border_width;
+      height = bin->child->allocation.height + 2 * border_width;
+    }
+  else if (di->orientation == GTK_ORIENTATION_HORIZONTAL)
+    {
+      width = widget->allocation.width - drag_handle_size;
+      height = widget->allocation.height;
+    }
+  else
+    {
+      width = widget->allocation.width;
+      height = widget->allocation.height - drag_handle_size;
+    }
+
+  if (!event)
+    gtk_paint_box(widget->style,
+                  di->bin_window,
+                  GTK_WIDGET_STATE (widget),
+                  di->shadow_type,
+                  NULL, widget,
+                  "dockitem_bin",
+                  0, 0, -1, -1);
+  else
+    gtk_paint_box(widget->style,
+                  di->bin_window,
+                  GTK_WIDGET_STATE (widget),
+                  di->shadow_type,
+                  &event->area, widget,
+                  "dockitem_bin",
+                  0, 0, -1, -1);
+
+  /* We currently draw the handle _above_ the relief of the dockitem.
+     It could also be drawn on the same level...  */
+
+  if (GNOME_DOCK_ITEM_NOT_LOCKED (di))
+    {
+      GdkRectangle dest;
+
+      rect.x = 0;
+      rect.y = 0;
+      
+      if (di->orientation == GTK_ORIENTATION_HORIZONTAL)
+        {
+          rect.width = DRAG_HANDLE_SIZE;
+          rect.height = height;
+        }
+      else
+        {
+          rect.width = width;
+          rect.height = DRAG_HANDLE_SIZE;
+        }
+
+      dest = rect;
+
+      if (event == NULL ||
+	  gdk_rectangle_intersect (&event->area, &rect, &dest))
+	draw_textured_frame (widget, di->bin_window, &rect,
+			     GTK_SHADOW_OUT,
+			     &dest);
+    }    
+}
+
+static gint
+gnome_dock_item_expose (GtkWidget      *widget,
+                        GdkEventExpose *event)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GNOME_IS_DOCK_ITEM (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget) && event->window != widget->window)
+    {
+      gnome_dock_item_paint (widget, event);
+
+      return GTK_WIDGET_CLASS (parent_class)->expose_event ?
+	  GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event) : FALSE;
+    }
+
+  return FALSE;
+}
+
+static gint
+gnome_dock_item_button_changed (GtkWidget      *widget,
+                                GdkEventButton *event)
+{
+  GnomeDockItem *di;
+  gboolean event_handled;
+  
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GNOME_IS_DOCK_ITEM (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  di = GNOME_DOCK_ITEM (widget);
+
+  if (event->window != di->bin_window)
+    return FALSE;
+
+  if (!GNOME_DOCK_ITEM_NOT_LOCKED(widget))
+    return FALSE;
+
+  event_handled = FALSE;
+
+  if (event->button == 1 && event->type == GDK_BUTTON_PRESS)
+    {
+      GtkWidget *child;
+      gboolean in_handle;
+      
+      child = GTK_BIN (di)->child;
+      
+      switch (di->orientation)
+	{
+	case GTK_ORIENTATION_HORIZONTAL:
+	  in_handle = event->x < DRAG_HANDLE_SIZE;
+	  break;
+	case GTK_ORIENTATION_VERTICAL:
+	  in_handle = event->y < DRAG_HANDLE_SIZE;
+	  break;
+	default:
+	  in_handle = FALSE;
+	  break;
+	}
+
+      if (!child)
+	{
+	  in_handle = FALSE;
+	  event_handled = TRUE;
+	}
+      
+      if (in_handle)
+	{
+	  di->dragoff_x = event->x;
+	  di->dragoff_y = event->y;
+
+	  di->in_drag = TRUE;
+
+          gnome_dock_item_grab_pointer (di);
+
+          gtk_signal_emit (GTK_OBJECT (widget),
+                           dock_item_signals[DOCK_DRAG_BEGIN]);
+
+	  event_handled = TRUE;
+	}
+    }
+  else if (event->type == GDK_BUTTON_RELEASE && di->in_drag)
+    {
+      gdk_pointer_ungrab (GDK_CURRENT_TIME);
+      
+      di->in_drag = FALSE;
+
+      gtk_signal_emit (GTK_OBJECT (widget),
+                       dock_item_signals[DOCK_DRAG_END]);
+      event_handled = TRUE;
+    }
+
+  return event_handled;
+}
+
+static gint
+gnome_dock_item_motion (GtkWidget      *widget,
+                        GdkEventMotion *event)
+{
+  GnomeDockItem *di;
+  gint new_x, new_y;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GNOME_IS_DOCK_ITEM (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  di = GNOME_DOCK_ITEM (widget);
+  if (!di->in_drag)
+    return FALSE;
+
+  if (event->window != di->bin_window)
+    return FALSE;
+
+  gdk_window_get_pointer (NULL, &new_x, &new_y, NULL);
+  
+  new_x -= di->dragoff_x;
+  new_y -= di->dragoff_y;
+
+  gtk_signal_emit (GTK_OBJECT (widget),
+                   dock_item_signals[DOCK_DRAG_MOTION],
+                   new_x, new_y);
+
+  return TRUE;
+}
+
+static void
+gnome_dock_item_add (GtkContainer *container,
+                     GtkWidget    *widget)
+{
+  GnomeDockItem *dock_item;
+  GParamSpec *pspec;
+
+  g_return_if_fail (GNOME_IS_DOCK_ITEM (container));
+  g_return_if_fail (GTK_BIN (container)->child == NULL);
+  g_return_if_fail (widget->parent == NULL);
+
+  dock_item = GNOME_DOCK_ITEM (container);
+
+  gtk_widget_set_parent_window (widget, dock_item->bin_window);
+  GTK_CONTAINER_CLASS (parent_class)->add (container, widget);
+
+  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (widget),
+					"orientation");
+  if (pspec != NULL) {
+    GValue value = { 0, };
+
+    g_value_init (&value, GTK_TYPE_ORIENTATION);
+    g_value_set_enum (&value, dock_item->orientation);
+    g_object_set_property (G_OBJECT (widget), "orientation", &value);
+    g_value_unset (&value);
+  }
+}
+
+static void
+gnome_dock_item_set_floating (GnomeDockItem *item, gboolean val)
+{
+  item->is_floating = val;
+
+  /* If there is a child and it supports the 'is_floating' flag
+   * set that too.
+   */
+  if (item->bin.child != NULL &&
+      g_object_class_find_property (G_OBJECT_GET_CLASS (item->bin.child),
+				    "is_floating") != NULL) {
+    GValue value = { 0, };
+    g_value_init (&value, G_TYPE_BOOLEAN);
+    g_value_set_boolean (&value, val);
+    g_object_set_property (G_OBJECT (item->bin.child), "is_floating", &value);
+    g_value_unset (&value);
+  }
+}
+
+static void
+gnome_dock_item_remove (GtkContainer *container,
+                        GtkWidget    *widget)
+{
+  GnomeDockItem *di;
+
+  g_return_if_fail (GNOME_IS_DOCK_ITEM (container));
+  g_return_if_fail (GTK_BIN (container)->child == widget);
+
+  di = GNOME_DOCK_ITEM (container);
+
+  if (di->is_floating)
+    {
+      gnome_dock_item_set_floating (di, FALSE);
+      if (GTK_WIDGET_REALIZED (di))
+	{
+	  gdk_window_hide (di->float_window);
+	  gdk_window_reparent (di->bin_window, GTK_WIDGET (di)->window, 0, 0);
+          gdk_window_show (widget->window);
+	}
+      di->float_window_mapped = FALSE;
+    }
+  if (di->in_drag)
+    {
+      gdk_pointer_ungrab (GDK_CURRENT_TIME);
+      di->in_drag = FALSE;
+    }
+  
+  GTK_CONTAINER_CLASS (parent_class)->remove (container, widget);
+}
+
+static gint
+gnome_dock_item_delete_event (GtkWidget *widget,
+                              GdkEventAny  *event)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GNOME_IS_DOCK_ITEM (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  return TRUE;
+}
+
+
+
+/**
+ * gnome_dock_item_construct:
+ * @new: a #GnomeDockItem.
+ * @name: Name for the new item
+ * @behavior: Behavior for the new item
+ * 
+ * Description: Constructs the @new GnomeDockItem named @name, with the
+ * specified @behavior.
+ * 
+ * Returns: A new GnomeDockItem widget.
+ **/
+void
+gnome_dock_item_construct (GnomeDockItem *new,
+			   const gchar *name,
+			   GnomeDockItemBehavior behavior)
+{
+	g_return_if_fail (new != NULL);
+	g_return_if_fail (GNOME_IS_DOCK_ITEM (new));
+	
+	new->name = g_strdup (name);
+	new->behavior = behavior;
+}
+
+/**
+ * gnome_dock_item_new:
+ * @name: Name for the new item
+ * @behavior: Behavior for the new item
+ * 
+ * Description: Create a new GnomeDockItem named @name, with the
+ * specified @behavior.
+ * 
+ * Returns: A new GnomeDockItem widget.
+ **/
+GtkWidget*
+gnome_dock_item_new (const gchar *name,
+                     GnomeDockItemBehavior behavior)
+{
+  GnomeDockItem *new;
+
+  new = GNOME_DOCK_ITEM (gtk_type_new (gnome_dock_item_get_type ()));
+
+  gnome_dock_item_construct (new, name, behavior);
+
+  return GTK_WIDGET (new);
+}
+
+/**
+ * gnome_dock_item_get_child:
+ * @item: A GnomeDockItem widget
+ * 
+ * Description: Retrieve the child of @item.
+ * 
+ * Returns: The child of @item.
+ **/
+GtkWidget *
+gnome_dock_item_get_child (GnomeDockItem *item)
+{
+  return GTK_BIN (item)->child;
+}
+
+/**
+ * gnome_dock_item_get_name:
+ * @item: A GnomeDockItem widget.
+ * 
+ * Description: Retrieve the name of @item.
+ * 
+ * Return value: The name of @item as a malloc()ed zero-terminated
+ * string.
+ **/
+gchar *
+gnome_dock_item_get_name (GnomeDockItem *item)
+{
+  return g_strdup (item->name);
+}
+
+/**
+ * gnome_dock_item_set_shadow_type:
+ * @dock_item: A GnomeDockItem widget
+ * @type: The shadow type for @dock_item
+ * 
+ * Description: Set the shadow type for @dock_item.
+ **/
+void
+gnome_dock_item_set_shadow_type (GnomeDockItem  *dock_item,
+                                 GtkShadowType  type)
+{
+  g_return_if_fail (dock_item != NULL);
+  g_return_if_fail (GNOME_IS_DOCK_ITEM (dock_item));
+
+  if (dock_item->shadow_type != type)
+    {
+      dock_item->shadow_type = type;
+
+      if (GTK_WIDGET_DRAWABLE (dock_item))
+        gtk_widget_queue_clear (GTK_WIDGET (dock_item));
+      gtk_widget_queue_resize (GTK_WIDGET (dock_item));
+    }
+}
+
+/**
+ * gnome_dock_item_get_shadow_type:
+ * @dock_item: A GnomeDockItem widget.
+ * 
+ * Description: Retrieve the shadow type of @dock_item.
+ * 
+ * Returns: @dock_item's shadow type.
+ **/
+GtkShadowType
+gnome_dock_item_get_shadow_type (GnomeDockItem  *dock_item)
+{
+  g_return_val_if_fail (dock_item != NULL, GTK_SHADOW_OUT);
+  g_return_val_if_fail (GNOME_IS_DOCK_ITEM (dock_item), GTK_SHADOW_OUT);
+
+  return dock_item->shadow_type;
+}
+
+/**
+ * gnome_dock_item_set_orientation:
+ * @dock_item: A GnomeDockItem widget
+ * @orientation: New orientation for @dock_item
+ * 
+ * Description: Set the orientation for @dock_item.
+ * 
+ * Returns: %TRUE if the operation succeeds, %FALSE if it fails.
+ **/
+gboolean
+gnome_dock_item_set_orientation (GnomeDockItem *dock_item,
+                                 GtkOrientation orientation)
+{
+  g_return_val_if_fail (dock_item != NULL, FALSE);
+  g_return_val_if_fail (GNOME_IS_DOCK_ITEM (dock_item), FALSE);
+
+  if (dock_item->orientation != orientation)
+    {
+      if ((orientation == GTK_ORIENTATION_VERTICAL
+           && (dock_item->behavior & GNOME_DOCK_ITEM_BEH_NEVER_VERTICAL))
+          || (orientation == GTK_ORIENTATION_HORIZONTAL
+              && (dock_item->behavior & GNOME_DOCK_ITEM_BEH_NEVER_HORIZONTAL)))
+        return FALSE;
+
+      dock_item->orientation = orientation;
+
+      if (dock_item->bin.child != NULL) {
+	GValue value = { 0, };
+
+	g_value_init (&value, GTK_TYPE_ORIENTATION);
+	g_value_set_enum (&value, orientation);
+	g_object_set_property (G_OBJECT (dock_item->bin.child),
+			       "orientation", &value);
+	g_value_unset (&value);
+      }
+      if (GTK_WIDGET_DRAWABLE (dock_item))
+        gtk_widget_queue_clear (GTK_WIDGET (dock_item));
+      gtk_widget_queue_resize (GTK_WIDGET (dock_item));
+
+      gtk_signal_emit(GTK_OBJECT(dock_item), dock_item_signals[ORIENTATION_CHANGED], orientation);
+    }
+
+  return TRUE;
+}
+
+/**
+ * gnome_dock_item_get_orientation:
+ * @dock_item: A GnomeDockItem widget.
+ * 
+ * Description: Retrieve the orientation of @dock_item.
+ * 
+ * Returns: The current orientation of @dock_item.
+ **/
+GtkOrientation
+gnome_dock_item_get_orientation (GnomeDockItem *dock_item)
+{
+  g_return_val_if_fail (dock_item != NULL,
+                        GTK_ORIENTATION_HORIZONTAL);
+  g_return_val_if_fail (GNOME_IS_DOCK_ITEM (dock_item),
+                        GTK_ORIENTATION_HORIZONTAL);
+
+  return dock_item->orientation;
+}
+
+/**
+ * gnome_dock_item_get_behavior:
+ * @dock_item: A GnomeDockItem widget.
+ * 
+ * Description: Retrieve the behavior of @dock_item.
+ * 
+ * Returns: The behavior of @dock_item.
+ **/
+GnomeDockItemBehavior
+gnome_dock_item_get_behavior (GnomeDockItem *dock_item)
+{
+  g_return_val_if_fail (dock_item != NULL,
+                        GNOME_DOCK_ITEM_BEH_NORMAL);
+  g_return_val_if_fail (GNOME_IS_DOCK_ITEM (dock_item),
+                        GNOME_DOCK_ITEM_BEH_NORMAL);
+
+  return dock_item->behavior;
+}
+
+
+
+/* Private interface.  */
+
+void
+gnome_dock_item_grab_pointer (GnomeDockItem *item)
+{
+  GdkCursor *fleur;
+
+  fleur = gdk_cursor_new (GDK_FLEUR);
+
+  /* Hm, not sure this is the right thing to do, but it seems to work.  */
+  while (gdk_pointer_grab (item->bin_window,
+                           FALSE,
+                           (GDK_BUTTON1_MOTION_MASK |
+                            GDK_POINTER_MOTION_HINT_MASK |
+                            GDK_BUTTON_RELEASE_MASK),
+                           NULL,
+                           fleur,
+                           GDK_CURRENT_TIME) != 0);
+
+  gdk_cursor_destroy (fleur);
+}
+
+gboolean
+gnome_dock_item_detach (GnomeDockItem *item, gint x, gint y)
+{
+  GtkRequisition requisition;
+  GtkAllocation allocation;
+
+  if (item->behavior & GNOME_DOCK_ITEM_BEH_NEVER_FLOATING)
+    return FALSE;
+
+  item->float_x = x;
+  item->float_y = y;
+
+  gnome_dock_item_set_floating (item, TRUE);
+
+  if (! GTK_WIDGET_REALIZED (item))
+    return TRUE;
+
+  gtk_widget_size_request (GTK_WIDGET (item), &requisition);
+
+  gdk_window_move_resize (item->float_window,
+                          x, y, requisition.width, requisition.height);
+
+  gdk_window_reparent (item->bin_window, item->float_window, 0, 0);
+  gdk_window_set_hints (item->float_window, x, y, 0, 0, 0, 0, GDK_HINT_POS);
+
+  gdk_window_show (item->float_window);
+  item->float_window_mapped = TRUE;
+
+  allocation.x = allocation.y = 0;
+  allocation.width = requisition.width;
+  allocation.height = requisition.height;
+  gtk_widget_size_allocate (GTK_WIDGET (item), &allocation);
+
+  gdk_window_hide (GTK_WIDGET (item)->window);
+  gtk_widget_queue_draw (GTK_WIDGET (item));
+
+  gdk_window_set_transient_for(item->float_window,
+                               gdk_window_get_toplevel(GTK_WIDGET (item)->window));
+
+  return TRUE;
+}
+
+void
+gnome_dock_item_attach (GnomeDockItem *item, GtkWidget *parent, gint x, gint y)
+{
+  if (GTK_WIDGET (item)->parent != GTK_WIDGET (parent))
+    {
+      gdk_window_move_resize (GTK_WIDGET (item)->window, -1, -1, 0, 0);
+      gtk_widget_reparent (GTK_WIDGET (item), parent);
+
+      gdk_window_hide (item->float_window);
+
+      gdk_window_reparent (item->bin_window, GTK_WIDGET (item)->window, 0, 0);
+      gdk_window_show (GTK_WIDGET (item)->window);
+
+      item->float_window_mapped = FALSE;
+      gnome_dock_item_set_floating (item, FALSE);
+
+      gtk_widget_queue_resize (GTK_WIDGET (item));
+
+      gnome_dock_item_grab_pointer (item);
+    }
+}
+
+void
+gnome_dock_item_drag_floating (GnomeDockItem *item, gint x, gint y)
+{
+  if (item->is_floating)
+    {
+      gdk_window_move (item->float_window, x, y);
+      gdk_window_raise (item->float_window);
+
+      item->float_x = x;
+      item->float_y = y;
+    }
+}
+
+void
+gnome_dock_item_handle_size_request (GnomeDockItem *item,
+                                     GtkRequisition *requisition)
+{
+  GtkBin *bin;
+  GtkContainer *container;
+
+  bin = GTK_BIN (item);
+  container = GTK_CONTAINER (item);
+
+  if (bin->child != NULL)
+    gtk_widget_size_request (bin->child, requisition);
+
+  if (item->orientation == GTK_ORIENTATION_HORIZONTAL)
+    requisition->width += DRAG_HANDLE_SIZE;
+  else
+    requisition->height += DRAG_HANDLE_SIZE;
+
+  requisition->width += container->border_width * 2;
+  requisition->height += container->border_width * 2;
+}
+
+void
+gnome_dock_item_get_floating_position (GnomeDockItem *item,
+                                       gint *x, gint *y)
+{
+  if (GTK_WIDGET_REALIZED (item) && item->is_floating)
+    gdk_window_get_position (item->float_window, x, y);
+  else
+    {
+      *x = item->float_x;
+      *y = item->float_y;
+    }
+}
diff --git a/libgnomeui/gnome-dock-item.h b/libgnomeui/gnome-dock-item.h
new file mode 100644
index 0000000..9fe8d2a
--- /dev/null
+++ b/libgnomeui/gnome-dock-item.h
@@ -0,0 +1,165 @@
+/*
+ * !!! MASTER CAUTION !!!!
+ *
+ * These files have been moved to libbonoboui and renamed to bonobo-dock*.[ch].
+ * We'll provide a compatibility wrapper with #defines in libgnomecompat soon, but
+ * at the moment I don't want to break the build here since libbonoboui doesn't work yet.
+ *
+ * If you do any changes in these files here, your work will be lost !
+ */
+
+/* WARNING ____ IMMATURE API ____ liable to change */
+
+/* gnome-dock-item.h
+ *
+ * Copyright (C) 1998 Ettore Perazzoli
+ * Copyright (C) 1998 Elliot Lee
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ * All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#ifndef _GNOME_DOCK_ITEM_H
+#define _GNOME_DOCK_ITEM_H
+
+#include <gdk/gdk.h>
+#include <gtk/gtkbin.h>
+
+
+
+G_BEGIN_DECLS
+
+#define GNOME_TYPE_DOCK_ITEM            (gnome_dock_item_get_type())
+#define GNOME_DOCK_ITEM(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_DOCK_ITEM, GnomeDockItem))
+#define GNOME_DOCK_ITEM_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_DOCK_ITEM, GnomeDockItemClass))
+#define GNOME_IS_DOCK_ITEM(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_DOCK_ITEM))
+#define GNOME_IS_DOCK_ITEM_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_DOCK_ITEM))
+#define GNOME_DOCK_ITEM_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_DOCK_ITEM, GnomeDockItemClass))
+
+typedef enum
+{
+  GNOME_DOCK_ITEM_BEH_NORMAL = 0,
+  GNOME_DOCK_ITEM_BEH_EXCLUSIVE = 1 << 0,
+  GNOME_DOCK_ITEM_BEH_NEVER_FLOATING = 1 << 1,
+  GNOME_DOCK_ITEM_BEH_NEVER_VERTICAL = 1 << 2,
+  GNOME_DOCK_ITEM_BEH_NEVER_HORIZONTAL = 1 << 3,
+  GNOME_DOCK_ITEM_BEH_LOCKED = 1 << 4
+  /* MAINT: Update the size of the bit field in the GnomeDockItem structure if you add items to this */
+} GnomeDockItemBehavior;
+
+/* obsolete, for compatibility; don't use */
+#define GNOME_DOCK_ITEM_BEH_NEVER_DETACH GNOME_DOCK_ITEM_BEH_NEVER_FLOATING
+
+#define GNOME_DOCK_ITEM_NOT_LOCKED(x) (! (GNOME_DOCK_ITEM(x)->behavior \
+                                          & GNOME_DOCK_ITEM_BEH_LOCKED))
+
+typedef struct _GnomeDockItem        GnomeDockItem;
+typedef struct _GnomeDockItemPrivate GnomeDockItemPrivate;
+typedef struct _GnomeDockItemClass   GnomeDockItemClass;
+
+struct _GnomeDockItem
+{
+  GtkBin bin;
+
+  gchar                *name;
+
+  GdkWindow            *bin_window; /* parent window for children */
+  GdkWindow            *float_window;
+  GtkShadowType         shadow_type;
+
+  /* Start drag position (wrt widget->window).  */
+  gint16                  dragoff_x, dragoff_y;
+
+  /* Position of the floating window.  */
+  gint16                  float_x, float_y;
+
+  GnomeDockItemBehavior behavior : 5;
+  GtkOrientation        orientation : 1;
+
+  guint                 float_window_mapped : 1;
+  guint                 is_floating : 1;
+  guint                 in_drag : 1;
+  /* If TRUE, the pointer must be grabbed on "map_event".  */
+  guint                 grab_on_map_event : 1;
+
+  /*< private >*/
+  GnomeDockItemPrivate *_priv;
+};
+
+struct _GnomeDockItemClass
+{
+  GtkBinClass parent_class;
+
+  void (* dock_drag_begin) (GnomeDockItem *item);
+  void (* dock_drag_motion) (GnomeDockItem *item, gint x, gint y);
+  void (* dock_drag_end) (GnomeDockItem *item);
+  void (* dock_detach) (GnomeDockItem *item);
+  void (* orientation_changed) (GnomeDockItem *item, GtkOrientation new_orientation);
+};
+
+/* Public methods.  */
+guint          gnome_dock_item_get_type        (void) G_GNUC_CONST;
+GtkWidget     *gnome_dock_item_new             (const gchar *name,
+                                                GnomeDockItemBehavior behavior);
+void           gnome_dock_item_construct       (GnomeDockItem *new_dock_item,
+						const gchar *name,
+						GnomeDockItemBehavior behavior);
+
+GtkWidget     *gnome_dock_item_get_child       (GnomeDockItem *dock_item);
+
+char          *gnome_dock_item_get_name        (GnomeDockItem *dock_item);
+
+void           gnome_dock_item_set_shadow_type (GnomeDockItem *dock_item,
+                                                GtkShadowType type);
+
+GtkShadowType  gnome_dock_item_get_shadow_type (GnomeDockItem *dock_item);
+ 
+gboolean       gnome_dock_item_set_orientation (GnomeDockItem *dock_item,
+                                                GtkOrientation orientation);
+
+GtkOrientation gnome_dock_item_get_orientation (GnomeDockItem *dock_item);
+
+GnomeDockItemBehavior
+               gnome_dock_item_get_behavior    (GnomeDockItem *dock_item);
+
+/* Private methods.  */
+gboolean       gnome_dock_item_detach          (GnomeDockItem *item,
+                                                gint x, gint y);
+                                               
+void           gnome_dock_item_attach          (GnomeDockItem *item,
+                                                GtkWidget *parent,
+                                                gint x, gint y);
+                                               
+void           gnome_dock_item_grab_pointer    (GnomeDockItem *item);
+                                               
+void           gnome_dock_item_drag_floating   (GnomeDockItem *item,
+                                                gint x, gint y);
+
+void           gnome_dock_item_handle_size_request
+                                               (GnomeDockItem *item,
+                                                GtkRequisition *requisition);
+
+void           gnome_dock_item_get_floating_position
+                                               (GnomeDockItem *item,
+                                                gint *x, gint *y);
+
+G_END_DECLS
+
+#endif /* _GNOME_DOCK_ITEM_H */
diff --git a/libgnomeui/gnome-dock-layout.c b/libgnomeui/gnome-dock-layout.c
new file mode 100644
index 0000000..dff69d6
--- /dev/null
+++ b/libgnomeui/gnome-dock-layout.c
@@ -0,0 +1,642 @@
+/*
+ * !!! MASTER CAUTION !!!!
+ *
+ * These files have been moved to libbonoboui and renamed to bonobo-dock*.[ch].
+ * We'll provide a compatibility wrapper with #defines in libgnomecompat soon, but
+ * at the moment I don't want to break the build here since libbonoboui doesn't work yet.
+ *
+ * If you do any changes in these files here, your work will be lost !
+ */
+
+/* gnome-dock-layout.c
+
+   Copyright (C) 1998 Free Software Foundation
+
+   All rights reserved.
+
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Ettore Perazzoli <ettore comm2000 it>
+*/
+/*
+  @NOTATION@
+*/
+
+#include <gtk/gtk.h>
+#include <stdio.h>
+
+#include "gnome-dock-layout.h"
+
+/* TODO: handle incorrect GNOME_DOCK_ITEM_BEH_EXCLUSIVE situations.  */
+
+struct _GnomeDockLayoutPrivate
+{
+	int dummy;
+	/* Nothing right now, needs to get filled with the private things */
+	/* XXX: When stuff is added, uncomment the allocation in the
+	 * gnome_dock_layout_init function! */
+};
+
+
+static GtkObjectClass *parent_class = NULL;
+
+
+
+static void   gnome_dock_layout_class_init   (GnomeDockLayoutClass  *class);
+
+static void   gnome_dock_layout_init         (GnomeDockLayout *layout);
+
+static void   gnome_dock_layout_destroy      (GtkObject *object);
+static void   gnome_dock_layout_finalize     (GObject *object);
+
+static gint   item_compare_func              (gconstpointer a,
+                                              gconstpointer b);
+
+static gint   compare_item_by_name           (gconstpointer a,
+                                              gconstpointer b);
+
+static gint   compare_item_by_pointer        (gconstpointer a,
+                                              gconstpointer b);
+
+static GList *find                           (GnomeDockLayout *layout,
+                                              gconstpointer a,
+                                              GCompareFunc func);
+
+static void   remove_item                    (GnomeDockLayout *layout,
+                                              GList *list);
+
+
+static void
+gnome_dock_layout_class_init (GnomeDockLayoutClass  *class)
+{
+  GtkObjectClass *object_class;
+  GObjectClass *gobject_class;
+
+  object_class = (GtkObjectClass *) class;
+  gobject_class = (GObjectClass *) class;
+
+  object_class->destroy = gnome_dock_layout_destroy;
+  gobject_class->finalize = gnome_dock_layout_finalize;
+
+  parent_class = gtk_type_class (gtk_object_get_type ());
+}
+
+static void
+gnome_dock_layout_init (GnomeDockLayout *layout)
+{
+  layout->_priv = NULL;
+  /* XXX: when there is some private stuff enable this
+  layout->_priv = g_new0(GnomeDockLayoutPrivate, 1);
+  */
+  layout->items = NULL;
+}
+
+static void
+gnome_dock_layout_destroy (GtkObject *object)
+{
+  GnomeDockLayout *layout;
+
+  /* remember, destroy can be run multiple times! */
+
+  layout = GNOME_DOCK_LAYOUT (object);
+
+  while (layout->items)
+    remove_item (layout, layout->items);
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gnome_dock_layout_finalize (GObject *object)
+{
+  GnomeDockLayout *layout;
+
+  layout = GNOME_DOCK_LAYOUT (object);
+
+  /* Free the private structure */
+  g_free (layout->_priv);
+  layout->_priv = NULL;
+
+  if (G_OBJECT_CLASS (parent_class)->finalize)
+    (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+
+
+static gint
+item_compare_func (gconstpointer a,
+                   gconstpointer b)
+{
+  const GnomeDockLayoutItem *item_a, *item_b;
+
+  item_a = a;
+  item_b = b;
+
+  if (item_a->placement != item_b->placement)
+    return item_b->placement - item_a->placement;
+
+  if (item_a->placement == GNOME_DOCK_FLOATING)
+    return 0; /* Floating items don't need to be ordered.  */
+  else
+    {
+      if (item_a->position.docked.band_num != item_b->position.docked.band_num)
+        return (item_b->position.docked.band_num
+                - item_a->position.docked.band_num);
+
+      return (item_b->position.docked.band_position
+              - item_a->position.docked.band_position);
+    }
+}
+
+static gint
+compare_item_by_name (gconstpointer a, gconstpointer b)
+{
+  const GnomeDockItem *item;
+  const gchar *name;
+
+  item = b;
+  name = a;
+
+  return strcmp (name, item->name);
+}
+
+static gint
+compare_item_by_pointer (gconstpointer a, gconstpointer b)
+{
+  return a != b;
+}
+
+static GList *
+find (GnomeDockLayout *layout, gconstpointer data, GCompareFunc func)
+{
+  GList *p;
+
+  for (p = layout->items; p != NULL; p = p->next)
+    {
+      GnomeDockLayoutItem *item;
+
+      item = p->data;
+      if (! (* func) (data, item->item))
+        return p;
+    }
+
+  return NULL;
+}
+
+static void
+remove_item (GnomeDockLayout *layout,
+             GList *list)
+{
+  GnomeDockItem *item;
+
+  item = ((GnomeDockLayoutItem *) list->data)->item;
+
+  gtk_widget_unref (GTK_WIDGET (item));
+
+  layout->items = g_list_remove_link (layout->items, list);
+
+  g_free (list->data);
+  g_list_free (list);
+}
+
+
+
+guint
+gnome_dock_layout_get_type (void)
+{
+  static guint layout_type = 0;
+	
+  if (layout_type == 0)
+    {
+      GtkTypeInfo layout_info =
+      {
+        "GnomeDockLayout",
+        sizeof (GnomeDockLayout),
+        sizeof (GnomeDockLayoutClass),
+        (GtkClassInitFunc) gnome_dock_layout_class_init,
+        (GtkObjectInitFunc) gnome_dock_layout_init,
+        NULL,
+        NULL,
+	NULL
+      };
+		
+      layout_type = gtk_type_unique (gtk_object_get_type (), &layout_info);
+    }
+
+  return layout_type;
+}
+
+/**
+ * gnome_dock_layout_new:
+ * 
+ * Description: Create a new #GnomeDockLayout widget.
+ * 
+ * Returns: The new #GnomeDockLayout widget.
+ **/
+   
+GnomeDockLayout *
+gnome_dock_layout_new (void)
+{
+  GnomeDockLayout *new;
+
+  new = gtk_type_new (gnome_dock_layout_get_type ());
+
+  return new;
+}
+
+/**
+ * gnome_dock_layout_add_item:
+ * @layout: A #GnomeDockLayout widget
+ * @item: The dock item to be added to @layout
+ * @placement: Placement of @item in @layout
+ * @band_num: Band number
+ * @band_position: Position within the band
+ * @offset: Distance from the previous element in the band
+ * 
+ * Description: Add @item to @layout with the specified parameters.
+ * 
+ * Returns: %TRUE if the operation succeeds, %FALSE if it fails.
+ **/
+gboolean
+gnome_dock_layout_add_item (GnomeDockLayout *layout,
+                            GnomeDockItem *item,
+                            GnomeDockPlacement placement,
+                            gint band_num,
+                            gint band_position,
+                            gint offset)
+{
+  GnomeDockLayoutItem *new;
+
+  new = g_new (GnomeDockLayoutItem, 1);
+  new->item = item;
+  new->placement = placement;
+  new->position.docked.band_num = band_num;
+  new->position.docked.band_position = band_position;
+  new->position.docked.offset = offset;
+
+  layout->items = g_list_prepend (layout->items, new);
+
+  gtk_object_ref (GTK_OBJECT (item));
+
+  return TRUE;
+}
+
+/**
+ * gnome_dock_layout_add_floating_item:
+ * @layout: A #GnomeDockLayout widget
+ * @item: The dock item to be added to @layout
+ * @x: X-coordinate for the floating item
+ * @y: Y-coordinate for the floating item
+ * @orientation: Orientation for the floating item
+ * 
+ * Description: Add @item to @layout as a floating item with the
+ * specified (@x, @y) position and @orientation.
+ * 
+ * Returns: %TRUE if the operation succeeds, %FALSE if it fails.
+ **/
+   
+gboolean
+gnome_dock_layout_add_floating_item (GnomeDockLayout *layout,
+                                     GnomeDockItem *item,
+                                     gint x, gint y,
+                                     GtkOrientation orientation)
+{
+  GnomeDockLayoutItem *new;
+
+  new = g_new (GnomeDockLayoutItem, 1);
+  new->item = item;
+  new->placement = GNOME_DOCK_FLOATING;
+  new->position.floating.x = x;
+  new->position.floating.y = y;
+  new->position.floating.orientation = orientation;
+
+  layout->items = g_list_prepend (layout->items, new);
+
+  gtk_object_ref (GTK_OBJECT (item));
+
+  return TRUE;
+}
+
+/**
+ * gnome_dock_layout_get_item:
+ * @layout: A #GnomeDockLayout widget
+ * @item: The #GnomeDockItem to be retrieved
+ * 
+ * Description: Retrieve a layout item.
+ * 
+ * Returns: The retrieved #GnomeDockLayoutItem widget.
+ **/
+GnomeDockLayoutItem *
+gnome_dock_layout_get_item (GnomeDockLayout *layout,
+                            GnomeDockItem *item)
+{
+  GList *list;
+
+  list = find (layout, item, compare_item_by_pointer);
+
+  if (list == NULL)
+    return NULL;
+  else
+    return list->data;
+}
+
+/**
+ * gnome_dock_layout_get_item_by_name:
+ * @layout: A #GnomeDockLayout widget
+ * @name: Name of the item to be retrieved
+ * 
+ * Description: Retrieve the dock item named @name.
+ * 
+ * Returns: The named #GnomeDockLayoutItem widget.
+ **/
+GnomeDockLayoutItem *
+gnome_dock_layout_get_item_by_name (GnomeDockLayout *layout,
+                                    const gchar *name)
+{
+  GList *list;
+
+  list = find (layout, name, compare_item_by_name);
+
+  if (list == NULL)
+    return NULL;
+  else
+    return list->data;
+}
+
+/**
+ * gnome_dock_layout_remove_item:
+ * @layout: A #GnomeDockLayout widget
+ * @item: The #GnomeDockItem to be removed
+ * 
+ * Description: Remove the specified @item from @layout.
+ * 
+ * Returns: %TRUE if the operation succeeds, %FALSE if it fails.
+ **/
+gboolean
+gnome_dock_layout_remove_item (GnomeDockLayout *layout,
+                               GnomeDockItem *item)
+{
+  GList *list;
+
+  list = find (layout, item, compare_item_by_pointer);
+  if (list == NULL)
+    return FALSE;
+
+  remove_item (layout, list);
+
+  return TRUE;
+}
+
+/**
+ * gnome_dock_layout_remove_item_by_name:
+ * @layout: A #GnomeDockLayout widget
+ * @name: Name of the #GnomeDockItem to be removed
+ * 
+ * Description: Remove the item named @name from @layout.
+ * 
+ * Returns: %TRUE if the operation succeeds, %FALSE if it fails.
+ **/
+gboolean
+gnome_dock_layout_remove_item_by_name (GnomeDockLayout *layout,
+                                       const gchar *name)
+{
+  GList *list;
+
+  list = find (layout, name, compare_item_by_name);
+  if (list == NULL)
+    return FALSE;
+
+  remove_item (layout, list);
+
+  return TRUE;
+}
+
+
+
+/**
+ * gnome_dock_layout_add_to_dock:
+ * @layout: A #GnomeDockLayout widget
+ * @dock: The #GnomeDock widget the layout items must be added to
+ * 
+ * Description: Add all the items in @layout to the specified @dock.
+ * 
+ * Returns: %TRUE if the operation succeeds, %FALSE if it fails.
+ **/
+gboolean
+gnome_dock_layout_add_to_dock (GnomeDockLayout *layout,
+                               GnomeDock *dock)
+{
+  GnomeDockLayoutItem *item;
+  GList *lp;
+  GnomeDockPlacement last_placement;
+  gint last_band_num;
+
+  if (layout->items == NULL)
+    return FALSE;
+
+  layout->items = g_list_sort (layout->items, item_compare_func);
+
+  item = layout->items->data;
+
+  last_placement = GNOME_DOCK_FLOATING;
+  last_band_num = 0;
+
+  for (lp = layout->items; lp != NULL; lp = lp->next)
+    {
+      item = lp->data;
+
+      if (item->placement == GNOME_DOCK_FLOATING)
+        {
+          gnome_dock_add_floating_item (dock,
+                                        item->item,
+                                        item->position.floating.x,
+                                        item->position.floating.y,
+                                        item->position.floating.orientation);
+        }
+      else
+        {
+          gboolean need_new;
+
+          if (last_placement != item->placement
+              || last_band_num != item->position.docked.band_num)
+            need_new = TRUE;
+          else
+            need_new = FALSE;
+
+          gnome_dock_add_item (dock,
+                               item->item,
+                               item->placement,
+                               0,
+                               0,
+                               item->position.docked.offset,
+                               need_new);
+
+          last_band_num = item->position.docked.band_num;
+          last_placement = item->placement;
+        }
+
+      gtk_widget_show (GTK_WIDGET (item->item));
+    }
+
+  return TRUE;
+}
+
+
+
+/* Layout string functions.  */
+
+/**
+ * gnome_dock_layout_create_string:
+ * @layout: A #GnomeDockLayout widget
+ * 
+ * Description: Generate a string describing the layout in @layout.
+ * 
+ * Returns: The (malloced) layout string for @layout.
+ **/
+gchar *
+gnome_dock_layout_create_string (GnomeDockLayout *layout)
+{
+  GList *lp;
+  guint tmp_count, tmp_alloc;
+  gchar **tmp;
+  gchar *retval;
+
+  if (layout->items == NULL)
+    return NULL;
+
+  tmp_alloc = 512;
+  tmp = g_new (gchar *, tmp_alloc);
+
+  tmp_count = 0;
+
+  for (lp = layout->items; lp != NULL; lp = lp->next)
+    {
+      GnomeDockLayoutItem *i;
+
+      i = lp->data;
+
+      if (tmp_alloc - tmp_count <= 2)
+        {
+          tmp_alloc *= 2;
+          tmp = g_renew (char *, tmp, tmp_alloc);
+        }
+
+      if (i->placement == GNOME_DOCK_FLOATING)
+        tmp[tmp_count] = g_strdup_printf ("%s\\%d,%d,%d,%d",
+                                          i->item->name,
+                                          (gint) i->placement,
+                                          i->position.floating.x,
+                                          i->position.floating.y,
+                                          i->position.floating.orientation);
+      else
+        tmp[tmp_count] = g_strdup_printf ("%s\\%d,%d,%d,%d",
+                                          i->item->name,
+                                          (gint) i->placement,
+                                          i->position.docked.band_num,
+                                          i->position.docked.band_position,
+                                          i->position.docked.offset);
+
+      tmp_count++;
+    }
+
+  tmp[tmp_count] = 0;
+
+  retval = g_strjoinv ("\\", tmp);
+  g_strfreev (tmp);
+
+  return retval;
+}
+
+/**
+ * gnome_dock_layout_parse_string:
+ * @layout: A #GnomeDockLayout widget
+ * @string: A layout string to be parsed
+ * 
+ * Description: Parse the layout string @string, and move around the
+ * items in @layout accordingly.
+ * 
+ * Returns: %TRUE if the operation succeeds, %FALSE if it fails.
+ **/
+gboolean
+gnome_dock_layout_parse_string (GnomeDockLayout *layout,
+				const gchar *string)
+{
+  gchar **tmp, **p;
+
+  if (string == NULL)
+    return FALSE;
+
+  tmp = g_strsplit (string, "\\", 0);
+  if (tmp == NULL)
+    return FALSE;
+
+  p = tmp;
+  while (*p != NULL)
+    {
+      GList *lp;
+
+      if (*(p + 1) == NULL)
+        {
+          g_strfreev (tmp);
+          return FALSE;
+        }
+
+      lp = find (layout, *p, compare_item_by_name);
+
+      if (lp != NULL)
+        {
+          GnomeDockLayoutItem *i;
+          gint p1, p2, p3, p4;
+
+          if (sscanf (*(p + 1), "%d,%d,%d,%d", &p1, &p2, &p3, &p4) != 4)
+            {
+              g_strfreev (tmp);
+              return FALSE;
+            }
+
+          if (p1 != (gint) GNOME_DOCK_TOP
+              && p1 != (gint) GNOME_DOCK_BOTTOM
+              && p1 != (gint) GNOME_DOCK_LEFT
+              && p1 != (gint) GNOME_DOCK_RIGHT
+              && p1 != (gint) GNOME_DOCK_FLOATING)
+            return FALSE;
+          
+          i = lp->data;
+
+          i->placement = (GnomeDockPlacement) p1;
+
+          if (i->placement == GNOME_DOCK_FLOATING)
+            {
+              i->position.floating.x = p2;
+              i->position.floating.y = p3;
+              i->position.floating.orientation = p4;
+            }
+          else
+            {
+              i->position.docked.band_num = p2;
+              i->position.docked.band_position = p3;
+              i->position.docked.offset = p4;
+            }
+        }
+
+      p += 2;
+    }
+
+  g_strfreev (tmp);
+
+  return TRUE;
+}
diff --git a/libgnomeui/gnome-dock-layout.h b/libgnomeui/gnome-dock-layout.h
new file mode 100644
index 0000000..4e13475
--- /dev/null
+++ b/libgnomeui/gnome-dock-layout.h
@@ -0,0 +1,143 @@
+/*
+ * !!! MASTER CAUTION !!!!
+ *
+ * These files have been moved to libbonoboui and renamed to bonobo-dock*.[ch].
+ * We'll provide a compatibility wrapper with #defines in libgnomecompat soon, but
+ * at the moment I don't want to break the build here since libbonoboui doesn't work yet.
+ *
+ * If you do any changes in these files here, your work will be lost !
+ */
+
+/* WARNING ____ IMMATURE API ____ liable to change */
+
+/* gnome-dock-layout.c
+
+   Copyright (C) 1998 Free Software Foundation
+
+   All rights reserved.
+
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Ettore Perazzoli <ettore comm2000 it>
+*/
+/*
+  @NOTATION@
+*/
+
+#ifndef _GNOME_DOCK_LAYOUT_H
+#define _GNOME_DOCK_LAYOUT_H
+
+
+
+G_BEGIN_DECLS
+
+#define GNOME_TYPE_DOCK_LAYOUT            (gnome_dock_layout_get_type ())
+#define GNOME_DOCK_LAYOUT(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_DOCK_LAYOUT, GnomeDockLayout))
+#define GNOME_DOCK_LAYOUT_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_DOCK_LAYOUT, GnomeDockLayoutClass))
+#define GNOME_IS_DOCK_LAYOUT(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_DOCK_LAYOUT))
+#define GNOME_IS_DOCK_LAYOUT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_DOCK_LAYOUT))
+#define GNOME_DOCK_LAYOUT_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_DOCK_LAYOUT, GnomeDockLayoutClass))
+
+typedef struct _GnomeDockLayoutItem    GnomeDockLayoutItem;
+typedef struct _GnomeDockLayoutClass   GnomeDockLayoutClass;
+typedef struct _GnomeDockLayout        GnomeDockLayout;
+typedef struct _GnomeDockLayoutPrivate GnomeDockLayoutPrivate;
+
+#include "gnome-dock.h"
+#include "gnome-dock-item.h"
+
+struct _GnomeDockLayoutItem
+{
+  GnomeDockItem *item;
+
+  GnomeDockPlacement placement;
+
+  union
+  {
+    struct
+    {
+      gint x;
+      gint y;
+      GtkOrientation orientation;
+    } floating;
+
+    struct
+    {
+      gint band_num;
+      gint band_position;
+      gint offset;
+    } docked;
+
+  } position;
+};
+
+struct _GnomeDockLayout
+{
+  GtkObject object;
+
+  GList *items;                 /* GnomeDockLayoutItem */
+
+  /*< private >*/
+  GnomeDockLayoutPrivate *_priv;
+};
+
+struct _GnomeDockLayoutClass
+{
+  GtkObjectClass parent_class;
+};
+
+GnomeDockLayout     *gnome_dock_layout_new      (void);
+guint                gnome_dock_layout_get_type (void) G_GNUC_CONST;
+   
+gboolean             gnome_dock_layout_add_item (GnomeDockLayout *layout,
+                                                 GnomeDockItem *item,
+                                                 GnomeDockPlacement placement,
+                                                 gint band_num,
+                                                 gint band_position,
+                                                 gint offset);
+   
+gboolean             gnome_dock_layout_add_floating_item
+                                                (GnomeDockLayout *layout,
+                                                 GnomeDockItem *item,
+                                                 gint x, gint y,
+                                                 GtkOrientation orientation);
+
+GnomeDockLayoutItem *gnome_dock_layout_get_item (GnomeDockLayout *layout,
+                                                 GnomeDockItem *item);
+GnomeDockLayoutItem *gnome_dock_layout_get_item_by_name
+                                                (GnomeDockLayout *layout,
+                                                 const gchar *name);
+
+gboolean             gnome_dock_layout_remove_item
+                                                (GnomeDockLayout *layout,
+                                                 GnomeDockItem *item);
+gboolean             gnome_dock_layout_remove_item_by_name
+                                                (GnomeDockLayout *layout,
+                                                 const gchar *name);
+
+gchar               *gnome_dock_layout_create_string
+                                                (GnomeDockLayout *layout);
+gboolean             gnome_dock_layout_parse_string
+                                                (GnomeDockLayout *layout,
+                                                 const gchar *string);
+
+gboolean             gnome_dock_layout_add_to_dock
+                                                (GnomeDockLayout *layout,
+                                                 GnomeDock *dock);
+
+G_END_DECLS
+
+#endif
diff --git a/libgnomeui/gnome-dock.c b/libgnomeui/gnome-dock.c
new file mode 100644
index 0000000..1047c01
--- /dev/null
+++ b/libgnomeui/gnome-dock.c
@@ -0,0 +1,1616 @@
+/*
+ * !!! MASTER CAUTION !!!!
+ *
+ * These files have been moved to libbonoboui and renamed to bonobo-dock*.[ch].
+ * We'll provide a compatibility wrapper with #defines in libgnomecompat soon, but
+ * at the moment I don't want to break the build here since libbonoboui doesn't work yet.
+ *
+ * If you do any changes in these files here, your work will be lost !
+ */
+
+/* gnome-dock.c
+
+   Copyright (C) 1998 Free Software Foundation
+
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Ettore Perazzoli <ettore comm2000 it>
+*/
+/*
+  @NOTATION@
+*/
+
+#include <gtk/gtk.h>
+
+#include "gnome-dock.h"
+#include "gnome-dock-band.h"
+#include "gnome-dock-item.h"
+
+
+
+#define noGNOME_DOCK_DEBUG
+
+/* FIXME: To be removed.  */
+#if defined GNOME_DOCK_DEBUG && defined __GNUC__
+#define DEBUG(x)                                        \
+  do                                                    \
+    {                                                   \
+      printf ("%s.%d: ", __FUNCTION__, __LINE__);       \
+      printf x;                                         \
+      putchar ('\n');                                   \
+    }                                                   \
+  while (0)
+#else
+#define DEBUG(x)
+#endif
+
+
+
+struct _GnomeDockPrivate
+{
+	int dummy;
+	/* Nothing right now, needs to get filled with the private things */
+	/* XXX: When stuff is added, uncomment the allocation in the
+	 * gnome_dock_init function! */
+};
+
+
+enum {
+  LAYOUT_CHANGED,
+  LAST_SIGNAL
+};
+
+
+
+static void     gnome_dock_class_init          (GnomeDockClass *class);
+static void     gnome_dock_init                (GnomeDock *app);
+static void     gnome_dock_size_request        (GtkWidget *widget,
+                                                GtkRequisition *requisition);
+static void     gnome_dock_size_allocate       (GtkWidget *widget,
+                                                GtkAllocation *allocation);
+static void     gnome_dock_map                 (GtkWidget *widget);
+static void     gnome_dock_unmap               (GtkWidget *widget);
+static void     gnome_dock_add                 (GtkContainer *container,
+                                                GtkWidget *child);
+static void     gnome_dock_remove              (GtkContainer *container,
+                                                GtkWidget *widget);
+static void     gnome_dock_forall              (GtkContainer *container,
+                                                gboolean include_internals,
+                                                GtkCallback callback,
+                                                gpointer callback_data);
+static void     gnome_dock_destroy             (GtkObject *object);
+static void     gnome_dock_finalize            (GObject *object);
+
+static void     size_request_v                 (GList *list,
+                                                GtkRequisition *requisition);
+static void     size_request_h                 (GList *list,
+                                                GtkRequisition *requisition);
+static gint     size_allocate_v                (GList *list,
+                                                gint start_x, gint start_y,
+                                                guint width, gint direction);
+static gint     size_allocate_h                (GList *list,
+                                                gint start_x, gint start_y,
+                                                guint width, gint direction);
+static void     map_widget                     (GtkWidget *w);
+static void     map_widget_foreach             (gpointer data,
+                                                gpointer user_data);
+static void     map_band_list                  (GList *list);
+static void     unmap_widget                     (GtkWidget *w);
+static void     unmap_widget_foreach             (gpointer data,
+                                                gpointer user_data);
+static void     unmap_band_list                  (GList *list);
+static gboolean remove_from_band_list          (GList **list,
+                                                GnomeDockBand *child);
+static void     forall_helper                  (GList *list,
+                                                GtkCallback callback,
+                                                gpointer callback_data);
+
+static void     drag_begin                     (GtkWidget *widget,
+                                                gpointer data);
+static void     drag_end_bands                 (GList **list,
+                                                GnomeDockItem *item);
+static void     drag_end                       (GtkWidget *widget,
+                                                gpointer data);
+static gboolean drag_new                       (GnomeDock *dock,
+                                                GnomeDockItem *item,
+                                                GList **area,
+                                                GList *where,
+                                                gint x, gint y,
+                                                gboolean is_vertical);
+static gboolean drag_to                        (GnomeDock *dock,
+                                                GnomeDockItem *item,
+                                                GList *where,
+                                                gint x, gint y,
+                                                gboolean is_vertical);
+static gboolean drag_floating                  (GnomeDock *dock,
+                                                GnomeDockItem *item,
+                                                gint x, gint y,
+                                                gint rel_x, gint rel_y);
+static gboolean drag_check                     (GnomeDock *dock,
+                                                GnomeDockItem *item,
+                                                GList **area,
+                                                gint x, gint y,
+                                                gboolean is_vertical);
+static void     drag_snap                      (GnomeDock *dock,
+                                                GtkWidget *widget,
+                                                gint x, gint y);
+static void     drag_motion                    (GtkWidget *widget,
+                                                gint x, gint y,
+                                                gpointer data);
+
+static GnomeDockItem *get_docked_item_by_name  (GnomeDock *dock,
+                                                const gchar *name,
+                                                GnomeDockPlacement *placement_return,
+                                                guint *num_band_return,
+                                                guint *band_position_return,
+                                                guint *offset_return);
+static GnomeDockItem *get_floating_item_by_name (GnomeDock *dock,
+                                                 const gchar *name);
+
+static void           connect_drag_signals      (GnomeDock *dock,
+                                                 GtkWidget *item);
+
+
+static GtkWidgetClass *parent_class = NULL;
+
+static guint dock_signals[LAST_SIGNAL] = { 0 };
+
+
+
+static void
+gnome_dock_class_init (GnomeDockClass *class)
+{
+  GtkObjectClass *object_class;
+  GObjectClass *gobject_class;
+  GtkWidgetClass *widget_class;
+  GtkContainerClass *container_class;
+
+  object_class = (GtkObjectClass *) class;
+  gobject_class = (GObjectClass *) class;
+  widget_class = (GtkWidgetClass *) class;
+  container_class = (GtkContainerClass *) class;
+
+  parent_class = gtk_type_class (gtk_container_get_type ());
+
+  object_class->destroy = gnome_dock_destroy;
+  gobject_class->finalize = gnome_dock_finalize;
+
+  widget_class->size_request = gnome_dock_size_request;
+  widget_class->size_allocate = gnome_dock_size_allocate;
+  widget_class->map = gnome_dock_map;
+  widget_class->unmap = gnome_dock_unmap;
+
+  container_class->add = gnome_dock_add;
+  container_class->remove = gnome_dock_remove;
+  container_class->forall = gnome_dock_forall;
+
+  dock_signals[LAYOUT_CHANGED] =
+    gtk_signal_new ("layout_changed",
+                    GTK_RUN_LAST,
+                    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (GnomeDockClass, layout_changed),
+                    gtk_marshal_NONE__NONE,
+                    GTK_TYPE_NONE, 0);
+
+}
+
+static void
+gnome_dock_init (GnomeDock *dock)
+{
+  GTK_WIDGET_SET_FLAGS (GTK_WIDGET (dock), GTK_NO_WINDOW);
+
+  dock->_priv = NULL;
+  /* XXX: when there is some private stuff enable this
+  dock->_priv = g_new0(GnomeDockPrivate, 1);
+  */
+
+  dock->client_area = NULL;
+
+  dock->top_bands = NULL;
+  dock->bottom_bands = NULL;
+  dock->right_bands = NULL;
+  dock->left_bands = NULL;
+
+  dock->floating_children = NULL;
+
+  dock->floating_items_allowed = TRUE;
+}
+
+
+
+static void
+size_request_v (GList *list, GtkRequisition *requisition)
+{
+  for (; list != NULL; list = list->next)
+    {
+      GtkWidget *w;
+      GtkRequisition req;
+
+      w = GTK_WIDGET (list->data);
+      gtk_widget_size_request (w, &req);
+      requisition->width += req.width;
+      requisition->height = MAX (requisition->height, req.height);
+    }
+}
+
+static void
+size_request_h (GList *list, GtkRequisition *requisition)
+{
+  for (list = list; list != NULL; list = list->next)
+    {
+      GtkWidget *w;
+      GtkRequisition req;
+
+      w = GTK_WIDGET (list->data);
+      gtk_widget_size_request (w, &req);
+      requisition->height += req.height;
+      requisition->width = MAX (requisition->width, req.width);
+    }
+}
+
+static void
+gnome_dock_size_request (GtkWidget *widget, GtkRequisition *requisition)
+{
+  GnomeDock *dock;
+  GList *lp;
+
+  dock = GNOME_DOCK (widget);
+
+  if (dock->client_area != NULL && GTK_WIDGET_VISIBLE (dock->client_area))
+    gtk_widget_size_request (dock->client_area, requisition);
+  else
+    {
+      requisition->width = 0;
+      requisition->height = 0;
+    }
+
+  size_request_v (dock->left_bands, requisition);
+  size_request_v (dock->right_bands, requisition);
+  size_request_h (dock->top_bands, requisition);
+  size_request_h (dock->bottom_bands, requisition);
+
+  lp = dock->floating_children;
+  while (lp != NULL)
+    {
+      GtkWidget *w;
+      GtkRequisition float_item_requisition;
+
+      w = lp->data;
+      lp = lp->next;
+      gtk_widget_size_request (w, &float_item_requisition);
+    }
+}
+
+
+
+static gint
+size_allocate_h (GList *list, gint start_x, gint start_y, guint width,
+                 gint direction)
+{
+  GtkAllocation allocation;
+
+  allocation.x = start_x;
+  allocation.y = start_y;
+  allocation.width = width;
+
+  if (direction < 0)
+    list = g_list_last (list);
+  while (list != NULL)
+    {
+      GtkWidget *w;
+
+      w = GTK_WIDGET (list->data);
+      allocation.height = w->requisition.height;
+
+      if (direction > 0)
+        {
+          gtk_widget_size_allocate (w, &allocation);
+          allocation.y += allocation.height;
+          list = list->next;
+        }
+      else
+        {
+          allocation.y -= allocation.height;
+          gtk_widget_size_allocate (w, &allocation);
+          list = list->prev;
+        }
+    }
+
+  return allocation.y;
+}
+
+static gint
+size_allocate_v (GList *list, gint start_x, gint start_y, guint height,
+                 gint direction)
+{
+  GtkAllocation allocation;
+
+  allocation.x = start_x;
+  allocation.y = start_y;
+  allocation.height = height;
+
+  if (direction < 0)
+    list = g_list_last (list);
+
+  while (list != NULL)
+    {
+      GtkWidget *w;
+
+      w = GTK_WIDGET (list->data);
+      allocation.width = w->requisition.width;
+
+      if (direction > 0)
+        {
+          gtk_widget_size_allocate (w, &allocation);
+          allocation.x += allocation.width;
+          list = list->next;
+        }
+      else
+        {
+          allocation.x -= allocation.width;
+          gtk_widget_size_allocate (w, &allocation);
+          list = list->prev;
+        }
+    }
+
+  return allocation.x;
+}
+
+static void
+gnome_dock_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
+{
+  GnomeDock *dock;
+  gint top_bands_y, bottom_bands_y;
+  gint left_bands_x, right_bands_x;
+  GtkAllocation child_allocation;
+  GList *lp;
+
+  dock = GNOME_DOCK (widget);
+
+  widget->allocation = *allocation;
+
+  top_bands_y = size_allocate_h (dock->top_bands,
+                                 allocation->x,
+                                 allocation->y,
+                                 allocation->width,
+                                 +1);
+
+  bottom_bands_y = size_allocate_h (dock->bottom_bands,
+                                    allocation->x,
+                                    allocation->y + allocation->height,
+                                    allocation->width,
+                                    -1);
+
+  child_allocation.height = MAX (bottom_bands_y - top_bands_y, 1);
+
+  left_bands_x = size_allocate_v (dock->left_bands,
+                                  allocation->x,
+                                  top_bands_y,
+                                  child_allocation.height,
+                                  +1);
+
+  right_bands_x = size_allocate_v (dock->right_bands,
+                                   allocation->x + allocation->width,
+                                   top_bands_y,
+                                   child_allocation.height,
+                                   -1);
+
+  child_allocation.width = MAX (right_bands_x - left_bands_x, 1);
+
+  child_allocation.x = left_bands_x;
+  child_allocation.y = top_bands_y;
+
+  dock->client_rect = child_allocation;
+
+  if (dock->client_area != NULL && GTK_WIDGET_VISIBLE (dock->client_area))
+    gtk_widget_size_allocate (dock->client_area, &child_allocation);
+
+  lp = dock->floating_children;
+  while (lp != NULL)
+    {
+      GtkWidget *w;
+      GtkAllocation float_item_allocation;
+
+      w = lp->data;
+      lp = lp->next;
+      float_item_allocation.x = 0;
+      float_item_allocation.y = 0;
+      float_item_allocation.width = w->requisition.width;
+      float_item_allocation.height = w->requisition.height;
+      gtk_widget_size_allocate (w, &float_item_allocation);
+    }
+}
+
+
+
+static void
+map_widget (GtkWidget *w)
+{
+  if (w != NULL && GTK_WIDGET_VISIBLE (w) && ! GTK_WIDGET_MAPPED (w))
+    gtk_widget_map (w);
+}
+
+static void
+unmap_widget (GtkWidget *w)
+{
+  if (w != NULL && GTK_WIDGET_VISIBLE (w) && GTK_WIDGET_MAPPED (w))
+    gtk_widget_unmap (w);
+}
+
+static void
+map_widget_foreach (gpointer data,
+                    gpointer user_data)
+{
+  map_widget (GTK_WIDGET (data));
+}
+
+static void
+unmap_widget_foreach (gpointer data,
+                      gpointer user_data)
+{
+  unmap_widget (GTK_WIDGET (data));
+}
+
+static void
+map_band_list (GList *list)
+{
+  while (list != NULL)
+    {
+      GtkWidget *w;
+
+      w = GTK_WIDGET (list->data);
+      map_widget (w);
+
+      list = list->next;
+    }
+}
+
+static void
+unmap_band_list (GList *list)
+{
+  while (list != NULL)
+    {
+      GtkWidget *w;
+
+      w = GTK_WIDGET (list->data);
+      unmap_widget (w);
+
+      list = list->next;
+    }
+}
+
+static void
+gnome_dock_map (GtkWidget *widget)
+{
+  GnomeDock *dock;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GNOME_IS_DOCK(widget));
+
+  if (GTK_WIDGET_CLASS (parent_class)->map != NULL)
+    (* GTK_WIDGET_CLASS (parent_class)->map) (widget);
+
+  dock = GNOME_DOCK (widget);
+
+  map_widget (dock->client_area);
+
+  map_band_list (dock->top_bands);
+  map_band_list (dock->bottom_bands);
+  map_band_list (dock->left_bands);
+  map_band_list (dock->right_bands);
+
+  g_list_foreach (dock->floating_children, map_widget_foreach, NULL);
+}
+
+static void
+gnome_dock_unmap (GtkWidget *widget)
+{
+  GnomeDock *dock;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GNOME_IS_DOCK(widget));
+
+  dock = GNOME_DOCK (widget);
+
+  unmap_widget (dock->client_area);
+
+  unmap_band_list (dock->top_bands);
+  unmap_band_list (dock->bottom_bands);
+  unmap_band_list (dock->left_bands);
+  unmap_band_list (dock->right_bands);
+
+  g_list_foreach (dock->floating_children, unmap_widget_foreach, NULL);
+
+  if (GTK_WIDGET_CLASS (parent_class)->unmap != NULL)
+    (* GTK_WIDGET_CLASS (parent_class)->unmap) (widget);
+}
+
+
+
+/* GtkContainer methods.  */
+
+static void
+gnome_dock_add (GtkContainer *container, GtkWidget *child)
+{
+  GnomeDock *dock;
+
+  dock = GNOME_DOCK (container);
+  gnome_dock_add_item (dock, GNOME_DOCK_ITEM(child), GNOME_DOCK_TOP, 0, 0, 0, TRUE);
+}
+
+static gboolean
+remove_from_band_list (GList **list, GnomeDockBand *child)
+{
+  GList *lp;
+
+  for (lp = *list; lp != NULL; lp = lp->next)
+    {
+      if (lp->data == child)
+        {
+          gtk_widget_unparent (GTK_WIDGET (child));
+          *list = g_list_remove_link (*list, lp);
+          g_list_free (lp);
+
+          return TRUE;
+        }
+    }
+
+  return FALSE;
+}
+
+static void
+gnome_dock_remove (GtkContainer *container, GtkWidget *widget)
+{
+  GnomeDock *dock;
+
+  dock = GNOME_DOCK (container);
+
+  if (dock->client_area == widget)
+    {
+      gtk_widget_unparent (widget);
+      dock->client_area = NULL;
+      gtk_widget_queue_resize (GTK_WIDGET (dock));
+    }
+  else
+    {
+      /* Check if it's a floating child.  */
+      {
+        GList *lp;
+
+        lp = dock->floating_children;
+        while (lp != NULL)
+          {
+            GtkWidget *w;
+
+            w = lp->data;
+            if (w == widget)
+              {
+                gtk_widget_unparent (w);
+                dock->floating_children
+                  = g_list_remove_link (dock->floating_children, lp);
+                g_list_free (lp);
+                return;
+              }
+
+            lp = lp->next;
+          }
+      }
+
+      /* Then it must be one of the bands.  */
+      {
+        GnomeDockBand *band;
+
+        g_return_if_fail (GNOME_IS_DOCK_BAND (widget));
+
+        band = GNOME_DOCK_BAND (widget);
+        if (remove_from_band_list (&dock->top_bands, band)
+            || remove_from_band_list (&dock->bottom_bands, band)
+            || remove_from_band_list (&dock->left_bands, band)
+            || remove_from_band_list (&dock->right_bands, band))
+          {
+            gtk_widget_queue_resize (GTK_WIDGET (dock));
+            return;
+          }
+      }
+    }
+}
+
+static void
+forall_helper (GList *list,
+               GtkCallback callback,
+               gpointer callback_data)
+{
+  while (list != NULL)
+    {
+      GtkWidget *w;
+
+      w = GTK_WIDGET(list->data);
+      list = list->next;
+      (* callback) (w, callback_data);
+    }
+}
+
+static void
+gnome_dock_forall (GtkContainer *container,
+                   gboolean include_internals,
+                   GtkCallback callback,
+                   gpointer callback_data)
+{
+  GnomeDock *dock;
+  GList *lp;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GNOME_IS_DOCK (container));
+  g_return_if_fail (callback != NULL);
+
+  dock = GNOME_DOCK (container);
+
+  forall_helper (dock->top_bands, callback, callback_data);
+  forall_helper (dock->bottom_bands, callback, callback_data);
+  forall_helper (dock->left_bands, callback, callback_data);
+  forall_helper (dock->right_bands, callback, callback_data);
+
+  lp = dock->floating_children;
+  while (lp != NULL)
+    {
+      GtkWidget *w;
+
+      w = lp->data;
+      lp = lp->next;
+      (* callback) (w, callback_data);
+    }
+
+  if (dock->client_area != NULL)
+    (* callback) (dock->client_area, callback_data);
+}
+
+static void
+gnome_dock_destroy (GtkObject *object)
+{
+  /* remember, destroy can be run multiple times! */
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gnome_dock_finalize (GObject *object)
+{
+  GnomeDock *self = GNOME_DOCK (object);
+
+  g_free (self->_priv);
+  self->_priv = NULL;
+
+  if (G_OBJECT_CLASS (parent_class)->finalize)
+    (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+
+
+/* When an item is being dragged, there can be 3 situations:
+
+   (I)   A new band is created and the item is docked to it.
+
+   (II)  The item is docked to an existing band.
+
+   (III) The item must be floating, so it has to be detached if
+         currently not floating, and moved around in its own window.  */
+
+/* Case (I): Dock `item' into a new band next to `where' in the
+   docking area `area'.  If `where' is NULL, the band becomes the
+   first one in `area'.  */
+static gboolean
+drag_new (GnomeDock *dock,
+          GnomeDockItem *item,
+          GList **area,
+          GList *where,
+          gint x, gint y,
+          gboolean is_vertical)
+{
+  GnomeDockBand *new_band;
+  GList *next;
+
+  DEBUG (("entering function"));
+
+  new_band = NULL;
+
+  /* We need a new band next to `where', but we try to re-use the band
+     next to it if either it contains no children, or it only contains
+     `item'.  */
+
+  next = NULL;
+  if (where == NULL && area != NULL)
+    next = *area;
+  else
+    next = where->next;
+  if (next != NULL)
+    {
+      GnomeDockBand *band;
+      guint num_children;
+
+      band = GNOME_DOCK_BAND (next->data);
+
+      num_children = gnome_dock_band_get_num_children (band);
+
+      if (num_children == 0
+          || (num_children == 1
+              && GTK_WIDGET (band) == GTK_WIDGET (item)->parent))
+        new_band = GNOME_DOCK_BAND (next->data);
+    }
+
+  /* Create the new band and make it our child if we cannot re-use an
+     existing one.  */
+  if (new_band == NULL)
+    {
+      new_band = GNOME_DOCK_BAND (gnome_dock_band_new ());
+      gnome_dock_band_set_orientation (new_band,
+                                       (is_vertical
+                                        ? GTK_ORIENTATION_VERTICAL
+                                        : GTK_ORIENTATION_HORIZONTAL));
+
+      /* This is mostly to remember that `drag_allocation' for this
+         child is bogus, as it was not previously allocated.  */
+      new_band->new_for_drag = TRUE;
+
+      if (where == NULL)
+        *area = where = g_list_prepend (*area, new_band);
+      else if (where->next == NULL)
+        g_list_append (where, new_band);
+      else
+        g_list_prepend (where->next, new_band);
+
+      gtk_widget_set_parent (GTK_WIDGET (new_band), GTK_WIDGET (dock));
+      gtk_widget_queue_resize (GTK_WIDGET (new_band));
+      gtk_widget_show (GTK_WIDGET (new_band));
+    }
+
+  /* Move the item to the new band.  (This is a no-op if we are using
+     `where->next' and it already contains `item'.)  */
+  gnome_dock_item_attach (item, GTK_WIDGET (new_band), x, y);
+
+  /* Prepare the band for dragging of `item'.  */
+  gnome_dock_band_drag_begin (new_band, item);
+
+  /* Set the offset of `item' in the band.  */
+  if (is_vertical)
+    gnome_dock_band_set_child_offset (new_band, GTK_WIDGET (item),
+                                      MAX (y - dock->client_rect.y, 0));
+  else
+    gnome_dock_band_set_child_offset (new_band, GTK_WIDGET (item),
+                                      MAX (x - GTK_WIDGET (dock)->allocation.x, 0));
+
+  return TRUE;
+}
+
+/* Case (II): Drag into an existing band.  */
+static gboolean
+drag_to (GnomeDock *dock,
+         GnomeDockItem *item,
+         GList *where,
+         gint x, gint y,
+         gboolean is_vertical)
+{
+  DEBUG (("x %d y %d", x, y));
+
+  return gnome_dock_band_drag_to (GNOME_DOCK_BAND (where->data), item, x, y);
+}
+
+/* Case (III): Move a floating (i.e. floating) item.  */
+static gboolean
+drag_floating (GnomeDock *dock,
+               GnomeDockItem *item,
+               gint x,
+               gint y,
+               gint rel_x,
+               gint rel_y)
+{
+  GtkWidget *item_widget, *dock_widget;
+
+  item_widget = GTK_WIDGET (item);
+  dock_widget = GTK_WIDGET (dock);
+
+  if (item_widget->parent != dock_widget)
+    {
+      GtkAllocation *dock_allocation, *client_allocation;
+
+      /* The item is currently not floating (so it is not our child).
+         Make it so if we are outside the docking areas.  */
+
+      dock_allocation = &dock_widget->allocation;
+      if (dock->client_area)
+        client_allocation = &dock->client_area->allocation;
+      else
+        client_allocation = NULL;
+
+      if (rel_x < 0
+          || rel_x >= dock_allocation->width
+          || rel_y < 0
+          || rel_y >= dock_allocation->height
+          || (client_allocation != NULL
+              && rel_x >= client_allocation->x
+              && rel_x < client_allocation->x + client_allocation->width
+              && rel_y >= client_allocation->y
+              && rel_y < client_allocation->y + client_allocation->height))
+        {
+          gtk_widget_ref (item_widget);
+
+          gtk_container_remove (GTK_CONTAINER (item_widget->parent),
+                                item_widget);
+          gtk_widget_set_parent (item_widget, dock_widget);
+
+          dock->floating_children = g_list_prepend (dock->floating_children,
+                                                    item);
+
+	  gtk_widget_realize (item_widget);
+	  gtk_widget_map (item_widget);
+	  gtk_widget_queue_resize (item_widget);
+
+	  gnome_dock_item_detach (item, x, y);
+          if (item->in_drag)
+            gnome_dock_item_grab_pointer (item);
+
+          gtk_widget_unref (item_widget);
+        }
+    }
+  else
+    {
+      /* The item is already floating; all we have to do is move it to
+         the current dragging position.  */
+      gnome_dock_item_drag_floating (item, x, y);
+    }
+
+  return TRUE;
+}
+
+
+
+/* Check if `item' can be docked to any of the DockBands of the dock
+   area `area'.  If so, dock it and return TRUE; otherwise, return
+   FALSE.  */
+static gboolean
+drag_check (GnomeDock *dock,
+            GnomeDockItem *item,
+            GList **area,
+            gint x, gint y,
+            gboolean is_vertical)
+{
+  GList *lp;
+  GtkAllocation *alloc;
+
+  for (lp = *area; lp != NULL; lp = lp->next)
+    {
+      GnomeDockBand *band;
+
+      band = GNOME_DOCK_BAND (lp->data);
+
+      if (! band->new_for_drag)
+        {
+          alloc = &band->drag_allocation;
+
+          if (x >= alloc->x - 10 && x < alloc->x + alloc->width
+              && y >= alloc->y && y < alloc->y + alloc->height)
+            {
+              if (is_vertical)
+                {
+                  if (x < alloc->x + alloc->width / 2
+                      && drag_to (dock, item, lp, x, y, TRUE))
+                    return TRUE;
+                  else
+                    return drag_new (dock, item, area, lp, x, y, TRUE);
+                }
+              else
+                {
+                  if (y < alloc->y + alloc->height / 2
+                      && drag_to (dock, item, lp, x, y, FALSE))
+                    return TRUE;
+                  else
+                    return drag_new (dock, item, area, lp, x, y, FALSE);
+                }
+            }
+        }
+    }
+
+  return FALSE;
+}
+
+/* Snap the GnomeDockItem `widget' to `dock' at the specified
+   position.  */
+static void
+drag_snap (GnomeDock *dock,
+           GtkWidget *widget,
+           gint x, gint y)
+{
+#define SNAP 50
+  GnomeDockItem *item;
+  GnomeDockItemBehavior item_behavior;
+  gint win_x, win_y;
+  gint rel_x, rel_y;
+  gboolean item_allows_horizontal, item_allows_vertical;
+
+  item = GNOME_DOCK_ITEM (widget);
+
+  item_behavior = gnome_dock_item_get_behavior (item);
+  item_allows_horizontal = ! (item_behavior
+                              & GNOME_DOCK_ITEM_BEH_NEVER_HORIZONTAL);
+  item_allows_vertical = ! (item_behavior
+                            & GNOME_DOCK_ITEM_BEH_NEVER_VERTICAL);
+
+  gdk_window_get_origin (GTK_WIDGET (dock)->window, &win_x, &win_y);
+  rel_x = x - win_x;
+  rel_y = y - win_y;
+
+  DEBUG (("(%d,%d)", x, y));
+  DEBUG (("relative (%d,%d)", rel_x, rel_y));
+
+  if (item_allows_horizontal
+      && rel_x >= 0 && rel_x < GTK_WIDGET (dock)->allocation.width)
+    {
+      /* Check prepending to top/bottom bands.  */
+      if (rel_y < 0 && rel_y >= -SNAP
+          && drag_new (dock, item, &dock->top_bands, NULL,
+                       rel_x, rel_y, FALSE))
+        return;
+      else if (rel_y >= dock->client_rect.y + dock->client_rect.height - SNAP
+               && rel_y < dock->client_rect.y + dock->client_rect.height
+               && drag_new (dock, item, &dock->bottom_bands, NULL,
+                            rel_x, rel_y, FALSE))
+        return;
+    }
+
+  if (item_allows_vertical
+      && rel_y >= dock->client_rect.y
+      && rel_y < dock->client_rect.y + dock->client_rect.height)
+    {
+      /* Check prepending to left/right bands.  */
+      if (rel_x < 0 && rel_x >= -SNAP
+          && drag_new (dock, item, &dock->left_bands, NULL,
+                       rel_x, rel_y, TRUE))
+        return;
+      else if (rel_x >= dock->client_rect.x + dock->client_rect.width - SNAP
+               && rel_x < dock->client_rect.x + dock->client_rect.width
+               && drag_new (dock, item, &dock->right_bands, NULL,
+                            rel_x, rel_y, TRUE))
+        return;
+    }
+
+  /* Check dragging into bands.  */
+  if (item_allows_horizontal
+      && drag_check (dock, item, &dock->top_bands, rel_x, rel_y, FALSE))
+    return;
+  else if (item_allows_horizontal
+           && drag_check (dock, item, &dock->bottom_bands, rel_x, rel_y, FALSE))
+    return;
+  else if (item_allows_vertical
+           && drag_check (dock, item, &dock->left_bands, rel_x, rel_y, TRUE))
+    return;
+  else if (item_allows_vertical
+           && drag_check (dock, item, &dock->right_bands, rel_x, rel_y, TRUE))
+    return;
+
+  /* We are not in any "interesting" area: the item must be floating
+     if allowed to.  */
+  if (dock->floating_items_allowed
+      && ! (item_behavior & GNOME_DOCK_ITEM_BEH_NEVER_DETACH))
+    drag_floating (dock, item, x, y, rel_x, rel_y);
+
+  /* If still not floating, fall back to moving the item in its own
+     band.  */
+  if (! item->is_floating)
+    gnome_dock_band_drag_to (GNOME_DOCK_BAND (GTK_WIDGET (item)->parent),
+                             item, rel_x, rel_y);
+}
+
+
+
+/* "drag_begin" signal handling.  */
+static void
+drag_begin (GtkWidget *widget, gpointer data)
+{
+  GnomeDock *dock;
+  GnomeDockItem *item;
+
+  DEBUG (("entering function"));
+
+  dock = GNOME_DOCK (data);
+  item = GNOME_DOCK_ITEM (widget);
+
+  /* Communicate all the bands that `widget' is currently being
+     dragged.  */
+  g_list_foreach (dock->top_bands, (GFunc) gnome_dock_band_drag_begin, item);
+  g_list_foreach (dock->bottom_bands, (GFunc) gnome_dock_band_drag_begin, item);
+  g_list_foreach (dock->right_bands, (GFunc) gnome_dock_band_drag_begin, item);
+  g_list_foreach (dock->left_bands, (GFunc) gnome_dock_band_drag_begin, item);
+}
+
+
+
+/* "drag_end" signal handling.  */
+
+static void
+drag_end_bands (GList **list, GnomeDockItem *item)
+{
+  GList *lp;
+  GnomeDockBand *band;
+
+  lp = *list;
+  while (lp != NULL)
+    {
+      band = GNOME_DOCK_BAND(lp->data);
+      gnome_dock_band_drag_end (band, item);
+
+      if (gnome_dock_band_get_num_children (band) == 0)
+        {
+          GList *next;
+
+          next = lp->next;
+
+          /* This will remove this link, too.  */
+          gtk_widget_destroy (GTK_WIDGET (band));
+
+          lp = next;
+        }
+      else
+        lp = lp->next;
+    }
+}
+
+static void
+drag_end (GtkWidget *widget, gpointer data)
+{
+  GnomeDockItem *item;
+  GnomeDock *dock;
+
+  DEBUG (("entering function"));
+
+  item = GNOME_DOCK_ITEM (widget);
+  dock = GNOME_DOCK (data);
+
+  /* Communicate to all the bands that `item' is no longer being
+     dragged.  */
+  drag_end_bands (&dock->top_bands, item);
+  drag_end_bands (&dock->bottom_bands, item);
+  drag_end_bands (&dock->left_bands, item);
+  drag_end_bands (&dock->right_bands, item);
+
+  gtk_signal_emit (GTK_OBJECT (data), dock_signals[LAYOUT_CHANGED]);
+}
+
+
+
+/* "drag_motion" signal handling.  */
+
+/* Handle a drag motion on the GnomeDockItem `widget'.  This is
+   connected to the "drag_motion" of all the children being added to
+   the GnomeDock, and tries to dock the dragged item at the current
+   (`x', `y') position of the pointer.  */
+static void
+drag_motion (GtkWidget *widget,
+             gint x, gint y,
+             gpointer data)
+{
+  drag_snap (GNOME_DOCK (data), widget, x, y);
+}
+
+
+
+static GnomeDockItem *
+get_docked_item_by_name (GnomeDock *dock,
+                         const gchar *name,
+                         GnomeDockPlacement *placement_return,
+                         guint *num_band_return,
+                         guint *band_position_return,
+                         guint *offset_return)
+{
+  {
+    struct
+    {
+      GList *band_list;
+      GnomeDockPlacement placement;
+    }
+    areas[] =
+    {
+      { NULL, GNOME_DOCK_TOP },
+      { NULL, GNOME_DOCK_BOTTOM },
+      { NULL, GNOME_DOCK_LEFT },
+      { NULL, GNOME_DOCK_RIGHT },
+      { NULL, GNOME_DOCK_FLOATING },
+    };
+    GList *lp;
+    guint i;
+
+    areas[0].band_list = dock->top_bands;
+    areas[1].band_list = dock->bottom_bands;
+    areas[2].band_list = dock->left_bands;
+    areas[3].band_list = dock->right_bands;
+
+    for (i = 0; i < 4; i++)
+      {
+        guint num_band;
+
+        for (lp = areas[i].band_list, num_band = 0;
+             lp != NULL;
+             lp = lp->next, num_band++)
+          {
+            GnomeDockBand *band;
+            GnomeDockItem *item;
+
+            band = GNOME_DOCK_BAND(lp->data);
+            item = gnome_dock_band_get_item_by_name (band,
+                                                     name,
+                                                     band_position_return,
+                                                     offset_return);
+            if (item != NULL)
+              {
+                if (num_band_return != NULL)
+                  *num_band_return = num_band;
+                if (placement_return != NULL)
+                  *placement_return = areas[i].placement;
+
+                return item;
+              }
+          }
+      }
+  }
+
+  return NULL;
+}
+
+static GnomeDockItem *
+get_floating_item_by_name (GnomeDock *dock,
+                           const gchar *name)
+{
+  GList *lp;
+  GnomeDockItem *item;
+
+  for (lp = dock->floating_children; lp != NULL; lp = lp->next)
+    {
+      item = lp->data;
+      if (strcmp (item->name, name) == 0)
+        return item;
+    }
+
+  return NULL;
+}
+
+static void
+connect_drag_signals (GnomeDock *dock,
+                      GtkWidget *item)
+{
+  if (GNOME_IS_DOCK_ITEM (item))
+    {
+      DEBUG (("here"));
+      gtk_signal_connect (GTK_OBJECT (item), "dock_drag_begin",
+                          GTK_SIGNAL_FUNC (drag_begin), (gpointer) dock);
+      gtk_signal_connect (GTK_OBJECT (item), "dock_drag_motion",
+                          GTK_SIGNAL_FUNC (drag_motion), (gpointer) dock);
+      gtk_signal_connect (GTK_OBJECT (item), "dock_drag_end",
+                          GTK_SIGNAL_FUNC (drag_end), (gpointer) dock);
+    }
+}
+
+
+
+GtkType
+gnome_dock_get_type (void)
+{
+  static GtkType dock_type = 0;
+
+  if (dock_type == 0)
+    {
+      GtkTypeInfo dock_info =
+      {
+	"GnomeDock",
+	sizeof (GnomeDock),
+	sizeof (GnomeDockClass),
+	(GtkClassInitFunc) gnome_dock_class_init,
+	(GtkObjectInitFunc) gnome_dock_init,
+        /* reserved_1 */ NULL,
+	/* reserved_2 */ NULL,
+	(GtkClassInitFunc) NULL,
+      };
+
+      dock_type = gtk_type_unique (gtk_container_get_type (), &dock_info);
+    }
+
+  return dock_type;
+}
+
+/**
+ * gnome_dock_new:
+ *
+ * Description: Creates a new #GnomeDock widget.
+ *
+ * Return value: The new widget.
+ **/
+GtkWidget *
+gnome_dock_new (void)
+{
+  GnomeDock *dock;
+  GtkWidget *widget;
+
+  dock = gtk_type_new (gnome_dock_get_type ());
+  widget = GTK_WIDGET (dock);
+
+#if 0                           /* FIXME: should I? */
+  if (GTK_WIDGET_VISIBLE (widget))
+    gtk_widget_queue_resize (widget);
+#endif
+
+  return widget;
+}
+
+/**
+ * gnome_dock_allow_floating_items:
+ * @dock: A pointer to a #GnomeDock widget
+ * @enable: Specifies whether floating items are allowed in this dock
+ *
+ * Description: Enable or disable floating items on @dock, according
+ * to @enable.
+ **/
+void
+gnome_dock_allow_floating_items (GnomeDock *dock,
+                                 gboolean enable)
+{
+  dock->floating_items_allowed = enable;
+}
+
+/**
+ * gnome_dock_add_item:
+ * @dock: A pointer to a #GnomeDock widget
+ * @item: The item to add
+ * @placement: Placement for the new item
+ * @band_num: Number of the band the new item must be added to
+ * @position: Position of the item in the specified band
+ * @offset: Offset (in pixels) from the previous item in the same band
+ * @in_new_band: Specifies whether a new band must be created for this item
+ *
+ * Description: Add @item to @dock.  @placement can be either
+ * %GNOME_DOCK_TOP, %GNOME_DOCK_RIGHT, %GNOME_DOCK_BOTTOM or
+ * %GNOME_DOCK_LEFT, and specifies what area of the dock should
+ * contain the item.  If @in_new_band is %TRUE, a new dock band is
+ * created at the position specified by @band_num; otherwise, the item
+ * is added to the @band_num'th band.
+ **/
+void
+gnome_dock_add_item (GnomeDock *dock,
+                     GnomeDockItem *item,
+                     GnomeDockPlacement placement,
+                     guint band_num,
+                     gint position,
+                     guint offset,
+                     gboolean in_new_band)
+{
+  GnomeDockBand *band;
+  GList **band_ptr;
+  GList *p;
+
+  DEBUG (("band_num %d offset %d position %d in_new_band %d",
+          band_num, offset, position, in_new_band));
+
+  switch (placement)
+    {
+    case GNOME_DOCK_TOP:
+      band_ptr = &dock->top_bands;
+      break;
+    case GNOME_DOCK_BOTTOM:
+      band_ptr = &dock->bottom_bands;
+      break;
+    case GNOME_DOCK_LEFT:
+      band_ptr = &dock->left_bands;
+      break;
+    case GNOME_DOCK_RIGHT:
+      band_ptr = &dock->right_bands;
+      break;
+    case GNOME_DOCK_FLOATING:
+      g_warning ("Floating dock items not supported by `gnome_dock_add_item'.");
+      return;
+    default:
+      g_error ("Unknown dock placement.");
+      return;
+    }
+
+  p = g_list_nth (*band_ptr, band_num);
+  if (in_new_band || p == NULL)
+    {
+      GtkWidget *new_band;
+
+      new_band = gnome_dock_band_new ();
+
+      /* FIXME: slow.  */
+      if (in_new_band)
+        {
+          *band_ptr = g_list_insert (*band_ptr, new_band, band_num);
+          p = g_list_nth (*band_ptr, band_num);
+          if (p == NULL)
+            p = g_list_last (*band_ptr);
+        }
+      else
+        {
+          *band_ptr = g_list_append (*band_ptr, new_band);
+          p = g_list_last (*band_ptr);
+        }
+
+      if (placement == GNOME_DOCK_TOP || placement == GNOME_DOCK_BOTTOM)
+        gnome_dock_band_set_orientation (GNOME_DOCK_BAND (new_band),
+                                         GTK_ORIENTATION_HORIZONTAL);
+      else
+        gnome_dock_band_set_orientation (GNOME_DOCK_BAND (new_band),
+                                         GTK_ORIENTATION_VERTICAL);
+
+      gtk_widget_set_parent (new_band, GTK_WIDGET (dock));
+      gtk_widget_show (new_band);
+      gtk_widget_queue_resize (GTK_WIDGET (dock));
+    }
+
+  band = GNOME_DOCK_BAND (p->data);
+  gnome_dock_band_insert (band, GTK_WIDGET(item), offset, position);
+
+  connect_drag_signals (dock, GTK_WIDGET(item));
+
+  gtk_signal_emit (GTK_OBJECT (dock), dock_signals[LAYOUT_CHANGED]);
+}
+
+/**
+ * gnome_dock_add_floating_item:
+ * @dock: A #GnomeDock widget
+ * @item: The item to be added
+ * @x: X-coordinate for the floating item
+ * @y: Y-coordinate for the floating item
+ * @orientation: Orientation for the new item.
+ *
+ * Description: Add @item to @dock and make it floating at the
+ * specified (@x, @y) coordinates (relative to the root window of the
+ * screen).
+ **/
+void
+gnome_dock_add_floating_item (GnomeDock *dock,
+                              GnomeDockItem *item,
+                              gint x, gint y,
+                              GtkOrientation orientation)
+{
+  GtkWidget *widget;
+
+  g_return_if_fail (GNOME_IS_DOCK_ITEM (item));
+
+  gnome_dock_item_set_orientation (item, orientation);
+
+  widget = GTK_WIDGET(item);
+  gtk_widget_ref (widget);
+
+#if 0
+  if (widget->parent != NULL)
+      gtk_container_remove (GTK_CONTAINER (widget->parent), widget);
+#endif
+
+  gtk_widget_set_parent (widget, GTK_WIDGET (dock));
+
+  if (GTK_WIDGET_REALIZED (widget->parent))
+    gtk_widget_realize (widget);
+
+  if (GTK_WIDGET_VISIBLE (widget->parent) && GTK_WIDGET_VISIBLE (widget))
+    {
+      if (GTK_WIDGET_MAPPED (widget->parent))
+	gtk_widget_map (widget);
+
+      gtk_widget_queue_resize (widget);
+    }
+
+  gnome_dock_item_detach (item, x, y);
+  dock->floating_children = g_list_prepend (dock->floating_children, widget);
+
+  connect_drag_signals (dock, widget);
+
+  gtk_widget_unref (widget);
+
+  gtk_signal_emit (GTK_OBJECT (dock), dock_signals[LAYOUT_CHANGED]);
+}
+
+/**
+ * gnome_dock_set_client_area:
+ * @dock: A #GnomeDock widget
+ * @widget: The widget to be used for the client area.
+ *
+ * Description: Specify a widget for the dock's client area.
+ **/
+void
+gnome_dock_set_client_area (GnomeDock *dock, GtkWidget *widget)
+{
+  g_return_if_fail (dock != NULL);
+
+  if (widget != NULL)
+    gtk_widget_ref (widget);
+
+  if (dock->client_area != NULL)
+    gtk_widget_unparent (dock->client_area);
+
+  if (widget != NULL)
+    {
+      gtk_widget_set_parent (widget, GTK_WIDGET (dock));
+      dock->client_area = widget;
+
+      if (GTK_WIDGET_REALIZED (widget->parent))
+	gtk_widget_realize (widget);
+
+      if (GTK_WIDGET_VISIBLE (widget->parent) && GTK_WIDGET_VISIBLE (widget))
+	{
+	  if (GTK_WIDGET_MAPPED (widget->parent))
+	    gtk_widget_map (widget);
+
+	  gtk_widget_queue_resize (widget);
+	}
+    }
+  else
+    {
+      if (dock->client_area != NULL && GTK_WIDGET_VISIBLE (dock))
+        gtk_widget_queue_resize (GTK_WIDGET (dock));
+      dock->client_area = NULL;
+    }
+
+  if (widget != NULL)
+    gtk_widget_unref (widget);
+}
+
+/**
+ * gnome_dock_get_client_area:
+ * @dock: A #GnomeDock widget.
+ *
+ * Description: Retrieve the widget being used as the client area in
+ * @dock.
+ *
+ * Returns: The client area widget.
+ **/
+GtkWidget *
+gnome_dock_get_client_area (GnomeDock *dock)
+{
+  return dock->client_area;
+}
+
+/**
+ * gnome_dock_get_item_by_name:
+ * @dock: A #GnomeDock widget.
+ * @name: The name of the dock item to retrieve
+ * @placement_return: A pointer to a variable holding the item's placement
+ * @num_band_return: A pointer to a variable holding the band number
+ * @band_position_return: A pointer to a variable holding the position
+ * of the item within the band
+ * @offset_return: A pointer to a variable holding the offset of the item
+ * from the previous item in the same band
+ *
+ * Description: Retrieve the dock item named @name; information about
+ * its position in the dock is returned via @placement_return,
+ * @num_band_return, @band_position_return and @offset_return.  If
+ * the placement is %GNOME_DOCK_FLOATING * num_band_return,
+ * * band_position_return and * offset_return are not set.
+ *
+ * Returns: The named #GnomeDockItem widget, or %NULL if no item with
+ * such name exists.
+ **/
+GnomeDockItem *
+gnome_dock_get_item_by_name (GnomeDock *dock,
+                             const gchar *name,
+                             GnomeDockPlacement *placement_return,
+                             guint *num_band_return,
+                             guint *band_position_return,
+                             guint *offset_return)
+{
+  GnomeDockItem *item;
+
+  item = get_docked_item_by_name (dock,
+                                  name,
+                                  placement_return,
+                                  num_band_return,
+                                  band_position_return,
+                                  offset_return);
+  if (item != NULL)
+    return item;
+
+  item = get_floating_item_by_name (dock, name);
+  if (item != NULL)
+    {
+      if (placement_return != NULL)
+        *placement_return = GNOME_DOCK_FLOATING;
+      return item;
+    }
+
+  return NULL;
+}
+
+
+
+/* Layout functions.  */
+
+static void
+layout_add_floating (GnomeDock *dock,
+                     GnomeDockLayout *layout)
+{
+  GList *lp;
+
+  for (lp = dock->floating_children; lp != NULL; lp = lp->next)
+    {
+      GtkOrientation orientation;
+      gint x, y;
+      GnomeDockItem *item;
+
+      item = GNOME_DOCK_ITEM (lp->data);
+
+      orientation = gnome_dock_item_get_orientation (item);
+      gnome_dock_item_get_floating_position (item, &x, &y);
+
+      gnome_dock_layout_add_floating_item (layout, item,
+                                           x, y,
+                                           orientation);
+    }
+}
+
+static void
+layout_add_bands (GnomeDock *dock,
+                  GnomeDockLayout *layout,
+                  GnomeDockPlacement placement,
+                  GList *band_list)
+{
+  guint band_num;
+  GList *lp;
+
+  for (lp = band_list, band_num = 0;
+       lp != NULL;
+       lp = lp->next, band_num++)
+    {
+      GnomeDockBand *band;
+
+      band = GNOME_DOCK_BAND(lp->data);
+      gnome_dock_band_layout_add (band, layout, placement, band_num);
+    }
+}
+
+/**
+ * gnome_dock_get_layout:
+ * @dock: A #GnomeDock widget
+ *
+ * Description: Retrieve the layout of @dock.
+ *
+ * Returns: @dock's layout as a #GnomeDockLayout object.
+ **/
+GnomeDockLayout *
+gnome_dock_get_layout (GnomeDock *dock)
+{
+  GnomeDockLayout *layout;
+
+  layout = gnome_dock_layout_new ();
+
+  layout_add_bands (dock, layout, GNOME_DOCK_TOP, dock->top_bands);
+  layout_add_bands (dock, layout, GNOME_DOCK_BOTTOM, dock->bottom_bands);
+  layout_add_bands (dock, layout, GNOME_DOCK_LEFT, dock->left_bands);
+  layout_add_bands (dock, layout, GNOME_DOCK_RIGHT, dock->right_bands);
+
+  layout_add_floating (dock, layout);
+
+  return layout;
+}
+
+/**
+ * gnome_dock_add_from_layout:
+ * @dock: The #GnomeDock widget
+ * @layout: A #GnomeDockLayout widget
+ *
+ * Description: Add all the items in @layout to the specified @dock.
+ *
+ * Returns: %TRUE if the operation succeeds, %FALSE if it fails.
+ **/
+gboolean
+gnome_dock_add_from_layout (GnomeDock *dock,
+                            GnomeDockLayout *layout)
+{
+  return gnome_dock_layout_add_to_dock (layout, dock);
+}
diff --git a/libgnomeui/gnome-dock.h b/libgnomeui/gnome-dock.h
new file mode 100644
index 0000000..b40f1a3
--- /dev/null
+++ b/libgnomeui/gnome-dock.h
@@ -0,0 +1,140 @@
+/*
+ * !!! MASTER CAUTION !!!!
+ *
+ * These files have been moved to libbonoboui and renamed to bonobo-dock*.[ch].
+ * We'll provide a compatibility wrapper with #defines in libgnomecompat soon, but
+ * at the moment I don't want to break the build here since libbonoboui doesn't work yet.
+ *
+ * If you do any changes in these files here, your work will be lost !
+ */
+
+/* WARNING ____ IMMATURE API ____ liable to change */
+
+/* gnome-dock.h
+
+   Copyright (C) 1998 Free Software Foundation
+
+   All rights reserved.
+
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Ettore Perazzoli <ettore comm2000 it>
+*/
+/*
+  @NOTATION@
+*/
+
+#ifndef _GNOME_DOCK_H
+#define _GNOME_DOCK_H
+
+
+
+G_BEGIN_DECLS
+
+#define GNOME_TYPE_DOCK            (gnome_dock_get_type ())
+#define GNOME_DOCK(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_DOCK, GnomeDock))
+#define GNOME_DOCK_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_DOCK, GnomeDockClass))
+#define GNOME_IS_DOCK(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_DOCK))
+#define GNOME_IS_DOCK_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_DOCK))
+#define GNOME_DOCK_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_DOCK, GnomeDockClass))
+
+typedef enum
+{
+  GNOME_DOCK_TOP,
+  GNOME_DOCK_RIGHT,
+  GNOME_DOCK_BOTTOM,
+  GNOME_DOCK_LEFT,
+  GNOME_DOCK_FLOATING
+} GnomeDockPlacement;
+
+typedef struct _GnomeDock GnomeDock;
+typedef struct _GnomeDockPrivate GnomeDockPrivate;
+typedef struct _GnomeDockClass GnomeDockClass;
+
+#include "gnome-dock-band.h"
+#include "gnome-dock-layout.h"
+
+struct _GnomeDock
+{
+  GtkContainer container;
+
+  GtkWidget *client_area;
+
+  /* GnomeDockBands associated with this dock.  */
+  GList *top_bands;
+  GList *bottom_bands;
+  GList *right_bands;
+  GList *left_bands;
+
+  /* Children that are currently not docked.  */
+  GList *floating_children;     /* GtkWidget */
+
+  /* Client rectangle before drag.  */
+  GtkAllocation client_rect;
+
+  gboolean floating_items_allowed : 1;
+
+  /*< private >*/
+  GnomeDockPrivate *_priv;
+};
+
+struct _GnomeDockClass
+{
+  GtkContainerClass parent_class;
+
+  void (* layout_changed) (GnomeDock *dock);
+};
+
+GtkWidget     *gnome_dock_new               (void);
+guint          gnome_dock_get_type          (void) G_GNUC_CONST;
+
+void           gnome_dock_allow_floating_items
+                                            (GnomeDock *dock,
+                                             gboolean enable);
+                                            
+void           gnome_dock_add_item          (GnomeDock             *dock,
+                                             GnomeDockItem         *item,
+                                             GnomeDockPlacement  placement,
+                                             guint                  band_num,
+                                             gint                   position,
+                                             guint                  offset,
+                                             gboolean               in_new_band);
+
+void           gnome_dock_add_floating_item (GnomeDock *dock,
+                                             GnomeDockItem *widget,
+                                             gint x, gint y,
+                                             GtkOrientation orientation);
+          
+void           gnome_dock_set_client_area   (GnomeDock             *dock,
+                                             GtkWidget             *widget);
+
+GtkWidget     *gnome_dock_get_client_area   (GnomeDock             *dock);
+  
+GnomeDockItem *gnome_dock_get_item_by_name  (GnomeDock *dock,
+                                             const gchar *name,
+                                             GnomeDockPlacement *placement_return,
+                                             guint *num_band_return,
+                                             guint *band_position_return,
+                                             guint *offset_return);
+ 
+GnomeDockLayout *gnome_dock_get_layout      (GnomeDock *dock);
+
+gboolean       gnome_dock_add_from_layout   (GnomeDock *dock,
+                                             GnomeDockLayout *layout);
+
+G_END_DECLS
+
+#endif
diff --git a/libgnomeui/gnome-druid-page-edge.c b/libgnomeui/gnome-druid-page-edge.c
new file mode 100644
index 0000000..da88602
--- /dev/null
+++ b/libgnomeui/gnome-druid-page-edge.c
@@ -0,0 +1,737 @@
+/* gnome-druid-page-edge.c
+ * Copyright (C) 1999  Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#include <config.h>
+#include "gnome-macros.h"
+
+#include <libgnomecanvas/gnome-canvas-pixbuf.h>
+#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
+#include <libgnomecanvas/gnome-canvas-text.h>
+#include "gnome-druid.h"
+#include "gnome-uidefs.h"
+#include <libgnome/gnome-i18n.h>
+
+#include "gnome-druid-page-edge.h"
+
+struct _GnomeDruidPageEdgePrivate
+{
+	GtkWidget *canvas;
+	GnomeCanvasItem *background_item;
+	GnomeCanvasItem *textbox_item;
+	GnomeCanvasItem *text_item;
+	GnomeCanvasItem *logo_item;
+	GnomeCanvasItem *logoframe_item;
+	GnomeCanvasItem *watermark_item;
+	GnomeCanvasItem *top_watermark_item;
+	GnomeCanvasItem *title_item;
+};
+
+static void gnome_druid_page_edge_init   	(GnomeDruidPageEdge		*druid_page_edge);
+static void gnome_druid_page_edge_class_init	(GnomeDruidPageEdgeClass	*klass);
+static void gnome_druid_page_edge_destroy 	(GtkObject                      *object);
+static void gnome_druid_page_edge_finalize 	(GObject                        *object);
+static void gnome_druid_page_edge_setup         (GnomeDruidPageEdge             *druid_page_edge);
+static void gnome_druid_page_edge_configure_canvas(GnomeDruidPageEdge           *druid_page_edge);
+static void gnome_druid_page_edge_size_allocate (GtkWidget                      *widget,
+						 GtkAllocation                  *allocation);
+static void gnome_druid_page_edge_prepare	(GnomeDruidPage		        *page,
+						 GtkWidget                      *druid,
+						 gpointer 			*data);
+
+#define LOGO_WIDTH 50.0
+#define DRUID_PAGE_HEIGHT 318
+#define DRUID_PAGE_WIDTH 516
+#define DRUID_PAGE_LEFT_WIDTH 100.0
+#define GDK_COLOR_TO_RGBA(color) GNOME_CANVAS_COLOR ((color).red/256, (color).green/256, (color).blue/256)
+
+GNOME_CLASS_BOILERPLATE (GnomeDruidPageEdge, gnome_druid_page_edge,
+			 GnomeDruidPage, gnome_druid_page);
+
+static void
+gnome_druid_page_edge_class_init (GnomeDruidPageEdgeClass *klass)
+{
+	GtkObjectClass *object_class;
+	GObjectClass *gobject_class;
+	GtkWidgetClass *widget_class;
+
+	object_class = (GtkObjectClass*) klass;
+	gobject_class = (GObjectClass*) klass;
+	widget_class = (GtkWidgetClass*) klass;
+
+	object_class->destroy = gnome_druid_page_edge_destroy;
+	gobject_class->finalize = gnome_druid_page_edge_finalize;
+	widget_class->size_allocate = gnome_druid_page_edge_size_allocate;
+}
+
+static void
+gnome_druid_page_edge_init (GnomeDruidPageEdge *druid_page_edge)
+{
+	druid_page_edge->_priv = g_new0(GnomeDruidPageEdgePrivate, 1);
+
+	/* initialize the color values */
+	druid_page_edge->background_color.red = 6400; /* midnight blue */
+	druid_page_edge->background_color.green = 6400;
+	druid_page_edge->background_color.blue = 28672;
+	druid_page_edge->textbox_color.red = 65280; /* white */
+	druid_page_edge->textbox_color.green = 65280;
+	druid_page_edge->textbox_color.blue = 65280;
+	druid_page_edge->logo_background_color.red = 65280; /* white */
+	druid_page_edge->logo_background_color.green = 65280;
+	druid_page_edge->logo_background_color.blue = 65280;
+	druid_page_edge->title_color.red = 65280; /* white */
+	druid_page_edge->title_color.green = 65280;
+	druid_page_edge->title_color.blue = 65280;
+	druid_page_edge->text_color.red = 0; /* black */
+	druid_page_edge->text_color.green = 0;
+	druid_page_edge->text_color.blue = 0;
+}
+
+/**
+ * gnome_druid_page_edge_construct:
+ *
+ * Description:  Useful for subclassing and binding only
+ **/
+void
+gnome_druid_page_edge_construct (GnomeDruidPageEdge *druid_page_edge,
+				 GnomeEdgePosition   position,
+				 gboolean            antialiased,
+				 const gchar        *title,
+				 const gchar        *text,
+				 GdkPixbuf          *logo,
+				 GdkPixbuf          *watermark,
+				 GdkPixbuf          *top_watermark)
+{
+	GtkWidget *canvas;
+
+	g_return_if_fail (druid_page_edge != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE_EDGE (druid_page_edge));
+	g_return_if_fail (position >= GNOME_EDGE_START &&
+			  position < GNOME_EDGE_LAST);
+
+	if (antialiased) {
+		gtk_widget_push_colormap (gdk_rgb_get_cmap ());
+		canvas = gnome_canvas_new_aa();
+		gtk_widget_pop_colormap ();
+	} else {
+		canvas = gnome_canvas_new();
+	}
+
+	druid_page_edge->_priv->canvas = canvas;
+
+	druid_page_edge->position = position;
+	druid_page_edge->title = g_strdup (title ? title : "");
+	druid_page_edge->text = g_strdup (text ? text : "");
+
+	if (logo != NULL)
+		gdk_pixbuf_ref (logo);
+	druid_page_edge->logo_image = logo;
+
+	if (watermark != NULL)
+		gdk_pixbuf_ref (watermark);
+	druid_page_edge->watermark_image = watermark;
+
+	if (top_watermark != NULL)
+		gdk_pixbuf_ref (top_watermark);
+	druid_page_edge->top_watermark_image = top_watermark;
+
+	/* Set up the canvas */
+	gtk_container_set_border_width (GTK_CONTAINER (druid_page_edge), 0);
+	gtk_widget_set_usize (canvas, DRUID_PAGE_WIDTH, DRUID_PAGE_HEIGHT);
+	gtk_widget_show (canvas);
+	gnome_canvas_set_scroll_region (GNOME_CANVAS (canvas), 0.0, 0.0, DRUID_PAGE_WIDTH, DRUID_PAGE_HEIGHT);
+	gtk_container_add (GTK_CONTAINER (druid_page_edge), canvas);
+
+	gnome_druid_page_edge_setup (druid_page_edge);
+}
+
+static void
+gnome_druid_page_edge_destroy(GtkObject *object)
+{
+	GnomeDruidPageEdge *druid_page_edge = GNOME_DRUID_PAGE_EDGE(object);
+
+	/* remember, destroy can be run multiple times! */
+
+	if (druid_page_edge->logo_image != NULL)
+		gdk_pixbuf_unref (druid_page_edge->logo_image);
+	druid_page_edge->logo_image = NULL;
+
+	if (druid_page_edge->watermark_image != NULL)
+		gdk_pixbuf_unref (druid_page_edge->watermark_image);
+	druid_page_edge->watermark_image = NULL;
+
+	g_free (druid_page_edge->text);
+	druid_page_edge->text = NULL;
+	g_free (druid_page_edge->title);
+	druid_page_edge->title = NULL;
+
+	GNOME_CALL_PARENT_HANDLER (GTK_OBJECT_CLASS, destroy, (object));
+}
+
+static void
+gnome_druid_page_edge_finalize(GObject *object)
+{
+	GnomeDruidPageEdge *druid_page_edge = GNOME_DRUID_PAGE_EDGE(object);
+
+	g_free(druid_page_edge->_priv);
+	druid_page_edge->_priv = NULL;
+
+	GNOME_CALL_PARENT_HANDLER (G_OBJECT_CLASS, finalize, (object));
+}
+
+static void
+gnome_druid_page_edge_configure_canvas (GnomeDruidPageEdge *druid_page_edge)
+{
+	gfloat watermark_width;
+	gfloat watermark_height;
+	gfloat watermark_ypos;
+	int width, height;
+
+	width = GTK_WIDGET (druid_page_edge)->allocation.width;
+	height = GTK_WIDGET (druid_page_edge)->allocation.height;
+
+	watermark_width = DRUID_PAGE_LEFT_WIDTH;
+	watermark_height = (gfloat) height - LOGO_WIDTH + GNOME_PAD * 2.0;
+	watermark_ypos = LOGO_WIDTH + GNOME_PAD * 2.0;
+
+	if (druid_page_edge->watermark_image) {
+		watermark_width = gdk_pixbuf_get_width (druid_page_edge->watermark_image);
+		watermark_height = gdk_pixbuf_get_height (druid_page_edge->watermark_image);
+		watermark_ypos = (gfloat) height - watermark_height;
+		if (watermark_width < 1)
+			watermark_width = 1.0;
+		if (watermark_height < 1)
+			watermark_height = 1.0;
+	}
+
+	gnome_canvas_item_set (druid_page_edge->_priv->background_item,
+			       "x1", 0.0,
+			       "y1", 0.0,
+			       "x2", (double) width,
+			       "y2", (double) height,
+			       NULL);
+	gnome_canvas_item_set (druid_page_edge->_priv->textbox_item,
+			       "x1", (double) watermark_width,
+			       "y1", (double) (LOGO_WIDTH + GNOME_PAD * 2.0),
+			       "x2", (double) width,
+			       "y2", (double) height,
+			       NULL);
+	if (druid_page_edge->logo_image != NULL) {
+		gnome_canvas_item_show (druid_page_edge->_priv->logoframe_item);
+		gnome_canvas_item_set (druid_page_edge->_priv->logoframe_item,
+				       "x1", (double) (width - LOGO_WIDTH -GNOME_PAD),
+				       "y1", (double) (GNOME_PAD),
+				       "x2", (double) (width - GNOME_PAD),
+				       "y2", (double) (GNOME_PAD + LOGO_WIDTH),
+				       "width_units", 1.0,
+				       NULL);
+	} else {
+		gnome_canvas_item_hide (druid_page_edge->_priv->logoframe_item);
+	}
+	gnome_canvas_item_set (druid_page_edge->_priv->logo_item,
+			       "x", (double) (width - GNOME_PAD - LOGO_WIDTH),
+			       "y", (double) (GNOME_PAD),
+			       "width", (double) (LOGO_WIDTH),
+			       "height", (double) (LOGO_WIDTH),
+			       NULL);
+	gnome_canvas_item_set (druid_page_edge->_priv->watermark_item,
+			       "x", 0.0,
+			       "y", (double) watermark_ypos,
+			       "width", (double) watermark_width,
+			       "height", (double) watermark_height,
+			       NULL);
+
+	gnome_canvas_item_set (druid_page_edge->_priv->title_item,
+			       "x", 15.0,
+			       "y", (double) (GNOME_PAD + LOGO_WIDTH / 2.0),
+			       "anchor", GTK_ANCHOR_WEST,
+			       NULL);
+	gnome_canvas_item_set (druid_page_edge->_priv->text_item,
+			       "x", (double) (((width - watermark_width) * 0.5) + watermark_width),
+			       "y", (double) (LOGO_WIDTH + GNOME_PAD * 2.0 + (height - (LOGO_WIDTH + GNOME_PAD * 2.0))/ 2.0),
+			       "anchor", GTK_ANCHOR_CENTER,
+			       NULL);
+}
+
+static void
+gnome_druid_page_edge_setup (GnomeDruidPageEdge *druid_page_edge)
+{
+	GnomeCanvas *canvas;
+	guint32 fill_color;
+
+	canvas = GNOME_CANVAS (druid_page_edge->_priv->canvas);
+
+	/* set up the rest of the page */
+	fill_color = GDK_COLOR_TO_RGBA (druid_page_edge->background_color);
+	druid_page_edge->_priv->background_item =
+		gnome_canvas_item_new (gnome_canvas_root (canvas),
+				       gnome_canvas_rect_get_type (),
+				       "fill_color_rgba", fill_color,
+				       NULL);
+
+	fill_color = GDK_COLOR_TO_RGBA (druid_page_edge->textbox_color);
+	druid_page_edge->_priv->textbox_item =
+		gnome_canvas_item_new (gnome_canvas_root (canvas),
+				       gnome_canvas_rect_get_type (),
+				       "fill_color_rgba", fill_color,
+				       NULL);
+
+	fill_color = GDK_COLOR_TO_RGBA (druid_page_edge->logo_background_color);
+	druid_page_edge->_priv->logoframe_item =
+		gnome_canvas_item_new (gnome_canvas_root (canvas),
+				       gnome_canvas_rect_get_type (),
+				       "fill_color_rgba", fill_color,
+				       NULL);
+	if (druid_page_edge->logo_image == NULL) {
+		gnome_canvas_item_hide (druid_page_edge->_priv->logoframe_item);
+	}
+
+	druid_page_edge->_priv->top_watermark_item =
+		gnome_canvas_item_new (gnome_canvas_root (canvas),
+				       gnome_canvas_pixbuf_get_type (),
+				       "x", 0.0,
+				       "y", 0.0,
+				       "x_set", TRUE,
+				       "y_set", TRUE,
+				       NULL);
+
+	if (druid_page_edge->top_watermark_image != NULL)
+		gnome_canvas_item_set (druid_page_edge->_priv->top_watermark_item,
+				       "pixbuf", druid_page_edge->top_watermark_image,
+				       NULL);
+
+	druid_page_edge->_priv->logo_item =
+		gnome_canvas_item_new (gnome_canvas_root (canvas),
+				       gnome_canvas_pixbuf_get_type (),
+				       "x_set", TRUE,
+				       "y_set", TRUE,
+				       NULL);
+
+	if (druid_page_edge->logo_image != NULL)
+		gnome_canvas_item_set (druid_page_edge->_priv->logo_item,
+				       "pixbuf", druid_page_edge->logo_image, NULL);
+
+	druid_page_edge->_priv->watermark_item =
+		gnome_canvas_item_new (gnome_canvas_root (canvas),
+				       gnome_canvas_pixbuf_get_type (),
+				       "x_set", TRUE,
+				       "y_set", TRUE,
+				       NULL);
+
+	if (druid_page_edge->watermark_image != NULL)
+		gnome_canvas_item_set (druid_page_edge->_priv->watermark_item,
+				       "pixbuf", druid_page_edge->watermark_image,
+				       NULL);
+
+	fill_color = GDK_COLOR_TO_RGBA (druid_page_edge->title_color);
+	druid_page_edge->_priv->title_item =
+		gnome_canvas_item_new (gnome_canvas_root (canvas),
+				       gnome_canvas_text_get_type (),
+				       "text", druid_page_edge->title,
+				       "fill_color_rgba", fill_color,
+				       "fontset", _("-adobe-helvetica-bold-r-normal-*-*-180-*-*-p-*-*-*,*-r-*"),
+				       NULL);
+
+	fill_color = GDK_COLOR_TO_RGBA (druid_page_edge->text_color);
+	druid_page_edge->_priv->text_item =
+		gnome_canvas_item_new (gnome_canvas_root (canvas),
+				       gnome_canvas_text_get_type (),
+				       "text", druid_page_edge->text,
+				       "justification", GTK_JUSTIFY_LEFT,
+				       "fontset", _("-adobe-helvetica-medium-r-normal-*-*-120-*-*-p-*-*-*,*-r-*"),
+				       "fill_color_rgba", fill_color,
+				       NULL);
+
+	gtk_signal_connect (GTK_OBJECT (druid_page_edge),
+			    "prepare",
+			    GTK_SIGNAL_FUNC (gnome_druid_page_edge_prepare),
+			    NULL);
+}
+
+static void
+gnome_druid_page_edge_prepare (GnomeDruidPage *page,
+			       GtkWidget *druid,
+			       gpointer *data)
+{
+	switch (GNOME_DRUID_PAGE_EDGE (page)->position) {
+	case GNOME_EDGE_START:
+		gnome_druid_set_buttons_sensitive (GNOME_DRUID (druid), FALSE, TRUE, TRUE);
+		gnome_druid_set_show_finish (GNOME_DRUID (druid), FALSE);
+		gtk_widget_grab_default (GNOME_DRUID (druid)->next);
+		break;
+	case GNOME_EDGE_FINISH:
+		gnome_druid_set_buttons_sensitive (GNOME_DRUID (druid), TRUE, FALSE, TRUE);
+		gnome_druid_set_show_finish (GNOME_DRUID (druid), TRUE);
+		gtk_widget_grab_default (GNOME_DRUID (druid)->finish);
+		break;
+	case GNOME_EDGE_OTHER:
+		gnome_druid_set_buttons_sensitive (GNOME_DRUID (druid), TRUE, TRUE, TRUE);
+		gnome_druid_set_show_finish (GNOME_DRUID (druid), FALSE);
+	default:
+		break;
+	}
+}
+
+static void
+gnome_druid_page_edge_size_allocate   (GtkWidget               *widget,
+				       GtkAllocation           *allocation)
+{
+	GnomeDruidPageEdge *druid_page_edge;
+
+	druid_page_edge = GNOME_DRUID_PAGE_EDGE (widget);
+
+	GNOME_CALL_PARENT_HANDLER (GTK_WIDGET_CLASS, size_allocate,
+				   (widget, allocation));
+
+	gnome_canvas_set_scroll_region (GNOME_CANVAS(druid_page_edge->_priv->canvas),
+					0.0, 0.0,
+					allocation->width,
+					allocation->height);
+	gnome_druid_page_edge_configure_canvas (druid_page_edge);
+}
+
+/**
+ * gnome_druid_page_edge_new:
+ * @position: Position in druid
+ *
+ * Description: Creates a new GnomeDruidPageEdge widget.
+ *
+ * Returns: #GtkWidget pointer to a new #GnomeDruidPageEdge.
+ **/
+/* Public functions */
+GtkWidget *
+gnome_druid_page_edge_new (GnomeEdgePosition position)
+{
+	GnomeDruidPageEdge *retval;
+
+	g_return_val_if_fail (position >= GNOME_EDGE_START &&
+			      position < GNOME_EDGE_LAST, NULL);
+
+	retval = gtk_type_new (gnome_druid_page_edge_get_type ());
+
+	gnome_druid_page_edge_construct (retval,
+					 position,
+					 FALSE,
+					 NULL,
+					 NULL,
+					 NULL,
+					 NULL,
+					 NULL);
+
+	return GTK_WIDGET (retval);
+}
+
+/**
+ * gnome_druid_page_edge_new_aa:
+ * @position: Position in druid
+ *
+ * Description: Creates a new GnomeDruidPageEdge widget.  The
+ * internal canvas is created in an antialiased mode.
+ *
+ * Returns: #GtkWidget pointer to a new #GnomeDruidPageEdge.
+ **/
+/* Public functions */
+GtkWidget *
+gnome_druid_page_edge_new_aa (GnomeEdgePosition position)
+{
+	GnomeDruidPageEdge *retval;
+
+	g_return_val_if_fail (position >= GNOME_EDGE_START &&
+			      position < GNOME_EDGE_LAST, NULL);
+
+	retval = gtk_type_new (gnome_druid_page_edge_get_type ());
+
+	gnome_druid_page_edge_construct (retval,
+					 position,
+					 TRUE,
+					 NULL,
+					 NULL,
+					 NULL,
+					 NULL,
+					 NULL);
+
+	return GTK_WIDGET (retval);
+}
+
+/**
+ * gnome_druid_page_edge_new_with_vals:
+ * @position: Position in druid
+ * @antialiased: Use an antialiased canvas
+ * @title: The title.
+ * @text: The introduction text.
+ * @logo: The logo in the upper right corner.
+ * @watermark: The watermark on the left.
+ * @top_watermark: The watermark on the left.
+ *
+ * Description: This will create a new GNOME Druid Edge page, with the values
+ * given.  It is acceptable for any of them to be %NULL.
+ * Position should be %GNOME_EDGE_START, %GNOME_EDGE_FINISH
+ * or %GNOME_EDGE_OTHER.
+ *
+ * Returns: #GtkWidget pointer to a new #GnomeDruidPageEdge.
+ **/
+GtkWidget *
+gnome_druid_page_edge_new_with_vals (GnomeEdgePosition position,
+				     gboolean antialiased,
+				     const gchar *title,
+				     const gchar* text,
+				     GdkPixbuf *logo,
+				     GdkPixbuf *watermark,
+				     GdkPixbuf *top_watermark)
+{
+	GnomeDruidPageEdge *retval;
+
+	g_return_val_if_fail (position >= GNOME_EDGE_START &&
+			      position < GNOME_EDGE_LAST, NULL);
+
+	retval = gtk_type_new (gnome_druid_page_edge_get_type ());
+
+	gnome_druid_page_edge_construct (retval,
+					 position,
+					 antialiased,
+					 title,
+					 text,
+					 logo,
+					 watermark,
+					 top_watermark);
+	return GTK_WIDGET (retval);
+}
+
+/**
+ * gnome_druid_page_edge_set_bg_color:
+ * @druid_page_edge: A DruidPageEdge.
+ * @color: The new background color.
+ *
+ * Description:  This will set the background color to be the @color.  You do
+ * not need to allocate the color, as the @druid_page_edge will do it for you.
+ **/
+void
+gnome_druid_page_edge_set_bg_color      (GnomeDruidPageEdge *druid_page_edge,
+					 GdkColor *color)
+{
+	guint fill_color;
+
+	g_return_if_fail (druid_page_edge != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE_EDGE (druid_page_edge));
+	g_return_if_fail (color != NULL);
+
+	druid_page_edge->background_color.red = color->red;
+	druid_page_edge->background_color.green = color->green;
+	druid_page_edge->background_color.blue = color->blue;
+
+	fill_color = GDK_COLOR_TO_RGBA (druid_page_edge->background_color);
+
+	gnome_canvas_item_set (druid_page_edge->_priv->background_item,
+			       "fill_color_rgba", fill_color,
+			       NULL);
+}
+
+void
+gnome_druid_page_edge_set_textbox_color (GnomeDruidPageEdge *druid_page_edge,
+					 GdkColor *color)
+{
+	guint fill_color;
+
+	g_return_if_fail (druid_page_edge != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE_EDGE (druid_page_edge));
+	g_return_if_fail (color != NULL);
+
+	druid_page_edge->textbox_color.red = color->red;
+	druid_page_edge->textbox_color.green = color->green;
+	druid_page_edge->textbox_color.blue = color->blue;
+
+	fill_color = GDK_COLOR_TO_RGBA (druid_page_edge->textbox_color);
+	gnome_canvas_item_set (druid_page_edge->_priv->textbox_item,
+			       "fill_color_rgba", fill_color,
+			       NULL);
+}
+
+void
+gnome_druid_page_edge_set_logo_bg_color (GnomeDruidPageEdge *druid_page_edge,
+					 GdkColor *color)
+{
+	guint fill_color;
+
+	g_return_if_fail (druid_page_edge != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE_EDGE (druid_page_edge));
+	g_return_if_fail (color != NULL);
+
+	druid_page_edge->logo_background_color.red = color->red;
+	druid_page_edge->logo_background_color.green = color->green;
+	druid_page_edge->logo_background_color.blue = color->blue;
+
+	fill_color = GDK_COLOR_TO_RGBA (druid_page_edge->logo_background_color);
+	gnome_canvas_item_set (druid_page_edge->_priv->logoframe_item,
+			       "fill_color_rgba", fill_color,
+			       NULL);
+}
+
+void
+gnome_druid_page_edge_set_title_color   (GnomeDruidPageEdge *druid_page_edge,
+					 GdkColor *color)
+{
+	guint32 fill_color;
+
+	g_return_if_fail (druid_page_edge != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE_EDGE (druid_page_edge));
+	g_return_if_fail (color != NULL);
+
+	druid_page_edge->title_color.red = color->red;
+	druid_page_edge->title_color.green = color->green;
+	druid_page_edge->title_color.blue = color->blue;
+
+	fill_color = GDK_COLOR_TO_RGBA (druid_page_edge->title_color);
+	gnome_canvas_item_set (druid_page_edge->_priv->title_item,
+			       "fill_color_rgba", fill_color,
+			       NULL);
+}
+
+void
+gnome_druid_page_edge_set_text_color    (GnomeDruidPageEdge *druid_page_edge,
+					 GdkColor *color)
+{
+	guint32 fill_color;
+
+	g_return_if_fail (druid_page_edge != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE_EDGE (druid_page_edge));
+	g_return_if_fail (color != NULL);
+
+	druid_page_edge->text_color.red = color->red;
+	druid_page_edge->text_color.green = color->green;
+	druid_page_edge->text_color.blue = color->blue;
+
+	fill_color = GDK_COLOR_TO_RGBA (druid_page_edge->text_color);
+	gnome_canvas_item_set (druid_page_edge->_priv->text_item,
+			       "fill_color_rgba", fill_color,
+			       NULL);
+}
+
+void
+gnome_druid_page_edge_set_text (GnomeDruidPageEdge *druid_page_edge,
+				const gchar *text)
+{
+	g_return_if_fail (druid_page_edge != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE_EDGE (druid_page_edge));
+
+	g_free (druid_page_edge->text);
+	druid_page_edge->text = g_strdup (text ? text : "");
+	gnome_canvas_item_set (druid_page_edge->_priv->text_item,
+			       "text", druid_page_edge->text,
+			       NULL);
+}
+
+void
+gnome_druid_page_edge_set_title         (GnomeDruidPageEdge *druid_page_edge,
+					 const gchar *title)
+{
+	g_return_if_fail (druid_page_edge != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE_EDGE (druid_page_edge));
+
+	g_free (druid_page_edge->title);
+	druid_page_edge->title = g_strdup (title ? title : "");
+	gnome_canvas_item_set (druid_page_edge->_priv->title_item,
+			       "text", druid_page_edge->title,
+			       NULL);
+}
+
+/**
+ * gnome_druid_page_edge_set_logo:
+ * @druid_page_edge: the #GnomeDruidPageEdge to work on
+ * @logo_image: The #GdkPixbuf to use as a logo
+ *
+ * Description:  Sets a #GdkPixbuf as the logo in the top right corner.
+ * If %NULL, then no logo will be displayed.
+ **/
+void
+gnome_druid_page_edge_set_logo (GnomeDruidPageEdge *druid_page_edge,
+				GdkPixbuf *logo_image)
+{
+	g_return_if_fail (druid_page_edge != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE_EDGE (druid_page_edge));
+	g_return_if_fail (logo_image != NULL);
+
+	if (druid_page_edge->logo_image != NULL)
+		gdk_pixbuf_unref (druid_page_edge->logo_image);
+
+	druid_page_edge->logo_image = logo_image;
+	if (logo_image != NULL )
+		gdk_pixbuf_ref (logo_image);
+	gnome_canvas_item_set (druid_page_edge->_priv->logo_item,
+			       "pixbuf", druid_page_edge->logo_image,
+			       NULL);
+}
+
+/**
+ * gnome_druid_page_edge_set_watermark:
+ * @druid_page_edge: the #GnomeDruidPageEdge to work on
+ * @top_watermark_image: The #GdkPixbuf to use as a watermark
+ *
+ * Description:  Sets a #GdkPixbuf as the watermark on the left
+ * strip on the druid.  If #top_watermark_image is %NULL, it is reset
+ * to the normal color.
+ **/
+void
+gnome_druid_page_edge_set_watermark (GnomeDruidPageEdge *druid_page_edge,
+				     GdkPixbuf *watermark)
+{
+	g_return_if_fail (druid_page_edge != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE_EDGE (druid_page_edge));
+	g_return_if_fail (watermark != NULL);
+
+	if (druid_page_edge->watermark_image != NULL)
+		gdk_pixbuf_unref (druid_page_edge->watermark_image);
+
+	druid_page_edge->watermark_image = watermark;
+	if (watermark != NULL )
+		gdk_pixbuf_ref (watermark);
+	gnome_canvas_item_set (druid_page_edge->_priv->watermark_item,
+			       "pixbuf", druid_page_edge->watermark_image,
+			       NULL);
+}
+
+/**
+ * gnome_druid_page_edge_set_top_watermark:
+ * @druid_page_edge: the #GnomeDruidPageEdge to work on
+ * @top_watermark_image: The #GdkPixbuf to use as a top watermark
+ *
+ * Description:  Sets a #GdkPixbuf as the watermark on top of the top
+ * strip on the druid.  If #top_watermark_image is %NULL, it is reset
+ * to the normal color.
+ **/
+void
+gnome_druid_page_edge_set_top_watermark (GnomeDruidPageEdge *druid_page_edge,
+					 GdkPixbuf *top_watermark_image)
+{
+	g_return_if_fail (druid_page_edge != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE_EDGE (druid_page_edge));
+
+	if (druid_page_edge->top_watermark_image)
+		gdk_pixbuf_unref (druid_page_edge->top_watermark_image);
+
+	druid_page_edge->top_watermark_image = top_watermark_image;
+	if (top_watermark_image != NULL)
+		gdk_pixbuf_ref (top_watermark_image);
+	gnome_canvas_item_set (druid_page_edge->_priv->top_watermark_item,
+			       "pixbuf", druid_page_edge->top_watermark_image,
+			       NULL);
+}
diff --git a/libgnomeui/gnome-druid-page-edge.h b/libgnomeui/gnome-druid-page-edge.h
new file mode 100644
index 0000000..953f41a
--- /dev/null
+++ b/libgnomeui/gnome-druid-page-edge.h
@@ -0,0 +1,122 @@
+/* gnome-druid-page-edge.h
+ * Copyright (C) 1999  Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+*/
+#ifndef __GNOME_DRUID_PAGE_EDGE_H__
+#define __GNOME_DRUID_PAGE_EDGE_H__
+
+#include <gtk/gtk.h>
+#include <libgnomecanvas/gnome-canvas.h>
+#include "gnome-druid-page.h"
+
+G_BEGIN_DECLS
+
+#define GNOME_TYPE_DRUID_PAGE_EDGE            (gnome_druid_page_edge_get_type ())
+#define GNOME_DRUID_PAGE_EDGE(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_DRUID_PAGE_EDGE, GnomeDruidPageEdge))
+#define GNOME_DRUID_PAGE_EDGE_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_DRUID_PAGE_EDGE, GnomeDruidPageEdgeClass))
+#define GNOME_IS_DRUID_PAGE_EDGE(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_DRUID_PAGE_EDGE))
+#define GNOME_IS_DRUID_PAGE_EDGE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_DRUID_PAGE_EDGE))
+#define GNOME_DRUID_PAGE_EDGE_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_DRUID_PAGE_EDGE, GnomeDruidPageEdgeClass))
+
+typedef enum {
+  /* update structure when adding enums */
+	GNOME_EDGE_START,
+	GNOME_EDGE_FINISH,
+	GNOME_EDGE_OTHER,
+	GNOME_EDGE_LAST /* for counting purposes */
+} GnomeEdgePosition;
+
+
+typedef struct _GnomeDruidPageEdge        GnomeDruidPageEdge;
+typedef struct _GnomeDruidPageEdgePrivate GnomeDruidPageEdgePrivate;
+typedef struct _GnomeDruidPageEdgeClass   GnomeDruidPageEdgeClass;
+
+struct _GnomeDruidPageEdge
+{
+	GnomeDruidPage parent;
+
+	/*< public >*/
+	gchar *title;
+	gchar *text;
+	GdkPixbuf *logo_image;
+	GdkPixbuf *watermark_image;
+	GdkPixbuf *top_watermark_image;
+
+	GdkColor background_color;
+	GdkColor textbox_color;
+	GdkColor logo_background_color;
+	GdkColor title_color;
+	GdkColor text_color;
+
+	GnomeEdgePosition position : 2;
+
+	/*< private >*/
+	GnomeDruidPageEdgePrivate *_priv;
+};
+
+struct _GnomeDruidPageEdgeClass
+{
+	GnomeDruidPageClass parent_class;
+};
+
+GtkType    gnome_druid_page_edge_get_type          (void) G_GNUC_CONST;
+GtkWidget *gnome_druid_page_edge_new               (GnomeEdgePosition   position);
+GtkWidget *gnome_druid_page_edge_new_aa            (GnomeEdgePosition   position);
+GtkWidget *gnome_druid_page_edge_new_with_vals     (GnomeEdgePosition   position,
+						    gboolean            antialiased,
+						    const gchar        *title,
+						    const gchar        *text,
+						    GdkPixbuf          *logo,
+						    GdkPixbuf          *watermark,
+						    GdkPixbuf	       *top_watermark);
+void       gnome_druid_page_edge_construct         (GnomeDruidPageEdge *druid_page_edge,
+						    GnomeEdgePosition   position,
+						    gboolean            antialiaed,
+						    const gchar        *title,
+						    const gchar        *text,
+						    GdkPixbuf          *logo,
+						    GdkPixbuf          *watermark,
+						    GdkPixbuf          *top_watermark);
+void       gnome_druid_page_edge_set_bg_color      (GnomeDruidPageEdge *druid_page_edge,
+						    GdkColor           *color);
+void       gnome_druid_page_edge_set_textbox_color (GnomeDruidPageEdge *druid_page_edge,
+						    GdkColor           *color);
+void       gnome_druid_page_edge_set_logo_bg_color (GnomeDruidPageEdge *druid_page_edge,
+						    GdkColor           *color);
+void       gnome_druid_page_edge_set_title_color   (GnomeDruidPageEdge *druid_page_edge,
+						    GdkColor           *color);
+void       gnome_druid_page_edge_set_text_color    (GnomeDruidPageEdge *druid_page_edge,
+						    GdkColor           *color);
+void       gnome_druid_page_edge_set_text          (GnomeDruidPageEdge *druid_page_edge,
+						    const gchar        *text);
+void       gnome_druid_page_edge_set_title         (GnomeDruidPageEdge *druid_page_edge,
+						    const gchar        *title);
+void       gnome_druid_page_edge_set_logo          (GnomeDruidPageEdge *druid_page_edge,
+						    GdkPixbuf          *logo_image);
+void       gnome_druid_page_edge_set_watermark     (GnomeDruidPageEdge *druid_page_edge,
+						    GdkPixbuf          *watermark);
+void       gnome_druid_page_edge_set_top_watermark (GnomeDruidPageEdge *druid_page_edge,
+						    GdkPixbuf          *top_watermark);
+
+G_END_DECLS
+
+#endif /* __GNOME_DRUID_PAGE_EDGE_H__ */
diff --git a/libgnomeui/gnome-druid-page-standard.c b/libgnomeui/gnome-druid-page-standard.c
new file mode 100644
index 0000000..a785e71
--- /dev/null
+++ b/libgnomeui/gnome-druid-page-standard.c
@@ -0,0 +1,543 @@
+/* gnome-druid-page-standard.c
+ * Copyright (C) 1999  Red Hat, Inc.
+ * All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#include <config.h>
+#include "gnome-macros.h"
+
+#include "gnome-druid.h"
+#include <libgnomecanvas/gnome-canvas-pixbuf.h>
+#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
+#include <libgnomecanvas/gnome-canvas-text.h>
+#include "gnome-uidefs.h"
+#include <libgnome/gnome-i18n.h>
+
+#include "gnome-druid-page-standard.h"
+
+struct _GnomeDruidPageStandardPrivate
+{
+	GtkWidget *canvas;
+	GtkWidget *side_bar;
+	GnomeCanvasItem *logoframe_item;
+	GnomeCanvasItem *logo_item;
+	GnomeCanvasItem *top_watermark_item;
+	GnomeCanvasItem *title_item;
+	GnomeCanvasItem *background_item;
+};
+
+
+static void gnome_druid_page_standard_init	    (GnomeDruidPageStandard          *druid_page_standard);
+static void gnome_druid_page_standard_class_init    (GnomeDruidPageStandardClass     *klass);
+static void gnome_druid_page_standard_destroy 	    (GtkObject                       *object);
+static void gnome_druid_page_standard_setup         (GnomeDruidPageStandard          *druid_page_standard);
+static void gnome_druid_page_standard_finalize      (GObject                         *widget);
+static void gnome_druid_page_standard_size_allocate (GtkWidget                       *widget,
+						     GtkAllocation                   *allocation);
+static void gnome_druid_page_standard_prepare       (GnomeDruidPage                  *page,
+						     GtkWidget                       *druid,
+						     gpointer                        *data);
+
+static void gnome_druid_page_standard_configure_canvas (GnomeDruidPageStandard	     *druid_page_standard);
+
+#define LOGO_WIDTH 50.0
+#define DRUID_PAGE_WIDTH 516
+#define GDK_COLOR_TO_RGBA(color) GNOME_CANVAS_COLOR ((color).red/256, (color).green/256, (color).blue/256)
+
+GNOME_CLASS_BOILERPLATE (GnomeDruidPageStandard, gnome_druid_page_standard,
+			 GnomeDruidPage, gnome_druid_page)
+
+static void
+gnome_druid_page_standard_class_init (GnomeDruidPageStandardClass *klass)
+{
+	GtkObjectClass *object_class;
+	GObjectClass *gobject_class;
+	GtkWidgetClass *widget_class;
+
+	object_class = (GtkObjectClass*) klass;
+	gobject_class = (GObjectClass*) klass;
+	widget_class = (GtkWidgetClass*) klass;
+
+	object_class->destroy = gnome_druid_page_standard_destroy;
+	gobject_class->finalize = gnome_druid_page_standard_finalize;
+	widget_class->size_allocate = gnome_druid_page_standard_size_allocate;
+
+}
+static void
+gnome_druid_page_standard_init (GnomeDruidPageStandard *druid_page_standard)
+{
+	druid_page_standard->_priv = g_new0(GnomeDruidPageStandardPrivate, 1);
+
+	/* initialize the color values */
+	druid_page_standard->background_color.red = 6400; /* midnight blue */
+	druid_page_standard->background_color.green = 6400;
+	druid_page_standard->background_color.blue = 28672;
+	druid_page_standard->logo_background_color.red = 65280; /* white */
+	druid_page_standard->logo_background_color.green = 65280;
+	druid_page_standard->logo_background_color.blue = 65280;
+	druid_page_standard->title_color.red = 65280; /* white */
+	druid_page_standard->title_color.green = 65280;
+	druid_page_standard->title_color.blue = 65280;
+}
+
+void
+gnome_druid_page_standard_construct (GnomeDruidPageStandard *druid_page_standard,
+				     gboolean		     antialiased,
+				     const gchar	    *title,
+				     GdkPixbuf		    *logo,
+				     GdkPixbuf              *top_watermark)
+{
+	GtkWidget *canvas;
+	GtkRcStyle *rc_style;
+	GtkWidget *vbox;
+	GtkWidget *hbox;
+
+	g_return_if_fail (druid_page_standard != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE_STANDARD (druid_page_standard));
+
+	if (antialiased) {
+		gtk_widget_push_colormap (gdk_rgb_get_cmap ());
+		canvas = gnome_canvas_new_aa();
+		gtk_widget_pop_colormap ();
+	} else {
+		canvas = gnome_canvas_new();
+	}
+
+	druid_page_standard->_priv->canvas = canvas;
+
+	druid_page_standard->title = g_strdup (title ? title : "");
+
+	if (logo != NULL)
+		gdk_pixbuf_ref (logo);
+	druid_page_standard->logo_image = logo;
+
+	if (top_watermark != NULL)
+		gdk_pixbuf_ref (top_watermark);
+	druid_page_standard->top_watermark_image = top_watermark;
+
+	/* Set up the widgets */
+	vbox = gtk_vbox_new (FALSE, 0);
+	hbox = gtk_hbox_new (FALSE, 0);
+	druid_page_standard->vbox = gtk_vbox_new (FALSE, 0);
+	druid_page_standard->_priv->side_bar = gtk_drawing_area_new ();
+	gtk_drawing_area_size (GTK_DRAWING_AREA (druid_page_standard->_priv->side_bar),
+			       15, 10);
+	rc_style = gtk_rc_style_new ();
+	rc_style->bg[GTK_STATE_NORMAL].red = 6400;
+	rc_style->bg[GTK_STATE_NORMAL].green = 6400;
+	rc_style->bg[GTK_STATE_NORMAL].blue = 28672;
+	rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_BG;
+	gtk_rc_style_ref (rc_style);
+	gtk_widget_modify_style (druid_page_standard->_priv->side_bar, rc_style);
+
+	/* FIXME: can I just ref the old style? */
+	rc_style = gtk_rc_style_new ();
+	rc_style->bg[GTK_STATE_NORMAL].red = 6400;
+	rc_style->bg[GTK_STATE_NORMAL].green = 6400;
+	rc_style->bg[GTK_STATE_NORMAL].blue = 28672;
+	rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_BG;
+	gtk_widget_modify_style (canvas, rc_style);
+	gtk_box_pack_start (GTK_BOX (vbox), canvas, FALSE, FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
+	gtk_box_pack_start (GTK_BOX (hbox), druid_page_standard->_priv->side_bar, FALSE, FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (hbox), druid_page_standard->vbox, TRUE, TRUE, 0);
+	gtk_widget_set_usize (canvas, 508, LOGO_WIDTH + GNOME_PAD * 2);
+	gtk_container_set_border_width (GTK_CONTAINER (druid_page_standard), 0);
+	gtk_container_add (GTK_CONTAINER (druid_page_standard), vbox);
+	gtk_widget_show_all (vbox);
+
+	gnome_druid_page_standard_setup (druid_page_standard);
+}
+
+static void
+gnome_druid_page_standard_destroy (GtkObject *object)
+{
+	GnomeDruidPageStandard *druid_page_standard = GNOME_DRUID_PAGE_STANDARD (object);
+
+	/* remember, destroy can be run multiple times! */
+
+	if (druid_page_standard->logo_image != NULL)
+		gdk_pixbuf_unref (druid_page_standard->logo_image);
+	druid_page_standard->logo_image = NULL;
+
+	if (druid_page_standard->top_watermark_image != NULL)
+		gdk_pixbuf_unref (druid_page_standard->top_watermark_image);
+	druid_page_standard->top_watermark_image = NULL;
+
+	g_free (druid_page_standard->title);
+	druid_page_standard->title = NULL;
+
+	GNOME_CALL_PARENT_HANDLER (GTK_OBJECT_CLASS, destroy, (object));
+}
+
+static void
+gnome_druid_page_standard_finalize (GObject *object)
+{
+	GnomeDruidPageStandard *druid_page_standard = GNOME_DRUID_PAGE_STANDARD(object);
+
+	g_free(druid_page_standard->_priv);
+	druid_page_standard->_priv = NULL;
+
+	GNOME_CALL_PARENT_HANDLER (G_OBJECT_CLASS, finalize, (object));
+}
+
+
+static void
+gnome_druid_page_standard_configure_canvas (GnomeDruidPageStandard *druid_page_standard)
+{
+	int width, height;
+
+	g_return_if_fail (druid_page_standard != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE_STANDARD (druid_page_standard));
+
+	width = GTK_WIDGET(druid_page_standard)->allocation.width;
+	height = GTK_WIDGET(druid_page_standard)->allocation.height;
+
+	gnome_canvas_item_set (druid_page_standard->_priv->background_item,
+			       "x1", 0.0,
+			       "y1", 0.0,
+			       "x2", (double) width,
+			       "y2", (double) (LOGO_WIDTH + GNOME_PAD * 2),
+			       "width_units", 1.0,
+			       NULL);
+	if (druid_page_standard->logo_image != NULL) {
+		gnome_canvas_item_show (druid_page_standard->_priv->logoframe_item);
+		gnome_canvas_item_set (druid_page_standard->_priv->logoframe_item,
+				       "x1", (double) (width - LOGO_WIDTH - GNOME_PAD),
+				       "y1", (double) (GNOME_PAD),
+				       "x2", (double) (width - GNOME_PAD),
+				       "y2", (double) (GNOME_PAD + LOGO_WIDTH),
+				       "width_units", 1.0,
+				       NULL);
+	} else {
+		gnome_canvas_item_hide (druid_page_standard->_priv->logoframe_item);
+	}
+	gnome_canvas_item_set (druid_page_standard->_priv->logo_item,
+			       "x", (double) (width - GNOME_PAD - LOGO_WIDTH),
+			       "y", (double) (GNOME_PAD),
+			       "width", (double) (LOGO_WIDTH),
+			       "height", (double) (LOGO_WIDTH),
+			       NULL);
+}
+
+static void
+gnome_druid_page_standard_setup (GnomeDruidPageStandard *druid_page_standard)
+{
+	GnomeCanvas *canvas;
+	static guint32 fill_color = 0;
+
+	canvas = GNOME_CANVAS (druid_page_standard->_priv->canvas);
+
+	/* set up the rest of the page */
+	fill_color = GDK_COLOR_TO_RGBA (druid_page_standard->background_color);
+	druid_page_standard->_priv->background_item =
+		gnome_canvas_item_new (gnome_canvas_root (canvas),
+				       gnome_canvas_rect_get_type (),
+				       "fill_color_rgba", fill_color,
+				       NULL);
+
+	fill_color = GDK_COLOR_TO_RGBA (druid_page_standard->logo_background_color);
+	druid_page_standard->_priv->logoframe_item =
+		gnome_canvas_item_new (gnome_canvas_root (canvas),
+				       gnome_canvas_rect_get_type (),
+				       "fill_color_rgba", fill_color,
+				       NULL);
+	if (druid_page_standard->logo_image == NULL) {
+		gnome_canvas_item_hide (druid_page_standard->_priv->logoframe_item);
+	}
+
+	druid_page_standard->_priv->top_watermark_item =
+		gnome_canvas_item_new (gnome_canvas_root (canvas),
+				       gnome_canvas_pixbuf_get_type (),
+				       "x", 0.0,
+				       "y", 0.0,
+				       "x_set", TRUE,
+				       "y_set", TRUE,
+				       NULL);
+
+	if (druid_page_standard->top_watermark_image != NULL) {
+		gnome_canvas_item_set (druid_page_standard->_priv->top_watermark_item,
+				       "pixbuf", druid_page_standard->top_watermark_image,
+				       NULL);
+	}
+
+
+	druid_page_standard->_priv->logo_item =
+		gnome_canvas_item_new (gnome_canvas_root (canvas),
+				       gnome_canvas_pixbuf_get_type (),
+				       "x_set", TRUE,
+				       "y_set", TRUE,
+				       NULL);
+
+	if (druid_page_standard->logo_image != NULL) {
+		gnome_canvas_item_set (druid_page_standard->_priv->logo_item,
+				       "pixbuf", druid_page_standard->logo_image,
+				       NULL);
+	}
+
+	fill_color = GDK_COLOR_TO_RGBA (druid_page_standard->title_color);
+	druid_page_standard->_priv->title_item =
+		gnome_canvas_item_new (gnome_canvas_root (canvas),
+				       gnome_canvas_text_get_type (),
+				       "text", druid_page_standard->title,
+				       "fontset", _("-adobe-helvetica-bold-r-normal-*-*-180-*-*-p-*-*-*,*-r-*"),
+				       "fill_color_rgba", fill_color,
+				       NULL);
+
+	gnome_canvas_item_set (druid_page_standard->_priv->title_item,
+			       "x", 15.0,
+			       "y", (double) (GNOME_PAD + LOGO_WIDTH / 2.0),
+			       "anchor", GTK_ANCHOR_WEST,
+			       NULL);
+
+	gtk_signal_connect (GTK_OBJECT (druid_page_standard),
+			    "prepare",
+			    GTK_SIGNAL_FUNC (gnome_druid_page_standard_prepare),
+			    NULL);
+
+}
+static void
+gnome_druid_page_standard_prepare (GnomeDruidPage *page,
+				   GtkWidget *druid,
+				   gpointer *data)
+{
+	gnome_druid_set_buttons_sensitive (GNOME_DRUID (druid), TRUE, TRUE, TRUE);
+	gnome_druid_set_show_finish (GNOME_DRUID (druid), FALSE);
+	gtk_widget_grab_default (GNOME_DRUID (druid)->next);
+}
+
+static void
+gnome_druid_page_standard_size_allocate (GtkWidget *widget,
+					 GtkAllocation *allocation)
+{
+	GtkWidget *canvas;
+
+	canvas = GNOME_DRUID_PAGE_STANDARD (widget)->_priv->canvas;
+
+	GNOME_CALL_PARENT_HANDLER (GTK_WIDGET_CLASS, size_allocate,
+				   (widget, allocation));
+
+	gnome_canvas_set_scroll_region (GNOME_CANVAS (canvas),
+					0.0, 0.0,
+					allocation->width,
+					allocation->height);
+	gnome_druid_page_standard_configure_canvas (GNOME_DRUID_PAGE_STANDARD (widget));
+}
+
+GtkWidget *
+gnome_druid_page_standard_new (void)
+{
+	GnomeDruidPageStandard *retval;
+
+	retval = gtk_type_new (gnome_druid_page_standard_get_type ());
+
+	gnome_druid_page_standard_construct (retval,
+					     FALSE,
+					     NULL,
+					     NULL,
+					     NULL);
+
+	return GTK_WIDGET (retval);
+}
+
+GtkWidget *
+gnome_druid_page_standard_new_aa (void)
+{
+	GnomeDruidPageStandard *retval;
+
+	retval = gtk_type_new (gnome_druid_page_standard_get_type ());
+
+	gnome_druid_page_standard_construct (retval,
+					     TRUE,
+					     NULL,
+					     NULL,
+					     NULL);
+
+	return GTK_WIDGET (retval);
+}
+
+GtkWidget *
+gnome_druid_page_standard_new_with_vals (gboolean antialiased,
+					 const gchar *title,
+					 GdkPixbuf *logo,
+					 GdkPixbuf *top_watermark)
+{
+	GnomeDruidPageStandard *retval;
+
+	retval = gtk_type_new (gnome_druid_page_standard_get_type ());
+
+	gnome_druid_page_standard_construct (retval,
+					     antialiased,
+					     title,
+					     logo,
+					     top_watermark);
+
+	return GTK_WIDGET (retval);
+}
+
+void
+gnome_druid_page_standard_set_bg_color (GnomeDruidPageStandard *druid_page_standard,
+					GdkColor *color)
+{
+	guint32 fill_color;
+
+	g_return_if_fail (druid_page_standard != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE_STANDARD (druid_page_standard));
+	g_return_if_fail (color != NULL);
+
+	druid_page_standard->background_color.red = color->red;
+	druid_page_standard->background_color.green = color->green;
+	druid_page_standard->background_color.blue = color->blue;
+
+	fill_color = GDK_COLOR_TO_RGBA (druid_page_standard->background_color);
+
+	gnome_canvas_item_set (druid_page_standard->_priv->background_item,
+			       "fill_color_rgba", fill_color,
+			       NULL);
+
+	if (GTK_WIDGET_REALIZED (druid_page_standard)) {
+
+		GtkStyle *style;
+
+		style = gtk_style_copy (gtk_widget_get_style (druid_page_standard->_priv->side_bar));
+		style->bg[GTK_STATE_NORMAL].red = color->red;
+		style->bg[GTK_STATE_NORMAL].green = color->green;
+		style->bg[GTK_STATE_NORMAL].blue = color->blue;
+		gtk_widget_set_style (druid_page_standard->_priv->side_bar, style);
+	} else {
+		GtkRcStyle *rc_style;
+
+		rc_style = gtk_rc_style_new ();
+		rc_style->bg[GTK_STATE_NORMAL].red = color->red;
+		rc_style->bg[GTK_STATE_NORMAL].green = color->green;
+		rc_style->bg[GTK_STATE_NORMAL].blue = color->blue;
+		rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_BG;
+		gtk_rc_style_ref (rc_style);
+		gtk_widget_modify_style (druid_page_standard->_priv->side_bar, rc_style);
+	}
+}
+
+void
+gnome_druid_page_standard_set_logo_bg_color (GnomeDruidPageStandard *druid_page_standard,
+					     GdkColor *color)
+{
+	guint32 fill_color;
+
+	g_return_if_fail (druid_page_standard != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE_STANDARD (druid_page_standard));
+	g_return_if_fail (color != NULL);
+
+	druid_page_standard->logo_background_color.red = color->red;
+	druid_page_standard->logo_background_color.green = color->green;
+	druid_page_standard->logo_background_color.blue = color->blue;
+
+	fill_color = GDK_COLOR_TO_RGBA (druid_page_standard->logo_background_color);
+	gnome_canvas_item_set (druid_page_standard->_priv->logoframe_item,
+			       "fill_color_rgba", fill_color,
+			       NULL);
+}
+
+void
+gnome_druid_page_standard_set_title_color (GnomeDruidPageStandard *druid_page_standard,
+					   GdkColor *color)
+{
+	guint32 fill_color;
+
+	g_return_if_fail (druid_page_standard != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE_STANDARD (druid_page_standard));
+	g_return_if_fail (color != NULL);
+
+	druid_page_standard->title_color.red = color->red;
+	druid_page_standard->title_color.green = color->green;
+	druid_page_standard->title_color.blue = color->blue;
+
+	fill_color = GDK_COLOR_TO_RGBA (druid_page_standard->title_color);
+	gnome_canvas_item_set (druid_page_standard->_priv->title_item,
+			       "fill_color_rgba", fill_color,
+			       NULL);
+}
+
+void
+gnome_druid_page_standard_set_title (GnomeDruidPageStandard *druid_page_standard,
+				     const gchar *title)
+{
+	g_return_if_fail (druid_page_standard != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE_STANDARD (druid_page_standard));
+
+	g_free (druid_page_standard->title);
+	druid_page_standard->title = g_strdup (title ? title : "");
+	gnome_canvas_item_set (druid_page_standard->_priv->title_item,
+			       "text", druid_page_standard->title,
+			       NULL);
+}
+
+/**
+ * gnome_druid_page_standard_set_logo:
+ * @druid_page_standard: the #GnomeDruidPageStandard to work on
+ * @logo_image: The #GdkPixbuf to use as a logo
+ *
+ * Description:  Sets a #GdkPixbuf as the logo in the top right corner.
+ * If %NULL, then no logo will be displayed.
+ **/
+void
+gnome_druid_page_standard_set_logo (GnomeDruidPageStandard *druid_page_standard,
+				    GdkPixbuf *logo_image)
+{
+	g_return_if_fail (druid_page_standard != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE_STANDARD (druid_page_standard));
+
+	if (druid_page_standard->logo_image)
+		gdk_pixbuf_unref (druid_page_standard->logo_image);
+
+	druid_page_standard->logo_image = logo_image;
+	if (logo_image != NULL)
+		gdk_pixbuf_ref (logo_image);
+	gnome_canvas_item_set (druid_page_standard->_priv->logo_item,
+			       "pixbuf", druid_page_standard->logo_image,
+			       NULL);
+}
+
+/**
+ * gnome_druid_page_standard_set_top_watermark:
+ * @druid_page_standard: the #GnomeDruidPageStandard to work on
+ * @top_watermark_image: The #GdkPixbuf to use as a top watermark
+ *
+ * Description:  Sets a #GdkPixbuf as the watermark on top of the top
+ * strip on the druid.  If #top_watermark_image is %NULL, it is reset
+ * to the normal color.
+ **/
+void
+gnome_druid_page_standard_set_top_watermark (GnomeDruidPageStandard *druid_page_standard,
+					     GdkPixbuf *top_watermark_image)
+{
+	g_return_if_fail (druid_page_standard != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE_STANDARD (druid_page_standard));
+
+	if (druid_page_standard->top_watermark_image)
+		gdk_pixbuf_unref (druid_page_standard->top_watermark_image);
+
+	druid_page_standard->top_watermark_image = top_watermark_image;
+	if (top_watermark_image != NULL)
+		gdk_pixbuf_ref (top_watermark_image);
+	gnome_canvas_item_set (druid_page_standard->_priv->top_watermark_item,
+			       "pixbuf", druid_page_standard->top_watermark_image,
+			       NULL);
+}
diff --git a/libgnomeui/gnome-druid-page-standard.h b/libgnomeui/gnome-druid-page-standard.h
new file mode 100644
index 0000000..47eb92b
--- /dev/null
+++ b/libgnomeui/gnome-druid-page-standard.h
@@ -0,0 +1,96 @@
+/* gnome-druid-page-standard.h
+ * Copyright (C) 1999  Red Hat, Inc.
+ * All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+*/
+#ifndef __GNOME_DRUID_PAGE_STANDARD_H__
+#define __GNOME_DRUID_PAGE_STANDARD_H__
+
+#include <gtk/gtk.h>
+#include <libgnomecanvas/gnome-canvas.h>
+#include "gnome-druid-page.h"
+
+G_BEGIN_DECLS
+
+#define GNOME_TYPE_DRUID_PAGE_STANDARD            (gnome_druid_page_standard_get_type ())
+#define GNOME_DRUID_PAGE_STANDARD(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_DRUID_PAGE_STANDARD, GnomeDruidPageStandard))
+#define GNOME_DRUID_PAGE_STANDARD_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_DRUID_PAGE_STANDARD, GnomeDruidPageStandardClass))
+#define GNOME_IS_DRUID_PAGE_STANDARD(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_DRUID_PAGE_STANDARD))
+#define GNOME_IS_DRUID_PAGE_STANDARD_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_DRUID_PAGE_STANDARD))
+#define GNOME_DRUID_PAGE_STANDARD_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_DRUID_PAGE_STANDARD, GnomeDruidPageStandardClass))
+
+
+typedef struct _GnomeDruidPageStandard        GnomeDruidPageStandard;
+typedef struct _GnomeDruidPageStandardPrivate GnomeDruidPageStandardPrivate;
+typedef struct _GnomeDruidPageStandardClass   GnomeDruidPageStandardClass;
+
+struct _GnomeDruidPageStandard
+{
+	GnomeDruidPage parent;
+
+	/*< public >*/
+	GtkWidget *vbox;
+	GdkPixbuf *logo_image;
+	GdkPixbuf *top_watermark_image;
+
+	gchar *title;
+
+	GdkColor background_color;
+	GdkColor logo_background_color;
+	GdkColor title_color;
+	
+	/*< private >*/
+	GnomeDruidPageStandardPrivate *_priv;
+};
+struct _GnomeDruidPageStandardClass
+{
+	GnomeDruidPageClass parent_class;
+};
+
+
+GtkType    gnome_druid_page_standard_get_type      (void) G_GNUC_CONST;
+GtkWidget *gnome_druid_page_standard_new           (void);
+GtkWidget *gnome_druid_page_standard_new_aa        (void);
+GtkWidget *gnome_druid_page_standard_new_with_vals (gboolean		 antialiased,
+						    const gchar		*title,
+						    GdkPixbuf		*logo,
+						    GdkPixbuf		*top_watermark);
+void       gnome_druid_page_standard_construct     (GnomeDruidPageStandard *druid_page_standard,
+						    gboolean		 antialiased,
+						    const gchar		*title,
+						    GdkPixbuf		*logo,
+						    GdkPixbuf		*top_watermark);
+void       gnome_druid_page_standard_set_bg_color  (GnomeDruidPageStandard *druid_page_standard,
+						    GdkColor		*color);
+void       gnome_druid_page_standard_set_logo_bg_color(GnomeDruidPageStandard *druid_page_standard,
+						    GdkColor		*color);
+void       gnome_druid_page_standard_set_title_color(GnomeDruidPageStandard *druid_page_standard,
+						    GdkColor		*color);
+void       gnome_druid_page_standard_set_title     (GnomeDruidPageStandard *druid_page_standard,
+						    const gchar		*title);
+void       gnome_druid_page_standard_set_logo      (GnomeDruidPageStandard *druid_page_standard,
+						    GdkPixbuf		*logo_image);
+void       gnome_druid_page_standard_set_top_watermark(GnomeDruidPageStandard *druid_page_standard,
+						    GdkPixbuf		*top_watermark_image);
+
+G_END_DECLS
+
+#endif /* __GNOME_DRUID_PAGE_STANDARD_H__ */
+
diff --git a/libgnomeui/gnome-druid-page.c b/libgnomeui/gnome-druid-page.c
new file mode 100644
index 0000000..23b2277
--- /dev/null
+++ b/libgnomeui/gnome-druid-page.c
@@ -0,0 +1,381 @@
+/* gnome-druid-page.c
+ * Copyright (C) 1999 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#include <config.h>
+#include "gnome-macros.h"
+
+#include "gnome-druid-page.h"
+
+#include <libgnomeuiP.h>
+
+enum {
+	NEXT,
+	PREPARE,
+	BACK,
+	FINISH,
+	CANCEL,
+	CONFIGURE_CANVAS,
+	LAST_SIGNAL
+};
+
+static void gnome_druid_page_init		(GnomeDruidPage		 *druid_page);
+static void gnome_druid_page_class_init  	(GnomeDruidPageClass	 *klass);
+static void gnome_druid_page_destroy  		(GtkObject		 *object);
+static void gnome_druid_page_finalize  		(GObject		 *object);
+static void gnome_druid_page_size_request       (GtkWidget               *widget, 
+						 GtkRequisition          *requisition);
+static void gnome_druid_page_size_allocate      (GtkWidget		 *widget,
+						 GtkAllocation           *allocation);
+static gint gnome_druid_page_expose             (GtkWidget               *widget,
+						 GdkEventExpose          *event);
+static void gnome_druid_page_realize            (GtkWidget		 *widget);
+
+
+static guint druid_page_signals[LAST_SIGNAL] = { 0 };
+
+GNOME_CLASS_BOILERPLATE (GnomeDruidPage, gnome_druid_page,
+			 GtkBin, gtk_bin)
+
+static void
+gnome_druid_page_class_init (GnomeDruidPageClass *klass)
+{
+	GtkObjectClass *object_class;
+	GObjectClass *gobject_class;
+	GtkWidgetClass *widget_class;
+
+	object_class = (GtkObjectClass*) klass;
+	gobject_class = (GObjectClass*) klass;
+	widget_class = (GtkWidgetClass*) klass;
+
+	druid_page_signals[NEXT] = 
+		gtk_signal_new ("next",
+				GTK_RUN_LAST,
+				GTK_CLASS_TYPE (object_class),
+				GTK_SIGNAL_OFFSET (GnomeDruidPageClass, next),
+				gnome_marshal_BOOLEAN__OBJECT,
+				GTK_TYPE_BOOL, 1,
+				GTK_TYPE_WIDGET);
+	druid_page_signals[PREPARE] = 
+		gtk_signal_new ("prepare",
+				GTK_RUN_LAST,
+				GTK_CLASS_TYPE (object_class),
+				GTK_SIGNAL_OFFSET (GnomeDruidPageClass, prepare),
+				gtk_marshal_VOID__OBJECT,
+				GTK_TYPE_NONE, 1,
+				GTK_TYPE_WIDGET);
+	druid_page_signals[BACK] = 
+		gtk_signal_new ("back",
+				GTK_RUN_LAST,
+				GTK_CLASS_TYPE (object_class),
+				GTK_SIGNAL_OFFSET (GnomeDruidPageClass, back),
+				gnome_marshal_BOOLEAN__OBJECT,
+				GTK_TYPE_WIDGET, 1,
+				GTK_TYPE_POINTER);
+	druid_page_signals[FINISH] = 
+		gtk_signal_new ("finish",
+				GTK_RUN_LAST,
+				GTK_CLASS_TYPE (object_class),
+				GTK_SIGNAL_OFFSET (GnomeDruidPageClass, finish),
+				gtk_marshal_VOID__OBJECT,
+				GTK_TYPE_NONE, 1,
+				GTK_TYPE_WIDGET);
+	druid_page_signals[CANCEL] = 
+		gtk_signal_new ("cancel",
+				GTK_RUN_LAST,
+				GTK_CLASS_TYPE (object_class),
+				GTK_SIGNAL_OFFSET (GnomeDruidPageClass, cancel),
+				gnome_marshal_BOOLEAN__OBJECT,
+				GTK_TYPE_BOOL, 1,
+				GTK_TYPE_WIDGET);
+
+	object_class->destroy = gnome_druid_page_destroy;
+	gobject_class->finalize = gnome_druid_page_finalize;
+
+	klass->next = NULL;
+	klass->prepare = NULL;
+	klass->back = NULL;
+	klass->finish = NULL;
+
+	widget_class->size_request = gnome_druid_page_size_request;
+	widget_class->size_allocate = gnome_druid_page_size_allocate;
+	widget_class->expose_event = gnome_druid_page_expose;
+	widget_class->realize = gnome_druid_page_realize;
+}
+
+
+static void
+gnome_druid_page_init (GnomeDruidPage *druid_page)
+{
+	/* enable if you add privates */
+	/*druid_page->_priv = g_new0 (GnomeDruidPagePrivate, 1);*/
+	druid_page->_priv = NULL;
+
+	GTK_WIDGET_UNSET_FLAGS (druid_page, GTK_NO_WINDOW);
+}
+
+static void
+gnome_druid_page_destroy (GtkObject *object)
+{
+	/* remember, destroy can be run multiple times! */
+
+	GNOME_CALL_PARENT_HANDLER (GTK_OBJECT_CLASS, destroy, (object));
+}
+
+static void
+gnome_druid_page_finalize (GObject *object)
+{
+	/*GnomeDruidPage *druid_page = GNOME_DRUID_PAGE(object);*/
+
+	/* Enable if you add privates */
+	/*g_free(druid_page->_priv);
+	druid_page->_priv = NULL;*/
+
+	GNOME_CALL_PARENT_HANDLER (G_OBJECT_CLASS, finalize, (object));
+}
+
+static void
+gnome_druid_page_size_request (GtkWidget *widget, 
+			       GtkRequisition *requisition)
+{
+	GtkBin *bin;
+
+	g_return_if_fail (widget != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE (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)) {
+		GtkRequisition child_requisition;
+
+		gtk_widget_size_request (bin->child, &child_requisition);
+
+		requisition->width += child_requisition.width;
+		requisition->height += child_requisition.height;
+	}
+}
+static void
+gnome_druid_page_size_allocate (GtkWidget *widget,
+				GtkAllocation *allocation)
+{
+	GtkBin *bin;
+	GtkAllocation child_allocation;
+
+	g_return_if_fail (widget != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE (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 = MAX (allocation->width - GTK_CONTAINER (widget)->border_width * 2, 0);
+	child_allocation.height = MAX (allocation->height - GTK_CONTAINER (widget)->border_width * 2, 0);
+	
+	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_size_allocate (bin->child, &child_allocation);
+	}
+}
+static void
+gnome_druid_page_paint (GtkWidget     *widget,
+			GdkRectangle *area)
+{
+	gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL, 
+			    GTK_SHADOW_NONE, area, widget, "base", 0, 0, -1, -1);
+}
+
+static gint
+gnome_druid_page_expose (GtkWidget               *widget,
+			 GdkEventExpose          *event)
+{
+	g_return_val_if_fail (widget != NULL, FALSE);
+	g_return_val_if_fail (GNOME_IS_DRUID_PAGE (widget), FALSE);
+	g_return_val_if_fail (event != NULL, FALSE);
+
+	if (!GTK_WIDGET_APP_PAINTABLE (widget))
+		gnome_druid_page_paint (widget, &event->area);
+
+	if (GTK_WIDGET_DRAWABLE (widget)) {
+		return GNOME_CALL_PARENT_HANDLER_WITH_DEFAULT 
+			(GTK_WIDGET_CLASS, expose_event, (widget, event), FALSE);
+	}
+
+	return FALSE;
+}
+
+static void
+gnome_druid_page_realize (GtkWidget *widget)
+{
+	GdkWindowAttr attributes;
+	gint attributes_mask;
+	gint border_width;
+	g_return_if_fail (widget != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE (widget));
+
+	GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+	
+	border_width = GTK_CONTAINER (widget)->border_width;
+
+	attributes.x = widget->allocation.x + border_width;
+	attributes.y = widget->allocation.y + border_width;
+	attributes.width = widget->allocation.width - 2*border_width;
+	attributes.height = widget->allocation.height - 2*border_width;
+	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 (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
+	gdk_window_set_user_data (widget->window, widget);
+	gdk_window_set_back_pixmap (widget->window, NULL, FALSE);
+
+	widget->style = gtk_style_attach (widget->style, widget->window);
+	gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
+}
+/**
+ * gnome_druid_page_next:
+ * @druid_page: A DruidPage widget.
+ * 
+ * Description: This will emit the "next" signal for that particular page.  It
+ * is called by gnome-druid exclusively.  It is expected that non-linear Druid's
+ * will override this signal and return TRUE if it handles changing pages.  
+ * 
+ * Return value: This function will return FALSE by default.
+ **/
+/* Public functions */
+gboolean
+gnome_druid_page_next     (GnomeDruidPage *druid_page)
+{
+	gboolean retval = FALSE;
+
+	g_return_val_if_fail (druid_page != NULL, FALSE);
+	g_return_val_if_fail (GNOME_IS_DRUID_PAGE (druid_page), FALSE);
+
+	gtk_signal_emit (GTK_OBJECT (druid_page),
+			 druid_page_signals [NEXT],
+			 GTK_WIDGET (druid_page)->parent,
+			 &retval);
+
+	return retval;
+}
+/**
+ * gnome_druid_page_prepare:
+ * @druid_page: A DruidPage widget.
+ * 
+ * Description: This emits the "prepare" signal for the page.  It is called by
+ * gnome-druid exclusively.
+ **/
+void
+gnome_druid_page_prepare  (GnomeDruidPage *druid_page)
+{
+	g_return_if_fail (druid_page != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE (druid_page));
+
+	gtk_signal_emit (GTK_OBJECT (druid_page),
+			 druid_page_signals [PREPARE],
+			 GTK_WIDGET (druid_page)->parent);
+}
+/**
+ * gnome_druid_page_back:
+ * @druid_page: A DruidPage widget.
+ * 
+ * Description: This will emit the "back" signal for that particular page.  It
+ * is called by gnome-druid exclusively.  It is expected that non-linear Druid's
+ * will override this signal and return TRUE if it handles changing pages.
+ * 
+ * Return value: This function will return FALSE by default.
+ **/
+gboolean
+gnome_druid_page_back     (GnomeDruidPage *druid_page)
+{
+	gboolean retval = FALSE;
+
+	g_return_val_if_fail (druid_page != NULL, FALSE);
+	g_return_val_if_fail (GNOME_IS_DRUID_PAGE (druid_page), FALSE);
+  
+	gtk_signal_emit (GTK_OBJECT (druid_page),
+			 druid_page_signals [BACK],
+			 GTK_WIDGET (druid_page)->parent,
+			 &retval);
+
+	return retval;
+}
+/**
+ * gnome_druid_page_finish:
+ * @druid_page: A DruidPage widget.
+ * 
+ * Description: This emits the "finish" signal for the page.  It is called by
+ * gnome-druid exclusively.
+ **/
+void
+gnome_druid_page_finish   (GnomeDruidPage *druid_page)
+{
+	g_return_if_fail (druid_page != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE (druid_page));
+  
+	gtk_signal_emit (GTK_OBJECT (druid_page),
+			 druid_page_signals [FINISH],
+			 GTK_WIDGET (druid_page)->parent);
+}
+/**
+ * gnome_druid_page_cancel:
+ * @druid_page: A DruidPage widget.
+ * 
+ * Description: This will emit the "cancel" signal for that particular page.  It
+ * is called by gnome-druid exclusively.  It is expected that a Druid will
+ * override this signal and return TRUE if it does not want to exit.
+ * 
+ * Return value: This function will return FALSE by default.
+ **/
+gboolean
+gnome_druid_page_cancel   (GnomeDruidPage *druid_page)
+{
+	gboolean retval = FALSE;
+
+	g_return_val_if_fail (druid_page != NULL, FALSE);
+	g_return_val_if_fail (GNOME_IS_DRUID_PAGE (druid_page), FALSE);
+
+	gtk_signal_emit (GTK_OBJECT (druid_page),
+			 druid_page_signals [CANCEL],
+			 GTK_WIDGET (druid_page)->parent,
+			 &retval);
+
+	return retval;
+}
diff --git a/libgnomeui/gnome-druid-page.h b/libgnomeui/gnome-druid-page.h
new file mode 100644
index 0000000..a115dba
--- /dev/null
+++ b/libgnomeui/gnome-druid-page.h
@@ -0,0 +1,85 @@
+/* gnome-druid-page.h
+ * Copyright (C) 1999  Red Hat, Inc.
+ * All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+*/
+#ifndef __GNOME_DRUID_PAGE_H__
+#define __GNOME_DRUID_PAGE_H__
+
+#include <gtk/gtk.h>
+
+#include <libgnomecanvas/gnome-canvas.h>
+
+G_BEGIN_DECLS
+
+#define GNOME_TYPE_DRUID_PAGE            (gnome_druid_page_get_type ())
+#define GNOME_DRUID_PAGE(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_DRUID_PAGE, GnomeDruidPage))
+#define GNOME_DRUID_PAGE_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_DRUID_PAGE, GnomeDruidPageClass))
+#define GNOME_IS_DRUID_PAGE(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_DRUID_PAGE))
+#define GNOME_IS_DRUID_PAGE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_DRUID_PAGE))
+#define GNOME_DRUID_PAGE_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_DRUID_PAGE, GnomeDruidPageClass))
+
+
+typedef struct _GnomeDruidPage        GnomeDruidPage;
+typedef struct _GnomeDruidPagePrivate GnomeDruidPagePrivate;
+typedef struct _GnomeDruidPageClass   GnomeDruidPageClass;
+
+struct _GnomeDruidPage
+{
+	GtkBin parent;
+
+	/*< private >*/
+	GnomeDruidPagePrivate *_priv;
+};
+struct _GnomeDruidPageClass
+{
+	GtkBinClass parent_class;
+
+	gboolean (*next)	(GnomeDruidPage *druid_page, GtkWidget *druid);
+	void     (*prepare)	(GnomeDruidPage *druid_page, GtkWidget *druid);
+	gboolean (*back)	(GnomeDruidPage *druid_page, GtkWidget *druid);
+	void     (*finish)	(GnomeDruidPage *druid_page, GtkWidget *druid);
+	gboolean (*cancel)	(GnomeDruidPage *druid_page, GtkWidget *druid);
+
+	/* Signal used for relaying out the canvas */
+	void     (*configure_canvas) (GnomeDruidPage *druid_page);
+
+	/* virtual */
+	void	 (*set_sidebar_shown) (GnomeDruidPage *druid_page,
+				       gboolean sidebar_shown);
+};
+
+
+GtkType  gnome_druid_page_get_type		(void) G_GNUC_CONST;
+
+/* These are really to be only called from GnomeDruid */
+gboolean gnome_druid_page_next			(GnomeDruidPage *druid_page);
+void     gnome_druid_page_prepare		(GnomeDruidPage *druid_page);
+gboolean gnome_druid_page_back			(GnomeDruidPage *druid_page);
+gboolean gnome_druid_page_cancel		(GnomeDruidPage *druid_page);
+void     gnome_druid_page_finish		(GnomeDruidPage *druid_page);
+
+G_END_DECLS
+
+#endif /* __GNOME_DRUID_PAGE_H__ */
+
+
+
+
diff --git a/libgnomeui/gnome-druid.c b/libgnomeui/gnome-druid.c
new file mode 100644
index 0000000..d534065
--- /dev/null
+++ b/libgnomeui/gnome-druid.c
@@ -0,0 +1,899 @@
+/* gnome-druid.c
+ * Copyright (C) 1999 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+*/
+#include <config.h>
+#include "gnome-macros.h"
+
+#include "gnome-druid.h"
+#include "gnome-stock.h"
+#include "gnome-uidefs.h"
+#include <libgnome/gnome-i18n.h>
+
+struct _GnomeDruidPrivate
+{
+	GnomeDruidPage *current;
+	GList *children;
+
+	gboolean show_finish : 1; /* if TRUE, then we are showing the finish button instead of the next button */
+};
+
+enum {
+	CANCEL,
+	LAST_SIGNAL
+};
+static void gnome_druid_init		(GnomeDruid		 *druid);
+static void gnome_druid_class_init	(GnomeDruidClass	 *klass);
+static void gnome_druid_destroy         (GtkObject               *object);
+static void gnome_druid_finalize        (GObject                 *object);
+static void gnome_druid_size_request    (GtkWidget               *widget,
+					 GtkRequisition          *requisition);
+static void gnome_druid_size_allocate   (GtkWidget               *widget,
+					 GtkAllocation           *allocation);
+static gint gnome_druid_expose          (GtkWidget               *widget,
+					 GdkEventExpose          *event);
+static void gnome_druid_map             (GtkWidget               *widget);
+static void gnome_druid_unmap           (GtkWidget               *widget);
+static GtkType gnome_druid_child_type   (GtkContainer            *container);
+static void gnome_druid_add             (GtkContainer            *widget,
+					 GtkWidget               *page);
+static void gnome_druid_remove          (GtkContainer            *widget,
+					 GtkWidget               *child);
+static void gnome_druid_forall          (GtkContainer            *container,
+					 gboolean                include_internals,
+					 GtkCallback             callback,
+					 gpointer                callback_data);
+static void gnome_druid_back_callback   (GtkWidget               *button,
+					 GnomeDruid              *druid);
+static void gnome_druid_next_callback   (GtkWidget               *button,
+					 GnomeDruid              *druid);
+static void gnome_druid_cancel_callback (GtkWidget               *button,
+					 GtkWidget               *druid);
+
+static guint druid_signals[LAST_SIGNAL] = { 0 };
+
+/* define the _get_type method and parent_class */
+GNOME_CLASS_BOILERPLATE(GnomeDruid, gnome_druid, GtkContainer, gtk_container)
+
+static void
+gnome_druid_class_init (GnomeDruidClass *klass)
+{
+	GtkObjectClass *object_class;
+	GObjectClass *gobject_class;
+	GtkWidgetClass *widget_class;
+	GtkContainerClass *container_class;
+
+	object_class = (GtkObjectClass*) klass;
+	gobject_class = (GObjectClass*) klass;
+	widget_class = (GtkWidgetClass*) klass;
+	container_class = (GtkContainerClass*) klass;
+
+	druid_signals[CANCEL] = 
+		gtk_signal_new ("cancel",
+				GTK_RUN_LAST,
+				GTK_CLASS_TYPE (object_class),
+				GTK_SIGNAL_OFFSET (GnomeDruidClass, cancel),
+				gtk_marshal_NONE__NONE,
+				GTK_TYPE_NONE, 0);
+	
+	
+	object_class->destroy = gnome_druid_destroy;
+	gobject_class->finalize = gnome_druid_finalize;
+	widget_class->size_request = gnome_druid_size_request;
+	widget_class->size_allocate = gnome_druid_size_allocate;
+	widget_class->map = gnome_druid_map;
+	widget_class->unmap = gnome_druid_unmap;
+	widget_class->expose_event = gnome_druid_expose;
+
+	container_class->forall = gnome_druid_forall;
+	container_class->add = gnome_druid_add;
+	container_class->remove = gnome_druid_remove;
+	container_class->child_type = gnome_druid_child_type;
+}
+
+static void
+gnome_druid_init (GnomeDruid *druid)
+{
+	GtkWidget *pixmap;
+
+	druid->_priv = g_new0(GnomeDruidPrivate, 1);
+
+	/* set the default border width */
+	GTK_CONTAINER (druid)->border_width = GNOME_PAD_SMALL;
+
+	/* set up the buttons */
+	GTK_WIDGET_SET_FLAGS (GTK_WIDGET (druid), GTK_NO_WINDOW);
+	pixmap =  gnome_stock_new_with_icon(GNOME_STOCK_BUTTON_PREV);
+	druid->back = gnome_pixmap_button (pixmap, _("Back"));
+	GTK_WIDGET_SET_FLAGS (druid->back, GTK_CAN_DEFAULT);
+	druid->next = gnome_stock_or_ordinary_button (GNOME_STOCK_BUTTON_NEXT);
+	GTK_WIDGET_SET_FLAGS (druid->next, GTK_CAN_DEFAULT);
+	GTK_WIDGET_SET_FLAGS (druid->next, GTK_HAS_FOCUS);
+	druid->cancel = gnome_stock_or_ordinary_button (GNOME_STOCK_BUTTON_CANCEL);
+	GTK_WIDGET_SET_FLAGS (druid->cancel, GTK_CAN_DEFAULT);
+	pixmap =  gnome_stock_new_with_icon(GNOME_STOCK_BUTTON_APPLY);
+	druid->finish = gnome_pixmap_button (pixmap, _("Finish"));
+	GTK_WIDGET_SET_FLAGS (druid->finish, GTK_CAN_DEFAULT);
+	gtk_widget_set_parent (druid->back, GTK_WIDGET (druid));
+	gtk_widget_set_parent (druid->next, GTK_WIDGET (druid));
+	gtk_widget_set_parent (druid->cancel, GTK_WIDGET (druid));
+	gtk_widget_set_parent (druid->finish, GTK_WIDGET (druid));
+	gtk_widget_show (druid->back);
+	gtk_widget_show (druid->next);
+	gtk_widget_show (druid->cancel);
+	gtk_widget_show (druid->finish);
+
+	/* other flags */
+	druid->_priv->current = NULL;
+	druid->_priv->children = NULL;
+	druid->_priv->show_finish = FALSE;
+	gtk_signal_connect (GTK_OBJECT (druid->back),
+			    "clicked",
+			    GTK_SIGNAL_FUNC (gnome_druid_back_callback),
+			    druid);
+	gtk_signal_connect (GTK_OBJECT (druid->next),
+			    "clicked",
+			    GTK_SIGNAL_FUNC (gnome_druid_next_callback),
+			    druid);
+	gtk_signal_connect (GTK_OBJECT (druid->cancel),
+			    "clicked",
+			    GTK_SIGNAL_FUNC (gnome_druid_cancel_callback),
+			    druid);
+	gtk_signal_connect (GTK_OBJECT (druid->finish),
+			    "clicked",
+			    GTK_SIGNAL_FUNC (gnome_druid_next_callback),
+			    druid);
+}
+
+
+
+static void
+gnome_druid_destroy (GtkObject *object)
+{
+	GnomeDruid *druid;
+
+	/* remember, destroy can be run multiple times! */
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GNOME_IS_DRUID (object));
+
+	druid = GNOME_DRUID (object);
+
+	if(druid->back) {
+		gtk_widget_destroy (druid->back);
+		druid->back = NULL;
+	}
+	if(druid->next) {
+		gtk_widget_destroy (druid->next);
+		druid->next = NULL;
+	}
+	if(druid->cancel) {
+		gtk_widget_destroy (druid->cancel);
+		druid->cancel = NULL;
+	}
+	if(druid->finish) {
+		gtk_widget_destroy (druid->finish);
+		druid->finish = NULL;
+	}
+
+	/* Remove all children, we set current to NULL so
+	 * that the remove code doesn't try to do anything funny */
+	druid->_priv->current = NULL;
+	while (druid->_priv->children != NULL) {
+		GnomeDruidPage *child = druid->_priv->children->data;
+		gtk_container_remove (GTK_CONTAINER (druid), GTK_WIDGET(child));
+	}
+
+	GNOME_CALL_PARENT_HANDLER (GTK_OBJECT_CLASS, destroy, (object));
+}
+
+static void
+gnome_druid_finalize (GObject *object)
+{
+	GnomeDruid *druid;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GNOME_IS_DRUID (object));
+
+	druid = GNOME_DRUID (object);
+
+	g_free(druid->_priv);
+	druid->_priv = NULL;
+
+	GNOME_CALL_PARENT_HANDLER (G_OBJECT_CLASS, finalize, (object));
+}
+
+static void
+gnome_druid_size_request (GtkWidget *widget,
+			  GtkRequisition *requisition)
+{
+	guint16 temp_width, temp_height;
+	GList *list;
+	GnomeDruid *druid;
+	GtkRequisition child_requisition;
+	GnomeDruidPage *child;
+	int border;
+	
+	g_return_if_fail (widget != NULL);
+	g_return_if_fail (GNOME_IS_DRUID (widget));
+
+	druid = GNOME_DRUID (widget);
+	temp_height = temp_width = 0;
+
+	border = GTK_CONTAINER(widget)->border_width;
+
+	/* We find the maximum size of all children widgets */
+	for (list = druid->_priv->children; list; list = list->next) {
+		child = GNOME_DRUID_PAGE (list->data);
+		if (GTK_WIDGET_VISIBLE (child)) {
+			gtk_widget_size_request (GTK_WIDGET (child), &child_requisition);
+			temp_width = MAX (temp_width, child_requisition.width);
+			temp_height = MAX (temp_height, child_requisition.height);
+			if (GTK_WIDGET_MAPPED (child) && child != druid->_priv->current)
+				gtk_widget_unmap (GTK_WIDGET(child));
+		}
+	}
+	
+        requisition->width = temp_width + 2 * border;
+        requisition->height = temp_height + 2 * border;
+
+	/* In an Attempt to show how the widgets are packed,
+	 * here's a little diagram.
+	 * 
+	 * ------------- [  Back  ] [  Next  ]    [ Cancel ]
+	 *    \
+	 *     This part needs to be at least 1 button width.
+	 *     In addition, there is 1/4 X Button width between Cancel and Next,
+	 *     and a GNOME_PAD_SMALL between Next and Back.
+	 */
+	/* our_button width is temp_width and temp_height */
+	temp_height = 0;
+	temp_width = 0;
+
+	gtk_widget_size_request (druid->back, &child_requisition);
+	temp_width = MAX (temp_width, child_requisition.width);
+	temp_height = MAX (temp_height, child_requisition.height);
+
+	gtk_widget_size_request (druid->next, &child_requisition);
+	temp_width = MAX (temp_width, child_requisition.width);
+	temp_height = MAX (temp_height, child_requisition.height);
+
+	gtk_widget_size_request (druid->cancel, &child_requisition);
+	temp_width = MAX (temp_width, child_requisition.width);
+	temp_height = MAX (temp_height, child_requisition.height);
+
+	gtk_widget_size_request (druid->finish, &child_requisition);
+	temp_width = MAX (temp_width, child_requisition.width);
+	temp_height = MAX (temp_height, child_requisition.height);
+
+	temp_width += border * 2;
+	temp_height += GNOME_PAD_SMALL;
+
+	temp_width = temp_width * 17/4  + GNOME_PAD_SMALL * 3;
+
+	/* pick which is bigger, the buttons, or the GnomeDruidPages */
+	requisition->width = MAX (temp_width, requisition->width);
+	requisition->height += temp_height + GNOME_PAD_SMALL * 2;
+}
+
+static void
+gnome_druid_size_allocate (GtkWidget *widget,
+			   GtkAllocation *allocation)
+{
+	GnomeDruid *druid;
+	GtkAllocation child_allocation;
+	gint button_height;
+	GList *list;
+	int border;
+	
+	g_return_if_fail (widget != NULL);
+	g_return_if_fail (GNOME_IS_DRUID (widget));
+
+	druid = GNOME_DRUID (widget);
+	widget->allocation = *allocation;
+
+	border = GTK_CONTAINER(widget)->border_width;
+
+	/* deal with the buttons */
+	child_allocation.width = child_allocation.height = 0;
+	child_allocation.width = druid->back->requisition.width;
+	child_allocation.height = druid->back->requisition.height;
+	child_allocation.width = MAX (child_allocation.width,
+			    druid->next->requisition.width);
+	child_allocation.height = MAX (child_allocation.height,
+			    druid->next->requisition.height);
+	child_allocation.width = MAX (child_allocation.width,
+			    druid->cancel->requisition.width);
+	child_allocation.height = MAX (child_allocation.height,
+			    druid->cancel->requisition.height);
+
+	child_allocation.height += GNOME_PAD_SMALL;
+	button_height = child_allocation.height;
+	child_allocation.width += 2 * GNOME_PAD_SMALL;
+	child_allocation.x = allocation->x + allocation->width - GNOME_PAD_SMALL - child_allocation.width;
+	child_allocation.y = allocation->y + allocation->height - GNOME_PAD_SMALL - child_allocation.height;
+	gtk_widget_size_allocate (druid->cancel, &child_allocation);
+	child_allocation.x -= (child_allocation.width * 5 / 4);
+	gtk_widget_size_allocate (druid->next, &child_allocation);
+	gtk_widget_size_allocate (druid->finish, &child_allocation);
+	child_allocation.x -= (GNOME_PAD_SMALL + child_allocation.width);
+	gtk_widget_size_allocate (druid->back, &child_allocation);
+
+	/* Put up the GnomeDruidPage */
+	child_allocation.x = allocation->x + border;
+	child_allocation.y = allocation->y + border;
+	child_allocation.width =
+		((allocation->width - 2 * border) > 0) ?
+		(allocation->width - 2 * border):0;
+	child_allocation.height =
+		((allocation->height - 2 * border - GNOME_PAD_SMALL - button_height) > 0) ?
+		(allocation->height - 2 * border - GNOME_PAD_SMALL - button_height):0;
+	for (list = druid->_priv->children; list; list=list->next) {
+		GtkWidget *widget = GTK_WIDGET (list->data);
+		if (GTK_WIDGET_VISIBLE (widget)) {
+			gtk_widget_size_allocate (widget, &child_allocation);
+		}
+	}
+}
+
+static GtkType
+gnome_druid_child_type (GtkContainer *container)
+{
+	return gnome_druid_page_get_type ();
+}
+
+static void
+gnome_druid_map (GtkWidget *widget)
+{
+	GnomeDruid *druid;
+
+	g_return_if_fail (widget != NULL);
+	g_return_if_fail (GNOME_IS_DRUID (widget));
+
+	druid = GNOME_DRUID (widget);
+	GTK_WIDGET_SET_FLAGS (druid, GTK_MAPPED);
+
+	gtk_widget_map (druid->back);
+	if (druid->_priv->show_finish)
+		gtk_widget_map (druid->finish);
+	else
+		gtk_widget_map (druid->next);
+	gtk_widget_map (druid->cancel);
+	if (druid->_priv->current &&
+	    GTK_WIDGET_VISIBLE (druid->_priv->current) &&
+	    !GTK_WIDGET_MAPPED (druid->_priv->current)) {
+		gtk_widget_map (GTK_WIDGET (druid->_priv->current));
+	}
+}
+
+static void
+gnome_druid_unmap (GtkWidget *widget)
+{
+	GnomeDruid *druid;
+
+	g_return_if_fail (widget != NULL);
+	g_return_if_fail (GNOME_IS_DRUID (widget));
+
+	druid = GNOME_DRUID (widget);
+	GTK_WIDGET_UNSET_FLAGS (druid, GTK_MAPPED);
+
+	gtk_widget_unmap (druid->back);
+	if (druid->_priv->show_finish)
+		gtk_widget_unmap (druid->finish);
+	else
+		gtk_widget_unmap (druid->next);
+	gtk_widget_unmap (druid->cancel);
+	if (druid->_priv->current &&
+	    GTK_WIDGET_VISIBLE (druid->_priv->current) &&
+	    GTK_WIDGET_MAPPED (druid->_priv->current))
+		gtk_widget_unmap (GTK_WIDGET (druid->_priv->current));
+}
+static void
+gnome_druid_add (GtkContainer *widget,
+		 GtkWidget *page)
+{
+	g_return_if_fail (widget != NULL);
+	g_return_if_fail (GNOME_IS_DRUID (widget));
+	g_return_if_fail (page != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE (page));
+
+	gnome_druid_append_page (GNOME_DRUID (widget), GNOME_DRUID_PAGE (page));
+}
+static void
+gnome_druid_remove (GtkContainer *widget,
+		    GtkWidget *child)
+{
+	GnomeDruid *druid;
+	GList *list;
+	
+	g_return_if_fail (widget != NULL);
+	g_return_if_fail (GNOME_IS_DRUID (widget));
+	g_return_if_fail (child != NULL);
+
+	druid = GNOME_DRUID (widget);
+
+	list = g_list_find (druid->_priv->children, child);
+	/* Is it a page? */ 
+	if (list != NULL) {
+		/* If we are mapped and visible, we want to deal with changing the page. */
+		if ((GTK_WIDGET_MAPPED (GTK_WIDGET (widget))) &&
+		    (list->data == (gpointer) druid->_priv->current) &&
+		    (list->next != NULL)) {
+			gnome_druid_set_page (druid, GNOME_DRUID_PAGE (list->next->data));
+		}
+	}
+	druid->_priv->children = g_list_remove (druid->_priv->children, child);
+	gtk_widget_unparent (child);
+}
+
+static void
+gnome_druid_forall (GtkContainer *container,
+		    gboolean      include_internals,
+		    GtkCallback   callback,
+		    gpointer      callback_data)
+{
+	GnomeDruid *druid;
+	GnomeDruidPage *child;
+	GList *children;
+
+	g_return_if_fail (container != NULL);
+	g_return_if_fail (GNOME_IS_DRUID (container));
+	g_return_if_fail (callback != NULL);
+
+	druid = GNOME_DRUID (container);
+
+	children = druid->_priv->children;
+	while (children) {
+		child = children->data;
+		children = children->next;
+
+		(* callback) (GTK_WIDGET (child), callback_data);
+	}
+	if (include_internals) {
+		(* callback) (druid->back, callback_data);
+		(* callback) (druid->next, callback_data);
+		(* callback) (druid->cancel, callback_data);
+		(* callback) (druid->finish, callback_data);
+	}
+}
+
+static gint
+gnome_druid_expose (GtkWidget      *widget,
+		    GdkEventExpose *event)
+{
+	GnomeDruid *druid;
+	GtkWidget *child;
+	GList *children;
+
+	g_return_val_if_fail (widget != NULL, FALSE);
+	g_return_val_if_fail (GNOME_IS_DRUID (widget), FALSE);
+	g_return_val_if_fail (event != NULL, FALSE);
+
+	if (GTK_WIDGET_DRAWABLE (widget)) {
+		druid = GNOME_DRUID (widget);
+		children = druid->_priv->children;
+
+		while (children) {
+			child = GTK_WIDGET (children->data);
+			children = children->next;
+
+			gtk_container_propagate_expose (GTK_CONTAINER (widget),
+							child, event);
+		}
+		gtk_container_propagate_expose (GTK_CONTAINER (widget),
+						druid->back, event);
+		gtk_container_propagate_expose (GTK_CONTAINER (widget),
+						druid->next, event);
+		gtk_container_propagate_expose (GTK_CONTAINER (widget),
+						druid->cancel, event);
+		gtk_container_propagate_expose (GTK_CONTAINER (widget),
+						druid->finish, event);
+	}
+	return FALSE;
+}
+
+static void
+gnome_druid_back_callback (GtkWidget *button, GnomeDruid *druid)
+{
+	GList *list;
+	g_return_if_fail (druid->_priv->current != NULL);
+
+	if (gnome_druid_page_back (druid->_priv->current))
+		return;
+
+	/* Make sure that we have a next list item */
+	list = g_list_find (druid->_priv->children, druid->_priv->current);
+	g_return_if_fail (list->prev != NULL);
+	gnome_druid_set_page (druid, GNOME_DRUID_PAGE (list->prev->data));
+}
+static void
+gnome_druid_next_callback (GtkWidget *button, GnomeDruid *druid)
+{
+	GList *list;
+	g_return_if_fail (druid->_priv->current != NULL);
+
+	if (druid->_priv->show_finish == FALSE) {
+		if (gnome_druid_page_next (druid->_priv->current))
+			return;
+
+		/* Make sure that we have a next list item */
+		list = g_list_find (druid->_priv->children,
+				    druid->_priv->current);
+		/* this would be a bug */
+		g_assert (list != NULL);
+
+		list = list->next;
+		while (list != NULL &&
+		        ! GTK_WIDGET_VISIBLE (list->data))
+			list = list->next;
+
+		if ( ! list)
+			return;
+
+		gnome_druid_set_page (druid, GNOME_DRUID_PAGE (list->data));
+	} else {
+		gnome_druid_page_finish (druid->_priv->current);
+	}
+}
+static void
+gnome_druid_cancel_callback (GtkWidget *button, GtkWidget *druid)
+{
+     if (GNOME_DRUID (druid)->_priv->current) {
+	     if (gnome_druid_page_cancel (GNOME_DRUID (druid)->_priv->current))
+		     return;
+
+	     gtk_signal_emit (GTK_OBJECT (druid), druid_signals [CANCEL]);
+     }
+}
+
+/* Public Functions */
+/**
+ * gnome_druid_new:
+ *
+ * Description: Creates a new #GnomeDruid widget.  You need to add this
+ * to a dialog yourself, it is not a dialog.
+ *
+ * Returns:  A new #GnomeDruid widget
+ **/
+GtkWidget *
+gnome_druid_new (void)
+{
+	return GTK_WIDGET (gtk_type_new (gnome_druid_get_type ()));
+}
+
+/**
+ * gnome_druid_new_with_window:
+ * @title: A title of the window
+ * @parent: The parent of this window (transient_for)
+ * @close_on_cancel: Close the window when cancel is pressed
+ * @window: Optional return of the #GtkWindow created
+ *
+ * Description: Creates a new #GnomeDruid widget.  It also creates a new
+ * toplevel window with the title of @title (which can be %NULL) and a parent
+ * of @parent (which also can be %NULL).  The window and the druid will both be
+ * shown.  If you need the window widget pointer you can optionally get it
+ * through the last argument.  When the druid gets destroyed, so will the
+ * window that is created here.
+ *
+ * Returns:  A new #GnomeDruid widget
+ **/
+GtkWidget *
+gnome_druid_new_with_window (const char *title,
+			     GtkWindow *parent,
+			     gboolean close_on_cancel,
+			     GtkWidget **window)
+{
+	GtkWidget *druid = gtk_type_new (gnome_druid_get_type ());
+
+	/* make sure we always set window to NULL, even in 
+	 * case of precondition errors */
+	if (window != NULL)
+		*window = NULL;
+
+	g_return_val_if_fail (parent == NULL ||
+			      GTK_IS_WINDOW (parent),
+			      NULL);
+
+	gnome_druid_construct_with_window (GNOME_DRUID (druid),
+					   title,
+					   parent,
+					   close_on_cancel,
+					   window);
+
+	return druid;
+}
+
+/**
+ * gnome_druid_construct_with_window:
+ * @druid: The #GnomeDruid
+ * @title: A title of the window
+ * @parent: The parent of this window (transient_for)
+ * @close_on_cancel: Close the window when cancel is pressed
+ * @window: Optional return of the #GtkWindow created
+ *
+ * Description: Creates a new toplevel window with the title of @title (which
+ * can be %NULL) and a parent of @parent (which also can be %NULL).  The @druid
+ * will be placed inside this window.  The window and the druid will both be
+ * shown.  If you need the window widget pointer you can optionally get it
+ * through the last argument.  When the druid gets destroyed, so will the
+ * window that is created here.
+ * See #gnome_druid_new_with_window.
+ **/
+void
+gnome_druid_construct_with_window (GnomeDruid *druid,
+				   const char *title,
+				   GtkWindow *parent,
+				   gboolean close_on_cancel,
+				   GtkWidget **window)
+{
+	GtkWidget *win;
+
+	/* make sure we always set window to NULL, even in 
+	 * case of precondition errors */
+	if (window != NULL)
+		*window = NULL;
+
+	g_return_if_fail (druid != NULL);
+	g_return_if_fail (GNOME_IS_DRUID (druid));
+	g_return_if_fail (parent == NULL ||
+			  GTK_IS_WINDOW (parent));
+
+	win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+	if (title != NULL)
+		gtk_window_set_title (GTK_WINDOW (win), title);
+	if (parent != NULL)
+		gtk_window_set_transient_for (GTK_WINDOW (win),
+					      parent);
+
+	gtk_widget_show (GTK_WIDGET (druid));
+
+	gtk_container_add (GTK_CONTAINER (win), GTK_WIDGET (druid));
+
+	gtk_widget_show (win);
+
+	if (close_on_cancel) {
+		/* Use while_alive just for sanity */
+		gtk_signal_connect_object_while_alive
+			(GTK_OBJECT (druid), "cancel",
+			 GTK_SIGNAL_FUNC (gtk_widget_destroy),
+			 GTK_OBJECT (win));
+	}
+
+	/* When the druid gets destroyed so does the window */
+	/* Use while_alive just for sanity */
+	gtk_signal_connect_object_while_alive
+		(GTK_OBJECT (druid), "destroy",
+		 GTK_SIGNAL_FUNC (gtk_widget_destroy),
+		 GTK_OBJECT (win));
+
+	/* return the window */
+	if (window != NULL)
+		*window = win;
+}
+
+
+/**
+ * gnome_druid_set_buttons_sensitive
+ * @druid: A Druid.
+ * @back_sensitive: The sensitivity of the back button.
+ * @next_sensitive: The sensitivity of the next button.
+ * @cancel_sensitive: The sensitivity of the cancel button.
+ *
+ * Description: Sets the sensitivity of the @druid's control-buttons.  If the
+ * variables are TRUE, then they will be clickable.  This function is used
+ * primarily by the actual GnomeDruidPage widgets.
+ **/
+
+void
+gnome_druid_set_buttons_sensitive (GnomeDruid *druid,
+				   gboolean back_sensitive,
+				   gboolean next_sensitive,
+				   gboolean cancel_sensitive)
+{
+	g_return_if_fail (druid != NULL);
+	g_return_if_fail (GNOME_IS_DRUID (druid));
+
+	gtk_widget_set_sensitive (druid->back, back_sensitive);
+	gtk_widget_set_sensitive (druid->next, next_sensitive);
+	gtk_widget_set_sensitive (druid->cancel, cancel_sensitive);
+}
+
+static void
+undefault_button (GtkWidget *widget)
+{
+	GtkWidget *toplevel;
+
+	toplevel = gtk_widget_get_toplevel (widget);
+
+	if (GTK_IS_WINDOW (toplevel) &&
+	    GTK_WINDOW (toplevel)->default_widget == widget) {
+		gtk_window_set_default (GTK_WINDOW (toplevel), NULL);
+	}
+}
+
+/**
+ * gnome_druid_set_show_finish
+ * @druid: A Druid widget.
+ # @show_finish: If TRUE, then the "Cancel" button is changed to be "Finish"
+ *
+ * Description: Sets the text on the last button on the @druid.  If @show_finish
+ * is TRUE, then the text becomes "Finish".  If @show_finish is FALSE, then the
+ * text becomes "Cancel".
+ **/
+void
+gnome_druid_set_show_finish (GnomeDruid *druid,
+			     gboolean show_finish)
+{
+	g_return_if_fail (druid != NULL);
+	g_return_if_fail (GNOME_IS_DRUID (druid));
+
+	if (show_finish) {
+		undefault_button (druid->next);
+
+		if (GTK_WIDGET_MAPPED (druid->next)) {
+			gtk_widget_unmap (druid->next);
+			gtk_widget_map (druid->finish);
+		}
+	} else {
+		undefault_button (druid->finish);
+
+		if (GTK_WIDGET_MAPPED (druid->finish)) {
+			gtk_widget_unmap (druid->finish);
+			gtk_widget_map (druid->next);
+		}
+	}
+	druid->_priv->show_finish = show_finish;
+}
+/**
+ * gnome_druid_prepend_page:
+ * @druid: A Druid widget.
+ * @page: The page to be inserted.
+ * 
+ * Description: This will prepend a GnomeDruidPage into the internal list of
+ * pages that the @druid has.  Since #GnomeDruid is just a container, you will
+ * need to also call #gtk_widget_show on the page, otherwise the page will not
+ * be shown.
+ **/
+void
+gnome_druid_prepend_page (GnomeDruid *druid,
+			  GnomeDruidPage *page)
+{
+	g_return_if_fail (druid != NULL);
+	g_return_if_fail (GNOME_IS_DRUID (druid));
+	g_return_if_fail (page != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE (page));
+
+	gnome_druid_insert_page (druid, NULL, page);
+}
+/**
+ * gnome_druid_insert_page:
+ * @druid: A Druid widget.
+ * @back_page: The page prior to the page to be inserted.
+ * @page: The page to insert.
+ * 
+ * Description: This will insert @page after @back_page into the list of
+ * internal pages that the @druid has.  If @back_page is not present in the list
+ * or %NULL, @page will be prepended to the list.  Since #GnomeDruid is just a
+ * container, you will need to also call #gtk_widget_show on the page,
+ * otherwise the page will not be shown.
+ **/
+void
+gnome_druid_insert_page (GnomeDruid *druid,
+			 GnomeDruidPage *back_page,
+			 GnomeDruidPage *page)
+{
+	GList *list;
+
+	g_return_if_fail (druid != NULL);
+	g_return_if_fail (GNOME_IS_DRUID (druid));
+	g_return_if_fail (page != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE (page));
+
+	list = g_list_find (druid->_priv->children, back_page);
+	if (list == NULL) {
+		druid->_priv->children = g_list_prepend (druid->_priv->children, page);
+	} else {
+		GList *new_el = g_list_alloc ();
+		new_el->next = list->next;
+		new_el->prev = list;
+		if (new_el->next) 
+			new_el->next->prev = new_el;
+		new_el->prev->next = new_el;
+		new_el->data = (gpointer) page;
+	}
+	gtk_widget_set_parent (GTK_WIDGET (page), GTK_WIDGET (druid));
+
+	if (GTK_WIDGET_REALIZED (GTK_WIDGET (druid)))
+		gtk_widget_realize (GTK_WIDGET (page));
+
+	if (GTK_WIDGET_VISIBLE (GTK_WIDGET (druid)) && GTK_WIDGET_VISIBLE (GTK_WIDGET (page))) {
+		if (GTK_WIDGET_MAPPED (GTK_WIDGET (page)))
+			gtk_widget_unmap (GTK_WIDGET (page));
+		gtk_widget_queue_resize (GTK_WIDGET (druid));
+	}
+
+	/* if it's the first and only page, we want to bring it to the foreground. */
+	if (druid->_priv->children->next == NULL)
+		gnome_druid_set_page (druid, page);
+}
+
+/**
+ * gnome_druid_append_page: 
+ * @druid: A Druid widget.
+ * @page: The #GnomeDruidPage to be appended.
+ * 
+ * Description: This will append @page onto the end of the internal list.  
+ * Since #GnomeDruid is just a container, you will need to also call
+ * #gtk_widget_show on the page, otherwise the page will not be shown.
+ **/
+void
+gnome_druid_append_page (GnomeDruid *druid,
+			 GnomeDruidPage *page)
+{
+	GList *list;
+	g_return_if_fail (druid != NULL);
+	g_return_if_fail (GNOME_IS_DRUID (druid));
+	g_return_if_fail (page != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE (page));
+
+	list = g_list_last (druid->_priv->children);
+	if (list) {
+		gnome_druid_insert_page (druid, GNOME_DRUID_PAGE (list->data), page);
+	} else {
+		gnome_druid_insert_page (druid, NULL, page);
+	}	
+}
+/**
+ * gnome_druid_set_page:
+ * @druid: A Druid widget.
+ * @page: The #GnomeDruidPage to be brought to the foreground.
+ * 
+ * Description: This will make @page the currently showing page in the druid.
+ * @page must already be in the druid.
+ **/
+void
+gnome_druid_set_page (GnomeDruid *druid,
+		      GnomeDruidPage *page)
+{
+	GList *list;
+	GtkWidget *old = NULL;
+	g_return_if_fail (druid != NULL);
+	g_return_if_fail (GNOME_IS_DRUID (druid));
+	g_return_if_fail (page != NULL);
+	g_return_if_fail (GNOME_IS_DRUID_PAGE (page));
+
+	if (druid->_priv->current == page)
+	     return;
+	list = g_list_find (druid->_priv->children, page);
+	g_return_if_fail (list != NULL);
+
+	if ((druid->_priv->current) && (GTK_WIDGET_VISIBLE (druid->_priv->current)) && (GTK_WIDGET_MAPPED (druid))) {
+		old = GTK_WIDGET (druid->_priv->current);
+	}
+	druid->_priv->current = GNOME_DRUID_PAGE (list->data);
+	gnome_druid_page_prepare (druid->_priv->current);
+	if (GTK_WIDGET_VISIBLE (druid->_priv->current) && (GTK_WIDGET_MAPPED (druid))) {
+		gtk_widget_map (GTK_WIDGET (druid->_priv->current));
+	}
+	if (old && GTK_WIDGET_MAPPED (old))
+	  gtk_widget_unmap (old);
+}
diff --git a/libgnomeui/gnome-druid.h b/libgnomeui/gnome-druid.h
new file mode 100644
index 0000000..11e69bb
--- /dev/null
+++ b/libgnomeui/gnome-druid.h
@@ -0,0 +1,89 @@
+/* gnome-druid.h
+ * Copyright (C) 1999  Red Hat, Inc.
+ * All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+*/
+/* TODO: allow setting bgcolor for all pages globally */
+#ifndef __GNOME_DRUID_H__
+#define __GNOME_DRUID_H__
+
+#include <gtk/gtk.h>
+#include "gnome-druid-page.h"
+
+
+G_BEGIN_DECLS
+
+#define GNOME_TYPE_DRUID            (gnome_druid_get_type ())
+#define GNOME_DRUID(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_DRUID, GnomeDruid))
+#define GNOME_DRUID_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_DRUID, GnomeDruidClass))
+#define GNOME_IS_DRUID(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_DRUID))
+#define GNOME_IS_DRUID_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_DRUID))
+#define GNOME_DRUID_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_DRUID, GnomeDruidClass))
+
+
+typedef struct _GnomeDruid        GnomeDruid;
+typedef struct _GnomeDruidPrivate GnomeDruidPrivate;
+typedef struct _GnomeDruidClass   GnomeDruidClass;
+
+struct _GnomeDruid
+{
+	GtkContainer parent;
+	GtkWidget *back;
+	GtkWidget *next;
+	GtkWidget *cancel;
+	GtkWidget *finish;
+
+	/*< private >*/
+	GnomeDruidPrivate *_priv;
+};
+struct _GnomeDruidClass
+{
+	GtkContainerClass parent_class;
+	
+	void     (*cancel)	(GnomeDruid *druid);
+};
+
+
+GtkType    gnome_druid_get_type              (void) G_GNUC_CONST;
+GtkWidget *gnome_druid_new                   (void);
+void	   gnome_druid_set_buttons_sensitive (GnomeDruid *druid,
+					      gboolean back_sensitive,
+					      gboolean next_sensitive,
+					      gboolean cancel_sensitive);
+void	   gnome_druid_set_show_finish       (GnomeDruid *druid, gboolean show_finish);
+void       gnome_druid_prepend_page          (GnomeDruid *druid, GnomeDruidPage *page);
+void       gnome_druid_insert_page           (GnomeDruid *druid, GnomeDruidPage *back_page, GnomeDruidPage *page);
+void       gnome_druid_append_page           (GnomeDruid *druid, GnomeDruidPage *page);
+void	   gnome_druid_set_page              (GnomeDruid *druid, GnomeDruidPage *page);
+
+/* Pure sugar, methods for making new druids with a window already */
+GtkWidget *gnome_druid_new_with_window       (const char *title,
+					      GtkWindow *parent,
+					      gboolean close_on_cancel,
+					      GtkWidget **window);
+void       gnome_druid_construct_with_window (GnomeDruid *druid,
+					      const char *title,
+					      GtkWindow *parent,
+					      gboolean close_on_cancel,
+					      GtkWidget **window);
+
+G_END_DECLS
+
+#endif /* __GNOME_DRUID_H__ */
diff --git a/libgnomeui/gnome-entry.c b/libgnomeui/gnome-entry.c
new file mode 100644
index 0000000..eee06a6
--- /dev/null
+++ b/libgnomeui/gnome-entry.c
@@ -0,0 +1,390 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+/* GnomeEntry widget - combo box with auto-saved history
+ *
+ * Author: Federico Mena <federico nuclecu unam mx>
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtkcombo.h>
+#include <gtk/gtklist.h>
+#include <gtk/gtklistitem.h>
+#include <gtk/gtksignal.h>
+#include <libgnome/gnome-i18n.h>
+#include "gnome-macros.h"
+#include "gnome-entry.h"
+
+struct _GnomeEntryPrivate {
+	GtkWidget *combo;
+	GtkWidget *entry;
+};
+	
+
+static void   gnome_entry_class_init   (GnomeEntryClass *class);
+static void   gnome_entry_init         (GnomeEntry      *gentry);
+static void   gnome_entry_destroy      (GtkObject       *object);
+static void   gnome_entry_finalize     (GObject         *object);
+
+static gchar *get_entry_text_handler   (GnomeSelector   *selector);
+static void   set_entry_text_handler   (GnomeSelector   *selector,
+                                        const gchar     *text);
+static void   activate_entry_handler   (GnomeSelector   *selector);
+static void   history_changed_handler  (GnomeSelector   *selector);
+static void   entry_activated_cb       (GtkWidget       *widget,
+                                        gpointer         data);
+static void   do_construct_handler     (GnomeSelector   *selector);
+
+
+static GObject*
+gnome_entry_constructor (GType                  type,
+			 guint                  n_construct_properties,
+			 GObjectConstructParam *construct_properties);
+
+
+static GnomeSelectorClass *parent_class;
+
+guint
+gnome_entry_get_type (void)
+{
+	static guint entry_type = 0;
+
+	if (!entry_type) {
+		GtkTypeInfo entry_info = {
+			"GnomeEntry",
+			sizeof (GnomeEntry),
+			sizeof (GnomeEntryClass),
+			(GtkClassInitFunc) gnome_entry_class_init,
+			(GtkObjectInitFunc) gnome_entry_init,
+			NULL,
+			NULL,
+			NULL
+		};
+
+		entry_type = gtk_type_unique (gnome_selector_get_type (), &entry_info);
+	}
+
+	return entry_type;
+}
+
+static void
+gnome_entry_class_init (GnomeEntryClass *class)
+{
+	GnomeSelectorClass *selector_class;
+	GtkObjectClass *object_class;
+	GObjectClass *gobject_class;
+
+	selector_class = (GnomeSelectorClass *) class;
+	object_class = (GtkObjectClass *) class;
+	gobject_class = (GObjectClass *) class;
+
+	parent_class = gtk_type_class (gnome_selector_get_type ());
+
+	object_class->destroy = gnome_entry_destroy;
+	gobject_class->finalize = gnome_entry_finalize;
+
+	gobject_class->constructor = gnome_entry_constructor;
+
+	selector_class->get_entry_text = get_entry_text_handler;
+	selector_class->set_entry_text = set_entry_text_handler;
+	selector_class->activate_entry = activate_entry_handler;
+	selector_class->history_changed = history_changed_handler;
+
+	selector_class->do_construct = do_construct_handler;
+}
+
+static void
+gnome_entry_init (GnomeEntry *gentry)
+{
+	gentry->_priv = g_new0(GnomeEntryPrivate, 1);
+}
+
+static gboolean
+get_value_boolean (GnomeEntry *gentry, const gchar *prop_name)
+{
+	GValue value = { 0, };
+	gboolean retval;
+
+	g_value_init (&value, G_TYPE_BOOLEAN);
+	g_object_get_property (G_OBJECT (gentry), prop_name, &value);
+	retval = g_value_get_boolean (&value);
+	g_value_unset (&value);
+
+	return retval;
+}
+
+static gboolean
+has_value_widget (GnomeEntry *gentry, const gchar *prop_name)
+{
+	GValue value = { 0, };
+	gboolean retval;
+
+	g_value_init (&value, GTK_TYPE_WIDGET);
+	g_object_get_property (G_OBJECT (gentry), prop_name, &value);
+	retval = g_value_get_object (&value) != NULL;
+	g_value_unset (&value);
+
+	return retval;
+}
+
+static void
+do_construct_handler (GnomeSelector *selector)
+{
+	GnomeEntry *gentry;
+
+	g_return_if_fail (selector != NULL);
+	g_return_if_fail (GNOME_IS_ENTRY (selector));
+
+	gentry = GNOME_ENTRY (selector);
+
+	g_message (G_STRLOC);
+
+	if (get_value_boolean (gentry, "want_default_behaviour")) {
+		g_object_set (G_OBJECT (gentry),
+			      "want_default_behaviour", FALSE,
+			      "use_default_entry_widget", TRUE,
+			      "want_browse_button", FALSE,
+			      "want_clear_button", FALSE,
+			      "want_default_button", FALSE,
+			      NULL);
+	}
+
+	if (get_value_boolean (gentry, "use_default_entry_widget") &&
+	    !has_value_widget (gentry, "entry_widget")) {
+		GtkWidget *entry_widget;
+		GValue value = { 0, };
+
+		g_message (G_STRLOC ": default entry");
+
+		entry_widget = gtk_combo_new ();
+
+		g_value_init (&value, GTK_TYPE_WIDGET);
+		g_value_set_object (&value, G_OBJECT (entry_widget));
+		g_object_set_property (G_OBJECT (gentry), "entry_widget", &value);
+		g_value_unset (&value);
+
+		gentry->_priv->combo = entry_widget;
+		gentry->_priv->entry = GTK_COMBO (entry_widget)->entry;
+
+		gtk_combo_disable_activate (GTK_COMBO (entry_widget));
+		gtk_combo_set_case_sensitive (GTK_COMBO (entry_widget), TRUE);
+
+		gtk_signal_connect (GTK_OBJECT (gentry->_priv->entry),
+				    "activate",
+				    GTK_SIGNAL_FUNC (entry_activated_cb),
+				    gentry);
+	}
+
+	GNOME_CALL_PARENT_HANDLER (GNOME_SELECTOR_CLASS, do_construct, (selector));
+}
+
+static GObject*
+gnome_entry_constructor (GType                  type,
+			 guint                  n_construct_properties,
+			 GObjectConstructParam *construct_properties)
+{
+	GObject *object = G_OBJECT_CLASS (parent_class)->constructor (type,
+								      n_construct_properties,
+								      construct_properties);
+	GnomeEntry *gentry = GNOME_ENTRY (object);
+
+	g_message (G_STRLOC ": %d - %d", type, GNOME_TYPE_ENTRY);
+
+	if (type == GNOME_TYPE_ENTRY)
+		gnome_selector_do_construct (GNOME_SELECTOR (gentry));
+
+	g_message (G_STRLOC);
+
+	return object;
+}
+
+
+/**
+ * gnome_entry_new
+ * @history_id: If not %NULL, the text id under which history data is stored
+ *
+ * Description: Creates a new GnomeEntry widget.  If  @history_id is
+ * not %NULL, then the history list will be saved and restored between
+ * uses under the given id.
+ *
+ * Returns: Newly-created GnomeEntry widget.
+ */
+GtkWidget *
+gnome_entry_new (const gchar *history_id)
+{
+	GnomeEntry *gentry;
+
+	gentry = g_object_new (gnome_entry_get_type (),
+			       "history_id", history_id,
+			       NULL);
+
+	return GTK_WIDGET (gentry);
+}
+
+static void
+gnome_entry_destroy (GtkObject *object)
+{
+	GnomeEntry *gentry;
+
+	/* remember, destroy can be run multiple times! */
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GNOME_IS_ENTRY (object));
+
+	gentry = GNOME_ENTRY (object);
+
+	if (GTK_OBJECT_CLASS (parent_class)->destroy)
+		(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gnome_entry_finalize (GObject *object)
+{
+	GnomeEntry *gentry;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GNOME_IS_ENTRY (object));
+
+	gentry = GNOME_ENTRY (object);
+
+	g_free (gentry->_priv);
+	gentry->_priv = NULL;
+
+	if (G_OBJECT_CLASS (parent_class)->finalize)
+		(* G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+static gchar *
+get_entry_text_handler (GnomeSelector *selector)
+{
+	GnomeEntry *gentry;
+	const char *text;
+
+	g_return_val_if_fail (selector != NULL, NULL);
+	g_return_val_if_fail (GNOME_IS_ENTRY (selector), NULL);
+
+	gentry = GNOME_ENTRY (selector);
+
+	text = gtk_entry_get_text (GTK_ENTRY (gentry->_priv->entry));
+	return g_strdup (text);
+}
+
+static void
+set_entry_text_handler (GnomeSelector *selector, const gchar *text)
+{
+	GnomeEntry *gentry;
+
+	g_return_if_fail (selector != NULL);
+	g_return_if_fail (GNOME_IS_ENTRY (selector));
+
+	gentry = GNOME_ENTRY (selector);
+
+	if (gentry->_priv->entry)
+		gtk_entry_set_text (GTK_ENTRY (gentry->_priv->entry), text);
+}
+
+static void
+activate_entry_handler (GnomeSelector *selector)
+{
+	GnomeEntry *gentry;
+	const char *text;
+
+	g_return_if_fail (selector != NULL);
+	g_return_if_fail (GNOME_IS_ENTRY (selector));
+
+	gentry = GNOME_ENTRY (selector);
+
+	text = gtk_entry_get_text (GTK_ENTRY (gentry->_priv->entry));
+	gnome_selector_prepend_history (selector, TRUE, text);
+}
+
+static void
+history_changed_handler (GnomeSelector *selector)
+{
+	GnomeEntry *gentry;
+	GtkWidget *list_widget;
+	GList *items = NULL;
+	GSList *history_list, *c;
+
+	g_return_if_fail (selector != NULL);
+	g_return_if_fail (GNOME_IS_ENTRY (selector));
+
+	gentry = GNOME_ENTRY (selector);
+
+	list_widget = GTK_COMBO (gentry->_priv->combo)->list;
+
+	gtk_list_clear_items (GTK_LIST (list_widget), 0, -1);
+
+	history_list = gnome_selector_get_history (GNOME_SELECTOR (gentry));
+
+	for (c = history_list; c; c = c->next) {
+		GtkWidget *item;
+
+		item = gtk_list_item_new_with_label (c->data);
+		items = g_list_prepend (items, item);
+		gtk_widget_show_all (item);
+	}
+
+	items = g_list_reverse (items);
+
+	gtk_list_prepend_items (GTK_LIST (list_widget), items);
+
+	g_slist_foreach (history_list, (GFunc) g_free, NULL);
+	g_slist_free (history_list);
+}
+
+static void
+entry_activated_cb (GtkWidget *widget, gpointer data)
+{
+	g_return_if_fail (data != NULL);
+	g_return_if_fail (GNOME_IS_SELECTOR (data));
+
+	gnome_selector_activate_entry (GNOME_SELECTOR (data));
+}
+
+gchar *
+gnome_entry_get_text (GnomeEntry *gentry)
+{
+	g_return_val_if_fail (gentry != NULL, NULL);
+	g_return_val_if_fail (GNOME_IS_ENTRY (gentry), NULL);
+
+	return gnome_selector_get_uri (GNOME_SELECTOR (gentry));
+}
+
+void
+gnome_entry_set_text (GnomeEntry *gentry, const gchar *text)
+{
+	g_return_if_fail (gentry != NULL);
+	g_return_if_fail (GNOME_IS_ENTRY (gentry));
+
+	gnome_selector_set_uri (GNOME_SELECTOR (gentry), NULL,
+				text, NULL, NULL);
+}
+
diff --git a/libgnomeui/gnome-entry.h b/libgnomeui/gnome-entry.h
new file mode 100644
index 0000000..879559f
--- /dev/null
+++ b/libgnomeui/gnome-entry.h
@@ -0,0 +1,78 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+/* GnomeEntry widget - combo box with auto-saved history
+ *
+ * Author: Federico Mena <federico nuclecu unam mx>
+ */
+
+#ifndef GNOME_ENTRY_H
+#define GNOME_ENTRY_H
+
+
+#include <glib.h>
+
+#include "gnome-selector.h"
+
+
+G_BEGIN_DECLS
+
+
+#define GNOME_TYPE_ENTRY            (gnome_entry_get_type ())
+#define GNOME_ENTRY(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_ENTRY, GnomeEntry))
+#define GNOME_ENTRY_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_ENTRY, GnomeEntryClass))
+#define GNOME_IS_ENTRY(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_ENTRY))
+#define GNOME_IS_ENTRY_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_ENTRY))
+#define GNOME_ENTRY_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_ENTRY, GnomeEntryClass))
+
+
+typedef struct _GnomeEntry        GnomeEntry;
+typedef struct _GnomeEntryPrivate GnomeEntryPrivate;
+typedef struct _GnomeEntryClass   GnomeEntryClass;
+
+struct _GnomeEntry {
+	GnomeSelector selector;
+
+	/*< private >*/
+	GnomeEntryPrivate *_priv;
+};
+
+struct _GnomeEntryClass {
+	GnomeSelectorClass parent_class;
+};
+
+
+guint        gnome_entry_get_type         (void) G_GNUC_CONST;
+GtkWidget   *gnome_entry_new              (const gchar *history_id);
+
+gchar       *gnome_entry_get_text         (GnomeEntry  *gentry);
+
+void         gnome_entry_set_text         (GnomeEntry  *gentry,
+					   const gchar *text);
+
+G_END_DECLS
+
+#endif
diff --git a/libgnomeui/gnome-file-saver.c b/libgnomeui/gnome-file-saver.c
new file mode 100644
index 0000000..62ce7df
--- /dev/null
+++ b/libgnomeui/gnome-file-saver.c
@@ -0,0 +1,718 @@
+/*  -*- Mode: C; c-set-style: linux; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* GNOME GUI Library - gnome-file-saver.c
+ * Copyright (C) 2000  Red Hat Inc.
+ * All rights reserved.
+ *
+ * Author: Havoc Pennington <hp redhat com>
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#include "gnome-file-saver.h"
+#include "gnome-gconf.h"
+#include "gnome-pixmap.h"
+#include <gtk/gtk.h>
+#include <libgnome/gnome-i18n.h>
+#include <libgnome/gnome-util.h>
+#include "gtkpixmapmenuitem.h"
+#include "gnome-stock.h"
+
+#include <libgnomevfs/gnome-vfs-mime.h>
+
+struct _GnomeFileSaverPrivate {
+        GtkWidget *filename_entry;
+
+        GtkWidget *location_option;
+        GtkWidget *location_menu;
+        
+        GConfClient *conf;
+        guint        conf_notify;
+
+        GSList      *locations;
+
+        GtkWidget   *type_option;
+        GtkWidget   *type_menu;
+        GtkWidget   *type_pixmap;
+        GtkWidget   *type_label;
+};
+
+
+
+enum {
+        FINISHED,
+        LAST_SIGNAL
+};
+
+enum {
+        ARG_0,
+        LAST_ARG
+};
+
+static void gnome_file_saver_init (GnomeFileSaver* file_saver);
+static void gnome_file_saver_class_init (GnomeFileSaverClass* klass);
+static void gnome_file_saver_destroy (GtkObject* object);
+static void gnome_file_saver_finalize (GObject* object);
+static void gnome_file_saver_set_arg (GtkObject* object, GtkArg* arg, guint arg_id);
+static void gnome_file_saver_get_arg (GtkObject* object, GtkArg* arg, guint arg_id);
+
+static void locations_changed_notify(GConfClient* client, guint cnxn_id, GConfEntry * entry, gpointer user_data);
+
+static void
+gnome_file_saver_remove_location(GnomeFileSaver* file_saver,
+                                 const gchar* gconf_key);
+static void
+gnome_file_saver_update_location(GnomeFileSaver* file_saver,
+                                 const gchar* gconf_key,
+                                 GConfValue* gconf_value);
+
+static GnomeDialog* parent_class = NULL;
+static guint signals[LAST_SIGNAL] = { 0 };
+
+GtkType
+gnome_file_saver_get_type (void)
+{
+        static GtkType our_type = 0;
+
+        if (our_type == 0) {
+                static const GtkTypeInfo our_info = {
+                        "GnomeFileSaver",
+                        sizeof (GnomeFileSaver),
+                        sizeof (GnomeFileSaverClass),
+                        (GtkClassInitFunc) gnome_file_saver_class_init,
+                        (GtkObjectInitFunc) gnome_file_saver_init,
+                        /* reserved_1 */ NULL,
+                        /* reserved_2 */ NULL,
+                        (GtkClassInitFunc) NULL
+                };
+
+                our_type = gtk_type_unique (gnome_dialog_get_type(), &our_info);
+        }
+        
+        return our_type;
+}
+
+static void
+gnome_file_saver_class_init (GnomeFileSaverClass* klass)
+{
+        GtkObjectClass* object_class;
+        GObjectClass* gobject_class;
+
+        object_class = (GtkObjectClass*) klass;
+        gobject_class = (GObjectClass*) klass;
+
+        parent_class = gtk_type_class (gnome_dialog_get_type());
+
+        signals[FINISHED] =
+                gtk_signal_new ("finished",
+                                GTK_RUN_LAST,
+                                GTK_CLASS_TYPE (object_class),
+                                GTK_SIGNAL_OFFSET (GnomeFileSaverClass, finished),
+                                gtk_marshal_NONE__POINTER_POINTER,
+                                GTK_TYPE_NONE,
+				2,
+				GTK_TYPE_STRING,
+				GTK_TYPE_STRING);
+        
+        gtk_object_class_add_signals (object_class, signals, 
+                                      LAST_SIGNAL);
+
+	klass->finished = NULL;
+        
+        object_class->set_arg = gnome_file_saver_set_arg;
+        object_class->get_arg = gnome_file_saver_get_arg;
+
+        object_class->destroy = gnome_file_saver_destroy;
+        gobject_class->finalize = gnome_file_saver_finalize;
+}
+
+void
+gnome_file_saver_init (GnomeFileSaver* file_saver)
+{
+        GnomeDialog *dialog;
+        GSList *all_entries;
+        GSList *iter;
+        GtkWidget *hbox;
+        GtkWidget *table;
+        GtkWidget *label;
+        GtkWidget *frame;
+        GtkWidget *vbox;
+        gchar *icon;
+
+	file_saver->_priv = g_new0(GnomeFileSaverPrivate, 1);
+
+        gtk_window_set_policy(GTK_WINDOW(file_saver), FALSE, TRUE, FALSE);
+        
+        dialog = GNOME_DIALOG(file_saver);
+
+        hbox = gtk_hbox_new(FALSE, 6);
+
+        gtk_box_pack_start (GTK_BOX(dialog->vbox),
+                            hbox,
+                            FALSE, FALSE, 6);
+
+        icon = gnome_pixmap_file("mc/i-regular.png");
+
+        if (icon)
+                file_saver->_priv->type_pixmap = gnome_pixmap_new_from_file (icon);
+        else
+                file_saver->_priv->type_pixmap = gnome_pixmap_new ();
+
+        g_free (icon);
+        
+        frame = gtk_frame_new (NULL);
+        vbox = gtk_vbox_new (FALSE, 0);
+        gtk_container_add (GTK_CONTAINER (vbox), frame);
+        gtk_container_add (GTK_CONTAINER (frame), file_saver->_priv->type_pixmap);
+        
+        gtk_box_pack_start (GTK_BOX(hbox),
+                            vbox,
+                            FALSE, FALSE, 6);
+        
+        table = gtk_table_new (2, 3, FALSE);
+
+        gtk_box_pack_end (GTK_BOX(hbox),
+                          table,
+                          TRUE, TRUE, 6);
+        
+        label = gtk_label_new(_("File Name:"));
+        gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
+        gtk_table_attach (GTK_TABLE(table),
+                          label,
+                          0, 1,
+                          0, 1,
+                          GTK_FILL, GTK_FILL, 3, 3);
+
+        label = gtk_label_new(_("Location:"));
+        gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
+        gtk_table_attach (GTK_TABLE(table),
+                          label,
+                          0, 1,
+                          1, 2,
+                          GTK_FILL, GTK_FILL, 3, 3);
+
+        file_saver->_priv->type_label =  gtk_label_new(_("Save As Type:"));
+        gtk_misc_set_alignment(GTK_MISC(file_saver->_priv->type_label), 0.0, 0.5);
+        gtk_table_attach (GTK_TABLE(table),
+                          file_saver->_priv->type_label,
+                          0, 1,
+                          2, 3,
+                          GTK_FILL, GTK_FILL, 3, 3);
+        
+        file_saver->_priv->filename_entry = gtk_entry_new();
+
+        file_saver->_priv->location_option = gtk_option_menu_new();        
+        file_saver->_priv->location_menu = gtk_menu_new();
+
+        file_saver->_priv->type_option = gtk_option_menu_new();        
+        file_saver->_priv->type_menu = gtk_menu_new();
+        
+        gtk_table_attach (GTK_TABLE(table),
+                          file_saver->_priv->filename_entry,
+                          1, 2,
+                          0, 1,
+                          GTK_FILL | GTK_EXPAND,
+                          GTK_FILL,
+                          3, 3);
+
+        gtk_table_attach (GTK_TABLE(table),
+                          file_saver->_priv->location_option,
+                          1, 2,
+                          1, 2,
+                          GTK_FILL | GTK_EXPAND,
+                          GTK_FILL,
+                          3, 3);
+
+        gtk_table_attach (GTK_TABLE(table),
+                          file_saver->_priv->type_option,
+                          1, 2,
+                          2, 3,
+                          GTK_FILL | GTK_EXPAND,
+                          GTK_FILL,
+                          3, 3);
+        
+        /*
+         * Get the GConfClient object
+         */ 
+        
+        file_saver->_priv->conf = gnome_get_gconf_client();
+
+        g_object_ref(G_OBJECT(file_saver->_priv->conf));
+
+        /*
+         * Fill in the Location menu
+         */
+        
+        /* No preload because the explicit all_entries call below
+           effectively results in a preload. */
+        gconf_client_add_dir(file_saver->_priv->conf,
+                             "/desktop/standard/save-locations",
+                             GCONF_CLIENT_PRELOAD_NONE, NULL);
+
+        all_entries =
+                gconf_client_all_entries(file_saver->_priv->conf,
+                                         "/desktop/standard/save-locations",
+                                         NULL);
+
+        iter = all_entries;
+        while (iter != NULL) {
+                GConfEntry *entry = iter->data;
+                gchar* full_key;
+
+                full_key = gconf_concat_dir_and_key("/desktop/standard/save-locations",
+                                                    gconf_entry_get_key(entry));
+
+                
+                gnome_file_saver_update_location(file_saver,
+                                                 full_key,
+                                                 gconf_entry_get_value(entry));
+
+                g_free(full_key);
+                gconf_entry_free(entry);
+                
+                iter = g_slist_next(iter);
+        }
+        g_slist_free(all_entries);
+        
+        file_saver->_priv->conf_notify =
+                gconf_client_notify_add(file_saver->_priv->conf,
+                                        "/desktop/standard/save-locations",
+                                        locations_changed_notify,
+                                        file_saver, NULL, NULL);
+
+        gtk_widget_show(file_saver->_priv->location_menu);
+        
+        /* Must do _after_ filling the menu */
+        gtk_option_menu_set_menu(GTK_OPTION_MENU(file_saver->_priv->location_option),
+                                 file_saver->_priv->location_menu);
+
+        gtk_widget_show(file_saver->_priv->type_menu);
+        
+        /* Must do _after_ filling the menu */
+        gtk_option_menu_set_menu(GTK_OPTION_MENU(file_saver->_priv->type_option),
+                                 file_saver->_priv->type_menu);
+
+        gtk_widget_show_all(hbox);
+
+        /* Now hide the type stuff until we get mime types added */
+        gtk_widget_hide(file_saver->_priv->type_label);
+        gtk_widget_hide(file_saver->_priv->type_option);
+
+        gnome_dialog_append_buttons (GNOME_DIALOG (file_saver),
+                                     GNOME_STOCK_BUTTON_OK,
+                                     GNOME_STOCK_BUTTON_CANCEL,
+                                     NULL);
+}
+
+GtkWidget*
+gnome_file_saver_new (const gchar* title, const gchar* saver_id)
+{
+        GtkWidget *widget;
+
+        widget = GTK_WIDGET (gtk_type_new (gnome_file_saver_get_type ()));
+
+        gtk_window_set_title(GTK_WINDOW(widget), title);
+        
+        return widget;
+}
+
+static void
+gnome_file_saver_destroy (GtkObject* object)
+{
+        GnomeFileSaver* file_saver;
+
+	/* remember, destroy can be run multiple times! */
+
+        file_saver = GNOME_FILE_SAVER (object);
+        
+	if (file_saver->_priv->conf) {
+		if (file_saver->_priv->conf_notify != 0) {
+			gconf_client_notify_remove(file_saver->_priv->conf,
+						   file_saver->_priv->conf_notify);
+			file_saver->_priv->conf_notify = 0;
+		}
+
+		gconf_client_remove_dir(file_saver->_priv->conf,
+					"/desktop/standard/save-locations",
+                                        NULL);
+
+		g_object_unref(G_OBJECT(file_saver->_priv->conf));
+		file_saver->_priv->conf = NULL;
+	}
+        
+        (* GTK_OBJECT_CLASS(parent_class)->destroy) (object);
+}
+
+static void
+gnome_file_saver_finalize (GObject* object)
+{
+        GnomeFileSaver* file_saver;
+
+        file_saver = GNOME_FILE_SAVER (object);
+
+	g_free(file_saver->_priv);
+	file_saver->_priv = NULL;
+
+        (* G_OBJECT_CLASS(parent_class)->finalize) (object);
+}
+
+static void
+gnome_file_saver_set_arg (GtkObject* object, GtkArg* arg, guint arg_id)
+{
+        GnomeFileSaver* file_saver;
+
+        file_saver = GNOME_FILE_SAVER (object);
+
+        switch (arg_id) {
+
+        default:
+                g_assert_not_reached();
+                break;
+        }
+}
+
+static void
+gnome_file_saver_get_arg (GtkObject* object, GtkArg* arg, guint arg_id)
+{
+        GnomeFileSaver* file_saver;
+
+        file_saver = GNOME_FILE_SAVER (object);
+
+        switch (arg_id) {
+                
+        default:
+                arg->type = GTK_TYPE_INVALID;
+                break;
+        }
+}
+
+/*
+ * MIME type stuff
+ */
+
+static void
+type_chosen_cb(GtkWidget* mi, GnomeFileSaver* file_saver)
+{
+        const gchar* mime_type;
+        const gchar* icon_file;
+        gchar* freeme = NULL;
+        GdkPixbuf *pixbuf;
+        
+        mime_type = gtk_object_get_data(GTK_OBJECT(mi),
+                                        "mimetype");
+
+        g_assert(mime_type != NULL);
+
+        icon_file = gnome_mime_get_value(mime_type, "icon-filename");
+
+        if (icon_file == NULL) {
+                freeme = gnome_pixmap_file("mc/i-regular.png");
+                icon_file = freeme;
+        }
+
+        if (icon_file) {
+                printf("file %s\n", icon_file);
+                pixbuf = gdk_pixbuf_new_from_file(icon_file, NULL);
+        } else {
+                pixbuf = NULL;
+        }
+
+        if (pixbuf) {
+                printf("loaded ok\n");
+                gnome_pixmap_set_pixbuf (GNOME_PIXMAP(file_saver->_priv->type_pixmap),
+                                         pixbuf);
+                gdk_pixbuf_unref(pixbuf);
+        } else {
+                printf("no load\n");
+                gnome_pixmap_clear (GNOME_PIXMAP(file_saver->_priv->type_pixmap));
+        }
+                
+        g_free(freeme);
+}
+
+void
+gnome_file_saver_add_mime_type(GnomeFileSaver *file_saver,
+                               const gchar    *mime_type)
+{
+        GtkWidget *mi;
+        GtkWidget *pix;
+        const gchar* icon_file;
+        gchar* freeme = NULL;
+        const gchar* desc;
+        GtkWidget *label;
+
+        gtk_widget_show(file_saver->_priv->type_option);
+        gtk_widget_show(file_saver->_priv->type_label);
+        
+        icon_file = gnome_mime_get_value(mime_type, "icon-filename");
+        desc = gnome_mime_description(mime_type);
+        if (desc == NULL)
+                desc = mime_type;
+
+        if (icon_file == NULL) {
+                freeme = gnome_pixmap_file("mc/i-regular.png");
+                icon_file = freeme;
+        }
+        
+        if (icon_file) 
+                pix = gnome_pixmap_new_from_file_at_size(icon_file, 16, 16);
+        else
+                pix = NULL;
+
+        mi = gtk_pixmap_menu_item_new();
+        label = gtk_label_new(desc);
+        gtk_container_add(GTK_CONTAINER(mi), label);
+
+        if (pix)
+                gtk_pixmap_menu_item_set_pixmap(GTK_PIXMAP_MENU_ITEM(mi),
+                                                pix);
+
+        g_free(freeme);
+
+        gtk_object_set_data_full(GTK_OBJECT(mi),
+                                 "mimetype",
+                                 g_strdup(mime_type),
+                                 g_free);
+
+        gtk_signal_connect (GTK_OBJECT(mi),
+                            "activate",
+                            type_chosen_cb,
+                            file_saver);
+        
+        gtk_widget_show_all(mi);
+
+        gtk_menu_shell_append(GTK_MENU_SHELL(file_saver->_priv->type_menu),
+                              mi);        
+}
+
+void
+gnome_file_saver_add_mime_types(GnomeFileSaver *file_saver,
+                                const gchar    *mime_types[])
+{
+        const gchar** mtp;
+
+        mtp = mime_types;
+
+        while (*mtp) {
+                gnome_file_saver_add_mime_type(file_saver, *mtp);
+                ++mtp;
+        }
+}
+
+/*
+ * Location list management
+ */
+
+static void
+location_mi_set(GtkWidget* mi,
+                const gchar* human_name,
+                const gchar* dirname);
+
+static GtkWidget*
+location_mi_new(const gchar* gconf_key,
+                const gchar* human_name,
+                const gchar* dirname)
+{
+        GtkWidget *mi;
+
+        g_return_val_if_fail(human_name != NULL, NULL);
+        g_return_val_if_fail(dirname != NULL, NULL);
+        
+        mi = gtk_menu_item_new_with_label (human_name);
+
+        location_mi_set(mi, human_name, dirname);
+
+        gtk_object_set_data_full(GTK_OBJECT(mi), "gconf_key", g_strdup(gconf_key), g_free);
+
+        return mi;
+}
+
+static const gchar*
+location_mi_get_human_name(GtkWidget *mi)
+{
+        return gtk_object_get_data(GTK_OBJECT(mi), "name");
+}
+
+/*UNUSED
+static const gchar*
+location_mi_get_dirname(GtkWidget *mi)
+{
+        return gtk_object_get_data(GTK_OBJECT(mi), "dirname");
+}
+*/
+
+static const gchar*
+location_mi_get_key(GtkWidget *mi)
+{
+        return gtk_object_get_data(GTK_OBJECT(mi), "gconf_key");
+}
+
+static void
+location_mi_set(GtkWidget* mi,
+                const gchar* human_name,
+                const gchar* dirname)
+{
+        gtk_object_set_data_full(GTK_OBJECT(mi), "dirname", g_strdup(dirname), g_free);
+        gtk_object_set_data_full(GTK_OBJECT(mi), "name", g_strdup(human_name), g_free);
+}
+
+/*UNUSED
+static gint
+location_compare_human_func(gconstpointer loc1, gconstpointer loc2)
+{
+
+        return strcmp(location_mi_get_human_name((GtkWidget*)loc1),
+                      location_mi_get_human_name((GtkWidget*)loc2));
+}
+*/
+
+static gint
+location_compare_gconf_func(gconstpointer loc1, gconstpointer loc2)
+{
+
+        return strcmp(location_mi_get_key((GtkWidget*)loc1),
+                      location_mi_get_key((GtkWidget*)loc2));
+}
+
+static void
+gnome_file_saver_remove_location(GnomeFileSaver* file_saver,
+                                 const gchar* gconf_key)
+{
+        GtkWidget *mi;
+        GSList *found;
+        
+        /* This function does NOT assume the location
+           is actually in the current list */
+        
+        found = g_slist_find_custom(file_saver->_priv->locations,
+                                    (gchar*)gconf_key,
+                                    location_compare_gconf_func);
+
+        mi = found ? found->data : NULL;
+        
+        if (mi != NULL) {
+                file_saver->_priv->locations =
+			g_slist_remove(file_saver->_priv->locations, mi);
+                gtk_widget_destroy(mi);
+        }
+}
+
+static void
+gnome_file_saver_update_location(GnomeFileSaver* file_saver,
+                                 const gchar* key,
+                                 GConfValue* value)
+{
+        GConfValue *car;
+        GConfValue *cdr;
+        const gchar* human_name;
+        const gchar* dirname;
+        GtkWidget *mi;
+        GSList *found;
+        
+        if (value == NULL || value->type != GCONF_VALUE_PAIR) {
+                /* Weird, whatever. */
+                gnome_file_saver_remove_location(file_saver,
+                                                 key);
+                return;
+        }
+        
+        car = gconf_value_get_car(value);
+        cdr = gconf_value_get_cdr(value);
+
+        if (car == NULL || car->type != GCONF_VALUE_STRING ||
+            cdr == NULL || cdr->type != GCONF_VALUE_STRING) {
+                /* Tsk tsk */
+                gnome_file_saver_remove_location(file_saver,
+                                                 key);
+                return;
+        }
+        
+        human_name = gconf_value_get_string(car);
+        dirname = gconf_value_get_string(cdr);
+
+        if (human_name == NULL ||
+            dirname == NULL) {
+                /* No dice! */
+                gnome_file_saver_remove_location(file_saver,
+                                                 key);
+                return;
+        }
+
+        found = g_slist_find_custom(file_saver->_priv->locations,
+                                    (gchar*)key,
+                                    location_compare_gconf_func);
+
+        mi = found ? found->data : NULL;
+        
+        if (mi != NULL)
+                location_mi_set(mi, human_name, dirname);
+        else {
+                GSList *iter;
+                gint count;
+                
+                mi = location_mi_new(key, human_name, dirname);
+
+                /* can't use g_slist_insert_sorted because we
+                   need to sync with the menu */
+
+                count = 0;
+                iter = file_saver->_priv->locations;
+                while (iter != NULL) {
+                        GtkWidget *old_mi = iter->data;
+                        const gchar* old_human_name;
+
+                        old_human_name = location_mi_get_human_name(old_mi);
+
+                        if (strcmp(human_name, old_human_name) >=  0) {
+                                /* We're >= than this element */
+                                break;
+                        }
+
+                        ++count;
+                        iter = g_slist_next(iter);
+                }
+
+                file_saver->_priv->locations =
+			g_slist_insert(file_saver->_priv->locations,
+				       mi, count);
+
+                gtk_menu_shell_insert(GTK_MENU_SHELL(file_saver->_priv->location_menu),
+                                      mi, count);
+        }
+}
+                
+static void
+locations_changed_notify(GConfClient* client, guint cnxn_id,
+                         GConfEntry *entry, gpointer user_data)
+{
+        GnomeFileSaver *file_saver;
+        GConfValue *value;
+        const gchar *key;
+
+        value = gconf_entry_get_value (entry);
+        key = gconf_entry_get_key (entry);
+
+        file_saver = GNOME_FILE_SAVER(user_data);
+        
+        if (value != NULL)
+                gnome_file_saver_update_location(file_saver,
+                                                 key,
+                                                 value);
+        else
+                gnome_file_saver_remove_location(file_saver,
+                                                 key);
+}
diff --git a/libgnomeui/gnome-file-saver.h b/libgnomeui/gnome-file-saver.h
new file mode 100644
index 0000000..53f1b20
--- /dev/null
+++ b/libgnomeui/gnome-file-saver.h
@@ -0,0 +1,75 @@
+/*  -*- Mode: C; c-set-style: linux; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* GNOME GUI Library - gnome-file-saver.h
+ * Copyright (C) 2000  Red Hat Inc.
+ * All rights reserved.
+ *
+ * Author: Havoc Pennington <hp redhat com>
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#ifndef GNOME_FILE_SAVER_H
+#define GNOME_FILE_SAVER_H
+
+
+#include <libgnomeui/gnome-dialog.h>
+#include <libgnomeui/gnome-gconf.h>
+
+G_BEGIN_DECLS
+
+#define GNOME_TYPE_FILE_SAVER            (gnome_file_saver_get_type())
+#define GNOME_FILE_SAVER(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_FILE_SAVER, GnomeFileSaver))
+#define GNOME_FILE_SAVER_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_FILE_SAVER, GnomeFileSaverClass))
+#define GNOME_IS_FILE_SAVER(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_FILE_SAVER))
+#define GNOME_IS_FILE_SAVER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_FILE_SAVER))
+#define GNOME_FILE_SAVER_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_FILE_SAVER, GnomeFileSaverClass))
+
+typedef struct _GnomeFileSaver        GnomeFileSaver;
+typedef struct _GnomeFileSaverPrivate GnomeFileSaverPrivate;
+typedef struct _GnomeFileSaverClass   GnomeFileSaverClass;
+
+struct _GnomeFileSaver {
+        GnomeDialog parent_instance;
+
+	/*< private >*/
+	GnomeFileSaverPrivate *_priv;
+};
+
+struct _GnomeFileSaverClass {
+        GnomeDialogClass parent_class;
+        
+        void (* finished) (GnomeFileSaver *saver,
+                           const gchar    *filename,
+                           const gchar    *mime_type);
+};
+
+GtkType         gnome_file_saver_get_type     (void) G_GNUC_CONST;
+GtkWidget*      gnome_file_saver_new          (const gchar    *title,
+                                               const gchar    *saver_id);
+
+void            gnome_file_saver_add_mime_type(GnomeFileSaver *file_saver,
+                                               const gchar    *mime_type);
+
+/* convenience wrapper; not language-binding friendly but also not
+   required to be wrapped */
+void            gnome_file_saver_add_mime_types(GnomeFileSaver *file_saver,
+                                                const gchar    *mime_types[]);
+
+G_END_DECLS
+
+#endif
diff --git a/libgnomeui/gnome-file-selector-dialog.h b/libgnomeui/gnome-file-selector-dialog.h
new file mode 100644
index 0000000..986778c
--- /dev/null
+++ b/libgnomeui/gnome-file-selector-dialog.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2000 SuSE GmbH
+ * Author: Martin Baulig <baulig suse de>
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+/* GnomeFileSelectorDialog - the new file selector dialog.
+ *
+ * Author: Martin Baulig <baulig suse de>
+ */
+
+#ifndef GNOME_FILE_SELECTOR_DIALOG_H
+#define GNOME_FILE_SELECTOR_DIALOG_H
+
+
+#include <gtk/gtkwindow.h>
+
+
+
+G_BEGIN_DECLS
+
+
+#define GNOME_TYPE_FILE_SELECTOR_DIALOG            (gnome_file_selector_dialog_get_type ())
+#define GNOME_FILE_SELECTOR_DIALOG(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_FILE_SELECTOR_DIALOG, GnomeFileSelectorDialog))
+#define GNOME_FILE_SELECTOR_DIALOG_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_FILE_SELECTOR_DIALOG, GnomeFileSelectorDialogClass))
+#define GNOME_IS_FILE_SELECTOR_DIALOG(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_FILE_SELECTOR_DIALOG))
+#define GNOME_IS_FILE_SELECTOR_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_FILE_SELECTOR_DIALOG))
+#define GNOME_FILE_SELECTOR_DIALOG_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_FILE_SELECTOR_DIALOG, GnomeFileSelectorDialogClass))
+
+
+typedef struct _GnomeFileSelectorDialog         GnomeFileSelectorDialog;
+typedef struct _GnomeFileSelectorDialogPrivate  GnomeFileSelectorDialogPrivate;
+typedef struct _GnomeFileSelectorDialogClass    GnomeFileSelectorDialogClass;
+
+struct _GnomeFileSelectorDialog {
+	GtkWindow window;
+	
+	/*< private >*/
+	GnomeFileSelectorDialogPrivate *_priv;
+};
+
+struct _GnomeFileSelectorDialogClass {
+	GtkWindowClass parent_class;
+
+	void (*update) (GnomeFileSelectorDialog *fsdialog);
+};
+
+guint
+gnome_file_selector_dialog_get_type     (void) G_GNUC_CONST;
+
+GtkWidget *
+gnome_file_selector_dialog_new          (const gchar *dialog_title);
+
+void
+gnome_file_selector_dialog_construct    (GnomeFileSelectorDialog *fsdialog,
+					 const gchar *dialog_title);
+
+/* Update the file selector dialog.*/
+void
+gnome_file_selector_dialog_update       (GnomeFileSelectorDialog *fsdialog);
+
+/* Get/Set current directory of the file selector dialog.*/
+void
+gnome_file_selector_dialog_set_dir      (GnomeFileSelectorDialog *fsdialog,
+					 const gchar *directory);
+
+const gchar *
+gnome_file_selector_dialog_get_dir      (GnomeFileSelectorDialog *fsdialog);
+
+/* Get/Set "Home Directory" of the file selector dialog.*/
+void
+gnome_file_selector_dialog_set_home_dir (GnomeFileSelectorDialog *fsdialog,
+					 const gchar *home_directory);
+
+const gchar *
+gnome_file_selector_dialog_get_home_dir (GnomeFileSelectorDialog *fsdialog);
+
+
+G_END_DECLS
+
+#endif
+
diff --git a/libgnomeui/gnome-file-selector.c b/libgnomeui/gnome-file-selector.c
new file mode 100644
index 0000000..153f0e9
--- /dev/null
+++ b/libgnomeui/gnome-file-selector.c
@@ -0,0 +1,1022 @@
+/* -*- Mode: C; c-set-style: gnu indent-tabs-mode: t; c-basic-offset: 4; tab-width: 8 -*- */
+/*
+ * Copyright (C) 2000 SuSE GmbH
+ * Author: Martin Baulig <baulig suse de>
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+/* GnomeFileSelector widget - a file selector widget.
+ *
+ * Author: Martin Baulig <baulig suse de>
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <gtk/gtkfilesel.h>
+#include <gtk/gtklist.h>
+#include <gtk/gtklistitem.h>
+#include <gtk/gtksignal.h>
+#include "gnome-macros.h"
+#include <libgnome/gnome-i18n.h>
+#include "gnome-file-selector.h"
+#include "gnome-selectorP.h"
+#include "gnome-entry.h"
+
+#include <libgnomevfs/gnome-vfs.h>
+
+#undef DEBUG_ASYNC_STUFF
+
+typedef struct _GnomeFileSelectorAsyncData      GnomeFileSelectorAsyncData;
+typedef struct _GnomeFileSelectorSubAsyncData   GnomeFileSelectorSubAsyncData;
+
+struct _GnomeFileSelectorAsyncData {
+    GnomeSelectorAsyncHandle *async_handle;
+
+    GnomeSelectorAsyncType type;
+    GnomeFileSelector *fselector;
+
+    GSList *async_ops;
+    gboolean completed;
+
+    GnomeVFSAsyncHandle *vfs_handle;
+    GnomeVFSURI *uri;
+    GSList *uri_list;
+    gint position;
+    guint list_id;
+};
+
+struct _GnomeFileSelectorSubAsyncData {
+    GnomeSelectorAsyncHandle *async_handle;
+
+    GnomeFileSelectorAsyncData *async_data;
+};
+
+struct _GnomeFileSelectorPrivate {
+    GnomeVFSDirectoryFilter *filter;
+    GnomeVFSFileInfoOptions file_info_options;
+
+    GtkWidget *browse_dialog;
+};
+
+
+static void gnome_file_selector_class_init  (GnomeFileSelectorClass *class);
+static void gnome_file_selector_init        (GnomeFileSelector      *fselector);
+static void gnome_file_selector_destroy     (GtkObject              *object);
+static void gnome_file_selector_finalize    (GObject                *object);
+
+static void      add_uri_handler                (GnomeSelector            *selector,
+                                                 const gchar              *uri,
+                                                 gint                      position,
+						 guint                     list_id,
+						 GnomeSelectorAsyncHandle *async_handle);
+
+static void      add_uri_list_handler           (GnomeSelector            *selector,
+						 GSList                   *list,
+						 gint                      position,
+						 guint                     list_id,
+						 GnomeSelectorAsyncHandle *async_handle);
+
+static void      add_directory_handler          (GnomeSelector            *selector,
+                                                 const gchar              *uri,
+                                                 gint                      position,
+						 guint                     list_id,
+						 GnomeSelectorAsyncHandle *async_handle);
+static void      check_filename_handler         (GnomeSelector            *selector,
+                                                 const gchar              *filename,
+						 GnomeSelectorAsyncHandle *async_handle);
+static void      check_directory_handler        (GnomeSelector            *selector,
+                                                 const gchar              *directory,
+						 GnomeSelectorAsyncHandle *async_handle);
+
+static void      activate_entry_handler         (GnomeSelector   *selector);
+
+static void      do_construct_handler           (GnomeSelector   *selector);
+
+
+static GObject*
+gnome_file_selector_constructor (GType                  type,
+				 guint                  n_construct_properties,
+				 GObjectConstructParam *construct_properties);
+
+
+/**
+ * gnome_file_selector_get_type
+ *
+ * Returns the type assigned to the GnomeFileSelector widget.
+ **/
+/* The following defines the get_type */
+GNOME_CLASS_BOILERPLATE (GnomeFileSelector, gnome_file_selector,
+			 GnomeEntry, gnome_entry)
+
+static void
+gnome_file_selector_class_init (GnomeFileSelectorClass *class)
+{
+    GnomeSelectorClass *selector_class;
+    GtkObjectClass *object_class;
+    GObjectClass *gobject_class;
+
+    selector_class = (GnomeSelectorClass *) class;
+    object_class = (GtkObjectClass *) class;
+    gobject_class = (GObjectClass *) class;
+
+    object_class->destroy = gnome_file_selector_destroy;
+    gobject_class->finalize = gnome_file_selector_finalize;
+
+    gobject_class->constructor = gnome_file_selector_constructor;
+
+    selector_class->add_uri = add_uri_handler;
+
+    selector_class->add_uri_list = add_uri_list_handler; 
+
+    selector_class->add_directory = add_directory_handler;
+
+    selector_class->activate_entry = activate_entry_handler;
+
+    selector_class->check_filename = check_filename_handler;
+    selector_class->check_directory = check_directory_handler;
+
+    selector_class->do_construct = do_construct_handler;
+}
+
+static void
+free_the_async_data (gpointer data)
+{
+    GnomeFileSelectorAsyncData *async_data = data;
+    GnomeFileSelector *fselector;
+
+    g_return_if_fail (async_data != NULL);
+    g_assert (GNOME_IS_FILE_SELECTOR (async_data->fselector));
+
+    fselector = async_data->fselector;
+
+    /* free the async data. */
+    gtk_object_unref (GTK_OBJECT (async_data->fselector));
+    _gnome_selector_deep_free_slist (async_data->uri_list);
+    if (async_data->uri)
+	gnome_vfs_uri_unref (async_data->uri);
+    g_free (async_data);
+}
+
+static void
+add_uri_async_done_cb (GnomeFileSelectorAsyncData *async_data)
+{
+    GnomeSelectorAsyncHandle *async_handle;
+    gchar *path;
+
+    g_return_if_fail (async_data != NULL);
+
+    /* When we finish our async reading, we set async_data->completed -
+     * but we need to wait until all our async operations are completed as
+     * well.
+     */
+
+#ifdef DEBUG_ASYNC_STUFF
+    g_message (G_STRLOC ": %p - %d - %p", async_data, async_data->completed,
+	       async_data->async_ops);
+#endif
+
+    if (!async_data->completed || async_data->async_ops != NULL)
+	return;
+
+    async_handle = async_data->async_handle;
+
+    path = gnome_vfs_uri_to_string (async_data->uri,
+				    GNOME_VFS_URI_HIDE_NONE);
+    GNOME_CALL_PARENT_HANDLER (GNOME_SELECTOR_CLASS, add_uri,
+			       (GNOME_SELECTOR (async_data->fselector), path,
+				async_data->position, async_data->list_id,
+				async_handle));
+
+#ifdef DEBUG_ASYNC_STUFF
+    g_message (G_STRLOC ": %p - async reading completed (%s).",
+	       async_data->fselector, path);
+#endif
+
+    g_free (path);
+
+    _gnome_selector_async_handle_remove (async_handle, async_data);
+}
+
+static void
+add_uri_async_add_cb (GnomeSelector *selector,
+		      GnomeSelectorAsyncHandle *async_handle,
+		      GnomeSelectorAsyncType async_type,
+		      const char *uri, GError *error,
+		      gboolean success, gpointer user_data)
+{
+    GnomeFileSelectorSubAsyncData *sub_async_data = user_data;
+    GnomeFileSelectorAsyncData *async_data;
+
+    g_return_if_fail (sub_async_data != NULL);
+    g_assert (sub_async_data->async_data != NULL);
+    async_data = sub_async_data->async_data;
+
+    /* This operation is completed, remove it from the list and call
+     * add_uri_async_done_cb() - this function will check whether
+     * this was the last one and the uri checking is done as well.
+     */
+
+    async_data->async_ops = g_slist_remove (async_data->async_ops,
+					    sub_async_data);
+
+#ifdef DEBUG_ASYNC_STUFF
+    g_message (G_STRLOC ": %p - %p - `%s'", async_data->async_ops,
+	       sub_async_data, uri);
+#endif
+
+    add_uri_async_done_cb (async_data);
+}
+
+
+static void
+add_uri_async_cb (GnomeVFSAsyncHandle *handle, GList *results,
+		  gpointer callback_data)
+{
+    GnomeFileSelectorAsyncData *async_data;
+    GnomeFileSelector *fselector;
+    GList *list;
+
+    g_return_if_fail (callback_data != NULL);
+
+    async_data = callback_data;
+    g_assert (async_data->vfs_handle == handle);
+    g_assert (GNOME_IS_FILE_SELECTOR (async_data->fselector));
+    g_assert (async_data->type == GNOME_SELECTOR_ASYNC_TYPE_ADD_URI);
+
+    fselector = GNOME_FILE_SELECTOR (async_data->fselector);
+
+    for (list = results; list; list = list->next) {
+	GnomeVFSGetFileInfoResult *file = list->data;
+	gchar *uri;
+
+	/* better assert this than risking a crash. */
+	g_assert (file != NULL);
+
+	uri = gnome_vfs_uri_to_string (file->uri, GNOME_VFS_URI_HIDE_NONE);
+
+	if (file->result != GNOME_VFS_OK) {
+	    g_message (G_STRLOC ": `%s': %s", uri,
+		       gnome_vfs_result_to_string (file->result));
+	    g_free (uri);
+	    continue;
+	}
+
+	if (file->file_info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) {
+	    GnomeFileSelectorSubAsyncData *sub_async_data;
+
+	    sub_async_data = g_new0 (GnomeFileSelectorSubAsyncData, 1);
+	    sub_async_data->async_data = async_data;
+
+	    async_data->async_ops = g_slist_prepend
+		(async_data->async_ops, sub_async_data);
+
+	    gnome_selector_add_directory (GNOME_SELECTOR (fselector),
+					  &sub_async_data->async_handle, uri,
+					  async_data->position,
+					  async_data->list_id,
+					  add_uri_async_add_cb,
+					  sub_async_data);
+
+	    g_free (uri);
+	    continue;
+	}
+
+	if (fselector->_priv->filter &&
+	    !gnome_vfs_directory_filter_apply (fselector->_priv->filter,
+					       file->file_info)) {
+
+	    g_message (G_STRLOC ": dropped by directory filter");
+
+	    g_free (uri);
+	    continue;
+	}
+
+	if (file->file_info->type == GNOME_VFS_FILE_TYPE_REGULAR) {
+	    GnomeFileSelectorSubAsyncData *sub_async_data;
+
+	    sub_async_data = g_new0 (GnomeFileSelectorSubAsyncData, 1);
+	    sub_async_data->async_data = async_data;
+
+	    async_data->async_ops = g_slist_prepend
+		(async_data->async_ops, sub_async_data);
+
+	    gnome_selector_add_file (GNOME_SELECTOR (fselector),
+				     &sub_async_data->async_handle, uri,
+				     async_data->position, async_data->list_id,
+				     add_uri_async_add_cb,
+				     sub_async_data);
+
+	    g_free (uri);
+	    continue;
+	}
+
+	g_free (uri);
+    }
+
+    /* Completed, but we may have async operations running. We set
+     * async_data->completed here to inform add_uri_async_done_cb()
+     * that we're done with our async operation.
+     */
+    async_data->completed = TRUE;
+    add_uri_async_done_cb (async_data);
+}
+
+void
+add_uri_handler (GnomeSelector *selector, const gchar *uri, gint position,
+		 guint list_id, GnomeSelectorAsyncHandle *async_handle)
+{
+    GnomeFileSelector *fselector;
+    GnomeFileSelectorAsyncData *async_data;
+    GList fake_list;
+
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_FILE_SELECTOR (selector));
+    g_return_if_fail (position >= -1);
+    g_return_if_fail (uri != NULL);
+    g_return_if_fail (async_handle != NULL);
+
+    fselector = GNOME_FILE_SELECTOR (selector);
+
+    async_data = g_new0 (GnomeFileSelectorAsyncData, 1);
+    async_data->async_handle = async_handle;
+    async_data->type = GNOME_SELECTOR_ASYNC_TYPE_ADD_URI;
+    async_data->fselector = fselector;
+    async_data->uri = gnome_vfs_uri_new (uri);
+    async_data->position = position;
+    async_data->list_id = list_id;
+
+    gnome_vfs_uri_ref (async_data->uri);
+    gtk_object_ref (GTK_OBJECT (async_data->fselector));
+
+    fake_list.data = async_data->uri;
+    fake_list.prev = NULL;
+    fake_list.next = NULL;
+
+    _gnome_selector_async_handle_add (async_handle, async_data,
+				      free_the_async_data);
+
+    gnome_vfs_async_get_file_info (&async_data->vfs_handle, &fake_list,
+				   fselector->_priv->file_info_options,
+				   add_uri_async_cb, async_data);
+
+    gnome_vfs_uri_unref (fake_list.data);
+}
+
+static void
+add_uri_list_async_done_cb (GnomeFileSelectorAsyncData *async_data)
+{
+    GnomeSelectorAsyncHandle *async_handle;
+
+    g_return_if_fail (async_data != NULL);
+
+    /* When we finish our directory reading, we set async_data->completed -
+     * but we need to wait until all our async operations are completed as
+     * well.
+     */
+
+    if (!async_data->completed || async_data->async_ops != NULL)
+	return;
+
+    async_handle = async_data->async_handle;
+
+    GNOME_CALL_PARENT_HANDLER (GNOME_SELECTOR_CLASS, add_uri_list,
+			       (GNOME_SELECTOR (async_data->fselector),
+				async_data->uri_list, async_data->position,
+				async_data->list_id, async_handle));
+
+    _gnome_selector_async_handle_remove (async_handle, async_data);
+}
+
+static void
+add_uri_list_async_cb (GnomeSelector *selector,
+		       GnomeSelectorAsyncHandle *async_handle,
+		       GnomeSelectorAsyncType async_type,
+		       const char *uri, GError *error,
+		       gboolean success, gpointer user_data)
+{
+    GnomeFileSelectorSubAsyncData *sub_async_data = user_data;
+    GnomeFileSelectorAsyncData *async_data;
+
+    g_return_if_fail (sub_async_data != NULL);
+    g_assert (sub_async_data->async_data != NULL);
+    async_data = sub_async_data->async_data;
+
+    /* This operation is completed, remove it from the list and call
+     * add_uri_list_async_done_cb() - this function will check whether
+     * this was the last one and the directory reading is done as well.
+     */
+
+    async_data->async_ops = g_slist_remove (async_data->async_ops,
+					    sub_async_data);
+
+    add_uri_list_async_done_cb (async_data);
+}
+
+static void
+add_uri_list_handler (GnomeSelector *selector, GSList *list,
+		      gint position, guint list_id,
+		      GnomeSelectorAsyncHandle *async_handle)
+{
+    GnomeFileSelectorAsyncData *async_data;
+    GnomeFileSelector *fselector;
+    GSList *c;
+
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_FILE_SELECTOR (selector));
+    g_return_if_fail (async_handle != NULL);
+
+    fselector = GNOME_FILE_SELECTOR (selector);
+
+    async_data = g_new0 (GnomeFileSelectorAsyncData, 1);
+    async_data->async_handle = async_handle;
+    async_data->type = GNOME_SELECTOR_ASYNC_TYPE_ADD_URI_LIST;
+    async_data->fselector = fselector;
+    async_data->position = position;
+    async_data->uri_list = _gnome_selector_deep_copy_slist (list);
+    async_data->list_id = list_id;
+
+    gtk_object_ref (GTK_OBJECT (async_data->fselector));
+
+    _gnome_selector_async_handle_add (async_handle, async_data,
+				      free_the_async_data);
+
+    for (c = list; c; c = c->next) {
+	GnomeFileSelectorSubAsyncData *sub_async_data;
+
+	sub_async_data = g_new0 (GnomeFileSelectorSubAsyncData, 1);
+	sub_async_data->async_data = async_data;
+
+	async_data->async_ops = g_slist_prepend
+	    (async_data->async_ops, sub_async_data);
+
+	gnome_selector_add_uri (GNOME_SELECTOR (fselector),
+				&sub_async_data->async_handle,
+				c->data, position, list_id,
+				add_uri_list_async_cb,
+				sub_async_data);
+    }
+
+    async_data->completed = TRUE;
+    add_uri_list_async_done_cb (async_data);
+}
+
+static void
+add_directory_async_done_cb (GnomeFileSelectorAsyncData *async_data)
+{
+    GnomeSelectorAsyncHandle *async_handle;
+    gchar *path;
+
+    g_return_if_fail (async_data != NULL);
+
+    /* When we finish our directory reading, we set async_data->completed -
+     * but we need to wait until all our async operations are completed as
+     * well.
+     */
+
+    if (!async_data->completed || async_data->async_ops != NULL)
+	return;
+
+    async_handle = async_data->async_handle;
+
+    path = gnome_vfs_uri_to_string (async_data->uri,
+				    GNOME_VFS_URI_HIDE_NONE);
+    GNOME_CALL_PARENT_HANDLER (GNOME_SELECTOR_CLASS, add_directory,
+			       (GNOME_SELECTOR (async_data->fselector), path,
+				async_data->position, async_data->list_id,
+				async_handle));
+
+    g_free (path);
+
+    _gnome_selector_async_handle_remove (async_handle, async_data);
+}
+
+static void
+add_directory_async_file_cb (GnomeSelector *selector,
+			     GnomeSelectorAsyncHandle *async_handle,
+			     GnomeSelectorAsyncType async_type,
+			     const char *uri, GError *error,
+			     gboolean success, gpointer user_data)
+{
+    GnomeFileSelectorSubAsyncData *sub_async_data = user_data;
+    GnomeFileSelectorAsyncData *async_data;
+
+    g_return_if_fail (sub_async_data != NULL);
+    g_assert (sub_async_data->async_data != NULL);
+    async_data = sub_async_data->async_data;
+
+    /* This operation is completed, remove it from the list and call
+     * add_directory_async_done_cb() - this function will check whether
+     * this was the last one and the directory reading is done as well.
+     */
+
+    async_data->async_ops = g_slist_remove (async_data->async_ops,
+					    sub_async_data);
+
+    add_directory_async_done_cb (async_data);
+}
+
+static void
+add_directory_async_cb (GnomeVFSAsyncHandle *handle, GnomeVFSResult result,
+			GList *list, guint entries_read, gpointer callback_data)
+{
+    GnomeFileSelectorAsyncData *async_data;
+    GnomeFileSelector *fselector;
+
+    g_return_if_fail (callback_data != NULL);
+
+    async_data = callback_data;
+    g_assert (async_data->vfs_handle == handle);
+    g_assert (GNOME_IS_FILE_SELECTOR (async_data->fselector));
+    g_assert (async_data->type == GNOME_SELECTOR_ASYNC_TYPE_ADD_DIRECTORY);
+
+    fselector = GNOME_FILE_SELECTOR (async_data->fselector);
+
+    if (list != NULL) {
+	GList *c;
+
+	for (c = list; c; c = c->next) {
+	    GnomeVFSFileInfo *info = c->data;
+	    GnomeFileSelectorSubAsyncData *sub_async_data;
+	    GnomeVFSURI *uri;
+	    gchar *text;
+
+	    if (fselector->_priv->filter &&
+		!gnome_vfs_directory_filter_apply (fselector->_priv->filter,
+						   info)) {
+		continue;
+	    }
+
+	    uri = gnome_vfs_uri_append_file_name (async_data->uri, info->name);
+	    text = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE);
+
+	    /* We keep a list of currently running async operations in
+	     * async_data->async_ops. This is that add_directory_async_done_cb()
+	     * knows whether we're really done or whether we still need to wait.
+	     */
+
+	    sub_async_data = g_new0 (GnomeFileSelectorSubAsyncData, 1);
+	    sub_async_data->async_data = async_data;
+
+	    async_data->async_ops = g_slist_prepend
+		(async_data->async_ops, sub_async_data);
+
+	    gnome_selector_add_file (GNOME_SELECTOR (fselector),
+				     &sub_async_data->async_handle,
+				     text, async_data->position,
+				     async_data->list_id,
+				     add_directory_async_file_cb,
+				     sub_async_data);
+
+	    gnome_vfs_uri_unref (uri);
+	    g_free (text);
+	}
+    }
+
+    if (result == GNOME_VFS_ERROR_EOF) {
+	/* Completed, but we may have async operations running. We set
+	 * async_data->completed here to inform add_directory_async_done_cb()
+	 * that we're done with our directory reading.
+	 */
+	async_data->completed = TRUE;
+	add_directory_async_done_cb (async_data);
+    }
+}
+
+static void
+add_directory_handler (GnomeSelector *selector, const gchar *uri,
+		       gint position, guint list_id,
+		       GnomeSelectorAsyncHandle *async_handle)
+{
+    GnomeFileSelector *fselector;
+    GnomeFileSelectorAsyncData *async_data;
+    GnomeVFSURI *vfs_uri;
+
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_FILE_SELECTOR (selector));
+    g_return_if_fail (position >= -1);
+    g_return_if_fail (uri != NULL);
+    g_return_if_fail (async_handle != NULL);
+
+    fselector = GNOME_FILE_SELECTOR (selector);
+
+#ifdef DEBUG_ASYNC_STUFF
+    g_message (G_STRLOC ": %p - starting async reading (%s).",
+	       selector, uri);
+#endif
+
+    vfs_uri = gnome_vfs_uri_new (uri);
+
+    async_data = g_new0 (GnomeFileSelectorAsyncData, 1);
+    async_data->type = GNOME_SELECTOR_ASYNC_TYPE_ADD_DIRECTORY;
+    async_data->fselector = fselector;
+    async_data->uri = vfs_uri;
+    async_data->position = position;
+    async_data->list_id = list_id;
+    async_data->async_handle = async_handle;
+
+    gnome_vfs_uri_ref (async_data->uri);
+    gtk_object_ref (GTK_OBJECT (async_data->fselector));
+
+    _gnome_selector_async_handle_add (async_handle, async_data,
+				      free_the_async_data);
+
+    gnome_vfs_async_load_directory_uri (&async_data->vfs_handle, vfs_uri,
+					fselector->_priv->file_info_options,
+					GNOME_VFS_DIRECTORY_FILTER_NONE,
+					GNOME_VFS_DIRECTORY_FILTER_NODIRS,
+					NULL, 1, add_directory_async_cb,
+					async_data);
+
+    gnome_vfs_uri_unref (vfs_uri);
+}
+
+void
+gnome_file_selector_set_filter (GnomeFileSelector *fselector,
+				GnomeVFSDirectoryFilter *filter)
+{
+    GnomeVFSDirectoryFilterNeeds needs;
+
+    g_return_if_fail (fselector != NULL);
+    g_return_if_fail (GNOME_IS_FILE_SELECTOR (fselector));
+    g_return_if_fail (filter != NULL);
+
+    if (fselector->_priv->filter)
+	gnome_vfs_directory_filter_destroy (fselector->_priv->filter);
+
+    fselector->_priv->filter = filter;
+    fselector->_priv->file_info_options = GNOME_VFS_FILE_INFO_DEFAULT;
+
+    needs = gnome_vfs_directory_filter_get_needs (filter);
+    if (needs & GNOME_VFS_DIRECTORY_FILTER_NEEDS_MIMETYPE)
+	fselector->_priv->file_info_options |=
+	    GNOME_VFS_FILE_INFO_GET_MIME_TYPE |
+	    GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE;
+}
+
+void
+gnome_file_selector_clear_filter (GnomeFileSelector *fselector)
+{
+    g_return_if_fail (fselector != NULL);
+    g_return_if_fail (GNOME_IS_FILE_SELECTOR (fselector));
+
+    if (fselector->_priv->filter)
+	gnome_vfs_directory_filter_destroy (fselector->_priv->filter);
+
+    fselector->_priv->filter = NULL;
+    fselector->_priv->file_info_options = GNOME_VFS_FILE_INFO_DEFAULT;
+}
+
+static void
+activate_entry_handler (GnomeSelector *selector)
+{
+    GnomeFileSelector *fselector;
+    gchar *text;
+
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_FILE_SELECTOR (selector));
+
+    fselector = GNOME_FILE_SELECTOR (selector);
+
+    GNOME_CALL_PARENT_HANDLER (GNOME_SELECTOR_CLASS, activate_entry,
+			       (selector));
+
+    text = gnome_selector_get_entry_text (selector);
+    gnome_selector_add_uri (selector, NULL, text, 0, FALSE, NULL, NULL);
+    g_free (text);
+}
+
+static void
+gnome_file_selector_init (GnomeFileSelector *fselector)
+{
+    fselector->_priv = g_new0 (GnomeFileSelectorPrivate, 1);
+}
+
+static void
+browse_dialog_cancel (GtkWidget *widget, gpointer data)
+{
+    GnomeFileSelector *fselector;
+    GtkFileSelection *fs;
+
+    g_assert (GNOME_IS_FILE_SELECTOR (data));
+
+    fselector = GNOME_FILE_SELECTOR (data);
+    fs = GTK_FILE_SELECTION (fselector->_priv->browse_dialog);
+
+    if (GTK_WIDGET (fs)->window)
+	gdk_window_lower (GTK_WIDGET (fs)->window);
+    gtk_widget_hide (GTK_WIDGET (fs));
+}
+
+static void
+browse_dialog_ok (GtkWidget *widget, gpointer data)
+{
+    GnomeFileSelector *fselector;
+    GtkFileSelection *fs;
+    const gchar *filename;
+
+    g_assert (GNOME_IS_FILE_SELECTOR (data));
+
+    fselector = GNOME_FILE_SELECTOR (data);
+
+    fs = GTK_FILE_SELECTION (fselector->_priv->browse_dialog);
+    filename = gtk_file_selection_get_filename (fs);
+
+    gnome_selector_set_uri (GNOME_SELECTOR (fselector), NULL, filename,
+			    NULL, NULL);
+
+    if (GTK_WIDGET (fs)->window)
+	gdk_window_lower (GTK_WIDGET (fs)->window);
+    gtk_widget_hide (GTK_WIDGET (fs));
+}
+
+static void
+check_uri_async_cb (GnomeVFSAsyncHandle *handle, GList *results, gpointer callback_data)
+{
+    GnomeFileSelectorAsyncData *async_data;
+    GnomeFileSelector *fselector;
+    GList *list;
+
+    g_return_if_fail (callback_data != NULL);
+
+    async_data = callback_data;
+    g_assert (async_data->vfs_handle == handle);
+    g_assert (GNOME_IS_FILE_SELECTOR (async_data->fselector));
+    g_assert ((async_data->type == GNOME_SELECTOR_ASYNC_TYPE_CHECK_FILENAME) ||
+	      (async_data->type == GNOME_SELECTOR_ASYNC_TYPE_CHECK_DIRECTORY));
+
+    fselector = GNOME_FILE_SELECTOR (async_data->fselector);
+
+    g_assert ((results == NULL) || (results->next == NULL));
+
+    for (list = results; list; list = list->next) {
+	GnomeVFSGetFileInfoResult *file = list->data;
+	GnomeSelectorAsyncHandle *async_handle = async_data->async_handle;
+
+	/* better assert this than risking a crash. */
+	g_assert (file != NULL);
+
+	_gnome_selector_async_handle_remove (async_handle, async_data);
+
+	if (file->result != GNOME_VFS_OK) {
+	    _gnome_selector_async_handle_completed (async_handle, FALSE);
+	    return;
+	}
+
+	if ((file->file_info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) &&
+	    (async_data->type != GNOME_SELECTOR_ASYNC_TYPE_CHECK_DIRECTORY)) {
+	    _gnome_selector_async_handle_completed (async_handle, FALSE);
+	    return;
+	}
+
+	if (fselector->_priv->filter &&
+	    !gnome_vfs_directory_filter_apply (fselector->_priv->filter,
+					       file->file_info)) {
+	    _gnome_selector_async_handle_completed (async_handle, FALSE);
+	    return;
+	}
+
+	_gnome_selector_async_handle_completed (async_handle, TRUE);
+	return;
+    }
+}
+
+static void
+check_uri_handler (GnomeSelector *selector, const gchar *uri,
+		   GnomeSelectorAsyncType async_type,
+		   GnomeSelectorAsyncHandle *async_handle)
+{
+    GnomeFileSelectorAsyncData *async_data;
+    GnomeFileSelector *fselector;
+    GList fake_list;
+
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_FILE_SELECTOR (selector));
+    g_return_if_fail (uri != NULL);
+    g_return_if_fail (async_handle != NULL);
+
+    fselector = GNOME_FILE_SELECTOR (selector);
+
+    async_data = g_new0 (GnomeFileSelectorAsyncData, 1);
+    async_data->async_handle = async_handle;
+    async_data->type = GNOME_SELECTOR_ASYNC_TYPE_CHECK_FILENAME;
+    async_data->fselector = fselector;
+    async_data->uri = gnome_vfs_uri_new (uri);
+
+    gnome_vfs_uri_ref (async_data->uri);
+    gtk_object_ref (GTK_OBJECT (async_data->fselector));
+
+    fake_list.data = async_data->uri;
+    fake_list.prev = NULL;
+    fake_list.next = NULL;
+
+    _gnome_selector_async_handle_add (async_handle, async_data,
+				      free_the_async_data);
+
+    gnome_vfs_async_get_file_info (&async_data->vfs_handle, &fake_list,
+				   fselector->_priv->file_info_options,
+				   check_uri_async_cb, async_data);
+
+    gnome_vfs_uri_unref (fake_list.data);
+}
+
+static void
+check_filename_handler (GnomeSelector *selector, const gchar *filename,
+			GnomeSelectorAsyncHandle *async_handle)
+{
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_FILE_SELECTOR (selector));
+    g_return_if_fail (filename != NULL);
+    g_return_if_fail (async_handle != NULL);
+
+    check_uri_handler (selector, filename, GNOME_SELECTOR_ASYNC_TYPE_CHECK_FILENAME, async_handle);
+}
+
+static void
+check_directory_handler (GnomeSelector *selector, const gchar *directory,
+			 GnomeSelectorAsyncHandle *async_handle)
+{
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_FILE_SELECTOR (selector));
+    g_return_if_fail (directory != NULL);
+    g_return_if_fail (async_handle != NULL);
+
+    check_uri_handler (selector, directory, GNOME_SELECTOR_ASYNC_TYPE_CHECK_DIRECTORY, async_handle);
+}
+
+static gboolean
+get_value_boolean (GnomeFileSelector *fselector, const gchar *prop_name)
+{
+    GValue value = { 0, };
+    gboolean retval;
+
+    g_value_init (&value, G_TYPE_BOOLEAN);
+    g_object_get_property (G_OBJECT (fselector), prop_name, &value);
+    retval = g_value_get_boolean (&value);
+    g_value_unset (&value);
+
+    return retval;
+}
+
+static gboolean
+has_value_widget (GnomeFileSelector *fselector, const gchar *prop_name)
+{
+	GValue value = { 0, };
+	gboolean retval;
+
+	g_value_init (&value, GTK_TYPE_WIDGET);
+	g_object_get_property (G_OBJECT (fselector), prop_name, &value);
+	retval = g_value_get_object (&value) != NULL;
+	g_value_unset (&value);
+
+	return retval;
+}
+
+static void
+do_construct_handler (GnomeSelector *selector)
+{
+    GnomeFileSelector *fselector;
+
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_FILE_SELECTOR (selector));
+
+    fselector = GNOME_FILE_SELECTOR (selector);
+
+    if (get_value_boolean (fselector, "want_default_behaviour")) {
+	g_object_set (G_OBJECT (fselector),
+		      "want_default_behaviour", FALSE,
+		      "use_default_entry_widget", TRUE,
+		      "use_default_selector_widget", TRUE,
+		      "use_default_browse_dialog", TRUE,
+		      "want_browse_button", TRUE,
+		      "want_clear_button", FALSE,
+		      "want_default_button", FALSE,
+		      NULL);
+    }
+
+    /* Create the default browser dialog if requested. */
+    if (get_value_boolean (fselector, "use_default_browse_dialog") &&
+	!has_value_widget (fselector, "browse_dialog")) {
+	GtkWidget *filesel_widget;
+	GtkFileSelection *filesel;
+	GValue value = { 0, };
+
+	g_value_init (&value, G_TYPE_STRING);
+	g_object_get_property (G_OBJECT (fselector), "dialog_title", &value);
+
+	filesel_widget = gtk_file_selection_new (g_value_get_string (&value));
+	filesel = GTK_FILE_SELECTION (filesel_widget);
+
+	g_value_unset (&value);
+
+	gtk_signal_connect (GTK_OBJECT (filesel->cancel_button),
+			    "clicked", GTK_SIGNAL_FUNC (browse_dialog_cancel),
+			    fselector);
+	gtk_signal_connect (GTK_OBJECT (filesel->ok_button),
+			    "clicked", GTK_SIGNAL_FUNC (browse_dialog_ok),
+			    fselector);
+
+	fselector->_priv->browse_dialog = GTK_WIDGET (filesel);
+
+	g_value_init (&value, GTK_TYPE_WIDGET);
+	g_value_set_object (&value, G_OBJECT (filesel));
+	g_object_set_property (G_OBJECT (fselector), "browse_dialog", &value);
+	g_value_unset (&value);
+    }
+
+    GNOME_CALL_PARENT_HANDLER (GNOME_SELECTOR_CLASS, do_construct, (selector));
+}
+
+
+static GObject*
+gnome_file_selector_constructor (GType                  type,
+				 guint                  n_construct_properties,
+				 GObjectConstructParam *construct_properties)
+{
+    GObject *object = G_OBJECT_CLASS (parent_class)->constructor (type,
+								  n_construct_properties,
+								  construct_properties);
+    GnomeFileSelector *fselector = GNOME_FILE_SELECTOR (object);
+
+    g_message (G_STRLOC ": %d - %d", type, GNOME_TYPE_FILE_SELECTOR);
+
+    if (type == GNOME_TYPE_FILE_SELECTOR)
+	gnome_selector_do_construct (GNOME_SELECTOR (fselector));
+
+    return object;
+}
+
+/**
+ * gnome_file_selector_new
+ * @history_id: If not %NULL, the text id under which history data is stored
+ *
+ * Description: Creates a new GnomeFileSelector widget.  If  @history_id
+ * is not %NULL, then the history list will be saved and restored between
+ * uses under the given id.
+ *
+ * Returns: Newly-created GnomeFileSelector widget.
+ */
+GtkWidget *
+gnome_file_selector_new (const gchar *history_id,
+			 const gchar *dialog_title)
+{
+    GnomeFileSelector *fselector;
+
+    fselector = g_object_new (gnome_file_selector_get_type (),
+			      "history_id", history_id,
+			      "dialog_title", dialog_title,
+			       NULL);
+
+    return GTK_WIDGET (fselector);
+}
+
+static void
+gnome_file_selector_destroy (GtkObject *object)
+{
+    GnomeFileSelector *fselector;
+
+    /* remember, destroy can be run multiple times! */
+
+    g_return_if_fail (object != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (object));
+
+    fselector = GNOME_FILE_SELECTOR (object);
+
+    GNOME_CALL_PARENT_HANDLER (GTK_OBJECT_CLASS, destroy, (object));
+}
+
+static void
+gnome_file_selector_finalize (GObject *object)
+{
+    GnomeFileSelector *fselector;
+
+    g_return_if_fail (object != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (object));
+
+    fselector = GNOME_FILE_SELECTOR (object);
+
+    g_free (fselector->_priv);
+    fselector->_priv = NULL;
+
+    GNOME_CALL_PARENT_HANDLER (G_OBJECT_CLASS, finalize, (object));
+}
diff --git a/libgnomeui/gnome-file-selector.h b/libgnomeui/gnome-file-selector.h
new file mode 100644
index 0000000..f46326e
--- /dev/null
+++ b/libgnomeui/gnome-file-selector.h
@@ -0,0 +1,83 @@
+/* -*- Mode: C; c-set-style: gnu indent-tabs-mode: t; c-basic-offset: 4; tab-width: 8 -*- */
+/*
+ * Copyright (C) 2000 SuSE GmbH
+ * Author: Martin Baulig <baulig suse de>
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+/* GnomeFileSelector widget - a file selector widget.
+ *
+ * Author: Martin Baulig <baulig suse de>
+ */
+
+#ifndef GNOME_FILE_SELECTOR_H
+#define GNOME_FILE_SELECTOR_H
+
+
+#include <gtk/gtkvbox.h>
+
+#include "gnome-entry.h"
+
+#include <libgnomevfs/gnome-vfs-types.h>
+#include <libgnomevfs/gnome-vfs-directory-filter.h>
+
+
+G_BEGIN_DECLS
+
+
+#define GNOME_TYPE_FILE_SELECTOR            (gnome_file_selector_get_type ())
+#define GNOME_FILE_SELECTOR(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_FILE_SELECTOR, GnomeFileSelector))
+#define GNOME_FILE_SELECTOR_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_FILE_SELECTOR, GnomeFileSelectorClass))
+#define GNOME_IS_FILE_SELECTOR(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_FILE_SELECTOR))
+#define GNOME_IS_FILE_SELECTOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_FILE_SELECTOR))
+#define GNOME_FILE_SELECTOR_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_FILE_SELECTOR, GnomeFileSelectorClass))
+
+
+typedef struct _GnomeFileSelector         GnomeFileSelector;
+typedef struct _GnomeFileSelectorPrivate  GnomeFileSelectorPrivate;
+typedef struct _GnomeFileSelectorClass    GnomeFileSelectorClass;
+
+struct _GnomeFileSelector {
+        GnomeEntry entry;
+        
+        /*< private >*/
+        GnomeFileSelectorPrivate *_priv;
+};
+
+struct _GnomeFileSelectorClass {
+        GnomeEntryClass parent_class;
+};
+
+
+guint      gnome_file_selector_get_type      (void) G_GNUC_CONST;
+
+GtkWidget *gnome_file_selector_new           (const gchar *history_id,
+                                              const gchar *dialog_title);
+
+void       gnome_file_selector_set_filter    (GnomeFileSelector *fselector,
+                                              GnomeVFSDirectoryFilter *filter);
+
+void       gnome_file_selector_clear_filter  (GnomeFileSelector *fselector);
+
+G_END_DECLS
+
+#endif
diff --git a/libgnomeui/gnome-font-picker.c b/libgnomeui/gnome-font-picker.c
new file mode 100644
index 0000000..5bb9e70
--- /dev/null
+++ b/libgnomeui/gnome-font-picker.c
@@ -0,0 +1,988 @@
+/* GNOME font picker button.
+ * Copyright (C) 1998 David Abilleira Freijeiro <odaf nexo es>
+ * All rights reserved.
+ *
+ * Based on gnome-color-picker by Federico Mena <federico nuclecu unam mx>
+ * 
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+#include <gtk/gtksignal.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkalignment.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkvseparator.h>
+#include <gtk/gtkfontsel.h>
+#include <libgnomeui/gnome-pixmap.h>
+#include <libgnomeui/gnome-stock.h>
+#include "gnome-font-picker.h"
+#include <libgnome/gnome-i18n.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+
+struct _GnomeFontPickerPrivate {
+        gchar         *title;
+        
+        gchar         *font_name;
+        gchar         *preview_text;
+
+        GnomeFontPickerMode mode : 2;
+
+        /* Only for GNOME_FONT_PICKER_MODE_FONT_INFO */
+        gboolean      use_font_in_label : 1;
+        gboolean      use_font_in_label_size : 1;
+        gboolean      show_size : 1;
+};
+
+
+#define DEF_FONT_NAME N_("-adobe-times-medium-r-normal-*-14-*-*-*-p-*-*-*")
+#define DEF_PREVIEW_TEXT N_("AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz")
+#define DEF_TITLE N_("Pick a Font")
+
+/* Signals */
+enum {
+	FONT_SET,
+	LAST_SIGNAL
+};
+
+enum {
+	ARG_0,
+	ARG_TITLE,
+	ARG_MODE,
+	ARG_FONT_NAME,
+	ARG_FONT,
+	ARG_PREVIEW_TEXT
+};
+
+/* Prototypes */
+static void gnome_font_picker_class_init (GnomeFontPickerClass *class);
+static void gnome_font_picker_init       (GnomeFontPicker      *cp);
+static void gnome_font_picker_destroy    (GtkObject            *object);
+static void gnome_font_picker_finalize   (GObject              *object);
+static void gnome_font_picker_set_arg    (GtkObject            *object,
+					  GtkArg               *arg,
+					  guint                 arg_id);
+static void gnome_font_picker_get_arg    (GtkObject            *object,
+					  GtkArg               *arg,
+					  guint                 arg_id);
+
+static void gnome_font_picker_clicked(GtkButton *button);
+
+/* Dialog response functions */
+static void gnome_font_picker_dialog_ok_clicked(GtkWidget *widget,
+                                                  gpointer   data);
+static void gnome_font_picker_dialog_cancel_clicked(GtkWidget *widget,
+                                                      gpointer   data);
+
+static gboolean gnome_font_picker_dialog_delete_event(GtkWidget *widget,
+						      GdkEventAny *ev,
+                                                      gpointer   data);
+static void gnome_font_picker_dialog_destroy(GtkWidget *widget,
+					     gpointer   data);
+
+/* Auxiliary functions */
+static GtkWidget *gnome_font_picker_create_inside(GnomeFontPicker *gfs);
+
+static void gnome_font_picker_font_extract_attr(gchar *font_name,
+						gchar *attr,
+						gint i);
+static void gnome_font_picker_font_set_attr(gchar **font_name,
+                                              const gchar *attr,
+                                              gint i);
+
+static void gnome_font_picker_label_use_font_in_label  (GnomeFontPicker *gfs);
+static void gnome_font_picker_update_font_info(GnomeFontPicker *gfs);
+
+
+
+
+static guint font_picker_signals[LAST_SIGNAL] = { 0 };
+
+static GtkButtonClass *parent_class;
+
+
+GtkType
+gnome_font_picker_get_type (void)
+{
+	static GtkType fp_type = 0;
+
+	if ( ! fp_type) {
+		GtkTypeInfo fp_info = {
+			"GnomeFontPicker",
+			sizeof (GnomeFontPicker),
+			sizeof (GnomeFontPickerClass),
+			(GtkClassInitFunc) gnome_font_picker_class_init,
+			(GtkObjectInitFunc) gnome_font_picker_init,
+			NULL, /* reserved_1 */
+			NULL, /* reserved_2 */
+			(GtkClassInitFunc) NULL
+		};
+
+		fp_type = gtk_type_unique (gtk_button_get_type (), &fp_info);
+	}
+
+	return fp_type;
+}
+
+static void
+gnome_font_picker_class_init (GnomeFontPickerClass *class)
+{
+	GtkObjectClass *object_class;
+	GObjectClass *gobject_class;
+	GtkButtonClass *button_class;
+
+	object_class = (GtkObjectClass *) class;
+	gobject_class = (GObjectClass *) class;
+	button_class = (GtkButtonClass *) class;
+
+	parent_class = gtk_type_class (gtk_button_get_type ());
+
+	gtk_object_add_arg_type("GnomeFontPicker::title",
+				GTK_TYPE_STRING,
+				GTK_ARG_READWRITE,
+				ARG_TITLE);
+	gtk_object_add_arg_type("GnomeFontPicker::mode",
+				GTK_TYPE_ENUM,
+				GTK_ARG_READWRITE,
+				ARG_MODE);
+	gtk_object_add_arg_type("GnomeFontPicker::font_name",
+				GTK_TYPE_STRING,
+				GTK_ARG_READWRITE,
+				ARG_FONT_NAME);
+	gtk_object_add_arg_type("GnomeFontPicker::font",
+				GTK_TYPE_POINTER,
+				GTK_ARG_READABLE,
+				ARG_FONT);
+	gtk_object_add_arg_type("GnomeFontPicker::preview_text",
+				GTK_TYPE_STRING,
+				GTK_ARG_READWRITE,
+				ARG_PREVIEW_TEXT);
+
+	font_picker_signals[FONT_SET] =
+		gtk_signal_new ("font_set",
+				GTK_RUN_FIRST,
+				GTK_CLASS_TYPE (object_class),
+				GTK_SIGNAL_OFFSET (GnomeFontPickerClass, font_set),
+				gtk_marshal_VOID__STRING,
+				GTK_TYPE_NONE, 1,
+				GTK_TYPE_STRING);
+
+
+	object_class->destroy = gnome_font_picker_destroy;
+	gobject_class->finalize = gnome_font_picker_finalize;
+	object_class->get_arg = gnome_font_picker_get_arg;
+	object_class->set_arg = gnome_font_picker_set_arg;
+
+	button_class->clicked = gnome_font_picker_clicked;
+
+	class->font_set = NULL;
+}
+
+static void
+gnome_font_picker_init (GnomeFontPicker *gfp)
+{
+
+    gfp->_priv                         = g_new0(GnomeFontPickerPrivate, 1);
+
+    /* Initialize fields */
+    gfp->_priv->mode                   = GNOME_FONT_PICKER_MODE_PIXMAP;
+    gfp->_priv->font_name              = NULL;
+    gfp->_priv->preview_text           = NULL;
+    gfp->_priv->use_font_in_label      = FALSE;
+    gfp->_priv->use_font_in_label_size = 14;
+    gfp->_priv->show_size              = TRUE;
+    gfp->font_dialog                   = NULL;
+    gfp->_priv->title                  = g_strdup(_(DEF_TITLE));
+
+
+    /* Create pixmap or info widgets */
+    gfp->inside = gnome_font_picker_create_inside(gfp);
+    if (gfp->inside)
+        gtk_container_add(GTK_CONTAINER(gfp), gfp->inside);
+
+    gnome_font_picker_set_font_name(gfp, _(DEF_FONT_NAME));
+    gnome_font_picker_set_preview_text(gfp, _(DEF_PREVIEW_TEXT));
+
+    if (gfp->_priv->mode == GNOME_FONT_PICKER_MODE_FONT_INFO) {
+        /* Update */
+        gnome_font_picker_update_font_info(gfp);
+    }
+}
+
+static void
+gnome_font_picker_destroy (GtkObject *object)
+{
+    GnomeFontPicker *gfp;
+    
+    g_return_if_fail (object != NULL);
+    g_return_if_fail (GNOME_IS_FONT_PICKER (object));
+
+    /* remember, destroy can be run multiple times! */
+
+    gfp = GNOME_FONT_PICKER(object);
+    
+    if (gfp->font_dialog)
+      {
+        gtk_widget_destroy(gfp->font_dialog);
+	gfp->font_dialog = NULL;
+      }
+
+    /* g_free handles NULL */
+    g_free(gfp->_priv->font_name);
+    gfp->_priv->font_name = NULL;
+
+    /* g_free handles NULL */
+    g_free(gfp->_priv->preview_text);
+    gfp->_priv->preview_text = NULL;
+
+    /* g_free handles NULL */
+    g_free(gfp->_priv->title);
+    gfp->_priv->title = NULL;
+
+    if (GTK_OBJECT_CLASS (parent_class)->destroy)
+        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+    
+} /* gnome_font_picker_destroy */
+
+static void
+gnome_font_picker_finalize (GObject *object)
+{
+    GnomeFontPicker *gfp;
+    
+    g_return_if_fail (object != NULL);
+    g_return_if_fail (GNOME_IS_FONT_PICKER (object));
+
+    gfp = GNOME_FONT_PICKER(object);
+    
+    /* g_free handles NULL */
+    g_free(gfp->_priv);
+    gfp->_priv = NULL;
+
+    if (G_OBJECT_CLASS (parent_class)->finalize)
+        (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+    
+} /* gnome_font_picker_finalize */
+
+static void
+gnome_font_picker_set_arg (GtkObject *object,
+			   GtkArg *arg,
+			   guint arg_id)
+{
+	GnomeFontPicker *self;
+
+	self = GNOME_FONT_PICKER (object);
+
+	switch (arg_id) {
+	case ARG_TITLE:
+		gnome_font_picker_set_title(self, GTK_VALUE_STRING(*arg));
+		break;
+	case ARG_MODE:
+		gnome_font_picker_set_mode(self, GTK_VALUE_ENUM(*arg));
+		break;
+	case ARG_FONT_NAME:
+		gnome_font_picker_set_font_name(self, GTK_VALUE_STRING(*arg));
+		break;
+	case ARG_PREVIEW_TEXT:
+		gnome_font_picker_set_preview_text(self, GTK_VALUE_STRING(*arg));
+		break;
+
+	default:
+		break;
+	}
+}
+
+static void
+gnome_font_picker_get_arg (GtkObject *object,
+			   GtkArg *arg,
+			   guint arg_id)
+{
+	GnomeFontPicker *self;
+
+	self = GNOME_FONT_PICKER (object);
+
+	switch (arg_id) {
+	case ARG_TITLE:
+		GTK_VALUE_STRING(*arg) =
+			g_strdup(gnome_font_picker_get_title(self));
+		break;
+	case ARG_MODE:
+		GTK_VALUE_ENUM(*arg) =
+			gnome_font_picker_get_mode(self);
+		break;
+	case ARG_FONT_NAME:
+		GTK_VALUE_STRING(*arg) =
+			g_strdup(gnome_font_picker_get_font_name(self));
+		break;
+	case ARG_FONT:
+		GTK_VALUE_POINTER(*arg) =
+			gnome_font_picker_get_font(self);
+		break;
+	case ARG_PREVIEW_TEXT:
+		GTK_VALUE_STRING(*arg) =
+			g_strdup(gnome_font_picker_get_preview_text(self));
+		break;
+	default:
+		break;
+	}
+}
+
+/*************************************************************************
+ Public functions
+ *************************************************************************/
+
+
+/**
+ * gnome_font_picker_new
+ *
+ * Description:
+ * Create new font picker widget.
+ *
+ * Returns:
+ * Pointer to new font picker widget.
+ */
+
+GtkWidget *
+gnome_font_picker_new (void)
+{
+	return GTK_WIDGET (gtk_type_new (gnome_font_picker_get_type ()));
+} /* gnome_font_picker_new */
+
+
+
+/**
+ * gnome_font_picker_set_title
+ * @gfp: Pointer to GNOME font picker widget.
+ * @title: String containing font selection dialog title.
+ *
+ * Description:
+ * Sets the title for the font selection dialog.  If @title is %NULL,
+ * then the default is used.
+ */
+
+void
+gnome_font_picker_set_title (GnomeFontPicker *gfp, const gchar *title)
+{
+	g_return_if_fail (gfp != NULL);
+	g_return_if_fail (GNOME_IS_FONT_PICKER (gfp));
+
+	if ( ! title)
+		title = _(DEF_TITLE);
+
+	/* g_free handles NULL */
+	g_free (gfp->_priv->title);
+        gfp->_priv->title = g_strdup (title);
+
+        /* If FontDialog is created change title */
+        if (gfp->font_dialog)
+            gtk_window_set_title(GTK_WINDOW(gfp->font_dialog),
+				 gfp->_priv->title);
+} /* gnome_font_picker_set_title */
+
+/**
+ * gnome_font_picker_get_title
+ * @gfp: Pointer to GNOME font picker widget.
+ *
+ * Description:
+ * Retrieve name of the font selection dialog title
+ *
+ * Returns:
+ * Pointer to an internal copy of the title string
+ */
+
+const gchar*
+gnome_font_picker_get_title(GnomeFontPicker *gfp)
+{
+    g_return_val_if_fail (gfp != NULL, NULL);
+    g_return_val_if_fail (GNOME_IS_FONT_PICKER (gfp), NULL);
+
+    return gfp->_priv->title;
+} /* gnome_font_picker_get_title */
+
+/**
+ * gnome_font_picker_get_mode
+ * @gfp: Pointer to GNOME font picker widget.
+ *
+ * Description:
+ * Returns current font picker button mode (or what to show).  Possible
+ * values include %GNOME_FONT_PICKER_MODE_PIXMAP,
+ * %GNOME_FONT_PICKER_MODE_FONT_INFO, and 
+ * %GNOME_FONT_PICKER_MODE_USER_WIDGET.
+ *
+ * Returns:
+ * Button mode currently set in font picker widget, or 
+ * %GNOME_FONT_PICKER_MODE_UNKNOWN on error.
+ */
+
+GnomeFontPickerMode
+gnome_font_picker_get_mode        (GnomeFontPicker *gfp)
+{
+    g_return_val_if_fail (gfp != NULL, GNOME_FONT_PICKER_MODE_UNKNOWN);
+    g_return_val_if_fail (GNOME_IS_FONT_PICKER (gfp),
+			  GNOME_FONT_PICKER_MODE_UNKNOWN);
+
+    return gfp->_priv->mode;
+} /* gnome_font_picker_get_mode */
+
+
+/**
+ * gnome_font_picker_set_mode
+ * @gfp: Pointer to GNOME font picker widget.
+ * @mode: Value of subsequent font picker button mode (or what to show)
+ *
+ * Description:
+ * Set value of subsequent font picker button mode (or what to show).
+ */
+
+void       gnome_font_picker_set_mode        (GnomeFontPicker *gfp,
+                                              GnomeFontPickerMode mode)
+{
+    g_return_if_fail (gfp != NULL);
+    g_return_if_fail (GNOME_IS_FONT_PICKER (gfp));
+    g_return_if_fail (mode >= 0 && mode < GNOME_FONT_PICKER_MODE_UNKNOWN);
+
+    if (gfp->_priv->mode != mode) {
+
+        gfp->_priv->mode = mode;
+
+        /* Next sentence will destroy gfp->inside after removing it */
+        gtk_container_remove(GTK_CONTAINER(gfp), gfp->inside);
+        gfp->inside = gnome_font_picker_create_inside(gfp);
+        if (gfp->inside)
+            gtk_container_add(GTK_CONTAINER(gfp), gfp->inside);
+        
+        if (gfp->_priv->mode == GNOME_FONT_PICKER_MODE_FONT_INFO) {
+            /* Update */
+            gnome_font_picker_update_font_info(gfp);
+        }
+    }
+} /* gnome_font_picker_set_mode */
+
+
+/**
+ * gnome_font_picker_fi_set_use_font_in_label
+ * @gfp: Pointer to GNOME font picker widget.
+ * @use_font_in_label: If %TRUE, font name will be written using font chosen.
+ * @size: Display font using this point size.
+ *
+ * Description:
+ * If @use_font_in_label is %TRUE, font name will be written using font chosen
+ * by user and using @size passed to this function.  This only applies if
+ * current button mode is %GNOME_FONT_PICKER_MODE_FONT_INFO.
+ */
+
+void  gnome_font_picker_fi_set_use_font_in_label (GnomeFontPicker *gfp,
+                                                  gboolean use_font_in_label,
+                                                  gint size)
+{
+    g_return_if_fail (gfp != NULL);
+    g_return_if_fail (GNOME_IS_FONT_PICKER (gfp));
+
+    if (gfp->_priv->mode==GNOME_FONT_PICKER_MODE_FONT_INFO) {
+        if (gfp->_priv->use_font_in_label!=use_font_in_label ||
+	    gfp->_priv->use_font_in_label_size!=size) {
+
+            gfp->_priv->use_font_in_label=use_font_in_label;
+            gfp->_priv->use_font_in_label_size=size;
+
+            if (!gfp->_priv->use_font_in_label)
+                gtk_widget_restore_default_style(gfp->font_label);
+            else
+                gnome_font_picker_label_use_font_in_label(gfp);
+        }
+    }
+
+} /* gnome_font_picker_fi_set_use_font_in_label */
+
+
+/**
+ * gnome_font_picker_fi_set_show_size
+ * @gfp: Pointer to GNOME font picker widget.
+ * @show_size: %TRUE if font size should be displayed in dialog.
+ *
+ * Description:
+ * If @show_size is %TRUE, font size will be displayed along with font chosen
+ * by user.  This only applies if current button mode is
+ * %GNOME_FONT_PICKER_MODE_FONT_INFO.
+ */
+
+void       gnome_font_picker_fi_set_show_size (GnomeFontPicker *gfp,
+                                               gboolean show_size)
+{
+    g_return_if_fail (gfp != NULL);
+    g_return_if_fail (GNOME_IS_FONT_PICKER (gfp));
+
+    if (gfp->_priv->mode==GNOME_FONT_PICKER_MODE_FONT_INFO) {
+        if (show_size!=gfp->_priv->show_size)
+        {
+            gfp->_priv->show_size=show_size;
+
+            /* Next sentence will destroy gfp->inside after removing it */
+            gtk_container_remove(GTK_CONTAINER(gfp),gfp->inside);
+            gfp->inside=gnome_font_picker_create_inside(gfp);
+            if (gfp->inside)
+                gtk_container_add(GTK_CONTAINER(gfp),gfp->inside);
+            
+            gnome_font_picker_update_font_info(gfp);
+            
+        } /* if (show_size... */
+    }
+} /* gnome_font_picker_fi_set_show_size */
+
+
+/**
+ * gnome_font_picker_uw_set_widget
+ * @gfp: Pointer to GNOME font picker widget.
+ * @widget: User widget to display for inside of font picker.
+ *
+ * Set the user-supplied @widget as the inside of the font picker.
+ * This only applies with GNOME_FONT_PICKER_MODE_USER_WIDGET.
+ */
+
+void       gnome_font_picker_uw_set_widget    (GnomeFontPicker *gfp,
+                                                        GtkWidget *widget)
+{
+    g_return_if_fail (gfp != NULL);
+    g_return_if_fail (GNOME_IS_FONT_PICKER (gfp));
+
+    if (gfp->_priv->mode==GNOME_FONT_PICKER_MODE_USER_WIDGET) {
+        if (gfp->inside)
+            gtk_container_remove(GTK_CONTAINER(gfp),gfp->inside);
+        
+        gfp->inside=widget;
+        if (gfp->inside)
+            gtk_container_add(GTK_CONTAINER(gfp),gfp->inside);
+    }
+
+} /* gnome_font_picker_uw_set_widget */
+
+
+/**
+ * gnome_font_picker_get_font_name
+ * @gfp: Pointer to GNOME font picker widget.
+ *
+ * Description:
+ * Retrieve name of font from font selection dialog.
+ *
+ * Returns:
+ * Pointer to an internal copy of the font name.
+ */
+
+const gchar*	   gnome_font_picker_get_font_name    (GnomeFontPicker *gfp)
+{
+    g_return_val_if_fail (gfp != NULL, NULL);
+    g_return_val_if_fail (GNOME_IS_FONT_PICKER (gfp), NULL);
+
+    if (gfp->font_dialog) {
+	/* g_free handles NULL */
+	g_free(gfp->_priv->font_name);
+        gfp->_priv->font_name = g_strdup(gtk_font_selection_dialog_get_font_name(GTK_FONT_SELECTION_DIALOG(gfp->font_dialog)));
+    }
+
+    return gfp->_priv->font_name;
+} /* gnome_font_picker_get_font_name */
+
+
+/**
+ * gnome_font_picker_get_font
+ * @gfp: Pointer to GNOME font picker widget.
+ *
+ * Description:
+ * Retrieve font info from font selection dialog.
+ *
+ * Returns:
+ * Return value of gtk_font_selection_dialog_get_font, or %NULL if
+ * font dialog is not being displayed.
+ */
+
+GdkFont*   gnome_font_picker_get_font	       (GnomeFontPicker *gfp)
+{
+    g_return_val_if_fail (gfp != NULL, NULL);
+    g_return_val_if_fail (GNOME_IS_FONT_PICKER (gfp), NULL);
+    
+    return (gfp->font_dialog ?
+             gtk_font_selection_dialog_get_font(GTK_FONT_SELECTION_DIALOG(gfp->font_dialog)) :
+             NULL);
+} /* gnome_font_picker_get_font */
+
+
+/**
+ * gnome_font_picker_set_font_name
+ * @gfp: Pointer to GNOME font picker widget.
+ * @fontname: Name of font to display in font selection dialog
+ *
+ * Description:
+ * Set or update currently-displayed font in font picker dialog.
+ *
+ * Returns:
+ * Return value of gtk_font_selection_dialog_set_font_name if the
+ * font selection dialog exists, otherwise %FALSE.
+ */
+
+gboolean   gnome_font_picker_set_font_name    (GnomeFontPicker *gfp,
+					       const gchar       *fontname)
+{
+    g_return_val_if_fail (gfp != NULL, FALSE);
+    g_return_val_if_fail (GNOME_IS_FONT_PICKER (gfp), FALSE);
+    g_return_val_if_fail (fontname != NULL, FALSE);
+
+    /* g_free handles NULL */
+    g_free(gfp->_priv->font_name);
+    gfp->_priv->font_name = g_strdup(fontname);
+    
+    if (gfp->_priv->mode == GNOME_FONT_PICKER_MODE_FONT_INFO)
+	gnome_font_picker_update_font_info(gfp);
+
+    if (gfp->font_dialog)
+        return gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(gfp->font_dialog), gfp->_priv->font_name);
+    else
+        return FALSE;
+} /* gnome_font_picker_set_font_name */
+
+
+/**
+ * gnome_font_picker_get_preview_text
+ * @gfp: Pointer to GNOME font picker widget.
+ *
+ * Description:
+ * Retrieve preview text from font selection dialog if available.
+ *
+ * Returns:
+ * Reference to internal copy of preview text string, or %NULL if no
+ * font dialog is being displayed.
+ */
+
+const gchar*	   gnome_font_picker_get_preview_text (GnomeFontPicker *gfp)
+{
+    g_return_val_if_fail (gfp != NULL, NULL);
+    g_return_val_if_fail (GNOME_IS_FONT_PICKER (gfp), NULL);
+
+    if (gfp->font_dialog) {
+        /* g_free handles NULL */
+        g_free(gfp->_priv->preview_text);
+        gfp->_priv->preview_text = g_strdup(gtk_font_selection_dialog_get_preview_text(GTK_FONT_SELECTION_DIALOG(gfp->font_dialog)));
+    }
+
+    return gfp->_priv->preview_text;
+    
+} /* gnome_font_picker_get_preview_text */
+
+
+/**
+ * gnome_font_picker_set_preview_text
+ * @gfp: Pointer to GNOME font picker widget.
+ * @text: New preview text
+ *
+ * Description:
+ * Set preview text in font picker, and in font selection dialog if one
+ * is being displayed.
+ */
+
+void	   gnome_font_picker_set_preview_text (GnomeFontPicker *gfp,
+                                               const gchar     *text)
+{
+    g_return_if_fail (gfp != NULL);
+    g_return_if_fail (GNOME_IS_FONT_PICKER (gfp));
+    g_return_if_fail (text != NULL);
+
+    /* g_free handles NULL */
+    g_free(gfp->_priv->preview_text);
+    gfp->_priv->preview_text = g_strdup(text);
+
+    if (gfp->font_dialog)
+        gtk_font_selection_dialog_set_preview_text(GTK_FONT_SELECTION_DIALOG(gfp->font_dialog), gfp->_priv->preview_text);
+
+} /* gnome_font_picker_set_preview_text */
+
+/* ************************************************************************
+ Internal functions
+ **************************************************************************/
+
+static void
+gnome_font_picker_clicked(GtkButton *button)
+{
+    GnomeFontPicker      *gfp;
+    GtkFontSelectionDialog *fsd;
+    
+    gfp = GNOME_FONT_PICKER(button);
+
+    if (!gfp->font_dialog) {
+        GtkWidget *parent;
+
+        parent = gtk_widget_get_toplevel(GTK_WIDGET(gfp));
+      
+        gfp->font_dialog=gtk_font_selection_dialog_new(gfp->_priv->title);
+
+        if (parent)
+            gtk_window_set_transient_for(GTK_WINDOW(gfp->font_dialog),
+                                         GTK_WINDOW(parent));
+        
+        fsd=GTK_FONT_SELECTION_DIALOG(gfp->font_dialog);
+
+        /* If there is a grabed window, set new dialog as modal */
+        if (gtk_grab_get_current())
+            gtk_window_set_modal(GTK_WINDOW(gfp->font_dialog),TRUE);
+
+        gtk_signal_connect(GTK_OBJECT(fsd->ok_button), "clicked",
+                           (GtkSignalFunc) gnome_font_picker_dialog_ok_clicked,
+                           gfp);
+
+        gtk_signal_connect(GTK_OBJECT(fsd->cancel_button), "clicked",
+                           (GtkSignalFunc) gnome_font_picker_dialog_cancel_clicked,
+                           gfp);
+        gtk_signal_connect(GTK_OBJECT(fsd),"delete_event",
+                           (GtkSignalFunc) gnome_font_picker_dialog_delete_event,
+                           gfp);
+        gtk_signal_connect(GTK_OBJECT(fsd),"destroy",
+                           (GtkSignalFunc) gnome_font_picker_dialog_destroy,
+                           gfp);
+                           
+    } /* if */
+
+    if (!GTK_WIDGET_VISIBLE(gfp->font_dialog)) {
+        
+        /* Set font and preview text */
+        gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(gfp->font_dialog),
+                                                gfp->_priv->font_name);
+        gtk_font_selection_dialog_set_preview_text(GTK_FONT_SELECTION_DIALOG(gfp->font_dialog),
+                                                   gfp->_priv->preview_text);
+        
+        gtk_widget_show(gfp->font_dialog);
+    } else if (gfp->font_dialog->window) {
+	/*raise the window so that if it is obscured that we see it*/
+	gdk_window_raise(gfp->font_dialog->window);
+    }/* if */
+} /* gnome_font_picker_clicked */
+
+static void
+gnome_font_picker_dialog_ok_clicked(GtkWidget *widget,
+				    gpointer   data)
+{
+    GnomeFontPicker *gfp;
+
+    gfp = GNOME_FONT_PICKER (data);
+
+    gtk_widget_hide(gfp->font_dialog);
+    
+    /* These calls will update gfp->_priv->font_name and gfp->_priv->preview_text */
+    gnome_font_picker_get_font_name(gfp);
+    gnome_font_picker_get_preview_text(gfp);
+
+    /* Set label font */
+    if (gfp->_priv->mode == GNOME_FONT_PICKER_MODE_FONT_INFO)
+        gnome_font_picker_update_font_info(gfp);
+
+    /* Emit font_set signal */
+    gtk_signal_emit(GTK_OBJECT(gfp),
+		    font_picker_signals[FONT_SET],
+		    gfp->_priv->font_name);
+    
+} /* gnome_font_picker_dialog_ok_clicked */
+
+
+static void
+gnome_font_picker_dialog_cancel_clicked(GtkWidget *widget,
+					gpointer   data)
+{
+    GnomeFontPicker *gfp;
+
+    gfp = GNOME_FONT_PICKER (data);
+
+    gtk_widget_hide(gfp->font_dialog);
+
+    /* Restore old values */
+    gnome_font_picker_set_font_name(gfp,gfp->_priv->font_name);
+    gnome_font_picker_set_preview_text(gfp,gfp->_priv->preview_text);
+
+} /* gnome_font_picker_dialog_cancel_clicked */
+
+static gboolean
+gnome_font_picker_dialog_delete_event(GtkWidget *widget, GdkEventAny *ev,
+				      gpointer   data)
+{
+    GnomeFontPicker *gfp;
+
+    gfp = GNOME_FONT_PICKER (data);
+    
+    /* Here we restore old values */
+    gnome_font_picker_set_font_name(gfp,gfp->_priv->font_name);
+    gnome_font_picker_set_preview_text(gfp,gfp->_priv->preview_text);
+
+    return FALSE;
+} /* gnome_font_picker_dialog_delete_event */
+
+static void
+gnome_font_picker_dialog_destroy(GtkWidget *widget,
+				 gpointer   data)
+{
+    GnomeFontPicker *gfp;
+
+    gfp = GNOME_FONT_PICKER (data);
+    
+    /* Query GtkFontSelectionDialog before it get destroyed */
+    /* These calls will update gfp->_priv->font_name and gfp->_priv->preview_text */
+    gnome_font_picker_get_font_name(gfp);
+    gnome_font_picker_get_preview_text(gfp);
+
+    /* Dialog will get destroyed so reference is no valid now */
+    gfp->font_dialog = NULL;
+} /* gnome_font_picker_dialog_destroy */
+
+GtkWidget *gnome_font_picker_create_inside(GnomeFontPicker *gfp)
+{
+    GtkWidget *widget;
+    
+    if (gfp->_priv->mode==GNOME_FONT_PICKER_MODE_PIXMAP) {
+        widget=gnome_stock_new_with_icon(GNOME_STOCK_PIXMAP_FONT);
+        gtk_widget_show(widget);
+    } else if (gfp->_priv->mode==GNOME_FONT_PICKER_MODE_FONT_INFO) {
+        widget=gtk_hbox_new(FALSE,0);
+
+        gfp->font_label=gtk_label_new(_("Font"));
+            
+        gtk_label_set_justify(GTK_LABEL(gfp->font_label),GTK_JUSTIFY_LEFT);
+        gtk_box_pack_start(GTK_BOX(widget),gfp->font_label,TRUE,TRUE,5);
+
+        if (gfp->_priv->show_size) {
+            gfp->vsep=gtk_vseparator_new();
+            gtk_box_pack_start(GTK_BOX(widget),gfp->vsep,FALSE,FALSE,0);
+            
+            gfp->size_label=gtk_label_new("14");
+            gtk_box_pack_start(GTK_BOX(widget),gfp->size_label,FALSE,FALSE,5);
+        }
+
+        gtk_widget_show_all(widget);
+
+    } else /* GNOME_FONT_PICKER_MODE_USER_WIDGET */ {
+        widget=NULL;
+    }
+    
+    return widget;
+        
+} /* gnome_font_picker_create_inside */
+
+static void gnome_font_picker_font_extract_attr(gchar *font_name,
+						gchar *attr,
+						gint i)
+{
+    gchar *pTmp;
+
+    /* Search paramether */
+    for (pTmp=font_name; *pTmp && i > 0; i--,pTmp++)
+        pTmp=(gchar *)strchr(pTmp,'-');
+
+    if (*pTmp!=0) {
+        while (*pTmp!='-' && *pTmp!=0) {
+            *attr=*pTmp;
+            attr++; pTmp++;
+        }
+        *attr=0;
+    }
+    else strcpy(attr, "Unknown");
+
+} /* gnome_font_picker_font_extract_attr */
+
+static void gnome_font_picker_font_set_attr(gchar **font_name,
+					    const gchar *attr,
+					    gint i)
+{
+    gchar *pTgt;
+    gchar *pTmpSrc,*pTmpTgt;
+
+
+    pTgt=g_malloc(strlen(*font_name)+strlen(attr)+1);
+    
+    /* Search paramether */
+    for (pTmpSrc=*font_name; i!=0; i--,pTmpSrc++)
+        pTmpSrc=(gchar *)strchr(pTmpSrc,'-');
+
+    /* Copy until attrib */
+    memcpy(pTgt,*font_name,pTmpSrc-*font_name);
+    
+    /* Copy attrib */
+    pTmpTgt=pTgt+(pTmpSrc-*font_name);
+    memcpy(pTmpTgt,attr,strlen(attr));
+    
+    /* Copy until end */
+    pTmpSrc=(gchar *)strchr(pTmpSrc,'-');
+    pTmpTgt+=strlen(attr);
+    strcpy(pTmpTgt,pTmpSrc);
+
+    /* Save result */
+    g_free(*font_name);
+    *font_name = g_strdup(pTgt);
+    g_free(pTgt);
+} /* gnome_font_picker_font_set_attr */
+
+static void gnome_font_picker_label_use_font_in_label  (GnomeFontPicker *gfp)
+{
+    GdkFont *font;
+    GtkStyle *style;
+    gchar *pStr,size[20];
+    
+    /* Change size */
+    pStr = g_strdup(gfp->_priv->font_name);
+    g_snprintf(size, sizeof(size), "%d",gfp->_priv->use_font_in_label_size);
+    gnome_font_picker_font_set_attr(&pStr,size,7);
+
+
+    /* Load font */
+    font=gdk_font_load(pStr);
+    if (!font) {
+      g_free (pStr);
+      return; /* Use widget default */
+    }
+
+    g_return_if_fail( font != NULL );
+
+    /* Change label style */
+    gtk_widget_ensure_style(gfp->font_label);
+    style=gtk_style_copy(gfp->font_label->style);
+    gdk_font_unref(style->font);
+    style->font=font;
+    gtk_widget_set_style(gfp->font_label,style);
+    gtk_style_unref(style);
+
+    g_free(pStr);    
+
+} /* gnome_font_picker_set_label_font */
+
+static void gnome_font_picker_update_font_info(GnomeFontPicker *gfp)
+{
+    gchar *pTmp;
+
+    pTmp = g_strdup(gfp->_priv->font_name);
+
+    /* Extract font name */
+    gnome_font_picker_font_extract_attr(gfp->_priv->font_name,pTmp,2);
+    *pTmp=toupper(*pTmp);
+    gtk_label_set_text(GTK_LABEL(gfp->font_label),pTmp);
+
+    /* Extract font size */
+    if (gfp->_priv->show_size)
+    {
+        gnome_font_picker_font_extract_attr(gfp->_priv->font_name,pTmp,7);
+        gtk_label_set_text(GTK_LABEL(gfp->size_label),pTmp);
+    }
+
+    if (gfp->_priv->use_font_in_label)
+        gnome_font_picker_label_use_font_in_label(gfp);
+        
+    g_free(pTmp);
+    
+} /* gnome_font_picker_update_font_info */
diff --git a/libgnomeui/gnome-font-picker.h b/libgnomeui/gnome-font-picker.h
new file mode 100644
index 0000000..53f1fcf
--- /dev/null
+++ b/libgnomeui/gnome-font-picker.h
@@ -0,0 +1,119 @@
+/* GNOME font picker button.
+ * Copyright (C) 1998 David Abilleira Freijeiro <odaf nexo es>
+ * All rights reserved
+ * Based on gnome-color-picker by Federico Mena <federico nuclecu unam mx>
+ * 
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+
+#ifndef GNOME_FONT_PICKER_H
+#define GNOME_FONT_PICKER_H
+
+#include <gtk/gtkbutton.h>
+
+
+G_BEGIN_DECLS
+
+/* GnomeFontPicker is a button widget that allow user to select a font.
+ */
+
+/* Button Mode or What to show */
+typedef enum {
+    GNOME_FONT_PICKER_MODE_PIXMAP,
+    GNOME_FONT_PICKER_MODE_FONT_INFO,
+    GNOME_FONT_PICKER_MODE_USER_WIDGET,
+    GNOME_FONT_PICKER_MODE_UNKNOWN
+} GnomeFontPickerMode;
+        
+
+#define GNOME_TYPE_FONT_PICKER            (gnome_font_picker_get_type ())
+#define GNOME_FONT_PICKER(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_FONT_PICKER, GnomeFontPicker))
+#define GNOME_FONT_PICKER_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_FONT_PICKER, GnomeFontPickerClass))
+#define GNOME_IS_FONT_PICKER(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_FONT_PICKER))
+#define GNOME_IS_FONT_PICKER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_FONT_PICKER))
+#define GNOME_FONT_PICKER_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_FONT_PICKER, GnomeFontPickerClass))
+
+typedef struct _GnomeFontPicker        GnomeFontPicker;
+typedef struct _GnomeFontPickerPrivate GnomeFontPickerPrivate;
+typedef struct _GnomeFontPickerClass   GnomeFontPickerClass;
+
+struct _GnomeFontPicker {
+        GtkButton button;
+    
+	GtkWidget     *font_dialog;
+        GtkWidget     *inside;
+        GtkWidget     *font_label, *vsep, *size_label;
+
+	/*< private >*/
+	GnomeFontPickerPrivate *_priv;
+};
+
+struct _GnomeFontPickerClass {
+	GtkButtonClass parent_class;
+
+	/* font_set signal is emitted when font is choosed */
+	void (* font_set) (GnomeFontPicker *gfp, gchar *font_name);
+};
+
+
+/* Standard Gtk function */
+GtkType gnome_font_picker_get_type (void) G_GNUC_CONST;
+
+/* Creates a new font picker widget */
+GtkWidget *gnome_font_picker_new (void);
+
+/* Sets the title for the font selection dialog */
+void       gnome_font_picker_set_title       (GnomeFontPicker *gfp,
+					      const gchar *title);
+const gchar * gnome_font_picker_get_title    (GnomeFontPicker *gfp);
+
+/* Button mode */
+GnomeFontPickerMode
+           gnome_font_picker_get_mode        (GnomeFontPicker *gfp);
+
+void       gnome_font_picker_set_mode        (GnomeFontPicker *gfp,
+                                              GnomeFontPickerMode mode);
+/* With  GNOME_FONT_PICKER_MODE_FONT_INFO */
+/* If use_font_in_label is true, font name will be writen using font choosed by user and
+ using size passed to this function*/
+void       gnome_font_picker_fi_set_use_font_in_label (GnomeFontPicker *gfp,
+                                                       gboolean use_font_in_label,
+                                                       gint size);
+
+void       gnome_font_picker_fi_set_show_size (GnomeFontPicker *gfp,
+                                               gboolean show_size);
+
+/* With GNOME_FONT_PICKER_MODE_USER_WIDGET */
+void       gnome_font_picker_uw_set_widget    (GnomeFontPicker *gfp,
+                                               GtkWidget       *widget);
+
+/* Functions to interface with GtkFontSelectionDialog */
+const gchar* gnome_font_picker_get_font_name  (GnomeFontPicker *gfp);
+
+GdkFont*   gnome_font_picker_get_font	      (GnomeFontPicker *gfp);
+
+gboolean   gnome_font_picker_set_font_name    (GnomeFontPicker *gfp,
+                                               const gchar     *fontname);
+
+const gchar* gnome_font_picker_get_preview_text (GnomeFontPicker *gfp);
+
+void	   gnome_font_picker_set_preview_text (GnomeFontPicker *gfp,
+                                               const gchar     *text);
+
+
+G_END_DECLS
+
+    
+#endif /* GNOME_FONT_PICKER_H */
diff --git a/libgnomeui/gnome-gconf-ui.c b/libgnomeui/gnome-gconf-ui.c
new file mode 100644
index 0000000..d541782
--- /dev/null
+++ b/libgnomeui/gnome-gconf-ui.c
@@ -0,0 +1,577 @@
+/*  -*- Mode: C; c-set-style: linux; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* GNOME GUI Library - gnome-gconf.h
+ * Copyright (C) 2000  Red Hat Inc.,
+ * All rights reserved.
+ *
+ * Author: Jonathan Blandford  <jrb redhat com>
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+
+#include <stdlib.h>
+#include <liboaf/liboaf.h>
+
+#define GCONF_ENABLE_INTERNALS 1
+#include <gconf/gconf.h>
+extern struct poptOption gconf_options[];
+
+#include <libgnome/libgnome.h>
+#include "oafgnome.h"
+#include "gnome-gconf.h"
+#include "gnome-messagebox.h"
+#include "gnome-stock-ids.h"
+#include <gtk/gtkmain.h>
+
+
+GConfValue *
+gnome_gconf_gtk_entry_get (GtkEntry       *entry,
+			   GConfValueType  type)
+{
+	GConfValue *retval = NULL;
+	const char *text;
+	gint i;
+	gfloat f;
+
+	g_return_val_if_fail (entry != NULL, NULL);
+	g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
+	g_return_val_if_fail ((type == GCONF_VALUE_STRING) ||
+			      (type == GCONF_VALUE_INT) ||
+			      (type == GCONF_VALUE_FLOAT), NULL);
+
+	text = gtk_entry_get_text (entry);
+	retval = gconf_value_new (type);
+	switch (type) {
+	case GCONF_VALUE_STRING:
+		gconf_value_set_string (retval, text);
+		break;
+	case GCONF_VALUE_INT:
+		i = strtol (text, NULL, 0);
+		gconf_value_set_int (retval, i);
+		break;
+	case GCONF_VALUE_FLOAT:
+		f = strtod (text, NULL);
+		gconf_value_set_float (retval, f);
+		break;
+	default:
+		g_assert_not_reached ();
+	}
+
+	return retval;
+
+}
+
+void
+gnome_gconf_gtk_entry_set (GtkEntry       *entry,
+			   GConfValue     *value)
+{
+	gchar string[33];
+
+	g_return_if_fail (entry != NULL);
+	g_return_if_fail (GTK_IS_ENTRY (entry));
+	g_return_if_fail (value != NULL);
+	g_return_if_fail ((value->type == GCONF_VALUE_STRING) ||
+			      (value->type == GCONF_VALUE_INT) ||
+			      (value->type == GCONF_VALUE_FLOAT));
+
+	switch (value->type) {
+	case GCONF_VALUE_STRING:
+		gtk_entry_set_text (entry, gconf_value_get_string (value));
+		break;
+	case GCONF_VALUE_INT:
+		g_snprintf (string, 32, "%d", gconf_value_get_int (value));
+		gtk_entry_set_text (entry, string);
+		break;
+	case GCONF_VALUE_FLOAT:
+		g_snprintf (string, 32, "%f", gconf_value_get_float (value));
+		gtk_entry_set_text (entry, string);
+		break;
+	default:
+		g_assert_not_reached ();
+	}
+}
+
+GConfValue *
+gnome_gconf_spin_button_get (GtkSpinButton *spin_button,
+			     GConfValueType  type)
+{
+	GConfValue *retval = NULL;
+	gint i;
+	gfloat f;
+
+	g_return_val_if_fail (spin_button != NULL, NULL);
+	g_return_val_if_fail (GTK_IS_SPIN_BUTTON (spin_button), NULL);
+	g_return_val_if_fail ((type == GCONF_VALUE_INT) ||
+			      (type == GCONF_VALUE_FLOAT), NULL);
+
+	retval = gconf_value_new (type);
+	switch (type) {
+	case GCONF_VALUE_INT:
+		i = gtk_spin_button_get_value_as_int (spin_button);
+		gconf_value_set_int (retval, i);
+		break;
+	case GCONF_VALUE_FLOAT:
+		f = gtk_spin_button_get_value_as_float (spin_button);
+		gconf_value_set_float (retval, f);
+		break;
+	default:
+		break;
+	}
+
+	return retval;
+}
+
+void
+gnome_gconf_spin_button_set (GtkSpinButton *spin_button,
+			     GConfValue    *value)
+{
+	float f;
+
+	g_return_if_fail (spin_button != NULL);
+	g_return_if_fail (GTK_IS_SPIN_BUTTON (spin_button));
+	g_return_if_fail (value != NULL);
+	g_return_if_fail ((value->type == GCONF_VALUE_INT) ||
+			  (value->type == GCONF_VALUE_FLOAT));
+
+	switch (value->type) {
+	case GCONF_VALUE_INT:
+		f = gconf_value_get_int (value);
+		gtk_spin_button_set_value (spin_button, f);
+		break;
+	case GCONF_VALUE_FLOAT:
+		f = gconf_value_get_float (value);
+		gtk_spin_button_set_value (spin_button, f);
+		break;
+	default:
+		break;
+	}
+}
+
+GConfValue *
+gnome_gconf_gtk_radio_button_get (GtkRadioButton  *radio,
+				  GConfValueType   type)
+{
+	GConfValue *retval;
+	int i = 0;
+	GSList *group;
+	
+	g_return_val_if_fail (radio != NULL, NULL);
+	g_return_val_if_fail (GTK_IS_RADIO_BUTTON (radio), NULL);
+	g_return_val_if_fail (((type == GCONF_VALUE_BOOL) ||
+			       (type == GCONF_VALUE_INT)), NULL);
+
+	retval = gconf_value_new (type);
+	for (i = 0, group = radio->group; group != NULL; i++, group = group->next) {
+		if (GTK_TOGGLE_BUTTON (group->data)->active) {
+			if (type == GCONF_VALUE_BOOL) {
+				if (i > 1)
+					g_warning ("more then two radio buttons used with a boolean\n");
+				else
+					gconf_value_set_bool (retval, i);
+			} else {
+				gconf_value_set_int (retval, i);
+			}
+			break;
+		}
+	}
+	return retval;
+}
+
+void
+gnome_gconf_gtk_radio_button_set (GtkRadioButton  *radio,
+				  GConfValue      *value)
+{
+	gint i, j = 0;
+	GSList *list;
+
+	g_return_if_fail (radio != NULL);
+	g_return_if_fail (GTK_IS_RADIO_BUTTON (radio));
+	g_return_if_fail (value != NULL);
+	g_return_if_fail ((value->type == GCONF_VALUE_BOOL) ||
+			  (value->type == GCONF_VALUE_INT));
+
+	switch (value->type) {
+	case GCONF_VALUE_BOOL:
+		j = gconf_value_get_bool (value);
+		break;
+	case GCONF_VALUE_INT:
+		j = gconf_value_get_int (value);
+		break;
+	default:
+		g_assert_not_reached();
+	}
+
+	for (list = radio->group, i = 0 ; i != j && list != NULL; i ++, list = list->next)
+		;
+	if (list)
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (list->data), TRUE);
+}
+
+GConfValue *
+gnome_gconf_gtk_range_get (GtkRange       *range,
+			   GConfValueType  type)
+{
+	GtkAdjustment *adjustment;
+	GConfValue *retval;
+	int i;
+
+	g_return_val_if_fail (range != NULL, NULL);
+	g_return_val_if_fail (GTK_IS_RANGE (range), NULL);
+	g_return_val_if_fail ((type == GCONF_VALUE_FLOAT) ||
+			      (type == GCONF_VALUE_INT), NULL);
+
+	adjustment = gtk_range_get_adjustment (range);
+	retval = gconf_value_new (type);
+	switch (type) {
+	case GCONF_VALUE_INT:
+		i = adjustment->value;
+		gconf_value_set_int (retval, i);
+		break;
+	case GCONF_VALUE_FLOAT:
+		gconf_value_set_float (retval, adjustment->value);
+		break;
+	default:
+		break;
+	}
+	return retval;
+}
+
+void
+gnome_gconf_gtk_range_set (GtkRange       *range,
+			   GConfValue     *value)
+{
+	GtkAdjustment *adjustment;
+	gdouble f = 0.0;
+
+	g_return_if_fail (range != NULL);
+	g_return_if_fail (GTK_IS_RANGE (range));
+	g_return_if_fail ((value->type == GCONF_VALUE_FLOAT) ||
+			  (value->type == GCONF_VALUE_INT));
+
+	switch (value->type) {
+	case GCONF_VALUE_FLOAT:
+		f = gconf_value_get_float (value);
+		break;
+	case GCONF_VALUE_INT:
+		f = gconf_value_get_int (value);
+		break;
+	default:
+		g_assert_not_reached();
+	}
+	adjustment = gtk_range_get_adjustment (range);
+	gtk_adjustment_set_value (adjustment, f);
+}
+
+GConfValue *
+gnome_gconf_gtk_toggle_button_get (GtkToggleButton *toggle,
+				   GConfValueType   type)
+{
+	GConfValue *retval;
+
+	g_return_val_if_fail (toggle != NULL, NULL);
+	g_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (toggle), NULL);
+	g_return_val_if_fail (((type == GCONF_VALUE_BOOL)||
+			       (type == GCONF_VALUE_INT)), NULL);
+
+	retval = gconf_value_new (type);
+	switch (type) {
+	case GCONF_VALUE_BOOL:
+		gconf_value_set_bool (retval, toggle->active);
+		break;
+	case GCONF_VALUE_INT:
+		gconf_value_set_int (retval, toggle->active);
+		break;
+	default:
+		g_assert_not_reached ();
+	}
+	return retval;
+}
+
+void
+gnome_gconf_gtk_toggle_button_set (GtkToggleButton *toggle,
+				   GConfValue      *value)
+{
+	g_return_if_fail (toggle != NULL);
+	g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle));
+	g_return_if_fail (value != NULL);
+	g_return_if_fail ((value->type == GCONF_VALUE_BOOL)||
+			  (value->type == GCONF_VALUE_INT));
+
+	switch (value->type) {
+	case GCONF_VALUE_BOOL:
+		gtk_toggle_button_set_active (toggle, gconf_value_get_bool (value));
+		break;
+	case GCONF_VALUE_INT:
+		gtk_toggle_button_set_active (toggle, gconf_value_get_int (value));
+		break;
+	default:
+		g_assert_not_reached ();
+	}
+}
+
+GConfValue *
+gnome_gconf_gnome_color_picker_get (GnomeColorPicker *picker,
+				    GConfValueType    type)
+{
+	GConfValue *retval;
+	gushort r, g, b, a;
+	gchar color[18];
+
+	g_return_val_if_fail (picker != NULL, NULL);
+	g_return_val_if_fail (GNOME_IS_COLOR_PICKER (picker), NULL);
+	g_return_val_if_fail ((type == GCONF_VALUE_STRING), NULL);
+
+	retval = gconf_value_new (type);
+	switch (type) {
+	case GCONF_VALUE_STRING:
+		gnome_color_picker_get_i16 (picker, &r, &g, &b, &a);
+		g_snprintf (color, 18, "#%04X%04X%04X%04X", r, g, b, a);
+		gconf_value_set_string (retval, color);
+		break;
+	default:
+		g_assert_not_reached ();
+	}
+	return retval;
+}
+
+void
+gnome_gconf_gnome_color_picker_set (GnomeColorPicker *picker,
+				    GConfValue       *value)
+{
+	gushort r, g, b, a;
+	gchar *color;
+
+	g_return_if_fail (picker != NULL);
+	g_return_if_fail (GNOME_IS_COLOR_PICKER (picker));
+	g_return_if_fail (value != NULL);
+	g_return_if_fail (value->type == GCONF_VALUE_STRING);
+
+	color = g_strndup (gconf_value_get_string (value), 17);
+	a = strtol (color  + 13, (char **)NULL, 16);
+	*(color +13) = '\0';
+	b = strtol (color  + 9, (char **)NULL, 16);
+	*(color +9) = '\0';
+	g = strtol (color  + 5, (char **)NULL, 16);
+	*(color +5) = '\0';
+	r = strtol (color  + 1, (char **)NULL, 16);
+	gnome_color_picker_set_i16 (picker, r, g, b, a);
+	g_free (color);
+}
+
+gchar*
+gnome_gconf_get_gnome_libs_settings_relative (const gchar *subkey)
+{
+        gchar *dir;
+        gchar *key;
+
+        dir = g_strconcat("/apps/gnome-settings/",
+                          gnome_program_get_name(gnome_program_get()),
+                          NULL);
+
+        if (subkey && *subkey) {
+                key = gconf_concat_dir_and_key(dir, subkey);
+                g_free(dir);
+        } else {
+                /* subkey == "" */
+                key = dir;
+        }
+
+        return key;
+}
+
+gchar*
+gnome_gconf_get_app_settings_relative (const gchar *subkey)
+{
+        gchar *dir;
+        gchar *key;
+
+        dir = g_strconcat("/apps/",
+                          gnome_program_get_name(gnome_program_get()),
+                          NULL);
+
+        if (subkey && *subkey) {
+                key = gconf_concat_dir_and_key(dir, subkey);
+                g_free(dir);
+        } else {
+                /* subkey == "" */
+                key = dir;
+        }
+
+        return key;
+}
+
+/*
+ * Our global GConfClient, and module stuff
+ */
+static void gnome_default_gconf_client_error_handler (GConfClient                  *client,
+                                                      GError                       *error);
+
+
+static GConfClient* global_client = NULL;
+
+GConfClient*
+gnome_get_gconf_client (void)
+{
+        g_return_val_if_fail(global_client != NULL, NULL);
+        
+        return global_client;
+}
+
+static void
+gnome_gconf_pre_args_parse(GnomeProgram *app, GnomeModuleInfo *mod_info)
+{
+        gconf_preinit(app, (GnomeModuleInfo*)mod_info);
+
+        gconf_client_set_global_default_error_handler(gnome_default_gconf_client_error_handler);
+}
+
+static void
+gnome_gconf_post_args_parse(GnomeProgram *app, GnomeModuleInfo *mod_info)
+{
+        gchar *settings_dir;
+        
+        gconf_postinit(app, (GnomeModuleInfo*)mod_info);
+
+        global_client = gconf_client_get_default();
+
+        gconf_client_add_dir(global_client,
+                             "/desktop/gnome",
+                             GCONF_CLIENT_PRELOAD_NONE, NULL);
+
+        settings_dir = gnome_gconf_get_gnome_libs_settings_relative("");
+
+        gconf_client_add_dir(global_client,
+                             settings_dir,
+                             /* Possibly we should turn preload on for this */
+                             GCONF_CLIENT_PRELOAD_NONE,
+                             NULL);
+        g_free(settings_dir);
+}
+
+extern GnomeModuleInfo gtk_module_info;
+
+static GnomeModuleRequirement gnome_gconf_requirements[] = {
+        { "1.2.5", &gtk_module_info },
+        /* VERSION is also our version note - it's all libgnomeui */
+        { VERSION, &liboafgnome_module_info },
+        { NULL, NULL }
+};
+
+GnomeModuleInfo gnome_gconf_module_info = {
+        "gnome-gconf", VERSION, N_("GNOME GConf Support"),
+        gnome_gconf_requirements,
+        gnome_gconf_pre_args_parse, gnome_gconf_post_args_parse,
+        gconf_options
+};
+
+
+typedef struct {
+        GConfClient                  *client;
+} ErrorIdleData;
+
+static guint error_handler_idle = 0;
+static GSList *pending_errors = NULL;
+static ErrorIdleData eid = { NULL };
+
+static gint
+error_idle_func(gpointer data)
+{
+        GtkWidget *dialog;
+        GSList *iter;
+        gboolean have_overridden = FALSE;
+        gchar* mesg = NULL;
+        const gchar* fmt = NULL;
+        
+        error_handler_idle = 0;
+
+        g_return_val_if_fail(eid.client != NULL, FALSE);
+        g_return_val_if_fail(pending_errors != NULL, FALSE);
+        
+        iter = pending_errors;
+        while (iter != NULL) {
+                GError *error = iter->data;
+
+                if (g_error_matches (error, GCONF_ERROR, GCONF_ERROR_OVERRIDDEN))
+                        have_overridden = TRUE;
+                
+                iter = g_slist_next(iter);
+        }
+        
+        if (have_overridden) {
+                fmt = _("You attempted to change an aspect of your configuration that your system administrator or operating system vendor does not allow you to change. Some of the settings you have selected may not take effect, or may not be restored next time you use this application (%s).");
+                
+        } else {
+                fmt = _("An error occurred while loading or saving configuration information for %s. Some of your configuration settings may not work properly.");
+        }
+
+        mesg = g_strdup_printf(fmt, gnome_program_get_human_readable_name(gnome_program_get()));
+        
+        dialog = gnome_message_box_new(mesg,
+                                       GNOME_MESSAGE_BOX_ERROR,
+                                       GNOME_STOCK_BUTTON_OK,
+                                       NULL);
+
+        g_free(mesg);
+        
+        gtk_widget_show_all(dialog);
+
+
+        /* FIXME put this in a "Technical Details" optional part of the dialog
+           that can be opened up if users are interested */
+        iter = pending_errors;
+        while (iter != NULL) {
+                GError *error = iter->data;
+                iter->data = NULL;
+
+                fprintf(stderr, _("GConf error details: %s\n"), error->message);
+
+                g_error_free(error);
+                
+                iter = g_slist_next(iter);
+        }
+
+        g_slist_free(pending_errors);
+
+        pending_errors = NULL;
+        
+        g_object_unref(G_OBJECT(eid.client));
+        eid.client = NULL;
+
+        return FALSE;
+}
+
+static void
+gnome_default_gconf_client_error_handler (GConfClient                  *client,
+                                          GError                       *error)
+{
+        g_object_ref(G_OBJECT(client));
+        
+        if (eid.client) {
+                g_object_unref(G_OBJECT(eid.client));
+        }
+        
+        eid.client = client;
+        
+        pending_errors = g_slist_append(pending_errors, g_error_copy(error));
+
+        if (error_handler_idle == 0) {
+                error_handler_idle = gtk_idle_add(error_idle_func, NULL);
+        }
+}
+
+
diff --git a/libgnomeui/gnome-gconf-ui.h b/libgnomeui/gnome-gconf-ui.h
new file mode 100644
index 0000000..5dd6496
--- /dev/null
+++ b/libgnomeui/gnome-gconf-ui.h
@@ -0,0 +1,87 @@
+/*  -*- Mode: C; c-set-style: linux; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* GNOME GUI Library - gnome-gconf.h
+ * Copyright (C) 2000  Red Hat Inc.,
+ * All rights reserved.
+ *
+ * Author: Jonathan Blandford  <jrb redhat com>
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#ifndef GNOME_GCONF_H
+#define GNOME_GCONF_H
+
+#include <gconf/gconf-value.h>
+#include <gconf/gconf-client.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtkrange.h>
+#include <gtk/gtkspinbutton.h>
+#include <gtk/gtktogglebutton.h>
+#include <gtk/gtkradiobutton.h>
+#include "gnome-color-picker.h"
+
+#include <libgnome/gnome-program.h>
+#include <libgnome/libgnome-init.h>
+
+/* GTK Widgets */
+GConfValue *gnome_gconf_gtk_entry_get          (GtkEntry         *entry,
+						GConfValueType    type);
+void        gnome_gconf_gtk_entry_set          (GtkEntry         *entry,
+						GConfValue       *value);
+GConfValue *gnome_gconf_spin_button_get        (GtkSpinButton    *spin_button,
+						GConfValueType    type);
+void        gnome_gconf_spin_button_set        (GtkSpinButton   *spin_button,
+						GConfValue      *value);
+GConfValue *gnome_gconf_gtk_radio_button_get   (GtkRadioButton   *radio,
+						GConfValueType    type);
+void        gnome_gconf_gtk_radio_button_set   (GtkRadioButton   *radio,
+						GConfValue       *value);
+GConfValue *gnome_gconf_gtk_range_get          (GtkRange         *range,
+						GConfValueType    type);
+void        gnome_gconf_gtk_range_set          (GtkRange         *range,
+						GConfValue       *value);
+GConfValue *gnome_gconf_gtk_toggle_button_get  (GtkToggleButton  *toggle,
+						GConfValueType    type);
+void        gnome_gconf_gtk_toggle_button_set  (GtkToggleButton  *toggle,
+						GConfValue       *value);
+
+
+/* GNOME Widgets */
+GConfValue *gnome_gconf_gnome_color_picker_get (GnomeColorPicker *picker,
+						GConfValueType    type);
+void        gnome_gconf_gnome_color_picker_set (GnomeColorPicker *picker,
+						GConfValue       *value);
+/* Get keys relative to the gnome-libs internal per-app directory and the
+   application author per-app directory */
+gchar      *gnome_gconf_get_gnome_libs_settings_relative (const gchar *subkey);
+gchar      *gnome_gconf_get_app_settings_relative        (const gchar *subkey);
+
+/* GNOME GConf module; basically what this does is
+   create a global GConfClient for a GNOME application; it's used
+   by libgnomeui, and applications can either use it or create
+   their own. However note that signals will be emitted for
+   libgnomeui settings and errors! Also the module inits
+   GConf
+*/
+
+#define gnome_get_gconf_client() gnome_program_get_gconf_client (gnome_program_get ())
+
+#endif
+
+
+
diff --git a/libgnomeui/gnome-gconf.c b/libgnomeui/gnome-gconf.c
new file mode 100644
index 0000000..d541782
--- /dev/null
+++ b/libgnomeui/gnome-gconf.c
@@ -0,0 +1,577 @@
+/*  -*- Mode: C; c-set-style: linux; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* GNOME GUI Library - gnome-gconf.h
+ * Copyright (C) 2000  Red Hat Inc.,
+ * All rights reserved.
+ *
+ * Author: Jonathan Blandford  <jrb redhat com>
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+
+#include <stdlib.h>
+#include <liboaf/liboaf.h>
+
+#define GCONF_ENABLE_INTERNALS 1
+#include <gconf/gconf.h>
+extern struct poptOption gconf_options[];
+
+#include <libgnome/libgnome.h>
+#include "oafgnome.h"
+#include "gnome-gconf.h"
+#include "gnome-messagebox.h"
+#include "gnome-stock-ids.h"
+#include <gtk/gtkmain.h>
+
+
+GConfValue *
+gnome_gconf_gtk_entry_get (GtkEntry       *entry,
+			   GConfValueType  type)
+{
+	GConfValue *retval = NULL;
+	const char *text;
+	gint i;
+	gfloat f;
+
+	g_return_val_if_fail (entry != NULL, NULL);
+	g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
+	g_return_val_if_fail ((type == GCONF_VALUE_STRING) ||
+			      (type == GCONF_VALUE_INT) ||
+			      (type == GCONF_VALUE_FLOAT), NULL);
+
+	text = gtk_entry_get_text (entry);
+	retval = gconf_value_new (type);
+	switch (type) {
+	case GCONF_VALUE_STRING:
+		gconf_value_set_string (retval, text);
+		break;
+	case GCONF_VALUE_INT:
+		i = strtol (text, NULL, 0);
+		gconf_value_set_int (retval, i);
+		break;
+	case GCONF_VALUE_FLOAT:
+		f = strtod (text, NULL);
+		gconf_value_set_float (retval, f);
+		break;
+	default:
+		g_assert_not_reached ();
+	}
+
+	return retval;
+
+}
+
+void
+gnome_gconf_gtk_entry_set (GtkEntry       *entry,
+			   GConfValue     *value)
+{
+	gchar string[33];
+
+	g_return_if_fail (entry != NULL);
+	g_return_if_fail (GTK_IS_ENTRY (entry));
+	g_return_if_fail (value != NULL);
+	g_return_if_fail ((value->type == GCONF_VALUE_STRING) ||
+			      (value->type == GCONF_VALUE_INT) ||
+			      (value->type == GCONF_VALUE_FLOAT));
+
+	switch (value->type) {
+	case GCONF_VALUE_STRING:
+		gtk_entry_set_text (entry, gconf_value_get_string (value));
+		break;
+	case GCONF_VALUE_INT:
+		g_snprintf (string, 32, "%d", gconf_value_get_int (value));
+		gtk_entry_set_text (entry, string);
+		break;
+	case GCONF_VALUE_FLOAT:
+		g_snprintf (string, 32, "%f", gconf_value_get_float (value));
+		gtk_entry_set_text (entry, string);
+		break;
+	default:
+		g_assert_not_reached ();
+	}
+}
+
+GConfValue *
+gnome_gconf_spin_button_get (GtkSpinButton *spin_button,
+			     GConfValueType  type)
+{
+	GConfValue *retval = NULL;
+	gint i;
+	gfloat f;
+
+	g_return_val_if_fail (spin_button != NULL, NULL);
+	g_return_val_if_fail (GTK_IS_SPIN_BUTTON (spin_button), NULL);
+	g_return_val_if_fail ((type == GCONF_VALUE_INT) ||
+			      (type == GCONF_VALUE_FLOAT), NULL);
+
+	retval = gconf_value_new (type);
+	switch (type) {
+	case GCONF_VALUE_INT:
+		i = gtk_spin_button_get_value_as_int (spin_button);
+		gconf_value_set_int (retval, i);
+		break;
+	case GCONF_VALUE_FLOAT:
+		f = gtk_spin_button_get_value_as_float (spin_button);
+		gconf_value_set_float (retval, f);
+		break;
+	default:
+		break;
+	}
+
+	return retval;
+}
+
+void
+gnome_gconf_spin_button_set (GtkSpinButton *spin_button,
+			     GConfValue    *value)
+{
+	float f;
+
+	g_return_if_fail (spin_button != NULL);
+	g_return_if_fail (GTK_IS_SPIN_BUTTON (spin_button));
+	g_return_if_fail (value != NULL);
+	g_return_if_fail ((value->type == GCONF_VALUE_INT) ||
+			  (value->type == GCONF_VALUE_FLOAT));
+
+	switch (value->type) {
+	case GCONF_VALUE_INT:
+		f = gconf_value_get_int (value);
+		gtk_spin_button_set_value (spin_button, f);
+		break;
+	case GCONF_VALUE_FLOAT:
+		f = gconf_value_get_float (value);
+		gtk_spin_button_set_value (spin_button, f);
+		break;
+	default:
+		break;
+	}
+}
+
+GConfValue *
+gnome_gconf_gtk_radio_button_get (GtkRadioButton  *radio,
+				  GConfValueType   type)
+{
+	GConfValue *retval;
+	int i = 0;
+	GSList *group;
+	
+	g_return_val_if_fail (radio != NULL, NULL);
+	g_return_val_if_fail (GTK_IS_RADIO_BUTTON (radio), NULL);
+	g_return_val_if_fail (((type == GCONF_VALUE_BOOL) ||
+			       (type == GCONF_VALUE_INT)), NULL);
+
+	retval = gconf_value_new (type);
+	for (i = 0, group = radio->group; group != NULL; i++, group = group->next) {
+		if (GTK_TOGGLE_BUTTON (group->data)->active) {
+			if (type == GCONF_VALUE_BOOL) {
+				if (i > 1)
+					g_warning ("more then two radio buttons used with a boolean\n");
+				else
+					gconf_value_set_bool (retval, i);
+			} else {
+				gconf_value_set_int (retval, i);
+			}
+			break;
+		}
+	}
+	return retval;
+}
+
+void
+gnome_gconf_gtk_radio_button_set (GtkRadioButton  *radio,
+				  GConfValue      *value)
+{
+	gint i, j = 0;
+	GSList *list;
+
+	g_return_if_fail (radio != NULL);
+	g_return_if_fail (GTK_IS_RADIO_BUTTON (radio));
+	g_return_if_fail (value != NULL);
+	g_return_if_fail ((value->type == GCONF_VALUE_BOOL) ||
+			  (value->type == GCONF_VALUE_INT));
+
+	switch (value->type) {
+	case GCONF_VALUE_BOOL:
+		j = gconf_value_get_bool (value);
+		break;
+	case GCONF_VALUE_INT:
+		j = gconf_value_get_int (value);
+		break;
+	default:
+		g_assert_not_reached();
+	}
+
+	for (list = radio->group, i = 0 ; i != j && list != NULL; i ++, list = list->next)
+		;
+	if (list)
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (list->data), TRUE);
+}
+
+GConfValue *
+gnome_gconf_gtk_range_get (GtkRange       *range,
+			   GConfValueType  type)
+{
+	GtkAdjustment *adjustment;
+	GConfValue *retval;
+	int i;
+
+	g_return_val_if_fail (range != NULL, NULL);
+	g_return_val_if_fail (GTK_IS_RANGE (range), NULL);
+	g_return_val_if_fail ((type == GCONF_VALUE_FLOAT) ||
+			      (type == GCONF_VALUE_INT), NULL);
+
+	adjustment = gtk_range_get_adjustment (range);
+	retval = gconf_value_new (type);
+	switch (type) {
+	case GCONF_VALUE_INT:
+		i = adjustment->value;
+		gconf_value_set_int (retval, i);
+		break;
+	case GCONF_VALUE_FLOAT:
+		gconf_value_set_float (retval, adjustment->value);
+		break;
+	default:
+		break;
+	}
+	return retval;
+}
+
+void
+gnome_gconf_gtk_range_set (GtkRange       *range,
+			   GConfValue     *value)
+{
+	GtkAdjustment *adjustment;
+	gdouble f = 0.0;
+
+	g_return_if_fail (range != NULL);
+	g_return_if_fail (GTK_IS_RANGE (range));
+	g_return_if_fail ((value->type == GCONF_VALUE_FLOAT) ||
+			  (value->type == GCONF_VALUE_INT));
+
+	switch (value->type) {
+	case GCONF_VALUE_FLOAT:
+		f = gconf_value_get_float (value);
+		break;
+	case GCONF_VALUE_INT:
+		f = gconf_value_get_int (value);
+		break;
+	default:
+		g_assert_not_reached();
+	}
+	adjustment = gtk_range_get_adjustment (range);
+	gtk_adjustment_set_value (adjustment, f);
+}
+
+GConfValue *
+gnome_gconf_gtk_toggle_button_get (GtkToggleButton *toggle,
+				   GConfValueType   type)
+{
+	GConfValue *retval;
+
+	g_return_val_if_fail (toggle != NULL, NULL);
+	g_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (toggle), NULL);
+	g_return_val_if_fail (((type == GCONF_VALUE_BOOL)||
+			       (type == GCONF_VALUE_INT)), NULL);
+
+	retval = gconf_value_new (type);
+	switch (type) {
+	case GCONF_VALUE_BOOL:
+		gconf_value_set_bool (retval, toggle->active);
+		break;
+	case GCONF_VALUE_INT:
+		gconf_value_set_int (retval, toggle->active);
+		break;
+	default:
+		g_assert_not_reached ();
+	}
+	return retval;
+}
+
+void
+gnome_gconf_gtk_toggle_button_set (GtkToggleButton *toggle,
+				   GConfValue      *value)
+{
+	g_return_if_fail (toggle != NULL);
+	g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle));
+	g_return_if_fail (value != NULL);
+	g_return_if_fail ((value->type == GCONF_VALUE_BOOL)||
+			  (value->type == GCONF_VALUE_INT));
+
+	switch (value->type) {
+	case GCONF_VALUE_BOOL:
+		gtk_toggle_button_set_active (toggle, gconf_value_get_bool (value));
+		break;
+	case GCONF_VALUE_INT:
+		gtk_toggle_button_set_active (toggle, gconf_value_get_int (value));
+		break;
+	default:
+		g_assert_not_reached ();
+	}
+}
+
+GConfValue *
+gnome_gconf_gnome_color_picker_get (GnomeColorPicker *picker,
+				    GConfValueType    type)
+{
+	GConfValue *retval;
+	gushort r, g, b, a;
+	gchar color[18];
+
+	g_return_val_if_fail (picker != NULL, NULL);
+	g_return_val_if_fail (GNOME_IS_COLOR_PICKER (picker), NULL);
+	g_return_val_if_fail ((type == GCONF_VALUE_STRING), NULL);
+
+	retval = gconf_value_new (type);
+	switch (type) {
+	case GCONF_VALUE_STRING:
+		gnome_color_picker_get_i16 (picker, &r, &g, &b, &a);
+		g_snprintf (color, 18, "#%04X%04X%04X%04X", r, g, b, a);
+		gconf_value_set_string (retval, color);
+		break;
+	default:
+		g_assert_not_reached ();
+	}
+	return retval;
+}
+
+void
+gnome_gconf_gnome_color_picker_set (GnomeColorPicker *picker,
+				    GConfValue       *value)
+{
+	gushort r, g, b, a;
+	gchar *color;
+
+	g_return_if_fail (picker != NULL);
+	g_return_if_fail (GNOME_IS_COLOR_PICKER (picker));
+	g_return_if_fail (value != NULL);
+	g_return_if_fail (value->type == GCONF_VALUE_STRING);
+
+	color = g_strndup (gconf_value_get_string (value), 17);
+	a = strtol (color  + 13, (char **)NULL, 16);
+	*(color +13) = '\0';
+	b = strtol (color  + 9, (char **)NULL, 16);
+	*(color +9) = '\0';
+	g = strtol (color  + 5, (char **)NULL, 16);
+	*(color +5) = '\0';
+	r = strtol (color  + 1, (char **)NULL, 16);
+	gnome_color_picker_set_i16 (picker, r, g, b, a);
+	g_free (color);
+}
+
+gchar*
+gnome_gconf_get_gnome_libs_settings_relative (const gchar *subkey)
+{
+        gchar *dir;
+        gchar *key;
+
+        dir = g_strconcat("/apps/gnome-settings/",
+                          gnome_program_get_name(gnome_program_get()),
+                          NULL);
+
+        if (subkey && *subkey) {
+                key = gconf_concat_dir_and_key(dir, subkey);
+                g_free(dir);
+        } else {
+                /* subkey == "" */
+                key = dir;
+        }
+
+        return key;
+}
+
+gchar*
+gnome_gconf_get_app_settings_relative (const gchar *subkey)
+{
+        gchar *dir;
+        gchar *key;
+
+        dir = g_strconcat("/apps/",
+                          gnome_program_get_name(gnome_program_get()),
+                          NULL);
+
+        if (subkey && *subkey) {
+                key = gconf_concat_dir_and_key(dir, subkey);
+                g_free(dir);
+        } else {
+                /* subkey == "" */
+                key = dir;
+        }
+
+        return key;
+}
+
+/*
+ * Our global GConfClient, and module stuff
+ */
+static void gnome_default_gconf_client_error_handler (GConfClient                  *client,
+                                                      GError                       *error);
+
+
+static GConfClient* global_client = NULL;
+
+GConfClient*
+gnome_get_gconf_client (void)
+{
+        g_return_val_if_fail(global_client != NULL, NULL);
+        
+        return global_client;
+}
+
+static void
+gnome_gconf_pre_args_parse(GnomeProgram *app, GnomeModuleInfo *mod_info)
+{
+        gconf_preinit(app, (GnomeModuleInfo*)mod_info);
+
+        gconf_client_set_global_default_error_handler(gnome_default_gconf_client_error_handler);
+}
+
+static void
+gnome_gconf_post_args_parse(GnomeProgram *app, GnomeModuleInfo *mod_info)
+{
+        gchar *settings_dir;
+        
+        gconf_postinit(app, (GnomeModuleInfo*)mod_info);
+
+        global_client = gconf_client_get_default();
+
+        gconf_client_add_dir(global_client,
+                             "/desktop/gnome",
+                             GCONF_CLIENT_PRELOAD_NONE, NULL);
+
+        settings_dir = gnome_gconf_get_gnome_libs_settings_relative("");
+
+        gconf_client_add_dir(global_client,
+                             settings_dir,
+                             /* Possibly we should turn preload on for this */
+                             GCONF_CLIENT_PRELOAD_NONE,
+                             NULL);
+        g_free(settings_dir);
+}
+
+extern GnomeModuleInfo gtk_module_info;
+
+static GnomeModuleRequirement gnome_gconf_requirements[] = {
+        { "1.2.5", &gtk_module_info },
+        /* VERSION is also our version note - it's all libgnomeui */
+        { VERSION, &liboafgnome_module_info },
+        { NULL, NULL }
+};
+
+GnomeModuleInfo gnome_gconf_module_info = {
+        "gnome-gconf", VERSION, N_("GNOME GConf Support"),
+        gnome_gconf_requirements,
+        gnome_gconf_pre_args_parse, gnome_gconf_post_args_parse,
+        gconf_options
+};
+
+
+typedef struct {
+        GConfClient                  *client;
+} ErrorIdleData;
+
+static guint error_handler_idle = 0;
+static GSList *pending_errors = NULL;
+static ErrorIdleData eid = { NULL };
+
+static gint
+error_idle_func(gpointer data)
+{
+        GtkWidget *dialog;
+        GSList *iter;
+        gboolean have_overridden = FALSE;
+        gchar* mesg = NULL;
+        const gchar* fmt = NULL;
+        
+        error_handler_idle = 0;
+
+        g_return_val_if_fail(eid.client != NULL, FALSE);
+        g_return_val_if_fail(pending_errors != NULL, FALSE);
+        
+        iter = pending_errors;
+        while (iter != NULL) {
+                GError *error = iter->data;
+
+                if (g_error_matches (error, GCONF_ERROR, GCONF_ERROR_OVERRIDDEN))
+                        have_overridden = TRUE;
+                
+                iter = g_slist_next(iter);
+        }
+        
+        if (have_overridden) {
+                fmt = _("You attempted to change an aspect of your configuration that your system administrator or operating system vendor does not allow you to change. Some of the settings you have selected may not take effect, or may not be restored next time you use this application (%s).");
+                
+        } else {
+                fmt = _("An error occurred while loading or saving configuration information for %s. Some of your configuration settings may not work properly.");
+        }
+
+        mesg = g_strdup_printf(fmt, gnome_program_get_human_readable_name(gnome_program_get()));
+        
+        dialog = gnome_message_box_new(mesg,
+                                       GNOME_MESSAGE_BOX_ERROR,
+                                       GNOME_STOCK_BUTTON_OK,
+                                       NULL);
+
+        g_free(mesg);
+        
+        gtk_widget_show_all(dialog);
+
+
+        /* FIXME put this in a "Technical Details" optional part of the dialog
+           that can be opened up if users are interested */
+        iter = pending_errors;
+        while (iter != NULL) {
+                GError *error = iter->data;
+                iter->data = NULL;
+
+                fprintf(stderr, _("GConf error details: %s\n"), error->message);
+
+                g_error_free(error);
+                
+                iter = g_slist_next(iter);
+        }
+
+        g_slist_free(pending_errors);
+
+        pending_errors = NULL;
+        
+        g_object_unref(G_OBJECT(eid.client));
+        eid.client = NULL;
+
+        return FALSE;
+}
+
+static void
+gnome_default_gconf_client_error_handler (GConfClient                  *client,
+                                          GError                       *error)
+{
+        g_object_ref(G_OBJECT(client));
+        
+        if (eid.client) {
+                g_object_unref(G_OBJECT(eid.client));
+        }
+        
+        eid.client = client;
+        
+        pending_errors = g_slist_append(pending_errors, g_error_copy(error));
+
+        if (error_handler_idle == 0) {
+                error_handler_idle = gtk_idle_add(error_idle_func, NULL);
+        }
+}
+
+
diff --git a/libgnomeui/gnome-gconf.h b/libgnomeui/gnome-gconf.h
new file mode 100644
index 0000000..5dd6496
--- /dev/null
+++ b/libgnomeui/gnome-gconf.h
@@ -0,0 +1,87 @@
+/*  -*- Mode: C; c-set-style: linux; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* GNOME GUI Library - gnome-gconf.h
+ * Copyright (C) 2000  Red Hat Inc.,
+ * All rights reserved.
+ *
+ * Author: Jonathan Blandford  <jrb redhat com>
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#ifndef GNOME_GCONF_H
+#define GNOME_GCONF_H
+
+#include <gconf/gconf-value.h>
+#include <gconf/gconf-client.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtkrange.h>
+#include <gtk/gtkspinbutton.h>
+#include <gtk/gtktogglebutton.h>
+#include <gtk/gtkradiobutton.h>
+#include "gnome-color-picker.h"
+
+#include <libgnome/gnome-program.h>
+#include <libgnome/libgnome-init.h>
+
+/* GTK Widgets */
+GConfValue *gnome_gconf_gtk_entry_get          (GtkEntry         *entry,
+						GConfValueType    type);
+void        gnome_gconf_gtk_entry_set          (GtkEntry         *entry,
+						GConfValue       *value);
+GConfValue *gnome_gconf_spin_button_get        (GtkSpinButton    *spin_button,
+						GConfValueType    type);
+void        gnome_gconf_spin_button_set        (GtkSpinButton   *spin_button,
+						GConfValue      *value);
+GConfValue *gnome_gconf_gtk_radio_button_get   (GtkRadioButton   *radio,
+						GConfValueType    type);
+void        gnome_gconf_gtk_radio_button_set   (GtkRadioButton   *radio,
+						GConfValue       *value);
+GConfValue *gnome_gconf_gtk_range_get          (GtkRange         *range,
+						GConfValueType    type);
+void        gnome_gconf_gtk_range_set          (GtkRange         *range,
+						GConfValue       *value);
+GConfValue *gnome_gconf_gtk_toggle_button_get  (GtkToggleButton  *toggle,
+						GConfValueType    type);
+void        gnome_gconf_gtk_toggle_button_set  (GtkToggleButton  *toggle,
+						GConfValue       *value);
+
+
+/* GNOME Widgets */
+GConfValue *gnome_gconf_gnome_color_picker_get (GnomeColorPicker *picker,
+						GConfValueType    type);
+void        gnome_gconf_gnome_color_picker_set (GnomeColorPicker *picker,
+						GConfValue       *value);
+/* Get keys relative to the gnome-libs internal per-app directory and the
+   application author per-app directory */
+gchar      *gnome_gconf_get_gnome_libs_settings_relative (const gchar *subkey);
+gchar      *gnome_gconf_get_app_settings_relative        (const gchar *subkey);
+
+/* GNOME GConf module; basically what this does is
+   create a global GConfClient for a GNOME application; it's used
+   by libgnomeui, and applications can either use it or create
+   their own. However note that signals will be emitted for
+   libgnomeui settings and errors! Also the module inits
+   GConf
+*/
+
+#define gnome_get_gconf_client() gnome_program_get_gconf_client (gnome_program_get ())
+
+#endif
+
+
+
diff --git a/libgnomeui/gnome-helpsys.c b/libgnomeui/gnome-helpsys.c
new file mode 100644
index 0000000..b967a75
--- /dev/null
+++ b/libgnomeui/gnome-helpsys.c
@@ -0,0 +1,1433 @@
+/*
+ * Copyright (C) 2000 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+/* TODO:
+ * Turn GnomeHelpView into a widget with a window (cut & paste eventbox code) so that we can handle right-click on it
+ * to get the style menu
+ *
+ * Add sanity checking to all parameters of API functions
+ */
+
+#include "config.h"
+#include "gnome-macros.h"
+
+#include <glib.h>
+#include <ctype.h>
+
+#include <libgnome/gnome-url.h>
+#include <libgnome/gnome-util.h>
+#include <libgnome/gnome-config.h>
+#include <libgnome/gnome-i18n.h>
+#include "gnome-helpsys.h"
+#include "gnome-stock.h"
+#include "gnome-uidefs.h"
+#include "gnome-popup-menu.h"
+#include "wap-textfu.h"
+#include "gnome-cursors.h"
+#include <libgnome/gnome-program.h>
+#include <gdk/gdkx.h>
+
+#include "libgnomeuiP.h"
+
+#include <stdio.h>
+#include <string.h>
+
+struct _GnomeHelpViewPrivate {
+  GtkWidget *popup_menu;
+
+  GtkWidget *toplevel;
+  GtkWidget *toolbar, *content, *btn_help, *btn_style, *evbox;
+
+  GnomeURLDisplayContext *url_ctx;
+
+  GtkOrientation orientation;
+
+  GnomeHelpViewStylePriority style_priority;
+  GnomeHelpViewStylePriority app_style_priority;
+
+  GnomeHelpViewStyle style : 2;
+
+  GnomeHelpViewStyle app_style : 2; /* Used to properly handle object args for style & prio */ 
+};
+
+enum {
+  PROP_0 = 0,
+  PROP_APP_STYLE,
+  PROP_APP_STYLE_PRIORITY,
+  PROP_ORIENTATION,
+  PROP_TOPLEVEL
+};
+
+typedef enum {
+  URL_SAME_APP,
+  URL_GENERAL_HELPSYSTEM,
+  URL_WEB
+} HelpURLType;
+
+static void gnome_help_view_class_init (GnomeHelpViewClass *class);
+static void gnome_help_view_init (GnomeHelpView *help_view);
+static void gnome_help_view_destroy (GtkObject *obj);
+static void gnome_help_view_finalize (GObject *obj);
+static void gnome_help_view_get_property	(GObject *object,
+						 guint param_id,
+						 GValue *value,
+						 GParamSpec * pspec);
+static void gnome_help_view_set_property	(GObject *object,
+						 guint param_id,
+						 const GValue * value,
+						 GParamSpec * pspec);
+static void gnome_help_view_size_request  (GtkWidget      *widget,
+					   GtkRequisition *requisition);
+static void gnome_help_view_size_allocate (GtkWidget      *widget,
+					   GtkAllocation  *allocation);
+static void gnome_help_view_select_style(GtkWidget *btn, GnomeHelpView *help_view);
+static char *gnome_help_view_find_help_id(GnomeHelpView *help_view, const char *widget_id);
+static void gnome_help_view_show_url(GnomeHelpView *help_view, const char *url, HelpURLType type);
+static void gnome_help_view_set_style_popup(gpointer dummy, GnomeHelpView *help_view);
+static void gnome_help_view_set_style_embedded(gpointer dummy, GnomeHelpView *help_view);
+static void gnome_help_view_set_style_browser(gpointer dummy, GnomeHelpView *help_view);
+static gint gnome_help_view_process_event(GtkWidget *btn, GdkEvent *event, GnomeHelpView *help_view);
+
+static GnomeUIInfo popup_style_menu_items[] = {
+  GNOMEUIINFO_RADIOITEM(N_("_Popup"),
+			N_("Show help in temporary popup windows"),
+			gnome_help_view_set_style_popup, NULL),
+  GNOMEUIINFO_RADIOITEM(N_("_Embedded"),
+			N_("Show help inside the application window"),
+			gnome_help_view_set_style_embedded, NULL),
+  GNOMEUIINFO_RADIOITEM(N_("_Browser"),
+			N_("Show help in a help browser window"),
+			gnome_help_view_set_style_browser, NULL),
+  GNOMEUIINFO_END
+};
+
+static GnomeUIInfo popup_style_menu[] = {
+  GNOMEUIINFO_RADIOLIST(popup_style_menu_items),
+  GNOMEUIINFO_END
+};
+
+static GdkCursor *choose_cursor = NULL;
+
+/**
+ * gnome_href_get_type
+ *
+ * Returns the type assigned to the GNOME href widget.
+ **/
+/* The following defines the get_type */
+GNOME_CLASS_BOILERPLATE (GnomeHelpView, gnome_help_view,
+			 GtkBox, gtk_box)
+
+/* UNUSED
+static GdkAtom atom_explain_query = 0, atom_explain_request = 0, atom_explain_query_reply = 0;
+*/
+
+static void
+gnome_help_view_class_init (GnomeHelpViewClass *class)
+{
+	GtkObjectClass *object_class;
+	GObjectClass *gobject_class;
+	GtkWidgetClass *widget_class;
+
+	object_class = (GtkObjectClass *) class;
+	gobject_class = (GObjectClass *) class;
+	widget_class = (GtkWidgetClass *) class;
+
+	object_class->destroy = gnome_help_view_destroy;
+
+	gobject_class->finalize = gnome_help_view_finalize;
+	gobject_class->set_property = gnome_help_view_set_property;
+	gobject_class->get_property = gnome_help_view_get_property;
+
+	widget_class->size_request = gnome_help_view_size_request;
+	widget_class->size_allocate = gnome_help_view_size_allocate;
+
+	g_object_class_install_property (gobject_class,
+				      PROP_APP_STYLE,
+				      g_param_spec_enum ("app_style",
+							 _("App style"),
+							 _("The style of GnomeHelpView"),
+							 GTK_TYPE_ENUM,
+							 GNOME_HELP_BROWSER,
+							 (G_PARAM_READABLE |
+							  G_PARAM_WRITABLE)));
+
+	g_object_class_install_property (gobject_class,
+				      PROP_APP_STYLE_PRIORITY,
+				      g_param_spec_enum ("app_style_priority",
+							 _("App style priority"),
+							 _("The priority of style of GnomeHelpView"),
+							 GTK_TYPE_ENUM,
+							 G_PRIORITY_LOW,
+							 (G_PARAM_READABLE |
+							  G_PARAM_WRITABLE)));
+
+	g_object_class_install_property (gobject_class,
+				      PROP_ORIENTATION,
+				      g_param_spec_enum ("orientation",
+							 _("Orientation"),
+							 _("Orientation"),
+							 GTK_TYPE_ENUM,
+							 GTK_ORIENTATION_HORIZONTAL,
+							 (G_PARAM_READABLE |
+							  G_PARAM_WRITABLE)));
+
+	g_object_class_install_property (gobject_class,
+				      PROP_TOPLEVEL,
+				      g_param_spec_object ("toplevel",
+							   _("Toplevel"),
+							   _("The toplevel widget"),
+							   GTK_TYPE_WIDGET,
+							   (G_PARAM_READABLE |
+							    G_PARAM_WRITABLE)));
+}
+
+static void
+gnome_help_view_init (GnomeHelpView *help_view)
+{
+  help_view->_priv = g_new0(GnomeHelpViewPrivate, 1);
+
+  help_view->_priv->orientation = GTK_ORIENTATION_VERTICAL;
+  help_view->_priv->style = GNOME_HELP_BROWSER;
+  help_view->_priv->style_priority = G_PRIORITY_LOW;
+
+  help_view->_priv->toolbar = gtk_toolbar_new(GTK_ORIENTATION_VERTICAL, GTK_TOOLBAR_ICONS);
+  help_view->_priv->btn_help = gtk_toolbar_append_item(GTK_TOOLBAR(help_view->_priv->toolbar), _("Help"),
+						_("Show help for a specific region of the application"),
+						NULL,
+						gnome_stock_new_with_icon(GNOME_STOCK_PIXMAP_HELP),
+						GTK_SIGNAL_FUNC (gnome_help_view_select_help_cb),
+						(gpointer) help_view);
+  help_view->_priv->btn_style = gtk_toolbar_append_item(GTK_TOOLBAR(help_view->_priv->toolbar), _("Style"),
+						_("Change the way help is displayed"),
+						NULL,
+						gnome_stock_new_with_icon(GNOME_STOCK_PIXMAP_PREFERENCES),
+						GTK_SIGNAL_FUNC (gnome_help_view_select_style),
+						(gpointer) help_view);
+
+  help_view->_priv->evbox = gtk_event_box_new();
+  gtk_widget_add_events(help_view->_priv->evbox,
+			GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK|GDK_POINTER_MOTION_MASK|GDK_KEY_PRESS_MASK);
+
+  gtk_box_pack_start(GTK_BOX(help_view), help_view->_priv->toolbar, TRUE, TRUE, GNOME_PAD_SMALL);
+  gtk_box_pack_start(GTK_BOX(help_view), help_view->_priv->evbox, FALSE, FALSE, 0);
+
+  gtk_widget_show(help_view->_priv->toolbar);
+  gtk_widget_show(help_view->_priv->btn_style);
+  gtk_widget_show(help_view->_priv->btn_help);
+  gtk_widget_show(help_view->_priv->evbox);
+
+  gnome_help_view_set_style(help_view, help_view->_priv->app_style, help_view->_priv->app_style_priority);
+  gnome_help_view_set_orientation(help_view, GTK_ORIENTATION_HORIZONTAL);
+}
+
+static void
+gnome_help_view_destroy (GtkObject *obj)
+{
+	GnomeHelpView *help_view = (GnomeHelpView *)obj;
+
+	/* remember, destroy can be run multiple times! */
+
+	if(help_view->_priv->popup_menu != NULL) {
+		gtk_widget_destroy(help_view->_priv->popup_menu);
+		help_view->_priv->popup_menu = NULL;
+	}
+
+	if(help_view->_priv->toplevel != NULL) {
+		gtk_object_remove_data(GTK_OBJECT(help_view->_priv->toplevel),
+				       GNOME_APP_HELP_VIEW_NAME);
+		gtk_object_unref(GTK_OBJECT(help_view->_priv->toplevel));
+		help_view->_priv->toplevel = NULL;
+	}
+
+	GNOME_CALL_PARENT_HANDLER (GTK_OBJECT_CLASS, destroy, (obj));
+}
+
+static void
+gnome_help_view_finalize (GObject *obj)
+{
+	GnomeHelpView *help_view = (GnomeHelpView *)obj;
+
+	g_free(help_view->_priv);
+	help_view->_priv = NULL;
+
+	if (choose_cursor != NULL) {
+		gdk_cursor_destroy (choose_cursor);
+		choose_cursor = NULL;
+	}
+
+	GNOME_CALL_PARENT_HANDLER (G_OBJECT_CLASS, finalize, (obj));
+}
+
+static void
+gnome_help_view_set_property (GObject *object,
+			      guint param_id,
+			      const GValue * value,
+			      GParamSpec * pspec)
+{
+	static gboolean set_style = FALSE;
+	static gboolean set_priority = FALSE;
+	static GnomeHelpViewStyle style = GNOME_HELP_BROWSER;
+	static GnomeHelpViewStylePriority priority = G_PRIORITY_LOW;
+
+	GnomeHelpView *help_view = (GnomeHelpView *)object;
+
+	switch(param_id) {
+	case PROP_APP_STYLE:
+		style = g_value_get_enum (value);
+		set_style = TRUE;
+		break;
+	case PROP_APP_STYLE_PRIORITY:
+		priority = g_value_get_enum (value);
+		set_priority = TRUE;
+		break;
+	case PROP_ORIENTATION:
+		gnome_help_view_set_orientation (help_view, 
+						 g_value_get_enum (value));
+		break;
+	case PROP_TOPLEVEL:
+		gnome_help_view_set_toplevel (help_view,
+					      (GtkWidget *) g_value_get_object (value));
+		break;
+	}
+
+	/* A bad hack, style and priority need to be set at the same
+	 * time, this is ugly, should be somehow gotten rid of, by
+	 * redesigning the priority beast
+	 * -George */
+	if (set_style && set_priority) {
+		gnome_help_view_set_style(help_view, style, priority);
+		set_style = FALSE;
+		set_priority = FALSE;
+	}
+}
+
+static void
+gnome_help_view_get_property (GObject *object,
+			   guint param_id,
+			   GValue *value,
+			   GParamSpec * pspec)
+{
+	GnomeHelpView *help_view = GNOME_HELP_VIEW (object);
+
+	switch(param_id) {
+	case PROP_APP_STYLE:
+		g_value_set_enum (value, help_view->_priv->style);
+		break;
+	case PROP_APP_STYLE_PRIORITY:
+		g_value_set_enum (value, help_view->_priv->style_priority);
+		break;
+	case PROP_ORIENTATION:
+		g_value_set_enum (value, help_view->_priv->orientation);
+		break;
+	case PROP_TOPLEVEL:
+		/* Don't use G_OBJECT cast as it could be null */
+		g_value_set_object (value, (GObject *)help_view->_priv->toplevel);
+		break;
+	}
+}
+
+GtkWidget *
+gnome_help_view_new(GtkWidget *toplevel, GnomeHelpViewStyle app_style,
+		    GnomeHelpViewStylePriority app_style_priority)
+{
+  return (GtkWidget *)g_object_new (gnome_help_view_get_type(),
+				    "toplevel", toplevel,
+				    "app_style", app_style,
+				    "app_style_priority", app_style_priority,
+				    NULL);
+}
+
+void
+gnome_help_view_construct(GnomeHelpView *self,
+			  GtkWidget *toplevel,
+			  GnomeHelpViewStyle app_style,
+			  GnomeHelpViewStylePriority app_style_priority)
+{
+	g_return_if_fail (self != NULL);
+	g_return_if_fail (GNOME_IS_HELP_VIEW (self));
+
+	g_object_set (G_OBJECT (self),
+		      "toplevel", toplevel,
+		      "app_style", app_style,
+		      "app_style_priority", app_style_priority,
+		      NULL);
+}
+
+void
+gnome_help_view_set_toplevel(GnomeHelpView *help_view,
+			     GtkWidget *toplevel)
+{
+	g_return_if_fail(help_view != NULL);
+	g_return_if_fail(GNOME_IS_HELP_VIEW(help_view));
+	g_return_if_fail(toplevel != NULL);
+	g_return_if_fail(GTK_IS_WIDGET(toplevel));
+
+	if(help_view->_priv->toplevel) {
+		gtk_object_remove_data(GTK_OBJECT(help_view->_priv->toplevel),
+				       GNOME_APP_HELP_VIEW_NAME);
+		gtk_object_unref(GTK_OBJECT(help_view->_priv->toplevel));
+	}
+	help_view->_priv->toplevel = toplevel;
+	gtk_object_ref(GTK_OBJECT(help_view->_priv->toplevel));
+	gtk_object_set_data(GTK_OBJECT(toplevel), GNOME_APP_HELP_VIEW_NAME,
+			    help_view);
+}
+
+void
+gnome_help_view_set_visibility(GnomeHelpView *help_view, gboolean visible)
+{
+  if(visible)
+    {
+      gtk_widget_show(help_view->_priv->content);
+      gtk_widget_show(help_view->_priv->toolbar);
+    }
+  else
+    {
+      gtk_widget_hide(help_view->_priv->content);
+      gtk_widget_hide(help_view->_priv->toolbar);
+    }
+}
+
+GnomeHelpView *
+gnome_help_view_find(GtkWidget *awidget)
+{
+  GtkWidget *tmpw;
+  GnomeHelpView *help_view;
+
+  for(tmpw = gtk_widget_get_toplevel(awidget);
+      tmpw && GTK_IS_MENU(tmpw);
+      tmpw = GTK_MENU(tmpw)->toplevel)
+	  ;
+
+  if(tmpw)
+	  help_view = gtk_object_get_data(GTK_OBJECT(tmpw),
+					  GNOME_APP_HELP_VIEW_NAME);
+  else
+	  help_view = NULL;
+
+  if(GNOME_IS_HELP_VIEW(tmpw))
+	  return help_view;
+  else
+	  return NULL;
+}
+
+/* size_request & size_allocate are generalizations of the same
+   methods from gtk_hbox to make them work for both horizontal &
+   vertical orientations */
+static void
+gnome_help_view_size_request  (GtkWidget      *widget,
+			       GtkRequisition *requisition)
+{
+  GtkBox *box;
+  GtkBoxChild *child;
+  GList *children;
+  gint nvis_children;
+  gint length;
+  gint *primary_axis = NULL;
+  gint *secondary_axis = NULL;
+  gint *primary_axis_child = NULL;
+  gint *secondary_axis_child = NULL;
+  GnomeHelpView *help_view;
+  GtkRequisition child_requisition;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GNOME_IS_HELP_VIEW (widget));
+  g_return_if_fail (requisition != NULL);
+
+  box = (GtkBox *)widget;
+  help_view = (GnomeHelpView *)widget;
+  requisition->width = 0;
+  requisition->height = 0;
+  nvis_children = 0;
+
+  switch(help_view->_priv->orientation)
+    {
+    case GTK_ORIENTATION_HORIZONTAL:
+      primary_axis = &requisition->width;
+      primary_axis_child = &child_requisition.width;
+
+      secondary_axis = &requisition->height;
+      secondary_axis_child = &child_requisition.height;
+      break;
+    case GTK_ORIENTATION_VERTICAL:
+      primary_axis = &requisition->height;
+      primary_axis_child = &child_requisition.height;
+
+      secondary_axis = &requisition->width;
+      secondary_axis_child = &child_requisition.width;
+      break;
+    default:
+      /* if this is reached the axis pointers would be very wrong */
+      g_assert_not_reached();
+    }
+
+  children = box->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child->widget))
+	{
+	  gtk_widget_size_request (child->widget, &child_requisition);
+
+	  if (box->homogeneous)
+	    {
+	      length = *primary_axis_child + child->padding * 2;
+	      *primary_axis = MAX (*primary_axis, length);
+	    }
+	  else
+	    {
+	      *primary_axis += *primary_axis_child + child->padding * 2;
+	    }
+
+	  *secondary_axis = MAX(*secondary_axis, *secondary_axis_child);
+
+	  nvis_children += 1;
+	}
+    }
+
+  if (nvis_children > 0)
+    {
+      if (box->homogeneous)
+	*primary_axis *= nvis_children;
+      *primary_axis += (nvis_children - 1) * box->spacing;
+    }
+
+  requisition->width += GTK_CONTAINER (box)->border_width * 2;
+  requisition->height += GTK_CONTAINER (box)->border_width * 2;
+}
+
+static void
+gnome_help_view_size_allocate (GtkWidget      *widget,
+			       GtkAllocation  *allocation)
+{
+  GtkBox *box;
+  GtkBoxChild *child;
+  GList *children;
+  GtkAllocation child_allocation;
+  gint nvis_children;
+  gint nexpand_children;
+  gint child_dimension;
+  gint dimension;
+  gint extra;
+  gint position;
+  gint *primary_axis_child = NULL, *secondary_axis_child = NULL;
+  gint *primary_size_child = NULL, *secondary_size_child = NULL;
+  gint *primary_req_size_child = NULL, *secondary_req_size_child = NULL;
+  gint *primary_axis = NULL, *secondary_axis = NULL;
+  gint *primary_size = NULL, *secondary_size = NULL;
+  gint *primary_req_size = NULL, *secondary_req_size = NULL;
+  GtkRequisition child_requisition;
+  GnomeHelpView *help_view;
+  gboolean got_req = FALSE;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GNOME_IS_HELP_VIEW (widget));
+  g_return_if_fail (allocation != NULL);
+
+  box = (GtkBox *)widget;
+  help_view = (GnomeHelpView *)widget;
+
+  widget->allocation = *allocation;
+
+  switch(help_view->_priv->orientation)
+    {
+    case GTK_ORIENTATION_HORIZONTAL:
+      primary_axis = &allocation->x;
+      primary_axis_child = &child_allocation.x;
+      primary_size = &allocation->width;
+      primary_size_child = &child_allocation.width;
+      primary_req_size = &widget->requisition.width;
+      primary_req_size_child = &child_requisition.width;
+
+      secondary_axis = &allocation->y;
+      secondary_axis_child = &child_allocation.y;
+      secondary_size = &allocation->height;
+      secondary_size_child = &child_allocation.height;
+      secondary_req_size = &widget->requisition.height;
+      secondary_req_size_child = &child_requisition.height;
+      break;
+    case GTK_ORIENTATION_VERTICAL:
+      primary_axis = &allocation->y;
+      primary_axis_child = &child_allocation.y;
+      primary_size = &allocation->height;
+      primary_size_child = &child_allocation.height;
+      primary_req_size = &widget->requisition.height;
+      primary_req_size_child = &child_requisition.height;
+
+      secondary_axis = &allocation->x;
+      secondary_axis_child = &child_allocation.x;
+      secondary_size = &allocation->width;
+      secondary_size_child = &child_allocation.width;
+      secondary_req_size = &widget->requisition.width;
+      secondary_req_size_child = &child_requisition.width;
+      break;
+    default:
+      g_assert_not_reached();
+    }
+
+  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)
+	{
+	  dimension = (*primary_size -
+		   GTK_CONTAINER (box)->border_width * 2 -
+		   (nvis_children - 1) * box->spacing);
+	  extra = dimension / nvis_children;
+	}
+      else if (nexpand_children > 0)
+	{
+	  dimension = (gint) *primary_size - (gint) *primary_req_size;
+	  extra = dimension / nexpand_children;
+	}
+      else
+	{
+	  dimension = 0;
+	  extra = 0;
+	}
+
+      position = *primary_axis + GTK_CONTAINER (box)->border_width;
+      *secondary_axis_child = *secondary_axis + GTK_CONTAINER (box)->border_width;
+      *secondary_size_child = MAX (1, (gint) *secondary_size - (gint) GTK_CONTAINER (box)->border_width * 2);
+
+      children = box->children;
+      while (children)
+	{
+	  child = children->data;
+	  children = children->next;
+
+	  got_req = 0;
+
+	  if ((child->pack == GTK_PACK_START) && GTK_WIDGET_VISIBLE (child->widget))
+	    {
+	      if (box->homogeneous)
+		{
+		  if (nvis_children == 1)
+		    child_dimension = dimension;
+		  else
+		    child_dimension = extra;
+
+		  nvis_children -= 1;
+		  dimension -= extra;
+		}
+	      else
+		{
+		  got_req = TRUE;
+		  gtk_widget_get_child_requisition (child->widget, &child_requisition);
+
+		  child_dimension = *primary_req_size_child + child->padding * 2;
+
+		  if (child->expand)
+		    {
+		      if (nexpand_children == 1)
+			child_dimension += dimension;
+		      else
+			child_dimension += extra;
+
+		      nexpand_children -= 1;
+		      dimension -= extra;
+		    }
+		}
+
+	      if (child->fill)
+		{
+		  *primary_size_child = MAX (1, (gint) child_dimension - (gint) child->padding * 2);
+		  *primary_axis_child = position + child->padding;
+		}
+	      else
+		{
+		  if(!got_req)
+		    gtk_widget_get_child_requisition (child->widget, &child_requisition);
+		  *primary_size_child = *primary_req_size_child;
+		  *primary_axis_child = position + (child_dimension - *primary_size_child) / 2;
+		}
+
+	      gtk_widget_size_allocate (child->widget, &child_allocation);
+
+	      position += child_dimension + box->spacing;
+	    }
+	}
+
+      position = *primary_axis + *primary_size - 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))
+	    {
+	      gtk_widget_get_child_requisition (child->widget, &child_requisition);
+
+              if (box->homogeneous)
+                {
+                  if (nvis_children == 1)
+                    child_dimension = dimension;
+                  else
+                    child_dimension = extra;
+
+                  nvis_children -= 1;
+                  dimension -= extra;
+                }
+              else
+                {
+		  child_dimension = *primary_req_size_child + child->padding * 2;
+
+                  if (child->expand)
+                    {
+                      if (nexpand_children == 1)
+                        child_dimension += dimension;
+                      else
+                        child_dimension += extra;
+
+                      nexpand_children -= 1;
+                      dimension -= extra;
+                    }
+                }
+
+              if (child->fill)
+                {
+                  *primary_size_child = MAX (1, (gint)child_dimension - (gint)child->padding * 2);
+                  *primary_axis_child = position + child->padding - child_dimension;
+                }
+              else
+                {
+		  *primary_size_child = *primary_req_size_child;
+                  *primary_axis_child = position + (child_dimension - *primary_size_child) / 2 - child_dimension;
+                }
+
+              gtk_widget_size_allocate (child->widget, &child_allocation);
+
+              position -= (child_dimension + box->spacing);
+	    }
+	}
+    }
+}
+
+static void
+gnome_help_view_update_style(GnomeHelpView *help_view)
+{
+  if(help_view->_priv->style == GNOME_HELP_EMBEDDED)
+    {
+      if(help_view->_priv->content) /* Popup help */
+	gtk_widget_destroy(help_view->_priv->content->parent);
+
+      help_view->_priv->content = wap_textfu_new();
+      gtk_box_pack_start(GTK_BOX(help_view), help_view->_priv->content, TRUE, TRUE, GNOME_PAD_SMALL);
+      gtk_widget_show(help_view->_priv->content);
+    }
+  else
+    {
+      if(help_view->_priv->content)
+	{
+	  gtk_container_remove(GTK_CONTAINER(help_view), help_view->_priv->content);
+	  help_view->_priv->content = NULL;
+	}
+    }
+}
+
+static void
+gnome_help_view_set_style_popup(gpointer dummy, GnomeHelpView *help_view)
+{
+  gnome_help_view_set_style(help_view, GNOME_HELP_POPUP, G_PRIORITY_HIGH);
+}
+
+static void
+gnome_help_view_set_style_embedded(gpointer dummy, GnomeHelpView *help_view)
+{
+  gnome_help_view_set_style(help_view, GNOME_HELP_EMBEDDED, G_PRIORITY_HIGH);
+}
+
+static void
+gnome_help_view_set_style_browser(gpointer dummy, GnomeHelpView *help_view)
+{
+  gnome_help_view_set_style(help_view, GNOME_HELP_BROWSER, G_PRIORITY_HIGH);
+}
+
+void
+gnome_help_view_set_style(GnomeHelpView *help_view,
+			  GnomeHelpViewStyle style,
+			  GnomeHelpViewStylePriority style_priority)
+{
+  help_view->_priv->app_style = style;
+  help_view->_priv->app_style_priority = style_priority;
+
+  if(style_priority <= help_view->_priv->style_priority)
+    {
+      GnomeHelpViewStyle old_style = help_view->_priv->style;
+
+      help_view->_priv->style = style;
+      help_view->_priv->style_priority = style_priority;
+
+      if(old_style != style)
+	gnome_help_view_update_style(help_view);
+    }
+
+  gnome_help_view_set_orientation(help_view, help_view->_priv->orientation);
+}
+
+static void
+gtk_widget_destroy_2(GtkWidget *x, GnomeHelpView *help_view)
+{
+  help_view->_priv->content = NULL;
+}
+
+static void G_GNUC_UNUSED
+gnome_help_view_popup_activate_uri(WapTextFu *tf, const char *uri, GnomeHelpView *help_view)
+{
+  gnome_help_view_show_url(help_view, uri, URL_GENERAL_HELPSYSTEM);
+}
+
+static gint
+do_popup_destroy(GtkWidget *win, GdkEvent *event)
+{
+  gtk_widget_destroy(win);
+  return TRUE;
+}
+
+static void
+gnome_help_view_popup(GnomeHelpView *help_view, const char *file_path)
+{
+  WapTextFu *tf;
+  GtkWidget *win;
+
+  if(!help_view->_priv->content)
+    {
+      win = gtk_window_new(GTK_WINDOW_POPUP);
+      tf = WAP_TEXTFU(wap_textfu_new());
+      wap_textfu_load_file(tf, file_path);
+
+      gtk_signal_connect_while_alive(GTK_OBJECT(win), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroy_2), help_view, GTK_OBJECT(help_view));
+      gtk_signal_connect(GTK_OBJECT(help_view), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroy_2), win);
+
+/*        gtk_signal_connect(GTK_OBJECT(tf), "activate_uri", GTK_SIGNAL_FUNC(gnome_help_view_popup_activate_uri), help_view); */
+
+      gtk_container_add(GTK_CONTAINER(win), GTK_WIDGET(tf));
+      gtk_widget_show_all(win);
+
+      gtk_signal_connect_after(GTK_OBJECT(win), "button_release_event", GTK_SIGNAL_FUNC(do_popup_destroy), NULL);
+    }
+  else
+    wap_textfu_load_file(WAP_TEXTFU(help_view->_priv->content), file_path);
+}
+
+void
+gnome_help_view_show_help(GnomeHelpView *help_view, const char *help_path, const char *help_type)
+{
+  char *file_type, *file_path;
+  GnomeHelpViewStyle style;
+
+  g_message("show_help: %s, %s", help_path, help_type);
+
+  style = help_view->_priv->style;
+  if(!help_type || strcmp(help_type, "popup"))
+    style = GNOME_HELP_BROWSER;
+
+  switch(style)
+    {
+    case GNOME_HELP_POPUP:
+    case GNOME_HELP_EMBEDDED:
+      file_type = "textfu";
+      break;
+    default:
+      file_type = "html";
+      break;
+    }
+  
+  file_path = gnome_help_path_resolve(help_path, file_type);
+
+  if(!file_path && !strcmp(file_type, "textfu"))
+    {
+      /* Fall back to browser if we can't find HTML */
+      file_path = gnome_help_path_resolve(help_path, "html");
+      style = GNOME_HELP_BROWSER;
+    }
+
+  if(!file_path)
+    return;
+
+  switch(style)
+    {
+    case GNOME_HELP_EMBEDDED:
+      wap_textfu_load_file(WAP_TEXTFU(help_view->_priv->content), file_path);
+      break;
+    case GNOME_HELP_POPUP:
+      gnome_help_view_popup(help_view, file_path);
+      break;
+    case GNOME_HELP_BROWSER:
+      gnome_help_view_show_url(help_view, file_path, URL_GENERAL_HELPSYSTEM);
+      break;
+    }
+
+  g_free(file_path);
+}
+
+void
+gnome_help_view_show_help_for(GnomeHelpView *help_view, GtkWidget *widget)
+{
+  GtkWidget *cur;
+  char *help_path = NULL;
+
+  for(cur = widget; cur && !help_path; cur = cur->parent)
+    {
+      if(cur->name) {
+	g_print ("widget: %s\n", cur->name);
+	help_path = gnome_help_view_find_help_id(help_view, cur->name);
+      }
+    }
+
+  if(help_path)
+    gnome_help_view_show_help(help_view, help_path, "popup");
+  else
+    {
+      GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(gtk_widget_get_toplevel(widget)),
+						 GTK_DIALOG_DESTROY_WITH_PARENT,
+						 GTK_MESSAGE_INFO,
+						 GTK_BUTTONS_OK,
+						 _("No help is available for the selected "
+						   "portion of the application."));
+      gtk_dialog_run(GTK_DIALOG(dialog));
+    }
+}
+
+void
+gnome_help_view_set_orientation(GnomeHelpView *help_view, GtkOrientation orientation)
+{
+  help_view->_priv->orientation = orientation;
+
+  switch(orientation)
+    {
+    case GTK_ORIENTATION_VERTICAL:
+      if(help_view->_priv->style == GNOME_HELP_EMBEDDED)
+	gtk_toolbar_set_orientation(GTK_TOOLBAR(help_view->_priv->toolbar), GTK_ORIENTATION_HORIZONTAL);
+      else
+	gtk_toolbar_set_orientation(GTK_TOOLBAR(help_view->_priv->toolbar), GTK_ORIENTATION_VERTICAL);
+      break;
+    case GTK_ORIENTATION_HORIZONTAL:
+      if(help_view->_priv->style == GNOME_HELP_EMBEDDED)
+	gtk_toolbar_set_orientation(GTK_TOOLBAR(help_view->_priv->toolbar), GTK_ORIENTATION_VERTICAL);
+      else
+	gtk_toolbar_set_orientation(GTK_TOOLBAR(help_view->_priv->toolbar), GTK_ORIENTATION_HORIZONTAL);
+      break;
+    }
+}
+
+/* The wonderful what-is-this protocol:
+   Source:
+     _EXPLAIN_QUERY - ask if help is supported
+     _EXPLAIN_REQUEST - user has requested for an explanation
+
+   Target:
+     _EXPLAIN_QUERY_REPLY - affirm that help is supported
+ */
+typedef struct {
+  GnomeHelpView *help_view;
+
+  Window cur_toplevel;
+  gboolean sent_query : 1, got_reply : 1;
+} SourceState;
+
+#if 0
+static GdkFilterReturn
+gnome_help_view_process_event(GdkXEvent *xevent, GdkEvent *event, GnomeHelpView *help_view)
+{
+  GdkFilterReturn retval = GDK_FILTER_CONTINUE;
+  XEvent *xev = (XEvent *)xevent;
+
+  switch(xev->type)
+    {
+    case ClientMessage:
+      if(!atom_explain_query_reply)
+	atom_explain_query_reply = gdk_atom_intern("_EXPLAIN_QUERY_REPLY", FALSE);
+      retval = GDK_FILTER_REMOVE;
+      break;
+    case MotionNotify:
+      retval = GDK_FILTER_REMOVE;
+      break;
+    case ButtonRelease:
+      retval = GDK_FILTER_REMOVE;
+      break;
+    default:
+      break;
+    }
+
+  return retval;
+}
+#else
+static gint
+gnome_help_view_process_event(GtkWidget *evbox, GdkEvent *event, GnomeHelpView *help_view)
+{
+  GdkEventButton *evb;
+  GtkWidget *chosen_widget;
+
+  if(event->type != GDK_BUTTON_RELEASE)
+    return TRUE;
+  
+  evb = (GdkEventButton *)event;
+  gtk_signal_disconnect_by_func(GTK_OBJECT(help_view->_priv->evbox), GTK_SIGNAL_FUNC(gnome_help_view_process_event), help_view);
+  gtk_signal_emit_stop_by_name(GTK_OBJECT(evbox), "event");
+  gtk_grab_remove(help_view->_priv->evbox);
+/*    gdk_pointer_ungrab(evb->time); */
+  gdk_window_set_cursor (help_view->_priv->toplevel->window, NULL);
+  gdk_flush();
+
+  if(evb->window)
+    {
+      gdk_window_get_user_data(evb->window, (gpointer *)&chosen_widget);
+
+      if(help_view->_priv->btn_help && (chosen_widget == help_view->_priv->btn_help))
+	/* do nothing - they canceled out of it */;
+      else if(chosen_widget)
+	gnome_help_view_show_help_for(help_view, chosen_widget);
+      else
+	{
+	  GtkWidget *dialog;
+
+	  dialog = gtk_message_dialog_new(GTK_WINDOW(gtk_widget_get_toplevel(help_view->_priv->btn_help)),
+					  GTK_DIALOG_DESTROY_WITH_PARENT,
+					  GTK_MESSAGE_INFO,
+					  GTK_BUTTONS_OK,
+					  _("No help is available for the selected "
+					    "portion of the application."));
+	  gtk_dialog_run(GTK_DIALOG(dialog));
+	}
+    }
+
+  return TRUE;
+#endif
+}
+
+void
+gnome_help_view_select_help_menu_cb(GtkWidget *widget)
+{
+  GnomeHelpView *hv = gnome_help_view_find(widget);
+
+  if(!hv)
+    {
+      g_warning("Can't find help view for this widget");
+      return;
+    }
+
+  gnome_help_view_select_help_cb(widget, hv);
+}
+
+void
+gnome_help_view_select_help_cb(GtkWidget *ignored, GnomeHelpView *help_view)
+{
+  g_return_if_fail(help_view->_priv->evbox->window != NULL);
+
+#if 0
+  SourceState *ss;
+
+  ss = g_new0(SourceState, 1);
+  ss->help_view = help_view;
+  ss->cur_toplevel = None;
+
+  gdk_window_add_filter(help_view->_priv->evbox->window, gnome_help_view_process_event, ss);
+#else
+
+  gtk_signal_connect(GTK_OBJECT(help_view->_priv->evbox), "event", 
+		     GTK_SIGNAL_FUNC(gnome_help_view_process_event), 
+		     help_view);
+
+#endif
+
+  if(!choose_cursor)
+    choose_cursor = gnome_stock_cursor_new(GNOME_STOCK_CURSOR_WHATISIT);
+
+  gtk_grab_add(help_view->_priv->evbox);
+  gdk_window_set_cursor (help_view->_priv->toplevel->window, 
+			 choose_cursor);
+
+#if 0
+  gdk_pointer_grab(help_view->_priv->evbox->window, TRUE, 
+  		   GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK|GDK_KEY_PRESS_MASK|GDK_POINTER_MOTION_MASK, 
+  		   NULL, choose_cursor, GDK_CURRENT_TIME); 
+#endif
+}
+
+#if 0
+/*UNUSED*/
+static void
+popup_set_selection (GnomeHelpView *help_view)
+{
+  int n;
+
+  switch(help_view->_priv->style)
+    {
+    case GNOME_HELP_POPUP:
+      n = 0;
+      break;
+    case GNOME_HELP_EMBEDDED:
+      n = 1;
+      break;
+    case GNOME_HELP_BROWSER:
+      n = 2;
+      break;
+    default:
+      n = -1;
+    }
+
+  if(n < 0)
+    return;
+
+  gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(popup_style_menu_items[n].widget), TRUE);
+}
+#endif
+
+static void
+gnome_help_view_select_style(GtkWidget *btn, GnomeHelpView *help_view)
+{
+  if( ! help_view->_priv->popup_menu)
+	  help_view->_priv->popup_menu =gnome_popup_menu_new(popup_style_menu);
+
+
+  gnome_popup_menu_do_popup(help_view->_priv->popup_menu,
+			    NULL, NULL, NULL, help_view, btn);
+}
+
+static char *
+gnome_help_view_find_help_id(GnomeHelpView *help_view, const char *widget_id)
+{
+  char *filename, buf[512];
+  FILE *fh = NULL;
+  char *retval = NULL;
+  
+  g_snprintf(buf, sizeof(buf),
+	     "help/%s/widget-help-map.txt",
+	     gnome_program_get_name(gnome_program_get()));
+  filename = gnome_program_locate_file (gnome_program_get (),
+					GNOME_FILE_DOMAIN_DATADIR,
+					buf, TRUE, NULL);
+
+  if(filename == NULL) {
+    /* Search the current directory as well */
+    if (g_file_test ("widget-help-map.txt", G_FILE_TEST_EXISTS))
+      filename = g_strdup ("widget-help-map.txt");
+    else
+      return NULL;
+  }
+  
+  fh = fopen(filename, "r");
+  g_free(filename);
+  
+  if(!fh)
+    return NULL;
+  
+  while(!retval && fgets(buf, sizeof(buf), fh))
+    {
+      char *ctmp;
+      
+      g_strstrip(buf);
+      if(buf[0] == '#' || buf[0] == '\0')
+	continue;
+      
+      ctmp = strchr(buf, '=');
+      if(!ctmp)
+	continue;
+      *ctmp = '\0';
+      
+      if(strcmp(buf, widget_id))
+	continue;
+      
+      retval = g_strdup(ctmp + 1);
+    }
+  
+  fclose(fh);
+  return retval;
+}
+
+static void
+gnome_help_view_show_url(GnomeHelpView *help_view, const char *url, HelpURLType type)
+{
+  char *url_type = NULL;
+  GError *error = NULL;
+
+  switch(type)
+    {
+    case URL_SAME_APP:
+    case URL_GENERAL_HELPSYSTEM:
+      url_type = "help";
+      break;
+    case URL_WEB:
+      url_type = NULL;
+      break;
+    }
+
+  help_view->_priv->url_ctx =
+	  gnome_url_show_full(help_view->_priv->url_ctx, url, url_type,
+			      GNOME_URL_DISPLAY_NEWWIN |
+			      GNOME_URL_DISPLAY_CLOSE_ATEXIT,
+			      &error);
+  if(error != NULL) {
+  /*FIXME: properly handle the error!*/
+	  g_warning (_("Cought GnomeURL error: %s"), error->message);
+	  g_clear_error (&error);
+  }
+}
+
+void
+gnome_help_view_display (GnomeHelpView *help_view, const char *help_path)
+{
+  char *url;
+
+  url = gnome_help_path_resolve(help_path, "html");
+
+  if(url)
+    {
+      if(help_view)
+	gnome_help_view_show_url(help_view, url, URL_GENERAL_HELPSYSTEM);
+      else
+	gnome_url_show(url);
+        /* FIXME: Handle errors */
+
+      g_free(url);
+    }
+}
+
+void
+gnome_help_view_display_callback (GtkWidget *widget, const char *help_path)
+{
+  GnomeHelpView *help_view;
+
+  help_view = gnome_help_view_find(widget);
+
+  gnome_help_view_display(help_view, help_path);
+}
+
+/**
+ * gnome_help_path_resolve:
+ * @path: A help path (of the form appname/chaptername/sectionname
+ * @file_type: The type of the file to be found, normally "html"
+ *
+ * Turns a "help path" into a full URL.
+ *
+ * Returns: a newly allocated string with the URL
+ */
+char *
+gnome_help_path_resolve(const char *path, const char *file_type)
+{
+  const GList *language_list;
+  char fnbuf[PATH_MAX], tmppath[PATH_MAX];
+  char *appname, *filepath, *sectpath;
+  char *res;
+  char *ctmp;
+
+  g_return_val_if_fail(path, NULL);
+  if(!file_type)
+    file_type = "html";
+
+  strcpy(tmppath, path);
+  appname = tmppath;
+
+  filepath = strchr(tmppath, '/');
+
+  if(filepath)
+    {
+      *filepath = '\0';
+      filepath++;
+      sectpath = strchr(filepath, '/');
+      if(sectpath)
+	{
+	  *sectpath = '\0';
+	  sectpath++;
+	}
+    }
+  else
+    {
+      sectpath = NULL;
+      filepath = appname;
+    }
+
+  for(language_list = gnome_i18n_get_language_list (NULL), res = NULL; !res && language_list;
+      language_list = language_list->next)
+    {
+      const char *lang;
+		
+      lang = language_list->data;
+		
+      g_snprintf(fnbuf, sizeof(fnbuf), "%s/%s/%s.%s", appname, lang, filepath, file_type);
+      res = gnome_program_locate_file (gnome_program_get (),
+				       GNOME_FILE_DOMAIN_HELP,
+				       fnbuf, TRUE, NULL);
+    }
+
+  if(res)
+    {
+      ctmp = g_strdup_printf("file:///%s%s%s", res, sectpath?"#":"", sectpath?sectpath:"");
+      g_free(res);
+      res = ctmp;
+    }
+	
+  return res;
+}
+
+/**
+ * gnome_help_app_topics:
+ * @app_id: The application's ID string
+ *
+ * Returns: A newly allocated GSList of newly allocate strings.
+ * The strings are in pairs, topic description then help path.
+ */
+GSList *
+gnome_help_app_topics(const char *app_id)
+{
+  const GList *language_list;
+  GSList *retval;
+  char *topicfn;
+  char fnbuf[PATH_MAX], aline[LINE_MAX];
+  FILE *fh;
+
+  for(language_list = gnome_i18n_get_language_list (NULL), topicfn = NULL; !topicfn && language_list;
+      language_list = language_list->next)
+    {
+      const char *lang;
+		
+      lang = language_list->data;
+		
+      g_snprintf(fnbuf, sizeof(fnbuf), "%s/%s/topic.list", app_id, lang);
+      topicfn = gnome_program_locate_file (gnome_program_get (),
+					   GNOME_FILE_DOMAIN_HELP,
+					   fnbuf, TRUE, NULL);
+
+/*        language_list = language_list->next;  */
+    }
+
+  if(!topicfn)
+    return NULL;
+
+  fh = fopen(topicfn, "r");
+  g_free(topicfn);
+  if(!fh)
+    return NULL;
+
+  retval = NULL;
+  while(fgets(aline, sizeof(aline), fh))
+    {
+      char *path_part, *name_part, *ctmp;
+
+      g_strstrip(aline);
+
+      if(aline[0] == '\0' || aline[0] == '#')
+	continue;
+
+      for(ctmp = aline; *ctmp && !isspace(*ctmp); ctmp++) /**/;
+      if(*ctmp == '\0')
+	continue;
+
+      *ctmp = '\0'; ctmp++;
+      path_part = aline;
+      while(*ctmp && isspace(*ctmp)) ctmp++;
+      if(*ctmp == '\0')
+	continue;
+
+      name_part = ctmp;
+
+      g_snprintf(fnbuf, sizeof(fnbuf), "%s/%s", app_id, path_part);
+      retval = g_slist_append(retval, g_strdup(name_part));
+      retval = g_slist_append(retval, g_strdup(fnbuf));
+    }
+
+  return retval;
+}
+
+/**
+ * gnome_widget_set_name:
+ * @widget: A widget
+ * @name: A name
+ *
+ * Sets the widget's name and returns the widget.
+ */
+GtkWidget *
+gnome_widget_set_name(GtkWidget *widget, const char *name)
+{
+	g_return_val_if_fail(widget != NULL, NULL);
+	g_return_val_if_fail(GTK_IS_WIDGET(widget), NULL);
+
+	gtk_widget_set_name(widget, name);
+
+	return widget;
+}
+
+/*
+ * Tooltips
+ */
+
+static GtkTooltips *tooltips = NULL;
+
+/**
+ * gnome_widget_set_tooltip:
+ * @widget: A widget
+ * @tiptext: The text to be placed in the tooltip
+ *
+ * Description:  Sets a tooltip for a widget
+ */
+void
+gnome_widget_set_tooltip (GtkWidget *widget, const char *tiptext)
+{
+	g_return_if_fail(widget != NULL);
+	g_return_if_fail(GTK_IS_WIDGET(widget));
+
+	if( ! tooltips)
+		tooltips = gtk_tooltips_new();
+
+	gtk_tooltips_set_tip(tooltips, widget, tiptext, NULL);
+}
+
+/**
+ * gnome_widget_get_tooltips:
+ *
+ * Description:  Gets the tooltips object so that you can
+ * manipulate tooltips that were set with #gnome_widget_set_tooltip
+ * 
+ * Returns:  a #GtkTooltips object
+ */
+GtkTooltips *
+gnome_widget_get_tooltips (void)
+{
+	if( ! tooltips)
+		tooltips = gtk_tooltips_new();
+
+	return tooltips;
+}
diff --git a/libgnomeui/gnome-helpsys.h b/libgnomeui/gnome-helpsys.h
new file mode 100644
index 0000000..0d3c804
--- /dev/null
+++ b/libgnomeui/gnome-helpsys.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2000 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#ifndef GNOME_HELPSYS_H
+#define GNOME_HELPSYS_H 1
+
+
+#include <libgnome/gnome-url.h>
+
+#include <gtk/gtk.h>
+#include <libgnomeui/gnome-dock-item.h>
+
+G_BEGIN_DECLS
+
+#define GNOME_TYPE_HELP_VIEW            (gnome_help_view_get_type ())
+#define GNOME_HELP_VIEW(obj)            (GTK_CHECK_CAST((obj), GNOME_TYPE_HELP_VIEW, GnomeHelpView))
+#define GNOME_HELP_VIEW_CLASS(klass)    (GTK_CHECK_CLASS_CAST((klass), GNOME_TYPE_HELP_VIEW, GnomeHelpViewClass))
+#define GNOME_IS_HELP_VIEW(obj)         (GTK_CHECK_TYPE((obj), GNOME_TYPE_HELP_VIEW))
+#define GNOME_IS_HELP_VIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_HELP_VIEW))
+#define GNOME_HELP_VIEW_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_HELP_VIEW, GnomeHelpViewClass))
+
+typedef enum {
+	GNOME_HELP_POPUP,
+	GNOME_HELP_EMBEDDED,
+	GNOME_HELP_BROWSER
+} GnomeHelpViewStyle;
+
+/*FIXME: hack warning, G_PRIOTIY is something completely different
+ * makeupourown enum */
+typedef int GnomeHelpViewStylePriority; /* Use the G_PRIORITY_* system */
+
+typedef struct _GnomeHelpView        GnomeHelpView;
+typedef struct _GnomeHelpViewPrivate GnomeHelpViewPrivate;
+typedef struct _GnomeHelpViewClass   GnomeHelpViewClass;
+
+struct _GnomeHelpView {
+  GtkBox parent_object;
+  
+  /*< private >*/
+  GnomeHelpViewPrivate *_priv;
+};
+
+struct _GnomeHelpViewClass {
+  GtkBoxClass parent_class;
+};
+
+GtkType		gnome_help_view_get_type	(void) G_GNUC_CONST;
+
+GtkWidget *	gnome_help_view_new		(GtkWidget *toplevel,
+						 GnomeHelpViewStyle app_style,
+						 GnomeHelpViewStylePriority app_style_priority);
+
+void		gnome_help_view_construct	(GnomeHelpView *self,
+						 GtkWidget *toplevel,
+						 GnomeHelpViewStyle app_style,
+						 GnomeHelpViewStylePriority app_style_priority);
+
+void		gnome_help_view_set_toplevel	(GnomeHelpView *help_view,
+						 GtkWidget *toplevel);
+
+GnomeHelpView *	gnome_help_view_find		(GtkWidget *awidget);
+void		gnome_help_view_set_visibility	(GnomeHelpView *help_view,
+						 gboolean visible);
+void		gnome_help_view_set_style	(GnomeHelpView *help_view,
+						 GnomeHelpViewStyle style,
+						 GnomeHelpViewStylePriority style_priority);
+void		gnome_help_view_select_help_cb	(GtkWidget *ignored,
+						 GnomeHelpView *help_view);
+
+/* as above, but does a lookup to try and figure out what the help_view is */
+void		gnome_help_view_select_help_menu_cb(GtkWidget *widget);
+
+void		gnome_help_view_show_help	(GnomeHelpView *help_view,
+						 const char *help_path,
+						 const char *help_type);
+void		gnome_help_view_show_help_for	(GnomeHelpView *help_view,
+						 GtkWidget *widget);
+void		gnome_help_view_set_orientation	(GnomeHelpView *help_view,
+						 GtkOrientation orientation);
+void		gnome_help_view_display		(GnomeHelpView *help_view,
+						 const char *help_path);
+void		gnome_help_view_display_callback(GtkWidget *widget,
+						 const char *help_path);
+
+/*** Non-widget routines ***/
+
+/* Turns a help path into a full URL */
+char *		gnome_help_path_resolve		(const char *path,
+						 const char *file_type);
+GSList *	gnome_help_app_topics		(const char *app_id);
+
+/* Object data on toplevel, name */
+#define GNOME_APP_HELP_VIEW_NAME "HelpView"
+
+/*** Utility routines ***/
+void		gnome_widget_set_tooltip	(GtkWidget *widget,
+						 const char *tiptext);
+GtkTooltips *	gnome_widget_get_tooltips	(void);
+GtkWidget *	gnome_widget_set_name		(GtkWidget *widget,
+						 const char *name);
+
+#define TT_(widget, text) gnome_widget_set_tooltip((widget), (text))
+#define H_(widget, help_id) gnome_widget_set_name((widget), (help_id))
+
+G_END_DECLS
+
+#endif
diff --git a/libgnomeui/gnome-href.c b/libgnomeui/gnome-href.c
new file mode 100644
index 0000000..5c28ea4
--- /dev/null
+++ b/libgnomeui/gnome-href.c
@@ -0,0 +1,508 @@
+/* gnome-href.c
+ * Copyright (C) 1998, James Henstridge <james daa com au>
+ * All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#include "config.h"
+#include "gnome-macros.h"
+
+#include <string.h> /* for strlen */
+
+#include <gtk/gtk.h>
+#include <libgnome/gnome-url.h>
+#include "gnome-href.h"
+#include "gnome-cursors.h"
+
+#include <libgnome/gnome-i18n.h>
+
+struct _GnomeHRefPrivate {
+	gchar *url;
+	GtkWidget *label;
+};
+
+static void gnome_href_class_init	(GnomeHRefClass *klass);
+static void gnome_href_init		(GnomeHRef *href);
+static void gnome_href_clicked		(GtkButton *button);
+static void gnome_href_destroy		(GtkObject *object);
+static void gnome_href_finalize		(GObject *object);
+static void gnome_href_get_property	(GObject *object,
+					 guint param_id,
+					 GValue *value,
+					 GParamSpec * pspec);
+static void gnome_href_set_property	(GObject *object,
+					 guint param_id,
+					 const GValue * value,
+					 GParamSpec * pspec);
+static void gnome_href_realize		(GtkWidget *widget);
+static void drag_data_get    		(GnomeHRef          *href,
+					 GdkDragContext     *context,
+					 GtkSelectionData   *selection_data,
+					 guint               info,
+					 guint               time,
+					 gpointer            data);
+
+static const GtkTargetEntry http_drop_types[] = {
+	{ "text/uri-list",       0, 0 },
+	{ "x-url/http",          0, 0 },
+	{ "_NETSCAPE_URL",       0, 0 }
+};
+static const GtkTargetEntry ftp_drop_types[] = {
+	{ "text/uri-list",       0, 0 },
+	{ "x-url/ftp",           0, 0 },
+	{ "_NETSCAPE_URL",       0, 0 }
+};
+static const GtkTargetEntry other_drop_types[] = {
+	{ "text/uri-list",       0, 0 },
+	{ "_NETSCAPE_URL",       0, 0 }
+};
+
+static const gint n_http_drop_types = 
+   sizeof(http_drop_types) / sizeof(http_drop_types[0]);
+static const gint n_ftp_drop_types = 
+   sizeof(ftp_drop_types) / sizeof(ftp_drop_types[0]);
+static const gint n_other_drop_types = 
+   sizeof(other_drop_types) / sizeof(other_drop_types[0]);
+
+
+enum {
+	PROP_0,
+	PROP_URL,
+	PROP_TEXT
+};
+
+/**
+ * gnome_href_get_type
+ *
+ * Returns the type assigned to the GNOME href widget.
+ **/
+/* The following defines the get_type */
+GNOME_CLASS_BOILERPLATE (GnomeHRef, gnome_href,
+			 GtkButton, gtk_button)
+
+static void
+gnome_href_class_init (GnomeHRefClass *klass)
+{
+	GtkObjectClass *object_class = (GtkObjectClass *)klass;
+	GObjectClass *gobject_class = (GObjectClass *)klass;
+	GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
+	GtkButtonClass *button_class = (GtkButtonClass *)klass;
+
+	/* By default we link to The World Food Programme */
+	g_object_class_install_property (gobject_class,
+				      PROP_URL,
+				      g_param_spec_string ("url",
+							   _("URL"),
+							   _("The URL that GnomeHRef activates"),
+							   "http://www.wfp.org";,
+							   (G_PARAM_READABLE |
+							    G_PARAM_WRITABLE)));
+	g_object_class_install_property (gobject_class,
+				      PROP_TEXT,
+				      g_param_spec_string ("text",
+							   _("Text"),
+							   _("The text on the button"),
+							   _("End World Hunger"),
+							   (G_PARAM_READABLE |
+							    G_PARAM_WRITABLE)));
+
+	object_class->destroy = gnome_href_destroy;
+
+	gobject_class->finalize = gnome_href_finalize;
+	gobject_class->set_property = gnome_href_set_property;
+	gobject_class->get_property = gnome_href_get_property;
+
+	widget_class->realize = gnome_href_realize;
+	button_class->clicked = gnome_href_clicked;
+}
+
+static void
+gnome_href_init(GnomeHRef *href)
+{
+	href->_priv = g_new0(GnomeHRefPrivate, 1);
+
+	href->_priv->label = gtk_label_new("");
+	gtk_widget_ref(href->_priv->label);
+
+	gtk_button_set_relief(GTK_BUTTON(href), GTK_RELIEF_NONE);
+	gtk_container_add(GTK_CONTAINER(href), href->_priv->label);
+	gtk_widget_show(href->_priv->label);
+
+	href->_priv->url = NULL;
+
+	/* the source dest is set on set_url */
+	gtk_signal_connect (GTK_OBJECT (href), "drag_data_get",
+			    GTK_SIGNAL_FUNC (drag_data_get), NULL);
+}
+
+static void
+drag_data_get(GnomeHRef          *href,
+	      GdkDragContext     *context,
+	      GtkSelectionData   *selection_data,
+	      guint               info,
+	      guint               time,
+	      gpointer            data)
+{
+	g_return_if_fail (href != NULL);
+	g_return_if_fail (GNOME_IS_HREF (href));
+
+	if( ! href->_priv->url) {
+		/*FIXME: cancel the drag*/
+		return;
+	}
+
+	/* if this doesn't look like an url, it's probably a file */
+	if(strchr(href->_priv->url, ':') == NULL) {
+		char *s = g_strdup_printf("file:%s\r\n", href->_priv->url);
+		gtk_selection_data_set (selection_data,
+					selection_data->target,
+					8, s, strlen(s)+1);
+		g_free(s);
+	} else {
+		gtk_selection_data_set (selection_data,
+					selection_data->target,
+					8, href->_priv->url, strlen(href->_priv->url)+1);
+	}
+}
+
+/**
+ * gnome_href_construct
+ * @href: Pointer to GnomeHRef widget
+ * @url: URL assigned to this object.
+ * @text: Text associated with the URL.
+ *
+ * Description:
+ * For bindings and subclassing, in C you should use #gnome_href_new
+ *
+ * Returns:
+ **/
+
+void
+gnome_href_construct (GnomeHRef *href, const gchar *url, const gchar *text)
+{
+  g_return_if_fail(href != NULL);
+  g_return_if_fail(GNOME_IS_HREF(href));
+  g_return_if_fail(url != NULL);
+
+  gnome_href_set_url(href, url);
+
+  if ( ! text)
+    text = url;
+
+  gnome_href_set_text(href, text);
+}
+
+
+/**
+ * gnome_href_new
+ * @url: URL assigned to this object.
+ * @text: Text associated with the URL.
+ *
+ * Description:
+ * Created a GNOME href object, a label widget with a clickable action
+ * and an associated URL.  If @text is set to %NULL, @url is used as
+ * the text for the label.
+ *
+ * Returns:  Pointer to new GNOME href widget.
+ **/
+
+GtkWidget *gnome_href_new(const gchar *url, const gchar *text) {
+  GnomeHRef *href;
+
+  g_return_val_if_fail(url != NULL, NULL);
+
+  href = gtk_type_new(gnome_href_get_type());
+
+  gnome_href_construct(href, url, text);
+
+  return GTK_WIDGET(href);
+}
+
+
+/**
+ * gnome_href_get_url
+ * @href: Pointer to GnomeHRef widget
+ *
+ * Description:
+ * Returns the pointer to the URL associated with the @href href object.  Note
+ * that the string should not be freed as it is internal memory.
+ *
+ * Returns:  Pointer to an internal URL string, or %NULL if failure.
+ **/
+
+const gchar *gnome_href_get_url(GnomeHRef *href) {
+  g_return_val_if_fail(href != NULL, NULL);
+  g_return_val_if_fail(GNOME_IS_HREF(href), NULL);
+  return href->_priv->url;
+}
+
+
+/**
+ * gnome_href_set_url
+ * @href: Pointer to GnomeHRef widget
+ * @url: String containing the URL to be stored within @href.
+ *
+ * Description:
+ * Sets the internal URL value within @href to the value of @url.
+ **/
+
+void gnome_href_set_url(GnomeHRef *href, const gchar *url) {
+  g_return_if_fail(href != NULL);
+  g_return_if_fail(GNOME_IS_HREF(href));
+  g_return_if_fail(url != NULL);
+
+  if (href->_priv->url) {
+	  gtk_drag_source_unset(GTK_WIDGET(href));
+	  g_free(href->_priv->url);
+  }
+  href->_priv->url = g_strdup(url);
+  if(strncmp(url, "http://";, 7) == 0 ||
+     strncmp(url, "https://";, 8) == 0) {
+	  gtk_drag_source_set (GTK_WIDGET(href),
+			       GDK_BUTTON1_MASK|GDK_BUTTON3_MASK,
+			       http_drop_types, n_http_drop_types,
+			       GDK_ACTION_COPY);
+  } else if(strncmp(url, "ftp://";, 6) == 0) {
+	  gtk_drag_source_set (GTK_WIDGET(href),
+			       GDK_BUTTON1_MASK|GDK_BUTTON3_MASK,
+			       ftp_drop_types, n_ftp_drop_types,
+			       GDK_ACTION_COPY);
+  } else {
+	  gtk_drag_source_set (GTK_WIDGET(href),
+			       GDK_BUTTON1_MASK|GDK_BUTTON3_MASK,
+			       other_drop_types, n_other_drop_types,
+			       GDK_ACTION_COPY);
+  }
+}
+
+
+/**
+ * gnome_href_get_text
+ * @href: Pointer to GnomeHRef widget
+ *
+ * Description:
+ * Returns the contents of the label widget used to display the link text.
+ * Note that the string should not be freed as it points to internal memory.
+ *
+ * Returns:  Pointer to text contained in the label widget.
+ **/
+
+const gchar *gnome_href_get_text(GnomeHRef *href) {
+  gchar *ret;
+
+  g_return_val_if_fail(href != NULL, NULL);
+  g_return_val_if_fail(GNOME_IS_HREF(href), NULL);
+
+  gtk_label_get(GTK_LABEL(href->_priv->label), &ret);
+  return ret;
+}
+
+
+/**
+ * gnome_href_set_text
+ * @href: Pointer to GnomeHRef widget
+ * @text: New link text for the href object.
+ *
+ * Description:
+ * Sets the internal label widget text (used to display a URL's link
+ * text) to the value given in @label.
+ **/
+void
+gnome_href_set_text (GnomeHRef *href, const gchar *text)
+{
+  gchar *pattern;
+
+  g_return_if_fail(href != NULL);
+  g_return_if_fail(GNOME_IS_HREF(href));
+  g_return_if_fail(text != NULL);
+
+  /* pattern used to set underline for string */
+  pattern = g_strnfill(strlen(text), '_');
+  gtk_label_set_text(GTK_LABEL(href->_priv->label), text);
+  gtk_label_set_pattern(GTK_LABEL(href->_priv->label), pattern);
+  g_free(pattern);
+}
+
+#ifndef GNOME_EXCLUDE_DEPRECATED_SOURCE
+
+/**
+ * gnome_href_get_label
+ * @href: Pointer to GnomeHRef widget
+ *
+ * Description:
+ * deprecated, use #gnome_href_get_text
+ **/
+
+const gchar *
+gnome_href_get_label(GnomeHRef *href)
+{
+	g_warning("gnome_href_get_label is deprecated, use gnome_href_get_text");
+	return gnome_href_get_text(href);
+}
+
+
+/**
+ * gnome_href_set_label
+ * @href: Pointer to GnomeHRef widget
+ * @label: New link text for the href object.
+ *
+ * Description:
+ * deprecated, use #gnome_href_set_text
+ **/
+
+void
+gnome_href_set_label (GnomeHRef *href, const gchar *label)
+{
+	g_return_if_fail(href != NULL);
+	g_return_if_fail(GNOME_IS_HREF(href));
+
+	g_warning("gnome_href_set_label is deprecated, use gnome_href_set_text");
+	gnome_href_set_text(href, label);
+}
+
+#endif /* not GNOME_EXCLUDE_DEPRECATED_SOURCE */
+
+static void
+gnome_href_clicked (GtkButton *button)
+{
+  GnomeHRef *href;
+
+  g_return_if_fail(button != NULL);
+  g_return_if_fail(GNOME_IS_HREF(button));
+
+  GNOME_CALL_PARENT_HANDLER (GTK_BUTTON_CLASS, clicked, (button));
+
+  href = GNOME_HREF(button);
+
+  g_return_if_fail(href->_priv->url != NULL);
+
+  if(!gnome_url_show(href->_priv->url)) {
+      GtkWidget *dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR,
+						 GTK_BUTTONS_OK,
+						 _("Error occured while trying to launch the "
+						   "URL handler.\n"
+						   "Please check the settings in the "
+						   "Control Center if they are correct."));
+
+      gtk_dialog_run(GTK_DIALOG(dialog));
+  }
+}
+
+static void
+gnome_href_destroy(GtkObject *object)
+{
+	GnomeHRef *href;
+
+	/* remember, destroy can be run multiple times! */
+
+	g_return_if_fail(object != NULL);
+	g_return_if_fail(GNOME_IS_HREF(object));
+
+	href = GNOME_HREF(object);
+
+	g_free(href->_priv->url);
+	href->_priv->url = NULL;
+
+	if(href->_priv->label) {
+		gtk_widget_unref(href->_priv->label);
+		href->_priv->label = NULL;
+	}
+
+	GNOME_CALL_PARENT_HANDLER (GTK_OBJECT_CLASS, destroy, (object));
+}
+
+static void
+gnome_href_finalize(GObject *object)
+{
+	GnomeHRef *href;
+
+	g_return_if_fail(object != NULL);
+	g_return_if_fail(GNOME_IS_HREF(object));
+
+	href = GNOME_HREF(object);
+
+	g_free(href->_priv);
+	href->_priv = NULL;
+
+	GNOME_CALL_PARENT_HANDLER (G_OBJECT_CLASS, finalize, (object));
+}
+
+static void
+gnome_href_realize(GtkWidget *widget)
+{
+	GdkCursor *cursor;
+
+	GNOME_CALL_PARENT_HANDLER (GTK_WIDGET_CLASS, realize, (widget));
+
+	cursor = gnome_stock_cursor_new(GNOME_STOCK_CURSOR_POINTING_HAND);
+	gdk_window_set_cursor(widget->window, cursor);
+	gdk_cursor_destroy(cursor);
+}
+
+static void
+gnome_href_set_property (GObject *object,
+			 guint param_id,
+			 const GValue * value,
+			 GParamSpec * pspec)
+{
+	GnomeHRef *self;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GNOME_IS_HREF (object));
+
+	self = GNOME_HREF (object);
+
+	switch (param_id) {
+	case PROP_URL:
+		gnome_href_set_url(self, g_value_get_string (value));
+		break;
+	case PROP_TEXT:
+		gnome_href_set_text(self, g_value_get_string (value));
+		break;
+	default:
+		break;
+	}
+}
+
+static void
+gnome_href_get_property (GObject *object,
+		      guint param_id,
+		      GValue *value,
+		      GParamSpec * pspec)
+{
+	GnomeHRef *self;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GNOME_IS_HREF (object));
+
+	self = GNOME_HREF (object);
+
+	switch (param_id) {
+	case PROP_URL:
+		g_value_set_string (value,
+				    gnome_href_get_url(self));
+		break;
+	case PROP_TEXT:
+		g_value_set_string (value,
+				    gnome_href_get_text(self));
+		break;
+	default:
+		break;
+	}
+}
diff --git a/libgnomeui/gnome-href.h b/libgnomeui/gnome-href.h
new file mode 100644
index 0000000..1f1ddad
--- /dev/null
+++ b/libgnomeui/gnome-href.h
@@ -0,0 +1,84 @@
+/* WARNING ____ IMMATURE API ____ liable to change */
+
+/* gnome-href.h
+ * Copyright (C) 1998, James Henstridge <james daa com au>
+ * All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#ifndef GNOME_HREF_H
+#define GNOME_HREF_H
+
+#include <glib.h>
+#include <gtk/gtkbutton.h>
+
+
+G_BEGIN_DECLS
+
+#define GNOME_TYPE_HREF            (gnome_href_get_type ())
+#define GNOME_HREF(obj)            (GTK_CHECK_CAST((obj), GNOME_TYPE_HREF, GnomeHRef))
+#define GNOME_HREF_CLASS(klass)    (GTK_CHECK_CLASS_CAST((klass), GNOME_TYPE_HREF, GnomeHRefClass))
+#define GNOME_IS_HREF(obj)         (GTK_CHECK_TYPE((obj), GNOME_TYPE_HREF))
+#define GNOME_IS_HREF_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_HREF))
+#define GNOME_HREF_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_HREF, GnomeHRefClass))
+
+typedef struct _GnomeHRef        GnomeHRef;
+typedef struct _GnomeHRefPrivate GnomeHRefPrivate;
+typedef struct _GnomeHRefClass   GnomeHRefClass;
+
+
+struct _GnomeHRef {
+  GtkButton button;
+
+  /*< private >*/
+  GnomeHRefPrivate *_priv;
+};
+
+struct _GnomeHRefClass {
+  GtkButtonClass parent_class;
+};
+
+/*
+ * GNOME href class methods
+ */
+
+GtkType gnome_href_get_type(void) G_GNUC_CONST;
+GtkWidget *gnome_href_new(const gchar *url, const gchar *text);
+
+/* for bindings and subclassing, use the gnome_href_new from C */
+void gnome_href_construct(GnomeHRef *href,
+			  const gchar *url,
+			  const gchar *text);
+
+void gnome_href_set_url(GnomeHRef *href, const gchar *url);
+const gchar *gnome_href_get_url(GnomeHRef *href);
+
+void gnome_href_set_text(GnomeHRef *href, const gchar *text);
+const gchar *gnome_href_get_text(GnomeHRef *href);
+
+#ifndef GNOME_EXCLUDE_DEPRECATED
+/* DEPRECATED!, use set/get_text */
+void gnome_href_set_label(GnomeHRef *href, const gchar *label);
+const gchar *gnome_href_get_label(GnomeHRef *href);
+#endif
+
+G_END_DECLS
+
+#endif
+
diff --git a/libgnomeui/gnome-ice.c b/libgnomeui/gnome-ice.c
new file mode 100644
index 0000000..739db9c
--- /dev/null
+++ b/libgnomeui/gnome-ice.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+/* gnome-ice.c - Interface between ICE and Gtk.
+   Written by Tom Tromey <tromey cygnus com>.  */
+
+#include <config.h>
+
+#ifdef HAVE_LIBSM
+#include <X11/ICE/ICElib.h>
+#endif /* HAVE_LIBSM */
+
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <gtk/gtk.h>
+#include "gnome-ice.h"
+
+#ifdef HAVE_LIBSM
+
+static void gnome_ice_io_error_handler (IceConn connection);
+
+static void new_ice_connection (IceConn connection, IcePointer client_data, 
+				Bool opening, IcePointer *watch_data);
+
+/* This is called when data is available on an ICE connection.  */
+static gboolean
+process_ice_messages (gpointer client_data, gint source,
+		      GdkInputCondition condition)
+{
+  IceConn connection = (IceConn) client_data;
+  IceProcessMessagesStatus status;
+
+  status = IceProcessMessages (connection, NULL, NULL);
+
+  if (status == IceProcessMessagesIOError)
+    {
+      IcePointer context = IceGetConnectionContext (connection);
+
+      if (context && GTK_IS_OBJECT (context))
+	{
+	  guint disconnect_id = gtk_signal_lookup ("disconnect", 
+						   GTK_OBJECT_TYPE (context));
+
+	  if (disconnect_id > 0)
+	    gtk_signal_emit (GTK_OBJECT (context), disconnect_id);
+	}
+      else
+	{
+	  IceSetShutdownNegotiation (connection, False);
+	  IceCloseConnection (connection);
+	}
+    }
+
+  return TRUE;
+}
+
+/* This is called when a new ICE connection is made.  It arranges for
+   the ICE connection to be handled via the event loop.  */
+static void
+new_ice_connection (IceConn connection, IcePointer client_data, Bool opening,
+		    IcePointer *watch_data)
+{
+  gint input_id;
+
+  if (opening)
+    {
+      /* Make sure we don't pass on these file descriptors to any
+         exec'ed children */
+      fcntl(IceConnectionNumber(connection),F_SETFD,
+	    fcntl(IceConnectionNumber(connection),F_GETFD,0) | FD_CLOEXEC);
+
+      input_id = gdk_input_add (IceConnectionNumber (connection),
+				GDK_INPUT_READ|GDK_INPUT_EXCEPTION,
+				(GdkInputFunction)process_ice_messages,
+				(gpointer) connection);
+
+      *watch_data = (IcePointer) GINT_TO_POINTER (input_id);
+    }
+  else 
+    {
+      input_id = GPOINTER_TO_INT ((gpointer) *watch_data);
+
+      gdk_input_remove (input_id);
+    }
+}
+
+static IceIOErrorHandler gnome_ice_installed_handler;
+
+/* We call any handler installed before (or after) gnome_ice_init but 
+   avoid calling the default libICE handler which does an exit() */
+static void
+gnome_ice_io_error_handler (IceConn connection)
+{
+    if (gnome_ice_installed_handler)
+      (*gnome_ice_installed_handler) (connection);
+}    
+
+#endif /* HAVE_LIBSM */
+
+void
+gnome_ice_init (void)
+{
+#ifdef HAVE_LIBSM
+  static gboolean ice_init = FALSE;
+
+  if (! ice_init)
+    {
+      IceIOErrorHandler default_handler;
+
+      gnome_ice_installed_handler = IceSetIOErrorHandler (NULL);
+      default_handler = IceSetIOErrorHandler (gnome_ice_io_error_handler);
+
+      if (gnome_ice_installed_handler == default_handler)
+	gnome_ice_installed_handler = NULL;
+
+      IceAddConnectionWatch (new_ice_connection, NULL);
+
+      ice_init = TRUE;
+    }
+#endif /* HAVE_LIBSM */
+}
diff --git a/libgnomeui/gnome-ice.h b/libgnomeui/gnome-ice.h
new file mode 100644
index 0000000..5b8677f
--- /dev/null
+++ b/libgnomeui/gnome-ice.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+/* gnome-ice.h - Interface between ICE and Gtk.
+   Written by Tom Tromey <tromey cygnus com>.  */
+
+#ifndef GNOME_ICE_H
+#define GNOME_ICE_H
+
+
+
+G_BEGIN_DECLS
+
+/* This function should be called before any ICE functions are used.
+   It will arrange for ICE connections to be read and dispatched via
+   the Gtk event loop.  This function can be called any number of
+   times without harm.  */
+void gnome_ice_init (void);
+
+G_END_DECLS
+
+#endif /* GNOME_ICE_H */
diff --git a/libgnomeui/gnome-icon-item.c b/libgnomeui/gnome-icon-item.c
new file mode 100644
index 0000000..2368358
--- /dev/null
+++ b/libgnomeui/gnome-icon-item.c
@@ -0,0 +1,1169 @@
+/*
+ * Copyright (C) 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+/* gnome-icon-text-item:  an editable text block with word wrapping for the
+ * GNOME canvas.
+ *
+ *
+ * Authors: Miguel de Icaza <miguel gnu org>
+ *          Federico Mena <federico gimp org>
+ *
+ * FIXME: Provide a ref-count fontname caching like thing.
+ */
+
+#include <math.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtksignal.h>
+#include <gtk/gtkwindow.h>
+#include "gnome-icon-item.h"
+#include "gnome-cursors.h"
+
+/* Margins used to display the information */
+#define MARGIN_X 2
+#define MARGIN_Y 2
+
+/* Default fontset to be used if the user specified fontset is not found */
+#define DEFAULT_FONT_NAME "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*,"	\
+			  "-*-*-medium-r-normal--10-*-*-*-*-*-*-*,*"
+
+/* Separators for text layout */
+#define DEFAULT_SEPARATORS " \t-.[]#"
+
+/* Aliases to minimize screen use in my laptop */
+#define ITI(x)       GNOME_ICON_TEXT_ITEM (x)
+#define ITI_CLASS(x) GNOME_ICON_TEXT_ITEM_CLASS (x)
+#define IS_ITI(x)    GNOME_IS_ICON_TEXT_ITEM (x)
+
+
+typedef GnomeIconTextItem Iti;
+
+/* Private part of the GnomeIconTextItem structure */
+typedef struct {
+	/* Font */
+	GdkFont *font;
+
+	/* Hack: create an offscreen window and place an entry inside it */
+	GtkEntry *entry;
+	GtkWidget *entry_top;
+
+	/* Whether the user pressed the mouse while the item was unselected */
+	guint unselected_click : 1;
+
+	/* Whether we need to update the position */
+	guint need_pos_update : 1;
+
+	/* Whether we need to update the font */
+	guint need_font_update : 1;
+
+	/* Whether we need to update the text */
+	guint need_text_update : 1;
+
+	/* Whether we need to update because the editing/selected state changed */
+	guint need_state_update : 1;
+} ItiPrivate;
+
+
+static GnomeCanvasItemClass *parent_class;
+
+enum {
+	TEXT_CHANGED,
+	HEIGHT_CHANGED,
+	WIDTH_CHANGED,
+	EDITING_STARTED,
+	EDITING_STOPPED,
+	SELECTION_STARTED,
+	SELECTION_STOPPED,
+	LAST_SIGNAL
+};
+
+static guint iti_signals [LAST_SIGNAL] = { 0 };
+
+static GdkFont *default_font;
+
+
+/* Stops the editing state of an icon text item */
+static void
+iti_stop_editing (Iti *iti)
+{
+	ItiPrivate *priv;
+
+	priv = iti->priv;
+
+	iti->editing = FALSE;
+
+	gtk_widget_destroy (priv->entry_top);
+	priv->entry = NULL;
+	priv->entry_top = NULL;
+
+	priv->need_state_update = TRUE;
+	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti));
+
+	gtk_signal_emit (GTK_OBJECT (iti), iti_signals[EDITING_STOPPED]);
+}
+
+/* Lays out the text in an icon item */
+static void
+layout_text (Iti *iti)
+{
+	ItiPrivate *priv;
+	const char *text;
+	int old_width, old_height;
+	int width, height;
+
+	priv = iti->priv;
+
+	/* Save old size */
+
+	if (iti->ti) {
+		old_width = iti->ti->width + 2 * MARGIN_X;
+		old_height = iti->ti->height + 2 * MARGIN_Y;
+
+		gnome_icon_text_info_free (iti->ti);
+	} else {
+		old_width = 2 * MARGIN_X;
+		old_height = 2 * MARGIN_Y;
+	}
+
+	/* Change the text layout */
+
+	if (iti->editing)
+		text = gtk_entry_get_text (priv->entry);
+	else
+		text = iti->text;
+
+	iti->ti = gnome_icon_layout_text (priv->font,
+					  text,
+					  DEFAULT_SEPARATORS,
+					  iti->width - 2 * MARGIN_X,
+					  TRUE);
+
+	/* Check the sizes and see if we need to emit any signals */
+
+	width = iti->ti->width + 2 * MARGIN_X;
+	height = iti->ti->height + 2 * MARGIN_Y;
+
+	if (width != old_width)
+		gtk_signal_emit (GTK_OBJECT (iti), iti_signals[WIDTH_CHANGED]);
+
+	if (height != old_height)
+		gtk_signal_emit (GTK_OBJECT (iti), iti_signals[HEIGHT_CHANGED]);
+}
+
+/* Accepts the text in the off-screen entry of an icon text item */
+static void
+iti_edition_accept (Iti *iti)
+{
+	ItiPrivate *priv;
+	gboolean accept;
+
+	priv = iti->priv;
+	accept = TRUE;
+
+	gtk_signal_emit (GTK_OBJECT (iti), iti_signals [TEXT_CHANGED], &accept);
+
+	if (iti->editing){
+		if (accept) {
+			if (iti->is_text_allocated)
+				g_free (iti->text);
+
+			iti->text = g_strdup (gtk_entry_get_text (priv->entry));
+			iti->is_text_allocated = 1;
+		}
+
+		iti_stop_editing (iti);
+	}
+	layout_text (iti);
+
+	priv->need_text_update = TRUE;
+	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti));
+}
+
+/* Callback used when the off-screen entry of an icon text item is activated.
+ * When this happens, we have to accept edition.
+ */
+static void
+iti_entry_activate (GtkWidget *entry, Iti *iti)
+{
+	iti_edition_accept (iti);
+}
+
+/* Starts the editing state of an icon text item */
+static void
+iti_start_editing (Iti *iti)
+{
+	ItiPrivate *priv;
+
+	priv = iti->priv;
+
+	if (iti->editing)
+		return;
+
+	/* Trick: The actual edition of the entry takes place in a GtkEntry
+	 * which is placed offscreen.  That way we get all of the advantages
+	 * from GtkEntry without duplicating code.  Yes, this is a hack.
+	 */
+	priv->entry = (GtkEntry *) gtk_entry_new ();
+	gtk_entry_set_text (priv->entry, iti->text);
+	gtk_signal_connect (GTK_OBJECT (priv->entry), "activate",
+			    GTK_SIGNAL_FUNC (iti_entry_activate), iti);
+
+	priv->entry_top = gtk_window_new (GTK_WINDOW_POPUP);
+	gtk_container_add (GTK_CONTAINER (priv->entry_top), GTK_WIDGET (priv->entry));
+	gtk_widget_set_uposition (priv->entry_top, 20000, 20000);
+	gtk_widget_show_all (priv->entry_top);
+
+	gtk_editable_select_region (GTK_EDITABLE (priv->entry), 0, -1);
+
+	iti->editing = TRUE;
+
+	priv->need_state_update = TRUE;
+	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti));
+
+	gtk_signal_emit (GTK_OBJECT (iti), iti_signals[EDITING_STARTED]);
+}
+
+/* Destroy method handler for the icon text item */
+static void
+iti_destroy (GtkObject *object)
+{
+	Iti *iti;
+	ItiPrivate *priv;
+	GnomeCanvasItem *item;
+
+	/* remember, destroy can be run multiple times! */
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (IS_ITI (object));
+
+	iti = ITI (object);
+	priv = iti->priv;
+	item = GNOME_CANVAS_ITEM (object);
+
+	/* FIXME: stop selection and editing */
+
+	/* Queue redraw of bounding box */
+
+	if (priv)
+	    gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);
+
+	/* Free everything */
+
+	if (iti->fontname)
+		g_free (iti->fontname);
+	iti->fontname = NULL;
+
+	if (iti->text && iti->is_text_allocated)
+		g_free (iti->text);
+	iti->text = NULL;
+
+	if (iti->ti)
+		gnome_icon_text_info_free (iti->ti);
+	iti->ti = NULL;
+
+	if (priv) {
+	    if (priv->font)
+		gdk_font_unref (priv->font);
+
+	    if (priv->entry_top)
+		gtk_widget_destroy (priv->entry_top);
+
+	    g_free (priv);
+	    iti->priv = NULL;
+	}
+
+	if (GTK_OBJECT_CLASS (parent_class)->destroy)
+		(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+/* Loads the default font for icon text items if necessary */
+static GdkFont *
+get_default_font (void)
+{
+	if (!default_font) {
+		/* FIXME: this is never unref-ed */
+		default_font = gdk_fontset_load (DEFAULT_FONT_NAME);
+		g_assert (default_font != NULL);
+	}
+
+	return gdk_font_ref (default_font);
+}
+
+/* Recomputes the bounding box of an icon text item */
+static void
+recompute_bounding_box (Iti *iti)
+{
+	GnomeCanvasItem *item;
+	double affine[6];
+	ArtPoint p, q;
+	int x1, y1, x2, y2;
+	int width, height;
+
+	item = GNOME_CANVAS_ITEM (iti);
+
+	/* Compute width, height, position */
+
+	width = iti->ti->width + 2 * MARGIN_X;
+	height = iti->ti->height + 2 * MARGIN_Y;
+
+	x1 = iti->x + (iti->width - width) / 2;
+	y1 = iti->y;
+	x2 = x1 + width;
+	y2 = y1 + height;
+
+	/* Translate to world coordinates */
+
+	gnome_canvas_item_i2w_affine (item, affine);
+
+	p.x = x1;
+	p.y = y1;
+	art_affine_point (&q, &p, affine);
+	item->x1 = q.x;
+	item->y1 = q.y;
+
+	p.x = x2;
+	p.y = y2;
+	art_affine_point (&q, &p, affine);
+	item->x2 = q.x;
+	item->y2 = q.y;
+}
+
+/* Update method for the icon text item */
+static void
+iti_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags)
+{
+	Iti *iti;
+	ItiPrivate *priv;
+
+	iti = ITI (item);
+	priv = iti->priv;
+
+	if (parent_class->update)
+		(* parent_class->update) (item, affine, clip_path, flags);
+
+	/* If necessary, queue a redraw of the old bounding box */
+
+	if ((flags & GNOME_CANVAS_UPDATE_VISIBILITY)
+	    || (flags & GNOME_CANVAS_UPDATE_AFFINE)
+	    || priv->need_pos_update
+	    || priv->need_font_update
+	    || priv->need_text_update)
+		gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);
+
+	/* Compute new bounds */
+
+	if (priv->need_pos_update
+	    || priv->need_font_update
+	    || priv->need_text_update)
+		recompute_bounding_box (iti);
+
+	/* Queue redraw */
+
+	gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2);
+
+	priv->need_pos_update = FALSE;
+	priv->need_font_update = FALSE;
+	priv->need_text_update = FALSE;
+	priv->need_state_update = FALSE;
+}
+
+/* Draw the icon text item's text when it is being edited */
+static void
+iti_paint_text (Iti *iti, GdkDrawable *drawable, int x, int y)
+{
+	ItiPrivate *priv;
+        GnomeIconTextInfoRow *row;
+	GnomeIconTextInfo *ti;
+	GtkStyle *style;
+	GdkGC *fg_gc, *bg_gc;
+	GdkGC *gc, *bgc, *sgc, *bsgc;
+        GList *item;
+        int xpos, len;
+
+	priv = iti->priv;
+	style = GTK_WIDGET (GNOME_CANVAS_ITEM (iti)->canvas)->style;
+
+	ti = iti->ti;
+	len = 0;
+        y += ti->font->ascent;
+
+	/*
+	 * Pointers to all of the GCs we use
+	 */
+	gc = style->fg_gc [GTK_STATE_NORMAL];
+	bgc = style->bg_gc [GTK_STATE_NORMAL];
+	sgc = style->fg_gc [GTK_STATE_SELECTED];
+	bsgc = style->bg_gc [GTK_STATE_SELECTED];
+
+        for (item = ti->rows; item; item = item->next, len += (row ? row->text_length : 0)) {
+		GdkWChar *text_wc;
+		int text_length;
+		int cursor, offset, i;
+		int sel_start, sel_end;
+
+		row = item->data;
+
+                if (!row) {
+			y += ti->baseline_skip / 2;
+			continue;
+		}
+
+		text_wc = row->text_wc;
+		text_length = row->text_length;
+
+		xpos = (ti->width - row->width) / 2;
+
+		/* FIXME: is this correct? */
+		gtk_editable_get_selection_bounds (GTK_EDITABLE (priv->entry),
+						   &sel_start,
+						   &sel_end);
+
+		sel_start -= len;
+		sel_end -= len;
+
+		offset = 0;
+		cursor = gtk_editable_get_position (GTK_EDITABLE (priv->entry));
+
+		/* FIXME: is the above aquivalent for 2.0 ??? */
+
+#if 0 /* FIXME */
+		sel_start = GTK_EDITABLE (priv->entry)->selection_start_pos - len;
+		sel_end = GTK_EDITABLE (priv->entry)->selection_end_pos - len;
+		offset = 0;
+		cursor = GTK_EDITABLE (priv->entry)->current_pos - len;
+#endif
+
+		for (i = 0; *text_wc; text_wc++, i++) {
+			int size, px;
+
+			size = gdk_text_width_wc (ti->font, text_wc, 1);
+
+			if (i >= sel_start && i < sel_end) {
+				fg_gc = sgc;
+				bg_gc = bsgc;
+			} else {
+				fg_gc = gc;
+				bg_gc = bgc;
+			}
+
+			px = x + xpos + offset;
+			gdk_draw_rectangle (drawable,
+					    bg_gc,
+					    TRUE,
+					    px,
+					    y - ti->font->ascent,
+					    size, ti->baseline_skip);
+
+			gdk_draw_text_wc (drawable,
+					  ti->font,
+					  fg_gc,
+					  px, y,
+					  text_wc, 1);
+
+			if (cursor == i)
+				gdk_draw_line (drawable,
+					       gc,
+					       px - 1,
+					       y - ti->font->ascent,
+					       px - 1,
+					       y + ti->font->descent - 1);
+
+			offset += size;
+		}
+
+		if (cursor == i) {
+			int px = x + xpos + offset;
+
+			gdk_draw_line (drawable,
+				       gc,
+				       px - 1,
+				       y - ti->font->ascent,
+				       px - 1,
+				       y + ti->font->descent - 1);
+		}
+
+		y += ti->baseline_skip;
+        }
+}
+
+/* Draw method handler for the icon text item */
+static void
+iti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height)
+{
+	Iti *iti;
+	GtkStyle *style;
+	int w, h;
+	int xofs, yofs;
+
+	iti = ITI (item);
+
+	if (iti->ti) {
+		w = iti->ti->width + 2 * MARGIN_X;
+		h = iti->ti->height + 2 * MARGIN_Y;
+	} else {
+		w = 2 * MARGIN_X;
+		h = 2 * MARGIN_Y;
+	}
+
+	xofs = item->x1 - x;
+	yofs = item->y1 - y;
+
+	style = GTK_WIDGET (item->canvas)->style;
+
+	if (iti->selected && !iti->editing)
+		gdk_draw_rectangle (drawable,
+				    style->bg_gc[GTK_STATE_SELECTED],
+				    TRUE,
+				    xofs, yofs,
+				    w, h);
+
+	if (iti->editing) {
+		gdk_draw_rectangle (drawable,
+				    style->fg_gc[GTK_STATE_NORMAL],
+				    FALSE,
+				    xofs, yofs,
+				    w - 1, h - 1);
+
+		iti_paint_text (iti, drawable, xofs + MARGIN_X, yofs + MARGIN_Y);
+	} else
+		gnome_icon_paint_text (iti->ti,
+				       drawable,
+				       style->fg_gc[(iti->selected
+						     ? GTK_STATE_SELECTED
+						     : GTK_STATE_NORMAL)],
+				       xofs + MARGIN_X,
+				       yofs + MARGIN_Y,
+				       GTK_JUSTIFY_CENTER);
+}
+
+/* Point method handler for the icon text item */
+static double
+iti_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, GnomeCanvasItem **actual_item)
+{
+	double dx, dy;
+
+	*actual_item = item;
+
+	if (cx < item->x1)
+		dx = item->x1 - cx;
+	else if (cx > item->x2)
+		dx = cx - item->x2;
+	else
+		dx = 0.0;
+
+	if (cy < item->y1)
+		dy = item->y1 - cy;
+	else if (cy > item->y2)
+		dy = cy - item->y2;
+	else
+		dy = 0.0;
+
+	return sqrt (dx * dx + dy * dy);
+}
+
+/* Given X, Y, a mouse position, return a valid index inside the edited text */
+static int
+iti_idx_from_x_y (Iti *iti, int x, int y)
+{
+	ItiPrivate *priv;
+        GnomeIconTextInfoRow *row;
+	int lines;
+	int line, col, i, idx;
+	GList *l;
+
+	priv = iti->priv;
+
+	if (iti->ti->rows == NULL)
+		return 0;
+
+	lines = g_list_length (iti->ti->rows);
+	line = y / iti->ti->baseline_skip;
+
+	if (line < 0)
+		line = 0;
+	else if (lines < line + 1)
+		line = lines - 1;
+
+	/* Compute the base index for this line */
+	for (l = iti->ti->rows, idx = i = 0; i < line; l = l->next, i++) {
+		row = l->data;
+		idx += row->text_length;
+	}
+
+	row = g_list_nth (iti->ti->rows, line)->data;
+	col = 0;
+	if (row != NULL) {
+		int first_char;
+		int last_char;
+
+		first_char = (iti->ti->width - row->width) / 2;
+		last_char = first_char + row->width;
+
+		if (x < first_char) {
+			/* nothing */
+		} else if (x > last_char) {
+			col = row->text_length;
+		} else {
+			GdkWChar *s = row->text_wc;
+			int pos = first_char;
+
+			while (pos < last_char) {
+				pos += gdk_text_width_wc (iti->ti->font, s, 1);
+				if (pos > x)
+					break;
+				col++;
+				s++;
+			}
+		}
+	}
+
+	idx += col;
+
+	g_assert (idx <= priv->entry->text_size);
+
+	return idx;
+}
+
+/* Starts the selection state in the icon text item */
+static void
+iti_start_selecting (Iti *iti, int idx, guint32 event_time)
+{
+	ItiPrivate *priv;
+	GtkEditable *e;
+	GdkCursor *ibeam;
+
+	priv = iti->priv;
+	e = GTK_EDITABLE (priv->entry);
+
+	gtk_editable_select_region (e, idx, idx);
+	gtk_editable_set_position (e, idx);
+	ibeam = gnome_stock_cursor_new (GNOME_STOCK_CURSOR_XTERM);
+	gnome_canvas_item_grab (GNOME_CANVAS_ITEM (iti),
+				GDK_BUTTON_RELEASE_MASK |
+				GDK_POINTER_MOTION_MASK,
+				ibeam, event_time);
+	gdk_cursor_destroy (ibeam);
+
+#if 0 /* FIXME */
+	gtk_editable_select_region (e, idx, idx);
+	e->current_pos = e->selection_start_pos;
+	e->has_selection = TRUE;
+	iti->selecting = TRUE;
+#endif
+
+	priv->need_state_update = TRUE;
+	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti));
+
+	gtk_signal_emit (GTK_OBJECT (iti), iti_signals[SELECTION_STARTED]);
+}
+
+/* Stops the selection state in the icon text item */
+static void
+iti_stop_selecting (Iti *iti, guint32 event_time)
+{
+	ItiPrivate *priv;
+	GnomeCanvasItem *item;
+	GtkEditable *e;
+
+	priv = iti->priv;
+	item = GNOME_CANVAS_ITEM (iti);
+	e = GTK_EDITABLE (priv->entry);
+
+	gnome_canvas_item_ungrab (item, event_time);
+#if 0 /* FIXME */
+	e->has_selection = FALSE;
+#endif
+	iti->selecting = FALSE;
+
+	priv->need_state_update = TRUE;
+	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti));
+	gtk_signal_emit (GTK_OBJECT (iti), iti_signals[SELECTION_STOPPED]);
+}
+
+/* Handles selection range changes on the icon text item */
+static void
+iti_selection_motion (Iti *iti, int idx)
+{
+	ItiPrivate *priv;
+	GtkEditable *e;
+
+	priv = iti->priv;
+	e = GTK_EDITABLE (priv->entry);
+
+#if 0 /* FIXME */
+	if (idx < e->current_pos) {
+		e->selection_start_pos = idx;
+		e->selection_end_pos   = e->current_pos;
+	} else {
+		e->selection_start_pos = e->current_pos;
+		e->selection_end_pos  = idx;
+	}
+#endif
+
+	priv->need_state_update = TRUE;
+	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti));
+}
+
+/* Event handler for icon text items */
+static gint
+iti_event (GnomeCanvasItem *item, GdkEvent *event)
+{
+	Iti *iti;
+	ItiPrivate *priv;
+	int idx;
+	double x, y;
+
+	iti = ITI (item);
+	priv = iti->priv;
+
+	switch (event->type) {
+	case GDK_KEY_PRESS:
+		if (!iti->editing)
+			break;
+
+		if (event->key.keyval == GDK_Escape)
+			iti_stop_editing (iti);
+		else
+			gtk_widget_event (GTK_WIDGET (priv->entry), event);
+
+		layout_text (iti);
+		priv->need_text_update = TRUE;
+		gnome_canvas_item_request_update (item);
+		return TRUE;
+
+	case GDK_BUTTON_PRESS:
+		if (!iti->editing)
+			break;
+
+		if (iti->editing && event->button.button == 1) {
+			x = event->button.x - (item->x1 + MARGIN_X);
+			y = event->button.y - (item->y1 + MARGIN_Y);
+			idx = iti_idx_from_x_y (iti, x, y);
+
+			iti_start_selecting (iti, idx, event->button.time);
+		} else
+			break;
+
+		return TRUE;
+
+	case GDK_MOTION_NOTIFY:
+		if (!iti->selecting)
+			break;
+
+		x = event->motion.x - (item->x1 + MARGIN_X);
+		y = event->motion.y - (item->y1 + MARGIN_Y);
+		idx = iti_idx_from_x_y (iti, x, y);
+		iti_selection_motion (iti, idx);
+		return TRUE;
+
+	case GDK_BUTTON_RELEASE:
+		if (iti->selecting && event->button.button == 1)
+			iti_stop_selecting (iti, event->button.time);
+		else
+			break;
+
+		return TRUE;
+
+	case GDK_FOCUS_CHANGE:
+		if (iti->editing && event->focus_change.in == FALSE)
+			iti_edition_accept (iti);
+
+		return TRUE;
+
+	default:
+		break;
+	}
+
+	return FALSE;
+}
+
+/* Bounds method handler for the icon text item */
+static void
+iti_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2)
+{
+	Iti *iti;
+	int width, height;
+
+	iti = ITI (item);
+
+	if (iti->ti) {
+		width = iti->ti->width + 2 * MARGIN_X;
+		height = iti->ti->height + 2 * MARGIN_Y;
+	} else {
+		width = 2 * MARGIN_X;
+		height = 2 * MARGIN_Y;
+	}
+
+	*x1 = iti->x + (iti->width - width) / 2;
+	*y1 = iti->y;
+	*x2 = *x1 + width;
+	*y2 = *y1 + height;
+}
+
+/* Class initialization function for the icon text item */
+static void
+iti_class_init (GnomeIconTextItemClass *text_item_class)
+{
+	GtkObjectClass  *object_class;
+	GnomeCanvasItemClass *item_class;
+
+	object_class = (GtkObjectClass *) text_item_class;
+	item_class   = (GnomeCanvasItemClass *) text_item_class;
+
+	parent_class = gtk_type_class (gnome_canvas_item_get_type ());
+
+	iti_signals [TEXT_CHANGED] =
+		gtk_signal_new (
+			"text_changed",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeIconTextItemClass, text_changed),
+			gtk_marshal_BOOLEAN__VOID,
+			GTK_TYPE_BOOL, 0);
+
+	iti_signals [HEIGHT_CHANGED] =
+		gtk_signal_new (
+			"height_changed",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeIconTextItemClass, height_changed),
+			gtk_marshal_VOID__VOID,
+			GTK_TYPE_NONE, 0);
+
+	iti_signals [WIDTH_CHANGED] =
+		gtk_signal_new (
+			"width_changed",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeIconTextItemClass, width_changed),
+			gtk_marshal_VOID__VOID,
+			GTK_TYPE_NONE, 0);
+
+	iti_signals[EDITING_STARTED] =
+		gtk_signal_new (
+			"editing_started",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeIconTextItemClass, editing_started),
+			gtk_marshal_VOID__VOID,
+			GTK_TYPE_NONE, 0);
+
+	iti_signals[EDITING_STOPPED] =
+		gtk_signal_new (
+			"editing_stopped",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeIconTextItemClass, editing_stopped),
+			gtk_marshal_VOID__VOID,
+			GTK_TYPE_NONE, 0);
+
+	iti_signals[SELECTION_STARTED] =
+		gtk_signal_new (
+			"selection_started",
+			GTK_RUN_FIRST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeIconTextItemClass, selection_started),
+			gtk_marshal_VOID__VOID,
+			GTK_TYPE_NONE, 0);
+
+	iti_signals[SELECTION_STOPPED] =
+		gtk_signal_new (
+			"selection_stopped",
+			GTK_RUN_FIRST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeIconTextItemClass, selection_stopped),
+			gtk_marshal_VOID__VOID,
+			GTK_TYPE_NONE, 0);
+
+
+	object_class->destroy = iti_destroy;
+
+	item_class->update = iti_update;
+	item_class->draw = iti_draw;
+	item_class->point = iti_point;
+	item_class->bounds = iti_bounds;
+	item_class->event = iti_event;
+}
+
+/* Object initialization function for the icon text item */
+static void
+iti_init (GnomeIconTextItem *iti)
+{
+	ItiPrivate *priv;
+
+	priv = g_new0 (ItiPrivate, 1);
+	iti->priv = priv;
+}
+
+/**
+ * gnome_icon_text_item_configure:
+ * @iti: An icon text item.
+ * @x: X position in which to place the item.
+ * @y: Y position in which to place the item.
+ * @width: Maximum width allowed for this item, to be used for word wrapping.
+ * @fontname: Name of the fontset that should be used to display the text.
+ * @text: Text that is going to be displayed.
+ * @is_editable: Deprecated.
+ * @is_static: Whether @text points to a static string or not.
+ *
+ * This routine is used to configure a &GnomeIconTextItem.
+ *
+ * @x and @y specify the cordinates where the item is placed inside the canvas.
+ * The @x coordinate should be the leftmost position that the icon text item can
+ * assume at any one time, that is, the left margin of the column in which the
+ * icon is to be placed.  The @y coordinate specifies the top of the icon text
+ * item.
+ *
+ * @width is the maximum width allowed for this icon text item.  The coordinates
+ * define the upper-left corner of an icon text item with maximum width; this may
+ * actually be outside the bounding box of the item if the text is narrower than
+ * the maximum width.
+ *
+ * If @is_static is true, it means that there is no need for the item to
+ * allocate memory for the string (it is a guarantee that the text is allocated
+ * by the caller and it will not be deallocated during the lifetime of this
+ * item).  This is an optimization to reduce memory usage for large icon sets.
+ */
+void
+gnome_icon_text_item_configure (GnomeIconTextItem *iti, int x, int y,
+				int width, const char *fontname,
+				const char *text,
+				gboolean is_editable, gboolean is_static)
+{
+	ItiPrivate *priv;
+
+	g_return_if_fail (iti != NULL);
+	g_return_if_fail (IS_ITI (iti));
+	g_return_if_fail (width > 2 * MARGIN_X);
+	g_return_if_fail (text != NULL);
+
+	priv = iti->priv;
+
+	iti->x = x;
+	iti->y = y;
+	iti->width = width;
+	iti->is_editable = is_editable != FALSE;
+
+	if (iti->text && iti->is_text_allocated)
+		g_free (iti->text);
+
+	iti->is_text_allocated = !is_static;
+
+	/* This cast is to shut up the compiler */
+	if (is_static)
+		iti->text = (char *) text;
+	else
+		iti->text = g_strdup (text);
+
+	if (iti->fontname)
+		g_free (iti->fontname);
+
+	iti->fontname = g_strdup (fontname ? fontname : DEFAULT_FONT_NAME);
+
+	/* FIXME: We update the font and layout here instead of in the
+	 * ::update() method because the stupid icon list makes use of iti->ti
+	 * and expects it to be valid at all times.  It should request the
+	 * item's bounds instead.
+	 */
+
+	if (priv->font)
+		gdk_font_unref (priv->font);
+
+	priv->font = NULL;
+	if (fontname)
+		priv->font = gdk_fontset_load (iti->fontname);
+	if (!priv->font)
+		priv->font = get_default_font ();
+
+	layout_text (iti);
+
+	/* Request update */
+
+	priv->need_pos_update = TRUE;
+	priv->need_font_update = TRUE;
+	priv->need_text_update = TRUE;
+	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti));
+}
+
+/**
+ * gnome_icon_text_item_setxy:
+ * @iti:  An icon text item.
+ * @x: X position.
+ * @y: Y position.
+ *
+ * Sets the coordinates at which the icon text item should be placed.
+ *
+ * See also: gnome_icon_text_item_configure().
+ */
+void
+gnome_icon_text_item_setxy (GnomeIconTextItem *iti, int x, int y)
+{
+	ItiPrivate *priv;
+
+	g_return_if_fail (iti != NULL);
+	g_return_if_fail (IS_ITI (iti));
+
+	priv = iti->priv;
+
+	iti->x = x;
+	iti->y = y;
+
+	priv->need_pos_update = TRUE;
+	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti));
+}
+
+/**
+ * gnome_icon_text_item_select:
+ * @iti: An icon text item
+ * @sel: Whether the icon text item should be displayed as selected.
+ *
+ * This function is used to control whether an icon text item is displayed as
+ * selected or not.  Mouse events are ignored by the item when it is unselected;
+ * when the user clicks on a selected icon text item, it will start the text
+ * editing process.
+ */
+void
+gnome_icon_text_item_select (GnomeIconTextItem *iti, int sel)
+{
+	ItiPrivate *priv;
+
+	g_return_if_fail (iti != NULL);
+	g_return_if_fail (IS_ITI (iti));
+
+	priv = iti->priv;
+
+	if (!iti->selected == !sel)
+		return;
+
+	iti->selected = sel ? TRUE : FALSE;
+
+	if (!iti->selected && iti->editing)
+		iti_edition_accept (iti);
+
+	priv->need_state_update = TRUE;
+	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti));
+}
+
+/**
+ * gnome_icon_text_item_get_text:
+ * @iti: An icon text item.
+ *
+ * Returns the current text string in an icon text item.  The client should not
+ * free this string, as it is internal to the icon text item.
+ */
+const char *
+gnome_icon_text_item_get_text (GnomeIconTextItem *iti)
+{
+	ItiPrivate *priv;
+
+	g_return_val_if_fail (iti != NULL, NULL);
+	g_return_val_if_fail (IS_ITI (iti), NULL);
+
+	priv = iti->priv;
+
+	if (iti->editing)
+		return gtk_entry_get_text (priv->entry);
+	else
+		return iti->text;
+}
+
+
+/**
+ * gnome_icon_text_item_start_editing:
+ * @iti: An icon text item.
+ *
+ * Starts the editing state of an icon text item.
+ **/
+void
+gnome_icon_text_item_start_editing (GnomeIconTextItem *iti)
+{
+	g_return_if_fail (iti != NULL);
+	g_return_if_fail (IS_ITI (iti));
+
+	if (iti->editing)
+		return;
+
+	iti->selected = TRUE; /* Ensure that we are selected */
+	gnome_canvas_item_grab_focus (GNOME_CANVAS_ITEM (iti));
+	iti_start_editing (iti);
+}
+
+/**
+ * gnome_icon_text_item_stop_editing:
+ * @iti: An icon text item.
+ * @accept: Whether to accept the current text or to discard it.
+ *
+ * Terminates the editing state of an icon text item.  The @accept argument
+ * controls whether the item's current text should be accepted or discarded.  If
+ * it is discarded, then the icon's original text will be restored.
+ **/
+void
+gnome_icon_text_item_stop_editing (GnomeIconTextItem *iti,
+				   gboolean accept)
+{
+	g_return_if_fail (iti != NULL);
+	g_return_if_fail (IS_ITI (iti));
+
+	if (!iti->editing)
+		return;
+
+	if (accept)
+		iti_edition_accept (iti);
+	else
+		iti_stop_editing (iti);
+}
+
+
+/**
+ * gnome_icon_text_item_get_type:
+ * @void:
+ *
+ * Registers the &GnomeIconTextItem class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value: the type ID of the &GnomeIconTextItem class.
+ **/
+GtkType
+gnome_icon_text_item_get_type (void)
+{
+	static GtkType iti_type = 0;
+
+	if (!iti_type) {
+		static const GtkTypeInfo iti_info = {
+			"GnomeIconTextItem",
+			sizeof (GnomeIconTextItem),
+			sizeof (GnomeIconTextItemClass),
+			(GtkClassInitFunc) iti_class_init,
+			(GtkObjectInitFunc) iti_init,
+			NULL, /* reserved_1 */
+			NULL, /* reserved_2 */
+			(GtkClassInitFunc) NULL
+		};
+
+		iti_type = gtk_type_unique (gnome_canvas_item_get_type (), &iti_info);
+	}
+
+	return iti_type;
+}
diff --git a/libgnomeui/gnome-icon-item.h b/libgnomeui/gnome-icon-item.h
new file mode 100644
index 0000000..200e3f2
--- /dev/null
+++ b/libgnomeui/gnome-icon-item.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+/* gnome-icon-text-item:  an editable text block with word wrapping for the
+ * GNOME canvas.
+ *
+ * Authors: Miguel de Icaza <miguel gnu org>
+ *          Federico Mena <federico gimp org>
+ */
+
+#ifndef _GNOME_ICON_TEXT_ITEM_H_
+#define _GNOME_ICON_TEXT_ITEM_H_
+
+
+#include <gtk/gtkentry.h>
+#include <libgnomecanvas/gnome-canvas.h>
+#include <libgnomeui/gnome-icon-text.h>
+
+G_BEGIN_DECLS
+
+#define GNOME_TYPE_ICON_TEXT_ITEM            (gnome_icon_text_item_get_type ())
+#define GNOME_ICON_TEXT_ITEM(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_ICON_TEXT_ITEM, GnomeIconTextItem))
+#define GNOME_ICON_TEXT_ITEM_CLASS(k)        (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_ICON_TEXT_ITEM))
+#define GNOME_IS_ICON_TEXT_ITEM(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_ICON_TEXT_ITEM))
+#define GNOME_IS_ICON_TEXT_ITEM_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_ICON_TEXT_ITEM))
+#define GNOME_ICON_TEXT_ITEM_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_ICON_TEXT_ITEM, GnomeIconTextItemClass))
+
+/* This structure has been converted to use public and private parts.  To avoid
+ * breaking binary compatibility, the slots for private fields have been
+ * replaced with padding.  Please remove these fields when gnome-libs has
+ * reached another major version and it is "fine" to break binary compatibility.
+ */
+typedef struct {
+	GnomeCanvasItem canvas_item;
+
+	/* Font name */
+	char *fontname;
+
+	/* Private data */
+	gpointer priv; /* was GtkEntry *entry */
+
+	/* Actual text */
+	char *text;
+
+	/* Text layout information */
+	GnomeIconTextInfo *ti;
+
+	/* Size and maximum allowed width */
+	int x, y;
+	int width;
+
+	/* Whether the text is being edited */
+	unsigned int editing : 1;
+
+	/* Whether the text item is selected */
+	unsigned int selected : 1;
+
+	/* Whether the user is select-dragging a block of text */
+	unsigned int selecting : 1;
+
+	/* Whether the text is editable */
+	unsigned int is_editable : 1;
+
+	/* Whether the text is allocated by us (FALSE if allocated by the client) */
+	unsigned int is_text_allocated : 1;
+} GnomeIconTextItem;
+
+typedef struct {
+	GnomeCanvasItemClass parent_class;
+
+	/* Signals we emit */
+	int  (* text_changed)      (GnomeIconTextItem *iti);
+	void (* height_changed)    (GnomeIconTextItem *iti);
+	void (* width_changed)     (GnomeIconTextItem *iti);
+	void (* editing_started)   (GnomeIconTextItem *iti);
+	void (* editing_stopped)   (GnomeIconTextItem *iti);
+	void (* selection_started) (GnomeIconTextItem *iti);
+	void (* selection_stopped) (GnomeIconTextItem *iti);
+} GnomeIconTextItemClass;
+
+GtkType  gnome_icon_text_item_get_type      (void) G_GNUC_CONST;
+
+void     gnome_icon_text_item_configure     (GnomeIconTextItem *iti,
+					     int                x,
+					     int                y,
+					     int                width,
+					     const char        *fontname,
+					     const char        *text,
+					     gboolean           is_editable,
+					     gboolean           is_static);
+
+void     gnome_icon_text_item_setxy         (GnomeIconTextItem *iti,
+					     int                x,
+					     int                y);
+
+void     gnome_icon_text_item_select        (GnomeIconTextItem *iti,
+					     int                sel);
+
+const char *gnome_icon_text_item_get_text   (GnomeIconTextItem *iti);
+
+void     gnome_icon_text_item_start_editing (GnomeIconTextItem *iti);
+void     gnome_icon_text_item_stop_editing  (GnomeIconTextItem *iti,
+					     gboolean           accept);
+
+
+G_END_DECLS
+
+#endif /* _GNOME_ICON_ITEM_H_ */
diff --git a/libgnomeui/gnome-icon-list.c b/libgnomeui/gnome-icon-list.c
new file mode 100644
index 0000000..852b121
--- /dev/null
+++ b/libgnomeui/gnome-icon-list.c
@@ -0,0 +1,2617 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+/*
+ * GnomeIconList widget - scrollable icon list
+ *
+ * Authors:
+ *    Federico Mena <federico nuclecu unam mx>
+ *    Miguel de Icaza <miguel nuclecu unam mx>
+ *
+ * Rewrote from scratch from the code written by Federico Mena
+ * <federico nuclecu unam mx> to be based on a GnomeCanvas, and
+ * to support banding selection and allow inline icon renaming.
+ *
+ * Redone somewhat by Elliot to support gdk-pixbuf, and to use GArray instead of GList for item storage.
+ */
+
+#include <config.h>
+#include <string.h>
+#include <stdio.h>
+#include <gtk/gtk.h>
+#include "gnome-icon-list.h"
+#include "gnome-icon-item.h"
+#include <libgnomecanvas/gnome-canvas-pixbuf.h>
+#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
+
+#include <libgnomeuiP.h>
+
+/* Aliases to minimize screen use in my laptop */
+#define GIL(x)       GNOME_ICON_LIST(x)
+#define GIL_CLASS(x) GNOME_ICON_LIST_CLASS(x)
+#define IS_GIL(x)    GNOME_IS_ICON_LIST(x)
+
+typedef GnomeIconList Gil;
+typedef GnomeIconListClass GilClass;
+
+
+/* default spacings */
+#define DEFAULT_ROW_SPACING  4
+#define DEFAULT_COL_SPACING  2
+#define DEFAULT_TEXT_SPACING 2
+#define DEFAULT_ICON_BORDER  2
+
+/* Autoscroll timeout in milliseconds */
+#define SCROLL_TIMEOUT 30
+
+
+/* Signals */
+enum {
+	SELECT_ICON,
+	UNSELECT_ICON,
+	TEXT_CHANGED,
+	LAST_SIGNAL
+};
+
+typedef enum {
+	SYNC_INSERT,
+	SYNC_REMOVE
+} SyncType;
+
+static guint gil_signals[LAST_SIGNAL] = { 0 };
+
+
+static GtkContainerClass *parent_class;
+
+
+/* Icon structure */
+typedef struct {
+	/* Icon image and text items */
+	GnomeCanvasPixbuf *image;
+	GnomeIconTextItem *text;
+
+	/* Filename of the icon file. */
+	gchar *icon_filename;
+
+	/* User data and destroy notify function */
+	gpointer data;
+	GtkDestroyNotify destroy;
+
+	/* ID for the text item's event signal handler */
+	guint text_event_id;
+
+	/* Whether the icon is selected, and temporary storage for rubberband
+         * selections.
+	 */
+	guint selected : 1;
+	guint tmp_selected : 1;
+} Icon;
+
+/* A row of icons */
+typedef struct {
+	GList *line_icons;
+	gint16 y;
+	gint16 icon_height, text_height;
+} IconLine;
+
+/* Private data of the GnomeIconList structure */
+struct _GnomeIconListPrivate {
+	/* List of icons */
+	GArray *icon_list;
+
+	/* List of rows of icons */
+	GList *lines;
+
+	/* Separators used to wrap the text below icons */
+	char *separators;
+
+	Icon *last_selected_icon;
+
+	/* Rubberband rectangle */
+	GnomeCanvasItem *sel_rect;
+
+	/* Saved event for a pending selection */
+	GdkEvent select_pending_event;
+
+	/* Max of the height of all the icon rows and window height */
+	int total_height;
+
+	/* Selection mode */
+	GtkSelectionMode selection_mode;
+
+	/* A list of integers with the indices of the currently selected icons */
+	GList *selection;
+
+	/* Number of icons in the list */
+	int icons;
+
+	/* Freeze count */
+	int frozen;
+
+	/* Width allocated for icons */
+	int icon_width;
+
+	/* Spacing values */
+	int row_spacing;
+	int col_spacing;
+	int text_spacing;
+	int icon_border;
+
+	/* Index and pointer to last selected icon */
+	int last_selected_idx;
+
+	/* Timeout ID for autoscrolling */
+	guint timer_tag;
+
+	/* Change the adjustment value by this amount when autoscrolling */
+	int value_diff;
+
+	/* Mouse position for autoscrolling */
+	int event_last_x;
+	int event_last_y;
+
+	/* Selection start position */
+	int sel_start_x;
+	int sel_start_y;
+
+	/* Modifier state when the selection began */
+	guint sel_state;
+
+	/* Whether the icon texts are editable */
+	guint is_editable : 1;
+
+	/* Whether the icon texts need to be copied */
+	guint static_text : 1;
+
+	/* Whether the icons need to be laid out */
+	guint dirty : 1;
+
+	/* Whether the user is performing a rubberband selection */
+	guint selecting : 1;
+
+	/* Whether editing an icon is pending after a button press */
+	guint edit_pending : 1;
+
+	/* Whether selection is pending after a button press */
+	guint select_pending : 1;
+
+	/* Whether the icon that is pending selection was selected to begin with */
+	guint select_pending_was_selected : 1;
+};
+
+
+static inline int
+icon_line_height (Gil *gil, IconLine *il)
+{
+	GnomeIconListPrivate *priv;
+
+	priv = gil->_priv;
+
+	return il->icon_height + il->text_height + priv->row_spacing + priv->text_spacing;
+}
+
+static void
+icon_get_height (Icon *icon, int *icon_height, int *text_height)
+{
+	double d_icon_height;
+	gtk_object_get(GTK_OBJECT(icon->image), "height", &d_icon_height, NULL);
+	*icon_height = d_icon_height;
+	*text_height = icon->text->ti->height;
+}
+
+static int
+gil_get_items_per_line (Gil *gil)
+{
+	GnomeIconListPrivate *priv;
+	int items_per_line;
+
+	priv = gil->_priv;
+
+	items_per_line = GTK_WIDGET (gil)->allocation.width / (priv->icon_width + priv->col_spacing);
+	if (items_per_line == 0)
+		items_per_line = 1;
+
+	return items_per_line;
+}
+
+/**
+ * gnome_icon_list_get_items_per_line:
+ * @gil: An icon list.
+ *
+ * Returns the number of icons that fit in a line or row.
+ */
+int
+gnome_icon_list_get_items_per_line (GnomeIconList *gil)
+{
+	g_return_val_if_fail (gil != NULL, 1);
+	g_return_val_if_fail (IS_GIL (gil), 1);
+
+	return gil_get_items_per_line (gil);
+}
+
+static void
+gil_place_icon (Gil *gil, Icon *icon, int x, int y, int icon_height)
+{
+	GnomeIconListPrivate *priv;
+	int x_offset, y_offset;
+	double d_icon_image_height;
+	double d_icon_image_width;
+	int icon_image_height;
+	int icon_image_width;
+
+	priv = gil->_priv;
+
+	gtk_object_get(GTK_OBJECT(icon->image), "height", &d_icon_image_height, NULL);
+	icon_image_height = d_icon_image_height;
+	g_assert(icon_image_height != 0);
+	if (icon_height > icon_image_height)
+		y_offset = (icon_height - icon_image_height) / 2;
+	else
+		y_offset = 0;
+
+	gtk_object_get(GTK_OBJECT(icon->image), "width", &d_icon_image_width, NULL);
+	icon_image_width = d_icon_image_width;
+	g_assert(icon_image_width != 0);
+	if (priv->icon_width > icon_image_width)
+		x_offset = (priv->icon_width - icon_image_width) / 2;
+	else
+		x_offset = 0;
+
+	gnome_canvas_item_set (GNOME_CANVAS_ITEM (icon->image),
+			       "x",  (double) (x + x_offset),
+			       "y",  (double) (y + y_offset),
+			       "x_set", TRUE,
+			       "y_set", TRUE,
+			       NULL);
+	gnome_icon_text_item_setxy (icon->text,
+				    x,
+				    y + icon_height + priv->text_spacing);
+}
+
+static void
+gil_layout_line (Gil *gil, IconLine *il)
+{
+	GnomeIconListPrivate *priv;
+	GList *l;
+	int x;
+
+	priv = gil->_priv;
+
+	x = 0;
+	for (l = il->line_icons; l; l = l->next) {
+		Icon *icon = l->data;
+
+		gil_place_icon (gil, icon, x, il->y, il->icon_height);
+		x += priv->icon_width + priv->col_spacing;
+	}
+}
+
+static void
+gil_add_and_layout_line (Gil *gil, GList *line_icons, int y,
+			 int icon_height, int text_height)
+{
+	GnomeIconListPrivate *priv;
+	IconLine *il;
+
+	priv = gil->_priv;
+
+	il = g_new (IconLine, 1);
+	il->line_icons = line_icons;
+	il->y = y;
+	il->icon_height = icon_height;
+	il->text_height = text_height;
+
+	gil_layout_line (gil, il);
+	priv->lines = g_list_append (priv->lines, il);
+}
+
+static void
+gil_relayout_icons_at (Gil *gil, int pos, int y)
+{
+	GnomeIconListPrivate *priv;
+	int col, row, text_height, icon_height;
+	int items_per_line, n;
+	GList *line_icons;
+
+	priv = gil->_priv;
+	items_per_line = gil_get_items_per_line (gil);
+
+	col = row = text_height = icon_height = 0;
+	line_icons = NULL;
+
+	for (n = pos; n < priv->icon_list->len; n++) {
+		Icon *icon = g_array_index(priv->icon_list, Icon*, n);
+		int ih, th;
+
+		if (!(n % items_per_line)) {
+			if (line_icons) {
+				gil_add_and_layout_line (gil, line_icons, y,
+							 icon_height, text_height);
+				line_icons = NULL;
+
+				y += (icon_height + text_height
+				      + priv->row_spacing + priv->text_spacing);
+			}
+
+			icon_height = 0;
+			text_height = 0;
+		}
+
+		icon_get_height (icon, &ih, &th);
+
+		icon_height = MAX (ih, icon_height);
+		text_height = MAX (th, text_height);
+
+		line_icons = g_list_append (line_icons, icon);
+	}
+
+	if (line_icons)
+		gil_add_and_layout_line (gil, line_icons, y, icon_height, text_height);
+}
+
+static void
+gil_free_line_info (Gil *gil)
+{
+	GnomeIconListPrivate *priv;
+	GList *l;
+
+	priv = gil->_priv;
+
+	for (l = priv->lines; l; l = l->next) {
+		IconLine *il = l->data;
+
+		g_list_free (il->line_icons);
+		g_free (il);
+	}
+
+	g_list_free (priv->lines);
+	priv->lines = NULL;
+	priv->total_height = 0;
+}
+
+static void
+gil_free_line_info_from (Gil *gil, int first_line)
+{
+	GnomeIconListPrivate *priv;
+	GList *l, *ll;
+
+	priv = gil->_priv;
+	ll = g_list_nth (priv->lines, first_line);
+
+	for (l = ll; l; l = l->next) {
+		IconLine *il = l->data;
+
+		g_list_free (il->line_icons);
+		g_free (il);
+	}
+
+	if (priv->lines) {
+		if (ll->prev)
+			ll->prev->next = NULL;
+		else
+			priv->lines = NULL;
+	}
+
+	g_list_free (ll);
+}
+
+static void
+gil_layout_from_line (Gil *gil, int line)
+{
+	GnomeIconListPrivate *priv;
+	GList *l;
+	int height;
+
+	priv = gil->_priv;
+
+	gil_free_line_info_from (gil, line);
+
+	height = 0;
+	for (l = priv->lines; l; l = l->next) {
+		IconLine *il = l->data;
+
+		height += icon_line_height (gil, il);
+	}
+
+	gil_relayout_icons_at (gil, line * gil_get_items_per_line (gil), height);
+}
+
+static void
+gil_layout_all_icons (Gil *gil)
+{
+	GnomeIconListPrivate *priv;
+
+	priv = gil->_priv;
+
+	if (!GTK_WIDGET_REALIZED (gil))
+		return;
+
+	gil_free_line_info (gil);
+	gil_relayout_icons_at (gil, 0, 0);
+	priv->dirty = FALSE;
+}
+
+static void
+gil_scrollbar_adjust (Gil *gil)
+{
+	GnomeIconListPrivate *priv;
+	GtkAdjustment *adj;
+	GList *l;
+	double wx, wy, wx1, wy1, wx2, wy2;
+	int height, step_increment;
+
+	priv = gil->_priv;
+
+	if (!GTK_WIDGET_REALIZED (gil))
+		return;
+
+	height = 0;
+	step_increment = 0;
+	for (l = priv->lines; l; l = l->next) {
+		IconLine *il = l->data;
+
+		height += icon_line_height (gil, il);
+
+		if (l == priv->lines)
+			step_increment = height;
+	}
+
+	if (!step_increment)
+		step_increment = 10;
+
+	priv->total_height = MAX (height, GTK_WIDGET (gil)->allocation.height);
+
+	gnome_canvas_c2w (GNOME_CANVAS (gil), 0, 0, &wx1, &wy1);
+	gnome_canvas_c2w (GNOME_CANVAS (gil),
+			  GTK_WIDGET (gil)->allocation.width,
+			  priv->total_height,
+			  &wx2, &wy2);
+
+	gnome_canvas_set_scroll_region (GNOME_CANVAS (gil),
+					wx1, wy1, wx2, wy2);
+
+	wx = wy = 0;
+	gnome_canvas_window_to_world (GNOME_CANVAS (gil), 0, 0, &wx, &wy);
+
+	adj = gtk_layout_get_vadjustment (GTK_LAYOUT (gil));
+
+	adj->upper = priv->total_height;
+	adj->step_increment = step_increment;
+	adj->page_increment = GTK_WIDGET (gil)->allocation.height;
+	adj->page_size = GTK_WIDGET (gil)->allocation.height;
+
+	if (wy > adj->upper - adj->page_size)
+		wy = adj->upper - adj->page_size;
+
+	adj->value = wy;
+
+	gtk_adjustment_changed (adj);
+}
+
+/* Emits the select_icon or unselect_icon signals as appropriate */
+static void
+emit_select (Gil *gil, int sel, int i, GdkEvent *event)
+{
+	gtk_signal_emit (GTK_OBJECT (gil),
+			 gil_signals[sel ? SELECT_ICON : UNSELECT_ICON],
+			 i,
+			 event);
+}
+
+static int
+gil_unselect_all (GnomeIconList *gil, GdkEvent *event, gpointer keep)
+{
+	GnomeIconListPrivate *priv;
+	Icon *icon;
+	int i, idx = 0;
+
+	g_return_val_if_fail (gil != NULL, 0);
+	g_return_val_if_fail (IS_GIL (gil), 0);
+
+	priv = gil->_priv;
+
+	for (i = 0; i < priv->icon_list->len; i++) {
+		icon = g_array_index(priv->icon_list, Icon*, i);
+
+		if (icon == keep)
+			idx = i;
+		else if (icon->selected)
+			emit_select (gil, FALSE, i, event);
+	}
+
+	return idx;
+}
+
+/**
+ * gnome_icon_list_unselect_all:
+ * @gil:   An icon list.
+ *
+ * Returns: the number of icons in the icon list
+ */
+int
+gnome_icon_list_unselect_all (GnomeIconList *gil)
+{
+	return gil_unselect_all (gil, NULL, NULL);
+}
+
+static void
+sync_selection (Gil *gil, int pos, SyncType type)
+{
+	GList *list;
+
+	for (list = gil->_priv->selection; list; list = list->next) {
+		if (GPOINTER_TO_INT (list->data) >= pos) {
+			int i = GPOINTER_TO_INT (list->data);
+
+			switch (type) {
+			case SYNC_INSERT:
+				list->data = GINT_TO_POINTER (i + 1);
+				break;
+
+			case SYNC_REMOVE:
+				list->data = GINT_TO_POINTER (i - 1);
+				break;
+
+			default:
+				g_assert_not_reached ();
+			}
+		}
+	}
+}
+
+static int
+gil_icon_to_index (Gil *gil, Icon *icon)
+{
+	GnomeIconListPrivate *priv;
+	int n;
+
+	priv = gil->_priv;
+
+	for (n = 0; n < priv->icon_list->len; n++)
+		if (g_array_index(priv->icon_list, Icon*, n) == icon)
+			return n;
+
+	g_assert_not_reached ();
+	return -1; /* Shut up the compiler */
+}
+
+/* Event handler for icons when we are in SINGLE or BROWSE mode */
+static gint
+selection_one_icon_event (Gil *gil, Icon *icon, int idx, int on_text, GdkEvent *event)
+{
+	GnomeIconListPrivate *priv;
+	GnomeIconTextItem *text;
+	int retval;
+
+	priv = gil->_priv;
+	retval = FALSE;
+
+	/* We use a separate variable and ref the object because it may be
+	 * destroyed by one of the signal handlers.
+	 */
+	text = icon->text;
+	gtk_object_ref (GTK_OBJECT (text));
+
+	switch (event->type) {
+	case GDK_BUTTON_PRESS:
+		priv->edit_pending = FALSE;
+		priv->select_pending = FALSE;
+
+		/* Ignore wheel mouse clicks for now */
+		if (event->button.button > 3)
+			break;
+
+		if (!icon->selected) {
+			gil_unselect_all (gil, NULL, NULL);
+			emit_select (gil, TRUE, idx, event);
+		} else {
+			if (priv->selection_mode == GTK_SELECTION_SINGLE
+			    && (event->button.state & GDK_CONTROL_MASK))
+				emit_select (gil, FALSE, idx, event);
+			else if (on_text && priv->is_editable && event->button.button == 1)
+				priv->edit_pending = TRUE;
+			else
+				emit_select (gil, TRUE, idx, event);
+		}
+
+		retval = TRUE;
+		break;
+
+	case GDK_2BUTTON_PRESS:
+	case GDK_3BUTTON_PRESS:
+		/* Ignore wheel mouse clicks for now */
+		if (event->button.button > 3)
+			break;
+
+		emit_select (gil, TRUE, idx, event);
+		retval = TRUE;
+		break;
+
+	case GDK_BUTTON_RELEASE:
+		if (priv->edit_pending) {
+			gnome_icon_text_item_start_editing (text);
+			priv->edit_pending = FALSE;
+		}
+
+		retval = TRUE;
+		break;
+
+	default:
+		break;
+	}
+
+	/* If the click was on the text and we actually did something, stop the
+	 * icon text item's own handler from executing.
+	 */
+	if (on_text && retval)
+		gtk_signal_emit_stop_by_name (GTK_OBJECT (text), "event");
+
+	gtk_object_unref (GTK_OBJECT (text));
+
+	return retval;
+}
+
+/* Handles range selections when clicking on an icon */
+static void
+select_range (Gil *gil, Icon *icon, int idx, GdkEvent *event)
+{
+	GnomeIconListPrivate *priv;
+	int a, b;
+	Icon *i;
+
+	priv = gil->_priv;
+
+	if (priv->last_selected_idx == -1) {
+		priv->last_selected_idx = idx;
+		priv->last_selected_icon = icon;
+	}
+
+	if (idx < priv->last_selected_idx) {
+		a = idx;
+		b = priv->last_selected_idx;
+	} else {
+		a = priv->last_selected_idx;
+		b = idx;
+	}
+
+	for (; a <= b; a++) {
+		i = g_array_index(priv->icon_list, Icon*, a);
+
+		if (!i->selected)
+			emit_select (gil, TRUE, a, NULL);
+	}
+
+	/* Actually notify the client of the event */
+	emit_select (gil, TRUE, idx, event);
+}
+
+/* Handles icon selection for MULTIPLE or EXTENDED selection modes */
+static void
+do_select_many (Gil *gil, Icon *icon, int idx, GdkEvent *event, int use_event)
+{
+	GnomeIconListPrivate *priv;
+	int range, additive;
+
+	priv = gil->_priv;
+
+	range = (event->button.state & GDK_SHIFT_MASK) != 0;
+	additive = (event->button.state & GDK_CONTROL_MASK) != 0;
+
+	if (!additive) {
+		if (icon->selected)
+			gil_unselect_all (gil, NULL, icon);
+		else
+			gil_unselect_all (gil, NULL, NULL);
+	}
+
+	if (!range) {
+		if (additive)
+			emit_select (gil, !icon->selected, idx, use_event ? event : NULL);
+		else
+			emit_select (gil, TRUE, idx, use_event ? event : NULL);
+
+		priv->last_selected_idx = idx;
+		priv->last_selected_icon = icon;
+	} else
+		select_range (gil, icon, idx, use_event ? event : NULL);
+}
+
+/* Event handler for icons when we are in MULTIPLE or EXTENDED mode */
+static gint
+selection_many_icon_event (Gil *gil, Icon *icon, int idx, int on_text, GdkEvent *event)
+{
+	GnomeIconListPrivate *priv;
+	GnomeIconTextItem *text;
+	int retval;
+	int additive, range;
+	int do_select;
+
+	priv = gil->_priv;
+	retval = FALSE;
+
+	/* We use a separate variable and ref the object because it may be
+	 * destroyed by one of the signal handlers.
+	 */
+	text = icon->text;
+	gtk_object_ref (GTK_OBJECT (text));
+
+	range = (event->button.state & GDK_SHIFT_MASK) != 0;
+	additive = (event->button.state & GDK_CONTROL_MASK) != 0;
+
+	switch (event->type) {
+	case GDK_BUTTON_PRESS:
+		priv->edit_pending = FALSE;
+		priv->select_pending = FALSE;
+
+		/* Ignore wheel mouse clicks for now */
+		if (event->button.button > 3)
+			break;
+
+		do_select = TRUE;
+
+		if (additive || range) {
+			if (additive && !range) {
+				priv->select_pending = TRUE;
+				priv->select_pending_event = *event;
+				priv->select_pending_was_selected = icon->selected;
+
+				/* We have to emit this so that the client will
+				 * know about the click.
+				 */
+				emit_select (gil, TRUE, idx, event);
+				do_select = FALSE;
+			}
+		} else if (icon->selected) {
+			priv->select_pending = TRUE;
+			priv->select_pending_event = *event;
+			priv->select_pending_was_selected = icon->selected;
+
+			if (on_text && priv->is_editable && event->button.button == 1)
+				priv->edit_pending = TRUE;
+
+			emit_select (gil, TRUE, idx, event);
+			do_select = FALSE;
+		}
+#if 0
+		} else if (icon->selected && on_text && priv->is_editable
+			   && event->button.button == 1) {
+			priv->edit_pending = TRUE;
+			do_select = FALSE;
+		}
+#endif
+
+		if (do_select)
+			do_select_many (gil, icon, idx, event, TRUE);
+
+		retval = TRUE;
+		break;
+
+	case GDK_2BUTTON_PRESS:
+	case GDK_3BUTTON_PRESS:
+		/* Ignore wheel mouse clicks for now */
+		if (event->button.button > 3)
+			break;
+
+		emit_select (gil, TRUE, idx, event);
+		retval = TRUE;
+		break;
+
+	case GDK_BUTTON_RELEASE:
+		if (priv->select_pending) {
+			icon->selected = priv->select_pending_was_selected;
+			do_select_many (gil, icon, idx, &priv->select_pending_event, FALSE);
+			priv->select_pending = FALSE;
+			retval = TRUE;
+		}
+
+		if (priv->edit_pending) {
+			gnome_icon_text_item_start_editing (text);
+			priv->edit_pending = FALSE;
+			retval = TRUE;
+		}
+#if 0
+		if (priv->select_pending) {
+			icon->selected = priv->select_pending_was_selected;
+			do_select_many (gil, icon, idx, &priv->select_pending_event);
+			priv->select_pending = FALSE;
+			retval = TRUE;
+		} else if (priv->edit_pending) {
+			gnome_icon_text_item_start_editing (text);
+			priv->edit_pending = FALSE;
+			retval = TRUE;
+		}
+#endif
+
+		break;
+
+	default:
+		break;
+	}
+
+	/* If the click was on the text and we actually did something, stop the
+	 * icon text item's own handler from executing.
+	 */
+	if (on_text && retval)
+		gtk_signal_emit_stop_by_name (GTK_OBJECT (text), "event");
+
+	gtk_object_unref (GTK_OBJECT (text));
+
+	return retval;
+}
+
+/* Event handler for icons in the icon list */
+static gint
+icon_event (GnomeCanvasItem *item, GdkEvent *event, gpointer data)
+{
+	Icon *icon;
+	Gil *gil;
+	GnomeIconListPrivate *priv;
+	int idx;
+	int on_text;
+
+	icon = data;
+	gil = GIL (item->canvas);
+	priv = gil->_priv;
+	idx = gil_icon_to_index (gil, icon);
+	on_text = item == GNOME_CANVAS_ITEM (icon->text);
+
+	switch (priv->selection_mode) {
+	case GTK_SELECTION_SINGLE:
+	case GTK_SELECTION_BROWSE:
+		return selection_one_icon_event (gil, icon, idx, on_text, event);
+
+	case GTK_SELECTION_MULTIPLE:
+	case GTK_SELECTION_EXTENDED:
+		return selection_many_icon_event (gil, icon, idx, on_text, event);
+
+	default:
+		g_assert_not_reached ();
+		return FALSE; /* Shut up the compiler */
+	}
+}
+
+/* Handler for the editing_started signal of an icon text item.  We block the
+ * event handler so that it will not be called while the text is being edited.
+ */
+static void
+editing_started (GnomeIconTextItem *iti, gpointer data)
+{
+	Icon *icon;
+
+	icon = data;
+	gtk_signal_handler_block (GTK_OBJECT (iti), icon->text_event_id);
+	gil_unselect_all (GIL (GNOME_CANVAS_ITEM (iti)->canvas), NULL, icon);
+}
+
+/* Handler for the editing_stopped signal of an icon text item.  We unblock the
+ * event handler so that we can get events from it again.
+ */
+static void
+editing_stopped (GnomeIconTextItem *iti, gpointer data)
+{
+	Icon *icon;
+
+	icon = data;
+	gtk_signal_handler_unblock (GTK_OBJECT (iti), icon->text_event_id);
+}
+
+static gboolean
+text_changed (GnomeCanvasItem *item, Icon *icon)
+{
+	Gil *gil;
+	gboolean accept;
+	int idx;
+
+	gil = GIL (item->canvas);
+	accept = TRUE;
+
+	idx = gil_icon_to_index (gil, icon);
+	gtk_signal_emit (GTK_OBJECT (gil),
+			 gil_signals[TEXT_CHANGED],
+			 idx, gnome_icon_text_item_get_text (icon->text),
+			 &accept);
+
+	return accept;
+}
+
+static void
+height_changed (GnomeCanvasItem *item, Icon *icon)
+{
+	Gil *gil;
+	GnomeIconListPrivate *priv;
+	int n;
+
+	gil = GIL (item->canvas);
+	priv = gil->_priv;
+
+	if (!GTK_WIDGET_REALIZED (gil))
+		return;
+
+	if (priv->frozen) {
+		priv->dirty = TRUE;
+		return;
+	}
+
+	n = gil_icon_to_index (gil, icon);
+	gil_layout_from_line (gil, n / gil_get_items_per_line (gil));
+	gil_scrollbar_adjust (gil);
+}
+
+static Icon *
+icon_new_from_pixbuf (GnomeIconList *gil, GdkPixbuf *im,
+		      const char *icon_filename, const char *text)
+{
+	GnomeIconListPrivate *priv;
+	GnomeCanvas *canvas;
+	GnomeCanvasGroup *group;
+	Icon *icon;
+
+	priv = gil->_priv;
+	canvas = GNOME_CANVAS (gil);
+	group = GNOME_CANVAS_GROUP (canvas->root);
+
+	icon = g_new0 (Icon, 1);
+
+	icon->icon_filename = g_strdup (icon_filename);
+
+	icon->image = GNOME_CANVAS_PIXBUF (gnome_canvas_item_new (
+		group,
+		gnome_canvas_pixbuf_get_type (),
+		"x", 0.0,
+		"y", 0.0,
+		"width", (double) gdk_pixbuf_get_width (im),
+		"height", (double) gdk_pixbuf_get_height (im),
+		"pixbuf", im,
+		NULL));
+
+	icon->text = GNOME_ICON_TEXT_ITEM (gnome_canvas_item_new (
+		group,
+		gnome_icon_text_item_get_type (),
+		NULL));
+
+	gnome_canvas_item_set (GNOME_CANVAS_ITEM (icon->text),
+			       "use_broken_event_handling", FALSE,
+			       NULL);
+
+	gnome_icon_text_item_configure (icon->text,
+					0, 0, priv->icon_width, NULL,
+					text, priv->is_editable, priv->static_text);
+
+	gtk_signal_connect (GTK_OBJECT (icon->image), "event",
+			    GTK_SIGNAL_FUNC (icon_event),
+			    icon);
+	icon->text_event_id = gtk_signal_connect (GTK_OBJECT (icon->text), "event",
+						  GTK_SIGNAL_FUNC (icon_event),
+						  icon);
+
+	gtk_signal_connect (GTK_OBJECT (icon->text), "editing_started",
+			    GTK_SIGNAL_FUNC (editing_started),
+			    icon);
+	gtk_signal_connect (GTK_OBJECT (icon->text), "editing_stopped",
+			    GTK_SIGNAL_FUNC (editing_stopped),
+			    icon);
+
+	gtk_signal_connect (GTK_OBJECT (icon->text), "text_changed",
+			    GTK_SIGNAL_FUNC (text_changed),
+			    icon);
+	gtk_signal_connect (GTK_OBJECT (icon->text), "height_changed",
+			    GTK_SIGNAL_FUNC (height_changed),
+			    icon);
+
+	return icon;
+}
+
+static Icon *
+icon_new (Gil *gil, const char *icon_filename, const char *text)
+{
+	GdkPixbuf *im;
+	Icon *retval;
+
+	if (icon_filename)
+		im = gdk_pixbuf_new_from_file (icon_filename, NULL);
+	else
+		im = NULL;
+
+	retval = icon_new_from_pixbuf (gil, im, icon_filename, text);
+
+	if(im)
+		gdk_pixbuf_unref(im);
+
+	return retval;
+}
+
+static int
+icon_list_append (Gil *gil, Icon *icon)
+{
+	GnomeIconListPrivate *priv;
+	int pos;
+
+	priv = gil->_priv;
+
+	pos = priv->icons++;
+	g_array_append_val(priv->icon_list, icon);
+
+	switch (priv->selection_mode) {
+	case GTK_SELECTION_BROWSE:
+		gnome_icon_list_select_icon (gil, 0);
+		break;
+
+	default:
+		break;
+	}
+
+	if (!priv->frozen) {
+		/* FIXME: this should only layout the last line */
+		gil_layout_all_icons (gil);
+		gil_scrollbar_adjust (gil);
+	} else
+		priv->dirty = TRUE;
+
+	return priv->icons - 1;
+}
+
+static void
+icon_list_insert (Gil *gil, int pos, Icon *icon)
+{
+	GnomeIconListPrivate *priv;
+
+	priv = gil->_priv;
+
+	if (pos == priv->icons) {
+		icon_list_append (gil, icon);
+		return;
+	}
+
+	g_array_insert_val(priv->icon_list, pos, icon);
+	priv->icons++;
+
+	switch (priv->selection_mode) {
+	case GTK_SELECTION_BROWSE:
+		gnome_icon_list_select_icon (gil, 0);
+		break;
+
+	default:
+		break;
+	}
+
+	if (!priv->frozen) {
+		/* FIXME: this should only layout the lines from then one
+		 * containing the Icon to the end.
+		 */
+		gil_layout_all_icons (gil);
+		gil_scrollbar_adjust (gil);
+	} else
+		priv->dirty = TRUE;
+
+	sync_selection (gil, pos, SYNC_INSERT);
+}
+
+/**
+ * gnome_icon_list_insert_pixbuf:
+ * @gil:      An icon list.
+ * @pos:      Position at which the new icon should be inserted.
+ * @im:       Pixbuf image with the icon image.
+ * @filename: Filename of the image file.
+ * @text:     Text to be used for the icon's caption.
+ *
+ * Inserts an icon in the specified icon list.  The icon is created from the
+ * specified Imlib image, and it is inserted at the @pos index.
+ */
+void
+gnome_icon_list_insert_pixbuf (GnomeIconList *gil, int pos, GdkPixbuf *im,
+			       const char *icon_filename, const char *text)
+{
+	Icon *icon;
+
+	g_return_if_fail (gil != NULL);
+	g_return_if_fail (IS_GIL (gil));
+	g_return_if_fail (im != NULL);
+
+	icon = icon_new_from_pixbuf (gil, im, icon_filename, text);
+	icon_list_insert (gil, pos, icon);
+	return;
+}
+
+/**
+ * gnome_icon_list_insert:
+ * @gil:           An icon list.
+ * @pos:           Position at which the new icon should be inserted.
+ * @icon_filename: Name of the file that holds the icon's image.
+ * @text:          Text to be used for the icon's caption.
+ *
+ * Inserts an icon in the specified icon list.  The icon's image is loaded
+ * from the specified file, and it is inserted at the @pos index.
+ */
+void
+gnome_icon_list_insert (GnomeIconList *gil, int pos, const char *icon_filename, const char *text)
+{
+	Icon *icon;
+
+	g_return_if_fail (gil != NULL);
+	g_return_if_fail (IS_GIL (gil));
+
+	icon = icon_new (gil, icon_filename, text);
+	icon_list_insert (gil, pos, icon);
+	return;
+}
+
+/**
+ * gnome_icon_list_append_pixbuf:
+ * @gil:      An icon list.
+ * @im:       Pixbuf image with the icon image.
+ * @filename: Filename of the image file.
+ * @text:     Text to be used for the icon's caption.
+ *
+ * Appends an icon to the specified icon list.  The icon is created from
+ * the specified Imlib image.
+ */
+int
+gnome_icon_list_append_pixbuf (GnomeIconList *gil, GdkPixbuf *im,
+			       const char *icon_filename, const char *text)
+{
+	Icon *icon;
+
+	g_return_val_if_fail (gil != NULL, -1);
+	g_return_val_if_fail (IS_GIL (gil), -1);
+	g_return_val_if_fail (im != NULL, -1);
+
+	icon = icon_new_from_pixbuf (gil, im, icon_filename, text);
+	return icon_list_append (gil, icon);
+}
+
+/**
+ * gnome_icon_list_append:
+ * @gil:           An icon list.
+ * @icon_filename: Name of the file that holds the icon's image.
+ * @text:          Text to be used for the icon's caption.
+ *
+ * Appends an icon to the specified icon list.  The icon's image is loaded from
+ * the specified file, and it is inserted at the @pos index.
+ */
+int
+gnome_icon_list_append (GnomeIconList *gil, const char *icon_filename,
+			const char *text)
+{
+	Icon *icon;
+
+	g_return_val_if_fail (gil != NULL, -1);
+	g_return_val_if_fail (IS_GIL (gil), -1);
+
+	icon = icon_new (gil, icon_filename, text);
+	return icon_list_append (gil, icon);
+}
+
+static void
+icon_destroy (Icon *icon)
+{
+	if (icon->destroy)
+		(* icon->destroy) (icon->data);
+
+	g_free (icon->icon_filename);
+
+	gtk_object_destroy (GTK_OBJECT (icon->image));
+	gtk_object_destroy (GTK_OBJECT (icon->text));
+	g_free (icon);
+}
+
+/**
+ * gnome_icon_list_remove:
+ * @gil: An icon list.
+ * @pos: Index of the icon that should be removed.
+ *
+ * Removes the icon at index position @pos.  If a destroy handler was specified
+ * for that icon, it will be called with the appropriate data.
+ */
+void
+gnome_icon_list_remove (GnomeIconList *gil, int pos)
+{
+	GnomeIconListPrivate *priv;
+	int was_selected;
+	Icon *icon;
+
+	g_return_if_fail (gil != NULL);
+	g_return_if_fail (IS_GIL (gil));
+	g_return_if_fail (pos >= 0 && pos < gil->_priv->icons);
+
+	priv = gil->_priv;
+
+	was_selected = FALSE;
+
+	icon = g_array_index(priv->icon_list, Icon*, pos);
+
+	if (icon->selected) {
+		was_selected = TRUE;
+
+		switch (priv->selection_mode) {
+		case GTK_SELECTION_SINGLE:
+		case GTK_SELECTION_BROWSE:
+		case GTK_SELECTION_MULTIPLE:
+		case GTK_SELECTION_EXTENDED:
+			gnome_icon_list_unselect_icon (gil, pos);
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	g_array_remove_index(priv->icon_list, pos);
+	priv->icons--;
+
+	sync_selection (gil, pos, SYNC_REMOVE);
+
+	if (was_selected) {
+		switch (priv->selection_mode) {
+		case GTK_SELECTION_BROWSE:
+			if (pos == priv->icons)
+				gnome_icon_list_select_icon (gil, pos - 1);
+			else
+				gnome_icon_list_select_icon (gil, pos);
+
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	if (priv->icons >= priv->last_selected_idx)
+		priv->last_selected_idx = -1;
+
+	if (priv->last_selected_icon == icon)
+		priv->last_selected_icon = NULL;
+
+	icon_destroy (icon);
+
+	if (!priv->frozen) {
+		/* FIXME: Optimize, only re-layout from pos to end */
+		gil_layout_all_icons (gil);
+		gil_scrollbar_adjust (gil);
+	} else
+		priv->dirty = TRUE;
+}
+
+/**
+ * gnome_icon_list_clear:
+ * @gil: An icon list.
+ *
+ * Clears the contents for the icon list by removing all the icons.  If destroy
+ * handlers were specified for any of the icons, they will be called with the
+ * appropriate data.
+ */
+void
+gnome_icon_list_clear (GnomeIconList *gil)
+{
+	GnomeIconListPrivate *priv;
+	int i;
+
+	g_return_if_fail (gil != NULL);
+	g_return_if_fail (IS_GIL (gil));
+
+	priv = gil->_priv;
+
+	for (i = 0; i < priv->icon_list->len; i++)
+		icon_destroy (g_array_index (priv->icon_list, Icon*, i));
+
+	gil_free_line_info (gil);
+
+	g_list_free (priv->selection);
+	priv->selection = NULL;
+	g_array_set_size(priv->icon_list, 0);
+	priv->icons = 0;
+	priv->last_selected_idx = -1;
+	priv->last_selected_icon = NULL;
+
+	if (!priv->frozen) {
+		gil_layout_all_icons (gil);
+		gil_scrollbar_adjust (gil);
+	} else
+		priv->dirty = TRUE;
+}
+
+static void
+gil_destroy (GtkObject *object)
+{
+	Gil *gil;
+
+	/* remember, destroy can be run multiple times! */
+
+	gil = GIL (object);
+
+	g_free (gil->_priv->separators);
+	gil->_priv->separators = NULL;
+
+	gil->_priv->frozen = 1;
+	gil->_priv->dirty  = TRUE;
+	if(gil->_priv->icon_list) {
+		gnome_icon_list_clear (gil);
+		g_array_free(gil->_priv->icon_list, TRUE);
+	}
+	gil->_priv->icon_list = NULL;
+
+	if (gil->_priv->timer_tag != 0) {
+		gtk_timeout_remove (gil->_priv->timer_tag);
+		gil->_priv->timer_tag = 0;
+	}
+
+	if (GTK_OBJECT_CLASS (parent_class)->destroy)
+		(*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gil_finalize (GObject *object)
+{
+	Gil *gil;
+
+	gil = GIL (object);
+
+	g_free (gil->_priv);
+	gil->_priv = NULL;
+
+	if (G_OBJECT_CLASS (parent_class)->finalize)
+		(*G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+
+static void
+select_icon (Gil *gil, int pos, GdkEvent *event)
+{
+	GnomeIconListPrivate *priv;
+	gint i;
+	Icon *icon;
+
+	priv = gil->_priv;
+
+	switch (priv->selection_mode) {
+	case GTK_SELECTION_SINGLE:
+	case GTK_SELECTION_BROWSE:
+		i = 0;
+
+		for (i = 0; i < priv->icon_list->len; i++) {
+			icon = g_array_index (priv->icon_list, Icon*, i);
+
+			if (i != pos && icon->selected)
+				emit_select (gil, FALSE, i, event);
+		}
+
+		emit_select (gil, TRUE, pos, event);
+		break;
+
+	case GTK_SELECTION_MULTIPLE:
+	case GTK_SELECTION_EXTENDED:
+		emit_select (gil, TRUE, pos, event);
+		break;
+
+	default:
+		break;
+	}
+}
+
+/**
+ * gnome_icon_list_select_icon:
+ * @gil: An icon list.
+ * @pos: Index of the icon to be selected.
+ *
+ * Selects the icon at the index specified by @pos.
+ */
+void
+gnome_icon_list_select_icon (GnomeIconList *gil, int pos)
+{
+	g_return_if_fail (gil != NULL);
+	g_return_if_fail (IS_GIL (gil));
+	g_return_if_fail (pos >= 0 && pos < gil->_priv->icons);
+
+	select_icon (gil, pos, NULL);
+}
+
+static void
+unselect_icon (Gil *gil, int pos, GdkEvent *event)
+{
+	GnomeIconListPrivate *priv;
+
+	priv = gil->_priv;
+
+	switch (priv->selection_mode) {
+	case GTK_SELECTION_SINGLE:
+	case GTK_SELECTION_BROWSE:
+	case GTK_SELECTION_MULTIPLE:
+	case GTK_SELECTION_EXTENDED:
+		emit_select (gil, FALSE, pos, event);
+		break;
+
+	default:
+		break;
+	}
+}
+
+/**
+ * gnome_icon_list_unselect_icon:
+ * @gil: An icon list.
+ * @pos: Index of the icon to be unselected.
+ *
+ * Unselects the icon at the index specified by @pos.
+ */
+void
+gnome_icon_list_unselect_icon (GnomeIconList *gil, int pos)
+{
+	g_return_if_fail (gil != NULL);
+	g_return_if_fail (IS_GIL (gil));
+	g_return_if_fail (pos >= 0 && pos < gil->_priv->icons);
+
+	unselect_icon (gil, pos, NULL);
+}
+
+static void
+gil_size_request (GtkWidget *widget, GtkRequisition *requisition)
+{
+	requisition->width = 1;
+	requisition->height = 1;
+}
+
+static void
+gil_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
+{
+	Gil *gil;
+	GnomeIconListPrivate *priv;
+
+	gil = GIL (widget);
+	priv = gil->_priv;
+
+	if (GTK_WIDGET_CLASS (parent_class)->size_allocate)
+		(* GTK_WIDGET_CLASS (parent_class)->size_allocate) (widget, allocation);
+
+	if (priv->frozen)
+		return;
+
+	gil_layout_all_icons (gil);
+}
+
+static void
+gil_realize (GtkWidget *widget)
+{
+	Gil *gil;
+	GnomeIconListPrivate *priv;
+	GtkStyle *style;
+
+	gil = GIL (widget);
+	priv = gil->_priv;
+
+	priv->frozen++;
+
+	if (GTK_WIDGET_CLASS (parent_class)->realize)
+		(* GTK_WIDGET_CLASS (parent_class)->realize) (widget);
+
+	priv->frozen--;
+
+	/* Change the style to use the base color as the background */
+
+	style = gtk_style_copy (gtk_widget_get_style (widget));
+	style->bg[GTK_STATE_NORMAL] = style->base[GTK_STATE_NORMAL];
+	gtk_widget_set_style (widget, style);
+
+	gdk_window_set_background (GTK_LAYOUT (gil)->bin_window,
+				   &widget->style->bg[GTK_STATE_NORMAL]);
+
+	if (priv->frozen)
+		return;
+
+	if (priv->dirty) {
+		gil_layout_all_icons (gil);
+		gil_scrollbar_adjust (gil);
+	}
+}
+
+static void
+real_select_icon (Gil *gil, gint num, GdkEvent *event)
+{
+	GnomeIconListPrivate *priv;
+	Icon *icon;
+
+	g_return_if_fail (gil != NULL);
+	g_return_if_fail (IS_GIL (gil));
+	g_return_if_fail (num >= 0 && num < gil->_priv->icons);
+
+	priv = gil->_priv;
+
+	icon = g_array_index (priv->icon_list, Icon*, num);
+
+	if (icon->selected)
+		return;
+
+	icon->selected = TRUE;
+	gnome_icon_text_item_select (icon->text, TRUE);
+	priv->selection = g_list_append (priv->selection, GINT_TO_POINTER (num));
+}
+
+static void
+real_unselect_icon (Gil *gil, gint num, GdkEvent *event)
+{
+	GnomeIconListPrivate *priv;
+	Icon *icon;
+
+	g_return_if_fail (gil != NULL);
+	g_return_if_fail (IS_GIL (gil));
+	g_return_if_fail (num >= 0 && num < gil->_priv->icons);
+
+	priv = gil->_priv;
+
+	icon = g_array_index (priv->icon_list, Icon*, num);
+
+	if (!icon->selected)
+		return;
+
+	icon->selected = FALSE;
+	gnome_icon_text_item_select (icon->text, FALSE);
+	priv->selection = g_list_remove (priv->selection, GINT_TO_POINTER (num));
+}
+
+/* Saves the selection of the icon list to temporary storage */
+static void
+store_temp_selection (Gil *gil)
+{
+	GnomeIconListPrivate *priv;
+	int i;
+	Icon *icon;
+
+	priv = gil->_priv;
+
+	for (i = 0; i < priv->icon_list->len; i++) {
+		icon = g_array_index(priv->icon_list, Icon*, i);
+
+		icon->tmp_selected = icon->selected;
+	}
+}
+
+#define gray50_width 2
+#define gray50_height 2
+static const char gray50_bits[] = {
+  0x02, 0x01, };
+
+/* Button press handler for the icon list */
+static gint
+gil_button_press (GtkWidget *widget, GdkEventButton *event)
+{
+	Gil *gil;
+	GnomeIconListPrivate *priv;
+	int only_one;
+	GdkBitmap *stipple;
+	double tx, ty;
+
+	gil = GIL (widget);
+	priv = gil->_priv;
+
+	/* Invoke the canvas event handler and see if an item picks up the event */
+
+	if ((* GTK_WIDGET_CLASS (parent_class)->button_press_event) (widget, event))
+		return TRUE;
+
+	if (!(event->type == GDK_BUTTON_PRESS
+	      && event->button == 1
+	      && priv->selection_mode != GTK_SELECTION_BROWSE))
+		return FALSE;
+
+	only_one = priv->selection_mode == GTK_SELECTION_SINGLE;
+
+	if (only_one || (event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) == 0)
+		gil_unselect_all (gil, NULL, NULL);
+
+	if (only_one)
+		return TRUE;
+
+	if (priv->selecting)
+		return FALSE;
+
+	gnome_canvas_window_to_world (GNOME_CANVAS (gil), event->x, event->y, &tx, &ty);
+	priv->sel_start_x = tx;
+	priv->sel_start_y = ty;
+	priv->sel_state = event->state;
+	priv->selecting = TRUE;
+
+	store_temp_selection (gil);
+
+	stipple = gdk_bitmap_create_from_data (NULL, gray50_bits, gray50_width, gray50_height);
+	priv->sel_rect = gnome_canvas_item_new (gnome_canvas_root (GNOME_CANVAS (gil)),
+						gnome_canvas_rect_get_type (),
+						"x1", tx,
+						"y1", ty,
+						"x2", tx,
+						"y2", ty,
+						"outline_color", "black",
+						"width_pixels", 1,
+						"outline_stipple", stipple,
+						NULL);
+	gdk_bitmap_unref (stipple);
+
+	gnome_canvas_item_grab (priv->sel_rect, GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
+				NULL, event->time);
+
+	return TRUE;
+}
+
+/* Returns whether the specified icon is at least partially inside the specified
+ * rectangle.
+ */
+static int
+icon_is_in_area (Icon *icon, int x1, int y1, int x2, int y2)
+{
+	double ix1, iy1, ix2, iy2;
+
+	if (x1 == x2 && y1 == y2)
+		return FALSE;
+
+	gnome_canvas_item_get_bounds (GNOME_CANVAS_ITEM (icon->image), &ix1, &iy1, &ix2, &iy2);
+
+	if (ix1 <= x2 && iy1 <= y2 && ix2 >= x1 && iy2 >= y1)
+		return TRUE;
+
+	gnome_canvas_item_get_bounds (GNOME_CANVAS_ITEM (icon->text), &ix1, &iy1, &ix2, &iy2);
+
+	if (ix1 <= x2 && iy1 <= y2 && ix2 >= x1 && iy2 >= y1)
+		return TRUE;
+
+	return FALSE;
+}
+
+/* Updates the rubberband selection to the specified point */
+static void
+update_drag_selection (Gil *gil, int x, int y)
+{
+	GnomeIconListPrivate *priv;
+	int x1, x2, y1, y2;
+	int i;
+	Icon *icon;
+	int additive, invert;
+
+	priv = gil->_priv;
+
+	/* Update rubberband */
+
+	if (priv->sel_start_x < x) {
+		x1 = priv->sel_start_x;
+		x2 = x;
+	} else {
+		x1 = x;
+		x2 = priv->sel_start_x;
+	}
+
+	if (priv->sel_start_y < y) {
+		y1 = priv->sel_start_y;
+		y2 = y;
+	} else {
+		y1 = y;
+		y2 = priv->sel_start_y;
+	}
+
+	if (x1 < 0)
+		x1 = 0;
+
+	if (y1 < 0)
+		y1 = 0;
+
+	if (x2 >= GTK_WIDGET (gil)->allocation.width)
+		x2 = GTK_WIDGET (gil)->allocation.width - 1;
+
+	if (y2 >= priv->total_height)
+		y2 = priv->total_height - 1;
+
+	gnome_canvas_item_set (priv->sel_rect,
+			       "x1", (double) x1,
+			       "y1", (double) y1,
+			       "x2", (double) x2,
+			       "y2", (double) y2,
+			       NULL);
+
+	/* Select or unselect icons as appropriate */
+
+	additive = priv->sel_state & GDK_SHIFT_MASK;
+	invert = priv->sel_state & GDK_CONTROL_MASK;
+
+	for (i = 0; i < priv->icon_list->len; i++) {
+		icon = g_array_index(priv->icon_list, Icon*, i);
+
+		if (icon_is_in_area (icon, x1, y1, x2, y2)) {
+			if (invert) {
+				if (icon->selected == icon->tmp_selected)
+					emit_select (gil, !icon->selected, i, NULL);
+			} else if (additive) {
+				if (!icon->selected)
+					emit_select (gil, TRUE, i, NULL);
+			} else {
+				if (!icon->selected)
+					emit_select (gil, TRUE, i, NULL);
+			}
+		} else if (icon->selected != icon->tmp_selected)
+			emit_select (gil, icon->tmp_selected, i, NULL);
+	}
+}
+
+/* Button release handler for the icon list */
+static gint
+gil_button_release (GtkWidget *widget, GdkEventButton *event)
+{
+	Gil *gil;
+	GnomeIconListPrivate *priv;
+	double x, y;
+
+	gil = GIL (widget);
+	priv = gil->_priv;
+
+	if (!priv->selecting)
+		return (* GTK_WIDGET_CLASS (parent_class)->button_release_event) (widget, event);
+
+	if (event->button != 1)
+		return FALSE;
+
+	gnome_canvas_window_to_world (GNOME_CANVAS (gil), event->x, event->y, &x, &y);
+	update_drag_selection (gil, x, y);
+	gnome_canvas_item_ungrab (priv->sel_rect, event->time);
+
+	gtk_object_destroy (GTK_OBJECT (priv->sel_rect));
+	priv->sel_rect = NULL;
+	priv->selecting = FALSE;
+
+	if (priv->timer_tag != 0) {
+		gtk_timeout_remove (priv->timer_tag);
+		priv->timer_tag = 0;
+	}
+
+	return TRUE;
+}
+
+/* Autoscroll timeout handler for the icon list */
+static gint
+scroll_timeout (gpointer data)
+{
+	Gil *gil;
+	GnomeIconListPrivate *priv;
+	GtkAdjustment *adj;
+	double x, y;
+	int value;
+
+	gil = data;
+	priv = gil->_priv;
+
+	GDK_THREADS_ENTER ();
+
+	adj = gtk_layout_get_vadjustment (GTK_LAYOUT (gil));
+
+	value = adj->value + priv->value_diff;
+	if (value > adj->upper - adj->page_size)
+		value = adj->upper - adj->page_size;
+
+	gtk_adjustment_set_value (adj, value);
+
+	gnome_canvas_window_to_world (GNOME_CANVAS (gil),
+				      priv->event_last_x, priv->event_last_y,
+				      &x, &y);
+	update_drag_selection (gil, x, y);
+
+	GDK_THREADS_LEAVE();
+
+	return TRUE;
+}
+
+/* Motion event handler for the icon list */
+static gint
+gil_motion_notify (GtkWidget *widget, GdkEventMotion *event)
+{
+	Gil *gil;
+	GnomeIconListPrivate *priv;
+	double x, y;
+
+	gil = GIL (widget);
+	priv = gil->_priv;
+
+	if (!priv->selecting)
+		return (* GTK_WIDGET_CLASS (parent_class)->motion_notify_event) (widget, event);
+
+	gnome_canvas_window_to_world (GNOME_CANVAS (gil), event->x, event->y, &x, &y);
+	update_drag_selection (gil, x, y);
+
+	/* If we are out of bounds, schedule a timeout that will do the scrolling */
+
+	if (event->y < 0 || event->y > widget->allocation.height) {
+		if (priv->timer_tag == 0)
+			priv->timer_tag = gtk_timeout_add (SCROLL_TIMEOUT, scroll_timeout, gil);
+
+		if (event->y < 0)
+			priv->value_diff = event->y;
+		else
+			priv->value_diff = event->y - widget->allocation.height;
+
+		priv->event_last_x = event->x;
+		priv->event_last_y = event->y;
+
+		/* Make the steppings be relative to the mouse distance from the
+		 * canvas.  Also notice the timeout above is small to give a
+		 * more smooth movement.
+		 */
+		priv->value_diff /= 5;
+	} else if (priv->timer_tag != 0) {
+		gtk_timeout_remove (priv->timer_tag);
+		priv->timer_tag = 0;
+	}
+
+	return TRUE;
+}
+
+static void
+gil_class_init (GilClass *gil_class)
+{
+	GtkObjectClass *object_class;
+	GObjectClass *gobject_class;
+	GtkWidgetClass *widget_class;
+	GtkLayoutClass *layout_class;
+	GnomeCanvasClass *canvas_class;
+
+	object_class = (GtkObjectClass *)   gil_class;
+	gobject_class = (GObjectClass *)    gil_class;
+	widget_class = (GtkWidgetClass *)   gil_class;
+	layout_class = (GtkLayoutClass *)   gil_class;
+	canvas_class = (GnomeCanvasClass *) gil_class;
+
+	parent_class = gtk_type_class (gnome_canvas_get_type ());
+
+	gil_signals[SELECT_ICON] =
+		gtk_signal_new (
+			"select_icon",
+			GTK_RUN_FIRST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeIconListClass, select_icon),
+			gnome_marshal_VOID__INT_BOXED,
+			GTK_TYPE_NONE, 2,
+			GTK_TYPE_INT,
+			GDK_TYPE_EVENT);
+
+	gil_signals[UNSELECT_ICON] =
+		gtk_signal_new (
+			"unselect_icon",
+			GTK_RUN_FIRST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeIconListClass, unselect_icon),
+			gnome_marshal_VOID__INT_BOXED,
+			GTK_TYPE_NONE, 2,
+			GTK_TYPE_INT,
+			GDK_TYPE_EVENT);
+
+	gil_signals[TEXT_CHANGED] =
+		gtk_signal_new (
+			"text_changed",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeIconListClass, text_changed),
+			gnome_marshal_BOOLEAN__INT_STRING,
+			GTK_TYPE_BOOL, 2,
+			GTK_TYPE_INT,
+			GTK_TYPE_POINTER);
+
+
+	object_class->destroy = gil_destroy;
+	gobject_class->finalize = gil_finalize;
+
+	widget_class->size_request = gil_size_request;
+	widget_class->size_allocate = gil_size_allocate;
+	widget_class->realize = gil_realize;
+	widget_class->button_press_event = gil_button_press;
+	widget_class->button_release_event = gil_button_release;
+	widget_class->motion_notify_event = gil_motion_notify;
+
+	gil_class->select_icon = real_select_icon;
+	gil_class->unselect_icon = real_unselect_icon;
+}
+
+static void
+gil_init (Gil *gil)
+{
+	gil->_priv = g_new0 (GnomeIconListPrivate, 1);
+
+	gil->_priv->icon_list = g_array_new(FALSE, FALSE, sizeof(gpointer));
+	gil->_priv->row_spacing = DEFAULT_ROW_SPACING;
+	gil->_priv->col_spacing = DEFAULT_COL_SPACING;
+	gil->_priv->text_spacing = DEFAULT_TEXT_SPACING;
+	gil->_priv->icon_border = DEFAULT_ICON_BORDER;
+	gil->_priv->separators = g_strdup (" ");
+
+	gil->_priv->selection_mode = GTK_SELECTION_SINGLE;
+	gil->_priv->dirty = TRUE;
+
+	gnome_canvas_set_scroll_region (GNOME_CANVAS (gil), 0.0, 0.0, 1000000.0, 1000000.0);
+	gnome_canvas_scroll_to (GNOME_CANVAS (gil), 0, 0);
+}
+
+/**
+ * gnome_icon_list_get_type:
+ *
+ * Registers the &GnomeIconList class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Returns: The type ID of the &GnomeIconList class.
+ */
+guint
+gnome_icon_list_get_type (void)
+{
+	static guint gil_type = 0;
+
+	if (!gil_type) {
+		GtkTypeInfo gil_info = {
+			"GnomeIconList",
+			sizeof (GnomeIconList),
+			sizeof (GnomeIconListClass),
+			(GtkClassInitFunc) gil_class_init,
+			(GtkObjectInitFunc) gil_init,
+			NULL,
+			NULL,
+			NULL
+		};
+
+		gil_type = gtk_type_unique (gnome_canvas_get_type (),
+					    &gil_info);
+	}
+
+	return gil_type;
+}
+
+/**
+ * gnome_icon_list_set_icon_width:
+ * @gil: An icon list.
+ * @w:   New width for the icon columns.
+ *
+ * Sets the amount of horizontal space allocated to the icons, i.e. the column
+ * width of the icon list.
+ */
+void
+gnome_icon_list_set_icon_width (GnomeIconList *gil, int w)
+{
+	GnomeIconListPrivate *priv;
+
+	g_return_if_fail (gil != NULL);
+	g_return_if_fail (IS_GIL (gil));
+
+	priv = gil->_priv;
+
+	priv->icon_width  = w;
+
+	if (priv->frozen) {
+		priv->dirty = TRUE;
+		return;
+	}
+
+	gil_layout_all_icons (gil);
+	gil_scrollbar_adjust (gil);
+}
+
+
+/**
+ * gnome_icon_list_construct:
+ * @gil: An icon list.
+ * @icon_width: Width for the icon columns.
+ * @flags: A combination of %GNOME_ICON_LIST_IS_EDITABLE and %GNOME_ICON_LIST_STATIC_TEXT.
+ *
+ * Constructor for the icon list, to be used by derived classes.
+ **/
+void
+gnome_icon_list_construct (GnomeIconList *gil, guint icon_width, int flags)
+{
+	GnomeIconListPrivate *priv;
+
+	g_return_if_fail (gil != NULL);
+	g_return_if_fail (IS_GIL (gil));
+
+	priv = gil->_priv;
+
+	gnome_icon_list_set_icon_width (gil, icon_width);
+	priv->is_editable = (flags & GNOME_ICON_LIST_IS_EDITABLE) != 0;
+	priv->static_text = (flags & GNOME_ICON_LIST_STATIC_TEXT) != 0;
+}
+
+
+/**
+ * gnome_icon_list_new: [constructor]
+ * @icon_width: Width for the icon columns.
+ * @flags:      A combination of %GNOME_ICON_LIST_IS_EDITABLE and %GNOME_ICON_LIST_STATIC_TEXT.
+ *
+ * Creates a new icon list widget.  The icon columns are allocated a width of
+ * @icon_width pixels.  Icon captions will be word-wrapped to this width as
+ * well.
+ *
+ * If @flags has the %GNOME_ICON_LIST_IS_EDITABLE flag set, then the user will be
+ * able to edit the text in the icon captions, and the "text_changed" signal
+ * will be emitted when an icon's text is changed.
+ *
+ * If @flags has the %GNOME_ICON_LIST_STATIC_TEXT flags set, then the text
+ * for the icon captions will not be copied inside the icon list; it will only
+ * store the pointers to the original text strings specified by the application.
+ * This is intended to save memory.  If this flag is not set, then the text
+ * strings will be copied and managed internally.
+ *
+ * Returns: a newly-created icon list widget
+ */
+GtkWidget *
+gnome_icon_list_new (guint icon_width, int flags)
+{
+	Gil *gil;
+
+	gtk_widget_push_colormap (gdk_rgb_get_cmap ());
+	gil = GIL (gtk_type_new (gnome_icon_list_get_type ()));
+	gtk_widget_pop_colormap ();
+
+	gnome_icon_list_construct (gil, icon_width, flags);
+
+	return GTK_WIDGET (gil);
+}
+
+
+/**
+ * gnome_icon_list_freeze:
+ * @gil:  An icon list.
+ *
+ * Freezes an icon list so that any changes made to it will not be
+ * reflected on the screen until it is thawed with gnome_icon_list_thaw().
+ * It is recommended to freeze the icon list before inserting or deleting
+ * many icons, for example, so that the layout process will only be executed
+ * once, when the icon list is finally thawed.
+ *
+ * You can call this function multiple times, but it must be balanced with the
+ * same number of calls to gnome_icon_list_thaw() before the changes will take
+ * effect.
+ */
+void
+gnome_icon_list_freeze (GnomeIconList *gil)
+{
+	g_return_if_fail (gil != NULL);
+	g_return_if_fail (IS_GIL (gil));
+
+	gil->_priv->frozen++;
+
+	/* We hide the root so that the user will not see any changes while the
+	 * icon list is doing stuff.
+	 */
+
+	if (gil->_priv->frozen == 1)
+		gnome_canvas_item_hide (GNOME_CANVAS (gil)->root);
+}
+
+/**
+ * gnome_icon_list_thaw:
+ * @gil:  An icon list.
+ *
+ * Thaws the icon list and performs any pending layout operations.  This
+ * is to be used in conjunction with gnome_icon_list_freeze().
+ */
+void
+gnome_icon_list_thaw (GnomeIconList *gil)
+{
+	g_return_if_fail (gil != NULL);
+	g_return_if_fail (IS_GIL (gil));
+	g_return_if_fail (gil->_priv->frozen > 0);
+
+	gil->_priv->frozen--;
+
+	if (gil->_priv->dirty) {
+                gil_layout_all_icons (gil);
+                gil_scrollbar_adjust (gil);
+        }
+
+	if (gil->_priv->frozen == 0)
+		gnome_canvas_item_show (GNOME_CANVAS (gil)->root);
+}
+
+/**
+ * gnome_icon_list_get_selection_mode
+ * @gil:  An icon list.
+ *
+ * Returns the current selection mode for an icon list.
+ */
+GtkSelectionMode
+gnome_icon_list_get_selection_mode (GnomeIconList *gil)
+{
+	g_return_val_if_fail (gil != NULL, 0);
+	g_return_val_if_fail (IS_GIL (gil), 0);
+
+	return gil->_priv->selection_mode;
+}
+
+/**
+ * gnome_icon_list_set_selection_mode
+ * @gil:  An icon list.
+ * @mode: New selection mode.
+ *
+ * Sets the selection mode for an icon list.  The %GTK_SELECTION_MULTIPLE and
+ * %GTK_SELECTION_EXTENDED modes are considered equivalent.
+ */
+void
+gnome_icon_list_set_selection_mode (GnomeIconList *gil, GtkSelectionMode mode)
+{
+	g_return_if_fail (gil != NULL);
+	g_return_if_fail (IS_GIL (gil));
+
+	gil->_priv->selection_mode = mode;
+	gil->_priv->last_selected_idx = -1;
+	gil->_priv->last_selected_icon = NULL;
+}
+
+/**
+ * gnome_icon_list_set_icon_data_full:
+ * @gil:     An icon list.
+ * @pos:     Index of an icon.
+ * @data:    User data to set on the icon.
+ * @destroy: Destroy notification handler for the icon.
+ *
+ * Associates the @data pointer to the icon at the index specified by @pos.  The
+ * @destroy argument points to a function that will be called when the icon is
+ * destroyed, or NULL if no function is to be called when this happens.
+ */
+void
+gnome_icon_list_set_icon_data_full (GnomeIconList *gil,
+				    int pos, gpointer data,
+				    GtkDestroyNotify destroy)
+{
+	Icon *icon;
+
+	g_return_if_fail (gil != NULL);
+	g_return_if_fail (IS_GIL (gil));
+	g_return_if_fail (pos >= 0 && pos < gil->_priv->icons);
+
+	icon = g_array_index (gil->_priv->icon_list, Icon*, pos);
+	icon->data = data;
+	icon->destroy = destroy;
+}
+
+/**
+ * gnome_icon_list_get_icon_data:
+ * @gil:  An icon list.
+ * @pos:  Index of an icon.
+ * @data: User data to set on the icon.
+ *
+ * Associates the @data pointer to the icon at the index specified by @pos.
+ */
+void
+gnome_icon_list_set_icon_data (GnomeIconList *gil, int pos, gpointer data)
+{
+	gnome_icon_list_set_icon_data_full (gil, pos, data, NULL);
+}
+
+/**
+ * gnome_icon_list_get_icon_data:
+ * @gil: An icon list.
+ * @pos: Index of an icon.
+ *
+ * Returns the user data pointer associated to the icon at the index specified
+ * by @pos.
+ */
+gpointer
+gnome_icon_list_get_icon_data (GnomeIconList *gil, int pos)
+{
+	Icon *icon;
+
+	g_return_val_if_fail (gil != NULL, NULL);
+	g_return_val_if_fail (IS_GIL (gil), NULL);
+	g_return_val_if_fail (pos >= 0 && pos < gil->_priv->icons, NULL);
+
+	icon = g_array_index (gil->_priv->icon_list, Icon*, pos);
+	return icon->data;
+}
+
+/**
+ * gnome_icon_list_find_icon_from_data:
+ * @gil:    An icon list.
+ * @data:   Data pointer associated to an icon.
+ *
+ * Returns the index of the icon whose user data has been set to @data,
+ * or -1 if no icon has this data associated to it.
+ */
+int
+gnome_icon_list_find_icon_from_data (GnomeIconList *gil, gpointer data)
+{
+	GnomeIconListPrivate *priv;
+	int n;
+	Icon *icon;
+
+	g_return_val_if_fail (gil != NULL, -1);
+	g_return_val_if_fail (IS_GIL (gil), -1);
+
+	priv = gil->_priv;
+
+	for (n = 0; n < priv->icon_list->len; n++) {
+		icon = g_array_index(priv->icon_list, Icon*, n);
+		if (icon->data == data)
+			return n;
+	}
+
+	return -1;
+}
+
+/* Sets an integer value in the private structure of the icon list, and updates it */
+static void
+set_value (GnomeIconList *gil, GnomeIconListPrivate *priv, int *dest, int val)
+{
+	if (val == *dest)
+		return;
+
+	*dest = val;
+
+	if (!priv->frozen) {
+		gil_layout_all_icons (gil);
+		gil_scrollbar_adjust (gil);
+	} else
+		priv->dirty = TRUE;
+}
+
+/**
+ * gnome_icon_list_set_row_spacing:
+ * @gil:    An icon list.
+ * @pixels: Number of pixels for inter-row spacing.
+ *
+ * Sets the spacing to be used between rows of icons.
+ */
+void
+gnome_icon_list_set_row_spacing (GnomeIconList *gil, int pixels)
+{
+	GnomeIconListPrivate *priv;
+
+	g_return_if_fail (gil != NULL);
+	g_return_if_fail (IS_GIL (gil));
+
+	priv = gil->_priv;
+	set_value (gil, priv, &priv->row_spacing, pixels);
+}
+
+/**
+ * gnome_icon_list_set_col_spacing:
+ * @gil:    An icon list.
+ * @pixels: Number of pixels for inter-column spacing.
+ *
+ * Sets the spacing to be used between columns of icons.
+ */
+void
+gnome_icon_list_set_col_spacing (GnomeIconList *gil, int pixels)
+{
+	GnomeIconListPrivate *priv;
+
+	g_return_if_fail (gil != NULL);
+	g_return_if_fail (IS_GIL (gil));
+
+	priv = gil->_priv;
+	set_value (gil, priv, &priv->col_spacing, pixels);
+}
+
+/**
+ * gnome_icon_list_set_text_spacing:
+ * @gil:    An icon list.
+ * @pixels: Number of pixels between an icon's image and its caption.
+ *
+ * Sets the spacing to be used between an icon's image and its text caption.
+ */
+void
+gnome_icon_list_set_text_spacing (GnomeIconList *gil, int pixels)
+{
+	GnomeIconListPrivate *priv;
+
+	g_return_if_fail (gil != NULL);
+	g_return_if_fail (IS_GIL (gil));
+
+	priv = gil->_priv;
+	set_value (gil, priv, &priv->text_spacing, pixels);
+}
+
+/**
+ * gnome_icon_list_set_icon_border:
+ * @gil:    An icon list.
+ * @pixels: Number of border pixels to be used around an icon's image.
+ *
+ * Sets the width of the border to be displayed around an icon's image.  This is
+ * currently not implemented.
+ */
+void
+gnome_icon_list_set_icon_border (GnomeIconList *gil, int pixels)
+{
+	GnomeIconListPrivate *priv;
+
+	g_return_if_fail (gil != NULL);
+	g_return_if_fail (IS_GIL (gil));
+
+	priv = gil->_priv;
+	set_value (gil, priv, &priv->icon_border, pixels);
+}
+
+/**
+ * gnome_icon_list_set_separators:
+ * @gil: An icon list.
+ * @sep: String with characters to be used as word separators.
+ *
+ * Sets the characters that can be used as word separators when doing
+ * word-wrapping in the icon text captions.
+ */
+void
+gnome_icon_list_set_separators (GnomeIconList *gil, const char *sep)
+{
+	GnomeIconListPrivate *priv;
+
+	g_return_if_fail (gil != NULL);
+	g_return_if_fail (IS_GIL (gil));
+	g_return_if_fail (sep != NULL);
+
+	priv = gil->_priv;
+
+	if (priv->separators)
+		g_free (priv->separators);
+
+	priv->separators = g_strdup (sep);
+
+	if (priv->frozen) {
+		priv->dirty = TRUE;
+		return;
+	}
+
+	gil_layout_all_icons (gil);
+	gil_scrollbar_adjust (gil);
+}
+
+/**
+ * gnome_icon_list_moveto:
+ * @gil:    An icon list.
+ * @pos:    Index of an icon.
+ * @yalign: Vertical alignment of the icon.
+ *
+ * Makes the icon whose index is @pos be visible on the screen.  The icon list
+ * gets scrolled so that the icon is visible.  An alignment of 0.0 represents
+ * the top of the visible part of the icon list, and 1.0 represents the bottom.
+ * An icon can be centered on the icon list.
+ */
+void
+gnome_icon_list_moveto (GnomeIconList *gil, int pos, double yalign)
+{
+	GnomeIconListPrivate *priv;
+	GtkAdjustment *adj;
+	IconLine *il;
+	GList *l;
+	int i, y, uh, line;
+
+	g_return_if_fail (gil != NULL);
+	g_return_if_fail (IS_GIL (gil));
+	g_return_if_fail (pos >= 0 && pos < gil->_priv->icons);
+	g_return_if_fail (yalign >= 0.0 && yalign <= 1.0);
+
+	priv = gil->_priv;
+
+	g_return_if_fail (priv->lines != NULL);
+
+	line = pos / gil_get_items_per_line (gil);
+
+	y = 0;
+	for (i = 0, l = priv->lines; l && i < line; l = l->next, i++) {
+		il = l->data;
+		y += icon_line_height (gil, il);
+	}
+
+	il = l->data;
+
+	uh = GTK_WIDGET (gil)->allocation.height - icon_line_height (gil,il);
+	adj = gtk_layout_get_vadjustment (GTK_LAYOUT (gil));
+	gtk_adjustment_set_value (adj, y - uh * yalign);
+}
+
+/**
+ * gnome_icon_list_is_visible:
+ * @gil: An icon list.
+ * @pos: Index of an icon.
+ *
+ * Returns whether the icon at the index specified by @pos is visible.  This
+ * will be %GTK_VISIBILITY_NONE if the icon is not visible at all,
+ * %GTK_VISIBILITY_PARTIAL if the icon is at least partially shown, and
+ * %GTK_VISIBILITY_FULL if the icon is fully visible.
+ */
+GtkVisibility
+gnome_icon_list_icon_is_visible (GnomeIconList *gil, int pos)
+{
+	GnomeIconListPrivate *priv;
+	GtkAdjustment *adj;
+	IconLine *il;
+	GList *l;
+	int line, y1, y2, i;
+
+	g_return_val_if_fail (gil != NULL, GTK_VISIBILITY_NONE);
+	g_return_val_if_fail (IS_GIL (gil), GTK_VISIBILITY_NONE);
+	g_return_val_if_fail (pos >= 0 && pos < gil->_priv->icons,
+			      GTK_VISIBILITY_NONE);
+
+	priv = gil->_priv;
+
+	if (priv->lines == NULL)
+		return GTK_VISIBILITY_NONE;
+
+	line = pos / gil_get_items_per_line (gil);
+	y1 = 0;
+	for (i = 0, l = priv->lines; l && i < line; l = l->next, i++) {
+		il = l->data;
+		y1 += icon_line_height (gil, il);
+	}
+
+	y2 = y1 + icon_line_height (gil, (IconLine *) l->data);
+
+	adj = gtk_layout_get_vadjustment (GTK_LAYOUT (gil));
+
+	if (y2 < adj->value)
+		return GTK_VISIBILITY_NONE;
+
+	if (y1 > adj->value + GTK_WIDGET (gil)->allocation.height)
+		return GTK_VISIBILITY_NONE;
+
+	if (y2 <= adj->value + GTK_WIDGET (gil)->allocation.height &&
+	    y1 >= adj->value)
+		return GTK_VISIBILITY_FULL;
+
+	return GTK_VISIBILITY_PARTIAL;
+}
+
+/**
+ * gnome_icon_list_get_icon_at:
+ * @gil: An icon list.
+ * @x:   X position in the icon list window.
+ * @y:   Y position in the icon list window.
+ *
+ * Returns the index of the icon that is under the specified coordinates, which
+ * are relative to the icon list's window.  If there is no icon in that
+ * position, -1 is returned.
+ */
+int
+gnome_icon_list_get_icon_at (GnomeIconList *gil, int x, int y)
+{
+	GnomeIconListPrivate *priv;
+	double wx, wy;
+	double dx, dy;
+	int cx, cy;
+	int n;
+	GnomeCanvasItem *item;
+	double dist;
+
+	g_return_val_if_fail (gil != NULL, -1);
+	g_return_val_if_fail (IS_GIL (gil), -1);
+
+	priv = gil->_priv;
+
+	dx = x;
+	dy = y;
+
+	gnome_canvas_window_to_world (GNOME_CANVAS (gil), dx, dy, &wx, &wy);
+	gnome_canvas_w2c (GNOME_CANVAS (gil), wx, wy, &cx, &cy);
+
+	for (n = 0; n < priv->icon_list->len; n++) {
+		Icon *icon = g_array_index(priv->icon_list, Icon*, n);
+		GnomeCanvasItem *image = GNOME_CANVAS_ITEM (icon->image);
+		GnomeCanvasItem *text = GNOME_CANVAS_ITEM (icon->text);
+
+		if (wx >= image->x1 && wx <= image->x2 && wy >= image->y1 && wy <= image->y2) {
+			dist = (* GNOME_CANVAS_ITEM_GET_CLASS (image)->point) (
+				image,
+				wx, wy,
+				cx, cy,
+				&item);
+
+			if ((int) (dist * GNOME_CANVAS (gil)->pixels_per_unit + 0.5)
+			    <= GNOME_CANVAS (gil)->close_enough)
+				return n;
+		}
+
+		if (wx >= text->x1 && wx <= text->x2 && wy >= text->y1 && wy <= text->y2) {
+			dist = (* GNOME_CANVAS_ITEM_GET_CLASS (text)->point) (
+				text,
+				wx, wy,
+				cx, cy,
+				&item);
+
+			if ((int) (dist * GNOME_CANVAS (gil)->pixels_per_unit + 0.5)
+			    <= GNOME_CANVAS (gil)->close_enough)
+				return n;
+		}
+	}
+
+	return -1;
+}
+
+
+/**
+ * gnome_icon_list_get_num_icons:
+ * @gil: An icon list.
+ *
+ * Returns the number of icons in the icon list.
+ */
+guint
+gnome_icon_list_get_num_icons (GnomeIconList *gil)
+{
+	g_return_val_if_fail (GNOME_IS_ICON_LIST (gil), 0);
+
+	return gil->_priv->icons;
+}
+
+
+/**
+ * gnome_icon_list_get_selection:
+ * @gil: An icon list.
+ *
+ * Returns a list of integers with the indices of the currently selected icons.
+ */
+GList *
+gnome_icon_list_get_selection (GnomeIconList *gil)
+{
+	g_return_val_if_fail (GNOME_IS_ICON_LIST (gil), NULL);
+
+	return gil->_priv->selection;
+}
+
+
+/**
+ * gnome_icon_list_get_selection:
+ * @gil: An icon list.
+ * @idx: Index of an @icon.
+ *
+ * Returns the filename of the icon with index @idx.
+ */
+gchar *
+gnome_icon_list_get_icon_filename (GnomeIconList *gil, int idx)
+{
+	Icon *icon;
+
+	g_return_val_if_fail (gil != NULL, NULL);
+	g_return_val_if_fail (IS_GIL (gil), NULL);
+	g_return_val_if_fail (idx >= 0 && idx < gil->_priv->icons, NULL);
+
+	icon = g_array_index (gil->_priv->icon_list, Icon*, idx);
+	return icon->icon_filename;
+}
+
+
+/**
+ * gnome_icon_list_find_icon_from_filename:
+ * @gil:       An icon list.
+ * @filename:  Filename of an icon.
+ *
+ * Returns the index of the icon whose filename is @filename or -1 if
+ * there is no icon with this filename.
+ */
+int
+gnome_icon_list_find_icon_from_filename (GnomeIconList *gil,
+					 const gchar *filename)
+{
+	GnomeIconListPrivate *priv;
+	int n;
+	Icon *icon;
+
+	g_return_val_if_fail (gil != NULL, -1);
+	g_return_val_if_fail (IS_GIL (gil), -1);
+	g_return_val_if_fail (filename != NULL, -1);
+
+	priv = gil->_priv;
+
+	for (n = 0; n < priv->icon_list->len; n++) {
+		icon = g_array_index(priv->icon_list, Icon*, n);
+		if (!strcmp (icon->icon_filename, filename))
+			return n;
+	}
+
+	return -1;
+}
+
diff --git a/libgnomeui/gnome-icon-list.h b/libgnomeui/gnome-icon-list.h
new file mode 100644
index 0000000..df86632
--- /dev/null
+++ b/libgnomeui/gnome-icon-list.h
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 1998, 1999 Free Software Foundation
+ * Copyright (C) 2000 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+/* GnomeIconList widget - scrollable icon list
+ *
+ *
+ * Authors:
+ *   Federico Mena   <federico nuclecu unam mx>
+ *   Miguel de Icaza <miguel nuclecu unam mx>
+ */
+
+#ifndef _GNOME_ICON_LIST_H_
+#define _GNOME_ICON_LIST_H_
+
+
+#include <libgnomecanvas/gnome-canvas.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+G_BEGIN_DECLS
+
+#define GNOME_TYPE_ICON_LIST            (gnome_icon_list_get_type ())
+#define GNOME_ICON_LIST(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_ICON_LIST, GnomeIconList))
+#define GNOME_ICON_LIST_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_ICON_LIST, GnomeIconListClass))
+#define GNOME_IS_ICON_LIST(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_ICON_LIST))
+#define GNOME_IS_ICON_LIST_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_ICON_LIST))
+#define GNOME_ICON_LIST_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_ICON_LIST, GnomeIconListClass))
+
+typedef struct _GnomeIconList        GnomeIconList;
+typedef struct _GnomeIconListPrivate GnomeIconListPrivate;
+typedef struct _GnomeIconListClass   GnomeIconListClass;
+
+typedef enum {
+	GNOME_ICON_LIST_ICONS,
+	GNOME_ICON_LIST_TEXT_BELOW,
+	GNOME_ICON_LIST_TEXT_RIGHT
+} GnomeIconListMode;
+
+/* This structure has been converted to use public and private parts.  To avoid
+ * breaking binary compatibility, the slots for private fields have been
+ * replaced with padding.  Please remove these fields when gnome-libs has
+ * reached another major version and it is "fine" to break binary compatibility.
+ */
+struct _GnomeIconList {
+	GnomeCanvas canvas;
+
+	/*< private >*/
+	GnomeIconListPrivate * _priv;
+};
+
+struct _GnomeIconListClass {
+	GnomeCanvasClass parent_class;
+
+	void     (*select_icon)    (GnomeIconList *gil, gint num, GdkEvent *event);
+	void     (*unselect_icon)  (GnomeIconList *gil, gint num, GdkEvent *event);
+	gboolean (*text_changed)   (GnomeIconList *gil, gint num, const char *new_text);
+};
+
+enum {
+	GNOME_ICON_LIST_IS_EDITABLE	= 1 << 0,
+	GNOME_ICON_LIST_STATIC_TEXT	= 1 << 1
+};
+
+guint          gnome_icon_list_get_type            (void) G_GNUC_CONST;
+
+GtkWidget     *gnome_icon_list_new                 (guint         icon_width,
+						    int           flags);
+void           gnome_icon_list_construct           (GnomeIconList *gil,
+						    guint icon_width,
+						    int flags);
+
+
+/* To avoid excesive recomputes during insertion/deletion */
+void           gnome_icon_list_freeze              (GnomeIconList *gil);
+void           gnome_icon_list_thaw                (GnomeIconList *gil);
+
+
+void           gnome_icon_list_insert              (GnomeIconList *gil,
+						    int idx,
+						    const char *icon_filename,
+						    const char *text);
+void           gnome_icon_list_insert_pixbuf       (GnomeIconList *gil,
+						    int idx,
+						    GdkPixbuf *im,
+						    const char *icon_filename,
+						    const char *text);
+
+int            gnome_icon_list_append              (GnomeIconList *gil,
+						    const char *icon_filename,
+						    const char *text);
+int            gnome_icon_list_append_pixbuf       (GnomeIconList *gil,
+						    GdkPixbuf *im,
+						    const char *icon_filename,
+						    const char *text);
+
+void           gnome_icon_list_clear               (GnomeIconList *gil);
+void           gnome_icon_list_remove              (GnomeIconList *gil,
+						    int idx);
+
+guint          gnome_icon_list_get_num_icons       (GnomeIconList *gil);
+
+
+/* Managing the selection */
+GtkSelectionMode gnome_icon_list_get_selection_mode(GnomeIconList *gil);
+void           gnome_icon_list_set_selection_mode  (GnomeIconList *gil,
+						    GtkSelectionMode mode);
+void           gnome_icon_list_select_icon         (GnomeIconList *gil,
+						    int idx);
+void           gnome_icon_list_unselect_icon       (GnomeIconList *gil,
+						    int idx);
+int            gnome_icon_list_unselect_all        (GnomeIconList *gil);
+GList *        gnome_icon_list_get_selection       (GnomeIconList *gil);
+
+/* Setting the spacing values */
+void           gnome_icon_list_set_icon_width      (GnomeIconList *gil,
+						    int w);
+void           gnome_icon_list_set_row_spacing     (GnomeIconList *gil,
+						    int pixels);
+void           gnome_icon_list_set_col_spacing     (GnomeIconList *gil,
+						    int pixels);
+void           gnome_icon_list_set_text_spacing    (GnomeIconList *gil,
+						    int pixels);
+void           gnome_icon_list_set_icon_border     (GnomeIconList *gil,
+						    int pixels);
+void           gnome_icon_list_set_separators      (GnomeIconList *gil,
+						    const char *sep);
+/* Icon filename. */
+gchar *        gnome_icon_list_get_icon_filename   (GnomeIconList *gil,
+						    int idx);
+int            gnome_icon_list_find_icon_from_filename (GnomeIconList *gil,
+							const char *filename);
+
+/* Attaching information to the icons */
+void           gnome_icon_list_set_icon_data       (GnomeIconList *gil,
+						    int idx, gpointer data);
+void           gnome_icon_list_set_icon_data_full  (GnomeIconList *gil,
+						    int idx, gpointer data,
+						    GtkDestroyNotify destroy);
+int            gnome_icon_list_find_icon_from_data (GnomeIconList *gil,
+						    gpointer data);
+gpointer       gnome_icon_list_get_icon_data       (GnomeIconList *gil,
+						    int idx);
+
+/* Visibility */
+void           gnome_icon_list_moveto              (GnomeIconList *gil,
+						    int idx, double yalign);
+GtkVisibility  gnome_icon_list_icon_is_visible     (GnomeIconList *gil,
+						    int idx);
+
+int            gnome_icon_list_get_icon_at         (GnomeIconList *gil,
+						    int x, int y);
+
+int            gnome_icon_list_get_items_per_line  (GnomeIconList *gil);
+
+G_END_DECLS
+
+#endif /* _GNOME_ICON_LIST_H_ */
diff --git a/libgnomeui/gnome-icon-text.c b/libgnomeui/gnome-icon-text.c
new file mode 100644
index 0000000..f500741
--- /dev/null
+++ b/libgnomeui/gnome-icon-text.c
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+/*
+ * gnome-icon-text.c: Formats and wraps around text to be used as
+ * icon captions.
+ *
+ * Author:
+ *    Federico Mena <federico nuclecu unam mx>
+ */
+#include <config.h>
+#include <gtk/gtk.h>
+#include <string.h>
+#include <libgnomeui/gnome-icon-text.h>
+
+static void
+free_row (gpointer data, gpointer user_data)
+{
+	GnomeIconTextInfoRow *row;
+
+	if (data) {
+		row = data;
+		g_free (row->text);
+		g_free (row->text_wc);
+		g_free (row);
+	}
+}
+
+/**
+ * gnome_icon_text_info_free:
+ * @ti: An icon text info structure.
+ *
+ * Frees a &GnomeIconTextInfo structure.  You should call this instead of
+ * freeing the structure yourself.
+ */
+void
+gnome_icon_text_info_free (GnomeIconTextInfo *ti)
+{
+	g_list_foreach (ti->rows, free_row, NULL);
+	g_list_free (ti->rows);
+	g_free (ti);
+}
+
+/**
+ * gnome_icon_layout_text:
+ * @font:       Name of the font that will be used to render the text.
+ * @text:       Text to be formatted.
+ * @separators: Separators used for word wrapping, can be NULL.
+ * @max_width:  Width in pixels to be used for word wrapping.
+ * @confine:    Whether it is mandatory to wrap at @max_width.
+ *
+ * Creates a new &GnomeIconTextInfo structure by wrapping the specified
+ * text.  If non-NULL, the @separators argument defines a set of characters
+ * to be used as word delimiters for performing word wrapping.  If it is
+ * NULL, then only spaces will be used as word delimiters.
+ *
+ * The @max_width argument is used to specify the width at which word
+ * wrapping will be performed.  If there is a very long word that does not
+ * fit in a single line, the @confine argument can be used to specify
+ * whether the word should be unconditionally split to fit or whether
+ * the maximum width should be increased as necessary.
+ *
+ * Return value: A newly-created &GnomeIconTextInfo structure.
+ */
+GnomeIconTextInfo *
+gnome_icon_layout_text (GdkFont *font, const gchar *text, const gchar *separators, gint max_width, gboolean confine)
+{
+	GnomeIconTextInfo *ti;
+	GnomeIconTextInfoRow *row;
+	GdkWChar *row_end;
+	GdkWChar *s, *word_start, *word_end, *old_word_end;
+	GdkWChar *sub_text;
+	int i, w_len, w;
+	GdkWChar *text_wc, *text_iter, *separators_wc;
+	int text_len_wc, separators_len_wc;
+
+	g_return_val_if_fail (font != NULL, NULL);
+	g_return_val_if_fail (text != NULL, NULL);
+
+	if (!separators)
+		separators = " ";
+
+	text_wc = g_new (GdkWChar, strlen (text) + 1);
+	text_len_wc = gdk_mbstowcs (text_wc, text, strlen (text));
+	if (text_len_wc < 0) text_len_wc = 0;
+	text_wc[text_len_wc] = 0;
+
+	separators_wc = g_new (GdkWChar, strlen (separators) + 1);
+	separators_len_wc = gdk_mbstowcs (separators_wc, separators, strlen (separators));
+	if (separators_len_wc < 0) separators_len_wc = 0;
+	separators_wc[separators_len_wc] = 0;
+	
+	ti = g_new (GnomeIconTextInfo, 1);
+
+	ti->rows = NULL;
+	ti->font = font;
+	ti->width = 0;
+	ti->height = 0;
+	ti->baseline_skip = font->ascent + font->descent;
+
+	word_end = NULL;
+
+	text_iter = text_wc;
+	while (*text_iter) {
+		for (row_end = text_iter; *row_end != 0 && *row_end != '\n'; row_end++);
+
+		/* Accumulate words from this row until they don't fit in the max_width */
+
+		s = text_iter;
+
+		while (s < row_end) {
+			word_start = s;
+			old_word_end = word_end;
+			for (word_end = word_start; *word_end; word_end++) {
+				GdkWChar *p;
+				for (p = separators_wc; *p; p++) {
+					if (*word_end == *p)
+						goto found;
+				}
+			}
+		  found:
+			if (word_end < row_end)
+				word_end++;
+
+			if (gdk_text_width_wc (font, text_iter, word_end - text_iter) > max_width) {
+				if (word_start == text_iter) {
+					if (confine) {
+						/* We must force-split the word.  Look for a proper
+                                                 * place to do it.
+						 */
+
+						w_len = word_end - word_start;
+
+						for (i = 1; i < w_len; i++) {
+							w = gdk_text_width_wc (font, word_start, i);
+							if (w > max_width) {
+								if (i == 1)
+									/* Shit, not even a single character fits */
+									max_width = w;
+								else
+									break;
+							}
+						}
+
+						/* Create sub-row with the chars that fit */
+
+						sub_text = g_new (GdkWChar, i);
+						memcpy (sub_text, word_start, (i - 1) * sizeof (GdkWChar));
+						sub_text[i - 1] = 0;
+						
+						row = g_new (GnomeIconTextInfoRow, 1);
+						row->text_wc = sub_text;
+						row->text_length = i - 1;
+						row->width = gdk_text_width_wc (font, sub_text, i - 1);
+						row->text = gdk_wcstombs(sub_text);
+						if (row->text == NULL)
+							row->text = g_strdup("");
+
+						ti->rows = g_list_append (ti->rows, row);
+
+						if (row->width > ti->width)
+							ti->width = row->width;
+
+						ti->height += ti->baseline_skip;
+
+						/* Bump the text pointer */
+
+						text_iter += i - 1;
+						s = text_iter;
+
+						continue;
+					} else
+						max_width = gdk_text_width_wc (font, word_start, word_end - word_start);
+
+					continue; /* Retry split */
+				} else {
+					word_end = old_word_end; /* Restore to region that does fit */
+					break; /* Stop the loop because we found something that doesn't fit */
+				}
+			}
+
+			s = word_end;
+		}
+
+		/* Append row */
+
+		if (text_iter == row_end) {
+			/* We are on a newline, so append an empty row */
+
+			ti->rows = g_list_append (ti->rows, NULL);
+			ti->height += ti->baseline_skip / 2;
+
+			/* Next! */
+
+			text_iter = row_end + 1;
+		} else {
+			/* Create subrow and append it to the list */
+
+			int sub_len;
+			sub_len = word_end - text_iter;
+
+			sub_text = g_new (GdkWChar, sub_len + 1);
+			memcpy (sub_text, text_iter, sub_len * sizeof (GdkWChar));
+			sub_text[sub_len] = 0;
+
+			row = g_new (GnomeIconTextInfoRow, 1);
+			row->text_wc = sub_text;
+			row->text_length = sub_len;
+			row->width = gdk_text_width_wc (font, sub_text, sub_len);
+			row->text = gdk_wcstombs(sub_text);
+			if (row->text == NULL)
+				row->text = g_strdup("");
+
+			ti->rows = g_list_append (ti->rows, row);
+
+			if (row->width > ti->width)
+				ti->width = row->width;
+
+			ti->height += ti->baseline_skip;
+
+			/* Next! */
+
+			text_iter = word_end;
+		}
+	}
+
+	g_free (text_wc);
+	g_free (separators_wc);
+	return ti;
+}
+
+/**
+ * gnome_icon_paint_text:
+ * @ti:       An icon text info structure.
+ * @drawable: Target drawable.
+ * @gc:       GC used to render the string.
+ * @x:        Left coordinate for text.
+ * @y:        Upper coordinate for text.
+ * @just:     Justification for text.
+ *
+ * Paints the formatted text in the icon text info structure onto a drawable.
+ * This is just a sample implementation; applications can choose to use other
+ * rendering functions.
+ */
+void
+gnome_icon_paint_text (GnomeIconTextInfo *ti, GdkDrawable *drawable, GdkGC *gc,
+		       gint x, gint y, GtkJustification just)
+{
+	GList *item;
+	GnomeIconTextInfoRow *row;
+	int xpos;
+
+	g_return_if_fail (ti != NULL);
+	g_return_if_fail (drawable != NULL);
+	g_return_if_fail (gc != NULL);
+
+	y += ti->font->ascent;
+
+	for (item = ti->rows; item; item = item->next) {
+		if (item->data) {
+			row = item->data;
+
+			switch (just) {
+			case GTK_JUSTIFY_LEFT:
+				xpos = 0;
+				break;
+
+			case GTK_JUSTIFY_RIGHT:
+				xpos = ti->width - row->width;
+				break;
+
+			case GTK_JUSTIFY_CENTER:
+				xpos = (ti->width - row->width) / 2;
+				break;
+
+			default:
+				/* Anyone care to implement GTK_JUSTIFY_FILL? */
+				g_warning ("Justification type %d not supported.  Using left-justification.",
+					   (int) just);
+				xpos = 0;
+			}
+
+			gdk_draw_text_wc (drawable, ti->font, gc, x + xpos, y, row->text_wc, row->text_length);
+
+			y += ti->baseline_skip;
+		} else
+			y += ti->baseline_skip / 2;
+	}
+}
diff --git a/libgnomeui/gnome-icon-text.h b/libgnomeui/gnome-icon-text.h
new file mode 100644
index 0000000..fd90eda
--- /dev/null
+++ b/libgnomeui/gnome-icon-text.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#ifndef GNOME_ICON_TEXT_H
+#define GNOME_ICON_TEXT_H
+
+
+
+G_BEGIN_DECLS
+
+typedef struct {
+	gchar *text;
+	GdkWChar *text_wc;	/* text in wide characters */
+	gint width;
+	gint text_length;	/* number of characters */
+} GnomeIconTextInfoRow;
+
+typedef struct {
+	GList *rows;
+	GdkFont *font;
+	gint width;
+	gint height;
+	gint baseline_skip;
+} GnomeIconTextInfo;
+
+GnomeIconTextInfo *gnome_icon_layout_text    (GdkFont *font, const gchar *text,
+					      const gchar *separators, gint max_width,
+					      gboolean confine);
+
+void               gnome_icon_paint_text     (GnomeIconTextInfo *ti,
+					      GdkDrawable *drawable, GdkGC *gc,
+					      gint x, gint y,
+					      GtkJustification just);
+
+void               gnome_icon_text_info_free (GnomeIconTextInfo *ti);
+
+G_END_DECLS
+
+#endif /* GNOME_ICON_TEXT_H */
diff --git a/libgnomeui/gnome-less.c b/libgnomeui/gnome-less.c
new file mode 100644
index 0000000..db9d3f3
--- /dev/null
+++ b/libgnomeui/gnome-less.c
@@ -0,0 +1,823 @@
+/* gnome-less.c:
+ * Copyright (C) 1998 Free Software Foundation
+ * All rights reserved.
+ *
+ * Written by: Havoc Pennington
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#include <config.h>
+#include "gnome-macros.h"
+
+#include "gnome-less.h"
+
+
+#include <libgnome/gnome-util.h>
+
+#include <libgnome/gnome-i18n.h>
+
+#include <libgnomeui/gnome-uidefs.h>
+
+#include <unistd.h>
+#include <time.h>
+#include <string.h> /* memset */
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+struct _GnomeLessPrivate {
+	GtkTextTag *text_tag;
+
+	PangoFontDescription *font_desc;
+
+	int columns;
+};
+
+static void gnome_less_class_init (GnomeLessClass *klass);
+static void gnome_less_init       (GnomeLess      *messagebox);
+
+static void gnome_less_destroy    (GtkObject      *object);
+static void gnome_less_finalize   (GObject        *object);
+
+GNOME_CLASS_BOILERPLATE (GnomeLess, gnome_less,
+			 GtkHBox, gtk_hbox)
+
+static void
+gnome_less_class_init (GnomeLessClass *klass)
+{
+  GtkObjectClass *object_class;
+  GObjectClass *gobject_class;
+
+  object_class = (GtkObjectClass*) klass;
+  gobject_class = (GObjectClass*) klass;
+
+  object_class->destroy = gnome_less_destroy;
+  gobject_class->finalize = gnome_less_finalize;
+}
+
+static void
+gnome_less_init (GnomeLess *gl)
+{
+	GtkWidget * vscroll;
+	GtkTextIter start, end;
+
+	gtk_box_set_homogeneous(GTK_BOX(gl), FALSE);
+	gtk_box_set_spacing(GTK_BOX(gl), 0);
+
+	gl->_priv = g_new0(GnomeLessPrivate, 1);
+
+	gl->_priv->columns = -1;
+
+	gl->_priv->font_desc = pango_font_description_copy(GTK_WIDGET(gl)->style->font_desc);
+
+	gl->text_buffer = GTK_TEXT_BUFFER(gtk_text_buffer_new(NULL));
+	gtk_object_ref(GTK_OBJECT(gl->text_buffer));
+	gl->text_view = GTK_TEXT_VIEW(gtk_text_view_new_with_buffer(gl->text_buffer));
+	gtk_object_set(GTK_OBJECT(gl->text_view),
+		       "editable", FALSE,
+		       NULL);
+	gtk_widget_ref(GTK_WIDGET(gl->text_view));
+	gtk_widget_show(GTK_WIDGET(gl->text_view));
+
+	/* FIXME: this is because gtktextview is broke! */
+	gtk_widget_set_scroll_adjustments(GTK_WIDGET(gl->text_view), NULL, NULL);
+
+	gl->_priv->text_tag = gtk_text_buffer_create_tag(gl->text_buffer, "text_tag", "font_desc", gl->_priv->font_desc, NULL);
+	gtk_text_buffer_get_bounds(gl->text_buffer, &start, &end);
+	gtk_text_buffer_apply_tag_by_name(gl->text_buffer, "text_tag", &start, &end);
+
+	vscroll = gtk_vscrollbar_new(gl->text_view->vadjustment);
+	gtk_widget_show(vscroll);
+
+	gtk_box_pack_start(GTK_BOX(gl), GTK_WIDGET(gl->text_view),
+			   TRUE, TRUE, 0);
+	gtk_box_pack_start(GTK_BOX(gl), vscroll, FALSE, FALSE, 0);
+
+	/* Since horizontal scroll doesn't work, use this hack. */
+	gtk_widget_set_usize(GTK_WIDGET(gl->text_view), 300, -1); 
+	gtk_text_view_set_wrap_mode(gl->text_view, GTK_WRAP_WORD);
+}
+
+/**
+ * gnome_less_new
+ *
+ * Description:  Creates a new #GnomeLess widget.
+ * 
+ * Returns: #GtkWidget pointer to a new #GnomeLess widget
+ **/
+
+GtkWidget* gnome_less_new (void)
+{
+  GnomeLess * gl;
+  
+  gl = gtk_type_new(gnome_less_get_type());
+
+  return GTK_WIDGET (gl);
+}
+
+/**
+ * gnome_less_new_fixed_font:
+ * @columns: the number of visible columns
+ *
+ * Description:  Creates a new #GnomeLess widget with the fixed font
+ * and with the specified number of columns visible.
+ * 
+ * Returns: #GtkWidget pointer to a new #GnomeLess widget
+ **/
+
+GtkWidget *
+gnome_less_new_fixed_font(int columns)
+{
+	GnomeLess * gl;
+
+	gl = gtk_type_new(gnome_less_get_type());
+
+	gnome_less_set_font_fixed(gl);
+	gnome_less_set_width_columns(gl, columns);
+
+	return GTK_WIDGET (gl);
+}
+
+static void gnome_less_destroy (GtkObject *object)
+{
+	GnomeLess *gl;
+
+	/* remember, destroy can be run multiple times! */
+
+	g_return_if_fail(object != NULL);
+	g_return_if_fail(GNOME_IS_LESS(object));
+
+	gl = GNOME_LESS(object);
+
+	if(gl->text_buffer)
+		gtk_object_unref(GTK_OBJECT(gl->text_buffer));
+	gl->text_buffer = NULL;
+
+	if(gl->text_view)
+		gtk_widget_unref(GTK_WIDGET(gl->text_view));
+	gl->text_view = NULL;
+
+	if(gl->_priv->font_desc)
+		pango_font_description_free(gl->_priv->font_desc);
+	gl->_priv->font_desc = NULL;
+
+	GNOME_CALL_PARENT_HANDLER (GTK_OBJECT_CLASS, destroy, (object));
+}
+
+static void gnome_less_finalize (GObject *object)
+{
+	GnomeLess *gl;
+
+	g_return_if_fail(object != NULL);
+	g_return_if_fail(GNOME_IS_LESS(object));
+
+	gl = GNOME_LESS(object);
+
+	g_free(gl->_priv);
+	gl->_priv = NULL;
+
+	GNOME_CALL_PARENT_HANDLER (G_OBJECT_CLASS, finalize, (object));
+}
+
+/**
+ * gnome_less_append_file
+ * @gl: Pointer to GnomeLess widget
+ * @path: Pathname of file to be displayed
+ *
+ * Displays a file in a GnomeLess widget.  Appending to any text currently in the widget
+ *
+ * Returns:
+ * %TRUE if successful, %FALSE if not. Error stored in %errno.
+ **/
+gboolean
+gnome_less_append_file(GnomeLess * gl, const gchar * path)
+{
+  FILE * f;
+
+  g_return_val_if_fail(gl != NULL, FALSE);
+  g_return_val_if_fail(GNOME_IS_LESS(gl), FALSE);
+  g_return_val_if_fail(path != NULL, FALSE);
+
+  if ( ! g_file_test(path, G_FILE_TEST_EXISTS) ) {
+    /* Leave errno from the stat in g_file_test */
+    return FALSE;
+  }
+
+  f = fopen(path, "rt");
+
+  if ( f == NULL ) {
+    /* Leave errno */
+    return FALSE;
+  }
+
+  if ( ! gnome_less_append_filestream(gl, f) ) {
+    /* Starting to feel like exceptions would be nice. */
+    int save_errno = errno;
+    fclose(f); /* nothing to do if it fails */
+    errno = save_errno;  /* Want to report the root cause of the error */
+    return FALSE;
+  }
+
+  if (fclose(f) != 0) {
+    return FALSE;
+  }
+  else return TRUE;
+}
+
+/**
+ * gnome_less_show_file
+ * @gl: Pointer to GnomeLess widget
+ * @path: Pathname of file to be displayed
+ *
+ * Displays a file in a GnomeLess widget. Replaces any text already being displayed
+ * in the widget.
+ *
+ * Returns:
+ * %TRUE if successful, %FALSE if not. Error stored in %errno.
+ **/
+gboolean
+gnome_less_show_file(GnomeLess * gl, const gchar * path)
+{
+	g_return_val_if_fail(gl != NULL, FALSE);
+	g_return_val_if_fail(GNOME_IS_LESS(gl), FALSE);
+	g_return_val_if_fail(path != NULL, FALSE);
+
+	gnome_less_clear(gl);
+	return gnome_less_append_file(gl, path);
+}
+
+/**
+ * gnome_less_append_command
+ * @gl: Pointer to GnomeLess widget
+ * @command_line: Command to be executed
+ *
+ * Runs the shell command specified in @command_line, and places the output of that command
+ * in the GnomeLess widget specified by @gl.  Appends to any text currently in the widget.
+ *
+ * Returns:
+ * %TRUE if successful, %FALSE if not. Error stored in %errno.
+ **/
+gboolean
+gnome_less_append_command(GnomeLess * gl,
+			  const gchar * command_line)
+{
+  FILE * p;
+
+  g_return_val_if_fail(gl != NULL, FALSE);
+  g_return_val_if_fail(GNOME_IS_LESS(gl), FALSE);
+  g_return_val_if_fail(command_line != NULL, FALSE);
+  
+  p = popen(command_line, "r");
+
+  if ( p == NULL ) {
+    return FALSE;
+  }
+
+  if ( ! gnome_less_append_filestream(gl, p) ) {
+    int save_errno = errno;
+    pclose(p); /* nothing to do if it fails */
+    errno = save_errno; /* Report the root cause of the error */
+    return FALSE;
+  }
+
+  if ( pclose(p) == -1 ) {
+    return FALSE;
+  }
+  else return TRUE;
+}
+
+/**
+ * gnome_less_show_command
+ * @gl: Pointer to GnomeLess widget
+ * @command_line: Command to be executed
+ *
+ * Runs the shell command specified in @command_line, and places the output of that command
+ * in the GnomeLess widget specified by @gl. Replaces any text already being displayed in the
+ * widget.
+ *
+ * Returns:
+ * %TRUE if successful, %FALSE if not. Error stored in %errno.
+ **/
+
+gboolean
+gnome_less_show_command(GnomeLess * gl,
+			const gchar * command_line)
+{
+	g_return_val_if_fail(gl != NULL, FALSE);
+	g_return_val_if_fail(GNOME_IS_LESS(gl), FALSE);
+	g_return_val_if_fail(command_line != NULL, FALSE);
+
+	gnome_less_clear(gl);
+	return gnome_less_append_command(gl, command_line);
+}
+
+#define GLESS_BUFSIZE 1024
+
+/**
+ * gnome_less_append_filestream
+ * @gl: Pointer to GnomeLess widget
+ * @f: Filestream to be displayed in the widget
+ *
+ * Reads all of the text from filestream @f, and places it in the GnomeLess widget @gl.
+ * Appends to any text already in the widget
+ *
+ * Returns:
+ * %TRUE if successful, %FALSE if not. Error stored in %errno.
+ **/
+
+gboolean gnome_less_append_filestream(GnomeLess * gl, FILE * f)
+{
+  gchar buffer [GLESS_BUFSIZE];
+  gchar * s;
+
+  g_return_val_if_fail(gl != NULL, FALSE);
+  g_return_val_if_fail(GNOME_IS_LESS(gl), FALSE);
+  g_return_val_if_fail(f != NULL, FALSE);
+
+  errno = 0; /* Reset it to detect errors */
+  while (TRUE) {
+	  GtkTextIter start, end;
+
+	  s = fgets(buffer, GLESS_BUFSIZE, f);
+
+	  if ( s == NULL ) break;
+
+	  gtk_text_buffer_get_bounds(gl->text_buffer, &start, &end);
+	  gtk_text_buffer_insert(gl->text_buffer, &end, buffer, strlen(buffer));
+	  gtk_text_buffer_get_bounds(gl->text_buffer, &start, &end);
+	  gtk_text_buffer_apply_tag_by_name(gl->text_buffer, "text_tag", &start, &end);
+  }
+
+  if ( errno != 0 ) {
+    /* We quit on an error, not EOF */
+    return FALSE;
+  }
+  else {
+    return TRUE;
+  }
+}
+
+/**
+ * gnome_less_show_filestream
+ * @gl: Pointer to GnomeLess widget
+ * @f: Filestream to be displayed in the widget
+ *
+ * Reads all of the text from filestream @f, and places it in the GnomeLess widget @gl. Replaces any text
+ * already being displayed.
+ *
+ * Returns:
+ * %TRUE if successful, %FALSE if not. Error stored in %errno.
+ **/
+
+gboolean gnome_less_show_filestream(GnomeLess * gl, FILE * f)
+{
+  g_return_val_if_fail(gl != NULL, FALSE);
+  g_return_val_if_fail(GNOME_IS_LESS(gl), FALSE);
+  g_return_val_if_fail(f != NULL, FALSE);
+
+  gnome_less_clear(gl);
+  return gnome_less_append_filestream(gl, f);
+}
+
+/**
+ * gnome_less_append_fd
+ * @gl: Pointer to GnomeLess widget
+ * @file_descriptor: Filestream to be displayed in the widget
+ *
+ * Reads all of the text from file descriptor @file_descriptor, and places it in the GnomeLess widget @gl.
+ * Appends to any text already being displayed.
+ *
+ * Returns:
+ * %TRUE if successful, %FALSE if not. Error stored in %errno.
+ **/
+
+gboolean
+gnome_less_append_fd(GnomeLess * gl, int file_descriptor)
+{
+  FILE * f;
+
+  g_return_val_if_fail(gl != NULL, FALSE);
+  g_return_val_if_fail(GNOME_IS_LESS(gl), FALSE);
+
+  f = fdopen(file_descriptor, "r");
+
+  if ( f && gnome_less_append_filestream(gl, f) ) {
+    return TRUE;
+  }
+  else return FALSE;
+}
+
+/**
+ * gnome_less_show_fd
+ * @gl: Pointer to GnomeLess widget
+ * @file_descriptor: Filestream to be displayed in the widget
+ *
+ * Reads all of the text from file descriptor @file_descriptor, and places it in the GnomeLess widget @gl.
+ * Replaces any text already being displayed.
+ *
+ * Returns:
+ * %TRUE if successful, %FALSE if not. Error stored in %errno.
+ **/
+
+gboolean
+gnome_less_show_fd(GnomeLess * gl, int file_descriptor)
+{
+	g_return_val_if_fail(gl != NULL, FALSE);
+	g_return_val_if_fail(GNOME_IS_LESS(gl), FALSE);
+
+	gnome_less_clear(gl);
+	return gnome_less_append_fd(gl, file_descriptor);
+}
+
+/**
+ * gnome_less_append_string:
+ * @gl: Pointer to GnomeLess widget
+ * @s: String to be displayed
+ *
+ * Description: Appends the @s string to any string already displayed in the
+ * widget.
+ **/
+void
+gnome_less_append_string(GnomeLess * gl, const gchar * s)
+{
+	GtkTextIter start, end;
+
+	g_return_if_fail(gl != NULL);
+	g_return_if_fail(GNOME_IS_LESS(gl));
+	g_return_if_fail(s != NULL);
+
+	gtk_text_buffer_get_bounds(gl->text_buffer, &start, &end);
+	gtk_text_buffer_insert(gl->text_buffer, &end, s, strlen(s));
+	gtk_text_buffer_get_bounds(gl->text_buffer, &start, &end);
+	gtk_text_buffer_apply_tag_by_name(gl->text_buffer, "text_tag", &start, &end);
+}
+
+/**
+ * gnome_less_show_string
+ * @gl: Pointer to GnomeLess widget
+ * @s: String to be displayed
+ *
+ * Displays a string in the GnomeLess widget @gl. Replaces any text
+ * already being displayed.
+ *
+ **/
+ 
+void gnome_less_show_string(GnomeLess * gl, const gchar * s)
+{
+  g_return_if_fail(gl != NULL);
+  g_return_if_fail(GNOME_IS_LESS(gl));
+  g_return_if_fail(s != NULL);
+
+  gnome_less_clear(gl);
+  gnome_less_append_string(gl, s);
+}
+
+/**
+ * gnome_less_clear
+ * @gl: Pointer to GnomeLess widget
+ *
+ * Clears all text from GnomeLess widget @gl.
+ **/
+
+void gnome_less_clear (GnomeLess * gl)
+{
+  GtkTextIter start, end;
+
+  g_return_if_fail(gl != NULL);
+  g_return_if_fail(GNOME_IS_LESS(gl));
+
+  gtk_text_buffer_get_bounds(gl->text_buffer, &start, &end);
+  gtk_text_buffer_delete(gl->text_buffer, &start, &end);
+}
+
+/**
+ * gnome_less_write_fd 
+ * @gl: Pointer to GnomeLess widget
+ * @fd: File descriptor
+ *
+ * Writes the text displayed in the GnomeLess widget @gl to file descriptor @fd.
+ *
+ * Returns: %TRUE if successful, %FALSE if not. Error stored in %errno.
+ **/
+
+gboolean
+gnome_less_write_fd(GnomeLess * gl, int fd)
+{
+	gchar * contents;
+	gint len;
+	gint bytes_written;
+	GtkTextIter start, end;
+
+
+	g_return_val_if_fail(gl != NULL, FALSE);
+	g_return_val_if_fail(GNOME_IS_LESS(gl), FALSE);
+	g_return_val_if_fail(fd >= 0, FALSE);
+
+	gtk_text_buffer_get_bounds(gl->text_buffer, &start, &end);
+	contents = gtk_text_buffer_get_text(gl->text_buffer, &start, &end, FALSE);
+	if(contents)
+		len = strlen(contents);
+	else
+		len = 0;
+
+	if(len > 0)
+		bytes_written = write(fd, contents, len);
+	else
+		bytes_written = 0;
+
+	g_free(contents); 
+
+	if(bytes_written != len)
+		return FALSE;
+	else
+		return TRUE;
+}
+
+/**
+ * gnome_less_write_file
+ * @gl: Pointer to GnomeLess widget
+ * @path: Path of file to be written
+ *
+ * Writes the text displayed in the GnomeLess widget @gl to the file specified by @path.
+ *
+ * Returns: %TRUE if successful, %FALSE if not. Error stored in %errno.
+ **/
+
+gboolean gnome_less_write_file   (GnomeLess * gl, const gchar * path)
+{
+  int fd;
+
+  g_return_val_if_fail(gl != NULL, FALSE);
+  g_return_val_if_fail(GNOME_IS_LESS(gl), FALSE);
+  g_return_val_if_fail(path != NULL, FALSE);
+  
+  fd = open( path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR );
+
+  if ( fd == -1 ) return FALSE; /* Leaving errno set */
+
+  if ( ! gnome_less_write_fd(gl, fd) ) {
+    int save_errno = errno;
+    close(fd); /* If it fails, nothing to do */
+    errno = save_errno; /* Return root cause of problem. */
+    return FALSE;
+  }
+
+  if ( close(fd) != 0 ) {
+    /* Error, leave errno and return */
+    return FALSE;
+  }
+  else return TRUE;
+}
+
+static void
+setup_columns(GnomeLess *gl)
+{
+	if(gl->_priv->columns <= 0) {
+		/* Set to 300 pixels if no columns */
+		gtk_widget_set_usize(GTK_WIDGET(gl->text_view), 300, -1); 
+	} else {
+		int i;
+		char *text = g_new(char, gl->_priv->columns + 1);
+		PangoLayout *layout;
+		PangoRectangle rect;
+
+		for(i = 0; i < gl->_priv->columns; i++)
+			text[i] = 'X';
+		text[i] = '\0';
+
+		layout = gtk_widget_create_pango_layout(GTK_WIDGET(gl), text);
+		pango_layout_set_font_description(layout, gl->_priv->font_desc);
+
+		pango_layout_set_width(layout, -1);
+		pango_layout_get_extents(layout, NULL, &rect);
+
+		gtk_widget_set_usize(GTK_WIDGET(gl->text_view),
+				     PANGO_PIXELS(rect.width) + 6, -1); 
+
+		g_object_unref(G_OBJECT(layout));
+	}
+}
+
+/**
+ * gnome_less_set_font_string:
+ * @gl: Pointer to GnomeLess widget
+ * @font: text of the string.
+ *
+ * Description:  Sets the current font of the widget to the @font.
+ * This should be in the format that pango understands such as "Sans 12"
+ **/
+void
+gnome_less_set_font_string(GnomeLess * gl, const gchar * font)
+{
+	g_return_if_fail(gl != NULL);
+	g_return_if_fail(GNOME_IS_LESS(gl));
+	g_return_if_fail(font != NULL);
+
+	pango_font_description_free(gl->_priv->font_desc);
+	gl->_priv->font_desc = pango_font_description_from_string(font);
+
+	gtk_object_set(GTK_OBJECT(gl->_priv->text_tag),
+		       "font_desc", gl->_priv->font_desc,
+		       NULL);
+
+	setup_columns(gl);
+}
+
+/**
+ * gnome_less_set_font_description:
+ * @gl: Pointer to GnomeLess widget
+ * @font_desc: the PangoFontDescription of the text
+ *
+ * Description:  Sets the current font of the widget to the @font_desc.
+ **/
+void
+gnome_less_set_font_description(GnomeLess * gl, const PangoFontDescription * font_desc)
+{
+	g_return_if_fail(gl != NULL);
+	g_return_if_fail(GNOME_IS_LESS(gl));
+	g_return_if_fail(font_desc != NULL);
+
+	pango_font_description_free(gl->_priv->font_desc);
+	gl->_priv->font_desc = pango_font_description_copy(font_desc);
+
+	gtk_object_set(GTK_OBJECT(gl->_priv->text_tag),
+		       "font_desc", gl->_priv->font_desc,
+		       NULL);
+
+	setup_columns(gl);
+}
+
+/**
+ * gnome_less_set_font_fixed:
+ * @gl: Pointer to GnomeLess widget
+ *
+ * Description:  Sets the current font to the "fixed" font.
+ * This is useful for displaying things that need to be ordered
+ * in columns.
+ **/
+void
+gnome_less_set_font_fixed(GnomeLess * gl)
+{
+	char *font;
+
+	g_return_if_fail(gl != NULL);
+	g_return_if_fail(GNOME_IS_LESS(gl));
+
+	pango_font_description_free(gl->_priv->font_desc);
+	font = g_strdup_printf("fixed %d", GTK_WIDGET(gl)->style->font_desc->size / PANGO_SCALE);
+	gl->_priv->font_desc = pango_font_description_from_string(font);
+	g_free(font);
+
+	gtk_object_set(GTK_OBJECT(gl->_priv->text_tag),
+		       "font_desc", gl->_priv->font_desc,
+		       NULL);
+
+	setup_columns(gl);
+}
+
+/**
+ * gnome_less_set_font_standard:
+ * @gl: Pointer to GnomeLess widget
+ *
+ * Description:  Sets the current font to the standard font
+ * This is the font that's from the current style of the widget.
+ **/
+void
+gnome_less_set_font_standard(GnomeLess * gl)
+{
+	g_return_if_fail(gl != NULL);
+	g_return_if_fail(GNOME_IS_LESS(gl));
+
+	pango_font_description_free(gl->_priv->font_desc);
+	gl->_priv->font_desc = pango_font_description_copy(GTK_WIDGET(gl)->style->font_desc);
+
+	gtk_object_set(GTK_OBJECT(gl->_priv->text_tag),
+		       "font_desc", gl->_priv->font_desc,
+		       NULL);
+
+	setup_columns(gl);
+}
+
+
+/**
+ * gnome_less_set_width_columns:
+ * @gl: Pointer to GnomeLess widget
+ * @columns: number of columns
+ *
+ * Description:  Sets the number of visible columns.  This will
+ * only work well with fixed width fonts, such as "fixed"
+ **/
+void
+gnome_less_set_width_columns(GnomeLess * gl, int columns)
+{
+	g_return_if_fail(gl != NULL);
+	g_return_if_fail(GNOME_IS_LESS(gl));
+
+	gl->_priv->columns = columns;
+
+	setup_columns(gl);
+}
+
+/**
+ * gnome_less_set_wrap_mode:
+ * @gl: Pointer to GnomeLess widget
+ * @wrap_mode: The wrap mode to set
+ *
+ * Description:  Sets the wrap mode of the internal text widget to
+ * @wrap_mode.
+ **/
+void
+gnome_less_set_wrap_mode(GnomeLess * gl, GtkWrapMode wrap_mode)
+{
+	g_return_if_fail(gl != NULL);
+	g_return_if_fail(GNOME_IS_LESS(gl));
+
+	gtk_text_view_set_wrap_mode(gl->text_view, wrap_mode);
+}
+
+/**
+ * gnome_less_get_font_description:
+ * @gl: Pointer to GnomeLess widget
+ *
+ * Description:  Gets the font description currently used
+ * in the widget;
+ *
+ * Returns:  A new copy of the font description, you should
+ * free it yourself.
+ **/
+PangoFontDescription *
+gnome_less_get_font_description(GnomeLess * gl)
+{
+	g_return_val_if_fail(gl != NULL, NULL);
+	g_return_val_if_fail(GNOME_IS_LESS(gl), NULL);
+
+	return pango_font_description_copy(gl->_priv->font_desc);
+}
+
+
+#ifndef GNOME_EXCLUDE_DEPRECATED_SOURCE
+
+/***************************************************************************/
+/* DEPRECATED */
+/**
+ * gnome_less_reshow
+ * @gl: Pointer to GnomeLess widget
+ *
+ * Description: Deprecated
+ **/
+ 
+void gnome_less_reshow(GnomeLess * gl)
+{
+	g_warning("gnome_less_reshow deprecated, font is now updated on the fly");
+}
+
+/**
+ * gnome_less_set_font
+ * @gl: Pointer to GnomeLess widget
+ * @font: Pointer to GdkFont
+ *
+ * Description: Deprecated, use #gnome_less_set_font_string
+ **/
+
+void gnome_less_set_font(GnomeLess * gl, GdkFont * font)
+{
+	g_warning("gnome_less_set_font deprecated, use gnome_less_set_font_string");
+}
+
+/**
+ * gnome_less_set_fixed_font
+ * @gl: Pointer to GNOME Less widget
+ * @fixed: Whether or not to use a fixed font
+ *
+ * Description:  Deprecated, use #gnome_less_set_font_fixed
+ **/
+void gnome_less_set_fixed_font  (GnomeLess * gl, gboolean fixed)
+{
+	g_warning("gnome_less_set_fixed_font deprecated, use gnome_less_set_font_fixed");
+
+	if(fixed) {
+		gnome_less_set_font_fixed(gl);
+	} else {
+		gnome_less_set_font_standard(gl);
+	}
+}
+
+#endif /* not GNOME_EXCLUDE_DEPRECATED_SOURCE */
+
diff --git a/libgnomeui/gnome-less.h b/libgnomeui/gnome-less.h
new file mode 100644
index 0000000..6e75c10
--- /dev/null
+++ b/libgnomeui/gnome-less.h
@@ -0,0 +1,128 @@
+/* gnome-less.h:
+ * Copyright (C) 1998,2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * A simple GtkText wrapper with a scroll bar, convenience functions,
+ * and a right-click popup menu. For displaying info to the user,
+ * like a license agreement for example. OK, bad example. :-)
+ * Written by: Havoc Pennington
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#ifndef GNOME_LESS_H
+#define GNOME_LESS_H
+
+
+#include <gtk/gtk.h>
+#include <stdio.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GnomeLess        GnomeLess;
+typedef struct _GnomeLessPrivate GnomeLessPrivate;
+typedef struct _GnomeLessClass   GnomeLessClass;
+
+#define GNOME_TYPE_LESS            (gnome_less_get_type ())
+#define GNOME_LESS(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_LESS, GnomeLess))
+#define GNOME_LESS_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_LESS, GnomeLessClass))
+#define GNOME_IS_LESS(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_LESS))
+#define GNOME_IS_LESS_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_LESS))
+#define GNOME_LESS_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_LESS, GnomeLessClass))
+
+struct _GnomeLess {
+	GtkHBox hbox;
+
+	/*< public >*/
+	GtkTextView *text_view; 
+	GtkTextBuffer *text_buffer;
+
+	/*< private >*/
+	GnomeLessPrivate *_priv;
+};
+
+struct _GnomeLessClass {
+	GtkHBoxClass parent_class;
+};
+
+GtkType  gnome_less_get_type		(void) G_GNUC_CONST;
+
+GtkWidget * gnome_less_new		(void);
+
+/* Sugar new function for program output */
+GtkWidget * gnome_less_new_fixed_font	(int columns);
+
+/* Clear the text */
+void     gnome_less_clear		(GnomeLess * gl);
+
+/* Append stuff to the widget.  TRUE on success, FALSE
+ * with errno set on failiure */
+gboolean gnome_less_append_file		(GnomeLess * gl, const gchar * path);
+gboolean gnome_less_append_command	(GnomeLess * gl, const gchar * command_line);
+void     gnome_less_append_string	(GnomeLess * gl, const gchar * s);
+gboolean gnome_less_append_filestream	(GnomeLess * gl, FILE * f);
+gboolean gnome_less_append_fd		(GnomeLess * gl, int file_descriptor);
+
+/* All these clear any existing text and show whatever you pass in. 
+   When applicable, they return TRUE on success, FALSE and set errno 
+   on failure. */
+gboolean gnome_less_show_file		(GnomeLess * gl, const gchar * path);
+gboolean gnome_less_show_command	(GnomeLess * gl, const gchar * command_line);
+void     gnome_less_show_string		(GnomeLess * gl, const gchar * s);
+gboolean gnome_less_show_filestream	(GnomeLess * gl, FILE * f);
+gboolean gnome_less_show_fd		(GnomeLess * gl, int file_descriptor);
+
+/* Write a file; returns FALSE and sets errno if either open
+   or close fails on the file. write_file overwrites any existing file. */
+gboolean gnome_less_write_file		(GnomeLess * gl, const gchar * path);
+gboolean gnome_less_write_fd		(GnomeLess * gl, int fd);
+
+/* Set an arbitrary font */
+void     gnome_less_set_font_string	(GnomeLess * gl, const char * font);
+/*
+ * Whether to use a fixed font for any future showings. 
+ * Recommended for anything that comes in columns, program code,
+ * etc. Just loads a fixed font and calls set_font above.
+ */
+void     gnome_less_set_font_fixed	(GnomeLess * gl);
+/* Sets the standard string */
+void     gnome_less_set_font_standard	(GnomeLess * gl);
+/* from a pango font description */
+void     gnome_less_set_font_description(GnomeLess * gl,
+					 const PangoFontDescription * font_desc);
+
+void     gnome_less_set_width_columns	(GnomeLess * gl, int columns);
+void     gnome_less_set_wrap_mode	(GnomeLess * gl, GtkWrapMode wrap_mode);
+
+PangoFontDescription *gnome_less_get_font_description(GnomeLess * gl);
+
+#ifndef GNOME_EXCLUDE_DEPRECATED
+/* DEPRECATED */
+/* Re-insert the text with the current font settings. */
+void gnome_less_reshow         		(GnomeLess * gl);
+void gnome_less_set_font		(GnomeLess * gl, GdkFont * font);
+void gnome_less_set_fixed_font		(GnomeLess * gl, gboolean fixed);
+#endif
+
+G_END_DECLS
+   
+#endif /* GNOME_LESS_H */
+
+
+
+
diff --git a/libgnomeui/gnome-macros.h b/libgnomeui/gnome-macros.h
new file mode 100644
index 0000000..2f31cdb
--- /dev/null
+++ b/libgnomeui/gnome-macros.h
@@ -0,0 +1,74 @@
+/* gnome-macros.h
+ *   Macros for making GTK+ objects to avoid typos and reduce code size
+ * Copyright (C) 2000  Eazel, Inc.
+ *
+ * Authors: George Lebl <jirka 5z com>
+ *
+ * All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#ifndef GNOME_MACROS_H
+#define GNOME_MACROS_H
+
+/* Macros for defining classes.  Ideas taken from Nautilus and GOB. */
+
+/* Define the boilerplate type stuff to reduce typos and code size.  Defines
+ * the get_type method and the parent_class static variable. */
+#define GNOME_CLASS_BOILERPLATE(type, type_as_function,			\
+				parent_type, parent_type_as_function)	\
+static parent_type *parent_class = NULL;				\
+GtkType									\
+type_as_function ## _get_type (void)					\
+{									\
+	static GtkType object_type = 0;					\
+	if (object_type == 0) {						\
+		GtkType type_of_parent;					\
+		static const GtkTypeInfo object_info = {		\
+			#type,						\
+			sizeof (type),					\
+			sizeof (type ## Class),				\
+			(GtkClassInitFunc) type_as_function ## _class_init, \
+			(GtkObjectInitFunc) type_as_function ## _init,	\
+			/* reserved_1 */ NULL,				\
+			/* reserved_2 */ NULL,				\
+			(GtkClassInitFunc) NULL				\
+		};							\
+		type_of_parent = parent_type_as_function ## _get_type (); \
+		object_type = gtk_type_unique (type_of_parent, &object_info); \
+		parent_class = gtk_type_class (type_of_parent);		\
+	}								\
+	return object_type;						\
+}
+
+/* Just call the parent handler.  This assumes that there is a variable
+ * named parent_class that points to the (duh!) parent class */
+#define GNOME_CALL_PARENT_HANDLER(parent_class_cast, name, args)	\
+	((parent_class_cast(parent_class)->name != NULL) ?		\
+	 parent_class_cast(parent_class)->name args : 0)
+
+/* Same as above, but in case there is no implementation, it evaluates
+ * to def_return */
+#define GNOME_CALL_PARENT_HANDLER_WITH_DEFAULT(parent_class_cast,	\
+					       name, args, def_return)	\
+	((parent_class_cast(parent_class)->name != NULL) ?		\
+	 parent_class_cast(parent_class)->name args : def_return)
+
+#endif /* GNOME_MACROS_H */
diff --git a/libgnomeui/gnome-mdi-child.c b/libgnomeui/gnome-mdi-child.c
new file mode 100644
index 0000000..2c3eae9
--- /dev/null
+++ b/libgnomeui/gnome-mdi-child.c
@@ -0,0 +1,378 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* gnome-mdi-child.c - implementation of an abstract class for MDI children
+
+   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+   All rights reserved.
+
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Jaka Mocnik <jaka mocnik kiss uni-lj si>
+*/
+/*
+  @NOTATION@
+*/
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include "gnome-app.h"
+#include "gnome-macros.h"
+#include "gnome-mdi-child.h"
+#include "gnome-mdi.h"
+#include "gnome-mdiP.h"
+
+static void       gnome_mdi_child_class_init       (GnomeMDIChildClass *klass);
+static void       gnome_mdi_child_init             (GnomeMDIChild *);
+static void       gnome_mdi_child_destroy          (GtkObject *);
+static void       gnome_mdi_child_finalize         (GObject *);
+
+static GtkWidget *gnome_mdi_child_set_label        (GnomeMDIChild *, GtkWidget *);
+static GtkWidget *gnome_mdi_child_create_view      (GnomeMDIChild *);
+
+GNOME_CLASS_BOILERPLATE (GnomeMDIChild, gnome_mdi_child,
+			 GtkObject, gtk_object);
+
+static void
+gnome_mdi_child_class_init (GnomeMDIChildClass *klass)
+{
+	GtkObjectClass *object_class;
+	GObjectClass *gobject_class;
+
+	object_class = (GtkObjectClass*)klass;
+	gobject_class = (GObjectClass*)klass;
+  
+	object_class->destroy = gnome_mdi_child_destroy;
+	gobject_class->finalize = gnome_mdi_child_finalize;
+  
+	klass->create_view = NULL;
+	klass->create_menus = NULL;
+	klass->get_config_string = NULL;
+	klass->set_label = gnome_mdi_child_set_label;
+}
+
+static void
+gnome_mdi_child_init (GnomeMDIChild *mdi_child)
+{
+	mdi_child->priv = g_new0(GnomeMDIChildPrivate, 1);
+
+	mdi_child->priv->name = NULL;
+	mdi_child->priv->parent = NULL;
+	mdi_child->priv->views = NULL;
+
+	mdi_child->priv->behavior = GNOME_DOCK_ITEM_BEH_NORMAL;
+	mdi_child->priv->placement = GNOME_DOCK_TOP;
+	mdi_child->priv->band_num = 101;
+	mdi_child->priv->band_pos = 0;
+	mdi_child->priv->offset = 0;
+}
+
+static GtkWidget *
+gnome_mdi_child_create_view (GnomeMDIChild *child)
+{
+	if(GNOME_MDI_CHILD_GET_CLASS(child)->create_view)
+		return GNOME_MDI_CHILD_GET_CLASS(child)->create_view(child);
+
+	return NULL;
+}
+
+/* the default set_label function: returns a GtkLabel with child->name
+ * if you provide your own, it should return a new widget if its old_label
+ * parameter is NULL and modify and return the old widget otherwise. it
+ * should (obviously) NOT call the parent class handler!
+ */
+static GtkWidget *
+gnome_mdi_child_set_label (GnomeMDIChild *child, GtkWidget *old_label)
+{
+#ifdef GNOME_ENABLE_DEBUG
+	g_message("GnomeMDIChild: default set_label handler called!\n");
+#endif
+
+	if(old_label) {
+		gtk_label_set_text(GTK_LABEL(old_label), child->priv->name);
+		return old_label;
+	}
+	else {
+		GtkWidget *label;
+
+		label = gtk_label_new(child->priv->name);
+		gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
+
+		return label;
+	}
+}
+
+static void
+gnome_mdi_child_finalize (GObject *obj)
+{
+	GnomeMDIChild *mdi_child;
+
+#ifdef GNOME_ENABLE_DEBUG
+	g_message("child finalization\n");
+#endif
+
+	mdi_child = GNOME_MDI_CHILD(obj);
+
+	if(mdi_child->priv->name)
+		g_free(mdi_child->priv->name);
+	mdi_child->priv->name = NULL;
+
+	GNOME_CALL_PARENT_HANDLER (G_OBJECT_CLASS, finalize, (obj));
+}
+
+static void
+gnome_mdi_child_destroy (GtkObject *obj)
+{
+	GnomeMDIChild *mdi_child;
+
+#ifdef GNOME_ENABLE_DEBUG
+	g_message("GnomeMDIChild: destroying!\n");
+#endif
+
+	/* remember, destroy can be run multiple times! */
+
+	mdi_child = GNOME_MDI_CHILD(obj);
+
+	while(mdi_child->priv->views)
+		gnome_mdi_child_remove_view(mdi_child,
+									GTK_WIDGET(mdi_child->priv->views->data));
+
+	GNOME_CALL_PARENT_HANDLER (GTK_OBJECT_CLASS, destroy, (obj));
+}
+
+void
+gnome_mdi_child_add_toolbar(GnomeMDIChild *mdi_child, GnomeApp *app,
+			    GtkToolbar *toolbar)
+{
+	g_return_if_fail (mdi_child != NULL);
+	g_return_if_fail (GNOME_IS_MDI_CHILD (mdi_child));
+	g_return_if_fail (app != NULL);
+	g_return_if_fail (GNOME_IS_APP (app));
+	g_return_if_fail (toolbar != NULL);
+	g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
+
+	gnome_app_add_toolbar (app, toolbar,
+			       GNOME_MDI_CHILD_TOOLBAR_NAME,
+			       mdi_child->priv->behavior,
+			       mdi_child->priv->placement,
+			       mdi_child->priv->band_num,
+			       mdi_child->priv->band_pos,
+			       mdi_child->priv->offset);
+}
+
+/**
+ * gnome_mdi_child_add_view:
+ * @mdi_child: A pointer to a GnomeMDIChild object.
+ * 
+ * Description:
+ * Creates a new view of a child (a GtkWidget) adds it to the list
+ * of the views and returns a pointer to it. Virtual function
+ * that has to be specified for classes derived from GnomeMDIChild
+ * is used to create the new view.
+ * 
+ * Return value:
+ * A pointer to the new view.
+ **/
+GtkWidget *
+gnome_mdi_child_add_view (GnomeMDIChild *mdi_child)
+{
+	GtkWidget *view = NULL;
+
+	g_return_val_if_fail(mdi_child != NULL, NULL);
+	g_return_val_if_fail(GNOME_IS_MDI_CHILD(mdi_child), NULL);
+
+	view = gnome_mdi_child_create_view(mdi_child);
+
+	if(view) {
+		mdi_child->priv->views = g_list_append(mdi_child->priv->views, view);
+
+		gtk_object_set_data(GTK_OBJECT(view), GNOME_MDI_CHILD_KEY, mdi_child);
+	}
+
+	return view;
+}
+
+/**
+ * gnome_mdi_child_remove_view:
+ * @mdi_child: A pointer to a GnomeMDIChild object.
+ * @view: View to be removed.
+ * 
+ * Description:
+ * Removes view @view from the list of @mdi_child's views and
+ * unrefs it.
+ **/
+void
+gnome_mdi_child_remove_view(GnomeMDIChild *mdi_child, GtkWidget *view)
+{
+	g_return_if_fail(mdi_child != NULL);
+	g_return_if_fail(GNOME_IS_MDI_CHILD(mdi_child));
+	g_return_if_fail(view != NULL);
+	g_return_if_fail(GTK_IS_WIDGET(view));
+
+	mdi_child->priv->views = g_list_remove(mdi_child->priv->views, view);
+
+	gtk_widget_unref(view);
+}
+
+/**
+ * gnome_mdi_child_set_name:
+ * @mdi_child: A pointer to a GnomeMDIChild object.
+ * @name: String containing the new name for the child.
+ * 
+ * Description:
+ * Changes name of @mdi_child to @name. @name is duplicated and stored
+ * in @mdi_child. If @mdi_child has already been added to GnomeMDI,
+ * it also takes care of updating it.
+ **/
+void
+gnome_mdi_child_set_name(GnomeMDIChild *mdi_child, const gchar *name)
+{
+	gchar *old_name;
+
+	g_return_if_fail(mdi_child != NULL);
+	g_return_if_fail(name != NULL);
+	g_return_if_fail(GNOME_IS_MDI_CHILD(mdi_child));
+
+	old_name = mdi_child->priv->name;
+
+	if(mdi_child->priv->parent)
+		gnome_mdi_child_list_remove(GNOME_MDI(mdi_child->priv->parent),
+									mdi_child);
+
+	mdi_child->priv->name = (gchar *)g_strdup(name);
+
+	if(old_name)
+		g_free(old_name);
+
+	if(mdi_child->priv->parent) {
+		gnome_mdi_child_list_add(GNOME_MDI(mdi_child->priv->parent), mdi_child);
+		gnome_mdi_update_child(GNOME_MDI(mdi_child->priv->parent), mdi_child);
+	}
+}
+
+/**
+ * gnome_mdi_child_get_name:
+ * @mdi_child: A pointer to a GnomeMDIChild object.
+ * 
+ * Description:
+ * Retrieves the @child's name.
+ *
+ * Return value:
+ * @child's name.
+ **/
+const gchar *
+gnome_mdi_child_get_name(GnomeMDIChild *mdi_child)
+{
+	g_return_val_if_fail(mdi_child != NULL, NULL);
+	g_return_val_if_fail(GNOME_IS_MDI_CHILD(mdi_child), NULL);
+
+	return mdi_child->priv->name;
+}
+
+/**
+ * gnome_mdi_child_set_menu_template:
+ * @mdi_child: A pointer to a GnomeMDIChild object.
+ * @menu_tmpl: A GnomeUIInfo array describing the child specific menus.
+ * 
+ * Description:
+ * Sets the template for menus that are added and removed when differrent
+ * children get activated. This way, each child can modify the MDI menubar
+ * to suit its needs. If no template is set, the create_menus virtual
+ * function will be used for creating these menus (it has to return a
+ * GList of menu items). If no such function is specified, the menubar will
+ * be unchanged by MDI children, but one can still modify the menubar
+ * using handlers for GnomeMDI view_changed or child_changed signal.
+ **/
+void
+gnome_mdi_child_set_menu_template (GnomeMDIChild *mdi_child,
+				   GnomeUIInfo *menu_tmpl)
+{
+	g_return_if_fail(mdi_child != NULL);
+	g_return_if_fail(GNOME_IS_MDI_CHILD(mdi_child));
+
+	mdi_child->priv->menu_template = menu_tmpl;
+}
+
+/**
+ * gnome_mdi_child_set_toolbar_template:
+ * @mdi_child: A pointer to a GnomeMDIChild object.
+ * @toolbar_tmpl: A GnomeUIInfo array describing the child specific toolbar.
+ * 
+ * Description:
+ * Sets the template for a toolbar that is added and removed when different
+ * children get activated. If no template is specified, one can still add
+ * toolbars utilizing the GnomeMDI view_changed or child_changed signal.
+ **/
+void
+gnome_mdi_child_set_toolbar_template (GnomeMDIChild *mdi_child,
+				      GnomeUIInfo *toolbar_tmpl)
+{
+	g_return_if_fail(mdi_child != NULL);
+	g_return_if_fail(GNOME_IS_MDI_CHILD(mdi_child));
+
+	mdi_child->priv->toolbar_template = toolbar_tmpl;
+}
+
+/**
+ * gnome_mdi_child_set_toolbar_position:
+ * @mdi_child: A pointer to a GnomeMDIChild object.
+ * @behavior: GnomeDockItem's behavior for the toolbar
+ * @placement: what area of the dock the toolbar should be placed in.
+ * @band_num: what band to place toolbar in.
+ * @band_pos: the toolbar's position in its band.
+ * @offset: offset from the previous GnomeDockItem in the band.
+ * 
+ * Description:
+ * Sets the default values for adding the child's toolbar to a GnomeApp.
+ * These values are used by MDI's default view_changed handler and
+ * gnome_mdi_child_add_toolbar() function.
+ **/
+void
+gnome_mdi_child_set_toolbar_position(GnomeMDIChild *mdi_child,
+				     GnomeDockItemBehavior behavior,
+				     GnomeDockPlacement placement,
+				     gint band_num, gint band_pos,
+				     gint offset)
+{
+	g_return_if_fail(mdi_child != NULL);
+	g_return_if_fail(GNOME_IS_MDI_CHILD(mdi_child));
+
+	mdi_child->priv->behavior = behavior;
+	mdi_child->priv->placement = placement;
+	mdi_child->priv->band_num = band_num;
+	mdi_child->priv->band_pos = band_pos;
+	mdi_child->priv->offset = offset;
+}
+
+/**
+ * gnome_mdi_child_get_name:
+ * @mdi_child: A pointer to a GnomeMDIChild object.
+ * 
+ * Description:
+ * Retrieves the @child's name.
+ *
+ * Return value:
+ * @child's name.
+ **/
+const GList *
+gnome_mdi_child_get_views  (GnomeMDIChild *mdi_child)
+{
+
+	g_return_val_if_fail(mdi_child != NULL, NULL);
+	g_return_val_if_fail(GNOME_IS_MDI_CHILD(mdi_child), NULL);
+
+	return mdi_child->priv->views;
+}
diff --git a/libgnomeui/gnome-mdi-child.h b/libgnomeui/gnome-mdi-child.h
new file mode 100644
index 0000000..524335e
--- /dev/null
+++ b/libgnomeui/gnome-mdi-child.h
@@ -0,0 +1,101 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* gnome-mdi-child.h - definition of an abstract MDI child class.
+
+   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+   All rights reserved
+
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Jaka Mocnik <jaka mocnik kiss uni-lj si>
+*/
+/*
+  @NOTATION@
+*/
+
+#ifndef __GNOME_MDI_CHILD_H__
+#define __GNOME_MDI_CHILD_H__
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include <libgnomeui/gnome-app.h>
+#include <libgnomeui/gnome-app-helper.h>
+
+G_BEGIN_DECLS
+
+#define GNOME_TYPE_MDI_CHILD            (gnome_mdi_child_get_type ())
+#define GNOME_MDI_CHILD(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_MDI_CHILD, GnomeMDIChild))
+#define GNOME_MDI_CHILD_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_MDI_CHILD, GnomeMDIChildClass))
+#define GNOME_IS_MDI_CHILD(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_MDI_CHILD))
+#define GNOME_IS_MDI_CHILD_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_MDI_CHILD))
+#define GNOME_MDI_CHILD_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_MDI_CHILD, GnomeMDIChildClass))
+
+typedef struct _GnomeMDIChild        GnomeMDIChild;
+typedef struct _GnomeMDIChildClass   GnomeMDIChildClass;
+
+typedef struct _GnomeMDIChildPrivate GnomeMDIChildPrivate;
+
+/* GnomeMDIChild
+ * is an abstract class. In order to use it, you have to either derive a
+ * new class from it and set the proper virtual functions in its parent
+ * GnomeMDIChildClass structure or use the GnomeMDIGenericChild class
+ * that allows to specify the relevant functions on a per-instance instead
+ * on a per-class basis and can directly be used with GnomeMDI.
+ */
+struct _GnomeMDIChild
+{
+	GtkObject object;
+
+	GnomeMDIChildPrivate *priv;
+};
+
+/* note that if you override the set_label virtual function, it should return
+ * a new widget if its GtkWidget* parameter is NULL and modify and return the
+ * old widget otherwise.
+ */
+struct _GnomeMDIChildClass
+{
+	GtkObjectClass parent_class;
+
+	/* these make no sense as signals, so we'll make them "virtual" functions */
+	/* these should correspond to the typedefs in gnome-mdi-generic-child,
+	 * except that they should lack the data argument */
+	GtkWidget * (* create_view)       (GnomeMDIChild *);
+	GList *     (* create_menus)      (GnomeMDIChild *, GtkWidget *);
+	char *      (* get_config_string) (GnomeMDIChild *);
+	GtkWidget * (* set_label)         (GnomeMDIChild *, GtkWidget *);
+};
+
+GtkType      gnome_mdi_child_get_type   (void) G_GNUC_CONST;
+GtkWidget   *gnome_mdi_child_add_view   (GnomeMDIChild *mdi_child);
+void         gnome_mdi_child_remove_view(GnomeMDIChild *mdi_child, GtkWidget *view);
+
+const gchar *gnome_mdi_child_get_name   (GnomeMDIChild *mdi_child);
+void         gnome_mdi_child_set_name   (GnomeMDIChild *mdi_child, const gchar *name);
+const GList *gnome_mdi_child_get_views  (GnomeMDIChild *mdi_child);
+ 
+void         gnome_mdi_child_set_menu_template(GnomeMDIChild *mdi_child, GnomeUIInfo *menu_tmpl);
+void         gnome_mdi_child_set_toolbar_template(GnomeMDIChild *mdi_child, GnomeUIInfo *toolbar_tmpl);
+void         gnome_mdi_child_set_toolbar_position(GnomeMDIChild *mdi_child,
+												  GnomeDockItemBehavior behavior,
+												  GnomeDockPlacement placement,
+												  gint band_num, gint band_pos,
+												  gint offset);
+
+
+G_END_DECLS
+
+#endif /* __GNOME_MDI_CHILD_H__ */
diff --git a/libgnomeui/gnome-mdi-generic-child.c b/libgnomeui/gnome-mdi-generic-child.c
new file mode 100644
index 0000000..2031a6b
--- /dev/null
+++ b/libgnomeui/gnome-mdi-generic-child.c
@@ -0,0 +1,487 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* gnome-mdi-generic-child.c - implementation of a generic MDI child class.
+
+   Copyright (C) 1997, 1998 Free Software Foundation
+   All rights reserved.
+
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Jaka Mocnik <jaka mocnik kiss uni-lj si>
+*/
+/*
+  @NOTATION@
+*/
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include "gnome-macros.h"
+#include "gnome-mdi-generic-child.h"
+#include "gnome-mdi-child.h"
+#include "gnome-mdi.h"
+#include "gnome-mdiP.h"
+
+static void        gnome_mdi_generic_child_class_init        (GnomeMDIGenericChildClass *klass);
+static void        gnome_mdi_generic_child_init              (GnomeMDIGenericChild *child);
+static void        gnome_mdi_generic_child_destroy           (GtkObject *child);
+
+static GtkWidget   *gnome_mdi_generic_child_create_view      (GnomeMDIChild *child);
+static GList       *gnome_mdi_generic_child_create_menus     (GnomeMDIChild *child,
+							      GtkWidget     *view);
+static gchar       *gnome_mdi_generic_child_get_config_string(GnomeMDIChild *child);
+static GtkWidget   *gnome_mdi_generic_child_set_label        (GnomeMDIChild *child,
+							      GtkWidget     *old_label);
+
+GNOME_CLASS_BOILERPLATE (GnomeMDIGenericChild, gnome_mdi_generic_child,
+			 GnomeMDIChild, gnome_mdi_child);
+
+static void
+gnome_mdi_generic_child_class_init (GnomeMDIGenericChildClass *klass)
+{
+	GnomeMDIChildClass *mdi_child_klass;
+	GtkObjectClass *object_klass;
+
+	object_klass = GTK_OBJECT_CLASS(klass);
+	mdi_child_klass = GNOME_MDI_CHILD_CLASS(klass);
+
+	object_klass->destroy = gnome_mdi_generic_child_destroy;
+
+	mdi_child_klass->create_view = gnome_mdi_generic_child_create_view;
+	mdi_child_klass->create_menus = gnome_mdi_generic_child_create_menus;
+	mdi_child_klass->set_label = gnome_mdi_generic_child_set_label;
+	mdi_child_klass->get_config_string = gnome_mdi_generic_child_get_config_string;
+}
+
+static void
+gnome_mdi_generic_child_init (GnomeMDIGenericChild *child)
+{
+	child->priv = g_new0(GnomeMDIGenericChildPrivate, 1);
+
+	child->priv->create_view = NULL;
+	child->priv->create_menus = NULL;
+	child->priv->set_label = NULL;
+	child->priv->get_config_string = NULL;
+
+	child->priv->create_view_cbm = NULL;
+	child->priv->create_menus_cbm = NULL;
+	child->priv->set_label_cbm = NULL;
+	child->priv->get_config_string_cbm = NULL;
+
+	child->priv->create_view_dn = NULL;
+	child->priv->create_menus_dn = NULL;
+	child->priv->set_label_dn = NULL;
+	child->priv->get_config_string_dn = NULL;
+
+	child->priv->create_view_data = NULL;
+	child->priv->create_menus_data = NULL;
+	child->priv->set_label_data = NULL;
+	child->priv->get_config_string_data = NULL;
+}
+
+/**
+ * gnome_mdi_generic_child_new:
+ * @name: the name of this MDI child.
+ * 
+ * Creates a new mdi child, which has the ability to set view creators, etc
+ * on an instance basis (rather than on a class basis like &GnomeMDIChild).
+ *
+ * After creation, you will need to set, at a minimum, the view creator
+ * function.
+ * 
+ * Return value: A newly created &GnomeMDIGenericChild object.
+ **/
+GnomeMDIGenericChild *
+gnome_mdi_generic_child_new (const gchar *name)
+{
+	GnomeMDIGenericChild *child;
+
+	child = gtk_type_new(gnome_mdi_generic_child_get_type ());
+
+	GNOME_MDI_CHILD(child)->priv->name = g_strdup(name);
+
+	return child;
+}
+
+/**
+ * gnome_mdi_generic_child_set_view_creator:
+ * @child: the mdi child object
+ * @func: a function used to create views
+ * @data: optional user data.
+ * 
+ * This function sets the function that is used to create new views for this
+ * particular mdi child object.  The function should return a newly created
+ * widget (the view).
+ *
+ * A &GnomeMDIGenericChild must have a view creator.
+ **/
+void
+gnome_mdi_generic_child_set_view_creator (GnomeMDIGenericChild *child,
+					  GnomeMDIChildViewCreator func,
+					  gpointer data)
+{
+	g_return_if_fail(child != NULL);
+	g_return_if_fail(GNOME_IS_MDI_GENERIC_CHILD(child));
+
+	gnome_mdi_generic_child_set_view_creator_full(child,func,NULL,data,NULL);
+}
+
+/**
+ * gnome_mdi_generic_child_set_view_creator_full:
+ * @child: the mdi child object
+ * @func: a function to create views (not used if @marshal != %NULL)
+ * @marshal: a callback marshaller
+ * @data: optional user data
+ * @notify: a function used to free the user data.
+ * 
+ * Similar to gnome_mdi_generic_child_set_view_creator(), except that it gives
+ * more control to the programmer.  If @marshal is not %NULL, then it will
+ * be called instead of @func.
+ *
+ * The &GtkArg array passed to @marshal will be of length 2.  The first
+ * element will be @child, and the second is the return value (a pointer to
+ * a &GtkWidget).
+ **/
+void
+gnome_mdi_generic_child_set_view_creator_full (GnomeMDIGenericChild *child,
+					       GnomeMDIChildViewCreator func,
+					       GtkCallbackMarshal marshal,
+					       gpointer data,
+					       GtkDestroyNotify notify)
+{
+	g_return_if_fail(child != NULL);
+	g_return_if_fail(GNOME_IS_MDI_GENERIC_CHILD(child));
+
+	if(child->priv->create_view_dn)
+		child->priv->create_view_dn(child->priv->create_view_data);
+	child->priv->create_view = func;
+	child->priv->create_view_cbm = marshal;
+	child->priv->create_view_data = data;
+	child->priv->create_view_dn = notify;
+}
+
+/**
+ * gnome_mdi_generic_child_set_menu_creator:
+ * @child: the mdi child object
+ * @func: a function to create a list of child specific menus
+ * @data: optional user data
+ * 
+ * Sets the function used to create child specific menus.  The function
+ * should return a &GList of the menus created.
+ *
+ * A &GnomeMDIGenericChild doesn't require a menu creator.
+ **/
+void
+gnome_mdi_generic_child_set_menu_creator (GnomeMDIGenericChild *child,
+										  GnomeMDIChildMenuCreator func,
+										  gpointer data)
+{
+	g_return_if_fail(child != NULL);
+	g_return_if_fail(GNOME_IS_MDI_GENERIC_CHILD(child));
+
+	gnome_mdi_generic_child_set_menu_creator_full(child,func,NULL,data,NULL);
+}
+
+/**
+ * gnome_mdi_generic_child_set_menu_creator_full:
+ * @child: the mdi child object
+ * @func: a menu creator function (not used if @marshal != %NULL)
+ * @marshal: a callback marshaller
+ * @data: optional user data
+ * @notify: a destroy notify for the data
+ * 
+ * This function is similar to gnome_mdi_generic_child_set_menu_creator(),
+ * but gives extra flexibility to the programmer, in the form of a a
+ * destroy notify for the user data, and a callback marshaller.
+ *
+ * The &GtkArg array passed to @marshal is of length 3.  The first element
+ * will be @child, the second will be a view of @child, and the third is the
+ * return value (a pointer to the returned GList).
+ **/
+void
+gnome_mdi_generic_child_set_menu_creator_full (GnomeMDIGenericChild *child,
+											   GnomeMDIChildMenuCreator func,
+											   GtkCallbackMarshal marshal,
+											   gpointer data,
+											   GtkDestroyNotify notify)
+{
+	g_return_if_fail(child != NULL);
+	g_return_if_fail(GNOME_IS_MDI_GENERIC_CHILD(child));
+
+	if(child->priv->create_menus_dn)
+		child->priv->create_menus_dn(child->priv->create_menus_data);
+	child->priv->create_menus = func;
+	child->priv->create_menus_cbm = marshal;
+	child->priv->create_menus_data = data;
+	child->priv->create_menus_dn = notify;
+}
+
+/**
+ * gnome_mdi_generic_child_set_config_func:
+ * @child: the mdi child object
+ * @func: a function to set the config key for session saves
+ * @data: optional user data
+ * 
+ * Sets the function used to get the config key used for session saves.
+ *
+ * A &GnomeMDIGenericChild doesn't require a config func.
+ **/
+void
+gnome_mdi_generic_child_set_config_func (GnomeMDIGenericChild *child,
+										 GnomeMDIChildConfigFunc func,
+										 gpointer data)
+{
+	g_return_if_fail(child != NULL);
+	g_return_if_fail(GNOME_IS_MDI_GENERIC_CHILD(child));
+
+	gnome_mdi_generic_child_set_config_func_full(child,func,NULL,data,NULL);
+}
+
+/**
+ * gnome_mdi_generic_child_set_config_func_full:
+ * @child: the mdi child object
+ * @func: a function (not used if @marshal != %NULL)
+ * @marshal: a callback marshaller
+ * @data: optional user data
+ * @notify: a destroy notify for the user data
+ * 
+ * A function similar to gnome_mdi_generic_child_set_config_func(), except
+ * it gives more control to the programmer.
+ *
+ * The &GtkArg array passed to @marshal is of length 2.  The first element is
+ * @child, and the second is the return value (a pointer to a string).
+ **/
+void
+gnome_mdi_generic_child_set_config_func_full (GnomeMDIGenericChild *child,
+											  GnomeMDIChildConfigFunc func,
+											  GtkCallbackMarshal marshal,
+											  gpointer data,
+											  GtkDestroyNotify notify)
+{
+	g_return_if_fail(child != NULL);
+	g_return_if_fail(GNOME_IS_MDI_GENERIC_CHILD(child));
+
+	if(child->priv->get_config_string_dn)
+		child->priv->get_config_string_dn(child->priv->get_config_string_data);
+	child->priv->get_config_string = func;
+	child->priv->get_config_string_cbm = marshal;
+	child->priv->get_config_string_data = data;
+	child->priv->get_config_string_dn = notify;
+}
+
+/**
+ * gnome_mdi_generic_child_set_label_func:
+ * @child: a mdi child object
+ * @func: a function
+ * @data: optional user data
+ * 
+ * Sets the function used to set (or modify) the label for @child.  The
+ * first argument to @func is @child.  If a label exists, it will be passed
+ * to @func as the second argument, otherwise, %NULL is passed.  The
+ * function should return the modified label.
+ *
+ * A &GnomeMDIGenericChild doesn't require a label function.
+ **/
+void
+gnome_mdi_generic_child_set_label_func (GnomeMDIGenericChild *child,
+					GnomeMDIChildLabelFunc func,
+					gpointer data)
+{
+	g_return_if_fail(child != NULL);
+	g_return_if_fail(GNOME_IS_MDI_GENERIC_CHILD(child));
+
+	gnome_mdi_generic_child_set_label_func_full(child,func,NULL,data,NULL);
+}
+
+/**
+ * gnome_mdi_generic_child_set_label_func_full:
+ * @child: the mdi child object
+ * @func: a function (not used if @marshal != %NULL)
+ * @marshal: a callback marshaller
+ * @data: optional user data
+ * @notify: a destroy notify for the data
+ * 
+ * Similar to gnome_mdi_generic_child_set_label_func(), except it gives more
+ * flexibility to the programmer.
+ *
+ * The &GtkArg array passed to @marshal is of length 3.  The first argument
+ * is @child, the second is the old widget (or %NULL), and the third is the
+ * return value (a pointer to a &GtkWidget).
+ **/
+void
+gnome_mdi_generic_child_set_label_func_full (GnomeMDIGenericChild *child,
+					     GnomeMDIChildLabelFunc func,
+					     GtkCallbackMarshal marshal,
+					     gpointer data,
+					     GtkDestroyNotify notify)
+{
+	g_return_if_fail(child != NULL);
+	g_return_if_fail(GNOME_IS_MDI_GENERIC_CHILD(child));
+
+	if(child->priv->set_label_dn)
+		child->priv->set_label_dn(child->priv->set_label_data);
+	child->priv->set_label = func;
+	child->priv->set_label_cbm = marshal;
+	child->priv->set_label_data = data;
+	child->priv->set_label_dn = notify;
+}
+
+static GtkWidget *
+gnome_mdi_generic_child_create_view (GnomeMDIChild *_child)
+{
+	GnomeMDIGenericChild *child = GNOME_MDI_GENERIC_CHILD (_child);
+
+	if(!child->priv->create_view && !child->priv->create_view_cbm) {
+		g_error("GnomeMDIGenericChild: No method for creating views was provided!");
+		return NULL;
+	}
+
+	if(child->priv->create_view_cbm) {
+		GtkArg args[2];
+		GtkWidget *ret = NULL;
+
+		args[0].name = NULL;
+		args[0].type = gnome_mdi_child_get_type();
+		GTK_VALUE_OBJECT(args[0]) = GTK_OBJECT(child);
+		args[1].name = NULL;
+		args[1].type = gtk_widget_get_type();
+		GTK_VALUE_POINTER(args[1]) = &ret;
+		child->priv->create_view_cbm(NULL, child->priv->create_view_data, 1, args);
+		return ret;
+	}
+	else
+		return child->priv->create_view(GNOME_MDI_CHILD(child),
+								  child->priv->create_view_data);
+}
+
+static GList *
+gnome_mdi_generic_child_create_menus(GnomeMDIChild *_child,
+				     GtkWidget *view)
+{
+	GnomeMDIGenericChild *child = GNOME_MDI_GENERIC_CHILD (_child);
+
+	if(!child->priv->create_menus && !child->priv->create_menus_cbm)
+		return GNOME_CALL_PARENT_HANDLER (GNOME_MDI_CHILD_CLASS,
+						  create_menus,
+						  (GNOME_MDI_CHILD (child),
+						   view));
+
+	if (child->priv->create_menus_cbm) {
+		GtkArg args[3];
+		GList *ret = NULL;
+		
+		args[0].name = NULL;
+		args[0].type = gnome_mdi_child_get_type();
+		GTK_VALUE_OBJECT(args[0]) = GTK_OBJECT(child);
+		args[1].name = NULL;
+		args[1].type = gtk_widget_get_type();
+		GTK_VALUE_OBJECT(args[1]) = GTK_OBJECT(view);
+		args[2].name = NULL;
+		args[2].type = GTK_TYPE_POINTER; /* should we have a boxed type? */
+		GTK_VALUE_POINTER(args[2]) = &ret;
+		child->priv->create_menus_cbm(NULL, child->priv->create_menus_data, 2, args);
+		return ret;
+	}
+	else
+		return child->priv->create_menus(GNOME_MDI_CHILD(child), view,
+										 child->priv->create_menus_data);
+}
+
+static gchar *
+gnome_mdi_generic_child_get_config_string (GnomeMDIChild *_child)
+{
+	GnomeMDIGenericChild *child = GNOME_MDI_GENERIC_CHILD (_child);
+
+	if(!child->priv->get_config_string && !child->priv->get_config_string_cbm)
+		return GNOME_CALL_PARENT_HANDLER (GNOME_MDI_CHILD_CLASS,
+						  get_config_string,
+						  (GNOME_MDI_CHILD (child)));
+
+	if(child->priv->get_config_string_cbm) {
+		GtkArg args[2];
+		gchar *ret = NULL;
+		
+		args[0].name = NULL;
+		args[0].type = gnome_mdi_child_get_type();
+		GTK_VALUE_OBJECT(args[0]) = GTK_OBJECT(child);
+		args[1].name = NULL;
+		args[1].type = GTK_TYPE_STRING;
+		GTK_VALUE_POINTER(args[1]) = &ret;
+		child->priv->get_config_string_cbm(NULL, child->priv->get_config_string_data,
+										   1, args);
+		return ret;
+	}
+	else
+		return child->priv->get_config_string(GNOME_MDI_CHILD(child),
+											  child->priv->get_config_string_data);
+}
+
+static GtkWidget *
+gnome_mdi_generic_child_set_label (GnomeMDIChild *_child,
+				   GtkWidget *old_label)
+{
+	GnomeMDIGenericChild *child = GNOME_MDI_GENERIC_CHILD (_child);
+
+	if(!child->priv->set_label && !child->priv->set_label_cbm)
+		return GNOME_CALL_PARENT_HANDLER (GNOME_MDI_CHILD_CLASS,
+						  set_label,
+						  (GNOME_MDI_CHILD (child),
+						   old_label));
+
+	if(child->priv->set_label_cbm) {
+		GtkArg args[3];
+		GtkWidget *ret = NULL;
+
+		args[0].name = NULL;
+		args[0].type = gnome_mdi_child_get_type();
+		GTK_VALUE_OBJECT(args[0]) = GTK_OBJECT(child);
+		args[1].name = NULL;
+		args[1].type = gtk_widget_get_type();
+		GTK_VALUE_OBJECT(args[0]) = GTK_OBJECT(old_label);
+		args[2].name = NULL;
+		args[2].type = gtk_widget_get_type();
+		GTK_VALUE_POINTER(args[2]) = &ret;
+		child->priv->set_label_cbm(NULL, child->priv->set_label_data, 2, args);
+		return ret;
+	}
+	else
+		return child->priv->set_label(GNOME_MDI_CHILD(child), old_label,
+									  child->priv->set_label_data);
+}
+
+static void
+gnome_mdi_generic_child_destroy (GtkObject *obj)
+{
+	GnomeMDIGenericChild *child = GNOME_MDI_GENERIC_CHILD(obj);
+
+	/* remember, destroy can be run multiple times! */
+
+	if(child->priv->create_view_dn)
+		child->priv->create_view_dn(child->priv->create_view_data);
+	child->priv->create_view_dn = NULL;
+	if(child->priv->create_menus_dn)
+		child->priv->create_menus_dn(child->priv->create_menus_data);
+	child->priv->create_menus_dn = NULL;
+	if(child->priv->get_config_string_dn)
+		child->priv->get_config_string_dn(child->priv->get_config_string_data);
+	child->priv->get_config_string_dn = NULL;
+	if(child->priv->set_label_dn)
+		child->priv->set_label_dn(child->priv->set_label_data);
+	child->priv->set_label_dn = NULL;
+	
+	GNOME_CALL_PARENT_HANDLER (GTK_OBJECT_CLASS, destroy, (obj));
+}
diff --git a/libgnomeui/gnome-mdi-generic-child.h b/libgnomeui/gnome-mdi-generic-child.h
new file mode 100644
index 0000000..0571d5b
--- /dev/null
+++ b/libgnomeui/gnome-mdi-generic-child.h
@@ -0,0 +1,111 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* gnome-mdi-generic-child.h - definition of a generic MDI child class
+
+   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+   All rights reserved.
+
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Jaka Mocnik <jaka mocnik kiss uni-lj si>
+   Interp modifications: James Henstridge <james daa com au>
+*/
+/*
+  @NOTATION@
+*/
+
+#ifndef __GNOME_MDI_GENERIC_CHILD_H__
+#define __GNOME_MDI_GENERIC_CHILD_H__
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include "gnome-mdi-child.h"
+
+G_BEGIN_DECLS
+
+#define GNOME_TYPE_MDI_GENERIC_CHILD            (gnome_mdi_generic_child_get_type ())
+#define GNOME_MDI_GENERIC_CHILD(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_MDI_GENERIC_CHILD, GnomeMDIGenericChild))
+#define GNOME_MDI_GENERIC_CHILD_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_MDI_GENERIC_CHILD, GnomeMDIGenericChildClass))
+#define GNOME_IS_MDI_GENERIC_CHILD(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_MDI_GENERIC_CHILD))
+#define GNOME_IS_MDI_GENERIC_CHILD_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_MDI_GENERIC_CHILD))
+#define GNOME_MDI_GENERIC_CHILD_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_MDI_GENERIC_CHILD, GnomeMDIGenericChildClass))
+/* The source backward-compatibility macro GNOME_IS_MDI_MDI_CHILD(obj)
+   is in gnome-compat.h.  */
+
+typedef struct _GnomeMDIGenericChild        GnomeMDIGenericChild;
+typedef struct _GnomeMDIGenericChildClass   GnomeMDIGenericChildClass;
+
+typedef struct _GnomeMDIGenericChildPrivate GnomeMDIGenericChildPrivate;
+
+struct _GnomeMDIGenericChild {
+	GnomeMDIChild mdi_child;
+
+	GnomeMDIGenericChildPrivate *priv;
+};
+
+struct _GnomeMDIGenericChildClass {
+	GnomeMDIChildClass parent_class;
+};
+
+/* These should correspond to the virtual functions in
+ * GnomeMDIChild, except that they should contain the extra "data" pointer */
+typedef GtkWidget   *(*GnomeMDIChildViewCreator) (GnomeMDIChild *, gpointer);
+typedef GList       *(*GnomeMDIChildMenuCreator) (GnomeMDIChild *, GtkWidget *, gpointer);
+typedef gchar       *(*GnomeMDIChildConfigFunc)  (GnomeMDIChild *, gpointer);
+typedef GtkWidget   *(*GnomeMDIChildLabelFunc)   (GnomeMDIChild *, GtkWidget *, gpointer);
+
+
+GtkType              gnome_mdi_generic_child_get_type (void) G_GNUC_CONST;
+
+GnomeMDIGenericChild *gnome_mdi_generic_child_new     (const gchar *name);
+
+void gnome_mdi_generic_child_set_view_creator     (GnomeMDIGenericChild *child,
+												   GnomeMDIChildViewCreator func,
+                                                   gpointer data);
+void gnome_mdi_generic_child_set_view_creator_full(GnomeMDIGenericChild *child,
+												   GnomeMDIChildViewCreator func,
+												   GtkCallbackMarshal marshal,
+												   gpointer data,
+												   GtkDestroyNotify notify);
+void gnome_mdi_generic_child_set_menu_creator     (GnomeMDIGenericChild *child,
+												   GnomeMDIChildMenuCreator func,
+                                                   gpointer data);
+void gnome_mdi_generic_child_set_menu_creator_full(GnomeMDIGenericChild *child,
+												   GnomeMDIChildMenuCreator func,
+												   GtkCallbackMarshal marshal,
+												   gpointer data,
+												   GtkDestroyNotify notify);
+void gnome_mdi_generic_child_set_config_func      (GnomeMDIGenericChild *child,
+												   GnomeMDIChildConfigFunc func,
+                                                   gpointer data);
+void gnome_mdi_generic_child_set_config_func_full (GnomeMDIGenericChild *child,
+												   GnomeMDIChildConfigFunc func,
+												   GtkCallbackMarshal marshal,
+												   gpointer data,
+												   GtkDestroyNotify notify);
+void gnome_mdi_generic_child_set_label_func       (GnomeMDIGenericChild *child,
+												   GnomeMDIChildLabelFunc func,
+                                                   gpointer data);
+void gnome_mdi_generic_child_set_label_func_full  (GnomeMDIGenericChild *child,
+												   GnomeMDIChildLabelFunc func,
+												   GtkCallbackMarshal marshal,
+												   gpointer data,
+												   GtkDestroyNotify notify);
+
+
+G_END_DECLS
+
+#endif
diff --git a/libgnomeui/gnome-mdi-session.c b/libgnomeui/gnome-mdi-session.c
new file mode 100644
index 0000000..5a508a2
--- /dev/null
+++ b/libgnomeui/gnome-mdi-session.c
@@ -0,0 +1,536 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#include <config.h>
+#include <stdio.h>
+
+#include <libgnome/gnome-i18n.h>
+
+#include <libgnome/gnome-config.h>
+
+#include "gnome-dock-layout.h"
+#include "gnome-mdi-session.h"
+#include "gnome-mdiP.h"
+
+static GPtrArray *	config_get_list		(const gchar *);
+static void		config_set_list		(const gchar *, GList *,
+						 gpointer (*)(gpointer));
+static void		restore_window_child	(GnomeMDI *, GHashTable *,
+						 GHashTable *, GHashTable *,
+						 GHashTable *, GHashTable *,
+						 glong, glong, gboolean *,
+						 gint, gint, gint, gint);
+static void		restore_window		(GnomeMDI *, const gchar *,
+						 GPtrArray *, GHashTable *,
+						 GHashTable *, GHashTable *,
+						 GHashTable *, GHashTable *,
+						 glong);
+static void		set_active_window	(GnomeMDI *, GHashTable *, glong);
+
+
+static gpointer		view_window_func	(gpointer);
+
+static gchar *
+gnome_mdi_child_get_config_string (GnomeMDIChild *child)
+{
+	if(GNOME_MDI_CHILD_GET_CLASS(child)->get_config_string)
+		return GNOME_MDI_CHILD_GET_CLASS(child)->get_config_string(child);
+
+	return NULL;
+}
+
+static GPtrArray *
+config_get_list (const gchar *key)
+{
+	GPtrArray *array;
+	gchar *string, *pos;
+
+	string = gnome_config_get_string (key);
+	if (!string) return NULL;
+
+	array = g_ptr_array_new ();
+
+	pos = string;
+	while (*pos) {
+		glong value;
+		gchar *tmp;
+
+		tmp = strchr (pos, ':');
+		if (tmp) *tmp = '\0';
+
+		if (sscanf (pos, "%lx", &value) == 1)
+			g_ptr_array_add (array, (gpointer) value);
+
+		if (tmp)
+			pos = tmp+1;
+		else
+			break;
+	}
+
+	g_free (string);
+	return array;
+}
+
+static void
+config_set_list (const gchar *key, GList *list, gpointer (*func)(gpointer))
+{
+	gchar value [BUFSIZ];
+
+	value [0] = '\0';
+	while (list) {
+		char buffer [BUFSIZ];
+		gpointer data;
+
+		data = func ? func (list->data) : list->data;
+		g_snprintf (buffer, sizeof(buffer), "%lx", (glong) data);
+		if (*value) strcat (value, ":");
+		strcat (value, buffer);
+
+		list = g_list_next (list);
+	}
+
+	gnome_config_set_string (key, value);
+}
+
+static void
+restore_window_child (GnomeMDI *mdi, GHashTable *child_hash,
+		      GHashTable *child_windows, GHashTable *child_views,
+		      GHashTable *view_hash, GHashTable *window_hash,
+		      glong window, glong child, gboolean *init,
+		      gint x, gint y, gint width, gint height)
+{
+	GPtrArray *windows, *views;
+	GnomeMDIChild *mdi_child;
+	GtkWidget *new_window = NULL;
+	guint k;
+
+	windows = g_hash_table_lookup (child_windows, (gpointer) child);
+	if (!windows) return;
+
+	views = g_hash_table_lookup (child_views, (gpointer) child);
+	if (!views) return;
+		
+	mdi_child = g_hash_table_lookup (child_hash, (gpointer) child);
+	if (!mdi_child) return;
+		
+	for (k = 0; k < windows->len; k++) {
+		if (windows->pdata [k] != (gpointer) window)
+			continue;
+
+		if (*init)
+			gnome_mdi_add_view (mdi, mdi_child);
+		else {
+			new_window = gnome_mdi_new_toplevel (mdi);
+
+			gnome_mdi_add_view (mdi, mdi_child);
+			
+			gtk_widget_set_usize
+				(GTK_WIDGET (mdi->priv->active_window),
+				 width, height);
+
+			gtk_widget_set_uposition
+				(GTK_WIDGET (mdi->priv->active_window), x, y);
+			
+			*init = TRUE;
+
+			g_hash_table_insert (window_hash,
+					     (gpointer) window,
+					     mdi->priv->active_window);
+		}
+
+		g_hash_table_insert (view_hash,
+				     views->pdata [k],
+				     mdi->priv->active_view);
+
+		if(new_window)
+			gtk_widget_show(new_window);
+	}
+}
+
+static void
+restore_window (GnomeMDI *mdi, const gchar *section, GPtrArray *child_list,
+		GHashTable *child_hash, GHashTable *child_windows,
+		GHashTable *child_views, GHashTable *view_hash,
+		GHashTable *window_hash, glong window)
+{
+	gboolean init = FALSE;
+	gchar key [BUFSIZ], *string;
+	gint ret, x, y, w, h;
+	guint j;
+
+	g_snprintf (key, sizeof(key), "%s/mdi_window_%lx", section, window);
+	string = gnome_config_get_string (key);
+	if (!string) return;
+
+	ret = sscanf (string, "%d/%d/%d/%d", &x, &y, &w, &h);
+	g_free (string);
+	if (ret != 4) return;
+
+	if(child_list->len == 0) {	
+		gnome_mdi_open_toplevel (mdi);
+
+		gtk_widget_set_usize (GTK_WIDGET (mdi->priv->active_window),
+				      w, h);
+
+		gtk_widget_set_uposition (GTK_WIDGET (mdi->priv->active_window),
+					  x, y);
+
+		g_hash_table_insert (window_hash, (gpointer) window,
+				     mdi->priv->active_window);
+ 	}
+	else
+		for (j = 0; j < child_list->len; j++)
+			restore_window_child (mdi, child_hash, child_windows,
+					      child_views, view_hash,
+					      window_hash, window,
+					      (glong) child_list->pdata [j],
+					      &init, x, y, w, h);
+
+	g_snprintf (key, sizeof(key), "%s/mdi_window_layout_%lx", section,
+		    window);
+	string = gnome_config_get_string (key);
+	if (!string) return;
+
+#if 0
+	{
+		GnomeApp *app = mdi->priv->active_window;
+		GnomeDockLayout *layout;
+
+		/* this should be a nasty hack before dock-layout gets a bit better
+		   don't even know if it works, though ;) */
+		layout = gnome_dock_get_layout(GNOME_DOCK(app->dock));
+		gnome_dock_layout_parse_string(mdi->priv->active_window->layout, string);
+		gtk_container_forall(GTK_CONTAINER(app->dock), remove_items, app->dock);
+		gnome_dock_add_from_layout(GNOME_DOCK(app->dock), layout);
+		gtk_object_unref(GTK_OBJECT(layout));
+	}
+#endif
+}
+
+static void
+set_active_window (GnomeMDI *mdi, GHashTable *window_hash, glong active_window)
+{
+	GnomeApp *app;
+	GtkWidget *view;
+
+	app = g_hash_table_lookup (window_hash, (gpointer) active_window);
+	if (!app) return;
+
+	view = gnome_mdi_get_view_from_window (mdi, app);
+	if (!view) return;
+
+	gnome_mdi_set_active_view (mdi, view);
+}
+
+/**
+ * gnome_mdi_restore_state:
+ * @mdi: A pointer to a GnomeMDI object.
+ * @section: Name of the section to restore MDI state from.
+ * @create_child_func: A function that recreates a child from its config string.
+ * 
+ * Description:
+ * Restores the MDI state. Children are recreated with @create_child_func that
+ * restores information about a child from a config string that was provided
+ * during saving state by the child. 
+ * 
+ * Return value:
+ * TRUE if state was successfully restored, FALSE otherwise.
+ **/
+gboolean
+gnome_mdi_restore_state (GnomeMDI *mdi, const gchar *section,
+			 GnomeMDIChildCreator create_child_func)
+{
+	gchar key [BUFSIZ], *string;
+	GPtrArray *window_list, *child_list;
+	GHashTable *child_hash, *child_windows;
+	GHashTable *child_views, *view_hash, *window_hash;
+	glong active_view = 0, active_window = 0;
+	guint i;
+	gint mode;
+
+	g_snprintf (key, sizeof(key), "%s/mdi_mode=-1", section);
+	mode = gnome_config_get_int (key);
+	if (gnome_config_get_int (key) == -1)
+		return FALSE;
+
+	gnome_mdi_set_mode (mdi, mode);
+
+	child_hash = g_hash_table_new (NULL, NULL);
+	child_windows = g_hash_table_new (NULL, NULL);
+	child_views = g_hash_table_new (NULL, NULL);
+	view_hash = g_hash_table_new (NULL, NULL);
+	window_hash = g_hash_table_new (NULL, NULL);
+
+	/* Walk the list of windows. */
+
+	g_snprintf (key, sizeof(key), "%s/mdi_windows", section);
+	window_list = config_get_list (key);
+
+	/* Walk the list of children. */
+
+	g_snprintf (key, sizeof(key), "%s/mdi_children", section);
+	child_list = config_get_list (key);
+
+	/* Get the active view. */
+
+	g_snprintf (key, sizeof(key), "%s/mdi_active_view", section);
+	string = gnome_config_get_string (key);
+
+	if (string) {
+		sscanf (string, "%lx", &active_view);
+		g_free (string);
+	}
+
+	/* Get the active window. */
+
+	g_snprintf (key, sizeof(key), "%s/mdi_active_window", section);
+	string = gnome_config_get_string (key);
+
+	if (string) {
+		sscanf (string, "%lx", &active_window);
+		g_free (string);
+	}
+
+	/* Read child descriptions. */
+
+	for (i = 0; i < child_list->len; i++) {
+		glong child = (glong) child_list->pdata [i];
+		GPtrArray *windows, *views;
+		GnomeMDIChild *mdi_child;
+
+		g_snprintf (key, sizeof(key), "%s/mdi_child_config_%lx",
+			    section, child);
+		string = gnome_config_get_string (key);
+		if (!string) continue;
+
+		mdi_child = create_child_func (string);
+		g_free (string);
+
+		gnome_mdi_add_child (mdi, mdi_child);
+
+		g_hash_table_insert (child_hash, (gpointer)child, mdi_child);
+		
+		g_snprintf (key, sizeof(key), "%s/mdi_child_windows_%lx",
+			    section, child);
+		windows = config_get_list (key);
+
+		g_hash_table_insert (child_windows, (gpointer) child, windows);
+
+		g_snprintf (key, sizeof(key), "%s/mdi_child_views_%lx",
+			    section, child);
+		views = config_get_list (key);
+
+		g_hash_table_insert (child_views, (gpointer) child, views);
+	}
+
+	/* Read window descriptions. */
+	
+	for (i = 0; i < window_list->len; i++)
+		restore_window (mdi, section, child_list,
+				child_hash, child_windows,
+				child_views, view_hash, window_hash,
+				(glong) window_list->pdata [i]);
+
+	/* For each window, set its active view. */
+
+	for (i = 0; i < window_list->len; i++) {
+		GtkWidget *real_view;
+		glong view;
+		gint ret;
+
+		g_snprintf (key, sizeof(key), "%s/mdi_window_view_%lx",
+			    section, (long) window_list->pdata [i]);
+		string = gnome_config_get_string (key);
+		if (!string) continue;
+
+		ret = sscanf (string, "%lx", &view);
+		g_free (string);
+		if (ret != 1) continue;
+
+		real_view = g_hash_table_lookup (view_hash, (gpointer) view);
+		if (!real_view) continue;
+
+		gnome_mdi_set_active_view (mdi, real_view);
+	}
+
+	/* Finally, set the active window. */
+
+	set_active_window (mdi, window_hash, active_window);
+
+	/* Free allocated memory. */
+
+	for (i = 0; i < child_list->len; i++) {
+		glong child = (glong) child_list->pdata [i];
+		GPtrArray *windows, *views;
+
+		windows = g_hash_table_lookup (child_windows, (gpointer) child);
+		if (windows) g_ptr_array_free (windows, FALSE);
+
+		views = g_hash_table_lookup (child_views, (gpointer) child);
+		if (views) g_ptr_array_free (views, FALSE);
+	}
+
+	g_hash_table_destroy (child_hash);
+	g_hash_table_destroy (child_windows);
+	g_hash_table_destroy (child_views);
+	g_hash_table_destroy (view_hash);
+	g_hash_table_destroy (window_hash);
+
+	return TRUE;
+}
+
+static gpointer
+view_window_func (gpointer data)
+{
+	if (GTK_WIDGET_REALIZED (GTK_WIDGET (data)))
+		return gnome_mdi_get_app_from_view(GTK_WIDGET(data));
+	else
+		return NULL;
+}
+
+/**
+ * gnome_mdi_save_state:
+ * @mdi: A pointer to a GnomeMDI object.
+ * @section: Name of the section that the MDI config should be saved to.
+ * 
+ * Description:
+ * Saves MDI state to the application's config file in section @section.
+ **/
+void
+gnome_mdi_save_state (GnomeMDI *mdi, const gchar *section)
+{
+	gchar key [BUFSIZ], value [BUFSIZ];
+	GList *child, *window;
+	gint x, y, w, h;
+
+	gnome_config_clean_section (section);
+
+	/* save MDI mode */
+	g_snprintf (key, sizeof(key), "%s/mdi_mode", section);
+	gnome_config_set_int (key, mdi->priv->mode);
+
+	/* Write list of children. */
+
+	g_snprintf (key, sizeof(key), "%s/mdi_children", section);
+	config_set_list (key, mdi->priv->children, NULL);
+
+	/* Write list of windows. */
+
+	g_snprintf (key, sizeof(key), "%s/mdi_windows", section);
+	config_set_list (key, mdi->priv->windows, NULL);
+
+	/* Save active window. */
+
+	g_snprintf (key, sizeof(key), "%s/mdi_active_window", section);
+	g_snprintf (value, sizeof(value), "%lx",
+		    (glong) mdi->priv->active_window);
+	gnome_config_set_string (key, value);
+
+	/* Save active view. */
+
+	g_snprintf (key, sizeof(key), "%s/mdi_active_view", section);
+	g_snprintf (value, sizeof(value), "%lx",
+		    (glong) mdi->priv->active_view);
+	gnome_config_set_string (key, value);
+
+	/* Walk list of children. */
+
+	child = mdi->priv->children;
+	while (child) {
+		GnomeMDIChild *mdi_child;
+		gchar *string;
+
+		mdi_child = GNOME_MDI_CHILD (child->data);
+
+		/* Save child configuration. */
+
+		string = gnome_mdi_child_get_config_string(mdi_child);
+
+		if (string) {
+			g_snprintf (key, sizeof(key),
+				    "%s/mdi_child_config_%lx",
+				    section, (long) mdi_child);
+			gnome_config_set_string (key, string);
+			g_free (string);
+		}
+
+		/* Save list of views this child has. */
+
+		g_snprintf (key, sizeof(key), "%s/mdi_child_windows_%lx",
+			    section, (long) mdi_child);
+		config_set_list (key, mdi_child->priv->views, view_window_func);
+
+		g_snprintf (key, sizeof(key), "%s/mdi_child_views_%lx",
+			    section, (long) mdi_child);
+		config_set_list (key, mdi_child->priv->views, NULL);
+
+		child = g_list_next (child);
+	}
+
+	/* Save list of toplevel windows. */
+
+	window = mdi->priv->windows;
+	while (window) {
+		GnomeApp *app;
+		GnomeDockLayout *layout;
+		GtkWidget *view;
+		gchar *string;
+
+		app = GNOME_APP (window->data);
+
+		gdk_window_get_geometry (GTK_WIDGET (app)->window,
+					 &x, &y, &w, &h, NULL);
+
+		gdk_window_get_origin (GTK_WIDGET (app)->window, &x, &y);
+
+		g_snprintf (key, sizeof(key), "%s/mdi_window_%lx",
+			    section, (long) app);
+		g_snprintf (value, sizeof(value), "%d/%d/%d/%d", x, y, w, h);
+
+		gnome_config_set_string (key, value);
+
+		view = gnome_mdi_get_view_from_window (mdi, app);
+
+		g_snprintf (key, sizeof(key), "%s/mdi_window_view_%lx",
+			    section, (long) app);
+		g_snprintf (value, sizeof(value), "%lx", (long) view);
+
+		gnome_config_set_string (key, value);
+
+		g_snprintf(key, sizeof(key), "%s/mdi_window_layout_%lx",
+			   section, (long) app);
+
+		layout = gnome_dock_get_layout (GNOME_DOCK (app->dock));
+		string = gnome_dock_layout_create_string (layout);
+		gtk_object_unref (GTK_OBJECT (layout));
+		gnome_config_set_string(key, string);
+		g_free(string);
+
+		window = g_list_next (window);
+	}
+
+	gnome_config_sync ();
+}
diff --git a/libgnomeui/gnome-mdi-session.h b/libgnomeui/gnome-mdi-session.h
new file mode 100644
index 0000000..629dcd6
--- /dev/null
+++ b/libgnomeui/gnome-mdi-session.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+/*
+ * gnome-mdi-session.h - session managament functions
+ * written by Martin Baulig <martin home-of-linux org>
+ */
+
+#ifndef __GNOME_MDI_SESSION_H__
+#define __GNOME_MDI_SESSION_H__
+
+#include <string.h>
+
+#include <libgnomeui/gnome-mdi.h>
+
+G_BEGIN_DECLS
+
+/* This function should parse the config string and return a newly
+ * created GnomeMDIChild. */
+typedef GnomeMDIChild *(*GnomeMDIChildCreator) (const gchar *);
+
+/* gnome_mdi_restore_state(): call this with the GnomeMDI object, the
+ * config section name and the function used to recreate the GnomeMDIChildren
+ * from their config strings. */
+gboolean	gnome_mdi_restore_state	(GnomeMDI *mdi, const gchar *section,
+					 GnomeMDIChildCreator child_create_func);
+
+/* gnome_mdi_save_state (): call this with the GnomeMDI object as the
+ * first and the config section name as the second argument. */
+void		gnome_mdi_save_state	(GnomeMDI *mdi, const gchar *section);
+
+G_END_DECLS
+
+#endif
diff --git a/libgnomeui/gnome-mdi.c b/libgnomeui/gnome-mdi.c
new file mode 100644
index 0000000..79d537f
--- /dev/null
+++ b/libgnomeui/gnome-mdi.c
@@ -0,0 +1,2553 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* gnome-mdi.c - implementation of the GnomeMDI object
+
+   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+   All rights reserved.
+
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Jaka Mocnik <jaka mocnik kiss uni-lj si>
+*/
+/*
+  @NOTATION@
+*/
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+
+#include <libgnome/gnome-config.h>
+#include <libgnome/gnome-i18n.h>
+#include <libgnome/gnome-util.h>
+#include "gnome-app.h"
+#include "gnome-cursors.h"
+#include "gnome-dock-layout.h"
+#include "gnome-stock.h"
+#include "gnome-preferences.h"
+#include "gnome-pouch.h"
+#include "gnome-roo.h"
+#include "gnome-macros.h"
+#include "gnome-mdi.h"
+#include "gnome-mdi-child.h"
+#include "gnome-mdiP.h"
+
+#include <libgnomeuiP.h>
+
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+static void            gnome_mdi_class_init(GnomeMDIClass  *);
+static void            gnome_mdi_init(GnomeMDI *);
+static void            gnome_mdi_destroy(GtkObject *);
+static void            gnome_mdi_finalize(GObject *);
+static void            gnome_mdi_app_create(GnomeMDI *, GnomeApp *);
+static void            gnome_mdi_view_changed(GnomeMDI *, GtkWidget *);
+
+static void            child_list_create(GnomeMDI *, GnomeApp *);
+static void            child_list_activated_cb(GtkWidget *, GnomeMDI *);
+static GtkWidget       *find_item_by_child(GtkMenuShell *, GnomeMDIChild *);
+
+static GtkWidget       *app_create(GnomeMDI *);
+static GtkWidget       *app_clone(GnomeMDI *, GnomeApp *);
+static void            app_destroy(GnomeApp *, GnomeMDI *);
+static gint            app_toplevel_delete_event(GnomeApp *, GdkEventAny *, GnomeMDI *);
+static gint            app_book_delete_event(GnomeApp *, GdkEventAny *, GnomeMDI *);
+static gint            app_wiw_delete_event (GnomeApp *app, GdkEventAny *event, GnomeMDI *mdi);
+static void            app_focus_in_event(GnomeApp *, GdkEventFocus *, GnomeMDI *);
+
+static GtkWidget       *book_create(GnomeMDI *);
+static void            book_switch_page(GtkNotebook *, GtkNotebookPage *, gint, GnomeMDI *);
+static gint            book_motion(GtkWidget *widget, GdkEventMotion *e, gpointer data);
+static gint            book_button_press(GtkWidget *widget, GdkEventButton *e, gpointer data);
+static gint            book_button_release(GtkWidget *widget, GdkEventButton *e, gpointer data);
+static void            book_add_view(GtkNotebook *, GtkWidget *);
+static void            set_page_by_widget(GtkNotebook *, GtkWidget *);
+
+static GtkWidget       *pouch_create (GnomeMDI *mdi);
+static void            pouch_add_view (GnomePouch *pouch, GtkWidget *view);
+static void            pouch_unselect_child(GnomePouch *pouch, GnomeRoo *roo, GnomeMDI *mdi);
+static void            pouch_select_child(GnomePouch *pouch, GnomeRoo *roo, GnomeMDI *mdi);
+static void            pouch_close_child(GnomePouch *pouch, GnomeRoo *roo, GnomeMDI *mdi);
+
+static void            top_add_view(GnomeMDI *, GtkWidget *, GnomeMDIChild *, GtkWidget *);
+static void            set_active_view(GnomeMDI *, GtkWidget *);
+
+static GnomeUIInfo     *copy_ui_info_tree(const GnomeUIInfo *);
+static void            free_ui_info_tree(GnomeUIInfo *);
+static gint            count_ui_info_items(const GnomeUIInfo *);
+
+static void            remove_view(GnomeMDI *, GtkWidget *);
+static void            remove_child(GnomeMDI *, GnomeMDIChild *);
+
+/* convenience functions that call child's "virtual" functions */
+static GList           *child_create_menus(GnomeMDIChild *, GtkWidget *);
+static GtkWidget       *child_set_label(GnomeMDIChild *, GtkWidget *);
+
+static gboolean		    emit_boolean_pointer (GnomeMDI *mdi,
+											  int sig,
+											  GtkObject *pointer,
+											  gboolean default_return);
+
+/* a macro for getting the app's pouch (app->scrolledwindow->viewport->pouch) */
+#define get_pouch_from_app(app) \
+        GNOME_POUCH(GTK_BIN(GTK_BIN(GNOME_APP(app)->contents)->child)->child)
+
+static GdkCursor *drag_cursor = NULL;
+
+enum {
+	ADD_CHILD,
+	REMOVE_CHILD,
+	ADD_VIEW,
+	REMOVE_VIEW,
+	CHILD_CHANGED,
+	VIEW_CHANGED,
+	APP_CREATED,
+	LAST_SIGNAL
+};
+
+static gint mdi_signals[LAST_SIGNAL];
+
+GNOME_CLASS_BOILERPLATE (GnomeMDI, gnome_mdi, GtkObject, gtk_object);
+
+static gboolean
+emit_boolean_pointer (GnomeMDI *mdi, int sig,
+					  GtkObject *pointer,
+					  gboolean default_return)
+{
+	gboolean retval;
+	GValue params[2] = {{0}};
+	GValue rvalue = {0};
+
+	g_return_val_if_fail (GTK_IS_OBJECT (mdi), default_return);
+
+	g_value_init (params + 0, GTK_OBJECT_TYPE (mdi));
+	g_value_set_object (params + 0, G_OBJECT (mdi));
+
+	g_value_init (params + 1, GTK_OBJECT_TYPE (pointer));
+	g_value_set_object (params + 1, G_OBJECT (pointer));
+
+	g_value_init (&rvalue, G_TYPE_BOOLEAN);
+	g_value_set_boolean (&rvalue, default_return);
+
+	g_signal_emitv (params, mdi_signals[sig], 0, &rvalue);
+
+	retval = g_value_get_boolean (&rvalue);
+  
+	g_value_unset (params + 0);
+	g_value_unset (params + 1);
+	g_value_unset (&rvalue);
+
+	return retval;
+}
+
+static void
+gnome_mdi_class_init (GnomeMDIClass *klass)
+{
+	GtkObjectClass *object_class;
+	GObjectClass *gobject_class;
+	
+	object_class = (GtkObjectClass*) klass;
+	gobject_class = (GObjectClass*) klass;
+	
+	object_class->destroy = gnome_mdi_destroy;
+	gobject_class->finalize = gnome_mdi_finalize;
+
+	mdi_signals[ADD_CHILD] =
+		gtk_signal_new ("add_child",
+				GTK_RUN_LAST,
+				GTK_CLASS_TYPE(object_class),
+				GTK_SIGNAL_OFFSET (GnomeMDIClass, add_child),
+				gnome_marshal_BOOLEAN__OBJECT,
+				GTK_TYPE_BOOL, 1, GNOME_TYPE_MDI_CHILD);
+	mdi_signals[REMOVE_CHILD] =
+		gtk_signal_new ("remove_child",
+				GTK_RUN_LAST,
+				GTK_CLASS_TYPE(object_class),
+				GTK_SIGNAL_OFFSET (GnomeMDIClass, remove_child),
+				gnome_marshal_BOOLEAN__OBJECT,
+				GTK_TYPE_BOOL, 1, GNOME_TYPE_MDI_CHILD);
+	mdi_signals[ADD_VIEW] =
+		gtk_signal_new ("add_view",
+				GTK_RUN_LAST,
+				GTK_CLASS_TYPE(object_class),
+				GTK_SIGNAL_OFFSET (GnomeMDIClass, add_view),
+				gnome_marshal_BOOLEAN__OBJECT,
+				GTK_TYPE_BOOL, 1, GTK_TYPE_WIDGET);
+	mdi_signals[REMOVE_VIEW] =
+		gtk_signal_new ("remove_view",
+				GTK_RUN_LAST,
+				GTK_CLASS_TYPE(object_class),
+				GTK_SIGNAL_OFFSET (GnomeMDIClass, remove_view),
+				gnome_marshal_BOOLEAN__OBJECT,
+				GTK_TYPE_BOOL, 1, GTK_TYPE_WIDGET);
+	mdi_signals[CHILD_CHANGED] =
+		gtk_signal_new ("child_changed",
+				GTK_RUN_FIRST,
+				GTK_CLASS_TYPE(object_class),
+				GTK_SIGNAL_OFFSET (GnomeMDIClass, child_changed),
+				gtk_marshal_VOID__OBJECT,
+				GTK_TYPE_NONE, 1, GNOME_TYPE_MDI_CHILD);
+	mdi_signals[VIEW_CHANGED] =
+		gtk_signal_new ("view_changed",
+				GTK_RUN_FIRST,
+				GTK_CLASS_TYPE(object_class),
+				GTK_SIGNAL_OFFSET(GnomeMDIClass, view_changed),
+				gtk_marshal_VOID__OBJECT,
+				GTK_TYPE_NONE, 1, GTK_TYPE_WIDGET);
+	mdi_signals[APP_CREATED] =
+		gtk_signal_new ("app_created",
+				GTK_RUN_FIRST,
+				GTK_CLASS_TYPE(object_class),
+				GTK_SIGNAL_OFFSET (GnomeMDIClass, app_created),
+				gtk_marshal_VOID__OBJECT,
+				GTK_TYPE_NONE, 1, GNOME_TYPE_APP);
+	
+	
+	klass->add_child = NULL;
+	klass->remove_child = NULL;
+	klass->add_view = NULL;
+	klass->remove_view = NULL;
+	klass->child_changed = NULL;
+	klass->view_changed = gnome_mdi_view_changed;
+	klass->app_created = gnome_mdi_app_create;
+}
+
+static void
+gnome_mdi_view_changed (GnomeMDI *mdi, GtkWidget *old_view)
+{
+	GList *menu_list = NULL, *children;
+	GtkWidget *parent = NULL, *view;
+	GtkWidget *toolbar;
+	GnomeApp *app = NULL, *old_app = NULL;
+	GnomeMDIChild *child;
+	GnomeDockItem *dock_item;
+	GnomeUIInfo *ui_info;
+	gpointer data;
+	gint pos, items;
+
+#ifdef GNOME_ENABLE_DEBUG
+	g_message("GnomeMDI: view changed handler called");
+#endif
+
+	view = mdi->priv->active_view;
+
+	if(view)
+		app = gnome_mdi_get_app_from_view(view);
+	if(old_view) {
+		data = gtk_object_get_data(GTK_OBJECT(old_view), GNOME_MDI_APP_KEY);
+		if(data)
+			old_app = GNOME_APP(data);
+	}
+
+	if(view && old_view && app != old_app) {
+		if(GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(app),
+											   GNOME_MDI_ITEM_COUNT_KEY)) != 0)
+			return;
+	}
+
+	if(app == NULL)
+		app = old_app;
+
+	/* free previous child toolbar ui-info */
+	ui_info = gtk_object_get_data(GTK_OBJECT(app),
+								  GNOME_MDI_CHILD_TOOLBAR_INFO_KEY);
+	if(ui_info != NULL) {
+		free_ui_info_tree(ui_info);
+		gtk_object_set_data(GTK_OBJECT(app),
+							GNOME_MDI_CHILD_TOOLBAR_INFO_KEY, NULL);
+	}
+	ui_info = NULL;
+
+	/* remove old child's toolbar */
+	dock_item = gnome_app_get_dock_item_by_name(app,
+												GNOME_MDI_CHILD_TOOLBAR_NAME);
+	if(dock_item)
+		gtk_widget_destroy(GTK_WIDGET(dock_item));
+
+	/* free previous child menu ui-info */
+	ui_info = gtk_object_get_data(GTK_OBJECT(app),
+								  GNOME_MDI_CHILD_MENU_INFO_KEY);
+	if(ui_info != NULL) {
+		free_ui_info_tree(ui_info);
+		gtk_object_set_data(GTK_OBJECT(app),
+							GNOME_MDI_CHILD_MENU_INFO_KEY, NULL);
+	}
+	ui_info = NULL;
+	
+	if(mdi->priv->child_menu_path)
+		parent = gnome_app_find_menu_pos(app->menubar,
+										 mdi->priv->child_menu_path, &pos);
+
+	/* remove old child-specific menus */
+	items = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(app),
+												GNOME_MDI_ITEM_COUNT_KEY));
+	if(items > 0 && parent) {
+		GtkWidget *widget;
+
+		/* remove items; should be kept in sync with gnome_app_remove_menus! */
+		children = g_list_nth(GTK_MENU_SHELL(parent)->children, pos);
+		while(children && items > 0) {
+			widget = GTK_WIDGET(children->data);
+			children = children->next;
+
+			/* if this item contains a gtkaccellabel, we have to set its
+			   accel_widget to NULL so that the item gets unrefed. */
+			if(GTK_IS_ACCEL_LABEL(GTK_BIN(widget)->child))
+				gtk_accel_label_set_accel_widget(GTK_ACCEL_LABEL(GTK_BIN(widget)->child), NULL);
+
+			gtk_container_remove(GTK_CONTAINER(parent), widget);
+			items--;
+		}
+	}
+
+	items = 0;
+	if(view) {
+		gtk_object_set_data(GTK_OBJECT(view), GNOME_MDI_APP_KEY, app);
+		child = gnome_mdi_get_child_from_view(view);
+
+		/* set the title */
+		if( mdi->priv->mode == GNOME_MDI_MODAL ||
+			mdi->priv->mode == GNOME_MDI_TOPLEVEL ) {
+			/* in MODAL and TOPLEVEL modes the window title includes the active
+			   child name: "child_name - mdi_title" */
+			gchar *fullname;
+			
+			fullname = g_strconcat(child->priv->name, " - ", mdi->priv->title, NULL);
+			gtk_window_set_title(GTK_WINDOW(app), fullname);
+			g_free(fullname);
+		}
+		else
+			gtk_window_set_title(GTK_WINDOW(app), mdi->priv->title);
+		
+		/* create new child-specific menus */
+		if(parent) {
+			if(child->priv->menu_template) {
+				ui_info = copy_ui_info_tree(child->priv->menu_template);
+				gnome_app_insert_menus_with_data(app,
+												 mdi->priv->child_menu_path,
+												 ui_info, child);
+				gtk_object_set_data(GTK_OBJECT(app),
+									GNOME_MDI_CHILD_MENU_INFO_KEY, ui_info);
+				gtk_object_set_data(GTK_OBJECT(view),
+									GNOME_MDI_CHILD_MENU_INFO_KEY, ui_info);
+				items = count_ui_info_items(ui_info);
+			}
+			else {
+				menu_list = child_create_menus(child, view);
+
+				if(menu_list) {
+					GList *menu;
+
+					items = 0;
+					menu = menu_list;					
+					while(menu) {
+						gtk_menu_shell_insert(GTK_MENU_SHELL(parent),
+											  GTK_WIDGET(menu->data), pos);
+						menu = menu->next;
+						pos++;
+						items++;
+					}
+
+					g_list_free(menu_list);
+				}
+				else
+					items = 0;
+			}
+		}
+
+		/* insert the new toolbar */
+		if(child->priv->toolbar_template &&
+		   (ui_info = copy_ui_info_tree(child->priv->toolbar_template)) != NULL) {
+			toolbar = gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL,
+									  GTK_TOOLBAR_BOTH);
+			gnome_app_fill_toolbar_with_data(GTK_TOOLBAR(toolbar), ui_info,
+											 app->accel_group, child);
+			gnome_mdi_child_add_toolbar(child, app, GTK_TOOLBAR(toolbar));
+			gtk_object_set_data(GTK_OBJECT(app),
+								GNOME_MDI_CHILD_TOOLBAR_INFO_KEY, ui_info);
+			gtk_object_set_data(GTK_OBJECT(view),
+								GNOME_MDI_CHILD_TOOLBAR_INFO_KEY, ui_info);
+		}
+	}
+	else
+		gtk_window_set_title(GTK_WINDOW(app), mdi->priv->title);
+
+	gtk_object_set_data(GTK_OBJECT(app), GNOME_MDI_ITEM_COUNT_KEY,
+						GINT_TO_POINTER(items));
+
+	if(parent)
+		gtk_widget_queue_resize(parent);
+}
+
+static void
+gnome_mdi_app_create (GnomeMDI *mdi, GnomeApp *app)
+{
+	GnomeUIInfo *ui_info;
+
+	/* set up menus */
+	if(mdi->priv->menu_template) {
+		ui_info = copy_ui_info_tree(mdi->priv->menu_template);
+		gnome_app_create_menus_with_data(app, ui_info, mdi);
+		gtk_object_set_data(GTK_OBJECT(app), GNOME_MDI_MENUBAR_INFO_KEY,
+							ui_info);
+	}
+
+	/* create toolbar */
+	if(mdi->priv->toolbar_template) {
+		ui_info = copy_ui_info_tree(mdi->priv->toolbar_template);
+		gnome_app_create_toolbar_with_data(app, ui_info, mdi);
+		gtk_object_set_data(GTK_OBJECT(app), GNOME_MDI_TOOLBAR_INFO_KEY,
+							ui_info);
+	}
+
+	child_list_create(mdi, app);
+}
+
+static void
+gnome_mdi_finalize (GObject *object)
+{
+    GnomeMDI *mdi;
+
+	g_return_if_fail(object != NULL);
+	g_return_if_fail(GNOME_IS_MDI(object));
+
+#ifdef GNOME_ENABLE_DEBUG
+	g_message("GnomeMDI: finalization!\n");
+#endif
+
+	mdi = GNOME_MDI(object);
+
+	if(mdi->priv->child_menu_path)
+		g_free(mdi->priv->child_menu_path);
+	if(mdi->priv->child_list_path)
+		g_free(mdi->priv->child_list_path);
+	
+	g_free(mdi->priv->appname);
+	g_free(mdi->priv->title);
+
+	GNOME_CALL_PARENT_HANDLER (G_OBJECT_CLASS, finalize, (object));
+}
+
+static void
+gnome_mdi_destroy (GtkObject *object)
+{
+	GnomeMDI *mdi;
+	GList *child_node;
+	GnomeMDIChild *child;
+
+	g_return_if_fail(object != NULL);
+	g_return_if_fail(GNOME_IS_MDI (object));
+
+	/* remember, destroy can be run multiple times! */
+	
+	mdi = GNOME_MDI(object);
+	
+	/* remove all remaining children */
+	child_node = mdi->priv->children;
+	while(child_node) {
+		child = GNOME_MDI_CHILD(child_node->data);
+		child_node = child_node->next;
+		remove_child(mdi, child);
+	}
+
+	/* this call tries to behave in a manner similar to
+	   destruction of toplevel windows: it unrefs itself,
+	   thus taking care of the initial reference added
+	   upon mdi creation. */
+	if (mdi->priv->has_user_refcount != 0) {
+		mdi->priv->has_user_refcount = 0;
+		gtk_object_unref(object);
+	}
+
+	GNOME_CALL_PARENT_HANDLER (GTK_OBJECT_CLASS, destroy, (object));
+}
+
+static void
+gnome_mdi_init (GnomeMDI *mdi)
+{
+	mdi->priv = g_new0(GnomeMDIPrivate, 1);
+
+	mdi->priv->mode = gnome_preferences_get_mdi_mode();
+	mdi->priv->tab_pos = gnome_preferences_get_mdi_tab_pos();
+	
+	mdi->priv->signal_id = 0;
+	mdi->priv->in_drag = FALSE;
+
+	mdi->priv->children = NULL;
+	mdi->priv->windows = NULL;
+	mdi->priv->registered = NULL;
+	
+	mdi->priv->active_child = NULL;
+	mdi->priv->active_window = NULL;
+	mdi->priv->active_view = NULL;
+	
+	mdi->priv->menu_template = NULL;
+	mdi->priv->toolbar_template = NULL;
+	mdi->priv->child_menu_path = NULL;
+	mdi->priv->child_list_path = NULL;
+
+	mdi->priv->has_user_refcount = 1;
+}
+
+static GList *
+child_create_menus (GnomeMDIChild *child, GtkWidget *view)
+{
+	if(GNOME_MDI_CHILD_GET_CLASS(child)->create_menus)
+		return GNOME_MDI_CHILD_GET_CLASS(child)->create_menus(child, view);
+
+	return NULL;
+}
+
+static GtkWidget *
+child_set_label (GnomeMDIChild *child, GtkWidget *label)
+{
+	if (GNOME_MDI_CHILD_GET_CLASS(child)->set_label != NULL)
+		return GNOME_MDI_CHILD_GET_CLASS(child)->set_label(child, label);
+	return NULL;
+}
+
+/* the app-helper support routines
+ * copying and freeing of GnomeUIInfo trees and counting items in them.
+ */
+static GnomeUIInfo *
+copy_ui_info_tree (const GnomeUIInfo source[])
+{
+	GnomeUIInfo *copy;
+	int i, count;
+	
+	for(count = 0; source[count].type != GNOME_APP_UI_ENDOFINFO; count++)
+		;
+	
+	count++;
+
+	copy = g_malloc(count*sizeof(GnomeUIInfo));
+	
+	memcpy(copy, source, count*sizeof(GnomeUIInfo));
+	
+	for(i = 0; i < count; i++) {
+		if( (source[i].type == GNOME_APP_UI_SUBTREE) ||
+			(source[i].type == GNOME_APP_UI_SUBTREE_STOCK) ||
+			(source[i].type == GNOME_APP_UI_RADIOITEMS) )
+			copy[i].moreinfo = copy_ui_info_tree(source[i].moreinfo);
+	}
+	
+	return copy;
+}
+
+static gint
+count_ui_info_items (const GnomeUIInfo *ui_info)
+{
+	gint num;
+	
+	for(num = 0; ui_info[num].type != GNOME_APP_UI_ENDOFINFO; num++)
+		;
+	
+	return num;
+}
+
+static void
+free_ui_info_tree (GnomeUIInfo *root)
+{
+	int count;
+	
+	for(count = 0; root[count].type != GNOME_APP_UI_ENDOFINFO; count++)
+		if( (root[count].type == GNOME_APP_UI_SUBTREE) ||
+			(root[count].type == GNOME_APP_UI_SUBTREE_STOCK) ||
+			(root[count].type == GNOME_APP_UI_RADIOITEMS) )
+			free_ui_info_tree(root[count].moreinfo);
+	
+	g_free(root);
+}
+
+static void
+set_page_by_widget (GtkNotebook *book, GtkWidget *child)
+{
+	gint i;
+
+#ifdef GNOME_ENABLE_DEBUG
+	g_message("GnomeMDI: set_page_by_widget");
+#endif
+	
+	i = gtk_notebook_page_num(book, child);
+	if(i != gtk_notebook_get_current_page(book))
+		gtk_notebook_set_page(book, i);
+}
+
+static GtkWidget *
+find_item_by_child (GtkMenuShell *shell, GnomeMDIChild *child)
+{
+	GList *node;
+
+	node = shell->children;
+	while(node) {
+		if(gtk_object_get_data(GTK_OBJECT(node->data), GNOME_MDI_CHILD_KEY) == child)
+			return GTK_WIDGET(node->data);
+		
+		node = node->next;
+	}
+
+	return NULL;
+}
+
+static void
+child_list_activated_cb (GtkWidget *w, GnomeMDI *mdi)
+{
+	GnomeMDIChild *child;
+	
+	child = gtk_object_get_data(GTK_OBJECT(w), GNOME_MDI_CHILD_KEY);
+	
+	if( child && (child != mdi->priv->active_child) ) {
+		if(child->priv->views)
+			gnome_mdi_set_active_view(mdi, child->priv->views->data);
+		else
+			gnome_mdi_add_view(mdi, child);
+	}
+}
+
+static void
+child_list_create (GnomeMDI *mdi, GnomeApp *app)
+{
+	GtkWidget *submenu, *item, *label;
+	GList *child_node;
+	gint pos;
+	
+	if(mdi->priv->child_list_path == NULL)
+		return;
+	
+	submenu = gnome_app_find_menu_pos(app->menubar,
+									  mdi->priv->child_list_path, &pos);
+	
+	if(submenu == NULL)
+		return;
+
+	child_node = mdi->priv->children;
+	while(child_node) {
+		item = gtk_menu_item_new();
+		gtk_signal_connect(GTK_OBJECT(item), "activate",
+						   GTK_SIGNAL_FUNC(child_list_activated_cb), mdi);
+		label = child_set_label(GNOME_MDI_CHILD(child_node->data), NULL);
+		gtk_widget_show(label);
+		gtk_container_add(GTK_CONTAINER(item), label);
+		gtk_object_set_data(GTK_OBJECT(item), GNOME_MDI_CHILD_KEY,
+							child_node->data);
+		gtk_widget_show(item);
+		
+		gtk_menu_shell_append(GTK_MENU_SHELL(submenu), item);
+		
+		child_node = child_node->next;
+	}
+
+	gtk_widget_queue_resize(submenu);
+}
+
+void
+gnome_mdi_child_list_remove (GnomeMDI *mdi, GnomeMDIChild *child)
+{
+	GtkWidget *item, *shell;
+	GnomeApp *app;
+	GList *app_node;
+	gint pos;
+	
+	if(mdi->priv->child_list_path == NULL)
+		return;
+	
+	app_node = mdi->priv->windows;
+	while(app_node) {
+		app = GNOME_APP(app_node->data);
+		shell = gnome_app_find_menu_pos(app->menubar,
+										mdi->priv->child_list_path, &pos);
+		if(shell) {
+			item = find_item_by_child(GTK_MENU_SHELL(shell), child);
+			if(item) {
+				gtk_container_remove(GTK_CONTAINER(shell), item);
+				gtk_widget_queue_resize (GTK_WIDGET (shell));
+			}
+		}
+		
+		app_node = app_node->next;
+	}
+}
+
+void
+gnome_mdi_child_list_add (GnomeMDI *mdi, GnomeMDIChild *child)
+{
+	GtkWidget *item, *submenu, *label;
+	GnomeApp *app;
+	GList *app_node;
+	gint pos;
+	
+	if(mdi->priv->child_list_path == NULL)
+		return;
+	
+	app_node = mdi->priv->windows;
+	while(app_node) {
+		app = GNOME_APP(app_node->data);
+		submenu = gnome_app_find_menu_pos(app->menubar,
+										  mdi->priv->child_list_path, &pos);
+		if(submenu) {
+			item = gtk_menu_item_new();
+			gtk_signal_connect(GTK_OBJECT(item), "activate",
+							   GTK_SIGNAL_FUNC(child_list_activated_cb), mdi);
+			label = child_set_label(child, NULL);
+			gtk_widget_show(label);
+			gtk_container_add(GTK_CONTAINER(item), label);
+			gtk_object_set_data(GTK_OBJECT(item), GNOME_MDI_CHILD_KEY, child);
+			gtk_widget_show(item);
+			gtk_menu_shell_append(GTK_MENU_SHELL(submenu), item);
+			gtk_widget_queue_resize(submenu);
+		}
+		
+		app_node = app_node->next;
+	}
+}
+
+static gint
+book_motion (GtkWidget *widget, GdkEventMotion *e, gpointer data)
+{
+	GnomeMDI *mdi;
+
+	mdi = GNOME_MDI(data);
+
+	if(!drag_cursor)
+		drag_cursor = gnome_stock_cursor_new(GNOME_STOCK_CURSOR_FLEUR);
+
+	if(e->window == widget->window) {
+		mdi->priv->in_drag = TRUE;
+		gtk_grab_add(widget);
+		gdk_pointer_grab(widget->window, FALSE,
+						 GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
+						 NULL, drag_cursor, GDK_CURRENT_TIME);
+		if(mdi->priv->signal_id) {
+			gtk_signal_disconnect(GTK_OBJECT(widget), mdi->priv->signal_id);
+			mdi->priv->signal_id = 0;
+		}
+	}
+
+	return FALSE;
+}
+
+static gint
+book_button_press (GtkWidget *widget, GdkEventButton *e, gpointer data)
+{
+	GnomeMDI *mdi;
+
+	mdi = GNOME_MDI(data);
+
+	if(e->button == 1 && e->window == widget->window)
+		mdi->priv->signal_id = gtk_signal_connect(GTK_OBJECT(widget),
+												  "motion_notify_event",
+												  GTK_SIGNAL_FUNC(book_motion),
+												  mdi);
+
+	return FALSE;
+}
+
+static gint
+book_button_release (GtkWidget *widget, GdkEventButton *e, gpointer data)
+{
+	gint x = e->x_root, y = e->y_root;
+	GnomeMDI *mdi;
+
+	mdi = GNOME_MDI(data);
+	
+	if(mdi->priv->signal_id) {
+		gtk_signal_disconnect(GTK_OBJECT(widget), mdi->priv->signal_id);
+		mdi->priv->signal_id = 0;
+	}
+
+	if(e->button == 1 && e->window == widget->window && mdi->priv->in_drag) {
+		GdkWindow *window;
+		GList *window_node;
+		GnomeApp *app;
+		GtkWidget *view, *new_book, *new_app;
+		GtkNotebook *old_book = GTK_NOTEBOOK(widget);
+		gint old_page_no;
+
+		mdi->priv->in_drag = FALSE;
+		gdk_pointer_ungrab(GDK_CURRENT_TIME);
+		gtk_grab_remove(widget);
+
+		window = gdk_window_at_pointer(&x, &y);
+		if(window)
+			window = gdk_window_get_toplevel(window);
+
+		window_node = mdi->priv->windows;
+		while(window_node) {
+			if(window == GTK_WIDGET(window_node->data)->window) {
+				gint cur_page_no;
+
+				/* page was dragged to another notebook */
+				old_book = GTK_NOTEBOOK(widget);
+				new_book = GNOME_APP(window_node->data)->contents;
+
+				if(old_book == (GtkNotebook *)new_book) /* page has been dropped on the source notebook */
+					return FALSE;
+	
+				cur_page_no = gtk_notebook_get_current_page(old_book);
+				if(cur_page_no >= 0) {
+					gint new_page_no;
+
+					view = gtk_notebook_get_nth_page(old_book, cur_page_no);
+					gtk_container_remove(GTK_CONTAINER(old_book), view);
+
+					/* a trick to make view_changed signal get emitted
+					   properly, taking care of updating the gnomeapps */
+					new_page_no = gtk_notebook_get_current_page(GTK_NOTEBOOK(new_book));
+					if(new_page_no >= 0) {
+						mdi->priv->active_view =
+							gtk_notebook_get_nth_page(GTK_NOTEBOOK(new_book), new_page_no);
+						mdi->priv->active_child =
+							gnome_mdi_get_child_from_view(mdi->priv->active_view);
+					}
+					else {
+						mdi->priv->active_view = NULL;
+						mdi->priv->active_child = NULL;
+					}
+
+					book_add_view(GTK_NOTEBOOK(new_book), view);
+
+					app = gnome_mdi_get_app_from_view(view);
+					gdk_window_raise(GTK_WIDGET(app)->window);
+
+					if(old_book->cur_page == NULL) {
+						mdi->priv->active_window = app;
+						app = GNOME_APP(gtk_widget_get_toplevel(GTK_WIDGET(old_book)));
+						mdi->priv->windows =
+							g_list_remove(mdi->priv->windows, app);
+						gtk_widget_destroy(GTK_WIDGET(app));
+					}
+				}
+
+				return FALSE;
+			}
+				
+			window_node = window_node->next;
+		}
+
+		if(g_list_length(old_book->children) == 1)
+			return FALSE;
+
+		/* create a new toplevel */
+		old_page_no = gtk_notebook_get_current_page(old_book);
+		if(old_page_no >= 0) {
+			gint width, height;
+				
+			view = gtk_notebook_get_nth_page(old_book, old_page_no);
+	
+			app = gnome_mdi_get_app_from_view(view);
+
+			width = view->allocation.width;
+			height = view->allocation.height;
+			
+			gtk_container_remove(GTK_CONTAINER(old_book), view);
+
+			new_app = app_clone(mdi, app);
+			new_book = book_create(mdi);
+			gnome_app_set_contents(GNOME_APP(new_app), new_book);
+			book_add_view(GTK_NOTEBOOK(new_book), view);
+
+			gtk_window_set_position(GTK_WINDOW(new_app), GTK_WIN_POS_MOUSE);
+			gtk_widget_set_usize (view, width, height);
+
+			if(!GTK_WIDGET_VISIBLE(new_app))
+				gtk_widget_show(new_app);
+		}
+	}
+
+	return FALSE;
+}
+
+static GtkWidget *
+book_create (GnomeMDI *mdi)
+{
+	GtkWidget *us;
+	
+	us = gtk_notebook_new();
+	gtk_notebook_set_tab_pos(GTK_NOTEBOOK(us), mdi->priv->tab_pos);
+	gtk_widget_add_events(us, GDK_BUTTON1_MOTION_MASK);
+	gtk_signal_connect(GTK_OBJECT(us), "switch_page",
+					   GTK_SIGNAL_FUNC(book_switch_page), mdi);
+	gtk_signal_connect(GTK_OBJECT(us), "button_press_event",
+					   GTK_SIGNAL_FUNC(book_button_press), mdi);
+	gtk_signal_connect(GTK_OBJECT(us), "button_release_event",
+					   GTK_SIGNAL_FUNC(book_button_release), mdi);
+	gtk_notebook_set_scrollable(GTK_NOTEBOOK(us), TRUE);
+	gtk_widget_show(us);
+	
+	return us;
+}
+
+static void 
+pouch_unselect_child(GnomePouch *pouch, GnomeRoo *roo, GnomeMDI *mdi)
+{
+	set_active_view(mdi, NULL);
+}
+
+static void
+pouch_select_child(GnomePouch *pouch, GnomeRoo *roo, GnomeMDI *mdi)
+{
+	if(roo)
+		set_active_view(mdi, GTK_BIN(roo)->child);
+	else
+		set_active_view(mdi, NULL);
+}
+
+static void
+pouch_close_child(GnomePouch *pouch, GnomeRoo *roo, GnomeMDI *mdi)
+{
+	GnomeMDIChild *child;
+
+	child = gnome_mdi_get_child_from_view(GTK_BIN(roo)->child);
+	if(g_list_length(child->priv->views) == 1) {
+		/* if this is the last view, we have to remove the child! */
+		if(!gnome_mdi_remove_child(mdi, child))
+			return;
+	}
+	else
+		gnome_mdi_remove_view(mdi, GTK_BIN(roo)->child);
+}
+
+static GtkWidget *
+pouch_create (GnomeMDI *mdi)
+{
+	GtkWidget *sw, *pouch;
+
+	sw = gtk_scrolled_window_new(NULL, NULL);
+	gtk_widget_show(sw);
+	pouch = gnome_pouch_new();
+	gnome_pouch_enable_popup_menu(GNOME_POUCH(pouch), TRUE);
+	gtk_signal_connect(GTK_OBJECT(pouch), "select-child",
+					   GTK_SIGNAL_FUNC(pouch_select_child), mdi);
+	gtk_signal_connect(GTK_OBJECT(pouch), "unselect-child",
+					   GTK_SIGNAL_FUNC(pouch_unselect_child), mdi);
+	gtk_signal_connect(GTK_OBJECT(pouch), "close-child",
+					   GTK_SIGNAL_FUNC(pouch_close_child), mdi);
+	gtk_widget_show(pouch);
+	gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw), pouch);
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
+								   GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+	return sw;
+}
+
+static void
+book_add_view (GtkNotebook *book, GtkWidget *view)
+{
+	GnomeMDIChild *child;
+	GtkWidget *title;
+
+	child = gnome_mdi_get_child_from_view(view);
+
+	title = child_set_label(child, NULL);
+
+	gtk_notebook_append_page(book, view, title);
+
+	if(g_list_length(book->children) > 1)
+		set_page_by_widget(book, view);
+}
+
+static void
+pouch_add_view (GnomePouch *pouch, GtkWidget *view)
+{
+	GnomeMDIChild *child;
+	GtkWidget *roo;
+
+	child = gnome_mdi_get_child_from_view(view);
+
+	roo = gnome_roo_new();
+	gnome_roo_set_title(GNOME_ROO(roo), child->priv->name);
+	gtk_container_add(GTK_CONTAINER(roo), view);
+	gtk_widget_show(roo);
+	gtk_container_add(GTK_CONTAINER(pouch), roo);
+	gnome_pouch_select_roo(pouch, GNOME_ROO(roo));
+}
+
+static void
+book_switch_page (GtkNotebook *book, GtkNotebookPage *page, gint page_num, GnomeMDI *mdi)
+{
+#ifdef GNOME_ENABLE_DEBUG
+	g_message("GnomeMDI: switching pages");
+#endif
+
+	if(page) {
+		GtkWidget *view;
+
+		view = gtk_notebook_get_nth_page(book, page_num);
+		if(view != mdi->priv->active_view)
+			set_active_view(mdi, view);
+	}
+	else
+		set_active_view(mdi, NULL);  
+}
+
+static void
+app_focus_in_event (GnomeApp *app, GdkEventFocus *event, GnomeMDI *mdi)
+{
+	/* updates active_view and active_child when a new toplevel receives focus */
+	g_return_if_fail(GNOME_IS_APP(app));
+#ifdef GNOME_ENABLE_DEBUG
+	g_message("GnomeMDI: toplevel receiving focus");
+#endif
+
+	if(mdi->priv->mode == GNOME_MDI_TOPLEVEL || 
+	   mdi->priv->mode == GNOME_MDI_MODAL)
+		set_active_view(mdi, app->contents);
+	else if(mdi->priv->mode == GNOME_MDI_WIW) {
+		GnomeRoo *roo = gnome_pouch_get_selected(get_pouch_from_app(app));
+		if(roo)
+			set_active_view(mdi, GTK_BIN(roo)->child);
+		else
+			set_active_view(mdi, NULL);
+	}
+	else if(mdi->priv->mode == GNOME_MDI_NOTEBOOK) {
+		gint cur_page_no = gtk_notebook_get_current_page(GTK_NOTEBOOK(app->contents));
+		if(cur_page_no >= 0)
+			set_active_view(mdi, gtk_notebook_get_nth_page(GTK_NOTEBOOK(app->contents), cur_page_no));
+		else
+			set_active_view(mdi, NULL);
+	}
+
+	mdi->priv->active_window = app;
+}
+
+static GtkWidget *
+app_clone (GnomeMDI *mdi, GnomeApp *app)
+{
+	GnomeDockLayout *layout;
+	gchar *layout_string = NULL;
+	GtkWidget *new_app;
+
+	if(app) {
+		layout = gnome_dock_get_layout(GNOME_DOCK(app->dock));
+		layout_string = gnome_dock_layout_create_string(layout);
+		gtk_object_unref(GTK_OBJECT(layout));
+	}
+
+	new_app = app_create(mdi);
+
+	if(layout_string) {
+		if(GNOME_APP(new_app)->layout)
+			gnome_dock_layout_parse_string(GNOME_APP(new_app)->layout, layout_string);
+		g_free(layout_string);
+	}
+
+	return new_app;
+}
+
+static gint
+app_toplevel_delete_event (GnomeApp *app, GdkEventAny *event, GnomeMDI *mdi)
+{
+	GnomeMDIChild *child = NULL;
+	
+	if(g_list_length(mdi->priv->windows) == 1) {
+		if(!gnome_mdi_remove_all(mdi))
+			return TRUE;
+
+		mdi->priv->windows = g_list_remove(mdi->priv->windows, app);
+		gtk_widget_destroy(GTK_WIDGET(app));
+		
+		/* only destroy mdi if there are no external objects registered
+		   with it. */
+		if(mdi->priv->registered == NULL)
+			gtk_object_destroy(GTK_OBJECT(mdi));
+	}
+	else if(app->contents) {
+		child = gnome_mdi_get_child_from_view(app->contents);
+		if(g_list_length(child->priv->views) == 1) {
+			/* if this is the last view, we have to remove the child! */
+			if(!gnome_mdi_remove_child(mdi, child))
+				return TRUE;
+		}
+		else
+			if(!gnome_mdi_remove_view(mdi, app->contents))
+				return TRUE;
+	}
+	else {
+		mdi->priv->windows = g_list_remove(mdi->priv->windows, app);
+		gtk_widget_destroy(GTK_WIDGET(app));
+	}
+
+	return FALSE;
+}
+
+static gint
+app_wiw_delete_event (GnomeApp *app, GdkEventAny *event, GnomeMDI *mdi)
+{
+	GnomeMDIChild *child;
+	GtkWidget *view;
+	GList *view_node, *node;
+	gint ret = FALSE;
+	
+	if(g_list_length(mdi->priv->windows) == 1) {		
+		if(!gnome_mdi_remove_all(mdi))
+			return TRUE;
+
+		mdi->priv->windows = g_list_remove(mdi->priv->windows, app);
+		gtk_widget_destroy(GTK_WIDGET(app));
+		
+		/* only destroy mdi if there are no non-MDI windows registered
+		   with it. */
+		if(mdi->priv->registered == NULL)
+			gtk_object_destroy(GTK_OBJECT(mdi));
+	}
+	else {
+		/* first check if all the children in this notebook can be removed */
+		view_node = GTK_FIXED(get_pouch_from_app(app))->children;
+		if(!view_node) {
+			mdi->priv->windows = g_list_remove(mdi->priv->windows, app);
+			gtk_widget_destroy(GTK_WIDGET(app));
+			return FALSE;
+		}
+
+		while(view_node) {
+			view = GTK_BIN(((GtkFixedChild *)view_node->data)->widget)->child;
+			child = gnome_mdi_get_child_from_view(view);
+			
+			view_node = view_node->next;
+			
+			node = child->priv->views;
+			while(node) {
+				if(gnome_mdi_get_app_from_view(node->data) != app)
+					break;
+				
+				node = node->next;
+			}
+			
+			if(node == NULL) {   /* all the views reside in this GnomeApp */
+				ret = emit_boolean_pointer (mdi, REMOVE_CHILD, GTK_OBJECT (child), FALSE);
+				if(!ret)
+					return TRUE;
+			}
+		}
+
+		ret = FALSE;
+		/* now actually remove all children/views! */
+		view_node = GTK_NOTEBOOK(app->contents)->children;
+		while(view_node) {
+			view = GTK_BIN(((GtkFixedChild *)view_node->data)->widget)->child;
+			child = gnome_mdi_get_child_from_view(view);
+			
+			view_node = view_node->next;
+			
+			/* if this is the last view, remove the child */
+			if(g_list_length(child->priv->views) == 1)
+				remove_child(mdi, child);
+			else
+				if(!gnome_mdi_remove_view(mdi, view))
+					ret = TRUE;
+		}
+	}
+
+	return ret;
+}
+
+static gint
+app_book_delete_event (GnomeApp *app, GdkEventAny *event, GnomeMDI *mdi)
+{
+	GnomeMDIChild *child;
+	GtkWidget *view;
+	gint page_no = 0;
+	GList *node;
+	gint ret = FALSE;
+	
+	if(g_list_length(mdi->priv->windows) == 1) {		
+		if(!gnome_mdi_remove_all(mdi))
+			return TRUE;
+
+		mdi->priv->windows = g_list_remove(mdi->priv->windows, app);
+		gtk_widget_destroy(GTK_WIDGET(app));
+		
+		/* only destroy mdi if there are no non-MDI windows registered
+		   with it. */
+		if(mdi->priv->registered == NULL)
+			gtk_object_destroy(GTK_OBJECT(mdi));
+	}
+	else {
+		/* first check if all the children in this notebook can be removed */
+		view = gtk_notebook_get_nth_page(GTK_NOTEBOOK(app->contents), 0);
+		if(!view) {
+			mdi->priv->windows = g_list_remove(mdi->priv->windows, app);
+			gtk_widget_destroy(GTK_WIDGET(app));
+			return FALSE;
+		}
+
+		page_no = 0;
+		while (view != NULL) {
+			child = gnome_mdi_get_child_from_view(view);
+
+			view = gtk_notebook_get_nth_page(GTK_NOTEBOOK(app->contents),
+											 ++page_no);
+			
+			node = child->priv->views;
+			while(node) {
+				if(gnome_mdi_get_app_from_view(node->data) != app)
+					break;
+				
+				node = node->next;
+			}
+
+			if(node == NULL) {   /* all the views reside in this GnomeApp */
+				ret = emit_boolean_pointer (mdi, REMOVE_CHILD, GTK_OBJECT (child), FALSE);
+				if(!ret)
+					return TRUE;
+			}
+		} while (view != NULL);
+
+		ret = FALSE;
+		/* now actually remove all children/views! */
+		page_no = 0;
+		view = gtk_notebook_get_nth_page(GTK_NOTEBOOK(app->contents), page_no);
+		while(view != NULL) {
+			child = gnome_mdi_get_child_from_view(view);
+			
+			view = gtk_notebook_get_nth_page(GTK_NOTEBOOK(app->contents),
+											 ++page_no);
+			
+			/* if this is the last view, remove the child */
+			if(g_list_length(child->priv->views) == 1)
+				remove_child(mdi, child);
+			else
+				if(!gnome_mdi_remove_view(mdi, view))
+					ret = TRUE;
+		}
+	}
+	
+	return ret;
+}
+
+static void
+app_destroy (GnomeApp *app, GnomeMDI *mdi)
+{
+	GnomeUIInfo *ui_info;
+	
+	if(mdi->priv->active_window == app) {
+		if(mdi->priv->windows != NULL)
+			mdi->priv->active_window = GNOME_APP(mdi->priv->windows->data);
+		else
+			mdi->priv->active_window = NULL;
+	}
+
+	/* free stuff that got allocated for this GnomeApp */
+	ui_info = gtk_object_get_data(GTK_OBJECT(app), GNOME_MDI_MENUBAR_INFO_KEY);
+	if(ui_info)
+		free_ui_info_tree(ui_info);
+	
+	ui_info = gtk_object_get_data(GTK_OBJECT(app), GNOME_MDI_TOOLBAR_INFO_KEY);
+	if(ui_info)
+		free_ui_info_tree(ui_info);
+	
+	ui_info = gtk_object_get_data(GTK_OBJECT(app), GNOME_MDI_CHILD_MENU_INFO_KEY);
+	if(ui_info)
+		free_ui_info_tree(ui_info);
+}
+
+static GtkWidget *
+app_create (GnomeMDI *mdi)
+{
+	GtkWidget *window;
+	GnomeApp *app;
+	GtkSignalFunc func = NULL;
+
+	window = gnome_app_new(mdi->priv->appname, mdi->priv->title);
+	app = GNOME_APP(window);
+
+	/* don't do automagical layout saving */
+	app->enable_layout_config = FALSE;
+
+	gtk_window_set_wmclass (GTK_WINDOW (app), mdi->priv->appname, mdi->priv->appname);
+  
+	gtk_window_set_policy(GTK_WINDOW(app), TRUE, TRUE, FALSE);
+  
+	mdi->priv->windows = g_list_append(mdi->priv->windows, window);
+
+	switch(mdi->priv->mode) {
+	case GNOME_MDI_TOPLEVEL:
+	case GNOME_MDI_MODAL:
+		func = GTK_SIGNAL_FUNC(app_toplevel_delete_event);
+		break;
+	case GNOME_MDI_NOTEBOOK:
+		func = GTK_SIGNAL_FUNC(app_book_delete_event);
+		break;
+	case GNOME_MDI_WIW:
+		func = GTK_SIGNAL_FUNC(app_wiw_delete_event);
+		break;
+	default:
+		break;
+	}
+	
+	gtk_signal_connect(GTK_OBJECT(window), "delete_event",
+					   func, mdi);
+	gtk_signal_connect(GTK_OBJECT(window), "focus_in_event",
+					   GTK_SIGNAL_FUNC(app_focus_in_event), mdi);
+	gtk_signal_connect(GTK_OBJECT(window), "destroy",
+					   GTK_SIGNAL_FUNC(app_destroy), mdi);
+
+	gtk_signal_emit(GTK_OBJECT(mdi), mdi_signals[APP_CREATED], window);
+
+	return window;
+}
+
+static void
+remove_view (GnomeMDI *mdi, GtkWidget *view)
+{
+	GtkWidget *parent;
+	GnomeApp *window;
+	GnomeMDIChild *child;
+
+	child = gnome_mdi_get_child_from_view(view);
+
+	parent = view->parent;
+
+	if(!parent)
+		return;
+
+	window = gnome_mdi_get_app_from_view(view);
+
+	if(mdi->priv->mode == GNOME_MDI_TOPLEVEL ||
+	   mdi->priv->mode == GNOME_MDI_MODAL) {
+		gtk_container_remove(GTK_CONTAINER(parent), view);
+		window->contents = NULL;
+
+		/* if this is NOT the last toplevel or a registered object exists,
+		   destroy the toplevel */
+		set_active_view(mdi, NULL);
+		if(g_list_length(mdi->priv->windows) > 1 || mdi->priv->registered) {
+			mdi->priv->windows = g_list_remove(mdi->priv->windows, window);
+			gtk_widget_destroy(GTK_WIDGET(window));
+		}
+	}
+	else if(mdi->priv->mode == GNOME_MDI_NOTEBOOK) {
+		gtk_container_remove(GTK_CONTAINER(parent), view);
+		if(GTK_NOTEBOOK(parent)->cur_page == NULL) {
+			set_active_view(mdi, NULL);
+			if(g_list_length(mdi->priv->windows) > 1 || mdi->priv->registered) {
+				/* if this is NOT the last toplevel or a registered object
+				   exists, destroy the toplevel */
+				mdi->priv->windows = g_list_remove(mdi->priv->windows, window);
+				gtk_widget_destroy(GTK_WIDGET(window));
+			}
+		}
+		else
+			set_active_view(mdi, gtk_notebook_get_nth_page(GTK_NOTEBOOK(parent), gtk_notebook_get_current_page(GTK_NOTEBOOK(parent))));
+	}
+	else if(mdi->priv->mode == GNOME_MDI_WIW) {
+		/* remove the roo from the pouch */
+		GtkFixed *fixed  = GTK_FIXED(parent->parent);
+		gtk_container_remove(GTK_CONTAINER(fixed), parent);
+		if(fixed->children == NULL) {
+			set_active_view(mdi, NULL);
+			if(g_list_length(mdi->priv->windows) > 1 || mdi->priv->registered) {
+				/* if this is NOT the last toplevel or a registered object
+				   exists, destroy the toplevel */
+				mdi->priv->windows = g_list_remove(mdi->priv->windows, window);
+				gtk_widget_destroy(GTK_WIDGET(window));
+			}
+		}
+	}
+
+	/* remove this view from the child's view list unless in MODAL mode */
+	if(mdi->priv->mode != GNOME_MDI_MODAL)
+		gnome_mdi_child_remove_view(child, view);
+}
+
+static void
+remove_child (GnomeMDI *mdi, GnomeMDIChild *child)
+{
+	GList *view_node;
+	GtkWidget *view;
+
+	view_node = child->priv->views;
+	while(view_node) {
+		view = GTK_WIDGET(view_node->data);
+		view_node = view_node->next;
+		remove_view(mdi, GTK_WIDGET(view));
+	}
+
+	mdi->priv->children = g_list_remove(mdi->priv->children, child);
+
+	gnome_mdi_child_list_remove(mdi, child);
+
+	if(child == mdi->priv->active_child)
+		mdi->priv->active_child = NULL;
+
+	child->priv->parent = NULL;
+
+	gtk_object_unref(GTK_OBJECT(child));
+
+	if(mdi->priv->mode == GNOME_MDI_MODAL && mdi->priv->children) {
+		GnomeMDIChild *next_child = mdi->priv->children->data;
+
+		if(next_child->priv->views) {
+			gnome_app_set_contents(mdi->priv->active_window,
+								   GTK_WIDGET(next_child->priv->views->data));
+			set_active_view(mdi, GTK_WIDGET(next_child->priv->views->data));
+		}
+		else
+			gnome_mdi_add_view(mdi, next_child);
+	}
+}
+
+static void
+top_add_view (GnomeMDI *mdi, GtkWidget *app, GnomeMDIChild *child, GtkWidget *view)
+{
+	if(child && view)
+		gnome_app_set_contents(GNOME_APP(app), view);
+
+	set_active_view(mdi, view);
+
+	if(!GTK_WIDGET_VISIBLE(app))
+		gtk_widget_show(app);
+}
+
+static void
+set_active_view (GnomeMDI *mdi, GtkWidget *view)
+{
+	GnomeMDIChild *old_child;
+	GtkWidget *old_view;
+
+#ifdef GNOME_ENABLE_DEBUG
+	g_message("setting active_view to %08lx\n", (gulong)view);
+#endif
+
+	old_child = mdi->priv->active_child;
+	old_view = mdi->priv->active_view;
+
+	if(!view) {
+		mdi->priv->active_child = NULL;
+		mdi->priv->active_view = NULL;
+	}
+
+	if(view == old_view)
+		return;
+
+	if(view) {
+		mdi->priv->active_child = gnome_mdi_get_child_from_view(view);
+		mdi->priv->active_window = gnome_mdi_get_app_from_view(view);
+	}
+
+	mdi->priv->active_view = view;
+
+	if(mdi->priv->active_child != old_child)
+		gtk_signal_emit(GTK_OBJECT(mdi), mdi_signals[CHILD_CHANGED],
+						old_child);
+
+	gtk_signal_emit(GTK_OBJECT(mdi), mdi_signals[VIEW_CHANGED], old_view);
+}
+
+/* the two functions below are supposed to be non-static but are not part
+   of the public API */
+GtkWidget *
+gnome_mdi_new_toplevel (GnomeMDI *mdi)
+{
+	GtkWidget *book, *pouch, *app;
+
+	if(mdi->priv->mode != GNOME_MDI_MODAL || mdi->priv->windows == NULL) {
+		app = app_clone(mdi, mdi->priv->active_window);
+
+		if(mdi->priv->mode == GNOME_MDI_NOTEBOOK) {
+			book = book_create(mdi);
+			gnome_app_set_contents(GNOME_APP(app), book);
+		}
+		else if(mdi->priv->mode == GNOME_MDI_WIW) {
+			pouch = pouch_create(mdi);
+			gnome_app_set_contents(GNOME_APP(app), pouch);
+		}
+
+		return app;
+	}
+
+	return GTK_WIDGET(mdi->priv->active_window);
+}
+
+void
+gnome_mdi_update_child (GnomeMDI *mdi, GnomeMDIChild *child)
+{
+	GtkWidget *view, *title;
+	GList *view_node;
+
+	g_return_if_fail(mdi != NULL);
+	g_return_if_fail(GNOME_IS_MDI(mdi));
+	g_return_if_fail(child != NULL);
+	g_return_if_fail(GNOME_IS_MDI_CHILD(child));
+
+	view_node = child->priv->views;
+	while(view_node) {
+		view = GTK_WIDGET(view_node->data);
+
+		/* for the time being all that update_child() does is update the
+		   children's names */
+		if(mdi->priv->mode == GNOME_MDI_MODAL ||
+		   mdi->priv->mode == GNOME_MDI_TOPLEVEL) {
+			/* in MODAL and TOPLEVEL modes the window title includes the active
+			   child name: "child_name - mdi_title" */
+			gchar *fullname;
+      
+			fullname = g_strconcat(child->priv->name, " - ", mdi->priv->title, NULL);
+			gtk_window_set_title(GTK_WINDOW(gnome_mdi_get_app_from_view(view)),
+								 fullname);
+			g_free(fullname);
+		}
+		else if(mdi->priv->mode == GNOME_MDI_NOTEBOOK) {
+			gint page_num;
+
+			page_num = gtk_notebook_page_num(GTK_NOTEBOOK(view->parent), view);
+			if(page_num >= 0) {
+				GtkWidget *old_label;
+
+				old_label = gtk_notebook_get_tab_label(GTK_NOTEBOOK(view->parent),
+													   view);
+				title = child_set_label(child, old_label);
+			}
+		}
+		else if(mdi->priv->mode == GNOME_MDI_WIW) {
+			gnome_roo_set_title(GNOME_ROO(view->parent), child->priv->name);
+		}
+
+		view_node = view_node->next;
+	}
+}
+
+/**
+ * gnome_mdi_construct:
+ * @mdi: A #GnomeMDI object to construct.
+ * @appname: Application name as used in filenames and paths.
+ * @title: Title of the application windows.
+ * 
+ * Description:
+ * Constructs a #GnomeMDI.
+ **/
+void
+gnome_mdi_construct(GnomeMDI *mdi, const gchar *appname, const gchar *title)
+{
+	g_return_if_fail(mdi != NULL);
+	g_return_if_fail(GNOME_IS_MDI(mdi));
+
+	mdi->priv->appname = g_strdup(appname);
+	mdi->priv->title = g_strdup(title);
+}
+
+/**
+ * gnome_mdi_new:
+ * @appname: Application name as used in filenames and paths.
+ * @title: Title of the application windows.
+ * 
+ * Description:
+ * Creates a new MDI object. @appname and @title are used for
+ * MDI's calling gnome_app_new(). 
+ * 
+ * Return value:
+ * A pointer to a new #GnomeMDI object.
+ **/
+GnomeMDI *
+gnome_mdi_new (const gchar *appname, const gchar *title)
+{
+	GnomeMDI *mdi;
+	
+	mdi = gtk_type_new (gnome_mdi_get_type ());
+  
+	gnome_mdi_construct(mdi, appname, title);
+
+	return mdi;
+}
+
+/**
+ * gnome_mdi_set_active_view:
+ * @mdi: A pointer to a #GnomeMDI object.
+ * @view: A pointer to the view that is to become the active one.
+ * 
+ * Description:
+ * Sets the active view to @view. It also raises the window containing it
+ * and gives it focus.
+ **/
+void
+gnome_mdi_set_active_view (GnomeMDI *mdi, GtkWidget *view)
+{
+	GtkWindow *window;
+	
+	g_return_if_fail(mdi != NULL);
+	g_return_if_fail(GNOME_IS_MDI(mdi));
+	g_return_if_fail(view != NULL);
+	g_return_if_fail(GTK_IS_WIDGET(view));
+
+#ifdef GNOME_ENABLE_DEBUG
+	g_message("GnomeMDI: setting active view");
+#endif
+
+	if(mdi->priv->mode == GNOME_MDI_NOTEBOOK)
+		set_page_by_widget(GTK_NOTEBOOK(view->parent), view);
+	else if(mdi->priv->mode == GNOME_MDI_WIW)
+		gnome_pouch_select_roo(GNOME_POUCH(view->parent->parent), GNOME_ROO(view->parent));
+	else if(mdi->priv->mode == GNOME_MDI_MODAL) {
+		if(mdi->priv->active_window->contents) {
+			remove_view(mdi, mdi->priv->active_window->contents);
+			mdi->priv->active_window->contents = NULL;
+		}
+		gnome_app_set_contents(mdi->priv->active_window, view);
+		set_active_view(mdi, view);
+	}
+
+	window = GTK_WINDOW(gnome_mdi_get_app_from_view(view));
+	
+	/* TODO: hmmm... I dont know how to give focus to the window, so that it
+	   would receive keyboard events */
+	gdk_window_raise(GTK_WIDGET(mdi->priv->active_window)->window);
+}
+
+/**
+ * gnome_mdi_add_view:
+ * @mdi: A pointer to a #GnomeMDI object.
+ * @child: A pointer to a child.
+ * 
+ * Description:
+ * Creates a new view of the child and adds it to the MDI. #GnomeMDIChild
+ * @child has to be added to the MDI with a call to gnome_mdi_add_child
+ * before its views are added to the MDI. 
+ * An "add_view" signal is emitted to the MDI after the view has been
+ * created, but before it is shown and added to the MDI, with a pointer to
+ * the created view as its parameter. The view is added to the MDI only if
+ * the signal handler (if it exists) returns %TRUE. If the handler returns
+ * %FALSE, the created view is destroyed and not added to the MDI. 
+ * 
+ * Return value:
+ * %TRUE if adding the view succeeded and %FALSE otherwise.
+ **/
+gint
+gnome_mdi_add_view (GnomeMDI *mdi, GnomeMDIChild *child)
+{
+	GtkWidget *view, *book, *pouch;
+	GtkWidget *app;
+	gint ret = TRUE;
+	
+	g_return_val_if_fail(mdi != NULL, FALSE);
+	g_return_val_if_fail(GNOME_IS_MDI(mdi), FALSE);
+	g_return_val_if_fail(child != NULL, FALSE);
+	g_return_val_if_fail(GNOME_IS_MDI_CHILD(child), FALSE);
+	
+	if(mdi->priv->mode != GNOME_MDI_MODAL || child->priv->views == NULL)
+		view = gnome_mdi_child_add_view(child);
+	else {
+		view = GTK_WIDGET(child->priv->views->data);
+
+		if(child == mdi->priv->active_child)
+			return TRUE;
+	}
+
+	ret = emit_boolean_pointer (mdi, ADD_VIEW, GTK_OBJECT (view), TRUE);
+
+	if(ret == FALSE) {
+		gnome_mdi_child_remove_view(child, view);
+		return FALSE;
+	}
+
+	if(mdi->priv->windows == NULL || mdi->priv->active_window == NULL) {
+		app = app_create(mdi);
+		gtk_widget_show(app);
+	}
+	else
+		app = GTK_WIDGET(mdi->priv->active_window);
+
+	/* this reference will compensate the view's unrefing
+	   when removed from its parent later, as we want it to
+	   stay valid until removed from the child with a call
+	   to gnome_mdi_child_remove_view() */
+	gtk_widget_ref(view);
+
+	if(!GTK_WIDGET_VISIBLE(view))
+		gtk_widget_show(view);
+
+	if(mdi->priv->mode == GNOME_MDI_NOTEBOOK) {
+		if(GNOME_APP(app)->contents == NULL) {
+			book = book_create(mdi);
+			gnome_app_set_contents(GNOME_APP(app), book);
+		}
+		book_add_view(GTK_NOTEBOOK(GNOME_APP(app)->contents), view);
+	}
+	else if(mdi->priv->mode == GNOME_MDI_WIW) {
+		if(GNOME_APP(app)->contents == NULL) {
+			pouch = pouch_create(mdi);
+			gnome_app_set_contents(GNOME_APP(app), pouch);
+		}
+		pouch_add_view(get_pouch_from_app(app), view);
+	}
+	else if(mdi->priv->mode == GNOME_MDI_TOPLEVEL) {
+		/* add a new toplevel unless the remaining one is empty */
+		if(app == NULL || GNOME_APP(app)->contents != NULL)
+			app = app_clone(mdi, GNOME_APP(app));
+		else
+			app = GTK_WIDGET(mdi->priv->active_window);
+		top_add_view(mdi, app, child, view);
+	}
+	else if(mdi->priv->mode == GNOME_MDI_MODAL) {
+		/* replace the existing view if there is one */
+		if(GNOME_APP(app)->contents) {
+			remove_view(mdi, GNOME_APP(app)->contents);
+			GNOME_APP(app)->contents = NULL;
+		}
+
+		gnome_app_set_contents(GNOME_APP(app), view);
+		set_active_view(mdi, view);
+	}
+
+	return TRUE;
+}
+
+/**
+ * gnome_mdi_add_toplevel_view:
+ * @mdi: A pointer to a #GnomeMDI object.
+ * @child: A pointer to a #GnomeMDIChild object to be added to the MDI.
+ * 
+ * Description:
+ * Creates a new view of the child and adds it to the MDI; it behaves the
+ * same way as gnome_mdi_add_view in %GNOME_MDI_MODAL and %GNOME_MDI_TOPLEVEL
+ * modes, but in %GNOME_MDI_NOTEBOOK or %GNOME_MDI_WIW mode, the view is added
+ * in a new toplevel window unless the active one has no views in it. 
+ * 
+ * Return value: 
+ * %TRUE if adding the view succeeded and %FALSE otherwise.
+ **/
+gint
+gnome_mdi_add_toplevel_view (GnomeMDI *mdi, GnomeMDIChild *child)
+{
+	GtkWidget *view, *app, *pouch;
+	gint ret = TRUE;
+	
+	g_return_val_if_fail(mdi != NULL, FALSE);
+	g_return_val_if_fail(GNOME_IS_MDI(mdi), FALSE);
+	g_return_val_if_fail(child != NULL, FALSE);
+	g_return_val_if_fail(GNOME_IS_MDI_CHILD(child), FALSE);
+
+	if(mdi->priv->mode != GNOME_MDI_MODAL || child->priv->views == NULL)
+		view = gnome_mdi_child_add_view(child);
+	else {
+		view = GTK_WIDGET(child->priv->views->data);
+
+		if(child == mdi->priv->active_child)
+			return TRUE;
+	}
+
+	if(!view)
+		return FALSE;
+
+	ret = emit_boolean_pointer (mdi, ADD_VIEW, GTK_OBJECT (view), TRUE);
+
+	if(ret == FALSE) {
+		gnome_mdi_child_remove_view(child, view);
+		return FALSE;
+	}
+
+	app = gnome_mdi_new_toplevel(mdi);
+
+	/* this reference will compensate the view's unrefing
+	   when removed from its parent later, as we want it to
+	   stay valid until removed from the child with a call
+	   to gnome_mdi_child_remove_view() */
+	gtk_widget_ref(view);
+
+	if(!GTK_WIDGET_VISIBLE(view))
+		gtk_widget_show(view);
+
+	if(mdi->priv->mode == GNOME_MDI_NOTEBOOK)
+		book_add_view(GTK_NOTEBOOK(GNOME_APP(app)->contents), view);
+	else if(mdi->priv->mode == GNOME_MDI_WIW) {
+		if(GNOME_APP(app)->contents == NULL) {
+			pouch = pouch_create(mdi);
+			gnome_app_set_contents(GNOME_APP(app), pouch);
+		}
+		pouch_add_view(get_pouch_from_app(app), view);
+	}
+	else if(mdi->priv->mode == GNOME_MDI_TOPLEVEL)
+		/* add a new toplevel unless the remaining one is empty */
+		top_add_view(mdi, app, child, view);
+	else if(mdi->priv->mode == GNOME_MDI_MODAL) {
+		/* replace the existing view if there is one */
+		if(GNOME_APP(app)->contents) {
+			remove_view(mdi, mdi->priv->active_window->contents);
+			GNOME_APP(app)->contents = NULL;
+		}
+
+		gnome_app_set_contents(GNOME_APP(app), view);
+		set_active_view(mdi, view);
+	}
+
+	if(!GTK_WIDGET_VISIBLE(app))
+		gtk_widget_show(app);
+	
+	return TRUE;
+}
+
+/**
+ * gnome_mdi_remove_view:
+ * @mdi: A pointer to a #GnomeMDI object.
+ * @view: View to remove.
+ * 
+ * Description:
+ * Removes a view from an MDI. 
+ * A "remove_view" signal is emitted to the MDI before actually removing
+ * view. The view is removed only if the signal handler (if it exists)
+ * returns %TRUE. 
+ * 
+ * Return value: 
+ * %TRUE if the view was removed and %FALSE otherwise.
+ **/
+gint
+gnome_mdi_remove_view (GnomeMDI *mdi, GtkWidget *view)
+{
+	gint ret = TRUE;
+	
+	g_return_val_if_fail(mdi != NULL, FALSE);
+	g_return_val_if_fail(GNOME_IS_MDI(mdi), FALSE);
+	g_return_val_if_fail(view != NULL, FALSE);
+	g_return_val_if_fail(GTK_IS_WIDGET(view), FALSE);
+
+	ret = emit_boolean_pointer (mdi, REMOVE_VIEW, GTK_OBJECT (view), TRUE);
+
+	if(ret == FALSE)
+		return FALSE;
+
+	remove_view(mdi, view);
+
+	return TRUE;
+}
+
+/**
+ * gnome_mdi_add_child:
+ * @mdi: A pointer to a #GnomeMDI object.
+ * @child: A pointer to a #GnomeMDIChild to add to the MDI.
+ * 
+ * Description:
+ * Adds a new child to the MDI. No views are added: this has to be done with
+ * a call to gnome_mdi_add_view. 
+ * First an "add_child" signal is emitted to the MDI with a pointer to the
+ * child as its parameter. The child is added to the MDI only if the signal
+ * handler (if it exists) returns %TRUE. If the handler returns %FALSE, the
+ * child is not added to the MDI. 
+ * 
+ * Return value: 
+ * %TRUE if the child was added successfully and %FALSE otherwise.
+ **/
+gint
+gnome_mdi_add_child (GnomeMDI *mdi, GnomeMDIChild *child)
+{
+	gint ret = TRUE;
+
+	g_return_val_if_fail(mdi != NULL, FALSE);
+	g_return_val_if_fail(GNOME_IS_MDI(mdi), FALSE);
+	g_return_val_if_fail(child != NULL, FALSE);
+	g_return_val_if_fail(GNOME_IS_MDI_CHILD(child), FALSE);
+
+	ret = emit_boolean_pointer (mdi, ADD_CHILD, GTK_OBJECT (child), TRUE);
+
+	if(ret == FALSE)
+		return FALSE;
+
+	child->priv->parent = GTK_OBJECT(mdi);
+
+	mdi->priv->children = g_list_append(mdi->priv->children, child);
+
+	gnome_mdi_child_list_add(mdi, child);
+
+	return TRUE;
+}
+
+/**
+ * gnome_mdi_remove_child:
+ * @mdi: A pointer to a #GnomeMDI object.
+ * @child: Child to remove.
+ * 
+ * Description:
+ * Removes a child and all of its views from the MDI. 
+ * A "remove_child" signal is emitted to the MDI with @child as its parameter
+ * before actually removing the child. The child is removed only if the signal
+ * handler (if it exists) returns %TRUE. 
+ * 
+ * Return value: 
+ * %TRUE if the removal was successful and %FALSE otherwise.
+ **/
+gint
+gnome_mdi_remove_child (GnomeMDI *mdi, GnomeMDIChild *child)
+{
+	gint ret = TRUE;
+
+	g_return_val_if_fail(mdi != NULL, FALSE);
+	g_return_val_if_fail(GNOME_IS_MDI(mdi), FALSE);
+	g_return_val_if_fail(child != NULL, FALSE);
+	g_return_val_if_fail(GNOME_IS_MDI_CHILD(child), FALSE);
+
+	ret = emit_boolean_pointer (mdi, REMOVE_CHILD, GTK_OBJECT (child), TRUE);
+
+	if(ret == FALSE)
+		return FALSE;
+
+	remove_child(mdi, child);
+
+	return TRUE;
+}
+
+/**
+ * gnome_mdi_remove_all:
+ * @mdi: A pointer to a #GnomeMDI object.
+ * 
+ * Description:
+ * Attempts to remove all children and all views from the MDI. 
+ * A "remove_child" signal is emitted to the MDI for each child before
+ * actually removing it. If signal handler for a child (if it exists)
+ * returns %TRUE, the child will be removed.
+ * 
+ * Return value:
+ * %TRUE if the removal was successful and %FALSE otherwise.
+ **/
+gint
+gnome_mdi_remove_all (GnomeMDI *mdi)
+{
+	GList *child_node;
+	GnomeMDIChild *child;
+	gint handler_ret = TRUE, ret = TRUE;
+	
+	g_return_val_if_fail(mdi != NULL, FALSE);
+	g_return_val_if_fail(GNOME_IS_MDI(mdi), FALSE);
+
+	child_node = mdi->priv->children;
+	while(child_node) {
+		handler_ret = emit_boolean_pointer
+			(mdi, REMOVE_CHILD,
+			 GTK_OBJECT (child_node->data), TRUE);
+		child = GNOME_MDI_CHILD(child_node->data);
+		child_node = child_node->next;
+		if(handler_ret)
+			remove_child(mdi, child);
+		else
+			ret = FALSE;
+	}
+
+	return ret;
+}
+
+/**
+ * gnome_mdi_open_toplevel:
+ * @mdi: A pointer to a #GnomeMDI object.
+ * 
+ * Description:
+ * Opens a new toplevel window (unless in %GNOME_MDI_MODAL mode and a
+ * toplevel window is already open). This is usually used only for opening
+ * the initial window on startup (just before calling gtk_main()) if no
+ * windows were open because a session was restored or children were added
+ * because of command line args).
+ **/
+void
+gnome_mdi_open_toplevel (GnomeMDI *mdi)
+{
+	GtkWidget *toplevel;
+
+	g_return_if_fail(mdi != NULL);
+	g_return_if_fail(GNOME_IS_MDI(mdi));
+
+	if((toplevel = gnome_mdi_new_toplevel(mdi)) != NULL)
+		
+	if(!GTK_WIDGET_VISIBLE(toplevel))
+		gtk_widget_show(toplevel);
+}
+
+/**
+ * gnome_mdi_find_child:
+ * @mdi: A pointer to a #GnomeMDI object.
+ * @name: A string with a name of the child to find.
+ * 
+ * Description:
+ * Finds a child named @name.
+ * 
+ * Return value: 
+ * A pointer to the #GnomeMDIChild object if the child was found and NULL
+ * otherwise.
+ **/
+GnomeMDIChild *
+gnome_mdi_find_child (GnomeMDI *mdi, const gchar *name)
+{
+	GList *child_node;
+
+	g_return_val_if_fail(mdi != NULL, NULL);
+	g_return_val_if_fail(GNOME_IS_MDI(mdi), NULL);
+
+	child_node = mdi->priv->children;
+	while(child_node) {
+		if(!strcmp(GNOME_MDI_CHILD(child_node->data)->priv->name, name))
+			return GNOME_MDI_CHILD(child_node->data);
+
+		child_node = g_list_next(child_node);
+	}
+
+	return NULL;
+}
+
+/**
+ * gnome_mdi_get_children:
+ * @mdi: A pointer to a #GnomeMDI object.
+ *
+ * Description:
+ * Returns a list of all children handled by the MDI @mdi.
+ * 
+ * Return value: 
+ * A pointer to a GList of all children handled by the MDI @mdi
+ **/
+const GList *
+gnome_mdi_get_children (GnomeMDI *mdi)
+{
+	return mdi->priv->children;
+}
+
+/**
+ * gnome_mdi_get_windows:
+ * @mdi: A pointer to a #GnomeMDI object.
+ *
+ * Description:
+ * Returns a list of all toplevel windows opened by the MDI @mdi.
+ * 
+ * Return value: 
+ * A pointer to a GList of all toplevel windows opened by the MDI @mdi
+ **/
+const GList *
+gnome_mdi_get_windows (GnomeMDI *mdi)
+{
+	return mdi->priv->windows;
+}
+
+/**
+ * gnome_mdi_set_mode:
+ * @mdi: A pointer to a GnomeMDI object.
+ * @mode: New mode.
+ *
+ * Description:
+ * Sets the MDI mode to mode. Possible values are %GNOME_MDI_TOPLEVEL,
+ * %GNOME_MDI_NOTEBOOK, %GNOME_MDI_MODAL and %GNOME_MDI_DEFAULT.
+ **/
+void
+gnome_mdi_set_mode (GnomeMDI *mdi, GnomeMDIMode mode)
+{
+	GtkWidget *view, *book, *pouch;
+	GnomeMDIChild *child;
+	GList *child_node, *view_node, *app_node;
+	gint windows = (mdi->priv->windows != NULL);
+	guint16 width = 0, height = 0;
+
+	/* FIXME: implement switching to WiW mode */
+
+	g_return_if_fail(mdi != NULL);
+	g_return_if_fail(GNOME_IS_MDI(mdi));
+
+	if(mode == GNOME_MDI_DEFAULT_MODE)
+		mode = gnome_preferences_get_mdi_mode();
+
+	if(mdi->priv->active_view) {
+		width = mdi->priv->active_view->allocation.width;
+		height = mdi->priv->active_view->allocation.height;
+	}
+
+	/* remove all views from their parents */
+	child_node = mdi->priv->children;
+	while(child_node) {
+		child = GNOME_MDI_CHILD(child_node->data);
+		view_node = child->priv->views;
+		while(view_node) {
+			view = GTK_WIDGET(view_node->data);
+
+			if(view->parent)
+				gtk_container_remove(GTK_CONTAINER(view->parent), view);
+
+			view_node = view_node->next;
+		}
+		child_node = child_node->next;
+	}
+
+	/* remove all GnomeApps but the active one */
+	app_node = mdi->priv->windows;
+	while(app_node) {
+		if(GNOME_APP(app_node->data) != mdi->priv->active_window)
+			gtk_widget_destroy(GTK_WIDGET(app_node->data));
+		app_node = app_node->next;
+	}
+
+	if(mdi->priv->windows)
+		g_list_free(mdi->priv->windows);
+
+	if(mdi->priv->active_window) {
+		if(mdi->priv->mode == GNOME_MDI_NOTEBOOK ||
+		   mdi->priv->mode == GNOME_MDI_WIW)
+			gtk_container_remove(GTK_CONTAINER(mdi->priv->active_window->dock),
+								 GNOME_DOCK(mdi->priv->active_window->dock)->client_area);
+
+		mdi->priv->active_window->contents = NULL;
+
+		if( (mdi->priv->mode == GNOME_MDI_TOPLEVEL) || (mdi->priv->mode == GNOME_MDI_MODAL))
+			gtk_signal_disconnect_by_func(GTK_OBJECT(mdi->priv->active_window),
+										  GTK_SIGNAL_FUNC(app_toplevel_delete_event), mdi);
+		else if(mdi->priv->mode == GNOME_MDI_NOTEBOOK)
+			gtk_signal_disconnect_by_func(GTK_OBJECT(mdi->priv->active_window),
+										  GTK_SIGNAL_FUNC(app_book_delete_event), mdi);
+		else if(mdi->priv->mode == GNOME_MDI_WIW)
+			gtk_signal_disconnect_by_func(GTK_OBJECT(mdi->priv->active_window),
+										  GTK_SIGNAL_FUNC(app_wiw_delete_event), mdi);
+
+		if( (mode == GNOME_MDI_TOPLEVEL) || (mode == GNOME_MDI_MODAL))
+			gtk_signal_connect(GTK_OBJECT(mdi->priv->active_window), "delete_event",
+							   GTK_SIGNAL_FUNC(app_toplevel_delete_event), mdi);
+		else if(mode == GNOME_MDI_NOTEBOOK)
+			gtk_signal_connect(GTK_OBJECT(mdi->priv->active_window), "delete_event",
+							   GTK_SIGNAL_FUNC(app_book_delete_event), mdi);
+		else if(mode == GNOME_MDI_WIW)
+			gtk_signal_connect(GTK_OBJECT(mdi->priv->active_window), "delete_event",
+							   GTK_SIGNAL_FUNC(app_wiw_delete_event), mdi);
+		
+		mdi->priv->windows = g_list_append(NULL, mdi->priv->active_window);
+
+		if(mode == GNOME_MDI_NOTEBOOK) {
+			book = book_create(mdi);
+			gnome_app_set_contents(mdi->priv->active_window, book);
+		}
+		else if(mode == GNOME_MDI_WIW) {
+			pouch = pouch_create(mdi);
+			gnome_app_set_contents(mdi->priv->active_window, pouch);
+		}
+	}
+
+	mdi->priv->mode = mode;
+
+	/* re-implant views in proper containers */
+	child_node = mdi->priv->children;
+	while(child_node) {
+		child = GNOME_MDI_CHILD(child_node->data);
+		view_node = child->priv->views;
+		while(view_node) {
+			view = GTK_WIDGET(view_node->data);
+
+			if(width != 0)
+				gtk_widget_set_usize(view, width, height);
+
+			if(mdi->priv->mode == GNOME_MDI_NOTEBOOK)
+				book_add_view(GTK_NOTEBOOK(mdi->priv->active_window->contents), view);
+			else if(mdi->priv->mode == GNOME_MDI_WIW)
+				pouch_add_view(get_pouch_from_app(mdi->priv->active_window), view);
+			else if(mdi->priv->mode == GNOME_MDI_TOPLEVEL) {
+				/* add a new toplevel unless the remaining one is empty */
+				if(mdi->priv->active_window->contents != NULL)
+					mdi->priv->active_window = GNOME_APP(app_clone(mdi, mdi->priv->active_window));
+				top_add_view(mdi, GTK_WIDGET(mdi->priv->active_window), child, view);
+			}
+			else if(mdi->priv->mode == GNOME_MDI_MODAL) {
+				/* replace the existing view if there is one */
+				if(mdi->priv->active_window->contents == NULL) {
+					gnome_app_set_contents(mdi->priv->active_window, view);
+					set_active_view(mdi, view);
+				}
+			}
+
+			view_node = view_node->next;
+
+			gtk_widget_show(GTK_WIDGET(mdi->priv->active_window));
+		}
+		child_node = child_node->next;
+	}
+
+	if(windows && !mdi->priv->active_window)
+		gnome_mdi_open_toplevel(mdi);
+}
+
+/**
+ * gnome_mdi_get_active_child:
+ * @mdi: A pointer to a #GnomeMDI object.
+ * 
+ * Description:
+ * Returns a pointer to the active #GnomeMDIChild object.
+ * 
+ * Return value: 
+ * A pointer to the active #GnomeMDIChild object. %NULL, if there is none.
+ **/
+GnomeMDIChild *
+gnome_mdi_get_active_child (GnomeMDI *mdi)
+{
+	g_return_val_if_fail(mdi != NULL, NULL);
+	g_return_val_if_fail(GNOME_IS_MDI(mdi), NULL);
+
+	if(mdi->priv->active_view)
+		return(gnome_mdi_get_child_from_view(mdi->priv->active_view));
+
+	return NULL;
+}
+
+/**
+ * gnome_mdi_get_active_view:
+ * @mdi: A pointer to a #GnomeMDI object.
+ * 
+ * Description:
+ * Returns a pointer to the active view (the one with the focus).
+ * 
+ * Return value: 
+ * A pointer to a #GtkWidget.
+ **/
+GtkWidget *
+gnome_mdi_get_active_view (GnomeMDI *mdi)
+{
+	g_return_val_if_fail(mdi != NULL, NULL);
+	g_return_val_if_fail(GNOME_IS_MDI(mdi), NULL);
+
+	return mdi->priv->active_view;
+}
+
+/**
+ * gnome_mdi_get_active_window:
+ * @mdi: A pointer to a #GnomeMDI object.
+ * 
+ * Description:
+ * Returns a pointer to the toplevel window containing the active view.
+ * 
+ * Return value:
+ * A pointer to a #GnomeApp that has the focus.
+ **/
+GnomeApp *
+gnome_mdi_get_active_window (GnomeMDI *mdi)
+{
+	g_return_val_if_fail(mdi != NULL, NULL);
+	g_return_val_if_fail(GNOME_IS_MDI(mdi), NULL);
+
+	return mdi->priv->active_window;
+}
+
+/**
+ * gnome_mdi_set_menubar_template:
+ * @mdi: A pointer to a #GnomeMDI object.
+ * @menu_tmpl: A #GnomeUIInfo array describing the menu.
+ * 
+ * Description:
+ * This function sets the template for menus that appear in each toplevel
+ * window to menu_template. For each new toplevel window created by the MDI,
+ * this structure is copied, the menus are created with
+ * #gnome_app_create_menus_with_data() function with mdi as the callback
+ * user data. Finally, the pointer to the copy is assigned to the new
+ * toplevel window (a #GnomeApp widget) and can be obtained by calling
+ * #gnome_mdi_get_menubar_info.
+ **/
+void
+gnome_mdi_set_menubar_template (GnomeMDI *mdi, GnomeUIInfo *menu_tmpl)
+{
+	g_return_if_fail(mdi != NULL);
+	g_return_if_fail(GNOME_IS_MDI(mdi));
+
+	mdi->priv->menu_template = menu_tmpl;
+}
+
+/**
+ * gnome_mdi_set_toolbar_template:
+ * @mdi: A pointer to a #GnomeMDI object.
+ * @tbar_tmpl: A #GnomeUIInfo array describing the toolbar.
+ * 
+ * Description:
+ * This function sets the template for toolbar that appears in each toplevel
+ * window to toolbar_template. For each new toplevel window created by the MDI,
+ * this structure is copied, the toolbar is created with
+ * #gnome_app_create_toolbar_with_data( function with mdi as the callback
+ * user data. Finally, the pointer to the copy is assigned to the new toplevel
+ * window (a #GnomeApp widget) and can be retrieved with a call to
+ * #gnome_mdi_get_toolbar_info. 
+ **/
+void
+gnome_mdi_set_toolbar_template (GnomeMDI *mdi, GnomeUIInfo *tbar_tmpl)
+{
+	g_return_if_fail(mdi != NULL);
+	g_return_if_fail(GNOME_IS_MDI(mdi));
+
+	mdi->priv->toolbar_template = tbar_tmpl;
+}
+
+/**
+ * gnome_mdi_set_child_menu_path:
+ * @mdi: A pointer to a #GnomeMDI object. 
+ * @path: A menu path where the child menus should be inserted.
+ * 
+ * Description:
+ * Sets the desired position of child-specific menus (which are added to and
+ * removed from the main menus as views of different children are activated).
+ * See #gnome_app_find_menu_pos for details on menu paths. 
+ **/
+void
+gnome_mdi_set_child_menu_path (GnomeMDI *mdi, const gchar *path)
+{
+	g_return_if_fail(mdi != NULL);
+	g_return_if_fail(GNOME_IS_MDI(mdi));
+
+	if(mdi->priv->child_menu_path)
+		g_free(mdi->priv->child_menu_path);
+
+	mdi->priv->child_menu_path = g_strdup(path);
+}
+
+/**
+ * gnome_mdi_set_child_list_path:
+ * @mdi: A pointer to a #GnomeMDI object.
+ * @path: A menu path where the child list menu should be inserted
+ * 
+ * Description:
+ * Sets the position for insertion of menu items used to activate the MDI
+ * children that were added to the MDI. See #gnome_app_find_menu_pos() for
+ * details on menu paths. If the path is not set or set to %NULL, these menu
+ * items aren't going to be inserted in the MDI menu structure. Note that if
+ * you want all menu items to be inserted in their own submenu, you have to
+ * create that submenu (and leave it empty, of course).
+ **/
+void
+gnome_mdi_set_child_list_path (GnomeMDI *mdi, const gchar *path)
+{
+	g_return_if_fail(mdi != NULL);
+	g_return_if_fail(GNOME_IS_MDI(mdi));
+
+	if(mdi->priv->child_list_path)
+		g_free(mdi->priv->child_list_path);
+
+	mdi->priv->child_list_path = g_strdup(path);
+}
+
+/**
+ * gnome_mdi_register:
+ * @mdi: A pointer to a #GnomeMDI object.
+ * @object: Object to register.
+ * 
+ * Description:
+ * Registers #GtkObject @object with MDI. 
+ * This is mostly intended for applications that open other windows besides
+ * those opened by the MDI and want to continue to run even when no MDI
+ * windows exist (an example of this would be GIMP's window with tools, if
+ * the pictures were MDI children). As long as there is an object registered
+ * with the MDI, the MDI will not destroy itself when the last of its windows
+ * is closed. If no objects are registered, closing the last MDI window
+ * results in MDI being destroyed. 
+ **/
+void
+gnome_mdi_register (GnomeMDI *mdi, GtkObject *object)
+{
+	g_return_if_fail(mdi != NULL);
+	g_return_if_fail(GNOME_IS_MDI(mdi));
+	g_return_if_fail(object != NULL);
+	g_return_if_fail(GTK_IS_OBJECT(object));
+
+	if(!g_slist_find(mdi->priv->registered, object))
+		mdi->priv->registered = g_slist_append(mdi->priv->registered, object);
+}
+
+/**
+ * gnome_mdi_unregister:
+ * @mdi: A pointer to a #GnomeMDI object.
+ * @object: Object to unregister.
+ * 
+ * Description:
+ * Removes #GtkObject @object from the list of registered objects. 
+ **/
+void
+gnome_mdi_unregister (GnomeMDI *mdi, GtkObject *object)
+{
+	g_return_if_fail(mdi != NULL);
+	g_return_if_fail(GNOME_IS_MDI(mdi));
+	g_return_if_fail(object != NULL);
+	g_return_if_fail(GTK_IS_OBJECT(object));
+
+	mdi->priv->registered = g_slist_remove(mdi->priv->registered, object);
+}
+
+/**
+ * gnome_mdi_get_child_from_view:
+ * @view: A pointer to a #GtkWidget.
+ * 
+ * Description:
+ * Returns a child that @view is a view of.
+ * 
+ * Return value:
+ * A pointer to the #GnomeMDIChild the view belongs to.
+ **/
+GnomeMDIChild *
+gnome_mdi_get_child_from_view (GtkWidget *view)
+{
+	gpointer child;
+
+	g_return_val_if_fail(view != NULL, NULL);
+	g_return_val_if_fail(GTK_IS_WIDGET(view), NULL);
+
+	if((child = gtk_object_get_data(GTK_OBJECT(view), GNOME_MDI_CHILD_KEY)) != NULL)
+		return GNOME_MDI_CHILD(child);
+
+	return NULL;
+}
+
+/**
+ * gnome_mdi_get_app_from_view:
+ * @view: A pointer to a #GtkWidget.
+ * 
+ * Description:
+ * Returns the toplevel window for this view.
+ * 
+ * Return value:
+ * A pointer to the #GnomeApp containg the specified view.
+ **/
+GnomeApp *
+gnome_mdi_get_app_from_view (GtkWidget *view)
+{
+	GtkWidget *app;
+
+	g_return_val_if_fail(view != NULL, NULL);
+	g_return_val_if_fail(GTK_IS_WIDGET(view), NULL);
+
+	app = gtk_widget_get_toplevel(view);
+	if(app)
+		return GNOME_APP(app);
+
+	return NULL;
+}
+
+/**
+ * gnome_mdi_get_view_from_window:
+ * @mdi: A pointer to a #GnomeMDI object.
+ * @app: A pointer to a #GnomeApp widget.
+ * 
+ * Description:
+ * Returns the pointer to the view in the MDI toplevel window @app.
+ * If the mode is set to %GNOME_MDI_NOTEBOOK or %GNOME_MDI_WIW, the
+ * currently selected view is returned.
+ * 
+ * Return value: 
+ * A pointer to a view.
+ **/
+GtkWidget *
+gnome_mdi_get_view_from_window (GnomeMDI *mdi, GnomeApp *app)
+{
+	g_return_val_if_fail(mdi != NULL, NULL);
+	g_return_val_if_fail(GNOME_IS_MDI(mdi), NULL);
+	g_return_val_if_fail(app != NULL, NULL);
+	g_return_val_if_fail(GNOME_IS_APP(app), NULL);
+
+	if((mdi->priv->mode == GNOME_MDI_TOPLEVEL) ||
+	   (mdi->priv->mode == GNOME_MDI_MODAL))
+		return app->contents;
+	else if(mdi->priv->mode == GNOME_MDI_NOTEBOOK) {
+		gint cur_page_no = gtk_notebook_get_current_page(GTK_NOTEBOOK(app->contents));
+		if (cur_page_no >= 0)
+			return gtk_notebook_get_nth_page(GTK_NOTEBOOK(app->contents), cur_page_no);
+		else
+			return NULL;
+	}
+	else if(mdi->priv->mode == GNOME_MDI_WIW)
+		return GTK_WIDGET(gnome_pouch_get_selected(get_pouch_from_app(app)));
+	else
+		return NULL;
+}
+
+/**
+ * gnome_mdi_get_menubar_info:
+ * @app: A pointer to a #GnomeApp widget created by the MDI.
+ * 
+ * Return value: 
+ * A #GnomeUIInfo array used for menubar in @app if the menubar has been created with a template.
+ * %NULL otherwise.
+ **/
+const GnomeUIInfo *
+gnome_mdi_get_menubar_info (GnomeApp *app)
+{
+	g_return_val_if_fail(app != NULL, NULL);
+	g_return_val_if_fail(GNOME_IS_APP(app), NULL);
+
+	return gtk_object_get_data(GTK_OBJECT(app), GNOME_MDI_MENUBAR_INFO_KEY);
+}
+
+/**
+ * gnome_mdi_get_toolbar_info:
+ * @app: A pointer to a #GnomeApp widget created by the MDI.
+ * 
+ * Return value: 
+ * A #GnomeUIInfo array used for toolbar in @app if the toolbar has been created with a template.
+ * %NULL otherwise.
+ **/
+const GnomeUIInfo *
+gnome_mdi_get_toolbar_info (GnomeApp *app)
+{
+	g_return_val_if_fail(app != NULL, NULL);
+	g_return_val_if_fail(GNOME_IS_APP(app), NULL);
+
+	return gtk_object_get_data(GTK_OBJECT(app), GNOME_MDI_TOOLBAR_INFO_KEY);
+}
+
+/**
+ * gnome_mdi_get_child_menu_info:
+ * @app: A pointer to a #GnomeApp widget created by the MDI.
+ * 
+ * Return value: 
+ * A #GnomeUIInfo array used for child's menus in @app if they have been created with a template.
+ * %NULL otherwise.
+ **/
+const GnomeUIInfo *
+gnome_mdi_get_child_menu_info (GnomeApp *app)
+{
+	g_return_val_if_fail(app != NULL, NULL);
+	g_return_val_if_fail(GNOME_IS_APP(app), NULL);
+
+	return gtk_object_get_data(GTK_OBJECT(app), GNOME_MDI_CHILD_MENU_INFO_KEY);
+}
+
+/**
+ * gnome_mdi_get_child_toolbar_info:
+ * @app: A pointer to a #GnomeApp widget created by the MDI.
+ * 
+ * Return value: 
+ * A #GnomeUIInfo array used for child's toolbar in @app if it has been created
+ * with a template. %NULL otherwise.
+ **/
+const GnomeUIInfo *
+gnome_mdi_get_child_toolbar_info(GnomeApp *app)
+{
+	g_return_val_if_fail(app != NULL, NULL);
+	g_return_val_if_fail(GNOME_IS_APP(app), NULL);
+
+	return gtk_object_get_data(GTK_OBJECT(app), GNOME_MDI_CHILD_TOOLBAR_INFO_KEY);
+}
+
+/**
+ * gnome_mdi_get_view_menu_info:
+ * @view: A pointer to a widget that is a view of an MDI child.
+ * 
+ * Return value: 
+ * A #GnomeUIInfo array used for @view's menus if they have been created with a
+ * template. %NULL otherwise.
+ **/
+const GnomeUIInfo *
+gnome_mdi_get_view_menu_info(GtkWidget *view)
+{
+	g_return_val_if_fail(view != NULL, NULL);
+	g_return_val_if_fail(GTK_IS_WIDGET(view), NULL);
+
+	return gtk_object_get_data(GTK_OBJECT(view), GNOME_MDI_CHILD_MENU_INFO_KEY);
+}
+
+/**
+ * gnome_mdi_get_view_toolbar_info:
+ * @view: A pointer to a widget that is a view of an MDI child.
+ * 
+ * Return value: 
+ * A #GnomeUIInfo array used for @view's toolbar if it has been created with a
+ * template. %NULL otherwise.
+ **/
+const GnomeUIInfo *
+gnome_mdi_get_view_toolbar_info(GtkWidget *view)
+{
+	g_return_val_if_fail(view != NULL, NULL);
+	g_return_val_if_fail(GTK_IS_WIDGET(view), NULL);
+
+	return gtk_object_get_data(GTK_OBJECT(view), GNOME_MDI_CHILD_TOOLBAR_INFO_KEY);
+}
diff --git a/libgnomeui/gnome-mdi.h b/libgnomeui/gnome-mdi.h
new file mode 100644
index 0000000..123b3bd
--- /dev/null
+++ b/libgnomeui/gnome-mdi.h
@@ -0,0 +1,193 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* gnome-mdi.h - definition of a Gnome MDI object
+
+   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+   All rights reserved.
+
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Jaka Mocnik <jaka mocnik kiss uni-lj si>
+*/
+/*
+  @NOTATION@
+*/
+
+#ifndef __GNOME_MDI_H__
+#define __GNOME_MDI_H__
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include "gnome-app.h"
+#include "gnome-mdi-child.h"
+
+G_BEGIN_DECLS
+
+#define GNOME_TYPE_MDI            (gnome_mdi_get_type ())
+#define GNOME_MDI(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_MDI, GnomeMDI))
+#define GNOME_MDI_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_MDI, GnomeMDIClass))
+#define GNOME_IS_MDI(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_MDI))
+#define GNOME_IS_MDI_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_MDI))
+#define GNOME_MDI_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_MDI, GnomeMDIClass))
+
+typedef struct _GnomeMDI        GnomeMDI;
+typedef struct _GnomeMDIClass   GnomeMDIClass;
+
+typedef struct _GnomeMDIPrivate GnomeMDIPrivate;
+
+typedef enum {
+	/* update struct when adding enums */
+	GNOME_MDI_NOTEBOOK,
+	GNOME_MDI_TOPLEVEL,
+	GNOME_MDI_MODAL,
+	GNOME_MDI_WIW,
+	GNOME_MDI_DEFAULT_MODE
+} GnomeMDIMode;
+
+/* all of the GnomeMDI members are considered private and should
+   only be accessed using the provided public API */
+struct _GnomeMDI {
+	GtkObject object;
+
+	GnomeMDIPrivate *priv;
+};
+
+struct _GnomeMDIClass {
+	GtkObjectClass parent_class;
+
+	gint        (*add_child)     (GnomeMDI *mdi, GnomeMDIChild *child);
+	gint        (*remove_child)  (GnomeMDI *mdi, GnomeMDIChild *child);
+	gint        (*add_view)      (GnomeMDI *mdi, GtkWidget *view);
+	gint        (*remove_view)   (GnomeMDI *mdi, GtkWidget *view);
+	void        (*child_changed) (GnomeMDI *mdi, GnomeMDIChild *app);
+	void        (*view_changed)  (GnomeMDI *mdi, GtkWidget *old_view);
+	void        (*app_created)   (GnomeMDI *mdi, GnomeApp *app);
+};
+
+/*
+ * description of GnomeMDI signals:
+ *
+ * gint add_child(GnomeMDI *, GnomeMDIChild *)
+ * gint add_view(GnomeMDI *, GtkWidget *)
+ *   are called before actually adding a mdi_child or a view to the MDI. if the
+ *   handler returns TRUE, the action proceeds otherwise the child or the view
+ *   are not added and are destroyed.
+ *
+ * gint remove_child(GnomeMDI *, GnomeMDIChild *)
+ * gint remove_view(GnomeMDI *, GtkWidget *)
+ *   are called before removing a child or a view. the handler should return
+ *   true if the object is to be removed from MDI
+ *
+ * void child_changed(GnomeMDI *, GnomeMDIChild *)
+ *   gets called each time when active child is changed with the second
+ *   argument pointing to the old child. mdi->active_view and
+ *   mdi->active_child still already hold the new values
+ *
+ * void view_changed(GnomeMDI *, GtkWidget *)
+ *   is emitted whenever a view is changed, regardless of it being the view of
+ *   the same child as the old view or not. the second argument points to the
+ *   old view, mdi->active_view and mdi->active_child hold the new values.
+ *   if the child has also been changed, this signal is emitted after the
+ *   child_changed signal.
+ * 
+ * void app_created(GnomeMDI *, GnomeApp *)
+ *   is called with each newly created GnomeApp to allow the MDI user to
+ *   customize it (add a statusbar, toolbars or menubar if the method with
+ *   GnomeUIInfo templates is not sufficient, etc.).
+ *   no contents may be set since GnomeMDI uses them for purposes of its own!
+ */
+
+GtkType        gnome_mdi_get_type            (void) G_GNUC_CONST;
+
+GnomeMDI      *gnome_mdi_new                 (const gchar *appname, const gchar *title);
+void           gnome_mdi_construct           (GnomeMDI *mdi, const gchar *appname, const gchar *title);
+
+/* setting the mdi mode */
+void           gnome_mdi_set_mode            (GnomeMDI *mdi, GnomeMDIMode mode);
+
+/* setting the menu paths */
+void           gnome_mdi_set_child_menu_path (GnomeMDI *mdi, const gchar *path);
+void           gnome_mdi_set_child_list_path (GnomeMDI *mdi, const gchar *path);
+
+/* manipulating views */
+gint           gnome_mdi_add_view            (GnomeMDI *mdi, GnomeMDIChild *child);
+gint           gnome_mdi_add_toplevel_view   (GnomeMDI *mdi, GnomeMDIChild *child);
+gint           gnome_mdi_remove_view         (GnomeMDI *mdi, GtkWidget *view);
+GtkWidget     *gnome_mdi_get_active_view     (GnomeMDI *mdi);
+void           gnome_mdi_set_active_view     (GnomeMDI *mdi, GtkWidget *view);
+
+/* manipulating children */
+gint           gnome_mdi_add_child           (GnomeMDI *mdi, GnomeMDIChild *child);
+gint           gnome_mdi_remove_child        (GnomeMDI *mdi, GnomeMDIChild *child);
+gint           gnome_mdi_remove_all          (GnomeMDI *mdi);
+GnomeMDIChild *gnome_mdi_get_active_child    (GnomeMDI *mdi);
+GnomeMDIChild *gnome_mdi_find_child          (GnomeMDI *mdi, const gchar *name);
+const GList   *gnome_mdi_get_children        (GnomeMDI *mdi);
+const GList   *gnome_mdi_get_windows         (GnomeMDI *mdi);
+
+/* manipulating windows */
+void           gnome_mdi_open_toplevel       (GnomeMDI *mdi);
+GnomeApp      *gnome_mdi_get_active_window   (GnomeMDI *mdi);
+
+/*
+ * the following two functions are here to make life easier if an application
+ * creates objects (like opening a window) that should "keep the application
+ * alive" even if there are no MDI windows open. any such windows should be
+ * registered with the MDI: as long as there is a window registered, the MDI
+ * will not destroy itself (even if the last of its windows is closed). on the
+ * other hand, closing the last MDI window when no objects are registered
+ * with the MDI will result in MDI being gtk_object_destroy()ed.
+ */
+void          gnome_mdi_register             (GnomeMDI *mdi, GtkObject *object);
+void          gnome_mdi_unregister           (GnomeMDI *mdi, GtkObject *object);
+
+/*
+ * convenience functions for retrieveing GnomeMDIChild and GnomeApp
+ * objects associated with a particular view and for retrieveing the
+ * visible view of a certain GnomeApp.
+ */
+GnomeApp      *gnome_mdi_get_app_from_view   (GtkWidget *view);
+GnomeMDIChild *gnome_mdi_get_child_from_view (GtkWidget *view);
+GtkWidget     *gnome_mdi_get_view_from_window(GnomeMDI *mdi, GnomeApp *app);
+
+/* the following API is used for easy creation of menus and toolbars
+   via GnomeUIInfo structures */
+
+/* setting the GnomeUIInfo templates for menu and toolbar */
+void           gnome_mdi_set_menubar_template   (GnomeMDI *mdi, GnomeUIInfo *menu_tmpl);
+void           gnome_mdi_set_toolbar_template   (GnomeMDI *mdi, GnomeUIInfo *tbar_tmpl);
+
+/* the following functions are used to obtain pointers to the GnomeUIInfo
+ * structures for a specified MDI GnomeApp widget. this might be useful for
+ * enabling/disabling menu items (via ui_info[i]->widget) when certain events
+ * happen or selecting the default menuitem in a radio item group. these
+ * GnomeUIInfo structures are exact copies of the template GnomeUIInfo trees
+ * and are non-NULL only if templates are used for menu/toolbar creation.
+ */
+const GnomeUIInfo *gnome_mdi_get_menubar_info      (GnomeApp *app);
+const GnomeUIInfo *gnome_mdi_get_toolbar_info      (GnomeApp *app);
+const GnomeUIInfo *gnome_mdi_get_child_menu_info   (GnomeApp *app);
+const GnomeUIInfo *gnome_mdi_get_child_toolbar_info(GnomeApp *app);
+
+/* extracting the child menu/toolbar GnomeUIInfos (when they are set)
+ * via a pointer to a view.
+ */
+const GnomeUIInfo *gnome_mdi_get_view_menu_info    (GtkWidget *view);
+const GnomeUIInfo *gnome_mdi_get_view_toolbar_info (GtkWidget *view);
+
+G_END_DECLS
+
+#endif /* __GNOME_MDI_H__ */
diff --git a/libgnomeui/gnome-mdiP.h b/libgnomeui/gnome-mdiP.h
new file mode 100644
index 0000000..7d8814f
--- /dev/null
+++ b/libgnomeui/gnome-mdiP.h
@@ -0,0 +1,137 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* gnome-mdiP.h - functions from gnome-mdi.c needed by other mdi sources,
+   but not a part of the public API amd the declaration of MDI's private
+   parts
+
+   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+   All rights reserved.
+
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Jaka Mocnik <jaka mocnik kiss uni-lj si>
+*/
+/*
+  @NOTATION@
+*/
+
+#ifndef __GNOME_MDIP_H__
+#define __GNOME_MDIP_H__
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include "gnome-app.h"
+
+#include "gnome-mdi.h"
+#include "gnome-mdi-child.h"
+#include "gnome-mdi-generic-child.h"
+
+G_BEGIN_DECLS
+
+/* keys for stuff that we'll assign to mdi data objects */
+#define GNOME_MDI_TOOLBAR_INFO_KEY           "MDIToolbarUIInfo"
+#define GNOME_MDI_MENUBAR_INFO_KEY           "MDIMenubarUIInfo"
+#define GNOME_MDI_CHILD_MENU_INFO_KEY        "MDIChildMenuUIInfo"
+#define GNOME_MDI_CHILD_TOOLBAR_INFO_KEY     "MDIChildToolbarUIInfo"
+#define GNOME_MDI_CHILD_KEY                  "MDIChild"
+#define GNOME_MDI_ITEM_COUNT_KEY             "MDIChildMenuItems"
+#define GNOME_MDI_APP_KEY                    "MDIApp"
+#define GNOME_MDI_PANED_KEY                  "MDIPaned"
+
+/* name for the child's toolbar */
+#define GNOME_MDI_CHILD_TOOLBAR_NAME         "MDIChildToolbar"
+
+struct _GnomeMDIPrivate 
+{
+	gchar *appname, *title;
+
+	GnomeUIInfo *menu_template;
+	GnomeUIInfo *toolbar_template;
+
+    /* probably only one of these would do, but... redundancy rules ;) */
+	GnomeMDIChild *active_child;
+	GtkWidget *active_view;  
+	GnomeApp *active_window;
+
+	GList *windows;     /* toplevel windows - GnomeApp widgets */
+	GList *children;    /* children - GnomeMDIChild objects*/
+
+	GSList *registered; /* see comment for gnome_mdi_(un)register() functions below for an explanation. */
+
+    /* paths for insertion of mdi_child specific menus and mdi_child list
+	   menu via gnome-app-helper routines */
+	gchar *child_menu_path;
+	gchar *child_list_path;
+
+	GtkPositionType tab_pos;
+
+	GnomeMDIMode mode : 3;
+
+	guint signal_id;
+	guint in_drag : 1;
+
+	guint has_user_refcount : 1;
+};
+
+struct _GnomeMDIChildPrivate
+{
+	GtkObject *parent;               /* a pointer to the MDI */
+
+	gchar *name;
+
+	GList *views;
+
+	GnomeUIInfo *menu_template;
+	GnomeUIInfo *toolbar_template;
+
+	/* default values for insertion of the child toolbar */
+	GnomeDockItemBehavior behavior;
+	GnomeDockPlacement placement;
+
+	gint band_num, band_pos, offset;
+};
+
+struct _GnomeMDIGenericChildPrivate
+{
+	/* if any of these are set they override the virtual functions
+	   in GnomeMDIChildClass. create_view is mandatory, as no default
+	   handler is provided, others may be NULL */
+	GnomeMDIChildViewCreator create_view;
+	GnomeMDIChildMenuCreator create_menus;
+	GnomeMDIChildConfigFunc  get_config_string;
+	GnomeMDIChildLabelFunc   set_label;
+
+	GtkCallbackMarshal create_view_cbm, create_menus_cbm,
+		               get_config_string_cbm, set_label_cbm;
+	GtkDestroyNotify   create_view_dn, create_menus_dn,
+		               get_config_string_dn, set_label_dn;
+	gpointer           create_view_data, create_menus_data,
+		               get_config_string_data, set_label_data;
+};
+
+/* declare the functions from gnome-mdi.c that other MDI source files need,
+   but are not part of the public API */
+void       gnome_mdi_child_list_remove (GnomeMDI *mdi, GnomeMDIChild *child);
+void       gnome_mdi_child_list_add    (GnomeMDI *mdi, GnomeMDIChild *child);
+GtkWidget *gnome_mdi_new_toplevel      (GnomeMDI *mdi);
+void       gnome_mdi_update_child      (GnomeMDI *mdi, GnomeMDIChild *child);
+void       gnome_mdi_child_add_toolbar (GnomeMDIChild *mdi_child,
+										GnomeApp *app,
+									    GtkToolbar *toolbar);
+
+G_END_DECLS
+
+#endif /* __GNOME_MDIP_H__ */
diff --git a/libgnomeui/gnome-paper-selector.c b/libgnomeui/gnome-paper-selector.c
new file mode 100644
index 0000000..b491fd6
--- /dev/null
+++ b/libgnomeui/gnome-paper-selector.c
@@ -0,0 +1,1058 @@
+/* GNOME Paper Selector
+ * Copyright (C) 1999 James Henstridge <james daa com au>
+ * All rights reserved.
+ *
+ * This replaces the paper selector by Dirk Luetjens.
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+/* #define PAGELAYOUT_TEST */
+
+#define DEFAULT_PAPER "A4"
+#define DEFAULT_UNIT "centimeter"
+
+#include <string.h>
+
+#include <libgnome/gnome-i18n.h>
+#include <libgnomeui/gnome-uidefs.h>
+
+#include "gnome-paper-selector.h"
+#include "gnome-unit-spinner.h"
+
+#include "portrait.xpm"
+#include "landscape.xpm"
+
+struct _GnomePaperSelectorPrivate {
+  const GnomeUnit *unit;
+  const GnomePaper *paper;
+
+  GtkWidget *paper_size, *paper_label;
+  GtkWidget *orient_portrait, *orient_landscape;
+  GtkWidget *tmargin, *bmargin, *lmargin, *rmargin;
+  GtkWidget *scaling;
+  GtkWidget *fittopage;
+
+  GtkWidget *darea;
+
+  GdkGC *gc;
+
+  /* position of paper preview */
+  gint16 x, y, width, height;
+
+  gboolean block_changed : 1;
+};
+
+static const GnomeUnit *default_unit = NULL;
+static const GnomeUnit *point_unit = NULL;
+static const GnomePaper *default_paper = NULL;
+
+enum {
+  CHANGED,
+  FITTOPAGE,
+  LAST_SIGNAL
+};
+
+static guint ps_signals[LAST_SIGNAL] = { 0 };
+static GtkTableClass *parent_class;
+
+static void gnome_paper_selector_class_init(GnomePaperSelectorClass *class);
+static void gnome_paper_selector_init(GnomePaperSelector *self);
+static void gnome_paper_selector_destroy(GtkObject *object);
+static void gnome_paper_selector_finalize(GObject *object);
+
+GtkType
+gnome_paper_selector_get_type(void)
+{
+  static GtkType ps_type = 0;
+
+  if (!ps_type) {
+    GtkTypeInfo ps_info = {
+      "GnomePaperSelector",
+      sizeof(GnomePaperSelector),
+      sizeof(GnomePaperSelectorClass),
+      (GtkClassInitFunc) gnome_paper_selector_class_init,
+      (GtkObjectInitFunc) gnome_paper_selector_init,
+      NULL,
+      NULL,
+      NULL
+    };
+    ps_type = gtk_type_unique(gtk_table_get_type(), &ps_info);
+  }
+  return ps_type;
+}
+
+static void
+gnome_paper_selector_class_init(GnomePaperSelectorClass *class)
+{
+  GtkObjectClass *object_class;
+  GObjectClass *gobject_class;
+  
+  object_class = (GtkObjectClass*) class;
+  gobject_class = (GObjectClass*) class;
+  parent_class = gtk_type_class(gtk_table_get_type());
+
+  ps_signals[CHANGED] =
+    gtk_signal_new("changed",
+		   GTK_RUN_FIRST,
+		   GTK_CLASS_TYPE(object_class),
+		   GTK_SIGNAL_OFFSET(GnomePaperSelectorClass, changed),
+		   gtk_signal_default_marshaller,
+		   GTK_TYPE_NONE, 0);
+  ps_signals[FITTOPAGE] =
+    gtk_signal_new("fittopage",
+		   GTK_RUN_FIRST,
+		   GTK_CLASS_TYPE(object_class),
+		   GTK_SIGNAL_OFFSET(GnomePaperSelectorClass, fittopage),
+		   gtk_signal_default_marshaller,
+		   GTK_TYPE_NONE, 0);
+
+  object_class->destroy = gnome_paper_selector_destroy;
+  gobject_class->finalize = gnome_paper_selector_finalize;
+}
+
+static void fittopage_pressed(GnomePaperSelector *self);
+static void darea_size_allocate(GnomePaperSelector *self,GtkAllocation *alloc);
+static gint darea_expose_event(GnomePaperSelector *self, GdkEventExpose *ev);
+static void paper_size_change(GtkMenuItem *item, GnomePaperSelector *self);
+static void orient_changed(GnomePaperSelector *self);
+static void margin_changed(GnomePaperSelector *self);
+static void scale_changed(GnomePaperSelector *self);
+
+static void
+gnome_paper_selector_init(GnomePaperSelector *self)
+{
+  GtkWidget *frame, *box, *table, *menu, *menuitem, *vbox, *wid;
+  GdkPixmap *pix;
+  GdkBitmap *mask;
+  const GList *papers;
+
+  self->_priv = g_new0(GnomePaperSelectorPrivate, 1);
+
+  if (default_unit == NULL)
+    default_unit = gnome_unit_with_name(DEFAULT_UNIT);
+  if (point_unit == NULL)
+    point_unit = gnome_unit_with_name("point");
+  if (default_paper == NULL)
+    default_paper = gnome_paper_with_name(DEFAULT_PAPER);
+
+  gtk_table_resize(GTK_TABLE(self), 3, 2);
+  gtk_table_set_row_spacings(GTK_TABLE(self), 5);
+  gtk_table_set_col_spacings(GTK_TABLE(self), 5);
+
+  /* paper size */
+  frame = gtk_frame_new(_("Paper Size"));
+  gtk_table_attach(GTK_TABLE(self), frame, 0,1, 0,1,
+		   GTK_FILL, GTK_FILL, 0, 0);
+  gtk_widget_show(frame);
+
+  box = gtk_vbox_new(FALSE, 5);
+  gtk_container_set_border_width(GTK_CONTAINER(box), 5);
+  gtk_container_add(GTK_CONTAINER(frame), box);
+  gtk_widget_show(box);
+
+  self->_priv->paper_size = gtk_option_menu_new();
+  gtk_box_pack_start(GTK_BOX(box), self->_priv->paper_size, TRUE, FALSE, 0);
+
+  menu = gtk_menu_new();
+  for (papers = gnome_paper_name_list(); papers; papers = papers->next) {
+    const GnomePaper *paper=gnome_paper_with_name((const gchar *)papers->data);
+
+    menuitem = gtk_menu_item_new_with_label((const gchar *)papers->data);
+    gtk_object_set_user_data(GTK_OBJECT(menuitem), (gpointer) paper);
+    gtk_signal_connect(GTK_OBJECT(menuitem), "activate",
+		       GTK_SIGNAL_FUNC(paper_size_change), self);
+    gtk_container_add(GTK_CONTAINER(menu), menuitem);
+    gtk_widget_show(menuitem);
+  }
+  gtk_option_menu_set_menu(GTK_OPTION_MENU(self->_priv->paper_size), menu);
+  gtk_widget_show(self->_priv->paper_size);
+
+  self->_priv->paper_label = gtk_label_new("");
+  gtk_box_pack_start(GTK_BOX(box), self->_priv->paper_label, TRUE, TRUE, 0);
+  gtk_widget_show(self->_priv->paper_label);
+
+  /* orientation */
+  frame = gtk_frame_new(_("Orientation"));
+  gtk_table_attach(GTK_TABLE(self), frame, 1,2, 0,1,
+		   GTK_FILL|GTK_EXPAND, GTK_FILL, 0, 0);
+  gtk_widget_show(frame);
+
+  box = gtk_hbox_new(FALSE, 5);
+  gtk_container_set_border_width(GTK_CONTAINER(box), 5);
+  gtk_container_add(GTK_CONTAINER(frame), box);
+  gtk_widget_show(box);
+
+  self->_priv->orient_portrait = gtk_radio_button_new(NULL);
+  vbox = gtk_vbox_new(FALSE, GNOME_PAD_SMALL);
+  gtk_container_add(GTK_CONTAINER(self->_priv->orient_portrait), vbox);
+  gtk_widget_show(vbox);
+  pix = gdk_pixmap_colormap_create_from_xpm_d(NULL,
+		gtk_widget_get_colormap(GTK_WIDGET(self)), &mask, NULL,
+		portrait_xpm);
+  wid = gtk_pixmap_new(pix, mask);
+  gdk_pixmap_unref(pix);
+  gdk_bitmap_unref(mask);
+  gtk_box_pack_start(GTK_BOX(vbox), wid, TRUE, TRUE, 0);
+  gtk_widget_show(wid);
+  wid = gtk_label_new(_("Portrait"));
+  gtk_box_pack_start(GTK_BOX(vbox), wid, TRUE, TRUE, 0);
+  gtk_widget_show(wid);
+
+  gtk_box_pack_start(GTK_BOX(box), self->_priv->orient_portrait, TRUE, TRUE, 0);
+  gtk_widget_show(self->_priv->orient_portrait);
+
+  self->_priv->orient_landscape = gtk_radio_button_new(
+	gtk_radio_button_group(GTK_RADIO_BUTTON(self->_priv->orient_portrait)));
+  vbox = gtk_vbox_new(FALSE, GNOME_PAD_SMALL);
+  gtk_container_add(GTK_CONTAINER(self->_priv->orient_landscape), vbox);
+  gtk_widget_show(vbox);
+  pix = gdk_pixmap_colormap_create_from_xpm_d(NULL,
+		gtk_widget_get_colormap(GTK_WIDGET(self)), &mask, NULL,
+		landscape_xpm);
+  wid = gtk_pixmap_new(pix, mask);
+  gdk_pixmap_unref(pix);
+  gdk_bitmap_unref(mask);
+  gtk_box_pack_start(GTK_BOX(vbox), wid, TRUE, TRUE, 0);
+  gtk_widget_show(wid);
+  wid = gtk_label_new(_("Landscape"));
+  gtk_box_pack_start(GTK_BOX(vbox), wid, TRUE, TRUE, 0);
+  gtk_widget_show(wid);
+
+  gtk_box_pack_start(GTK_BOX(box), self->_priv->orient_landscape, TRUE, TRUE, 0);
+  gtk_widget_show(self->_priv->orient_landscape);
+
+  /* margins */
+  frame = gtk_frame_new(_("Margins"));
+  gtk_table_attach(GTK_TABLE(self), frame, 0,1, 1,2,
+		   GTK_FILL, GTK_FILL, 0, 0);
+  gtk_widget_show(frame);
+
+  table = gtk_table_new(4, 2, FALSE);
+  gtk_container_set_border_width(GTK_CONTAINER(table), 5);
+  gtk_table_set_row_spacings(GTK_TABLE(table), 5);
+  gtk_table_set_col_spacings(GTK_TABLE(table), 5);
+  gtk_container_add(GTK_CONTAINER(frame), table);
+  gtk_widget_show(table);
+
+  wid = gtk_label_new(_("Top:"));
+  gtk_misc_set_alignment(GTK_MISC(wid), 1.0, 0.5);
+  gtk_table_attach(GTK_TABLE(table), wid, 0,1, 0,1,
+		   GTK_FILL, GTK_FILL|GTK_EXPAND, 0, 0);
+  gtk_widget_show(wid);
+
+  self->_priv->tmargin = gnome_unit_spinner_new(
+	GTK_ADJUSTMENT(gtk_adjustment_new(1, 0,100, 0.1,10,10)),
+	2, default_unit);
+  gtk_table_attach(GTK_TABLE(table), self->_priv->tmargin, 1,2, 0,1,
+		   GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
+  gtk_widget_show(self->_priv->tmargin);
+
+  wid = gtk_label_new(_("Bottom:"));
+  gtk_misc_set_alignment(GTK_MISC(wid), 1.0, 0.5);
+  gtk_table_attach(GTK_TABLE(table), wid, 0,1, 1,2,
+		   GTK_FILL, GTK_FILL|GTK_EXPAND, 0, 0);
+  gtk_widget_show(wid);
+
+  self->_priv->bmargin = gnome_unit_spinner_new(
+	GTK_ADJUSTMENT(gtk_adjustment_new(1, 0,100, 0.1,10,10)),
+	2, default_unit);
+  gtk_table_attach(GTK_TABLE(table), self->_priv->bmargin, 1,2, 1,2,
+		   GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
+  gtk_widget_show(self->_priv->bmargin);
+
+  wid = gtk_label_new(_("Left:"));
+  gtk_misc_set_alignment(GTK_MISC(wid), 1.0, 0.5);
+  gtk_table_attach(GTK_TABLE(table), wid, 0,1, 2,3,
+		   GTK_FILL, GTK_FILL|GTK_EXPAND, 0, 0);
+  gtk_widget_show(wid);
+
+  self->_priv->lmargin = gnome_unit_spinner_new(
+	GTK_ADJUSTMENT(gtk_adjustment_new(1, 0,100, 0.1,10,10)),
+	2, default_unit);
+  gtk_table_attach(GTK_TABLE(table), self->_priv->lmargin, 1,2, 2,3,
+		   GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
+  gtk_widget_show(self->_priv->lmargin);
+
+  wid = gtk_label_new(_("Right:"));
+  gtk_misc_set_alignment(GTK_MISC(wid), 1.0, 0.5);
+  gtk_table_attach(GTK_TABLE(table), wid, 0,1, 3,4,
+		   GTK_FILL, GTK_FILL|GTK_EXPAND, 0, 0);
+  gtk_widget_show(wid);
+
+  self->_priv->rmargin = gnome_unit_spinner_new(
+	GTK_ADJUSTMENT(gtk_adjustment_new(1, 0,100, 0.1,10,10)),
+	2, default_unit);
+  gtk_table_attach(GTK_TABLE(table), self->_priv->rmargin, 1,2, 3,4,
+		   GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
+  gtk_widget_show(self->_priv->rmargin);
+
+  /* Scaling */
+  frame = gtk_frame_new(_("Scaling"));
+  gtk_table_attach(GTK_TABLE(self), frame, 0,1, 2,3,
+		   GTK_FILL, GTK_FILL, 0, 0);
+  gtk_widget_show(frame);
+
+  box = gtk_vbox_new(FALSE, 5);
+  gtk_container_set_border_width(GTK_CONTAINER(box), 5);
+  gtk_container_add(GTK_CONTAINER(frame), box);
+  gtk_widget_show(box);
+
+  self->_priv->scaling = gtk_spin_button_new(
+	GTK_ADJUSTMENT(gtk_adjustment_new(100,1,10000, 1,10,10)), 1, 1);
+  gtk_box_pack_start(GTK_BOX(box), self->_priv->scaling, TRUE, FALSE, 0);
+  gtk_widget_show(self->_priv->scaling);
+
+  self->_priv->fittopage = gtk_button_new_with_label(_("Fit to Page"));
+  gtk_box_pack_start(GTK_BOX(box), self->_priv->fittopage, TRUE, FALSE, 0);
+  gtk_widget_show(self->_priv->fittopage);
+
+  /* the drawing area */
+  self->_priv->darea = gtk_drawing_area_new();
+  gtk_table_attach(GTK_TABLE(self), self->_priv->darea, 1,2, 1,3,
+		   GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
+  gtk_widget_show(self->_priv->darea);
+
+  /* connect the signal handlers */
+  gtk_signal_connect_object(GTK_OBJECT(self->_priv->orient_portrait), "toggled",
+			    GTK_SIGNAL_FUNC(orient_changed), GTK_OBJECT(self));
+
+  gtk_signal_connect_object(GTK_OBJECT(self->_priv->tmargin), "changed",
+			    GTK_SIGNAL_FUNC(margin_changed), GTK_OBJECT(self));
+  gtk_signal_connect_object(GTK_OBJECT(self->_priv->bmargin), "changed",
+			    GTK_SIGNAL_FUNC(margin_changed), GTK_OBJECT(self));
+  gtk_signal_connect_object(GTK_OBJECT(self->_priv->lmargin), "changed",
+			    GTK_SIGNAL_FUNC(margin_changed), GTK_OBJECT(self));
+  gtk_signal_connect_object(GTK_OBJECT(self->_priv->rmargin), "changed",
+			    GTK_SIGNAL_FUNC(margin_changed), GTK_OBJECT(self));
+
+  gtk_signal_connect_object(GTK_OBJECT(self->_priv->scaling), "changed",
+			    GTK_SIGNAL_FUNC(scale_changed), GTK_OBJECT(self));
+  gtk_signal_connect_object(GTK_OBJECT(self->_priv->fittopage), "pressed",
+			    GTK_SIGNAL_FUNC(fittopage_pressed),
+			    GTK_OBJECT(self));
+
+  gtk_signal_connect_object(GTK_OBJECT(self->_priv->darea), "size_allocate",
+			    GTK_SIGNAL_FUNC(darea_size_allocate),
+			    GTK_OBJECT(self));
+  gtk_signal_connect_object(GTK_OBJECT(self->_priv->darea), "expose_event",
+			    GTK_SIGNAL_FUNC(darea_expose_event),
+			    GTK_OBJECT(self));
+
+  self->_priv->unit = default_unit;
+  self->_priv->paper = default_paper;
+
+  self->_priv->gc = NULL;
+  self->_priv->block_changed = FALSE;
+}
+
+/**
+ * gnome_paper_selector_new:
+ * 
+ * createa GnomePaperSelector, using centimeters as the display unit for
+ * the spin buttons.
+ * 
+ * Return value: the GnomePaperSelector
+ **/
+GtkWidget *
+gnome_paper_selector_new(void)
+{
+  return gnome_paper_selector_new_with_unit(default_unit);
+}
+
+/**
+ * gnome_paper_selector_new_with_unit:
+ * @unit: the display units for the spin buttons
+ * 
+ * creates a new GnomePaperSelector
+ * 
+ * Return value: the GnomePaperSelector
+ **/
+GtkWidget *
+gnome_paper_selector_new_with_unit(const GnomeUnit *unit)
+{
+  GnomePaperSelector *self = gtk_type_new(gnome_paper_selector_get_type());
+
+  if (unit) {
+    self->_priv->unit = unit;
+    gnome_unit_spinner_change_units(GNOME_UNIT_SPINNER(self->_priv->tmargin), unit);
+    gnome_unit_spinner_change_units(GNOME_UNIT_SPINNER(self->_priv->bmargin), unit);
+    gnome_unit_spinner_change_units(GNOME_UNIT_SPINNER(self->_priv->lmargin), unit);
+    gnome_unit_spinner_change_units(GNOME_UNIT_SPINNER(self->_priv->rmargin), unit);
+  }
+  gnome_paper_selector_set_paper(self, DEFAULT_PAPER);
+  return GTK_WIDGET(self);
+}
+
+/**
+ * gnome_paper_selector_get_paper:
+ * @self: the GnomePaperSelector
+ * 
+ * get the currently selected paper.
+ * 
+ * Return value: the GnomePaper representing the currently selected paper.
+ **/
+const GnomePaper *
+gnome_paper_selector_get_paper(GnomePaperSelector *self)
+{
+  g_return_val_if_fail(self != NULL, NULL);
+
+  return self->_priv->paper;
+}
+
+/**
+ * gnome_paper_selector_set_paper:
+ * @self: the GnomePaperSelector
+ * @paper: the name of the paper.
+ * 
+ * change the currently selected paper.  This will also reset the margins
+ * for the new paper.
+ **/
+void
+gnome_paper_selector_set_paper(GnomePaperSelector *self, const gchar *paper)
+{
+  const GList *l;
+  gint i;
+  const GnomePaper *p = NULL;
+
+  g_return_if_fail(self != NULL);
+
+  if (paper)
+    p = gnome_paper_with_name(paper);
+  if (!p)
+    p = default_paper;
+  paper = gnome_paper_name(p);
+
+  for (l = gnome_paper_name_list(), i = 0; l; l = l->next, i++)
+    if (!strcmp((const gchar *)l->data, paper))
+      break;
+  gtk_option_menu_set_history(GTK_OPTION_MENU(self->_priv->paper_size), i);
+  gtk_menu_item_activate(
+	GTK_MENU_ITEM(GTK_OPTION_MENU(self->_priv->paper_size)->menu_item));
+}
+
+/**
+ * gnome_paper_selector_get_margins:
+ * @self: the GnomePaperSelector
+ * @unit: the units to return the margin widths in.
+ * @tmargin: a variable for the top margin, or NULL
+ * @bmargin: a variable for the bottom margin, or NULL
+ * @lmargin: a variable for the left margin, or NULL
+ * @rmargin: a variable for the right margin or NULL
+ * 
+ * Get the currently set margins for the paper.  If the unit argument
+ * is NULL, then the paper selector's default unit is used.
+ **/
+void
+gnome_paper_selector_get_margins(GnomePaperSelector *self,
+				 const GnomeUnit *unit,
+				 gfloat *tmargin, gfloat *bmargin,
+				 gfloat *lmargin, gfloat *rmargin)
+{
+  g_return_if_fail(self != NULL);
+
+  if (!unit)
+    unit = self->_priv->unit;
+
+  if (tmargin)
+    *tmargin = gnome_unit_spinner_get_value(GNOME_UNIT_SPINNER(self->_priv->tmargin),
+					    unit);
+  if (bmargin)
+    *bmargin = gnome_unit_spinner_get_value(GNOME_UNIT_SPINNER(self->_priv->bmargin),
+					    unit);
+  if (lmargin)
+    *lmargin = gnome_unit_spinner_get_value(GNOME_UNIT_SPINNER(self->_priv->lmargin),
+					    unit);
+  if (rmargin)
+    *rmargin = gnome_unit_spinner_get_value(GNOME_UNIT_SPINNER(self->_priv->rmargin),
+					    unit);
+}
+
+/**
+ * gnome_paper_selector_set_margins:
+ * @self: the GnomePaperSelector
+ * @unit: the unit the margin widths are in terms of, or NULL
+ * @tmargin: the new top margin
+ * @bmargin: the new bottom margin
+ * @lmargin: the new left margin
+ * @rmargin: the new right margin
+ * 
+ * Set the margins for the paper selector.  If the unit argument is NULL,
+ * the paper selector's default unit is used.
+ **/
+void
+gnome_paper_selector_set_margins(GnomePaperSelector *self,
+				 const GnomeUnit *unit,
+				 gfloat tmargin, gfloat bmargin,
+				 gfloat lmargin, gfloat rmargin)
+{
+  g_return_if_fail(self != NULL);
+
+  if ( ! unit)
+	  unit = self->_priv->unit;
+
+  self->_priv->block_changed = TRUE;
+  gnome_unit_spinner_set_value(GNOME_UNIT_SPINNER(self->_priv->tmargin), tmargin,
+			       unit);
+  gnome_unit_spinner_set_value(GNOME_UNIT_SPINNER(self->_priv->bmargin), bmargin,
+			       unit);
+  gnome_unit_spinner_set_value(GNOME_UNIT_SPINNER(self->_priv->lmargin), lmargin,
+			       unit);
+  gnome_unit_spinner_set_value(GNOME_UNIT_SPINNER(self->_priv->rmargin), rmargin,
+			       unit);
+  self->_priv->block_changed = FALSE;
+
+  gtk_signal_emit(GTK_OBJECT(self), ps_signals[CHANGED]);
+}
+
+/**
+ * gnome_paper_selector_get_orientation:
+ * @self: the GnomePaperSelector
+ * 
+ * get the currently set orientation of the paper.
+ * 
+ * Return value: the paper orientation.
+ **/
+GnomePaperOrient
+gnome_paper_selector_get_orientation(GnomePaperSelector *self)
+{
+  g_return_val_if_fail(self != NULL, GNOME_PAPER_ORIENT_PORTRAIT);
+
+  if (GTK_TOGGLE_BUTTON(self->_priv->orient_portrait)->active)
+    return GNOME_PAPER_ORIENT_PORTRAIT;
+  else
+    return GNOME_PAPER_ORIENT_LANDSCAPE;
+}
+
+/**
+ * gnome_paper_selector_set_orientation:
+ * @self: the GnomePaperSelector
+ * @orient: the new paper orientation.
+ * 
+ * Set the paper orientation for the paper selector.
+ **/
+void
+gnome_paper_selector_set_orientation(GnomePaperSelector *self,
+				     GnomePaperOrient orient)
+{
+  g_return_if_fail(self != NULL);
+
+  switch (orient) {
+  case GNOME_PAPER_ORIENT_PORTRAIT:
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->_priv->orient_portrait),
+				 TRUE);
+    break;
+  case GNOME_PAPER_ORIENT_LANDSCAPE:
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->_priv->orient_landscape),
+				 TRUE);
+    break;
+  }
+}
+
+/**
+ * gnome_paper_selector_get_scaling:
+ * @self: the GnomePaperSelector
+ * 
+ * Get the scaling factor for the paper selector
+ * 
+ * Return value: the scaling factor.
+ **/
+gfloat
+gnome_paper_selector_get_scaling(GnomePaperSelector *self)
+{
+  g_return_val_if_fail(self != NULL, 0.0);
+
+  return GTK_SPIN_BUTTON(self->_priv->scaling)->adjustment->value / 100.0;
+}
+
+/**
+ * gnome_paper_selector_set_scaling:
+ * @self: the GnomePaperSelector
+ * @scaling: the new scaling factor
+ * 
+ * Set the scaling factor.
+ **/
+void
+gnome_paper_selector_set_scaling(GnomePaperSelector *self, gfloat scaling)
+{
+  g_return_if_fail(self != NULL);
+
+  GTK_SPIN_BUTTON(self->_priv->scaling)->adjustment->value = scaling * 100.0;
+  gtk_adjustment_value_changed(GTK_SPIN_BUTTON(self->_priv->scaling)->adjustment);
+}
+
+/**
+ * gnome_paper_selector_get_effective_area:
+ * @self: the GnomePaperSelector
+ * @unit: the unit the width/height should be in, or NULL
+ * @width: a variable to return the width in
+ * @height: a variable to return the height in 
+ * 
+ * Returns the effective area of the paper.  This takes the paper size,
+ * margin widths and scaling factor into account.
+ **/
+void
+gnome_paper_selector_get_effective_area(GnomePaperSelector *self,
+					const GnomeUnit *unit,
+					gfloat *width, gfloat *height)
+{
+  gfloat h, w, scaling;
+
+  g_return_if_fail(self != NULL);
+
+  if ( ! unit)
+	  unit = self->_priv->unit;
+
+  if (GTK_TOGGLE_BUTTON(self->_priv->orient_portrait)->active) {
+    w = gnome_paper_pswidth(self->_priv->paper);
+    h = gnome_paper_psheight(self->_priv->paper);
+  } else {
+    h = gnome_paper_pswidth(self->_priv->paper);
+    w = gnome_paper_psheight(self->_priv->paper);
+  }
+  w = gnome_unit_convert(w, point_unit, unit);
+  h = gnome_unit_convert(h, point_unit, unit);
+
+  h -= gnome_unit_spinner_get_value(GNOME_UNIT_SPINNER(self->_priv->tmargin), unit);
+  h -= gnome_unit_spinner_get_value(GNOME_UNIT_SPINNER(self->_priv->bmargin), unit);
+  w -= gnome_unit_spinner_get_value(GNOME_UNIT_SPINNER(self->_priv->lmargin), unit);
+  w -= gnome_unit_spinner_get_value(GNOME_UNIT_SPINNER(self->_priv->rmargin), unit);
+  scaling = GTK_SPIN_BUTTON(self->_priv->scaling)->adjustment->value / 100.0;
+  h /= scaling;
+  w /= scaling;
+
+  if (width)  *width = w;
+  if (height) *height = h;
+}
+
+static void
+fittopage_pressed(GnomePaperSelector *self)
+{
+  gtk_signal_emit(GTK_OBJECT(self), ps_signals[FITTOPAGE]);
+}
+
+static void size_page(GnomePaperSelector *self, GtkAllocation *a)
+{
+  self->_priv->width = a->width - 3;
+  self->_priv->height = a->height - 3;
+
+  /* change to correct metrics */
+  if (GTK_TOGGLE_BUTTON(self->_priv->orient_portrait)->active) {
+    if (self->_priv->width * gnome_paper_psheight(self->_priv->paper) >
+	self->_priv->height * gnome_paper_pswidth(self->_priv->paper))
+      self->_priv->width = self->_priv->height * gnome_paper_pswidth(self->_priv->paper) /
+	gnome_paper_psheight(self->_priv->paper);
+    else
+      self->_priv->height = self->_priv->width * gnome_paper_psheight(self->_priv->paper) /
+	gnome_paper_pswidth(self->_priv->paper);
+  } else {
+    if (self->_priv->width * gnome_paper_pswidth(self->_priv->paper) >
+	self->_priv->height * gnome_paper_psheight(self->_priv->paper))
+      self->_priv->width = self->_priv->height * gnome_paper_psheight(self->_priv->paper) /
+	gnome_paper_pswidth(self->_priv->paper);
+    else
+      self->_priv->height = self->_priv->width * gnome_paper_pswidth(self->_priv->paper) /
+	gnome_paper_psheight(self->_priv->paper);
+  }
+
+  self->_priv->x = (a->width - self->_priv->width - 3) / 2;
+  self->_priv->y = (a->height - self->_priv->height - 3) / 2;
+}
+
+static void
+darea_size_allocate(GnomePaperSelector *self, GtkAllocation *allocation)
+{
+  size_page(self, allocation);
+}
+
+static gint
+darea_expose_event(GnomePaperSelector *self, GdkEventExpose *event)
+{
+  GdkWindow *window= self->_priv->darea->window;
+  gfloat val;
+  gint num;
+  GdkGC *black_gc = gtk_widget_get_style(GTK_WIDGET(self))->black_gc;
+  GdkGC *white_gc = gtk_widget_get_style(GTK_WIDGET(self))->white_gc;
+
+  if (!window)
+    return FALSE;
+
+  /* setup gc ... */
+  if (!self->_priv->gc) {
+    GdkColor blue;
+
+    self->_priv->gc = gdk_gc_new(window);
+    blue.red = 0;
+    blue.green = 0;
+    blue.blue = 0x7fff;
+    gdk_color_alloc(gtk_widget_get_colormap(GTK_WIDGET(self)), &blue);
+    gdk_gc_set_foreground(self->_priv->gc, &blue);
+  }
+
+  gdk_window_clear_area (window,
+                         0, 0,
+                         self->_priv->darea->allocation.width,
+                         self->_priv->darea->allocation.height);
+
+  /* draw the page image */
+  gdk_draw_rectangle(window, black_gc, TRUE, self->_priv->x+3, self->_priv->y+3,
+		     self->_priv->width, self->_priv->height);
+  gdk_draw_rectangle(window, white_gc, TRUE, self->_priv->x, self->_priv->y,
+		     self->_priv->width, self->_priv->height);
+  gdk_draw_rectangle(window, black_gc, FALSE, self->_priv->x, self->_priv->y,
+		     self->_priv->width-1, self->_priv->height-1);
+
+  /* draw margins */
+  if (GTK_TOGGLE_BUTTON(self->_priv->orient_portrait)->active) {
+    val = gnome_unit_spinner_get_value(GNOME_UNIT_SPINNER(self->_priv->tmargin),
+				       point_unit);
+    num = self->_priv->y + val * self->_priv->height /gnome_paper_psheight(self->_priv->paper);
+    gdk_draw_line(window, self->_priv->gc, self->_priv->x+1, num, self->_priv->x+self->_priv->width-2,num);
+
+    val = gnome_unit_spinner_get_value(GNOME_UNIT_SPINNER(self->_priv->bmargin),
+				       point_unit);
+    num = self->_priv->y + self->_priv->height -
+      val * self->_priv->height / gnome_paper_psheight(self->_priv->paper);
+    gdk_draw_line(window, self->_priv->gc, self->_priv->x+1, num, self->_priv->x+self->_priv->width-2,num);
+
+    val = gnome_unit_spinner_get_value(GNOME_UNIT_SPINNER(self->_priv->lmargin),
+				       point_unit);
+    num = self->_priv->x + val * self->_priv->width / gnome_paper_pswidth(self->_priv->paper);
+    gdk_draw_line(window, self->_priv->gc, num, self->_priv->y+1,num,self->_priv->y+self->_priv->height-2);
+
+    val = gnome_unit_spinner_get_value(GNOME_UNIT_SPINNER(self->_priv->rmargin),
+				       point_unit);
+    num = self->_priv->x + self->_priv->width -
+      val * self->_priv->width / gnome_paper_pswidth(self->_priv->paper);
+    gdk_draw_line(window, self->_priv->gc, num, self->_priv->y+1,num,self->_priv->y+self->_priv->height-2);
+  } else {
+    val = gnome_unit_spinner_get_value(GNOME_UNIT_SPINNER(self->_priv->tmargin),
+				       point_unit);
+    num = self->_priv->y + val * self->_priv->height /gnome_paper_pswidth(self->_priv->paper);
+    gdk_draw_line(window, self->_priv->gc, self->_priv->x+1, num, self->_priv->x+self->_priv->width-2,num);
+
+    val = gnome_unit_spinner_get_value(GNOME_UNIT_SPINNER(self->_priv->bmargin),
+				       point_unit);
+    num = self->_priv->y + self->_priv->height -
+      val * self->_priv->height / gnome_paper_pswidth(self->_priv->paper);
+    gdk_draw_line(window, self->_priv->gc, self->_priv->x+1, num, self->_priv->x+self->_priv->width-2,num);
+
+    val = gnome_unit_spinner_get_value(GNOME_UNIT_SPINNER(self->_priv->lmargin),
+				       point_unit);
+    num = self->_priv->x + val * self->_priv->width / gnome_paper_psheight(self->_priv->paper);
+    gdk_draw_line(window, self->_priv->gc, num, self->_priv->y+1,num,self->_priv->y+self->_priv->height-2);
+
+    val = gnome_unit_spinner_get_value(GNOME_UNIT_SPINNER(self->_priv->rmargin),
+				       point_unit);
+    num = self->_priv->x + self->_priv->width -
+      val * self->_priv->width / gnome_paper_psheight(self->_priv->paper);
+    gdk_draw_line(window, self->_priv->gc, num, self->_priv->y+1,num,self->_priv->y+self->_priv->height-2);
+  }
+
+  return FALSE;
+}
+
+static void
+paper_size_change(GtkMenuItem *item, GnomePaperSelector *self)
+{
+  gchar buf[512];
+
+  self->_priv->paper = (const GnomePaper *)gtk_object_get_user_data(GTK_OBJECT(item));
+  size_page(self, &self->_priv->darea->allocation);
+  gtk_widget_queue_draw(self->_priv->darea);
+
+  self->_priv->block_changed = TRUE;
+  gnome_unit_spinner_set_value(GNOME_UNIT_SPINNER(self->_priv->tmargin),
+			     gnome_paper_tmargin(self->_priv->paper), point_unit);
+  gnome_unit_spinner_set_value(GNOME_UNIT_SPINNER(self->_priv->bmargin),
+			     gnome_paper_bmargin(self->_priv->paper), point_unit);
+  gnome_unit_spinner_set_value(GNOME_UNIT_SPINNER(self->_priv->lmargin),
+			     gnome_paper_lmargin(self->_priv->paper), point_unit);
+  gnome_unit_spinner_set_value(GNOME_UNIT_SPINNER(self->_priv->rmargin),
+			     gnome_paper_rmargin(self->_priv->paper), point_unit);
+
+  if (GTK_TOGGLE_BUTTON(self->_priv->orient_portrait)->active) {
+    gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->_priv->tmargin))->upper =
+      gnome_paper_psheight(self->_priv->paper);
+    gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->_priv->bmargin))->upper =
+      gnome_paper_psheight(self->_priv->paper);
+    gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->_priv->lmargin))->upper =
+      gnome_paper_pswidth(self->_priv->paper);
+    gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->_priv->rmargin))->upper =
+      gnome_paper_pswidth(self->_priv->paper);
+  } else {
+    gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->_priv->tmargin))->upper =
+      gnome_paper_pswidth(self->_priv->paper);
+    gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->_priv->bmargin))->upper =
+      gnome_paper_pswidth(self->_priv->paper);
+    gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->_priv->lmargin))->upper =
+      gnome_paper_psheight(self->_priv->paper);
+    gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->_priv->rmargin))->upper =
+      gnome_paper_psheight(self->_priv->paper);
+  }
+  self->_priv->block_changed = FALSE;
+
+  g_snprintf(buf, sizeof(buf), _("%0.3g%s x %0.3g%s"),
+	     gnome_unit_convert(gnome_paper_pswidth(self->_priv->paper),
+				point_unit, self->_priv->unit),
+	     gnome_unit_abbrev(self->_priv->unit),
+	     gnome_unit_convert(gnome_paper_psheight(self->_priv->paper),
+				point_unit, self->_priv->unit),
+	     gnome_unit_abbrev(self->_priv->unit));
+  gtk_label_set(GTK_LABEL(self->_priv->paper_label), buf);
+
+  gtk_signal_emit(GTK_OBJECT(self), ps_signals[CHANGED]);
+}
+
+static void
+orient_changed(GnomePaperSelector *self)
+{
+  size_page(self, &self->_priv->darea->allocation);
+  gtk_widget_queue_draw(self->_priv->darea);
+
+  if (GTK_TOGGLE_BUTTON(self->_priv->orient_portrait)->active) {
+    gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->_priv->tmargin))->upper =
+      gnome_paper_psheight(self->_priv->paper);
+    gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->_priv->bmargin))->upper =
+      gnome_paper_psheight(self->_priv->paper);
+    gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->_priv->lmargin))->upper =
+      gnome_paper_pswidth(self->_priv->paper);
+    gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->_priv->rmargin))->upper =
+      gnome_paper_pswidth(self->_priv->paper);
+  } else {
+    gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->_priv->tmargin))->upper =
+      gnome_paper_pswidth(self->_priv->paper);
+    gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->_priv->bmargin))->upper =
+      gnome_paper_pswidth(self->_priv->paper);
+    gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->_priv->lmargin))->upper =
+      gnome_paper_psheight(self->_priv->paper);
+    gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->_priv->rmargin))->upper =
+      gnome_paper_psheight(self->_priv->paper);
+  }
+
+  if (!self->_priv->block_changed)
+    gtk_signal_emit(GTK_OBJECT(self), ps_signals[CHANGED]);
+}
+
+static void
+margin_changed(GnomePaperSelector *self)
+{
+  gtk_widget_queue_draw(self->_priv->darea);
+  if (!self->_priv->block_changed)
+    gtk_signal_emit(GTK_OBJECT(self), ps_signals[CHANGED]);
+}
+
+static void
+scale_changed(GnomePaperSelector *self)
+{
+  if (!self->_priv->block_changed)
+    gtk_signal_emit(GTK_OBJECT(self), ps_signals[CHANGED]);
+}
+
+static void
+gnome_paper_selector_destroy(GtkObject *object)
+{
+  GnomePaperSelector *self;
+
+  g_return_if_fail(object != NULL);
+
+  /* remember, destroy can be run multiple times! */
+
+  self = GNOME_PAPER_SELECTOR(object);
+  if (self->_priv->gc)
+    gdk_gc_unref(self->_priv->gc);
+  self->_priv->gc = NULL;
+
+  if (GTK_OBJECT_CLASS(parent_class)->destroy)
+    (* GTK_OBJECT_CLASS(parent_class)->destroy)(object);
+}
+
+static void
+gnome_paper_selector_finalize(GObject *object)
+{
+  GnomePaperSelector *self;
+
+  g_return_if_fail(object != NULL);
+
+  self = GNOME_PAPER_SELECTOR(object);
+
+  g_free(self->_priv);
+  self->_priv = NULL;
+
+  if (G_OBJECT_CLASS(parent_class)->finalize)
+    (* G_OBJECT_CLASS(parent_class)->finalize)(object);
+}
+
+
+
+#ifdef OLD_PAGE_SELECTOR_API
+/**
+ * gnome_paper_selector_get_width:
+ * @gspaper: the GnomePaperSelector
+ * 
+ * Get the paper width in points.  This function is provided for backward
+ * compatibility.
+ * 
+ * Return value: the paper width in points.
+ **/
+gfloat
+gnome_paper_selector_get_width(GnomePaperSelector *gspaper)
+{
+  g_return_val_if_fail(gspaper != NULL, 0);
+
+  return gnome_paper_pswidth(gnome_paper_selector_get_paper(gspaper));
+}
+/**
+ * gnome_paper_selector_get_height:
+ * @gspaper: the GnomePaperSelector
+ * 
+ * Get the paper height in points.  This function is provided for backward
+ * compatibility.
+ * 
+ * Return value: the paper height in points.
+ **/
+gfloat
+gnome_paper_selector_get_height(GnomePaperSelector *gspaper);
+{
+  g_return_val_if_fail(gspaper != NULL, 0);
+
+  return gnome_paper_psheight(gnome_paper_selector_get_paper(gspaper));
+}
+/**
+ * gnome_paper_selector_get_left_margin:
+ * @gspaper: the GnomePaperSelector
+ * 
+ * Get the left margin width in points.  This function is provided for
+ * backward compatibility.
+ * 
+ * Return value: the left margin width in points.
+ **/
+gfloat
+gnome_paper_selector_get_left_margin(GnomePaperSelector *gspaper);
+{
+  gfloat margin;
+
+  g_return_val_if_fail(gspaper != NULL, 0);
+
+  gnome_paper_selector_get_margins(gspaper, point_unit,
+				   NULL, NULL, &margin, NULL);
+  return margin;
+}
+/**
+ * gnome_paper_selector_get_right_margin:
+ * @gspaper: the GnomePaperSelector
+ * 
+ * Get the right margin width in points.  This function is provided for
+ * backward compatibility.
+ * 
+ * Return value: the right margin width in points.
+ **/
+gfloat
+gnome_paper_selector_get_right_margin(GnomePaperSelector *gspaper);
+{
+  gfloat margin;
+
+  g_return_val_if_fail(gspaper != NULL, 0);
+
+  gnome_paper_selector_get_margins(gspaper, point_unit,
+				   NULL, NULL, NULL, &margin);
+  return margin;
+}
+/**
+ * gnome_paper_selector_get_top_margin:
+ * @gspaper: the GnomePaperSelector
+ * 
+ * Get the top margin width in points.  This function is provided for
+ * backward compatibility.
+ * 
+ * Return value: the top margin width in points.
+ **/
+gfloat
+gnome_paper_selector_get_top_margin(GnomePaperSelector *gspaper);
+{
+  gfloat margin;
+
+  g_return_val_if_fail(gspaper != NULL, 0);
+
+  gnome_paper_selector_get_margins(gspaper, point_unit,
+				   &margin, NULL, NULL, NULL);
+  return margin;
+}
+/**
+ * gnome_paper_selector_get_bottom_margin:
+ * @gspaper: the GnomePaperSelector
+ * 
+ * Get the bottom margin width in points.  This function is provided for
+ * backward compatibility.
+ * 
+ * Return value: the bottom margin width in points.
+ **/
+gfloat
+gnome_paper_selector_get_bottom_margin(GnomePaperSelector *gspaper);
+{
+  gfloat margin;
+
+  g_return_val_if_fail(gspaper != NULL, 0);
+
+  gnome_paper_selector_get_margins(gspaper, point_unit,
+				   NULL, &margin, NULL, NULL);
+  return margin;
+}
+#endif
+
+
+#ifdef PAGELAYOUT_TEST
+
+void
+changed_signal(GnomePaperSelector *self)
+{
+  g_message("changed");
+}
+void
+fittopage_signal(GnomePaperSelector *self)
+{
+  g_message("fit to page");
+}
+
+void
+main(int argc, char **argv)
+{
+  GtkWidget *win, *ps;
+
+  gtk_init(&argc, &argv);
+
+  win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title(GTK_WINDOW(win), _("Page Setup"));
+  gtk_signal_connect(GTK_OBJECT(win), "destroy",
+		     GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
+
+  ps = gnome_paper_selector_new();
+  gtk_container_set_border_width(GTK_CONTAINER(ps), 5);
+  gtk_container_add(GTK_CONTAINER(win), ps);
+  gtk_widget_show(ps);
+
+  gtk_signal_connect(GTK_OBJECT(ps), "changed",
+		     GTK_SIGNAL_FUNC(changed_signal), NULL);
+  gtk_signal_connect(GTK_OBJECT(ps), "fittopage",
+		     GTK_SIGNAL_FUNC(fittopage_signal), NULL);
+
+  gtk_widget_show(win);
+  gtk_main();
+}
+
+#endif
diff --git a/libgnomeui/gnome-paper-selector.h b/libgnomeui/gnome-paper-selector.h
new file mode 100644
index 0000000..b35cac3
--- /dev/null
+++ b/libgnomeui/gnome-paper-selector.h
@@ -0,0 +1,110 @@
+/* GNOME Paper Selector
+ * Copyright (C) 1999 James Henstridge <james daa com au>
+ * All rights reserved.
+ *
+ * This replaces the paper selector by Dirk Luetjens.
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#ifndef GNOME_PAPER_SELECTOR_H
+#define GNOME_PAPER_SELECTOR_H
+
+#include <gtk/gtk.h>
+
+#include <libgnome/gnome-paper.h>
+
+G_BEGIN_DECLS
+
+#define OLD_GNOME_SELECTOR_API
+
+#define GNOME_TYPE_PAPER_SELECTOR            (gnome_paper_selector_get_type ())
+#define GNOME_PAPER_SELECTOR(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_PAPER_SELECTOR, GnomePaperSelector))
+#define GNOME_PAPER_SELECTOR_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_PAPER_SELECTOR, GnomePaperSelectorClass))
+#define GNOME_IS_PAPER_SELECTOR(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_PAPER_SELECTOR))
+#define GNOME_IS_PAPER_SELECTOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_PAPER_SELECTOR))
+#define GNOME_PAPER_SELECTOR_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_PAPER_SELECTOR, GnomePaperSelectorClass))
+
+#define DIA_IS_PAGE_LAYOUT(obj) GTK_CHECK_TYPE(obj, gnome_paper_selector_get_type())
+
+typedef struct _GnomePaperSelector        GnomePaperSelector;
+typedef struct _GnomePaperSelectorPrivate GnomePaperSelectorPrivate;
+typedef struct _GnomePaperSelectorClass   GnomePaperSelectorClass;
+
+typedef enum {
+  GNOME_PAPER_ORIENT_PORTRAIT,
+  GNOME_PAPER_ORIENT_LANDSCAPE
+} GnomePaperOrient;
+
+struct _GnomePaperSelector {
+  GtkTable parent;
+
+  /*<private>*/
+  GnomePaperSelectorPrivate *_priv;
+};
+
+struct _GnomePaperSelectorClass {
+  GtkTableClass parent_class;
+
+  void (*changed)(GnomePaperSelector *pl);
+  void (*fittopage)(GnomePaperSelector *pl);
+};
+
+GtkType      gnome_paper_selector_get_type    (void) G_GNUC_CONST;
+GtkWidget   *gnome_paper_selector_new(void);
+GtkWidget   *gnome_paper_selector_new_with_unit (const GnomeUnit *unit);
+
+const GnomePaper *gnome_paper_selector_get_paper (GnomePaperSelector *pl);
+void         gnome_paper_selector_set_paper   (GnomePaperSelector *pl,
+					       const gchar *paper);
+void         gnome_paper_selector_get_margins (GnomePaperSelector *pl,
+					       const GnomeUnit *unit,
+					       gfloat *tmargin,
+					       gfloat *bmargin,
+					       gfloat *lmargin,
+					       gfloat *rmargin);
+void         gnome_paper_selector_set_margins (GnomePaperSelector *pl,
+					       const GnomeUnit *unit,
+					       gfloat tmargin, gfloat bmargin,
+					       gfloat lmargin, gfloat rmargin);
+GnomePaperOrient gnome_paper_selector_get_orientation
+					      (GnomePaperSelector *pl);
+void         gnome_paper_selector_set_orientation (GnomePaperSelector *pl,
+						   GnomePaperOrient orient);
+gfloat       gnome_paper_selector_get_scaling (GnomePaperSelector *self);
+void         gnome_paper_selector_set_scaling (GnomePaperSelector *self,
+					       gfloat scaling);
+
+void         gnome_paper_selector_get_effective_area (GnomePaperSelector *self,
+						      const GnomeUnit *unit,
+						      gfloat *width,
+						      gfloat *height);
+
+/* compatibility with old interface ... */
+#ifdef OLD_PAGE_SELECTOR_API
+gfloat gnome_paper_selector_get_width  (GnomePaperSelector *gspaper);
+gfloat gnome_paper_selector_get_height (GnomePaperSelector *gspaper);
+gfloat gnome_paper_selector_get_left_margin   (GnomePaperSelector *gspaper);
+gfloat gnome_paper_selector_get_right_margin  (GnomePaperSelector *gspaper);
+gfloat gnome_paper_selector_get_top_margin    (GnomePaperSelector *gspaper);
+gfloat gnome_paper_selector_get_bottom_margin (GnomePaperSelector *gspaper);
+#endif
+
+G_END_DECLS
+
+#endif
diff --git a/libgnomeui/gnome-pixmap.c b/libgnomeui/gnome-pixmap.c
new file mode 100644
index 0000000..371bb3a
--- /dev/null
+++ b/libgnomeui/gnome-pixmap.c
@@ -0,0 +1,1443 @@
+/*  -*- Mode: C; c-set-style: linux; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+
+   Copyright (C) 1999 Red Hat, Inc.
+   All rights reserved.
+    
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   GnomePixmap Developers: Havoc Pennington, Jonathan Blandford
+*/
+/*
+  @NOTATION@
+*/
+
+#include <config.h>
+#include "gnome-pixmap.h"
+#include <stdio.h>
+#include "libart_lgpl/art_affine.h"
+#include "libart_lgpl/art_rgb_affine.h"
+#include "libart_lgpl/art_rgb_rgba_affine.h"
+#include <libgnomeuiP.h>
+
+static void gnome_pixmap_class_init    (GnomePixmapClass *class);
+static void gnome_pixmap_init          (GnomePixmap      *gpixmap);
+static void gnome_pixmap_destroy       (GtkObject        *object);
+static gint gnome_pixmap_expose        (GtkWidget        *widget,
+					GdkEventExpose   *event);
+static void gnome_pixmap_size_request  (GtkWidget        *widget,
+                                        GtkRequisition    *requisition);
+static void gnome_pixmap_set_property  (GObject            *object,
+                                        guint               param_id,
+                                        const GValue       *value,
+                                        GParamSpec         *pspec);
+static void gnome_pixmap_get_property  (GObject            *object,
+                                        guint               param_id,
+                                        GValue             *value,
+                                        GParamSpec         *pspec);
+
+static void clear_provided_state_image (GnomePixmap *gpixmap,
+                                        GtkStateType state);
+static void clear_generated_state_image(GnomePixmap *gpixmap,
+                                        GtkStateType state);
+static void clear_provided_image       (GnomePixmap *gpixmap);
+static void clear_scaled_image         (GnomePixmap *gpixmap);
+static void clear_all_images           (GnomePixmap *gpixmap);
+static void clear_generated_images     (GnomePixmap *gpixmap);
+static void generate_image             (GnomePixmap *gpixmap,
+                                        GtkStateType state);
+static void set_size                   (GnomePixmap *gpixmap,
+                                        gint width, gint height);
+
+static GdkPixbuf* saturate_and_pixelate(GdkPixbuf *pixbuf,
+                                        gfloat saturation, gboolean pixelate);
+
+static GdkBitmap* create_mask(GnomePixmap *gpixmap, GdkPixbuf *pixbuf);
+
+static GtkMiscClass *parent_class = NULL;
+
+#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
+
+enum {
+	PROP_0,
+	PROP_PIXBUF,
+	PROP_PIXBUF_WIDTH,
+	PROP_PIXBUF_HEIGHT,
+	PROP_FILE,
+	PROP_XPM_D,
+	PROP_DRAW_MODE,
+	PROP_ALPHA_THRESHOLD
+};
+
+/*
+ * Widget functions
+ */
+
+/**
+ * gnome_pixmap_get_type:
+ *
+ * Registers the &GnomePixmap class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Returns: the type ID of the &GnomePixmap class.
+ */
+guint
+gnome_pixmap_get_type (void)
+{
+	static guint pixmap_type = 0;
+
+	if (!pixmap_type) {
+		GtkTypeInfo pixmap_info = {
+			"GnomePixmap",
+			sizeof (GnomePixmap),
+			sizeof (GnomePixmapClass),
+			(GtkClassInitFunc) gnome_pixmap_class_init,
+			(GtkObjectInitFunc) gnome_pixmap_init,
+			NULL,
+			NULL,
+			NULL
+		};
+
+		pixmap_type = gtk_type_unique (gtk_misc_get_type (), &pixmap_info);
+	}
+
+	return pixmap_type;
+}
+
+static void
+gnome_pixmap_init (GnomePixmap *gpixmap)
+{
+        guint i;
+
+        GTK_WIDGET_SET_FLAGS(GTK_WIDGET(gpixmap), GTK_NO_WINDOW);
+
+	gpixmap->provided_image = NULL;
+        gpixmap->generated_scaled_image = NULL;
+        gpixmap->generated_scaled_mask = NULL;
+
+	gpixmap->width = -1;
+	gpixmap->height = -1;
+	gpixmap->alpha_threshold = 128;
+	gpixmap->mode = GNOME_PIXMAP_SIMPLE;
+
+        for (i = 0; i < 5; i ++) {
+                gpixmap->generated[i].pixbuf = NULL;
+                gpixmap->generated[i].mask = NULL;
+
+                gpixmap->provided[i].pixbuf = NULL;
+                gpixmap->provided[i].mask = NULL;
+		gpixmap->provided[i].saturation = 1.0;
+		gpixmap->provided[i].pixelate = FALSE;
+
+		if (i == GTK_STATE_INSENSITIVE) {
+			gpixmap->provided[i].saturation = 0.8;
+			gpixmap->provided[i].pixelate = TRUE;
+		}
+        }
+}
+
+static void
+gnome_pixmap_class_init (GnomePixmapClass *class)
+{
+        GObjectClass *gobject_class;
+	GtkObjectClass *object_class;
+	GtkWidgetClass *widget_class;
+
+        gobject_class = (GObjectClass *) class;
+	object_class = (GtkObjectClass *) class;
+	widget_class = (GtkWidgetClass *) class;
+
+	object_class->destroy = gnome_pixmap_destroy;
+
+	parent_class = gtk_type_class (gtk_misc_get_type ());
+
+	gobject_class->get_property = gnome_pixmap_get_property;
+	gobject_class->set_property = gnome_pixmap_set_property;
+
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_PIXBUF,
+                 g_param_spec_object ("pixbuf", NULL, NULL,
+                                      GDK_TYPE_PIXBUF,
+                                      (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_PIXBUF_WIDTH,
+                 g_param_spec_uint ("pixbuf_width", NULL, NULL,
+                                    0, G_MAXINT, 0,
+                                    (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_PIXBUF_HEIGHT,
+                 g_param_spec_uint ("pixbuf_height", NULL, NULL,
+                                    0, G_MAXINT, 0,
+                                    (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_FILE,
+                 g_param_spec_string ("file", NULL, NULL,
+                                      NULL,
+                                      G_PARAM_WRITABLE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_XPM_D,
+                 g_param_spec_pointer ("xpm_d", NULL, NULL,
+                                       G_PARAM_WRITABLE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_DRAW_MODE,
+                 g_param_spec_enum ("draw_mode", NULL, NULL,
+                                    GNOME_TYPE_PIXMAP_DRAW_MODE,
+                                    GNOME_PIXMAP_SIMPLE,
+                                    (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_ALPHA_THRESHOLD,
+                 g_param_spec_int ("alpha_threshold", NULL, NULL,
+                                   0, G_MAXINT, 128,
+                                   (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+	
+	widget_class->expose_event = gnome_pixmap_expose;
+        widget_class->size_request = gnome_pixmap_size_request;
+}
+
+static void
+gnome_pixmap_set_property (GObject            *object,
+                           guint               param_id,
+                           const GValue       *value,
+                           GParamSpec         *pspec)
+{
+        GnomePixmap *self;
+
+        g_return_if_fail (object != NULL);
+        g_return_if_fail (GNOME_IS_PIXMAP (object));
+
+	self = GNOME_PIXMAP (object);
+
+	switch (param_id) {
+	case PROP_PIXBUF:
+                gnome_pixmap_set_pixbuf (self, (GdkPixbuf *) g_value_get_object (value));
+		break;
+	case PROP_PIXBUF_WIDTH:
+		gnome_pixmap_set_pixbuf_size (self, g_value_get_uint (value),
+					      self->height);
+		break;
+	case PROP_PIXBUF_HEIGHT:
+		gnome_pixmap_set_pixbuf_size (self, self->width,
+					      g_value_get_uint (value));
+		break;
+	case PROP_FILE: {
+		GdkPixbuf *pixbuf;
+                GError *error = NULL;
+                const char *filename;
+
+                filename = g_value_get_string (value);
+		pixbuf = gdk_pixbuf_new_from_file (filename, &error);
+                if (error != NULL) {
+                        g_warning (G_STRLOC ": cannot open %s: %s",
+                                   filename, error->message);
+                        g_error_free (error);
+                }
+		if (pixbuf != NULL) {
+			gnome_pixmap_set_pixbuf (self, pixbuf);
+			gdk_pixbuf_unref (pixbuf);
+		}
+		break;
+        }
+	case PROP_XPM_D: {
+		GdkPixbuf *pixbuf;
+		pixbuf = gdk_pixbuf_new_from_xpm_data (g_value_get_pointer (value));
+		if (pixbuf != NULL) {
+			gnome_pixmap_set_pixbuf (self, pixbuf);
+			gdk_pixbuf_unref (pixbuf);
+		}
+		break;
+        }
+	case PROP_DRAW_MODE:
+		gnome_pixmap_set_draw_mode (self, g_value_get_enum (value));
+		break;
+	case PROP_ALPHA_THRESHOLD:
+		gnome_pixmap_set_alpha_threshold (self, g_value_get_int (value));
+		break;
+	default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+}
+
+static void
+gnome_pixmap_get_property (GObject            *object,
+                           guint               param_id,
+                           GValue             *value,
+                           GParamSpec         *pspec)
+{
+        GnomePixmap *self;
+
+        g_return_if_fail (object != NULL);
+        g_return_if_fail (GNOME_IS_PIXMAP (object));
+
+	self = GNOME_PIXMAP (object);
+
+	switch (param_id) {
+	case PROP_PIXBUF:
+		g_value_set_object (value, (GObject *) gnome_pixmap_get_pixbuf (self));
+		break;
+	case PROP_PIXBUF_WIDTH:
+		g_value_set_int (value, self->width);
+		break;
+	case PROP_PIXBUF_HEIGHT:
+		g_value_set_int (value, self->height);
+		break;
+	case PROP_DRAW_MODE:
+		g_value_set_enum (value, gnome_pixmap_get_draw_mode (self));
+		break;
+	case PROP_ALPHA_THRESHOLD:
+		g_value_set_int (value, gnome_pixmap_get_alpha_threshold (self));
+		break;
+	default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+}
+
+static void
+gnome_pixmap_destroy (GtkObject *object)
+{
+	GnomePixmap *gpixmap;
+
+	/* remember, destroy can be run multiple times! */
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GNOME_IS_PIXMAP (object));
+
+	gpixmap = GNOME_PIXMAP (object);
+
+        clear_all_images(gpixmap);
+
+	if (GTK_OBJECT_CLASS (parent_class)->destroy)
+		(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gnome_pixmap_size_request  (GtkWidget        *widget,
+                            GtkRequisition    *requisition)
+{
+        /* We base size on the max of all provided images if w,h are -1
+           else the scaled "main" image size (gpixmap->width, gpixmap->height) */
+        gint maxwidth = 0;
+        gint maxheight = 0;
+        int i;
+        GnomePixmap *gpixmap;
+
+        gpixmap = GNOME_PIXMAP(widget);
+        
+        if (gpixmap->width >= 0 &&
+            gpixmap->height >= 0) {
+                /* shortcut if both sizes are set */
+                maxwidth = gpixmap->width;
+                maxheight = gpixmap->height;
+        } else {
+                if (gpixmap->provided_image != NULL) {
+                        maxwidth = MAX(maxwidth, gdk_pixbuf_get_width(gpixmap->provided_image));
+                        maxheight = MAX(maxheight, gdk_pixbuf_get_height(gpixmap->provided_image));
+                }
+                
+                i = 0;
+                
+                while (i < 5) {
+                        GdkPixbuf *pix = gpixmap->provided[i].pixbuf;
+                        
+                        if (pix != NULL) {
+                                maxwidth = MAX(maxwidth, gdk_pixbuf_get_width(pix));
+                                maxheight = MAX(maxheight, gdk_pixbuf_get_height(pix));
+                        }
+                        
+                        ++i;
+                }
+
+                /* fix the size that was specified, if one was. */
+                if (gpixmap->width >= 0)
+                        maxwidth = gpixmap->width;
+                
+                if (gpixmap->height >= 0)
+                        maxheight = gpixmap->height;
+        }
+
+        requisition->width = maxwidth + GTK_MISC (gpixmap)->xpad * 2;
+        requisition->height = maxheight + GTK_MISC (gpixmap)->ypad * 2;
+}
+
+static void
+paint_with_pixbuf (GnomePixmap *gpixmap, GdkRectangle *area)
+{
+	GtkWidget *widget;
+        GdkPixbuf *draw_source;
+        GdkBitmap *draw_mask;
+        GtkMisc   *misc;
+	gint x_off, y_off;
+	gint top_clip, bottom_clip, left_clip, right_clip;
+
+        g_return_if_fail (GTK_WIDGET_DRAWABLE(gpixmap));
+
+        misc = GTK_MISC (gpixmap);
+        widget = GTK_WIDGET (gpixmap);
+
+        /* Ensure we have this state, if we can think of a way to have
+           it */
+        generate_image (gpixmap, GTK_WIDGET_STATE (widget));
+        
+        draw_source = gpixmap->generated[GTK_WIDGET_STATE (widget)].pixbuf;
+        draw_mask = gpixmap->generated[GTK_WIDGET_STATE (widget)].mask;
+        
+        if (draw_source == NULL)
+		return;
+
+	/* Now we actually want to draw the image */
+	/* The first thing we do for that, is write the images coords in the
+	 * drawable's coordinate system. */
+	x_off = (widget->allocation.x * (1.0 - misc->xalign) +
+		 (widget->allocation.x + widget->allocation.width
+		  - (widget->requisition.width - misc->xpad * 2)) *
+		 misc->xalign) + 0.5;
+	y_off = (widget->allocation.y * (1.0 - misc->yalign) +
+		 (widget->allocation.y + widget->allocation.height
+		  - (widget->requisition.height - misc->ypad * 2)) *
+		 misc->yalign) + 0.5;
+
+	/* next, we want to do clipping, to find the coordinates in image space of
+	 * the region to be drawn.  */
+	left_clip = (x_off < area->x)?area->x - x_off:0;
+	top_clip = (y_off < area->y)?area->y - y_off:0;
+	if (x_off + gdk_pixbuf_get_width (draw_source) > area->x + area->width)
+		right_clip = x_off + gdk_pixbuf_get_width (draw_source) - (area->x + area->width);
+	else
+		right_clip = 0;
+	if (y_off + gdk_pixbuf_get_height (draw_source) > area->y + area->height)
+		bottom_clip = y_off + gdk_pixbuf_get_height (draw_source) - (area->y + area->height);
+	else
+		bottom_clip = 0;
+
+	/* it's in the allocation, but not the image, so we return */
+	if (right_clip + left_clip >= gdk_pixbuf_get_width (draw_source)||
+	    top_clip + bottom_clip >= gdk_pixbuf_get_height (draw_source))
+		return;
+
+#if 0
+	g_print ("width=%d\theight=%d\n", gdk_pixbuf_get_width (draw_source), gdk_pixbuf_get_height (draw_source));
+	g_print ("area->x=%d\tarea->y=%d\tarea->width=%d\tarea->height=%d\nx_off=%d\ty_off=%d\nright=%d\tleft=%d\ttop=%d\tbottom=%d\n\n", area->x, area->y, area->width, area->height, x_off, y_off, right_clip, left_clip, top_clip, bottom_clip);
+#endif
+	if (gpixmap->mode == GNOME_PIXMAP_SIMPLE || !gdk_pixbuf_get_has_alpha (draw_source)) {
+		if (draw_mask) {
+			gdk_gc_set_clip_mask (widget->style->black_gc, draw_mask);
+			gdk_gc_set_clip_origin (widget->style->black_gc, x_off, y_off);
+		}
+
+		gdk_pixbuf_render_to_drawable (draw_source,
+					       widget->window,
+					       widget->style->black_gc,
+					       left_clip, top_clip,
+					       x_off + left_clip, y_off + top_clip,
+					       gdk_pixbuf_get_width (draw_source) - left_clip - right_clip,
+					       gdk_pixbuf_get_height (draw_source) - top_clip - bottom_clip,
+					       GDK_RGB_DITHER_NORMAL,
+					       0, 0); /* FIXME -- get the right offset */
+
+		if (draw_mask) {
+			gdk_gc_set_clip_mask (widget->style->black_gc, NULL);
+			gdk_gc_set_clip_origin (widget->style->black_gc, 0, 0);
+		}
+	} else if (gpixmap->mode == GNOME_PIXMAP_COLOR) {
+		GdkPixbuf *dest_source;
+		gint i, j, height, width, rowstride, dest_rowstride;
+		gint r, g, b;
+		guchar *dest_pixels, *c, *a, *original_pixels;
+
+
+		dest_source = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+					      FALSE,
+					      gdk_pixbuf_get_bits_per_sample (draw_source),
+					      gdk_pixbuf_get_width (draw_source) - left_clip - right_clip,
+					      gdk_pixbuf_get_height (draw_source) - top_clip - bottom_clip);
+
+
+		gdk_gc_set_clip_mask (widget->style->black_gc, draw_mask);
+		gdk_gc_set_clip_origin (widget->style->black_gc, x_off, y_off);
+
+		r = widget->style->bg[GTK_WIDGET_STATE (widget)].red >> 8;
+		g = widget->style->bg[GTK_WIDGET_STATE (widget)].green >> 8;
+		b = widget->style->bg[GTK_WIDGET_STATE (widget)].blue >> 8;
+		height = gdk_pixbuf_get_height (dest_source);
+		width = gdk_pixbuf_get_width (dest_source);
+		rowstride = gdk_pixbuf_get_rowstride (draw_source);
+		dest_rowstride = gdk_pixbuf_get_rowstride (dest_source);
+		dest_pixels = gdk_pixbuf_get_pixels (dest_source);
+		original_pixels = gdk_pixbuf_get_pixels (draw_source);
+		for (i = 0; i < height; i++) {
+			for (j = 0; j < width; j++) {
+				c = original_pixels + (i + top_clip)*rowstride + (j + left_clip)*4;
+				a = c + 3;
+				*(dest_pixels + i*dest_rowstride + j*3) = r + (((*c - r) * (*a) + 0x80) >> 8);
+				c++;
+				*(dest_pixels + i*dest_rowstride + j*3 + 1) = g + (((*c - g) * (*a) + 0x80) >> 8);
+				c++;
+				*(dest_pixels + i*dest_rowstride + j*3 + 2) = b + (((*c - b) * (*a) + 0x80) >> 8);
+			}
+		}
+
+		gdk_pixbuf_render_to_drawable (dest_source,
+					       widget->window,
+					       widget->style->black_gc,
+					       0, 0,
+					       x_off + left_clip, y_off + top_clip,
+					       width, height,
+					       GDK_RGB_DITHER_NORMAL,
+					       0, 0); /* FIXME -- get the right offset */
+
+		gdk_gc_set_clip_mask (widget->style->black_gc, NULL);
+		gdk_gc_set_clip_origin (widget->style->black_gc, 0, 0);
+
+		gdk_pixbuf_unref (dest_source);
+	}
+}
+
+static gint
+gnome_pixmap_expose (GtkWidget *widget, GdkEventExpose *event)
+{
+	g_return_val_if_fail (widget != NULL, FALSE);
+	g_return_val_if_fail (GNOME_IS_PIXMAP (widget), FALSE);
+	g_return_val_if_fail (event != NULL, FALSE);
+
+	if (GTK_WIDGET_DRAWABLE (widget))
+		paint_with_pixbuf (GNOME_PIXMAP (widget), &event->area);
+
+	return FALSE;
+}
+
+
+/*
+ * Set image data, create with image data
+ */
+
+static void
+set_state_pixbuf(GnomePixmap* gpixmap, GtkStateType state, GdkPixbuf* pixbuf, GdkBitmap* mask)
+{
+        clear_generated_state_image(gpixmap, state);
+        clear_provided_state_image(gpixmap, state);
+
+        g_return_if_fail(gpixmap->provided[state].pixbuf == NULL);
+        g_return_if_fail(gpixmap->provided[state].mask == NULL);
+
+        gpixmap->provided[state].pixbuf = pixbuf;
+        if (pixbuf)
+                gdk_pixbuf_ref(pixbuf);
+
+        gpixmap->provided[state].mask = mask;
+        if (mask)
+                gdk_bitmap_ref(mask);
+
+        if (GTK_WIDGET_VISIBLE(gpixmap)) {
+                gtk_widget_queue_resize(GTK_WIDGET(gpixmap));
+                gtk_widget_queue_clear(GTK_WIDGET(gpixmap));
+        }
+}
+
+static void
+set_state_pixbufs(GnomePixmap* gpixmap, GdkPixbuf* pixbufs[5], GdkBitmap* masks[5])
+{
+        guint i;
+
+        i = 0;
+        while (i < 5) {
+
+                set_state_pixbuf(gpixmap,
+                                 i,
+                                 pixbufs ? pixbufs[i] : NULL,
+                                 masks ? masks[i] : NULL);
+                ++i;
+        }
+}
+
+static void
+set_pixbuf(GnomePixmap* gpixmap, GdkPixbuf* pixbuf)
+{
+        if (pixbuf == gpixmap->provided_image)
+                return;
+        
+        clear_generated_images(gpixmap);
+        clear_provided_image(gpixmap);
+
+        g_return_if_fail(gpixmap->provided_image == NULL);
+
+        gpixmap->provided_image = pixbuf;
+
+        if (pixbuf)
+                gdk_pixbuf_ref(pixbuf);
+
+        if (GTK_WIDGET_VISIBLE(gpixmap)) {
+                gtk_widget_queue_resize(GTK_WIDGET(gpixmap));
+                gtk_widget_queue_clear(GTK_WIDGET(gpixmap));
+        }
+}
+
+
+
+/*
+ * Public functions
+ */
+
+
+/**
+ * gnome_pixmap_new:
+ * @void:
+ *
+ * Creates a new empty @GnomePixmap.
+ *
+ * Return value: A newly-created @GnomePixmap
+ **/
+GtkWidget*
+gnome_pixmap_new (void)
+{
+        GtkWidget* widget;
+
+        widget = gtk_type_new(gnome_pixmap_get_type());
+
+	return widget;
+}
+
+/**
+ * gnome_pixmap_new_from_file:
+ * @filename: The filename of the file to be loaded.
+ *
+ * Note that the new_from_file functions give you no way to detect errors;
+ * if the file isn't found/loaded, you get an empty widget.
+ * to detect errors just do:
+ *
+ * <programlisting>
+ * gdk_pixbuf_new_from_file (filename);
+ * if (pixbuf != NULL) {
+ *         gpixmap = gnome_pixmap_new_from_pixbuf (pixbuf);
+ * } else {
+ *         // handle your error...
+ * }
+ * </programlisting>
+ * 
+ * Return value: A newly allocated @GnomePixmap with the file at @filename loaded.
+ **/
+GtkWidget*
+gnome_pixmap_new_from_file          (const char *filename)
+{
+	GtkWidget *retval = NULL;
+	GdkPixbuf *pixbuf;
+        GError *error;
+
+	g_return_val_if_fail (filename != NULL, NULL);
+
+        error = NULL;
+	pixbuf = gdk_pixbuf_new_from_file (filename, &error);
+        if (error != NULL) {
+                g_warning (G_STRLOC ": cannot open %s: %s",
+                           filename, error->message);
+                g_error_free (error);
+        }
+	if (pixbuf != NULL) {
+		retval = gnome_pixmap_new_from_pixbuf (pixbuf);
+		gdk_pixbuf_unref (pixbuf);
+	} else {
+		retval = gnome_pixmap_new ();
+	}
+
+        return retval;
+}
+
+/**
+ * gnome_pixmap_new_from_file_at_size:
+ * @filename: The filename of the file to be loaded.
+ * @width: The width to scale the image to.
+ * @height: The height to scale the image to.
+ *
+ * Loads a new @GnomePixmap from a file, and scales it (if necessary) to the
+ * size indicated by @height and @width.  If either are set to -1, then the
+ * "natural" dimension of the image is used in place.  See
+ * @gnome_pixmap_new_from_file for information on error handling.
+ *
+ * Return value: value: A newly allocated @GnomePixmap with the file at @filename loaded.
+ **/
+GtkWidget*
+gnome_pixmap_new_from_file_at_size          (const gchar *filename, gint width, gint height)
+{
+        GtkWidget *retval = NULL;
+
+	g_return_val_if_fail (filename != NULL, NULL);
+	g_return_val_if_fail (width >= -1, NULL);
+	g_return_val_if_fail (height >= -1, NULL);
+
+	retval = gnome_pixmap_new_from_file (filename);
+	gnome_pixmap_set_pixbuf_size (GNOME_PIXMAP (retval), width, height);
+
+        return retval;
+}
+
+/**
+ * gnome_pixmap_new_from_file_at_size:
+ * @xpm_data: The xpm data to be loaded.
+ * @width: The width to scale the image to.
+ * @height: The height to scale the image to.
+ *
+ * Loads a new @GnomePixmap from the @xpm_data, and scales it (if necessary) to
+ * the size indicated by @height and @width.  If either are set to -1, then the
+ * "natural" dimension of the image is used in place.
+ *
+ * Return value: value: A newly allocated @GnomePixmap with the image from @xpm_data loaded.
+ **/
+GtkWidget*
+gnome_pixmap_new_from_xpm_d         (const char **xpm_data)
+{
+	GtkWidget *retval = NULL;
+	GdkPixbuf *pixbuf;
+
+	g_return_val_if_fail (xpm_data != NULL, NULL);
+
+	pixbuf = gdk_pixbuf_new_from_xpm_data (xpm_data);
+	if (pixbuf != NULL) {
+		retval = gnome_pixmap_new_from_pixbuf (pixbuf);
+		gdk_pixbuf_unref (pixbuf);
+	} else {
+		retval = gnome_pixmap_new ();
+	}
+
+        return retval;
+}
+
+/**
+ * gnome_pixmap_new_from_file_at_size:
+ * @xpm_data: The xpm data to be loaded.
+ * @width: The width to scale the image to.
+ * @height: The height to scale the image to.
+ *
+ * Loads a new @GnomePixmap from the @xpm_data, and scales it (if necessary) to
+ * the size indicated by @height and @width.  If either are set to -1, then the
+ * "natural" dimension of the image is used in place.
+ *
+ * Return value: value: A newly allocated @GnomePixmap with the image from @xpm_data loaded.
+ **/
+GtkWidget*
+gnome_pixmap_new_from_xpm_d_at_size (const char **xpm_data, int width, int height)
+{
+        GtkWidget *retval = NULL;
+
+	g_return_val_if_fail (xpm_data != NULL, NULL);
+	g_return_val_if_fail (width >= -1, NULL);
+	g_return_val_if_fail (height >= -1, NULL);
+
+	retval = gnome_pixmap_new_from_xpm_d (xpm_data);
+	gnome_pixmap_set_pixbuf_size (GNOME_PIXMAP (retval), width, height);
+
+        return retval;
+}
+
+
+/**
+ * gnome_pixmap_new_from_file_at_size:
+ * @pixbuf: The pixbuf to be loaded.
+ *
+ * Loads a new @GnomePixmap from the @pixbuf.
+ *
+ * Return value: value: A newly allocated @GnomePixmap with the image from @pixbuf loaded.
+ **/
+GtkWidget*
+gnome_pixmap_new_from_pixbuf          (GdkPixbuf *pixbuf)
+{
+	GnomePixmap *retval;
+
+	retval = gtk_type_new (gnome_pixmap_get_type ());
+
+	g_return_val_if_fail (pixbuf != NULL, GTK_WIDGET (retval));
+
+        set_pixbuf(retval, pixbuf);
+
+	return GTK_WIDGET (retval);
+        /*return gnome_pixmap_new_from_pixbuf_at_size(pixbuf, -1, -1);*/
+}
+
+/**
+ * gnome_pixmap_new_from_file_at_size:
+ * @pixbuf: The pixbuf be loaded.
+ * @width: The width to scale the image to.
+ * @height: The height to scale the image to.
+ *
+ * Loads a new @GnomePixmap from the @pixbuf, and scales it (if necessary) to
+ * the size indicated by @height and @width.  If either are set to -1, then the
+ * "natural" dimension of the image is used in place.
+ *
+ * Return value: value: A newly allocated @GnomePixmap with the image from @pixbuf loaded.
+ **/
+GtkWidget*
+gnome_pixmap_new_from_pixbuf_at_size  (GdkPixbuf *pixbuf, gint width, gint height)
+{
+        GtkWidget *retval = NULL;
+
+	g_return_val_if_fail (pixbuf != NULL, NULL);
+	g_return_val_if_fail (width >= -1, NULL);
+	g_return_val_if_fail (height >= -1, NULL);
+
+	retval = gnome_pixmap_new_from_pixbuf (pixbuf);
+	gnome_pixmap_set_pixbuf_size (GNOME_PIXMAP (retval), width, height);
+
+        return retval;
+}
+
+/**
+ * gnome_pixmap_set_pixbuf_size:
+ * @gpixmap: A @GnomePixmap.
+ * @width: The new width.
+ * @height: The new height.
+ *
+ * Sets the current size of the image displayed.  If there were custom "state"
+ * pixbufs set, as a side effect, they are discarded and must be re set at the
+ * new size.
+ *
+ **/
+/* Setters and getters */
+void
+gnome_pixmap_set_pixbuf_size (GnomePixmap      *gpixmap,
+			      gint              width,
+			      gint              height)
+{
+	g_return_if_fail (gpixmap != NULL);
+	g_return_if_fail (GNOME_IS_PIXMAP (gpixmap));
+        
+        set_size(gpixmap, width, height);
+}
+
+/**
+ * gnome_pixmap_get_pixbuf_size:
+ * @gpixmap: A @GnomePixmap
+ * @width: A pointer to place the width in.
+ * @height: A pointer to place the height in.
+ *
+ * Sets @width and @height to be the widgets current dimensions.  They will
+ * return the width or height of the image, or -1, -1 if the image's "natural"
+ * dimensions are used.  Either or both dimension arguments may be NULL, as
+ * necessary.
+ *
+ **/
+void
+gnome_pixmap_get_pixbuf_size (GnomePixmap      *gpixmap,
+			      gint             *width,
+			      gint             *height)
+{
+	g_return_if_fail (gpixmap != NULL);
+	g_return_if_fail (GNOME_IS_PIXMAP (gpixmap));
+
+	if (width)
+		*width = gpixmap->width;
+	if (height)
+		*height = gpixmap->height;
+}
+
+
+/**
+ * gnome_pixmap_set_pixbuf:
+ * @gpixmap: A @GnomePixmap.
+ * @pixbuf: The new pixbuf.
+ *
+ * Sets the image shown to be that of the pixbuf.  If there is a current image
+ * used by the @gpixmap, it is discarded along with any pixmaps at a particular
+ * state.  However, the @gpixmap will keep the same geometry as the old image,
+ * or if the width or height are set to -1, it will inherit the new image's
+ * geometry.
+ *
+ **/
+void
+gnome_pixmap_set_pixbuf (GnomePixmap *gpixmap,
+			 GdkPixbuf *pixbuf)
+{
+	g_return_if_fail (gpixmap != NULL);
+	g_return_if_fail (GNOME_IS_PIXMAP (gpixmap));
+	g_return_if_fail (pixbuf != NULL);
+
+        set_pixbuf(gpixmap, pixbuf);
+}
+
+
+/**
+ * gnome_pixmap_get_pixbuf:
+ * @gpixmap: A @GnomePixmap.
+ *
+ * Gets the current image used by @gpixmap, if you have set the
+ * pixbuf. If you've only set the value for particular states,
+ * then this won't return anything.
+ *
+ * Return value: A pixbuf.
+ **/
+GdkPixbuf *
+gnome_pixmap_get_pixbuf (GnomePixmap      *gpixmap)
+{
+	g_return_val_if_fail (gpixmap != NULL, NULL);
+	g_return_val_if_fail (GNOME_IS_PIXMAP (gpixmap), NULL);
+
+	return gpixmap->provided_image;
+}
+
+
+/**
+ * gnome_pixmap_set_pixbuf_at_state:
+ * @gpixmap: A @GnomePixmap.
+ * @state: The state being set.
+ * @pixbuf: The new image for the state.
+ * @mask: The mask for the new image.
+ *
+ * Sets a custom image for the image at @state.  For example, you can set the
+ * prelighted appearance to a different image from the normal one.  If
+ * necessary, the image will be scaled to the appropriate size.  The mask can
+ * also be optionally NULL.  The image set will be modified by the draw vals as
+ * normal.
+ *
+ **/
+void
+gnome_pixmap_set_pixbuf_at_state (GnomePixmap *gpixmap,
+				  GtkStateType state,
+				  GdkPixbuf *pixbuf,
+				  GdkBitmap *mask)
+{
+        g_return_if_fail (gpixmap != NULL);
+        g_return_if_fail (GNOME_IS_PIXMAP (gpixmap));
+        
+        set_state_pixbuf (gpixmap, state, pixbuf, mask);
+}
+
+/**
+ * gnome_pixmap_set_state_pixbufs
+ * @gpixmap: A @GnomePixmap.
+ * @pixbufs: The images.
+ * @masks: The masks.
+ *
+ * Sets a custom image for all the possible states of the image.  Both @pixbufs
+ * and @masks are indexed by a GtkStateType.  Any or all of the images can be
+ * NULL, as necessary.  The image set will be modified by the draw vals as
+ * normal.
+ *
+ **/
+void
+gnome_pixmap_set_state_pixbufs (GnomePixmap *gpixmap,
+                                GdkPixbuf   *pixbufs[5],
+                                GdkBitmap   *masks[5])
+{
+        g_return_if_fail(gpixmap != NULL);
+        g_return_if_fail(GNOME_IS_PIXMAP (gpixmap));
+        
+        set_state_pixbufs(gpixmap, pixbufs, masks);
+}
+
+/**
+ * gnome_pixmap_clear:
+ * @gpixmap: A @GnomePixmap.
+ *
+ * Removes any images from @gpixmap.  If still visible, the image will appear empty.
+ *
+ **/
+void
+gnome_pixmap_clear (GnomePixmap *gpixmap)
+{
+        g_return_if_fail(gpixmap != NULL);
+        g_return_if_fail(GNOME_IS_PIXMAP (gpixmap));
+
+        clear_all_images(gpixmap);
+
+        if (GTK_WIDGET_VISIBLE(gpixmap)) {
+                gtk_widget_queue_resize(GTK_WIDGET(gpixmap));
+                gtk_widget_queue_clear(GTK_WIDGET(gpixmap));
+        }
+}
+
+/**
+ * gnome_pixmap_set_draw_vals:
+ * @gpixmap: A @GnomePixmap.
+ * @state: The the state to set the modifications to
+ * @saturation: The saturtion offset.
+ * @pixelate: Draw the insensitive stipple.
+ *
+ * Sets the modification parameters for a particular state.  The saturation
+ * level determines the amount of color in the image.  The default level of 1.0
+ * leaves the color unchanged while a level of 0.0 means the image is fully
+ * saturated, and has no color.  @saturation can be set to values greater then 1.0,
+ * or less then 0.0, but this produces less meaningful results.  If @pixelate is
+ * set to TRUE, then in adition to any saturation, a light stipple is overlayed
+ * over the image.
+ *
+ **/
+void
+gnome_pixmap_set_draw_vals (GnomePixmap *gpixmap,
+			    GtkStateType state,
+			    gfloat saturation,
+			    gboolean pixelate)
+{
+	g_return_if_fail (gpixmap != NULL);
+	g_return_if_fail (GNOME_IS_PIXMAP (gpixmap));
+	g_return_if_fail (state >= 0 && state < 5);
+
+	gpixmap->provided[state].saturation = saturation;
+	gpixmap->provided[state].pixelate = pixelate;
+
+        if (GTK_WIDGET_VISIBLE(gpixmap)) {
+                gtk_widget_queue_clear(GTK_WIDGET(gpixmap));
+        }
+}
+
+/**
+ * gnome_pixmap_get_draw_vals:
+ * @gpixmap: A @GnomePixmap.
+ * @state: The the state to set the modifications to
+ * @saturation: return location for the saturation offset
+ * @pixelate: return value for whether to draw the insensitive stipple
+ *
+ * Retrieve the values set by gnome_pixmap_set_draw_vals(). Either
+ * return location can be NULL if you don't care about it.
+ *
+ **/
+void
+gnome_pixmap_get_draw_vals           (GnomePixmap      *gpixmap,
+                                      GtkStateType      state,
+                                      gfloat           *saturation,
+                                      gboolean         *pixelate)
+{
+	g_return_if_fail (gpixmap != NULL);
+	g_return_if_fail (GNOME_IS_PIXMAP (gpixmap));
+	g_return_if_fail (state >= 0 && state < 5);
+
+        if (saturation)
+                *saturation = gpixmap->provided[state].saturation;
+        if (pixelate)
+                *pixelate = gpixmap->provided[state].pixelate;
+}
+
+/**
+ * gnome_pixmap_set_draw_mode:
+ * @gpixmap: A @GnomePixmap.
+ * @mode: The new drawing mode.
+ *
+ * This sets the drawing mode of the image to be @mode.  The image
+ * must have an alpha channel if @GNOME_PIXMAP_COLOR is to be used.
+ **/
+void
+gnome_pixmap_set_draw_mode (GnomePixmap *gpixmap,
+			    GnomePixmapDrawMode mode)
+{
+	g_return_if_fail (gpixmap != NULL);
+	g_return_if_fail (GNOME_IS_PIXMAP (gpixmap));
+
+	if (gpixmap->mode == mode)
+		return;
+        
+	gpixmap->mode = mode;
+	clear_generated_images (gpixmap);
+
+        if (GTK_WIDGET_VISIBLE (gpixmap)) {
+                gtk_widget_queue_resize (GTK_WIDGET (gpixmap));
+		gtk_widget_queue_clear (GTK_WIDGET (gpixmap));
+	}
+}
+
+/**
+ * gnome_pixmap_get_draw_mode:
+ * @gpixmap: A @GnomePixmap.
+ *
+ * Gets the current draw mode.
+ *
+ * Return value: The current @GnomePixmapDrawMode setting.
+ **/
+GnomePixmapDrawMode
+gnome_pixmap_get_draw_mode (GnomePixmap *gpixmap)
+{
+	g_return_val_if_fail (gpixmap != NULL, GNOME_PIXMAP_SIMPLE);
+	g_return_val_if_fail (GNOME_IS_PIXMAP (gpixmap), GNOME_PIXMAP_SIMPLE);
+
+	return gpixmap->mode;
+}
+
+/**
+ * gnome_pixmap_set_alpha_threshold:
+ * @gpixmap: A @GnomePixmap.
+ * @alpha_threshold: The alpha threshold
+ *
+ * Sets the alpha threshold for @gpixmap.  It is used to determine which pixels
+ * are shown when the image has an alpha channel, and is only used if no mask is
+ * set.
+ *
+ **/
+void
+gnome_pixmap_set_alpha_threshold (GnomePixmap *gpixmap,
+				  gint alpha_threshold)
+{
+	g_return_if_fail (gpixmap != NULL);
+	g_return_if_fail (GNOME_IS_PIXMAP (gpixmap));
+	g_return_if_fail (alpha_threshold >= 0 || alpha_threshold <= 255);
+
+	if (alpha_threshold == gpixmap->alpha_threshold)
+		return;
+
+	gpixmap->alpha_threshold = alpha_threshold;
+
+	clear_generated_images (gpixmap);
+        
+        if (GTK_WIDGET_VISIBLE (gpixmap)) {
+		gtk_widget_queue_clear (GTK_WIDGET (gpixmap));
+	}
+}
+
+/**
+ * gnome_pixmap_get_alpha_threshold:
+ * @gpixmap: A @GnomePixmap.
+ *
+ * Gets the current alpha threshold.
+ *
+ * Return value: The alpha threshold
+ **/
+gint
+gnome_pixmap_get_alpha_threshold (GnomePixmap *gpixmap)
+{
+	g_return_val_if_fail (gpixmap != NULL, 0);
+	g_return_val_if_fail (GNOME_IS_PIXMAP (gpixmap), 0);
+
+	return gpixmap->alpha_threshold;
+}
+
+/*
+ * Internal functions
+ */
+
+static void
+clear_provided_state_image (GnomePixmap *gpixmap,
+                            GtkStateType state)
+{
+        if (gpixmap->provided[state].pixbuf != NULL) {
+                gdk_pixbuf_unref(gpixmap->provided[state].pixbuf);
+                gpixmap->provided[state].pixbuf = NULL;
+        }
+        
+        if (gpixmap->provided[state].mask != NULL) {
+                gdk_bitmap_unref(gpixmap->provided[state].mask);
+                gpixmap->provided[state].mask = NULL;
+        }
+}
+
+static void
+clear_generated_state_image(GnomePixmap *gpixmap,
+                            GtkStateType state)
+{
+        if (gpixmap->generated[state].pixbuf != NULL) {
+                gdk_pixbuf_unref(gpixmap->generated[state].pixbuf);
+                gpixmap->generated[state].pixbuf = NULL;
+        }
+
+        if (gpixmap->generated[state].mask != NULL) {
+                gdk_bitmap_unref(gpixmap->generated[state].mask);
+                gpixmap->generated[state].mask = NULL;
+        }
+}
+        
+static void
+clear_provided_image (GnomePixmap *gpixmap)
+{
+        if (gpixmap->provided_image) {
+                gdk_pixbuf_unref(gpixmap->provided_image);
+                gpixmap->provided_image = NULL;
+        }
+}
+
+static void
+clear_scaled_image (GnomePixmap *gpixmap)
+{
+        if (gpixmap->generated_scaled_image) {
+                gdk_pixbuf_unref(gpixmap->generated_scaled_image);
+                gpixmap->generated_scaled_image = NULL;
+        }
+        if (gpixmap->generated_scaled_mask) {
+                gdk_bitmap_unref(gpixmap->generated_scaled_mask);
+                gpixmap->generated_scaled_mask = NULL;
+        }
+}
+
+static void
+clear_all_images (GnomePixmap *gpixmap)
+{
+        guint i;
+
+        i = 0;
+        while (i < 5) {
+
+                clear_provided_state_image(gpixmap, i);
+
+                ++i;
+        }
+        
+        clear_generated_images(gpixmap);
+        clear_provided_image(gpixmap);
+}
+
+static void
+clear_generated_images (GnomePixmap *gpixmap)
+{
+        guint i;
+
+        i = 0;
+        while (i < 5) {
+
+                clear_generated_state_image(gpixmap, i);
+
+                ++i;
+        }
+
+        clear_scaled_image(gpixmap);
+}
+
+static void
+generate_image (GnomePixmap *gpixmap,
+                GtkStateType state)
+{
+        /* See if this image is already generated */
+        if (gpixmap->generated[state].pixbuf != NULL)
+                return;
+
+        g_return_if_fail(gpixmap->generated[state].pixbuf == NULL);
+        g_return_if_fail(gpixmap->generated[state].mask == NULL);
+        
+        /* To generate an image, we first use the provided image for a given
+           state, if any; if not we use the gpixmap->provided_image; if that
+           doesn't exist then we bail out. */
+           
+        if (gpixmap->provided[state].pixbuf != NULL) {
+                gint width = gpixmap->width;
+                gint height = gpixmap->height;
+                GdkPixbuf *scaled;
+                GdkPixbuf *generated;
+
+                if (width >= 0 || height >= 0) {
+                        if (width < 0)
+                                width = gdk_pixbuf_get_width(gpixmap->provided[state].pixbuf);
+
+                        if (height < 0)
+                                height = gdk_pixbuf_get_height(gpixmap->provided[state].pixbuf);
+                        
+                        scaled = gdk_pixbuf_scale_simple (gpixmap->provided[state].pixbuf,
+                                                          gpixmap->width,
+                                                          gpixmap->height,
+                                                          ART_FILTER_BILINEAR);
+                } else {
+                        /* just copy */
+                        scaled = gpixmap->provided[state].pixbuf;
+                        gdk_pixbuf_ref(scaled);
+                }
+                        
+                generated = saturate_and_pixelate(scaled,
+                                                  gpixmap->provided[state].saturation,
+                                                  gpixmap->provided[state].pixelate);
+                
+                gpixmap->generated[state].pixbuf = generated;
+
+                if ((scaled == gpixmap->provided[state].pixbuf) &&
+                    gpixmap->provided[state].mask) {
+                        /* use provided mask if it exists
+                           and we did not have to scale */
+                        gpixmap->generated[state].mask =
+                                gpixmap->provided[state].mask;
+                        gdk_bitmap_ref(gpixmap->generated[state].mask);
+                } else {
+                        /* create mask */
+                        gpixmap->generated[state].mask =
+                                create_mask(gpixmap, generated);
+                }
+
+                /* Drop intermediate image */
+                gdk_pixbuf_unref(scaled);
+        }
+        
+        /* Ensure we've generated the scaled image
+           if we have an original image */
+        if (gpixmap->provided_image != NULL &&
+            gpixmap->generated_scaled_image == NULL) {
+                gint width = gpixmap->width;
+                gint height = gpixmap->height;
+                
+                if (width < 0)
+                        width = gdk_pixbuf_get_width(gpixmap->provided_image);
+                if (height < 0)
+                        height = gdk_pixbuf_get_height(gpixmap->provided_image);
+                
+                if (gpixmap->width < 0 && /* orig w/h, not the "fixed" ones */
+                    gpixmap->height < 0) {
+                        /* Just copy */
+                        gpixmap->generated_scaled_image = gpixmap->provided_image;
+                        gdk_pixbuf_ref(gpixmap->generated_scaled_image);
+                } else {
+                        gpixmap->generated_scaled_image =
+                                gdk_pixbuf_scale_simple (gpixmap->provided_image,
+                                                         width,
+                                                         height,
+                                                         ART_FILTER_BILINEAR);
+                }
+
+                gpixmap->generated_scaled_mask =
+                        create_mask(gpixmap, gpixmap->generated_scaled_image);
+        }
+
+        /* Now we generate the per-state image from the scaled
+           copy of the provided image */
+        if (gpixmap->generated_scaled_image != NULL) {
+                GdkPixbuf *generated;
+
+                g_return_if_fail(gpixmap->generated_scaled_mask);
+                
+                generated = saturate_and_pixelate(gpixmap->generated_scaled_image,
+                                                  gpixmap->provided[state].saturation,
+                                                  gpixmap->provided[state].pixelate);
+                
+                gpixmap->generated[state].pixbuf = generated;
+
+                if (gpixmap->provided[state].mask) {
+                        /* use provided mask if it exists */
+                        gpixmap->generated[state].mask =
+                                gpixmap->provided[state].mask;
+                        gdk_bitmap_ref(gpixmap->generated[state].mask);
+                } else {
+                        /* If we just copied the generated_scaled_image
+                           then also copy the mask */
+                        if (generated == gpixmap->generated_scaled_image) {
+                                gpixmap->generated[state].mask =
+                                        gpixmap->generated_scaled_mask;
+                                gdk_bitmap_ref(gpixmap->generated_scaled_mask);
+                        } else {
+                                /* create mask */
+                                gpixmap->generated[state].mask =
+                                        create_mask(gpixmap, generated);
+                        }
+                }
+        }
+
+        /* If we didn't have a provided_image or a provided image for the
+           particular state, then we have no way to generate an image.
+        */
+}
+
+static void
+set_size (GnomePixmap *gpixmap,
+          gint width, gint height)
+{
+        if (gpixmap->width == width &&
+            gpixmap->height == height)
+                return;
+        
+	/* FIXME: if old_width == -1 and pixbuf->width == width, we can just set
+	 * the values and return as an optomization step. */
+        
+        clear_generated_images(gpixmap);
+        
+        gpixmap->width = width;
+        gpixmap->height = height;
+        
+        if (GTK_WIDGET_VISIBLE (gpixmap)) {
+                if ((GTK_WIDGET (gpixmap)->requisition.width != width) ||
+                    (GTK_WIDGET (gpixmap)->requisition.height != height))
+                        gtk_widget_queue_resize (GTK_WIDGET (gpixmap));
+                else
+                        gtk_widget_queue_clear (GTK_WIDGET (gpixmap));
+	}
+}
+
+static GdkBitmap*
+create_mask(GnomePixmap *gpixmap, GdkPixbuf *pixbuf)
+{
+        GdkBitmap *mask;
+        gint width = gdk_pixbuf_get_width(pixbuf);
+        gint height = gdk_pixbuf_get_height(pixbuf);
+        
+        mask = gdk_pixmap_new (NULL, width, height, 1);
+
+        gdk_pixbuf_render_threshold_alpha(pixbuf,
+                                          mask,
+                                          0, 0, 0, 0,
+                                          width, height,
+                                          gpixmap->alpha_threshold);
+                
+        
+        return mask;
+}
+ 
+static GdkPixbuf*
+saturate_and_pixelate(GdkPixbuf *pixbuf, gfloat saturation, gboolean pixelate)
+{
+        if (saturation == 1.0) {
+                gdk_pixbuf_ref(pixbuf);
+                return pixbuf;
+        } else {
+		GdkPixbuf *target;
+		gint i, j;
+		gint width, height, has_alpha, rowstride;
+		guchar *target_pixels;
+		guchar *original_pixels;
+		guchar *current_pixel;
+		guchar intensity;
+
+		has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
+		width = gdk_pixbuf_get_width (pixbuf);
+		height = gdk_pixbuf_get_height (pixbuf);
+		rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+                
+		target = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+					 has_alpha,
+					 gdk_pixbuf_get_bits_per_sample (pixbuf),
+					 width, height);
+                
+		target_pixels = gdk_pixbuf_get_pixels (target);
+		original_pixels = gdk_pixbuf_get_pixels (pixbuf);
+
+		for (i = 0; i < height; i++) {
+			for (j = 0; j < width; j++) {
+				current_pixel = original_pixels + i*rowstride + j*(has_alpha?4:3);
+				intensity = INTENSITY (*(current_pixel), *(current_pixel + 1), *(current_pixel + 2));
+				if (pixelate && (i+j)%2 == 0) {
+					*(target_pixels + i*rowstride + j*(has_alpha?4:3)) = intensity/2 + 127;
+					*(target_pixels + i*rowstride + j*(has_alpha?4:3) + 1) = intensity/2 + 127;
+					*(target_pixels + i*rowstride + j*(has_alpha?4:3) + 2) = intensity/2 + 127;
+				} else if (pixelate) {
+#define DARK_FACTOR 0.7
+					*(target_pixels + i*rowstride + j*(has_alpha?4:3)) =
+						(guchar) (((1.0 - saturation) * intensity
+							   + saturation * (*(current_pixel)))) * DARK_FACTOR;
+					*(target_pixels + i*rowstride + j*(has_alpha?4:3) + 1) =
+						(guchar) (((1.0 - saturation) * intensity
+							   + saturation * (*(current_pixel + 1)))) * DARK_FACTOR;
+					*(target_pixels + i*rowstride + j*(has_alpha?4:3) + 2) =
+						(guchar) (((1.0 - saturation) * intensity
+							   + saturation * (*(current_pixel + 2)))) * DARK_FACTOR;
+				} else {
+					*(target_pixels + i*rowstride + j*(has_alpha?4:3)) =
+						(guchar) ((1.0 - saturation) * intensity
+							  + saturation * (*(current_pixel)));
+					*(target_pixels + i*rowstride + j*(has_alpha?4:3) + 1) =
+						(guchar) ((1.0 - saturation) * intensity
+							  + saturation * (*(current_pixel + 1)));
+					*(target_pixels + i*rowstride + j*(has_alpha?4:3) + 2) =
+						(guchar) ((1.0 - saturation) * intensity
+							  + saturation * (*(current_pixel + 2)));
+				}
+				if (has_alpha)
+					*(target_pixels + i*rowstride + j*(has_alpha?4:3) + 3) = *(original_pixels + i*rowstride + j*(has_alpha?4:3) + 3);
+			}
+		}
+
+                return target;
+	}
+}
diff --git a/libgnomeui/gnome-pixmap.h b/libgnomeui/gnome-pixmap.h
new file mode 100644
index 0000000..93f98ab
--- /dev/null
+++ b/libgnomeui/gnome-pixmap.h
@@ -0,0 +1,145 @@
+/*  -*- Mode: C; c-set-style: linux; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+
+   Copyright (C) 1999, 2000 Red Hat, Inc.
+   All rights reserved.
+    
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   GnomePixmap Developers: Havoc Pennington, Jonathan Blandford
+*/
+/*
+  @NOTATION@
+*/
+
+#ifndef GNOME_PIXMAP_H
+#define GNOME_PIXMAP_H
+
+#include <gtk/gtkmisc.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+
+
+G_BEGIN_DECLS
+
+typedef enum {
+        /* update struct when adding enum values */
+	GNOME_PIXMAP_SIMPLE, /* No alpha blending */
+	GNOME_PIXMAP_COLOR   /* */
+} GnomePixmapDrawMode;
+
+#define GNOME_TYPE_PIXMAP            (gnome_pixmap_get_type ())
+#define GNOME_PIXMAP(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_PIXMAP, GnomePixmap))
+#define GNOME_PIXMAP_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_PIXMAP, GnomePixmapClass))
+#define GNOME_IS_PIXMAP(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_PIXMAP))
+#define GNOME_IS_PIXMAP_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_PIXMAP))
+#define GNOME_PIXMAP_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_PIXMAP, GnomePixmapClass))
+
+
+typedef struct _GnomePixmap GnomePixmap;
+typedef struct _GnomePixmapClass GnomePixmapClass;
+
+struct _GnomePixmap {
+	GtkMisc misc;
+
+        /* NOTE. In the old GnomePixmap, _lots_ of people were using GnomePixmap to
+	 * load images, sucking out the pixmap field, and then not using the
+	 * GnomePixmap as a widget at all. IF YOU DO THIS I WILL PERSONALLY
+	 * KICK YOUR ASS. Use gdk_pixbuf_new_from_file(). Thank you.
+	 * These are PRIVATE FIELDS which I will gratuitously change just to
+	 * break your broken code.
+	 *                          -  hp + jrb + quartic + Jesse Ventura + GW Bush 
+	 */
+
+	GdkPixbuf *provided_image;
+
+        struct {
+                GdkPixbuf *pixbuf;
+                GdkBitmap *mask;
+		gfloat saturation;
+		gboolean pixelate;
+        } provided[5]; /* the five states */
+
+	GdkPixbuf *generated_scaled_image;
+	GdkBitmap *generated_scaled_mask;
+        
+        struct {
+                GdkPixbuf *pixbuf;
+                GdkBitmap *mask;
+        } generated[5]; /* the five states */
+        
+	gint width, height;
+	gint alpha_threshold;
+
+	GnomePixmapDrawMode mode : 2;
+};
+
+
+struct _GnomePixmapClass {
+	GtkMiscClass parent_class;
+};
+
+guint           gnome_pixmap_get_type                (void) G_GNUC_CONST;
+GtkWidget      *gnome_pixmap_new                     (void);
+GtkWidget      *gnome_pixmap_new_from_file           (const gchar      *filename);
+GtkWidget      *gnome_pixmap_new_from_file_at_size   (const gchar      *filename,
+						      gint              width,
+						      gint              height);
+GtkWidget      *gnome_pixmap_new_from_xpm_d          (const gchar     **xpm_data);
+GtkWidget      *gnome_pixmap_new_from_xpm_d_at_size  (const gchar     **xpm_data,
+						      gint              width,
+						      gint              height);
+GtkWidget      *gnome_pixmap_new_from_pixbuf         (GdkPixbuf        *pixbuf);
+GtkWidget      *gnome_pixmap_new_from_pixbuf_at_size (GdkPixbuf        *pixbuf,
+						      gint              width,
+						      gint              height);
+void            gnome_pixmap_set_pixbuf_size         (GnomePixmap      *gpixmap,
+						      gint              width,
+						      gint              height);
+void            gnome_pixmap_get_pixbuf_size         (GnomePixmap      *gpixmap,
+						      gint             *width,
+						      gint             *height);
+void            gnome_pixmap_set_pixbuf              (GnomePixmap      *gpixmap,
+						      GdkPixbuf        *pixbuf);
+GdkPixbuf      *gnome_pixmap_get_pixbuf              (GnomePixmap      *gpixmap);
+   
+/* Sets the individual states, instead of generating them. */
+void            gnome_pixmap_set_pixbuf_at_state     (GnomePixmap      *gpixmap,
+						      GtkStateType      state,
+						      GdkPixbuf        *pixbuf,
+						      GdkBitmap        *mask);
+void            gnome_pixmap_set_state_pixbufs       (GnomePixmap      *gpixmap,
+                                                      GdkPixbuf        *pixbufs[5],
+                                                      GdkBitmap        *masks[5]);
+void            gnome_pixmap_set_draw_vals           (GnomePixmap      *gpixmap,
+						      GtkStateType      state,
+						      gfloat            saturation,
+						      gboolean          pixelate);
+void            gnome_pixmap_get_draw_vals           (GnomePixmap      *gpixmap,
+						      GtkStateType      state,
+						      gfloat           *saturation,
+						      gboolean         *pixelate);
+void            gnome_pixmap_set_draw_mode           (GnomePixmap      *gpixmap,
+						      GnomePixmapDrawMode   mode);
+GnomePixmapDrawMode gnome_pixmap_get_draw_mode       (GnomePixmap      *gpixmap);
+void            gnome_pixmap_clear                   (GnomePixmap      *gpixmap);
+void            gnome_pixmap_set_alpha_threshold     (GnomePixmap      *gpixmap,
+						      gint              alpha_threshold);
+gint            gnome_pixmap_get_alpha_threshold     (GnomePixmap      *gpixmap);
+
+
+G_END_DECLS
+
+#endif /* __GNOME_PIXMAP_H__ */
diff --git a/libgnomeui/gnome-popup-help.c b/libgnomeui/gnome-popup-help.c
new file mode 100644
index 0000000..77a6563
--- /dev/null
+++ b/libgnomeui/gnome-popup-help.c
@@ -0,0 +1,510 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* Popup menus for GNOME
+ * 
+ * Copyright (C) 1998 Jonathan Blandford
+ * All rights reserved.
+ *
+ * Authors: Jonathan Blandford <jrb redhat com>
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <config.h>
+#include <gtk/gtkdrawingarea.h>
+#include <gtk/gtkwidget.h>
+#include <gtk/gtkeditable.h>
+#include <gtk/gtkentry.h>
+
+#include <libgnome/gnome-i18n.h>
+#include "gnome-app.h"
+#include "gnome-stock.h"
+#include "gnome-popup-help.h"
+#include "gnome-popup-menu.h"
+
+/* Prototypes */
+static void help_callback (GtkWidget *widget, gpointer data);
+static void helpwindow_destroy_callback (GtkWidget *widget, gpointer data);
+static void cut_callback (GtkWidget *widget, gpointer data);
+static void copy_callback (GtkWidget *widget, gpointer data);
+static void paste_callback (GtkWidget *widget, gpointer data);
+static gint popup_pre_callback (GtkWidget *widget, GdkEventButton *event, GnomeUIInfo *cutptr);
+static GnomeUIInfo *append_ui_info (GnomeUIInfo *base, GnomeUIInfo *info, GnomeUIInfo **cutptr);
+
+static GnomeUIInfo separator[] = {
+        {GNOME_APP_UI_SEPARATOR},
+        {GNOME_APP_UI_ENDOFINFO, NULL, NULL, NULL, NULL, NULL,
+         GNOME_APP_PIXMAP_NONE, NULL, 0, 0, NULL}
+};
+static GnomeUIInfo helpmenu[] = {
+        {GNOME_APP_UI_ITEM, N_("_Help with this"), NULL, help_callback, NULL, NULL,
+         GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_ABOUT, 0, 0, NULL},
+        {GNOME_APP_UI_ENDOFINFO, NULL, NULL, NULL, NULL, NULL,
+         GNOME_APP_PIXMAP_NONE, NULL, 0, 0, NULL}
+};
+static GnomeUIInfo cutcopymenu[] = {
+        {GNOME_APP_UI_ITEM, N_("Cu_t"), NULL, cut_callback, NULL, NULL,
+         GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_CUT, 0, 0, NULL},
+        {GNOME_APP_UI_ITEM, N_("_Copy"), NULL, copy_callback, NULL, NULL,
+         GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_COPY, 0, 0, NULL},
+        {GNOME_APP_UI_ITEM, N_("_Paste"), NULL, paste_callback, NULL, NULL,
+         GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_PASTE, 0, 0, NULL},
+        {GNOME_APP_UI_ENDOFINFO, NULL, NULL, NULL, NULL, NULL,
+         GNOME_APP_PIXMAP_NONE, NULL, 0, 0, NULL}
+};
+
+/* Note: Taken mostly from GtkTooltipsData from GTK+ 1.2 */
+typedef struct _PopupData PopupData;
+struct _PopupData
+{
+  GdkFont *font;
+  gint width;
+  GList *row;
+};
+
+
+static void
+gtk_tooltips_free_string (gpointer data, gpointer user_data)
+{
+  if (data)
+    g_free (data);
+}
+
+static void
+gnome_popup_help_layout_text (GtkWidget *helpwindow, PopupData *data, gchar* text)
+     /* Swiped from gtktooltips.c  (: */
+{
+  gchar *row_end, *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 = helpwindow->style->font;
+  data->width = 0;
+
+
+  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 */
+}
+
+static gint
+gnome_popup_help_expose (GtkWidget *darea, GdkEventExpose *event, PopupData *data)
+{
+        GtkStyle *style;
+        gint y, baseline_skip, gap;
+        GList *el;
+      
+        style = darea->style;
+        
+        gap = (style->font->ascent + style->font->descent) / 4;
+        if (gap < 2)
+                gap = 2;
+        baseline_skip = style->font->ascent + style->font->descent + gap;
+
+        gtk_paint_flat_box(style, darea->window,
+                           GTK_STATE_NORMAL, GTK_SHADOW_OUT, 
+                           NULL, GTK_WIDGET(darea), "tooltip",
+                           0, 0, -1, -1);
+
+        y = style->font->ascent + 4;
+  
+        for (el = data->row; el; el = el->next) {
+                if (el->data) {
+                        gtk_paint_string (style, darea->window, 
+                                          GTK_STATE_NORMAL, 
+                                          NULL, GTK_WIDGET(darea), "tooltip",
+                                          4, y, el->data);
+                        y += baseline_skip;
+                }
+                else
+                        y += baseline_skip / 2;
+        }
+        return FALSE;
+}
+
+static void
+gnome_popup_help_size_window (GtkWidget *helpwindow, PopupData *data, gint *h, gint *w)
+{
+  GtkStyle *style;
+  gint gap, baseline_skip;
+  GList *el;
+
+  style = helpwindow->style;
+
+  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;
+
+  gtk_widget_set_usize (helpwindow, *w + 1, *h + 1);
+}
+
+static void
+gnome_popup_help_place_window (GtkWidget *helpwindow, GtkWidget *widget, PopupData *data, gint h, gint w)
+{
+  gint x, y, scr_w, scr_h;
+
+  scr_w = gdk_screen_width ();
+  scr_h = gdk_screen_height ();
+
+  gdk_window_get_pointer (NULL, &x, NULL, NULL);
+  gdk_window_get_origin (widget->window, NULL, &y);
+  if (GTK_WIDGET_NO_WINDOW (widget))
+    y += widget->allocation.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_uposition (helpwindow, x, y);
+  gtk_widget_show_now (helpwindow);
+}
+
+static GnomeUIInfo *
+append_ui_info (GnomeUIInfo *base, GnomeUIInfo *info, GnomeUIInfo **cutptr)
+{
+        GnomeUIInfo *retval;
+        gint j, i = 0;
+
+	for (retval = base; retval&&retval->type != GNOME_APP_UI_ENDOFINFO; retval++, i++);
+	for (retval = info; retval&&retval->type != GNOME_APP_UI_ENDOFINFO; retval++, i++);
+        retval = g_new (GnomeUIInfo, i+1);
+
+        for (i = 0;base&&base->type != GNOME_APP_UI_ENDOFINFO; base++, i++) {
+                retval[i] = base[0];
+        }
+
+        if (info == cutcopymenu)
+                *cutptr = retval + i;
+        for (j = 0;info&&info->type != GNOME_APP_UI_ENDOFINFO; info++, j++) {
+                retval[i + j] = info[0];
+        }
+
+        /* get the GNOME_APP_UI_ENDOFINFO */
+        retval[i+j] = info[0];
+
+        /* er, i should free base here... */
+        return retval;
+}
+
+static void
+helpwindow_click_callback (GtkWidget *widget, gpointer data)
+{
+        gtk_widget_hide (widget->parent);
+        gdk_pointer_ungrab (GDK_CURRENT_TIME);
+
+}
+
+static void
+helpwindow_destroy_callback (GtkWidget *widget, gpointer data)
+{
+        g_free ((gchar*) data);
+}
+
+static void
+help_callback (GtkWidget *menu, gpointer unused)
+{
+        PopupData *data;
+        gint h, w;
+        GtkWidget *widget, *helpwindow, *darea;
+
+        gchar *text;
+
+
+        /* get the */
+        text = (gchar *) (gtk_object_get_data (GTK_OBJECT (menu->parent), 
+                                                "gnome_popup_help_text"));
+        helpwindow = gtk_object_get_data (GTK_OBJECT (menu->parent),
+                                                      "gnome_popup_help_window");
+        widget = gtk_object_get_data (GTK_OBJECT (menu->parent), 
+                                      "gnome_popup_help_widget");
+        data = gtk_object_get_data (GTK_OBJECT (menu->parent), 
+                                    "gnome_popup_help_data");
+        if (helpwindow == NULL) {
+                data = g_new0 (PopupData, 1);
+                data->row = NULL;
+
+                helpwindow = gtk_window_new (GTK_WINDOW_POPUP);
+                gtk_window_set_policy (GTK_WINDOW (helpwindow), FALSE, FALSE, TRUE);
+                
+                darea = gtk_drawing_area_new ();
+                gtk_widget_set_events (darea, GDK_BUTTON_PRESS_MASK);
+                gtk_container_add (GTK_CONTAINER (helpwindow), darea);
+                gtk_widget_show (darea);
+
+                gnome_popup_help_layout_text (helpwindow, data, text);
+                gnome_popup_help_size_window (helpwindow, data, &h, &w);
+                gnome_popup_help_place_window (helpwindow, widget, data, h, w);
+
+                gtk_signal_connect (GTK_OBJECT (darea), "expose_event",
+                                    GTK_SIGNAL_FUNC (gnome_popup_help_expose), 
+                                    data);
+                gtk_signal_connect (GTK_OBJECT (darea), "button_press_event",
+                                    GTK_SIGNAL_FUNC (helpwindow_click_callback), 
+                                    NULL);
+                gtk_signal_connect (GTK_OBJECT (helpwindow),
+                                    "destroy",
+                                    GTK_SIGNAL_FUNC (helpwindow_destroy_callback),
+                                    text);
+                gtk_object_set_data (GTK_OBJECT (menu->parent), 
+                                     "gnome_popup_help_data", data);
+                gtk_object_set_data (GTK_OBJECT (menu->parent), 
+                                     "gnome_popup_help_window", helpwindow);
+
+                gdk_pointer_grab (darea->window,
+                                  FALSE,
+                                  GDK_BUTTON_PRESS_MASK,
+                                  NULL,
+                                  NULL,
+                                  GDK_CURRENT_TIME);
+        } else {
+                gnome_popup_help_place_window (helpwindow, widget, 
+                                               data, 
+                                               helpwindow->allocation.height,
+                                               helpwindow->allocation.width);
+                gdk_flush ();
+                gdk_pointer_grab (GTK_BIN(helpwindow)->child->window,
+                                  FALSE,
+                                  GDK_BUTTON_PRESS_MASK,
+                                  NULL,
+                                  NULL,
+                                  GDK_CURRENT_TIME);
+        }
+
+}
+
+static gint
+popup_pre_callback (GtkWidget *widget, GdkEventButton *event, GnomeUIInfo *cutptr) 
+{
+        if (event->button != 3)
+		return FALSE;
+
+#if 0 /* FIXME !!! FIXME !!! FIXME */
+
+        if (GTK_EDITABLE (widget)->selection_start_pos == GTK_EDITABLE (widget)->selection_end_pos) {
+                gtk_widget_set_sensitive (cutptr[0].widget, FALSE);
+                gtk_widget_set_sensitive (cutptr[1].widget, FALSE);
+        } else {
+                gtk_widget_set_sensitive (cutptr[0].widget, TRUE);
+                gtk_widget_set_sensitive (cutptr[1].widget, TRUE);
+        }
+
+        if (GTK_EDITABLE (widget)->editable)
+                gtk_widget_set_sensitive (cutptr[2].widget, TRUE);
+        else
+                gtk_widget_set_sensitive (cutptr[2].widget, FALSE);
+
+#endif
+        
+        return FALSE;
+}
+
+
+static void
+cut_callback (GtkWidget *widget, gpointer data)
+{
+        GtkWidget *editable;
+        editable = GTK_WIDGET (gtk_object_get_data (GTK_OBJECT (widget->parent), 
+                                                    "gnome_popup_help_widget"));
+        gtk_editable_cut_clipboard (GTK_EDITABLE (editable));
+}
+
+static void
+copy_callback (GtkWidget *widget, gpointer data)
+{
+        GtkWidget *editable;
+        editable = GTK_WIDGET (gtk_object_get_data (GTK_OBJECT (widget->parent), 
+                                                    "gnome_popup_help_widget"));
+        gtk_editable_copy_clipboard (GTK_EDITABLE (editable));
+}
+
+static void
+paste_callback (GtkWidget *widget, gpointer data)
+{
+        GtkWidget *editable;
+        editable = GTK_WIDGET (gtk_object_get_data (GTK_OBJECT (widget->parent), 
+                                                    "gnome_popup_help_widget"));
+        gtk_editable_paste_clipboard (GTK_EDITABLE (editable));
+}
+
+
+/**
+ * gnome_widget_add_help_with_uidata:
+ * @widget: The widget to add the popup help to.
+ * @help: The help message text.
+ * @menuinfo: The template for possible additional menu items.
+ * @user_data: The user data to be passed to menu callbacks.
+ * 
+ * This creates a popup menu on @widget with one entry.  The menu, invoked by
+ * pressing button three on the widget, will have one entry entitled: "Help with
+ * this."  Selecting this entry will bring up a tooltip with the help variable
+ * as its text.  In addition, if the widget is a descendent of #GtkEditable, it
+ * will add "cut", "copy", and "paste" to the menu.  If @help is NULL, then it
+ * will <emphasis>just</emphasis> add the "cut", "copy", and "paste".  Finally,
+ * if @menuinfo is non-NULL, it will append the menu defined by it on the end of
+ * the popup menu, with @user_data passed to the callbacks.  This function
+ * currently only works on non GTK_WIDGET_NO_WINDOW () widgets (ie. it only
+ * works on widgets with windows.)  If you would actually like a handle to the
+ * popup menu, call gnome_popup_menu_get() as normal.
+
+ * 
+ * Return value: 
+ **/
+/* public function. */
+void
+gnome_widget_add_help_with_uidata (GtkWidget *widget,
+				   const gchar *help,
+				   GnomeUIInfo *menuinfo,
+                                   gpointer user_data)
+{
+        GnomeUIInfo *finalmenu = NULL;
+        GtkWidget *menu;
+        GnomeUIInfo *cutptr = NULL;
+
+        g_return_if_fail (widget != NULL);
+	g_return_if_fail (GTK_IS_WIDGET (widget));
+	g_return_if_fail (GTK_IS_WIDGET (widget));
+
+        /* set up the menu type */
+        if (help != NULL) {
+                finalmenu = append_ui_info (finalmenu, helpmenu, NULL);
+        }
+        if (GTK_IS_EDITABLE (widget)) {
+                if (help != NULL)
+                        finalmenu = append_ui_info (finalmenu, separator, NULL);
+                finalmenu = append_ui_info (finalmenu, cutcopymenu, &cutptr);
+        }
+
+        if (menuinfo != NULL) {
+                if ((help != NULL) || (GTK_IS_EDITABLE (widget)))
+                        finalmenu = append_ui_info (finalmenu, separator, NULL);
+                finalmenu = append_ui_info (finalmenu, menuinfo, NULL);
+        }
+        
+        if (finalmenu == NULL)
+                /* hmmm, no tooltip set, no extra data, and no cut copy paste.
+                 * we do nothing then.*/
+                return;
+
+        menu = gnome_popup_menu_new (finalmenu);
+        /* now, we tweak. */
+        if (GTK_IS_EDITABLE (widget)) {
+                gtk_signal_connect (GTK_OBJECT (widget), "button_press_event",
+                                    (GtkSignalFunc) popup_pre_callback,
+                                    cutptr);
+        }
+        gnome_popup_menu_attach (menu, widget, user_data);
+        
+        if (help != NULL) {
+                /* set the tool tip! */
+                gtk_object_set_data (GTK_OBJECT (menu), 
+                                     "gnome_popup_help_text",g_strdup(help));
+                gtk_object_set_data (GTK_OBJECT (menu), 
+                                     "gnome_popup_help_widget", widget);
+        }
+}
diff --git a/libgnomeui/gnome-popup-help.h b/libgnomeui/gnome-popup-help.h
new file mode 100644
index 0000000..1cebd5c
--- /dev/null
+++ b/libgnomeui/gnome-popup-help.h
@@ -0,0 +1,48 @@
+/* Popup menus for GNOME
+ * 
+ * Copyright (C) 1998 Jonathan Blandford
+ * All rights reserved.
+ *
+ * Authors: Jonathan Blandford <jrb mit edu>
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#ifndef GNOME_POPUP_HELP_H
+#define GNOME_POPUP_HELP_H
+
+
+#include <libgnomeui/gnome-app.h>
+#include <libgnomeui/gnome-app-helper.h>
+
+
+G_BEGIN_DECLS
+
+#define gnome_widget_add_help(widget, help) \
+	(gnome_widget_add_help_with_uidata((widget),(help),NULL, NULL))
+void gnome_widget_add_help_with_uidata  (GtkWidget *widget,
+					 const gchar *help,
+					 GnomeUIInfo *menuinfo,
+					 gpointer user_data);
+
+
+
+G_END_DECLS
+
+#endif
+
diff --git a/libgnomeui/gnome-popup-menu.c b/libgnomeui/gnome-popup-menu.c
new file mode 100644
index 0000000..c62d4e6
--- /dev/null
+++ b/libgnomeui/gnome-popup-menu.c
@@ -0,0 +1,525 @@
+/* Popup menus for GNOME
+ * 
+ * Copyright (C) 1998 Mark Crichton
+ * All rights reserved.
+ *
+ * Authors: Mark Crichton <mcrichto purdue edu>
+ *          Federico Mena <federico nuclecu unam mx>
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#include <config.h>
+#include <gtk/gtk.h>
+#include "gnome-popup-menu.h"
+
+static GtkWidget* global_menushell_hack = NULL;
+#define TOPLEVEL_MENUSHELL_KEY "gnome-popup-menu:toplevel_menushell_key"
+
+/* This is our custom signal connection function for popup menu items -- see below for the
+ * marshaller information.  We pass the original callback function as the data pointer for the
+ * marshaller (uiinfo->moreinfo).
+ */
+static void
+popup_connect_func (GnomeUIInfo *uiinfo, const char *signal_name, GnomeUIBuilderData *uibdata)
+{
+	g_assert (uibdata->is_interp);
+
+	gtk_object_set_data (GTK_OBJECT (uiinfo->widget), 
+			     TOPLEVEL_MENUSHELL_KEY, 
+			     global_menushell_hack);
+
+	gtk_signal_connect_full (GTK_OBJECT (uiinfo->widget), signal_name,
+				 NULL,
+				 uibdata->relay_func,
+				 uiinfo->moreinfo,
+				 uibdata->destroy_func,
+				 FALSE,
+				 FALSE);
+}
+
+static GtkWidget* 
+get_toplevel(GtkWidget* menuitem)
+{
+	return gtk_object_get_data (GTK_OBJECT (menuitem),
+				    TOPLEVEL_MENUSHELL_KEY);
+}
+
+/* Our custom marshaller for menu items.  We need it so that it can extract the per-attachment
+ * user_data pointer from the parent menu shell and pass it to the callback.  This overrides the
+ * user-specified data from the GnomeUIInfo structures.
+ */
+
+typedef void (* ActivateFunc) (GtkObject *object, gpointer data, GtkWidget *for_widget);
+
+static void
+popup_marshal_func (GtkObject *object, gpointer data, guint n_args, GtkArg *args)
+{
+	ActivateFunc func;
+	gpointer user_data;
+	GtkObject *tl;
+	GtkWidget *for_widget;
+
+	tl = GTK_OBJECT (get_toplevel(GTK_WIDGET (object)));
+	user_data = gtk_object_get_data (tl, "gnome_popup_menu_do_popup_user_data");
+	for_widget = gtk_object_get_data (tl, "gnome_popup_menu_do_popup_for_widget");
+
+	gtk_object_set_data (GTK_OBJECT (get_toplevel(GTK_WIDGET (object))),
+			     "gnome_popup_menu_active_item",
+			     object);
+
+	func = (ActivateFunc) data;
+	if (func)
+		(* func) (object, user_data, for_widget);
+}
+
+/**
+ * gnome_popup_menu_new_with_accelgroup
+ * @uiinfo:
+ * @accelgroup:
+ *
+ * Creates a popup menu out of the specified uiinfo array.  Use
+ * gnome_popup_menu_do_popup() to pop the menu up, or attach it to a
+ * window with gnome_popup_menu_attach().
+ *
+ * Returns a menu widget
+ */
+GtkWidget *
+gnome_popup_menu_new_with_accelgroup (GnomeUIInfo *uiinfo,
+				      GtkAccelGroup *accelgroup)
+{
+	GtkWidget *menu;
+	GtkAccelGroup *my_accelgroup;
+
+	/* We use our own callback marshaller so that it can fetch the
+	 * popup user data from the popup menu and pass it on to the
+	 * user-defined callbacks.
+	 */
+
+	menu = gtk_menu_new ();
+
+	if(accelgroup)
+	  my_accelgroup = accelgroup;
+	else
+	  my_accelgroup = gtk_accel_group_new();
+	gtk_menu_set_accel_group (GTK_MENU (menu), my_accelgroup);
+	if(!accelgroup)
+	  gtk_accel_group_unref(my_accelgroup);
+
+	gnome_popup_menu_append (menu, uiinfo);
+
+	return menu;
+}
+
+/**
+ * gnome_popup_menu_new
+ * @uiinfo:
+ *
+ * This function behaves just like
+ * gnome_popup_menu_new_with_accelgroup(), except that it creates an
+ * accelgroup for you and attaches it to the menu object.  Use
+ * gnome_popup_menu_get_accel_group() to get the accelgroup that is
+ * created.
+ *
+ * Returns a menu widget
+ *
+ */
+GtkWidget *
+gnome_popup_menu_new (GnomeUIInfo *uiinfo)
+{
+  return gnome_popup_menu_new_with_accelgroup(uiinfo, NULL);
+}
+
+/**
+ * gnome_popup_menu_get_accel_group
+ * @menu: 
+ *
+ * Returns the accelgroup associated with the specified GtkMenu.  This
+ * is the accelgroup that was created by gnome_popup_menu_new().  If
+ * you want to specify the accelgroup that the popup menu accelerators
+ * use, then use gnome_popup_menu_new_with_accelgroup().
+ */
+GtkAccelGroup *
+gnome_popup_menu_get_accel_group(GtkMenu *menu)
+{
+	g_return_val_if_fail (menu != NULL, NULL);
+        g_return_val_if_fail (GTK_IS_MENU (menu), NULL);
+
+#if GTK_CHECK_VERSION(1,2,1)
+        return gtk_menu_get_accel_group (menu);
+#else
+	return NULL;
+#endif
+}
+
+/* Callback used when a button is pressed in a widget attached to a popup menu.  It decides whether
+ * the menu should be popped up and does the appropriate stuff.
+ */
+static gint
+real_popup_button_pressed (GtkWidget *widget, GdkEventButton *event, gpointer data)
+{
+	GtkWidget *popup;
+	gpointer user_data;
+
+	popup = data;
+
+	/*
+	 * Fetch the attachment user data from the widget and install
+	 * it in the popup menu -- it will be used by the callback
+	 * mashaller to pass the data to the callbacks.
+	 *
+	 */
+
+	user_data = gtk_object_get_data (GTK_OBJECT (widget), "gnome_popup_menu_attach_user_data");
+
+	gnome_popup_menu_do_popup (popup, NULL, NULL, event, user_data, widget);
+
+	return TRUE;
+}
+
+static gint
+popup_button_pressed (GtkWidget *widget, GdkEventButton *event, gpointer data)
+{
+	if (event->button != 3)
+		return FALSE;
+
+	gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "button_press_event");
+
+	return real_popup_button_pressed (widget, event, data);
+}
+
+static gint
+relay_popup_button_pressed (GtkWidget *widget, GdkEventButton *event, gpointer data)
+{
+        GtkWidget *new_widget = NULL;
+
+	if (event->button != 3)
+		return FALSE;
+
+	gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "button_press_event");
+
+	if (GTK_IS_CONTAINER(widget))
+	  {
+
+	    do {
+	      GList *children;
+
+	      for (children = gtk_container_children(GTK_CONTAINER(widget)), new_widget = NULL;
+		   children; children = children->next)
+		{
+		  GtkWidget *cur;
+		  
+		  cur = (GtkWidget *)children->data;
+		  
+		  if(! GTK_WIDGET_NO_WINDOW(cur) )
+		    continue;
+		  
+		  if(cur->allocation.x <= event->x
+		     && cur->allocation.y <= event->y
+		     && (cur->allocation.x + cur->allocation.width) > event->x
+		     && (cur->allocation.y + cur->allocation.height) > event->y
+		     && gtk_object_get_data (GTK_OBJECT(cur), "gnome_popup_menu_nowindow"))
+		    {
+		      new_widget = cur;
+		      break;
+		    }
+		}
+	      if(new_widget)
+		widget = new_widget;
+	      else
+		break;
+	    } while(widget && GTK_IS_CONTAINER (widget) && GTK_WIDGET_NO_WINDOW(widget));
+
+	    if(!widget || !gtk_object_get_data (GTK_OBJECT(widget), "gnome_popup_menu"))
+	      {
+		return TRUE;
+	      }
+	  }
+	else
+	  new_widget = widget;
+
+	return real_popup_button_pressed (new_widget, event, data);
+}
+
+
+/* Callback used to unref the popup menu when the widget it is attached to gets destroyed */
+static void
+popup_attach_widget_destroyed (GtkWidget *widget, gpointer data)
+{
+	GtkWidget *popup;
+
+	popup = data;
+
+	gtk_object_unref (GTK_OBJECT (popup));
+}
+
+/**
+ * gnome_popup_menu_attach:
+ * @popup:
+ * @widget:
+ * @user_data:
+ *
+ * Attaches the specified popup menu to the specified widget.  The
+ * menu can then be activated by pressing mouse button 3 over the
+ * widget.  When a menu item callback is invoked, the specified
+ * user_data will be passed to it.
+ *
+ * This function requires the widget to have its own window
+ * (i.e. GTK_WIDGET_NO_WINDOW (widget) == FALSE), This function will
+ * try to set the GDK_BUTTON_PRESS_MASK flag on the widget's event
+ * mask if it does not have it yet; if this is the case, then the
+ * widget must not be realized for it to work.
+ *
+ * The popup menu can be attached to different widgets at the same
+ * time.  A reference count is kept on the popup menu; when all the
+ * widgets it is attached to are destroyed, the popup menu will be
+ * destroyed as well.
+ *
+ * Under the current implementation, setting a popup menu for a NO_WINDOW widget and then reparenting
+ * that widget will cause Bad Things to happen.
+ */
+void
+gnome_popup_menu_attach (GtkWidget *popup, GtkWidget *widget,
+			 gpointer user_data)
+{
+        GtkWidget *ev_widget;
+
+	g_return_if_fail (popup != NULL);
+	g_return_if_fail (GTK_IS_MENU (popup));
+	g_return_if_fail (widget != NULL);
+	g_return_if_fail (GTK_IS_WIDGET (widget));
+
+	if(gtk_object_get_data (GTK_OBJECT (widget), "gnome_popup_menu"))
+	  return;
+
+	gtk_object_set_data (GTK_OBJECT (widget), "gnome_popup_menu", popup);
+
+	/* This operation can fail if someone is trying to set a popup on e.g. an uncontained label, so we do it first. */
+	for(ev_widget = widget; ev_widget && GTK_WIDGET_NO_WINDOW(ev_widget); ev_widget = ev_widget->parent)
+	  {
+	    gtk_object_set_data (GTK_OBJECT (ev_widget), "gnome_popup_menu_nowindow", GUINT_TO_POINTER(1));
+	  }
+
+	g_return_if_fail (ev_widget);
+
+	/* Ref/sink the popup menu so that we take "ownership" of it */
+
+	gtk_object_ref (GTK_OBJECT (popup));
+	gtk_object_sink (GTK_OBJECT (popup));
+
+	/* Store the user data pointer in the widget -- we will use it later when the menu has to be
+	 * invoked.
+	 */
+
+	gtk_object_set_data (GTK_OBJECT (widget), "gnome_popup_menu_attach_user_data", user_data);
+	gtk_object_set_data (GTK_OBJECT (widget), "gnome_popup_menu", user_data);
+
+	/* Prepare the widget to accept button presses -- the proper assertions will be
+	 * shouted by gtk_widget_set_events().
+	 */
+
+	gtk_widget_add_events (ev_widget, GDK_BUTTON_PRESS_MASK);
+
+	gtk_signal_connect (GTK_OBJECT (widget), "button_press_event",
+			    GTK_SIGNAL_FUNC (popup_button_pressed), popup);
+
+	if (ev_widget != widget)
+	  gtk_signal_connect_while_alive (GTK_OBJECT (ev_widget), "button_press_event",
+					  (GtkSignalFunc) relay_popup_button_pressed,
+					  popup, GTK_OBJECT(widget));
+
+	/* This callback will unref the popup menu when the widget it is attached to gets destroyed. */
+	gtk_signal_connect (GTK_OBJECT (widget), "destroy",
+			    (GtkSignalFunc) popup_attach_widget_destroyed,
+			    popup);
+}
+
+/**
+ * gnome_popup_menu_do_popup:
+ * @popup:
+ * @pos_func:
+ * @pos_data:
+ * @event:
+ * @user_data:
+ *
+ *
+ * You can use this function to pop up a menu.  When a menu item *
+ * callback is invoked, the specified user_data will be passed to it.
+ *
+ * The pos_func and pos_data parameters are the same as for
+ * gtk_menu_popup(), i.e. you can use them to specify a function to
+ * position the menu explicitly.  If you want the default position
+ * (near the mouse), pass NULL for these parameters.
+ *
+ * The event parameter is needed to figure out the mouse button that
+ * activated the menu and the time at which this happened.  If you
+ * pass in NULL, then no button and the current time will be used as
+ * defaults.
+ */
+void
+gnome_popup_menu_do_popup (GtkWidget *popup, GtkMenuPositionFunc pos_func, gpointer pos_data,
+			   GdkEventButton *event, gpointer user_data, GtkWidget *for_widget)
+{
+	guint button;
+	guint32 timestamp;
+
+	g_return_if_fail (popup != NULL);
+	g_return_if_fail (GTK_IS_WIDGET (popup));
+
+	/* Store the user data in the menu for when a callback is activated -- if it is a
+	 * Gnome-generated menu, then the user data will be passed on to callbacks by our custom
+	 * marshaller.
+	 */
+
+	gtk_object_set_data (GTK_OBJECT (popup), "gnome_popup_menu_do_popup_user_data", user_data);
+	gtk_object_set_data (GTK_OBJECT (popup), "gnome_popup_menu_do_popup_for_widget", for_widget);
+
+	if (event) {
+		button = event->button;
+		timestamp = event->time;
+	} else {
+		button = 0;
+		timestamp = GDK_CURRENT_TIME;
+	}
+
+	gtk_menu_popup (GTK_MENU (popup), NULL, NULL, pos_func, pos_data, button, timestamp);
+}
+
+/* Convenience callback to exit the main loop of a modal popup menu when it is deactivated*/
+static void
+menu_shell_deactivated (GtkMenuShell *menu_shell, gpointer data)
+{
+	gtk_main_quit ();
+}
+
+/* Returns the index of the active item in the specified menu, or -1 if none is active */
+static int
+get_active_index (GtkMenu *menu)
+{
+	GList *l;
+	GtkWidget *active;
+	int i;
+
+	active = gtk_object_get_data (GTK_OBJECT (menu), "gnome_popup_menu_active_item");
+
+	for (i = 0, l = GTK_MENU_SHELL (menu)->children; l; l = l->next, i++)
+		if (active == l->data)
+			return i;
+
+	return -1;
+}
+
+/**
+ * gnome_popup_menu_do_popup_modal:
+ * @popup:
+ * @pos_func:
+ * @pos_data:
+ * @event:
+ * @user_data:
+ * 
+ * Same as above, but runs the popup menu modally and returns the
+ * index of the selected item, or -1 if none.
+ */
+int
+gnome_popup_menu_do_popup_modal (GtkWidget *popup, GtkMenuPositionFunc pos_func, gpointer pos_data,
+				 GdkEventButton *event, gpointer user_data, GtkWidget *for_widget)
+{
+	guint id;
+	guint button;
+	guint32 timestamp;
+
+	g_return_val_if_fail (popup != NULL, -1);
+	g_return_val_if_fail (GTK_IS_WIDGET (popup), -1);
+
+	/* Connect to the deactivation signal to be able to quit our modal main loop */
+
+	id = gtk_signal_connect (GTK_OBJECT (popup), "deactivate",
+				 (GtkSignalFunc) menu_shell_deactivated,
+				 NULL);
+
+	gtk_object_set_data (GTK_OBJECT (popup), "gnome_popup_menu_active_item", NULL);
+	gtk_object_set_data (GTK_OBJECT (popup), "gnome_popup_menu_do_popup_user_data", user_data);
+	gtk_object_set_data (GTK_OBJECT (popup), "gnome_popup_menu_do_popup_for_widget", for_widget);
+
+	if (event) {
+		button = event->button;
+		timestamp = event->time;
+	} else {
+		button = 0;
+		timestamp = GDK_CURRENT_TIME;
+	}
+
+	gtk_menu_popup (GTK_MENU (popup), NULL, NULL, pos_func, pos_data, button, timestamp);
+	gtk_grab_add (popup);
+	gtk_main ();
+	gtk_grab_remove (popup);
+
+	gtk_signal_disconnect (GTK_OBJECT (popup), id);
+
+	return get_active_index (GTK_MENU (popup));
+}
+
+void
+gnome_popup_menu_append (GtkWidget *popup, GnomeUIInfo *uiinfo)
+{
+	GnomeUIBuilderData uibdata;
+	gint length;
+
+	g_return_if_fail (uiinfo != NULL);
+
+	uibdata.connect_func = popup_connect_func;
+	uibdata.data = NULL;
+	uibdata.is_interp = TRUE;
+	uibdata.relay_func = popup_marshal_func;
+	uibdata.destroy_func = NULL;
+
+	for (length = 0; uiinfo[length].type != GNOME_APP_UI_ENDOFINFO; length++)
+		if (uiinfo[length].type == GNOME_APP_UI_ITEM_CONFIGURABLE)
+			gnome_app_ui_configure_configurable (uiinfo + length);
+
+        global_menushell_hack = popup;
+	gnome_app_fill_menu_custom (GTK_MENU_SHELL (popup), uiinfo,
+				    &uibdata, gtk_menu_get_accel_group(GTK_MENU(popup)), FALSE, 0);
+        global_menushell_hack = NULL;
+}
+
+
+/**
+ * gnome_widget_add_popup_items:
+ * @widget: The widget to append popup menu items for
+ * @uiinfo: The array holding information on the menu items
+ * @user_data: The user_data to pass to the callbacks for the menu items
+ *
+ * This creates a new popup menu for the widget if none exists, and
+ * then adds the items in 'uiinfo' to the widget's popup menu.
+ */
+void
+gnome_widget_add_popup_items (GtkWidget *widget, GnomeUIInfo *uiinfo, gpointer user_data)
+{
+  GtkWidget *prev_popup;
+
+  prev_popup = gtk_object_get_data (GTK_OBJECT (widget), "gnome_popup_menu");
+
+  if(!prev_popup)
+    {
+      prev_popup = gnome_popup_menu_new(uiinfo);
+      gnome_popup_menu_attach(prev_popup, widget, user_data);
+    }
+  else
+    gnome_popup_menu_append(prev_popup, uiinfo);
+}
diff --git a/libgnomeui/gnome-popup-menu.h b/libgnomeui/gnome-popup-menu.h
new file mode 100644
index 0000000..4112109
--- /dev/null
+++ b/libgnomeui/gnome-popup-menu.h
@@ -0,0 +1,65 @@
+/* Popup menus for GNOME
+ * 
+ * Copyright (C) 1998 Mark Crichton
+ * All rights reserved
+ *
+ * Authors: Mark Crichton <mcrichto purdue edu>
+ *          Federico Mena <federico nuclecu unam mx>
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#ifndef GNOME_POPUPMENU_H
+#define GNOME_POPUPMENU_H
+
+
+#include <gtk/gtkmenu.h>
+#include <libgnomeui/gnome-app.h>
+#include <libgnomeui/gnome-app-helper.h>
+
+
+G_BEGIN_DECLS
+
+
+/* These routines are documented in gnome-popup-menu.c */
+
+GtkWidget *gnome_popup_menu_new (GnomeUIInfo *uiinfo);
+GtkWidget *gnome_popup_menu_new_with_accelgroup (GnomeUIInfo *uiinfo,
+						 GtkAccelGroup *accelgroup);
+GtkAccelGroup *gnome_popup_menu_get_accel_group(GtkMenu *menu);
+
+
+void gnome_popup_menu_attach (GtkWidget *popup, GtkWidget *widget,
+			      gpointer user_data);
+
+void gnome_popup_menu_do_popup (GtkWidget *popup, GtkMenuPositionFunc pos_func, gpointer pos_data,
+				GdkEventButton *event, gpointer user_data, GtkWidget *for_widget);
+
+int gnome_popup_menu_do_popup_modal (GtkWidget *popup, GtkMenuPositionFunc pos_func, gpointer pos_data,
+				     GdkEventButton *event, gpointer user_data, GtkWidget *for_widget);
+
+void gnome_popup_menu_append (GtkWidget *popup, GnomeUIInfo *uiinfo);
+
+/*** This layer, on top of the gnome_popup_menu_*() routines, defines a standard way of
+listing items on a widget's popup ****/
+void gnome_widget_add_popup_items (GtkWidget *widget, GnomeUIInfo *uiinfo, gpointer user_data);
+
+G_END_DECLS
+
+#endif
+
diff --git a/libgnomeui/gnome-pouch.c b/libgnomeui/gnome-pouch.c
new file mode 100644
index 0000000..a6a7a84
--- /dev/null
+++ b/libgnomeui/gnome-pouch.c
@@ -0,0 +1,916 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* gnome-pouch.c - a GnomePouch widget - WiW MDI container
+
+   Copyright (C) 2000 Jaka Mocnik
+
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Jaka Mocnik <jaka mocnik kiss uni-lj si>
+*/
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include <config.h>
+
+#include <libgnome/gnome-config.h>
+#include <libgnome/gnome-i18n.h>
+#include <libgnome/gnome-util.h>
+#include <libgnomeui/gnome-app.h>
+#include <libgnomeui/gnome-app-helper.h>
+#include <libgnomeui/gnome-popup-menu.h>
+#include "gnome-pouch.h"
+#include "gnome-roo.h"
+#include "gnome-pouchP.h"
+
+enum {
+	CLOSE_CHILD,
+	ICONIFY_CHILD,
+    UNICONIFY_CHILD,
+    MAXIMIZE_CHILD,
+	UNMAXIMIZE_CHILD,
+	SELECT_CHILD,
+	UNSELECT_CHILD,
+	LAST_SIGNAL
+};
+
+guint pouch_signals[LAST_SIGNAL];
+
+static GtkObjectClass *parent_class;
+
+static void gnome_pouch_class_init(GnomePouchClass *klass);
+static void gnome_pouch_init(GnomePouch *pouch);
+
+static gboolean gnome_pouch_button_press(GtkWidget *w, GdkEventButton *e);
+
+static void gnome_pouch_add(GtkContainer *container, GtkWidget *child);
+static void gnome_pouch_remove(GtkContainer *container, GtkWidget *child);
+
+static void gnome_pouch_maximize_child(GnomePouch *pouch, GnomeRoo *roo);
+static void gnome_pouch_unmaximize_child(GnomePouch *pouch, GnomeRoo *roo);
+static void gnome_pouch_iconify_child(GnomePouch *pouch, GnomeRoo *roo);
+static void gnome_pouch_uniconify_child(GnomePouch *pouch, GnomeRoo *roo);
+static void gnome_pouch_select_child(GnomePouch *pouch, GnomeRoo *roo);
+static void gnome_pouch_unselect_child(GnomePouch *pouch, GnomeRoo *roo);
+
+static void arrange_roo(GnomePouch *pouch, GnomeRoo *roo);
+static void set_active_items(GnomePouch *pouch);
+
+/* popup menu callbacks */
+static void tile_callback(GtkWidget *w, gpointer user_data);
+static void cascade_callback(GtkWidget *w, gpointer user_data);
+static void arrange_callback(GtkWidget *w, gpointer user_data);
+static void autoarrange_callback(GtkWidget *w, gpointer user_data);
+static void orientation_callback(GtkWidget *w, gpointer user_data);
+static void position_callback(GtkWidget *w, gpointer user_data);
+
+guint
+gnome_pouch_get_type()
+{
+	static guint pouch_type = 0;
+	
+	if (!pouch_type) {
+		GtkTypeInfo pouch_info = {
+			"GnomePouch",
+			sizeof(GnomePouch),
+			sizeof(GnomePouchClass),
+			(GtkClassInitFunc) gnome_pouch_class_init,
+			(GtkObjectInitFunc) gnome_pouch_init,
+			NULL,
+			NULL,
+			NULL
+		};
+		pouch_type = gtk_type_unique(gtk_fixed_get_type(), &pouch_info);
+	}
+	return pouch_type;
+}
+
+static void
+gnome_pouch_class_init(GnomePouchClass *klass)
+{
+	GtkContainerClass *container_class;
+	GtkWidgetClass *widget_class;
+	GtkObjectClass *object_class;
+
+	parent_class = GTK_OBJECT_CLASS(gtk_type_class(gtk_fixed_get_type()));
+	container_class = GTK_CONTAINER_CLASS(klass);
+	widget_class = GTK_WIDGET_CLASS(klass);
+	object_class = GTK_OBJECT_CLASS(klass);
+
+	pouch_signals[CLOSE_CHILD] =
+		gtk_signal_new ("close-child",
+				GTK_RUN_LAST,
+				GTK_CLASS_TYPE (object_class),
+				GTK_SIGNAL_OFFSET (GnomePouchClass, close_child),
+				gtk_marshal_VOID__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_WIDGET);
+	pouch_signals[ICONIFY_CHILD] =
+		gtk_signal_new ("iconify-child",
+				GTK_RUN_FIRST,
+				GTK_CLASS_TYPE (object_class),
+				GTK_SIGNAL_OFFSET (GnomePouchClass, iconify_child),
+				gtk_marshal_VOID__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_WIDGET);
+	pouch_signals[UNICONIFY_CHILD] =
+		gtk_signal_new ("uniconify-child",
+				GTK_RUN_FIRST,
+				GTK_CLASS_TYPE (object_class),
+				GTK_SIGNAL_OFFSET (GnomePouchClass, uniconify_child),
+				gtk_marshal_VOID__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_WIDGET);
+	pouch_signals[MAXIMIZE_CHILD] =
+		gtk_signal_new ("maximize-child",
+				GTK_RUN_FIRST,
+				GTK_CLASS_TYPE (object_class),
+				GTK_SIGNAL_OFFSET (GnomePouchClass, maximize_child),
+				gtk_marshal_VOID__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_WIDGET);
+	pouch_signals[UNMAXIMIZE_CHILD] =
+		gtk_signal_new ("unmaximize-child",
+				GTK_RUN_FIRST,
+				GTK_CLASS_TYPE (object_class),
+				GTK_SIGNAL_OFFSET (GnomePouchClass, unmaximize_child),
+				gtk_marshal_VOID__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_WIDGET);
+	pouch_signals[SELECT_CHILD] =
+		gtk_signal_new ("select-child",
+				GTK_RUN_FIRST,
+				GTK_CLASS_TYPE (object_class),
+				GTK_SIGNAL_OFFSET (GnomePouchClass, select_child),
+				gtk_marshal_VOID__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_WIDGET);
+	pouch_signals[UNSELECT_CHILD] =
+		gtk_signal_new ("unselect-child",
+				GTK_RUN_FIRST,
+				GTK_CLASS_TYPE (object_class),
+				GTK_SIGNAL_OFFSET (GnomePouchClass, unselect_child),
+				gtk_marshal_VOID__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_WIDGET);
+
+
+	widget_class->button_press_event = gnome_pouch_button_press;
+
+	container_class->add = gnome_pouch_add;
+	container_class->remove = gnome_pouch_remove;
+
+	klass->iconify_child = gnome_pouch_iconify_child;
+	klass->uniconify_child = gnome_pouch_uniconify_child;
+	klass->maximize_child = gnome_pouch_maximize_child;
+	klass->unmaximize_child = gnome_pouch_unmaximize_child;
+	klass->select_child = gnome_pouch_select_child;
+	klass->unselect_child = gnome_pouch_unselect_child;
+}
+
+static void
+gnome_pouch_init(GnomePouch *pouch)
+{
+	pouch->priv = g_new0(GnomePouchPrivate, 1);
+
+	pouch->priv->arranged = NULL;
+	pouch->priv->selected = NULL;
+	pouch->priv->popup_menu = NULL;
+
+	pouch->priv->icon_corner = GTK_CORNER_BOTTOM_LEFT;
+	pouch->priv->icon_orientation = GTK_ORIENTATION_HORIZONTAL;
+	pouch->priv->auto_arrange = TRUE;
+}
+
+static void
+gnome_pouch_add(GtkContainer *container, GtkWidget *child)
+{
+	GnomeRoo *roo;
+
+	g_return_if_fail(GNOME_IS_ROO(child));
+
+	roo = GNOME_ROO(child);
+	roo->priv->user_allocation.x = roo->priv->user_allocation.y = 0;
+	roo->priv->icon_allocation.x = roo->priv->icon_allocation.y = 0;
+
+	gtk_fixed_put(GTK_FIXED(container), child, 0, 0);
+}
+
+static void
+gnome_pouch_remove(GtkContainer *container, GtkWidget *child)
+{
+	GnomeRoo *roo;
+	GnomePouch *pouch;
+
+	g_return_if_fail(child != NULL);
+	g_return_if_fail(GNOME_IS_ROO(child));
+
+	pouch = GNOME_POUCH(container);
+	roo = GNOME_ROO(child);
+
+	if(pouch->priv->selected == roo)
+		gnome_pouch_select_roo(pouch, NULL);
+
+	if(gnome_roo_is_iconified(roo))
+		pouch->priv->arranged = g_list_remove(pouch->priv->arranged, roo);
+
+	(*GTK_CONTAINER_CLASS(parent_class)->remove)(container, child);
+}
+
+static gboolean
+gnome_pouch_button_press(GtkWidget *w, GdkEventButton *e)
+{
+	GnomePouch *pouch = GNOME_POUCH(w);
+
+	if(e->button == 1) {
+		/* unselect a possibly selected child */
+		if(pouch->priv->selected) {
+			gtk_signal_emit_by_name(GTK_OBJECT(pouch->priv->selected), "deselect",
+									NULL);
+		}
+	}
+	else if(e->button == 3 && pouch->priv->popup_menu) {
+		/* popup a menu */
+		gnome_popup_menu_do_popup(pouch->priv->popup_menu, NULL, NULL,
+								  e, pouch, GTK_WIDGET(pouch));
+		set_active_items(pouch);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+static void
+gnome_pouch_maximize_child(GnomePouch *pouch, GnomeRoo *roo)
+{
+	GtkWidget *w = GTK_WIDGET(roo);
+
+#ifdef GNOME_ENABLE_DEBUG
+	g_message("GnomePouch: maximize");
+#endif
+
+	gnome_pouch_move(pouch, roo, 0, 0);
+	gtk_widget_set_usize(w,
+						 GTK_WIDGET(pouch)->allocation.width,
+						 GTK_WIDGET(pouch)->allocation.height);
+	gdk_window_raise(w->window);
+}
+
+static void
+gnome_pouch_unmaximize_child(GnomePouch *pouch, GnomeRoo *roo)
+{
+	GtkWidget *w = GTK_WIDGET(roo);
+
+#ifdef GNOME_ENABLE_DEBUG
+	g_message("GnomePouch: unmaximize");
+#endif
+
+	if(gnome_roo_is_iconified(roo)) {
+		gtk_fixed_move(GTK_FIXED(pouch), GTK_WIDGET(roo),
+					   roo->priv->icon_allocation.x, roo->priv->icon_allocation.y);
+	}
+	else {
+		gnome_pouch_move(pouch, roo,
+						 roo->priv->user_allocation.x, roo->priv->user_allocation.y);
+		gtk_widget_set_usize(w,
+							 roo->priv->user_allocation.width,
+							 roo->priv->user_allocation.height);
+	}
+}
+
+static void
+gnome_pouch_iconify_child(GnomePouch *pouch, GnomeRoo *roo)
+{
+#ifdef GNOME_ENABLE_DEBUG
+	g_message("GnomePouch: iconify");
+#endif
+
+	if(!gnome_roo_is_parked(roo)) {
+		if(pouch->priv->auto_arrange)
+			arrange_roo(pouch, roo);
+	}
+	else {
+		gnome_pouch_move(pouch, roo,
+						 roo->priv->icon_allocation.x, roo->priv->icon_allocation.y);
+	}
+}
+
+static void
+gnome_pouch_uniconify_child(GnomePouch *pouch, GnomeRoo *roo)
+{
+#ifdef GNOME_ENABLE_DEBUG
+	g_message("GnomePouch: uniconify");
+#endif
+
+	gnome_pouch_move(pouch, roo,
+					 roo->priv->user_allocation.x, roo->priv->user_allocation.y);
+	gtk_widget_set_usize(GTK_WIDGET(roo),
+						 roo->priv->user_allocation.width,
+						 roo->priv->user_allocation.height);
+
+	pouch->priv->arranged = g_list_remove(pouch->priv->arranged, roo);
+}
+
+static void
+gnome_pouch_select_child(GnomePouch *pouch, GnomeRoo *roo)
+{
+	if(pouch->priv->selected == roo)
+		return;
+
+#ifdef GNOME_ENABLE_DEBUG
+	g_message("GnomePouch: select");
+#endif
+	if(pouch->priv->selected) 
+		gtk_signal_emit_by_name(GTK_OBJECT(pouch->priv->selected), "deselect", NULL);
+	if(roo) {
+		if(pouch->priv->selected && gnome_roo_is_maximized(pouch->priv->selected))
+			gnome_roo_set_maximized(roo, TRUE);
+		gdk_window_raise(GTK_WIDGET(roo)->window);
+	}
+	pouch->priv->selected = roo;
+}
+
+static void
+gnome_pouch_unselect_child(GnomePouch *pouch, GnomeRoo *roo)
+{
+#ifdef GNOME_ENABLE_DEBUG
+	g_message("GnomePouch: unselect");
+#endif
+	if(pouch->priv->selected == roo)
+		pouch->priv->selected = NULL;
+
+	if(gnome_roo_is_maximized(roo))
+		gnome_roo_set_maximized(roo, FALSE);
+}
+
+static void
+arrange_roo(GnomePouch *pouch, GnomeRoo *roo)
+{
+	GList *arranged, *node;
+	GnomeRoo *this_roo, *next_roo;
+	gint space = 0;
+	gint px = 0, py = 0;
+	gboolean found = FALSE, new_line = TRUE, was_new_line = FALSE; 
+
+	arranged = pouch->priv->arranged;
+
+	while(arranged && arranged->next && !found) {
+		was_new_line = new_line;
+		this_roo = GNOME_ROO(arranged->data);
+		next_roo = GNOME_ROO(arranged->next->data);
+
+		if(new_line) {
+			switch(pouch->priv->icon_orientation) {
+			case GTK_ORIENTATION_VERTICAL:
+				if(pouch->priv->icon_corner == GTK_CORNER_TOP_LEFT ||
+				   pouch->priv->icon_corner == GTK_CORNER_TOP_RIGHT) {
+					space = this_roo->priv->icon_allocation.y;
+				}
+				else {
+					space = GTK_WIDGET(pouch)->allocation.height - this_roo->priv->icon_allocation.y - this_roo->priv->icon_allocation.height;
+				}
+				break;
+			case GTK_ORIENTATION_HORIZONTAL:
+				if(pouch->priv->icon_corner == GTK_CORNER_TOP_LEFT ||
+				   pouch->priv->icon_corner == GTK_CORNER_BOTTOM_LEFT) {
+					space = this_roo->priv->icon_allocation.x;
+				}
+				else {
+					space = GTK_WIDGET(pouch)->allocation.width - this_roo->priv->icon_allocation.x - this_roo->priv->icon_allocation.width;
+				}
+				break;
+			}
+
+#ifdef GNOME_ENABLE_DEBUG
+			g_message("GnomePouch: found space at new line: %d", space);
+#endif
+
+			new_line = FALSE;
+		}
+		else {
+			switch(pouch->priv->icon_orientation) {
+			case GTK_ORIENTATION_VERTICAL:
+				if(pouch->priv->icon_corner == GTK_CORNER_TOP_LEFT ||
+				   pouch->priv->icon_corner == GTK_CORNER_TOP_RIGHT) {
+					if(next_roo->priv->icon_allocation.y <= this_roo->priv->icon_allocation.y) {
+						space = GTK_WIDGET(pouch)->allocation.height - this_roo->priv->icon_allocation.y - this_roo->priv->icon_allocation.height;
+						new_line = TRUE;
+					}
+					else 
+						space = next_roo->priv->icon_allocation.y - this_roo->priv->icon_allocation.y - this_roo->priv->icon_allocation.height;
+				}
+				else if(pouch->priv->icon_corner == GTK_CORNER_BOTTOM_LEFT ||
+						pouch->priv->icon_corner == GTK_CORNER_BOTTOM_RIGHT) {
+					if(next_roo->priv->icon_allocation.y >= this_roo->priv->icon_allocation.y) {
+						space = this_roo->priv->icon_allocation.y;
+						new_line = TRUE;
+					}
+					else
+						space = this_roo->priv->icon_allocation.y - next_roo->priv->icon_allocation.y - this_roo->priv->icon_allocation.height;
+				}
+				break;
+			case GTK_ORIENTATION_HORIZONTAL:
+				if(pouch->priv->icon_corner == GTK_CORNER_TOP_LEFT ||
+				   pouch->priv->icon_corner == GTK_CORNER_BOTTOM_LEFT) {
+					if(next_roo->priv->icon_allocation.x <= this_roo->priv->icon_allocation.x) {
+						space = GTK_WIDGET(pouch)->allocation.width - this_roo->priv->icon_allocation.x - this_roo->priv->icon_allocation.width;
+						new_line = TRUE;
+					}
+					else
+						space = next_roo->priv->icon_allocation.x - this_roo->priv->icon_allocation.x - this_roo->priv->icon_allocation.width;
+				}
+				else if(pouch->priv->icon_corner == GTK_CORNER_TOP_RIGHT ||
+						pouch->priv->icon_corner == GTK_CORNER_BOTTOM_RIGHT) {					
+					if(next_roo->priv->icon_allocation.x >= this_roo->priv->icon_allocation.x) {
+						space = this_roo->priv->icon_allocation.x;
+						new_line = TRUE;
+					}
+					else
+						space = this_roo->priv->icon_allocation.x - next_roo->priv->icon_allocation.x - this_roo->priv->icon_allocation.width;
+				}
+				break;
+			}
+		}
+
+#ifdef GNOME_ENABLE_DEBUG
+		g_message("GnomePouch: found %d space", space);
+#endif
+
+		switch(pouch->priv->icon_orientation) {
+		case GTK_ORIENTATION_VERTICAL:
+			px = this_roo->priv->icon_allocation.x;
+			if(space >= roo->priv->icon_allocation.height) {
+				if(pouch->priv->icon_corner == GTK_CORNER_TOP_LEFT ||
+				   pouch->priv->icon_corner == GTK_CORNER_TOP_RIGHT) {
+					if(was_new_line)
+						py = 0;
+					else
+						py = this_roo->priv->icon_allocation.y + this_roo->priv->icon_allocation.height;
+				}
+				else {
+					if(was_new_line)
+						py = GTK_WIDGET(pouch)->allocation.height - roo->priv->icon_allocation.height;
+					else
+						py = this_roo->priv->icon_allocation.y - roo->priv->icon_allocation.height;
+				}
+				found = TRUE;
+			}
+			break;
+		case GTK_ORIENTATION_HORIZONTAL:
+			py = this_roo->priv->icon_allocation.y;
+			if(space >= roo->priv->icon_allocation.width) {
+				if(pouch->priv->icon_corner == GTK_CORNER_TOP_LEFT ||
+				   pouch->priv->icon_corner == GTK_CORNER_BOTTOM_LEFT) {
+					if(was_new_line)
+						px = 0;
+					else
+						px = this_roo->priv->icon_allocation.x + this_roo->priv->icon_allocation.width;
+				}
+				else {
+					if(was_new_line)
+						px = GTK_WIDGET(pouch)->allocation.width - roo->priv->icon_allocation.width;
+					else
+						px = this_roo->priv->icon_allocation.x - roo->priv->icon_allocation.width;
+				}
+				found = TRUE;
+			}
+			break;
+		}
+
+		if(!found && !was_new_line)
+			arranged = arranged->next;
+	}
+
+
+	if(!found) {
+		if(arranged) { /* && !arranged->next */
+			this_roo = GNOME_ROO(arranged->data);
+
+			/* have we really found space after the last iconified roo */
+#ifdef GNOME_ENABLE_DEBUG
+			g_message("GnomePouch: found space after last roo");
+#endif
+			switch(pouch->priv->icon_orientation) {
+			case GTK_ORIENTATION_HORIZONTAL:
+				if(pouch->priv->icon_corner == GTK_CORNER_TOP_LEFT ||
+				   pouch->priv->icon_corner == GTK_CORNER_BOTTOM_LEFT) { /* left corners */
+					if(GTK_WIDGET(pouch)->allocation.width - this_roo->priv->icon_allocation.x - this_roo->priv->icon_allocation.width >= roo->priv->icon_allocation.width) {
+						py = this_roo->priv->icon_allocation.y;
+						px = this_roo->priv->icon_allocation.x +
+							 this_roo->priv->icon_allocation.width;
+					}
+					else { /* next row */
+						px = 0;
+						if(pouch->priv->icon_corner == GTK_CORNER_TOP_LEFT)
+							py = this_roo->priv->icon_allocation.y +
+								 this_roo->priv->icon_allocation.height;
+						else
+							py = this_roo->priv->icon_allocation.y -
+								 roo->priv->icon_allocation.height;
+					}
+				}
+				else { /* right corners */
+					if(this_roo->priv->icon_allocation.x >= roo->priv->icon_allocation.width) {
+						py = this_roo->priv->icon_allocation.y;
+						px = this_roo->priv->icon_allocation.x -
+							 roo->priv->icon_allocation.width;
+					}
+					else { /* next row */
+						px = GTK_WIDGET(pouch)->allocation.width - roo->priv->icon_allocation.width;
+						if(pouch->priv->icon_corner == GTK_CORNER_TOP_RIGHT)
+							py = this_roo->priv->icon_allocation.y +
+								 this_roo->priv->icon_allocation.height;
+						else
+							py = this_roo->priv->icon_allocation.y -
+								 roo->priv->icon_allocation.height;
+					}
+				}
+				break;
+			case GTK_ORIENTATION_VERTICAL:
+				if(pouch->priv->icon_corner == GTK_CORNER_TOP_LEFT ||
+				   pouch->priv->icon_corner == GTK_CORNER_TOP_RIGHT) { /* top corners */
+					if(GTK_WIDGET(pouch)->allocation.height - this_roo->priv->icon_allocation.y - this_roo->priv->icon_allocation.height >= roo->priv->icon_allocation.height) {
+						py = this_roo->priv->icon_allocation.y +
+							 this_roo->priv->icon_allocation.height;
+						px = this_roo->priv->icon_allocation.x;
+					}
+					else { /* next row */
+						py = 0;
+						if(pouch->priv->icon_corner == GTK_CORNER_TOP_LEFT)
+							px = this_roo->priv->icon_allocation.x +
+								 this_roo->priv->icon_allocation.width;
+						else
+							px = this_roo->priv->icon_allocation.x -
+								 roo->priv->icon_allocation.width;
+					}
+				}
+				else { /* bottom corners */
+					if(this_roo->priv->icon_allocation.y >= roo->priv->icon_allocation.height) {
+						py = this_roo->priv->icon_allocation.y -
+							 roo->priv->icon_allocation.height;
+						px = this_roo->priv->icon_allocation.x;
+					}
+					else { /* next row */
+						py = GTK_WIDGET(pouch)->allocation.height - roo->priv->icon_allocation.height;
+						if(pouch->priv->icon_corner == GTK_CORNER_BOTTOM_LEFT)
+							px = this_roo->priv->icon_allocation.x +
+								 this_roo->priv->icon_allocation.width;
+						else
+							px = this_roo->priv->icon_allocation.x -
+								 roo->priv->icon_allocation.width;
+					}
+				}
+				break;
+			default:
+				break;
+			}
+
+			node = g_list_alloc();
+			node->data = roo;
+			node->prev = arranged;
+			node->next = NULL;
+			arranged->next = node;
+		}
+		else { /* the first roo */
+			switch(pouch->priv->icon_corner) {
+			case GTK_CORNER_TOP_LEFT:
+				px = 0;
+				py = 0;
+				break;
+			case GTK_CORNER_BOTTOM_LEFT:
+				px = 0;
+				py = GTK_WIDGET(pouch)->allocation.height - roo->priv->icon_allocation.height;
+				break;
+			case GTK_CORNER_BOTTOM_RIGHT:
+				px = GTK_WIDGET(pouch)->allocation.width - roo->priv->icon_allocation.width;
+				py = GTK_WIDGET(pouch)->allocation.height - roo->priv->icon_allocation.height;
+				break;
+			case GTK_CORNER_TOP_RIGHT:
+				px = GTK_WIDGET(pouch)->allocation.width - roo->priv->icon_allocation.width;
+				py = 0;
+				break;
+			}
+
+			pouch->priv->arranged = g_list_alloc();
+			pouch->priv->arranged->data = roo;
+		}
+	}
+	else {
+		node = g_list_alloc();
+		node->data = roo;
+		if(was_new_line) {
+			node->next = arranged;
+			if(arranged->prev) {
+				node->prev = arranged->prev;
+				arranged->prev->next = node;
+			}
+			else
+				pouch->priv->arranged = node;
+			arranged->prev = node;
+		}
+		else {
+			node->prev = arranged;
+			node->next = arranged->next;
+			arranged->next = node;
+			node->next->prev = node;
+		}
+	}
+
+	roo->priv->icon_allocation.x = px;
+	roo->priv->icon_allocation.y = py;
+
+	gtk_fixed_move(GTK_FIXED(pouch), GTK_WIDGET(roo), px, py);
+}
+
+static void
+set_active_items(GnomePouch *pouch)
+{
+	gtk_check_menu_item_set_active(pouch->priv->oitem[pouch->priv->icon_orientation], TRUE);
+	gtk_check_menu_item_set_active(pouch->priv->citem[pouch->priv->icon_corner], TRUE);
+	gtk_check_menu_item_set_active(pouch->priv->aitem, pouch->priv->auto_arrange);
+}
+
+/**
+ * gnome_pouch_move:
+ * @pouch: A pointer to a GnomePouch widget.
+ * @roo: A pointer to a child GnomeRoo widget.
+ * @x: New horizontal position.
+ * @y: New vertical position.
+ * 
+ * Description:
+ * Moves the child @roo to a new position (@x,@y).
+ **/
+void
+gnome_pouch_move(GnomePouch *pouch, GnomeRoo *roo, gint x, gint y)
+{
+	g_return_if_fail(pouch != NULL);
+	g_return_if_fail(GNOME_IS_POUCH(pouch));
+	g_return_if_fail(roo != NULL);
+	g_return_if_fail(GNOME_IS_ROO(roo));
+
+	if(gnome_roo_is_iconified(roo)) {
+		pouch->priv->arranged = g_list_remove(pouch->priv->arranged, roo);
+		roo->priv->icon_allocation.x = x;
+		roo->priv->icon_allocation.y = y;
+	}
+
+	gtk_fixed_move(GTK_FIXED(pouch), GTK_WIDGET(roo), x, y);
+}
+
+/**
+ * gnome_pouch_select_roo:
+ * @pouch: A pointer to a GnomePouch widget.
+ * @roo: A pointer to a GnomeRoo widget that should be selected or NULL
+ * for no selected GnomeRoo.
+ *
+ * Description:
+ * Selects @roo.
+ **/
+void
+gnome_pouch_select_roo(GnomePouch *pouch, GnomeRoo *roo)
+{
+	g_return_if_fail(pouch != NULL);
+	g_return_if_fail(GNOME_IS_POUCH(pouch));
+	g_return_if_fail(GNOME_IS_ROO(roo));
+
+	if(roo)
+		gtk_signal_emit_by_name(GTK_OBJECT(roo), "select", NULL);
+	else if(pouch->priv->selected)
+		gtk_signal_emit_by_name(GTK_OBJECT(pouch->priv->selected), "deselect", NULL);
+}
+
+/**
+ * gnome_pouch_get_selected:
+ * @pouch: A pointer to a GnomePouch widget.
+ *
+ * Description:
+ * Retrieves the currently selected @roo.
+ *
+ * Return value:
+ * Currently selected @roo or %NULL if none.
+ **/
+GnomeRoo *
+gnome_pouch_get_selected(GnomePouch *pouch)
+{
+	g_return_val_if_fail(pouch != NULL, NULL);
+	g_return_val_if_fail(GNOME_IS_POUCH(pouch), NULL);
+
+	return pouch->priv->selected;
+}
+
+/**
+ * gnome_pouch_arrange_icons:
+ * @pouch: A pointer to a GnomePouch widget.
+ * 
+ * Description:
+ * Arranges all iconified and not parked children according to the user's
+ * preferred arrangement set with a call to gnome_pouch_set_icon_arrangement().
+ **/
+void
+gnome_pouch_arrange_icons(GnomePouch *pouch)
+{
+	GList *child_info;
+	GnomeRoo *roo;
+
+	g_return_if_fail(pouch != NULL);
+	g_return_if_fail(GNOME_IS_POUCH(pouch));
+
+	if(pouch->priv->arranged) {
+		g_list_free(pouch->priv->arranged);
+		pouch->priv->arranged = NULL;
+	}
+
+	child_info = GTK_FIXED(pouch)->children;
+	while(child_info) {
+		roo = GNOME_ROO(((GtkFixedChild *)child_info->data)->widget);
+		if(gnome_roo_is_iconified(roo)) {
+			if(gnome_roo_is_parked(roo))
+				gnome_roo_unpark(roo);
+			arrange_roo(pouch, roo);
+		}
+		child_info = child_info->next;
+	}
+}
+
+/**
+ * gnome_pouch_set_icon_arrangement:
+ * @pouch: A pointer to a GnomePouch widget.
+ * @corner: GtkCornerType specifying corner for the iconified children.
+ * @orientation: GtkOrientationType specifiying whether the iconified children
+ * should be laid out horizontally or vertically.
+ *
+ * Description:
+ * Specifies the corner and the direction in which the iconified roos arranged
+ * by the pouch should be put. The children are stacked according to
+ * @orientation, starting in corner @corner.
+ **/
+void
+gnome_pouch_set_icon_arrangement(GnomePouch *pouch, GtkCornerType corner,
+								 GtkOrientation orientation)
+{
+	g_return_if_fail(pouch != NULL);
+	g_return_if_fail(GNOME_IS_POUCH(pouch));
+
+	if(corner != pouch->priv->icon_corner || orientation != pouch->priv->icon_orientation) {
+		pouch->priv->icon_corner = corner;
+		pouch->priv->icon_orientation = orientation;
+	}
+}
+
+/**
+ * gnome_pouch_enable_auto_arrange:
+ * @auto_arr: A gboolean specifying if the children should be automatically
+ * arranged when iconified.
+ *
+ * Description:
+ * If set to %TRUE, the children which have not been gnome_roo_park()ed,
+ * will be automatically arranged by the pouch when iconified.
+ **/
+void
+gnome_pouch_enable_auto_arrange(GnomePouch *pouch, gboolean auto_arr)
+{
+	g_return_if_fail(pouch != NULL);
+	g_return_if_fail(GNOME_IS_POUCH(pouch));
+
+	pouch->priv->auto_arrange = auto_arr;
+}
+
+/** 
+ * popup menu
+ **/
+static GnomeUIInfo position_list[] = {
+	/* to be kept in sync with GtkCornerType enumeration */
+	GNOMEUIINFO_RADIOITEM_DATA(N_("Top left"), NULL, position_callback, (gpointer)GTK_CORNER_TOP_LEFT, NULL),
+	GNOMEUIINFO_RADIOITEM_DATA(N_("Bottom left"), NULL, position_callback, (gpointer)GTK_CORNER_BOTTOM_LEFT, NULL),
+	GNOMEUIINFO_RADIOITEM_DATA(N_("Top right"), NULL, position_callback, (gpointer)GTK_CORNER_TOP_RIGHT, NULL),
+	GNOMEUIINFO_RADIOITEM_DATA(N_("Bottom right"), NULL, position_callback, (gpointer)GTK_CORNER_BOTTOM_RIGHT, NULL),
+	GNOMEUIINFO_END
+};
+
+static GnomeUIInfo position_menu[] = {
+	GNOMEUIINFO_RADIOLIST(position_list),
+	GNOMEUIINFO_END
+};
+
+static GnomeUIInfo orientation_list[] = {
+	/* to be kept in sync with GtkOrientation enumeration */
+	GNOMEUIINFO_RADIOITEM_DATA(N_("Horizontal"), NULL, orientation_callback, (gpointer)GTK_ORIENTATION_HORIZONTAL, NULL),
+	GNOMEUIINFO_RADIOITEM_DATA(N_("Vertical"), NULL, orientation_callback, (gpointer)GTK_ORIENTATION_VERTICAL, NULL),
+	GNOMEUIINFO_END
+};
+
+static GnomeUIInfo orientation_menu[] = {
+	GNOMEUIINFO_RADIOLIST(orientation_list),
+	GNOMEUIINFO_END
+};
+
+static GnomeUIInfo popup_menu[] = {
+	GNOMEUIINFO_SUBTREE(N_("Icon position"), position_menu),
+	GNOMEUIINFO_SUBTREE(N_("Icon orientation"), orientation_menu),
+	GNOMEUIINFO_SEPARATOR,
+	GNOMEUIINFO_ITEM(N_("Tile children"), NULL, tile_callback, NULL),
+	GNOMEUIINFO_ITEM(N_("Cascade children"), NULL, cascade_callback, NULL),
+	GNOMEUIINFO_SEPARATOR,
+	GNOMEUIINFO_ITEM(N_("Arrange icons"), NULL, arrange_callback, NULL),
+	GNOMEUIINFO_TOGGLEITEM(N_("Autoarrange icons"), NULL, autoarrange_callback, NULL),
+	GNOMEUIINFO_END
+};
+
+static void
+tile_callback(GtkWidget *w, gpointer user_data)
+{
+	// FIXME: implement
+}
+
+static void
+cascade_callback(GtkWidget *w, gpointer user_data)
+{
+	// FIXME: implement
+}
+
+static void
+arrange_callback(GtkWidget *w, gpointer user_data)
+{
+	gnome_pouch_arrange_icons(GNOME_POUCH(user_data));
+}
+
+static void
+autoarrange_callback(GtkWidget *w, gpointer user_data)
+{
+	GNOME_POUCH(user_data)->priv->auto_arrange =
+		GTK_CHECK_MENU_ITEM(w)->active;
+}
+
+static void
+orientation_callback(GtkWidget *w, gpointer user_data)
+{
+	GtkOrientation orient;
+	GnomePouch *pouch = GNOME_POUCH(user_data);
+
+	if(!GTK_CHECK_MENU_ITEM(w)->active)
+		return;
+
+	orient = (GtkOrientation)gtk_object_get_data(GTK_OBJECT(w),
+												 GNOMEUIINFO_KEY_UIDATA);
+
+	gnome_pouch_set_icon_arrangement(pouch, pouch->priv->icon_corner, orient);
+}
+
+static void
+position_callback(GtkWidget *w, gpointer user_data)
+{
+	GtkCornerType corner;
+	GnomePouch *pouch = GNOME_POUCH(user_data);
+
+	if(!GTK_CHECK_MENU_ITEM(w)->active)
+		return;
+
+	corner = (GtkCornerType)gtk_object_get_data(GTK_OBJECT(w),
+												GNOMEUIINFO_KEY_UIDATA);
+
+	gnome_pouch_set_icon_arrangement(pouch, corner, pouch->priv->icon_orientation);
+}
+
+/**
+ * gnome_pouch_enable_popup_menu:
+ * @enable: A gboolean specifying if the pouch pop-up menu should be enabled.
+ *
+ * Description:
+ * When set to %TRUE, a right click on the pouch will pop up a menu with
+ * some common options.
+ **/
+void
+gnome_pouch_enable_popup_menu(GnomePouch *pouch, gboolean enable)
+{
+	gint i;
+
+	g_return_if_fail(pouch != NULL);
+	g_return_if_fail(GNOME_IS_POUCH(pouch));
+
+	if(enable && pouch->priv->popup_menu == NULL) {
+		pouch->priv->popup_menu = gnome_popup_menu_new(popup_menu);
+		for(i = 0; i < 2; i++)
+			pouch->priv->oitem[i] = GTK_CHECK_MENU_ITEM(orientation_list[i].widget);
+		for(i = 0; i < 4; i++)
+			pouch->priv->citem[i] = GTK_CHECK_MENU_ITEM(position_list[i].widget);
+		pouch->priv->aitem = GTK_CHECK_MENU_ITEM(popup_menu[7].widget);
+	}
+	else if(!enable && pouch->priv->popup_menu) {
+		gtk_widget_destroy(pouch->priv->popup_menu);
+		pouch->priv->popup_menu = NULL;
+	}
+}
+
+/**
+ * gnome_pouch_new:
+ * 
+ * Description:
+ * Creates a new GnomePouch container.
+ * 
+ * Return value:
+ * A pointer to a new GnomePouch widget.
+ **/
+GtkWidget *
+gnome_pouch_new()
+{
+	return gtk_type_new(gnome_pouch_get_type());
+}
diff --git a/libgnomeui/gnome-pouch.h b/libgnomeui/gnome-pouch.h
new file mode 100644
index 0000000..485d5dd
--- /dev/null
+++ b/libgnomeui/gnome-pouch.h
@@ -0,0 +1,82 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* gnome-pouch.h - definition of a Gnome Pouch widget - a WiW MDI container
+
+   Copyright (C) 2000 Jaka Mocnik
+
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Jaka Mocnik <jaka mocnik kiss uni-lj si>
+*/
+
+#ifndef __GNOME_POUCH_H__
+#define __GNOME_POUCH_H__
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+
+#include "gnome-roo.h"
+
+G_BEGIN_DECLS
+
+#define GNOME_TYPE_POUCH            (gnome_pouch_get_type ())
+#define GNOME_POUCH(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_POUCH, GnomePouch))
+#define GNOME_POUCH_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_POUCH, GnomePouchClass))
+#define GNOME_IS_POUCH(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_POUCH))
+#define GNOME_IS_POUCH_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_POUCH))
+#define GNOME_POUCH_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_POUCH, GnomePouchClass))
+
+typedef struct _GnomePouch       GnomePouch;
+typedef struct _GnomePouchClass  GnomePouchClass;
+
+typedef struct _GnomePouchPrivate GnomePouchPrivate;
+
+struct _GnomePouch {
+	GtkFixed fixed;
+
+	GnomePouchPrivate *priv;
+};
+
+struct _GnomePouchClass {
+	GtkFixedClass parent_class;
+
+	void (*close_child)(GnomePouch *pouch, GnomeRoo *roo);
+	void (*iconify_child)(GnomePouch *pouch, GnomeRoo *roo);
+	void (*uniconify_child)(GnomePouch *pouch, GnomeRoo *roo);
+	void (*maximize_child)(GnomePouch *pouch, GnomeRoo *roo);
+	void (*unmaximize_child)(GnomePouch *pouch, GnomeRoo *roo);
+	void (*select_child)(GnomePouch *pouch, GnomeRoo *roo);
+	void (*unselect_child)(GnomePouch *pouch, GnomeRoo *roo);
+};
+
+guint      gnome_pouch_get_type(void) G_GNUC_CONST;
+GtkWidget *gnome_pouch_new(void);
+void       gnome_pouch_select_roo(GnomePouch *pouch, GnomeRoo *roo);
+GnomeRoo  *gnome_pouch_get_selected(GnomePouch *pouch);
+void       gnome_pouch_move(GnomePouch *pouch, GnomeRoo *roo, gint x, gint y);
+void       gnome_pouch_set_icon_arrangement(GnomePouch *pouch,
+											GtkCornerType corner,
+											GtkOrientation orientation);
+void       gnome_pouch_arrange_icons(GnomePouch *pouch);
+void       gnome_pouch_enable_auto_arrange(GnomePouch *pouch,
+										   gboolean auto_arr);
+void       gnome_pouch_enable_popup_menu(GnomePouch *pouch, gboolean enable);
+void       gnome_pouch_tile_children(GnomePouch *pouch);
+void       gnome_pouch_cascade_children(GnomePouch *pouch);
+
+G_END_DECLS
+
+#endif /* __GNOME_POUCH_H__ */
diff --git a/libgnomeui/gnome-pouchP.h b/libgnomeui/gnome-pouchP.h
new file mode 100644
index 0000000..fa3cd69
--- /dev/null
+++ b/libgnomeui/gnome-pouchP.h
@@ -0,0 +1,70 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* gnome-pouchP.h - private parts ;) of GnomePouch and GnomeRoo widgets
+
+   Copyright (C) 2000 Free Software Foundation
+   All rights reserved.
+
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Jaka Mocnik <jaka mocnik kiss uni-lj si>
+*/
+/*
+  @NOTATION@
+*/
+
+#ifndef __GNOME_POUCHP_H__
+#define __GNOME_POUCHP_H__
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include "gnome-pouch.h"
+#include "gnome-roo.h"
+
+G_BEGIN_DECLS
+
+struct _GnomePouchPrivate
+{
+	GnomeRoo *selected;
+	GList *arranged;
+
+	gboolean auto_arrange : 1;
+	GtkCornerType icon_corner;
+	GtkOrientation icon_orientation;
+
+	GtkWidget *popup_menu;
+
+	GtkCheckMenuItem *oitem[2], *citem[4], *aitem;
+};
+
+struct _GnomeRooPrivate
+{
+	gchar *title;
+
+	/* the following are private */
+	guint16 min_width, min_height, title_bar_height;
+	guint resize_type;
+	guint16 grab_x, grab_y;
+	GtkAllocation user_allocation;
+	GtkAllocation icon_allocation;
+	guint16 flags;
+	gchar *vis_title;
+	GdkWindow *cover;
+};
+
+G_END_DECLS
+
+#endif /* __GNOME_POUCHP_H__ */
diff --git a/libgnomeui/gnome-preferences.c b/libgnomeui/gnome-preferences.c
new file mode 100644
index 0000000..5aafcfa
--- /dev/null
+++ b/libgnomeui/gnome-preferences.c
@@ -0,0 +1,938 @@
+/* GNOME GUI Library: gnome-preferences.c
+ * Copyright (C) 1998 Free Software Foundation
+ * All rights reserved.
+ * Author: Havoc Pennington
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#include <config.h>
+#include "gnome-preferences.h"
+#include <libgnome/gnome-config.h>
+#include <string.h>
+
+
+struct _GnomePreferences {
+  GtkButtonBoxStyle dialog_buttons_style;
+  int property_box_buttons_ok : 1;
+  int property_box_buttons_apply : 1;
+  int property_box_buttons_close : 1;
+  int property_box_buttons_help : 1;
+  int statusbar_not_dialog : 1;
+  int statusbar_is_interactive : 1;
+  int statusbar_meter_on_right : 1;
+  int menubar_detachable : 1;
+  int menubar_relief : 1;
+  int toolbar_detachable : 1;
+  int toolbar_relief : 1;
+  int toolbar_relief_btn : 1;
+  int toolbar_lines : 1;
+  int toolbar_labels : 1;
+  int dialog_centered : 1;
+  int menus_have_tearoff : 1;
+  int menus_have_icons : 1;
+  int disable_imlib_cache : 1;
+  GtkWindowType dialog_type;
+  GtkWindowPosition dialog_position;
+  GnomeMDIMode mdi_mode;
+  GtkPositionType mdi_tab_pos;
+};
+
+
+/* 
+ * Variable holds current preferences.  
+ */
+
+/* These initial values are the Gnome defaults */
+static GnomePreferences prefs =
+{
+  GTK_BUTTONBOX_END,  /* Position of dialog buttons. */
+  TRUE,               /* PropertyBox has OK button */
+  TRUE,               /* PropertyBox has Apply */
+  TRUE,               /* PropertyBox has Close */
+  TRUE,               /* PropertyBox has Help */
+  FALSE,              /* Use dialogs, not the statusbar */
+  FALSE,              /* Statusbar isn't interactive */
+  TRUE,               /* Menubars are detachable */
+  TRUE,               /* Menubars are relieved */
+  TRUE,               /* Toolbars are detachable */
+  TRUE,               /* Toolbars are relieved */
+  FALSE,              /* Toolbar buttons are relieved */
+  TRUE,               /* Toolbars show lines for separators */
+  TRUE,               /* Toolbars show labels */
+  TRUE,               /* Center dialogs over apps when possible */
+  TRUE,               /* Menus have a tearoff bar */
+  TRUE,               /* Menu items have icons in them */
+  TRUE,               /* Disable the Imlib cache */
+  GTK_WINDOW_TOPLEVEL,/* Dialogs are treated specially */
+  GTK_WIN_POS_CENTER, /* Put dialogs in center of screen. */
+  GNOME_MDI_NOTEBOOK, /* Use notebook MDI mode. */
+  GTK_POS_TOP         /* Show tabs on top of MDI notebooks. */
+};
+
+/* Tons of defines for where to store the preferences. */
+
+/* Used for global defaults. (well, maybe someday) */
+#define UI_APPNAME "/Gnome/UI_Prefs"
+
+/* ============= Sections ====================== */
+#define GENERAL   "/Gnome/UI_General/"
+#define DIALOGS   "/Gnome/UI_Dialogs/"
+#define STATUSBAR "/Gnome/UI_StatusBar/"
+#define APP       "/Gnome/UI_GnomeApp/"
+#define MDI       "/Gnome/UI_MDI/"
+#define CACHE     "/Gnome/Cache/"
+
+/* ==================== GnomeDialog ===================== */
+
+#define DIALOG_BUTTONS_STYLE_KEY "DialogButtonsStyle"
+
+static const gchar * const dialog_button_styles [] = {
+  "Default",
+  "Spread",
+  "Edge",
+  "Start",
+  "End"
+};
+
+#define NUM_BUTTON_STYLES 5
+
+#define DIALOG_CENTERED_KEY "Dialog_is_Centered"
+
+#define DIALOG_TYPE_KEY "DialogType"
+
+static const gchar * const dialog_types [] = {
+  "Toplevel",
+  "Dialog"
+};
+
+#define NUM_DIALOG_TYPES 2
+
+#define DIALOG_POSITION_KEY "DialogPosition"
+
+static const gchar * const dialog_positions [] = {
+  "None",
+  "Center",
+  "Mouse"
+};
+
+#define NUM_DIALOG_POSITIONS 3
+
+/* ============ Property Box ======================= */
+
+/* ignore this */
+#define _PROPERTY_BOX_BUTTONS "PropertyBoxButton"
+
+/* Each of these are bools; better way? */
+#define PROPERTY_BOX_BUTTONS_OK_KEY _PROPERTY_BOX_BUTTONS"OK"
+#define PROPERTY_BOX_BUTTONS_APPLY_KEY _PROPERTY_BOX_BUTTONS"Apply"
+#define PROPERTY_BOX_BUTTONS_CLOSE_KEY _PROPERTY_BOX_BUTTONS"Close"
+#define PROPERTY_BOX_BUTTONS_HELP_KEY _PROPERTY_BOX_BUTTONS"Help"
+
+/* =========== GnomeApp ============================ */
+
+#define STATUSBAR_DIALOG_KEY       "StatusBar_not_Dialog"
+#define STATUSBAR_INTERACTIVE_KEY  "StatusBar_is_Interactive"
+#define STATUSBAR_METER_ON_RIGHT   "StatusBar_Meter_on_Right"
+
+#define MENUBAR_DETACHABLE_KEY     "Menubar_detachable"
+#define MENUBAR_RELIEF_KEY         "Menubar_relieved"
+
+#define TOOLBAR_DETACHABLE_KEY     "Toolbar_detachable"
+#define TOOLBAR_RELIEF_KEY         "Toolbar_relieved"
+#define TOOLBAR_RELIEF_BTN_KEY     "Toolbar_relieved_buttons"
+#define TOOLBAR_LINES_KEY          "Toolbar_lines"
+#define TOOLBAR_LABELS_KEY         "Toolbar_labels"
+
+#define MENUS_HAVE_TEAROFF_KEY     "Menus_have_tearoff"
+#define MENUS_HAVE_ICONS_KEY       "Menus_have_icons"
+#define DISABLE_IMLIB_CACHE_KEY    "Disable_Imlib_cache"
+
+/* =========== MDI ================================= */
+
+#define MDI_MODE_KEY               "MDI_mode"
+#define MDI_TAB_POS_KEY            "MDI_tab_pos"
+
+static const gchar * const mdi_modes [] = {
+  "Notebook",
+  "Toplevel",
+  "Modal"
+};
+
+#define NUM_MDI_MODES 3
+
+static const gchar * const tab_positions [] = {
+  "Left",
+  "Right",
+  "Top",
+  "Bottom"
+};
+
+#define NUM_TAB_POSITIONS 4
+
+static gboolean 
+enum_from_strings(gint * setme, gchar * findme, 
+		  const gchar * const array[], gint N)
+{
+	gboolean retval = FALSE;
+	gint i = 0;
+
+	if (findme == NULL) {
+		/* Leave default */
+		retval = TRUE;
+	} else {
+		while (i < N) {
+			if (g_strcasecmp(findme, array[i]) == 0) {
+				*setme = i;
+				retval = TRUE;
+				break;
+			} 
+			++i;
+		}
+	}
+	return retval;
+}
+
+/**
+ * gnome_preferences_load_custom
+ * @settings: App-specified set of user preferences
+ *
+ * Description:
+ * Uses gnome_config_xxx() interface to load a set of
+ * standard GNOME preferences into the specified @settings object.
+ **/
+ 
+void
+gnome_preferences_load_custom(GnomePreferences *settings)
+{
+  /* Probably this function should be rewritten to use the 
+   *  _preferences_get functions
+   */
+  gboolean b;
+  gchar * s;
+
+  gnome_config_push_prefix(DIALOGS);
+
+  s = gnome_config_get_string(DIALOG_BUTTONS_STYLE_KEY);
+
+
+  if ( ! enum_from_strings((int*) &settings->dialog_buttons_style, s,
+			   dialog_button_styles, NUM_BUTTON_STYLES) ) {
+    g_warning("Didn't recognize buttonbox style in libgnomeui config");
+  }
+
+  g_free(s);
+  
+  s = gnome_config_get_string(DIALOG_TYPE_KEY);
+
+  if ( ! enum_from_strings((int*) &settings->dialog_type, s,
+			   dialog_types, NUM_DIALOG_TYPES) ) {
+    g_warning("Didn't recognize dialog type in libgnomeui config");
+  }
+
+  g_free(s);
+  
+  s = gnome_config_get_string(DIALOG_POSITION_KEY);
+
+  if ( ! enum_from_strings((int*) &settings->dialog_position, s,
+			   dialog_positions, NUM_DIALOG_POSITIONS) ) {
+    g_warning("Didn't recognize dialog position in libgnomeui config");
+  }  
+
+  g_free(s);
+  
+  /* Fixme. There's a little problem with no error value from the 
+     bool get function. This makes it yucky to do the propertybox 
+     thing. The intermediate 'b' variable is only in anticipation
+     of a future way to check for errors. */
+
+  b = gnome_config_get_bool_with_default(DIALOG_CENTERED_KEY"=true",
+					 NULL);
+  settings->dialog_centered = b;
+
+  /* This is unused for now */
+  b = gnome_config_get_bool_with_default(PROPERTY_BOX_BUTTONS_OK_KEY"=true",
+					 NULL);
+  settings->property_box_buttons_ok = b;
+
+  b = gnome_config_get_bool_with_default(PROPERTY_BOX_BUTTONS_APPLY_KEY"=true",
+					 NULL);
+  settings->property_box_buttons_apply = b;
+
+  b = gnome_config_get_bool_with_default(PROPERTY_BOX_BUTTONS_CLOSE_KEY"=true",
+					 NULL);
+  settings->property_box_buttons_close = b;
+
+  b = gnome_config_get_bool_with_default(PROPERTY_BOX_BUTTONS_HELP_KEY"=true",
+					 NULL);
+  settings->property_box_buttons_help = b;
+
+  gnome_config_pop_prefix();
+  gnome_config_push_prefix(STATUSBAR);
+
+  b = gnome_config_get_bool_with_default(STATUSBAR_DIALOG_KEY"=false",
+					 NULL);
+  settings->statusbar_not_dialog = b;
+  
+  b = gnome_config_get_bool_with_default(STATUSBAR_INTERACTIVE_KEY"=false",
+					 NULL);
+  settings->statusbar_is_interactive = b;
+
+  b = gnome_config_get_bool_with_default(STATUSBAR_METER_ON_RIGHT"=true",
+					 NULL);
+  settings->statusbar_meter_on_right = b;
+
+  gnome_config_pop_prefix();
+  gnome_config_push_prefix(APP);
+
+  b = gnome_config_get_bool_with_default(MENUBAR_DETACHABLE_KEY"=true",
+					 NULL);
+  settings->menubar_detachable = b;
+
+  b = gnome_config_get_bool_with_default(MENUBAR_RELIEF_KEY"=true",
+					 NULL);
+  settings->menubar_relief = b;
+
+  b = gnome_config_get_bool_with_default(TOOLBAR_DETACHABLE_KEY"=true",
+					 NULL);
+  settings->toolbar_detachable = b;
+
+  b = gnome_config_get_bool_with_default(TOOLBAR_RELIEF_KEY"=true",
+					 NULL);
+  settings->toolbar_relief = b;
+
+  b = gnome_config_get_bool_with_default(TOOLBAR_RELIEF_BTN_KEY"=false",
+					 NULL);
+  settings->toolbar_relief_btn = b;
+
+  b = gnome_config_get_bool_with_default(TOOLBAR_LINES_KEY"=true",
+					 NULL);
+  settings->toolbar_lines = b;
+
+  b = gnome_config_get_bool_with_default(TOOLBAR_LABELS_KEY"=true",
+					 NULL);
+  settings->toolbar_labels = b;
+
+  b = gnome_config_get_bool_with_default (MENUS_HAVE_TEAROFF_KEY"=true",
+					  NULL);
+  settings->menus_have_tearoff = b;
+
+  b = gnome_config_get_bool_with_default (MENUS_HAVE_ICONS_KEY"=true",
+					  NULL);
+  settings->menus_have_icons = b;
+
+  gnome_config_pop_prefix ();
+  gnome_config_push_prefix (CACHE);
+  b = gnome_config_get_bool_with_default (DISABLE_IMLIB_CACHE_KEY"=true",
+					  NULL);
+  settings->disable_imlib_cache = b;
+  
+  gnome_config_pop_prefix();
+  gnome_config_push_prefix(MDI);
+
+  s = gnome_config_get_string(MDI_MODE_KEY);
+
+  if ( ! enum_from_strings((int*) &settings->mdi_mode, s,
+			   mdi_modes, NUM_MDI_MODES) ) {
+    g_warning("Didn't recognize MDI mode in libgnomeui config");
+  }
+
+  g_free(s);
+  
+  s = gnome_config_get_string(MDI_TAB_POS_KEY);
+
+  if ( ! enum_from_strings((int*) &settings->mdi_tab_pos, s,
+			   tab_positions, NUM_TAB_POSITIONS) ) {
+    g_warning("Didn't recognize MDI notebook tab position in libgnomeui config");
+  }
+
+  g_free(s);
+  
+  gnome_config_pop_prefix();
+}
+
+/**
+ * gnome_preferences_save_custom
+ * @settings: App-specified set of user preferences
+ *
+ * Description:
+ * Uses gnome_config_xxx() interface to store a set of
+ * standard GNOME preferences from info in the @settings object.
+ **/
+ 
+void
+gnome_preferences_save_custom(GnomePreferences *settings)
+{
+  gnome_config_push_prefix(DIALOGS);
+  
+  gnome_config_set_string(DIALOG_BUTTONS_STYLE_KEY, 
+			  dialog_button_styles[settings->dialog_buttons_style]);
+
+  gnome_config_set_string(DIALOG_TYPE_KEY, 
+			  dialog_types[settings->dialog_type]);
+
+  gnome_config_set_string(DIALOG_POSITION_KEY, 
+			  dialog_positions[settings->dialog_position]);
+  
+  gnome_config_set_bool  (DIALOG_CENTERED_KEY,
+			  settings->dialog_centered);
+
+  gnome_config_pop_prefix();
+
+  gnome_config_push_prefix(STATUSBAR);
+
+  gnome_config_set_bool(STATUSBAR_DIALOG_KEY,
+			settings->statusbar_not_dialog);
+  gnome_config_set_bool(STATUSBAR_INTERACTIVE_KEY,
+			settings->statusbar_is_interactive);
+  gnome_config_set_bool(STATUSBAR_METER_ON_RIGHT,
+			settings->statusbar_meter_on_right);
+
+
+  gnome_config_pop_prefix();
+  gnome_config_push_prefix(APP);
+
+  gnome_config_set_bool(MENUBAR_DETACHABLE_KEY,
+			settings->menubar_detachable);
+  gnome_config_set_bool(MENUBAR_RELIEF_KEY,
+			settings->menubar_relief);
+  gnome_config_set_bool(TOOLBAR_DETACHABLE_KEY,
+			settings->toolbar_detachable);
+  gnome_config_set_bool(TOOLBAR_RELIEF_KEY,
+			settings->toolbar_relief);
+  gnome_config_set_bool(TOOLBAR_RELIEF_BTN_KEY,
+			settings->toolbar_relief_btn);
+  gnome_config_set_bool(TOOLBAR_LINES_KEY,
+			settings->toolbar_lines);
+  gnome_config_set_bool(TOOLBAR_LABELS_KEY,
+			settings->toolbar_labels);
+  gnome_config_set_bool(MENUS_HAVE_TEAROFF_KEY,
+			settings->menus_have_tearoff);
+  gnome_config_set_bool(MENUS_HAVE_ICONS_KEY,
+			settings->menus_have_icons);
+  gnome_config_set_bool(DISABLE_IMLIB_CACHE_KEY,
+			settings->disable_imlib_cache);
+  gnome_config_pop_prefix();
+  gnome_config_push_prefix(MDI);
+
+  gnome_config_set_string(MDI_MODE_KEY, mdi_modes[settings->mdi_mode]);
+  gnome_config_set_string(MDI_TAB_POS_KEY, tab_positions[settings->mdi_tab_pos]);
+
+  gnome_config_pop_prefix();
+
+  gnome_config_sync();
+}
+
+/**
+ * gnome_preferences_load
+ *
+ * Description:
+ * Uses gnome_config_xxx() API to load a standard set of GNOME
+ * preferences into the default GNOME preferences object.
+ **/
+ 
+void gnome_preferences_load(void)
+{
+  gnome_preferences_load_custom(&prefs);
+}
+
+/**
+ * gnome_preferences_save
+ *
+ * Description:
+ * Uses gnome_config_xxx() API to store a standard set of GNOME
+ * preferences using info in the default GNOME preferences object.
+ **/
+ 
+void gnome_preferences_save(void)
+{
+  gnome_preferences_save_custom(&prefs);
+}
+
+
+/**
+ * gnome_preferences_get_button_layout 
+ *
+ * Description:
+ * Obtain the button style from the default GNOME preferences object.
+ *
+ * Returns:
+ * Enumerated type indicating the default GNOME dialog button style.
+ **/
+    
+GtkButtonBoxStyle gnome_preferences_get_button_layout (void)
+{
+  return prefs.dialog_buttons_style;
+}
+
+
+/**
+ * gnome_preferences_set_button_layout :
+ * @style: Enumerated type indicating the default GNOME dialog button style.
+ *
+ * Set the default GNOME preferences object's default button style.
+ **/
+
+void gnome_preferences_set_button_layout (GtkButtonBoxStyle style)
+{
+	g_return_if_fail ((style <= GTK_BUTTONBOX_END));
+	prefs.dialog_buttons_style = style;
+}
+
+
+/**
+ * gnome_preferences_get_statusbar_dialog     
+ *
+ * Description:
+ * Determine whether or not the statusbar is a dialog.
+ *
+ * Returns:
+ * %FALSE if statusbar is a dialog, %TRUE if not.
+ **/
+
+gboolean          gnome_preferences_get_statusbar_dialog     (void)
+{
+  return prefs.statusbar_not_dialog;
+}
+
+
+/**
+ * gnome_preferences_set_statusbar_dialog:
+ * @b: %FALSE if statusbar is a dialog, %TRUE if not.
+ *
+ * Indicate whether or not the default for GNOME status bars
+ * is a dialog.
+ *
+ */
+
+void              gnome_preferences_set_statusbar_dialog     (gboolean b)
+{
+  prefs.statusbar_not_dialog = b;
+}
+
+
+/**
+ * gnome_preferences_get_statusbar_interactive
+ *
+ * Description:
+ * Determine whether or not the statusbar is interactive.
+ *
+ * Returns:
+ * %TRUE if statusbar is interactive, %FALSE if not.
+ **/
+
+gboolean          gnome_preferences_get_statusbar_interactive(void)
+{
+  return prefs.statusbar_is_interactive;
+}
+
+
+/**
+ * gnome_preferences_set_statusbar_interactive:
+ * @b: %TRUE if statusbar is interactive, %FALSE if not.
+ *
+ * Indicate whether or not the GNOME status bars are, by default,
+ * interactive.
+ **/
+
+void              gnome_preferences_set_statusbar_interactive(gboolean b)
+{
+  prefs.statusbar_is_interactive = b;
+}
+
+
+/**
+ * gnome_preferences_get_statusbar_meter_on_right 
+ *
+ * Description:
+ * Determine whether or not the statusbar's meter is on the right-hand side. 
+ *
+ * Returns:
+ * %TRUE if statusbar meter is on the right side, %FALSE if not.
+ **/
+
+gboolean gnome_preferences_get_statusbar_meter_on_right (void)
+{
+  return prefs.statusbar_meter_on_right;
+}
+
+
+/**
+ * gnome_preferences_set_statusbar_meter_on_right:
+ * @statusbar_meter_on_right: %TRUE if statusbar meter is on the right side, %FALSE if not.
+ *
+ * Indicate whether or not the GNOME status bars are, by default,
+ * on the right-hand side.
+ **/
+
+void
+gnome_preferences_set_statusbar_meter_on_right (gboolean statusbar_meter_on_right)
+{
+  prefs.statusbar_meter_on_right = statusbar_meter_on_right;
+}
+
+
+/**
+ * gnome_preferences_get_menubar_detachable:
+ *
+ * Determine whether or not a menu bar is, by default,
+ * detachable from its parent frame.
+ *
+ * Returns:
+ * %TRUE if menu bars are detachable, %FALSE if not.
+ */
+gboolean          gnome_preferences_get_menubar_detachable   (void)
+{
+  return prefs.menubar_detachable;
+}
+
+
+/**
+ * gnome_preferences_set_menubar_detachable:
+ * @b: %TRUE if menu bars are detachable, %FALSE if not.
+ *
+ * Indicate whether or not the GNOME menu bars are, by default,
+ * detachable from their parent frame.
+ */
+void              gnome_preferences_set_menubar_detachable   (gboolean b)
+{
+  prefs.menubar_detachable = b;
+}
+
+
+/**
+ * gnome_preferences_get_menubar_relief:
+ *
+ * Returns: the relieft settings for the menubar.
+ */
+gboolean          gnome_preferences_get_menubar_relief    (void)
+{
+  return prefs.menubar_relief;
+}
+
+
+/**
+ * gnome_preferences_set_menubar_relief:
+ * @b: 
+ *
+ */
+void              gnome_preferences_set_menubar_relief    (gboolean b)
+{
+  prefs.menubar_relief = b;
+}
+
+
+/**
+ * gnome_preferences_get_toolbar_detachable:
+ *
+ */
+gboolean          gnome_preferences_get_toolbar_detachable   (void)
+{
+  return prefs.toolbar_detachable;
+}
+
+
+/**
+ * gnome_preferences_set_toolbar_detachable:
+ * @b:
+ *
+ */
+void              gnome_preferences_set_toolbar_detachable   (gboolean b)
+{
+  prefs.toolbar_detachable = b;
+}
+
+
+/**
+ * gnome_preferences_get_toolbar_relief:
+ *
+ */
+gboolean          gnome_preferences_get_toolbar_relief    (void)
+{
+  return prefs.toolbar_relief;
+}
+
+
+/**
+ * gnome_preferences_set_toolbar_relief:
+ * @b:
+ *
+ */
+void              gnome_preferences_set_toolbar_relief    (gboolean b)
+{
+  prefs.toolbar_relief = b;
+}
+
+
+/**
+ * gnome_preferences_get_toolbar_relief_btn:
+ *
+ */
+gboolean          gnome_preferences_get_toolbar_relief_btn (void)
+{
+  return prefs.toolbar_relief_btn;
+}
+
+
+/**
+ * gnome_preferences_set_toolbar_relief_btn:
+ * @b:
+ *
+ */
+void              gnome_preferences_set_toolbar_relief_btn (gboolean b)
+{
+  prefs.toolbar_relief_btn = b;
+}
+
+
+/**
+ * gnome_preferences_get_toolbar_lines:
+ *
+ */
+gboolean          gnome_preferences_get_toolbar_lines     (void)
+{
+  return prefs.toolbar_lines;
+}
+
+
+/**
+ * gnome_preferences_set_toolbar_lines:
+ * @b:
+ *
+ */
+void              gnome_preferences_set_toolbar_lines     (gboolean b)
+{
+  prefs.toolbar_lines = b;
+}
+
+
+/**
+ * gnome_preferences_get_toolbar_labels:
+ *
+ */
+gboolean          gnome_preferences_get_toolbar_labels    (void)
+{
+  return prefs.toolbar_labels;
+}
+
+
+/**
+ * gnome_preferences_set_toolbar_labels:
+ * @b:
+ *
+ */
+void              gnome_preferences_set_toolbar_labels    (gboolean b)
+{
+  prefs.toolbar_labels = b;
+}
+
+
+/**
+ * gnome_preferences_get_dialog_centered:
+ *
+ */
+gboolean          gnome_preferences_get_dialog_centered      (void)
+{
+  return prefs.dialog_centered;
+}
+
+
+/**
+ * gnome_preferences_set_dialog_centered:
+ * @b:
+ *
+ */
+void              gnome_preferences_set_dialog_centered      (gboolean b)
+{
+  prefs.dialog_centered = b;
+}
+
+
+/**
+ * gnome_preferences_get_dialog_type:
+ *
+ */
+GtkWindowType     gnome_preferences_get_dialog_type          (void)
+{
+  return prefs.dialog_type;
+}
+
+
+/**
+ * gnome_preferences_set_dialog_type:
+ * @t:
+ *
+ */
+void              gnome_preferences_set_dialog_type          (GtkWindowType t)
+{
+  prefs.dialog_type = t;
+}
+
+/* Whether dialogs are GTK_WIN_POS_NONE, GTK_WIN_POS_CENTER,
+   GTK_WIN_POS_MOUSE */
+
+/**
+ * gnome_preferences_get_dialog_position:
+ *
+ */
+GtkWindowPosition gnome_preferences_get_dialog_position      (void)
+{
+  return prefs.dialog_position;
+}
+
+
+/**
+ * gnome_preferences_set_dialog_position:
+ * @p:
+ *
+ */
+void              gnome_preferences_set_dialog_position      (GtkWindowPosition p)
+{
+  prefs.dialog_position = p;
+}
+
+
+/**
+ * gnome_preferences_get_mdi_mode:
+ *
+ */
+GnomeMDIMode      gnome_preferences_get_mdi_mode             (void)
+{
+  return prefs.mdi_mode;
+}
+
+
+/**
+ * gnome_preferences_set_mdi_mode:
+ * @m:
+ *
+ */
+void              gnome_preferences_set_mdi_mode             (GnomeMDIMode m)
+{
+  prefs.mdi_mode = m;
+}
+
+
+/**
+ * gnome_preferences_get_mdi_tab_pos:
+ *
+ */
+GtkPositionType   gnome_preferences_get_mdi_tab_pos          (void)
+{
+  return prefs.mdi_tab_pos;
+}
+
+
+/**
+ * gnome_preferences_set_mdi_tab_pos:
+ * @p:
+ *
+ */
+
+void              gnome_preferences_set_mdi_tab_pos          (GtkPositionType p)
+{
+  prefs.mdi_tab_pos = p;
+}
+
+
+/**
+ * gnome_preferences_get_property_box_apply:
+ *
+ */
+int gnome_preferences_get_property_box_apply (void)
+{
+	return prefs.property_box_buttons_apply;
+}
+
+
+/**
+ * gnome_preferences_set_property_box_button_apply:
+ * @v:
+ *
+ */
+
+void gnome_preferences_set_property_box_button_apply (int v)
+{
+	prefs.property_box_buttons_apply = v;
+}
+
+
+/**
+ * gnome_preferences_get_menus_have_tearoff:
+ *
+ */
+
+gboolean gnome_preferences_get_menus_have_tearoff (void)
+{
+	return prefs.menus_have_tearoff;
+}
+
+
+/**
+ * gnome_preferences_set_menus_have_tearoff:
+ * @b:
+ *
+ */
+void gnome_preferences_set_menus_have_tearoff (gboolean b)
+{
+	prefs.menus_have_tearoff = b;
+}
+
+
+/**
+ * gnome_preferences_get_menus_have_icons:
+ *
+ */
+int gnome_preferences_get_menus_have_icons (void)
+{
+	return prefs.menus_have_icons;
+}
+
+
+/**
+ * gnome_preferences_set_menus_have_icons:
+ * @have_icons:
+ *
+ */
+void gnome_preferences_set_menus_have_icons (int have_icons)
+{
+	prefs.menus_have_icons = have_icons ? TRUE : FALSE;
+}
+
+
+/**
+ * gnome_preferences_get_disable_imlib_cache:
+ *
+ * Description:
+ */
+int gnome_preferences_get_disable_imlib_cache (void)
+{
+	return prefs.disable_imlib_cache;
+}
+
+
+/**
+ * gnome_preferences_set_disable_imlib_cache:
+ * @disable_imlib_cache:
+ *
+ */
+void gnome_preferences_set_disable_imlib_cache (int disable_imlib_cache)
+{
+	prefs.disable_imlib_cache = disable_imlib_cache ? TRUE : FALSE;
+}
+
diff --git a/libgnomeui/gnome-preferences.h b/libgnomeui/gnome-preferences.h
new file mode 100644
index 0000000..3ff4fb8
--- /dev/null
+++ b/libgnomeui/gnome-preferences.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+/* DEPRECATED */
+#ifndef GNOME_PREFERENCES_H
+#define GNOME_PREFERENCES_H
+/****
+  Gnome preferences settings
+
+  These should be used only in libgnomeui and Gnome configuration
+  utilities. Don't worry about them otherwise, the library should
+  handle it (if not, fix the library, not your app).
+  ****/
+
+/*************
+          OK, these were already not supposed to be used; now they
+          are massively deprecated. Access the standardized GConf keys
+          directly, instead.
+**************/
+
+
+#include <gtk/gtkbbox.h>
+
+#include "gnome-mdi.h"
+
+G_BEGIN_DECLS
+
+/* Global config choices. App-specific choices are handled in GnomeApp. */
+
+/* By now an opaque type */
+typedef struct _GnomePreferences GnomePreferences;
+
+/* Load and sync the config file. */
+void gnome_preferences_load(void);
+void gnome_preferences_load_custom(GnomePreferences *settings);
+void gnome_preferences_save(void);
+void gnome_preferences_save_custom(GnomePreferences *settings);
+
+/* How buttons are layed out in dialogs */
+GtkButtonBoxStyle gnome_preferences_get_button_layout (void);
+void              gnome_preferences_set_button_layout (GtkButtonBoxStyle style);
+
+/* Whether to use the statusbar instead of dialogs when possible:
+   TRUE means use the statusbar */
+gboolean          gnome_preferences_get_statusbar_dialog     (void);
+void              gnome_preferences_set_statusbar_dialog     (gboolean statusbar);
+
+/* Whether the statusbar can be used for interactive questions 
+   TRUE means the statusbar is interactive */
+gboolean          gnome_preferences_get_statusbar_interactive(void);
+void              gnome_preferences_set_statusbar_interactive(gboolean b);
+
+/* Whether the AppBar progress meter goes on the right or left */
+gboolean          gnome_preferences_get_statusbar_meter_on_right (void);
+void              gnome_preferences_set_statusbar_meter_on_right (gboolean status_meter_on_right);
+
+
+/* Whether menubars can be detached */
+gboolean          gnome_preferences_get_menubar_detachable   (void);
+void              gnome_preferences_set_menubar_detachable   (gboolean b);
+
+/* Whether menubars have a beveled edge */
+gboolean          gnome_preferences_get_menubar_relief       (void);
+void              gnome_preferences_set_menubar_relief       (gboolean b);
+
+/* Whether toolbars can be detached */
+gboolean          gnome_preferences_get_toolbar_detachable   (void);
+void              gnome_preferences_set_toolbar_detachable   (gboolean b);
+
+/* Whether toolbars have a beveled edge  */
+gboolean          gnome_preferences_get_toolbar_relief       (void);
+void              gnome_preferences_set_toolbar_relief       (gboolean b);
+
+/* Whether toolbar buttons have a beveled edge */
+gboolean          gnome_preferences_get_toolbar_relief_btn   (void);
+void              gnome_preferences_set_toolbar_relief_btn   (gboolean b);
+
+/* Whether toolbars show lines in separators  */
+gboolean          gnome_preferences_get_toolbar_lines        (void);
+void              gnome_preferences_set_toolbar_lines        (gboolean b);
+
+/* Whether toolbars show labels  */
+gboolean          gnome_preferences_get_toolbar_labels       (void);
+void              gnome_preferences_set_toolbar_labels       (gboolean b);
+
+/* Whether to try to center dialogs over their parent window.
+   If it's possible, dialog_position is ignored. If not,
+   fall back to dialog_position. */
+gboolean          gnome_preferences_get_dialog_centered      (void);
+void              gnome_preferences_set_dialog_centered      (gboolean b);
+
+/* Whether dialogs are GTK_WINDOW_DIALOG or GTK_WINDOW_TOPLEVEL */
+GtkWindowType     gnome_preferences_get_dialog_type          (void);
+void              gnome_preferences_set_dialog_type          (GtkWindowType t);
+
+/* Whether dialogs are GTK_WIN_POS_NONE, GTK_WIN_POS_CENTER,
+   GTK_WIN_POS_MOUSE */
+GtkWindowPosition gnome_preferences_get_dialog_position      (void);
+void              gnome_preferences_set_dialog_position      (GtkWindowPosition p);
+
+/* default MDI mode and MDI notebook tab position */
+GnomeMDIMode      gnome_preferences_get_mdi_mode             (void);
+void              gnome_preferences_set_mdi_mode             (GnomeMDIMode m);
+GtkPositionType   gnome_preferences_get_mdi_tab_pos          (void);
+void              gnome_preferences_set_mdi_tab_pos          (GtkPositionType p);
+
+/* Whether property box has Apply button.  */
+int               gnome_preferences_get_property_box_apply (void);
+void              gnome_preferences_set_property_box_button_apply (int v);
+
+/* Whether menus can be torn off */
+gboolean          gnome_preferences_get_menus_have_tearoff   (void);
+void              gnome_preferences_set_menus_have_tearoff   (gboolean b);
+
+/* Whether menu items have icons in them or not */
+int               gnome_preferences_get_menus_have_icons (void);
+void              gnome_preferences_set_menus_have_icons (int have_icons);
+
+/* Whether we want to disable the imlib cache or not */
+int               gnome_preferences_get_disable_imlib_cache (void);
+void              gnome_preferences_set_disable_imlib_cache (int disable_imlib_cache);
+
+G_END_DECLS
+
+#endif
diff --git a/libgnomeui/gnome-recently-used.c b/libgnomeui/gnome-recently-used.c
new file mode 100644
index 0000000..b0956c8
--- /dev/null
+++ b/libgnomeui/gnome-recently-used.c
@@ -0,0 +1,1124 @@
+/*  -*- Mode: C; c-set-style: linux; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* GNOME GUI Library - gnome-recently-used.c
+ * Copyright (C) 2000  Red Hat Inc.,
+ * All rights reserved.
+ *
+ * Author: Havoc Pennington <hp redhat com>
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#include "gnome-recently-used.h"
+#include "gnome-macros.h"
+
+#include <sys/time.h>
+#include <stdlib.h>
+
+#include <libgnome/gnome-program.h>
+
+#include <gtk/gtk.h>
+
+#include <string.h>
+#include <errno.h>
+#include <libgnome/gnome-i18n.h>
+
+/* The default maximum number of documents */
+#define DEFAULT_MAX 30
+
+struct _GnomeRecentlyUsedPrivate {
+        GHashTable   *hash;
+        GConfClient  *conf;
+        guint         conf_notify;
+        GSList       *add_list;
+        gchar        *key_root;
+        gboolean      app_specific;
+};
+
+
+enum {
+        DOCUMENT_ADDED,
+        DOCUMENT_REMOVED,
+        DOCUMENT_CHANGED,
+        LAST_SIGNAL
+};
+
+enum {
+        PROP_0,
+        PROP_APP_SPECIFIC,
+        LAST_PARAM
+};
+
+static void                 gnome_recently_used_init               (GnomeRecentlyUsed      *recently_used);
+static void                 gnome_recently_used_class_init         (GnomeRecentlyUsedClass *klass);
+static void                 gnome_recently_used_destroy            (GtkObject              *object);
+static void                 gnome_recently_used_finalize           (GObject                *object);
+
+static void                 gnome_recently_used_get_property          (GObject                *object,
+								    guint                   param_id,
+								    GValue                 *value,
+								    GParamSpec             *pspec);
+static void                 gnome_recently_used_set_property          (GObject                *object,
+								    guint                   param_id,
+								    const GValue           *value,
+								    GParamSpec             *pspec);
+
+static GConfValue*          gnome_recent_document_to_gconf_value   (GnomeRecentDocument    *doc);
+static GnomeRecentDocument* gnome_recent_document_from_gconf_value (GConfValue             *val);
+static void                 gnome_recent_document_fill_from_gconf_value (GnomeRecentDocument *doc,
+                                                                         GConfValue        *val);
+
+static void                 gnome_recent_document_set_gconf_key    (GnomeRecentDocument    *doc,
+                                                                    const gchar            *key);
+static const gchar*         gnome_recent_document_get_gconf_key    (GnomeRecentDocument    *doc);
+static void                 documents_changed_notify               (GConfClient            *client,
+                                                                    guint                   cnxn_id,
+                                                                    GConfEntry             *entry,
+                                                                    gpointer                user_data);
+
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+GNOME_CLASS_BOILERPLATE(GnomeRecentlyUsed, gnome_recently_used,
+			GtkObject, gtk_object)
+
+static void
+gnome_recently_used_class_init (GnomeRecentlyUsedClass* klass)
+{
+        GtkObjectClass* object_class;
+        GObjectClass* gobject_class;
+
+        object_class = (GtkObjectClass*) klass;
+        gobject_class = (GObjectClass*) klass;
+
+	g_object_class_install_property (gobject_class,
+				      PROP_APP_SPECIFIC,
+				      g_param_spec_boolean ("app_specific",
+							    _("App Specific"),
+							    _("Is this list "
+							      "application "
+							      "specific"),
+							    FALSE,
+							    (G_PARAM_READABLE |
+							     G_PARAM_WRITABLE)));
+        signals[DOCUMENT_ADDED] =
+                gtk_signal_new ("document_added",
+                                GTK_RUN_FIRST,
+                                GTK_CLASS_TYPE (object_class),
+                                GTK_SIGNAL_OFFSET (GnomeRecentlyUsedClass, document_added),
+                                gtk_marshal_NONE__POINTER,
+                                GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
+
+        signals[DOCUMENT_REMOVED] =
+                gtk_signal_new ("document_removed",
+                                GTK_RUN_FIRST,
+                                GTK_CLASS_TYPE (object_class),
+                                GTK_SIGNAL_OFFSET (GnomeRecentlyUsedClass, document_removed),
+                                gtk_marshal_NONE__POINTER,
+                                GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
+
+        signals[DOCUMENT_CHANGED] =
+                gtk_signal_new ("document_changed",
+                                GTK_RUN_FIRST,
+                                GTK_CLASS_TYPE (object_class),
+                                GTK_SIGNAL_OFFSET (GnomeRecentlyUsedClass, document_changed),
+                                gtk_marshal_NONE__POINTER,
+                                GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
+
+
+        object_class->destroy = gnome_recently_used_destroy;
+
+        gobject_class->set_property = gnome_recently_used_set_property;
+        gobject_class->get_property = gnome_recently_used_get_property;
+        gobject_class->finalize = gnome_recently_used_finalize;
+}
+
+void
+gnome_recently_used_init (GnomeRecentlyUsed* recently_used)
+{
+	recently_used->_priv = g_new0 (GnomeRecentlyUsedPrivate, 1);
+
+}
+
+/* Does not actually load data, that is, it doesn't init the hash.
+ * All this does is set up the keys and the gconf notification */
+static void
+gnome_recently_used_ensure (GnomeRecentlyUsed *recently_used)
+{
+	if (recently_used->_priv->conf != NULL) {
+		/* if the conf is set, we are all set up */
+		return;
+	}
+        
+        if (recently_used->_priv->app_specific) {
+                recently_used->_priv->key_root = g_strconcat ("/apps/gnome-settings/",
+							      gnome_program_get_name (gnome_program_get()),
+							      "/recent-documents",
+							      NULL);
+	} else {
+                recently_used->_priv->key_root = g_strdup ("/desktop/standard/recent-documents");
+        }
+        
+        recently_used->_priv->conf = gnome_get_gconf_client ();
+
+        g_object_ref (G_OBJECT (recently_used->_priv->conf));
+        
+        /* No preload because the explicit all_entries call when ensuring
+           effectively results in a preload. */
+        gconf_client_add_dir (recently_used->_priv->conf,
+			      recently_used->_priv->key_root,
+			      GCONF_CLIENT_PRELOAD_NONE, NULL);
+        
+        recently_used->_priv->conf_notify =
+                gconf_client_notify_add (recently_used->_priv->conf,
+					 recently_used->_priv->key_root,
+					 documents_changed_notify,
+					 recently_used, NULL, NULL);
+}
+
+/* Actually load data */
+static void
+gnome_recently_used_ensure_data (GnomeRecentlyUsed *recently_used)
+{
+        GSList *all_entries;
+        GSList *iter;
+
+	if (recently_used->_priv->hash != NULL) {
+		/* if the hash is set, we are all set up */
+		return;
+	}
+
+	if (recently_used->_priv->conf == NULL)
+		gnome_recently_used_ensure (recently_used);
+        
+        
+        all_entries =
+                gconf_client_all_entries (recently_used->_priv->conf,
+					  recently_used->_priv->key_root,
+					  NULL);
+
+        recently_used->_priv->hash = g_hash_table_new (g_str_hash, g_str_equal);
+        
+        iter = all_entries;
+        while (iter != NULL) {
+                GConfEntry *entry = iter->data;
+                gchar* full_key;
+                GnomeRecentDocument *doc;
+                
+                full_key = gconf_concat_dir_and_key (recently_used->_priv->key_root,
+                                                     gconf_entry_get_key(entry));
+
+                doc = gnome_recent_document_from_gconf_value (gconf_entry_get_value (entry));
+
+                if (doc != NULL) {
+                        gnome_recent_document_ref (doc);
+                        gnome_recent_document_set_gconf_key (doc, full_key);
+                        
+                        g_hash_table_insert (recently_used->_priv->hash,
+					     (gchar*)gnome_recent_document_get_gconf_key(doc),
+					     doc);
+                }
+
+                g_free (full_key);
+                gconf_entry_free (entry);
+                
+                iter = g_slist_next (iter);
+        }
+        g_slist_free (all_entries);
+}
+
+static void
+destroy_foreach (gpointer key, gpointer value, gpointer user_data)
+{
+        gnome_recent_document_unref (value);
+}
+
+static void
+gnome_recently_used_clear (GnomeRecentlyUsed *recently_used)
+{
+        GSList *iter;
+
+	if (recently_used->_priv->add_list != NULL) {
+		iter = recently_used->_priv->add_list;
+		while (iter != NULL) {
+			gnome_recent_document_unref(iter->data);
+
+			iter = g_slist_next(iter);
+		}
+
+		g_slist_free(recently_used->_priv->add_list);
+		recently_used->_priv->add_list = NULL;
+	}
+
+	if (recently_used->_priv->hash != NULL) {
+		g_hash_table_foreach(recently_used->_priv->hash,
+				     destroy_foreach,
+				     recently_used);
+
+		g_hash_table_destroy(recently_used->_priv->hash);
+		recently_used->_priv->hash = NULL;
+	}
+
+	if (recently_used->_priv->conf != NULL) {
+		if (recently_used->_priv->conf_notify != 0) {
+			gconf_client_notify_remove(recently_used->_priv->conf,
+						   recently_used->_priv->conf_notify);
+			recently_used->_priv->conf_notify = 0;
+		}
+
+		gconf_client_remove_dir(recently_used->_priv->conf,
+					recently_used->_priv->key_root,
+                                        NULL);
+
+
+		g_object_unref(G_OBJECT(recently_used->_priv->conf));
+		recently_used->_priv->conf = NULL;
+	}
+}
+
+GnomeRecentlyUsed*
+gnome_recently_used_new (void)
+{
+        GnomeRecentlyUsed *recently_used;
+
+        recently_used = GNOME_RECENTLY_USED (gtk_type_new (gnome_recently_used_get_type ()));
+
+	recently_used->_priv->app_specific = FALSE;
+
+	gnome_recently_used_ensure (recently_used);
+
+        return recently_used;
+}
+
+GnomeRecentlyUsed*
+gnome_recently_used_new_app_specific (void)
+{
+        GnomeRecentlyUsed *recently_used;
+
+        recently_used = GNOME_RECENTLY_USED (gtk_type_new (gnome_recently_used_get_type ()));
+
+	recently_used->_priv->app_specific = FALSE;
+
+	gnome_recently_used_ensure (recently_used);
+        
+        return recently_used;
+}
+
+static void
+gnome_recently_used_get_property (GObject      *object,
+			       guint         param_id,
+			       GValue       *value,
+			       GParamSpec   *pspec)
+{
+        GnomeRecentlyUsed *recently_used;
+
+        recently_used = GNOME_RECENTLY_USED(object);
+
+        switch (param_id) {
+        case PROP_APP_SPECIFIC:
+		g_value_set_boolean (value,
+				     recently_used->_priv->app_specific);
+                break;
+
+        default:
+                break;
+        }
+}
+
+static void
+gnome_recently_used_set_property (GObject      *object,
+			       guint         param_id,
+			       const GValue *value,
+			       GParamSpec   *pspec)
+{
+        GnomeRecentlyUsed *recently_used;
+
+        recently_used = GNOME_RECENTLY_USED(object);
+
+        switch (param_id) {
+        case PROP_APP_SPECIFIC:
+		gnome_recently_used_clear (recently_used);
+                recently_used->_priv->app_specific = g_value_get_boolean (value);
+                gnome_recently_used_ensure (recently_used);
+                break;
+
+        default:
+                break;
+        }
+}
+
+static void
+gnome_recently_used_destroy (GtkObject* object)
+{
+        GnomeRecentlyUsed* recently_used;
+
+	/* remember, destroy can be run multiple times! */
+
+        recently_used = GNOME_RECENTLY_USED (object);
+
+	gnome_recently_used_clear (recently_used);
+
+	GNOME_CALL_PARENT_HANDLER (GTK_OBJECT_CLASS, destroy, (object));
+}
+
+static void
+gnome_recently_used_finalize (GObject* object)
+{
+        GnomeRecentlyUsed* recently_used;
+        
+        recently_used = GNOME_RECENTLY_USED (object);
+
+	g_free(recently_used->_priv);
+	recently_used->_priv = NULL;
+        
+	GNOME_CALL_PARENT_HANDLER (G_OBJECT_CLASS, finalize, (object));
+}
+
+/*
+ * Manipulate the recently used list
+ */
+
+/* The minus_one is a flag if we should subtract one, because we're about to 
+ * add an entry, This is not a perfect way to keep track of the maximum number
+ * of items, there are possible races etc...  But this is 1) simple 2) absolutely
+ * non-critical.  In the worst case we'll have one or two entries more if there is
+ * a race, I think it's worth the simiplicity. */
+static void
+gnome_recently_used_truncate (GnomeRecentlyUsed *recently_used,
+			      gboolean minus_one)
+{
+        gchar *full_key;
+	int max, size;
+	GConfValue *value;
+	GSList *list, *li;
+
+        full_key = gconf_concat_dir_and_key(recently_used->_priv->key_root,
+                                            "MaximumSize");
+
+	value = gconf_client_get (recently_used->_priv->conf,
+				  full_key, NULL);
+
+	g_free (full_key);
+
+	/* use DEFAULT_MAX */
+	if (value != NULL) {
+		max = gconf_value_get_int (value);
+		gconf_value_free (value);
+	} else {
+		max = DEFAULT_MAX;
+	}
+
+	/* Weird value == no limit */
+	if (max <= 0)
+		return;
+
+	if (minus_one)
+		max--;
+
+	size = g_hash_table_size (recently_used->_priv->hash);
+	if (size <= max)
+		return;
+
+	/* This is inefficent, but ok I'd say */
+	list = gnome_recently_used_get_all (recently_used);
+
+	list = g_slist_reverse (list);
+	li = list;
+
+	while (size > max &&
+	       li != NULL/* just for sanity, should never happen */) {
+		GnomeRecentDocument *doc = li->data;
+
+		gnome_recently_used_remove (recently_used, doc);
+
+		li = li->next;
+		size --;
+	}
+
+	g_slist_free (list);
+}
+
+/**
+ * gnome_recently_used_add:
+ * @recently_used: the #GnomeRecentlyUsed object
+ * @doc: document to add
+ *
+ * Description:  Add a document to the recently used list
+ **/
+void
+gnome_recently_used_add (GnomeRecentlyUsed   *recently_used,
+                         GnomeRecentDocument *doc)
+{
+        gchar *key;
+        gchar *full_key;
+        GConfValue *val;
+        
+	g_return_if_fail (recently_used != NULL);
+	g_return_if_fail (GNOME_IS_RECENTLY_USED (recently_used));
+	g_return_if_fail (doc != NULL);
+        g_return_if_fail (gnome_recent_document_get_gconf_key (doc) == NULL);
+
+	/* load data if we haven't done that yet */
+	gnome_recently_used_ensure_data (recently_used);
+
+	/* "Make room", that is truncate the list to max (minus one) items */
+	gnome_recently_used_truncate (recently_used, TRUE /* minus_one */);
+
+        key = gconf_unique_key ();
+
+        full_key = gconf_concat_dir_and_key(recently_used->_priv->key_root,
+                                            key);
+
+        g_free(key);
+
+        gnome_recent_document_set_gconf_key(doc, full_key);
+
+        val = gnome_recent_document_to_gconf_value(doc);
+        
+        gconf_client_set (recently_used->_priv->conf,
+			  full_key,
+			  val,
+			  NULL);
+
+        gconf_value_free(val);
+
+        g_free (full_key);
+
+        /* Store it in a list; we don't actually add it to the hash
+           until we get notification from GConf. But we need to
+           keep this same GnomeRecentDocument rather than creating
+           another one when we get that notification.
+        */
+        gnome_recent_document_ref (doc);
+        recently_used->_priv->add_list = g_slist_prepend (recently_used->_priv->add_list, doc);
+}
+
+void
+gnome_recently_used_remove (GnomeRecentlyUsed   *recently_used,
+                            GnomeRecentDocument *doc)
+{
+        g_return_if_fail(GNOME_IS_RECENTLY_USED(recently_used));
+        
+        gconf_client_unset(recently_used->_priv->conf,
+                           gnome_recent_document_get_gconf_key(doc),
+                           NULL);
+}
+
+static void
+listize_foreach(gpointer key, gpointer value, gpointer user_data)
+{
+        GSList **list = user_data;
+
+        *list = g_slist_prepend(*list, value);
+}
+
+static gint
+descending_chronological_compare_func(gconstpointer a, gconstpointer b)
+{
+        GTime a_time;
+        GTime b_time;
+
+        a_time = gnome_recent_document_get_creation_time((GnomeRecentDocument*)a);
+        b_time = gnome_recent_document_get_creation_time((GnomeRecentDocument*)b);
+
+        if (a_time > b_time)
+                return -1;
+        else if (a_time < b_time)
+                return 1;
+        else
+                return 0;
+}
+
+GSList*
+gnome_recently_used_get_all (GnomeRecentlyUsed   *recently_used)
+{
+        GSList *list = NULL;
+        
+        g_return_val_if_fail (recently_used != NULL, NULL);
+        g_return_val_if_fail (GNOME_IS_RECENTLY_USED(recently_used), NULL);
+
+	/* load data if we haven't done that yet */
+	gnome_recently_used_ensure_data (recently_used);
+
+        g_hash_table_foreach (recently_used->_priv->hash, listize_foreach,
+			      &list);
+
+        /* Sort from newest to oldest */
+        list = g_slist_sort (list, descending_chronological_compare_func);
+        
+        return list;
+}
+
+void
+gnome_recently_used_document_changed (GnomeRecentlyUsed   *recently_used,
+                                      GnomeRecentDocument *doc)
+{
+        GConfValue *val;
+        const gchar *key;
+
+        g_return_if_fail (recently_used != NULL);
+        g_return_if_fail (GNOME_IS_RECENTLY_USED(recently_used));
+        g_return_if_fail (doc != NULL);
+
+	/* load data if we haven't done that yet */
+	gnome_recently_used_ensure_data (recently_used);
+        
+        gnome_recent_document_ref(doc);
+
+        key = gnome_recent_document_get_gconf_key(doc);
+
+        g_return_if_fail(key != NULL);
+        g_return_if_fail(g_hash_table_lookup(recently_used->_priv->hash, key) == NULL);
+        
+        val = gnome_recent_document_to_gconf_value(doc);
+        
+        gconf_client_set(recently_used->_priv->conf,
+                         key,
+                         val,
+                         NULL);
+
+        gconf_value_free(val);        
+
+        gnome_recent_document_unref(doc);
+}
+
+static void
+documents_changed_notify(GConfClient* client, guint cnxn_id,
+                         GConfEntry *entry, gpointer user_data)
+{
+        GnomeRecentlyUsed *recently_used;
+        GnomeRecentDocument *doc;
+        GConfValue *value;
+        const gchar *key;
+
+        value = gconf_entry_get_value (entry);
+        key = gconf_entry_get_key (entry);
+        
+        recently_used = GNOME_RECENTLY_USED(user_data);
+
+	/* load data if we haven't done that yet */
+	gnome_recently_used_ensure_data (recently_used);
+
+        doc = g_hash_table_lookup(recently_used->_priv->hash,
+                                  key);
+
+        if (doc != NULL) {
+                if (value == NULL) {
+                        /* Has been removed */
+                        gtk_signal_emit(GTK_OBJECT(recently_used),
+                                        signals[DOCUMENT_REMOVED],
+                                        doc);
+
+                        gnome_recent_document_unref(doc);
+                        
+                        g_hash_table_remove(recently_used->_priv->hash, key);
+                        
+                        return;
+                } else {
+                        /* This entry has changed */
+                        gnome_recent_document_fill_from_gconf_value(doc,
+                                                                    value);
+                        
+                        gtk_signal_emit(GTK_OBJECT(recently_used),
+                                        signals[DOCUMENT_CHANGED],
+                                        doc);
+                        
+                        return;
+                }
+        } else {
+                /* This is a new entry */
+
+                GSList *iter;
+
+                if (value == NULL) {
+                        /* Someone deleted an entry we never knew about anyway */
+                        return;
+                }
+                
+                /* Scan the add list, so we recycle the
+                   GnomeRecentDocument if the addition came from the
+                   same process (and more importantly maintain the
+                   mapping of one GnomeRecentDocument per gconf key) */
+
+                iter = recently_used->_priv->add_list;
+
+                while (iter != NULL) {
+                        const gchar* this_key;
+
+                        this_key = gnome_recent_document_get_gconf_key(iter->data);
+
+                        g_assert(this_key != NULL);
+                        
+                        if (strcmp(key, this_key) == 0) {
+                                doc = iter->data;
+                                break;
+                        }
+
+                        iter = g_slist_next(iter);
+                }
+
+                if (doc != NULL) {
+                        /* Here we assume the value received is the same
+                           as the value we sent (since we don't fill_from_value)
+                           which isn't necessarily true but is a lot faster
+                           and will pretty much always be true */
+                        recently_used->_priv->add_list = g_slist_remove(recently_used->_priv->add_list,
+									doc);
+
+                        g_hash_table_insert(recently_used->_priv->hash,
+                                            (gchar*)gnome_recent_document_get_gconf_key(doc),
+                                            doc);
+                } else {
+                        doc = gnome_recent_document_from_gconf_value(value);
+
+                        if (doc == NULL) {
+                                /* Value was junk somehow */
+                                return;
+                        }
+                        
+                        gnome_recent_document_set_gconf_key(doc, key);
+                        g_hash_table_insert(recently_used->_priv->hash,
+                                            (gchar*)gnome_recent_document_get_gconf_key(doc),
+                                            doc);
+                }
+
+                if (doc != NULL) {
+                        gtk_signal_emit(GTK_OBJECT(recently_used),
+                                        signals[DOCUMENT_ADDED],
+                                        doc);
+                }
+        }
+}
+
+
+void
+gnome_recently_used_add_simple       (GnomeRecentlyUsed   *recently_used,
+                                      const gchar         *command,
+                                      const gchar         *menu_text,
+                                      const gchar         *menu_pixmap,
+                                      const gchar         *menu_hint,
+                                      const gchar         *filename,
+                                      const gchar         *mime_type)
+{
+        GnomeRecentDocument *doc;
+        const gchar *appid;
+        
+        doc = gnome_recent_document_new();
+
+        if (command)
+                gnome_recent_document_set(doc, "command", command);
+
+        if (menu_text)
+                gnome_recent_document_set(doc, "menu-text", menu_text);
+
+        if (menu_pixmap)
+                gnome_recent_document_set(doc, "menu-pixmap", menu_pixmap);
+
+        if (menu_hint)
+                gnome_recent_document_set(doc, "menu-hint", menu_hint);
+
+        if (filename)
+                gnome_recent_document_set(doc, "filename", filename);
+
+        if (mime_type)
+                gnome_recent_document_set(doc, "mime-type", mime_type);
+        
+        appid = gnome_program_get_name(gnome_program_get());
+
+        gnome_recent_document_set(doc, "app", appid);
+        
+        gnome_recently_used_add (recently_used, doc);
+
+        gnome_recent_document_unref(doc);
+}
+
+/*
+ * Recent document data type
+ */
+
+struct _GnomeRecentDocument {
+        guint refcount;
+
+        /* Could use a hash table here and save some code,
+           but it's quite a bit more RAM and likely not faster
+           for this number of elements */
+        gchar *command;
+        gchar *menu_text;
+        gchar *menu_pixmap;
+        gchar *menu_hint;
+        gchar *filename;
+        gchar *mime_type;
+        gchar *gconf_key;
+        gchar *app_id;
+
+        GTime creation_time;
+};
+
+GnomeRecentDocument*
+gnome_recent_document_new (void)
+{
+        GnomeRecentDocument *doc;
+
+        doc = g_new0(GnomeRecentDocument, 1);
+
+        doc->refcount = 1;
+
+        doc->creation_time = time(NULL);
+        
+        return doc;
+}
+
+GnomeRecentDocument *
+gnome_recent_document_ref (GnomeRecentDocument *doc)
+{
+        g_return_val_if_fail(doc != NULL, NULL);
+
+        doc->refcount += 1;
+
+	return doc;
+}
+
+static void
+clear_doc (GnomeRecentDocument *doc)
+{
+        /* ignore gconf_key, creation_time, and refcount
+           since we keep those when filling a doc from
+           a GConfValue */
+        
+        g_free(doc->command);
+        doc->command = NULL;
+
+        g_free(doc->menu_hint);
+        doc->menu_hint = NULL;
+
+        g_free(doc->menu_pixmap);
+        doc->menu_pixmap = NULL;
+
+        g_free(doc->menu_text);
+        doc->menu_text = NULL;
+
+        g_free(doc->filename);
+        doc->filename = NULL;
+
+        g_free(doc->mime_type);
+        doc->mime_type = NULL;
+
+        g_free(doc->app_id);
+        doc->app_id = NULL;
+}
+
+void
+gnome_recent_document_unref (GnomeRecentDocument *doc)
+{
+        g_return_if_fail(doc != NULL);
+        g_return_if_fail(doc->refcount > 0);
+        
+        doc->refcount -= 1;
+
+        if (doc->refcount == 0) {
+                clear_doc(doc);
+
+                g_free(doc->gconf_key);
+                doc->gconf_key = NULL;
+
+                g_free(doc);
+        }
+}
+
+static gchar**
+find_arg(GnomeRecentDocument *doc,
+         const gchar *arg)
+{
+        if (strcmp(arg, "command") == 0)
+                return &doc->command;
+        else if (strcmp(arg, "menu-text") == 0)
+                return &doc->menu_text;
+        else if (strcmp(arg, "menu-pixmap") == 0)
+                return &doc->menu_pixmap;
+        else if (strcmp(arg, "menu-hint") == 0)
+                return &doc->menu_hint;
+        else if (strcmp(arg, "filename") == 0)
+                return &doc->filename;
+        else if (strcmp(arg, "mime-type") == 0)        
+                return &doc->mime_type;
+        else if (strcmp(arg, "app") == 0)
+                return &doc->app_id;
+        else {
+                g_warning("Unknown GnomeRecentDocument arg %s", arg);
+                return NULL;
+        }
+}
+
+/* Available args:
+      "command" - command to run when menu item is selected
+      "menu-text" - menu text to display
+      "menu-pixmap" - pixmap filename to display
+      "menu-hint" - menu hint to put in statusbar
+      "filename" - document filename (maybe used if command isn't run)
+*/
+void
+gnome_recent_document_set            (GnomeRecentDocument *doc,
+                                      const gchar         *arg,
+                                      const gchar         *val)
+{
+        gchar** setme;
+
+        g_return_if_fail (doc != NULL);
+        g_return_if_fail (arg != NULL);
+
+        setme = find_arg(doc, arg);
+
+        /* This check is required, since arg may come in from GConf and
+           be invalid */
+
+        setme = find_arg(doc, arg);
+
+        /* This check is required, since arg may come in from GConf and
+           be invalid */
+        if (setme == NULL) {
+                g_warning(_("bad GnomeRecentDocument attribute: %s\n"), arg);
+                return;
+        }
+        
+        if (*setme != NULL)
+                g_free(*setme);
+
+        *setme = val ? g_strdup(val) : NULL;
+}
+
+const gchar*
+gnome_recent_document_peek (GnomeRecentDocument *doc,
+			    const gchar         *arg)
+{
+        gchar** getme;
+
+        g_return_val_if_fail (doc != NULL, NULL);
+        g_return_val_if_fail (arg != NULL, NULL);
+
+        getme = find_arg(doc, arg);
+
+        if (getme)
+                return *getme;
+        else {
+                g_warning("bad GnomeRecentDocument attribute: %s\n", arg);
+                return NULL;
+        }
+}
+
+GTime
+gnome_recent_document_get_creation_time (GnomeRecentDocument *doc)
+{
+        g_return_val_if_fail (doc != NULL, 0);
+
+        return doc->creation_time;
+}
+
+static void
+gnome_recent_document_set_gconf_key    (GnomeRecentDocument    *doc,
+                                        const gchar            *key)
+{
+        g_return_if_fail (doc != NULL);
+        g_return_if_fail (key != NULL);
+
+        if (doc->gconf_key != NULL)
+                g_free(doc->gconf_key);
+
+        doc->gconf_key = g_strdup(key);
+}
+
+static const gchar*
+gnome_recent_document_get_gconf_key    (GnomeRecentDocument    *doc)
+{
+        g_return_val_if_fail (doc != NULL, NULL);
+
+        return doc->gconf_key;
+}
+
+static gchar*
+encode_arg (const gchar* arg, const gchar* val)
+{
+        if (val == NULL)
+                return NULL;
+        else
+                return g_strconcat(arg, ":", val, NULL);
+}
+
+static void
+decode_arg(const gchar* arg, gchar** argp, gchar** valp)
+{
+        const gchar* colon;
+
+        colon = strchr(arg, ':');
+
+        if (colon == NULL)
+                goto failed;
+
+        *argp = g_strndup(arg, colon - arg);
+        ++colon;
+        *valp = g_strdup(colon);
+        
+        return;
+        
+ failed:
+        *argp = NULL;
+        *valp = NULL;
+}
+
+static void
+add_arg(GnomeRecentDocument *doc, GSList** listp, const gchar* argname, const gchar* argval)
+{
+        gchar* encoded;
+        GConfValue* val;
+
+        if (argval == NULL)
+                return;
+        
+        encoded = encode_arg(argname, argval);
+
+        g_assert(encoded);
+
+                
+        val = gconf_value_new(GCONF_VALUE_STRING);
+        gconf_value_set_string(val, encoded);
+        g_free(encoded);
+        
+        *listp = g_slist_prepend(*listp, val);
+}
+
+static GConfValue*
+gnome_recent_document_to_gconf_value (GnomeRecentDocument *doc)
+{
+        GConfValue *val;
+        GSList *list = NULL;
+        gchar *t;
+
+	g_return_val_if_fail (doc != NULL, NULL);
+        
+        val = gconf_value_new(GCONF_VALUE_LIST);
+        gconf_value_set_list_type(val, GCONF_VALUE_STRING);
+        
+        add_arg(doc, &list, "command", doc->command);
+        add_arg(doc, &list, "menu-text", doc->menu_text);
+        add_arg(doc, &list, "menu-pixmap", doc->menu_pixmap);
+        add_arg(doc, &list, "menu-hint", doc->menu_hint);
+        add_arg(doc, &list, "filename", doc->filename);
+        add_arg(doc, &list, "mime-type", doc->mime_type);
+        add_arg(doc, &list, "app", doc->app_id);
+
+        t = g_strdup_printf("%lu", (gulong)doc->creation_time);
+
+        add_arg(doc, &list, "creation-time", t);
+        g_free(t);
+        
+        gconf_value_set_list_nocopy(val, list);
+
+        return val;
+}
+
+static gulong
+string_to_gulong(const gchar* str)
+{
+	gulong retval;
+
+	errno = 0;
+	retval = strtoul(str, NULL, 10);
+	if (errno != 0)
+		retval = 0;
+
+	return retval;
+}
+
+static gboolean
+fill_doc(GnomeRecentDocument **docp, GConfValue *val)
+{
+        GSList *iter;
+        
+        if (val == NULL)
+                return FALSE;
+
+        if (val->type != GCONF_VALUE_LIST)
+                return FALSE;
+
+        if (gconf_value_get_list_type(val) != GCONF_VALUE_STRING)
+                return FALSE;
+        
+        iter = gconf_value_get_list(val);
+
+        while (iter != NULL) {
+                GConfValue *elem;
+
+                elem = iter->data;
+                
+                g_assert(elem != NULL);
+
+                if (elem->type == GCONF_VALUE_STRING) {
+                        const gchar* encoded;
+                        gchar* arg = NULL;
+                        gchar* argval = NULL;
+                        
+                        encoded = gconf_value_get_string(elem);
+
+                        decode_arg(encoded, &arg, &argval);
+
+                        if (arg) {
+                                /* create the doc only if we get > 0 args */
+                                if (*docp == NULL)
+                                        *docp = gnome_recent_document_new();
+
+                                if (strcmp(arg, "creation-time") == 0) {
+                                        (*docp)->creation_time = string_to_gulong(argval);
+                                } else {
+                                        gnome_recent_document_set(*docp, arg, argval);
+                                }
+                        }
+
+                        g_free(arg);
+                        g_free(argval);
+                }
+                
+                iter = g_slist_next(iter);
+        }
+
+        return TRUE;
+}
+
+static GnomeRecentDocument*
+gnome_recent_document_from_gconf_value (GConfValue *val)
+{
+        GnomeRecentDocument *doc = NULL;
+
+        fill_doc(&doc, val);
+
+        if (doc && doc->menu_text == NULL) {
+                /* Junk value */
+                gnome_recent_document_unref(doc);
+                return NULL;
+        }
+                
+        return doc;        
+}
+
+static void
+gnome_recent_document_fill_from_gconf_value (GnomeRecentDocument *doc,
+                                             GConfValue *val)
+{
+        clear_doc(doc);
+        fill_doc(&doc, val);
+        /* guarantee that menu name always exists */
+        if (doc->menu_text == NULL)
+                doc->menu_text = g_strdup(_("Unknown"));
+}
diff --git a/libgnomeui/gnome-recently-used.h b/libgnomeui/gnome-recently-used.h
new file mode 100644
index 0000000..d0642df
--- /dev/null
+++ b/libgnomeui/gnome-recently-used.h
@@ -0,0 +1,112 @@
+/*  -*- Mode: C; c-set-style: linux; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* GNOME GUI Library - gnome-recently-used.h
+ * Copyright (C) 2000  Red Hat Inc.,
+ * All rights reserved.
+ *
+ * Author: Havoc Pennington <hp redhat com>
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#ifndef GNOME_RECENTLY_USED_H
+#define GNOME_RECENTLY_USED_H
+
+
+#include <libgnomeui/gnome-gconf.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GnomeRecentDocument GnomeRecentDocument;
+
+#define GNOME_TYPE_RECENTLY_USED            (gnome_recently_used_get_type())
+#define GNOME_RECENTLY_USED(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_RECENTLY_USED, GnomeRecentlyUsed))
+#define GNOME_RECENTLY_USED_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_RECENTLY_USED, GnomeRecentlyUsedClass))
+#define GNOME_IS_RECENTLY_USED(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_RECENTLY_USED))
+#define GNOME_IS_RECENTLY_USED_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_RECENTLY_USED))
+#define GNOME_RECENTLY_USED_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_RECENTLY_USED, GnomeRecentlyUsedClass))
+
+typedef struct _GnomeRecentlyUsed        GnomeRecentlyUsed;
+typedef struct _GnomeRecentlyUsedPrivate GnomeRecentlyUsedPrivate;
+typedef struct _GnomeRecentlyUsedClass   GnomeRecentlyUsedClass;
+
+struct _GnomeRecentlyUsed {
+        GtkObject parent_instance;
+
+	/*< private >*/
+	GnomeRecentlyUsedPrivate *_priv;
+};
+
+struct _GnomeRecentlyUsedClass {
+        GtkObjectClass parent_class;
+
+        void (* document_added) (GnomeRecentlyUsed* obj, GnomeRecentDocument *doc);
+        void (* document_removed) (GnomeRecentlyUsed* obj, GnomeRecentDocument *doc);
+        void (* document_changed) (GnomeRecentlyUsed* obj, GnomeRecentDocument *doc);
+};
+
+GtkType              gnome_recently_used_get_type         (void) G_GNUC_CONST;
+GnomeRecentlyUsed*   gnome_recently_used_new              (void);
+GnomeRecentlyUsed*   gnome_recently_used_new_app_specific (void);
+
+void                 gnome_recently_used_add              (GnomeRecentlyUsed   *recently_used,
+                                                           GnomeRecentDocument *doc);
+void                 gnome_recently_used_remove           (GnomeRecentlyUsed   *recently_used,
+                                                           GnomeRecentDocument *doc);
+GSList*              gnome_recently_used_get_all          (GnomeRecentlyUsed   *recently_used);
+
+void                 gnome_recently_used_document_changed (GnomeRecentlyUsed   *recently_used,
+                                                           GnomeRecentDocument *doc);
+
+/* convenience wrapper to allow ignoring the GnomeRecentDocument data
+   type. string args can be NULL. auto-sets the app ID and creation time */
+void                 gnome_recently_used_add_simple       (GnomeRecentlyUsed   *recently_used,
+                                                           const gchar         *command,
+                                                           const gchar         *menu_text,
+                                                           const gchar         *menu_pixmap,
+                                                           const gchar         *menu_hint,
+                                                           const gchar         *filename,
+                                                           const gchar         *mime_type);
+
+GnomeRecentDocument* gnome_recent_document_new            (void);
+GnomeRecentDocument* gnome_recent_document_ref            (GnomeRecentDocument *doc);
+void                 gnome_recent_document_unref          (GnomeRecentDocument *doc);
+
+/* Available args:
+      "command" - command to run when menu item is selected
+      "menu-text" - menu text to display
+      "menu-pixmap" - pixmap filename to display
+      "menu-hint" - menu hint to put in statusbar
+      "filename" - document filename (maybe used if command isn't run)
+      "mime-type" - mime type of the file
+      "app" - application ID of the app creating the GnomeRecentDocument
+*/
+void                 gnome_recent_document_set            (GnomeRecentDocument *doc,
+                                                           const gchar         *arg,
+                                                           const gchar         *val);
+
+/* can return NULL if the arg wasn't set for whatever reason */
+const gchar*         gnome_recent_document_peek            (GnomeRecentDocument *doc,
+							    const gchar         *arg);
+
+
+GTime                gnome_recent_document_get_creation_time (GnomeRecentDocument *doc);
+
+
+G_END_DECLS
+
+#endif
diff --git a/libgnomeui/gnome-remote-bootstrap.c b/libgnomeui/gnome-remote-bootstrap.c
new file mode 100644
index 0000000..0d30421
--- /dev/null
+++ b/libgnomeui/gnome-remote-bootstrap.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 1999, 2000 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * 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 the Gnome Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#include <libgnome/libgnome.h>
+#include <libgnomeui/gnome-init.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+
+static char *display = NULL, *languages = NULL;
+static int ior_fd = -1;
+
+struct poptOption options[] = {
+  {"display", '\0', POPT_ARG_STRING, &display, 0},
+  {"ior-fd", '\0', POPT_ARG_INT, &ior_fd, 0},
+  {"languages", '\0', POPT_ARG_STRING, &languages, 0},
+  {NULL}
+};
+
+typedef struct {
+  FILE *pipe_fh;
+  GMainLoop *ml;
+  int pipe_fd, pipe_tag;
+} proginfo;
+
+static gboolean handle_commands(GIOChannel *ioc, GIOCondition cond, gpointer data);
+static gboolean relay_output   (GIOChannel *ioc, GIOCondition cond, gpointer data);
+
+int main(int argc, char **argv)
+{
+  proginfo myprog;
+
+  gnome_program_init("gnome-remote-bootstrap", VERSION, &libgnomeui_module_info,
+		     argc, argv, GNOME_PARAM_POPT_TABLE, options, NULL);
+
+  if(!display
+     || (ior_fd < 0))
+    {
+      g_printerr("This is program is used internally to bootstrap the network connections for the desktop.\n");
+      return 1;
+    }
+
+  setenv("DISPLAY", display, TRUE);
+  if(strcmp(languages, "C"))
+    setenv("LANG", languages, TRUE);
+
+  memset(&myprog, 0, sizeof(myprog));
+  myprog.pipe_fd = -1;
+
+  myprog.ml = g_main_new(FALSE);
+
+  {
+    GIOChannel *glib_bites = g_io_channel_unix_new(0); /* stdin */
+
+    g_io_add_watch(glib_bites, G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL, handle_commands, &myprog);
+    g_io_channel_unref(glib_bites);
+  }
+  
+  fprintf(stdout, "GNOME BOOTSTRAP READY\n");
+  fflush(stdout);
+
+  g_main_run(myprog.ml);
+
+  return 0;
+}
+
+static gboolean
+handle_commands(GIOChannel *ioc, GIOCondition cond, gpointer data)
+{
+  char aline[4096];
+  proginfo *pi = (proginfo *) data;
+
+  if(!(cond & G_IO_IN))
+    {
+      g_main_quit(pi->ml);
+      return FALSE;
+    }
+
+  if(!fgets(aline, sizeof(aline), stdin))
+    {
+      g_main_quit(pi->ml);
+      return FALSE;
+    }
+
+  g_strstrip(aline);
+
+  if(!strcmp(aline, "DONE"))
+    {
+      g_main_quit(pi->ml);
+      return FALSE;
+    }
+  else if(!strncmp(aline, "RUN ", strlen("RUN ")))
+    {
+      int pipes[2];
+      int childpid;
+      char **pieces;
+      int i;
+
+      if(pipe(pipes))
+	goto err;
+
+      dup2(pipes[1], ior_fd);
+      pieces = g_strsplit(aline + strlen("RUN "), " ", -1);
+      for(i = 0; pieces[i]; i++) /**/;
+
+      childpid = gnome_execute_async_fds(NULL, i, pieces, FALSE);
+
+      if(childpid < 0)
+	{
+	  close(pipes[1]);
+	  close(pipes[0]);
+	  close(ior_fd);
+	  goto err;
+	}
+      close(pipes[1]);
+      pi->pipe_fd = pipes[0];
+      pi->pipe_fh = fdopen(pi->pipe_fd, "r");
+      {
+	GIOChannel *glib_bites = g_io_channel_unix_new(pi->pipe_fd);
+
+	pi->pipe_tag = g_io_add_watch(glib_bites, G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL, relay_output, pi);
+	g_io_channel_unref(glib_bites);
+      }
+
+      return TRUE;
+    err:
+      fprintf(stdout, "ERROR\n");
+      fflush(stdout);
+      return TRUE;
+    }
+
+  return TRUE;
+}
+
+static gboolean
+relay_output(GIOChannel *ioc, GIOCondition cond, gpointer data)
+{
+  char aline[4096];
+  proginfo *pi = (proginfo *) data;
+
+  if(!(cond & G_IO_IN))
+    goto err;
+
+  if(!fgets(aline, sizeof(aline), pi->pipe_fh))
+    goto err;
+
+  fprintf(stdout, "OUTPUT %s%s", aline,
+	  (aline[strlen(aline) - 1] == '\n')?"":"\n");
+  fflush(stdout);
+
+  return TRUE;
+
+ err:
+  g_source_remove(pi->pipe_tag);
+  fclose(pi->pipe_fh);
+  return FALSE;
+}
diff --git a/libgnomeui/gnome-rexec-server.c b/libgnomeui/gnome-rexec-server.c
new file mode 100644
index 0000000..c9aeebb
--- /dev/null
+++ b/libgnomeui/gnome-rexec-server.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 1999, 2000 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * 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 the Gnome Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#include <liboaf/liboaf.h>
+
+#include <libgnome/gnome-exec.h>
+#include <errno.h>
+#include "gnome-corba-rexec.h"
+
+static CORBA_long
+impl_execVectorEnvPath(POA_GNOME_RemoteExecution *servant,
+		       GNOME_stringlist *argv,
+		       GNOME_stringlist *envp,
+		       CORBA_Environment *ev)
+{
+  int retval;
+
+  retval = gnome_execute_async_with_env(NULL, argv->_length, argv->_buffer, envp->_length, envp->_buffer);
+  if(retval < 0) {
+    int myerrno = errno;
+    GNOME_RemoteExecution_POSIXError *raiseme = GNOME_RemoteExecution_POSIXError__alloc();
+
+    raiseme->unportable_errno = myerrno;
+    raiseme->errstr = CORBA_string_dup(g_strerror(myerrno));
+
+    CORBA_exception_set(ev, CORBA_USER_EXCEPTION, ex_GNOME_RemoteExecution_POSIXError, raiseme);
+  }
+
+  return retval;
+}
+
+int main(int argc, char *argv[])
+{
+  static POA_GNOME_RemoteExecution__epv POA_GNOME_RemoteExecution_epv = {
+    NULL, /* _private */
+    (gpointer)&impl_execVectorEnvPath
+  };
+  static POA_GNOME_RemoteExecution__vepv POA_GNOME_RemoteExecution_vepv = {
+    NULL, /* _private */
+    &POA_GNOME_RemoteExecution_epv
+  };
+  static POA_GNOME_RemoteExecution rexec_servant = {
+    NULL, /* _private */
+    &POA_GNOME_RemoteExecution_vepv
+  };
+  GMainLoop *ml;
+  CORBA_ORB orb;
+  PortableServer_POA poa;
+  CORBA_Environment ev;
+  CORBA_Object rexec_client;
+
+  CORBA_exception_init(&ev);
+  orb = oaf_init(argc, argv);
+
+  poa = (PortableServer_POA)CORBA_ORB_resolve_initial_references(orb, "RootPOA", &ev);
+  PortableServer_POAManager_activate(PortableServer_POA__get_the_POAManager(poa, &ev), &ev);
+  PortableServer_POA_activate_object(poa, &rexec_servant, &ev);
+
+  rexec_client = PortableServer_POA_servant_to_reference(poa,
+							 &rexec_servant,
+							 &ev);
+
+  oaf_active_server_register("OAFIID:gnome-rexec:19991122", rexec_client);
+
+  ml = g_main_new(FALSE);
+  g_main_run(ml);
+
+  return 0;
+}
diff --git a/libgnomeui/gnome-rexec-server.oafinfo b/libgnomeui/gnome-rexec-server.oafinfo
new file mode 100644
index 0000000..65d0727
--- /dev/null
+++ b/libgnomeui/gnome-rexec-server.oafinfo
@@ -0,0 +1,5 @@
+<oaf_server iid="OAFIID:gnome-rexec:19991122" type="exe" location="gnome-rexec-server">
+<oaf_attribute name="repo_ids" type="stringv">
+<item value="IDL:GNOME/RemoteExecution:1.0"/>
+</oaf_attribute>
+</oaf_server>
diff --git a/libgnomeui/gnome-roo.c b/libgnomeui/gnome-roo.c
new file mode 100644
index 0000000..6288401
--- /dev/null
+++ b/libgnomeui/gnome-roo.c
@@ -0,0 +1,1320 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* gnome-roo.c
+
+   Copyright (C) 2000 Jaka Mocnik
+
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Jaka Mocnik <jaka mocnik kiss uni-lj si>
+*/
+
+#include <config.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+
+#include <libgnome/gnome-i18n.h>
+#include "gnome-roo.h"
+#include "gnome-pouch.h"
+#include "gnome-pouchP.h"
+
+#define ROO_CLOSE_HILIT    (1L << 0)
+#define ROO_ICONIFY_HILIT  (1L << 1)
+#define ROO_MAXIMIZE_HILIT (1L << 2)
+#define ROO_ICONIFIED      (1L << 3)
+#define ROO_MAXIMIZED      (1L << 4)
+#define ROO_SELECTED       (1L << 5)
+#define ROO_IN_MOVE        (1L << 6)
+#define ROO_IN_RESIZE      (1L << 7)
+#define ROO_ICON_PARKED    (1L << 8)
+#define ROO_WAS_ICONIFIED  (1L << 9)
+#define ROO_UNPOSITIONED   (1L << 10)
+
+enum
+{
+	CLOSE,
+	ICONIFY,
+	UNICONIFY,
+    MAXIMIZE,
+    UNMAXIMIZE,
+	SELECT,
+	DESELECT,
+	LAST_SIGNAL
+};
+
+typedef enum
+{
+	RESIZE_TOP_LEFT,
+	RESIZE_TOP,
+    RESIZE_TOP_RIGHT,
+    RESIZE_RIGHT,
+	RESIZE_BOTTOM_RIGHT,
+    RESIZE_BOTTOM,
+    RESIZE_BOTTOM_LEFT,
+    RESIZE_LEFT,
+	RESIZE_NONE,
+} GnomeRooResizeType;
+
+static void gnome_roo_class_init(GnomeRooClass *klass);
+static void gnome_roo_init(GnomeRoo *roo);
+static void gnome_roo_finalize(GObject *object);
+static void gnome_roo_size_request(GtkWidget *w, GtkRequisition *req);
+static void gnome_roo_realize(GtkWidget *w);
+static void gnome_roo_unrealize(GtkWidget *w);
+static void gnome_roo_map(GtkWidget *w);
+static void gnome_roo_unmap(GtkWidget *w);
+static void gnome_roo_size_allocate(GtkWidget *w, GtkAllocation *allocation);
+static void gnome_roo_paint(GtkWidget *w, GdkRectangle *area);
+static gboolean gnome_roo_expose(GtkWidget *w, GdkEventExpose *e);
+static gboolean gnome_roo_button_press(GtkWidget *w, GdkEventButton *e);
+static gboolean gnome_roo_button_release(GtkWidget *w, GdkEventButton *e);
+static gboolean gnome_roo_motion_notify(GtkWidget *w, GdkEventMotion *e);
+static void gnome_roo_maximize(GnomeRoo *roo);
+static void gnome_roo_unmaximize(GnomeRoo *roo);
+static void gnome_roo_iconify(GnomeRoo *roo);
+static void gnome_roo_uniconify(GnomeRoo *roo);
+static void gnome_roo_select(GnomeRoo *roo);
+static void gnome_roo_deselect(GnomeRoo *roo);
+static void gnome_roo_parent_set(GtkWidget *widget, GtkWidget *old_parent);
+
+static GnomeRooResizeType get_resize_type(GnomeRoo *roo, gint x, gint y);
+static void calculate_size(GnomeRoo *roo, guint *rw, guint *rh);
+static void calculate_title_size(GnomeRoo *roo);
+static gboolean in_title_bar(GnomeRoo *roo, guint x, guint y);
+static gboolean in_close_button(GnomeRoo *roo, guint x, guint y);
+static gboolean in_maximize_button(GnomeRoo *roo, guint x, guint y);
+static gboolean in_iconify_button(GnomeRoo *roo, guint x, guint y);
+static void draw_shadow(GtkWidget *widget, GtkStateType state, gboolean out, gint x, gint y, gint w, gint h);
+static void draw_cross(GtkWidget *widget, GdkGC *gc, gint x, gint y, gint s);
+static void paint_close_button(GnomeRoo *roo, gboolean hilight);
+static void paint_iconify_button(GnomeRoo *roo, gboolean hilight);
+static void paint_maximize_button(GnomeRoo *roo, gboolean hilight);
+
+static GdkCursor *resize_cursor[8] = { NULL, NULL, NULL, NULL,
+									   NULL, NULL, NULL, NULL };
+static GdkCursor *move_cursor = NULL;
+static GdkCursorType resize_cursor_type[8] = {
+	GDK_TOP_LEFT_CORNER,
+	GDK_TOP_SIDE,
+	GDK_TOP_RIGHT_CORNER,
+	GDK_RIGHT_SIDE,
+	GDK_BOTTOM_RIGHT_CORNER,
+	GDK_BOTTOM_SIDE,
+	GDK_BOTTOM_LEFT_CORNER,
+	GDK_LEFT_SIDE,
+};
+
+static gint roo_signals[LAST_SIGNAL];
+
+static GtkObjectClass *parent_class;
+
+guint
+gnome_roo_get_type()
+{
+	static guint roo_type = 0;
+	
+	if (!roo_type) {
+		GtkTypeInfo roo_info = {
+			"GnomeRoo",
+			sizeof(GnomeRoo),
+			sizeof(GnomeRooClass),
+			(GtkClassInitFunc) gnome_roo_class_init,
+			(GtkObjectInitFunc) gnome_roo_init,
+			NULL,
+			NULL,
+			NULL
+		};
+		roo_type = gtk_type_unique(gtk_bin_get_type(), &roo_info);
+	}
+	return roo_type;
+}
+
+static void gnome_roo_class_init(GnomeRooClass *klass)
+{
+	GtkWidgetClass *widget_class;
+	GtkObjectClass *object_class;
+	GObjectClass *gobject_class;
+
+	parent_class = GTK_OBJECT_CLASS(gtk_type_class(gtk_bin_get_type()));
+	widget_class = GTK_WIDGET_CLASS(klass);
+	object_class = GTK_OBJECT_CLASS(klass);
+	gobject_class = G_OBJECT_CLASS(klass);
+
+	roo_signals[CLOSE] =
+		gtk_signal_new ("close",
+				GTK_RUN_LAST,
+				GTK_CLASS_TYPE (object_class),
+				GTK_SIGNAL_OFFSET (GnomeRooClass, close),
+				gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
+	roo_signals[ICONIFY] =
+		gtk_signal_new ("iconify",
+				GTK_RUN_LAST,
+				GTK_CLASS_TYPE (object_class),
+				GTK_SIGNAL_OFFSET (GnomeRooClass, iconify),
+				gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
+	roo_signals[UNICONIFY] =
+		gtk_signal_new ("uniconify",
+				GTK_RUN_LAST,
+				GTK_CLASS_TYPE (object_class),
+				GTK_SIGNAL_OFFSET (GnomeRooClass, uniconify),
+				gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
+	roo_signals[MAXIMIZE] =
+		gtk_signal_new ("maximize",
+				GTK_RUN_LAST,
+				GTK_CLASS_TYPE (object_class),
+				GTK_SIGNAL_OFFSET (GnomeRooClass, maximize),
+				gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
+	roo_signals[UNMAXIMIZE] =
+		gtk_signal_new ("unmaximize",
+				GTK_RUN_LAST,
+				GTK_CLASS_TYPE (object_class),
+				GTK_SIGNAL_OFFSET (GnomeRooClass, unmaximize),
+				gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
+	roo_signals[SELECT] =
+		gtk_signal_new ("select",
+				GTK_RUN_LAST,
+				GTK_CLASS_TYPE (object_class),
+				GTK_SIGNAL_OFFSET (GnomeRooClass, select),
+				gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
+	roo_signals[DESELECT] =
+		gtk_signal_new ("deselect",
+				GTK_RUN_LAST,
+				GTK_CLASS_TYPE (object_class),
+				GTK_SIGNAL_OFFSET (GnomeRooClass, deselect),
+				gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
+
+
+	gobject_class->finalize = gnome_roo_finalize;
+
+	widget_class->realize = gnome_roo_realize;
+	widget_class->unrealize = gnome_roo_unrealize;
+	widget_class->map = gnome_roo_map;
+	widget_class->unmap = gnome_roo_unmap;
+	widget_class->size_request = gnome_roo_size_request;
+	widget_class->size_allocate = gnome_roo_size_allocate;
+	widget_class->expose_event = gnome_roo_expose;
+	widget_class->button_press_event = gnome_roo_button_press;
+	widget_class->button_release_event = gnome_roo_button_release;
+	widget_class->motion_notify_event = gnome_roo_motion_notify;
+	widget_class->parent_set = gnome_roo_parent_set;
+
+	klass->close = NULL;
+	klass->iconify = gnome_roo_iconify;
+	klass->uniconify = gnome_roo_uniconify;
+	klass->maximize = gnome_roo_maximize;
+	klass->unmaximize = gnome_roo_unmaximize;
+	klass->select = gnome_roo_select;
+	klass->deselect = gnome_roo_deselect;
+}
+
+static void
+gnome_roo_init(GnomeRoo *roo)
+{ 
+	GTK_WIDGET_UNSET_FLAGS(roo, GTK_NO_WINDOW);
+
+	roo->priv = g_new0(GnomeRooPrivate, 1);
+
+	roo->priv->flags = 0;
+	roo->priv->title = NULL;
+	roo->priv->vis_title = NULL;
+	roo->priv->cover = NULL;
+	roo->priv->icon_allocation.width = roo->priv->icon_allocation.height = -1;
+	roo->priv->user_allocation.width = roo->priv->user_allocation.height = -1;
+
+	GTK_CONTAINER(roo)->border_width = 2;
+}
+
+static void gnome_roo_finalize(GObject *object)
+{
+	GnomeRoo *roo = GNOME_ROO(object);
+
+#ifdef GNOME_ENABLE_DEBUG
+	g_message("GnomeRoo: finalization");
+#endif
+
+	if(roo->priv->title)
+		g_free(roo->priv->title);
+	roo->priv->title = NULL;
+
+	if(G_OBJECT_CLASS(parent_class)->finalize)
+		G_OBJECT_CLASS(parent_class)->finalize(object);
+}
+
+static void
+gnome_roo_parent_set(GtkWidget *widget, GtkWidget *old_parent)
+{
+	if(widget->parent && !GNOME_IS_POUCH(widget->parent))
+		g_warning("GnomeRoo: parent is not a GnomePouch");
+
+	if(GTK_WIDGET_CLASS(parent_class)->parent_set)
+		(*GTK_WIDGET_CLASS(parent_class)->parent_set)(widget, old_parent);
+}
+
+static
+gboolean in_title_bar(GnomeRoo *roo, guint x, guint y)
+{
+	if(y < roo->priv->title_bar_height - 1 + GTK_WIDGET(roo)->style->ythickness)
+		return TRUE;
+
+	return FALSE;
+}
+
+static
+gboolean in_close_button(GnomeRoo *roo, guint x, guint y)
+{
+	if(x < 2 + roo->priv->title_bar_height && x >= 2 && in_title_bar(roo, x, y))
+		return TRUE;
+
+	return FALSE;
+}
+
+static
+gboolean in_maximize_button(GnomeRoo *roo, guint x, guint y)
+{
+	GtkWidget *w = GTK_WIDGET(roo);
+
+	if(x < w->allocation.width - 2 &&
+	   x >= w->allocation.width - roo->priv->title_bar_height - 2 &&
+	   in_title_bar(roo, x, y))
+		return TRUE;
+
+	return FALSE;
+}
+
+static
+gboolean in_iconify_button(GnomeRoo *roo, guint x, guint y)
+{
+	GtkWidget *w = GTK_WIDGET(roo);
+
+	if(x < w->allocation.width - 2 - roo->priv->title_bar_height - 1 &&
+	   x >= w->allocation.width - 2 - 2*roo->priv->title_bar_height &&
+	   in_title_bar(roo, x, y))
+		return TRUE;
+
+	return FALSE;
+}
+
+static void
+draw_shadow(GtkWidget *widget, GtkStateType state, gboolean out, gint x, gint y, gint w, gint h)
+{
+	GdkGC *tl_gc, *br_gc;
+
+	if(out) {
+		tl_gc = widget->style->light_gc[state];
+		br_gc = widget->style->dark_gc[state];
+	}
+	else {
+		tl_gc = widget->style->dark_gc[state];
+		br_gc = widget->style->light_gc[state];
+	}
+
+	gdk_draw_line(widget->window, tl_gc,
+				  x, y, x + w - 2, y);
+	gdk_draw_line(widget->window, tl_gc,
+				  x, y, x, y + h - 1);
+	gdk_draw_line(widget->window, br_gc,
+				  x + w - 1, y, x + w - 1, y + h - 1);
+	gdk_draw_line(widget->window, br_gc,
+				  x + 1, y + h - 1, x + w - 1, y + h - 1);
+}
+
+static void
+draw_cross(GtkWidget *widget, GdkGC *gc, gint x, gint y, gint s)
+{
+	gdk_draw_line(widget->window, gc,
+				  x + s/4, y + s/4, x + s - s/4, y + s - s/4);
+	gdk_draw_line(widget->window, gc,
+				  x + s/4, y + s - s/4, x + s - s/4, y + s/4);
+}
+
+static void
+paint_close_button(GnomeRoo *roo, gboolean hilight)
+{
+	GtkWidget *w = GTK_WIDGET(roo);
+	GtkStateType state;
+
+	if(roo->priv->flags & ROO_SELECTED)
+		state = GTK_STATE_SELECTED;
+	else
+		state = GTK_STATE_NORMAL;
+
+	if(hilight) {
+		roo->priv->flags |= ROO_CLOSE_HILIT;
+	}
+	else {
+		roo->priv->flags &= ~ROO_CLOSE_HILIT;
+	}
+
+	/* draw buttons */
+	draw_shadow(w, state, !hilight,
+				2, 2,
+				roo->priv->title_bar_height, roo->priv->title_bar_height);
+	draw_cross(w, (hilight?w->style->white_gc:w->style->black_gc),
+			   2, 2, roo->priv->title_bar_height);
+}
+
+static void
+paint_iconify_button(GnomeRoo *roo, gboolean hilight)
+{
+	GtkWidget *w = GTK_WIDGET(roo);
+	GtkStateType state;
+
+	if(roo->priv->flags & ROO_SELECTED)
+		state = GTK_STATE_SELECTED;
+	else
+		state = GTK_STATE_NORMAL;
+
+	if(hilight) {
+		roo->priv->flags |= ROO_ICONIFY_HILIT;
+	}
+	else {
+		roo->priv->flags &= ~ROO_ICONIFY_HILIT;
+	}
+
+	draw_shadow(w, state, !hilight,
+				w->allocation.width - 2 - 2*roo->priv->title_bar_height - 1, 2,
+				roo->priv->title_bar_height, roo->priv->title_bar_height);
+	gdk_draw_rectangle(w->window, (hilight?w->style->white_gc:w->style->black_gc), TRUE,
+					   w->allocation.width - 2*roo->priv->title_bar_height - 1, roo->priv->title_bar_height - 2,
+					   roo->priv->title_bar_height - 4, 2);
+}
+
+static void
+paint_maximize_button(GnomeRoo *roo, gboolean hilight)
+{
+	GtkWidget *w = GTK_WIDGET(roo);
+	GtkStateType state;
+
+	if(roo->priv->flags & ROO_SELECTED)
+		state = GTK_STATE_SELECTED;
+	else
+		state = GTK_STATE_NORMAL;
+
+	if(hilight) {
+		roo->priv->flags |= ROO_MAXIMIZE_HILIT;
+	}
+	else {
+		roo->priv->flags &= ~ROO_MAXIMIZE_HILIT;
+	}
+
+	draw_shadow(w, state, !hilight,
+				w->allocation.width - 2 - roo->priv->title_bar_height, 2,
+				roo->priv->title_bar_height, roo->priv->title_bar_height);
+	gdk_draw_rectangle(w->window, (hilight?w->style->white_gc:w->style->black_gc), FALSE,
+					   w->allocation.width - roo->priv->title_bar_height, 4,
+					   roo->priv->title_bar_height - 5, roo->priv->title_bar_height - 5);
+}
+
+static void
+calculate_size(GnomeRoo *roo, guint *rw, guint *rh)
+{
+	GtkWidget *w = GTK_WIDGET(roo);
+
+	guint16 width, height, bw;
+	GtkRequisition child_req;
+
+	width = 4;
+	height = 4;
+	if(!(roo->priv->flags & ROO_ICONIFIED)) {
+		width += 2*GTK_CONTAINER(w)->border_width + 2;
+		height += GTK_CONTAINER(w)->border_width + 2;
+	}
+	roo->priv->title_bar_height = w->style->font->ascent + 2*w->style->font->descent;
+	height += roo->priv->title_bar_height;
+
+	bw = 3*roo->priv->title_bar_height;
+
+	if(roo->priv->flags & ROO_ICONIFIED && roo->priv->title)
+		bw += gdk_string_width(w->style->font, roo->priv->title);
+	else
+		bw += gdk_string_width(w->style->font, "Abc...") + 4;
+
+	if(GTK_BIN(w)->child && !(roo->priv->flags & ROO_ICONIFIED)) {
+		gtk_widget_size_request(GTK_BIN(w)->child, &child_req);
+		bw = MAX(bw, child_req.width);
+		height += child_req.height;
+	}
+
+	width += bw;
+
+	roo->priv->min_width = width;
+	roo->priv->min_height = height;
+	*rw = width;
+	*rh = height;
+}
+
+static void
+gnome_roo_size_request(GtkWidget *w, GtkRequisition *req)
+{
+	guint width = 0, height = 0;
+
+	calculate_size(GNOME_ROO(w), &width, &height);
+
+	req->width = width;
+	req->height = height;
+}
+
+static void
+calculate_title_size(GnomeRoo *roo)
+{
+	GtkWidget *w = GTK_WIDGET(roo);
+	gint title_len, title_space, vis_space;
+
+	if(roo->priv->vis_title)
+		g_free(roo->priv->vis_title);
+
+	title_space = w->allocation.width;
+	title_space -= 4 + 4 + 1 + 3*roo->priv->title_bar_height;
+	vis_space = gdk_string_width(w->style->font, roo->priv->title);
+	if(vis_space < title_space) {
+		roo->priv->vis_title = g_strdup(roo->priv->title);
+		return;
+	}
+	title_space -= gdk_string_width(w->style->font, "...");
+	title_len = 0;
+	do {
+		title_len++;
+		vis_space = gdk_text_width(w->style->font, roo->priv->title, title_len);
+	} while(roo->priv->title[title_len] != '\0' && title_space > vis_space);
+	if(title_space < vis_space)
+		title_len--;
+	roo->priv->vis_title = g_new(gchar, title_len + 4);
+	strcpy(roo->priv->vis_title + title_len, "...");
+   	while(--title_len >= 0)
+		roo->priv->vis_title[title_len] = roo->priv->title[title_len];
+}
+
+static void
+gnome_roo_size_allocate(GtkWidget *w, GtkAllocation *allocation)
+{
+	GnomeRoo *roo = GNOME_ROO(w);
+	GtkAllocation child_alloc;
+	GtkRequisition child_req;
+
+	w->allocation = *allocation;
+
+	if(GTK_WIDGET_REALIZED(w)) {
+		gdk_window_move_resize(w->window,
+							   allocation->x, allocation->y,
+							   allocation->width, allocation->height);
+		gdk_window_move_resize(roo->priv->cover,
+							   allocation->x, allocation->y,
+							   allocation->width, allocation->height);
+	}
+
+	if(GTK_BIN(w)->child && GTK_WIDGET_VISIBLE(GTK_BIN(w)->child)) {
+		gtk_widget_get_child_requisition(GTK_BIN(w)->child, &child_req);
+		child_alloc.y = roo->priv->title_bar_height + 4;
+		child_alloc.height = w->allocation.height - child_alloc.y;
+		if(roo->priv->flags & ROO_MAXIMIZED)
+			child_alloc.x = 0;
+		else {
+			child_alloc.x = 2 + GTK_CONTAINER(w)->border_width;
+			child_alloc.height -= 2 + GTK_CONTAINER(w)->border_width;
+		}
+		child_alloc.width = w->allocation.width - 2*child_alloc.x;
+		gtk_widget_size_allocate(GTK_BIN(w)->child, &child_alloc);
+	}
+
+	if(!((roo->priv->flags & ROO_MAXIMIZED) || (roo->priv->flags & ROO_ICONIFIED))) {
+#ifdef GNOME_ENABLE_DEBUG
+		g_message("GnomeRoo: user allocation %dx%d at (%d,%d)",
+				  allocation->width, allocation->height,
+				  allocation->x, allocation->y);
+#endif
+		roo->priv->user_allocation = *allocation;
+	}
+
+	calculate_title_size(roo);
+}
+
+static void
+gnome_roo_realize(GtkWidget *w)
+{
+	GnomeRoo *roo = GNOME_ROO(w);
+	GdkWindowAttr attributes;
+	gint attributes_mask;
+
+	GTK_WIDGET_SET_FLAGS(w, GTK_REALIZED);
+
+	attributes.window_type = GDK_WINDOW_CHILD;
+	attributes.x = w->allocation.x;
+	attributes.y = w->allocation.y;
+	attributes.width = w->allocation.width;
+	attributes.height = w->allocation.height;
+	attributes.wclass = GDK_INPUT_OUTPUT;
+	attributes.visual = gtk_widget_get_visual(w);
+	attributes.colormap = gtk_widget_get_colormap(w);
+	attributes.event_mask = gtk_widget_get_events(w) |
+		                    GDK_POINTER_MOTION_MASK |
+		                    GDK_BUTTON_PRESS_MASK |
+		                    GDK_BUTTON_RELEASE_MASK |
+		                    GDK_EXPOSURE_MASK;
+	attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+
+	w->window = gdk_window_new(gtk_widget_get_parent_window(w), &attributes, attributes_mask);
+	gdk_window_set_user_data (w->window, w);
+
+	attributes.wclass = GDK_INPUT_ONLY;
+	attributes.event_mask = GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK;
+	roo->priv->cover = gdk_window_new(gtk_widget_get_parent_window(w), &attributes, attributes_mask);
+	gdk_window_set_user_data (roo->priv->cover, w);
+
+	w->style = gtk_style_attach(w->style, w->window);
+	gtk_style_set_background(w->style, w->window, GTK_STATE_NORMAL);
+}
+
+static void gnome_roo_unrealize(GtkWidget *w)
+{
+	GnomeRoo *roo = GNOME_ROO(w);
+
+	if(roo->priv->cover) {
+		gdk_window_destroy(roo->priv->cover);
+		roo->priv->cover = NULL;
+	}
+
+	if(GTK_WIDGET_CLASS(parent_class)->unrealize)
+		(*GTK_WIDGET_CLASS(parent_class)->unrealize)(w);
+}
+
+static void
+gnome_roo_map(GtkWidget *w)
+{
+	GnomeRoo *roo = GNOME_ROO(w);
+
+	if(GTK_WIDGET_CLASS(parent_class)->map)
+		(*GTK_WIDGET_CLASS(parent_class)->map)(w);
+
+	if(!gnome_roo_is_selected(roo)) {
+#ifdef GNOME_ENABLE_DEBUG
+		g_message("GnomeRoo: showing cover");
+#endif
+		gdk_window_show(roo->priv->cover);
+	}
+}
+
+static void gnome_roo_unmap(GtkWidget *w)
+{
+	GnomeRoo *roo = GNOME_ROO(w);
+
+	if(GTK_WIDGET_MAPPED(w) && !gnome_roo_is_selected(roo)) {
+#ifdef GNOME_ENABLE_DEBUG
+		g_message("GnomeRoo: hiding cover");
+#endif
+		gdk_window_hide(roo->priv->cover);
+	}
+
+	if(GTK_WIDGET_CLASS(parent_class)->unmap)
+		(*GTK_WIDGET_CLASS(parent_class)->unmap)(w);
+}
+
+static GnomeRooResizeType get_resize_type(GnomeRoo *roo, gint x, gint y)
+{
+	GnomeRooResizeType resize;
+	GtkWidget *w = GTK_WIDGET(roo);
+	guint border_width = GTK_CONTAINER(roo)->border_width;
+	gint ww, wh, wx, wy, wd;
+
+	if(roo->priv->flags & (ROO_ICONIFIED | ROO_MAXIMIZED))
+		return RESIZE_NONE;
+
+	gdk_window_get_geometry(w->window, &wx, &wy, &ww, &wh, &wd);
+
+	resize = RESIZE_NONE;
+	if(x >= w->parent->allocation.width - wx || x < -wx ||
+	   y >= w->parent->allocation.height - wy || y < -wy)
+		;
+	else if(x < border_width) {
+		if(y < border_width)
+			resize = RESIZE_TOP_LEFT;
+		else if(y >= wh - border_width)
+			resize = RESIZE_BOTTOM_LEFT;
+		else
+			resize = RESIZE_LEFT;
+	}
+	else if(x >= ww - border_width) {
+		if(y < border_width)
+			resize = RESIZE_TOP_RIGHT;
+		else if(y >= wh - border_width)
+			resize = RESIZE_BOTTOM_RIGHT;
+		else
+			resize = RESIZE_RIGHT;
+	}
+	else if(y < border_width)
+		resize = RESIZE_TOP;
+	else if(y >= wh - border_width)
+		resize = RESIZE_BOTTOM;
+
+	return resize;
+}
+
+static gboolean
+gnome_roo_button_press(GtkWidget *w, GdkEventButton *e)
+{
+	GnomeRoo *roo = GNOME_ROO(w);
+	GnomeRooResizeType resize;
+	GdkCursor *cursor = NULL;
+
+	if(e->window == roo->priv->cover) {
+#ifdef GNOME_ENABLE_DEBUG
+		g_message("GnomeRoo: got button press on cover");
+#endif
+		gtk_signal_emit(GTK_OBJECT(roo), roo_signals[SELECT], NULL);
+	}
+
+	if(e->button != 1)
+		return FALSE;
+
+	resize = get_resize_type(roo, e->x, e->y);
+	if(resize != RESIZE_NONE) {
+		if(!resize_cursor[resize])
+			resize_cursor[resize] = gdk_cursor_new(resize_cursor_type[resize]);
+
+		cursor = resize_cursor[resize];
+		roo->priv->flags |= ROO_IN_RESIZE;
+		roo->priv->resize_type = resize;
+	}
+	else if(in_title_bar(roo, e->x, e->y)) {
+		/* do we want to highlight any title bar button? */
+		if(in_close_button(roo, e->x, e->y))
+			paint_close_button(roo, TRUE);
+		else if(in_iconify_button(roo, e->x, e->y))
+			paint_iconify_button(roo, TRUE);
+		else if(in_maximize_button(roo, e->x, e->y))
+			paint_maximize_button(roo, TRUE);
+		else if(!(roo->priv->flags & ROO_MAXIMIZED)) {
+			roo->priv->flags |= ROO_IN_MOVE;
+			if(!move_cursor)
+				move_cursor = gdk_cursor_new(GDK_FLEUR);
+			cursor = move_cursor;
+		}
+	}
+
+	if(roo->priv->flags &  (ROO_IN_MOVE | ROO_IN_RESIZE)) {
+		roo->priv->grab_x = e->x;
+		roo->priv->grab_y = e->y;
+
+		gtk_grab_add(w);
+		gdk_pointer_grab(w->window, FALSE,
+						 GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
+						 NULL, cursor, GDK_CURRENT_TIME);
+	}
+
+	return TRUE;
+}
+
+static gboolean
+gnome_roo_button_release(GtkWidget *w, GdkEventButton *e)
+{
+	GnomeRoo *roo = GNOME_ROO(w);
+	gint wx, wy, ww, wh, wd;
+
+	if(e->button != 1)
+		return FALSE;
+
+	if(roo->priv->flags & ROO_IN_MOVE) {
+		gdk_window_get_position(w->window, &wx, &wy);
+		if(w->allocation.x != wx || w->allocation.y != wy) {
+			if(roo->priv->flags & ROO_ICONIFIED)
+				gnome_roo_park(roo, wx, wy);
+			else
+				gnome_pouch_move(GNOME_POUCH(w->parent), roo, wx, wy);
+		}
+		roo->priv->flags &= ~ROO_IN_MOVE;
+	}
+	else if(roo->priv->flags & ROO_IN_RESIZE) {
+		gdk_window_get_geometry(w->window, &wx, &wy, &ww, &wh, &wd);
+		if(w->allocation.x != wx || w->allocation.y != wy)
+			gnome_pouch_move(GNOME_POUCH(w->parent), roo, wx, wy);
+		if(w->allocation.width != ww || w->allocation.height != wh)
+			gtk_widget_set_usize(w, ww, wh);
+		roo->priv->flags &= ~ROO_IN_RESIZE;
+	}
+	else {
+		if(roo->priv->flags & ROO_CLOSE_HILIT)
+			paint_close_button(roo, FALSE);
+		else if(roo->priv->flags & ROO_ICONIFY_HILIT)
+			paint_iconify_button(roo, FALSE);
+		else if(roo->priv->flags & ROO_MAXIMIZE_HILIT)
+			paint_maximize_button(roo, FALSE);
+
+		if(in_close_button(roo, e->x, e->y)) {
+			gtk_signal_emit_by_name(GTK_OBJECT(w->parent), "close-child", roo, NULL);
+		}
+		else if(in_maximize_button(roo, e->x, e->y)) {
+			gnome_roo_set_maximized(roo, !gnome_roo_is_maximized(roo));
+		}
+		else if(in_iconify_button(roo, e->x, e->y)) {
+			if(gnome_roo_is_maximized(roo)) {
+				gnome_roo_set_maximized(roo, FALSE);
+				if(!(roo->priv->flags & ROO_ICONIFIED))
+					gnome_roo_set_iconified(roo, TRUE);
+			}
+			else
+				gnome_roo_set_iconified(roo, !(roo->priv->flags & ROO_ICONIFIED));
+		}
+	}
+
+	gdk_pointer_ungrab(GDK_CURRENT_TIME);
+	gtk_grab_remove(w);
+
+	return TRUE;
+}
+
+static gboolean
+gnome_roo_motion_notify(GtkWidget *w, GdkEventMotion *e)
+{
+	GnomeRoo *roo = GNOME_ROO(w);
+	GnomeRooResizeType resize;
+	gint dx, dy, wx, wy;
+
+	if(roo->priv->flags & ROO_IN_MOVE) {
+		dx = e->x - roo->priv->grab_x;
+		dy = e->y - roo->priv->grab_y;
+		gdk_window_get_position(w->window, &wx, &wy);
+		wx += dx;
+		wy += dy;
+		wx = MAX(wx, -w->allocation.width + 3*roo->priv->title_bar_height);
+		wx = MIN(wx, w->parent->allocation.width - 2*roo->priv->title_bar_height);
+		wy = MAX(wy, 0);
+		wy = MIN(wy, w->parent->allocation.height - roo->priv->title_bar_height);
+		gdk_window_move(w->window, wx, wy);
+		gdk_window_move(roo->priv->cover, wx, wy);
+
+		return TRUE;
+	}
+	else if(!(roo->priv->flags & ROO_IN_RESIZE)) {
+		resize = get_resize_type(roo, e->x, e->y);
+
+		/* are we in a border area that indicates resizing? */
+		if(resize != roo->priv->resize_type) {
+			if(resize != RESIZE_NONE) {
+				if(!resize_cursor[resize])
+					resize_cursor[resize] = gdk_cursor_new(resize_cursor_type[resize]);
+				gdk_window_set_cursor(w->window, resize_cursor[resize]);
+				gdk_window_set_cursor(roo->priv->cover, resize_cursor[resize]);
+
+			}
+			else {
+				gdk_window_set_cursor(w->window, NULL);
+				gdk_window_set_cursor(roo->priv->cover, NULL);
+			}
+			roo->priv->resize_type = (guint)resize;
+		}
+	}
+	else { /* roo->priv->flags & ROO_IN_RESIZE */
+		gint move_x = 0, move_y = 0, resize_x = 0, resize_y = 0;
+		gint new_x, new_y, new_width, new_height;
+		gint max_x, max_y, max_w, max_h;
+		gint pw, ph, ww, wh, wd;
+
+		gdk_window_get_geometry(w->window, &wx, &wy, &ww, &wh, &wd);
+		gdk_window_get_size(w->parent->window, &pw, &ph);
+
+		max_x = wx + ww - roo->priv->min_width;
+		max_y = wy + wh - roo->priv->min_height;
+
+		switch(roo->priv->resize_type) {
+		case RESIZE_TOP_LEFT:
+			move_x = e->x;
+			move_y = e->y;
+			resize_x = -e->x;
+			resize_y = -e->y;
+			break;
+		case RESIZE_TOP:
+			move_y = e->y;
+			resize_y = -e->y;
+			break;
+		case RESIZE_TOP_RIGHT:
+			move_y = e->y;
+			resize_x = e->x - ww;
+			resize_y = -e->y;
+			break;
+		case RESIZE_RIGHT:
+			resize_x = e->x - ww;
+			break;
+		case RESIZE_BOTTOM_RIGHT:
+			resize_x = e->x - ww;
+			resize_y = e->y - wh;
+			break;
+		case RESIZE_BOTTOM:
+			resize_y = e->y - wh;
+			break;
+		case RESIZE_BOTTOM_LEFT:
+			move_x = e->x;
+			resize_x = -e->x;
+			resize_y = e->y - wh;
+			break;
+		case RESIZE_LEFT:
+			move_x = e->x;
+			resize_x = -e->x;
+			break;
+		default:
+			break;
+		}
+
+		new_x = wx + move_x;
+		new_y = wy + move_y;
+		if(new_x < 0) {
+			resize_x += new_x;
+			new_x = 0;
+		}
+		if(new_y < 0) {
+			resize_y += new_y;
+			new_y = 0;
+		}
+		new_x = MIN(new_x, max_x);
+		new_y = MIN(new_y, max_y);
+
+		new_width = ww + resize_x;
+		new_height = wh + resize_y;
+		new_width = MAX(roo->priv->min_width, new_width);
+		new_height = MAX(roo->priv->min_height, new_height);
+		max_w = pw - wx;
+		max_h = ph - wy;
+		new_width = MIN(new_width, max_w);
+		new_height = MIN(new_height, max_h);
+
+		if(wx != new_x || wy != new_y)
+			gnome_pouch_move(GNOME_POUCH(w->parent), roo, new_x, new_y);
+		if(ww != new_width || wh != new_height)
+			gtk_widget_set_usize(w, new_width, new_height);
+	}
+
+	return FALSE;
+}
+
+static void
+gnome_roo_maximize(GnomeRoo *roo)
+{
+	GtkWidget *w = GTK_WIDGET(roo);
+
+#ifdef GNOME_ENABLE_DEBUG
+		g_message("GnomeRoo: maximize");
+#endif
+
+	if(roo->priv->flags & ROO_MAXIMIZED)
+		return;
+
+	roo->priv->flags |= ROO_MAXIMIZED;
+
+	if(roo->priv->flags & ROO_ICONIFIED) {
+		roo->priv->flags |= ROO_WAS_ICONIFIED;
+		gtk_signal_emit(GTK_OBJECT(roo), roo_signals[UNICONIFY], NULL);
+	}
+
+	if(w->parent)
+		gtk_signal_emit_by_name(GTK_OBJECT(w->parent), "maximize-child", roo, NULL);
+}
+
+static void gnome_roo_unmaximize(GnomeRoo *roo)
+{
+	GtkWidget *w = GTK_WIDGET(roo);
+
+#ifdef GNOME_ENABLE_DEBUG
+	g_message("GnomeRoo: unmaximize");
+#endif
+
+	if(!(roo->priv->flags & ROO_MAXIMIZED))
+		return;
+
+	roo->priv->flags &= ~ROO_MAXIMIZED;
+
+	if(roo->priv->flags & ROO_WAS_ICONIFIED) {
+		gtk_signal_emit(GTK_OBJECT(roo), roo_signals[ICONIFY], NULL);
+		roo->priv->flags &= ~ROO_WAS_ICONIFIED;
+	}
+
+	if(w->parent)
+		gtk_signal_emit_by_name(GTK_OBJECT(w->parent), "unmaximize-child", roo, NULL);
+}
+
+static void
+gnome_roo_iconify(GnomeRoo *roo)
+{
+	GtkWidget *w = GTK_WIDGET(roo);
+	guint icon_width = 0, icon_height = 0;
+
+#ifdef GNOME_ENABLE_DEBUG
+	g_message("GnomeRoo: iconify");
+#endif
+
+	if(roo->priv->flags & ROO_MAXIMIZED)
+		gtk_signal_emit(GTK_OBJECT(roo), roo_signals[UNMAXIMIZE], NULL);
+
+	roo->priv->flags |= ROO_ICONIFIED;
+
+	if(GTK_BIN(roo)->child && GTK_WIDGET_VISIBLE(GTK_BIN(roo)->child))
+		gtk_widget_hide(GTK_BIN(roo)->child);
+	calculate_size(roo, &icon_width, &icon_height);
+	roo->priv->icon_allocation.width = icon_width;
+	roo->priv->icon_allocation.height = icon_height;
+	gtk_widget_set_usize(w, icon_width, icon_height);
+
+	if(w->parent)
+		gtk_signal_emit_by_name(GTK_OBJECT(w->parent), "iconify-child", roo, NULL);
+}
+
+static void gnome_roo_uniconify(GnomeRoo *roo)
+{
+	GtkWidget *w = GTK_WIDGET(roo);
+
+#ifdef GNOME_ENABLE_DEBUG
+		g_message("GnomeRoo: uniconify");
+#endif
+
+	if(!(roo->priv->flags & ROO_ICONIFIED))
+		return;
+
+	roo->priv->flags &= ~ROO_ICONIFIED;
+
+	if(GTK_BIN(roo)->child && !GTK_WIDGET_VISIBLE(GTK_BIN(roo)->child)) {
+		/* recall last size and position */
+		if(w->parent) {
+			gnome_pouch_move(GNOME_POUCH(w->parent), roo,
+							 roo->priv->user_allocation.x,
+							 roo->priv->user_allocation.y);
+			gtk_widget_set_usize(w,
+								 roo->priv->user_allocation.width,
+								 roo->priv->user_allocation.height);
+		}
+		gtk_widget_show(GTK_BIN(roo)->child);
+	}
+
+	gtk_widget_queue_resize(w);
+
+	if(w->parent)
+		gtk_signal_emit_by_name(GTK_OBJECT(w->parent), "uniconify-child", roo, NULL);
+}
+
+static void
+gnome_roo_select(GnomeRoo *roo)
+{
+	GtkWidget *w = GTK_WIDGET(roo);
+
+#ifdef GNOME_ENABLE_DEBUG
+	g_message("GnomeRoo: select");
+#endif
+	roo->priv->flags |= ROO_SELECTED;
+
+	if(GTK_WIDGET_MAPPED(roo)) {
+		gdk_window_hide(roo->priv->cover);
+		gtk_widget_queue_draw(w);
+	}
+
+	if(w->parent)
+		gtk_signal_emit_by_name(GTK_OBJECT(w->parent), "select-child", roo, NULL);
+}
+
+static void gnome_roo_deselect(GnomeRoo *roo)
+{
+	GtkWidget *w = GTK_WIDGET(roo);
+
+#ifdef GNOME_ENABLE_DEBUG
+	g_message("GnomeRoo: deselect");
+#endif
+	roo->priv->flags &= ~ROO_SELECTED;
+
+	if(GTK_WIDGET_MAPPED(roo)) {
+		gdk_window_show(roo->priv->cover);
+		gtk_widget_queue_draw(w);
+	}
+
+	if(w->parent)
+		gtk_signal_emit_by_name(GTK_OBJECT(w->parent), "unselect-child", roo, NULL);
+}
+
+static void
+gnome_roo_paint(GtkWidget *w, GdkRectangle *area)
+{
+	GnomeRoo *roo = GNOME_ROO(w);
+	guint border_width = GTK_CONTAINER(w)->border_width;
+	GtkStateType state;
+
+	if(roo->priv->flags & ROO_SELECTED)
+		state = GTK_STATE_SELECTED;
+	else
+		state = GTK_STATE_NORMAL;
+
+	gdk_gc_set_clip_rectangle(w->style->mid_gc[state], area);
+
+	/* draw borders */
+	gdk_draw_rectangle(w->window, w->style->mid_gc[state], TRUE,
+					   1, 1,
+					   w->allocation.width - 2, roo->priv->title_bar_height + 2);
+	if(!(roo->priv->flags & ROO_MAXIMIZED)) {
+		gdk_draw_rectangle(w->window, w->style->mid_gc[state], TRUE,
+						   1, roo->priv->title_bar_height + 3,
+						   border_width, w->allocation.height - roo->priv->title_bar_height - 2);
+		gdk_draw_rectangle(w->window, w->style->mid_gc[state], TRUE,
+						   w->allocation.width - border_width - 1, roo->priv->title_bar_height + 3,
+						   border_width, w->allocation.height - roo->priv->title_bar_height - 2);
+		gdk_draw_rectangle(w->window, w->style->mid_gc[state], TRUE,
+						   1, w->allocation.height - border_width - 1,
+						   w->allocation.width - 2, border_width);
+	}
+
+	/* draw border bevels */
+	if(roo->priv->flags & ROO_MAXIMIZED)
+		draw_shadow(w, state, TRUE, 0, 0, w->allocation.width, roo->priv->title_bar_height + 4);
+	else {
+		draw_shadow(w, state, TRUE, 0, 0, w->allocation.width, w->allocation.height);
+		if(!(roo->priv->flags & ROO_ICONIFIED))
+			draw_shadow(w, state, FALSE,
+						border_width + 1, roo->priv->title_bar_height + 3,
+						w->allocation.width - 2*(1 + border_width),
+						w->allocation.height - border_width - 1 - roo->priv->title_bar_height - 3);
+	}
+
+	/* paint buttons */
+	paint_close_button(roo, roo->priv->flags & ROO_CLOSE_HILIT);
+	paint_iconify_button(roo, roo->priv->flags & ROO_ICONIFY_HILIT);
+	paint_maximize_button(roo, roo->priv->flags & ROO_MAXIMIZE_HILIT);
+
+	/* TODO: properly draw title */
+	if(roo->priv->title)
+		gtk_paint_string(w->style, w->window,
+						 state, area,
+						 w, "gnome-roo",
+						 roo->priv->title_bar_height + 4, w->style->font->ascent + w->style->font->descent,
+						 roo->priv->vis_title);
+}
+
+static gboolean gnome_roo_expose(GtkWidget *w, GdkEventExpose *e)
+{
+	if(GTK_WIDGET_DRAWABLE(w)) {
+		gnome_roo_paint(w, &e->area);
+	}
+
+	if(GTK_WIDGET_CLASS(parent_class)->expose_event)
+		(*GTK_WIDGET_CLASS(parent_class)->expose_event)(w, e);
+
+	return FALSE;
+}
+
+/**
+ * gnome_roo_set_title:
+ * @roo: A pointer to a GnomeRoo widget.
+ * @title: The new title.
+ * 
+ * Description:
+ * Changes the title of a @roo to @title.
+ **/
+void
+gnome_roo_set_title(GnomeRoo *roo, const gchar *title)
+{
+	g_return_if_fail(GNOME_IS_ROO(roo));
+
+	if(roo->priv->title)
+		g_free(roo->priv->title);
+	roo->priv->title = g_strdup(title);
+	gtk_widget_queue_draw(GTK_WIDGET(roo));
+}
+
+/**
+ * gnome_roo_get_title:
+ * @roo: A pointer to a GnomeRoo widget.
+ * 
+ * Description:
+ * Retrieves the title of a @roo.
+ *
+ * Return value:
+ * @roo's title.
+ **/
+const gchar *
+gnome_roo_get_title(GnomeRoo *roo)
+{
+	g_return_val_if_fail(roo != NULL, NULL);
+	g_return_val_if_fail(GNOME_IS_ROO(roo), NULL);
+
+	return roo->priv->title;
+}
+
+/**
+ * gnome_roo_set_iconified:
+ * @roo: A pointer to a GnomeRoo widget.
+ * @iconified: A boolean value indicating if the roo should be
+ * iconified or not.
+ * 
+ * Description:
+ * Iconifies or uniconifies the @roo according to the value of @iconified.
+ **/
+void
+gnome_roo_set_iconified(GnomeRoo *roo, gboolean iconified)
+{
+	g_return_if_fail(GNOME_IS_ROO(roo));
+
+	if(iconified && !gnome_roo_is_iconified(roo))
+		gtk_signal_emit(GTK_OBJECT(roo), roo_signals[ICONIFY], NULL);
+	else if(!iconified && gnome_roo_is_iconified(roo))
+		gtk_signal_emit(GTK_OBJECT(roo), roo_signals[UNICONIFY], NULL);
+}
+
+/**
+ * gnome_roo_set_maximized:
+ * @roo: A pointer to a GnomeRoo widget.
+ * @maximized: A boolean value indicating if the view should be
+ * maximized or not.
+ * 
+ * Description:
+ * Maximizes or unmaximizes the @roo according to the value of @maximized.
+ **/
+void
+gnome_roo_set_maximized(GnomeRoo *roo, gboolean maximized)
+{
+	g_return_if_fail(GNOME_IS_ROO(roo));
+
+	if(maximized && !gnome_roo_is_maximized(roo))
+		gtk_signal_emit(GTK_OBJECT(roo), roo_signals[MAXIMIZE], NULL);
+	else if(!maximized && gnome_roo_is_maximized(roo))
+		gtk_signal_emit(GTK_OBJECT(roo), roo_signals[UNMAXIMIZE], NULL);
+}
+
+/**
+ * gnome_roo_is_iconified:
+ * @roo: A pointer to a GnomeRoo widget.
+ * 
+ * Description:
+ * Returns %TRUE if the @roo is iconified and %FALSE otherwise.
+ *
+ * Return value:
+ * A gboolean indicating if the @roo is iconified.
+ **/
+gboolean
+gnome_roo_is_iconified(GnomeRoo *roo)
+{
+	g_return_val_if_fail(GNOME_IS_ROO(roo), FALSE);
+
+	return roo->priv->flags & ROO_ICONIFIED;
+}
+
+/**
+ * gnome_roo_is_maximized:
+ * @roo: A pointer to a GnomeRoo widget.
+ * 
+ * Description:
+ * Returns %TRUE if the @roo is maximized and %FALSE otherwise.
+ *
+ * Return value:
+ * A gboolean indicating if the @roo is maximized.
+ **/
+gboolean
+gnome_roo_is_maximized(GnomeRoo *roo)
+{
+	g_return_val_if_fail(GNOME_IS_ROO(roo), FALSE);
+
+	return roo->priv->flags & ROO_MAXIMIZED;
+}
+
+/**
+ * gnome_roo_is_selected:
+ * @roo: A pointer to a GnomeRoo widget.
+ * 
+ * Description:
+ * Returns %TRUE if the @roo is selected and %FALSE otherwise.
+ *
+ * Return value:
+ * A gboolean indicating if the @roo is selected.
+ **/
+gboolean
+gnome_roo_is_selected(GnomeRoo *roo)
+{
+	g_return_val_if_fail(GNOME_IS_ROO(roo), FALSE);
+
+	return roo->priv->flags & ROO_SELECTED;
+}
+
+/**
+ * gnome_roo_park:
+ * @roo: A pointer to a GnomeRoo widget.
+ * @x: X coordinate of the parking space
+ * @y: Y coordinate of the parking space
+ * 
+ * Description:
+ * At each next iconification, @roo will be moved to (@x, @y). If the @roo
+ * is already iconified, it is moved there immediately.
+ **/
+void
+gnome_roo_park(GnomeRoo *roo, gint x, gint y)
+{
+	GtkWidget *w;
+
+	g_return_if_fail(GNOME_IS_ROO(roo));
+
+	w = GTK_WIDGET(roo);
+
+	roo->priv->flags |= ROO_ICON_PARKED;
+	if(gnome_roo_is_iconified(roo) && w->parent)
+		gnome_pouch_move(GNOME_POUCH(w->parent), roo, x, y);
+	else {
+		roo->priv->icon_allocation.x = x;
+		roo->priv->icon_allocation.y = y;
+	}
+
+#ifdef GNOME_ENABLE_DEBUG
+	g_message("GnomeRoo: parked at %d,%d\n",
+			  roo->priv->icon_allocation.x, roo->priv->icon_allocation.y);
+#endif
+}
+
+/**
+ * gnome_roo_unpark:
+ * @roo: A pointer to a GnomeRoo widget.
+ * 
+ * Description:
+ * As of the next iconification, the @roo's icon will not be moved to
+ * the position set with a previous call to gnome_roo_park() anymore.
+ **/
+void gnome_roo_unpark(GnomeRoo *roo)
+{
+	g_return_if_fail(GNOME_IS_ROO(roo));
+
+	roo->priv->flags &= ~ROO_ICON_PARKED;
+}
+
+/**
+ * gnome_roo_is_parked:
+ * @roo: A pointer to a GnomeRoo widget.
+ * 
+ * Description:
+ * Returns %TRUE if the @roo has been parked. The return value is valid
+ * even if the @roo is currently not iconified and therefore not parked.
+ *
+ * Return value:
+ * A gboolean indicating if the @roo has been parked. 
+ **/
+gboolean
+gnome_roo_is_parked(GnomeRoo *roo)
+{
+	return roo->priv->flags & ROO_ICON_PARKED;
+}
+
+/**
+ * gnome_roo_new:
+ * 
+ * Description:
+ * Creates a new GnomeRoo widget.
+ *
+ * Return value:
+ * A pointer to a GnomeRoo widget.
+ **/
+GtkWidget *
+gnome_roo_new()
+{
+	return gtk_type_new(gnome_roo_get_type());
+}
diff --git a/libgnomeui/gnome-roo.h b/libgnomeui/gnome-roo.h
new file mode 100644
index 0000000..f01bbc4
--- /dev/null
+++ b/libgnomeui/gnome-roo.h
@@ -0,0 +1,79 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* gnome-roo.h - a Gnome Roo widget - WiW MDI child
+
+   Copyright (C) 2000 Jaka Mocnik
+
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Jaka Mocnik <jaka mocnik kiss uni-lj si>
+*/
+
+#ifndef __GNOME_ROO_H__
+#define __GNOME_ROO_H__
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+
+
+G_BEGIN_DECLS
+
+#define GNOME_TYPE_ROO            (gnome_roo_get_type ())
+#define GNOME_ROO(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_ROO, GnomeRoo))
+#define GNOME_ROO_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_ROO, GnomeRooClass))
+#define GNOME_IS_ROO(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_ROO))
+#define GNOME_IS_ROO_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_ROO))
+#define GNOME_ROO_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_ROO, GnomeRooClass))
+
+typedef struct _GnomeRoo        GnomeRoo;
+typedef struct _GnomeRooClass   GnomeRooClass;
+
+typedef struct _GnomeRooPrivate GnomeRooPrivate;
+
+struct _GnomeRoo {
+	GtkBin bin;
+
+	GnomeRooPrivate *priv;
+};
+
+struct _GnomeRooClass {
+	GtkBinClass parent_class;
+
+	void (*close)(GnomeRoo *roo);
+	void (*iconify)(GnomeRoo *roo);
+	void (*uniconify)(GnomeRoo *roo);
+	void (*maximize)(GnomeRoo *roo);
+	void (*unmaximize)(GnomeRoo *roo);
+	void (*select)(GnomeRoo *roo);
+	void (*deselect)(GnomeRoo *roo);
+};
+
+guint        gnome_roo_get_type(void) G_GNUC_CONST;
+GtkWidget   *gnome_roo_new(void);
+const gchar *gnome_roo_get_title(GnomeRoo *roo);
+void         gnome_roo_set_title(GnomeRoo *roo, const gchar *name);
+void         gnome_roo_set_iconified(GnomeRoo *roo, gboolean iconified);
+gboolean     gnome_roo_is_iconified(GnomeRoo *roo);
+void         gnome_roo_set_maximized(GnomeRoo *roo, gboolean maximized);
+gboolean     gnome_roo_is_maximized(GnomeRoo *roo);
+gboolean     gnome_roo_is_selected(GnomeRoo *roo);
+gboolean     gnome_roo_is_parked(GnomeRoo *roo);
+void         gnome_roo_park(GnomeRoo *roo, gint x, gint y);
+void         gnome_roo_unpark(GnomeRoo *roo);
+
+G_END_DECLS
+
+#endif /* __GNOME_ROO_H__ */
diff --git a/libgnomeui/gnome-selector.c b/libgnomeui/gnome-selector.c
new file mode 100644
index 0000000..b6b93cb
--- /dev/null
+++ b/libgnomeui/gnome-selector.c
@@ -0,0 +1,2287 @@
+/* -*- Mode: C; c-set-style: gnu indent-tabs-mode: t; c-basic-offset: 4; tab-width: 8 -*- */
+/*
+ * Copyright (C) 2000 SuSE GmbH
+ * Author: Martin Baulig <baulig suse de>
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+/* GnomeSelector widget - pure virtual widget.
+ *
+ *   Use the Gnome{File,Icon,Pixmap}Selector subclasses.
+ *
+ * Author: Martin Baulig <baulig suse de>
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkvbox.h>
+#include <gtk/gtkbutton.h>
+#include <gtk/gtksignal.h>
+#include <libgnome/gnome-i18n.h>
+#include "gnome-macros.h"
+#include "gnome-selectorP.h"
+#include "gnome-uidefs.h"
+
+#include <libgnome/libgnome-init.h>
+#include <bonobo/bonobo-config-database.h>
+
+#include <libgnomeuiP.h>
+
+#undef DEBUG_ASYNC_HANDLE
+
+typedef struct _GnomeSelectorListData    GnomeSelectorListData;
+typedef struct _GnomeSelectorHistoryItem GnomeSelectorHistoryItem;
+typedef struct _GnomeSelectorAsyncData   GnomeSelectorAsyncData;
+
+struct _GnomeSelectorPrivate {
+    Bonobo_ConfigDatabase db;
+
+    gchar       *history_id;
+    gchar       *dialog_title;
+
+    gchar       *gconf_history_dir;
+    gchar       *gconf_history_key;
+    gchar       *gconf_uri_list_key;
+
+    GPtrArray   *lists;
+
+    GSList      *history;
+    guint        max_history_length;
+
+    GtkWidget   *entry_widget;
+    GtkWidget   *selector_widget;
+    GtkWidget   *browse_dialog;
+
+    GtkWidget   *box;
+    GtkWidget   *hbox;
+    GtkWidget   *browse_button;
+    GtkWidget   *clear_button;
+    GtkWidget   *default_button;
+
+    guint32      flags;
+
+    guint32      want_default_behaviour : 1;
+    guint32      use_default_entry_widget : 1;
+    guint32      use_default_selector_widget : 1;
+    guint32      use_default_browse_dialog : 1;
+    guint32      want_browse_button : 1;
+    guint32      want_clear_button : 1;
+    guint32      want_default_button : 1;
+    guint32      auto_save_history : 1;
+    guint32      auto_save_all : 1;
+
+    guint32      constructed : 1;
+
+    guint32      changed : 1;
+    guint32      history_changed : 1;
+    guint32      need_rebuild : 1;
+    guint32      dirty : 1;
+
+    guint        frozen;
+
+    GList       *async_ops;
+};
+
+struct _GnomeSelectorListData {
+    GQuark quark;
+    GSList *list;
+};
+
+struct _GnomeSelectorHistoryItem {
+    gboolean save;
+    gchar *text;
+};
+
+struct _GnomeSelectorAsyncData {
+    gpointer async_data;
+    GDestroyNotify async_data_destroy;
+};
+
+struct _GnomeSelectorAsyncHandle {
+    int refcount;
+
+    GnomeSelectorAsyncType async_type;
+
+    GnomeSelector *selector;
+    GnomeSelectorAsyncFunc async_func;
+    gpointer user_data;
+
+    GError *error;
+
+    gboolean success;
+    gboolean destroyed;
+    gboolean completed;
+
+    gchar *uri;
+
+    GSList *async_data_list;
+};
+
+static void gnome_selector_load_all            (GnomeSelector *selector);
+#if 0
+static void gnome_selector_save_all            (GnomeSelector *selector);
+#endif
+
+static void gnome_selector_class_init          (GnomeSelectorClass *class);
+static void gnome_selector_init                (GnomeSelector      *selector);
+static void gnome_selector_destroy             (GtkObject          *object);
+static void gnome_selector_finalize            (GObject            *object);
+
+static void gnome_selector_get_property        (GObject            *object,
+                                                guint               param_id,
+                                                GValue             *value,
+                                                GParamSpec         *pspec);
+static void gnome_selector_set_property        (GObject            *object,
+                                                guint               param_id,
+                                                const GValue       *value,
+                                                GParamSpec         *pspec);
+
+static GObject *gnome_selector_constructor     (GType                  type,
+						guint                  n_construct_properties,
+						GObjectConstructParam *construct_properties);
+
+static void     update_handler                 (GnomeSelector            *selector);
+static void     browse_handler                 (GnomeSelector            *selector);
+static void     clear_handler                  (GnomeSelector            *selector,
+						guint                     list_id);
+
+static gchar   *get_uri_handler                (GnomeSelector            *selector);
+static void     set_uri_handler                (GnomeSelector            *selector,
+                                                const gchar              *uri,
+						GnomeSelectorAsyncHandle *async_handle);
+
+static void     add_uri_handler                (GnomeSelector            *selector,
+                                                const gchar              *uri,
+                                                gint                      position,
+						guint                     list_id,
+						GnomeSelectorAsyncHandle *async_handle);
+
+static void     add_file_handler               (GnomeSelector            *selector,
+                                                const gchar              *uri,
+                                                gint                      position,
+						guint                     list_id,
+						GnomeSelectorAsyncHandle *async_handle);
+
+static void     add_directory_handler          (GnomeSelector            *selector,
+                                                const gchar              *uri,
+                                                gint                      position,
+						guint                     list_id,
+						GnomeSelectorAsyncHandle *async_handle);
+static void     add_uri_list_handler           (GnomeSelector            *selector,
+						GSList                   *list,
+						gint                      position,
+						guint                     list_id,
+						GnomeSelectorAsyncHandle *async_handle);
+
+static GSList  *get_uri_list_handler           (GnomeSelector            *selector,
+                                                guint                     list_id);
+
+static void     do_construct_handler           (GnomeSelector            *selector);
+
+
+
+static void     free_entry_func                (gpointer         data,
+                                                gpointer         user_data);
+
+
+
+#define GNOME_SELECTOR_GCONF_DIR "/desktop/standard/gnome-selector"
+
+enum {
+    PROP_0,
+
+    /* Construction properties */
+    PROP_ENTRY_WIDGET,
+    PROP_SELECTOR_WIDGET,
+    PROP_BROWSE_DIALOG,
+    PROP_WANT_DEFAULT_BEHAVIOUR,
+    PROP_USE_DEFAULT_ENTRY_WIDGET,
+    PROP_USE_DEFAULT_SELECTOR_WIDGET,
+    PROP_USE_DEFAULT_BROWSE_DIALOG,
+    PROP_WANT_BROWSE_BUTTON,
+    PROP_WANT_CLEAR_BUTTON,
+    PROP_WANT_DEFAULT_BUTTON,
+    PROP_AUTO_SAVE_HISTORY,
+    PROP_AUTO_SAVE_ALL,
+
+    /* Normal properties */
+    PROP_DIALOG_TITLE,
+    PROP_HISTORY_ID,
+    PROP_SELECTION_MODE
+};
+
+enum {
+    CHANGED_SIGNAL,
+    BROWSE_SIGNAL,
+    CLEAR_SIGNAL,
+    CHECK_FILENAME_SIGNAL,
+    GET_URI_SIGNAL,
+    SET_URI_SIGNAL,
+    ADD_FILE_SIGNAL,
+    CHECK_DIRECTORY_SIGNAL,
+    ADD_DIRECTORY_SIGNAL,
+    FREEZE_SIGNAL,
+    UPDATE_SIGNAL,
+    UPDATE_URI_LIST_SIGNAL,
+    THAW_SIGNAL,
+    GET_SELECTION_MODE_SIGNAL,
+    SET_SELECTION_MODE_SIGNAL,
+    GET_SELECTION_SIGNAL,
+    SELECTION_CHANGED_SIGNAL,
+    SET_ENTRY_TEXT_SIGNAL,
+    GET_ENTRY_TEXT_SIGNAL,
+    ACTIVATE_ENTRY_SIGNAL,
+    HISTORY_CHANGED_SIGNAL,
+    GET_URI_LIST_SIGNAL,
+    ADD_URI_LIST_SIGNAL,
+    ADD_URI_SIGNAL,
+    LAST_SIGNAL
+};
+
+static int gnome_selector_signals [LAST_SIGNAL] = {0};
+
+/**
+ * gnome_selector_get_type
+ *
+ * Returns the type assigned to the GnomeSelector widget.
+ **/
+/* The following defines the get_type */
+GNOME_CLASS_BOILERPLATE (GnomeSelector, gnome_selector,
+			 GtkVBox, gtk_vbox)
+
+
+static void
+gnome_selector_class_init (GnomeSelectorClass *class)
+{
+    GtkObjectClass *object_class;
+    GObjectClass *gobject_class;
+
+    object_class = (GtkObjectClass *) class;
+    gobject_class = (GObjectClass *) class;
+
+    gnome_selector_signals [CHANGED_SIGNAL] =
+	gtk_signal_new ("changed",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeSelectorClass,
+					   changed),
+			gtk_signal_default_marshaller,
+			GTK_TYPE_NONE,
+			0);
+    gnome_selector_signals [BROWSE_SIGNAL] =
+	gtk_signal_new ("browse",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeSelectorClass,
+					   browse),
+			gtk_signal_default_marshaller,
+			GTK_TYPE_NONE,
+			0);
+    gnome_selector_signals [CLEAR_SIGNAL] =
+	gtk_signal_new ("clear",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeSelectorClass,
+					   clear),
+			gnome_marshal_VOID__UINT,
+			GTK_TYPE_NONE, 1,
+			GTK_TYPE_UINT);
+    gnome_selector_signals [FREEZE_SIGNAL] =
+	gtk_signal_new ("freeze",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeSelectorClass,
+					   freeze),
+			gtk_signal_default_marshaller,
+			GTK_TYPE_NONE,
+			0);
+    gnome_selector_signals [UPDATE_SIGNAL] =
+	gtk_signal_new ("update",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeSelectorClass,
+					   update),
+			gtk_signal_default_marshaller,
+			GTK_TYPE_NONE,
+			0);
+    gnome_selector_signals [THAW_SIGNAL] =
+	gtk_signal_new ("thaw",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeSelectorClass,
+					   thaw),
+			gtk_signal_default_marshaller,
+			GTK_TYPE_NONE,
+			0);
+    gnome_selector_signals [GET_URI_SIGNAL] =
+	gtk_signal_new ("get_uri",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeSelectorClass,
+					   get_uri),
+			gnome_marshal_STRING__VOID,
+			GTK_TYPE_STRING,
+			0);
+    gnome_selector_signals [SET_URI_SIGNAL] =
+	gtk_signal_new ("set_uri",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeSelectorClass,
+					   set_uri),
+			gnome_marshal_VOID__STRING_BOXED,
+			GTK_TYPE_NONE, 2,
+			GTK_TYPE_STRING,
+			GNOME_TYPE_SELECTOR_ASYNC_HANDLE);
+    gnome_selector_signals [ADD_FILE_SIGNAL] =
+	gtk_signal_new ("add_file",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeSelectorClass,
+					   add_file),
+			gnome_marshal_VOID__STRING_INT_UINT_BOXED,
+			GTK_TYPE_NONE, 4,
+			GTK_TYPE_STRING, GTK_TYPE_INT, GTK_TYPE_UINT,
+			GNOME_TYPE_SELECTOR_ASYNC_HANDLE);
+    gnome_selector_signals [ADD_DIRECTORY_SIGNAL] =
+	gtk_signal_new ("add_directory",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeSelectorClass,
+					   add_directory),
+			gnome_marshal_VOID__STRING_INT_UINT_BOXED,
+			GTK_TYPE_NONE, 4,
+			GTK_TYPE_STRING, GTK_TYPE_INT, GTK_TYPE_UINT,
+			GNOME_TYPE_SELECTOR_ASYNC_HANDLE);
+    gnome_selector_signals [ADD_URI_SIGNAL] =
+	gtk_signal_new ("add_uri",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeSelectorClass,
+					   add_uri),
+			gnome_marshal_VOID__STRING_INT_UINT_BOXED,
+			GTK_TYPE_NONE, 4,
+			GTK_TYPE_STRING, GTK_TYPE_INT, GTK_TYPE_UINT,
+			GNOME_TYPE_SELECTOR_ASYNC_HANDLE);
+    gnome_selector_signals [UPDATE_URI_LIST_SIGNAL] =
+	gtk_signal_new ("update_uri_list",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeSelectorClass,
+					   update_uri_list),
+			gnome_marshal_VOID__UINT,
+			GTK_TYPE_NONE, 1,
+			GTK_TYPE_UINT);
+    gnome_selector_signals [GET_SELECTION_MODE_SIGNAL] =
+	gtk_signal_new ("get_selection_mode",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeSelectorClass,
+					   get_selection_mode),
+			gnome_marshal_ENUM__VOID,
+			GTK_TYPE_SELECTION_MODE, 0);
+    gnome_selector_signals [SET_SELECTION_MODE_SIGNAL] =
+	gtk_signal_new ("set_selection_mode",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeSelectorClass,
+					   set_selection_mode),
+			gtk_marshal_VOID__ENUM,
+			GTK_TYPE_NONE, 1,
+			GTK_TYPE_SELECTION_MODE);
+    gnome_selector_signals [GET_SELECTION_SIGNAL] =
+	gtk_signal_new ("get_selection",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeSelectorClass,
+					   get_selection),
+			gnome_marshal_POINTER__VOID,
+			GTK_TYPE_POINTER,
+			0);
+    gnome_selector_signals [SELECTION_CHANGED_SIGNAL] =
+	gtk_signal_new ("selection_changed",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeSelectorClass,
+					   selection_changed),
+			gtk_signal_default_marshaller,
+			GTK_TYPE_NONE,
+			0);
+    gnome_selector_signals [GET_ENTRY_TEXT_SIGNAL] =
+	gtk_signal_new ("get_entry_text",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeSelectorClass,
+					   get_entry_text),
+			gnome_marshal_STRING__VOID,
+			GTK_TYPE_STRING,
+			0);
+    gnome_selector_signals [SET_ENTRY_TEXT_SIGNAL] =
+	gtk_signal_new ("set_entry_text",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeSelectorClass,
+					   set_entry_text),
+			gtk_marshal_VOID__STRING,
+			GTK_TYPE_NONE,
+			1,
+			GTK_TYPE_STRING);
+    gnome_selector_signals [ACTIVATE_ENTRY_SIGNAL] =
+	gtk_signal_new ("activate_entry",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeSelectorClass,
+					   activate_entry),
+			gtk_marshal_VOID__VOID,
+			GTK_TYPE_NONE,
+			0);
+    gnome_selector_signals [HISTORY_CHANGED_SIGNAL] =
+	gtk_signal_new ("history_changed",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeSelectorClass,
+					   history_changed),
+			gtk_marshal_VOID__VOID,
+			GTK_TYPE_NONE,
+			0);
+    gnome_selector_signals [GET_URI_LIST_SIGNAL] =
+	gtk_signal_new ("get_uri_list",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeSelectorClass,
+					   get_uri_list),
+			gnome_marshal_POINTER__BOOLEAN,
+			GTK_TYPE_POINTER, 1,
+			GTK_TYPE_BOOL);
+    gnome_selector_signals [ADD_URI_LIST_SIGNAL] =
+	gtk_signal_new ("add_uri_list",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeSelectorClass,
+					   add_uri_list),
+			gnome_marshal_VOID__POINTER_INT_BOOLEAN_BOXED,
+			GTK_TYPE_NONE, 4,
+			GTK_TYPE_POINTER, GTK_TYPE_INT, GTK_TYPE_BOOL,
+			GNOME_TYPE_SELECTOR_ASYNC_HANDLE);
+    gnome_selector_signals [CHECK_FILENAME_SIGNAL] =
+	gtk_signal_new ("check_filename",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeSelectorClass,
+					   check_filename),
+			gnome_marshal_VOID__STRING_BOXED,
+			GTK_TYPE_NONE, 2,
+			GTK_TYPE_STRING,
+			GNOME_TYPE_SELECTOR_ASYNC_HANDLE);
+    gnome_selector_signals [CHECK_DIRECTORY_SIGNAL] =
+	gtk_signal_new ("check_directory",
+			GTK_RUN_LAST,
+			GTK_CLASS_TYPE (object_class),
+			GTK_SIGNAL_OFFSET (GnomeSelectorClass,
+					   check_directory),
+			gnome_marshal_VOID__STRING_BOXED,
+			GTK_TYPE_NONE, 2,
+			GTK_TYPE_STRING,
+			GNOME_TYPE_SELECTOR_ASYNC_HANDLE);
+
+    gobject_class->get_property = gnome_selector_get_property;
+    gobject_class->set_property = gnome_selector_set_property;
+    gobject_class->constructor = gnome_selector_constructor;
+
+    /* Construction properties */
+    g_object_class_install_property
+	(gobject_class,
+	 PROP_ENTRY_WIDGET,
+	 g_param_spec_object ("entry_widget", NULL, NULL,
+			      GTK_TYPE_WIDGET,
+			      (G_PARAM_READABLE | G_PARAM_WRITABLE |
+			       G_PARAM_CONSTRUCT_ONLY)));
+    g_object_class_install_property
+	(gobject_class,
+	 PROP_SELECTOR_WIDGET,
+	 g_param_spec_object ("selector_widget", NULL, NULL,
+			      GTK_TYPE_WIDGET,
+			      (G_PARAM_READABLE | G_PARAM_WRITABLE |
+			       G_PARAM_CONSTRUCT_ONLY)));
+    g_object_class_install_property
+	(gobject_class,
+	 PROP_BROWSE_DIALOG,
+	 g_param_spec_object ("browse_dialog", NULL, NULL,
+			      GTK_TYPE_WIDGET,
+			      (G_PARAM_READABLE | G_PARAM_WRITABLE |
+			       G_PARAM_CONSTRUCT_ONLY)));
+    g_object_class_install_property
+	(gobject_class,
+	 PROP_WANT_DEFAULT_BEHAVIOUR,
+	 g_param_spec_boolean ("want_default_behaviour", NULL, NULL,
+			       TRUE,
+			       (G_PARAM_READABLE | G_PARAM_WRITABLE |
+				G_PARAM_CONSTRUCT_ONLY)));
+    g_object_class_install_property
+	(gobject_class,
+	 PROP_USE_DEFAULT_ENTRY_WIDGET,
+	 g_param_spec_boolean ("use_default_entry_widget", NULL, NULL,
+			       TRUE,
+			       (G_PARAM_READABLE | G_PARAM_WRITABLE |
+				G_PARAM_CONSTRUCT_ONLY)));
+    g_object_class_install_property
+	(gobject_class,
+	 PROP_USE_DEFAULT_SELECTOR_WIDGET,
+	 g_param_spec_boolean ("use_default_selector_widget", NULL, NULL,
+			       TRUE,
+			       (G_PARAM_READABLE | G_PARAM_WRITABLE |
+				G_PARAM_CONSTRUCT_ONLY)));
+    g_object_class_install_property
+	(gobject_class,
+	 PROP_USE_DEFAULT_BROWSE_DIALOG,
+	 g_param_spec_boolean ("use_default_browse_dialog", NULL, NULL,
+			       TRUE,
+			       (G_PARAM_READABLE | G_PARAM_WRITABLE |
+				G_PARAM_CONSTRUCT_ONLY)));
+    g_object_class_install_property
+	(gobject_class,
+	 PROP_WANT_BROWSE_BUTTON,
+	 g_param_spec_boolean ("want_browse_button", NULL, NULL,
+			       TRUE,
+			       (G_PARAM_READABLE | G_PARAM_WRITABLE |
+				G_PARAM_CONSTRUCT_ONLY)));
+    g_object_class_install_property
+	(gobject_class,
+	 PROP_WANT_CLEAR_BUTTON,
+	 g_param_spec_boolean ("want_clear_button", NULL, NULL,
+			       TRUE,
+			       (G_PARAM_READABLE | G_PARAM_WRITABLE |
+				G_PARAM_CONSTRUCT_ONLY)));
+    g_object_class_install_property
+	(gobject_class,
+	 PROP_WANT_DEFAULT_BUTTON,
+	 g_param_spec_boolean ("want_default_button", NULL, NULL,
+			       TRUE,
+			       (G_PARAM_READABLE | G_PARAM_WRITABLE |
+				G_PARAM_CONSTRUCT_ONLY)));
+    g_object_class_install_property
+	(gobject_class,
+	 PROP_AUTO_SAVE_HISTORY,
+	 g_param_spec_boolean ("auto_save_history", NULL, NULL,
+			       FALSE,
+			       (G_PARAM_READABLE | G_PARAM_WRITABLE |
+				G_PARAM_CONSTRUCT_ONLY)));
+    g_object_class_install_property
+	(gobject_class,
+	 PROP_AUTO_SAVE_ALL,
+	 g_param_spec_boolean ("auto_save_all", NULL, NULL,
+			       FALSE,
+			       (G_PARAM_READABLE | G_PARAM_WRITABLE |
+				G_PARAM_CONSTRUCT_ONLY)));
+
+    /* Normal properties */
+    g_object_class_install_property
+	(gobject_class,
+	 PROP_DIALOG_TITLE,
+	 g_param_spec_string ("dialog_title", NULL, NULL,
+			      NULL,
+			      (G_PARAM_READABLE | G_PARAM_WRITABLE |
+			       G_PARAM_CONSTRUCT)));
+    g_object_class_install_property
+	(gobject_class,
+	 PROP_HISTORY_ID,
+	 g_param_spec_string ("history_id", NULL, NULL,
+			      NULL,
+			      (G_PARAM_READABLE | G_PARAM_WRITABLE |
+			       G_PARAM_CONSTRUCT)));
+    g_object_class_install_property
+	(gobject_class,
+	 PROP_SELECTION_MODE,
+	 g_param_spec_enum ("selection_mode", NULL, NULL,
+			    GTK_TYPE_SELECTION_MODE, GTK_SELECTION_SINGLE,
+			    (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+
+    object_class->destroy = gnome_selector_destroy;
+    gobject_class->finalize = gnome_selector_finalize;
+
+    class->do_construct = do_construct_handler;
+
+    class->browse = browse_handler;
+    class->clear = clear_handler;
+    class->update = update_handler;
+
+    class->get_uri = get_uri_handler;
+    class->set_uri = set_uri_handler;
+
+    class->add_uri = add_uri_handler;
+    class->add_file = add_file_handler;
+    class->add_directory = add_directory_handler;
+
+    class->get_uri_list = get_uri_list_handler;
+    class->add_uri_list = add_uri_list_handler;
+}
+
+static void
+gnome_selector_set_property (GObject *object, guint param_id,
+			     const GValue *value, GParamSpec *pspec)
+{
+    GnomeSelector *selector;
+
+    g_return_if_fail (object != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (object));
+
+    selector = GNOME_SELECTOR (object);
+
+    switch (param_id) {
+    case PROP_ENTRY_WIDGET:
+	g_assert (!selector->_priv->constructed);
+	selector->_priv->entry_widget = (GtkWidget *) g_value_get_object (value);
+	if (selector->_priv->entry_widget)
+	    gtk_widget_ref (selector->_priv->entry_widget);
+	break;
+    case PROP_SELECTOR_WIDGET:
+	g_assert (!selector->_priv->constructed);
+	selector->_priv->selector_widget = (GtkWidget *) g_value_get_object (value);
+	if (selector->_priv->selector_widget)
+	    gtk_widget_ref (selector->_priv->selector_widget);
+	break;
+    case PROP_BROWSE_DIALOG:
+	g_assert (!selector->_priv->constructed);
+	selector->_priv->browse_dialog = (GtkWidget *) g_value_get_object (value);
+	if (selector->_priv->browse_dialog)
+	    gtk_widget_ref (selector->_priv->browse_dialog);
+	break;
+    case PROP_WANT_DEFAULT_BEHAVIOUR:
+	g_assert (!selector->_priv->constructed);
+	selector->_priv->want_default_behaviour = g_value_get_boolean (value);
+	break;
+    case PROP_USE_DEFAULT_ENTRY_WIDGET:
+	g_assert (!selector->_priv->constructed);
+	selector->_priv->use_default_entry_widget = g_value_get_boolean (value);
+	break;
+    case PROP_USE_DEFAULT_SELECTOR_WIDGET:
+	g_assert (!selector->_priv->constructed);
+	selector->_priv->use_default_selector_widget = g_value_get_boolean (value);
+	break;
+    case PROP_USE_DEFAULT_BROWSE_DIALOG:
+	g_assert (!selector->_priv->constructed);
+	selector->_priv->use_default_browse_dialog = g_value_get_boolean (value);
+	break;
+    case PROP_WANT_BROWSE_BUTTON:
+	g_assert (!selector->_priv->constructed);
+	selector->_priv->want_browse_button = g_value_get_boolean (value);
+	break;
+    case PROP_WANT_CLEAR_BUTTON:
+	g_assert (!selector->_priv->constructed);
+	selector->_priv->want_clear_button = g_value_get_boolean (value);
+	break;
+    case PROP_WANT_DEFAULT_BUTTON:
+	g_assert (!selector->_priv->constructed);
+	selector->_priv->want_default_button = g_value_get_boolean (value);
+	break;
+    case PROP_AUTO_SAVE_HISTORY:
+	g_assert (!selector->_priv->constructed);
+	selector->_priv->auto_save_history = g_value_get_boolean (value);
+	break;
+    case PROP_AUTO_SAVE_ALL:
+	g_assert (!selector->_priv->constructed);
+	selector->_priv->auto_save_all = g_value_get_boolean (value);
+	break;
+   case PROP_DIALOG_TITLE:
+	gnome_selector_set_dialog_title (selector, g_value_get_string (value));
+	break;
+    case PROP_HISTORY_ID:
+	gnome_selector_set_history_id (selector, g_value_get_string (value));
+	break;
+    case PROP_SELECTION_MODE:
+	gnome_selector_set_selection_mode (selector, g_value_get_enum (value));
+	break;
+    default:
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+	break;
+    }
+}
+
+static void
+gnome_selector_get_property (GObject *object, guint param_id, GValue *value,
+			     GParamSpec *pspec)
+{
+    GnomeSelector *selector;
+
+    g_return_if_fail (object != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (object));
+
+    selector = GNOME_SELECTOR (object);
+
+    switch (param_id) {
+    case PROP_ENTRY_WIDGET:
+	g_value_set_object (value, (GObject *) selector->_priv->entry_widget);
+	break;
+    case PROP_SELECTOR_WIDGET:
+	g_value_set_object (value, (GObject *) selector->_priv->selector_widget);
+	break;
+    case PROP_BROWSE_DIALOG:
+	g_value_set_object (value, (GObject *) selector->_priv->browse_dialog);
+	break;
+    case PROP_WANT_DEFAULT_BEHAVIOUR:
+	g_value_set_boolean (value, selector->_priv->want_default_behaviour);
+	break;
+    case PROP_USE_DEFAULT_ENTRY_WIDGET:
+	g_value_set_boolean (value, selector->_priv->use_default_entry_widget);
+	break;
+    case PROP_USE_DEFAULT_SELECTOR_WIDGET:
+	g_value_set_boolean (value, selector->_priv->use_default_selector_widget);
+	break;
+    case PROP_USE_DEFAULT_BROWSE_DIALOG:
+	g_value_set_boolean (value, selector->_priv->use_default_browse_dialog);
+	break;
+    case PROP_WANT_BROWSE_BUTTON:
+	g_value_set_boolean (value, selector->_priv->want_browse_button);
+	break;
+    case PROP_WANT_CLEAR_BUTTON:
+	g_value_set_boolean (value, selector->_priv->want_clear_button);
+	break;
+    case PROP_WANT_DEFAULT_BUTTON:
+	g_value_set_boolean (value, selector->_priv->want_default_button);
+	break;
+    case PROP_AUTO_SAVE_HISTORY:
+	g_value_set_boolean (value, selector->_priv->auto_save_history);
+	break;
+    case PROP_AUTO_SAVE_ALL:
+	g_value_set_boolean (value, selector->_priv->auto_save_all);
+	break;
+    case PROP_DIALOG_TITLE:
+	g_value_set_string (value, gnome_selector_get_dialog_title (selector));
+	break;
+    case PROP_HISTORY_ID:
+	g_value_set_string (value, gnome_selector_get_history_id (selector));
+	break;
+    case PROP_SELECTION_MODE:
+	g_value_set_enum (value, gnome_selector_get_selection_mode (selector));
+	break;
+    default:
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+	break;
+    }
+}
+
+static void
+gnome_selector_init (GnomeSelector *selector)
+{
+    guint i;
+
+    selector->_priv = g_new0 (GnomeSelectorPrivate, 1);
+
+    selector->_priv->changed = FALSE;
+
+    selector->_priv->selector_widget = NULL;
+    selector->_priv->browse_dialog = NULL;
+
+    selector->_priv->lists = g_ptr_array_sized_new (GNOME_SELECTOR_LIST_MAX);
+    for (i = 0; i < GNOME_SELECTOR_LIST_MAX; i++) {
+	GnomeSelectorListData *data;
+
+	data = g_new0 (GnomeSelectorListData, 1);
+	g_ptr_array_index (selector->_priv->lists, i) = data;
+    }
+}
+
+/*
+ * Default signal handlers.
+ */
+
+static void
+update_handler (GnomeSelector *selector)
+{
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+#if 0
+    if (selector->_priv->need_rebuild)
+	gnome_selector_update_uri_list (selector);
+#endif
+
+    if (selector->_priv->history_changed)
+	gtk_signal_emit (GTK_OBJECT (selector),
+			 gnome_selector_signals [HISTORY_CHANGED_SIGNAL]);
+
+    selector->_priv->history_changed = FALSE;
+    selector->_priv->dirty = FALSE;
+}
+
+static void
+browse_handler (GnomeSelector *selector)
+{
+    GnomeSelectorPrivate *priv;
+
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    priv = selector->_priv;
+
+    /*if it already exists make sure it's shown and raised*/
+    if (priv->browse_dialog) {
+	gtk_widget_show (priv->browse_dialog);
+	if (priv->browse_dialog->window)
+	    gdk_window_raise (priv->browse_dialog->window);
+    }
+}
+
+static void
+free_entry_func (gpointer data, gpointer user_data)
+{
+    g_free (data);
+}
+
+static void
+clear_handler (GnomeSelector *selector, guint list_id)
+{
+    GSList **list_ptr;
+
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    list_ptr = _gnome_selector_get_list_by_id (selector, list_id);
+    g_assert (list_ptr != NULL);
+
+    g_slist_foreach (*list_ptr, free_entry_func, selector);
+    g_slist_free (*list_ptr);
+    *list_ptr = NULL;
+}
+
+static gchar *
+get_uri_handler (GnomeSelector *selector)
+{
+    g_return_val_if_fail (selector != NULL, FALSE);
+    g_return_val_if_fail (GNOME_IS_SELECTOR (selector), FALSE);
+
+    return gnome_selector_get_entry_text (selector);
+}
+
+static void
+set_uri_handler (GnomeSelector *selector, const gchar *filename,
+		 GnomeSelectorAsyncHandle *async_handle)
+{
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    gnome_selector_set_entry_text (selector, filename);
+    /* gnome_selector_activate_entry (selector); */
+
+    if (async_handle != NULL)
+	_gnome_selector_async_handle_completed (async_handle, TRUE);
+}
+
+static void
+add_uri_handler (GnomeSelector *selector, const gchar *uri, gint position,
+		 guint list_id, GnomeSelectorAsyncHandle *async_handle)
+{
+    GSList **list_ptr;
+
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+    g_return_if_fail (uri != NULL);
+    g_return_if_fail (position >= -1);
+
+    list_ptr = _gnome_selector_get_list_by_id (selector, list_id);
+    g_assert (list_ptr != NULL);
+
+    if (position == -1)
+	*list_ptr = g_slist_append (*list_ptr, g_strdup (uri));
+    else
+	*list_ptr = g_slist_insert (*list_ptr, g_strdup (uri), position);
+
+    if (async_handle != NULL)
+	_gnome_selector_async_handle_completed (async_handle, TRUE);
+}
+
+static void
+add_file_handler (GnomeSelector *selector, const gchar *uri, gint position,
+		 guint list_id, GnomeSelectorAsyncHandle *async_handle)
+{
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    if (async_handle != NULL)
+	_gnome_selector_async_handle_completed (async_handle, TRUE);
+}
+
+static void
+add_directory_handler (GnomeSelector *selector, const gchar *uri, gint position,
+		       guint list_id, GnomeSelectorAsyncHandle *async_handle)
+{
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    if (async_handle != NULL)
+	_gnome_selector_async_handle_completed (async_handle, TRUE);
+}
+
+static void
+add_uri_list_handler (GnomeSelector *selector, GSList *list, gint position,
+		      guint list_id, GnomeSelectorAsyncHandle *async_handle)
+{
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    if (async_handle != NULL)
+	_gnome_selector_async_handle_completed (async_handle, TRUE);
+}
+
+static GSList *
+get_uri_list_handler (GnomeSelector *selector, guint list_id)
+{
+    GSList **list_ptr;
+
+    g_return_val_if_fail (selector != NULL, NULL);
+    g_return_val_if_fail (GNOME_IS_SELECTOR (selector), NULL);
+
+    list_ptr = _gnome_selector_get_list_by_id (selector, list_id);
+    g_assert (list_ptr != NULL);
+
+    return _gnome_selector_deep_copy_slist (*list_ptr);
+}
+
+/*
+ * Misc callbacks.
+ */
+
+static void
+browse_clicked_cb (GtkWidget *widget, gpointer data)
+{
+    gtk_signal_emit (GTK_OBJECT (data),
+		     gnome_selector_signals [BROWSE_SIGNAL]);
+}
+
+static void
+default_clicked_cb (GtkWidget *widget, gpointer data)
+{
+    GnomeSelector *selector;
+    GSList *list;
+
+    g_return_if_fail (data != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (data));
+
+    selector = GNOME_SELECTOR (data);
+
+    list = gnome_selector_get_uri_list (selector, GNOME_SELECTOR_LIST_DEFAULT);
+    gnome_selector_clear (selector, GNOME_SELECTOR_LIST_PRIMARY);
+    gnome_selector_add_uri_list (selector, NULL, list, 0,
+				 GNOME_SELECTOR_LIST_PRIMARY, NULL, NULL);
+}
+
+static void
+clear_clicked_cb (GtkWidget *widget, gpointer data)
+{
+    gnome_selector_clear (GNOME_SELECTOR (data), FALSE);
+}
+
+
+static GObject*
+gnome_selector_constructor (GType                  type,
+			    guint                  n_construct_properties,
+			    GObjectConstructParam *construct_properties)
+{
+    GObject *object = G_OBJECT_CLASS (parent_class)->constructor (type,
+								  n_construct_properties,
+								  construct_properties);
+
+    return object;
+}
+
+static void
+do_construct_handler (GnomeSelector *selector)
+{
+    GnomeSelectorPrivate *priv;
+
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    priv = selector->_priv;
+
+    g_message (G_STRLOC);
+
+    priv->db = gnome_program_get_config_database (gnome_program_get ());
+
+    priv->box = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
+
+    priv->hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
+
+    if (priv->entry_widget) {
+	gtk_widget_show_all (priv->entry_widget);
+
+	gtk_box_pack_start (GTK_BOX (priv->hbox), priv->entry_widget,
+			    TRUE, TRUE, 0);
+    }
+
+    gtk_box_pack_start (GTK_BOX (priv->box), priv->hbox,
+			TRUE, FALSE, GNOME_PAD_SMALL);
+
+    if (priv->want_browse_button) {
+	priv->browse_button = gtk_button_new_with_label (_("Browse..."));
+
+	gtk_signal_connect (GTK_OBJECT (priv->browse_button),
+			    "clicked", GTK_SIGNAL_FUNC (browse_clicked_cb),
+			    selector);
+
+	gtk_box_pack_start (GTK_BOX (priv->hbox),
+			    priv->browse_button, FALSE, FALSE, 0);
+    }
+
+    if (priv->want_default_button) {
+	priv->default_button = gtk_button_new_with_label (_("Default..."));
+
+	gtk_signal_connect (GTK_OBJECT (priv->default_button),
+			    "clicked", GTK_SIGNAL_FUNC (default_clicked_cb),
+			    selector);
+
+	gtk_box_pack_start (GTK_BOX (priv->hbox),
+			    priv->default_button, FALSE, FALSE, 0);
+    }
+
+    if (priv->want_clear_button) {
+	priv->clear_button = gtk_button_new_with_label (_("Clear..."));
+
+	gtk_signal_connect (GTK_OBJECT (priv->clear_button),
+			    "clicked", GTK_SIGNAL_FUNC (clear_clicked_cb),
+			    selector);
+
+	gtk_box_pack_start (GTK_BOX (priv->hbox),
+			    priv->clear_button, FALSE, FALSE, 0);
+    }
+
+    if (priv->selector_widget) {
+	gtk_box_pack_start (GTK_BOX (priv->box),
+			    priv->selector_widget, TRUE, TRUE,
+			    GNOME_PAD_SMALL);
+    }
+
+    gtk_widget_show_all (priv->box);
+
+    gtk_box_pack_start (GTK_BOX (selector), priv->box,
+			TRUE, TRUE, GNOME_PAD_SMALL);
+
+    if (priv->auto_save_history)
+	gnome_selector_load_history (selector);
+
+    if (priv->auto_save_all)
+	gnome_selector_load_all (selector);
+
+    selector->_priv->constructed = TRUE;
+}
+
+void
+gnome_selector_do_construct (GnomeSelector *selector)
+{
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    GNOME_SELECTOR_CLASS (G_OBJECT_GET_CLASS (selector))->do_construct (selector);
+}
+
+static void
+gnome_selector_destroy (GtkObject *object)
+{
+    GnomeSelector *selector;
+
+    /* remember, destroy can be run multiple times! */
+
+    g_return_if_fail (object != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (object));
+
+    selector = GNOME_SELECTOR (object);
+
+#if 0
+    if (selector->_priv->client) {
+	if (selector->_priv->flags & GNOME_SELECTOR_AUTO_SAVE_ALL)
+	    gnome_selector_save_all (selector);
+
+	if (selector->_priv->gconf_history_dir)
+	    gconf_client_remove_dir
+		(selector->_priv->client,
+		 selector->_priv->gconf_history_dir,
+		 NULL);
+
+	g_object_unref (G_OBJECT (selector->_priv->client));
+	selector->_priv->client = NULL;
+    }
+#endif
+
+    if (selector->_priv->selector_widget) {
+	gtk_widget_unref (selector->_priv->selector_widget);
+	selector->_priv->selector_widget = NULL;
+    }
+
+    if (selector->_priv->browse_dialog) {
+	gtk_widget_unref (selector->_priv->browse_dialog);
+	selector->_priv->browse_dialog = NULL;
+    }
+
+    if (selector->_priv->entry_widget) {
+	gtk_widget_unref (selector->_priv->entry_widget);
+	selector->_priv->entry_widget = NULL;
+    }
+
+    GNOME_CALL_PARENT_HANDLER (GTK_OBJECT_CLASS, destroy, (object));
+}
+
+static void
+gnome_selector_finalize (GObject *object)
+{
+    GnomeSelector *selector;
+
+    g_return_if_fail (object != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (object));
+
+    selector = GNOME_SELECTOR (object);
+
+    if (selector->_priv) {
+	guint i;
+
+	for (i = 0; i < selector->_priv->lists->len; i++) {
+	    GnomeSelectorListData *data = g_ptr_array_index
+		(selector->_priv->lists, i);
+
+	    g_slist_foreach (data->list, free_entry_func, selector);
+	}
+
+	g_ptr_array_free (selector->_priv->lists, TRUE);
+
+	g_free (selector->_priv->dialog_title);
+	g_free (selector->_priv->history_id);
+	g_free (selector->_priv->gconf_history_dir);
+	g_free (selector->_priv->gconf_history_key);
+	g_free (selector->_priv->gconf_uri_list_key);
+    }
+
+    g_free (selector->_priv);
+    selector->_priv = NULL;
+
+    GNOME_CALL_PARENT_HANDLER (G_OBJECT_CLASS, finalize, (object));
+}
+
+
+/**
+ * gnome_selector_get_dialog_title
+ * @selector: Pointer to GnomeSelector object.
+ *
+ * Description: Returns the titel of the popup dialog.
+ *
+ * Returns: Titel of the popup dialog.
+ */
+const gchar *
+gnome_selector_get_dialog_title (GnomeSelector *selector)
+{
+    g_return_val_if_fail (selector != NULL, NULL);
+    g_return_val_if_fail (GNOME_IS_SELECTOR (selector), NULL);
+
+    return selector->_priv->dialog_title;
+}
+
+
+/**
+ * gnome_selector_set_dialog_title
+ * @selector: Pointer to GnomeSelector object.
+ * @dialog_title: New title for the popup dialog.
+ *
+ * Description: Sets the titel of the popup dialog.
+ *
+ * This is only used when the widget uses a popup dialog for
+ * the actual selector.
+ *
+ * Returns:
+ */
+void
+gnome_selector_set_dialog_title (GnomeSelector *selector,
+				 const gchar *dialog_title)
+{
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    if (selector->_priv->dialog_title) {
+	g_free (selector->_priv->dialog_title);
+	selector->_priv->dialog_title = NULL;
+    }
+
+    /* this is NULL safe. */
+    selector->_priv->dialog_title = g_strdup (dialog_title);
+
+    g_object_notify (G_OBJECT (selector), "dialog_title");
+}
+
+const gchar *
+gnome_selector_get_history_id (GnomeSelector *selector)
+{
+    g_return_val_if_fail (selector != NULL, NULL);
+    g_return_val_if_fail (GNOME_IS_SELECTOR (selector), NULL);
+
+    return selector->_priv->history_id;
+}
+
+void
+gnome_selector_set_history_id (GnomeSelector *selector,
+			       const gchar *history_id)
+{
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    if (selector->_priv->history_id) {
+	g_free (selector->_priv->history_id);
+	selector->_priv->history_id = NULL;
+    }
+
+    /* this is NULL safe. */
+    selector->_priv->history_id = g_strdup (history_id);
+
+    g_object_notify (G_OBJECT (selector), "history_id");
+}
+
+GSList *
+gnome_selector_get_uri_list (GnomeSelector *selector, guint list_id)
+{
+    GSList *retval = NULL;
+
+    g_return_val_if_fail (selector != NULL, NULL);
+    g_return_val_if_fail (GNOME_IS_SELECTOR (selector), NULL);
+
+    gtk_signal_emit (GTK_OBJECT (selector),
+		     gnome_selector_signals [GET_URI_LIST_SIGNAL],
+		     list_id, &retval);
+
+    return retval;
+}
+
+void
+gnome_selector_add_uri_list (GnomeSelector *selector,
+			     GnomeSelectorAsyncHandle **async_handle_return,
+			     GSList *uri_list, gint position, guint list_id,
+			     GnomeSelectorAsyncFunc async_func,
+			     gpointer user_data)
+{
+    GnomeSelectorAsyncHandle *async_handle;
+
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    async_handle = _gnome_selector_async_handle_get
+	(selector, GNOME_SELECTOR_ASYNC_TYPE_ADD_URI_LIST,
+	 NULL, async_func, user_data);
+    if (async_handle_return != NULL)
+	*async_handle_return = async_handle;
+
+    gtk_signal_emit (GTK_OBJECT (selector),
+		     gnome_selector_signals [ADD_URI_LIST_SIGNAL],
+		     uri_list, position, list_id, async_handle);
+}
+
+GtkSelectionMode
+gnome_selector_get_selection_mode (GnomeSelector *selector)
+{
+    GtkSelectionMode mode = 0;
+
+    g_return_val_if_fail (selector != NULL, 0);
+    g_return_val_if_fail (GNOME_IS_SELECTOR (selector), 0);
+
+    gtk_signal_emit (GTK_OBJECT (selector),
+		     gnome_selector_signals [GET_SELECTION_MODE_SIGNAL],
+		     &mode);
+
+    return mode;
+}
+
+void
+gnome_selector_set_selection_mode (GnomeSelector *selector,
+				   GtkSelectionMode mode)
+{
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    gtk_signal_emit (GTK_OBJECT (selector),
+		     gnome_selector_signals [SET_SELECTION_MODE_SIGNAL],
+		     (gint) mode);
+}
+
+
+GSList *
+gnome_selector_get_selection (GnomeSelector *selector)
+{
+    GSList *retval = NULL;
+
+    g_return_val_if_fail (selector != NULL, NULL);
+    g_return_val_if_fail (GNOME_IS_SELECTOR (selector), NULL);
+
+    gtk_signal_emit (GTK_OBJECT (selector),
+		     gnome_selector_signals [GET_SELECTION_SIGNAL],
+		     &retval);
+
+    return retval;
+}
+
+
+/**
+ * gnome_selector_update
+ * @selector: Pointer to GnomeSelector object.
+ *
+ * Description: Updates the file list.
+ *
+ * Returns:
+ */
+void
+gnome_selector_update (GnomeSelector *selector)
+{
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    gtk_signal_emit (GTK_OBJECT (selector),
+		     gnome_selector_signals [UPDATE_SIGNAL]);
+}
+
+
+/**
+ * gnome_selector_clear
+ * @selector: Pointer to GnomeSelector object.
+ *
+ * Description: Removes all entries from the selector.
+ *
+ * Returns:
+ */
+void
+gnome_selector_clear (GnomeSelector *selector, guint list_id)
+{
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    gnome_selector_freeze (selector);
+    gtk_signal_emit (GTK_OBJECT (selector),
+		     gnome_selector_signals [CLEAR_SIGNAL],
+		     list_id);
+    gnome_selector_thaw (selector);
+
+    selector->_priv->need_rebuild = TRUE;
+
+    if (selector->_priv->frozen)
+	selector->_priv->dirty = TRUE;
+    else
+	gnome_selector_update (selector);
+}
+
+/**
+ * gnome_selector_get_uri
+ * @selector: Pointer to GnomeSelector object.
+ *
+ * Description:
+ *
+ * Returns:
+ */
+gchar *
+gnome_selector_get_uri (GnomeSelector *selector)
+{
+    gchar *retval = NULL;
+
+    g_return_val_if_fail (selector != NULL, NULL);
+    g_return_val_if_fail (GNOME_IS_SELECTOR (selector), NULL);
+
+    gtk_signal_emit (GTK_OBJECT (selector),
+		     gnome_selector_signals [GET_URI_SIGNAL],
+		     &retval);
+
+    return retval;
+}
+
+
+/**
+ * gnome_selector_set_uri
+ * @selector: Pointer to GnomeSelector object.
+ * @filename: Filename to set.
+ *
+ * Description: Sets @filename as the currently selected filename.
+ *
+ * This calls gnome_selector_check_filename() to make sure @filename
+ * is a valid file for this kind of selector.
+ *
+ * Returns: #TRUE if @filename was ok or #FALSE if not.
+ */
+void
+gnome_selector_set_uri (GnomeSelector *selector,
+			GnomeSelectorAsyncHandle **async_handle_return,
+			const gchar *filename,
+			GnomeSelectorAsyncFunc async_func,
+			gpointer user_data)
+{
+    GnomeSelectorAsyncHandle *async_handle;
+
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+    g_return_if_fail (filename != NULL);
+
+    async_handle = _gnome_selector_async_handle_get
+	(selector, GNOME_SELECTOR_ASYNC_TYPE_SET_URI,
+	 filename, async_func, user_data);
+    if (async_handle_return != NULL)
+	*async_handle_return = async_handle;
+
+    gtk_signal_emit (GTK_OBJECT (selector),
+		     gnome_selector_signals [SET_URI_SIGNAL],
+		     filename, async_handle);
+}
+
+
+/**
+ * gnome_selector_update_uri_list
+ * @selector: Pointer to GnomeSelector object.
+ *
+ * Description: Updates the internal file list.
+ *
+ * Returns:
+ */
+void
+gnome_selector_update_uri_list (GnomeSelector *selector, guint list_id)
+{
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    gtk_signal_emit (GTK_OBJECT (selector),
+		     gnome_selector_signals [UPDATE_URI_LIST_SIGNAL],
+		     list_id);
+}
+
+
+/**
+ * gnome_selector_freeze
+ * @selector: Pointer to GnomeSelector object.
+ *
+ * Description:
+ *
+ * Returns:
+ */
+void
+gnome_selector_freeze (GnomeSelector *selector)
+{
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    selector->_priv->frozen++;
+
+    /* Note that we only emit the signal once. */
+    if (selector->_priv->frozen == 1)
+	gtk_signal_emit (GTK_OBJECT (selector),
+			 gnome_selector_signals [FREEZE_SIGNAL]);
+}
+
+/**
+ * gnome_selector_is_frozen
+ * @selector: Pointer to GnomeSelector object.
+ *
+ * Description:
+ *
+ * Returns:
+ */
+gboolean
+gnome_selector_is_frozen (GnomeSelector *selector)
+{
+    g_return_val_if_fail (selector != NULL, FALSE);
+    g_return_val_if_fail (GNOME_IS_SELECTOR (selector), FALSE);
+
+    return selector->_priv->frozen ? TRUE : FALSE;
+}
+
+
+/**
+ * gnome_selector_thaw
+ * @selector: Pointer to GnomeSelector object.
+ *
+ * Description:
+ *
+ * Returns:
+ */
+void
+gnome_selector_thaw (GnomeSelector *selector)
+{
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    g_return_if_fail (selector->_priv->frozen > 0);
+
+    selector->_priv->frozen--;
+
+    /* Note that we only emit the signal once. */
+    if (selector->_priv->frozen == 0) {
+	gtk_signal_emit (GTK_OBJECT (selector),
+			 gnome_selector_signals [THAW_SIGNAL]);
+
+	if (selector->_priv->dirty) {
+	    selector->_priv->dirty = FALSE;
+	    gnome_selector_update (selector);
+	}
+    }
+}
+
+
+/**
+ * gnome_selector_get_entry_text
+ * @selector: Pointer to GnomeSelector object.
+ *
+ * Description:
+ *
+ * Returns:
+ */
+gchar *
+gnome_selector_get_entry_text (GnomeSelector *selector)
+{
+    gchar *retval = NULL;
+
+    g_return_val_if_fail (selector != NULL, NULL);
+    g_return_val_if_fail (GNOME_IS_SELECTOR (selector), NULL);
+
+    gtk_signal_emit (GTK_OBJECT (selector),
+		     gnome_selector_signals [GET_ENTRY_TEXT_SIGNAL],
+		     &retval);
+
+    return retval;
+}
+
+
+/**
+ * gnome_selector_set_entry_text
+ * @selector: Pointer to GnomeSelector object.
+ * @text: The text which should be set.
+ *
+ * Description:
+ *
+ * Returns:
+ */
+void
+gnome_selector_set_entry_text (GnomeSelector *selector, const gchar *text)
+{
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    gtk_signal_emit (GTK_OBJECT (selector),
+		     gnome_selector_signals [SET_ENTRY_TEXT_SIGNAL],
+		     text);
+}
+
+void
+gnome_selector_activate_entry (GnomeSelector *selector)
+{
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    gtk_signal_emit (GTK_OBJECT (selector),
+		     gnome_selector_signals [ACTIVATE_ENTRY_SIGNAL]);
+}
+
+guint
+gnome_selector_get_history_length (GnomeSelector *selector)
+{
+    g_return_val_if_fail (selector != NULL, 0);
+    g_return_val_if_fail (GNOME_IS_SELECTOR (selector), 0);
+
+    return selector->_priv->max_history_length;
+}
+
+static void
+free_history_item (GnomeSelectorHistoryItem *item, gpointer data)
+{
+    if (item != NULL)
+	g_free (item->text);
+    g_free (item);
+}
+
+static gint
+compare_history_items (gconstpointer a, gconstpointer b)
+{
+    GnomeSelectorHistoryItem *ia, *ib;
+
+    ia = (GnomeSelectorHistoryItem *) a;
+    ib = (GnomeSelectorHistoryItem *) b;
+
+    return strcmp (ia->text, ib->text);
+}
+
+static void
+set_history_changed (GnomeSelector *selector)
+{
+    if (selector->_priv->frozen)
+	selector->_priv->history_changed = TRUE;
+    else
+	gtk_signal_emit (GTK_OBJECT (selector),
+			 gnome_selector_signals [HISTORY_CHANGED_SIGNAL]);
+}
+
+void
+gnome_selector_set_history_length (GnomeSelector *selector,
+				   guint history_length)
+{
+    guint old_length;
+
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    /* truncate history if necessary. */
+    old_length = g_slist_length (selector->_priv->history);
+
+    if (old_length < history_length) {
+	guint prev_pos = (history_length > 0) ? history_length-1 : 0;
+	GSList *c = g_slist_nth (selector->_priv->history, prev_pos);
+
+	if (c) {
+	    g_slist_foreach (c->next, (GFunc) free_history_item,
+			     selector);
+	    g_slist_free (c->next);
+	    c->next = NULL;
+
+	    set_history_changed (selector);
+	}
+    }
+
+    selector->_priv->max_history_length = history_length;
+}
+
+static void
+_gnome_selector_add_history (GnomeSelector *selector, gboolean save,
+			     const gchar *text, gboolean append)
+{
+    GnomeSelectorHistoryItem *item;
+    GSList *node;
+
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+    g_return_if_fail (text != NULL);
+
+    item = g_new0 (GnomeSelectorHistoryItem, 1);
+    item->text = g_strdup (text);
+    item->save = save;
+
+    /* if it's already in the history */
+    node = g_slist_find_custom (selector->_priv->history, item,
+				compare_history_items);
+    if (node) {
+	free_history_item (node->data, selector);
+	selector->_priv->history = g_slist_remove
+	    (selector->_priv->history, node->data);
+    }
+
+    if (append)
+	selector->_priv->history = g_slist_append
+	    (selector->_priv->history, item);
+    else
+	selector->_priv->history = g_slist_prepend
+	    (selector->_priv->history, item);
+
+    set_history_changed (selector);
+}
+
+void
+gnome_selector_prepend_history (GnomeSelector *selector, gboolean save,
+				const gchar *text)
+{
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+    g_return_if_fail (text != NULL);
+
+    _gnome_selector_add_history (selector, save, text, FALSE);
+}
+
+void
+gnome_selector_append_history (GnomeSelector *selector, gboolean save,
+			       const gchar *text)
+{
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+    g_return_if_fail (text != NULL);
+
+    _gnome_selector_add_history (selector, save, text, TRUE);
+}
+
+GSList *
+gnome_selector_get_history (GnomeSelector *selector)
+{
+    GSList *retval = NULL, *c;
+
+    g_return_val_if_fail (selector != NULL, NULL);
+    g_return_val_if_fail (GNOME_IS_SELECTOR (selector), NULL);
+
+    for (c = selector->_priv->history; c; c = c->next) {
+	GnomeSelectorHistoryItem *item = c->data;
+
+	retval = g_slist_prepend (retval, g_strdup (item->text));
+    }
+
+    return g_slist_reverse (retval);
+}
+
+void
+gnome_selector_set_history (GnomeSelector *selector, GSList *history)
+{
+    GSList *c;
+
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    gnome_selector_clear_history (selector);
+
+    for (c = history; c; c = c->next)
+	gnome_selector_prepend_history (selector, TRUE, c->data);
+
+    selector->_priv->history = g_slist_reverse (selector->_priv->history);
+
+    set_history_changed (selector);
+}
+
+static GSList * G_GNUC_UNUSED
+_gnome_selector_history_to_list (GnomeSelector *selector, gboolean only_save)
+{
+    GSList *thelist = NULL, *c;
+
+    g_return_val_if_fail (selector != NULL, NULL);
+    g_return_val_if_fail (GNOME_IS_SELECTOR (selector), NULL);
+
+    for (c = selector->_priv->history; c; c = c->next) {
+	GnomeSelectorHistoryItem *item = c->data;
+
+	if (only_save && !item->save)
+	    continue;
+
+	thelist = g_slist_prepend (thelist, item->text);
+    }
+
+    thelist = g_slist_reverse (thelist);
+    return thelist;
+}
+
+void
+gnome_selector_load_history (GnomeSelector *selector)
+{
+#if 0
+    GSList *thelist;
+#endif
+
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    if (!selector->_priv->gconf_history_key)
+	return;
+
+#if 0
+    thelist = gconf_client_get_list (selector->_priv->client,
+				     selector->_priv->gconf_history_key,
+				     GCONF_VALUE_STRING, NULL);
+
+    gnome_selector_set_history (selector, thelist);
+
+    g_slist_foreach (thelist, (GFunc) g_free, NULL);
+    g_slist_free (thelist);
+#endif
+}
+
+void
+gnome_selector_save_history (GnomeSelector *selector)
+{
+#if 0
+    GSList *thelist;
+    gboolean result;
+#endif
+
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    if (!selector->_priv->gconf_history_key)
+	return;
+
+#if 0
+    thelist = _gnome_selector_history_to_list (selector, TRUE);
+
+    result = gconf_client_set_list (selector->_priv->client,
+				    selector->_priv->gconf_history_key,
+				    GCONF_VALUE_STRING, thelist, NULL);
+
+    g_slist_free (thelist);
+#endif
+}
+
+void
+gnome_selector_clear_history (GnomeSelector *selector)
+{
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    g_slist_foreach (selector->_priv->history,
+		     (GFunc) free_history_item, selector);
+    g_slist_free (selector->_priv->history);
+    selector->_priv->history = NULL;
+
+    set_history_changed (selector);
+}
+
+guint
+_gnome_selector_register_list (GnomeSelector *selector, GQuark list_quark)
+{
+    GnomeSelectorListData *data;
+    guint i;
+
+    g_return_val_if_fail (selector != NULL, 0);
+    g_return_val_if_fail (GNOME_IS_SELECTOR (selector), 0);
+
+    data = g_new0 (GnomeSelectorListData, 1);
+    data->quark = list_quark;
+
+    g_ptr_array_add (selector->_priv->lists, data);
+
+    for (i = 0; i < selector->_priv->lists->len; i++)
+	if (g_ptr_array_index (selector->_priv->lists, i) == data)
+	    return i;
+
+    g_assert_not_reached ();
+    return 0;
+}
+
+void
+_gnome_selector_unregister_list (GnomeSelector *selector, guint list_id)
+{
+    GnomeSelectorListData *data;
+
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    data = g_ptr_array_remove_index (selector->_priv->lists, list_id);
+    if (data == NULL)
+	return;
+
+    _gnome_selector_deep_free_slist (data->list);
+    g_free (data);
+}
+
+GSList **
+_gnome_selector_get_list_by_id (GnomeSelector *selector, guint list_id)
+{
+    GnomeSelectorListData *data;
+
+    g_return_val_if_fail (selector != NULL, NULL);
+    g_return_val_if_fail (GNOME_IS_SELECTOR (selector), NULL);
+
+    data = g_ptr_array_index (selector->_priv->lists, list_id);
+    if (data == NULL)
+	return NULL;
+    else
+	return &data->list;
+}
+
+GSList *
+_gnome_selector_deep_copy_slist (GSList *thelist)
+{
+    GSList *retval = NULL, *c;
+
+    for (c = thelist; c; c = c->next)
+	retval = g_slist_prepend (retval, g_strdup (c->data));
+
+    retval = g_slist_reverse (retval);
+    return retval;
+}
+
+void
+_gnome_selector_deep_free_slist (GSList *thelist)
+{
+    g_slist_foreach (thelist, (GFunc) g_free, NULL);
+    g_slist_free (thelist);
+}
+
+#if 0
+static void
+gnome_selector_save_all (GnomeSelector *selector)
+{
+    GSList *uri_list;
+    gboolean result;
+
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    if (!selector->_priv->gconf_uri_list_key)
+	return;
+
+    uri_list = gnome_selector_get_uri_list (selector, FALSE);
+
+    result = gconf_client_set_list (selector->_priv->client,
+				    selector->_priv->gconf_uri_list_key,
+				    GCONF_VALUE_STRING, uri_list,
+				    NULL);
+
+    _gnome_selector_deep_free_slist (uri_list);
+}
+#endif
+
+static void
+gnome_selector_load_all (GnomeSelector *selector)
+{
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+
+    if (!selector->_priv->gconf_uri_list_key)
+	return;
+
+#if 0
+    selector->_priv->uri_list = gconf_client_get_list
+	(selector->_priv->client,
+	 selector->_priv->gconf_uri_list_key,
+	 GCONF_VALUE_STRING, NULL);
+
+    selector->_priv->need_rebuild = TRUE;
+
+    if (selector->_priv->frozen)
+	selector->_priv->dirty = TRUE;
+    else
+	gnome_selector_update (selector);
+#endif
+}
+
+GnomeSelectorAsyncHandle *
+_gnome_selector_async_handle_get (GnomeSelector *selector,
+				  GnomeSelectorAsyncType async_type,
+				  const char *uri,
+				  GnomeSelectorAsyncFunc async_func,
+				  gpointer async_data)
+{
+    GnomeSelectorAsyncHandle *async_handle;
+
+    g_return_val_if_fail (selector != NULL, NULL);
+    g_return_val_if_fail (GNOME_IS_SELECTOR (selector), NULL);
+
+    async_handle = g_new0 (GnomeSelectorAsyncHandle, 1);
+    async_handle->refcount = 1;
+    async_handle->selector = selector;
+    async_handle->async_type = async_type;
+    async_handle->async_func = async_func;
+    async_handle->user_data = async_data;
+    async_handle->uri = g_strdup (uri);
+
+    gtk_object_ref (GTK_OBJECT (async_handle->selector));
+
+    selector->_priv->async_ops = g_list_prepend (selector->_priv->async_ops,
+						 async_handle);
+
+    return async_handle;
+}
+
+void
+_gnome_selector_async_handle_add (GnomeSelectorAsyncHandle *async_handle,
+				  gpointer async_data,
+				  GDestroyNotify async_data_destroy)
+{
+    GnomeSelector *selector;
+    GnomeSelectorAsyncData *data;
+
+    g_return_if_fail (async_handle != NULL);
+    g_assert (GNOME_IS_SELECTOR (async_handle->selector));
+    g_assert (!async_handle->destroyed && !async_handle->completed);
+
+    selector = async_handle->selector;
+
+    data = g_new0 (GnomeSelectorAsyncData, 1);
+    data->async_data = async_data;
+    data->async_data_destroy = async_data_destroy;
+
+    async_handle->async_data_list = g_slist_prepend
+	(async_handle->async_data_list, data);
+}
+
+void
+_gnome_selector_async_handle_remove (GnomeSelectorAsyncHandle *async_handle,
+				     gpointer async_data)
+{
+    GSList *c;
+
+    for (c = async_handle->async_data_list; c; c = c->next) {
+	GnomeSelectorAsyncData *data = c->data;
+
+	if (data->async_data == async_data) {
+	    async_handle->async_data_list = g_slist_remove
+		(async_handle->async_data_list, data);
+
+	    if (data->async_data_destroy)
+		data->async_data_destroy (async_data);
+
+	    g_free (data);
+
+#ifdef DEBUG_ASYNC_HANDLE
+	    g_message (G_STRLOC ": %p - %d - %p", async_handle,
+		       async_handle->completed, async_handle->async_data_list);
+#endif
+
+	    if (async_handle->completed &&
+		async_handle->async_data_list == NULL)
+		_gnome_selector_async_handle_destroy (async_handle);
+
+	    return;
+	}
+    }
+
+    g_assert_not_reached ();
+}
+
+void
+_gnome_selector_async_handle_completed (GnomeSelectorAsyncHandle *async_handle,
+					gboolean success)
+{
+    GnomeSelector *selector;
+
+    g_return_if_fail (async_handle != NULL);
+    g_assert (GNOME_IS_SELECTOR (async_handle->selector));
+    g_assert (!async_handle->destroyed);
+
+    selector = async_handle->selector;
+
+#ifdef DEBUG_ASYNC_HANDLE
+    g_message (G_STRLOC ": %p - %d - %d - %p", async_handle,
+	       async_handle->completed, success,
+	       async_handle->async_data_list);
+#endif
+
+    if (!async_handle->completed)
+	async_handle->success = success;
+
+    async_handle->completed = TRUE;
+
+    if (async_handle->async_data_list == NULL)
+	_gnome_selector_async_handle_destroy (async_handle);
+}
+
+void
+_gnome_selector_async_handle_destroy (GnomeSelectorAsyncHandle *async_handle)
+{
+    GnomeSelector *selector;
+    GSList *c;
+
+    g_return_if_fail (async_handle != NULL);
+    g_assert (GNOME_IS_SELECTOR (async_handle->selector));
+
+    selector = async_handle->selector;
+
+#ifdef DEBUG_ASYNC_HANDLE
+    g_message (G_STRLOC ": %p - %d", async_handle, async_handle->refcount);
+#endif
+
+    for (c = async_handle->async_data_list; c; c = c->next) {
+	GnomeSelectorAsyncData *async_data = c->data;
+
+	if (async_data->async_data_destroy)
+	    async_data->async_data_destroy (async_data->async_data);
+    }
+
+    g_slist_foreach (async_handle->async_data_list, (GFunc) g_free, NULL);
+    g_slist_free (async_handle->async_data_list);
+    async_handle->async_data_list = NULL;
+
+    if (async_handle->async_func)
+	async_handle->async_func (selector, async_handle,
+				  async_handle->async_type, async_handle->uri,
+				  async_handle->error, async_handle->success,
+				  async_handle->user_data);
+
+    selector->_priv->async_ops = g_list_remove (selector->_priv->async_ops,
+						async_handle);
+
+    async_handle->completed = TRUE;
+    async_handle->destroyed = TRUE;
+
+    gnome_selector_async_handle_unref (async_handle);
+}
+
+void
+_gnome_selector_async_handle_set_error (GnomeSelectorAsyncHandle *async_handle, GError *error)
+{
+    g_return_if_fail (async_handle != NULL);
+    g_assert (GNOME_IS_SELECTOR (async_handle->selector));
+
+    /* Don't override. */
+    if (async_handle->error != NULL)
+	return;
+
+    async_handle->error = g_error_copy (error);
+    async_handle->success = FALSE;
+}
+
+void
+gnome_selector_async_handle_ref (GnomeSelectorAsyncHandle *async_handle)
+{
+    g_return_if_fail (async_handle != NULL);
+    g_assert (GNOME_IS_SELECTOR (async_handle->selector));
+
+    async_handle->refcount++;
+}
+
+void
+gnome_selector_async_handle_unref (GnomeSelectorAsyncHandle *async_handle)
+{
+    GnomeSelector *selector;
+
+    g_return_if_fail (async_handle != NULL);
+    g_assert (GNOME_IS_SELECTOR (async_handle->selector));
+
+    selector = async_handle->selector;
+
+    async_handle->refcount--;
+    if (async_handle->refcount <= 0) {
+	if (async_handle->error)
+	    g_error_free (async_handle->error);
+
+	gtk_object_unref (GTK_OBJECT (async_handle->selector));
+	g_assert (async_handle->destroyed);
+
+	g_free (async_handle->uri);
+	g_free (async_handle);
+    }
+}
+
+void
+gnome_selector_check_filename (GnomeSelector *selector,
+			       GnomeSelectorAsyncHandle **async_handle_return,
+			       const gchar *filename,
+			       GnomeSelectorAsyncFunc async_func,
+			       gpointer user_data)
+{
+    GnomeSelectorAsyncHandle *async_handle;
+
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+    g_return_if_fail (filename != NULL);
+    g_return_if_fail (async_func != NULL);
+
+    async_handle = _gnome_selector_async_handle_get
+	(selector, GNOME_SELECTOR_ASYNC_TYPE_CHECK_FILENAME,
+	 filename, async_func, user_data);
+    if (async_handle_return != NULL)
+	*async_handle_return = async_handle;
+
+    gtk_signal_emit (GTK_OBJECT (selector),
+		     gnome_selector_signals [CHECK_FILENAME_SIGNAL],
+		     filename, async_handle);
+}
+
+void
+gnome_selector_check_directory (GnomeSelector *selector,
+				GnomeSelectorAsyncHandle **async_handle_return,
+				const gchar *directory,
+				GnomeSelectorAsyncFunc async_func,
+				gpointer user_data)
+{
+    GnomeSelectorAsyncHandle *async_handle;
+
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+    g_return_if_fail (directory != NULL);
+    g_return_if_fail (async_func != NULL);
+
+    async_handle = _gnome_selector_async_handle_get
+	(selector, GNOME_SELECTOR_ASYNC_TYPE_CHECK_DIRECTORY,
+	 directory, async_func, user_data);
+    if (async_handle_return != NULL)
+	*async_handle_return = async_handle;
+
+    gtk_signal_emit (GTK_OBJECT (selector),
+		     gnome_selector_signals [CHECK_DIRECTORY_SIGNAL],
+		     directory, async_handle);
+
+}
+
+void
+gnome_selector_add_file (GnomeSelector *selector,
+			 GnomeSelectorAsyncHandle **async_handle_return,
+			 const gchar *filename, gint position, guint list_id,
+			 GnomeSelectorAsyncFunc async_func,
+			 gpointer user_data)
+{
+    GnomeSelectorAsyncHandle *async_handle;
+
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+    g_return_if_fail (filename != NULL);
+
+    async_handle = _gnome_selector_async_handle_get
+	(selector, GNOME_SELECTOR_ASYNC_TYPE_ADD_FILE,
+	 filename, async_func, user_data);
+    if (async_handle_return != NULL)
+	*async_handle_return = async_handle;
+
+    gtk_signal_emit (GTK_OBJECT (selector),
+		     gnome_selector_signals [ADD_FILE_SIGNAL],
+		     filename, position, list_id, async_handle);
+}
+
+void
+gnome_selector_add_directory (GnomeSelector *selector,
+			      GnomeSelectorAsyncHandle **async_handle_return,
+			      const gchar *directory, gint position,
+			      guint list_id, GnomeSelectorAsyncFunc async_func,
+			      gpointer user_data)
+{
+    GnomeSelectorAsyncHandle *async_handle;
+
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+    g_return_if_fail (directory != NULL);
+
+    async_handle = _gnome_selector_async_handle_get
+	(selector, GNOME_SELECTOR_ASYNC_TYPE_ADD_DIRECTORY,
+	 directory, async_func, user_data);
+    if (async_handle_return != NULL)
+	*async_handle_return = async_handle;
+
+    gtk_signal_emit (GTK_OBJECT (selector),
+		     gnome_selector_signals [ADD_DIRECTORY_SIGNAL],
+		     directory, position, list_id, async_handle);
+}
+
+void
+gnome_selector_add_uri (GnomeSelector *selector,
+			GnomeSelectorAsyncHandle **async_handle_return,
+			const gchar *uri, gint position, guint list_id,
+			GnomeSelectorAsyncFunc async_func,
+			gpointer user_data)
+{
+    GnomeSelectorAsyncHandle *async_handle;
+
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+    g_return_if_fail (uri != NULL);
+
+    async_handle = _gnome_selector_async_handle_get
+	(selector, GNOME_SELECTOR_ASYNC_TYPE_ADD_URI,
+	 uri, async_func, user_data);
+    if (async_handle_return != NULL)
+	*async_handle_return = async_handle;
+
+    gtk_signal_emit (GTK_OBJECT (selector),
+		     gnome_selector_signals [ADD_URI_SIGNAL],
+		     uri, position, list_id, async_handle);
+}
+
+
+void
+gnome_selector_cancel_async_operation (GnomeSelector *selector, GnomeSelectorAsyncHandle *async_handle)
+{
+    g_return_if_fail (selector != NULL);
+    g_return_if_fail (GNOME_IS_SELECTOR (selector));
+    g_return_if_fail (async_handle != NULL);
+
+    _gnome_selector_async_handle_destroy (async_handle);
+}
+
diff --git a/libgnomeui/gnome-selector.h b/libgnomeui/gnome-selector.h
new file mode 100644
index 0000000..ab03946
--- /dev/null
+++ b/libgnomeui/gnome-selector.h
@@ -0,0 +1,358 @@
+/* -*- Mode: C; c-set-style: gnu indent-tabs-mode: t; c-basic-offset: 4; tab-width: 8 -*- */
+/*
+ * Copyright (C) 2000 SuSE GmbH
+ * Author: Martin Baulig <baulig suse de>
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+/* GnomeSelector widget - pure virtual widget.
+ *
+ *   Use the Gnome{File,Icon,Pixmap}Selector subclasses.
+ *
+ * Author: Martin Baulig <baulig suse de>
+ */
+
+#ifndef GNOME_SELECTOR_H
+#define GNOME_SELECTOR_H
+
+
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkvbox.h>
+
+
+G_BEGIN_DECLS
+
+
+#define GNOME_TYPE_SELECTOR            (gnome_selector_get_type ())
+#define GNOME_SELECTOR(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_SELECTOR, GnomeSelector))
+#define GNOME_SELECTOR_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_SELECTOR, GnomeSelectorClass))
+#define GNOME_IS_SELECTOR(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_SELECTOR))
+#define GNOME_IS_SELECTOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_SELECTOR))
+#define GNOME_SELECTOR_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_SELECTOR, GnomeSelectorClass))
+
+
+typedef struct _GnomeSelector             GnomeSelector;
+typedef struct _GnomeSelectorPrivate      GnomeSelectorPrivate;
+typedef struct _GnomeSelectorClass        GnomeSelectorClass;
+
+typedef struct _GnomeSelectorAsyncHandle  GnomeSelectorAsyncHandle;
+typedef gint                              GnomeSelectorAsyncType;
+
+typedef void (*GnomeSelectorAsyncFunc)   (GnomeSelector            *selector,
+                                          GnomeSelectorAsyncHandle *async_handle,
+                                          GnomeSelectorAsyncType    async_type,
+                                          const char               *uri,
+                                          GError                   *error,
+                                          gboolean                  success,
+                                          gpointer                  user_data);
+
+enum {
+    GNOME_SELECTOR_DEFAULT_ENTRY_WIDGET    = 1 << 0,
+    GNOME_SELECTOR_DEFAULT_SELECTOR_WIDGET = 1 << 1,
+    GNOME_SELECTOR_DEFAULT_BROWSE_DIALOG   = 1 << 2,
+    GNOME_SELECTOR_WANT_BROWSE_BUTTON      = 1 << 3,
+    GNOME_SELECTOR_WANT_CLEAR_BUTTON       = 1 << 4,
+    GNOME_SELECTOR_WANT_DEFAULT_BUTTON     = 1 << 5,
+    GNOME_SELECTOR_AUTO_SAVE_HISTORY       = 1 << 16,
+    GNOME_SELECTOR_AUTO_SAVE_ALL           = 1 << 17
+};
+
+enum {
+    GNOME_SELECTOR_LIST_PRIMARY            = 0,
+    GNOME_SELECTOR_LIST_DEFAULT,
+    GNOME_SELECTOR_LIST_MAX
+};
+
+#define GNOME_SELECTOR_USER_FLAGS          (~((1 << 16)-1))
+
+struct _GnomeSelector {
+    GtkVBox vbox;
+        
+    /*< private >*/
+    GnomeSelectorPrivate *_priv;
+};
+
+struct _GnomeSelectorClass {
+    GtkVBoxClass parent_class;
+
+    void     (*changed)               (GnomeSelector            *selector);
+    void     (*browse)                (GnomeSelector            *selector);
+    void     (*clear)                 (GnomeSelector            *selector,
+                                       guint                     list_id);
+
+    void     (*freeze)                (GnomeSelector            *selector);
+    void     (*update)                (GnomeSelector            *selector);
+    void     (*thaw)                  (GnomeSelector            *selector);
+
+    gchar *  (*get_uri)               (GnomeSelector            *selector);
+    void     (*set_uri)               (GnomeSelector            *selector,
+                                       const gchar              *filename,
+                                       GnomeSelectorAsyncHandle *async_handle);
+
+    gchar *  (*get_entry_text)        (GnomeSelector            *selector);
+    void     (*set_entry_text)        (GnomeSelector            *selector,
+                                       const gchar              *text);
+    void     (*activate_entry)        (GnomeSelector            *selector);
+
+    void     (*update_uri_list)       (GnomeSelector            *selector,
+                                       guint                     list_id);
+
+    GSList * (*get_uri_list)          (GnomeSelector            *selector,
+                                       guint                     list_id);
+    void     (*add_uri_list)          (GnomeSelector            *selector,
+                                       GSList                   *list,
+                                       gint                      position,
+                                       guint                     list_id,
+                                       GnomeSelectorAsyncHandle *async_handle);
+
+    GtkSelectionMode (*get_selection_mode) (GnomeSelector       *selector);
+    void     (*set_selection_mode)    (GnomeSelector            *selector,
+                                       GtkSelectionMode          mode);
+    GSList * (*get_selection)         (GnomeSelector            *selector);
+
+    void     (*selection_changed)     (GnomeSelector            *selector);
+    void     (*history_changed)       (GnomeSelector            *selector);
+
+    /* Check whether it's ok to add the file/directory to the selector. */
+    void     (*check_filename)        (GnomeSelector            *selector,
+                                       const gchar              *filename,
+                                       GnomeSelectorAsyncHandle *async_handle);
+    void     (*check_directory)       (GnomeSelector            *selector,
+                                       const gchar              *directory,
+                                       GnomeSelectorAsyncHandle *async_handle);
+
+    /* Add a file/directory to the selector. */
+    void     (*add_file)              (GnomeSelector            *selector,
+                                       const gchar              *filename,
+                                       gint                      position,
+                                       guint                     list_id,
+                                       GnomeSelectorAsyncHandle *async_handle);
+    void     (*add_directory)         (GnomeSelector            *selector,
+                                       const gchar              *directory,
+                                       gint                      position,
+                                       guint                     list_id,
+                                       GnomeSelectorAsyncHandle *async_handle);
+
+    void     (*add_uri)               (GnomeSelector            *selector,
+                                       const gchar              *filename,
+                                       gint                      position,
+                                       guint                     list_id,
+                                       GnomeSelectorAsyncHandle *async_handle);
+
+    /* For subclasses only. */
+    void     (*do_construct)          (GnomeSelector            *selector);
+};
+
+guint
+gnome_selector_get_type           (void) G_GNUC_CONST;
+
+/* This is a purely virtual class, so there is no _new method.
+ * Use gnome_{file,icon,pixmap}_selector_new instead. */
+
+/* This is ONLY for subclasses ! */
+void
+gnome_selector_do_construct       (GnomeSelector             *selector);
+
+/* checks whether this is a valid filename/directory. */
+void
+gnome_selector_check_filename     (GnomeSelector             *selector,
+                                   GnomeSelectorAsyncHandle **async_handle_return,
+                                   const gchar               *filename,
+                                   GnomeSelectorAsyncFunc     async_func,
+                                   gpointer                   user_data);
+void
+gnome_selector_check_directory    (GnomeSelector             *selector,
+                                   GnomeSelectorAsyncHandle **async_handle_return,
+                                   const gchar               *directory,
+                                   GnomeSelectorAsyncFunc     async_func,
+                                   gpointer                   user_data);
+
+/* Add file/directory. */
+void
+gnome_selector_add_file           (GnomeSelector             *selector,
+                                   GnomeSelectorAsyncHandle **async_handle_return,
+                                   const gchar               *filename,
+                                   gint                       position,
+                                   guint                      list_id,
+                                   GnomeSelectorAsyncFunc     async_func,
+                                   gpointer                   user_data);
+
+void
+gnome_selector_add_directory      (GnomeSelector             *selector,
+                                   GnomeSelectorAsyncHandle **async_handle_return,
+                                   const gchar               *directory,
+                                   gint                       position,
+                                   guint                      list_id,
+                                   GnomeSelectorAsyncFunc     async_func,
+                                   gpointer                   user_data);
+
+void
+gnome_selector_add_uri            (GnomeSelector             *selector,
+                                   GnomeSelectorAsyncHandle **async_handle_return,
+                                   const gchar               *filename,
+                                   gint                       position,
+                                   guint                      list_id,
+                                   GnomeSelectorAsyncFunc     async_func,
+                                   gpointer                   user_data);
+
+
+/* Get/set file list (set will replace the old file list). */
+GSList *
+gnome_selector_get_uri_list       (GnomeSelector             *selector,
+                                   guint                      list_id);
+void
+gnome_selector_add_uri_list       (GnomeSelector             *selector,
+                                   GnomeSelectorAsyncHandle **async_handle_return,
+                                   GSList                    *uri_list,
+                                   gint                       position,
+                                   guint                      list_id,
+                                   GnomeSelectorAsyncFunc     async_func,
+                                   gpointer                   user_data);
+
+/* Get/set URI. */
+gchar *
+gnome_selector_get_uri            (GnomeSelector             *selector);
+
+void
+gnome_selector_set_uri            (GnomeSelector             *selector,
+                                   GnomeSelectorAsyncHandle **async_handle_return,
+                                   const gchar               *filename,
+                                   GnomeSelectorAsyncFunc     async_func,
+                                   gpointer                   user_data);
+
+/* Remove all entries from the selector. */
+void
+gnome_selector_clear              (GnomeSelector             *selector,
+                                   guint                      list_id);
+
+/* Updates the internal file list. This will also read all the directories
+ * from the directory list and add the files to an internal list. */
+void
+gnome_selector_update_uri_list    (GnomeSelector             *selector,
+                                   guint                      list_id);
+
+/* Get/set the selection mode. */
+GtkSelectionMode
+gnome_selector_get_selection_mode (GnomeSelector             *selector);
+
+void
+gnome_selector_set_selection_mode (GnomeSelector             *selector,
+                                   GtkSelectionMode           mode);
+
+/* Returns the current selection. */
+GSList *
+gnome_selector_get_selection      (GnomeSelector             *selector);
+
+/* To avoid excesive recomputes during insertion/deletion */
+void
+gnome_selector_freeze             (GnomeSelector             *selector);
+
+gboolean
+gnome_selector_is_frozen          (GnomeSelector             *selector);
+
+void
+gnome_selector_thaw               (GnomeSelector             *selector);
+
+/* Perform an update (also works in frozen state). */
+void
+gnome_selector_update             (GnomeSelector             *selector);
+
+/* Get/set the dialog title. */
+const gchar *
+gnome_selector_get_dialog_title   (GnomeSelector             *selector);
+
+void
+gnome_selector_set_dialog_title   (GnomeSelector             *selector,
+                                   const gchar               *dialog_title);
+
+/* Get/set the history id. */
+const gchar *
+gnome_selector_get_history_id     (GnomeSelector             *selector);
+
+void
+gnome_selector_set_history_id     (GnomeSelector             *selector,
+                                   const gchar               *history_id);
+
+/* Get/set the text in the entry widget. */
+gchar *
+gnome_selector_get_entry_text     (GnomeSelector             *selector);
+
+void
+gnome_selector_set_entry_text     (GnomeSelector             *selector,
+                                   const gchar               *text);
+
+/* If the entry widget is derived from GtkEditable, then we can use this
+ * function to send an "activate" signal to it. */
+void
+gnome_selector_activate_entry     (GnomeSelector             *selector);
+
+/* Get/set maximum number of history items we save. */
+guint
+gnome_selector_get_history_length (GnomeSelector             *selector);
+
+void
+gnome_selector_set_history_length (GnomeSelector             *selector,
+                                   guint                      history_length);
+
+/* Append/Prepend an item to the history. */
+void
+gnome_selector_prepend_history    (GnomeSelector             *selector,
+                                   gboolean                   save,
+                                   const gchar               *text);
+
+void
+gnome_selector_append_history     (GnomeSelector             *selector,
+                                   gboolean                   save,
+                                   const gchar               *text);
+
+/* Get/set the history. */
+GSList *
+gnome_selector_get_history        (GnomeSelector             *selector);
+
+void
+gnome_selector_set_history        (GnomeSelector             *selector,
+                                   GSList                    *history);
+
+/* Load/save/clear the history. */
+void
+gnome_selector_load_history       (GnomeSelector             *selector);
+
+void
+gnome_selector_save_history       (GnomeSelector             *selector);
+
+void
+gnome_selector_clear_history      (GnomeSelector             *selector);
+
+/* Async operations. */
+void
+gnome_selector_cancel_async_operation (GnomeSelector             *selector,
+                                       GnomeSelectorAsyncHandle  *async_handle);
+
+void
+gnome_selector_async_handle_ref   (GnomeSelectorAsyncHandle  *async_handle);
+
+void
+gnome_selector_async_handle_unref (GnomeSelectorAsyncHandle  *async_handle);
+
+G_END_DECLS
+
+#endif
diff --git a/libgnomeui/gnome-selectorP.h b/libgnomeui/gnome-selectorP.h
new file mode 100644
index 0000000..7c74b32
--- /dev/null
+++ b/libgnomeui/gnome-selectorP.h
@@ -0,0 +1,100 @@
+/* -*- Mode: C; c-set-style: gnu indent-tabs-mode: t; c-basic-offset: 4; tab-width: 8 -*- */
+/*
+ * private header file for gnome-*-selector.h.
+ *
+ * Copyright (C) 2000 SuSE GmbH
+ * Author: Martin Baulig <baulig suse de>
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#ifndef GNOME_SELECTORP_H
+#define GNOME_SELECTORP_H
+
+
+#include <gtk/gtkvbox.h>
+
+#include "gnome-selector.h"
+
+#include <gconf/gconf-client.h>
+
+G_BEGIN_DECLS
+
+enum {
+    GNOME_SELECTOR_ASYNC_TYPE_UNSPECIFIED = 0,
+    GNOME_SELECTOR_ASYNC_TYPE_CHECK_FILENAME = 1,
+    GNOME_SELECTOR_ASYNC_TYPE_CHECK_DIRECTORY,
+    GNOME_SELECTOR_ASYNC_TYPE_ADD_FILE,
+    GNOME_SELECTOR_ASYNC_TYPE_ADD_DIRECTORY,
+    GNOME_SELECTOR_ASYNC_TYPE_ADD_URI,
+    GNOME_SELECTOR_ASYNC_TYPE_ADD_URI_LIST,
+    GNOME_SELECTOR_ASYNC_TYPE_SET_URI,
+    GNOME_SELECTOR_ASYNC_TYPE_LAST
+};
+
+GnomeSelectorAsyncHandle *
+_gnome_selector_async_handle_get        (GnomeSelector            *selector,
+                                         GnomeSelectorAsyncType    async_type,
+                                         const char               *uri,
+                                         GnomeSelectorAsyncFunc    async_func,
+                                         gpointer                  user_data);
+
+void
+_gnome_selector_async_handle_add        (GnomeSelectorAsyncHandle *async_handle,
+                                         gpointer                  async_data,
+                                         GDestroyNotify            async_data_destroy);
+
+void
+_gnome_selector_async_handle_remove     (GnomeSelectorAsyncHandle *async_handle,
+                                         gpointer                  async_data);
+
+void
+_gnome_selector_async_handle_completed  (GnomeSelectorAsyncHandle *async_handle,
+                                         gboolean                  success);
+
+void
+_gnome_selector_async_handle_destroy    (GnomeSelectorAsyncHandle *async_handle);
+
+void
+_gnome_selector_async_handle_set_error  (GnomeSelectorAsyncHandle *async_handle,
+                                         GError                   *error);
+
+guint
+_gnome_selector_register_list           (GnomeSelector            *selector,
+                                         GQuark                    list_quark);
+
+void
+_gnome_selector_unregister_list         (GnomeSelector            *selector,
+                                         guint                     list_id);
+
+GSList **
+_gnome_selector_get_list_by_id          (GnomeSelector            *selector,
+                                         guint                     list_id);
+
+GSList *
+_gnome_selector_deep_copy_slist         (GSList                   *thelist);
+
+void
+_gnome_selector_deep_free_slist         (GSList                   *thelist);
+
+G_END_DECLS
+
+#endif
diff --git a/libgnomeui/gnome-stock-ids.c b/libgnomeui/gnome-stock-ids.c
new file mode 100644
index 0000000..2ccd999
--- /dev/null
+++ b/libgnomeui/gnome-stock-ids.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#include "gnome-stock-ids.h"
+
+const char gnome_stock_pixmap_new[]="New";
+const char gnome_stock_pixmap_open[]="Open";
+const char gnome_stock_pixmap_close[]="Close";
+const char gnome_stock_pixmap_revert[]="Revert";
+const char gnome_stock_pixmap_save[]="Save";
+const char gnome_stock_pixmap_save_as[]="Save As";
+const char gnome_stock_pixmap_cut[]="Cut";
+const char gnome_stock_pixmap_copy[]="Copy";
+const char gnome_stock_pixmap_paste[]="Paste";
+const char gnome_stock_pixmap_clear[]="Clear";
+const char gnome_stock_pixmap_properties[]="Properties";
+const char gnome_stock_pixmap_preferences[]="Preferences";
+const char gnome_stock_pixmap_help[]="Help";
+const char gnome_stock_pixmap_scores[]="Scores";
+const char gnome_stock_pixmap_print[]="Print";
+const char gnome_stock_pixmap_search[]="Search";
+const char gnome_stock_pixmap_srchrpl[]="Search/Replace";
+const char gnome_stock_pixmap_back[]="Back";
+const char gnome_stock_pixmap_forward[]="Forward";
+const char gnome_stock_pixmap_first[]="First";
+const char gnome_stock_pixmap_last[]="Last";
+const char gnome_stock_pixmap_home[]="Home";
+const char gnome_stock_pixmap_stop[]="Stop";
+const char gnome_stock_pixmap_refresh[]="Refresh";
+const char gnome_stock_pixmap_undo[]="Undo";
+const char gnome_stock_pixmap_redo[]="Redo";
+const char gnome_stock_pixmap_timer[]="Timer";
+const char gnome_stock_pixmap_timer_stop[]="Timer Stop";
+const char gnome_stock_pixmap_mail[]="Mail";
+const char gnome_stock_pixmap_mail_rcv[]="Receive Mail";
+const char gnome_stock_pixmap_mail_snd[]="Send Mail";
+const char gnome_stock_pixmap_mail_rpl[]="Reply to Mail";
+const char gnome_stock_pixmap_mail_fwd[]="Forward Mail";
+const char gnome_stock_pixmap_mail_new[]="New Mail";
+const char gnome_stock_pixmap_trash[]="Trash";
+const char gnome_stock_pixmap_trash_full[]="Trash Full";
+const char gnome_stock_pixmap_undelete[]="Undelete";
+const char gnome_stock_pixmap_spellcheck[]="Spellchecker";
+const char gnome_stock_pixmap_mic[]="Microphone";
+const char gnome_stock_pixmap_line_in[]="Line In";
+const char gnome_stock_pixmap_cdrom[]="Cdrom";
+const char gnome_stock_pixmap_volume[]="Volume";
+const char gnome_stock_pixmap_midi[]="Midi";
+const char gnome_stock_pixmap_book_red[]="Book Red";
+const char gnome_stock_pixmap_book_green[]="Book Green";
+const char gnome_stock_pixmap_book_blue[]="Book Blue";
+const char gnome_stock_pixmap_book_yellow[]="Book Yellow";
+const char gnome_stock_pixmap_book_open[]="Book Open";
+const char gnome_stock_pixmap_about[]="About";
+const char gnome_stock_pixmap_quit[]="Quit";
+const char gnome_stock_pixmap_multiple[]="Multiple";
+const char gnome_stock_pixmap_not[]="Not";
+const char gnome_stock_pixmap_convert[]="Convert";
+const char gnome_stock_pixmap_jump_to[]="Jump To";
+const char gnome_stock_pixmap_up[]="Up";
+const char gnome_stock_pixmap_down[]="Down";
+const char gnome_stock_pixmap_top[]="Top";
+const char gnome_stock_pixmap_bottom[]="Bottom";
+const char gnome_stock_pixmap_attach[]="Attach";
+const char gnome_stock_pixmap_index[]="Index";
+const char gnome_stock_pixmap_font[]="Font";
+const char gnome_stock_pixmap_exec[]="Exec";
+const char gnome_stock_pixmap_align_left[]="Left";
+const char gnome_stock_pixmap_align_right[]="Right";
+const char gnome_stock_pixmap_align_center[]="Center";
+const char gnome_stock_pixmap_align_justify[]="Justify";
+const char gnome_stock_pixmap_text_bold[]="Bold";
+const char gnome_stock_pixmap_text_italic[]="Italic";
+const char gnome_stock_pixmap_text_underline[]="Underline";
+const char gnome_stock_pixmap_text_strikeout[]="Strikeout";
+const char gnome_stock_pixmap_text_indent[]="Text Indent";
+const char gnome_stock_pixmap_text_unindent[]="Text Unindent";
+const char gnome_stock_pixmap_colorselector[]="Color Selector";
+const char gnome_stock_pixmap_add[]="Add";
+const char gnome_stock_pixmap_remove[]="Remove";
+const char gnome_stock_pixmap_table_borders[]="Table Borders";
+const char gnome_stock_pixmap_table_fill[]="Table Fill";
+const char gnome_stock_pixmap_text_bulleted_list[]="Text Bulleted List";
+const char gnome_stock_pixmap_text_numbered_list[]="Text Numbered List";
+const char gnome_stock_button_ok[]="Button_Ok";
+const char gnome_stock_button_cancel[]="Button_Cancel";
+const char gnome_stock_button_yes[]="Button_Yes";
+const char gnome_stock_button_no[]="Button_No";
+const char gnome_stock_button_close[]="Button_Close";
+const char gnome_stock_button_apply[]="Button_Apply";
+const char gnome_stock_button_help[]="Button_Help";
+const char gnome_stock_button_next[]="Button_Next";
+const char gnome_stock_button_prev[]="Button_Prev";
+const char gnome_stock_button_up[]="Button_Up";
+const char gnome_stock_button_down[]="Button_Down";
+const char gnome_stock_button_font[]="Button_Font";
+const char gnome_stock_menu_blank[]="Menu_";
+const char gnome_stock_menu_new[]="Menu_New";
+const char gnome_stock_menu_save[]="Menu_Save";
+const char gnome_stock_menu_save_as[]="Menu_Save As";
+const char gnome_stock_menu_revert[]="Menu_Revert";
+const char gnome_stock_menu_open[]="Menu_Open";
+const char gnome_stock_menu_close[]="Menu_Close";
+const char gnome_stock_menu_quit[]="Menu_Quit";
+const char gnome_stock_menu_cut[]="Menu_Cut";
+const char gnome_stock_menu_copy[]="Menu_Copy";
+const char gnome_stock_menu_paste[]="Menu_Paste";
+const char gnome_stock_menu_prop[]="Menu_Properties";
+const char gnome_stock_menu_pref[]="Menu_Preferences";
+const char gnome_stock_menu_about[]="Menu_About";
+const char gnome_stock_menu_scores[]="Menu_Scores";
+const char gnome_stock_menu_undo[]="Menu_Undo";
+const char gnome_stock_menu_redo[]="Menu_Redo";
+const char gnome_stock_menu_print[]="Menu_Print";
+const char gnome_stock_menu_search[]="Menu_Search";
+const char gnome_stock_menu_srchrpl[]="Menu_Search/Replace";
+const char gnome_stock_menu_back[]="Menu_Back";
+const char gnome_stock_menu_forward[]="Menu_Forward";
+const char gnome_stock_menu_first[]="Menu_First";
+const char gnome_stock_menu_last[]="Menu_Last";
+const char gnome_stock_menu_home[]="Menu_Home";
+const char gnome_stock_menu_stop[]="Menu_Stop";
+const char gnome_stock_menu_refresh[]="Menu_Refresh";
+const char gnome_stock_menu_mail[]="Menu_Mail";
+const char gnome_stock_menu_mail_rcv[]="Menu_Receive Mail";
+const char gnome_stock_menu_mail_snd[]="Menu_Send Mail";
+const char gnome_stock_menu_mail_rpl[]="Menu_Reply to Mail";
+const char gnome_stock_menu_mail_fwd[]="Menu_Forward Mail";
+const char gnome_stock_menu_mail_new[]="Menu_New Mail";
+const char gnome_stock_menu_trash[]="Menu_Trash";
+const char gnome_stock_menu_trash_full[]="Menu_Trash Full";
+const char gnome_stock_menu_undelete[]="Menu_Undelete";
+const char gnome_stock_menu_timer[]="Menu_Timer";
+const char gnome_stock_menu_timer_stop[]="Menu_Timer Stop";
+const char gnome_stock_menu_spellcheck[]="Menu_Spellchecker";
+const char gnome_stock_menu_mic[]="Menu_Microphone";
+const char gnome_stock_menu_line_in[]="Menu_Line In";
+const char gnome_stock_menu_cdrom[]="Menu_Cdrom";
+const char gnome_stock_menu_volume[]="Menu_Volume";
+const char gnome_stock_menu_midi[]="Menu_Midi";
+const char gnome_stock_menu_book_red[]="Menu_Book Red";
+const char gnome_stock_menu_book_green[]="Menu_Book Green";
+const char gnome_stock_menu_book_blue[]="Menu_Book Blue";
+const char gnome_stock_menu_book_yellow[]="Menu_Book Yellow";
+const char gnome_stock_menu_book_open[]="Menu_Book Open";
+const char gnome_stock_menu_convert[]="Menu_Convert";
+const char gnome_stock_menu_jump_to[]="Menu_Jump To";
+const char gnome_stock_menu_up[]="Menu_Up";
+const char gnome_stock_menu_down[]="Menu_Down";
+const char gnome_stock_menu_top[]="Menu_Top";
+const char gnome_stock_menu_bottom[]="Menu_Bottom";
+const char gnome_stock_menu_attach[]="Menu_Attach";
+const char gnome_stock_menu_index[]="Menu_Index";
+const char gnome_stock_menu_font[]="Menu_Font";
+const char gnome_stock_menu_exec[]="Menu_Exec";
+const char gnome_stock_menu_align_left[]="Menu_Left";
+const char gnome_stock_menu_align_right[]="Menu_Right";
+const char gnome_stock_menu_align_center[]="Menu_Center";
+const char gnome_stock_menu_align_justify[]="Menu_Justify";
+const char gnome_stock_menu_text_bold[]="Menu_Bold";
+const char gnome_stock_menu_text_italic[]="Menu_Italic";
+const char gnome_stock_menu_text_underline[]="Menu_Underline";
+const char gnome_stock_menu_text_strikeout[]="Menu_Strikeout";
diff --git a/libgnomeui/gnome-stock-ids.h b/libgnomeui/gnome-stock-ids.h
new file mode 100644
index 0000000..56665cc
--- /dev/null
+++ b/libgnomeui/gnome-stock-ids.h
@@ -0,0 +1,378 @@
+/* Stock icons, buttons, and menu items.
+   Copyright (C) 1997, 1998 Free Software Foundation
+   All rights reserved.
+
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Eckehard Berns
+*/
+/*
+  @NOTATION@
+*/
+
+#ifndef __GNOME_STOCK_IDS_H__
+#define __GNOME_STOCK_IDS_H__
+
+#include <gmacros.h>
+
+G_BEGIN_DECLS
+
+/* The names of `well known' icons. I define these strings mainly to
+   prevent errors due to typos. */
+
+extern const char gnome_stock_pixmap_new[];
+extern const char gnome_stock_pixmap_open[];
+extern const char gnome_stock_pixmap_close[];
+extern const char gnome_stock_pixmap_revert[];
+extern const char gnome_stock_pixmap_save[];
+extern const char gnome_stock_pixmap_save_as[];
+extern const char gnome_stock_pixmap_cut[];
+extern const char gnome_stock_pixmap_copy[];
+extern const char gnome_stock_pixmap_paste[];
+extern const char gnome_stock_pixmap_clear[];
+extern const char gnome_stock_pixmap_properties[];
+extern const char gnome_stock_pixmap_preferences[];
+extern const char gnome_stock_pixmap_help[];
+extern const char gnome_stock_pixmap_scores[];
+extern const char gnome_stock_pixmap_print[];
+extern const char gnome_stock_pixmap_search[];
+extern const char gnome_stock_pixmap_srchrpl[];
+extern const char gnome_stock_pixmap_back[];
+extern const char gnome_stock_pixmap_forward[];
+extern const char gnome_stock_pixmap_first[];
+extern const char gnome_stock_pixmap_last[];
+extern const char gnome_stock_pixmap_home[];
+extern const char gnome_stock_pixmap_stop[];
+extern const char gnome_stock_pixmap_refresh[];
+extern const char gnome_stock_pixmap_undo[];
+extern const char gnome_stock_pixmap_redo[];
+extern const char gnome_stock_pixmap_timer[];
+extern const char gnome_stock_pixmap_timer_stop[];
+extern const char gnome_stock_pixmap_mail[];
+extern const char gnome_stock_pixmap_mail_rcv[];
+extern const char gnome_stock_pixmap_mail_snd[];
+extern const char gnome_stock_pixmap_mail_rpl[];
+extern const char gnome_stock_pixmap_mail_fwd[];
+extern const char gnome_stock_pixmap_mail_new[];
+extern const char gnome_stock_pixmap_trash[];
+extern const char gnome_stock_pixmap_trash_full[];
+extern const char gnome_stock_pixmap_undelete[];
+extern const char gnome_stock_pixmap_spellcheck[];
+extern const char gnome_stock_pixmap_mic[];
+extern const char gnome_stock_pixmap_line_in[];
+extern const char gnome_stock_pixmap_cdrom[];
+extern const char gnome_stock_pixmap_volume[];
+extern const char gnome_stock_pixmap_midi[];
+extern const char gnome_stock_pixmap_book_red[];
+extern const char gnome_stock_pixmap_book_green[];
+extern const char gnome_stock_pixmap_book_blue[];
+extern const char gnome_stock_pixmap_book_yellow[];
+extern const char gnome_stock_pixmap_book_open[];
+extern const char gnome_stock_pixmap_about[];
+extern const char gnome_stock_pixmap_quit[];
+extern const char gnome_stock_pixmap_multiple[];
+extern const char gnome_stock_pixmap_not[];
+extern const char gnome_stock_pixmap_convert[];
+extern const char gnome_stock_pixmap_jump_to[];
+extern const char gnome_stock_pixmap_up[];
+extern const char gnome_stock_pixmap_down[];
+extern const char gnome_stock_pixmap_top[];
+extern const char gnome_stock_pixmap_bottom[];
+extern const char gnome_stock_pixmap_attach[];
+extern const char gnome_stock_pixmap_index[];
+extern const char gnome_stock_pixmap_font[];
+extern const char gnome_stock_pixmap_exec[];
+extern const char gnome_stock_pixmap_align_left[];
+extern const char gnome_stock_pixmap_align_right[];
+extern const char gnome_stock_pixmap_align_center[];
+extern const char gnome_stock_pixmap_align_justify[];
+extern const char gnome_stock_pixmap_text_bold[];
+extern const char gnome_stock_pixmap_text_italic[];
+extern const char gnome_stock_pixmap_text_underline[];
+extern const char gnome_stock_pixmap_text_strikeout[];
+extern const char gnome_stock_pixmap_text_indent[];
+extern const char gnome_stock_pixmap_text_unindent[];
+extern const char gnome_stock_pixmap_colorselector[];
+extern const char gnome_stock_pixmap_add[];
+extern const char gnome_stock_pixmap_remove[];
+extern const char gnome_stock_pixmap_table_borders[];
+extern const char gnome_stock_pixmap_table_fill[];
+extern const char gnome_stock_pixmap_text_bulleted_list[];
+extern const char gnome_stock_pixmap_text_numbered_list[];
+
+#define GNOME_STOCK_PIXMAP_NEW gnome_stock_pixmap_new
+#define GNOME_STOCK_PIXMAP_OPEN gnome_stock_pixmap_open
+#define GNOME_STOCK_PIXMAP_CLOSE gnome_stock_pixmap_close
+#define GNOME_STOCK_PIXMAP_REVERT gnome_stock_pixmap_revert
+#define GNOME_STOCK_PIXMAP_SAVE gnome_stock_pixmap_save
+#define GNOME_STOCK_PIXMAP_SAVE_AS gnome_stock_pixmap_save_as
+#define GNOME_STOCK_PIXMAP_CUT gnome_stock_pixmap_cut
+#define GNOME_STOCK_PIXMAP_COPY gnome_stock_pixmap_copy
+#define GNOME_STOCK_PIXMAP_PASTE gnome_stock_pixmap_paste
+#define GNOME_STOCK_PIXMAP_CLEAR gnome_stock_pixmap_clear
+#define GNOME_STOCK_PIXMAP_PROPERTIES gnome_stock_pixmap_properties
+#define GNOME_STOCK_PIXMAP_PREFERENCES gnome_stock_pixmap_preferences
+#define GNOME_STOCK_PIXMAP_HELP gnome_stock_pixmap_help
+#define GNOME_STOCK_PIXMAP_SCORES gnome_stock_pixmap_scores
+#define GNOME_STOCK_PIXMAP_PRINT gnome_stock_pixmap_print
+#define GNOME_STOCK_PIXMAP_SEARCH gnome_stock_pixmap_search
+#define GNOME_STOCK_PIXMAP_SRCHRPL gnome_stock_pixmap_srchrpl
+#define GNOME_STOCK_PIXMAP_BACK gnome_stock_pixmap_back
+#define GNOME_STOCK_PIXMAP_FORWARD gnome_stock_pixmap_forward
+#define GNOME_STOCK_PIXMAP_FIRST gnome_stock_pixmap_first
+#define GNOME_STOCK_PIXMAP_LAST gnome_stock_pixmap_last
+#define GNOME_STOCK_PIXMAP_HOME gnome_stock_pixmap_home
+#define GNOME_STOCK_PIXMAP_STOP gnome_stock_pixmap_stop
+#define GNOME_STOCK_PIXMAP_REFRESH gnome_stock_pixmap_refresh
+#define GNOME_STOCK_PIXMAP_UNDO gnome_stock_pixmap_undo
+#define GNOME_STOCK_PIXMAP_REDO gnome_stock_pixmap_redo
+#define GNOME_STOCK_PIXMAP_TIMER gnome_stock_pixmap_timer
+#define GNOME_STOCK_PIXMAP_TIMER_STOP gnome_stock_pixmap_timer_stop
+#define GNOME_STOCK_PIXMAP_MAIL gnome_stock_pixmap_mail
+#define GNOME_STOCK_PIXMAP_MAIL_RCV gnome_stock_pixmap_mail_rcv
+#define GNOME_STOCK_PIXMAP_MAIL_SND gnome_stock_pixmap_mail_snd
+#define GNOME_STOCK_PIXMAP_MAIL_RPL gnome_stock_pixmap_mail_rpl
+#define GNOME_STOCK_PIXMAP_MAIL_FWD gnome_stock_pixmap_mail_fwd
+#define GNOME_STOCK_PIXMAP_MAIL_NEW gnome_stock_pixmap_mail_new
+#define GNOME_STOCK_PIXMAP_TRASH gnome_stock_pixmap_trash
+#define GNOME_STOCK_PIXMAP_TRASH_FULL gnome_stock_pixmap_trash_full
+#define GNOME_STOCK_PIXMAP_UNDELETE gnome_stock_pixmap_undelete
+#define GNOME_STOCK_PIXMAP_SPELLCHECK gnome_stock_pixmap_spellcheck
+#define GNOME_STOCK_PIXMAP_MIC gnome_stock_pixmap_mic
+#define GNOME_STOCK_PIXMAP_LINE_IN gnome_stock_pixmap_line_in
+#define GNOME_STOCK_PIXMAP_CDROM gnome_stock_pixmap_cdrom
+#define GNOME_STOCK_PIXMAP_VOLUME gnome_stock_pixmap_volume
+#define GNOME_STOCK_PIXMAP_MIDI gnome_stock_pixmap_midi
+#define GNOME_STOCK_PIXMAP_BOOK_RED gnome_stock_pixmap_book_red
+#define GNOME_STOCK_PIXMAP_BOOK_GREEN gnome_stock_pixmap_book_green
+#define GNOME_STOCK_PIXMAP_BOOK_BLUE gnome_stock_pixmap_book_blue
+#define GNOME_STOCK_PIXMAP_BOOK_YELLOW gnome_stock_pixmap_book_yellow
+#define GNOME_STOCK_PIXMAP_BOOK_OPEN gnome_stock_pixmap_book_open
+#define GNOME_STOCK_PIXMAP_ABOUT gnome_stock_pixmap_about
+#define GNOME_STOCK_PIXMAP_QUIT gnome_stock_pixmap_quit
+#define GNOME_STOCK_PIXMAP_MULTIPLE gnome_stock_pixmap_multiple
+#define GNOME_STOCK_PIXMAP_NOT gnome_stock_pixmap_not
+#define GNOME_STOCK_PIXMAP_CONVERT gnome_stock_pixmap_convert
+#define GNOME_STOCK_PIXMAP_JUMP_TO gnome_stock_pixmap_jump_to
+#define GNOME_STOCK_PIXMAP_UP gnome_stock_pixmap_up
+#define GNOME_STOCK_PIXMAP_DOWN gnome_stock_pixmap_down
+#define GNOME_STOCK_PIXMAP_TOP gnome_stock_pixmap_top
+#define GNOME_STOCK_PIXMAP_BOTTOM gnome_stock_pixmap_bottom
+#define GNOME_STOCK_PIXMAP_ATTACH gnome_stock_pixmap_attach
+#define GNOME_STOCK_PIXMAP_INDEX gnome_stock_pixmap_index
+#define GNOME_STOCK_PIXMAP_FONT gnome_stock_pixmap_font
+#define GNOME_STOCK_PIXMAP_EXEC gnome_stock_pixmap_exec
+
+#define GNOME_STOCK_PIXMAP_ALIGN_LEFT gnome_stock_pixmap_align_left
+#define GNOME_STOCK_PIXMAP_ALIGN_RIGHT gnome_stock_pixmap_align_right
+#define GNOME_STOCK_PIXMAP_ALIGN_CENTER gnome_stock_pixmap_align_center
+#define GNOME_STOCK_PIXMAP_ALIGN_JUSTIFY gnome_stock_pixmap_align_justify
+
+#define GNOME_STOCK_PIXMAP_TEXT_BOLD gnome_stock_pixmap_text_bold
+#define GNOME_STOCK_PIXMAP_TEXT_ITALIC gnome_stock_pixmap_text_italic
+#define GNOME_STOCK_PIXMAP_TEXT_UNDERLINE gnome_stock_pixmap_text_underline
+#define GNOME_STOCK_PIXMAP_TEXT_STRIKEOUT gnome_stock_pixmap_text_strikeout
+#define GNOME_STOCK_PIXMAP_TEXT_INDENT gnome_stock_pixmap_text_indent
+#define GNOME_STOCK_PIXMAP_TEXT_UNINDENT gnome_stock_pixmap_text_unindent
+#define GNOME_STOCK_PIXMAP_COLORSELECTOR gnome_stock_pixmap_colorselector
+
+#define GNOME_STOCK_PIXMAP_ADD gnome_stock_pixmap_add
+#define GNOME_STOCK_PIXMAP_REMOVE gnome_stock_pixmap_remove
+
+#define GNOME_STOCK_PIXMAP_TABLE_BORDERS gnome_stock_pixmap_table_borders
+#define GNOME_STOCK_PIXMAP_TABLE_FILL gnome_stock_pixmap_table_fill
+
+#define GNOME_STOCK_PIXMAP_TEXT_BULLETED_LIST gnome_stock_pixmap_text_bulleted_list
+#define GNOME_STOCK_PIXMAP_TEXT_NUMBERED_LIST gnome_stock_pixmap_text_numbered_list
+
+#define GNOME_STOCK_PIXMAP_EXIT        GNOME_STOCK_PIXMAP_QUIT
+
+/*
+ * Buttons
+ */
+
+extern const char gnome_stock_button_ok[];
+extern const char gnome_stock_button_cancel[];
+extern const char gnome_stock_button_yes[];
+extern const char gnome_stock_button_no[];
+extern const char gnome_stock_button_close[];
+extern const char gnome_stock_button_apply[];
+extern const char gnome_stock_button_help[];
+extern const char gnome_stock_button_next[];
+extern const char gnome_stock_button_prev[];
+extern const char gnome_stock_button_up[];
+extern const char gnome_stock_button_down[];
+extern const char gnome_stock_button_font[];
+#define GNOME_STOCK_BUTTON_OK gnome_stock_button_ok
+#define GNOME_STOCK_BUTTON_CANCEL gnome_stock_button_cancel
+#define GNOME_STOCK_BUTTON_YES gnome_stock_button_yes
+#define GNOME_STOCK_BUTTON_NO gnome_stock_button_no
+#define GNOME_STOCK_BUTTON_CLOSE gnome_stock_button_close
+#define GNOME_STOCK_BUTTON_APPLY gnome_stock_button_apply
+#define GNOME_STOCK_BUTTON_HELP gnome_stock_button_help
+#define GNOME_STOCK_BUTTON_NEXT gnome_stock_button_next
+#define GNOME_STOCK_BUTTON_PREV gnome_stock_button_prev
+#define GNOME_STOCK_BUTTON_UP gnome_stock_button_up
+#define GNOME_STOCK_BUTTON_DOWN gnome_stock_button_down
+#define GNOME_STOCK_BUTTON_FONT gnome_stock_button_font
+
+/*
+ * Menus
+ */
+
+extern const char gnome_stock_menu_blank[];
+extern const char gnome_stock_menu_new[];
+extern const char gnome_stock_menu_save[];
+extern const char gnome_stock_menu_save_as[];
+extern const char gnome_stock_menu_revert[];
+extern const char gnome_stock_menu_open[];
+extern const char gnome_stock_menu_close[];
+extern const char gnome_stock_menu_quit[];
+extern const char gnome_stock_menu_cut[];
+extern const char gnome_stock_menu_copy[];
+extern const char gnome_stock_menu_paste[];
+extern const char gnome_stock_menu_prop[];
+extern const char gnome_stock_menu_pref[];
+extern const char gnome_stock_menu_about[];
+extern const char gnome_stock_menu_scores[];
+extern const char gnome_stock_menu_undo[];
+extern const char gnome_stock_menu_redo[];
+extern const char gnome_stock_menu_print[];
+extern const char gnome_stock_menu_search[];
+extern const char gnome_stock_menu_srchrpl[];
+extern const char gnome_stock_menu_back[];
+extern const char gnome_stock_menu_forward[];
+extern const char gnome_stock_menu_first[];
+extern const char gnome_stock_menu_last[];
+extern const char gnome_stock_menu_home[];
+extern const char gnome_stock_menu_stop[];
+extern const char gnome_stock_menu_refresh[];
+extern const char gnome_stock_menu_mail[];
+extern const char gnome_stock_menu_mail_rcv[];
+extern const char gnome_stock_menu_mail_snd[];
+extern const char gnome_stock_menu_mail_rpl[];
+extern const char gnome_stock_menu_mail_fwd[];
+extern const char gnome_stock_menu_mail_new[];
+extern const char gnome_stock_menu_trash[];
+extern const char gnome_stock_menu_trash_full[];
+extern const char gnome_stock_menu_undelete[];
+extern const char gnome_stock_menu_timer[];
+extern const char gnome_stock_menu_timer_stop[];
+extern const char gnome_stock_menu_spellcheck[];
+extern const char gnome_stock_menu_mic[];
+extern const char gnome_stock_menu_line_in[];
+extern const char gnome_stock_menu_cdrom[];
+extern const char gnome_stock_menu_volume[];
+extern const char gnome_stock_menu_midi[];
+extern const char gnome_stock_menu_book_red[];
+extern const char gnome_stock_menu_book_green[];
+extern const char gnome_stock_menu_book_blue[];
+extern const char gnome_stock_menu_book_yellow[];
+extern const char gnome_stock_menu_book_open[];
+extern const char gnome_stock_menu_convert[];
+extern const char gnome_stock_menu_jump_to[];
+extern const char gnome_stock_menu_up[];
+extern const char gnome_stock_menu_down[];
+extern const char gnome_stock_menu_top[];
+extern const char gnome_stock_menu_bottom[];
+extern const char gnome_stock_menu_attach[];
+extern const char gnome_stock_menu_index[];
+extern const char gnome_stock_menu_font[];
+extern const char gnome_stock_menu_exec[];
+extern const char gnome_stock_menu_align_left[];
+extern const char gnome_stock_menu_align_right[];
+extern const char gnome_stock_menu_align_center[];
+extern const char gnome_stock_menu_align_justify[];
+extern const char gnome_stock_menu_text_bold[];
+extern const char gnome_stock_menu_text_italic[];
+extern const char gnome_stock_menu_text_underline[];
+extern const char gnome_stock_menu_text_strikeout[];
+#define GNOME_STOCK_MENU_BLANK gnome_stock_menu_blank
+#define GNOME_STOCK_MENU_NEW gnome_stock_menu_new
+#define GNOME_STOCK_MENU_SAVE gnome_stock_menu_save
+#define GNOME_STOCK_MENU_SAVE_AS gnome_stock_menu_save_as
+#define GNOME_STOCK_MENU_REVERT gnome_stock_menu_revert
+#define GNOME_STOCK_MENU_OPEN gnome_stock_menu_open
+#define GNOME_STOCK_MENU_CLOSE gnome_stock_menu_close
+#define GNOME_STOCK_MENU_QUIT gnome_stock_menu_quit
+#define GNOME_STOCK_MENU_CUT gnome_stock_menu_cut
+#define GNOME_STOCK_MENU_COPY gnome_stock_menu_copy
+#define GNOME_STOCK_MENU_PASTE gnome_stock_menu_paste
+#define GNOME_STOCK_MENU_PROP gnome_stock_menu_prop
+#define GNOME_STOCK_MENU_PREF gnome_stock_menu_pref
+#define GNOME_STOCK_MENU_ABOUT gnome_stock_menu_about
+#define GNOME_STOCK_MENU_SCORES gnome_stock_menu_scores
+#define GNOME_STOCK_MENU_UNDO gnome_stock_menu_undo
+#define GNOME_STOCK_MENU_REDO gnome_stock_menu_redo
+#define GNOME_STOCK_MENU_PRINT gnome_stock_menu_print
+#define GNOME_STOCK_MENU_SEARCH gnome_stock_menu_search
+#define GNOME_STOCK_MENU_SRCHRPL gnome_stock_menu_srchrpl
+#define GNOME_STOCK_MENU_BACK gnome_stock_menu_back
+#define GNOME_STOCK_MENU_FORWARD gnome_stock_menu_forward
+#define GNOME_STOCK_MENU_FIRST gnome_stock_menu_first
+#define GNOME_STOCK_MENU_LAST gnome_stock_menu_last
+#define GNOME_STOCK_MENU_HOME gnome_stock_menu_home
+#define GNOME_STOCK_MENU_STOP gnome_stock_menu_stop
+#define GNOME_STOCK_MENU_REFRESH gnome_stock_menu_refresh
+#define GNOME_STOCK_MENU_MAIL gnome_stock_menu_mail
+#define GNOME_STOCK_MENU_MAIL_RCV gnome_stock_menu_mail_rcv
+#define GNOME_STOCK_MENU_MAIL_SND gnome_stock_menu_mail_snd
+#define GNOME_STOCK_MENU_MAIL_RPL gnome_stock_menu_mail_rpl
+#define GNOME_STOCK_MENU_MAIL_FWD gnome_stock_menu_mail_fwd
+#define GNOME_STOCK_MENU_MAIL_NEW gnome_stock_menu_mail_new
+#define GNOME_STOCK_MENU_TRASH gnome_stock_menu_trash
+#define GNOME_STOCK_MENU_TRASH_FULL gnome_stock_menu_trash_full
+#define GNOME_STOCK_MENU_UNDELETE gnome_stock_menu_undelete
+#define GNOME_STOCK_MENU_TIMER gnome_stock_menu_timer
+#define GNOME_STOCK_MENU_TIMER_STOP gnome_stock_menu_timer_stop
+#define GNOME_STOCK_MENU_SPELLCHECK gnome_stock_menu_spellcheck
+#define GNOME_STOCK_MENU_MIC gnome_stock_menu_mic
+#define GNOME_STOCK_MENU_LINE_IN gnome_stock_menu_line_in
+#define GNOME_STOCK_MENU_CDROM gnome_stock_menu_cdrom
+#define GNOME_STOCK_MENU_VOLUME gnome_stock_menu_volume
+#define GNOME_STOCK_MENU_MIDI gnome_stock_menu_midi
+#define GNOME_STOCK_MENU_BOOK_RED gnome_stock_menu_book_red
+#define GNOME_STOCK_MENU_BOOK_GREEN gnome_stock_menu_book_green
+#define GNOME_STOCK_MENU_BOOK_BLUE gnome_stock_menu_book_blue
+#define GNOME_STOCK_MENU_BOOK_YELLOW gnome_stock_menu_book_yellow
+#define GNOME_STOCK_MENU_BOOK_OPEN gnome_stock_menu_book_open
+#define GNOME_STOCK_MENU_CONVERT gnome_stock_menu_convert
+#define GNOME_STOCK_MENU_JUMP_TO gnome_stock_menu_jump_to
+#define GNOME_STOCK_MENU_UP gnome_stock_menu_up
+#define GNOME_STOCK_MENU_DOWN gnome_stock_menu_down
+#define GNOME_STOCK_MENU_TOP gnome_stock_menu_top
+#define GNOME_STOCK_MENU_BOTTOM gnome_stock_menu_bottom
+#define GNOME_STOCK_MENU_ATTACH gnome_stock_menu_attach
+#define GNOME_STOCK_MENU_INDEX gnome_stock_menu_index
+#define GNOME_STOCK_MENU_FONT gnome_stock_menu_font
+#define GNOME_STOCK_MENU_EXEC gnome_stock_menu_exec
+
+#define GNOME_STOCK_MENU_ALIGN_LEFT gnome_stock_menu_align_left
+#define GNOME_STOCK_MENU_ALIGN_RIGHT gnome_stock_menu_align_right
+#define GNOME_STOCK_MENU_ALIGN_CENTER gnome_stock_menu_align_center
+#define GNOME_STOCK_MENU_ALIGN_JUSTIFY gnome_stock_menu_align_justify
+
+#define GNOME_STOCK_MENU_TEXT_BOLD gnome_stock_menu_text_bold
+#define GNOME_STOCK_MENU_TEXT_ITALIC gnome_stock_menu_text_italic
+#define GNOME_STOCK_MENU_TEXT_UNDERLINE gnome_stock_menu_text_underline
+#define GNOME_STOCK_MENU_TEXT_STRIKEOUT gnome_stock_menu_text_strikeout
+
+#define GNOME_STOCK_MENU_EXIT     GNOME_STOCK_MENU_QUIT
+
+
+G_END_DECLS
+
+#endif /* GNOME_STOCK_H */
diff --git a/libgnomeui/gnome-stock.c b/libgnomeui/gnome-stock.c
new file mode 100644
index 0000000..499a4a3
--- /dev/null
+++ b/libgnomeui/gnome-stock.c
@@ -0,0 +1,1518 @@
+/*  -*- Mode: C; c-set-style: linux; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/* Stock icons, buttons, and menu items.
+   Copyright (C) 1997, 1998 Free Software Foundation
+
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Eckehard Berns  */
+
+#include <config.h>
+
+#include <libgnome/gnome-util.h>
+#include <libgnome/gnome-i18n.h>
+#include <libgnome/gnome-config.h>
+#include "gnome-stock.h"
+#include "gnome-pixmap.h"
+#include "gnome-uidefs.h"
+#include "gnome-preferences.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+
+#include "pixmaps/gnome-stock-pixbufs.h"
+
+#define STOCK_SEP '.'
+#define STOCK_SEP_STR "."
+
+#define GNOME_STOCK_BUTTON_PADDING 2
+
+static GnomeStockPixmapEntry **lookup(const char *icon);
+
+static GdkPixbuf *gnome_stock_pixmap_entry_get_gdk_pixbuf(GnomeStockPixmapEntry *entry);
+
+/***************************/
+/*  new GnomeStock widget  */
+/***************************/
+
+static GnomePixmapClass* parent_class = NULL;
+
+static void
+gnome_stock_destroy(GtkObject *object)
+{
+	GnomeStock *stock;
+
+	/* remember, destroy can be run multiple times! */
+
+	g_return_if_fail(object != NULL);
+	g_return_if_fail(GNOME_IS_STOCK(object));
+
+	stock = GNOME_STOCK(object);
+
+        (* GTK_OBJECT_CLASS(parent_class)->destroy)(object);
+}
+
+
+
+static void
+gnome_stock_class_init(GtkObjectClass * klass)
+{
+  	GtkObjectClass *object_class;
+	GtkWidgetClass *widget_class;
+
+	object_class = (GtkObjectClass *) klass;
+	widget_class = (GtkWidgetClass *) klass;
+
+	parent_class = gtk_type_class (gnome_pixmap_get_type ());
+  
+	klass->destroy = gnome_stock_destroy;
+}
+
+static void
+gnome_stock_init(GnomeStock *stock)
+{
+	stock->icon = NULL;
+	gnome_pixmap_set_draw_mode (GNOME_PIXMAP (stock), GNOME_PIXMAP_COLOR);
+}
+
+/**
+ * gnome_stock_get_type:
+ *
+ * Returns: The GtkType for the #GnomeStock widget.
+ */
+guint
+gnome_stock_get_type(void)
+{
+	static guint new_type = 0;
+	if (!new_type) {
+		GtkTypeInfo type_info = {
+			"GnomeStock",
+			sizeof(GnomeStock),
+			sizeof(GnomeStockClass),
+			(GtkClassInitFunc)gnome_stock_class_init,
+			(GtkObjectInitFunc)gnome_stock_init,
+			NULL,
+			NULL,
+			NULL
+		};
+		new_type = gtk_type_unique(gnome_pixmap_get_type(), &type_info);
+	}
+	return new_type;
+}
+
+/** 
+ * gnome_stock_new:
+ *
+ * Returns: a new empty GnomeStock widget
+ */
+GtkWidget *
+gnome_stock_new(void)
+{
+        GnomeStock *stock;
+	stock = gtk_type_new(gnome_stock_get_type());
+
+        return GTK_WIDGET(stock);
+}
+
+/**
+ * gnome_stock_set_icon:
+ * @stock: The GnomeStock object on which to operate
+ * @icon: Icon code to set
+ *
+ * Sets the @stock object icon to be the one whose code is @icon.
+ */
+gboolean
+gnome_stock_set_icon(GnomeStock *stock, const char *icon)
+{
+	GnomeStockPixmapEntry **entries;
+        GdkPixbuf *pixbufs[5] = { NULL, NULL, NULL, NULL, NULL };
+        GdkBitmap *bitmasks[5] = { NULL, NULL, NULL, NULL, NULL };
+        int i;
+        
+	g_return_val_if_fail(stock != NULL, FALSE);
+	g_return_val_if_fail(GNOME_IS_STOCK(stock), FALSE);
+	g_return_val_if_fail(icon != NULL, FALSE);
+
+	if (stock->icon) {
+		if (0 == strcmp(icon, stock->icon))
+			return FALSE;
+		g_free(stock->icon);
+                stock->icon = NULL;
+	}
+        
+	entries = lookup(icon);
+        
+        if (entries == NULL) {
+                g_warning("No such stock icon `%s'", icon);
+                return FALSE;
+        }
+        
+	stock->icon = g_strdup(icon);
+
+        i = 0;
+        while (i < 5) {
+          if (entries[i] != NULL)
+            pixbufs[i] = gnome_stock_pixmap_entry_get_gdk_pixbuf(entries[i]);
+          else
+            pixbufs[i] = NULL;
+
+          bitmasks[i] = NULL;
+          
+          ++i;
+        }
+
+        i = 0;
+        while (i < 5) {
+          if (pixbufs[i] != NULL &&
+              gdk_pixbuf_get_has_alpha(pixbufs[i])) {
+                  bitmasks[i] = gdk_pixmap_new(NULL,
+                                               gdk_pixbuf_get_width(pixbufs[i]),
+                                               gdk_pixbuf_get_height(pixbufs[i]),
+                                               1);
+
+                  gdk_pixbuf_render_threshold_alpha(pixbufs[i], bitmasks[i],
+                                                    0, 0, 0, 0,
+                                                    gdk_pixbuf_get_width(pixbufs[i]),
+                                                    gdk_pixbuf_get_height(pixbufs[i]),
+                                                    128); /* clip at 50% alpha */
+          }
+          ++i;
+        }
+
+        /* Note that we may be building a new insensitive image for each widget,
+           while we could share the insensitive versions in our hash table.
+           It's an open question which is the right thing...
+        */
+        gnome_pixmap_set_state_pixbufs (GNOME_PIXMAP(stock),
+                                        pixbufs,
+                                        bitmasks);
+
+        /* Set the main pixbuf from the normal version, in
+           case pixbufs[] contains NULL for some images */
+        if (pixbufs[GTK_STATE_NORMAL] != NULL)
+                gnome_pixmap_set_pixbuf(GNOME_PIXMAP(stock),
+                                        pixbufs[GTK_STATE_NORMAL]);
+	return TRUE;
+}
+
+/**
+ * gnome_stock_new_with_icon:
+ * @icon: icon code.
+ *
+ * Returns: A GnomeStock widget created with the initial icon code
+ * set to @icon. The icon must exist.
+ */ 
+GtkWidget *
+gnome_stock_new_with_icon(const char *icon)
+{
+	GtkWidget *w;
+
+	g_return_val_if_fail(icon != NULL, NULL);
+	w = gtk_type_new(gnome_stock_get_type());
+
+	gnome_stock_set_icon(GNOME_STOCK(w), icon);
+
+	return w;
+}
+
+
+/*
+ * Hash entry for the stock icon hash
+ */
+
+
+/* Structures for the internal stock image hash table entries */
+
+/* for even easier debugging */ 
+#define GNOME_IS_STOCK_PIXMAP_ENTRY(entry) \
+        (entry->type >= 0 && entry->type < GNOME_STOCK_PIXMAP_TYPE_LAST)
+
+static GnomeStockPixmapEntry*
+gnome_stock_pixmap_entry_new_blank (GnomeStockPixmapType type, const gchar* label)
+{
+        GnomeStockPixmapEntry* entry = NULL;
+
+        switch (type) {
+        case GNOME_STOCK_PIXMAP_TYPE_DATA:
+                entry = (GnomeStockPixmapEntry*) g_new0(GnomeStockPixmapEntryData, 1);
+                break;
+        case GNOME_STOCK_PIXMAP_TYPE_FILE:
+                entry = (GnomeStockPixmapEntry*) g_new0(GnomeStockPixmapEntryFile, 1);
+                break;
+                
+        case GNOME_STOCK_PIXMAP_TYPE_PATH:
+                entry = (GnomeStockPixmapEntry*) g_new0(GnomeStockPixmapEntryPath, 1);
+                break;
+                
+        case GNOME_STOCK_PIXMAP_TYPE_PIXBUF:
+                entry = (GnomeStockPixmapEntry*) g_new0(GnomeStockPixmapEntryPixbuf, 1);
+                break;
+
+        case GNOME_STOCK_PIXMAP_TYPE_PIXBUF_SCALED:
+                entry = (GnomeStockPixmapEntry*) g_new0(GnomeStockPixmapEntryPixbufScaled, 1);
+                break;
+
+        default:
+                g_assert_not_reached();
+                break;
+        }
+        
+        g_assert(entry != NULL);
+
+        entry->type = type;
+	entry->any.ref_count = 1;
+        
+        if (label != NULL)
+                entry->any.label = g_strdup(label);
+
+        return entry;
+}
+
+static void
+gnome_stock_pixmap_entry_destroy (GnomeStockPixmapEntry* entry)
+{
+        switch (entry->type) {
+        case GNOME_STOCK_PIXMAP_TYPE_DATA:
+                /* nothing to free */
+                break;
+
+        case GNOME_STOCK_PIXMAP_TYPE_FILE:
+                if (entry->file.filename != NULL) 
+                        g_free(entry->file.filename);
+                break;
+                
+        case GNOME_STOCK_PIXMAP_TYPE_PATH:
+                if (entry->path.pathname != NULL)
+                        g_free(entry->path.pathname);
+                break;
+                
+        case GNOME_STOCK_PIXMAP_TYPE_PIXBUF:
+                break;
+                
+        case GNOME_STOCK_PIXMAP_TYPE_PIXBUF_SCALED:
+                if (entry->scaled.unscaled_pixbuf != NULL)
+                        gdk_pixbuf_unref(entry->scaled.unscaled_pixbuf);
+                break;
+
+        default:
+                g_assert_not_reached();
+                break;
+        }
+
+        if (entry->any.pixbuf != NULL)
+                gdk_pixbuf_unref(entry->any.pixbuf);
+        
+        if (entry->any.label != NULL)
+                g_free(entry->any.label);
+
+	/* just in case we double free, then GNOME_IS_STOCK_PIXMAP_ENTRY
+	 * will fail */
+	entry->type = -1;
+
+        g_free(entry);
+}
+
+/**
+ * gnome_stock_pixmap_entry_ref:
+ * @entry: gnome stock pixmap entry
+ *
+ * Description:  Increments the reference count on the entry
+ */
+static void
+gnome_stock_pixmap_entry_ref (GnomeStockPixmapEntry* entry)
+{
+	g_return_if_fail (entry != NULL);
+	g_return_if_fail (GNOME_IS_STOCK_PIXMAP_ENTRY(entry));
+
+	entry->any.ref_count++;
+}
+
+/**
+ * gnome_stock_pixmap_entry_unref:
+ * @entry: gnome stock pixmap entry
+ *
+ * Description:  Decrements the reference count on the entry, and
+ * destroys the structure if it went to 0
+ */
+static void
+gnome_stock_pixmap_entry_unref (GnomeStockPixmapEntry* entry)
+{
+	g_return_if_fail (entry != NULL);
+	g_return_if_fail (GNOME_IS_STOCK_PIXMAP_ENTRY(entry));
+
+	entry->any.ref_count--;
+	if(entry->any.ref_count == 0)
+		gnome_stock_pixmap_entry_destroy(entry);
+}
+
+static GnomeStockPixmapEntry*
+gnome_stock_pixmap_entry_new_from_gdk_pixbuf_at_size (GdkPixbuf *pixbuf,
+                                                      const gchar* label,
+                                                      gint width, gint height)
+{
+        GnomeStockPixmapEntry* entry;
+
+        entry = gnome_stock_pixmap_entry_new_blank (GNOME_STOCK_PIXMAP_TYPE_PIXBUF_SCALED,
+                                                    label);
+
+        gdk_pixbuf_ref(pixbuf);
+
+        ((GnomeStockPixmapEntryPixbufScaled*)entry)->unscaled_pixbuf = pixbuf;
+        ((GnomeStockPixmapEntryPixbufScaled*)entry)->scaled_width = width;
+        ((GnomeStockPixmapEntryPixbufScaled*)entry)->scaled_height = height;
+
+        return entry;
+}
+
+
+/**
+ * gnome_stock_pixmap_entry_get_gdk_pixbuf:
+ * @entry: the #GnomeStockPixmapEntry
+ *
+ * Description: Returns the #GdkPixbuf that is used for drawing
+ * this stock entry.  The returned pixbuf is the internal data with
+ * it's reference count incremented, so do gdk_pixbuf_unref when you
+ * are done with it and treat it as read only data.
+ *
+ * Returns: a #GdkPixbuf with an incremented reference count.
+ **/
+static GdkPixbuf*
+gnome_stock_pixmap_entry_get_gdk_pixbuf (GnomeStockPixmapEntry *entry)
+{
+	g_return_val_if_fail (entry != NULL, NULL);
+	g_return_val_if_fail (GNOME_IS_STOCK_PIXMAP_ENTRY(entry), NULL);
+
+        if (entry->any.pixbuf != NULL) {
+                /* Return the cached pixbuf, with refcount incremented. */
+                gdk_pixbuf_ref(entry->any.pixbuf);
+                return entry->any.pixbuf;
+        }
+
+        switch (entry->type) {
+        case GNOME_STOCK_PIXMAP_TYPE_DATA:
+                entry->any.pixbuf = gdk_pixbuf_new_from_xpm_data(entry->data.xpm_data);
+                break;
+                
+        case GNOME_STOCK_PIXMAP_TYPE_FILE: {
+                gchar* pathname;
+
+                g_assert(entry->file.filename != NULL);
+
+                pathname = gnome_program_locate_file (gnome_program_get (),
+                                                      GNOME_FILE_DOMAIN_PIXMAP,
+                                                      entry->file.filename,
+                                                      TRUE, NULL);
+                entry->any.pixbuf = gdk_pixbuf_new_from_file(pathname, NULL);
+                g_free(pathname);
+                /* drop some memory */
+                if (entry->any.pixbuf != NULL) {
+                        g_free(entry->file.filename);
+                        entry->file.filename = NULL;
+                }
+        }
+                break;
+                
+        case GNOME_STOCK_PIXMAP_TYPE_PATH:
+                g_assert(entry->path.pathname != NULL);
+                
+                entry->any.pixbuf = gdk_pixbuf_new_from_file(entry->path.pathname, NULL);
+                /* drop some memory */
+                if (entry->any.pixbuf != NULL) {
+                        g_free(entry->path.pathname);
+                        entry->path.pathname = NULL;
+                }
+                break;
+                
+        case GNOME_STOCK_PIXMAP_TYPE_PIXBUF:
+                /* no work to do here */
+                break;
+
+        case GNOME_STOCK_PIXMAP_TYPE_PIXBUF_SCALED:
+                if (entry->scaled.unscaled_pixbuf != NULL) {
+                        g_assert(entry->any.pixbuf == NULL);
+
+                        entry->any.pixbuf = gdk_pixbuf_scale_simple(entry->scaled.unscaled_pixbuf,
+                                                                    entry->scaled.scaled_width,
+                                                                    entry->scaled.scaled_height,
+                                                                    GDK_INTERP_BILINEAR);
+                }
+                if (entry->any.pixbuf != NULL &&
+                    entry->scaled.unscaled_pixbuf != NULL) {
+                        gdk_pixbuf_unref(entry->scaled.unscaled_pixbuf);
+                        entry->scaled.unscaled_pixbuf = NULL;
+                }
+                break;
+
+        default:
+                g_assert_not_reached();
+                break;
+
+        }
+
+        if (entry->any.pixbuf != NULL) {
+                /* Return the cached pixbuf, with refcount incremented. */
+                gdk_pixbuf_ref(entry->any.pixbuf);
+                return entry->any.pixbuf;
+        } else {
+                return NULL;
+        }
+}
+
+/*
+ * Builtin stock icons 
+ */
+
+struct _default_entries_data {
+	const char *icon;
+        GtkStateType state;
+	const char *label;
+	const gchar *inline_pixbuf;
+	int scaled_width, scaled_height;
+};
+
+#define TB_W 20
+#define TB_H 20
+#define TIGERT_W 24
+#define TIGERT_H 24
+#define MENU_W 16
+#define MENU_H 16
+
+static const struct _default_entries_data entries_data[] = {
+	{GNOME_STOCK_PIXMAP_NEW, GTK_STATE_NORMAL, NULL, stock_new, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_SAVE, GTK_STATE_NORMAL, NULL, stock_save, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_SAVE_AS, GTK_STATE_NORMAL, NULL, stock_save_as, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_REVERT, GTK_STATE_NORMAL, NULL, stock_revert, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_CUT, GTK_STATE_NORMAL, NULL, stock_cut, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_HELP, GTK_STATE_NORMAL, NULL, stock_help, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_PRINT, GTK_STATE_NORMAL, NULL, stock_print, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_SEARCH, GTK_STATE_NORMAL, NULL, stock_search, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_SRCHRPL, GTK_STATE_NORMAL, NULL, stock_search_replace, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_BACK, GTK_STATE_NORMAL, NULL, stock_left_arrow, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_FORWARD, GTK_STATE_NORMAL, NULL, stock_right_arrow, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_FIRST, GTK_STATE_NORMAL, NULL, stock_first, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_LAST, GTK_STATE_NORMAL, NULL, stock_last, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_HOME, GTK_STATE_NORMAL, NULL, stock_home, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_STOP, GTK_STATE_NORMAL, NULL, stock_stop, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_REFRESH, GTK_STATE_NORMAL, NULL, stock_refresh, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_UNDELETE, GTK_STATE_NORMAL, NULL, stock_undelete, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_OPEN, GTK_STATE_NORMAL, NULL, stock_open, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_CLOSE, GTK_STATE_NORMAL, NULL, stock_close, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_COPY, GTK_STATE_NORMAL, NULL, stock_copy, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_PASTE, GTK_STATE_NORMAL, NULL, stock_paste, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_PROPERTIES, GTK_STATE_NORMAL, NULL, stock_properties, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_PREFERENCES, GTK_STATE_NORMAL, NULL, stock_preferences, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_SCORES, GTK_STATE_NORMAL, NULL, stock_scores, TB_W, TB_H},
+	{GNOME_STOCK_PIXMAP_UNDO, GTK_STATE_NORMAL, NULL, stock_undo, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_REDO, GTK_STATE_NORMAL, NULL, stock_redo, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_TIMER, GTK_STATE_NORMAL, NULL, stock_timer, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_TIMER_STOP, GTK_STATE_NORMAL, NULL, stock_timer_stopped, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_MAIL, GTK_STATE_NORMAL, NULL, stock_mail, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_MAIL_RCV, GTK_STATE_NORMAL, NULL, stock_mail_receive, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_MAIL_SND, GTK_STATE_NORMAL, NULL, stock_mail_send, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_MAIL_RPL, GTK_STATE_NORMAL, NULL, stock_mail_reply, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_MAIL_FWD, GTK_STATE_NORMAL, NULL, stock_mail_forward, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_MAIL_NEW, GTK_STATE_NORMAL, NULL, stock_mail_compose, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_TRASH, GTK_STATE_NORMAL, NULL, stock_trash, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_TRASH_FULL, GTK_STATE_NORMAL, NULL, stock_trash_full, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_SPELLCHECK, GTK_STATE_NORMAL, NULL, stock_spellcheck, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_MIC, GTK_STATE_NORMAL, NULL, stock_mic, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_VOLUME, GTK_STATE_NORMAL, NULL, stock_volume, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_MIDI, GTK_STATE_NORMAL, NULL, stock_midi, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_LINE_IN, GTK_STATE_NORMAL, NULL, stock_line_in, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_CDROM, GTK_STATE_NORMAL, NULL, stock_cdrom, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_BOOK_RED, GTK_STATE_NORMAL, NULL, stock_book_red, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_BOOK_GREEN, GTK_STATE_NORMAL, NULL, stock_book_green, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_BOOK_BLUE, GTK_STATE_NORMAL, NULL, stock_book_blue, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_BOOK_YELLOW, GTK_STATE_NORMAL, NULL, stock_book_yellow, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_BOOK_OPEN, GTK_STATE_NORMAL, NULL, stock_book_open, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_NOT, GTK_STATE_NORMAL, NULL, stock_not, TB_W, TB_H},
+	{GNOME_STOCK_PIXMAP_CONVERT, GTK_STATE_NORMAL, NULL, stock_convert, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_JUMP_TO, GTK_STATE_NORMAL, NULL, stock_jump_to, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_MULTIPLE, GTK_STATE_NORMAL, NULL, stock_multiple_file, 32, 32},
+	{GNOME_STOCK_PIXMAP_EXIT, GTK_STATE_NORMAL, NULL, stock_exit, TB_W, TB_H},
+	{GNOME_STOCK_PIXMAP_ABOUT, GTK_STATE_NORMAL, NULL, stock_menu_about, MENU_W, MENU_H},
+	{GNOME_STOCK_PIXMAP_UP, GTK_STATE_NORMAL, NULL, stock_up_arrow, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_DOWN, GTK_STATE_NORMAL, NULL, stock_down_arrow, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_TOP, GTK_STATE_NORMAL, NULL, stock_top, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_BOTTOM, GTK_STATE_NORMAL, NULL, stock_bottom, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_ATTACH, GTK_STATE_NORMAL, NULL, stock_attach, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_FONT, GTK_STATE_NORMAL, NULL, stock_font, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_INDEX, GTK_STATE_NORMAL, NULL, stock_index, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_EXEC, GTK_STATE_NORMAL, NULL, stock_exec, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_ALIGN_LEFT, GTK_STATE_NORMAL, NULL, stock_align_left, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_ALIGN_RIGHT, GTK_STATE_NORMAL, NULL, stock_align_right, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_ALIGN_CENTER, GTK_STATE_NORMAL, NULL, stock_align_center, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_ALIGN_JUSTIFY, GTK_STATE_NORMAL, NULL, stock_align_justify, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_TEXT_BOLD, GTK_STATE_NORMAL, NULL, stock_text_bold, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_TEXT_ITALIC, GTK_STATE_NORMAL, NULL, stock_text_italic, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_TEXT_UNDERLINE, GTK_STATE_NORMAL, NULL, stock_text_underline, TIGERT_W, TIGERT_H},
+	{GNOME_STOCK_PIXMAP_TEXT_STRIKEOUT, GTK_STATE_NORMAL, NULL, stock_text_strikeout, TIGERT_W, TIGERT_H},
+
+	{GNOME_STOCK_PIXMAP_ADD, GTK_STATE_NORMAL, N_("Add"), stock_add, TB_W, TB_H},
+	{GNOME_STOCK_PIXMAP_CLEAR, GTK_STATE_NORMAL, N_("Clear"), stock_clear, TB_W, TB_H},
+	{GNOME_STOCK_PIXMAP_COLORSELECTOR, GTK_STATE_NORMAL, N_("Select Color"), stock_colorselector, TB_W, TB_H},
+	{GNOME_STOCK_PIXMAP_REMOVE, GTK_STATE_NORMAL, N_("Remove"), stock_remove, TB_W, TB_H},
+	{GNOME_STOCK_PIXMAP_TABLE_BORDERS, GTK_STATE_NORMAL, N_("Table Borders"), stock_table_borders, TB_W, TB_H},
+	{GNOME_STOCK_PIXMAP_TABLE_FILL, GTK_STATE_NORMAL, N_("Table Fill"), stock_table_fill, TB_W, TB_H},
+	{GNOME_STOCK_PIXMAP_TEXT_BULLETED_LIST, GTK_STATE_NORMAL, N_("Bulleted List"), stock_text_bulleted_list, TB_W, TB_H},
+	{GNOME_STOCK_PIXMAP_TEXT_NUMBERED_LIST, GTK_STATE_NORMAL, N_("Numbered List"), stock_text_numbered_list, TB_W, TB_H},
+	{GNOME_STOCK_PIXMAP_TEXT_INDENT, GTK_STATE_NORMAL, N_("Indent"), stock_text_indent, TB_W, TB_H},
+	{GNOME_STOCK_PIXMAP_TEXT_UNINDENT, GTK_STATE_NORMAL, N_("Un-Indent"), stock_text_unindent, TB_W, TB_H},
+
+
+	{GNOME_STOCK_BUTTON_OK, GTK_STATE_NORMAL, N_("OK"), stock_button_ok, TB_W, TB_H},
+	{GNOME_STOCK_BUTTON_APPLY, GTK_STATE_NORMAL, N_("Apply"), stock_button_apply, TB_W, TB_H},
+	{GNOME_STOCK_BUTTON_CANCEL, GTK_STATE_NORMAL, N_("Cancel"), stock_button_cancel, TB_W, TB_H},
+	{GNOME_STOCK_BUTTON_CLOSE, GTK_STATE_NORMAL, N_("Close"), stock_button_close, TB_W, TB_H},
+	{GNOME_STOCK_BUTTON_YES, GTK_STATE_NORMAL, N_("Yes"), stock_button_yes, TB_W, TB_H},
+	{GNOME_STOCK_BUTTON_NO, GTK_STATE_NORMAL, N_("No"), stock_button_no, TB_W, TB_H},
+	{GNOME_STOCK_BUTTON_HELP, GTK_STATE_NORMAL, N_("Help"), stock_help, TB_W, TB_H},
+	{GNOME_STOCK_BUTTON_NEXT, GTK_STATE_NORMAL, N_("Next"), stock_right_arrow, TB_W, TB_H},
+	{GNOME_STOCK_BUTTON_PREV, GTK_STATE_NORMAL, N_("Prev"), stock_left_arrow, TB_W, TB_H},
+	{GNOME_STOCK_BUTTON_UP, GTK_STATE_NORMAL, N_("Up"), stock_up_arrow, TB_W, TB_H},
+	{GNOME_STOCK_BUTTON_DOWN, GTK_STATE_NORMAL, N_("Down"), stock_down_arrow, TB_W, TB_H},
+	{GNOME_STOCK_BUTTON_FONT, GTK_STATE_NORMAL, N_("Font"), stock_font, TB_W, TB_H},
+	{GNOME_STOCK_MENU_NEW, GTK_STATE_NORMAL, NULL, stock_new, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_SAVE, GTK_STATE_NORMAL, NULL, stock_save, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_SAVE_AS, GTK_STATE_NORMAL, NULL, stock_save_as, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_REVERT, GTK_STATE_NORMAL, NULL, stock_revert, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_OPEN, GTK_STATE_NORMAL, NULL, stock_open, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_CLOSE, GTK_STATE_NORMAL, NULL, stock_close, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_QUIT, GTK_STATE_NORMAL, NULL, stock_exit, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_CUT, GTK_STATE_NORMAL, NULL, stock_cut, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_COPY, GTK_STATE_NORMAL, NULL, stock_copy, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_PASTE, GTK_STATE_NORMAL, NULL, stock_paste, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_PROP, GTK_STATE_NORMAL, NULL, stock_properties, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_PREF, GTK_STATE_NORMAL, NULL, stock_preferences, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_UNDO, GTK_STATE_NORMAL, NULL, stock_undo, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_REDO, GTK_STATE_NORMAL, NULL, stock_redo, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_PRINT, GTK_STATE_NORMAL, NULL, stock_print, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_SEARCH, GTK_STATE_NORMAL, NULL, stock_search, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_SRCHRPL, GTK_STATE_NORMAL, NULL, stock_search_replace, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_BACK, GTK_STATE_NORMAL, NULL, stock_left_arrow, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_FORWARD, GTK_STATE_NORMAL, NULL, stock_right_arrow, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_FIRST, GTK_STATE_NORMAL, NULL, stock_first, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_LAST, GTK_STATE_NORMAL, NULL, stock_last, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_HOME, GTK_STATE_NORMAL, NULL, stock_home, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_STOP, GTK_STATE_NORMAL, NULL, stock_stop, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_REFRESH, GTK_STATE_NORMAL, NULL, stock_refresh, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_UNDELETE, GTK_STATE_NORMAL, NULL, stock_undelete, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_TIMER, GTK_STATE_NORMAL, NULL, stock_timer, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_TIMER_STOP, GTK_STATE_NORMAL, NULL, stock_timer_stopped, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_MAIL, GTK_STATE_NORMAL, NULL, stock_mail, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_MAIL_RCV, GTK_STATE_NORMAL, NULL, stock_mail_receive, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_MAIL_SND, GTK_STATE_NORMAL, NULL, stock_mail_send, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_MAIL_RPL, GTK_STATE_NORMAL, NULL, stock_mail_reply, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_MAIL_FWD, GTK_STATE_NORMAL, NULL, stock_mail_forward, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_MAIL_NEW, GTK_STATE_NORMAL, NULL, stock_mail_compose, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_TRASH, GTK_STATE_NORMAL, NULL, stock_trash, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_TRASH_FULL, GTK_STATE_NORMAL, NULL, stock_trash_full, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_SPELLCHECK, GTK_STATE_NORMAL, NULL, stock_spellcheck, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_MIC, GTK_STATE_NORMAL, NULL, stock_mic, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_LINE_IN, GTK_STATE_NORMAL, NULL, stock_line_in, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_VOLUME, GTK_STATE_NORMAL, NULL, stock_volume, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_MIDI, GTK_STATE_NORMAL, NULL, stock_midi, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_CDROM, GTK_STATE_NORMAL, NULL, stock_cdrom, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_BOOK_RED, GTK_STATE_NORMAL, NULL, stock_book_red, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_BOOK_GREEN, GTK_STATE_NORMAL, NULL, stock_book_green, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_BOOK_BLUE, GTK_STATE_NORMAL, NULL, stock_book_blue, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_BOOK_YELLOW, GTK_STATE_NORMAL, NULL, stock_book_yellow, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_BOOK_OPEN, GTK_STATE_NORMAL, NULL, stock_book_open, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_CONVERT, GTK_STATE_NORMAL, NULL, stock_convert, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_JUMP_TO, GTK_STATE_NORMAL, NULL, stock_jump_to, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_ABOUT, GTK_STATE_NORMAL, NULL, stock_menu_about, MENU_W, MENU_H},
+	/* TODO: I shouldn't waste a pixmap for that */
+	{GNOME_STOCK_MENU_BLANK, GTK_STATE_NORMAL, NULL, stock_menu_blank, MENU_W, MENU_H}, 
+	{GNOME_STOCK_MENU_SCORES, GTK_STATE_NORMAL, NULL, stock_menu_scores, 20, 20},
+	{GNOME_STOCK_MENU_UP, GTK_STATE_NORMAL, NULL, stock_up_arrow, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_DOWN, GTK_STATE_NORMAL, NULL, stock_down_arrow, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_TOP, GTK_STATE_NORMAL, NULL, stock_top, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_BOTTOM, GTK_STATE_NORMAL, NULL, stock_bottom, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_ATTACH, GTK_STATE_NORMAL, NULL, stock_attach, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_INDEX, GTK_STATE_NORMAL, NULL, stock_index, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_FONT, GTK_STATE_NORMAL, NULL, stock_font, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_EXEC, GTK_STATE_NORMAL, NULL, stock_exec, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_ALIGN_LEFT, GTK_STATE_NORMAL, NULL, stock_align_left, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_ALIGN_RIGHT, GTK_STATE_NORMAL, NULL, stock_align_right, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_ALIGN_CENTER, GTK_STATE_NORMAL, NULL, stock_align_center, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_ALIGN_JUSTIFY, GTK_STATE_NORMAL, NULL, stock_align_justify, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_TEXT_BOLD, GTK_STATE_NORMAL, NULL, stock_text_bold, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_TEXT_ITALIC, GTK_STATE_NORMAL, NULL, stock_text_italic, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_TEXT_UNDERLINE, GTK_STATE_NORMAL, NULL, stock_text_underline, MENU_W, MENU_H},
+	{GNOME_STOCK_MENU_TEXT_STRIKEOUT, GTK_STATE_NORMAL, NULL, stock_text_strikeout, MENU_W, MENU_H},
+
+};
+
+static const int entries_data_num = sizeof(entries_data) / sizeof(entries_data[0]);
+
+
+typedef struct _HashEntry HashEntry;
+
+struct _HashEntry {
+        /* indexed by state type */
+        GnomeStockPixmapEntry *entries[5];
+};
+
+static HashEntry*
+hash_entry_new (void)
+{
+        HashEntry* he;
+
+        he = g_new0 (HashEntry, 1);
+
+        return he;
+}
+
+static void
+hash_entry_set (HashEntry *he, GtkStateType state, GnomeStockPixmapEntry *entry)
+{
+        g_return_if_fail (state < 5);
+        
+        if (he->entries[state] != NULL) {
+                gnome_stock_pixmap_entry_unref (he->entries[state]);
+                he->entries[state] = NULL;
+        }
+
+	gnome_stock_pixmap_entry_ref (entry);
+        he->entries[state] = entry;
+}
+
+static void
+hash_insert (GHashTable *hash, const gchar* icon, GtkStateType state,
+             GnomeStockPixmapEntry *entry)
+{
+        gpointer key = NULL;
+        gpointer value = NULL;
+        
+        if (g_hash_table_lookup_extended (hash, icon, &key, &value)) {
+                HashEntry *he;
+                
+                he = value;
+
+                g_assert (he != NULL);
+
+                hash_entry_set (he, state, entry);
+
+                return;
+        } else {
+                HashEntry *he;
+
+                he = hash_entry_new ();
+
+                hash_entry_set (he, state, entry);
+
+                g_hash_table_insert (hash,
+                                     g_strdup(icon),
+                                     he);
+
+                return;
+        }
+}
+
+static GHashTable *
+stock_pixmaps(void)
+{
+	static GHashTable *hash = NULL;
+	int i;
+
+	if (hash != NULL)
+                return hash;
+
+	hash = g_hash_table_new(g_str_hash, g_str_equal);
+
+	for (i = 0; i < entries_data_num; i++) {
+                GdkPixbuf *pixbuf;
+                GnomeStockPixmapEntry *entry;
+
+                pixbuf = gdk_pixbuf_new_from_inline (entries_data[i].inline_pixbuf,
+                                                     FALSE, -1, NULL);
+                
+                
+                entry = gnome_stock_pixmap_entry_new_from_gdk_pixbuf_at_size (pixbuf,
+                                                                              entries_data[i].label,
+                                                                              entries_data[i].scaled_width,
+                                                                              entries_data[i].scaled_height);
+                
+
+                /* entry holds a ref */
+                gdk_pixbuf_unref (pixbuf);
+
+                hash_insert (hash, entries_data[i].icon, entries_data[i].state, entry);
+		/* the above code has have reffed it in our database, so
+		 * we need to get rid of the initial refcount */
+		gnome_stock_pixmap_entry_unref(entry);
+	}
+        
+	return hash;
+}
+
+
+static GnomeStockPixmapEntry **
+lookup(const char *icon)
+{
+	GHashTable *hash = stock_pixmaps();
+        HashEntry* he;
+
+        he = g_hash_table_lookup(hash, icon);
+
+        if (he == NULL)
+                return NULL;
+        else
+                return he->entries;
+}
+
+gint
+gnome_stock_pixmap_register(const char *icon, GtkStateType state,
+			    GnomeStockPixmapEntry *entry)
+{
+        GHashTable* hash;
+        
+	g_return_val_if_fail (icon != NULL, 0);
+	g_return_val_if_fail (entry != NULL, 0);
+	g_return_val_if_fail (GNOME_IS_STOCK_PIXMAP_ENTRY(entry), 0);
+
+        hash = stock_pixmaps();
+        
+        g_return_val_if_fail(g_hash_table_lookup(hash, icon) == NULL, 0);
+        
+        hash_insert (hash, icon, state, entry);
+
+        return 1;
+}
+
+gint
+gnome_stock_pixmap_change(const char *icon, GtkStateType state,
+			  GnomeStockPixmapEntry *entry)
+{
+	GHashTable *hash;
+        HashEntry *he;
+
+	g_return_val_if_fail (icon != NULL, 0);
+	g_return_val_if_fail (entry != NULL, 0);
+	g_return_val_if_fail (GNOME_IS_STOCK_PIXMAP_ENTRY(entry), 0);
+        
+	hash = stock_pixmaps();
+
+        he = g_hash_table_lookup(hash, icon);
+
+        if (he == NULL) {
+                gnome_stock_pixmap_register(icon, state, entry);
+        } else {
+                hash_entry_set(he, state, entry);
+        }
+
+        return 1;
+}
+
+
+
+GnomeStockPixmapEntry *
+gnome_stock_pixmap_checkfor (const char *icon, GtkStateType state)
+{
+	GHashTable *hash;
+        HashEntry *he;
+
+	g_return_val_if_fail(icon != NULL, NULL);
+        
+	hash = stock_pixmaps();
+
+        he = g_hash_table_lookup(hash, icon);
+
+        if (he == NULL) {
+                return NULL;
+        } else {
+                gnome_stock_pixmap_entry_ref(he->entries[state]);
+                return he->entries[state];
+        }
+}
+
+/*******************/
+/*  stock buttons  */
+/*******************/
+
+GtkWidget *
+gnome_pixmap_button(GtkWidget *pixmap, const char *text)
+{
+	GtkWidget *button, *label, *hbox, *w;
+	gboolean use_icon, use_label;
+
+	g_return_val_if_fail(text != NULL, NULL);
+
+	button = gtk_button_new();
+	hbox = gtk_hbox_new(FALSE, 0);
+	gtk_widget_show(hbox);
+	gtk_container_add(GTK_CONTAINER(button), hbox);
+	w = hbox;
+	hbox = gtk_hbox_new(FALSE, 0);
+	gtk_widget_show(hbox);
+	gtk_box_pack_start(GTK_BOX(w), hbox, TRUE, FALSE,
+                           GNOME_STOCK_BUTTON_PADDING);
+
+	use_icon = gnome_config_get_bool("/Gnome/Icons/ButtonUseIcons=true");
+	use_label = gnome_config_get_bool("/Gnome/Icons/ButtonUseLabels=true");
+
+	if ((use_label) || (!use_icon) || (!pixmap)) {
+		label = gtk_label_new(_(text));
+		gtk_widget_show(label);
+		gtk_box_pack_end(GTK_BOX(hbox), label, FALSE, FALSE,
+                                 GNOME_STOCK_BUTTON_PADDING);
+	}
+
+	if ((use_icon) && (pixmap)) {
+
+		gtk_widget_show(pixmap);
+		gtk_box_pack_start(GTK_BOX(hbox), pixmap,
+				   FALSE, FALSE, 0);
+	} else {
+                gtk_widget_unref(pixmap);
+        }
+
+	return button;
+}
+
+static GtkWidget *
+stock_button_from_entries (const char *type, GnomeStockPixmapEntry **entries)
+{
+	char *text;
+	GtkWidget *pixmap;
+
+        /* FIXME we should actually change the label on state changes,
+           or else not store a label for every state. */
+	if (entries[GTK_STATE_NORMAL]->any.label)
+		text = dgettext(PACKAGE, entries[GTK_STATE_NORMAL]->any.label);
+	else
+		text = dgettext(PACKAGE, type);
+
+	pixmap = gnome_stock_new_with_icon(type);
+	return gnome_pixmap_button(pixmap, text);
+}
+
+/**
+ * gnome_stock_button:
+ * @type: gnome stock type code.
+ *
+ * Constructs a new #GtkButton which contains a stock icon and text
+ * whose type is @type.
+ *
+ * Returns: A configured #GtkButton widget
+ */
+GtkWidget *
+gnome_stock_button(const char *type)
+{
+	GnomeStockPixmapEntry **entries;
+
+	entries = lookup(type);
+
+        g_return_val_if_fail(entries != NULL, NULL);
+
+	return stock_button_from_entries (type, entries);
+}
+
+/**
+ * gnome_stock_or_ordinary_button:
+ * @type: gnome stock type code.
+ *
+ * It @type contains a valid GNOME stock code, it constructs a new
+ * #GtkButton which contains a stock icon and text for the matching
+ * type, or if the type does not exist, it creates a button with the
+ * label being the same as "type".
+ *
+ * The use of this routine is discouraged, given that on international 
+ * setups it might break subtly.
+ *
+ * Returns: A #GtkButton.
+ */
+GtkWidget *
+gnome_stock_or_ordinary_button (const char *type)
+{
+        GnomeStockPixmapEntry **entries;
+
+	entries = lookup(type);
+        
+        if (entries == NULL)
+                return gtk_button_new_with_label (type);
+        else
+                return stock_button_from_entries (type, entries);
+}
+
+
+/***********/
+/*  menus  */
+/***********/
+
+GtkWidget *
+gnome_stock_menu_item(const char *type, const char *text)
+{
+	GtkWidget *hbox, *w, *menu_item;
+
+	g_return_val_if_fail(type != NULL, NULL);
+	g_return_val_if_fail(text != NULL, NULL);
+
+ 	if(gnome_preferences_get_menus_have_icons()) {
+		hbox = gtk_hbox_new(FALSE, 2);
+		gtk_widget_show(hbox);
+		w = gnome_stock_new_with_icon(type);
+		gtk_widget_show(w);
+		gtk_box_pack_start(GTK_BOX(hbox), w, FALSE, FALSE, 0);
+
+		menu_item = gtk_menu_item_new();
+
+		w = gtk_accel_label_new (text);
+		gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (w), menu_item);
+		gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.5);
+		gtk_widget_show(w);
+		gtk_box_pack_start(GTK_BOX(hbox), w, TRUE, TRUE, 0);
+
+		gtk_container_add(GTK_CONTAINER(menu_item), hbox);
+	} else {
+		menu_item = gtk_menu_item_new_with_label(text);
+	}
+
+	return menu_item;
+}
+
+
+/***********************/
+/*  menu accelerators  */
+/***********************/
+
+typedef struct _AccelEntry AccelEntry;
+struct _AccelEntry {
+	guchar key;
+	guint8 mod;
+};
+
+struct default_AccelEntry {
+	const char *type;
+	AccelEntry entry;
+};
+
+static const struct default_AccelEntry default_accel_hash[] = {
+	{GNOME_STOCK_MENU_NEW, {'N', GDK_CONTROL_MASK}},
+	{GNOME_STOCK_MENU_OPEN, {'O', GDK_CONTROL_MASK}},
+	{GNOME_STOCK_MENU_CLOSE, {'W', GDK_CONTROL_MASK}},
+	{GNOME_STOCK_MENU_SAVE, {'S', GDK_CONTROL_MASK}},
+	{GNOME_STOCK_MENU_SAVE_AS, {'S', GDK_SHIFT_MASK | GDK_CONTROL_MASK}},
+	{GNOME_STOCK_MENU_QUIT, {'Q', GDK_CONTROL_MASK}},
+	{GNOME_STOCK_MENU_CUT, {'X', GDK_CONTROL_MASK}},
+	{GNOME_STOCK_MENU_COPY, {'C', GDK_CONTROL_MASK}},
+	{GNOME_STOCK_MENU_PASTE, {'V', GDK_CONTROL_MASK}},
+	{GNOME_STOCK_MENU_PROP, {0, 0}},
+	{GNOME_STOCK_MENU_PREF, {'E', GDK_CONTROL_MASK}},
+	{GNOME_STOCK_MENU_ABOUT, {'A', GDK_MOD1_MASK}},
+	{GNOME_STOCK_MENU_SCORES, {0, 0}},
+	{GNOME_STOCK_MENU_UNDO, {'Z', GDK_CONTROL_MASK}},
+	{GNOME_STOCK_MENU_PRINT, {'P', GDK_CONTROL_MASK}},
+	{GNOME_STOCK_MENU_SEARCH, {'S', GDK_MOD1_MASK}},
+	{GNOME_STOCK_MENU_BACK, {'B', GDK_CONTROL_MASK}},
+	{GNOME_STOCK_MENU_FORWARD, {'F', GDK_CONTROL_MASK}},
+	{GNOME_STOCK_MENU_UP, {'U', GDK_CONTROL_MASK}},
+	{GNOME_STOCK_MENU_DOWN, {'D', GDK_CONTROL_MASK}},
+	{GNOME_STOCK_MENU_MAIL, {0, 0}},
+	{GNOME_STOCK_MENU_MAIL_RCV, {0, 0}},
+	{GNOME_STOCK_MENU_MAIL_SND, {0, 0}},
+	{NULL, {0,0}}
+};
+
+
+static char *
+accel_to_string(const AccelEntry *entry)
+{
+	static char s[30];
+
+	s[0] = 0;
+	if (!entry->key) return NULL;
+	if (entry->mod & GDK_CONTROL_MASK)
+		strcat(s, "Ctl+");
+	if (entry->mod & GDK_MOD1_MASK)
+		strcat(s, "Alt+");
+	if (entry->mod & GDK_SHIFT_MASK)
+		strcat(s, "Shft+");
+	if (entry->mod & GDK_MOD2_MASK)
+		strcat(s, "Mod2+");
+	if (entry->mod & GDK_MOD3_MASK)
+		strcat(s, "Mod3+");
+	if (entry->mod & GDK_MOD4_MASK)
+		strcat(s, "Mod4+");
+	if (entry->mod & GDK_MOD5_MASK)
+		strcat(s, "Mod5+");
+	if ((entry->key >= 'a') && (entry->key <= 'z')) {
+		s[strlen(s) + 1] = 0;
+		s[strlen(s)] = entry->key - 'a' + 'A';
+	} else if ((entry->key >= 'A') && (entry->key <= 'Z')) {
+		s[strlen(s) + 1] = 0;
+		s[strlen(s)] = entry->key;
+	} else {
+		return NULL;
+	}
+	return s;
+}
+
+
+static void
+accel_from_string(char *s, guchar *key, guint8 *mod)
+{
+	char *p, *p1;
+
+	*mod = 0;
+	*key = 0;
+	if (!s) return;
+	p = s;
+	do {
+		p1 = p;
+		while ((*p) && (*p != '+')) p++;
+		if (*p == '+') {
+			*p = 0;
+			if (0 == g_strcasecmp(p1, "Ctl"))
+				*mod |= GDK_CONTROL_MASK;
+			else if (0 == g_strcasecmp(p1, "Alt"))
+				*mod |= GDK_MOD1_MASK;
+			else if (0 == g_strcasecmp(p1, "Shft"))
+				*mod |= GDK_SHIFT_MASK;
+			else if (0 == g_strcasecmp(p1, "Mod2"))
+				*mod |= GDK_MOD2_MASK;
+			else if (0 == g_strcasecmp(p1, "Mod3"))
+				*mod |= GDK_MOD3_MASK;
+			else if (0 == g_strcasecmp(p1, "Mod4"))
+				*mod |= GDK_MOD4_MASK;
+			else if (0 == g_strcasecmp(p1, "Mod5"))
+				*mod |= GDK_MOD5_MASK;
+			*p = '+';
+			p++;
+		}
+	} while (*p);
+	if (p1[1] == 0) {
+		*key = *p1;
+	} else {
+		*key = 0;
+		*mod = 0;
+		return;
+	}
+}
+
+
+static void
+accel_read_rc(gpointer key, gpointer value, gpointer data)
+{
+	char *path, *s;
+	AccelEntry *entry = value;
+	gboolean got_default;
+
+	path = g_strconcat(data, key, "=", accel_to_string(value), NULL);
+	s = gnome_config_get_string_with_default(path, &got_default);
+	g_free(path);
+	if (got_default) {
+		g_free(s);
+		return;
+	}
+	accel_from_string(s, &entry->key, &entry->mod);
+	g_free(s);
+}
+
+
+static GHashTable *
+accel_hash(void) {
+	static GHashTable *hash = NULL;
+	const struct default_AccelEntry *p;
+
+	if (!hash) {
+		hash = g_hash_table_new(g_str_hash, g_str_equal);
+		for (p = default_accel_hash; p->type; p++)
+			g_hash_table_insert(hash, (gpointer) p->type, (gpointer) &p->entry);
+		g_hash_table_foreach(hash, accel_read_rc,
+				     "/Gnome/Accelerators/");
+	}
+	return hash;
+}
+
+gboolean
+gnome_stock_menu_accel(const char *type, guchar *key, guint8 *mod)
+{
+	AccelEntry *entry;
+
+	entry = g_hash_table_lookup(accel_hash(), (char *)type);
+	if (!entry) {
+		*key = 0;
+		*mod = 0;
+		return FALSE;
+	}
+
+	*key = entry->key;
+	*mod = entry->mod;
+	return (*key != 0);
+}
+
+void
+gnome_stock_menu_accel_parse(const char *section)
+{
+	g_return_if_fail(section != NULL);
+	g_hash_table_foreach(accel_hash(), accel_read_rc,
+			     (char *)section);
+}
+
+
+/********************************/
+/*  accelerator definition box  */
+/********************************/
+
+#if 0
+
+#include <libgnomeui/gnome-messagebox.h>
+#include <libgnomeui/gnome-propertybox.h>
+
+static void
+accel_dlg_apply(GtkWidget *box, int n)
+{
+	GtkCList *clist;
+	char *section, *key, *s;
+	int i;
+
+	if (n != 0) return;
+	clist = gtk_object_get_data(GTK_OBJECT(box), "clist");
+	section = gtk_object_get_data(GTK_OBJECT(box), "section");
+	for (i = 0; i < clist->rows; i++) {
+		gtk_clist_get_text(clist, i, 0, &s);
+		key = g_strconcat(section, s, NULL);
+		gtk_clist_get_text(clist, i, 1, &s);
+		gnome_config_set_string(key, s);
+		g_free(key);
+	}
+	gnome_config_sync();
+}
+
+
+
+static void
+accel_dlg_help(GtkWidget *box, int n)
+{
+	GtkWidget *w;
+	
+	w = gnome_message_box_new("No help available yet!", "info",
+				 GNOME_STOCK_BUTTON_OK, NULL);
+	gtk_widget_show(w);
+}
+
+
+
+static void
+accel_dlg_select_ok(GtkWidget *widget, GtkWindow *window)
+{
+	AccelEntry entry;
+	GtkToggleButton *check;
+	gchar *s, *s2;
+        const char *key;
+	int row;
+
+	key = gtk_entry_get_text(GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(window), "key")));
+	if (!key) {
+		entry.key = 0;
+		entry.mod = 0;
+	} else {
+		accel_from_string((gchar *) key, &entry.key, &entry.mod);
+		entry.mod = 0;
+		check = gtk_object_get_data(GTK_OBJECT(window), "shift");
+		if (check->active)
+			entry.mod |= GDK_SHIFT_MASK;
+		check = gtk_object_get_data(GTK_OBJECT(window), "control");
+		if (check->active)
+			entry.mod |= GDK_CONTROL_MASK;
+		check = gtk_object_get_data(GTK_OBJECT(window), "alt");
+		if (check->active)
+			entry.mod |= GDK_MOD1_MASK;
+	}
+	row = GPOINTER_TO_INT (gtk_object_get_data(GTK_OBJECT(window), "row"));
+	gtk_clist_get_text(GTK_CLIST(gtk_object_get_data(GTK_OBJECT(window), "clist")),
+			   row, 1, &s);
+	if (!s) s = "";
+	s2 = accel_to_string(&entry);
+	if (!s2) s2 = "";
+	if (g_strcasecmp(s2, s)) {
+		gnome_property_box_changed(GNOME_PROPERTY_BOX(gtk_object_get_data(GTK_OBJECT(window), "box")));
+		gtk_clist_set_text(GTK_CLIST(gtk_object_get_data(GTK_OBJECT(window),
+								 "clist")),
+					     row, 1, accel_to_string(&entry));
+	}
+}
+
+
+
+static void
+accel_dlg_select(GtkCList *widget, gint row, gint col, GdkEventButton *event)
+{
+	AccelEntry entry;
+	GtkTable *table;
+	GtkWidget *window, *w;
+	char *s;
+
+	gtk_clist_unselect_row(widget, row, col);
+	s = NULL;
+	gtk_clist_get_text(widget, row, col, &s);
+	if (s) {
+		accel_from_string(s, &entry.key, &entry.mod);
+	} else {
+		entry.key = 0;
+		entry.mod = 0;
+	}
+	window = gtk_dialog_new();
+	gtk_window_set_title(GTK_WINDOW(window), "Menu Accelerator");
+	gtk_object_set_data(GTK_OBJECT(window), "clist", widget);
+	gtk_object_set_data(GTK_OBJECT(window), "row", GINT_TO_POINTER (row));
+	gtk_object_set_data(GTK_OBJECT(window), "col", GINT_TO_POINTER (col));
+	gtk_object_set_data(GTK_OBJECT(window), "box",
+			    gtk_object_get_data(GTK_OBJECT(widget), "box"));
+
+	table = (GtkTable *)gtk_table_new(0, 0, FALSE);
+	gtk_widget_show(GTK_WIDGET(table));
+	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(window)->vbox),
+			  GTK_WIDGET(table));
+
+	gtk_clist_get_text(GTK_CLIST(widget), row, 0, &s);
+	s = g_strconcat("Accelerator for ", s, NULL);
+	w = gtk_label_new(s);
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, 0, 2, 0, 1);
+
+	w = gtk_label_new("Key:");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, 0, 1, 1, 2);
+	w = gtk_entry_new();
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, 1, 2, 1, 2);
+	gtk_object_set_data(GTK_OBJECT(window), "key", w);
+	if (accel_to_string(&entry)) {
+		s = g_strdup(accel_to_string(&entry));
+		if (strrchr(s, '+'))
+			gtk_entry_set_text(GTK_ENTRY(w), strrchr(s, '+') + 1);
+		else
+			gtk_entry_set_text(GTK_ENTRY(w), s);
+		g_free(s);
+	}
+
+	w = gtk_check_button_new_with_label("Control");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, 0, 2, 2, 3);
+	gtk_object_set_data(GTK_OBJECT(window), "control", w);
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),
+				    entry.mod & GDK_CONTROL_MASK);
+
+	w = gtk_check_button_new_with_label("Shift");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, 0, 2, 3, 4);
+	gtk_object_set_data(GTK_OBJECT(window), "shift", w);
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),
+				    entry.mod & GDK_SHIFT_MASK);
+
+	w = gtk_check_button_new_with_label("Alt");
+	gtk_widget_show(w);
+	gtk_table_attach_defaults(table, w, 0, 2, 4, 5);
+	gtk_object_set_data(GTK_OBJECT(window), "alt", w);
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),
+				    entry.mod & GDK_MOD1_MASK);
+
+	w = gnome_stock_button(GNOME_STOCK_BUTTON_CANCEL);
+	gtk_widget_show(w);
+	gtk_signal_connect_object(GTK_OBJECT(w), "clicked",
+				  (GtkSignalFunc)gtk_widget_destroy,
+				  GTK_OBJECT(window));
+	gtk_box_pack_end_defaults(GTK_BOX(GTK_DIALOG(window)->action_area), w);
+	w = gnome_stock_button(GNOME_STOCK_BUTTON_OK);
+	gtk_widget_show(w);
+	gtk_signal_connect(GTK_OBJECT(w), "clicked",
+			   (GtkSignalFunc)accel_dlg_select_ok,
+			   window);
+	gtk_signal_connect_object(GTK_OBJECT(w), "clicked",
+				  (GtkSignalFunc)gtk_widget_destroy,
+				  GTK_OBJECT(window));
+	gtk_box_pack_end_defaults(GTK_BOX(GTK_DIALOG(window)->action_area), w);
+	gtk_widget_show(window);
+}
+
+
+/* make the compiler happy */
+void gnome_stock_menu_accel_dlg(char *section);
+
+void
+gnome_stock_menu_accel_dlg(char *section)
+{
+	GnomePropertyBox *box;
+	GtkWidget *w, *label;
+	const struct default_AccelEntry *p;
+	char *titles[2];
+	char *row_data[2];
+
+	box = GNOME_PROPERTY_BOX(gnome_property_box_new());
+	gtk_window_set_title(GTK_WINDOW(box), _("Menu Accelerator Keys"));
+
+	label = gtk_label_new(_("Global"));
+	gtk_widget_show(label);
+	titles[0] = _("Menu Item");
+	titles[1] = _("Accelerator");
+	w = gtk_clist_new_with_titles(2, titles);
+	gtk_object_set_data(GTK_OBJECT(box), "clist", w);
+	gtk_widget_set_usize(w, -1, 170);
+	gtk_clist_set_column_width(GTK_CLIST(w), 0, 100);
+	gtk_clist_column_titles_passive(GTK_CLIST(w));
+	gtk_widget_show(w);
+	gtk_signal_connect(GTK_OBJECT(w), "select_row",
+			   (GtkSignalFunc)accel_dlg_select,
+			   NULL);
+	gtk_object_set_data(GTK_OBJECT(w), "box", box);
+	for (p = default_accel_hash; p->type; p++) {
+		row_data[0] = (char*)p->type;
+		row_data[1] = g_strdup(accel_to_string(&p->entry));
+		gtk_clist_append(GTK_CLIST(w), row_data);
+		g_free(row_data[1]);
+	}
+	gnome_property_box_append_page(box, w, label);
+
+	if (!section) {
+		gtk_object_set_data(GTK_OBJECT(box), "section",
+				    "/Gnome/Accelerators/");
+	} else {
+		gtk_object_set_data(GTK_OBJECT(box), "section", section);
+		/* TODO: maybe add another page for the app's menu accelerator
+		 * config */
+	}
+
+	gtk_signal_connect(GTK_OBJECT(box), "apply",
+			  (GtkSignalFunc)accel_dlg_apply, NULL);
+	gtk_signal_connect(GTK_OBJECT(box), "help",
+			  (GtkSignalFunc)accel_dlg_help, NULL);
+
+	gtk_widget_show(GTK_WIDGET(box));
+}
+
+#endif
+
+GtkWidget *
+gnome_stock_transparent_window (const char *icon, GtkStateType state)
+{
+	GnomeStockPixmapEntry **entries = NULL;
+	GtkWidget *window = NULL;
+        GdkPixbuf *pixbuf = NULL;
+        GdkBitmap *mask = NULL;
+        GdkPixmap *pixmap = NULL;
+        
+	g_return_val_if_fail(icon != NULL, NULL);
+
+        entries = lookup(icon);
+	
+	window = NULL;
+
+        if (entries[state] == NULL)
+                return NULL;
+        
+        pixbuf = gnome_stock_pixmap_entry_get_gdk_pixbuf(entries[state]);
+
+        if (pixbuf == NULL)
+                return NULL;
+        
+	/* Create the window on GdkRGB's visual */
+	gtk_widget_push_colormap (gdk_rgb_get_cmap ());
+	window = gtk_window_new (GTK_WINDOW_POPUP);
+	gtk_widget_pop_colormap ();
+
+	/* Force realization */
+	gtk_widget_realize (window);
+
+	/* Kids:  DO not do this.  I repeat.  Do not do this.
+	 * we are trained professionals and we know what we are doing.
+	 *
+	 * Here is an explanation in case you care:
+	 *   We break the GDK abstraction here, as older Gdks do not
+	 *   support the Xserver SaveUnder flag.  We do set the
+	 *   windows's realize bit and we create the window manually
+	 *   setting the saveunder flag.
+	 */
+	/* Set proper size */
+	gtk_widget_set_usize (window,
+                              gdk_pixbuf_get_width(pixbuf),
+                              gdk_pixbuf_get_height(pixbuf));
+
+
+        /* generate mask */
+        if (gdk_pixbuf_get_has_alpha(pixbuf)) {
+                mask = gdk_pixmap_new(NULL,
+                                      gdk_pixbuf_get_width(pixbuf),
+                                      gdk_pixbuf_get_height(pixbuf),
+                                      1);
+
+                gdk_pixbuf_render_threshold_alpha(pixbuf, mask,
+                                                  0, 0, 0, 0,
+                                                  gdk_pixbuf_get_width(pixbuf),
+                                                  gdk_pixbuf_get_height(pixbuf),
+                                                  128); /* 50% alpha */
+        }
+
+        /* Draw to a pixmap */
+        
+        pixmap = gdk_pixmap_new(window->window,
+                                gdk_pixbuf_get_width(pixbuf),
+                                gdk_pixbuf_get_height(pixbuf),
+                                -1);
+
+        gdk_pixbuf_render_to_drawable(pixbuf, pixmap,
+                                      window->style->white_gc,
+                                      0, 0, 0, 0,
+                                      gdk_pixbuf_get_width(pixbuf),
+                                      gdk_pixbuf_get_height(pixbuf),
+                                      GDK_RGB_DITHER_NORMAL,
+                                      0, 0);
+        
+        /* Install pixmap/mask in the window */
+	gdk_window_set_back_pixmap (window->window, pixmap, FALSE);
+
+        gdk_pixmap_unref(pixmap);
+
+        /* This appears to take ownership of the mask */
+	gtk_widget_shape_combine_mask (window, mask, 0, 0);
+
+        /* Destroy the pixbuf */
+        gdk_pixbuf_unref(pixbuf);
+	
+	return window;
+}
+
+void 
+gnome_stock_pixmap_gdk (const char    *icon,
+                        GtkStateType   state,
+			GdkPixmap    **pixmap,
+			GdkPixmap    **mask)
+{
+	GnomeStockPixmapEntry **entries;
+        GdkPixbuf *pixbuf;
+        
+	g_return_if_fail(icon != NULL);
+	g_return_if_fail(pixmap != NULL);
+	g_return_if_fail(mask != NULL);
+
+        entries = lookup(icon);
+
+        if (entries == NULL)
+                return;
+
+        pixbuf = gnome_stock_pixmap_entry_get_gdk_pixbuf(entries[state]);
+
+        gdk_pixbuf_render_pixmap_and_mask(pixbuf,
+                                          pixmap,
+                                          mask,
+                                          128);
+
+        gdk_pixbuf_unref(pixbuf);
+}
+
diff --git a/libgnomeui/gnome-stock.h b/libgnomeui/gnome-stock.h
new file mode 100644
index 0000000..5c17847
--- /dev/null
+++ b/libgnomeui/gnome-stock.h
@@ -0,0 +1,515 @@
+/* Stock icons, buttons, and menu items.
+   Copyright (C) 1997, 1998 Free Software Foundation
+
+   The Gnome 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.
+
+   The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Eckehard Berns  */
+
+#ifndef __GNOME_STOCK_H__
+#define __GNOME_STOCK_H__
+
+
+#include <gtk/gtkwidget.h>
+#include <gtk/gtkpixmap.h>
+#include <gtk/gtkvbox.h>
+#include <gtk/gtkbutton.h>
+#include "gnome-pixmap.h"
+/* #include <gdk_imlib.h> */
+
+
+
+
+/* A short description:
+ *
+ *  These functions provide an applications programmer with default
+ *  icons for toolbars, menu pixmaps, etc. One such `icon' should have
+ *  at least three pixmaps to reflect it's state. There is a `regular'
+ *  pixmap, a `disabled' pixmap and a `focused' pixmap. You can get
+ *  either each of these pixmaps by calling gnome_stock_pixmap or you
+ *  can get a widget by calling gnome_stock_pixmap_widget. This widget
+ *  is a container which gtk_widget_shows the pixmap, that is
+ *  reflecting the current state of the widget. If for example you
+ *  gtk_container_add this widget to a button, which is currently not
+ *  sensitive, the widget will just show the `disabled' pixmap. If the
+ *  state of the button changes to sensitive, the widget will change to
+ *  the `regular' pixmap. The `focused' pixmap will be shown, when the
+ *  mouse pointer enters the widget.
+ *
+ *  To support themability, we use (char *) to call those functions. A
+ *  new theme might register new icons by calling
+ *  gnome_stock_pixmap_register, or may change existing icons by
+ *  calling gnome_stock_pixmap_change. An application should check (by
+ *  calling gnome_stock_pixmap_checkfor), if the current theme supports
+ *  an uncommon icon, before using it. The only icons an app can rely
+ *  on, are those defined in this header file.
+ *
+ *  We now have stock buttons too. To use them, just replace any
+ *  gtk_button_new{_with_label} with
+ *  gnome_stock_button(GNOME_STOCK_BUTTON_...).  This function returns
+ *  a GtkButton with a gettexted default text and an icon.
+ *
+ *  There's an additional feature, which might be interesting. If an
+ *  application calls gnome_stock_pixmap_register and uses it by
+ *  calling gnome_stock_pixmap_widget, it doesn't have to care about
+ *  the state_changed signal to display the appropriate pixmap
+ *  itself. Additionally gnome-stock generates a disabled version of a
+ *  pixmap automatically, when no pixmap for a disabled state is
+ *  provided.
+ */
+
+/* State:
+ *
+ *  currently implemented:
+ *    - gnome_stock_pixmap
+ *    - gnome_stock_pixmap_widget
+ *    - gnome_stock_pixmap_checkfor
+ *    - GnomeStockPixmapWidget
+ *    - gnome_stock_button
+ *    - gnome_stock_pixmap_register
+ *
+ *  not implemented:
+ *    - gnome_stock_pixmap_change
+ */
+
+G_BEGIN_DECLS
+
+/* The names of `well known' icons. I define these strings mainly to
+   prevent errors due to typos. */
+
+#define GNOME_STOCK_PIXMAP_NEW         "New"
+#define GNOME_STOCK_PIXMAP_OPEN        "Open"
+#define GNOME_STOCK_PIXMAP_CLOSE       "Close"
+#define GNOME_STOCK_PIXMAP_REVERT      "Revert"
+#define GNOME_STOCK_PIXMAP_SAVE        "Save"
+#define GNOME_STOCK_PIXMAP_SAVE_AS     "Save As"
+#define GNOME_STOCK_PIXMAP_CUT         "Cut"
+#define GNOME_STOCK_PIXMAP_COPY        "Copy"
+#define GNOME_STOCK_PIXMAP_PASTE       "Paste"
+#define GNOME_STOCK_PIXMAP_CLEAR       "Clear"
+#define GNOME_STOCK_PIXMAP_PROPERTIES  "Properties"
+#define GNOME_STOCK_PIXMAP_PREFERENCES "Preferences"
+#define GNOME_STOCK_PIXMAP_HELP        "Help"
+#define GNOME_STOCK_PIXMAP_SCORES      "Scores"
+#define GNOME_STOCK_PIXMAP_PRINT       "Print"
+#define GNOME_STOCK_PIXMAP_SEARCH      "Search"
+#define GNOME_STOCK_PIXMAP_SRCHRPL     "Search/Replace"
+#define GNOME_STOCK_PIXMAP_BACK        "Back"
+#define GNOME_STOCK_PIXMAP_FORWARD     "Forward"
+#define GNOME_STOCK_PIXMAP_FIRST       "First"
+#define GNOME_STOCK_PIXMAP_LAST        "Last"
+#define GNOME_STOCK_PIXMAP_HOME        "Home"
+#define GNOME_STOCK_PIXMAP_STOP        "Stop"
+#define GNOME_STOCK_PIXMAP_REFRESH     "Refresh"
+#define GNOME_STOCK_PIXMAP_UNDO        "Undo"
+#define GNOME_STOCK_PIXMAP_REDO        "Redo"
+#define GNOME_STOCK_PIXMAP_TIMER       "Timer"
+#define GNOME_STOCK_PIXMAP_TIMER_STOP  "Timer Stopped"
+#define GNOME_STOCK_PIXMAP_MAIL	       "Mail"
+#define GNOME_STOCK_PIXMAP_MAIL_RCV    "Receive Mail"
+#define GNOME_STOCK_PIXMAP_MAIL_SND    "Send Mail"
+#define GNOME_STOCK_PIXMAP_MAIL_RPL    "Reply to Mail"
+#define GNOME_STOCK_PIXMAP_MAIL_FWD    "Forward Mail"
+#define GNOME_STOCK_PIXMAP_MAIL_NEW    "New Mail"
+#define GNOME_STOCK_PIXMAP_TRASH       "Trash"
+#define GNOME_STOCK_PIXMAP_TRASH_FULL  "Trash Full"
+#define GNOME_STOCK_PIXMAP_UNDELETE    "Undelete"
+#define GNOME_STOCK_PIXMAP_SPELLCHECK  "Spellchecker"
+#define GNOME_STOCK_PIXMAP_MIC         "Microphone"
+#define GNOME_STOCK_PIXMAP_LINE_IN     "Line In"
+#define GNOME_STOCK_PIXMAP_CDROM       "Cdrom"
+#define GNOME_STOCK_PIXMAP_VOLUME      "Volume"
+#define GNOME_STOCK_PIXMAP_MIDI        "Midi"
+#define GNOME_STOCK_PIXMAP_BOOK_RED    "Book Red"
+#define GNOME_STOCK_PIXMAP_BOOK_GREEN  "Book Green"
+#define GNOME_STOCK_PIXMAP_BOOK_BLUE   "Book Blue"
+#define GNOME_STOCK_PIXMAP_BOOK_YELLOW "Book Yellow"
+#define GNOME_STOCK_PIXMAP_BOOK_OPEN   "Book Open"
+#define GNOME_STOCK_PIXMAP_ABOUT       "About"
+#define GNOME_STOCK_PIXMAP_QUIT        "Quit"
+#define GNOME_STOCK_PIXMAP_MULTIPLE    "Multiple"
+#define GNOME_STOCK_PIXMAP_NOT         "Not"
+#define GNOME_STOCK_PIXMAP_CONVERT     "Convert"
+#define GNOME_STOCK_PIXMAP_JUMP_TO     "Jump To"
+#define GNOME_STOCK_PIXMAP_UP          "Up"
+#define GNOME_STOCK_PIXMAP_DOWN        "Down"
+#define GNOME_STOCK_PIXMAP_TOP         "Top"
+#define GNOME_STOCK_PIXMAP_BOTTOM      "Bottom"
+#define GNOME_STOCK_PIXMAP_ATTACH      "Attach"
+#define GNOME_STOCK_PIXMAP_INDEX       "Index"
+#define GNOME_STOCK_PIXMAP_FONT        "Font"
+#define GNOME_STOCK_PIXMAP_EXEC        "Exec"
+
+#define GNOME_STOCK_PIXMAP_ALIGN_LEFT    "Left"
+#define GNOME_STOCK_PIXMAP_ALIGN_RIGHT   "Right"
+#define GNOME_STOCK_PIXMAP_ALIGN_CENTER  "Center"
+#define GNOME_STOCK_PIXMAP_ALIGN_JUSTIFY "Justify"
+
+#define GNOME_STOCK_PIXMAP_TEXT_BOLD      "Bold"
+#define GNOME_STOCK_PIXMAP_TEXT_ITALIC    "Italic"
+#define GNOME_STOCK_PIXMAP_TEXT_UNDERLINE "Underline"
+#define GNOME_STOCK_PIXMAP_TEXT_STRIKEOUT "Strikeout"
+
+#define GNOME_STOCK_PIXMAP_TEXT_INDENT "Text Indent"
+#define GNOME_STOCK_PIXMAP_TEXT_UNINDENT "Text Unindent"
+
+#define GNOME_STOCK_PIXMAP_EXIT        GNOME_STOCK_PIXMAP_QUIT
+
+#define GNOME_STOCK_PIXMAP_COLORSELECTOR "Color Select"
+
+#define GNOME_STOCK_PIXMAP_ADD    "Add"
+#define GNOME_STOCK_PIXMAP_REMOVE "Remove"
+
+#define GNOME_STOCK_PIXMAP_TABLE_BORDERS "Table Borders"
+#define GNOME_STOCK_PIXMAP_TABLE_FILL "Table Fill"
+
+#define GNOME_STOCK_PIXMAP_TEXT_BULLETED_LIST "Text Bulleted List"
+#define GNOME_STOCK_PIXMAP_TEXT_NUMBERED_LIST "Text Numbered List"
+
+/* The basic pixmap version of an icon. */
+
+#define GNOME_STOCK_PIXMAP_REGULAR     "regular"
+#define GNOME_STOCK_PIXMAP_DISABLED    "disabled"
+#define GNOME_STOCK_PIXMAP_FOCUSED     "focused"
+
+
+
+/* some internal definitions */
+
+typedef struct _GnomeStockPixmapEntryAny     GnomeStockPixmapEntryAny;
+typedef struct _GnomeStockPixmapEntryData    GnomeStockPixmapEntryData;
+typedef struct _GnomeStockPixmapEntryFile    GnomeStockPixmapEntryFile;
+typedef struct _GnomeStockPixmapEntryPath    GnomeStockPixmapEntryPath;
+typedef struct _GnomeStockPixmapEntryPixbuf       GnomeStockPixmapEntryPixbuf;
+typedef struct _GnomeStockPixmapEntryPixbufScaled GnomeStockPixmapEntryPixbufScaled;
+typedef union  _GnomeStockPixmapEntry        GnomeStockPixmapEntry;
+
+typedef enum {
+        GNOME_STOCK_PIXMAP_TYPE_NONE,
+        GNOME_STOCK_PIXMAP_TYPE_DATA,
+        GNOME_STOCK_PIXMAP_TYPE_FILE,
+        GNOME_STOCK_PIXMAP_TYPE_PATH,
+	GNOME_STOCK_PIXMAP_TYPE_PIXBUF,
+	GNOME_STOCK_PIXMAP_TYPE_PIXBUF_SCALED,
+	GNOME_STOCK_PIXMAP_TYPE_LAST
+} GnomeStockPixmapType;
+
+struct _GnomeStockPixmapEntryAny {
+        GnomeStockPixmapType type;
+	int ref_count;
+	char *label;
+        GdkPixbuf *pixbuf;
+};
+
+/* a data entry holds a hardcoded pixmap */
+struct _GnomeStockPixmapEntryData {
+        GnomeStockPixmapType type;
+	int ref_count;
+	char *label;
+        GdkPixbuf *pixbuf;
+        const gchar **xpm_data;
+};
+
+/* a file entry holds a filename (no path) to the pixamp. this pixmap
+   will be seached for using gnome_pixmap_file */
+struct _GnomeStockPixmapEntryFile {
+        GnomeStockPixmapType type;
+	int ref_count;
+	char *label;
+        GdkPixbuf *pixbuf;
+        gchar *filename;
+};
+
+/* a path entry holds the complete (absolut) path to the pixmap file */
+struct _GnomeStockPixmapEntryPath {
+        GnomeStockPixmapType type;
+	int ref_count;
+	char *label;
+        GdkPixbuf *pixbuf;
+        gchar *pathname;
+};
+
+/* a data entry holds a hardcoded pixmap */
+struct _GnomeStockPixmapEntryPixbuf {
+        GnomeStockPixmapType type;
+	int ref_count;
+        char *label;
+        GdkPixbuf *pixbuf;
+};
+
+ 
+/* scales the Pixbuf data to the given size when used (allows scale-on-demand) */
+struct _GnomeStockPixmapEntryPixbufScaled {
+        GnomeStockPixmapType type;
+	int ref_count;
+        char *label;
+        GdkPixbuf *pixbuf;
+        int scaled_width, scaled_height;
+        GdkPixbuf *unscaled_pixbuf;
+};
+
+union _GnomeStockPixmapEntry {
+        GnomeStockPixmapType type;
+        GnomeStockPixmapEntryAny any;
+        GnomeStockPixmapEntryData data;
+        GnomeStockPixmapEntryFile file;
+        GnomeStockPixmapEntryPath path;
+        GnomeStockPixmapEntryPixbuf pixbuf;
+        GnomeStockPixmapEntryPixbufScaled scaled;
+};
+
+
+
+#define GNOME_STOCK_PIXMAP_WIDGET GNOME_STOCK
+#define GNOME_IS_STOCK_PIXMAP_WIDGET GNOME_IS_STOCK
+
+GtkWidget *gnome_stock_pixmap_widget_new(GtkWidget *window, const char *icon);
+
+
+/* The new GnomeStock widget */
+
+
+#define GNOME_TYPE_STOCK            (gnome_stock_get_type ())
+#define GNOME_STOCK(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_STOCK, GnomeStock))
+#define GNOME_STOCK_CLASS(klass)    (GTK_CHECK_CAST_CLASS ((klass), GNOME_TYPE_STOCK, GnomeStock))
+#define GNOME_IS_STOCK(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_STOCK))
+#define GNOME_IS_STOCK_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_STOCK))
+
+typedef struct _GnomeStock       GnomeStock;
+typedef struct _GnomeStockClass  GnomeStockClass;
+
+struct _GnomeStock {
+	GnomePixmap pixmap;
+	GnomePixmap *regular, *disabled, *focused; /* pixmap cache */
+	GnomePixmap *current;
+	char *icon;
+	guint32 c_regular, c_disabled, c_focused;
+};
+
+struct _GnomeStockClass {
+	GnomePixmapClass pixmap_class;
+};
+
+guint         gnome_stock_get_type(void);
+GtkWidget    *gnome_stock_new(void);
+GtkWidget    *gnome_stock_new_with_icon(const char *icon);
+gboolean      gnome_stock_set_icon(GnomeStock *stock, const char *icon);
+
+
+/* the utility functions */
+
+/* just fetch a pixmap */
+/* window isn't needed for pixmap creation but for the style
+ * when a disabled icon is automatically created */
+/* okay, since there are many problems with this function (realization issues),
+ * don't use it. Use gnome_stock_pixmap_widget instead -- it's far more save and
+ * the result is the same */
+#if 0
+GnomePixmap           *gnome_stock_pixmap          (GtkWidget *window,
+                                                    const char *icon,
+                                                    const char *subtype);
+#endif
+
+/* just fetch a GnomeStock(PixmapWidget) */
+/* It is possible to specify a filename instead of an icon name. Gnome stock
+ * will use gnome_pixmap_file to find the pixmap and return a GnomeStock widget
+ * from that file. */
+GtkWidget             *gnome_stock_pixmap_widget   (GtkWidget *window,
+                                                    const char *icon);
+
+/* This function loads that file scaled to the specified size. Unlike
+ * gnome_pixmap_new_from_file_at_size this function uses antializing and stuff
+ * to scale the pixmap */
+GtkWidget             *gnome_stock_pixmap_widget_at_size(GtkWidget *window,
+							 const char *icon,
+				  			 guint width,
+							 guint height);
+
+/* change the icon/look of a GnomeStockPixmapWidget */
+void gnome_stock_pixmap_widget_set_icon(GnomeStock *widget,
+					const char *icon);
+
+/* register a pixmap. returns non-zero, if successful */
+gint                   gnome_stock_pixmap_register (const char *icon,
+						    GtkStateType state,
+                                                    GnomeStockPixmapEntry *entry);
+
+/* change an existing entry. returns non-zero on success */
+gint                   gnome_stock_pixmap_change   (const char *icon,
+						    GtkStateType state,
+                                                    GnomeStockPixmapEntry *entry);
+
+/* check for the existance of an entry. returns the entry if it
+   exists, or NULL otherwise */
+GnomeStockPixmapEntry *gnome_stock_pixmap_checkfor (const char *icon,
+						    GtkStateType state);
+
+
+
+/*  buttons  */
+
+/* this function returns a button with a pixmap (if ButtonUseIcons is enabled)
+ * and the provided text */
+
+GtkWidget            *gnome_pixmap_button         (GtkWidget *pixmap,
+						   const char *text);
+void		      gnome_button_can_default    (GtkButton *button,
+						   gboolean can_default);
+
+#define GNOME_STOCK_BUTTON_OK     "Button_Ok"
+#define GNOME_STOCK_BUTTON_CANCEL "Button_Cancel"
+#define GNOME_STOCK_BUTTON_YES    "Button_Yes"
+#define GNOME_STOCK_BUTTON_NO     "Button_No"
+#define GNOME_STOCK_BUTTON_CLOSE  "Button_Close"
+#define GNOME_STOCK_BUTTON_APPLY  "Button_Apply"
+#define GNOME_STOCK_BUTTON_HELP   "Button_Help"
+#define GNOME_STOCK_BUTTON_NEXT   "Button_Next"
+#define GNOME_STOCK_BUTTON_PREV   "Button_Prev"
+#define GNOME_STOCK_BUTTON_UP     "Button_Up"
+#define GNOME_STOCK_BUTTON_DOWN   "Button_Down"
+#define GNOME_STOCK_BUTTON_FONT   "Button_Font"
+
+/* returns a default button widget for dialogs */
+GtkWidget             *gnome_stock_button          (const char *type);
+
+/* Returns a button widget.  If the TYPE argument matches a
+   GNOME_STOCK_BUTTON_* define, then a stock button is created.
+   Otherwise, an ordinary button is created, and TYPE is given as the
+   label.  */
+GtkWidget             *gnome_stock_or_ordinary_button (const char *type);
+
+
+/*  menus  */
+
+#define GNOME_STOCK_MENU_BLANK        "Menu_"
+#define GNOME_STOCK_MENU_NEW          "Menu_New"
+#define GNOME_STOCK_MENU_SAVE         "Menu_Save"
+#define GNOME_STOCK_MENU_SAVE_AS      "Menu_Save As"
+#define GNOME_STOCK_MENU_REVERT       "Menu_Revert"
+#define GNOME_STOCK_MENU_OPEN         "Menu_Open"
+#define GNOME_STOCK_MENU_CLOSE        "Menu_Close"
+#define GNOME_STOCK_MENU_QUIT         "Menu_Quit"
+#define GNOME_STOCK_MENU_CUT          "Menu_Cut"
+#define GNOME_STOCK_MENU_COPY         "Menu_Copy"
+#define GNOME_STOCK_MENU_PASTE        "Menu_Paste"
+#define GNOME_STOCK_MENU_PROP         "Menu_Properties"
+#define GNOME_STOCK_MENU_PREF         "Menu_Preferences"
+#define GNOME_STOCK_MENU_ABOUT        "Menu_About"
+#define GNOME_STOCK_MENU_SCORES       "Menu_Scores"
+#define GNOME_STOCK_MENU_UNDO         "Menu_Undo"
+#define GNOME_STOCK_MENU_REDO         "Menu_Redo"
+#define GNOME_STOCK_MENU_PRINT        "Menu_Print"
+#define GNOME_STOCK_MENU_SEARCH       "Menu_Search"
+#define GNOME_STOCK_MENU_SRCHRPL      "Menu_Search/Replace"
+#define GNOME_STOCK_MENU_BACK         "Menu_Back"
+#define GNOME_STOCK_MENU_FORWARD      "Menu_Forward"
+#define GNOME_STOCK_MENU_FIRST        "Menu_First"
+#define GNOME_STOCK_MENU_LAST         "Menu_Last"
+#define GNOME_STOCK_MENU_HOME         "Menu_Home"
+#define GNOME_STOCK_MENU_STOP         "Menu_Stop"
+#define GNOME_STOCK_MENU_REFRESH      "Menu_Refresh"
+#define GNOME_STOCK_MENU_MAIL         "Menu_Mail"
+#define GNOME_STOCK_MENU_MAIL_RCV     "Menu_Receive Mail"
+#define GNOME_STOCK_MENU_MAIL_SND     "Menu_Send Mail"
+#define GNOME_STOCK_MENU_MAIL_RPL     "Menu_Reply to Mail"
+#define GNOME_STOCK_MENU_MAIL_FWD     "Menu_Forward Mail"
+#define GNOME_STOCK_MENU_MAIL_NEW     "Menu_New Mail"
+#define GNOME_STOCK_MENU_TRASH        "Menu_Trash"
+#define GNOME_STOCK_MENU_TRASH_FULL   "Menu_Trash Full"
+#define GNOME_STOCK_MENU_UNDELETE     "Menu_Undelete"
+#define GNOME_STOCK_MENU_TIMER        "Menu_Timer"
+#define GNOME_STOCK_MENU_TIMER_STOP   "Menu_Timer Stopped"
+#define GNOME_STOCK_MENU_SPELLCHECK   "Menu_Spellchecker"
+#define GNOME_STOCK_MENU_MIC          "Menu_Microphone"
+#define GNOME_STOCK_MENU_LINE_IN      "Menu_Line In"
+#define GNOME_STOCK_MENU_CDROM	     "Menu_Cdrom"
+#define GNOME_STOCK_MENU_VOLUME       "Menu_Volume"
+#define GNOME_STOCK_MENU_MIDI         "Menu_Midi"
+#define GNOME_STOCK_MENU_BOOK_RED     "Menu_Book Red"
+#define GNOME_STOCK_MENU_BOOK_GREEN   "Menu_Book Green"
+#define GNOME_STOCK_MENU_BOOK_BLUE    "Menu_Book Blue"
+#define GNOME_STOCK_MENU_BOOK_YELLOW  "Menu_Book Yellow"
+#define GNOME_STOCK_MENU_BOOK_OPEN    "Menu_Book Open"
+#define GNOME_STOCK_MENU_CONVERT      "Menu_Convert"
+#define GNOME_STOCK_MENU_JUMP_TO      "Menu_Jump To"
+#define GNOME_STOCK_MENU_UP           "Menu_Up"
+#define GNOME_STOCK_MENU_DOWN         "Menu_Down"
+#define GNOME_STOCK_MENU_TOP          "Menu_Top"
+#define GNOME_STOCK_MENU_BOTTOM       "Menu_Bottom"
+#define GNOME_STOCK_MENU_ATTACH       "Menu_Attach"
+#define GNOME_STOCK_MENU_INDEX        "Menu_Index"
+#define GNOME_STOCK_MENU_FONT         "Menu_Font"
+#define GNOME_STOCK_MENU_EXEC         "Menu_Exec"
+
+#define GNOME_STOCK_MENU_ALIGN_LEFT     "Menu_Left"
+#define GNOME_STOCK_MENU_ALIGN_RIGHT    "Menu_Right"
+#define GNOME_STOCK_MENU_ALIGN_CENTER   "Menu_Center"
+#define GNOME_STOCK_MENU_ALIGN_JUSTIFY  "Menu_Justify"
+
+#define GNOME_STOCK_MENU_TEXT_BOLD      "Menu_Bold"
+#define GNOME_STOCK_MENU_TEXT_ITALIC    "Menu_Italic"
+#define GNOME_STOCK_MENU_TEXT_UNDERLINE "Menu_Underline"
+#define GNOME_STOCK_MENU_TEXT_STRIKEOUT "Menu_Strikeout"
+
+#define GNOME_STOCK_MENU_EXIT     GNOME_STOCK_MENU_QUIT
+
+
+/* returns a GtkMenuItem with an stock icon and text */
+GtkWidget             *gnome_stock_menu_item       (const char *type,
+						    const char *text);
+
+
+/*
+ * Stock menu accelerators
+ */
+
+/* To customize the accelerators add a file ~/.gnome/GnomeStock, wich looks
+ * like that:
+ *
+ * [Accelerators]
+ * Menu_New=Shft+Ctl+N
+ * Menu_About=Ctl+A
+ * Menu_Save As=Ctl+Shft+S
+ * Menu_Quit=Alt+X
+ */
+
+/* this function returns the stock menu accelerators for the menu type in key
+ * and mod */
+gboolean	       gnome_stock_menu_accel      (const char *type,
+						    guchar *key,
+						    guint8 *mod);
+
+/* apps can call this function at startup to add per app accelerator
+ * redefinitions. section should be something like "/filename/section/" with
+ * both the leading and trailing `/' */
+void                   gnome_stock_menu_accel_parse(const char *section);
+
+/*
+ * Creates a toplevel window with a shaped mask.  Useful for making the DnD
+ * windows
+ */
+GtkWidget *gnome_stock_transparent_window (const char *icon, GtkStateType state);
+
+/*
+ * Return a GdkPixmap and GdkMask for a stock pixmap
+ */
+void gnome_stock_pixmap_gdk (const char *icon,
+			     GtkStateType state,
+			     GdkPixmap **pixmap,
+			     GdkPixmap **mask);
+
+G_END_DECLS
+
+#endif /* GNOME_STOCK_H */
diff --git a/libgnomeui/gnome-textfu.c b/libgnomeui/gnome-textfu.c
new file mode 100644
index 0000000..4eba76d
--- /dev/null
+++ b/libgnomeui/gnome-textfu.c
@@ -0,0 +1,1394 @@
+/* gnome-textfu.c
+ * Copyright (C) 2000 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+*/
+/* Written by Elliot Lee <sopwith redhat com>. This code is pretty aweful, but so is all my other code. */
+
+#include <config.h>
+#include "gnome-macros.h"
+
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <ctype.h>
+
+#include <libgnome/gnome-util.h>
+#include "gnome-cursors.h"
+#include "gnome-helpsys.h"
+#include "gnome-pixmap.h"
+
+#include "gnome-textfu.h"
+
+#define my_isspace(x) (isspace(x) || (x) == '\r' || (x) == '\n')
+#define LINE_SPACING 4
+
+typedef struct {
+  GnomeTextFuTagHandler handler;
+  guint16 tag_id;
+
+  char tag_name[1];
+} TagRegistration;
+
+typedef struct {
+  GdkRegion *region;
+  char *link_to;
+} TextRegionInfo;
+
+enum {
+  ACTIVATE_URI,
+  LAST_SIGNAL
+};
+
+static void gnome_textfu_init		(GnomeTextFu		 *textfu);
+static void gnome_textfu_class_init	(GnomeTextFuClass	 *klass);
+static void gnome_real_textfu_activate_uri (GnomeTextFu		 *textfu, const char *uri);
+static void gnome_textfu_realize            (GtkWidget      *widget);
+static void gnome_textfu_unrealize          (GtkWidget      *widget);
+static void gnome_textfu_map                (GtkWidget      *widget);
+static void gnome_textfu_unrealize          (GtkWidget      *widget);
+static void gnome_textfu_size_request       (GtkWidget      *widget,
+					     GtkRequisition *requisition);
+static void gnome_textfu_size_allocate      (GtkWidget      *widget,
+					     GtkAllocation  *allocation);
+static gint gnome_textfu_expose             (GtkWidget      *widget, 
+					     GdkEventExpose *event);
+static gint gnome_textfu_button_release_event(GtkWidget *widget, GdkEventButton *event);
+static gint gnome_textfu_motion_notify_event(GtkWidget *widget, GdkEventMotion *event);
+
+static guint textfu_signals[LAST_SIGNAL] = { 0 };
+
+/* Define boilerplate such as parent_class and _get_type */
+GNOME_CLASS_BOILERPLATE (GnomeTextFu, gnome_textfu,
+			 GtkLayout, gtk_layout)
+
+static GnomeTextFuItemContainer *
+gnome_textfu_item_container_new(void)
+{
+  GnomeTextFuItemContainer * retval;
+
+  retval = g_new0(GnomeTextFuItemContainer, 1);
+
+  retval->item.type = TEXTFU_ITEM_CONTAINER;
+
+  retval->subitems_newpara = TEXTFU_FALSE;
+  retval->subitems_italic = TEXTFU_FALSE;
+  retval->subitems_bold = TEXTFU_FALSE;
+  retval->subitems_bullet = TEXTFU_FALSE;
+
+  return retval;
+}
+
+static GnomeTextFuItemWidget *
+gnome_textfu_item_widget_new(GtkWidget *widget)
+{
+  GnomeTextFuItemWidget * retval;
+
+  retval = g_new0(GnomeTextFuItemWidget, 1);
+
+  retval->item.type = TEXTFU_ITEM_WIDGET;
+  retval->widget = widget;
+
+  return retval;
+}
+
+static char *
+gnome_textfu_resolve_filename(GnomeTextFu *textfu, char *in_filename, const char *type)
+{
+  int slen;
+
+  if (in_filename[0] == '"')
+    in_filename++;
+  slen = strlen(in_filename) - 1;
+  if (in_filename[slen] == '"')
+    in_filename[slen] = '\0';
+
+  if (g_file_test (in_filename, G_FILE_TEST_EXISTS))
+    return g_strdup (in_filename);
+  else if(in_filename[0] == '/')
+    return gnome_help_path_resolve(in_filename, type);
+  else
+    {
+      char *dirname_ret;
+      char *retval;
+      dirname_ret = g_path_get_dirname (textfu->cur_filename);
+      retval = g_concat_dir_and_file (dirname_ret, in_filename);
+      g_free (dirname_ret);
+      return retval;
+    }
+}
+
+#define IMPL_CTAG(x) static GnomeTextFuItem *handler_##x(GnomeTextFu *textfu, const char *tag, guint16 tag_id, char **attrs) \
+{ \
+GnomeTextFuItemContainer *retval; \
+retval = gnome_textfu_item_container_new(); \
+retval->subitems_newpara = TEXTFU_FALSE
+
+#define END_CTAG return (GnomeTextFuItem *)retval; }
+
+#define DUMMY_TAG(x) IMPL_CTAG(x); END_CTAG
+
+IMPL_CTAG(popup);
+retval->subitems_newpara = TEXTFU_TRUE;
+END_CTAG
+
+
+IMPL_CTAG(sect1);
+retval->subitems_newpara = TEXTFU_TRUE;
+END_CTAG
+
+IMPL_CTAG(title);
+retval->subitems_bold = TEXTFU_TRUE;
+retval->subitems_font_size = 16;
+END_CTAG
+
+
+IMPL_CTAG(sect2);
+retval->subitems_left_indent = 10;
+retval->subitems_right_indent = 10;
+END_CTAG
+
+
+IMPL_CTAG(para);
+END_CTAG
+
+IMPL_CTAG(ulink);
+{
+  int i;
+  for(i = 0; attrs[i]; i++)
+    {
+      if(!g_strncasecmp(attrs[i], "url=", strlen("url=")))
+	{
+	  char *link_ptr;
+	  int slen;
+
+	  link_ptr = attrs[i] + strlen("url=");
+	  if(*link_ptr == '"')
+	    link_ptr++;
+	  slen = strlen(link_ptr) - 1;
+	  if(link_ptr[slen] == '"')
+	    link_ptr[slen] = '\0';
+
+	  retval->link_to = g_strdup(link_ptr);
+	}
+    }
+}
+END_CTAG
+
+
+IMPL_CTAG(itemizedlist);
+retval->subitems_bullet = TEXTFU_TRUE;
+retval->subitems_newpara = TEXTFU_TRUE;
+END_CTAG
+
+IMPL_CTAG(listitem);
+END_CTAG
+
+IMPL_CTAG(application);
+retval->font_name = "fixed";
+END_CTAG
+
+IMPL_CTAG(guibutton);
+retval->subitems_bold = TEXTFU_TRUE;
+END_CTAG
+
+IMPL_CTAG(guiicon);
+retval->subitems_bold = TEXTFU_TRUE;
+END_CTAG
+
+IMPL_CTAG(guilabel);
+retval->font_name = "fixed";
+retval->subitems_bold = TEXTFU_TRUE;
+END_CTAG
+
+IMPL_CTAG(guimenu);
+retval->subitems_bold = TEXTFU_TRUE;
+END_CTAG
+
+IMPL_CTAG(guimenuitem);
+retval->subitems_bold = TEXTFU_TRUE;
+END_CTAG
+
+IMPL_CTAG(guisubmenu);
+retval->subitems_bold = TEXTFU_TRUE;
+END_CTAG
+
+IMPL_CTAG(keycap);
+retval->subitems_bold = TEXTFU_TRUE;
+END_CTAG
+
+IMPL_CTAG(keycombo);
+retval->subitems_bold = TEXTFU_TRUE;
+END_CTAG
+
+IMPL_CTAG(mousebutton);
+retval->subitems_italic = TEXTFU_TRUE;
+END_CTAG
+
+IMPL_CTAG(citetitle);
+retval->subitems_italic = TEXTFU_TRUE;
+END_CTAG
+
+IMPL_CTAG(authorgroup);
+retval->subitems_ignore = TRUE;
+END_CTAG
+
+DUMMY_TAG(author)
+DUMMY_TAG(honorific)
+DUMMY_TAG(firstname)
+DUMMY_TAG(surname)
+DUMMY_TAG(othername)
+DUMMY_TAG(affiliation)
+DUMMY_TAG(orgname)
+DUMMY_TAG(jobtitle)
+DUMMY_TAG(email)
+DUMMY_TAG(copyright)
+DUMMY_TAG(revhistory)
+DUMMY_TAG(revision)
+DUMMY_TAG(revnumber)
+DUMMY_TAG(date)
+
+static GnomeTextFuItem *
+handler_img(GnomeTextFu *textfu, const char *tag, guint16 tag_id, char **attrs)
+{
+  GtkWidget *pmap = NULL;
+  int i;
+
+  for(i = 0; !pmap && attrs[i]; i++)
+    {
+      if(!strncmp(attrs[i], "src=", 4))
+	{
+	  char *filename;
+	  filename = gnome_textfu_resolve_filename(textfu, attrs[i] + 4, "image");
+
+	  if(filename)
+	    {
+	      pmap = gnome_pixmap_new_from_file(filename);
+	      gtk_widget_show(pmap);
+	      g_free(filename);
+	    }
+	  else
+	    {
+	      g_warning("Couldn't find %s for an image", attrs[i]+4);
+	    }
+	}
+    }
+
+  if(!pmap)
+    return NULL;
+
+  return (GnomeTextFuItem *)gnome_textfu_item_widget_new(pmap);
+}
+
+static void
+gnome_textfu_class_init (GnomeTextFuClass *klass)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+
+  object_class = (GtkObjectClass*) klass;
+
+  widget_class = (GtkWidgetClass*) klass;
+
+  textfu_signals[ACTIVATE_URI] = 
+    gtk_signal_new ("activate_uri",
+                    GTK_RUN_FIRST,
+                    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (GnomeTextFuClass, activate_uri),
+                    gtk_marshal_VOID__STRING,
+                    GTK_TYPE_NONE, 1, GTK_TYPE_STRING);
+
+
+  klass->activate_uri = gnome_real_textfu_activate_uri;
+  klass->tag_handlers = g_hash_table_new(g_str_hash, g_str_equal);
+
+#define HA(x) gnome_textfu_tagid_alloc(#x, handler_##x)
+  HA(img);
+  HA(popup);
+  HA(sect1);
+  HA(title);
+  HA(sect2);
+  HA(para);
+  HA(ulink);
+  HA(itemizedlist);
+  HA(listitem);
+  HA(application);
+  HA(guibutton);
+  HA(guiicon);
+  HA(guilabel);
+  HA(guimenu);
+  HA(guimenuitem);
+  HA(guisubmenu);
+  HA(keycap);
+  HA(keycombo);
+  HA(mousebutton);
+  HA(citetitle);
+  HA(authorgroup);
+  HA(author);
+  HA(honorific);
+  HA(firstname);
+  HA(surname);
+  HA(othername);
+  HA(affiliation);
+  HA(orgname);
+  HA(jobtitle);
+  HA(email);
+  HA(copyright);
+  HA(revhistory);
+  HA(revnumber);
+  HA(revision);
+  HA(date);
+
+  widget_class->realize = gnome_textfu_realize;
+  widget_class->unrealize = gnome_textfu_unrealize;
+  widget_class->size_request = gnome_textfu_size_request;
+  widget_class->size_allocate = gnome_textfu_size_allocate;
+  widget_class->expose_event = gnome_textfu_expose;
+  widget_class->map = gnome_textfu_map;
+  widget_class->motion_notify_event = gnome_textfu_motion_notify_event;
+  widget_class->button_release_event = gnome_textfu_button_release_event;
+}
+
+static void
+gnome_textfu_init (GnomeTextFu *textfu)
+{
+  gtk_widget_add_events(GTK_WIDGET(textfu),
+			GDK_EXPOSURE_MASK|GDK_POINTER_MOTION_MASK|GDK_BUTTON_RELEASE_MASK
+			|GDK_BUTTON_PRESS_MASK|GDK_BUTTON_MOTION_MASK);
+}
+
+GtkWidget *
+gnome_textfu_new(void)
+{
+  GtkWidget *retval;
+
+  retval = gtk_widget_new(gnome_textfu_get_type(), NULL);
+  gtk_layout_set_hadjustment(GTK_LAYOUT(retval), NULL);
+  gtk_layout_set_vadjustment(GTK_LAYOUT(retval), NULL);
+
+  return retval;
+}
+
+static void
+gnome_real_textfu_activate_uri (GnomeTextFu *textfu, const char *uri)
+{
+  g_return_if_fail (textfu != NULL);
+  g_return_if_fail (GNOME_IS_TEXTFU (textfu));
+  
+}
+
+static void
+gnome_textfu_map(GtkWidget *widget)
+{
+	GNOME_CALL_PARENT_HANDLER (GTK_WIDGET_CLASS, map, (widget));
+
+	gtk_widget_queue_draw(widget);
+}
+
+static void
+gnome_textfu_realize(GtkWidget      *widget)
+{
+	GNOME_CALL_PARENT_HANDLER (GTK_WIDGET_CLASS, realize, (widget));
+}
+
+static void
+gnome_textfu_unrealize(GtkWidget      *widget)
+{
+	GNOME_CALL_PARENT_HANDLER (GTK_WIDGET_CLASS, unrealize, (widget));
+}
+
+static TextRegionInfo *
+find_text_region_for_window_coords(GnomeTextFu *textfu, gint x, gint y)
+{
+  GList *cur;
+
+  x += GTK_LAYOUT(textfu)->xoffset;
+  y += GTK_LAYOUT(textfu)->yoffset;
+
+  for(cur = textfu->link_regions; cur; cur = cur->next)
+    {
+      TextRegionInfo *info;
+
+      info = cur->data;
+
+      if(gdk_region_point_in(info->region, x, y))
+	return info;
+    }
+
+  return NULL;
+}
+
+static gint
+gnome_textfu_button_release_event(GtkWidget *widget, GdkEventButton *event)
+{
+  GnomeTextFu *textfu = GNOME_TEXTFU(widget);
+  TextRegionInfo *info = NULL;
+
+  if(event->window != GTK_LAYOUT(widget)->bin_window)
+    goto default_handling;
+
+  info = find_text_region_for_window_coords(textfu, event->x, event->y);
+  if(!info)
+    goto default_handling;
+
+  if(event->type == GDK_BUTTON_RELEASE)
+    gtk_signal_emit(GTK_OBJECT(widget), textfu_signals[ACTIVATE_URI], info->link_to);
+
+ default_handling:
+  return GNOME_CALL_PARENT_HANDLER_WITH_DEFAULT (GTK_WIDGET_CLASS,
+						 button_release_event,
+						 (widget, event),
+						 (info ? TRUE : FALSE));
+}
+
+static gint
+gnome_textfu_motion_notify_event(GtkWidget *widget, GdkEventMotion *event)
+{
+  static GdkCursor *cursor_hand = NULL;
+  GnomeTextFu *textfu = GNOME_TEXTFU(widget);
+  TextRegionInfo *info;
+
+  if(event->window != GTK_LAYOUT(widget)->bin_window)
+    goto default_handling;
+
+  info = find_text_region_for_window_coords(textfu, event->x, event->y);
+
+  if((info && TRUE) != textfu->linkpoint_cursor)
+    {
+      GdkCursor *set_new_cursor;
+
+      textfu->linkpoint_cursor = info && TRUE;
+
+      if(info)
+	{
+	  if(!cursor_hand)
+	    cursor_hand = gnome_stock_cursor_new(GNOME_STOCK_CURSOR_POINTING_HAND);
+	  set_new_cursor = cursor_hand;
+	}
+      else
+	set_new_cursor = NULL;
+
+      gdk_window_set_cursor(GTK_LAYOUT(widget)->bin_window, set_new_cursor);
+    }
+
+ default_handling:
+  return GNOME_CALL_PARENT_HANDLER_WITH_DEFAULT (GTK_WIDGET_CLASS,
+						 motion_notify_event,
+						 (widget, event),
+						 FALSE);
+}
+
+/* This data structure is really used for drawing just as much as sizing */
+typedef struct {
+  int xpos, ypos, line_height;
+  gboolean did_newpara;
+
+  gboolean drawing : 1;
+  gboolean reposition : 1;
+} SizingGlobalState;
+
+typedef struct {
+  SizingGlobalState global;
+
+  gint ascent, descent;
+
+  /* For use in figuring out the text layout */
+  gint8 left_indent, right_indent;
+  gint8 font_size;
+
+  gboolean italic : 1;
+  gboolean bold : 1;
+  gboolean bullet : 1;
+  gboolean newpara : 1;
+
+  char *link_to, *font_name;
+} SizingState;
+
+static void gnome_textfu_determine_size(GnomeTextFu *textfu, GtkRequisition *requisition, gboolean do_drawing);
+static void gnome_textfu_item_determine_size(GnomeTextFu *textfu, GnomeTextFuItem *item, SizingState *ss);
+
+static gboolean /* Returns true if coords are at least partially visible */
+gnome_textfu_draw_translate(GnomeTextFu *textfu, SizingState *ss, gint *x, gint *y, gint width, gint height)
+{
+  GtkLayout *layout = GTK_LAYOUT(textfu);
+
+  *x -= layout->xoffset;
+  *y -= layout->yoffset;
+  return ((*x + width) >= 0
+	  || (*y + height) >= 0
+	  || (*x < layout->width)
+	  || (*y < layout->height));
+}
+
+static void
+gnome_textfu_new_paragraph(GnomeTextFu *textfu, SizingState *ss)
+{
+  if(ss->global.did_newpara || !ss->newpara)
+    return;
+
+  ss->global.xpos = ss->left_indent;
+  ss->global.ypos += ss->global.line_height;
+
+  ss->global.ypos += 10; /* Inter-paragraph spacing */
+
+  ss->global.line_height = 0;
+  ss->global.did_newpara = TRUE;
+
+  if(ss->global.drawing && ss->bullet) /* Draw bullet for the new paragraph, if we're supposed to */
+    {
+      gint x, y, width=10, height=10;
+
+      x = ss->global.xpos;
+      y = ss->global.ypos;
+
+      if(gnome_textfu_draw_translate(textfu, ss, &x, &y, width, height))
+	{
+	  GdkGC *gc;
+	  gc = gdk_gc_new(GTK_LAYOUT(textfu)->bin_window);
+	  gdk_draw_arc(GTK_LAYOUT(textfu)->bin_window, gc, TRUE,
+		       x, y, width, height, 0, 360);
+	  gdk_gc_unref(gc);
+	}
+    }
+}
+
+static GdkFont *
+gnome_textfu_get_font(GnomeTextFu *textfu, GnomeTextFuItem *item, SizingState *ss)
+{
+  char fontname[512];
+  GdkFont *retval;
+  const char *foundry = "*",
+    *family = "helvetica",
+    *weight = "medium",
+    *slant = "r",
+    *set_width = "normal",
+    *charset = "*",
+    *pixel_size = "*",
+    *spacing = "*"
+    ;
+  int point_size = 120;
+
+  GnomeTextFuItemContainer *citem = (GnomeTextFuItemContainer *)item;
+
+  while(citem && (citem->item.type != TEXTFU_ITEM_CONTAINER || citem->inherited_font))
+    citem = (GnomeTextFuItemContainer *)citem->item.up;
+
+  g_assert(citem);
+
+  if(!citem->font)
+    {
+      if(ss->font_name)
+	family = ss->font_name;
+      if(ss->italic)
+	slant = "o";
+      if(ss->bold)
+	weight = "bold";
+      point_size = ss->font_size * 10;
+
+      g_snprintf(fontname, sizeof(fontname),"-%s-%s-%s-%s-%s-*-%s-%d-*-*-%s-*-%s",
+		 foundry, family, weight, slant, set_width,
+		 pixel_size, point_size, spacing, charset);
+
+      citem->font = retval = gdk_fontset_load(fontname);
+    }
+
+  /* We need a constant ascent/descent for all usages of this font */
+  gdk_string_extents(citem->font, "TLyg", NULL, NULL, NULL, &ss->ascent, &ss->descent);
+
+  return citem->font;
+}
+
+static void
+gnome_textfu_container_determine_size(GnomeTextFu *textfu, GnomeTextFuItemContainer *citem,
+				      SizingState *ss)
+{
+  GSList *cur;
+
+  citem->item.x = ss->global.xpos;
+  citem->item.y = ss->global.ypos;
+
+  if(citem->subitems_ignore)
+    return;
+
+  if(citem->subitems_left_indent > 0)
+    ss->left_indent += citem->subitems_left_indent;
+  if(citem->subitems_right_indent > 0)
+    ss->right_indent += citem->subitems_right_indent;
+
+  if(!citem->inherited_font)
+    {
+      if(citem->subitems_bold != TEXTFU_UNKNOWN)
+	ss->bold = citem->subitems_bold;
+      if(citem->subitems_italic != TEXTFU_UNKNOWN)
+	ss->italic = citem->subitems_italic;
+      if(citem->subitems_font_size > 0)
+	ss->font_size = citem->subitems_font_size;
+      if(citem->font_name)
+	ss->font_name = citem->font_name;
+      if(citem->link_to)
+	ss->link_to = citem->link_to;
+    }
+
+  if(citem->subitems_newpara != TEXTFU_UNKNOWN)
+    ss->newpara = citem->subitems_newpara;
+  if(citem->subitems_bullet != TEXTFU_UNKNOWN)
+    ss->bullet = citem->subitems_bullet;
+
+  for(cur = citem->children; cur; cur = cur->next)
+    {
+      GnomeTextFuItem *subitem = cur->data;
+      SizingState sub_state;
+
+      sub_state = *ss;
+
+      gnome_textfu_new_paragraph(textfu, &sub_state);
+
+      gnome_textfu_item_determine_size(textfu, subitem, &sub_state);
+
+      ss->global = sub_state.global;
+      ss->global.did_newpara = FALSE;
+    }
+}
+
+static void
+gnome_textfu_text_free_region_info(TextRegionInfo *info, GnomeTextFu *textfu)
+{
+  gdk_region_destroy(info->region);
+  g_free(info);
+}
+
+static void
+gnome_textfu_text_free_region(GnomeTextFu *textfu, TextRegionInfo *info)
+{
+  textfu->link_regions = g_list_remove(textfu->link_regions, info);
+
+  gnome_textfu_text_free_region_info(info, textfu);
+}
+
+static void
+gnome_textfu_text_free_regions(GnomeTextFu *textfu)
+{
+  g_list_foreach(textfu->link_regions, (GFunc)gnome_textfu_text_free_region_info, textfu);
+  g_list_free(textfu->link_regions);
+  textfu->link_regions = NULL;
+}
+
+static void
+gnome_textfu_text_set_region(GnomeTextFu *textfu, GnomeTextFuItemText *item, char *link_to, GdkRegion *region)
+{
+  TextRegionInfo *info = NULL;
+
+  if(item->link_region != NULL)
+    gnome_textfu_text_free_region(textfu, item->link_region);
+
+  if(link_to)
+    {
+      info = g_new(TextRegionInfo, 1);
+
+      info->region = region;
+      info->link_to = link_to;
+      textfu->link_regions = g_list_prepend(textfu->link_regions, info);
+    }
+
+  item->link_region = info;
+}
+
+#define REGION_ADD_RECT(rx, ry, rwidth, rheight)		\
+	{							\
+		GdkRectangle rect;				\
+		rect.x = rx;					\
+		rect.y = ry;					\
+		rect.width = rwidth;				\
+		rect.height = rheight;				\
+		gdk_region_union_with_rect(link_region, &rect);	\
+	}
+
+static void
+gnome_textfu_text_determine_size(GnomeTextFu *textfu, GnomeTextFuItemText *item, SizingState *ss)
+{
+  GdkFont *font;
+  gint lbearing, rbearing, width, ascent, descent;
+  gint space_left;
+  char *remaining_text;
+  GdkGC *gc = NULL;
+  double avg_width;
+  GdkDrawable *outwin;
+  gint remaining_len;
+  GdkGCValues vals;
+  GdkGCValuesMask mask = 0;
+  GdkRegion *link_region = NULL;
+
+  outwin = GTK_LAYOUT(textfu)->bin_window;
+  if(ss->global.drawing)
+    {
+      if(ss->link_to)
+	{
+	  mask |= GDK_GC_FOREGROUND;
+	  vals.foreground.red = 20 << 8;
+	  vals.foreground.green = 20 << 8;
+	  vals.foreground.blue = 65535;
+
+	  gdk_colormap_alloc_color(gdk_rgb_get_cmap(), &vals.foreground, TRUE, TRUE);
+
+	  link_region = gdk_region_new();
+	}
+
+      gc = gdk_gc_new_with_values(outwin, &vals, mask);
+    }
+
+  font = gnome_textfu_get_font(textfu, (GnomeTextFuItem *)item, ss);
+
+  g_return_if_fail(font);
+
+  remaining_text = item->text;
+
+  if(ss->newpara)
+    while(*remaining_text && my_isspace(*remaining_text)) remaining_text++;
+
+  if(!*remaining_text)
+    return; /* Nothing to draw */
+    
+  remaining_len = strlen(remaining_text);
+  gdk_string_extents(font, remaining_text, &lbearing, &rbearing, &width, NULL, NULL);
+  ascent = ss->ascent;
+  descent = ss->descent;
+
+  avg_width = width;
+  avg_width /= strlen(remaining_text);
+  ss->global.line_height = MAX(ss->global.line_height, ascent + descent + LINE_SPACING);
+  space_left = (textfu->width - ss->right_indent) - ss->global.xpos;
+
+  while((width > space_left) && (remaining_len > 0))
+    {
+      int chunklen;
+
+      space_left = (textfu->width - ss->right_indent) - ss->global.xpos;
+      chunklen = (int) (((double)space_left)/avg_width);
+      while(!my_isspace(remaining_text[chunklen]) && chunklen > 0) chunklen--;
+      if(chunklen <= 0) /* try over-shooting instead */
+	{
+	  chunklen = space_left/avg_width; 
+	  while(!my_isspace(remaining_text[chunklen]) && (chunklen < remaining_len)) chunklen++;
+	}
+      if(chunklen <= 0)
+	chunklen = space_left/avg_width;
+      if(chunklen <= 0)
+	goto out; /* It's hopeless */
+
+      if(ss->global.drawing)
+	{
+	  gint x, y, width, height;
+
+	  height = ascent + descent + LINE_SPACING;
+	  width = gdk_text_width(font, remaining_text, chunklen);
+	  x = ss->global.xpos;
+	  y = ss->global.ypos + ss->global.line_height - height;
+
+	  if(gnome_textfu_draw_translate(textfu, ss, &x, &y, width, height))
+	    {
+	      y += height;
+	      gdk_draw_text(outwin, font, gc, x, y, remaining_text, chunklen);
+
+	      if(ss->link_to)
+		{
+		  gdk_draw_line(outwin, gc, x, y + 1, x + width, y + 1);
+
+		  x = ss->global.xpos;
+		  y = ss->global.ypos + ss->global.line_height - height;
+		  REGION_ADD_RECT(x, y, width, height+1);
+		}
+	    }
+	}
+      remaining_text += chunklen;
+      remaining_len -= chunklen;
+      while(*remaining_text && my_isspace(*remaining_text))
+	{
+	  remaining_text++;
+	  remaining_len--;
+	}
+
+      gdk_string_extents(font, remaining_text, &lbearing, &rbearing, &width, NULL, NULL);
+      space_left = (textfu->width - ss->right_indent) - ss->global.xpos;
+      ss->global.xpos = ss->left_indent;
+      ss->global.ypos += ss->global.line_height;
+      ss->global.line_height = ascent + descent + LINE_SPACING;
+    }
+
+  {
+      gint x, y, width, height;
+
+      height = ascent + descent + LINE_SPACING;
+      width = gdk_string_width(font, remaining_text);
+
+      x = ss->global.xpos;
+      y = ss->global.ypos + ss->global.line_height - height;
+
+      if(ss->global.drawing)
+	{
+	  if(gnome_textfu_draw_translate(textfu, ss, &x, &y, width, height))
+	    {
+	      y += height;
+	      gdk_draw_string(outwin, font, gc, x, y, remaining_text);
+
+	      if(ss->link_to)
+		{
+		  gdk_draw_line(outwin, gc, x, y + 1, x + width, y + 1);
+
+		  x = ss->global.xpos;
+		  y = ss->global.ypos + ss->global.line_height - height;
+		  REGION_ADD_RECT(x, y, width, height+1);
+		}
+	    }
+	}
+
+      ss->global.xpos += width;
+
+    }
+
+ out:
+  if(ss->global.drawing)
+    {
+      gdk_gc_unref(gc);
+
+      if(ss->link_to)
+	{
+	  gdk_colormap_free_colors(gdk_rgb_get_cmap(), &vals.foreground, 1);
+	  gnome_textfu_text_set_region(textfu, item, ss->link_to, link_region);
+	}
+    }
+}
+
+static void
+gnome_textfu_widget_determine_size(GnomeTextFu *textfu, GnomeTextFuItemWidget *item, SizingState *ss)
+{
+  GnomeTextFuItemWidget *eitem = item;
+  gint last_xpos, last_ypos;
+
+  if((ss->global.xpos + eitem->widget->requisition.width) > textfu->width)
+    {
+      ss->global.xpos = ss->left_indent;
+      ss->global.ypos += ss->global.line_height;
+    }
+
+  eitem->item.x = ss->global.xpos;
+  eitem->item.y = ss->global.ypos;
+
+  if(ss->global.reposition && !ss->global.drawing)
+    {
+      last_xpos = eitem->last_xpos;
+      last_ypos = eitem->last_ypos;
+      if(last_xpos != ss->global.xpos || last_ypos != ss->global.ypos)
+	{
+	  gtk_layout_move(GTK_LAYOUT(textfu), eitem->widget, ss->global.xpos, ss->global.ypos);
+
+	  eitem->last_xpos = ss->global.xpos;
+	  eitem->last_ypos = ss->global.ypos;
+	}
+    }
+  ss->global.xpos += eitem->widget->requisition.width;
+  ss->global.line_height = MAX(ss->global.line_height, eitem->widget->requisition.height);
+  ss->global.did_newpara = FALSE;
+}
+
+static void
+gnome_textfu_item_determine_size(GnomeTextFu *textfu, GnomeTextFuItem *item, SizingState *ss)
+{
+  switch(item->type)
+    {
+    case TEXTFU_ITEM_CONTAINER:
+      gnome_textfu_container_determine_size(textfu, (GnomeTextFuItemContainer *)item, ss);
+      break;
+    case TEXTFU_ITEM_TEXT:
+      gnome_textfu_text_determine_size(textfu, (GnomeTextFuItemText *)item, ss);
+      break;
+    case TEXTFU_ITEM_WIDGET:
+      gnome_textfu_widget_determine_size(textfu, (GnomeTextFuItemWidget *)item, ss);
+      break;
+    default:
+      g_assert_not_reached();
+      break;
+    }
+}
+
+static void
+gnome_textfu_determine_size(GnomeTextFu *textfu, GtkRequisition *requisition, gboolean do_drawing)
+{
+  SizingState ss;
+  gint real_textfu_width;
+
+  memset(&ss, 0, sizeof(ss));
+
+  ss.global.drawing = do_drawing;
+
+  /* Top margin */
+  ss.global.ypos = 10;
+
+  real_textfu_width = textfu->width;
+
+  if(requisition)
+    {
+      textfu->width = gdk_screen_width()/5;
+    }
+  ss.global.reposition = requisition?FALSE:TRUE;
+
+  gnome_textfu_item_determine_size(textfu, textfu->item_tree, &ss);
+
+  /* Bottom margin */
+  ss.global.ypos += 10;
+
+  if(requisition)
+    {
+      requisition->width = textfu->width;
+      requisition->height = ss.global.ypos + ss.global.line_height;
+    }
+
+  textfu->width = real_textfu_width;
+}
+
+static void
+gnome_textfu_size_request(GtkWidget      *widget,
+			  GtkRequisition *requisition)
+{
+  GnomeTextFu *textfu;
+
+  textfu = GNOME_TEXTFU(widget);
+
+  GNOME_CALL_PARENT_HANDLER (GTK_WIDGET_CLASS,
+			     size_request,
+			     (widget, requisition));
+
+  if(textfu->item_tree)
+    {
+      GtkRequisition my_requisition;
+
+      gnome_textfu_determine_size(textfu, &my_requisition, FALSE);
+
+      requisition->width = MAX(requisition->width, my_requisition.width);
+      requisition->height = MAX(requisition->height, my_requisition.height);
+    }
+}
+
+static void
+gnome_textfu_size_allocate(GtkWidget      *widget,
+			   GtkAllocation  *allocation)
+{
+  GnomeTextFu *textfu;
+
+  textfu = GNOME_TEXTFU(widget);
+
+  GNOME_CALL_PARENT_HANDLER (GTK_WIDGET_CLASS,
+			     size_allocate,
+			     (widget, allocation));
+
+  if(textfu->width != allocation->width)
+    {
+      textfu->width = allocation->width;
+
+      gnome_textfu_determine_size(textfu, NULL, FALSE);
+
+      gtk_widget_queue_draw(widget);
+    }
+}
+
+static gint
+gnome_textfu_expose(GtkWidget      *widget, 
+		    GdkEventExpose *event)
+{
+  GNOME_CALL_PARENT_HANDLER (GTK_WIDGET_CLASS,
+			     expose_event,
+			     (widget, event));
+
+  gnome_textfu_determine_size(GNOME_TEXTFU(widget), NULL, TRUE);
+
+  return TRUE;
+}
+
+static void
+parse_tag(char *tag_start, char *tag_end, char *tag_name, char **tag_attrs)
+{
+  char *ctmp, *attr_start;
+  int i;
+
+  ctmp = tag_start;
+  while(*ctmp && !my_isspace(*ctmp)) ctmp++;
+  if(my_isspace(*ctmp))
+    {
+      *ctmp = '\0';
+      ctmp++;
+    }
+
+  strcpy(tag_name, tag_start);
+  g_strdown(tag_name);
+
+  for(i = 0; *ctmp && (i < 32); i++)
+    {
+      attr_start = ctmp;
+      while(*ctmp && !my_isspace(*ctmp)) ctmp++;
+
+      tag_attrs[i] = attr_start;
+      if(*ctmp)
+	{
+	  *ctmp = '\0';
+	  ctmp++;
+	}
+    }
+  tag_attrs[i] = NULL;
+}
+
+static void
+handle_tag(GnomeTextFu *textfu, GHashTable *tag_handlers,
+	   GnomeTextFuItem **stack, int *stack_cur,
+	   const char *tag_name, char **tag_attrs)
+{
+  TagRegistration *tr;
+  GnomeTextFuItem *new_item;
+
+  if(tag_name[0] == '/')
+    {
+      if(*stack_cur > 0)
+	(*stack_cur)--;
+      else
+	g_warning("Too many close tags %s", tag_name);
+      return;
+    }
+
+  tr = g_hash_table_lookup(tag_handlers, tag_name);
+  if(!tr)
+    {
+      g_warning("No handler for a %s tag", tag_name);
+      return;
+    }
+
+  new_item = tr->handler(textfu, tag_name, tr->tag_id, tag_attrs);
+
+  if(new_item)
+    {
+      GnomeTextFuItemContainer *container;
+      container = (GnomeTextFuItemContainer *)stack[*stack_cur];
+      container->children = g_slist_append(container->children, new_item);
+      new_item->up = (GnomeTextFuItem *)container;
+
+      switch(new_item->type)
+	{
+	case TEXTFU_ITEM_WIDGET:
+	  gtk_layout_put(GTK_LAYOUT(textfu), ((GnomeTextFuItemWidget *)new_item)->widget, 0, 0);
+	  break;
+	case TEXTFU_ITEM_CONTAINER:
+	  {
+	    container = (GnomeTextFuItemContainer *)new_item;
+	    if(container->subitems_italic == TEXTFU_UNKNOWN
+	       && container->subitems_bold == TEXTFU_UNKNOWN
+	       && container->subitems_font_size <= 0
+	       && !container->font_name
+	       && !container->link_to)
+	      container->inherited_font = TRUE;
+
+	    stack[++(*stack_cur)] = new_item;
+	  }
+	  break;
+	default:
+	  break;
+	}
+
+    }
+}
+
+static gpointer
+handle_text(GnomeTextFu *textfu, GnomeTextFuItem **stack, int stack_cur,
+	    char *text_start, char *text_end)
+{
+  GnomeTextFuItemContainer *container;
+  GnomeTextFuItemText *new_item;
+  char *ctmp, *space_start;
+
+  /* lame hack for getting rid of extra whitespace, oh well ;-) */
+
+  for(space_start = NULL, ctmp = text_start; ctmp < text_end; ctmp++)
+    {
+      if(my_isspace(*ctmp))
+	{
+	  if(!space_start)
+	    space_start = ctmp;
+	}
+      else if(space_start)
+	{
+	  int nmove = (ctmp - space_start) - 1;
+
+	  if(nmove > 0)
+	    {
+	      memmove(space_start + 1, ctmp, text_end - ctmp);
+	      text_end -= nmove;
+	      ctmp -= nmove;
+	    }
+
+	  space_start = NULL;
+	}
+    }
+  if(space_start)
+    {
+      int nmove = (ctmp - space_start) - 1;
+
+      if(nmove > 0)
+	{
+	  memmove(space_start + 1, ctmp, text_end - ctmp);
+	  text_end -= nmove;
+	  ctmp -= nmove;
+	}
+    }
+
+  if((text_end <= text_start) || !*text_start)
+    return NULL;
+
+  for(space_start = text_start; *space_start && my_isspace(*space_start); space_start++) /**/ ;
+
+  if(! *space_start) /* weed out text things that are just a newline */
+    return NULL;
+
+  new_item = g_malloc0(G_STRUCT_OFFSET(GnomeTextFuItemText, text) + (text_end - text_start) + 1);
+
+  new_item->item.type = TEXTFU_ITEM_TEXT;
+  strncpy(new_item->text, text_start, text_end - text_start);
+  new_item->text[text_end - text_start] = '\0';
+
+  container = (GnomeTextFuItemContainer *)stack[stack_cur];
+  container->children = g_slist_append(container->children, new_item);
+  new_item->item.up = (GnomeTextFuItem *)container;
+
+  return NULL;
+}
+
+static GnomeTextFuItem *
+gnome_textfu_parse(GnomeTextFu *textfu)
+{
+  int fd;
+  int bracecount, quotecount, in_comment;
+  struct stat sbuf;
+  char *mem = NULL, *tag_start = NULL, *tag_end, *text_start;
+  int size_left, n = 0;
+  char tag_name[32];
+  char *attrs[32]; /* Ick. Hardcoded maximum of 32 attributes */
+  GHashTable *tag_handlers;
+
+  GnomeTextFuItem *retval = NULL;
+  GnomeTextFuItemContainer *container;
+  GnomeTextFuItem *stack[1024];
+  int stack_cur = 0;
+
+  tag_handlers = GNOME_TEXTFU_GET_CLASS(textfu)->tag_handlers;
+
+  fd = open(textfu->cur_filename, O_RDONLY);
+  if(fd < 0)
+    return NULL;
+
+  fstat(fd, &sbuf);
+
+  mem = g_malloc(sbuf.st_size + 1);
+  size_left = sbuf.st_size;
+  while((size_left > 0) && (n = read(fd, mem + sbuf.st_size - size_left, size_left)) > 0)
+    size_left -= n;
+  if(n <= 0)
+    goto out;
+
+  retval = stack[0] = g_malloc0(sizeof(GnomeTextFuItemContainer));
+  container = ((GnomeTextFuItemContainer *)retval);
+  /* Set document defaults */
+  container->subitems_font_size = 0;
+  container->font_name = "helvetica";
+  container->subitems_left_indent = 10;
+  container->subitems_right_indent = 10;
+  container->subitems_newpara = TEXTFU_TRUE;
+  container->subitems_italic = TEXTFU_FALSE;
+  container->subitems_bold = TEXTFU_FALSE;
+  container->subitems_bullet = TEXTFU_FALSE;
+  container->inherited_font = FALSE;
+
+  stack_cur = 0;
+  retval->type = TEXTFU_ITEM_CONTAINER;
+
+  bracecount = quotecount = in_comment = 0;
+  text_start = NULL;
+  for(tag_end = mem; *tag_end; tag_end++)
+    {
+      switch(*tag_end)
+	{
+	case '<':
+	  if(in_comment || quotecount)
+	    break;
+
+	  if(!bracecount)
+	    {
+	      if(text_start)
+		{
+		  *tag_end = '\0';
+		  handle_text(textfu, stack, stack_cur, text_start, tag_end);
+		  *tag_end = '<';
+		  text_start = NULL;
+		}
+	      tag_start = tag_end;
+	    }
+	  if(!strncmp(tag_start, "<!", 2))
+	    in_comment++;
+	  else
+	    bracecount++;
+	  break;
+	case '>':
+	  if(!tag_start) /* just for sanity - George */
+	    break;
+	  if(!strncmp(tag_start, "<!", 2))
+	    {
+	      if(!strncmp(tag_end - 2, "-->", 3))
+		in_comment--;
+	      else
+		break; /* Ignore bogus comment termination */
+	    }
+
+	  if(in_comment || quotecount)
+	    break;
+
+	  bracecount--;
+	  if(!bracecount)
+	    {
+	      quotecount = 0;
+	      *tag_start = *tag_end = '\0';
+
+	      tag_start++;
+	      if(tag_start >= tag_end) /* Empty tag, ignore */
+		break;
+
+	      parse_tag(tag_start, tag_end, tag_name, attrs);
+	      handle_tag(textfu, tag_handlers, stack, &stack_cur, tag_name, attrs);
+	    }
+	  break;
+	case '"':
+	  if(bracecount)
+	    quotecount = !quotecount;
+	  break;
+	default:
+	  if(!text_start && !bracecount)
+	    text_start = tag_end;
+	  break;
+	}
+    }
+  if(text_start)
+    text_start = handle_text(textfu, stack, stack_cur, text_start, tag_end);
+
+ out:
+  g_free (mem);
+  close(fd);
+  return retval;
+}
+
+static void
+gnome_textfu_item_destroy(GnomeTextFuItem *textfu)
+{
+  if(textfu == NULL)
+    return;
+
+  switch(textfu->type)
+    {
+    case TEXTFU_ITEM_CONTAINER:
+      g_slist_foreach(((GnomeTextFuItemContainer *)textfu)->children, (GFunc)gnome_textfu_item_destroy, NULL);
+      g_slist_free(((GnomeTextFuItemContainer *)textfu)->children);
+      ((GnomeTextFuItemContainer *)textfu)->children = NULL;
+      break;
+    default:
+      break;
+    }
+  g_free(textfu);
+}
+
+static void
+dump_tree(GnomeTextFuItem *item, guint indent)
+{
+  int i;
+  for(i = 0; i < indent; i++)
+    g_print(" ");
+
+  switch(item->type)
+    {
+    case TEXTFU_ITEM_CONTAINER:
+      {
+	GSList *children = ((GnomeTextFuItemContainer *)item)->children;
+
+	g_print("CONTAINER: %d items\n", g_slist_length(children));
+	g_slist_foreach(children, (GFunc)dump_tree, GUINT_TO_POINTER(indent + 4));
+      }
+      break;
+    case TEXTFU_ITEM_WIDGET:
+      {
+	GnomeTextFuItemWidget *eitem = (GnomeTextFuItemWidget *)item;
+	g_print("WIDGET: %dx%d\n", eitem->widget->requisition.width, eitem->widget->requisition.height);
+      }
+      break;
+    case TEXTFU_ITEM_TEXT:
+      {
+	GnomeTextFuItemText *titem = (GnomeTextFuItemText *)item;
+	g_print("TEXT: %16.16s%s\n", titem->text, (strlen(titem->text) > 16)?"...":"");
+      }
+      break;
+    default:
+      break;
+    }
+}
+
+void
+gnome_textfu_load_file(GnomeTextFu *textfu, const char *filename)
+{
+  g_return_if_fail (textfu != NULL);
+  g_return_if_fail (GNOME_IS_TEXTFU (textfu));
+
+  /* out with old */
+  gnome_textfu_item_destroy(textfu->item_tree);
+  textfu->item_tree = NULL;
+
+  gnome_textfu_text_free_regions(textfu);
+
+  g_free(textfu->cur_filename);
+
+  /* in with new */
+  textfu->cur_filename = g_strdup(filename);
+  textfu->item_tree = gnome_textfu_parse(textfu);
+  dump_tree(textfu->item_tree, 0);
+}
+
+guint16
+gnome_textfu_tagid_alloc(const char *name, GnomeTextFuTagHandler handler)
+{
+  GnomeTextFuClass *klass;
+  TagRegistration *cur_reg, *new_reg;
+  static guint16 tag_counter = 1;
+
+  klass = GNOME_TEXTFU_CLASS(gtk_type_class(gnome_textfu_get_type()));
+
+  cur_reg = g_hash_table_lookup(klass->tag_handlers, name);
+  if(cur_reg)
+    return 0;
+
+  new_reg = g_malloc(G_STRUCT_OFFSET(TagRegistration, tag_name) + strlen(name) + 1);
+  new_reg->handler = handler;
+  new_reg->tag_id = tag_counter++;
+  strcpy(new_reg->tag_name, name);
+  g_strdown(new_reg->tag_name);
+  g_hash_table_insert(klass->tag_handlers, new_reg->tag_name, new_reg);
+
+  return new_reg->tag_id;
+}
diff --git a/libgnomeui/gnome-textfu.h b/libgnomeui/gnome-textfu.h
new file mode 100644
index 0000000..df51352
--- /dev/null
+++ b/libgnomeui/gnome-textfu.h
@@ -0,0 +1,139 @@
+/* gnome-textfu.h
+ * Copyright (C) 2000 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+*/
+#ifndef __GNOME_TEXTFU_H__
+#define __GNOME_TEXTFU_H__
+
+#include <gtk/gtk.h>
+
+#ifdef __cplusplus
+extern "C" {
+#pragma }
+#endif /* __cplusplus */
+
+#define GNOME_TYPE_TEXTFU			(gnome_textfu_get_type ())
+#define GNOME_TEXTFU(obj)			(GTK_CHECK_CAST ((obj), GNOME_TYPE_TEXTFU, GnomeTextFu))
+#define GNOME_TEXTFU_CLASS(klass)		(GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_TEXTFU, GnomeTextFuClass))
+#define GNOME_IS_TEXTFU(obj)			(GTK_CHECK_TYPE ((obj), GNOME_TYPE_TEXTFU))
+#define GNOME_IS_TEXTFU_CLASS(klass)		(GTK_CHECK_CLASS_TYPE ((obj), GNOME_TYPE_TEXTFU))
+#define GNOME_TEXTFU_GET_CLASS(obj)             (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_TEXTFU, GnomeTextFuClass))
+
+
+typedef enum {
+  TEXTFU_ITEM_TEXT,
+  TEXTFU_ITEM_CONTAINER,
+  TEXTFU_ITEM_WIDGET
+} GnomeTextFuItemType;
+
+typedef struct _GnomeTextFuItem GnomeTextFuItem;
+
+struct _GnomeTextFuItem {
+  GnomeTextFuItem *up;
+  GnomeTextFuItemType type;
+  guint16 x, y;
+};
+
+typedef struct {
+  GnomeTextFuItem item;
+
+  gpointer link_region;
+
+  char text[1];
+} GnomeTextFuItemText;
+
+typedef enum {
+  TEXTFU_FALSE,
+  TEXTFU_TRUE,
+  TEXTFU_UNKNOWN
+} GnomeTextFuTruthValue;
+
+typedef struct {
+  GnomeTextFuItem item;
+
+  GSList *children;
+
+  /* For use to modify various specific subitems that we might encounter */
+
+  char *link_to, *font_name;
+
+  GdkFont *font; /* internal */
+
+  gint8 subitems_font_size, subitems_left_indent, subitems_right_indent;
+  
+  GnomeTextFuTruthValue subitems_newpara : 2;
+  GnomeTextFuTruthValue subitems_italic : 2;
+  GnomeTextFuTruthValue subitems_bold : 2;
+  GnomeTextFuTruthValue subitems_bullet : 2;
+
+  gboolean subitems_ignore : 1;
+
+  gboolean inherited_font : 1; /* internal */
+} GnomeTextFuItemContainer;
+
+typedef struct {
+  GnomeTextFuItem item;
+
+  guint16 last_xpos, last_ypos;
+  GtkWidget *widget;
+} GnomeTextFuItemWidget;
+
+typedef struct _GnomeTextFu       GnomeTextFu;
+typedef struct _GnomeTextFuClass  GnomeTextFuClass;
+
+struct _GnomeTextFu
+{
+  GtkLayout parent;
+
+  /* All fields are private, don't touch */
+  char *cur_filename;
+
+  guint16 width;
+
+  GnomeTextFuItem *item_tree;
+  GList *link_regions;
+
+  gboolean linkpoint_cursor;
+};
+
+struct _GnomeTextFuClass
+{
+  GtkLayoutClass parent_class;
+
+  GHashTable *tag_handlers;
+
+  /* Signals go here */
+  void (*activate_uri)	(GnomeTextFu *textfu, const char *uri);
+};
+
+typedef GnomeTextFuItem * (*GnomeTextFuTagHandler)(GnomeTextFu *textfu, const char *tag, guint16 tag_id, char **attrs);
+
+GtkType    gnome_textfu_get_type   (void) G_GNUC_CONST;
+GtkWidget *gnome_textfu_new        (void);
+void       gnome_textfu_load_file  (GnomeTextFu *textfu, const char *filename);
+guint16    gnome_textfu_tagid_alloc(const char *name, GnomeTextFuTagHandler handler);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GNOME_TEXTFU_H__ */
diff --git a/libgnomeui/gnome-types.h b/libgnomeui/gnome-types.h
new file mode 100644
index 0000000..7a2432e
--- /dev/null
+++ b/libgnomeui/gnome-types.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#ifndef GNOME_TYPES_H
+#define GNOME_TYPES_H
+/****
+  Gnome-wide useful types.
+  ****/
+
+
+
+G_BEGIN_DECLS
+
+/* string is a g_malloc'd string which should be freed, or NULL if the
+   user cancelled. */
+typedef void (* GnomeStringCallback)(gchar * string, gpointer data); 
+
+/* See gnome-uidefs for the Yes/No Ok/Cancel defines which can be
+   "reply" */
+typedef void (* GnomeReplyCallback)(gint reply, gpointer data);
+
+/* Do something never, only when the user wants, or always. */
+typedef enum {
+  GNOME_PREFERENCES_NEVER,
+  GNOME_PREFERENCES_USER,
+  GNOME_PREFERENCES_ALWAYS
+} GnomePreferencesType;
+
+G_END_DECLS
+
+#endif
diff --git a/libgnomeui/gnome-ui-init.c b/libgnomeui/gnome-ui-init.c
new file mode 100644
index 0000000..d12de37
--- /dev/null
+++ b/libgnomeui/gnome-ui-init.c
@@ -0,0 +1,569 @@
+/* -*- Mode: C; tab-width: 8; c-basic-offset: 8; indent-tabs-mode: nil -*- */
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+/* Blame Elliot for most of this stuff*/
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
+#include <libgnome/libgnome.h>
+#include <libgnomeui/gnome-canvas-init.h>
+
+#include "gnome-client.h"
+#include "gnome-preferences.h"
+#include "gnome-init.h"
+#include "gnome-winhints.h"
+#include "gnome-gconf.h"
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include "gnome-pixmap.h"
+
+#include "libgnomeuiP.h"
+
+/*****************************************************************************
+ * libbonoboui
+ *****************************************************************************/
+
+static void
+libbonoboui_pre_args_parse (GnomeProgram *program, GnomeModuleInfo *mod_info)
+{
+        /* Initialize libbonoboui here.
+         *
+         * Attention: libbonobo has already been initialized from libgnome !
+         */
+}
+
+static void
+libbonoboui_post_args_parse (GnomeProgram *program, GnomeModuleInfo *mod_info)
+{
+        /* Initialize libbonoboui here.
+         *
+         * Attention: libbonobo has already been initialized from libgnome !
+         */
+}
+
+static GnomeModuleRequirement libbonoboui_requirements[] = {
+        /* libgnome already depends on libbonobo, so we need to depend on
+         * libgnome here as well to make sure the init functions are called
+         * in the correct order. */
+        { VERSION, &libgnome_module_info },
+        { NULL, NULL }
+};
+
+GnomeModuleInfo libbonoboui_module_info = {
+        "libbonoboui", VERSION, N_("Bonobo UI"),
+        libbonoboui_requirements, NULL,
+        libbonoboui_pre_args_parse, libbonoboui_post_args_parse,
+        NULL, NULL, NULL, NULL, NULL
+};
+
+/*****************************************************************************
+ * libgnomeui
+ *****************************************************************************/
+
+static void libgnomeui_arg_callback(poptContext con,
+                                    enum poptCallbackReason reason,
+                                    const struct poptOption * opt,
+                                    const char * arg, void * data);
+static void libgnomeui_init_pass(const GnomeModuleInfo *mod_info);
+static void libgnomeui_class_init(GnomeProgramClass *klass, const GnomeModuleInfo *mod_info);
+static void libgnomeui_instance_init(GnomeProgram *program, GnomeModuleInfo *mod_info);
+static void libgnomeui_pre_args_parse(GnomeProgram *app, GnomeModuleInfo *mod_info);
+static void libgnomeui_post_args_parse(GnomeProgram *app, GnomeModuleInfo *mod_info);
+static void libgnomeui_rc_parse (gchar *command);
+static GdkPixmap *libgnomeui_pixbuf_image_loader(GdkWindow   *window,
+                                                 GdkColormap *colormap,
+                                                 GdkBitmap  **mask,
+                                                 GdkColor    *transparent_color,
+                                                 const char *filename);
+static void libgnomeui_segv_setup(gboolean post_arg_parse);
+
+static GnomeModuleRequirement libgnomeui_requirements[] = {
+        {VERSION, &libgnome_module_info},
+        {VERSION, &libgnomecanvas_module_info},
+        {VERSION, &libbonoboui_module_info},
+        {NULL, NULL}
+};
+
+enum { ARG_DISABLE_CRASH_DIALOG=1, ARG_DISPLAY };
+
+static struct poptOption libgnomeui_options[] = {
+        {NULL, '\0', POPT_ARG_INTL_DOMAIN, PACKAGE, 0, NULL, NULL},
+	{NULL, '\0', POPT_ARG_CALLBACK|POPT_CBFLAG_PRE|POPT_CBFLAG_POST,
+	 &libgnomeui_arg_callback, 0, NULL, NULL},
+	{"disable-crash-dialog", '\0', POPT_ARG_NONE, NULL, ARG_DISABLE_CRASH_DIALOG},
+        {"display", '\0', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, NULL, ARG_DISPLAY,
+         N_("X display to use"), N_("DISPLAY")},
+	{NULL, '\0', 0, NULL, 0}
+};
+
+GnomeModuleInfo libgnomeui_module_info = {
+        "libgnomeui", VERSION, "GNOME GUI Library",
+        libgnomeui_requirements, libgnomeui_instance_init,
+        libgnomeui_pre_args_parse, libgnomeui_post_args_parse,
+        libgnomeui_options,
+        libgnomeui_init_pass, libgnomeui_class_init,
+        NULL, NULL
+};
+
+typedef struct {
+        guint crash_dialog_id;
+        guint display_id;
+        guint default_icon_id;
+} GnomeProgramClass_libgnomeui;
+
+typedef struct {
+        gboolean constructed;
+} GnomeProgramPrivate_libgnomeui;
+
+static GQuark quark_gnome_program_private_libgnomeui = 0;
+static GQuark quark_gnome_program_class_libgnomeui = 0;
+
+static void
+libgnomeui_get_property (GObject *object, guint param_id, GValue *value,
+                         GParamSpec *pspec)
+{
+        GnomeProgramClass_libgnomeui *cdata;
+        GnomeProgramPrivate_libgnomeui *priv;
+        GnomeProgram *program;
+
+        g_return_if_fail(object != NULL);
+        g_return_if_fail(GNOME_IS_PROGRAM (object));
+
+        program = GNOME_PROGRAM(object);
+
+        cdata = g_type_get_qdata(G_OBJECT_TYPE(program), quark_gnome_program_class_libgnomeui);
+        priv = g_object_get_qdata(G_OBJECT(program), quark_gnome_program_private_libgnomeui);
+
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
+}
+
+static void
+libgnomeui_set_property (GObject *object, guint param_id,
+                         const GValue *value, GParamSpec *pspec)
+{
+        GnomeProgramClass_libgnomeui *cdata;
+        GnomeProgramPrivate_libgnomeui *priv;
+        GnomeProgram *program;
+
+        g_return_if_fail(object != NULL);
+        g_return_if_fail(GNOME_IS_PROGRAM (object));
+
+        program = GNOME_PROGRAM(object);
+
+        cdata = g_type_get_qdata(G_OBJECT_TYPE(program), quark_gnome_program_class_libgnomeui);
+        priv = g_object_get_qdata(G_OBJECT(program), quark_gnome_program_private_libgnomeui);
+
+        switch(param_id) {
+        default:
+                g_message(G_STRLOC);
+                G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
+                break;
+        }
+}
+
+static void
+libgnomeui_init_pass (const GnomeModuleInfo *mod_info)
+{
+    if (!quark_gnome_program_private_libgnomeui)
+	quark_gnome_program_private_libgnomeui = g_quark_from_static_string
+	    ("gnome-program-private:libgnomeui");
+
+    if (!quark_gnome_program_class_libgnomeui)
+	quark_gnome_program_class_libgnomeui = g_quark_from_static_string
+	    ("gnome-program-class:libgnomeui");
+}
+
+static void
+libgnomeui_class_init (GnomeProgramClass *klass, const GnomeModuleInfo *mod_info)
+{
+        GnomeProgramClass_libgnomeui *cdata = g_new0 (GnomeProgramClass_libgnomeui, 1);
+
+        g_type_set_qdata (G_OBJECT_CLASS_TYPE (klass), quark_gnome_program_class_libgnomeui, cdata);
+
+        cdata->crash_dialog_id = gnome_program_install_property (
+                klass,
+                libgnomeui_get_property,
+                libgnomeui_set_property,
+                g_param_spec_boolean (LIBGNOMEUI_PARAM_CRASH_DIALOG, NULL, NULL,
+                                      TRUE, (G_PARAM_READABLE | G_PARAM_WRITABLE |
+                                             G_PARAM_CONSTRUCT_ONLY)));
+        cdata->display_id = gnome_program_install_property (
+                klass,
+                libgnomeui_get_property,
+                libgnomeui_set_property,
+                g_param_spec_string (LIBGNOMEUI_PARAM_DISPLAY, NULL, NULL, NULL,
+                                     (G_PARAM_READABLE | G_PARAM_WRITABLE |
+                                      G_PARAM_CONSTRUCT_ONLY)));
+
+        cdata->default_icon_id = gnome_program_install_property (
+                klass,
+                libgnomeui_get_property,
+                libgnomeui_set_property,
+                g_param_spec_string (LIBGNOMEUI_PARAM_DEFAULT_ICON, NULL, NULL, NULL,
+                                     (G_PARAM_READABLE | G_PARAM_WRITABLE |
+                                      G_PARAM_CONSTRUCT_ONLY)));
+}
+
+static void
+libgnomeui_instance_init (GnomeProgram *program, GnomeModuleInfo *mod_info)
+{
+    GnomeProgramPrivate_libgnomeui *priv = g_new0 (GnomeProgramPrivate_libgnomeui, 1);
+
+    g_object_set_qdata (G_OBJECT (program), quark_gnome_program_private_libgnomeui, priv);
+}
+
+static void
+libgnomeui_pre_args_parse(GnomeProgram *app, GnomeModuleInfo *mod_info)
+{
+        gboolean ctype_set;
+        char *ctype, *old_ctype = NULL;
+        gboolean do_crash_dialog = TRUE;
+        const char *envar;
+
+        envar = g_getenv("GNOME_DISABLE_CRASH_DIALOG");
+        if(envar)
+                do_crash_dialog = atoi(envar)?FALSE:TRUE;
+        g_object_set (G_OBJECT(app), LIBGNOMEUI_PARAM_CRASH_DIALOG,
+                      do_crash_dialog, LIBGNOMEUI_PARAM_DISPLAY,
+                      g_getenv("DISPLAY"), NULL);
+
+        if(do_crash_dialog)
+                libgnomeui_segv_setup(FALSE);
+
+        /* Begin hack to propogate an en_US locale into Gtk+ if LC_CTYPE=C, so that non-ASCII
+           characters will display for as many people as possible. Related to bug #1979 */
+        ctype = setlocale (LC_CTYPE, NULL);
+
+        if (!strcmp(ctype, "C")) {
+                old_ctype = g_strdup (g_getenv ("LC_CTYPE"));
+                putenv ("LC_CTYPE=en_US");
+                ctype_set = TRUE;
+        } else
+                ctype_set = FALSE;
+
+        gtk_set_locale ();
+
+        if (ctype_set) {
+                char *setme;
+
+                if (old_ctype) {
+                        setme = g_strconcat ("LC_CTYPE=", old_ctype, NULL);
+                        g_free(old_ctype);
+                } else
+                        setme = "LC_CTYPE";
+
+                putenv (setme);
+        }
+        /* End hack */
+}
+
+static void
+libgnomeui_post_args_parse(GnomeProgram *program, GnomeModuleInfo *mod_info)
+{
+        GnomeProgramPrivate_libgnomeui *priv = g_new0(GnomeProgramPrivate_libgnomeui, 1);
+
+        gnome_type_init();
+        gtk_rc_set_image_loader(libgnomeui_pixbuf_image_loader);
+        libgnomeui_rc_parse(program_invocation_name);
+        gnome_preferences_load();
+
+        libgnomeui_segv_setup(TRUE);
+
+        priv = g_object_get_qdata(G_OBJECT(program), quark_gnome_program_private_libgnomeui);
+        priv->constructed = TRUE;
+}
+
+static void
+libgnomeui_arg_callback(poptContext con,
+                        enum poptCallbackReason reason,
+                        const struct poptOption * opt,
+                        const char * arg, void * data)
+{
+        GnomeProgram *program = gnome_program_get ();
+
+        switch(reason) {
+        case POPT_CALLBACK_REASON_OPTION:
+                switch(opt->val) {
+                case ARG_DISABLE_CRASH_DIALOG:
+                        g_object_set (G_OBJECT (program),
+                                      LIBGNOMEUI_PARAM_CRASH_DIALOG,
+                                      FALSE, NULL);
+                        break;
+                case ARG_DISPLAY:
+                        g_object_set (G_OBJECT (program),
+                                      LIBGNOMEUI_PARAM_DISPLAY,
+                                      arg, NULL);
+                        break;
+                }
+                break;
+        default:
+                break;
+        }
+}
+
+/* automagically parse all the gtkrc files for us.
+ * 
+ * Parse:
+ * $gnomedatadir/gtkrc
+ * $gnomedatadir/$apprc
+ * ~/.gnome/gtkrc
+ * ~/.gnome/$apprc
+ *
+ * appname is derived from argv[0].  IMHO this is a great solution.
+ * It provides good consistancy (you always know the rc file will be
+ * the same name as the executable), and it's easy for the programmer.
+ * 
+ * If you don't like it.. give me a good reason.  Symlin
+ */
+static void
+libgnomeui_rc_parse (gchar *command)
+{
+	gint i;
+	gint buf_len;
+	gchar *buf = NULL;
+	gchar *file;
+	gchar *apprc;
+	
+	buf_len = strlen(command);
+	
+	for (i = 0; i < buf_len; i++) {
+		if (command[buf_len - i] == '/') {
+			buf = &command[buf_len - i + 1];
+			break;
+		}
+	}
+	
+	if (!buf)
+                buf = command;
+
+        apprc = g_alloca (strlen(buf) + 4);
+	sprintf(apprc, "%src", buf);
+	
+	/* <gnomedatadir>/gtkrc */
+        file = gnome_program_locate_file (gnome_program_get (),
+                                          GNOME_FILE_DOMAIN_DATADIR,
+                                          "gtkrc", TRUE, NULL);
+  	if (file) {
+  		gtk_rc_add_default_file (file); 
+		g_free (file);
+	}
+
+	/* <gnomedatadir>/<progname> */
+        file = gnome_program_locate_file (gnome_program_get (),
+                                          GNOME_FILE_DOMAIN_DATADIR,
+                                          apprc, TRUE, NULL);
+	if (file) {
+                gtk_rc_add_default_file (file);
+                g_free (file);
+        }
+	
+	/* ~/.gnome/gtkrc */
+	file = gnome_util_home_file("gtkrc");
+	if (file) {
+		gtk_rc_add_default_file (file);
+		g_free (file);
+	}
+	
+	/* ~/.gnome/<progname> */
+	file = gnome_util_home_file(apprc);
+	if (file) {
+		gtk_rc_add_default_file (file);
+		g_free (file);
+	}
+
+	gtk_rc_init ();
+}
+
+static GdkPixmap *
+libgnomeui_pixbuf_image_loader(GdkWindow   *window,
+                               GdkColormap *colormap,
+                               GdkBitmap  **maskp,
+                               GdkColor    *transparent_color,
+                               const char *filename)
+{
+	GdkPixmap *retval = NULL;
+        GdkBitmap *mask = NULL;
+        GdkPixbuf *pixbuf;
+        GError *error;
+
+        /* FIXME we are ignoring colormap and transparent color */
+        
+        error = NULL;
+        pixbuf = gdk_pixbuf_new_from_file(filename, &error);
+        if (error != NULL) {
+                g_warning (G_STRLOC ": cannot load %s: %s", filename,
+                           error->message);
+                g_error_free (error);
+        }
+
+        if (pixbuf == NULL)
+                return NULL;
+
+        gdk_pixbuf_render_pixmap_and_mask(pixbuf, &retval, &mask, 128);
+
+        gdk_pixbuf_unref(pixbuf);
+        
+        if (maskp)
+                *maskp = mask;
+        else
+                gdk_bitmap_unref(mask);
+
+        return retval;
+}
+
+/* crash handler */
+static void libgnomeui_segv_handle(int signum);
+
+static void
+libgnomeui_segv_setup(gboolean post_arg_parse)
+{
+        static struct sigaction *setptr;
+        struct sigaction sa;
+        gboolean do_crash_dialog = TRUE;
+        GValue value = { 0, };
+
+        g_value_init (&value, G_TYPE_BOOLEAN);
+        g_object_get_property (G_OBJECT (gnome_program_get()),
+                               LIBGNOMEUI_PARAM_CRASH_DIALOG, &value);
+        do_crash_dialog = g_value_get_boolean (&value);
+        g_value_unset (&value);
+
+        memset(&sa, 0, sizeof(sa));
+
+        setptr = &sa;
+        if(do_crash_dialog) {
+                sa.sa_handler = (gpointer)libgnomeui_segv_handle;
+        } else {
+                sa.sa_handler = SIG_DFL;
+        }
+
+        sigaction(SIGSEGV, setptr, NULL);
+        sigaction(SIGFPE, setptr, NULL);
+        sigaction(SIGBUS, setptr, NULL);
+}
+
+static void libgnomeui_segv_handle(int signum)
+{
+	static int in_segv = 0;
+	pid_t pid;
+	
+	in_segv++;
+
+        if (in_segv > 2) {
+                /* The fprintf() was segfaulting, we are just totally hosed */
+                _exit(1);
+        } else if (in_segv > 1) {
+                /* dialog display isn't working out */
+                fprintf(stderr, _("Multiple segmentation faults occurred; can't display error dialog\n"));
+                _exit(1);
+        }
+
+        /* Make sure we release grabs */
+        gdk_pointer_ungrab(GDK_CURRENT_TIME);
+        gdk_keyboard_ungrab(GDK_CURRENT_TIME);
+
+        gdk_flush();
+        
+	if ((pid = fork())) {
+                /* Wait for user to see the dialog, then exit. */
+                /* Why wait at all? Because we want to allow people to attach to the
+		   process */
+		int estatus;
+		pid_t eret;
+
+		eret = waitpid(pid, &estatus, 0);
+
+                /* Don't use app attributes here - a lot of things are probably hosed */
+		if(g_getenv("GNOME_DUMP_CORE"))
+	                abort ();
+
+		_exit(1);
+	} else {
+                GnomeProgram *program;
+		char buf[32];
+
+		g_snprintf(buf, sizeof(buf), "%d", signum);
+
+                program = gnome_program_get();
+
+		/* Child process */
+		execl(GNOMEUIBINDIR "/gnome_segv", GNOMEUIBINDIR "/gnome_segv",
+		      gnome_program_get_name(program), buf, gnome_program_get_version(program), NULL);
+
+                execlp("gnome_segv", "gnome_segv", gnome_program_get_name(program), buf,
+                       gnome_program_get_version(program), NULL);
+
+                _exit(99);
+	}
+
+	in_segv--;
+}
+
+/* #warning "Solve the sound events situation" */
+
+/* backwards compat */
+int gnome_init_with_popt_table(const char *app_id,
+			       const char *app_version,
+			       int argc, char **argv,
+			       const struct poptOption *options,
+			       int flags,
+			       poptContext *return_ctx)
+{
+        gnome_program_init(app_id, app_version,
+                           &libgnomeui_module_info,
+                           argc, argv,
+                           GNOME_PARAM_POPT_TABLE, options,
+                           GNOME_PARAM_POPT_FLAGS, flags,
+                           NULL);
+
+        if(return_ctx) {
+                GValue value = { 0, };
+
+                g_value_init (&value, G_TYPE_POINTER);
+                g_object_get_property (G_OBJECT (gnome_program_get()),
+                                       GNOME_PARAM_POPT_CONTEXT, &value);
+                *return_ctx = g_value_peek_pointer (&value);
+                g_value_unset (&value);
+        }
+
+        return 0;
+}
+
+
diff --git a/libgnomeui/gnome-ui-init.h b/libgnomeui/gnome-ui-init.h
new file mode 100644
index 0000000..95e13c6
--- /dev/null
+++ b/libgnomeui/gnome-ui-init.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#ifndef GNOME_INIT_H
+#define GNOME_INIT_H
+
+G_BEGIN_DECLS
+
+#include <libgnome/gnome-program.h>
+
+#define LIBGNOMEUI_PARAM_CRASH_DIALOG	"show-crash-dialog"
+#define LIBGNOMEUI_PARAM_DISPLAY	"display"
+#define LIBGNOMEUI_PARAM_DEFAULT_ICON	"default-icon"
+
+extern GnomeModuleInfo libgnomeui_module_info;
+extern GnomeModuleInfo libbonoboui_module_info;
+
+/* The gnome_init define is in libgnomeui.h so it can be a macro */
+int gnome_init_with_popt_table(const char *app_id,
+			       const char *app_version,
+			       int argc, char **argv,
+			       const struct poptOption *options,
+			       int flags,
+			       poptContext *return_ctx);
+
+
+G_END_DECLS
+
+#endif
diff --git a/libgnomeui/gnome-uidefs.h b/libgnomeui/gnome-uidefs.h
new file mode 100644
index 0000000..b53c5ce
--- /dev/null
+++ b/libgnomeui/gnome-uidefs.h
@@ -0,0 +1,107 @@
+/* gnome-uidefs.h:
+ * Copyright (C) 1998 Havoc Pennington
+ * All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#ifndef GNOME_UIDEFS_H
+#define GNOME_UIDEFS_H
+
+/* This file defines standard sizes, spacings, and whatever
+   else seems standardizable via simple defines. */
+
+/* All-purpose padding. If you always use these instead of making up 
+   some arbitrary padding number that looks good on your screen, 
+   people can change the "spaciousness" of the GUI globally. */
+#define GNOME_PAD          8
+#define GNOME_PAD_SMALL    4
+#define GNOME_PAD_BIG      12
+
+/* These are the button numbers on a yes-no or ok-cancel GnomeDialog,
+   and in the gnome-app-util callbacks. Make the program more
+   readable, is all. */ 
+#define GNOME_YES 0 
+#define GNOME_NO 1 
+#define GNOME_OK 0
+#define GNOME_CANCEL 1
+
+#include <gdk/gdkkeysyms.h>
+
+/* These are keybindings, in GnomeUIInfo format. USE THEM OR DIE! 
+   Add to the list as well..
+*/
+#define GNOME_KEY_NAME_EXIT 	        'Q'
+#define GNOME_KEY_MOD_EXIT	        (GDK_CONTROL_MASK)
+#define GNOME_KEY_NAME_CLOSE 	        'W'
+#define	GNOME_KEY_MOD_CLOSE	        (GDK_CONTROL_MASK)
+
+#define GNOME_KEY_NAME_CUT 	        'X'
+#define GNOME_KEY_MOD_CUT 	        (GDK_CONTROL_MASK)
+#define GNOME_KEY_NAME_COPY	        'C'
+#define GNOME_KEY_MOD_COPY	        (GDK_CONTROL_MASK)
+#define GNOME_KEY_NAME_PASTE 	        'V'
+#define GNOME_KEY_MOD_PASTE 	        (GDK_CONTROL_MASK)
+#define GNOME_KEY_NAME_SELECT_ALL       0
+#define GNOME_KEY_MOD_SELECT_ALL        (0)
+#define GNOME_KEY_NAME_CLEAR 	        0
+#define GNOME_KEY_MOD_CLEAR 	        (0)
+
+#define GNOME_KEY_NAME_UNDO  	        'Z'
+#define GNOME_KEY_MOD_UNDO  	        (GDK_CONTROL_MASK)
+#define GNOME_KEY_NAME_REDO	        'R'
+#define GNOME_KEY_MOD_REDO	        (GDK_CONTROL_MASK)
+
+#define GNOME_KEY_NAME_SAVE	        'S'
+#define GNOME_KEY_MOD_SAVE	        (GDK_CONTROL_MASK)
+#define GNOME_KEY_NAME_OPEN	        GDK_F3
+#define GNOME_KEY_MOD_OPEN	        (0)
+#define GNOME_KEY_NAME_SAVE_AS	        0
+#define GNOME_KEY_MOD_SAVE_AS           (0)
+#define GNOME_KEY_NAME_NEW	        0
+#define GNOME_KEY_MOD_NEW	        (0)
+
+#define GNOME_KEY_NAME_PRINT            0
+#define GNOME_KEY_MOD_PRINT             (0)
+
+#define GNOME_KEY_NAME_PRINT_SETUP      0
+#define GNOME_KEY_MOD_PRINT_SETUP       (0)
+
+#define GNOME_KEY_NAME_FIND             GDK_F6
+#define GNOME_KEY_MOD_FIND              (0)
+#define GNOME_KEY_NAME_FIND_AGAIN       GDK_F6
+#define GNOME_KEY_MOD_FIND_AGAIN        (GDK_SHIFT_MASK)
+#define GNOME_KEY_NAME_REPLACE          GDK_F7
+#define GNOME_KEY_MOD_REPLACE           (0)
+
+#define GNOME_KEY_NAME_NEW_WINDOW       0
+#define GNOME_KEY_MOD_NEW_WINDOW        (0)
+#define GNOME_KEY_NAME_CLOSE_WINDOW     0
+#define GNOME_KEY_MOD_CLOSE_WINDOW      (0)
+
+#define GNOME_KEY_NAME_REDO_MOVE        'R'
+#define GNOME_KEY_MOD_REDO_MOVE         (GDK_CONTROL_MASK)
+#define GNOME_KEY_NAME_UNDO_MOVE        'Z'
+#define GNOME_KEY_MOD_UNDO_MOVE         (GDK_CONTROL_MASK)
+
+#define GNOME_KEY_NAME_PAUSE_GAME       0
+#define GNOME_KEY_MOD_PAUSE_GAME        (0)
+#define GNOME_KEY_NAME_NEW_GAME         'N'
+#define GNOME_KEY_MOD_NEW_GAME          (GDK_CONTROL_MASK)
+
+#endif
diff --git a/libgnomeui/gnome-unit-spinner.c b/libgnomeui/gnome-unit-spinner.c
new file mode 100644
index 0000000..71f3bd2
--- /dev/null
+++ b/libgnomeui/gnome-unit-spinner.c
@@ -0,0 +1,360 @@
+/* GNOME Unit spinner
+ * Copyright (C) 1999 James Henstridge <james daa com au>
+ * All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#include <ctype.h>
+
+#include "gnome-unit-spinner.h"
+#include "gdk/gdkkeysyms.h"
+
+static GtkObjectClass *parent_class;
+static GtkObjectClass *entry_class;
+
+static const GnomeUnit *default_unit = NULL;
+
+static void gnome_unit_spinner_class_init(GnomeUnitSpinnerClass *class);
+static void gnome_unit_spinner_init(GnomeUnitSpinner *self);
+
+GtkType
+gnome_unit_spinner_get_type(void)
+{
+  static GtkType us_type = 0;
+
+  if (!us_type) {
+    GtkTypeInfo us_info = {
+      "GnomeUnitSpinner",
+      sizeof(GnomeUnitSpinner),
+      sizeof(GnomeUnitSpinnerClass),
+      (GtkClassInitFunc) gnome_unit_spinner_class_init,
+      (GtkObjectInitFunc) gnome_unit_spinner_init,
+      NULL,
+      NULL,
+      NULL
+    };
+    us_type = gtk_type_unique(gtk_spin_button_get_type(), &us_info);
+  }
+  return us_type;
+}
+
+static void
+gnome_unit_spinner_value_changed(GtkAdjustment *adjustment,
+				 GnomeUnitSpinner *spinner)
+{
+  char buf[256];
+  GtkSpinButton *sbutton;
+
+  g_return_if_fail(adjustment != NULL);
+  g_return_if_fail(spinner != NULL);
+  g_return_if_fail(GNOME_IS_UNIT_SPINNER(spinner));
+
+  sbutton = GTK_SPIN_BUTTON(spinner);
+  g_snprintf(buf, sizeof(buf), "%0.*f%s", sbutton->digits,
+	     adjustment->value, gnome_unit_abbrev(spinner->adj_unit));
+
+  if (strcmp(buf, gtk_entry_get_text(GTK_ENTRY(spinner))))
+    gtk_entry_set_text(GTK_ENTRY(spinner), buf);
+}
+
+static gint gnome_unit_spinner_focus_out    (GtkWidget *widget,
+					     GdkEventFocus *ev);
+static gint gnome_unit_spinner_button_press (GtkWidget *widget,
+					     GdkEventButton *ev);
+static gint gnome_unit_spinner_key_press    (GtkWidget *widget,
+					     GdkEventKey *event);
+#if 0 /* FIXME */
+static void gnome_unit_spinner_activate     (GtkEditable *editable);
+#endif
+
+static void
+gnome_unit_spinner_class_init(GnomeUnitSpinnerClass *class)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+  GtkEditableClass *editable_class;
+
+  object_class = (GtkObjectClass *)class;
+  widget_class = (GtkWidgetClass *)class;
+  editable_class = (GtkEditableClass *)class;
+
+  widget_class->focus_out_event    = gnome_unit_spinner_focus_out;
+  widget_class->button_press_event = gnome_unit_spinner_button_press;
+  widget_class->key_press_event    = gnome_unit_spinner_key_press;
+#if 0 /* FIXME */
+  editable_class->activate         = gnome_unit_spinner_activate;
+#endif
+
+  parent_class = gtk_type_class(GTK_TYPE_SPIN_BUTTON);
+  entry_class  = gtk_type_class(GTK_TYPE_ENTRY);
+}
+
+static void
+gnome_unit_spinner_init(GnomeUnitSpinner *self)
+{
+  /* change over to our own print function that appends the unit name on the
+   * end */
+  if (self->parent.adjustment) {
+    gtk_signal_disconnect_by_data(GTK_OBJECT(self->parent.adjustment),
+				  (gpointer) self);
+    gtk_signal_connect(GTK_OBJECT(self->parent.adjustment), "value_changed",
+		       GTK_SIGNAL_FUNC(gnome_unit_spinner_value_changed),
+		       (gpointer) self);
+  }
+
+  if ( ! default_unit)
+    default_unit = gnome_unit_with_name("centimeter");
+
+  self->adj_unit = default_unit;
+}
+
+/**
+ * gnome_unit_spinner_new:
+ * @adjustment: the adjustment specifying the range of the spinner
+ * @digits: The number of decimal digits to display
+ * @adj_unit: the default unit for the spinner.
+ * 
+ * Creates a new GnomeUnitSpinner.  A GnomeUnitSpinner is basically a
+ * GtkSpinButton that displays the units the value is in terms of.  It
+ * also allows you to enter a value with a different unit suffix, and
+ * then convert the value to the correct set of units.
+ * 
+ * Return value: the new GnomeUnitSpinner.
+ **/
+GtkWidget *
+gnome_unit_spinner_new(GtkAdjustment *adjustment, guint digits,
+		       const GnomeUnit *adj_unit)
+{
+  GnomeUnitSpinner *self;
+
+  self = gtk_type_new(gnome_unit_spinner_get_type());
+
+  gnome_unit_spinner_construct(self, adjustment, digits, adj_unit);
+
+  return GTK_WIDGET(self);
+}
+
+/**
+ * gnome_unit_spinner_construct:
+ * @self: The object to construct
+ * @adjustment: the adjustment specifying the range of the spinner
+ * @digits: The number of decimal digits to display
+ * @adj_unit: the default unit for the spinner.
+ * 
+ * Constructor for language bindings or subclassing only, for C
+ * use #gnome_unit_spinner_new
+ **/
+void
+gnome_unit_spinner_construct(GnomeUnitSpinner *self,
+			     GtkAdjustment *adjustment, guint digits,
+			     const GnomeUnit *adj_unit)
+{
+  gtk_spin_button_configure(GTK_SPIN_BUTTON(self), adjustment, 0.0, digits);
+
+  if (adjustment) {
+    gtk_signal_disconnect_by_data(GTK_OBJECT(adjustment),
+				  (gpointer) self);
+    gtk_signal_connect(GTK_OBJECT(adjustment), "value_changed",
+		       GTK_SIGNAL_FUNC(gnome_unit_spinner_value_changed),
+		       (gpointer) self);
+  }
+
+  if (adj_unit)
+    self->adj_unit = adj_unit;
+}
+
+/**
+ * gnome_unit_spinner_set_value:
+ * @self: the GnomeUnitSpinner
+ * @val: the new value
+ * @unit: the units the new value is in, or NULL for the spinner's default.
+ * 
+ * Change the value of the GnomeUnitSpinner.
+ **/
+void
+gnome_unit_spinner_set_value(GnomeUnitSpinner *self, gfloat val,
+			     const GnomeUnit *unit)
+{
+  GtkSpinButton *sbutton;
+  gfloat adj_val;
+
+  g_return_if_fail(self != NULL);
+  g_return_if_fail(GNOME_IS_UNIT_SPINNER(self));
+
+  sbutton = GTK_SPIN_BUTTON(self);
+  if (unit) {
+    adj_val = gnome_unit_convert(val, unit, self->adj_unit);
+  } else {
+    unit = self->adj_unit;
+    adj_val = val;
+  }
+
+  if (adj_val < sbutton->adjustment->lower)
+    adj_val = sbutton->adjustment->lower;
+  else if (adj_val > sbutton->adjustment->upper)
+    adj_val = sbutton->adjustment->upper;
+  if (adj_val != sbutton->adjustment->value) {
+    sbutton->adjustment->value = adj_val;
+    gtk_adjustment_value_changed(sbutton->adjustment);
+  }
+}
+
+/**
+ * gnome_unit_spinner_get_value:
+ * @self: the GnomeUnitSpinner
+ * @unit: the unit you want the result in, or NULL for the spinner's default.
+ * 
+ * returns the value of the GnomeUnitSpinner in a particular set of units.
+ * 
+ * Return value: the value.
+ **/
+gfloat
+gnome_unit_spinner_get_value(GnomeUnitSpinner *self, const GnomeUnit *unit)
+{
+  GtkSpinButton *sbutton;
+
+  g_return_val_if_fail(self != NULL, 0);
+  g_return_val_if_fail(GNOME_IS_UNIT_SPINNER(self), 0);
+
+  sbutton = GTK_SPIN_BUTTON(self);
+  if (unit)
+    return gnome_unit_convert(sbutton->adjustment->value, self->adj_unit,
+			      unit);
+  else
+    return sbutton->adjustment->value;
+}
+
+/**
+ * gnome_unit_spinner_change_units:
+ * @self: the GnomeUnitSpinner
+ * @unit: the new set of units.
+ * 
+ * Changes the default set of units for the GnomeUnitSpinner.
+ **/
+void
+gnome_unit_spinner_change_units(GnomeUnitSpinner *self, const GnomeUnit *unit)
+{
+  GtkSpinButton *sbutton;
+  GtkAdjustment *adj;
+
+  g_return_if_fail(self != NULL);
+  g_return_if_fail(unit != NULL);
+
+  if (self->adj_unit == unit)
+    return;
+
+  sbutton = GTK_SPIN_BUTTON(self);
+  adj = sbutton->adjustment;
+  adj->lower = gnome_unit_convert(adj->lower, self->adj_unit, unit);
+  adj->upper = gnome_unit_convert(adj->upper, self->adj_unit, unit);
+  adj->value = gnome_unit_convert(adj->value, self->adj_unit, unit);
+  adj->step_increment = gnome_unit_convert(adj->step_increment,
+					   self->adj_unit, unit);
+  adj->page_increment = gnome_unit_convert(adj->page_increment,
+					   self->adj_unit, unit);
+  adj->page_size = gnome_unit_convert(adj->page_size, self->adj_unit, unit);
+  self->adj_unit = unit;
+
+  gtk_adjustment_value_changed(sbutton->adjustment);
+}
+
+static void
+gnome_unit_spinner_update(GnomeUnitSpinner *self)
+{
+  GtkSpinButton *sbutton;
+  gdouble val;
+  gchar *extra = NULL;
+
+  g_return_if_fail(self != NULL);
+  g_return_if_fail(GNOME_IS_UNIT_SPINNER(self));
+
+  sbutton = GTK_SPIN_BUTTON(self);
+  val = g_strtod(gtk_entry_get_text(GTK_ENTRY(self)), &extra);
+
+  /* get rid of extra white space after number */
+  while (*extra && isspace(*extra)) extra++;
+  if (*extra) {
+    const GnomeUnit *disp_unit = gnome_unit_with_abbrev(extra);
+
+    if (disp_unit) {
+      val = gnome_unit_convert(val, disp_unit, self->adj_unit);
+    }
+  }
+  /* convert to prefered units */
+  if (val < sbutton->adjustment->lower)
+    val = sbutton->adjustment->lower;
+  else if (val > sbutton->adjustment->upper)
+    val = sbutton->adjustment->upper;
+  sbutton->adjustment->value = val;
+  gtk_adjustment_value_changed(sbutton->adjustment);
+}
+
+static gint
+gnome_unit_spinner_focus_out(GtkWidget *widget, GdkEventFocus *event)
+{
+  g_return_val_if_fail(widget != NULL, 0);
+  g_return_val_if_fail(GNOME_IS_UNIT_SPINNER(widget), 0);
+
+#if 0 /* FIXME */
+  if (GTK_EDITABLE(widget)->editable)
+    gnome_unit_spinner_update(GNOME_UNIT_SPINNER(widget));
+#endif
+  return GTK_WIDGET_CLASS(entry_class)->focus_out_event(widget, event);
+}
+
+static gint
+gnome_unit_spinner_button_press(GtkWidget *widget, GdkEventButton *event)
+{
+  g_return_val_if_fail(widget != NULL, 0);
+  g_return_val_if_fail(GNOME_IS_UNIT_SPINNER(widget), 0);
+
+  gnome_unit_spinner_update(GNOME_UNIT_SPINNER(widget));
+  return GTK_WIDGET_CLASS(parent_class)->button_press_event(widget, event);
+}
+
+static gint
+gnome_unit_spinner_key_press(GtkWidget *widget, GdkEventKey *event)
+{
+  /* gint key = event->keyval; */
+
+  g_return_val_if_fail(widget != NULL, 0);
+  g_return_val_if_fail(GNOME_IS_UNIT_SPINNER(widget), 0);
+
+#if 0 /* FIXME */
+  if (GTK_EDITABLE (widget)->editable &&
+      (key == GDK_Up || key == GDK_Down || 
+       key == GDK_Page_Up || key == GDK_Page_Down))
+    gnome_unit_spinner_update (GNOME_UNIT_SPINNER(widget));
+#endif
+  return GTK_WIDGET_CLASS(parent_class)->key_press_event(widget, event);
+}
+
+#if 0 /* FIXME */
+
+static void
+gnome_unit_spinner_activate(GtkEditable *editable)
+{
+  g_return_if_fail(editable != NULL);
+  g_return_if_fail(GNOME_IS_UNIT_SPINNER(editable));
+
+  if (editable->editable)
+    gnome_unit_spinner_update(GNOME_UNIT_SPINNER(editable));
+}
+
+#endif
diff --git a/libgnomeui/gnome-unit-spinner.h b/libgnomeui/gnome-unit-spinner.h
new file mode 100644
index 0000000..da0acb1
--- /dev/null
+++ b/libgnomeui/gnome-unit-spinner.h
@@ -0,0 +1,73 @@
+/* GNOME Unit spinner
+ * Copyright (C) 1999 James Henstridge <james daa com au>
+ * All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+#ifndef GNOME_UNIT_SPINNER_H
+#define GNOME_UNIT_SPINNER_H
+
+#include <gtk/gtk.h>
+
+#include <libgnome/gnome-paper.h>
+
+G_BEGIN_DECLS
+
+#define GNOME_TYPE_UNIT_SPINNER            (gnome_unit_spinner_get_type ())
+#define GNOME_UNIT_SPINNER(obj)            (GTK_CHECK_CAST ((obj), GNOME_TYPE_UNIT_SPINNER, GnomeUnitSpinner))
+#define GNOME_UNIT_SPINNER_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_UNIT_SPINNER, GnomeUnitSpinnerClass))
+#define GNOME_IS_UNIT_SPINNER(obj)         (GTK_CHECK_TYPE ((obj), GNOME_TYPE_UNIT_SPINNER))
+#define GNOME_IS_UNIT_SPINNER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_UNIT_SPINNER))
+#define GNOME_UNIT_SPINNER_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GNOME_TYPE_UNIT_SPINNER, GnomeUnitSpinnerClass))
+
+typedef struct _GnomeUnitSpinner GnomeUnitSpinner;
+typedef struct _GnomeUnitSpinnerClass GnomeUnitSpinnerClass;
+
+struct _GnomeUnitSpinner {
+  GtkSpinButton parent;
+
+  /*< public >*/
+  const GnomeUnit *adj_unit;
+
+  /*< private >*/
+  gpointer _priv; /* reserved for a future private pointer */
+};
+
+struct _GnomeUnitSpinnerClass {
+  GtkSpinButtonClass parent_class;
+};
+
+GtkType    gnome_unit_spinner_get_type     (void) G_GNUC_CONST;
+GtkWidget *gnome_unit_spinner_new          (GtkAdjustment *adjustment,
+					    guint digits,
+					    const GnomeUnit *adj_unit);
+void       gnome_unit_spinner_construct    (GnomeUnitSpinner *self,
+					    GtkAdjustment *adjustment,
+					    guint digits,
+					    const GnomeUnit *adj_unit);
+void       gnome_unit_spinner_set_value    (GnomeUnitSpinner *self,
+					    gfloat val,
+					    const GnomeUnit *unit);
+gfloat     gnome_unit_spinner_get_value    (GnomeUnitSpinner *self,
+					    const GnomeUnit *unit);
+void       gnome_unit_spinner_change_units (GnomeUnitSpinner *self,
+					    const GnomeUnit *unit);
+
+G_END_DECLS
+
+#endif
diff --git a/libgnomeui/gnome-vfs-util.c b/libgnomeui/gnome-vfs-util.c
new file mode 100644
index 0000000..a6a7887
--- /dev/null
+++ b/libgnomeui/gnome-vfs-util.c
@@ -0,0 +1,290 @@
+/* -*- Mode: C; c-set-style: gnu indent-tabs-mode: t; c-basic-offset: 4; tab-width: 8 -*- */
+/*
+ * Copyright (C) 2000 SuSE GmbH
+ * Author: Martin Baulig <baulig suse de>
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <gtk/gtkobject.h>
+#include <libgnome/gnome-i18n.h>
+
+#include "gnome-vfs-util.h"
+
+#include <gdk-pixbuf/gdk-pixbuf-loader.h>
+#include <libgnomevfs/gnome-vfs-async-ops.h>
+#include <libgnomevfs/gnome-vfs-ops.h>
+#include <libgnomevfs/gnome-vfs-utils.h>
+
+/* =======================================================================
+ * gdk-pixbuf handing stuff.
+ *
+ * Shamelessly stolen from nautilus-gdk-pixbuf-extensions.c which is
+ * Copyright (C) 2000 Eazel, Inc.
+ * Authors: Darin Adler <darin eazel com>
+            Ramiro Estrugo <ramiro eazel com>
+ *
+ * =======================================================================
+ */
+
+#define LOAD_BUFFER_SIZE 4096
+
+struct GnomeGdkPixbufAsyncHandle {
+    GnomeVFSAsyncHandle *vfs_handle;
+    GnomeGdkPixbufLoadCallback load_callback;
+    GnomeGdkPixbufDoneCallback done_callback;
+    gpointer callback_data;
+    GdkPixbufLoader *loader;
+    char buffer[LOAD_BUFFER_SIZE];
+};
+
+static void file_opened_callback (GnomeVFSAsyncHandle      *vfs_handle,
+                                  GnomeVFSResult            result,
+                                  gpointer                  callback_data);
+static void file_read_callback   (GnomeVFSAsyncHandle      *vfs_handle,
+                                  GnomeVFSResult            result,
+                                  gpointer                  buffer,
+                                  GnomeVFSFileSize          bytes_requested,
+                                  GnomeVFSFileSize          bytes_read,
+                                  gpointer                  callback_data);
+static void file_closed_callback (GnomeVFSAsyncHandle      *handle,
+                                  GnomeVFSResult            result,
+                                  gpointer                  callback_data);
+static void load_done            (GnomeGdkPixbufAsyncHandle *handle,
+                                  GnomeVFSResult            result,
+                                  GdkPixbuf                *pixbuf);
+
+/* Loading a GdkPixbuf with a URI. */
+GdkPixbuf *
+gnome_gdk_pixbuf_new_from_uri (const char *uri)
+{
+    GnomeVFSResult result;
+    GnomeVFSHandle *handle;
+    char buffer[LOAD_BUFFER_SIZE];
+    char *local_path;
+    GnomeVFSFileSize bytes_read;
+    GdkPixbufLoader *loader;
+    GdkPixbuf *pixbuf;	
+
+    g_return_val_if_fail (uri != NULL, NULL);
+
+    /* FIXME bugzilla.eazel.com 1964: unfortunately, there are
+     * bugs in the gdk_pixbuf_loader stuff that make it not work
+     * for various image types like .xpms. Since
+     * gdk_pixbuf_new_from_file uses different code that does not
+     * have the same bugs and is better-tested, we call that when
+     * the file is local. This should be fixed (in gdk_pixbuf)
+     * eventually, then this hack can be removed.
+     */
+    local_path = gnome_vfs_get_local_path_from_uri (uri);
+    if (local_path != NULL) {
+	pixbuf = gdk_pixbuf_new_from_file (local_path, NULL);
+	g_free (local_path);
+	return pixbuf;
+    }
+	
+    result = gnome_vfs_open (&handle,
+			     uri,
+			     GNOME_VFS_OPEN_READ);
+    if (result != GNOME_VFS_OK) {
+	return NULL;
+    }
+
+    loader = gdk_pixbuf_loader_new ();
+    while (1) {
+	result = gnome_vfs_read (handle,
+				 buffer,
+				 sizeof (buffer),
+				 &bytes_read);
+	if (result != GNOME_VFS_OK) {
+	    break;
+	}
+	if (bytes_read == 0) {
+	    break;
+	}
+	if (!gdk_pixbuf_loader_write (loader,
+				      buffer,
+				      bytes_read,
+				      NULL)) {
+	    result = GNOME_VFS_ERROR_WRONG_FORMAT;
+	    break;
+	}
+    }
+
+    if (result != GNOME_VFS_OK) {
+	gtk_object_unref (GTK_OBJECT (loader));
+	gnome_vfs_close (handle);
+	return NULL;
+    }
+
+    gnome_vfs_close (handle);
+
+    pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+    if (pixbuf != NULL) {
+	gdk_pixbuf_ref (pixbuf);
+    }
+    gtk_object_unref (GTK_OBJECT (loader));
+
+    return pixbuf;
+}
+
+GnomeGdkPixbufAsyncHandle *
+gnome_gdk_pixbuf_new_from_uri_async (const char *uri,
+				     GnomeGdkPixbufLoadCallback load_callback,
+				     GnomeGdkPixbufDoneCallback done_callback,
+				     gpointer callback_data)
+{
+    GnomeGdkPixbufAsyncHandle *handle;
+
+    handle = g_new0 (GnomeGdkPixbufAsyncHandle, 1);
+    handle->load_callback = load_callback;
+    handle->done_callback = done_callback;
+    handle->callback_data = callback_data;
+
+    gnome_vfs_async_open (&handle->vfs_handle,
+			  uri,
+			  GNOME_VFS_OPEN_READ,
+			  file_opened_callback,
+			  handle);
+
+    return handle;
+}
+
+static void
+file_opened_callback (GnomeVFSAsyncHandle *vfs_handle,
+		      GnomeVFSResult result,
+		      gpointer callback_data)
+{
+    GnomeGdkPixbufAsyncHandle *handle;
+
+    handle = callback_data;
+    g_assert (handle->vfs_handle == vfs_handle);
+
+    if (result != GNOME_VFS_OK) {
+	load_done (handle, result, NULL);
+	return;
+    }
+
+    handle->loader = gdk_pixbuf_loader_new ();
+
+    gnome_vfs_async_read (handle->vfs_handle,
+			  handle->buffer,
+			  sizeof (handle->buffer),
+			  file_read_callback,
+			  handle);
+}
+
+static void
+file_read_callback (GnomeVFSAsyncHandle *vfs_handle,
+		    GnomeVFSResult result,
+		    gpointer buffer,
+		    GnomeVFSFileSize bytes_requested,
+		    GnomeVFSFileSize bytes_read,
+		    gpointer callback_data)
+{
+    GnomeGdkPixbufAsyncHandle *handle;
+
+    handle = callback_data;
+    g_assert (handle->vfs_handle == vfs_handle);
+    g_assert (handle->buffer == buffer);
+
+    if (result == GNOME_VFS_OK && bytes_read != 0) {
+	if (!gdk_pixbuf_loader_write (handle->loader,
+				      buffer,
+				      bytes_read,
+				      NULL)) {
+	    result = GNOME_VFS_ERROR_WRONG_FORMAT;
+	}
+	gnome_vfs_async_read (handle->vfs_handle,
+			      handle->buffer,
+			      sizeof (handle->buffer),
+			      file_read_callback,
+			      handle);
+	return;
+    }
+
+    switch (result) {
+    case GNOME_VFS_OK:
+	if (bytes_read == 0) {
+	    GdkPixbuf *pixbuf;
+
+	    pixbuf = gdk_pixbuf_loader_get_pixbuf (handle->loader);
+	    load_done (handle, result, pixbuf);
+	}
+	break;
+    case GNOME_VFS_ERROR_EOF:
+	{
+	    GdkPixbuf *pixbuf;
+
+	    pixbuf = gdk_pixbuf_loader_get_pixbuf (handle->loader);
+	    load_done (handle, pixbuf ? GNOME_VFS_OK : result, pixbuf);
+	}
+	break;
+    default:
+	load_done (handle, result, NULL);
+	break;
+    }
+}
+
+static void
+file_closed_callback (GnomeVFSAsyncHandle *handle,
+		      GnomeVFSResult result,
+		      gpointer callback_data)
+{
+    g_assert (callback_data == NULL);
+}
+
+static void
+free_pixbuf_load_handle (GnomeGdkPixbufAsyncHandle *handle)
+{
+    if (handle->done_callback)
+	(* handle->done_callback) (handle, handle->callback_data);
+    if (handle->loader != NULL) {
+	gdk_pixbuf_loader_close (handle->loader, NULL);
+	g_object_unref (G_OBJECT (handle->loader));
+    }
+    g_free (handle);
+}
+
+static void
+load_done (GnomeGdkPixbufAsyncHandle *handle,
+	   GnomeVFSResult result,
+	   GdkPixbuf *pixbuf)
+{
+    if (handle->vfs_handle != NULL) {
+	gnome_vfs_async_close (handle->vfs_handle, file_closed_callback, NULL);
+    }
+    (* handle->load_callback) (handle, result, pixbuf, handle->callback_data);
+    free_pixbuf_load_handle (handle);
+}
+
+void
+gnome_gdk_pixbuf_new_from_uri_cancel (GnomeGdkPixbufAsyncHandle *handle)
+{
+    if (handle == NULL) {
+	return;
+    }
+    if (handle->vfs_handle != NULL) {
+	gnome_vfs_async_cancel (handle->vfs_handle);
+    }
+    free_pixbuf_load_handle (handle);
+}
diff --git a/libgnomeui/gnome-vfs-util.h b/libgnomeui/gnome-vfs-util.h
new file mode 100644
index 0000000..ba7fa90
--- /dev/null
+++ b/libgnomeui/gnome-vfs-util.h
@@ -0,0 +1,71 @@
+/* -*- Mode: C; c-set-style: gnu indent-tabs-mode: t; c-basic-offset: 4; tab-width: 8 -*- */
+/*
+ * Copyright (C) 2000 SuSE GmbH
+ * Author: Martin Baulig <baulig suse de>
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#ifndef GNOME_VFS_UTIL_H
+#define GNOME_VFS_UTIL_H
+
+
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <libgnomevfs/gnome-vfs-types.h>
+
+G_BEGIN_DECLS
+
+/* =======================================================================
+ * gdk-pixbuf handing stuff.
+ *
+ * Shamelessly stolen from nautilus-gdk-pixbuf-extensions.h which is
+ * Copyright (C) 2000 Eazel, Inc.
+ * Authors: Darin Adler <darin eazel com>
+ *
+ * =======================================================================
+ */
+
+typedef struct GnomeGdkPixbufAsyncHandle    GnomeGdkPixbufAsyncHandle;
+typedef void (*GnomeGdkPixbufLoadCallback) (GnomeGdkPixbufAsyncHandle *handle,
+                                            GnomeVFSResult             error,
+                                            GdkPixbuf                 *pixbuf,
+                                            gpointer                   cb_data);
+typedef void (*GnomeGdkPixbufDoneCallback) (GnomeGdkPixbufAsyncHandle *handle,
+                                            gpointer                   cb_data);
+
+/* Loading a GdkPixbuf with a URI. */
+GdkPixbuf *
+gnome_gdk_pixbuf_new_from_uri        (const char                 *uri);
+
+/* Same thing async. */
+GnomeGdkPixbufAsyncHandle *
+gnome_gdk_pixbuf_new_from_uri_async  (const char                 *uri,
+                                      GnomeGdkPixbufLoadCallback  load_callback,
+                                      GnomeGdkPixbufDoneCallback  done_callback,
+                                      gpointer                    callback_data);
+
+void
+gnome_gdk_pixbuf_new_from_uri_cancel (GnomeGdkPixbufAsyncHandle  *handle);
+
+G_END_DECLS
+
+#endif
diff --git a/libgnomeui/gnome-window.c b/libgnomeui/gnome-window.c
new file mode 100644
index 0000000..4b21bb3
--- /dev/null
+++ b/libgnomeui/gnome-window.c
@@ -0,0 +1,164 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * gnome-window.c: wrappers for setting window properties
+ *
+ * Copyright 2000, Chema Celorio
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ *
+ * Authors:  Chema Celorio <chema celorio com>
+ */
+
+
+#include <config.h>
+#include <glib.h>
+#include <string.h>
+#include <libgnome/gnome-program.h>
+#include <gtk/gtkwindow.h>
+#include <gtk/gtksignal.h>
+#include <gdk/gdkx.h>
+
+#include "gnome-window.h"
+
+/**
+ * gnome_window_toplevel_set_title:
+ * @window: A pointer to the toplevel window
+ * @doc_name: the document name with extension (if any)
+ * @app_name: the application name
+ * @extension: the default extension that the application uses.
+ *             NULL if there isn't a default extension.
+ * 
+ * Set the title of a toplevel window. Acording to gnome policy or
+ * (if implemented) to a gnome setting.
+ *
+ **/
+void
+gnome_window_toplevel_set_title (GtkWindow *window, const gchar *doc_name,
+				 const gchar *app_name, const gchar *extension)
+{
+    gchar *full_title;
+    gchar *doc_name_clean = NULL;
+	
+    g_return_if_fail (GTK_IS_WINDOW (window));
+    g_return_if_fail (doc_name != NULL);
+    g_return_if_fail (app_name != NULL);
+
+    /* Remove the extension from the doc_name*/
+    if (extension != NULL) {
+	gchar * pos = strstr (doc_name, extension);
+	if (pos != NULL)
+	    doc_name_clean = g_strndup (doc_name, pos - doc_name);
+    }
+
+    if (!doc_name_clean)
+	doc_name_clean = g_strdup (doc_name);
+	
+    full_title = g_strdup_printf ("%s : %s", doc_name_clean, app_name);
+    gtk_window_set_title (window, full_title);
+
+    g_free (doc_name_clean);
+    g_free (full_title);
+}
+
+typedef struct {
+    GdkPixmap *icon_pixmap;
+    GdkBitmap *icon_mask;
+    GdkWindow *icon_window;
+} IconInfo;
+
+static void
+gnome_window_realized (GtkWindow *window, IconInfo *pbi)
+{
+    gdk_window_set_icon (GTK_WIDGET (window)->window, pbi->icon_window,
+			 pbi->icon_pixmap, pbi->icon_mask);
+}
+
+static void
+gnome_window_destroyed (GtkWindow *window, IconInfo *pbi)
+{
+    gdk_pixmap_unref (pbi->icon_pixmap);
+    gdk_bitmap_unref (pbi->icon_mask);
+    gdk_window_unref (pbi->icon_window);
+    g_free (pbi);
+}
+
+void
+gnome_window_set_icon (GtkWindow *window, GdkPixbuf *pixbuf, gboolean overwrite)
+{
+    gboolean skip_connect = FALSE;
+    IconInfo *pbi;
+
+    pbi = gtk_object_get_data (GTK_OBJECT (window), "WM_HINTS.icon_info");
+    if (pbi && !overwrite)
+	return;
+    if(pbi) {
+	skip_connect = TRUE;
+	gdk_pixmap_unref (pbi->icon_pixmap);
+	gdk_pixmap_unref (pbi->icon_mask);
+	gdk_window_unref (pbi->icon_window);
+    } else
+	pbi = g_new (IconInfo, 1);
+
+    {
+	GdkWindowAttr wa;
+	wa.visual = gdk_rgb_get_visual ();
+	wa.colormap = gdk_rgb_get_cmap ();
+	pbi->icon_window = gdk_window_new (GDK_ROOT_PARENT (), &wa, GDK_WA_VISUAL|GDK_WA_COLORMAP);
+    }
+    gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pbi->icon_pixmap, &pbi->icon_mask, 128);
+
+    if (!skip_connect) {
+	gtk_object_set_data (GTK_OBJECT (window), "WM_HINTS.icon_info", pbi);
+	gtk_signal_connect_after (GTK_OBJECT (window), "realize",
+				  GTK_SIGNAL_FUNC (gnome_window_realized), pbi);
+	gtk_signal_connect (GTK_OBJECT (window), "destroy",
+			   GTK_SIGNAL_FUNC (gnome_window_destroyed), pbi);
+    }
+
+    if (GTK_WIDGET_REALIZED (window))
+	gnome_window_realized (window, pbi);
+}
+
+void
+gnome_window_set_icon_from_file (GtkWindow *window, const char *filename, gboolean overwrite)
+{
+    GdkPixbuf *pb;
+    GError *error;
+
+    error = NULL;
+    pb = gdk_pixbuf_new_from_file (filename, &error);
+    if (error != NULL) {
+	g_warning (error->message);
+	g_error_free (error);
+    }
+    if(!pb) {
+	error = NULL;
+	filename = gnome_program_locate_file (gnome_program_get (),
+					      GNOME_FILE_DOMAIN_PIXMAP,
+					      filename, TRUE, NULL);
+		
+	pb = gdk_pixbuf_new_from_file (filename, &error);
+	if (error != NULL) {
+	    g_warning (error->message);
+	    g_error_free (error);
+	}
+	g_free ((gpointer)filename);
+    }
+    if(!pb)
+	return;
+
+    gnome_window_set_icon (window, pb, overwrite);
+    gdk_pixbuf_unref (pb);
+}
diff --git a/libgnomeui/gnome-window.h b/libgnomeui/gnome-window.h
new file mode 100644
index 0000000..5ef0dc8
--- /dev/null
+++ b/libgnomeui/gnome-window.h
@@ -0,0 +1,43 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * gnome-window.h: wrappers for setting window properties
+ *
+ * Author:  Chema Celorio <chema celorio com>
+ */
+
+/*
+ * These functions are a convenience wrapper for gtk_window_set_title
+ * This allows all the gnome-apps to have a consitent way of setting
+ * the window & dialogs titles. We could also add a configurable way
+ * of setting the windows titles in the future..
+ *
+ * These functions were added with the 1.2.5 release of the GNOME libraries
+ * in Oct, 2000.  This means that not all users will have this functionality
+ * in the GNOME libraries, and should only be used accordingly.  The header file
+ * must be explicitely included, also (#include <libgnomeui/gnome-window.h>).
+ */
+
+#ifndef GNOME_WINDOW_H
+#define GNOME_WINDOW_H
+
+#include <gtk/gtkwindow.h>
+
+G_BEGIN_DECLS
+
+/* set the window title */
+void gnome_window_toplevel_set_title (GtkWindow *w,
+				      const gchar *doc_name,
+				      const gchar *app_name,
+				      const gchar *extension);
+
+void gnome_window_set_icon (GtkWindow *window,
+			    GdkPixbuf *pixbuf,
+			    gboolean overwrite);
+
+void gnome_window_set_icon_from_file (GtkWindow *window,
+				      const char *filename,
+				      gboolean overwrite);
+
+G_END_DECLS
+
+#endif /* GNOME_WINDOW_H */
diff --git a/libgnomeui/gnome-winhints.c b/libgnomeui/gnome-winhints.c
new file mode 100644
index 0000000..85e9852
--- /dev/null
+++ b/libgnomeui/gnome-winhints.c
@@ -0,0 +1,749 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#include <config.h>
+#include <X11/Xlib.h>
+#include <X11/Xmd.h>
+#include <X11/Xatom.h>
+#include <gdk/gdkx.h>
+#include <gdk/gdkprivate.h>
+#include "gnome-winhints.h"
+
+/* these are the X atoms for the hints we use */
+static Atom _XA_WIN_PROTOCOLS;
+static Atom _XA_WIN_WORKSPACE;
+static Atom _XA_WIN_WORKSPACE_COUNT;
+static Atom _XA_WIN_WORKSPACE_NAMES;
+static Atom _XA_WIN_STATE;
+static Atom _XA_WIN_HINTS;
+static Atom _XA_WIN_PROTOCOLS;
+static Atom _XA_WIN_LAYER;
+static Atom _XA_WIN_ICONS;
+static Atom _XA_WIN_CLIENT_LIST;
+static Atom _XA_WIN_APP_STATE;
+static Atom _XA_WIN_EXPANDED_SIZE;
+static Atom _XA_WIN_CLIENT_MOVING;
+static Atom _XA_WIN_SUPPORTING_WM_CHECK;
+
+static int need_init = TRUE;
+
+void
+gnome_win_hints_init(void)
+{
+  /* Get the atoms we are working with, creating them if necessary.
+   */
+  g_return_if_fail(GDK_DISPLAY());
+  _XA_WIN_PROTOCOLS = XInternAtom(GDK_DISPLAY(), XA_WIN_PROTOCOLS, False);
+  _XA_WIN_STATE = XInternAtom(GDK_DISPLAY(), XA_WIN_STATE, False);
+  _XA_WIN_WORKSPACE = XInternAtom(GDK_DISPLAY(), XA_WIN_WORKSPACE, False);
+  _XA_WIN_WORKSPACE_COUNT = XInternAtom(GDK_DISPLAY(), XA_WIN_WORKSPACE_COUNT, False);
+  _XA_WIN_WORKSPACE_NAMES = XInternAtom(GDK_DISPLAY(), XA_WIN_WORKSPACE_NAMES, False);
+  _XA_WIN_LAYER = XInternAtom(GDK_DISPLAY(), XA_WIN_LAYER, False);
+  _XA_WIN_PROTOCOLS = XInternAtom(GDK_DISPLAY(), XA_WIN_PROTOCOLS, False);
+  _XA_WIN_HINTS = XInternAtom(GDK_DISPLAY(), XA_WIN_HINTS, False);
+  _XA_WIN_ICONS = XInternAtom(GDK_DISPLAY(), XA_WIN_ICONS, False);
+  _XA_WIN_CLIENT_LIST = XInternAtom(GDK_DISPLAY(), XA_WIN_CLIENT_LIST, False);
+  _XA_WIN_APP_STATE = XInternAtom(GDK_DISPLAY(), XA_WIN_APP_STATE, False);
+  _XA_WIN_EXPANDED_SIZE = XInternAtom(GDK_DISPLAY(), XA_WIN_EXPANDED_SIZE, False);
+  _XA_WIN_CLIENT_MOVING = XInternAtom(GDK_DISPLAY(), XA_WIN_CLIENT_MOVING, False);
+  _XA_WIN_SUPPORTING_WM_CHECK = XInternAtom(GDK_DISPLAY(), XA_WIN_SUPPORTING_WM_CHECK, False);
+  need_init = FALSE;
+}
+
+void
+gnome_win_hints_set_layer(GtkWidget *window, GnomeWinLayer layer)
+{
+  XEvent xev;
+  gint prev_error;
+
+  g_return_if_fail(window != NULL);
+  g_return_if_fail(GTK_IS_WIDGET(window));
+  g_return_if_fail(GTK_WIDGET_REALIZED(window));
+  
+  if (need_init)
+    gnome_win_hints_init();
+  
+  prev_error = gdk_error_warnings;
+  gdk_error_warnings = 0;
+  
+  if (GTK_WIDGET_MAPPED(window))
+    {
+      xev.type = ClientMessage;
+      xev.xclient.type = ClientMessage;
+      xev.xclient.window = GDK_WINDOW_XWINDOW(window->window);
+      xev.xclient.message_type = _XA_WIN_LAYER;
+      xev.xclient.format = 32;
+      xev.xclient.data.l[0] = (long)layer;
+      xev.xclient.data.l[1] = GDK_CURRENT_TIME;
+      
+      XSendEvent(GDK_DISPLAY(), GDK_ROOT_WINDOW(), False,
+		 SubstructureNotifyMask, (XEvent*) &xev);
+    }
+  else
+    {
+      long data[1];
+      
+      data[0] = layer;
+      XChangeProperty(GDK_DISPLAY(), GDK_WINDOW_XWINDOW(window->window),
+		      _XA_WIN_LAYER, XA_CARDINAL, 32, PropModeReplace,
+		      (unsigned char *)data, 1);
+    }
+  gdk_error_warnings = prev_error;
+}
+
+GnomeWinLayer
+gnome_win_hints_get_layer(GtkWidget *window)
+{
+  GnomeWinLayer mylayer;
+  Atom r_type;
+  int r_format;
+  unsigned long count;
+  unsigned long bytes_remain;
+  unsigned char *prop;
+  long layer;
+  gint prev_error;
+
+  g_return_val_if_fail(window != NULL, WIN_LAYER_NORMAL);
+  g_return_val_if_fail(GTK_IS_WIDGET(window), WIN_LAYER_NORMAL);
+  g_return_val_if_fail(GTK_WIDGET_REALIZED(window), WIN_LAYER_NORMAL);
+
+  if (need_init)
+    gnome_win_hints_init();
+  
+  prev_error = gdk_error_warnings;
+  gdk_error_warnings = 0;  
+  if (XGetWindowProperty(GDK_DISPLAY(), GDK_WINDOW_XWINDOW(window->window),
+			 _XA_WIN_LAYER, 0, 1, False, XA_CARDINAL, &r_type,
+			 &r_format, &count, &bytes_remain, &prop) == Success)
+    {
+      if (r_type == XA_CARDINAL && r_format == 32 && count == 1)
+	{
+	  layer = ((long *)prop)[0];
+	  mylayer = (GnomeWinLayer)layer;
+	  XFree(prop);
+	  gdk_error_warnings = prev_error;
+	  return mylayer;
+	}
+      XFree(prop);
+    }
+  gdk_error_warnings = prev_error;
+  return WIN_LAYER_NORMAL;
+}
+
+void
+gnome_win_hints_set_state(GtkWidget *window, GnomeWinState state)
+{
+  XEvent xev;
+  gint prev_error;
+
+  g_return_if_fail(window != NULL);
+  g_return_if_fail(GTK_IS_WIDGET(window));
+  g_return_if_fail(GTK_WIDGET_REALIZED(window));
+  
+  if (need_init)
+    gnome_win_hints_init();
+  
+  prev_error = gdk_error_warnings;
+  gdk_error_warnings = 0;  
+  
+  if (GTK_WIDGET_MAPPED(window))
+    {
+      xev.type = ClientMessage;
+      xev.xclient.type = ClientMessage;
+      xev.xclient.window = GDK_WINDOW_XWINDOW(window->window);
+      xev.xclient.message_type = _XA_WIN_STATE;
+      xev.xclient.format = 32;
+      xev.xclient.data.l[0] = (long)(WIN_STATE_STICKY |
+				     WIN_STATE_MAXIMIZED_VERT |
+				     WIN_STATE_MAXIMIZED_HORIZ |
+				     WIN_STATE_HIDDEN |
+				     WIN_STATE_SHADED |
+				     WIN_STATE_HID_WORKSPACE |
+				     WIN_STATE_HID_TRANSIENT |
+				     WIN_STATE_FIXED_POSITION |
+				     WIN_STATE_ARRANGE_IGNORE);
+      xev.xclient.data.l[1] = (long)state;
+      xev.xclient.data.l[2] = GDK_CURRENT_TIME;
+      
+      XSendEvent(GDK_DISPLAY(), GDK_ROOT_WINDOW(), False, 
+		 SubstructureNotifyMask, (XEvent*) &xev);
+    }
+  else
+    {
+      long data[1];
+      
+      data[0] = (long)state;
+      XChangeProperty(GDK_DISPLAY(), GDK_WINDOW_XWINDOW(window->window),
+		      _XA_WIN_STATE, XA_CARDINAL, 32, PropModeReplace,
+		      (unsigned char *)data, 1);
+    }
+  gdk_error_warnings = prev_error;
+}
+
+GnomeWinState
+gnome_win_hints_get_state(GtkWidget *window)
+{
+  GnomeWinState state;
+  Atom r_type;
+  int r_format;
+  unsigned long count;
+  unsigned long bytes_remain;
+  unsigned char *prop;
+  gint prev_error;
+
+  g_return_val_if_fail(window != NULL, 0);
+  g_return_val_if_fail(GTK_IS_WIDGET(window), 0);
+  g_return_val_if_fail(GTK_WIDGET_REALIZED(window), 0);
+  
+  if (need_init)
+    gnome_win_hints_init();
+  
+  prev_error = gdk_error_warnings;
+  gdk_error_warnings = 0;  
+  if (XGetWindowProperty(GDK_DISPLAY(), GDK_WINDOW_XWINDOW(window->window),
+			 _XA_WIN_STATE, 0, 1, False, XA_CARDINAL, &r_type,
+			 &r_format, &count, &bytes_remain, &prop) == Success)
+    {
+      if (r_type == XA_CARDINAL && r_format == 32 && count == 2)
+	{
+	  state = (GnomeWinState)(((long *)prop)[0]) && 
+	    (GnomeWinState)(((long *)prop)[1]);
+	  XFree(prop);
+	  gdk_error_warnings = prev_error;
+	  return state;
+	}
+      XFree(prop);
+    }
+  gdk_error_warnings = prev_error;
+  return (GnomeWinState)0;
+}
+
+void
+gnome_win_hints_set_hints(GtkWidget *window,  GnomeWinHints skip)
+{
+  XEvent xev;
+  gint prev_error;
+
+  g_return_if_fail(window != NULL);
+  g_return_if_fail(GTK_IS_WIDGET(window));
+  g_return_if_fail(GTK_WIDGET_REALIZED(window));
+  
+  if (need_init)
+    gnome_win_hints_init();
+  
+  prev_error = gdk_error_warnings;
+  gdk_error_warnings = 0;  
+  
+  if (GTK_WIDGET_MAPPED(window))
+    {
+      xev.type = ClientMessage;
+      xev.xclient.type = ClientMessage;
+      xev.xclient.window = GDK_WINDOW_XWINDOW(window->window);
+      xev.xclient.message_type = _XA_WIN_HINTS;
+      xev.xclient.format = 32;
+      xev.xclient.data.l[0] = (long)(WIN_HINTS_SKIP_FOCUS | 
+				     WIN_HINTS_SKIP_WINLIST | 
+				     WIN_HINTS_SKIP_TASKBAR | 
+				     WIN_HINTS_GROUP_TRANSIENT);
+      xev.xclient.data.l[1] = (long)skip;
+      xev.xclient.data.l[2] = GDK_CURRENT_TIME;
+      
+      XSendEvent(GDK_DISPLAY(), GDK_ROOT_WINDOW(), False, 
+		 SubstructureNotifyMask, (XEvent*) &xev);
+    }
+  else
+    {
+      long data[1];
+      
+      data[0] = (long)skip;
+      XChangeProperty(GDK_DISPLAY(), GDK_WINDOW_XWINDOW(window->window),
+		      _XA_WIN_HINTS, XA_CARDINAL, 32, PropModeReplace,
+		      (unsigned char *)data, 1);
+    }
+  gdk_error_warnings = prev_error;
+}
+
+GnomeWinHints
+gnome_win_hints_get_hints(GtkWidget *window)
+{
+  GnomeWinHints hints;
+  Atom r_type;
+  int r_format;
+  unsigned long count;
+  unsigned long bytes_remain;
+  unsigned char *prop;
+  gint prev_error;
+
+  g_return_val_if_fail(window != NULL, 0);
+  g_return_val_if_fail(GTK_IS_WIDGET(window), 0);
+  g_return_val_if_fail(GTK_WIDGET_REALIZED(window), 0);
+  
+  if (need_init)
+    gnome_win_hints_init();
+  
+  prev_error = gdk_error_warnings;
+  gdk_error_warnings = 0;  
+  if (XGetWindowProperty(GDK_DISPLAY(), GDK_WINDOW_XWINDOW(window->window),
+			 _XA_WIN_HINTS, 0, 1, False, XA_CARDINAL, &r_type,
+			 &r_format, &count, &bytes_remain, &prop) == Success)
+    {
+      if (r_type == XA_CARDINAL && r_format == 32 && count == 2)
+	{
+	  hints = (GnomeWinState)(((long *)prop)[0]) && 
+	    (GnomeWinState)(((long *)prop)[1]);
+	  XFree(prop);
+	  gdk_error_warnings = prev_error;
+	  return hints;
+	}
+      XFree(prop);
+    }
+  gdk_error_warnings = prev_error;
+  return (GnomeWinState)0;
+}
+
+void
+gnome_win_hints_set_workspace(GtkWidget *window, gint workspace)
+{
+  long data[1];
+  gint prev_error;
+
+  g_return_if_fail(window != NULL);
+  g_return_if_fail(GTK_IS_WIDGET(window));
+  g_return_if_fail(GTK_WIDGET_REALIZED(window));
+  
+  if (need_init)
+    gnome_win_hints_init();
+  
+  prev_error = gdk_error_warnings;
+  gdk_error_warnings = 0;  
+
+  data[0] = (long)workspace;
+  XChangeProperty(GDK_DISPLAY(), GDK_WINDOW_XWINDOW(window->window),
+		  _XA_WIN_WORKSPACE, XA_CARDINAL, 32, PropModeReplace,
+		  (unsigned char *)data, 1);
+  gdk_error_warnings = prev_error;
+}
+
+gint
+gnome_win_hints_get_workspace(GtkWidget *window)
+{
+  gint ws;
+  Atom r_type;
+  int r_format;
+  unsigned long count;
+  unsigned long bytes_remain;
+  unsigned char *prop;
+  gint prev_error;
+
+  g_return_val_if_fail(window != NULL, 0);
+  g_return_val_if_fail(GTK_IS_WIDGET(window), 0);
+  g_return_val_if_fail(GTK_WIDGET_REALIZED(window), 0);
+  
+  if (need_init)
+    gnome_win_hints_init();
+  
+  prev_error = gdk_error_warnings;
+  gdk_error_warnings = 0;  
+  if (XGetWindowProperty(GDK_DISPLAY(), GDK_WINDOW_XWINDOW(window->window),
+			 _XA_WIN_WORKSPACE, 0, 1, False, XA_CARDINAL, &r_type,
+			 &r_format, &count, &bytes_remain, &prop) == Success)
+    {
+      if (r_type == XA_CARDINAL && r_format == 32 && count == 1)
+	{
+	  ws = (gint)(((long *)prop)[0]); 
+	  XFree(prop);
+	  gdk_error_warnings = prev_error;
+	  return ws;
+	}
+      XFree(prop);
+    }
+  gdk_error_warnings = prev_error;
+  return 0;
+}
+
+void
+gnome_win_hints_set_current_workspace(gint workspace)
+{
+  XEvent xev;
+  gint prev_error;
+  
+  if (need_init)
+    gnome_win_hints_init();
+  
+  prev_error = gdk_error_warnings;
+  gdk_error_warnings = 0;  
+  xev.type = ClientMessage;
+  xev.xclient.type = ClientMessage;
+  xev.xclient.window = GDK_ROOT_WINDOW();
+  xev.xclient.message_type = _XA_WIN_WORKSPACE;
+  xev.xclient.format = 32;
+  xev.xclient.data.l[0] = workspace;
+  xev.xclient.data.l[1] = GDK_CURRENT_TIME;
+  
+  XSendEvent(GDK_DISPLAY(), GDK_ROOT_WINDOW(), False,
+	     SubstructureNotifyMask, (XEvent*) &xev);
+  gdk_error_warnings = prev_error;
+}
+
+gint
+gnome_win_hints_get_current_workspace(void)
+{
+  Atom r_type;
+  int r_format;
+  unsigned long count;
+  unsigned long bytes_remain;
+  unsigned char *prop;
+  long ws = 0;
+  gint prev_error;
+  
+  if (need_init)
+    gnome_win_hints_init();
+  
+  prev_error = gdk_error_warnings;
+  gdk_error_warnings = 0;  
+  if (XGetWindowProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(),
+			 _XA_WIN_WORKSPACE, 0, 1, False, XA_CARDINAL,
+			 &r_type, &r_format,
+			 &count, &bytes_remain, &prop) == Success)
+    {
+      if (r_type == XA_CARDINAL && r_format == 32 && count == 1)
+        {
+	  long n = *(long *)prop;
+	  
+	  ws = (gint)n;
+        }
+      XFree(prop);
+    }       
+  gdk_error_warnings = prev_error;
+  return ws;
+}
+
+GList*
+gnome_win_hints_get_workspace_names(void)
+{
+  GList *tmp_list;
+  XTextProperty tp;
+  char **list;
+  int count, i;
+  gint prev_error;
+  
+  if (need_init)
+    gnome_win_hints_init();
+  
+  prev_error = gdk_error_warnings;
+  gdk_error_warnings = 0;  
+  XGetTextProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(),
+		   &tp, _XA_WIN_WORKSPACE_NAMES);  
+  XTextPropertyToStringList(&tp, &list, &count);
+  
+  if (tp.value==NULL) 
+    {
+      gdk_error_warnings = prev_error;
+      return NULL; /* current wm does not support this! */
+    }
+  
+  tmp_list = NULL;
+  for(i=0; i<count; i++)
+    {
+      tmp_list = g_list_append(tmp_list, g_strdup(list[i]));
+    }  
+  gdk_error_warnings = prev_error;
+  return tmp_list;
+}
+
+gint
+gnome_win_hints_get_workspace_count(void)
+{
+  gint wscount;
+  Atom r_type;
+  int r_format;
+  unsigned long count;
+  unsigned long bytes_remain;
+  unsigned char *prop;
+  gint prev_error;
+  
+  if (need_init)
+    gnome_win_hints_init();
+  
+  prev_error = gdk_error_warnings;
+  gdk_error_warnings = 0;  
+  wscount = 1;
+  if (XGetWindowProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(),
+			 _XA_WIN_WORKSPACE_COUNT, 0, 1, False, XA_CARDINAL,
+			 &r_type, &r_format,
+			 &count, &bytes_remain, &prop) == Success && prop)
+    {
+      if (r_type == XA_CARDINAL && r_format == 32 && count == 1)
+        {
+	  long n = *(long *)prop;
+	  wscount = (gint)n;
+        }
+      XFree(prop);
+    }       
+  gdk_error_warnings = prev_error;
+  return wscount;
+}
+
+void
+gnome_win_hints_set_expanded_size(GtkWidget *window, gint x, gint y, gint width, gint height)
+{
+  long data[4];
+  gint prev_error;
+  
+  g_return_if_fail(window != NULL);
+  g_return_if_fail(GTK_IS_WIDGET(window));
+  g_return_if_fail(GTK_WIDGET_REALIZED(window));
+
+  if (need_init)
+    gnome_win_hints_init();
+  
+  prev_error = gdk_error_warnings;
+  gdk_error_warnings = 0;  
+  
+  data[0] = (long)x;
+  data[1] = (long)y;
+  data[2] = (long)width;
+  data[3] = (long)height;
+  XChangeProperty(GDK_DISPLAY(), GDK_WINDOW_XWINDOW(window->window),
+		  _XA_WIN_APP_STATE, XA_CARDINAL, 32, PropModeReplace,
+		  (unsigned char *)data, 4);
+  gdk_error_warnings = prev_error;
+}
+
+gboolean
+gnome_win_hints_get_expanded_size(GtkWidget *window, gint *x, gint *y, gint *width, gint *height)
+{
+  Atom r_type;
+  int r_format;
+  unsigned long count;
+  unsigned long bytes_remain;
+  unsigned char *prop;
+  gint prev_error;
+
+  g_return_val_if_fail(window != NULL, FALSE);
+  g_return_val_if_fail(GTK_IS_WIDGET(window), FALSE);
+  g_return_val_if_fail(GTK_WIDGET_REALIZED(window), FALSE);
+  
+  if (need_init)
+    gnome_win_hints_init();
+  
+  prev_error = gdk_error_warnings;
+  gdk_error_warnings = 0;  
+  if (XGetWindowProperty(GDK_DISPLAY(), GDK_WINDOW_XWINDOW(window->window),
+			 _XA_WIN_APP_STATE, 0, 1, False, XA_CARDINAL, &r_type,
+			 &r_format, &count, &bytes_remain, &prop) == Success)
+    {
+      if (r_type == XA_CARDINAL && r_format == 32 && count == 4)
+	{
+	  if (x)
+	    *x = (gint)(((long *)prop)[0]);
+	  if (y)
+	    *y = (gint)(((long *)prop)[1]);
+	  if (width)
+	    *width = (gint)(((long *)prop)[2]);
+	  if (height)
+	    *height = (gint)(((long *)prop)[3]);
+	  XFree(prop);
+	  gdk_error_warnings = prev_error;
+	  return TRUE;
+	}
+      XFree(prop);
+    }
+  gdk_error_warnings = prev_error;
+  return FALSE;
+}
+
+void
+gnome_win_hints_set_app_state(GtkWidget *window,  GnomeWinAppState state)
+{
+  long data[1];
+  gint prev_error;
+
+  g_return_if_fail(window != NULL);
+  g_return_if_fail(GTK_IS_WIDGET(window));
+  g_return_if_fail(GTK_WIDGET_REALIZED(window));
+  
+  if (need_init)
+    gnome_win_hints_init();
+  
+  prev_error = gdk_error_warnings;
+  gdk_error_warnings = 0;  
+  
+  data[0] = (long)state;
+  XChangeProperty(GDK_DISPLAY(), GDK_WINDOW_XWINDOW(window->window),
+		  _XA_WIN_APP_STATE, XA_CARDINAL, 32, PropModeReplace,
+		  (unsigned char *)data, 1);
+  gdk_error_warnings = prev_error;
+}
+
+GnomeWinAppState
+gnome_win_hints_get_app_state(GtkWidget *window)
+{
+  GnomeWinAppState state;
+  Atom r_type;
+  int r_format;
+  unsigned long count;
+  unsigned long bytes_remain;
+  unsigned char *prop;
+  gint prev_error;
+
+  g_return_val_if_fail(window != NULL, WIN_APP_STATE_NONE);
+  g_return_val_if_fail(GTK_IS_WIDGET(window), WIN_APP_STATE_NONE);
+  g_return_val_if_fail(GTK_WIDGET_REALIZED(window), WIN_APP_STATE_NONE);
+  
+  if (need_init)
+    gnome_win_hints_init();
+  
+  prev_error = gdk_error_warnings;
+  gdk_error_warnings = 0;  
+  if (XGetWindowProperty(GDK_DISPLAY(), GDK_WINDOW_XWINDOW(window->window),
+			 _XA_WIN_APP_STATE, 0, 1, False, XA_CARDINAL, &r_type,
+			 &r_format, &count, &bytes_remain, &prop) == Success)
+    {
+      if (r_type == XA_CARDINAL && r_format == 32 && count == 2)
+	{
+	  state = (GnomeWinAppState)(((long *)prop)[0]);
+	  XFree(prop);
+	  gdk_error_warnings = prev_error;
+	  return state;
+	}
+      XFree(prop);
+    }
+  gdk_error_warnings = prev_error;
+  return WIN_APP_STATE_NONE;
+}
+
+void
+gnome_win_hints_set_moving(GtkWidget *window, gboolean moving)
+{
+  long data[1];
+  gint prev_error;
+  
+  g_return_if_fail(window != NULL);
+  g_return_if_fail(GTK_IS_WIDGET(window));
+  g_return_if_fail(GTK_WIDGET_REALIZED(window));
+
+  if (need_init)
+    gnome_win_hints_init();
+  
+  prev_error = gdk_error_warnings;
+  gdk_error_warnings = 0;  
+  
+  if (moving)
+    data[0] = 1;
+  else
+    data[0] = 0;
+  XChangeProperty(GDK_DISPLAY(), GDK_WINDOW_XWINDOW(window->window),
+		  _XA_WIN_CLIENT_MOVING, XA_CARDINAL, 32, PropModeReplace,
+		  (unsigned char *)data, 1);
+  gdk_error_warnings = prev_error;
+}
+
+gboolean
+gnome_win_hints_wm_exists(void)
+{
+  Atom r_type;
+  int r_format;
+  unsigned long count;
+  unsigned long bytes_remain;
+  unsigned char *prop, *prop2;
+  gint prev_error;
+  
+  if (need_init)
+    gnome_win_hints_init();
+  
+  prev_error = gdk_error_warnings;
+  gdk_error_warnings = 0;  
+  if (XGetWindowProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(),
+			 _XA_WIN_SUPPORTING_WM_CHECK, 0, 1, False, XA_CARDINAL,
+			 &r_type, &r_format,
+			 &count, &bytes_remain, &prop) == Success && prop)
+    {
+      if (r_type == XA_CARDINAL && r_format == 32 && count == 1)
+        {
+	  Window n = *(long *)prop;
+	  if (XGetWindowProperty(GDK_DISPLAY(), n,
+				 _XA_WIN_SUPPORTING_WM_CHECK, 0, 1, False, 
+				 XA_CARDINAL,
+				 &r_type, &r_format, &count, &bytes_remain, 
+				 &prop2) == Success && prop)
+	    {
+	      if (r_type == XA_CARDINAL && r_format == 32 && count == 1)
+		{
+		  XFree(prop);
+		  XFree(prop2);
+		  gdk_error_warnings = prev_error;
+		  return TRUE;
+		}
+	      XFree(prop2);
+	    }       
+        }
+      XFree(prop);
+    }       
+  gdk_error_warnings = prev_error;
+  return FALSE;
+}
+
+GList*
+gnome_win_hints_get_client_window_ids(void)
+{
+  GList *tmp_list;
+  Window *wlist;
+  int i;
+  Atom r_type;
+  int r_format;
+  unsigned long count;
+  unsigned long bytes_remain;
+  unsigned char *prop;
+  gint prev_error;
+  
+  if (need_init)
+    gnome_win_hints_init();
+  
+  prev_error = gdk_error_warnings;
+  gdk_error_warnings = 0;  
+  if (XGetWindowProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(), 
+			 _XA_WIN_CLIENT_LIST, 0, 1,
+			 False, XA_CARDINAL, &r_type, &r_format,
+			 &count, &bytes_remain, &prop) == Success)
+    {
+      if (r_type == XA_CARDINAL && r_format == 32)
+	{
+	  tmp_list = NULL;
+	  
+	  wlist = (Window *)prop;
+	  for(i=0; i<count; i++)
+	    {
+	      tmp_list = g_list_append(tmp_list, (gpointer)wlist[i]);
+	    }  
+	  XFree(prop);
+	  gdk_error_warnings = prev_error;
+	  return tmp_list;
+	}
+      XFree(prop);
+    }
+  gdk_error_warnings = prev_error;
+  return NULL;
+}
diff --git a/libgnomeui/gnome-winhints.h b/libgnomeui/gnome-winhints.h
new file mode 100644
index 0000000..efc4b74
--- /dev/null
+++ b/libgnomeui/gnome-winhints.h
@@ -0,0 +1,196 @@
+/* gnome-winhints.h:
+ * Copyright (C) 1998 Free Software Foundation
+ * All rights reserved.
+ *
+ * Convenience functions for working with XA_WIN_* hints.
+ *
+ * Written by: M.Watson <redline pdq net>
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+
+#ifndef GNOME_WINHINTS_H
+#define GNOME_WINHINTS_H
+
+
+#include <gtk/gtkwidget.h>
+
+G_BEGIN_DECLS
+
+/* The hints we recognize */
+#define XA_WIN_PROTOCOLS           "_WIN_PROTOCOLS"
+#define XA_WIN_ICONS               "_WIN_ICONS"
+#define XA_WIN_WORKSPACE           "_WIN_WORKSPACE"
+#define XA_WIN_WORKSPACE_COUNT     "_WIN_WORKSPACE_COUNT"
+#define XA_WIN_WORKSPACE_NAMES     "_WIN_WORKSPACE_NAMES"    
+#define XA_WIN_LAYER               "_WIN_LAYER"
+#define XA_WIN_STATE               "_WIN_STATE"
+#define XA_WIN_HINTS               "_WIN_HINTS"
+#define XA_WIN_WORKAREA            "_WIN_WORKAREA"
+#define XA_WIN_CLIENT_LIST         "_WIN_CLIENT_LIST"
+#define XA_WIN_APP_STATE           "_WIN_APP_STATE"
+#define XA_WIN_EXPANDED_SIZE       "_WIN_EXPANDED_SIZE"
+#define XA_WIN_CLIENT_MOVING       "_WIN_CLIENT_MOVING"
+#define XA_WIN_SUPPORTING_WM_CHECK "_WIN_SUPPORTING_WM_CHECK"
+
+/* flags for the window layer */
+typedef enum
+{
+  WIN_LAYER_DESKTOP     = 0,
+  WIN_LAYER_BELOW       = 2,
+  WIN_LAYER_NORMAL      = 4,
+  WIN_LAYER_ONTOP       = 6,
+  WIN_LAYER_DOCK        = 8,
+  WIN_LAYER_ABOVE_DOCK  = 10
+} GnomeWinLayer;
+
+/* flags for the window state */
+typedef enum
+{
+  WIN_STATE_STICKY          = (1<<0), /* everyone knows sticky */
+  WIN_STATE_MINIMIZED       = (1<<1), /* ??? */
+  WIN_STATE_MAXIMIZED_VERT  = (1<<2), /* window in maximized V state */
+  WIN_STATE_MAXIMIZED_HORIZ = (1<<3), /* window in maximized H state */
+  WIN_STATE_HIDDEN          = (1<<4), /* not on taskbar but window visible */
+  WIN_STATE_SHADED          = (1<<5), /* shaded (NeXT style) */
+  WIN_STATE_HID_WORKSPACE   = (1<<6), /* not on current desktop */
+  WIN_STATE_HID_TRANSIENT   = (1<<7), /* owner of transient is hidden */
+  WIN_STATE_FIXED_POSITION  = (1<<8), /* window is fixed in position even */
+  WIN_STATE_ARRANGE_IGNORE  = (1<<9)  /* ignore for auto arranging */
+} GnomeWinState;
+
+/* flags for skip hint */
+typedef enum
+{
+  WIN_HINTS_SKIP_FOCUS      = (1<<0), /* "alt-tab" skips this win */
+  WIN_HINTS_SKIP_WINLIST    = (1<<1), /* not in win list */
+  WIN_HINTS_SKIP_TASKBAR    = (1<<2), /* not on taskbar */
+  WIN_HINTS_GROUP_TRANSIENT = (1<<3), /* ??????? */
+  WIN_HINTS_FOCUS_ON_CLICK  = (1<<4), /* app only accepts focus when clicked */
+  WIN_HINTS_DO_NOT_COVER    = (1<<5)  /* attempt to not cover this window */
+} GnomeWinHints;
+
+typedef enum
+{
+  WIN_APP_STATE_NONE,
+  WIN_APP_STATE_ACTIVE1,
+  WIN_APP_STATE_ACTIVE2,
+  WIN_APP_STATE_ERROR1,
+  WIN_APP_STATE_ERROR2,
+  WIN_APP_STATE_FATAL_ERROR1,
+  WIN_APP_STATE_FATAL_ERROR2,
+  WIN_APP_STATE_IDLE1,
+  WIN_APP_STATE_IDLE2,
+  WIN_APP_STATE_WAITING1,
+  WIN_APP_STATE_WAITING2,
+  WIN_APP_STATE_WORKING1,
+  WIN_APP_STATE_WORKING2,
+  WIN_APP_STATE_NEED_USER_INPUT1,
+  WIN_APP_STATE_NEED_USER_INPUT2,
+  WIN_APP_STATE_STRUGGLING1,
+  WIN_APP_STATE_STRUGGLING2,
+  WIN_APP_STATE_DISK_TRAFFIC1,
+  WIN_APP_STATE_DISK_TRAFFIC2,
+  WIN_APP_STATE_NETWORK_TRAFFIC1,
+  WIN_APP_STATE_NETWORK_TRAFFIC2,
+  WIN_APP_STATE_OVERLOADED1,
+  WIN_APP_STATE_OVERLOADED2,
+  WIN_APP_STATE_PERCENT000_1,
+  WIN_APP_STATE_PERCENT000_2,
+  WIN_APP_STATE_PERCENT010_1,
+  WIN_APP_STATE_PERCENT010_2,
+  WIN_APP_STATE_PERCENT020_1,
+  WIN_APP_STATE_PERCENT020_2,
+  WIN_APP_STATE_PERCENT030_1,
+  WIN_APP_STATE_PERCENT030_2,
+  WIN_APP_STATE_PERCENT040_1,
+  WIN_APP_STATE_PERCENT040_2,
+  WIN_APP_STATE_PERCENT050_1,
+  WIN_APP_STATE_PERCENT050_2,
+  WIN_APP_STATE_PERCENT060_1,
+  WIN_APP_STATE_PERCENT060_2,
+  WIN_APP_STATE_PERCENT070_1,
+  WIN_APP_STATE_PERCENT070_2,
+  WIN_APP_STATE_PERCENT080_1,
+  WIN_APP_STATE_PERCENT080_2,
+  WIN_APP_STATE_PERCENT090_1,
+  WIN_APP_STATE_PERCENT090_2,
+  WIN_APP_STATE_PERCENT100_1,
+  WIN_APP_STATE_PERCENT100_2
+} GnomeWinAppState;
+
+/* Called during gnome initiailisation */
+void
+gnome_win_hints_init(void);
+
+void
+gnome_win_hints_set_layer(GtkWidget *window, GnomeWinLayer layer);
+GnomeWinLayer
+gnome_win_hints_get_layer(GtkWidget *window);
+
+
+void
+gnome_win_hints_set_state(GtkWidget *window, GnomeWinState state);
+GnomeWinState
+gnome_win_hints_get_state(GtkWidget *window);
+
+void
+gnome_win_hints_set_hints(GtkWidget *window, GnomeWinHints skip);
+GnomeWinHints
+gnome_win_hints_get_hints(GtkWidget *window);
+
+void
+gnome_win_hints_set_workspace(GtkWidget *window, gint workspace);
+gint
+gnome_win_hints_get_workspace(GtkWidget *window);
+
+void
+gnome_win_hints_set_current_workspace(gint workspace);
+gint
+gnome_win_hints_get_current_workspace(void);
+
+GList*
+gnome_win_hints_get_workspace_names(void);
+gint
+gnome_win_hints_get_workspace_count(void);
+
+void
+gnome_win_hints_set_expanded_size(GtkWidget *window, gint x, gint y, gint width, gint height);
+gboolean
+gnome_win_hints_get_expanded_size(GtkWidget *window, gint *x, gint *y, gint *width, gint *height);
+
+void
+gnome_win_hints_set_moving(GtkWidget *window, gboolean moving);
+
+void
+gnome_win_hints_set_app_state(GtkWidget *window,  GnomeWinAppState state);
+GnomeWinAppState
+gnome_win_hints_get_app_state(GtkWidget *window);
+
+void
+gnome_win_hints_set_moving(GtkWidget *window, gboolean moving);
+
+gboolean
+gnome_win_hints_wm_exists(void);
+
+GList*
+gnome_win_hints_get_client_window_ids(void);
+
+G_END_DECLS
+
+#endif
diff --git a/libgnomeui/gnome.defs b/libgnomeui/gnome.defs
new file mode 100644
index 0000000..2040891
--- /dev/null
+++ b/libgnomeui/gnome.defs
@@ -0,0 +1,289 @@
+;; generated by makeenums.pl  ; -*- scheme -*-
+
+
+; enumerations from "gnome-animator.h"
+
+(define-enum GnomeAnimatorStatus
+   (stopped GNOME_ANIMATOR_STATUS_STOPPED)
+   (running GNOME_ANIMATOR_STATUS_RUNNING))
+
+(define-enum GnomeAnimatorLoopType
+   (none GNOME_ANIMATOR_LOOP_NONE)
+   (restart GNOME_ANIMATOR_LOOP_RESTART)
+   (ping-pong GNOME_ANIMATOR_LOOP_PING_PONG))
+
+; enumerations from "gnome-app-helper.h"
+
+(define-enum GnomeUIInfoType
+   (endofinfo GNOME_APP_UI_ENDOFINFO)
+   (item GNOME_APP_UI_ITEM)
+   (toggleitem GNOME_APP_UI_TOGGLEITEM)
+   (radioitems GNOME_APP_UI_RADIOITEMS)
+   (subtree GNOME_APP_UI_SUBTREE)
+   (separator GNOME_APP_UI_SEPARATOR)
+   (help GNOME_APP_UI_HELP)
+   (builder-data GNOME_APP_UI_BUILDER_DATA)
+   (item-configurable GNOME_APP_UI_ITEM_CONFIGURABLE)
+   (subtree-stock GNOME_APP_UI_SUBTREE_STOCK))
+
+(define-enum GnomeUIInfoConfigurableTypes
+   (new GNOME_APP_CONFIGURABLE_ITEM_NEW)
+   (open GNOME_APP_CONFIGURABLE_ITEM_OPEN)
+   (save GNOME_APP_CONFIGURABLE_ITEM_SAVE)
+   (save-as GNOME_APP_CONFIGURABLE_ITEM_SAVE_AS)
+   (revert GNOME_APP_CONFIGURABLE_ITEM_REVERT)
+   (print GNOME_APP_CONFIGURABLE_ITEM_PRINT)
+   (print-setup GNOME_APP_CONFIGURABLE_ITEM_PRINT_SETUP)
+   (close GNOME_APP_CONFIGURABLE_ITEM_CLOSE)
+   (exit GNOME_APP_CONFIGURABLE_ITEM_EXIT)
+   (cut GNOME_APP_CONFIGURABLE_ITEM_CUT)
+   (copy GNOME_APP_CONFIGURABLE_ITEM_COPY)
+   (paste GNOME_APP_CONFIGURABLE_ITEM_PASTE)
+   (clear GNOME_APP_CONFIGURABLE_ITEM_CLEAR)
+   (undo GNOME_APP_CONFIGURABLE_ITEM_UNDO)
+   (redo GNOME_APP_CONFIGURABLE_ITEM_REDO)
+   (find GNOME_APP_CONFIGURABLE_ITEM_FIND)
+   (find-again GNOME_APP_CONFIGURABLE_ITEM_FIND_AGAIN)
+   (replace GNOME_APP_CONFIGURABLE_ITEM_REPLACE)
+   (properties GNOME_APP_CONFIGURABLE_ITEM_PROPERTIES)
+   (preferences GNOME_APP_CONFIGURABLE_ITEM_PREFERENCES)
+   (about GNOME_APP_CONFIGURABLE_ITEM_ABOUT)
+   (select-all GNOME_APP_CONFIGURABLE_ITEM_SELECT_ALL)
+   (new-window GNOME_APP_CONFIGURABLE_ITEM_NEW_WINDOW)
+   (close-window GNOME_APP_CONFIGURABLE_ITEM_CLOSE_WINDOW)
+   (new-game GNOME_APP_CONFIGURABLE_ITEM_NEW_GAME)
+   (pause-game GNOME_APP_CONFIGURABLE_ITEM_PAUSE_GAME)
+   (restart-game GNOME_APP_CONFIGURABLE_ITEM_RESTART_GAME)
+   (undo-move GNOME_APP_CONFIGURABLE_ITEM_UNDO_MOVE)
+   (redo-move GNOME_APP_CONFIGURABLE_ITEM_REDO_MOVE)
+   (hint GNOME_APP_CONFIGURABLE_ITEM_HINT)
+   (scores GNOME_APP_CONFIGURABLE_ITEM_SCORES)
+   (end-game GNOME_APP_CONFIGURABLE_ITEM_END_GAME))
+
+(define-enum GnomeUIPixmapType
+   (none GNOME_APP_PIXMAP_NONE)
+   (stock GNOME_APP_PIXMAP_STOCK)
+   (data GNOME_APP_PIXMAP_DATA)
+   (filename GNOME_APP_PIXMAP_FILENAME))
+
+; enumerations from "gnome-calculator.h"
+
+(define-enum GnomeCalculatorMode
+   (deg GNOME_CALCULATOR_DEG)
+   (rad GNOME_CALCULATOR_RAD)
+   (grad GNOME_CALCULATOR_GRAD))
+
+; enumerations from "gnome-client.h"
+
+(define-enum GnomeInteractStyle
+   (none GNOME_INTERACT_NONE)
+   (errors GNOME_INTERACT_ERRORS)
+   (any GNOME_INTERACT_ANY))
+
+(define-enum GnomeDialogType
+   (error GNOME_DIALOG_ERROR)
+   (normal GNOME_DIALOG_NORMAL))
+
+(define-enum GnomeSaveStyle
+   (global GNOME_SAVE_GLOBAL)
+   (local GNOME_SAVE_LOCAL)
+   (both GNOME_SAVE_BOTH))
+
+(define-enum GnomeRestartStyle
+   (if-running GNOME_RESTART_IF_RUNNING)
+   (anyway GNOME_RESTART_ANYWAY)
+   (immediately GNOME_RESTART_IMMEDIATELY)
+   (never GNOME_RESTART_NEVER))
+
+(define-enum GnomeClientState
+   (idle GNOME_CLIENT_IDLE)
+   (saving-phase-1 GNOME_CLIENT_SAVING_PHASE_1)
+   (waiting-for-phase-2 GNOME_CLIENT_WAITING_FOR_PHASE_2)
+   (saving-phase-2 GNOME_CLIENT_SAVING_PHASE_2)
+   (frozen GNOME_CLIENT_FROZEN)
+   (disconnected GNOME_CLIENT_DISCONNECTED)
+   (registering GNOME_CLIENT_REGISTERING))
+
+(define-flags GnomeClientFlags
+   (is-connected GNOME_CLIENT_IS_CONNECTED)
+   (restarted GNOME_CLIENT_RESTARTED)
+   (restored GNOME_CLIENT_RESTORED))
+
+; enumerations from "gnome-dateedit.h"
+
+(define-flags GnomeDateEditFlags
+   (show-time GNOME_DATE_EDIT_SHOW_TIME)
+   (24-hr GNOME_DATE_EDIT_24_HR)
+   (week-starts-on-monday GNOME_DATE_EDIT_WEEK_STARTS_ON_MONDAY))
+
+; enumerations from "gnome-dock.h"
+
+(define-enum GnomeDockPlacement
+   (top GNOME_DOCK_TOP)
+   (right GNOME_DOCK_RIGHT)
+   (bottom GNOME_DOCK_BOTTOM)
+   (left GNOME_DOCK_LEFT)
+   (floating GNOME_DOCK_FLOATING))
+
+; enumerations from "gnome-dock-item.h"
+
+(define-flags GnomeDockItemBehavior
+   (normal GNOME_DOCK_ITEM_BEH_NORMAL)
+   (exclusive GNOME_DOCK_ITEM_BEH_EXCLUSIVE)
+   (never-floating GNOME_DOCK_ITEM_BEH_NEVER_FLOATING)
+   (never-vertical GNOME_DOCK_ITEM_BEH_NEVER_VERTICAL)
+   (never-horizontal GNOME_DOCK_ITEM_BEH_NEVER_HORIZONTAL)
+   (locked GNOME_DOCK_ITEM_BEH_LOCKED))
+
+; enumerations from "gnome-font-picker.h"
+
+(define-enum GnomeFontPickerMode
+   (pixmap GNOME_FONT_PICKER_MODE_PIXMAP)
+   (font-info GNOME_FONT_PICKER_MODE_FONT_INFO)
+   (user-widget GNOME_FONT_PICKER_MODE_USER_WIDGET)
+   (unknown GNOME_FONT_PICKER_MODE_UNKNOWN))
+
+; enumerations from "gnome-icon-list.h"
+
+(define-enum GnomeIconListMode
+   (icons GNOME_ICON_LIST_ICONS)
+   (text-below GNOME_ICON_LIST_TEXT_BELOW)
+   (text-right GNOME_ICON_LIST_TEXT_RIGHT))
+
+; enumerations from "gnome-mdi.h"
+
+(define-enum GnomeMDIMode
+   (notebook GNOME_MDI_NOTEBOOK)
+   (toplevel GNOME_MDI_TOPLEVEL)
+   (modal GNOME_MDI_MODAL)
+   (default-mode GNOME_MDI_DEFAULT_MODE))
+
+; enumerations from "gnome-properties.h"
+
+(define-enum GnomePropertyAction
+   (apply GNOME_PROPERTY_ACTION_APPLY)
+   (update GNOME_PROPERTY_ACTION_UPDATE)
+   (load GNOME_PROPERTY_ACTION_LOAD)
+   (save GNOME_PROPERTY_ACTION_SAVE)
+   (load-temp GNOME_PROPERTY_ACTION_LOAD_TEMP)
+   (save-temp GNOME_PROPERTY_ACTION_SAVE_TEMP)
+   (discard-temp GNOME_PROPERTY_ACTION_DISCARD_TEMP)
+   (changed GNOME_PROPERTY_ACTION_CHANGED))
+
+; enumerations from "gnome-stock.h"
+
+(define-enum GnomeStockPixmapType
+   (none GNOME_STOCK_PIXMAP_TYPE_NONE)
+   (data GNOME_STOCK_PIXMAP_TYPE_DATA)
+   (file GNOME_STOCK_PIXMAP_TYPE_FILE)
+   (path GNOME_STOCK_PIXMAP_TYPE_PATH)
+   (widget GNOME_STOCK_PIXMAP_TYPE_WIDGET)
+   (imlib GNOME_STOCK_PIXMAP_TYPE_IMLIB)
+   (imlib-scaled GNOME_STOCK_PIXMAP_TYPE_IMLIB_SCALED)
+   (gpixmap GNOME_STOCK_PIXMAP_TYPE_GPIXMAP))
+
+; enumerations from "gnome-types.h"
+
+(define-enum GnomePreferencesType
+   (never GNOME_PREFERENCES_NEVER)
+   (user GNOME_PREFERENCES_USER)
+   (always GNOME_PREFERENCES_ALWAYS))
+
+; enumerations from "gnome-winhints.h"
+
+(define-enum GnomeWinLayer
+   (desktop WIN_LAYER_DESKTOP)
+   (below WIN_LAYER_BELOW)
+   (normal WIN_LAYER_NORMAL)
+   (ontop WIN_LAYER_ONTOP)
+   (dock WIN_LAYER_DOCK)
+   (above-dock WIN_LAYER_ABOVE_DOCK))
+
+(define-flags GnomeWinState
+   (sticky WIN_STATE_STICKY)
+   (minimized WIN_STATE_MINIMIZED)
+   (maximized-vert WIN_STATE_MAXIMIZED_VERT)
+   (maximized-horiz WIN_STATE_MAXIMIZED_HORIZ)
+   (hidden WIN_STATE_HIDDEN)
+   (shaded WIN_STATE_SHADED)
+   (hid-workspace WIN_STATE_HID_WORKSPACE)
+   (hid-transient WIN_STATE_HID_TRANSIENT)
+   (fixed-position WIN_STATE_FIXED_POSITION)
+   (arrange-ignore WIN_STATE_ARRANGE_IGNORE))
+
+(define-flags GnomeWinHints
+   (skip-focus WIN_HINTS_SKIP_FOCUS)
+   (skip-winlist WIN_HINTS_SKIP_WINLIST)
+   (skip-taskbar WIN_HINTS_SKIP_TASKBAR)
+   (group-transient WIN_HINTS_GROUP_TRANSIENT)
+   (focus-on-click WIN_HINTS_FOCUS_ON_CLICK)
+   (do-not-cover WIN_HINTS_DO_NOT_COVER))
+
+(define-enum GnomeWinAppState
+   (none WIN_APP_STATE_NONE)
+   (active1 WIN_APP_STATE_ACTIVE1)
+   (active2 WIN_APP_STATE_ACTIVE2)
+   (error1 WIN_APP_STATE_ERROR1)
+   (error2 WIN_APP_STATE_ERROR2)
+   (fatal-error1 WIN_APP_STATE_FATAL_ERROR1)
+   (fatal-error2 WIN_APP_STATE_FATAL_ERROR2)
+   (idle1 WIN_APP_STATE_IDLE1)
+   (idle2 WIN_APP_STATE_IDLE2)
+   (waiting1 WIN_APP_STATE_WAITING1)
+   (waiting2 WIN_APP_STATE_WAITING2)
+   (working1 WIN_APP_STATE_WORKING1)
+   (working2 WIN_APP_STATE_WORKING2)
+   (need-user-input1 WIN_APP_STATE_NEED_USER_INPUT1)
+   (need-user-input2 WIN_APP_STATE_NEED_USER_INPUT2)
+   (struggling1 WIN_APP_STATE_STRUGGLING1)
+   (struggling2 WIN_APP_STATE_STRUGGLING2)
+   (disk-traffic1 WIN_APP_STATE_DISK_TRAFFIC1)
+   (disk-traffic2 WIN_APP_STATE_DISK_TRAFFIC2)
+   (network-traffic1 WIN_APP_STATE_NETWORK_TRAFFIC1)
+   (network-traffic2 WIN_APP_STATE_NETWORK_TRAFFIC2)
+   (overloaded1 WIN_APP_STATE_OVERLOADED1)
+   (overloaded2 WIN_APP_STATE_OVERLOADED2)
+   (percent000-1 WIN_APP_STATE_PERCENT000_1)
+   (percent000-2 WIN_APP_STATE_PERCENT000_2)
+   (percent010-1 WIN_APP_STATE_PERCENT010_1)
+   (percent010-2 WIN_APP_STATE_PERCENT010_2)
+   (percent020-1 WIN_APP_STATE_PERCENT020_1)
+   (percent020-2 WIN_APP_STATE_PERCENT020_2)
+   (percent030-1 WIN_APP_STATE_PERCENT030_1)
+   (percent030-2 WIN_APP_STATE_PERCENT030_2)
+   (percent040-1 WIN_APP_STATE_PERCENT040_1)
+   (percent040-2 WIN_APP_STATE_PERCENT040_2)
+   (percent050-1 WIN_APP_STATE_PERCENT050_1)
+   (percent050-2 WIN_APP_STATE_PERCENT050_2)
+   (percent060-1 WIN_APP_STATE_PERCENT060_1)
+   (percent060-2 WIN_APP_STATE_PERCENT060_2)
+   (percent070-1 WIN_APP_STATE_PERCENT070_1)
+   (percent070-2 WIN_APP_STATE_PERCENT070_2)
+   (percent080-1 WIN_APP_STATE_PERCENT080_1)
+   (percent080-2 WIN_APP_STATE_PERCENT080_2)
+   (percent090-1 WIN_APP_STATE_PERCENT090_1)
+   (percent090-2 WIN_APP_STATE_PERCENT090_2)
+   (percent100-1 WIN_APP_STATE_PERCENT100_1)
+   (percent100-2 WIN_APP_STATE_PERCENT100_2))
+
+; enumerations from "gtk-clock.h"
+
+(define-enum GtkClockType
+   (increasing GTK_CLOCK_INCREASING)
+   (decreasing GTK_CLOCK_DECREASING)
+   (realtime GTK_CLOCK_REALTIME))
+; -*- scheme -*-
+
+; These definitions here cause the creation of some new GTK_TYPE_* ids
+; The code doesn't benefit most C programs directly, but is very useful
+; for language bindings.
+
+;; Maybe this should be defined in a gdk_imlib specific library -- but
+;; gdk_imlib has no gtk+ code in it.
+(define-boxed GdkImlibImage
+)
+
+;; An array of points used by GnomeCanvasLine and GnomeCanvasPolygon
+(define-boxed GnomeCanvasPoints
+)
+
diff --git a/libgnomeui/gnome_segv.c b/libgnomeui/gnome_segv.c
new file mode 100644
index 0000000..5f29408
--- /dev/null
+++ b/libgnomeui/gnome_segv.c
@@ -0,0 +1,199 @@
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
+/*
+ * Copyright (C) 1999, 2000 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * 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 the Gnome Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#include <config.h>
+
+/* needed for sigaction and friends under 'gcc -ansi -pedantic' on 
+ * GNU/Linux */
+#ifndef _POSIX_SOURCE
+#  define _POSIX_SOURCE 1
+#endif
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <errno.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <gnome.h>
+#include <signal.h>
+#include <string.h>
+#include <stdio.h>
+
+enum {
+  RESPONSE_NULL,
+  RESPONSE_BUG_BUDDY,
+  RESPONSE_DEBUG
+};
+
+int main(int argc, char *argv[])
+{
+  GtkWidget *mainwin, *urlbtn;
+  gchar* msg;
+  struct sigaction sa;
+  poptContext ctx;
+  const char **args;
+  char *urlstr;
+  const char *app_version = NULL;
+  int res;
+  gchar *appname;
+  gchar *bug_buddy_path = NULL;
+  const char *debugger = NULL;
+  gchar *debugger_path = NULL;
+  
+  int bb_sm_disable = 0;
+
+  /* We do this twice to make sure we don't start running ourselves... :) */
+  memset(&sa, 0, sizeof(sa));
+  sa.sa_handler = SIG_IGN;
+  sigaction(SIGSEGV, &sa, NULL);
+
+
+  bindtextdomain (PACKAGE, GNOMEUILOCALEDIR);
+  textdomain (PACKAGE);
+
+  /* in case gnome-session is segfaulting :-) */
+  gnome_client_disable_master_connection();
+  
+  gnome_init_with_popt_table("gnome_segv", VERSION, argc, argv, NULL, 0, &ctx);
+
+  memset(&sa, 0, sizeof(sa));
+  sa.sa_handler = SIG_IGN;
+  sigaction(SIGSEGV, &sa, NULL);
+
+  args = poptGetArgs(ctx);
+  if (args && args[0] && args[1])
+    {
+      char *base = g_path_get_basename (args[0]);
+      if (strcmp(base, "gnome-session") == 0)
+        {
+          msg = g_strdup_printf(_("The GNOME Session Manager (process %d) has crashed\n"
+                                  "due to a fatal error (%s).\n"
+                                  "When you close this dialog, all applications will close "
+                                  "and your session will exit.\n"
+                                  "Please save all your files before closing this dialog."),
+                                getppid(), g_strsignal(atoi(args[1])));
+          bb_sm_disable = 1;
+        }
+      else
+        {
+          msg = g_strdup_printf(_("Application \"%s\" (process %d) has crashed\ndue to a fatal error.\n(%s)"),
+                                args[0], getppid(), g_strsignal(atoi(args[1])));
+        }
+      g_free(base);
+      if(args[2])
+	app_version = args[2];
+    }
+  else
+    {
+      fprintf(stderr, _("Usage: gnome_segv appname signum\n"));
+      return 1;
+    }
+  appname = g_strdup(args[0]);
+
+  mainwin = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
+                                    GTK_MESSAGE_ERROR,
+                                    GTK_BUTTONS_CLOSE,
+                                    msg);
+
+
+  
+  bug_buddy_path = gnome_is_program_in_path ("bug-buddy");
+  if (bug_buddy_path != NULL)
+    {
+      gtk_dialog_add_button(GTK_DIALOG(mainwin),
+                            _("Submit a bug report"),
+                            RESPONSE_BUG_BUDDY);
+    }
+
+  debugger = g_getenv("GNOME_DEBUGGER");
+  if (debugger && strlen(debugger)>0)
+  {
+    debugger_path = gnome_is_program_in_path (debugger);
+    if (debugger_path != NULL)
+      {
+        gtk_dialog_add_button(GTK_DIALOG(mainwin),
+                              _("Debug"),
+                              RESPONSE_DEBUG);
+      }
+  }
+  
+  /* Please download http://www.gnome.org/application_crashed-shtml.txt,
+   * translate the plain text, and send the file to webmaster gnome org  */
+  urlstr = g_strdup_printf("%s?app=%s%s%s&libsver=%s", 
+		_("http://www.gnome.org/application_crashed.shtml";),
+		args[0],
+		app_version?"&version=":"",
+		app_version?app_version:"",
+		VERSION);
+  urlbtn = gnome_href_new(urlstr,
+                          _("Please visit the GNOME Application Crash page for more information"));
+  gtk_widget_show(urlbtn);
+  gtk_container_add(GTK_CONTAINER(GTK_DIALOG(mainwin)->vbox), urlbtn);
+
+  g_free(msg);
+
+  res = gtk_dialog_run(GTK_DIALOG(mainwin));
+
+  if (res == RESPONSE_BUG_BUDDY && (bug_buddy_path != NULL))
+    {
+      gchar *exec_str;
+      int retval;
+
+      g_assert(bug_buddy_path);
+      exec_str = g_strdup_printf("%s --appname=\"%s\" --pid=%d "
+                                 "--package-ver=\"%s\" %s", 
+                                 bug_buddy_path, appname, getppid(), 
+                                 app_version, bb_sm_disable 
+                                 ? "--sm-disable" : "");
+
+      retval = system(exec_str);
+      g_free(exec_str);
+      if (retval == -1 || retval == 127)
+        {
+          g_warning("Couldn't run bug-buddy: %s", g_strerror(errno));
+        }
+    }
+  else if (res == RESPONSE_DEBUG || (res == RESPONSE_BUG_BUDDY && (bug_buddy_path == NULL)))
+    {
+      gchar *exec_str;
+      int retval;
+
+      g_assert (debugger_path);
+      exec_str = g_strdup_printf("%s --appname=\"%s\" --pid=%d "
+                                 "--package-ver=\"%s\" %s", 
+                                 debugger_path, appname, getppid(), 
+                                 app_version, bb_sm_disable 
+                                 ? "--sm-disable" : "");
+
+      retval = system(exec_str);
+      g_free(exec_str);
+      if (retval == -1 || retval == 127)
+        {
+          g_warning("Couldn't run debugger: %s", g_strerror(errno));
+        }
+    }
+
+  return 0;
+}
diff --git a/libgnomeui/gnometypebuiltins.h b/libgnomeui/gnometypebuiltins.h
new file mode 100644
index 0000000..6499296
--- /dev/null
+++ b/libgnomeui/gnometypebuiltins.h
@@ -0,0 +1,30 @@
+/* type macros, generated by maketypes.awk */
+
+extern GtkType GTK_TYPE_GNOME_UI_INFO_TYPE;
+extern GtkType GTK_TYPE_GNOME_UI_INFO_CONFIGURABLE_TYPES;
+extern GtkType GTK_TYPE_GNOME_UI_PIXMAP_TYPE;
+extern GtkType GTK_TYPE_GNOME_CALCULATOR_MODE;
+extern GtkType GTK_TYPE_GNOME_INTERACT_STYLE;
+extern GtkType GTK_TYPE_GNOME_DIALOG_TYPE;
+extern GtkType GTK_TYPE_GNOME_SAVE_STYLE;
+extern GtkType GTK_TYPE_GNOME_RESTART_STYLE;
+extern GtkType GTK_TYPE_GNOME_CLIENT_STATE;
+extern GtkType GTK_TYPE_GNOME_CLIENT_FLAGS;
+extern GtkType GTK_TYPE_GNOME_DATE_EDIT_FLAGS;
+extern GtkType GTK_TYPE_GNOME_DOCK_PLACEMENT;
+extern GtkType GTK_TYPE_GNOME_DOCK_ITEM_BEHAVIOR;
+extern GtkType GTK_TYPE_GNOME_EDGE_POSITION;
+extern GtkType GTK_TYPE_GNOME_FONT_PICKER_MODE;
+extern GtkType GTK_TYPE_GNOME_HELP_VIEW_STYLE;
+extern GtkType GTK_TYPE_GNOME_MDI_MODE;
+extern GtkType GTK_TYPE_GNOME_PIXMAP_DRAW;
+extern GtkType GTK_TYPE_GNOME_PREFERENCES_TYPE;
+extern GtkType GTK_TYPE_GNOME_WIN_LAYER;
+extern GtkType GTK_TYPE_GNOME_WIN_STATE;
+extern GtkType GTK_TYPE_GNOME_WIN_HINTS;
+extern GtkType GTK_TYPE_GNOME_WIN_APP_STATE;
+extern GtkType GTK_TYPE_CLOCK_TYPE;
+extern GtkType GTK_TYPE_GDK_IMLIB_IMAGE;
+extern GtkType GTK_TYPE_GNOME_CANVAS_POINTS;
+
+#define	GNOME_TYPE_NUM_BUILTINS	(26)
diff --git a/libgnomeui/gnometypebuiltins_evals.c b/libgnomeui/gnometypebuiltins_evals.c
new file mode 100644
index 0000000..aaada48
--- /dev/null
+++ b/libgnomeui/gnometypebuiltins_evals.c
@@ -0,0 +1,249 @@
+/* Generated by makeenums.pl */
+
+static const GtkEnumValue _gnome_ui_info_type_values[] = {
+  { GNOME_APP_UI_ENDOFINFO, "GNOME_APP_UI_ENDOFINFO", "endofinfo" },
+  { GNOME_APP_UI_ITEM, "GNOME_APP_UI_ITEM", "item" },
+  { GNOME_APP_UI_TOGGLEITEM, "GNOME_APP_UI_TOGGLEITEM", "toggleitem" },
+  { GNOME_APP_UI_RADIOITEMS, "GNOME_APP_UI_RADIOITEMS", "radioitems" },
+  { GNOME_APP_UI_SUBTREE, "GNOME_APP_UI_SUBTREE", "subtree" },
+  { GNOME_APP_UI_SEPARATOR, "GNOME_APP_UI_SEPARATOR", "separator" },
+  { GNOME_APP_UI_HELP, "GNOME_APP_UI_HELP", "help" },
+  { GNOME_APP_UI_BUILDER_DATA, "GNOME_APP_UI_BUILDER_DATA", "builder-data" },
+  { GNOME_APP_UI_ITEM_CONFIGURABLE, "GNOME_APP_UI_ITEM_CONFIGURABLE", "item-configurable" },
+  { GNOME_APP_UI_SUBTREE_STOCK, "GNOME_APP_UI_SUBTREE_STOCK", "subtree-stock" },
+  { GNOME_APP_UI_INCLUDE, "GNOME_APP_UI_INCLUDE", "include" },
+  { 0, NULL, NULL }
+};
+static const GtkEnumValue _gnome_ui_info_configurable_types_values[] = {
+  { GNOME_APP_CONFIGURABLE_ITEM_NEW, "GNOME_APP_CONFIGURABLE_ITEM_NEW", "new" },
+  { GNOME_APP_CONFIGURABLE_ITEM_OPEN, "GNOME_APP_CONFIGURABLE_ITEM_OPEN", "open" },
+  { GNOME_APP_CONFIGURABLE_ITEM_SAVE, "GNOME_APP_CONFIGURABLE_ITEM_SAVE", "save" },
+  { GNOME_APP_CONFIGURABLE_ITEM_SAVE_AS, "GNOME_APP_CONFIGURABLE_ITEM_SAVE_AS", "save-as" },
+  { GNOME_APP_CONFIGURABLE_ITEM_REVERT, "GNOME_APP_CONFIGURABLE_ITEM_REVERT", "revert" },
+  { GNOME_APP_CONFIGURABLE_ITEM_PRINT, "GNOME_APP_CONFIGURABLE_ITEM_PRINT", "print" },
+  { GNOME_APP_CONFIGURABLE_ITEM_PRINT_SETUP, "GNOME_APP_CONFIGURABLE_ITEM_PRINT_SETUP", "print-setup" },
+  { GNOME_APP_CONFIGURABLE_ITEM_CLOSE, "GNOME_APP_CONFIGURABLE_ITEM_CLOSE", "close" },
+  { GNOME_APP_CONFIGURABLE_ITEM_EXIT, "GNOME_APP_CONFIGURABLE_ITEM_EXIT", "exit" },
+  { GNOME_APP_CONFIGURABLE_ITEM_CUT, "GNOME_APP_CONFIGURABLE_ITEM_CUT", "cut" },
+  { GNOME_APP_CONFIGURABLE_ITEM_COPY, "GNOME_APP_CONFIGURABLE_ITEM_COPY", "copy" },
+  { GNOME_APP_CONFIGURABLE_ITEM_PASTE, "GNOME_APP_CONFIGURABLE_ITEM_PASTE", "paste" },
+  { GNOME_APP_CONFIGURABLE_ITEM_CLEAR, "GNOME_APP_CONFIGURABLE_ITEM_CLEAR", "clear" },
+  { GNOME_APP_CONFIGURABLE_ITEM_UNDO, "GNOME_APP_CONFIGURABLE_ITEM_UNDO", "undo" },
+  { GNOME_APP_CONFIGURABLE_ITEM_REDO, "GNOME_APP_CONFIGURABLE_ITEM_REDO", "redo" },
+  { GNOME_APP_CONFIGURABLE_ITEM_FIND, "GNOME_APP_CONFIGURABLE_ITEM_FIND", "find" },
+  { GNOME_APP_CONFIGURABLE_ITEM_FIND_AGAIN, "GNOME_APP_CONFIGURABLE_ITEM_FIND_AGAIN", "find-again" },
+  { GNOME_APP_CONFIGURABLE_ITEM_REPLACE, "GNOME_APP_CONFIGURABLE_ITEM_REPLACE", "replace" },
+  { GNOME_APP_CONFIGURABLE_ITEM_PROPERTIES, "GNOME_APP_CONFIGURABLE_ITEM_PROPERTIES", "properties" },
+  { GNOME_APP_CONFIGURABLE_ITEM_PREFERENCES, "GNOME_APP_CONFIGURABLE_ITEM_PREFERENCES", "preferences" },
+  { GNOME_APP_CONFIGURABLE_ITEM_ABOUT, "GNOME_APP_CONFIGURABLE_ITEM_ABOUT", "about" },
+  { GNOME_APP_CONFIGURABLE_ITEM_SELECT_ALL, "GNOME_APP_CONFIGURABLE_ITEM_SELECT_ALL", "select-all" },
+  { GNOME_APP_CONFIGURABLE_ITEM_NEW_WINDOW, "GNOME_APP_CONFIGURABLE_ITEM_NEW_WINDOW", "new-window" },
+  { GNOME_APP_CONFIGURABLE_ITEM_CLOSE_WINDOW, "GNOME_APP_CONFIGURABLE_ITEM_CLOSE_WINDOW", "close-window" },
+  { GNOME_APP_CONFIGURABLE_ITEM_NEW_GAME, "GNOME_APP_CONFIGURABLE_ITEM_NEW_GAME", "new-game" },
+  { GNOME_APP_CONFIGURABLE_ITEM_PAUSE_GAME, "GNOME_APP_CONFIGURABLE_ITEM_PAUSE_GAME", "pause-game" },
+  { GNOME_APP_CONFIGURABLE_ITEM_RESTART_GAME, "GNOME_APP_CONFIGURABLE_ITEM_RESTART_GAME", "restart-game" },
+  { GNOME_APP_CONFIGURABLE_ITEM_UNDO_MOVE, "GNOME_APP_CONFIGURABLE_ITEM_UNDO_MOVE", "undo-move" },
+  { GNOME_APP_CONFIGURABLE_ITEM_REDO_MOVE, "GNOME_APP_CONFIGURABLE_ITEM_REDO_MOVE", "redo-move" },
+  { GNOME_APP_CONFIGURABLE_ITEM_HINT, "GNOME_APP_CONFIGURABLE_ITEM_HINT", "hint" },
+  { GNOME_APP_CONFIGURABLE_ITEM_SCORES, "GNOME_APP_CONFIGURABLE_ITEM_SCORES", "scores" },
+  { GNOME_APP_CONFIGURABLE_ITEM_END_GAME, "GNOME_APP_CONFIGURABLE_ITEM_END_GAME", "end-game" },
+  { 0, NULL, NULL }
+};
+static const GtkEnumValue _gnome_ui_pixmap_type_values[] = {
+  { GNOME_APP_PIXMAP_NONE, "GNOME_APP_PIXMAP_NONE", "none" },
+  { GNOME_APP_PIXMAP_STOCK, "GNOME_APP_PIXMAP_STOCK", "stock" },
+  { GNOME_APP_PIXMAP_DATA, "GNOME_APP_PIXMAP_DATA", "data" },
+  { GNOME_APP_PIXMAP_FILENAME, "GNOME_APP_PIXMAP_FILENAME", "filename" },
+  { 0, NULL, NULL }
+};
+static const GtkEnumValue _gnome_calculator_mode_values[] = {
+  { GNOME_CALCULATOR_DEG, "GNOME_CALCULATOR_DEG", "deg" },
+  { GNOME_CALCULATOR_RAD, "GNOME_CALCULATOR_RAD", "rad" },
+  { GNOME_CALCULATOR_GRAD, "GNOME_CALCULATOR_GRAD", "grad" },
+  { 0, NULL, NULL }
+};
+static const GtkEnumValue _gnome_interact_style_values[] = {
+  { GNOME_INTERACT_NONE, "GNOME_INTERACT_NONE", "none" },
+  { GNOME_INTERACT_ERRORS, "GNOME_INTERACT_ERRORS", "errors" },
+  { GNOME_INTERACT_ANY, "GNOME_INTERACT_ANY", "any" },
+  { 0, NULL, NULL }
+};
+static const GtkEnumValue _gnome_dialog_type_values[] = {
+  { GNOME_DIALOG_ERROR, "GNOME_DIALOG_ERROR", "error" },
+  { GNOME_DIALOG_NORMAL, "GNOME_DIALOG_NORMAL", "normal" },
+  { 0, NULL, NULL }
+};
+static const GtkEnumValue _gnome_save_style_values[] = {
+  { GNOME_SAVE_GLOBAL, "GNOME_SAVE_GLOBAL", "global" },
+  { GNOME_SAVE_LOCAL, "GNOME_SAVE_LOCAL", "local" },
+  { GNOME_SAVE_BOTH, "GNOME_SAVE_BOTH", "both" },
+  { 0, NULL, NULL }
+};
+static const GtkEnumValue _gnome_restart_style_values[] = {
+  { GNOME_RESTART_IF_RUNNING, "GNOME_RESTART_IF_RUNNING", "if-running" },
+  { GNOME_RESTART_ANYWAY, "GNOME_RESTART_ANYWAY", "anyway" },
+  { GNOME_RESTART_IMMEDIATELY, "GNOME_RESTART_IMMEDIATELY", "immediately" },
+  { GNOME_RESTART_NEVER, "GNOME_RESTART_NEVER", "never" },
+  { 0, NULL, NULL }
+};
+static const GtkEnumValue _gnome_client_state_values[] = {
+  { GNOME_CLIENT_IDLE, "GNOME_CLIENT_IDLE", "idle" },
+  { GNOME_CLIENT_SAVING_PHASE_1, "GNOME_CLIENT_SAVING_PHASE_1", "saving-phase-1" },
+  { GNOME_CLIENT_WAITING_FOR_PHASE_2, "GNOME_CLIENT_WAITING_FOR_PHASE_2", "waiting-for-phase-2" },
+  { GNOME_CLIENT_SAVING_PHASE_2, "GNOME_CLIENT_SAVING_PHASE_2", "saving-phase-2" },
+  { GNOME_CLIENT_FROZEN, "GNOME_CLIENT_FROZEN", "frozen" },
+  { GNOME_CLIENT_DISCONNECTED, "GNOME_CLIENT_DISCONNECTED", "disconnected" },
+  { GNOME_CLIENT_REGISTERING, "GNOME_CLIENT_REGISTERING", "registering" },
+  { 0, NULL, NULL }
+};
+static const GtkEnumValue _gnome_client_flags_values[] = {
+  { GNOME_CLIENT_IS_CONNECTED, "GNOME_CLIENT_IS_CONNECTED", "is-connected" },
+  { GNOME_CLIENT_RESTARTED, "GNOME_CLIENT_RESTARTED", "restarted" },
+  { GNOME_CLIENT_RESTORED, "GNOME_CLIENT_RESTORED", "restored" },
+  { 0, NULL, NULL }
+};
+static const GtkEnumValue _gnome_date_edit_flags_values[] = {
+  { GNOME_DATE_EDIT_SHOW_TIME, "GNOME_DATE_EDIT_SHOW_TIME", "show-time" },
+  { GNOME_DATE_EDIT_24_HR, "GNOME_DATE_EDIT_24_HR", "24-hr" },
+  { GNOME_DATE_EDIT_WEEK_STARTS_ON_MONDAY, "GNOME_DATE_EDIT_WEEK_STARTS_ON_MONDAY", "week-starts-on-monday" },
+  { 0, NULL, NULL }
+};
+static const GtkEnumValue _gnome_dock_placement_values[] = {
+  { GNOME_DOCK_TOP, "GNOME_DOCK_TOP", "top" },
+  { GNOME_DOCK_RIGHT, "GNOME_DOCK_RIGHT", "right" },
+  { GNOME_DOCK_BOTTOM, "GNOME_DOCK_BOTTOM", "bottom" },
+  { GNOME_DOCK_LEFT, "GNOME_DOCK_LEFT", "left" },
+  { GNOME_DOCK_FLOATING, "GNOME_DOCK_FLOATING", "floating" },
+  { 0, NULL, NULL }
+};
+static const GtkEnumValue _gnome_dock_item_behavior_values[] = {
+  { GNOME_DOCK_ITEM_BEH_NORMAL, "GNOME_DOCK_ITEM_BEH_NORMAL", "normal" },
+  { GNOME_DOCK_ITEM_BEH_EXCLUSIVE, "GNOME_DOCK_ITEM_BEH_EXCLUSIVE", "exclusive" },
+  { GNOME_DOCK_ITEM_BEH_NEVER_FLOATING, "GNOME_DOCK_ITEM_BEH_NEVER_FLOATING", "never-floating" },
+  { GNOME_DOCK_ITEM_BEH_NEVER_VERTICAL, "GNOME_DOCK_ITEM_BEH_NEVER_VERTICAL", "never-vertical" },
+  { GNOME_DOCK_ITEM_BEH_NEVER_HORIZONTAL, "GNOME_DOCK_ITEM_BEH_NEVER_HORIZONTAL", "never-horizontal" },
+  { GNOME_DOCK_ITEM_BEH_LOCKED, "GNOME_DOCK_ITEM_BEH_LOCKED", "locked" },
+  { 0, NULL, NULL }
+};
+static const GtkEnumValue _gnome_edge_position_values[] = {
+  { GNOME_EDGE_START, "GNOME_EDGE_START", "start" },
+  { GNOME_EDGE_FINISH, "GNOME_EDGE_FINISH", "finish" },
+  { GNOME_EDGE_OTHER, "GNOME_EDGE_OTHER", "other" },
+  { 0, NULL, NULL }
+};
+static const GtkEnumValue _gnome_font_picker_mode_values[] = {
+  { GNOME_FONT_PICKER_MODE_PIXMAP, "GNOME_FONT_PICKER_MODE_PIXMAP", "pixmap" },
+  { GNOME_FONT_PICKER_MODE_FONT_INFO, "GNOME_FONT_PICKER_MODE_FONT_INFO", "font-info" },
+  { GNOME_FONT_PICKER_MODE_USER_WIDGET, "GNOME_FONT_PICKER_MODE_USER_WIDGET", "user-widget" },
+  { GNOME_FONT_PICKER_MODE_UNKNOWN, "GNOME_FONT_PICKER_MODE_UNKNOWN", "unknown" },
+  { 0, NULL, NULL }
+};
+static const GtkEnumValue _gnome_help_view_style_values[] = {
+  { GNOME_HELP_POPUP, "GNOME_HELP_POPUP", "popup" },
+  { GNOME_HELP_EMBEDDED, "GNOME_HELP_EMBEDDED", "embedded" },
+  { GNOME_HELP_BROWSER, "GNOME_HELP_BROWSER", "browser" },
+  { 0, NULL, NULL }
+};
+static const GtkEnumValue _gnome_mdi_mode_values[] = {
+  { GNOME_MDI_NOTEBOOK, "GNOME_MDI_NOTEBOOK", "notebook" },
+  { GNOME_MDI_TOPLEVEL, "GNOME_MDI_TOPLEVEL", "toplevel" },
+  { GNOME_MDI_MODAL, "GNOME_MDI_MODAL", "modal" },
+  { GNOME_MDI_DEFAULT_MODE, "GNOME_MDI_DEFAULT_MODE", "default-mode" },
+  { 0, NULL, NULL }
+};
+static const GtkEnumValue _gnome_pixmap_draw_values[] = {
+  { GNOME_PIXMAP_SIMPLE, "GNOME_PIXMAP_SIMPLE", "simple" },
+  { GNOME_PIXMAP_COLOR, "GNOME_PIXMAP_COLOR", "color" },
+  { 0, NULL, NULL }
+};
+static const GtkEnumValue _gnome_preferences_type_values[] = {
+  { GNOME_PREFERENCES_NEVER, "GNOME_PREFERENCES_NEVER", "never" },
+  { GNOME_PREFERENCES_USER, "GNOME_PREFERENCES_USER", "user" },
+  { GNOME_PREFERENCES_ALWAYS, "GNOME_PREFERENCES_ALWAYS", "always" },
+  { 0, NULL, NULL }
+};
+static const GtkEnumValue _gnome_win_layer_values[] = {
+  { WIN_LAYER_DESKTOP, "WIN_LAYER_DESKTOP", "desktop" },
+  { WIN_LAYER_BELOW, "WIN_LAYER_BELOW", "below" },
+  { WIN_LAYER_NORMAL, "WIN_LAYER_NORMAL", "normal" },
+  { WIN_LAYER_ONTOP, "WIN_LAYER_ONTOP", "ontop" },
+  { WIN_LAYER_DOCK, "WIN_LAYER_DOCK", "dock" },
+  { WIN_LAYER_ABOVE_DOCK, "WIN_LAYER_ABOVE_DOCK", "above-dock" },
+  { 0, NULL, NULL }
+};
+static const GtkEnumValue _gnome_win_state_values[] = {
+  { WIN_STATE_STICKY, "WIN_STATE_STICKY", "sticky" },
+  { WIN_STATE_MINIMIZED, "WIN_STATE_MINIMIZED", "minimized" },
+  { WIN_STATE_MAXIMIZED_VERT, "WIN_STATE_MAXIMIZED_VERT", "maximized-vert" },
+  { WIN_STATE_MAXIMIZED_HORIZ, "WIN_STATE_MAXIMIZED_HORIZ", "maximized-horiz" },
+  { WIN_STATE_HIDDEN, "WIN_STATE_HIDDEN", "hidden" },
+  { WIN_STATE_SHADED, "WIN_STATE_SHADED", "shaded" },
+  { WIN_STATE_HID_WORKSPACE, "WIN_STATE_HID_WORKSPACE", "hid-workspace" },
+  { WIN_STATE_HID_TRANSIENT, "WIN_STATE_HID_TRANSIENT", "hid-transient" },
+  { WIN_STATE_FIXED_POSITION, "WIN_STATE_FIXED_POSITION", "fixed-position" },
+  { WIN_STATE_ARRANGE_IGNORE, "WIN_STATE_ARRANGE_IGNORE", "arrange-ignore" },
+  { 0, NULL, NULL }
+};
+static const GtkEnumValue _gnome_win_hints_values[] = {
+  { WIN_HINTS_SKIP_FOCUS, "WIN_HINTS_SKIP_FOCUS", "skip-focus" },
+  { WIN_HINTS_SKIP_WINLIST, "WIN_HINTS_SKIP_WINLIST", "skip-winlist" },
+  { WIN_HINTS_SKIP_TASKBAR, "WIN_HINTS_SKIP_TASKBAR", "skip-taskbar" },
+  { WIN_HINTS_GROUP_TRANSIENT, "WIN_HINTS_GROUP_TRANSIENT", "group-transient" },
+  { WIN_HINTS_FOCUS_ON_CLICK, "WIN_HINTS_FOCUS_ON_CLICK", "focus-on-click" },
+  { WIN_HINTS_DO_NOT_COVER, "WIN_HINTS_DO_NOT_COVER", "do-not-cover" },
+  { 0, NULL, NULL }
+};
+static const GtkEnumValue _gnome_win_app_state_values[] = {
+  { WIN_APP_STATE_NONE, "WIN_APP_STATE_NONE", "none" },
+  { WIN_APP_STATE_ACTIVE1, "WIN_APP_STATE_ACTIVE1", "active1" },
+  { WIN_APP_STATE_ACTIVE2, "WIN_APP_STATE_ACTIVE2", "active2" },
+  { WIN_APP_STATE_ERROR1, "WIN_APP_STATE_ERROR1", "error1" },
+  { WIN_APP_STATE_ERROR2, "WIN_APP_STATE_ERROR2", "error2" },
+  { WIN_APP_STATE_FATAL_ERROR1, "WIN_APP_STATE_FATAL_ERROR1", "fatal-error1" },
+  { WIN_APP_STATE_FATAL_ERROR2, "WIN_APP_STATE_FATAL_ERROR2", "fatal-error2" },
+  { WIN_APP_STATE_IDLE1, "WIN_APP_STATE_IDLE1", "idle1" },
+  { WIN_APP_STATE_IDLE2, "WIN_APP_STATE_IDLE2", "idle2" },
+  { WIN_APP_STATE_WAITING1, "WIN_APP_STATE_WAITING1", "waiting1" },
+  { WIN_APP_STATE_WAITING2, "WIN_APP_STATE_WAITING2", "waiting2" },
+  { WIN_APP_STATE_WORKING1, "WIN_APP_STATE_WORKING1", "working1" },
+  { WIN_APP_STATE_WORKING2, "WIN_APP_STATE_WORKING2", "working2" },
+  { WIN_APP_STATE_NEED_USER_INPUT1, "WIN_APP_STATE_NEED_USER_INPUT1", "need-user-input1" },
+  { WIN_APP_STATE_NEED_USER_INPUT2, "WIN_APP_STATE_NEED_USER_INPUT2", "need-user-input2" },
+  { WIN_APP_STATE_STRUGGLING1, "WIN_APP_STATE_STRUGGLING1", "struggling1" },
+  { WIN_APP_STATE_STRUGGLING2, "WIN_APP_STATE_STRUGGLING2", "struggling2" },
+  { WIN_APP_STATE_DISK_TRAFFIC1, "WIN_APP_STATE_DISK_TRAFFIC1", "disk-traffic1" },
+  { WIN_APP_STATE_DISK_TRAFFIC2, "WIN_APP_STATE_DISK_TRAFFIC2", "disk-traffic2" },
+  { WIN_APP_STATE_NETWORK_TRAFFIC1, "WIN_APP_STATE_NETWORK_TRAFFIC1", "network-traffic1" },
+  { WIN_APP_STATE_NETWORK_TRAFFIC2, "WIN_APP_STATE_NETWORK_TRAFFIC2", "network-traffic2" },
+  { WIN_APP_STATE_OVERLOADED1, "WIN_APP_STATE_OVERLOADED1", "overloaded1" },
+  { WIN_APP_STATE_OVERLOADED2, "WIN_APP_STATE_OVERLOADED2", "overloaded2" },
+  { WIN_APP_STATE_PERCENT000_1, "WIN_APP_STATE_PERCENT000_1", "percent000-1" },
+  { WIN_APP_STATE_PERCENT000_2, "WIN_APP_STATE_PERCENT000_2", "percent000-2" },
+  { WIN_APP_STATE_PERCENT010_1, "WIN_APP_STATE_PERCENT010_1", "percent010-1" },
+  { WIN_APP_STATE_PERCENT010_2, "WIN_APP_STATE_PERCENT010_2", "percent010-2" },
+  { WIN_APP_STATE_PERCENT020_1, "WIN_APP_STATE_PERCENT020_1", "percent020-1" },
+  { WIN_APP_STATE_PERCENT020_2, "WIN_APP_STATE_PERCENT020_2", "percent020-2" },
+  { WIN_APP_STATE_PERCENT030_1, "WIN_APP_STATE_PERCENT030_1", "percent030-1" },
+  { WIN_APP_STATE_PERCENT030_2, "WIN_APP_STATE_PERCENT030_2", "percent030-2" },
+  { WIN_APP_STATE_PERCENT040_1, "WIN_APP_STATE_PERCENT040_1", "percent040-1" },
+  { WIN_APP_STATE_PERCENT040_2, "WIN_APP_STATE_PERCENT040_2", "percent040-2" },
+  { WIN_APP_STATE_PERCENT050_1, "WIN_APP_STATE_PERCENT050_1", "percent050-1" },
+  { WIN_APP_STATE_PERCENT050_2, "WIN_APP_STATE_PERCENT050_2", "percent050-2" },
+  { WIN_APP_STATE_PERCENT060_1, "WIN_APP_STATE_PERCENT060_1", "percent060-1" },
+  { WIN_APP_STATE_PERCENT060_2, "WIN_APP_STATE_PERCENT060_2", "percent060-2" },
+  { WIN_APP_STATE_PERCENT070_1, "WIN_APP_STATE_PERCENT070_1", "percent070-1" },
+  { WIN_APP_STATE_PERCENT070_2, "WIN_APP_STATE_PERCENT070_2", "percent070-2" },
+  { WIN_APP_STATE_PERCENT080_1, "WIN_APP_STATE_PERCENT080_1", "percent080-1" },
+  { WIN_APP_STATE_PERCENT080_2, "WIN_APP_STATE_PERCENT080_2", "percent080-2" },
+  { WIN_APP_STATE_PERCENT090_1, "WIN_APP_STATE_PERCENT090_1", "percent090-1" },
+  { WIN_APP_STATE_PERCENT090_2, "WIN_APP_STATE_PERCENT090_2", "percent090-2" },
+  { WIN_APP_STATE_PERCENT100_1, "WIN_APP_STATE_PERCENT100_1", "percent100-1" },
+  { WIN_APP_STATE_PERCENT100_2, "WIN_APP_STATE_PERCENT100_2", "percent100-2" },
+  { 0, NULL, NULL }
+};
+static const GtkEnumValue _gtk_clock_type_values[] = {
+  { GTK_CLOCK_INCREASING, "GTK_CLOCK_INCREASING", "increasing" },
+  { GTK_CLOCK_DECREASING, "GTK_CLOCK_DECREASING", "decreasing" },
+  { GTK_CLOCK_REALTIME, "GTK_CLOCK_REALTIME", "realtime" },
+  { 0, NULL, NULL }
+};
diff --git a/libgnomeui/gnometypebuiltins_ids.c b/libgnomeui/gnometypebuiltins_ids.c
new file mode 100644
index 0000000..c6ba5ca
--- /dev/null
+++ b/libgnomeui/gnometypebuiltins_ids.c
@@ -0,0 +1,54 @@
+/* type entries, generated by maketypes.awk */
+
+  { "GnomeUIInfoType", &GTK_TYPE_GNOME_UI_INFO_TYPE,
+    GTK_TYPE_ENUM, _gnome_ui_info_type_values },
+  { "GnomeUIInfoConfigurableTypes", &GTK_TYPE_GNOME_UI_INFO_CONFIGURABLE_TYPES,
+    GTK_TYPE_ENUM, _gnome_ui_info_configurable_types_values },
+  { "GnomeUIPixmapType", &GTK_TYPE_GNOME_UI_PIXMAP_TYPE,
+    GTK_TYPE_ENUM, _gnome_ui_pixmap_type_values },
+  { "GnomeCalculatorMode", &GTK_TYPE_GNOME_CALCULATOR_MODE,
+    GTK_TYPE_ENUM, _gnome_calculator_mode_values },
+  { "GnomeInteractStyle", &GTK_TYPE_GNOME_INTERACT_STYLE,
+    GTK_TYPE_ENUM, _gnome_interact_style_values },
+  { "GnomeDialogType", &GTK_TYPE_GNOME_DIALOG_TYPE,
+    GTK_TYPE_ENUM, _gnome_dialog_type_values },
+  { "GnomeSaveStyle", &GTK_TYPE_GNOME_SAVE_STYLE,
+    GTK_TYPE_ENUM, _gnome_save_style_values },
+  { "GnomeRestartStyle", &GTK_TYPE_GNOME_RESTART_STYLE,
+    GTK_TYPE_ENUM, _gnome_restart_style_values },
+  { "GnomeClientState", &GTK_TYPE_GNOME_CLIENT_STATE,
+    GTK_TYPE_ENUM, _gnome_client_state_values },
+  { "GnomeClientFlags", &GTK_TYPE_GNOME_CLIENT_FLAGS,
+    GTK_TYPE_FLAGS, _gnome_client_flags_values },
+  { "GnomeDateEditFlags", &GTK_TYPE_GNOME_DATE_EDIT_FLAGS,
+    GTK_TYPE_FLAGS, _gnome_date_edit_flags_values },
+  { "GnomeDockPlacement", &GTK_TYPE_GNOME_DOCK_PLACEMENT,
+    GTK_TYPE_ENUM, _gnome_dock_placement_values },
+  { "GnomeDockItemBehavior", &GTK_TYPE_GNOME_DOCK_ITEM_BEHAVIOR,
+    GTK_TYPE_FLAGS, _gnome_dock_item_behavior_values },
+  { "GnomeEdgePosition", &GTK_TYPE_GNOME_EDGE_POSITION,
+    GTK_TYPE_ENUM, _gnome_edge_position_values },
+  { "GnomeFontPickerMode", &GTK_TYPE_GNOME_FONT_PICKER_MODE,
+    GTK_TYPE_ENUM, _gnome_font_picker_mode_values },
+  { "GnomeHelpViewStyle", &GTK_TYPE_GNOME_HELP_VIEW_STYLE,
+    GTK_TYPE_ENUM, _gnome_help_view_style_values },
+  { "GnomeMDIMode", &GTK_TYPE_GNOME_MDI_MODE,
+    GTK_TYPE_ENUM, _gnome_mdi_mode_values },
+  { "GnomePixmapDraw", &GTK_TYPE_GNOME_PIXMAP_DRAW,
+    GTK_TYPE_ENUM, _gnome_pixmap_draw_values },
+  { "GnomePreferencesType", &GTK_TYPE_GNOME_PREFERENCES_TYPE,
+    GTK_TYPE_ENUM, _gnome_preferences_type_values },
+  { "GnomeWinLayer", &GTK_TYPE_GNOME_WIN_LAYER,
+    GTK_TYPE_ENUM, _gnome_win_layer_values },
+  { "GnomeWinState", &GTK_TYPE_GNOME_WIN_STATE,
+    GTK_TYPE_FLAGS, _gnome_win_state_values },
+  { "GnomeWinHints", &GTK_TYPE_GNOME_WIN_HINTS,
+    GTK_TYPE_FLAGS, _gnome_win_hints_values },
+  { "GnomeWinAppState", &GTK_TYPE_GNOME_WIN_APP_STATE,
+    GTK_TYPE_ENUM, _gnome_win_app_state_values },
+  { "GtkClockType", &GTK_TYPE_CLOCK_TYPE,
+    GTK_TYPE_ENUM, _gtk_clock_type_values },
+  { "GdkImlibImage", &GTK_TYPE_GDK_IMLIB_IMAGE,
+    GTK_TYPE_BOXED, NULL },
+  { "GnomeCanvasPoints", &GTK_TYPE_GNOME_CANVAS_POINTS,
+    GTK_TYPE_BOXED, NULL },
diff --git a/libgnomeui/gnometypebuiltins_vars.c b/libgnomeui/gnometypebuiltins_vars.c
new file mode 100644
index 0000000..3f59c71
--- /dev/null
+++ b/libgnomeui/gnometypebuiltins_vars.c
@@ -0,0 +1,28 @@
+/* type variables, generated by maketypes.awk */
+
+GtkType GTK_TYPE_GNOME_UI_INFO_TYPE = 0;
+GtkType GTK_TYPE_GNOME_UI_INFO_CONFIGURABLE_TYPES = 0;
+GtkType GTK_TYPE_GNOME_UI_PIXMAP_TYPE = 0;
+GtkType GTK_TYPE_GNOME_CALCULATOR_MODE = 0;
+GtkType GTK_TYPE_GNOME_INTERACT_STYLE = 0;
+GtkType GTK_TYPE_GNOME_DIALOG_TYPE = 0;
+GtkType GTK_TYPE_GNOME_SAVE_STYLE = 0;
+GtkType GTK_TYPE_GNOME_RESTART_STYLE = 0;
+GtkType GTK_TYPE_GNOME_CLIENT_STATE = 0;
+GtkType GTK_TYPE_GNOME_CLIENT_FLAGS = 0;
+GtkType GTK_TYPE_GNOME_DATE_EDIT_FLAGS = 0;
+GtkType GTK_TYPE_GNOME_DOCK_PLACEMENT = 0;
+GtkType GTK_TYPE_GNOME_DOCK_ITEM_BEHAVIOR = 0;
+GtkType GTK_TYPE_GNOME_EDGE_POSITION = 0;
+GtkType GTK_TYPE_GNOME_FONT_PICKER_MODE = 0;
+GtkType GTK_TYPE_GNOME_HELP_VIEW_STYLE = 0;
+GtkType GTK_TYPE_GNOME_MDI_MODE = 0;
+GtkType GTK_TYPE_GNOME_PIXMAP_DRAW = 0;
+GtkType GTK_TYPE_GNOME_PREFERENCES_TYPE = 0;
+GtkType GTK_TYPE_GNOME_WIN_LAYER = 0;
+GtkType GTK_TYPE_GNOME_WIN_STATE = 0;
+GtkType GTK_TYPE_GNOME_WIN_HINTS = 0;
+GtkType GTK_TYPE_GNOME_WIN_APP_STATE = 0;
+GtkType GTK_TYPE_CLOCK_TYPE = 0;
+GtkType GTK_TYPE_GDK_IMLIB_IMAGE = 0;
+GtkType GTK_TYPE_GNOME_CANVAS_POINTS = 0;
diff --git a/libgnomeui/gnometypes.c b/libgnomeui/gnometypes.c
new file mode 100644
index 0000000..5e06820
--- /dev/null
+++ b/libgnomeui/gnometypes.c
@@ -0,0 +1,47 @@
+#include <config.h>
+#include <gtk/gtktypeutils.h>
+#include <libgnomeui.h>
+
+#include "gnometypebuiltins_vars.c"
+#include "gnometypebuiltins_evals.c"
+void gnome_type_init(void);
+
+void
+gnome_type_init(void) {
+  static gboolean initialized = FALSE;
+
+  if (!initialized) {
+    int i;
+
+    static struct {
+      gchar           *type_name;
+      GtkType         *type_id;
+      GtkType          parent;
+      gconstpointer    pointer1;
+      gconstpointer    pointer2;
+      gconstpointer    pointer3;
+      gboolean         boolean1;
+    } builtin_info[GNOME_TYPE_NUM_BUILTINS + 1] = {
+#include "gnometypebuiltins_ids.c"
+      { NULL }
+    };
+
+    initialized = TRUE;
+
+    for (i = 0; i < GNOME_TYPE_NUM_BUILTINS; i++)
+      {
+	GtkType type_id = GTK_TYPE_INVALID;
+	g_assert (builtin_info[i].type_name != NULL);
+	if ( builtin_info[i].parent == GTK_TYPE_ENUM )
+	  type_id = g_enum_register_static (builtin_info[i].type_name, (GtkEnumValue *)builtin_info[i].pointer1);
+	else if ( builtin_info[i].parent == GTK_TYPE_FLAGS )
+	  type_id = g_flags_register_static (builtin_info[i].type_name, (GtkFlagValue *)builtin_info[i].pointer1);
+	else if ( builtin_info[i].parent == GTK_TYPE_BOXED )
+	  type_id = g_boxed_type_register_static (builtin_info[i].type_name, (GBoxedInitFunc)builtin_info[i].pointer1, (GBoxedCopyFunc)builtin_info[i].pointer2, (GBoxedFreeFunc)builtin_info[i].pointer3, builtin_info[1].boolean1);
+
+	g_assert (type_id != GTK_TYPE_INVALID);
+	(*builtin_info[i].type_id) = type_id;
+      }
+  }
+}
+
diff --git a/libgnomeui/gtk-clock.c b/libgnomeui/gtk-clock.c
new file mode 100644
index 0000000..88529ed
--- /dev/null
+++ b/libgnomeui/gtk-clock.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+
+/*
+ * gtk-clock: The GTK clock widget
+ *
+ * Author: Szekeres István (szekeres cyberspace mht bme hu)
+ */
+
+#include <time.h>
+#include <gtk/gtk.h>
+#include <string.h>
+#include "gtk-clock.h"
+
+static void gtk_clock_class_init(GtkClockClass *klass);
+static void gtk_clock_init(GtkClock *clock);
+
+static GtkLabelClass *parent_class = NULL;
+
+guint gtk_clock_get_type(void)
+{
+	static guint gtkclock_type = 0;
+	if (!gtkclock_type) {
+		GtkTypeInfo gtkclock_info = {
+			"GtkClock",
+			sizeof(GtkClock),
+			sizeof(GtkClockClass),
+			(GtkClassInitFunc) gtk_clock_class_init,
+			(GtkObjectInitFunc) gtk_clock_init,
+			NULL,
+			NULL,
+			NULL
+		};
+		gtkclock_type = gtk_type_unique(gtk_label_get_type(), &gtkclock_info);
+	}
+
+	return gtkclock_type;
+}
+
+static void gtk_clock_destroy(GtkObject *object)
+{
+	g_return_if_fail(object != NULL);
+
+	/* remember, destroy can be run multiple times! */
+
+	gtk_clock_stop(GTK_CLOCK(object));
+	GTK_OBJECT_CLASS(parent_class)->destroy(object);
+}
+
+static void gtk_clock_class_init(GtkClockClass *klass)
+{
+	GtkObjectClass *object_class = (GtkObjectClass *)klass;
+	
+	object_class->destroy = gtk_clock_destroy;
+	parent_class = gtk_type_class(gtk_label_get_type());
+}
+
+static void gtk_clock_init(GtkClock *clock)
+{
+	clock->timer_id  = -1;
+	clock->update_interval = 1;
+	clock->seconds = time(NULL);
+        clock->stopped = 0;
+}
+
+static void gtk_clock_gen_str(GtkClock *clock)
+{
+	gchar timestr[64];
+	time_t secs;
+
+	switch (clock->type) {
+	case GTK_CLOCK_DECREASING:
+                secs = clock->seconds-time(NULL);
+		break;
+	case GTK_CLOCK_INCREASING:
+                secs = time(NULL)-clock->seconds;
+		break;
+	case GTK_CLOCK_REALTIME:
+		secs = time(NULL);
+		break;
+	}
+
+
+	if (clock->type == GTK_CLOCK_REALTIME) {
+		clock->tm = localtime(&secs);
+	} else {
+		clock->tm->tm_hour = secs/3600;
+		secs -= clock->tm->tm_hour*3600;
+		clock->tm->tm_min = secs/60;
+		clock->tm->tm_sec = secs - clock->tm->tm_min*60;
+	}
+	
+	strftime(timestr, 64, clock->fmt, clock->tm);
+	gtk_label_set_text(GTK_LABEL(clock), timestr);
+}
+
+static gint gtk_clock_timer_callback(gpointer data)
+{
+	GtkClock *clock = (GtkClock *)data;
+
+	GDK_THREADS_ENTER ();
+	gtk_clock_gen_str(clock);
+	GDK_THREADS_LEAVE ();
+
+	return TRUE;
+}
+
+static gint gtk_clock_timer_first_callback(gpointer data)
+{
+	GtkClock *clock = (GtkClock *)data;
+        gint tmpid;
+
+	GDK_THREADS_ENTER();
+	
+	gtk_clock_gen_str(clock);
+
+	tmpid =  gtk_timeout_add(1000*clock->update_interval,
+				 gtk_clock_timer_callback, clock);
+
+	gtk_clock_stop(clock);
+
+	clock->timer_id = tmpid;
+
+	GDK_THREADS_LEAVE();
+
+	return FALSE;
+}
+
+void gtk_clock_construct(GtkClock *gclock, GtkClockType type)
+{
+	g_return_if_fail(gclock != NULL);
+	g_return_if_fail(GTK_IS_CLOCK(gclock));
+
+	gclock->type = type;
+	
+	if (type == GTK_CLOCK_REALTIME) {
+		gclock->fmt = g_strdup("%H:%M");
+		gclock->update_interval = 60;
+		gclock->tm = localtime(&gclock->seconds);
+		gclock->timer_id = gtk_timeout_add(1000*(60-gclock->tm->tm_sec),
+						   gtk_clock_timer_first_callback, gclock);
+	} else {
+		gclock->fmt = g_strdup("%H:%M:%S");
+		gclock->tm = g_new(struct tm, 1);
+  		memset(gclock->tm, 0, sizeof(struct tm));
+		gclock->update_interval = 1;
+	}
+
+	gtk_clock_gen_str(gclock);
+}
+
+GtkWidget *gtk_clock_new(GtkClockType type)
+{
+	GtkClock *clock = gtk_type_new(gtk_clock_get_type());
+
+	gtk_clock_construct (clock, type);
+	return GTK_WIDGET(clock);
+}
+
+void gtk_clock_set_format(GtkClock *clock, const gchar *fmt)
+{
+	g_return_if_fail(clock != NULL);
+	g_return_if_fail(fmt != NULL);
+	
+	g_free(clock->fmt);
+	clock->fmt = g_strdup(fmt);
+}
+
+void gtk_clock_set_seconds(GtkClock *clock, time_t seconds)
+{
+	g_return_if_fail(clock != NULL);
+
+	if (clock->type == GTK_CLOCK_INCREASING) {
+		clock->seconds = time(NULL)-seconds;
+	} else if (clock->type == GTK_CLOCK_DECREASING) {
+		clock->seconds = time(NULL)+seconds;
+	}
+	if (clock->timer_id == -1) clock->stopped = seconds;
+	gtk_clock_gen_str(clock);
+}
+
+void gtk_clock_set_update_interval(GtkClock *clock, gint seconds)
+{
+	guint tmp;
+
+	g_return_if_fail(clock != NULL);
+
+	tmp = clock->update_interval;
+
+	clock->update_interval = seconds;
+
+	if (tmp > seconds && clock->timer_id != -1) {
+		gtk_clock_stop(clock);
+		gtk_clock_start(clock);
+	}
+}
+
+void gtk_clock_start(GtkClock *clock)
+{
+	g_return_if_fail(clock != NULL);
+
+        if (clock->timer_id != -1) return;
+
+        gtk_clock_set_seconds(clock, clock->stopped);
+	clock->timer_id = gtk_timeout_add(1000*clock->update_interval, gtk_clock_timer_callback, clock);
+}
+
+void gtk_clock_stop(GtkClock *clock)
+{
+	g_return_if_fail(clock != NULL);
+
+	if (clock->timer_id == -1)
+		return;
+
+	if (clock->type == GTK_CLOCK_INCREASING) {
+		clock->stopped = time(NULL)-clock->seconds;
+	} else if (clock->type == GTK_CLOCK_DECREASING) {
+		clock->stopped = clock->seconds-time(NULL);
+	}
+
+	gtk_timeout_remove(clock->timer_id);
+        clock->timer_id = -1;
+}
diff --git a/libgnomeui/gtk-clock.h b/libgnomeui/gtk-clock.h
new file mode 100644
index 0000000..2a6348f
--- /dev/null
+++ b/libgnomeui/gtk-clock.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+
+/*
+ * gtk-clock: The GTK clock widget
+ *
+ * Author: Szekeres István (szekeres cyberspace mht bme hu)
+ */
+
+#ifndef __GTK_CLOCK_H__
+#define __GTK_CLOCK_H__
+
+#include <time.h>
+#include <gtk/gtk.h>
+
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_CLOCK            (gtk_clock_get_type ())
+#define GTK_CLOCK(obj)            (GTK_CHECK_CAST((obj), GTK_TYPE_CLOCK, GtkClock))
+#define GTK_CLOCK_CLASS(klass)    (GTK_CHECK_CAST_CLASS((klass), GTK_TYPE_CLOCK, GtkClockClass))
+#define GTK_IS_CLOCK(obj)         (GTK_CHECK_TYPE((obj), GTK_TYPE_CLOCK))
+#define GTK_IS_CLOCK_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_CLOCK))
+#define GTK_CLOCK_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_CLOCK, GtkClockClass))
+	
+typedef struct _GtkClock GtkClock;
+typedef struct _GtkClockClass GtkClockClass;
+
+typedef enum {
+  /* update struct when adding values to enum */
+	GTK_CLOCK_INCREASING,
+	GTK_CLOCK_DECREASING,
+	GTK_CLOCK_REALTIME
+} GtkClockType;
+
+struct _GtkClock {
+	GtkLabel widget;
+	gchar *fmt;
+	struct tm *tm;
+
+	time_t seconds;
+	time_t stopped;
+	GtkClockType type : 3;
+	gint timer_id;
+	gint update_interval;
+};
+
+struct _GtkClockClass {
+	GtkLabelClass parent_class;
+};
+
+guint gtk_clock_get_type(void) G_GNUC_CONST;
+GtkWidget *gtk_clock_new(GtkClockType type);
+void gtk_clock_construct(GtkClock *gclock, GtkClockType type);
+void gtk_clock_set_format(GtkClock *gclock, const gchar *fmt);
+void gtk_clock_set_seconds(GtkClock *gclock, time_t seconds);
+void gtk_clock_set_update_interval(GtkClock *gclock, gint seconds);
+void gtk_clock_start(GtkClock *gclock);
+void gtk_clock_stop(GtkClock *gclock);
+
+G_END_DECLS
+
+#endif /* __GTK_CLOCK_H__ */
diff --git a/libgnomeui/gtkdial.c b/libgnomeui/gtkdial.c
new file mode 100644
index 0000000..655398c
--- /dev/null
+++ b/libgnomeui/gtkdial.c
@@ -0,0 +1,904 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1999 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+
+/* gtkdial.c: Written by Owen Taylor <otaylor redhat com> */
+
+/* needed for M_* under 'gcc -ansi -pedantic' on GNU/Linux */
+#ifndef _BSD_SOURCE
+#  define _BSD_SOURCE 1
+#endif
+#include <sys/types.h>
+
+#include <math.h>
+#include <stdio.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtksignal.h>
+
+#include "gtkdial.h"
+
+#define SCROLL_DELAY_LENGTH  300
+#define DIAL_MIN_SIZE        75   /* the absoulte smallest the dial can be. */
+#define DIAL_MAX_SIZE        200  /* How big this thing should get. */
+#define DIAL_DEFAULT_SIZE    75   /* The default size */
+#define DIAL_NUM_TICKS       25   /* How many ticks to draw */
+/* Forward declararations */
+
+static void gtk_dial_class_init               (GtkDialClass      *klass);
+static void gtk_dial_init                     (GtkDial           *dial);
+static void gtk_dial_destroy                  (GtkObject         *object);
+static void gtk_dial_realize                  (GtkWidget         *widget);
+static void gtk_dial_size_request             (GtkWidget         *widget,
+					       GtkRequisition    *requisition);
+static void gtk_dial_size_allocate            (GtkWidget         *widget,
+					       GtkAllocation     *allocation);
+static gint gtk_dial_expose                   (GtkWidget         *widget,
+					       GdkEventExpose    *event);
+static void gtk_dial_make_pixmap              (GtkDial           *dial);
+static void gtk_dial_paint                    (GtkDial           *dial);
+static gint gtk_dial_button_press             (GtkWidget         *widget,
+					       GdkEventButton    *event);
+static gint gtk_dial_button_release           (GtkWidget         *widget,
+					       GdkEventButton    *event);
+static gint gtk_dial_motion_notify            (GtkWidget         *widget,
+					       GdkEventMotion    *event);
+static gint gtk_dial_timer                    (GtkDial           *dial);
+
+static void gtk_dial_update_mouse             (GtkDial *dial, gint x, gint y);
+static void gtk_dial_update                   (GtkDial *dial);
+static void gtk_dial_adjustment_changed       (GtkAdjustment    *adjustment,
+						gpointer          data);
+static void gtk_dial_adjustment_value_changed (GtkAdjustment    *adjustment,
+						gpointer          data);
+
+/* Local data */
+
+static GtkWidgetClass *parent_class = NULL;
+
+guint
+gtk_dial_get_type ()
+{
+  static guint dial_type = 0;
+
+  if (!dial_type)
+    {
+      GtkTypeInfo dial_info =
+      {
+	"GtkDial",
+	sizeof (GtkDial),
+	sizeof (GtkDialClass),
+	(GtkClassInitFunc) gtk_dial_class_init,
+	(GtkObjectInitFunc) gtk_dial_init,
+	NULL,
+	NULL,
+	NULL
+      };
+
+      dial_type = gtk_type_unique (gtk_widget_get_type (), &dial_info);
+    }
+
+  return dial_type;
+}
+
+static void
+gtk_dial_class_init (GtkDialClass *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_dial_destroy;
+
+  /* Widget basics */
+  widget_class->realize = gtk_dial_realize;
+  widget_class->expose_event = gtk_dial_expose;
+  widget_class->size_request = gtk_dial_size_request;
+  widget_class->size_allocate = gtk_dial_size_allocate;
+  /* Widget events */
+  widget_class->button_press_event = gtk_dial_button_press;
+  widget_class->button_release_event = gtk_dial_button_release;
+  widget_class->motion_notify_event = gtk_dial_motion_notify;
+}
+
+static void
+gtk_dial_init (GtkDial *dial)
+{
+  dial->button           = 0;
+  dial->policy           = GTK_UPDATE_CONTINUOUS;
+  dial->view_only        = FALSE;
+  dial->timer            = 0;
+  dial->radius           = 0;
+  dial->pointer_width    = 0;
+  dial->angle            = 0.0;
+  dial->percentage       = 0.0;
+  dial->old_value        = 0.0;
+  dial->old_lower        = 0.0;
+  dial->old_upper        = 0.0;
+  dial->adjustment       = NULL;
+  dial->offscreen_pixmap = NULL;
+}
+
+/**
+ * gtk_dial_new
+ * @adjustment: Pointer to GtkAdjustment object
+ *
+ * This function creates a new GtkDial widget, and ties it to a
+ * specified GtkAdjustment. When the dial is moved, the adjustment is
+ * updated, and vice-versa.
+ *
+ * Returns: Pointer to new GtkDial widget.
+ **/
+GtkWidget*
+gtk_dial_new (GtkAdjustment *adjustment)
+{
+  GtkDial        *dial;
+
+  dial = gtk_type_new (gtk_dial_get_type ());
+
+  if (!adjustment)
+    adjustment  = (GtkAdjustment*) gtk_adjustment_new (0.0, 0.0, 0.0, 
+						      0.0, 0.0, 0.0);
+    gtk_dial_set_adjustment (dial, adjustment);
+
+  return GTK_WIDGET (dial);
+}
+
+static void
+gtk_dial_destroy (GtkObject *object)
+{
+  GtkDial *dial;
+
+  /* remember, destroy can be run multiple times! */
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_DIAL (object));
+
+  dial = GTK_DIAL (object);
+
+  if (dial->adjustment)
+    gtk_object_unref (GTK_OBJECT (dial->adjustment));
+  dial->adjustment = NULL;
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+/**
+ * gtk_dial_get_adjustment
+ * @dial: Pointer to GtkDial widget
+ *
+ * Description: Retrieves the GtkAdjustment associated with the
+ * GtkDial @dial.
+ *
+ * Returns: Pointer to GtkAdjustment object.
+ **/
+GtkAdjustment*
+gtk_dial_get_adjustment (GtkDial *dial)
+{
+  g_return_val_if_fail (dial != NULL, NULL);
+  g_return_val_if_fail (GTK_IS_DIAL (dial), NULL);
+
+  return dial->adjustment;
+}
+
+/**
+ * gtk_dial_set_view_only
+ * @dial: Pointer to GtkDial widget
+ * @view_only: TRUE to set dial to read-only, FALSE to edit.
+ *
+ * Description: Specifies whether or not the user is to be able to
+ * edit the value represented by the dial widget. If @view_only is
+ * TRUE, the dial will be set to view-only mode, and the user will not 
+ * be able to edit it. If @view_only is FALSE, the user will be able
+ * to change the value represented.
+ **/
+void gtk_dial_set_view_only (GtkDial *dial,
+			     gboolean view_only)
+{
+  g_return_if_fail(dial != NULL);
+  g_return_if_fail(GTK_IS_DIAL (dial));
+
+  dial->view_only = view_only;
+}
+/**
+ * gtk_dial_set_update_policy
+ * @dial: Pointer to GtkDial widget
+ * @policy: New policy type
+ * 
+ * Description: Sets the update policy of the GtkDial @dial to one of either
+ * %GTK_UPDATE_CONTINUOUS, %GTK_UPDATE_DISCONTINUOUS, or
+ * %GTK_UPDATE_DELAYED. Please see Gtk+ documentation for an
+ * explanation of these values.
+ **/
+void
+gtk_dial_set_update_policy (GtkDial      *dial,
+			     GtkUpdateType  policy)
+{
+  g_return_if_fail (dial != NULL);
+  g_return_if_fail (GTK_IS_DIAL (dial));
+
+  dial->policy = policy;
+}
+
+/**
+ * gtk_dial_set_adjustment
+ * @dial: Pointer to GtkDial widget
+ * @adjustment: Pointer to GtkAdjustment object
+ *
+ * Description: Associates a new GtkAdjustment with GtkDial @dial
+ * widget. The old adjustment is removed and replaced with the new.
+ **/
+void
+gtk_dial_set_adjustment (GtkDial      *dial,
+			  GtkAdjustment *adjustment)
+{
+  g_return_if_fail (dial != NULL);
+  g_return_if_fail (GTK_IS_DIAL (dial));
+
+  if (dial->adjustment)
+    {
+      gtk_signal_disconnect_by_data (GTK_OBJECT (dial->adjustment), 
+				     (gpointer) dial);
+      gtk_object_unref (GTK_OBJECT (dial->adjustment));
+    }
+
+  dial->adjustment = adjustment;
+  gtk_object_ref (GTK_OBJECT (dial->adjustment));
+
+  gtk_signal_connect (GTK_OBJECT (adjustment), "changed",
+		      (GtkSignalFunc) gtk_dial_adjustment_changed,
+		      (gpointer) dial);
+  gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
+		      (GtkSignalFunc) gtk_dial_adjustment_value_changed,
+		      (gpointer) dial);
+
+  dial->old_value = adjustment->value;
+  dial->old_lower = adjustment->lower;
+  dial->old_upper = adjustment->upper;
+
+  gtk_dial_update (dial);
+}
+/**
+ * gtk_dial_set_percentage
+ * @dial: Pointer to GtkDial widget
+ * @percent: New percentage
+ *
+ * Description: Sets the GtkDial's value to @percent of
+ * @dial->adjustment->upper. The upper value is set when the
+ * GtkAdjustment is created.
+ *
+ * Returns: New value of adjustment.
+ **/
+gfloat 
+gtk_dial_set_percentage (GtkDial *dial, gfloat percent)
+{
+ 
+  g_return_val_if_fail (dial != NULL, 0.0);
+  g_return_val_if_fail (GTK_IS_DIAL (dial), 0.0);
+
+  if (percent <= 1.0)
+    {
+      dial->percentage = percent;
+      dial->adjustment->value = percent * dial->adjustment->upper;
+      gtk_dial_update (dial);
+    }
+  
+  return dial->adjustment->value;
+}
+
+/**
+ * gtk_dial_get_percentage
+ * @dial: Pointer to GtkDial widget
+ *
+ * Description: Retrieves the current percentage held in the dial widget.
+ *
+ * Returns: Current percentage.
+ **/
+gfloat
+gtk_dial_get_percentage (GtkDial *dial)
+{
+  g_return_val_if_fail (dial != NULL, 0.0);
+  g_return_val_if_fail (GTK_IS_DIAL (dial), 0.0);
+
+  return dial->percentage;
+}
+
+/**
+ * gtk_dial_get_value
+ * @dial: Pointer to GtkDial widget
+ *
+ * Description: Retrieves the current value helt in the dial widget.
+ *
+ * Returns: Current value
+ **/
+gfloat
+gtk_dial_get_value (GtkDial *dial)
+{
+  g_return_val_if_fail (dial != NULL, 0.0);
+  g_return_val_if_fail (GTK_IS_DIAL (dial), 0.0);
+
+  return dial->adjustment->value;
+}
+
+/**
+ * gtk_dial_set_value
+ * @dial: Pointer to GtkDial widget
+ * @value: New value
+ *
+ * Description: Sets the current value held in the GtkDial's
+ * adjustment object to @value.
+ *
+ * Returns: New percentage of value to the adjustment's upper limit.
+ **/
+gfloat
+gtk_dial_set_value (GtkDial *dial, gfloat value)
+{
+  g_return_val_if_fail (dial != NULL, 0.0);
+  g_return_val_if_fail (GTK_IS_DIAL (dial), 0.0);
+
+  if (value <= dial->adjustment->upper)
+    {
+      dial->adjustment->value = value;
+      dial->percentage = value / dial->adjustment->upper;
+      gtk_dial_update (dial);
+    }
+  return dial->percentage;
+}
+static void
+gtk_dial_realize (GtkWidget *widget)
+{
+  GtkDial *dial;
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_DIAL (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+  dial = GTK_DIAL (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 | GDK_BUTTON_PRESS_MASK | 
+    GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK |
+    GDK_POINTER_MOTION_HINT_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);
+
+  widget->style = gtk_style_attach (widget->style, widget->window);
+
+  gdk_window_set_user_data (widget->window, widget);
+
+  gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE);
+  gtk_dial_make_pixmap (dial);
+}
+
+static void 
+gtk_dial_size_request (GtkWidget      *widget,
+		       GtkRequisition *requisition)
+{
+  if (requisition->width < DIAL_MIN_SIZE  ||
+      requisition->height < DIAL_MIN_SIZE)
+    {
+      requisition->width  = DIAL_MIN_SIZE;
+      requisition->height = DIAL_MIN_SIZE;
+      return;
+    }
+  if (requisition->width > DIAL_MAX_SIZE ||
+      requisition->height > DIAL_MAX_SIZE)
+    {
+      requisition->width = DIAL_MAX_SIZE;
+      requisition->height = DIAL_MAX_SIZE;
+      return;
+    }
+  
+}
+
+/*
+ * In here I would like to restrict the size of the dial to specific max
+ * size, when it gets to big it just looks silly, plus it slows down.
+ */
+static void
+gtk_dial_size_allocate (GtkWidget     *widget,
+			GtkAllocation *allocation)
+{
+  GtkDial *dial;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_DIAL (widget));
+  g_return_if_fail (allocation != NULL);
+
+  widget->allocation = *allocation;
+  dial = GTK_DIAL (widget);
+
+  if (GTK_WIDGET_REALIZED (widget))
+    {
+      gdk_window_move_resize (widget->window,
+			      allocation->x, allocation->y,
+			      allocation->width, 
+			      allocation->height);
+    }
+  dial->radius = MIN (allocation->width, allocation->height) * 0.45;
+  dial->pointer_width = dial->radius / 5;
+  gtk_dial_make_pixmap (GTK_DIAL (widget));
+
+}
+
+static gint
+gtk_dial_expose (GtkWidget      *widget,
+		 GdkEventExpose *event)
+{
+  GtkDial *dial;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (event->count > 0)
+    return FALSE;
+  
+  if (GTK_WIDGET_DRAWABLE (widget))
+   {
+     dial = GTK_DIAL (widget);
+     gdk_draw_pixmap (widget->window,
+                      widget->style->black_gc,
+                      dial->offscreen_pixmap,
+                      0, 0, 0, 0,
+                      widget->allocation.width, 
+                      widget->allocation.height);
+   }
+  return FALSE;
+}
+
+static gint
+gtk_dial_button_press (GtkWidget      *widget,
+		       GdkEventButton *event)
+{
+  GtkDial *dial;
+  gint dx, dy;
+  double s, c;
+  double d_parallel;
+  double d_perpendicular;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  dial = GTK_DIAL (widget);
+
+  /* Determine if button press was within pointer region - we 
+     do this by computing the parallel and perpendicular distance of
+     the point where the mouse was pressed from the line passing through
+     the pointer */
+  
+  dx = event->x - widget->allocation.width / 2;
+  dy = widget->allocation.height / 2 - event->y;
+  
+  s = sin(dial->angle);
+  c = cos(dial->angle);
+  
+  d_parallel = s*dy + c*dx;
+  d_perpendicular = fabs(s*dx - c*dy);
+  
+  if (!dial->button &&
+      (d_perpendicular < dial->pointer_width/2) &&
+      (d_parallel > - dial->pointer_width))
+    {
+      gtk_grab_add (widget);
+
+      dial->button = event->button;
+      gtk_dial_update_mouse (dial, event->x, event->y);
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_dial_button_release (GtkWidget      *widget,
+			  GdkEventButton *event)
+{
+  GtkDial *dial;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  dial = GTK_DIAL (widget);
+
+  if (dial->button == event->button)
+    {
+      gtk_grab_remove (widget);
+
+      dial->button = 0;
+
+      if (dial->policy == GTK_UPDATE_DELAYED)
+	gtk_timeout_remove (dial->timer);
+      
+      if ((dial->policy != GTK_UPDATE_CONTINUOUS) &&
+	  (dial->old_value != dial->adjustment->value))
+	gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_dial_motion_notify (GtkWidget      *widget,
+			 GdkEventMotion *event)
+{
+  GtkDial *dial;
+  GdkModifierType mods;
+  gint x, y, mask;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  dial = GTK_DIAL (widget);
+
+  if (dial->button != 0)
+    {
+      x = event->x;
+      y = event->y;
+
+      if (event->is_hint || (event->window != widget->window))
+	gdk_window_get_pointer (widget->window, &x, &y, &mods);
+
+      switch (dial->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)
+	gtk_dial_update_mouse (dial, x,y);
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_dial_timer (GtkDial *dial)
+{
+  GDK_THREADS_ENTER();
+  
+  g_return_val_if_fail (dial != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_DIAL (dial), FALSE);
+
+  if (dial->policy == GTK_UPDATE_DELAYED)
+    gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
+
+  GDK_THREADS_LEAVE();
+
+  return FALSE;
+}
+
+static void
+gtk_dial_update_mouse (GtkDial *dial, gint x, gint y)
+{
+  gint xc, yc;
+  gfloat old_value;
+
+  g_return_if_fail (dial != NULL);
+  g_return_if_fail (GTK_IS_DIAL (dial));
+
+  if(dial->view_only)
+    return;
+
+  xc = GTK_WIDGET(dial)->allocation.width / 2;
+  yc = GTK_WIDGET(dial)->allocation.height / 2;
+
+  old_value = dial->adjustment->value;
+  dial->angle = atan2(yc-y, x-xc);
+
+  if (dial->angle < -M_PI/2.)
+    dial->angle += 2*M_PI;
+
+  if (dial->angle < -M_PI/6)
+    dial->angle = -M_PI/6;
+
+  if (dial->angle > 7.*M_PI/6.)
+    dial->angle = 7.*M_PI/6.;
+
+  dial->adjustment->value = dial->adjustment->lower + (7.*M_PI/6 - dial->angle) *
+    (dial->adjustment->upper - dial->adjustment->lower) / (4.*M_PI/3.);
+
+  if (dial->adjustment->value != old_value)
+    {
+      if (dial->policy == GTK_UPDATE_CONTINUOUS)
+	{
+	  gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), 
+                                   "value_changed");
+	}
+      else
+	{
+          gtk_dial_paint (dial);
+
+	  if (dial->policy == GTK_UPDATE_DELAYED)
+	    {
+	      if (dial->timer)
+		gtk_timeout_remove (dial->timer);
+
+	      dial->timer = gtk_timeout_add (SCROLL_DELAY_LENGTH,
+					     (GtkFunction) gtk_dial_timer,
+					     (gpointer) dial);
+	    }
+	}
+    }
+}
+
+static void
+gtk_dial_update (GtkDial *dial)
+{
+  gfloat new_value;
+  
+  g_return_if_fail (dial != NULL);
+  g_return_if_fail (GTK_IS_DIAL (dial));
+
+  new_value = dial->adjustment->value;
+  
+  if (new_value < dial->adjustment->lower)
+    new_value = dial->adjustment->lower;
+
+  if (new_value > dial->adjustment->upper)
+    new_value = dial->adjustment->upper;
+
+  if (new_value != dial->adjustment->value)
+    {
+      dial->adjustment->value = new_value;
+      gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
+    }
+  /*
+   * save the percentage of the values..
+   * ( remember to * 100.00 to get the usual representation of %)
+   */
+  dial->percentage = dial->adjustment->value / dial->adjustment->upper;
+  dial->angle = 7.*M_PI/6. - (new_value - dial->adjustment->lower) * 
+    4.*M_PI/3. / (dial->adjustment->upper - dial->adjustment->lower);
+  gtk_dial_paint (dial);
+}
+
+static void
+gtk_dial_adjustment_changed (GtkAdjustment *adjustment,
+			      gpointer       data)
+{
+  GtkDial *dial;
+
+  g_return_if_fail (adjustment != NULL);
+  g_return_if_fail (data != NULL);
+
+  dial = GTK_DIAL (data);
+
+  if ((dial->old_value != adjustment->value) ||
+      (dial->old_lower != adjustment->lower) ||
+      (dial->old_upper != adjustment->upper))
+    {
+      gtk_dial_update (dial);
+
+      dial->old_value = adjustment->value;
+      dial->old_lower = adjustment->lower;
+      dial->old_upper = adjustment->upper;
+    }
+}
+
+static void
+gtk_dial_adjustment_value_changed (GtkAdjustment *adjustment,
+				    gpointer       data)
+{
+  GtkDial *dial;
+
+  g_return_if_fail (adjustment != NULL);
+  g_return_if_fail (data != NULL);
+
+  dial = GTK_DIAL (data);
+
+  if (dial->old_value != adjustment->value)
+    {
+      gtk_dial_update (dial);
+
+      dial->old_value = adjustment->value;
+    }
+}
+
+static void
+gtk_dial_make_pixmap (GtkDial *dial)
+{
+  GtkWidget *widget;
+
+  g_return_if_fail (dial != NULL);
+  g_return_if_fail (GTK_IS_DIAL (dial));
+
+  if (GTK_WIDGET_REALIZED (dial))
+   {
+      widget = GTK_WIDGET (dial);
+      if (dial->offscreen_pixmap)
+        gdk_pixmap_unref (dial->offscreen_pixmap);
+
+      dial->offscreen_pixmap = gdk_pixmap_new (widget->window,
+                                               widget->allocation.width,
+                                               widget->allocation.height,
+                                               -1);
+      gdk_window_set_back_pixmap (widget->window, 
+                                  dial->offscreen_pixmap, FALSE);
+      gdk_draw_rectangle (dial->offscreen_pixmap,
+                          widget->style->bg_gc[GTK_STATE_NORMAL],
+                          TRUE,
+                          0, 0,
+                          widget->allocation.width,
+                          widget->allocation.height);
+      gtk_dial_paint (dial);
+   }
+
+}
+
+static void
+gtk_dial_paint (GtkDial *dial)
+{
+  GtkWidget *widget;
+  GdkPoint  points[3];
+  GdkGC     *gc1;
+  GdkGC     *gc2;
+  gdouble   s, c, theta;
+  gint      xc, yc;
+  gint      tick_length;
+  gint      i, t_x, t_y;
+  char      buf[20];
+
+  g_return_if_fail (dial != NULL);
+  g_return_if_fail (GTK_IS_DIAL (dial));
+
+  if (dial->offscreen_pixmap)
+   {
+     widget = GTK_WIDGET (dial);
+     gdk_draw_rectangle (dial->offscreen_pixmap,
+			 widget->style->bg_gc[GTK_STATE_NORMAL],
+			 TRUE,
+			 0, 0,
+			 widget->allocation.width,
+			 widget->allocation.height);
+
+     xc = (widget->allocation.width)/2;
+     yc = (widget->allocation.height)/2;
+
+     for (i = 0; i < DIAL_NUM_TICKS; i++)
+      {
+          theta = (i * M_PI/18. - M_PI/6.);
+          s     = sin(theta);
+          c     = cos(theta);
+          tick_length = (i % 6 == 0) ? dial->pointer_width : 
+                                       dial->pointer_width/2;
+          gdk_draw_line (dial->offscreen_pixmap,
+                         widget->style->fg_gc[widget->state],
+                         xc + c * (dial->radius - tick_length),
+                         yc - s * (dial->radius - tick_length),
+                         xc + c * dial->radius,
+                         yc - s * dial->radius);
+      }
+
+     t_x = xc + c * dial->radius;
+     t_y = yc - s * dial->radius;
+     g_snprintf (buf, sizeof(buf), "%3.0f%%", 
+	         (dial->percentage * 100.0));
+
+     i = gdk_string_width (widget->style->font, buf) / 2;
+     gdk_draw_string (dial->offscreen_pixmap,
+		      widget->style->font,
+		      widget->style->black_gc,
+		      xc - i,
+		      t_y + (tick_length /2) + widget->style->font->ascent + 1,
+		      buf);
+
+     s = sin(dial->angle);
+     c = cos(dial->angle);
+     /* 
+      * Build the pointer
+      */
+     points[0].x = xc + s*dial->pointer_width/2;
+     points[0].y = yc + c*dial->pointer_width/2;
+     points[1].x = xc + c*dial->radius;
+     points[1].y = yc - s*dial->radius;
+     points[2].x = xc - s*dial->pointer_width/2;
+     points[2].y = yc - c*dial->pointer_width/2;
+     gdk_draw_polygon (dial->offscreen_pixmap,
+                       widget->style->fg_gc[widget->state],
+                       TRUE,
+                       points, 3);
+     /*
+      * Our own frame. (Can't use gtk cause this is our own pixmap)
+      */
+     gc1 = widget->style->light_gc[GTK_STATE_NORMAL];
+     gc2 = widget->style->dark_gc[GTK_STATE_NORMAL];
+     /* 
+      * Bottom and right side
+      */
+     gdk_draw_line (dial->offscreen_pixmap,
+		    gc1,
+		    0, 
+		    widget->allocation.height - 1,
+		    widget->allocation.width -1,
+		    widget->allocation.height - 1);
+     gdk_draw_line (dial->offscreen_pixmap,
+		    gc1,
+		    widget->allocation.width -1,
+		    0,
+		    widget->allocation.width -1,
+		    widget->allocation.height - 1 );
+     gdk_draw_line (dial->offscreen_pixmap,
+		    widget->style->bg_gc[GTK_STATE_NORMAL],
+		    1,
+		    widget->allocation.height - 2,
+		    widget->allocation.width - 2,
+		    widget->allocation.height - 2);
+     gdk_draw_line (dial->offscreen_pixmap,
+		    widget->style->bg_gc[GTK_STATE_NORMAL],
+		    widget->allocation.width - 2,
+		    1,
+		    widget->allocation.width - 2,
+		    widget->allocation.height - 2);
+     /*
+      * Top and left side
+      */
+     gdk_draw_line (dial->offscreen_pixmap,
+		    widget->style->black_gc,
+		    0,
+		    0,
+		    widget->allocation.width - 1, 
+		    0);
+     gdk_draw_line (dial->offscreen_pixmap,
+		    widget->style->black_gc,
+		    0,
+		    0,
+		    0,
+		    widget->allocation.height - 1);
+     gdk_draw_line (dial->offscreen_pixmap,
+		    gc2,
+		    1, 1,
+		    widget->allocation.width - 2,
+		    1);
+     gdk_draw_line (dial->offscreen_pixmap,
+		    gc2,
+		    1, 1, 1,
+		    widget->allocation.height - 2);
+     gtk_widget_draw (widget, NULL);
+     gdk_window_clear (widget->window);
+  }
+}
+
+/* EOF */
diff --git a/libgnomeui/gtkdial.h b/libgnomeui/gtkdial.h
new file mode 100644
index 0000000..31f474b
--- /dev/null
+++ b/libgnomeui/gtkdial.h
@@ -0,0 +1,93 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ * All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ */
+/*
+  @NOTATION@
+*/
+#ifndef __GTK_DIAL_H__
+#define __GTK_DIAL_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkadjustment.h>
+#include <gtk/gtkwidget.h>
+
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_DIAL            (gtk_dial_get_type ())
+#define GTK_DIAL(obj)            (GTK_CHECK_CAST ((obj), GTK_TYPE_DIAL, GtkDial))
+#define GTK_DIAL_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_DIAL, GtkDialClass))
+#define GTK_IS_DIAL(obj)         (GTK_CHECK_TYPE ((obj), GTK_TYPE_DIAL))
+#define GTK_IS_DIAL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_DIAL))
+#define GTK_DIAL_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_DIAL, GtkDialClass))
+
+
+typedef struct _GtkDial        GtkDial;
+typedef struct _GtkDialClass   GtkDialClass;
+
+struct _GtkDial
+{
+  GtkWidget     widget;
+  GdkPixmap     *offscreen_pixmap;
+  GtkAdjustment *adjustment;
+
+  gfloat angle;
+  gfloat percentage;
+  gfloat old_value;
+  gfloat old_lower;
+  gfloat old_upper;
+
+  /* Dimensions of dial components */
+  gint radius;
+  gint pointer_width;
+
+  guint32 timer;
+
+  guint8 button;
+
+  guint policy : 2;
+  guint view_only : 1;
+};
+
+struct _GtkDialClass
+{
+  GtkWidgetClass parent_class;
+};
+
+
+GtkWidget*     gtk_dial_new                    (GtkAdjustment  *adjustment);
+guint          gtk_dial_get_type               (void) G_GNUC_CONST;
+GtkAdjustment* gtk_dial_get_adjustment         (GtkDial        *dial);
+void           gtk_dial_set_update_policy      (GtkDial        *dial,
+						GtkUpdateType  policy);
+
+void           gtk_dial_set_adjustment         (GtkDial        *dial,
+						GtkAdjustment  *adjustment);
+gfloat         gtk_dial_set_percentage         (GtkDial        *dial,
+						gfloat         percent);
+gfloat         gtk_dial_get_percentage         (GtkDial        *dial);
+gfloat         gtk_dial_set_value              (GtkDial        *dial,
+						gfloat         value);
+gfloat         gtk_dial_get_value              (GtkDial        *dial);
+void           gtk_dial_set_view_only          (GtkDial        *dial,
+						gboolean       view_only);
+
+G_END_DECLS
+
+#endif /* __GTK_DIAL_H__ */
diff --git a/libgnomeui/gtkpixmapmenuitem.c b/libgnomeui/gtkpixmapmenuitem.c
new file mode 100644
index 0000000..40cd399
--- /dev/null
+++ b/libgnomeui/gtkpixmapmenuitem.c
@@ -0,0 +1,350 @@
+/*
+ * Copyright (C) 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+/* Author: Dietmar Maurer <dm vlsivie tuwien ac at> */
+
+#include "gtkpixmapmenuitem.h"
+#include <gtk/gtkaccellabel.h>
+#include <gtk/gtksignal.h>
+#include <gtk/gtkmenuitem.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkcontainer.h>
+
+static void gtk_pixmap_menu_item_class_init    (GtkPixmapMenuItemClass *klass);
+static void gtk_pixmap_menu_item_init          (GtkPixmapMenuItem      *menu_item);
+static gint gtk_pixmap_menu_item_expose        (GtkWidget              *widget,
+					        GdkEventExpose         *event);
+
+/* we must override the following functions */
+
+static void gtk_pixmap_menu_item_map           (GtkWidget        *widget);
+static void gtk_pixmap_menu_item_size_allocate (GtkWidget        *widget,
+						GtkAllocation    *allocation);
+static void gtk_pixmap_menu_item_forall        (GtkContainer    *container,
+						gboolean         include_internals,
+						GtkCallback      callback,
+						gpointer         callback_data);
+static void gtk_pixmap_menu_item_size_request  (GtkWidget        *widget,
+						GtkRequisition   *requisition);
+static void gtk_pixmap_menu_item_remove        (GtkContainer *container,
+						GtkWidget    *child);
+
+static void changed_have_pixmap_status         (GtkPixmapMenuItem *menu_item);
+
+static GtkMenuItemClass *parent_class = NULL;
+
+#define BORDER_SPACING  3
+#define PMAP_WIDTH 20
+
+GtkType
+gtk_pixmap_menu_item_get_type (void)
+{
+  static GtkType pixmap_menu_item_type = 0;
+
+  if (!pixmap_menu_item_type)
+    {
+      GtkTypeInfo pixmap_menu_item_info =
+      {
+        "GtkPixmapMenuItem",
+        sizeof (GtkPixmapMenuItem),
+        sizeof (GtkPixmapMenuItemClass),
+        (GtkClassInitFunc) gtk_pixmap_menu_item_class_init,
+        (GtkObjectInitFunc) gtk_pixmap_menu_item_init,
+        /* reserved_1 */ NULL,
+        /* reserved_2 */ NULL,
+        (GtkClassInitFunc) NULL,
+      };
+
+      pixmap_menu_item_type = gtk_type_unique (gtk_menu_item_get_type (), 
+					       &pixmap_menu_item_info);
+    }
+
+  return pixmap_menu_item_type;
+}
+
+/**
+ * gtk_pixmap_menu_item_new
+ *
+ * Creates a new pixmap menu item. Use gtk_pixmap_menu_item_set_pixmap() 
+ * to set the pixmap wich is displayed at the left side.
+ *
+ * Returns:
+ * &GtkWidget pointer to new menu item
+ **/
+
+GtkWidget*
+gtk_pixmap_menu_item_new (void)
+{
+  return GTK_WIDGET (gtk_type_new (gtk_pixmap_menu_item_get_type ()));
+}
+
+static void
+gtk_pixmap_menu_item_class_init (GtkPixmapMenuItemClass *klass)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+  GtkMenuItemClass *menu_item_class;
+  GtkContainerClass *container_class;
+
+  object_class = (GtkObjectClass*) klass;
+  widget_class = (GtkWidgetClass*) klass;
+  menu_item_class = (GtkMenuItemClass*) klass;
+  container_class = (GtkContainerClass*) klass;
+
+  parent_class = gtk_type_class (gtk_menu_item_get_type ());
+
+  widget_class->expose_event = gtk_pixmap_menu_item_expose;
+  widget_class->map = gtk_pixmap_menu_item_map;
+  widget_class->size_allocate = gtk_pixmap_menu_item_size_allocate;
+  widget_class->size_request = gtk_pixmap_menu_item_size_request;
+
+  container_class->forall = gtk_pixmap_menu_item_forall;
+  container_class->remove = gtk_pixmap_menu_item_remove;
+
+#if 0 /* FIXME */
+  klass->orig_toggle_size = menu_item_class->toggle_size;
+#endif
+  klass->have_pixmap_count = 0;
+}
+
+static void
+gtk_pixmap_menu_item_init (GtkPixmapMenuItem *menu_item)
+{
+  GtkMenuItem *mi;
+
+  mi = GTK_MENU_ITEM (menu_item);
+
+  menu_item->pixmap = NULL;
+}
+
+static gint
+gtk_pixmap_menu_item_expose (GtkWidget      *widget,
+			     GdkEventExpose *event)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_PIXMAP_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);
+
+  if (GTK_WIDGET_DRAWABLE (widget) && 
+      GTK_PIXMAP_MENU_ITEM(widget)->pixmap) {
+    gtk_widget_draw(GTK_WIDGET(GTK_PIXMAP_MENU_ITEM(widget)->pixmap),NULL);
+  }
+
+  return FALSE;
+}
+
+/**
+ * gtk_pixmap_menu_item_set_pixmap
+ * @menu_item: Pointer to the pixmap menu item
+ * @pixmap: Pointer to a pixmap widget
+ *
+ * Set the pixmap of the menu item.
+ *
+ **/
+
+void
+gtk_pixmap_menu_item_set_pixmap (GtkPixmapMenuItem *menu_item,
+				 GtkWidget         *pixmap)
+{
+  g_return_if_fail (menu_item != NULL);
+  g_return_if_fail (pixmap != NULL);
+  g_return_if_fail (GTK_IS_PIXMAP_MENU_ITEM (menu_item));
+  g_return_if_fail (GTK_IS_WIDGET (pixmap));
+  g_return_if_fail (menu_item->pixmap == NULL);
+
+  gtk_widget_set_parent (pixmap, GTK_WIDGET (menu_item));
+  menu_item->pixmap = pixmap;
+
+  if (GTK_WIDGET_REALIZED (pixmap->parent) &&
+      !GTK_WIDGET_REALIZED (pixmap))
+    gtk_widget_realize (pixmap);
+  
+  if (GTK_WIDGET_VISIBLE (pixmap->parent)) {      
+    if (GTK_WIDGET_MAPPED (pixmap->parent) &&
+	GTK_WIDGET_VISIBLE(pixmap) &&
+        !GTK_WIDGET_MAPPED (pixmap))
+      gtk_widget_map (pixmap);
+  }
+
+  changed_have_pixmap_status(menu_item);
+  
+  if (GTK_WIDGET_VISIBLE (pixmap) && GTK_WIDGET_VISIBLE (menu_item))
+    gtk_widget_queue_resize (pixmap);
+}
+
+static void
+gtk_pixmap_menu_item_map (GtkWidget *widget)
+{
+  GtkPixmapMenuItem *menu_item;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_PIXMAP_MENU_ITEM (widget));
+
+  menu_item = GTK_PIXMAP_MENU_ITEM(widget);
+
+  GTK_WIDGET_CLASS(parent_class)->map(widget);
+
+  if (menu_item->pixmap &&
+      GTK_WIDGET_VISIBLE (menu_item->pixmap) &&
+      !GTK_WIDGET_MAPPED (menu_item->pixmap))
+    gtk_widget_map (menu_item->pixmap);
+}
+
+static void
+gtk_pixmap_menu_item_size_allocate (GtkWidget        *widget,
+				    GtkAllocation    *allocation)
+{
+  GtkPixmapMenuItem *pmenu_item;
+
+  pmenu_item = GTK_PIXMAP_MENU_ITEM(widget);
+
+  if (pmenu_item->pixmap && GTK_WIDGET_VISIBLE(pmenu_item))
+    {
+      GtkAllocation child_allocation;
+      int border_width;
+
+      border_width = GTK_CONTAINER (widget)->border_width;
+
+      child_allocation.width = pmenu_item->pixmap->requisition.width;
+      child_allocation.height = pmenu_item->pixmap->requisition.height;
+      child_allocation.x = border_width + BORDER_SPACING;
+      child_allocation.y = (border_width + BORDER_SPACING
+			    + (((allocation->height - child_allocation.height) - child_allocation.x)
+			       / 2)); /* center pixmaps vertically */
+      gtk_widget_size_allocate (pmenu_item->pixmap, &child_allocation);
+    }
+
+  if (GTK_WIDGET_CLASS (parent_class)->size_allocate)
+    GTK_WIDGET_CLASS(parent_class)->size_allocate (widget, allocation);
+}
+
+static void
+gtk_pixmap_menu_item_forall (GtkContainer    *container,
+			     gboolean         include_internals,
+			     GtkCallback      callback,
+			     gpointer         callback_data)
+{
+  GtkPixmapMenuItem *menu_item;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_PIXMAP_MENU_ITEM (container));
+  g_return_if_fail (callback != NULL);
+
+  menu_item = GTK_PIXMAP_MENU_ITEM (container);
+
+  if (menu_item->pixmap)
+    (* callback) (menu_item->pixmap, callback_data);
+
+  GTK_CONTAINER_CLASS(parent_class)->forall(container,include_internals,
+					    callback,callback_data);
+}
+
+static void
+gtk_pixmap_menu_item_size_request (GtkWidget      *widget,
+				   GtkRequisition *requisition)
+{
+  GtkPixmapMenuItem *menu_item;
+  GtkRequisition req = {0, 0};
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MENU_ITEM (widget));
+  g_return_if_fail (requisition != NULL);
+
+  GTK_WIDGET_CLASS(parent_class)->size_request(widget,requisition);
+
+  menu_item = GTK_PIXMAP_MENU_ITEM (widget);
+  
+  if (menu_item->pixmap)
+    gtk_widget_size_request(menu_item->pixmap, &req);
+
+  requisition->height = MAX(req.height + GTK_CONTAINER(widget)->border_width + BORDER_SPACING, requisition->height);
+  requisition->width += (req.width + GTK_CONTAINER(widget)->border_width + BORDER_SPACING);
+}
+
+static void
+gtk_pixmap_menu_item_remove (GtkContainer *container,
+			     GtkWidget    *child)
+{
+  GtkBin *bin;
+  gboolean widget_was_visible;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_PIXMAP_MENU_ITEM (container));
+  g_return_if_fail (child != NULL);
+  g_return_if_fail (GTK_IS_WIDGET (child));
+
+  bin = GTK_BIN (container);
+  g_return_if_fail ((bin->child == child || 
+		     (GTK_PIXMAP_MENU_ITEM(container)->pixmap == child)));
+
+  widget_was_visible = GTK_WIDGET_VISIBLE (child);
+  
+  gtk_widget_unparent (child);
+  if (bin->child == child)
+    bin->child = NULL; 
+  else {
+    GTK_PIXMAP_MENU_ITEM(container)->pixmap = NULL;
+    changed_have_pixmap_status(GTK_PIXMAP_MENU_ITEM(container));
+  }
+    
+  if (widget_was_visible)
+    gtk_widget_queue_resize (GTK_WIDGET (container));
+}
+
+
+/* important to only call this if there was actually a _change_ in pixmap == NULL */
+static void
+changed_have_pixmap_status (GtkPixmapMenuItem *menu_item)
+{
+#if 0 /* FIXME */
+  if (menu_item->pixmap != NULL) {
+    GTK_PIXMAP_MENU_ITEM_GET_CLASS(menu_item)->have_pixmap_count += 1;
+
+    if (GTK_PIXMAP_MENU_ITEM_GET_CLASS(menu_item)->have_pixmap_count == 1) {
+      /* Install pixmap toggle size */
+      GTK_MENU_ITEM_GET_CLASS(menu_item)->toggle_size = MAX(GTK_PIXMAP_MENU_ITEM_GET_CLASS(menu_item)->orig_toggle_size, PMAP_WIDTH);
+    }
+  } else {
+    GTK_PIXMAP_MENU_ITEM_GET_CLASS(menu_item)->have_pixmap_count -= 1;
+
+    if (GTK_PIXMAP_MENU_ITEM_GET_CLASS(menu_item)->have_pixmap_count == 0) {
+      /* Install normal toggle size */
+      GTK_MENU_ITEM_GET_CLASS(menu_item)->toggle_size = GTK_PIXMAP_MENU_ITEM_GET_CLASS(menu_item)->orig_toggle_size;    
+    }
+  }
+#endif
+
+  /* Note that we actually need to do this for _all_ GtkPixmapMenuItem
+     whenever the klass->toggle_size changes; but by doing it anytime
+     this function is called, we get the same effect, just because of
+     how the preferences option to show pixmaps works. Bogus, broken.
+  */
+  if (GTK_WIDGET_VISIBLE(GTK_WIDGET(menu_item))) 
+    gtk_widget_queue_resize(GTK_WIDGET(menu_item));
+}
+
diff --git a/libgnomeui/gtkpixmapmenuitem.h b/libgnomeui/gtkpixmapmenuitem.h
new file mode 100644
index 0000000..3b0d40e
--- /dev/null
+++ b/libgnomeui/gtkpixmapmenuitem.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+/* Author: Dietmar Maurer <dm vlsivie tuwien ac at> */
+/* Description:
+   
+   This widget works like a normal menu_item, but you can insert a
+   arbitrary widget (most often a pixmap widget), which is displayed 
+   at the left side. The advantage is that indentation is handled the 
+   same way as GTK does.
+
+   (i.e if you create a menu with a gtk_check_menu_item, all normal
+   menu_items are automatically indented by GTK - so if you use a normal
+   menu_item to display pixmaps at the left side, the pixmaps will be 
+   indented, which is not what you want. This widget solves the problem)
+
+   */
+
+#ifndef __GTK_MENU_PIXMAP_ITEM_H__
+#define __GTK_MENU_PIXMAP_ITEM_H__
+
+
+#include <gtk/gtkpixmap.h>
+#include <gtk/gtkmenuitem.h>
+
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_PIXMAP_MENU_ITEM	     (gtk_pixmap_menu_item_get_type ())
+#define GTK_PIXMAP_MENU_ITEM(obj)	     (GTK_CHECK_CAST ((obj), GTK_TYPE_PIXMAP_MENU_ITEM, GtkPixmapMenuItem))
+#define GTK_PIXMAP_MENU_ITEM_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_PIXMAP_MENU_ITEM, GtkPixmapMenuItemClass))
+#define GTK_IS_PIXMAP_MENU_ITEM(obj)	     (GTK_CHECK_TYPE ((obj), GTK_TYPE_PIXMAP_MENU_ITEM))
+#define GTK_IS_PIXMAP_MENU_ITEM_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PIXMAP_MENU_ITEM))
+#define GTK_PIXMAP_MENU_ITEM_GET_CLASS(obj)  (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_PIXMAP_MENU_ITEM, GtkPixmapMenuItemClass))
+
+
+typedef struct _GtkPixmapMenuItem       GtkPixmapMenuItem;
+typedef struct _GtkPixmapMenuItemClass  GtkPixmapMenuItemClass;
+
+struct _GtkPixmapMenuItem
+{
+  GtkMenuItem menu_item;
+
+  GtkWidget *pixmap;
+};
+
+struct _GtkPixmapMenuItemClass
+{
+  GtkMenuItemClass parent_class;
+
+  guint orig_toggle_size;
+  guint have_pixmap_count;
+};
+
+
+GtkType	   gtk_pixmap_menu_item_get_type      (void) G_GNUC_CONST;
+GtkWidget* gtk_pixmap_menu_item_new	      (void);
+void       gtk_pixmap_menu_item_set_pixmap    (GtkPixmapMenuItem *menu_item,
+					       GtkWidget *pixmap);
+
+G_END_DECLS
+
+#endif /* __GTK_PIXMAP_MENU_ITEM_H__ */
diff --git a/libgnomeui/gtkrc b/libgnomeui/gtkrc
new file mode 100644
index 0000000..18155be
--- /dev/null
+++ b/libgnomeui/gtkrc
@@ -0,0 +1,66 @@
+# $(datadir)/gtkrc
+
+style "GnomeScores_CurrentPlayer_style"
+{
+  fg[NORMAL] = {1.0, 0.0, 0.0}
+}
+
+style "GnomeScores_Logo_style"
+{
+  font = "-freefont-garamond-*-*-*-*-30-170-*-*-*-*-iso8859-1"
+  fg[NORMAL] = {0.0, 0.0, 1.0}
+}
+
+style "GnomeAbout_DrawingArea_style"
+{
+  bg[NORMAL] = {1.0, 1.0, 1.0}
+}
+
+style "GnomeAbout_Title_style"
+{
+  font = "-adobe-helvetica-bold-r-normal-*-20-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Copyright_style"
+{
+  font = "-adobe-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Author_style"
+{
+  font = "-adobe-helvetica-bold-r-normal-*-12-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Names_style"
+{
+  font = "-adobe-helvetica-medium-r-normal-*-12-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Comments_style"
+{
+  font = "-adobe-helvetica-medium-r-normal-*-10-*-*-*-*-*-*-*"
+}
+
+style "GnomeHRef_Label_style"
+{
+  fg[NORMAL] = { 0.0, 0.0, 1.0 }
+  fg[PRELIGHT] = { 0.0, 0.0, 1.0 }
+  fg[INSENSITIVE] = { 0.5, 0.5, 1.0 }
+  fg[ACTIVE] = { 1.0, 0.0, 0.0 }
+}
+
+style "GnomeGuru_PageTitle_style" 
+{
+ font = "-adobe-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*"	
+}
+
+widget "*GnomeScores*.CurrentPlayer" style "GnomeScores_CurrentPlayer_style"
+widget "*GnomeScores*.Logo" style "GnomeScores_Logo_style"
+widget "*GnomeAbout*.DrawingArea" style "GnomeAbout_DrawingArea_style"
+widget "*GnomeAbout*.Author" style "GnomeAbout_Author_style"
+widget "*GnomeAbout*.Comments" style "GnomeAbout_Comments_style"
+widget "*GnomeAbout*.Copyright" style "GnomeAbout_Copyright_style"
+widget "*GnomeAbout*.Names" style "GnomeAbout_Names_style"
+widget "*GnomeAbout*.Title" style "GnomeAbout_Title_style"
+widget "*GnomeHRef.GtkLabel" style "GnomeHRef_Label_style"
+widget "*GnomeGuru*.PageTitle" style "GnomeGuru_PageTitle_style"
diff --git a/libgnomeui/gtkrc.el b/libgnomeui/gtkrc.el
new file mode 100644
index 0000000..f45b5cb
--- /dev/null
+++ b/libgnomeui/gtkrc.el
@@ -0,0 +1,72 @@
+# $(datadir)/gtkrc.el
+#
+# This file defines the fontsets for Greek language (el)
+#
+# 1999 Pablo Saratxaga <srtxg chanae alphanet ch>
+
+style "GnomeScores_CurrentPlayer_style"
+{
+  fg[NORMAL] = {1.0, 0.0, 0.0}
+}
+
+style "GnomeScores_Logo_style"
+{
+  fontset = "-freefont-garamond-*-*-*-*-30-170-*-*-*-*-iso8859-1,\
+          -*-garamond-*-r-*-*-34-*-*-*-*-*-iso8859-7,\
+	  -*-*-*-r-*-*-34-*-*-*-*-*-iso8859-7"
+  fg[NORMAL] = {0.0, 0.0, 1.0}
+}
+
+style "GnomeAbout_DrawingArea_style"
+{
+  bg[NORMAL] = {1.0, 1.0, 1.0}
+}
+
+style "GnomeAbout_Title_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-20-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Copyright_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Author_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-12-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Names_style"
+{
+  fontset = "-*-helvetica-medium-r-normal-*-12-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Comments_style"
+{
+  fontset = "-*-helvetica-medium-r-normal-*-10-*-*-*-*-*-*-*"
+}
+
+style "GnomeHRef_Label_style"
+{
+  fg[NORMAL] = { 0.0, 0.0, 1.0 }
+  fg[PRELIGHT] = { 0.0, 0.0, 1.0 }
+  fg[INSENSITIVE] = { 0.5, 0.5, 1.0 }
+  fg[ACTIVE] = { 1.0, 0.0, 0.0 }
+}
+
+style "GnomeGuru_PageTitle_style" 
+{
+ fontset = "-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*"	
+}
+
+widget "*GnomeScores*.CurrentPlayer" style "GnomeScores_CurrentPlayer_style"
+widget "*GnomeScores*.Logo" style "GnomeScores_Logo_style"
+widget "*GnomeAbout*.DrawingArea" style "GnomeAbout_DrawingArea_style"
+widget "*GnomeAbout*.Author" style "GnomeAbout_Author_style"
+widget "*GnomeAbout*.Comments" style "GnomeAbout_Comments_style"
+widget "*GnomeAbout*.Copyright" style "GnomeAbout_Copyright_style"
+widget "*GnomeAbout*.Names" style "GnomeAbout_Names_style"
+widget "*GnomeAbout*.Title" style "GnomeAbout_Title_style"
+widget "*GnomeHRef.GtkLabel" style "GnomeHRef_Label_style"
+widget "*GnomeGuru*.PageTitle" style "GnomeGuru_PageTitle_style"
diff --git a/libgnomeui/gtkrc.eo b/libgnomeui/gtkrc.eo
new file mode 100644
index 0000000..7bdee17
--- /dev/null
+++ b/libgnomeui/gtkrc.eo
@@ -0,0 +1,72 @@
+# $(datadir)/gtkrc.eo
+#
+# This file defines the fontsets for Esperanto language (eo)
+#
+# 1999 Pablo Saratxaga <srtxg chanae alphanet ch>
+
+style "GnomeScores_CurrentPlayer_style"
+{
+  fg[NORMAL] = {1.0, 0.0, 0.0}
+}
+
+style "GnomeScores_Logo_style"
+{
+  fontset = "-freefont-garamond-*-*-*-*-30-170-*-*-*-*-iso8859-1,\
+          -*-garamond-*-r-*-*-34-*-*-*-*-*-iso8859-3,\
+	  -*-*-*-r-*-*-34-*-*-*-*-*-iso8859-3"
+  fg[NORMAL] = {0.0, 0.0, 1.0}
+}
+
+style "GnomeAbout_DrawingArea_style"
+{
+  bg[NORMAL] = {1.0, 1.0, 1.0}
+}
+
+style "GnomeAbout_Title_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-20-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Copyright_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Author_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-12-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Names_style"
+{
+  fontset = "-*-helvetica-medium-r-normal-*-12-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Comments_style"
+{
+  fontset = "-*-helvetica-medium-r-normal-*-10-*-*-*-*-*-*-*"
+}
+
+style "GnomeHRef_Label_style"
+{
+  fg[NORMAL] = { 0.0, 0.0, 1.0 }
+  fg[PRELIGHT] = { 0.0, 0.0, 1.0 }
+  fg[INSENSITIVE] = { 0.5, 0.5, 1.0 }
+  fg[ACTIVE] = { 1.0, 0.0, 0.0 }
+}
+
+style "GnomeGuru_PageTitle_style" 
+{
+ fontset = "-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*"	
+}
+
+widget "*GnomeScores*.CurrentPlayer" style "GnomeScores_CurrentPlayer_style"
+widget "*GnomeScores*.Logo" style "GnomeScores_Logo_style"
+widget "*GnomeAbout*.DrawingArea" style "GnomeAbout_DrawingArea_style"
+widget "*GnomeAbout*.Author" style "GnomeAbout_Author_style"
+widget "*GnomeAbout*.Comments" style "GnomeAbout_Comments_style"
+widget "*GnomeAbout*.Copyright" style "GnomeAbout_Copyright_style"
+widget "*GnomeAbout*.Names" style "GnomeAbout_Names_style"
+widget "*GnomeAbout*.Title" style "GnomeAbout_Title_style"
+widget "*GnomeHRef.GtkLabel" style "GnomeHRef_Label_style"
+widget "*GnomeGuru*.PageTitle" style "GnomeGuru_PageTitle_style"
diff --git a/libgnomeui/gtkrc.he b/libgnomeui/gtkrc.he
new file mode 100644
index 0000000..5baf807
--- /dev/null
+++ b/libgnomeui/gtkrc.he
@@ -0,0 +1,76 @@
+# $(datadir)/gtkrc.he
+#
+# This file defines the fontsets for Hebrew language (he)
+#
+# 1999 Pablo Saratxaga <srtxg chanae alphanet ch>
+#
+# IMPORTANT NOTE: the standard Gtk+ widgets aren't bidirectional yet;
+#	I don't know if this file would need any special adaptation for
+#	bidirectional scripts; I hope it won't.
+
+style "GnomeScores_CurrentPlayer_style"
+{
+  fg[NORMAL] = {1.0, 0.0, 0.0}
+}
+
+style "GnomeScores_Logo_style"
+{
+  fontset = "-freefont-garamond-*-*-*-*-30-170-*-*-*-*-iso8859-1,\
+          -*-garamond-*-r-*-*-34-*-*-*-*-*-iso8859-8,\
+	  -*-*-*-r-*-*-34-*-*-*-*-*-iso8859-8"
+  fg[NORMAL] = {0.0, 0.0, 1.0}
+}
+
+style "GnomeAbout_DrawingArea_style"
+{
+  bg[NORMAL] = {1.0, 1.0, 1.0}
+}
+
+style "GnomeAbout_Title_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-20-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Copyright_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Author_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-12-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Names_style"
+{
+  fontset = "-*-helvetica-medium-r-normal-*-12-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Comments_style"
+{
+  fontset = "-*-helvetica-medium-r-normal-*-10-*-*-*-*-*-*-*"
+}
+
+style "GnomeHRef_Label_style"
+{
+  fg[NORMAL] = { 0.0, 0.0, 1.0 }
+  fg[PRELIGHT] = { 0.0, 0.0, 1.0 }
+  fg[INSENSITIVE] = { 0.5, 0.5, 1.0 }
+  fg[ACTIVE] = { 1.0, 0.0, 0.0 }
+}
+
+style "GnomeGuru_PageTitle_style" 
+{
+ fontset = "-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*"	
+}
+
+widget "*GnomeScores*.CurrentPlayer" style "GnomeScores_CurrentPlayer_style"
+widget "*GnomeScores*.Logo" style "GnomeScores_Logo_style"
+widget "*GnomeAbout*.DrawingArea" style "GnomeAbout_DrawingArea_style"
+widget "*GnomeAbout*.Author" style "GnomeAbout_Author_style"
+widget "*GnomeAbout*.Comments" style "GnomeAbout_Comments_style"
+widget "*GnomeAbout*.Copyright" style "GnomeAbout_Copyright_style"
+widget "*GnomeAbout*.Names" style "GnomeAbout_Names_style"
+widget "*GnomeAbout*.Title" style "GnomeAbout_Title_style"
+widget "*GnomeHRef.GtkLabel" style "GnomeHRef_Label_style"
+widget "*GnomeGuru*.PageTitle" style "GnomeGuru_PageTitle_style"
diff --git a/libgnomeui/gtkrc.hy b/libgnomeui/gtkrc.hy
new file mode 100644
index 0000000..fe17d2f
--- /dev/null
+++ b/libgnomeui/gtkrc.hy
@@ -0,0 +1,73 @@
+# $(datadir)/gtkrc.hy
+#
+# This file defines the fontsets for Armenina language (hy) encoding (armscii-8)
+# You can find links for armscii-8 True Type fonts following the links at my
+# page on armenian localisation at http://www.ping.be/linux/armenian/
+#
+# 1999, Pablo Saratxaga <srtxg chanae alphanet ch>
+#
+
+style "GnomeScores_CurrentPlayer_style"
+{
+  fg[NORMAL] = {1.0, 0.0, 0.0}
+}
+
+style "GnomeScores_Logo_style"
+{
+  fontset = "-*-armnet helvetica-medium-r-normal--30-*-*-*-*-*-armscii-8"
+  fg[NORMAL] = {0.0, 0.0, 1.0}
+}
+
+style "GnomeAbout_DrawingArea_style"
+{
+  bg[NORMAL] = {1.0, 1.0, 1.0}
+}
+
+style "GnomeAbout_Title_style"
+{
+  fontset = "-*-armnet helvetica-medium-r-normal--20-*-*-*-*-*-armscii-8"
+}
+
+style "GnomeAbout_Copyright_style"
+{
+  fontset = "-*-armnet helvetica-medium-r-normal--14-*-*-*-*-*-armscii-8"
+}
+
+style "GnomeAbout_Author_style"
+{
+  fontset = "-*-armnet helvetica-medium-r-normal--12-*-*-*-*-*-armscii-8"
+}
+
+style "GnomeAbout_Names_style"
+{
+  fontset = "-*-armnet helvetica-medium-r-normal--12-*-*-*-*-*-armscii-8"
+}
+
+style "GnomeAbout_Comments_style"
+{
+  fontset = "-*-armnet helvetica-medium-r-normal--10-*-*-*-*-*-armscii-8"
+}
+
+style "GnomeHRef_Label_style"
+{
+  fg[NORMAL] = { 0.0, 0.0, 1.0 }
+  fg[PRELIGHT] = { 0.0, 0.0, 1.0 }
+  fg[INSENSITIVE] = { 0.5, 0.5, 1.0 }
+  fg[ACTIVE] = { 1.0, 0.0, 0.0 }
+}
+
+style "GnomeGuru_PageTitle_style" 
+{
+ fontset = "-*-armnet helvetica-medium-r-normal--10-*-*-*-*-*-armscii-8"
+}
+
+widget "*GnomeScores*.CurrentPlayer" style "GnomeScores_CurrentPlayer_style"
+widget "*GnomeScores*.Logo" style "GnomeScores_Logo_style"
+widget "*GnomeAbout*.DrawingArea" style "GnomeAbout_DrawingArea_style"
+widget "*GnomeAbout*.Author" style "GnomeAbout_Author_style"
+widget "*GnomeAbout*.Comments" style "GnomeAbout_Comments_style"
+widget "*GnomeAbout*.Copyright" style "GnomeAbout_Copyright_style"
+widget "*GnomeAbout*.Names" style "GnomeAbout_Names_style"
+widget "*GnomeAbout*.Title" style "GnomeAbout_Title_style"
+widget "*GnomeHRef.GtkLabel" style "GnomeHRef_Label_style"
+widget "*GnomeGuru*.PageTitle" style "GnomeGuru_PageTitle_style"
diff --git a/libgnomeui/gtkrc.iso88592 b/libgnomeui/gtkrc.iso88592
new file mode 100644
index 0000000..e2cd989
--- /dev/null
+++ b/libgnomeui/gtkrc.iso88592
@@ -0,0 +1,75 @@
+# $(datadir)/gtkrc.iso88592
+#
+# This file defines the fontsets for iso-8859-2 encoding
+# make symliks or hardlinks to gtkrc.$LANG if your language uses iso-8859-2
+# and a gtkrc.$LANG doesn't exist yet.
+#
+# 1999, Pablo Saratxaga <srtxg chanae alphanet ch>
+#
+
+style "GnomeScores_CurrentPlayer_style"
+{
+  fg[NORMAL] = {1.0, 0.0, 0.0}
+}
+
+style "GnomeScores_Logo_style"
+{
+  fontset = "-freefont-garamond-*-*-*-*-30-170-*-*-*-*-iso8859-1,\
+          -*-garamond-*-r-*-*-34-*-*-*-*-*-iso8859-2,\
+	  -*-*-*-r-*-*-34-*-*-*-*-*-iso8859-2"
+  fg[NORMAL] = {0.0, 0.0, 1.0}
+}
+
+style "GnomeAbout_DrawingArea_style"
+{
+  bg[NORMAL] = {1.0, 1.0, 1.0}
+}
+
+style "GnomeAbout_Title_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-20-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Copyright_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Author_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-12-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Names_style"
+{
+  fontset = "-*-helvetica-medium-r-normal-*-12-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Comments_style"
+{
+  fontset = "-*-helvetica-medium-r-normal-*-10-*-*-*-*-*-*-*"
+}
+
+style "GnomeHRef_Label_style"
+{
+  fg[NORMAL] = { 0.0, 0.0, 1.0 }
+  fg[PRELIGHT] = { 0.0, 0.0, 1.0 }
+  fg[INSENSITIVE] = { 0.5, 0.5, 1.0 }
+  fg[ACTIVE] = { 1.0, 0.0, 0.0 }
+}
+
+style "GnomeGuru_PageTitle_style" 
+{
+ fontset = "-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*"	
+}
+
+widget "*GnomeScores*.CurrentPlayer" style "GnomeScores_CurrentPlayer_style"
+widget "*GnomeScores*.Logo" style "GnomeScores_Logo_style"
+widget "*GnomeAbout*.DrawingArea" style "GnomeAbout_DrawingArea_style"
+widget "*GnomeAbout*.Author" style "GnomeAbout_Author_style"
+widget "*GnomeAbout*.Comments" style "GnomeAbout_Comments_style"
+widget "*GnomeAbout*.Copyright" style "GnomeAbout_Copyright_style"
+widget "*GnomeAbout*.Names" style "GnomeAbout_Names_style"
+widget "*GnomeAbout*.Title" style "GnomeAbout_Title_style"
+widget "*GnomeHRef.GtkLabel" style "GnomeHRef_Label_style"
+widget "*GnomeGuru*.PageTitle" style "GnomeGuru_PageTitle_style"
diff --git a/libgnomeui/gtkrc.iso88595 b/libgnomeui/gtkrc.iso88595
new file mode 100644
index 0000000..510b076
--- /dev/null
+++ b/libgnomeui/gtkrc.iso88595
@@ -0,0 +1,75 @@
+# $(datadir)/gtkrc.iso88595
+#
+# This file defines the fontsets for iso-8859-5 encoding
+# make symliks or hardlinks to gtkrc.$LANG if your language uses iso-8859-5
+# and a gtkrc.$LANG doesn't exist yet.
+#
+# 1999, Pablo Saratxaga <srtxg chanae alphanet ch>
+#
+
+style "GnomeScores_CurrentPlayer_style"
+{
+  fg[NORMAL] = {1.0, 0.0, 0.0}
+}
+
+style "GnomeScores_Logo_style"
+{
+  fontset = "-freefont-garamond-*-*-*-*-30-170-*-*-*-*-iso8859-1,\
+          -*-garamond-*-r-*-*-34-*-*-*-*-*-iso8859-5,\
+	  -*-*-*-r-*-*-34-*-*-*-*-*-iso8859-5"
+  fg[NORMAL] = {0.0, 0.0, 1.0}
+}
+
+style "GnomeAbout_DrawingArea_style"
+{
+  bg[NORMAL] = {1.0, 1.0, 1.0}
+}
+
+style "GnomeAbout_Title_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-20-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Copyright_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Author_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-12-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Names_style"
+{
+  fontset = "-*-helvetica-medium-r-normal-*-12-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Comments_style"
+{
+  fontset = "-*-helvetica-medium-r-normal-*-10-*-*-*-*-*-*-*"
+}
+
+style "GnomeHRef_Label_style"
+{
+  fg[NORMAL] = { 0.0, 0.0, 1.0 }
+  fg[PRELIGHT] = { 0.0, 0.0, 1.0 }
+  fg[INSENSITIVE] = { 0.5, 0.5, 1.0 }
+  fg[ACTIVE] = { 1.0, 0.0, 0.0 }
+}
+
+style "GnomeGuru_PageTitle_style" 
+{
+ fontset = "-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*"	
+}
+
+widget "*GnomeScores*.CurrentPlayer" style "GnomeScores_CurrentPlayer_style"
+widget "*GnomeScores*.Logo" style "GnomeScores_Logo_style"
+widget "*GnomeAbout*.DrawingArea" style "GnomeAbout_DrawingArea_style"
+widget "*GnomeAbout*.Author" style "GnomeAbout_Author_style"
+widget "*GnomeAbout*.Comments" style "GnomeAbout_Comments_style"
+widget "*GnomeAbout*.Copyright" style "GnomeAbout_Copyright_style"
+widget "*GnomeAbout*.Names" style "GnomeAbout_Names_style"
+widget "*GnomeAbout*.Title" style "GnomeAbout_Title_style"
+widget "*GnomeHRef.GtkLabel" style "GnomeHRef_Label_style"
+widget "*GnomeGuru*.PageTitle" style "GnomeGuru_PageTitle_style"
diff --git a/libgnomeui/gtkrc.ja b/libgnomeui/gtkrc.ja
new file mode 100644
index 0000000..55c0e1e
--- /dev/null
+++ b/libgnomeui/gtkrc.ja
@@ -0,0 +1,74 @@
+# $(datadir)/gtkrc.ja
+#
+# This file is needed for the Japanese users.
+# The fonts are changed from the original gtkrc.
+# And fontset is specified.
+#
+# Yukihiro Nakai<Nakai abricot co jp>
+#
+
+style "GnomeScores_CurrentPlayer_style"
+{
+  fg[NORMAL] = {1.0, 0.0, 0.0}
+}
+
+style "GnomeScores_Logo_style"
+{
+  fontset = "-misc-fixed-medium-r-normal--14-*-*-*-*-*-*-*"
+  fg[NORMAL] = {0.0, 0.0, 1.0}
+}
+
+style "GnomeAbout_DrawingArea_style"
+{
+  bg[NORMAL] = {1.0, 1.0, 1.0}
+}
+
+style "GnomeAbout_Title_style"
+{
+  fontset = "-misc-fixed-medium-r-normal--14-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Copyright_style"
+{
+  fontset = "-misc-fixed-medium-r-normal--14-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Author_style"
+{
+  fontset = "-misc-fixed-medium-r-normal--14-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Names_style"
+{
+  fontset = "-misc-fixed-medium-r-normal--14-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Comments_style"
+{
+  fontset = "-misc-fixed-medium-r-normal--14-*-*-*-*-*-*-*"
+}
+
+style "GnomeHRef_Label_style"
+{
+  fg[NORMAL] = { 0.0, 0.0, 1.0 }
+  fg[PRELIGHT] = { 0.0, 0.0, 1.0 }
+  fg[INSENSITIVE] = { 0.5, 0.5, 1.0 }
+  fg[ACTIVE] = { 1.0, 0.0, 0.0 }
+}
+
+style "GnomeGuru_PageTitle_style" 
+{
+  fontset = "-misc-fixed-medium-r-normal--14-*-*-*-*-*-*-*"
+}
+
+
+widget "*GnomeScores*.CurrentPlayer" style "GnomeScores_CurrentPlayer_style"
+widget "*GnomeScores*.Logo" style "GnomeScores_Logo_style"
+widget "*GnomeAbout*.DrawingArea" style "GnomeAbout_DrawingArea_style"
+widget "*GnomeAbout*.Author" style "GnomeAbout_Author_style"
+widget "*GnomeAbout*.Comments" style "GnomeAbout_Comments_style"
+widget "*GnomeAbout*.Copyright" style "GnomeAbout_Copyright_style"
+widget "*GnomeAbout*.Names" style "GnomeAbout_Names_style"
+widget "*GnomeAbout*.Title" style "GnomeAbout_Title_style"
+widget "*GnomeHRef.GtkLabel" style "GnomeHRef_Label_style"
+widget "*GnomeGuru*.PageTitle" style "GnomeGuru_PageTitle_style"
diff --git a/libgnomeui/gtkrc.ka_GE.georgianacademy b/libgnomeui/gtkrc.ka_GE.georgianacademy
new file mode 100644
index 0000000..cd2ca34
--- /dev/null
+++ b/libgnomeui/gtkrc.ka_GE.georgianacademy
@@ -0,0 +1,78 @@
+# $(datadir)/gtkrc.ka_GE.georgianacademy
+#
+# This file defines the fontsets for Georgian language (ka) using
+# the GEORGIAN-ACADEMY charset encoding.
+#
+# You can find links for georgian-academy True Type fonts following the
+# links at my page on georgian localisation at 
+# http://www.ping.be/linux/georgian/
+#
+# 1999, Pablo Saratxaga <srtxg chanae alphanet ch>
+#
+
+style "GnomeScores_CurrentPlayer_style"
+{
+  fg[NORMAL] = {1.0, 0.0, 0.0}
+}
+
+style "GnomeScores_Logo_style"
+{
+  fontset = "-freefont-garamond-*-*-*-*-30-170-*-*-*-*-iso8859-1,\
+	  -*-*-*-*-*-*-30-**-*-*-*-georgian-academy"
+  fg[NORMAL] = {0.0, 0.0, 1.0}
+}
+
+style "GnomeAbout_DrawingArea_style"
+{
+  bg[NORMAL] = {1.0, 1.0, 1.0}
+}
+
+style "GnomeAbout_Title_style"
+{
+  fontset = "-*-*-bold-r-normal-*-20-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Copyright_style"
+{
+  fontset = "-*-*-bold-r-normal-*-16-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Author_style"
+{
+  fontset = "-*-*-bold-r-normal-*-14-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Names_style"
+{
+  fontset = "-*-*-medium-r-normal-*-14-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Comments_style"
+{
+  fontset = "-adobe-helvetica-medium-r-normal-*-10-*-*-*-*-*-*-*,\
+             -*-*-medium-r-normal-*-14-*-*-*-*-*-*-*"
+}
+
+style "GnomeHRef_Label_style"
+{
+  fg[NORMAL] = { 0.0, 0.0, 1.0 }
+  fg[PRELIGHT] = { 0.0, 0.0, 1.0 }
+  fg[INSENSITIVE] = { 0.5, 0.5, 1.0 }
+  fg[ACTIVE] = { 1.0, 0.0, 0.0 }
+}
+
+style "GnomeGuru_PageTitle_style" 
+{
+ fontset = "-*-*-bold-r-normal-*-16-*-*-*-*-*-*-*"	
+}
+
+widget "*GnomeScores*.CurrentPlayer" style "GnomeScores_CurrentPlayer_style"
+widget "*GnomeScores*.Logo" style "GnomeScores_Logo_style"
+widget "*GnomeAbout*.DrawingArea" style "GnomeAbout_DrawingArea_style"
+widget "*GnomeAbout*.Author" style "GnomeAbout_Author_style"
+widget "*GnomeAbout*.Comments" style "GnomeAbout_Comments_style"
+widget "*GnomeAbout*.Copyright" style "GnomeAbout_Copyright_style"
+widget "*GnomeAbout*.Names" style "GnomeAbout_Names_style"
+widget "*GnomeAbout*.Title" style "GnomeAbout_Title_style"
+widget "*GnomeHRef.GtkLabel" style "GnomeHRef_Label_style"
+widget "*GnomeGuru*.PageTitle" style "GnomeGuru_PageTitle_style"
diff --git a/libgnomeui/gtkrc.ka_GE.georgianps b/libgnomeui/gtkrc.ka_GE.georgianps
new file mode 100644
index 0000000..07dc914
--- /dev/null
+++ b/libgnomeui/gtkrc.ka_GE.georgianps
@@ -0,0 +1,78 @@
+# $(datadir)/gtkrc.ka_GE.georgianaps
+#
+# This file defines the fontsets for Georgian language (ka) using
+# the GEORGIAN-PS (Parliament-Soros found) charset encoding.
+#
+# You can find links for georgian-ps True Type fonts following the
+# links at my page on georgian localisation at
+# http://www.ping.be/linux/georgian/
+#
+# 1999, Pablo Saratxaga <srtxg chanae alphanet ch>
+#
+
+style "GnomeScores_CurrentPlayer_style"
+{
+  fg[NORMAL] = {1.0, 0.0, 0.0}
+}
+
+style "GnomeScores_Logo_style"
+{
+  fontset = "-freefont-garamond-*-*-*-*-30-170-*-*-*-*-iso8859-1,\
+	  -*-*-*-*-*-*-30-**-*-*-*-georgian-ps"
+  fg[NORMAL] = {0.0, 0.0, 1.0}
+}
+
+style "GnomeAbout_DrawingArea_style"
+{
+  bg[NORMAL] = {1.0, 1.0, 1.0}
+}
+
+style "GnomeAbout_Title_style"
+{
+  fontset = "-*-*-bold-r-normal-*-20-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Copyright_style"
+{
+  fontset = "-*-*-bold-r-normal-*-14-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Author_style"
+{
+  fontset = "-*-*-bold-r-normal-*-12-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Names_style"
+{
+  fontset = "-*-*-medium-r-normal-*-12-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Comments_style"
+{
+  fontset = "-adobe-helvetica-medium-r-normal-*-10-*-*-*-*-*-*-*,\
+             -*-*-medium-r-normal-*-11-*-*-*-*-*-*-*"
+}
+
+style "GnomeHRef_Label_style"
+{
+  fg[NORMAL] = { 0.0, 0.0, 1.0 }
+  fg[PRELIGHT] = { 0.0, 0.0, 1.0 }
+  fg[INSENSITIVE] = { 0.5, 0.5, 1.0 }
+  fg[ACTIVE] = { 1.0, 0.0, 0.0 }
+}
+
+style "GnomeGuru_PageTitle_style" 
+{
+ fontset = "-*-*-bold-r-normal-*-14-*-*-*-*-*-*-*"	
+}
+
+widget "*GnomeScores*.CurrentPlayer" style "GnomeScores_CurrentPlayer_style"
+widget "*GnomeScores*.Logo" style "GnomeScores_Logo_style"
+widget "*GnomeAbout*.DrawingArea" style "GnomeAbout_DrawingArea_style"
+widget "*GnomeAbout*.Author" style "GnomeAbout_Author_style"
+widget "*GnomeAbout*.Comments" style "GnomeAbout_Comments_style"
+widget "*GnomeAbout*.Copyright" style "GnomeAbout_Copyright_style"
+widget "*GnomeAbout*.Names" style "GnomeAbout_Names_style"
+widget "*GnomeAbout*.Title" style "GnomeAbout_Title_style"
+widget "*GnomeHRef.GtkLabel" style "GnomeHRef_Label_style"
+widget "*GnomeGuru*.PageTitle" style "GnomeGuru_PageTitle_style"
diff --git a/libgnomeui/gtkrc.ko b/libgnomeui/gtkrc.ko
new file mode 100644
index 0000000..f377e7d
--- /dev/null
+++ b/libgnomeui/gtkrc.ko
@@ -0,0 +1,81 @@
+# $(datadir)/gtkrc.ko
+#
+# This file is needed for the Korean users.
+# The fonts are changed from the original gtkrc.
+# And fontset is specified.
+#
+# Changwoo Ryu <cwryu adam kaist ac kr>
+#
+
+style "GnomeScores_CurrentPlayer_style"
+{
+  fg[NORMAL] = {1.0, 0.0, 0.0}
+}
+
+style "GnomeScores_Logo_style"
+{
+  fontset = "-freefont-garamond-*-*-*-*-24-170-*-*-*-*-iso8859-1,
+-*-*-*-*-*--24-*-*-*-*-*-ksc5601.1987-*"
+  fg[NORMAL] = {0.0, 0.0, 1.0}
+}
+
+style "GnomeAbout_DrawingArea_style"
+{
+  bg[NORMAL] = {1.0, 1.0, 1.0}
+}
+
+style "GnomeAbout_Title_style"
+{
+  fontset = "-adobe-helvetica-bold-r-normal-*-18-*-*-*-*-*-*-*,
+-*-*-bold-*-*--18-*-*-*-*-*-ksc5601.1987-*"
+}
+
+style "GnomeAbout_Copyright_style"
+{
+  fontset = "-adobe-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*,
+-*-*-bold-*-*--14-*-*-*-*-*-ksc5601.1987-*"
+}
+
+style "GnomeAbout_Author_style"
+{
+  fontset = "-adobe-helvetica-bold-r-normal-*-12-*-*-*-*-*-*-*,
+-*-*-bold-*-*--12-*-*-*-*-*-ksc5601.1987-*"
+}
+
+style "GnomeAbout_Names_style"
+{
+  fontset = "-adobe-helvetica-medium-r-normal-*-12-*-*-*-*-*-*-*,
+-*-*-medium-*-*--12-*-*-*-*-*-ksc5601.1987-*"
+}
+
+style "GnomeAbout_Comments_style"
+{
+  fontset = "-adobe-helvetica-medium-r-normal-*-10-*-*-*-*-*-*-*,
+-*-*-medium-*-*--10-*-*-*-*-*-ksc5601.1987-*"
+}
+
+style "GnomeHRef_Label_style"
+{
+  fg[NORMAL] = { 0.0, 0.0, 1.0 }
+  fg[PRELIGHT] = { 0.0, 0.0, 1.0 }
+  fg[INSENSITIVE] = { 0.5, 0.5, 1.0 }
+  fg[ACTIVE] = { 1.0, 0.0, 0.0 }
+}
+
+style "GnomeGuru_PageTitle_style" 
+{
+ fontset = "-adobe-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*,
+-*-*-bold-*-*--14-*-*-*-*-*-ksc5601.1987-*"
+}
+
+
+widget "*GnomeScores*.CurrentPlayer" style "GnomeScores_CurrentPlayer_style"
+widget "*GnomeScores*.Logo" style "GnomeScores_Logo_style"
+widget "*GnomeAbout*.DrawingArea" style "GnomeAbout_DrawingArea_style"
+widget "*GnomeAbout*.Author" style "GnomeAbout_Author_style"
+widget "*GnomeAbout*.Comments" style "GnomeAbout_Comments_style"
+widget "*GnomeAbout*.Copyright" style "GnomeAbout_Copyright_style"
+widget "*GnomeAbout*.Names" style "GnomeAbout_Names_style"
+widget "*GnomeAbout*.Title" style "GnomeAbout_Title_style"
+widget "*GnomeHRef.GtkLabel" style "GnomeHRef_Label_style"
+widget "*GnomeGuru*.PageTitle" style "GnomeGuru_PageTitle_style"
diff --git a/libgnomeui/gtkrc.ru b/libgnomeui/gtkrc.ru
new file mode 100644
index 0000000..bcecb6d
--- /dev/null
+++ b/libgnomeui/gtkrc.ru
@@ -0,0 +1,68 @@
+# $(datadir)/gtkrc
+
+style "GnomeScores_CurrentPlayer_style"
+{
+  fg[NORMAL] = {1.0, 0.0, 0.0}
+}
+
+style "GnomeScores_Logo_style"
+{
+  fontset = "-freefont-garamond-*-*-*-*-30-170-*-*-*-*-iso8859-1,\
+          -cronyx-times-*-r-*-*-34-*-*-*-*-*-koi8-r"
+  fg[NORMAL] = {0.0, 0.0, 1.0}
+}
+
+style "GnomeAbout_DrawingArea_style"
+{
+  bg[NORMAL] = {1.0, 1.0, 1.0}
+}
+
+style "GnomeAbout_Title_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-20-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Copyright_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Author_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-12-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Names_style"
+{
+  fontset = "-*-helvetica-medium-r-normal-*-12-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Comments_style"
+{
+  fontset = "-adobe-helvetica-medium-r-normal-*-10-*-*-*-*-*-*-*,\
+             -cronyx-helvetica-medium-r-normal-*-11-*-*-*-*-*-*-*"
+}
+
+style "GnomeHRef_Label_style"
+{
+  fg[NORMAL] = { 0.0, 0.0, 1.0 }
+  fg[PRELIGHT] = { 0.0, 0.0, 1.0 }
+  fg[INSENSITIVE] = { 0.5, 0.5, 1.0 }
+  fg[ACTIVE] = { 1.0, 0.0, 0.0 }
+}
+
+style "GnomeGuru_PageTitle_style" 
+{
+ fontset = "-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*"	
+}
+
+widget "*GnomeScores*.CurrentPlayer" style "GnomeScores_CurrentPlayer_style"
+widget "*GnomeScores*.Logo" style "GnomeScores_Logo_style"
+widget "*GnomeAbout*.DrawingArea" style "GnomeAbout_DrawingArea_style"
+widget "*GnomeAbout*.Author" style "GnomeAbout_Author_style"
+widget "*GnomeAbout*.Comments" style "GnomeAbout_Comments_style"
+widget "*GnomeAbout*.Copyright" style "GnomeAbout_Copyright_style"
+widget "*GnomeAbout*.Names" style "GnomeAbout_Names_style"
+widget "*GnomeAbout*.Title" style "GnomeAbout_Title_style"
+widget "*GnomeHRef.GtkLabel" style "GnomeHRef_Label_style"
+widget "*GnomeGuru*.PageTitle" style "GnomeGuru_PageTitle_style"
diff --git a/libgnomeui/gtkrc.th b/libgnomeui/gtkrc.th
new file mode 100644
index 0000000..540baf1
--- /dev/null
+++ b/libgnomeui/gtkrc.th
@@ -0,0 +1,79 @@
+# $(datadir)/gtkrc.th
+#
+# This file defines the fontsets for Thai language (th) using
+# the TIS-620 charset encoding.
+#
+# 1999, Pablo Saratxaga <srtxg chanae alphanet ch>
+#
+
+style "GnomeScores_CurrentPlayer_style"
+{
+  fg[NORMAL] = {1.0, 0.0, 0.0}
+}
+
+style "GnomeScores_Logo_style"
+{
+  fontset = "-freefont-garamond-*-*-*-*-30-170-*-*-*-*-iso8859-1,\
+          -*-*-*-*-*-*-30-*-*-*-*-*-tis620.*-*"
+  fg[NORMAL] = {0.0, 0.0, 1.0}
+}
+
+style "GnomeAbout_DrawingArea_style"
+{
+  bg[NORMAL] = {1.0, 1.0, 1.0}
+}
+
+style "GnomeAbout_Title_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-20-*-*-*-*-*-iso8859-1,\
+             -*-phaisarn-*-r-normal-*-20-*-*-*-*-*-tis620.*-*"
+}
+
+style "GnomeAbout_Copyright_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-iso8859-1,\
+             -*-phaisarn-*-r-normal-*-14-*-*-*-*-*-tis620.*-*"
+}
+
+style "GnomeAbout_Author_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-12-*-*-*-*-*-iso8859-1,\
+             -*-phaisarn-*-r-normal-*-12-*-*-*-*-*-tis620.*-*"
+}
+
+style "GnomeAbout_Names_style"
+{
+  fontset = "-*-helvetica-medium-r-normal-*-12-*-*-*-*-*-iso8859-1,\
+             -*-phaisarn-medium-r-normal-*-12-*-*-*-*-*-tis620.*-*"
+}
+
+style "GnomeAbout_Comments_style"
+{
+  fontset = "-adobe-helvetica-medium-r-normal-*-10-*-*-*-*-*-iso8859-1,\
+             -*-phaisarn-medium-r-normal-*-10-*-*-*-*-*-tis620.*-*"
+}
+
+style "GnomeHRef_Label_style"
+{
+  fg[NORMAL] = { 0.0, 0.0, 1.0 }
+  fg[PRELIGHT] = { 0.0, 0.0, 1.0 }
+  fg[INSENSITIVE] = { 0.5, 0.5, 1.0 }
+  fg[ACTIVE] = { 1.0, 0.0, 0.0 }
+}
+
+style "GnomeGuru_PageTitle_style" 
+{
+ fontset = "-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-iso8859-1,\
+             -*-phaisarn-*-r-normal-*-14-*-*-*-*-*-tis620.*-*"
+}
+
+widget "*GnomeScores*.CurrentPlayer" style "GnomeScores_CurrentPlayer_style"
+widget "*GnomeScores*.Logo" style "GnomeScores_Logo_style"
+widget "*GnomeAbout*.DrawingArea" style "GnomeAbout_DrawingArea_style"
+widget "*GnomeAbout*.Author" style "GnomeAbout_Author_style"
+widget "*GnomeAbout*.Comments" style "GnomeAbout_Comments_style"
+widget "*GnomeAbout*.Copyright" style "GnomeAbout_Copyright_style"
+widget "*GnomeAbout*.Names" style "GnomeAbout_Names_style"
+widget "*GnomeAbout*.Title" style "GnomeAbout_Title_style"
+widget "*GnomeHRef.GtkLabel" style "GnomeHRef_Label_style"
+widget "*GnomeGuru*.PageTitle" style "GnomeGuru_PageTitle_style"
diff --git a/libgnomeui/gtkrc.tr b/libgnomeui/gtkrc.tr
new file mode 100644
index 0000000..aa36f01
--- /dev/null
+++ b/libgnomeui/gtkrc.tr
@@ -0,0 +1,72 @@
+# $(datadir)/gtkrc.tr
+#
+# This file defines the fontsets for Turkish language (tr)
+#
+# 1999 Pablo Saratxaga <srtxg chanae alphanet ch>
+
+style "GnomeScores_CurrentPlayer_style"
+{
+  fg[NORMAL] = {1.0, 0.0, 0.0}
+}
+
+style "GnomeScores_Logo_style"
+{
+  fontset = "-freefont-garamond-*-*-*-*-30-170-*-*-*-*-iso8859-1,\
+          -*-garamond-*-r-*-*-34-*-*-*-*-*-iso8859-9,\
+	  -*-*-*-r-*-*-34-*-*-*-*-*-iso8859-9"
+  fg[NORMAL] = {0.0, 0.0, 1.0}
+}
+
+style "GnomeAbout_DrawingArea_style"
+{
+  bg[NORMAL] = {1.0, 1.0, 1.0}
+}
+
+style "GnomeAbout_Title_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-20-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Copyright_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Author_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-12-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Names_style"
+{
+  fontset = "-*-helvetica-medium-r-normal-*-12-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Comments_style"
+{
+  fontset = "-*-helvetica-medium-r-normal-*-10-*-*-*-*-*-*-*"
+}
+
+style "GnomeHRef_Label_style"
+{
+  fg[NORMAL] = { 0.0, 0.0, 1.0 }
+  fg[PRELIGHT] = { 0.0, 0.0, 1.0 }
+  fg[INSENSITIVE] = { 0.5, 0.5, 1.0 }
+  fg[ACTIVE] = { 1.0, 0.0, 0.0 }
+}
+
+style "GnomeGuru_PageTitle_style" 
+{
+ fontset = "-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*"	
+}
+
+widget "*GnomeScores*.CurrentPlayer" style "GnomeScores_CurrentPlayer_style"
+widget "*GnomeScores*.Logo" style "GnomeScores_Logo_style"
+widget "*GnomeAbout*.DrawingArea" style "GnomeAbout_DrawingArea_style"
+widget "*GnomeAbout*.Author" style "GnomeAbout_Author_style"
+widget "*GnomeAbout*.Comments" style "GnomeAbout_Comments_style"
+widget "*GnomeAbout*.Copyright" style "GnomeAbout_Copyright_style"
+widget "*GnomeAbout*.Names" style "GnomeAbout_Names_style"
+widget "*GnomeAbout*.Title" style "GnomeAbout_Title_style"
+widget "*GnomeHRef.GtkLabel" style "GnomeHRef_Label_style"
+widget "*GnomeGuru*.PageTitle" style "GnomeGuru_PageTitle_style"
diff --git a/libgnomeui/gtkrc.uk b/libgnomeui/gtkrc.uk
new file mode 100644
index 0000000..cc4a371
--- /dev/null
+++ b/libgnomeui/gtkrc.uk
@@ -0,0 +1,75 @@
+# $(datadir)/gtkrc.uk
+#
+# This file defines the fontsets for Ukrainian language (uk) using
+# the KOI8-U charset encoding.
+#
+# 1999, Pablo Saratxaga <srtxg chanae alphanet ch>
+#
+
+style "GnomeScores_CurrentPlayer_style"
+{
+  fg[NORMAL] = {1.0, 0.0, 0.0}
+}
+
+style "GnomeScores_Logo_style"
+{
+  fontset = "-freefont-garamond-*-*-*-*-30-170-*-*-*-*-iso8859-1,\
+	  -*-garamond-*-*-*-*-30-**-*-*-*-koi8-u,\
+          -cronyx-times-*-r-*-*-34-*-*-*-*-*-koi8-u"
+  fg[NORMAL] = {0.0, 0.0, 1.0}
+}
+
+style "GnomeAbout_DrawingArea_style"
+{
+  bg[NORMAL] = {1.0, 1.0, 1.0}
+}
+
+style "GnomeAbout_Title_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-20-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Copyright_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Author_style"
+{
+  fontset = "-*-helvetica-bold-r-normal-*-12-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Names_style"
+{
+  fontset = "-*-helvetica-medium-r-normal-*-12-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Comments_style"
+{
+  fontset = "-adobe-helvetica-medium-r-normal-*-10-*-*-*-*-*-*-*,\
+             -cronyx-helvetica-medium-r-normal-*-11-*-*-*-*-*-*-*"
+}
+
+style "GnomeHRef_Label_style"
+{
+  fg[NORMAL] = { 0.0, 0.0, 1.0 }
+  fg[PRELIGHT] = { 0.0, 0.0, 1.0 }
+  fg[INSENSITIVE] = { 0.5, 0.5, 1.0 }
+  fg[ACTIVE] = { 1.0, 0.0, 0.0 }
+}
+
+style "GnomeGuru_PageTitle_style" 
+{
+ fontset = "-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*"	
+}
+
+widget "*GnomeScores*.CurrentPlayer" style "GnomeScores_CurrentPlayer_style"
+widget "*GnomeScores*.Logo" style "GnomeScores_Logo_style"
+widget "*GnomeAbout*.DrawingArea" style "GnomeAbout_DrawingArea_style"
+widget "*GnomeAbout*.Author" style "GnomeAbout_Author_style"
+widget "*GnomeAbout*.Comments" style "GnomeAbout_Comments_style"
+widget "*GnomeAbout*.Copyright" style "GnomeAbout_Copyright_style"
+widget "*GnomeAbout*.Names" style "GnomeAbout_Names_style"
+widget "*GnomeAbout*.Title" style "GnomeAbout_Title_style"
+widget "*GnomeHRef.GtkLabel" style "GnomeHRef_Label_style"
+widget "*GnomeGuru*.PageTitle" style "GnomeGuru_PageTitle_style"
diff --git a/libgnomeui/gtkrc.vi_VN.tcvn b/libgnomeui/gtkrc.vi_VN.tcvn
new file mode 100644
index 0000000..a2bc8f0
--- /dev/null
+++ b/libgnomeui/gtkrc.vi_VN.tcvn
@@ -0,0 +1,76 @@
+# $(datadir)/gtkrc.vi_VN.tcvn
+#
+# This file defines the fontsets for Vietnamese language (vi) using
+# the Vietnam's official tcvn-5712 charset encoding.
+#
+# You can find links for tcvn True Type fonts following the
+# links at my page on vietnamese localisation at
+# http://www.ping.be/linux/viet/
+#
+# 1999, Pablo Saratxaga <srtxg chanae alphanet ch>
+#
+
+style "GnomeScores_CurrentPlayer_style"
+{
+  fg[NORMAL] = {1.0, 0.0, 0.0}
+}
+
+style "GnomeScores_Logo_style"
+{
+  fontset = "-*-verdana-*-*-*-*-30-170-*-*-*-*-tcvn-5712"
+  fg[NORMAL] = {0.0, 0.0, 1.0}
+}
+
+style "GnomeAbout_DrawingArea_style"
+{
+  bg[NORMAL] = {1.0, 1.0, 1.0}
+}
+
+style "GnomeAbout_Title_style"
+{
+  fontset = "-*-verdana-bold-r-normal-*-20-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Copyright_style"
+{
+  fontset = "-*-verdana-bold-r-normal-*-14-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Author_style"
+{
+  fontset = "-*-verdana-bold-r-normal-*-12-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Names_style"
+{
+  fontset = "-*-verdana-medium-r-normal-*-12-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Comments_style"
+{
+  fontset = "-*-verdana-medium-r-normal-*-10-*-*-*-*-*-*-*"
+}
+
+style "GnomeHRef_Label_style"
+{
+  fg[NORMAL] = { 0.0, 0.0, 1.0 }
+  fg[PRELIGHT] = { 0.0, 0.0, 1.0 }
+  fg[INSENSITIVE] = { 0.5, 0.5, 1.0 }
+  fg[ACTIVE] = { 1.0, 0.0, 0.0 }
+}
+
+style "GnomeGuru_PageTitle_style" 
+{
+ fontset = "-adobe-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*"	
+}
+
+widget "*GnomeScores*.CurrentPlayer" style "GnomeScores_CurrentPlayer_style"
+widget "*GnomeScores*.Logo" style "GnomeScores_Logo_style"
+widget "*GnomeAbout*.DrawingArea" style "GnomeAbout_DrawingArea_style"
+widget "*GnomeAbout*.Author" style "GnomeAbout_Author_style"
+widget "*GnomeAbout*.Comments" style "GnomeAbout_Comments_style"
+widget "*GnomeAbout*.Copyright" style "GnomeAbout_Copyright_style"
+widget "*GnomeAbout*.Names" style "GnomeAbout_Names_style"
+widget "*GnomeAbout*.Title" style "GnomeAbout_Title_style"
+widget "*GnomeHRef.GtkLabel" style "GnomeHRef_Label_style"
+widget "*GnomeGuru*.PageTitle" style "GnomeGuru_PageTitle_style"
diff --git a/libgnomeui/gtkrc.vi_VN.viscii b/libgnomeui/gtkrc.vi_VN.viscii
new file mode 100644
index 0000000..73e06e8
--- /dev/null
+++ b/libgnomeui/gtkrc.vi_VN.viscii
@@ -0,0 +1,76 @@
+# $(datadir)/gtkrc.vi_VN.viscii
+#
+# This file defines the fontsets for Vietnamese language (vi) using
+# the viscii 1.1 charset encoding.
+#
+# You can find links for viscii True Type fonts following the
+# links at my page on vietnamese localisation at
+# http://www.ping.be/linux/viet/
+#
+# 1999, Pablo Saratxaga <srtxg chanae alphanet ch>
+#
+
+style "GnomeScores_CurrentPlayer_style"
+{
+  fg[NORMAL] = {1.0, 0.0, 0.0}
+}
+
+style "GnomeScores_Logo_style"
+{
+  fontset = "-*-verdana-*-*-*-*-30-170-*-*-*-*-viscii1.1-1"
+  fg[NORMAL] = {0.0, 0.0, 1.0}
+}
+
+style "GnomeAbout_DrawingArea_style"
+{
+  bg[NORMAL] = {1.0, 1.0, 1.0}
+}
+
+style "GnomeAbout_Title_style"
+{
+  fontset = "-*-verdana-bold-r-normal-*-20-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Copyright_style"
+{
+  fontset = "-*-verdana-bold-r-normal-*-14-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Author_style"
+{
+  fontset = "-*-verdana-bold-r-normal-*-12-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Names_style"
+{
+  fontset = "-*-verdana-medium-r-normal-*-12-*-*-*-*-*-*-*"
+}
+
+style "GnomeAbout_Comments_style"
+{
+  fontset = "-*-verdana-medium-r-normal-*-10-*-*-*-*-*-*-*"
+}
+
+style "GnomeHRef_Label_style"
+{
+  fg[NORMAL] = { 0.0, 0.0, 1.0 }
+  fg[PRELIGHT] = { 0.0, 0.0, 1.0 }
+  fg[INSENSITIVE] = { 0.5, 0.5, 1.0 }
+  fg[ACTIVE] = { 1.0, 0.0, 0.0 }
+}
+
+style "GnomeGuru_PageTitle_style" 
+{
+ fontset = "-adobe-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*"	
+}
+
+widget "*GnomeScores*.CurrentPlayer" style "GnomeScores_CurrentPlayer_style"
+widget "*GnomeScores*.Logo" style "GnomeScores_Logo_style"
+widget "*GnomeAbout*.DrawingArea" style "GnomeAbout_DrawingArea_style"
+widget "*GnomeAbout*.Author" style "GnomeAbout_Author_style"
+widget "*GnomeAbout*.Comments" style "GnomeAbout_Comments_style"
+widget "*GnomeAbout*.Copyright" style "GnomeAbout_Copyright_style"
+widget "*GnomeAbout*.Names" style "GnomeAbout_Names_style"
+widget "*GnomeAbout*.Title" style "GnomeAbout_Title_style"
+widget "*GnomeHRef.GtkLabel" style "GnomeHRef_Label_style"
+widget "*GnomeGuru*.PageTitle" style "GnomeGuru_PageTitle_style"
diff --git a/libgnomeui/gtkrc.zh_CN b/libgnomeui/gtkrc.zh_CN
new file mode 100644
index 0000000..7373dca
--- /dev/null
+++ b/libgnomeui/gtkrc.zh_CN
@@ -0,0 +1,72 @@
+# $(datadir)/gtkrc.zh_CN
+#
+# This file defines the fontsets for Chinese language (zh) using
+# the simplified chinese standard GuoBiao as in mainland China (CN)
+#
+# 1999, Pablo Saratxaga <srtxg chanae alphanet ch>
+
+style "GnomeScores_CurrentPlayer_style"
+{
+  fg[NORMAL] = {1.0, 0.0, 0.0}
+}
+
+style "GnomeScores_Logo_style"
+{
+  fontset = "-misc-fixed-medium-r-normal--14-*-*-*-*-*-gb2312.1980-0"
+  fg[NORMAL] = {0.0, 0.0, 1.0}
+}
+
+style "GnomeAbout_DrawingArea_style"
+{
+  bg[NORMAL] = {1.0, 1.0, 1.0}
+}
+
+style "GnomeAbout_Title_style"
+{
+  fontset = "-misc-fixed-medium-r-normal--14-*-*-*-*-*-gb2312.1980-0"
+}
+
+style "GnomeAbout_Copyright_style"
+{
+  fontset = "-misc-fixed-medium-r-normal--14-*-*-*-*-*-gb2312.1980-0"
+}
+
+style "GnomeAbout_Author_style"
+{
+  fontset = "-misc-fixed-medium-r-normal--14-*-*-*-*-*-gb2312.1980-0"
+}
+
+style "GnomeAbout_Names_style"
+{
+  fontset = "-misc-fixed-medium-r-normal--14-*-*-*-*-*-gb2312.1980-0"
+}
+
+style "GnomeAbout_Comments_style"
+{
+  fontset = "-misc-fixed-medium-r-normal--14-*-*-*-*-*-gb2312.1980-0"
+}
+
+style "GnomeHRef_Label_style"
+{
+  fg[NORMAL] = { 0.0, 0.0, 1.0 }
+  fg[PRELIGHT] = { 0.0, 0.0, 1.0 }
+  fg[INSENSITIVE] = { 0.5, 0.5, 1.0 }
+  fg[ACTIVE] = { 1.0, 0.0, 0.0 }
+}
+
+style "GnomeGuru_PageTitle_style" 
+{
+  fontset = "-misc-fixed-medium-r-normal--14-*-*-*-*-*-gb2312.1980-0"
+}
+
+
+widget "*GnomeScores*.CurrentPlayer" style "GnomeScores_CurrentPlayer_style"
+widget "*GnomeScores*.Logo" style "GnomeScores_Logo_style"
+widget "*GnomeAbout*.DrawingArea" style "GnomeAbout_DrawingArea_style"
+widget "*GnomeAbout*.Author" style "GnomeAbout_Author_style"
+widget "*GnomeAbout*.Comments" style "GnomeAbout_Comments_style"
+widget "*GnomeAbout*.Copyright" style "GnomeAbout_Copyright_style"
+widget "*GnomeAbout*.Names" style "GnomeAbout_Names_style"
+widget "*GnomeAbout*.Title" style "GnomeAbout_Title_style"
+widget "*GnomeHRef.GtkLabel" style "GnomeHRef_Label_style"
+widget "*GnomeGuru*.PageTitle" style "GnomeGuru_PageTitle_style"
diff --git a/libgnomeui/gtkrc.zh_TW.Big5 b/libgnomeui/gtkrc.zh_TW.Big5
new file mode 100644
index 0000000..36819ce
--- /dev/null
+++ b/libgnomeui/gtkrc.zh_TW.Big5
@@ -0,0 +1,73 @@
+# $(datadir)/gtkrc.zh_TW
+#
+# This file defines the fontsets for Chinese language (ch) using
+# the traditional chinese Big5 encoding as used in Taiwan (TW)
+#
+# 1999, Pablo Saratxaga <srtxg chanae alphanet ch>
+#
+
+style "GnomeScores_CurrentPlayer_style"
+{
+  fg[NORMAL] = {1.0, 0.0, 0.0}
+}
+
+style "GnomeScores_Logo_style"
+{
+  fontset = "-*-fixed-medium-r-normal--24-*-*-*-*-*-big5-0"
+  fg[NORMAL] = {0.0, 0.0, 1.0}
+}
+
+style "GnomeAbout_DrawingArea_style"
+{
+  bg[NORMAL] = {1.0, 1.0, 1.0}
+}
+
+style "GnomeAbout_Title_style"
+{
+  fontset = "-*-fixed-medium-r-normal--16-*-*-*-*-*-big5-0"
+}
+
+style "GnomeAbout_Copyright_style"
+{
+  fontset = "-*-fixed-medium-r-normal--16-*-*-*-*-*-big5-0"
+}
+
+style "GnomeAbout_Author_style"
+{
+  fontset = "-*-fixed-medium-r-normal--16-*-*-*-*-*-big5-0"
+}
+
+style "GnomeAbout_Names_style"
+{
+  fontset = "-*-fixed-medium-r-normal--16-*-*-*-*-*-big5-0"
+}
+
+style "GnomeAbout_Comments_style"
+{
+  fontset = "-*-fixed-medium-r-normal--16-*-*-*-*-*-big5-0"
+}
+
+style "GnomeHRef_Label_style"
+{
+  fg[NORMAL] = { 0.0, 0.0, 1.0 }
+  fg[PRELIGHT] = { 0.0, 0.0, 1.0 }
+  fg[INSENSITIVE] = { 0.5, 0.5, 1.0 }
+  fg[ACTIVE] = { 1.0, 0.0, 0.0 }
+}
+
+style "GnomeGuru_PageTitle_style" 
+{
+  fontset = "-*-fixed-medium-r-normal--16-*-*-*-*-*-big5-0"
+}
+
+
+widget "*GnomeScores*.CurrentPlayer" style "GnomeScores_CurrentPlayer_style"
+widget "*GnomeScores*.Logo" style "GnomeScores_Logo_style"
+widget "*GnomeAbout*.DrawingArea" style "GnomeAbout_DrawingArea_style"
+widget "*GnomeAbout*.Author" style "GnomeAbout_Author_style"
+widget "*GnomeAbout*.Comments" style "GnomeAbout_Comments_style"
+widget "*GnomeAbout*.Copyright" style "GnomeAbout_Copyright_style"
+widget "*GnomeAbout*.Names" style "GnomeAbout_Names_style"
+widget "*GnomeAbout*.Title" style "GnomeAbout_Title_style"
+widget "*GnomeHRef.GtkLabel" style "GnomeHRef_Label_style"
+widget "*GnomeGuru*.PageTitle" style "GnomeGuru_PageTitle_style"
diff --git a/libgnomeui/landscape.xpm b/libgnomeui/landscape.xpm
new file mode 100644
index 0000000..f31d529
--- /dev/null
+++ b/libgnomeui/landscape.xpm
@@ -0,0 +1,36 @@
+/* XPM */
+static char * landscape_xpm[] = {
+"40 30 3 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"      ................................  ",
+"     ..++++++++++++++++++++++++++++++.  ",
+"    ...++++++++++++++++++++++++++++++...",
+"   ....++++++++++++++++++++++++++++++...",
+"  .....++++++++++++++++++++++++++++++...",
+" ......++++++++++++++++++++++++++++++...",
+".......++++++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++++++++++++...",
+"........................................",
+"  ......................................",
+"  ......................................"};
diff --git a/libgnomeui/libgnomeui-2.0.pc.in b/libgnomeui/libgnomeui-2.0.pc.in
new file mode 100644
index 0000000..b9e3dad
--- /dev/null
+++ b/libgnomeui/libgnomeui-2.0.pc.in
@@ -0,0 +1,11 @@
+prefix= prefix@
+exec_prefix= exec_prefix@
+libdir= libdir@
+includedir= includedir@
+
+Name: libgnomeui
+Description: libgnomeui
+Requires: libgnome-2.0 gtk+-2.0 gdk-pixbuf-2.0 gconf-2.0 libart-2.0
+Version: @VERSION@
+Libs: -L${libdir} -lgnomeui- GNOME_INTERFACE_VERSION@
+Cflags:
diff --git a/libgnomeui/libgnomeui.h b/libgnomeui/libgnomeui.h
new file mode 100644
index 0000000..39d1adc
--- /dev/null
+++ b/libgnomeui/libgnomeui.h
@@ -0,0 +1,98 @@
+/*  -*- Mode: C; c-set-style: linux; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#ifndef LIBGNOMEUI_H
+#define LIBGNOMEUI_H
+
+
+#include <libgnomeui/gnome-uidefs.h>
+#include <libgnomeui/gnome-about.h>
+#include <libgnomeui/gnome-animator.h>
+#include <libgnomeui/gnome-app.h>
+#include <libgnomeui/gnome-appbar.h>
+#include <libgnomecanvas/gnome-canvas.h>
+#include <libgnomecanvas/gnome-canvas-pixbuf.h>
+#include <libgnomecanvas/gnome-canvas-line.h>
+#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
+#include <libgnomecanvas/gnome-canvas-polygon.h>
+#include <libgnomecanvas/gnome-canvas-text.h>
+#include <libgnomecanvas/gnome-canvas-util.h>
+#include <libgnomecanvas/gnome-canvas-widget.h>
+#include <libgnomeui/gnome-color-picker.h>
+#include <libgnomeui/gnome-cursors.h>
+#include <libgnomeui/gnome-dock.h>
+#include <libgnomeui/gnome-dock-band.h>
+#include <libgnomeui/gnome-dock-item.h>
+#include <libgnomeui/gnome-entry.h>
+#include <libgnomeui/gnome-selector.h>
+#include <libgnomeui/gnome-file-selector.h>
+#include <libgnomeui/gnome-font-picker.h>
+#include <libgnomeui/gnome-gconf.h>
+#include <libgnomeui/gnome-geometry.h>
+#include <libgnomeui/gnome-helpsys.h>
+
+#include <libgnomeui/gnome-icon-list.h>
+#include <libgnomeui/gnome-icon-item.h>
+#include <libgnomeui/gnome-icon-selector.h>
+#include <libgnomeui/gnome-icon-entry.h>
+#include <libgnomeui/gnome-canvas-init.h>
+#include <libgnomeui/gnome-init.h>
+#include <libgnomeui/gnome-less.h>
+#include <libgnomeui/gnome-macros.h>
+/* Considering moving this to gnome-print, so this file 
+   is deprecated but the API isn't */
+#include <libgnomeui/gnome-paper-selector.h>
+#include <libgnomeui/gnome-unit-spinner.h>
+#include <libgnomeui/gnome-popup-menu.h>
+#include <libgnomeui/gnome-popup-help.h>
+#include <libgnomeui/gnome-pixmap.h>
+#include <libgnomeui/gnome-types.h>
+#include <libgnomeui/gnome-stock.h>
+#include <libgnomeui/gnome-client.h>
+#include <libgnomeui/gtk-clock.h>
+#include <libgnomeui/gtkdial.h>
+#include <libgnomeui/gtkpixmapmenuitem.h>
+#include <libgnomeui/gnome-dateedit.h>
+#include <libgnomeui/gnome-mdi.h>
+#include <libgnomeui/gnome-mdi-child.h>
+#include <libgnomeui/gnome-mdi-generic-child.h>
+#include <libgnomeui/gnome-mdi-session.h>
+#include <libgnomeui/gnometypebuiltins.h>
+#include <libgnomeui/gnome-winhints.h>
+#include <libgnomeui/gnome-href.h>
+#include <libgnomeui/gnome-druid.h>
+#include <libgnomeui/gnome-druid-page.h>
+#include <libgnomeui/gnome-druid-page-edge.h>
+#include <libgnomeui/gnome-druid-page-standard.h>
+#include <libgnomeui/oafgnome.h>
+#include <libgnomeui/gnome-textfu.h>
+#include <libgnomeui/gnome-vfs-util.h>
+
+#ifdef COMPAT_1_0
+#include "compat/1.0/libgnomeui-compat-1.0.h"
+#endif
+
+#endif
diff --git a/libgnomeui/libgnomeui.schemas b/libgnomeui/libgnomeui.schemas
new file mode 100644
index 0000000..a86a958
--- /dev/null
+++ b/libgnomeui/libgnomeui.schemas
@@ -0,0 +1,42 @@
+<gconfschemafile>
+
+<!-- 
+Note: all double hyphens in this comment have a space in the middle
+because double hyphen isn't allowed in comments. So, remove the space
+before use.
+
+To install this file type: 
+      gconftool - -install-schema-file basic-gconf-app.schemas 
+You probably want your "make install" to do this for real applications.
+Also, you probably want a configure option so people can retarget where the 
+schema file gets installed. The option should be called - -gconf-config-source=blah
+To change the gconftool target use the - -config-source=blah option to gconftool.
+-->
+
+    <schemalist>    
+      <schema>
+      <key>/schemas/desktop/gnome/dialog-buttons-style</key>
+      <applyto>/desktop/gnome/dialog-buttons-style</applyto>
+      <owner>libgnomeui</owner>
+      <type>string</type>
+      <default>End</default>
+      <locale name="C">
+        <short>How to arrange the buttons in GNOME dialogs</short>
+
+        <long>There are five possible values for this setting: "Default",
+        "Spread", "Edge", "Start", and "End". </long>
+      </locale>
+
+      <locale name="no">
+        <short>short description in Norway</short>
+        <long>Long description in Norway. long long long. this is a long sentence.</long>
+      </locale>
+    </schema>
+
+  </schemalist>
+  
+</gconfschemafile>
+
+
+
+
diff --git a/libgnomeui/libgnomeuiP.h b/libgnomeui/libgnomeuiP.h
new file mode 100644
index 0000000..7263621
--- /dev/null
+++ b/libgnomeui/libgnomeuiP.h
@@ -0,0 +1,51 @@
+/*  -*- Mode: C; c-set-style: linux; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#ifndef LIBGNOMEUIP_H
+#define LIBGNOMEUIP_H
+
+#include <glib.h>
+#include <gobject/gsignal.h>
+#include <gtk/gtktypeutils.h>
+
+
+
+#include "gnome-macros.h"
+#include "gnometypebuiltins.h"
+#include "gnomemarshal.h"
+
+G_BEGIN_DECLS
+
+void gnome_type_init(void);
+
+/* FIXME: broken */
+extern const GList *gnome_i18n_get_language_list (const gchar *category_name);
+extern char *gnome_i18n_get_preferred_language (void);
+
+G_END_DECLS
+
+#endif /* LIBGNOMEUIP_H */
+
diff --git a/libgnomeui/oafgnome.c b/libgnomeui/oafgnome.c
new file mode 100644
index 0000000..ee5eff4
--- /dev/null
+++ b/libgnomeui/oafgnome.c
@@ -0,0 +1,521 @@
+/*
+ * Copyright (C) 1999, 2000 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#include "oafgnome.h"
+#include <signal.h>
+#include <popt.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <gtk/gtk.h>
+
+#include <libgnome/gnome-i18n.h>
+#include <libgnome/gnome-config.h>
+#include <liboaf/liboaf.h>
+#include <gdk/gdkx.h>
+#include <gdk/gdk.h>
+#include <libgnomeui/gnome-init.h>
+#include <libgnomeui/gnome-dialog-util.h>
+#include <libgnomeui/gnome-dialog.h>
+
+static void og_pre_args_parse(GnomeProgram *app,
+			      GnomeModuleInfo *mod_info);
+static void og_post_args_parse(GnomeProgram *app,
+			       GnomeModuleInfo *mod_info);
+static OAFRegistrationLocation rootwin_regloc;
+static CORBA_Object rcmd_activator(const OAFRegistrationCategory *regcat, const char **cmd,
+				   int ior_fd, CORBA_Environment *ev);
+
+static GnomeModuleInfo orbit_module_info = {
+  "ORBit", orbit_version, "CORBA implementation",
+   NULL,
+   NULL, NULL,
+   NULL,
+   NULL
+};
+
+static GnomeModuleRequirement liboaf_requirements[] = {
+  {"0.5.1", &orbit_module_info},
+  {NULL}
+};
+
+static GnomeModuleInfo liboaf_module_info = {
+  "liboaf", liboaf_version, "Object Activation Framework",
+  liboaf_requirements,
+  (GnomeModuleHook)oaf_preinit, (GnomeModuleHook)oaf_postinit,
+  (struct poptOption *)oaf_popt_options,
+  NULL
+};
+
+static GnomeModuleRequirement og_requirements[] = {
+  {"0.0", &liboaf_module_info},
+  {"1.2.0", &gtk_module_info},
+  {NULL}
+};
+
+GnomeModuleInfo liboafgnome_module_info = {
+  "liboafgnome", VERSION, "OAF integration for GNOME programs",
+  og_requirements,
+  og_pre_args_parse, og_post_args_parse,
+  NULL,
+  NULL
+};
+
+static void
+og_pre_args_parse(GnomeProgram *app, GnomeModuleInfo *mod_info)
+{
+  int dumb_argc = 1;
+  char *dumb_argv[] = {NULL};
+  dumb_argv[0] = program_invocation_name;
+  (void) oaf_orb_init(&dumb_argc, dumb_argv);
+}
+
+static void
+og_post_args_parse(GnomeProgram *app, GnomeModuleInfo *mod_info)
+{
+  oaf_registration_location_add(&rootwin_regloc, -100, NULL);
+  oaf_registration_activator_add(rcmd_activator, 100);
+}
+
+/* Registration location stuff */
+#include <gdk/gdkx.h>
+
+static void
+rootwin_lock(const OAFRegistrationLocation *regloc,
+	     gpointer user_data)
+{
+  XGrabServer(GDK_DISPLAY());
+  gdk_flush();
+}
+
+static void
+rootwin_unlock(const OAFRegistrationLocation *regloc,
+	       gpointer user_data)
+{
+  XUngrabServer(GDK_DISPLAY());
+  gdk_flush();
+}
+
+static char *
+rootwin_check(const OAFRegistrationLocation *regloc,
+	      const OAFRegistrationCategory *regcat,
+	      int *ret_distance, gpointer user_data)
+{
+  GdkAtom type;
+  int fmt;
+  char *ior = NULL;
+  gint actual_length;
+
+  if(strcmp(regcat->name, "IDL:OAF/ActivationContext:1.0"))
+    return NULL;
+
+  if(!
+     gdk_property_get (GDK_ROOT_PARENT(),
+		       gdk_atom_intern("OAFGNOME_AC_IOR", FALSE),
+		       gdk_atom_intern("STRING", FALSE),
+		       0, 99999, FALSE, &type, &fmt, &actual_length,
+		       (guchar **)&ior))
+    return NULL;
+
+  return ior;
+}
+
+static void
+rootwin_register(const OAFRegistrationLocation *regloc,
+		 const char *ior,
+		 const OAFRegistrationCategory *regcat,
+		 gpointer user_data)
+{
+  gdk_property_change(GDK_ROOT_PARENT(), gdk_atom_intern("OAFGNOME_AC_IOR", FALSE),
+		      gdk_atom_intern("STRING", FALSE), 8, GDK_PROP_MODE_REPLACE, (guchar *) ior, strlen(ior));
+}
+
+static void
+rootwin_unregister(const OAFRegistrationLocation *regloc,
+		   const char *ior,
+		   const OAFRegistrationCategory *regcat,
+		   gpointer user_data)
+{
+  gdk_property_delete(GDK_ROOT_PARENT(), gdk_atom_intern("OAFGNOME_AC_IOR", FALSE));
+}
+
+static OAFRegistrationLocation rootwin_regloc = {
+  rootwin_lock,
+  rootwin_unlock,
+  rootwin_check,
+  rootwin_register,
+  rootwin_unregister
+};
+
+/******** The "execute a remote command" hack :) *******/
+typedef struct {
+  const OAFRegistrationCategory *regcat;
+
+  char iorbuf[4096];
+
+  int infd, outfd;
+  GString *in_buf;
+  FILE *in_fh, *out_fh;
+
+  guint out_tag;
+
+  enum { CONNECTING, ITEMWAIT, REMOTE_CONV, DONE } state;
+  const char **cmd;
+} RCMDRunInfo;
+
+static void
+item_send_val(gchar *string, gpointer data)
+{
+  RCMDRunInfo *ri = (RCMDRunInfo *)data;
+
+  if(string) {
+    fprintf(ri->in_fh, "%s\n", string);
+    g_free(string);
+    ri->state = CONNECTING;
+  }
+
+  gtk_main_quit();
+}
+
+/* What a stupid replacement for expect. It will break if anything isn't working exactly right. Oh well :\ */
+static void
+rcmd_handle_connecting(RCMDRunInfo *ri)
+{
+  char aline[4096];
+  int nchars;
+  char *ctmp;
+
+ retry:
+  nchars = read(ri->outfd, aline, sizeof(aline) - 1);
+  if(nchars < 0)
+    {
+      switch(errno)
+	{
+	case EAGAIN:
+	  goto retry;
+	  break;
+	default:
+	  gtk_main_quit();
+	  return;
+	  break;
+	}
+      return;
+    }
+  aline[nchars] = '\0';
+  g_string_append(ri->in_buf, aline);
+
+  /* Now, see if we have timed out or got a whole line */
+
+  if((ctmp = strstr(ri->in_buf->str, "login:")))
+    {
+      GtkWidget *prompt_dialog;
+
+      g_string_erase(ri->in_buf, 0, ctmp - ri->in_buf->str + strlen("login:"));
+
+      ri->state = ITEMWAIT;
+
+      prompt_dialog = gnome_request_dialog(FALSE, N_("Username:"), g_get_user_name(), -1, item_send_val, ri, NULL);
+      gnome_dialog_run(GNOME_DIALOG(prompt_dialog));
+
+      if(ri->state == ITEMWAIT)
+	gtk_main_quit(); /* User cancelled, show is over */
+    }
+  else if((ctmp = strstr(ri->in_buf->str, "ssword:")))
+    {
+      GtkWidget *prompt_dialog;
+
+      g_string_erase(ri->in_buf, 0, ctmp - ri->in_buf->str + strlen("ssword:"));
+
+      ri->state = ITEMWAIT;
+
+      prompt_dialog = gnome_request_dialog(TRUE, N_("Password:"), "", -1, item_send_val, ri, NULL);
+      gnome_dialog_run(GNOME_DIALOG(prompt_dialog));
+
+      if(ri->state == ITEMWAIT)
+	gtk_main_quit(); /* User cancelled, show is over */
+    }
+  else if((ctmp = strstr(ri->in_buf->str, "continue connecting (yes/no)?")))
+    {
+      g_string_erase(ri->in_buf, 0, ctmp - ri->in_buf->str + strlen("continue connecting (yes/no)?"));
+
+      fputs("yes\n", ri->in_fh);
+    }
+  else if((ctmp = strstr(ri->in_buf->str, "GNOME BOOTSTRAP READY")))
+    {
+      int i;
+
+      g_string_erase(ri->in_buf, 0, ctmp - ri->in_buf->str + strlen("GNOME BOOTSTRAP READY"));
+
+      ri->state = REMOTE_CONV;
+
+      fprintf(ri->in_fh, "RUN");
+      for(i = 0; ri->cmd[i]; i++)
+	fprintf(ri->in_fh, " %s", ri->cmd[i]);
+      fprintf(ri->in_fh, "\n");
+
+      g_string_erase(ri->in_buf, 0, ctmp - ri->in_buf->str);
+    }
+  else if(strstr(aline, "Permission denied.")
+	  || strstr(aline, "connection closed."))
+    {
+      gtk_main_quit(); /* Can't connect */
+    }
+
+  fflush(ri->in_fh);
+}
+
+static void
+rcmd_handle_itemwait(RCMDRunInfo *ri)
+{
+  g_error("We should never get an FD callback in itemwait state!");
+}
+
+static void
+rcmd_handle_remote_conv(RCMDRunInfo *ri)
+{
+  char aline[4096];
+
+  if(!fgets(aline, sizeof(aline), ri->out_fh))
+    {
+      gtk_main_quit();
+      return;
+    }
+
+  g_strstrip(aline);
+
+  if(!strncmp(aline, "OUTPUT ", strlen("OUTPUT ")))
+    {
+      if(!strncmp(aline + strlen("OUTPUT "), "IOR:", strlen("IOR:"))) /* Bingo */
+	{
+	  ri->state = DONE;
+
+	  fprintf(ri->in_fh, "DONE\n");
+	  gtk_main_quit();
+	}
+    }
+  else if(!strncmp(aline, "ERROR ", strlen("ERROR ")))
+    {
+      ri->state = DONE;
+      gtk_main_quit();
+    }
+}
+
+static gboolean
+rcmd_handle_output(GIOChannel *src, GIOCondition condition, gpointer data)
+{
+  RCMDRunInfo *ri;
+
+  ri = (RCMDRunInfo *)data;
+
+  if(!(condition & G_IO_IN)) /* Some sort of error */
+    {
+      ri->iorbuf[0] = '\0';
+      gtk_main_quit();
+      return TRUE;
+    }
+
+  switch(ri->state)
+    {
+    case CONNECTING:
+      rcmd_handle_connecting(ri);
+      break;
+    case ITEMWAIT:
+      rcmd_handle_itemwait(ri);
+      break;
+    case REMOTE_CONV:
+      rcmd_handle_remote_conv(ri);
+      break;
+    case DONE:
+      gtk_main_quit();
+      break;
+    }
+
+  return TRUE;
+}
+
+static char *
+rcmd_run(const OAFRegistrationCategory *regcat, const char **argv, int argc, const char **remote_cmd)
+{
+  RCMDRunInfo ri;
+  int pipes_in[2], pipes_out[2];
+  int childpid;
+
+  if(pipe(pipes_in))
+    return NULL;
+
+  if(pipe(pipes_out))
+    {
+      close(pipes_in[0]);
+      close(pipes_in[1]);
+      return NULL;
+    }
+
+  memset(&ri, 0, sizeof(ri));
+
+  ri.in_buf = g_string_new("");
+  ri.regcat = regcat;
+  ri.state = CONNECTING;
+  ri.cmd = remote_cmd;
+
+  childpid = fork();
+  if(!childpid)
+    {
+      sigset_t mask;
+
+      setsid();
+
+      /* Make sure that the rsh/ssh command doesn't wig out after papa stops listening */
+      sigemptyset(&mask);
+      sigaddset(&mask, SIGPIPE);
+      sigprocmask(SIG_BLOCK, &mask, NULL);
+
+      close(pipes_out[0]);
+
+      if(dup2(pipes_out[1], 1) < 0)
+	_exit(1);
+
+      if(dup2(pipes_out[1], 2) < 0)
+	_exit(1);
+
+      if(pipes_out[1] != 1 && pipes_out[1] != 2)
+	close(pipes_out[1]);
+
+      close(pipes_in[1]);
+
+      if(dup2(pipes_in[0], 0) < 0)
+	_exit(1);
+
+      if(pipes_in[0] != 0)
+	close(pipes_in[0]);
+
+      /* Now we have all the pipes set up ready to run the process - let's do it */
+
+      execvp(argv[0], (char **)argv);
+
+      _exit(1); /* Doh! */
+    }
+
+  ri.infd = pipes_in[1];
+  ri.in_fh = fdopen(ri.infd, "w");
+  ri.outfd = pipes_out[0];
+  fcntl(ri.outfd, F_SETFL, O_NONBLOCK);
+  ri.out_fh = fdopen(ri.outfd, "r");
+
+  {
+    GIOChannel *i_hate_glib;
+    i_hate_glib = g_io_channel_unix_new(ri.outfd);
+    ri.out_tag = g_io_add_watch(i_hate_glib, G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL, rcmd_handle_output, &ri);
+    g_io_channel_unref(i_hate_glib);
+  }
+
+  gtk_main();
+
+  g_source_remove(ri.out_tag);
+
+  fclose(ri.in_fh);
+  fclose(ri.out_fh);
+
+  waitpid(childpid, &ri.out_tag, WNOHANG); /* Try to reap it if possible */
+
+  g_string_free(ri.in_buf, TRUE);
+
+  return (*ri.iorbuf)?g_strdup(ri.iorbuf):NULL;
+}
+
+static CORBA_Object
+rcmd_activator(const OAFRegistrationCategory *regcat, const char **cmd,
+	       int ior_fd, CORBA_Environment *ev)
+{
+  char *basecmd = gnome_config_get_string("/OAF/RemoteCommand=rsh");
+  char *ior_string;
+  const char *argv[10/*XXX: MAGIC Number, but it's right*/];
+  char iornum_buf[25], display_buf[512], langs_buf[512];
+  int argc = 0;
+  CORBA_Object retval;
+
+  if(!regcat->hostname && !regcat->username)
+    return CORBA_OBJECT_NIL;
+
+  argv[argc++] = basecmd;
+  if(regcat->username)
+    {
+      argv[argc++] = "-l";
+      argv[argc++] = regcat->username;
+    }
+
+  argv[argc++] = regcat->hostname?regcat->hostname:"localhost";
+  argv[argc++] = "gnome-remote-bootstrap"; /* The command that runs on the remote end to start oafd for us */
+  g_snprintf(iornum_buf, sizeof(iornum_buf), "--ior-fd=%d", ior_fd);
+  argv[argc++] = iornum_buf;
+
+  {
+    const char *mydisplay = NULL;
+    GValue value = { 0, };
+
+    g_value_init (&value, G_TYPE_STRING);
+    g_object_get_property (G_OBJECT (gnome_program_get()),
+			   LIBGNOMEUI_PARAM_DISPLAY, &value);
+    mydisplay = g_value_get_string (&value);
+
+    g_assert(mydisplay);
+
+    g_snprintf(display_buf, sizeof(display_buf), "--display=%s%s", (mydisplay[0]==':')?oaf_hostname_get():"", mydisplay);
+    argv[argc++] = display_buf;
+
+    g_value_unset (&value);
+  }
+
+  {
+    const GList *langs = gnome_i18n_get_language_list(NULL);
+    GString *langparam = g_string_new(langs?langs->data:"");
+
+    if(langs)
+      for(langs = langs->next; langs; langs = langs->next)
+	{
+	  g_string_append_c(langparam, ':');
+	  g_string_append(langparam, langs->data);
+	}
+
+    g_snprintf(langs_buf, sizeof(langs_buf), "--languages=%s", langparam->str);
+    g_string_free(langparam, TRUE);
+    argv[argc++] = langs_buf;
+  }
+
+  argv[argc] = NULL; /* The last one */
+
+  ior_string = rcmd_run(regcat, argv, argc, cmd);
+  g_free(basecmd);
+
+  retval = CORBA_ORB_string_to_object(oaf_orb_get(), ior_string, ev);
+  if(ev->_major != CORBA_NO_EXCEPTION)
+    retval = CORBA_OBJECT_NIL;
+
+  g_free(ior_string);
+
+  return retval;
+}
diff --git a/libgnomeui/oafgnome.h b/libgnomeui/oafgnome.h
new file mode 100644
index 0000000..1acf277
--- /dev/null
+++ b/libgnomeui/oafgnome.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 1999, 2000 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+ */
+
+#ifndef OAF_GNOME_H
+#define OAF_GNOME_H 1
+
+#include <libgnome/gnome-program.h>
+
+extern GnomeModuleInfo liboafgnome_module_info;
+
+#define OAF_GNOME_INIT GNOME_PARAM_MODULE,&liboafgnome_module_info
+
+#endif
diff --git a/libgnomeui/pixmaps/.cvsignore b/libgnomeui/pixmaps/.cvsignore
new file mode 100644
index 0000000..9f2bcfe
--- /dev/null
+++ b/libgnomeui/pixmaps/.cvsignore
@@ -0,0 +1,5 @@
+Makefile
+Makefile.in
+.deps
+.xvpics
+gnome-stock-pixbufs.h
diff --git a/libgnomeui/pixmaps/Makefile.am b/libgnomeui/pixmaps/Makefile.am
new file mode 100644
index 0000000..9d91207
--- /dev/null
+++ b/libgnomeui/pixmaps/Makefile.am
@@ -0,0 +1,106 @@
+pixmapdir = $(datadir)/pixmaps
+BITMAPS    = calculator-font.png
+
+pixmap_DATA = $(BITMAPS)
+
+# Please update this when you add more `stock_*.png' files
+stock_images = \
+	stock_add.png \
+	stock_align_center.png \
+	stock_align_justify.png \
+	stock_align_left.png \
+	stock_align_right.png \
+	stock_attach.png \
+	stock_book_blue.png \
+	stock_book_green.png \
+	stock_book_open.png \
+	stock_book_red.png \
+	stock_book_yellow.png \
+	stock_bottom.png \
+	stock_button_apply.png \
+	stock_button_cancel.png \
+	stock_button_close.png \
+	stock_button_no.png \
+	stock_button_ok.png \
+	stock_button_yes.png \
+	stock_cdrom.png \
+	stock_clear.png \
+	stock_close.png \
+	stock_colorselector.png \
+	stock_convert.png \
+	stock_copy.png \
+	stock_cut.png \
+	stock_down_arrow.png \
+	stock_exec.png \
+	stock_exit.png \
+	stock_font.png \
+	stock_first.png \
+	stock_help.png \
+	stock_home.png \
+	stock_index.png \
+	stock_jump_to.png \
+	stock_last.png \
+	stock_left_arrow.png \
+	stock_line_in.png \
+	stock_mail.png \
+	stock_mail_compose.png \
+	stock_mail_forward.png \
+	stock_mail_receive.png \
+	stock_mail_reply.png \
+	stock_mail_send.png \
+	stock_menu_about.png \
+	stock_menu_blank.png \
+	stock_menu_scores.png \
+	stock_mic.png \
+	stock_multiple_file.png \
+	stock_new.png \
+	stock_not.png \
+	stock_open.png \
+	stock_paste.png \
+	stock_preferences.png \
+	stock_print.png \
+	stock_properties.png \
+	stock_redo.png \
+	stock_refresh.png \
+	stock_remove.png \
+	stock_revert.png \
+	stock_right_arrow.png \
+	stock_save.png \
+	stock_save_as.png \
+	stock_scores.png \
+	stock_search.png \
+	stock_search_replace.png \
+	stock_spellcheck.png \
+	stock_stop.png \
+	stock_table_borders.png \
+	stock_table_fill.png \
+	stock_text_bold.png \
+	stock_text_bulleted_list.png \
+	stock_text_indent.png \
+	stock_text_italic.png \
+	stock_text_numbered_list.png \
+	stock_text_strikeout.png \
+	stock_text_underline.png \
+	stock_text_unindent.png \
+	stock_timer.png \
+	stock_timer_stopped.png \
+	stock_top.png \
+	stock_trash.png \
+	stock_trash_full.png \
+	stock_undelete.png \
+	stock_undo.png \
+	stock_up_arrow.png \
+	stock_volume.png \
+	stock_midi.png
+
+EXTRA_DIST  = $(BITMAPS) $(stock_images)
+
+noinst_HEADERS = gnome-stock-pixbufs.h
+BUILT_SOURCES = gnome-stock-pixbufs.h
+
+CLEANFILES = $(BUILT_SOURCES)
+
+gnome-stock-pixbufs.h: @MAKE_INLINE_PIXBUF@ $(stock_images)
+	-rm -f gnome-stock-pixbufs.h
+	vars=`echo "$(stock_images)" | sed -e 's,stock_\([^\.]*\)\.png,stock_\1 stock_\1.png,g'`; @MAKE_INLINE_PIXBUF@ pixbufs-tmp $$vars && cat $(srcdir)/copyright.txt pixbufs-tmp > gnome-stock-pixbufs.h
+	-rm -f pixbufs-tmp
\ No newline at end of file
diff --git a/libgnomeui/pixmaps/calculator-font.png b/libgnomeui/pixmaps/calculator-font.png
new file mode 100644
index 0000000..a2daefc
Binary files /dev/null and b/libgnomeui/pixmaps/calculator-font.png differ
diff --git a/libgnomeui/pixmaps/copyright.txt b/libgnomeui/pixmaps/copyright.txt
new file mode 100644
index 0000000..d2eff33
--- /dev/null
+++ b/libgnomeui/pixmaps/copyright.txt
@@ -0,0 +1,14 @@
+/* gnome stock icons in Imlib usable rgb data
+ *
+ * Copyright (C) 1997 the Free Software Foundation
+ *
+ * the pixmaps for button_cancel, save_as, trash, mail_receive, stop
+ * right_arrow, home, save, book_blue, trash_full, undo, search, mail_forward
+ * revert, mail_compose, mic, copy, jump_to, convert, button_apply, timer
+ * mail, book_red, book_yellow, help, redo, new, mail_send, button_yes, cut
+ * properties, print, mail_reply, refresh, search_replace, open, preferences
+ * left_arrow, undelete, close, volume, button_no, exit, book_green
+ * book_open, paste, line_in, spellcheck, timer_stopped
+ * are Copyright (C) 1998 Tuomas Kuosmanen
+ */
+
diff --git a/libgnomeui/pixmaps/stock_add.png b/libgnomeui/pixmaps/stock_add.png
new file mode 100644
index 0000000..62ddebe
Binary files /dev/null and b/libgnomeui/pixmaps/stock_add.png differ
diff --git a/libgnomeui/pixmaps/stock_align_center.png b/libgnomeui/pixmaps/stock_align_center.png
new file mode 100644
index 0000000..b11ae62
Binary files /dev/null and b/libgnomeui/pixmaps/stock_align_center.png differ
diff --git a/libgnomeui/pixmaps/stock_align_justify.png b/libgnomeui/pixmaps/stock_align_justify.png
new file mode 100644
index 0000000..964a9fb
Binary files /dev/null and b/libgnomeui/pixmaps/stock_align_justify.png differ
diff --git a/libgnomeui/pixmaps/stock_align_left.png b/libgnomeui/pixmaps/stock_align_left.png
new file mode 100644
index 0000000..c125dcc
Binary files /dev/null and b/libgnomeui/pixmaps/stock_align_left.png differ
diff --git a/libgnomeui/pixmaps/stock_align_right.png b/libgnomeui/pixmaps/stock_align_right.png
new file mode 100644
index 0000000..8ac8632
Binary files /dev/null and b/libgnomeui/pixmaps/stock_align_right.png differ
diff --git a/libgnomeui/pixmaps/stock_attach.png b/libgnomeui/pixmaps/stock_attach.png
new file mode 100644
index 0000000..b4bac8d
Binary files /dev/null and b/libgnomeui/pixmaps/stock_attach.png differ
diff --git a/libgnomeui/pixmaps/stock_book_blue.png b/libgnomeui/pixmaps/stock_book_blue.png
new file mode 100644
index 0000000..9f69313
Binary files /dev/null and b/libgnomeui/pixmaps/stock_book_blue.png differ
diff --git a/libgnomeui/pixmaps/stock_book_green.png b/libgnomeui/pixmaps/stock_book_green.png
new file mode 100644
index 0000000..ac7f375
Binary files /dev/null and b/libgnomeui/pixmaps/stock_book_green.png differ
diff --git a/libgnomeui/pixmaps/stock_book_open.png b/libgnomeui/pixmaps/stock_book_open.png
new file mode 100644
index 0000000..428b1b1
Binary files /dev/null and b/libgnomeui/pixmaps/stock_book_open.png differ
diff --git a/libgnomeui/pixmaps/stock_book_red.png b/libgnomeui/pixmaps/stock_book_red.png
new file mode 100644
index 0000000..99f6d5b
Binary files /dev/null and b/libgnomeui/pixmaps/stock_book_red.png differ
diff --git a/libgnomeui/pixmaps/stock_book_yellow.png b/libgnomeui/pixmaps/stock_book_yellow.png
new file mode 100644
index 0000000..293c52c
Binary files /dev/null and b/libgnomeui/pixmaps/stock_book_yellow.png differ
diff --git a/libgnomeui/pixmaps/stock_bottom.png b/libgnomeui/pixmaps/stock_bottom.png
new file mode 100755
index 0000000..c0d2035
Binary files /dev/null and b/libgnomeui/pixmaps/stock_bottom.png differ
diff --git a/libgnomeui/pixmaps/stock_button_apply.png b/libgnomeui/pixmaps/stock_button_apply.png
new file mode 100644
index 0000000..58a64cf
Binary files /dev/null and b/libgnomeui/pixmaps/stock_button_apply.png differ
diff --git a/libgnomeui/pixmaps/stock_button_cancel.png b/libgnomeui/pixmaps/stock_button_cancel.png
new file mode 100644
index 0000000..2d7c194
Binary files /dev/null and b/libgnomeui/pixmaps/stock_button_cancel.png differ
diff --git a/libgnomeui/pixmaps/stock_button_close.png b/libgnomeui/pixmaps/stock_button_close.png
new file mode 100644
index 0000000..b900bdf
Binary files /dev/null and b/libgnomeui/pixmaps/stock_button_close.png differ
diff --git a/libgnomeui/pixmaps/stock_button_no.png b/libgnomeui/pixmaps/stock_button_no.png
new file mode 100644
index 0000000..6478554
Binary files /dev/null and b/libgnomeui/pixmaps/stock_button_no.png differ
diff --git a/libgnomeui/pixmaps/stock_button_ok.png b/libgnomeui/pixmaps/stock_button_ok.png
new file mode 100644
index 0000000..f1c3375
Binary files /dev/null and b/libgnomeui/pixmaps/stock_button_ok.png differ
diff --git a/libgnomeui/pixmaps/stock_button_yes.png b/libgnomeui/pixmaps/stock_button_yes.png
new file mode 100644
index 0000000..e061e7f
Binary files /dev/null and b/libgnomeui/pixmaps/stock_button_yes.png differ
diff --git a/libgnomeui/pixmaps/stock_cdrom.png b/libgnomeui/pixmaps/stock_cdrom.png
new file mode 100644
index 0000000..a4f741d
Binary files /dev/null and b/libgnomeui/pixmaps/stock_cdrom.png differ
diff --git a/libgnomeui/pixmaps/stock_clear.png b/libgnomeui/pixmaps/stock_clear.png
new file mode 100644
index 0000000..96b6d57
Binary files /dev/null and b/libgnomeui/pixmaps/stock_clear.png differ
diff --git a/libgnomeui/pixmaps/stock_close.png b/libgnomeui/pixmaps/stock_close.png
new file mode 100644
index 0000000..4338bdc
Binary files /dev/null and b/libgnomeui/pixmaps/stock_close.png differ
diff --git a/libgnomeui/pixmaps/stock_colorselector.png b/libgnomeui/pixmaps/stock_colorselector.png
new file mode 100644
index 0000000..2876ff2
Binary files /dev/null and b/libgnomeui/pixmaps/stock_colorselector.png differ
diff --git a/libgnomeui/pixmaps/stock_convert.png b/libgnomeui/pixmaps/stock_convert.png
new file mode 100644
index 0000000..e81e11d
Binary files /dev/null and b/libgnomeui/pixmaps/stock_convert.png differ
diff --git a/libgnomeui/pixmaps/stock_copy.png b/libgnomeui/pixmaps/stock_copy.png
new file mode 100644
index 0000000..c00e9d4
Binary files /dev/null and b/libgnomeui/pixmaps/stock_copy.png differ
diff --git a/libgnomeui/pixmaps/stock_cut.png b/libgnomeui/pixmaps/stock_cut.png
new file mode 100644
index 0000000..ae8c7ed
Binary files /dev/null and b/libgnomeui/pixmaps/stock_cut.png differ
diff --git a/libgnomeui/pixmaps/stock_down_arrow.png b/libgnomeui/pixmaps/stock_down_arrow.png
new file mode 100755
index 0000000..f181a71
Binary files /dev/null and b/libgnomeui/pixmaps/stock_down_arrow.png differ
diff --git a/libgnomeui/pixmaps/stock_exec.png b/libgnomeui/pixmaps/stock_exec.png
new file mode 100755
index 0000000..62cb297
Binary files /dev/null and b/libgnomeui/pixmaps/stock_exec.png differ
diff --git a/libgnomeui/pixmaps/stock_exit.png b/libgnomeui/pixmaps/stock_exit.png
new file mode 100644
index 0000000..34cccc3
Binary files /dev/null and b/libgnomeui/pixmaps/stock_exit.png differ
diff --git a/libgnomeui/pixmaps/stock_first.png b/libgnomeui/pixmaps/stock_first.png
new file mode 100644
index 0000000..af9ae0c
Binary files /dev/null and b/libgnomeui/pixmaps/stock_first.png differ
diff --git a/libgnomeui/pixmaps/stock_font.png b/libgnomeui/pixmaps/stock_font.png
new file mode 100644
index 0000000..de98dc1
Binary files /dev/null and b/libgnomeui/pixmaps/stock_font.png differ
diff --git a/libgnomeui/pixmaps/stock_help.png b/libgnomeui/pixmaps/stock_help.png
new file mode 100644
index 0000000..2836a0f
Binary files /dev/null and b/libgnomeui/pixmaps/stock_help.png differ
diff --git a/libgnomeui/pixmaps/stock_home.png b/libgnomeui/pixmaps/stock_home.png
new file mode 100644
index 0000000..0b2e9e6
Binary files /dev/null and b/libgnomeui/pixmaps/stock_home.png differ
diff --git a/libgnomeui/pixmaps/stock_index.png b/libgnomeui/pixmaps/stock_index.png
new file mode 100644
index 0000000..1fd0f29
Binary files /dev/null and b/libgnomeui/pixmaps/stock_index.png differ
diff --git a/libgnomeui/pixmaps/stock_jump_to.png b/libgnomeui/pixmaps/stock_jump_to.png
new file mode 100644
index 0000000..880cf9a
Binary files /dev/null and b/libgnomeui/pixmaps/stock_jump_to.png differ
diff --git a/libgnomeui/pixmaps/stock_last.png b/libgnomeui/pixmaps/stock_last.png
new file mode 100644
index 0000000..9bd28bf
Binary files /dev/null and b/libgnomeui/pixmaps/stock_last.png differ
diff --git a/libgnomeui/pixmaps/stock_left_arrow.png b/libgnomeui/pixmaps/stock_left_arrow.png
new file mode 100644
index 0000000..5a1fe92
Binary files /dev/null and b/libgnomeui/pixmaps/stock_left_arrow.png differ
diff --git a/libgnomeui/pixmaps/stock_line_in.png b/libgnomeui/pixmaps/stock_line_in.png
new file mode 100644
index 0000000..8bbae95
Binary files /dev/null and b/libgnomeui/pixmaps/stock_line_in.png differ
diff --git a/libgnomeui/pixmaps/stock_mail.png b/libgnomeui/pixmaps/stock_mail.png
new file mode 100644
index 0000000..670898e
Binary files /dev/null and b/libgnomeui/pixmaps/stock_mail.png differ
diff --git a/libgnomeui/pixmaps/stock_mail_compose.png b/libgnomeui/pixmaps/stock_mail_compose.png
new file mode 100644
index 0000000..225c0e0
Binary files /dev/null and b/libgnomeui/pixmaps/stock_mail_compose.png differ
diff --git a/libgnomeui/pixmaps/stock_mail_forward.png b/libgnomeui/pixmaps/stock_mail_forward.png
new file mode 100644
index 0000000..62fbe9c
Binary files /dev/null and b/libgnomeui/pixmaps/stock_mail_forward.png differ
diff --git a/libgnomeui/pixmaps/stock_mail_receive.png b/libgnomeui/pixmaps/stock_mail_receive.png
new file mode 100644
index 0000000..405eab7
Binary files /dev/null and b/libgnomeui/pixmaps/stock_mail_receive.png differ
diff --git a/libgnomeui/pixmaps/stock_mail_reply.png b/libgnomeui/pixmaps/stock_mail_reply.png
new file mode 100644
index 0000000..02896e0
Binary files /dev/null and b/libgnomeui/pixmaps/stock_mail_reply.png differ
diff --git a/libgnomeui/pixmaps/stock_mail_send.png b/libgnomeui/pixmaps/stock_mail_send.png
new file mode 100644
index 0000000..f0c5b56
Binary files /dev/null and b/libgnomeui/pixmaps/stock_mail_send.png differ
diff --git a/libgnomeui/pixmaps/stock_menu_about.png b/libgnomeui/pixmaps/stock_menu_about.png
new file mode 100644
index 0000000..2795bdc
Binary files /dev/null and b/libgnomeui/pixmaps/stock_menu_about.png differ
diff --git a/libgnomeui/pixmaps/stock_menu_blank.png b/libgnomeui/pixmaps/stock_menu_blank.png
new file mode 100644
index 0000000..78560c1
Binary files /dev/null and b/libgnomeui/pixmaps/stock_menu_blank.png differ
diff --git a/libgnomeui/pixmaps/stock_mic.png b/libgnomeui/pixmaps/stock_mic.png
new file mode 100644
index 0000000..5b1e3e3
Binary files /dev/null and b/libgnomeui/pixmaps/stock_mic.png differ
diff --git a/libgnomeui/pixmaps/stock_midi.png b/libgnomeui/pixmaps/stock_midi.png
new file mode 100644
index 0000000..8257d5a
Binary files /dev/null and b/libgnomeui/pixmaps/stock_midi.png differ
diff --git a/libgnomeui/pixmaps/stock_multiple_file.png b/libgnomeui/pixmaps/stock_multiple_file.png
new file mode 100644
index 0000000..a4c21ec
Binary files /dev/null and b/libgnomeui/pixmaps/stock_multiple_file.png differ
diff --git a/libgnomeui/pixmaps/stock_new.png b/libgnomeui/pixmaps/stock_new.png
new file mode 100644
index 0000000..538e9ac
Binary files /dev/null and b/libgnomeui/pixmaps/stock_new.png differ
diff --git a/libgnomeui/pixmaps/stock_not.png b/libgnomeui/pixmaps/stock_not.png
new file mode 100644
index 0000000..b06b36c
Binary files /dev/null and b/libgnomeui/pixmaps/stock_not.png differ
diff --git a/libgnomeui/pixmaps/stock_open.png b/libgnomeui/pixmaps/stock_open.png
new file mode 100644
index 0000000..e966ad7
Binary files /dev/null and b/libgnomeui/pixmaps/stock_open.png differ
diff --git a/libgnomeui/pixmaps/stock_paste.png b/libgnomeui/pixmaps/stock_paste.png
new file mode 100644
index 0000000..1f1b94a
Binary files /dev/null and b/libgnomeui/pixmaps/stock_paste.png differ
diff --git a/libgnomeui/pixmaps/stock_preferences.png b/libgnomeui/pixmaps/stock_preferences.png
new file mode 100644
index 0000000..82b3eef
Binary files /dev/null and b/libgnomeui/pixmaps/stock_preferences.png differ
diff --git a/libgnomeui/pixmaps/stock_print.png b/libgnomeui/pixmaps/stock_print.png
new file mode 100644
index 0000000..5213dff
Binary files /dev/null and b/libgnomeui/pixmaps/stock_print.png differ
diff --git a/libgnomeui/pixmaps/stock_properties.png b/libgnomeui/pixmaps/stock_properties.png
new file mode 100644
index 0000000..5b638a6
Binary files /dev/null and b/libgnomeui/pixmaps/stock_properties.png differ
diff --git a/libgnomeui/pixmaps/stock_redo.png b/libgnomeui/pixmaps/stock_redo.png
new file mode 100644
index 0000000..e359590
Binary files /dev/null and b/libgnomeui/pixmaps/stock_redo.png differ
diff --git a/libgnomeui/pixmaps/stock_refresh.png b/libgnomeui/pixmaps/stock_refresh.png
new file mode 100644
index 0000000..81951b6
Binary files /dev/null and b/libgnomeui/pixmaps/stock_refresh.png differ
diff --git a/libgnomeui/pixmaps/stock_remove.png b/libgnomeui/pixmaps/stock_remove.png
new file mode 100644
index 0000000..23cd2d2
Binary files /dev/null and b/libgnomeui/pixmaps/stock_remove.png differ
diff --git a/libgnomeui/pixmaps/stock_revert.png b/libgnomeui/pixmaps/stock_revert.png
new file mode 100644
index 0000000..9ef47a8
Binary files /dev/null and b/libgnomeui/pixmaps/stock_revert.png differ
diff --git a/libgnomeui/pixmaps/stock_right_arrow.png b/libgnomeui/pixmaps/stock_right_arrow.png
new file mode 100644
index 0000000..d16216c
Binary files /dev/null and b/libgnomeui/pixmaps/stock_right_arrow.png differ
diff --git a/libgnomeui/pixmaps/stock_save.png b/libgnomeui/pixmaps/stock_save.png
new file mode 100644
index 0000000..2281b92
Binary files /dev/null and b/libgnomeui/pixmaps/stock_save.png differ
diff --git a/libgnomeui/pixmaps/stock_save_as.png b/libgnomeui/pixmaps/stock_save_as.png
new file mode 100644
index 0000000..13cc1bf
Binary files /dev/null and b/libgnomeui/pixmaps/stock_save_as.png differ
diff --git a/libgnomeui/pixmaps/stock_scores.png b/libgnomeui/pixmaps/stock_scores.png
new file mode 100644
index 0000000..a3a7da0
Binary files /dev/null and b/libgnomeui/pixmaps/stock_scores.png differ
diff --git a/libgnomeui/pixmaps/stock_search.png b/libgnomeui/pixmaps/stock_search.png
new file mode 100644
index 0000000..db20813
Binary files /dev/null and b/libgnomeui/pixmaps/stock_search.png differ
diff --git a/libgnomeui/pixmaps/stock_search_replace.png b/libgnomeui/pixmaps/stock_search_replace.png
new file mode 100644
index 0000000..895201d
Binary files /dev/null and b/libgnomeui/pixmaps/stock_search_replace.png differ
diff --git a/libgnomeui/pixmaps/stock_spellcheck.png b/libgnomeui/pixmaps/stock_spellcheck.png
new file mode 100644
index 0000000..8093dcd
Binary files /dev/null and b/libgnomeui/pixmaps/stock_spellcheck.png differ
diff --git a/libgnomeui/pixmaps/stock_stop.png b/libgnomeui/pixmaps/stock_stop.png
new file mode 100644
index 0000000..b092118
Binary files /dev/null and b/libgnomeui/pixmaps/stock_stop.png differ
diff --git a/libgnomeui/pixmaps/stock_table_borders.png b/libgnomeui/pixmaps/stock_table_borders.png
new file mode 100644
index 0000000..080c2e7
Binary files /dev/null and b/libgnomeui/pixmaps/stock_table_borders.png differ
diff --git a/libgnomeui/pixmaps/stock_table_fill.png b/libgnomeui/pixmaps/stock_table_fill.png
new file mode 100644
index 0000000..e0f9c98
Binary files /dev/null and b/libgnomeui/pixmaps/stock_table_fill.png differ
diff --git a/libgnomeui/pixmaps/stock_text_bold.png b/libgnomeui/pixmaps/stock_text_bold.png
new file mode 100644
index 0000000..1319deb
Binary files /dev/null and b/libgnomeui/pixmaps/stock_text_bold.png differ
diff --git a/libgnomeui/pixmaps/stock_text_bulleted_list.png b/libgnomeui/pixmaps/stock_text_bulleted_list.png
new file mode 100644
index 0000000..cc3d864
Binary files /dev/null and b/libgnomeui/pixmaps/stock_text_bulleted_list.png differ
diff --git a/libgnomeui/pixmaps/stock_text_indent.png b/libgnomeui/pixmaps/stock_text_indent.png
new file mode 100644
index 0000000..1dd91f9
Binary files /dev/null and b/libgnomeui/pixmaps/stock_text_indent.png differ
diff --git a/libgnomeui/pixmaps/stock_text_italic.png b/libgnomeui/pixmaps/stock_text_italic.png
new file mode 100644
index 0000000..2712337
Binary files /dev/null and b/libgnomeui/pixmaps/stock_text_italic.png differ
diff --git a/libgnomeui/pixmaps/stock_text_numbered_list.png b/libgnomeui/pixmaps/stock_text_numbered_list.png
new file mode 100644
index 0000000..2ce904c
Binary files /dev/null and b/libgnomeui/pixmaps/stock_text_numbered_list.png differ
diff --git a/libgnomeui/pixmaps/stock_text_strikeout.png b/libgnomeui/pixmaps/stock_text_strikeout.png
new file mode 100644
index 0000000..9a9a373
Binary files /dev/null and b/libgnomeui/pixmaps/stock_text_strikeout.png differ
diff --git a/libgnomeui/pixmaps/stock_text_underline.png b/libgnomeui/pixmaps/stock_text_underline.png
new file mode 100644
index 0000000..35f5c1f
Binary files /dev/null and b/libgnomeui/pixmaps/stock_text_underline.png differ
diff --git a/libgnomeui/pixmaps/stock_text_unindent.png b/libgnomeui/pixmaps/stock_text_unindent.png
new file mode 100644
index 0000000..b6a85bc
Binary files /dev/null and b/libgnomeui/pixmaps/stock_text_unindent.png differ
diff --git a/libgnomeui/pixmaps/stock_timer.png b/libgnomeui/pixmaps/stock_timer.png
new file mode 100644
index 0000000..f7ffe8b
Binary files /dev/null and b/libgnomeui/pixmaps/stock_timer.png differ
diff --git a/libgnomeui/pixmaps/stock_timer_stopped.png b/libgnomeui/pixmaps/stock_timer_stopped.png
new file mode 100644
index 0000000..e0a8b3b
Binary files /dev/null and b/libgnomeui/pixmaps/stock_timer_stopped.png differ
diff --git a/libgnomeui/pixmaps/stock_top.png b/libgnomeui/pixmaps/stock_top.png
new file mode 100755
index 0000000..7ebb6c8
Binary files /dev/null and b/libgnomeui/pixmaps/stock_top.png differ
diff --git a/libgnomeui/pixmaps/stock_trash.png b/libgnomeui/pixmaps/stock_trash.png
new file mode 100644
index 0000000..1c70b72
Binary files /dev/null and b/libgnomeui/pixmaps/stock_trash.png differ
diff --git a/libgnomeui/pixmaps/stock_trash_full.png b/libgnomeui/pixmaps/stock_trash_full.png
new file mode 100644
index 0000000..6e2f08c
Binary files /dev/null and b/libgnomeui/pixmaps/stock_trash_full.png differ
diff --git a/libgnomeui/pixmaps/stock_undelete.png b/libgnomeui/pixmaps/stock_undelete.png
new file mode 100644
index 0000000..faff910
Binary files /dev/null and b/libgnomeui/pixmaps/stock_undelete.png differ
diff --git a/libgnomeui/pixmaps/stock_undo.png b/libgnomeui/pixmaps/stock_undo.png
new file mode 100644
index 0000000..601a1fa
Binary files /dev/null and b/libgnomeui/pixmaps/stock_undo.png differ
diff --git a/libgnomeui/pixmaps/stock_up_arrow.png b/libgnomeui/pixmaps/stock_up_arrow.png
new file mode 100755
index 0000000..4bb674b
Binary files /dev/null and b/libgnomeui/pixmaps/stock_up_arrow.png differ
diff --git a/libgnomeui/pixmaps/stock_volume.png b/libgnomeui/pixmaps/stock_volume.png
new file mode 100644
index 0000000..64e4731
Binary files /dev/null and b/libgnomeui/pixmaps/stock_volume.png differ
diff --git a/libgnomeui/portrait.xpm b/libgnomeui/portrait.xpm
new file mode 100644
index 0000000..cc3a6b9
--- /dev/null
+++ b/libgnomeui/portrait.xpm
@@ -0,0 +1,46 @@
+/* XPM */
+static char * portrait_xpm[] = {
+"30 40 3 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"      ......................  ",
+"     ..++++++++++++++++++++.  ",
+"    ...++++++++++++++++++++...",
+"   ....++++++++++++++++++++...",
+"  .....++++++++++++++++++++...",
+" ......++++++++++++++++++++...",
+".......++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+".++++++++++++++++++++++++++...",
+"..............................",
+"  ............................",
+"  ............................"};
diff --git a/libgnomeui/wap-textfu.c b/libgnomeui/wap-textfu.c
new file mode 100644
index 0000000..936144e
--- /dev/null
+++ b/libgnomeui/wap-textfu.c
@@ -0,0 +1,3625 @@
+/* wap-textfu.c
+ * Copyright (C) 2000 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+*/
+/* Written by Elliot Lee <sopwith redhat com>. This code is pretty aweful, but you should see my other code. */
+
+#define BULLET_WIDTH 20
+#define BULLET_HEIGHT 20
+#define BASIC_INDENT 25
+#define SMALL_FONT_SIZE 12
+#define NORMAL_FONT_SIZE 18
+#define LARGE_FONT_SIZE 24
+#define PARA_SPACE_AFTER 12
+#define BULLET_ALIGNMENT 1.0
+#define MAX_SCROLL_AMT 20
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <gobject/gobject.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gdk-pixbuf/gdk-pixbuf-loader.h>
+#include <gdk/gdkkeysyms.h>
+#include "wap-textfu.h"
+
+#ifndef g_alloca
+#define g_alloca alloca
+#endif
+
+#define my_isspace(x) (isspace(x) || (x) == '\r' || (x) == '\n')
+#define LINE_SPACING 4
+
+static const gchar wap_unknown_char_utf8[] = { 0xEF, 0xBF, 0xBD, '\0' };
+static void wap_textfu_cleanup_page(WapTextFu *textfu);
+/*  static void xml_ctxt_done(WapStreamHandle handle, WapStreamStatus status, gpointer user_data); */
+static void tag_option_event_selected(GtkWidget *list_item, GtkObject *textfu);
+
+struct _PangoAttrList
+{
+  guint ref_count;
+  GSList *attributes;
+  GSList *attributes_tail;
+};
+
+static void
+PC(PangoAttrList *attrs)
+{
+  GSList *ltmp;
+
+  for(ltmp = attrs->attributes; ltmp; ltmp = ltmp->next)
+    {
+      PangoAttribute *attr = ltmp->data;
+
+      g_assert(attr->start_index < attr->end_index);
+    }
+}
+
+static void
+dump_attrs(PangoAttrList *attrs) G_GNUC_UNUSED;
+static void
+dump_attrs(PangoAttrList *attrs)
+{
+  GSList *ltmp;
+  const char *attr_names[] = {
+    "PANGO_ATTR_LANG",
+    "PANGO_ATTR_FAMILY",
+    "PANGO_ATTR_STYLE",
+    "PANGO_ATTR_WEIGHT",
+    "PANGO_ATTR_VARIANT",
+    "PANGO_ATTR_STRETCH",
+    "PANGO_ATTR_SIZE",
+    "PANGO_ATTR_FONT_DESC",
+    "PANGO_ATTR_FOREGROUND",
+    "PANGO_ATTR_BACKGROUND",
+    "PANGO_ATTR_UNDERLINE",
+    "PANGO_ATTR_STRIKETHROUGH",
+    "PANGO_ATTR_RISE",
+    "PANGO_ATTR_SHAPE"
+  };
+
+  g_print("Attrs for %p\n", attrs);
+  for(ltmp = attrs->attributes; ltmp; ltmp = ltmp->next)
+    {
+      PangoAttribute *attr = ltmp->data;
+
+      g_print("%d (%s): %d-%d\n",
+	      attr->klass->type,
+	      (attr->klass->type<(sizeof(attr_names)/sizeof(attr_names[0])))?attr_names[attr->klass->type]:"?",
+	      attr->start_index, attr->end_index);
+    }
+}
+
+typedef struct {
+  WapTextFuTagHandler handler;
+  guint16 tag_id;
+
+  char tag_name[1];
+} TagRegistration;
+
+enum {
+  LINK_FOLLOWED,
+  ANCHOR_FOLLOWED,
+  PREV_FOLLOWED,
+  LOAD_DONE,
+  LOAD_ERROR,
+  ACTIVATE_CARD,
+  DEACTIVATE_CARD,
+  LAST_SIGNAL
+};
+
+static void wap_textfu_init		(WapTextFu		 *textfu);
+static void wap_textfu_class_init	(WapTextFuClass	 *klass);
+static void wap_textfu_realize            (GtkWidget      *widget);
+static void wap_textfu_unrealize          (GtkWidget      *widget);
+static void wap_textfu_map                (GtkWidget      *widget);
+static void wap_textfu_unrealize          (GtkWidget      *widget);
+static void wap_textfu_size_request       (GtkWidget      *widget,
+					     GtkRequisition *requisition);
+static void wap_textfu_size_allocate      (GtkWidget      *widget,
+					     GtkAllocation  *allocation);
+static void wap_textfu_draw               (GtkWidget      *widget, 
+					     GdkRectangle   *area);
+static gint wap_textfu_expose             (GtkWidget      *widget, 
+					     GdkEventExpose *event);
+static gint wap_textfu_button_release_event(GtkWidget *widget, GdkEventButton *event);
+static gint wap_textfu_motion_notify_event(GtkWidget *widget, GdkEventMotion *event);
+static gint wap_textfu_key_press_event(GtkWidget *widget, GdkEventKey *event);
+static void wap_textfu_set_scroll_adjustments(GtkLayout      *layout,
+					      GtkAdjustment  *hadjustment,
+					      GtkAdjustment  *vadjustment);
+
+static GtkWidget *wap_pixmap_new_from_uri(WapTextFu *textfu, char *uri, const char *alt_text);
+
+static GtkWidgetClass *parent_class = NULL;
+static guint textfu_signals[LAST_SIGNAL] = { 0 };
+
+typedef struct {
+  PangoAttribute attr;
+  WapAnchorInfo *wai;
+
+  /* Title, accessnum, etc. are stored elsewhere */
+  PangoAttribute *fg_color_attr, *bg_color_attr; /* So we can change the color when the link is clicked on */
+} LinkURLAttr;
+
+static PangoAttribute *link_url_attr_new(WapAnchorInfo *wai);
+
+static PangoAttribute *link_url_attr_copy(const PangoAttribute *attr)
+{
+  LinkURLAttr *r, *in = (LinkURLAttr *)attr;
+  PangoAttribute *retval = link_url_attr_new(in->wai);
+
+  r = (LinkURLAttr *)retval;
+  *r = *in;
+
+  return retval;
+}
+
+static void link_url_attr_destroy(PangoAttribute *attr)
+{
+  g_free(attr);
+}
+
+static gboolean
+link_url_attr_compare(const PangoAttribute *attr1, const PangoAttribute *attr2)
+{
+  LinkURLAttr *ua1 = (LinkURLAttr *)attr1, *ua2 = (LinkURLAttr *)attr2;
+
+  return ua1->wai == ua2->wai;
+}
+
+static PangoAttrClass link_url_attr_class = {
+  0,
+  link_url_attr_copy,
+  link_url_attr_destroy,
+  link_url_attr_compare
+};
+
+static PangoAttribute *link_url_attr_new(WapAnchorInfo *wai)
+{
+  LinkURLAttr *retval = g_new0(LinkURLAttr, 1);
+
+  retval->attr.klass = &link_url_attr_class;
+  retval->wai = wai;
+
+  return (PangoAttribute *)retval;
+}
+
+typedef struct {
+  PangoAttribute *shape_attr;
+  GtkWidget *widget;
+  gint bullet_level; /* If widget is NULL */
+  double alignment;
+} PlacedItem;
+
+static void
+wap_text_style_free(WapTextStyle *ts)
+{
+  g_free(ts->font_family);
+  g_free(ts);
+}
+
+static void
+populate_attr_list_2(WapTextFu *textfu, WapTextStyle *ts, int end_offset,
+		     int link_start, int font_family_start, int bold_start, int italic_start,
+		     int underline_start, int fg_color_start, int bg_color_start, int font_size_start,
+		     gboolean color_from_link)
+{
+  LinkURLAttr *link_attr = NULL;
+  PangoAttribute *attr;
+
+  if(!textfu->cur_para)
+    return;
+
+  if(ts->wai)
+    {
+      attr = link_url_attr_new(ts->wai);
+      attr->start_index = link_start;
+      attr->end_index = end_offset;
+      pango_attr_list_insert(textfu->cur_para->attrs, attr);
+      link_attr = (LinkURLAttr *)attr;
+      ts->wai->attr = attr;
+    }
+
+  if(ts->font_family)
+    {
+      attr = pango_attr_family_new(ts->font_family);
+      attr->start_index = font_family_start;
+      attr->end_index = end_offset;
+      pango_attr_list_insert(textfu->cur_para->attrs, attr);
+    }
+
+  if(ts->bold != TEXTFU_UNKNOWN)
+    {
+      attr = pango_attr_weight_new((ts->bold == TEXTFU_TRUE)?PANGO_WEIGHT_BOLD:PANGO_WEIGHT_NORMAL);
+      attr->start_index = bold_start;
+      attr->end_index = end_offset;
+      pango_attr_list_insert(textfu->cur_para->attrs, attr);
+    }
+
+  if(ts->italic != TEXTFU_UNKNOWN)
+    {
+      attr = pango_attr_style_new((ts->italic == TEXTFU_TRUE)?PANGO_STYLE_ITALIC:PANGO_STYLE_NORMAL);
+      attr->start_index = italic_start;
+      attr->end_index = end_offset;
+      pango_attr_list_insert(textfu->cur_para->attrs, attr);
+    }
+
+  if(ts->underline != TEXTFU_UNKNOWN)
+    {
+      attr = pango_attr_underline_new((ts->underline == TEXTFU_TRUE)?PANGO_UNDERLINE_SINGLE:PANGO_UNDERLINE_NONE);
+      attr->start_index = underline_start;
+      attr->end_index = end_offset;
+      pango_attr_list_insert(textfu->cur_para->attrs, attr);
+    }
+
+  if(ts->fg_color_set)
+    {
+      attr = pango_attr_foreground_new(ts->fg_color.red, ts->fg_color.green, ts->fg_color.blue);
+      g_assert(fg_color_start < end_offset);
+      attr->start_index = fg_color_start;
+      attr->end_index = end_offset;
+      pango_attr_list_insert(textfu->cur_para->attrs, attr);
+
+      if(color_from_link)
+	link_attr->fg_color_attr = attr;
+    }
+
+  if(ts->bg_color_set)
+    {
+      attr = pango_attr_background_new(ts->bg_color.red, ts->bg_color.green, ts->bg_color.blue);
+      g_assert(bg_color_start < end_offset);
+      attr->start_index = bg_color_start;
+      attr->end_index = end_offset;
+      pango_attr_list_insert(textfu->cur_para->attrs, attr);
+
+      if(color_from_link)
+	link_attr->bg_color_attr = attr;
+    }
+
+  if(ts->font_size_set)
+    {
+      attr = pango_attr_size_new(ts->font_size * PANGO_SCALE);
+      attr->start_index = font_size_start;
+      attr->end_index = end_offset;
+      pango_attr_list_insert(textfu->cur_para->attrs, attr);
+    }
+}
+
+static void
+populate_attr_list(WapTextFu *textfu, WapTextStyle *ts, gboolean color_from_link)
+{
+  int real_offset = MAX(ts->start_offset, 0);
+
+  populate_attr_list_2(textfu, ts, textfu->tmp_text->len,
+		       real_offset,
+		       real_offset,
+		       real_offset,
+		       real_offset,
+		       real_offset,
+		       real_offset,
+		       real_offset,
+		       real_offset,
+		       color_from_link);
+}
+
+static WapParagraphInfo *
+push_pango_para(WapTextFu *textfu)
+{
+  GList *ltmp;
+  WapTextStyle result;
+  PangoAttribute *attr;
+  int font_family_start=0, font_size_start=0, bold_start=0, italic_start=0, underline_start=0, bg_color_start=0, fg_color_start=0, link_start=0;
+  int end_offset;
+  WapParaStyle *ps;
+  gboolean got_ul, got_ol;
+  int bullet_level = 0, bullet_num = 0;
+  int start_offset = 0;
+  int first_indent = 0;
+  gboolean color_from_link = FALSE;
+
+  if(!textfu->cur_para)
+    return NULL; /* nothing to do! */
+
+  memset(&result, 0, sizeof(result));
+
+  g_assert(textfu->cur_card->para_style_stack);
+  ps = textfu->cur_card->para_style_stack->data;
+  for(ltmp = textfu->cur_card->para_style_stack, got_ul = got_ol = FALSE; ltmp && !(got_ul || got_ol); ltmp = ltmp->next)
+    {
+      WapParaStyle *pstmp = ltmp->data;
+
+      /* Eek, hardcoding tags in */
+      if(pstmp->ul_container)
+	got_ul = TRUE;
+      else if(pstmp->ol_container)
+	got_ol = TRUE;
+      bullet_level = pstmp->bullet_level;
+      bullet_num = pstmp->bullet_num;
+    }
+  if(!ltmp)
+    bullet_level = bullet_num = 0;
+
+  if(got_ol)
+    {
+      char cbuf[8];
+
+      switch(bullet_level)
+	{
+	case 0:
+	  g_assert_not_reached();
+	  break;
+	case 1:
+	  g_snprintf(cbuf, sizeof(cbuf), "%d. ", bullet_num + 1);
+	  break;
+	case 2:
+	  g_snprintf(cbuf, sizeof(cbuf), "(%c) ", 'a' + (bullet_num % 26));
+	  break;
+	default:
+	  g_snprintf(cbuf, sizeof(cbuf), "(%d) ", bullet_num + 1);
+	  break;
+	}
+
+      start_offset = strlen(cbuf);
+      g_string_prepend_len(textfu->tmp_text, cbuf, start_offset);
+      first_indent = -BULLET_WIDTH * PANGO_SCALE;
+    }
+  else if(got_ul)
+    start_offset = strlen(wap_unknown_char_utf8);
+
+#define CALC_OFFSET() (ts->start_offset>=0)?(ts->start_offset+start_offset):0
+
+  result.bold = result.italic = result.underline = TEXTFU_UNKNOWN;
+
+  for(ltmp = g_list_last(textfu->cur_card->text_style_stack); ltmp; ltmp = ltmp->prev)
+    {
+      WapTextStyle *ts = ltmp->data;
+
+      if(ts->wai)
+	{
+	  result.wai = ts->wai;
+	  link_start = CALC_OFFSET();
+	}
+
+      if(ts->font_family)
+	{
+	  result.font_family = ts->font_family;
+	  font_family_start = CALC_OFFSET();
+	}
+
+      if(ts->bold != TEXTFU_UNKNOWN)
+	{
+	  bold_start = CALC_OFFSET();
+	  result.bold = ts->bold;
+	}
+      if(ts->italic != TEXTFU_UNKNOWN)
+	{
+	  result.italic = ts->italic;
+	  italic_start = CALC_OFFSET();
+	}
+      if(ts->underline != TEXTFU_UNKNOWN)
+	{
+	  result.underline = ts->underline;
+	  underline_start = CALC_OFFSET();
+	}
+      if(ts->fg_color_set)
+	{
+	  result.fg_color_set = TRUE;
+	  result.fg_color = ts->fg_color;
+	  fg_color_start = CALC_OFFSET();
+	  color_from_link = ts->wai?TRUE:FALSE;
+	}
+      if(ts->bg_color_set)
+	{
+	  result.bg_color_set = TRUE;
+	  result.bg_color = ts->bg_color;
+	  bg_color_start = CALC_OFFSET();
+	  color_from_link = ts->wai?TRUE:FALSE;
+	}
+      if(ts->font_size_set)
+	{
+	  result.font_size_set = TRUE;
+	  result.font_size = ts->font_size;
+	  font_size_start = CALC_OFFSET();
+	}
+
+      ts->start_offset = -1; /* Indicates that it is a carryover from previous paragraph */
+    }
+
+  end_offset = textfu->tmp_text->len;
+
+  /* Now we have figured out what the text is supposed to look like, finish creating 'cur_attrs' */
+
+  populate_attr_list_2(textfu, &result, end_offset, link_start,
+		       font_family_start, bold_start, italic_start, underline_start,
+		       fg_color_start, bg_color_start, font_size_start, color_from_link);
+  PC(textfu->cur_para->attrs);
+
+  if(got_ul)
+    {
+      GList *placed_items = textfu->cur_para->placed_items;
+      PlacedItem *pi;
+      PangoRectangle bullet_rect;
+
+      pi = g_new0(PlacedItem, 1);
+
+      bullet_rect.x = 0;
+      bullet_rect.y = -(BULLET_ALIGNMENT * BULLET_HEIGHT) * PANGO_SCALE;
+      bullet_rect.width = BULLET_WIDTH * PANGO_SCALE;
+      bullet_rect.height = BULLET_HEIGHT * PANGO_SCALE;
+      pi->alignment = BULLET_ALIGNMENT;
+
+      pi->shape_attr = attr = pango_attr_shape_new(&bullet_rect, &bullet_rect);
+      pi->shape_attr->start_index = 0;
+      pi->shape_attr->end_index = start_offset;
+      pi->bullet_level = bullet_level;
+      g_string_prepend_len(textfu->tmp_text, wap_unknown_char_utf8, start_offset);
+
+      placed_items = g_list_prepend(placed_items, pi);
+      textfu->cur_para->placed_items = placed_items;
+
+      pango_attr_list_insert(textfu->cur_para->attrs, attr);
+      first_indent = -BULLET_WIDTH * PANGO_SCALE;
+    }
+
+  pango_layout_set_indent(textfu->cur_para->layout, first_indent);
+  pango_layout_set_text(textfu->cur_para->layout, textfu->tmp_text->str, textfu->tmp_text->len);
+
+  pango_layout_set_attributes(textfu->cur_para->layout, textfu->cur_para->attrs);
+  pango_attr_list_unref(textfu->cur_para->attrs);
+  pango_layout_set_alignment(textfu->cur_para->layout, ps->alignment);
+  textfu->cur_para->left_indent = ps->left_indent;
+  textfu->cur_para->right_indent = ps->right_indent;
+  textfu->cur_para->space_after = ps->space_after;
+
+  textfu->cur_card->paragraphs = g_list_append(textfu->cur_card->paragraphs, textfu->cur_para);
+  textfu->cur_para = NULL;
+  g_string_truncate(textfu->tmp_text, 0);
+
+  return textfu->cur_para;
+}
+
+static WapTextStyle *
+style_change(WapTextFu *textfu, const char *tagname, gboolean begin_new, gboolean ascend_tree, gboolean is_link)
+{
+  WapTextStyle *retval = NULL, *old = NULL;
+  GList *cur;
+
+  cur = textfu->cur_card->text_style_stack;
+  if(cur)
+    do {
+      old = cur->data;
+      if(!strcasecmp(old->style.tag, tagname))
+	break;
+
+      cur = ascend_tree?cur->next:NULL;
+    } while(cur);
+
+  if(!cur)
+    old = NULL;
+
+  if(old)
+    {
+      /* Pump it into the attribute list */
+      populate_attr_list(textfu, old, is_link);
+
+      textfu->cur_card->text_style_stack = g_list_remove_link(textfu->cur_card->text_style_stack, cur);
+      g_list_free_1(cur);
+    }
+
+  if(begin_new)
+    {
+      retval = g_new0(WapTextStyle, 1);
+      strcpy(retval->style.tag, tagname);
+
+      retval->start_offset = textfu->tmp_text->len;
+
+      if(old && old->replace_prev)
+	{
+	  retval->wai = old->wai;
+	  retval->font_family = g_strdup(old->font_family);
+	  retval->font_size = old->font_size;
+	  retval->bg_color = old->bg_color;
+	  retval->fg_color = old->fg_color;
+	  retval->bold = old->bold;
+	  retval->italic = old->italic;
+	  retval->underline = old->underline;
+	  retval->fg_color_set = old->fg_color_set;
+	  retval->bg_color_set = old->bg_color_set;
+	  retval->font_size_set = old->font_size_set;
+	  retval->replace_prev = old->replace_prev;
+	}
+      else
+	{
+	  retval->bold = TEXTFU_UNKNOWN;
+	  retval->italic = TEXTFU_UNKNOWN;
+	  retval->underline = TEXTFU_UNKNOWN;
+	}
+
+      textfu->cur_card->text_style_stack = g_list_prepend(textfu->cur_card->text_style_stack, retval);
+    }
+
+  g_free(old);
+
+  return retval;
+}
+
+/* Called when we parse some displayable content that might require setting up things for a paragraph */
+static void
+initiate_para(WapTextFu *textfu)
+{
+  if(!textfu->cur_para)
+    {
+      textfu->cur_para = g_new0(WapParagraphInfo, 1);
+      textfu->cur_para->layout = pango_layout_new(textfu->pango_ctx);
+      textfu->cur_para->attrs = pango_attr_list_new();
+    }
+}
+
+static WapParaStyle *
+paragraph_division(WapTextFu *textfu, const char *tagname, gboolean begin_new, gboolean ascend_tree)
+{
+  WapParaStyle *retval = NULL, *old = NULL;
+  GList *cur;
+
+  push_pango_para(textfu);
+
+  cur = textfu->cur_card->para_style_stack;
+  if(cur)
+    do {
+      old = cur->data;
+      if(!strcasecmp(old->style.tag, tagname))
+	break;
+
+      cur = ascend_tree?cur->next:NULL;
+    } while(cur);
+
+  if(!cur)
+    old = NULL;
+
+  if(old)
+    {
+      textfu->cur_card->para_style_stack = g_list_remove_link(textfu->cur_card->para_style_stack, cur);
+      g_list_free_1(cur);
+    }
+
+  if(begin_new)
+    {
+      retval = g_new0(WapParaStyle, 1);
+      strcpy(retval->style.tag, tagname);
+      if(old && old->replace_prev)
+	{
+	  retval->left_indent = old->left_indent;
+	  retval->right_indent = old->right_indent;
+	  retval->alignment = old->alignment;
+	  retval->replace_prev = old->replace_prev;
+	  retval->space_after = old->space_after;
+	  /* Don't copy bulleting info - should be zero'd unless explicitly set */
+	}
+      else
+	{
+	  if(textfu->cur_card->para_style_stack)
+	    {
+	      WapParaStyle *parent_ps;
+
+	      parent_ps = textfu->cur_card->para_style_stack->data;
+	      retval->left_indent = parent_ps->left_indent;
+	      retval->right_indent = parent_ps->right_indent;
+	      retval->space_after = parent_ps->space_after;
+	    }
+	  else
+	    {
+	      retval->left_indent = retval->right_indent = BASIC_INDENT;
+	      retval->space_after = PARA_SPACE_AFTER;
+	    }
+
+	  retval->alignment = PANGO_ALIGN_LEFT;
+	}
+
+      textfu->cur_card->para_style_stack = g_list_prepend(textfu->cur_card->para_style_stack, retval);
+    }
+
+  g_free(old);
+
+  return retval;
+}
+
+static gboolean
+toboolean(const char *string)
+{
+  if(string[0] == '1'
+     || tolower(string[0]) == 't'
+     || tolower(string[0]) == 'y')
+    return TRUE;
+
+  return FALSE;
+}
+
+static GList *
+parse_query_string(const char *str)
+{
+  char **pieces;
+  int j;
+  GList *retval = NULL;
+
+  pieces = g_strsplit(str, "&", -1);
+  for(j = 0; pieces[j]; j++)
+    {
+      char **vpieces;
+      vpieces = g_strsplit(pieces[j], "=", 2);
+
+      retval = g_list_prepend(retval, vpieces[1]);
+      retval = g_list_prepend(retval, vpieces[0]);
+      g_free(vpieces);
+    }
+  g_strfreev(pieces);
+
+  return retval;
+}
+
+static PlacedItem *
+make_placed_widget(WapTextFu *textfu, GtkWidget *widget, double alignment)
+{
+  PlacedItem *pi;
+  PangoRectangle rect;
+  GList *placed_items;
+  PangoAttribute *attr;
+
+  g_assert(textfu->in_content);
+
+  initiate_para(textfu);
+
+  placed_items = textfu->cur_para->placed_items;
+
+  pi = g_new0(PlacedItem, 1);
+  pi->widget = widget;
+  pi->alignment = alignment;
+
+  rect.x = 0;
+  rect.y = -(alignment * widget->allocation.height) * PANGO_SCALE;
+  rect.width = widget->allocation.width * PANGO_SCALE;
+  rect.height = widget->allocation.height * PANGO_SCALE;
+
+  pi->shape_attr = attr = pango_attr_shape_new(&rect, &rect);
+  attr->start_index = textfu->tmp_text->len;
+  attr->end_index = attr->start_index + strlen(wap_unknown_char_utf8);
+  /* Dummy char to take up the spot */
+  g_string_append_len(textfu->tmp_text, wap_unknown_char_utf8, strlen(wap_unknown_char_utf8));
+
+  placed_items = g_list_prepend(placed_items, pi);
+  textfu->cur_para->placed_items = placed_items;
+
+  pango_attr_list_insert(textfu->cur_para->attrs, attr);
+
+  gtk_layout_put(GTK_LAYOUT(textfu), widget, -100, -100);
+  gtk_widget_show(widget);
+
+  return pi;
+}
+
+/* tag implementations (X'd needs implementing):
+   a
+   anchor
+   b
+   big
+   br
+   card
+   do
+   em
+   go
+   i
+   img
+   input
+   option
+   p
+   postfield
+   prev
+   select
+   small
+   strong
+   table
+   tr
+   td
+   u
+   wml
+ */
+
+/* Ignore all the text underneath this tag */
+static void
+tag_handler_ignore(WapTextFu *textfu, const char *tag, guint16 tag_id,
+		   char **attrs, gboolean is_end)
+{
+  if(is_end)
+    textfu->ignore_counter--;
+  else
+    textfu->ignore_counter++;
+}
+
+static void
+link_style_setup(WapTextFu *textfu, WapTextStyle *ts, WapAnchorInfo *wai)
+{
+  ts->wai = wai;
+  ts->underline = TEXTFU_TRUE;
+  ts->fg_color.red = ts->fg_color.green = 0; ts->fg_color.blue = 65535;
+  gdk_color_alloc(gdk_rgb_get_cmap(), &ts->fg_color);
+  ts->fg_color_set = TRUE;
+
+  /* Even if this is currently same as the default bg right now, we will be changing it for selected links */
+  ts->bg_color.red = ts->bg_color.green = 65535; ts->bg_color.blue = 65535;
+  gdk_color_alloc(gdk_rgb_get_cmap(), &ts->bg_color);
+  ts->bg_color_set = TRUE;
+
+  ts->replace_prev = TRUE;
+}
+
+static void
+tag_handler_a_hdml(WapTextFu *textfu, const char *tag, guint16 tag_id,
+		   char **attrs, gboolean is_end)
+{
+  WapTextStyle *ts;
+
+  ts = style_change(textfu, tag, !is_end, TRUE, TRUE);
+
+  if(ts && attrs)
+    {
+      int i;
+      WapAnchorInfo *wai;
+
+      wai = g_new0(WapAnchorInfo, 1);
+      wai->type = ANCHORS_AWAY;
+      for(i = 0; attrs[i]; i++)
+	{
+	  if(!strcasecmp(attrs[i], "task"))
+	    {
+	      i++;
+	      if(!strcasecmp(attrs[i], "go"))
+		wai->type = ANCHOR_GO;
+	      else if(!strcasecmp(attrs[i], "prev"))
+		wai->type = ANCHOR_PREV;
+	      continue;
+	    }
+	  if(!strcasecmp(attrs[i], "dest"))
+	    {
+	      if(!wai->go_info)
+		wai->go_info = g_new0(WapGoInfo, 1);
+	      wai->go_info->url = g_strdup(attrs[i++]);
+	      continue;
+	    }
+	  if(!strcasecmp(attrs[i], "method"))
+	    {
+	      if(!wai->go_info)
+		wai->go_info = g_new0(WapGoInfo, 1);
+
+	      wai->go_info->post_method = !strcasecmp(attrs[++i], "post");
+	      continue;
+	    }
+	  if(!strcasecmp(attrs[i], "label"))
+	    {
+	      wai->title = g_strdup(attrs[++i]);
+	      continue;
+	    }
+	  if(!strcasecmp(attrs[i], "sendreferer"))
+	    {
+	      if(!wai->go_info)
+		wai->go_info = g_new0(WapGoInfo, 1);
+
+	      wai->go_info->sendreferer = toboolean(attrs[++i]);
+	      continue;
+	    }
+	  if(!strcasecmp(attrs[i], "accept-charset"))
+	    {
+	      if(!wai->go_info)
+		wai->go_info = g_new0(WapGoInfo, 1);
+
+	      wai->go_info->charset = g_strdup(attrs[++i]);
+	      continue;
+	    }
+	  if(!strcasecmp(attrs[i], "postdata"))
+	    {
+	      if(!wai->go_info)
+		wai->go_info = g_new0(WapGoInfo, 1);
+
+	      wai->go_info->postvalues = parse_query_string(attrs[++i]);
+	      continue;
+	    }
+	}
+
+      if(wai->go_info)
+	wai->go_info->sendreferer = TRUE;
+      link_style_setup(textfu, ts, wai);
+
+      textfu->cur_para->anchors = g_list_append(textfu->cur_para->anchors, wai);
+    }
+}
+
+static void
+tag_handler_a(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  WapTextStyle *ts;
+  /* We need to roughly translate this into
+     <anchor title=thetitle><go href=thehref/></anchor> */
+
+  initiate_para(textfu);
+
+  if(textfu->is_hdml)
+    return tag_handler_a_hdml(textfu, tag, tag_id, attrs, is_end);
+
+  ts = style_change(textfu, tag, !is_end, TRUE, TRUE);
+
+  if(ts && attrs)
+    {
+      int i;
+      char *link_title = NULL, *link_url = NULL;
+      WapAnchorInfo *wai;
+      
+      for(i = 0; attrs[i]; i++)
+      {
+	if(!strcasecmp(attrs[i], "href"))
+	  {
+	    link_url = g_strdup(attrs[++i]);
+	    continue;
+	  }
+	if(!strcasecmp(attrs[i], "title"))
+	  {
+	    link_title = g_strdup(attrs[++i]);
+	    continue;
+	  }
+      }
+      
+      wai = g_new0(WapAnchorInfo, 1);
+      wai->title = link_title;
+      wai->type = ANCHOR_GO;
+      wai->go_info = g_new0(WapGoInfo, 1);
+      wai->go_info->url = link_url;
+      wai->go_info->sendreferer = TRUE;
+
+      link_style_setup(textfu, ts, wai);
+
+      textfu->cur_para->anchors = g_list_append(textfu->cur_para->anchors, wai);
+    }
+}
+
+static void
+tag_handler_action(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  int i;
+  WapDoInfo *doi;
+
+  if(is_end)
+    return;
+
+  doi = g_new0(WapDoInfo, 1);
+
+  for(i = 0; attrs[i]; i++)
+    {
+      if(!strcasecmp(attrs[i], "type"))
+	{
+	  i++;
+	  if(!strcasecmp(attrs[i], "go"))
+	    doi->type = DO_ACCEPT;
+	  else if(!strcasecmp(attrs[i], "prev"))
+	    doi->type = DO_PREV;
+	  else if(!strcasecmp(attrs[i], "help"))
+	    doi->type = DO_HELP;
+	  else if(!strcasecmp(attrs[i], "soft1"))
+	    doi->type = DO_SOFT1;
+	  else if(!strcasecmp(attrs[i], "soft2"))
+	    doi->type = DO_SOFT2;
+	  else if(!strcasecmp(attrs[i], "prev"))
+	    doi->type = DO_PREV;
+	  else if(!strcasecmp(attrs[i], "send"))
+	    doi->type = DO_SEND;
+	  else
+	    doi->type = DO_NOTHING;
+
+	  continue;
+	}
+
+      if(!strcasecmp(attrs[i], "label"))
+	{
+	  doi->label = g_strdup(attrs[++i]);
+	  continue;
+	}
+
+      if(!strcasecmp(attrs[i], "name"))
+	{
+	  doi->name = g_strdup(attrs[++i]);
+	  continue;
+	}
+
+      if(!strcasecmp(attrs[i], "task"))
+	{
+	  if(!strcasecmp(attrs[i], "go")
+	     || !strcasecmp(attrs[i], "gosub"))
+	    doi->task = ACT_GO;
+	  else if(!strcasecmp(attrs[i], "prev"))
+	    doi->task = ACT_PREV;
+	  else
+	    doi->task = ACT_NOTHING;
+	}
+
+      if(!strcasecmp(attrs[i], "dest"))
+	{
+	  if(!doi->go)
+	    doi->go = g_new0(WapGoInfo, 1);
+
+	  doi->go->url = g_strdup(attrs[++i]);
+	  continue;
+	}
+
+      if(!strcasecmp(attrs[i], "accept-charset"))
+	{
+	  if(!doi->go)
+	    doi->go = g_new0(WapGoInfo, 1);
+
+	  doi->go->charset = g_strdup(attrs[++i]);
+	  continue;
+	}
+
+      if(!strcasecmp(attrs[i], "postdata"))
+	{
+	  if(!doi->go)
+	    doi->go = g_new0(WapGoInfo, 1);
+
+	  doi->go->postvalues = parse_query_string(attrs[++i]);
+	  continue;
+	}
+
+      if(!strcasecmp(attrs[i], "method"))
+	{
+	  if(!doi->go)
+	    doi->go = g_new0(WapGoInfo, 1);
+
+	  if(!strcasecmp(attrs[++i], "post"))
+	    doi->go->post_method = TRUE;
+
+	  continue;
+	}
+
+      if(!strcasecmp(attrs[i], "sendreferer"))
+	{
+	  if(!doi->go)
+	    doi->go = g_new0(WapGoInfo, 1);
+
+	  doi->go->sendreferer = toboolean(attrs[++i]);
+	  continue;
+	}
+      if(!strcasecmp(attrs[i], "src"))
+	{
+	  doi->img = wap_pixmap_new_from_uri(textfu, attrs[++i], NULL);
+	  continue;
+	}
+    }
+
+  textfu->cur_card->actions = g_list_append(textfu->cur_card->actions, doi);
+}
+
+static void
+tag_handler_anchor(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  WapTextStyle *ts;
+
+  ts = style_change(textfu, tag, !is_end, TRUE, TRUE);
+  textfu->in_anchor = !is_end;
+
+  if(ts)
+    {
+      int i;
+      char *link_title = NULL;
+      WapAnchorInfo *wai;
+      
+      initiate_para(textfu);
+
+      if(attrs)
+	for(i = 0; attrs[i]; i++)
+	  {
+	    if(!strcasecmp(attrs[i], "title"))
+	      {
+		link_title = g_strdup(attrs[++i]);
+		continue;
+	      }
+	  }
+      
+      wai = g_new0(WapAnchorInfo, 1);
+      wai->title = link_title;
+      wai->type = ANCHORS_AWAY;
+
+      link_style_setup(textfu, ts, wai);
+
+      textfu->cur_anchor = wai;
+      textfu->cur_para->anchors = g_list_append(textfu->cur_para->anchors, wai);
+    }
+  else
+    textfu->cur_anchor = NULL;
+}
+
+static void
+tag_handler_b(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  WapTextStyle *ts;
+
+  ts = style_change(textfu, tag, !is_end, TRUE, FALSE);
+
+  if(ts)
+    {
+      ts->bold = TEXTFU_TRUE;
+    }
+}
+
+static void
+tag_handler_big(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  WapTextStyle *ts;
+
+  ts = style_change(textfu, tag, !is_end, TRUE, FALSE);
+
+  if(ts)
+    {
+      ts->font_size = LARGE_FONT_SIZE;
+      ts->font_size_set = TRUE;
+    }
+}
+
+static void
+tag_handler_br(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  WapParagraphInfo *para;
+
+  para = push_pango_para(textfu);
+  if(para)
+    para->space_after = 0;
+}
+
+static void
+tag_handler_card(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  textfu->in_content = !is_end;
+
+  if(is_end)
+    {
+      g_assert(textfu->cur_card);
+
+      paragraph_division(textfu, tag, FALSE, FALSE);
+      style_change(textfu, tag, FALSE, TRUE, FALSE);
+
+      g_list_foreach(textfu->cur_card->para_style_stack, (GFunc)g_free, NULL);
+      g_list_free(textfu->cur_card->para_style_stack); textfu->cur_card->para_style_stack = NULL;
+
+      g_list_foreach(textfu->cur_card->para_style_stack, (GFunc)wap_text_style_free, NULL);
+      g_list_free(textfu->cur_card->text_style_stack); textfu->cur_card->text_style_stack = NULL;
+    }
+  else
+    {
+      WapCard *card;
+      int i;
+      WapTextStyle *ts;
+
+      card = g_new0(WapCard, 1);
+      textfu->cur_card = card;
+
+      textfu->cards = g_list_append(textfu->cards, card);
+
+      if(attrs)
+	for(i = 0; attrs[i]; i++)
+	  {
+	    if(!strcasecmp(attrs[i], "id"))
+	      {
+		card->id = g_strdup(attrs[++i]);
+		continue;
+	      }
+
+	    if(!strcasecmp(attrs[i], "title"))
+	      {
+		card->title = g_strdup(attrs[++i]);
+		continue;
+	      }
+
+	    if(!strcasecmp(attrs[i], "ontimer"))
+	      {
+		card->ontimer = g_strdup(attrs[++i]);
+		continue;
+	      }
+
+	    if(!strcasecmp(attrs[i], "onenterforward"))
+	      {
+		card->onenterbackward = g_strdup(attrs[++i]);
+		continue;
+	      }
+
+	    if(!strcasecmp(attrs[i], "onenterbackward"))
+	      {
+		card->onenterbackward = g_strdup(attrs[++i]);
+		continue;
+	      }
+
+	    if(!strcasecmp(attrs[i], "newcontext"))
+	      {
+		card->newcontext = toboolean(attrs[++i]);
+		continue;
+	      }
+	  }
+      if(!card->id)
+	card->id = g_strdup("X!!X");
+
+      ts = style_change(textfu, tag, TRUE, TRUE, FALSE);
+      ts->font_size_set = TRUE;
+      ts->font_size = NORMAL_FONT_SIZE;
+
+      paragraph_division(textfu, tag, TRUE, FALSE);
+    }
+}
+
+static void
+tag_handler_ce(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  WapInputInfo *input;
+  WapOptionInfo *opt;
+
+  if(is_end)
+    return;
+
+  if(textfu->cur_option)
+    {
+      /* End the previous CE tag */
+
+      PlacedItem *pi;
+      GtkWidget *mi, *b;
+
+      pi = textfu->cur_input->placed_item;
+
+      textfu->cur_option->text = g_strdup(textfu->nc_text->str);
+      g_strstrip(textfu->cur_option->text);
+      if(!strlen(textfu->cur_option->text))
+	{
+	  g_free(textfu->cur_option->text); textfu->cur_option->text = NULL;
+	}
+
+      if(textfu->cur_option->image)
+	{
+	  mi = gtk_list_item_new();
+	  if(textfu->cur_option->text)
+	    {
+	      b = gtk_hbox_new(FALSE, 5);
+	      gtk_container_add(GTK_CONTAINER(b), textfu->cur_option->image);
+	      gtk_container_add(GTK_CONTAINER(b), gtk_label_new(textfu->cur_option->text));
+	      gtk_container_add(GTK_CONTAINER(mi), b);
+	    }
+	  else
+	    gtk_container_add(GTK_CONTAINER(mi), textfu->cur_option->image);
+	}
+      else
+	mi = gtk_list_item_new_with_label(textfu->cur_option->text?textfu->cur_option->text:"");
+      gtk_widget_show_all(mi);
+
+      gtk_object_set_data(GTK_OBJECT(mi), "WapOptionInfo", textfu->cur_option);
+
+      if(textfu->cur_option->onpick)
+	gtk_signal_connect(GTK_OBJECT(mi), "select", GTK_SIGNAL_FUNC(tag_option_event_selected), textfu);
+
+      textfu->cur_option->li_widget = mi;
+      textfu->in_option = FALSE;
+      textfu->cur_option = NULL;
+
+      gtk_container_add(GTK_CONTAINER(pi->widget), mi);
+    }
+
+  g_assert(textfu->in_select);
+  textfu->in_content = FALSE;
+  textfu->in_option = TRUE;
+  input = textfu->cur_input;
+
+  opt = textfu->cur_option = g_new0(WapOptionInfo, 1);
+  textfu->cur_input->options = g_list_append(textfu->cur_input->options, opt);
+
+  if(attrs)
+    {
+      int i;
+
+      for(i = 0; attrs[i]; i++)
+	{
+	  if(!strcasecmp(attrs[i], "value"))
+	    {
+	      opt->value = g_strdup(attrs[++i]);
+	      continue;
+	    }
+
+	  /* Bad hack - we don't handle the "task" attribute */
+	  if(!strcasecmp(attrs[i], "dest"))
+	    {
+	      opt->onpick = g_strdup(attrs[++i]);
+	      continue;
+	    }
+	}
+    }
+}
+
+static void
+tag_handler_choice(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  textfu->in_content = !is_end;
+
+  if(is_end)
+    {
+      textfu->cur_input = NULL;
+
+      paragraph_division(textfu, tag, FALSE, FALSE);
+      style_change(textfu, tag, FALSE, TRUE, FALSE);
+
+      g_list_foreach(textfu->cur_card->para_style_stack, (GFunc)g_free, NULL);
+      g_list_free(textfu->cur_card->para_style_stack); textfu->cur_card->para_style_stack = NULL;
+
+      g_list_foreach(textfu->cur_card->para_style_stack, (GFunc)wap_text_style_free, NULL);
+      g_list_free(textfu->cur_card->text_style_stack); textfu->cur_card->text_style_stack = NULL;
+    }
+  else
+    {
+      WapCard *card;
+      int i;
+      WapTextStyle *ts;
+      GtkWidget *widget;
+
+      card = g_new0(WapCard, 1);
+      textfu->cur_card = card;
+
+      textfu->cards = g_list_append(textfu->cards, card);
+
+      textfu->cur_input = g_new0(WapInputInfo, 1);
+      textfu->cur_card->inputs = g_list_append(textfu->cur_card->inputs, textfu->cur_input);
+      /* We purposely don't set in_select and in_content here, we do it in the 'ce' tag handler to be able to grok the
+	 line or two of text that comes along */
+
+      for(i = 0; attrs[i]; i++)
+	{
+	  if(!strcasecmp(attrs[i], "name"))
+	    {
+	      card->id = g_strdup(attrs[++i]);
+	      continue;
+	    }
+
+	  if(!strcasecmp(attrs[i], "title"))
+	    {
+	      card->title = g_strdup(attrs[++i]);
+	      continue;
+	    }
+
+	  if(!strcasecmp(attrs[i], "key"))
+	    {
+	      textfu->cur_input->name = g_strdup(attrs[++i]);
+	      continue;
+	    }
+	}
+
+      textfu->cur_input->is_selection = TRUE;
+      widget = gtk_list_new();
+      gtk_list_set_selection_mode(GTK_LIST(widget), GTK_SELECTION_SINGLE);
+      gtk_object_set_data(GTK_OBJECT(widget), "PlacedItem",
+			  textfu->cur_input->placed_item = make_placed_widget(textfu, widget, 0.1));
+
+      ts = style_change(textfu, tag, TRUE, TRUE, FALSE);
+      ts->font_size_set = TRUE;
+      ts->font_size = NORMAL_FONT_SIZE;
+
+      paragraph_division(textfu, tag, TRUE, FALSE);
+    }
+}
+
+static void
+tag_handler_display(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  textfu->in_content = !is_end;
+
+  if(is_end)
+    {
+      g_assert(textfu->cur_card);
+
+      paragraph_division(textfu, tag, FALSE, FALSE);
+      style_change(textfu, tag, FALSE, TRUE, FALSE);
+
+      g_list_foreach(textfu->cur_card->para_style_stack, (GFunc)g_free, NULL);
+      g_list_free(textfu->cur_card->para_style_stack); textfu->cur_card->para_style_stack = NULL;
+
+      g_list_foreach(textfu->cur_card->para_style_stack, (GFunc)wap_text_style_free, NULL);
+      g_list_free(textfu->cur_card->text_style_stack); textfu->cur_card->text_style_stack = NULL;
+    }
+  else
+    {
+      WapCard *card;
+      int i;
+      WapTextStyle *ts;
+
+      card = g_new0(WapCard, 1);
+      textfu->cur_card = card;
+
+      textfu->cards = g_list_append(textfu->cards, card);
+
+      for(i = 0; attrs[i]; i++)
+	{
+	  if(!strcasecmp(attrs[i], "name"))
+	    {
+	      card->id = g_strdup(attrs[++i]);
+	      continue;
+	    }
+
+	  if(!strcasecmp(attrs[i], "title"))
+	    {
+	      card->title = g_strdup(attrs[++i]);
+	      continue;
+	    }
+	}
+
+      ts = style_change(textfu, tag, TRUE, TRUE, FALSE);
+      ts->font_size_set = TRUE;
+      ts->font_size = NORMAL_FONT_SIZE;
+
+      paragraph_division(textfu, tag, TRUE, FALSE);
+    }
+}
+
+static void
+tag_handler_do(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  textfu->in_do = !is_end;
+  textfu->in_content = is_end;
+
+  if(!is_end)
+    {
+      int i;
+      WapDoInfo *doi = g_new0(WapDoInfo, 1);
+
+      for(i = 0; attrs[i]; i++)
+	{
+	  if(!strcasecmp(attrs[i], "type"))
+	    {
+	      i++;
+	      if(!strcasecmp(attrs[i], "accept"))
+		doi->type = DO_ACCEPT;
+	      else if(!strcasecmp(attrs[i], "delete"))
+		doi->type = DO_DELETE;
+	      else if(!strcasecmp(attrs[i], "help"))
+		doi->type = DO_HELP;
+	      else if(!strcasecmp(attrs[i], "options"))
+		doi->type = DO_OPTIONS;
+	      else if(!strcasecmp(attrs[i], "prev"))
+		{
+		  doi->type = DO_PREV;
+		  doi->task = ACT_PREV;
+		}
+	      else
+		doi->type = DO_NOTHING;
+
+	      continue;
+	    }
+
+	  if(!strcasecmp(attrs[i], "label"))
+	    {
+	      doi->label = g_strdup(attrs[++i]);
+	      continue;
+	    }
+
+	  if(!strcasecmp(attrs[i], "name"))
+	    {
+	      doi->name = g_strdup(attrs[++i]);
+	      continue;
+	    }
+
+	  /* Exactly why are we supposed to care about the 'optional' attribute? */
+	}
+
+      if(!doi->label)
+	{
+	  switch(doi->task)
+	    {
+	    case ACT_GO:
+	      doi->label = g_strdup("Go");
+	      break;
+	    case ACT_PREV:
+	      doi->label = g_strdup("Prev");
+	      break;
+	    default:
+	      doi->label = g_strdup("Unknown");
+	      break;
+	    }
+	}
+
+      textfu->cur_card->actions = g_list_append(textfu->cur_card->actions, doi);
+      textfu->cur_do = doi;
+    }
+  else
+    {
+      textfu->cur_do = NULL;
+    }
+}
+
+static void
+tag_handler_em(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  WapTextStyle *ts;
+
+  ts = style_change(textfu, tag, !is_end, TRUE, FALSE);
+
+  if(ts)
+    {
+      ts->italic = TEXTFU_TRUE;
+    }
+}
+
+static void
+tag_handler_entry(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  int i;
+  WapInputInfo *input;
+  GtkWidget *widget;
+  WapCard *card;
+  WapTextStyle *ts;
+
+  if(is_end)
+    {
+      g_assert(textfu->cur_card);
+
+      paragraph_division(textfu, tag, FALSE, FALSE);
+      style_change(textfu, tag, FALSE, TRUE, FALSE);
+
+      g_list_foreach(textfu->cur_card->para_style_stack, (GFunc)g_free, NULL);
+      g_list_free(textfu->cur_card->para_style_stack); textfu->cur_card->para_style_stack = NULL;
+
+      g_list_foreach(textfu->cur_card->para_style_stack, (GFunc)wap_text_style_free, NULL);
+      g_list_free(textfu->cur_card->text_style_stack); textfu->cur_card->text_style_stack = NULL;
+    }
+
+  card = g_new0(WapCard, 1);
+  textfu->cur_card = card;
+
+  textfu->cards = g_list_append(textfu->cards, card);
+
+  ts = style_change(textfu, tag, TRUE, TRUE, FALSE);
+  ts->font_size_set = TRUE;
+  ts->font_size = NORMAL_FONT_SIZE;
+  paragraph_division(textfu, tag, TRUE, FALSE);
+
+  input = g_new0(WapInputInfo, 1);
+  input->ivalue = -1;
+  textfu->cur_card->inputs = g_list_append(textfu->cur_card->inputs, input);
+
+  for(i = 0; attrs[i]; i++)
+    {
+      if(!strcasecmp(attrs[i], "name"))
+	{
+	  card->id = g_strdup(attrs[++i]);
+	  continue;
+	}
+      if(!strcasecmp(attrs[i], "title"))
+	{
+	  card->title = g_strdup(attrs[++i]);
+	  continue;
+	}
+      if(!strcasecmp(attrs[i], "format"))
+	{
+	  input->fmt = g_strdup(attrs[++i]);
+	  continue;
+	}
+      if(!strcasecmp(attrs[i], "default"))
+	{
+	  input->value = g_strdup(attrs[++i]);
+	  continue;
+	}
+      if(!strcasecmp(attrs[i], "emptyok"))
+	{
+	  input->emptyok = toboolean(attrs[++i]);
+	  continue;
+	}
+      if(!strcasecmp(attrs[i], "maxlength"))
+	{
+	  input->maxlen = atoi(attrs[++i]);
+	  continue;
+	}
+    }
+
+  widget = input->maxlen?gtk_entry_new_with_max_length(input->maxlen):gtk_entry_new();
+  gtk_object_set_data(GTK_OBJECT(widget), "PlacedItem", input->placed_item = make_placed_widget(textfu, widget, 1.0));
+}
+
+/* Dunno how to handle fieldset */
+
+static void
+tag_handler_go(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  if(is_end)
+    {
+      if(textfu->in_do)
+	textfu->cur_do->go = textfu->cur_go;
+      else if(textfu->in_anchor)
+	{
+	  textfu->cur_anchor->go_info = textfu->cur_go;
+	  textfu->cur_anchor->type = ANCHOR_GO;
+	}
+      else
+	g_assert_not_reached();
+
+      textfu->cur_go = NULL;
+    }
+  else
+    {
+      int i;
+      WapGoInfo *go;
+
+      go = textfu->cur_go = g_new0(WapGoInfo, 1);
+      for(i = 0; attrs[i]; i++)
+	{
+	  if(!strcasecmp(attrs[i], "method"))
+	    {
+	      if(!strcasecmp(attrs[++i], "post"))
+		go->post_method = TRUE;
+	      continue;
+	    }
+
+	  if(!strcasecmp(attrs[i], "sendreferer"))
+	    {
+	      go->sendreferer = toboolean(attrs[++i]);
+	      continue;
+	    }
+
+	  if(!strcasecmp(attrs[i], "href"))
+	    {
+	      go->url = g_strdup(attrs[++i]);
+	      continue;
+	    }
+	}
+    }
+}
+
+static void
+tag_handler_hdml(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  textfu->is_hdml = !is_end;
+}
+
+static void
+tag_handler_i(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  return tag_handler_em(textfu, "em", tag_id, attrs, is_end);
+}
+
+static void
+tag_handler_img(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  char *url = NULL, *alt = NULL;
+  int i;
+  GtkWidget *widget;
+  double align = 0.0;
+
+  if(is_end)
+    return;
+
+  for(i = 0; attrs[i]; i++)
+    {
+      if(!strcasecmp(attrs[i], "src"))
+	{
+	  url = g_strdup(attrs[++i]);
+	  continue;
+	}
+      if(!strcasecmp(attrs[i], "alt"))
+	{
+	  alt = g_strdup(attrs[++i]);
+	  continue;
+	}
+      if(!strcasecmp(attrs[i], "align"))
+	{
+	  i++;
+	  if(!strcasecmp(attrs[i], "top"))
+	    align = 0.0;
+	  else if(!strcasecmp(attrs[i], "center"))
+	    align = 0.5;
+	  else
+	    align = 1.0;
+	}
+    }
+
+  widget = wap_pixmap_new_from_uri(textfu, url, alt);
+  g_free(url);
+  g_free(alt);
+
+  if(textfu->in_option)
+    textfu->cur_option->image = widget;
+  else if(textfu->in_do)
+    {
+      textfu->cur_do->img = gtk_widget_ref(widget);
+      /* gtk_object_sink(GTK_OBJECT(widget)); */
+    }
+  else
+    gtk_object_set_data(GTK_OBJECT(widget), "PlacedItem", make_placed_widget(textfu, widget, align));
+}
+
+static void
+tag_handler_input(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  int i;
+  WapInputInfo *input;
+  GtkWidget *widget;
+
+  if(is_end)
+    return;
+
+  input = g_new0(WapInputInfo, 1);
+  input->ivalue = -1;
+  textfu->cur_card->inputs = g_list_append(textfu->cur_card->inputs, input);
+  for(i = 0; attrs[i]; i++)
+    {
+      if(!strcasecmp(attrs[i], "name"))
+	{
+	  input->name = g_strdup(attrs[++i]);
+	  continue;
+	}
+      if(!strcasecmp(attrs[i], "title"))
+	{
+	  input->title = g_strdup(attrs[++i]);
+	  continue;
+	}
+      if(!strcasecmp(attrs[i], "value"))
+	{
+	  input->value = g_strdup(attrs[++i]);
+	  continue;
+	}
+      if(!strcasecmp(attrs[i], "emptyok"))
+	{
+	  input->emptyok = toboolean(attrs[++i]);
+	  continue;
+	}
+      if(!strcasecmp(attrs[i], "maxlength"))
+	{
+	  input->maxlen = atoi(attrs[++i]);
+	  continue;
+	}
+      if(!strcasecmp(attrs[i], "format"))
+	{
+	  input->fmt = g_strdup(attrs[++i]);
+	  continue;
+	}
+    }
+
+  widget = input->maxlen?gtk_entry_new_with_max_length(input->maxlen):gtk_entry_new();
+  gtk_object_set_data(GTK_OBJECT(widget), "PlacedItem", input->placed_item = make_placed_widget(textfu, widget, 1.0));
+}
+
+static void
+tag_option_event_selected(GtkWidget *list_item, GtkObject *textfu)
+{
+  WapOptionInfo *woi = gtk_object_get_data(GTK_OBJECT(list_item), "WapOptionInfo");
+
+  gtk_signal_emit(textfu, textfu_signals[LINK_FOLLOWED], woi->onpick);
+}
+
+static void
+tag_handler_option(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  WapOptionInfo *option;
+
+  if(is_end)
+    {
+      PlacedItem *pi;
+      GtkWidget *mi, *b;
+
+      pi = textfu->cur_input->placed_item;
+
+      textfu->cur_option->text = g_strdup(textfu->nc_text->str);
+      g_strstrip(textfu->cur_option->text);
+      if(!strlen(textfu->cur_option->text))
+	{
+	  g_free(textfu->cur_option->text); textfu->cur_option->text = NULL;
+	}
+
+      if(textfu->cur_option->image)
+	{
+	  mi = gtk_list_item_new();
+	  if(textfu->cur_option->text)
+	    {
+	      b = gtk_hbox_new(FALSE, 5);
+	      gtk_container_add(GTK_CONTAINER(b), textfu->cur_option->image);
+	      gtk_container_add(GTK_CONTAINER(b), gtk_label_new(textfu->cur_option->text));
+	      gtk_container_add(GTK_CONTAINER(mi), b);
+	    }
+	  else
+	    gtk_container_add(GTK_CONTAINER(mi), textfu->cur_option->image);
+	}
+      else
+	mi = gtk_list_item_new_with_label(textfu->cur_option->text?textfu->cur_option->text:"");
+      gtk_widget_show_all(mi);
+
+      gtk_object_set_data(GTK_OBJECT(mi), "WapOptionInfo", textfu->cur_option);
+
+      if(textfu->cur_option->onpick)
+	gtk_signal_connect(GTK_OBJECT(mi), "select", GTK_SIGNAL_FUNC(tag_option_event_selected), textfu);
+
+      textfu->cur_option->li_widget = mi;
+      textfu->in_option = FALSE;
+      textfu->cur_option = NULL;
+
+      gtk_container_add(GTK_CONTAINER(pi->widget), mi);
+      return;
+    }
+
+  g_assert(textfu->in_select);
+
+  g_string_truncate(textfu->nc_text, 0);
+  textfu->in_content = FALSE;
+  textfu->in_option = TRUE;
+  textfu->cur_option = option = g_new0(WapOptionInfo, 1);
+  textfu->cur_input->options = g_list_append(textfu->cur_input->options, option);
+  if(attrs)
+    {
+      int i;
+
+      for(i = 0; attrs[i]; i++)
+	{
+	  if(!strcasecmp(attrs[i], "onpick"))
+	    {
+	      option->onpick = g_strdup(attrs[++i]);
+	      continue;
+	    }
+	  if(!strcasecmp(attrs[i], "value"))
+	    {
+	      option->value = g_strdup(attrs[++i]);
+	      continue;
+	    }
+	}
+    }
+}
+
+static void
+tag_handler_p(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  WapParaStyle *ps;
+
+  ps = paragraph_division(textfu, tag, !is_end, FALSE);
+
+  if(ps && attrs)
+    {
+      int i;
+      for(i = 0; attrs[i]; i++)
+	{
+	  if(!strcasecmp(attrs[i], "align"))
+	    {
+	      i++;
+	      if(!strcasecmp(attrs[i], "left"))
+		{
+		  ps->alignment = PANGO_ALIGN_LEFT;
+		}
+	      else if(!strcasecmp(attrs[i], "center"))
+		{
+		  ps->alignment = PANGO_ALIGN_CENTER;
+		}
+	      else if(!strcasecmp(attrs[i], "right"))
+		{
+		  ps->alignment = PANGO_ALIGN_RIGHT;
+		}
+	    }
+	}
+
+      ps->space_after = PARA_SPACE_AFTER;
+    }
+}
+
+static void
+tag_handler_postfield(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  int i;
+  char *name = NULL, *value = NULL;
+
+  g_assert(textfu->cur_go);
+  if(is_end)
+    return;
+
+  for(i = 0; attrs[i]; i++)
+    {
+      if(!strcasecmp(attrs[i], "name"))
+	{
+	  name = g_strdup(attrs[++i]);
+	  continue;
+	}
+      if(!strcasecmp(attrs[i], "value"))
+	{
+	  value = g_strdup(attrs[++i]);
+	  continue;
+	}
+    }
+
+  textfu->cur_go->postvalues = g_list_prepend(textfu->cur_go->postvalues, value);
+  textfu->cur_go->postvalues = g_list_prepend(textfu->cur_go->postvalues, name);
+}
+
+static void
+tag_handler_prev(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  if(!is_end)
+    {
+      if(textfu->in_do)
+	textfu->cur_do->type = DO_PREV;
+      else if(textfu->in_anchor)
+	textfu->cur_anchor->type = ANCHOR_PREV;
+    }
+}
+
+static void
+tag_handler_select(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  int i;
+  WapInputInfo *input;
+  GtkWidget *widget;
+
+  if(is_end)
+    {
+      textfu->cur_input = NULL;
+      textfu->in_content = TRUE;
+      textfu->in_select = FALSE;
+      return;
+    }
+
+  textfu->cur_input = input = g_new0(WapInputInfo, 1);
+  textfu->cur_card->inputs = g_list_append(textfu->cur_card->inputs, input);
+  if(attrs)
+    {
+      for(i = 0; attrs[i]; i++)
+	{
+	  if(!strcasecmp(attrs[i], "name"))
+	    {
+	      input->name = g_strdup(attrs[++i]);
+	      continue;
+	    }
+	  if(!strcasecmp(attrs[i], "title"))
+	    {
+	      input->title = g_strdup(attrs[++i]);
+	      continue;
+	    }
+	  if(!strcasecmp(attrs[i], "value"))
+	    {
+	      input->value = g_strdup(attrs[++i]);
+	      continue;
+	    }
+	  if(!strcasecmp(attrs[i], "multiple"))
+	    {
+	      input->multiple = toboolean(attrs[++i]);
+	      continue;
+	    }
+	  if(!strcasecmp(attrs[i], "ivalue"))
+	    {
+	      input->ivalue = atoi(attrs[++i]);
+	      continue;
+	    }
+	  if(!strcasecmp(attrs[i], "iname"))
+	    {
+	      input->iname = g_strdup(attrs[++i]);
+	      continue;
+	    }
+	}
+    }
+
+  input->is_selection = TRUE;
+
+  widget = gtk_list_new();
+  gtk_list_set_selection_mode(GTK_LIST(widget), input->multiple?GTK_SELECTION_MULTIPLE:GTK_SELECTION_SINGLE);
+
+  gtk_object_set_data(GTK_OBJECT(widget), "PlacedItem", input->placed_item = make_placed_widget(textfu, widget, 0.1));
+  textfu->in_content = FALSE;
+  textfu->in_select = TRUE;
+}
+
+static void
+tag_handler_small(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  WapTextStyle *ts;
+
+  ts = style_change(textfu, tag, !is_end, TRUE, FALSE);
+
+  if(ts)
+    {
+      ts->font_size = SMALL_FONT_SIZE;
+      ts->font_size_set = TRUE;
+    }
+}
+
+static void
+tag_handler_strong(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  return tag_handler_b(textfu, "b", tag_id, attrs, is_end);
+}
+
+/* The next three are very bad hacks to emulate tables... */
+static void
+tag_handler_table(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  push_pango_para(textfu);
+}
+
+static void
+tag_handler_td(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  g_assert(textfu->in_content);
+
+  if(is_end && !my_isspace(textfu->tmp_text->str[textfu->tmp_text->len - 1]))
+    g_string_append_c(textfu->tmp_text, ' ');
+}
+
+static void
+tag_handler_tr(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  g_assert(textfu->in_content);
+
+  if(!is_end)
+    push_pango_para(textfu);
+}
+
+static void
+tag_handler_timer(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  g_assert(textfu->cur_card);
+
+  if(!is_end && attrs)
+    {
+      WapTimerInfo *timer;
+      int i;
+
+      timer = g_new0(WapTimerInfo, 1);
+      for(i = 0; attrs[i]; i++)
+	{
+	  if(!strcasecmp(attrs[i], "name"))
+	    {
+	      timer->name = g_strdup(attrs[++i]);
+	      continue;
+	    }
+	  if(!strcasecmp(attrs[i], "name"))
+	    {
+	      timer->value = atoi(attrs[++i]);
+	      continue;
+	    }
+	}
+
+      textfu->cur_card->timers = g_list_prepend(textfu->cur_card->timers, timer);
+    }
+}
+
+static void
+tag_handler_u(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  WapTextStyle *ts;
+
+  ts = style_change(textfu, tag, !is_end, TRUE, FALSE);
+
+  if(ts)
+    {
+      ts->underline = TEXTFU_TRUE;
+    }
+}
+
+static void
+tag_handler_wml(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end)
+{
+  if(is_end)
+    {
+      textfu->cur_card = NULL;
+    }
+  else
+    {
+      int i;
+
+      g_free(textfu->lang); textfu->lang = NULL;
+
+      if(attrs)
+	for(i = 0; attrs[i]; i++)
+	  {
+	    if(!strcasecmp(attrs[i], "xml:lang"))
+	      {
+		textfu->lang = g_strdup(attrs[++i]);
+		pango_context_set_lang(textfu->pango_ctx, textfu->lang);
+		continue;
+	      }
+	  }
+      if(!textfu->lang)
+	pango_context_set_lang(textfu->pango_ctx, "en");
+    }
+}
+
+/* Image loading */
+typedef struct {
+  WapTextFu *textfu;
+  GtkWidget *pmap;
+  GdkPixbufLoader *loader;
+  GdkPixmap *pixmap;
+  GdkBitmap *bitmap;
+} PixmapLoaderInfo;
+
+#if 0
+static void wap_pixmap_prepared(GdkPixbufLoader *loader,
+				PixmapLoaderInfo *pli)
+{
+  GdkPixbuf *pb;
+  GdkPixmap *pmap = NULL;
+  GdkBitmap *mask = NULL;
+
+  g_assert(loader == pli->loader);
+  pb = gdk_pixbuf_loader_get_pixbuf(loader);
+  g_assert(pb);
+
+  gdk_pixbuf_render_pixmap_and_mask(pb, &pmap, &mask, 127);
+
+  gtk_pixmap_set(GTK_PIXMAP(pli->pmap), pmap, mask);
+  pli->pixmap = pmap;
+  pli->bitmap = mask;
+}
+
+static void wap_pixmap_updated(GdkPixbufLoader *loader,
+			       guint            x,
+			       guint            y,
+			       guint            width,
+			       guint            height,
+			       PixmapLoaderInfo *pli)
+{
+  GdkPixbuf *pb;
+
+  pb = gdk_pixbuf_loader_get_pixbuf(pli->loader);
+  gdk_pixbuf_render_to_drawable_alpha(pb, pli->pixmap, 0, 0, 0, 0,
+				      gdk_pixbuf_get_width(pb),
+				      gdk_pixbuf_get_height(pb),
+				      GDK_PIXBUF_ALPHA_BILEVEL, 127, GDK_RGB_DITHER_NORMAL, 0, 0);
+}
+
+static void wap_pixmap_closed(GdkPixbufLoader *loader,
+			      PixmapLoaderInfo *pli)
+{
+  wap_pixmap_prepared(loader, pli); /* Do it all again */
+}
+#endif
+
+#if 0
+static void wap_pixmap_start(WapStreamHandle handle, const char *mime_type, gpointer user_data)
+{
+  PixmapLoaderInfo *pli = user_data;
+
+  if(mime_type)
+    {
+      char *ctmp;
+      int n;
+
+      n = strlen("image/");
+      if(strncmp(mime_type, "image/", n))
+	return;
+
+      mime_type += n;
+
+      ctmp = strrchr(mime_type, '.');
+      if(ctmp)
+	mime_type = ctmp+1;
+      if(!strncmp(mime_type, "x-", 2))
+	mime_type += 2;
+
+      pli->loader = gdk_pixbuf_loader_new_with_type(mime_type);
+    }
+  else
+    pli->loader = gdk_pixbuf_loader_new();
+
+  gtk_signal_connect(GTK_OBJECT(pli->loader), "area_prepared", wap_pixmap_prepared, pli);
+  gtk_signal_connect(GTK_OBJECT(pli->loader), "area_updated", wap_pixmap_updated, pli);
+  gtk_signal_connect(GTK_OBJECT(pli->loader), "closed", wap_pixmap_closed, pli);
+}
+
+static void wap_pixmap_end(WapStreamHandle handle, WapStreamStatus status, gpointer user_data)
+{
+  PixmapLoaderInfo *pli = user_data;
+
+  gtk_widget_queue_resize(GTK_WIDGET(pli->textfu));
+  if(pli->loader)
+    {
+      gdk_pixbuf_loader_close(pli->loader);
+      g_object_unref(G_OBJECT(pli->loader));
+      pli->loader = NULL;
+    }
+  if(pli->pmap)
+    {
+      gtk_widget_unref(pli->pmap);
+      pli->pmap = NULL;
+    }
+
+  g_free(pli);
+}
+
+static void wap_pixmap_write(WapStreamHandle handle, const guchar *buffer, size_t size, gpointer user_data)
+{
+  PixmapLoaderInfo *pli = user_data;
+
+  if(!pli->loader)
+    {
+      g_warning("Don't have a loader for this image!");
+      return;
+    }
+
+  gdk_pixbuf_loader_write(pli->loader, buffer, size);
+}
+#endif
+
+static GtkWidget *
+wap_pixmap_new_from_uri(WapTextFu *textfu, char *uri, const char *alt_text)
+{
+  GtkWidget *retval;
+  GdkPixmap *pmap;
+  PixmapLoaderInfo *pli;
+  int n;
+
+  if(uri[0] == '"')
+    uri++;
+  n = strlen(uri) - 1;
+  if(uri[n] == '"')
+    uri[n] = '\0';
+  pmap = gdk_pixmap_new(NULL, 1, 1, 24); /* GDK_ROOT_PARENT () */
+  retval = gtk_pixmap_new(pmap, NULL);
+  gtk_widget_ref(retval);
+  gdk_pixmap_unref(pmap);
+
+  pli = g_new0(PixmapLoaderInfo, 1);
+  pli->textfu = textfu;
+  pli->pmap = retval;
+  pli->loader = NULL;
+
+  return retval;
+}
+
+GtkType
+wap_textfu_get_type (void)
+{
+  static GtkType textfu_type = 0;
+
+  if (!textfu_type)
+    {
+      static const GtkTypeInfo textfu_info =
+      {
+        "WapTextFu",
+        sizeof (WapTextFu),
+        sizeof (WapTextFuClass),
+        (GtkClassInitFunc) wap_textfu_class_init,
+        (GtkObjectInitFunc) wap_textfu_init,
+        /* reserved_1 */ NULL,
+        /* reserved_2 */ NULL,
+        (GtkClassInitFunc) NULL,
+      };
+
+      textfu_type = gtk_type_unique (gtk_layout_get_type (), &textfu_info);
+    }
+
+  return textfu_type;
+}
+
+static void
+wap_textfu_class_init (WapTextFuClass *klass)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+  GtkLayoutClass *layout_class;
+
+  link_url_attr_class.type = pango_attr_type_register("link_url");
+
+  object_class = (GtkObjectClass*) klass;
+
+  widget_class = (GtkWidgetClass*) klass;
+
+  layout_class = (GtkLayoutClass*) klass;
+
+  parent_class = gtk_type_class(g_type_parent(GTK_CLASS_TYPE(object_class)));
+
+  textfu_signals[LINK_FOLLOWED] = 
+    gtk_signal_new ("link_followed",
+                    GTK_RUN_FIRST,
+                    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (WapTextFuClass, link_followed),
+                    gtk_marshal_VOID__STRING,
+                    GTK_TYPE_NONE, 1, GTK_TYPE_STRING);
+  textfu_signals[ANCHOR_FOLLOWED] = 
+    gtk_signal_new ("anchor_followed",
+                    GTK_RUN_FIRST,
+                    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (WapTextFuClass, anchor_followed),
+                    gtk_marshal_VOID__POINTER,
+                    GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
+  textfu_signals[PREV_FOLLOWED] = 
+    gtk_signal_new ("prev_followed",
+                    GTK_RUN_FIRST,
+                    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (WapTextFuClass, prev_followed),
+                    gtk_marshal_VOID__VOID,
+                    GTK_TYPE_NONE, 0);
+  textfu_signals[LOAD_DONE] = 
+    gtk_signal_new ("load_done",
+                    GTK_RUN_FIRST,
+                    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (WapTextFuClass, load_done),
+                    gtk_marshal_VOID__VOID,
+                    GTK_TYPE_NONE, 0);
+  textfu_signals[LOAD_ERROR] = 
+    gtk_signal_new ("load_error",
+                    GTK_RUN_FIRST,
+                    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (WapTextFuClass, load_error),
+                    gtk_marshal_VOID__VOID,
+                    GTK_TYPE_NONE, 0);
+  textfu_signals[ACTIVATE_CARD] = 
+    gtk_signal_new ("activate_card",
+                    GTK_RUN_FIRST,
+                    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (WapTextFuClass, activate_card),
+                    gtk_marshal_VOID__POINTER,
+                    GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
+  textfu_signals[DEACTIVATE_CARD] = 
+    gtk_signal_new ("deactivate_card",
+                    GTK_RUN_FIRST,
+                    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (WapTextFuClass, deactivate_card),
+                    gtk_marshal_VOID__POINTER,
+                    GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
+
+
+  klass->tag_handlers = g_hash_table_new(g_str_hash, g_str_equal);
+
+#define IGNORE_TAG(x) wap_textfu_tagid_alloc(#x, tag_handler_ignore)
+#define ADD_HANDLER(x) wap_textfu_tagid_alloc(#x, tag_handler_##x)
+  ADD_HANDLER(a);
+  ADD_HANDLER(anchor);
+  ADD_HANDLER(b);
+  ADD_HANDLER(big);
+  ADD_HANDLER(br);
+  ADD_HANDLER(card);
+  ADD_HANDLER(do);
+  ADD_HANDLER(em);
+  ADD_HANDLER(go);
+  ADD_HANDLER(i);
+  ADD_HANDLER(img);
+  ADD_HANDLER(input);
+  ADD_HANDLER(option);
+  ADD_HANDLER(p);
+  ADD_HANDLER(postfield);
+  ADD_HANDLER(prev);
+  ADD_HANDLER(select);
+  ADD_HANDLER(small);
+  ADD_HANDLER(strong);
+  ADD_HANDLER(timer);
+  ADD_HANDLER(table);
+  ADD_HANDLER(tr);
+  ADD_HANDLER(td);
+  ADD_HANDLER(u);
+  ADD_HANDLER(wml);
+
+  /* HDML */
+  /* HDML <a> tag is handled too as part of wml handler */
+  ADD_HANDLER(action);
+  ADD_HANDLER(ce);
+  ADD_HANDLER(choice);
+  ADD_HANDLER(display);
+  ADD_HANDLER(entry);
+  ADD_HANDLER(hdml);
+
+  IGNORE_TAG(head);
+  IGNORE_TAG(template);
+
+  widget_class->realize = wap_textfu_realize;
+  widget_class->unrealize = wap_textfu_unrealize;
+  widget_class->size_request = wap_textfu_size_request;
+  widget_class->size_allocate = wap_textfu_size_allocate;
+  widget_class->expose_event = wap_textfu_expose;
+  widget_class->map = wap_textfu_map;
+  widget_class->motion_notify_event = wap_textfu_motion_notify_event;
+  widget_class->button_release_event = wap_textfu_button_release_event;
+  widget_class->key_press_event = wap_textfu_key_press_event;
+
+  layout_class->set_scroll_adjustments = wap_textfu_set_scroll_adjustments;
+}
+
+static void
+wap_textfu_init (WapTextFu *textfu)
+{
+  GTK_WIDGET_SET_FLAGS(GTK_WIDGET(textfu), GTK_CAN_FOCUS);
+  
+  gtk_widget_add_events(GTK_WIDGET(textfu),
+			GDK_EXPOSURE_MASK|GDK_POINTER_MOTION_MASK|GDK_BUTTON_RELEASE_MASK
+			|GDK_BUTTON_PRESS_MASK|GDK_BUTTON_MOTION_MASK
+			|GDK_KEY_PRESS_MASK|GDK_KEY_RELEASE_MASK);
+  textfu->tmp_text = g_string_new(NULL);
+  textfu->nc_text = g_string_new(NULL);
+  textfu->pango_ctx = gdk_pango_context_get();
+}
+
+GtkWidget *
+wap_textfu_new(void)
+{
+  GtkWidget *retval;
+
+  retval = gtk_widget_new(wap_textfu_get_type(), NULL);
+  gtk_layout_set_hadjustment(GTK_LAYOUT(retval), NULL);
+  gtk_layout_set_vadjustment(GTK_LAYOUT(retval), NULL);
+
+  return retval;
+}
+
+static void
+wap_textfu_map(GtkWidget *widget)
+{
+  if(parent_class->map)
+    parent_class->map(widget);
+}
+
+static void
+wap_textfu_realize(GtkWidget      *widget)
+{
+  WapTextFu *textfu = WAP_TEXTFU(widget);
+  GdkColor colr_white, colr_black;
+
+  if(parent_class->realize)
+    parent_class->realize(widget);
+
+  gdk_color_white(gdk_rgb_get_cmap(), &colr_white);
+  gdk_color_black(gdk_rgb_get_cmap(), &colr_black);
+  gdk_window_set_background(widget->window, &colr_white);
+  gdk_window_set_background(GTK_LAYOUT(widget)->bin_window, &colr_white);
+
+  textfu->drawing_gc = gdk_gc_new(GTK_LAYOUT(widget)->bin_window);
+  gdk_gc_copy(textfu->drawing_gc, widget->style->fg_gc[GTK_STATE_NORMAL]);
+  gdk_gc_set_foreground(textfu->drawing_gc, &colr_black);
+}
+
+static void
+wap_textfu_unrealize(GtkWidget      *widget)
+{
+  WapTextFu *textfu = WAP_TEXTFU(widget);
+
+  if(parent_class->unrealize)
+    parent_class->unrealize(widget);
+
+  gdk_gc_unref(textfu->drawing_gc);
+}
+
+/* Multipurpose - either gets bounding box or does a redraw */
+static void
+wap_textfu_get_anchor_vbounds(WapTextFu *textfu, WapParagraphInfo *para, WapAnchorInfo *wai, int *starty, int *endy)
+{
+  PangoAttribute *attr;
+  PangoRectangle r;
+  int y1, y2;
+
+  attr = wai->attr;
+
+  pango_layout_index_to_pos(para->layout, attr->start_index, &r);
+  y1 = r.y;
+  y2 = r.y+r.height;
+
+  pango_layout_index_to_pos(para->layout, attr->end_index, &r);
+  y1 = MIN(y1, r.y);
+  y2 = MAX(y2, r.y+r.height);
+
+  if(starty)
+    *starty = PANGO_PIXELS(y1) + para->y_offset;
+  if(endy)
+    *endy = PANGO_PIXELS(y2) + para->y_offset;
+}
+
+static void
+wap_textfu_redraw_anchor(WapTextFu *textfu, WapParagraphInfo *para, WapAnchorInfo *wai)
+{
+  PangoAttribute *attr;
+  PangoRectangle r;
+  GSList *lines;
+  int i, n;
+
+  attr = wai->attr;
+
+  /* This is essentially the hypothetical pango_layout_range_get_extents() with some redrawing code thrown in */
+  for(i = n = 0, lines = pango_layout_get_lines(para->layout); lines && i < attr->end_index; lines = lines->next, n++)
+    {
+      PangoLayoutLine *line = lines->data;
+
+      if((i + line->length) > attr->start_index
+	 && i < attr->end_index)
+	{
+	  GdkRectangle redrawrect;
+	  GdkSegment seg;
+	  int line_start_idx, line_end_idx;
+
+	  line_start_idx = MAX(i, attr->start_index);
+	  pango_layout_index_to_pos(para->layout, line_start_idx, &r);
+	  seg.x1 = r.x;
+	  seg.y1 = r.y;
+	  seg.x2 = r.x+r.width;
+	  seg.y2 = r.y+r.height;
+
+	  line_end_idx = MIN(i + line->length - 1, attr->end_index);
+	  pango_layout_index_to_pos(para->layout, line_end_idx, &r);
+	  seg.x1 = MIN(seg.x1, r.x);
+	  seg.y1 = MIN(seg.y1, r.y);
+	  seg.x2 = MAX(seg.x2, r.x+r.width);
+	  seg.y2 = MAX(seg.y2, r.y+r.height);
+
+	  redrawrect.x = PANGO_PIXELS(seg.x1) + para->left_indent;
+	  redrawrect.y = PANGO_PIXELS(seg.y1) + para->y_offset;
+	  redrawrect.width = PANGO_PIXELS(seg.x2 - seg.x1);
+	  redrawrect.height = PANGO_PIXELS(seg.y2 - seg.y1);
+
+	  gdk_window_invalidate_rect(GTK_LAYOUT(textfu)->bin_window, &redrawrect, TRUE);
+	}
+
+      i += line->length;
+    }
+}
+
+static void
+wap_textfu_unselect_anchor(WapTextFu *textfu)
+{
+  WapAnchorInfo *wai;
+  LinkURLAttr *attr;
+  PangoAttrColor *bgcolor, *fgcolor;
+
+  g_return_if_fail(textfu->active_card->active_anchor);
+
+  wai = textfu->active_card->active_anchor;
+  attr = wai->attr;
+  bgcolor = (PangoAttrColor *)attr->bg_color_attr;
+  bgcolor->color.red = bgcolor->color.green = bgcolor->color.blue = 65535;
+
+  fgcolor = (PangoAttrColor *)attr->fg_color_attr;
+  fgcolor->color.red = fgcolor->color.green = 0;
+  fgcolor->color.blue = 65535;
+
+  textfu->active_card->active_anchor = NULL;
+  pango_layout_set_attributes(textfu->active_card->active_anchor_para->layout, textfu->active_card->active_anchor_para->attrs);
+  wap_textfu_redraw_anchor(textfu, textfu->active_card->active_anchor_para, wai);
+}
+
+static void
+wap_textfu_select_anchor(WapTextFu *textfu, WapParagraphInfo *para, WapAnchorInfo *wai)
+{
+  LinkURLAttr *attr;
+  PangoAttrColor *bgcolor, *fgcolor;
+
+  if(wai == textfu->active_card->active_anchor)
+    return;
+
+  if(textfu->active_card->active_anchor)
+    wap_textfu_unselect_anchor(textfu);
+
+  attr = wai->attr;
+  bgcolor = (PangoAttrColor *)attr->bg_color_attr;
+  bgcolor->color.red = bgcolor->color.green = 0; bgcolor->color.blue = 65535;
+
+  fgcolor = (PangoAttrColor *)attr->fg_color_attr;
+  fgcolor->color.red = fgcolor->color.green = fgcolor->color.blue = 65535;
+
+  textfu->active_card->active_anchor = wai;
+  textfu->active_card->active_anchor_para = para;
+  pango_layout_set_attributes(textfu->active_card->active_anchor_para->layout, textfu->active_card->active_anchor_para->attrs);
+  wap_textfu_redraw_anchor(textfu, textfu->active_card->active_anchor_para, wai);
+}
+
+static void
+wap_textfu_activate_anchor(WapTextFu *textfu, WapAnchorInfo *wai)
+{
+  gtk_signal_emit(GTK_OBJECT(textfu), textfu_signals[ANCHOR_FOLLOWED], wai);
+}
+
+static void
+wap_textfu_find_anchor(WapTextFu *textfu, gint evx, gint evy, WapAnchorInfo **wai, WapParagraphInfo **para)
+{
+  GList *ltmp;
+  int y_sum = BASIC_INDENT;
+  GtkLayout *layout;
+  int event_x, event_y, px, py;
+  gboolean trailing;
+  int idx;
+
+  layout = GTK_LAYOUT(textfu);
+  event_x = evx + layout->xoffset;
+  event_y = evy + layout->yoffset;
+
+  for(*wai = NULL, *para = NULL, ltmp = textfu->active_card->paragraphs; y_sum < event_y && ltmp; ltmp = ltmp->next)
+    {
+      WapParagraphInfo *check_para = ltmp->data;
+
+      if(event_y < (check_para->y_offset + check_para->height) && event_y >= y_sum)
+	{
+	  *para = check_para;
+	  break;
+	}
+
+      y_sum = check_para->y_offset + check_para->height + check_para->space_after;
+    }
+
+  if(!*para)
+    return;
+
+  /* Now, para is the paragraph that was clicked on and y_sum is the offset of the start of the paragraph */
+  trailing = FALSE;
+  px = PANGO_SCALE*(event_x - (*para)->left_indent);
+  py = PANGO_SCALE*(event_y - (*para)->y_offset);
+  if(px < 0 || !pango_layout_xy_to_index((*para)->layout, px, py, &idx, &trailing))
+    return;
+
+  g_print("pango says the event [%d, %d] is at index %d of paragraph %p\n", px, py, idx, *para);
+
+  {
+    PangoAttrIterator *iter;
+    PangoAttribute *attr = NULL;
+    int rstart, rend;
+
+    iter = pango_attr_list_get_iterator((*para)->attrs);
+    rstart = rend = -1;
+    for(pango_attr_iterator_range(iter, &rstart, &rend);
+	(idx > rend || idx < rstart) && pango_attr_iterator_next(iter);
+	pango_attr_iterator_range(iter, &rstart, &rend));
+
+    if(idx >= rstart && idx <= rend)
+      attr = pango_attr_iterator_get(iter, link_url_attr_class.type);
+
+    pango_attr_iterator_destroy(iter);
+
+    if(attr)
+      {
+	LinkURLAttr *lua;
+	lua = (LinkURLAttr *)attr;
+	*wai = lua->wai;
+      }
+  }
+}
+
+static gint
+wap_textfu_button_release_event(GtkWidget *widget, GdkEventButton *event)
+{
+  WapTextFu *textfu = WAP_TEXTFU(widget);
+  WapAnchorInfo *wai;
+  WapParagraphInfo *para;
+
+  if(event->window != GTK_LAYOUT(widget)->bin_window
+     || !textfu->active_card
+     || event->type != GDK_BUTTON_RELEASE)
+    goto default_handling;
+
+  wap_textfu_find_anchor(textfu, event->x, event->y, &wai, &para);
+  if(wai)
+    {
+      wap_textfu_select_anchor(textfu, para, wai);
+      wap_textfu_activate_anchor(textfu, wai);
+    }
+
+ default_handling:
+  if(parent_class->button_release_event)
+    return parent_class->button_release_event(widget, event);
+  else
+    return wai?TRUE:FALSE;
+}
+
+static gint
+wap_textfu_motion_notify_event(GtkWidget *widget, GdkEventMotion *event)
+{
+  if(event->window != GTK_LAYOUT(widget)->bin_window)
+    goto default_handling;
+
+  /* Don't handle mouseovers for now... */
+#if 0
+  gpointer info = NULL;
+  if((info && TRUE) != textfu->linkpoint_cursor)
+    {
+      GdkCursor *set_new_cursor;
+
+      textfu->linkpoint_cursor = info && TRUE;
+
+      if(info)
+	{
+	  if(!cursor_hand)
+	    cursor_hand = /* wap_stock_cursor_new(WAP_STOCK_CURSOR_POINTING_HAND) */ NULL;
+	  set_new_cursor = cursor_hand;
+	}
+      else
+	set_new_cursor = NULL;
+
+      gdk_window_set_cursor(GTK_LAYOUT(widget)->bin_window, set_new_cursor);
+    }
+#endif
+
+ default_handling:
+  if(parent_class->motion_notify_event)
+    return parent_class->motion_notify_event(widget, event);
+  else
+    return FALSE;
+}
+
+static GList *
+wap_textfu_paragraphs_in_viewport(WapTextFu *textfu)
+{
+  GList *ltmp, *retval;
+  int vstart, vend, y;
+
+  y = GTK_LAYOUT(textfu)->vadjustment->value;
+  vstart = y - MAX_SCROLL_AMT;
+  vend = y + GTK_WIDGET(textfu)->allocation.height + MAX_SCROLL_AMT;
+
+  for(retval = NULL, ltmp = textfu->active_card->paragraphs; ltmp; ltmp = ltmp->next)
+    {
+      WapParagraphInfo *para = ltmp->data;
+
+      if((para->y_offset + para->height) < vstart)
+	continue;
+      if(para->y_offset > vend)
+	break;
+
+      retval = g_list_append(retval, para);
+    }
+
+  return retval;
+}
+
+static void
+wap_textfu_pick_anchor(WapTextFu *textfu, gboolean is_next)
+{
+  GList *ltmp = NULL, *piv = NULL;
+  WapAnchorInfo *wai = NULL;
+  WapParagraphInfo *para = NULL;
+  gint scroll_amount = 0;
+  GList *ltmp2 = NULL;
+  int y1, y2;
+  int vstart, vend;
+
+  vstart = vend = GTK_LAYOUT(textfu)->vadjustment->value;
+  vend += GTK_WIDGET(textfu)->allocation.height;
+
+  piv = wap_textfu_paragraphs_in_viewport(textfu);
+
+  if(textfu->active_card->active_anchor)
+    {
+      ltmp = g_list_find(piv, textfu->active_card->active_anchor_para);
+      if(ltmp)
+	{
+	  ltmp2 = g_list_find(textfu->active_card->active_anchor_para->anchors, textfu->active_card->active_anchor);
+	  if(ltmp2)
+	    ltmp2 = is_next?ltmp2->next:ltmp2->prev;
+	  if(!ltmp2)
+	    ltmp = is_next?ltmp->next:ltmp->prev;
+	  if(!ltmp)
+	    goto out; /* nothing prev/next to go to - just scroll things */
+	}
+    }
+
+    /* If user presses 'up' w/o selected link then we pick the last visible link on the page */
+
+  if(!ltmp)
+    {
+      if(is_next)
+	ltmp = piv;
+      else
+	ltmp = g_list_last(piv);
+    }
+
+  for(; ltmp; ltmp = is_next?ltmp->next:ltmp->prev)
+    {
+      WapParagraphInfo *check_para = ltmp->data;
+
+      if(!ltmp2)
+	ltmp2 = is_next?check_para->anchors:g_list_last(check_para->anchors);
+
+      for(; ltmp2; ltmp2 = is_next?ltmp2->next:ltmp2->prev)
+	{
+	  WapAnchorInfo *check_wai = ltmp2->data;
+
+	  wap_textfu_get_anchor_vbounds(textfu, check_para, check_wai, &y1, &y2);
+
+	  if((is_next && (y1 > (vstart - MAX_SCROLL_AMT)))
+	     || (!is_next && (y2 < (vend+MAX_SCROLL_AMT))))
+	    {
+	      para = check_para;
+	      wai = check_wai;
+	      goto out;
+	    }
+	}
+    }
+ out:
+
+  if(wai)
+    {
+      if(is_next)
+	scroll_amount = MAX(y2 - vend, 0);
+      else
+	scroll_amount = MIN(y1 - vstart, 0);
+    }
+  if(!wai || abs(scroll_amount) > MAX_SCROLL_AMT)
+    {
+      scroll_amount = is_next?MAX_SCROLL_AMT:-MAX_SCROLL_AMT;
+      wai = NULL;
+    }
+
+  if(scroll_amount)
+    gtk_adjustment_set_value(GTK_LAYOUT(textfu)->vadjustment,
+			     CLAMP(GTK_LAYOUT(textfu)->vadjustment->value + scroll_amount,
+				   GTK_LAYOUT(textfu)->vadjustment->lower,
+				   GTK_LAYOUT(textfu)->vadjustment->upper - GTK_WIDGET(textfu)->allocation.height));
+
+  if(wai)
+    wap_textfu_select_anchor(textfu, para, wai);
+
+  g_list_free(piv);
+}
+
+static void
+wap_textfu_handle_external_scrolling(GtkAdjustment *adjustment, WapTextFu *textfu)
+{
+  /* If someone uses scroll bars to move the view we need to handle the interaction with the active_anchor stuff.
+     For now, just deselect it if it is offscreen. */
+
+  if(textfu->active_card
+     && textfu->active_card->active_anchor)
+    {
+      int y1, y2;
+
+      wap_textfu_get_anchor_vbounds(textfu, textfu->active_card->active_anchor_para,
+				   textfu->active_card->active_anchor, &y1, &y2);
+
+      if(y2 < GTK_LAYOUT(textfu)->vadjustment->value
+	 || y1 > (GTK_LAYOUT(textfu)->vadjustment->value + GTK_WIDGET(textfu)->allocation.height))
+	wap_textfu_unselect_anchor(textfu);
+    }
+}
+
+static gint
+wap_textfu_key_press_event(GtkWidget *widget, GdkEventKey *event)
+{
+  WapTextFu *textfu = textfu = WAP_TEXTFU(widget);
+  gboolean gotit = FALSE;
+
+  if(!textfu->active_card)
+    goto default_handling;
+
+  gotit = TRUE;
+  /* We basically handle scrolling keys and Enter */
+  switch(event->keyval)
+    {
+    case GDK_Return:
+    case GDK_KP_Enter:
+    case GDK_Right:
+    case GDK_KP_Right:
+      if(textfu->active_card->active_anchor)
+	wap_textfu_activate_anchor(textfu, textfu->active_card->active_anchor);
+      break;
+    case GDK_Left:
+    case GDK_KP_Left:
+      gtk_signal_emit(GTK_OBJECT(textfu), textfu_signals[PREV_FOLLOWED]);
+      break;
+    case GDK_Up:
+    case GDK_KP_Up:
+      wap_textfu_pick_anchor(textfu, FALSE);
+      break;
+    case GDK_Down:
+    case GDK_KP_Down:
+      wap_textfu_pick_anchor(textfu, TRUE);
+      break;
+    default:
+      gotit = FALSE;
+      break;
+    }
+
+ default_handling:
+  if(!gotit && parent_class->key_press_event)
+    return parent_class->key_press_event(widget, event);
+  else
+    return gotit;
+}
+
+static void
+wap_textfu_size_request(GtkWidget      *widget,
+			  GtkRequisition *requisition)
+{
+  WapTextFu *textfu = textfu = WAP_TEXTFU(widget);
+
+  if(parent_class->size_request)
+    parent_class->size_request(widget, requisition);
+}
+
+static void
+wap_textfu_redraw(GtkWidget *widget)
+{
+  GdkRectangle redraw_me;
+
+  if(!GTK_LAYOUT(widget)->bin_window)
+    return;
+
+  redraw_me.x = GTK_LAYOUT(widget)->hadjustment->value;
+  redraw_me.y = GTK_LAYOUT(widget)->vadjustment->value;
+  redraw_me.width = widget->allocation.width;
+  redraw_me.height = widget->allocation.height;
+  gdk_window_invalidate_rect(GTK_LAYOUT(widget)->bin_window, &redraw_me, TRUE);
+}
+
+static void
+wap_textfu_size_allocate(GtkWidget      *widget,
+			 GtkAllocation  *allocation)
+{
+  WapTextFu *textfu;
+
+  textfu = WAP_TEXTFU(widget);
+
+  if(allocation->x == widget->allocation.x
+     && allocation->y == widget->allocation.y
+     && allocation->width == widget->allocation.width
+     && allocation->height == widget->allocation.height
+     && textfu->old_width == allocation->width)
+    return; /* Nothing to do here */
+
+  if(parent_class->size_allocate)
+    parent_class->size_allocate(widget, allocation);
+
+  if(textfu->old_width != allocation->width)
+    {
+      /* Relayout */
+      gint fu_height = BASIC_INDENT;
+      GList *ltmp;
+      int n;
+
+      if(textfu->active_card)
+	for(n = 0, ltmp = textfu->active_card->paragraphs; ltmp; ltmp = ltmp->next, n++)
+	  {
+	    WapParagraphInfo *para = ltmp->data;
+	    int pwid, pheight;
+	    /* Move old placed items off-screen */
+	    GList *ltmp2;
+
+	    for(ltmp2 = para->placed_items; ltmp2; ltmp2 = ltmp2->next)
+	      {
+		PlacedItem *pl = ltmp2->data;
+		PangoAttrShape *sa;
+
+		sa = (PangoAttrShape *)pl->shape_attr;
+		sa->ink_rect.width = sa->logical_rect.width = pl->widget->allocation.width * PANGO_SCALE;
+		sa->ink_rect.height = sa->logical_rect.height = pl->widget->allocation.height * PANGO_SCALE;
+		sa->ink_rect.y = sa->logical_rect.y = -(sa->ink_rect.height * pl->alignment);
+		sa->ink_rect.x = sa->logical_rect.x = 0;
+	      }
+
+	    pango_layout_set_width(para->layout, (allocation->width - (para->left_indent+para->right_indent))*PANGO_SCALE);
+
+	    pango_layout_get_pixel_size(para->layout, &pwid, &pheight);
+
+	    for(ltmp2 = para->placed_items; ltmp2; ltmp2 = ltmp2->next)
+	      {
+		PlacedItem *pl = ltmp2->data;
+		PangoRectangle rect;
+
+		pango_layout_index_to_pos(para->layout, pl->shape_attr->start_index, &rect);
+		rect.x = PANGO_PIXELS(rect.x);
+		rect.y = PANGO_PIXELS(rect.y);
+		rect.width = PANGO_PIXELS(rect.width);
+		rect.height = PANGO_PIXELS(rect.height);
+		g_print("moving %p to [%d, %d]\n",
+			pl->widget,
+			rect.x + para->left_indent,
+			rect.y + fu_height);
+		gtk_layout_move(GTK_LAYOUT(textfu), pl->widget, rect.x + para->left_indent, rect.y + fu_height);
+	      }
+
+	    para->y_offset = fu_height;
+	    para->height = pheight;
+
+	    fu_height += pheight + para->space_after;
+	  }
+      fu_height += BASIC_INDENT;
+
+      gtk_layout_set_size(GTK_LAYOUT(widget), GTK_LAYOUT(widget)->width, fu_height);
+      textfu->old_width = allocation->width;
+      wap_textfu_redraw(widget);
+    }
+}
+
+static void
+wap_textfu_set_scroll_adjustments(GtkLayout      *layout,
+				  GtkAdjustment  *hadjustment,
+				  GtkAdjustment  *vadjustment)
+{
+  WapTextFu *textfu = WAP_TEXTFU(layout);
+
+  if(textfu->vscroll_tag)
+    gtk_signal_disconnect(GTK_OBJECT(layout->vadjustment), textfu->vscroll_tag);
+
+  textfu->vscroll_tag = gtk_signal_connect(GTK_OBJECT(vadjustment), "value_changed",
+					   GTK_SIGNAL_FUNC(wap_textfu_handle_external_scrolling),
+					   textfu);
+
+  if(GTK_LAYOUT_CLASS(parent_class)->set_scroll_adjustments)
+    GTK_LAYOUT_CLASS(parent_class)->set_scroll_adjustments(layout, hadjustment, vadjustment);
+}
+
+static void
+wap_textfu_draw(GtkWidget      *widget, 
+		GdkRectangle   *area)
+{
+  GList *ltmp;
+  int y;
+  WapTextFu *textfu;
+  GtkLayout *layout;
+  int view_start, view_end;
+  GdkRectangle myrect;
+  int n;
+
+  textfu = WAP_TEXTFU(widget);
+  layout = GTK_LAYOUT(widget);
+
+  if(!textfu->active_card
+     || textfu->old_width != widget->allocation.width)
+    return;
+
+  myrect = *area;
+  myrect.x += layout->xoffset;
+  myrect.y += layout->yoffset;
+  gdk_gc_set_clip_rectangle(textfu->drawing_gc, &myrect);
+
+  view_start = area->y + layout->yoffset;
+  view_end = area->y + area->height + layout->yoffset;
+
+  for(n = 0, y = BASIC_INDENT, ltmp = textfu->active_card->paragraphs; ltmp && y < view_end; ltmp = ltmp->next, n++)
+    {
+      WapParagraphInfo *para = ltmp->data;
+
+      y = para->y_offset;
+      if((y + para->height) >= view_start)
+	 gdk_draw_layout(GTK_LAYOUT(widget)->bin_window, textfu->drawing_gc,
+			 para->left_indent + layout->xoffset, y + layout->yoffset,
+			 para->layout);
+
+      y = para->y_offset + para->height + para->space_after;
+    }
+}
+
+static gint
+wap_textfu_expose(GtkWidget      *widget, 
+		  GdkEventExpose *event)
+{
+  if(parent_class->expose_event)
+    parent_class->expose_event(widget, event);
+
+  if(event->window == GTK_LAYOUT(widget)->bin_window)
+    wap_textfu_draw(widget, &event->area);
+
+  return TRUE;
+}
+
+/* libxml handlers  */
+
+static void
+wml_startDocument(void *ctx)
+{
+}
+
+static void
+wml_endDocument(void *ctx)
+{
+}
+
+static void
+wml_startElement(void *ctx, const xmlChar *name,
+		 const xmlChar **atts)
+{
+  WapTextFu *textfu = WAP_TEXTFU(ctx);
+  TagRegistration *tr;
+  WapTextFuClass *klass;
+  gchar *lowercase_name;
+
+  lowercase_name = g_strdup (name);
+  g_strdown(lowercase_name);
+  klass = WAP_TEXTFU_CLASS(gtk_type_class(wap_textfu_get_type()));
+
+  tr = g_hash_table_lookup(klass->tag_handlers, lowercase_name);
+  g_free(lowercase_name);
+  if(!tr)
+    return;
+
+  if(textfu->ignore_counter > 0
+     && tr->handler != tag_handler_ignore)
+    return;
+
+  tr->handler(textfu, name, tr->tag_id, (char **)atts, FALSE);
+}
+
+static void
+wml_endElement(void *ctx, const xmlChar *name)
+{
+  WapTextFu *textfu = WAP_TEXTFU(ctx);
+  TagRegistration *tr;
+  WapTextFuClass *klass;
+  gchar *lowercase_name;
+
+  lowercase_name = g_strdup (name);
+  g_strdown(lowercase_name);
+  klass = WAP_TEXTFU_CLASS(gtk_type_class(wap_textfu_get_type()));
+
+  tr = g_hash_table_lookup(klass->tag_handlers, lowercase_name);
+  g_free(lowercase_name);
+  if(!tr)
+     return;
+
+  if(textfu->ignore_counter > 0
+     && tr->handler != tag_handler_ignore)
+    return;
+
+    tr->handler(textfu, name, tr->tag_id, NULL, TRUE);
+}
+
+static void
+wml_characters(void *ctx, const xmlChar *ch,
+	       int len)
+{
+  WapTextFu *textfu = WAP_TEXTFU(ctx);
+  GString *str;
+  gboolean head_space = FALSE, tail_space = FALSE;
+  gboolean do_initiate = FALSE;
+
+  if(textfu->ignore_counter > 0)
+    return;
+
+  if(textfu->in_content)
+    {
+      do_initiate = TRUE;
+
+      str = textfu->tmp_text;
+    }
+  else
+    {
+      str = textfu->nc_text;
+    }
+
+  while(len > 0 && my_isspace(*ch))
+    {
+      ch++;
+      len--;
+      head_space = TRUE;
+    }
+  while(len > 0 && my_isspace(ch[len-1]))
+    {
+      len--;
+      tail_space = TRUE;
+    }
+
+  if(len > 0)
+    {
+      int i;
+      gboolean prev_was_space = FALSE;
+
+      if(do_initiate)
+	initiate_para(textfu);
+
+      if(str->len > 0
+	 && !my_isspace(str->str[str->len-1])
+	 && head_space)
+	g_string_append_c(str, ' ');
+
+      /* XXX fixme slow */
+      for(i = 0; i < len; i++)
+	{
+	  gboolean this_is_space = my_isspace(ch[i]);
+	  char nc;
+
+	  if(this_is_space)
+	    nc = ' ';
+	  else
+	    nc = ch[i];
+
+	  if(!(this_is_space && prev_was_space))
+	    g_string_append_c(str, nc);
+
+	  prev_was_space = this_is_space;
+	}
+
+      if(tail_space)
+	g_string_append_c(str, ' ');
+    }
+}
+
+
+static void
+wml_error(void *ctx, const char *msg, ...)
+{
+  /* WapTextFu *textfu = WAP_TEXTFU(ctx); */
+  va_list args;
+
+  va_start(args, msg);
+  vprintf(msg, args);
+  va_end(args);
+
+/*    xml_ctxt_done(NULL, WAP_STREAM_ERROR, textfu); */
+}
+
+static void
+wml_fatalError(void *ctx, const char *msg, ...)
+{
+  /* WapTextFu *textfu = WAP_TEXTFU(ctx); */
+  va_list args;
+
+  va_start(args, msg);
+  vprintf(msg, args);
+  va_end(args);
+
+/*    xml_ctxt_done(NULL, WAP_STREAM_ERROR, textfu); */
+}
+
+static xmlSAXHandler wml_handler = {
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  wml_startDocument,
+  wml_endDocument,
+  wml_startElement,
+  wml_endElement,
+  NULL,
+  wml_characters,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  wml_error,
+  wml_fatalError,
+  NULL,
+  NULL
+};
+
+#if 0
+static void
+xml_ctxt_start (WapStreamHandle stream,
+		const char *mime_type,
+		gpointer user_data)
+{
+#if 0
+  /* Can diff between HDML & WML here, eventually */
+  if(strcmp(mime_type, "text/vnd.wap.wml"))
+    /*      xml_ctxt_done(stream, WAP_STREAM_ERROR, user_data)*/ ;
+#endif
+}
+
+static void xml_ctxt_done(int handle, int status, gpointer user_data)
+{
+
+}
+
+static void
+xml_ctxt_write(WapStreamHandle handle, const guchar *buffer, size_t size, gpointer user_data)
+{
+  WapTextFu *textfu = user_data;
+
+  if(!textfu->doc_stream)
+    return;
+
+  xmlParseChunk(textfu->ctxt, buffer, size, 0);
+}
+#endif
+
+static void
+placed_item_free(PlacedItem *pi)
+{
+  gtk_container_remove(GTK_CONTAINER(pi->widget->parent), pi->widget);
+  g_free(pi);
+}
+
+static void
+wap_go_free(WapGoInfo *go)
+{
+  g_free(go->url);
+  g_free(go->charset); 
+  g_list_foreach(go->postvalues, (GFunc)g_free, NULL);
+  g_list_free(go->postvalues);
+  g_free(go);
+}
+
+static void
+wap_anchor_free(WapAnchorInfo *wai)
+{
+  g_free(wai->title);
+  if(wai->go_info)
+    wap_go_free(wai->go_info);
+  g_list_foreach(wai->setvars, (GFunc)g_free, NULL);
+  g_list_free(wai->setvars);
+  g_free(wai);
+}
+
+static void
+wap_paragraph_free(WapParagraphInfo *para)
+{
+  g_object_unref(G_OBJECT(para->layout));
+
+  g_list_foreach(para->anchors, (GFunc)wap_anchor_free, NULL);
+  g_list_free(para->anchors);
+
+  g_list_foreach(para->placed_items, (GFunc)placed_item_free, NULL);
+  g_list_free(para->placed_items);
+
+  g_free(para);
+}
+
+static void
+wap_action_free(WapDoInfo *doi)
+{
+  if(doi->go)
+    wap_go_free(doi->go);
+  g_free(doi->label);
+  g_free(doi->name);
+  if(doi->img)
+    gtk_widget_unref(doi->img);
+  g_free(doi);
+}
+
+static void
+wap_option_free(WapOptionInfo *option)
+{
+  g_free(option->text);
+  g_free(option->onpick);
+  g_free(option);
+}
+
+static void
+wap_input_free(WapInputInfo *input)
+{
+  g_free(input->name);
+  g_free(input->title);
+  g_free(input->value);
+  g_free(input->fmt);
+  g_free(input->iname);
+
+  g_list_foreach(input->options, (GFunc)wap_option_free, NULL);
+  g_list_free(input->options);
+
+  g_free(input);
+}
+
+static void
+wap_card_free(WapCard *card)
+{
+  g_list_foreach(card->paragraphs, (GFunc)wap_paragraph_free, NULL);
+  g_list_free(card->paragraphs);
+  g_list_foreach(card->actions, (GFunc)wap_action_free, NULL);
+  g_list_free(card->actions);
+  g_list_foreach(card->inputs, (GFunc)wap_input_free, NULL);
+  g_list_free(card->inputs);
+
+  g_free(card->id);
+  g_free(card->title);
+  g_free(card->onenterforward);
+  g_free(card->onenterbackward);
+  g_free(card->ontimer);
+
+  g_assert(!card->para_style_stack);
+  g_assert(!card->text_style_stack);
+  g_free(card);
+}
+
+static void
+wap_textfu_cleanup_page(WapTextFu *textfu)
+{
+  g_free(textfu->cur_filename);
+  textfu->cur_filename = NULL;
+  if(textfu->active_card)
+    gtk_signal_emit(GTK_OBJECT(textfu), textfu_signals[DEACTIVATE_CARD], textfu->active_card);
+  textfu->cur_card = textfu->active_card = NULL;
+  textfu->cur_go = NULL;
+  textfu->cur_do = NULL;
+  textfu->cur_anchor = NULL;
+  textfu->cur_input = NULL;
+  textfu->cur_option = NULL;
+  g_string_truncate(textfu->tmp_text, 0);
+  g_string_truncate(textfu->nc_text, 0);
+  g_list_foreach(textfu->cards, (GFunc)wap_card_free, NULL);
+  g_list_free(textfu->cards); textfu->cards = NULL;
+}
+
+static GList *
+wap_textfu_copy_postvalues(GList *postvalues)
+{
+  GList *retval = NULL;
+
+  for(postvalues = g_list_last(postvalues); postvalues; postvalues = postvalues->prev)
+    retval = g_list_prepend(retval, g_strdup(postvalues->data));
+
+  return retval;
+}
+
+static GList *
+wap_textfu_build_postvalues(WapTextFu *textfu)
+{
+  GList *retval, *ltmp;
+
+  for(ltmp = textfu->active_card->inputs, retval = NULL; ltmp; ltmp = ltmp->next)
+    {
+      WapInputInfo *input = ltmp->data;
+      PlacedItem *item = input->placed_item;
+
+      if(input->is_selection)
+	{
+	  if(GTK_IS_LIST(item->widget))
+	    {
+	      GList *selection;
+
+	      for(selection = GTK_LIST(item->widget)->selection; selection; selection = selection->next)
+		{
+		  WapOptionInfo *option = gtk_object_get_data(GTK_OBJECT(selection->data), "WapOptionInfo");
+
+		  retval = g_list_prepend(retval, g_strdup(option->value?option->value:option->text));
+		  retval = g_list_prepend(retval, g_strdup(input->name));
+		}
+	    }
+	  else
+	    g_assert_not_reached();
+	}
+      else
+	{
+	  retval = g_list_prepend(retval, g_strdup(gtk_entry_get_text(GTK_ENTRY(item->widget))));
+	  retval = g_list_prepend(retval, g_strdup(input->name));
+	}
+    }
+
+  return retval;
+}
+
+static char *
+wap_textfu_get_var(WapTextFu *textfu, const char *varname, int n)
+{
+  GList *l;
+  WapInputInfo *input;
+  PlacedItem *item;
+
+  g_assert(varname[0] == '$');
+  varname++;
+  if(varname[0] == '(')
+    {
+      varname++;
+      n--;
+    }
+
+  printf("checking for variable %.*s\n", n, varname);
+  for(l = textfu->active_card->inputs; l; l = l->next)
+    {
+      input = l->data;
+
+      if(!strncasecmp(input->name, varname, n))
+	break;
+    }
+  if(!l)
+    return NULL;
+
+  item = input->placed_item;
+  if(input->is_selection)
+    {
+      g_assert(!input->multiple);
+
+      if(GTK_IS_LIST(item->widget))
+	{
+	  GList *selection;
+
+	  for(selection = GTK_LIST(item->widget)->selection; selection; selection = selection->next)
+	    {
+	      WapOptionInfo *option = gtk_object_get_data(GTK_OBJECT(selection->data), "WapOptionInfo");
+
+	      return g_strdup(option->value?option->value:option->text);
+	    }
+	}
+      else
+	g_assert_not_reached();
+    }
+
+  return g_strdup(gtk_entry_get_text(GTK_ENTRY(item->widget)));
+}
+
+static char *
+wap_textfu_subst_vars(WapTextFu *textfu, char *str)
+{
+  char *ctmp, *retval, *varnamestart;
+  GString *build;
+  int i;
+
+  build = g_string_new(NULL);
+  for(i = 0, varnamestart = NULL; str[i]; i++)
+    {
+      if(varnamestart)
+	{
+	  if(!isalnum(str[i])
+	     && (str[i] != '('
+		 || (str+i-varnamestart) > 1))
+	    {
+	      ctmp = wap_textfu_get_var(textfu, varnamestart, str+i-varnamestart-1);
+	      if(ctmp)
+		g_string_append(build, ctmp);
+	      g_free(ctmp);
+	      if(!ctmp)
+		g_string_append_len(build, varnamestart, str+i-varnamestart);
+	      varnamestart = NULL;
+	    }
+	}
+      else if(str[i] == '$')
+	{
+	  varnamestart = str + i;
+	}
+      else
+	g_string_append_c(build, str[i]);
+    }
+  if(varnamestart)
+    {
+      ctmp = wap_textfu_get_var(textfu, varnamestart, strlen(varnamestart));
+      if(ctmp)
+	g_string_append(build, ctmp);
+      else
+	g_string_append(build, varnamestart);
+      g_free(ctmp);
+    }
+
+  retval = build->str;
+  g_string_free(build, FALSE);
+
+  g_print("var substitution results in '%s'\n", retval);
+
+  return retval;
+}
+
+void
+wap_textfu_load_go_info(WapTextFu *textfu, WapGoInfo *go)
+{
+  GList *postvalues = NULL;
+  char *real_url;
+
+  g_return_if_fail (textfu != NULL);
+  g_return_if_fail (WAP_IS_TEXTFU (textfu));
+
+  /* out with old */
+  real_url = wap_textfu_subst_vars(textfu, go->url);
+
+  if(textfu->active_card && go->post_method)
+    postvalues = wap_textfu_build_postvalues(textfu);
+
+  wap_textfu_cleanup_page(textfu);
+  GTK_LAYOUT(textfu)->vadjustment->upper = 0;
+  GTK_LAYOUT(textfu)->hadjustment->upper = 0;
+  GTK_LAYOUT(textfu)->vadjustment->value = 0;
+  GTK_LAYOUT(textfu)->hadjustment->value = 0;
+  gtk_adjustment_changed(GTK_LAYOUT(textfu)->vadjustment);
+  gtk_adjustment_changed(GTK_LAYOUT(textfu)->hadjustment);
+  textfu->old_width = 0; /* Force resize */
+  wap_textfu_redraw(GTK_WIDGET(textfu));
+
+  /* in with new */
+  textfu->ctxt = xmlCreatePushParserCtxt(&wml_handler, textfu, NULL, 0, NULL);
+  textfu->cur_filename = real_url;
+  textfu->in_content = FALSE;
+
+  if(go->post_method)
+     postvalues = g_list_concat(postvalues, wap_textfu_copy_postvalues(go->postvalues));
+
+}
+
+void
+wap_textfu_load_file(WapTextFu *textfu, const char *file)
+{
+  WapGoInfo go;
+
+  memset(&go, 0, sizeof(go));
+  go.url = (char *)file;
+  go.sendreferer = TRUE;
+  wap_textfu_load_go_info(textfu, &go);
+}
+
+typedef struct {
+  WapTimerInfo *timer;
+  WapTextFu *textfu;
+} TimerCallbackInfo;
+
+static gboolean
+wap_textfu_timer_cb(gpointer data)
+{
+  TimerCallbackInfo *tci = data;
+
+  tci->timer->tag = 0;
+
+  if(tci->textfu->active_card->ontimer)
+    gtk_signal_emit(GTK_OBJECT(tci->textfu), textfu_signals[LINK_FOLLOWED], tci->textfu->active_card->ontimer);
+
+  return FALSE;
+}
+
+void
+wap_textfu_activate_card(WapTextFu *textfu, WapCard *card)
+{
+  GList *ltmp;
+
+  if(card == textfu->active_card)
+    return;
+
+  if(textfu->active_card)
+    {
+      /* Move old placed items off-screen */
+      for(ltmp = textfu->active_card->paragraphs; ltmp; ltmp = ltmp->next)
+	{
+	  WapParagraphInfo *pi = ltmp->data;
+	  GList *ltmp2;
+
+	  for(ltmp2 = pi->placed_items; ltmp2; ltmp2 = ltmp2->next)
+	    {
+	      PlacedItem *pl = ltmp2->data;
+
+	      gtk_layout_move(GTK_LAYOUT(textfu), pl->widget, -10000, -10000);
+	    }
+	}
+
+      gtk_signal_emit(GTK_OBJECT(textfu), textfu_signals[DEACTIVATE_CARD], textfu->active_card);
+    }
+
+  card->active_anchor = NULL;
+  textfu->old_width = 0;
+  textfu->active_card = card;
+
+  gtk_signal_emit(GTK_OBJECT(textfu), textfu_signals[ACTIVATE_CARD], card);
+  gtk_widget_queue_resize(GTK_WIDGET(textfu));
+
+  for(ltmp = textfu->active_card->timers; ltmp; ltmp = ltmp->next)
+    {
+      WapTimerInfo *timer = ltmp->data;
+
+      if(!timer->tag)
+	{
+	  TimerCallbackInfo *tci = g_new(TimerCallbackInfo, 1);
+
+	  tci->timer = timer;
+	  tci->textfu = textfu;
+	  timer->tag = g_timeout_add_full(G_PRIORITY_DEFAULT, timer->value * 100 /* 10ths of seconds into 1000ths of seconds */,
+					  wap_textfu_timer_cb, tci, g_free);
+	}
+    }
+}
+
+guint16
+wap_textfu_tagid_alloc(const char *name, WapTextFuTagHandler handler)
+{
+  WapTextFuClass *klass;
+  TagRegistration *cur_reg, *new_reg;
+  static guint16 tag_counter = 1;
+
+  klass = WAP_TEXTFU_CLASS(gtk_type_class(wap_textfu_get_type()));
+
+  cur_reg = g_hash_table_lookup(klass->tag_handlers, name);
+  if(cur_reg)
+    return 0;
+
+  new_reg = g_malloc(G_STRUCT_OFFSET(TagRegistration, tag_name) + strlen(name) + 1);
+  new_reg->handler = handler;
+  new_reg->tag_id = tag_counter++;
+  strcpy(new_reg->tag_name, name);
+  g_strdown(new_reg->tag_name);
+  g_hash_table_insert(klass->tag_handlers, new_reg->tag_name, new_reg);
+
+  return new_reg->tag_id;
+}
+
+void
+wap_textfu_postvalues_free(GList *postvalues)
+{
+  g_list_foreach(postvalues, (GFunc)g_free, NULL);
+  g_list_free(postvalues);
+}
diff --git a/libgnomeui/wap-textfu.h b/libgnomeui/wap-textfu.h
new file mode 100644
index 0000000..bfc69f7
--- /dev/null
+++ b/libgnomeui/wap-textfu.h
@@ -0,0 +1,231 @@
+/* wap-textfu.h
+ * Copyright (C) 2000 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+  @NOTATION@
+*/
+#ifndef __WAP_TEXTFU_H__
+#define __WAP_TEXTFU_H__
+
+#include <gtk/gtk.h>
+#include <libxml/parser.h>
+#include <pango/pango.h>
+
+#ifdef __cplusplus
+extern "C" {
+#pragma }
+#endif /* __cplusplus */
+
+#define WAP_TYPE_TEXTFU			(wap_textfu_get_type ())
+#define WAP_TEXTFU(obj)			(GTK_CHECK_CAST ((obj), WAP_TYPE_TEXTFU, WapTextFu))
+#define WAP_TEXTFU_CLASS(klass)		(GTK_CHECK_CLASS_CAST ((klass), WAP_TYPE_TEXTFU, WapTextFuClass))
+#define WAP_IS_TEXTFU(obj)			(GTK_CHECK_TYPE ((obj), WAP_TYPE_TEXTFU))
+#define WAP_IS_TEXTFU_CLASS(klass)		(GTK_CHECK_CLASS_TYPE ((obj), WAP_TYPE_TEXTFU))
+#define WAP_TEXTFU_GET_CLASS(obj)             (GTK_CHECK_GET_CLASS ((obj), WAP_TYPE_TEXTFU, WapTextFuClass))
+
+typedef enum {
+  TEXTFU_ITEM_TEXT,
+  TEXTFU_ITEM_CONTAINER,
+  TEXTFU_ITEM_WIDGET
+} WapTextFuItemType;
+
+typedef struct {
+  char tag[16];
+} WapStyle;
+
+typedef struct {
+  WapStyle style;
+
+  PangoAlignment alignment;
+  gint16 left_indent, right_indent;
+  gint16 bullet_num, bullet_level;
+  gint16 space_after;
+  gboolean ul_container : 1;
+  gboolean ol_container : 1;
+  gboolean replace_prev : 1;
+} WapParaStyle;
+
+typedef enum {
+  TEXTFU_FALSE,
+  TEXTFU_TRUE,
+  TEXTFU_UNKNOWN
+} WapTextFuTruthValue;
+
+typedef struct {
+  char *url;
+  char *charset;
+  GList *postvalues;
+
+  gboolean sendreferer : 1;
+  gboolean post_method : 1;
+} WapGoInfo;
+
+typedef struct {
+  char *title;
+  gpointer attr;
+  enum { ANCHOR_GO, ANCHOR_PREV, ANCHOR_REFRESH, ANCHORS_AWAY } type;
+  WapGoInfo *go_info;
+  GList *setvars;
+} WapAnchorInfo;
+
+typedef struct {
+  enum { DO_ACCEPT, DO_DELETE, DO_HELP, DO_OPTIONS, DO_PREV,
+	 DO_SOFT1, DO_SOFT2, DO_SEND, DO_NOTHING } type;
+  enum { ACT_GO, ACT_PREV, ACT_NOTHING } task;
+  WapGoInfo *go;
+  char *label, *name;
+  GtkWidget *img;
+} WapDoInfo;
+
+typedef struct {
+  WapStyle style;
+
+  WapAnchorInfo *wai;
+  char *font_family;
+  int font_size;
+  GdkColor fg_color, bg_color;
+
+  int start_offset;
+  guint bold : 2, italic : 2, underline : 2;
+
+  guint replace_prev : 1;
+  guint fg_color_set : 1;
+  guint bg_color_set : 1;
+  guint font_size_set : 1;
+} WapTextStyle;
+
+typedef struct {
+  PangoLayout *layout;
+  PangoAttrList *attrs;
+  int left_indent, right_indent;
+  GList *placed_items;
+  int space_after;
+
+  GList *anchors;
+
+  int y_offset, height;
+} WapParagraphInfo;
+
+typedef struct {
+  char *text, *onpick, *value;
+  GtkWidget *image, *li_widget;
+} WapOptionInfo;
+
+typedef struct {
+  char *name, *title, *value, *fmt, *iname;
+  gpointer placed_item;
+  GList *options;
+  int maxlen, ivalue;
+  gboolean emptyok : 1, multiple : 1, is_selection : 1;
+} WapInputInfo;
+
+typedef struct {
+  char *name;
+  guint value;
+  guint tag;
+} WapTimerInfo;
+
+typedef struct {
+  char *id, *title;
+  char *onenterforward, *onenterbackward, *ontimer;
+
+  WapAnchorInfo *active_anchor;
+  WapParagraphInfo *active_anchor_para;
+
+  GList *paragraphs;
+  GList *actions;
+  GList *inputs;
+  GList *timers;
+  guint newcontext : 1;
+
+  /* Layout stuff */
+  GList *para_style_stack;
+  GList *text_style_stack;
+} WapCard;
+
+typedef struct _WapTextFu       WapTextFu;
+typedef struct _WapTextFuClass  WapTextFuClass;
+
+struct _WapTextFu
+{
+  GtkLayout parent;
+
+  /* All fields are private, don't touch */
+  char *cur_filename;
+
+  guint old_width;
+
+  guint vscroll_tag;
+
+  WapCard *active_card;
+  GList *cards;
+  char *lang;
+
+  GdkGC *drawing_gc;
+
+  /* Parser info */
+  WapCard *cur_card;
+  WapGoInfo *cur_go;
+  WapDoInfo *cur_do;
+  WapAnchorInfo *cur_anchor;
+  WapInputInfo *cur_input;
+  WapOptionInfo *cur_option;
+
+  xmlParserCtxtPtr ctxt;
+  GString *tmp_text, *nc_text;
+  WapParagraphInfo *cur_para;
+  PangoContext *pango_ctx;
+
+  gint ignore_counter;
+  gboolean in_content : 1, in_do : 1, in_anchor : 1, in_select : 1, in_option : 1;
+  gboolean last_was_placed : 1, is_hdml : 1;
+};
+
+struct _WapTextFuClass
+{
+  GtkLayoutClass parent_class;
+
+  GHashTable *tag_handlers;
+
+  /* Signals */
+  void (*link_followed) (WapTextFu *textfu, const char *url);
+  void (*anchor_followed) (WapTextFu *textfu, WapAnchorInfo *anchor);
+  void (*prev_followed) (WapTextFu *textfu);
+  void (*load_done)     (WapTextFu *textfu);
+  void (*load_error)    (WapTextFu *textfu);
+  void (*activate_card) (WapTextFu *textfu, WapCard *card);
+  void (*deactivate_card) (WapTextFu *textfu, WapCard *card);
+};
+
+typedef void (*WapTextFuTagHandler)(WapTextFu *textfu, const char *tag, guint16 tag_id, char **attrs, gboolean is_end);
+
+GtkType    wap_textfu_get_type   (void);
+GtkWidget *wap_textfu_new        (void);
+void       wap_textfu_load_file  (WapTextFu *textfu, const char *filename);
+void       wap_textfu_load_go_info  (WapTextFu *textfu, WapGoInfo *go);
+void       wap_textfu_activate_card(WapTextFu *textfu, WapCard *card);
+guint16    wap_textfu_tagid_alloc(const char *name, WapTextFuTagHandler handler);
+void wap_textfu_postvalues_free(GList *postvalues);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __WAP_TEXTFU_H__ */
diff --git a/message-of-doom b/message-of-doom
new file mode 100644
index 0000000..c71bda9
--- /dev/null
+++ b/message-of-doom
@@ -0,0 +1,24 @@
+ *** IMPORTANT *** 
+
+This is a development version of gnome-libs.  You should be using a stable
+version, which is available at ftp://ftp.gnome.org/pub/GNOME/stable/sources/gnome-libs/
+The version you just configured is meant for developers of gnome-libs only:
+
+  * You should not base ANY software on this version of gnome-libs.
+
+Distributions should *NOT* ship a development package of this gnome-libs.
+Do not ship the headers and do not ship the gnome-config script. These
+things will conflict with the stable 1.0 series.  Package only enough
+to satisfy the requirements of some other package.  Package only the
+library itself.  Doing otherwise will do no favors to the community.
+
+ *** You should be using gnome-libs 1.0 instead. ***
+
+If you are using this source tree from CVS, please run:
+	cvs update -r gnome-libs-1-0"
+now.
+
+			....
+     Do not bother the mailing lists, IRC channels, or other forums if you cannot
+     figure out how to build gnome-libs HEAD. It is not in working condition.
+			....
diff --git a/po/.cvsignore b/po/.cvsignore
new file mode 100644
index 0000000..83c9c3b
--- /dev/null
+++ b/po/.cvsignore
@@ -0,0 +1,11 @@
+*.gmo
+*.mo
+Makefile
+Makefile.in
+Makefile.in.in
+POTFILES
+cat-id-tbl.c
+*.pot
+gnome.pot
+stamp-cat-id
+messages
diff --git a/po/ChangeLog b/po/ChangeLog
new file mode 100644
index 0000000..804f367
--- /dev/null
+++ b/po/ChangeLog
@@ -0,0 +1,6 @@
+2001-04-21  Kjartan Maraas  <kmaraas gnome org>
+
+	* no.po: Added Norwegian (bokmål) translation.
+	* nn.po: Added Norwegian (nynorsk) translation.
+	* POTFILES.in: Populated.
+	
\ No newline at end of file
diff --git a/po/POTFILES.in b/po/POTFILES.in
new file mode 100644
index 0000000..9edd4c8
--- /dev/null
+++ b/po/POTFILES.in
@@ -0,0 +1,38 @@
+demos/mdi_demo.c
+demos/stock_demo.c
+demos/winhints_demo.c
+libgnomeui/gnome-about.c
+libgnomeui/gnome-about.h
+libgnomeui/gnome-animator.c
+libgnomeui/gnome-app-helper.c
+libgnomeui/gnome-app-helper.h
+libgnomeui/gnome-app-util.c
+libgnomeui/gnome-app.c
+libgnomeui/gnome-canvas-init.c
+libgnomeui/gnome-client.c
+libgnomeui/gnome-color-picker.c
+libgnomeui/gnome-dateedit.c
+libgnomeui/gnome-dialog.c
+libgnomeui/gnome-ditem-edit.c
+libgnomeui/gnome-dock-item.c
+libgnomeui/gnome-druid-page-edge.c
+libgnomeui/gnome-druid-page-standard.c
+libgnomeui/gnome-druid.c
+libgnomeui/gnome-file-saver.c
+libgnomeui/gnome-font-picker.c
+libgnomeui/gnome-gconf.c
+libgnomeui/gnome-helpsys.c
+libgnomeui/gnome-href.c
+libgnomeui/gnome-icon-entry.c
+libgnomeui/gnome-init.c
+libgnomeui/gnome-messagebox.c
+libgnomeui/gnome-paper-selector.c
+libgnomeui/gnome-popup-help.c
+libgnomeui/gnome-pouch.c
+libgnomeui/gnome-recently-used.c
+libgnomeui/gnome-scores.c
+libgnomeui/gnome-scores.h
+libgnomeui/gnome-selector.c
+libgnomeui/gnome-stock.c
+libgnomeui/gnome_segv.c
+libgnomeui/oafgnome.c
diff --git a/po/nn.po b/po/nn.po
new file mode 100644
index 0000000..3542ed9
--- /dev/null
+++ b/po/nn.po
@@ -0,0 +1,1501 @@
+# Norwegian translation of gnome-libs (bokmål dialect).
+# Copyright (C) 1998-2000 Free Software Foundation, Inc.
+# Kjartan Maraas <kmaraas online no>, 1998-2000.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: gnome-libs 1.2.7\n"
+"POT-Creation-Date: 2001-04-21 14:55-0400\n"
+"PO-Revision-Date: 2001-04-21 14:57-04:00\n"
+"Last-Translator: Kjartan Maraas <kmaraas gnome org>\n"
+"Language-Team: Norwegian <no li org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+"Content-Transfer-Encoding: 8-bit\n"
+
+#: demos/mdi_demo.c:116
+msgid "Child Item 1"
+msgstr ""
+
+#: demos/mdi_demo.c:117
+msgid "Hint for item 1"
+msgstr ""
+
+#: demos/mdi_demo.c:119
+msgid "Child Item 2"
+msgstr ""
+
+#: demos/mdi_demo.c:120
+msgid "Hint for item 2"
+msgstr ""
+
+#: demos/stock_demo.c:137
+msgid "New..."
+msgstr "Ny..."
+
+#: demos/stock_demo.c:145
+msgid "Open..."
+msgstr "Åpne..."
+
+#: demos/stock_demo.c:153
+msgid "Save"
+msgstr "Lagre"
+
+#: demos/stock_demo.c:161
+msgid "Save as..."
+msgstr "Lagre som..."
+
+#: demos/stock_demo.c:169 libgnomeui/gnome-stock.c:581
+msgid "Close"
+msgstr "Lukk"
+
+#: demos/stock_demo.c:181
+msgid "Print..."
+msgstr "Skriv ut..."
+
+#: demos/stock_demo.c:189
+msgid "Setup Page..."
+msgstr "Sideoppsett..."
+
+#: demos/stock_demo.c:198
+msgid "Quit"
+msgstr "Avslutt"
+
+#: demos/stock_demo.c:209
+msgid "File"
+msgstr "Fil"
+
+#: demos/stock_demo.c:216
+msgid "Undo"
+msgstr "Angre"
+
+#: demos/stock_demo.c:224
+msgid "Redo"
+msgstr "Gjenopprett"
+
+#: demos/stock_demo.c:233
+msgid "Delete"
+msgstr "Slett"
+
+#: demos/stock_demo.c:238
+msgid "Cut"
+msgstr "Klipp ut"
+
+#: demos/stock_demo.c:246
+msgid "Copy"
+msgstr "Kopier"
+
+#: demos/stock_demo.c:254
+msgid "Paste"
+msgstr "Lim inn"
+
+#: demos/stock_demo.c:266
+msgid "Properties..."
+msgstr "Egenskaper..."
+
+#: demos/stock_demo.c:276
+msgid "Preferences..."
+msgstr "Brukervalg..."
+
+#: demos/stock_demo.c:291
+msgid "Scores..."
+msgstr "Poengsummer..."
+
+#: demos/stock_demo.c:299
+msgid "Edit"
+msgstr "Rediger"
+
+#: demos/stock_demo.c:307 demos/winhints_demo.c:258
+#: libgnomeui/gnome-about.c:1078
+msgid "About"
+msgstr "Om"
+
+#: demos/stock_demo.c:315 libgnomeui/gnome-helpsys.c:219
+#: libgnomeui/gnome-stock.c:584
+msgid "Help"
+msgstr "Hjelp"
+
+#: demos/winhints_demo.c:48
+msgid "wmhints-test"
+msgstr "wmhints-test"
+
+#: demos/winhints_demo.c:48
+msgid "winhints-test"
+msgstr "winhints-test"
+
+#: demos/winhints_demo.c:73
+msgid "Layer:"
+msgstr "Lag:"
+
+#: demos/winhints_demo.c:96
+msgid "Above Dock"
+msgstr "Over dokk"
+
+#: demos/winhints_demo.c:100
+msgid "Dock"
+msgstr "Dokk"
+
+#: demos/winhints_demo.c:104
+msgid "On Top"
+msgstr "Øverst"
+
+#: demos/winhints_demo.c:108
+msgid "Normal"
+msgstr "Normal"
+
+#: demos/winhints_demo.c:112
+msgid "Below"
+msgstr "Under"
+
+#: demos/winhints_demo.c:116
+msgid "Desktop"
+msgstr "Skrivebord"
+
+#: demos/winhints_demo.c:124
+msgid "Set Layer"
+msgstr "Sett lag"
+
+#: demos/winhints_demo.c:131
+msgid "Workspaces:"
+msgstr "Arbeidsområder:"
+
+#: demos/winhints_demo.c:153
+msgid "Sticky"
+msgstr "Klebrig"
+
+#: demos/winhints_demo.c:157
+msgid "Set Workspace"
+msgstr "Sett arbeidsplass"
+
+#: demos/winhints_demo.c:167
+msgid "State Toggles:"
+msgstr "Tilstandsvelgere:"
+
+#: demos/winhints_demo.c:177
+msgid "Minimized"
+msgstr "Minimert"
+
+#: demos/winhints_demo.c:181
+msgid "Maximized Vertical"
+msgstr "Maksimert vertikalt"
+
+#: demos/winhints_demo.c:185
+msgid "Maximized Horizontal"
+msgstr "Maksimert horisontalt"
+
+#: demos/winhints_demo.c:189
+msgid "Hidden"
+msgstr "Skjult"
+
+#: demos/winhints_demo.c:193
+msgid "Shaded"
+msgstr "Skyggelagt"
+
+#: demos/winhints_demo.c:197
+msgid "Fixed Position"
+msgstr "Fast posisjon"
+
+#: demos/winhints_demo.c:201
+msgid "Ignore on Arrange"
+msgstr "Ignorer ved plassering"
+
+#: demos/winhints_demo.c:205
+msgid "Set State"
+msgstr "Set tilstand"
+
+#: demos/winhints_demo.c:211
+msgid "Skip Toggles:"
+msgstr "Hopp over velgere:"
+
+#: demos/winhints_demo.c:221
+msgid "Skip Focus"
+msgstr "Hopp over fokus"
+
+#: demos/winhints_demo.c:225
+msgid "Skip Window Menu"
+msgstr "Hopp over vindusmeny"
+
+#: demos/winhints_demo.c:229
+msgid "Skip Taskbar / WinList"
+msgstr "Hopp over oppgavelinje / vindusliste"
+
+#: demos/winhints_demo.c:233
+msgid "Set Skip"
+msgstr "Hopp over"
+
+#: demos/winhints_demo.c:412
+msgid "WIN_HINTS Test"
+msgstr "WIN_HINTS test"
+
+#: demos/winhints_demo.c:413
+msgid "Copyright (C) 1998"
+msgstr "Copyright (C) 1998"
+
+#: demos/winhints_demo.c:415
+msgid ""
+"Simple test app to check how the WIN_HINTS work.\n"
+"And to test the gnome_win_hints_* functions for errors. :)"
+msgstr ""
+"Enkel testapplikasjon for å sjekke hvordan WIN_HINTS verker.\n"
+"Og for å teste gnome_win_hints_*-funksjonane for feil. :)"
+
+#: libgnomeui/gnome-about.c:331
+msgid "Author:"
+msgstr "Forfatter:"
+
+#: libgnomeui/gnome-about.c:341 libgnomeui/gnome-about.c:345
+msgid "Authors:"
+msgstr "Forfattere:"
+
+#: libgnomeui/gnome-about.c:679
+msgid "Authors: "
+msgstr "Forfattere: "
+
+#: libgnomeui/gnome-about.c:1172 libgnomeui/gnome-href.c:397
+msgid ""
+"Error occured while trying to launch the URL handler.\n"
+"Please check the settings in the Control Center if they are correct."
+msgstr ""
+
+#: libgnomeui/gnome-animator.c:136
+msgid "Loop type"
+msgstr ""
+
+#: libgnomeui/gnome-animator.c:137
+msgid "The type of loop the GnomeAnimator uses"
+msgstr ""
+
+#: libgnomeui/gnome-animator.c:145
+msgid "Direction"
+msgstr ""
+
+#: libgnomeui/gnome-animator.c:146
+#, fuzzy
+msgid "Animation direction"
+msgstr "Hovedordbok:"
+
+#: libgnomeui/gnome-animator.c:154
+msgid "Number of frames"
+msgstr ""
+
+#: libgnomeui/gnome-animator.c:155
+msgid "Total number of frames in animation"
+msgstr ""
+
+#: libgnomeui/gnome-animator.c:163
+#, fuzzy
+msgid "Current frame"
+msgstr "Avslutt aktivt spill"
+
+#: libgnomeui/gnome-animator.c:164
+msgid "Current frame number"
+msgstr ""
+
+#: libgnomeui/gnome-animator.c:172 libgnomeui/gnome-animator.c:173
+msgid "Animation status"
+msgstr ""
+
+#: libgnomeui/gnome-animator.c:181
+#, fuzzy
+msgid "Speed"
+msgstr "Stav"
+
+#: libgnomeui/gnome-animator.c:182
+msgid "Animation speed"
+msgstr ""
+
+#: libgnomeui/gnome-app-helper.c:84
+msgid "_File"
+msgstr "_Fil"
+
+#: libgnomeui/gnome-app-helper.c:85
+msgid "_File/"
+msgstr "_Fil/"
+
+#: libgnomeui/gnome-app-helper.c:86
+msgid "_Edit"
+msgstr "R_ediger"
+
+#: libgnomeui/gnome-app-helper.c:87
+msgid "_Edit/"
+msgstr "R_ediger/"
+
+#: libgnomeui/gnome-app-helper.c:88
+msgid "_View"
+msgstr "_Vis"
+
+#: libgnomeui/gnome-app-helper.c:89
+msgid "_View/"
+msgstr "_Vis/"
+
+#: libgnomeui/gnome-app-helper.c:90
+msgid "_Settings"
+msgstr "_Innstillinger"
+
+#: libgnomeui/gnome-app-helper.c:91
+msgid "_Settings/"
+msgstr "_Innstillinger/"
+
+#: libgnomeui/gnome-app-helper.c:92
+msgid "_New"
+msgstr "_Ny"
+
+#: libgnomeui/gnome-app-helper.c:93
+msgid "_New/"
+msgstr "_Ny/"
+
+#: libgnomeui/gnome-app-helper.c:94
+msgid "Fi_les"
+msgstr "Fi_ler"
+
+#: libgnomeui/gnome-app-helper.c:95
+msgid "Fi_les/"
+msgstr "Fi_ler/"
+
+#: libgnomeui/gnome-app-helper.c:96
+msgid "_Windows"
+msgstr "Vin_duer"
+
+#: libgnomeui/gnome-app-helper.c:97
+msgid "_Game"
+msgstr "_Spill"
+
+#: libgnomeui/gnome-app-helper.c:98
+msgid "_Help"
+msgstr "_Hjelp"
+
+#: libgnomeui/gnome-app-helper.c:99
+msgid "_Windows/"
+msgstr "Vin_duer/"
+
+#. Open
+#: libgnomeui/gnome-app-helper.c:111
+msgid "_Open..."
+msgstr "_Åpne..."
+
+#: libgnomeui/gnome-app-helper.c:111
+msgid "Open a file"
+msgstr "Åpne en fil"
+
+#. Save
+#: libgnomeui/gnome-app-helper.c:116
+msgid "_Save"
+msgstr "_Lagre"
+
+#: libgnomeui/gnome-app-helper.c:116
+msgid "Save the current file"
+msgstr "Lagre aktiv fil"
+
+#. Save As
+#: libgnomeui/gnome-app-helper.c:121
+msgid "Save _As..."
+msgstr "L_agre som..."
+
+#: libgnomeui/gnome-app-helper.c:122
+msgid "Save the current file with a different name"
+msgstr "Lagre aktiv fil med et nytt navn"
+
+#. Revert
+#: libgnomeui/gnome-app-helper.c:127
+msgid "_Revert"
+msgstr "_Gå tilbake"
+
+#: libgnomeui/gnome-app-helper.c:128
+msgid "Revert to a saved version of the file"
+msgstr "Gå tilbake til lagret versjon av filen"
+
+#. Print
+#: libgnomeui/gnome-app-helper.c:133
+msgid "_Print"
+msgstr "S_kriv ut"
+
+#: libgnomeui/gnome-app-helper.c:133
+msgid "Print the current file"
+msgstr "Skriv ut aktiv fil"
+
+#. Print Setup
+#: libgnomeui/gnome-app-helper.c:138
+msgid "Print S_etup..."
+msgstr "Skriveropps_ett"
+
+#: libgnomeui/gnome-app-helper.c:139
+msgid "Setup the page settings for your current printer"
+msgstr "Oppsett av sideinnstillingene for din nåværende skriver"
+
+#. Close
+#: libgnomeui/gnome-app-helper.c:144
+msgid "_Close"
+msgstr "L_ukk"
+
+#: libgnomeui/gnome-app-helper.c:144
+msgid "Close the current file"
+msgstr "Lukk aktiv fil"
+
+#. Exit
+#: libgnomeui/gnome-app-helper.c:149
+msgid "E_xit"
+msgstr "_Avslutt"
+
+#: libgnomeui/gnome-app-helper.c:149
+msgid "Exit the program"
+msgstr "Avslutt programmet"
+
+#.
+#. * The "Edit" menu
+#.
+#. Cut
+#: libgnomeui/gnome-app-helper.c:157
+msgid "C_ut"
+msgstr "Klipp _ut"
+
+#: libgnomeui/gnome-app-helper.c:157
+msgid "Cut the selection"
+msgstr "Klipp ut utvalget"
+
+#. 10
+#. Copy
+#: libgnomeui/gnome-app-helper.c:163 libgnomeui/gnome-popup-help.c:65
+msgid "_Copy"
+msgstr "_Kopier"
+
+#: libgnomeui/gnome-app-helper.c:163
+msgid "Copy the selection"
+msgstr "Kopier utvalget"
+
+#. Paste
+#: libgnomeui/gnome-app-helper.c:168 libgnomeui/gnome-popup-help.c:67
+msgid "_Paste"
+msgstr "_Lim inn"
+
+#: libgnomeui/gnome-app-helper.c:168
+msgid "Paste the clipboard"
+msgstr "Lim inn fra utklippstavlen"
+
+#. Clear
+#: libgnomeui/gnome-app-helper.c:173
+msgid "C_lear"
+msgstr "_Slett"
+
+#: libgnomeui/gnome-app-helper.c:173
+msgid "Clear the selection"
+msgstr "Slett utvalget"
+
+#. Undo
+#: libgnomeui/gnome-app-helper.c:178
+msgid "_Undo"
+msgstr "A_ngre"
+
+#: libgnomeui/gnome-app-helper.c:178
+msgid "Undo the last action"
+msgstr "Angre siste handling"
+
+#. Redo
+#: libgnomeui/gnome-app-helper.c:183
+msgid "_Redo"
+msgstr "_Gjenopprett"
+
+#: libgnomeui/gnome-app-helper.c:183
+msgid "Redo the undone action"
+msgstr "Gjenopprett den angrede handlingen"
+
+#. Find
+#: libgnomeui/gnome-app-helper.c:188
+msgid "_Find..."
+msgstr "_Finn..."
+
+#: libgnomeui/gnome-app-helper.c:188
+msgid "Search for a string"
+msgstr "Søk etter en tekststreng"
+
+#. Find Again
+#: libgnomeui/gnome-app-helper.c:193
+msgid "Find _Again"
+msgstr "Finn _igjen"
+
+#: libgnomeui/gnome-app-helper.c:194
+msgid "Search again for the same string"
+msgstr "Søk på nytt etter den samme tekststrengen"
+
+#. Replace
+#: libgnomeui/gnome-app-helper.c:199
+msgid "_Replace..."
+msgstr "E_rstatt"
+
+#: libgnomeui/gnome-app-helper.c:199
+msgid "Replace a string"
+msgstr "Erstatt en tekststreng"
+
+#. Properties
+#: libgnomeui/gnome-app-helper.c:204
+msgid "_Properties..."
+msgstr "E_genskaper..."
+
+#: libgnomeui/gnome-app-helper.c:205
+msgid "Modify the file's properties"
+msgstr "Modifiser filens egenskaper"
+
+#.
+#. * The Settings menu
+#.
+#. Settings
+#: libgnomeui/gnome-app-helper.c:213
+msgid "_Preferences..."
+msgstr "_Brukervalg..."
+
+#: libgnomeui/gnome-app-helper.c:214
+msgid "Configure the application"
+msgstr "Konfigurer applikasjonen"
+
+#. 20
+#.
+#. * And the "Help" menu
+#.
+#. About
+#: libgnomeui/gnome-app-helper.c:223
+#, fuzzy
+msgid "_About"
+msgstr "Om"
+
+#: libgnomeui/gnome-app-helper.c:224
+msgid "About this application"
+msgstr "Om denne applikasjonen"
+
+#: libgnomeui/gnome-app-helper.c:227
+msgid "_Select All"
+msgstr "_Velg alt"
+
+#: libgnomeui/gnome-app-helper.c:228
+msgid "Select everything"
+msgstr "Velg alt"
+
+#.
+#. * Window menu
+#.
+#: libgnomeui/gnome-app-helper.c:236
+msgid "Create New _Window"
+msgstr "Opprett nytt _vindu"
+
+#: libgnomeui/gnome-app-helper.c:237
+msgid "Create a new window"
+msgstr "Opprett et nytt vindu"
+
+#: libgnomeui/gnome-app-helper.c:241
+msgid "_Close This Window"
+msgstr "L_ukk dette vinduet"
+
+#: libgnomeui/gnome-app-helper.c:242
+msgid "Close the current window"
+msgstr "Lukk aktivt vindu"
+
+#.
+#. * The "Game" menu
+#.
+#: libgnomeui/gnome-app-helper.c:250
+msgid "_New game"
+msgstr "_Nytt spill"
+
+#: libgnomeui/gnome-app-helper.c:251
+msgid "Start a new game"
+msgstr "Start et nytt spill"
+
+#: libgnomeui/gnome-app-helper.c:255
+msgid "_Pause game"
+msgstr "_Pause spillet"
+
+#: libgnomeui/gnome-app-helper.c:256
+msgid "Pause the game"
+msgstr "Pause spillet"
+
+#: libgnomeui/gnome-app-helper.c:260
+msgid "_Restart game"
+msgstr "Sta_rt spillet på nytt"
+
+#: libgnomeui/gnome-app-helper.c:261
+msgid "Restart the game"
+msgstr "Start spillet på nytt"
+
+#: libgnomeui/gnome-app-helper.c:265
+msgid "_Undo move"
+msgstr "An_gre trekk"
+
+#: libgnomeui/gnome-app-helper.c:266
+msgid "Undo the last move"
+msgstr "Angre siste trekk"
+
+#: libgnomeui/gnome-app-helper.c:270
+msgid "_Redo move"
+msgstr "Gjenopp_rett trekk"
+
+#: libgnomeui/gnome-app-helper.c:271
+msgid "Redo the undone move"
+msgstr "Gjenopprett siste angrede trekk"
+
+#: libgnomeui/gnome-app-helper.c:275
+msgid "_Hint"
+msgstr "_Hint"
+
+#: libgnomeui/gnome-app-helper.c:276
+msgid "Get a hint for your next move"
+msgstr "Gi et hint for ditt neste trekk"
+
+#. 30
+#: libgnomeui/gnome-app-helper.c:281
+msgid "_Scores..."
+msgstr "Poeng_summer..."
+
+#: libgnomeui/gnome-app-helper.c:282
+msgid "View the scores"
+msgstr "Se på poengsummene"
+
+#: libgnomeui/gnome-app-helper.c:286
+msgid "_End game"
+msgstr "_Avslutt spillet"
+
+#: libgnomeui/gnome-app-helper.c:287
+msgid "End the current game"
+msgstr "Avslutt aktivt spill"
+
+#: libgnomeui/gnome-app-util.c:100
+msgid " (press return)"
+msgstr " (trykk linjeskift)"
+
+#: libgnomeui/gnome-app-util.c:143
+msgid "ERROR: "
+msgstr "FEIL: "
+
+#: libgnomeui/gnome-app-util.c:180
+msgid "Warning: "
+msgstr "Advarsel:"
+
+#: libgnomeui/gnome-app-util.c:317
+msgid "y"
+msgstr "j"
+
+#: libgnomeui/gnome-app-util.c:318
+msgid "yes"
+msgstr "ja"
+
+#: libgnomeui/gnome-app-util.c:321
+msgid "n"
+msgstr "n"
+
+#: libgnomeui/gnome-app-util.c:322
+msgid "no"
+msgstr "nei"
+
+#: libgnomeui/gnome-app-util.c:361
+msgid " (yes or no)"
+msgstr " (ja eller nei)"
+
+#: libgnomeui/gnome-app-util.c:362
+msgid "  - OK? (yes or no)"
+msgstr "  - OK? (ja eller nei)"
+
+#: libgnomeui/gnome-app-util.c:694
+msgid "Progress"
+msgstr "Fremgang"
+
+#: libgnomeui/gnome-app.c:149
+msgid "App ID"
+msgstr ""
+
+#: libgnomeui/gnome-app.c:150
+msgid "The application ID string"
+msgstr ""
+
+#: libgnomeui/gnome-canvas-init.c:52
+msgid "Gdk debugging flags to set"
+msgstr "Gdk avlusingsflagg som skal slås på"
+
+#: libgnomeui/gnome-canvas-init.c:52 libgnomeui/gnome-canvas-init.c:55
+#: libgnomeui/gnome-canvas-init.c:85 libgnomeui/gnome-canvas-init.c:88
+msgid "FLAGS"
+msgstr "FLAGG"
+
+#: libgnomeui/gnome-canvas-init.c:55
+msgid "Gdk debugging flags to unset"
+msgstr "Gdk avlusingsflagg som skal slås av"
+
+#: libgnomeui/gnome-canvas-init.c:58 libgnomeui/gnome-init.c:132
+msgid "X display to use"
+msgstr "X-display som skal brukes"
+
+#: libgnomeui/gnome-canvas-init.c:58 libgnomeui/gnome-init.c:132
+msgid "DISPLAY"
+msgstr "DISPLAY"
+
+#: libgnomeui/gnome-canvas-init.c:61
+msgid "Make X calls synchronous"
+msgstr "Bruk synkrone X-kall"
+
+#: libgnomeui/gnome-canvas-init.c:64
+msgid "Don't use X shared memory extension"
+msgstr "ikkje bruk X-utvidelse for delt minne"
+
+#: libgnomeui/gnome-canvas-init.c:67
+msgid "Program name as used by the window manager"
+msgstr "Programnavn som brukt av vindusbehandleren"
+
+#: libgnomeui/gnome-canvas-init.c:67
+msgid "NAME"
+msgstr "NAVN"
+
+#: libgnomeui/gnome-canvas-init.c:70
+msgid "Program class as used by the window manager"
+msgstr "Programklasse som brukt av vindusbehandleren"
+
+#: libgnomeui/gnome-canvas-init.c:70
+msgid "CLASS"
+msgstr "KLASSE"
+
+#: libgnomeui/gnome-canvas-init.c:73
+msgid "HOST"
+msgstr "VERT"
+
+#: libgnomeui/gnome-canvas-init.c:76
+msgid "PORT"
+msgstr "PORT"
+
+#: libgnomeui/gnome-canvas-init.c:79 libgnomeui/gnome-canvas-init.c:82
+msgid "STYLE"
+msgstr "STIL"
+
+#: libgnomeui/gnome-canvas-init.c:85
+msgid "Gtk+ debugging flags to set"
+msgstr "Gtk+ avlusingsflagg som skal slås på"
+
+#: libgnomeui/gnome-canvas-init.c:88
+msgid "Gtk+ debugging flags to unset"
+msgstr "Gtk+ avlusingsflagg som skal slås av"
+
+#: libgnomeui/gnome-canvas-init.c:91
+msgid "Make all warnings fatal"
+msgstr "Gjør alle advarsler til fatale"
+
+#: libgnomeui/gnome-canvas-init.c:94
+msgid "Load an additional Gtk module"
+msgstr "Last tilleggsmodul for Gtk+"
+
+#: libgnomeui/gnome-canvas-init.c:94
+msgid "MODULE"
+msgstr "MODUL"
+
+#: libgnomeui/gnome-client.c:836
+msgid "Specify session management ID"
+msgstr "Spesifiser ID for sesjonskontroll"
+
+#: libgnomeui/gnome-client.c:836
+msgid "ID"
+msgstr "ID"
+
+#: libgnomeui/gnome-client.c:839
+msgid "Specify prefix of saved configuration"
+msgstr "Spesifiser prefiks for lagret konfigurasjon"
+
+#: libgnomeui/gnome-client.c:839
+msgid "PREFIX"
+msgstr "PREFIKS"
+
+#: libgnomeui/gnome-client.c:842
+msgid "Disable connection to session manager"
+msgstr "Fjern forbindelse til sesjonsbehandler"
+
+#: libgnomeui/gnome-client.c:854
+#, fuzzy
+msgid "Session management"
+msgstr "Alternativer for sesjonskontroll"
+
+#: libgnomeui/gnome-client.c:2345
+msgid "Cancel Logout"
+msgstr "Avbryt utlogging"
+
+#: libgnomeui/gnome-color-picker.c:421
+msgid "Received invalid color data\n"
+msgstr ""
+
+#: libgnomeui/gnome-color-picker.c:485
+msgid "Pick a color"
+msgstr "Velg en farge"
+
+#: libgnomeui/gnome-dateedit.c:359
+msgid "Time"
+msgstr ""
+
+#: libgnomeui/gnome-dateedit.c:360
+msgid "The time currentlyselected"
+msgstr ""
+
+#: libgnomeui/gnome-dateedit.c:371
+msgid "DateEdit Flags"
+msgstr ""
+
+#: libgnomeui/gnome-dateedit.c:372
+msgid "Flags for how DateEdit looks"
+msgstr ""
+
+#: libgnomeui/gnome-dateedit.c:381
+msgid "Lower Hour"
+msgstr ""
+
+#: libgnomeui/gnome-dateedit.c:382
+msgid "Lower hour in the time popup selector"
+msgstr ""
+
+#: libgnomeui/gnome-dateedit.c:392
+msgid "Upper Hour"
+msgstr ""
+
+#: libgnomeui/gnome-dateedit.c:393
+msgid "Upper hour in the time popup selector"
+msgstr ""
+
+#: libgnomeui/gnome-dateedit.c:403
+msgid "Initial Time"
+msgstr ""
+
+#: libgnomeui/gnome-dateedit.c:404
+msgid "The initial time"
+msgstr ""
+
+#. Calendar label, only shown if the date editor has a time field
+#: libgnomeui/gnome-dateedit.c:647
+msgid "Calendar"
+msgstr "Kalender"
+
+#: libgnomeui/gnome-dateedit.c:843
+msgid "gnome_date_edit_get_date deprecated, use gnome_date_edit_get_time"
+msgstr ""
+
+#: libgnomeui/gnome-ditem-edit.c:211
+msgid "Name:"
+msgstr "Navn:"
+
+#: libgnomeui/gnome-ditem-edit.c:224
+msgid "Comment:"
+msgstr "Kommentar:"
+
+#: libgnomeui/gnome-ditem-edit.c:234
+msgid "Command:"
+msgstr "Kommando:"
+
+#: libgnomeui/gnome-ditem-edit.c:244
+msgid "Type:"
+msgstr "Type:"
+
+#: libgnomeui/gnome-ditem-edit.c:261
+msgid "Icon:"
+msgstr "Ikon:"
+
+#: libgnomeui/gnome-ditem-edit.c:271
+msgid "Choose an icon"
+msgstr "Velg et ikon"
+
+#: libgnomeui/gnome-ditem-edit.c:283
+msgid "Run in Terminal"
+msgstr "Kjør i terminalvindu"
+
+#: libgnomeui/gnome-ditem-edit.c:309
+msgid "Simple drag and drop"
+msgstr ""
+
+#: libgnomeui/gnome-ditem-edit.c:331
+#, c-format
+msgid ""
+"In the following commands you should use %s in the spot where the\n"
+"filename/URL should be substituted.  If you leave the field blank\n"
+"drops will not be accepted.  If this application can accept\n"
+"multiple files or URLs as arguments after its command name check the box "
+"above."
+msgstr ""
+
+#: libgnomeui/gnome-ditem-edit.c:343
+msgid "Command for file drops:"
+msgstr ""
+
+#: libgnomeui/gnome-ditem-edit.c:353
+msgid "Drop one file at a time only."
+msgstr ""
+
+#: libgnomeui/gnome-ditem-edit.c:365
+msgid "Command for URL drops:"
+msgstr ""
+
+#: libgnomeui/gnome-ditem-edit.c:375
+msgid "Drop one URL at a time only."
+msgstr ""
+
+#: libgnomeui/gnome-ditem-edit.c:488
+msgid "Try this before using:"
+msgstr "Prøv dette før bruk:"
+
+#: libgnomeui/gnome-ditem-edit.c:498
+msgid "Documentation:"
+msgstr "Dokumentasjon:"
+
+#: libgnomeui/gnome-ditem-edit.c:508
+msgid "Window titles to wait for (comma separated):"
+msgstr ""
+
+#: libgnomeui/gnome-ditem-edit.c:518
+msgid "Name/Comment translations:"
+msgstr "Navngi/Kommenter oversettelsene:"
+
+#: libgnomeui/gnome-ditem-edit.c:521
+msgid "Language"
+msgstr "Språk"
+
+#: libgnomeui/gnome-ditem-edit.c:522
+msgid "Name"
+msgstr "Navn"
+
+#: libgnomeui/gnome-ditem-edit.c:523
+msgid "Comment"
+msgstr "Kommentar"
+
+#: libgnomeui/gnome-ditem-edit.c:551
+msgid "Add/Set"
+msgstr "Legg til/sett"
+
+#: libgnomeui/gnome-ditem-edit.c:556 libgnomeui/gnome-stock.c:569
+msgid "Remove"
+msgstr "Fjern"
+
+#: libgnomeui/gnome-ditem-edit.c:703
+msgid "Basic"
+msgstr "Enkel"
+
+#: libgnomeui/gnome-ditem-edit.c:707
+msgid "Drag and Drop"
+msgstr ""
+
+#: libgnomeui/gnome-ditem-edit.c:711
+msgid "Advanced"
+msgstr "Avansert"
+
+#: libgnomeui/gnome-dock-item.c:230 libgnomeui/gnome-dock-item.c:231
+msgid "Shadow type"
+msgstr ""
+
+#. orientation
+#: libgnomeui/gnome-dock-item.c:239 libgnomeui/gnome-dock-item.c:240
+#: libgnomeui/gnome-helpsys.c:192 libgnomeui/gnome-helpsys.c:193
+#: libgnomeui/gnome-paper-selector.c:191
+#, fuzzy
+msgid "Orientation"
+msgstr "Dokumentasjon:"
+
+#: libgnomeui/gnome-dock-item.c:248 libgnomeui/gnome-dock-item.c:249
+msgid "Preferred width"
+msgstr ""
+
+#: libgnomeui/gnome-dock-item.c:256 libgnomeui/gnome-dock-item.c:257
+msgid "Preferred height"
+msgstr ""
+
+#: libgnomeui/gnome-druid-page-edge.c:352
+#: libgnomeui/gnome-druid-page-standard.c:301
+msgid "-adobe-helvetica-bold-r-normal-*-*-180-*-*-p-*-*-*,*-r-*"
+msgstr ""
+
+#: libgnomeui/gnome-druid-page-edge.c:361
+msgid "-adobe-helvetica-medium-r-normal-*-*-120-*-*-p-*-*-*,*-r-*"
+msgstr ""
+
+#: libgnomeui/gnome-druid.c:125
+msgid "Back"
+msgstr "Tilbake"
+
+#: libgnomeui/gnome-druid.c:133
+msgid "Finish"
+msgstr "Fullfør"
+
+#: libgnomeui/gnome-file-saver.c:192
+#, fuzzy
+msgid "File Name:"
+msgstr "Navn:"
+
+#: libgnomeui/gnome-file-saver.c:200
+#, fuzzy
+msgid "Location:"
+msgstr "Dokumentasjon:"
+
+#: libgnomeui/gnome-file-saver.c:208
+msgid "Save As Type:"
+msgstr ""
+
+#: libgnomeui/gnome-font-picker.c:856 libgnomeui/gnome-stock.c:589
+msgid "Font"
+msgstr "Skrifttype"
+
+#: libgnomeui/gnome-gconf.c:476
+msgid "GNOME GConf Support"
+msgstr ""
+
+#: libgnomeui/gnome-gconf.c:516
+#, c-format
+msgid ""
+"You attempted to change an aspect of your configuration that your system "
+"administrator or operating system vendor does not allow you to change. Some "
+"of the settings you have selected may not take effect, or may not be "
+"restored next time you use this application (%s)."
+msgstr ""
+
+#: libgnomeui/gnome-gconf.c:519
+#, c-format
+msgid ""
+"An error occurred while loading or saving configuration information for %s. "
+"Some of your configuration settings may not work properly."
+msgstr ""
+
+#: libgnomeui/gnome-gconf.c:541
+#, c-format
+msgid "GConf error details: %s\n"
+msgstr ""
+
+#: libgnomeui/gnome-helpsys.c:117
+msgid "_Popup"
+msgstr ""
+
+#: libgnomeui/gnome-helpsys.c:118
+msgid "Show help in temporary popup windows"
+msgstr ""
+
+#: libgnomeui/gnome-helpsys.c:120
+msgid "_Embedded"
+msgstr ""
+
+#: libgnomeui/gnome-helpsys.c:121
+#, fuzzy
+msgid "Show help inside the application window"
+msgstr "Konfigurer applikasjonen"
+
+#: libgnomeui/gnome-helpsys.c:123
+#, fuzzy
+msgid "_Browser"
+msgstr "Bla gjennom..."
+
+#: libgnomeui/gnome-helpsys.c:124
+msgid "Show help in a help browser window"
+msgstr ""
+
+#: libgnomeui/gnome-helpsys.c:172
+msgid "App style"
+msgstr ""
+
+#: libgnomeui/gnome-helpsys.c:173
+msgid "The style of GnomeHelpView"
+msgstr ""
+
+#: libgnomeui/gnome-helpsys.c:182
+msgid "App style priority"
+msgstr ""
+
+#: libgnomeui/gnome-helpsys.c:183
+msgid "The priority of style of GnomeHelpView"
+msgstr ""
+
+#: libgnomeui/gnome-helpsys.c:202
+msgid "Toplevel"
+msgstr ""
+
+#: libgnomeui/gnome-helpsys.c:203
+msgid "The toplevel widget"
+msgstr ""
+
+#: libgnomeui/gnome-helpsys.c:220
+msgid "Show help for a specific region of the application"
+msgstr ""
+
+#: libgnomeui/gnome-helpsys.c:225
+msgid "Style"
+msgstr ""
+
+#: libgnomeui/gnome-helpsys.c:226
+msgid "Change the way help is displayed"
+msgstr ""
+
+#: libgnomeui/gnome-helpsys.c:926 libgnomeui/gnome-helpsys.c:1020
+msgid "No help is available for the selected portion of the application."
+msgstr ""
+
+#. FIXME: properly handle the error!
+#: libgnomeui/gnome-helpsys.c:1192
+#, c-format
+msgid "Cought GnomeURL error: %s"
+msgstr ""
+
+#: libgnomeui/gnome-href.c:112
+#, fuzzy
+msgid "URL"
+msgstr "RCL"
+
+#: libgnomeui/gnome-href.c:113
+msgid "The URL that GnomeHRef activates"
+msgstr ""
+
+#: libgnomeui/gnome-href.c:120
+#, fuzzy
+msgid "Text"
+msgstr "Neste"
+
+#: libgnomeui/gnome-href.c:121
+msgid "The text on the button"
+msgstr ""
+
+#: libgnomeui/gnome-href.c:122
+msgid "End World Hunger"
+msgstr ""
+
+#: libgnomeui/gnome-icon-entry.c:348 libgnomeui/gnome-icon-entry.c:717
+#: libgnomeui/gnome-icon-entry.c:734
+msgid "No Icon"
+msgstr "Uten ikon"
+
+#: libgnomeui/gnome-init.c:90
+msgid "Bonobo UI"
+msgstr ""
+
+#. dialog display isn't working out
+#: libgnomeui/gnome-init.c:453
+msgid "Multiple segmentation faults occurred; can't display error dialog\n"
+msgstr "Flere segmenteringsfeil oppstod; kan ikkje vise feildialogen\n"
+
+#: libgnomeui/gnome-messagebox.c:179
+msgid "Information"
+msgstr "Informasjon"
+
+#: libgnomeui/gnome-messagebox.c:188
+msgid "Warning"
+msgstr "Advarsel"
+
+#: libgnomeui/gnome-messagebox.c:197
+msgid "Error"
+msgstr "Feil"
+
+#: libgnomeui/gnome-messagebox.c:206
+msgid "Question"
+msgstr "Spørsmål"
+
+#: libgnomeui/gnome-messagebox.c:215
+msgid "Message"
+msgstr "Beskjed"
+
+#. paper size
+#: libgnomeui/gnome-paper-selector.c:159
+msgid "Paper Size"
+msgstr ""
+
+#: libgnomeui/gnome-paper-selector.c:213
+msgid "Portrait"
+msgstr ""
+
+#: libgnomeui/gnome-paper-selector.c:233
+msgid "Landscape"
+msgstr ""
+
+#. margins
+#: libgnomeui/gnome-paper-selector.c:241
+msgid "Margins"
+msgstr ""
+
+#: libgnomeui/gnome-paper-selector.c:253
+#, fuzzy
+msgid "Top:"
+msgstr "Type:"
+
+#: libgnomeui/gnome-paper-selector.c:266
+msgid "Bottom:"
+msgstr ""
+
+#: libgnomeui/gnome-paper-selector.c:279
+msgid "Left:"
+msgstr ""
+
+#: libgnomeui/gnome-paper-selector.c:292
+msgid "Right:"
+msgstr ""
+
+#. Scaling
+#: libgnomeui/gnome-paper-selector.c:306
+msgid "Scaling"
+msgstr ""
+
+#: libgnomeui/gnome-paper-selector.c:321
+msgid "Fit to Page"
+msgstr ""
+
+#: libgnomeui/gnome-paper-selector.c:810
+#, c-format
+msgid "%0.3g%s x %0.3g%s"
+msgstr ""
+
+#: libgnomeui/gnome-paper-selector.c:1040
+msgid "Page Setup"
+msgstr ""
+
+#: libgnomeui/gnome-popup-help.c:57
+msgid "_Help with this"
+msgstr "_Hjelp om dette"
+
+#: libgnomeui/gnome-popup-help.c:63
+msgid "Cu_t"
+msgstr "K_lipp"
+
+#. to be kept in sync with GtkCornerType enumeration
+#: libgnomeui/gnome-pouch.c:782
+#, fuzzy
+msgid "Top left"
+msgstr "Topp ti"
+
+#: libgnomeui/gnome-pouch.c:783
+msgid "Bottom left"
+msgstr ""
+
+#: libgnomeui/gnome-pouch.c:784
+msgid "Top right"
+msgstr ""
+
+#: libgnomeui/gnome-pouch.c:785
+msgid "Bottom right"
+msgstr ""
+
+#. to be kept in sync with GtkOrientation enumeration
+#: libgnomeui/gnome-pouch.c:796
+#, fuzzy
+msgid "Horizontal"
+msgstr "Maksimert horisontalt"
+
+#: libgnomeui/gnome-pouch.c:797
+#, fuzzy
+msgid "Vertical"
+msgstr "Maksimert vertikalt"
+
+#: libgnomeui/gnome-pouch.c:807
+msgid "Icon position"
+msgstr ""
+
+#: libgnomeui/gnome-pouch.c:808
+#, fuzzy
+msgid "Icon orientation"
+msgstr "Informasjon"
+
+#: libgnomeui/gnome-pouch.c:810
+msgid "Tile children"
+msgstr ""
+
+#: libgnomeui/gnome-pouch.c:811
+msgid "Cascade children"
+msgstr ""
+
+#: libgnomeui/gnome-pouch.c:813
+msgid "Arrange icons"
+msgstr ""
+
+#: libgnomeui/gnome-pouch.c:814
+msgid "Autoarrange icons"
+msgstr ""
+
+#: libgnomeui/gnome-recently-used.c:111
+msgid "App Specific"
+msgstr ""
+
+#: libgnomeui/gnome-recently-used.c:112
+#, fuzzy
+msgid "Is this list application specific"
+msgstr "Om denne applikasjonen"
+
+#: libgnomeui/gnome-recently-used.c:893
+#, c-format
+msgid "bad GnomeRecentDocument attribute: %s\n"
+msgstr ""
+
+#: libgnomeui/gnome-recently-used.c:1123
+msgid "Unknown"
+msgstr ""
+
+#: libgnomeui/gnome-scores.c:105
+msgid "Top Ten"
+msgstr "Topp ti"
+
+#: libgnomeui/gnome-scores.c:115
+msgid "User"
+msgstr "Bruker"
+
+#: libgnomeui/gnome-scores.c:118
+msgid "Score"
+msgstr "Poengsum"
+
+#: libgnomeui/gnome-scores.c:121
+msgid "Date"
+msgstr "Dato"
+
+#. the localized string should fit (after replacing the %a %b
+#. etc) in ~18 chars.
+#. %a is abbreviated weekday, %A is full weekday,
+#. %b %B are abbreviated and full monthname, %Y is year,
+#. %d is day of month, %m is month number, %T full hour,
+#. %H hours, %M minutes, %S seconds
+#.
+#: libgnomeui/gnome-scores.c:236
+msgid "%a %b %d %T %Y"
+msgstr "%a %b %d %T %Y"
+
+#: libgnomeui/gnome-scores.c:444
+msgid "-freefont-garamond-*-*-*-*-30-170-*-*-*-*-*-*,*-r-*"
+msgstr ""
+
+#: libgnomeui/gnome-selector.c:1037
+msgid "Browse..."
+msgstr "Bla gjennom..."
+
+#: libgnomeui/gnome-selector.c:1048
+#, fuzzy
+msgid "Default..."
+msgstr "Kalkulator..."
+
+#: libgnomeui/gnome-selector.c:1059
+#, fuzzy
+msgid "Clear..."
+msgstr "Slett"
+
+#: libgnomeui/gnome-stock.c:566
+msgid "Add"
+msgstr "Legg til"
+
+#: libgnomeui/gnome-stock.c:567
+msgid "Clear"
+msgstr "Slett"
+
+#: libgnomeui/gnome-stock.c:568
+msgid "Select Color"
+msgstr "Velg farge"
+
+#: libgnomeui/gnome-stock.c:570
+msgid "Table Borders"
+msgstr "Kanter for tabell"
+
+#: libgnomeui/gnome-stock.c:571
+msgid "Table Fill"
+msgstr "Fyll for tabell"
+
+#: libgnomeui/gnome-stock.c:572
+msgid "Bulleted List"
+msgstr "Punktmerket liste"
+
+#: libgnomeui/gnome-stock.c:573
+msgid "Numbered List"
+msgstr "Nummerert liste"
+
+#: libgnomeui/gnome-stock.c:574
+msgid "Indent"
+msgstr "Rykk inn"
+
+#: libgnomeui/gnome-stock.c:575
+msgid "Un-Indent"
+msgstr "Fjern innrykk"
+
+#: libgnomeui/gnome-stock.c:578
+msgid "OK"
+msgstr "OK"
+
+#: libgnomeui/gnome-stock.c:579
+msgid "Apply"
+msgstr "Bruk"
+
+#: libgnomeui/gnome-stock.c:580
+msgid "Cancel"
+msgstr "Avbryt"
+
+#: libgnomeui/gnome-stock.c:582
+msgid "Yes"
+msgstr "Ja"
+
+#: libgnomeui/gnome-stock.c:583
+msgid "No"
+msgstr "Nei"
+
+#: libgnomeui/gnome-stock.c:585
+msgid "Next"
+msgstr "Neste"
+
+#: libgnomeui/gnome-stock.c:586
+msgid "Prev"
+msgstr "Forrige"
+
+#: libgnomeui/gnome-stock.c:587
+msgid "Up"
+msgstr "Opp"
+
+#: libgnomeui/gnome-stock.c:588
+msgid "Down"
+msgstr "Ned"
+
+#: libgnomeui/gnome-stock.c:1357
+msgid "Menu Accelerator Keys"
+msgstr "Taster for menyakselleratorer"
+
+#: libgnomeui/gnome-stock.c:1359
+msgid "Global"
+msgstr "Global"
+
+#: libgnomeui/gnome-stock.c:1361
+msgid "Menu Item"
+msgstr "Menyvalg"
+
+#: libgnomeui/gnome-stock.c:1362
+msgid "Accelerator"
+msgstr "Aksellerator"
+
+#: libgnomeui/gnome_segv.c:85
+#, c-format
+msgid ""
+"The GNOME Session Manager (process %d) has crashed\n"
+"due to a fatal error (%s).\n"
+"When you close this dialog, all applications will close and your session "
+"will exit.\n"
+"Please save all your files before closing this dialog."
+msgstr ""
+"GNOME's sesjonhåndterer (prosess %d) har krasjet\n"
+"pga en fatal feil (%s).\n"
+"Når du lukker denne dialogen vil alle applikasjoner lukkes og din sesjon \n"
+"vil avslutte.\n"
+"Vennligst lagre alle åpne filer før du lukker denne dialogen."
+
+#: libgnomeui/gnome_segv.c:95
+#, c-format
+msgid ""
+"Application \"%s\" (process %d) has crashed\n"
+"due to a fatal error.\n"
+"(%s)"
+msgstr ""
+"Applikasjonen \"%s\" (prosess %d) har krasjet\n"
+"pga en fatal feil.\n"
+"(%s)"
+
+#: libgnomeui/gnome_segv.c:104
+msgid "Usage: gnome_segv appname signum\n"
+msgstr "Bruk: gnome_segv appname signum\n"
+
+#: libgnomeui/gnome_segv.c:118
+msgid "Submit a bug report"
+msgstr "Send inn en feilrapport"
+
+#: libgnomeui/gnome_segv.c:128
+msgid "Debug"
+msgstr "Feilsøk"
+
+#: libgnomeui/gnome_segv.c:135
+msgid "http://www.gnome.org/application_crashed.shtml";
+msgstr "http://www.gnome.org/application_crashed.shtml";
+
+#: libgnomeui/gnome_segv.c:141
+msgid "Please visit the GNOME Application Crash page for more information"
+msgstr "Vennligst besøk GNOME Applikasjonskrasj-siden for mer informasjon"
+
+#: libgnomeui/oafgnome.c:242
+msgid "Username:"
+msgstr "Brukernamn:"
+
+#: libgnomeui/oafgnome.c:256
+msgid "Password:"
+msgstr "Passord:"
diff --git a/po/no.po b/po/no.po
new file mode 100644
index 0000000..1a76302
--- /dev/null
+++ b/po/no.po
@@ -0,0 +1,1494 @@
+# Norwegian translation of gnome-libs (bokmål dialect).
+# Copyright (C) 1998,1999,2000 Free Software Foundation, Inc.
+# Kjartan Maraas <kmaraas gnome org>, 1998,1999,2000
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: gnome-libs 2.0\n"
+"POT-Creation-Date: 2001-04-21 14:55-0400\n"
+"PO-Revision-Date: 2001-04-21 14:57-04:00\n"
+"Last-Translator: Kjartan Maraas <kmaraas gnome org>\n"
+"Language-Team: Norwegian <no li org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+"Content-Transfer-Encoding: 8-bit\n"
+
+#: demos/mdi_demo.c:116
+msgid "Child Item 1"
+msgstr "Avkom-oppføring 1"
+
+#: demos/mdi_demo.c:117
+msgid "Hint for item 1"
+msgstr "Hint for oppføring 1"
+
+#: demos/mdi_demo.c:119
+msgid "Child Item 2"
+msgstr "Avkom-oppføring 2"
+
+#: demos/mdi_demo.c:120
+msgid "Hint for item 2"
+msgstr "Hint for oppføring 2"
+
+#: demos/stock_demo.c:137
+msgid "New..."
+msgstr "Ny..."
+
+#: demos/stock_demo.c:145
+msgid "Open..."
+msgstr "Åpne..."
+
+#: demos/stock_demo.c:153
+msgid "Save"
+msgstr "Lagre"
+
+#: demos/stock_demo.c:161
+msgid "Save as..."
+msgstr "Lagre som..."
+
+#: demos/stock_demo.c:169 libgnomeui/gnome-stock.c:581
+msgid "Close"
+msgstr "Lukk"
+
+#: demos/stock_demo.c:181
+msgid "Print..."
+msgstr "Skriv ut..."
+
+#: demos/stock_demo.c:189
+msgid "Setup Page..."
+msgstr "Sideoppsett..."
+
+#: demos/stock_demo.c:198
+msgid "Quit"
+msgstr "Avslutt"
+
+#: demos/stock_demo.c:209
+msgid "File"
+msgstr "Fil"
+
+#: demos/stock_demo.c:216
+msgid "Undo"
+msgstr "Angre"
+
+#: demos/stock_demo.c:224
+msgid "Redo"
+msgstr "Gjenopprett"
+
+#: demos/stock_demo.c:233
+msgid "Delete"
+msgstr "Slett"
+
+#: demos/stock_demo.c:238
+msgid "Cut"
+msgstr "Klipp ut"
+
+#: demos/stock_demo.c:246
+msgid "Copy"
+msgstr "Kopier"
+
+#: demos/stock_demo.c:254
+msgid "Paste"
+msgstr "Lim inn"
+
+#: demos/stock_demo.c:266
+msgid "Properties..."
+msgstr "Egenskaper..."
+
+#: demos/stock_demo.c:276
+msgid "Preferences..."
+msgstr "Brukervalg..."
+
+#: demos/stock_demo.c:291
+msgid "Scores..."
+msgstr "Poengsummer..."
+
+#: demos/stock_demo.c:299
+msgid "Edit"
+msgstr "Rediger"
+
+#: demos/stock_demo.c:307 demos/winhints_demo.c:258
+#: libgnomeui/gnome-about.c:1078
+msgid "About"
+msgstr "Om"
+
+#: demos/stock_demo.c:315 libgnomeui/gnome-helpsys.c:219
+#: libgnomeui/gnome-stock.c:584
+msgid "Help"
+msgstr "Hjelp"
+
+#: demos/winhints_demo.c:48
+msgid "wmhints-test"
+msgstr "wmhints-test"
+
+#: demos/winhints_demo.c:48
+msgid "winhints-test"
+msgstr "winhints-test"
+
+#: demos/winhints_demo.c:73
+msgid "Layer:"
+msgstr "Lag:"
+
+#: demos/winhints_demo.c:96
+msgid "Above Dock"
+msgstr "Over dokk"
+
+#: demos/winhints_demo.c:100
+msgid "Dock"
+msgstr "Dokk"
+
+#: demos/winhints_demo.c:104
+msgid "On Top"
+msgstr "Øverst"
+
+#: demos/winhints_demo.c:108
+msgid "Normal"
+msgstr "Normal"
+
+#: demos/winhints_demo.c:112
+msgid "Below"
+msgstr "Under"
+
+#: demos/winhints_demo.c:116
+msgid "Desktop"
+msgstr "Skrivebord"
+
+#: demos/winhints_demo.c:124
+msgid "Set Layer"
+msgstr "Sett lag"
+
+#: demos/winhints_demo.c:131
+msgid "Workspaces:"
+msgstr "Arbeidsområder:"
+
+#: demos/winhints_demo.c:153
+msgid "Sticky"
+msgstr "Klebrig"
+
+#: demos/winhints_demo.c:157
+msgid "Set Workspace"
+msgstr "Sett arbeidsplass"
+
+#: demos/winhints_demo.c:167
+msgid "State Toggles:"
+msgstr "Tilstandsvelgere:"
+
+#: demos/winhints_demo.c:177
+msgid "Minimized"
+msgstr "Minimert"
+
+#: demos/winhints_demo.c:181
+msgid "Maximized Vertical"
+msgstr "Maksimert vertikalt"
+
+#: demos/winhints_demo.c:185
+msgid "Maximized Horizontal"
+msgstr "Maksimert horisontalt"
+
+#: demos/winhints_demo.c:189
+msgid "Hidden"
+msgstr "Skjult"
+
+#: demos/winhints_demo.c:193
+msgid "Shaded"
+msgstr "Skyggelagt"
+
+#: demos/winhints_demo.c:197
+msgid "Fixed Position"
+msgstr "Fast posisjon"
+
+#: demos/winhints_demo.c:201
+msgid "Ignore on Arrange"
+msgstr "Ignorer ved plassering"
+
+#: demos/winhints_demo.c:205
+msgid "Set State"
+msgstr "Set tilstand"
+
+#: demos/winhints_demo.c:211
+msgid "Skip Toggles:"
+msgstr "Hopp over velgere:"
+
+#: demos/winhints_demo.c:221
+msgid "Skip Focus"
+msgstr "Hopp over fokus"
+
+#: demos/winhints_demo.c:225
+msgid "Skip Window Menu"
+msgstr "Hopp over vindusmeny"
+
+#: demos/winhints_demo.c:229
+msgid "Skip Taskbar / WinList"
+msgstr "Hopp over oppgavelinje / vindusliste"
+
+#: demos/winhints_demo.c:233
+msgid "Set Skip"
+msgstr "Hopp over"
+
+#: demos/winhints_demo.c:412
+msgid "WIN_HINTS Test"
+msgstr "WIN_HINTS test"
+
+#: demos/winhints_demo.c:413
+msgid "Copyright (C) 1998"
+msgstr "Copyright (C) 1998"
+
+#: demos/winhints_demo.c:415
+msgid ""
+"Simple test app to check how the WIN_HINTS work.\n"
+"And to test the gnome_win_hints_* functions for errors. :)"
+msgstr ""
+"Enkel testapplikasjon for å sjekke hvordan WIN_HINTS virker.\n"
+"Og for å teste gnome_win_hints_*-funksjonene for feil. :)"
+
+#: libgnomeui/gnome-about.c:331
+msgid "Author:"
+msgstr "Forfatter:"
+
+#: libgnomeui/gnome-about.c:341 libgnomeui/gnome-about.c:345
+msgid "Authors:"
+msgstr "Forfattere:"
+
+#: libgnomeui/gnome-about.c:679
+msgid "Authors: "
+msgstr "Forfattere: "
+
+#: libgnomeui/gnome-about.c:1172 libgnomeui/gnome-href.c:397
+msgid ""
+"Error occured while trying to launch the URL handler.\n"
+"Please check the settings in the Control Center if they are correct."
+msgstr ""
+"En feil oppsto under forsøk på å starte opp URL-håndtereren.\n"
+"Vennligst sjekk om innstillingene i kontrollsenteret er korrekt."
+
+#: libgnomeui/gnome-animator.c:136
+msgid "Loop type"
+msgstr "Løkketype"
+
+#: libgnomeui/gnome-animator.c:137
+msgid "The type of loop the GnomeAnimator uses"
+msgstr "Type løkke GnomeAnimator bruker"
+
+#: libgnomeui/gnome-animator.c:145
+msgid "Direction"
+msgstr "Retning"
+
+#: libgnomeui/gnome-animator.c:146
+msgid "Animation direction"
+msgstr "Animasjonens retning"
+
+#: libgnomeui/gnome-animator.c:154
+msgid "Number of frames"
+msgstr "Antall bilder"
+
+#: libgnomeui/gnome-animator.c:155
+msgid "Total number of frames in animation"
+msgstr "Totalt antall bilder i animasjonen"
+
+#: libgnomeui/gnome-animator.c:163
+msgid "Current frame"
+msgstr "Aktivt bilde"
+
+#: libgnomeui/gnome-animator.c:164
+msgid "Current frame number"
+msgstr "Nummer på aktivt bilde"
+
+#: libgnomeui/gnome-animator.c:172 libgnomeui/gnome-animator.c:173
+msgid "Animation status"
+msgstr "Animasjonsstatus"
+
+#: libgnomeui/gnome-animator.c:181
+msgid "Speed"
+msgstr "Hastighet"
+
+#: libgnomeui/gnome-animator.c:182
+msgid "Animation speed"
+msgstr "Animasjonshastighet"
+
+#: libgnomeui/gnome-app-helper.c:84
+msgid "_File"
+msgstr "_Fil"
+
+#: libgnomeui/gnome-app-helper.c:85
+msgid "_File/"
+msgstr "_Fil/"
+
+#: libgnomeui/gnome-app-helper.c:86
+msgid "_Edit"
+msgstr "R_ediger"
+
+#: libgnomeui/gnome-app-helper.c:87
+msgid "_Edit/"
+msgstr "R_ediger/"
+
+#: libgnomeui/gnome-app-helper.c:88
+msgid "_View"
+msgstr "_Vis"
+
+#: libgnomeui/gnome-app-helper.c:89
+msgid "_View/"
+msgstr "_Vis/"
+
+#: libgnomeui/gnome-app-helper.c:90
+msgid "_Settings"
+msgstr "_Innstillinger"
+
+#: libgnomeui/gnome-app-helper.c:91
+msgid "_Settings/"
+msgstr "_Innstillinger"
+
+#: libgnomeui/gnome-app-helper.c:92
+msgid "_New"
+msgstr "_Ny"
+
+#: libgnomeui/gnome-app-helper.c:93
+msgid "_New/"
+msgstr "_Ny/"
+
+#: libgnomeui/gnome-app-helper.c:94
+msgid "Fi_les"
+msgstr "Fi_ler"
+
+#: libgnomeui/gnome-app-helper.c:95
+msgid "Fi_les/"
+msgstr "Fi_ler/"
+
+#: libgnomeui/gnome-app-helper.c:96
+msgid "_Windows"
+msgstr "Vin_duer"
+
+#: libgnomeui/gnome-app-helper.c:97
+msgid "_Game"
+msgstr "_Spill"
+
+#: libgnomeui/gnome-app-helper.c:98
+msgid "_Help"
+msgstr "_Hjelp"
+
+#: libgnomeui/gnome-app-helper.c:99
+msgid "_Windows/"
+msgstr "Vin_duer/"
+
+#. Open
+#: libgnomeui/gnome-app-helper.c:111
+msgid "_Open..."
+msgstr "_Åpne..."
+
+#: libgnomeui/gnome-app-helper.c:111
+msgid "Open a file"
+msgstr "Åpne en fil"
+
+#. Save
+#: libgnomeui/gnome-app-helper.c:116
+msgid "_Save"
+msgstr "_Lagre"
+
+#: libgnomeui/gnome-app-helper.c:116
+msgid "Save the current file"
+msgstr "Lagre aktiv fil"
+
+#. Save As
+#: libgnomeui/gnome-app-helper.c:121
+msgid "Save _As..."
+msgstr "L_agre som..."
+
+#: libgnomeui/gnome-app-helper.c:122
+msgid "Save the current file with a different name"
+msgstr "Lagre aktiv fil med et nytt navn"
+
+#. Revert
+#: libgnomeui/gnome-app-helper.c:127
+msgid "_Revert"
+msgstr "_Gå tilbake"
+
+#: libgnomeui/gnome-app-helper.c:128
+msgid "Revert to a saved version of the file"
+msgstr "Gå tilbake til lagret versjon av filen"
+
+#. Print
+#: libgnomeui/gnome-app-helper.c:133
+msgid "_Print"
+msgstr "S_kriv ut"
+
+#: libgnomeui/gnome-app-helper.c:133
+msgid "Print the current file"
+msgstr "Skriv ut aktiv fil"
+
+#. Print Setup
+#: libgnomeui/gnome-app-helper.c:138
+msgid "Print S_etup..."
+msgstr "Skriveropps_ett"
+
+#: libgnomeui/gnome-app-helper.c:139
+msgid "Setup the page settings for your current printer"
+msgstr "Oppsett av sideinnstillingene for din nåværende skriver"
+
+#. Close
+#: libgnomeui/gnome-app-helper.c:144
+msgid "_Close"
+msgstr "L_ukk"
+
+#: libgnomeui/gnome-app-helper.c:144
+msgid "Close the current file"
+msgstr "Lukk aktiv fil"
+
+#. Exit
+#: libgnomeui/gnome-app-helper.c:149
+msgid "E_xit"
+msgstr "_Avslutt"
+
+#: libgnomeui/gnome-app-helper.c:149
+msgid "Exit the program"
+msgstr "Avslutt programmet"
+
+#.
+#. * The "Edit" menu
+#.
+#. Cut
+#: libgnomeui/gnome-app-helper.c:157
+msgid "C_ut"
+msgstr "Klipp _ut"
+
+#: libgnomeui/gnome-app-helper.c:157
+msgid "Cut the selection"
+msgstr "Klipp ut utvalget"
+
+#. 10
+#. Copy
+#: libgnomeui/gnome-app-helper.c:163 libgnomeui/gnome-popup-help.c:65
+msgid "_Copy"
+msgstr "_Kopier"
+
+#: libgnomeui/gnome-app-helper.c:163
+msgid "Copy the selection"
+msgstr "Kopier utvalget"
+
+#. Paste
+#: libgnomeui/gnome-app-helper.c:168 libgnomeui/gnome-popup-help.c:67
+msgid "_Paste"
+msgstr "_Lim inn"
+
+#: libgnomeui/gnome-app-helper.c:168
+msgid "Paste the clipboard"
+msgstr "Lim inn fra utklippstavlen"
+
+#. Clear
+#: libgnomeui/gnome-app-helper.c:173
+msgid "C_lear"
+msgstr "_Slett"
+
+#: libgnomeui/gnome-app-helper.c:173
+msgid "Clear the selection"
+msgstr "Slett utvalget"
+
+#. Undo
+#: libgnomeui/gnome-app-helper.c:178
+msgid "_Undo"
+msgstr "A_ngre"
+
+#: libgnomeui/gnome-app-helper.c:178
+msgid "Undo the last action"
+msgstr "Angre siste handling"
+
+#. Redo
+#: libgnomeui/gnome-app-helper.c:183
+msgid "_Redo"
+msgstr "_Gjenopprett"
+
+#: libgnomeui/gnome-app-helper.c:183
+msgid "Redo the undone action"
+msgstr "Gjenopprett den angrede handlingen"
+
+#. Find
+#: libgnomeui/gnome-app-helper.c:188
+msgid "_Find..."
+msgstr "_Finn..."
+
+#: libgnomeui/gnome-app-helper.c:188
+msgid "Search for a string"
+msgstr "Søk etter en tekststreng"
+
+#. Find Again
+#: libgnomeui/gnome-app-helper.c:193
+msgid "Find _Again"
+msgstr "Finn _igjen"
+
+#: libgnomeui/gnome-app-helper.c:194
+msgid "Search again for the same string"
+msgstr "Søk på nytt etter den samme tekststrengen"
+
+#. Replace
+#: libgnomeui/gnome-app-helper.c:199
+msgid "_Replace..."
+msgstr "E_rstatt"
+
+#: libgnomeui/gnome-app-helper.c:199
+msgid "Replace a string"
+msgstr "Erstatt en tekststreng"
+
+#. Properties
+#: libgnomeui/gnome-app-helper.c:204
+msgid "_Properties..."
+msgstr "E_genskaper..."
+
+#: libgnomeui/gnome-app-helper.c:205
+msgid "Modify the file's properties"
+msgstr "Modifiser filens egenskaper"
+
+#.
+#. * The Settings menu
+#.
+#. Settings
+#: libgnomeui/gnome-app-helper.c:213
+msgid "_Preferences..."
+msgstr "_Brukervalg..."
+
+#: libgnomeui/gnome-app-helper.c:214
+msgid "Configure the application"
+msgstr "Konfigurer applikasjonen"
+
+#. 20
+#.
+#. * And the "Help" menu
+#.
+#. About
+#: libgnomeui/gnome-app-helper.c:223
+msgid "_About"
+msgstr "_Om"
+
+#: libgnomeui/gnome-app-helper.c:224
+msgid "About this application"
+msgstr "Om denne applikasjonen"
+
+#: libgnomeui/gnome-app-helper.c:227
+msgid "_Select All"
+msgstr "_Velg alt"
+
+#: libgnomeui/gnome-app-helper.c:228
+msgid "Select everything"
+msgstr "Velg alt"
+
+#.
+#. * Window menu
+#.
+#: libgnomeui/gnome-app-helper.c:236
+msgid "Create New _Window"
+msgstr "Opprett nytt _vindu"
+
+#: libgnomeui/gnome-app-helper.c:237
+msgid "Create a new window"
+msgstr "Opprett et nytt vindu"
+
+#: libgnomeui/gnome-app-helper.c:241
+msgid "_Close This Window"
+msgstr "L_ukk dette vinduet"
+
+#: libgnomeui/gnome-app-helper.c:242
+msgid "Close the current window"
+msgstr "Lukk aktivt vindu"
+
+#.
+#. * The "Game" menu
+#.
+#: libgnomeui/gnome-app-helper.c:250
+msgid "_New game"
+msgstr "_Nytt spill"
+
+#: libgnomeui/gnome-app-helper.c:251
+msgid "Start a new game"
+msgstr "Start et nytt spill"
+
+#: libgnomeui/gnome-app-helper.c:255
+msgid "_Pause game"
+msgstr "_Pause spillet"
+
+#: libgnomeui/gnome-app-helper.c:256
+msgid "Pause the game"
+msgstr "Pause spillet"
+
+#: libgnomeui/gnome-app-helper.c:260
+msgid "_Restart game"
+msgstr "Sta_rt spillet på nytt"
+
+#: libgnomeui/gnome-app-helper.c:261
+msgid "Restart the game"
+msgstr "Start spillet på nytt"
+
+#: libgnomeui/gnome-app-helper.c:265
+msgid "_Undo move"
+msgstr "An_gre trekk"
+
+#: libgnomeui/gnome-app-helper.c:266
+msgid "Undo the last move"
+msgstr "Angre siste trekk"
+
+#: libgnomeui/gnome-app-helper.c:270
+msgid "_Redo move"
+msgstr "Gjenopp_rett trekk"
+
+#: libgnomeui/gnome-app-helper.c:271
+msgid "Redo the undone move"
+msgstr "Gjenopprett siste angrede trekk"
+
+#: libgnomeui/gnome-app-helper.c:275
+msgid "_Hint"
+msgstr "_Hint"
+
+#: libgnomeui/gnome-app-helper.c:276
+msgid "Get a hint for your next move"
+msgstr "Gi et hint for ditt neste trekk"
+
+#. 30
+#: libgnomeui/gnome-app-helper.c:281
+msgid "_Scores..."
+msgstr "Poeng_summer..."
+
+#: libgnomeui/gnome-app-helper.c:282
+msgid "View the scores"
+msgstr "Se på poengsummene"
+
+#: libgnomeui/gnome-app-helper.c:286
+msgid "_End game"
+msgstr "_Avslutt spillet"
+
+#: libgnomeui/gnome-app-helper.c:287
+msgid "End the current game"
+msgstr "Avslutt aktivt spill"
+
+#: libgnomeui/gnome-app-util.c:100
+msgid " (press return)"
+msgstr " (trykk linjeskift)"
+
+#: libgnomeui/gnome-app-util.c:143
+msgid "ERROR: "
+msgstr "FEIL: "
+
+#: libgnomeui/gnome-app-util.c:180
+msgid "Warning: "
+msgstr "Advarsel:"
+
+#: libgnomeui/gnome-app-util.c:317
+msgid "y"
+msgstr "j"
+
+#: libgnomeui/gnome-app-util.c:318
+msgid "yes"
+msgstr "ja"
+
+#: libgnomeui/gnome-app-util.c:321
+msgid "n"
+msgstr "n"
+
+#: libgnomeui/gnome-app-util.c:322
+msgid "no"
+msgstr "nei"
+
+#: libgnomeui/gnome-app-util.c:361
+msgid " (yes or no)"
+msgstr " (ja eller nei)"
+
+#: libgnomeui/gnome-app-util.c:362
+msgid "  - OK? (yes or no)"
+msgstr "  - OK? (ja eller nei)"
+
+#: libgnomeui/gnome-app-util.c:694
+msgid "Progress"
+msgstr "Fremgang"
+
+#: libgnomeui/gnome-app.c:149
+msgid "App ID"
+msgstr "App-ID"
+
+#: libgnomeui/gnome-app.c:150
+msgid "The application ID string"
+msgstr "Applikasjonens ID-streng"
+
+#: libgnomeui/gnome-canvas-init.c:52
+msgid "Gdk debugging flags to set"
+msgstr "Gdk avlusingsflagg som skal slås på"
+
+#: libgnomeui/gnome-canvas-init.c:52 libgnomeui/gnome-canvas-init.c:55
+#: libgnomeui/gnome-canvas-init.c:85 libgnomeui/gnome-canvas-init.c:88
+msgid "FLAGS"
+msgstr "FLAGG"
+
+#: libgnomeui/gnome-canvas-init.c:55
+msgid "Gdk debugging flags to unset"
+msgstr "Gdk avlusingsflagg som skal slås av"
+
+#: libgnomeui/gnome-canvas-init.c:58 libgnomeui/gnome-init.c:132
+msgid "X display to use"
+msgstr "X-display som skal brukes"
+
+#: libgnomeui/gnome-canvas-init.c:58 libgnomeui/gnome-init.c:132
+msgid "DISPLAY"
+msgstr "DISPLAY"
+
+#: libgnomeui/gnome-canvas-init.c:61
+msgid "Make X calls synchronous"
+msgstr "Bruk synkrone X-kall"
+
+#: libgnomeui/gnome-canvas-init.c:64
+msgid "Don't use X shared memory extension"
+msgstr "Ikke bruk X-utvidelse for delt minne"
+
+#: libgnomeui/gnome-canvas-init.c:67
+msgid "Program name as used by the window manager"
+msgstr "Programnavn som brukt av vindusbehandleren"
+
+#: libgnomeui/gnome-canvas-init.c:67
+msgid "NAME"
+msgstr "NAVN"
+
+#: libgnomeui/gnome-canvas-init.c:70
+msgid "Program class as used by the window manager"
+msgstr "Programklasse som brukt av vindusbehandleren"
+
+#: libgnomeui/gnome-canvas-init.c:70
+msgid "CLASS"
+msgstr "KLASSE"
+
+#: libgnomeui/gnome-canvas-init.c:73
+msgid "HOST"
+msgstr "VERT"
+
+#: libgnomeui/gnome-canvas-init.c:76
+msgid "PORT"
+msgstr "PORT"
+
+#: libgnomeui/gnome-canvas-init.c:79 libgnomeui/gnome-canvas-init.c:82
+msgid "STYLE"
+msgstr "STIL"
+
+#: libgnomeui/gnome-canvas-init.c:85
+msgid "Gtk+ debugging flags to set"
+msgstr "Gtk+ avlusingsflagg som skal slås på"
+
+#: libgnomeui/gnome-canvas-init.c:88
+msgid "Gtk+ debugging flags to unset"
+msgstr "Gtk+ avlusingsflagg som skal slås av"
+
+#: libgnomeui/gnome-canvas-init.c:91
+msgid "Make all warnings fatal"
+msgstr "Gjør alle advarsler til fatale"
+
+#: libgnomeui/gnome-canvas-init.c:94
+msgid "Load an additional Gtk module"
+msgstr "Last tilleggsmodul for Gtk+"
+
+#: libgnomeui/gnome-canvas-init.c:94
+msgid "MODULE"
+msgstr "MODUL"
+
+#: libgnomeui/gnome-client.c:836
+msgid "Specify session management ID"
+msgstr "Spesifiser ID for sesjonskontroll"
+
+#: libgnomeui/gnome-client.c:836
+msgid "ID"
+msgstr "ID"
+
+#: libgnomeui/gnome-client.c:839
+msgid "Specify prefix of saved configuration"
+msgstr "Spesifiser prefiks for lagret konfigurasjon"
+
+#: libgnomeui/gnome-client.c:839
+msgid "PREFIX"
+msgstr "PREFIKS"
+
+#: libgnomeui/gnome-client.c:842
+msgid "Disable connection to session manager"
+msgstr "Fjern forbindelse til sesjonsbehandler"
+
+#: libgnomeui/gnome-client.c:854
+msgid "Session management"
+msgstr "Sesjonshåndtering"
+
+#: libgnomeui/gnome-client.c:2345
+msgid "Cancel Logout"
+msgstr "Avbryt utlogging"
+
+#: libgnomeui/gnome-color-picker.c:421
+msgid "Received invalid color data\n"
+msgstr "Mottok ugyldige fargedata\n"
+
+#: libgnomeui/gnome-color-picker.c:485
+msgid "Pick a color"
+msgstr "Velg en farge"
+
+#: libgnomeui/gnome-dateedit.c:359
+msgid "Time"
+msgstr "Tid"
+
+#: libgnomeui/gnome-dateedit.c:360
+msgid "The time currentlyselected"
+msgstr "Valgt tid"
+
+#: libgnomeui/gnome-dateedit.c:371
+msgid "DateEdit Flags"
+msgstr "DateEdit flagg"
+
+#: libgnomeui/gnome-dateedit.c:372
+msgid "Flags for how DateEdit looks"
+msgstr "Flagg for hvordanm DateEdit ser ut"
+
+#: libgnomeui/gnome-dateedit.c:381
+msgid "Lower Hour"
+msgstr "Laveste tid"
+
+#: libgnomeui/gnome-dateedit.c:382
+msgid "Lower hour in the time popup selector"
+msgstr "Laveste timetall i velgeren"
+
+#: libgnomeui/gnome-dateedit.c:392
+msgid "Upper Hour"
+msgstr "Øvre tid"
+
+#: libgnomeui/gnome-dateedit.c:393
+msgid "Upper hour in the time popup selector"
+msgstr "Øvre time i velgeren"
+
+#: libgnomeui/gnome-dateedit.c:403
+msgid "Initial Time"
+msgstr "Opprinnelig tid"
+
+#: libgnomeui/gnome-dateedit.c:404
+msgid "The initial time"
+msgstr "Opprinnelig tid"
+
+#. Calendar label, only shown if the date editor has a time field
+#: libgnomeui/gnome-dateedit.c:647
+msgid "Calendar"
+msgstr "Kalender"
+
+#: libgnomeui/gnome-dateedit.c:843
+msgid "gnome_date_edit_get_date deprecated, use gnome_date_edit_get_time"
+msgstr "gnome_date_edit_get_date har gått ut, bruk gnome_date_edit_get_time"
+
+#: libgnomeui/gnome-ditem-edit.c:211
+msgid "Name:"
+msgstr "Navn:"
+
+#: libgnomeui/gnome-ditem-edit.c:224
+msgid "Comment:"
+msgstr "Kommentar:"
+
+#: libgnomeui/gnome-ditem-edit.c:234
+msgid "Command:"
+msgstr "Kommando:"
+
+#: libgnomeui/gnome-ditem-edit.c:244
+msgid "Type:"
+msgstr "Type:"
+
+#: libgnomeui/gnome-ditem-edit.c:261
+msgid "Icon:"
+msgstr "Ikon:"
+
+#: libgnomeui/gnome-ditem-edit.c:271
+msgid "Choose an icon"
+msgstr "Velg et ikon"
+
+#: libgnomeui/gnome-ditem-edit.c:283
+msgid "Run in Terminal"
+msgstr "Kjør i terminalvindu"
+
+#: libgnomeui/gnome-ditem-edit.c:309
+msgid "Simple drag and drop"
+msgstr "Enkel dra-og-slipp"
+
+#: libgnomeui/gnome-ditem-edit.c:331
+#, c-format
+msgid ""
+"In the following commands you should use %s in the spot where the\n"
+"filename/URL should be substituted.  If you leave the field blank\n"
+"drops will not be accepted.  If this application can accept\n"
+"multiple files or URLs as arguments after its command name check the box "
+"above."
+msgstr ""
+"I de følgende kommandoene bør du bruke %s som erstatning for filnavn/\n"
+"URL. Hvis du lar feltet stå timt, vil ikke slipp aksepteres. Hvis\n"
+"denne applikasjonen kan motta flere filer eller URLer som argument\n"
+"etter applikasjonsnavnet krysser du av i boksen over."
+
+#: libgnomeui/gnome-ditem-edit.c:343
+msgid "Command for file drops:"
+msgstr "Kommando for slipp av filer:"
+
+#: libgnomeui/gnome-ditem-edit.c:353
+msgid "Drop one file at a time only."
+msgstr "Slipp kun én fil om gangen."
+
+#: libgnomeui/gnome-ditem-edit.c:365
+msgid "Command for URL drops:"
+msgstr "Kommando for slipp av URLer:"
+
+#: libgnomeui/gnome-ditem-edit.c:375
+msgid "Drop one URL at a time only."
+msgstr "Slipp kun én URL om gangen."
+
+#: libgnomeui/gnome-ditem-edit.c:488
+msgid "Try this before using:"
+msgstr "Prøv dette før bruk:"
+
+#: libgnomeui/gnome-ditem-edit.c:498
+msgid "Documentation:"
+msgstr "Dokumentasjon:"
+
+#: libgnomeui/gnome-ditem-edit.c:508
+msgid "Window titles to wait for (comma separated):"
+msgstr "Vindustitler det skal ventes på (kommaseparert):"
+
+#: libgnomeui/gnome-ditem-edit.c:518
+msgid "Name/Comment translations:"
+msgstr "Navngi/Kommenter oversettelsene:"
+
+#: libgnomeui/gnome-ditem-edit.c:521
+msgid "Language"
+msgstr "Språk"
+
+#: libgnomeui/gnome-ditem-edit.c:522
+msgid "Name"
+msgstr "Navn"
+
+#: libgnomeui/gnome-ditem-edit.c:523
+msgid "Comment"
+msgstr "Kommentar"
+
+#: libgnomeui/gnome-ditem-edit.c:551
+msgid "Add/Set"
+msgstr "Legg til/sett"
+
+#: libgnomeui/gnome-ditem-edit.c:556 libgnomeui/gnome-stock.c:569
+msgid "Remove"
+msgstr "Fjern"
+
+#: libgnomeui/gnome-ditem-edit.c:703
+msgid "Basic"
+msgstr "Enkel"
+
+#: libgnomeui/gnome-ditem-edit.c:707
+msgid "Drag and Drop"
+msgstr "Dra-og-slipp"
+
+#: libgnomeui/gnome-ditem-edit.c:711
+msgid "Advanced"
+msgstr "Avansert"
+
+#: libgnomeui/gnome-dock-item.c:230 libgnomeui/gnome-dock-item.c:231
+msgid "Shadow type"
+msgstr "Skyggetype"
+
+#. orientation
+#: libgnomeui/gnome-dock-item.c:239 libgnomeui/gnome-dock-item.c:240
+#: libgnomeui/gnome-helpsys.c:192 libgnomeui/gnome-helpsys.c:193
+#: libgnomeui/gnome-paper-selector.c:191
+msgid "Orientation"
+msgstr "Orientering"
+
+#: libgnomeui/gnome-dock-item.c:248 libgnomeui/gnome-dock-item.c:249
+msgid "Preferred width"
+msgstr "Foretrukket bredde"
+
+#: libgnomeui/gnome-dock-item.c:256 libgnomeui/gnome-dock-item.c:257
+msgid "Preferred height"
+msgstr "Foretrukket høyde"
+
+#: libgnomeui/gnome-druid-page-edge.c:352
+#: libgnomeui/gnome-druid-page-standard.c:301
+msgid "-adobe-helvetica-bold-r-normal-*-*-180-*-*-p-*-*-*,*-r-*"
+msgstr "-adobe-helvetica-fet-r-normal-*-*-180-*-*-p-*-*-*,*-r-*"
+
+#: libgnomeui/gnome-druid-page-edge.c:361
+msgid "-adobe-helvetica-medium-r-normal-*-*-120-*-*-p-*-*-*,*-r-*"
+msgstr "-adobe-helvetica-medium-r-normal-*-*-120-*-*-p-*-*-*,*-r-*"
+
+#: libgnomeui/gnome-druid.c:125
+msgid "Back"
+msgstr "Tilbake"
+
+#: libgnomeui/gnome-druid.c:133
+msgid "Finish"
+msgstr "Fullfør"
+
+#: libgnomeui/gnome-file-saver.c:192
+msgid "File Name:"
+msgstr "Filnavn:"
+
+#: libgnomeui/gnome-file-saver.c:200
+msgid "Location:"
+msgstr "Plassering:"
+
+#: libgnomeui/gnome-file-saver.c:208
+msgid "Save As Type:"
+msgstr "Lagre som type:"
+
+#: libgnomeui/gnome-font-picker.c:856 libgnomeui/gnome-stock.c:589
+msgid "Font"
+msgstr "Skrifttype"
+
+#: libgnomeui/gnome-gconf.c:476
+msgid "GNOME GConf Support"
+msgstr "GNOME GConf støtte"
+
+#: libgnomeui/gnome-gconf.c:516
+#, c-format
+msgid ""
+"You attempted to change an aspect of your configuration that your system "
+"administrator or operating system vendor does not allow you to change. Some "
+"of the settings you have selected may not take effect, or may not be "
+"restored next time you use this application (%s)."
+msgstr ""
+"Du forsøkte å endre et aspekt ved din konfigurasjon som din "
+"systemadministrator ikke tillater deg å endre. Noen av innstillingene du har "
+"valgt vil ikke tre i kraft, eller vil ikke bli gjenopprettet neste gang du "
+"bruker denne applikasjonen (%s)."
+
+#: libgnomeui/gnome-gconf.c:519
+#, c-format
+msgid ""
+"An error occurred while loading or saving configuration information for %s. "
+"Some of your configuration settings may not work properly."
+msgstr ""
+"En feil oppsto under lasting eller lagring av konfigurasjonsinformasjon for "
+"%s. Noen av innstillingene virker kanskje ikke riktig."
+
+#: libgnomeui/gnome-gconf.c:541
+#, c-format
+msgid "GConf error details: %s\n"
+msgstr "Detaljer om GConf feil: %s\n"
+
+#: libgnomeui/gnome-helpsys.c:117
+msgid "_Popup"
+msgstr "_Oppsprett"
+
+#: libgnomeui/gnome-helpsys.c:118
+msgid "Show help in temporary popup windows"
+msgstr "Vis hjelp i midlertidig dialogvindu"
+
+#: libgnomeui/gnome-helpsys.c:120
+msgid "_Embedded"
+msgstr "_Innebygget"
+
+#: libgnomeui/gnome-helpsys.c:121
+msgid "Show help inside the application window"
+msgstr "Vis hjelp inne i applikasjonsvinduet"
+
+#: libgnomeui/gnome-helpsys.c:123
+msgid "_Browser"
+msgstr "_Leser"
+
+#: libgnomeui/gnome-helpsys.c:124
+msgid "Show help in a help browser window"
+msgstr "Vis hjelp i et hjelpleservindu"
+
+#: libgnomeui/gnome-helpsys.c:172
+msgid "App style"
+msgstr "App-stil"
+
+#: libgnomeui/gnome-helpsys.c:173
+msgid "The style of GnomeHelpView"
+msgstr "GnomeHelpView stil"
+
+#: libgnomeui/gnome-helpsys.c:182
+msgid "App style priority"
+msgstr "Prioritet for app-stil"
+
+#: libgnomeui/gnome-helpsys.c:183
+msgid "The priority of style of GnomeHelpView"
+msgstr "Prioriteten for GnomeHelpView stilen"
+
+#: libgnomeui/gnome-helpsys.c:202
+msgid "Toplevel"
+msgstr "Toppnivå"
+
+#: libgnomeui/gnome-helpsys.c:203
+msgid "The toplevel widget"
+msgstr "Det øverste widgetet"
+
+#: libgnomeui/gnome-helpsys.c:220
+msgid "Show help for a specific region of the application"
+msgstr "Vis hjelp for en spesiell del av applikasjonen"
+
+#: libgnomeui/gnome-helpsys.c:225
+msgid "Style"
+msgstr "Stil"
+
+#: libgnomeui/gnome-helpsys.c:226
+msgid "Change the way help is displayed"
+msgstr "Endre måten hjelpen vises"
+
+#: libgnomeui/gnome-helpsys.c:926 libgnomeui/gnome-helpsys.c:1020
+msgid "No help is available for the selected portion of the application."
+msgstr ""
+"Ingen hjelp er tilgjengelig for den valgte delen av denne applikasjonen."
+
+#. FIXME: properly handle the error!
+#: libgnomeui/gnome-helpsys.c:1192
+#, c-format
+msgid "Cought GnomeURL error: %s"
+msgstr "Fanget opp GnomeURL feil: %s"
+
+#: libgnomeui/gnome-href.c:112
+msgid "URL"
+msgstr "URL"
+
+#: libgnomeui/gnome-href.c:113
+msgid "The URL that GnomeHRef activates"
+msgstr "URLen som GnomeHRef aktiverer"
+
+#: libgnomeui/gnome-href.c:120
+msgid "Text"
+msgstr "Tekst"
+
+#: libgnomeui/gnome-href.c:121
+msgid "The text on the button"
+msgstr "Teksten på knappen"
+
+#: libgnomeui/gnome-href.c:122
+msgid "End World Hunger"
+msgstr "End world hunger"
+
+#: libgnomeui/gnome-icon-entry.c:348 libgnomeui/gnome-icon-entry.c:717
+#: libgnomeui/gnome-icon-entry.c:734
+msgid "No Icon"
+msgstr "Uten ikon"
+
+#: libgnomeui/gnome-init.c:90
+msgid "Bonobo UI"
+msgstr "Bonobo-UI"
+
+#. dialog display isn't working out
+#: libgnomeui/gnome-init.c:453
+msgid "Multiple segmentation faults occurred; can't display error dialog\n"
+msgstr "Flere segmenteringsfeil oppstod; kan ikke vise feildialogen\n"
+
+#: libgnomeui/gnome-messagebox.c:179
+msgid "Information"
+msgstr "Informasjon"
+
+#: libgnomeui/gnome-messagebox.c:188
+msgid "Warning"
+msgstr "Advarsel"
+
+#: libgnomeui/gnome-messagebox.c:197
+msgid "Error"
+msgstr "Feil"
+
+#: libgnomeui/gnome-messagebox.c:206
+msgid "Question"
+msgstr "Spørsmål"
+
+#: libgnomeui/gnome-messagebox.c:215
+msgid "Message"
+msgstr "Beskjed"
+
+#. paper size
+#: libgnomeui/gnome-paper-selector.c:159
+msgid "Paper Size"
+msgstr "Papirstørrelse"
+
+#: libgnomeui/gnome-paper-selector.c:213
+msgid "Portrait"
+msgstr "Portrett"
+
+#: libgnomeui/gnome-paper-selector.c:233
+msgid "Landscape"
+msgstr "Landskap"
+
+#. margins
+#: libgnomeui/gnome-paper-selector.c:241
+msgid "Margins"
+msgstr "Marger"
+
+#: libgnomeui/gnome-paper-selector.c:253
+msgid "Top:"
+msgstr "Topp:"
+
+#: libgnomeui/gnome-paper-selector.c:266
+msgid "Bottom:"
+msgstr "Bunn:"
+
+#: libgnomeui/gnome-paper-selector.c:279
+msgid "Left:"
+msgstr "Venstre:"
+
+#: libgnomeui/gnome-paper-selector.c:292
+msgid "Right:"
+msgstr "Høyre:"
+
+#. Scaling
+#: libgnomeui/gnome-paper-selector.c:306
+msgid "Scaling"
+msgstr "Skalering"
+
+#: libgnomeui/gnome-paper-selector.c:321
+msgid "Fit to Page"
+msgstr "Tilpass til siden"
+
+#: libgnomeui/gnome-paper-selector.c:810
+#, c-format
+msgid "%0.3g%s x %0.3g%s"
+msgstr "%0.3g%s x %0.3g%s"
+
+#: libgnomeui/gnome-paper-selector.c:1040
+msgid "Page Setup"
+msgstr "Papiroppsett"
+
+#: libgnomeui/gnome-popup-help.c:57
+msgid "_Help with this"
+msgstr "_Hjelp om dette"
+
+#: libgnomeui/gnome-popup-help.c:63
+msgid "Cu_t"
+msgstr "K_lipp"
+
+#. to be kept in sync with GtkCornerType enumeration
+#: libgnomeui/gnome-pouch.c:782
+msgid "Top left"
+msgstr "Øverst til venstre"
+
+#: libgnomeui/gnome-pouch.c:783
+msgid "Bottom left"
+msgstr "Nederst til venstre"
+
+#: libgnomeui/gnome-pouch.c:784
+msgid "Top right"
+msgstr "Øverst til høyre"
+
+#: libgnomeui/gnome-pouch.c:785
+msgid "Bottom right"
+msgstr "Nederst til venstre"
+
+#. to be kept in sync with GtkOrientation enumeration
+#: libgnomeui/gnome-pouch.c:796
+msgid "Horizontal"
+msgstr "Horisontal"
+
+#: libgnomeui/gnome-pouch.c:797
+msgid "Vertical"
+msgstr "Vertikal"
+
+#: libgnomeui/gnome-pouch.c:807
+msgid "Icon position"
+msgstr "Ikonposisjon"
+
+#: libgnomeui/gnome-pouch.c:808
+msgid "Icon orientation"
+msgstr "Ikonorientering"
+
+#: libgnomeui/gnome-pouch.c:810
+msgid "Tile children"
+msgstr "Flislegg avkom"
+
+#: libgnomeui/gnome-pouch.c:811
+msgid "Cascade children"
+msgstr "Vis avkom side-ved-side"
+
+#: libgnomeui/gnome-pouch.c:813
+msgid "Arrange icons"
+msgstr "Plassér ikoner"
+
+#: libgnomeui/gnome-pouch.c:814
+msgid "Autoarrange icons"
+msgstr "Plassér ikoner automatisk"
+
+#: libgnomeui/gnome-recently-used.c:111
+msgid "App Specific"
+msgstr "Applikasjonsspesifikk"
+
+#: libgnomeui/gnome-recently-used.c:112
+msgid "Is this list application specific"
+msgstr "Er denne listen applikasjonsspesifikk"
+
+#: libgnomeui/gnome-recently-used.c:893
+#, c-format
+msgid "bad GnomeRecentDocument attribute: %s\n"
+msgstr "ugyldig GnomeRecentDocument attributt: %s\n"
+
+#: libgnomeui/gnome-recently-used.c:1123
+msgid "Unknown"
+msgstr "Ukjent"
+
+#: libgnomeui/gnome-scores.c:105
+msgid "Top Ten"
+msgstr "Topp ti"
+
+#: libgnomeui/gnome-scores.c:115
+msgid "User"
+msgstr "Bruker"
+
+#: libgnomeui/gnome-scores.c:118
+msgid "Score"
+msgstr "Poengsum"
+
+#: libgnomeui/gnome-scores.c:121
+msgid "Date"
+msgstr "Dato"
+
+#. the localized string should fit (after replacing the %a %b
+#. etc) in ~18 chars.
+#. %a is abbreviated weekday, %A is full weekday,
+#. %b %B are abbreviated and full monthname, %Y is year,
+#. %d is day of month, %m is month number, %T full hour,
+#. %H hours, %M minutes, %S seconds
+#.
+#: libgnomeui/gnome-scores.c:236
+msgid "%a %b %d %T %Y"
+msgstr "%a %b %d %T %Y"
+
+#: libgnomeui/gnome-scores.c:444
+msgid "-freefont-garamond-*-*-*-*-30-170-*-*-*-*-*-*,*-r-*"
+msgstr "-freefont-garamond-*-*-*-*-30-170-*-*-*-*-*-*,*-r-*"
+
+#: libgnomeui/gnome-selector.c:1037
+msgid "Browse..."
+msgstr "Bla gjennom..."
+
+#: libgnomeui/gnome-selector.c:1048
+msgid "Default..."
+msgstr "Forvalgt..."
+
+#: libgnomeui/gnome-selector.c:1059
+msgid "Clear..."
+msgstr "Tøm..."
+
+#: libgnomeui/gnome-stock.c:566
+msgid "Add"
+msgstr "Legg til"
+
+#: libgnomeui/gnome-stock.c:567
+msgid "Clear"
+msgstr "Slett"
+
+#: libgnomeui/gnome-stock.c:568
+msgid "Select Color"
+msgstr "Velg farge"
+
+#: libgnomeui/gnome-stock.c:570
+msgid "Table Borders"
+msgstr "Kanter for tabell"
+
+#: libgnomeui/gnome-stock.c:571
+msgid "Table Fill"
+msgstr "Fyll for tabell"
+
+#: libgnomeui/gnome-stock.c:572
+msgid "Bulleted List"
+msgstr "Punktmerket liste"
+
+#: libgnomeui/gnome-stock.c:573
+msgid "Numbered List"
+msgstr "Nummerert liste"
+
+#: libgnomeui/gnome-stock.c:574
+msgid "Indent"
+msgstr "Indentér"
+
+#: libgnomeui/gnome-stock.c:575
+msgid "Un-Indent"
+msgstr "Av-indentér"
+
+#: libgnomeui/gnome-stock.c:578
+msgid "OK"
+msgstr "OK"
+
+#: libgnomeui/gnome-stock.c:579
+msgid "Apply"
+msgstr "Bruk"
+
+#: libgnomeui/gnome-stock.c:580
+msgid "Cancel"
+msgstr "Avbryt"
+
+#: libgnomeui/gnome-stock.c:582
+msgid "Yes"
+msgstr "Ja"
+
+#: libgnomeui/gnome-stock.c:583
+msgid "No"
+msgstr "Nei"
+
+#: libgnomeui/gnome-stock.c:585
+msgid "Next"
+msgstr "Neste"
+
+#: libgnomeui/gnome-stock.c:586
+msgid "Prev"
+msgstr "Forrige"
+
+#: libgnomeui/gnome-stock.c:587
+msgid "Up"
+msgstr "Opp"
+
+#: libgnomeui/gnome-stock.c:588
+msgid "Down"
+msgstr "Ned"
+
+#: libgnomeui/gnome-stock.c:1357
+msgid "Menu Accelerator Keys"
+msgstr "Taster for menyakselleratorer"
+
+#: libgnomeui/gnome-stock.c:1359
+msgid "Global"
+msgstr "Global"
+
+#: libgnomeui/gnome-stock.c:1361
+msgid "Menu Item"
+msgstr "Menyvalg"
+
+#: libgnomeui/gnome-stock.c:1362
+msgid "Accelerator"
+msgstr "Aksellerator"
+
+#: libgnomeui/gnome_segv.c:85
+#, c-format
+msgid ""
+"The GNOME Session Manager (process %d) has crashed\n"
+"due to a fatal error (%s).\n"
+"When you close this dialog, all applications will close and your session "
+"will exit.\n"
+"Please save all your files before closing this dialog."
+msgstr ""
+"GNOME's sesjonhåndterer (prosess %d) har krasjet\n"
+"pga en fatal feil (%s).\n"
+"Når du lukker denne dialogen vil alle applikasjoner lukkes og din sesjon \n"
+"vil avslutte.\n"
+"Vennligst lagre alle åpne filer før du lukker denne dialogen."
+
+#: libgnomeui/gnome_segv.c:95
+#, c-format
+msgid ""
+"Application \"%s\" (process %d) has crashed\n"
+"due to a fatal error.\n"
+"(%s)"
+msgstr ""
+"Applikasjonen \"%s\" (prosess %d) har krasjet\n"
+"pga en fatal feil.\n"
+"(%s)"
+
+#: libgnomeui/gnome_segv.c:104
+msgid "Usage: gnome_segv appname signum\n"
+msgstr "Bruk: gnome_segv appname signum\n"
+
+#: libgnomeui/gnome_segv.c:118
+msgid "Submit a bug report"
+msgstr "Send inn en feilrapport"
+
+#: libgnomeui/gnome_segv.c:128
+msgid "Debug"
+msgstr "Feilsøk"
+
+#: libgnomeui/gnome_segv.c:135
+msgid "http://www.gnome.org/application_crashed.shtml";
+msgstr "http://www.gnome.org/application_crashed.shtml";
+
+#: libgnomeui/gnome_segv.c:141
+msgid "Please visit the GNOME Application Crash page for more information"
+msgstr "Vennligst besøk GNOME Applikasjonskrasj-siden for mer informasjon"
+
+#: libgnomeui/oafgnome.c:242
+msgid "Username:"
+msgstr "Brukernavn:"
+
+#: libgnomeui/oafgnome.c:256
+msgid "Password:"
+msgstr "Passord:"



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]