From c801d85f158c4cba50b588807daabdcbd0ed3853 Mon Sep 17 00:00:00 2001
From: =?utf8?q?Karsten=20Ball=C3=BCder?= <ballueder@usa.net>
Date: Wed, 20 May 1998 14:01:55 +0000
Subject: [PATCH] Initial revision

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 INSTALL                              |  321 ++
 Makefile                             |  167 +
 config.guess                         |  599 +++
 config.sub                           |  927 ++++
 configure                            | 6572 ++++++++++++++++++++++++++
 configure.in                         | 1453 ++++++
 docs/changes.txt                     |  227 +
 docs/gtk/welcome.html                |  292 ++
 docs/licence.txt                     |  224 +
 docs/readme.txt                      |   10 +
 docs/symbols.txt                     |   56 +
 im_palette.pal                       |   48 +
 imrc                                 |   99 +
 include/wx/app.h                     |   61 +
 include/wx/bitmap.h                  |   13 +
 include/wx/bmpbuttn.h                |   12 +
 include/wx/brush.h                   |   13 +
 include/wx/button.h                  |   13 +
 include/wx/checkbox.h                |   13 +
 include/wx/choicdlg.h                |    7 +
 include/wx/choice.h                  |   13 +
 include/wx/clipbrd.h                 |   13 +
 include/wx/cmndata.h                 |  223 +
 include/wx/colordlg.h                |   13 +
 include/wx/combobox.h                |   13 +
 include/wx/config.h                  |  121 +
 include/wx/control.h                 |   13 +
 include/wx/cursor.h                  |   13 +
 include/wx/date.h                    |  131 +
 include/wx/dc.h                      |   13 +
 include/wx/dcclient.h                |   13 +
 include/wx/dcmemory.h                |   13 +
 include/wx/dcprint.h                 |    9 +
 include/wx/dcscreen.h                |   13 +
 include/wx/dde.h                     |   13 +
 include/wx/debug.h                   |   94 +
 include/wx/defs.h                    |  861 ++++
 include/wx/dialog.h                  |   13 +
 include/wx/dirdlg.h                  |   13 +
 include/wx/dnd.h                     |   11 +
 include/wx/docview.h                 |  519 ++
 include/wx/dynarray.h                |  338 ++
 include/wx/event.h                   | 1199 +++++
 include/wx/file.h                    |  159 +
 include/wx/filedlg.h                 |   13 +
 include/wx/filefn.h                  |  166 +
 include/wx/font.h                    |   13 +
 include/wx/fontdlg.h                 |   13 +
 include/wx/frame.h                   |   13 +
 include/wx/gauge.h                   |   13 +
 include/wx/gdicmn.h                  |  335 ++
 include/wx/gdiobj.h                  |   13 +
 include/wx/generic/choicdgg.h        |  100 +
 include/wx/generic/colrdlgg.h        |  121 +
 include/wx/generic/fontdlgg.h        |   94 +
 include/wx/generic/gridg.h           |  319 ++
 include/wx/generic/helpxlp.h         |  127 +
 include/wx/generic/imaglist.h        |   67 +
 include/wx/generic/listctrl.h        |  649 +++
 include/wx/generic/msgdlgg.h         |   52 +
 include/wx/generic/panelg.h          |   69 +
 include/wx/generic/printps.h         |   57 +
 include/wx/generic/prntdlgg.h        |  145 +
 include/wx/generic/scrolwin.h        |  141 +
 include/wx/generic/splitter.h        |  180 +
 include/wx/generic/statusbr.h        |   92 +
 include/wx/generic/tabg.h            |  343 ++
 include/wx/generic/textdlgg.h        |   51 +
 include/wx/generic/treectrl.h        |  300 ++
 include/wx/grid.h                    |   11 +
 include/wx/gtk/app.h                 |  113 +
 include/wx/gtk/bitmap.h              |  118 +
 include/wx/gtk/bmpbuttn.h            |   34 +
 include/wx/gtk/brush.h               |   60 +
 include/wx/gtk/button.h              |   58 +
 include/wx/gtk/checkbox.h            |   57 +
 include/wx/gtk/choice.h              |   68 +
 include/wx/gtk/colour.h              |   76 +
 include/wx/gtk/combobox.h            |   34 +
 include/wx/gtk/control.h             |   51 +
 include/wx/gtk/cursor.h              |   61 +
 include/wx/gtk/dc.h                  |  306 ++
 include/wx/gtk/dcclient.h            |  107 +
 include/wx/gtk/dcmemory.h            |   49 +
 include/wx/gtk/dcscreen.h            |   32 +
 include/wx/gtk/dialog.h              |   95 +
 include/wx/gtk/dirdlg.h              |   35 +
 include/wx/gtk/dnd.h                 |  116 +
 include/wx/gtk/filedlg.h             |   93 +
 include/wx/gtk/font.h                |  120 +
 include/wx/gtk/frame.h               |   90 +
 include/wx/gtk/gauge.h               |   34 +
 include/wx/gtk/gdiobj.h              |   37 +
 include/wx/gtk/icon.h                |   53 +
 include/wx/gtk/listbox.h             |   85 +
 include/wx/gtk/mdi.h                 |  146 +
 include/wx/gtk/menu.h                |  107 +
 include/wx/gtk/palette.h             |   60 +
 include/wx/gtk/pen.h                 |   68 +
 include/wx/gtk/radiobox.h            |   84 +
 include/wx/gtk/radiobut.h            |   31 +
 include/wx/gtk/region.h              |   99 +
 include/wx/gtk/scrolbar.h            |   82 +
 include/wx/gtk/settings.h            |   40 +
 include/wx/gtk/setup.h               |  534 +++
 include/wx/gtk/slider.h              |   91 +
 include/wx/gtk/statbmp.h             |   34 +
 include/wx/gtk/statbox.h             |   55 +
 include/wx/gtk/stattext.h            |   57 +
 include/wx/gtk/tbargtk.h             |  139 +
 include/wx/gtk/textctrl.h            |  106 +
 include/wx/gtk/timer.h               |   53 +
 include/wx/gtk/win_gtk.h             |   75 +
 include/wx/gtk/window.h              |  262 +
 include/wx/gtk1/app.h                |  113 +
 include/wx/gtk1/bitmap.h             |  118 +
 include/wx/gtk1/bmpbuttn.h           |   34 +
 include/wx/gtk1/brush.h              |   60 +
 include/wx/gtk1/button.h             |   58 +
 include/wx/gtk1/checkbox.h           |   57 +
 include/wx/gtk1/choice.h             |   68 +
 include/wx/gtk1/colour.h             |   76 +
 include/wx/gtk1/combobox.h           |   34 +
 include/wx/gtk1/control.h            |   51 +
 include/wx/gtk1/cursor.h             |   61 +
 include/wx/gtk1/dc.h                 |  306 ++
 include/wx/gtk1/dcclient.h           |  107 +
 include/wx/gtk1/dcmemory.h           |   49 +
 include/wx/gtk1/dcscreen.h           |   32 +
 include/wx/gtk1/dialog.h             |   95 +
 include/wx/gtk1/dirdlg.h             |   35 +
 include/wx/gtk1/dnd.h                |  116 +
 include/wx/gtk1/filedlg.h            |   93 +
 include/wx/gtk1/font.h               |  120 +
 include/wx/gtk1/frame.h              |   90 +
 include/wx/gtk1/gauge.h              |   34 +
 include/wx/gtk1/gdiobj.h             |   37 +
 include/wx/gtk1/icon.h               |   53 +
 include/wx/gtk1/listbox.h            |   85 +
 include/wx/gtk1/mdi.h                |  146 +
 include/wx/gtk1/menu.h               |  107 +
 include/wx/gtk1/palette.h            |   60 +
 include/wx/gtk1/pen.h                |   68 +
 include/wx/gtk1/radiobox.h           |   84 +
 include/wx/gtk1/radiobut.h           |   31 +
 include/wx/gtk1/region.h             |   99 +
 include/wx/gtk1/scrolbar.h           |   82 +
 include/wx/gtk1/settings.h           |   40 +
 include/wx/gtk1/setup.h              |  534 +++
 include/wx/gtk1/slider.h             |   91 +
 include/wx/gtk1/statbmp.h            |   34 +
 include/wx/gtk1/statbox.h            |   55 +
 include/wx/gtk1/stattext.h           |   57 +
 include/wx/gtk1/tbargtk.h            |  139 +
 include/wx/gtk1/textctrl.h           |  106 +
 include/wx/gtk1/timer.h              |   53 +
 include/wx/gtk1/win_gtk.h            |   75 +
 include/wx/gtk1/window.h             |  262 +
 include/wx/hash.h                    |   98 +
 include/wx/help.h                    |   13 +
 include/wx/helpbase.h                |   50 +
 include/wx/helphtml.h                |    7 +
 include/wx/helpwin.h                 |    7 +
 include/wx/helpxlp.h                 |    7 +
 include/wx/icon.h                    |   13 +
 include/wx/imaglist.h                |   13 +
 include/wx/intl.h                    |  159 +
 include/wx/ipcbase.h                 |   93 +
 include/wx/layout.h                  |  304 ++
 include/wx/list.h                    |  148 +
 include/wx/listbox.h                 |   13 +
 include/wx/listctrl.h                |   13 +
 include/wx/log.h                     |  275 ++
 include/wx/matrix.h                  |  139 +
 include/wx/mdi.h                     |   13 +
 include/wx/memory.h                  |  277 ++
 include/wx/menu.h                    |   13 +
 include/wx/menuitem.h                |   89 +
 include/wx/metafile.h                |    9 +
 include/wx/minifram.h                |   13 +
 include/wx/module.h                  |   49 +
 include/wx/msgdlg.h                  |   13 +
 include/wx/object.h                  |  269 ++
 include/wx/odbc.h                    |  322 ++
 include/wx/palette.h                 |   13 +
 include/wx/panel.h                   |    7 +
 include/wx/pen.h                     |   13 +
 include/wx/pnghand.h                 |   13 +
 include/wx/postscrp.h                |  294 ++
 include/wx/print.h                   |   28 +
 include/wx/printdlg.h                |   13 +
 include/wx/prntbase.h                |  335 ++
 include/wx/radiobox.h                |   13 +
 include/wx/radiobut.h                |   13 +
 include/wx/region.h                  |   13 +
 include/wx/scrolbar.h                |   13 +
 include/wx/scrolwin.h                |    7 +
 include/wx/settings.h                |  117 +
 include/wx/setup.h                   |   14 +
 include/wx/slider.h                  |   13 +
 include/wx/spinbutt.h                |   13 +
 include/wx/splitter.h                |    7 +
 include/wx/statbmp.h                 |   13 +
 include/wx/statbox.h                 |   13 +
 include/wx/stattext.h                |   13 +
 include/wx/statusbr.h                |    7 +
 include/wx/string.h                  |  832 ++++
 include/wx/tab.h                     |    7 +
 include/wx/tabctrl.h                 |   13 +
 include/wx/textctrl.h                |   13 +
 include/wx/textdlg.h                 |    7 +
 include/wx/textfile.h                |  123 +
 include/wx/time.h                    |   97 +
 include/wx/timer.h                   |   13 +
 include/wx/toolbar.h                 |   11 +
 include/wx/treectrl.h                |   13 +
 include/wx/types.h                   |   97 +
 include/wx/utils.h                   |  309 ++
 include/wx/validate.h                |   70 +
 include/wx/valtext.h                 |   77 +
 include/wx/version.h                 |   25 +
 include/wx/window.h                  |   13 +
 include/wx/wx.h                      |   70 +
 include/wx/wxprec.h                  |   61 +
 install-sh                           |  250 +
 lib/dummy                            |    1 +
 misc/afm/Cour.afm                    |  341 ++
 misc/afm/CourBo.afm                  |  341 ++
 misc/afm/CourBoO.afm                 |  341 ++
 misc/afm/CourO.afm                   |  341 ++
 misc/afm/Helv.afm                    |  435 ++
 misc/afm/HelvBo.afm                  |  431 ++
 misc/afm/HelvBoO.afm                 |  429 ++
 misc/afm/HelvO.afm                   |  428 ++
 misc/afm/TimesBo.afm                 |  454 ++
 misc/afm/TimesBoO.afm                |  438 ++
 misc/afm/TimesO.afm                  |  450 ++
 misc/afm/TimesRo.afm                 |  443 ++
 misc/gs_afm/Cour.afm                 |  255 +
 misc/gs_afm/CourBo.afm               |  255 +
 misc/gs_afm/CourBoO.afm              |  255 +
 misc/gs_afm/CourO.afm                |  255 +
 misc/gs_afm/Helv.afm                 | 1257 +++++
 misc/gs_afm/HelvBo.afm               | 1257 +++++
 misc/gs_afm/HelvBoO.afm              | 1257 +++++
 misc/gs_afm/HelvO.afm                | 1257 +++++
 misc/gs_afm/TimesBo.afm              | 1257 +++++
 misc/gs_afm/TimesBoO.afm             | 1253 +++++
 misc/gs_afm/TimesO.afm               | 1253 +++++
 misc/gs_afm/TimesRo.afm              | 1257 +++++
 samples/Makefile                     |    1 +
 samples/grid/Makefile                |    1 +
 samples/grid/Makefile.in             |   26 +
 samples/grid/aiai.ico                |  Bin 0 -> 766 bytes
 samples/grid/aiai.xbm                |   38 +
 samples/grid/bitmap1.bmp             |  Bin 0 -> 406 bytes
 samples/grid/bitmap2.bmp             |  Bin 0 -> 238 bytes
 samples/grid/test.cpp                |  318 ++
 samples/grid/test.def                |    8 +
 samples/grid/test.rc                 |    5 +
 samples/internat/Makefile            |    1 +
 samples/internat/Makefile.in         |   26 +
 samples/internat/aiai.ico            |  Bin 0 -> 766 bytes
 samples/internat/aiai.xbm            |   38 +
 samples/internat/internat.cpp        |  151 +
 samples/internat/internat.def        |    8 +
 samples/internat/internat.po         |   74 +
 samples/internat/internat.rc         |    3 +
 samples/internat/makefile.b32        |   64 +
 samples/internat/makefile.bcc        |   73 +
 samples/internat/makefile.dos        |   65 +
 samples/internat/makefile.g95        |   36 +
 samples/internat/makefile.nt         |   64 +
 samples/internat/makefile.sc         |   35 +
 samples/internat/makefile.unx        |   58 +
 samples/internat/makefile.vms        |   38 +
 samples/internat/makefile.wat        |   43 +
 samples/internat/mondrian.ico        |  Bin 0 -> 766 bytes
 samples/internat/wxstd.po            |  131 +
 samples/layout/Makefile              |    1 +
 samples/layout/Makefile.in           |   26 +
 samples/layout/aiai.ico              |  Bin 0 -> 766 bytes
 samples/layout/aiai.xbm              |   38 +
 samples/layout/expt.cpp              |  161 +
 samples/layout/fload.xbm             |   11 +
 samples/layout/layout.cpp            |  367 ++
 samples/layout/layout.def            |    9 +
 samples/layout/layout.h              |   79 +
 samples/layout/layout.rc             |    3 +
 samples/layout/makefile.b32          |   63 +
 samples/layout/makefile.bcc          |   76 +
 samples/layout/makefile.dos          |   85 +
 samples/layout/makefile.g95          |   35 +
 samples/layout/makefile.nt           |   63 +
 samples/layout/makefile.sc           |   37 +
 samples/layout/makefile.unx          |   76 +
 samples/layout/makefile.vms          |   41 +
 samples/layout/makefile.wat          |   44 +
 samples/mdi/Makefile                 |    1 +
 samples/mdi/Makefile.in              |   26 +
 samples/mdi/aiai.ico                 |  Bin 0 -> 766 bytes
 samples/mdi/aiai.xbm                 |   38 +
 samples/mdi/chart.ico                |  Bin 0 -> 766 bytes
 samples/mdi/makefile.b32             |   64 +
 samples/mdi/makefile.bcc             |   75 +
 samples/mdi/makefile.dos             |   63 +
 samples/mdi/makefile.g95             |   35 +
 samples/mdi/makefile.nt              |   63 +
 samples/mdi/makefile.sc              |   36 +
 samples/mdi/makefile.unx             |   55 +
 samples/mdi/makefile.vms             |   38 +
 samples/mdi/makefile.wat             |   43 +
 samples/mdi/mdi.cpp                  |  381 ++
 samples/mdi/mdi.def                  |    8 +
 samples/mdi/mdi.h                    |   82 +
 samples/mdi/mdi.ico                  |  Bin 0 -> 766 bytes
 samples/mdi/mdi.rc                   |   24 +
 samples/mdi/mondrian.ico             |  Bin 0 -> 766 bytes
 samples/minimal/Makefile             |    1 +
 samples/minimal/Makefile.in          |   26 +
 samples/minimal/aiai.ico             |  Bin 0 -> 766 bytes
 samples/minimal/aiai.xbm             |   38 +
 samples/minimal/makefile.b32         |   64 +
 samples/minimal/makefile.bcc         |   73 +
 samples/minimal/makefile.dos         |   65 +
 samples/minimal/makefile.g95         |   37 +
 samples/minimal/makefile.nt          |   64 +
 samples/minimal/makefile.sc          |   35 +
 samples/minimal/makefile.unx         |   58 +
 samples/minimal/makefile.vms         |   38 +
 samples/minimal/makefile.wat         |   43 +
 samples/minimal/minimal.cpp          |  116 +
 samples/minimal/minimal.def          |    8 +
 samples/minimal/minimal.rc           |    3 +
 samples/minimal/mondrian.ico         |  Bin 0 -> 766 bytes
 samples/png/Makefile                 |    1 +
 samples/png/Makefile.in              |   26 +
 samples/png/makefile.nt              |   66 +
 samples/png/pngdemo.cpp              |  186 +
 samples/png/pngdemo.h                |   57 +
 samples/png/pngdemo.rc               |    2 +
 samples/printing/Cour.afm            |  341 ++
 samples/printing/CourBo.afm          |  341 ++
 samples/printing/CourBoO.afm         |  341 ++
 samples/printing/CourO.afm           |  341 ++
 samples/printing/Helv.afm            |  435 ++
 samples/printing/HelvBo.afm          |  431 ++
 samples/printing/HelvBoO.afm         |  429 ++
 samples/printing/HelvO.afm           |  428 ++
 samples/printing/Makefile            |    1 +
 samples/printing/Makefile.in         |   26 +
 samples/printing/TimesBo.afm         |  454 ++
 samples/printing/TimesBoO.afm        |  438 ++
 samples/printing/TimesO.afm          |  450 ++
 samples/printing/TimesRo.afm         |  443 ++
 samples/printing/aiai.ico            |  Bin 0 -> 766 bytes
 samples/printing/aiai.xbm            |   38 +
 samples/printing/fload.xbm           |   11 +
 samples/printing/printing.cpp        |  550 +++
 samples/printing/printing.def        |    9 +
 samples/printing/printing.h          |   89 +
 samples/printing/printing.rc         |    3 +
 samples/splitter/Makefile            |    1 +
 samples/splitter/Makefile.in         |   26 +
 samples/splitter/aiai.xbm            |   38 +
 samples/splitter/makefile.b32        |   64 +
 samples/splitter/makefile.g95        |   37 +
 samples/splitter/makefile.nt         |   63 +
 samples/splitter/mondrian.ico        |  Bin 0 -> 766 bytes
 samples/splitter/test.cpp            |  230 +
 samples/splitter/test.def            |    8 +
 samples/splitter/test.rc             |    4 +
 samples/tab/Makefile                 |    1 +
 samples/tab/Makefile.in              |   26 +
 samples/tab/makefile.b32             |   64 +
 samples/tab/makefile.bcc             |   73 +
 samples/tab/makefile.dos             |   65 +
 samples/tab/makefile.g95             |   37 +
 samples/tab/makefile.nt              |   64 +
 samples/tab/makefile.sc              |   35 +
 samples/tab/makefile.unx             |   58 +
 samples/tab/makefile.vms             |   38 +
 samples/tab/makefile.wat             |   43 +
 samples/tab/mondrian.ico             |  Bin 0 -> 766 bytes
 samples/tab/test.cpp                 |  147 +
 samples/tab/test.def                 |    8 +
 samples/tab/test.h                   |   49 +
 samples/tab/test.rc                  |    3 +
 src/Makefile                         |    1 +
 src/Makefile.in                      |  183 +
 src/common/cmndata.cpp               |  473 ++
 src/common/config.cpp                |  153 +
 src/common/date.cpp                  |  650 +++
 src/common/docview.cpp               | 1898 ++++++++
 src/common/dynarray.cpp              |  216 +
 src/common/event.cpp                 |  442 ++
 src/common/file.cpp                  |  399 ++
 src/common/fileconf.cpp              | 1248 +++++
 src/common/filefn.cpp                | 1314 +++++
 src/common/gdicmn.cpp                |  603 +++
 src/common/glob.inc                  |  361 ++
 src/common/hash.cpp                  |  350 ++
 src/common/helpbase.cpp              |   35 +
 src/common/intl.cpp                  |  538 +++
 src/common/ipcbase.cpp               |   35 +
 src/common/layout.cpp                | 1747 +++++++
 src/common/list.cpp                  |  640 +++
 src/common/log.cpp                   |  611 +++
 src/common/matrix.cpp                |  267 ++
 src/common/memory.cpp                | 1082 +++++
 src/common/module.cpp                |   73 +
 src/common/object.cpp                |  304 ++
 src/common/odbc.cpp                  | 1829 +++++++
 src/common/postscrp.cpp              | 2577 ++++++++++
 src/common/prntbase.cpp              |  784 +++
 src/common/string.cpp                | 1210 +++++
 src/common/textfile.cpp              |  233 +
 src/common/time.cpp                  |  383 ++
 src/common/timercmn.cpp              |  207 +
 src/common/utilscmn.cpp              |  742 +++
 src/common/validate.cpp              |   44 +
 src/common/valtext.cpp               |  293 ++
 src/gdk_imlib/AUDIT                  |   26 +
 src/gdk_imlib/AUTHORS                |    1 +
 src/gdk_imlib/COPYING.LIB            |  481 ++
 src/gdk_imlib/ChangeLog              |   74 +
 src/gdk_imlib/README                 |   29 +
 src/gdk_imlib/cache.c                |  496 ++
 src/gdk_imlib/colors.c               |  113 +
 src/gdk_imlib/config.h               |    2 +
 src/gdk_imlib/gdk_imlib.h            |   76 +
 src/gdk_imlib/gdk_imlib_private.h    |  226 +
 src/gdk_imlib/gdk_imlib_types.h      |  101 +
 src/gdk_imlib/globals.c              |    6 +
 src/gdk_imlib/load.c                 | 1494 ++++++
 src/gdk_imlib/misc.c                 | 1165 +++++
 src/gdk_imlib/rend.c                 | 6170 ++++++++++++++++++++++++
 src/gdk_imlib/save.c                 |  538 +++
 src/gdk_imlib/utils.c                | 1518 ++++++
 src/generic/choicdgg.cpp             |  303 ++
 src/generic/colrdlgg.cpp             |  487 ++
 src/generic/fontdlgg.cpp             |  425 ++
 src/generic/gridg.cpp                | 2365 +++++++++
 src/generic/helpxlp.cpp              |  257 +
 src/generic/imaglist.cpp             |  112 +
 src/generic/listctrl.cpp             | 2454 ++++++++++
 src/generic/msgdlgg.cpp              |  201 +
 src/generic/panelg.cpp               |   82 +
 src/generic/printps.cpp              |  264 ++
 src/generic/prntdlgg.cpp             |  610 +++
 src/generic/scrolwin.cpp             |  442 ++
 src/generic/splitter.cpp             |  729 +++
 src/generic/statusbr.cpp             |  332 ++
 src/generic/tabg.cpp                 | 1164 +++++
 src/generic/textdlgg.cpp             |  143 +
 src/generic/treectrl.cpp             |  932 ++++
 src/gtk/app.cpp                      |  279 ++
 src/gtk/bdiag.xbm                    |    6 +
 src/gtk/bitmap.cpp                   |  293 ++
 src/gtk/brush.cpp                    |  132 +
 src/gtk/button.cpp                   |   89 +
 src/gtk/cdiag.xbm                    |    6 +
 src/gtk/checkbox.cpp                 |   84 +
 src/gtk/choice.cpp                   |  198 +
 src/gtk/colour.cpp                   |  225 +
 src/gtk/control.cpp                  |   51 +
 src/gtk/cross.xbm                    |    6 +
 src/gtk/cursor.cpp                   |  173 +
 src/gtk/data.cpp                     |  705 +++
 src/gtk/dc.cpp                       |  370 ++
 src/gtk/dcclient.cpp                 |  773 +++
 src/gtk/dcmemory.cpp                 |   68 +
 src/gtk/dcscreen.cpp                 |  121 +
 src/gtk/dialog.cpp                   |  212 +
 src/gtk/dnd.cpp                      |  207 +
 src/gtk/fdiag.xbm                    |    6 +
 src/gtk/filedlg.cpp                  |  146 +
 src/gtk/font.cpp                     |  822 ++++
 src/gtk/frame.cpp                    |  353 ++
 src/gtk/gdiobj.cpp                   |   21 +
 src/gtk/horiz.xbm                    |    6 +
 src/gtk/icon.cpp                     |   22 +
 src/gtk/listbox.cpp                  |  266 ++
 src/gtk/mdi.cpp                      |  198 +
 src/gtk/menu.cpp                     |  293 ++
 src/gtk/palette.cpp                  |  106 +
 src/gtk/pen.cpp                      |  204 +
 src/gtk/radiobox.cpp                 |  229 +
 src/gtk/radiobut.cpp                 |   17 +
 src/gtk/region.cpp                   |  253 +
 src/gtk/scrolbar.cpp                 |  216 +
 src/gtk/settings.cpp                 |  183 +
 src/gtk/setup/general/createall      |   98 +
 src/gtk/setup/general/jointar        |   67 +
 src/gtk/setup/general/makeapp        |   73 +
 src/gtk/setup/general/makedirs       |   19 +
 src/gtk/setup/general/makedoc        |  102 +
 src/gtk/setup/general/mygrep         |    3 +
 src/gtk/setup/general/needed         |   10 +
 src/gtk/setup/linux/maketmpl         |  123 +
 src/gtk/setup/linux/substit          |   70 +
 src/gtk/setup/maketmpl.in            |  123 +
 src/gtk/setup/rules/bin              |   13 +
 src/gtk/setup/rules/bin2             |   14 +
 src/gtk/setup/rules/doc              |   90 +
 src/gtk/setup/rules/gbin             |   14 +
 src/gtk/setup/rules/gbin2            |   14 +
 src/gtk/setup/rules/generic/bin1     |    8 +
 src/gtk/setup/rules/generic/bin1gen  |   16 +
 src/gtk/setup/rules/generic/bin2     |    9 +
 src/gtk/setup/rules/generic/bin2gen  |   16 +
 src/gtk/setup/rules/generic/depend   |   18 +
 src/gtk/setup/rules/generic/globals  |   15 +
 src/gtk/setup/rules/generic/lib      |   17 +
 src/gtk/setup/rules/generic/needed   |   24 +
 src/gtk/setup/rules/generic/obj      |   30 +
 src/gtk/setup/rules/generic/slib     |   21 +
 src/gtk/setup/rules/generic/sobj     |   42 +
 src/gtk/setup/rules/glib             |   15 +
 src/gtk/setup/rules/glibbin          |   17 +
 src/gtk/setup/rules/glibgbin         |   18 +
 src/gtk/setup/rules/gslib            |   15 +
 src/gtk/setup/rules/lib              |   14 +
 src/gtk/setup/rules/libbin           |   17 +
 src/gtk/setup/rules/libgbin          |   17 +
 src/gtk/setup/setup.hin              |  533 +++
 src/gtk/setup/shared/sharedAIX       |   26 +
 src/gtk/setup/shared/sharedBsd       |   33 +
 src/gtk/setup/shared/sharedDgux      |   29 +
 src/gtk/setup/shared/sharedHpux      |   29 +
 src/gtk/setup/shared/sharedIrix      |   45 +
 src/gtk/setup/shared/sharedLinux     |   34 +
 src/gtk/setup/shared/sharedOSF       |   33 +
 src/gtk/setup/shared/sharedSolaris2  |   33 +
 src/gtk/setup/shared/sharedSunos4    |   33 +
 src/gtk/setup/shared/sharedSysV      |   29 +
 src/gtk/setup/substit.in             |   70 +
 src/gtk/slider.cpp                   |  247 +
 src/gtk/statbox.cpp                  |   49 +
 src/gtk/stattext.cpp                 |   69 +
 src/gtk/tbargtk.cpp                  |  207 +
 src/gtk/textctrl.cpp                 |  391 ++
 src/gtk/timer.cpp                    |   71 +
 src/gtk/utilsgtk.cpp                 |  406 ++
 src/gtk/utilsres.cpp                 |  332 ++
 src/gtk/verti.xbm                    |    6 +
 src/gtk/win_gtk.c                    |  512 ++
 src/gtk/window.cpp                   | 2386 ++++++++++
 src/gtk1/app.cpp                     |  279 ++
 src/gtk1/bdiag.xbm                   |    6 +
 src/gtk1/bitmap.cpp                  |  293 ++
 src/gtk1/brush.cpp                   |  132 +
 src/gtk1/button.cpp                  |   89 +
 src/gtk1/cdiag.xbm                   |    6 +
 src/gtk1/checkbox.cpp                |   84 +
 src/gtk1/choice.cpp                  |  198 +
 src/gtk1/colour.cpp                  |  225 +
 src/gtk1/control.cpp                 |   51 +
 src/gtk1/cross.xbm                   |    6 +
 src/gtk1/cursor.cpp                  |  173 +
 src/gtk1/data.cpp                    |  705 +++
 src/gtk1/dc.cpp                      |  370 ++
 src/gtk1/dcclient.cpp                |  773 +++
 src/gtk1/dcmemory.cpp                |   68 +
 src/gtk1/dcscreen.cpp                |  121 +
 src/gtk1/dialog.cpp                  |  212 +
 src/gtk1/dnd.cpp                     |  207 +
 src/gtk1/fdiag.xbm                   |    6 +
 src/gtk1/filedlg.cpp                 |  146 +
 src/gtk1/font.cpp                    |  822 ++++
 src/gtk1/frame.cpp                   |  353 ++
 src/gtk1/gdiobj.cpp                  |   21 +
 src/gtk1/horiz.xbm                   |    6 +
 src/gtk1/icon.cpp                    |   22 +
 src/gtk1/listbox.cpp                 |  266 ++
 src/gtk1/mdi.cpp                     |  198 +
 src/gtk1/menu.cpp                    |  293 ++
 src/gtk1/palette.cpp                 |  106 +
 src/gtk1/pen.cpp                     |  204 +
 src/gtk1/radiobox.cpp                |  229 +
 src/gtk1/radiobut.cpp                |   17 +
 src/gtk1/region.cpp                  |  253 +
 src/gtk1/scrolbar.cpp                |  216 +
 src/gtk1/settings.cpp                |  183 +
 src/gtk1/setup/general/createall     |   98 +
 src/gtk1/setup/general/jointar       |   67 +
 src/gtk1/setup/general/makeapp       |   73 +
 src/gtk1/setup/general/makedirs      |   19 +
 src/gtk1/setup/general/makedoc       |  102 +
 src/gtk1/setup/general/mygrep        |    3 +
 src/gtk1/setup/general/needed        |   10 +
 src/gtk1/setup/linux/maketmpl        |  123 +
 src/gtk1/setup/linux/substit         |   70 +
 src/gtk1/setup/maketmpl.in           |  123 +
 src/gtk1/setup/rules/bin             |   13 +
 src/gtk1/setup/rules/bin2            |   14 +
 src/gtk1/setup/rules/doc             |   90 +
 src/gtk1/setup/rules/gbin            |   14 +
 src/gtk1/setup/rules/gbin2           |   14 +
 src/gtk1/setup/rules/generic/bin1    |    8 +
 src/gtk1/setup/rules/generic/bin1gen |   16 +
 src/gtk1/setup/rules/generic/bin2    |    9 +
 src/gtk1/setup/rules/generic/bin2gen |   16 +
 src/gtk1/setup/rules/generic/depend  |   18 +
 src/gtk1/setup/rules/generic/globals |   15 +
 src/gtk1/setup/rules/generic/lib     |   17 +
 src/gtk1/setup/rules/generic/needed  |   24 +
 src/gtk1/setup/rules/generic/obj     |   30 +
 src/gtk1/setup/rules/generic/slib    |   21 +
 src/gtk1/setup/rules/generic/sobj    |   42 +
 src/gtk1/setup/rules/glib            |   15 +
 src/gtk1/setup/rules/glibbin         |   17 +
 src/gtk1/setup/rules/glibgbin        |   18 +
 src/gtk1/setup/rules/gslib           |   15 +
 src/gtk1/setup/rules/lib             |   14 +
 src/gtk1/setup/rules/libbin          |   17 +
 src/gtk1/setup/rules/libgbin         |   17 +
 src/gtk1/setup/setup.hin             |  533 +++
 src/gtk1/setup/shared/sharedAIX      |   26 +
 src/gtk1/setup/shared/sharedBsd      |   33 +
 src/gtk1/setup/shared/sharedDgux     |   29 +
 src/gtk1/setup/shared/sharedHpux     |   29 +
 src/gtk1/setup/shared/sharedIrix     |   45 +
 src/gtk1/setup/shared/sharedLinux    |   34 +
 src/gtk1/setup/shared/sharedOSF      |   33 +
 src/gtk1/setup/shared/sharedSolaris2 |   33 +
 src/gtk1/setup/shared/sharedSunos4   |   33 +
 src/gtk1/setup/shared/sharedSysV     |   29 +
 src/gtk1/setup/substit.in            |   70 +
 src/gtk1/slider.cpp                  |  247 +
 src/gtk1/statbox.cpp                 |   49 +
 src/gtk1/stattext.cpp                |   69 +
 src/gtk1/tbargtk.cpp                 |  207 +
 src/gtk1/textctrl.cpp                |  391 ++
 src/gtk1/timer.cpp                   |   71 +
 src/gtk1/utilsgtk.cpp                |  406 ++
 src/gtk1/utilsres.cpp                |  332 ++
 src/gtk1/verti.xbm                   |    6 +
 src/gtk1/win_gtk.c                   |  512 ++
 src/gtk1/window.cpp                  | 2386 ++++++++++
 src/mkdirs                           |   32 +
 src/png/CHANGES                      |  288 ++
 src/png/INSTALL                      |   87 +
 src/png/README                       |  194 +
 src/png/TODO                         |   22 +
 src/png/ansi2knr.1                   |   36 +
 src/png/ansi2knr.c                   |  693 +++
 src/png/example.c                    |  688 +++
 src/png/libpng.3                     | 2409 ++++++++++
 src/png/libpngpf.3                   |  342 ++
 src/png/makefile.bcc                 |  107 +
 src/png/makefile.dos                 |   76 +
 src/png/makefile.nt                  |   64 +
 src/png/png.5                        |   44 +
 src/png/png.c                        |  304 ++
 src/png/png.h                        | 2063 ++++++++
 src/png/pngconf.h                    |  565 +++
 src/png/pngerror.c                   |  174 +
 src/png/pngget.c                     |  644 +++
 src/png/pngmem.c                     |  360 ++
 src/png/pngpread.c                   | 1143 +++++
 src/png/pngread.c                    |  787 +++
 src/png/pngrio.c                     |  145 +
 src/png/pngrtran.c                   | 3409 +++++++++++++
 src/png/pngrutil.c                   | 2245 +++++++++
 src/png/pngset.c                     |  380 ++
 src/png/pngtest.c                    | 1036 ++++
 src/png/pngtrans.c                   |  577 +++
 src/png/pngwio.c                     |  207 +
 src/png/pngwrite.c                   |  970 ++++
 src/png/pngwtran.c                   |  495 ++
 src/png/pngwutil.c                   | 1934 ++++++++
 src/png/scripts/SCOPTIONS.ppc        |    7 +
 src/png/scripts/build.bat            |    2 +
 src/png/scripts/descrip.mms          |   52 +
 src/png/scripts/makefile.aco         |  221 +
 src/png/scripts/makefile.ama         |   42 +
 src/png/scripts/makefile.atr         |   31 +
 src/png/scripts/makefile.bor         |  168 +
 src/png/scripts/makefile.dec         |   68 +
 src/png/scripts/makefile.dj2         |   52 +
 src/png/scripts/makefile.knr         |   73 +
 src/png/scripts/makefile.lnx         |   99 +
 src/png/scripts/makefile.mip         |   62 +
 src/png/scripts/makefile.msc         |   86 +
 src/png/scripts/makefile.os2         |   69 +
 src/png/scripts/makefile.s2x         |  104 +
 src/png/scripts/makefile.sgi         |   69 +
 src/png/scripts/makefile.std         |   68 +
 src/png/scripts/makefile.sun         |   72 +
 src/png/scripts/makefile.tc3         |   82 +
 src/png/scripts/makefile.wat         |   88 +
 src/png/scripts/makevms.com          |  125 +
 src/png/scripts/pngos2.def           |  286 ++
 src/png/scripts/smakefile.ppc        |   29 +
 src/zlib/ChangeLog                   |  423 ++
 src/zlib/INDEX                       |   82 +
 src/zlib/Make_vms.com                |  115 +
 src/zlib/Makefile.in2                |  160 +
 src/zlib/Makefile.riscos             |   46 +
 src/zlib/README                      |  143 +
 src/zlib/adler32.c                   |   48 +
 src/zlib/algorithm.txt               |  213 +
 src/zlib/compress.c                  |   68 +
 src/zlib/configure                   |  163 +
 src/zlib/crc32.c                     |  162 +
 src/zlib/deflate.c                   | 1348 ++++++
 src/zlib/deflate.h                   |  318 ++
 src/zlib/descrip.mms                 |   48 +
 src/zlib/example.c                   |  550 +++
 src/zlib/gzio.c                      |  869 ++++
 src/zlib/infblock.c                  |  405 ++
 src/zlib/infblock.h                  |   39 +
 src/zlib/infcodes.c                  |  250 +
 src/zlib/infcodes.h                  |   27 +
 src/zlib/inffast.c                   |  170 +
 src/zlib/inffast.h                   |   17 +
 src/zlib/inffixed.h                  |  125 +
 src/zlib/inflate.c                   |  366 ++
 src/zlib/inftrees.c                  |  455 ++
 src/zlib/inftrees.h                  |   58 +
 src/zlib/infutil.c                   |   87 +
 src/zlib/infutil.h                   |   98 +
 src/zlib/makefile.b32                |  107 +
 src/zlib/makefile.bcc                |   88 +
 src/zlib/makefile.nt                 |   88 +
 src/zlib/makefile.unx                |  133 +
 src/zlib/makefile.wat                |  105 +
 src/zlib/maketree.c                  |  119 +
 src/zlib/minigzip.c                  |  317 ++
 src/zlib/trees.c                     | 1216 +++++
 src/zlib/trees.h                     |  128 +
 src/zlib/uncompr.c                   |   58 +
 src/zlib/zconf.h                     |  252 +
 src/zlib/zlib.3                      |  107 +
 src/zlib/zlib.h                      |  888 ++++
 src/zlib/zutil.c                     |  225 +
 src/zlib/zutil.h                     |  221 +
 template.mak                         |   35 +
 user/Makefile                        |    1 +
 user/wxConvert/Makefile              |    1 +
 user/wxConvert/Makefile.in           |   26 +
 user/wxConvert/wxConvert.cpp         |  175 +
 user/wxConvert/wxConvert.h           |   71 +
 user/wxFile/Makefile                 |    1 +
 user/wxFile/Makefile.in              |   26 +
 user/wxFile/commanderview.xpm        |   31 +
 user/wxFile/delete.xpm               |   31 +
 user/wxFile/dirctrl.cpp              |  220 +
 user/wxFile/dirctrl.h                |   74 +
 user/wxFile/exit.xpm                 |   29 +
 user/wxFile/filectrl.cpp             |  541 +++
 user/wxFile/filectrl.h               |  112 +
 user/wxFile/fileopen.xpm             |   30 +
 user/wxFile/find.xpm                 |   99 +
 user/wxFile/folder.xpm               |   48 +
 user/wxFile/help.xpm                 |   29 +
 user/wxFile/home.xpm                 |   28 +
 user/wxFile/iconview.xpm             |   31 +
 user/wxFile/list.xpm                 |   45 +
 user/wxFile/listview.xpm             |   30 +
 user/wxFile/prev.xpm                 |   29 +
 user/wxFile/reportview.xpm           |   31 +
 user/wxFile/save.xpm                 |   30 +
 user/wxFile/search.xpm               |   32 +
 user/wxFile/singleview.xpm           |   30 +
 user/wxFile/trash.xpm                |   44 +
 user/wxFile/treeview.xpm             |   31 +
 user/wxFile/txt.xpm                  |   53 +
 user/wxFile/wxFile.cpp               |  393 ++
 user/wxFile/wxFile.h                 |   87 +
 user/wxTest/Makefile                 |    1 +
 user/wxTest/Makefile.in              |   26 +
 user/wxTest/folder.xpm               |   48 +
 user/wxTest/horse.png                |  Bin 0 -> 68850 bytes
 user/wxTest/list.xpm                 |   45 +
 user/wxTest/wxTest.cpp               |  594 +++
 user/wxTest/wxTest.h                 |  164 +
 utils/Makefile                       |    1 +
 779 files changed, 172138 insertions(+)
 create mode 100644 INSTALL
 create mode 100644 Makefile
 create mode 100755 config.guess
 create mode 100755 config.sub
 create mode 100755 configure
 create mode 100644 configure.in
 create mode 100644 docs/changes.txt
 create mode 100644 docs/gtk/welcome.html
 create mode 100644 docs/licence.txt
 create mode 100644 docs/readme.txt
 create mode 100644 docs/symbols.txt
 create mode 100644 im_palette.pal
 create mode 100644 imrc
 create mode 100644 include/wx/app.h
 create mode 100644 include/wx/bitmap.h
 create mode 100644 include/wx/bmpbuttn.h
 create mode 100644 include/wx/brush.h
 create mode 100644 include/wx/button.h
 create mode 100644 include/wx/checkbox.h
 create mode 100644 include/wx/choicdlg.h
 create mode 100644 include/wx/choice.h
 create mode 100644 include/wx/clipbrd.h
 create mode 100644 include/wx/cmndata.h
 create mode 100644 include/wx/colordlg.h
 create mode 100644 include/wx/combobox.h
 create mode 100644 include/wx/config.h
 create mode 100644 include/wx/control.h
 create mode 100644 include/wx/cursor.h
 create mode 100644 include/wx/date.h
 create mode 100644 include/wx/dc.h
 create mode 100644 include/wx/dcclient.h
 create mode 100644 include/wx/dcmemory.h
 create mode 100644 include/wx/dcprint.h
 create mode 100644 include/wx/dcscreen.h
 create mode 100644 include/wx/dde.h
 create mode 100644 include/wx/debug.h
 create mode 100644 include/wx/defs.h
 create mode 100644 include/wx/dialog.h
 create mode 100644 include/wx/dirdlg.h
 create mode 100644 include/wx/dnd.h
 create mode 100644 include/wx/docview.h
 create mode 100644 include/wx/dynarray.h
 create mode 100644 include/wx/event.h
 create mode 100644 include/wx/file.h
 create mode 100644 include/wx/filedlg.h
 create mode 100644 include/wx/filefn.h
 create mode 100644 include/wx/font.h
 create mode 100644 include/wx/fontdlg.h
 create mode 100644 include/wx/frame.h
 create mode 100644 include/wx/gauge.h
 create mode 100644 include/wx/gdicmn.h
 create mode 100644 include/wx/gdiobj.h
 create mode 100644 include/wx/generic/choicdgg.h
 create mode 100644 include/wx/generic/colrdlgg.h
 create mode 100644 include/wx/generic/fontdlgg.h
 create mode 100644 include/wx/generic/gridg.h
 create mode 100644 include/wx/generic/helpxlp.h
 create mode 100644 include/wx/generic/imaglist.h
 create mode 100644 include/wx/generic/listctrl.h
 create mode 100644 include/wx/generic/msgdlgg.h
 create mode 100644 include/wx/generic/panelg.h
 create mode 100644 include/wx/generic/printps.h
 create mode 100644 include/wx/generic/prntdlgg.h
 create mode 100644 include/wx/generic/scrolwin.h
 create mode 100644 include/wx/generic/splitter.h
 create mode 100644 include/wx/generic/statusbr.h
 create mode 100644 include/wx/generic/tabg.h
 create mode 100644 include/wx/generic/textdlgg.h
 create mode 100644 include/wx/generic/treectrl.h
 create mode 100644 include/wx/grid.h
 create mode 100644 include/wx/gtk/app.h
 create mode 100644 include/wx/gtk/bitmap.h
 create mode 100644 include/wx/gtk/bmpbuttn.h
 create mode 100644 include/wx/gtk/brush.h
 create mode 100644 include/wx/gtk/button.h
 create mode 100644 include/wx/gtk/checkbox.h
 create mode 100644 include/wx/gtk/choice.h
 create mode 100644 include/wx/gtk/colour.h
 create mode 100644 include/wx/gtk/combobox.h
 create mode 100644 include/wx/gtk/control.h
 create mode 100644 include/wx/gtk/cursor.h
 create mode 100644 include/wx/gtk/dc.h
 create mode 100644 include/wx/gtk/dcclient.h
 create mode 100644 include/wx/gtk/dcmemory.h
 create mode 100644 include/wx/gtk/dcscreen.h
 create mode 100644 include/wx/gtk/dialog.h
 create mode 100644 include/wx/gtk/dirdlg.h
 create mode 100644 include/wx/gtk/dnd.h
 create mode 100644 include/wx/gtk/filedlg.h
 create mode 100644 include/wx/gtk/font.h
 create mode 100644 include/wx/gtk/frame.h
 create mode 100644 include/wx/gtk/gauge.h
 create mode 100644 include/wx/gtk/gdiobj.h
 create mode 100644 include/wx/gtk/icon.h
 create mode 100644 include/wx/gtk/listbox.h
 create mode 100644 include/wx/gtk/mdi.h
 create mode 100644 include/wx/gtk/menu.h
 create mode 100644 include/wx/gtk/palette.h
 create mode 100644 include/wx/gtk/pen.h
 create mode 100644 include/wx/gtk/radiobox.h
 create mode 100644 include/wx/gtk/radiobut.h
 create mode 100644 include/wx/gtk/region.h
 create mode 100644 include/wx/gtk/scrolbar.h
 create mode 100644 include/wx/gtk/settings.h
 create mode 100644 include/wx/gtk/setup.h
 create mode 100644 include/wx/gtk/slider.h
 create mode 100644 include/wx/gtk/statbmp.h
 create mode 100644 include/wx/gtk/statbox.h
 create mode 100644 include/wx/gtk/stattext.h
 create mode 100644 include/wx/gtk/tbargtk.h
 create mode 100644 include/wx/gtk/textctrl.h
 create mode 100644 include/wx/gtk/timer.h
 create mode 100644 include/wx/gtk/win_gtk.h
 create mode 100644 include/wx/gtk/window.h
 create mode 100644 include/wx/gtk1/app.h
 create mode 100644 include/wx/gtk1/bitmap.h
 create mode 100644 include/wx/gtk1/bmpbuttn.h
 create mode 100644 include/wx/gtk1/brush.h
 create mode 100644 include/wx/gtk1/button.h
 create mode 100644 include/wx/gtk1/checkbox.h
 create mode 100644 include/wx/gtk1/choice.h
 create mode 100644 include/wx/gtk1/colour.h
 create mode 100644 include/wx/gtk1/combobox.h
 create mode 100644 include/wx/gtk1/control.h
 create mode 100644 include/wx/gtk1/cursor.h
 create mode 100644 include/wx/gtk1/dc.h
 create mode 100644 include/wx/gtk1/dcclient.h
 create mode 100644 include/wx/gtk1/dcmemory.h
 create mode 100644 include/wx/gtk1/dcscreen.h
 create mode 100644 include/wx/gtk1/dialog.h
 create mode 100644 include/wx/gtk1/dirdlg.h
 create mode 100644 include/wx/gtk1/dnd.h
 create mode 100644 include/wx/gtk1/filedlg.h
 create mode 100644 include/wx/gtk1/font.h
 create mode 100644 include/wx/gtk1/frame.h
 create mode 100644 include/wx/gtk1/gauge.h
 create mode 100644 include/wx/gtk1/gdiobj.h
 create mode 100644 include/wx/gtk1/icon.h
 create mode 100644 include/wx/gtk1/listbox.h
 create mode 100644 include/wx/gtk1/mdi.h
 create mode 100644 include/wx/gtk1/menu.h
 create mode 100644 include/wx/gtk1/palette.h
 create mode 100644 include/wx/gtk1/pen.h
 create mode 100644 include/wx/gtk1/radiobox.h
 create mode 100644 include/wx/gtk1/radiobut.h
 create mode 100644 include/wx/gtk1/region.h
 create mode 100644 include/wx/gtk1/scrolbar.h
 create mode 100644 include/wx/gtk1/settings.h
 create mode 100644 include/wx/gtk1/setup.h
 create mode 100644 include/wx/gtk1/slider.h
 create mode 100644 include/wx/gtk1/statbmp.h
 create mode 100644 include/wx/gtk1/statbox.h
 create mode 100644 include/wx/gtk1/stattext.h
 create mode 100644 include/wx/gtk1/tbargtk.h
 create mode 100644 include/wx/gtk1/textctrl.h
 create mode 100644 include/wx/gtk1/timer.h
 create mode 100644 include/wx/gtk1/win_gtk.h
 create mode 100644 include/wx/gtk1/window.h
 create mode 100644 include/wx/hash.h
 create mode 100644 include/wx/help.h
 create mode 100644 include/wx/helpbase.h
 create mode 100644 include/wx/helphtml.h
 create mode 100644 include/wx/helpwin.h
 create mode 100644 include/wx/helpxlp.h
 create mode 100644 include/wx/icon.h
 create mode 100644 include/wx/imaglist.h
 create mode 100644 include/wx/intl.h
 create mode 100644 include/wx/ipcbase.h
 create mode 100644 include/wx/layout.h
 create mode 100644 include/wx/list.h
 create mode 100644 include/wx/listbox.h
 create mode 100644 include/wx/listctrl.h
 create mode 100644 include/wx/log.h
 create mode 100644 include/wx/matrix.h
 create mode 100644 include/wx/mdi.h
 create mode 100644 include/wx/memory.h
 create mode 100644 include/wx/menu.h
 create mode 100644 include/wx/menuitem.h
 create mode 100644 include/wx/metafile.h
 create mode 100644 include/wx/minifram.h
 create mode 100644 include/wx/module.h
 create mode 100644 include/wx/msgdlg.h
 create mode 100644 include/wx/object.h
 create mode 100644 include/wx/odbc.h
 create mode 100644 include/wx/palette.h
 create mode 100644 include/wx/panel.h
 create mode 100644 include/wx/pen.h
 create mode 100644 include/wx/pnghand.h
 create mode 100644 include/wx/postscrp.h
 create mode 100644 include/wx/print.h
 create mode 100644 include/wx/printdlg.h
 create mode 100644 include/wx/prntbase.h
 create mode 100644 include/wx/radiobox.h
 create mode 100644 include/wx/radiobut.h
 create mode 100644 include/wx/region.h
 create mode 100644 include/wx/scrolbar.h
 create mode 100644 include/wx/scrolwin.h
 create mode 100644 include/wx/settings.h
 create mode 100644 include/wx/setup.h
 create mode 100644 include/wx/slider.h
 create mode 100644 include/wx/spinbutt.h
 create mode 100644 include/wx/splitter.h
 create mode 100644 include/wx/statbmp.h
 create mode 100644 include/wx/statbox.h
 create mode 100644 include/wx/stattext.h
 create mode 100644 include/wx/statusbr.h
 create mode 100644 include/wx/string.h
 create mode 100644 include/wx/tab.h
 create mode 100644 include/wx/tabctrl.h
 create mode 100644 include/wx/textctrl.h
 create mode 100644 include/wx/textdlg.h
 create mode 100644 include/wx/textfile.h
 create mode 100644 include/wx/time.h
 create mode 100644 include/wx/timer.h
 create mode 100644 include/wx/toolbar.h
 create mode 100644 include/wx/treectrl.h
 create mode 100644 include/wx/types.h
 create mode 100644 include/wx/utils.h
 create mode 100644 include/wx/validate.h
 create mode 100644 include/wx/valtext.h
 create mode 100644 include/wx/version.h
 create mode 100644 include/wx/window.h
 create mode 100644 include/wx/wx.h
 create mode 100644 include/wx/wxprec.h
 create mode 100755 install-sh
 create mode 100644 lib/dummy
 create mode 100644 misc/afm/Cour.afm
 create mode 100644 misc/afm/CourBo.afm
 create mode 100644 misc/afm/CourBoO.afm
 create mode 100644 misc/afm/CourO.afm
 create mode 100644 misc/afm/Helv.afm
 create mode 100644 misc/afm/HelvBo.afm
 create mode 100644 misc/afm/HelvBoO.afm
 create mode 100644 misc/afm/HelvO.afm
 create mode 100644 misc/afm/TimesBo.afm
 create mode 100644 misc/afm/TimesBoO.afm
 create mode 100644 misc/afm/TimesO.afm
 create mode 100644 misc/afm/TimesRo.afm
 create mode 100644 misc/gs_afm/Cour.afm
 create mode 100644 misc/gs_afm/CourBo.afm
 create mode 100644 misc/gs_afm/CourBoO.afm
 create mode 100644 misc/gs_afm/CourO.afm
 create mode 100644 misc/gs_afm/Helv.afm
 create mode 100644 misc/gs_afm/HelvBo.afm
 create mode 100644 misc/gs_afm/HelvBoO.afm
 create mode 100644 misc/gs_afm/HelvO.afm
 create mode 100644 misc/gs_afm/TimesBo.afm
 create mode 100644 misc/gs_afm/TimesBoO.afm
 create mode 100644 misc/gs_afm/TimesO.afm
 create mode 100644 misc/gs_afm/TimesRo.afm
 create mode 100644 samples/Makefile
 create mode 100644 samples/grid/Makefile
 create mode 100644 samples/grid/Makefile.in
 create mode 100644 samples/grid/aiai.ico
 create mode 100644 samples/grid/aiai.xbm
 create mode 100644 samples/grid/bitmap1.bmp
 create mode 100644 samples/grid/bitmap2.bmp
 create mode 100644 samples/grid/test.cpp
 create mode 100644 samples/grid/test.def
 create mode 100644 samples/grid/test.rc
 create mode 100644 samples/internat/Makefile
 create mode 100644 samples/internat/Makefile.in
 create mode 100644 samples/internat/aiai.ico
 create mode 100644 samples/internat/aiai.xbm
 create mode 100644 samples/internat/internat.cpp
 create mode 100644 samples/internat/internat.def
 create mode 100644 samples/internat/internat.po
 create mode 100644 samples/internat/internat.rc
 create mode 100644 samples/internat/makefile.b32
 create mode 100644 samples/internat/makefile.bcc
 create mode 100644 samples/internat/makefile.dos
 create mode 100644 samples/internat/makefile.g95
 create mode 100644 samples/internat/makefile.nt
 create mode 100644 samples/internat/makefile.sc
 create mode 100644 samples/internat/makefile.unx
 create mode 100644 samples/internat/makefile.vms
 create mode 100644 samples/internat/makefile.wat
 create mode 100644 samples/internat/mondrian.ico
 create mode 100644 samples/internat/wxstd.po
 create mode 100644 samples/layout/Makefile
 create mode 100644 samples/layout/Makefile.in
 create mode 100644 samples/layout/aiai.ico
 create mode 100644 samples/layout/aiai.xbm
 create mode 100644 samples/layout/expt.cpp
 create mode 100644 samples/layout/fload.xbm
 create mode 100644 samples/layout/layout.cpp
 create mode 100644 samples/layout/layout.def
 create mode 100644 samples/layout/layout.h
 create mode 100644 samples/layout/layout.rc
 create mode 100644 samples/layout/makefile.b32
 create mode 100644 samples/layout/makefile.bcc
 create mode 100644 samples/layout/makefile.dos
 create mode 100644 samples/layout/makefile.g95
 create mode 100644 samples/layout/makefile.nt
 create mode 100644 samples/layout/makefile.sc
 create mode 100644 samples/layout/makefile.unx
 create mode 100644 samples/layout/makefile.vms
 create mode 100644 samples/layout/makefile.wat
 create mode 100644 samples/mdi/Makefile
 create mode 100644 samples/mdi/Makefile.in
 create mode 100644 samples/mdi/aiai.ico
 create mode 100644 samples/mdi/aiai.xbm
 create mode 100644 samples/mdi/chart.ico
 create mode 100644 samples/mdi/makefile.b32
 create mode 100644 samples/mdi/makefile.bcc
 create mode 100644 samples/mdi/makefile.dos
 create mode 100644 samples/mdi/makefile.g95
 create mode 100644 samples/mdi/makefile.nt
 create mode 100644 samples/mdi/makefile.sc
 create mode 100644 samples/mdi/makefile.unx
 create mode 100644 samples/mdi/makefile.vms
 create mode 100644 samples/mdi/makefile.wat
 create mode 100644 samples/mdi/mdi.cpp
 create mode 100644 samples/mdi/mdi.def
 create mode 100644 samples/mdi/mdi.h
 create mode 100644 samples/mdi/mdi.ico
 create mode 100644 samples/mdi/mdi.rc
 create mode 100644 samples/mdi/mondrian.ico
 create mode 100644 samples/minimal/Makefile
 create mode 100644 samples/minimal/Makefile.in
 create mode 100644 samples/minimal/aiai.ico
 create mode 100644 samples/minimal/aiai.xbm
 create mode 100644 samples/minimal/makefile.b32
 create mode 100644 samples/minimal/makefile.bcc
 create mode 100644 samples/minimal/makefile.dos
 create mode 100644 samples/minimal/makefile.g95
 create mode 100644 samples/minimal/makefile.nt
 create mode 100644 samples/minimal/makefile.sc
 create mode 100644 samples/minimal/makefile.unx
 create mode 100644 samples/minimal/makefile.vms
 create mode 100644 samples/minimal/makefile.wat
 create mode 100644 samples/minimal/minimal.cpp
 create mode 100644 samples/minimal/minimal.def
 create mode 100644 samples/minimal/minimal.rc
 create mode 100644 samples/minimal/mondrian.ico
 create mode 100644 samples/png/Makefile
 create mode 100644 samples/png/Makefile.in
 create mode 100644 samples/png/makefile.nt
 create mode 100644 samples/png/pngdemo.cpp
 create mode 100644 samples/png/pngdemo.h
 create mode 100644 samples/png/pngdemo.rc
 create mode 100644 samples/printing/Cour.afm
 create mode 100644 samples/printing/CourBo.afm
 create mode 100644 samples/printing/CourBoO.afm
 create mode 100644 samples/printing/CourO.afm
 create mode 100644 samples/printing/Helv.afm
 create mode 100644 samples/printing/HelvBo.afm
 create mode 100644 samples/printing/HelvBoO.afm
 create mode 100644 samples/printing/HelvO.afm
 create mode 100644 samples/printing/Makefile
 create mode 100644 samples/printing/Makefile.in
 create mode 100644 samples/printing/TimesBo.afm
 create mode 100644 samples/printing/TimesBoO.afm
 create mode 100644 samples/printing/TimesO.afm
 create mode 100644 samples/printing/TimesRo.afm
 create mode 100644 samples/printing/aiai.ico
 create mode 100644 samples/printing/aiai.xbm
 create mode 100644 samples/printing/fload.xbm
 create mode 100644 samples/printing/printing.cpp
 create mode 100644 samples/printing/printing.def
 create mode 100644 samples/printing/printing.h
 create mode 100644 samples/printing/printing.rc
 create mode 100644 samples/splitter/Makefile
 create mode 100644 samples/splitter/Makefile.in
 create mode 100644 samples/splitter/aiai.xbm
 create mode 100644 samples/splitter/makefile.b32
 create mode 100644 samples/splitter/makefile.g95
 create mode 100644 samples/splitter/makefile.nt
 create mode 100644 samples/splitter/mondrian.ico
 create mode 100644 samples/splitter/test.cpp
 create mode 100644 samples/splitter/test.def
 create mode 100644 samples/splitter/test.rc
 create mode 100644 samples/tab/Makefile
 create mode 100644 samples/tab/Makefile.in
 create mode 100644 samples/tab/makefile.b32
 create mode 100644 samples/tab/makefile.bcc
 create mode 100644 samples/tab/makefile.dos
 create mode 100644 samples/tab/makefile.g95
 create mode 100644 samples/tab/makefile.nt
 create mode 100644 samples/tab/makefile.sc
 create mode 100644 samples/tab/makefile.unx
 create mode 100644 samples/tab/makefile.vms
 create mode 100644 samples/tab/makefile.wat
 create mode 100644 samples/tab/mondrian.ico
 create mode 100644 samples/tab/test.cpp
 create mode 100644 samples/tab/test.def
 create mode 100644 samples/tab/test.h
 create mode 100644 samples/tab/test.rc
 create mode 100644 src/Makefile
 create mode 100644 src/Makefile.in
 create mode 100644 src/common/cmndata.cpp
 create mode 100644 src/common/config.cpp
 create mode 100644 src/common/date.cpp
 create mode 100644 src/common/docview.cpp
 create mode 100644 src/common/dynarray.cpp
 create mode 100644 src/common/event.cpp
 create mode 100644 src/common/file.cpp
 create mode 100644 src/common/fileconf.cpp
 create mode 100644 src/common/filefn.cpp
 create mode 100644 src/common/gdicmn.cpp
 create mode 100644 src/common/glob.inc
 create mode 100644 src/common/hash.cpp
 create mode 100644 src/common/helpbase.cpp
 create mode 100644 src/common/intl.cpp
 create mode 100644 src/common/ipcbase.cpp
 create mode 100644 src/common/layout.cpp
 create mode 100644 src/common/list.cpp
 create mode 100644 src/common/log.cpp
 create mode 100644 src/common/matrix.cpp
 create mode 100644 src/common/memory.cpp
 create mode 100644 src/common/module.cpp
 create mode 100644 src/common/object.cpp
 create mode 100644 src/common/odbc.cpp
 create mode 100644 src/common/postscrp.cpp
 create mode 100644 src/common/prntbase.cpp
 create mode 100644 src/common/string.cpp
 create mode 100644 src/common/textfile.cpp
 create mode 100644 src/common/time.cpp
 create mode 100644 src/common/timercmn.cpp
 create mode 100644 src/common/utilscmn.cpp
 create mode 100644 src/common/validate.cpp
 create mode 100644 src/common/valtext.cpp
 create mode 100644 src/gdk_imlib/AUDIT
 create mode 100644 src/gdk_imlib/AUTHORS
 create mode 100644 src/gdk_imlib/COPYING.LIB
 create mode 100644 src/gdk_imlib/ChangeLog
 create mode 100644 src/gdk_imlib/README
 create mode 100644 src/gdk_imlib/cache.c
 create mode 100644 src/gdk_imlib/colors.c
 create mode 100644 src/gdk_imlib/config.h
 create mode 100644 src/gdk_imlib/gdk_imlib.h
 create mode 100644 src/gdk_imlib/gdk_imlib_private.h
 create mode 100644 src/gdk_imlib/gdk_imlib_types.h
 create mode 100644 src/gdk_imlib/globals.c
 create mode 100644 src/gdk_imlib/load.c
 create mode 100644 src/gdk_imlib/misc.c
 create mode 100644 src/gdk_imlib/rend.c
 create mode 100644 src/gdk_imlib/save.c
 create mode 100644 src/gdk_imlib/utils.c
 create mode 100644 src/generic/choicdgg.cpp
 create mode 100644 src/generic/colrdlgg.cpp
 create mode 100644 src/generic/fontdlgg.cpp
 create mode 100644 src/generic/gridg.cpp
 create mode 100644 src/generic/helpxlp.cpp
 create mode 100644 src/generic/imaglist.cpp
 create mode 100644 src/generic/listctrl.cpp
 create mode 100644 src/generic/msgdlgg.cpp
 create mode 100644 src/generic/panelg.cpp
 create mode 100644 src/generic/printps.cpp
 create mode 100644 src/generic/prntdlgg.cpp
 create mode 100644 src/generic/scrolwin.cpp
 create mode 100644 src/generic/splitter.cpp
 create mode 100644 src/generic/statusbr.cpp
 create mode 100644 src/generic/tabg.cpp
 create mode 100644 src/generic/textdlgg.cpp
 create mode 100644 src/generic/treectrl.cpp
 create mode 100644 src/gtk/app.cpp
 create mode 100644 src/gtk/bdiag.xbm
 create mode 100644 src/gtk/bitmap.cpp
 create mode 100644 src/gtk/brush.cpp
 create mode 100644 src/gtk/button.cpp
 create mode 100644 src/gtk/cdiag.xbm
 create mode 100644 src/gtk/checkbox.cpp
 create mode 100644 src/gtk/choice.cpp
 create mode 100644 src/gtk/colour.cpp
 create mode 100644 src/gtk/control.cpp
 create mode 100644 src/gtk/cross.xbm
 create mode 100644 src/gtk/cursor.cpp
 create mode 100644 src/gtk/data.cpp
 create mode 100644 src/gtk/dc.cpp
 create mode 100644 src/gtk/dcclient.cpp
 create mode 100644 src/gtk/dcmemory.cpp
 create mode 100644 src/gtk/dcscreen.cpp
 create mode 100644 src/gtk/dialog.cpp
 create mode 100644 src/gtk/dnd.cpp
 create mode 100644 src/gtk/fdiag.xbm
 create mode 100644 src/gtk/filedlg.cpp
 create mode 100644 src/gtk/font.cpp
 create mode 100644 src/gtk/frame.cpp
 create mode 100644 src/gtk/gdiobj.cpp
 create mode 100644 src/gtk/horiz.xbm
 create mode 100644 src/gtk/icon.cpp
 create mode 100644 src/gtk/listbox.cpp
 create mode 100644 src/gtk/mdi.cpp
 create mode 100644 src/gtk/menu.cpp
 create mode 100644 src/gtk/palette.cpp
 create mode 100644 src/gtk/pen.cpp
 create mode 100644 src/gtk/radiobox.cpp
 create mode 100644 src/gtk/radiobut.cpp
 create mode 100644 src/gtk/region.cpp
 create mode 100644 src/gtk/scrolbar.cpp
 create mode 100644 src/gtk/settings.cpp
 create mode 100755 src/gtk/setup/general/createall
 create mode 100755 src/gtk/setup/general/jointar
 create mode 100644 src/gtk/setup/general/makeapp
 create mode 100644 src/gtk/setup/general/makedirs
 create mode 100644 src/gtk/setup/general/makedoc
 create mode 100755 src/gtk/setup/general/mygrep
 create mode 100755 src/gtk/setup/general/needed
 create mode 100644 src/gtk/setup/linux/maketmpl
 create mode 100644 src/gtk/setup/linux/substit
 create mode 100644 src/gtk/setup/maketmpl.in
 create mode 100644 src/gtk/setup/rules/bin
 create mode 100644 src/gtk/setup/rules/bin2
 create mode 100644 src/gtk/setup/rules/doc
 create mode 100644 src/gtk/setup/rules/gbin
 create mode 100644 src/gtk/setup/rules/gbin2
 create mode 100644 src/gtk/setup/rules/generic/bin1
 create mode 100644 src/gtk/setup/rules/generic/bin1gen
 create mode 100644 src/gtk/setup/rules/generic/bin2
 create mode 100644 src/gtk/setup/rules/generic/bin2gen
 create mode 100644 src/gtk/setup/rules/generic/depend
 create mode 100644 src/gtk/setup/rules/generic/globals
 create mode 100644 src/gtk/setup/rules/generic/lib
 create mode 100644 src/gtk/setup/rules/generic/needed
 create mode 100644 src/gtk/setup/rules/generic/obj
 create mode 100644 src/gtk/setup/rules/generic/slib
 create mode 100644 src/gtk/setup/rules/generic/sobj
 create mode 100644 src/gtk/setup/rules/glib
 create mode 100644 src/gtk/setup/rules/glibbin
 create mode 100644 src/gtk/setup/rules/glibgbin
 create mode 100644 src/gtk/setup/rules/gslib
 create mode 100644 src/gtk/setup/rules/lib
 create mode 100644 src/gtk/setup/rules/libbin
 create mode 100644 src/gtk/setup/rules/libgbin
 create mode 100644 src/gtk/setup/setup.hin
 create mode 100755 src/gtk/setup/shared/sharedAIX
 create mode 100755 src/gtk/setup/shared/sharedBsd
 create mode 100755 src/gtk/setup/shared/sharedDgux
 create mode 100755 src/gtk/setup/shared/sharedHpux
 create mode 100755 src/gtk/setup/shared/sharedIrix
 create mode 100755 src/gtk/setup/shared/sharedLinux
 create mode 100755 src/gtk/setup/shared/sharedOSF
 create mode 100755 src/gtk/setup/shared/sharedSolaris2
 create mode 100755 src/gtk/setup/shared/sharedSunos4
 create mode 100755 src/gtk/setup/shared/sharedSysV
 create mode 100644 src/gtk/setup/substit.in
 create mode 100644 src/gtk/slider.cpp
 create mode 100644 src/gtk/statbox.cpp
 create mode 100644 src/gtk/stattext.cpp
 create mode 100644 src/gtk/tbargtk.cpp
 create mode 100644 src/gtk/textctrl.cpp
 create mode 100644 src/gtk/timer.cpp
 create mode 100644 src/gtk/utilsgtk.cpp
 create mode 100644 src/gtk/utilsres.cpp
 create mode 100644 src/gtk/verti.xbm
 create mode 100644 src/gtk/win_gtk.c
 create mode 100644 src/gtk/window.cpp
 create mode 100644 src/gtk1/app.cpp
 create mode 100644 src/gtk1/bdiag.xbm
 create mode 100644 src/gtk1/bitmap.cpp
 create mode 100644 src/gtk1/brush.cpp
 create mode 100644 src/gtk1/button.cpp
 create mode 100644 src/gtk1/cdiag.xbm
 create mode 100644 src/gtk1/checkbox.cpp
 create mode 100644 src/gtk1/choice.cpp
 create mode 100644 src/gtk1/colour.cpp
 create mode 100644 src/gtk1/control.cpp
 create mode 100644 src/gtk1/cross.xbm
 create mode 100644 src/gtk1/cursor.cpp
 create mode 100644 src/gtk1/data.cpp
 create mode 100644 src/gtk1/dc.cpp
 create mode 100644 src/gtk1/dcclient.cpp
 create mode 100644 src/gtk1/dcmemory.cpp
 create mode 100644 src/gtk1/dcscreen.cpp
 create mode 100644 src/gtk1/dialog.cpp
 create mode 100644 src/gtk1/dnd.cpp
 create mode 100644 src/gtk1/fdiag.xbm
 create mode 100644 src/gtk1/filedlg.cpp
 create mode 100644 src/gtk1/font.cpp
 create mode 100644 src/gtk1/frame.cpp
 create mode 100644 src/gtk1/gdiobj.cpp
 create mode 100644 src/gtk1/horiz.xbm
 create mode 100644 src/gtk1/icon.cpp
 create mode 100644 src/gtk1/listbox.cpp
 create mode 100644 src/gtk1/mdi.cpp
 create mode 100644 src/gtk1/menu.cpp
 create mode 100644 src/gtk1/palette.cpp
 create mode 100644 src/gtk1/pen.cpp
 create mode 100644 src/gtk1/radiobox.cpp
 create mode 100644 src/gtk1/radiobut.cpp
 create mode 100644 src/gtk1/region.cpp
 create mode 100644 src/gtk1/scrolbar.cpp
 create mode 100644 src/gtk1/settings.cpp
 create mode 100755 src/gtk1/setup/general/createall
 create mode 100755 src/gtk1/setup/general/jointar
 create mode 100644 src/gtk1/setup/general/makeapp
 create mode 100644 src/gtk1/setup/general/makedirs
 create mode 100644 src/gtk1/setup/general/makedoc
 create mode 100755 src/gtk1/setup/general/mygrep
 create mode 100755 src/gtk1/setup/general/needed
 create mode 100644 src/gtk1/setup/linux/maketmpl
 create mode 100644 src/gtk1/setup/linux/substit
 create mode 100644 src/gtk1/setup/maketmpl.in
 create mode 100644 src/gtk1/setup/rules/bin
 create mode 100644 src/gtk1/setup/rules/bin2
 create mode 100644 src/gtk1/setup/rules/doc
 create mode 100644 src/gtk1/setup/rules/gbin
 create mode 100644 src/gtk1/setup/rules/gbin2
 create mode 100644 src/gtk1/setup/rules/generic/bin1
 create mode 100644 src/gtk1/setup/rules/generic/bin1gen
 create mode 100644 src/gtk1/setup/rules/generic/bin2
 create mode 100644 src/gtk1/setup/rules/generic/bin2gen
 create mode 100644 src/gtk1/setup/rules/generic/depend
 create mode 100644 src/gtk1/setup/rules/generic/globals
 create mode 100644 src/gtk1/setup/rules/generic/lib
 create mode 100644 src/gtk1/setup/rules/generic/needed
 create mode 100644 src/gtk1/setup/rules/generic/obj
 create mode 100644 src/gtk1/setup/rules/generic/slib
 create mode 100644 src/gtk1/setup/rules/generic/sobj
 create mode 100644 src/gtk1/setup/rules/glib
 create mode 100644 src/gtk1/setup/rules/glibbin
 create mode 100644 src/gtk1/setup/rules/glibgbin
 create mode 100644 src/gtk1/setup/rules/gslib
 create mode 100644 src/gtk1/setup/rules/lib
 create mode 100644 src/gtk1/setup/rules/libbin
 create mode 100644 src/gtk1/setup/rules/libgbin
 create mode 100644 src/gtk1/setup/setup.hin
 create mode 100755 src/gtk1/setup/shared/sharedAIX
 create mode 100755 src/gtk1/setup/shared/sharedBsd
 create mode 100755 src/gtk1/setup/shared/sharedDgux
 create mode 100755 src/gtk1/setup/shared/sharedHpux
 create mode 100755 src/gtk1/setup/shared/sharedIrix
 create mode 100755 src/gtk1/setup/shared/sharedLinux
 create mode 100755 src/gtk1/setup/shared/sharedOSF
 create mode 100755 src/gtk1/setup/shared/sharedSolaris2
 create mode 100755 src/gtk1/setup/shared/sharedSunos4
 create mode 100755 src/gtk1/setup/shared/sharedSysV
 create mode 100644 src/gtk1/setup/substit.in
 create mode 100644 src/gtk1/slider.cpp
 create mode 100644 src/gtk1/statbox.cpp
 create mode 100644 src/gtk1/stattext.cpp
 create mode 100644 src/gtk1/tbargtk.cpp
 create mode 100644 src/gtk1/textctrl.cpp
 create mode 100644 src/gtk1/timer.cpp
 create mode 100644 src/gtk1/utilsgtk.cpp
 create mode 100644 src/gtk1/utilsres.cpp
 create mode 100644 src/gtk1/verti.xbm
 create mode 100644 src/gtk1/win_gtk.c
 create mode 100644 src/gtk1/window.cpp
 create mode 100755 src/mkdirs
 create mode 100644 src/png/CHANGES
 create mode 100644 src/png/INSTALL
 create mode 100644 src/png/README
 create mode 100644 src/png/TODO
 create mode 100644 src/png/ansi2knr.1
 create mode 100644 src/png/ansi2knr.c
 create mode 100644 src/png/example.c
 create mode 100644 src/png/libpng.3
 create mode 100644 src/png/libpngpf.3
 create mode 100644 src/png/makefile.bcc
 create mode 100644 src/png/makefile.dos
 create mode 100644 src/png/makefile.nt
 create mode 100644 src/png/png.5
 create mode 100644 src/png/png.c
 create mode 100644 src/png/png.h
 create mode 100644 src/png/pngconf.h
 create mode 100644 src/png/pngerror.c
 create mode 100644 src/png/pngget.c
 create mode 100644 src/png/pngmem.c
 create mode 100644 src/png/pngpread.c
 create mode 100644 src/png/pngread.c
 create mode 100644 src/png/pngrio.c
 create mode 100644 src/png/pngrtran.c
 create mode 100644 src/png/pngrutil.c
 create mode 100644 src/png/pngset.c
 create mode 100644 src/png/pngtest.c
 create mode 100644 src/png/pngtrans.c
 create mode 100644 src/png/pngwio.c
 create mode 100644 src/png/pngwrite.c
 create mode 100644 src/png/pngwtran.c
 create mode 100644 src/png/pngwutil.c
 create mode 100644 src/png/scripts/SCOPTIONS.ppc
 create mode 100644 src/png/scripts/build.bat
 create mode 100644 src/png/scripts/descrip.mms
 create mode 100644 src/png/scripts/makefile.aco
 create mode 100644 src/png/scripts/makefile.ama
 create mode 100644 src/png/scripts/makefile.atr
 create mode 100644 src/png/scripts/makefile.bor
 create mode 100644 src/png/scripts/makefile.dec
 create mode 100644 src/png/scripts/makefile.dj2
 create mode 100644 src/png/scripts/makefile.knr
 create mode 100644 src/png/scripts/makefile.lnx
 create mode 100644 src/png/scripts/makefile.mip
 create mode 100644 src/png/scripts/makefile.msc
 create mode 100644 src/png/scripts/makefile.os2
 create mode 100644 src/png/scripts/makefile.s2x
 create mode 100644 src/png/scripts/makefile.sgi
 create mode 100644 src/png/scripts/makefile.std
 create mode 100644 src/png/scripts/makefile.sun
 create mode 100644 src/png/scripts/makefile.tc3
 create mode 100644 src/png/scripts/makefile.wat
 create mode 100644 src/png/scripts/makevms.com
 create mode 100644 src/png/scripts/pngos2.def
 create mode 100644 src/png/scripts/smakefile.ppc
 create mode 100644 src/zlib/ChangeLog
 create mode 100644 src/zlib/INDEX
 create mode 100644 src/zlib/Make_vms.com
 create mode 100644 src/zlib/Makefile.in2
 create mode 100644 src/zlib/Makefile.riscos
 create mode 100644 src/zlib/README
 create mode 100644 src/zlib/adler32.c
 create mode 100644 src/zlib/algorithm.txt
 create mode 100644 src/zlib/compress.c
 create mode 100644 src/zlib/configure
 create mode 100644 src/zlib/crc32.c
 create mode 100644 src/zlib/deflate.c
 create mode 100644 src/zlib/deflate.h
 create mode 100644 src/zlib/descrip.mms
 create mode 100644 src/zlib/example.c
 create mode 100644 src/zlib/gzio.c
 create mode 100644 src/zlib/infblock.c
 create mode 100644 src/zlib/infblock.h
 create mode 100644 src/zlib/infcodes.c
 create mode 100644 src/zlib/infcodes.h
 create mode 100644 src/zlib/inffast.c
 create mode 100644 src/zlib/inffast.h
 create mode 100644 src/zlib/inffixed.h
 create mode 100644 src/zlib/inflate.c
 create mode 100644 src/zlib/inftrees.c
 create mode 100644 src/zlib/inftrees.h
 create mode 100644 src/zlib/infutil.c
 create mode 100644 src/zlib/infutil.h
 create mode 100644 src/zlib/makefile.b32
 create mode 100644 src/zlib/makefile.bcc
 create mode 100644 src/zlib/makefile.nt
 create mode 100644 src/zlib/makefile.unx
 create mode 100644 src/zlib/makefile.wat
 create mode 100644 src/zlib/maketree.c
 create mode 100644 src/zlib/minigzip.c
 create mode 100644 src/zlib/trees.c
 create mode 100644 src/zlib/trees.h
 create mode 100644 src/zlib/uncompr.c
 create mode 100644 src/zlib/zconf.h
 create mode 100644 src/zlib/zlib.3
 create mode 100644 src/zlib/zlib.h
 create mode 100644 src/zlib/zutil.c
 create mode 100644 src/zlib/zutil.h
 create mode 100644 template.mak
 create mode 100644 user/Makefile
 create mode 100644 user/wxConvert/Makefile
 create mode 100644 user/wxConvert/Makefile.in
 create mode 100644 user/wxConvert/wxConvert.cpp
 create mode 100644 user/wxConvert/wxConvert.h
 create mode 100644 user/wxFile/Makefile
 create mode 100644 user/wxFile/Makefile.in
 create mode 100644 user/wxFile/commanderview.xpm
 create mode 100644 user/wxFile/delete.xpm
 create mode 100644 user/wxFile/dirctrl.cpp
 create mode 100644 user/wxFile/dirctrl.h
 create mode 100644 user/wxFile/exit.xpm
 create mode 100644 user/wxFile/filectrl.cpp
 create mode 100644 user/wxFile/filectrl.h
 create mode 100644 user/wxFile/fileopen.xpm
 create mode 100644 user/wxFile/find.xpm
 create mode 100644 user/wxFile/folder.xpm
 create mode 100644 user/wxFile/help.xpm
 create mode 100644 user/wxFile/home.xpm
 create mode 100644 user/wxFile/iconview.xpm
 create mode 100644 user/wxFile/list.xpm
 create mode 100644 user/wxFile/listview.xpm
 create mode 100644 user/wxFile/prev.xpm
 create mode 100644 user/wxFile/reportview.xpm
 create mode 100644 user/wxFile/save.xpm
 create mode 100644 user/wxFile/search.xpm
 create mode 100644 user/wxFile/singleview.xpm
 create mode 100644 user/wxFile/trash.xpm
 create mode 100644 user/wxFile/treeview.xpm
 create mode 100644 user/wxFile/txt.xpm
 create mode 100644 user/wxFile/wxFile.cpp
 create mode 100644 user/wxFile/wxFile.h
 create mode 100644 user/wxTest/Makefile
 create mode 100644 user/wxTest/Makefile.in
 create mode 100644 user/wxTest/folder.xpm
 create mode 100644 user/wxTest/horse.png
 create mode 100644 user/wxTest/list.xpm
 create mode 100644 user/wxTest/wxTest.cpp
 create mode 100644 user/wxTest/wxTest.h
 create mode 100644 utils/Makefile

diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000000..37efbd0e06
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,321 @@
+* General
+----------
+
+wxGTK uses GNU configure. If you have problems with your make use GNU
+make instead.
+
+* Create your configuration
+-----------------------------
+Usage:
+	./configure options
+
+If you want to use system's C and C++ compiler,
+set environment variables CC and CCC as
+
+	% setenv CC cc
+	% setenv CCC CC
+	% ./configure options
+
+to see all the options please use:
+
+	./configure --help
+
+The basic philosophy is that if you want to use different
+configurations, like a debug and a release version, 
+or use the same source tree on different systems,
+you have only to change the environment variable OSTYPE.
+(Sadly this variable is not set by default on some systems
+in some shells - on SGI's for example). So you will have to 
+set it there. This variable HAS to be set before starting 
+configure, so that it knows which system it tries to 
+configure for.
+
+Configure will complain if the system variable OSTYPE has 
+not been defined. And Make in some circumstances as well...
+
+* General options
+-------------------
+
+The following options handle the kind of library you want to build.
+
+	--with-shared           Create shared libraries.
+
+	--without-optimise	Do not optimise the code.
+
+	--with-profile          Add profiling info to the
+	                        object files. Currently
+				broken.
+				
+	--with-mem_tracing      Add built-in memory tracing.
+	                        Not yet.
+				
+	--with-debug		Add debug info to object
+	                        files.
+
+* Feature Options
+-------------------
+
+When using the Windows version of wxWindows, it is possible
+to edit the file /include/wx/msw/setup.h in order to enable
+or disable some features of wxWindows so that the resulting
+binaries get smaller.
+
+As I don't yet care for binary size and target mainly at
+producing a shared library, wxGTK's configure system auto-
+matically enables all features, as long as they are already
+implemented.
+
+* Additional libraries
+-----------------------
+
+[Note: Currently wxGTK will compile out-of-the-box
+ with no extra libraries required. Support for
+ OpenGl, threads, Python and hopefully ODBC
+ support will soon be added.]
+
+wxGTK requires the GTK (The Gimp Toolkit) to be installed,
+which probably makes sense.
+
+There will be a few more features of wxGTK, which will 
+require further libraries (on some platforms). These
+features will be optional. I hope to teach configure
+to check that out automatically.
+
+Thread support:
+
+  Requires pthreads under Linux without glibc.
+  
+OpenGl:
+
+  Requires OpenGl or MesaGl.
+  
+Python scripting language support:
+
+  Requires Python.
+  
+* Compiling
+-------------
+
+First you have to create all makefiles in all subdirectories:
+
+	make makefiles
+
+Dependencies are generated automatically using
+
+	make depend
+
+Now the makefiles are created you can compile everything is as simple
+as typing:
+
+	make
+
+make yourself some coffee, as it will try to compile
+ALL the files in this distribution.
+
+if you want to be more selective:
+
+	make src	will build only the base libraries
+	make utils	will build the utils
+	make samples	will build the samples
+	make other	will build the other samples
+	make user	will build the files in the directory other
+
+Depending on the configuration of some files, the libraries
+and binaries will be placed in different directories.
+The "global" binaries and libraries will be placed in:
+
+	bin/$(OSTYPE) and
+	lib/$(OSTYPE) respectively
+
+"local" binaries and libraries will be placed in:
+
+	(basedir of that application)/$(OSTYPE).
+
+This is also the place where all the object-files will go.
+
+If you want to conserve disk space by removing unnecessary
+object-files:
+
+	 make clean_obj
+
+will do the work for you.
+
+* Creating a new Project
+--------------------------
+
+I propose to put all contributed programs in the directory
+"user", with a directory of its own.
+
+This directory then should include the following files:
+
+Makefile        (You can copy this one from any application in samples
+                 probably you will not need to edit this one. There is
+                 only one case where you might be interested in changing
+                 this file, but about that see later.)
+Makefile.in	(This is the base application-Makefile template, from
+                 which the actual Makefile for each system is created.
+                 More about this later)
+
+put ALL your source code along with all the other stuff you need for
+your application in this directory (subdirectories are welcome).
+
+** Something about Makefiles
+------------------------------
+
+On general principle it should only contain ONE line, which is as follows:
+
+	include ../../src/gtk/setup/general/makeapp
+
+this will include all the necessary definitions for creating the applications
+
+the only case where you might want to add another line is the following:
+this version of configure also supports creation of source archives of the
+application for easy distribution and updates to newer version of wxxt.
+    For this purpose all files in the application-directory will be put into
+a gziped tar-file in the full notation user/<your application>/*
+if you want to include some other files that you want "more visible", like
+a README.<yourApp> or a shell script for easy 
+compilation/installation/distribution, then you have to add a variable
+
+	DISTRIBUTE_ADDITIONAL=<your files>
+
+to the Makefile.
+So it would look like this:
+
+	DISTRIBUTE_ADDITIONAL=README.TheApp
+	include ../../src/gtk/setup/general/makeapp
+
+As we have already talked about distribution the command to create a 
+distribution is:
+
+	make distrib
+
+NOTE: If you are in the base directory of wxxt it will create 
+distribution packages for wxxt as well as for all packages in the
+user directory.
+    So if you want to create only packages for the files in user,
+then go to the directory other and type:
+
+	make distrib
+
+or if you only want one application to be created then
+enter the specific directory and type there:
+make distrib
+
+All the distribution files will be put in the directory
+distrib at the base of the wxxt-tree (where also configure
+and template.mak can be found).
+
+** Something about Makefile.in
+--------------------------------
+
+As you have already seen with Makefile, configure makes a lot of use
+if the include statement in make to keep the Makefiles as simple as 
+possible.
+
+So basically there are only variables to define and then a include command.
+Exception to this rule is if you have special rules for some stuff...
+These rules should go AFTER the include statement!!!
+
+so the general header looks like this:
+
+	# wxGTK base directory
+	WXBASEDIR=@WXBASEDIR@
+	# set the OS type for compilation
+	OS=@OS@
+	# compile a library only
+	RULE=bin
+
+and the general footer will look like this:
+
+	# include the definitions now
+	include ../../../template.mak
+
+the key variable is RULE, which defines what make should create
+in this directory.
+
+here are some examples:
+
+  RULE	  description              
+  ===========================================================================
+  bin	  creates a local binary (for a global binary prefix bin with g)
+  	  additional variables needed:
+  		BIN_TARGET	this gives the name of your application
+  		BIN_OBJ		this gives the object files needed to
+  				link the application
+  	  optional variables are:
+  		BIN_SRC		this gives the list of c/c++ files for
+  				which dependencies will be checked.
+  				(This can be achieved with: make depend)
+  		BIN_LINK	this gives commands for additional
+  				libraries needed to link the application
+  ---------------------------------------------------------------------------
+  bin2	  creates two local binaries (for global binaries prefix bin2 with g)
+  	  in addition to the variables specified above you MUST also
+  	  provide the same variables with BIN2_ instead of BIN_
+  ---------------------------------------------------------------------------
+  lib	  creates a local library (for a global binary prefix bin with g)
+  	  additional variables needed:
+  		LIB_TARGET	this gives the name of your library
+  		LIB_OBJ		this gives the object files needed for
+  				the library to be build.
+  	  optional variables are:
+  		LIB_SRC		this gives the list of c/c++ files for
+  				which dependencies will be checked.
+  	  libbin and libgbin are also possible and will need in addition
+  	  the variables from bin
+  ---------------------------------------------------------------------------
+  gslib	  is similar to lib, but it creates a shared library if the system
+  	  supports it.
+  	  additional variables needed:
+  		LIB_MAJOR	major number of the shared library
+  		LIB_MINOR	minor number of the shared library
+  ---------------------------------------------------------------------------
+  other additional variables:
+
+  	  ADD_COMPILE	   define additional includes/defines that
+  			   are needed to compile the object files
+  			   (if you need to reference some directory
+  			   utils - like wxGrid -, then please 
+  			   reference them with the variables defined
+  			   in template.mak - e.g.: $(SRCDIR),$(UTILS),
+  			   $(SAMPLES),$(OTHERS))
+
+  	  NEEDED_DEFINES   lists all the defines that HAVE to be set in
+  			   /include/wx/setup.h to compile correctly.
+
+	  SRC_DIR	   lists all directories that are needed to
+			   compile. (i.e: lists all the directories,
+			   where there are source-files.) But it is 
+			   also needed to clean an object and for 
+			   machines, for which make does not support 
+			   VPATH
+
+currently there are the following compiling rules provided:
+object files are created for the following file extensions:
+.c .cc .cpp
+
+Please have a closer look at the Makefiles in this distribution.
+
+* Platforms configure is working with
+---------------------------------------
+
+Please report build succes on any machine. Especially non-
+Linux operating systems (which I don't have).
+
+Original author of the autoconf system for wxxt-1.66 and for this INSTALL
+file:
+
+	Martin Sperl	sperl@dsn.ast.univie.ac.at
+	
+Ported to wxGTK 0.1:
+
+	Wolfram Gloger  wmglo@dent.med.uni-muenchen.de
+
+Thanks alot to both of them.
+
+In the hope that it will be useful,
+
+        Robert Roebling roebling@sun2.ruf.uni-freiburg.de
+	
+	
\ No newline at end of file
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000..4b603f1824
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,167 @@
+# Top-level Makefile for wxGTK by Wolfram Gloger
+# based on the version for wx-Xt by Martin Sperl
+
+SHELL=/bin/sh
+
+#if DIRS are defind make only executes in these diretories
+all::
+	@if test "x$(DIRS)" = x; then \
+	  for i in src samples utils user; do \
+	    echo "entering directory $$i building $@"; \
+	    (cd $$i; ${MAKE} -k $@); \
+	  done; \
+	else \
+	  for i in $(DIRS) xxx; do \
+	    if test "$$i" != xxx; then \
+	      echo "entering directory $$i building $@"; \
+	      (cd $$i; ${MAKE} -k $@); \
+	    fi; \
+	  done; \
+	fi	    
+
+# what to do if a target is not understood:
+# pass it on to all the children...
+
+.DEFAULT::
+	@if test "x$(DIRS)" = x; then \
+	  for i in src samples utils user; do \
+	    echo "entering directory $$i building $@"; \
+	    (cd $$i; ${MAKE} -k $@); \
+	  done; \
+	else \
+	  for i in $(DIRS) xxx; do \
+	    if test "$$i" != xxx; then \
+	      echo "entering directory $$i building $@"; \
+	      (cd $$i; ${MAKE} -k $@); \
+	    fi; \
+	  done; \
+	fi
+
+src::
+	@echo "entering directory src building all"
+	@cd src; ${MAKE} all
+
+samples::
+	@echo "entering directory samples building all"
+	@cd samples; ${MAKE} all
+
+utils::
+	@echo "entering directory utils building all"
+	@cd utils; ${MAKE} all
+
+user::
+	@echo "entering directory user building all"
+	@cd user; ${MAKE} all
+
+# the following ones recreate all Makefiles.
+
+makefiles:: recreate
+Makefiles:: recreate
+recreate::
+	@src/gtk/setup/general/createall
+
+# the following ones define what needs to be done to distribute the 
+# library and its components
+
+distribute:: distrib
+distrib:: distrib_base distrib_user join_utils join_samples
+
+distrib_samples::
+	@echo "entering directory samples creating distribution files"
+	@(cd samples; ${MAKE} -k distrib)
+
+distrib_user::
+	@echo "entering directory user creating distribution files"
+	@(cd user; ${MAKE} -k distrib)
+
+distrib_utils:: 
+	@echo "entering directory utils creating distribution files"
+	@(cd utils; ${MAKE} -k distrib)
+
+join_utils:: distrib_utils
+	@$(MAKE) join \
+	    BASEDIR=utils \
+	    FILES=`echo distrib/utils/*.tgz `
+
+join_samples:: distrib_samples
+	@$(MAKE) join \
+	    BASEDIR=samples \
+	    FILES=`echo distrib/samples/*.tgz `
+
+join_user:: distrib_user
+	@$(MAKE) join \
+	    BASEDIR=user \
+	    FILES=`echo distrib/user/*.tgz `
+
+join::
+	@# needed are BASEDIR and FILES
+	@if test "x$$BASEDIR" = x; then\
+	  echo "BASEDIR not specified.";\
+	  exit -1;\
+	fi
+	@if test "x$$FILES" != x ; then \
+	  echo "putting all seperate distribution files:";\
+	  echo "$$FILES";\
+	  echo "into distrib/$(BASEDIR).tgz";\
+	  src/gtk/setup/general/jointar $(BASEDIR) $$FILES distrib/$(BASEDIR).tgz; \
+	else \
+	  echo "Nothing to join - deleting..."; \
+	  echo "This may be the case, if you have not specified FILES."\
+	  rm -f distrib/$(BASEDIR).tgz; \
+	fi
+
+distrib_base:: 
+	@if test ! -d distrib ; then mkdir distrib; fi;
+	@if test ! -f system.list ; then \
+	  echo "dummy" > system.list;\
+	fi
+	@(curr=`pwd`; direc=`basename $$curr`;\
+	 (cd ..; \
+	  echo creating distrib/$$direc.tar from the current directory;\
+	  tar -cf /tmp/$$direc.tar \
+	    $$direc/COPYING\
+	    $$direc/INSTALL\
+	    $$direc/Makefile\
+	    $$direc/template.mak\
+	    $$direc/configure\
+	    $$direc/configure.in\
+	    $$direc/config.guess\
+	    $$direc/config.sub\
+	    $$direc/install-sh\
+	    $$direc/user/Makefile \
+	    $$direc/utils/Makefile \
+	    $$direc/samples/Makefile \
+	    ;\
+	  sed "s|^\(.*\)$$|/\1/|g" $$direc/system.list \
+	    | uniq > /tmp/$$direc.list; \
+	  echo "/RCS/" >> /tmp/$$direc.list; \
+	  for each in misc docs wx src setup; do \
+	    tar -uf /tmp/$$direc.tar \
+	      `\
+	       find $$direc/$$each \( -type f -o -type l \) -print \
+	       | fgrep -vf /tmp/$$direc.list \
+	       | grep -v "[~#]$$" \
+	      ` ;\
+	  done; \
+	  echo compressing $$direc.tar to $$direc.tgz;\
+	  gzip -9 -c /tmp/$$direc.tar > $$direc/distrib/$$direc.tgz;\
+	  rm /tmp/$$direc.tar /tmp/$$direc.list;\
+	 )\
+	)
+
+# the following ones are only needed if configure.in has changed
+# and needs to be updated...
+
+config:: configure
+
+configure::
+	@autoconf
+	@cat configure \
+	  | sed "s/config.cache/\$$OSTYPE.config.cache/g" \
+	  | sed "s/config.status/\$$OSTYPE.config.status/g" \
+	  | sed "s/\*\*--/  --/g" \
+	  > configure1
+	@chmod a+x configure1
+	@mv configure1 configure
+
+
diff --git a/config.guess b/config.guess
new file mode 100755
index 0000000000..c3c4e799a6
--- /dev/null
+++ b/config.guess
@@ -0,0 +1,599 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# The master version of this file is at the FSF in /home/gd/gnu/lib.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit system type (host/target name).
+#
+# Only a few systems have been added to this list; please add others
+# (but try to keep the structure clean).
+#
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 8/24/94.)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    alpha:OSF1:[VX]*:*)
+	# After 1.2, OSF1 uses "V1.3" for uname -r.
+	# After 4.x, OSF1 uses "X4.x" for uname -r.
+	echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VX]//'`
+	exit 0 ;;
+    alpha:OSF1:*:*)
+	# 1.2 uses "1.2" for uname -r.
+	echo alpha-dec-osf${UNAME_RELEASE}
+        exit 0 ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-cbm-sysv4
+	exit 0;;
+    amiga:NetBSD:*:*)
+      echo m68k-cbm-netbsd${UNAME_RELEASE}
+      exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit 0;;
+    Pyramid*:OSx*:*:*)
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit 0 ;;
+    sun4*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit 0 ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    atari*:NetBSD:*:*)
+	echo m68k-atari-netbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sun3*:NetBSD:*:*)
+	echo m68k-sun-netbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mac68k:NetBSD:*:*)
+	echo m68k-apple-netbsd${UNAME_RELEASE}
+	exit 0 ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    mips:*:4*:UMIPS)
+	echo mips-mips-riscos4sysv
+	exit 0 ;;
+    mips:*:5*:RISCos)
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit 0 ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit 0 ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit 0 ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`uname -p`
+        if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88100 ] ; then
+	if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
+	     -o ${TARGET_BINARY_INTERFACE}x = x ] ; then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	fi
+        else echo i586-dg-dgux${UNAME_RELEASE}
+        fi
+ 	exit 0 ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit 0 ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit 0 ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit 0 ;;
+   ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+	exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i[34]86:AIX:*:*)
+	echo i386-ibm-aix
+	exit 0 ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		sed 's/^		//' << EOF >dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
+		rm -f dummy.c dummy
+		echo rs6000-ibm-aix3.2.5
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit 0 ;;
+    *:AIX:*:4)
+	if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=4.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC NetBSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to 
+	exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit 0 ;;
+    9000/[3478]??:HP-UX:*:*)
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/7?? | 9000/8?[679] ) HP_ARCH=hppa1.1 ;;
+	    9000/8?? )            HP_ARCH=hppa1.0 ;;
+	esac
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    3050*:HI-UX:*:*)
+	sed 's/^	//' << EOF >dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
+	rm -f dummy.c dummy
+	echo unknown-hitachi-hiuxwe2
+	exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit 0 ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit 0 ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*X-MP:*:*:*)
+	echo xmp-cray-unicos
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE}
+	exit 0 ;;
+    CRAY*C90:*:*:*)
+	echo c90-cray-unicos${UNAME_RELEASE}
+	exit 0 ;;
+    CRAY-2:*:*:*)
+	echo cray2-cray-unicos
+        exit 0 ;;
+    hp3[0-9][05]:NetBSD:*:*)
+	echo m68k-hp-netbsd${UNAME_RELEASE}
+	exit 0 ;;
+    i[34]86:BSD/386:*:* | *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:FreeBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit 0 ;;
+    *:NetBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+	exit 0 ;;
+    i*:CYGWIN*:*)
+	echo i386-unknown-cygwin32
+	exit 0 ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin32
+	exit 0 ;;
+    *:GNU:*:*)
+	echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit 0 ;;
+    *:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us.
+	ld_help_string=`ld --help 2>&1`
+	if echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf_i[345]86"; then
+	  echo "${UNAME_MACHINE}-unknown-linux" ; exit 0
+	elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i[345]86linux"; then
+	  echo "${UNAME_MACHINE}-unknown-linuxaout" ; exit 0
+	elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i[345]86coff"; then
+	  echo "${UNAME_MACHINE}-unknown-linuxcoff" ; exit 0
+	elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68kelf"; then
+	  echo "${UNAME_MACHINE}-unknown-linux" ; exit 0
+	elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68klinux"; then
+	  echo "${UNAME_MACHINE}-unknown-linuxaout" ; exit 0
+	elif test "${UNAME_MACHINE}" = "alpha" ; then
+	  echo alpha-unknown-linux ; exit 0
+	else
+	  # Either a pre-BFD a.out linker (linuxoldld) or one that does not give us
+	  # useful --help.  Gcc wants to distinguish between linuxoldld and linuxaout.
+	  test ! -d /usr/lib/ldscripts/. \
+	    && echo "${UNAME_MACHINE}-unknown-linuxoldld" && exit 0
+	  # Determine whether the default compiler is a.out or elf
+	  cat >dummy.c <<EOF
+main(argc, argv)
+int argc;
+char *argv[];
+{
+#ifdef __ELF__
+  printf ("%s-unknown-linux\n", argv[1]);
+#else
+  printf ("%s-unknown-linuxaout\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+	  ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
+	  rm -f dummy.c dummy
+	fi ;;
+# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.  earlier versions
+# are messed up and put the nodename in both sysname and nodename.
+    i[34]86:DYNIX/ptx:4*:*)
+	echo i386-sequent-sysv4
+	exit 0 ;;
+    i[34]86:*:4.*:* | i[34]86:SYSTEM_V:4.*:*)
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
+	else
+		echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}
+	fi
+	exit 0 ;;
+    i[34]86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-unknown-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		echo ${UNAME_MACHINE}-unknown-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-unknown-sysv32
+	fi
+	exit 0 ;;
+    Intel:Mach:3*:*)
+	echo i386-unknown-mach3
+	exit 0 ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit 0 ;;
+    M680[234]0:*:R3V[567]*:*)
+	test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0)
+        uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4.3 && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m680[234]0:LynxOS:2.[23]*:*)
+	echo m68k-lynx-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit 0 ;;
+    i[34]86:LynxOS:2.[23]*:*)
+	echo i386-lynx-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    TSUNAMI:LynxOS:2.[23]*:*)
+	echo sparc-lynx-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    rs6000:LynxOS:2.[23]*:*)
+	echo rs6000-lynx-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit 0 ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit 0 ;;
+    R3000:*System_V*:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  printf ("%s-next-nextstep%s\n", __ARCHITECTURE__,  version==2 ? "2" : "3");
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-unknown-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+  printf ("vax-dec-bsd\n"); exit (0);
+#else
+  printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
+rm -f dummy.c dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit 0 ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit 0 ;;
+    c34*)
+	echo c34-convex-bsd
+	exit 0 ;;
+    c38*)
+	echo c38-convex-bsd
+	exit 0 ;;
+    c4*)
+	echo c4-convex-bsd
+	exit 0 ;;
+    esac
+fi
+
+#echo '(Unable to guess system type)' 1>&2
+
+exit 1
diff --git a/config.sub b/config.sub
new file mode 100755
index 0000000000..0432524944
--- /dev/null
+++ b/config.sub
@@ -0,0 +1,927 @@
+#! /bin/sh
+# Configuration validation subroutine script, version 1.1.
+#   Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+if [ x$1 = x ]
+then
+	echo Configuration name missing. 1>&2
+	echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
+	echo "or     $0 ALIAS" 1>&2
+	echo where ALIAS is a recognized configuration type. 1>&2
+	exit 1
+fi
+
+# First pass through any local machine types.
+case $1 in
+	*local*)
+		echo $1
+		exit 0
+		;;
+	*)
+	;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  linux-gnu*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple)
+		os=
+		basic_machine=$1
+		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco5)
+		os=sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	tahoe | i860 | m68k | m68000 | m88k | ns32k | arm \
+		| arme[lb] | pyramid \
+		| tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \
+		| alpha | we32k | ns16k | clipper | i370 | sh \
+		| powerpc | powerpcle | 1750a | dsp16xx | mips64 | mipsel \
+		| pdp11 | mips64el | mips64orion | mips64orionel \
+		| sparc | sparclet | sparclite | sparc64)
+		basic_machine=$basic_machine-unknown
+		;;
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i[3456]86)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	vax-* | tahoe-* | i[3456]86-* | i860-* | m68k-* | m68000-* | m88k-* \
+	      | sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \
+	      | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \
+	      | none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \
+	      | hppa-* | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \
+	      | pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \
+	      | pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* | mips64-* | mipsel-* \
+	      | mips64el-* | mips64orion-* | mips64orionel-* | f301-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-cbm
+		;;
+	amigados)
+		basic_machine=m68k-cbm
+		os=-amigados
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-cbm
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	cray2)
+		basic_machine=cray2-cray
+		os=-unicos
+		;;
+	[ctj]90-cray)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7)
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i[3456]86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i[3456]86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i[3456]86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i[3456]86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+        pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pentium | p5)
+		basic_machine=i586-intel
+		;;
+	pentiumpro | p6)
+		basic_machine=i686-intel
+		;;
+	pentium-* | p5-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	k5)
+		# We don't have specific support for AMD's K5 yet, so just call it a Pentium
+		basic_machine=i586-amd
+		;;
+	nexen)
+		# We don't have specific support for Nexgen yet, so just call it a Pentium
+		basic_machine=i586-nexgen
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=rs6000-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+	        ;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+	        ;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+       vpp*|vx|vx-*)
+               basic_machine=f301-fujitsu
+               ;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	xmp)
+		basic_machine=xmp-cray
+		os=-unicos
+		;;
+        xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	mips)
+		basic_machine=mips-mips
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sparc)
+		basic_machine=sparc-sun
+		;;
+        cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-unixware* | svr4*)
+		os=-sysv4
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigados* | -msdos* | -newsos* | -unicos* | -aof* | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+	      | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -linux-gnu* | -uxpv*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-ns2 )
+	        os=-nextstep2
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+        pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-ibm)
+		os=-aix
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigados
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+        *-gould)
+		os=-sysv
+		;;
+        *-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+        *-sgi)
+		os=-irix
+		;;
+        *-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f301-fujitsu)
+		os=-uxpv
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-vxsim* | -vxworks*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
diff --git a/configure b/configure
new file mode 100755
index 0000000000..833cfc2bd8
--- /dev/null
+++ b/configure
@@ -0,0 +1,6572 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12 
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+  --with-x                use the X Window System"
+ac_help="$ac_help
+**--with-shared           create shared libraries"
+ac_help="$ac_help
+**--without-optimise      create unoptimised code"
+ac_help="$ac_help
+**--with-debug_flag       create code with DEBUG define set to 1"
+ac_help="$ac_help
+**--with-debug_info       create code with debuging information included"
+ac_help="$ac_help
+**--with-mem_traing       create code with memory tracing"
+ac_help="$ac_help
+**--with-profile          create code with profiling information included"
+ac_help="$ac_help
+**--with-zlib          use zlib (LZW comression)"
+ac_help="$ac_help
+**--with-gdk_imlib     use Raster's gdk_imlib (Image library)"
+ac_help="$ac_help
+**--with-libpng        use libpng (PNG image format)"
+ac_help="$ac_help
+**--with-threads       use threads"
+ac_help="$ac_help
+**--with-opengl        use opengl (OpenGL or Mesa)"
+ac_help="$ac_help
+**--with-storable          use storable classes"
+ac_help="$ac_help
+**--with-autotrans         use gettext automatic translation"
+ac_help="$ac_help
+**--with-afmfonts         use Adobe Font Metric Font table"
+ac_help="$ac_help
+**--with-PS-normalized    use normalized PS fonts"
+ac_help="$ac_help
+**--with-rpc              use RPC"
+ac_help="$ac_help
+**--with-wxresources      use wxresources"
+ac_help="$ac_help
+**--with-prologio         use prologio"
+ac_help="$ac_help
+**--with-postscript       use postscript-device-context"
+ac_help="$ac_help
+**--with-metafile         use metafile"
+ac_help="$ac_help
+**--with-form             use form"
+ac_help="$ac_help
+**--with-help             use help"
+ac_help="$ac_help
+**--with-ipc              use ipc"
+ac_help="$ac_help
+**--with-enhanceddialog   use enhanced dialog"
+ac_help="$ac_help
+**--with-resources        use resources"
+ac_help="$ac_help
+**--with-clipboard        use clipboard"
+ac_help="$ac_help
+**--with-timedate         use timedate"
+ac_help="$ac_help
+**--with-fraction         use fraction"
+ac_help="$ac_help
+**--with-constraints      use constraints"
+ac_help="$ac_help
+**--with-toolbar          use toolbar"
+ac_help="$ac_help
+**--with-gauge            use gauge"
+ac_help="$ac_help
+**--with-vlbox            use virtual list box"
+ac_help="$ac_help
+**--with-scrollbar        use scrollbar"
+ac_help="$ac_help
+**--with-docview          use document view architecture"
+ac_help="$ac_help
+**--with-printarch        use printing architecture"
+ac_help="$ac_help
+**--with-typetree         use typetree"
+ac_help="$ac_help
+**--with-wxgraph          use wxgraph"
+ac_help="$ac_help
+**--with-wxtree           use wxtree"
+ac_help="$ac_help
+  --with-gtk-prefix=PFX   Prefix where GTK is installed (optional)"
+ac_help="$ac_help
+  --with-gtk-exec-prefix=PFX Exec prefix where GTK is installed (optional)"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  case "$ac_option" in
+  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) ac_optarg= ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case "$ac_option" in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir="$ac_optarg" ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build="$ac_optarg" ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file="$ac_optarg" ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir="$ac_optarg" ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    eval "enable_${ac_feature}=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix="$ac_optarg" ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he)
+    # Omit some internal or obsolete options to make the list less imposing.
+    # This message is too long to be a string in the A/UX 3.1 sh.
+    cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+  --cache-file=FILE       cache test results in FILE
+  --help                  print this message
+  --no-create             do not create output files
+  --quiet, --silent       do not print \`checking...' messages
+  --version               print the version of autoconf that created configure
+Directory and file names:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [same as prefix]
+  --bindir=DIR            user executables in DIR [EPREFIX/bin]
+  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
+  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
+  --datadir=DIR           read-only architecture-independent data in DIR
+                          [PREFIX/share]
+  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
+                          [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
+  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
+  --includedir=DIR        C header files in DIR [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
+  --infodir=DIR           info documentation in DIR [PREFIX/info]
+  --mandir=DIR            man documentation in DIR [PREFIX/man]
+  --srcdir=DIR            find the sources in DIR [configure dir or ..]
+  --program-prefix=PREFIX prepend PREFIX to installed program names
+  --program-suffix=SUFFIX append SUFFIX to installed program names
+  --program-transform-name=PROGRAM
+                          run sed PROGRAM on installed program names
+EOF
+    cat << EOF
+Host type:
+  --build=BUILD           configure for building on BUILD [BUILD=HOST]
+  --host=HOST             configure for HOST [guessed]
+  --target=TARGET         configure for TARGET [TARGET=HOST]
+Features and packages:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --x-includes=DIR        X include files are in DIR
+  --x-libraries=DIR       X library files are in DIR
+EOF
+    if test -n "$ac_help"; then
+      echo "--enable and --with options recognized:$ac_help"
+    fi
+    exit 0 ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host="$ac_optarg" ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir="$ac_optarg" ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir="$ac_optarg" ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir="$ac_optarg" ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir="$ac_optarg" ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir="$ac_optarg" ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir="$ac_optarg" ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir="$ac_optarg" ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix="$ac_optarg" ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix="$ac_optarg" ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix="$ac_optarg" ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name="$ac_optarg" ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir="$ac_optarg" ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir="$ac_optarg" ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site="$ac_optarg" ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir="$ac_optarg" ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir="$ac_optarg" ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target="$ac_optarg" ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers)
+    echo "configure generated by autoconf version 2.12"
+    exit 0 ;;
+
+  -with-* | --with-*)
+    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_${ac_package}='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    eval "with_${ac_package}=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes="$ac_optarg" ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries="$ac_optarg" ;;
+
+  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+    ;;
+
+  *)
+    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+      echo "configure: warning: $ac_option: invalid host type" 1>&2
+    fi
+    if test "x$nonopt" != xNONE; then
+      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+    fi
+    nonopt="$ac_option"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+  case "$ac_arg" in
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c) ;;
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+  *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+  esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set.  These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=configure.in
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_prog=$0
+  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+  else
+    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+  fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    echo "loading site script $ac_site_file"
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  echo "loading cache $cache_file"
+  . $cache_file
+else
+  echo "creating cache $cache_file"
+  > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='	'
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+
+OS="${OSTYPE}"
+
+if test "x$OS" = "x"; then
+  UNAME=`uname`
+  { echo "configure: error: "The system variable OS has not been set"
+               "please set is everytime befor compiling on this system"
+               "A good example for this system would be:"
+               "setenv OSTYPE $UNAME        for csh as a SHELL"
+               "EXPORT OSTYPE=$UNAME        for sh as SHELL"
+               "please set this and restart again."
+              " 1>&2; exit 1; }
+fi
+
+
+WXBASEDIR=`pwd`
+
+
+
+SEARCH_INCLUDE="\
+    /usr/Motif1.2/include     \
+			      \
+    /usr/X11R6/include        \
+    /usr/X11R5/include        \
+    /usr/X11R4/include        \
+                              \
+    /usr/include/X11R6        \
+    /usr/include/X11R5        \
+    /usr/include/X11R4        \
+                              \
+    /usr/local/X11R6/include  \
+    /usr/local/X11R5/include  \
+    /usr/local/X11R4/include  \
+                              \
+    /usr/local/include/X11R6  \
+    /usr/local/include/X11R5  \
+    /usr/local/include/X11R4  \
+                              \
+    /usr/X11/include          \
+    /usr/include/X11          \
+    /usr/local/X11/include    \
+    /usr/local/include/X11    \
+                              \
+    /usr/X386/include         \
+    /usr/x386/include         \
+    /usr/XFree86/include/X11  \
+                              \
+    /usr/include              \
+    /usr/local/include        \
+    /usr/local/include/gtk    \
+    /usr/unsupported/include  \
+    /usr/athena/include       \
+    /usr/local/x11r5/include  \
+    /usr/lpp/Xamples/include  \
+                              \
+    /usr/openwin/include      \
+    /usr/openwin/share/include \
+    "
+
+SEARCH_LIB="`echo "$SEARCH_INCLUDE" | sed s/include/lib/g` \
+    "
+
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:672: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="gcc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:701: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  ac_prog_rejected=no
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+        ac_prog_rejected=yes
+	continue
+      fi
+      ac_cv_prog_CC="cc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# -gt 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    set dummy "$ac_dir/$ac_word" "$@"
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:749: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext <<EOF
+#line 759 "configure"
+#include "confdefs.h"
+main(){return(0);}
+EOF
+if { (eval echo configure:763: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  ac_cv_prog_cc_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cc_cross=no
+  else
+    ac_cv_prog_cc_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:783: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:788: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:797: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gcc=yes
+else
+  ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+  GCC=yes
+  ac_test_CFLAGS="${CFLAGS+set}"
+  ac_save_CFLAGS="$CFLAGS"
+  CFLAGS=
+  echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:812: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+  ac_cv_prog_cc_g=yes
+else
+  ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+  if test "$ac_test_CFLAGS" = set; then
+    CFLAGS="$ac_save_CFLAGS"
+  elif test $ac_cv_prog_cc_g = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-O2"
+  fi
+else
+  GCC=
+  test "${CFLAGS+set}" = set || CFLAGS="-g"
+fi
+
+
+CFLAGS=`echo "$CFLAGS" | sed 's/-g//g'`
+
+if test "x$CC" != xcc; then
+  echo $ac_n "checking whether $CC and cc understand -c and -o together""... $ac_c" 1>&6
+echo "configure:844: checking whether $CC and cc understand -c and -o together" >&5
+else
+  echo $ac_n "checking whether cc understands -c and -o together""... $ac_c" 1>&6
+echo "configure:847: checking whether cc understands -c and -o together" >&5
+fi
+set dummy $CC; ac_cc="`echo $2 |
+		       sed -e 's/[^a-zA-Z0-9_]/_/g' -e 's/^[0-9]/_/'`"
+if eval "test \"`echo '$''{'ac_cv_prog_cc_${ac_cc}_c_o'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'foo(){}' > conftest.c
+# Make sure it works both with $CC and with simple cc.
+# We do the test twice because some compilers refuse to overwrite an
+# existing .o file with -o, though they will create one.
+ac_try='${CC-cc} -c conftest.c -o conftest.o 1>&5'
+if { (eval echo configure:859: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } &&
+   test -f conftest.o && { (eval echo configure:860: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; };
+then
+  eval ac_cv_prog_cc_${ac_cc}_c_o=yes
+  if test "x$CC" != xcc; then
+    # Test first that cc exists at all.
+    if { ac_try='cc -c conftest.c 1>&5'; { (eval echo configure:865: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+      ac_try='cc -c conftest.c -o conftest.o 1>&5'
+      if { (eval echo configure:867: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } &&
+	 test -f conftest.o && { (eval echo configure:868: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; };
+      then
+        # cc works too.
+        :
+      else
+        # cc exists but doesn't like -o.
+        eval ac_cv_prog_cc_${ac_cc}_c_o=no
+      fi
+    fi
+  fi
+else
+  eval ac_cv_prog_cc_${ac_cc}_c_o=no
+fi
+rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+  cat >> confdefs.h <<\EOF
+#define NO_MINUS_C_MINUS_O 1
+EOF
+
+fi
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:895: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    # This must be in double quotes, not single quotes, because CPP may get
+  # substituted into the Makefile and "${CC-cc}" will confuse make.
+  CPP="${CC-cc} -E"
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp.
+  cat > conftest.$ac_ext <<EOF
+#line 910 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:916: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -E -traditional-cpp"
+  cat > conftest.$ac_ext <<EOF
+#line 927 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:933: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+  ac_cv_prog_CPP="$CPP"
+fi
+  CPP="$ac_cv_prog_CPP"
+else
+  ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+    echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
+echo "configure:957: checking whether ${CC-cc} needs -traditional" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    ac_pattern="Autoconf.*'x'"
+  cat > conftest.$ac_ext <<EOF
+#line 963 "configure"
+#include "confdefs.h"
+#include <sgtty.h>
+Autoconf TIOCGETP
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "$ac_pattern" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_prog_gcc_traditional=yes
+else
+  rm -rf conftest*
+  ac_cv_prog_gcc_traditional=no
+fi
+rm -f conftest*
+
+
+  if test $ac_cv_prog_gcc_traditional = no; then
+    cat > conftest.$ac_ext <<EOF
+#line 981 "configure"
+#include "confdefs.h"
+#include <termio.h>
+Autoconf TCGETA
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "$ac_pattern" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_prog_gcc_traditional=yes
+fi
+rm -f conftest*
+
+  fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6
+  if test $ac_cv_prog_gcc_traditional = yes; then
+    CC="$CC -traditional"
+  fi
+fi
+
+
+
+
+for ac_prog in $CCC c++ g++ gcc CC cxx cc++
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1010: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CXX="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CXX="$ac_cv_prog_CXX"
+if test -n "$CXX"; then
+  echo "$ac_t""$CXX" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$CXX" && break
+done
+test -n "$CXX" || CXX="gcc"
+
+
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1041: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
+
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+
+cat > conftest.$ac_ext <<EOF
+#line 1051 "configure"
+#include "confdefs.h"
+main(){return(0);}
+EOF
+if { (eval echo configure:1055: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  ac_cv_prog_cxx_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cxx_cross=no
+  else
+    ac_cv_prog_cxx_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cxx_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6
+if test $ac_cv_prog_cxx_works = no; then
+  { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1081: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
+cross_compiling=$ac_cv_prog_cxx_cross
+
+echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
+echo "configure:1086: checking whether we are using GNU C++" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.C <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1095: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gxx=yes
+else
+  ac_cv_prog_gxx=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gxx" 1>&6
+
+if test $ac_cv_prog_gxx = yes; then
+  GXX=yes
+  ac_test_CXXFLAGS="${CXXFLAGS+set}"
+  ac_save_CXXFLAGS="$CXXFLAGS"
+  CXXFLAGS=
+  echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
+echo "configure:1110: checking whether ${CXX-g++} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.cc
+if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then
+  ac_cv_prog_cxx_g=yes
+else
+  ac_cv_prog_cxx_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6
+  if test "$ac_test_CXXFLAGS" = set; then
+    CXXFLAGS="$ac_save_CXXFLAGS"
+  elif test $ac_cv_prog_cxx_g = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-O2"
+  fi
+else
+  GXX=
+  test "${CXXFLAGS+set}" = set || CXXFLAGS="-g"
+fi
+
+echo $ac_n "checking how to run the C++ preprocessor""... $ac_c" 1>&6
+echo "configure:1138: checking how to run the C++ preprocessor" >&5
+if test -z "$CXXCPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CXXCPP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+  CXXCPP="${CXX-g++} -E"
+  cat > conftest.$ac_ext <<EOF
+#line 1151 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1156: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CXXCPP=/lib/cpp
+fi
+rm -f conftest*
+  ac_cv_prog_CXXCPP="$CXXCPP"
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+fi
+fi
+CXXCPP="$ac_cv_prog_CXXCPP"
+echo "$ac_t""$CXXCPP" 1>&6
+
+
+CXXFLAGS=`echo "$CXXFLAGS" | sed 's/-g//g'`
+
+
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1188: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_RANLIB="ranlib"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+  echo "$ac_t""$RANLIB" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+# Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1218: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_AR="ar"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar"
+fi
+fi
+AR="$ac_cv_prog_AR"
+if test -n "$AR"; then
+  echo "$ac_t""$AR" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:1275: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    IFS="${IFS= 	}"; ac_save_IFS="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    # Account for people who put trailing slashes in PATH elements.
+    case "$ac_dir/" in
+    /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+    *)
+      # OSF1 and SCO ODT 3.0 have their own names for install.
+      for ac_prog in ginstall installbsd scoinst install; do
+        if test -f $ac_dir/$ac_prog; then
+	  if test $ac_prog = install &&
+            grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    # OSF/1 installbsd also uses dspmsg, but is usable.
+	    :
+	  else
+	    ac_cv_path_install="$ac_dir/$ac_prog -c"
+	    break 2
+	  fi
+	fi
+      done
+      ;;
+    esac
+  done
+  IFS="$ac_save_IFS"
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL="$ac_cv_path_install"
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL="$ac_install_sh"
+  fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:1326: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+  rm -f conftestdata
+  ac_cv_prog_LN_S="ln -s"
+else
+  ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+for ac_prog in mawk gawk nawk awk
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1352: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_AWK="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+AWK="$ac_cv_prog_AWK"
+if test -n "$AWK"; then
+  echo "$ac_t""$AWK" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$AWK" && break
+done
+
+
+echo $ac_n "checking "make for VPATH support"""... $ac_c" 1>&6
+echo "configure:1382: checking "make for VPATH support"" >&5
+cat - << EOF > confMake
+check : file
+	cp \$? \$@
+	cp \$? final_file
+EOF
+
+if test ! -d sub ; then
+  mkdir sub
+fi
+echo dummy > sub/file
+${MAKE-make} -f confMake VPATH=sub 2> config.log > /dev/null
+RESULT=$?
+rm -f sub/file check final_file config.log confMake
+rmdir sub 
+if test "$RESULT" = 0; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+  { echo "configure: error: You need a make-utility that is able to use the variable
+VPATH correctly.
+If your version of make does not support VPATH correctly" 1>&2; exit 1; } 
+fi
+
+
+# If we find X, set shell vars x_includes and x_libraries to the
+# paths, otherwise set no_x=yes.
+# Uses ac_ vars as temps to allow command line to override cache and checks.
+# --without-x overrides everything else, but does not touch the cache.
+echo $ac_n "checking for X""... $ac_c" 1>&6
+echo "configure:1412: checking for X" >&5
+
+# Check whether --with-x or --without-x was given.
+if test "${with_x+set}" = set; then
+  withval="$with_x"
+  :
+fi
+
+# $have_x is `yes', `no', `disabled', or empty when we do not yet know.
+if test "x$with_x" = xno; then
+  # The user explicitly disabled X.
+  have_x=disabled
+else
+  if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then
+    # Both variables are already set.
+    have_x=yes
+  else
+if eval "test \"`echo '$''{'ac_cv_have_x'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  # One or both of the vars are not set, and there is no cached value.
+ac_x_includes=NO ac_x_libraries=NO
+rm -fr conftestdir
+if mkdir conftestdir; then
+  cd conftestdir
+  # Make sure to not put "make" in the Imakefile rules, since we grep it out.
+  cat > Imakefile <<'EOF'
+acfindx:
+	@echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"'
+EOF
+  if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then
+    # GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+    eval `${MAKE-make} acfindx 2>/dev/null | grep -v make`
+    # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR.
+    for ac_extension in a so sl; do
+      if test ! -f $ac_im_usrlibdir/libX11.$ac_extension &&
+        test -f $ac_im_libdir/libX11.$ac_extension; then
+        ac_im_usrlibdir=$ac_im_libdir; break
+      fi
+    done
+    # Screen out bogus values from the imake configuration.  They are
+    # bogus both because they are the default anyway, and because
+    # using them would break gcc on systems where it needs fixed includes.
+    case "$ac_im_incroot" in
+	/usr/include) ;;
+	*) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes="$ac_im_incroot" ;;
+    esac
+    case "$ac_im_usrlibdir" in
+	/usr/lib | /lib) ;;
+	*) test -d "$ac_im_usrlibdir" && ac_x_libraries="$ac_im_usrlibdir" ;;
+    esac
+  fi
+  cd ..
+  rm -fr conftestdir
+fi
+
+if test "$ac_x_includes" = NO; then
+  # Guess where to find include files, by looking for this one X11 .h file.
+  test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h
+
+  # First, try using that file with no special directory specified.
+cat > conftest.$ac_ext <<EOF
+#line 1474 "configure"
+#include "confdefs.h"
+#include <$x_direct_test_include>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1479: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  # We can compile using X headers with no special include directory.
+ac_x_includes=
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  # Look for the header file in a standard set of common directories.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+  for ac_dir in               \
+    /usr/X11/include          \
+    /usr/X11R6/include        \
+    /usr/X11R5/include        \
+    /usr/X11R4/include        \
+                              \
+    /usr/include/X11          \
+    /usr/include/X11R6        \
+    /usr/include/X11R5        \
+    /usr/include/X11R4        \
+                              \
+    /usr/local/X11/include    \
+    /usr/local/X11R6/include  \
+    /usr/local/X11R5/include  \
+    /usr/local/X11R4/include  \
+                              \
+    /usr/local/include/X11    \
+    /usr/local/include/X11R6  \
+    /usr/local/include/X11R5  \
+    /usr/local/include/X11R4  \
+                              \
+    /usr/X386/include         \
+    /usr/x386/include         \
+    /usr/XFree86/include/X11  \
+                              \
+    /usr/include              \
+    /usr/local/include        \
+    /usr/unsupported/include  \
+    /usr/athena/include       \
+    /usr/local/x11r5/include  \
+    /usr/lpp/Xamples/include  \
+                              \
+    /usr/openwin/include      \
+    /usr/openwin/share/include \
+    ; \
+  do
+    if test -r "$ac_dir/$x_direct_test_include"; then
+      ac_x_includes=$ac_dir
+      break
+    fi
+  done
+fi
+rm -f conftest*
+fi # $ac_x_includes = NO
+
+if test "$ac_x_libraries" = NO; then
+  # Check for the libraries.
+
+  test -z "$x_direct_test_library" && x_direct_test_library=Xt
+  test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc
+
+  # See if we find them without any special options.
+  # Don't add to $LIBS permanently.
+  ac_save_LIBS="$LIBS"
+  LIBS="-l$x_direct_test_library $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1548 "configure"
+#include "confdefs.h"
+
+int main() {
+${x_direct_test_function}()
+; return 0; }
+EOF
+if { (eval echo configure:1555: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  LIBS="$ac_save_LIBS"
+# We can link X programs with no special library path.
+ac_x_libraries=
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  LIBS="$ac_save_LIBS"
+# First see if replacing the include by lib works.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+for ac_dir in `echo "$ac_x_includes" | sed s/include/lib/` \
+    /usr/X11/lib          \
+    /usr/X11R6/lib        \
+    /usr/X11R5/lib        \
+    /usr/X11R4/lib        \
+                          \
+    /usr/lib/X11          \
+    /usr/lib/X11R6        \
+    /usr/lib/X11R5        \
+    /usr/lib/X11R4        \
+                          \
+    /usr/local/X11/lib    \
+    /usr/local/X11R6/lib  \
+    /usr/local/X11R5/lib  \
+    /usr/local/X11R4/lib  \
+                          \
+    /usr/local/lib/X11    \
+    /usr/local/lib/X11R6  \
+    /usr/local/lib/X11R5  \
+    /usr/local/lib/X11R4  \
+                          \
+    /usr/X386/lib         \
+    /usr/x386/lib         \
+    /usr/XFree86/lib/X11  \
+                          \
+    /usr/lib              \
+    /usr/local/lib        \
+    /usr/unsupported/lib  \
+    /usr/athena/lib       \
+    /usr/local/x11r5/lib  \
+    /usr/lpp/Xamples/lib  \
+    /lib/usr/lib/X11	  \
+                          \
+    /usr/openwin/lib      \
+    /usr/openwin/share/lib \
+    ; \
+do
+  for ac_extension in a so sl; do
+    if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then
+      ac_x_libraries=$ac_dir
+      break 2
+    fi
+  done
+done
+fi
+rm -f conftest*
+fi # $ac_x_libraries = NO
+
+if test "$ac_x_includes" = NO || test "$ac_x_libraries" = NO; then
+  # Didn't find X anywhere.  Cache the known absence of X.
+  ac_cv_have_x="have_x=no"
+else
+  # Record where we found X for the cache.
+  ac_cv_have_x="have_x=yes \
+	        ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries"
+fi
+fi
+  fi
+  eval "$ac_cv_have_x"
+fi # $with_x != no
+
+if test "$have_x" != yes; then
+  echo "$ac_t""$have_x" 1>&6
+  no_x=yes
+else
+  # If each of the values was on the command line, it overrides each guess.
+  test "x$x_includes" = xNONE && x_includes=$ac_x_includes
+  test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries
+  # Update the cache value to reflect the command line values.
+  ac_cv_have_x="have_x=yes \
+		ac_x_includes=$x_includes ac_x_libraries=$x_libraries"
+  echo "$ac_t""libraries $x_libraries, headers $x_includes" 1>&6
+fi
+
+if test "$no_x" = yes; then
+  # Not all programs may use this symbol, but it does not hurt to define it.
+  cat >> confdefs.h <<\EOF
+#define X_DISPLAY_MISSING 1
+EOF
+
+  X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS=
+else
+  if test -n "$x_includes"; then
+    X_CFLAGS="$X_CFLAGS -I$x_includes"
+  fi
+
+  # It would also be nice to do this for all -L options, not just this one.
+  if test -n "$x_libraries"; then
+    X_LIBS="$X_LIBS -L$x_libraries"
+    # For Solaris; some versions of Sun CC require a space after -R and
+    # others require no space.  Words are not sufficient . . . .
+    case "`(uname -sr) 2>/dev/null`" in
+    "SunOS 5"*)
+      echo $ac_n "checking whether -R must be followed by a space""... $ac_c" 1>&6
+echo "configure:1661: checking whether -R must be followed by a space" >&5
+      ac_xsave_LIBS="$LIBS"; LIBS="$LIBS -R$x_libraries"
+      cat > conftest.$ac_ext <<EOF
+#line 1664 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1671: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  ac_R_nospace=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_R_nospace=no
+fi
+rm -f conftest*
+      if test $ac_R_nospace = yes; then
+	echo "$ac_t""no" 1>&6
+	X_LIBS="$X_LIBS -R$x_libraries"
+      else
+	LIBS="$ac_xsave_LIBS -R $x_libraries"
+	cat > conftest.$ac_ext <<EOF
+#line 1687 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1694: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  ac_R_space=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_R_space=no
+fi
+rm -f conftest*
+	if test $ac_R_space = yes; then
+	  echo "$ac_t""yes" 1>&6
+	  X_LIBS="$X_LIBS -R $x_libraries"
+	else
+	  echo "$ac_t""neither works" 1>&6
+	fi
+      fi
+      LIBS="$ac_xsave_LIBS"
+    esac
+  fi
+
+  # Check for system-dependent libraries X programs must link with.
+  # Do this before checking for the system-independent R6 libraries
+  # (-lICE), since we may need -lsocket or whatever for X linking.
+
+  if test "$ISC" = yes; then
+    X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet"
+  else
+    # Martyn.Johnson@cl.cam.ac.uk says this is needed for Ultrix, if the X
+    # libraries were built with DECnet support.  And karl@cs.umb.edu says
+    # the Alpha needs dnet_stub (dnet does not exist).
+    echo $ac_n "checking for dnet_ntoa in -ldnet""... $ac_c" 1>&6
+echo "configure:1726: checking for dnet_ntoa in -ldnet" >&5
+ac_lib_var=`echo dnet'_'dnet_ntoa | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldnet  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1734 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char dnet_ntoa();
+
+int main() {
+dnet_ntoa()
+; return 0; }
+EOF
+if { (eval echo configure:1745: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    if test $ac_cv_lib_dnet_dnet_ntoa = no; then
+      echo $ac_n "checking for dnet_ntoa in -ldnet_stub""... $ac_c" 1>&6
+echo "configure:1767: checking for dnet_ntoa in -ldnet_stub" >&5
+ac_lib_var=`echo dnet_stub'_'dnet_ntoa | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldnet_stub  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1775 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char dnet_ntoa();
+
+int main() {
+dnet_ntoa()
+; return 0; }
+EOF
+if { (eval echo configure:1786: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    fi
+
+    # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT,
+    # to get the SysV transport functions.
+    # chad@anasazi.com says the Pyramis MIS-ES running DC/OSx (SVR4)
+    # needs -lnsl.
+    # The nsl library prevents programs from opening the X display
+    # on Irix 5.2, according to dickey@clark.net.
+    echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6
+echo "configure:1815: checking for gethostbyname" >&5
+if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1820 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char gethostbyname(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char gethostbyname();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname)
+choke me
+#else
+gethostbyname();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1843: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_func_gethostbyname=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_gethostbyname=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    if test $ac_cv_func_gethostbyname = no; then
+      echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6
+echo "configure:1864: checking for gethostbyname in -lnsl" >&5
+ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lnsl  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1872 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char gethostbyname();
+
+int main() {
+gethostbyname()
+; return 0; }
+EOF
+if { (eval echo configure:1883: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    fi
+
+    # lieder@skyler.mavd.honeywell.com says without -lsocket,
+    # socket/setsockopt and other routines are undefined under SCO ODT
+    # 2.0.  But -lsocket is broken on IRIX 5.2 (and is not necessary
+    # on later versions), says simon@lia.di.epfl.ch: it contains
+    # gethostby* variants that don't use the nameserver (or something).
+    # -lsocket must be given before -lnsl if both are needed.
+    # We assume that if connect needs -lnsl, so does gethostbyname.
+    echo $ac_n "checking for connect""... $ac_c" 1>&6
+echo "configure:1913: checking for connect" >&5
+if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1918 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char connect(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char connect();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_connect) || defined (__stub___connect)
+choke me
+#else
+connect();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1941: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_func_connect=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_connect=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'connect`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    if test $ac_cv_func_connect = no; then
+      echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6
+echo "configure:1962: checking for connect in -lsocket" >&5
+ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lsocket $X_EXTRA_LIBS $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1970 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char connect();
+
+int main() {
+connect()
+; return 0; }
+EOF
+if { (eval echo configure:1981: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    fi
+
+    # gomez@mi.uni-erlangen.de says -lposix is necessary on A/UX.
+    echo $ac_n "checking for remove""... $ac_c" 1>&6
+echo "configure:2005: checking for remove" >&5
+if eval "test \"`echo '$''{'ac_cv_func_remove'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2010 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char remove(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char remove();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_remove) || defined (__stub___remove)
+choke me
+#else
+remove();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2033: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_func_remove=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_remove=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'remove`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    if test $ac_cv_func_remove = no; then
+      echo $ac_n "checking for remove in -lposix""... $ac_c" 1>&6
+echo "configure:2054: checking for remove in -lposix" >&5
+ac_lib_var=`echo posix'_'remove | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lposix  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2062 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char remove();
+
+int main() {
+remove()
+; return 0; }
+EOF
+if { (eval echo configure:2073: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    fi
+
+    # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay.
+    echo $ac_n "checking for shmat""... $ac_c" 1>&6
+echo "configure:2097: checking for shmat" >&5
+if eval "test \"`echo '$''{'ac_cv_func_shmat'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2102 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char shmat(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char shmat();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_shmat) || defined (__stub___shmat)
+choke me
+#else
+shmat();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2125: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_func_shmat=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_shmat=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'shmat`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    if test $ac_cv_func_shmat = no; then
+      echo $ac_n "checking for shmat in -lipc""... $ac_c" 1>&6
+echo "configure:2146: checking for shmat in -lipc" >&5
+ac_lib_var=`echo ipc'_'shmat | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lipc  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2154 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char shmat();
+
+int main() {
+shmat()
+; return 0; }
+EOF
+if { (eval echo configure:2165: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    fi
+  fi
+
+  # Check for libraries that X11R6 Xt/Xaw programs need.
+  ac_save_LDFLAGS="$LDFLAGS"
+  test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries"
+  # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to
+  # check for ICE first), but we must link in the order -lSM -lICE or
+  # we get undefined symbols.  So assume we have SM if we have ICE.
+  # These have to be linked with before -lX11, unlike the other
+  # libraries we check for below, so use a different variable.
+  #  --interran@uluru.Stanford.EDU, kb@cs.umb.edu.
+  echo $ac_n "checking for IceConnectionNumber in -lICE""... $ac_c" 1>&6
+echo "configure:2198: checking for IceConnectionNumber in -lICE" >&5
+ac_lib_var=`echo ICE'_'IceConnectionNumber | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lICE  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2206 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char IceConnectionNumber();
+
+int main() {
+IceConnectionNumber()
+; return 0; }
+EOF
+if { (eval echo configure:2217: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  LDFLAGS="$ac_save_LDFLAGS"
+
+fi
+
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
+echo "configure:2247: checking for $ac_hdr that defines DIR" >&5
+if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2252 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <$ac_hdr>
+int main() {
+DIR *dirp = 0;
+; return 0; }
+EOF
+if { (eval echo configure:2260: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  eval "ac_cv_header_dirent_$ac_safe=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_dirent_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ ac_header_dirent=$ac_hdr; break
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
+echo "configure:2285: checking for opendir in -ldir" >&5
+ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldir  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2293 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
+EOF
+if { (eval echo configure:2304: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  LIBS="$LIBS -ldir"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+else
+echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
+echo "configure:2326: checking for opendir in -lx" >&5
+ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lx  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2334 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
+EOF
+if { (eval echo configure:2345: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  LIBS="$LIBS -lx"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:2368: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2373 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2381: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  ac_cv_header_stdc=yes
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 2398 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "memchr" >/dev/null 2>&1; then
+  :
+else
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 2416 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "free" >/dev/null 2>&1; then
+  :
+else
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+  :
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2437 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:2448: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  :
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+  cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
+echo "configure:2472: checking for sys/wait.h that is POSIX.1 compatible" >&5
+if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2477 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+int main() {
+int s;
+wait (&s);
+s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+; return 0; }
+EOF
+if { (eval echo configure:2493: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_header_sys_wait_h=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_header_sys_wait_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6
+if test $ac_cv_header_sys_wait_h = yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_SYS_WAIT_H 1
+EOF
+
+fi
+
+ac_safe=`echo "fcntl.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for fcntl.h""... $ac_c" 1>&6
+echo "configure:2515: checking for fcntl.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2520 "configure"
+#include "confdefs.h"
+#include <fcntl.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2525: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+ac_safe=`echo "limits.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for limits.h""... $ac_c" 1>&6
+echo "configure:2548: checking for limits.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2553 "configure"
+#include "confdefs.h"
+#include <limits.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2558: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+ac_safe=`echo "sys/file.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for sys/file.h""... $ac_c" 1>&6
+echo "configure:2581: checking for sys/file.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2586 "configure"
+#include "confdefs.h"
+#include <sys/file.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2591: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+ac_safe=`echo "sys/time.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for sys/time.h""... $ac_c" 1>&6
+echo "configure:2614: checking for sys/time.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2619 "configure"
+#include "confdefs.h"
+#include <sys/time.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2624: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+ac_safe=`echo "unistd.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for unistd.h""... $ac_c" 1>&6
+echo "configure:2647: checking for unistd.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2652 "configure"
+#include "confdefs.h"
+#include <unistd.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2657: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
+echo "configure:2680: checking for uid_t in sys/types.h" >&5
+if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2685 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "uid_t" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_uid_t=yes
+else
+  rm -rf conftest*
+  ac_cv_type_uid_t=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_type_uid_t" 1>&6
+if test $ac_cv_type_uid_t = no; then
+  cat >> confdefs.h <<\EOF
+#define uid_t int
+EOF
+
+  cat >> confdefs.h <<\EOF
+#define gid_t int
+EOF
+
+fi
+
+echo $ac_n "checking type of array argument to getgroups""... $ac_c" 1>&6
+echo "configure:2714: checking type of array argument to getgroups" >&5
+if eval "test \"`echo '$''{'ac_cv_type_getgroups'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_type_getgroups=cross
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2722 "configure"
+#include "confdefs.h"
+
+/* Thanks to Mike Rendell for this test.  */
+#include <sys/types.h>
+#define NGID 256
+#undef MAX
+#define MAX(x, y) ((x) > (y) ? (x) : (y))
+main()
+{
+  gid_t gidset[NGID];
+  int i, n;
+  union { gid_t gval; long lval; }  val;
+
+  val.lval = -1;
+  for (i = 0; i < NGID; i++)
+    gidset[i] = val.gval;
+  n = getgroups (sizeof (gidset) / MAX (sizeof (int), sizeof (gid_t)) - 1,
+                 gidset);
+  /* Exit non-zero if getgroups seems to require an array of ints.  This
+     happens when gid_t is short but getgroups modifies an array of ints.  */
+  exit ((n > 0 && gidset[n] != val.gval) ? 1 : 0);
+}
+
+EOF
+if { (eval echo configure:2747: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+    ac_cv_type_getgroups=gid_t
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_type_getgroups=int
+fi
+rm -fr conftest*
+fi
+
+if test $ac_cv_type_getgroups = cross; then
+        cat > conftest.$ac_ext <<EOF
+#line 2761 "configure"
+#include "confdefs.h"
+#include <unistd.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "getgroups.*int.*gid_t" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_getgroups=gid_t
+else
+  rm -rf conftest*
+  ac_cv_type_getgroups=int
+fi
+rm -f conftest*
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_type_getgroups" 1>&6
+cat >> confdefs.h <<EOF
+#define GETGROUPS_T $ac_cv_type_getgroups
+EOF
+
+
+echo $ac_n "checking for mode_t""... $ac_c" 1>&6
+echo "configure:2785: checking for mode_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_mode_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2790 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "mode_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_mode_t=yes
+else
+  rm -rf conftest*
+  ac_cv_type_mode_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_mode_t" 1>&6
+if test $ac_cv_type_mode_t = no; then
+  cat >> confdefs.h <<\EOF
+#define mode_t int
+EOF
+
+fi
+
+echo $ac_n "checking for off_t""... $ac_c" 1>&6
+echo "configure:2818: checking for off_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2823 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_off_t=yes
+else
+  rm -rf conftest*
+  ac_cv_type_off_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_off_t" 1>&6
+if test $ac_cv_type_off_t = no; then
+  cat >> confdefs.h <<\EOF
+#define off_t long
+EOF
+
+fi
+
+echo $ac_n "checking for pid_t""... $ac_c" 1>&6
+echo "configure:2851: checking for pid_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2856 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_pid_t=yes
+else
+  rm -rf conftest*
+  ac_cv_type_pid_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_pid_t" 1>&6
+if test $ac_cv_type_pid_t = no; then
+  cat >> confdefs.h <<\EOF
+#define pid_t int
+EOF
+
+fi
+
+echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
+echo "configure:2884: checking return type of signal handlers" >&5
+if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2889 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int main() {
+int i;
+; return 0; }
+EOF
+if { (eval echo configure:2906: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_type_signal=void
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_type_signal=int
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_signal" 1>&6
+cat >> confdefs.h <<EOF
+#define RETSIGTYPE $ac_cv_type_signal
+EOF
+
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:2925: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2930 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_size_t=yes
+else
+  rm -rf conftest*
+  ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+  cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
+echo "configure:2958: checking for uid_t in sys/types.h" >&5
+if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2963 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "uid_t" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_uid_t=yes
+else
+  rm -rf conftest*
+  ac_cv_type_uid_t=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_type_uid_t" 1>&6
+if test $ac_cv_type_uid_t = no; then
+  cat >> confdefs.h <<\EOF
+#define uid_t int
+EOF
+
+  cat >> confdefs.h <<\EOF
+#define gid_t int
+EOF
+
+fi
+
+
+
+echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6
+echo "configure:2994: checking whether stat file-mode macros are broken" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stat_broken'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2999 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if defined(S_ISBLK) && defined(S_IFDIR)
+# if S_ISBLK (S_IFDIR)
+You lose.
+# endif
+#endif
+
+#if defined(S_ISBLK) && defined(S_IFCHR)
+# if S_ISBLK (S_IFCHR)
+You lose.
+# endif
+#endif
+
+#if defined(S_ISLNK) && defined(S_IFREG)
+# if S_ISLNK (S_IFREG)
+You lose.
+# endif
+#endif
+
+#if defined(S_ISSOCK) && defined(S_IFREG)
+# if S_ISSOCK (S_IFREG)
+You lose.
+# endif
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "You lose" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_header_stat_broken=yes
+else
+  rm -rf conftest*
+  ac_cv_header_stat_broken=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_header_stat_broken" 1>&6
+if test $ac_cv_header_stat_broken = yes; then
+  cat >> confdefs.h <<\EOF
+#define STAT_MACROS_BROKEN 1
+EOF
+
+fi
+
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+echo "configure:3050: checking whether time.h and sys/time.h may both be included" >&5
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3055 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+int main() {
+struct tm *tp;
+; return 0; }
+EOF
+if { (eval echo configure:3064: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_header_time=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_header_time=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_time" 1>&6
+if test $ac_cv_header_time = yes; then
+  cat >> confdefs.h <<\EOF
+#define TIME_WITH_SYS_TIME 1
+EOF
+
+fi
+
+echo $ac_n "checking for st_blksize in struct stat""... $ac_c" 1>&6
+echo "configure:3085: checking for st_blksize in struct stat" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_st_blksize'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3090 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+int main() {
+struct stat s; s.st_blksize;
+; return 0; }
+EOF
+if { (eval echo configure:3098: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_struct_st_blksize=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_struct_st_blksize=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_st_blksize" 1>&6
+if test $ac_cv_struct_st_blksize = yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_ST_BLKSIZE 1
+EOF
+
+fi
+ 
+echo $ac_n "checking for st_blocks in struct stat""... $ac_c" 1>&6
+echo "configure:3119: checking for st_blocks in struct stat" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_st_blocks'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3124 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+int main() {
+struct stat s; s.st_blocks;
+; return 0; }
+EOF
+if { (eval echo configure:3132: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_struct_st_blocks=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_struct_st_blocks=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_st_blocks" 1>&6
+if test $ac_cv_struct_st_blocks = yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_ST_BLOCKS 1
+EOF
+
+else
+  LIBOBJS="$LIBOBJS fileblocks.o"
+fi
+ 
+echo $ac_n "checking for st_rdev in struct stat""... $ac_c" 1>&6
+echo "configure:3155: checking for st_rdev in struct stat" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_st_rdev'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3160 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+int main() {
+struct stat s; s.st_rdev;
+; return 0; }
+EOF
+if { (eval echo configure:3168: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_struct_st_rdev=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_struct_st_rdev=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_st_rdev" 1>&6
+if test $ac_cv_struct_st_rdev = yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_ST_RDEV 1
+EOF
+
+fi
+ 
+echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6
+echo "configure:3189: checking whether struct tm is in sys/time.h or time.h" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3194 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <time.h>
+int main() {
+struct tm *tp; tp->tm_sec;
+; return 0; }
+EOF
+if { (eval echo configure:3202: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_struct_tm=time.h
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_struct_tm=sys/time.h
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_tm" 1>&6
+if test $ac_cv_struct_tm = sys/time.h; then
+  cat >> confdefs.h <<\EOF
+#define TM_IN_SYS_TIME 1
+EOF
+
+fi
+
+echo $ac_n "checking for tm_zone in struct tm""... $ac_c" 1>&6
+echo "configure:3223: checking for tm_zone in struct tm" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_tm_zone'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3228 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <$ac_cv_struct_tm>
+int main() {
+struct tm tm; tm.tm_zone;
+; return 0; }
+EOF
+if { (eval echo configure:3236: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_struct_tm_zone=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_struct_tm_zone=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_tm_zone" 1>&6
+if test "$ac_cv_struct_tm_zone" = yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_TM_ZONE 1
+EOF
+
+else
+  echo $ac_n "checking for tzname""... $ac_c" 1>&6
+echo "configure:3256: checking for tzname" >&5
+if eval "test \"`echo '$''{'ac_cv_var_tzname'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3261 "configure"
+#include "confdefs.h"
+#include <time.h>
+#ifndef tzname /* For SGI.  */
+extern char *tzname[]; /* RS6000 and others reject char **tzname.  */
+#endif
+int main() {
+atoi(*tzname);
+; return 0; }
+EOF
+if { (eval echo configure:3271: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  ac_cv_var_tzname=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_var_tzname=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_var_tzname" 1>&6
+  if test $ac_cv_var_tzname = yes; then
+    cat >> confdefs.h <<\EOF
+#define HAVE_TZNAME 1
+EOF
+
+  fi
+fi
+
+
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:3295: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3300 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this.  */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this.  */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this.  */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+   It does not let you subtract one const X* pointer from another in an arm
+   of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this.  */
+  char *t;
+  char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+  *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+  int x[] = {25, 17};
+  const int *foo = &x[0];
+  ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+  typedef const int *iptr;
+  iptr p = 0;
+  ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+     "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+  struct s { int j; const int *ap[3]; };
+  struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+  const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:3349: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_c_const=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+  cat >> confdefs.h <<\EOF
+#define const 
+EOF
+
+fi
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:3370: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+  cat > conftest.$ac_ext <<EOF
+#line 3377 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:3384: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_c_inline=$ac_kw; break
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+  inline | yes) ;;
+  no) cat >> confdefs.h <<\EOF
+#define inline 
+EOF
+ ;;
+  *)  cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+echo $ac_n "checking whether char is unsigned""... $ac_c" 1>&6
+echo "configure:3410: checking whether char is unsigned" >&5
+if eval "test \"`echo '$''{'ac_cv_c_char_unsigned'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$GCC" = yes; then
+  # GCC predefines this symbol on systems where it applies.
+cat > conftest.$ac_ext <<EOF
+#line 3417 "configure"
+#include "confdefs.h"
+#ifdef __CHAR_UNSIGNED__
+  yes
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "yes" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_c_char_unsigned=yes
+else
+  rm -rf conftest*
+  ac_cv_c_char_unsigned=no
+fi
+rm -f conftest*
+
+else
+if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3439 "configure"
+#include "confdefs.h"
+/* volatile prevents gcc2 from optimizing the test away on sparcs.  */
+#if !defined(__STDC__) || __STDC__ != 1
+#define volatile
+#endif
+main() {
+  volatile char c = 255; exit(c < 0);
+}
+EOF
+if { (eval echo configure:3449: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_c_char_unsigned=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_c_char_unsigned=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_c_char_unsigned" 1>&6
+if test $ac_cv_c_char_unsigned = yes && test "$GCC" != yes; then
+  cat >> confdefs.h <<\EOF
+#define __CHAR_UNSIGNED__ 1
+EOF
+
+fi
+
+echo $ac_n "checking for long double""... $ac_c" 1>&6
+echo "configure:3473: checking for long double" >&5
+if eval "test \"`echo '$''{'ac_cv_c_long_double'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$GCC" = yes; then
+  ac_cv_c_long_double=yes
+else
+if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3484 "configure"
+#include "confdefs.h"
+int main() {
+/* The Stardent Vistra knows sizeof(long double), but does not support it.  */
+long double foo = 0.0;
+/* On Ultrix 4.3 cc, long double is 4 and double is 8.  */
+exit(sizeof(long double) < sizeof(double)); }
+EOF
+if { (eval echo configure:3492: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_c_long_double=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_c_long_double=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_c_long_double" 1>&6
+if test $ac_cv_c_long_double = yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_LONG_DOUBLE 1
+EOF
+
+fi
+
+
+echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
+echo "configure:3517: checking whether byte ordering is bigendian" >&5
+if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_cv_c_bigendian=unknown
+# See if sys/param.h defines the BYTE_ORDER macro.
+cat > conftest.$ac_ext <<EOF
+#line 3524 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:3535: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+cat > conftest.$ac_ext <<EOF
+#line 3539 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:3550: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_c_bigendian=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_c_bigendian=no
+fi
+rm -f conftest*
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+if test $ac_cv_c_bigendian = unknown; then
+if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3570 "configure"
+#include "confdefs.h"
+main () {
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+  u.l = 1;
+  exit (u.c[sizeof (long) - 1] == 1);
+}
+EOF
+if { (eval echo configure:3583: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_c_bigendian=no
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_c_bigendian=yes
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_c_bigendian" 1>&6
+if test $ac_cv_c_bigendian = yes; then
+  cat >> confdefs.h <<\EOF
+#define WORDS_BIGENDIAN 1
+EOF
+
+fi
+
+
+echo $ac_n "checking size of int *""... $ac_c" 1>&6
+echo "configure:3608: checking size of int *" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_int_p'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3616 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(int *));
+  exit(0);
+}
+EOF
+if { (eval echo configure:3627: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_int_p=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_int_p=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_int_p" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_INT_P $ac_cv_sizeof_int_p
+EOF
+
+
+echo $ac_n "checking size of int""... $ac_c" 1>&6
+echo "configure:3647: checking size of int" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3655 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(int));
+  exit(0);
+}
+EOF
+if { (eval echo configure:3666: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_int=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_int=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_int" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+EOF
+
+
+echo $ac_n "checking size of long""... $ac_c" 1>&6
+echo "configure:3686: checking size of long" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3694 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(long));
+  exit(0);
+}
+EOF
+if { (eval echo configure:3705: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_long=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_long=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_long" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+EOF
+
+
+
+
+
+echo $ac_n "checking for long file names""... $ac_c" 1>&6
+echo "configure:3728: checking for long file names" >&5
+if eval "test \"`echo '$''{'ac_cv_sys_long_file_names'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_cv_sys_long_file_names=yes
+# Test for long file names in all the places we know might matter:
+#      .		the current directory, where building will happen
+#      $prefix/lib	where we will be installing things
+#      $exec_prefix/lib	likewise
+# eval it to expand exec_prefix.
+#      $TMPDIR		if set, where it might want to write temporary files
+# if $TMPDIR is not set:
+#      /tmp		where it might want to write temporary files
+#      /var/tmp		likewise
+#      /usr/tmp		likewise
+if test -n "$TMPDIR" && test -d "$TMPDIR" && test -w "$TMPDIR"; then
+  ac_tmpdirs="$TMPDIR"
+else
+  ac_tmpdirs='/tmp /var/tmp /usr/tmp'
+fi
+for ac_dir in  . $ac_tmpdirs `eval echo $prefix/lib $exec_prefix/lib` ; do
+  test -d $ac_dir || continue
+  test -w $ac_dir || continue # It is less confusing to not echo anything here.
+  (echo 1 > $ac_dir/conftest9012345) 2>/dev/null
+  (echo 2 > $ac_dir/conftest9012346) 2>/dev/null
+  val=`cat $ac_dir/conftest9012345 2>/dev/null`
+  if test ! -f $ac_dir/conftest9012345 || test "$val" != 1; then
+    ac_cv_sys_long_file_names=no
+    rm -f $ac_dir/conftest9012345 $ac_dir/conftest9012346 2>/dev/null
+    break
+  fi
+  rm -f $ac_dir/conftest9012345 $ac_dir/conftest9012346 2>/dev/null
+done
+fi
+
+echo "$ac_t""$ac_cv_sys_long_file_names" 1>&6
+if test $ac_cv_sys_long_file_names = yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_LONG_FILE_NAMES 1
+EOF
+
+fi
+
+
+                                          
+
+for ac_prog in 'bison -y' byacc
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3779: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$YACC"; then
+  ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_YACC="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+YACC="$ac_cv_prog_YACC"
+if test -n "$YACC"; then
+  echo "$ac_t""$YACC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+
+# Extract the first word of "flex", so it can be a program name with args.
+set dummy flex; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3812: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$LEX"; then
+  ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_LEX="flex"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_LEX" && ac_cv_prog_LEX="lex"
+fi
+fi
+LEX="$ac_cv_prog_LEX"
+if test -n "$LEX"; then
+  echo "$ac_t""$LEX" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$LEXLIB"
+then
+  case "$LEX" in
+  flex*) ac_lib=fl ;;
+  *) ac_lib=l ;;
+  esac
+  echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6
+echo "configure:3845: checking for yywrap in -l$ac_lib" >&5
+ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-l$ac_lib  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3853 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char yywrap();
+
+int main() {
+yywrap()
+; return 0; }
+EOF
+if { (eval echo configure:3864: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  LEXLIB="-l$ac_lib"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking lex output file root""... $ac_c" 1>&6
+echo "configure:3887: checking lex output file root" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_lex_root'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  # The minimal lex program is just a single line: %%.  But some broken lexes
+# (Solaris, I think it was) want two %% lines, so accommodate them.
+echo '%%
+%%' | $LEX
+if test -f lex.yy.c; then
+  ac_cv_prog_lex_root=lex.yy
+elif test -f lexyy.c; then
+  ac_cv_prog_lex_root=lexyy
+else
+  { echo "configure: error: cannot find output from $LEX; giving up" 1>&2; exit 1; }
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_lex_root" 1>&6
+LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root
+
+echo $ac_n "checking whether yytext is a pointer""... $ac_c" 1>&6
+echo "configure:3908: checking whether yytext is a pointer" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_lex_yytext_pointer'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  # POSIX says lex can declare yytext either as a pointer or an array; the
+# default is implementation-dependent. Figure out which it is, since
+# not all implementations provide the %pointer and %array declarations.
+ac_cv_prog_lex_yytext_pointer=no
+echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c
+ac_save_LIBS="$LIBS"
+LIBS="$LIBS $LEXLIB"
+cat > conftest.$ac_ext <<EOF
+#line 3920 "configure"
+#include "confdefs.h"
+`cat $LEX_OUTPUT_ROOT.c`
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:3927: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  ac_cv_prog_lex_yytext_pointer=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+rm -f "${LEX_OUTPUT_ROOT}.c"
+
+fi
+
+echo "$ac_t""$ac_cv_prog_lex_yytext_pointer" 1>&6
+if test $ac_cv_prog_lex_yytext_pointer = yes; then
+  cat >> confdefs.h <<\EOF
+#define YYTEXT_POINTER 1
+EOF
+
+fi
+
+
+
+CHECK_INCLUDE="-I/usr/include $X_CFLAGS"
+CHECK_LIB="-L/lib -L/usr/lib $X_LIBS"
+
+
+
+# Make sure we can run config.sub.
+if $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:3961: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+  case $nonopt in
+  NONE)
+    if host_alias=`$ac_config_guess`; then :
+    else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+    fi ;;
+  *) host_alias=$nonopt ;;
+  esac ;;
+esac
+
+host=`$ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+canonical=$host
+configuration=$host_alias
+
+
+USE_GTK=1
+USE_UNIX=1
+
+TOOLKIT=GTK
+TOOLKIT_DEF=__GTK__
+
+USE_LINUX=
+USE_SGI=
+USE_HPUX=
+USE_SYSV=
+USE_SVR4=
+USE_AIX=
+USE_SUN=
+USE_SOLARIS=
+USE_SUNOS=
+USE_ALPHA=
+USE_OSF=
+USE_BSD=
+USE_FREEBSD=
+USE_VMS=
+USE_ULTRIX=
+USE_DATA_GENERAL=
+
+case "${canonical}" in
+  *-hp-hpux* )
+    USE_HPUX=1
+    cat >> confdefs.h <<\EOF
+#define __HPUX__ 1
+EOF
+
+  ;;
+  *-*-linux* )
+    USE_LINUX=1
+    cat >> confdefs.h <<\EOF
+#define __LINUX__ 1
+EOF
+
+  ;;
+  *-*-irix5* | *-*-irix6* ) 
+    USE_SGI=1
+    USE_SVR4=1
+    cat >> confdefs.h <<\EOF
+#define __SGI__ 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define __SVR4__ 1
+EOF
+
+  ;;
+  *-*-solaris2* ) 
+    USE_SUN=1
+    USE_SOLARIS=1
+    USE_SVR4=1
+    cat >> confdefs.h <<\EOF
+#define __SUN__ 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define __SOLARIS__ 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define __SVR4__ 1
+EOF
+
+  ;;
+  *-*-sunos4* ) 
+    USE_SUN=1
+    USE_SUNOS=1
+    USE_BSD=1
+    cat >> confdefs.h <<\EOF
+#define __SUN__ 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define __SUNOS__ 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define __BSD__ 1
+EOF
+
+  ;;
+  *-*-freebsd* | *-*-netbsd*)
+    USE_BSD=1
+    USE_FREEBSD=1
+    cat >> confdefs.h <<\EOF
+#define __FREEBSD__ 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define __BSD__ 1
+EOF
+
+  ;;
+  *-*-osf* ) 
+    USE_ALPHA=1
+    USE_OSF=1
+    cat >> confdefs.h <<\EOF
+#define __ALPHA__ 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define __OSF__ 1
+EOF
+
+  ;;
+  *-*-dgux5* ) 
+    USE_ALPHA=1
+    USE_SVR4=1
+    cat >> confdefs.h <<\EOF
+#define __ALPHA__ 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define __SVR4__ 1
+EOF
+
+  ;;
+  *-*-sysv5* ) 
+    USE_SYSV=1
+    USE_SVR4=1
+    cat >> confdefs.h <<\EOF
+#define __SYSV__ 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define __SVR4__ 1
+EOF
+
+  ;;
+  *-*-aix* ) 
+    USE_AIX=1
+    USE_SYSV=1
+    USE_SVR4=1
+    cat >> confdefs.h <<\EOF
+#define __AIX__ 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define __SYSV__ 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define __SVR4__ 1
+EOF
+
+  ;;
+  *)
+    { echo "configure: error: I don't know your system type." 1>&2; exit 1; }
+esac
+
+
+
+rm -f ${OSTYPE}.system.cache.tmp
+touch ${OSTYPE}.system.cache.tmp
+touch ${OSTYPE}.system.cache
+
+
+DEFAULT_USE_SHARED=0
+DEFAULT_USE_OPTIMISE=1
+DEFAULT_USE_PROFILE=0
+DEFAULT_USE_DEBUG_FLAG=0
+DEFAULT_USE_DEBUG_INFO=0
+DEFAULT_USE_MEM_TRACING=0
+
+DEFAULT_USE_ZLIB=1
+DEFAULT_USE_GDK_IMLIB=1
+DEFAULT_USE_LIBPNG=1
+
+DEFAULT_USE_STORABLE_CLASSES=1
+DEFAULT_USE_AUTOTRANS=1
+DEFAULT_USE_AFM_FOR_POSTSCRIPT=1
+DEFAULT_WX_NORMALIZED_PS_FONTS=1
+
+DEFAULT_USE_IOSTREAMH=1
+
+DEFAULT_USE_THREADS=0
+DEFAULT_USE_THREADS_SGI=0
+DEFAULT_USE_THREADS_POSIX=0
+DEFAULT_USE_OPENGL=0
+
+DEFAULT_USE_POSTSCRIPT=1
+DEFAULT_USE_IPC=1
+DEFAULT_USE_RESOURCES=1
+DEFAULT_USE_TIMEDATE=1
+DEFAULT_USE_FRACTION=1
+DEFAULT_USE_CONSTRAINTS=1
+DEFAULT_USE_TOOLBAR=1
+DEFAULT_USE_GAUGE=1
+DEFAULT_USE_SCROLLBAR=1
+DEFAULT_USE_DOC_VIEW_ARCHITECTURE=1
+DEFAULT_USE_PRINTING_ARCHITECTURE=1
+
+DEFAULT_USE_METAFILE=0
+DEFAULT_USE_HELP=0
+DEFAULT_USE_CLIPBOARD=0
+DEFAULT_USE_VLBOX=0
+DEFAULT_USE_WXGRAPH=0
+DEFAULT_USE_WXTREE=0
+DEFAULT_USE_ENHANCED_DIALOG=0
+
+DEFAULT_USE_FORM=0
+DEFAULT_USE_PROLOGIO=0
+DEFAULT_USE_RPC=0
+DEFAULT_USE_WX_RESOURCES=1
+
+
+
+echo $ac_n "checking "for shared"""... $ac_c" 1>&6
+echo "configure:4196: checking "for shared"" >&5
+# Check whether --with-shared or --without-shared was given.
+if test "${with_shared+set}" = set; then
+  withval="$with_shared"
+  if test "x$with_shared" = xyes; then
+  ac_cv_use_shared='USE_SHARED="1"'
+else
+  ac_cv_use_shared='USE_SHARED="0"'
+fi
+else
+  
+  LINE=`grep "USE_SHARED" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_shared='USE_SHARED='$DEFAULT_USE_SHARED
+
+fi
+
+eval "$ac_cv_use_shared"
+echo $ac_cv_use_shared >> ${OSTYPE}.system.cache.tmp
+if test "$USE_SHARED" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for optimise"""... $ac_c" 1>&6
+echo "configure:4226: checking "for optimise"" >&5
+# Check whether --with-optimise or --without-optimise was given.
+if test "${with_optimise+set}" = set; then
+  withval="$with_optimise"
+  if test "x$with_optimise" = xyes; then
+  ac_cv_use_optimise='USE_OPTIMISE="1"'
+else
+  ac_cv_use_optimise='USE_OPTIMISE="0"'
+fi
+else
+  
+  LINE=`grep "USE_OPTIMISE" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_optimise='USE_OPTIMISE='$DEFAULT_USE_OPTIMISE
+
+fi
+
+eval "$ac_cv_use_optimise"
+echo $ac_cv_use_optimise >> ${OSTYPE}.system.cache.tmp
+if test "$USE_OPTIMISE" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for debug_flag"""... $ac_c" 1>&6
+echo "configure:4256: checking "for debug_flag"" >&5
+# Check whether --with-debug_flag or --without-debug_flag was given.
+if test "${with_debug_flag+set}" = set; then
+  withval="$with_debug_flag"
+  if test "x$with_debug_flag" = xyes; then
+  ac_cv_use_debug_flag='USE_DEBUG_FLAG="1"'
+else
+  ac_cv_use_debug_flag='USE_DEBUG_FLAG="0"'
+fi
+else
+  
+  LINE=`grep "USE_DEBUG_FLAG" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_debug_flag='USE_DEBUG_FLAG='$DEFAULT_USE_DEBUG_FLAG
+
+fi
+
+eval "$ac_cv_use_debug_flag"
+echo $ac_cv_use_debug_flag >> ${OSTYPE}.system.cache.tmp
+if test "$USE_DEBUG_FLAG" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for debug_info"""... $ac_c" 1>&6
+echo "configure:4286: checking "for debug_info"" >&5
+# Check whether --with-debug_info or --without-debug_info was given.
+if test "${with_debug_info+set}" = set; then
+  withval="$with_debug_info"
+  if test "x$with_debug_info" = xyes; then
+  ac_cv_use_debug_info='USE_DEBUG_INFO="1"'
+else
+  ac_cv_use_debug_info='USE_DEBUG_INFO="0"'
+fi
+else
+  
+  LINE=`grep "USE_DEBUG_INFO" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_debug_info='USE_DEBUG_INFO='$DEFAULT_USE_DEBUG_INFO
+
+fi
+
+eval "$ac_cv_use_debug_info"
+echo $ac_cv_use_debug_info >> ${OSTYPE}.system.cache.tmp
+if test "$USE_DEBUG_INFO" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for mem_tracing"""... $ac_c" 1>&6
+echo "configure:4316: checking "for mem_tracing"" >&5
+# Check whether --with-mem_tracing or --without-mem_tracing was given.
+if test "${with_mem_tracing+set}" = set; then
+  withval="$with_mem_tracing"
+  if test "x$with_mem_tracing" = xyes; then
+  ac_cv_use_mem_tracing='USE_MEM_TRACING="1"'
+else
+  ac_cv_use_mem_tracing='USE_MEM_TRACING="0"'
+fi
+else
+  
+  LINE=`grep "USE_MEM_TRACING" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_mem_tracing='USE_MEM_TRACING='$DEFAULT_USE_MEM_TRACING
+
+fi
+
+eval "$ac_cv_use_mem_tracing"
+echo $ac_cv_use_mem_tracing >> ${OSTYPE}.system.cache.tmp
+if test "$USE_MEM_TRACING" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for profile"""... $ac_c" 1>&6
+echo "configure:4346: checking "for profile"" >&5
+# Check whether --with-profile or --without-profile was given.
+if test "${with_profile+set}" = set; then
+  withval="$with_profile"
+  if test "x$with_profile" = xyes; then
+  ac_cv_use_profile='USE_PROFILE="1"'
+else
+  ac_cv_use_profile='USE_PROFILE="0"'
+fi
+else
+  
+  LINE=`grep "USE_PROFILE" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_profile='USE_PROFILE='$DEFAULT_USE_PROFILE
+
+fi
+
+eval "$ac_cv_use_profile"
+echo $ac_cv_use_profile >> ${OSTYPE}.system.cache.tmp
+if test "$USE_PROFILE" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+
+echo $ac_n "checking "for zlib"""... $ac_c" 1>&6
+echo "configure:4377: checking "for zlib"" >&5
+# Check whether --with-zlib or --without-zlib was given.
+if test "${with_zlib+set}" = set; then
+  withval="$with_zlib"
+  if test "x$with_zlib" = xyes; then
+  ac_cv_use_zlib='USE_ZLIB="1"'
+else
+  ac_cv_use_zlib='USE_ZLIB="0"'
+fi
+else
+  
+  LINE=`grep "USE_ZLIB" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_zlib='USE_ZLIB='$DEFAULT_USE_ZLIB
+
+fi
+
+eval "$ac_cv_use_zlib"
+echo $ac_cv_use_zlib >> ${OSTYPE}.system.cache.tmp
+if test "$USE_ZLIB" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for gdk_imlib"""... $ac_c" 1>&6
+echo "configure:4407: checking "for gdk_imlib"" >&5
+# Check whether --with-gdk_imlib or --without-gdk_imlib was given.
+if test "${with_gdk_imlib+set}" = set; then
+  withval="$with_gdk_imlib"
+  if test "x$with_gdk_imlib" = xyes; then
+  ac_cv_use_gdk_imlib='USE_GDK_IMLIB="1"'
+else
+  ac_cv_use_gdk_imlib='USE_GDK_IMLIB="0"'
+fi
+else
+  
+  LINE=`grep "USE_GDK_IMLIB" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_gdk_imlib='USE_GDK_IMLIB='$DEFAULT_USE_GDK_IMLIB
+
+fi
+
+eval "$ac_cv_use_gdk_imlib"
+echo $ac_cv_use_gdk_imlib >> ${OSTYPE}.system.cache.tmp
+if test "$USE_GDK_IMLIB" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for libpng"""... $ac_c" 1>&6
+echo "configure:4437: checking "for libpng"" >&5
+# Check whether --with-libpng or --without-libpng was given.
+if test "${with_libpng+set}" = set; then
+  withval="$with_libpng"
+  if test "x$with_libpng" = xyes; then
+  ac_cv_use_libpng='USE_LIBPNG="1"'
+else
+  ac_cv_use_libpng='USE_LIBPNG="0"'
+fi
+else
+  
+  LINE=`grep "USE_LIBPNG" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_libpng='USE_LIBPNG='$DEFAULT_USE_LIBPNG
+
+fi
+
+eval "$ac_cv_use_libpng"
+echo $ac_cv_use_libpng >> ${OSTYPE}.system.cache.tmp
+if test "$USE_LIBPNG" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for threads"""... $ac_c" 1>&6
+echo "configure:4467: checking "for threads"" >&5
+# Check whether --with-threads or --without-threads was given.
+if test "${with_threads+set}" = set; then
+  withval="$with_threads"
+  if test "x$with_threads" = xyes; then
+  ac_cv_use_threads='USE_THREADS="1"'
+else
+  ac_cv_use_threads='USE_THREADS="0"'
+fi
+else
+  
+  LINE=`grep "USE_THREADS" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_threads='USE_THREADS='$DEFAULT_USE_THREADS
+
+fi
+
+eval "$ac_cv_use_threads"
+echo $ac_cv_use_threads >> ${OSTYPE}.system.cache.tmp
+if test "$USE_THREADS" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for opengl"""... $ac_c" 1>&6
+echo "configure:4497: checking "for opengl"" >&5
+# Check whether --with-opengl or --without-opengl was given.
+if test "${with_opengl+set}" = set; then
+  withval="$with_opengl"
+  if test "x$with_opengl" = xyes; then
+  ac_cv_use_opengl='USE_OPENGL="1"'
+else
+  ac_cv_use_opengl='USE_OPENGL="0"'
+fi
+else
+  
+  LINE=`grep "USE_OPENGL" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_opengl='USE_OPENGL='$DEFAULT_USE_OPENGL
+
+fi
+
+eval "$ac_cv_use_opengl"
+echo $ac_cv_use_opengl >> ${OSTYPE}.system.cache.tmp
+if test "$USE_OPENGL" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+
+echo $ac_n "checking "for storable"""... $ac_c" 1>&6
+echo "configure:4528: checking "for storable"" >&5
+# Check whether --with-storable or --without-storable was given.
+if test "${with_storable+set}" = set; then
+  withval="$with_storable"
+  if test "x$with_storable" = xyes; then
+  ac_cv_use_storable='USE_STORABLE_CLASSES="1"'
+else
+  ac_cv_use_storable='USE_STORABLE_CLASSES="0"'
+fi
+else
+  
+  LINE=`grep "USE_STORABLE_CLASSES" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_storable='USE_STORABLE_CLASSES='$DEFAULT_USE_STORABLE_CLASSES
+
+fi
+
+eval "$ac_cv_use_storable"
+echo $ac_cv_use_storable >> ${OSTYPE}.system.cache.tmp
+if test "$USE_STORABLE_CLASSES" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for autotrans"""... $ac_c" 1>&6
+echo "configure:4558: checking "for autotrans"" >&5
+# Check whether --with-autotrans or --without-autotrans was given.
+if test "${with_autotrans+set}" = set; then
+  withval="$with_autotrans"
+  if test "x$with_autotrans" = xyes; then
+  ac_cv_use_autotrans='USE_AUTOTRANS="1"'
+else
+  ac_cv_use_autotrans='USE_AUTOTRANS="0"'
+fi
+else
+  
+  LINE=`grep "USE_AUTOTRANS" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_autotrans='USE_AUTOTRANS='$DEFAULT_USE_AUTOTRANS
+
+fi
+
+eval "$ac_cv_use_autotrans"
+echo $ac_cv_use_autotrans >> ${OSTYPE}.system.cache.tmp
+if test "$USE_AUTOTRANS" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for afmfonts"""... $ac_c" 1>&6
+echo "configure:4588: checking "for afmfonts"" >&5
+# Check whether --with-afmfonts or --without-afmfonts was given.
+if test "${with_afmfonts+set}" = set; then
+  withval="$with_afmfonts"
+  if test "x$with_afmfonts" = xyes; then
+  ac_cv_use_afmfonts='USE_AFM_FOR_POSTSCRIPT="1"'
+else
+  ac_cv_use_afmfonts='USE_AFM_FOR_POSTSCRIPT="0"'
+fi
+else
+  
+  LINE=`grep "USE_AFM_FOR_POSTSCRIPT" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_afmfonts='USE_AFM_FOR_POSTSCRIPT='$DEFAULT_USE_AFM_FOR_POSTSCRIPT
+
+fi
+
+eval "$ac_cv_use_afmfonts"
+echo $ac_cv_use_afmfonts >> ${OSTYPE}.system.cache.tmp
+if test "$USE_AFM_FOR_POSTSCRIPT" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for normalized"""... $ac_c" 1>&6
+echo "configure:4618: checking "for normalized"" >&5
+# Check whether --with-normalized or --without-normalized was given.
+if test "${with_normalized+set}" = set; then
+  withval="$with_normalized"
+  if test "x$with_normalized" = xyes; then
+  ac_cv_use_normalized='WX_NORMALIZED_PS_FONTS="1"'
+else
+  ac_cv_use_normalized='WX_NORMALIZED_PS_FONTS="0"'
+fi
+else
+  
+  LINE=`grep "WX_NORMALIZED_PS_FONTS" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_normalized='WX_NORMALIZED_PS_FONTS='$DEFAULT_WX_NORMALIZED_PS_FONTS
+
+fi
+
+eval "$ac_cv_use_normalized"
+echo $ac_cv_use_normalized >> ${OSTYPE}.system.cache.tmp
+if test "$WX_NORMALIZED_PS_FONTS" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for RPC"""... $ac_c" 1>&6
+echo "configure:4648: checking "for RPC"" >&5
+# Check whether --with-rpc or --without-rpc was given.
+if test "${with_rpc+set}" = set; then
+  withval="$with_rpc"
+  if test "x$with_rpc" = xyes; then
+  ac_cv_use_rpc='USE_RPC="1"'
+else
+  ac_cv_use_rpc='USE_RPC="0"'
+fi
+else
+  
+  LINE=`grep "USE_RPC" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_rpc='USE_RPC='$DEFAULT_USE_RPC
+
+fi
+
+eval "$ac_cv_use_rpc"
+echo $ac_cv_use_rpc >> ${OSTYPE}.system.cache.tmp
+if test "$USE_RPC" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for wxresources"""... $ac_c" 1>&6
+echo "configure:4678: checking "for wxresources"" >&5
+# Check whether --with-wxresources or --without-wxresources was given.
+if test "${with_wxresources+set}" = set; then
+  withval="$with_wxresources"
+  if test "x$with_wxresources" = xyes; then
+  ac_cv_use_wxresources='USE_WX_RESOURCES="1"'
+else
+  ac_cv_use_wxresources='USE_WX_RESOURCES="0"'
+fi
+else
+  
+  LINE=`grep "USE_WX_RESOURCES" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_wxresources='USE_WX_RESOURCES='$DEFAULT_USE_WX_RESOURCES
+
+fi
+
+eval "$ac_cv_use_wxresources"
+echo $ac_cv_use_wxresources >> ${OSTYPE}.system.cache.tmp
+if test "$USE_WX_RESOURCES" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for prologio"""... $ac_c" 1>&6
+echo "configure:4708: checking "for prologio"" >&5
+# Check whether --with-prologio or --without-prologio was given.
+if test "${with_prologio+set}" = set; then
+  withval="$with_prologio"
+  if test "x$with_prologio" = xyes; then
+  ac_cv_use_prologio='USE_PROLOGIO="1"'
+else
+  ac_cv_use_prologio='USE_PROLOGIO="0"'
+fi
+else
+  
+  LINE=`grep "USE_PROLOGIO" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_prologio='USE_PROLOGIO='$DEFAULT_USE_PROLOGIO
+
+fi
+
+eval "$ac_cv_use_prologio"
+echo $ac_cv_use_prologio >> ${OSTYPE}.system.cache.tmp
+if test "$USE_PROLOGIO" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for postscript"""... $ac_c" 1>&6
+echo "configure:4738: checking "for postscript"" >&5
+# Check whether --with-postscript or --without-postscript was given.
+if test "${with_postscript+set}" = set; then
+  withval="$with_postscript"
+  if test "x$with_postscript" = xyes; then
+  ac_cv_use_postscript='USE_POSTSCRIPT="1"'
+else
+  ac_cv_use_postscript='USE_POSTSCRIPT="0"'
+fi
+else
+  
+  LINE=`grep "USE_POSTSCRIPT" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_postscript='USE_POSTSCRIPT='$DEFAULT_USE_POSTSCRIPT
+
+fi
+
+eval "$ac_cv_use_postscript"
+echo $ac_cv_use_postscript >> ${OSTYPE}.system.cache.tmp
+if test "$USE_POSTSCRIPT" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for metafile"""... $ac_c" 1>&6
+echo "configure:4768: checking "for metafile"" >&5
+# Check whether --with-metafile or --without-metafile was given.
+if test "${with_metafile+set}" = set; then
+  withval="$with_metafile"
+  if test "x$with_metafile" = xyes; then
+  ac_cv_use_metafile='USE_METAFILE="1"'
+else
+  ac_cv_use_metafile='USE_METAFILE="0"'
+fi
+else
+  
+  LINE=`grep "USE_METAFILE" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_metafile='USE_METAFILE='$DEFAULT_USE_METAFILE
+
+fi
+
+eval "$ac_cv_use_metafile"
+echo $ac_cv_use_metafile >> ${OSTYPE}.system.cache.tmp
+if test "$USE_METAFILE" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for form"""... $ac_c" 1>&6
+echo "configure:4798: checking "for form"" >&5
+# Check whether --with-form or --without-form was given.
+if test "${with_form+set}" = set; then
+  withval="$with_form"
+  if test "x$with_form" = xyes; then
+  ac_cv_use_form='USE_FORM="1"'
+else
+  ac_cv_use_form='USE_FORM="0"'
+fi
+else
+  
+  LINE=`grep "USE_FORM" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_form='USE_FORM='$DEFAULT_USE_FORM
+
+fi
+
+eval "$ac_cv_use_form"
+echo $ac_cv_use_form >> ${OSTYPE}.system.cache.tmp
+if test "$USE_FORM" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for help"""... $ac_c" 1>&6
+echo "configure:4828: checking "for help"" >&5
+# Check whether --with-help or --without-help was given.
+if test "${with_help+set}" = set; then
+  withval="$with_help"
+  if test "x$with_help" = xyes; then
+  ac_cv_use_help='USE_HELP="1"'
+else
+  ac_cv_use_help='USE_HELP="0"'
+fi
+else
+  
+  LINE=`grep "USE_HELP" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_help='USE_HELP='$DEFAULT_USE_HELP
+
+fi
+
+eval "$ac_cv_use_help"
+echo $ac_cv_use_help >> ${OSTYPE}.system.cache.tmp
+if test "$USE_HELP" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for IPC"""... $ac_c" 1>&6
+echo "configure:4858: checking "for IPC"" >&5
+# Check whether --with-ipc or --without-ipc was given.
+if test "${with_ipc+set}" = set; then
+  withval="$with_ipc"
+  if test "x$with_ipc" = xyes; then
+  ac_cv_use_ipc='USE_IPC="1"'
+else
+  ac_cv_use_ipc='USE_IPC="0"'
+fi
+else
+  
+  LINE=`grep "USE_IPC" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_ipc='USE_IPC='$DEFAULT_USE_IPC
+
+fi
+
+eval "$ac_cv_use_ipc"
+echo $ac_cv_use_ipc >> ${OSTYPE}.system.cache.tmp
+if test "$USE_IPC" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for enhanced dialog"""... $ac_c" 1>&6
+echo "configure:4888: checking "for enhanced dialog"" >&5
+# Check whether --with-enhanceddialog or --without-enhanceddialog was given.
+if test "${with_enhanceddialog+set}" = set; then
+  withval="$with_enhanceddialog"
+  if test "x$with_enhanceddialog" = xyes; then
+  ac_cv_use_enhanceddialog='USE_ENHANCED_DIALOG="1"'
+else
+  ac_cv_use_enhanceddialog='USE_ENHANCED_DIALOG="0"'
+fi
+else
+  
+  LINE=`grep "USE_ENHANCED_DIALOG" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_enhanceddialog='USE_ENHANCED_DIALOG='$DEFAULT_USE_ENHANCED_DIALOG
+
+fi
+
+eval "$ac_cv_use_enhanceddialog"
+echo $ac_cv_use_enhanceddialog >> ${OSTYPE}.system.cache.tmp
+if test "$USE_ENHANCED_DIALOG" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for resources"""... $ac_c" 1>&6
+echo "configure:4918: checking "for resources"" >&5
+# Check whether --with-resources or --without-resources was given.
+if test "${with_resources+set}" = set; then
+  withval="$with_resources"
+  if test "x$with_resources" = xyes; then
+  ac_cv_use_resources='USE_RESOURCES="1"'
+else
+  ac_cv_use_resources='USE_RESOURCES="0"'
+fi
+else
+  
+  LINE=`grep "USE_RESOURCES" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_resources='USE_RESOURCES='$DEFAULT_USE_RESOURCES
+
+fi
+
+eval "$ac_cv_use_resources"
+echo $ac_cv_use_resources >> ${OSTYPE}.system.cache.tmp
+if test "$USE_RESOURCES" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for clipboard"""... $ac_c" 1>&6
+echo "configure:4948: checking "for clipboard"" >&5
+# Check whether --with-clipboard or --without-clipboard was given.
+if test "${with_clipboard+set}" = set; then
+  withval="$with_clipboard"
+  if test "x$with_clipboard" = xyes; then
+  ac_cv_use_clipboard='USE_CLIPBOARD="1"'
+else
+  ac_cv_use_clipboard='USE_CLIPBOARD="0"'
+fi
+else
+  
+  LINE=`grep "USE_CLIPBOARD" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_clipboard='USE_CLIPBOARD='$DEFAULT_USE_CLIPBOARD
+
+fi
+
+eval "$ac_cv_use_clipboard"
+echo $ac_cv_use_clipboard >> ${OSTYPE}.system.cache.tmp
+if test "$USE_CLIPBOARD" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for timedate"""... $ac_c" 1>&6
+echo "configure:4978: checking "for timedate"" >&5
+# Check whether --with-timedate or --without-timedate was given.
+if test "${with_timedate+set}" = set; then
+  withval="$with_timedate"
+  if test "x$with_timedate" = xyes; then
+  ac_cv_use_timedate='USE_TIMEDATE="1"'
+else
+  ac_cv_use_timedate='USE_TIMEDATE="0"'
+fi
+else
+  
+  LINE=`grep "USE_TIMEDATE" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_timedate='USE_TIMEDATE='$DEFAULT_USE_TIMEDATE
+
+fi
+
+eval "$ac_cv_use_timedate"
+echo $ac_cv_use_timedate >> ${OSTYPE}.system.cache.tmp
+if test "$USE_TIMEDATE" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for fraction"""... $ac_c" 1>&6
+echo "configure:5008: checking "for fraction"" >&5
+# Check whether --with-fraction or --without-fraction was given.
+if test "${with_fraction+set}" = set; then
+  withval="$with_fraction"
+  if test "x$with_fraction" = xyes; then
+  ac_cv_use_fraction='USE_FRACTION="1"'
+else
+  ac_cv_use_fraction='USE_FRACTION="0"'
+fi
+else
+  
+  LINE=`grep "USE_FRACTION" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_fraction='USE_FRACTION='$DEFAULT_USE_FRACTION
+
+fi
+
+eval "$ac_cv_use_fraction"
+echo $ac_cv_use_fraction >> ${OSTYPE}.system.cache.tmp
+if test "$USE_FRACTION" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for constrains"""... $ac_c" 1>&6
+echo "configure:5038: checking "for constrains"" >&5
+# Check whether --with-constraints or --without-constraints was given.
+if test "${with_constraints+set}" = set; then
+  withval="$with_constraints"
+  if test "x$with_constraints" = xyes; then
+  ac_cv_use_constraints='USE_CONSTRAINTS="1"'
+else
+  ac_cv_use_constraints='USE_CONSTRAINTS="0"'
+fi
+else
+  
+  LINE=`grep "USE_CONSTRAINTS" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_constraints='USE_CONSTRAINTS='$DEFAULT_USE_CONSTRAINTS
+
+fi
+
+eval "$ac_cv_use_constraints"
+echo $ac_cv_use_constraints >> ${OSTYPE}.system.cache.tmp
+if test "$USE_CONSTRAINTS" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for toolbar"""... $ac_c" 1>&6
+echo "configure:5068: checking "for toolbar"" >&5
+# Check whether --with-toolbar or --without-toolbar was given.
+if test "${with_toolbar+set}" = set; then
+  withval="$with_toolbar"
+  if test "x$with_toolbar" = xyes; then
+  ac_cv_use_toolbar='USE_TOOLBAR="1"'
+else
+  ac_cv_use_toolbar='USE_TOOLBAR="0"'
+fi
+else
+  
+  LINE=`grep "USE_TOOLBAR" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_toolbar='USE_TOOLBAR='$DEFAULT_USE_TOOLBAR
+
+fi
+
+eval "$ac_cv_use_toolbar"
+echo $ac_cv_use_toolbar >> ${OSTYPE}.system.cache.tmp
+if test "$USE_TOOLBAR" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for gauge"""... $ac_c" 1>&6
+echo "configure:5098: checking "for gauge"" >&5
+# Check whether --with-gauge or --without-gauge was given.
+if test "${with_gauge+set}" = set; then
+  withval="$with_gauge"
+  if test "x$with_gauge" = xyes; then
+  ac_cv_use_gauge='USE_GAUGE="1"'
+else
+  ac_cv_use_gauge='USE_GAUGE="0"'
+fi
+else
+  
+  LINE=`grep "USE_GAUGE" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_gauge='USE_GAUGE='$DEFAULT_USE_GAUGE
+
+fi
+
+eval "$ac_cv_use_gauge"
+echo $ac_cv_use_gauge >> ${OSTYPE}.system.cache.tmp
+if test "$USE_GAUGE" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for vllist"""... $ac_c" 1>&6
+echo "configure:5128: checking "for vllist"" >&5
+# Check whether --with-vllist or --without-vllist was given.
+if test "${with_vllist+set}" = set; then
+  withval="$with_vllist"
+  if test "x$with_vllist" = xyes; then
+  ac_cv_use_vllist='USE_VLBOX="1"'
+else
+  ac_cv_use_vllist='USE_VLBOX="0"'
+fi
+else
+  
+  LINE=`grep "USE_VLBOX" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_vllist='USE_VLBOX='$DEFAULT_USE_VLBOX
+
+fi
+
+eval "$ac_cv_use_vllist"
+echo $ac_cv_use_vllist >> ${OSTYPE}.system.cache.tmp
+if test "$USE_VLBOX" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for scrollbar"""... $ac_c" 1>&6
+echo "configure:5158: checking "for scrollbar"" >&5
+# Check whether --with-scrollbar or --without-scrollbar was given.
+if test "${with_scrollbar+set}" = set; then
+  withval="$with_scrollbar"
+  if test "x$with_scrollbar" = xyes; then
+  ac_cv_use_scrollbar='USE_SCROLLBAR="1"'
+else
+  ac_cv_use_scrollbar='USE_SCROLLBAR="0"'
+fi
+else
+  
+  LINE=`grep "USE_SCROLLBAR" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_scrollbar='USE_SCROLLBAR='$DEFAULT_USE_SCROLLBAR
+
+fi
+
+eval "$ac_cv_use_scrollbar"
+echo $ac_cv_use_scrollbar >> ${OSTYPE}.system.cache.tmp
+if test "$USE_SCROLLBAR" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for docview"""... $ac_c" 1>&6
+echo "configure:5188: checking "for docview"" >&5
+# Check whether --with-docview or --without-docview was given.
+if test "${with_docview+set}" = set; then
+  withval="$with_docview"
+  if test "x$with_docview" = xyes; then
+  ac_cv_use_docview='USE_DOC_VIEW_ARCHITECTURE="1"'
+else
+  ac_cv_use_docview='USE_DOC_VIEW_ARCHITECTURE="0"'
+fi
+else
+  
+  LINE=`grep "USE_DOC_VIEW_ARCHITECTURE" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_docview='USE_DOC_VIEW_ARCHITECTURE='$DEFAULT_USE_DOC_VIEW_ARCHITECTURE
+
+fi
+
+eval "$ac_cv_use_docview"
+echo $ac_cv_use_docview >> ${OSTYPE}.system.cache.tmp
+if test "$USE_DOC_VIEW_ARCHITECTURE" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for printarch"""... $ac_c" 1>&6
+echo "configure:5218: checking "for printarch"" >&5
+# Check whether --with-printarch or --without-printarch was given.
+if test "${with_printarch+set}" = set; then
+  withval="$with_printarch"
+  if test "x$with_printarch" = xyes; then
+  ac_cv_use_printarch='USE_PRINTING_ARCHITECTURE="1"'
+else
+  ac_cv_use_printarch='USE_PRINTING_ARCHITECTURE="0"'
+fi
+else
+  
+  LINE=`grep "USE_PRINTING_ARCHITECTURE" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_printarch='USE_PRINTING_ARCHITECTURE='$DEFAULT_USE_PRINTING_ARCHITECTURE
+
+fi
+
+eval "$ac_cv_use_printarch"
+echo $ac_cv_use_printarch >> ${OSTYPE}.system.cache.tmp
+if test "$USE_PRINTING_ARCHITECTURE" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for typetree"""... $ac_c" 1>&6
+echo "configure:5248: checking "for typetree"" >&5
+# Check whether --with-typetree or --without-typetree was given.
+if test "${with_typetree+set}" = set; then
+  withval="$with_typetree"
+  if test "x$with_typetree" = xyes; then
+  ac_cv_use_typetree='USE_TYPETREE="1"'
+else
+  ac_cv_use_typetree='USE_TYPETREE="0"'
+fi
+else
+  
+  LINE=`grep "USE_TYPETREE" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_typetree='USE_TYPETREE='$DEFAULT_USE_TYPETREE
+
+fi
+
+eval "$ac_cv_use_typetree"
+echo $ac_cv_use_typetree >> ${OSTYPE}.system.cache.tmp
+if test "$USE_TYPETREE" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for wxgraph"""... $ac_c" 1>&6
+echo "configure:5278: checking "for wxgraph"" >&5
+# Check whether --with-wxgraph or --without-wxgraph was given.
+if test "${with_wxgraph+set}" = set; then
+  withval="$with_wxgraph"
+  if test "x$with_wxgraph" = xyes; then
+  ac_cv_use_wxgraph='USE_WXGRAPH="1"'
+else
+  ac_cv_use_wxgraph='USE_WXGRAPH="0"'
+fi
+else
+  
+  LINE=`grep "USE_WXGRAPH" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_wxgraph='USE_WXGRAPH='$DEFAULT_USE_WXGRAPH
+
+fi
+
+eval "$ac_cv_use_wxgraph"
+echo $ac_cv_use_wxgraph >> ${OSTYPE}.system.cache.tmp
+if test "$USE_WXGRAPH" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking "for wxtree"""... $ac_c" 1>&6
+echo "configure:5308: checking "for wxtree"" >&5
+# Check whether --with-wxtree or --without-wxtree was given.
+if test "${with_wxtree+set}" = set; then
+  withval="$with_wxtree"
+  if test "x$with_wxtree" = xyes; then
+  ac_cv_use_wxtree='USE_WXTREE="1"'
+else
+  ac_cv_use_wxtree='USE_WXTREE="0"'
+fi
+else
+  
+  LINE=`grep "USE_WXTREE" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_wxtree='USE_WXTREE='$DEFAULT_USE_WXTREE
+
+fi
+
+eval "$ac_cv_use_wxtree"
+echo $ac_cv_use_wxtree >> ${OSTYPE}.system.cache.tmp
+if test "$USE_WXTREE" = 1; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+
+ZLIB=NONE
+if test "$USE_ZLIB" = 1 ; then
+  ZLIB="ZLIB"
+fi
+
+GDK_IMLIB=NONE
+if test "$USE_GDK_IMLIB" = 1 ; then
+  GDK_IMLIB="GDK_IMLIB"
+fi
+
+LIBPNG=NONE
+if test "$USE_LIBPNG" = 1 ; then
+  LIBPNG="LIBPNG"
+fi
+
+THREADS=NONE
+THREADS_LINK=
+if test "$USE_THREADS" = 1 ; then
+  case "$OS" in iris | IRIX | Irix5 | Irix6)
+    USE_THREADS_POSIX=0
+    USE_THREADS_SGI=1
+  ;;
+  *)
+    USE_THREADS_POSIX=1
+    USE_THREADS_SGI=0
+    THREADS_LINK=-lpthread
+  ;;
+  esac
+  THREADS="THREADS"
+  cat >> confdefs.h <<EOF
+#define USE_THREADS $USE_THREADS
+EOF
+
+  cat >> confdefs.h <<EOF
+#define USE_THREADS_SGI $USE_THREADS_SGI
+EOF
+
+  cat >> confdefs.h <<EOF
+#define USE_THREADS_POSIX $USE_THREADS_POSIX
+EOF
+
+fi
+
+
+
+STORABLE=NONE
+if test "$USE_STORABLE_CLASSES" = 1 ; then
+  STORABLE="STORABLE"
+  cat >> confdefs.h <<EOF
+#define USE_STORABLE_CLASSES $USE_STORABLE_CLASSES
+EOF
+
+fi
+
+AUTOTRANS=NONE
+if test "$USE_AUTOTRANS" = 1 ; then
+  AUTOTRANS="AUTOTRANS"
+  cat >> confdefs.h <<EOF
+#define USE_AUTOTRANS $USE_AUTOTRANS
+EOF
+
+fi
+
+DEBUG=
+if test "$USE_DEBUG_INFO" = 1 ; then
+  DEBUG="-g"
+fi
+
+
+if test "$USE_DEBUG_FLAG" = 1 ; then
+  cat >> confdefs.h <<EOF
+#define DEBUG $USE_DEBUG_FLAG
+EOF
+
+fi
+
+if test "$USE_MEM_TRACING" = 1 ; then
+  cat >> confdefs.h <<EOF
+#define USE_MEMORY_TRACING $USE_MEM_TRACING
+EOF
+
+  cat >> confdefs.h <<EOF
+#define USE_GLOBAL_MEMORY_OPERATORS $USE_MEM_TRACING
+EOF
+
+fi
+
+PROFILE=
+if test "$USE_PROFILE" = 1 ; then
+  PROFILE="-pg"
+fi
+
+
+CXXFLAGS=`echo "${CXXFLAGS}" | sed "s/\-O.//g" `
+CFLAGS=`echo "${CFLAGS}" | sed "s/\-O.//g" `
+if test "$USE_OPTIMISE" = 0 ; then
+  OPTIMISE=
+else
+  if test "$GCC" = yes ; then
+    OPTIMISE="-O2"
+    case "${canonical}" in
+      i586-*-*|i686-*-* )
+	OPTIMISE="${OPTIMISE} "
+	;;
+    esac
+  else
+    OPTIMISE="-O"
+  fi
+fi
+
+
+USE_IOSTREAMH=$DEFAULT_USE_IOSTREAMH
+cat >> confdefs.h <<EOF
+#define USE_IOSTREAMH $USE_IOSTREAMH
+EOF
+
+
+RPC=NONE
+if test "$USE_RPC" = 1 ; then
+  RPC="RPC"
+  cat >> confdefs.h <<EOF
+#define USE_RPC $USE_RPC
+EOF
+
+fi
+
+
+WXRESOURCES=NONE
+if test "$USE_WX_RESOURCES" = 1 ; then
+  WXRESOURCES="WXRESOURCES"
+  cat >> confdefs.h <<EOF
+#define USE_WX_RESOURCES $USE_WX_RESOURCES
+EOF
+
+fi
+
+
+PROLOGIO=NONE
+PROLOGIOSRC=NONE
+if test "$USE_PROLOGIO" = 1 ; then
+  PROLOGIO="PROLOGIO"
+  PROLOGIOSRC="PROLOGIOSRC"
+  cat >> confdefs.h <<EOF
+#define USE_PROLOGIO 1
+EOF
+
+fi
+
+
+
+POSTSCRIPTDC=NONE
+if test "$USE_POSTSCRIPT" = 1 ; then
+  POSTSCRIPTDC="POSTSCRIPTDC"
+  cat >> confdefs.h <<EOF
+#define USE_POSTSCRIPT 1
+EOF
+
+fi
+
+
+METAFILE=NONE
+if test "$USE_METAFILE" = 1 ; then
+  METAFILE="METAFILE"
+  cat >> confdefs.h <<EOF
+#define USE_METAFILE $USE_METAFILE
+EOF
+
+fi
+
+
+FORM=NONE
+if test "$USE_FORM" = 1 ; then
+  FORM="FORM"
+  cat >> confdefs.h <<EOF
+#define USE_FORM $USE_FORM
+EOF
+
+fi
+
+
+HELP=NONE
+if test "$USE_HELP" = 1 ; then
+  HELP="HELP"
+  cat >> confdefs.h <<EOF
+#define USE_HELP $USE_HELP
+EOF
+
+fi
+
+
+IPC=NONE
+if test "$USE_IPC" = 1 ; then
+  IPC="IPC"
+  cat >> confdefs.h <<EOF
+#define USE_IPC 1
+EOF
+
+fi
+
+
+ENHDIALOGBOX=NONE
+if test "$USE_ENHANCED_DIALOG" = 1 ; then
+  ENHDIALOGBOX="ENHDIALOGBOX"
+  cat >> confdefs.h <<EOF
+#define USE_ENHANCED_DIALOG $USE_ENHANCED_DIALOG
+EOF
+
+fi
+
+
+XRESOURCES=NONE
+if test "$USE_RESOURCES" = 1 ; then
+  XRESOURCES="XRESOURCES"
+  cat >> confdefs.h <<EOF
+#define USE_RESOURCES $USE_RESOURCES
+EOF
+
+fi
+
+
+CLIPBOARD=NONE
+if test "$USE_CLIPBOARD" = 1 ; then
+  CLIPBOARD="CLIPBOARD"
+  cat >> confdefs.h <<EOF
+#define USE_CLIPBOARD $USE_CLIPBOARD
+EOF
+
+fi
+
+
+CONSTRAINTS=NONE
+if test "$USE_CONSTRAINTS" = 1 ; then
+  CONSTRAINTS="CONSTRAINTS"
+  cat >> confdefs.h <<EOF
+#define USE_CONSTRAINTS $USE_CONSTRAINTS
+EOF
+
+fi
+
+
+TIMEDATE=NONE
+if test "$USE_TIMEDATE" = 1 ; then
+  TIMEDATE="TIMEDATE"
+  cat >> confdefs.h <<EOF
+#define USE_TIMEDATE $USE_TIMEDATE
+EOF
+
+fi
+
+
+FRACTION=NONE
+if test "$USE_FRACTION" = 1 ; then
+  FRACTION="FRACTION"
+  cat >> confdefs.h <<EOF
+#define USE_FRACTION $USE_FRACTION
+EOF
+
+fi
+
+
+TOOLBAR=NONE
+if test "$USE_TOOLBAR" = 1 ; then
+  TOOLBAR="TOOLBAR"
+  cat >> confdefs.h <<EOF
+#define USE_TOOLBAR $USE_TOOLBAR
+EOF
+
+  cat >> confdefs.h <<EOF
+#define USE_XT_TOOLBAR $USE_XT_TOOLBAR
+EOF
+
+fi
+
+
+GAUGE=NONE
+if test "$USE_GAUGE" = 1 ; then
+  GAUGE="GAUGE"
+  
+  cat >> confdefs.h <<EOF
+#define USE_GAUGE $USE_GAUGE
+EOF
+
+fi
+
+VIRLISTBOX=NONE
+if test "$USE_VLBOX" = 1 ; then
+  VIRTLISTBOX="VIRLISTBOX"
+  cat >> confdefs.h <<EOF
+#define USE_VIRLISTBOX $USE_VIRLISTBOX
+EOF
+
+fi
+
+
+SCROLLBAR=NONE
+if test "$USE_SCROLLBAR" = 1 ; then
+  SCROLLBAR="SCROLLBAR"
+  cat >> confdefs.h <<EOF
+#define USE_SCROLLBAR $USE_SCROLLBAR
+EOF
+
+fi
+
+
+DOCVIEW=NONE
+if test "$USE_DOC_VIEW_ARCHITECTURE" = 1 ; then
+  DOCVIEW="DOCVIEW"
+  cat >> confdefs.h <<EOF
+#define USE_DOC_VIEW_ARCHITECTURE $USE_DOC_VIEW_ARCHITECTURE
+EOF
+
+fi
+
+
+PRINTPREVIEW=NONE
+if test "$USE_PRINTING_ARCHITECTURE" = 1 ; then
+  PRINTPREVIEW="PRINTPREVIEW"
+  cat >> confdefs.h <<EOF
+#define USE_PRINTING_ARCHITECTURE $USE_PRINTING_ARCHITECTURE
+EOF
+
+fi
+
+
+TYPETREE=NONE
+if test "$USE_TYPETREE" = 1 ; then
+  TYPETREE="TYPETREE"
+  cat >> confdefs.h <<EOF
+#define USE_TYPETREE $USE_TYPETREE
+EOF
+
+fi
+
+
+WXGRAPH=NONE
+if test "$USE_WXGRAPH" = 1 ; then
+  WXGRAPH="WXGRAPH"
+  cat >> confdefs.h <<EOF
+#define USE_WXGRAPH $USE_WXGRAPH
+EOF
+
+fi
+
+
+WXTREE=NONE
+if test "$USE_WXTREE" = 1 ; then
+  WXTREE="WXTREE"
+  cat >> confdefs.h <<EOF
+#define USE_WXTREE $USE_WXTREE
+EOF
+
+fi
+
+
+GLCANVAS=NONE
+if test "$USE_OPENGL" = 1 ; then
+  GLCANVAS="GLCANVAS"
+fi
+
+cat >> confdefs.h <<EOF
+#define USE_AFM_FOR_POSTSCRIPT $USE_AFM_FOR_POSTSCRIPT
+EOF
+
+
+cat >> confdefs.h <<EOF
+#define WX_NORMALIZED_PS_FONTS $WX_NORMALIZED_PS_FONTS
+EOF
+
+
+
+if test "$USE_UNIX" = 1 ; then
+  cat >> confdefs.h <<\EOF
+#define __UNIX__ 1
+EOF
+
+fi
+
+
+GUI_TK_INCLUDE=
+GUI_TK_LIBRARY=
+GUI_TK_LINK=
+
+if test "$USE_GTK" = 1; then
+  # Check whether --with-gtk-prefix or --without-gtk-prefix was given.
+if test "${with_gtk_prefix+set}" = set; then
+  withval="$with_gtk_prefix"
+  gtk_config_prefix="$withval"
+else
+  gtk_config_prefix=""
+fi
+
+# Check whether --with-gtk-exec-prefix or --without-gtk-exec-prefix was given.
+if test "${with_gtk_exec_prefix+set}" = set; then
+  withval="$with_gtk_exec_prefix"
+  gtk_config_exec_prefix="$withval"
+else
+  gtk_config_exec_prefix=""
+fi
+
+
+  if test x$gtk_config_exec_prefix != x ; then
+     gtk_config_args="$gtk_config_args --exec-prefix=$gtk_config_exec_prefix"
+     if test x${GTK_CONFIG+set} != xset ; then
+        GTK_CONFIG=$gtk_config_exec_prefix/bin/gtk-config
+     fi
+  fi
+  if test x$gtk_config_prefix != x ; then
+     gtk_config_args="$gtk_config_args --prefix=$gtk_config_prefix"
+     if test x${GTK_CONFIG+set} != xset ; then
+        GTK_CONFIG=$gtk_config_prefix/bin/gtk-config
+     fi
+  fi
+
+  # Extract the first word of "gtk-config", so it can be a program name with args.
+set dummy gtk-config; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:5754: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GTK_CONFIG'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$GTK_CONFIG" in
+  /*)
+  ac_cv_path_GTK_CONFIG="$GTK_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_GTK_CONFIG="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_GTK_CONFIG" && ac_cv_path_GTK_CONFIG="no"
+  ;;
+esac
+fi
+GTK_CONFIG="$ac_cv_path_GTK_CONFIG"
+if test -n "$GTK_CONFIG"; then
+  echo "$ac_t""$GTK_CONFIG" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  min_gtk_version=0.99.7
+  echo $ac_n "checking for GTK - version >= $min_gtk_version""... $ac_c" 1>&6
+echo "configure:5785: checking for GTK - version >= $min_gtk_version" >&5
+  no_gtk=""
+  if test "$GTK_CONFIG" != "no" ; then
+    GTK_CFLAGS=`$GTK_CONFIG --cflags`
+    GTK_LIBS=`$GTK_CONFIG --libs`
+    ac_save_CFLAGS="$CFLAGS"
+    ac_save_LIBS="$LIBS"
+    CFLAGS="$CFLAGS $GTK_CFLAGS"
+    LIBS="$LIBS $GTK_LIBS"
+    if test "$cross_compiling" = yes; then
+  echo $ac_n "cross compiling; assumed OK... $ac_c"
+else
+  cat > conftest.$ac_ext <<EOF
+#line 5798 "configure"
+#include "confdefs.h"
+
+#include <gtk/gtk.h>
+#include <stdio.h>
+
+int 
+main ()
+{
+  int major, minor, micro;
+
+  if (sscanf("$min_gtk_version", "%d.%d.%d", &major, &minor, &micro) != 3) {
+     printf("%s, bad version string\n", "$min_gtk_version");
+     exit(1);
+   }
+
+   return !((gtk_major_version > major) ||
+   	    ((gtk_major_version == major) && (gtk_minor_version > minor)) ||
+ 	    ((gtk_major_version == major) && (gtk_minor_version == minor) && (gtk_micro_version >= micro)));
+}
+
+EOF
+if { (eval echo configure:5820: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  :
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  no_gtk=yes
+fi
+rm -fr conftest*
+fi
+
+     CFLAGS="$ac_save_CFLAGS"
+     LIBS="$ac_save_LIBS"
+  else
+     no_gtk=yes
+  fi
+  if test "x$no_gtk" = x ; then
+     echo "$ac_t""yes" 1>&6
+     
+       GUI_TK_INCLUDE="$GTK_CFLAGS"
+       GUI_TK_LIBRARY="$GTK_LIBS"
+       
+  else
+     echo "$ac_t""no" 1>&6
+     GTK_CFLAGS=""
+     GTK_LIBS=""
+     { echo "configure: error: Are gtk-config and the GTK in path and up-to-date?" 1>&2; exit 1; }
+  fi
+  
+  
+
+  cat >> confdefs.h <<\EOF
+#define __GTK__ 1
+EOF
+
+fi
+
+
+
+
+
+
+
+
+OPENGL_INCLUDE=
+OPENGL_LIBRARY=
+OPENGL_LINK=
+
+if test "$USE_OPENGL" = 1; then
+    echo $ac_n "checking for OpenGL includes""... $ac_c" 1>&6
+echo "configure:5871: checking for OpenGL includes" >&5
+  
+ac_find_includes=
+for ac_dir in $SEARCH_INCLUDE;
+  do
+    if test -f "$ac_dir/GL/gl.h"; then
+      ac_find_includes=$ac_dir
+      break
+    fi
+  done
+
+  if test "$ac_find_includes" != "" ; then
+    OPENGL_INCLUDE="-I$ac_find_includes"
+    echo "$ac_t""found $ac_find_includes" 1>&6
+        echo $ac_n "checking for OpenGL library""... $ac_c" 1>&6
+echo "configure:5886: checking for OpenGL library" >&5
+    
+ac_find_libraries=
+for ac_dir in $SEARCH_LIB;
+  do
+    for ac_extension in a so sl; do
+      if test -f "$ac_dir/libGL.$ac_extension"; then
+        ac_find_libraries=$ac_dir
+        break 2
+      fi
+    done
+  done
+
+    if test "$ac_find_libraries" != "" ; then
+      
+  ac_path_to_include=$ac_find_includes
+  echo "$CHECK_INCLUDE" | grep "\-I$ac_find_includes" > /dev/null
+  result=$?
+  if test $result = 0; then
+    ac_path_to_include=""
+  else
+    ac_path_to_include="-I$ac_find_includes"    
+  fi
+
+      
+  echo "$CHECK_LIB" | grep "\-L$ac_find_libraries" > /dev/null
+  result=$?
+  if test $result = 0; then
+    ac_path_to_link=""
+  else
+    ac_path_to_link="-L$ac_find_libraries"    
+  fi
+
+      CHECK_LINK="$CHECK_INCLUDE $ac_path_to_link"
+      CHECK_INCLUDE="$CHECK_INCLUDE $ac_path_to_include"
+      OPENGL_LIBRARY="$ac_path_to_link"
+      OPENGL_INCLUDE="$ac_path_to_include"
+      OPENGL_LINK="-lGL"
+      echo "$ac_t""found OpenGL at $ac_find_libraries" 1>&6
+    else
+      
+ac_find_libraries=
+for ac_dir in $SEARCH_LIB;
+  do
+    for ac_extension in a so sl; do
+      if test -f "$ac_dir/libMesaGL.$ac_extension"; then
+        ac_find_libraries=$ac_dir
+        break 2
+      fi
+    done
+  done
+
+      if test "$ac_find_libraries" != "" ; then
+        
+  ac_path_to_include=$ac_find_includes
+  echo "$CHECK_INCLUDE" | grep "\-I$ac_find_includes" > /dev/null
+  result=$?
+  if test $result = 0; then
+    ac_path_to_include=""
+  else
+    ac_path_to_include="-I$ac_find_includes"    
+  fi
+
+        
+  echo "$CHECK_LIB" | grep "\-L$ac_find_libraries" > /dev/null
+  result=$?
+  if test $result = 0; then
+    ac_path_to_link=""
+  else
+    ac_path_to_link="-L$ac_find_libraries"    
+  fi
+
+        CHECK_LINK="$CHECK_INCLUDE $ac_path_to_link"
+        CHECK_INCLUDE="$CHECK_INCLUDE $ac_path_to_include"
+        OPENGL_LIBRARY="$ac_path_to_link"
+        OPENGL_INCLUDE="$ac_path_to_include"
+        OPENGL_LINK="-lMesaGL"
+        echo "$ac_t""found MESA at $ac_find_libraries" 1>&6
+      else
+        { echo "configure: error: no" 1>&2; exit 1; }
+      fi
+    fi
+  else
+    { echo "configure: error: no" 1>&2; exit 1; }
+  fi
+fi
+
+    if test "$USE_GDK_IMLIB" = 1; then
+      cat >> confdefs.h <<EOF
+#define USE_GDK_IMLIB $USE_GDK_IMLIB
+EOF
+
+    fi
+
+    if test "$USE_ZLIB" = 1; then
+      cat >> confdefs.h <<EOF
+#define USE_ZLIB $USE_ZLIB
+EOF
+
+    fi
+
+    if test "$USE_LIBPNG" = 1; then
+      cat >> confdefs.h <<EOF
+#define USE_LIBPNG $USE_LIBPNG
+EOF
+ 
+    fi
+
+
+
+
+USE_GLX=$USE_OPENGL
+if test "$USE_OPENGL" != 1; then
+  OPENGL_LIBRARIES=
+  OPENGL_INCLUDE=
+  OPENGL_LINK=
+  GLCANVAS=NONE
+fi
+
+cat >> confdefs.h <<EOF
+#define USE_GLX $USE_GLX
+EOF
+
+
+
+
+
+
+
+PICFLAGS=
+CREATE_SHARED=
+case "${canonical}" in
+
+  *-hp-hpux* )
+    if test "${CC}" != "gcc" ; then
+      CXXFLAGS="${CXXFLAGS} +a1 -z -Aa -D_HPUX_SOURCE"
+      CFLAGS="${CFLAGS} -z -D_HPUX_SOURCE"
+      PICFLAGS="+z"
+    else
+      PICFLAGS="-fPIC"
+    fi
+    LDFLAGS="-Wl,+s"
+    CREATE_SHARED=sharedHpux
+  ;;
+
+  *-*-linux* )
+    PICFLAGS=-fPIC
+    CREATE_SHARED=sharedLinux
+  ;;
+
+  *-*-irix5* | *-*-irix6* ) 
+    # PICFLAGS can remain empty, as pic is the default
+    LDFLAGS="-Wl,+s"
+    CREATE_SHARED=sharedIrix
+    cat >> confdefs.h <<\EOF
+#define SVR4 1
+EOF
+
+  ;;
+
+  *-*-solaris2* ) 
+    if test "${CC}" != "gcc" ; then
+      PICFLAGS="-KPIC"
+    else
+      PICFLAGS="-fPIC"
+    fi
+    CREATE_SHARED=sharedSolaris2
+    cat >> confdefs.h <<\EOF
+#define SVR4 1
+EOF
+
+  ;;
+
+  *-*-sunos4* ) 
+    if test "${CC}" != "gcc" ; then
+      PICFLAGS="-PIC"
+    else
+      PICFLAGS="-fPIC"
+    fi
+    LDFLAGS="-Wl,+s"
+    CREATE_SHARED=sharedSunos4
+    cat >> confdefs.h <<\EOF
+#define BSD 1
+EOF
+
+  ;;
+
+  *-*-freebsd* | *-*-netbsd*)
+    PICFLAGS=-fPIC
+    CREATE_SHARED=sharedBsd
+    cat >> confdefs.h <<\EOF
+#define BSD 1
+EOF
+
+  ;;
+
+  *-*-osf* ) 
+    PICFLAGS="-fPIC"
+    CREATE_SHARED=sharedOSF
+  ;;
+
+  *-*-dgux5* ) 
+    if test "${CC}" != "gcc" ; then
+      PICFLAGS="-K PIC"
+    else
+      PICFLAGS="-fPIC"
+    fi
+    CREATE_SHARED=sharedDgux
+    cat >> confdefs.h <<\EOF
+#define SVR4 1
+EOF
+
+  ;;
+
+  *-*-sysv5* ) 
+    if test "${CC}" != "gcc" ; then
+      PICFLAGS="-K PIC"
+    else
+      PICFLAGS="-fPIC"
+    fi
+    CREATE_SHARED=sharedSysV
+    cat >> confdefs.h <<\EOF
+#define SVR4 1
+EOF
+
+  ;;
+
+  *-*-aix* ) 
+    if test "${CC}" != "gcc" ; then
+      PICFLAGS="-bM\:SRE"
+    else
+      PICFLAGS="-fPIC"
+    fi
+    CREATE_SHARED=sharedAIX
+    cat >> confdefs.h <<\EOF
+#define SYSV 1
+EOF
+
+  ;;
+
+  *)
+    CREATE_SHARED=
+    PICFLAGS=
+esac
+
+if test "x$GCC" = xyes; then
+  CFLAGS="${CFLAGS} -Wall"
+fi
+
+if test "x$GXX" = xyes; then
+  CXXFLAGS="${CXXFLAGS} -Wall"
+fi
+
+if test "$USE_SHARED" != 1; then
+    CREATE_SHARED=
+    PICFLAGS=
+fi
+
+
+
+
+
+
+echo $OS >> system.list
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[ 	]*VPATH[ 	]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+  case "\$ac_option" in
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+    echo "$CONFIG_STATUS generated by autoconf version 2.12"
+    exit 0 ;;
+  -help | --help | --hel | --he | --h)
+    echo "\$ac_cs_usage"; exit 0 ;;
+  *) echo "\$ac_cs_usage"; exit 1 ;;
+  esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "src/gtk/setup/substit include/wx/gtk/setup.h:src/gtk/setup/setup.hin" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@WXBASEDIR@%$WXBASEDIR%g
+s%@CC@%$CC%g
+s%@CPP@%$CPP%g
+s%@CXX@%$CXX%g
+s%@CXXCPP@%$CXXCPP%g
+s%@RANLIB@%$RANLIB%g
+s%@AR@%$AR%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@LN_S@%$LN_S%g
+s%@AWK@%$AWK%g
+s%@X_CFLAGS@%$X_CFLAGS%g
+s%@X_PRE_LIBS@%$X_PRE_LIBS%g
+s%@X_LIBS@%$X_LIBS%g
+s%@X_EXTRA_LIBS@%$X_EXTRA_LIBS%g
+s%@LIBOBJS@%$LIBOBJS%g
+s%@YACC@%$YACC%g
+s%@LEX@%$LEX%g
+s%@LEXLIB@%$LEXLIB%g
+s%@LEX_OUTPUT_ROOT@%$LEX_OUTPUT_ROOT%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@THREADS@%$THREADS%g
+s%@THREADS_LINK@%$THREADS_LINK%g
+s%@DEBUG@%$DEBUG%g
+s%@PROFILE@%$PROFILE%g
+s%@OPTIMISE@%$OPTIMISE%g
+s%@RPC@%$RPC%g
+s%@WXRESOURCES@%$WXRESOURCES%g
+s%@PROLOGIO@%$PROLOGIO%g
+s%@PROLOGIOSRC@%$PROLOGIOSRC%g
+s%@POSTSCRIPTDC@%$POSTSCRIPTDC%g
+s%@METAFILE@%$METAFILE%g
+s%@FORM@%$FORM%g
+s%@HELP@%$HELP%g
+s%@IPC@%$IPC%g
+s%@ENHDIALOGBOX@%$ENHDIALOGBOX%g
+s%@XRESOURCES@%$XRESOURCES%g
+s%@CLIPBOARD@%$CLIPBOARD%g
+s%@CONSTRAINTS@%$CONSTRAINTS%g
+s%@TIMEDATE@%$TIMEDATE%g
+s%@FRACTION@%$FRACTION%g
+s%@TOOLBAR@%$TOOLBAR%g
+s%@GAUGE@%$GAUGE%g
+s%@VIRLISTBOX@%$VIRLISTBOX%g
+s%@SCROLLBAR@%$SCROLLBAR%g
+s%@DOCVIEW@%$DOCVIEW%g
+s%@PRINTPREVIEW@%$PRINTPREVIEW%g
+s%@TYPETREE@%$TYPETREE%g
+s%@WXGRAPH@%$WXGRAPH%g
+s%@WXTREE@%$WXTREE%g
+s%@GTK_CONFIG@%$GTK_CONFIG%g
+s%@GTK_CFLAGS@%$GTK_CFLAGS%g
+s%@GTK_LIBS@%$GTK_LIBS%g
+s%@GUI_TK_INCLUDE@%$GUI_TK_INCLUDE%g
+s%@GUI_TK_LIBRARY@%$GUI_TK_LIBRARY%g
+s%@GUI_TK_LINK@%$GUI_TK_LINK%g
+s%@TOOLKIT@%$TOOLKIT%g
+s%@TOOLKIT_DEF@%$TOOLKIT_DEF%g
+s%@OPENGL_INCLUDE@%$OPENGL_INCLUDE%g
+s%@OPENGL_LIBRARY@%$OPENGL_LIBRARY%g
+s%@OPENGL_LINK@%$OPENGL_LINK%g
+s%@GLCANVAS@%$GLCANVAS%g
+s%@OS@%$OS%g
+s%@PICFLAGS@%$PICFLAGS%g
+s%@CREATE_SHARED@%$CREATE_SHARED%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+  if test $ac_beg -gt 1; then
+    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+  else
+    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+  fi
+  if test ! -s conftest.s$ac_file; then
+    ac_more_lines=false
+    rm -f conftest.s$ac_file
+  else
+    if test -z "$ac_sed_cmds"; then
+      ac_sed_cmds="sed -f conftest.s$ac_file"
+    else
+      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+    fi
+    ac_file=`expr $ac_file + 1`
+    ac_beg=$ac_end
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
+  fi
+done
+if test -z "$ac_sed_cmds"; then
+  ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"src/gtk/setup/substit"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+  # Remove last slash and all that follows it.  Not all systems have dirname.
+  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+    # The file is in a subdirectory.
+    test ! -d "$ac_dir" && mkdir "$ac_dir"
+    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+    # A "../" for each directory in $ac_dir_suffix.
+    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+  else
+    ac_dir_suffix= ac_dots=
+  fi
+
+  case "$ac_given_srcdir" in
+  .)  srcdir=.
+      if test -z "$ac_dots"; then top_srcdir=.
+      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+  *) # Relative path.
+    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+    top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+  case "$ac_given_INSTALL" in
+  [/$]*) INSTALL="$ac_given_INSTALL" ;;
+  *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+  esac
+
+  echo creating "$ac_file"
+  rm -f "$ac_file"
+  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+  case "$ac_file" in
+  *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+  *) ac_comsub= ;;
+  esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ 	]*\)#\([ 	]*define[ 	][ 	]*\)'
+ac_dB='\([ 	][ 	]*\)[^ 	]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
+ac_uB='\([ 	]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+  CONFIG_HEADERS="include/wx/gtk/setup.h:src/gtk/setup/setup.hin"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  echo creating $ac_file
+
+  rm -f conftest.frag conftest.in conftest.out
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h.  And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ 	]*#[ 	]*undef[ 	][ 	]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+  ac_lines=`grep -c . conftest.vals`
+  # grep -c gives empty output for an empty file on some AIX systems.
+  if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+  # Write a limited-size here document to conftest.frag.
+  echo '  cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+  echo 'CEOF
+  sed -f conftest.frag conftest.in > conftest.out
+  rm -f conftest.in
+  mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+  rm -f conftest.vals
+  mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+  rm -f conftest.frag conftest.h
+  echo "/* $ac_file.  Generated automatically by configure.  */" > conftest.h
+  cat conftest.in >> conftest.h
+  rm -f conftest.in
+  if cmp -s $ac_file conftest.h 2>/dev/null; then
+    echo "$ac_file is unchanged"
+    rm -f conftest.h
+  else
+    # Remove last slash and all that follows it.  Not all systems have dirname.
+      ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+      if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+      # The file is in a subdirectory.
+      test ! -d "$ac_dir" && mkdir "$ac_dir"
+    fi
+    rm -f $ac_file
+    mv conftest.h $ac_file
+  fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+src/gtk/setup/general/createall
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
+
+mv ${OSTYPE}.system.cache.tmp ${OSTYPE}.system.cache
+
diff --git a/configure.in b/configure.in
new file mode 100644
index 0000000000..0d44fab9c3
--- /dev/null
+++ b/configure.in
@@ -0,0 +1,1453 @@
+dnl ////////////////////////////////////////////////////////////////////////
+dnl
+dnl Top-level configure.in for wxGTK by Robert Roebling, Wolfram Gloger
+dnl and Martin Sperl.
+dnl
+dnl This script is under the wxWindows licence.
+dnl
+dnl ////////////////////////////////////////////////////////////////////////
+
+dnl AM_PATH_GTK([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+dnl Test for GTK, and define GTK_CFLAGS and GTK_LIBS
+dnl
+AC_DEFUN(AM_PATH_GTK,
+[dnl 
+dnl Get the cflags and libraries from the gtk-config script
+dnl
+AC_ARG_WITH(gtk-prefix,[  --with-gtk-prefix=PFX   Prefix where GTK is installed (optional)],
+            gtk_config_prefix="$withval", gtk_config_prefix="")
+AC_ARG_WITH(gtk-exec-prefix,[  --with-gtk-exec-prefix=PFX Exec prefix where GTK is installed (optional)],
+            gtk_config_exec_prefix="$withval", gtk_config_exec_prefix="")
+
+  if test x$gtk_config_exec_prefix != x ; then
+     gtk_config_args="$gtk_config_args --exec-prefix=$gtk_config_exec_prefix"
+     if test x${GTK_CONFIG+set} != xset ; then
+        GTK_CONFIG=$gtk_config_exec_prefix/bin/gtk-config
+     fi
+  fi
+  if test x$gtk_config_prefix != x ; then
+     gtk_config_args="$gtk_config_args --prefix=$gtk_config_prefix"
+     if test x${GTK_CONFIG+set} != xset ; then
+        GTK_CONFIG=$gtk_config_prefix/bin/gtk-config
+     fi
+  fi
+
+  AC_PATH_PROG(GTK_CONFIG, gtk-config, no)
+  min_gtk_version=ifelse([$1], ,0.99.7,$1)
+  AC_MSG_CHECKING(for GTK - version >= $min_gtk_version)
+  no_gtk=""
+  if test "$GTK_CONFIG" != "no" ; then
+    GTK_CFLAGS=`$GTK_CONFIG --cflags`
+    GTK_LIBS=`$GTK_CONFIG --libs`
+    ac_save_CFLAGS="$CFLAGS"
+    ac_save_LIBS="$LIBS"
+    CFLAGS="$CFLAGS $GTK_CFLAGS"
+    LIBS="$LIBS $GTK_LIBS"
+dnl
+dnl Now check if the installed GTK is sufficiently new. (Also sanity
+dnl checks the results of gtk-config to some extent
+dnl
+    AC_TRY_RUN([
+#include <gtk/gtk.h>
+#include <stdio.h>
+
+int 
+main ()
+{
+  int major, minor, micro;
+
+  if (sscanf("$min_gtk_version", "%d.%d.%d", &major, &minor, &micro) != 3) {
+     printf("%s, bad version string\n", "$min_gtk_version");
+     exit(1);
+   }
+
+   return !((gtk_major_version > major) ||
+   	    ((gtk_major_version == major) && (gtk_minor_version > minor)) ||
+ 	    ((gtk_major_version == major) && (gtk_minor_version == minor) && (gtk_micro_version >= micro)));
+}
+],, no_gtk=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
+     CFLAGS="$ac_save_CFLAGS"
+     LIBS="$ac_save_LIBS"
+  else
+     no_gtk=yes
+  fi
+  if test "x$no_gtk" = x ; then
+     AC_MSG_RESULT(yes)
+     ifelse([$2], , :, [$2])     
+  else
+     AC_MSG_RESULT(no)
+     GTK_CFLAGS=""
+     GTK_LIBS=""
+     ifelse([$3], , :, [$3])
+  fi
+  AC_SUBST(GTK_CFLAGS)
+  AC_SUBST(GTK_LIBS)
+])
+
+dnl ------------------------------------------------------------------------
+dnl custom macros
+dnl ------------------------------------------------------------------------
+
+AC_DEFUN(AC_OVERRIDES_PREPARE,
+[
+rm -f ${OSTYPE}.system.cache.tmp
+touch ${OSTYPE}.system.cache.tmp
+touch ${OSTYPE}.system.cache
+])
+
+AC_DEFUN(AC_OVERRIDES_DONE,
+[
+mv ${OSTYPE}.system.cache.tmp ${OSTYPE}.system.cache
+])
+
+dnl package,message,helpmessage,variable
+AC_DEFUN(AC_OVERRIDES,
+[
+AC_MSG_CHECKING("for $2")
+AC_ARG_WITH($1,$3,
+[if test "x$with_$1" = xyes; then
+  ac_cv_use_$1='$4="1"'
+else
+  ac_cv_use_$1='$4="0"'
+fi],
+[
+  LINE=`grep "$4" ${OSTYPE}.system.cache`
+  if test "x$LINE" != x ; then
+    eval "DEFAULT_$LINE"
+  fi
+  ac_cv_use_$1='$4='$DEFAULT_$4
+])
+eval "$ac_cv_use_$1"
+echo $ac_cv_use_$1 >> ${OSTYPE}.system.cache.tmp
+if test "$$4" = 1; then
+  AC_MSG_RESULT(yes)
+else
+  AC_MSG_RESULT(no)
+fi
+])
+
+dnl package,message,helpmessage,variable
+AC_DEFUN(AC_OVERRIDES_OLD,
+[
+AC_MSG_CHECKING("for $2")
+AC_CACHE_VAL(ac_cv_use_$1,
+[
+AC_ARG_WITH($1,$3,
+[if test "x$with_$1" = xyes; then
+  ac_cv_use_$1='$4="1"'
+else
+  ac_cv_use_$1='$4="0"'
+fi],[ac_cv_use_$1='$4=$DEFAULT_$4'])
+])
+eval "$ac_cv_use_$1"
+
+if test "$$4" = 1; then
+  AC_MSG_RESULT(yes)
+else
+  AC_MSG_RESULT(no)
+fi
+])
+
+AC_DEFUN(AC_PATH_FIND_INCLUDES,
+[
+ac_find_includes=
+for ac_dir in $1;
+  do
+    if test -f "$ac_dir/$2"; then
+      ac_find_includes=$ac_dir
+      break
+    fi
+  done
+])
+
+AC_DEFUN(AC_PATH_FIND_LIBRARIES,
+[
+ac_find_libraries=
+for ac_dir in $1;
+  do
+    for ac_extension in a so sl; do
+      if test -f "$ac_dir/lib$2.$ac_extension"; then
+        ac_find_libraries=$ac_dir
+        break 2
+      fi
+    done
+  done
+])
+
+dnl Path to include, allready defined
+AC_DEFUN(AC_INCLUDE_PATH_EXIST,
+[
+  ac_path_to_include=$1
+  echo "$2" | grep "\-I$1" > /dev/null
+  result=$?
+  if test $result = 0; then
+    ac_path_to_include=""
+  else
+    ac_path_to_include="-I$1"    
+  fi
+])
+
+dnl Path to link, allready defined
+AC_DEFUN(AC_LINK_PATH_EXIST,
+[
+  echo "$2" | grep "\-L$1" > /dev/null
+  result=$?
+  if test $result = 0; then
+    ac_path_to_link=""
+  else
+    ac_path_to_link="-L$1"    
+  fi
+])
+
+dnl ------------------------------------------------------------------------
+dnl Process this file with autoconf to produce a configure script.
+dnl ------------------------------------------------------------------------
+
+AC_INIT(configure.in)
+
+dnl ------------------------------------------------------------------------
+dnl Check platform
+dnl ------------------------------------------------------------------------
+
+OS="${OSTYPE}"
+
+if test "x$OS" = "x"; then
+  UNAME=`uname`
+  AC_MSG_ERROR("The system variable OS has not been set"
+               "please set is everytime befor compiling on this system"
+               "A good example for this system would be:"
+               "setenv OSTYPE $UNAME        for csh as a SHELL"
+               "EXPORT OSTYPE=$UNAME        for sh as SHELL"
+               "please set this and restart again."
+              )
+fi
+
+dnl ------------------------------------------------------------------------
+dnl Set base directory
+dnl ------------------------------------------------------------------------
+
+WXBASEDIR=`pwd`
+AC_SUBST(WXBASEDIR)
+
+dnl ------------------------------------------------------------------------
+dnl search path for includes and libraries
+dnl ------------------------------------------------------------------------
+
+SEARCH_INCLUDE="\
+    /usr/Motif1.2/include     \
+			      \
+    /usr/X11R6/include        \
+    /usr/X11R5/include        \
+    /usr/X11R4/include        \
+                              \
+    /usr/include/X11R6        \
+    /usr/include/X11R5        \
+    /usr/include/X11R4        \
+                              \
+    /usr/local/X11R6/include  \
+    /usr/local/X11R5/include  \
+    /usr/local/X11R4/include  \
+                              \
+    /usr/local/include/X11R6  \
+    /usr/local/include/X11R5  \
+    /usr/local/include/X11R4  \
+                              \
+    /usr/X11/include          \
+    /usr/include/X11          \
+    /usr/local/X11/include    \
+    /usr/local/include/X11    \
+                              \
+    /usr/X386/include         \
+    /usr/x386/include         \
+    /usr/XFree86/include/X11  \
+                              \
+    /usr/include              \
+    /usr/local/include        \
+    /usr/local/include/gtk    \
+    /usr/unsupported/include  \
+    /usr/athena/include       \
+    /usr/local/x11r5/include  \
+    /usr/lpp/Xamples/include  \
+                              \
+    /usr/openwin/include      \
+    /usr/openwin/share/include \
+    "
+
+SEARCH_LIB="`echo "$SEARCH_INCLUDE" | sed s/include/lib/g` \
+    "
+
+dnl ------------------------------------------------------------------------
+dnl standard checks
+dnl ------------------------------------------------------------------------
+
+dnl ###################
+dnl # checks programs #
+dnl ###################
+
+dnl C-compiler checks
+dnl =================
+dnl use what compiler
+AC_PROG_CC
+dnl   defines CC with the compiler to use
+dnl   defines GCC with yes if using gcc
+dnl   defines GCC empty if not using gcc
+dnl   defines CFLAGS
+
+CFLAGS=`echo "$CFLAGS" | sed 's/-g//g'`
+
+dnl does compiler support -c and -o simultaniously
+AC_PROG_CC_C_O
+dnl   defines NO_MINUS_C_MINUS_O if compiler does not accept 
+dnl                              both switches simultaniously
+dnl what is the c-preprocessor
+AC_PROG_CPP
+dnl   defines CPP with the c-preprocessor
+dnl is -traditional needed for correct compilations
+AC_PROG_GCC_TRADITIONAL
+dnl   adds -traditional for gcc if needed
+
+AC_LANG_SAVE
+
+dnl C++-compiler checks
+dnl ===================
+dnl use what compiler
+AC_PROG_CXX
+dnl   defines CXX with the compiler to use
+dnl   defines GXX with yes if using gxx
+dnl   defines GXX empty if not using gxx
+dnl   defines CXXFLAGS
+dnl what is the C++-preprocessor
+AC_PROG_CXXCPP
+dnl   defines CXXCPP with the C++-preprocessor
+
+CXXFLAGS=`echo "$CXXFLAGS" | sed 's/-g//g'`
+
+AC_LANG_RESTORE
+
+dnl ranlib command
+dnl ==============
+AC_PROG_RANLIB
+dnl   defines RANLIB with the appropriate command
+
+dnl ar command
+dnl ==========
+AC_CHECK_PROG(AR, ar, ar, ar)
+dnl   defines AR with the appropriate command
+
+dnl install checks
+dnl ==============
+AC_PROG_INSTALL
+dnl   defines INSTALL with the appropriate command
+
+dnl does ln -s works
+dnl ================
+AC_PROG_LN_S
+dnl   defines LN_S with the appropriate command
+
+dnl awk command
+dnl ===========
+AC_PROG_AWK
+dnl   defines AWK with the appropriate command
+
+dnl ###############
+dnl # make checks #
+dnl ###############
+dnl check if VPATH works
+AC_MSG_CHECKING("make for VPATH support")
+dnl create Makefile
+cat - << EOF > confMake
+check : file
+	cp \$? \$@
+	cp \$? final_file
+EOF
+
+if test ! -d sub ; then
+  mkdir sub
+fi
+echo dummy > sub/file
+${MAKE-make} -f confMake VPATH=sub 2> config.log > /dev/null
+RESULT=$?
+rm -f sub/file check final_file config.log confMake
+rmdir sub 
+if test "$RESULT" = 0; then
+  AC_MSG_RESULT(yes)
+else
+  AC_MSG_RESULT(no)
+  AC_MSG_ERROR(
+You need a make-utility that is able to use the variable
+VPATH correctly.
+If your version of make does not support VPATH correctly,
+please install GNU-make (possibly as gmake), and start
+configure with the following command:
+export MAKE=gmake; ./configure  for sh-type shells
+setenv MAKE gmake; ./configure  for csh-type shells
+Also please do remember to use gmake in this case every time
+you are trying to compile.
+) 
+fi
+
+dnl ####################
+dnl # checks libraries #
+dnl ####################
+
+dnl find the X11 include and library files
+AC_PATH_XTRA
+dnl   defines x_includes and x_libraries
+
+dnl #######################
+dnl # checks header files #
+dnl #######################
+AC_HEADER_DIRENT
+dnl   defines DIR
+dnl   defines MACRO HAVE_DIRENT_H if dirent.h exists
+dnl   defines MACRO HAVE_SYS_NDIR_H if sys/ndir.h exists
+dnl   defines MACRO HAVE_SYS_DIR_H if sys/dir.h exists
+dnl   defines MACRO HAVE_NDIR_H if ndir.h exists
+AC_HEADER_STDC
+dnl   defines STDC_HEADERS if ANSI-C header
+AC_HEADER_SYS_WAIT
+dnl   defines HAVE_SYS_WAIT_H if sys/wait.h exist and is POSIX.1
+AC_CHECK_HEADER(fcntl.h)
+dnl   defines HAVE_FCNTL_H
+AC_CHECK_HEADER(limits.h)
+dnl   defines HAVE_LIMITS_h
+AC_CHECK_HEADER(sys/file.h)
+dnl   defines HAVE_SYS_FILE_H
+AC_CHECK_HEADER(sys/time.h)
+dnl   defines HAVE_SYS_TIME_H
+AC_CHECK_HEADER(unistd.h)
+dnl   defines HAVE_UNISTD_H
+
+dnl ###################
+dnl # checks typedefs #
+dnl ###################
+AC_TYPE_GETGROUPS
+dnl   defines GETGROUPS_T
+AC_TYPE_MODE_T
+dnl   defines mode_t if not already defined
+AC_TYPE_OFF_T
+dnl   defines off_t if not already defined
+AC_TYPE_PID_T
+dnl   defines pid_t if not already defined
+AC_TYPE_SIGNAL
+dnl   defines RETSIGTYPE for the correct return type of signal
+AC_TYPE_SIZE_T
+dnl   defines size_t if not already defined
+AC_TYPE_UID_T
+dnl   defines uid_t and gid_t if not already defined
+
+dnl #####################
+dnl # checks structures #
+dnl #####################
+
+AC_HEADER_STAT
+dnl   defines STAT_MACROS_BROKEN if S_ISDIR and S_ISREG 
+dnl                              do not work properly
+AC_HEADER_TIME
+dnl   defines TIME_WITH_SYS_TIME if time.h and sys/time.h can
+dnl                              both be included
+AC_STRUCT_ST_BLKSIZE 
+dnl   defines HAVE_ST_BLKSIZE if struct stat contains st_blksize
+AC_STRUCT_ST_BLOCKS 
+dnl   defines HAVE_ST_BLOCKS if struct stat contains st_blocks
+AC_STRUCT_ST_RDEV 
+dnl   defines HAVE_ST_RDEV if struct stat contains st_rdev
+AC_STRUCT_TM
+dnl   defines TM_IN_SYS_TIME if struct tm is not in time.h
+AC_STRUCT_TIMEZONE
+dnl   defines HAVE_ST_BLKSIZE if struct tm contains tm_zone
+dnl   otherwise
+dnl   defines HAVE_TZNAME if external array tzname is found
+
+dnl ###################################
+dnl # checks compiler characteristics #
+dnl ###################################
+dnl AC_C_CROSS
+
+AC_C_CONST
+dnl   defines const to be empty if c-compiler does not support const fully
+AC_C_INLINE
+dnl   defines inline to a sensible value for the c-compiler
+AC_C_CHAR_UNSIGNED
+dnl   defines __CHAR_UNSIGNED__ if char is unsigned
+AC_C_LONG_DOUBLE
+dnl   defines HAVE_LONGDOUBLE if compiler supports long double
+
+AC_C_BIGENDIAN
+dnl   defines WORDS_BIGENDIAN if system is big endian
+
+AC_CHECK_SIZEOF(int *)
+AC_CHECK_SIZEOF(int)
+AC_CHECK_SIZEOF(long)
+dnl   defines the size of certain types of variables in SIZEOF_???
+
+dnl ############################
+dnl # checks library functions #
+dnl ############################
+
+dnl ##########################
+dnl # checks system services #
+dnl ##########################
+
+AC_SYS_LONG_FILE_NAMES
+dnl   defines HAVE_LONG_FILENAMES if filenames longer then
+dnl                               14 chars are supported
+
+dnl AC_SYS_RESTARTABLE_SYSCALLS
+dnl   defines HAVE_RESTARTABLE_SYSCALLS if the system restarts a 
+dnl                                     system call that is interrupted
+dnl                                     by a signal
+                                          
+dnl #################
+dnl # checks PARSER #
+dnl #################
+
+dnl YACC checks
+dnl ===========
+AC_PROG_YACC
+dnl   defines YACC with the appropriate command
+
+dnl LEX checks
+dnl ==========
+AC_PROG_LEX
+dnl   defines LEX with the appropriate command
+dnl   defines LEXLIB with the appropriate library
+dnl what type is yytext
+AC_DECL_YYTEXT
+dnl   defines YYTEXT_POINTER  if yytext is char*
+dnl   defines LEX_OUTPUT_ROOT as to the base of the 
+dnl                           filename output by the lexer
+
+dnl ------------------------------------------------------------------------
+dnl main includes
+dnl ------------------------------------------------------------------------
+
+CHECK_INCLUDE="-I/usr/include $X_CFLAGS"
+CHECK_LIB="-L/lib -L/usr/lib $X_LIBS"
+
+dnl ------------------------------------------------------------------------
+dnl host system
+dnl ------------------------------------------------------------------------
+
+AC_CANONICAL_HOST
+canonical=$host
+configuration=$host_alias
+
+dnl ------------------------------------------------------------------------
+dnl system settings
+dnl ------------------------------------------------------------------------
+
+USE_GTK=1
+USE_UNIX=1
+
+TOOLKIT=GTK
+TOOLKIT_DEF=__GTK__
+
+USE_LINUX=
+USE_SGI=
+USE_HPUX=
+USE_SYSV=
+USE_SVR4=
+USE_AIX=
+USE_SUN=
+USE_SOLARIS=
+USE_SUNOS=
+USE_ALPHA=
+USE_OSF=
+USE_BSD=
+USE_FREEBSD=
+USE_VMS=
+USE_ULTRIX=
+USE_DATA_GENERAL=
+
+case "${canonical}" in
+  *-hp-hpux* )
+    USE_HPUX=1
+    AC_DEFINE(__HPUX__)
+  ;;
+  *-*-linux* )
+    USE_LINUX=1
+    AC_DEFINE(__LINUX__)
+  ;;
+  *-*-irix5* | *-*-irix6* ) 
+    USE_SGI=1
+    USE_SVR4=1
+    AC_DEFINE(__SGI__)
+    AC_DEFINE(__SVR4__)
+  ;;
+  *-*-solaris2* ) 
+    USE_SUN=1
+    USE_SOLARIS=1
+    USE_SVR4=1
+    AC_DEFINE(__SUN__)
+    AC_DEFINE(__SOLARIS__)
+    AC_DEFINE(__SVR4__)
+  ;;
+  *-*-sunos4* ) 
+    USE_SUN=1
+    USE_SUNOS=1
+    USE_BSD=1
+    AC_DEFINE(__SUN__)
+    AC_DEFINE(__SUNOS__)
+    AC_DEFINE(__BSD__)
+  ;;
+  *-*-freebsd* | *-*-netbsd*)
+    USE_BSD=1
+    USE_FREEBSD=1
+    AC_DEFINE(__FREEBSD__)
+    AC_DEFINE(__BSD__)
+  ;;
+  *-*-osf* ) 
+    USE_ALPHA=1
+    USE_OSF=1
+    AC_DEFINE(__ALPHA__)
+    AC_DEFINE(__OSF__)
+  ;;
+  *-*-dgux5* ) 
+    USE_ALPHA=1
+    USE_SVR4=1
+    AC_DEFINE(__ALPHA__)
+    AC_DEFINE(__SVR4__)
+  ;;
+  *-*-sysv5* ) 
+    USE_SYSV=1
+    USE_SVR4=1
+    AC_DEFINE(__SYSV__)
+    AC_DEFINE(__SVR4__)
+  ;;
+  *-*-aix* ) 
+    USE_AIX=1
+    USE_SYSV=1
+    USE_SVR4=1
+    AC_DEFINE(__AIX__)
+    AC_DEFINE(__SYSV__)
+    AC_DEFINE(__SVR4__)
+  ;;
+  *)
+    AC_MSG_ERROR(I don't know your system type.)
+esac
+
+dnl ------------------------------------------------------------------------
+dnl defaults for command options
+dnl ------------------------------------------------------------------------
+
+AC_OVERRIDES_PREPARE
+
+DEFAULT_USE_SHARED=0
+DEFAULT_USE_OPTIMISE=1
+DEFAULT_USE_PROFILE=0
+DEFAULT_USE_DEBUG_FLAG=0
+DEFAULT_USE_DEBUG_INFO=0
+DEFAULT_USE_MEM_TRACING=0
+
+DEFAULT_USE_ZLIB=1
+DEFAULT_USE_GDK_IMLIB=1
+DEFAULT_USE_LIBPNG=1
+
+DEFAULT_USE_STORABLE_CLASSES=1
+DEFAULT_USE_AUTOTRANS=1
+DEFAULT_USE_AFM_FOR_POSTSCRIPT=1
+DEFAULT_WX_NORMALIZED_PS_FONTS=1
+
+DEFAULT_USE_IOSTREAMH=1
+
+DEFAULT_USE_THREADS=0
+DEFAULT_USE_THREADS_SGI=0
+DEFAULT_USE_THREADS_POSIX=0
+DEFAULT_USE_OPENGL=0
+
+DEFAULT_USE_POSTSCRIPT=1
+DEFAULT_USE_IPC=1
+DEFAULT_USE_RESOURCES=1
+DEFAULT_USE_TIMEDATE=1
+DEFAULT_USE_FRACTION=1
+DEFAULT_USE_CONSTRAINTS=1
+DEFAULT_USE_TOOLBAR=1
+DEFAULT_USE_GAUGE=1
+DEFAULT_USE_SCROLLBAR=1
+DEFAULT_USE_DOC_VIEW_ARCHITECTURE=1
+DEFAULT_USE_PRINTING_ARCHITECTURE=1
+
+DEFAULT_USE_METAFILE=0
+DEFAULT_USE_HELP=0
+DEFAULT_USE_CLIPBOARD=0
+DEFAULT_USE_VLBOX=0
+DEFAULT_USE_WXGRAPH=0
+DEFAULT_USE_WXTREE=0
+DEFAULT_USE_ENHANCED_DIALOG=0
+
+DEFAULT_USE_FORM=0
+DEFAULT_USE_PROLOGIO=0
+DEFAULT_USE_RPC=0
+DEFAULT_USE_WX_RESOURCES=1
+
+dnl ----------------------------------------------------------------
+dnl user options
+dnl ----------------------------------------------------------------
+
+AC_OVERRIDES(shared,shared,
+**--with-shared           create shared libraries,
+USE_SHARED)
+
+AC_OVERRIDES(optimise,optimise,
+**--without-optimise      create unoptimised code,
+USE_OPTIMISE)
+
+AC_OVERRIDES(debug_flag,debug_flag,
+**--with-debug_flag       create code with DEBUG define set to 1,
+USE_DEBUG_FLAG)
+
+AC_OVERRIDES(debug_info,debug_info,
+**--with-debug_info       create code with debuging information included,
+USE_DEBUG_INFO)
+
+AC_OVERRIDES(mem_tracing,mem_tracing,
+**--with-mem_traing       create code with memory tracing,
+USE_MEM_TRACING)
+
+AC_OVERRIDES(profile,profile,
+**--with-profile          create code with profiling information included,
+USE_PROFILE)
+
+dnl ----------------------------------------------------------------
+dnl user options for libraries (no choice yet)
+dnl ----------------------------------------------------------------
+
+AC_OVERRIDES(zlib,zlib,
+**--with-zlib          use zlib (LZW comression),
+USE_ZLIB)
+
+AC_OVERRIDES(gdk_imlib,gdk_imlib,
+**--with-gdk_imlib     use Raster's gdk_imlib (Image library),
+USE_GDK_IMLIB)
+
+AC_OVERRIDES(libpng,libpng,
+**--with-libpng        use libpng (PNG image format),
+USE_LIBPNG)
+
+AC_OVERRIDES(threads,threads,
+**--with-threads       use threads,
+USE_THREADS)
+
+AC_OVERRIDES(opengl,opengl,
+**--with-opengl        use opengl (OpenGL or Mesa),
+USE_OPENGL)
+
+dnl ----------------------------------------------------------------
+dnl user options for code features (no choice yet)
+dnl ----------------------------------------------------------------
+
+AC_OVERRIDES(storable,storable,
+**--with-storable          use storable classes,
+USE_STORABLE_CLASSES)
+
+AC_OVERRIDES(autotrans,autotrans,
+**--with-autotrans         use gettext automatic translation,
+USE_AUTOTRANS)
+
+AC_OVERRIDES(afmfonts,afmfonts,
+**--with-afmfonts         use Adobe Font Metric Font table,
+USE_AFM_FOR_POSTSCRIPT)
+
+AC_OVERRIDES(normalized, normalized,
+**--with-PS-normalized    use normalized PS fonts,
+WX_NORMALIZED_PS_FONTS)
+
+AC_OVERRIDES(rpc,RPC,
+**--with-rpc              use RPC,
+USE_RPC)
+
+AC_OVERRIDES(wxresources,wxresources,
+**--with-wxresources      use wxresources,
+USE_WX_RESOURCES)
+
+AC_OVERRIDES(prologio,prologio,
+**--with-prologio         use prologio,
+USE_PROLOGIO)
+
+AC_OVERRIDES(postscript, postscript,
+**--with-postscript       use postscript-device-context,
+USE_POSTSCRIPT)
+
+AC_OVERRIDES(metafile, metafile,
+**--with-metafile         use metafile,
+USE_METAFILE)
+
+AC_OVERRIDES(form,form,
+**--with-form             use form,
+USE_FORM)
+
+AC_OVERRIDES(help,help,
+**--with-help             use help,
+USE_HELP)
+
+AC_OVERRIDES(ipc,IPC,
+**--with-ipc              use ipc,
+USE_IPC)
+
+AC_OVERRIDES(enhanceddialog,enhanced dialog,
+**--with-enhanceddialog   use enhanced dialog,
+USE_ENHANCED_DIALOG)
+
+AC_OVERRIDES(resources,resources,
+**--with-resources        use resources,
+USE_RESOURCES)
+
+AC_OVERRIDES(clipboard,clipboard,
+**--with-clipboard        use clipboard,
+USE_CLIPBOARD)
+
+AC_OVERRIDES(timedate, timedate,
+**--with-timedate         use timedate,
+USE_TIMEDATE)
+
+AC_OVERRIDES(fraction,fraction,
+**--with-fraction         use fraction,
+USE_FRACTION)
+
+AC_OVERRIDES(constraints,constrains,
+**--with-constraints      use constraints,
+USE_CONSTRAINTS)
+
+AC_OVERRIDES(toolbar,toolbar,
+**--with-toolbar          use toolbar,
+USE_TOOLBAR)
+
+AC_OVERRIDES(gauge,gauge,
+**--with-gauge            use gauge,
+USE_GAUGE)
+
+AC_OVERRIDES(vllist,vllist,
+**--with-vlbox            use virtual list box,
+USE_VLBOX)
+
+AC_OVERRIDES(scrollbar,scrollbar,
+**--with-scrollbar        use scrollbar,
+USE_SCROLLBAR)
+
+AC_OVERRIDES(docview,docview,
+**--with-docview          use document view architecture,
+USE_DOC_VIEW_ARCHITECTURE)
+
+AC_OVERRIDES(printarch,printarch,
+**--with-printarch        use printing architecture,
+USE_PRINTING_ARCHITECTURE)
+
+AC_OVERRIDES(typetree,typetree,
+**--with-typetree         use typetree,
+USE_TYPETREE)
+
+AC_OVERRIDES(wxgraph,wxgraph,
+**--with-wxgraph          use wxgraph,
+USE_WXGRAPH)
+
+AC_OVERRIDES(wxtree,wxtree,
+**--with-wxtree           use wxtree,
+USE_WXTREE)
+
+dnl AC_OVERRIDES(package,message,helpmessage,variable)
+
+dnl ----------------------------------------------------------------
+dnl register changes for Makefiles (via substit) and setup.h
+dnl ----------------------------------------------------------------
+
+ZLIB=NONE
+if test "$USE_ZLIB" = 1 ; then
+  ZLIB="ZLIB"
+fi
+
+GDK_IMLIB=NONE
+if test "$USE_GDK_IMLIB" = 1 ; then
+  GDK_IMLIB="GDK_IMLIB"
+fi
+
+LIBPNG=NONE
+if test "$USE_LIBPNG" = 1 ; then
+  LIBPNG="LIBPNG"
+fi
+
+THREADS=NONE
+THREADS_LINK=
+if test "$USE_THREADS" = 1 ; then
+  case "$OS" in iris | IRIX | Irix5 | Irix6)
+    USE_THREADS_POSIX=0
+    USE_THREADS_SGI=1
+  ;;
+  *)
+    USE_THREADS_POSIX=1
+    USE_THREADS_SGI=0
+    THREADS_LINK=-lpthread
+  ;;
+  esac
+  THREADS="THREADS"
+  AC_DEFINE_UNQUOTED(USE_THREADS,$USE_THREADS)
+  AC_DEFINE_UNQUOTED(USE_THREADS_SGI,$USE_THREADS_SGI)
+  AC_DEFINE_UNQUOTED(USE_THREADS_POSIX,$USE_THREADS_POSIX)
+fi
+AC_SUBST(THREADS)
+AC_SUBST(THREADS_LINK)
+
+STORABLE=NONE
+if test "$USE_STORABLE_CLASSES" = 1 ; then
+  STORABLE="STORABLE"
+  AC_DEFINE_UNQUOTED(USE_STORABLE_CLASSES,$USE_STORABLE_CLASSES)
+fi
+
+AUTOTRANS=NONE
+if test "$USE_AUTOTRANS" = 1 ; then
+  AUTOTRANS="AUTOTRANS"
+  AC_DEFINE_UNQUOTED(USE_AUTOTRANS,$USE_AUTOTRANS)
+fi
+
+DEBUG=
+if test "$USE_DEBUG_INFO" = 1 ; then
+  DEBUG="-g"
+fi
+AC_SUBST(DEBUG)
+
+if test "$USE_DEBUG_FLAG" = 1 ; then
+  AC_DEFINE_UNQUOTED(DEBUG,$USE_DEBUG_FLAG)
+fi
+
+if test "$USE_MEM_TRACING" = 1 ; then
+  AC_DEFINE_UNQUOTED(USE_MEMORY_TRACING,$USE_MEM_TRACING)
+  AC_DEFINE_UNQUOTED(USE_GLOBAL_MEMORY_OPERATORS,$USE_MEM_TRACING)
+fi
+
+PROFILE=
+if test "$USE_PROFILE" = 1 ; then
+  PROFILE="-pg"
+fi
+AC_SUBST(PROFILE)
+
+CXXFLAGS=`echo "${CXXFLAGS}" | sed "s/\-O.//g" `
+CFLAGS=`echo "${CFLAGS}" | sed "s/\-O.//g" `
+if test "$USE_OPTIMISE" = 0 ; then
+  OPTIMISE=
+else
+  if test "$GCC" = yes ; then
+    OPTIMISE="-O2"
+    case "${canonical}" in
+      i586-*-*|i686-*-* )
+	OPTIMISE="${OPTIMISE} "
+	;;
+    esac
+  else
+    OPTIMISE="-O"
+  fi
+fi
+AC_SUBST(OPTIMISE)
+
+USE_IOSTREAMH=$DEFAULT_USE_IOSTREAMH
+AC_DEFINE_UNQUOTED(USE_IOSTREAMH,$USE_IOSTREAMH)
+
+RPC=NONE
+if test "$USE_RPC" = 1 ; then
+  RPC="RPC"
+  AC_DEFINE_UNQUOTED(USE_RPC,$USE_RPC)
+fi
+AC_SUBST(RPC)
+
+WXRESOURCES=NONE
+if test "$USE_WX_RESOURCES" = 1 ; then
+  WXRESOURCES="WXRESOURCES"
+  AC_DEFINE_UNQUOTED(USE_WX_RESOURCES,$USE_WX_RESOURCES)
+fi
+AC_SUBST(WXRESOURCES)
+
+PROLOGIO=NONE
+PROLOGIOSRC=NONE
+if test "$USE_PROLOGIO" = 1 ; then
+  PROLOGIO="PROLOGIO"
+  PROLOGIOSRC="PROLOGIOSRC"
+  AC_DEFINE_UNQUOTED(USE_PROLOGIO)
+fi
+AC_SUBST(PROLOGIO)
+AC_SUBST(PROLOGIOSRC)
+
+POSTSCRIPTDC=NONE
+if test "$USE_POSTSCRIPT" = 1 ; then
+  POSTSCRIPTDC="POSTSCRIPTDC"
+  AC_DEFINE_UNQUOTED(USE_POSTSCRIPT)
+fi
+AC_SUBST(POSTSCRIPTDC)
+
+METAFILE=NONE
+if test "$USE_METAFILE" = 1 ; then
+  METAFILE="METAFILE"
+  AC_DEFINE_UNQUOTED(USE_METAFILE,$USE_METAFILE)
+fi
+AC_SUBST(METAFILE)
+
+FORM=NONE
+if test "$USE_FORM" = 1 ; then
+  FORM="FORM"
+  AC_DEFINE_UNQUOTED(USE_FORM,$USE_FORM)
+fi
+AC_SUBST(FORM)
+
+HELP=NONE
+if test "$USE_HELP" = 1 ; then
+  HELP="HELP"
+  AC_DEFINE_UNQUOTED(USE_HELP,$USE_HELP)
+fi
+AC_SUBST(HELP)
+
+IPC=NONE
+if test "$USE_IPC" = 1 ; then
+  IPC="IPC"
+  AC_DEFINE_UNQUOTED(USE_IPC)
+fi
+AC_SUBST(IPC)
+
+ENHDIALOGBOX=NONE
+if test "$USE_ENHANCED_DIALOG" = 1 ; then
+  ENHDIALOGBOX="ENHDIALOGBOX"
+  AC_DEFINE_UNQUOTED(USE_ENHANCED_DIALOG,$USE_ENHANCED_DIALOG)
+fi
+AC_SUBST(ENHDIALOGBOX)
+
+XRESOURCES=NONE
+if test "$USE_RESOURCES" = 1 ; then
+  XRESOURCES="XRESOURCES"
+  AC_DEFINE_UNQUOTED(USE_RESOURCES,$USE_RESOURCES)
+fi
+AC_SUBST(XRESOURCES)
+
+CLIPBOARD=NONE
+if test "$USE_CLIPBOARD" = 1 ; then
+  CLIPBOARD="CLIPBOARD"
+  AC_DEFINE_UNQUOTED(USE_CLIPBOARD,$USE_CLIPBOARD)
+fi
+AC_SUBST(CLIPBOARD)
+
+CONSTRAINTS=NONE
+if test "$USE_CONSTRAINTS" = 1 ; then
+  CONSTRAINTS="CONSTRAINTS"
+  AC_DEFINE_UNQUOTED(USE_CONSTRAINTS,$USE_CONSTRAINTS)
+fi
+AC_SUBST(CONSTRAINTS)
+
+TIMEDATE=NONE
+if test "$USE_TIMEDATE" = 1 ; then
+  TIMEDATE="TIMEDATE"
+  AC_DEFINE_UNQUOTED(USE_TIMEDATE,$USE_TIMEDATE)
+fi
+AC_SUBST(TIMEDATE)
+
+FRACTION=NONE
+if test "$USE_FRACTION" = 1 ; then
+  FRACTION="FRACTION"
+  AC_DEFINE_UNQUOTED(USE_FRACTION,$USE_FRACTION)
+fi
+AC_SUBST(FRACTION)
+
+TOOLBAR=NONE
+if test "$USE_TOOLBAR" = 1 ; then
+  TOOLBAR="TOOLBAR"
+  AC_DEFINE_UNQUOTED(USE_TOOLBAR,$USE_TOOLBAR)
+  AC_DEFINE_UNQUOTED(USE_XT_TOOLBAR,$USE_XT_TOOLBAR)
+fi
+AC_SUBST(TOOLBAR)
+
+GAUGE=NONE
+if test "$USE_GAUGE" = 1 ; then
+  GAUGE="GAUGE"
+  AC_SUBST(GAUGE)
+  AC_DEFINE_UNQUOTED(USE_GAUGE,$USE_GAUGE)
+fi
+
+VIRLISTBOX=NONE
+if test "$USE_VLBOX" = 1 ; then
+  VIRTLISTBOX="VIRLISTBOX"
+  AC_DEFINE_UNQUOTED(USE_VIRLISTBOX,$USE_VIRLISTBOX)
+fi
+AC_SUBST(VIRLISTBOX)
+
+SCROLLBAR=NONE
+if test "$USE_SCROLLBAR" = 1 ; then
+  SCROLLBAR="SCROLLBAR"
+  AC_DEFINE_UNQUOTED(USE_SCROLLBAR,$USE_SCROLLBAR)
+fi
+AC_SUBST(SCROLLBAR)
+
+DOCVIEW=NONE
+if test "$USE_DOC_VIEW_ARCHITECTURE" = 1 ; then
+  DOCVIEW="DOCVIEW"
+  AC_DEFINE_UNQUOTED(USE_DOC_VIEW_ARCHITECTURE,$USE_DOC_VIEW_ARCHITECTURE)
+fi
+AC_SUBST(DOCVIEW)
+
+PRINTPREVIEW=NONE
+if test "$USE_PRINTING_ARCHITECTURE" = 1 ; then
+  PRINTPREVIEW="PRINTPREVIEW"
+  AC_DEFINE_UNQUOTED(USE_PRINTING_ARCHITECTURE,$USE_PRINTING_ARCHITECTURE)
+fi
+AC_SUBST(PRINTPREVIEW)
+
+TYPETREE=NONE
+if test "$USE_TYPETREE" = 1 ; then
+  TYPETREE="TYPETREE"
+  AC_DEFINE_UNQUOTED(USE_TYPETREE,$USE_TYPETREE)
+fi
+AC_SUBST(TYPETREE)
+
+WXGRAPH=NONE
+if test "$USE_WXGRAPH" = 1 ; then
+  WXGRAPH="WXGRAPH"
+  AC_DEFINE_UNQUOTED(USE_WXGRAPH,$USE_WXGRAPH)
+fi
+AC_SUBST(WXGRAPH)
+
+WXTREE=NONE
+if test "$USE_WXTREE" = 1 ; then
+  WXTREE="WXTREE"
+  AC_DEFINE_UNQUOTED(USE_WXTREE,$USE_WXTREE)
+fi
+AC_SUBST(WXTREE)
+
+GLCANVAS=NONE
+if test "$USE_OPENGL" = 1 ; then
+  GLCANVAS="GLCANVAS"
+fi
+
+AC_DEFINE_UNQUOTED(USE_AFM_FOR_POSTSCRIPT,$USE_AFM_FOR_POSTSCRIPT)
+
+AC_DEFINE_UNQUOTED(WX_NORMALIZED_PS_FONTS,$WX_NORMALIZED_PS_FONTS)
+
+dnl ----------------------------------------------------------------
+dnl Unix, obviously
+dnl ----------------------------------------------------------------
+
+if test "$USE_UNIX" = 1 ; then
+  AC_DEFINE(__UNIX__)
+fi
+
+dnl ----------------------------------------------------------------
+dnl search for GTK
+dnl ----------------------------------------------------------------
+
+GUI_TK_INCLUDE=
+GUI_TK_LIBRARY=
+GUI_TK_LINK=
+
+if test "$USE_GTK" = 1; then
+  AM_PATH_GTK(0.99.7, [
+       GUI_TK_INCLUDE="$GTK_CFLAGS"
+       GUI_TK_LIBRARY="$GTK_LIBS"
+  ], AC_MSG_ERROR(Are gtk-config and the GTK in path and up-to-date?))
+  AC_DEFINE(__GTK__)
+fi
+AC_SUBST(GUI_TK_INCLUDE)
+AC_SUBST(GUI_TK_LIBRARY)
+AC_SUBST(GUI_TK_LINK)
+
+AC_SUBST(TOOLKIT)
+AC_SUBST(TOOLKIT_DEF)
+
+dnl ----------------------------------------------------------------
+dnl search for opengl
+dnl ----------------------------------------------------------------
+
+OPENGL_INCLUDE=
+OPENGL_LIBRARY=
+OPENGL_LINK=
+
+if test "$USE_OPENGL" = 1; then
+  dnl checking OPENGL includes
+  AC_MSG_CHECKING(for OpenGL includes)
+  AC_PATH_FIND_INCLUDES($SEARCH_INCLUDE,GL/gl.h)
+  if test "$ac_find_includes" != "" ; then
+    OPENGL_INCLUDE="-I$ac_find_includes"
+    AC_MSG_RESULT(found $ac_find_includes)
+    dnl checking OPENGL libraries
+    AC_MSG_CHECKING(for OpenGL library)
+    AC_PATH_FIND_LIBRARIES($SEARCH_LIB,GL)
+    if test "$ac_find_libraries" != "" ; then
+      AC_INCLUDE_PATH_EXIST($ac_find_includes,$CHECK_INCLUDE)
+      AC_LINK_PATH_EXIST($ac_find_libraries,$CHECK_LIB)
+      CHECK_LINK="$CHECK_INCLUDE $ac_path_to_link"
+      CHECK_INCLUDE="$CHECK_INCLUDE $ac_path_to_include"
+      OPENGL_LIBRARY="$ac_path_to_link"
+      OPENGL_INCLUDE="$ac_path_to_include"
+      OPENGL_LINK="-lGL"
+      AC_MSG_RESULT(found OpenGL at $ac_find_libraries)
+    else
+      AC_PATH_FIND_LIBRARIES($SEARCH_LIB,MesaGL)
+      if test "$ac_find_libraries" != "" ; then
+        AC_INCLUDE_PATH_EXIST($ac_find_includes,$CHECK_INCLUDE)
+        AC_LINK_PATH_EXIST($ac_find_libraries,$CHECK_LIB)
+        CHECK_LINK="$CHECK_INCLUDE $ac_path_to_link"
+        CHECK_INCLUDE="$CHECK_INCLUDE $ac_path_to_include"
+        OPENGL_LIBRARY="$ac_path_to_link"
+        OPENGL_INCLUDE="$ac_path_to_include"
+        OPENGL_LINK="-lMesaGL"
+        AC_MSG_RESULT(found MESA at $ac_find_libraries)
+      else
+        AC_MSG_ERROR(no)
+      fi
+    fi
+  else
+    AC_MSG_ERROR(no)
+  fi
+fi
+
+dnl ----------------------------------------------------------------
+dnl search for gdk_imlib
+dnl ----------------------------------------------------------------
+dnl 
+dnl GDK_IMLIB_INCLUDE=
+dnl GDK_IMLIB_LIBRARY=
+dnl GDK_IMLIB_LINK=
+dnl 
+    if test "$USE_GDK_IMLIB" = 1; then
+dnl   AC_MSG_CHECKING(for gdk_imlib includes)
+dnl   AC_PATH_FIND_INCLUDES($SEARCH_INCLUDE,gdk_imlib.h)
+dnl   if test "$ac_find_includes" != "" ; then
+dnl     dnl GDK_IMLIB_INCLUDE="-I$ac_find_includes"
+dnl     AC_MSG_RESULT(found $ac_find_includes)
+dnl     AC_MSG_CHECKING(for gdk_imlib library)
+dnl     AC_PATH_FIND_LIBRARIES($SEARCH_LIB,gdk_imlib)
+dnl     if test "$ac_find_libraries" != "" ; then
+dnl       AC_INCLUDE_PATH_EXIST($ac_find_includes,$CHECK_INCLUDE)
+dnl       AC_LINK_PATH_EXIST($ac_find_libraries,$CHECK_LIB)
+dnl       CHECK_LINK="$CHECK_INCLUDE $ac_path_to_link"
+dnl       CHECK_INCLUDE="$CHECK_INCLUDE $ac_path_to_include"
+dnl       GDK_IMLIB_LIBRARY="$ac_path_to_link"
+dnl       GDK_IMLIB_INCLUDE="$ac_path_to_include"
+dnl       GDK_IMLIB_LINK="-lgdk_imlib"
+dnl       AC_MSG_RESULT(found gdk_imlib at $ac_find_libraries)
+dnl     else
+dnl       AC_MSG_ERROR(no)
+dnl     fi
+dnl   else
+dnl     AC_MSG_ERROR(no)
+dnl   fi
+      AC_DEFINE_UNQUOTED(USE_GDK_IMLIB,$USE_GDK_IMLIB)
+    fi
+dnl AC_SUBST(GDK_IMLIB_INCLUDE)
+dnl AC_SUBST(GDK_IMLIB_LIBRARY)
+dnl AC_SUBST(GDK_IMLIB_LINK)
+
+dnl ----------------------------------------------------------------
+dnl search for zlib
+dnl ----------------------------------------------------------------
+dnl
+dnl ZLIB_INCLUDE=
+dnl ZLIB_LINK=
+dnl 
+    if test "$USE_ZLIB" = 1; then
+dnl   AC_MSG_CHECKING(for zlib includes)
+dnl   AC_PATH_FIND_INCLUDES($SEARCH_INCLUDE,zlib.h)
+dnl   if test "$ac_find_includes" != "" ; then
+dnl     AC_MSG_RESULT(found $ac_find_includes)
+dnl     AC_MSG_CHECKING(for zlib library)
+dnl     AC_PATH_FIND_LIBRARIES($SEARCH_LIB,z)
+dnl     if test "$ac_find_libraries" != "" ; then
+dnl       AC_INCLUDE_PATH_EXIST($ac_find_includes,$CHECK_INCLUDE)
+dnl       AC_LINK_PATH_EXIST($ac_find_libraries,$CHECK_LIB)
+dnl       CHECK_LINK="$CHECK_INCLUDE $ac_path_to_link"
+dnl       CHECK_INCLUDE="$CHECK_INCLUDE $ac_path_to_include"
+dnl       ZLIB_INCLUDE="$ac_path_to_include"
+dnl       ZLIB_LINK="-lz"
+dnl       AC_MSG_RESULT(found zlib at $ac_find_libraries)
+dnl     else
+dnl       AC_MSG_ERROR(no)
+dnl     fi
+dnl   else
+dnl     AC_MSG_ERROR(no)
+dnl   fi
+      AC_DEFINE_UNQUOTED(USE_ZLIB,$USE_ZLIB)
+    fi
+dnl AC_SUBST(ZLIB_INCLUDE)
+dnl AC_SUBST(ZLIB_LIBRARY)
+dnl AC_SUBST(ZLIB_LINK)
+
+dnl ----------------------------------------------------------------
+dnl search for libpng
+dnl ----------------------------------------------------------------
+dnl 
+dnl LIBPNG_INCLUDE=
+dnl LIBPNG_LIBRARY=
+dnl LIBPNG_LINK=
+dnl 
+    if test "$USE_LIBPNG" = 1; then
+dnl   AC_MSG_CHECKING(for libpng includes)
+dnl   AC_PATH_FIND_INCLUDES($SEARCH_INCLUDE,png.h)
+dnl   if test "$ac_find_includes" != "" ; then
+dnl     AC_MSG_RESULT(found $ac_find_includes)
+dnl     AC_MSG_CHECKING(for libpng library)
+dnl     AC_PATH_FIND_LIBRARIES($SEARCH_LIB,png)
+dnl     if test "$ac_find_libraries" != "" ; then
+dnl       AC_INCLUDE_PATH_EXIST($ac_find_includes,$CHECK_INCLUDE)
+dnl       AC_LINK_PATH_EXIST($ac_find_libraries,$CHECK_LIB)
+dnl       CHECK_LINK="$CHECK_INCLUDE $ac_path_to_link"
+dnl       CHECK_INCLUDE="$CHECK_INCLUDE $ac_path_to_include"
+dnl       LIBPNG_LIBRARY="$ac_path_to_link"
+dnl       LIBPNG_INCLUDE="$ac_path_to_include"
+dnl       LIBPNG_LINK="-lpng"
+dnl       AC_MSG_RESULT(found libpng at $ac_find_libraries)
+dnl     else
+dnl       AC_MSG_RESULT(no)
+dnl     fi
+dnl   else
+dnl     AC_MSG_ERROR(no)
+dnl   fi
+      AC_DEFINE_UNQUOTED(USE_LIBPNG,$USE_LIBPNG) 
+    fi
+dnl AC_SUBST(LIBPNG_INCLUDE)
+dnl AC_SUBST(LIBPNG_LIBRARY)
+dnl AC_SUBST(LIBPNG_LINK)
+
+dnl ----------------------------------------------------------------
+dnl search for Python
+dnl ----------------------------------------------------------------
+
+dnl ----------------------------------------------------------------
+dnl search for ODBC
+dnl ----------------------------------------------------------------
+
+dnl ----------------------------------------------------------------
+dnl left-over
+dnl ----------------------------------------------------------------
+
+USE_GLX=$USE_OPENGL
+if test "$USE_OPENGL" != 1; then
+  OPENGL_LIBRARIES=
+  OPENGL_INCLUDE=
+  OPENGL_LINK=
+  GLCANVAS=NONE
+fi
+
+AC_DEFINE_UNQUOTED(USE_GLX,$USE_GLX)
+AC_SUBST(OPENGL_INCLUDE)
+AC_SUBST(OPENGL_LIBRARY)
+AC_SUBST(OPENGL_LINK)
+AC_SUBST(GLCANVAS)
+
+dnl ------------------------------------------------------------------------
+dnl compiler options for shared libs
+dnl ------------------------------------------------------------------------
+
+PICFLAGS=
+CREATE_SHARED=
+case "${canonical}" in
+
+  *-hp-hpux* )
+    if test "${CC}" != "gcc" ; then
+      CXXFLAGS="${CXXFLAGS} +a1 -z -Aa -D_HPUX_SOURCE"
+      CFLAGS="${CFLAGS} -z -D_HPUX_SOURCE"
+      PICFLAGS="+z"
+    else
+      PICFLAGS="-fPIC"
+    fi
+    LDFLAGS="-Wl,+s"
+    CREATE_SHARED=sharedHpux
+  ;;
+
+  *-*-linux* )
+    PICFLAGS=-fPIC
+    CREATE_SHARED=sharedLinux
+  ;;
+
+  *-*-irix5* | *-*-irix6* ) 
+    # PICFLAGS can remain empty, as pic is the default
+    LDFLAGS="-Wl,+s"
+    CREATE_SHARED=sharedIrix
+    AC_DEFINE(SVR4)
+  ;;
+
+  *-*-solaris2* ) 
+    if test "${CC}" != "gcc" ; then
+      PICFLAGS="-KPIC"
+    else
+      PICFLAGS="-fPIC"
+    fi
+    CREATE_SHARED=sharedSolaris2
+    AC_DEFINE(SVR4)
+  ;;
+
+  *-*-sunos4* ) 
+    if test "${CC}" != "gcc" ; then
+      PICFLAGS="-PIC"
+    else
+      PICFLAGS="-fPIC"
+    fi
+    LDFLAGS="-Wl,+s"
+    CREATE_SHARED=sharedSunos4
+    AC_DEFINE(BSD)
+  ;;
+
+  *-*-freebsd* | *-*-netbsd*)
+    PICFLAGS=-fPIC
+    CREATE_SHARED=sharedBsd
+    AC_DEFINE(BSD)
+  ;;
+
+  *-*-osf* ) 
+    PICFLAGS="-fPIC"
+    CREATE_SHARED=sharedOSF
+  ;;
+
+  *-*-dgux5* ) 
+    if test "${CC}" != "gcc" ; then
+      PICFLAGS="-K PIC"
+    else
+      PICFLAGS="-fPIC"
+    fi
+    CREATE_SHARED=sharedDgux
+    AC_DEFINE(SVR4)
+  ;;
+
+  *-*-sysv5* ) 
+    if test "${CC}" != "gcc" ; then
+      PICFLAGS="-K PIC"
+    else
+      PICFLAGS="-fPIC"
+    fi
+    CREATE_SHARED=sharedSysV
+    AC_DEFINE(SVR4)
+  ;;
+
+  *-*-aix* ) 
+    if test "${CC}" != "gcc" ; then
+      PICFLAGS="-bM\:SRE"
+    else
+      PICFLAGS="-fPIC"
+    fi
+    CREATE_SHARED=sharedAIX
+    AC_DEFINE(SYSV)
+  ;;
+
+  *)
+    CREATE_SHARED=
+    PICFLAGS=
+esac
+
+if test "x$GCC" = xyes; then
+  CFLAGS="${CFLAGS} -Wall"
+fi
+
+if test "x$GXX" = xyes; then
+  CXXFLAGS="${CXXFLAGS} -Wall"
+fi
+
+if test "$USE_SHARED" != 1; then
+    CREATE_SHARED=
+    PICFLAGS=
+fi
+
+AC_SUBST(OS)
+AC_SUBST(PICFLAGS)
+AC_SUBST(CREATE_SHARED)
+
+dnl ------------------------------------------------------------------------
+dnl finish and clean-up
+dnl ------------------------------------------------------------------------
+
+dnl add OS to list of configured
+echo $OS >> system.list
+
+AC_CONFIG_HEADER(include/wx/gtk/setup.h:src/gtk/setup/setup.hin)
+AC_OUTPUT(src/gtk/setup/substit,src/gtk/setup/general/createall)
+AC_OVERRIDES_DONE
diff --git a/docs/changes.txt b/docs/changes.txt
new file mode 100644
index 0000000000..9d4737708e
--- /dev/null
+++ b/docs/changes.txt
@@ -0,0 +1,227 @@
+
+Generic wxWindows 2.0 Change Log
+--------------------------------
+
+Note: for platform-specific changes, see wx/docs/XXX/changes.txt
+where XXX is one of msw, motif, xt, gtk, mac.
+
+Alpha 9, April 27th 1998
+------------------------
+
+- Corrected some bugs, such as the wxModule compilation problem.
+- Added Gnu-Win32 b19/Mingw32 support by changing resource
+  compilation and pragmas.
+- Changed SIZEOF to WXSIZEOF.
+
+Alpha 8, April 17th 1998
+------------------------
+
+- Added src/other/png, src/other/zlib directories.
+- Added samples/png.
+- IMPORTANT: Changed 'no id' number from 0 to -1, in wxEVT_ macros.
+  Porters, please check particularly your wxTreeCtrl and wxListCtrl
+  header files.
+- Added modules.h/cpp, config.cpp, fileconf.cpp, textfile.cpp/h.
+
+Alpha 7, March 30th 1998
+------------------------
+
+- Added tab classes, tab sample.
+- Revised memory.cpp, memory.h slightly; memory.h now #defines
+  new to WXDEBUG_NEW in DEBUG mode. Windows implementation app.cpp
+  now checks for leaks on exit. Added memcheck sample.
+  See src/msw/issues.txt for more details.
+- resource.h, resource.cpp changed to make wxDefaultResourceTable
+  a pointer. Now initialize resource system with
+  wxInitializeResourceSystem and wxCleanUpResourceSystem, to
+  allow better control of memory.
+- wxString now derives from wxObject, to enable memory leak
+  checking.
+- Added some #include fixes in various files, plus changed
+  float to long in wxToolBar files.
+
+Alpha 6, March 10th 1998
+------------------------
+
+- Added Vadim's dynarray.h, dynarray.cpp.
+- Added Vadim's menuitem.cpp.
+- Added Windows-specific wxCheckListBox,
+  owner-draw wxListBox, and drag-and-drop
+  (see docs/msw/changes.txt).
+
+Alpha 5, 14th February 1998
+--------------------------
+
+- GENERIC AND MSW-SPECIFIC CODE NOW TREATED AS TWO SEPARATE
+  DISTRIBUTIONS. This change log will therefore now refer to
+  the generic code only. See docs/msw/changes.txt for Windows-specific
+  changes.
+- Readmes, change logs and installation files now go in
+  platform-specific directories under docs, e.g. docs/msw,
+  docs/gtk.
+- Added DECLARE_APP and IMPLEMENT_APP macros so wxApp object gets
+  created dynamically, not as a global object.
+- Put wxColour into wx/msw/colour.h, src/msw/colour.cpp.
+- Changed names of some include/wx/generic headers to be
+  consistent and to conform to gcc pragma conventions. Also
+  changed choicesg.cpp to choicdgg.cpp.
+- Added gcc pragmas.
+- Added gtk inclusion in include/wx headers.
+- Added consistent file headings to source and headers.
+- Removed lang.cpp, lang.h and references to wxSTR_... variables;
+  added a few references to wxTransString.
+- Added operator to wxTransString that converts automatically
+  to wxString, so we can say e.g. wxMessageBox(wxTransString("Hello"), ...).
+- samples/internat now works (minimally).
+- Added wxMouseEvent::GetPosition and
+  wxMouseEvent::GetLogicalPosition, both returning wxPoints.
+- Made wxSize and wxRect contain longs not ints.
+- Cured some lemory leaks (thanks Vadim).
+- Tidied up OnIdle and introduced RequestMore/MoreRequested so
+  will only keep processing OnIdle if it returns TRUE from
+  MoreRequested.
+
+Alpha 4, 31st January 1998
+--------------------------
+
+- Changed wxDC functions to take longs instead of floats. GetSize now takes
+  integer pointers, plus a version that returns a wxSize.
+- const keyword added to various wxDC functions.
+- Under Windows, wxDC no longer has any knowledge of whether
+  an associated window is scrolled or not. Instead, the device
+  origin is set by wxScrolledWindow in wxScrolledWindow::PrepareDC.
+- wxScrolledWindow applications can optionally override the virtual OnDraw
+  function instead of using the OnPaint event handler. The wxDC passed to
+  OnDraw will be translated by PrepareDC to reflect scrolling.
+  When drawing outside of OnDraw, must call PrepareDC explicitly.
+- wxToolBarBase/wxToolBarSimple similarly changed to allow for
+  scrolling toolbars.
+- Integrated wxPostScriptDC patches for 1.xx by Chris Breeze,
+  to help printing with multiple pages.
+- IPC classes given base classes (wxConnectionBase etc.) which
+  define the API used by different implementations. DDE
+  implementation updated to use these base classes.
+- wxHelpInstance now separated into wxHelpControllerBase (base
+  for all implementations), wxWinHelpController (uses standard
+  WinHelp), wxXLPHelPController (talks to wxHelp by DDE or
+  TCP/IP). There will be others eventually, such as
+  wxHTMLHelpController for Microsoft (and Netscape?) HTML Help.
+- Added Vadim Zeitlin's wxString class plus
+  internationalization code (gettext simulation, wxLocale, etc.).
+  New files from Vadim:
+  include\wx\string.h
+  include\wx\debug.h
+  include\wx\file.h
+  include\wx\log.h
+  include\wx\intl.h
+  src\common\string.cpp
+  src\common\log.cpp
+  src\common\intl.cpp
+  src\common\file.cpp
+  No longer use GNU wxString files.
+- Split off file-related functions into include\wx\filefn.h and
+  src\common\filefn.cpp.
+- Borland C++ support (WIN32) for main library and
+  samples, using makefile.b32 files.
+- Preparation done for allowing BC++ to compile wxWin as a DLL,
+  including changes to defs.h.
+- wxIntPoint removed, wxPoint is now int, and wxRealPoint
+  introduced.
+- Added wxShowEvent (generated when window is being shown or
+  hidden).
+- Got minimal, docview, mdi samples working for 16-bit VC++ and
+  cured 16-bit problem with wxTextCtrl (removed global memory
+  trick).
+- Updated GnuWin32 makefiles, checked minimal, mdi, docview samples.
+
+Alpha 3, September 1997
+-----------------------
+
+- wxListCtrl, wxTreeCtrl, wxImageList classes done.
+- Instigated new file hierarchy, split files and classes up more logically.
+- PrologIO and some other utils now put into core library.
+- Revamped print/preview classes, added wxPageSetupDialog.
+- Started documentation.
+
+Alpha 2, 30th April 1997
+------------------------
+
+- EVT_... macros now have at least one argument, for conformance
+  with MetroWerks compiler.
+- Added ids to .wxr file format.
+- Got Dialog Editor compiled and running again but need
+  to extend functionality to be in line with new controls.
+  Added dialoged\test app to allow dynamic loading of .wxr files
+  for testing purposes.
+- Rewrote wxBitmap to allow installable file type
+  handlers.
+- Rewrote wxBitmapButton, wxStaticBitmap to not use Fafa.
+- Wrote most of wxTreeCtrl and sample (need wxImageList to implement it
+  fully).
+- Added back wxRadioBox.
+- Tidied up wx_main.cpp, wxApp class, putting PenWin code in
+  a separate file.
+
+Alpha 1, 5th April 1997
+-----------------------
+
+At this point, the following has been achieved:
+
+- A lot, but not all, of the code has been revamped for better
+  naming conventions, protection of data members, and use of
+  wxString instead of char *.
+- Obsolete functionality deleted (e.g. default wxPanel layout,
+  old system event system) and code size reduced.
+- Class hierarchy changed (see design doc) - base classes such
+  as wxbWindow now removed.
+- No longer includes windows.h in wxWin headers, by using stand-in
+  Windows types where needed e.g. WXHWND.
+- PrologIO revised.
+- wxScrolledWindow, wxStatusBar and new MDI classes added.
+  MDI is now achived using separate classes, not window styles.
+- wxSystemSettings added, and made use of to reflect standard
+  Windows settings.
+- SetButtonFont/SetLabelFont replaced by SetFont; font and colour
+  settings mucho rationalised.
+- All windows are now subclassed with the same window proc to make
+  event handling far more consistent. Old internal wxWnd and derived
+  classes removed.
+- API for controls revised, in particular addition of
+  wxValidator parameters and removal of labels for some controls.
+- 1 validator written: see examples/validate.
+- Event table system introduced (see most samples and
+  wx_event.cpp/ProcessEvent, wx_event.h). wxEvtHandler
+  made more flexible, with Push/PopEventHandler allowing a chain
+  of event handlers.
+- wxRadioBox removed - will be added back soon.
+- Toolbar class hierarchy revised:
+  wxToolBarBase
+  wxToolBarSimple (= old wxToolBar)
+  wxToolBar95 (= old wxButtonBar under Win95
+  wxToolBarMSW (= old wxButtonBar under WIN16/WIN32)
+- Constraint system debugged somewhat (sizers now work properly).
+- wxFileDialog, wxDirDialog added; other common dialogs now
+  have class equivalents. Generic colour and font dialogs
+  rewritten to not need obsolete panel layout.
+- .wxr resource system partially reinstated, though needs
+  an integer ID for controls. Hopefully the resource system
+  will be replaced by something better and more efficient
+  in the future.
+- Device contexts no longer stored with window and accessed
+  with GetDC - use wxClientDC, wxPaintDC, wxWindowDC stack
+  variables instead.
+- wxSlider uses trackbar class under Win95, and wxSL_LABELS flag
+  determines whether labels are shown. Other Win95-specific flags
+  introduced, e.g. for showing ticks.
+- Styles introduced for dealing with 3D effects per window, for
+  any window: all Win95 3D effects supported, plus transparent windows.
+- Major change to allow 3D effect support without CTL3D, under
+  Win95.
+- Bitmap versions of button and checkbox separated out into new
+  classes, but unimplemented as yet because I intend to remove
+  the need for Fafa - it apparently causes GPFs in Win95 OSR 2.
+- utils/wxprop classes working (except maybe wxPropertyFormView)
+  in preparation for use in Dialog Editor.
+- GNU-WIN32 compilation verified (a month or so ago).
+
+
diff --git a/docs/gtk/welcome.html b/docs/gtk/welcome.html
new file mode 100644
index 0000000000..ac59b63028
--- /dev/null
+++ b/docs/gtk/welcome.html
@@ -0,0 +1,292 @@
+<html>
+<head><title>wxGTK Homepage</title>
+</head>
+<body bgcolor=#FFFFFF text=#000000 link=#0020FF vlink=#800000 alink=#007777>
+<h1>"wxWindows for the GTK" Homepage</h1>
+
+<hr>
+<h3>Current version</h3>
+15th May '98: wxGTK v0.12 (alpha-)
+<p> 
+This release is hardly more stable than the one before, but it
+has many new features. It's main purpose is actually to prepare
+the final merge of the Windows port and the GTK port source
+trees into a common tree, developed using CVS. The growing
+number of demos which compile and run with wxGTK "although"
+being written for wxMSW shows that we seem to be on the right
+track. One nice new feature for many potential users is that
+wxGTK no longer needs any extra libraries to be installed,
+other than the GTK.
+<p>
+If you have a compiler
+better than gcc 2.7.2.2 then you can uncomment a line in src/common/prntbase.cpp
+which defines __GOOD_COMPILER__. This should make the printing demo work.
+I haven't got such a compiler, so I actually don't know. Somebody reported
+problems with version 2.7.2.3 as well.
+<p>
+<hr>
+<h3>Acknowledgements</h3>
+I'd like to thank the 
+<a href="http://www.freiburg.linux.de">Freiburg Linux User Group</a>
+ for kindly providing
+this site and Christian Wetzel in particular for helping me with
+this site's administration.
+<p>
+
+<hr>
+<h3>What is wxWindows?</h3>
+wxWindows is a C++ cross-platform GUI toolkit written mainly by Julian Smart. 
+More information about wxWindows can be found at the
+<a href="http://web.ukonline.co.uk/julian.smart/wxwin">wxWindows Homepage</a>.
+
+<p>
+The current version of wxWindows (v1.68) supports Windows ('95 and NT), Motif and
+XView (aka OpenLook). There is another port (wxXt) available, which uses the 
+free-ware widget set from the Free Widget Foundation (FSF). Ports have been
+started for the Mac, OS/2 and NextStep.
+<p>
+For different reasons, it was decided to start a complete rewrite of wxWindows,
+which will then be called wxWindows 2.0. For a list of new features and changes
+from the current version, you may read the wxWindows Homepage (see above).
+<p>
+Currently, work is being done on four ports of wxWindows 2.0:
+<dl>
+  <li> Windows (wxMSW, main author Julian Smart)
+  <li> Unix, Motif (wxMotif, main author Markus Holzhem)
+  <li> Unix, GIMP Toolkit (wxGTK, main author Robert Roebling)
+  <li> Macintosh (wxMac, main author Greg Whitehead)
+</dl>
+<p>
+wxWindows provides a rich set of classes which help to make cross-platform
+GUI programming easy. In many aspect, it is modelled after MFC, making transition
+from MFC to wxWindows relatively painless. The main technical
+difference between most other free or commercial cross platform libraries is
+that wxWindows is a wrapper around existing widget sets, whereas the other
+toolkits (Qt, Tk, Java, Amulet, OPaC, JX, Fresko) draw their widgets themselves, 
+which results in applications having a different look than native applications 
+for that specific platform.
+<p>
+There are classes for the following categories
+<dl>
+  <li> Window classes: wxWindow, wxFrame, wxDialogBox, wxPanel, wxCanvas etc.
+  <li> Widget classes: wxButton, wxCheckbox, wxChoice, wxListBox, wxListCtrl, wxText, wxGauge etc.
+  <li> Data structures: wxList, wxString, wxHashTable, wxDate etc.
+  <li> Layout/constraint system
+  <li> GDI classes: wxPen, wxBrush, wxFont, wxBitmap etc.
+  <li> Events: wxCommandEvent, wxMouseEvent, wxKeyEvent etc.
+  <li> Devices contexts: wxCanvasDC, wxPostScriptDC, wxMemoryDC, wxPrinterDC
+  <li> Base classes for runtime-type information: wxObject
+  <li> Interprocess communication: wxClient, wxConnection, wxSocket, wxServer etc.
+  <li> Document-view architecture: wxDocument, wxView, wxDocManager etc.
+  <li> Printing framework: wxPreviewFrame, wxPrintDialog, wxPrinter etc.
+  <li> Many helper classes, wxApplication, wxTypeTree, wxPathList etc.
+  <li> Classes for internationalization
+  <li> Built-in memory leak checking, log-files
+  <li> A multitude of functions and macros
+</dl>
+
+<hr>
+<h3>Copyright</h3>
+The choice of a suitable copyright has been subject to endless discussions. It
+has always been the aim, to put wxWindows under a copyright, which protects
+the work of its authors while at the same time encouraging the use of wxWindows
+in as many projects as possible. 
+<p>
+The (so far) last decision has been to put the whole of wxWindows
+under a modified (less restrictive) version of the GNU library general 
+public license.
+<p>
+The only exception is that wxGTK now contains code (gdk_imlib) which is 
+under the GNU library general public license. When you make changes to 
+this part of wxGTK, you'll have to make these changes public (in contrast 
+to changes to the rest).
+<p>
+It is obviously encouraged that anybody who uses wxWindows and who
+makes any improvements to it will make these changes available to
+wxWindows' authors.
+<p>
+<hr>
+<h3>What can I do with wxWindows 2.0?</h3>
+wxWindows is still in alpha stage, which means that there are still bugs
+waiting for you and several features are not yet (fully) implemented, but
+you can expect the interface to be more or less stable, so no major 
+modifications will have to be made to your source code. wxGTK is already
+used in a number of medium sized projects and is it being developped
+in close cooperation with the authors of these applications.
+<p>
+<hr>
+<h3>Can I write a GNOME application with wxGTK 2.0?</h3>
+Good question. The idea to use wxGTK for the GNOME desktop environment is
+quite obvious. When this topic came up on the GNOME mailing list, the GNOME
+people have shown an amazingly negative opinion about wxWindows. One reason
+might be that several of the main authors of the GNOME-project consider
+C++ a "broken language". I don't share that view and I am sure many people
+find C++ easier to handle and better suited for GUI programming than C.
+<p>
+Just recently, the topic of C++ in general and wxGTK in particular appeared
+again on the GNOME list. It has shown that - at least - the opinion on C++
+on the GNOME list is split. 
+<p>
+There is already a C++ wrapper for the GTK called GTK-- written by Tero Pulkkinen. 
+It is very small and adds very little overhead to the GTK. If platform
+independence is no issue for you and you want to write a small tool
+for Linux, you should probably use GTK--. Of course you can use wxGTK
+for that, too :-)
+<p>
+<hr>
+<h3>Screenshots</h3>
+What would a home page of a GUI be without a screenshot? Well, as wxWindows
+is a wrapper around existing widget/item sets, a wxWindows application will
+look like any other native Windows, Motif, GTK or Mac application.
+<p>
+But for those of you, who wouldn't download wxGTK only because there
+is no screenshot, 
+<a href="ftp://ftp.freiburg.linux.de/pub/linux/wxxt/sshot.jpg">here it comes</a>.
+<p>
+<hr>
+<h3>Download 1.68</h3>
+Go to the 
+<a href="ftp://ftp.freiburg.linux.de/pub/linux/wxxt">FTP</a>
+section directly.
+<p>
+There is documentation for version 1.68 in html available. 
+<a href="ftp://ftp.freiburg.linux.de/pub/linux/wxxt">here</a>. Not yet.
+<p>
+You can download current wxWindows version 1.68 for Windows, Motif and
+XView from
+<a href="ftp://ftp.freiburg.linux.de/pub/linux/wxxt">here</a>. Not yet.
+<p>
+You can download wxXt 1.66d from
+<a href="ftp://ftp.freiburg.linux.de/pub/linux/wxxt/wxxt166d.tgz">here</a>.
+<p>
+<hr>
+<h3>Download 2.0 alpha</h3>
+There is documentation for version 2.0 in html available. 
+<a href="ftp://ftp.freiburg.linux.de/pub/linux/wxxt/wxGTK_doc.tgz">here</a>.
+<p>
+You can download the first alpha for wxWindows 2.0 for Windows from
+<a href="ftp://ftp.freiburg.linux.de/pub/linux/wxxt/">here</a>. Not yet.
+<p>
+You can download the current alpha for wxWindows 2.0 for GTK from
+<a href="ftp://ftp.freiburg.linux.de/pub/linux/wxxt/wxGTK-0.12.tgz">here</a>. 
+<p>
+
+<hr>
+<h3>News from wxGTK 0.12</h3>
+<p>
+PNG, zlib and gdk_imlib code included.
+<p>
+MDI implementation. More a basis for further testing
+than of real value.
+<p>
+Split "--with-debug" option into two options: "--with-debug_info"
+and "--with-debug_flag". The first one sets the "-g" flag when
+compiling, the second defines "DEBUG" in setup.h (which is included
+from defs.h).
+<p>
+Merged DocView framework. The sample doesn't compile yet, because
+it uses features from wxTextCtrl, which I haven't implemented yet.
+<p>
+Merged TabCtrl. Doesn't look perfect, but it seems to work.
+<p>
+Merged remaining classes from the newest wxMSW alpha. (wxDynArray,
+wxModule etc.).
+<p>
+Further updates, bug fixes or additions:
+<p>
+<dl>
+  <li> wxYield() (again)
+  <li> postscript support for bitmaps
+  <li> spline code merged
+  <li> several bug fixes
+  <li> new samples
+</dl>
+
+<p>
+<hr>
+<h3>Known problems</h3>
+
+Missing implementation of:
+<dl>
+  <li>Impossible to set new font in GTK's widgets
+  <li>Items containing bitmaps
+  <li>Masks, bitmap handlers (partially done)
+  <li>Gauge
+  <li>Combobox
+  <li>Palettes (colormaps)
+  <li>Keyboard accelerators for menus
+  <li>Validation
+  <li>Clipboard functions
+  <li>Resources (for use with wxIDE-to-be)
+  <li>Drag and Drop
+  <li>Threads, Interprocess communication
+  <li>Sockets
+  <li>Database classes
+</dl>
+
+<p>
+<hr>
+<h3>Installation of wxGTK under Linux</h3>
+
+GTK requires an up-to-date version of the 
+<dl>
+  <li> GTK (GIMP ToolKit)
+</dl>
+to be installed as a shared lib on your system. wxGTK is being developped with
+version 1.0.1 and it is known not to work with earlier versions.
+The GTK library is available from 
+<a href="ftp://ftp.gtk.org/pub/">somewhere here (gtk.org).</a>
+After having typed "make install" the GTK header files should be
+in "/usr/local/include". Correct me, if I am wrong.
+<p>
+Compilation itself works as usual with autoconf:
+<dl>
+  <li> Unpack it to a suitable subdirectory, let's say ~/wxGTK
+  <li> Type "cd wxGTK"
+  <li> Type "configure"
+  <li> Type "make"
+</dl>
+Some demos use files stored in the source directory of those demos
+(e.g. internat uses files in samples/internat) whereas the binaries
+will end up in samples/internat/linux. You'll have to copy the binaries
+down or call them like "linux/test" from samples/internat. This is
+also the case for wxTest (which should display a horse).
+<p>
+You can create a shared library by adding the option "--with-shared" to
+the "configure" command. Afterwards, you'll have to copy the library
+~/wxGTK/lib/linux (if you have Linux) to a directory in your LDPATH (e.g. /usr/X11R6/lib)
+and run "ldconfig".
+<p>
+
+<hr>
+<h3>Mailing list for wxGTK</h3>
+The mailing list (as well as this page) is called wxxt for more
+or less historical reasons.
+<p>
+You can subsribe to the mailing list by sending a mail to
+<a href="mailto:majordomo@wesley.informatik.uni-freiburg.de">majordomo@wesley.informatik.uni-freiburg.de</a>.
+This mail must contain the text "subscribe wxxt" in the body (not the subject) of the
+mail. You will then get a confirmation that somebody asked majordomo to put you
+on the list and you will have to confirm this once again by sending back
+the authentisation, which comes in the confirmation mail. The last step
+is also described in the actual confirmation mail (I think).
+<p>
+You can send a mail to the mailing list to the address
+<a href="mailto:wxxt@www.freiburg.linux.de">wxxt@www.freiburg.linux.de</a>.
+
+<p>
+Unsubscribe by sending "unsubscribe wxxt" to majordomo (see above). Not to
+the actual mailing list.
+<p>
+<hr>
+<address>
+<br>This page is maintained by <a href="mailto:roebling@sun2.ruf.uni-freiburg.de">Robert Roebling</a>.
+Comments, in contrast to junk and flames, welcome.
+<p>
+Last changed 15th Mai '98. 
+</address>
+</body>
+</html>
+
+
+
diff --git a/docs/licence.txt b/docs/licence.txt
new file mode 100644
index 0000000000..44fb89cab9
--- /dev/null
+++ b/docs/licence.txt
@@ -0,0 +1,224 @@
+wxWindows Licence
+-----------------
+
+Copyright (c) 1998 Julian Smart, Markus Holzem
+
+
+Preamble
+--------
+
+This licence is intended to protect wxWindows, its developers,
+and its users, so that the considerable investment it represents
+is not abused.
+
+Unlike the wxWindows licence, you as a user are not obliged to
+distribute wxWindows source code with your products. However,
+you are prevented from selling the code without permission from
+the authors, or denying others the rights to use or distribute
+wxWindows in the way intended.
+
+The wxWindows Licence establishes the copyright for the code and
+related material, and it gives you legal permission to copy,
+distribute and/or modify the library. It also asserts that no
+warranty is given by the authors for this or derived code.
+
+Finally, the licence specifies that any patent involving
+wxWindows, must be licenced for everyone's free use.
+
+wxWindows Licence
+-----------------
+
+Terms and conditions for copying, distribution and modification
+
+1. This Licence Agreement applies to any software library which
+contains a notice placed by the copyright holder or other
+authorized party saying it may be distributed under the terms of
+this wxWindows Licence (also called "this Licence").  Each
+licencee is addressed as "you". 
+
+A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application
+programs (which use some of those functions and data) to form
+executables.
+
+The "Library", below, refers to any such software library or
+work which has been distributed under these terms.  A "work
+based on the Library" means either the Library or any derivative
+work under copyright law: that is to say, a work containing the
+Library or a portion of it, either verbatim or with
+modifications and/or translated straightforwardly into another
+language.  (Hereinafter, translation is included without
+limitation in the term "modification".)
+
+"Source code" for a work means the preferred form of the work
+for making modifications to it.  For a library, complete source
+code means all the source code for all modules it contains, plus
+any associated interface definition files, plus the scripts used
+to control compilation and installation of the library.
+
+Activities other than copying, distribution and modification are
+not covered by this Licence; they are outside its scope. The act
+of running a program using the Library is not restricted, and
+output from such a program is covered only if its contents
+constitute a work based on the Library (independent of the use
+of the Library in a tool for writing it). Whether that is true
+depends on what the Library does and what the program that uses
+the Library does.
+  
+2. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided
+that you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep
+intact all the notices that refer to this Licence and to the
+absence of any warranty; and distribute a copy of this Licence
+along with the Library.
+
+You may charge a fee for the physical act of transferring a
+copy, and you may at your option offer warranty protection in
+exchange for a fee.
+
+3. You may modify your copy or copies of the Library or any
+portion of it, thus forming a work based on the Library, and
+copy and distribute such modifications or work under the terms
+of Section 1 above, provided that you cause the files modified
+to carry prominent notices stating that you changed the files
+and the date of any change. With agreement from the authors of
+wxWindows, you may charge for value added to the Library, for
+example, a commercially supported version, or a port to a new
+platform. It is expected that collaboration between such
+commercial interests and the free wxWindows community will yield
+benefits to both parties, since wxWindows represents a
+substantial investment of time and effort. It is not in the
+spirit of this agreement that commercial exploitation of
+wxWindows should in any way detract from the free version.
+
+4. You may copy and distribute the Library in object code or
+derived library form under the terms of Sections 1 and 2 above
+provided that you accompany it with the complete corresponding
+machine-readable source code.
+
+If distribution of object code is made by offering access to
+copy from a designated place, then offering equivalent access to
+copy the source code from the same place satisfies the
+requirement to distribute the source code, even though third
+parties are not compelled to copy the source along with the
+object code.
+
+5. You may not copy, modify, sublicence, link with, or
+distribute the Library except as expressly provided under this
+Licence.  Any attempt otherwise to copy, modify, sublicence,
+link with, or distribute the Library is void, and will
+automatically terminate your rights under this Licence.
+However, parties who have received copies, or rights, from you
+under this Licence will not have their licences terminated so
+long as such parties remain in full compliance.
+
+6. You are not required to accept this Licence, since you have
+not signed it. However, nothing else grants you permission to
+modify or distribute the Library or its derivative works.  These
+actions are prohibited by law if you do not accept this Licence.
+Therefore, by modifying or distributing the Library (or any work
+based on the Library), you indicate your acceptance of this
+Licence to do so, and all its terms and conditions for copying,
+distributing or modifying the Library or works based on it.
+
+7. Each time you redistribute the Library (or any work based on
+the Library), the recipient automatically receives a licence
+from the original licensor to copy, distribute, link with or
+modify the Library subject to these terms and conditions. You
+may not impose any further restrictions on the recipients'
+exercise of the rights granted herein. You are not responsible
+for enforcing compliance by third parties to this Licence.
+
+8. If, as a consequence of a court judgment or allegation of
+patent infringement or for any other reason (not limited to
+patent issues), conditions are imposed on you (whether by court
+order, agreement or otherwise) that contradict the conditions of
+this Licence, they do not excuse you from the conditions of this
+Licence. If you cannot distribute so as to satisfy
+simultaneously your obligations under this Licence and any other
+pertinent obligations, then as a consequence you may not
+distribute the Library at all. For example, if a patent licence
+would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you,
+then the only way you could satisfy both it and this Licence
+would be to refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable
+under any particular circumstance, the balance of the section is
+intended to apply, and the section as a whole is intended to
+apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe
+any patents or other property right claims or to contest
+validity of any such claims; this section has the sole purpose
+of protecting the integrity of the free software distribution
+system which is implemented by public licence practices. Many
+people have made generous contributions to the wide range of
+software distributed through that system in reliance on
+consistent application of that system; it is up to the
+author/donor to decide if he or she is willing to distribute
+software through any other system and a licencee cannot impose
+that choice.
+
+This section is intended to make thoroughly clear what is
+believed to be a consequence of the rest of this Licence.
+
+9. If the distribution and/or use of the Library is restricted
+in certain countries either by patents or by copyrighted
+interfaces, the original copyright holder who places the Library
+under this Licence may add an explicit geographical distribution
+limitation excluding those countries, so that distribution is
+permitted only in or among countries not thus excluded. In such
+case, this Licence incorporates the limitation as if written in
+the body of this Licence.
+
+10. The authors of wxWindows may publish revised and/or new
+versions of the wxWindows Licence from time to time. Such new
+versions will be similar in spirit to the present version, but
+may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the
+Library specifies a version number of this Licence which applies
+to it and "any later version", you have the option of following
+the terms and conditions either of that version or of any later
+version published by the wxWindows authors.  If the Library does
+not specify a licence version number, you may choose any version
+ever published by the wxWindows authors.
+
+11. If you wish to incorporate parts of the Library into other
+free programs whose distribution conditions are incompatible
+with these, write to the program author to ask for permission.
+For software which is copyrighted by the wxWindows authors,
+write to the wxWindows authors.  Our decision will be guided by
+the two goals of preserving the free status of all derivatives
+of our free software and of promoting the sharing and reuse of
+software generally.
+
+NO WARRANTY
+-----------
+
+12. BECAUSE THE LIBRARY IS LICENCED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE
+LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT
+WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE
+QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU.  SHOULD THE
+LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY
+SERVICING, REPAIR OR CORRECTION.
+
+13. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO
+IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY
+MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE
+LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
+INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
+INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS
+OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH
+ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+END OF TERMS AND CONDITIONS
+
diff --git a/docs/readme.txt b/docs/readme.txt
new file mode 100644
index 0000000000..dfff164e67
--- /dev/null
+++ b/docs/readme.txt
@@ -0,0 +1,10 @@
+wxWindows 2.0 alpha
+-------------------
+
+This is an alpha distribution of wxWindows 2.0. It may be made up
+of sources for different platforms from different authors.
+
+For generic installation information, see the docs directory. For
+platform-specific installation information see for example docs/msw or
+docs/gtk.
+
diff --git a/docs/symbols.txt b/docs/symbols.txt
new file mode 100644
index 0000000000..65612ab69c
--- /dev/null
+++ b/docs/symbols.txt
@@ -0,0 +1,56 @@
+This is a list of preprocessor symbols used in the wxWindows source.
+
+GUIs:
+-----
+
+__X__           any X, but not GTK
+__MOTIF__       Motif
+__XT__          Xt; mutually exclusive with WX_MOTIF (?)
+__GTK__         GTK
+__XVIEW__       Obsolete!
+__WINDOWS__     Any Windows
+__MAC__         MacOS
+__UNIX__        any Unix
+__WIN95__       GUI for Windows 95 and above; NT 4.0 and above.
+__WIN32__       WIN32 API
+__NT__          Windows NT
+__CURSES__      CURSES
+
+OSes/machines:
+
+__HPUX__
+__SVR4__
+__SYSV__
+__LINUX__
+__SGI__
+__ULTRIX__
+__BSD__
+__VMS__
+__SUN__         Any Sun
+__SUNOS__
+__SOLARIS__
+__ALPHA__
+__AIX__
+__DATA_GENERAL__
+__OSF__
+__FREEBSD__
+
+Compilers:
+----------
+
+__GNUWIN32__    Gnu-Win32 compiler
+__DJGPP__       DJGPP
+__GNUG__        Gnu C++ on any platform
+__BORLANDC__    Borland C++
+__WATCOMC__     Watcom C++
+__SYMANTECC__   Symantec C++
+__VISUALC__     VC++
+__SUNCC__
+__XLC__         ?? compiler
+
+wxWindows modes:
+----------------
+
+__DEBUG__       usage: #ifdef __DEBUG__ (=> debug mode, else => release)
+WXDEBUG         usage: #if DEBUG (0: release, 1: minimal debug code, ...)
+
diff --git a/im_palette.pal b/im_palette.pal
new file mode 100644
index 0000000000..44660998d4
--- /dev/null
+++ b/im_palette.pal
@@ -0,0 +1,48 @@
+0x00 0x00 0x00
+0xff 0xff 0xff
+0xdd 0xdd 0xdd
+0xbb 0xbb 0xbb
+0x99 0x99 0x99
+0x77 0x77 0x77
+0x55 0x55 0x55
+0x33 0x33 0x33
+0x88 0x00 0x00
+0xcc 0x00 0x00
+0xff 0x00 0x00
+0xff 0x44 0x00
+0xff 0x88 0x00
+0xff 0xcc 0x00
+0xff 0xff 0x00
+0xcc 0xcc 0x00
+0x88 0x88 0x00
+0x44 0x44 0x00
+0x00 0x44 0x00
+0x00 0x88 0x00
+0x00 0xcc 0x00
+0x00 0xff 0x00
+0x00 0x44 0x44
+0x00 0x88 0x88
+0x00 0xff 0xff
+0x00 0x00 0x44
+0x00 0x00 0x88
+0x00 0x00 0xff
+0x88 0x00 0x88
+0xff 0xcc 0x99
+0xcc 0xaa 0x77
+0xaa 0x88 0x55
+0x88 0x66 0x33
+0x66 0x44 0x11
+0x44 0x22 0x00
+0x22 0x00 0x00
+0x00 0x44 0x88
+0x44 0x88 0xcc
+0x88 0xcc 0xff
+0x00 0xcc 0x44
+0x44 0x88 0x44
+0x88 0xcc 0x00
+0x22 0x44 0x11
+0x33 0x66 0x22
+0x44 0x55 0x33
+0x66 0x88 0x44
+0x33 0x66 0x22
+0x22 0x44 0x11
diff --git a/imrc b/imrc
new file mode 100644
index 0000000000..5849d45bb7
--- /dev/null
+++ b/imrc
@@ -0,0 +1,99 @@
+################################
+#    Config file for Imlib     #
+################################
+
+# The file that contains palette entries for a global palette for all Imlib
+# based programs.
+# options: full path to palette file
+PaletteFile                       /etc/im_palette.pal
+# This defines if when the display is greater than 8 bit, that it still remaps
+# the images to the palette defined, rather than using "perfect" rendering
+# options: yes/no
+PaletteOverride                   no
+# If remapping to the palette, whether to use Floyd-Steinberg dithering. Saying
+# yes will slow things down though.
+# options: yes/no
+Dither                            yes
+# when remapping to the palette, saying fast will reduce accuracy, but improve
+# speed quite considerably
+# options: fast/slow
+Remap                             fast
+# This turns on dithering for 15/16 bpp. This makes smooth gradients look much
+# smoother - in fact almost perfect. You will find it nigh impossible to tell
+# the difference between 15/16bpp dithered and 24bpp. Unless you have extra
+# CPU to burn, its not recommended, unless you are a image quality freak, and
+# you insist on maximum quality in 15/16bpp. It does slow things down. It
+# would be best to leave it off and let the applications themselves allow
+# you to select it for certain purposes only.
+HighQuality                       off
+# This option if specified off will force MIT-SHM off, otherwise will allow
+# Imlib to work it out itself.
+Mit-Shm                           on
+# This will turn shared pixmaps on or off (off forces off, on lets imlib
+# work it out). This is yet another speedup. leave it on unless it doesn't
+# work.. then turn it off.
+SharedPixmaps                     off
+# This speeds up rendering considerably, but may not work on your hardware
+# due to it bypassing a few layers and byte-twiddling the rendered image data
+# manually, and due to endianess, bit-ordering or RGB ordering it may screw up
+# and not work, so try it.. if things work great!, if not, wait until a
+# renderer for your situation is written, or write one yourself and donate
+# it. It's easy to do, just look at rend.c
+FastRender                        on
+# This is in fact a workaround due to Solaris's shared memory theories.
+# This specifies the maximum size of a shared memory chunk in bytes. If an
+# image is larger that this in bytes for the video mode you're in, imlib will
+# not use MIT-SHM. if you comment this out, imlib will use as much memory as
+# necessary to render the image.
+# Shm_Max_Size                      1000000
+# This turns Image loading (24) bit caching on or off. HIGHLY suggested to be
+# turned ON!
+Image_Cache                       on
+# Image cache size in bytes.  As with any cache, the more, the better.  If you
+# load the same image more than once. Imlib will used a previously loaded
+# copy, and if its freed, the Image_Cache_Size amount of bytes of image data
+# are kept even after being freed, in case the same image is loaded again soon
+# afterwards. Neat eh?
+Image_Cache_Size                  4000000
+# This turns the pixmap caching system on or off.  If on, only well-behaved
+# programs that conform to the specs for using Imlib will exhibit the
+# behavior as expected. It is suggested to leave this on, as it will boost
+# performance considerably, speed-wise and memory-wise. The reason apps need
+# to be well-behaved is so that they don't go drawing on, and XFreePixmap'ing
+# these pixmaps themselves, because this will trample all over the cache
+# and give very horrid effects, or even make the apps crash with segfaults or
+# Xlib errors.
+Pixmap_Cache                      on
+# Pixmap cache is in **-> BITS <-**... the end result is APPROXIMATELY
+# 10000000 bits of pixmap make your Xserver grow by 1Mb of RAM (VERY rough).
+# As with any cache, the more, the better. The more you have, the less likely
+# it is that you will get cache misses and so performance on scaling the same
+# image to commonly used sizes (ie if 3 or 4 sizes of the same image are used)
+# will be lightning fast, in fact in some tests I did, in 16bpp up to 38 times
+# as fast, and in 8bpp (with dithering on) up to 105 times faster!!! (these
+# are nominal figures obtained on my machine. these are MAXIMUM speedup
+# results.  Results may vary on other machines and according to the way
+# programs are written and use Imlib)
+Pixmap_Cache_Size                 40000000
+# This FORCES Imlib to use the hexadecimal visual id stated here if it is
+# defined in the imrc. This bypasses Imlib's routines that hunt for the best
+# visual. You can obtain a list of visual ID's using the xdpyinfo command.
+# You should only need this if Imlib doesn't pick the correct visual or you
+# have strange hardware/Xserver combinations.
+#ForceVisualID                   22
+# This allows Imlib to fall back on Imagemagick and/or NETPBM
+# utilities if it can't load the file.
+Fallback                         on
+# Default Gamma, Brightness and Contrast stuff....
+Gamma                            1.0
+Brightness                       1.0
+Contrast                         1.0
+Red_Gamma                        1.0
+Red_Brightness                   1.0
+Red_Contrast                     1.0
+Green_Gamma                      1.0
+Green_Brightness                 1.0
+Green_Contrast                   1.0
+Blue_Gamma                       1.0
+Blue_Brightness                  1.0
+Blue_Contrast                    1.0
diff --git a/include/wx/app.h b/include/wx/app.h
new file mode 100644
index 0000000000..0a6bccac70
--- /dev/null
+++ b/include/wx/app.h
@@ -0,0 +1,61 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        app.h
+// Purpose:     wxApp inclusion
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __APPH_BASE__
+#define __APPH_BASE__
+
+/*
+class WXDLLEXPORT wxApp;
+typedef wxApp* (*wxAppInitializerFunction) (void);
+*/
+
+#include "wx/object.h"
+
+typedef wxObject* (*wxAppInitializerFunction) (void);  // returning wxApp* won't work with gcc
+
+#if defined(__WINDOWS__)
+#include "wx/msw/app.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/app.h"
+#elif defined(__GTK__)
+#include "wx/gtk/app.h"
+#endif
+
+
+// Having a global instance of this class allows
+// wxApp to be aware of the app creator function.
+// wxApp can then call this function to create a new
+// app object. Convoluted, but necessary.
+
+class WXDLLEXPORT wxAppInitializer
+{
+public:
+	wxAppInitializer(wxAppInitializerFunction fn)
+	{
+		wxApp::SetInitializerFunction(fn);
+	}
+};
+
+#define IMPLEMENT_APP(appname)                          \
+        wxApp *wxCreateApp(void) { return new appname; }      \
+		wxAppInitializer wxTheAppInitializer((wxAppInitializerFunction) wxCreateApp); \
+        appname& wxGetApp(void) { return *(appname *)wxTheApp; } \
+\
+        extern int wxEntry( int argc, char *argv[] ); \
+        int main(int argc, char *argv[]) { return wxEntry(argc, argv); }
+
+
+#define DECLARE_APP(appname) \
+	extern appname& wxGetApp(void) ;
+
+
+#endif
+    // __APPH_BASE__
diff --git a/include/wx/bitmap.h b/include/wx/bitmap.h
new file mode 100644
index 0000000000..b3cf33ce7f
--- /dev/null
+++ b/include/wx/bitmap.h
@@ -0,0 +1,13 @@
+#ifndef __BITMAPH_BASE__
+#define __BITMAPH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/bitmap.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/bitmap.h"
+#elif defined(__GTK__)
+#include "wx/gtk/bitmap.h"
+#endif
+
+#endif
+    // __BITMAPH_BASE__
diff --git a/include/wx/bmpbuttn.h b/include/wx/bmpbuttn.h
new file mode 100644
index 0000000000..0f9e160d64
--- /dev/null
+++ b/include/wx/bmpbuttn.h
@@ -0,0 +1,12 @@
+#ifndef __BMPBUTTONH_BASE__
+#define __BMPBUTTONH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/bmpbuttn.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/bmpbuttn.h"
+#elif defined(__GTK__)
+#include "wx/gtk/bmpbuttn.h"
+#endif
+
+#endif
diff --git a/include/wx/brush.h b/include/wx/brush.h
new file mode 100644
index 0000000000..bc05548735
--- /dev/null
+++ b/include/wx/brush.h
@@ -0,0 +1,13 @@
+#ifndef __BRUSHH_BASE__
+#define __BRUSHH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/brush.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/brush.h"
+#elif defined(__GTK__)
+#include "wx/gtk/brush.h"
+#endif
+
+#endif
+    // __BRUSHH_BASE__
diff --git a/include/wx/button.h b/include/wx/button.h
new file mode 100644
index 0000000000..950435db03
--- /dev/null
+++ b/include/wx/button.h
@@ -0,0 +1,13 @@
+#ifndef __BUTTONH_BASE__
+#define __BUTTONH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/button.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/button.h"
+#elif defined(__GTK__)
+#include "wx/gtk/button.h"
+#endif
+
+#endif
+    // __BUTTONH_BASE__
diff --git a/include/wx/checkbox.h b/include/wx/checkbox.h
new file mode 100644
index 0000000000..e4868ee671
--- /dev/null
+++ b/include/wx/checkbox.h
@@ -0,0 +1,13 @@
+#ifndef __CHECKBOXH_BASE__
+#define __CHECKBOXH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/checkbox.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/checkbox.h"
+#elif defined(__GTK__)
+#include "wx/gtk/checkbox.h"
+#endif
+
+#endif
+    // __CHECKBOXH_BASE__
diff --git a/include/wx/choicdlg.h b/include/wx/choicdlg.h
new file mode 100644
index 0000000000..88153df70e
--- /dev/null
+++ b/include/wx/choicdlg.h
@@ -0,0 +1,7 @@
+#ifndef __CHOICDLGH_BASE__
+#define __CHOICDLGH_BASE__
+
+#include "wx/generic/choicdgg.h"
+
+#endif
+    // __CHOICDLGH_BASE__
diff --git a/include/wx/choice.h b/include/wx/choice.h
new file mode 100644
index 0000000000..5a421268ed
--- /dev/null
+++ b/include/wx/choice.h
@@ -0,0 +1,13 @@
+#ifndef __CHOICEH_BASE__
+#define __CHOICEH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/choice.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/choice.h"
+#elif defined(__GTK__)
+#include "wx/gtk/choice.h"
+#endif
+
+#endif
+    // __CHOICEH_BASE__
diff --git a/include/wx/clipbrd.h b/include/wx/clipbrd.h
new file mode 100644
index 0000000000..f5e8571912
--- /dev/null
+++ b/include/wx/clipbrd.h
@@ -0,0 +1,13 @@
+#ifndef __CLIPBRDH_BASE__
+#define __CLIPBRDH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/clipbrd.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/clipbrd.h"
+#elif defined(__GTK__)
+#include "wx/gtk/clipbrd.h"
+#endif
+
+#endif
+    // __CLIPBRDH_BASE__
diff --git a/include/wx/cmndata.h b/include/wx/cmndata.h
new file mode 100644
index 0000000000..abb8c5da51
--- /dev/null
+++ b/include/wx/cmndata.h
@@ -0,0 +1,223 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        cmndata.h
+// Purpose:     Common GDI data classes
+// Author:      Julian Smart and others
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c)
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __CMNDATAH_BASE__
+#define __CMNDATAH_BASE__
+
+#ifdef __GNUG__
+#pragma interface "cmndata.h"
+#endif
+
+class WXDLLEXPORT wxColourData: public wxObject
+{
+ DECLARE_DYNAMIC_CLASS(wxColourData)
+ public:
+  wxColour dataColour;
+  wxColour custColours[16];
+  bool chooseFull;
+
+  wxColourData(void);
+  ~wxColourData(void);
+
+  inline void SetChooseFull(bool flag) { chooseFull = flag; }
+  inline bool GetChooseFull(void) { return chooseFull; }
+  inline void SetColour(wxColour& colour) { dataColour = colour; }
+  inline wxColour &GetColour(void) { return dataColour; } 
+
+  // Array of 16 custom colours
+  void SetCustomColour(int i, wxColour& colour);
+  wxColour GetCustomColour(int i);
+
+  void operator=(const wxColourData& data);
+};
+
+class WXDLLEXPORT wxFontData: public wxObject
+{
+ DECLARE_DYNAMIC_CLASS(wxFontData)
+ public:
+  wxColour fontColour;
+  bool showHelp;
+  bool allowSymbols;
+  bool enableEffects;
+  wxFont initialFont;
+  wxFont chosenFont;
+  int minSize;
+  int maxSize;
+
+  wxFontData(void);
+  ~wxFontData(void);
+
+  inline void SetAllowSymbols(bool flag) { allowSymbols = flag; }
+  inline bool GetAllowSymbols(void) { return allowSymbols; }
+  inline void SetColour(const wxColour& colour) { fontColour = colour; }
+  inline wxColour &GetColour(void) { return fontColour; }
+  inline void SetShowHelp(bool flag) { showHelp = flag; }
+  inline bool GetShowHelp(void) { return showHelp; }
+  inline void EnableEffects(bool flag) { enableEffects = flag; }
+  inline bool GetEnableEffects(void) { return enableEffects; }
+  inline void SetInitialFont(const wxFont& font) { initialFont = font; }
+  inline wxFont GetInitialFont(void) { return initialFont; }
+  inline void SetChosenFont(const wxFont& font) { chosenFont = font; }
+  inline wxFont GetChosenFont(void) { return chosenFont; }
+  inline void SetRange(int minRange, int maxRange) { minSize = minRange; maxSize = maxRange; }
+
+  void operator=(const wxFontData& data);
+};
+
+/*
+ * wxPrintData
+ * Encapsulates information displayed and edited in the printer dialog box.
+ */
+ 
+class WXDLLEXPORT wxPrintData: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxPrintData)
+
+ public:
+#ifdef __WINDOWS__
+  void *printData;
+#endif
+  int printFromPage;
+  int printToPage;
+  int printMinPage;
+  int printMaxPage;
+  int printNoCopies;
+  int printOrientation;
+  bool printAllPages;
+  bool printCollate;
+  bool printToFile;
+  bool printEnableSelection;
+  bool printEnablePageNumbers;
+  bool printEnableHelp;
+  bool printEnablePrintToFile;
+  bool printSetupDialog;
+
+  wxPrintData(void);
+  ~wxPrintData(void);
+
+  inline int GetFromPage(void) { return printFromPage; };
+  inline int GetToPage(void) { return printToPage; };
+  inline int GetMinPage(void) { return printMinPage; };
+  inline int GetMaxPage(void) { return printMaxPage; };
+  inline int GetNoCopies(void) { return printNoCopies; };
+  inline bool GetAllPages(void) { return printAllPages; };
+  inline bool GetCollate(void) { return printCollate; };
+  inline bool GetPrintToFile(void) { return printToFile; };
+  inline bool GetSetupDialog(void) { return printSetupDialog; };
+  inline int  GetOrientation(void) { return printOrientation; };
+
+  inline void SetFromPage(int v) { printFromPage = v; };
+  inline void SetToPage(int v) { printToPage = v; };
+  inline void SetMinPage(int v) { printMinPage = v; };
+  inline void SetMaxPage(int v) { printMaxPage = v; };
+  inline void SetNoCopies(int v) { printNoCopies = v; };
+  inline void SetAllPages(bool flag) { printAllPages = flag; };
+  inline void SetCollate(bool flag) { printCollate = flag; };
+  inline void SetPrintToFile(bool flag) { printToFile = flag; };
+  inline void SetSetupDialog(bool flag) { printSetupDialog = flag; };
+  inline void SetOrientation(int orient) { printOrientation = orient; };
+
+  inline void EnablePrintToFile(bool flag) { printEnablePrintToFile = flag; };
+  inline void EnableSelection(bool flag) { printEnableSelection = flag; };
+  inline void EnablePageNumbers(bool flag) { printEnablePageNumbers = flag; };
+  inline void EnableHelp(bool flag) { printEnableHelp = flag; };
+
+  inline bool GetEnablePrintToFile(void) { return printEnablePrintToFile; };
+  inline bool GetEnableSelection(void) { return printEnableSelection; };
+  inline bool GetEnablePageNumbers(void) { return printEnablePageNumbers; };
+  inline bool GetEnableHelp(void) { return printEnableHelp; };
+
+  void operator=(const wxPrintData& data);
+
+#ifdef __WINDOWS__
+  // Convert to/from the PRINTDLG structure
+  void ConvertToNative(void);
+  void ConvertFromNative(void);
+  void SetOwnerWindow(wxWindow* win);
+  inline void* GetNativeData(void) { return printData; }
+#endif
+};
+
+/*
+ * This is the data used (and returned) by the wxPageSetupDialog.
+ */
+
+class WXDLLEXPORT wxPageSetupData: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxPageSetupData)
+
+ public:
+#if defined(__WIN95__)
+  void*     m_pageSetupData;
+#endif
+  wxPoint   m_paperSize;
+  wxPoint   m_minMarginTopLeft;
+  wxPoint   m_minMarginBottomRight;
+  wxPoint   m_marginTopLeft;
+  wxPoint   m_marginBottomRight;
+  int       m_orientation;
+
+  // Flags
+  bool      m_defaultMinMargins;
+  bool      m_enableMargins;
+  bool      m_enableOrientation;
+  bool      m_enablePaper;
+  bool      m_enablePrinter;
+  bool      m_getDefaultInfo; // Equiv. to PSD_RETURNDEFAULT
+  bool      m_enableHelp;
+
+  wxPageSetupData(void);
+  ~wxPageSetupData(void);
+
+  inline wxPoint GetPaperSize(void) { return m_paperSize; };
+  inline wxPoint GetMinMarginTopLeft(void) { return m_minMarginTopLeft; };
+  inline wxPoint GetMinMarginBottomRight(void) { return m_minMarginBottomRight; };
+  inline wxPoint GetMarginTopLeft(void) { return m_marginTopLeft; };
+  inline wxPoint GetMarginBottomRight(void) { return m_marginBottomRight; };
+  inline int GetOrientation(void) { return m_orientation; };
+
+  inline bool GetDefaultMinMargins(void) { return m_defaultMinMargins; };
+  inline bool GetEnableMargins(void) { return m_enableMargins; };
+  inline bool GetEnableOrientation(void) { return m_enableOrientation; };
+  inline bool GetEnablePaper(void) { return m_enablePaper; };
+  inline bool GetEnablePrinter(void) { return m_enablePrinter; };
+  inline bool GetDefaultInfo(void) { return m_getDefaultInfo; };
+  inline bool GetEnableHelp(void) { return m_enableHelp; };
+
+  inline void SetPaperSize(const wxPoint& pt) { m_paperSize = pt; };
+  inline void SetMinMarginTopLeft(const wxPoint& pt) { m_minMarginTopLeft = pt; };
+  inline void SetMinMarginBottomRight(const wxPoint& pt) { m_minMarginBottomRight = pt; };
+  inline void SetMarginTopLeft(const wxPoint& pt) { m_marginTopLeft = pt; };
+  inline void SetMarginBottomRight(const wxPoint& pt) { m_marginBottomRight = pt; };
+  inline void SetOrientation(int orient) { m_orientation = orient; };
+  inline void SetDefaultMinMargins(bool flag) { m_defaultMinMargins = flag; };
+  inline void SetDefaultInfo(bool flag) { m_getDefaultInfo = flag; };
+
+  inline void EnableMargins(bool flag) { m_enableMargins = flag; };
+  inline void EnableOrientation(bool flag) { m_enableOrientation = flag; };
+  inline void EnablePaper(bool flag) { m_enablePaper = flag; };
+  inline void EnablePrinter(bool flag) { m_enablePrinter = flag; };
+  inline void EnableHelp(bool flag) { m_enableHelp = flag; };
+
+#if defined(__WIN95__)
+  // Convert to/from the PAGESETUPDLG structure
+  void ConvertToNative(void);
+  void ConvertFromNative(void);
+  void SetOwnerWindow(wxWindow* win);
+  inline void* GetNativeData(void) { return m_pageSetupData; }
+#endif
+
+  void operator=(const wxPageSetupData& data);
+};
+
+
+#endif
+    // __CMNDATAH_BASE__
diff --git a/include/wx/colordlg.h b/include/wx/colordlg.h
new file mode 100644
index 0000000000..8e113d039e
--- /dev/null
+++ b/include/wx/colordlg.h
@@ -0,0 +1,13 @@
+#ifndef __COLORDLGH_BASE__
+#define __COLORDLGH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/colordlg.h"
+#elif defined(__MOTIF__)
+#include "wx/generic/colrdlgg.h"
+#elif defined(__GTK__)
+#include "wx/generic/colrdlgg.h"
+#endif
+
+#endif
+    // __COLORDLGH_BASE__
diff --git a/include/wx/combobox.h b/include/wx/combobox.h
new file mode 100644
index 0000000000..e21e3af6ec
--- /dev/null
+++ b/include/wx/combobox.h
@@ -0,0 +1,13 @@
+#ifndef __COMBOBOXH_BASE__
+#define __COMBOBOXH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/combobox.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/combobox.h"
+#elif defined(__GTK__)
+#include "wx/gtk/combobox.h"
+#endif
+
+#endif
+    // __COMBOBOXH_BASE__
diff --git a/include/wx/config.h b/include/wx/config.h
new file mode 100644
index 0000000000..e7278dfd32
--- /dev/null
+++ b/include/wx/config.h
@@ -0,0 +1,121 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        
+// Purpose:     
+// Author:      Karsten Ballüder & Vadim Zeitlin
+// Modified by: 
+// Created:     07.04.98 (adapted from appconf.h)
+// RCS-ID:      $Id$
+// Copyright:   (c) 1997 Karsten Ballüder   Ballueder@usa.net  
+//                       Vadim Zeitlin      <zeitlin@dptmaths.ens-cachan.fr>
+// Licence:     wxWindows license
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef   _APPCONF_H
+#define   _APPCONF_H
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+/// shall we be case sensitive in parsing variable names?
+#ifndef APPCONF_CASE_SENSITIVE
+  #define  APPCONF_CASE_SENSITIVE       FALSE
+#endif
+
+/// separates group and entry names
+#ifndef APPCONF_PATH_SEPARATOR
+  #define   APPCONF_PATH_SEPARATOR     '/'
+#endif
+
+/// introduces immutable entries
+#ifndef APPCONF_IMMUTABLE_PREFIX
+  #define   APPCONF_IMMUTABLE_PREFIX   '!'
+#endif
+
+/// should we use registry instead of configuration files under Win32?
+#ifndef   APPCONF_WIN32_NATIVE
+  #define APPCONF_WIN32_NATIVE          TRUE
+#endif
+
+// ----------------------------------------------------------------------------
+// global functions
+// ----------------------------------------------------------------------------
+
+/*
+  Replace environment variables ($SOMETHING) with their values. The format is
+  $VARNAME or ${VARNAME} where VARNAME contains alphanumeric characters and
+  '_' only. '$' must be escaped ('\$') in order to be taken literally.
+*/
+wxString ExpandEnvVars(const wxString& str);
+
+// ----------------------------------------------------------------------------
+// abstract base class wxConfig which defines the interface for derived classes
+//
+// wxConfig organizes the items in a tree-like structure (modeled after the 
+// Unix/Dos filesystem). There are groups (directories) and keys (files). 
+// There is always one current group given by the current path.
+//
+// Keys are pairs "key_name = value" where value may be of string or integer
+// (long) type (@@@ doubles and other types such as wxDate coming soon).
+// ----------------------------------------------------------------------------
+class wxConfig
+{
+public:
+  // ctor & virtual dtor
+  wxConfig() { }
+  virtual ~wxConfig();
+
+  // path management
+    // set current path: if the first character is '/', it's the absolute path,
+    // otherwise it's a relative path. '..' is supported. If the strPath 
+    // doesn't exist it is created.
+  virtual void SetPath(const wxString& strPath) = 0;
+    // retrieve the current path (always as absolute path)
+  virtual const wxString& GetPath() const = 0;
+
+  // enumeration: all functions here return false when there are no more items.
+  // you must pass the same lIndex to GetNext and GetFirst (don't modify it)
+    // enumerate subgroups
+  virtual bool GetFirstGroup(wxString& str, long& lIndex) = 0;
+  virtual bool GetNextGroup (wxString& str, long& lIndex) = 0;
+    // enumerate entries
+  virtual bool GetFirstEntry(wxString& str, long& lIndex) = 0;
+  virtual bool GetNextEntry (wxString& str, long& lIndex) = 0;
+
+  // key access
+    // read a string or long value from the key. If the key is not
+    // found the default value is returned.
+    virtual const char *Read(const char *szKey,
+                             const char *szDefault = NULL) const = 0;
+    virtual long Read(const char *szKey, long lDefault) const = 0;
+
+    // write the value (return true on success)
+  virtual bool Write(const char *szKey, const char *szValue) = 0;
+  virtual bool Write(const char *szKey, long lValue) = 0;
+    // permanently writes all changes
+  virtual bool Flush(bool bCurrentOnly = FALSE) = 0;
+
+  // delete entries/groups
+    // deletes the specified entry and the group it belongs to if
+    // it was the last key in it and the second parameter is true
+  virtual bool DeleteEntry(const char *szKey,
+                           bool bDeleteGroupIfEmpty = TRUE) = 0;
+    // delete the group (with all subgroups)
+  virtual bool DeleteGroup(const char *szKey) = 0;
+    // delete the whole underlying object (disk file, registry key, ...)
+    // primarly for use by desinstallation routine.
+  virtual bool DeleteAll() = 0;
+
+protected:
+  // true if environment variables are to be auto-expanded
+  bool m_bExpandEnvVars;
+};
+
+// ----------------------------------------------------------------------------
+// functions to create different config implementations
+// ----------------------------------------------------------------------------
+
+wxConfig *CreateFileConfig(const wxString& strFile, bool bLocalOnly = FALSE);
+
+#endif  //_APPCONF_H
+
diff --git a/include/wx/control.h b/include/wx/control.h
new file mode 100644
index 0000000000..bb5003ae20
--- /dev/null
+++ b/include/wx/control.h
@@ -0,0 +1,13 @@
+#ifndef __CONTROLH_BASE__
+#define __CONTROLH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/control.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/control.h"
+#elif defined(__GTK__)
+#include "wx/gtk/control.h"
+#endif
+
+#endif
+    // __CONTROLH_BASE__
diff --git a/include/wx/cursor.h b/include/wx/cursor.h
new file mode 100644
index 0000000000..b56d15ec5b
--- /dev/null
+++ b/include/wx/cursor.h
@@ -0,0 +1,13 @@
+#ifndef __CURSORH_BASE__
+#define __CURSORH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/cursor.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/cursor.h"
+#elif defined(__GTK__)
+#include "wx/gtk/cursor.h"
+#endif
+
+#endif
+    // __CURSORH_BASE__
diff --git a/include/wx/date.h b/include/wx/date.h
new file mode 100644
index 0000000000..2347dad445
--- /dev/null
+++ b/include/wx/date.h
@@ -0,0 +1,131 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        date.h
+// Purpose:     wxDate class
+// Author:      Julian Smart, Steve Marcus, Eric Simon, Chris Hill,
+//              Charles D. Price
+// Modified by:	
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c)
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __WXDATEH__
+#define __WXDATEH__
+
+#ifdef __GNUG__
+#pragma interface "date.h"
+#endif
+
+#include "wx/object.h"
+#include "wx/string.h"
+
+#if USE_TIMEDATE
+
+enum wxdate_format_type {wxMDY, wxDAY, wxMONTH, wxFULL, wxEUROPEAN};
+
+#define wxNO_CENTURY  0x02
+#define wxDATE_ABBR   0x04
+
+class WXDLLEXPORT wxDate: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxDate)
+ protected:
+   unsigned long julian; // see julDate();  days since 1/1/4713 B.C.
+   int month;            // see NMonth()
+   int day;              // see Day()
+   int year;             // see NYear4()
+   int day_of_week;      // see NDOW();  1 = Sunday, ... 7 = Saturday
+
+ private:
+  int  		 DisplayFormat;
+  unsigned char DisplayOptions;
+
+  void julian_to_mdy ();         // convert julian day to mdy
+  void julian_to_wday ();        // convert julian day to day_of_week
+  void mdy_to_julian ();         // convert mdy to julian day
+
+ public:
+  wxDate ();
+  wxDate (const long j);
+  wxDate (const int m, const int d, const int y);
+  wxDate (const wxString& dat);
+  wxDate (const wxDate &dt);
+
+  operator wxString  (void);
+  void operator =   (const wxDate& date);
+  void operator =   (const wxString& date);
+
+  wxDate operator +  (const long i);
+  wxDate operator +  (const int  i);
+
+  wxDate operator -  (const long i);
+  wxDate operator -  (const int  i);
+
+  long operator -  (const wxDate &dt);
+
+  wxDate &operator += (const long i);
+  wxDate &operator -= (const long i);
+
+  wxDate &operator ++ ();     // Prefix increment
+  wxDate &operator ++ (int);  // Postfix increment
+  wxDate &operator -- ();     // Prefix decrement
+  wxDate &operator -- (int);  // Postfix decrement
+
+  friend bool operator <  (const wxDate &dt1, const wxDate &dt2);
+  friend bool operator <= (const wxDate &dt1, const wxDate &dt2);
+  friend bool operator >  (const wxDate &dt1, const wxDate &dt2);
+  friend bool operator >= (const wxDate &dt1, const wxDate &dt2);
+  friend bool operator == (const wxDate &dt1, const wxDate &dt2);
+  friend bool operator != (const wxDate &dt1, const wxDate &dt2);
+
+  friend ostream &operator << (ostream &os, const wxDate &dt);
+
+  wxString FormatDate 	   (const int type=-1) const;
+  void  SetFormat (const int format);
+  int   SetOption (const int option, const bool enable=TRUE);
+
+  long  GetJulianDate() const;  // returns julian date
+  int   GetDayOfYear()  const;  // returns relative date since Jan. 1
+  bool  IsLeapYear()    const;  // returns TRUE if leap year, FALSE if not
+
+  // Version 4.0 Extension to Public Interface - CDP
+  
+  // These 'Set's modify the date object and actually SET it
+  // They all return a reference to self (*this)
+
+  wxDate &Set();            // Sets to current system date
+  wxDate &Set(long lJulian);
+  wxDate &Set(int nMonth, int nDay, int nYear);
+
+  wxDate &AddWeeks(int nCount = 1);  // 
+  wxDate &AddMonths(int nCount = 1); // May also pass neg# to decrement
+  wxDate &AddYears(int nCount = 1);  //
+
+  int   GetDay() const;      // Numeric Day of date object
+  int   GetDaysInMonth();    // Number of days in month (1..31)
+  int   GetFirstDayOfMonth() const; // First Day Of Month  (1..7)
+
+  wxString GetDayOfWeekName();       // Character Day Of Week ('Sunday'..'Saturday')
+  int   GetDayOfWeek() const;     // (1..7)
+
+  int   GetWeekOfMonth();            // Numeric Week Of Month  (1..6)
+  int   GetWeekOfYear();            // Numeric Week Of Year   (1..52)
+
+  wxString GetMonthName();            // Character Month name
+  int   GetMonth() const;          // Month Number (1..12)
+  wxDate  GetMonthStart();         // First Date Of Month
+  wxDate  GetMonthEnd();           // Last Date Of Month
+
+  int   GetYear() const;           // eg. 1992
+  wxDate  GetYearStart();          // First Date Of Year
+  wxDate  GetYearEnd();            // Last Date Of Year
+
+  bool IsBetween(const wxDate& first, const wxDate& second) const;
+
+  wxDate Previous(const int dayOfWeek) const;
+};
+
+#endif
+#endif
+    // __WXDATEH__
diff --git a/include/wx/dc.h b/include/wx/dc.h
new file mode 100644
index 0000000000..be0b417d98
--- /dev/null
+++ b/include/wx/dc.h
@@ -0,0 +1,13 @@
+#ifndef __DCH_BASE__
+#define __DCH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/dc.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/dc.h"
+#elif defined(__GTK__)
+#include "wx/gtk/dc.h"
+#endif
+
+#endif
+    // __DCH_BASE__
diff --git a/include/wx/dcclient.h b/include/wx/dcclient.h
new file mode 100644
index 0000000000..795f9d0c8d
--- /dev/null
+++ b/include/wx/dcclient.h
@@ -0,0 +1,13 @@
+#ifndef __DCCLIENTH_BASE__
+#define __DCCLIENTH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/dcclient.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/dcclient.h"
+#elif defined(__GTK__)
+#include "wx/gtk/dcclient.h"
+#endif
+
+#endif
+    // __DCCLIENTH_BASE__
diff --git a/include/wx/dcmemory.h b/include/wx/dcmemory.h
new file mode 100644
index 0000000000..256db8c2f9
--- /dev/null
+++ b/include/wx/dcmemory.h
@@ -0,0 +1,13 @@
+#ifndef __DCMEMORYH_BASE__
+#define __DCMEMORYH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/dcmemory.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/dcmemory.h"
+#elif defined(__GTK__)
+#include "wx/gtk/dcmemory.h"
+#endif
+
+#endif
+    // __DCMEMORYH_BASE__
diff --git a/include/wx/dcprint.h b/include/wx/dcprint.h
new file mode 100644
index 0000000000..d84dd73ad8
--- /dev/null
+++ b/include/wx/dcprint.h
@@ -0,0 +1,9 @@
+#ifndef __DCPRINTH_BASE__
+#define __DCPRINTH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/dcprint.h"
+#endif
+
+#endif
+    // __DCPRINTH_BASE__
diff --git a/include/wx/dcscreen.h b/include/wx/dcscreen.h
new file mode 100644
index 0000000000..9dde7580d3
--- /dev/null
+++ b/include/wx/dcscreen.h
@@ -0,0 +1,13 @@
+#ifndef __DCSCREENH_BASE__
+#define __DCSCREENH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/dcscreen.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/dcscreen.h"
+#elif defined(__GTK__)
+#include "wx/gtk/dcscreen.h"
+#endif
+
+#endif
+    // __DCSCREENH_BASE__
diff --git a/include/wx/dde.h b/include/wx/dde.h
new file mode 100644
index 0000000000..e103c7882e
--- /dev/null
+++ b/include/wx/dde.h
@@ -0,0 +1,13 @@
+#ifndef __DDEH_BASE__
+#define __DDEH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/dde.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/dde.h"
+#elif defined(__GTK__)
+#include "wx/gtk/dde.h"
+#endif
+
+#endif
+    // __DDEH_BASE__
diff --git a/include/wx/debug.h b/include/wx/debug.h
new file mode 100644
index 0000000000..029790e47d
--- /dev/null
+++ b/include/wx/debug.h
@@ -0,0 +1,94 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        debug.h
+// Purpose:     Misc debug functions and macros
+// Author:      Vadim Zeitlin
+// Modified by:
+// Created:     29/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef   __DEBUGH__
+#define   __DEBUGH__
+
+#include  <assert.h>
+
+// ----------------------------------------------------------------------------
+/** 
+  @name Debugging macros 
+
+  All debugging macros rely on ASSERT() which in turn calls user-defined
+  OnAssert() function. To keep things simple, it's called even when the
+  expression is TRUE (i.e. everything is ok) and by default does nothing: just
+  returns the same value back. But if you redefine it to do something more sexy
+  (popping up a message box in your favourite GUI, sending you e-mail or 
+  whatever) it will affect all ASSERTs, FAILs and CHECKs in your code.
+  <BR>
+  <BR>
+  <b>Warning</b>: if you don't like advices on programming style, don't read 
+  further! ;-)
+  <BR>
+  <BR>
+  Extensive use of these macros is recommended! Remember that ASSERTs are
+  disabled in final (without DEBUG defined) build, so they add strictly
+  nothing to your program's code. On the other hand, CHECK macros do stay
+  even in release builds, but in general are not much of a burden, while
+  a judicious use of them might increase your program's stability.
+
+  @memo Debugging macros (replacement for standard assert()) and more.
+  */
+// ----------------------------------------------------------------------------
+//@{
+
+/** @name Macros which are completely disabled in 'release' mode */
+//@{
+#ifdef  __DEBUG__
+  /**
+  this function may be redefined to do something non trivial and is called
+  whenever one of debugging macros fails (i.e. condition is false in an
+  assertion)
+  @param   szFile and nLine - file name and line number of the ASSERT
+           szMsg            - optional message explaining the reason
+  */
+  void wxOnAssert(const char *szFile, int nLine, const char *szMsg = NULL);
+
+  /// generic assert macro
+  #define   wxASSERT(cond)   if ( !(cond) ) wxOnAssert(__FILE__, __LINE__)
+  /// assert with additional message explaining it's cause 
+  #define   wxASSERT_MSG(x, m)  if ( !(x) ) wxOnAssert(__FILE__, __LINE__, m)
+#else
+  // nothing to do in release modes (hopefully at this moment there are
+  // no more bugs ;-)
+  #define   wxASSERT(cond)
+  #define   wxASSERT_MSG(x, m)
+#endif  //DEBUG
+
+  /// special form of assert: always triggers it (in debug mode)
+#define   wxFAIL                 wxASSERT(0)
+  /// FAIL with some message
+#define   wxFAIL_MSG(msg)        wxASSERT_MSG(0, msg)
+//@}
+
+// NB: these macros work also in release mode!
+
+/** 
+  These macros must be used only in invalid situation: for example, an
+  invalid parameter (NULL pointer) is passed to a function. Instead of
+  dereferencing it and causing core dump the function might try using
+  CHECK( p != NULL ) or CHECK( p != NULL, return LogError("p is NULL!!") )
+
+  @name Macros which remain even in 'release' mode 
+*/
+//@{
+  /// check that expression is true, "return" if not (also FAILs in debug mode)
+#define   wxCHECK(x)             if (!(x)) {wxFAIL; return; }
+  /// check that expression is true, "return ret" if not
+#define   wxCHECK_RET(x, ret)    if (!(x)) {wxFAIL; return ret; }
+  /// check that expression is true, perform op if not
+#define   wxCHECK2(x, op)        if (!(x)) {wxFAIL; op; }
+//@}
+
+//@}
+
+#endif  // __DEBUGH__
\ No newline at end of file
diff --git a/include/wx/defs.h b/include/wx/defs.h
new file mode 100644
index 0000000000..20ef449029
--- /dev/null
+++ b/include/wx/defs.h
@@ -0,0 +1,861 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        defs.h
+// Purpose:     Declarations/definitions common to all wx source files
+// Author:      Julian Smart and others
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c)
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __DEFSH__
+#define __DEFSH__
+
+#ifdef __GNUG__
+#pragma interface "defs.h"
+#endif
+
+#ifdef __GTK__
+
+#include "glib.h"
+#include "gdk/gdk.h"
+#include "gtk/gtk.h"
+
+#endif
+
+#include <stddef.h>
+
+#include "wx/setup.h"
+#include "wx/version.h"
+
+// Helps SGI compilation, apparently
+#if defined(__SGI__) && defined(__GNUG__)
+#define __need_wchar_t
+#endif
+
+// Eliminate double/float warnings
+#ifdef _MSC_VER
+# pragma warning(disable:4244)
+#endif
+
+
+//////////////////////////////////////////////////////////////////////////////////
+// Currently Only MS-Windows/NT, XView and Motif are supported
+//
+#if defined(__HPUX__) && !defined(__MOTIF__)
+# define __MOTIF__
+#endif
+#if defined(__MOTIF__)
+# define __X__
+#elif defined(__WINDOWS__) || defined(__WINDOWS_386__) || defined(__NT__) || defined(__MSDOS__) 
+# ifndef __WINDOWS__
+#  define __WINDOWS__
+# endif
+#endif
+
+// wxWindows checks for WIN32, not __WIN32__
+#if ((defined(WIN32) || defined(__NT__)) && !defined(__WIN32__))
+#define __WIN32__
+#endif
+
+#ifndef __WIN32__
+#define __WIN16__
+#endif
+
+#if !defined(__WIN95__) && (WINVER >= 0x0400)
+#define __WIN95__
+#endif
+
+// Make sure the environment is set correctly
+#if defined(__WINDOWS__) && defined(__X__)
+# error "Target can't be both X and Windows"
+#elif !defined(__MOTIF__) && !defined(__WINDOWS__) && !defined(__GTK__) && !defined(__MAC__) && !defined(__X__)
+#error "No Target! Use -D[__MOTIF__|__GTK__|__WINDOWS__|__MAC__]"
+#endif
+
+#if defined(__MOTIF__) || defined(__GTK__)
+
+// Bool is now obsolete, use bool instead
+// typedef int Bool;
+
+#ifndef TRUE
+# define TRUE  1
+# define FALSE 0
+# define Bool_DEFINED
+#endif
+
+#elif defined(__WINDOWS__)
+
+#ifndef TRUE
+# define TRUE  1
+# define FALSE 0
+#endif
+
+#endif
+
+// VC++ 4.0 is 1000.
+
+// Add more tests here for compilers that don't already define bool.
+#if ( defined(_MSC_VER) && (_MSC_VER <= 1000) ) || (defined(__BORLANDC__) && (__BORLANDC__ < 0x500))
+typedef unsigned int bool;
+#endif
+
+#if ( defined(_MSC_VER) && (_MSC_VER <= 800) ) || defined(__GNUWIN32__)
+#define byte unsigned char
+#endif
+
+typedef short int WXTYPE;
+typedef int wxWindowID;
+
+// Macro to cut down on compiler warnings.
+#if REMOVE_UNUSED_ARG
+#define WXUNUSED(identifier) /* identifier */
+#else  // stupid, broken compiler
+#define WXUNUSED(identifier) identifier
+#endif
+
+/*
+ * Making or using wxWindows as a Windows DLL
+ */
+
+#ifdef __WINDOWS__
+
+#ifdef __BORLANDC__
+
+#  ifdef WXMAKINGDLL
+#    define WXDLLEXPORT __export
+#    define WXDLLEXPORT_DATA(type) type __export
+#    define WXDLLEXPORT_CTORFN __export
+#  elif defined(WXUSINGDLL)
+#    define WXDLLEXPORT __import
+#    define WXDLLEXPORT_DATA(type) type __import
+#    define WXDLLEXPORT_CTORFN
+#  else
+#    define WXDLLEXPORT
+#    define WXDLLEXPORT_DATA(type) type
+#    define WXDLLEXPORT_CTORFN
+#  endif
+
+#else
+
+#  ifdef WXMAKINGDLL
+#    define WXDLLEXPORT __declspec( dllexport )
+#    define WXDLLEXPORT_DATA(type) __declspec( dllexport ) type
+#    define WXDLLEXPORT_CTORFN __declspec( dllexport )
+#  elif defined(WXUSINGDLL)
+#    define WXDLLEXPORT __declspec( dllimport )
+#    define WXDLLEXPORT_DATA(type) __declspec( dllimport ) type
+#    define WXDLLEXPORT_CTORFN
+#  else
+#    define WXDLLEXPORT
+#    define WXDLLEXPORT_DATA(type) type
+#    define WXDLLEXPORT_CTORFN
+#  endif
+
+#endif
+
+#else
+// Non-Windows
+#  define WXDLLEXPORT
+#  define WXDLLEXPORT_DATA(type) type
+#  define WXDLLEXPORT_CTORFN
+#endif
+
+// For ostream, istream ofstream
+#if defined(__BORLANDC__) && defined( _RTLDLL )
+#  define WXDLLIMPORT __import
+#else
+#  define WXDLLIMPORT
+#endif
+
+class WXDLLEXPORT wxObject;
+class WXDLLEXPORT wxEvent;
+
+// Vadim's types - check whether we need them all
+
+/// the type for various indexes (string, arrays, ...)
+typedef unsigned int    uint;
+
+/// extended boolean type: { yes, no, may be }
+typedef signed   int    EBool;
+
+/// with TRUE and FALSE is a possible value for a "3-state" boolean var
+#define UNKNOWN         (-1)
+  /** symbolic constant used by all Find()-like functions returning positive
+      integer on success as failure indicator */
+#define NOT_FOUND       (-1)
+  /** useful for Windows programmers: makes somewhat more clear all these 
+      zeroes being passed to Windows APIs */
+#define RESERVED        (NULL)
+
+// ----------------------------------------------------------------------------
+// Error codes
+// ----------------------------------------------------------------------------
+
+/// Standard error codes
+enum  ErrCode
+{
+  /// invalid parameter (in broad sense)
+  ERR_PARAM = (-4000),
+  /// no more data (iteration functions usually return this)
+  ERR_NODATA,
+  /// user cancelled the operation
+  ERR_CANCEL,
+  /// no error (the only non negative error code)
+  ERR_SUCCESS = 0
+};
+
+// ----------------------------------------------------------------------------
+/** @name Very common macros */
+// ----------------------------------------------------------------------------
+//@{
+/// delete pointer if it is not NULL
+#define DELETEP(p)      if ( (p) != NULL ) delete (p)
+/// delete array pointer if it is not NULL
+#define DELETEA(p)      if ( (p) != NULL ) delete [] (p)
+
+/// size of statically declared array
+#define WXSIZEOF(array)   (sizeof(array)/sizeof(array[0]))
+
+// ----------------------------------------------------------------------------
+// compiler and OS identification
+// ----------------------------------------------------------------------------
+
+// OS
+#if     defined(__HPUX__) || defined(____SVR4____) || defined(__LINUX__)
+  #ifndef __UNIX__
+    #define __UNIX__
+  #endif
+#endif
+
+#ifndef __UNIX__                     // Windows
+  #ifndef __WINDOWS__
+    #define __WINDOWS__
+  #endif
+
+  #if   defined(_MSC_VER)
+    #define __VISUALC__
+  #elif defined(__BCPLUSPLUS__) && !defined(__BORLANDC__)
+    #define __BORLANDC__
+  #elif defined(__WATCOMC__)
+    //#define __WATCOMC__
+  #elif defined(__SC__)
+    #define __SYMANTECC__
+  #endif  // compiler
+
+#endif  // OS
+
+#if     defined(__UNIX__)
+  #define FILE_PATH_SEPARATOR   ('/')
+#elif   defined(__WINDOWS__)
+  #define FILE_PATH_SEPARATOR   ('\\')
+#else
+  #error "don't know path separator for this platform"
+#endif
+
+// ----------------------------------------------------------------------------
+// compiler specific settings
+// ----------------------------------------------------------------------------
+
+// to allow compiling with warning level 4 under Microsoft Visual C++ some
+// warnings just must be disabled
+#ifdef  __VISUALC__
+  #pragma warning(disable: 4514) // unreferenced inline func has been removed
+/* 
+  you might be tempted to disable this one also: triggered by CHECK and FAIL
+  macros in debug.h, but it's, overall, is a rather useful one, so I leave it
+  and will try to find some way to disable this warning just for CHECK/FAIL.
+  Anyone?
+*/
+  #pragma warning(disable: 4127) // conditional expression is constant
+
+#endif  // VC++
+
+// Callback function type definition
+typedef void (*wxFunction) (wxObject&, wxEvent&);
+
+/*
+ * Window style flags.
+ * Values are chosen so they can be |'ed in a bit list.
+ * Some styles are used across more than one group,
+ * so the values mustn't clash with others in the group.
+ * Otherwise, numbers can be reused across groups.
+ *
+ * From version 1.66:
+ * Window (cross-group) styles now take up the first half
+ * of the flag, and control-specific styles the
+ * second half.
+ * 
+ */
+
+/*
+ * Window (Frame/dialog/subwindow/panel item) style flags
+ */
+#define wxVSCROLL           0x80000000
+#define wxHSCROLL           0x40000000
+#define wxCAPTION           0x20000000
+
+// New styles
+#define wxDOUBLE_BORDER     0x10000000
+#define wxSUNKEN_BORDER     0x08000000
+#define wxRAISED_BORDER     0x04000000
+#define wxBORDER            0x02000000
+#define wxSIMPLE_BORDER     0x02000000
+#define wxSTATIC_BORDER     0x01000000
+#define wxTRANSPARENT_WINDOW 0x00100000
+#define wxNO_BORDER         0x00200000
+
+#define wxUSER_COLOURS      0x00800000
+                                 // Override CTL3D etc. control colour processing to
+                                 // allow own background colour
+                                 // OBSOLETE - use wxNO_CTL3D instead
+#define wxNO_3D             0x00800000
+                                 // Override CTL3D or native 3D styles for children
+#define wxOVERRIDE_KEY_TRANSLATIONS 0x00400000
+                                 // TODO: do we need this??? (Motif only)
+
+// Add this style to a panel to get tab traversal working
+// outside of dialogs.
+#define wxTAB_TRAVERSAL     0x00080000
+
+// Orientations
+#define wxHORIZONTAL     0x01
+#define wxVERTICAL       0x02
+#define wxBOTH           (wxVERTICAL|wxHORIZONTAL)
+#define wxCENTER_FRAME   0x04  /* centering into frame rather than screen */
+
+/*
+ * Frame/dialog style flags
+ */
+#define wxSTAY_ON_TOP       0x8000
+#define wxICONIZE           0x4000
+#define wxMINIMIZE          wxICONIZE
+#define wxMAXIMIZE          0x2000
+#define wxTHICK_FRAME       0x1000
+#define wxSYSTEM_MENU       0x0800
+#define wxMINIMIZE_BOX      0x0400
+#define wxMAXIMIZE_BOX      0x0200
+#define wxTINY_CAPTION_HORIZ 0x0100
+#define wxTINY_CAPTION_VERT 0x0080
+#define wxRESIZE_BOX        wxMAXIMIZE_BOX
+#define wxRESIZE_BORDER	    0x0040
+#define wxDIALOG_MODAL      0x0020
+#define wxDIALOG_MODELESS   0x0000
+
+#define wxDEFAULT_FRAME_STYLE    (wxRESIZE_BORDER | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxTHICK_FRAME | wxSYSTEM_MENU | wxCAPTION)
+
+#if WXWIN_COMPATIBILITY
+#define wxDEFAULT_FRAME wxDEFAULT_FRAME_STYLE
+#endif
+
+#define wxDEFAULT_DIALOG_STYLE	(wxSYSTEM_MENU|wxCAPTION|wxTHICK_FRAME)
+
+/*
+ * Subwindow style flags
+ */
+#define wxRETAINED          0x0001
+#define wxBACKINGSTORE      wxRETAINED
+// wxCanvas or wxPanel can optionally have a thick frame under MS Windows.
+// #define wxTHICK_FRAME       0x1000
+
+/*
+ * wxToolBar style flags
+ */
+ 
+#define wxTB_3DBUTTONS      0x8000
+
+/*
+ * Apply to all panel items
+ */
+ 
+#define wxCOLOURED          0x0800
+// Alignment for panel item labels: replaces characters with zeros
+// when creating label, so spaces can be included in string for alignment.
+#define wxFIXED_LENGTH      0x0400
+#define wxALIGN_LEFT        0x0000
+#define wxALIGN_CENTER      0x0100
+#define wxALIGN_CENTRE      0x0100
+#define wxALIGN_RIGHT       0x0200
+
+/*
+ * Styles for wxListBox
+ */
+
+// In wxListBox style flag
+#define wxSB_MASK           0x0008
+#define wxNEEDED_SB         0x0000
+#define wxALWAYS_SB         0x0008
+
+// New naming convention
+#define wxLB_NEEDED_SB      wxNEEDED_SB
+#define wxLB_ALWAYS_SB      wxALWAYS_SB
+#define wxLB_SORT           0x0010
+// These duplicate the styles in the Multiple argument
+#define wxLB_SINGLE         0x0000
+#define wxLB_MULTIPLE       0x0040
+#define wxLB_EXTENDED       0x0080
+// wxLB_OWNERDRAW is Windows-only
+#define wxLB_OWNERDRAW      0x0100
+#define wxLB_HSCROLL        wxHSCROLL
+
+/*
+ * wxTextCtrl style flags
+ */
+#define wxPROCESS_ENTER     0x0004
+#define wxPASSWORD          0x0008
+#define wxTE_PROCESS_ENTER  wxPROCESS_ENTER
+#define wxTE_PASSWORD       wxPASSWORD
+#define wxTE_READONLY       0x0010
+#define wxTE_MULTILINE      0x0020
+
+// TODO For backward compatibility, need wxOLD_READONLY
+#define wxREADONLY          wxTE_READONLY
+#define wxEDITABLE          0
+
+// #define wxTE_RICHTEXT       0x0020
+
+/*
+ * wxComboBox style flags
+ */
+#define wxCB_SIMPLE         0x0004
+#define wxCB_DROPDOWN       0x0000
+#define wxCB_SORT           0x0008
+#define wxCB_READONLY       wxREADONLY
+
+/*
+ * wxRadioBox/wxRadioButton style flags
+ */
+#define wxRA_HORIZONTAL     wxHORIZONTAL
+#define wxRA_VERTICAL       wxVERTICAL
+#define wxRB_GROUP          0x0004
+
+/*
+ * wxGauge flags
+ */
+#define wxGA_PROGRESSBAR     0x0004
+#define wxGA_HORIZONTAL      wxHORIZONTAL
+#define wxGA_VERTICAL        wxVERTICAL
+
+/*
+ * wxSlider flags
+ */
+ 
+#define wxSL_HORIZONTAL      wxHORIZONTAL
+#define wxSL_VERTICAL        wxVERTICAL
+// The next one is obsolete - use scroll events instead
+#define wxSL_NOTIFY_DRAG     0x0000
+#define wxSL_AUTOTICKS       0x0008
+// #define wxSL_MANUALTICKS     0x0010
+#define wxSL_LABELS          0x0020
+#define wxSL_LEFT            0x0040
+#define wxSL_TOP             0x0080
+#define wxSL_RIGHT           0x0100
+#define wxSL_BOTTOM          0x0200
+#define wxSL_BOTH            0x0400
+#define wxSL_SELRANGE        0x0800
+
+/*
+ * wxScrollBar flags
+ */
+ 
+#define wxSB_HORIZONTAL      wxHORIZONTAL
+#define wxSB_VERTICAL        wxVERTICAL
+
+/*
+ * wxButton flags
+ */
+
+#define wxBU_AUTODRAW        0x0004
+#define wxBU_NOAUTODRAW      0x0000
+
+/*
+ * wxTreeCtrl flags
+ */
+
+#define wxTR_HAS_BUTTONS     0x0004
+#define wxTR_EDIT_LABELS     0x0008
+
+/*
+ * wxListCtrl flags
+ */
+
+#define wxLC_ICON            0x0004
+#define wxLC_SMALL_ICON      0x0008
+#define wxLC_LIST            0x0010
+#define wxLC_REPORT          0x0020
+#define wxLC_ALIGN_TOP       0x0040
+#define wxLC_ALIGN_LEFT      0x0080
+#define wxLC_AUTOARRANGE     0x0100
+#define wxLC_USER_TEXT       0x0200
+#define wxLC_EDIT_LABELS     0x0400
+#define wxLC_NO_HEADER       0x0800
+#define wxLC_NO_SORT_HEADER  0x1000
+#define wxLC_SINGLE_SEL      0x2000
+#define wxLC_SORT_ASCENDING  0x4000
+#define wxLC_SORT_DESCENDING 0x8000
+
+#define wxLC_MASK_TYPE       (wxLC_ICON | wxLC_SMALL_ICON | wxLC_LIST | wxLC_REPORT)
+#define wxLC_MASK_ALIGN      (wxLC_ALIGN_TOP | wxLC_ALIGN_LEFT)
+#define wxLC_MASK_SORT       (wxLC_SORT_ASCENDING | wxLC_SORT_DESCENDING)
+
+// Omitted because (a) too much detail (b) not enough style flags
+// #define wxLC_NO_SCROLL
+// #define wxLC_NO_LABEL_WRAP
+// #define wxLC_OWNERDRAW_FIXED
+// #define wxLC_SHOW_SEL_ALWAYS
+
+/*
+ * wxSpinButton flags
+ */
+
+#define wxSP_VERTICAL       0x0004
+#define wxSP_HORIZONTAL     0x0008
+#define wxSP_ARROW_KEYS     0x0010
+#define wxSP_WRAP           0x0020
+
+/*
+ * wxSplitterWnd flags
+ */
+
+#define wxSP_NOBORDER       0x0000
+#define wxSP_3D             0x0004
+#define wxSP_BORDER         0x0008
+
+/*
+ * wxTabCtrl flags
+ */
+
+#define wxTAB_MULTILINE     0x0000
+#define wxTAB_RIGHTJUSTIFY  0x0004
+#define wxTAB_FIXEDWIDTH    0x0008
+#define wxTAB_OWNERDRAW     0x0010
+
+/*
+ * wxStatusBar95 flags
+ */
+
+#define wxSB_SIZEGRIP       0x0002
+
+/*
+ * GDI descriptions
+ */
+
+enum {
+// Text font families
+  wxDEFAULT    = 70,
+  wxDECORATIVE,
+  wxROMAN,
+  wxSCRIPT,
+  wxSWISS,
+  wxMODERN,
+  wxTELETYPE,  /* @@@@ */
+
+// Proportional or Fixed width fonts (not yet used)
+  wxVARIABLE   = 80,
+  wxFIXED,
+
+  wxNORMAL     = 90,
+  wxLIGHT,
+  wxBOLD,
+// Also wxNORMAL for normal (non-italic text)
+  wxITALIC,
+  wxSLANT,
+
+// Pen styles
+  wxSOLID      =   100,
+  wxDOT,
+  wxLONG_DASH,
+  wxSHORT_DASH,
+  wxDOT_DASH,
+  wxUSER_DASH,
+
+  wxTRANSPARENT,
+
+// Brush & Pen Stippling. Note that a stippled pen cannot be dashed!!
+// Note also that stippling a Pen IS meaningfull, because a Line is
+// drawn with a Pen, and without any Brush -- and it can be stippled.
+  wxSTIPPLE =          110,
+  wxBDIAGONAL_HATCH,
+  wxCROSSDIAG_HATCH,
+  wxFDIAGONAL_HATCH,
+  wxCROSS_HATCH,
+  wxHORIZONTAL_HATCH,
+  wxVERTICAL_HATCH,
+#define IS_HATCH(s)	((s)>=wxBDIAGONAL_HATCH && (s)<=wxVERTICAL_HATCH)
+
+  wxJOIN_BEVEL =     120,
+  wxJOIN_MITER,
+  wxJOIN_ROUND,
+
+  wxCAP_ROUND =      130,
+  wxCAP_PROJECTING,
+  wxCAP_BUTT
+};
+
+
+// Logical ops
+typedef enum {
+  wxCLEAR,      // 0
+  wxXOR,        // src XOR dst
+  wxINVERT,     // NOT dst
+  wxOR_REVERSE, // src OR (NOT dst)
+  wxAND_REVERSE,// src AND (NOT dst)
+  wxCOPY,       // src
+  wxAND,        // src AND dst
+  wxAND_INVERT, // (NOT src) AND dst
+  wxNO_OP,      // dst
+  wxNOR,        // (NOT src) AND (NOT dst)
+  wxEQUIV,      // (NOT src) XOR dst
+  wxSRC_INVERT, // (NOT src)
+  wxOR_INVERT,  // (NOT src) OR dst
+  wxNAND,       // (NOT src) OR (NOT dst)
+  wxOR,         // src OR dst
+  wxSET,        // 1
+  wxSRC_OR,     // source _bitmap_ OR destination
+  wxSRC_AND     // source _bitmap_ AND destination
+} form_ops_t;
+
+// Flood styles
+#define  wxFLOOD_SURFACE   1
+#define  wxFLOOD_BORDER    2
+
+// Polygon filling mode
+#define  wxODDEVEN_RULE    1
+#define  wxWINDING_RULE    2
+
+// ToolPanel in wxFrame
+#define	wxTOOL_TOP	   1
+#define	wxTOOL_BOTTOM	   2
+#define	wxTOOL_LEFT	   3
+#define	wxTOOL_RIGHT	   4
+
+// Dialog specifiers/return values
+
+#define wxOK                0x0001
+#define wxYES_NO            0x0002
+#define wxCANCEL            0x0004
+#define wxYES               0x0008
+#define wxNO                0x0010
+
+#define wxICON_EXCLAMATION  0x0020
+#define wxICON_HAND         0x0040
+#define wxICON_QUESTION     0x0080
+#define wxICON_INFORMATION  0x0100
+
+#define wxICON_STOP         wxICON_HAND
+#define wxICON_ASTERISK     wxICON_INFORMATION
+#define wxICON_MASK         (0x0020|0x0040|0x0080|0x0100)
+
+#define wxCENTRE            0x0200
+#define wxCENTER wxCENTRE
+
+// Possible SetSize flags
+
+// Use internally-calculated width if -1
+#define wxSIZE_AUTO_WIDTH       1
+// Use internally-calculated height if -1
+#define wxSIZE_AUTO_HEIGHT      2
+// Use internally-calculated width and height if each is -1
+#define wxSIZE_AUTO             3
+// Ignore missing (-1) dimensions (use existing).
+// For readability only: test for wxSIZE_AUTO_WIDTH/HEIGHT in code.
+#define wxSIZE_USE_EXISTING     0
+// Allow -1 as a valid position
+#define wxSIZE_ALLOW_MINUS_ONE  4
+
+// Clipboard formats
+// Numbers as per winuser.h
+# define wxCF_TEXT               1 /* CF_TEXT */
+# define wxCF_BITMAP             2 /* CF_BITMAP */
+# define wxCF_METAFILE           3 /* CF_METAFILEPICT */
+# define wxCF_DIB                8 /* CF_DIB */
+# define wxCF_OEMTEXT            7 /* CF_OEMTEXT */
+
+// Virtual keycodes
+enum _Virtual_keycodes {
+ WXK_BACK    =   8,
+ WXK_TAB     =   9,
+ WXK_RETURN  =	13,
+ WXK_ESCAPE  =	27,
+ WXK_SPACE   =	32,
+ WXK_DELETE  = 127,
+
+ WXK_START   = 300,
+ WXK_LBUTTON,
+ WXK_RBUTTON,
+ WXK_CANCEL,
+ WXK_MBUTTON,
+ WXK_CLEAR,
+ WXK_SHIFT,
+ WXK_CONTROL,
+ WXK_MENU,
+ WXK_PAUSE,
+ WXK_CAPITAL,
+ WXK_PRIOR,  // Page up
+ WXK_NEXT,   // Page down
+ WXK_END,
+ WXK_HOME,
+ WXK_LEFT,
+ WXK_UP,
+ WXK_RIGHT,
+ WXK_DOWN,
+ WXK_SELECT,
+ WXK_PRINT,
+ WXK_EXECUTE,
+ WXK_SNAPSHOT,
+ WXK_INSERT,
+ WXK_HELP,
+ WXK_NUMPAD0,
+ WXK_NUMPAD1,
+ WXK_NUMPAD2,
+ WXK_NUMPAD3,
+ WXK_NUMPAD4,
+ WXK_NUMPAD5,
+ WXK_NUMPAD6,
+ WXK_NUMPAD7,
+ WXK_NUMPAD8,
+ WXK_NUMPAD9,
+ WXK_MULTIPLY,
+ WXK_ADD,
+ WXK_SEPARATOR,
+ WXK_SUBTRACT,
+ WXK_DECIMAL,
+ WXK_DIVIDE,
+ WXK_F1,
+ WXK_F2,
+ WXK_F3,
+ WXK_F4,
+ WXK_F5,
+ WXK_F6,
+ WXK_F7,
+ WXK_F8,
+ WXK_F9,
+ WXK_F10,
+ WXK_F11,
+ WXK_F12,
+ WXK_F13,
+ WXK_F14,
+ WXK_F15,
+ WXK_F16,
+ WXK_F17,
+ WXK_F18,
+ WXK_F19,
+ WXK_F20,
+ WXK_F21,
+ WXK_F22,
+ WXK_F23,
+ WXK_F24,
+ WXK_NUMLOCK,
+ WXK_SCROLL,
+ WXK_PAGEUP,
+ WXK_PAGEDOWN
+};
+
+// Colours - see wx_gdi.cc for database
+
+// OS mnemonics -- Identify the running OS (useful for Windows)
+// [Not all platforms are currently available or supported]
+enum {
+  wxCURSES,
+  wxXVIEW_X,	// Sun's XView OpenLOOK toolkit
+  wxMOTIF_X,	// OSF Motif 1.x.x
+  wxCOSE_X,	// OSF Common Desktop Environment
+  wxNEXTSTEP,	// NeXTStep
+  wxMACINTOSH,	// Apple System 7
+  wxGEOS,	// GEOS
+  wxOS2_PM,	// OS/2 Workplace
+  wxWINDOWS,	// Windows or WfW
+  wxPENWINDOWS,	// Windows for Pen Computing
+  wxWINDOWS_NT,	// Windows NT
+  wxWIN32S,	// Windows 32S API
+  wxWIN95,	// Windows 95
+  wxWIN386	// Watcom 32-bit supervisor modus
+};
+
+// Printing
+#ifndef wxPORTRAIT
+#define wxPORTRAIT      1
+#define wxLANDSCAPE     2
+#endif
+
+// Standard menu identifiers
+#define wxID_OPEN               5000
+#define wxID_CLOSE              5001
+#define wxID_NEW                5002
+#define wxID_SAVE               5003
+#define wxID_SAVEAS             5004
+#define wxID_REVERT             5005
+#define wxID_EXIT               5006
+#define wxID_UNDO               5007
+#define wxID_REDO               5008
+#define wxID_HELP               5009
+#define wxID_PRINT              5010
+#define wxID_PRINT_SETUP        5011
+#define wxID_PREVIEW            5012
+#define wxID_ABOUT              5013
+#define wxID_HELP_CONTENTS      5014
+#define wxID_HELP_COMMANDS      5015
+#define wxID_HELP_PROCEDURES    5016
+#define wxID_HELP_CONTEXT       5017
+
+#define wxID_CUT                5030
+#define wxID_COPY               5031
+#define wxID_PASTE              5032
+#define wxID_CLEAR              5033
+#define wxID_FIND               5034
+
+#define wxID_FILE1              5050
+#define wxID_FILE2              5051
+#define wxID_FILE3              5052
+#define wxID_FILE4              5053
+#define wxID_FILE5              5054
+#define wxID_FILE6              5055
+#define wxID_FILE7              5056
+#define wxID_FILE8              5057
+#define wxID_FILE9              5058
+
+#define wxID_OK                 5100
+#define wxID_CANCEL             5101
+#define wxID_APPLY              5102
+#define wxID_YES                5103
+#define wxID_NO                 5104
+
+#ifdef __WINDOWS__
+// Stand-ins for Windows types, to avoid
+// #including all of windows.h
+
+typedef unsigned long   WXHWND;
+typedef unsigned long   WXHANDLE;
+typedef unsigned long   WXHICON;
+typedef unsigned long   WXHFONT;
+typedef unsigned long   WXHMENU;
+typedef unsigned long   WXHPEN;
+typedef unsigned long   WXHBRUSH;
+typedef unsigned long   WXHPALETTE;
+typedef unsigned long   WXHCURSOR;
+typedef unsigned long   WXHRGN;
+typedef unsigned long   WXHINSTANCE;
+typedef unsigned long   WXHBITMAP;
+typedef unsigned long   WXHIMAGELIST;
+typedef unsigned long   WXHGLOBAL;
+typedef unsigned long   WXHDC;
+typedef unsigned int    WXUINT;
+typedef unsigned long   WXDWORD;
+typedef unsigned short  WXWORD;
+typedef unsigned int    WXWPARAM;
+typedef long            WXLPARAM;
+typedef unsigned long   WXCOLORREF;
+typedef void *          WXRGN;
+typedef void *          WXRGNDATA;
+typedef void *          WXMSG;
+typedef unsigned long   WXHCONV;
+typedef void *          WXDRAWITEMSTRUCT;
+typedef void *          WXMEASUREITEMSTRUCT;
+typedef void *          WXLPCREATESTRUCT;
+typedef int (*WXFARPROC)();
+
+#endif
+
+#endif
+    // __WXDEFSH__
diff --git a/include/wx/dialog.h b/include/wx/dialog.h
new file mode 100644
index 0000000000..78c9a79d88
--- /dev/null
+++ b/include/wx/dialog.h
@@ -0,0 +1,13 @@
+#ifndef __DIALOGH_BASE__
+#define __DIALOGH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/dialog.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/dialog.h"
+#elif defined(__GTK__)
+#include "wx/gtk/dialog.h"
+#endif
+
+#endif
+    // __DIALOGH_BASE__
diff --git a/include/wx/dirdlg.h b/include/wx/dirdlg.h
new file mode 100644
index 0000000000..518c9912ac
--- /dev/null
+++ b/include/wx/dirdlg.h
@@ -0,0 +1,13 @@
+#ifndef __DIRDLGH_BASE__
+#define __DIRDLGH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/dirdlg.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/dirdlg.h"
+#elif defined(__GTK__)
+#include "wx/gtk/dirdlg.h"
+#endif
+
+#endif
+    // __DIRDLGH_BASE__
diff --git a/include/wx/dnd.h b/include/wx/dnd.h
new file mode 100644
index 0000000000..a654c6e7a1
--- /dev/null
+++ b/include/wx/dnd.h
@@ -0,0 +1,11 @@
+#ifndef __DNDH_BASE__
+#define __DNDH_BASE__
+
+#if defined(__WINDOWS__)
+#elif defined(__MOTIF__)
+#elif defined(__GTK__)
+#include "wx/gtk/dnd.h"
+#endif
+
+#endif
+    // __DNDH_BASE__
diff --git a/include/wx/docview.h b/include/wx/docview.h
new file mode 100644
index 0000000000..793049f770
--- /dev/null
+++ b/include/wx/docview.h
@@ -0,0 +1,519 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        docview.h
+// Purpose:     Doc/View classes
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c)
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __DOCH__
+#define __DOCH__
+
+#ifdef __GNUG__
+#pragma interface "docview.h"
+#endif
+
+#include "wx/defs.h"
+#include "wx/list.h"
+#include "wx/cmndata.h"
+#include "wx/string.h"
+
+#if USE_PRINTING_ARCHITECTURE
+#include "wx/print.h"
+#endif
+
+class WXDLLEXPORT wxWindow;
+class WXDLLEXPORT wxDocument;
+class WXDLLEXPORT wxView;
+class WXDLLEXPORT wxDocTemplate;
+class WXDLLEXPORT wxDocManager;
+class WXDLLEXPORT wxPrintInfo;
+class WXDLLEXPORT wxCommand;
+class WXDLLEXPORT wxCommandProcessor;
+class WXDLLEXPORT wxFileHistory;
+
+class WXDLLIMPORT ostream;
+class WXDLLIMPORT istream;
+
+// Document manager flags
+#define wxDOC_SDI       1
+#define wxDOC_MDI       2
+#define wxDOC_NEW       4
+#define wxDOC_SILENT    8
+#define wxDEFAULT_DOCMAN_FLAGS      wxDOC_SDI
+
+// Document template flags
+#define wxTEMPLATE_VISIBLE      1
+#define wxTEMPLATE_INVISIBLE    2
+#define wxDEFAULT_TEMPLATE_FLAGS    wxTEMPLATE_VISIBLE
+
+#define wxMAX_FILE_HISTORY      9
+
+class WXDLLEXPORT wxDocument : public wxEvtHandler
+{
+  DECLARE_ABSTRACT_CLASS(wxDocument)
+ public:
+  wxDocument(wxDocument *parent = NULL);
+  ~wxDocument(void);
+
+  void SetFilename(const wxString& filename, bool notifyViews = FALSE);
+  inline wxString GetFilename(void) const { return m_documentFile; }
+  inline void SetTitle(const wxString& title) { m_documentTitle = title; };
+  inline wxString GetTitle(void) const { return m_documentTitle; }
+  inline void SetDocumentName(const wxString& name) { m_documentTypeName = name; };
+  inline wxString GetDocumentName(void) const { return m_documentTypeName; }
+  // Has the document been saved yet?
+  inline bool GetDocumentSaved(void) { return m_savedYet; }
+  inline void SetDocumentSaved(bool saved = TRUE) { m_savedYet = saved; }
+
+  virtual bool Close(void);
+  virtual bool Save(void);
+  virtual bool SaveAs(void);
+  virtual bool Revert(void);
+
+  virtual ostream& SaveObject(ostream& stream);
+  virtual istream& LoadObject(istream& stream);
+
+  // Called by wxWindows
+  virtual bool OnSaveDocument(const wxString& filename);
+  virtual bool OnOpenDocument(const wxString& filename);
+  virtual bool OnNewDocument(void);
+  virtual bool OnCloseDocument(void);
+
+  // Prompts for saving if about to close a modified document.
+  // Returns TRUE if ok to close the document (may have saved in the
+  // meantime, or set modified to FALSE)
+  virtual bool OnSaveModified(void);
+
+  // Called by framework if created automatically by the
+  // default document manager: gives document a chance to
+  // initialise and (usually) create a view
+  virtual bool OnCreate(const wxString& path, long flags);
+
+  // By default, creates a base wxCommandProcessor.
+  virtual wxCommandProcessor *OnCreateCommandProcessor(void);
+  virtual inline wxCommandProcessor *GetCommandProcessor(void) const { return m_commandProcessor; }
+  virtual inline void SetCommandProcessor(wxCommandProcessor *proc) { m_commandProcessor = proc; }
+
+  // Called after a view is added or removed.
+  // The default implementation deletes the document if this
+  // is there are no more views.
+  virtual void OnChangedViewList(void);
+
+  virtual bool DeleteContents(void);
+
+  virtual bool Draw(wxDC&);
+  virtual inline bool IsModified(void) const { return m_documentModified; }
+  virtual inline void Modify(bool mod) { m_documentModified = mod; }
+
+  virtual bool AddView(wxView *view);
+  virtual bool RemoveView(wxView *view);
+  inline wxList& GetViews(void) const { return (wxList&) m_documentViews; }
+  wxView *GetFirstView(void) const;
+
+  virtual void UpdateAllViews(wxView *sender = NULL, wxObject *hint = NULL);
+
+  // Remove all views (because we're closing the document)
+  virtual bool DeleteAllViews(void);
+
+  // Other stuff
+  virtual wxDocManager *GetDocumentManager(void) const;
+  virtual inline wxDocTemplate *GetDocumentTemplate(void) const { return m_documentTemplate; }
+  virtual inline void SetDocumentTemplate(wxDocTemplate *temp) { m_documentTemplate = temp; }
+
+  // Get title, or filename if no title, else [unnamed]
+  virtual bool GetPrintableName(wxString& buf) const;
+
+  // Returns a window that can be used as a parent for document-related
+  // dialogs. Override if necessary.
+  virtual wxWindow *GetDocumentWindow(void) const;
+ protected:
+  wxList                m_documentViews;
+  wxString              m_documentFile;
+  wxString              m_documentTitle;
+  wxString              m_documentTypeName;
+  wxDocTemplate*        m_documentTemplate;
+  bool                  m_documentModified;
+  wxDocument*           m_documentParent;
+  wxCommandProcessor*   m_commandProcessor;
+  bool                  m_savedYet;
+};
+
+class WXDLLEXPORT wxView: public wxEvtHandler
+{
+  DECLARE_ABSTRACT_CLASS(wxView)
+ public:
+  wxView(wxDocument *doc = NULL);
+  ~wxView(void);
+
+  inline wxDocument *GetDocument(void) const { return m_viewDocument; }
+  void SetDocument(wxDocument *doc);
+
+  inline wxString GetViewName(void) const { return m_viewTypeName; }
+  void SetViewName(const wxString& name) { m_viewTypeName = name; };
+
+  inline wxFrame *GetFrame(void) const { return m_viewFrame ; }
+  inline void SetFrame(wxFrame *frame) { m_viewFrame = frame; }
+
+  virtual void OnActivateView(bool activate, wxView *activeView, wxView *deactiveView);
+  virtual void OnDraw(wxDC *dc) = 0;
+  virtual void OnPrint(wxDC *dc, wxObject *info);
+  virtual void OnUpdate(wxView *sender, wxObject *hint = NULL);
+  virtual void OnChangeFilename(void);
+
+  // Called by framework if created automatically by the
+  // default document manager class: gives view a chance to
+  // initialise
+  virtual bool OnCreate(wxDocument *WXUNUSED(doc), long WXUNUSED(flags)) { return TRUE; };
+
+  // Checks if the view is the last one for the document; if so,
+  // asks user to confirm save data (if modified). If ok,
+  // deletes itself and returns TRUE.
+  virtual bool Close(bool deleteWindow = TRUE);
+
+  // Override to do cleanup/veto close
+  virtual bool OnClose(bool deleteWindow);
+  // Defeat compiler warning
+  inline bool OnClose(void) { return wxEvtHandler::OnClose(); }
+
+  // Extend event processing to search the document's event table
+  virtual bool ProcessEvent(wxEvent& event);
+
+  // A view's window can call this to notify the view it is (in)active.
+  // The function then notifies the document manager.
+  virtual void Activate(bool activate);
+
+  inline wxDocManager *GetDocumentManager(void) const { return m_viewDocument->GetDocumentManager(); }
+
+#if USE_PRINTING_ARCHITECTURE
+  virtual wxPrintout *OnCreatePrintout(void);
+#endif
+
+ protected:
+  wxDocument*       m_viewDocument;
+  wxString          m_viewTypeName;
+  wxFrame*          m_viewFrame;
+};
+
+// Represents user interface (and other) properties of documents and views
+class WXDLLEXPORT wxDocTemplate: public wxObject
+{
+  DECLARE_CLASS(wxDocTemplate)
+
+ friend class WXDLLEXPORT wxDocManager;
+
+ public:
+
+  // Associate document and view types.
+  // They're for identifying what view is associated with what
+  // template/document type
+  wxDocTemplate(wxDocManager *manager, const wxString& descr, const wxString& filter, const wxString& dir,
+     const wxString& ext, const wxString& docTypeName, const wxString& viewTypeName,
+     wxClassInfo *docClassInfo = NULL, wxClassInfo *viewClassInfo = NULL,
+     long flags = wxDEFAULT_TEMPLATE_FLAGS);
+
+  ~wxDocTemplate(void);
+
+  // By default, these two member functions dynamically creates document
+  // and view using dynamic instance construction.
+  // Override these if you need a different method of construction.
+  virtual wxDocument *CreateDocument(const wxString& path, long flags = 0);
+  virtual wxView *CreateView(wxDocument *doc, long flags = 0);
+
+  inline wxString GetDefaultExtension(void) const { return m_defaultExt; };
+  inline wxString GetDescription(void) const { return m_description; }
+  inline wxString GetDirectory(void) const { return m_directory; };
+  inline wxDocManager *GetDocumentManager(void) const { return m_documentManager; }
+  inline void SetDocumentManager(wxDocManager *manager) { m_documentManager = manager; }
+  inline wxString GetFileFilter(void) const { return m_fileFilter; };
+  inline long GetFlags(void) const { return m_flags; };
+  virtual wxString GetViewName(void) const { return m_viewTypeName; }
+  virtual wxString GetDocumentName(void) const { return m_docTypeName; }
+
+  inline void SetFileFilter(const wxString& filter) { m_fileFilter = filter; };
+  inline void SetDirectory(const wxString& dir) { m_directory = dir; };
+  inline void SetDescription(const wxString& descr) { m_description = descr; };
+  inline void SetDefaultExtension(const wxString& ext) { m_defaultExt = ext; };
+  inline void SetFlags(long flags) { m_flags = flags; };
+
+  inline bool IsVisible(void) const { return ((m_flags & wxTEMPLATE_VISIBLE) == wxTEMPLATE_VISIBLE); }
+
+ protected:
+  long              m_flags;
+  wxString          m_fileFilter;
+  wxString          m_directory;
+  wxString          m_description;
+  wxString          m_defaultExt;
+  wxString          m_docTypeName;
+  wxString          m_viewTypeName;
+  wxDocManager*     m_documentManager;
+
+  // For dynamic creation of appropriate instances.
+  wxClassInfo*      m_docClassInfo;
+  wxClassInfo*      m_viewClassInfo;
+
+};
+
+// One object of this class may be created in an application,
+// to manage all the templates and documents.
+class WXDLLEXPORT wxDocManager: public wxEvtHandler
+{
+  DECLARE_DYNAMIC_CLASS(wxDocManager)
+ public:
+  wxDocManager(long flags = wxDEFAULT_DOCMAN_FLAGS, bool initialize = TRUE);
+  ~wxDocManager(void);
+
+  virtual bool Initialize(void);
+
+  // Handlers for common user commands
+//   virtual void OldOnMenuCommand(int command);
+
+  void OnFileClose(wxCommandEvent& event);
+  void OnFileNew(wxCommandEvent& event);
+  void OnFileOpen(wxCommandEvent& event);
+  void OnFileRevert(wxCommandEvent& event);
+  void OnFileSave(wxCommandEvent& event);
+  void OnFileSaveAs(wxCommandEvent& event);
+  void OnPrint(wxCommandEvent& event);
+  void OnPrintSetup(wxCommandEvent& event);
+  void OnPreview(wxCommandEvent& event);
+  void OnUndo(wxCommandEvent& event);
+  void OnRedo(wxCommandEvent& event);
+
+#ifdef WXWIN_COMPATIBILITY
+  virtual wxDocument *CreateDocument(char *WXUNUSED(path), long WXUNUSED(flags = 0)) { return NULL; };
+#endif
+  virtual wxDocument *CreateDocument(const wxString& path, long flags = 0);
+  virtual wxView *CreateView(wxDocument *doc, long flags = 0);
+  virtual void DeleteTemplate(wxDocTemplate *temp, long flags = 0);
+  virtual bool FlushDoc(wxDocument *doc);
+  virtual wxDocTemplate *MatchTemplate(const wxString& path);
+  virtual wxDocTemplate *SelectDocumentPath(wxDocTemplate **templates,
+    int noTemplates, wxString& path, long flags, bool save = FALSE);
+  virtual wxDocTemplate *SelectDocumentType(wxDocTemplate **templates,
+    int noTemplates);
+  virtual wxDocTemplate *SelectViewType(wxDocTemplate **templates,
+    int noTemplates);
+  virtual wxDocTemplate *FindTemplateForPath(const wxString& path);
+
+  void AssociateTemplate(wxDocTemplate *temp);
+  void DisassociateTemplate(wxDocTemplate *temp);
+
+  wxDocument *GetCurrentDocument(void) const;
+
+  inline void SetMaxDocsOpen(int n) { m_maxDocsOpen = n; }
+  inline int GetMaxDocsOpen(void) const { return m_maxDocsOpen; }
+
+  // Add and remove a document from the manager's list
+  void AddDocument(wxDocument *doc);
+  void RemoveDocument(wxDocument *doc);
+
+  // Clear remaining documents and templates
+  bool Clear(bool force = TRUE);
+
+  // Views or windows should inform the document manager
+  // when a view is going in or out of focus
+  virtual void ActivateView(wxView *view, bool activate = TRUE, bool deleting = FALSE);
+  virtual inline wxView *GetCurrentView(void) const { return m_currentView; }
+
+  virtual inline wxList& GetDocuments(void) const { return (wxList&) m_docs; }
+
+  // Make a default document name
+  virtual bool MakeDefaultName(wxString& buf);
+
+  virtual wxFileHistory *OnCreateFileHistory(void);
+  virtual inline wxFileHistory *GetFileHistory(void) const { return m_fileHistory; }
+
+  // File history management
+  virtual void AddFileToHistory(const wxString& file);
+  virtual int GetNoHistoryFiles(void) const;
+  virtual wxString GetHistoryFile(int i) const;
+  virtual void FileHistoryUseMenu(wxMenu *menu);
+  virtual void FileHistoryLoad(const wxString& resourceFile, const wxString& section);
+  virtual void FileHistorySave(const wxString& resourceFile, const wxString& section);
+ protected:
+  long              m_flags;
+  int               m_defaultDocumentNameCounter;
+  int               m_maxDocsOpen;
+  wxList            m_docs;
+  wxList            m_templates;
+  wxView*           m_currentView;
+  wxFileHistory*    m_fileHistory;
+
+DECLARE_EVENT_TABLE()
+};
+
+/*
+ * A default child frame
+ */
+
+class WXDLLEXPORT wxDocChildFrame: public wxFrame
+{
+  DECLARE_CLASS(wxDocChildFrame)
+
+ public:
+  wxDocChildFrame(wxDocument *doc, wxView *view, wxFrame *frame, const wxString& title,
+    const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+    const long type = wxDEFAULT_FRAME_STYLE, const wxString& name = "frame");
+  ~wxDocChildFrame(void);
+
+  bool OnClose(void);
+  // Extend event processing to search the view's event table
+  virtual bool ProcessEvent(wxEvent& event);
+
+//  void OldOnMenuCommand(int id);
+  void OnActivate(wxActivateEvent& event);
+
+  inline wxDocument *GetDocument(void) const { return m_childDocument; }
+  inline wxView *GetView(void) const { return m_childView; }
+  inline void SetDocument(wxDocument *doc) { m_childDocument = doc; }
+  inline void SetView(wxView *view) { m_childView = view; }
+ protected:
+  wxDocument*       m_childDocument;
+  wxView*           m_childView;
+
+DECLARE_EVENT_TABLE()
+
+};
+
+/*
+ * A default parent frame
+ */
+ 
+class WXDLLEXPORT wxDocParentFrame: public wxFrame
+{
+  DECLARE_CLASS(wxDocParentFrame)
+ public:
+  wxDocParentFrame(wxDocManager *manager, wxFrame *frame, const wxString& title,
+    const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+    const long type = wxDEFAULT_FRAME, const wxString& name = "frame");
+
+  bool OnClose(void);
+  // Extend event processing to search the document manager's event table
+  virtual bool ProcessEvent(wxEvent& event);
+
+//  void OldOnMenuCommand(int id);
+  wxDocManager *GetDocumentManager(void) const { return m_docManager; }
+
+  void OnExit(wxCommandEvent& event);
+  void OnMRUFile(wxCommandEvent& event);
+
+ protected:
+  wxDocManager *m_docManager;
+
+DECLARE_EVENT_TABLE()
+};
+
+/*
+ * Provide simple default printing facilities
+ */
+
+#if USE_PRINTING_ARCHITECTURE
+class WXDLLEXPORT wxDocPrintout: public wxPrintout
+{
+  DECLARE_DYNAMIC_CLASS(wxDocPrintout)
+ public:
+  wxDocPrintout(wxView *view = NULL, const wxString& title = "Printout");
+  bool OnPrintPage(int page);
+  bool HasPage(int page);
+  bool OnBeginDocument(int startPage, int endPage);
+  void GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo);
+
+  virtual inline wxView *GetView(void) { return m_printoutView; }
+ protected:
+  wxView*       m_printoutView;
+};
+#endif
+
+/*
+ * Command processing framework
+ */
+
+class WXDLLEXPORT wxCommand: public wxObject
+{
+  DECLARE_CLASS(wxCommand)
+ public:
+  wxCommand(bool canUndoIt = FALSE, const wxString& name = "");
+  ~wxCommand(void);
+
+  // Override this to perform a command
+  virtual bool Do(void) = 0;
+
+  // Override this to undo a command
+  virtual bool Undo(void) = 0;
+
+  virtual inline bool CanUndo(void) const { return m_canUndo; }
+  virtual inline wxString GetName(void) const { return m_commandName; }
+ protected:
+  bool              m_canUndo;
+  wxString          m_commandName;
+};
+
+class WXDLLEXPORT wxCommandProcessor: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxCommandProcessor)
+ public:
+  wxCommandProcessor(int maxCommands = 100);
+  ~wxCommandProcessor(void);
+
+  // Pass a command to the processor. The processor calls Do();
+  // if successful, is appended to the command history unless
+  // storeIt is FALSE.
+  virtual bool Submit(wxCommand *command, bool storeIt = TRUE);
+  virtual bool Undo(void);
+  virtual bool Redo(void);
+  virtual bool CanUndo(void);
+
+  // Call this to manage an edit menu.
+  inline void SetEditMenu(wxMenu *menu) { m_commandEditMenu = menu; }
+  inline wxMenu *GetEditMenu(void) const { return m_commandEditMenu; }
+  virtual void SetMenuStrings(void);
+  virtual void Initialize(void);
+
+  inline wxList& GetCommands(void) const { return (wxList&) m_commands; }
+  inline int GetMaxCommands(void) const { return m_maxNoCommands; }
+  virtual void ClearCommands(void);
+
+ protected:
+  int           m_maxNoCommands;
+  wxList        m_commands;
+  wxNode*       m_currentCommand;
+  wxMenu*       m_commandEditMenu;
+};
+
+class WXDLLEXPORT wxFileHistory: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxFileHistory)
+ public:
+  wxFileHistory(int maxFiles = 9);
+  ~wxFileHistory(void);
+
+  // File history management
+  virtual void AddFileToHistory(const wxString& file);
+  inline virtual int GetNoHistoryFiles(void) const { return m_fileHistoryN; }
+  virtual wxString GetHistoryFile(int i) const;
+  virtual int GetMaxFiles(void) const { return m_fileMaxFiles; }
+  virtual void FileHistoryUseMenu(wxMenu *menu);
+  virtual void FileHistoryLoad(const wxString& resourceFile, const wxString& section);
+  virtual void FileHistorySave(const wxString& resourceFile, const wxString& section);
+ protected:
+  // Last n files
+  char**            m_fileHistory;
+  // Number of files saved
+  int               m_fileHistoryN;
+  // Menu to maintain
+  wxMenu*           m_fileMenu;
+  // Max files to maintain
+  int               m_fileMaxFiles;
+};
+
+// For compatibility with existing file formats:
+// converts from/to a stream to/from a temporary file.
+bool WXDLLEXPORT wxTransferFileToStream(const wxString& filename, ostream& stream);
+bool WXDLLEXPORT wxTransferStreamToFile(istream& stream, const wxString& filename);
+
+
+#endif
diff --git a/include/wx/dynarray.h b/include/wx/dynarray.h
new file mode 100644
index 0000000000..ef2f64518a
--- /dev/null
+++ b/include/wx/dynarray.h
@@ -0,0 +1,338 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        dynarray.h
+// Purpose:     auto-resizable (i.e. dynamic) array support
+// Author:      Vadim Zeitlin
+// Modified by: 
+// Created:     12.09.97
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// Licence:     wxWindows license
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef   _DYNARRAY_H
+#define   _DYNARRAY_H
+
+#ifdef __GNUG__
+#pragma interface "dynarray.h"
+#endif
+
+#include "wx/defs.h"
+#include "wx/utils.h"
+
+typedef   bool Bool;
+
+/** @name Dynamic arrays and lists 
+    @memo Arrays which grow on demand and do range checking (only in debug)
+  */
+//@{
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+/**
+ the initial size by which an array/list grows when an element is added
+ default value avoids allocate one or two bytes when the array is created 
+ which is rather inefficient
+*/
+#define   WX_ARRAY_DEFAULT_INITIAL_SIZE    (16)
+
+// ----------------------------------------------------------------------------
+// types
+// ----------------------------------------------------------------------------
+
+/**
+ callback compare function for quick sort
+ must return -1, 0 or +1 if pItem1 <, = or > pItem2
+ */
+
+#ifdef  __VISUALC__
+  #define   CMPFUNC_CONV    _cdecl
+#else   // !Visual C++
+  #define   CMPFUNC_CONV
+#endif  // compiler
+typedef int (CMPFUNC_CONV *CMPFUNC)(const void* pItem1, const void* pItem2);
+
+// ----------------------------------------------------------------------------
+/**
+ base class managing data having size of type 'long' (not used directly)
+
+ NB: for efficiency this often used class has no virtual functions (hence no
+     VTBL), even dtor is <B>not</B> virtual. If used as expected it won't 
+     create any problems because ARRAYs from DEFINE_ARRAY have no dtor at all, 
+     so it's not too important if it's not called (this happens when you cast 
+     "SomeArray *" as "BaseArray *" and then delete it)
+
+  @memo Base class for template array and list classes
+*/
+// ----------------------------------------------------------------------------
+class wxBaseArray
+{
+public:
+  /** @name ctors and dtor */
+  //@{
+    /// default ctor
+  wxBaseArray();
+    /// copy ctor
+  wxBaseArray(const wxBaseArray& array);
+    /// assignment operator
+  wxBaseArray& operator=(const wxBaseArray& src);
+    /// not virtual, see above
+    /// EXCEPT for Gnu compiler to reduce warnings...
+#ifdef __GNUG__
+ virtual
+#endif
+  ~wxBaseArray();
+  //@}
+
+  /** @name memory management */
+  //@{
+    /// empties the list, but doesn't release memory
+  void Empty() { m_uiCount = 0; }
+    /// empties the list and releases memory
+  void Clear();
+    /// preallocates memory for given number of items
+  void Alloc(uint uiSize);
+  //@}
+
+  /** @name simple accessors */
+  //@{
+    /// number of elements in the array
+  uint  Count() const   { return m_uiCount;      }
+    /// is it empty?
+  Bool  IsEmpty() const { return m_uiCount == 0; }
+  //@}
+
+protected:
+  // these methods are protected because if they were public one could 
+  // mistakenly call one of them instead of DEFINE_ARRAY's or LIST's
+  // type safe methods
+
+  /** @name items access */
+  //@{
+    /// get item at position uiIndex (range checking is done in debug version)
+  long& Item(uint uiIndex) const
+    { wxASSERT( uiIndex < m_uiCount ); return m_pItems[uiIndex]; }
+    /// same as Item()
+  long& operator[](uint uiIndex) const { return Item(uiIndex); }
+  //@}
+
+  /** @name item management */
+  //@{
+    /**
+      Search the element in the array, starting from the either side
+      @param bFromEnd if TRUE, start from the end
+      @return index of the first item matched or NOT_FOUND
+      @see NOT_FOUND
+     */
+  int  Index (long lItem, Bool bFromEnd = FALSE) const;
+    /// add new element at the end
+  void Add   (long lItem);
+    /// add new element at given position
+  void Insert(long lItem, uint uiIndex);
+    /// remove first item matching this value
+  void Remove(long lItem);
+    /// remove item by index
+  void Remove(uint uiIndex);
+  //@}
+
+  /// sort array elements using given compare function
+  void Sort(CMPFUNC fCmp);
+
+private:
+  void    Grow();     // makes array bigger if needed
+
+  uint    m_uiSize,   // current size of the array
+          m_uiCount;  // current number of elements
+
+  long   *m_pItems;   // pointer to data
+};
+
+// ============================================================================
+// template classes
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// This macro generates a new array class. It is intended for storage of simple
+// types of sizeof()<=sizeof(long) or pointers if sizeof(pointer)<=sizeof(long)
+// 
+// NB: it has only inline functions => takes no space at all
+// ----------------------------------------------------------------------------
+#define  _WX_DEFINE_ARRAY(T, name)                                  \
+typedef int (CMPFUNC_CONV *CMPFUNC##T)(T *pItem1, T *pItem2);       \
+class name : public wxBaseArray                                     \
+{                                                                   \
+public:                                                             \
+  name()                                                            \
+    { wxASSERT( sizeof(T) <= sizeof(long) ); }                      \
+                                                                    \
+  name& operator=(const name& src)                                  \
+    { ((wxBaseArray *)this)->operator=((const wxBaseArray&)src);    \
+      return *this; }                                               \
+                                                                    \
+  T& operator[](uint uiIndex) const                                 \
+    { return (T&)(wxBaseArray::Item(uiIndex)); }                    \
+  T& Item(uint uiIndex) const                                       \
+    { return (T&)(wxBaseArray::Item(uiIndex)); }                    \
+                                                                    \
+  int Index(T Item, Bool bFromEnd = FALSE) const                    \
+    { return wxBaseArray::Index((long)Item, bFromEnd); }            \
+                                                                    \
+  void Add(T Item)                                                  \
+    { wxBaseArray::Add((long)Item); }                               \
+  void Insert(T Item, uint uiIndex)                                 \
+    { wxBaseArray::Insert((long)Item, uiIndex) ; }                  \
+                                                                    \
+  void Remove(uint uiIndex) { wxBaseArray::Remove(uiIndex); }       \
+  void Remove(T Item)                                               \
+    { int iIndex = Index(Item);                                     \
+      wxCHECK( iIndex != NOT_FOUND );                               \
+      wxBaseArray::Remove((uint)iIndex); }                          \
+                                                                    \
+  void Sort(CMPFUNC##T fCmp) { wxBaseArray::Sort((CMPFUNC)fCmp); }  \
+}
+
+// ----------------------------------------------------------------------------
+// see WX_DECLARE_LIST and WX_DEFINE_LIST
+// ----------------------------------------------------------------------------
+#define _WX_DECLARE_LIST(T, name)                                   \
+typedef int (CMPFUNC_CONV *CMPFUNC##T)(T** pItem1, T** pItem2);     \
+class name : public wxBaseArray                                     \
+{                                                                   \
+public:                                                             \
+  name() { }                                                        \
+  name(const name& src);                                            \
+  name& operator=(const name& src);                                 \
+                                                                    \
+  ~name();                                                          \
+                                                                    \
+  T& operator[](uint uiIndex) const                                 \
+    { return *(T*)wxBaseArray::Item(uiIndex); }                     \
+  T& Item(uint uiIndex) const                                       \
+    { return *(T*)wxBaseArray::Item(uiIndex); }                     \
+                                                                    \
+  int Index(const T& Item, Bool bFromEnd = FALSE) const;            \
+                                                                    \
+  void Add(const T& Item);                                          \
+  void Add(const T* pItem)                                          \
+    { wxBaseArray::Add((long)pItem); }                              \
+                                                                    \
+  void Insert(const T& Item,  uint uiIndex);                        \
+  void Insert(const T* pItem, uint uiIndex)                         \
+    { wxBaseArray::Insert((long)pItem, uiIndex); }                  \
+                                                                    \
+  void Empty();                                                     \
+                                                                    \
+  T*   Detach(uint uiIndex)                                         \
+    { T* p = (T*)wxBaseArray::Item(uiIndex);                        \
+      wxBaseArray::Remove(uiIndex); return p; }                     \
+  void Remove(uint uiIndex);                                        \
+                                                                    \
+  void Sort(CMPFUNC##T fCmp) { wxBaseArray::Sort((CMPFUNC)fCmp); }  \
+                                                                    \
+private:                                                            \
+  void DoCopy(const name& src);                                     \
+}
+
+// ----------------------------------------------------------------------------
+/** @name Macros for definition of dynamic arrays and lists 
+
+  These macros are ugly (especially if you look in the sources ;-), but they
+  allow us to define 'template' classes without actually using templates.
+  <BR>
+  <BR>
+  Range checking is performed in debug build for both arrays and lists. Type
+  checking is done at compile-time. Warning: arrays <I>never</I> shrink, they
+  only grow, so loading 10 millions in an array only to delete them 2 lines
+  below is <I>not</I> recommended. However, it does free memory when it's 
+  destroyed, so if you destroy array also, it's ok.
+  */
+// ----------------------------------------------------------------------------
+
+//@{
+  /**
+   This macro generates a new array class. It is intended for storage of simple
+   types of sizeof()<=sizeof(long) or pointers if sizeof(pointer)<=sizeof(long)
+   <BR>
+   NB: it has only inline functions => takes no space at all
+   <BR>
+
+   @memo declare and define array class 'name' containing elements of type 'T'
+  */
+#define WX_DEFINE_ARRAY(T, name)  typedef T _A##name;                        \
+                                  _WX_DEFINE_ARRAY(_A##name, name)
+  /**
+   This macro generates a new list class which owns the objects it contains,
+   i.e. it will delete them when it is destroyed. An element is of type T*,
+   but arguments of type T& are taken (see below!) and T& is returned.
+   <BR>
+   Don't use this for simple types such as "int" or "long"!
+   You _may_ use it for "double" but it's awfully inefficient.
+   <BR>
+   <BR>
+   Note on Add/Insert functions:
+   <BR>
+    1) function(T*) gives the object to the list, i.e. it will delete the
+       object when it's removed or in the list's dtor
+   <BR>
+    2) function(T&) will create a copy of the object and work with it
+   <BR>
+   <BR>
+   Also:
+   <BR>
+    1) Remove() will delete the object after removing it from the list
+   <BR>
+    2) Detach() just removes the object from the list (returning pointer to it)
+   <BR>
+   <BR>
+   NB1: Base type T should have an accessible copy ctor  if  Add(T&) is used,
+   <BR>
+   NB2: Never ever cast a list to it's base type: as dtor is <B>not</B> virtual 
+        it will provoke memory leaks
+   <BR>
+   <BR>
+   some functions of this class are not inline, so it takes some space to 
+   define new class from this template.
+
+   @memo declare list class 'name' containing elements of type 'T'
+  */
+#define WX_DECLARE_LIST(T, name)  typedef T _L##name;                 \
+                                  _WX_DECLARE_LIST(_L##name, name)
+  /**
+    To use a list class you must
+    <ll>
+    <li>#include "dynarray.h"
+    <li>DECLARE_LIST(element_type, list_class_name)
+    <li>#include "listimpl.cpp"
+    <li>DEFINE_LIST(list_class_name)   // same as above!
+    </ll>
+    <BR><BR>
+    This is necessary because at the moment of DEFINE_LIST class element_type
+    must be fully defined (i.e. forward declaration is not enough), while
+    DECLARE_LIST may be done anywhere. The separation of two allows to break
+    cicrcular dependencies with classes which have member variables of list 
+    type.
+
+    @memo define (must include listimpl.cpp!) list class 'name'
+   */
+#define WX_DEFINE_LIST(name)       "don't forget to include listimpl.cpp!"
+//@}
+
+// ----------------------------------------------------------------------------
+/** @name Some commonly used predefined arrays */
+// # overhead if not used?
+// ----------------------------------------------------------------------------
+
+//@{
+  /** @name ArrayInt */
+WX_DEFINE_ARRAY(int,    wxArrayInt);
+  /** @name ArrayLong */
+WX_DEFINE_ARRAY(long,   wxArrayLong);
+  /** @name ArrayPtrVoid */
+WX_DEFINE_ARRAY(void *, wxArrayPtrVoid);
+//@}
+
+//@}
+
+#endif // _DYNARRAY_H
+
diff --git a/include/wx/event.h b/include/wx/event.h
new file mode 100644
index 0000000000..ca877fc5ee
--- /dev/null
+++ b/include/wx/event.h
@@ -0,0 +1,1199 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        event.h
+// Purpose:     Event classes
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c)
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __EVENTH__
+#define __EVENTH__
+
+#ifdef __GNUG__
+#pragma interface "event.h"
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/gdicmn.h"
+
+/*
+ * Event types
+ *
+ */
+enum {
+ wxEVT_FIRST = 10000,
+
+ // New names
+ wxEVT_COMMAND_BUTTON_CLICKED,
+ wxEVT_COMMAND_CHECKBOX_CLICKED,
+ wxEVT_COMMAND_CHOICE_SELECTED,
+ wxEVT_COMMAND_LISTBOX_SELECTED,
+ wxEVT_COMMAND_LISTBOX_DOUBLECLICKED,
+ wxEVT_COMMAND_CHECKLISTBOX_TOGGLED,
+ wxEVT_COMMAND_TEXT_UPDATED,
+ wxEVT_COMMAND_TEXT_ENTER,
+ wxEVT_COMMAND_MENU_SELECTED,
+ wxEVT_COMMAND_SLIDER_UPDATED,
+ wxEVT_COMMAND_RADIOBOX_SELECTED,
+ wxEVT_COMMAND_RADIOBUTTON_SELECTED,
+// wxEVT_COMMAND_SCROLLBAR_UPDATED is now obsolete since we use wxEVT_SCROLL... events
+ wxEVT_COMMAND_SCROLLBAR_UPDATED,
+ wxEVT_COMMAND_VLBOX_SELECTED,
+ wxEVT_COMMAND_COMBOBOX_SELECTED,
+ wxEVT_COMMAND_TOOL_CLICKED,
+ wxEVT_COMMAND_TOOL_RCLICKED,
+ wxEVT_COMMAND_TOOL_ENTER,
+ wxEVT_SET_FOCUS,
+ wxEVT_KILL_FOCUS,
+
+/* Mouse event types */
+ wxEVT_LEFT_DOWN,
+ wxEVT_LEFT_UP,
+ wxEVT_MIDDLE_DOWN,
+ wxEVT_MIDDLE_UP,
+ wxEVT_RIGHT_DOWN,
+ wxEVT_RIGHT_UP,
+ wxEVT_MOTION,
+ wxEVT_ENTER_WINDOW,
+ wxEVT_LEAVE_WINDOW,
+ wxEVT_LEFT_DCLICK,
+ wxEVT_MIDDLE_DCLICK,
+ wxEVT_RIGHT_DCLICK,
+
+ // Non-client mouse events
+ wxEVT_NC_LEFT_DOWN = wxEVT_FIRST + 100,
+ wxEVT_NC_LEFT_UP,
+ wxEVT_NC_MIDDLE_DOWN,
+ wxEVT_NC_MIDDLE_UP,
+ wxEVT_NC_RIGHT_DOWN,
+ wxEVT_NC_RIGHT_UP,
+ wxEVT_NC_MOTION,
+ wxEVT_NC_ENTER_WINDOW,
+ wxEVT_NC_LEAVE_WINDOW,
+ wxEVT_NC_LEFT_DCLICK,
+ wxEVT_NC_MIDDLE_DCLICK,
+ wxEVT_NC_RIGHT_DCLICK,
+
+/* Character input event type  */
+ wxEVT_CHAR,
+
+ /*
+  * Scrollbar event identifiers
+  */
+ wxEVT_SCROLL_TOP,
+ wxEVT_SCROLL_BOTTOM,
+ wxEVT_SCROLL_LINEUP,
+ wxEVT_SCROLL_LINEDOWN,
+ wxEVT_SCROLL_PAGEUP,
+ wxEVT_SCROLL_PAGEDOWN,
+ wxEVT_SCROLL_THUMBTRACK,
+ 
+ wxEVT_SIZE = wxEVT_FIRST + 200,
+ wxEVT_MOVE,
+ wxEVT_CLOSE_WINDOW,
+ wxEVT_END_SESSION,
+ wxEVT_QUERY_END_SESSION,
+ wxEVT_ACTIVATE_APP,
+ wxEVT_POWER,
+ wxEVT_CHAR_HOOK,
+ wxEVT_KEY_UP,
+ wxEVT_ACTIVATE,
+ wxEVT_CREATE,
+ wxEVT_DESTROY,
+ wxEVT_SHOW,
+ wxEVT_ICONIZE,
+ wxEVT_MAXIMIZE,
+ wxEVT_MOUSE_CAPTURE_CHANGED,
+ wxEVT_PAINT,
+ wxEVT_ERASE_BACKGROUND,
+ wxEVT_NC_PAINT,
+ wxEVT_PAINT_ICON,
+ wxEVT_MENU_CHAR,
+ wxEVT_MENU_INIT,
+ wxEVT_MENU_HIGHLIGHT,
+ wxEVT_POPUP_MENU_INIT,
+ wxEVT_CONTEXT_MENU,
+ wxEVT_SYS_COLOUR_CHANGED,
+ wxEVT_SETTING_CHANGED,
+ wxEVT_QUERY_NEW_PALETTE,
+ wxEVT_PALETTE_CHANGED,
+ wxEVT_JOY_BUTTON_DOWN,
+ wxEVT_JOY_BUTTON_UP,
+ wxEVT_JOY_MOVE,
+ wxEVT_JOY_ZMOVE,
+ wxEVT_DROP_FILES,
+ wxEVT_DRAW_ITEM,
+ wxEVT_MEASURE_ITEM,
+ wxEVT_COMPARE_ITEM,
+ wxEVT_INIT_DIALOG,
+ wxEVT_IDLE,
+ wxEVT_UPDATE_UI,
+
+ /* Generic command events */
+ // Note: a click is a higher-level event
+ // than button down/up
+ wxEVT_COMMAND_LEFT_CLICK,
+ wxEVT_COMMAND_LEFT_DCLICK,
+ wxEVT_COMMAND_RIGHT_CLICK,
+ wxEVT_COMMAND_RIGHT_DCLICK,
+ wxEVT_COMMAND_SET_FOCUS,
+ wxEVT_COMMAND_KILL_FOCUS,
+ wxEVT_COMMAND_ENTER,
+
+ /* Tree control event types */
+ wxEVT_COMMAND_TREE_BEGIN_DRAG,
+ wxEVT_COMMAND_TREE_BEGIN_RDRAG,
+ wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT,
+ wxEVT_COMMAND_TREE_END_LABEL_EDIT,
+ wxEVT_COMMAND_TREE_DELETE_ITEM,
+ wxEVT_COMMAND_TREE_GET_INFO,
+ wxEVT_COMMAND_TREE_SET_INFO,
+ wxEVT_COMMAND_TREE_ITEM_EXPANDED,
+ wxEVT_COMMAND_TREE_ITEM_EXPANDING,
+ wxEVT_COMMAND_TREE_SEL_CHANGED,
+ wxEVT_COMMAND_TREE_SEL_CHANGING,
+ wxEVT_COMMAND_TREE_KEY_DOWN,
+
+ /* List control event types */
+ wxEVT_COMMAND_LIST_BEGIN_DRAG,
+ wxEVT_COMMAND_LIST_BEGIN_RDRAG,
+ wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT,
+ wxEVT_COMMAND_LIST_END_LABEL_EDIT,
+ wxEVT_COMMAND_LIST_DELETE_ITEM,
+ wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS,
+ wxEVT_COMMAND_LIST_GET_INFO,
+ wxEVT_COMMAND_LIST_SET_INFO,
+ wxEVT_COMMAND_LIST_ITEM_SELECTED,
+ wxEVT_COMMAND_LIST_ITEM_DESELECTED,
+ wxEVT_COMMAND_LIST_KEY_DOWN,
+ wxEVT_COMMAND_LIST_INSERT_ITEM,
+ wxEVT_COMMAND_LIST_COL_CLICK,
+
+ /* Tab control event types */
+ wxEVT_COMMAND_TAB_SEL_CHANGED,
+ wxEVT_COMMAND_TAB_SEL_CHANGING
+
+};
+
+// Compatibility
+
+#if WXWIN_COMPATIBILITY
+
+#define wxEVENT_TYPE_BUTTON_COMMAND             wxEVT_COMMAND_BUTTON_CLICKED
+#define wxEVENT_TYPE_CHECKBOX_COMMAND           wxEVT_COMMAND_CHECKBOX_CLICKED
+#define wxEVENT_TYPE_CHOICE_COMMAND             wxEVT_COMMAND_CHOICE_SELECTED
+#define wxEVENT_TYPE_LISTBOX_COMMAND            wxEVT_COMMAND_LISTBOX_SELECTED
+#define wxEVENT_TYPE_LISTBOX_DCLICK_COMMAND     wxEVT_COMMAND_LISTBOX_DOUBLECLICKED
+#define wxEVENT_TYPE_TEXT_COMMAND               wxEVT_COMMAND_TEXT_UPDATED
+#define wxEVENT_TYPE_MULTITEXT_COMMAND          wxEVT_COMMAND_TEXT_UPDATED
+#define wxEVENT_TYPE_MENU_COMMAND               wxEVT_COMMAND_MENU_SELECTED
+#define wxEVENT_TYPE_SLIDER_COMMAND             wxEVT_COMMAND_SLIDER_UPDATED
+#define wxEVENT_TYPE_RADIOBOX_COMMAND           wxEVT_COMMAND_RADIOBOX_SELECTED
+#define wxEVENT_TYPE_RADIOBUTTON_COMMAND        wxEVT_COMMAND_RADIOBUTTON_SELECTED
+#define wxEVENT_TYPE_TEXT_ENTER_COMMAND         wxEVT_COMMAND_TEXT_ENTER
+#define wxEVENT_TYPE_SET_FOCUS                  wxEVT_SET_FOCUS
+#define wxEVENT_TYPE_KILL_FOCUS                 wxEVT_KILL_FOCUS
+#define wxEVENT_TYPE_SCROLLBAR_COMMAND          wxEVT_COMMAND_SCROLLBAR_UPDATED
+#define wxEVENT_TYPE_VIRT_LISTBOX_COMMAND       wxEVT_COMMAND_VLBOX_SELECTED
+#define wxEVENT_TYPE_COMBOBOX_COMMAND           wxEVT_COMMAND_COMBOBOX_SELECTED
+
+#define wxEVENT_TYPE_LEFT_DOWN                  wxEVT_LEFT_DOWN
+#define wxEVENT_TYPE_LEFT_UP                    wxEVT_LEFT_UP
+#define wxEVENT_TYPE_MIDDLE_DOWN                wxEVT_MIDDLE_DOWN
+#define wxEVENT_TYPE_MIDDLE_UP                  wxEVT_MIDDLE_UP
+#define wxEVENT_TYPE_RIGHT_DOWN                 wxEVT_RIGHT_DOWN
+#define wxEVENT_TYPE_RIGHT_UP                   wxEVT_RIGHT_UP
+#define wxEVENT_TYPE_MOTION                     wxEVT_MOTION
+#define wxEVENT_TYPE_ENTER_WINDOW               wxEVT_ENTER_WINDOW
+#define wxEVENT_TYPE_LEAVE_WINDOW               wxEVT_LEAVE_WINDOW
+#define wxEVENT_TYPE_LEFT_DCLICK                wxEVT_LEFT_DCLICK
+#define wxEVENT_TYPE_MIDDLE_DCLICK              wxEVT_MIDDLE_DCLICK
+#define wxEVENT_TYPE_RIGHT_DCLICK               wxEVT_RIGHT_DCLICK
+#define wxEVENT_TYPE_CHAR                       wxEVT_CHAR
+#define wxEVENT_TYPE_SCROLL_TOP                 wxEVT_SCROLL_TOP
+#define wxEVENT_TYPE_SCROLL_BOTTOM              wxEVT_SCROLL_BOTTOM
+#define wxEVENT_TYPE_SCROLL_LINEUP              wxEVT_SCROLL_LINEUP
+#define wxEVENT_TYPE_SCROLL_LINEDOWN            wxEVT_SCROLL_LINEDOWN
+#define wxEVENT_TYPE_SCROLL_PAGEUP              wxEVT_SCROLL_PAGEUP
+#define wxEVENT_TYPE_SCROLL_PAGEDOWN            wxEVT_SCROLL_PAGEDOWN
+#define wxEVENT_TYPE_SCROLL_THUMBTRACK          wxEVT_SCROLL_THUMBTRACK
+
+#endif
+
+/*
+ * wxWindows events, covering all interesting things that might happen
+ * (button clicking, resizing, setting text in widgets, etc.).
+ *
+ * For each completely new event type, derive a new event class.
+ * An event CLASS represents a C++ class defining a range of similar event TYPES;
+ * examples are canvas events, panel item command events.
+ * An event TYPE is a unique identifier for a particular system event,
+ * such as a button press or a listbox deselection.
+ *
+ */
+
+class WXDLLEXPORT wxEvent: public wxObject
+{
+  DECLARE_ABSTRACT_CLASS(wxEvent)
+
+public:
+  wxEvent(int id = 0);
+  inline ~wxEvent(void) {}
+
+  inline void SetEventType(WXTYPE typ) { m_eventType = typ; }
+  inline WXTYPE GetEventType(void) const { return m_eventType; }
+  inline wxObject *GetEventObject(void) const { return m_eventObject; }
+  inline void SetEventObject(wxObject *obj) { m_eventObject = obj; }
+  inline long GetTimestamp(void) const { return m_timeStamp; }
+  inline void SetTimestamp(long ts = 0) { m_timeStamp = ts; }
+  inline int GetId() const { return m_id; }
+  inline void SetId(int Id) { m_id = Id; }
+
+  // Can instruct event processor that we wish to ignore this event
+  // (treat as if the event table entry had not been found)
+  inline void Skip(const bool skip = TRUE) { m_skipped = skip; }
+  inline bool GetSkipped(void) const { return m_skipped; };
+
+public:
+  bool              m_skipped;
+  wxObject*         m_eventObject;
+  char*             m_eventHandle;         // Handle of an underlying windowing system event
+  WXTYPE            m_eventType;
+  long              m_timeStamp;
+  int               m_id;
+
+};
+
+// Item or menu event class
+/*
+ wxEVT_COMMAND_BUTTON_CLICKED
+ wxEVT_COMMAND_CHECKBOX_CLICKED
+ wxEVT_COMMAND_CHOICE_SELECTED
+ wxEVT_COMMAND_LISTBOX_SELECTED
+ wxEVT_COMMAND_LISTBOX_DOUBLECLICKED
+ wxEVT_COMMAND_TEXT_UPDATED
+ wxEVT_COMMAND_TEXT_ENTER
+ wxEVT_COMMAND_MENU_SELECTED
+ wxEVT_COMMAND_SLIDER_UPDATED
+ wxEVT_COMMAND_RADIOBOX_SELECTED
+ wxEVT_COMMAND_RADIOBUTTON_SELECTED
+ wxEVT_COMMAND_SCROLLBAR_UPDATED
+ wxEVT_COMMAND_VLBOX_SELECTED
+ wxEVT_COMMAND_COMBOBOX_SELECTED
+*/
+
+class WXDLLEXPORT wxCommandEvent: public wxEvent
+{
+  DECLARE_DYNAMIC_CLASS(wxCommandEvent)
+
+  wxCommandEvent(WXTYPE commandType = 0, int id = 0);
+  inline ~wxCommandEvent(void) {}
+
+  /*
+   * Accessors dependent on context
+   *
+   */
+
+  // Set/Get listbox/choice client data
+  inline void SetClientData(char* clientData) { m_clientData = clientData; }
+  inline char *GetClientData() const { return m_clientData; }
+
+  // Get listbox selection if single-choice
+  inline int GetSelection() const { return m_commandInt; }
+
+  // Set/Get listbox/choice selection string
+  inline void SetString(char* s) { m_commandString = s; }
+  inline char *GetString() const { return m_commandString; }
+
+  // Get checkbox value
+  inline bool Checked() const { return (m_commandInt != 0); }
+
+  // TRUE if the listbox event was a selection.
+  inline bool IsSelection() const { return (m_extraLong != 0); }
+
+  inline void SetExtraLong(long extraLong) { m_extraLong = extraLong; }
+  inline long GetExtraLong(void) const { return m_extraLong ; }
+
+  inline void SetInt(int i) { m_commandInt = i; }
+  inline long GetInt(void) const { return m_commandInt ; }
+
+ public:
+  char*             m_commandString; // String event argument
+  int               m_commandInt;
+  long              m_extraLong;      // Additional information (e.g. select/deselect)
+  char*             m_clientData;    // Arbitrary client data
+};
+
+// Scroll event class
+/*
+ wxEVT_SCROLL_TOP
+ wxEVT_SCROLL_BOTTOM
+ wxEVT_SCROLL_LINEUP
+ wxEVT_SCROLL_LINEDOWN
+ wxEVT_SCROLL_PAGEUP
+ wxEVT_SCROLL_PAGEDOWN
+ wxEVT_SCROLL_THUMBTRACK
+*/
+
+class WXDLLEXPORT wxScrollEvent: public wxCommandEvent
+{
+  DECLARE_DYNAMIC_CLASS(wxScrollEvent)
+
+ public:
+  wxScrollEvent(WXTYPE commandType = 0, int id = 0, int pos = 0, int orient = 0);
+  inline ~wxScrollEvent(void) {}
+
+  /*
+   * Accessors
+   *
+   */
+
+  inline int GetOrientation(void) const { return (int) m_extraLong ; }
+  inline int GetPosition(void) const { return m_commandInt ; }
+  inline void SetOrientation(int orient) { m_extraLong = (long) orient; }
+  inline void SetPosition(int pos) { m_commandInt = pos; }
+};
+
+// Mouse event class
+
+/*
+ wxEVT_LEFT_DOWN
+ wxEVT_LEFT_UP
+ wxEVT_MIDDLE_DOWN
+ wxEVT_MIDDLE_UP
+ wxEVT_RIGHT_DOWN
+ wxEVT_RIGHT_UP
+ wxEVT_MOTION
+ wxEVT_ENTER_WINDOW
+ wxEVT_LEAVE_WINDOW
+ wxEVT_LEFT_DCLICK
+ wxEVT_MIDDLE_DCLICK
+ wxEVT_RIGHT_DCLICK
+ wxEVT_NC_LEFT_DOWN
+ wxEVT_NC_LEFT_UP,
+ wxEVT_NC_MIDDLE_DOWN,
+ wxEVT_NC_MIDDLE_UP,
+ wxEVT_NC_RIGHT_DOWN,
+ wxEVT_NC_RIGHT_UP,
+ wxEVT_NC_MOTION,
+ wxEVT_NC_ENTER_WINDOW,
+ wxEVT_NC_LEAVE_WINDOW,
+ wxEVT_NC_LEFT_DCLICK,
+ wxEVT_NC_MIDDLE_DCLICK,
+ wxEVT_NC_RIGHT_DCLICK,
+*/
+
+class WXDLLEXPORT wxMouseEvent: public wxEvent
+{
+  DECLARE_DYNAMIC_CLASS(wxMouseEvent)
+
+ public:
+  wxMouseEvent(WXTYPE mouseType = 0);
+
+  // Was it a button event? (*doesn't* mean: is any button *down*?)
+  inline bool IsButton(void) const { return Button(-1); }
+
+  // Was it a down event from button 1, 2 or 3 or any?
+  bool ButtonDown(int but = -1) const;
+
+  // Was it a dclick event from button 1, 2 or 3 or any?
+  bool ButtonDClick(int but = -1) const;
+
+  // Was it a up event from button 1, 2 or 3 or any?
+  bool ButtonUp(int but = -1) const;
+
+  // Was the given button 1,2,3 or any changing state?
+  bool Button(int but) const;
+
+  // Was the given button 1,2,3 or any in Down state?
+  bool ButtonIsDown(int but) const;
+
+  // Find state of shift/control keys
+  inline bool ControlDown(void) const { return m_controlDown; }
+  inline bool MetaDown(void) const { return m_metaDown; }
+  inline bool AltDown(void) const { return m_altDown; }
+  inline bool ShiftDown(void) const { return m_shiftDown; }
+
+  // Find which event was just generated
+  inline bool LeftDown(void) const { return (m_eventType == wxEVT_LEFT_DOWN); }
+  inline bool MiddleDown(void) const { return (m_eventType == wxEVT_MIDDLE_DOWN); }
+  inline bool RightDown(void) const { return (m_eventType == wxEVT_RIGHT_DOWN); }
+
+  inline bool LeftUp(void) const { return (m_eventType == wxEVT_LEFT_UP); }
+  inline bool MiddleUp(void) const { return (m_eventType == wxEVT_MIDDLE_UP); }
+  inline bool RightUp(void) const { return (m_eventType == wxEVT_RIGHT_UP); }
+
+  inline bool LeftDClick(void) const { return (m_eventType == wxEVT_LEFT_DCLICK); }
+  inline bool MiddleDClick(void) const { return (m_eventType == wxEVT_MIDDLE_DCLICK); }
+  inline bool RightDClick(void) const { return (m_eventType == wxEVT_RIGHT_DCLICK); }
+
+  // Find the current state of the mouse buttons (regardless
+  // of current event type)
+  inline bool LeftIsDown(void) const { return m_leftDown; }
+  inline bool MiddleIsDown(void) const { return m_middleDown; }
+  inline bool RightIsDown(void) const { return m_rightDown; }
+
+  // True if a button is down and the mouse is moving
+  inline bool Dragging(void) const { return ((m_eventType == wxEVENT_TYPE_MOTION) && (LeftIsDown() || MiddleIsDown() || RightIsDown())); }
+
+  // True if the mouse is moving, and no button is down
+  inline bool Moving(void) const { return (m_eventType == wxEVT_MOTION); }
+
+  // True if the mouse is just entering the window
+  inline bool Entering(void) const { return (m_eventType == wxEVT_ENTER_WINDOW); }
+
+  // True if the mouse is just leaving the window
+  inline bool Leaving(void) const { return (m_eventType == wxEVT_LEAVE_WINDOW); }
+
+  // Find the position of the event
+  inline void Position(long *xpos, long *ypos) const { *xpos = m_x; *ypos = m_y; }
+
+  // Find the position of the event
+  inline wxPoint GetPosition() const { return wxPoint(m_x, m_y); }
+
+  // Find the logical position of the event given the DC
+  wxPoint GetLogicalPosition(const wxDC& dc) const ;
+
+  // Compatibility
+  inline void Position(float *xpos, float *ypos) const { *xpos = (float) m_x; *ypos = (float) m_y; }
+
+  // Get X position
+  inline long GetX(void) const { return m_x; }
+
+  // Get Y position
+  inline long GetY(void) const { return m_y; }
+
+public:
+  long          m_x;
+  long          m_y;
+  bool          m_leftDown;
+  bool          m_middleDown;
+  bool          m_rightDown;
+
+  bool          m_controlDown;
+  bool          m_shiftDown;
+  bool          m_altDown;
+  bool          m_metaDown;
+
+};
+
+// Keyboard input event class
+
+/*
+ wxEVT_CHAR
+ wxEVT_CHAR_HOOK
+ wxEVT_KEY_UP
+ */
+
+class WXDLLEXPORT wxKeyEvent: public wxEvent
+{
+  DECLARE_DYNAMIC_CLASS(wxKeyEvent)
+
+public:
+  wxKeyEvent(WXTYPE keyType = 0);
+
+  // Find state of shift/control keys
+  inline bool ControlDown(void) const { return m_controlDown; }
+  inline bool MetaDown(void) const { return m_metaDown; }
+  inline bool AltDown(void) const { return m_altDown; }
+  inline bool ShiftDown(void) const { return m_shiftDown; }
+  inline long KeyCode(void) const { return m_keyCode; }
+
+  // Find the position of the event
+  inline void Position(float *xpos, float *ypos) const { *xpos = m_x; *ypos = m_y; }
+
+  // Get X position
+  inline float GetX(void) const { return m_x; }
+
+  // Get Y position
+  inline float GetY(void) const { return m_y; }
+
+public:
+  float         m_x ;
+  float         m_y ;
+  long          m_keyCode;
+  bool          m_controlDown;
+  bool          m_shiftDown;
+  bool          m_altDown;
+  bool          m_metaDown;
+
+};
+
+// Size event class
+/*
+ wxEVT_SIZE
+ */
+
+class WXDLLEXPORT wxSizeEvent: public wxEvent
+{
+  DECLARE_DYNAMIC_CLASS(wxSizeEvent)
+
+ public:
+  wxSize m_size;
+
+  inline wxSizeEvent(void) { m_eventType = wxEVT_SIZE; }
+  inline wxSizeEvent(const wxSize& sz, int id = 0)
+     { m_eventType = wxEVT_SIZE; m_size.x = sz.x; m_size.y = sz.y; m_id = id; }
+
+  inline wxSize GetSize(void) const { return m_size; }
+};
+
+// Move event class
+
+/*
+ wxEVT_MOVE
+ */
+
+class WXDLLEXPORT wxMoveEvent: public wxEvent
+{
+  DECLARE_DYNAMIC_CLASS(wxMoveEvent)
+
+ public:
+  wxPoint m_pos;
+
+  inline wxMoveEvent(void) { m_eventType = wxEVT_MOVE; }
+  inline wxMoveEvent(const wxPoint& pos, int id = 0)
+     { m_eventType = wxEVT_MOVE; m_pos.x = pos.x; m_pos.y = pos.y; m_id = id; }
+
+  inline wxPoint GetPosition(void) const { return m_pos; }
+};
+
+// Paint event class
+/*
+ wxEVT_PAINT
+ wxEVT_NC_PAINT
+ wxEVT_PAINT_ICON
+ */
+
+class WXDLLEXPORT wxPaintEvent: public wxEvent
+{
+  DECLARE_DYNAMIC_CLASS(wxPaintEvent)
+
+ public:
+  inline wxPaintEvent(int Id = 0) { m_eventType = wxEVT_PAINT; m_id = Id; }
+};
+
+// Erase background event class
+/*
+ wxEVT_ERASE_BACKGROUND
+ */
+
+class WXDLLEXPORT wxDC;
+class WXDLLEXPORT wxEraseEvent: public wxEvent
+{
+  DECLARE_DYNAMIC_CLASS(wxEraseEvent)
+ public:
+  wxDC *m_dc ;
+  inline wxEraseEvent(int Id = 0, wxDC *dc = NULL) { m_eventType = wxEVT_ERASE_BACKGROUND; m_id = Id; m_dc = dc; }
+  inline wxDC *GetDC() const { return m_dc; }
+};
+
+// Focus event class
+/*
+ wxEVT_SET_FOCUS
+ wxEVT_KILL_FOCUS
+ */
+
+class WXDLLEXPORT wxFocusEvent: public wxEvent
+{
+  DECLARE_DYNAMIC_CLASS(wxFocusEvent)
+
+ public:
+  inline wxFocusEvent(WXTYPE type = 0, int Id = 0) { m_eventType = type; m_id = Id; }
+};
+
+// Activate event class
+/*
+ wxEVT_ACTIVATE
+ wxEVT_ACTIVATE_APP
+ */
+
+class WXDLLEXPORT wxActivateEvent: public wxEvent
+{
+  DECLARE_DYNAMIC_CLASS(wxActivateEvent)
+
+ public:
+  bool m_active;
+  inline wxActivateEvent(WXTYPE type = 0, bool active = TRUE, int Id = 0) { m_eventType = type; m_active = active; m_id = Id; }
+  inline bool GetActive(void) const { return m_active; }
+};
+
+// InitDialog event class
+/*
+ wxEVT_INIT_DIALOG
+ */
+
+class WXDLLEXPORT wxInitDialogEvent: public wxEvent
+{
+  DECLARE_DYNAMIC_CLASS(wxInitDialogEvent)
+
+ public:
+  inline wxInitDialogEvent(int Id = 0) { m_eventType = wxEVT_INIT_DIALOG; m_id = Id; }
+};
+
+// Miscellaneous menu event class
+/*
+ wxEVT_MENU_CHAR,
+ wxEVT_MENU_INIT,
+ wxEVT_MENU_HIGHLIGHT,
+ wxEVT_POPUP_MENU_INIT,
+ wxEVT_CONTEXT_MENU,
+*/
+
+class WXDLLEXPORT wxMenuEvent: public wxEvent
+{
+  DECLARE_DYNAMIC_CLASS(wxMenuEvent)
+
+public:
+  int m_menuId;
+
+  inline wxMenuEvent(WXTYPE type = 0, int id = 0) { m_eventType = type; m_menuId = id; }
+
+  inline int GetMenuId(void) const { return m_menuId; }
+};
+
+// Window close or session close event class
+/*
+ wxEVT_CLOSE_WINDOW,
+ wxEVT_END_SESSION,
+ wxEVT_QUERY_END_SESSION
+ */
+
+class WXDLLEXPORT wxCloseEvent: public wxEvent
+{
+  DECLARE_DYNAMIC_CLASS(wxCloseEvent)
+public:
+
+  inline wxCloseEvent(WXTYPE type = 0, int id = 0)
+     { m_eventType = type; m_sessionEnding = TRUE; m_loggingOff = TRUE; m_veto = FALSE;
+       m_id = id; m_force = FALSE; }
+
+  inline bool GetSessionEnding(void) const { return m_sessionEnding; }
+  inline bool GetLoggingOff(void) const { return m_loggingOff; }
+  inline void Veto(bool veto = TRUE) { m_veto = veto; }
+  inline bool GetVeto(void) const { return m_veto; }
+  inline void SetForce(bool force) { m_force = force; }
+  inline bool GetForce(void) const { return m_force; }
+
+ protected:
+  bool m_sessionEnding;
+  bool m_loggingOff;
+  bool m_veto;
+  bool m_force;
+
+};
+
+/*
+ wxEVT_SHOW
+ */
+
+class WXDLLEXPORT wxShowEvent: public wxEvent
+{
+  DECLARE_DYNAMIC_CLASS(wxShowEvent)
+public:
+
+  inline wxShowEvent(int id = 0, bool show = FALSE)
+  { m_eventType = wxEVT_SHOW; m_id = id; m_show = show; }
+
+  inline void SetShow(bool show) { m_show = show; }
+  inline bool GetShow(void) const { return m_show; }
+
+protected:
+  bool m_show;
+};
+
+/*
+ wxEVT_ICONIZE
+ */
+
+class WXDLLEXPORT wxIconizeEvent: public wxEvent
+{
+  DECLARE_DYNAMIC_CLASS(wxIconizeEvent)
+public:
+
+  inline wxIconizeEvent(int id = 0)
+  { m_eventType = wxEVT_ICONIZE; m_id = id; }
+};
+
+/*
+ wxEVT_MAXIMIZE
+ */
+
+class WXDLLEXPORT wxMaximizeEvent: public wxEvent
+{
+  DECLARE_DYNAMIC_CLASS(wxMaximizeEvent)
+public:
+
+  inline wxMaximizeEvent(int id = 0)
+  { m_eventType = wxEVT_MAXIMIZE; m_id = id; }
+};
+
+// Joystick event class
+/*
+ wxEVT_JOY_BUTTON_DOWN,
+ wxEVT_JOY_BUTTON_UP,
+ wxEVT_JOY_MOVE,
+ wxEVT_JOY_ZMOVE
+*/
+
+// Which joystick? Same as Windows ids so no conversion necessary.
+#define wxJOYSTICK1     0
+#define wxJOYSTICK2     1
+
+// Which button is down?
+#define wxJOY_BUTTON1   1
+#define wxJOY_BUTTON2   2
+#define wxJOY_BUTTON3   4
+#define wxJOY_BUTTON4   8
+#define wxJOY_BUTTON_ANY -1
+
+class WXDLLEXPORT wxJoystickEvent: public wxEvent
+{
+  DECLARE_DYNAMIC_CLASS(wxJoystickEvent)
+
+ public:
+  wxPoint   m_pos;
+  int       m_zPosition;
+  int       m_buttonChange; // Which button changed?
+  int       m_buttonState; // Which buttons are down?
+  int       m_joyStick; // Which joystick?
+
+  inline wxJoystickEvent(WXTYPE type = 0, int state = 0, int joystick = wxJOYSTICK1, int change = 0)
+     { m_eventType = type; m_buttonState = state; m_pos = wxPoint(0,0); m_zPosition = 0;
+       m_joyStick = joystick; m_buttonChange = change; }
+
+  inline wxPoint GetPosition(void) const { return m_pos; }
+  inline int GetZPosition(void) const { return m_zPosition; }
+  inline int GetButtonState(void) const { return m_buttonState; }
+  inline int GetButtonChange(void) const { return m_buttonChange; }
+  inline int GetJoystick(void) const { return m_joyStick; }
+
+  inline void SetJoystick(int stick) { m_joyStick = stick; }
+  inline void SetButtonState(int state) { m_buttonState = state; }
+  inline void SetButtonChange(int change) { m_buttonChange = change; }
+  inline void SetPosition(const wxPoint& pos) { m_pos = pos; }
+  inline void SetZPosition(int zPos) { m_zPosition = zPos; }
+
+  // Was it a button event? (*doesn't* mean: is any button *down*?)
+  inline bool IsButton(void) const { return ((GetEventType() == wxEVT_JOY_BUTTON_DOWN) ||
+    (GetEventType() == wxEVT_JOY_BUTTON_DOWN)); }
+
+  // Was it a move event?
+  inline bool IsMove(void) const { return (GetEventType() == wxEVT_JOY_MOVE) ; }
+
+  // Was it a zmove event?
+  inline bool IsZMove(void) const { return (GetEventType() == wxEVT_JOY_ZMOVE) ; }
+
+  // Was it a down event from button 1, 2, 3, 4 or any?
+  inline bool ButtonDown(int but = wxJOY_BUTTON_ANY) const
+    { return ((GetEventType() == wxEVT_JOY_BUTTON_DOWN) &&
+              ((but == wxJOY_BUTTON_ANY) || (but == m_buttonChange))); }
+
+  // Was it a up event from button 1, 2, 3 or any?
+  inline bool ButtonUp(int but = wxJOY_BUTTON_ANY) const
+    { return ((GetEventType() == wxEVT_JOY_BUTTON_UP) &&
+                ((but == wxJOY_BUTTON_ANY) || (but == m_buttonChange))); }
+
+  // Was the given button 1,2,3,4 or any in Down state?
+  inline bool ButtonIsDown(int but =  wxJOY_BUTTON_ANY) const
+    { return (((but == wxJOY_BUTTON_ANY) && (m_buttonState != 0)) ||
+              ((m_buttonState & but) == but)); }
+};
+
+// Drop files event class
+/*
+ wxEVT_DROP_FILES
+ */
+
+class WXDLLEXPORT wxDropFilesEvent: public wxEvent
+{
+  DECLARE_DYNAMIC_CLASS(wxDropFilesEvent)
+
+ public:
+  int       m_noFiles;
+  wxPoint   m_pos;
+  wxString* m_files;        // Memory (de)allocated by code calling ProcessEvent
+
+  inline wxDropFilesEvent(WXTYPE type = 0, int noFiles = 0, wxString *files = NULL)
+     { m_eventType = type; m_noFiles = noFiles; m_files = files; }
+
+  inline wxPoint GetPosition(void) const { return m_pos; }
+  inline int GetNumberOfFiles(void) const { return m_noFiles; }
+  inline wxString *GetFiles(void) const { return m_files; }
+};
+
+// Idle event
+/*
+ wxEVT_IDLE
+ */
+
+class WXDLLEXPORT wxIdleEvent: public wxEvent
+{
+  DECLARE_DYNAMIC_CLASS(wxIdleEvent)
+
+public:
+  inline wxIdleEvent(void)
+     { m_eventType = wxEVT_IDLE; m_requestMore = FALSE; }
+
+  inline void RequestMore(bool needMore = TRUE) { m_requestMore = needMore; }
+  inline bool MoreRequested(void) const { return m_requestMore; }
+
+protected:
+  bool m_requestMore;
+};
+
+// Update UI event
+/*
+ wxEVT_UPDATE_UI
+ */
+
+class WXDLLEXPORT wxMenu;
+class WXDLLEXPORT wxWindow;
+
+class WXDLLEXPORT wxUpdateUIEvent: public wxEvent
+{
+  DECLARE_DYNAMIC_CLASS(wxUpdateUIEvent)
+
+  inline wxUpdateUIEvent(wxWindowID commandId = 0)
+     { m_eventType = wxEVT_UPDATE_UI; m_id = commandId;
+       m_checked = FALSE; m_setChecked = FALSE; m_enabled = FALSE; m_setEnabled = FALSE;
+       m_setText = FALSE; m_text = ""; }
+
+  inline bool GetChecked(void) const { return m_checked; }
+  inline bool GetEnabled(void) const { return m_enabled; }
+  inline wxString GetText(void) const { return m_text; }
+  inline bool GetSetText(void) const { return m_setText; }
+  inline bool GetSetChecked(void) const { return m_setChecked; }
+  inline bool GetSetEnabled(void) const { return m_setEnabled; }
+
+  inline void Check(bool check) { m_checked = check; m_setChecked = TRUE; }
+  inline void Enable(bool enable) { m_enabled = enable; m_setEnabled = TRUE; }
+  inline void SetText(const wxString& text) { m_text = text; m_setText = TRUE; }
+
+ protected:
+
+  bool          m_checked;
+  bool          m_enabled;
+  bool          m_setEnabled;
+  bool          m_setText;
+  bool          m_setChecked;
+  wxString      m_text;
+
+};
+
+/*
+ wxEVT_SYS_COLOUR_CHANGED
+ */
+
+// TODO: shouldn't all events record the window ID?
+class WXDLLEXPORT wxSysColourChangedEvent: public wxEvent
+{
+  DECLARE_DYNAMIC_CLASS(wxSysColourChangedEvent)
+
+ public:
+  inline wxSysColourChangedEvent(void)
+     { m_eventType = wxEVT_SYS_COLOUR_CHANGED; }
+};
+
+/* TODO, apart from events for individual controls...
+ wxEVT_POWER,
+ wxEVT_CREATE,
+ wxEVT_DESTROY,
+ wxEVT_SHOW,
+ wxEVT_MOUSE_CAPTURE_CHANGED,
+ wxEVT_SETTING_CHANGED, // WM_WININICHANGE (NT) / WM_SETTINGCHANGE (Win95)
+ wxEVT_QUERY_NEW_PALETTE,
+ wxEVT_PALETTE_CHANGED,
+// wxEVT_FONT_CHANGED,  // WM_FONTCHANGE: roll into wxEVT_SETTING_CHANGED, but remember to propagate
+                        // wxEVT_FONT_CHANGED to all other windows (maybe).
+ wxEVT_DRAW_ITEM, // Leave these three as virtual functions in wxControl?? Platform-specific.
+ wxEVT_MEASURE_ITEM,
+ wxEVT_COMPARE_ITEM
+*/
+
+class WXDLLEXPORT wxWindow;
+class WXDLLEXPORT wxControl;
+
+// struct WXDLLEXPORT wxEventTableEntry;
+
+typedef void (wxObject::*wxObjectEventFunction)(wxEvent&);
+
+struct WXDLLEXPORT wxEventTableEntry
+{
+	int		m_eventType;	        // main event type
+	int		m_id;		            // control/menu/toolbar id
+	int		m_lastId;		        // used for ranges of ids
+	wxObjectEventFunction	m_fn;	// function to call: not wxEventFunction, because
+        				            // of dependency problems
+};
+
+struct WXDLLEXPORT wxEventTable
+{
+    const wxEventTable *baseTable;	// Points to base event table (next in chain)
+    const wxEventTableEntry *entries;	// Points to bottom of entry array
+};
+
+class WXDLLEXPORT wxEvtHandler: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxEvtHandler)
+ public:
+  wxEvtHandler(void);
+  ~wxEvtHandler(void);
+
+  inline wxEvtHandler *GetNextHandler(void) const { return m_nextHandler; }
+  inline wxEvtHandler *GetPreviousHandler(void) const { return m_previousHandler; }
+  inline void SetNextHandler(wxEvtHandler *handler) { m_nextHandler = handler; }
+  inline void SetPreviousHandler(wxEvtHandler *handler) { m_previousHandler = handler; }
+
+  inline void SetEvtHandlerEnabled(bool en) { m_enabled = en; }
+  inline bool GetEvtHandlerEnabled(void) const { return m_enabled; }
+
+  inline virtual void OnCommand(wxWindow& WXUNUSED(win), wxCommandEvent& WXUNUSED(event)) {};
+                                                 // Called if child control has no
+                                                 // callback function
+  // Default behaviour
+  virtual long Default(void) { if (GetNextHandler()) return GetNextHandler()->Default(); else return 0; };
+#if WXWIN_COMPATIBILITY
+  virtual void OldOnMenuCommand(int WXUNUSED(cmd));
+  virtual void OldOnMenuSelect(int WXUNUSED(cmd));
+  virtual void OldOnInitMenuPopup(int WXUNUSED(pos));
+  virtual void OldOnScroll(wxCommandEvent& WXUNUSED(event));
+  virtual void OldOnPaint(void);
+  virtual void OldOnSize(int WXUNUSED(width), int WXUNUSED(height));
+  virtual void OldOnMove(int WXUNUSED(x), int WXUNUSED(y));
+  virtual void OldOnMouseEvent(wxMouseEvent& WXUNUSED(event));
+  virtual void OldOnChar(wxKeyEvent& WXUNUSED(event));
+  // Under Windows, we can intercept character input per dialog or frame
+  virtual bool OldOnCharHook(wxKeyEvent& WXUNUSED(event));
+  virtual void OldOnActivate(bool WXUNUSED(active));
+  virtual void OldOnSetFocus(void);
+  virtual void OldOnKillFocus(void);
+  virtual bool OldOnSysColourChange(void);
+  virtual void OldOnDropFiles(int n, char *files[], int x, int y);
+#endif
+
+  virtual bool OnClose(void);
+  virtual void OnDefaultAction(wxControl *WXUNUSED(initiatingItem)) {};
+  virtual void OnChangeFocus(wxControl *WXUNUSED(from), wxControl *WXUNUSED(to)) {};
+  virtual bool OnFunctionKey(wxKeyEvent &WXUNUSED(event)) { return FALSE; };
+
+  inline char *GetClientData(void) const { return m_clientData; }
+  inline void SetClientData(char *clientData) { m_clientData = clientData; }
+  
+  virtual bool ProcessEvent(wxEvent& event);
+  virtual bool SearchEventTable(wxEventTable& table, wxEvent& event);
+
+private:
+	static const wxEventTableEntry 	sm_eventTableEntries[];
+protected:
+    static const wxEventTable	sm_eventTable;
+	virtual const wxEventTable*	GetEventTable() const;
+protected:
+    wxEvtHandler*     m_nextHandler;
+    wxEvtHandler*     m_previousHandler;
+    char*             m_clientData;                   // Any user client data
+    bool              m_enabled;                      // Is event handler enabled?
+
+};
+
+typedef void (wxEvtHandler::*wxEventFunction)(wxEvent&);
+typedef void (wxEvtHandler::*wxCommandEventFunction)(wxCommandEvent&);
+typedef void (wxEvtHandler::*wxScrollEventFunction)(wxScrollEvent&);
+typedef void (wxEvtHandler::*wxSizeEventFunction)(wxSizeEvent&);
+typedef void (wxEvtHandler::*wxMoveEventFunction)(wxMoveEvent&);
+typedef void (wxEvtHandler::*wxPaintEventFunction)(wxPaintEvent&);
+typedef void (wxEvtHandler::*wxEraseEventFunction)(wxEraseEvent&);
+typedef void (wxEvtHandler::*wxMouseEventFunction)(wxMouseEvent&);
+typedef void (wxEvtHandler::*wxCharEventFunction)(wxKeyEvent&);
+typedef void (wxEvtHandler::*wxFocusEventFunction)(wxFocusEvent&);
+typedef void (wxEvtHandler::*wxActivateEventFunction)(wxActivateEvent&);
+typedef void (wxEvtHandler::*wxMenuEventFunction)(wxMenuEvent&);
+typedef void (wxEvtHandler::*wxJoystickEventFunction)(wxJoystickEvent&);
+typedef void (wxEvtHandler::*wxDropFilesEventFunction)(wxDropFilesEvent&);
+typedef void (wxEvtHandler::*wxInitDialogEventFunction)(wxInitDialogEvent&);
+typedef void (wxEvtHandler::*wxSysColourChangedFunction)(wxSysColourChangedEvent&);
+typedef void (wxEvtHandler::*wxUpdateUIEventFunction)(wxUpdateUIEvent&);
+typedef void (wxEvtHandler::*wxIdleEventFunction)(wxIdleEvent&);
+typedef void (wxEvtHandler::*wxCloseEventFunction)(wxCloseEvent&);
+typedef void (wxEvtHandler::*wxShowEventFunction)(wxShowEvent&);
+typedef void (wxEvtHandler::*wxIconizeEventFunction)(wxShowEvent&);
+typedef void (wxEvtHandler::*wxMaximizeEventFunction)(wxShowEvent&);
+
+// N.B. In GNU-WIN32, you *have* to take the address of a member function
+// (use &) or the compiler crashes...
+
+#define DECLARE_EVENT_TABLE() \
+private:\
+	static const wxEventTableEntry 	sm_eventTableEntries[];\
+protected:\
+	static const wxEventTable	sm_eventTable;\
+	virtual const wxEventTable*	GetEventTable() const;
+
+#define BEGIN_EVENT_TABLE(theClass, baseClass) \
+const wxEventTable *theClass::GetEventTable() const { return &theClass::sm_eventTable; }\
+const wxEventTable theClass::sm_eventTable =\
+	{ &baseClass::sm_eventTable, &theClass::sm_eventTableEntries[0] };\
+const wxEventTableEntry theClass::sm_eventTableEntries[] = { \
+
+#define END_EVENT_TABLE() \
+ { 0, 0, 0, 0 } };
+ 
+/*
+ * Event table macros
+ */
+
+// Generic events
+#define EVT_CUSTOM(event, id, func) { event, id, -1, (wxObjectEventFunction) (wxEventFunction) & func },
+#define EVT_CUSTOM_RANGE(event, id1, id2, func) { event, id1, id2, (wxObjectEventFunction) (wxEventFunction) & func },
+
+// Miscellaneous
+#define EVT_SIZE(func)  { wxEVT_SIZE, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxSizeEventFunction) & func },
+#define EVT_MOVE(func)  { wxEVT_MOVE, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMoveEventFunction) & func },
+#define EVT_CLOSE(func)  { wxEVT_CLOSE_WINDOW, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxCloseEventFunction) & func },
+#define EVT_PAINT(func)  { wxEVT_PAINT, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxPaintEventFunction) & func },
+#define EVT_ERASE_BACKGROUND(func)  { wxEVT_ERASE_BACKGROUND, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxEraseEventFunction) & func },
+#define EVT_CHAR(func)  { wxEVT_CHAR, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxCharEventFunction) & func },
+#define EVT_CHAR_HOOK(func)  { wxEVT_CHAR_HOOK, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxCharEventFunction) & func },
+#define EVT_MENU_HIGHLIGHT(id, func)  { wxEVT_MENU_HIGHLIGHT, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxMenuEventFunction) & func },
+#define EVT_MENU_HIGHLIGHT_ALL(func)  { wxEVT_MENU_HIGHLIGHT, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMenuEventFunction) & func },
+#define EVT_SET_FOCUS(func)  { wxEVT_SET_FOCUS, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxFocusEventFunction) & func },
+#define EVT_KILL_FOCUS(func)  { wxEVT_KILL_FOCUS, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxFocusEventFunction) & func },
+#define EVT_ACTIVATE(func)  { wxEVT_ACTIVATE, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxActivateEventFunction) & func },
+#define EVT_ACTIVATE_APP(func)  { wxEVT_ACTIVATE_APP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxActivateEventFunction) & func },
+#define EVT_END_SESSION(func)  { wxEVT_END_SESSION, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxCloseEventFunction) & func },
+#define EVT_QUERY_END_SESSION(func)  { wxEVT_QUERY_END_SESSION, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxCloseEventFunction) & func },
+#define EVT_DROP_FILES(func)  { wxEVT_DROP_FILES, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxDropFilesEventFunction) & func },
+#define EVT_INIT_DIALOG(func)  { wxEVT_INIT_DIALOG, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxInitDialogEventFunction) & func },
+#define EVT_SYS_COLOUR_CHANGED(func)  { wxEVT_SYS_COLOUR_CHANGED, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxSysColourChangedFunction) & func },
+#define EVT_SHOW(func) { wxEVT_SHOW, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxShowEventFunction) & func },
+#define EVT_MAXIMIZE(func) { wxEVT_MAXIMIZE, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMaximizeEventFunction) & func },
+#define EVT_ICONIZE(func) { wxEVT_ICONIZE, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxIconizeEventFunction) & func },
+
+// Mouse events
+#define EVT_LEFT_DOWN(func) { wxEVT_LEFT_DOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func },
+#define EVT_LEFT_UP(func) { wxEVT_LEFT_UP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func },
+#define EVT_MIDDLE_DOWN(func) { wxEVT_MIDDLE_DOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func },
+#define EVT_MIDDLE_UP(func) { wxEVT_MIDDLE_UP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func },
+#define EVT_RIGHT_DOWN(func) { wxEVT_RIGHT_DOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func },
+#define EVT_RIGHT_UP(func) { wxEVT_RIGHT_UP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func },
+#define EVT_MOTION(func) { wxEVT_MOTION, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func },
+#define EVT_LEFT_DCLICK(func) { wxEVT_LEFT_DCLICK, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func },
+#define EVT_MIDDLE_DCLICK(func) { wxEVT_MIDDLE_DCLICK, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func },
+#define EVT_RIGHT_DCLICK(func) { wxEVT_RIGHT_DCLICK, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func },
+#define EVT_LEAVE_WINDOW(func) { wxEVT_LEAVE_WINDOW, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func },
+#define EVT_ENTER_WINDOW(func) { wxEVT_ENTER_WINDOW, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func },
+
+// All mouse events
+#define EVT_MOUSE_EVENTS(func) \
+ { wxEVT_LEFT_DOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func },\
+ { wxEVT_LEFT_UP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func },\
+ { wxEVT_MIDDLE_DOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func },\
+ { wxEVT_MIDDLE_UP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func },\
+ { wxEVT_RIGHT_DOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func },\
+ { wxEVT_RIGHT_UP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func },\
+ { wxEVT_MOTION, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func },\
+ { wxEVT_LEFT_DCLICK, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func },\
+ { wxEVT_MIDDLE_DCLICK, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func },\
+ { wxEVT_RIGHT_DCLICK, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func },
+
+// EVT_COMMAND
+#define EVT_COMMAND(id, cmd, fn)  { cmd, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+#define EVT_COMMAND_RANGE(id1, id2, cmd, fn)  { cmd, id1, id2, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+
+// Scrolling
+#define EVT_SCROLL(func) \
+  { wxEVT_SCROLL_TOP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },\
+  { wxEVT_SCROLL_BOTTOM, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },\
+  { wxEVT_SCROLL_LINEUP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },\
+  { wxEVT_SCROLL_LINEDOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },\
+  { wxEVT_SCROLL_PAGEUP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },\
+  { wxEVT_SCROLL_PAGEDOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },\
+  { wxEVT_SCROLL_THUMBTRACK, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },
+
+#define EVT_SCROLL_TOP(func) { wxEVT_SCROLL_TOP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },
+#define EVT_SCROLL_BOTTOM(func) { wxEVT_SCROLL_BOTTOM, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },
+#define EVT_SCROLL_LINEUP(func) { wxEVT_SCROLL_LINEUP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },
+#define EVT_SCROLL_LINEDOWN(func) { wxEVT_SCROLL_LINEDOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },
+#define EVT_SCROLL_PAGEUP(func) { wxEVT_SCROLL_PAGEUP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },
+#define EVT_SCROLL_PAGEDOWN(func) { wxEVT_SCROLL_PAGEDOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },
+#define EVT_SCROLL_THUMBTRACK(func) { wxEVT_SCROLL_THUMBTRACK, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },
+
+// Scrolling, with an id
+#define EVT_COMMAND_SCROLL(id, func) \
+  { wxEVT_SCROLL_TOP, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },\
+  { wxEVT_SCROLL_BOTTOM, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },\
+  { wxEVT_SCROLL_LINEUP, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },\
+  { wxEVT_SCROLL_LINEDOWN, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },\
+  { wxEVT_SCROLL_PAGEUP, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },\
+  { wxEVT_SCROLL_PAGEDOWN, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },\
+  { wxEVT_SCROLL_THUMBTRACK, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },
+
+#define EVT_COMMAND_SCROLL_TOP(id, func) { wxEVT_SCROLL_TOP, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },
+#define EVT_COMMAND_SCROLL_BOTTOM(id, func) { wxEVT_SCROLL_BOTTOM, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },
+#define EVT_COMMAND_SCROLL_LINEUP(id, func) { wxEVT_SCROLL_LINEUP, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },
+#define EVT_COMMAND_SCROLL_LINEDOWN(id, func) { wxEVT_SCROLL_LINEDOWN, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },
+#define EVT_COMMAND_SCROLL_PAGEUP(id, func) { wxEVT_SCROLL_PAGEUP, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },
+#define EVT_COMMAND_SCROLL_PAGEDOWN(id, func) { wxEVT_SCROLL_PAGEDOWN, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },
+#define EVT_COMMAND_SCROLL_THUMBTRACK(id, func) { wxEVT_SCROLL_THUMBTRACK, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func },
+
+// Convenience macros for commonly-used commands
+#define EVT_BUTTON(id, fn) { wxEVT_COMMAND_BUTTON_CLICKED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+#define EVT_CHECKBOX(id, fn) { wxEVT_COMMAND_CHECKBOX_CLICKED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+#define EVT_CHOICE(id, fn) { wxEVT_COMMAND_CHOICE_SELECTED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+#define EVT_LISTBOX(id, fn) { wxEVT_COMMAND_LISTBOX_SELECTED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+#define EVT_TEXT(id, fn) { wxEVT_COMMAND_TEXT_UPDATED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+#define EVT_TEXT_ENTER(id, fn) { wxEVT_COMMAND_TEXT_ENTER, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+#define EVT_MENU(id, fn) { wxEVT_COMMAND_MENU_SELECTED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+#define EVT_MENU_RANGE(id1, id2, fn) { wxEVT_COMMAND_MENU_SELECTED, id1, id2, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+#define EVT_SLIDER(id, fn) { wxEVT_COMMAND_SLIDER_UPDATED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+#define EVT_RADIOBOX(id, fn) { wxEVT_COMMAND_RADIOBOX_SELECTED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+#define EVT_RADIOBUTTON(id, fn) { wxEVT_COMMAND_RADIOBUTTON_SELECTED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+// EVT_SCROLLBAR is now obsolete since we use EVT_COMMAND_SCROLL... events
+#define EVT_SCROLLBAR(id, fn) { wxEVT_COMMAND_SCROLLBAR_UPDATED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+#define EVT_VLBOX(id, fn) { wxEVT_COMMAND_VLBOX_SELECTED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+#define EVT_COMBOBOX(id, fn) { wxEVT_COMMAND_COMBOBOX_SELECTED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+#define EVT_TOOL(id, fn) { wxEVT_COMMAND_TOOL_CLICKED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+#define EVT_TOOL_RCLICKED(id, fn) { wxEVT_COMMAND_TOOL_RCLICKED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+#define EVT_TOOL_ENTER(id, fn) { wxEVT_COMMAND_TOOL_ENTER, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+#define EVT_CHECKLISTBOX(id, fn) { wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+
+// Generic command events
+#define EVT_COMMAND_LEFT_CLICK(id, fn) { wxEVT_COMMAND_LEFT_CLICK, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+#define EVT_COMMAND_LEFT_DCLICK(id, fn) { wxEVT_COMMAND_LEFT_DCLICK, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+#define EVT_COMMAND_RIGHT_CLICK(id, fn) { wxEVT_COMMAND_RIGHT_CLICK, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+#define EVT_COMMAND_RIGHT_DCLICK(id, fn) { wxEVT_COMMAND_RIGHT_DCLICK, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+#define EVT_COMMAND_SET_FOCUS(id, fn) { wxEVT_COMMAND_SET_FOCUS, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+#define EVT_COMMAND_KILL_FOCUS(id, fn) { wxEVT_COMMAND_KILL_FOCUS, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+#define EVT_COMMAND_ENTER(id, fn) { wxEVT_COMMAND_ENTER, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn },
+
+// Joystick events
+#define EVT_JOY_DOWN(func) \
+ { wxEVT_JOY_BUTTON_DOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxJoystickEventFunction) & func },
+#define EVT_JOY_UP(func) \
+ { wxEVT_JOY_BUTTON_UP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxJoystickEventFunction) & func },
+#define EVT_JOY_MOVE(func) \
+ { wxEVT_JOY_MOVE, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxJoystickEventFunction) & func },
+#define EVT_JOY_ZMOVE(func) \
+ { wxEVT_JOY_ZMOVE, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxJoystickEventFunction) & func },
+
+// All joystick events
+#define EVT_JOYSTICK_EVENTS(func) \
+ { wxEVT_JOY_BUTTON_DOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxJoystickEventFunction) & func },\
+ { wxEVT_JOY_BUTTON_UP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxJoystickEventFunction) & func },\
+ { wxEVT_JOY_MOVE, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxJoystickEventFunction) & func },\
+ { wxEVT_JOY_ZMOVE, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxJoystickEventFunction) & func },\
+
+// Idle event
+#define EVT_IDLE(func) \
+ { wxEVT_IDLE, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxIdleEventFunction) & func },\
+
+// Update UI event
+#define EVT_UPDATE_UI(id, func) \
+ { wxEVT_UPDATE_UI, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxUpdateUIEventFunction) & func },\
+
+#endif
+	// __EVENTH__
diff --git a/include/wx/file.h b/include/wx/file.h
new file mode 100644
index 0000000000..ece4086f95
--- /dev/null
+++ b/include/wx/file.h
@@ -0,0 +1,159 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        file.cpp
+// Purpose:     wxFile - encapsulates low-level "file descriptor"
+//              wxTempFile - safely replace the old file
+// Author:      Vadim Zeitlin
+// Modified by:
+// Created:     29/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef   __FILEH__
+#define   __FILEH__
+
+#ifdef __GNUG__
+#pragma interface "file.h"
+#endif
+
+// ----------------------------------------------------------------------------
+// simple types
+// ----------------------------------------------------------------------------
+
+#include  <wx/filefn.h>
+
+// define off_t
+#include  <sys/types.h>
+
+#ifdef    _MSC_VER
+  #define   off_t       _off_t
+#endif
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+// error return value for Seek() functions
+const off_t ofsInvalid = (off_t)-1;
+
+// ----------------------------------------------------------------------------
+// class wxFile: raw file IO
+//
+// NB: for space efficiency this class has no virtual functions, including
+//     dtor which is _not_ virtual, so it shouldn't be used as a base class.
+// ----------------------------------------------------------------------------
+class WXDLLEXPORT wxFile
+{
+public:
+  // more file constants
+  // -------------------
+    
+    // opening mode
+  enum OpenMode { read, write, read_write };
+    // standard values for file descriptor
+  enum { fd_invalid = -1, fd_stdin, fd_stdout, fd_stderr };
+    // seek type
+  enum SeekMode { FromStart, FromEnd, FromCurrent };
+
+  // static functions
+  // ----------------
+  static bool Exists(const char *sz);  // also checks it's a regular file
+
+  // ctors
+  // -----
+    // def ctor
+  wxFile() { m_fd = fd_invalid; }
+    // open specified file (may fail, use IsOpened())
+  wxFile(const char *szFileName, OpenMode mode = read);
+    // attach to (already opened) file
+  wxFile(int fd) { m_fd = fd; }
+
+  // open/close
+  bool Create(const char *szFileName, bool bOverwrite = FALSE);
+  bool Open(const char *szFileName, OpenMode mode = read);
+  void Attach(int fd) { Close(); m_fd = fd; }
+  inline void Close();  // Close is a NOP if not opened
+
+  // read/write (unbuffered)
+    // returns number of bytes read or ofsInvalid on error
+  off_t Read(void *pBuf, off_t nCount);
+    // returns true on success
+  bool Write(const void *pBuf, uint nCount);
+    // returns true on success
+  bool Write(const wxString& str) { return Write(str.c_str(), str.Len()); }
+    // flush data not yet written
+  bool Flush();
+
+  // file pointer operations (return ofsInvalid on failure)
+    // move ptr ofs bytes related to start/current off_t/end of file
+  off_t Seek(off_t ofs, SeekMode mode = FromStart);
+    // move ptr to ofs bytes before the end
+  off_t SeekEnd(off_t ofs = 0) { return Seek(ofs, FromEnd); }
+    // get current off_t
+  off_t Tell() const;
+    // get current file length
+  off_t Length() const;
+
+  // simple accessors
+    // is file opened?
+  bool IsOpened() const { return m_fd != fd_invalid; }
+    // is end of file reached?
+  bool Eof() const;
+    
+  // dtor closes the file if opened
+ ~wxFile();
+
+private:
+  // copy ctor and assignment operator are private because
+  // it doesn't make sense to copy files this way:
+  // attempt to do it will provoke a compile-time error.
+  wxFile(const wxFile&);
+  wxFile& operator=(const wxFile&);
+
+  int m_fd; // file descriptor or INVALID_FD if not opened
+};
+
+// ----------------------------------------------------------------------------
+// class wxTempFile: if you want to replace another file, create an instance
+// of wxTempFile passing the name of the file to be replaced to the ctor. Then
+// you can write to wxTempFile and call Commit() function to replace the old
+// file (and close this one) or call Discard() to cancel the modification. If
+// you call neither of them, dtor will call Discard().
+// ----------------------------------------------------------------------------
+class wxTempFile
+{
+public:
+  // ctors
+    // default
+  wxTempFile() { }
+    // associates the temp file with the file to be replaced and opens it
+  wxTempFile(const wxString& strName);
+
+  // open the temp file (strName is the name of file to be replaced)
+  bool Open(const wxString& strName);
+
+  // is the file opened?
+  bool IsOpened() const { return m_file.IsOpened(); }
+
+  // I/O (both functions return true on success, false on failure)
+  bool Write(const void *p, uint n) { return m_file.Write(p, n); }
+  bool Write(const wxString& str)   { return m_file.Write(str);  }
+
+  // different ways to close the file
+    // validate changes and delete the old file of name m_strName
+  bool Commit();
+    // discard changes
+  void Discard();
+
+  // dtor calls Discard() if file is still opened
+ ~wxTempFile();
+
+private:
+  wxString  m_strName,  // name of the file to replace in Commit()
+            m_strTemp;  // temporary file name
+  wxFile    m_file;     // the temporary file
+};
+
+#endif
+	// __FILEH__
diff --git a/include/wx/filedlg.h b/include/wx/filedlg.h
new file mode 100644
index 0000000000..f877d9b471
--- /dev/null
+++ b/include/wx/filedlg.h
@@ -0,0 +1,13 @@
+#ifndef __FILEDLGH_BASE__
+#define __FILEDLGH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/filedlg.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/filedlg.h"
+#elif defined(__GTK__)
+#include "wx/gtk/filedlg.h"
+#endif
+
+#endif
+    // __FILEDLGH_BASE__
diff --git a/include/wx/filefn.h b/include/wx/filefn.h
new file mode 100644
index 0000000000..64ff0521de
--- /dev/null
+++ b/include/wx/filefn.h
@@ -0,0 +1,166 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        filefn.h
+// Purpose:     File- and directory-related functions
+// Author:      Julian Smart
+// Modified by:
+// Created:     29/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Julian Smart
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef   __FILEFNH__
+#define   __FILEFNH__
+
+#ifdef __GNUG__
+#pragma interface "filefn.h"
+#endif
+
+#include "wx/list.h"
+
+bool WXDLLEXPORT wxFileExists(const wxString& filename);
+#define FileExists wxFileExists
+
+// does the path exist? (may have or not '/' or '\\' at the end)
+bool WXDLLEXPORT wxPathExists(const char *pszPathName);
+
+#define wxDirExists wxPathExists
+#define DirExists wxDirExists
+
+bool WXDLLEXPORT wxIsAbsolutePath(const wxString& filename);
+#define IsAbsolutePath wxIsAbsolutePath
+
+// Get filename
+char* WXDLLEXPORT wxFileNameFromPath(char *path);
+wxString WXDLLEXPORT wxFileNameFromPath(const wxString& path);
+#define FileNameFromPath wxFileNameFromPath
+
+// Get directory
+char* WXDLLEXPORT wxPathOnly(char *path);
+wxString WXDLLEXPORT wxPathOnly(const wxString& path);
+#define PathOnly wxPathOnly
+
+// wxString version
+wxString WXDLLEXPORT wxRealPath(const wxString& path);
+
+void WXDLLEXPORT wxDos2UnixFilename(char *s);
+#define Dos2UnixFilename wxDos2UnixFilename
+
+void WXDLLEXPORT wxUnix2DosFilename(char *s);
+#define Unix2DosFilename wxUnix2DosFilename
+
+// Strip the extension, in situ
+void WXDLLEXPORT wxStripExtension(char *buffer);
+
+// Get a temporary filename, opening and closing the file.
+char* WXDLLEXPORT wxGetTempFileName(const wxString& prefix, char *buf = NULL);
+
+// Expand file name (~/ and ${OPENWINHOME}/ stuff)
+char* WXDLLEXPORT wxExpandPath(char *dest, const char *path);
+
+// Contract w.r.t environment (</usr/openwin/lib, OPENWHOME> -> ${OPENWINHOME}/lib)
+// and make (if under the home tree) relative to home
+// [caller must copy-- volatile]
+char* WXDLLEXPORT wxContractPath (const wxString& filename,
+   const wxString& envname = "", const wxString& user = "");
+
+// Destructive removal of /./ and /../ stuff
+char* WXDLLEXPORT wxRealPath(char *path);
+
+// Allocate a copy of the full absolute path
+char* WXDLLEXPORT wxCopyAbsolutePath(const wxString& path);
+
+// Get first file name matching given wild card.
+// Flags are reserved for future use.
+#define wxFILE  1
+#define wxDIR   2
+char* WXDLLEXPORT wxFindFirstFile(const char *spec, int flags = wxFILE);
+char* WXDLLEXPORT wxFindNextFile(void);
+
+// Does the pattern contain wildcards?
+bool WXDLLEXPORT wxIsWild(const wxString& pattern);
+
+// Does the pattern match the text (usually a filename)?
+// If dot_special is TRUE, doesn't match * against . (eliminating
+// `hidden' dot files)
+bool WXDLLEXPORT wxMatchWild(const wxString& pattern,  const wxString& text, bool dot_special = TRUE);
+
+// Concatenate two files to form third
+bool WXDLLEXPORT wxConcatFiles(const wxString& file1, const wxString& file2, const wxString& file3);
+
+// Copy file1 to file2
+bool WXDLLEXPORT wxCopyFile(const wxString& file1, const wxString& file2);
+
+// Remove file
+bool WXDLLEXPORT wxRemoveFile(const wxString& file);
+
+// Rename file
+bool WXDLLEXPORT wxRenameFile(const wxString& file1, const wxString& file2);
+
+// Get current working directory.
+// If buf is NULL, allocates space using new, else
+// copies into buf.
+// IMPORTANT NOTE getcwd is know not to work under some releases
+// of Win32s 1.3, according to MS release notes!
+char* WXDLLEXPORT wxGetWorkingDirectory(char *buf = NULL, int sz = 1000);
+
+// Set working directory
+bool WXDLLEXPORT wxSetWorkingDirectory(const wxString& d);
+
+// Make directory
+bool WXDLLEXPORT wxMkdir(const wxString& dir);
+
+// Remove directory. Flags reserved for future use.
+bool WXDLLEXPORT wxRmdir(const wxString& dir, int flags = 0);
+
+// separators in file names
+#define FILE_SEP_EXT        '.'
+#define FILE_SEP_DSK        ':'
+#define FILE_SEP_PATH_DOS   '\\'
+#define FILE_SEP_PATH_UNIX  '/'
+
+// separator in the path list (as in PATH environment variable)
+// NB: these are strings and not characters on purpose!
+#define PATH_SEP_DOS        ";"
+#define PATH_SEP_UNIX       ":"
+
+// platform independent versions
+#ifdef  __UNIX__
+  #define FILE_SEP_PATH     FILE_SEP_PATH_UNIX
+  #define PATH_SEP          PATH_SEP_UNIX
+#else   // Windows
+  #define FILE_SEP_PATH     FILE_SEP_PATH_DOS
+  #define PATH_SEP          PATH_SEP_DOS
+#endif  // Unix/Windows
+
+// is the char a path separator?
+inline bool wxIsPathSeparator(char c)
+  { return c == FILE_SEP_PATH_DOS || c == FILE_SEP_PATH_UNIX; }
+
+// does the string ends with path separator?
+bool WXDLLEXPORT wxEndsWithPathSeparator(const char *pszFileName);
+
+// find a file in a list of directories, returns false if not found
+bool WXDLLEXPORT wxFindFileInPath(wxString *pStr, const char *pszPath, const char *pszFile);
+
+// Path searching
+class WXDLLEXPORT wxPathList: public wxStringList
+{
+  DECLARE_DYNAMIC_CLASS(wxPathList)
+
+  public:
+  void AddEnvList(const wxString& envVariable);    // Adds all paths in environment variable
+  void Add(const wxString& path);
+  wxString FindValidPath(const wxString& filename);   // Find the first full path
+                                         // for which the file exists
+  wxString FindAbsoluteValidPath(const wxString& filename);   // Find the first full path
+                                         // for which the file exists; ensure it's an absolute
+                                         // path that gets returned.
+  void EnsureFileAccessible(const wxString& path); // Given full path and filename,
+                                         // add path to list
+  bool Member(const wxString& path);
+};
+
+#endif
+  // __FILEFNH__
+
diff --git a/include/wx/font.h b/include/wx/font.h
new file mode 100644
index 0000000000..438c623973
--- /dev/null
+++ b/include/wx/font.h
@@ -0,0 +1,13 @@
+#ifndef __FONTH_BASE__
+#define __FONTH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/font.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/font.h"
+#elif defined(__GTK__)
+#include "wx/gtk/font.h"
+#endif
+
+#endif
+    // __FONTH_BASE__
diff --git a/include/wx/fontdlg.h b/include/wx/fontdlg.h
new file mode 100644
index 0000000000..ca180e0bfe
--- /dev/null
+++ b/include/wx/fontdlg.h
@@ -0,0 +1,13 @@
+#ifndef __FONTDLGH_BASE__
+#define __FONTDLGH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/fontdlg.h"
+#elif defined(__MOTIF__)
+#include "wx/generic/fontdlgg.h"
+#elif defined(__GTK__)
+#include "wx/generic/fontdlgg.h"
+#endif
+
+#endif
+    // __FONTDLGH_BASE__
diff --git a/include/wx/frame.h b/include/wx/frame.h
new file mode 100644
index 0000000000..4b42b3ac4c
--- /dev/null
+++ b/include/wx/frame.h
@@ -0,0 +1,13 @@
+#ifndef __FRAMEH_BASE__
+#define __FRAMEH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/frame.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/frame.h"
+#elif defined(__GTK__)
+#include "wx/gtk/frame.h"
+#endif
+
+#endif
+    // __FRAMEH_BASE__
diff --git a/include/wx/gauge.h b/include/wx/gauge.h
new file mode 100644
index 0000000000..d9bdbf7faa
--- /dev/null
+++ b/include/wx/gauge.h
@@ -0,0 +1,13 @@
+#ifndef __GAUGEH_BASE__
+#define __GAUGEH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/gauge.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/gauge.h"
+#elif defined(__GTK__)
+#include "wx/gtk/gauge.h"
+#endif
+
+#endif
+    // __GAUGEH_BASE__
diff --git a/include/wx/gdicmn.h b/include/wx/gdicmn.h
new file mode 100644
index 0000000000..36c371c91c
--- /dev/null
+++ b/include/wx/gdicmn.h
@@ -0,0 +1,335 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        gdicmn.h
+// Purpose:     Common GDI classes, types and declarations
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c)
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __GDICMNH__
+#define __GDICMNH__
+
+#ifdef __GNUG__
+#pragma interface "gdicmn.h"
+#endif
+
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/hash.h"
+#include "wx/setup.h"
+
+#ifdef __WINDOWS__
+#include "wx/msw/colour.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/colour.h"
+#elif defined(__GTK__)
+#include "wx/gtk/colour.h"
+#endif
+
+// Standard cursors
+typedef enum {
+ wxCURSOR_ARROW =  1,
+ wxCURSOR_BULLSEYE,
+ wxCURSOR_CHAR,
+ wxCURSOR_CROSS,
+ wxCURSOR_HAND,
+ wxCURSOR_IBEAM,
+ wxCURSOR_LEFT_BUTTON,
+ wxCURSOR_MAGNIFIER,
+ wxCURSOR_MIDDLE_BUTTON,
+ wxCURSOR_NO_ENTRY,
+ wxCURSOR_PAINT_BRUSH,
+ wxCURSOR_PENCIL,
+ wxCURSOR_POINT_LEFT,
+ wxCURSOR_POINT_RIGHT,
+ wxCURSOR_QUESTION_ARROW,
+ wxCURSOR_RIGHT_BUTTON,
+ wxCURSOR_SIZENESW,
+ wxCURSOR_SIZENS,
+ wxCURSOR_SIZENWSE,
+ wxCURSOR_SIZEWE,
+ wxCURSOR_SIZING,
+ wxCURSOR_SPRAYCAN,
+ wxCURSOR_WAIT,
+ wxCURSOR_WATCH,
+ wxCURSOR_BLANK
+#ifdef __X__
+  /* Not yet implemented for Windows */
+  , wxCURSOR_CROSS_REVERSE,
+  wxCURSOR_DOUBLE_ARROW,
+  wxCURSOR_BASED_ARROW_UP,
+  wxCURSOR_BASED_ARROW_DOWN
+#endif
+} _standard_cursors_t;
+
+class WXDLLEXPORT wxSize: public wxObject
+{
+public:
+  long x;
+  long y;
+  inline wxSize(void) { x = 0; y = 0; }
+  inline wxSize(long xx, long yy) { x = xx; y = yy; }
+  inline wxSize(const wxSize& sz) { x = sz.x; y = sz.y; }
+  inline void operator = (const wxSize& sz) { x = sz.x; y = sz.y; }
+  inline void Set(long xx, long yy) { x = xx; y = yy; }
+  inline long GetX() const { return x; }
+  inline long GetY() const { return y; }
+};
+
+// Point
+class WXDLLEXPORT wxRealPoint: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxRealPoint)
+ public:
+  double x;
+  double y;
+  inline wxRealPoint(void) { x = 0.0; y = 0.0; };
+  inline wxRealPoint(double the_x, double the_y) { x = the_x; y = the_y; };
+
+  inline void operator = (const wxRealPoint& pt) { x = pt.x; y = pt.y; }
+};
+
+class WXDLLEXPORT wxPoint: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxPoint)
+ public:
+  long x;
+  long y;
+  inline wxPoint(void) { x = 0; y = 0; };
+  wxPoint(long the_x, long the_y) { x = the_x; y = the_y; };
+  inline void operator = (const wxPoint& pt) { x = pt.x; y = pt.y; }
+};
+
+#if WXWIN_COMPATIBILITY
+#define wxIntPoint wxPoint
+#define wxRectangle wxRect
+#endif
+
+class WXDLLEXPORT wxRect : public wxObject {
+    DECLARE_DYNAMIC_CLASS(wxRect)
+public:
+   wxRect(void) ;
+   wxRect(const long x, const long y, const long w, const long h);
+   wxRect(const wxPoint& topLeft, const wxPoint& bottomRight);
+   wxRect(const wxPoint& pos, const wxSize& size);
+   wxRect(const wxRect& rect);
+
+   inline long  GetX(void) const        { return x; }
+   inline void SetX(const long X)       { x = X; }
+   inline long  GetY(void) const        { return y; }
+   inline void SetY(const long Y)       { y = Y; }
+   inline long  GetWidth() const        { return width; }
+   inline void SetWidth(const long w)   { width = w; }
+   inline long  GetHeight() const       { return height; }
+   inline void SetHeight(const long h)  { height = h; }
+
+   inline wxPoint GetPosition(void) { return wxPoint(x, y); }
+   inline wxSize GetSize(void) { return wxSize(width, height); }
+
+   inline long  GetLeft(void)   const { return x; }
+   inline long  GetTop(void)    const { return y; }
+   inline long  GetBottom(void) const { return y + height; }
+   inline long  GetRight(void)  const { return x + width; }
+
+   wxRect& operator = (const wxRect& rect);
+   bool operator == (const wxRect& rect);
+   bool operator != (const wxRect& rect);
+public:
+   long x, y, width, height;
+};
+
+class WXDLLEXPORT wxBrush;
+class WXDLLEXPORT wxPen;
+class WXDLLEXPORT wxBitmap;
+class WXDLLEXPORT wxIcon;
+class WXDLLEXPORT wxCursor;
+class WXDLLEXPORT wxFont;
+class WXDLLEXPORT wxPalette;
+class WXDLLEXPORT wxPalette;
+
+/*
+ * Bitmap flags
+ */
+
+// Hint to indicate filetype
+#define wxBITMAP_TYPE_BMP               1
+#define wxBITMAP_TYPE_BMP_RESOURCE      2
+#define wxBITMAP_TYPE_ICO               3
+#define wxBITMAP_TYPE_ICO_RESOURCE      4
+#define wxBITMAP_TYPE_CUR               5
+#define wxBITMAP_TYPE_CUR_RESOURCE      6
+#define wxBITMAP_TYPE_XBM               7
+#define wxBITMAP_TYPE_XBM_DATA          8
+#define wxBITMAP_TYPE_XPM               9
+#define wxBITMAP_TYPE_XPM_DATA          10
+#define wxBITMAP_TYPE_TIF               11
+#define wxBITMAP_TYPE_TIF_RESOURCE      12
+#define wxBITMAP_TYPE_GIF               13
+#define wxBITMAP_TYPE_GIF_RESOURCE      14
+#define wxBITMAP_TYPE_PNG               15
+#define wxBITMAP_TYPE_PNG_RESOURCE      16
+#define wxBITMAP_TYPE_ANY               50
+
+#define wxBITMAP_TYPE_RESOURCE wxBITMAP_TYPE_BMP_RESOURCE
+
+class WXDLLEXPORT wxBitmap;
+class WXDLLEXPORT wxCursor;
+class WXDLLEXPORT wxIcon;
+
+// Management of pens, brushes and fonts
+class WXDLLEXPORT wxPenList: public wxList
+{
+  DECLARE_DYNAMIC_CLASS(wxPenList)
+ public:
+  inline wxPenList(void)
+    { }
+  ~wxPenList(void);
+  void AddPen(wxPen *pen);
+  void RemovePen(wxPen *pen);
+  wxPen *FindOrCreatePen(const wxColour& colour, const int width, const int style);
+  wxPen *FindOrCreatePen(const wxString& colour, const int width, const int style);
+};
+
+class WXDLLEXPORT wxBrushList: public wxList
+{
+  DECLARE_DYNAMIC_CLASS(wxBrushList)
+ public:
+  inline wxBrushList(void)
+    { }
+  ~wxBrushList(void);
+  void AddBrush(wxBrush *brush);
+  void RemoveBrush(wxBrush *brush);
+  wxBrush *FindOrCreateBrush(const wxColour& colour, const int style);
+  wxBrush *FindOrCreateBrush(const wxString& colour, const int style);
+};
+
+WXDLLEXPORT_DATA(extern const char*) wxEmptyString;
+
+class WXDLLEXPORT wxFontList: public wxList
+{
+  DECLARE_DYNAMIC_CLASS(wxFontList)
+ public:
+  inline wxFontList(void)
+    { }
+  ~wxFontList(void);
+  void AddFont(wxFont *font);
+  void RemoveFont(wxFont *font);
+  wxFont *FindOrCreateFont(const int pointSize, const int family, const int style, const int weight,
+    const bool underline = FALSE, const wxString& face = wxEmptyString);
+};
+
+class WXDLLEXPORT wxColourDatabase: public wxList
+{
+  DECLARE_CLASS(wxColourDatabase)
+ public:
+  wxColourDatabase(int type);
+  ~wxColourDatabase(void) ;
+  // Not const because it may add a name to the database
+  wxColour *FindColour(const wxString& colour) ;
+  wxString FindName(const wxColour& colour) const;
+  void Initialize(void);
+};
+
+class WXDLLEXPORT wxBitmapList: public wxList
+{
+  DECLARE_DYNAMIC_CLASS(wxBitmapList)
+ public:
+   wxBitmapList(void);
+  ~wxBitmapList(void);
+
+  void AddBitmap(wxBitmap *bitmap);
+  void RemoveBitmap(wxBitmap *bitmap);
+};
+
+// Lists of GDI objects
+WXDLLEXPORT_DATA(extern wxPenList*) 	wxThePenList;
+WXDLLEXPORT_DATA(extern wxBrushList*) 	wxTheBrushList;
+WXDLLEXPORT_DATA(extern wxFontList*)		wxTheFontList;
+WXDLLEXPORT_DATA(extern wxBitmapList*)	wxTheBitmapList;
+
+// Stock objects
+WXDLLEXPORT_DATA(extern wxFont*)			wxNORMAL_FONT;
+WXDLLEXPORT_DATA(extern wxFont*)			wxSMALL_FONT;
+WXDLLEXPORT_DATA(extern wxFont*)			wxITALIC_FONT;
+WXDLLEXPORT_DATA(extern wxFont*)			wxSWISS_FONT;
+
+WXDLLEXPORT_DATA(extern wxPen*)			wxRED_PEN;
+WXDLLEXPORT_DATA(extern wxPen*)			wxCYAN_PEN;
+WXDLLEXPORT_DATA(extern wxPen*)			wxGREEN_PEN;
+WXDLLEXPORT_DATA(extern wxPen*)			wxBLACK_PEN;
+WXDLLEXPORT_DATA(extern wxPen*)			wxWHITE_PEN;
+WXDLLEXPORT_DATA(extern wxPen*)			wxTRANSPARENT_PEN;
+WXDLLEXPORT_DATA(extern wxPen*)			wxBLACK_DASHED_PEN;
+WXDLLEXPORT_DATA(extern wxPen*)			wxGREY_PEN;
+WXDLLEXPORT_DATA(extern wxPen*)			wxMEDIUM_GREY_PEN;
+WXDLLEXPORT_DATA(extern wxPen*)			wxLIGHT_GREY_PEN;
+
+WXDLLEXPORT_DATA(extern wxBrush*)		wxBLUE_BRUSH;
+WXDLLEXPORT_DATA(extern wxBrush*)		wxGREEN_BRUSH;
+WXDLLEXPORT_DATA(extern wxBrush*)		wxWHITE_BRUSH;
+WXDLLEXPORT_DATA(extern wxBrush*)		wxBLACK_BRUSH;
+WXDLLEXPORT_DATA(extern wxBrush*)		wxGREY_BRUSH;
+WXDLLEXPORT_DATA(extern wxBrush*)		wxMEDIUM_GREY_BRUSH;
+WXDLLEXPORT_DATA(extern wxBrush*)		wxLIGHT_GREY_BRUSH;
+WXDLLEXPORT_DATA(extern wxBrush*)		wxTRANSPARENT_BRUSH;
+WXDLLEXPORT_DATA(extern wxBrush*)		wxCYAN_BRUSH;
+WXDLLEXPORT_DATA(extern wxBrush*)		wxRED_BRUSH;
+
+WXDLLEXPORT_DATA(extern wxColour*)		wxBLACK;
+WXDLLEXPORT_DATA(extern wxColour*)		wxWHITE;
+WXDLLEXPORT_DATA(extern wxColour*)		wxRED;
+WXDLLEXPORT_DATA(extern wxColour*)		wxBLUE;
+WXDLLEXPORT_DATA(extern wxColour*)		wxGREEN;
+WXDLLEXPORT_DATA(extern wxColour*)		wxCYAN;
+WXDLLEXPORT_DATA(extern wxColour*)		wxLIGHT_GREY;
+
+// 'Null' objects
+WXDLLEXPORT_DATA(extern wxBitmap) 		wxNullBitmap;
+WXDLLEXPORT_DATA(extern wxIcon)   		wxNullIcon;
+WXDLLEXPORT_DATA(extern wxCursor) 		wxNullCursor;
+WXDLLEXPORT_DATA(extern wxPen)    		wxNullPen;
+WXDLLEXPORT_DATA(extern wxBrush)  		wxNullBrush;
+WXDLLEXPORT_DATA(extern wxPalette) 		wxNullPalette;
+WXDLLEXPORT_DATA(extern wxFont)   		wxNullFont;
+WXDLLEXPORT_DATA(extern wxColour) 		wxNullColour;
+
+// Stock cursors types
+WXDLLEXPORT_DATA(extern wxCursor*)		wxSTANDARD_CURSOR;
+WXDLLEXPORT_DATA(extern wxCursor*)		wxHOURGLASS_CURSOR;
+WXDLLEXPORT_DATA(extern wxCursor*)		wxCROSS_CURSOR;
+
+WXDLLEXPORT_DATA(extern wxColourDatabase*)	wxTheColourDatabase;
+extern void WXDLLEXPORT wxInitializeStockObjects(void);
+extern void WXDLLEXPORT wxDeleteStockObjects(void);
+
+extern bool WXDLLEXPORT wxColourDisplay(void);
+
+// Returns depth of screen
+extern int WXDLLEXPORT wxDisplayDepth(void);
+
+extern void WXDLLEXPORT wxDisplaySize(int *width, int *height);
+
+extern void WXDLLEXPORT wxSetCursor(const wxCursor& cursor);
+
+// Useful macro for create icons portably
+
+#ifdef __WINDOWS__
+# define wxICON(X) wxIcon(X##_icon);
+#elif defined(__X__)
+# define wxICON(X) wxIcon(X##_bits, X##_width, X##_height);
+#else
+# define wxICON    wxIcon
+#endif
+
+/*
+  Example:
+  #define wxbuild_icon "wxbuild"
+ 
+  wxIcon *icon = new wxICON(wxbuild);
+ */
+
+#endif
+    // __GDICMNH__
diff --git a/include/wx/gdiobj.h b/include/wx/gdiobj.h
new file mode 100644
index 0000000000..aa3606dbdf
--- /dev/null
+++ b/include/wx/gdiobj.h
@@ -0,0 +1,13 @@
+#ifndef __GDIOBJH_BASE__
+#define __GDIOBJH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/gdiobj.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/gdiobj.h"
+#elif defined(__GTK__)
+#include "wx/gtk/gdiobj.h"
+#endif
+
+#endif
+    // __GDIOBJH_BASE__
diff --git a/include/wx/generic/choicdgg.h b/include/wx/generic/choicdgg.h
new file mode 100644
index 0000000000..28517d704e
--- /dev/null
+++ b/include/wx/generic/choicdgg.h
@@ -0,0 +1,100 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        choicdgg.h
+// Purpose:     Generic choice dialogs
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c)
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __CHOICEDLGH_G__
+#define __CHOICEDLGH_G__
+
+#ifdef __GNUG__
+#pragma interface "choicdgg.h"
+#endif
+
+#include "wx/setup.h"
+#include "wx/dialog.h"
+
+#define wxCHOICE_HEIGHT 150
+#define wxCHOICE_WIDTH 200
+
+#define wxID_LISTBOX 3000
+
+class WXDLLEXPORT wxSingleChoiceDialog: public wxDialog
+{
+DECLARE_DYNAMIC_CLASS(wxSingleChoiceDialog)
+public:
+    wxSingleChoiceDialog(wxWindow *parent, const wxString& message, const wxString& caption,
+        const int n, const wxString *choices, char **clientData = NULL, long style = wxOK|wxCANCEL|wxCENTRE, const wxPoint& pos = wxDefaultPosition);
+
+    wxSingleChoiceDialog(wxWindow *parent, const wxString& message, const wxString& caption,
+        const wxStringList& choices, char **clientData = NULL, long style = wxOK|wxCANCEL|wxCENTRE, const wxPoint& pos = wxDefaultPosition);
+
+    bool Create(wxWindow *parent, const wxString& message, const wxString& caption,
+        const int n, const wxString *choices, char **clientData = NULL, long style = wxOK|wxCANCEL|wxCENTRE, const wxPoint& pos = wxDefaultPosition);
+    bool Create(wxWindow *parent, const wxString& message, const wxString& caption,
+        const wxStringList& choices, char **clientData = NULL, long style = wxOK|wxCANCEL|wxCENTRE, const wxPoint& pos = wxDefaultPosition);
+
+    inline int GetSelection(void) const { return m_selection; }
+    inline wxString GetStringSelection(void) const { return m_stringSelection; }
+    inline char *GetSelectionClientData(void) const { return m_clientData; }
+
+    void OnOK(wxCommandEvent& event);
+
+DECLARE_EVENT_TABLE()
+
+protected:
+    long        m_dialogStyle;
+    int         m_selection;
+    wxString    m_stringSelection;
+    char*       m_clientData;
+};
+
+wxString WXDLLEXPORT wxGetSingleChoice(const wxString& message, const wxString& caption,
+                        const int n, const wxString *choices, wxWindow *parent = NULL,
+                        const int x = -1, const int y = -1, const bool centre = TRUE,
+                        const int width = wxCHOICE_WIDTH, const int height = wxCHOICE_HEIGHT);
+
+wxString WXDLLEXPORT wxGetSingleChoice(const wxString& message, const wxString& caption,
+                        const int n, char *choices[], wxWindow *parent = NULL,
+                        const int x = -1, const int y = -1, const bool centre = TRUE,
+                        const int width = wxCHOICE_WIDTH, const int height = wxCHOICE_HEIGHT);
+
+// Same as above but gets position in list of strings, instead of string,
+// or -1 if no selection
+int WXDLLEXPORT wxGetSingleChoiceIndex(const wxString& message, const wxString& caption,
+                           const int n, const wxString *choices, wxWindow *parent = NULL,
+                           const int x = -1, const int y = -1, const bool centre = TRUE,
+                           const int width = wxCHOICE_WIDTH, const int height = wxCHOICE_HEIGHT);
+
+int WXDLLEXPORT wxGetSingleChoiceIndex(const wxString& message, const wxString& caption,
+                           const int n, char *choices[], wxWindow *parent = NULL,
+                           const int x = -1, const int y = -1, const bool centre = TRUE,
+                           const int width = wxCHOICE_WIDTH, const int height = wxCHOICE_HEIGHT);
+
+// Return client data instead
+char* WXDLLEXPORT wxGetSingleChoiceData(const wxString& message, const wxString& caption,
+                            const int n, const wxString *choices, char **client_data,
+                            wxWindow *parent = NULL, const int x = -1, const int y = -1,
+                            const bool centre = TRUE,
+                            const int width = wxCHOICE_WIDTH, const int height = wxCHOICE_HEIGHT);
+
+char* WXDLLEXPORT wxGetSingleChoiceData(const wxString& message, const wxString& caption,
+                            const int n, char *choices[], char **client_data,
+                            wxWindow *parent = NULL, const int x = -1, const int y = -1,
+                            const bool centre = TRUE,
+                            const int width = wxCHOICE_WIDTH, const int height = wxCHOICE_HEIGHT);
+                           
+/*
+int WXDLLEXPORT wxGetMultipleChoice(const wxString& message, const wxString& caption,
+			  const int n, const wxString *choices,
+			  const int nsel, int * selection,
+			  wxWindow *parent = NULL, const int x = -1 , const int y = -1, const bool centre = TRUE,
+			  const int width = wxCHOICE_WIDTH, const int height = wxCHOICE_HEIGHT);
+*/
+
+#endif
diff --git a/include/wx/generic/colrdlgg.h b/include/wx/generic/colrdlgg.h
new file mode 100644
index 0000000000..c0629c183e
--- /dev/null
+++ b/include/wx/generic/colrdlgg.h
@@ -0,0 +1,121 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        colrdlgg.h
+// Purpose:     wxGenericColourDialog
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c)
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __COLORDLGH_G__
+#define __COLORDLGH_G__
+
+#ifdef __GNUG__
+#pragma interface "colrdlgg.h"
+#endif
+
+#include "wx/setup.h"
+#include "wx/gdicmn.h"
+#include "wx/dialog.h"
+#include "wx/cmndata.h"
+
+#define wxID_ADD_CUSTOM     3000
+#define wxID_RED_SLIDER     3001
+#define wxID_GREEN_SLIDER   3002
+#define wxID_BLUE_SLIDER    3003
+
+class WXDLLEXPORT wxSlider;
+class WXDLLEXPORT wxGenericColourDialog: public wxDialog
+{
+ DECLARE_DYNAMIC_CLASS(wxGenericColourDialog)
+ protected:
+  wxColourData colourData;
+  wxWindow *dialogParent;
+
+  // Area reserved for grids of colours
+  wxRectangle standardColoursRect;
+  wxRectangle customColoursRect;
+  wxRectangle singleCustomColourRect;
+
+  // Size of each colour rectangle
+  wxIntPoint smallRectangleSize;
+
+  // For single customizable colour
+  wxIntPoint customRectangleSize;
+
+  // Grid spacing (between rectangles)
+  int gridSpacing;
+
+  // Section spacing (between left and right halves of dialog box)
+  int sectionSpacing;
+
+  // 48 'standard' colours
+  wxColour standardColours[48];
+
+  // 16 'custom' colours
+  wxColour customColours[16];
+
+  // One single custom colour (use sliders)
+  wxColour singleCustomColour;
+
+  // Which colour is selected? An index into one of the two areas.
+  int colourSelection;
+  int whichKind; // 1 for standard colours, 2 for custom colours,
+
+  wxSlider *redSlider;
+  wxSlider *greenSlider;
+  wxSlider *blueSlider;
+
+  int buttonY;
+
+  int okButtonX;
+  int customButtonX;
+
+//  static bool colourDialogCancelled;
+ public:
+  wxGenericColourDialog(void);
+  wxGenericColourDialog(wxWindow *parent, wxColourData *data = NULL);
+  ~wxGenericColourDialog(void);
+
+  bool Create(wxWindow *parent, wxColourData *data = NULL);
+
+  int ShowModal(void);
+  wxColourData GetColourData(void) { return colourData; }
+
+  // Internal functions
+  void OnMouseEvent(wxMouseEvent& event);
+  void OnPaint(wxPaintEvent& event);
+
+  bool OnClose(void);
+
+  virtual void CalculateMeasurements(void);
+  virtual void CreateWidgets(void);
+  virtual void InitializeColours(void);
+  
+  virtual void PaintBasicColours(wxDC& dc);
+  virtual void PaintCustomColours(wxDC& dc);
+  virtual void PaintCustomColour(wxDC& dc);
+  virtual void PaintHighlight(wxDC& dc, bool draw);
+
+  virtual void OnBasicColourClick(int which);
+  virtual void OnCustomColourClick(int which);
+
+/*
+  virtual void OnOk(void);
+  virtual void OnCancel(void);
+  virtual void OnAddCustom(void);
+*/
+  void OnAddCustom(wxCommandEvent& event);
+
+  void OnRedSlider(wxCommandEvent& event);
+  void OnGreenSlider(wxCommandEvent& event);
+  void OnBlueSlider(wxCommandEvent& event);
+
+DECLARE_EVENT_TABLE()
+};
+
+typedef wxGenericColourDialog wxColourDialog;
+
+#endif
diff --git a/include/wx/generic/fontdlgg.h b/include/wx/generic/fontdlgg.h
new file mode 100644
index 0000000000..8afda5b745
--- /dev/null
+++ b/include/wx/generic/fontdlgg.h
@@ -0,0 +1,94 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        fontdlgg.h
+// Purpose:     wxGenericFontDialog
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c)
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __FONTDLGH_G__
+#define __FONTDLGH_G__
+
+#ifdef __GNUG__
+#pragma interface "fontdlgg.h"
+#endif
+
+#include "wx/setup.h"
+#include "wx/gdicmn.h"
+#include "wx/font.h"
+#include "wx/dialog.h"
+#include "wx/cmndata.h"
+
+/*
+ * FONT DIALOG
+ */
+ 
+class WXDLLEXPORT wxChoice;
+class WXDLLEXPORT wxText;
+class WXDLLEXPORT wxCheckBox;
+
+#define wxID_FONT_UNDERLINE 3000
+#define wxID_FONT_STYLE     3001
+#define wxID_FONT_WEIGHT    3002
+#define wxID_FONT_FAMILY    3003
+#define wxID_FONT_COLOUR    3004
+#define wxID_FONT_SIZE      3005
+
+class WXDLLEXPORT wxGenericFontDialog: public wxDialog
+{
+ DECLARE_DYNAMIC_CLASS(wxGenericFontDialog)
+ protected:
+  wxFontData fontData;
+  wxFont dialogFont;
+  wxWindow *dialogParent;
+
+  // Area reserved for font display
+  wxRectangle fontRect;
+
+  wxChoice *familyChoice;
+  wxChoice *styleChoice;
+  wxChoice *weightChoice;
+  wxChoice *colourChoice;
+  wxCheckBox *underLineCheckBox;
+  wxChoice   *pointSizeChoice;
+
+//  static bool fontDialogCancelled;
+ public:
+ 
+  wxGenericFontDialog(void);
+  wxGenericFontDialog(wxWindow *parent, wxFontData *data = NULL);
+  ~wxGenericFontDialog(void);
+
+  bool Create(wxWindow *parent, wxFontData *data = NULL);
+
+  int ShowModal(void);
+
+  inline wxFontData& GetFontData(void) { return fontData; }
+
+  // Internal functions
+  void OnPaint(wxPaintEvent& event);
+
+  bool OnClose(void);
+
+  virtual void CreateWidgets(void);
+  virtual void InitializeFont(void);
+  
+  virtual void PaintFontBackground(wxDC& dc);
+  virtual void PaintFont(wxDC& dc);
+
+  void OnChangeFont(wxCommandEvent& event);
+
+DECLARE_EVENT_TABLE()
+};
+
+char* WXDLLEXPORT wxFontFamilyIntToString(int family);
+char* WXDLLEXPORT wxFontWeightIntToString(int weight);
+char* WXDLLEXPORT wxFontStyleIntToString(int style);
+int WXDLLEXPORT wxFontFamilyStringToInt(char *family);
+int WXDLLEXPORT wxFontWeightStringToInt(char *weight);
+int WXDLLEXPORT wxFontStyleStringToInt(char *style);
+
+#endif
diff --git a/include/wx/generic/gridg.h b/include/wx/generic/gridg.h
new file mode 100644
index 0000000000..d3ef3c2766
--- /dev/null
+++ b/include/wx/generic/gridg.h
@@ -0,0 +1,319 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        gridg.h
+// Purpose:     wxGenericGrid
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c)
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __GRIDH_G__
+#define __GRIDH_G__
+
+#ifdef __GNUG__
+#pragma interface "gridg.h"
+#endif
+
+#include "wx/defs.h"
+#include "wx/panel.h"
+#include "wx/string.h"
+#include "wx/scrolbar.h"
+
+#define wxGRID_DEFAULT_EDIT_WIDTH 300
+#define wxGRID_DEFAULT_EDIT_HEIGHT 27
+#define wxGRID_DEFAULT_EDIT_X 5
+#define wxGRID_DEFAULT_EDIT_Y 1
+#define wxGRID_DEFAULT_SHEET_TOP 31
+#define wxGRID_DEFAULT_SHEET_LEFT 0
+#define wxGRID_DEFAULT_CELL_HEIGHT 20
+#define wxGRID_DEFAULT_CELL_WIDTH 80
+#define wxGRID_DEFAULT_VERTICAL_LABEL_WIDTH 40
+#define wxGRID_DEFAULT_HORIZONAL_LABEL_HEIGHT 20
+
+#ifndef wxLEFT
+#define wxLEFT 0x0400
+#endif
+
+#ifndef wxRIGHT
+#define wxRIGHT 0x0800
+#endif
+
+#define WXGENERIC_GRID_VERSION  0.4
+
+class WXDLLEXPORT wxGridCell;
+class WXDLLEXPORT wxGenericGrid: public wxPanel
+{
+  DECLARE_DYNAMIC_CLASS(wxGenericGrid)
+ protected:
+  wxTextCtrl *textItem;
+  wxScrollBar *hScrollBar;
+  wxScrollBar *vScrollBar;
+  int wCursorRow;
+  int wCursorColumn;
+  wxRectangle CurrentRect;
+  bool currentRectVisible;
+  wxGridCell ***gridCells;
+  wxGridCell **rowLabelCells;
+  wxGridCell **colLabelCells;
+  bool bEditCreated;
+  bool editable;
+
+  int totalRows;
+  int totalCols;
+  
+  // Row and column we're currently looking at
+  int scrollPosX;
+  int scrollPosY;
+
+  // Dimensions
+  int leftOfSheet;
+  int topOfSheet;
+  int rightOfSheet;    // Calculated from colWidths
+  int bottomOfSheet;   // Calculated from rowHeights
+  int totalGridWidth; // Total 'virtual' size
+  int totalGridHeight;
+  int cellHeight;      // For now, a default
+  int verticalLabelWidth;
+  int horizontalLabelHeight;
+  int verticalLabelAlignment;
+  int horizontalLabelAlignment;
+  int cellAlignment;
+  short *colWidths;   // Dynamically allocated
+  short *rowHeights;  // Dynamically allocated
+  int scrollWidth;    // Vert. scroll width, horiz. scroll height
+  
+  // Colours
+  wxColour cellTextColour;
+  wxColour cellBackgroundColour;
+  wxFont *cellTextFont;
+  wxColour labelTextColour;
+  wxColour labelBackgroundColour;
+  wxBrush *labelBackgroundBrush;
+  wxFont *labelTextFont;
+  wxPen *divisionPen;
+
+  // Position of Edit control
+  wxRectangle editControlPosition;
+  
+  // Drag status
+  int dragStatus;
+  int dragRowOrCol;
+  int dragStartPosition;
+  int dragLastPosition;
+  static wxCursor *horizontalSashCursor;
+  static wxCursor *verticalSashCursor;
+  
+  // Don't refresh whilst this is > 0
+  int batchCount;
+  
+ public:
+  wxGenericGrid(void);
+
+  inline wxGenericGrid(wxWindow *parent, int x, int y, int width, int height, const long style = 0, char *name = "grid")
+  {
+    Create(parent, -1, wxPoint(x, y), wxSize(width, height), style, name);
+  }
+  inline wxGenericGrid(wxWindow *parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, const long style = 0, const wxString& name = "grid")
+  {
+    Create(parent, id, pos, size, style, name);
+  }
+  ~wxGenericGrid(void);
+
+  void OnPaint(wxPaintEvent& event);
+  void OnMouseEvent(wxMouseEvent& event);
+  void OnSize(wxSizeEvent& event);
+
+  bool Create(wxWindow *parent, const wxWindowID, const wxPoint& pos, const wxSize& size, const long style = 0, const wxString& name = "grid");
+
+  bool CreateGrid(int nRows, int nCols, wxString **cellValues = NULL, short *widths = NULL,
+     short defaultWidth = wxGRID_DEFAULT_CELL_WIDTH, short defaultHeight = wxGRID_DEFAULT_CELL_HEIGHT);
+  void ClearGrid(void);
+  virtual wxGridCell *GetCell(int row, int col);
+  inline wxGridCell ***GetCells(void) { return gridCells; }
+  bool InsertCols(int pos = 0, int n = 1, bool updateLabels = TRUE);
+  bool InsertRows(int pos = 0, int n = 1, bool updateLabels = TRUE);
+  bool AppendCols(int n = 1, bool updateLabels = TRUE);
+  bool AppendRows(int n = 1, bool updateLabels = TRUE);
+  bool DeleteCols(int pos = 0, int n = 1, bool updateLabels = TRUE);
+  bool DeleteRows(int pos = 0, int n = 1, bool updateLabels = TRUE);
+
+  // Cell accessors
+  void SetCellValue(const wxString& val, int row, int col);
+  wxString& GetCellValue(int row, int col);
+  void SetCellAlignment(int flag, int row, int col);
+  void SetCellAlignment(int flag);
+  int GetCellAlignment(int row, int col);
+  int GetCellAlignment(void);
+  void SetCellTextColour(const wxColour& val, int row, int col);
+  void SetCellTextColour(const wxColour& col);
+  wxColour& GetCellTextColour(int row, int col);
+  inline wxColour& GetCellTextColour(void) { return cellTextColour; }
+  void SetCellBackgroundColour(const wxColour& col);
+  void SetCellBackgroundColour(const wxColour& colour, int row, int col);
+  inline wxColour& GetCellBackgroundColour(void) { return cellBackgroundColour; }
+  wxColour& GetCellBackgroundColour(int row, int col);
+  inline wxFont *GetCellTextFont(void) { return cellTextFont; }
+  wxFont *GetCellTextFont(int row, int col);
+  void SetCellTextFont(wxFont *fnt);
+  void SetCellTextFont(wxFont *fnt, int row, int col);
+  wxBitmap *GetCellBitmap(int row, int col);
+  void SetCellBitmap(wxBitmap *bitmap, int row, int col);
+  
+  // Size accessors
+  void SetColumnWidth(int col, int width);
+  int GetColumnWidth(int col);
+  void SetRowHeight(int row, int height);
+  int GetRowHeight(int row);
+  
+  // Label accessors
+  void SetLabelSize(int orientation, int sz);
+  int GetLabelSize(int orientation);
+  void SetLabelAlignment(int orientation, int alignment);
+  int GetLabelAlignment(int orientation);
+  wxGridCell *GetLabelCell(int orientation, int pos);
+  void SetLabelValue(int orientation, const wxString& val, int pos);
+  wxString& GetLabelValue(int orientation, int pos);
+  void SetLabelTextColour(const wxColour& colour);
+  void SetLabelBackgroundColour(const wxColour& colour);
+  inline wxColour& GetLabelTextColour(void) { return labelTextColour; }
+  inline wxColour& GetLabelBackgroundColour(void) { return labelBackgroundColour; }
+  inline wxFont *GetLabelTextFont(void) { return labelTextFont; }
+  inline void SetLabelTextFont(wxFont *fnt) { labelTextFont = fnt; }
+
+  // Miscellaneous accessors
+  inline int GetCursorRow(void) { return wCursorRow; }
+  inline int GetCursorColumn(void) { return wCursorColumn; }
+  void SetGridCursor(int row, int col);
+  inline int GetRows(void) { return totalRows; }
+  inline int GetCols(void) { return totalCols; }
+  inline int GetScrollPosX(void) { return scrollPosX; }
+  inline int GetScrollPosY(void) { return scrollPosY; }
+  inline void SetScrollPosX(int pos) { scrollPosX = pos; }
+  inline void SetScrollPosY(int pos) { scrollPosY = pos; }
+  inline wxTextCtrl *GetTextItem(void) { return textItem; }
+  inline wxScrollBar *GetHorizScrollBar(void) { return hScrollBar; }
+  inline wxScrollBar *GetVertScrollBar(void) { return vScrollBar; }
+  inline bool GetEditable(void) { return editable; }
+  void SetEditable(bool edit);
+  inline wxRectangle& GetCurrentRect(void) { return CurrentRect; }
+  inline bool CurrentCellVisible(void) { return currentRectVisible; }
+  inline void SetDividerPen(wxPen *pen) { divisionPen = pen; }
+  inline wxPen *GetDividerPen(void) { return divisionPen; }
+  
+  // High-level event handling
+  // Override e.g. to check value of current cell; but call
+  // base member for default processing.
+  virtual void OnSelectCellImplementation(wxDC *dc, int row, int col);
+
+  virtual void OnSelectCell(int WXUNUSED(row), int WXUNUSED(col)) {};
+
+  // Override to create your own class of grid cell
+  virtual wxGridCell *OnCreateCell(void);
+  
+  // Override to change labels e.g. creation of grid, inserting/deleting a row/col.
+  // By default, auto-labels the grid.
+  virtual void OnChangeLabels(void);
+
+  // Override to change the label of the edit field when selecting a cell
+  // By default, sets it to e.g. A12
+  virtual void OnChangeSelectionLabel(void);
+  
+  // Override for event processing
+  virtual void OnCellChange(int WXUNUSED(row), int WXUNUSED(col)) {};
+  virtual void OnCellLeftClick(int WXUNUSED(row), int WXUNUSED(col), int WXUNUSED(x), int WXUNUSED(y), bool WXUNUSED(control), bool WXUNUSED(shift)) {};
+  virtual void OnCellRightClick(int WXUNUSED(row), int WXUNUSED(col), int WXUNUSED(x), int WXUNUSED(y), bool WXUNUSED(control), bool WXUNUSED(shift)) {};
+  virtual void OnLabelLeftClick(int WXUNUSED(row), int WXUNUSED(col), int WXUNUSED(x), int WXUNUSED(y), bool WXUNUSED(control), bool WXUNUSED(shift)) {};
+  virtual void OnLabelRightClick(int WXUNUSED(row), int WXUNUSED(col), int WXUNUSED(x), int WXUNUSED(y), bool WXUNUSED(control), bool WXUNUSED(shift)) {};
+
+  // Activation: call from wxFrame::OnActivate
+  void OnActivate(bool active);
+
+  // Miscellaneous
+  void AdjustScrollbars(void);
+  void UpdateDimensions(void);
+
+  /* INTERNAL
+   */
+  void SetCurrentRect (int Row, int Column, int canvasW = -1, int canvasH = -1);
+  void HighlightCell (wxDC *dc);
+  void DrawCellText(void);
+  void SetGridClippingRegion(wxDC *dc);
+  virtual bool CellHitTest(int x, int y, int *row, int *col);
+  virtual bool LabelSashHitTest(int x, int y, int *orientation, int *rowOrCol, int *startPos);
+  virtual bool LabelHitTest(int x, int y, int *row, int *col);
+  // Painting
+  virtual void DrawLabelAreas(wxDC *dc);
+  virtual void DrawEditableArea(wxDC *dc);
+  virtual void DrawGridLines(wxDC *dc);
+  virtual void DrawColumnLabels(wxDC *dc);
+  virtual void DrawColumnLabel(wxDC *dc, wxRectangle *rect, int col);
+  virtual void DrawRowLabels(wxDC *dc);
+  virtual void DrawRowLabel(wxDC *dc, wxRectangle *rect, int row);
+  virtual void DrawCells(wxDC *dc);
+  virtual void DrawCellValue(wxDC *dc, wxRectangle *rect, int row, int col);
+  virtual void DrawCellBackground(wxDC *dc, wxRectangle *rect, int row, int col);
+  virtual void DrawTextRect(wxDC *dc, const wxString& text, wxRectangle *rect, int flag);
+  virtual void DrawBitmapRect(wxDC *dc, wxBitmap *bitmap, wxRectangle *rect, int flag);
+
+  // Refresh cell and optionally set the text field
+  void RefreshCell(int row, int col, bool setText = FALSE);
+
+  // Don't refresh within the outer pair of these.
+  inline void BeginBatch(void) { batchCount ++; }
+  inline void EndBatch(void) { batchCount --; }
+  inline int GetBatchCount(void) { return batchCount; }
+
+  void OnText(wxCommandEvent& ev);
+  void OnGridScroll(wxScrollEvent& ev);
+
+DECLARE_EVENT_TABLE()
+};
+
+#define wxGRID_TEXT_CTRL 2000
+#define wxGRID_HSCROLL   2001
+#define wxGRID_VSCROLL   2002
+
+class WXDLLEXPORT wxGridCell: public wxObject
+{
+ public:
+  wxString textValue;
+  wxFont *font;
+  wxColour textColour;
+  wxColour backgroundColour;
+  wxBrush *backgroundBrush;
+  wxBitmap *cellBitmap;
+  int alignment;
+
+  wxGridCell(wxGenericGrid *window = NULL);
+  ~wxGridCell(void);
+  
+  virtual wxString& GetTextValue(void) { return textValue; }
+  virtual void SetTextValue(const wxString& str) { textValue = str; }
+  inline wxFont *GetFont(void) { return font; }
+  inline void SetFont(wxFont *f) { font = f; }
+  inline wxColour& GetTextColour(void) { return textColour; }
+  inline void SetTextColour(const wxColour& colour) { textColour = colour; }
+  inline wxColour& GetBackgroundColour(void) { return backgroundColour; }
+  void SetBackgroundColour(const wxColour& colour);
+  inline wxBrush *GetBackgroundBrush(void) { return backgroundBrush; }
+  inline int GetAlignment(void) { return alignment; }
+  inline void SetAlignment(int align) { alignment = align; }
+  inline wxBitmap *GetCellBitmap(void) { return cellBitmap; }
+  inline void SetCellBitmap(wxBitmap *bitmap) { cellBitmap = bitmap; }
+};
+
+class WXDLLEXPORT wxGrid: public wxGenericGrid
+{
+  public:
+    wxGrid(void):wxGenericGrid() {}
+    wxGrid(wxWindow *parent, int x=-1, int y=-1, int width=-1, int height=-1,
+               long style=0, char *name = "gridWindow"):
+     wxGenericGrid(parent, x, y, width, height, style, name)
+    {
+    }
+};
+
+#endif
+
diff --git a/include/wx/generic/helpxlp.h b/include/wx/generic/helpxlp.h
new file mode 100644
index 0000000000..80587b3d07
--- /dev/null
+++ b/include/wx/generic/helpxlp.h
@@ -0,0 +1,127 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        helpxlp.h
+// Purpose:     Help system: wxHelp implementation
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+/* sccsid[] = "@(#)wx_help.h	1.2 5/9/94" */
+
+#ifndef __HELPXLPH__
+#define __HELPXLPH__
+
+#ifdef __GNUG__
+#pragma interface "helpxlp.h"
+#endif
+
+#include <stdio.h>
+#include "wx/wx.h"
+
+#if USE_HELP
+
+#include "wx/helpbase.h"
+
+#ifdef __WINDOWS__
+#include "wx/dde.h"
+#else
+// Or whatever it'll be called
+#include "wx/ipctcp.h"
+#endif
+
+class WXDLLEXPORT wxXLPHelpController;
+
+// Connection class for implementing the connection between the
+// wxHelp process and the application
+class WXDLLEXPORT wxXLPHelpConnection: public
+
+#ifdef __WINDOWS__
+ wxDDEConnection
+#else
+ wxTCPConnection
+#endif
+
+{
+  friend class wxXLPHelpController;
+
+  DECLARE_DYNAMIC_CLASS(wxXLPHelpConnection)
+
+ public:
+
+  wxXLPHelpConnection(wxXLPHelpController *instance);
+  bool OnDisconnect(void);
+
+ private:
+  wxXLPHelpController *helpInstance;
+};
+
+// Connection class for implementing the client process
+// controlling the wxHelp process
+class WXDLLEXPORT wxXLPHelpClient: public
+
+#ifdef __WINDOWS__
+ wxDDEClient
+#else
+ wxTCPClient
+#endif
+
+{
+DECLARE_CLASS(wxXLPHelpClient)
+
+	friend class WXDLLEXPORT wxXLPHelpController;
+public:
+  wxXLPHelpClient(wxXLPHelpController* c) { m_controller = c; }
+
+  wxConnectionBase *OnMakeConnection(void)
+    { return new wxXLPHelpConnection(m_controller);
+    }
+protected:
+  wxXLPHelpController* m_controller;
+};
+
+// An application can have one or more instances of wxHelp,
+// represented by an object of this class.
+// Nothing happens on initial creation; the application
+// must call a member function to display help.
+// If the instance of wxHelp is already active, that instance
+// will be used for subsequent help.
+
+class WXDLLEXPORT wxXLPHelpController: public wxHelpControllerBase
+{
+  friend class WXDLLEXPORT wxXLPHelpConnection;
+  DECLARE_CLASS(wxXLPHelpController)
+
+ public:
+  wxXLPHelpController(void);
+  ~wxXLPHelpController(void);
+
+  // Must call this to set the filename and server name
+  virtual bool Initialize(const wxString& file, int server = -1);
+  // If file is "", reloads file given in Initialize
+  virtual bool LoadFile(const wxString& file = "");
+  virtual bool DisplayContents(void);
+  virtual bool DisplaySection(int sectionNo);
+  virtual bool DisplayBlock(long blockNo);
+  virtual bool KeywordSearch(const wxString& k);
+
+  virtual bool Quit(void);
+  virtual void OnQuit(void);
+
+  // Private
+  bool Run(void);
+
+ protected:
+  wxString				helpFile;
+  wxString				helpHost;
+  int					helpServer;
+  bool					helpRunning;
+  wxXLPHelpConnection*	helpConnection;
+  wxXLPHelpClient		helpClient;
+};
+
+#endif // USE_HELP
+#endif
+    // __HELPXLPH__
diff --git a/include/wx/generic/imaglist.h b/include/wx/generic/imaglist.h
new file mode 100644
index 0000000000..b6e68ef11e
--- /dev/null
+++ b/include/wx/generic/imaglist.h
@@ -0,0 +1,67 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        imaglist.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __IMAGELISTH_G__
+#define __IMAGELISTH_G__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/gdicmn.h"
+#include "wx/bitmap.h"
+#include "wx/dc.h"
+
+/*
+ * wxImageList is used for wxListCtrl, wxTreeCtrl. These controls refer to
+ * images for their items by an index into an image list.
+ * A wxImageList is capable of creating images with optional masks from
+ * a variety of sources - a single bitmap plus a colour to indicate the mask,
+ * two bitmaps, or an icon.
+ *
+ * Image lists can also create and draw images used for drag and drop functionality.
+ * This is not yet implemented in wxImageList. We need to discuss a generic API
+ * for doing drag and drop and see whether it ties in with the Win95 view of it.
+ * See below for candidate functions and an explanation of how they might be
+ * used.
+ */
+
+// Flags for Draw
+#define wxIMAGELIST_DRAW_NORMAL         0x0001
+#define wxIMAGELIST_DRAW_TRANSPARENT    0x0002
+#define wxIMAGELIST_DRAW_SELECTED       0x0004
+#define wxIMAGELIST_DRAW_FOCUSED        0x0008
+
+class wxImageList: public wxObject
+{
+   DECLARE_DYNAMIC_CLASS(wxImageList)
+   
+  public:
+
+    wxImageList(void);
+    ~wxImageList(void);
+    bool Create(void);
+    int GetImageCount(void) const;
+    int Add( const wxBitmap &bitmap );
+    bool Replace( const int index, const wxBitmap &bitmap );
+    bool Remove( const int index );
+    bool RemoveAll(void);
+    bool GetSize( const int index, int &width, int &height ) const;
+    bool Draw(const int index, wxDC& dc, const int x, const int y,
+      const int flags = wxIMAGELIST_DRAW_NORMAL, const bool solidBackground = FALSE );
+    
+  private:
+
+    wxList  m_images;
+};
+
+#endif  // __IMAGELISTH_G__
+
diff --git a/include/wx/generic/listctrl.h b/include/wx/generic/listctrl.h
new file mode 100644
index 0000000000..3a3ad0151a
--- /dev/null
+++ b/include/wx/generic/listctrl.h
@@ -0,0 +1,649 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        listctrl.h
+// Purpose:     Generic list control
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __LISTCTRLH_G__
+#define __LISTCTRLH_G__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/imaglist.h"
+#include "wx/control.h"
+#include "wx/timer.h"
+#include "wx/dcclient.h"
+#include "wx/scrolwin.h"
+#include "wx/settings.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxListItem;
+class wxListEvent;
+class wxListCtrl;
+
+//-----------------------------------------------------------------------------
+// internal classes
+//-----------------------------------------------------------------------------
+
+class wxListHeaderData;
+class wxListItemData;
+class wxListLineData;
+
+class wxListHeaderWindow;
+class wxListMainWindow;
+
+class wxListRenameTimer;
+//class wxListTextCtrl;
+
+//-----------------------------------------------------------------------------
+// types
+//-----------------------------------------------------------------------------
+
+// type of compare function for wxListCtrl sort operation
+typedef int (*wxListCtrlCompare)(const long item1, const long item2, long sortData);
+
+//-----------------------------------------------------------------------------
+// wxListCtrl flags
+//-----------------------------------------------------------------------------
+
+#define wxLC_ICON            0x0004
+#define wxLC_SMALL_ICON      0x0008
+#define wxLC_LIST            0x0010
+#define wxLC_REPORT          0x0020
+#define wxLC_ALIGN_TOP       0x0040
+#define wxLC_ALIGN_LEFT      0x0080
+#define wxLC_AUTOARRANGE     0x0100  // not supported in wxGLC
+#define wxLC_USER_TEXT       0x0200  // not supported in wxGLC (how does it work?)
+#define wxLC_EDIT_LABELS     0x0400
+#define wxLC_NO_HEADER       0x0800  // not supported in wxGLC
+#define wxLC_NO_SORT_HEADER  0x1000  // not supported in wxGLC
+#define wxLC_SINGLE_SEL      0x2000
+#define wxLC_SORT_ASCENDING  0x4000  
+#define wxLC_SORT_DESCENDING 0x8000  // not supported in wxGLC
+
+#define wxLC_MASK_TYPE       (wxLC_ICON | wxLC_SMALL_ICON | wxLC_LIST | wxLC_REPORT)
+#define wxLC_MASK_ALIGN      (wxLC_ALIGN_TOP | wxLC_ALIGN_LEFT)
+#define wxLC_MASK_SORT       (wxLC_SORT_ASCENDING | wxLC_SORT_DESCENDING)
+
+// Omitted because (a) too much detail (b) not enough style flags
+// #define wxLC_NO_SCROLL
+// #define wxLC_NO_LABEL_WRAP
+// #define wxLC_OWNERDRAW_FIXED
+// #define wxLC_SHOW_SEL_ALWAYS
+
+// Mask flags to tell app/GUI what fields of wxListItem are valid
+#define wxLIST_MASK_STATE           0x0001
+#define wxLIST_MASK_TEXT            0x0002
+#define wxLIST_MASK_IMAGE           0x0004
+#define wxLIST_MASK_DATA            0x0008
+#define wxLIST_SET_ITEM             0x0010
+#define wxLIST_MASK_WIDTH           0x0020
+#define wxLIST_MASK_FORMAT          0x0040
+
+// State flags for indicating the state of an item
+#define wxLIST_STATE_DONTCARE       0x0000
+#define wxLIST_STATE_DROPHILITED    0x0001  // not supported in wxGLC
+#define wxLIST_STATE_FOCUSED        0x0002
+#define wxLIST_STATE_SELECTED       0x0004  
+#define wxLIST_STATE_CUT            0x0008  // not supported in wxGLC
+
+// Hit test flags, used in HitTest // wxGLC suppots 20 and 80
+#define wxLIST_HITTEST_ABOVE            0x0001  // Above the client area.
+#define wxLIST_HITTEST_BELOW            0x0002  // Below the client area.
+#define wxLIST_HITTEST_NOWHERE          0x0004  // In the client area but below the last item.
+#define wxLIST_HITTEST_ONITEMICON       0x0020  // On the bitmap associated with an item.
+#define wxLIST_HITTEST_ONITEMLABEL      0x0080  // On the label (string) associated with an item.
+#define wxLIST_HITTEST_ONITEMRIGHT      0x0100  // In the area to the right of an item.
+#define wxLIST_HITTEST_ONITEMSTATEICON  0x0200  // On the state icon for a tree view item that is in a user-defined state.
+#define wxLIST_HITTEST_TOLEFT           0x0400  // To the right of the client area.
+#define wxLIST_HITTEST_TORIGHT          0x0800  // To the left of the client area.
+
+#define wxLIST_HITTEST_ONITEM (wxLIST_HITTEST_ONITEMICON | wxLIST_HITTEST_ONITEMLABEL | wxLIST_HITTEST_ONITEMSTATEICON)
+
+
+
+// Flags for GetNextItem  // always wxLIST_NEXT_ALL in wxGLC
+enum {
+    wxLIST_NEXT_ABOVE,          // Searches for an item above the specified item
+    wxLIST_NEXT_ALL,            // Searches for subsequent item by index
+    wxLIST_NEXT_BELOW,          // Searches for an item below the specified item
+    wxLIST_NEXT_LEFT,           // Searches for an item to the left of the specified item
+    wxLIST_NEXT_RIGHT,          // Searches for an item to the right of the specified item
+};
+
+// Alignment flags for Arrange  // always wxLIST_ALIGN_LEFT in wxGLC
+enum {
+    wxLIST_ALIGN_DEFAULT,
+    wxLIST_ALIGN_LEFT,
+    wxLIST_ALIGN_TOP,
+    wxLIST_ALIGN_SNAP_TO_GRID
+};
+
+// Column format  // always wxLIST_FORMAT_LEFT in wxGLC
+enum {
+    wxLIST_FORMAT_LEFT,
+    wxLIST_FORMAT_RIGHT,
+    wxLIST_FORMAT_CENTRE,
+    wxLIST_FORMAT_CENTER = wxLIST_FORMAT_CENTRE
+};
+
+// Autosize values for SetColumnWidth
+enum {
+    wxLIST_AUTOSIZE = -1,          // always 80 in wxGLC (what else?)
+    wxLIST_AUTOSIZE_USEHEADER = -2
+};
+
+// Flag values for GetItemRect
+enum {
+    wxLIST_RECT_BOUNDS,
+    wxLIST_RECT_ICON,
+    wxLIST_RECT_LABEL
+};
+
+// Flag values for FindItem  // not supported by wxGLC
+enum {
+    wxLIST_FIND_UP,
+    wxLIST_FIND_DOWN,
+    wxLIST_FIND_LEFT,
+    wxLIST_FIND_RIGHT
+};
+
+// Flag values for Set/GetImageList
+enum {
+    wxIMAGE_LIST_NORMAL, // Normal icons
+    wxIMAGE_LIST_SMALL,  // Small icons
+    wxIMAGE_LIST_STATE   // State icons: unimplemented (see WIN32 documentation)
+                         // not implemented in wxGLC (see non-existing documentation..)
+};
+
+//-----------------------------------------------------------------------------
+// wxListItem
+//-----------------------------------------------------------------------------
+
+class wxListItem: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxListItem)
+
+  public:
+    long            m_mask;     // Indicates what fields are valid
+    long            m_itemId;   // The zero-based item position
+    int             m_col;      // Zero-based column, if in report mode
+    long            m_state;    // The state of the item
+    long            m_stateMask; // Which flags of m_state are valid (uses same flags)
+    wxString        m_text;     // The label/header text
+    int             m_image;    // The zero-based index into an image list
+    long            m_data;     // App-defined data
+    wxColour       *m_colour;   // only wxGLC, not supported by Windows ;->
+
+    // For columns only
+    int             m_format;   // left, right, centre
+    int             m_width;    // width of column
+
+    wxListItem(void);
+};
+
+//-----------------------------------------------------------------------------
+// wxListEvent
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxListEvent: public wxCommandEvent
+{
+  DECLARE_DYNAMIC_CLASS(wxListEvent)
+
+ public:
+  wxListEvent(WXTYPE commandType = 0, int id = 0);
+
+  int           m_code;
+  long          m_itemIndex;
+  long          m_oldItemIndex;
+  int           m_col;
+  bool          m_cancelled;
+  wxPoint       m_pointDrag;
+
+  wxListItem    m_item;
+};
+
+typedef void (wxEvtHandler::*wxListEventFunction)(wxListEvent&);
+
+#define EVT_LIST_BEGIN_DRAG(id, fn) { wxEVT_COMMAND_LIST_BEGIN_DRAG, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxListEventFunction) & fn },
+#define EVT_LIST_BEGIN_RDRAG(id, fn) { wxEVT_COMMAND_LIST_BEGIN_RDRAG, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxListEventFunction) & fn },
+#define EVT_LIST_BEGIN_LABEL_EDIT(id, fn) { wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxListEventFunction) & fn },
+#define EVT_LIST_END_LABEL_EDIT(id, fn) { wxEVT_COMMAND_LIST_END_LABEL_EDIT, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxListEventFunction) & fn },
+#define EVT_LIST_DELETE_ITEM(id, fn) { wxEVT_COMMAND_LIST_DELETE_ITEM, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxListEventFunction) & fn },
+#define EVT_LIST_DELETE_ALL_ITEMS(id, fn) { wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxListEventFunction) & fn },
+#define EVT_LIST_GET_INFO(id, fn) { wxEVT_COMMAND_LIST_GET_INFO, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxListEventFunction) & fn },
+#define EVT_LIST_SET_INFO(id, fn) { wxEVT_COMMAND_LIST_SET_INFO, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxListEventFunction) & fn },
+#define EVT_LIST_ITEM_SELECTED(id, fn) { wxEVT_COMMAND_LIST_ITEM_SELECTED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxListEventFunction) & fn },
+#define EVT_LIST_ITEM_DESELECTED(id, fn) { wxEVT_COMMAND_LIST_ITEM_DESELECTED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxListEventFunction) & fn },
+#define EVT_LIST_KEY_DOWN(id, fn) { wxEVT_COMMAND_LIST_KEY_DOWN, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxListEventFunction) & fn },
+#define EVT_LIST_INSERT_ITEM(id, fn) { wxEVT_COMMAND_LIST_INSERT_ITEM, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxListEventFunction) & fn },
+#define EVT_LIST_COL_CLICK(id, fn) { wxEVT_COMMAND_LIST_COL_CLICK, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxListEventFunction) & fn },
+
+
+//-----------------------------------------------------------------------------
+//  wxListItemData (internal)
+//-----------------------------------------------------------------------------
+
+class wxListItemData : public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxListItemData);
+
+  protected:
+    wxString   m_text;
+    int        m_image;
+    long       m_data;
+    int        m_xpos,m_ypos;
+    int        m_width,m_height;
+    wxColour   *m_colour;
+    
+  public:
+    wxListItemData(void);
+    wxListItemData( const wxListItem &info );
+    void SetItem( const wxListItem &info );
+    void SetText( const wxString &s );
+    void SetImage( const int image );
+    void SetData( const long data );
+    void SetPosition( const int x, const int y );
+    void SetSize( const int width, const int height );
+    void SetColour( wxColour *col );
+    bool HasImage(void) const;
+    bool HasText(void) const;
+    bool IsHit( const int x, const int y ) const;
+    void GetText( wxString &s );
+    int GetX( void ) const;
+    int GetY( void ) const;
+    int GetWidth(void) const;
+    int GetHeight(void) const;
+    int GetImage(void) const;
+    void GetItem( wxListItem &info );
+    wxColour *GetColour(void);
+};
+
+//-----------------------------------------------------------------------------
+//  wxListHeaderData (internal)
+//-----------------------------------------------------------------------------
+
+class wxListHeaderData : public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxListHeaderData);
+
+  protected:
+    long      m_mask;
+    int       m_image;
+    wxString  m_text;
+    int       m_format;
+    int       m_width;
+    int       m_xpos,m_ypos;
+    int       m_height;
+    
+  public:
+    wxListHeaderData(void);
+    wxListHeaderData( const wxListItem &info );
+    void SetItem( const wxListItem &item );
+    void SetPosition( const int x, const int y );
+    void SetWidth( const int w );
+    void SetFormat( const int format );
+    void SetHeight( const int h );
+    bool HasImage(void) const;
+    bool HasText(void) const;
+    bool IsHit( const int x, const int y ) const;
+    void GetItem( wxListItem &item );
+    void GetText( wxString &s );
+    int GetImage(void) const;
+    int GetWidth(void) const;
+    int GetFormat(void) const;
+};
+
+//-----------------------------------------------------------------------------
+//  wxListLineData (internal)
+//-----------------------------------------------------------------------------
+
+class wxListLineData : public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxListLineData);
+
+  protected:
+    wxList              m_items;
+    wxRectangle         m_bound_all;
+    wxRectangle         m_bound_label;
+    wxRectangle         m_bound_icon;
+    wxRectangle         m_bound_hilight;
+    int                 m_mode;
+    bool                m_hilighted;
+    wxBrush            *m_hilightBrush;
+    int                 m_spacing;
+    wxListMainWindow   *m_owner;
+
+    void DoDraw( wxPaintDC *dc, const bool hilight, const bool paintBG );
+
+  public:
+    wxListLineData( void ) {};
+    wxListLineData( wxListMainWindow *owner, const int mode, wxBrush *hilightBrush );
+    void CalculateSize( wxPaintDC *dc, const int spacing );
+    void SetPosition( wxPaintDC *dc, const int x, const int y,  const int window_width );
+    void SetColumnPosition( const int index, const int x );
+    void GetSize( int &width, int &height );
+    void GetExtent( int &x, int &y, int &width, int &height );
+    void GetLabelExtent( int &x, int &y, int &width, int &height );
+    long IsHit( const int x, const int y );
+    void InitItems( const int num );
+    void SetItem( const int index, const wxListItem &info );
+    void GetItem( const int index, wxListItem &info );
+    void GetText( const int index, wxString &s );
+    void SetText( const int index, const wxString s );
+    int GetImage( const int index );
+    void GetRect( wxRectangle &rect );
+    void Hilight( const bool on );
+    void ReverseHilight( void );
+    void DrawRubberBand( wxPaintDC *dc, const bool on );
+    void Draw( wxPaintDC *dc );
+    bool IsInRect( const int x, const int y, const wxRectangle &rect );
+    bool IsHilighted( void );
+    void AssignRect( wxRectangle &dest, const int x, const int y, const int width, const int height );
+    void AssignRect( wxRectangle &dest, const wxRectangle &source );
+};
+
+//-----------------------------------------------------------------------------
+//  wxListHeaderWindow (internal)
+//-----------------------------------------------------------------------------
+
+class wxListHeaderWindow : public wxWindow
+{
+  DECLARE_DYNAMIC_CLASS(wxListHeaderWindow)
+
+  protected:
+    wxListMainWindow  *m_owner;
+    wxCursor          *m_currentCursor;
+    wxCursor          *m_resizeCursor;
+
+  public:
+    wxListHeaderWindow( void );
+    wxListHeaderWindow( wxWindow *win, const wxWindowID id, wxListMainWindow *owner, 
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = "columntitles" );
+    void DoDrawRect( wxPaintDC *dc, int x, int y, int w, int h );
+    void OnPaint( wxPaintEvent &event );
+    void OnMouse( wxMouseEvent &event );
+    void OnSetFocus( wxFocusEvent &event );
+    
+  DECLARE_EVENT_TABLE()
+};
+
+//-----------------------------------------------------------------------------
+// wxListRenameTimer (internal)
+//-----------------------------------------------------------------------------
+
+class wxListRenameTimer: public wxTimer
+{
+ private:
+   wxListMainWindow   *m_owner;
+   
+ public:
+   wxListRenameTimer( wxListMainWindow *owner );
+   void Notify();
+};
+
+/*
+
+//-----------------------------------------------------------------------------
+//  wxListTextCtrl (internal)
+//-----------------------------------------------------------------------------
+
+class wxListTextCtrl: public wxTextCtrl
+{
+  DECLARE_DYNAMIC_CLASS(wxListTextCtrl);
+  
+  private:
+    bool               *m_accept;
+    wxString           *m_res;
+    wxListMainWindow   *m_owner;
+
+  public:
+    wxListTextCtrl(void) : wxTextCtrl() {};
+    wxListTextCtrl(  wxWindow *parent, const char *value = "", 
+      bool *accept, wxString *res, wxListMainWindow *owner,
+      int x = -1, int y = -1, int w = -1, int h = -1, int style = 0, char *name = "rawtext" ) :
+      wxTextCtrl( parent, value, x, y, w, h, style, name ) 
+      {
+        m_res = res;
+        m_accept = accept;
+	m_owner = owner;
+      };
+    void OnChar( wxKeyEvent &event )
+      {
+        if (event.keyCode == WXK_RETURN)
+        {
+          (*m_accept) = TRUE;
+	  (*m_res) = GetValue();
+	  m_owner->OnRenameAccept();
+//	  Show( FALSE );
+          delete this;
+  	  return;
+	};
+        if (event.keyCode == WXK_ESCAPE)
+        {
+          (*m_accept) = FALSE;
+	  (*m_res) = "";
+//	  Show( FALSE );
+          delete this;
+	  return;
+	};
+      };
+    void OnKillFocus(void)
+      {
+        (*m_accept) = FALSE;
+        (*m_res) = "";
+//      Show( FALSE );
+        delete this;
+        return;
+      };
+};
+
+*/
+
+//-----------------------------------------------------------------------------
+//  wxListMainWindow (internal)
+//-----------------------------------------------------------------------------
+
+class wxListMainWindow: public wxScrolledWindow
+{
+  DECLARE_DYNAMIC_CLASS(wxListMainWindow);
+
+  public:
+    long                 m_mode;
+    wxList               m_lines;
+    wxList               m_columns; 
+    wxListLineData      *m_current;
+    int                  m_visibleLines;
+    wxBrush             *m_hilightBrush;
+    wxColour            *m_hilightColour;
+    wxFont              *m_myFont;
+    int                  m_xScroll,m_yScroll;
+    bool                 m_dirty;
+    wxImageList         *m_small_image_list;
+    wxImageList         *m_normal_image_list;
+    int                  m_small_spacing;
+    int                  m_normal_spacing;
+    bool                 m_hasFocus;
+    bool                 m_usedKeys;
+    bool                 m_lastOnSame;
+    wxTimer             *m_renameTimer;
+//  wxListTextCtrl      *m_text;
+    bool                 m_renameAccept;
+    wxString             m_renameRes;
+    bool                 m_isCreated;
+    bool                 m_isDragging;
+
+  public:
+    wxListMainWindow(void); 
+    wxListMainWindow( wxWindow *parent, const wxWindowID id, 
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = "listctrl" );
+    ~wxListMainWindow(void);
+    void RefreshLine( wxListLineData *line );
+    void OnPaint( wxPaintEvent &event );
+    void HilightAll( const bool on );
+    void ActivateLine( wxListLineData *line );
+    void SendNotify( wxListLineData *line, long command );
+    void FocusLine( wxListLineData *line );
+    void UnfocusLine( wxListLineData *line );
+    void SelectLine( wxListLineData *line );
+    void DeselectLine( wxListLineData *line );
+    void DeleteLine( wxListLineData *line );
+    void RenameLine( wxListLineData *line, const wxString &newName );
+    void OnRenameTimer(void);
+    void OnRenameAccept(void);
+    void OnMouse( wxMouseEvent &event );
+    void MoveToFocus( void );
+    void OnArrowChar( wxListLineData *newCurrent, bool shiftDown );
+    void OnChar( wxKeyEvent &event );
+    void OnSetFocus( wxFocusEvent &event );
+    void OnKillFocus( wxFocusEvent &event );
+    void OnSize( wxSizeEvent &event );
+    wxFont *GetMyFont( void );
+    void DrawImage( int index, wxPaintDC *dc, int x, int y );
+    void GetImageSize( int index, int &width, int &height );
+    int GetIndexOfLine( const wxListLineData *line );
+    int GetTextLength( wxString &s );  // should be const
+
+    void SetImageList( wxImageList *imageList, const int which );
+    void SetItemSpacing( const int spacing, const bool isSmall = FALSE );
+    int GetItemSpacing( const bool isSmall = FALSE );
+    void SetColumn( const int col, wxListItem &item );
+    void SetColumnWidth( const int col, const int width );
+    void GetColumn( const int col, wxListItem &item );
+    int GetColumnWidth( const int vol );
+    int GetColumnCount( void );
+    int GetCountPerPage( void );     
+    void SetItem( wxListItem &item );
+    void GetItem( wxListItem &item );
+    void SetItemState( const long item, const long state, const long stateMask ); 
+    int GetItemState( const long item, const long stateMask );
+    int GetItemCount( void );
+    void GetItemRect( const long index, wxRectangle &rect );
+    int GetSelectedItemCount( void );
+    void SetMode( const long mode );
+    long GetMode( void ) const;
+    void CalculatePositions( void );
+    void RealizeChanges(void);
+    long GetNextItem( const long item, int geometry, int state );
+    void DeleteItem( const long index );
+    void DeleteAllItems( void );
+    void DeleteColumn( const int col );
+    void DeleteEverything( void );
+    void EnsureVisible( const long index );
+    long FindItem(const long start, const wxString& str, const bool partial = FALSE );
+    long FindItem(const long start, const long data);
+    long HitTest( const int x, const int y, int &flags );
+    void InsertItem( wxListItem &item );
+    void InsertColumn( const long col, wxListItem &item );
+    void SortItems( wxListCtrlCompare fn, long data );
+    virtual bool OnListNotify( wxListEvent &event );
+    
+  DECLARE_EVENT_TABLE()
+};
+
+//-----------------------------------------------------------------------------
+// wxListCtrl
+//-----------------------------------------------------------------------------
+
+class wxListCtrl: public wxControl
+{
+  DECLARE_DYNAMIC_CLASS(wxListCtrl);
+  
+  public:
+  
+    wxListCtrl(void);
+    wxListCtrl( wxWindow *parent, const wxWindowID id, 
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = "listctrl" );
+    ~wxListCtrl(void);
+    bool Create( wxWindow *parent, const wxWindowID id, 
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = "listctrl" );
+    void OnSize( wxSizeEvent &event );
+    void SetBackgroundColour( const wxColour& col );
+    bool GetColumn( const int col, wxListItem& item );
+    bool SetColumn( const int col, wxListItem& item );
+    int GetColumnWidth( const int col );
+    bool SetColumnWidth( const int col, const int width);
+    int GetCountPerPage(void); // not the same in wxGLC as in Windows, I think
+//  wxText& GetEditControl(void) const; // not supported in wxGLC
+    bool GetItem( wxListItem& info );
+    bool SetItem( wxListItem& info ) ;
+    long SetItem( const long index, const int col, const wxString& label, const int imageId = -1 );
+    int  GetItemState( const long item, const long stateMask );
+    bool SetItemState( const long item, const long state, const long stateMask); 
+    bool SetItemImage( const long item, const int image, const int selImage); 
+    wxString GetItemText( const long item );
+    void SetItemText( const long item, const wxString& str );
+    long GetItemData( const long item );
+    bool SetItemData( const long item, long data );
+    bool GetItemRect( const long item, wxRectangle& rect, const int code = wxLIST_RECT_BOUNDS ); // not supported in wxGLC
+    bool GetItemPosition( const long item, wxPoint& pos ) const; // not supported in wxGLC
+    bool SetItemPosition( const long item, const wxPoint& pos ); // not supported in wxGLC
+    int GetItemCount(void);
+    int GetItemSpacing( bool isSmall );
+    int GetSelectedItemCount(void);
+//  wxColour GetTextColour(void) const; // wxGLC has colours for every Item (see wxListItem)
+//  void SetTextColour(const wxColour& col);
+    long GetTopItem(void);
+    void SetSingleStyle( const long style, const bool add = TRUE ) ;
+    void SetWindowStyleFlag(const long style);
+    void RecreateWindow(void) {};
+    void RealizeChanges( void );  // whereas this is much needed in wxGLC
+    long GetNextItem(const long item, int geometry = wxLIST_NEXT_ALL, int state = wxLIST_STATE_DONTCARE);
+    wxImageList *GetImageList(const int which);
+    void SetImageList(wxImageList *imageList, const int which) ;
+    bool Arrange( const int flag = wxLIST_ALIGN_DEFAULT ); // always wxLIST_ALIGN_LEFT in wxGLC
+    bool DeleteItem( const long item );
+    bool DeleteAllItems(void) ;
+    bool DeleteColumn( const int col );
+//  wxText& Edit(const long item) ;  // not supported in wxGLC
+    bool EnsureVisible( const long item );
+    long FindItem(const long start, const wxString& str, const bool partial = FALSE );
+    long FindItem(const long start, const long data);
+    long FindItem(const long start, const wxPoint& pt, const int direction); // not supported in wxGLC
+    long HitTest(const wxPoint& point, int& flags);
+    long InsertItem(wxListItem& info);
+    long InsertItem(const long index, const wxString& label);
+    long InsertItem(const long index, const int imageIndex);
+    long InsertItem(const long index, const wxString& label, const int imageIndex);
+    long InsertColumn(const long col, wxListItem& info);
+    long InsertColumn(const long col, const wxString& heading, const int format = wxLIST_FORMAT_LEFT,
+      const int width = -1);
+    bool ScrollList(const int dx, const int dy);
+    bool SortItems(wxListCtrlCompare fn, long data);
+    bool Update(const long item);
+    virtual bool OnListNotify(wxListEvent& WXUNUSED(event)) { return FALSE; }
+    void SetDropTarget( wxDropTarget *dropTarget )
+      { m_mainWin->SetDropTarget( dropTarget ); };
+    wxDropTarget *GetDropTarget() const
+      { return m_mainWin->GetDropTarget(); };
+
+  protected:
+  
+//  wxListTextCtrl       m_textCtrl;
+    wxImageList         *m_imageListNormal; 
+    wxImageList         *m_imageListSmall;  
+    wxImageList         *m_imageListState;  // what's that ?
+    wxListHeaderWindow  *m_headerWin;
+    wxListMainWindow    *m_mainWin;
+    
+  DECLARE_EVENT_TABLE()
+
+};
+
+
+#endif // __LISTCTRLH_G__
diff --git a/include/wx/generic/msgdlgg.h b/include/wx/generic/msgdlgg.h
new file mode 100644
index 0000000000..a2029036a5
--- /dev/null
+++ b/include/wx/generic/msgdlgg.h
@@ -0,0 +1,52 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        msgdlgg.h
+// Purpose:     Generic wxMessageDialog
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c)
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __MSGDLGH_G__
+#define __MSGDLGH_G__
+
+#ifdef __GNUG__
+#pragma interface "msgdlgg.h"
+#endif
+
+#include "wx/setup.h"
+#include "wx/dialog.h"
+
+// type is an 'or' (|) of wxOK, wxCANCEL, wxYES_NO
+// Returns wxYES/NO/OK/CANCEL
+
+WXDLLEXPORT_DATA(extern const char*) wxMessageBoxCaptionStr;
+
+class WXDLLEXPORT wxGenericMessageDialog: public wxDialog
+{
+DECLARE_DYNAMIC_CLASS(wxGenericMessageDialog)
+protected:
+    long m_dialogStyle;
+public:
+    wxGenericMessageDialog(wxWindow *parent, const wxString& message, const wxString& caption = wxMessageBoxCaptionStr,
+        long style = wxOK|wxCENTRE, const wxPoint& pos = wxDefaultPosition);
+
+    void OnYes(wxCommandEvent& event);
+    void OnNo(wxCommandEvent& event);
+    void OnCancel(wxCommandEvent& event);
+
+DECLARE_EVENT_TABLE()
+};
+
+#ifndef __WINDOWS__
+#define wxMessageDialog wxGenericMessageDialog
+
+int wxMessageBox(const wxString& message, const wxString& caption = wxMessageBoxCaptionStr, 
+  const long style = wxOK|wxCENTRE, wxWindow *parent = NULL, const int x = -1, const int y = -1);
+
+#endif
+
+#endif
+	// __MSGDLGH_G__
diff --git a/include/wx/generic/panelg.h b/include/wx/generic/panelg.h
new file mode 100644
index 0000000000..89b117992c
--- /dev/null
+++ b/include/wx/generic/panelg.h
@@ -0,0 +1,69 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        panelg.h
+// Purpose:     wxPanel: similar to wxWindows but is coloured as for a dialog
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c)
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __PANELH_G__
+#define __PANELH_G__
+
+#ifdef __GNUG__
+#pragma interface "panelg.h"
+#endif
+
+#include "wx/window.h"
+
+WXDLLEXPORT_DATA(extern const char*) wxPanelNameStr;
+
+// Dialog boxes
+class WXDLLEXPORT wxPanel: public wxWindow
+{
+  DECLARE_DYNAMIC_CLASS(wxPanel)
+public:
+
+  wxPanel(void);
+
+  // Old-style constructor
+  inline wxPanel(wxWindow *parent,
+           const int x = -1, const int y= -1, const int width = 500, const int height = 500,
+           const long style = wxTAB_TRAVERSAL | wxNO_BORDER,
+           const wxString& name = wxPanelNameStr)
+  {
+      Create(parent, -1, wxPoint(x, y), wxSize(width, height), style, name);
+  }
+
+  // Constructor
+  inline wxPanel(wxWindow *parent, const wxWindowID id,
+           const wxPoint& pos = wxDefaultPosition,
+           const wxSize& size = wxDefaultSize,
+           const long style = wxTAB_TRAVERSAL | wxNO_BORDER,
+           const wxString& name = wxPanelNameStr)
+  {
+      Create(parent, id, pos, size, style, name);
+  }
+
+  bool Create(wxWindow *parent, const wxWindowID id,
+           const wxPoint& pos = wxDefaultPosition,
+           const wxSize& size = wxDefaultSize,
+           const long style = wxTAB_TRAVERSAL | wxNO_BORDER,
+           const wxString& name = wxPanelNameStr);
+
+  void OnPaint(wxPaintEvent& event);
+
+  // Sends an OnInitDialog event, which in turns transfers data to
+  // to the dialog via validators.
+  virtual void InitDialog(void);
+
+  // Responds to colour changes
+  void OnSysColourChanged(wxSysColourChangedEvent& event);
+
+DECLARE_EVENT_TABLE()
+};
+
+#endif
+    // __PANELH_G__
diff --git a/include/wx/generic/printps.h b/include/wx/generic/printps.h
new file mode 100644
index 0000000000..9bf783b4bc
--- /dev/null
+++ b/include/wx/generic/printps.h
@@ -0,0 +1,57 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        printps.h
+// Purpose:     wxPostScriptPrinter, wxPostScriptPrintPreview
+//              wxGenericPageSetupDialog
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c)
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __PRINTPSH__
+#define __PRINTPSH__
+
+#ifdef __GNUG__
+#pragma interface "printps.h"
+#endif
+
+#include "wx/prntbase.h"
+
+/*
+ * Represents the printer: manages printing a wxPrintout object
+ */
+ 
+class WXDLLEXPORT wxPostScriptPrinter: public wxPrinterBase
+{
+  DECLARE_DYNAMIC_CLASS(wxPostScriptPrinter)
+
+ public:
+  wxPostScriptPrinter(wxPrintData *data = NULL);
+  ~wxPostScriptPrinter(void);
+
+  virtual bool Print(wxWindow *parent, wxPrintout *printout, bool prompt = TRUE);
+  virtual bool PrintDialog(wxWindow *parent);
+  virtual bool Setup(wxWindow *parent);
+};
+
+/*
+ * wxPrintPreview
+ * Programmer creates an object of this class to preview a wxPrintout.
+ */
+ 
+class WXDLLEXPORT wxPostScriptPrintPreview: public wxPrintPreviewBase
+{
+  DECLARE_CLASS(wxPostScriptPrintPreview)
+
+ public:
+  wxPostScriptPrintPreview(wxPrintout *printout, wxPrintout *printoutForPrinting = NULL, wxPrintData *data = NULL);
+  ~wxPostScriptPrintPreview(void);
+
+  virtual bool Print(bool interactive);
+  virtual void DetermineScaling(void);
+};
+
+#endif
+    // __PRINTPSH__
diff --git a/include/wx/generic/prntdlgg.h b/include/wx/generic/prntdlgg.h
new file mode 100644
index 0000000000..c9cbee6d75
--- /dev/null
+++ b/include/wx/generic/prntdlgg.h
@@ -0,0 +1,145 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        prntdlgg.h
+// Purpose:     wxGenericPrintDialog, wxGenericPrintSetupDialog,
+//              wxGenericPageSetupDialog
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c)
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __PRINTDLGH_G_
+#define __PRINTDLGH_G_
+
+#ifdef __GNUG__
+#pragma interface "prntdlgg.h"
+#endif
+
+#include "wx/defs.h"
+#include "wx/dialog.h"
+#include "wx/dc.h"
+#include "wx/cmndata.h"
+#include "wx/postscrp.h"
+
+class WXDLLEXPORT wxTextCtrl;
+class WXDLLEXPORT wxButton;
+class WXDLLEXPORT wxCheckBox;
+class WXDLLEXPORT wxChoice;
+class WXDLLEXPORT wxStaticText;
+class WXDLLEXPORT wxRadioBox;
+
+/*
+ * Simulated Print and Print Setup dialogs
+ * for non-Windows platforms (and Windows using PostScript print/preview)
+ */
+
+#define wxPRINTID_STATIC        10
+#define wxPRINTID_RANGE         11
+#define wxPRINTID_FROM          12
+#define wxPRINTID_TO            13
+#define wxPRINTID_COPIES        14
+#define wxPRINTID_PRINTTOFILE   15
+#define wxPRINTID_SETUP         16
+
+class WXDLLEXPORT wxGenericPrintDialog: public wxDialog
+{
+  DECLARE_DYNAMIC_CLASS(wxGenericPrintDialog)
+
+ public:
+  wxStaticText  *printerMessage;
+  wxButton   *setupButton;
+  wxButton   *helpButton;
+  wxRadioBox *rangeRadioBox;
+  wxTextCtrl     *fromText;
+  wxTextCtrl     *toText;
+  wxTextCtrl     *noCopiesText;
+  wxCheckBox *printToFileCheckBox;
+  wxCheckBox *collateCopiesCheckBox;
+
+  wxPrintData printData;
+  wxGenericPrintDialog(wxWindow *parent, wxPrintData* data);
+  ~wxGenericPrintDialog(void);
+
+  void OnSetup(wxCommandEvent& event);
+  void OnRange(wxCommandEvent& event);
+  void OnOK(wxCommandEvent& event);
+
+  virtual bool TransferDataFromWindow(void);
+  virtual bool TransferDataToWindow(void);
+
+  virtual int ShowModal(void);
+
+  inline wxPrintData& GetPrintData(void) { return printData; }
+  wxDC *GetPrintDC(void);
+
+DECLARE_EVENT_TABLE()
+};
+
+#define wxPRINTID_PRINTCOLOUR       10
+#define wxPRINTID_ORIENTATION       11
+#define wxPRINTID_COMMAND           12
+#define wxPRINTID_OPTIONS           13
+#define wxPRINTID_PAPERSIZE         14
+
+class WXDLLEXPORT wxGenericPrintSetupDialog: public wxDialog
+{
+  DECLARE_CLASS(wxGenericPrintSetupDialog)
+
+ public:
+  wxRadioBox *orientationRadioBox;
+  wxTextCtrl     *printerCommandText;
+  wxTextCtrl     *printerOptionsText;
+  wxCheckBox *colourCheckBox;
+  wxChoice   *paperTypeChoice;
+
+  wxPrintSetupData printData;
+  wxGenericPrintSetupDialog(wxWindow *parent, wxPrintSetupData* data);
+  ~wxGenericPrintSetupDialog(void);
+
+  virtual bool TransferDataFromWindow(void);
+  virtual bool TransferDataToWindow(void);
+
+  wxChoice *CreatePaperTypeChoice(int* x, int* y);
+  inline wxPrintSetupData& GetPrintData(void) { return printData; }
+};
+
+#define wxPRINTID_LEFTMARGIN         30
+#define wxPRINTID_RIGHTMARGIN        31
+#define wxPRINTID_TOPMARGIN          32
+#define wxPRINTID_BOTTOMMARGIN       33
+
+class WXDLLEXPORT wxGenericPageSetupDialog: public wxDialog
+{
+  DECLARE_CLASS(wxGenericPageSetupDialog)
+
+ public:
+  wxButton   *printerButton;
+  wxRadioBox *orientationRadioBox;
+  wxTextCtrl     *marginLeftText;
+  wxTextCtrl     *marginTopText;
+  wxTextCtrl     *marginRightText;
+  wxTextCtrl     *marginBottomText;
+  wxChoice   *paperTypeChoice;
+
+  static bool pageSetupDialogCancelled;
+  
+  wxPageSetupData pageData;
+
+  wxGenericPageSetupDialog(wxWindow *parent, wxPageSetupData* data = NULL);
+  ~wxGenericPageSetupDialog(void);
+
+  virtual bool TransferDataFromWindow(void);
+  virtual bool TransferDataToWindow(void);
+
+  void OnPrinter(wxCommandEvent& event);
+
+  wxChoice *CreatePaperTypeChoice(int* x, int* y);
+  inline wxPageSetupData& GetPageSetupData(void) { return pageData; }
+
+DECLARE_EVENT_TABLE()
+};
+
+#endif
+    // __PRINTDLGH_G__
diff --git a/include/wx/generic/scrolwin.h b/include/wx/generic/scrolwin.h
new file mode 100644
index 0000000000..b80e443e14
--- /dev/null
+++ b/include/wx/generic/scrolwin.h
@@ -0,0 +1,141 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        scrolwin.h
+// Purpose:     wxScrolledWindow class
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __SCROLWINH_G__
+#define __SCROLWINH_G__
+
+#ifdef __GNUG__
+#pragma interface "scrolwin.h"
+#endif
+
+#include "wx/window.h"
+
+WXDLLEXPORT_DATA(extern const char*) wxPanelNameStr;
+
+class WXDLLEXPORT wxScrolledWindow: public wxWindow
+{
+  DECLARE_ABSTRACT_CLASS(wxScrolledWindow)
+
+public:
+  wxScrolledWindow(void);
+  inline wxScrolledWindow(wxWindow *parent, const wxWindowID id = -1,
+           const wxPoint& pos = wxDefaultPosition,
+           const wxSize& size = wxDefaultSize,
+           const long style = wxHSCROLL|wxVSCROLL,
+           const wxString& name = wxPanelNameStr)
+  {
+      Create(parent, id, pos, size, style, name);
+  }
+
+  inline ~wxScrolledWindow(void) {}
+
+  bool Create(wxWindow *parent, const wxWindowID id,
+           const wxPoint& pos = wxDefaultPosition,
+           const wxSize& size = wxDefaultSize,
+           const long style = wxHSCROLL|wxVSCROLL,
+           const wxString& name = wxPanelNameStr);
+
+  // Set client size
+  // Should take account of scrollbars
+//  virtual void SetClientSize(const int width, const int size);
+
+  // Is the window retained?
+//  inline bool IsRetained(void) const;
+
+  // Number of pixels per user unit (0 or -1 for no scrollbar)
+  // Length of virtual canvas in user units
+  // Length of page in user units
+  virtual void SetScrollbars(const int pixelsPerUnitX, const int pixelsPerUnitY,
+                             const int noUnitsX, const int noUnitsY,
+                             const int xPos = 0, const int yPos = 0, 
+			     const bool noRefresh = FALSE );
+
+  // Physically scroll the window
+  virtual void Scroll(const int x_pos, const int y_pos);
+
+#if WXWIN_COMPATIBILITY
+  virtual void GetScrollUnitsPerPage(int *x_page, int *y_page) const;
+#endif
+
+  int GetScrollPageSize(int orient) const ;
+  void SetScrollPageSize(int orient, int pageSize);
+
+  virtual void GetScrollPixelsPerUnit(int *x_unit, int *y_unit) const;
+  // Enable/disable Windows scrolling in either direction.
+  // If TRUE, wxWindows scrolls the canvas and only a bit of
+  // the canvas is invalidated; no Clear() is necessary.
+  // If FALSE, the whole canvas is invalidated and a Clear() is
+  // necessary. Disable for when the scroll increment is used
+  // to actually scroll a non-constant distance
+  virtual void EnableScrolling(const bool x_scrolling, const bool y_scrolling);
+
+  // Get the view start
+  virtual void ViewStart(int *x, int *y) const;
+
+  // Actual size in pixels when scrolling is taken into account
+  virtual void GetVirtualSize(int *x, int *y) const;
+
+  virtual void CalcScrolledPosition(const int x, const int y, int *xx, int *yy) const ;
+  virtual void CalcUnscrolledPosition(const int x, const int y, float *xx, float *yy) const ;
+
+  // Adjust the scrollbars
+  virtual void AdjustScrollbars(void);
+
+/*
+#if WXWIN_COMPATIBILITY
+  virtual void OldOnScroll(wxCommandEvent& WXUNUSED(event));
+  virtual void OldOnPaint(void);                 // Called when needs painting
+  virtual void OldOnSize(int width, int height);           // Called on resize
+  virtual void OldOnMouseEvent(wxMouseEvent& event);  // Called on mouse event
+  virtual void OldOnChar(wxKeyEvent& event);     // Called on character event
+#endif
+*/
+
+  void OnScroll(wxScrollEvent& event);
+  void OnSize(wxSizeEvent& event);
+  void OnPaint(wxPaintEvent& event);
+
+  // Override this function to draw the graphic.
+  virtual void OnDraw(wxDC& WXUNUSED(dc)) {};
+
+  // Override this function if you don't want to have wxScrolledWindow
+  // automatically change the origin according to the scroll position.
+  virtual void PrepareDC(wxDC& dc);
+
+public:
+  ////////////////////////////////////////////////////////////////////////
+  //// IMPLEMENTATION
+  
+  // Calculate scroll increment
+  virtual int CalcScrollInc(wxScrollEvent& event);
+
+  ////////////////////////////////////////////////////////////////////////
+  //// PROTECTED DATA
+protected:
+  int                   m_xScrollPixelsPerLine;
+  int                   m_yScrollPixelsPerLine;
+  bool                  m_xScrollingEnabled;
+  bool                  m_yScrollingEnabled;
+  int                   m_xScrollPosition;
+  int                   m_yScrollPosition;
+  int                   m_xScrollLines;
+  int                   m_yScrollLines;
+  int                   m_xScrollLinesPerPage;
+  int                   m_yScrollLinesPerPage;
+
+DECLARE_EVENT_TABLE()
+};
+
+////////////////////////////////////////////////////////////////////////
+//// INLINES
+
+#endif
+    // __SCROLWINH_G__
diff --git a/include/wx/generic/splitter.h b/include/wx/generic/splitter.h
new file mode 100644
index 0000000000..0a41b11bdc
--- /dev/null
+++ b/include/wx/generic/splitter.h
@@ -0,0 +1,180 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        splitter.h
+// Purpose:     wxSplitterWindow class
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __SPLITTERH_G__
+#define __SPLITTERH_G__
+
+#ifdef __GNUG__
+#pragma interface "splitter.h"
+#endif
+
+#include "wx/defs.h"
+#include "wx/window.h"
+#include "wx/string.h"
+
+#define WXSPLITTER_VERSION      1.0
+
+#define wxSPLIT_HORIZONTAL      1
+#define wxSPLIT_VERTICAL        2
+
+#define wxSPLIT_DRAG_NONE       0
+#define wxSPLIT_DRAG_DRAGGING   1
+#define wxSPLIT_DRAG_LEFT_DOWN  2
+
+/*
+ * wxSplitterWindow maintains one or two panes, with
+ * an optional vertical or horizontal split which
+ * can be used with the mouse or programmatically.
+ */
+
+// TODO:
+// 1) Perhaps make the borders sensitive to dragging in order to create a split.
+//    The MFC splitter window manages scrollbars as well so is able to
+//    put sash buttons on the scrollbars, but we probably don't want to go down
+//    this path.
+// 2) for wxWindows 2.0, we must find a way to set the WS_CLIPCHILDREN style
+//    to prevent flickering. (WS_CLIPCHILDREN doesn't work in all cases so can't be
+//    standard).
+
+class WXDLLEXPORT wxSplitterWindow: public wxWindow
+{
+  DECLARE_DYNAMIC_CLASS(wxSplitterWindow)
+
+ public:
+
+////////////////////////////////////////////////////////////////////////////
+// Public API
+
+    // Default constructor
+    wxSplitterWindow(void);
+
+    // Normal constructor
+    wxSplitterWindow(wxWindow *parent, const wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition,
+        const wxSize& size = wxDefaultSize, const long style = wxSP_3D, const wxString& name = "splitter");
+    ~wxSplitterWindow(void);
+
+    // Gets the only or left/top pane
+    inline wxWindow *GetWindow1(void) { return m_windowOne; }
+
+    // Gets the right/bottom pane
+    inline wxWindow *GetWindow2(void) { return m_windowTwo; }
+
+    // Sets the split mode
+    inline void SetSplitMode(const int mode) { m_splitMode = mode; }
+
+    // Gets the split mode
+    inline int GetSplitMode(void) const { return m_splitMode; };
+
+    // Initialize with one window
+    void Initialize(wxWindow *window);
+
+    // Associates the given window with window 2, drawing the appropriate sash
+    // and changing the split mode.
+    // Does nothing and returns FALSE if the window is already split.
+    // A sashPosition of -1 means choose a default sash position.
+    bool SplitVertically(wxWindow *window1, wxWindow *window2, const int sashPosition = -1);
+    bool SplitHorizontally(wxWindow *window1, wxWindow *window2, const int sashPosition = -1);
+
+    // Removes the specified (or second) window from the view
+    // Doesn't actually delete the window.
+    bool Unsplit(wxWindow *toRemove = NULL);
+
+    // Is the window split?
+    inline bool IsSplit(void) const { return (m_windowTwo != NULL); }
+
+    // Sets the sash size
+    inline void SetSashSize(const int width) { m_sashSize = width; }
+
+    // Sets the border size
+    inline void SetBorderSize(const int width) { m_borderSize = width; }
+
+    // Gets the sash size
+    inline int GetSashSize(void) const { return m_sashSize; }
+
+    // Gets the border size
+    inline int GetBorderSize(void) const { return m_borderSize; }
+
+    // Set the sash position
+    void SetSashPosition(const int position, const bool redaw = TRUE);
+
+    // Gets the sash position
+    inline int GetSashPosition(void) const { return m_sashPosition; }
+
+    // If this is zero, we can remove panes by dragging the sash.
+    inline void SetMinimumPaneSize(const int min) { m_minimumPaneSize = min; }
+    inline int GetMinimumPaneSize(void) const { return m_minimumPaneSize; }
+
+    // If the sash is moved to an extreme position, a subwindow
+    // is removed from the splitter window, and the app is
+    // notified. The app should delete or hide the window.
+    virtual void OnUnsplit(wxWindow *removed) { removed->Show(FALSE); }
+
+    // Called when the sash is double-clicked.
+    // The default behaviour is to remove the sash if the
+    // minimum pane size is zero.
+    virtual void OnDoubleClickSash(int x, int y);
+
+////////////////////////////////////////////////////////////////////////////
+// Implementation
+
+    // Paints the border and sash
+    void OnPaint(wxPaintEvent& event);
+
+    // Handles mouse events
+    void OnMouseEvent(wxMouseEvent& ev);
+
+    // Adjusts the panes
+    void OnSize(wxSizeEvent& event);
+
+    // Draws borders
+    void DrawBorders(wxDC& dc);
+
+    // Draws the sash
+    void DrawSash(wxDC& dc);
+
+    // Draws the sash tracker (for whilst moving the sash)
+    void DrawSashTracker(const int x, const int y);
+
+    // Tests for x, y over sash
+    bool SashHitTest(const int x, const int y, const int tolerance = 2);
+
+    // Resizes subwindows
+    void SizeWindows(void);
+
+    // Initialize colours
+    void InitColours(void);
+
+ protected:
+    int         m_splitMode;
+    wxWindow*   m_windowOne;
+    wxWindow*   m_windowTwo;
+    int         m_dragMode;
+    int         m_oldX;
+    int         m_oldY;
+    int         m_borderSize;
+    int         m_sashSize;     // Sash width or height
+    int         m_sashPosition; // Number of pixels from left or top
+    int         m_firstX;
+    int         m_firstY;
+    int         m_minimumPaneSize;
+    wxCursor*   m_sashCursorWE;
+    wxCursor*   m_sashCursorNS;
+    wxPen*      m_sashTrackerPen;
+    wxPen*      m_lightShadowPen;
+    wxPen*      m_mediumShadowPen;
+    wxPen*      m_darkShadowPen;
+    wxPen*      m_hilightPen;
+    wxBrush*    m_faceBrush;
+    wxPen*      m_facePen;
+DECLARE_EVENT_TABLE()
+};
+
+#endif
diff --git a/include/wx/generic/statusbr.h b/include/wx/generic/statusbr.h
new file mode 100644
index 0000000000..91c4abcac2
--- /dev/null
+++ b/include/wx/generic/statusbr.h
@@ -0,0 +1,92 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        statusbr.h
+// Purpose:     wxStatusBar class
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __STATUSBRH_G__
+#define __STATUSBRH_G__
+
+#ifdef __GNUG__
+#pragma interface "statusbr.h"
+#endif
+
+#include "wx/window.h"
+
+WXDLLEXPORT_DATA(extern const char*) wxPanelNameStr;
+
+class WXDLLEXPORT wxStatusBar: public wxWindow
+{
+  DECLARE_DYNAMIC_CLASS(wxStatusBar)
+
+public:
+  wxStatusBar(void);
+  inline wxStatusBar(wxWindow *parent, const wxWindowID id,
+           const wxPoint& pos = wxDefaultPosition,
+           const wxSize& size = wxDefaultSize,
+           const long style = 0,
+           const wxString& name = wxPanelNameStr)
+  {
+      Create(parent, id, pos, size, style, name);
+  }
+
+  ~wxStatusBar(void);
+
+  bool Create(wxWindow *parent, const wxWindowID id,
+           const wxPoint& pos = wxDefaultPosition,
+           const wxSize& size = wxDefaultSize,
+           const long style = 0,
+           const wxString& name = wxPanelNameStr);
+
+  // Create status line
+  virtual void SetFieldsCount(const int number=1, const int *widths = NULL);
+  inline int GetFieldsCount(void) const { return m_nFields; }
+
+  // Set status line text
+  virtual void SetStatusText(const wxString& text, const int number = 0);
+  virtual wxString GetStatusText(const int number = 0) const;
+
+  // Set status line widths
+  virtual void SetStatusWidths(const int n, const int *widths_field);
+
+  virtual void DrawFieldText(wxDC& dc, const int i);
+  virtual void DrawField(wxDC& dc, const int i);
+
+  // Get the position and size of the field's internal bounding rectangle
+  virtual bool GetFieldRect(const int i, wxRectangle& rect) const;
+
+  inline int GetBorderX(void) const { return m_borderX; }
+  inline int GetBorderY(void) const { return m_borderY; }
+  inline void SetBorderX(const int x);
+  inline void SetBorderY(const int y);
+
+  ////////////////////////////////////////////////////////////////////////
+  // Implementation
+
+  void OnPaint(wxPaintEvent& event);
+
+  virtual void InitColours(void);
+
+  // Responds to colour changes
+  void OnSysColourChanged(wxSysColourChangedEvent& event);
+
+protected:
+  int *             m_statusWidths;
+  int               m_nFields;
+  wxString *        m_statusStrings;
+  int               m_borderX;
+  int               m_borderY;
+  wxFont            m_defaultStatusBarFont;
+  wxPen             m_mediumShadowPen;
+  wxPen             m_hilightPen;
+
+  DECLARE_EVENT_TABLE()
+};
+
+#endif
+    // __STATUSBRH_G__
diff --git a/include/wx/generic/tabg.h b/include/wx/generic/tabg.h
new file mode 100644
index 0000000000..34cf2326f7
--- /dev/null
+++ b/include/wx/generic/tabg.h
@@ -0,0 +1,343 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        tabg.h
+// Purpose:     Generic tabbed dialogs
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c)
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __TABGH_G__
+#define __TABGH_G__
+
+#ifdef __GNUG__
+#pragma interface "tabg.h"
+#endif
+
+#define WXTAB_VERSION   1.1
+
+#include "wx/hash.h"
+#include "wx/string.h"
+
+class wxTabView;
+
+/*
+ * A wxTabControl is the internal and visual representation
+ * of the tab.
+ */
+ 
+class wxTabControl: public wxObject
+{
+DECLARE_DYNAMIC_CLASS(wxTabControl)
+public:
+    wxTabControl(wxTabView *v = NULL);
+    ~wxTabControl(void);
+    
+    virtual void OnDraw(wxDC& dc, bool lastInRow);
+    inline void SetLabel(const wxString& str) { m_controlLabel = str; }
+    inline wxString GetLabel(void) const { return m_controlLabel; }
+
+    inline void SetFont(wxFont *f) { m_labelFont = f; }
+    inline wxFont *GetFont(void) const { return m_labelFont; }
+
+    inline void SetSelected(bool sel) { m_isSelected = sel; }
+    inline bool IsSelected(void) const { return m_isSelected; }
+
+    inline void SetPosition(int x, int y) { m_offsetX = x; m_offsetY = y; }
+    inline void SetSize(int x, int y) { m_width = x; m_height = y; }
+    
+    inline void SetRowPosition(int r) { m_rowPosition = r; }
+    inline int GetRowPosition() const { return m_rowPosition; }
+    inline void SetColPosition(int c) { m_colPosition = c; }
+    inline int GetColPosition() const { return m_colPosition; }
+    
+    inline int GetX(void) const { return m_offsetX; }
+    inline int GetY(void) const { return m_offsetY; }
+    inline int GetWidth(void) const { return m_width; }
+    inline int GetHeight(void) const { return m_height; }
+    
+    inline int GetId(void) const { return m_id; }
+    inline void SetId(int i) { m_id = i; }
+    
+    virtual bool HitTest(int x, int y) const ;
+
+protected:
+    wxTabView*      m_view;
+    wxString        m_controlLabel;
+    bool            m_isSelected;
+    wxFont*         m_labelFont;
+    int             m_offsetX; // Offsets from top-left of tab view area (the area below the tabs)
+    int             m_offsetY;
+    int             m_width;
+    int             m_height;
+    int             m_id;
+    int             m_rowPosition; // Position in row from 0
+    int             m_colPosition; // Position in col from 0
+};
+ 
+/*
+ * Each wxTabLayer is a list of tabs. E.g. there
+ * are 3 layers in the MS Word Options dialog.
+ */
+ 
+class wxTabLayer: public wxList
+{
+  DECLARE_DYNAMIC_CLASS(wxTabLayer)
+  public:
+    wxTabLayer(void)
+    {
+    }
+};
+
+/*
+ * The wxTabView controls and draws the tabbed object
+ */
+
+#define wxTAB_STYLE_DRAW_BOX         1   // Draws 3D boxes round tab layers
+#define wxTAB_STYLE_COLOUR_INTERIOR  2   // Colours interior of tabs, otherwise draws outline
+
+class wxTabView: public wxObject
+{
+DECLARE_DYNAMIC_CLASS(wxTabView)
+public:
+  wxTabView(long style = wxTAB_STYLE_DRAW_BOX | wxTAB_STYLE_COLOUR_INTERIOR);
+  ~wxTabView();
+
+  inline int GetNumberOfLayers() const { return m_layers.Number(); }
+  inline wxList& GetLayers() { return m_layers; }
+
+  inline void SetWindow(wxWindow* wnd) { m_window = wnd; }
+  inline wxWindow* GetWindow(void) const { return m_window; }
+  
+  // Automatically positions tabs
+  wxTabControl *AddTab(int id, const wxString& label, wxTabControl *existingTab = NULL);
+  
+  void ClearTabs(bool deleteTabs = TRUE);
+
+  // Layout tabs (optional, e.g. if resizing window)
+  void Layout(void);
+
+  // Draw all tabs
+  virtual void Draw(wxDC& dc);
+  
+  // Process mouse event, return FALSE if we didn't process it
+  virtual bool OnEvent(wxMouseEvent& event);
+
+  // Called when a tab is activated
+  virtual void OnTabActivate(int activateId, int deactivateId);
+  // Allows vetoing
+  virtual bool OnTabPreActivate(int WXUNUSED(activateId), int WXUNUSED(deactivateId) ) { return TRUE; };
+
+  // Allows use of application-supplied wxTabControl classes.
+  virtual wxTabControl *OnCreateTabControl(void) { return new wxTabControl(this); }
+
+  void SetHighlightColour(const wxColour& col);
+  void SetShadowColour(const wxColour& col);
+  void SetBackgroundColour(const wxColour& col);
+  inline void SetTextColour(const wxColour& col) { m_textColour = col; }
+  
+  inline wxColour GetHighlightColour(void) const { return m_highlightColour; }
+  inline wxColour GetShadowColour(void) const { return m_shadowColour; }
+  inline wxColour GetBackgroundColour(void) const { return m_backgroundColour; }
+  inline wxColour GetTextColour(void) const { return m_textColour; }
+  inline wxPen *GetHighlightPen(void) const { return m_highlightPen; }
+  inline wxPen *GetShadowPen(void) const { return m_shadowPen; }
+  inline wxPen *GetBackgroundPen(void) const { return m_backgroundPen; }
+  inline wxBrush *GetBackgroundBrush(void) const { return m_backgroundBrush; }
+  
+  inline void SetViewRect(const wxRectangle& rect) { m_tabViewRect = rect; }
+  inline wxRect GetViewRect(void) const { return m_tabViewRect; }
+  
+  // Calculate tab width to fit to view, and optionally adjust the view
+  // to fit the tabs exactly.
+  int CalculateTabWidth(int noTabs, bool adjustView = FALSE);
+
+  inline void SetTabStyle(long style) { m_tabStyle = style; }
+  inline long GetTabStyle(void) const { return m_tabStyle; }
+  
+  inline void SetTabSize(int w, int h) { m_tabWidth = w; m_tabHeight = h; }
+  inline int GetTabWidth(void) const { return m_tabWidth; }
+  inline int GetTabHeight(void) const { return m_tabHeight; }
+  inline void SetTabSelectionHeight(int h) { m_tabSelectionHeight = h; }
+  inline int GetTabSelectionHeight(void) const { return m_tabSelectionHeight; }
+  
+  inline int GetTopMargin(void) const { return m_topMargin; }
+  inline void SetTopMargin(int margin) { m_topMargin = margin; }
+  
+  void SetTabSelection(int sel, bool activateTool = TRUE);
+  inline int GetTabSelection() const { return m_tabSelection; }
+  
+  // Find tab control for id
+  wxTabControl *FindTabControlForId(int id) const ;
+
+  // Find tab control for layer, position (starting from zero)
+  wxTabControl *FindTabControlForPosition(int layer, int position) const ;
+  
+  inline int GetHorizontalTabOffset() const { return m_tabHorizontalOffset; }
+  inline int GetHorizontalTabSpacing() const { return m_tabHorizontalSpacing; }
+  inline void SetHorizontalTabOffset(int sp) { m_tabHorizontalOffset = sp; }
+  inline void SetHorizontalTabSpacing(int sp) { m_tabHorizontalSpacing = sp; }
+  
+  inline void SetVerticalTabTextSpacing(int s) { m_tabVerticalTextSpacing = s; }
+  inline int GetVerticalTabTextSpacing() const { return m_tabVerticalTextSpacing; }
+  
+  inline wxFont *GetTabFont() const { return m_tabFont; }
+  inline void SetTabFont(wxFont *f) { m_tabFont = f; }
+
+  inline wxFont *GetSelectedTabFont() const { return m_tabSelectedFont; }
+  inline void SetSelectedTabFont(wxFont *f) { m_tabSelectedFont = f; }
+  // Find the node and the column at which this control is positioned.
+  wxNode *FindTabNodeAndColumn(wxTabControl *control, int *col) const ;
+  
+  // Do the necessary to change to this tab
+  virtual bool ChangeTab(wxTabControl *control);
+
+  // Move the selected tab to the bottom layer, if necessary,
+  // without calling app activation code
+  bool MoveSelectionTab(wxTabControl *control);
+
+  inline int GetNumberOfTabs() const { return m_noTabs; }
+
+protected:
+   // List of layers, from front to back.
+   wxList           m_layers;
+   
+   // Selected tab
+   int              m_tabSelection;
+
+   // Usual tab height
+   int              m_tabHeight;
+
+   // The height of the selected tab
+   int              m_tabSelectionHeight;
+
+   // Usual tab width
+   int              m_tabWidth;
+   
+   // Space between tabs
+   int              m_tabHorizontalSpacing;
+   
+   // Space between top of normal tab and text
+   int              m_tabVerticalTextSpacing;
+   
+   // Horizontal offset of each tab row above the first
+   int              m_tabHorizontalOffset;
+
+   // The distance between the bottom of the first tab row
+   // and the top of the client area (i.e. the margin)
+   int              m_topMargin;
+
+   // The position and size of the view above which the tabs are placed.
+   // I.e., the internal client area of the sheet.
+   wxRect           m_tabViewRect;
+   
+   // Bitlist of styles
+   long             m_tabStyle;
+
+   // Colours
+   wxColour         m_highlightColour;
+   wxColour         m_shadowColour;
+   wxColour         m_backgroundColour;
+   wxColour         m_textColour;
+   
+   // Pen and brush cache
+   wxPen*           m_highlightPen;
+   wxPen*           m_shadowPen;
+   wxPen*           m_backgroundPen;
+   wxBrush*         m_backgroundBrush;
+   
+   wxFont*          m_tabFont;
+   wxFont*          m_tabSelectedFont;
+   
+   int              m_noTabs;
+
+   wxWindow*        m_window;
+};
+
+/*
+ * A dialog box class that is tab-friendly
+ */
+ 
+class wxTabbedDialog: public wxDialog
+{
+DECLARE_DYNAMIC_CLASS(wxTabbedDialog)
+ 
+public:
+
+   wxTabbedDialog(wxWindow *parent, const wxWindowID id, const wxString& title,
+    const wxPoint& pos = wxDefaultPosition,
+    const wxSize& size = wxDefaultSize,
+     const long windowStyle = wxDEFAULT_DIALOG_STYLE, const wxString& name = wxDialogNameStr);
+   ~wxTabbedDialog(void);
+ 
+   inline wxTabView *GetTabView() const { return m_tabView; }
+   inline void SetTabView(wxTabView *v) { m_tabView = v; }
+
+   void OnCloseWindow(wxCloseEvent& event);
+   void OnMouseEvent(wxMouseEvent& event);
+   void OnPaint(wxPaintEvent& event);
+
+protected:
+   wxTabView*   m_tabView;
+   
+DECLARE_EVENT_TABLE()
+};
+
+/*
+ * A panel class that is tab-friendly
+ */
+
+class wxTabbedPanel: public wxPanel
+{
+DECLARE_DYNAMIC_CLASS(wxTabbedPanel)
+ 
+public:
+
+   wxTabbedPanel(wxWindow *parent, const wxWindowID id,
+    const wxPoint& pos = wxDefaultPosition,
+    const wxSize& size = wxDefaultSize,
+    const long windowStyle = 0, const wxString& name = wxPanelNameStr);
+   ~wxTabbedPanel(void);
+ 
+   inline wxTabView *GetTabView() const { return m_tabView; }
+   inline void SetTabView(wxTabView *v) { m_tabView = v; }
+  
+   void OnMouseEvent(wxMouseEvent& event);
+   void OnPaint(wxPaintEvent& event);
+
+protected:
+   wxTabView*   m_tabView;
+   
+DECLARE_EVENT_TABLE()
+};
+
+class wxPanelTabView: public wxTabView
+{
+DECLARE_DYNAMIC_CLASS(wxPanelTabView)
+public:
+  wxPanelTabView(wxPanel *pan, long style = wxTAB_STYLE_DRAW_BOX | wxTAB_STYLE_COLOUR_INTERIOR);
+  ~wxPanelTabView(void);
+
+  // Called when a tab is activated
+  virtual void OnTabActivate(int activateId, int deactivateId);
+
+  // Specific to this class
+   void AddTabWindow(int id, wxWindow *window);
+   wxWindow *GetTabWindow(int id) const ;
+   void ClearWindows(bool deleteWindows = TRUE);
+   inline wxWindow *GetCurrentWindow() const { return m_currentWindow; }
+   
+   void ShowWindowForTab(int id);
+
+protected:
+   // List of panels, one for each tab. Indexed
+   // by tab ID.
+   wxList           m_tabWindows;
+   wxWindow*        m_currentWindow;
+   wxPanel*         m_panel;
+};
+
+#endif
+
diff --git a/include/wx/generic/textdlgg.h b/include/wx/generic/textdlgg.h
new file mode 100644
index 0000000000..0cf94426a3
--- /dev/null
+++ b/include/wx/generic/textdlgg.h
@@ -0,0 +1,51 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        textdlgg.h
+// Purpose:     wxStatusBar class
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __TEXTDLGH_G__
+#define __TEXTDLGH_G__
+
+#ifdef __GNUG__
+#pragma interface "textdlgg.h"
+#endif
+
+#include "wx/setup.h"
+#include "wx/dialog.h"
+
+// Handy dialog functions (will be converted into classes at some point)
+WXDLLEXPORT_DATA(extern const char*) wxGetTextFromUserPromptStr;
+WXDLLEXPORT_DATA(extern const char*) wxEmptyString;
+
+#define wxID_TEXT 3000
+
+class WXDLLEXPORT wxTextEntryDialog: public wxDialog
+{
+DECLARE_DYNAMIC_CLASS(wxTextEntryDialog)
+protected:
+    long m_dialogStyle;
+    wxString m_value;
+public:
+    wxTextEntryDialog(wxWindow *parent, const wxString& message, const wxString& caption = wxGetTextFromUserPromptStr,
+        const wxString& value = wxEmptyString, long style = wxOK|wxCANCEL|wxCENTRE, const wxPoint& pos = wxDefaultPosition);
+
+    inline void SetValue(const wxString& val) { m_value = val; }
+    inline wxString GetValue(void) const { return m_value; }
+
+    void OnOK(wxCommandEvent& event);
+
+DECLARE_EVENT_TABLE()
+};
+
+wxString WXDLLEXPORT wxGetTextFromUser(const wxString& message, const wxString& caption = wxGetTextFromUserPromptStr,
+                        const wxString& default_value = wxEmptyString, wxWindow *parent = NULL,
+                        int x = -1, int y = -1, bool centre = TRUE);
+
+#endif
+    // __TEXTDLGH_G__
diff --git a/include/wx/generic/treectrl.h b/include/wx/generic/treectrl.h
new file mode 100644
index 0000000000..328ea2474e
--- /dev/null
+++ b/include/wx/generic/treectrl.h
@@ -0,0 +1,300 @@
+/*
+ * Author: Robert Roebling
+ *
+ * Copyright: (C) 1997,1998 Robert Roebling
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the wxWindows Licence, which
+ * you have received with this library (see Licence.htm).
+ *
+ */
+
+#ifndef __GTKTREECTRLH_G__
+#define __GTKTREECTRLH_G__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/string.h"
+#include "wx/list.h"
+#include "wx/control.h"
+#include "wx/event.h"
+#include "wx/imaglist.h"
+#include "wx/scrolwin.h"
+#include "wx/dcclient.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxTreeItem;
+class wxTreeEvent;
+
+class wxGenericTreeItem;
+class wxTreeCtrl;
+
+//-----------------------------------------------------------------------------
+// constants
+//-----------------------------------------------------------------------------
+
+// WXDLLEXPORT extern const char *wxTreeNameStr;
+
+#define wxTREE_MASK_HANDLE          0x0001
+#define wxTREE_MASK_STATE           0x0002
+#define wxTREE_MASK_TEXT            0x0004
+#define wxTREE_MASK_IMAGE           0x0008
+#define wxTREE_MASK_SELECTED_IMAGE  0x0010
+#define wxTREE_MASK_CHILDREN        0x0020
+#define wxTREE_MASK_DATA            0x0040
+
+#define wxTREE_STATE_BOLD           0x0001
+#define wxTREE_STATE_DROPHILITED    0x0002
+#define wxTREE_STATE_EXPANDED       0x0004
+#define wxTREE_STATE_EXPANDEDONCE   0x0008
+#define wxTREE_STATE_FOCUSED        0x0010
+#define wxTREE_STATE_SELECTED       0x0020
+#define wxTREE_STATE_CUT            0x0040
+
+#define wxTREE_HITTEST_ABOVE            0x0001  // Above the client area.
+#define wxTREE_HITTEST_BELOW            0x0002  // Below the client area.
+#define wxTREE_HITTEST_NOWHERE          0x0004  // In the client area but below the last item.
+#define wxTREE_HITTEST_ONITEMBUTTON     0x0010  // On the button associated with an item.
+#define wxTREE_HITTEST_ONITEMICON       0x0020  // On the bitmap associated with an item.
+#define wxTREE_HITTEST_ONITEMINDENT     0x0040  // In the indentation associated with an item.
+#define wxTREE_HITTEST_ONITEMLABEL      0x0080  // On the label (string) associated with an item.
+#define wxTREE_HITTEST_ONITEMRIGHT      0x0100  // In the area to the right of an item.
+#define wxTREE_HITTEST_ONITEMSTATEICON  0x0200  // On the state icon for a tree view item that is in a user-defined state.
+#define wxTREE_HITTEST_TOLEFT           0x0400  // To the right of the client area.
+#define wxTREE_HITTEST_TORIGHT          0x0800  // To the left of the client area.
+
+#define wxTREE_HITTEST_ONITEM (wxTREE_HITTEST_ONITEMICON | wxTREE_HITTEST_ONITEMLABEL wxTREE_HITTEST_ONITEMSTATEICON)
+
+// Flags for GetNextItem
+enum {
+    wxTREE_NEXT_CARET,                 // Retrieves the currently selected item.
+    wxTREE_NEXT_CHILD,                 // Retrieves the first child item. The hItem parameter must be NULL.
+    wxTREE_NEXT_DROPHILITE,            // Retrieves the item that is the target of a drag-and-drop operation.
+    wxTREE_NEXT_FIRSTVISIBLE,          // Retrieves the first visible item.
+    wxTREE_NEXT_NEXT,                  // Retrieves the next sibling item.
+    wxTREE_NEXT_NEXTVISIBLE,           // Retrieves the next visible item that follows the specified item.
+    wxTREE_NEXT_PARENT,                // Retrieves the parent of the specified item.
+    wxTREE_NEXT_PREVIOUS,              // Retrieves the previous sibling item.
+    wxTREE_NEXT_PREVIOUSVISIBLE,       // Retrieves the first visible item that precedes the specified item.
+    wxTREE_NEXT_ROOT                   // Retrieves the first child item of the root item of which the specified item is a part.
+};
+
+// Flags for ExpandItem
+enum {
+    wxTREE_EXPAND_EXPAND,
+    wxTREE_EXPAND_COLLAPSE,
+    wxTREE_EXPAND_COLLAPSE_RESET,
+    wxTREE_EXPAND_TOGGLE
+};
+
+// Flags for InsertItem
+enum {
+    wxTREE_INSERT_LAST = -1,
+    wxTREE_INSERT_FIRST = -2,
+    wxTREE_INSERT_SORT = -3
+};
+
+/* defined in "wx/event.h"
+ wxEVT_COMMAND_TREE_BEGIN_DRAG,
+ wxEVT_COMMAND_TREE_BEGIN_RDRAG,
+ wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT,
+ wxEVT_COMMAND_TREE_END_LABEL_EDIT,
+ wxEVT_COMMAND_TREE_DELETE_ITEM,
+ wxEVT_COMMAND_TREE_GET_INFO,
+ wxEVT_COMMAND_TREE_SET_INFO,
+ wxEVT_COMMAND_TREE_ITEM_EXPANDED,
+ wxEVT_COMMAND_TREE_ITEM_EXPANDING,
+ wxEVT_COMMAND_TREE_SEL_CHANGED,
+ wxEVT_COMMAND_TREE_SEL_CHANGING,
+ wxEVT_COMMAND_TREE_KEY_DOWN
+*/
+
+//-----------------------------------------------------------------------------
+// wxTreeItem
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxTreeItem: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxTreeItem)
+  
+  public:
+    long            m_mask;
+    long            m_itemId;
+    long            m_state;
+    long            m_stateMask;
+    wxString        m_text;
+    int             m_image;
+    int             m_selectedImage;
+    int             m_children;
+    long            m_data;
+
+    wxTreeItem(void);
+};
+
+//-----------------------------------------------------------------------------
+// wxTreeEvent
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxTreeEvent: public wxCommandEvent
+{
+  DECLARE_DYNAMIC_CLASS(wxTreeEvent)
+
+ public:
+  wxTreeEvent(WXTYPE commandType = 0, int id = 0);
+
+  int           m_code;
+  wxTreeItem    m_item;
+  long          m_oldItem;
+  wxPoint       m_pointDrag;
+};
+
+typedef void (wxEvtHandler::*wxTreeEventFunction)(wxTreeEvent&);
+
+#define EVT_TREE_BEGIN_DRAG(id, fn) { wxEVT_COMMAND_TREE_BEGIN_DRAG, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn },
+#define EVT_TREE_BEGIN_RDRAG(id, fn) { wxEVT_COMMAND_TREE_BEGIN_RDRAG, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn },
+#define EVT_TREE_BEGIN_LABEL_EDIT(id, fn) { wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn },
+#define EVT_TREE_END_LABEL_EDIT(id, fn) { wxEVT_COMMAND_TREE_END_LABEL_EDIT, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn },
+#define EVT_TREE_DELETE_ITEM(id, fn) { wxEVT_COMMAND_TREE_DELETE_ITEM, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn },
+#define EVT_TREE_GET_INFO(id, fn) { wxEVT_COMMAND_TREE_GET_INFO, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn },
+#define EVT_TREE_SET_INFO(id, fn) { wxEVT_COMMAND_TREE_SET_INFO, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn },
+#define EVT_TREE_ITEM_EXPANDED(id, fn) { wxEVT_COMMAND_TREE_ITEM_EXPANDED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn },
+#define EVT_TREE_ITEM_EXPANDING(id, fn) { wxEVT_COMMAND_TREE_ITEM_EXPANDING, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn },
+#define EVT_TREE_SEL_CHANGED(id, fn) { wxEVT_COMMAND_TREE_SEL_CHANGED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn },
+#define EVT_TREE_SEL_CHANGING(id, fn) { wxEVT_COMMAND_TREE_SEL_CHANGING, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn },
+#define EVT_TREE_KEY_DOWN(id, fn) { wxEVT_COMMAND_TREE_KEY_DOWN, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) & fn },
+
+//-----------------------------------------------------------------------------
+// wxGenericTreeItem
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxGenericTreeItem: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxGenericTreeItem)
+  
+  public:
+
+    long                m_itemId;
+    long                m_state;
+    wxString            m_text;
+    int                 m_image;
+    int                 m_selectedImage;
+//    int               m_children;
+    bool                m_hasChildren;
+    long                m_data;
+
+    int                 m_x,m_y;
+    int                 m_height,m_width;
+    int                 m_xCross,m_yCross;
+    int                 m_level;
+    wxList              m_children;
+    wxGenericTreeItem  *m_parent;
+    bool                m_hasHilight;
+    
+    wxGenericTreeItem(void) {};
+    wxGenericTreeItem( wxGenericTreeItem *parent );
+    wxGenericTreeItem( wxGenericTreeItem *parent, const wxTreeItem& item, wxDC *dc );
+    void SetItem( const wxTreeItem &item, wxDC *dc );
+    void SetText( const wxString &text, wxDC *dc );
+    void Reset(void);
+    void GetItem( wxTreeItem &item ) const;
+    void AddChild( const wxTreeItem &item );
+    bool HasChildren(void);
+    bool HasPlus(void);
+    int NumberOfVisibleDescendents(void);
+    int NumberOfVisibleChildren(void);
+    wxGenericTreeItem *FindItem( long itemId ) const;
+    void AddChild( wxGenericTreeItem *child );
+    void SetCross( int x, int y );
+    void GetSize( int &x, int &y );
+    long HitTest( const wxPoint& point, int &flags );
+    void PrepareEvent( wxTreeEvent &event );
+    void SendKeyDown( wxWindow *target );
+    void SendSelected( wxWindow *target );
+    void SendDelete( wxWindow *target );
+    void SendExpand( wxWindow *target );
+    void SetHilight( bool set = TRUE );
+    bool HasHilight(void);
+};
+
+//-----------------------------------------------------------------------------
+// wxTreeCtrl
+//-----------------------------------------------------------------------------
+
+class wxTreeCtrl: public wxScrolledWindow
+{
+  DECLARE_DYNAMIC_CLASS(wxTreeCtrl)
+  
+   public:
+     
+    wxTreeCtrl(void);
+    wxTreeCtrl(wxWindow *parent, const wxWindowID id = -1,
+            const wxPoint& pos = wxDefaultPosition,
+            const wxSize& size = wxDefaultSize,
+            const long style = wxTR_HAS_BUTTONS,
+            const wxString& name = "wxTreeCtrl" );
+    ~wxTreeCtrl(void);
+    bool Create(wxWindow *parent, const wxWindowID id = -1,
+            const wxPoint& pos = wxDefaultPosition,
+            const wxSize& size = wxDefaultSize,
+            const long style = wxTR_HAS_BUTTONS,
+            const wxString& name = "wxTreeCtrl");
+
+    int GetCount(void) const;
+    long InsertItem( const long parent, const wxString& label, const int image = -1,
+      const int selImage = -1, const long insertAfter = wxTREE_INSERT_LAST );
+    long InsertItem( const long parent, wxTreeItem &info, const long insertAfter = wxTREE_INSERT_LAST );
+    bool DeleteAllItems(void);
+    bool ExpandItem( const long item, const int action );
+    bool GetItem( wxTreeItem &info ) const;
+    long GetItemData( const long item ) const;
+    wxString GetItemText( const long item ) const;
+    long GetParent( const long item ) const;
+    long GetRootItem(void) const;
+    long GetSelection(void) const;
+    bool SelectItem( const long item ) const;
+    bool ItemHasChildren( const long item ) const;
+    void SetIndent( const int indent );
+    int GetIndent(void) const;
+    bool SetItem( wxTreeItem &info );
+    bool SetItemData( const long item, const long data );
+    bool SetItemText( const long item, const wxString &text );
+    long HitTest( const wxPoint& point, int &flags );
+
+    void AdjustMyScrollbars(void);
+    void PaintLevel( wxGenericTreeItem *item, wxPaintDC &dc, int level, int &y );
+    void OnPaint( const wxPaintEvent &event );
+    void OnSetFocus( const wxFocusEvent &event );
+    void OnKillFocus( const wxFocusEvent &event );
+    void OnChar( wxKeyEvent &event );
+    void OnMouse( const wxMouseEvent &event );
+        
+  private:
+  
+    wxGenericTreeItem   *m_anchor;
+    wxGenericTreeItem   *m_current;
+    bool                 m_hasFocus;
+    int                  m_xScroll,m_yScroll;
+    int                  m_indent;
+    long                 m_lastId;
+    int                  m_lineHeight;
+    wxPen                m_dottedPen;
+    bool                 m_isCreated;
+    wxPaintDC           *m_dc;
+    wxBrush            *m_hilightBrush;
+  
+    void CalculateLevel( wxGenericTreeItem *item, wxPaintDC &dc, int level, int &y );
+    void CalculatePositions(void);
+    wxGenericTreeItem *FindItem( const long itemId ) const;
+    void RefreshLine( wxGenericTreeItem *item );
+    
+  DECLARE_EVENT_TABLE()
+};
+
+#endif
+    // __GTKTREECTRLH_G__
diff --git a/include/wx/grid.h b/include/wx/grid.h
new file mode 100644
index 0000000000..6d55e0889b
--- /dev/null
+++ b/include/wx/grid.h
@@ -0,0 +1,11 @@
+#ifndef __GRIDH_BASE__
+#define __GRIDH_BASE__
+
+#include "wx/generic/gridg.h"
+
+#ifndef wxGrid
+#define wxGrid wxGenericGrid
+#endif
+
+#endif
+    // __GRIDH_BASE__
diff --git a/include/wx/gtk/app.h b/include/wx/gtk/app.h
new file mode 100644
index 0000000000..11af9c4903
--- /dev/null
+++ b/include/wx/gtk/app.h
@@ -0,0 +1,113 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        app.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __GTKAPPH__
+#define __GTKAPPH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/window.h"
+#include "wx/frame.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxApp;
+class wxLog;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern wxApp *wxTheApp;
+
+//-----------------------------------------------------------------------------
+// global functions
+//-----------------------------------------------------------------------------
+
+void wxExit(void);
+bool wxYield(void);
+
+//-----------------------------------------------------------------------------
+// constants
+//-----------------------------------------------------------------------------
+
+#define wxPRINT_WINDOWS         1
+#define wxPRINT_POSTSCRIPT      2
+
+//-----------------------------------------------------------------------------
+// wxApp
+//-----------------------------------------------------------------------------
+
+class wxApp: public wxEvtHandler
+{
+  DECLARE_DYNAMIC_CLASS(wxApp)
+
+  public:
+  
+    wxApp(void);
+    ~wxApp(void);
+    
+    static void SetInitializerFunction(wxAppInitializerFunction fn) { m_appInitFn = fn; }
+    static wxAppInitializerFunction GetInitializerFunction(void) { return m_appInitFn; }
+    virtual bool OnInit(void);
+    virtual bool OnInitGui(void);
+    virtual int OnRun(void);
+    virtual bool OnIdle(void);
+    virtual int OnExit(void);
+    
+    wxWindow *GetTopWindow(void);
+    void SetTopWindow( wxWindow *win );
+    virtual int MainLoop(void);
+    void ExitMainLoop(void);
+    bool Initialized(void);
+    virtual bool Pending(void);
+    virtual void Dispatch(void);
+    void DeletePendingObjects(void);
+    
+    inline wxString GetAppName(void) const {
+      if (m_appName != "")
+        return m_appName;
+      else return m_className;
+    }
+    inline void SetAppName(const wxString& name) { m_appName = name; };
+    inline wxString GetClassName(void) const { return m_className; }
+    inline void SetClassName(const wxString& name) { m_className = name; }
+
+    inline void SetExitOnFrameDelete(bool flag) { m_exitOnFrameDelete = flag; }
+    inline bool GetExitOnFrameDelete(void) const { return m_exitOnFrameDelete; }
+  
+    void SetPrintMode(int WXUNUSED(mode) ) {}; 
+    int GetPrintMode(void) const { return wxPRINT_POSTSCRIPT; };
+  
+    static void CommonInit(void);
+    static void CommonCleanUp(void);    
+    
+    // override this function to create default log target of arbitrary
+    // user-defined classv (default implementation creates a wxLogGui object)
+    virtual wxLog *CreateLogTarget();
+    
+    bool          m_initialized;
+    bool          m_exitOnFrameDelete;
+    gint          m_idleTag;
+    wxWindow     *m_topWindow;
+    wxString      m_appName;
+    wxString      m_className;
+    
+    int         argc;
+    char      **argv;
+    
+    static wxAppInitializerFunction m_appInitFn;
+};
+
+#endif // __GTKAPPH__
diff --git a/include/wx/gtk/bitmap.h b/include/wx/gtk/bitmap.h
new file mode 100644
index 0000000000..1d6260c5fc
--- /dev/null
+++ b/include/wx/gtk/bitmap.h
@@ -0,0 +1,118 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        bitmap.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKBITMAPH__
+#define __GTKBITMAPH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/string.h"
+#include "wx/palette.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxDC;
+class wxPaintDC;
+class wxMemoryDC;
+class wxToolBarGTK;
+
+class wxMask;
+class wxBitmap;
+
+//-----------------------------------------------------------------------------
+// wxMask
+//-----------------------------------------------------------------------------
+
+class wxMask: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxMask)
+
+  public:
+  
+    wxMask(void);
+    wxMask( const wxBitmap& bitmap, const wxColour& colour );
+    wxMask( const wxBitmap& bitmap, const int paletteIndex );
+    wxMask( const wxBitmap& bitmap );
+    ~wxMask(void);
+
+  private:
+  
+    friend wxBitmap;
+    friend wxDC;
+    friend wxPaintDC;
+    friend wxToolBarGTK;
+    
+    GdkBitmap *GetBitmap(void) const;
+    
+  protected:
+  
+    GdkBitmap *m_bitmap;     
+    
+};
+
+//-----------------------------------------------------------------------------
+// wxBitmap
+//-----------------------------------------------------------------------------
+
+class wxBitmap: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxBitmap)
+
+  public:
+
+    wxBitmap(void);
+    wxBitmap( const int width, const int height, const int depth = -1 );
+    wxBitmap( char **bits );
+    wxBitmap( const wxBitmap& bmp );
+    wxBitmap( const wxBitmap* bmp );
+    wxBitmap( const wxString &filename, const int type );
+    ~wxBitmap(void);
+    wxBitmap& operator = ( const wxBitmap& bmp );
+    bool operator == ( const wxBitmap& bmp );
+    bool operator != ( const wxBitmap& bmp );
+    bool Ok(void) const;
+    
+    int GetHeight(void) const;
+    int GetWidth(void) const;
+    int GetDepth(void) const;
+    void SetHeight( const int height );
+    void SetWidth( const int width );
+    void SetDepth( const int depth );
+
+    wxMask *GetMask(void) const;
+    void SetMask( wxMask *mask );
+    
+    bool SaveFile( const wxString &name, const int type, wxPalette *palette = NULL );
+    bool LoadFile( const wxString &name, const int type );
+        
+    wxPalette *GetPalette(void) const;
+    wxPalette *GetColourMap(void) const
+      { return GetPalette(); };
+
+  private:
+  
+    friend wxDC;
+    friend wxPaintDC;
+    friend wxMemoryDC;
+    friend wxToolBarGTK;
+
+    GdkPixmap *GetPixmap(void) const;
+    
+    // no data :-)
+};
+
+#endif // __GTKBITMAPH__
diff --git a/include/wx/gtk/bmpbuttn.h b/include/wx/gtk/bmpbuttn.h
new file mode 100644
index 0000000000..c8dbaba78d
--- /dev/null
+++ b/include/wx/gtk/bmpbuttn.h
@@ -0,0 +1,34 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        bmpbutton.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __BMPBUTTONH__
+#define __BMPBUTTONH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxBitmapButton;
+
+//-----------------------------------------------------------------------------
+// wxBitmapButton
+//-----------------------------------------------------------------------------
+
+#endif // __BMPBUTTONH__
diff --git a/include/wx/gtk/brush.h b/include/wx/gtk/brush.h
new file mode 100644
index 0000000000..3cac78adc7
--- /dev/null
+++ b/include/wx/gtk/brush.h
@@ -0,0 +1,60 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        brush.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKBRUSHH__
+#define __GTKBRUSHH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/string.h"
+#include "wx/gdiobj.h"
+#include "wx/bitmap.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxBrush;
+
+//-----------------------------------------------------------------------------
+// wxBrush
+//-----------------------------------------------------------------------------
+
+class wxBrush: public wxGDIObject
+{
+  DECLARE_DYNAMIC_CLASS(wxBrush)
+
+  public:
+
+    wxBrush(void);
+    wxBrush( const wxColour &colour, const int style );
+    wxBrush( const wxString &colourName, const int style );
+    wxBrush( const wxBitmap &stippleBitmap );
+    wxBrush( const wxBrush &brush );
+    wxBrush( const wxBrush *brush );
+    ~wxBrush(void);
+    wxBrush& operator = ( const wxBrush& brush );
+    bool operator == ( const wxBrush& brush );
+    bool operator != ( const wxBrush& brush );
+    bool Ok(void) const;
+
+    int GetStyle(void) const;
+    wxColour &GetColour(void) const;
+    wxBitmap *GetStipple(void) const;
+    
+    // no data :-)
+};
+
+#endif // __GTKBRUSHH__
diff --git a/include/wx/gtk/button.h b/include/wx/gtk/button.h
new file mode 100644
index 0000000000..b0e2220c0e
--- /dev/null
+++ b/include/wx/gtk/button.h
@@ -0,0 +1,58 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        button.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKBUTTONH__
+#define __GTKBUTTONH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxButton;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxButtonNameStr;
+
+//-----------------------------------------------------------------------------
+// wxButton
+//-----------------------------------------------------------------------------
+
+class wxButton: public wxControl
+{
+  DECLARE_DYNAMIC_CLASS(wxButton)
+
+  public:
+
+    wxButton(void);
+    wxButton( wxWindow *parent, wxWindowID id, const wxString &label,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = wxButtonNameStr  );
+    bool Create(  wxWindow *parent, wxWindowID id, const wxString &label,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = wxButtonNameStr  );
+    void SetDefault(void);
+    void SetLabel( const wxString &label );
+    wxString GetLabel(void) const;
+};
+
+#endif // __GTKBUTTONH__
diff --git a/include/wx/gtk/checkbox.h b/include/wx/gtk/checkbox.h
new file mode 100644
index 0000000000..0f95924e1b
--- /dev/null
+++ b/include/wx/gtk/checkbox.h
@@ -0,0 +1,57 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        checkbox.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKCHECKBOXH__
+#define __GTKCHECKBOXH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxCheckBox;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxCheckBoxNameStr;
+
+//-----------------------------------------------------------------------------
+// wxCheckBox
+//-----------------------------------------------------------------------------
+
+class wxCheckBox: public wxControl
+{
+  DECLARE_DYNAMIC_CLASS(wxCheckBox)
+
+  public:
+
+    wxCheckBox(void);
+    wxCheckBox( wxWindow *parent, wxWindowID id, const wxString &label,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = wxCheckBoxNameStr  );
+    bool Create(  wxWindow *parent, wxWindowID id, const wxString &label,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = wxCheckBoxNameStr  );
+    void SetValue( const bool state );
+    bool GetValue(void) const;
+};
+
+#endif // __GTKCHECKBOXH__
diff --git a/include/wx/gtk/choice.h b/include/wx/gtk/choice.h
new file mode 100644
index 0000000000..b3feb2c065
--- /dev/null
+++ b/include/wx/gtk/choice.h
@@ -0,0 +1,68 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        choice.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKCHOICEH__
+#define __GTKCHOICEH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxChoice;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxChoiceNameStr;
+
+//-----------------------------------------------------------------------------
+// wxChoice
+//-----------------------------------------------------------------------------
+
+class wxChoice: public wxControl
+{
+  DECLARE_DYNAMIC_CLASS(wxChoice)
+
+  public:
+
+    wxChoice(void);
+    wxChoice( wxWindow *parent, const wxWindowID id,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const int n = 0, const wxString choices[] = NULL,
+      const long style = 0, const wxString &name = wxChoiceNameStr );
+    bool Create( wxWindow *parent, const wxWindowID id,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const int n = 0, const wxString choices[] = NULL,
+      const long style = 0, const wxString &name = wxChoiceNameStr );
+    void Append( const wxString &item );
+    void Clear(void);
+    int FindString( const wxString &string ) const;
+    int GetColumns(void) const;
+    int GetSelection(void);
+    wxString GetString( const int n ) const;
+    wxString GetStringSelection(void) const;
+    int Number(void) const;
+    void SetColumns( const int n = 1 );
+    void SetSelection( const int n );
+    void SetStringSelection( const wxString &string );
+};
+
+#endif // __GTKCHOICEH__
diff --git a/include/wx/gtk/colour.h b/include/wx/gtk/colour.h
new file mode 100644
index 0000000000..8757d2c00b
--- /dev/null
+++ b/include/wx/gtk/colour.h
@@ -0,0 +1,76 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        colour.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKCOLOURH__
+#define __GTKCOLOURH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/string.h"
+#include "wx/gdiobj.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxDC;
+class wxPaintDC;
+class wxBitmap;
+class wxWindow;
+
+class wxColour;
+
+//-----------------------------------------------------------------------------
+// wxColour
+//-----------------------------------------------------------------------------
+
+class wxColour: public wxGDIObject
+{
+  DECLARE_DYNAMIC_CLASS(wxColour)
+
+  public:
+
+    wxColour(void);
+    wxColour( char red, char green, char blue );
+    wxColour( const wxString &colourName );
+    wxColour( const wxColour& col );
+    wxColour( const wxColour* col );
+    ~wxColour(void);
+    wxColour& operator = ( const wxColour& col );
+    wxColour& operator = ( const wxString& colourName );
+    bool operator == ( const wxColour& col );
+    bool operator != ( const wxColour& col );
+    void Set( const unsigned char red, const unsigned char green, const unsigned char blue );
+    unsigned char Red(void) const;
+    unsigned char Green(void) const;
+    unsigned char Blue(void) const;
+    bool Ok(void) const;
+
+  private:
+  public:
+  
+    friend wxDC;
+    friend wxPaintDC;
+    friend wxBitmap;
+    friend wxWindow;
+        
+    void CalcPixel( GdkColormap *cmap );
+    int GetPixel(void);
+    GdkColor *GetColor(void);
+    
+    // no data :-)
+};
+  
+#endif // __GTKCOLOURH__
diff --git a/include/wx/gtk/combobox.h b/include/wx/gtk/combobox.h
new file mode 100644
index 0000000000..355d087281
--- /dev/null
+++ b/include/wx/gtk/combobox.h
@@ -0,0 +1,34 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        combobox.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKCOMBOBOXH__
+#define __GTKCOMBOBOXH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxComboBox;
+
+//-----------------------------------------------------------------------------
+// wxComboBox
+//-----------------------------------------------------------------------------
+
+#endif // __GTKCOMBOBOXH__
diff --git a/include/wx/gtk/control.h b/include/wx/gtk/control.h
new file mode 100644
index 0000000000..ad8ea7abea
--- /dev/null
+++ b/include/wx/gtk/control.h
@@ -0,0 +1,51 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        control.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKCONTROLH__
+#define __GTKCONTROLH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/window.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxControl;
+
+//-----------------------------------------------------------------------------
+// wxControl
+//-----------------------------------------------------------------------------
+
+class wxControl: public wxWindow
+{
+  DECLARE_DYNAMIC_CLASS(wxControl)
+
+  public:
+
+    wxControl(void);
+    wxControl( wxWindow *parent, wxWindowID id, 
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = wxPanelNameStr  );
+    virtual void Command( wxCommandEvent &event );
+    virtual void SetLabel( const wxString &label );
+    virtual wxString GetLabel(void) const;
+    
+    wxString   m_label;
+};
+
+#endif // __GTKCONTROLH__
diff --git a/include/wx/gtk/cursor.h b/include/wx/gtk/cursor.h
new file mode 100644
index 0000000000..a6fcb40b17
--- /dev/null
+++ b/include/wx/gtk/cursor.h
@@ -0,0 +1,61 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        cursor.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKCURSORH__
+#define __GTKCURSORH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/gdicmn.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxWindow;
+
+class wxCursor;
+
+//-----------------------------------------------------------------------------
+// wxCursor
+//-----------------------------------------------------------------------------
+
+class wxCursor: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxCursor)
+
+  public:
+
+    wxCursor(void);
+    wxCursor( const int cursorId );
+    wxCursor( const wxCursor &cursor );
+    wxCursor( const wxCursor *cursor );
+    ~wxCursor(void);
+    wxCursor& operator = ( const wxCursor& cursor );
+    bool operator == ( const wxCursor& cursor );
+    bool operator != ( const wxCursor& cursor );
+    bool Ok(void) const;
+    
+  private:
+  public:
+  
+    friend wxWindow;
+  
+    GdkCursor *GetCursor(void) const;
+
+    // no data :-)
+};
+
+#endif // __GTKCURSORH__
diff --git a/include/wx/gtk/dc.h b/include/wx/gtk/dc.h
new file mode 100644
index 0000000000..9abb2793df
--- /dev/null
+++ b/include/wx/gtk/dc.h
@@ -0,0 +1,306 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        dc.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKDCH__
+#define __GTKDCH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/gdicmn.h"
+#include "wx/pen.h"
+#include "wx/brush.h"
+#include "wx/icon.h"
+#include "wx/font.h"
+#include "wx/gdicmn.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxDC;
+
+//-----------------------------------------------------------------------------
+// constants
+//-----------------------------------------------------------------------------
+
+#define MM_TEXT			0
+#define MM_ISOTROPIC		1
+#define MM_ANISOTROPIC		2
+#define MM_LOMETRIC		3
+#define MM_HIMETRIC		4
+#define MM_TWIPS		5
+#define MM_POINTS		6
+#define MM_METRIC		7
+
+//-----------------------------------------------------------------------------
+// global variables
+//-----------------------------------------------------------------------------
+
+extern int wxPageNumber;
+
+//-----------------------------------------------------------------------------
+// wxDC
+//-----------------------------------------------------------------------------
+
+class wxDC: public wxObject
+{
+  DECLARE_ABSTRACT_CLASS(wxDC)
+
+  public:
+
+    wxDC(void);
+    ~wxDC(void);
+    
+    void BeginDrawing(void) {};
+    void EndDrawing(void) {};
+    
+    virtual bool Ok(void) const { return m_ok; };
+
+    virtual void FloodFill( long x1, long y1, wxColour *col, int style=wxFLOOD_SURFACE ) = 0;
+    virtual bool GetPixel( long x1, long y1, wxColour *col ) const = 0;
+
+    virtual void DrawLine( long x1, long y1, long x2, long y2 ) = 0;
+    virtual void CrossHair( long x, long y ) = 0;
+    virtual void DrawArc( long x1, long y1, long x2, long y2, double xc, double yc );
+    virtual void DrawEllipticArc( long x, long y, long width, long height, double sa, double ea ) = 0;
+    virtual void DrawPoint( long x, long y ) = 0;
+    virtual void DrawPoint( wxPoint& point );
+    
+    virtual void DrawLines( int n, wxPoint points[], long xoffset = 0, long yoffset = 0 ) = 0;
+    virtual void DrawLines( wxList *points, long xoffset = 0, long yoffset = 0 );
+    virtual void DrawPolygon( int n, wxPoint points[], long xoffset = 0, long yoffset = 0, 
+                              int fillStyle=wxODDEVEN_RULE ) = 0;
+    virtual void DrawPolygon( wxList *lines, long xoffset = 0, long yoffset = 0, 
+                              int fillStyle=wxODDEVEN_RULE );
+    
+    virtual void DrawRectangle( long x, long y, long width, long height ) = 0;
+    virtual void DrawRoundedRectangle( long x, long y, long width, long height, double radius = 20.0 ) = 0;
+    virtual void DrawEllipse( long x, long y, long width, long height ) = 0;
+    
+    virtual void DrawSpline( long x1, long y1, long x2, long y2, long x3, long y3 );
+    virtual void DrawSpline( wxList *points );
+    virtual void DrawSpline( int n, wxPoint points[] );
+    
+    virtual bool CanDrawBitmap(void) const = 0;
+    virtual void DrawIcon( const wxIcon &icon, long x, long y, bool useMask=FALSE );
+            void DrawBitmap( const wxBitmap &bmp, long x, long y, bool useMask=FALSE )
+	    { DrawIcon( *((wxIcon*)(&bmp)), x, y, useMask ); }
+    virtual bool Blit( long xdest, long ydest, long width, long height,
+       wxDC *source, long xsrc, long ysrc, int logical_func = wxCOPY, bool useMask=FALSE ) = 0;
+
+    virtual void DrawText( const wxString &text, long x, long y, bool use16 = FALSE ) = 0;
+    virtual bool CanGetTextExtent(void) const = 0;
+    virtual void GetTextExtent( const wxString &string, long *width, long *height,
+                     long *descent = NULL, long *externalLeading = NULL,
+                     wxFont *theFont = NULL, bool use16 = FALSE ) = 0;
+    virtual long GetCharWidth(void) = 0;
+    virtual long GetCharHeight(void) = 0;
+    
+    virtual void Clear(void) = 0;
+            
+    virtual void SetFont( const wxFont &font ) = 0;
+    virtual wxFont *GetFont(void) { return &m_font; };
+    
+    virtual void SetPen( const wxPen &pen ) = 0;
+    virtual wxPen *GetPen(void) { return &m_pen; };
+    
+    virtual void SetBrush( const wxBrush &brush ) = 0;
+    virtual wxBrush *GetBrush(void) { return &m_brush; };
+
+    virtual void SetLogicalFunction( int function ) = 0;
+    virtual int GetLogicalFunction(void) { return m_logicalFunction; };
+    
+    virtual void SetTextForeground( const wxColour &col );
+    virtual void SetTextBackground( const wxColour &col );
+    virtual wxColour& GetTextBackground(void) const { return (wxColour&)m_textBackgroundColour; };
+    virtual wxColour& GetTextForeground(void) const { return (wxColour&)m_textForegroundColour; };
+    
+    virtual void SetBackgroundMode( int mode ) = 0;
+    virtual int GetBackgroundMode(void) { return m_backgroundMode; };
+    
+    virtual void SetPalette( const wxPalette& palette ) = 0;
+      void SetColourMap( const wxPalette& palette ) { SetPalette(palette); };
+    
+    // the first two must be overridden and called
+    virtual void SetClippingRegion( long x, long y, long width, long height );
+    virtual void DestroyClippingRegion(void);
+    virtual void GetClippingBox( long *x, long *y, long *width, long *height ) const;
+    
+    virtual inline long MinX(void) const { return m_minX; }
+    virtual inline long MaxX(void) const { return m_maxX; }
+    virtual inline long MinY(void) const { return m_minY; }
+    virtual inline long MaxY(void) const { return m_maxY; }
+
+    virtual void GetSize( int* width, int* height ) const;
+    inline wxSize GetSize(void) const { int w, h; GetSize(&w, &h); return wxSize(w, h); }
+    virtual void GetSizeMM( long* width, long* height ) const;
+    
+    virtual bool StartDoc( const wxString& WXUNUSED(message) ) { return TRUE; };
+    virtual void EndDoc(void) {};
+    virtual void StartPage(void) {};
+    virtual void EndPage(void) {};
+    
+    virtual void SetMapMode( int mode );
+    virtual int GetMapMode(void) const { return m_mappingMode; };
+    
+    virtual void SetUserScale( double x, double y );
+    virtual void GetUserScale( double *x, double *y );
+    virtual void SetLogicalScale( double x, double y );
+    virtual void GetLogicalScale( double *x, double *y );
+    
+    virtual void SetLogicalOrigin( long x, long y );
+    virtual void GetLogicalOrigin( long *x, long *y );
+    virtual void SetDeviceOrigin( long x, long y );
+    virtual void GetDeviceOrigin( long *x, long *y );
+    virtual void SetInternalDeviceOrigin( long x, long y );
+    virtual void GetInternalDeviceOrigin( long *x, long *y );
+
+    virtual void SetAxisOrientation( bool xLeftRight, bool yBottomUp );
+    
+    virtual void SetOptimization( bool WXUNUSED(optimize) ) {};
+    virtual bool GetOptimization(void) { return m_optimize; };
+    
+    virtual long DeviceToLogicalX(long x) const;
+    virtual long DeviceToLogicalY(long y) const;
+    virtual long DeviceToLogicalXRel(long x) const;
+    virtual long DeviceToLogicalYRel(long y) const;
+    virtual long LogicalToDeviceX(long x) const;
+    virtual long LogicalToDeviceY(long y) const;
+    virtual long LogicalToDeviceXRel(long x) const;
+    virtual long LogicalToDeviceYRel(long y) const;
+
+  public:
+  
+    void CalcBoundingBox( long x, long y );
+    void ComputeScaleAndOrigin(void);
+    
+    long XDEV2LOG(long x) const
+	{
+	  long new_x = x - m_deviceOriginX;
+	  if (new_x > 0) 
+	    return (long)((double)(new_x) / m_scaleX + 0.5) * m_signX + m_logicalOriginX;
+	  else
+	    return (long)((double)(new_x) / m_scaleX - 0.5) * m_signX + m_logicalOriginX;
+	}
+    long XDEV2LOGREL(long x) const
+	{ 
+	  if (x > 0) 
+	    return (long)((double)(x) / m_scaleX + 0.5);
+	  else
+	    return (long)((double)(x) / m_scaleX - 0.5);
+	}
+    long YDEV2LOG(long y) const
+	{
+	  long new_y = y - m_deviceOriginY;
+	  if (new_y > 0)
+	    return (long)((double)(new_y) / m_scaleY + 0.5) * m_signY + m_logicalOriginY;
+	  else
+	    return (long)((double)(new_y) / m_scaleY - 0.5) * m_signY + m_logicalOriginY;
+	}
+    long YDEV2LOGREL(long y) const
+	{ 
+	  if (y > 0)
+	    return (long)((double)(y) / m_scaleY + 0.5);
+	  else
+	    return (long)((double)(y) / m_scaleY - 0.5);
+	}
+    long XLOG2DEV(long x) const
+	{ 
+	  long new_x = x - m_logicalOriginX;
+	  if (new_x > 0)
+	    return (long)((double)(new_x) * m_scaleX + 0.5) * m_signX + m_deviceOriginX;
+	  else
+	    return (long)((double)(new_x) * m_scaleX - 0.5) * m_signX + m_deviceOriginX;
+	}
+    long XLOG2DEVREL(long x) const
+	{ 
+	  if (x > 0)
+	    return (long)((double)(x) * m_scaleX + 0.5);
+	  else
+	    return (long)((double)(x) * m_scaleX - 0.5);
+	}
+    long YLOG2DEV(long y) const
+	{
+	  long new_y = y - m_logicalOriginY;
+	  if (new_y > 0)
+	    return (long)((double)(new_y) * m_scaleY + 0.5) * m_signY + m_deviceOriginY;
+	  else
+	    return (long)((double)(new_y) * m_scaleY - 0.5) * m_signY + m_deviceOriginY;
+	}
+    long YLOG2DEVREL(long y) const
+	{ 
+	  if (y > 0)
+	    return (long)((double)(y) * m_scaleY + 0.5);
+	  else
+	    return (long)((double)(y) * m_scaleY - 0.5);
+	}
+  
+    virtual void DrawOpenSpline( wxList *points ) = 0;
+	
+  public:
+    
+    bool         m_ok;
+    bool         m_colour;
+    
+    // not sure, what these mean
+    bool         m_clipping;      // Is clipping on right now ?
+    bool         m_isInteractive; // Is GetPixel possible ?
+    bool         m_autoSetting;   // wxMSW only ?
+    bool         m_dontDelete;    // wxMSW only ?
+    bool         m_optimize;      // wxMSW only ?
+    wxString     m_filename;      // Not sure where this belongs.
+    
+    wxPen        m_pen;
+    wxBrush      m_brush;
+    wxBrush      m_backgroundBrush;
+    wxColour     m_textForegroundColour;
+    wxColour     m_textBackgroundColour;
+    wxFont       m_font;
+    
+    int          m_logicalFunction;
+    int          m_backgroundMode;
+    int          m_textAlignment;    // gone in wxWin 2.0 ?
+    
+    int          m_mappingMode;
+    
+    // not sure what for, but what is a mm on a screen you don't know the size of?
+    double       m_mm_to_pix_x,m_mm_to_pix_y; 
+    
+    long         m_internalDeviceOriginX,m_internalDeviceOriginY;   // If un-scrolled is non-zero or
+								    // d.o. changes with scrolling.
+								    // Set using SetInternalDeviceOrigin().
+								    
+    long         m_externalDeviceOriginX,m_externalDeviceOriginY;   // To be set by external classes
+                                                                    // such as wxScrolledWindow
+								    // using SetDeviceOrigin()
+								    
+    long         m_deviceOriginX,m_deviceOriginY;                   // Sum of the two above.
+    
+    long         m_logicalOriginX,m_logicalOriginY;                 // User defined.
+
+    double       m_scaleX,m_scaleY;
+    double       m_logicalScaleX,m_logicalScaleY;
+    double       m_userScaleX,m_userScaleY;
+    long         m_signX,m_signY;
+    
+    bool         m_needComputeScaleX,m_needComputeScaleY;         // not yet used
+    
+    float        m_scaleFactor;  // wxPSDC wants to have this. Will disappear.
+    
+    long         m_clipX1,m_clipY1,m_clipX2,m_clipY2;
+    long         m_minX,m_maxX,m_minY,m_maxY;
+};
+
+#endif // __GTKDCH__
diff --git a/include/wx/gtk/dcclient.h b/include/wx/gtk/dcclient.h
new file mode 100644
index 0000000000..7ae3e3099c
--- /dev/null
+++ b/include/wx/gtk/dcclient.h
@@ -0,0 +1,107 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        dcclient.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKDCCLIENTH__
+#define __GTKDCCLIENTH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/dc.h"
+#include "wx/window.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxPaintDC;
+typedef wxPaintDC wxClientDC;
+typedef wxPaintDC wxWindowDC;
+
+//-----------------------------------------------------------------------------
+// wxPaintDC
+//-----------------------------------------------------------------------------
+
+class wxPaintDC: public wxDC
+{
+  DECLARE_DYNAMIC_CLASS(wxPaintDC)
+
+  public:
+
+    wxPaintDC(void);
+    wxPaintDC( wxWindow *win );
+    
+    ~wxPaintDC(void);
+    
+    virtual void FloodFill( long x1, long y1, wxColour *col, int style=wxFLOOD_SURFACE );
+    virtual bool GetPixel( long x1, long y1, wxColour *col ) const;
+
+    virtual void DrawLine( long x1, long y1, long x2, long y2 );
+    virtual void CrossHair( long x, long y );
+    virtual void DrawArc( long x1, long y1, long x2, long y2, double xc, double yc );
+    virtual void DrawEllipticArc( long x, long y, long width, long height, double sa, double ea );
+    virtual void DrawPoint( long x, long y );
+    
+    virtual void DrawLines( int n, wxPoint points[], long xoffset = 0, long yoffset = 0 );
+    virtual void DrawLines( wxList *points, long xoffset = 0, long yoffset = 0 );
+    virtual void DrawPolygon( int n, wxPoint points[], long xoffset = 0, long yoffset = 0, 
+                              int fillStyle=wxODDEVEN_RULE );
+    virtual void DrawPolygon( wxList *lines, long xoffset = 0, long yoffset = 0, 
+                              int fillStyle=wxODDEVEN_RULE );
+    
+    virtual void DrawRectangle( long x, long y, long width, long height );
+    virtual void DrawRoundedRectangle( long x, long y, long width, long height, double radius = 20.0 );
+    virtual void DrawEllipse( long x, long y, long width, long height );
+    
+    virtual bool CanDrawBitmap(void) const;
+    virtual void DrawIcon( const wxIcon &icon, long x, long y, bool useMask=FALSE );
+    virtual bool Blit( long xdest, long ydest, long width, long height,
+       wxDC *source, long xsrc, long ysrc, int logical_func = wxCOPY, bool useMask=FALSE );
+
+    virtual void DrawText( const wxString &text, long x, long y, bool use16 = FALSE );
+    virtual bool CanGetTextExtent(void) const;
+    virtual void GetTextExtent( const wxString &string, long *width, long *height,
+                     long *descent = NULL, long *externalLeading = NULL,
+                     wxFont *theFont = NULL, bool use16 = FALSE );
+    virtual long GetCharWidth(void);
+    virtual long GetCharHeight(void);
+    
+    virtual void Clear(void);
+            
+    virtual void SetFont( const wxFont &font );
+    virtual void SetPen( const wxPen &pen );
+    virtual void SetBrush( const wxBrush &brush );
+    virtual void SetLogicalFunction( int function );
+    virtual void SetTextForeground( const wxColour &col );
+    virtual void SetTextBackground( const wxColour &col );
+    virtual void SetBackgroundMode( int mode );
+    virtual void SetPalette( const wxPalette& palette );
+    
+    virtual void SetClippingRegion( long x, long y, long width, long height );
+    virtual void DestroyClippingRegion(void);
+    
+    virtual void DrawOpenSpline( wxList *points );
+    
+  public: // shouldn't be public
+    
+    GdkWindow    *m_window;
+    GdkGC        *m_penGC;
+    GdkGC        *m_brushGC;
+    GdkGC        *m_textGC;
+    GdkGC        *m_bgGC;
+    GdkColormap  *m_cmap;
+    
+    void SetUpDC(void);
+    GdkWindow *GetWindow(void);
+};
+
+#endif // __GTKDCCLIENTH__
diff --git a/include/wx/gtk/dcmemory.h b/include/wx/gtk/dcmemory.h
new file mode 100644
index 0000000000..66cf85bfc0
--- /dev/null
+++ b/include/wx/gtk/dcmemory.h
@@ -0,0 +1,49 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        dcmemory.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKDCMEMORYH__
+#define __GTKDCMEMORYH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/dcclient.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxMemoryDC;
+
+//-----------------------------------------------------------------------------
+// wxMemoryDC
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxMemoryDC: public wxPaintDC
+{
+  DECLARE_DYNAMIC_CLASS(wxMemoryDC)
+
+  public:
+    wxMemoryDC(void);
+    wxMemoryDC( wxDC *dc ); // Create compatible DC
+    ~wxMemoryDC(void);
+    virtual void SelectObject( const wxBitmap& bitmap );
+    void GetSize( int *width, int *height );
+
+  private: 
+    wxBitmap  m_selected;
+};
+
+#endif
+    // __GTKDCMEMORYH__
+
diff --git a/include/wx/gtk/dcscreen.h b/include/wx/gtk/dcscreen.h
new file mode 100644
index 0000000000..5cb1991fe9
--- /dev/null
+++ b/include/wx/gtk/dcscreen.h
@@ -0,0 +1,32 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        dcscreen.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKDCSCREENH__
+#define __GTKDCSCREENH__
+
+#include "wx/dcclient.h"
+
+class WXDLLEXPORT wxScreenDC: public wxPaintDC
+{
+  DECLARE_DYNAMIC_CLASS(wxScreenDC)
+
+ public:
+  wxScreenDC(void);
+  ~wxScreenDC(void);
+
+  static bool StartDrawingOnTop( wxWindow *window );
+  static bool StartDrawingOnTop( wxRectangle *rect = NULL );
+  static bool EndDrawingOnTop(void);
+};
+
+#endif
+    // __GTKDCSCREENH__
+
diff --git a/include/wx/gtk/dialog.h b/include/wx/gtk/dialog.h
new file mode 100644
index 0000000000..6c9c99e2a1
--- /dev/null
+++ b/include/wx/gtk/dialog.h
@@ -0,0 +1,95 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        dialog.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKDIALOGH__
+#define __GTKDIALOGH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/string.h"
+#include "wx/event.h"
+#include "wx/window.h"
+
+//-----------------------------------------------------------------------------
+// forward decls
+//-----------------------------------------------------------------------------
+
+class wxRadioBox;
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxDialog;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxDialogNameStr;
+
+//-----------------------------------------------------------------------------
+// wxDialog
+//-----------------------------------------------------------------------------
+
+class wxDialog: public wxWindow
+{
+  DECLARE_DYNAMIC_CLASS(wxDialog)
+
+  public:
+
+    wxDialog(void);
+    wxDialog( wxWindow *parent, wxWindowID id, const wxString &title,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = wxDEFAULT_DIALOG_STYLE, const wxString &name = wxDialogNameStr );
+    bool Create( wxWindow *parent, wxWindowID id, const wxString &title,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = wxDEFAULT_DIALOG_STYLE, const wxString &name = wxDialogNameStr );
+    ~wxDialog(void);
+    void SetTitle(const wxString& title);
+    wxString GetTitle(void) const;
+    bool OnClose(void);
+    void OnApply( wxCommandEvent &event );
+    void OnCancel( wxCommandEvent &event );
+    void OnOk( wxCommandEvent &event );
+    void OnPaint(wxPaintEvent& event);
+    void OnCloseWindow(wxCloseEvent& event);
+/*
+    void OnCharHook(wxKeyEvent& event);
+*/
+    virtual bool Show( const bool show );
+    virtual int ShowModal(void);
+    virtual void EndModal(int retCode);
+    virtual bool IsModal(void) const { return ((GetWindowStyleFlag() & wxDIALOG_MODAL) == wxDIALOG_MODAL); }
+    virtual void InitDialog(void);
+/*
+    void OnOK(wxCommandEvent& event);
+    void OnApply(wxCommandEvent& event);
+    void OnCancel(wxCommandEvent& event);
+*/
+    
+  private:
+  
+    friend    wxWindow;
+    friend    wxDC;
+    friend    wxRadioBox;
+    bool       m_modalShowing;
+    wxString   m_title;
+    
+  DECLARE_EVENT_TABLE()
+    
+};
+
+#endif // __GTKDIALOGH__
diff --git a/include/wx/gtk/dirdlg.h b/include/wx/gtk/dirdlg.h
new file mode 100644
index 0000000000..7d8829f55b
--- /dev/null
+++ b/include/wx/gtk/dirdlg.h
@@ -0,0 +1,35 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        dirdlg.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __DIRDIALOGH__
+#define __DIRDIALOGH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+#include "wx/dialog.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxDirDialog;
+
+//-----------------------------------------------------------------------------
+// wxDirDialog
+//-----------------------------------------------------------------------------
+
+#endif // __DIRDIALOGH__
diff --git a/include/wx/gtk/dnd.h b/include/wx/gtk/dnd.h
new file mode 100644
index 0000000000..45bf0cf2f6
--- /dev/null
+++ b/include/wx/gtk/dnd.h
@@ -0,0 +1,116 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        dnd.h
+// Purpose:     declaration of the wxDropTarget class
+// Author:      Robert Roebling
+// RCS-ID:      
+// Copyright:   (c) 1998 Vadim Zeitlin, Robert Roebling
+// Licence:     wxWindows license
+///////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKDNDH__
+#define __GTKDNDH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/string.h"
+#include "wx/cursor.h"
+
+//-------------------------------------------------------------------------
+// classes
+//-------------------------------------------------------------------------
+
+class wxWindow;
+
+class wxDropTarget;
+class wxTextDropTarget;
+class wxDragSource;
+class wxTextDragSource;
+
+//-------------------------------------------------------------------------
+// wxDropTarget
+//-------------------------------------------------------------------------
+
+class wxDropTarget: wxObject
+{
+  public:
+
+    wxDropTarget();
+    ~wxDropTarget();
+    virtual void OnEnter() { }
+    virtual void OnLeave() { }
+    virtual bool OnDrop( long x, long y, const void *pData ) = 0;
+
+  public:
+
+    void Drop( GdkEvent *event, int x, int y );
+    virtual void RegisterWidget( GtkWidget *widget ) = 0;
+    void UnregisterWidget( GtkWidget *widget );
+};
+
+//-------------------------------------------------------------------------
+// wxTextDropTarget
+//-------------------------------------------------------------------------
+
+class wxTextDropTarget: public wxDropTarget
+{
+  public:
+
+    wxTextDropTarget() {};
+    virtual bool OnDrop( long x, long y, const void *pData );
+    virtual bool OnDropText( long x, long y, const char *psz );
+    virtual void RegisterWidget( GtkWidget *widget );
+};
+
+//-------------------------------------------------------------------------
+// wxDragSource
+//-------------------------------------------------------------------------
+
+class wxDragSource: public wxObject
+{
+  public:
+
+    wxDragSource( wxWindow *win );
+    ~wxDragSource(void);
+    void SetData( char *data, const long size );
+    void Start( int x, int y );
+
+  public:
+
+    void ConnectWindow(void);
+    void UnconnectWindow(void);
+    virtual void RegisterWindow(void) = 0;
+    void UnregisterWindow(void);
+  
+    GtkWidget   *m_widget;
+    wxWindow    *m_window;
+    char        *m_data;
+    long         m_size;
+    wxCursor     m_defaultCursor;
+    wxCursor     m_goaheadCursor;
+};
+
+//-------------------------------------------------------------------------
+// wxTextDragSource
+//-------------------------------------------------------------------------
+
+class wxTextDragSource: public wxDragSource
+{
+  public:
+
+    wxTextDragSource( wxWindow *win ) : wxDragSource(win) {};
+    void SetTextData( const wxString &text );
+    void RegisterWindow(void);
+    
+  private:
+  
+    wxString m_tmp;
+};
+
+#endif  
+       //__GTKDNDH__
+
diff --git a/include/wx/gtk/filedlg.h b/include/wx/gtk/filedlg.h
new file mode 100644
index 0000000000..665debbe74
--- /dev/null
+++ b/include/wx/gtk/filedlg.h
@@ -0,0 +1,93 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        filedlg.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKFILEDLGH__
+#define __GTKFILEDLGH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/dialog.h"
+
+//-------------------------------------------------------------------------
+// File selector
+//-------------------------------------------------------------------------
+
+extern const char *wxFileSelectorPromptStr;
+extern const char *wxFileSelectorDefaultWildcardStr;
+
+class wxFileDialog: public wxDialog
+{
+
+  DECLARE_DYNAMIC_CLASS(wxFileDialog)
+  
+  public:
+
+    wxFileDialog() {};
+    
+    wxFileDialog(wxWindow *parent, const wxString& message = wxFileSelectorPromptStr,
+        const wxString& defaultDir = "", const wxString& defaultFile = "", 
+	const wxString& wildCard = wxFileSelectorDefaultWildcardStr,
+        long style = 0, const wxPoint& pos = wxDefaultPosition);
+
+    inline void SetMessage(const wxString& message) { m_message = message; }
+    inline void SetPath(const wxString& path) { m_path = path; }
+    inline void SetDirectory(const wxString& dir) { m_dir = dir; }
+    inline void SetFilename(const wxString& name) { m_fileName = name; }
+    inline void SetWildcard(const wxString& wildCard) { m_wildCard = wildCard; }
+    inline void SetStyle(long style) { m_dialogStyle = style; }
+    inline void SetFilterIndex(int filterIndex) { m_filterIndex = filterIndex; }
+
+    inline wxString GetMessage(void) const { return m_message; }
+    inline wxString GetPath(void) const { return m_path; }
+    inline wxString GetDirectory(void) const { return m_dir; }
+    inline wxString GetFilename(void) const { return m_fileName; }
+    inline wxString GetWildcard(void) const { return m_wildCard; }
+    inline long GetStyle(void) const { return m_dialogStyle; }
+    inline int GetFilterIndex(void) const { return m_filterIndex ; }
+
+    int ShowModal(void);
+    
+  protected:
+  
+    wxString    m_message;
+    long        m_dialogStyle;
+    wxWindow *  m_parent;
+    wxString    m_dir;
+    wxString    m_path; // Full path
+    wxString    m_fileName;
+    wxString    m_wildCard;
+    int         m_filterIndex;
+};
+
+#define wxOPEN 1
+#define wxSAVE 2
+#define wxOVERWRITE_PROMPT 4
+#define wxHIDE_READONLY 8
+
+// File selector - backward compatibility
+
+char* wxFileSelector(const char *message = wxFileSelectorPromptStr, const char *default_path = NULL,
+         const char *default_filename = NULL, const char *default_extension = NULL,
+         const char *wildcard = wxFileSelectorDefaultWildcardStr, int flags = 0,
+         wxWindow *parent = NULL, int x = -1, int y = -1);
+
+char* wxLoadFileSelector(const char *what, const char *extension, const char *default_name = NULL, 
+         wxWindow *parent = NULL);
+
+char* wxSaveFileSelector(const char *what, const char *extension, const char *default_name = NULL, 
+         wxWindow *parent = NULL);
+
+
+
+#endif
+    // __GTKFILEDLGH__
diff --git a/include/wx/gtk/font.h b/include/wx/gtk/font.h
new file mode 100644
index 0000000000..619813b17e
--- /dev/null
+++ b/include/wx/gtk/font.h
@@ -0,0 +1,120 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        font.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKFONTH__
+#define __GTKFONTH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/string.h"
+#include "wx/hash.h"
+#include "wx/gdiobj.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxDC;
+class wxPaintDC;
+class wxWindow;
+
+class wxFont;
+class wxFontNameDirectory;
+
+//-----------------------------------------------------------------------------
+// global variables
+//-----------------------------------------------------------------------------
+
+// extern wxFontNameDirectory wxTheFontNameDirectory;  // defined below
+
+//-----------------------------------------------------------------------------
+// wxFont
+//-----------------------------------------------------------------------------
+
+class wxFont: public wxGDIObject 
+{
+  DECLARE_DYNAMIC_CLASS(wxFont)
+  
+  public:
+    wxFont(void);
+    wxFont( int PointSize, int FontIdOrFamily, int Style, int Weight,
+	   bool underlined = FALSE, const char *Face=NULL );
+    wxFont( int PointSize, const char *Face, int Family, int Style, int Weight, 
+	   bool underlined = FALSE );
+    wxFont( const wxFont& font );
+    wxFont( const wxFont* font );
+    ~wxFont(void);
+    wxFont& operator = ( const wxFont& font );
+    bool operator == ( const wxFont& font );
+    bool operator != ( const wxFont& font );
+    bool Ok();
+
+    int GetPointSize(void) const;
+    wxString GetFaceName(void) const;
+    int GetFamily(void) const;
+    wxString GetFamilyString(void) const;
+    int GetFontId(void) const;
+    wxString GetFaceString(void) const;
+    int GetStyle(void) const;
+    wxString GetStyleString(void) const;
+    int GetWeight(void) const;
+    wxString GetWeightString(void) const;
+    bool GetUnderlined(void) const;
+
+    wxFont( char *xFontName );
+    
+  private:
+  
+    friend wxDC;
+    friend wxPaintDC;
+    friend wxWindow;
+    
+    GdkFont* GetInternalFont(float scale = 1.0);
+
+    // no data :-)
+};
+
+//-----------------------------------------------------------------------------
+// wxFontDirectory
+//-----------------------------------------------------------------------------
+
+class wxFontNameDirectory: public wxObject 
+{
+  DECLARE_DYNAMIC_CLASS(wxFontNameDirectory)
+  
+  public:
+    wxFontNameDirectory(void);
+    ~wxFontNameDirectory();
+
+    void  Initialize(void);
+    void  Initialize(int fontid, int family, const char *name);
+
+    int   FindOrCreateFontId(const char *name, int family);
+    char* GetAFMName(int fontid, int weight, int style);
+    int   GetFamily(int fontid);
+    int   GetFontId(const char *name);
+    char* GetFontName(int fontid);
+    int   GetNewFontId(void);
+    char* GetPostScriptName(int fontid, int weight, int style);
+    char* GetScreenName(int fontid, int weight, int style);
+    
+    
+    class wxHashTable *table;
+    int   nextFontId;
+};
+
+extern wxFontNameDirectory wxTheFontNameDirectory;
+
+#endif // __GTKFONTH__
diff --git a/include/wx/gtk/frame.h b/include/wx/gtk/frame.h
new file mode 100644
index 0000000000..aacd0b4274
--- /dev/null
+++ b/include/wx/gtk/frame.h
@@ -0,0 +1,90 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        frame.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKFRAMEH__
+#define __GTKFRAMEH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/window.h"
+#include "wx/menu.h"
+#include "wx/statusbr.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxRadioBox;
+
+class wxFrame;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxFrameNameStr;
+
+//-----------------------------------------------------------------------------
+// wxFrame
+//-----------------------------------------------------------------------------
+
+class wxFrame: public wxWindow
+{
+  DECLARE_DYNAMIC_CLASS(wxFrame)
+
+  public:
+  
+    wxFrame(void);
+    wxFrame( wxWindow *parent, const wxWindowID id, const wxString &title, 
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = wxDEFAULT_FRAME_STYLE, const wxString &name = wxFrameNameStr );
+    bool Create( wxWindow *parent, const wxWindowID id, const wxString &title,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = wxDEFAULT_FRAME_STYLE, const wxString &name = wxFrameNameStr );
+    ~wxFrame(void);
+    bool Destroy(void);
+    void OnCloseWindow( wxCloseEvent& event );
+    virtual bool Show( const bool show );
+    virtual void Enable( const bool enable );
+    virtual void GetClientSize( int *width, int *height ) const;
+    void OnSize( wxSizeEvent &event );
+    void SetMenuBar( wxMenuBar *menuBar );
+    virtual bool CreateStatusBar( const int number = 1 );
+    virtual void SetStatusText( const wxString &text, const int number = 0 );
+    virtual void SetStatusWidths( const int n, const int *width );
+    wxStatusBar *GetStatusBar(void);
+    wxMenuBar *GetMenuBar(void);
+    void SetTitle( const wxString &title );
+    wxString GetTitle(void) const;
+    void OnActivate( wxActivateEvent &WXUNUSED(event) ) {};
+    
+    void GtkOnSize( int width, int height );
+    
+  private:
+  
+    friend        wxWindow;
+    
+    GtkWidget    *m_mainWindow;
+    wxMenuBar    *m_frameMenuBar;
+    wxStatusBar  *m_frameStatusBar;
+    bool          m_doingOnSize;
+    wxString      m_title;
+    
+    
+  DECLARE_EVENT_TABLE()
+    
+};
+
+#endif // __GTKFRAMEH__
diff --git a/include/wx/gtk/gauge.h b/include/wx/gtk/gauge.h
new file mode 100644
index 0000000000..49e031fea2
--- /dev/null
+++ b/include/wx/gtk/gauge.h
@@ -0,0 +1,34 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        gauge.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKGAUGEH__
+#define __GTKGAUGEH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxGauge;
+
+//-----------------------------------------------------------------------------
+// wxGaugeBox
+//-----------------------------------------------------------------------------
+
+#endif // __GTKGAUGEH__
diff --git a/include/wx/gtk/gdiobj.h b/include/wx/gtk/gdiobj.h
new file mode 100644
index 0000000000..2b6a5d1921
--- /dev/null
+++ b/include/wx/gtk/gdiobj.h
@@ -0,0 +1,37 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        gdiobj.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GDIOBJH__
+#define __GDIOBJH__
+
+#include "wx/object.h"
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+class WXDLLEXPORT wxGDIObject: public wxObject
+{
+DECLARE_DYNAMIC_CLASS(wxGDIObject)
+ public:
+  inline wxGDIObject(void) { m_visible = FALSE; };
+  inline ~wxGDIObject(void) {};
+
+  virtual bool GetVisible(void) { return m_visible; }
+  virtual void SetVisible(bool v) { m_visible = v; }
+
+protected:
+  bool m_visible; // Can a pointer to this object be safely taken?
+                 // - only if created within FindOrCreate...
+};
+
+#endif
+    // __GDIOBJH__
diff --git a/include/wx/gtk/icon.h b/include/wx/gtk/icon.h
new file mode 100644
index 0000000000..edb7ab07fe
--- /dev/null
+++ b/include/wx/gtk/icon.h
@@ -0,0 +1,53 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        icon.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKICONH__
+#define __GTKICONH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/bitmap.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxIcon;
+
+//-----------------------------------------------------------------------------
+// wxIcon
+//-----------------------------------------------------------------------------
+
+class wxIcon: public wxBitmap
+{
+  DECLARE_DYNAMIC_CLASS(wxIcon)
+
+public:
+
+  wxIcon(void) {};
+
+  inline wxIcon(const wxIcon& icon) { Ref(icon); }
+  inline wxIcon(const wxIcon* icon) { if (icon) Ref(*icon); }
+
+  wxIcon( char **bits, const int WXUNUSED(width), const int WXUNUSED(height) ) :
+    wxBitmap( bits ) {};
+    
+  inline wxIcon& operator = (const wxIcon& icon) { if (*this == icon) return (*this); Ref(icon); return *this; }
+  inline bool operator == (const wxIcon& icon) { return m_refData == icon.m_refData; }
+  inline bool operator != (const wxIcon& icon) { return m_refData != icon.m_refData; }
+};
+
+
+#endif // __GTKICONH__
diff --git a/include/wx/gtk/listbox.h b/include/wx/gtk/listbox.h
new file mode 100644
index 0000000000..081570556e
--- /dev/null
+++ b/include/wx/gtk/listbox.h
@@ -0,0 +1,85 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        listbox.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKLISTBOXH__
+#define __GTKLISTBOXH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxListBox;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxListBoxNameStr;
+
+//-----------------------------------------------------------------------------
+// wxListBox
+//-----------------------------------------------------------------------------
+
+class wxListBox: public wxControl
+{
+  DECLARE_DYNAMIC_CLASS(wxListBox)
+
+  public:
+
+    wxListBox(void);
+    wxListBox( wxWindow *parent, wxWindowID id, 
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const int n = 0, const wxString choices[] = NULL,
+      const long style = 0, const wxString &name = wxListBoxNameStr );
+    bool Create( wxWindow *parent, wxWindowID id, 
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const int n = 0, const wxString choices[] = NULL,
+      const long style = 0, const wxString &name = wxListBoxNameStr );
+    void Append( const wxString &item );
+    void Append( const wxString &item, char *clientData );
+    void Clear(void);
+    void Delete( int n );
+    void Deselect( int n );
+    int FindString( const wxString &item ) const;
+    char *GetClientData( const int n ) const;
+    int GetSelection(void) const;
+    int GetSelections( int **selections ) const;
+    wxString GetString( int n ) const;
+    wxString GetStringSelection(void) const;
+    int Number(void);
+    bool Selected( const int n );
+    void Set( const int n, const wxString *choices );
+    void SetClientData( const int n, char *clientData );
+    void SetFirstItem( int n );
+    void SetFirstItem( const wxString &item );
+    void SetSelection( const int n, const bool select = TRUE );
+    void SetString( const int n, const wxString &string );
+    void SetStringSelection( const wxString &string, const bool select = TRUE );
+    
+  private:
+  
+    GtkList   *m_list;
+    
+  public:
+  
+    int GetIndex( GtkWidget *item ) const;
+};
+
+#endif // __GTKLISTBOXH__
diff --git a/include/wx/gtk/mdi.h b/include/wx/gtk/mdi.h
new file mode 100644
index 0000000000..ff9181d771
--- /dev/null
+++ b/include/wx/gtk/mdi.h
@@ -0,0 +1,146 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        mdi.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __MDIH__
+#define __MDIH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+#include "wx/panel.h"
+#include "wx/frame.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxMDIParentFrame;
+class wxMDIClientWindow;
+class wxMDIChildFrame;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char* wxFrameNameStr;
+extern const char* wxStatusLineNameStr;
+
+//-----------------------------------------------------------------------------
+// wxMDIParentFrame
+//-----------------------------------------------------------------------------
+
+class wxMDIParentFrame: public wxFrame
+{
+  DECLARE_DYNAMIC_CLASS(wxMDIParentFrame)
+
+  friend class wxMDIChildFrame;
+  
+  public:
+
+    wxMDIParentFrame(void);
+    wxMDIParentFrame( wxWindow *parent,
+      const wxWindowID id, const wxString& title,
+      const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+      const long style = wxDEFAULT_FRAME_STYLE | wxVSCROLL | wxHSCROLL,
+      const wxString& name = wxFrameNameStr );
+  ~wxMDIParentFrame(void);
+   bool Create( wxWindow *parent,
+      const wxWindowID id, const wxString& title,
+      const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+      const long style = wxDEFAULT_FRAME_STYLE | wxVSCROLL | wxHSCROLL,
+      const wxString& name = wxFrameNameStr );
+
+  void OnSize( wxSizeEvent& event );
+  void OnActivate( wxActivateEvent& event );
+
+  void SetMenuBar( wxMenuBar *menu_bar );
+  void GetClientSize(int *width, int *height) const;
+  wxMDIChildFrame *GetActiveChild(void) const;
+  
+  wxMDIClientWindow *GetClientWindow(void) const; 
+  virtual wxMDIClientWindow *OnCreateClient(void);
+  
+  virtual void Cascade(void) {};
+  virtual void Tile(void) {};
+  virtual void ArrangeIcons(void) {};
+  virtual void ActivateNext(void);
+  virtual void ActivatePrevious(void);
+
+  void OnSysColourChanged(wxSysColourChangedEvent& event);
+    
+ protected:
+    wxMDIClientWindow *             m_clientWindow;
+    wxMDIChildFrame *               m_currentChild;
+    bool                            m_parentFrameActive;
+
+//  DECLARE_EVENT_TABLE()    
+};
+
+//-----------------------------------------------------------------------------
+// wxMDIChildFrame
+//-----------------------------------------------------------------------------
+
+class wxMDIChildFrame: public wxPanel
+{
+  DECLARE_DYNAMIC_CLASS(wxMDIChildFrame)
+  
+  public:
+
+    wxMDIChildFrame(void);
+    wxMDIChildFrame( wxMDIParentFrame *parent,
+      const wxWindowID id, const wxString& title,
+      const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+      const long style = wxDEFAULT_FRAME_STYLE, const wxString& name = wxFrameNameStr );
+    ~wxMDIChildFrame(void);
+    bool Create( wxMDIParentFrame *parent,
+      const wxWindowID id, const wxString& title,
+      const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+      const long style = wxDEFAULT_FRAME_STYLE, const wxString& name = wxFrameNameStr );
+    void SetMenuBar( wxMenuBar *menu_bar );
+
+    // no status bars in wxGTK
+    virtual bool CreateStatusBar( const int WXUNUSED(number) = 1 ) { return FALSE; };
+    virtual void SetStatusText( const wxString &WXUNUSED(text), const int WXUNUSED(number) ) {};
+    virtual void SetStatusWidths( const int WXUNUSED(n), const int *WXUNUSED(width) ) {};
+    
+    virtual void Maximize(void) {};
+    virtual void Restore(void) {};
+    virtual void Activate(void);
+    
+  public:
+  
+    wxString    m_title;
+};
+
+//-----------------------------------------------------------------------------
+// wxMDIClientWindow
+//-----------------------------------------------------------------------------
+
+class wxMDIClientWindow: public wxWindow
+{
+  DECLARE_DYNAMIC_CLASS(wxMDIClientWindow)
+  
+  public:
+  
+    wxMDIClientWindow(void);
+    wxMDIClientWindow( wxMDIParentFrame *parent, const long style = 0 );
+    ~wxMDIClientWindow(void);
+    virtual bool CreateClient( wxMDIParentFrame *parent, const long style = wxVSCROLL | wxHSCROLL );
+    void AddChild( wxWindow *child );
+};
+
+#endif // __MDIH__
+
diff --git a/include/wx/gtk/menu.h b/include/wx/gtk/menu.h
new file mode 100644
index 0000000000..7e24c65f6d
--- /dev/null
+++ b/include/wx/gtk/menu.h
@@ -0,0 +1,107 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        menu.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKMENUH__
+#define __GTKMENUH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/window.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxMenuBar;
+class wxMenuItem;
+class wxMenu;
+
+//-----------------------------------------------------------------------------
+// wxMenuBar
+//-----------------------------------------------------------------------------
+
+class wxMenuBar: public wxWindow
+{
+  DECLARE_DYNAMIC_CLASS(wxMenuBar)
+
+  public:
+
+    wxMenuBar(void);
+    void Append( wxMenu *menu, const wxString &title );
+    int FindMenuItem( const wxString &menuString, const wxString &itemString ) const;
+    
+    wxList       m_menus;
+    GtkWidget   *m_menubar;
+};
+
+//-----------------------------------------------------------------------------
+// wxMenu
+//-----------------------------------------------------------------------------
+
+class wxMenuItem: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxMenuItem)
+
+  public:
+  
+    wxMenuItem(void);
+  
+    int           m_id;
+    wxString      m_text;
+    bool          m_isCheckMenu;
+    bool          m_checked;
+    bool          m_isSubMenu;
+    bool          m_isEnabled;
+    wxMenu       *m_subMenu;
+    wxString      m_helpStr;
+    
+    GtkWidget    *m_menuItem;  // GtkMenuItem
+  
+};
+
+class wxMenu: public wxEvtHandler
+{
+  DECLARE_DYNAMIC_CLASS(wxMenu)
+
+  public:
+
+    wxMenu( const wxString &title = "" );
+    void AppendSeparator(void);
+    void Append( const int id, const wxString &item, 
+      const wxString &helpStr = "", const bool checkable = FALSE );
+    void Append( const int id, const wxString &item, 
+      wxMenu *subMenu, const wxString &helpStr = "" );
+    int FindItem( const wxString itemString ) const;
+    void Break(void) {};
+    void Enable( const int id, const bool enable );
+    bool Enabled( const int id ) const;
+    void SetLabel( const int id, const wxString &label );
+      
+  public:
+      
+    int FindMenuIdByMenuItem( GtkWidget *menuItem ) const;
+    void SetInvokingWindow( wxWindow *win );
+    wxWindow *GetInvokingWindow(void);
+
+    wxString    m_title;
+    wxList      m_items;
+    wxWindow   *m_invokingWindow;
+    
+    GtkWidget  *m_menu;  // GtkMenu
+      
+};
+
+#endif // __GTKMENUH__
diff --git a/include/wx/gtk/palette.h b/include/wx/gtk/palette.h
new file mode 100644
index 0000000000..2163e73309
--- /dev/null
+++ b/include/wx/gtk/palette.h
@@ -0,0 +1,60 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        palette.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKPALETTEH__
+#define __GTKPALETTEH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/gdiobj.h"
+#include "wx/gdicmn.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxPalette;
+
+//-----------------------------------------------------------------------------
+// wxPalette
+//-----------------------------------------------------------------------------
+
+class wxPalette: public wxGDIObject
+{
+  DECLARE_DYNAMIC_CLASS(wxPalette)
+
+  public:
+  
+    wxPalette(void);
+    wxPalette( const int n, const unsigned char *red, const unsigned char *green, const unsigned char *blue );
+    wxPalette( const wxPalette& palette );
+    wxPalette( const wxPalette* palette );
+    ~wxPalette(void);
+    wxPalette& operator = ( const wxPalette& palette );
+    bool operator == ( const wxPalette& palette );
+    bool operator != ( const wxPalette& palette );
+    bool Ok(void) const;
+    
+    bool Create( const int n, const unsigned char *red, const unsigned char *green, const unsigned char *blue);
+    int GetPixel( const unsigned char red, const unsigned char green, const unsigned char blue ) const;
+    bool GetRGB( const int pixel, unsigned char *red, unsigned char *green, unsigned char *blue ) const;
+    
+    // no data
+};
+
+#define wxColorMap wxPalette
+#define wxColourMap wxPalette
+
+#endif // __GTKPALETTEH__
diff --git a/include/wx/gtk/pen.h b/include/wx/gtk/pen.h
new file mode 100644
index 0000000000..e3529c6699
--- /dev/null
+++ b/include/wx/gtk/pen.h
@@ -0,0 +1,68 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        pen.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKPENH__
+#define __GTKPENH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/string.h"
+#include "wx/gdiobj.h"
+#include "wx/gdicmn.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxPen;
+
+//-----------------------------------------------------------------------------
+// wxPen
+//-----------------------------------------------------------------------------
+
+class wxPen: public wxGDIObject
+{
+  DECLARE_DYNAMIC_CLASS(wxPen)
+
+  public:
+  
+    wxPen(void);
+    wxPen( const wxColour &colour, int width, int style );
+    wxPen( const wxString &colourName, int width, int style );
+    wxPen( const wxPen& pen );
+    wxPen( const wxPen* pen );
+    ~wxPen(void);
+    wxPen& operator = ( const wxPen& pen );
+    bool operator == ( const wxPen& pen );
+    bool operator != ( const wxPen& pen );
+    
+    void SetColour( const wxColour &colour );
+    void SetColour( const wxString &colourName );
+    void SetColour( const int red, const int green, const int blue );
+    void SetCap( int capStyle );
+    void SetJoin( int joinStyle );
+    void SetStyle( int style );
+    void SetWidth( int width );
+    wxColour &GetColour(void) const;
+    int GetCap(void) const;
+    int GetJoin(void) const;
+    int GetStyle(void) const;
+    int GetWidth(void) const;
+    bool Ok(void) const;
+    
+    // no data :-)
+};
+
+#endif // __GTKPENH__
diff --git a/include/wx/gtk/radiobox.h b/include/wx/gtk/radiobox.h
new file mode 100644
index 0000000000..7282de301c
--- /dev/null
+++ b/include/wx/gtk/radiobox.h
@@ -0,0 +1,84 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        radiobox.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKRADIOBOXH__
+#define __GTKRADIOBOXH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+#include "wx/bitmap.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxRadioBox;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxRadioBoxNameStr;
+
+//-----------------------------------------------------------------------------
+// wxRadioBox
+//-----------------------------------------------------------------------------
+
+class wxRadioBox: public wxControl
+{
+
+  DECLARE_DYNAMIC_CLASS(wxRadioBox)
+  
+  public:
+  
+    wxRadioBox(void);
+    wxRadioBox( wxWindow *parent, const wxWindowID id, const wxString& title,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const int n = 0, const wxString choices[] = NULL,
+      const int majorDim = 0, const long style = wxRA_HORIZONTAL,
+      const wxString &name = wxRadioBoxNameStr );
+    bool Create( wxWindow *parent, const wxWindowID id, const wxString& title,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const int n = 0, const wxString choices[] = NULL,
+      const int majorDim = 0, const long style = wxRA_HORIZONTAL,
+      const wxString &name = wxRadioBoxNameStr );
+    int FindString( const wxString& s) const;
+    void SetSelection( const int n );
+    int GetSelection(void) const;
+    wxString GetString( const int n ) const;
+    wxString GetLabel(void) const;
+    void SetLabel( const wxString& label );
+    void SetLabel( const int item, const wxString& label );
+    void SetLabel( const int item, wxBitmap *bitmap );
+    wxString GetLabel( const int item ) const;
+    bool Show( const bool show );
+    void Enable( const bool enable );
+    void Enable( const int item, const bool enable );
+    void Show( const int item, const bool show );
+    virtual wxString GetStringSelection(void) const;
+    virtual bool SetStringSelection( const wxString& s );
+    virtual int Number(void) const;
+    int GetNumberOfRowsOrCols(void) const;
+    void SetNumberOfRowsOrCols( const int n );
+    
+  private:
+  
+    GtkRadioButton *m_radio;
+    
+};
+
+#endif // __GTKRADIOBOXH__
diff --git a/include/wx/gtk/radiobut.h b/include/wx/gtk/radiobut.h
new file mode 100644
index 0000000000..337264fe5a
--- /dev/null
+++ b/include/wx/gtk/radiobut.h
@@ -0,0 +1,31 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        radiobut.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKRADIOBUTTONH__
+#define __GTKRADIOBUTTONH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxRadioButton;
+
+
+#endif // __GTKRADIOBUTTONH__
diff --git a/include/wx/gtk/region.h b/include/wx/gtk/region.h
new file mode 100644
index 0000000000..282904708a
--- /dev/null
+++ b/include/wx/gtk/region.h
@@ -0,0 +1,99 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        region.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __REGIONH__
+#define __REGIONH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/list.h"
+#include "wx/gdiobj.h"
+#include "wx/gdicmn.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxRegion;
+
+//-----------------------------------------------------------------------------
+// constants
+//-----------------------------------------------------------------------------
+
+enum wxRegionContain 
+{
+  wxOutRegion = 0, wxPartRegion = 1, wxInRegion = 2
+};
+
+// So far, for internal use only
+enum wxRegionOp {
+wxRGN_AND,          // Creates the intersection of the two combined regions.
+wxRGN_COPY,         // Creates a copy of the region identified by hrgnSrc1.
+wxRGN_DIFF,         // Combines the parts of hrgnSrc1 that are not part of hrgnSrc2.
+wxRGN_OR,           // Creates the union of two combined regions.
+wxRGN_XOR           // Creates the union of two combined regions except for any overlapping areas.
+};
+
+//-----------------------------------------------------------------------------
+// wxRegion
+//-----------------------------------------------------------------------------
+
+class wxRegion : public wxGDIObject 
+{
+  DECLARE_DYNAMIC_CLASS(wxRegion);
+  
+  public:
+  
+    wxRegion( long x, long y, long w, long h );
+    wxRegion( const wxPoint& topLeft, const wxPoint& bottomRight );
+    wxRegion( const wxRect& rect );
+    wxRegion(void);
+    ~wxRegion(void);
+
+    inline wxRegion( const wxRegion& r ) 
+      { Ref(r); }
+    inline wxRegion& operator = ( const wxRegion& r )
+      { Ref(r); return (*this); }
+
+    void Clear(void);
+
+    bool Union( long x, long y, long width, long height );
+    bool Union( const wxRect& rect );
+    bool Union( const wxRegion& region );
+
+    bool Intersect( long x, long y, long width, long height );
+    bool Intersect( const wxRect& rect );
+    bool Intersect( const wxRegion& region );
+
+    bool Subtract( long x, long y, long width, long height );
+    bool Subtract( const wxRect& rect );
+    bool Subtract( const wxRegion& region );
+
+    bool Xor( long x, long y, long width, long height );
+    bool Xor( const wxRect& rect );
+    bool Xor( const wxRegion& region );
+
+    void GetBox( long& x, long& y, long&w, long &h ) const;
+    wxRect GetBox(void) const ;
+
+    bool Empty(void) const;
+
+    wxRegionContain Contains( long x, long y ) const;
+    wxRegionContain Contains( long x, long y, long w, long h ) const;
+    
+  public:
+    
+    GdkRegion *GetRegion(void) const;
+};
+
+#endif
+	// __REGIONH__
diff --git a/include/wx/gtk/scrolbar.h b/include/wx/gtk/scrolbar.h
new file mode 100644
index 0000000000..758e3cb18a
--- /dev/null
+++ b/include/wx/gtk/scrolbar.h
@@ -0,0 +1,82 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        scrolbar.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKSCROLLBARH__
+#define __GTKSCROLLBARH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxScrollBar;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxScrollBarNameStr;
+
+//-----------------------------------------------------------------------------
+// wxScrollBar
+//-----------------------------------------------------------------------------
+
+class wxScrollBar: public wxControl
+{
+  DECLARE_DYNAMIC_CLASS(wxScrollBar)
+
+  public:
+  
+    wxScrollBar(void) { m_adjust = NULL; m_oldPos = 0.0; };
+    wxScrollBar(wxWindow *parent, const wxWindowID id,
+           const wxPoint& pos = wxDefaultPosition,
+           const wxSize& size = wxDefaultSize,
+           const long style = wxSB_HORIZONTAL,
+           const wxString& name = wxScrollBarNameStr );
+    ~wxScrollBar(void);
+    bool Create(wxWindow *parent, const wxWindowID id,
+           const wxPoint& pos = wxDefaultPosition,
+           const wxSize& size = wxDefaultSize,
+           const long style = wxSB_HORIZONTAL,
+           const wxString& name = wxScrollBarNameStr);
+    int GetPosition(void) const;
+    int GetThumbSize() const;
+    int GetPageSize() const;
+    int GetRange() const;
+    virtual void SetPosition( const int viewStart );
+    virtual void SetScrollbar( const int position, const int thumbSize, const int range, const int pageSize,
+      const bool refresh = TRUE );
+
+    // Backward compatibility
+    int GetValue(void) const;
+    void SetValue( const int viewStart );
+    void GetValues( int *viewStart, int *viewLength, int *objectLength, int *pageLength) const;
+    int GetViewLength() const;
+    int GetObjectLength() const;
+    void SetPageSize( const int pageLength );
+    void SetObjectLength( const int objectLength );
+    void SetViewLength( const int viewLength );
+      
+  public:
+  
+    GtkAdjustment  *m_adjust;
+    float           m_oldPos;
+};
+
+#endif
+    // __GTKSCROLLBARH__
diff --git a/include/wx/gtk/settings.h b/include/wx/gtk/settings.h
new file mode 100644
index 0000000000..7b801bbb81
--- /dev/null
+++ b/include/wx/gtk/settings.h
@@ -0,0 +1,40 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        settings.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKSETTINGSH__
+#define __GTKSETTINGSH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/gdicmn.h"
+#include "wx/pen.h"
+#include "wx/font.h"
+
+class WXDLLEXPORT wxSystemSettings: public wxObject
+{
+public:
+    inline wxSystemSettings(void) {}
+
+    // Get a system colour
+    static wxColour    GetSystemColour(int index);
+
+    // Get a system font
+    static wxFont      GetSystemFont(int index);
+
+    // Get a system metric, e.g. scrollbar size
+    static int         GetSystemMetric(int index);
+};
+
+#endif
+    // __GTKSETTINGSH__
diff --git a/include/wx/gtk/setup.h b/include/wx/gtk/setup.h
new file mode 100644
index 0000000000..6220819c33
--- /dev/null
+++ b/include/wx/gtk/setup.h
@@ -0,0 +1,534 @@
+/* include/wx/gtk/setup.h.  Generated automatically by configure.  */
+/* wx_setup.h
+   This file is in the public domain.
+
+   Descriptive text for the C preprocessor macros that
+   the distributed Autoconf macros can define.
+   No software package will use all of them; autoheader copies the ones
+   your configure.in uses into your configuration header file templates.
+
+   The entries are in sort -df order: alphabetical, case insensitive,
+   ignoring punctuation (such as underscores).  Although this order
+   can split up related entries, it makes it easier to check whether
+   a given entry is in the file.
+
+   Leave the following blank line there!!  Autoheader needs it.  */
+
+#ifndef __GTKSETUPH__
+#define __GTKSETUPH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+/* define the system to compile */
+#define __GTK__ 1
+#define __UNIX__ 1
+#define __LINUX__ 1
+/* #undef __SGI__ */
+/* #undef __HPUX__ */
+/* #undef __SYSV__ */
+/* #undef __SVR4__ */
+/* #undef __AIX__ */
+/* #undef __SUN__ */
+/* #undef __SOLARIS__ */
+/* #undef __SUNOS__ */
+/* #undef __ALPHA__ */
+/* #undef __OSF__ */
+/* #undef __BSD__ */
+/* #undef __FREEBSD__ */
+/* #undef __VMS__ */
+/* #undef __ULTRIX__ */
+/* #undef __DATA_GENERAL__ */
+
+/*
+ * Use zlib
+ */
+#define USE_ZLIB 1
+/*
+ * Use gdk_imlib
+ */
+#define USE_GDK_IMLIB 1
+/*
+ * Use libpng
+ */
+#define USE_LIBPNG 1
+/*
+ * Use Threads
+ */
+/* #undef USE_THREADS */
+/* #undef USE_THREADS_POSIX */
+/* #undef USE_THREADS_SGI */
+/*
+ * Use storable classes
+ */
+#define USE_STORABLE_CLASSES 1
+/*
+ * Use automatic translation via gettext() in wxTString
+ */
+#define USE_AUTOTRANS 1
+/*
+ * Use font metric files in GetTextExtent for wxPostScriptDC
+ * Use consistent PostScript fonts for AFM and printing (!)
+ */
+#define USE_AFM_FOR_POSTSCRIPT 1
+#define WX_NORMALIZED_PS_FONTS 1
+/*
+ * Use clipboard
+ */
+/* #undef USE_CLIPBOARD */
+/*
+ * Use wxWindows layout constraint system
+ */
+#define USE_CONSTRAINTS 1
+/*
+ * Use the document/view architecture
+ */
+#define USE_DOC_VIEW_ARCHITECTURE 1
+/*
+ * Use enhanced dialog
+ */
+/* #undef USE_ENHANCED_DIALOG */
+/*
+ * Use Form panel item placement
+ */
+/* #undef USE_FORM */
+/*
+ * Use fraction class
+ */
+#define USE_FRACTION 1
+/*
+ * Use gauge item
+ */
+#define USE_GAUGE 1
+/*
+ * Implement a GLCanvas class as an interface to OpenGL, using the GLX
+ * extension to the X11 protocol.  You can use the (free) Mesa library
+ * if you don't have a 'real' OpenGL.
+ */
+#define USE_GLX 0
+/*
+ * Use wxWindows help facility (needs USE_IPC 1)
+ */
+/* #undef USE_HELP */
+/*
+ * Use iostream.h rather than iostream
+ */
+#define USE_IOSTREAMH 1
+/*
+ * Use Interprocess communication
+ */
+#define USE_IPC 1
+/*
+ * Use Metafile and Metafile device context
+ */
+/* #undef USE_METAFILE */
+/*
+ * Use PostScript device context
+ */
+#define USE_POSTSCRIPT 1
+/*
+ * Use the print/preview architecture
+ */
+#define USE_PRINTING_ARCHITECTURE 1
+/*
+ * Use Prolog IO
+ */
+/* #undef USE_PROLOGIO */
+/*
+ * Use Remote Procedure Call (Needs USE_IPC and USE_PROLOGIO)
+ */
+/* #undef USE_RPC */
+/*
+ * Use wxGetResource & wxWriteResource (change .Xdefaults)
+ */
+#define USE_RESOURCES 1
+/*
+ * Use scrollbar item
+ */
+#define USE_SCROLLBAR 1
+/*
+ * Use time and date classes
+ */
+#define USE_TIMEDATE 1
+/*
+ * Use toolbar, use Xt port toolbar (3D look)
+ */
+#define USE_TOOLBAR 1
+#define USE_XT_TOOLBAR 
+/*
+ * Enables old type checking mechanism (wxSubType)
+ */
+/* #undef USE_TYPETREE */
+/*
+ * Use virtual list box item
+ */
+/* #undef USE_VLBOX */
+/*
+ * Use wxWindows resource loading (.wxr-files) (Needs USE_PROLOGIO 1)
+ */
+#define USE_WX_RESOURCES 1
+/*
+ * Use wxGraph
+ */
+/* #undef USE_WXGRAPH */
+/*
+ * Use wxTree
+ */
+
+/********************** DO NOT CHANGE BELOW THIS POINT **********************/
+
+/**************************** DEBUGGING FEATURES ****************************/
+
+/* Compatibility with 1.66 API.
+   Level 0: no backward compatibility, all new features
+   Level 1: wxDC, OnSize (etc.) compatibility, but
+   some new features such as event tables */
+#define WXWIN_COMPATIBILITY  1
+/*
+ * Enables debugging: memory tracing, assert, etc.
+ */
+/* #undef DEBUG */
+/*
+ * Enables debugging version of wxObject::new and wxObject::delete (IF DEBUG)
+ * WARNING: this code may not work with all architectures, especially
+ * if alignment is an issue.
+ */
+/* #undef USE_MEMORY_TRACING */
+/*
+ * Enable debugging version of global memory operators new and delete
+ * Disable it, If this causes problems (e.g. link errors)
+ */
+/* #undef USE_GLOBAL_MEMORY_OPERATORS */
+/*
+ * If WXDEBUG && USE_MEMORY_TRACING && USE_GLOBAL_MEMORY_OPERATORS
+ * used to debug the memory allocation of wxWindows Xt port code
+ */
+#define USE_INTERNAL_MEMORY_TRACING 0
+/*
+ * Matthews garbage collection (used for MrEd?)
+ */
+#define WXGARBAGE_COLLECTION_ON 0
+
+/**************************** COMPILER FEATURES *****************************/
+
+/*
+ * Disable this if your compiler can't cope
+ * with omission of prototype parameters.
+ */
+#define REMOVE_UNUSED_ARG 1
+/*
+ * The const keyword is being introduced more in wxWindows.
+ * You can use this setting to maintain backward compatibility.
+ * If 0:	will use const wherever possible.
+ * If 1:	will use const only where necessary
+ *              for precompiled headers to work.
+ * If 2:	will be totally backward compatible, but precompiled
+ *	headers may not work and program size will be larger.
+ */
+#define CONST_COMPATIBILITY 0
+
+/************************ WINDOWS 3.1 COMPATIBILITY *************************/
+
+/*
+ * Normalize X drawing code to behave exactly as MSW.
+ */
+#define WX_STANDARD_GRAPHICS 0
+
+/******************* other stuff **********************************/
+/*
+ * Support image loading for wxBitmap (wxImage is needed for this)
+ */
+#define USE_IMAGE_LOADING 0
+#define WXIMAGE_INCLUDE "../../utils/image/src/wx_image.h"
+/*
+ * Use splines
+ */
+#define USE_SPLINES 1
+
+/*
+ * USE_DYNAMIC_CLASSES is TRUE for the Xt port
+ */
+#define USE_DYNAMIC_CLASSES 1
+/*
+ * USE_EXTENDED_STATICS is FALSE for the Xt port
+*/
+#define USE_EXTENDED_STATICS 0
+
+/*************************** IMAKEFILE EVALUATIOS ***************************/
+
+#if USE_XPM
+	#define USE_XPM_IN_X 1
+#else
+	#define USE_XPM_IN_X 0
+#endif
+#if USE_IMAGE_LOADING
+	#define USE_IMAGE_LOADING_IN_X 1
+#else
+	#define USE_IMAGE_LOADING_IN_X 0
+#endif
+
+/* here comes the system-specific stuff */
+
+/* acconfig.h
+   This file is in the public domain.
+
+   Descriptive text for the C preprocessor macros that
+   the distributed Autoconf macros can define.
+   No software package will use all of them; autoheader copies the ones
+   your configure.in uses into your configuration header file templates.
+
+   The entries are in sort -df order: alphabetical, case insensitive,
+   ignoring punctuation (such as underscores).  Although this order
+   can split up related entries, it makes it easier to check whether
+   a given entry is in the file. */
+
+/* Define if on AIX 3.
+   System headers sometimes define this.
+   We just want to avoid a redefinition error message.  */
+#ifndef _ALL_SOURCE
+/* #undef _ALL_SOURCE */
+#endif
+
+/* Define if using alloca.c.  */
+/* #undef C_ALLOCA */
+
+/* Define if type char is unsigned and you are not using gcc.  */
+#ifndef __CHAR_UNSIGNED__
+/* #undef __CHAR_UNSIGNED__ */
+#endif
+
+/* Define if the closedir function returns void instead of int.  */
+/* #undef CLOSEDIR_VOID */
+
+/* Define to empty if the keyword does not work.  */
+/* #undef const */
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+   This function is required for alloca.c support on those systems.  */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define for DGUX with <sys/dg_sys_info.h>.  */
+/* #undef DGUX */
+
+/* Define if you have <dirent.h>.  */
+/* #undef DIRENT */
+
+/* Define to the type of elements in the array set by `getgroups'.
+   Usually this is either `int' or `gid_t'.  */
+#define GETGROUPS_T gid_t
+
+/* Define if the `getloadavg' function needs to be run setuid or setgid.  */
+/* #undef GETLOADAVG_PRIVILEGED */
+
+/* Define if the `getpgrp' function takes no argument.  */
+/* #undef GETPGRP_VOID */
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+/* #undef gid_t */
+
+/* Define if you have alloca, as a function or macro.  */
+/* #undef HAVE_ALLOCA */
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix).  */
+/* #undef HAVE_ALLOCA_H */
+
+/* Define if you don't have vprintf but do have _doprnt.  */
+/* #undef HAVE_DOPRNT */
+
+/* Define if your system has its own `getloadavg' function.  */
+/* #undef HAVE_GETLOADAVG */
+
+/* Define if you have the getmntent function.  */
+/* #undef HAVE_GETMNTENT */
+
+/* Define if the `long double' type works.  */
+#define HAVE_LONG_DOUBLE 1
+
+/* Define if you support file names longer than 14 characters.  */
+#define HAVE_LONG_FILE_NAMES 1
+
+/* Define if you have a working `mmap' system call.  */
+/* #undef HAVE_MMAP */
+
+/* Define if system calls automatically restart after interruption
+   by a signal.  */
+/* #undef HAVE_RESTARTABLE_SYSCALLS */
+
+/* Define if your struct stat has st_blksize.  */
+#define HAVE_ST_BLKSIZE 1
+
+/* Define if your struct stat has st_blocks.  */
+#define HAVE_ST_BLOCKS 1
+
+/* Define if you have the strcoll function and it is properly defined.  */
+/* #undef HAVE_STRCOLL */
+
+/* Define if your struct stat has st_rdev.  */
+#define HAVE_ST_RDEV 1
+
+/* Define if you have the strftime function.  */
+/* #undef HAVE_STRFTIME */
+
+/* Define if you have <sys/wait.h> that is POSIX.1 compatible.  */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define if your struct tm has tm_zone.  */
+/* #undef HAVE_TM_ZONE */
+
+/* Define if you don't have tm_zone but do have the external array
+   tzname.  */
+#define HAVE_TZNAME 1
+
+/* Define if you have <unistd.h>.  */
+/* #undef HAVE_UNISTD_H */
+
+/* Define if utime(file, NULL) sets file's timestamp to the present.  */
+/* #undef HAVE_UTIME_NULL */
+
+/* Define if you have <vfork.h>.  */
+/* #undef HAVE_VFORK_H */
+
+/* Define if you have the vprintf function.  */
+/* #undef HAVE_VPRINTF */
+
+/* Define if you have the wait3 system call.  */
+/* #undef HAVE_WAIT3 */
+
+/* Define as __inline if that's what the C compiler calls it.  */
+#ifndef __cplusplus
+/* #undef inline */
+#endif
+
+/* Define if major, minor, and makedev are declared in <mkdev.h>.  */
+/* #undef MAJOR_IN_MKDEV */
+
+/* Define if major, minor, and makedev are declared in <sysmacros.h>.  */
+/* #undef MAJOR_IN_SYSMACROS */
+
+/* Define if on MINIX.  */
+/* #undef _MINIX */
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+/* #undef mode_t */
+
+/* Define if you don't have <dirent.h>, but have <ndir.h>.  */
+/* #undef NDIR */
+
+/* Define if you have <memory.h>, and <string.h> doesn't declare the
+   mem* functions.  */
+/* #undef NEED_MEMORY_H */
+
+/* Define if your struct nlist has an n_un member.  */
+/* #undef NLIST_NAME_UNION */
+
+/* Define if you have <nlist.h>.  */
+/* #undef NLIST_STRUCT */
+
+/* Define if your C compiler doesn't accept -c and -o together.  */
+/* #undef NO_MINUS_C_MINUS_O */
+
+/* Define to `long' if <sys/types.h> doesn't define.  */
+/* #undef off_t */
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+/* #undef pid_t */
+
+/* Define if the system does not provide POSIX.1 features except
+   with this defined.  */
+/* #undef _POSIX_1_SOURCE */
+
+/* Define if you need to in order for stat and other things to work.  */
+/* #undef _POSIX_SOURCE */
+
+/* Define as the return type of signal handlers (int or void).  */
+#define RETSIGTYPE void
+
+/* Define if the setvbuf function takes the buffering type as its second
+   argument and the buffer pointer as the third, as on System V
+   before release 3.  */
+/* #undef SETVBUF_REVERSED */
+
+/* Define SIZESOF for some Objects  */
+#define SIZEOF_INT 4
+#define SIZEOF_INT_P 4
+#define SIZEOF_LONG 4
+
+/* Define to `unsigned' if <sys/types.h> doesn't define.  */
+/* #undef size_t */
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at run-time.
+	STACK_DIRECTION > 0 => grows toward higher addresses
+	STACK_DIRECTION < 0 => grows toward lower addresses
+	STACK_DIRECTION = 0 => direction of growth unknown
+ */
+/* #undef STACK_DIRECTION */
+
+/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly.  */
+/* #undef STAT_MACROS_BROKEN */
+
+/* Define if you have the ANSI C header files.  */
+#define STDC_HEADERS 1
+
+/* Define on System V Release 4.  */
+/* #undef SVR4 */
+
+/* Define on BSD  */
+/* #undef BSD */
+
+/* Define on System V */
+/* #undef SYSV */
+
+/* Define if you don't have <dirent.h>, but have <sys/dir.h>.  */
+/* #undef SYSDIR */
+
+/* Define if you don't have <dirent.h>, but have <sys/ndir.h>.  */
+/* #undef SYSNDIR */
+
+/* Define if `sys_siglist' is declared by <signal.h>.  */
+/* #undef SYS_SIGLIST_DECLARED */
+
+/* Define if you can safely include both <sys/time.h> and <time.h>.  */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define if your <sys/time.h> declares struct tm.  */
+/* #undef TM_IN_SYS_TIME */
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+/* #undef uid_t */
+
+/* Define for Encore UMAX.  */
+/* #undef UMAX */
+
+/* Define for Encore UMAX 4.3 that has <inq_status/cpustats.h>
+   instead of <sys/cpustats.h>.  */
+/* #undef UMAX4_3 */
+
+/* Define if you do not have <strings.h>, index, bzero, etc..  */
+/* #undef USG */
+
+/* Define if the system is System V Release 4 */
+/* #undef SVR4 */
+
+/* Define vfork as fork if vfork does not work.  */
+/* #undef vfork */
+
+/* Define if the closedir function returns void instead of int.  */
+/* #undef VOID_CLOSEDIR */
+
+/* Define if your processor stores words with the most significant
+   byte first (like Motorola and SPARC, unlike Intel and VAX).  */
+/* #undef WORDS_BIGENDIAN */
+
+/* Define if lex declares yytext as a char * by default, not a char[].  */
+#define YYTEXT_POINTER 1
+
+#endif /* __GTKSETUPH__ */
+
+
+/* Leave that blank line there!!  Autoheader needs it.
+   If you're adding to this file, keep in mind:
+   The entries are in sort -df order: alphabetical, case insensitive,
+   ignoring punctuation (such as underscores).  */
diff --git a/include/wx/gtk/slider.h b/include/wx/gtk/slider.h
new file mode 100644
index 0000000000..a983248fed
--- /dev/null
+++ b/include/wx/gtk/slider.h
@@ -0,0 +1,91 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        slider.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKSLIDERH__
+#define __GTKSLIDERH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxSlider;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxSliderNameStr;
+
+//-----------------------------------------------------------------------------
+// wxSlider
+//-----------------------------------------------------------------------------
+
+class wxSlider: public wxControl
+{
+  DECLARE_DYNAMIC_CLASS(wxSlider)
+
+  public:
+    wxSlider(void);
+    wxSlider( wxWindow *parent, const wxWindowID id,
+           const int value, const int minValue, const int maxValue,
+           const wxPoint& pos = wxDefaultPosition,
+           const wxSize& size = wxDefaultSize,
+           const long style = wxSL_HORIZONTAL,
+/*           const wxValidator& validator = wxDefaultValidator, */
+           const wxString& name = wxSliderNameStr);
+   ~wxSlider(void);
+   bool Create(wxWindow *parent, const wxWindowID id,
+           const int value, const int minValue, const int maxValue,
+           const wxPoint& pos = wxDefaultPosition,
+           const wxSize& size = wxDefaultSize,
+           const long style = wxSL_HORIZONTAL,
+/*           const wxValidator& validator = wxDefaultValidator, */
+           const wxString& name = wxSliderNameStr);
+    virtual int GetValue(void) const;
+    virtual void SetValue( const int );
+    void GetSize( int *x, int *y ) const;
+    void SetSize( const int x, const int y, const int width, const int height, const int sizeFlags = wxSIZE_AUTO );
+    void GetPosition( int *x, int *y ) const;
+    void SetRange( const int minValue, const int maxValue );
+    int GetMin(void) const;
+    int GetMax(void) const;
+    void SetTickFreq( const int n, const int pos );
+    int GetTickFreq(void) const;
+    void SetPageSize( const int pageSize );
+    int GetPageSize(void) const;
+    void ClearSel(void);
+    void ClearTicks(void);
+    void SetLineSize( const int lineSize );
+    int GetLineSize(void) const;
+    int GetSelEnd(void) const;
+    int GetSelStart(void) const;
+    void SetSelection( const int minPos, const int maxPos );
+    void SetThumbLength( const int len );
+    int GetThumbLength(void) const;
+    void SetTick( const int tickPos );
+
+  public:
+  
+    GtkAdjustment  *m_adjust;
+    float           m_oldPos;
+    
+};
+
+#endif // __GTKSLIDERH__
diff --git a/include/wx/gtk/statbmp.h b/include/wx/gtk/statbmp.h
new file mode 100644
index 0000000000..d6731e42d6
--- /dev/null
+++ b/include/wx/gtk/statbmp.h
@@ -0,0 +1,34 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        statbmp.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKSTATICBITMAPH__
+#define __GTKSTATICBITMAPH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxStaticBitmap;
+
+//-----------------------------------------------------------------------------
+// wxStaticBitmap
+//-----------------------------------------------------------------------------
+
+#endif // __GTKSTATICBITMAPH__
diff --git a/include/wx/gtk/statbox.h b/include/wx/gtk/statbox.h
new file mode 100644
index 0000000000..a260d4f05e
--- /dev/null
+++ b/include/wx/gtk/statbox.h
@@ -0,0 +1,55 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        stabox.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKSTATICBOXH__
+#define __GTKSTATICBOXH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxStaticBox;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxStaticBoxNameStr;
+
+//-----------------------------------------------------------------------------
+// wxStaticBox
+//-----------------------------------------------------------------------------
+
+class wxStaticBox: public wxControl
+{
+  DECLARE_DYNAMIC_CLASS(wxStaticBox)
+
+  public:
+
+    wxStaticBox(void);
+    wxStaticBox( wxWindow *parent, wxWindowID id, const wxString &label, 
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = wxStaticBoxNameStr  );
+    bool Create( wxWindow *parent, wxWindowID id, const wxString &label, 
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = wxStaticBoxNameStr  );
+};
+
+#endif // __GTKSTATICBOXH__
diff --git a/include/wx/gtk/stattext.h b/include/wx/gtk/stattext.h
new file mode 100644
index 0000000000..12d8d6995e
--- /dev/null
+++ b/include/wx/gtk/stattext.h
@@ -0,0 +1,57 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        stattext.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKSTATICTEXTH__
+#define __GTKSTATICTEXTH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxStaticText;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxStaticTextNameStr;
+
+//-----------------------------------------------------------------------------
+// wxStaticText
+//-----------------------------------------------------------------------------
+
+class wxStaticText: public wxControl
+{
+  DECLARE_DYNAMIC_CLASS(wxStaticText)
+
+  public:
+
+    wxStaticText(void);
+    wxStaticText( wxWindow *parent, wxWindowID id, const wxString &label,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = wxStaticTextNameStr );
+    bool Create(  wxWindow *parent, wxWindowID id, const wxString &label,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = wxStaticTextNameStr );
+    wxString GetLabel(void) const;
+    void SetLabel( const wxString &label );
+};
+
+#endif // __GTKSTATICTEXTH__
diff --git a/include/wx/gtk/tbargtk.h b/include/wx/gtk/tbargtk.h
new file mode 100644
index 0000000000..adb04a56f0
--- /dev/null
+++ b/include/wx/gtk/tbargtk.h
@@ -0,0 +1,139 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        tbargtk.h
+// Purpose:     GTK toolbar
+// Author:      Robert Roebling
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Robert Roebling
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __TBARGTKH__
+#define __TBARGTKH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxToolBarTool;
+class wxToolBarGTK;
+
+//-----------------------------------------------------------------------------
+// constants
+//-----------------------------------------------------------------------------
+
+#define wxTOOL_STYLE_BUTTON          1
+#define wxTOOL_STYLE_SEPARATOR       2
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxToolBarNameStr;
+
+//-----------------------------------------------------------------------------
+// wxToolBarTool
+//-----------------------------------------------------------------------------
+
+class wxToolBarTool: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxToolBarTool)
+  
+  public:
+
+    wxToolBarTool(void) {}; 
+    wxToolBarTool( wxToolBarGTK *owner, const int theIndex = 0, 
+      const wxBitmap& bitmap1 = wxNullBitmap, const wxBitmap& bitmap2 = wxNullBitmap, 
+      const bool toggle = FALSE, wxObject *clientData = NULL, 
+      const wxString& shortHelpString = "", const wxString& longHelpString = "");
+   ~wxToolBarTool(void);
+
+  public:
+  
+    int                   m_toolStyle;
+    wxObject             *m_clientData;
+    int                   m_index;
+    bool                  m_toggleState;
+    bool                  m_isToggle;
+    bool                  m_deleteSecondBitmap;
+    bool                  m_enabled;
+    wxBitmap              m_bitmap1;
+    wxBitmap              m_bitmap2;
+    bool                  m_isMenuCommand;
+    wxString              m_shortHelpString;
+    wxString              m_longHelpString;
+    wxToolBarGTK         *m_owner;
+};
+
+//-----------------------------------------------------------------------------
+// wxToolBarGTK
+//-----------------------------------------------------------------------------
+
+class wxToolBarGTK: public wxControl
+{
+  DECLARE_DYNAMIC_CLASS(wxToolBarGTK)
+  
+  public:
+
+    wxToolBarGTK(void);
+    wxToolBarGTK( wxWindow *parent, const wxWindowID id, 
+      const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+      const long style = 0, const wxString& name = wxToolBarNameStr );
+   ~wxToolBarGTK(void);
+
+   bool Create( wxWindow *parent, const wxWindowID id, 
+     const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+     const long style = 0, const wxString& name = wxToolBarNameStr);
+
+    // Only allow toggle if returns TRUE. Call when left button up.
+    virtual bool OnLeftClick(int toolIndex, bool toggleDown);
+
+    // Call when right button down.
+    virtual void OnRightClick(int toolIndex, float x, float y);
+
+    // Called when the mouse cursor enters a tool bitmap.
+    // Argument is -1 if mouse is exiting the toolbar.
+    virtual void OnMouseEnter(int toolIndex);
+
+    // If pushedBitmap is NULL, a reversed version of bitmap is
+    // created and used as the pushed/toggled image.
+    // If toggle is TRUE, the button toggles between the two states.
+    virtual wxToolBarTool *AddTool( const int toolIndex, const wxBitmap& bitmap, 
+      const wxBitmap& pushedBitmap = wxNullBitmap, const bool toggle = FALSE,
+      const float xPos = -1, const float yPos = -1, wxObject *clientData = NULL,
+      const wxString& helpString1 = "", const wxString& helpString2 = "");
+    virtual void AddSeparator(void);
+    virtual void ClearTools(void);
+
+    virtual void EnableTool(const int toolIndex, const bool enable);
+    virtual void ToggleTool(const int toolIndex, const bool toggle); // toggle is TRUE if toggled on
+    virtual void SetToggle(const int toolIndex, const bool toggle); // Set this to be togglable (or not)
+    virtual wxObject *GetToolClientData(const int index) const;
+
+    virtual bool GetToolState(const int toolIndex) const;
+    virtual bool GetToolEnabled(const int toolIndex) const;
+
+    virtual void SetMargins(const int x, const int y);
+    void SetMargins(const wxSize& size) { SetMargins(size.x, size.y); };
+    virtual void SetToolPacking(const int packing);
+    virtual void SetToolSeparation(const int separation);
+  
+  public:
+  
+    GtkToolbar   *m_toolbar;
+    wxList        m_tools;
+  
+  DECLARE_EVENT_TABLE()
+};
+
+#endif
+    // __TBARGTKH__
+
diff --git a/include/wx/gtk/textctrl.h b/include/wx/gtk/textctrl.h
new file mode 100644
index 0000000000..0222373fe2
--- /dev/null
+++ b/include/wx/gtk/textctrl.h
@@ -0,0 +1,106 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        textctrl.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKTEXTCTRLH__
+#define __GTKTEXTCTRLH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/string.h"
+#include "wx/control.h"
+
+#if USE_IOSTREAMH
+#include <iostream.h>
+#else
+#include <iostream>
+#endif
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxTextCtrl;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxTextCtrlNameStr;
+
+//-----------------------------------------------------------------------------
+//  wxTextCtrl
+//-----------------------------------------------------------------------------
+
+class wxTextCtrl: public wxControl, public streambuf
+{
+  DECLARE_DYNAMIC_CLASS(wxTextCtrl);
+
+  public:
+  
+    wxTextCtrl(void);
+    wxTextCtrl( wxWindow *parent, const wxWindowID id, const wxString &value = "", 
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const int style = 0, const wxString &name = wxTextCtrlNameStr );
+    bool Create( wxWindow *parent, const wxWindowID id, const wxString &value = "", 
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const int style = 0, const wxString &name = wxTextCtrlNameStr );
+    wxString GetValue(void) const;
+    void SetValue( const wxString &value );
+    void WriteText( const wxString &text );
+/*
+    wxString GetLineText( const long lineNo ) const;
+    bool LoadFile( const wxString &file );
+    bool SaveFile( const wxString &file );
+    void DiscardEdits(void);
+    bool IsModified(void);
+    void OnDropFiles( wxDropFilesEvent &event );
+    long PositionToXY( const long pos, long *x, long *y ) const;
+    long XYToPosition( const long x, const long y );
+    int GetNumberOfLines(void);
+*/
+    virtual void SetInsertionPoint( const long pos );
+    virtual void SetInsertionPointEnd(void);
+    virtual void SetEditable( const bool editable );
+    virtual void SetSelection( const long from, const long to );
+    void ShowPosition( const long pos );
+    virtual long GetInsertionPoint(void) const;
+    virtual long GetLastPosition(void) const;
+    virtual void Remove( const long from, const long to );
+    virtual void Replace( const long from, const long to, const wxString &value );
+    void Cut(void);
+    void Copy(void);
+    void Paste(void);
+    void Delete(void);
+    
+    void OnChar( wxKeyEvent &event );
+    
+    int overflow(int i);
+    int sync(void);
+    int underflow(void);
+
+    wxTextCtrl& operator<<(const wxString& s);
+    wxTextCtrl& operator<<(const int i);
+    wxTextCtrl& operator<<(const long i);
+    wxTextCtrl& operator<<(const float f);
+    wxTextCtrl& operator<<(const double d);
+    wxTextCtrl& operator<<(const char c);
+
+  DECLARE_EVENT_TABLE()
+    
+};
+
+#endif // __GTKTEXTCTRLH__
+
+
diff --git a/include/wx/gtk/timer.h b/include/wx/gtk/timer.h
new file mode 100644
index 0000000000..821c03b30d
--- /dev/null
+++ b/include/wx/gtk/timer.h
@@ -0,0 +1,53 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        timer.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKTIMERH__
+#define __GTKTIMERH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+
+//-----------------------------------------------------------------------------
+// derived classes
+//-----------------------------------------------------------------------------
+
+class wxTimer;
+
+//-----------------------------------------------------------------------------
+// wxTimer
+//-----------------------------------------------------------------------------
+
+class wxTimer: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxTimer)
+
+  public:
+
+    wxTimer(void);
+    ~wxTimer(void);
+    int Interval(void);
+    bool OneShot(void);
+    virtual void Notify(void);
+    void Start( int millisecs = -1, bool oneShot = FALSE );
+    void Stop(void);
+    
+  private:
+  
+    int  m_tag;
+    int  m_time;
+    bool m_oneShot;
+};
+
+#endif // __GTKTIMERH__
diff --git a/include/wx/gtk/win_gtk.h b/include/wx/gtk/win_gtk.h
new file mode 100644
index 0000000000..6bc8e3ea11
--- /dev/null
+++ b/include/wx/gtk/win_gtk.h
@@ -0,0 +1,75 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        win_gtk.h
+// Purpose:     wxWindows's GTK base widget
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTK_MYFIXED_H__
+#define __GTK_MYFIXED_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkcontainer.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_MYFIXED(obj)          GTK_CHECK_CAST (obj, gtk_myfixed_get_type (), GtkMyFixed)
+#define GTK_MYFIXED_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_myfixed_get_type (), GtkMyFixedClass)
+#define GTK_IS_MYFIXED(obj)       GTK_CHECK_TYPE (obj, gtk_myfixed_get_type ())
+
+
+typedef struct _GtkMyFixed        GtkMyFixed;
+typedef struct _GtkMyFixedClass   GtkMyFixedClass;
+typedef struct _GtkMyFixedChild   GtkMyFixedChild;
+
+struct _GtkMyFixed
+{
+  GtkContainer container;
+
+  GList *children;
+  
+  gint16  scroll_offset_x;
+  gint16  scroll_offset_y;
+};
+
+struct _GtkMyFixedClass
+{
+  GtkContainerClass parent_class;
+};
+
+struct _GtkMyFixedChild
+{
+  GtkWidget *widget;
+  gint16 x;
+  gint16 y;
+};
+
+guint      gtk_myfixed_get_type        (void);
+GtkWidget* gtk_myfixed_new             (void);
+void       gtk_myfixed_set_offset      (GtkMyFixed     *myfixed,
+                                        gint16         x,
+                                        gint16         y);
+void       gtk_myfixed_put             (GtkMyFixed     *myfixed,
+                                        GtkWidget      *widget,
+                                        gint16         x,
+                                        gint16         y);
+void       gtk_myfixed_move            (GtkMyFixed     *myfixed,
+                                        GtkWidget      *widget,
+                                        gint16         x,
+                                        gint16         y);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_MYFIXED_H__ */
diff --git a/include/wx/gtk/window.h b/include/wx/gtk/window.h
new file mode 100644
index 0000000000..40fbc48706
--- /dev/null
+++ b/include/wx/gtk/window.h
@@ -0,0 +1,262 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        window.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKWINDOWH__
+#define __GTKWINDOWH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/event.h"
+#include "wx/validate.h"
+#include "wx/cursor.h"
+#include "wx/font.h"
+#include "wx/dc.h"
+#include "wx/region.h"
+#include "wx/dnd.h"
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxFrameNameStr;
+extern wxList wxTopLevelWindows;
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxLayoutConstraints;
+class wxSizer;
+
+class wxWindow;
+class wxCanvas;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxPanelNameStr;
+extern const wxSize wxDefaultSize;
+extern const wxPoint wxDefaultPosition;
+
+//-----------------------------------------------------------------------------
+// wxWindow
+//-----------------------------------------------------------------------------
+
+class wxWindow: public wxEvtHandler
+{
+  DECLARE_DYNAMIC_CLASS(wxWindow)
+
+  public:
+  
+    wxWindow(void);
+    wxWindow( wxWindow *parent, const wxWindowID id,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = wxPanelNameStr );
+    bool Create( wxWindow *parent, const wxWindowID id,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = wxPanelNameStr );
+    virtual ~wxWindow(void);
+    bool Close( const bool force = FALSE );
+    virtual bool Destroy(void);
+    virtual bool DestroyChildren(void);
+    
+    virtual void PrepareDC( wxDC &dc );
+    
+    virtual void SetSize( const int x, const int y, const int width, const int height, 
+      const int sizeFlags = wxSIZE_AUTO );
+    virtual void SetSize( const int width, const int height );
+    virtual void Move( const int x, const int y );
+    virtual void GetSize( int *width, int *height ) const;
+    virtual void SetClientSize( int const width, int const height );
+    virtual void GetClientSize( int *width, int *height ) const;
+    virtual void GetPosition( int *x, int *y ) const;
+    virtual void Centre( const int direction = wxHORIZONTAL );
+    virtual void Fit(void);
+    
+    void OnSize( wxSizeEvent &event );
+    
+    virtual bool Show( const bool show );
+    virtual void Enable( const bool enable );
+    virtual void MakeModal( const bool modal );
+    virtual bool IsEnabled(void) const { return m_isEnabled; };
+    virtual void SetFocus(void);
+    virtual bool OnClose(void);
+    
+    virtual void AddChild( wxWindow *child );
+    wxList *GetChildren(void);
+    virtual void RemoveChild( wxWindow *child );
+    void SetReturnCode( int retCode );
+    int GetReturnCode(void);
+    wxWindow *GetParent(void);
+    
+    wxEvtHandler *GetEventHandler(void);
+    void SetEventhandler( wxEvtHandler *handler );
+    
+    virtual wxValidator *GetValidator(void);
+    virtual void SetValidator( wxValidator *validator );
+    
+    bool IsBeingDeleted(void);
+    
+    void SetId( wxWindowID id );
+    wxWindowID GetId(void);
+    
+    void SetCursor( const wxCursor &cursor );
+    
+    virtual void Refresh( const bool eraseBackground = TRUE, const wxRect *rect = NULL );
+    virtual void Clear(void);
+    virtual bool IsExposed( const long x, const long y );
+    virtual bool IsExposed( const long x, const long y, const long width, const long height );
+    
+    virtual wxColour GetBackgroundColour(void) const;
+    virtual void SetBackgroundColour( const wxColour &colour );
+    
+    virtual void SetDefaultBackgroundColour( const wxColour& col )
+      { m_defaultBackgroundColour = col; };
+    virtual wxColour GetDefaultBackgroundColour(void) const
+      { return m_defaultBackgroundColour; };
+    virtual void SetDefaultForegroundColour( const wxColour& col )
+      { m_defaultForegroundColour = col; };
+    virtual wxColour GetDefaultForegroundColour(void) const
+      { return m_defaultForegroundColour; };
+    
+    virtual void SetFont( const wxFont &font );
+    virtual wxFont *GetFont(void);
+    // For backward compatibility
+    inline virtual void SetButtonFont(const wxFont& font) { SetFont(font); }
+    inline virtual void SetLabelFont(const wxFont& font) { SetFont(font); }
+    inline virtual wxFont *GetLabelFont(void) { return GetFont(); };
+    inline virtual wxFont *GetButtonFont(void) { return GetFont(); };
+    virtual void SetWindowStyleFlag( long flag );
+    virtual long GetWindowStyleFlag(void) const;
+    virtual void CaptureMouse(void);
+    virtual void ReleaseMouse(void);
+    virtual void SetTitle( const wxString &title );
+    virtual wxString GetTitle(void) const;
+    virtual void SetName( const wxString &name );
+    virtual wxString GetName(void) const;
+    virtual wxString GetLabel(void) const;
+    
+    void OnSysColourChanged( wxSysColourChangedEvent &WXUNUSED(event) ) {};
+    
+    virtual bool IsShown(void);
+    virtual bool IsRetained(void);
+    virtual wxWindow *FindWindow( const long id );
+    virtual wxWindow *FindWindow( const wxString& name );
+    void AllowDoubleClick( bool WXUNUSED(allow) ) {};
+    void SetDoubleClick( bool WXUNUSED(allow) ) {};
+    virtual void ClientToScreen( int *x, int *y );
+    virtual void ScreenToClient( int *x, int *y );
+    
+    virtual bool Validate(void);
+    virtual bool TransferDataToWindow(void);
+    virtual bool TransferDataFromWindow(void);
+    void OnInitDialog( wxInitDialogEvent &event );
+    virtual void InitDialog(void);
+    
+    virtual void SetDropTarget( wxDropTarget *dropTarget );
+    virtual wxDropTarget *GetDropTarget() const;
+    
+    virtual void SetScrollbar( const int orient, const int pos, const int thumbVisible,
+      const int range, const bool refresh = TRUE );
+    virtual void SetScrollPos( const int orient, const int pos, const bool refresh = TRUE );
+    virtual int GetScrollPos( const int orient ) const;
+    virtual int GetScrollThumb( const int orient ) const;
+    virtual int GetScrollRange( const int orient ) const;
+    virtual void ScrollWindow( const int dx, const int dy, const wxRect* rect = NULL );
+    
+  public:         // cannot get private going yet
+    
+    void PreCreation( wxWindow *parent, const wxWindowID id, const wxPoint &pos, 
+      const wxSize &size, const long style, const wxString &name );
+    void PostCreation(void);
+    bool HasVMT(void);
+    virtual void ImplementSetSize(void);
+    virtual void ImplementSetPosition(void);
+    void GetDrawingOffset( long *x, long *y );
+    
+    wxWindow       *m_parent;
+    wxList          m_children;
+    int             m_x,m_y;
+    int             m_width,m_height;
+    int             m_retCode;
+    wxEvtHandler   *m_eventHandler;
+    wxValidator    *m_windowValidator;
+    wxDropTarget   *m_pDropTarget;   
+    wxWindowID      m_windowId;
+    wxCursor       *m_cursor;
+    wxFont          m_font;
+    wxColour        m_backgroundColour;
+    wxColour        m_defaultBackgroundColour;
+    wxColour        m_foregroundColour ;
+    wxColour        m_defaultForegroundColour;
+    wxRegion        m_updateRegion;
+    long            m_windowStyle;
+    bool            m_isShown;
+    bool            m_isEnabled;
+    wxString        m_windowName;
+    long            m_drawingOffsetX,m_drawingOffsetY;
+    
+    GtkWidget      *m_widget;
+    GtkWidget      *m_wxwindow;
+    GtkAdjustment  *m_hAdjust,*m_vAdjust;
+    float           m_oldHorizontalPos;
+    float           m_oldVerticalPos;
+    bool            m_needParent;
+    bool            m_hasScrolling;
+    bool            m_hasVMT;
+    bool            m_sizeSet;
+    
+  public:  // Layout section
+  
+    wxLayoutConstraints * m_constraints;  
+    wxList *              m_constraintsInvolvedIn;
+    wxSizer *             m_windowSizer;  
+    wxWindow *            m_sizerParent;  
+    bool                  m_autoLayout;                    
+
+    wxLayoutConstraints *GetConstraints(void) const;
+    void SetConstraints( wxLayoutConstraints *constraints );
+    void SetAutoLayout( const bool autoLayout );
+    bool GetAutoLayout(void) const;
+    bool Layout(void);
+    void SetSizer( wxSizer *sizer );
+    wxSizer *GetSizer(void) const;
+    void SetSizerParent( wxWindow *win );
+    wxWindow *GetSizerParent(void) const;
+    void UnsetConstraints(wxLayoutConstraints *c);
+    inline wxList *GetConstraintsInvolvedIn(void) const ;
+    void AddConstraintReference(wxWindow *otherWin);
+    void RemoveConstraintReference(wxWindow *otherWin);
+    void DeleteRelatedConstraints(void);
+    virtual void ResetConstraints(void);
+    virtual void SetConstraintSizes(const bool recurse = TRUE);
+    virtual bool LayoutPhase1(int *noChanges);
+    virtual bool LayoutPhase2(int *noChanges);
+    virtual bool DoPhase(const int);
+    virtual void TransformSizerToActual(int *x, int *y) const ;
+    virtual void SizerSetSize(const int x, const int y, const int w, const int h);
+    virtual void SizerMove(const int x, const int y);
+    virtual void SetSizeConstraint(const int x, const int y, const int w, const int h);
+    virtual void MoveConstraint(const int x, const int y);
+    virtual void GetSizeConstraint(int *w, int *h) const ;
+    virtual void GetClientSizeConstraint(int *w, int *h) const ;
+    virtual void GetPositionConstraint(int *x, int *y) const ;
+  
+  DECLARE_EVENT_TABLE()
+};
+
+#endif // __GTKWINDOWH__
diff --git a/include/wx/gtk1/app.h b/include/wx/gtk1/app.h
new file mode 100644
index 0000000000..11af9c4903
--- /dev/null
+++ b/include/wx/gtk1/app.h
@@ -0,0 +1,113 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        app.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __GTKAPPH__
+#define __GTKAPPH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/window.h"
+#include "wx/frame.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxApp;
+class wxLog;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern wxApp *wxTheApp;
+
+//-----------------------------------------------------------------------------
+// global functions
+//-----------------------------------------------------------------------------
+
+void wxExit(void);
+bool wxYield(void);
+
+//-----------------------------------------------------------------------------
+// constants
+//-----------------------------------------------------------------------------
+
+#define wxPRINT_WINDOWS         1
+#define wxPRINT_POSTSCRIPT      2
+
+//-----------------------------------------------------------------------------
+// wxApp
+//-----------------------------------------------------------------------------
+
+class wxApp: public wxEvtHandler
+{
+  DECLARE_DYNAMIC_CLASS(wxApp)
+
+  public:
+  
+    wxApp(void);
+    ~wxApp(void);
+    
+    static void SetInitializerFunction(wxAppInitializerFunction fn) { m_appInitFn = fn; }
+    static wxAppInitializerFunction GetInitializerFunction(void) { return m_appInitFn; }
+    virtual bool OnInit(void);
+    virtual bool OnInitGui(void);
+    virtual int OnRun(void);
+    virtual bool OnIdle(void);
+    virtual int OnExit(void);
+    
+    wxWindow *GetTopWindow(void);
+    void SetTopWindow( wxWindow *win );
+    virtual int MainLoop(void);
+    void ExitMainLoop(void);
+    bool Initialized(void);
+    virtual bool Pending(void);
+    virtual void Dispatch(void);
+    void DeletePendingObjects(void);
+    
+    inline wxString GetAppName(void) const {
+      if (m_appName != "")
+        return m_appName;
+      else return m_className;
+    }
+    inline void SetAppName(const wxString& name) { m_appName = name; };
+    inline wxString GetClassName(void) const { return m_className; }
+    inline void SetClassName(const wxString& name) { m_className = name; }
+
+    inline void SetExitOnFrameDelete(bool flag) { m_exitOnFrameDelete = flag; }
+    inline bool GetExitOnFrameDelete(void) const { return m_exitOnFrameDelete; }
+  
+    void SetPrintMode(int WXUNUSED(mode) ) {}; 
+    int GetPrintMode(void) const { return wxPRINT_POSTSCRIPT; };
+  
+    static void CommonInit(void);
+    static void CommonCleanUp(void);    
+    
+    // override this function to create default log target of arbitrary
+    // user-defined classv (default implementation creates a wxLogGui object)
+    virtual wxLog *CreateLogTarget();
+    
+    bool          m_initialized;
+    bool          m_exitOnFrameDelete;
+    gint          m_idleTag;
+    wxWindow     *m_topWindow;
+    wxString      m_appName;
+    wxString      m_className;
+    
+    int         argc;
+    char      **argv;
+    
+    static wxAppInitializerFunction m_appInitFn;
+};
+
+#endif // __GTKAPPH__
diff --git a/include/wx/gtk1/bitmap.h b/include/wx/gtk1/bitmap.h
new file mode 100644
index 0000000000..1d6260c5fc
--- /dev/null
+++ b/include/wx/gtk1/bitmap.h
@@ -0,0 +1,118 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        bitmap.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKBITMAPH__
+#define __GTKBITMAPH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/string.h"
+#include "wx/palette.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxDC;
+class wxPaintDC;
+class wxMemoryDC;
+class wxToolBarGTK;
+
+class wxMask;
+class wxBitmap;
+
+//-----------------------------------------------------------------------------
+// wxMask
+//-----------------------------------------------------------------------------
+
+class wxMask: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxMask)
+
+  public:
+  
+    wxMask(void);
+    wxMask( const wxBitmap& bitmap, const wxColour& colour );
+    wxMask( const wxBitmap& bitmap, const int paletteIndex );
+    wxMask( const wxBitmap& bitmap );
+    ~wxMask(void);
+
+  private:
+  
+    friend wxBitmap;
+    friend wxDC;
+    friend wxPaintDC;
+    friend wxToolBarGTK;
+    
+    GdkBitmap *GetBitmap(void) const;
+    
+  protected:
+  
+    GdkBitmap *m_bitmap;     
+    
+};
+
+//-----------------------------------------------------------------------------
+// wxBitmap
+//-----------------------------------------------------------------------------
+
+class wxBitmap: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxBitmap)
+
+  public:
+
+    wxBitmap(void);
+    wxBitmap( const int width, const int height, const int depth = -1 );
+    wxBitmap( char **bits );
+    wxBitmap( const wxBitmap& bmp );
+    wxBitmap( const wxBitmap* bmp );
+    wxBitmap( const wxString &filename, const int type );
+    ~wxBitmap(void);
+    wxBitmap& operator = ( const wxBitmap& bmp );
+    bool operator == ( const wxBitmap& bmp );
+    bool operator != ( const wxBitmap& bmp );
+    bool Ok(void) const;
+    
+    int GetHeight(void) const;
+    int GetWidth(void) const;
+    int GetDepth(void) const;
+    void SetHeight( const int height );
+    void SetWidth( const int width );
+    void SetDepth( const int depth );
+
+    wxMask *GetMask(void) const;
+    void SetMask( wxMask *mask );
+    
+    bool SaveFile( const wxString &name, const int type, wxPalette *palette = NULL );
+    bool LoadFile( const wxString &name, const int type );
+        
+    wxPalette *GetPalette(void) const;
+    wxPalette *GetColourMap(void) const
+      { return GetPalette(); };
+
+  private:
+  
+    friend wxDC;
+    friend wxPaintDC;
+    friend wxMemoryDC;
+    friend wxToolBarGTK;
+
+    GdkPixmap *GetPixmap(void) const;
+    
+    // no data :-)
+};
+
+#endif // __GTKBITMAPH__
diff --git a/include/wx/gtk1/bmpbuttn.h b/include/wx/gtk1/bmpbuttn.h
new file mode 100644
index 0000000000..c8dbaba78d
--- /dev/null
+++ b/include/wx/gtk1/bmpbuttn.h
@@ -0,0 +1,34 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        bmpbutton.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __BMPBUTTONH__
+#define __BMPBUTTONH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxBitmapButton;
+
+//-----------------------------------------------------------------------------
+// wxBitmapButton
+//-----------------------------------------------------------------------------
+
+#endif // __BMPBUTTONH__
diff --git a/include/wx/gtk1/brush.h b/include/wx/gtk1/brush.h
new file mode 100644
index 0000000000..3cac78adc7
--- /dev/null
+++ b/include/wx/gtk1/brush.h
@@ -0,0 +1,60 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        brush.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKBRUSHH__
+#define __GTKBRUSHH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/string.h"
+#include "wx/gdiobj.h"
+#include "wx/bitmap.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxBrush;
+
+//-----------------------------------------------------------------------------
+// wxBrush
+//-----------------------------------------------------------------------------
+
+class wxBrush: public wxGDIObject
+{
+  DECLARE_DYNAMIC_CLASS(wxBrush)
+
+  public:
+
+    wxBrush(void);
+    wxBrush( const wxColour &colour, const int style );
+    wxBrush( const wxString &colourName, const int style );
+    wxBrush( const wxBitmap &stippleBitmap );
+    wxBrush( const wxBrush &brush );
+    wxBrush( const wxBrush *brush );
+    ~wxBrush(void);
+    wxBrush& operator = ( const wxBrush& brush );
+    bool operator == ( const wxBrush& brush );
+    bool operator != ( const wxBrush& brush );
+    bool Ok(void) const;
+
+    int GetStyle(void) const;
+    wxColour &GetColour(void) const;
+    wxBitmap *GetStipple(void) const;
+    
+    // no data :-)
+};
+
+#endif // __GTKBRUSHH__
diff --git a/include/wx/gtk1/button.h b/include/wx/gtk1/button.h
new file mode 100644
index 0000000000..b0e2220c0e
--- /dev/null
+++ b/include/wx/gtk1/button.h
@@ -0,0 +1,58 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        button.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKBUTTONH__
+#define __GTKBUTTONH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxButton;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxButtonNameStr;
+
+//-----------------------------------------------------------------------------
+// wxButton
+//-----------------------------------------------------------------------------
+
+class wxButton: public wxControl
+{
+  DECLARE_DYNAMIC_CLASS(wxButton)
+
+  public:
+
+    wxButton(void);
+    wxButton( wxWindow *parent, wxWindowID id, const wxString &label,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = wxButtonNameStr  );
+    bool Create(  wxWindow *parent, wxWindowID id, const wxString &label,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = wxButtonNameStr  );
+    void SetDefault(void);
+    void SetLabel( const wxString &label );
+    wxString GetLabel(void) const;
+};
+
+#endif // __GTKBUTTONH__
diff --git a/include/wx/gtk1/checkbox.h b/include/wx/gtk1/checkbox.h
new file mode 100644
index 0000000000..0f95924e1b
--- /dev/null
+++ b/include/wx/gtk1/checkbox.h
@@ -0,0 +1,57 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        checkbox.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKCHECKBOXH__
+#define __GTKCHECKBOXH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxCheckBox;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxCheckBoxNameStr;
+
+//-----------------------------------------------------------------------------
+// wxCheckBox
+//-----------------------------------------------------------------------------
+
+class wxCheckBox: public wxControl
+{
+  DECLARE_DYNAMIC_CLASS(wxCheckBox)
+
+  public:
+
+    wxCheckBox(void);
+    wxCheckBox( wxWindow *parent, wxWindowID id, const wxString &label,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = wxCheckBoxNameStr  );
+    bool Create(  wxWindow *parent, wxWindowID id, const wxString &label,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = wxCheckBoxNameStr  );
+    void SetValue( const bool state );
+    bool GetValue(void) const;
+};
+
+#endif // __GTKCHECKBOXH__
diff --git a/include/wx/gtk1/choice.h b/include/wx/gtk1/choice.h
new file mode 100644
index 0000000000..b3feb2c065
--- /dev/null
+++ b/include/wx/gtk1/choice.h
@@ -0,0 +1,68 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        choice.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKCHOICEH__
+#define __GTKCHOICEH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxChoice;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxChoiceNameStr;
+
+//-----------------------------------------------------------------------------
+// wxChoice
+//-----------------------------------------------------------------------------
+
+class wxChoice: public wxControl
+{
+  DECLARE_DYNAMIC_CLASS(wxChoice)
+
+  public:
+
+    wxChoice(void);
+    wxChoice( wxWindow *parent, const wxWindowID id,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const int n = 0, const wxString choices[] = NULL,
+      const long style = 0, const wxString &name = wxChoiceNameStr );
+    bool Create( wxWindow *parent, const wxWindowID id,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const int n = 0, const wxString choices[] = NULL,
+      const long style = 0, const wxString &name = wxChoiceNameStr );
+    void Append( const wxString &item );
+    void Clear(void);
+    int FindString( const wxString &string ) const;
+    int GetColumns(void) const;
+    int GetSelection(void);
+    wxString GetString( const int n ) const;
+    wxString GetStringSelection(void) const;
+    int Number(void) const;
+    void SetColumns( const int n = 1 );
+    void SetSelection( const int n );
+    void SetStringSelection( const wxString &string );
+};
+
+#endif // __GTKCHOICEH__
diff --git a/include/wx/gtk1/colour.h b/include/wx/gtk1/colour.h
new file mode 100644
index 0000000000..8757d2c00b
--- /dev/null
+++ b/include/wx/gtk1/colour.h
@@ -0,0 +1,76 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        colour.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKCOLOURH__
+#define __GTKCOLOURH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/string.h"
+#include "wx/gdiobj.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxDC;
+class wxPaintDC;
+class wxBitmap;
+class wxWindow;
+
+class wxColour;
+
+//-----------------------------------------------------------------------------
+// wxColour
+//-----------------------------------------------------------------------------
+
+class wxColour: public wxGDIObject
+{
+  DECLARE_DYNAMIC_CLASS(wxColour)
+
+  public:
+
+    wxColour(void);
+    wxColour( char red, char green, char blue );
+    wxColour( const wxString &colourName );
+    wxColour( const wxColour& col );
+    wxColour( const wxColour* col );
+    ~wxColour(void);
+    wxColour& operator = ( const wxColour& col );
+    wxColour& operator = ( const wxString& colourName );
+    bool operator == ( const wxColour& col );
+    bool operator != ( const wxColour& col );
+    void Set( const unsigned char red, const unsigned char green, const unsigned char blue );
+    unsigned char Red(void) const;
+    unsigned char Green(void) const;
+    unsigned char Blue(void) const;
+    bool Ok(void) const;
+
+  private:
+  public:
+  
+    friend wxDC;
+    friend wxPaintDC;
+    friend wxBitmap;
+    friend wxWindow;
+        
+    void CalcPixel( GdkColormap *cmap );
+    int GetPixel(void);
+    GdkColor *GetColor(void);
+    
+    // no data :-)
+};
+  
+#endif // __GTKCOLOURH__
diff --git a/include/wx/gtk1/combobox.h b/include/wx/gtk1/combobox.h
new file mode 100644
index 0000000000..355d087281
--- /dev/null
+++ b/include/wx/gtk1/combobox.h
@@ -0,0 +1,34 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        combobox.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKCOMBOBOXH__
+#define __GTKCOMBOBOXH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxComboBox;
+
+//-----------------------------------------------------------------------------
+// wxComboBox
+//-----------------------------------------------------------------------------
+
+#endif // __GTKCOMBOBOXH__
diff --git a/include/wx/gtk1/control.h b/include/wx/gtk1/control.h
new file mode 100644
index 0000000000..ad8ea7abea
--- /dev/null
+++ b/include/wx/gtk1/control.h
@@ -0,0 +1,51 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        control.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKCONTROLH__
+#define __GTKCONTROLH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/window.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxControl;
+
+//-----------------------------------------------------------------------------
+// wxControl
+//-----------------------------------------------------------------------------
+
+class wxControl: public wxWindow
+{
+  DECLARE_DYNAMIC_CLASS(wxControl)
+
+  public:
+
+    wxControl(void);
+    wxControl( wxWindow *parent, wxWindowID id, 
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = wxPanelNameStr  );
+    virtual void Command( wxCommandEvent &event );
+    virtual void SetLabel( const wxString &label );
+    virtual wxString GetLabel(void) const;
+    
+    wxString   m_label;
+};
+
+#endif // __GTKCONTROLH__
diff --git a/include/wx/gtk1/cursor.h b/include/wx/gtk1/cursor.h
new file mode 100644
index 0000000000..a6fcb40b17
--- /dev/null
+++ b/include/wx/gtk1/cursor.h
@@ -0,0 +1,61 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        cursor.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKCURSORH__
+#define __GTKCURSORH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/gdicmn.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxWindow;
+
+class wxCursor;
+
+//-----------------------------------------------------------------------------
+// wxCursor
+//-----------------------------------------------------------------------------
+
+class wxCursor: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxCursor)
+
+  public:
+
+    wxCursor(void);
+    wxCursor( const int cursorId );
+    wxCursor( const wxCursor &cursor );
+    wxCursor( const wxCursor *cursor );
+    ~wxCursor(void);
+    wxCursor& operator = ( const wxCursor& cursor );
+    bool operator == ( const wxCursor& cursor );
+    bool operator != ( const wxCursor& cursor );
+    bool Ok(void) const;
+    
+  private:
+  public:
+  
+    friend wxWindow;
+  
+    GdkCursor *GetCursor(void) const;
+
+    // no data :-)
+};
+
+#endif // __GTKCURSORH__
diff --git a/include/wx/gtk1/dc.h b/include/wx/gtk1/dc.h
new file mode 100644
index 0000000000..9abb2793df
--- /dev/null
+++ b/include/wx/gtk1/dc.h
@@ -0,0 +1,306 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        dc.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKDCH__
+#define __GTKDCH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/gdicmn.h"
+#include "wx/pen.h"
+#include "wx/brush.h"
+#include "wx/icon.h"
+#include "wx/font.h"
+#include "wx/gdicmn.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxDC;
+
+//-----------------------------------------------------------------------------
+// constants
+//-----------------------------------------------------------------------------
+
+#define MM_TEXT			0
+#define MM_ISOTROPIC		1
+#define MM_ANISOTROPIC		2
+#define MM_LOMETRIC		3
+#define MM_HIMETRIC		4
+#define MM_TWIPS		5
+#define MM_POINTS		6
+#define MM_METRIC		7
+
+//-----------------------------------------------------------------------------
+// global variables
+//-----------------------------------------------------------------------------
+
+extern int wxPageNumber;
+
+//-----------------------------------------------------------------------------
+// wxDC
+//-----------------------------------------------------------------------------
+
+class wxDC: public wxObject
+{
+  DECLARE_ABSTRACT_CLASS(wxDC)
+
+  public:
+
+    wxDC(void);
+    ~wxDC(void);
+    
+    void BeginDrawing(void) {};
+    void EndDrawing(void) {};
+    
+    virtual bool Ok(void) const { return m_ok; };
+
+    virtual void FloodFill( long x1, long y1, wxColour *col, int style=wxFLOOD_SURFACE ) = 0;
+    virtual bool GetPixel( long x1, long y1, wxColour *col ) const = 0;
+
+    virtual void DrawLine( long x1, long y1, long x2, long y2 ) = 0;
+    virtual void CrossHair( long x, long y ) = 0;
+    virtual void DrawArc( long x1, long y1, long x2, long y2, double xc, double yc );
+    virtual void DrawEllipticArc( long x, long y, long width, long height, double sa, double ea ) = 0;
+    virtual void DrawPoint( long x, long y ) = 0;
+    virtual void DrawPoint( wxPoint& point );
+    
+    virtual void DrawLines( int n, wxPoint points[], long xoffset = 0, long yoffset = 0 ) = 0;
+    virtual void DrawLines( wxList *points, long xoffset = 0, long yoffset = 0 );
+    virtual void DrawPolygon( int n, wxPoint points[], long xoffset = 0, long yoffset = 0, 
+                              int fillStyle=wxODDEVEN_RULE ) = 0;
+    virtual void DrawPolygon( wxList *lines, long xoffset = 0, long yoffset = 0, 
+                              int fillStyle=wxODDEVEN_RULE );
+    
+    virtual void DrawRectangle( long x, long y, long width, long height ) = 0;
+    virtual void DrawRoundedRectangle( long x, long y, long width, long height, double radius = 20.0 ) = 0;
+    virtual void DrawEllipse( long x, long y, long width, long height ) = 0;
+    
+    virtual void DrawSpline( long x1, long y1, long x2, long y2, long x3, long y3 );
+    virtual void DrawSpline( wxList *points );
+    virtual void DrawSpline( int n, wxPoint points[] );
+    
+    virtual bool CanDrawBitmap(void) const = 0;
+    virtual void DrawIcon( const wxIcon &icon, long x, long y, bool useMask=FALSE );
+            void DrawBitmap( const wxBitmap &bmp, long x, long y, bool useMask=FALSE )
+	    { DrawIcon( *((wxIcon*)(&bmp)), x, y, useMask ); }
+    virtual bool Blit( long xdest, long ydest, long width, long height,
+       wxDC *source, long xsrc, long ysrc, int logical_func = wxCOPY, bool useMask=FALSE ) = 0;
+
+    virtual void DrawText( const wxString &text, long x, long y, bool use16 = FALSE ) = 0;
+    virtual bool CanGetTextExtent(void) const = 0;
+    virtual void GetTextExtent( const wxString &string, long *width, long *height,
+                     long *descent = NULL, long *externalLeading = NULL,
+                     wxFont *theFont = NULL, bool use16 = FALSE ) = 0;
+    virtual long GetCharWidth(void) = 0;
+    virtual long GetCharHeight(void) = 0;
+    
+    virtual void Clear(void) = 0;
+            
+    virtual void SetFont( const wxFont &font ) = 0;
+    virtual wxFont *GetFont(void) { return &m_font; };
+    
+    virtual void SetPen( const wxPen &pen ) = 0;
+    virtual wxPen *GetPen(void) { return &m_pen; };
+    
+    virtual void SetBrush( const wxBrush &brush ) = 0;
+    virtual wxBrush *GetBrush(void) { return &m_brush; };
+
+    virtual void SetLogicalFunction( int function ) = 0;
+    virtual int GetLogicalFunction(void) { return m_logicalFunction; };
+    
+    virtual void SetTextForeground( const wxColour &col );
+    virtual void SetTextBackground( const wxColour &col );
+    virtual wxColour& GetTextBackground(void) const { return (wxColour&)m_textBackgroundColour; };
+    virtual wxColour& GetTextForeground(void) const { return (wxColour&)m_textForegroundColour; };
+    
+    virtual void SetBackgroundMode( int mode ) = 0;
+    virtual int GetBackgroundMode(void) { return m_backgroundMode; };
+    
+    virtual void SetPalette( const wxPalette& palette ) = 0;
+      void SetColourMap( const wxPalette& palette ) { SetPalette(palette); };
+    
+    // the first two must be overridden and called
+    virtual void SetClippingRegion( long x, long y, long width, long height );
+    virtual void DestroyClippingRegion(void);
+    virtual void GetClippingBox( long *x, long *y, long *width, long *height ) const;
+    
+    virtual inline long MinX(void) const { return m_minX; }
+    virtual inline long MaxX(void) const { return m_maxX; }
+    virtual inline long MinY(void) const { return m_minY; }
+    virtual inline long MaxY(void) const { return m_maxY; }
+
+    virtual void GetSize( int* width, int* height ) const;
+    inline wxSize GetSize(void) const { int w, h; GetSize(&w, &h); return wxSize(w, h); }
+    virtual void GetSizeMM( long* width, long* height ) const;
+    
+    virtual bool StartDoc( const wxString& WXUNUSED(message) ) { return TRUE; };
+    virtual void EndDoc(void) {};
+    virtual void StartPage(void) {};
+    virtual void EndPage(void) {};
+    
+    virtual void SetMapMode( int mode );
+    virtual int GetMapMode(void) const { return m_mappingMode; };
+    
+    virtual void SetUserScale( double x, double y );
+    virtual void GetUserScale( double *x, double *y );
+    virtual void SetLogicalScale( double x, double y );
+    virtual void GetLogicalScale( double *x, double *y );
+    
+    virtual void SetLogicalOrigin( long x, long y );
+    virtual void GetLogicalOrigin( long *x, long *y );
+    virtual void SetDeviceOrigin( long x, long y );
+    virtual void GetDeviceOrigin( long *x, long *y );
+    virtual void SetInternalDeviceOrigin( long x, long y );
+    virtual void GetInternalDeviceOrigin( long *x, long *y );
+
+    virtual void SetAxisOrientation( bool xLeftRight, bool yBottomUp );
+    
+    virtual void SetOptimization( bool WXUNUSED(optimize) ) {};
+    virtual bool GetOptimization(void) { return m_optimize; };
+    
+    virtual long DeviceToLogicalX(long x) const;
+    virtual long DeviceToLogicalY(long y) const;
+    virtual long DeviceToLogicalXRel(long x) const;
+    virtual long DeviceToLogicalYRel(long y) const;
+    virtual long LogicalToDeviceX(long x) const;
+    virtual long LogicalToDeviceY(long y) const;
+    virtual long LogicalToDeviceXRel(long x) const;
+    virtual long LogicalToDeviceYRel(long y) const;
+
+  public:
+  
+    void CalcBoundingBox( long x, long y );
+    void ComputeScaleAndOrigin(void);
+    
+    long XDEV2LOG(long x) const
+	{
+	  long new_x = x - m_deviceOriginX;
+	  if (new_x > 0) 
+	    return (long)((double)(new_x) / m_scaleX + 0.5) * m_signX + m_logicalOriginX;
+	  else
+	    return (long)((double)(new_x) / m_scaleX - 0.5) * m_signX + m_logicalOriginX;
+	}
+    long XDEV2LOGREL(long x) const
+	{ 
+	  if (x > 0) 
+	    return (long)((double)(x) / m_scaleX + 0.5);
+	  else
+	    return (long)((double)(x) / m_scaleX - 0.5);
+	}
+    long YDEV2LOG(long y) const
+	{
+	  long new_y = y - m_deviceOriginY;
+	  if (new_y > 0)
+	    return (long)((double)(new_y) / m_scaleY + 0.5) * m_signY + m_logicalOriginY;
+	  else
+	    return (long)((double)(new_y) / m_scaleY - 0.5) * m_signY + m_logicalOriginY;
+	}
+    long YDEV2LOGREL(long y) const
+	{ 
+	  if (y > 0)
+	    return (long)((double)(y) / m_scaleY + 0.5);
+	  else
+	    return (long)((double)(y) / m_scaleY - 0.5);
+	}
+    long XLOG2DEV(long x) const
+	{ 
+	  long new_x = x - m_logicalOriginX;
+	  if (new_x > 0)
+	    return (long)((double)(new_x) * m_scaleX + 0.5) * m_signX + m_deviceOriginX;
+	  else
+	    return (long)((double)(new_x) * m_scaleX - 0.5) * m_signX + m_deviceOriginX;
+	}
+    long XLOG2DEVREL(long x) const
+	{ 
+	  if (x > 0)
+	    return (long)((double)(x) * m_scaleX + 0.5);
+	  else
+	    return (long)((double)(x) * m_scaleX - 0.5);
+	}
+    long YLOG2DEV(long y) const
+	{
+	  long new_y = y - m_logicalOriginY;
+	  if (new_y > 0)
+	    return (long)((double)(new_y) * m_scaleY + 0.5) * m_signY + m_deviceOriginY;
+	  else
+	    return (long)((double)(new_y) * m_scaleY - 0.5) * m_signY + m_deviceOriginY;
+	}
+    long YLOG2DEVREL(long y) const
+	{ 
+	  if (y > 0)
+	    return (long)((double)(y) * m_scaleY + 0.5);
+	  else
+	    return (long)((double)(y) * m_scaleY - 0.5);
+	}
+  
+    virtual void DrawOpenSpline( wxList *points ) = 0;
+	
+  public:
+    
+    bool         m_ok;
+    bool         m_colour;
+    
+    // not sure, what these mean
+    bool         m_clipping;      // Is clipping on right now ?
+    bool         m_isInteractive; // Is GetPixel possible ?
+    bool         m_autoSetting;   // wxMSW only ?
+    bool         m_dontDelete;    // wxMSW only ?
+    bool         m_optimize;      // wxMSW only ?
+    wxString     m_filename;      // Not sure where this belongs.
+    
+    wxPen        m_pen;
+    wxBrush      m_brush;
+    wxBrush      m_backgroundBrush;
+    wxColour     m_textForegroundColour;
+    wxColour     m_textBackgroundColour;
+    wxFont       m_font;
+    
+    int          m_logicalFunction;
+    int          m_backgroundMode;
+    int          m_textAlignment;    // gone in wxWin 2.0 ?
+    
+    int          m_mappingMode;
+    
+    // not sure what for, but what is a mm on a screen you don't know the size of?
+    double       m_mm_to_pix_x,m_mm_to_pix_y; 
+    
+    long         m_internalDeviceOriginX,m_internalDeviceOriginY;   // If un-scrolled is non-zero or
+								    // d.o. changes with scrolling.
+								    // Set using SetInternalDeviceOrigin().
+								    
+    long         m_externalDeviceOriginX,m_externalDeviceOriginY;   // To be set by external classes
+                                                                    // such as wxScrolledWindow
+								    // using SetDeviceOrigin()
+								    
+    long         m_deviceOriginX,m_deviceOriginY;                   // Sum of the two above.
+    
+    long         m_logicalOriginX,m_logicalOriginY;                 // User defined.
+
+    double       m_scaleX,m_scaleY;
+    double       m_logicalScaleX,m_logicalScaleY;
+    double       m_userScaleX,m_userScaleY;
+    long         m_signX,m_signY;
+    
+    bool         m_needComputeScaleX,m_needComputeScaleY;         // not yet used
+    
+    float        m_scaleFactor;  // wxPSDC wants to have this. Will disappear.
+    
+    long         m_clipX1,m_clipY1,m_clipX2,m_clipY2;
+    long         m_minX,m_maxX,m_minY,m_maxY;
+};
+
+#endif // __GTKDCH__
diff --git a/include/wx/gtk1/dcclient.h b/include/wx/gtk1/dcclient.h
new file mode 100644
index 0000000000..7ae3e3099c
--- /dev/null
+++ b/include/wx/gtk1/dcclient.h
@@ -0,0 +1,107 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        dcclient.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKDCCLIENTH__
+#define __GTKDCCLIENTH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/dc.h"
+#include "wx/window.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxPaintDC;
+typedef wxPaintDC wxClientDC;
+typedef wxPaintDC wxWindowDC;
+
+//-----------------------------------------------------------------------------
+// wxPaintDC
+//-----------------------------------------------------------------------------
+
+class wxPaintDC: public wxDC
+{
+  DECLARE_DYNAMIC_CLASS(wxPaintDC)
+
+  public:
+
+    wxPaintDC(void);
+    wxPaintDC( wxWindow *win );
+    
+    ~wxPaintDC(void);
+    
+    virtual void FloodFill( long x1, long y1, wxColour *col, int style=wxFLOOD_SURFACE );
+    virtual bool GetPixel( long x1, long y1, wxColour *col ) const;
+
+    virtual void DrawLine( long x1, long y1, long x2, long y2 );
+    virtual void CrossHair( long x, long y );
+    virtual void DrawArc( long x1, long y1, long x2, long y2, double xc, double yc );
+    virtual void DrawEllipticArc( long x, long y, long width, long height, double sa, double ea );
+    virtual void DrawPoint( long x, long y );
+    
+    virtual void DrawLines( int n, wxPoint points[], long xoffset = 0, long yoffset = 0 );
+    virtual void DrawLines( wxList *points, long xoffset = 0, long yoffset = 0 );
+    virtual void DrawPolygon( int n, wxPoint points[], long xoffset = 0, long yoffset = 0, 
+                              int fillStyle=wxODDEVEN_RULE );
+    virtual void DrawPolygon( wxList *lines, long xoffset = 0, long yoffset = 0, 
+                              int fillStyle=wxODDEVEN_RULE );
+    
+    virtual void DrawRectangle( long x, long y, long width, long height );
+    virtual void DrawRoundedRectangle( long x, long y, long width, long height, double radius = 20.0 );
+    virtual void DrawEllipse( long x, long y, long width, long height );
+    
+    virtual bool CanDrawBitmap(void) const;
+    virtual void DrawIcon( const wxIcon &icon, long x, long y, bool useMask=FALSE );
+    virtual bool Blit( long xdest, long ydest, long width, long height,
+       wxDC *source, long xsrc, long ysrc, int logical_func = wxCOPY, bool useMask=FALSE );
+
+    virtual void DrawText( const wxString &text, long x, long y, bool use16 = FALSE );
+    virtual bool CanGetTextExtent(void) const;
+    virtual void GetTextExtent( const wxString &string, long *width, long *height,
+                     long *descent = NULL, long *externalLeading = NULL,
+                     wxFont *theFont = NULL, bool use16 = FALSE );
+    virtual long GetCharWidth(void);
+    virtual long GetCharHeight(void);
+    
+    virtual void Clear(void);
+            
+    virtual void SetFont( const wxFont &font );
+    virtual void SetPen( const wxPen &pen );
+    virtual void SetBrush( const wxBrush &brush );
+    virtual void SetLogicalFunction( int function );
+    virtual void SetTextForeground( const wxColour &col );
+    virtual void SetTextBackground( const wxColour &col );
+    virtual void SetBackgroundMode( int mode );
+    virtual void SetPalette( const wxPalette& palette );
+    
+    virtual void SetClippingRegion( long x, long y, long width, long height );
+    virtual void DestroyClippingRegion(void);
+    
+    virtual void DrawOpenSpline( wxList *points );
+    
+  public: // shouldn't be public
+    
+    GdkWindow    *m_window;
+    GdkGC        *m_penGC;
+    GdkGC        *m_brushGC;
+    GdkGC        *m_textGC;
+    GdkGC        *m_bgGC;
+    GdkColormap  *m_cmap;
+    
+    void SetUpDC(void);
+    GdkWindow *GetWindow(void);
+};
+
+#endif // __GTKDCCLIENTH__
diff --git a/include/wx/gtk1/dcmemory.h b/include/wx/gtk1/dcmemory.h
new file mode 100644
index 0000000000..66cf85bfc0
--- /dev/null
+++ b/include/wx/gtk1/dcmemory.h
@@ -0,0 +1,49 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        dcmemory.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKDCMEMORYH__
+#define __GTKDCMEMORYH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/dcclient.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxMemoryDC;
+
+//-----------------------------------------------------------------------------
+// wxMemoryDC
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxMemoryDC: public wxPaintDC
+{
+  DECLARE_DYNAMIC_CLASS(wxMemoryDC)
+
+  public:
+    wxMemoryDC(void);
+    wxMemoryDC( wxDC *dc ); // Create compatible DC
+    ~wxMemoryDC(void);
+    virtual void SelectObject( const wxBitmap& bitmap );
+    void GetSize( int *width, int *height );
+
+  private: 
+    wxBitmap  m_selected;
+};
+
+#endif
+    // __GTKDCMEMORYH__
+
diff --git a/include/wx/gtk1/dcscreen.h b/include/wx/gtk1/dcscreen.h
new file mode 100644
index 0000000000..5cb1991fe9
--- /dev/null
+++ b/include/wx/gtk1/dcscreen.h
@@ -0,0 +1,32 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        dcscreen.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKDCSCREENH__
+#define __GTKDCSCREENH__
+
+#include "wx/dcclient.h"
+
+class WXDLLEXPORT wxScreenDC: public wxPaintDC
+{
+  DECLARE_DYNAMIC_CLASS(wxScreenDC)
+
+ public:
+  wxScreenDC(void);
+  ~wxScreenDC(void);
+
+  static bool StartDrawingOnTop( wxWindow *window );
+  static bool StartDrawingOnTop( wxRectangle *rect = NULL );
+  static bool EndDrawingOnTop(void);
+};
+
+#endif
+    // __GTKDCSCREENH__
+
diff --git a/include/wx/gtk1/dialog.h b/include/wx/gtk1/dialog.h
new file mode 100644
index 0000000000..6c9c99e2a1
--- /dev/null
+++ b/include/wx/gtk1/dialog.h
@@ -0,0 +1,95 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        dialog.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKDIALOGH__
+#define __GTKDIALOGH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/string.h"
+#include "wx/event.h"
+#include "wx/window.h"
+
+//-----------------------------------------------------------------------------
+// forward decls
+//-----------------------------------------------------------------------------
+
+class wxRadioBox;
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxDialog;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxDialogNameStr;
+
+//-----------------------------------------------------------------------------
+// wxDialog
+//-----------------------------------------------------------------------------
+
+class wxDialog: public wxWindow
+{
+  DECLARE_DYNAMIC_CLASS(wxDialog)
+
+  public:
+
+    wxDialog(void);
+    wxDialog( wxWindow *parent, wxWindowID id, const wxString &title,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = wxDEFAULT_DIALOG_STYLE, const wxString &name = wxDialogNameStr );
+    bool Create( wxWindow *parent, wxWindowID id, const wxString &title,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = wxDEFAULT_DIALOG_STYLE, const wxString &name = wxDialogNameStr );
+    ~wxDialog(void);
+    void SetTitle(const wxString& title);
+    wxString GetTitle(void) const;
+    bool OnClose(void);
+    void OnApply( wxCommandEvent &event );
+    void OnCancel( wxCommandEvent &event );
+    void OnOk( wxCommandEvent &event );
+    void OnPaint(wxPaintEvent& event);
+    void OnCloseWindow(wxCloseEvent& event);
+/*
+    void OnCharHook(wxKeyEvent& event);
+*/
+    virtual bool Show( const bool show );
+    virtual int ShowModal(void);
+    virtual void EndModal(int retCode);
+    virtual bool IsModal(void) const { return ((GetWindowStyleFlag() & wxDIALOG_MODAL) == wxDIALOG_MODAL); }
+    virtual void InitDialog(void);
+/*
+    void OnOK(wxCommandEvent& event);
+    void OnApply(wxCommandEvent& event);
+    void OnCancel(wxCommandEvent& event);
+*/
+    
+  private:
+  
+    friend    wxWindow;
+    friend    wxDC;
+    friend    wxRadioBox;
+    bool       m_modalShowing;
+    wxString   m_title;
+    
+  DECLARE_EVENT_TABLE()
+    
+};
+
+#endif // __GTKDIALOGH__
diff --git a/include/wx/gtk1/dirdlg.h b/include/wx/gtk1/dirdlg.h
new file mode 100644
index 0000000000..7d8829f55b
--- /dev/null
+++ b/include/wx/gtk1/dirdlg.h
@@ -0,0 +1,35 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        dirdlg.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __DIRDIALOGH__
+#define __DIRDIALOGH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+#include "wx/dialog.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxDirDialog;
+
+//-----------------------------------------------------------------------------
+// wxDirDialog
+//-----------------------------------------------------------------------------
+
+#endif // __DIRDIALOGH__
diff --git a/include/wx/gtk1/dnd.h b/include/wx/gtk1/dnd.h
new file mode 100644
index 0000000000..45bf0cf2f6
--- /dev/null
+++ b/include/wx/gtk1/dnd.h
@@ -0,0 +1,116 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        dnd.h
+// Purpose:     declaration of the wxDropTarget class
+// Author:      Robert Roebling
+// RCS-ID:      
+// Copyright:   (c) 1998 Vadim Zeitlin, Robert Roebling
+// Licence:     wxWindows license
+///////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKDNDH__
+#define __GTKDNDH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/string.h"
+#include "wx/cursor.h"
+
+//-------------------------------------------------------------------------
+// classes
+//-------------------------------------------------------------------------
+
+class wxWindow;
+
+class wxDropTarget;
+class wxTextDropTarget;
+class wxDragSource;
+class wxTextDragSource;
+
+//-------------------------------------------------------------------------
+// wxDropTarget
+//-------------------------------------------------------------------------
+
+class wxDropTarget: wxObject
+{
+  public:
+
+    wxDropTarget();
+    ~wxDropTarget();
+    virtual void OnEnter() { }
+    virtual void OnLeave() { }
+    virtual bool OnDrop( long x, long y, const void *pData ) = 0;
+
+  public:
+
+    void Drop( GdkEvent *event, int x, int y );
+    virtual void RegisterWidget( GtkWidget *widget ) = 0;
+    void UnregisterWidget( GtkWidget *widget );
+};
+
+//-------------------------------------------------------------------------
+// wxTextDropTarget
+//-------------------------------------------------------------------------
+
+class wxTextDropTarget: public wxDropTarget
+{
+  public:
+
+    wxTextDropTarget() {};
+    virtual bool OnDrop( long x, long y, const void *pData );
+    virtual bool OnDropText( long x, long y, const char *psz );
+    virtual void RegisterWidget( GtkWidget *widget );
+};
+
+//-------------------------------------------------------------------------
+// wxDragSource
+//-------------------------------------------------------------------------
+
+class wxDragSource: public wxObject
+{
+  public:
+
+    wxDragSource( wxWindow *win );
+    ~wxDragSource(void);
+    void SetData( char *data, const long size );
+    void Start( int x, int y );
+
+  public:
+
+    void ConnectWindow(void);
+    void UnconnectWindow(void);
+    virtual void RegisterWindow(void) = 0;
+    void UnregisterWindow(void);
+  
+    GtkWidget   *m_widget;
+    wxWindow    *m_window;
+    char        *m_data;
+    long         m_size;
+    wxCursor     m_defaultCursor;
+    wxCursor     m_goaheadCursor;
+};
+
+//-------------------------------------------------------------------------
+// wxTextDragSource
+//-------------------------------------------------------------------------
+
+class wxTextDragSource: public wxDragSource
+{
+  public:
+
+    wxTextDragSource( wxWindow *win ) : wxDragSource(win) {};
+    void SetTextData( const wxString &text );
+    void RegisterWindow(void);
+    
+  private:
+  
+    wxString m_tmp;
+};
+
+#endif  
+       //__GTKDNDH__
+
diff --git a/include/wx/gtk1/filedlg.h b/include/wx/gtk1/filedlg.h
new file mode 100644
index 0000000000..665debbe74
--- /dev/null
+++ b/include/wx/gtk1/filedlg.h
@@ -0,0 +1,93 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        filedlg.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKFILEDLGH__
+#define __GTKFILEDLGH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/dialog.h"
+
+//-------------------------------------------------------------------------
+// File selector
+//-------------------------------------------------------------------------
+
+extern const char *wxFileSelectorPromptStr;
+extern const char *wxFileSelectorDefaultWildcardStr;
+
+class wxFileDialog: public wxDialog
+{
+
+  DECLARE_DYNAMIC_CLASS(wxFileDialog)
+  
+  public:
+
+    wxFileDialog() {};
+    
+    wxFileDialog(wxWindow *parent, const wxString& message = wxFileSelectorPromptStr,
+        const wxString& defaultDir = "", const wxString& defaultFile = "", 
+	const wxString& wildCard = wxFileSelectorDefaultWildcardStr,
+        long style = 0, const wxPoint& pos = wxDefaultPosition);
+
+    inline void SetMessage(const wxString& message) { m_message = message; }
+    inline void SetPath(const wxString& path) { m_path = path; }
+    inline void SetDirectory(const wxString& dir) { m_dir = dir; }
+    inline void SetFilename(const wxString& name) { m_fileName = name; }
+    inline void SetWildcard(const wxString& wildCard) { m_wildCard = wildCard; }
+    inline void SetStyle(long style) { m_dialogStyle = style; }
+    inline void SetFilterIndex(int filterIndex) { m_filterIndex = filterIndex; }
+
+    inline wxString GetMessage(void) const { return m_message; }
+    inline wxString GetPath(void) const { return m_path; }
+    inline wxString GetDirectory(void) const { return m_dir; }
+    inline wxString GetFilename(void) const { return m_fileName; }
+    inline wxString GetWildcard(void) const { return m_wildCard; }
+    inline long GetStyle(void) const { return m_dialogStyle; }
+    inline int GetFilterIndex(void) const { return m_filterIndex ; }
+
+    int ShowModal(void);
+    
+  protected:
+  
+    wxString    m_message;
+    long        m_dialogStyle;
+    wxWindow *  m_parent;
+    wxString    m_dir;
+    wxString    m_path; // Full path
+    wxString    m_fileName;
+    wxString    m_wildCard;
+    int         m_filterIndex;
+};
+
+#define wxOPEN 1
+#define wxSAVE 2
+#define wxOVERWRITE_PROMPT 4
+#define wxHIDE_READONLY 8
+
+// File selector - backward compatibility
+
+char* wxFileSelector(const char *message = wxFileSelectorPromptStr, const char *default_path = NULL,
+         const char *default_filename = NULL, const char *default_extension = NULL,
+         const char *wildcard = wxFileSelectorDefaultWildcardStr, int flags = 0,
+         wxWindow *parent = NULL, int x = -1, int y = -1);
+
+char* wxLoadFileSelector(const char *what, const char *extension, const char *default_name = NULL, 
+         wxWindow *parent = NULL);
+
+char* wxSaveFileSelector(const char *what, const char *extension, const char *default_name = NULL, 
+         wxWindow *parent = NULL);
+
+
+
+#endif
+    // __GTKFILEDLGH__
diff --git a/include/wx/gtk1/font.h b/include/wx/gtk1/font.h
new file mode 100644
index 0000000000..619813b17e
--- /dev/null
+++ b/include/wx/gtk1/font.h
@@ -0,0 +1,120 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        font.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKFONTH__
+#define __GTKFONTH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/string.h"
+#include "wx/hash.h"
+#include "wx/gdiobj.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxDC;
+class wxPaintDC;
+class wxWindow;
+
+class wxFont;
+class wxFontNameDirectory;
+
+//-----------------------------------------------------------------------------
+// global variables
+//-----------------------------------------------------------------------------
+
+// extern wxFontNameDirectory wxTheFontNameDirectory;  // defined below
+
+//-----------------------------------------------------------------------------
+// wxFont
+//-----------------------------------------------------------------------------
+
+class wxFont: public wxGDIObject 
+{
+  DECLARE_DYNAMIC_CLASS(wxFont)
+  
+  public:
+    wxFont(void);
+    wxFont( int PointSize, int FontIdOrFamily, int Style, int Weight,
+	   bool underlined = FALSE, const char *Face=NULL );
+    wxFont( int PointSize, const char *Face, int Family, int Style, int Weight, 
+	   bool underlined = FALSE );
+    wxFont( const wxFont& font );
+    wxFont( const wxFont* font );
+    ~wxFont(void);
+    wxFont& operator = ( const wxFont& font );
+    bool operator == ( const wxFont& font );
+    bool operator != ( const wxFont& font );
+    bool Ok();
+
+    int GetPointSize(void) const;
+    wxString GetFaceName(void) const;
+    int GetFamily(void) const;
+    wxString GetFamilyString(void) const;
+    int GetFontId(void) const;
+    wxString GetFaceString(void) const;
+    int GetStyle(void) const;
+    wxString GetStyleString(void) const;
+    int GetWeight(void) const;
+    wxString GetWeightString(void) const;
+    bool GetUnderlined(void) const;
+
+    wxFont( char *xFontName );
+    
+  private:
+  
+    friend wxDC;
+    friend wxPaintDC;
+    friend wxWindow;
+    
+    GdkFont* GetInternalFont(float scale = 1.0);
+
+    // no data :-)
+};
+
+//-----------------------------------------------------------------------------
+// wxFontDirectory
+//-----------------------------------------------------------------------------
+
+class wxFontNameDirectory: public wxObject 
+{
+  DECLARE_DYNAMIC_CLASS(wxFontNameDirectory)
+  
+  public:
+    wxFontNameDirectory(void);
+    ~wxFontNameDirectory();
+
+    void  Initialize(void);
+    void  Initialize(int fontid, int family, const char *name);
+
+    int   FindOrCreateFontId(const char *name, int family);
+    char* GetAFMName(int fontid, int weight, int style);
+    int   GetFamily(int fontid);
+    int   GetFontId(const char *name);
+    char* GetFontName(int fontid);
+    int   GetNewFontId(void);
+    char* GetPostScriptName(int fontid, int weight, int style);
+    char* GetScreenName(int fontid, int weight, int style);
+    
+    
+    class wxHashTable *table;
+    int   nextFontId;
+};
+
+extern wxFontNameDirectory wxTheFontNameDirectory;
+
+#endif // __GTKFONTH__
diff --git a/include/wx/gtk1/frame.h b/include/wx/gtk1/frame.h
new file mode 100644
index 0000000000..aacd0b4274
--- /dev/null
+++ b/include/wx/gtk1/frame.h
@@ -0,0 +1,90 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        frame.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKFRAMEH__
+#define __GTKFRAMEH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/window.h"
+#include "wx/menu.h"
+#include "wx/statusbr.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxRadioBox;
+
+class wxFrame;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxFrameNameStr;
+
+//-----------------------------------------------------------------------------
+// wxFrame
+//-----------------------------------------------------------------------------
+
+class wxFrame: public wxWindow
+{
+  DECLARE_DYNAMIC_CLASS(wxFrame)
+
+  public:
+  
+    wxFrame(void);
+    wxFrame( wxWindow *parent, const wxWindowID id, const wxString &title, 
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = wxDEFAULT_FRAME_STYLE, const wxString &name = wxFrameNameStr );
+    bool Create( wxWindow *parent, const wxWindowID id, const wxString &title,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = wxDEFAULT_FRAME_STYLE, const wxString &name = wxFrameNameStr );
+    ~wxFrame(void);
+    bool Destroy(void);
+    void OnCloseWindow( wxCloseEvent& event );
+    virtual bool Show( const bool show );
+    virtual void Enable( const bool enable );
+    virtual void GetClientSize( int *width, int *height ) const;
+    void OnSize( wxSizeEvent &event );
+    void SetMenuBar( wxMenuBar *menuBar );
+    virtual bool CreateStatusBar( const int number = 1 );
+    virtual void SetStatusText( const wxString &text, const int number = 0 );
+    virtual void SetStatusWidths( const int n, const int *width );
+    wxStatusBar *GetStatusBar(void);
+    wxMenuBar *GetMenuBar(void);
+    void SetTitle( const wxString &title );
+    wxString GetTitle(void) const;
+    void OnActivate( wxActivateEvent &WXUNUSED(event) ) {};
+    
+    void GtkOnSize( int width, int height );
+    
+  private:
+  
+    friend        wxWindow;
+    
+    GtkWidget    *m_mainWindow;
+    wxMenuBar    *m_frameMenuBar;
+    wxStatusBar  *m_frameStatusBar;
+    bool          m_doingOnSize;
+    wxString      m_title;
+    
+    
+  DECLARE_EVENT_TABLE()
+    
+};
+
+#endif // __GTKFRAMEH__
diff --git a/include/wx/gtk1/gauge.h b/include/wx/gtk1/gauge.h
new file mode 100644
index 0000000000..49e031fea2
--- /dev/null
+++ b/include/wx/gtk1/gauge.h
@@ -0,0 +1,34 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        gauge.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKGAUGEH__
+#define __GTKGAUGEH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxGauge;
+
+//-----------------------------------------------------------------------------
+// wxGaugeBox
+//-----------------------------------------------------------------------------
+
+#endif // __GTKGAUGEH__
diff --git a/include/wx/gtk1/gdiobj.h b/include/wx/gtk1/gdiobj.h
new file mode 100644
index 0000000000..2b6a5d1921
--- /dev/null
+++ b/include/wx/gtk1/gdiobj.h
@@ -0,0 +1,37 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        gdiobj.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GDIOBJH__
+#define __GDIOBJH__
+
+#include "wx/object.h"
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+class WXDLLEXPORT wxGDIObject: public wxObject
+{
+DECLARE_DYNAMIC_CLASS(wxGDIObject)
+ public:
+  inline wxGDIObject(void) { m_visible = FALSE; };
+  inline ~wxGDIObject(void) {};
+
+  virtual bool GetVisible(void) { return m_visible; }
+  virtual void SetVisible(bool v) { m_visible = v; }
+
+protected:
+  bool m_visible; // Can a pointer to this object be safely taken?
+                 // - only if created within FindOrCreate...
+};
+
+#endif
+    // __GDIOBJH__
diff --git a/include/wx/gtk1/icon.h b/include/wx/gtk1/icon.h
new file mode 100644
index 0000000000..edb7ab07fe
--- /dev/null
+++ b/include/wx/gtk1/icon.h
@@ -0,0 +1,53 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        icon.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKICONH__
+#define __GTKICONH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/bitmap.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxIcon;
+
+//-----------------------------------------------------------------------------
+// wxIcon
+//-----------------------------------------------------------------------------
+
+class wxIcon: public wxBitmap
+{
+  DECLARE_DYNAMIC_CLASS(wxIcon)
+
+public:
+
+  wxIcon(void) {};
+
+  inline wxIcon(const wxIcon& icon) { Ref(icon); }
+  inline wxIcon(const wxIcon* icon) { if (icon) Ref(*icon); }
+
+  wxIcon( char **bits, const int WXUNUSED(width), const int WXUNUSED(height) ) :
+    wxBitmap( bits ) {};
+    
+  inline wxIcon& operator = (const wxIcon& icon) { if (*this == icon) return (*this); Ref(icon); return *this; }
+  inline bool operator == (const wxIcon& icon) { return m_refData == icon.m_refData; }
+  inline bool operator != (const wxIcon& icon) { return m_refData != icon.m_refData; }
+};
+
+
+#endif // __GTKICONH__
diff --git a/include/wx/gtk1/listbox.h b/include/wx/gtk1/listbox.h
new file mode 100644
index 0000000000..081570556e
--- /dev/null
+++ b/include/wx/gtk1/listbox.h
@@ -0,0 +1,85 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        listbox.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKLISTBOXH__
+#define __GTKLISTBOXH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxListBox;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxListBoxNameStr;
+
+//-----------------------------------------------------------------------------
+// wxListBox
+//-----------------------------------------------------------------------------
+
+class wxListBox: public wxControl
+{
+  DECLARE_DYNAMIC_CLASS(wxListBox)
+
+  public:
+
+    wxListBox(void);
+    wxListBox( wxWindow *parent, wxWindowID id, 
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const int n = 0, const wxString choices[] = NULL,
+      const long style = 0, const wxString &name = wxListBoxNameStr );
+    bool Create( wxWindow *parent, wxWindowID id, 
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const int n = 0, const wxString choices[] = NULL,
+      const long style = 0, const wxString &name = wxListBoxNameStr );
+    void Append( const wxString &item );
+    void Append( const wxString &item, char *clientData );
+    void Clear(void);
+    void Delete( int n );
+    void Deselect( int n );
+    int FindString( const wxString &item ) const;
+    char *GetClientData( const int n ) const;
+    int GetSelection(void) const;
+    int GetSelections( int **selections ) const;
+    wxString GetString( int n ) const;
+    wxString GetStringSelection(void) const;
+    int Number(void);
+    bool Selected( const int n );
+    void Set( const int n, const wxString *choices );
+    void SetClientData( const int n, char *clientData );
+    void SetFirstItem( int n );
+    void SetFirstItem( const wxString &item );
+    void SetSelection( const int n, const bool select = TRUE );
+    void SetString( const int n, const wxString &string );
+    void SetStringSelection( const wxString &string, const bool select = TRUE );
+    
+  private:
+  
+    GtkList   *m_list;
+    
+  public:
+  
+    int GetIndex( GtkWidget *item ) const;
+};
+
+#endif // __GTKLISTBOXH__
diff --git a/include/wx/gtk1/mdi.h b/include/wx/gtk1/mdi.h
new file mode 100644
index 0000000000..ff9181d771
--- /dev/null
+++ b/include/wx/gtk1/mdi.h
@@ -0,0 +1,146 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        mdi.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __MDIH__
+#define __MDIH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+#include "wx/panel.h"
+#include "wx/frame.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxMDIParentFrame;
+class wxMDIClientWindow;
+class wxMDIChildFrame;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char* wxFrameNameStr;
+extern const char* wxStatusLineNameStr;
+
+//-----------------------------------------------------------------------------
+// wxMDIParentFrame
+//-----------------------------------------------------------------------------
+
+class wxMDIParentFrame: public wxFrame
+{
+  DECLARE_DYNAMIC_CLASS(wxMDIParentFrame)
+
+  friend class wxMDIChildFrame;
+  
+  public:
+
+    wxMDIParentFrame(void);
+    wxMDIParentFrame( wxWindow *parent,
+      const wxWindowID id, const wxString& title,
+      const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+      const long style = wxDEFAULT_FRAME_STYLE | wxVSCROLL | wxHSCROLL,
+      const wxString& name = wxFrameNameStr );
+  ~wxMDIParentFrame(void);
+   bool Create( wxWindow *parent,
+      const wxWindowID id, const wxString& title,
+      const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+      const long style = wxDEFAULT_FRAME_STYLE | wxVSCROLL | wxHSCROLL,
+      const wxString& name = wxFrameNameStr );
+
+  void OnSize( wxSizeEvent& event );
+  void OnActivate( wxActivateEvent& event );
+
+  void SetMenuBar( wxMenuBar *menu_bar );
+  void GetClientSize(int *width, int *height) const;
+  wxMDIChildFrame *GetActiveChild(void) const;
+  
+  wxMDIClientWindow *GetClientWindow(void) const; 
+  virtual wxMDIClientWindow *OnCreateClient(void);
+  
+  virtual void Cascade(void) {};
+  virtual void Tile(void) {};
+  virtual void ArrangeIcons(void) {};
+  virtual void ActivateNext(void);
+  virtual void ActivatePrevious(void);
+
+  void OnSysColourChanged(wxSysColourChangedEvent& event);
+    
+ protected:
+    wxMDIClientWindow *             m_clientWindow;
+    wxMDIChildFrame *               m_currentChild;
+    bool                            m_parentFrameActive;
+
+//  DECLARE_EVENT_TABLE()    
+};
+
+//-----------------------------------------------------------------------------
+// wxMDIChildFrame
+//-----------------------------------------------------------------------------
+
+class wxMDIChildFrame: public wxPanel
+{
+  DECLARE_DYNAMIC_CLASS(wxMDIChildFrame)
+  
+  public:
+
+    wxMDIChildFrame(void);
+    wxMDIChildFrame( wxMDIParentFrame *parent,
+      const wxWindowID id, const wxString& title,
+      const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+      const long style = wxDEFAULT_FRAME_STYLE, const wxString& name = wxFrameNameStr );
+    ~wxMDIChildFrame(void);
+    bool Create( wxMDIParentFrame *parent,
+      const wxWindowID id, const wxString& title,
+      const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+      const long style = wxDEFAULT_FRAME_STYLE, const wxString& name = wxFrameNameStr );
+    void SetMenuBar( wxMenuBar *menu_bar );
+
+    // no status bars in wxGTK
+    virtual bool CreateStatusBar( const int WXUNUSED(number) = 1 ) { return FALSE; };
+    virtual void SetStatusText( const wxString &WXUNUSED(text), const int WXUNUSED(number) ) {};
+    virtual void SetStatusWidths( const int WXUNUSED(n), const int *WXUNUSED(width) ) {};
+    
+    virtual void Maximize(void) {};
+    virtual void Restore(void) {};
+    virtual void Activate(void);
+    
+  public:
+  
+    wxString    m_title;
+};
+
+//-----------------------------------------------------------------------------
+// wxMDIClientWindow
+//-----------------------------------------------------------------------------
+
+class wxMDIClientWindow: public wxWindow
+{
+  DECLARE_DYNAMIC_CLASS(wxMDIClientWindow)
+  
+  public:
+  
+    wxMDIClientWindow(void);
+    wxMDIClientWindow( wxMDIParentFrame *parent, const long style = 0 );
+    ~wxMDIClientWindow(void);
+    virtual bool CreateClient( wxMDIParentFrame *parent, const long style = wxVSCROLL | wxHSCROLL );
+    void AddChild( wxWindow *child );
+};
+
+#endif // __MDIH__
+
diff --git a/include/wx/gtk1/menu.h b/include/wx/gtk1/menu.h
new file mode 100644
index 0000000000..7e24c65f6d
--- /dev/null
+++ b/include/wx/gtk1/menu.h
@@ -0,0 +1,107 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        menu.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKMENUH__
+#define __GTKMENUH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/window.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxMenuBar;
+class wxMenuItem;
+class wxMenu;
+
+//-----------------------------------------------------------------------------
+// wxMenuBar
+//-----------------------------------------------------------------------------
+
+class wxMenuBar: public wxWindow
+{
+  DECLARE_DYNAMIC_CLASS(wxMenuBar)
+
+  public:
+
+    wxMenuBar(void);
+    void Append( wxMenu *menu, const wxString &title );
+    int FindMenuItem( const wxString &menuString, const wxString &itemString ) const;
+    
+    wxList       m_menus;
+    GtkWidget   *m_menubar;
+};
+
+//-----------------------------------------------------------------------------
+// wxMenu
+//-----------------------------------------------------------------------------
+
+class wxMenuItem: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxMenuItem)
+
+  public:
+  
+    wxMenuItem(void);
+  
+    int           m_id;
+    wxString      m_text;
+    bool          m_isCheckMenu;
+    bool          m_checked;
+    bool          m_isSubMenu;
+    bool          m_isEnabled;
+    wxMenu       *m_subMenu;
+    wxString      m_helpStr;
+    
+    GtkWidget    *m_menuItem;  // GtkMenuItem
+  
+};
+
+class wxMenu: public wxEvtHandler
+{
+  DECLARE_DYNAMIC_CLASS(wxMenu)
+
+  public:
+
+    wxMenu( const wxString &title = "" );
+    void AppendSeparator(void);
+    void Append( const int id, const wxString &item, 
+      const wxString &helpStr = "", const bool checkable = FALSE );
+    void Append( const int id, const wxString &item, 
+      wxMenu *subMenu, const wxString &helpStr = "" );
+    int FindItem( const wxString itemString ) const;
+    void Break(void) {};
+    void Enable( const int id, const bool enable );
+    bool Enabled( const int id ) const;
+    void SetLabel( const int id, const wxString &label );
+      
+  public:
+      
+    int FindMenuIdByMenuItem( GtkWidget *menuItem ) const;
+    void SetInvokingWindow( wxWindow *win );
+    wxWindow *GetInvokingWindow(void);
+
+    wxString    m_title;
+    wxList      m_items;
+    wxWindow   *m_invokingWindow;
+    
+    GtkWidget  *m_menu;  // GtkMenu
+      
+};
+
+#endif // __GTKMENUH__
diff --git a/include/wx/gtk1/palette.h b/include/wx/gtk1/palette.h
new file mode 100644
index 0000000000..2163e73309
--- /dev/null
+++ b/include/wx/gtk1/palette.h
@@ -0,0 +1,60 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        palette.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKPALETTEH__
+#define __GTKPALETTEH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/gdiobj.h"
+#include "wx/gdicmn.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxPalette;
+
+//-----------------------------------------------------------------------------
+// wxPalette
+//-----------------------------------------------------------------------------
+
+class wxPalette: public wxGDIObject
+{
+  DECLARE_DYNAMIC_CLASS(wxPalette)
+
+  public:
+  
+    wxPalette(void);
+    wxPalette( const int n, const unsigned char *red, const unsigned char *green, const unsigned char *blue );
+    wxPalette( const wxPalette& palette );
+    wxPalette( const wxPalette* palette );
+    ~wxPalette(void);
+    wxPalette& operator = ( const wxPalette& palette );
+    bool operator == ( const wxPalette& palette );
+    bool operator != ( const wxPalette& palette );
+    bool Ok(void) const;
+    
+    bool Create( const int n, const unsigned char *red, const unsigned char *green, const unsigned char *blue);
+    int GetPixel( const unsigned char red, const unsigned char green, const unsigned char blue ) const;
+    bool GetRGB( const int pixel, unsigned char *red, unsigned char *green, unsigned char *blue ) const;
+    
+    // no data
+};
+
+#define wxColorMap wxPalette
+#define wxColourMap wxPalette
+
+#endif // __GTKPALETTEH__
diff --git a/include/wx/gtk1/pen.h b/include/wx/gtk1/pen.h
new file mode 100644
index 0000000000..e3529c6699
--- /dev/null
+++ b/include/wx/gtk1/pen.h
@@ -0,0 +1,68 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        pen.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKPENH__
+#define __GTKPENH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/string.h"
+#include "wx/gdiobj.h"
+#include "wx/gdicmn.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxPen;
+
+//-----------------------------------------------------------------------------
+// wxPen
+//-----------------------------------------------------------------------------
+
+class wxPen: public wxGDIObject
+{
+  DECLARE_DYNAMIC_CLASS(wxPen)
+
+  public:
+  
+    wxPen(void);
+    wxPen( const wxColour &colour, int width, int style );
+    wxPen( const wxString &colourName, int width, int style );
+    wxPen( const wxPen& pen );
+    wxPen( const wxPen* pen );
+    ~wxPen(void);
+    wxPen& operator = ( const wxPen& pen );
+    bool operator == ( const wxPen& pen );
+    bool operator != ( const wxPen& pen );
+    
+    void SetColour( const wxColour &colour );
+    void SetColour( const wxString &colourName );
+    void SetColour( const int red, const int green, const int blue );
+    void SetCap( int capStyle );
+    void SetJoin( int joinStyle );
+    void SetStyle( int style );
+    void SetWidth( int width );
+    wxColour &GetColour(void) const;
+    int GetCap(void) const;
+    int GetJoin(void) const;
+    int GetStyle(void) const;
+    int GetWidth(void) const;
+    bool Ok(void) const;
+    
+    // no data :-)
+};
+
+#endif // __GTKPENH__
diff --git a/include/wx/gtk1/radiobox.h b/include/wx/gtk1/radiobox.h
new file mode 100644
index 0000000000..7282de301c
--- /dev/null
+++ b/include/wx/gtk1/radiobox.h
@@ -0,0 +1,84 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        radiobox.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKRADIOBOXH__
+#define __GTKRADIOBOXH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+#include "wx/bitmap.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxRadioBox;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxRadioBoxNameStr;
+
+//-----------------------------------------------------------------------------
+// wxRadioBox
+//-----------------------------------------------------------------------------
+
+class wxRadioBox: public wxControl
+{
+
+  DECLARE_DYNAMIC_CLASS(wxRadioBox)
+  
+  public:
+  
+    wxRadioBox(void);
+    wxRadioBox( wxWindow *parent, const wxWindowID id, const wxString& title,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const int n = 0, const wxString choices[] = NULL,
+      const int majorDim = 0, const long style = wxRA_HORIZONTAL,
+      const wxString &name = wxRadioBoxNameStr );
+    bool Create( wxWindow *parent, const wxWindowID id, const wxString& title,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const int n = 0, const wxString choices[] = NULL,
+      const int majorDim = 0, const long style = wxRA_HORIZONTAL,
+      const wxString &name = wxRadioBoxNameStr );
+    int FindString( const wxString& s) const;
+    void SetSelection( const int n );
+    int GetSelection(void) const;
+    wxString GetString( const int n ) const;
+    wxString GetLabel(void) const;
+    void SetLabel( const wxString& label );
+    void SetLabel( const int item, const wxString& label );
+    void SetLabel( const int item, wxBitmap *bitmap );
+    wxString GetLabel( const int item ) const;
+    bool Show( const bool show );
+    void Enable( const bool enable );
+    void Enable( const int item, const bool enable );
+    void Show( const int item, const bool show );
+    virtual wxString GetStringSelection(void) const;
+    virtual bool SetStringSelection( const wxString& s );
+    virtual int Number(void) const;
+    int GetNumberOfRowsOrCols(void) const;
+    void SetNumberOfRowsOrCols( const int n );
+    
+  private:
+  
+    GtkRadioButton *m_radio;
+    
+};
+
+#endif // __GTKRADIOBOXH__
diff --git a/include/wx/gtk1/radiobut.h b/include/wx/gtk1/radiobut.h
new file mode 100644
index 0000000000..337264fe5a
--- /dev/null
+++ b/include/wx/gtk1/radiobut.h
@@ -0,0 +1,31 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        radiobut.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKRADIOBUTTONH__
+#define __GTKRADIOBUTTONH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxRadioButton;
+
+
+#endif // __GTKRADIOBUTTONH__
diff --git a/include/wx/gtk1/region.h b/include/wx/gtk1/region.h
new file mode 100644
index 0000000000..282904708a
--- /dev/null
+++ b/include/wx/gtk1/region.h
@@ -0,0 +1,99 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        region.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __REGIONH__
+#define __REGIONH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/list.h"
+#include "wx/gdiobj.h"
+#include "wx/gdicmn.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxRegion;
+
+//-----------------------------------------------------------------------------
+// constants
+//-----------------------------------------------------------------------------
+
+enum wxRegionContain 
+{
+  wxOutRegion = 0, wxPartRegion = 1, wxInRegion = 2
+};
+
+// So far, for internal use only
+enum wxRegionOp {
+wxRGN_AND,          // Creates the intersection of the two combined regions.
+wxRGN_COPY,         // Creates a copy of the region identified by hrgnSrc1.
+wxRGN_DIFF,         // Combines the parts of hrgnSrc1 that are not part of hrgnSrc2.
+wxRGN_OR,           // Creates the union of two combined regions.
+wxRGN_XOR           // Creates the union of two combined regions except for any overlapping areas.
+};
+
+//-----------------------------------------------------------------------------
+// wxRegion
+//-----------------------------------------------------------------------------
+
+class wxRegion : public wxGDIObject 
+{
+  DECLARE_DYNAMIC_CLASS(wxRegion);
+  
+  public:
+  
+    wxRegion( long x, long y, long w, long h );
+    wxRegion( const wxPoint& topLeft, const wxPoint& bottomRight );
+    wxRegion( const wxRect& rect );
+    wxRegion(void);
+    ~wxRegion(void);
+
+    inline wxRegion( const wxRegion& r ) 
+      { Ref(r); }
+    inline wxRegion& operator = ( const wxRegion& r )
+      { Ref(r); return (*this); }
+
+    void Clear(void);
+
+    bool Union( long x, long y, long width, long height );
+    bool Union( const wxRect& rect );
+    bool Union( const wxRegion& region );
+
+    bool Intersect( long x, long y, long width, long height );
+    bool Intersect( const wxRect& rect );
+    bool Intersect( const wxRegion& region );
+
+    bool Subtract( long x, long y, long width, long height );
+    bool Subtract( const wxRect& rect );
+    bool Subtract( const wxRegion& region );
+
+    bool Xor( long x, long y, long width, long height );
+    bool Xor( const wxRect& rect );
+    bool Xor( const wxRegion& region );
+
+    void GetBox( long& x, long& y, long&w, long &h ) const;
+    wxRect GetBox(void) const ;
+
+    bool Empty(void) const;
+
+    wxRegionContain Contains( long x, long y ) const;
+    wxRegionContain Contains( long x, long y, long w, long h ) const;
+    
+  public:
+    
+    GdkRegion *GetRegion(void) const;
+};
+
+#endif
+	// __REGIONH__
diff --git a/include/wx/gtk1/scrolbar.h b/include/wx/gtk1/scrolbar.h
new file mode 100644
index 0000000000..758e3cb18a
--- /dev/null
+++ b/include/wx/gtk1/scrolbar.h
@@ -0,0 +1,82 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        scrolbar.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKSCROLLBARH__
+#define __GTKSCROLLBARH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxScrollBar;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxScrollBarNameStr;
+
+//-----------------------------------------------------------------------------
+// wxScrollBar
+//-----------------------------------------------------------------------------
+
+class wxScrollBar: public wxControl
+{
+  DECLARE_DYNAMIC_CLASS(wxScrollBar)
+
+  public:
+  
+    wxScrollBar(void) { m_adjust = NULL; m_oldPos = 0.0; };
+    wxScrollBar(wxWindow *parent, const wxWindowID id,
+           const wxPoint& pos = wxDefaultPosition,
+           const wxSize& size = wxDefaultSize,
+           const long style = wxSB_HORIZONTAL,
+           const wxString& name = wxScrollBarNameStr );
+    ~wxScrollBar(void);
+    bool Create(wxWindow *parent, const wxWindowID id,
+           const wxPoint& pos = wxDefaultPosition,
+           const wxSize& size = wxDefaultSize,
+           const long style = wxSB_HORIZONTAL,
+           const wxString& name = wxScrollBarNameStr);
+    int GetPosition(void) const;
+    int GetThumbSize() const;
+    int GetPageSize() const;
+    int GetRange() const;
+    virtual void SetPosition( const int viewStart );
+    virtual void SetScrollbar( const int position, const int thumbSize, const int range, const int pageSize,
+      const bool refresh = TRUE );
+
+    // Backward compatibility
+    int GetValue(void) const;
+    void SetValue( const int viewStart );
+    void GetValues( int *viewStart, int *viewLength, int *objectLength, int *pageLength) const;
+    int GetViewLength() const;
+    int GetObjectLength() const;
+    void SetPageSize( const int pageLength );
+    void SetObjectLength( const int objectLength );
+    void SetViewLength( const int viewLength );
+      
+  public:
+  
+    GtkAdjustment  *m_adjust;
+    float           m_oldPos;
+};
+
+#endif
+    // __GTKSCROLLBARH__
diff --git a/include/wx/gtk1/settings.h b/include/wx/gtk1/settings.h
new file mode 100644
index 0000000000..7b801bbb81
--- /dev/null
+++ b/include/wx/gtk1/settings.h
@@ -0,0 +1,40 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        settings.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKSETTINGSH__
+#define __GTKSETTINGSH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/gdicmn.h"
+#include "wx/pen.h"
+#include "wx/font.h"
+
+class WXDLLEXPORT wxSystemSettings: public wxObject
+{
+public:
+    inline wxSystemSettings(void) {}
+
+    // Get a system colour
+    static wxColour    GetSystemColour(int index);
+
+    // Get a system font
+    static wxFont      GetSystemFont(int index);
+
+    // Get a system metric, e.g. scrollbar size
+    static int         GetSystemMetric(int index);
+};
+
+#endif
+    // __GTKSETTINGSH__
diff --git a/include/wx/gtk1/setup.h b/include/wx/gtk1/setup.h
new file mode 100644
index 0000000000..6220819c33
--- /dev/null
+++ b/include/wx/gtk1/setup.h
@@ -0,0 +1,534 @@
+/* include/wx/gtk/setup.h.  Generated automatically by configure.  */
+/* wx_setup.h
+   This file is in the public domain.
+
+   Descriptive text for the C preprocessor macros that
+   the distributed Autoconf macros can define.
+   No software package will use all of them; autoheader copies the ones
+   your configure.in uses into your configuration header file templates.
+
+   The entries are in sort -df order: alphabetical, case insensitive,
+   ignoring punctuation (such as underscores).  Although this order
+   can split up related entries, it makes it easier to check whether
+   a given entry is in the file.
+
+   Leave the following blank line there!!  Autoheader needs it.  */
+
+#ifndef __GTKSETUPH__
+#define __GTKSETUPH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+/* define the system to compile */
+#define __GTK__ 1
+#define __UNIX__ 1
+#define __LINUX__ 1
+/* #undef __SGI__ */
+/* #undef __HPUX__ */
+/* #undef __SYSV__ */
+/* #undef __SVR4__ */
+/* #undef __AIX__ */
+/* #undef __SUN__ */
+/* #undef __SOLARIS__ */
+/* #undef __SUNOS__ */
+/* #undef __ALPHA__ */
+/* #undef __OSF__ */
+/* #undef __BSD__ */
+/* #undef __FREEBSD__ */
+/* #undef __VMS__ */
+/* #undef __ULTRIX__ */
+/* #undef __DATA_GENERAL__ */
+
+/*
+ * Use zlib
+ */
+#define USE_ZLIB 1
+/*
+ * Use gdk_imlib
+ */
+#define USE_GDK_IMLIB 1
+/*
+ * Use libpng
+ */
+#define USE_LIBPNG 1
+/*
+ * Use Threads
+ */
+/* #undef USE_THREADS */
+/* #undef USE_THREADS_POSIX */
+/* #undef USE_THREADS_SGI */
+/*
+ * Use storable classes
+ */
+#define USE_STORABLE_CLASSES 1
+/*
+ * Use automatic translation via gettext() in wxTString
+ */
+#define USE_AUTOTRANS 1
+/*
+ * Use font metric files in GetTextExtent for wxPostScriptDC
+ * Use consistent PostScript fonts for AFM and printing (!)
+ */
+#define USE_AFM_FOR_POSTSCRIPT 1
+#define WX_NORMALIZED_PS_FONTS 1
+/*
+ * Use clipboard
+ */
+/* #undef USE_CLIPBOARD */
+/*
+ * Use wxWindows layout constraint system
+ */
+#define USE_CONSTRAINTS 1
+/*
+ * Use the document/view architecture
+ */
+#define USE_DOC_VIEW_ARCHITECTURE 1
+/*
+ * Use enhanced dialog
+ */
+/* #undef USE_ENHANCED_DIALOG */
+/*
+ * Use Form panel item placement
+ */
+/* #undef USE_FORM */
+/*
+ * Use fraction class
+ */
+#define USE_FRACTION 1
+/*
+ * Use gauge item
+ */
+#define USE_GAUGE 1
+/*
+ * Implement a GLCanvas class as an interface to OpenGL, using the GLX
+ * extension to the X11 protocol.  You can use the (free) Mesa library
+ * if you don't have a 'real' OpenGL.
+ */
+#define USE_GLX 0
+/*
+ * Use wxWindows help facility (needs USE_IPC 1)
+ */
+/* #undef USE_HELP */
+/*
+ * Use iostream.h rather than iostream
+ */
+#define USE_IOSTREAMH 1
+/*
+ * Use Interprocess communication
+ */
+#define USE_IPC 1
+/*
+ * Use Metafile and Metafile device context
+ */
+/* #undef USE_METAFILE */
+/*
+ * Use PostScript device context
+ */
+#define USE_POSTSCRIPT 1
+/*
+ * Use the print/preview architecture
+ */
+#define USE_PRINTING_ARCHITECTURE 1
+/*
+ * Use Prolog IO
+ */
+/* #undef USE_PROLOGIO */
+/*
+ * Use Remote Procedure Call (Needs USE_IPC and USE_PROLOGIO)
+ */
+/* #undef USE_RPC */
+/*
+ * Use wxGetResource & wxWriteResource (change .Xdefaults)
+ */
+#define USE_RESOURCES 1
+/*
+ * Use scrollbar item
+ */
+#define USE_SCROLLBAR 1
+/*
+ * Use time and date classes
+ */
+#define USE_TIMEDATE 1
+/*
+ * Use toolbar, use Xt port toolbar (3D look)
+ */
+#define USE_TOOLBAR 1
+#define USE_XT_TOOLBAR 
+/*
+ * Enables old type checking mechanism (wxSubType)
+ */
+/* #undef USE_TYPETREE */
+/*
+ * Use virtual list box item
+ */
+/* #undef USE_VLBOX */
+/*
+ * Use wxWindows resource loading (.wxr-files) (Needs USE_PROLOGIO 1)
+ */
+#define USE_WX_RESOURCES 1
+/*
+ * Use wxGraph
+ */
+/* #undef USE_WXGRAPH */
+/*
+ * Use wxTree
+ */
+
+/********************** DO NOT CHANGE BELOW THIS POINT **********************/
+
+/**************************** DEBUGGING FEATURES ****************************/
+
+/* Compatibility with 1.66 API.
+   Level 0: no backward compatibility, all new features
+   Level 1: wxDC, OnSize (etc.) compatibility, but
+   some new features such as event tables */
+#define WXWIN_COMPATIBILITY  1
+/*
+ * Enables debugging: memory tracing, assert, etc.
+ */
+/* #undef DEBUG */
+/*
+ * Enables debugging version of wxObject::new and wxObject::delete (IF DEBUG)
+ * WARNING: this code may not work with all architectures, especially
+ * if alignment is an issue.
+ */
+/* #undef USE_MEMORY_TRACING */
+/*
+ * Enable debugging version of global memory operators new and delete
+ * Disable it, If this causes problems (e.g. link errors)
+ */
+/* #undef USE_GLOBAL_MEMORY_OPERATORS */
+/*
+ * If WXDEBUG && USE_MEMORY_TRACING && USE_GLOBAL_MEMORY_OPERATORS
+ * used to debug the memory allocation of wxWindows Xt port code
+ */
+#define USE_INTERNAL_MEMORY_TRACING 0
+/*
+ * Matthews garbage collection (used for MrEd?)
+ */
+#define WXGARBAGE_COLLECTION_ON 0
+
+/**************************** COMPILER FEATURES *****************************/
+
+/*
+ * Disable this if your compiler can't cope
+ * with omission of prototype parameters.
+ */
+#define REMOVE_UNUSED_ARG 1
+/*
+ * The const keyword is being introduced more in wxWindows.
+ * You can use this setting to maintain backward compatibility.
+ * If 0:	will use const wherever possible.
+ * If 1:	will use const only where necessary
+ *              for precompiled headers to work.
+ * If 2:	will be totally backward compatible, but precompiled
+ *	headers may not work and program size will be larger.
+ */
+#define CONST_COMPATIBILITY 0
+
+/************************ WINDOWS 3.1 COMPATIBILITY *************************/
+
+/*
+ * Normalize X drawing code to behave exactly as MSW.
+ */
+#define WX_STANDARD_GRAPHICS 0
+
+/******************* other stuff **********************************/
+/*
+ * Support image loading for wxBitmap (wxImage is needed for this)
+ */
+#define USE_IMAGE_LOADING 0
+#define WXIMAGE_INCLUDE "../../utils/image/src/wx_image.h"
+/*
+ * Use splines
+ */
+#define USE_SPLINES 1
+
+/*
+ * USE_DYNAMIC_CLASSES is TRUE for the Xt port
+ */
+#define USE_DYNAMIC_CLASSES 1
+/*
+ * USE_EXTENDED_STATICS is FALSE for the Xt port
+*/
+#define USE_EXTENDED_STATICS 0
+
+/*************************** IMAKEFILE EVALUATIOS ***************************/
+
+#if USE_XPM
+	#define USE_XPM_IN_X 1
+#else
+	#define USE_XPM_IN_X 0
+#endif
+#if USE_IMAGE_LOADING
+	#define USE_IMAGE_LOADING_IN_X 1
+#else
+	#define USE_IMAGE_LOADING_IN_X 0
+#endif
+
+/* here comes the system-specific stuff */
+
+/* acconfig.h
+   This file is in the public domain.
+
+   Descriptive text for the C preprocessor macros that
+   the distributed Autoconf macros can define.
+   No software package will use all of them; autoheader copies the ones
+   your configure.in uses into your configuration header file templates.
+
+   The entries are in sort -df order: alphabetical, case insensitive,
+   ignoring punctuation (such as underscores).  Although this order
+   can split up related entries, it makes it easier to check whether
+   a given entry is in the file. */
+
+/* Define if on AIX 3.
+   System headers sometimes define this.
+   We just want to avoid a redefinition error message.  */
+#ifndef _ALL_SOURCE
+/* #undef _ALL_SOURCE */
+#endif
+
+/* Define if using alloca.c.  */
+/* #undef C_ALLOCA */
+
+/* Define if type char is unsigned and you are not using gcc.  */
+#ifndef __CHAR_UNSIGNED__
+/* #undef __CHAR_UNSIGNED__ */
+#endif
+
+/* Define if the closedir function returns void instead of int.  */
+/* #undef CLOSEDIR_VOID */
+
+/* Define to empty if the keyword does not work.  */
+/* #undef const */
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+   This function is required for alloca.c support on those systems.  */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define for DGUX with <sys/dg_sys_info.h>.  */
+/* #undef DGUX */
+
+/* Define if you have <dirent.h>.  */
+/* #undef DIRENT */
+
+/* Define to the type of elements in the array set by `getgroups'.
+   Usually this is either `int' or `gid_t'.  */
+#define GETGROUPS_T gid_t
+
+/* Define if the `getloadavg' function needs to be run setuid or setgid.  */
+/* #undef GETLOADAVG_PRIVILEGED */
+
+/* Define if the `getpgrp' function takes no argument.  */
+/* #undef GETPGRP_VOID */
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+/* #undef gid_t */
+
+/* Define if you have alloca, as a function or macro.  */
+/* #undef HAVE_ALLOCA */
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix).  */
+/* #undef HAVE_ALLOCA_H */
+
+/* Define if you don't have vprintf but do have _doprnt.  */
+/* #undef HAVE_DOPRNT */
+
+/* Define if your system has its own `getloadavg' function.  */
+/* #undef HAVE_GETLOADAVG */
+
+/* Define if you have the getmntent function.  */
+/* #undef HAVE_GETMNTENT */
+
+/* Define if the `long double' type works.  */
+#define HAVE_LONG_DOUBLE 1
+
+/* Define if you support file names longer than 14 characters.  */
+#define HAVE_LONG_FILE_NAMES 1
+
+/* Define if you have a working `mmap' system call.  */
+/* #undef HAVE_MMAP */
+
+/* Define if system calls automatically restart after interruption
+   by a signal.  */
+/* #undef HAVE_RESTARTABLE_SYSCALLS */
+
+/* Define if your struct stat has st_blksize.  */
+#define HAVE_ST_BLKSIZE 1
+
+/* Define if your struct stat has st_blocks.  */
+#define HAVE_ST_BLOCKS 1
+
+/* Define if you have the strcoll function and it is properly defined.  */
+/* #undef HAVE_STRCOLL */
+
+/* Define if your struct stat has st_rdev.  */
+#define HAVE_ST_RDEV 1
+
+/* Define if you have the strftime function.  */
+/* #undef HAVE_STRFTIME */
+
+/* Define if you have <sys/wait.h> that is POSIX.1 compatible.  */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define if your struct tm has tm_zone.  */
+/* #undef HAVE_TM_ZONE */
+
+/* Define if you don't have tm_zone but do have the external array
+   tzname.  */
+#define HAVE_TZNAME 1
+
+/* Define if you have <unistd.h>.  */
+/* #undef HAVE_UNISTD_H */
+
+/* Define if utime(file, NULL) sets file's timestamp to the present.  */
+/* #undef HAVE_UTIME_NULL */
+
+/* Define if you have <vfork.h>.  */
+/* #undef HAVE_VFORK_H */
+
+/* Define if you have the vprintf function.  */
+/* #undef HAVE_VPRINTF */
+
+/* Define if you have the wait3 system call.  */
+/* #undef HAVE_WAIT3 */
+
+/* Define as __inline if that's what the C compiler calls it.  */
+#ifndef __cplusplus
+/* #undef inline */
+#endif
+
+/* Define if major, minor, and makedev are declared in <mkdev.h>.  */
+/* #undef MAJOR_IN_MKDEV */
+
+/* Define if major, minor, and makedev are declared in <sysmacros.h>.  */
+/* #undef MAJOR_IN_SYSMACROS */
+
+/* Define if on MINIX.  */
+/* #undef _MINIX */
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+/* #undef mode_t */
+
+/* Define if you don't have <dirent.h>, but have <ndir.h>.  */
+/* #undef NDIR */
+
+/* Define if you have <memory.h>, and <string.h> doesn't declare the
+   mem* functions.  */
+/* #undef NEED_MEMORY_H */
+
+/* Define if your struct nlist has an n_un member.  */
+/* #undef NLIST_NAME_UNION */
+
+/* Define if you have <nlist.h>.  */
+/* #undef NLIST_STRUCT */
+
+/* Define if your C compiler doesn't accept -c and -o together.  */
+/* #undef NO_MINUS_C_MINUS_O */
+
+/* Define to `long' if <sys/types.h> doesn't define.  */
+/* #undef off_t */
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+/* #undef pid_t */
+
+/* Define if the system does not provide POSIX.1 features except
+   with this defined.  */
+/* #undef _POSIX_1_SOURCE */
+
+/* Define if you need to in order for stat and other things to work.  */
+/* #undef _POSIX_SOURCE */
+
+/* Define as the return type of signal handlers (int or void).  */
+#define RETSIGTYPE void
+
+/* Define if the setvbuf function takes the buffering type as its second
+   argument and the buffer pointer as the third, as on System V
+   before release 3.  */
+/* #undef SETVBUF_REVERSED */
+
+/* Define SIZESOF for some Objects  */
+#define SIZEOF_INT 4
+#define SIZEOF_INT_P 4
+#define SIZEOF_LONG 4
+
+/* Define to `unsigned' if <sys/types.h> doesn't define.  */
+/* #undef size_t */
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at run-time.
+	STACK_DIRECTION > 0 => grows toward higher addresses
+	STACK_DIRECTION < 0 => grows toward lower addresses
+	STACK_DIRECTION = 0 => direction of growth unknown
+ */
+/* #undef STACK_DIRECTION */
+
+/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly.  */
+/* #undef STAT_MACROS_BROKEN */
+
+/* Define if you have the ANSI C header files.  */
+#define STDC_HEADERS 1
+
+/* Define on System V Release 4.  */
+/* #undef SVR4 */
+
+/* Define on BSD  */
+/* #undef BSD */
+
+/* Define on System V */
+/* #undef SYSV */
+
+/* Define if you don't have <dirent.h>, but have <sys/dir.h>.  */
+/* #undef SYSDIR */
+
+/* Define if you don't have <dirent.h>, but have <sys/ndir.h>.  */
+/* #undef SYSNDIR */
+
+/* Define if `sys_siglist' is declared by <signal.h>.  */
+/* #undef SYS_SIGLIST_DECLARED */
+
+/* Define if you can safely include both <sys/time.h> and <time.h>.  */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define if your <sys/time.h> declares struct tm.  */
+/* #undef TM_IN_SYS_TIME */
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+/* #undef uid_t */
+
+/* Define for Encore UMAX.  */
+/* #undef UMAX */
+
+/* Define for Encore UMAX 4.3 that has <inq_status/cpustats.h>
+   instead of <sys/cpustats.h>.  */
+/* #undef UMAX4_3 */
+
+/* Define if you do not have <strings.h>, index, bzero, etc..  */
+/* #undef USG */
+
+/* Define if the system is System V Release 4 */
+/* #undef SVR4 */
+
+/* Define vfork as fork if vfork does not work.  */
+/* #undef vfork */
+
+/* Define if the closedir function returns void instead of int.  */
+/* #undef VOID_CLOSEDIR */
+
+/* Define if your processor stores words with the most significant
+   byte first (like Motorola and SPARC, unlike Intel and VAX).  */
+/* #undef WORDS_BIGENDIAN */
+
+/* Define if lex declares yytext as a char * by default, not a char[].  */
+#define YYTEXT_POINTER 1
+
+#endif /* __GTKSETUPH__ */
+
+
+/* Leave that blank line there!!  Autoheader needs it.
+   If you're adding to this file, keep in mind:
+   The entries are in sort -df order: alphabetical, case insensitive,
+   ignoring punctuation (such as underscores).  */
diff --git a/include/wx/gtk1/slider.h b/include/wx/gtk1/slider.h
new file mode 100644
index 0000000000..a983248fed
--- /dev/null
+++ b/include/wx/gtk1/slider.h
@@ -0,0 +1,91 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        slider.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKSLIDERH__
+#define __GTKSLIDERH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxSlider;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxSliderNameStr;
+
+//-----------------------------------------------------------------------------
+// wxSlider
+//-----------------------------------------------------------------------------
+
+class wxSlider: public wxControl
+{
+  DECLARE_DYNAMIC_CLASS(wxSlider)
+
+  public:
+    wxSlider(void);
+    wxSlider( wxWindow *parent, const wxWindowID id,
+           const int value, const int minValue, const int maxValue,
+           const wxPoint& pos = wxDefaultPosition,
+           const wxSize& size = wxDefaultSize,
+           const long style = wxSL_HORIZONTAL,
+/*           const wxValidator& validator = wxDefaultValidator, */
+           const wxString& name = wxSliderNameStr);
+   ~wxSlider(void);
+   bool Create(wxWindow *parent, const wxWindowID id,
+           const int value, const int minValue, const int maxValue,
+           const wxPoint& pos = wxDefaultPosition,
+           const wxSize& size = wxDefaultSize,
+           const long style = wxSL_HORIZONTAL,
+/*           const wxValidator& validator = wxDefaultValidator, */
+           const wxString& name = wxSliderNameStr);
+    virtual int GetValue(void) const;
+    virtual void SetValue( const int );
+    void GetSize( int *x, int *y ) const;
+    void SetSize( const int x, const int y, const int width, const int height, const int sizeFlags = wxSIZE_AUTO );
+    void GetPosition( int *x, int *y ) const;
+    void SetRange( const int minValue, const int maxValue );
+    int GetMin(void) const;
+    int GetMax(void) const;
+    void SetTickFreq( const int n, const int pos );
+    int GetTickFreq(void) const;
+    void SetPageSize( const int pageSize );
+    int GetPageSize(void) const;
+    void ClearSel(void);
+    void ClearTicks(void);
+    void SetLineSize( const int lineSize );
+    int GetLineSize(void) const;
+    int GetSelEnd(void) const;
+    int GetSelStart(void) const;
+    void SetSelection( const int minPos, const int maxPos );
+    void SetThumbLength( const int len );
+    int GetThumbLength(void) const;
+    void SetTick( const int tickPos );
+
+  public:
+  
+    GtkAdjustment  *m_adjust;
+    float           m_oldPos;
+    
+};
+
+#endif // __GTKSLIDERH__
diff --git a/include/wx/gtk1/statbmp.h b/include/wx/gtk1/statbmp.h
new file mode 100644
index 0000000000..d6731e42d6
--- /dev/null
+++ b/include/wx/gtk1/statbmp.h
@@ -0,0 +1,34 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        statbmp.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKSTATICBITMAPH__
+#define __GTKSTATICBITMAPH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxStaticBitmap;
+
+//-----------------------------------------------------------------------------
+// wxStaticBitmap
+//-----------------------------------------------------------------------------
+
+#endif // __GTKSTATICBITMAPH__
diff --git a/include/wx/gtk1/statbox.h b/include/wx/gtk1/statbox.h
new file mode 100644
index 0000000000..a260d4f05e
--- /dev/null
+++ b/include/wx/gtk1/statbox.h
@@ -0,0 +1,55 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        stabox.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKSTATICBOXH__
+#define __GTKSTATICBOXH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxStaticBox;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxStaticBoxNameStr;
+
+//-----------------------------------------------------------------------------
+// wxStaticBox
+//-----------------------------------------------------------------------------
+
+class wxStaticBox: public wxControl
+{
+  DECLARE_DYNAMIC_CLASS(wxStaticBox)
+
+  public:
+
+    wxStaticBox(void);
+    wxStaticBox( wxWindow *parent, wxWindowID id, const wxString &label, 
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = wxStaticBoxNameStr  );
+    bool Create( wxWindow *parent, wxWindowID id, const wxString &label, 
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = wxStaticBoxNameStr  );
+};
+
+#endif // __GTKSTATICBOXH__
diff --git a/include/wx/gtk1/stattext.h b/include/wx/gtk1/stattext.h
new file mode 100644
index 0000000000..12d8d6995e
--- /dev/null
+++ b/include/wx/gtk1/stattext.h
@@ -0,0 +1,57 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        stattext.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKSTATICTEXTH__
+#define __GTKSTATICTEXTH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxStaticText;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxStaticTextNameStr;
+
+//-----------------------------------------------------------------------------
+// wxStaticText
+//-----------------------------------------------------------------------------
+
+class wxStaticText: public wxControl
+{
+  DECLARE_DYNAMIC_CLASS(wxStaticText)
+
+  public:
+
+    wxStaticText(void);
+    wxStaticText( wxWindow *parent, wxWindowID id, const wxString &label,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = wxStaticTextNameStr );
+    bool Create(  wxWindow *parent, wxWindowID id, const wxString &label,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = wxStaticTextNameStr );
+    wxString GetLabel(void) const;
+    void SetLabel( const wxString &label );
+};
+
+#endif // __GTKSTATICTEXTH__
diff --git a/include/wx/gtk1/tbargtk.h b/include/wx/gtk1/tbargtk.h
new file mode 100644
index 0000000000..adb04a56f0
--- /dev/null
+++ b/include/wx/gtk1/tbargtk.h
@@ -0,0 +1,139 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        tbargtk.h
+// Purpose:     GTK toolbar
+// Author:      Robert Roebling
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Robert Roebling
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __TBARGTKH__
+#define __TBARGTKH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxToolBarTool;
+class wxToolBarGTK;
+
+//-----------------------------------------------------------------------------
+// constants
+//-----------------------------------------------------------------------------
+
+#define wxTOOL_STYLE_BUTTON          1
+#define wxTOOL_STYLE_SEPARATOR       2
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxToolBarNameStr;
+
+//-----------------------------------------------------------------------------
+// wxToolBarTool
+//-----------------------------------------------------------------------------
+
+class wxToolBarTool: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxToolBarTool)
+  
+  public:
+
+    wxToolBarTool(void) {}; 
+    wxToolBarTool( wxToolBarGTK *owner, const int theIndex = 0, 
+      const wxBitmap& bitmap1 = wxNullBitmap, const wxBitmap& bitmap2 = wxNullBitmap, 
+      const bool toggle = FALSE, wxObject *clientData = NULL, 
+      const wxString& shortHelpString = "", const wxString& longHelpString = "");
+   ~wxToolBarTool(void);
+
+  public:
+  
+    int                   m_toolStyle;
+    wxObject             *m_clientData;
+    int                   m_index;
+    bool                  m_toggleState;
+    bool                  m_isToggle;
+    bool                  m_deleteSecondBitmap;
+    bool                  m_enabled;
+    wxBitmap              m_bitmap1;
+    wxBitmap              m_bitmap2;
+    bool                  m_isMenuCommand;
+    wxString              m_shortHelpString;
+    wxString              m_longHelpString;
+    wxToolBarGTK         *m_owner;
+};
+
+//-----------------------------------------------------------------------------
+// wxToolBarGTK
+//-----------------------------------------------------------------------------
+
+class wxToolBarGTK: public wxControl
+{
+  DECLARE_DYNAMIC_CLASS(wxToolBarGTK)
+  
+  public:
+
+    wxToolBarGTK(void);
+    wxToolBarGTK( wxWindow *parent, const wxWindowID id, 
+      const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+      const long style = 0, const wxString& name = wxToolBarNameStr );
+   ~wxToolBarGTK(void);
+
+   bool Create( wxWindow *parent, const wxWindowID id, 
+     const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+     const long style = 0, const wxString& name = wxToolBarNameStr);
+
+    // Only allow toggle if returns TRUE. Call when left button up.
+    virtual bool OnLeftClick(int toolIndex, bool toggleDown);
+
+    // Call when right button down.
+    virtual void OnRightClick(int toolIndex, float x, float y);
+
+    // Called when the mouse cursor enters a tool bitmap.
+    // Argument is -1 if mouse is exiting the toolbar.
+    virtual void OnMouseEnter(int toolIndex);
+
+    // If pushedBitmap is NULL, a reversed version of bitmap is
+    // created and used as the pushed/toggled image.
+    // If toggle is TRUE, the button toggles between the two states.
+    virtual wxToolBarTool *AddTool( const int toolIndex, const wxBitmap& bitmap, 
+      const wxBitmap& pushedBitmap = wxNullBitmap, const bool toggle = FALSE,
+      const float xPos = -1, const float yPos = -1, wxObject *clientData = NULL,
+      const wxString& helpString1 = "", const wxString& helpString2 = "");
+    virtual void AddSeparator(void);
+    virtual void ClearTools(void);
+
+    virtual void EnableTool(const int toolIndex, const bool enable);
+    virtual void ToggleTool(const int toolIndex, const bool toggle); // toggle is TRUE if toggled on
+    virtual void SetToggle(const int toolIndex, const bool toggle); // Set this to be togglable (or not)
+    virtual wxObject *GetToolClientData(const int index) const;
+
+    virtual bool GetToolState(const int toolIndex) const;
+    virtual bool GetToolEnabled(const int toolIndex) const;
+
+    virtual void SetMargins(const int x, const int y);
+    void SetMargins(const wxSize& size) { SetMargins(size.x, size.y); };
+    virtual void SetToolPacking(const int packing);
+    virtual void SetToolSeparation(const int separation);
+  
+  public:
+  
+    GtkToolbar   *m_toolbar;
+    wxList        m_tools;
+  
+  DECLARE_EVENT_TABLE()
+};
+
+#endif
+    // __TBARGTKH__
+
diff --git a/include/wx/gtk1/textctrl.h b/include/wx/gtk1/textctrl.h
new file mode 100644
index 0000000000..0222373fe2
--- /dev/null
+++ b/include/wx/gtk1/textctrl.h
@@ -0,0 +1,106 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        textctrl.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKTEXTCTRLH__
+#define __GTKTEXTCTRLH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/string.h"
+#include "wx/control.h"
+
+#if USE_IOSTREAMH
+#include <iostream.h>
+#else
+#include <iostream>
+#endif
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxTextCtrl;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxTextCtrlNameStr;
+
+//-----------------------------------------------------------------------------
+//  wxTextCtrl
+//-----------------------------------------------------------------------------
+
+class wxTextCtrl: public wxControl, public streambuf
+{
+  DECLARE_DYNAMIC_CLASS(wxTextCtrl);
+
+  public:
+  
+    wxTextCtrl(void);
+    wxTextCtrl( wxWindow *parent, const wxWindowID id, const wxString &value = "", 
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const int style = 0, const wxString &name = wxTextCtrlNameStr );
+    bool Create( wxWindow *parent, const wxWindowID id, const wxString &value = "", 
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const int style = 0, const wxString &name = wxTextCtrlNameStr );
+    wxString GetValue(void) const;
+    void SetValue( const wxString &value );
+    void WriteText( const wxString &text );
+/*
+    wxString GetLineText( const long lineNo ) const;
+    bool LoadFile( const wxString &file );
+    bool SaveFile( const wxString &file );
+    void DiscardEdits(void);
+    bool IsModified(void);
+    void OnDropFiles( wxDropFilesEvent &event );
+    long PositionToXY( const long pos, long *x, long *y ) const;
+    long XYToPosition( const long x, const long y );
+    int GetNumberOfLines(void);
+*/
+    virtual void SetInsertionPoint( const long pos );
+    virtual void SetInsertionPointEnd(void);
+    virtual void SetEditable( const bool editable );
+    virtual void SetSelection( const long from, const long to );
+    void ShowPosition( const long pos );
+    virtual long GetInsertionPoint(void) const;
+    virtual long GetLastPosition(void) const;
+    virtual void Remove( const long from, const long to );
+    virtual void Replace( const long from, const long to, const wxString &value );
+    void Cut(void);
+    void Copy(void);
+    void Paste(void);
+    void Delete(void);
+    
+    void OnChar( wxKeyEvent &event );
+    
+    int overflow(int i);
+    int sync(void);
+    int underflow(void);
+
+    wxTextCtrl& operator<<(const wxString& s);
+    wxTextCtrl& operator<<(const int i);
+    wxTextCtrl& operator<<(const long i);
+    wxTextCtrl& operator<<(const float f);
+    wxTextCtrl& operator<<(const double d);
+    wxTextCtrl& operator<<(const char c);
+
+  DECLARE_EVENT_TABLE()
+    
+};
+
+#endif // __GTKTEXTCTRLH__
+
+
diff --git a/include/wx/gtk1/timer.h b/include/wx/gtk1/timer.h
new file mode 100644
index 0000000000..821c03b30d
--- /dev/null
+++ b/include/wx/gtk1/timer.h
@@ -0,0 +1,53 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        timer.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKTIMERH__
+#define __GTKTIMERH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+
+//-----------------------------------------------------------------------------
+// derived classes
+//-----------------------------------------------------------------------------
+
+class wxTimer;
+
+//-----------------------------------------------------------------------------
+// wxTimer
+//-----------------------------------------------------------------------------
+
+class wxTimer: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxTimer)
+
+  public:
+
+    wxTimer(void);
+    ~wxTimer(void);
+    int Interval(void);
+    bool OneShot(void);
+    virtual void Notify(void);
+    void Start( int millisecs = -1, bool oneShot = FALSE );
+    void Stop(void);
+    
+  private:
+  
+    int  m_tag;
+    int  m_time;
+    bool m_oneShot;
+};
+
+#endif // __GTKTIMERH__
diff --git a/include/wx/gtk1/win_gtk.h b/include/wx/gtk1/win_gtk.h
new file mode 100644
index 0000000000..6bc8e3ea11
--- /dev/null
+++ b/include/wx/gtk1/win_gtk.h
@@ -0,0 +1,75 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        win_gtk.h
+// Purpose:     wxWindows's GTK base widget
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTK_MYFIXED_H__
+#define __GTK_MYFIXED_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkcontainer.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_MYFIXED(obj)          GTK_CHECK_CAST (obj, gtk_myfixed_get_type (), GtkMyFixed)
+#define GTK_MYFIXED_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_myfixed_get_type (), GtkMyFixedClass)
+#define GTK_IS_MYFIXED(obj)       GTK_CHECK_TYPE (obj, gtk_myfixed_get_type ())
+
+
+typedef struct _GtkMyFixed        GtkMyFixed;
+typedef struct _GtkMyFixedClass   GtkMyFixedClass;
+typedef struct _GtkMyFixedChild   GtkMyFixedChild;
+
+struct _GtkMyFixed
+{
+  GtkContainer container;
+
+  GList *children;
+  
+  gint16  scroll_offset_x;
+  gint16  scroll_offset_y;
+};
+
+struct _GtkMyFixedClass
+{
+  GtkContainerClass parent_class;
+};
+
+struct _GtkMyFixedChild
+{
+  GtkWidget *widget;
+  gint16 x;
+  gint16 y;
+};
+
+guint      gtk_myfixed_get_type        (void);
+GtkWidget* gtk_myfixed_new             (void);
+void       gtk_myfixed_set_offset      (GtkMyFixed     *myfixed,
+                                        gint16         x,
+                                        gint16         y);
+void       gtk_myfixed_put             (GtkMyFixed     *myfixed,
+                                        GtkWidget      *widget,
+                                        gint16         x,
+                                        gint16         y);
+void       gtk_myfixed_move            (GtkMyFixed     *myfixed,
+                                        GtkWidget      *widget,
+                                        gint16         x,
+                                        gint16         y);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_MYFIXED_H__ */
diff --git a/include/wx/gtk1/window.h b/include/wx/gtk1/window.h
new file mode 100644
index 0000000000..40fbc48706
--- /dev/null
+++ b/include/wx/gtk1/window.h
@@ -0,0 +1,262 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        window.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __GTKWINDOWH__
+#define __GTKWINDOWH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/event.h"
+#include "wx/validate.h"
+#include "wx/cursor.h"
+#include "wx/font.h"
+#include "wx/dc.h"
+#include "wx/region.h"
+#include "wx/dnd.h"
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxFrameNameStr;
+extern wxList wxTopLevelWindows;
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxLayoutConstraints;
+class wxSizer;
+
+class wxWindow;
+class wxCanvas;
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+extern const char *wxPanelNameStr;
+extern const wxSize wxDefaultSize;
+extern const wxPoint wxDefaultPosition;
+
+//-----------------------------------------------------------------------------
+// wxWindow
+//-----------------------------------------------------------------------------
+
+class wxWindow: public wxEvtHandler
+{
+  DECLARE_DYNAMIC_CLASS(wxWindow)
+
+  public:
+  
+    wxWindow(void);
+    wxWindow( wxWindow *parent, const wxWindowID id,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = wxPanelNameStr );
+    bool Create( wxWindow *parent, const wxWindowID id,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = 0, const wxString &name = wxPanelNameStr );
+    virtual ~wxWindow(void);
+    bool Close( const bool force = FALSE );
+    virtual bool Destroy(void);
+    virtual bool DestroyChildren(void);
+    
+    virtual void PrepareDC( wxDC &dc );
+    
+    virtual void SetSize( const int x, const int y, const int width, const int height, 
+      const int sizeFlags = wxSIZE_AUTO );
+    virtual void SetSize( const int width, const int height );
+    virtual void Move( const int x, const int y );
+    virtual void GetSize( int *width, int *height ) const;
+    virtual void SetClientSize( int const width, int const height );
+    virtual void GetClientSize( int *width, int *height ) const;
+    virtual void GetPosition( int *x, int *y ) const;
+    virtual void Centre( const int direction = wxHORIZONTAL );
+    virtual void Fit(void);
+    
+    void OnSize( wxSizeEvent &event );
+    
+    virtual bool Show( const bool show );
+    virtual void Enable( const bool enable );
+    virtual void MakeModal( const bool modal );
+    virtual bool IsEnabled(void) const { return m_isEnabled; };
+    virtual void SetFocus(void);
+    virtual bool OnClose(void);
+    
+    virtual void AddChild( wxWindow *child );
+    wxList *GetChildren(void);
+    virtual void RemoveChild( wxWindow *child );
+    void SetReturnCode( int retCode );
+    int GetReturnCode(void);
+    wxWindow *GetParent(void);
+    
+    wxEvtHandler *GetEventHandler(void);
+    void SetEventhandler( wxEvtHandler *handler );
+    
+    virtual wxValidator *GetValidator(void);
+    virtual void SetValidator( wxValidator *validator );
+    
+    bool IsBeingDeleted(void);
+    
+    void SetId( wxWindowID id );
+    wxWindowID GetId(void);
+    
+    void SetCursor( const wxCursor &cursor );
+    
+    virtual void Refresh( const bool eraseBackground = TRUE, const wxRect *rect = NULL );
+    virtual void Clear(void);
+    virtual bool IsExposed( const long x, const long y );
+    virtual bool IsExposed( const long x, const long y, const long width, const long height );
+    
+    virtual wxColour GetBackgroundColour(void) const;
+    virtual void SetBackgroundColour( const wxColour &colour );
+    
+    virtual void SetDefaultBackgroundColour( const wxColour& col )
+      { m_defaultBackgroundColour = col; };
+    virtual wxColour GetDefaultBackgroundColour(void) const
+      { return m_defaultBackgroundColour; };
+    virtual void SetDefaultForegroundColour( const wxColour& col )
+      { m_defaultForegroundColour = col; };
+    virtual wxColour GetDefaultForegroundColour(void) const
+      { return m_defaultForegroundColour; };
+    
+    virtual void SetFont( const wxFont &font );
+    virtual wxFont *GetFont(void);
+    // For backward compatibility
+    inline virtual void SetButtonFont(const wxFont& font) { SetFont(font); }
+    inline virtual void SetLabelFont(const wxFont& font) { SetFont(font); }
+    inline virtual wxFont *GetLabelFont(void) { return GetFont(); };
+    inline virtual wxFont *GetButtonFont(void) { return GetFont(); };
+    virtual void SetWindowStyleFlag( long flag );
+    virtual long GetWindowStyleFlag(void) const;
+    virtual void CaptureMouse(void);
+    virtual void ReleaseMouse(void);
+    virtual void SetTitle( const wxString &title );
+    virtual wxString GetTitle(void) const;
+    virtual void SetName( const wxString &name );
+    virtual wxString GetName(void) const;
+    virtual wxString GetLabel(void) const;
+    
+    void OnSysColourChanged( wxSysColourChangedEvent &WXUNUSED(event) ) {};
+    
+    virtual bool IsShown(void);
+    virtual bool IsRetained(void);
+    virtual wxWindow *FindWindow( const long id );
+    virtual wxWindow *FindWindow( const wxString& name );
+    void AllowDoubleClick( bool WXUNUSED(allow) ) {};
+    void SetDoubleClick( bool WXUNUSED(allow) ) {};
+    virtual void ClientToScreen( int *x, int *y );
+    virtual void ScreenToClient( int *x, int *y );
+    
+    virtual bool Validate(void);
+    virtual bool TransferDataToWindow(void);
+    virtual bool TransferDataFromWindow(void);
+    void OnInitDialog( wxInitDialogEvent &event );
+    virtual void InitDialog(void);
+    
+    virtual void SetDropTarget( wxDropTarget *dropTarget );
+    virtual wxDropTarget *GetDropTarget() const;
+    
+    virtual void SetScrollbar( const int orient, const int pos, const int thumbVisible,
+      const int range, const bool refresh = TRUE );
+    virtual void SetScrollPos( const int orient, const int pos, const bool refresh = TRUE );
+    virtual int GetScrollPos( const int orient ) const;
+    virtual int GetScrollThumb( const int orient ) const;
+    virtual int GetScrollRange( const int orient ) const;
+    virtual void ScrollWindow( const int dx, const int dy, const wxRect* rect = NULL );
+    
+  public:         // cannot get private going yet
+    
+    void PreCreation( wxWindow *parent, const wxWindowID id, const wxPoint &pos, 
+      const wxSize &size, const long style, const wxString &name );
+    void PostCreation(void);
+    bool HasVMT(void);
+    virtual void ImplementSetSize(void);
+    virtual void ImplementSetPosition(void);
+    void GetDrawingOffset( long *x, long *y );
+    
+    wxWindow       *m_parent;
+    wxList          m_children;
+    int             m_x,m_y;
+    int             m_width,m_height;
+    int             m_retCode;
+    wxEvtHandler   *m_eventHandler;
+    wxValidator    *m_windowValidator;
+    wxDropTarget   *m_pDropTarget;   
+    wxWindowID      m_windowId;
+    wxCursor       *m_cursor;
+    wxFont          m_font;
+    wxColour        m_backgroundColour;
+    wxColour        m_defaultBackgroundColour;
+    wxColour        m_foregroundColour ;
+    wxColour        m_defaultForegroundColour;
+    wxRegion        m_updateRegion;
+    long            m_windowStyle;
+    bool            m_isShown;
+    bool            m_isEnabled;
+    wxString        m_windowName;
+    long            m_drawingOffsetX,m_drawingOffsetY;
+    
+    GtkWidget      *m_widget;
+    GtkWidget      *m_wxwindow;
+    GtkAdjustment  *m_hAdjust,*m_vAdjust;
+    float           m_oldHorizontalPos;
+    float           m_oldVerticalPos;
+    bool            m_needParent;
+    bool            m_hasScrolling;
+    bool            m_hasVMT;
+    bool            m_sizeSet;
+    
+  public:  // Layout section
+  
+    wxLayoutConstraints * m_constraints;  
+    wxList *              m_constraintsInvolvedIn;
+    wxSizer *             m_windowSizer;  
+    wxWindow *            m_sizerParent;  
+    bool                  m_autoLayout;                    
+
+    wxLayoutConstraints *GetConstraints(void) const;
+    void SetConstraints( wxLayoutConstraints *constraints );
+    void SetAutoLayout( const bool autoLayout );
+    bool GetAutoLayout(void) const;
+    bool Layout(void);
+    void SetSizer( wxSizer *sizer );
+    wxSizer *GetSizer(void) const;
+    void SetSizerParent( wxWindow *win );
+    wxWindow *GetSizerParent(void) const;
+    void UnsetConstraints(wxLayoutConstraints *c);
+    inline wxList *GetConstraintsInvolvedIn(void) const ;
+    void AddConstraintReference(wxWindow *otherWin);
+    void RemoveConstraintReference(wxWindow *otherWin);
+    void DeleteRelatedConstraints(void);
+    virtual void ResetConstraints(void);
+    virtual void SetConstraintSizes(const bool recurse = TRUE);
+    virtual bool LayoutPhase1(int *noChanges);
+    virtual bool LayoutPhase2(int *noChanges);
+    virtual bool DoPhase(const int);
+    virtual void TransformSizerToActual(int *x, int *y) const ;
+    virtual void SizerSetSize(const int x, const int y, const int w, const int h);
+    virtual void SizerMove(const int x, const int y);
+    virtual void SetSizeConstraint(const int x, const int y, const int w, const int h);
+    virtual void MoveConstraint(const int x, const int y);
+    virtual void GetSizeConstraint(int *w, int *h) const ;
+    virtual void GetClientSizeConstraint(int *w, int *h) const ;
+    virtual void GetPositionConstraint(int *x, int *y) const ;
+  
+  DECLARE_EVENT_TABLE()
+};
+
+#endif // __GTKWINDOWH__
diff --git a/include/wx/hash.h b/include/wx/hash.h
new file mode 100644
index 0000000000..8000d7b8b3
--- /dev/null
+++ b/include/wx/hash.h
@@ -0,0 +1,98 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        hash.h
+// Purpose:     wxHashTable class
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c)
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __WXHASHH__
+#define __WXHASHH__
+
+#ifdef __GNUG__
+#pragma interface "hash.h"
+#endif
+
+#include "wx/object.h"
+#include "wx/list.h"
+
+/*
+ * A hash table is an array of user-definable size with lists
+ * of data items hanging off the array positions.  Usually there'll
+ * be a hit, so no search is required; otherwise we'll have to run down
+ * the list to find the desired item.
+*/
+
+class WXDLLEXPORT wxHashTable: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxHashTable)
+
+ public:
+  int n;
+  int current_position;
+  wxNode *current_node;
+
+  unsigned int key_type;
+  wxList **hash_table;
+
+  wxHashTable(const int the_key_type = wxKEY_INTEGER, const int size = 1000);
+  ~wxHashTable(void);
+
+  bool Create(const int the_key_type = wxKEY_INTEGER, const int size = 1000);
+
+  // Note that there are 2 forms of Put, Get.
+  // With a key and a value, the *value* will be checked
+  // when a collision is detected. Otherwise, if there are
+  // 2 items with a different value but the same key,
+  // we'll retrieve the WRONG ONE. So where possible,
+  // supply the required value along with the key.
+  // In fact, the value-only versions make a key, and still store
+  // the value. The use of an explicit key might be required
+  // e.g. when combining several values into one key.
+  // When doing that, it's highly likely we'll get a collision,
+  // e.g. 1 + 2 = 3, 2 + 1 = 3.
+
+  // key and value are NOT necessarily the same
+  void Put(const long key, const long value, wxObject *object);
+  void Put(const long key, const char *value, wxObject *object);
+
+  // key and value are the same
+  void Put(const long value, wxObject *object);
+  void Put(const char *value, wxObject *object);
+
+  // key and value not the same
+  wxObject *Get(const long key, const long value) const;
+  wxObject *Get(const long key, const char *value) const;
+
+  // key and value are the same
+  wxObject *Get(const long value) const;
+  wxObject *Get(const char *value) const;
+
+  // Deletes entry and returns data if found
+  wxObject *Delete(const long key);
+  wxObject *Delete(const char *key);
+
+  wxObject *Delete(const long key, const int value);
+  wxObject *Delete(const long key, const char *value);
+
+  // Construct your own integer key from a string, e.g. in case
+  // you need to combine it with something
+  long MakeKey(const char *string) const;
+
+  // Way of iterating through whole hash table (e.g. to delete everything)
+  // Not necessary, of course, if you're only storing pointers to
+  // objects maintained separately
+
+  void BeginFind(void);
+  wxNode *Next(void);
+
+  void DeleteContents(const bool flag);
+  void Clear(void);
+
+};
+
+#endif
+    // __WXHASHH__
diff --git a/include/wx/help.h b/include/wx/help.h
new file mode 100644
index 0000000000..9622355ff6
--- /dev/null
+++ b/include/wx/help.h
@@ -0,0 +1,13 @@
+#ifndef __HELPH_BASE__
+#define __HELPH_BASE__
+
+#ifdef __WINDOWS__
+#include "wx/msw/helpwin.h"
+#elif defined(__GTK__)
+#include "wx/generic/helphtml.h"
+#else
+#include "wx/generic/helpxlp.h"
+#endif
+
+#endif
+    // __HELPH_BASE__
diff --git a/include/wx/helpbase.h b/include/wx/helpbase.h
new file mode 100644
index 0000000000..24557948d1
--- /dev/null
+++ b/include/wx/helpbase.h
@@ -0,0 +1,50 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        helpbase.h
+// Purpose:     Help system base classes
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __HELPBASEH__
+#define __HELPBASEH__
+
+#ifdef __GNUG__
+#pragma interface "helpbase.h"
+#endif
+
+#include "wx/wx.h"
+
+#if USE_HELP
+
+// Defines the API for help controllers
+class WXDLLEXPORT wxHelpControllerBase: public wxObject
+{
+  DECLARE_CLASS(wxHelpControllerBase)
+
+ public:
+  inline wxHelpControllerBase(void) {}
+  inline ~wxHelpControllerBase(void) {};
+
+  // Must call this to set the filename and server name.
+  // server is only required when implementing TCP/IP-based
+  // help controllers.
+  virtual bool Initialize(const wxString& file, int server = -1) = 0;
+
+  // If file is "", reloads file given  in Initialize
+  virtual bool LoadFile(const wxString& file = "") = 0;
+  virtual bool DisplayContents(void) = 0;
+  virtual bool DisplaySection(int sectionNo) = 0;
+  virtual bool DisplayBlock(long blockNo) = 0;
+  virtual bool KeywordSearch(const wxString& k) = 0;
+
+  virtual bool Quit(void) = 0;
+  virtual void OnQuit(void) {};
+};
+
+#endif // USE_HELP
+#endif
+    // __HELPBASEH__
diff --git a/include/wx/helphtml.h b/include/wx/helphtml.h
new file mode 100644
index 0000000000..345c71cac0
--- /dev/null
+++ b/include/wx/helphtml.h
@@ -0,0 +1,7 @@
+#ifndef __HELPHTMLH_BASE__
+#define __HELPHTMLH_BASE__
+
+#include "wx/generic/helphtml.h"
+
+#endif
+    // __HELPHTMLH_BASE__
diff --git a/include/wx/helpwin.h b/include/wx/helpwin.h
new file mode 100644
index 0000000000..b855c1fb99
--- /dev/null
+++ b/include/wx/helpwin.h
@@ -0,0 +1,7 @@
+#ifndef __HELPWINH_BASE__
+#define __HELPWINH_BASE__
+
+#include "wx/msw/helpwin.h"
+
+#endif
+    // __HELPWINH_BASE__
diff --git a/include/wx/helpxlp.h b/include/wx/helpxlp.h
new file mode 100644
index 0000000000..877d908823
--- /dev/null
+++ b/include/wx/helpxlp.h
@@ -0,0 +1,7 @@
+#ifndef __HELPXLPH_BASE__
+#define __HELPXLPH_BASE__
+
+#include "wx/generic/helpxlp.h"
+
+#endif
+    // __HELPXLPH_BASE__
diff --git a/include/wx/icon.h b/include/wx/icon.h
new file mode 100644
index 0000000000..cb6bc66b60
--- /dev/null
+++ b/include/wx/icon.h
@@ -0,0 +1,13 @@
+#ifndef __ICONH_BASE__
+#define __ICONH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/icon.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/icon.h"
+#elif defined(__GTK__)
+#include "wx/gtk/icon.h"
+#endif
+
+#endif
+    // __ICONH_BASE__
diff --git a/include/wx/imaglist.h b/include/wx/imaglist.h
new file mode 100644
index 0000000000..12774bdff4
--- /dev/null
+++ b/include/wx/imaglist.h
@@ -0,0 +1,13 @@
+#ifndef __IMAGLISTH_BASE__
+#define __IMAGLISTH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/imaglist.h"
+#elif defined(__MOTIF__)
+#include "wx/generic/imaglist.h"
+#elif defined(__GTK__)
+#include "wx/generic/imaglist.h"
+#endif
+
+#endif
+    // __IMAGLISTH_BASE__
diff --git a/include/wx/intl.h b/include/wx/intl.h
new file mode 100644
index 0000000000..d0bea59c9f
--- /dev/null
+++ b/include/wx/intl.h
@@ -0,0 +1,159 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        intl.h
+// Purpose:     Internationalization and localisation for wxWindows
+// Author:      Vadim Zeitlin
+// Modified by:
+// Created:     29/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef   __INTLH__
+#define   __INTLH__
+
+#ifdef __GNUG__
+#pragma interface "intl.h"
+#endif
+
+#include "wx/defs.h"
+#include "wx/string.h"
+
+// ============================================================================
+// global decls
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// simple types
+// ----------------------------------------------------------------------------
+
+// # adjust if necessary
+typedef unsigned char uint8;
+typedef unsigned long uint32;
+
+// ----------------------------------------------------------------------------
+// macros
+// ----------------------------------------------------------------------------
+
+// gettext() style macro
+#define   _(str)  wxGetTranslation(str)
+
+// ----------------------------------------------------------------------------
+// forward decls
+// ----------------------------------------------------------------------------
+class WXDLLEXPORT wxLocale;
+class WXDLLEXPORT wxMsgCatalog;
+
+// ----------------------------------------------------------------------------
+// global functions
+// ----------------------------------------------------------------------------
+extern wxLocale* WXDLLEXPORT wxGetLocale();
+inline const char* wxGetTranslation(const char *sz);
+
+// ============================================================================
+// locale support
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxLocale: encapsulates all language dependent settings, including current
+//           message catalogs, date, time and currency formats (#### to do) &c
+// ----------------------------------------------------------------------------
+class WXDLLEXPORT wxLocale
+{
+public:
+  // ctor & dtor
+    // the ctor has a side effect of changing current locale
+    wxLocale(const char *szName,              // name (for messages)
+             const char *szShort = NULL,      // dir prefix (for msg files)
+             const char *szLocale = NULL,     // locale (for setlocale)
+             bool bLoadDefault = TRUE);       // preload wxstd.mo?
+    // restores old locale
+ ~wxLocale();
+
+  // returns locale name
+  const char *GetLocale() const { return m_strLocale; }
+
+  // add a catalog: it's searched for in standard places (current directory 
+  // first, system one after). It will be used for message lookup by
+  // GetString().
+  //
+  // Returns 'true' if it was successfully loaded
+  bool AddCatalog(const char *szDomain);
+  
+  // check if the given catalog is loaded
+  bool IsLoaded(const char *szDomain) const;
+  
+  // retrieve the translation for a string in all loaded domains unless
+  // the szDomain parameter is specified (and then only this domain is
+  // searched)
+  //
+  // return original string if translation is not available
+  // (in this case an error message is generated the first time
+  //  a string is not found; use wxLogNull to suppress it)
+  //
+  // domains are searched in the last to first order, i.e. catalogs
+  // added later override those added before.
+  const char *GetString(const char *szOrigString, 
+                        const char *szDomain = NULL) const;
+
+private:
+  // find catalog by name in a linked list, return NULL if !found
+  wxMsgCatalog  *FindCatalog(const char *szDomain) const;
+
+  wxString       m_strLocale,     // this locale name
+                 m_strShort;      // short name for the locale
+  
+  const char    *m_pszOldLocale;  // previous locale from setlocale()
+  wxLocale      *m_pOldLocale;    // previous wxLocale
+  
+  wxMsgCatalog  *m_pMsgCat;       // pointer to linked list of catalogs
+};
+
+// ============================================================================
+// optional features
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxTString: automatically translates strings to current language
+// ----------------------------------------------------------------------------
+
+// this feature should be enabled by defining WX_USE_AUTOTRANS, if it's not
+// done no automatic translation is performed
+#if  USE_AUTOTRANS
+  class WXDLLEXPORT wxTString
+  {
+  public:
+    // NB: different ctors do different things!
+      // does translation
+    wxTString(const char *sz) : m_pcsz(wxGetTranslation(sz)) { }
+      // no translation
+    wxTString(const wxString& s) : m_pcsz(s) { }
+
+    // NB: no copy ctor, it must be a POD so that we can pass it
+    //     to vararg functions (and it's not needed anyhow)
+    
+    // implicit conversion
+    operator const char *() const { return m_pcsz; }
+
+  private:
+    const char *m_pcsz;
+  };
+#else   //!USE_AUTOTRANS
+  #define wxTString   wxString
+#endif  //USE_AUTOTRANS
+
+#define TRANSSTRING_DEFINED
+  
+// ----------------------------------------------------------------------------
+// inline functions
+// ----------------------------------------------------------------------------
+
+// get the translation of the string in the current locale  
+inline const char *wxGetTranslation(const char *sz)
+{
+  wxLocale *pLoc = wxGetLocale();
+  return pLoc == NULL ? sz : pLoc->GetString(sz);
+}
+
+#endif
+	// __INTLH__
diff --git a/include/wx/ipcbase.h b/include/wx/ipcbase.h
new file mode 100644
index 0000000000..4fb3b7b8eb
--- /dev/null
+++ b/include/wx/ipcbase.h
@@ -0,0 +1,93 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        ipcbase.h
+// Purpose:     Base classes for IPC
+// Author:      Julian Smart
+// Modified by:
+// Created:     4/1/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __IPCBASEH__
+#define __IPCBASEH__
+
+#include "wx/defs.h"
+#include "wx/object.h"
+#include "wx/string.h"
+
+class WXDLLEXPORT wxDDEServerBase;
+class WXDLLEXPORT wxDDEClientBase;
+
+class WXDLLEXPORT wxConnectionBase: public wxObject
+{
+  DECLARE_CLASS(wxConnectionBase)
+ public:
+  inline wxConnectionBase(void) {}
+  inline ~wxConnectionBase(void) {}
+
+  // Calls that CLIENT can make
+  virtual bool Execute(char *data, int size = -1, int format = wxCF_TEXT) = 0;
+  virtual bool Execute(const wxString& str) { return Execute((char *)(const char *)str, -1, wxCF_TEXT); }
+  virtual char *Request(const wxString& item, int *size = NULL, int format = wxCF_TEXT) = 0;
+  virtual bool Poke(const wxString& item, char *data, int size = -1, int format = wxCF_TEXT) = 0;
+  virtual bool StartAdvise(const wxString& item) = 0;
+  virtual bool StopAdvise(const wxString& item) = 0;
+
+  // Calls that SERVER can make
+  virtual bool Advise(const wxString& item, char *data, int size = -1, int format = wxCF_TEXT) = 0;
+
+  // Calls that both can make
+  virtual bool Disconnect(void) = 0;
+
+  // Callbacks to SERVER - override at will
+  virtual bool OnExecute( const wxString& WXUNUSED(topic), char *WXUNUSED(data), int WXUNUSED(size), 
+                          int WXUNUSED(format) ) { return FALSE; };
+  virtual char *OnRequest( const wxString& WXUNUSED(topic), const wxString& WXUNUSED(item), 
+                           int *WXUNUSED(size), int WXUNUSED(format) ) { return NULL; };
+  virtual bool OnPoke( const wxString& WXUNUSED(topic), const wxString& WXUNUSED(item), char *WXUNUSED(data), 
+		       int WXUNUSED(size), int WXUNUSED(format) ) { return FALSE; };
+  virtual bool OnStartAdvise( const wxString& WXUNUSED(topic), const wxString& WXUNUSED(item) ) 
+                              { return FALSE; };
+  virtual bool OnStopAdvise( const wxString& WXUNUSED(topic), const wxString& WXUNUSED(item) ) 
+                             { return FALSE; };
+
+  // Callbacks to CLIENT - override at will
+  virtual bool OnAdvise( const wxString& WXUNUSED(topic), const wxString& WXUNUSED(item), char *WXUNUSED(data), 
+			 int WXUNUSED(size), int WXUNUSED(format) ) { return FALSE; };
+
+  // Callbacks to BOTH
+
+  // Default behaviour is to delete connection and return TRUE
+  virtual bool OnDisconnect(void) = 0;
+};
+
+class WXDLLEXPORT wxServerBase: public wxObject
+{
+  DECLARE_CLASS(wxServerBase)
+ public:
+
+  inline wxServerBase(void) {}
+  inline ~wxServerBase(void) {};
+  virtual bool Create(const wxString& serverName) = 0; // Returns FALSE if can't create server (e.g. port
+                                  // number is already in use)
+  virtual wxConnectionBase *OnAcceptConnection(const wxString& topic) = 0;
+
+};
+
+class WXDLLEXPORT wxClientBase: public wxObject
+{
+  DECLARE_CLASS(wxClientBase)
+ public:
+  inline wxClientBase(void) {};
+  inline ~wxClientBase(void) {};
+  virtual bool ValidHost(const wxString& host) = 0;
+  virtual wxConnectionBase *MakeConnection(const wxString& host, const wxString& server, const wxString& topic) = 0;
+                                                // Call this to make a connection.
+                                                // Returns NULL if cannot.
+  virtual wxConnectionBase *OnMakeConnection(void) = 0; // Tailor this to return own connection.
+
+};
+
+#endif
+    // __IPCBASEH__
diff --git a/include/wx/layout.h b/include/wx/layout.h
new file mode 100644
index 0000000000..800bbdf5ea
--- /dev/null
+++ b/include/wx/layout.h
@@ -0,0 +1,304 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        layout.h
+// Purpose:     Layout classes
+// Author:      Julian Smart
+// Modified by:
+// Created:     29/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Julian Smart
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __LAYOUTH__
+#define __LAYOUTH__
+
+#ifdef __GNUG__
+#pragma interface "layout.h"
+#endif
+
+#include "wx/defs.h"
+
+class WXDLLEXPORT wxWindow;
+
+// X stupidly defines these in X.h
+#ifdef Above
+#undef Above
+#endif
+#ifdef Below
+#undef Below
+#endif
+
+#define wxLAYOUT_DEFAULT_MARGIN 0
+
+enum wxEdge { wxLeft, wxTop, wxRight, wxBottom, wxWidth, wxHeight,
+  wxCentre, wxCenter = wxCentre, wxCentreX, wxCentreY };
+enum wxRelationship { wxUnconstrained = 0,
+                      wxAsIs,
+                      wxPercentOf,
+                      wxAbove,
+                      wxBelow,
+                      wxLeftOf,
+                      wxRightOf,
+                      wxSameAs,
+                      wxAbsolute };
+
+class WXDLLEXPORT wxLayoutConstraints;
+class WXDLLEXPORT wxIndividualLayoutConstraint: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxIndividualLayoutConstraint)
+
+ protected:
+   // 'This' window is the parent or sibling of otherWin
+   wxWindow *otherWin;
+
+   wxEdge myEdge;
+   wxRelationship relationship;
+   int margin;
+   int value;
+   int percent;
+   wxEdge otherEdge;
+   bool done;
+
+ public:
+   wxIndividualLayoutConstraint(void);
+   ~wxIndividualLayoutConstraint(void);
+
+  void Set(wxRelationship rel, wxWindow *otherW, wxEdge otherE, int val = 0, int marg = wxLAYOUT_DEFAULT_MARGIN);
+
+  //
+  // Sibling relationships
+  //
+  void LeftOf(wxWindow *sibling, int marg = wxLAYOUT_DEFAULT_MARGIN);
+  void RightOf(wxWindow *sibling, int marg = wxLAYOUT_DEFAULT_MARGIN);
+  void Above(wxWindow *sibling, int marg = wxLAYOUT_DEFAULT_MARGIN);
+  void Below(wxWindow *sibling, int marg = wxLAYOUT_DEFAULT_MARGIN);
+
+  //
+  // 'Same edge' alignment
+  //
+  void SameAs(wxWindow *otherW, wxEdge edge, int marg = wxLAYOUT_DEFAULT_MARGIN);
+
+  // The edge is a percentage of the other window's edge
+  void PercentOf(wxWindow *otherW, wxEdge wh, int per);
+
+  //
+  // Edge has absolute value
+  //
+  void Absolute(int val);
+
+  //
+  // Dimension is unconstrained
+  //
+  inline void Unconstrained(void) { relationship = wxUnconstrained; }
+
+  //
+  // Dimension is 'as is' (use current size settings)
+  //
+  inline void AsIs(void) { relationship = wxAsIs; }
+
+  //
+  // Accessors
+  //
+  inline wxWindow *GetOtherWindow(void) { return otherWin; }
+  inline wxEdge GetMyEdge(void) { return myEdge; }
+  inline void SetEdge(wxEdge which) { myEdge = which; }
+  inline void SetValue(int v) { value = v; }
+  inline int GetMargin(void) { return margin; }
+  inline void SetMargin(int m) { margin = m; }
+  inline int GetValue(void) { return value; }
+  inline int GetPercent(void) { return percent; }
+  inline int GetOtherEdge(void) { return otherEdge; }
+  inline bool GetDone(void) { return done; }
+  inline void SetDone(bool d) { done = d; }
+  inline wxRelationship GetRelationship(void) { return relationship; }
+  inline void SetRelationship(wxRelationship r) { relationship = r; }
+
+  // Reset constraint if it mentions otherWin
+  bool ResetIfWin(wxWindow *otherW);
+
+  // Try to satisfy constraint
+  bool SatisfyConstraint(wxLayoutConstraints *constraints, wxWindow *win);
+
+  // Get the value of this edge or dimension, or if this
+  // is not determinable, -1.
+  int GetEdge(wxEdge which, wxWindow *thisWin, wxWindow *other);
+};
+
+class WXDLLEXPORT wxLayoutConstraints: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxLayoutConstraints)
+
+ public:
+  // Edge constraints
+  wxIndividualLayoutConstraint left;
+  wxIndividualLayoutConstraint top;
+  wxIndividualLayoutConstraint right;
+  wxIndividualLayoutConstraint bottom;
+  // Size constraints
+  wxIndividualLayoutConstraint width;
+  wxIndividualLayoutConstraint height;
+  // Centre constraints
+  wxIndividualLayoutConstraint centreX;
+  wxIndividualLayoutConstraint centreY;
+
+  wxLayoutConstraints(void);
+  ~wxLayoutConstraints(void);
+
+  bool SatisfyConstraints(wxWindow *win, int *noChanges);
+};
+
+bool WXDLLEXPORT wxOldDoLayout(wxWindow *win);
+
+/*
+
+Algorithm:
+
+ Each sizer has a Layout function.
+
+ wxExpandSizer::Layout                  ; E.g. for resizeable windows
+ 
+   - parent size must be known (i.e. called
+      from OnSize or explicitly)
+   - call Layout on each child to give it a chance to resize
+     (e.g. child shrinks around its own children):
+     stop when all children return TRUE, or no change
+   - evaluate constraints on self to set size
+
+ wxShrinkSizer::Layout                  ; E.g. fit-to-contents windows
+                                        ; Perhaps 2 rowcols, one above other.
+ 
+   - call Layout on each child to give it a chance to resize
+     (e.g. child shrinks around its own children):
+     stop when each returns TRUE, or no change
+   - fit around children
+        (what if some want to be centred? E.g. OK/Cancel rowcol.
+         - done by centring e.g. bottom sizer w.r.t. top sizer.
+           (sibling relationship only))
+   - evaluate own constraints (e.g. may be below another window)
+   - IF parent is a real window (remember: a real window can
+     have only one child sizer, although a sizer can have several child
+     (real) windows), then resize this parent WITHOUT invoking Layout
+     again.
+     Frame and dialog box OnSizes can check if the sizer is a shrink
+     sizer; if not, can call layout. Maybe have virtual bool AutoSizeLayout()
+     to determine this.
+
+How to relayout if a child sizer/window changes? Need to go all the way
+to the top of the hierarchy and call Layout() again.
+     
+ wxRowColSizer::Layout
+
+   - Similar to wxShrinkSizer only instead of shrinking to fit
+     contents, more sophisticated layout of contents, and THEN
+     shrinking (possibly).
+   - Do the same parent window check/setsize as for wxShrinkSizer.
+ 
+*/
+
+typedef enum {
+    wxSizerShrink,
+    wxSizerExpand,
+    wxSizerNone
+} wxSizerBehaviour;
+
+#define wxTYPE_SIZER        90
+
+class WXDLLEXPORT wxSizer: public wxWindow
+{
+  DECLARE_DYNAMIC_CLASS(wxSizer)
+
+ private:
+ protected:
+  wxSizerBehaviour sizerBehaviour;
+  int borderX;
+  int borderY;
+  int sizerWidth;
+  int sizerHeight;
+  int sizerX;
+  int sizerY;
+ public:
+  wxSizer(void);
+  wxSizer(wxWindow *parent, wxSizerBehaviour behav = wxSizerNone);
+  ~wxSizer(void);
+
+  bool Create(wxWindow *parent, wxSizerBehaviour behav = wxSizerNone);
+  virtual void SetSize(const int x, const int y, const int w, const int h, const int flags = wxSIZE_AUTO);
+  // Avoid compiler warning
+  void SetSize(const int w, const int h) { wxWindow::SetSize(w, h); }
+  virtual void Move(const int x, const int y);
+  virtual void GetSize(int *w, int *h) const;
+  inline virtual void GetClientSize(int *w, int *h) const { GetSize(w, h); }
+  virtual void GetPosition(int *x, int *y) const;
+
+  inline void SizerSetSize(const int x, const int y, const int w, const int h)
+    { SetSize(x, y, w, h); }
+  inline void SizerMove(const int x, const int y)
+    { Move(x, y); }
+
+  virtual void SetBorder(int w, int h);
+  inline int GetBorderX(void) { return borderX ; }
+  inline int GetBorderY(void) { return borderY ; }
+
+  virtual void AddSizerChild(wxWindow *child);
+  virtual void RemoveSizerChild(wxWindow *child);
+
+  inline virtual void SetBehaviour(wxSizerBehaviour b) { sizerBehaviour = b; }
+  inline virtual wxSizerBehaviour GetBehaviour(void) { return sizerBehaviour; }
+
+  virtual bool LayoutPhase1(int *);
+  virtual bool LayoutPhase2(int *);
+};
+
+#define wxSIZER_ROWS  TRUE
+#define wxSIZER_COLS  FALSE
+
+class WXDLLEXPORT wxRowColSizer: public wxSizer
+{
+  DECLARE_DYNAMIC_CLASS(wxRowColSizer)
+
+ private:
+ protected:
+  bool rowOrCol;
+  int rowOrColSize;
+  int xSpacing;
+  int ySpacing;
+ public:
+  // rowOrCol = TRUE to be laid out in rows, otherwise in columns.
+  wxRowColSizer(void);
+  wxRowColSizer(wxWindow *parent, bool rowOrCol = wxSIZER_ROWS, int rowsOrColSize = 20, wxSizerBehaviour = wxSizerShrink);
+  ~wxRowColSizer(void);
+
+  bool Create(wxWindow *parent, bool rowOrCol = wxSIZER_ROWS, int rowsOrColSize = 20, wxSizerBehaviour = wxSizerShrink);
+  void SetSize(const int x, const int y, const int w, const int h, const int flags = wxSIZE_AUTO);
+  // Avoid compiler warning
+  void SetSize(const int w, const int h) { wxSizer::SetSize(w, h); }
+
+  inline virtual void SetRowOrCol(bool rc) { rowOrCol = rc; }
+  inline virtual bool GetRowOrCol(void) { return rowOrCol; }
+  inline virtual void SetRowOrColSize(int n) { rowOrColSize = n; }
+  inline virtual int GetRowOrColSize(void) { return rowOrColSize; }
+  inline virtual void SetSpacing(int x, int y) { xSpacing = x; ySpacing = y; }
+  inline virtual void GetSpacing(int *x, int *y) { *x = xSpacing; *y = ySpacing; }
+
+  bool LayoutPhase1(int *);
+  bool LayoutPhase2(int *);
+};
+
+class WXDLLEXPORT wxSpacingSizer: public wxSizer
+{
+  DECLARE_DYNAMIC_CLASS(wxSpacingSizer)
+
+ private:
+ protected:
+ public:
+  wxSpacingSizer(void);
+  wxSpacingSizer(wxWindow *parent, wxRelationship rel, wxWindow *other, int spacing);
+  wxSpacingSizer(wxWindow *parent);
+  ~wxSpacingSizer(void);
+
+  bool Create(wxWindow *parent, wxRelationship rel, wxWindow *other, int sp);
+  bool Create(wxWindow *parent);
+};
+
+#endif
+    // __LAYOUTH__
diff --git a/include/wx/list.h b/include/wx/list.h
new file mode 100644
index 0000000000..90f773e79a
--- /dev/null
+++ b/include/wx/list.h
@@ -0,0 +1,148 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        list.h
+// Purpose:     wxList, wxStringList classes
+// Author:      Julian Smart
+// Modified by:
+// Created:     29/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Julian Smart
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __LISTH__
+#define __LISTH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/object.h"
+
+class WXDLLEXPORT wxList;
+
+#define wxKEY_NONE    0
+#define wxKEY_INTEGER 1
+#define wxKEY_STRING  2
+class WXDLLEXPORT wxNode: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxNode)
+ private:
+ 
+  wxObject *data;
+  wxNode *next;
+  wxNode *previous;
+
+ public:
+  wxList *list;
+
+  // Optional key stuff
+  union
+  {
+    long integer;
+    char *string;
+  } key;
+
+  wxNode(wxList *the_list = NULL, wxNode *last_one = NULL, wxNode *next_one = NULL, wxObject *object = NULL);
+  wxNode(wxList *the_list, wxNode *last_one, wxNode *next_one,
+         wxObject *object, long the_key);
+  wxNode(wxList *the_list, wxNode *last_one, wxNode *next_one,
+         wxObject *object, const char *the_key);
+  ~wxNode(void);
+
+  inline wxNode *Next(void) const { return next; }
+  inline wxNode *Previous(void) const { return previous; }
+  inline wxObject *Data(void) const { return (wxObject *)data; }
+  inline void SetData(wxObject *the_data) { data = the_data; }
+};
+
+// type of compare function for list sort operation (as in 'qsort')
+typedef int (*wxSortCompareFunction)(const void *elem1, const void *elem2);
+typedef int (*wxListIterateFunction)(wxObject *o);
+
+class WXDLLEXPORT wxList: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxList)
+
+ public:
+  int n;
+  int destroy_data;
+  wxNode *first_node;
+  wxNode *last_node;
+  unsigned int key_type;
+
+  wxList(void);
+  wxList(const unsigned int the_key_type);
+  wxList(const int N, wxObject *Objects[]);
+  wxList(wxObject *object, ...);
+  
+#ifdef USE_STORABLE_CLASSES
+  wxList( istream &stream, char *data );
+  virtual void StoreObject( ostream &stream );
+#endif
+  
+  ~wxList(void);
+
+  inline int Number(void) const { return n; }
+
+  // Append to end of list
+  wxNode *Append(wxObject *object);
+
+  // Insert at front of list
+  wxNode *Insert(wxObject *object);
+
+  // Insert before given node
+  wxNode *Insert(wxNode *position, wxObject *object);
+
+  // Keyed append
+  wxNode *Append(const long key, wxObject *object);
+  wxNode *Append(const char *key, wxObject *object);
+
+  bool DeleteNode(wxNode *node);
+  bool DeleteObject(wxObject *object);  // Finds object pointer and
+                                        // deletes node (and object if
+                                        // DeleteContents is on)
+  void Clear(void);                     // Delete all nodes
+
+  inline wxNode *First(void) const { return first_node; }
+  inline wxNode *Last(void) const { return last_node; }
+  wxNode *Nth(const int i) const;                  // nth node counting from 0
+
+  // Keyed search
+  wxNode *Find(const long key) const;
+  wxNode *Find(const char *key) const;
+
+  wxNode *Member(wxObject *object) const;
+
+  inline void DeleteContents(const int destroy) { destroy_data = destroy; }
+                                             // Instruct it to destroy user data
+                                             // when deleting nodes
+  // this function allows the sorting of arbitrary lists by giving
+  // a function to compare two list elements.
+  void Sort(const wxSortCompareFunction compfunc);
+
+  wxObject *FirstThat(wxListIterateFunction func);
+  void ForEach(wxListIterateFunction func);
+  wxObject *LastThat(wxListIterateFunction func);
+};
+
+// String list class. N.B. this always copies strings
+// with Add and deletes them itself.
+class WXDLLEXPORT wxStringList: public wxList
+{
+  DECLARE_DYNAMIC_CLASS(wxStringList)
+
+ public:
+  wxStringList(void);
+  wxStringList(const char *first ...);
+  ~wxStringList(void);
+
+  virtual wxNode *Add(const char *s);
+  virtual void Delete(const char *s);
+  virtual char **ListToArray(const bool new_copies = FALSE) const;
+  virtual void Sort(void);
+  virtual bool Member(const char *s) const;
+};
+
+#endif
+    // __LISTH__
diff --git a/include/wx/listbox.h b/include/wx/listbox.h
new file mode 100644
index 0000000000..545ddb54dc
--- /dev/null
+++ b/include/wx/listbox.h
@@ -0,0 +1,13 @@
+#ifndef __LISTBOXH_BASE__
+#define __LISTBOXH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/listbox.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/listbox.h"
+#elif defined(__GTK__)
+#include "wx/gtk/listbox.h"
+#endif
+
+#endif
+    // __LISTBOXH_BASE__
diff --git a/include/wx/listctrl.h b/include/wx/listctrl.h
new file mode 100644
index 0000000000..1025f70334
--- /dev/null
+++ b/include/wx/listctrl.h
@@ -0,0 +1,13 @@
+#ifndef __LISTCTRLH_BASE__
+#define __LISTCTRLH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/listctrl.h"
+#elif defined(__MOTIF__)
+#include "wx/generic/listctrl.h"
+#elif defined(__GTK__)
+#include "wx/generic/listctrl.h"
+#endif
+
+#endif
+    // __LISTCTRLH_BASE__
diff --git a/include/wx/log.h b/include/wx/log.h
new file mode 100644
index 0000000000..7a3fd73d9e
--- /dev/null
+++ b/include/wx/log.h
@@ -0,0 +1,275 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        log.h
+// Purpose:     Assorted wxLogXXX functions, and wxLog (sink for logs)
+// Author:      Vadim Zeitlin
+// Modified by:
+// Created:     29/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef   __LOGH__
+#define   __LOGH__
+
+#ifdef    __GNUG__
+#pragma interface "log.h"
+#endif  //GNU C++
+
+// ----------------------------------------------------------------------------
+// derive from this class to redirect (or suppress, or ...) log messages
+// normally, only a single instance of this class exists but it's not enforced
+//
+// ## would ne nice to add a time stamp to log messages
+// ----------------------------------------------------------------------------
+class WXDLLEXPORT wxLog
+{
+public:
+  enum Level
+  {
+    FatalError, // program can't continue, abort immediately
+    Error,      // a serious error, user must be informed about it
+    Warning,    // warning: user is normally informed about but may ignore it
+    Message,    // normal message (i.e. normal output of a non GUI app)
+    Info,       // informational message (a.k.a. 'Verbose')
+    Status,     // informational: might go to the status line of GUI app
+    Debug,      // never shown to the user, disabled in release mode
+    Trace,      // trace messages are also only enabled in debug mode
+    Progress,   // used for progress indicator (not yet)
+    User1,      // user defined levels (use with wxLogGeneric(wxLog::User1,...)
+    User2,      //
+    User3,      //
+  };
+
+  // ctor
+  wxLog();
+
+  // sink function
+  static void OnLog(Level level, const char *szString)
+    { if ( ms_pLogger != 0 ) ms_pLogger->DoLog(level, szString); }
+
+  // message buffering
+    // flush shows all messages if they're not logged immediately
+    // (FILE and iostream logs don't need it, but wxGuiLog does to avoid
+    //  showing 17 modal dialogs one after another)
+  virtual void Flush();
+    // call Flush() only if this function returns true
+  bool HasPendingMessages() const { return m_bHasMessages; }
+
+  // only one sink is active at each moment
+    // get current log target
+  static wxLog *GetActiveTarget();
+    // change log target, pLogger = NULL disables logging,
+    // returns the previous log target
+  static wxLog *SetActiveTarget(wxLog *pLogger);
+
+  // functions controlling the default wxLog behaviour
+    // verbose mode is activated by standard command-line '-verbose' option
+  static void SetVerbose(bool bVerbose = TRUE) { ms_bVerbose = bVerbose; }
+    // sets the format for timestamp prepended by wxLog::DoLog(): it's
+    // passed to strftime() function, see it's documentation for details.
+    // the string is not copied!
+  static void SetTimeStampFormat(const char *szTimeFormat)
+    { ms_szTimeFormat = szTimeFormat; }
+
+  // accessors
+    // gets the verbose status
+  static bool GetVerbose() { return ms_bVerbose; }
+
+  // make dtor virtual for all derived classes
+  virtual ~wxLog() { }
+
+protected:
+  bool m_bHasMessages;
+
+  // static variables
+  // ----------------
+  static bool        ms_bVerbose;     // FALSE => ignore LogInfo messages
+  static const char *ms_szTimeFormat; // format for strftime()
+
+private:
+  // the logging functions that can be overriden
+    // default DoLog() prepends the time stamp and a prefix corresponding
+    // to the message to szString and then passes it to DoLogString()
+  virtual void DoLog(Level level, const char *szString);
+    // default DoLogString does nothing but is not pure virtual because if
+    // you override DoLog() you might not need it at all
+  virtual void DoLogString(const char *szString);
+  
+  static wxLog *ms_pLogger;       // currently active log sink
+  static bool   ms_bInitialized;  // any log targets created?
+};
+
+// ----------------------------------------------------------------------------
+// "trivial" derivations of wxLog
+// ----------------------------------------------------------------------------
+
+// log everything to a "FILE *", stderr by default
+class WXDLLEXPORT wxLogStderr : public wxLog
+{
+public:
+  // redirect log output to a FILE
+  wxLogStderr(FILE *fp = NULL);
+
+private:
+  // implement sink function
+  virtual void DoLogString(const char *szString);
+
+  FILE *m_fp;
+};
+
+// log everything to an "ostream", cerr by default
+class WXDLLEXPORT wxLogStream : public wxLog
+{
+public:
+  // redirect log output to an ostream
+  wxLogStream(ostream *ostr = NULL);
+
+protected:
+  // implement sink function
+  virtual void DoLogString(const char *szString);
+
+  // @@ using ptr here to avoid including <iostream.h> from this file
+  ostream *m_ostr;
+};
+
+/*
+// log everything to a text window (GUI only of course)
+class WXDLLEXPORT wxLogTextCtrl : public wxLogStream
+{
+public:
+  // we just create an ostream from wxTextCtrl and use it in base class
+  wxLogTextCtrl(wxTextCtrl *pTextCtrl);
+ ~wxLogTextCtrl();
+};
+*/
+
+// ----------------------------------------------------------------------------
+// GUI log target, the default one for wxWindows programs
+// ----------------------------------------------------------------------------
+class WXDLLEXPORT wxLogGui : public wxLog
+{
+public:
+  // ctor
+  wxLogGui();
+
+  // show all messages that were logged since the last Flush()
+  virtual void Flush();
+
+protected:
+  virtual void DoLog(Level level, const char *szString);
+
+  wxArrayString m_aMessages;
+  bool          m_bErrors;
+};
+
+// ----------------------------------------------------------------------------
+// /dev/null log target: suppress logging until this object goes out of scope
+// ----------------------------------------------------------------------------
+
+// example of usage:
+/*
+void Foo() {
+  wxFile file;
+
+  // wxFile.Open() normally complains if file can't be opened, we don't want it
+  wxLogNull logNo;
+  if ( !file.Open("bar") )
+    ... process error ourselves ...
+
+  // ~wxLogNull called, old log sink restored
+}
+*/
+class WXDLLEXPORT wxLogNull
+{
+public:
+  // ctor saves old log target, dtor restores it
+  wxLogNull() { m_pPrevLogger = wxLog::SetActiveTarget(NULL); }
+ ~wxLogNull() { (void)wxLog::SetActiveTarget(m_pPrevLogger);  }
+
+private:
+  wxLog *m_pPrevLogger; // old log target
+};
+
+// ============================================================================
+// global functions
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// Log functions should be used by application instead of stdio, iostream &c
+// for log messages for easy redirection
+// ----------------------------------------------------------------------------
+
+// define wxLog<level>
+// -------------------
+
+// NB: all these functions take `wxTString' and not
+//     `const wxTString&' because according to C++ standard
+//     the first argument to a vararg function can not be
+//     an array, function or reference :-(
+
+// the most generic log function
+void WXDLLEXPORT wxLogGeneric(wxLog::Level level, wxTString strFormat, ...);
+
+#define DECLARE_LOG_FUNCTION(level)                                 \
+        extern void WXDLLEXPORT wxLog##level(wxTString strFormat, ...)
+
+// one function per each level
+DECLARE_LOG_FUNCTION(FatalError);
+DECLARE_LOG_FUNCTION(Error);
+DECLARE_LOG_FUNCTION(Warning);
+DECLARE_LOG_FUNCTION(Message);
+DECLARE_LOG_FUNCTION(Info);
+DECLARE_LOG_FUNCTION(Status);
+DECLARE_LOG_FUNCTION(Verbose);
+
+// additional one: as wxLogError, but also logs last system call error code
+// and the corresponding error message if available
+DECLARE_LOG_FUNCTION(SysError);
+
+// and another one which also takes the error code (for those broken APIs
+// that don't set the errno (like registry APIs in Win32))
+void WXDLLEXPORT wxLogSysError(long lErrCode, wxTString strFormat, ...);
+
+// debug functions don't translate their arguments
+#undef  DECLARE_LOG_FUNCTION
+#define DECLARE_LOG_FUNCTION(level)                                 \
+        extern void WXDLLEXPORT wxLog##level(const char *szFormat, ...)
+
+DECLARE_LOG_FUNCTION(Debug);
+DECLARE_LOG_FUNCTION(Trace);
+
+// are we in 'verbose' mode?
+// (note that it's often handy to change this var manually from the
+//  debugger, thus enabling/disabling verbose reporting for some
+//  parts of the program only)
+WXDLLEXPORT_DATA(extern bool) g_bVerbose;
+
+// fwd decl to avoid including iostream.h here
+class ostream;
+
+// ----------------------------------------------------------------------------
+// get error code/error message from system in a portable way
+// ----------------------------------------------------------------------------
+
+// return the last system error code
+unsigned long WXDLLEXPORT wxSysErrorCode();
+// return the error message for given (or last if 0) error code
+const char* WXDLLEXPORT wxSysErrorMsg(unsigned long nErrCode = 0);
+
+// ----------------------------------------------------------------------------
+// debug only logging functions: use them with API name and error code
+// ----------------------------------------------------------------------------
+
+#ifdef  __DEBUG__
+  #define wxLogApiError(api, rc)                                              \
+                    wxLogDebug("At %s(%d) '%s' failed with error %lx (%s).",  \
+                               __FILE__, __LINE__, api,                       \
+                               rc, wxSysErrorMsg(rc))
+  #define wxLogLastError(api) wxLogApiError(api, ::GetLastError())
+#else   //!debug
+  #define wxLogApiError(api, rc)
+  #define wxLogLastError(api)
+#endif  //debug/!debug
+
+#endif  //__LOGH__
diff --git a/include/wx/matrix.h b/include/wx/matrix.h
new file mode 100644
index 0000000000..1c5b592778
--- /dev/null
+++ b/include/wx/matrix.h
@@ -0,0 +1,139 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        matrix.h
+// Purpose:     wxTransformMatrix class. NOT YET USED
+// Author:      Chris Breeze, Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __MATRIXH__
+#define __MATRIXH__
+
+#ifdef __GNUG__
+#pragma interface "matrix.h"
+#endif
+
+#include "wx/object.h"
+
+// A simple 3x3 matrix. This may be replaced by a more general matrix
+// class some day.
+//
+// Note: this is intended to be used in wxDC at some point to replace
+// the current system of scaling/translation. It is not yet used.
+
+class WXDLLEXPORT wxTransformMatrix: public wxObject
+{
+public:
+	wxTransformMatrix(void);
+	wxTransformMatrix(const wxTransformMatrix& mat);
+
+	double GetValue(int row, int col) const;
+	void SetValue(int row, int col, double value);
+
+	void operator = (const wxTransformMatrix& mat);
+	bool operator == (const wxTransformMatrix& mat);
+	bool operator != (const wxTransformMatrix& mat);
+
+	double& operator()(int row, int col);
+	double operator()(int row, int col) const;
+
+	// Invert matrix
+	bool Invert(void);
+
+	// Make into identity matrix
+	bool Identity(void);
+
+	// Is the matrix the identity matrix?
+	// Only returns a flag, which is set whenever an operation
+	// is done.
+	inline bool IsIdentity(void) const { return m_isIdentity; };
+
+	// This does an actual check.
+	inline bool IsIdentity1(void) const ;
+
+	// Isotropic scaling
+	bool Scale(double scale);
+
+	// Translate
+	bool Translate(double x, double y);
+
+	// Rotate
+	bool Rotate(double angle);
+
+	// Transform X value from logical to device
+	inline double TransformX(double x) const;
+
+	// Transform Y value from logical to device
+	inline double TransformY(double y) const;
+
+	// Transform a point from logical to device coordinates
+	bool TransformPoint(double x, double y, double& tx, double& ty) const;
+
+	// Transform a point from device to logical coordinates.
+
+	// Example of use:
+	//   wxTransformMatrix mat = dc.GetTransformation();
+	//   mat.Invert();
+	//   mat.InverseTransformPoint(x, y, x1, y1);
+	// OR (shorthand:)
+	//   dc.LogicalToDevice(x, y, x1, y1);
+	// The latter is slightly less efficient if we're doing several
+	// conversions, since the matrix is inverted several times.
+
+	// N.B. 'this' matrix is the inverse at this point
+
+	bool InverseTransformPoint(double x, double y, double& tx, double& ty) const;
+
+public:
+    double 	m_matrix[3][3];
+	bool	m_isIdentity;
+/*
+	double m11, m21, m31;
+	double m12, m22, m32;
+	double m13, m23, m33;
+*/
+};
+
+// Transform X value from logical to device
+inline double wxTransformMatrix::TransformX(double x) const
+{
+//	return (m_isIdentity ? x : (x * m_matrix[0][0] + y * m_matrix[1][0] + m_matrix[2][0]));
+  return 0;
+}
+
+// Transform Y value from logical to device
+inline double wxTransformMatrix::TransformY(double y) const
+{
+//	return (m_isIdentity ? y : (x * m_matrix[0][1] + y * m_matrix[1][1] + m_matrix[2][1]));
+  return 0;
+}
+
+// Is the matrix the identity matrix?
+// Perhaps there's some kind of optimization we can do to make this
+// a faster operation. E.g. each operation (scale, translate etc.)
+// checks whether it's still the identity matrix and sets a flag.
+inline bool wxTransformMatrix::IsIdentity1(void) const
+{
+	return
+	 (m_matrix[0][0] == 1.0 &&
+	  m_matrix[1][1] == 1.0 &&
+	  m_matrix[2][2] == 1.0 &&
+	  m_matrix[1][0] == 0.0 &&
+	  m_matrix[2][0] == 0.0 &&
+	  m_matrix[0][1] == 0.0 &&
+	  m_matrix[2][1] == 0.0 &&
+	  m_matrix[0][2] == 0.0 &&
+	  m_matrix[1][2] == 0.0) ;
+}
+
+// Calculates the determinant of a 2 x 2 matrix
+inline double wxCalculateDet(double a11, double a21, double a12, double a22)
+{
+	return a11 * a22 - a12 * a21;
+}
+
+#endif
+	// __MATRIXH__
diff --git a/include/wx/mdi.h b/include/wx/mdi.h
new file mode 100644
index 0000000000..fade7fa0dd
--- /dev/null
+++ b/include/wx/mdi.h
@@ -0,0 +1,13 @@
+#ifndef __MDIH_BASE__
+#define __MDIH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/mdi.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/mdi.h"
+#elif defined(__GTK__)
+#include "wx/gtk/mdi.h"
+#endif
+
+#endif
+    // __MDIH_BASE__
diff --git a/include/wx/memory.h b/include/wx/memory.h
new file mode 100644
index 0000000000..840d5085ca
--- /dev/null
+++ b/include/wx/memory.h
@@ -0,0 +1,277 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        memory.h
+// Purpose:     MDI classes
+// Author:      Arthur Seaton, Julian Smart
+// Modified by:
+// Created:     29/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Julian Smart
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __MEMORYH__
+#define __MEMORYH__
+
+#ifdef __GNUG__
+#pragma interface "memory.h"
+#endif
+
+#include "wx/defs.h"
+
+/*
+  The macro which will be expanded to include the file and line number
+  info, or to be a straight call to the new operator.
+*/
+
+#if (DEBUG && USE_MEMORY_TRACING) || USE_DEBUG_CONTEXT
+
+#include <stddef.h>
+
+#if USE_IOSTREAMH
+#include <iostream.h>
+#else
+#include <iostream>
+#endif
+
+#include "wx/string.h"
+
+#ifndef WXDEBUG_NEW
+#define WXDEBUG_NEW new(__FILE__,__LINE__)
+#endif
+
+#if DEBUG
+void * wxDebugAlloc(size_t size, char * fileName, int lineNum, bool isObject, bool isVect = FALSE);
+void wxDebugFree(void * buf, bool isVect = FALSE);
+
+// Global versions of the new and delete operators.
+// Currently, these merely call malloc and free; only the wxObject
+// operators do something interesting. But this allows WXDEBUG_NEW to
+// work for all 'new's in a file.
+#if USE_GLOBAL_MEMORY_OPERATORS
+
+#ifdef new
+#undef new
+#endif
+
+void * operator new (size_t size, char * fileName, int lineNum);
+void operator delete (void * buf);
+
+void * operator new[] (size_t size, char * fileName, int lineNum);
+void operator delete[] (void * buf);
+
+#define new WXDEBUG_NEW
+
+#endif
+#endif
+
+typedef unsigned int wxMarkerType;
+
+/*
+  Define the struct which will be placed at the start of all dynamically
+  allocated memory.
+*/
+
+class WXDLLEXPORT wxMemStruct {
+
+friend class WXDLLEXPORT wxDebugContext; // access to the m_next pointer for list traversal.
+
+public:
+public:
+    int AssertList ();
+
+    size_t RequestSize () { return m_reqSize; }
+    wxMarkerType Marker () { return m_firstMarker; }
+
+    // When an object is deleted we set the id slot to a specific value.
+    inline void SetDeleted ();
+    inline int IsDeleted ();
+
+    int Append ();
+    int Unlink ();
+
+    // Used to determine if the object is really a wxMemStruct.
+    // Not a foolproof test by any means, but better than none I hope!
+    int AssertIt ();
+
+    // Do all validation on a node.
+    int ValidateNode ();
+
+    // Check the integrity of a node and of the list, node by node.
+    int CheckBlock ();
+    int CheckAllPrevious ();
+
+    // Print a single node.
+    void PrintNode ();
+
+    // Called when the memory linking functions get an error.
+    void ErrorMsg (const char *);
+    void ErrorMsg ();
+
+    inline void *GetActualData(void) const { return m_actualData; }
+
+    void Dump(void);
+
+public:
+    // Check for underwriting. There are 2 of these checks. This one
+    // inside the struct and another right after the struct.
+    wxMarkerType        m_firstMarker;
+
+    // File name and line number are from cpp.
+    char*               m_fileName;
+    int                 m_lineNum;
+
+    // The amount of memory requested by the caller.
+    size_t              m_reqSize;
+
+    // Used to try to verify that we really are dealing with an object
+    // of the required class. Can be 1 of 2 values these indicating a valid
+    // wxMemStruct object, or a deleted wxMemStruct object.
+    wxMarkerType        m_id;
+
+    wxMemStruct *       m_prev;
+    wxMemStruct *       m_next;
+
+    void *              m_actualData;
+    bool                m_isObject;
+};
+
+
+typedef void (wxMemStruct::*PmSFV) ();
+
+
+/*
+  Debugging class. This will only have a single instance, but it\'s
+  a reasonable way to keep everything together and to make this
+  available for change if needed by someone else.
+  A lot of this stuff would be better off within the wxMemStruct class, but
+  it\'s stuff which we need to access at times when there is no wxMemStruct
+  object so we use this class instead. Think of it as a collection of
+  globals which have to do with the wxMemStruct class.
+*/
+
+class WXDLLEXPORT wxDebugContext {
+
+protected:
+    // Used to set alignment for markers.
+    static size_t CalcAlignment ();
+
+    // Returns the amount of padding needed after something of the given
+    // size. This is so that when we cast pointers backwards and forwards
+    // the pointer value will be valid for a wxMarkerType.
+    static size_t GetPadding (const size_t size) ;
+
+    // Traverse the list.
+    static void TraverseList (PmSFV, wxMemStruct *from = NULL);
+
+    static streambuf *m_streamBuf;
+    static ostream *m_debugStream;
+
+    static int debugLevel;
+    static bool debugOn;
+
+public:
+    // Set a checkpoint to dump only the memory from
+    // a given point
+    static wxMemStruct *checkPoint;
+
+    wxDebugContext(void);
+    ~wxDebugContext(void);
+
+    static bool HasStream(void) { return (m_debugStream != NULL); };
+    static ostream& GetStream(void) { return *m_debugStream; }
+    static streambuf *GetStreamBuf(void) { return m_streamBuf; }
+    static void SetStream(ostream *stream, streambuf *buf = NULL);
+    static bool SetFile(const wxString& file);
+    static bool SetStandardError(void);
+
+    static int GetLevel(void) { return debugLevel; }
+    static void SetLevel(int level) { debugLevel = level; }
+
+    static bool GetDebugMode(void) { return debugOn; }
+    static void SetDebugMode(bool flag) { debugOn = flag; }
+
+    static void SetCheckpoint(bool all = FALSE);
+    static wxMemStruct *GetCheckpoint(void) { return checkPoint; }
+    
+    // Calculated from the request size and any padding needed
+    // before the final marker.
+    static size_t PaddedSize (const size_t reqSize);
+
+    // Calc the total amount of space we need from the system
+    // to satisfy a caller request. This includes all padding.
+    static size_t TotSize (const size_t reqSize);
+
+    // Return valid pointers to offsets within the allocated memory.
+    static char * StructPos (const char * buf);
+    static char * MidMarkerPos (const char * buf);
+    static char * CallerMemPos (const char * buf);
+    static char * EndMarkerPos (const char * buf, const size_t size);
+
+    // Given a pointer to the start of the caller requested area
+    // return a pointer to the start of the entire alloc\'d buffer.
+    static char * StartPos (const char * caller);
+
+    // Access to the list.
+    static wxMemStruct * GetHead () { return m_head; }
+    static wxMemStruct * GetTail () { return m_tail; }
+
+    // Set the list sentinals.
+    static wxMemStruct * SetHead (wxMemStruct * st) { return (m_head = st); }
+    static wxMemStruct * SetTail (wxMemStruct * st) { return (m_tail = st); }
+
+    // If this is set then every new operation checks the validity
+    // of the all previous nodes in the list.
+    static bool GetCheckPrevious () { return m_checkPrevious; }
+    static void SetCheckPrevious (bool value) { m_checkPrevious = value; }
+
+    // Checks all nodes, or all nodes if checkAll is TRUE
+    static int Check(bool checkAll = FALSE);
+
+    // Print out the list of wxMemStruct nodes.
+    static bool PrintList(void);
+
+    // Dump objects
+    static bool Dump(void);
+
+    // Print statistics
+    static bool PrintStatistics(bool detailed = TRUE);
+
+    // Print out the classes in the application.
+    static bool PrintClasses(void);
+
+    // Count the number of non-wxDebugContext-related objects
+    // that are outstanding
+    static int CountObjectsLeft(void);
+
+private:
+    // Store these here to allow access to the list without
+    // needing to have a wxMemStruct object.
+    static wxMemStruct*         m_head;
+    static wxMemStruct*         m_tail;
+
+    // Set to FALSE if we're not checking all previous nodes when
+    // we do a new. Set to TRUE when we are.
+    static bool                 m_checkPrevious;
+};
+
+// Output a debug mess., in a system dependent fashion.
+void WXDLLEXPORT wxTrace(const char *fmt ...);
+void WXDLLEXPORT wxTraceLevel(int level, const char *fmt ...);
+
+#define WXTRACE wxTrace
+#define WXTRACELEVEL wxTraceLevel
+
+#else // else part for the #if DEBUG
+
+inline void wxTrace(const char *WXUNUSED(fmt)) {}
+inline void wxTraceLevel(int WXUNUSED(level), const char *WXUNUSED(fmt)) {}
+
+#define WXTRACE TRUE ? (void)0 : wxTrace
+#define WXTRACELEVEL TRUE ? (void)0 : wxTraceLevel
+#define WXDEBUG_NEW new
+
+#endif // DEBUG
+
+#endif
+    // __MEMORYH__
+
diff --git a/include/wx/menu.h b/include/wx/menu.h
new file mode 100644
index 0000000000..9a9335729d
--- /dev/null
+++ b/include/wx/menu.h
@@ -0,0 +1,13 @@
+#ifndef __MENUH_BASE__
+#define __MENUH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/menu.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/menu.h"
+#elif defined(__GTK__)
+#include "wx/gtk/menu.h"
+#endif
+
+#endif
+    // __MENUH_BASE__
diff --git a/include/wx/menuitem.h b/include/wx/menuitem.h
new file mode 100644
index 0000000000..5de85d5e24
--- /dev/null
+++ b/include/wx/menuitem.h
@@ -0,0 +1,89 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        menuitem.h
+// Purpose:     wxMenuItem class
+// Author:      Vadim Zeitlin
+// Modified by: 
+// Created:     11.11.97
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// Licence:     wxWindows license
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef   _MENUITEM_H
+#define   _MENUITEM_H
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+// an exception to the general rule that a normal header doesn't include other
+// headers - only because ownerdrw.h is not always included and I don't want
+// to write #ifdef's everywhere...
+#if USE_OWNER_DRAWN
+#include  "wx/ownerdrw.h"
+#endif
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+// id for a separator line in the menu (invalid for normal item)
+#define   ID_SEPARATOR    (-1)
+
+// ----------------------------------------------------------------------------
+// wxMenuItem: an item in the menu, optionally implements owner-drawn behaviour
+// ----------------------------------------------------------------------------
+class WXDLLEXPORT wxMenuItem: public wxObject
+#if USE_OWNER_DRAWN
+                            , public wxOwnerDrawn
+#endif
+{
+DECLARE_DYNAMIC_CLASS(wxMenuItem)
+
+public:
+  // ctor & dtor
+  wxMenuItem(wxMenu *pParentMenu = NULL, int id = ID_SEPARATOR,
+             const wxTString& strName = "", const wxTString& wxHelp = "",
+             bool bCheckable = FALSE, wxMenu *pSubMenu = NULL);
+  virtual ~wxMenuItem();
+
+  // accessors (some more are inherited from wxOwnerDrawn or are below)
+  bool              IsSeparator() const { return m_idItem == ID_SEPARATOR;  }
+  bool              IsEnabled()   const { return m_bEnabled;  }
+  bool              IsChecked()   const { return m_bChecked;  }
+
+  int               GetId()       const { return m_idItem;    }
+  const wxString&   GetHelp()     const { return m_strHelp;   }
+  wxMenu           *GetSubMenu()  const { return m_pSubMenu;  }
+
+  // operations
+  void SetName(const wxString& strName) { m_strName = strName; }
+  void SetHelp(const wxString& strHelp) { m_strHelp = strHelp; }
+
+  void Enable(bool bDoEnable = TRUE);
+  void Check(bool bDoCheck = TRUE);
+
+  void DeleteSubMenu();
+
+private:
+  int         m_idItem;         // numeric id of the item
+  wxString    m_strHelp;        // associated help string
+  wxMenu     *m_pSubMenu,       // may be NULL
+             *m_pParentMenu;    // menu this item is contained in
+  bool        m_bEnabled,       // enabled or greyed?
+              m_bChecked;       // checked? (only if checkable)
+
+#if USE_OWNER_DRAWN
+  // wxOwnerDrawn base class already has these variables - nothing to do
+
+#else   //!owner drawn
+  bool        m_bCheckable;     // can be checked?
+  wxString    m_strName;        // name or label of the item
+
+public:
+  const wxString&   GetName()     const { return m_strName;    }
+  bool              IsCheckable() const { return m_bCheckable; }
+#endif  //owner drawn
+};
+
+#endif  //_MENUITEM_H
\ No newline at end of file
diff --git a/include/wx/metafile.h b/include/wx/metafile.h
new file mode 100644
index 0000000000..20e53dd894
--- /dev/null
+++ b/include/wx/metafile.h
@@ -0,0 +1,9 @@
+#ifndef __METAFILEH_BASE__
+#define __METAFILEH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/metafile.h"
+#endif
+
+#endif
+    // __METAFILEH_BASE__
diff --git a/include/wx/minifram.h b/include/wx/minifram.h
new file mode 100644
index 0000000000..d340f57307
--- /dev/null
+++ b/include/wx/minifram.h
@@ -0,0 +1,13 @@
+#ifndef __MINIFRAMH_BASE__
+#define __MINIFRAMH_BASE_
+
+#if defined(__WINDOWS__)
+#include "wx/msw/minifram.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/minifram.h"
+#elif defined(__GTK__)
+#include "wx/gtk/minifram.h"
+#endif
+
+#endif
+    // __MINIFRAMH_BASE__
diff --git a/include/wx/module.h b/include/wx/module.h
new file mode 100644
index 0000000000..aaa9354269
--- /dev/null
+++ b/include/wx/module.h
@@ -0,0 +1,49 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        module.h
+// Purpose:     Modules handling
+// Author:      Wolfram Gloger/adapted by Guilhem Lavaux
+// Modified by:
+// Created:     04/11/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Wolfram Gloger and Guilhem Lavaux
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __MODULEH__
+#define __MODULEH__
+
+#ifdef __GNUG__
+#pragma interface "module.h"
+#endif
+
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/setup.h"
+
+class WXDLLEXPORT wxModule: public wxObject
+{
+public:
+    wxModule(void) {}
+    ~wxModule(void) {}
+
+    // If returns FALSE, quits the application immediately.
+    bool Init(void) { return OnInit(); }
+    void Exit(void) { OnExit(); }
+
+    // Override both of these
+    virtual bool OnInit(void) = 0;
+    virtual void OnExit(void) = 0;
+
+    static void RegisterModule(wxModule* module);
+    static bool RegisterModules(void);
+    static bool InitializeModules(void);
+    static void CleanUpModules(void);
+
+protected:
+    static wxList   m_modules;
+
+DECLARE_CLASS(wxModule)
+};
+
+#endif
+
diff --git a/include/wx/msgdlg.h b/include/wx/msgdlg.h
new file mode 100644
index 0000000000..0771b4631b
--- /dev/null
+++ b/include/wx/msgdlg.h
@@ -0,0 +1,13 @@
+#ifndef __MSGDLGH_BASE__
+#define __MSGDLGH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/msgdlg.h"
+#elif defined(__MOTIF__)
+#include "wx/generic/msgdlgg.h"
+#elif defined(__GTK__)
+#include "wx/generic/msgdlgg.h"
+#endif
+
+#endif
+    // __MSGDLGH_BASE__
diff --git a/include/wx/object.h b/include/wx/object.h
new file mode 100644
index 0000000000..b11e323e69
--- /dev/null
+++ b/include/wx/object.h
@@ -0,0 +1,269 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        object.h
+// Purpose:     wxObject class, plus run-time type information macros
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __OBJECTH__
+#define __OBJECTH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+
+class WXDLLEXPORT wxObject;
+
+#if USE_DYNAMIC_CLASSES
+
+#ifdef __GNUWIN32__
+#ifdef GetClassName
+#undef GetClassName
+#endif
+#endif
+
+class WXDLLEXPORT wxClassInfo;
+
+class WXDLLIMPORT istream;
+class WXDLLIMPORT ostream;
+
+/*
+ * Dynamic object system declarations
+ */
+
+typedef wxObject * (*wxObjectConstructorFn) (void);
+
+#ifdef USE_STORABLE_CLASSES
+typedef wxObject* (*wxStorableConstructorFn) ( istream &stream, char *data );
+#endif
+
+class WXDLLEXPORT wxClassInfo
+{
+ public:
+   char *className;
+   char *baseClassName1;
+   char *baseClassName2;
+   int objectSize;
+   wxObjectConstructorFn objectConstructor;
+   
+#ifdef USE_STORABLE_CLASSES
+  wxStorableConstructorFn storableConstructor;
+#endif
+
+   // Pointers to base wxClassInfos: set in InitializeClasses
+   // called from wx_main.cc
+   wxClassInfo *baseInfo1;
+   wxClassInfo *baseInfo2;
+
+   static wxClassInfo *first;
+   wxClassInfo *next;
+
+#ifdef USE_STORABLE_CLASSES
+   wxClassInfo(char *cName, char *baseName1, char *baseName2, int sz, wxObjectConstructorFn fn,
+     wxStorableConstructorFn stoFn = NULL );
+#else
+   wxClassInfo(char *cName, char *baseName1, char *baseName2, int sz, wxObjectConstructorFn fn);
+#endif
+
+   wxObject *CreateObject(void);
+   
+#ifdef USE_STORABLE_CLASSES
+   wxObject* CreateObject( istream &stream, char *data );
+#endif
+
+   inline char *GetClassName(void) const { return className; }
+   inline char *GetBaseClassName1(void) const { return baseClassName1; }
+   inline char *GetBaseClassName2(void) const { return baseClassName2; }
+   inline int GetSize(void) const { return objectSize; }
+   bool IsKindOf(wxClassInfo *info);
+
+   static wxClassInfo *FindClass(char *c);
+   // Initializes parent pointers for fast searching.
+   static void InitializeClasses(void);
+};
+
+wxObject* WXDLLEXPORT wxCreateDynamicObject(char *name);
+
+#ifdef USE_STORABLE_CLASSES
+wxObject* WXDLLEXPORT wxCreateStoredObject( char *name, istream &stream, char *data );
+#endif
+
+#define DECLARE_DYNAMIC_CLASS(name) \
+ public:\
+  static wxClassInfo class##name;\
+  wxClassInfo *GetClassInfo() \
+   { return &name::class##name; }
+
+#define DECLARE_ABSTRACT_CLASS(name) DECLARE_DYNAMIC_CLASS(name)
+#define DECLARE_CLASS(name) DECLARE_DYNAMIC_CLASS(name)
+
+#ifdef USE_STORABLE_CLASSES
+#define DECLARE_STORABLECLASS(name) DECLARE_DYNAMIC_CLASS(name)
+#endif
+
+//////
+////// for concrete classes
+//////
+
+// Single inheritance with one base class
+#define IMPLEMENT_DYNAMIC_CLASS(name, basename) \
+wxObject* WXDLLEXPORT_CTORFN wxConstructorFor##name(void) \
+   { return new name; }\
+ wxClassInfo name::class##name(#name, #basename, NULL, sizeof(name), wxConstructorFor##name);
+
+// Multiple inheritance with two base classes
+#define IMPLEMENT_DYNAMIC_CLASS2(name, basename1, basename2) \
+wxObject* WXDLLEXPORT_CTORFN wxConstructorFor##name(void) \
+   { return new name; }\
+ wxClassInfo name::class##name(#name, #basename1, #basename2, sizeof(name), wxConstructorFor##name);
+
+//////
+////// for storable classes
+//////
+
+#ifdef USE_STORABLE_CLASSES
+
+#define IMPLEMENT_STORABLE_CLASS(name, basename) \
+wxObject* WXDLLEXPORT_CTORFN wxStorableConstructorFor##name( fstream* stream, char* data )\
+	{ return new name( stream, data ); }\
+wxObject* WXDLLEXPORT_CTORFN wxConstructorFor##name(void)\
+   { return new name; }\
+ wxClassInfo name::class##name(#name, #basename, NULL, sizeof(name), wxConstructorFor##name,\
+   wxStorableConstructorFor##name );
+
+#define IMPLEMENT_STORABLE_CLASS2(name, basename1, basename2) \
+wxObject* WXDLLEXPORT_CTORFN wxStorableConstructorFor##name( fstream* stream, char* data )\
+	{ return new name( stream, data ); }\
+wxObject* WXDLLEXPORT_CTORFN wxConstructorFor##name(void)\
+   { return new name; }\
+ wxClassInfo name::class##name(#name, #basename1, basename2, sizeof(name), wxConstructorFor##name,\
+   wxStorableConstructorFor##name );
+
+#endif
+ 
+//////
+////// for abstract classes
+//////
+
+// Single inheritance with one base class
+#define IMPLEMENT_ABSTRACT_CLASS(name, basename) \
+ wxClassInfo name::class##name(#name, #basename, NULL, sizeof(name), NULL);
+
+// Multiple inheritance with two base classes
+#define IMPLEMENT_ABSTRACT_CLASS2(name, basename1, basename2) \
+ wxClassInfo name::class##name(#name, #basename1, #basename2, sizeof(name), NULL);
+
+#define IMPLEMENT_CLASS IMPLEMENT_ABSTRACT_CLASS
+#define IMPLEMENT_CLASS2 IMPLEMENT_ABSTRACT_CLASS2
+
+#define CLASSINFO(name) (&name::class##name)
+
+#else
+
+// No dynamic class system: so stub out the macros
+#define DECLARE_DYNAMIC_CLASS(name)
+#define DECLARE_ABSTRACT_CLASS(name)
+#define DECLARE_CLASS(name)
+#define IMPLEMENT_DYNAMIC_CLASS(name, basename)
+#define IMPLEMENT_DYNAMIC_CLASS2(name, basename1, basename2)
+#define IMPLEMENT_ABSTRACT_CLASS(name, basename)
+#define IMPLEMENT_ABSTRACT_CLASS2(name, basename1, basename2)
+#define IMPLEMENT_CLASS IMPLEMENT_ABSTRACT_CLASS
+#define IMPLEMENT_CLASS2 IMPLEMENT_ABSTRACT_CLASS2
+
+#endif
+
+#define IS_KIND_OF(obj, className) obj->IsKindOf(&className::class##name)
+
+// Unfortunately Borland seems to need this include.
+#ifdef __BORLANDC__
+#if USE_IOSTREAMH
+#include <iostream.h>
+#else
+#include <iostream>
+#endif
+#endif
+
+class WXDLLEXPORT wxObjectRefData;
+
+class WXDLLEXPORT wxObject
+{
+ public:
+
+  // This is equivalent to using the macro DECLARE_ABSTRACT_CLASS
+  static wxClassInfo classwxObject;
+
+  wxObject(void);
+  virtual ~wxObject(void);
+
+  virtual wxClassInfo *GetClassInfo(void) { return &classwxObject; }
+
+  bool IsKindOf(wxClassInfo *info);
+
+#if DEBUG && USE_MEMORY_TRACING
+  void * operator new (size_t size, char * fileName = NULL, int lineNum = 0);
+  void operator delete (void * buf);
+  
+  // Cause problems for VC++
+#ifndef _MSC_VER
+  void * operator new[] (size_t size, char * fileName = NULL, int lineNum = 0);
+  void operator delete[] (void * buf);
+#endif
+
+#endif
+
+#if DEBUG || USE_DEBUG_CONTEXT
+  virtual void Dump(ostream& str);
+#endif
+
+#ifdef USE_STORABLE_CLASSES
+  virtual void StoreObject( ostream &WXUNUSED(stream) ) {};
+#endif
+
+  // make a 'clone' of the object
+  void Ref(const wxObject& clone);
+
+  // destroy a reference
+  void UnRef(void);
+
+  inline wxObjectRefData *GetRefData(void) const { return m_refData; }
+  inline void SetRefData(wxObjectRefData *data) { m_refData = data; }
+
+protected:
+  wxObjectRefData *m_refData;
+};
+
+/*
+ * wxObjectData
+ */
+
+class WXDLLEXPORT wxObjectRefData {
+
+    friend class wxObject;
+
+public:
+    wxObjectRefData(void);
+    virtual ~wxObjectRefData(void);
+
+    inline int GetRefCount(void) const { return m_count; }
+private:
+    int m_count;
+};
+
+#if DEBUG && USE_GLOBAL_MEMORY_OPERATORS
+#ifndef WXDEBUG_NEW
+#define WXDEBUG_NEW new(__FILE__,__LINE__)
+#endif
+#define new WXDEBUG_NEW
+#endif
+
+#endif
+    // __OBJECTH__
+
+
diff --git a/include/wx/odbc.h b/include/wx/odbc.h
new file mode 100644
index 0000000000..0f6756adcc
--- /dev/null
+++ b/include/wx/odbc.h
@@ -0,0 +1,322 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        odbc.h
+// Purpose:     ODBC classes
+// Author:      Olaf Klein, Patrick Halke, Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#include "wx/setup.h"
+
+#if USE_ODBC
+
+#ifndef __ODBCH__
+#define __ODBCH__
+
+#ifdef __WINDOWS__
+#include <windows.h>
+#endif
+
+#include <sqlext.h>
+
+#include "wx/defs.h"
+#include "wx/list.h"
+#include "wx/string.h"
+
+typedef RETCODE wxRETCODE;
+
+// Recordset open types
+#define wxOPEN_TYPE_DYNASET         1
+#define wxOPEN_TYPE_SNAPSHOT        2
+#define wxOPEN_TYPE_FORWARD_ONLY    3
+
+// Recordset open options
+#define wxOPTION_DEFAULT            1
+#define wxOPTION_APPEND_ONLY        2
+#define wxOPTION_READ_ONLY          3
+
+// Data types
+class WXDLLEXPORT wxRecordSet;
+
+class WXDLLEXPORT wxDatabase: public wxObject
+{
+  // JACS
+  DECLARE_DYNAMIC_CLASS(wxDatabase)
+ private:
+ protected:
+  static HENV hEnv;
+  static int refCount;
+  
+  HDBC hDBC;
+  char* username;
+  char* password;
+  char* datasource;
+  char* dbname;
+  char* connectstring;
+  bool isOpen;
+
+  // error-handling variables
+  wxRETCODE retcode;
+  char sqlstate[SQL_SQLSTATE_SIZE+1];  // error class and subclass
+  char errmsg[SQL_MAX_MESSAGE_LENGTH]; // error message
+  long nat_err;                        // error number by ODBC driver
+  bool err_occured;
+
+  wxList recordSets; // Record sets: Added by JACS
+
+ public:
+  wxDatabase(void);
+  ~wxDatabase(void);
+  
+  bool Open(char *, bool exclusive =FALSE, bool readOnly =TRUE, char *username ="ODBC", char *password ="");
+  bool Close(void);
+
+  // Cleanup operations, added by JACS
+  void DeleteRecordSets(void); // Called when the database is deleted
+  void ResetRecordSets(void); // Required if the database is closed
+  inline wxList& GetRecordSets(void) { return recordSets; }
+  
+  inline char *GetUsername(void) { return username; }
+  inline char *GetPassword(void) { return password; }
+  inline char *GetDataSource(void) { return datasource; }
+  inline bool IsOpen(void) { return isOpen; }
+  inline wxRETCODE GetErrorCode(void) { return retcode; }
+  inline HDBC GetHDBC(void) { return hDBC; }
+  inline HENV GetHENV(void) { return hEnv; }
+  
+  void SetPassword(char *s);
+  void SetUsername(char *s);
+  void SetDataSource(char *s);
+  
+  // Database attributes
+  char *GetDatabaseName(void);
+  bool CanUpdate(void);
+  bool CanTransact(void);
+  bool InWaitForDataSource(void);
+  void SetLoginTimeout(long seconds);
+  void SetQueryTimeout(long seconds);
+  void SetSynchronousMode(bool synchronous);
+
+  // Database operations
+  bool BeginTrans(void);
+  bool CommitTrans(void);
+  bool RollbackTrans(void);
+  void Cancel(void);
+
+  // Error handling
+  bool ErrorOccured(void);
+  char* GetErrorMessage(void);
+  long  GetErrorNumber(void);
+  char* GetErrorClass(void);
+  inline void ErrorSnapshot(HSTMT =SQL_NULL_HSTMT);
+
+  // Overridables
+  virtual void OnSetOptions(wxRecordSet *recordSet);
+  virtual void OnWaitForDataSource(bool stillExecuting);
+
+  bool GetInfo(long infoType, long *buf);
+  bool GetInfo(long infoType, char *buf, int bufSize = -1);
+
+  // implementation = TRUE means get the DLL version.
+  // Otherwise, returns header file version.
+  wxString GetODBCVersionString(bool implementation = TRUE);
+  float GetODBCVersionFloat(bool implementation = TRUE);
+};
+
+// Represents a data row
+class WXDLLEXPORT wxQueryField: public wxObject
+{
+  // JACS
+  DECLARE_DYNAMIC_CLASS(wxQueryField)
+ private:
+  void *data;
+  short type;
+  long size;
+  bool dirty;
+
+  bool AllocData(void);
+
+  public:
+  wxQueryField(void);
+  ~wxQueryField(void);
+  
+  bool SetData(void*, long);
+  void SetDirty(bool =TRUE);
+  void ClearData(void);
+  void SetType(short);
+  void SetSize(long);
+  
+  void* GetData(void);
+  short GetType(void);
+  long GetSize(void);
+  
+  bool IsDirty(void);
+};
+
+// Represents a column description
+class WXDLLEXPORT wxQueryCol: public wxObject
+{
+  // JACS
+  DECLARE_DYNAMIC_CLASS(wxQueryCol)
+ private:
+  short type;
+  char *name;
+  bool nullable;
+  long varsize;
+  void* var;
+  
+  public:
+  wxList fields;
+  
+  wxQueryCol(void);
+  ~wxQueryCol(void);
+  
+  void* BindVar(void*, long);
+  void FillVar(int);
+  void AppendField(void*, long);
+  bool SetData(int, void*, long);
+  void SetName(char*);
+  void SetNullable(bool);
+  void SetFieldDirty(int, bool =TRUE);
+  void SetType(short);
+  
+  char* GetName(void);
+  short GetType(void);
+  bool IsNullable(void);
+  void* GetData(int);
+  long GetSize(int);
+
+  bool IsFieldDirty(int);
+};
+
+class WXDLLEXPORT wxRecordSet: public wxObject
+{
+  // JACS
+  DECLARE_DYNAMIC_CLASS(wxRecordSet)
+ private:
+  int cursor;
+  int type;
+  int options;
+  
+  protected:
+  HSTMT hStmt;
+  int nFields;
+  int nParams;
+  int nRecords;
+  short nCols;
+  char *recordFilter;
+  char *sortString;
+  char *defaultSQL;
+  char* tablename;
+  wxDatabase *parentdb;
+  wxRETCODE retcode;
+  wxList cols;
+  wxList fetchbuf;
+  
+  void FillVars(int);
+
+  public:
+  // JACS gave parent a default value for benefit of IMPLEMENT_DYNAMIC_CLASS
+  wxRecordSet(wxDatabase *parent = NULL, int =wxOPEN_TYPE_DYNASET, int =wxOPTION_DEFAULT);
+  ~wxRecordSet(void);
+  
+  // My own, lower-level functions.
+  bool BeginQuery(int openType, char *sql = NULL, int options = wxOPTION_DEFAULT);
+  bool EndQuery(void);
+  bool Query(char* columns, char* table =NULL, char *filter =NULL);
+
+  // Attributes
+  inline int GetNumberFields(void) { return nFields; }
+  inline int GetNumberParams(void) { return nParams; }
+  long GetNumberRecords(void);
+  long GetNumberCols(void);
+  inline char *GetFilter(void) { return recordFilter; }
+  inline char *GetSortString(void) { return sortString; }
+  inline wxDatabase *GetDatabase(void) { return parentdb; }
+  inline wxRETCODE GetErrorCode(void) { return retcode; }
+  bool CanAppend(void);
+  bool CanRestart(void);
+  bool CanScroll(void);
+  bool CanTransact(void);
+  bool CanUpdate(void);
+  long GetCurrentRecord(void);
+  bool RecordCountFinal(void);
+  bool GetResultSet(void);
+  bool ExecuteSQL(char*);
+  bool GetTables(void);
+  bool GetColumns(char* =NULL);
+  bool GetPrimaryKeys(char* =NULL);
+  bool GetForeignKeys(char* , char * );
+  char *GetTableName(void);
+  void SetTableName(char*);
+  char *GetSQL(void);
+  bool IsOpen(void);
+  bool IsBOF(void);
+  bool IsEOF(void);
+  bool IsDeleted(void);
+
+  bool GetFieldData(int colPos, int dataType, void *dataPtr);
+  bool GetFieldData(const char*, int dataType, void *dataPtr);
+  void* GetFieldDataPtr(int, int);
+  void* GetFieldDataPtr(const char*, int);
+  char* GetColName(int);
+  short GetColType(int);
+  short GetColType(const char*);
+  void* BindVar(int, void*, long);
+  void* BindVar(const char*, void*, long);
+
+  void SetType(int);
+  int GetType(void);
+  void SetOptions(int);
+  int GetOptions(void);
+    
+  // Update operations
+  void AddNew(void);
+  bool Delete(void);
+  void Edit(void);
+  bool Update(void);
+
+  // Record navigation
+  virtual bool Move(long rows);
+  virtual bool MoveFirst(void);
+  virtual bool MoveLast(void);
+  virtual bool MoveNext(void);
+  virtual bool MovePrev(void);
+  virtual bool GoTo(long);
+
+  // Others
+  bool GetDataSources(void);
+
+  // Associate a column name/position with a data location
+  //   bool BindColumn(int colPos, int dataType, void *dataPtr);
+
+  void Cancel(void);
+  bool IsFieldDirty(int);
+  bool IsFieldDirty(const char*);
+  bool IsFieldNull(int);
+  bool IsFieldNull(const char*);
+  bool IsColNullable(int);
+  bool IsColNullable(const char*);
+  virtual bool Requery(void);
+  virtual void SetFieldDirty(int, bool dirty = TRUE);
+  virtual void SetFieldDirty(const char*, bool dirty = TRUE);
+  void SetFieldNull(void *p, bool isNull = TRUE);
+
+  // Overridables
+  virtual char *GetDefaultConnect(void);
+  virtual char *GetDefaultSQL(void);
+  
+  // Internal
+  
+  // Build SQL query from column specification
+  bool ConstructDefaultSQL(void);
+  void SetDefaultSQL(char *s);
+  bool ReleaseHandle(void); // Added JACS
+};
+
+#endif
+
+#endif  // USE_ODBC
diff --git a/include/wx/palette.h b/include/wx/palette.h
new file mode 100644
index 0000000000..1dbae83aa4
--- /dev/null
+++ b/include/wx/palette.h
@@ -0,0 +1,13 @@
+#ifndef __PALETTEH_BASE__
+#define __PALETTEH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/palette.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/palette.h"
+#elif defined(__GTK__)
+#include "wx/gtk/palette.h"
+#endif
+
+#endif
+    // __PALETTEH_BASE__
diff --git a/include/wx/panel.h b/include/wx/panel.h
new file mode 100644
index 0000000000..8944fee1c5
--- /dev/null
+++ b/include/wx/panel.h
@@ -0,0 +1,7 @@
+#ifndef __PANELH_BASE__
+#define __PANELH_BASE__
+
+#include "wx/generic/panelg.h"
+
+#endif
+    // __PANELH_BASE_
diff --git a/include/wx/pen.h b/include/wx/pen.h
new file mode 100644
index 0000000000..7a61d50a2a
--- /dev/null
+++ b/include/wx/pen.h
@@ -0,0 +1,13 @@
+#ifndef __PENH_BASE__
+#define __PENH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/pen.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/pen.h"
+#elif defined(__GTK__)
+#include "wx/gtk/pen.h"
+#endif
+
+#endif
+    // __PENH_BASE__
diff --git a/include/wx/pnghand.h b/include/wx/pnghand.h
new file mode 100644
index 0000000000..9ee53318d8
--- /dev/null
+++ b/include/wx/pnghand.h
@@ -0,0 +1,13 @@
+#ifndef __PNGHANDH_BASE__
+#define __PNGHANDH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/pnghand.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/pnghand.h"
+#elif defined(__GTK__)
+#include "wx/gtk/pnghand.h"
+#endif
+
+#endif
+    // __PNGHANDH_BASE__
diff --git a/include/wx/postscrp.h b/include/wx/postscrp.h
new file mode 100644
index 0000000000..0ec1ecc570
--- /dev/null
+++ b/include/wx/postscrp.h
@@ -0,0 +1,294 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        postscrp.h
+// Purpose:     wxPostScriptDC class
+// Author:      Julian Smart and others
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __POSTSCRPH__
+#define __POSTSCRPH__
+
+#ifdef __GNUG__
+#pragma interface "postscrp.h"
+#endif
+
+#include "wx/dc.h"
+#include "wx/dialog.h"
+
+#if USE_POSTSCRIPT
+
+class WXDLLIMPORT ofstream;
+class WXDLLEXPORT wxPostScriptDC: public wxDC
+{
+  DECLARE_DYNAMIC_CLASS(wxPostScriptDC)
+
+ public:
+  // Create a printer DC
+  wxPostScriptDC(void);
+  wxPostScriptDC(const wxString& output, bool interactive = TRUE, wxWindow *parent = NULL);
+
+  ~wxPostScriptDC(void);
+
+  bool Create(const wxString& output, bool interactive = TRUE, wxWindow *parent = NULL);
+
+  virtual bool PrinterDialog(wxWindow *parent = NULL);
+
+  inline virtual void BeginDrawing(void) {} ;
+  inline virtual void EndDrawing(void) {} ;
+
+  void FloodFill(long x1, long y1, wxColour *col, int style=wxFLOOD_SURFACE) ;
+  bool GetPixel(long x1, long y1, wxColour *col) const;
+
+  void DrawLine(long x1, long y1, long x2, long y2);
+  void CrossHair(long x, long y) ;
+  void DrawArc(long x1,long y1,long x2,long y2,long xc,long yc);
+  void DrawEllipticArc(long x,long y,long w,long h,double sa,double ea);
+  void DrawPoint(long x, long y);
+  // Avoid compiler warning
+  void DrawPoint(wxPoint& point) { wxDC::DrawPoint(point); }
+  void DrawLines(int n, wxPoint points[], long xoffset = 0, long yoffset = 0);
+  // Avoid compiler warning
+  void DrawLines(wxList *lines, long xoffset = 0, long yoffset = 0)
+  { wxDC::DrawLines(lines, xoffset, yoffset); }
+  void DrawPolygon(int n, wxPoint points[], long xoffset = 0, long yoffset = 0, int fillStyle=wxODDEVEN_RULE);
+  // Avoid compiler warning
+  void DrawPolygon(wxList *lines, long xoffset = 0, long yoffset = 0, int fillStyle=wxODDEVEN_RULE)
+  { wxDC::DrawPolygon(lines, xoffset, yoffset, fillStyle); }
+  void DrawRectangle(long x, long y, long width, long height);
+  void DrawRoundedRectangle(long x, long y, long width, long height, double radius = 20);
+  void DrawEllipse(long x, long y, long width, long height);
+
+/*
+  // Splines
+  // 3-point spline
+  void DrawSpline(long x1, long y1, long x2, long y2, long x3, long y3);
+  // Any number of control points - a list of pointers to wxPoints
+  void DrawSpline(wxList *points);
+  void DrawSpline(int n, wxPoint points[]);
+  
+  I define these in wxDC, after all they all do the same everywhere
+  
+*/
+  void DrawOpenSpline(wxList *points);
+
+  void DrawIcon(const wxIcon& icon, long x, long y);
+  void DrawText(const wxString& text, long x, long y, bool use16 = FALSE);
+
+  void Clear(void);
+  void SetFont(const wxFont& font);
+  void SetPen(const wxPen& pen);
+  void SetBrush(const wxBrush& brush);
+  void SetLogicalFunction(int function);
+  void SetBackground(const wxBrush& brush);
+  void SetClippingRegion(long x, long y, long width, long height);
+  void DestroyClippingRegion(void);
+
+  bool StartDoc(const wxString& message);
+  void EndDoc(void);
+  void StartPage(void);
+  void EndPage(void);
+
+  long GetCharHeight(void);
+  long GetCharWidth(void);
+  void GetTextExtent(const wxString& string, long *x, long *y,
+                     long *descent = NULL, long *externalLeading = NULL,
+                     wxFont *theFont = NULL, bool use16 = FALSE);
+  virtual void SetLogicalOrigin(long x, long y);
+  virtual void CalcBoundingBox(long x, long y);
+
+  void SetMapMode(int mode);
+  void SetUserScale(double x, double y);
+  long DeviceToLogicalX(int x) const;
+  long DeviceToLogicalY(int y) const;
+  long DeviceToLogicalXRel(int x) const;
+  long DeviceToLogicalYRel(int y) const;
+  long LogicalToDeviceX(long x) const;
+  long LogicalToDeviceY(long y) const;
+  long LogicalToDeviceXRel(long x) const;
+  long LogicalToDeviceYRel(long y) const;
+  bool Blit(long xdest, long ydest, long width, long height,
+            wxDC *source, long xsrc, long ysrc, int rop = wxCOPY, bool useMask = FALSE);
+  inline bool CanGetTextExtent(void) const { return FALSE; }
+  inline bool CanDrawBitmap(void) const { return FALSE; }
+
+  void GetSize(int* width, int* height) const;
+  void GetSizeMM(long *width, long *height) const;
+
+  inline void SetBackgroundMode(int WXUNUSED(mode)) {};
+  inline void SetPalette(const wxPalette& WXUNUSED(palette)) {}
+  
+  inline ofstream *GetStream(void) const { return m_pstream; }
+  inline int GetYOrigin(void) const { return m_yOrigin; }
+
+  void SetupCTM();
+
+protected:
+  int               m_yOrigin;          // For EPS
+  ofstream *        m_pstream;    // PostScript output stream
+  wxString          m_title;
+  unsigned char     m_currentRed;
+  unsigned char     m_currentGreen;
+  unsigned char     m_currentBlue;
+  double            m_scaleFactor;
+};
+
+#define wxID_PRINTER_COMMAND        1
+#define wxID_PRINTER_OPTIONS        2
+#define wxID_PRINTER_ORIENTATION    3
+#define wxID_PRINTER_MODES          4
+#define wxID_PRINTER_X_SCALE        5
+#define wxID_PRINTER_Y_SCALE        6
+#define wxID_PRINTER_X_TRANS        7
+#define wxID_PRINTER_Y_TRANS        8
+
+class WXDLLEXPORT wxPostScriptPrintDialog: public wxDialog
+{
+DECLARE_CLASS(wxPostScriptPrintDialog)
+public:
+    wxPostScriptPrintDialog (wxWindow *parent, const wxString& title,
+		      const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+			  const long style = wxDEFAULT_DIALOG_STYLE);
+
+    virtual int ShowModal(void) ;
+};
+
+
+// Print Orientation (Should also add Left, Right)
+enum {
+  PS_PORTRAIT = 1,
+  PS_LANDSCAPE = 2
+};// ps_orientation = PS_PORTRAIT;
+
+// Print Actions
+enum {
+  PS_PRINTER,
+  PS_FILE,
+  PS_PREVIEW
+};// ps_action = PS_PREVIEW;
+
+// PostScript printer settings
+void WXDLLEXPORT wxSetPrinterCommand(char *cmd);
+void WXDLLEXPORT wxSetPrintPreviewCommand(char *cmd);
+void WXDLLEXPORT wxSetPrinterOptions(char *flags);
+void WXDLLEXPORT wxSetPrinterOrientation(int orientation);
+void WXDLLEXPORT wxSetPrinterScaling(double x, double y);
+void WXDLLEXPORT wxSetPrinterTranslation(long x, long y);
+void WXDLLEXPORT wxSetPrinterMode(int mode);
+void WXDLLEXPORT wxSetPrinterFile(char *f);
+void WXDLLEXPORT wxSetAFMPath(char *f);
+
+// Get current values
+char* WXDLLEXPORT wxGetPrinterCommand(void);
+char* WXDLLEXPORT wxGetPrintPreviewCommand(void);
+char* WXDLLEXPORT wxGetPrinterOptions(void);
+int WXDLLEXPORT wxGetPrinterOrientation(void);
+void WXDLLEXPORT wxGetPrinterScaling(double* x, double* y);
+void WXDLLEXPORT wxGetPrinterTranslation(long *x, long *y);
+int WXDLLEXPORT wxGetPrinterMode(void);
+char* WXDLLEXPORT wxGetPrinterFile(void);
+char* WXDLLEXPORT wxGetAFMPath(void);
+
+/*
+ * PostScript print setup information
+ */
+
+class WXDLLEXPORT wxPrintSetupData: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxPrintSetupData)
+
+ public:
+  char *printerCommand;
+  char *previewCommand;
+  char *printerFlags;
+  char *printerFile;
+  int printerOrient;
+  double printerScaleX;
+  double printerScaleY;
+  long printerTranslateX;
+  long printerTranslateY;
+  // 1 = Preview, 2 = print to file, 3 = send to printer
+  int printerMode;
+  char *afmPath;
+  // A name in the paper database (see wx_print.h: the printing framework)
+  char *paperName;
+  bool printColour;
+ public:
+  wxPrintSetupData(void);
+  ~wxPrintSetupData(void);
+
+  void SetPrinterCommand(char *cmd);
+  void SetPaperName(char *paper);
+  void SetPrintPreviewCommand(char *cmd);
+  void SetPrinterOptions(char *flags);
+  void SetPrinterFile(char *f);
+  void SetPrinterOrientation(int orient);
+  void SetPrinterScaling(double x, double y);
+  void SetPrinterTranslation(long x, long y);
+  // 1 = Preview, 2 = print to file, 3 = send to printer
+  void SetPrinterMode(int mode);
+  void SetAFMPath(char *f);
+  void SetColour(bool col);
+
+  // Get current values
+  char *GetPrinterCommand(void);
+  char *GetPrintPreviewCommand(void);
+  char *GetPrinterOptions(void);
+  char *GetPrinterFile(void);
+  char *GetPaperName(void);
+  int GetPrinterOrientation(void);
+  void GetPrinterScaling(double* x, double* y);
+  void GetPrinterTranslation(long *x, long *y);
+  int GetPrinterMode(void);
+  char *GetAFMPath(void);
+  bool GetColour(void);
+
+  void operator=(wxPrintSetupData& data);
+};
+
+extern wxPrintSetupData* WXDLLEXPORT wxThePrintSetupData;
+extern void WXDLLEXPORT wxInitializePrintSetupData(bool init = TRUE);
+
+/*
+ * Again, this only really needed for non-Windows platforms
+ * or if you want to test the PostScript printing under Windows.
+ */
+
+class WXDLLEXPORT wxPrintPaperType: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxPrintPaperType)
+
+ public:
+  int widthMM;
+  int heightMM;
+  int widthPixels;
+  int heightPixels;
+  char *pageName;
+
+  wxPrintPaperType(char *name = NULL, int wmm = 0, int hmm = 0, int wp = 0, int hp = 0);
+  ~wxPrintPaperType(void);
+};
+
+class WXDLLEXPORT wxPrintPaperDatabase: public wxList
+{
+  DECLARE_DYNAMIC_CLASS(wxPrintPaperDatabase)
+
+ public:
+  wxPrintPaperDatabase(void);
+  ~wxPrintPaperDatabase(void);
+
+  void CreateDatabase(void);
+  void ClearDatabase(void);
+
+  void AddPaperType(char *name, int wmm, int hmm, int wp, int hp);
+  wxPrintPaperType *FindPaperType(char *name);
+};
+
+WXDLLEXPORT_DATA(extern wxPrintPaperDatabase*) wxThePrintPaperDatabase;
+
+#endif // USE_POSTSCRIPT
+#endif
+        // __POSTSCRPH__
diff --git a/include/wx/print.h b/include/wx/print.h
new file mode 100644
index 0000000000..0eeee4fe6a
--- /dev/null
+++ b/include/wx/print.h
@@ -0,0 +1,28 @@
+#ifndef __PRINTH_BASE__
+#define __PRINTH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/printwin.h"
+
+#ifndef wxPrinter
+#define wxPrinter wxWindowsPrinter
+#endif
+#ifndef wxPrintPreview
+#define wxPrintPreview wxWindowsPrintPreview
+#endif
+
+#else
+#include "wx/generic/printps.h"
+
+#ifndef wxPrinter
+#define wxPrinter wxPostScriptPrinter
+#endif
+#ifndef wxPrintPreview
+#define wxPrintPreview wxPostScriptPrintPreview
+#endif
+
+#endif
+
+
+#endif
+    // __PRINTH_BASE__
diff --git a/include/wx/printdlg.h b/include/wx/printdlg.h
new file mode 100644
index 0000000000..9570bfb9fe
--- /dev/null
+++ b/include/wx/printdlg.h
@@ -0,0 +1,13 @@
+#ifndef __PRINTDLGH_BASE__
+#define __PRINTDLGH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/printdlg.h"
+#elif defined(__MOTIF__)
+#include "wx/generic/prntdlgg.h"
+#elif defined(__GTK__)
+#include "wx/generic/prntdlgg.h"
+#endif
+
+#endif
+    // __PRINTDLGH_BASE__
diff --git a/include/wx/prntbase.h b/include/wx/prntbase.h
new file mode 100644
index 0000000000..9e1df3b8c0
--- /dev/null
+++ b/include/wx/prntbase.h
@@ -0,0 +1,335 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        prntbase.h
+// Purpose:     Base classes for printing framework
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __PRNTBASEH__
+#define __PRNTBASEH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/event.h"
+#include "wx/cmndata.h"
+#include "wx/panel.h"
+#include "wx/scrolwin.h"
+#include "wx/dialog.h"
+
+class WXDLLEXPORT wxDC;
+class WXDLLEXPORT wxButton;
+class WXDLLEXPORT wxChoice;
+class WXDLLEXPORT wxPrintout;
+class WXDLLEXPORT wxPrinterBase;
+class WXDLLEXPORT wxPrintDialog;
+class WXDLLEXPORT wxPrintPreviewBase;
+class WXDLLEXPORT wxPreviewCanvas;
+class WXDLLEXPORT wxPreviewControlBar;
+class WXDLLEXPORT wxPreviewFrame;
+
+/*
+ * Represents the printer: manages printing a wxPrintout object
+ */
+ 
+class WXDLLEXPORT wxPrinterBase: public wxObject
+{
+  DECLARE_CLASS(wxPrinterBase)
+
+ protected:
+  wxPrintData printData;
+  wxPrintout *currentPrintout;
+ public:
+  static  wxWindow *abortWindow;
+  static  bool abortIt;
+
+  wxPrinterBase(wxPrintData *data = NULL);
+  ~wxPrinterBase(void);
+
+  virtual wxWindow *CreateAbortWindow(wxWindow *parent, wxPrintout *printout);
+  virtual void ReportError(wxWindow *parent, wxPrintout *printout, char *message);
+  inline wxPrintData& GetPrintData(void) { return printData; };
+  inline bool GetAbort(void) { return abortIt; }
+
+  ///////////////////////////////////////////////////////////////////////////
+  // OVERRIDES
+
+  virtual bool Setup(wxWindow *parent) = 0;
+  virtual bool Print(wxWindow *parent, wxPrintout *printout, bool prompt = TRUE) = 0;
+  virtual bool PrintDialog(wxWindow *parent) = 0;
+};
+
+/*
+ * wxPrintout
+ * Represents an object via which a document may be printed.
+ * The programmer derives from this, overrides (at least) OnPrintPage,
+ * and passes it to a wxPrinter object for printing, or a wxPrintPreview
+ * object for previewing.
+ */
+ 
+class WXDLLEXPORT wxPrintout: public wxObject
+{
+  DECLARE_ABSTRACT_CLASS(wxPrintout)
+
+ private:
+   char *printoutTitle;
+   wxDC *printoutDC;
+
+   int pageWidthPixels;
+   int pageHeightPixels;
+
+   int pageWidthMM;
+   int pageHeightMM;
+
+   int PPIScreenX;
+   int PPIScreenY;
+   int PPIPrinterX;
+   int PPIPrinterY;
+
+   bool isPreview;
+ public:
+  wxPrintout(char *title = "Printout");
+  ~wxPrintout(void);
+
+  virtual bool OnBeginDocument(int startPage, int endPage);
+  virtual void OnEndDocument(void);
+  virtual void OnBeginPrinting(void);
+  virtual void OnEndPrinting(void);
+
+  // Guaranteed to be before any other functions are called
+  inline virtual void OnPreparePrinting(void) { }
+
+  virtual bool HasPage(int page);
+  virtual bool OnPrintPage(int page) = 0;
+  virtual void GetPageInfo(int *minPage, int *maxPage, int *pageFrom, int *pageTo);
+
+  inline virtual char *GetTitle(void) { return printoutTitle; }
+
+  inline wxDC *GetDC(void) { return printoutDC; }
+  inline void SetDC(wxDC *dc) { printoutDC = dc; }
+  inline void SetPageSizePixels(int w, int  h) { pageWidthPixels = w; pageHeightPixels = h; }
+  inline void GetPageSizePixels(int *w, int  *h) { *w = pageWidthPixels; *h = pageHeightPixels; }
+  inline void SetPageSizeMM(int w, int  h) { pageWidthMM = w; pageHeightMM = h; }
+  inline void GetPageSizeMM(int *w, int  *h) { *w = pageWidthMM; *h = pageHeightMM; }
+
+  inline void SetPPIScreen(int x, int y) { PPIScreenX = x; PPIScreenY = y; }
+  inline void GetPPIScreen(int *x, int *y) { *x = PPIScreenX; *y = PPIScreenY; }
+  inline void SetPPIPrinter(int x, int y) { PPIPrinterX = x; PPIPrinterY = y; }
+  inline void GetPPIPrinter(int *x, int *y) { *x = PPIPrinterX; *y = PPIPrinterY; }
+
+  inline virtual bool IsPreview(void) { return isPreview; }
+
+  inline virtual void SetIsPreview(bool p) { isPreview = p; }
+};
+
+/*
+ * wxPreviewCanvas
+ * Canvas upon which a preview is drawn.
+ */
+ 
+class WXDLLEXPORT wxPreviewCanvas: public wxScrolledWindow
+{
+  DECLARE_CLASS(wxPreviewCanvas)
+
+ private:
+  wxPrintPreviewBase *printPreview;
+ public:
+  wxPreviewCanvas(wxPrintPreviewBase *preview, wxWindow *parent,
+    const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+    long style = 0, const wxString& name = "canvas");
+  ~wxPreviewCanvas(void);
+
+  void OnPaint(wxPaintEvent& event);
+
+  // Responds to colour changes
+  void OnSysColourChanged(wxSysColourChangedEvent& event);
+
+DECLARE_EVENT_TABLE()
+};
+
+/*
+ * wxPreviewFrame
+ * Default frame for showing preview.
+ */
+
+class WXDLLEXPORT wxPreviewFrame: public wxFrame
+{
+  DECLARE_CLASS(wxPreviewFrame)
+
+ protected:
+  wxWindow *previewCanvas;
+  wxPreviewControlBar *controlBar;
+  wxPrintPreviewBase *printPreview;
+ public:
+  wxPreviewFrame(wxPrintPreviewBase *preview, wxFrame *parent, const wxString& title = "Print Preview",
+    const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+    long style = wxDEFAULT_FRAME, const wxString& name = "frame");
+  ~wxPreviewFrame(void);
+
+  bool OnClose(void);
+  virtual void Initialize(void);
+  virtual void CreateCanvas(void);
+  virtual void CreateControlBar(void);
+};
+
+/*
+ * wxPreviewControlBar
+ * A panel with buttons for controlling a print preview.
+ * The programmer may wish to use other means for controlling
+ * the print preview.
+ */
+
+#define wxPREVIEW_PRINT        1
+#define wxPREVIEW_PREVIOUS     2
+#define wxPREVIEW_NEXT         4
+#define wxPREVIEW_ZOOM         8
+
+#define wxPREVIEW_DEFAULT      wxPREVIEW_PREVIOUS|wxPREVIEW_NEXT|wxPREVIEW_ZOOM
+
+// Ids for controls
+#define wxID_PREVIEW_CLOSE      1
+#define wxID_PREVIEW_NEXT       2
+#define wxID_PREVIEW_PREVIOUS   3
+#define wxID_PREVIEW_PRINT      4
+#define wxID_PREVIEW_ZOOM       5
+
+class WXDLLEXPORT wxPreviewControlBar: public wxPanel
+{
+  DECLARE_CLASS(wxPreviewControlBar)
+
+ protected:
+  wxPrintPreviewBase *printPreview;
+  wxButton *closeButton;
+  wxButton *nextPageButton;
+  wxButton *previousPageButton;
+  wxButton *printButton;
+  wxChoice *zoomControl;
+  static wxFont *buttonFont;
+  long buttonFlags;
+ public:
+  wxPreviewControlBar(wxPrintPreviewBase *preview, long buttons,
+    wxWindow *parent, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+    long style = 0, const wxString& name = "panel");
+  ~wxPreviewControlBar(void);
+
+  virtual void CreateButtons(void);
+  virtual void SetZoomControl(int zoom);
+  virtual int GetZoomControl(void);
+  inline virtual wxPrintPreviewBase *GetPrintPreview(void) { return printPreview; }
+
+  void OnPrint(wxCommandEvent& event);
+  void OnClose(wxCommandEvent& event);
+  void OnNext(wxCommandEvent& event);
+  void OnPrevious(wxCommandEvent& event);
+  void OnZoom(wxCommandEvent& event);
+  void OnPaint(wxPaintEvent& event);
+
+DECLARE_EVENT_TABLE()
+};
+
+/*
+ * wxPrintPreview
+ * Programmer creates an object of this class to preview a wxPrintout.
+ */
+ 
+class WXDLLEXPORT wxPrintPreviewBase: public wxObject
+{
+  DECLARE_CLASS(wxPrintPreviewBase)
+
+ protected:
+  wxPrintData printData;
+  wxWindow *previewCanvas;
+  wxFrame *previewFrame;
+  wxBitmap *previewBitmap;
+  wxPrintout *previewPrintout;
+  wxPrintout *printPrintout;
+  int currentPage;
+  int currentZoom;
+  float previewScale;
+  int topMargin;
+  int leftMargin;
+  int pageWidth;
+  int pageHeight;
+  int minPage;
+  int maxPage;
+ protected:
+  bool isOk;
+ public:
+  wxPrintPreviewBase(wxPrintout *printout, wxPrintout *printoutForPrinting = NULL, wxPrintData *data = NULL);
+  ~wxPrintPreviewBase(void);
+
+  virtual bool SetCurrentPage(int pageNum);
+  inline int GetCurrentPage(void) { return currentPage; };
+
+  inline void SetPrintout(wxPrintout *printout) { previewPrintout = printout; };
+  inline wxPrintout *GetPrintout(void) { return previewPrintout; };
+  inline wxPrintout *GetPrintoutForPrinting(void) { return printPrintout; };
+
+  inline void SetFrame(wxFrame *frame) { previewFrame = frame; };
+  inline void SetCanvas(wxWindow *canvas) { previewCanvas = canvas; };
+
+  inline virtual wxFrame *GetFrame(void) { return previewFrame; }
+  inline virtual wxWindow *GetCanvas(void) { return previewCanvas; }
+
+  // The preview canvas should call this from OnPaint
+  virtual bool PaintPage(wxWindow *canvas, wxDC& dc);
+
+  // This draws a blank page onto the preview canvas
+  virtual bool DrawBlankPage(wxWindow *canvas, wxDC& dc);
+
+  // This is called by wxPrintPreview to render a page into
+  // a wxMemoryDC.
+  virtual bool RenderPage(int pageNum);
+
+  inline wxPrintData& GetPrintData(void) { return printData; }
+
+  virtual void SetZoom(int percent);
+  int GetZoom(void) { return currentZoom; };
+
+  inline int GetMaxPage(void) { return maxPage; }
+  inline int GetMinPage(void) { return minPage; }
+  
+  inline bool Ok(void) { return isOk; }
+  inline void SetOk(bool ok) { isOk = ok; }
+
+  ///////////////////////////////////////////////////////////////////////////
+  // OVERRIDES
+
+  // If we own a wxPrintout that can be used for printing, this
+  // will invoke the actual printing procedure. Called
+  // by the wxPreviewControlBar.
+  virtual bool Print(bool interactive) = 0;
+
+  // Calculate scaling that needs to be done to get roughly
+  // the right scaling for the screen pretending to be
+  // the currently selected printer.
+  virtual void DetermineScaling(void) = 0;
+};
+
+/*
+ * Abort dialog
+ */
+
+class WXDLLEXPORT wxPrintAbortDialog: public wxDialog
+{
+public:
+    void OnCancel(wxCommandEvent& event);
+
+  wxPrintAbortDialog(wxWindow *parent,
+    const wxString& title, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+    long style = 0, const wxString& name = "dialog"):
+   wxDialog(parent, -1, title, pos, size, style, name)
+  {
+  }
+
+  DECLARE_EVENT_TABLE()
+};
+
+#endif
+    // __PRNTBASEH__
diff --git a/include/wx/radiobox.h b/include/wx/radiobox.h
new file mode 100644
index 0000000000..a3d0c0737a
--- /dev/null
+++ b/include/wx/radiobox.h
@@ -0,0 +1,13 @@
+#ifndef __RADIOBOXH_BASE__
+#define __RADIOBOXH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/radiobox.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/radiobox.h"
+#elif defined(__GTK__)
+#include "wx/gtk/radiobox.h"
+#endif
+
+#endif
+    // __RADIOBOXH_BASE__
diff --git a/include/wx/radiobut.h b/include/wx/radiobut.h
new file mode 100644
index 0000000000..f6a4eaeb84
--- /dev/null
+++ b/include/wx/radiobut.h
@@ -0,0 +1,13 @@
+#ifndef __RADIOBUTH_BASE__
+#define __RADIOBUTH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/radiobut.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/radiobut.h"
+#elif defined(__GTK__)
+#include "wx/gtk/radiobut.h"
+#endif
+
+#endif
+    // __RADIOBUTH_BASE__
diff --git a/include/wx/region.h b/include/wx/region.h
new file mode 100644
index 0000000000..aa208368f3
--- /dev/null
+++ b/include/wx/region.h
@@ -0,0 +1,13 @@
+#ifndef __REGIONH_BASE__
+#define __REGIONH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/region.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/region.h"
+#elif defined(__GTK__)
+#include "wx/gtk/region.h"
+#endif
+
+#endif
+    // __REGIONH_BASE__
diff --git a/include/wx/scrolbar.h b/include/wx/scrolbar.h
new file mode 100644
index 0000000000..fa67805e0d
--- /dev/null
+++ b/include/wx/scrolbar.h
@@ -0,0 +1,13 @@
+#ifndef __SCROLBARH_BASE__
+#define __SCROLBARH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/scrolbar.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/scrolbar.h"
+#elif defined(__GTK__)
+#include "wx/gtk/scrolbar.h"
+#endif
+
+#endif
+    // __SCROLBARH_BASE__
diff --git a/include/wx/scrolwin.h b/include/wx/scrolwin.h
new file mode 100644
index 0000000000..2f98b0274b
--- /dev/null
+++ b/include/wx/scrolwin.h
@@ -0,0 +1,7 @@
+#ifndef __SCROLWINH_BASE__
+#define __SCROLWINH_BASE__
+
+#include "wx/generic/scrolwin.h"
+
+#endif
+    // __SCROLWINH_BASE__
diff --git a/include/wx/settings.h b/include/wx/settings.h
new file mode 100644
index 0000000000..a3f1901ba8
--- /dev/null
+++ b/include/wx/settings.h
@@ -0,0 +1,117 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        settings.h
+// Purpose:     wxSystemSettings defines; includes platform settings.h
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __SETTINGSH_BASE__
+#define __SETTINGSH_BASE__
+
+#define wxSYS_WHITE_BRUSH         0
+#define wxSYS_LTGRAY_BRUSH        1
+#define wxSYS_GRAY_BRUSH          2
+#define wxSYS_DKGRAY_BRUSH        3
+#define wxSYS_BLACK_BRUSH         4
+#define wxSYS_NULL_BRUSH          5
+#define wxSYS_HOLLOW_BRUSH        wxSYS_NULL_BRUSH
+#define wxSYS_WHITE_PEN           6
+#define wxSYS_BLACK_PEN           7
+#define wxSYS_NULL_PEN            8
+#define wxSYS_OEM_FIXED_FONT      10
+#define wxSYS_ANSI_FIXED_FONT     11
+#define wxSYS_ANSI_VAR_FONT       12
+#define wxSYS_SYSTEM_FONT         13
+#define wxSYS_DEVICE_DEFAULT_FONT 14
+#define wxSYS_DEFAULT_PALETTE     15
+#define wxSYS_SYSTEM_FIXED_FONT   16
+#define wxSYS_DEFAULT_GUI_FONT    17
+
+#define wxSYS_COLOUR_SCROLLBAR         0
+#define wxSYS_COLOUR_BACKGROUND        1
+#define wxSYS_COLOUR_ACTIVECAPTION     2
+#define wxSYS_COLOUR_INACTIVECAPTION   3
+#define wxSYS_COLOUR_MENU              4
+#define wxSYS_COLOUR_WINDOW            5
+#define wxSYS_COLOUR_WINDOWFRAME       6
+#define wxSYS_COLOUR_MENUTEXT          7
+#define wxSYS_COLOUR_WINDOWTEXT        8
+#define wxSYS_COLOUR_CAPTIONTEXT       9
+#define wxSYS_COLOUR_ACTIVEBORDER      10
+#define wxSYS_COLOUR_INACTIVEBORDER    11
+#define wxSYS_COLOUR_APPWORKSPACE      12
+#define wxSYS_COLOUR_HIGHLIGHT         13
+#define wxSYS_COLOUR_HIGHLIGHTTEXT     14
+#define wxSYS_COLOUR_BTNFACE           15
+#define wxSYS_COLOUR_BTNSHADOW         16
+#define wxSYS_COLOUR_GRAYTEXT          17
+#define wxSYS_COLOUR_BTNTEXT           18
+#define wxSYS_COLOUR_INACTIVECAPTIONTEXT 19
+#define wxSYS_COLOUR_BTNHIGHLIGHT      20
+
+#define wxSYS_COLOUR_3DDKSHADOW        21
+#define wxSYS_COLOUR_3DLIGHT           22
+#define wxSYS_COLOUR_INFOTEXT          23
+#define wxSYS_COLOUR_INFOBK            24
+
+#define wxSYS_COLOUR_DESKTOP           wxSYS_COLOUR_BACKGROUND
+#define wxSYS_COLOUR_3DFACE            wxSYS_COLOUR_BTNFACE
+#define wxSYS_COLOUR_3DSHADOW          wxSYS_COLOUR_BTNSHADOW
+#define wxSYS_COLOUR_3DHIGHLIGHT       wxSYS_COLOUR_BTNHIGHLIGHT
+#define wxSYS_COLOUR_3DHILIGHT         wxSYS_COLOUR_BTNHIGHLIGHT
+#define wxSYS_COLOUR_BTNHILIGHT        wxSYS_COLOUR_BTNHIGHLIGHT
+
+// Metrics
+#define wxSYS_MOUSE_BUTTONS           1
+#define wxSYS_BORDER_X                2
+#define wxSYS_BORDER_Y                3
+#define wxSYS_CURSOR_X                4
+#define wxSYS_CURSOR_Y                5
+#define wxSYS_DCLICK_X                6
+#define wxSYS_DCLICK_Y                7
+#define wxSYS_DRAG_X                  8
+#define wxSYS_DRAG_Y                  9
+#define wxSYS_EDGE_X                  10
+#define wxSYS_EDGE_Y                  11
+#define wxSYS_HSCROLL_ARROW_X         12
+#define wxSYS_HSCROLL_ARROW_Y         13
+#define wxSYS_HTHUMB_X                14
+#define wxSYS_ICON_X                  15
+#define wxSYS_ICON_Y                  16
+#define wxSYS_ICONSPACING_X           17
+#define wxSYS_ICONSPACING_Y           18
+#define wxSYS_WINDOWMIN_X             19
+#define wxSYS_WINDOWMIN_Y             20
+#define wxSYS_SCREEN_X                21
+#define wxSYS_SCREEN_Y                22
+#define wxSYS_FRAMESIZE_X             23
+#define wxSYS_FRAMESIZE_Y             24
+#define wxSYS_SMALLICON_X             25
+#define wxSYS_SMALLICON_Y             26
+#define wxSYS_HSCROLL_Y               27
+#define wxSYS_VSCROLL_X               28
+#define wxSYS_VSCROLL_ARROW_X         29
+#define wxSYS_VSCROLL_ARROW_Y         30
+#define wxSYS_VTHUMB_Y                31
+#define wxSYS_CAPTION_Y               32
+#define wxSYS_MENU_Y                  33
+#define wxSYS_NETWORK_PRESENT         34
+#define wxSYS_PENWINDOWS_PRESENT      35
+#define wxSYS_SHOW_SOUNDS             36
+#define wxSYS_SWAP_BUTTONS            37
+
+#if defined(__WINDOWS__)
+#include "wx/msw/settings.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/settings.h"
+#elif defined(__GTK__)
+#include "wx/gtk/settings.h"
+#endif
+
+#endif
+    // __SETTINGSH_BASE__
+
diff --git a/include/wx/setup.h b/include/wx/setup.h
new file mode 100644
index 0000000000..2f0e6abc46
--- /dev/null
+++ b/include/wx/setup.h
@@ -0,0 +1,14 @@
+
+#ifndef __SETUPH_BASE__
+#define __SETUPH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/setup.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/setup.h"
+#elif defined(__GTK__)
+#include "wx/gtk/setup.h"
+#endif
+
+#endif
+	// __SETUPH_BASE__
diff --git a/include/wx/slider.h b/include/wx/slider.h
new file mode 100644
index 0000000000..2161341a97
--- /dev/null
+++ b/include/wx/slider.h
@@ -0,0 +1,13 @@
+#ifndef __SLIDERH_BASE__
+#define __SLIDERH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/slider.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/slider.h"
+#elif defined(__GTK__)
+#include "wx/gtk/slider.h"
+#endif
+
+#endif
+    // __SLIDERH_BASE__
diff --git a/include/wx/spinbutt.h b/include/wx/spinbutt.h
new file mode 100644
index 0000000000..839e13d1f5
--- /dev/null
+++ b/include/wx/spinbutt.h
@@ -0,0 +1,13 @@
+#ifndef __SPINBUTTH_BASE__
+#define __SPINBUTTH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/spinbutt.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/spinbutt.h"
+#elif defined(__GTK__)
+#include "wx/gtk/spinbutt.h"
+#endif
+
+#endif
+    // __SPINBUTTH_BASE__
diff --git a/include/wx/splitter.h b/include/wx/splitter.h
new file mode 100644
index 0000000000..626852e49f
--- /dev/null
+++ b/include/wx/splitter.h
@@ -0,0 +1,7 @@
+#ifndef __SPLITTERH_BASE__
+#define __SPLITTERH_BASE__
+
+#include "wx/generic/splitter.h"
+
+#endif
+    // __SPLITTERH_BASE__
diff --git a/include/wx/statbmp.h b/include/wx/statbmp.h
new file mode 100644
index 0000000000..c2f90dd1bb
--- /dev/null
+++ b/include/wx/statbmp.h
@@ -0,0 +1,13 @@
+#ifndef __STATBMPH_BASE__
+#define __STATBMPH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/statbmp.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/statbmp.h"
+#elif defined(__GTK__)
+#include "wx/gtk/statbmp.h"
+#endif
+
+#endif
+    // __STATBMPH_BASE__
diff --git a/include/wx/statbox.h b/include/wx/statbox.h
new file mode 100644
index 0000000000..cf7d4d36bc
--- /dev/null
+++ b/include/wx/statbox.h
@@ -0,0 +1,13 @@
+#ifndef __STATBOXH_BASE__
+#define __STATBOXH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/statbox.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/statbox.h"
+#elif defined(__GTK__)
+#include "wx/gtk/statbox.h"
+#endif
+
+#endif
+    // __STATBOXH_BASE__
diff --git a/include/wx/stattext.h b/include/wx/stattext.h
new file mode 100644
index 0000000000..0c30862324
--- /dev/null
+++ b/include/wx/stattext.h
@@ -0,0 +1,13 @@
+#ifndef __STATTEXTH_BASE__
+#define __STATTEXTH_BASE_
+
+#if defined(__WINDOWS__)
+#include "wx/msw/stattext.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/stattext.h"
+#elif defined(__GTK__)
+#include "wx/gtk/stattext.h"
+#endif
+
+#endif
+    // __STATTEXTH_BASE__
diff --git a/include/wx/statusbr.h b/include/wx/statusbr.h
new file mode 100644
index 0000000000..1775a2594a
--- /dev/null
+++ b/include/wx/statusbr.h
@@ -0,0 +1,7 @@
+#ifndef __STATUSBRH_BASE__
+#define __STATUSBRH_BASE__
+
+#include "wx/generic/statusbr.h"
+
+#endif
+    // __STATUSBRH_BASE__
diff --git a/include/wx/string.h b/include/wx/string.h
new file mode 100644
index 0000000000..55b4812624
--- /dev/null
+++ b/include/wx/string.h
@@ -0,0 +1,832 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        string.h
+// Purpose:     wxString class
+// Author:      Vadim Zeitlin
+// Modified by:
+// Created:     29/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __WXSTRINGH__
+#define __WXSTRINGH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+/* Dependencies (should be included before this header):
+ *         string.h
+ *         stdio.h
+ *         stdarg.h
+ *         limits.h
+ */
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <limits.h>
+
+#include "wx/defs.h"     // Robert Roebling
+#include "wx/object.h"
+#include "wx/debug.h"
+
+/** @name wxString library
+    @memo Efficient wxString class [more or less] compatible with MFC CString,
+          wxWindows wxString and std::string and some handy functions 
+          missing from string.h.
+  */
+//@{
+
+// ---------------------------------------------------------------------------
+// macros
+// ---------------------------------------------------------------------------
+
+/** @name Macros 
+    @memo You can switch off wxString/std::string compatibility if desired
+ */
+/// compile the std::string compatibility functions
+#define   STD_STRING_COMPATIBILITY
+
+/// define to derive wxString from wxObject
+#undef    WXSTRING_IS_WXOBJECT
+
+/// maximum possible length for a string means "take all string" everywhere
+//  (as sizeof(StringData) is unknown here we substract 100)
+#define   STRING_MAXLEN     (UINT_MAX - 100)
+
+// 'naughty' cast
+#define   WXSTRINGCAST (char *)(const char *)
+
+// NB: works only inside wxString class
+#define   ASSERT_VALID_INDEX(i) wxASSERT( (unsigned)(i) < Len() )
+
+// ---------------------------------------------------------------------------
+/** @name Global functions complementing standard C string library 
+    @memo replacements for strlen() and portable strcasecmp()
+ */
+// ---------------------------------------------------------------------------
+
+/// checks whether the passed in pointer is NULL and if the string is empty
+inline bool WXDLLEXPORT IsEmpty(const char *p) { return !p || !*p; }
+
+/// safe version of strlen() (returns 0 if passed NULL pointer)
+inline size_t  WXDLLEXPORT Strlen(const char *psz)
+  { return psz ? strlen(psz) : 0; }
+
+/// portable strcasecmp/_stricmp
+int WXDLLEXPORT Stricmp(const char *, const char *);
+
+// ---------------------------------------------------------------------------
+// string data prepended with some housekeeping info (used by String class),
+// is never used directly (but had to be put here to allow inlining)
+// ---------------------------------------------------------------------------
+struct WXDLLEXPORT wxStringData
+{
+  int     nRefs;        // reference count
+  size_t  nDataLength,  // actual string length
+          nAllocLength; // allocated memory size
+
+  // mimics declaration 'char data[nAllocLength]'
+  char* data() const { return (char*)(this + 1); }  
+
+  // empty string has a special ref count so it's never deleted
+  bool  IsEmpty()   const { return nRefs == -1; }
+  bool  IsShared()  const { return nRefs > 1;   }
+  bool  IsValid()   const { return nRefs != 0;  }
+
+  // lock/unlock
+  void  Lock()   { if ( !IsEmpty() ) nRefs++;                             }
+  void  Unlock() { if ( !IsEmpty() && --nRefs == 0) delete (char *)this;  }
+};
+
+extern const char *g_szNul; // global pointer to empty string
+
+// ---------------------------------------------------------------------------
+/**
+    This is (yet another one) String class for C++ programmers. It doesn't use
+    any of "advanced" C++ features (i.e. templates, exceptions, namespaces...)
+    thus you should be able to compile it with practicaly any C++ compiler.
+    This class uses copy-on-write technique, i.e. identical strings share the
+    same memory as long as neither of them is changed.
+
+    This class aims to be as compatible as possible with the new standard
+    std::string class, but adds some additional functions and should be
+    at least as efficient than the standard implementation.
+    
+    Performance note: it's more efficient to write functions which take 
+    "const String&" arguments than "const char *" if you assign the argument 
+    to another string.
+
+    It was compiled and tested under Win32, Linux (libc 5 & 6), Solaris 5.5.
+
+    To do:
+      - ressource support (string tables in ressources)
+      - more wide character (UNICODE) support
+      - regular expressions support
+    
+@memo     A non-template portable wxString class implementing copy-on-write.
+@author   VZ
+@version  1.3
+*/
+// ---------------------------------------------------------------------------
+#ifdef  WXSTRING_IS_WXOBJECT
+  class WXDLLEXPORT wxString : public wxObject
+  {
+    DECLARE_DYNAMIC_CLASS(wxString)
+#else   //WXSTRING_IS_WXOBJECT
+  class WXDLLEXPORT wxString
+  {
+#endif  //WXSTRING_IS_WXOBJECT
+
+friend class wxArrayString;
+
+public:
+  /** @name constructors & dtor */
+  //@{
+    /// ctor for an empty string
+  wxString();
+    /// copy ctor
+  wxString(const wxString& stringSrc);        
+    /// string containing nRepeat copies of ch
+  wxString(char ch, size_t nRepeat = 1);       
+    /// ctor takes first nLength characters from C string
+  wxString(const char *psz, size_t nLength = STRING_MAXLEN);
+    /// from C string (for compilers using unsigned char)
+  wxString(const unsigned char* psz, size_t nLength = STRING_MAXLEN);
+    /// from wide (UNICODE) string
+  wxString(const wchar_t *pwz);
+    /// dtor is not virtual, this class must not be inherited from!
+ ~wxString();
+  //@}
+
+  /** @name generic attributes & operations */
+  //@{
+    /// as standard strlen()
+  size_t Len() const { return GetStringData()->nDataLength; }
+    /// string contains any characters?
+  bool IsEmpty() const;
+    /// reinitialize string (and free data!)
+  void Empty();
+    /// Is an ascii value
+  bool IsAscii() const;
+    /// Is a number
+  bool IsNumber() const;
+    /// Is a word
+  bool IsWord() const;
+  //@}
+
+  /** @name data access (all indexes are 0 based) */
+  //@{
+    /// read access
+    char  GetChar(size_t n) const
+  	  { ASSERT_VALID_INDEX( n );  return m_pchData[n]; }
+    /// read/write access
+    char& GetWritableChar(size_t n)
+  	  { ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); return m_pchData[n]; }
+    /// write access
+    void  SetChar(size_t n, char ch)
+      { ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); m_pchData[n] = ch; }
+
+    /// get last character
+    char  Last() const
+      { wxASSERT( !IsEmpty() ); return m_pchData[Len() - 1]; }
+    /// get writable last character
+    char& Last() 
+      { wxASSERT( !IsEmpty() ); CopyBeforeWrite(); return m_pchData[Len()-1]; }
+
+    /// operator version of GetChar
+    char  operator[](size_t n) const
+      { ASSERT_VALID_INDEX( n ); return m_pchData[n]; }
+    /// operator version of GetChar
+    char  operator[](int n) const
+      { ASSERT_VALID_INDEX( n ); return m_pchData[n]; }
+    /// operator version of GetWritableChar
+    char& operator[](size_t n)
+      { ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); return m_pchData[n]; }
+
+    /// implicit conversion to C string
+    operator const char*() const { return m_pchData; } 
+    /// explicit conversion to C string (use this with printf()!)
+    const char* c_str()   const { return m_pchData; }
+    ///
+    const char* GetData() const { return m_pchData; }
+  //@}
+
+  /** @name overloaded assignment */
+  //@{
+    ///
+  wxString& operator=(const wxString& stringSrc);
+    ///
+  wxString& operator=(char ch);
+    ///
+  wxString& operator=(const char *psz);
+    ///
+  wxString& operator=(const unsigned char* psz);
+    ///
+  wxString& operator=(const wchar_t *pwz);
+  //@}
+  
+  /** @name string concatenation */
+  //@{
+    /** @name in place concatenation */
+    //@{
+      /// string += string
+  void operator+=(const wxString& string);
+      /// string += C string
+  void operator+=(const char *psz);
+      /// string += char
+  void operator+=(char ch);
+    //@}
+    /** @name concatenate and return the result
+        left to right associativity of << allows to write 
+        things like "str << str1 << str2 << ..."          */
+    //@{
+      /// as +=
+  wxString& operator<<(const wxString& string);
+      /// as +=
+  wxString& operator<<(char ch);
+      /// as +=
+  wxString& operator<<(const char *psz);
+    //@}
+    
+    /** @name return resulting string */
+    //@{
+      ///
+  friend wxString operator+(const wxString& string1,  const wxString& string2);
+      ///
+  friend wxString operator+(const wxString& string, char ch);
+      ///
+  friend wxString operator+(char ch, const wxString& string);
+      ///
+  friend wxString operator+(const wxString& string, const char *psz);
+      ///
+  friend wxString operator+(const char *psz, const wxString& string);
+    //@}
+  //@}
+  
+  /** @name string comparison */
+  //@{
+    /** 
+    case-sensitive comparaison
+    @return 0 if equal, +1 if greater or -1 if less
+    @see CmpNoCase, IsSameAs
+    */
+  int  Cmp(const char *psz) const { return strcmp(c_str(), psz); }
+    /**
+    case-insensitive comparaison, return code as for wxString::Cmp()
+    @see: Cmp, IsSameAs
+    */
+  int  CmpNoCase(const char *psz) const { return Stricmp(c_str(), psz); }
+    /**
+    test for string equality, case-sensitive (default) or not
+    @param   bCase is TRUE by default (case matters)
+    @return  TRUE if strings are equal, FALSE otherwise
+    @see     Cmp, CmpNoCase
+    */
+  bool IsSameAs(const char *psz, bool bCase = TRUE) const 
+    { return !(bCase ? Cmp(psz) : CmpNoCase(psz)); }
+  //@}
+  
+  /** @name other standard string operations */
+  //@{
+    /** @name simple sub-string extraction
+     */
+    //@{
+      /** 
+      return substring starting at nFirst of length 
+      nCount (or till the end if nCount = default value)
+      */
+  wxString Mid(size_t nFirst, size_t nCount = STRING_MAXLEN) const;  
+      /// get first nCount characters
+  wxString Left(size_t nCount) const;
+      /// get all characters before the first occurence of ch
+      /// (returns the whole string if ch not found)
+  wxString Left(char ch) const;
+      /// get all characters before the last occurence of ch
+      /// (returns empty string if ch not found)
+  wxString Before(char ch) const;
+      /// get all characters after the first occurence of ch
+      /// (returns empty string if ch not found)
+  wxString After(char ch) const;
+      /// get last nCount characters
+  wxString Right(size_t nCount) const;
+      /// get all characters after the last occurence of ch
+      /// (returns the whole string if ch not found)
+  wxString Right(char ch) const;
+    //@}
+    
+    /** @name case conversion */
+    //@{ 
+      ///
+  wxString& MakeUpper();
+      ///
+  wxString& MakeLower();
+    //@}
+
+    /** @name trimming/padding whitespace (either side) and truncating */
+    //@{
+      /// remove spaces from left or from right (default) side
+  wxString& Trim(bool bFromRight = TRUE);
+      /// add nCount copies chPad in the beginning or at the end (default)
+  wxString& Pad(size_t nCount, char chPad = ' ', bool bFromRight = TRUE);
+      /// truncate string to given length
+  wxString& Truncate(size_t uiLen);
+    //@}
+    
+    /** @name searching and replacing */
+    //@{
+      /// searching (return starting index, or -1 if not found)
+  int Find(char ch, bool bFromEnd = FALSE) const;   // like strchr/strrchr
+      /// searching (return starting index, or -1 if not found)
+  int Find(const char *pszSub) const;               // like strstr
+      /**
+      replace first (or all) occurences of substring with another one
+      @param  bReplaceAll: global replace (default) or only the first occurence
+      @return the number of replacements made
+      */
+  uint Replace(const char *szOld, const char *szNew, bool bReplaceAll = TRUE);
+    //@}
+  //@}
+
+  /** @name formated output */
+  //@{
+    /// as sprintf(), returns the number of characters written or < 0 on error
+  int Printf(const char *pszFormat, ...);
+    /// as vprintf(), returns the number of characters written or < 0 on error
+  int PrintfV(const char* pszFormat, va_list argptr);
+  //@}
+  
+  // get writable buffer of at least nLen characters
+  char *GetWriteBuf(size_t nLen);
+
+  /** @name wxWindows compatibility functions */
+  //@{
+    /// values for second parameter of CompareTo function
+  enum caseCompare {exact, ignoreCase};
+    /// values for first parameter of Strip function
+  enum stripType {leading = 0x1, trailing = 0x2, both = 0x3};
+    /// same as Printf()
+  inline int sprintf(const char *pszFormat, ...)
+  {
+    va_list argptr;
+    va_start(argptr, pszFormat);
+    int iLen = PrintfV(pszFormat, argptr);
+    va_end(argptr);
+    return iLen;
+  }
+
+    /// same as Cmp
+  inline int CompareTo(const char* psz, caseCompare cmp = exact) const
+  { return cmp == exact ? Cmp(psz) : CmpNoCase(psz); }
+
+    /// same as Mid (substring extraction)
+  inline wxString  operator()(size_t start, size_t len) const { return Mid(start, len); }
+
+    /// same as += or <<
+  inline wxString& Append(const char* psz) { return *this << psz; }
+  inline wxString& Append(char ch, int count = 1) { wxString str(ch, count); (*this) += str; return *this; }
+
+    ///
+  wxString& Prepend(const wxString& str) { *this = str + *this; return *this; }
+    /// same as Len
+  size_t Length() const { return Len(); }
+    /// same as MakeLower
+  void LowerCase() { MakeLower(); }
+    /// same as MakeUpper
+  void UpperCase() { MakeUpper(); }
+    /// same as Trim except that it doesn't change this string
+  wxString Strip(stripType w = trailing) const;
+
+    /// same as Find (more general variants not yet supported)
+  size_t Index(const char* psz) const { return Find(psz); }
+  size_t Index(char ch)         const { return Find(ch);  }
+    /// same as Truncate
+  wxString& Remove(size_t pos) { return Truncate(pos); }
+  wxString& RemoveLast() { return Truncate(Len() - 1); }
+
+  // Robert Roebling
+  
+  wxString& Remove(size_t nStart, size_t nLen) { return erase( nStart, nLen ); }
+  
+  size_t First( const char ch ) const { return find(ch); }
+  size_t First( const char* psz ) const { return find(psz); }
+  size_t First( const wxString &str ) const { return find(str); }
+
+  size_t Last( const char ch ) const { return rfind(ch,0); }
+  size_t Last( const char* psz ) const { return rfind(psz,0); }
+  size_t Last( const wxString &str ) const { return rfind(str,0); }
+
+    /// same as IsEmpty
+  bool IsNull() const { return IsEmpty(); }
+  //@}
+
+#ifdef  STD_STRING_COMPATIBILITY
+  /** @name std::string compatibility functions */
+  
+  /// an 'invalid' value for string index
+  static const size_t npos;
+        
+  //@{
+    /** @name constructors */
+    //@{
+      /// take nLen chars starting at nPos
+      wxString(const wxString& s, size_t nPos, size_t nLen = npos);
+      /// take all characters from pStart to pEnd
+      wxString(const void *pStart, const void *pEnd);
+    //@}
+    /** @name lib.string.capacity */
+    //@{
+      /// return the length of the string
+      size_t size() const { return Len(); }
+      /// return the length of the string
+      size_t length() const { return Len(); }
+      /// return the maximum size of the string
+      size_t max_size() const { return STRING_MAXLEN; } 
+      /// resize the string, filling the space with c if c != 0
+      void resize(size_t nSize, char ch = '\0');
+      /// delete the contents of the string
+      void clear() { Empty(); }
+      /// returns true if the string is empty
+      bool empty() const { return IsEmpty(); }
+    //@}
+    /** @name lib.string.access */
+    //@{
+      /// return the character at position n
+      char at(size_t n) const { return GetChar(n); }
+      /// returns the writable character at position n
+      char& at(size_t n) { return GetWritableChar(n); }
+    //@}
+    /** @name lib.string.modifiers */
+    //@{
+      /** @name append something to the end of this one */
+      //@{
+        /// append a string
+        wxString& append(const wxString& str) 
+          { *this += str; return *this; }
+        /// append elements str[pos], ..., str[pos+n]
+        wxString& append(const wxString& str, size_t pos, size_t n) 
+          { ConcatSelf(n, str.c_str() + pos); return *this; }
+        /// append first n (or all if n == npos) characters of sz
+        wxString& append(const char *sz, size_t n = npos) 
+          { ConcatSelf(n == npos ? Strlen(sz) : n, sz); return *this; }
+
+        /// append n copies of ch
+        wxString& append(size_t n, char ch) { return Pad(n, ch); }
+      //@}
+        
+      /** @name replaces the contents of this string with another one */
+      //@{
+        /// same as `this_string = str'
+        wxString& assign(const wxString& str) { return (*this) = str; }
+        /// same as ` = str[pos..pos + n]
+        wxString& assign(const wxString& str, size_t pos, size_t n) 
+          { return *this = wxString((const char *)str + pos, n); }
+        /// same as `= first n (or all if n == npos) characters of sz'
+        wxString& assign(const char *sz, size_t n = npos) 
+          { return *this = wxString(sz, n); }
+        /// same as `= n copies of ch'
+        wxString& assign(size_t n, char ch) 
+          { return *this = wxString(ch, n); }
+
+      //@}
+        
+      /** @name inserts something at position nPos into this one */  
+      //@{
+        /// insert another string
+        wxString& insert(size_t nPos, const wxString& str);
+        /// insert n chars of str starting at nStart (in str)
+        wxString& insert(size_t nPos, const wxString& str, size_t nStart, size_t n)
+	  	    { return insert(nPos, wxString((const char *)str + nStart, n)); }
+
+        /// insert first n (or all if n == npos) characters of sz
+        wxString& insert(size_t nPos, const char *sz, size_t n = npos)
+          { return insert(nPos, wxString(sz, n)); }
+        /// insert n copies of ch
+        wxString& insert(size_t nPos, size_t n, char ch) 
+          { return insert(nPos, wxString(ch, n)); }
+
+      //@}
+      
+      /** @name deletes a part of the string */
+      //@{
+        /// delete characters from nStart to nStart + nLen
+        wxString& erase(size_t nStart = 0, size_t nLen = npos);
+      //@}
+      
+      /** @name replaces a substring of this string with another one */
+      //@{
+         /// replaces the substring of length nLen starting at nStart
+         wxString& replace(size_t nStart, size_t nLen, const char* sz);
+         /// replaces the substring with nCount copies of ch
+         wxString& replace(size_t nStart, size_t nLen, size_t nCount, char ch);
+         /// replaces a substring with another substring
+         wxString& replace(size_t nStart, size_t nLen, 
+                         const wxString& str, size_t nStart2, size_t nLen2);
+         /// replaces the substring with first nCount chars of sz
+         wxString& replace(size_t nStart, size_t nLen, 
+                         const char* sz, size_t nCount);
+      //@}
+    //@}
+         
+    /// swap two strings
+    void swap(wxString& str);
+
+    /** @name string operations */
+    //@{
+      /** All find() functions take the nStart argument which specifies
+          the position to start the search on, the default value is 0.
+          
+          All functions return npos if there were no match.
+          
+          @name string search 
+      */
+      //@{
+        /**
+            @name find a match for the string/character in this string 
+        */
+        //@{
+          /// find a substring
+          size_t find(const wxString& str, size_t nStart = 0) const;
+          /// find first n characters of sz
+          size_t find(const char* sz, size_t nStart = 0, size_t n = npos) const;
+          /// find the first occurence of character ch after nStart
+          size_t find(char ch, size_t nStart = 0) const;
+
+		  // wxWin compatibility
+		  inline bool Contains(const wxString& str) { return (Find(str) != -1); }
+
+        //@}
+        
+        /** 
+          @name rfind() family is exactly like find() but works right to left
+        */
+        //@{
+        /// as find, but from the end
+        size_t rfind(const wxString& str, size_t nStart = npos) const;
+        /// as find, but from the end
+        size_t rfind(const char* sz, size_t nStart = npos, 
+                     size_t n = npos) const;
+        /// as find, but from the end
+        size_t rfind(char ch, size_t nStart = npos) const;
+        //@}
+        
+        /**
+          @name find first/last occurence of any character in the set
+        */
+        //@{
+          ///
+          size_t find_first_of(const wxString& str, size_t nStart = 0) const;
+          ///
+          size_t find_first_of(const char* sz, size_t nStart = 0) const;
+          /// same as find(char, size_t)
+          size_t find_first_of(char c, size_t nStart = 0) const;
+          
+          ///
+          size_t find_last_of (const wxString& str, size_t nStart = npos) const;
+          ///
+          size_t find_last_of (const char* s, size_t nStart = npos) const;
+          /// same as rfind(char, size_t)
+          size_t find_last_of (char c, size_t nStart = npos) const;
+        //@}
+        
+        /**
+          @name find first/last occurence of any character not in the set
+        */
+        //@{
+          ///
+          size_t find_first_not_of(const wxString& str, size_t nStart = 0) const;
+          ///
+          size_t find_first_not_of(const char* s, size_t nStart = 0) const;
+          ///
+          size_t find_first_not_of(char ch, size_t nStart = 0) const;
+          
+          ///
+          size_t find_last_not_of(const wxString& str, size_t nStart=npos) const;
+          ///
+          size_t find_last_not_of(const char* s, size_t nStart = npos) const;
+          ///
+          size_t find_last_not_of(char ch, size_t nStart = npos) const;
+        //@}
+      //@}
+      
+      /** 
+        All compare functions return -1, 0 or 1 if the [sub]string 
+        is less, equal or greater than the compare() argument.
+        
+        @name comparison
+      */
+      //@{
+        /// just like strcmp()
+        int compare(const wxString& str) const { return Cmp(str); }
+        /// comparaison with a substring
+        int compare(size_t nStart, size_t nLen, const wxString& str) const;
+        /// comparaison of 2 substrings
+        int compare(size_t nStart, size_t nLen,
+                    const wxString& str, size_t nStart2, size_t nLen2) const;
+        /// just like strcmp()
+        int compare(const char* sz) const { return Cmp(sz); }
+        /// substring comparaison with first nCount characters of sz
+        int compare(size_t nStart, size_t nLen,
+                    const char* sz, size_t nCount = npos) const;
+      //@}
+    wxString substr(size_t nStart = 0, size_t nLen = npos) const;
+  //@}
+#endif
+    
+protected:
+  // points to data preceded by wxStringData structure with ref count info
+  char *m_pchData;
+
+  // accessor to string data
+  wxStringData* GetStringData() const { return (wxStringData*)m_pchData - 1; }
+
+  // string (re)initialization functions
+    // initializes the string to the empty value (must be called only from
+    // ctors, use Reinit() otherwise)
+  void Init() { m_pchData = (char *)g_szNul; }
+    // initializaes the string with (a part of) C-string
+  void InitWith(const char *psz, size_t nPos = 0, size_t nLen = STRING_MAXLEN);
+    // as Init, but also frees old data
+  inline void Reinit(); 
+
+  // memory allocation
+    // allocates memory for string of lenght nLen
+  void AllocBuffer(size_t nLen);
+    // copies data to another string
+  void AllocCopy(wxString&, int, int) const;
+    // effectively copies data to string
+  void AssignCopy(size_t, const char *);
+  
+  // append a (sub)string
+  void ConcatCopy(int nLen1, const char *src1, int nLen2, const char *src2);
+  void ConcatSelf(int nLen, const char *src);
+
+  // functions called before writing to the string: they copy it if there 
+  // other references (should be the only owner when writing)
+  void CopyBeforeWrite();
+  void AllocBeforeWrite(size_t);
+};
+
+// ----------------------------------------------------------------------------
+/** The string array uses it's knowledge of internal structure of the String
+    class to optimize string storage. Normally, we would store pointers to
+    string, but as String is, in fact, itself a pointer (sizeof(String) is
+    sizeof(char *)) we store these pointers instead. The cast to "String *"
+    is really all we need to turn such pointer into a string!
+
+    Of course, it can be called a dirty hack, but we use twice less memory 
+    and this approach is also more speed efficient, so it's probably worth it.
+
+    Usage notes: when a string is added/inserted, a new copy of it is created,
+    so the original string may be safely deleted. When a string is retrieved
+    from the array (operator[] or Item() method), a reference is returned.
+
+    @name wxArrayString
+    @memo probably the most commonly used array type - array of strings
+ */
+// ----------------------------------------------------------------------------
+class wxArrayString
+{
+public:
+  /** @name ctors and dtor */
+  //@{
+    /// default ctor
+  wxArrayString();
+    /// copy ctor
+  wxArrayString(const wxArrayString& array);
+    /// assignment operator
+  wxArrayString& operator=(const wxArrayString& src);
+    /// not virtual, this class can't be derived from
+ ~wxArrayString();
+  //@}
+
+  /** @name memory management */
+  //@{
+    /// empties the list, but doesn't release memory
+  void Empty();
+    /// empties the list and releases memory
+  void Clear();
+    /// preallocates memory for given number of items
+  void Alloc(size_t nCount);
+  //@}
+
+  /** @name simple accessors */
+  //@{
+    /// number of elements in the array
+  uint  Count() const   { return m_nCount;      }
+    /// is it empty?
+  bool  IsEmpty() const { return m_nCount == 0; }
+  //@}
+
+  /** @name items access (range checking is done in debug version) */
+  //@{
+    /// get item at position uiIndex
+  wxString& Item(size_t nIndex) const
+    { wxASSERT( nIndex < m_nCount ); return *(wxString *)&(m_pItems[nIndex]); }
+    /// same as Item()
+  wxString& operator[](size_t nIndex) const { return Item(nIndex); }
+    /// get last item
+  wxString& Last() const { wxASSERT( !IsEmpty() ); return Item(Count() - 1); }
+  //@}
+
+  /** @name item management */
+  //@{
+    /**
+      Search the element in the array, starting from the either side
+      @param if bFromEnd reverse search direction
+      @param if bCase, comparaison is case sensitive (default)
+      @return index of the first item matched or NOT_FOUND
+      @see NOT_FOUND
+     */
+  int  Index (const char *sz, bool bCase = TRUE, bool bFromEnd = FALSE) const;
+    /// add new element at the end
+  void Add   (const wxString& str);
+    /// add new element at given position
+  void Insert(const wxString& str, uint uiIndex);
+    /// remove first item matching this value
+  void Remove(const char *sz);
+    /// remove item by index
+  void Remove(size_t nIndex);
+  //@}
+
+  /// sort array elements
+  void Sort(bool bCase = TRUE, bool bReverse = FALSE);
+
+private:
+  void    Grow();     // makes array bigger if needed
+  void    Free();     // free the string stored
+
+  size_t  m_nSize,    // current size of the array
+          m_nCount;   // current number of elements
+
+  char  **m_pItems;   // pointer to data
+};
+
+// ---------------------------------------------------------------------------
+// implementation of inline functions
+// ---------------------------------------------------------------------------
+
+// Put back into class, since BC++ can't create precompiled header otherwise
+
+// ---------------------------------------------------------------------------
+/** @name wxString comparaison functions 
+    @memo Comparaisons are case sensitive
+ */
+// ---------------------------------------------------------------------------
+//@{
+inline bool operator==(const wxString& s1, const wxString& s2) { return s1.Cmp(s2) == 0; }
+///
+inline bool operator==(const wxString& s1, const char  * s2) { return s1.Cmp(s2) == 0; }
+///
+inline bool operator==(const char  * s1, const wxString& s2) { return s2.Cmp(s1) == 0; }
+///
+inline bool operator!=(const wxString& s1, const wxString& s2) { return s1.Cmp(s2) != 0; }
+///
+inline bool operator!=(const wxString& s1, const char  * s2) { return s1.Cmp(s2) != 0; }
+///
+inline bool operator!=(const char  * s1, const wxString& s2) { return s2.Cmp(s1) != 0; }
+///
+inline bool operator< (const wxString& s1, const wxString& s2) { return s1.Cmp(s2) <  0; }
+///
+inline bool operator< (const wxString& s1, const char  * s2) { return s1.Cmp(s2) <  0; }
+///
+inline bool operator< (const char  * s1, const wxString& s2) { return s2.Cmp(s1) >  0; }
+///
+inline bool operator> (const wxString& s1, const wxString& s2) { return s1.Cmp(s2) >  0; }
+///
+inline bool operator> (const wxString& s1, const char  * s2) { return s1.Cmp(s2) >  0; }
+///
+inline bool operator> (const char  * s1, const wxString& s2) { return s2.Cmp(s1) <  0; }
+///
+inline bool operator<=(const wxString& s1, const wxString& s2) { return s1.Cmp(s2) <= 0; }
+///
+inline bool operator<=(const wxString& s1, const char  * s2) { return s1.Cmp(s2) <= 0; }
+///
+inline bool operator<=(const char  * s1, const wxString& s2) { return s2.Cmp(s1) >= 0; }
+///
+inline bool operator>=(const wxString& s1, const wxString& s2) { return s1.Cmp(s2) >= 0; }
+///
+inline bool operator>=(const wxString& s1, const char  * s2) { return s1.Cmp(s2) >= 0; }
+///
+inline bool operator>=(const char  * s1, const wxString& s2) { return s2.Cmp(s1) <= 0; }
+//@}
+    
+// ---------------------------------------------------------------------------
+/** @name Global functions complementing standard C string library 
+    @memo replacements for strlen() and portable strcasecmp()
+ */
+// ---------------------------------------------------------------------------
+
+#ifdef  STD_STRING_COMPATIBILITY
+
+// fwd decl
+class WXDLLEXPORT istream;
+
+istream& WXDLLEXPORT operator>>(istream& is, wxString& str);
+
+#endif  //std::string compatibility
+
+#endif  // __WXSTRINGH__
+
+//@}
diff --git a/include/wx/tab.h b/include/wx/tab.h
new file mode 100644
index 0000000000..1f75593dd6
--- /dev/null
+++ b/include/wx/tab.h
@@ -0,0 +1,7 @@
+#ifndef __TABH_BASE__
+#define __TABH_BASE__
+
+#include "wx/generic/tabg.h"
+
+#endif
+    // __TABH_BASE__
diff --git a/include/wx/tabctrl.h b/include/wx/tabctrl.h
new file mode 100644
index 0000000000..ad3b849fd6
--- /dev/null
+++ b/include/wx/tabctrl.h
@@ -0,0 +1,13 @@
+#ifndef __TABCTRLH_BASE__
+#define __TABCTRLH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/tabctrl.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/tabctrl.h"
+#elif defined(__GTK__)
+#include "wx/gtk/tabctrl.h"
+#endif
+
+#endif
+    // __TABCTRLH_BASE__
diff --git a/include/wx/textctrl.h b/include/wx/textctrl.h
new file mode 100644
index 0000000000..bbe414be2d
--- /dev/null
+++ b/include/wx/textctrl.h
@@ -0,0 +1,13 @@
+#ifndef __TEXTCTRLH_BASE__
+#define __TEXTCTRLH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/textctrl.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/textctrl.h"
+#elif defined(__GTK__)
+#include "wx/gtk/textctrl.h"
+#endif
+
+#endif
+    // __TEXTCTRLH_BASE__
diff --git a/include/wx/textdlg.h b/include/wx/textdlg.h
new file mode 100644
index 0000000000..4404fe1435
--- /dev/null
+++ b/include/wx/textdlg.h
@@ -0,0 +1,7 @@
+#ifndef __TEXTDLGH_BASE__
+#define __TEXTDLGH_BASE__
+
+#include "wx/generic/textdlgg.h"
+
+#endif
+    // __TEXTDLGH_BASE__
diff --git a/include/wx/textfile.h b/include/wx/textfile.h
new file mode 100644
index 0000000000..a57931687d
--- /dev/null
+++ b/include/wx/textfile.h
@@ -0,0 +1,123 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        textfile.h
+// Purpose:     class wxTextFile to work with text files of _small_ size
+//              (file is fully loaded in memory) and which understands CR/LF
+//              differences between platforms.
+// Author:      Vadim Zeitlin
+// Modified by: 
+// Created:     03.04.98
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// Licence:     wxWindows license
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef   _TEXTFILE_H
+#define   _TEXTFILE_H
+
+#ifdef __GNUG__
+#pragma interface "textfile.h"
+#endif
+
+#include "wx/defs.h"
+#include "wx/string.h"
+#include "wx/file.h"
+#include "wx/dynarray.h"
+
+// ----------------------------------------------------------------------------
+// wxTextFile
+// ----------------------------------------------------------------------------
+class wxTextFile
+{
+public:
+  // constants
+  enum Type
+  {
+    Type_None,  // incomplete (the last line of the file only)
+    Type_Unix,  // line is terminated with 'CR' = 0xA = 10 = '\n'
+    Type_Dos,   //                         'LF' 'CR'
+    Type_Mac    //                         'LF' = 0xD = 12 = '\r'
+  };
+
+  // default type for current platform (determined at compile time)
+  static const Type typeDefault;
+
+  // ctors
+    // def ctor, use Open(string)
+  wxTextFile() { }
+    // 
+  wxTextFile(const wxString& strFile);
+
+  // file operations
+    // file exists?
+  bool Exists() const;
+    // Open() also loads file in memory on success
+  bool Open();
+    // same as Open() but with (another) file name
+  bool Open(const wxString& strFile);
+    // closes the file and frees memory, losing all changes
+  bool Close();
+    // is file currently opened?
+  bool IsOpened() const { return m_file.IsOpened(); }
+
+  // accessors
+    // get the number of lines in the file
+  size_t    GetLineCount() const { return m_aLines.Count(); }
+    // the returned line may be modified (but don't add CR/LF at the end!)
+  wxString& GetLine(uint n)    const { return m_aLines[n]; }
+  wxString& operator[](uint n) const { return m_aLines[n]; }
+    // get the type of the line (see also GetEOL)
+  Type GetLineType(uint n) const { return m_aTypes[n]; }
+    // guess the type of file (m_file is supposed to be opened)
+  Type GuessType() const;
+    // get the name of the file
+  const char *GetName() const { return m_strFile.c_str(); }
+
+  // add/remove lines
+    // add a line to the end
+  void AddLine(const wxString& str, Type type = typeDefault) 
+    { m_aLines.Add(str); m_aTypes.Add(type); }
+    // insert a line before the line number n
+  void InsertLine(const wxString& str, uint n, Type type = typeDefault) 
+    { m_aLines.Insert(str, n); m_aTypes.Insert(type, n); }
+    // delete one line
+  void RemoveLine(uint n) { m_aLines.Remove(n); m_aTypes.Remove(n); }
+
+  // change the file on disk (default argument means "don't change type")
+  // possibly in another format
+  bool Write(Type typeNew = Type_None);
+
+  // get the file termination string
+  inline static const char *GetEOL(Type type = typeDefault)
+  {
+    switch ( type ) {
+      case Type_None: return "";
+      case Type_Unix: return "\n";
+      case Type_Dos:  return "\r\n";
+      case Type_Mac:  return "\r";
+
+      default:
+        wxFAIL_MSG("bad file type in wxTextFile::GetEOL.");
+        return NULL;
+    }
+  }
+
+  // dtor
+  ~wxTextFile();
+
+private:
+  // copy ctor/assignment operator not implemented
+  wxTextFile(const wxTextFile&);
+  wxTextFile& operator=(const wxTextFile&);
+
+  // read the file in memory (m_file is supposed to be just opened)
+  bool Read();
+
+  WX_DEFINE_ARRAY(Type, ArrayFileType);
+
+  wxFile        m_file;     // current file
+  ArrayFileType m_aTypes;   // type of each line
+  wxArrayString m_aLines;   // lines of file
+  wxString      m_strFile;  // name of the file
+};
+
+#endif  //_TEXTFILE_H
\ No newline at end of file
diff --git a/include/wx/time.h b/include/wx/time.h
new file mode 100644
index 0000000000..05c5a263e6
--- /dev/null
+++ b/include/wx/time.h
@@ -0,0 +1,97 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        time.h
+// Purpose:     wxTime class, from NIHCL
+// Author:      Julian Smart, after K. E. Gorlen
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __TIMEH__
+#define __TIMEH__
+
+#include "wx/object.h"
+
+#if USE_TIMEDATE
+
+#ifdef __GNUG__
+#pragma interface "time.h"
+#endif
+
+class WXDLLEXPORT wxDate;
+
+typedef unsigned short hourTy;
+typedef unsigned short minuteTy;
+typedef unsigned short secondTy;
+typedef unsigned long clockTy;
+
+class WXDLLEXPORT wxTime: public wxObject
+{
+        DECLARE_DYNAMIC_CLASS(wxTime)
+        
+public:                 // type definitions
+	enum tFormat { wx12h, wx24h };
+	enum tPrecision { wxStdMinSec, wxStdMin };
+private:
+		  static tFormat		Format;
+		  static tPrecision	Precision;
+
+		  clockTy		sec;			/* seconds since 1/1/1901 */
+
+        bool IsDST() const;
+        wxTime GetLocalTime() const;
+private:                // static member functions
+        static wxTime GetLocalTime(const wxDate& date, hourTy h=0, minuteTy m=0, secondTy s=0);
+        static wxTime GetBeginDST(unsigned year);
+        static wxTime GetEndDST(unsigned year);
+public:
+        wxTime();                         // current time 
+        wxTime(clockTy s)                 { sec = s; }
+        wxTime(const wxTime& t)                 { (*this) = t ; }
+		  wxTime(hourTy h, minuteTy m, secondTy s =0, bool dst =FALSE);
+		  wxTime(const wxDate&, hourTy h =0, minuteTy m =0, secondTy s=0, bool dst =FALSE);
+		  // Convert to string
+        operator char *   (void);
+        operator wxDate() const;
+        bool operator<(const wxTime& t) const     { return sec < t.sec; }
+        bool operator<=(const wxTime& t) const    { return sec <= t.sec; }
+        bool operator>(const wxTime& t) const     { return sec > t.sec; }
+        bool operator>=(const wxTime& t) const    { return sec >= t.sec; }
+        bool operator==(const wxTime& t) const    { return sec == t.sec; }
+        bool operator!=(const wxTime& t) const    { return sec != t.sec; }
+        void operator=(const wxTime& t)     { sec = t.sec; }
+        friend wxTime operator+(const wxTime& t, long s)    { return wxTime(t.sec+s); }
+		  friend wxTime operator+(long s, const wxTime& t)    { return wxTime(t.sec+s); }
+		  long operator-(const wxTime& t) const     { return sec - t.sec; }
+		  wxTime operator-(long s) const    { return wxTime(sec-s); }
+        void operator+=(long s)         { sec += s; }
+        void operator-=(long s)         { sec -= s; }
+        bool IsBetween(const wxTime& a, const wxTime& b) const;
+        hourTy GetHour() const;            // hour in local time
+        hourTy GetHourGMT() const;         // hour in GMT 
+        minuteTy GetMinute() const;        // minute in local time 
+        minuteTy GetMinuteGMT() const;     // minute in GMT 
+        secondTy GetSecond() const;        // second in local time or GMT 
+        clockTy GetSeconds() const         { return sec; }
+        wxTime Max(const wxTime&) const;
+		  wxTime Min(const wxTime&) const;
+		  static void SetFormat(const tFormat lFormat			= wx12h,
+		  								const tPrecision lPrecision	= wxStdMinSec);
+		  char *FormatTime() const;
+/*
+        virtual int compare(const Object&) const;
+        virtual void deepenShallowCopy();       // {}
+        virtual unsigned hash() const;
+        virtual bool isEqual(const Object&) const;
+        virtual void printOn(ostream& strm =cout) const;
+        virtual const Class* species() const;
+*/
+};
+
+#endif
+  // USE_TIMEDATE
+#endif
+    // __TIMEH__
+
diff --git a/include/wx/timer.h b/include/wx/timer.h
new file mode 100644
index 0000000000..3dbe809312
--- /dev/null
+++ b/include/wx/timer.h
@@ -0,0 +1,13 @@
+#ifndef __TIMERH_BASE__
+#define __TIMERH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/timer.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/timer.h"
+#elif defined(__GTK__)
+#include "wx/gtk/timer.h"
+#endif
+
+#endif
+    // __TIMERH_BASE__
diff --git a/include/wx/toolbar.h b/include/wx/toolbar.h
new file mode 100644
index 0000000000..5e329fba0f
--- /dev/null
+++ b/include/wx/toolbar.h
@@ -0,0 +1,11 @@
+#ifndef __TOOLBARH_BASE__
+#define __TOOLBARH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/tbar95.h"
+#elif defined(__GTK__)
+#include "wx/gtk/tbargtk.h"
+#endif
+
+#endif
+    // __TOOLBARH_BASE__
diff --git a/include/wx/treectrl.h b/include/wx/treectrl.h
new file mode 100644
index 0000000000..e167d56f6b
--- /dev/null
+++ b/include/wx/treectrl.h
@@ -0,0 +1,13 @@
+#ifndef __TREECTRLH_BASE__
+#define __TREECTRLH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/treectrl.h"
+#elif defined(__MOTIF__)
+#include "wx/generic/treectrl.h"
+#elif defined(__GTK__)
+#include "wx/generic/treectrl.h"
+#endif
+
+#endif
+    // __TREECTRLH_BASE__
diff --git a/include/wx/types.h b/include/wx/types.h
new file mode 100644
index 0000000000..9545eae4de
--- /dev/null
+++ b/include/wx/types.h
@@ -0,0 +1,97 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        types.h
+// Purpose:     Type identifiers, used by resource system
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __TYPESH__
+#define __TYPESH__
+
+#ifdef __GNUG__
+// #pragma interface "types.h"
+#endif
+
+// Types of objects
+#define wxTYPE_ANY             0
+#define wxTYPE_OBJECT          wxTYPE_ANY
+#define wxTYPE_WINDOW          1
+#define wxTYPE_DIALOG_BOX      2
+#define wxTYPE_ITEM            3
+#define wxTYPE_PANEL           4
+#define wxTYPE_CANVAS          5
+#define wxTYPE_TEXT_WINDOW     6
+#define wxTYPE_FRAME           7
+
+#define wxTYPE_BUTTON          8
+#define wxTYPE_TEXT            9
+#define wxTYPE_MESSAGE         10
+#define wxTYPE_CHOICE          11
+#define wxTYPE_LIST_BOX        12
+#define wxTYPE_SLIDER          13
+#define wxTYPE_CHECK_BOX       14
+#define wxTYPE_MENU            15
+#define wxTYPE_MENU_BAR        16
+#define wxTYPE_MULTI_TEXT      17
+#define wxTYPE_RADIO_BOX       18
+#define wxTYPE_GROUP_BOX       19
+#define wxTYPE_GAUGE           20
+#define wxTYPE_SCROLL_BAR      21
+#define wxTYPE_VIRT_LIST_BOX   22
+#define wxTYPE_COMBO_BOX       23
+#define wxTYPE_RADIO_BUTTON    24
+
+#define wxTYPE_EVENT           25
+#define wxTYPE_DC              26
+#define wxTYPE_DC_CANVAS       27
+#define wxTYPE_DC_POSTSCRIPT   28
+#define wxTYPE_DC_PRINTER      29
+#define wxTYPE_DC_METAFILE     30
+#define wxTYPE_DC_MEMORY       31
+#define wxTYPE_MOUSE_EVENT     32
+#define wxTYPE_KEY_EVENT       33
+#define wxTYPE_COMMAND_EVENT   34
+#define wxTYPE_DC_PANEL        35
+
+#define wxTYPE_PEN             40
+#define wxTYPE_BRUSH           41
+#define wxTYPE_FONT            42
+#define wxTYPE_ICON            42
+#define wxTYPE_BITMAP          43
+#define wxTYPE_METAFILE        44
+#define wxTYPE_TIMER           45
+#define wxTYPE_COLOUR          46
+#define wxTYPE_COLOURMAP       47
+#define wxTYPE_CURSOR          48
+
+#define wxTYPE_DDE_CLIENT      60
+#define wxTYPE_DDE_SERVER      61
+#define wxTYPE_DDE_CONNECTION  62
+
+#define wxTYPE_HELP_INSTANCE   63
+
+#define wxTYPE_LIST            70
+#define wxTYPE_STRING_LIST     71
+#define wxTYPE_HASH_TABLE      72
+#define wxTYPE_NODE            73
+#define wxTYPE_APP             74
+#define wxTYPE_DATE            75
+
+#define wxTYPE_ENHANCED_DIALOG 80
+#define wxTYPE_TOOLBAR         81
+#define wxTYPE_BUTTONBAR       82
+
+#define wxTYPE_DATABASE        90
+#define wxTYPE_QUERY_FIELD     91
+#define wxTYPE_QUERY_COL       92
+#define wxTYPE_RECORDSET       93
+
+#define wxTYPE_USER            500
+
+#endif
+    // __TYPESH__
+
diff --git a/include/wx/utils.h b/include/wx/utils.h
new file mode 100644
index 0000000000..530e38f309
--- /dev/null
+++ b/include/wx/utils.h
@@ -0,0 +1,309 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        utils.h
+// Purpose:     Miscellaneous utilities
+// Author:      Julian Smart
+// Modified by:
+// Created:     29/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Julian Smart
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __UTILSH__
+#define __UTILSH__
+
+#ifdef __GNUG__
+#pragma interface "utils.h"
+#endif
+
+#include "wx/setup.h"
+#include "wx/object.h"
+#include "wx/list.h"
+#include "wx/window.h"
+#include "wx/filefn.h"
+
+#if USE_IOSTREAMH
+#include <iostream.h>
+#else
+#include <iostream>
+#endif
+
+#ifdef __X__
+#ifndef __VMS__
+/*steve: these two are not known under VMS */
+#include <dirent.h>
+#include <unistd.h>
+#endif
+#endif
+
+#include <stdio.h>
+
+#ifdef __GNUWIN32__
+#define stricmp strcasecmp
+#define strnicmp strncasecmp
+#endif
+
+// Forward declaration
+class WXDLLEXPORT wxFrame;
+
+// Stupid ASCII macros
+#define   wxToUpper(C)      (((C) >= 'a' && (C) <= 'z')? (C) - 'a' + 'A': (C))
+#define   wxToLower(C)      (((C) >= 'A' && (C) <= 'Z')? (C) - 'A' + 'a': (C))
+
+// Return a string with the current date/time
+wxString WXDLLEXPORT wxNow(void);
+
+// Make a copy of this string using 'new'
+char* WXDLLEXPORT copystring(const char *s);
+
+// Generate a unique ID
+long WXDLLEXPORT wxNewId(void);
+#define NewId wxNewId
+
+// Ensure subsequent IDs don't clash with this one
+void WXDLLEXPORT wxRegisterId(long id);
+#define RegisterId wxRegisterId
+
+// Return the current ID
+long WXDLLEXPORT wxGetCurrentId(void);
+
+// Useful buffer
+WXDLLEXPORT_DATA(extern char*) wxBuffer;
+
+WXDLLEXPORT_DATA(extern const char*) wxFloatToStringStr;
+WXDLLEXPORT_DATA(extern const char*) wxDoubleToStringStr;
+
+// Various conversions
+void WXDLLEXPORT StringToFloat(char *s, float *number);
+char* WXDLLEXPORT FloatToString(float number, const char *fmt = wxFloatToStringStr);
+void WXDLLEXPORT StringToDouble(char *s, double *number);
+char* WXDLLEXPORT DoubleToString(double number, const char *fmt = wxDoubleToStringStr);
+void WXDLLEXPORT StringToInt(char *s, int *number);
+void WXDLLEXPORT StringToLong(char *s, long *number);
+char* WXDLLEXPORT IntToString(int number);
+char* WXDLLEXPORT LongToString(long number);
+
+// Matches string one within string two regardless of case
+bool WXDLLEXPORT StringMatch(char *one, char *two, bool subString = TRUE, bool exact = FALSE);
+
+// A shorter way of using strcmp
+#define wxStringEq(s1, s2) (s1 && s2 && (strcmp(s1, s2) == 0))
+
+// Convert 2-digit hex number to decimal
+int WXDLLEXPORT wxHexToDec(char *buf);
+
+// Convert decimal integer to 2-character hex string
+void WXDLLEXPORT wxDecToHex(int dec, char *buf);
+
+// Execute another program. Returns 0 if there was an error, a PID otherwise.
+long WXDLLEXPORT wxExecute(char **argv, bool Async = FALSE);
+long WXDLLEXPORT wxExecute(const wxString& command, bool Async = FALSE);
+
+#define wxSIGTERM 1
+
+int WXDLLEXPORT wxKill(long pid, int sig=wxSIGTERM);
+
+// Execute a command in an interactive shell window
+// If no command then just the shell
+bool WXDLLEXPORT wxShell(const wxString& command = "");
+
+// Sleep for nSecs seconds under UNIX, do nothing under Windows
+void WXDLLEXPORT wxSleep(int nSecs);
+
+// Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
+long WXDLLEXPORT wxGetFreeMemory(void);
+
+// Consume all events until no more left
+void WXDLLEXPORT wxFlushEvents(void);
+
+/*
+ * Network and username functions.
+ *
+ */
+
+// Get eMail address
+bool WXDLLEXPORT wxGetEmailAddress(char *buf, int maxSize);
+
+// Get hostname.
+bool WXDLLEXPORT wxGetHostName(char *buf, int maxSize);
+
+// Get user ID e.g. jacs
+bool WXDLLEXPORT wxGetUserId(char *buf, int maxSize);
+
+// Get user name e.g. Julian Smart
+bool WXDLLEXPORT wxGetUserName(char *buf, int maxSize);
+
+/*
+ * Strip out any menu codes
+ */
+char* WXDLLEXPORT wxStripMenuCodes(char *in, char *out = NULL);
+
+// Find the window/widget with the given title or label.
+// Pass a parent to begin the search from, or NULL to look through
+// all windows.
+wxWindow* WXDLLEXPORT wxFindWindowByLabel(const wxString& title, wxWindow *parent = NULL);
+
+// Find window by name, and if that fails, by label.
+wxWindow* WXDLLEXPORT wxFindWindowByName(const wxString& name, wxWindow *parent = NULL);
+
+// Returns menu item id or -1 if none.
+int WXDLLEXPORT wxFindMenuItemId(wxFrame *frame, const wxString& menuString, const wxString& itemString);
+
+// A debugging stream buffer.
+// Under Windows, this writes to the Windows debug output.
+// Under other platforms, it writes to cerr.
+
+// ALl this horrible gubbins required for Borland, because the calling
+// convention needs to be the same as for streambuf.
+// Thanks to Gerhard.Vogt@embl-heidelberg.de for this solution.
+
+#if defined(__BORLANDC__) && defined(__BCOPT__) && !defined(_RTL_ALLOW_po) && !defined(__FLAT__)
+#pragma option -po-
+#endif
+
+// Can't export a class derived from a non-export class
+#if !defined(_WINDLL) && !defined(WXUSINGDLL)
+
+#ifdef new
+#undef new
+#endif
+
+class WXDLLEXPORT wxDebugStreamBuf: public streambuf
+{
+  public:
+    wxDebugStreamBuf(void);
+    ~wxDebugStreamBuf(void) {}
+
+    int overflow(int i);
+    inline int underflow(void) { return EOF; }
+    int sync(void);
+};
+
+#if DEBUG && USE_GLOBAL_MEMORY_OPERATORS
+#define new WXDEBUG_NEW
+#endif
+
+#endif
+
+#if defined(__BORLANDC__) && defined(__BCOPT__) && !defined(_RTL_ALLOW_po) && !defined(__FLAT__)
+#pragma option -po.
+#endif
+
+/*
+#if (!defined(__MINMAX_DEFINED) && !defined(max))
+#define max(a,b)            (((a) > (b)) ? (a) : (b))
+#define min(a,b)            (((a) < (b)) ? (a) : (b))
+#define __MINMAX_DEFINED 1
+#endif
+*/
+#define wxMax(a,b)            (((a) > (b)) ? (a) : (b))
+#define wxMin(a,b)            (((a) < (b)) ? (a) : (b))
+
+// Yield to other apps/messages
+bool WXDLLEXPORT wxYield(void);
+
+// Format a message on the standard error (UNIX) or the debugging
+// stream (Windows)
+void WXDLLEXPORT wxDebugMsg(const char *fmt ...) ;
+ 
+// Sound the bell
+void WXDLLEXPORT wxBell(void) ;
+  
+// Get OS version
+int WXDLLEXPORT wxGetOsVersion(int *majorVsn=NULL,int *minorVsn=NULL) ;
+
+// Set the cursor to the busy cursor for all windows
+class WXDLLEXPORT wxCursor;
+WXDLLEXPORT_DATA(extern wxCursor*) wxHOURGLASS_CURSOR;
+void WXDLLEXPORT wxBeginBusyCursor(wxCursor *cursor = wxHOURGLASS_CURSOR);
+ 
+// Restore cursor to normal
+void WXDLLEXPORT wxEndBusyCursor(void);
+ 
+// TRUE if we're between the above two calls
+bool WXDLLEXPORT wxIsBusy(void);
+
+/* Error message functions used by wxWindows */
+
+// Non-fatal error (continues)
+WXDLLEXPORT_DATA(extern const char*) wxInternalErrorStr;
+void WXDLLEXPORT wxError(const wxString& msg, const wxString& title = wxInternalErrorStr);
+
+// Fatal error (exits)
+WXDLLEXPORT_DATA(extern const char*) wxFatalErrorStr;
+void WXDLLEXPORT wxFatalError(const wxString& msg, const wxString& title = wxFatalErrorStr);
+
+// Reading and writing resources (eg WIN.INI, .Xdefaults)
+#if USE_RESOURCES
+bool WXDLLEXPORT wxWriteResource(const wxString& section, const wxString& entry, const wxString& value, const wxString& file = "");
+bool WXDLLEXPORT wxWriteResource(const wxString& section, const wxString& entry, float value, const wxString& file = "");
+bool WXDLLEXPORT wxWriteResource(const wxString& section, const wxString& entry, long value, const wxString& file = "");
+bool WXDLLEXPORT wxWriteResource(const wxString& section, const wxString& entry, int value, const wxString& file = "");
+
+bool WXDLLEXPORT wxGetResource(const wxString& section, const wxString& entry, char **value, const wxString& file = "");
+bool WXDLLEXPORT wxGetResource(const wxString& section, const wxString& entry, float *value, const wxString& file = "");
+bool WXDLLEXPORT wxGetResource(const wxString& section, const wxString& entry, long *value, const wxString& file = "");
+bool WXDLLEXPORT wxGetResource(const wxString& section, const wxString& entry, int *value, const wxString& file = "");
+#endif // USE_RESOURCES
+
+#ifdef __UNIX__
+// 'X' Only, will soon vanish....
+// Get current Home dir and copy to dest
+char* WXDLLEXPORT wxGetHomeDir( char *dest );
+#endif
+// Get the user's home dir (caller must copy--- volatile)
+// returns NULL is no HOME dir is known
+char* WXDLLEXPORT wxGetUserHome(const wxString& user = "");
+
+// Check whether this window wants to process messages, e.g. Stop button
+// in long calculations.
+bool WXDLLEXPORT wxCheckForInterrupt(wxWindow *wnd);
+
+void WXDLLEXPORT wxGetMousePosition( int* x, int* y );
+
+// MSW only: get user-defined resource from the .res file.
+// Returns NULL or newly-allocated memory, so use delete[] to clean up.
+#ifdef __WINDOWS__
+extern const char* WXDLLEXPORT wxUserResourceStr;
+char* WXDLLEXPORT wxLoadUserResource(const wxString& resourceName, const wxString& resourceType = wxUserResourceStr);
+#endif
+
+// X only
+#ifdef __X__
+// Get X display: often needed in the wxWindows implementation.
+Display *wxGetDisplay(void);
+/* Matthew Flatt: Added wxSetDisplay and wxGetDisplayName */
+bool wxSetDisplay(const wxString& display_name);
+wxString wxGetDisplayName(void);
+#endif
+
+#ifdef __X__
+
+#include <X11/Xlib.h>
+
+#define wxMAX_RGB           0xff
+#define wxMAX_SV            1000
+#define wxSIGN(x)           ((x < 0) ? -x : x)
+#define wxH_WEIGHT          4
+#define wxS_WEIGHT          1
+#define wxV_WEIGHT          2
+
+typedef struct wx_hsv {
+                        int h,s,v;
+                      } wxHSV;
+ 
+#define wxMax3(x,y,z) ((x > y) ? ((x > z) ? x : z) : ((y > z) ? y : z))
+#define wxMin3(x,y,z) ((x < y) ? ((x < z) ? x : z) : ((y < z) ? y : z))
+
+#define wxMax2(x,y)   ((x > y) ? x : y)
+#define wxMin2(x,y)   ((x < y) ? x : y)
+
+void wxHSVToXColor(wxHSV *hsv,XColor *xcolor);
+void wxXColorToHSV(wxHSV *hsv,XColor *xcolor);
+void wxAllocNearestColor(Display *display,Colormap colormap,XColor *xcolor);
+void wxAllocColor(Display *display,Colormap colormap,XColor *xcolor);
+
+#endif //__X__
+
+#endif
+    // __UTILSH__
diff --git a/include/wx/validate.h b/include/wx/validate.h
new file mode 100644
index 0000000000..f068eb225c
--- /dev/null
+++ b/include/wx/validate.h
@@ -0,0 +1,70 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        validate.h
+// Purpose:     wxValidator class
+// Author:      Julian Smart
+// Modified by:
+// Created:     29/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Julian Smart
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __VALIDATEH__
+#define __VALIDATEH__
+
+#ifdef __GNUG__
+#pragma interface "validate.h"
+#endif
+
+#include "wx/event.h"
+
+class WXDLLEXPORT wxWindow;
+
+/*
+ A validator has up to three purposes:
+
+ 1) To validate the data in the window that's associated
+    with the validator.
+ 2) To transfer data to and from the window.
+ 3) To filter input, using its role as a wxEvtHandler
+    to intercept e.g. OnChar.
+
+ Note that wxValidator and derived classes use reference counting.
+ */
+
+class WXDLLEXPORT wxValidator: public wxEvtHandler
+{
+DECLARE_DYNAMIC_CLASS(wxValidator)
+public:
+  wxValidator(void);
+  ~wxValidator();
+
+  // Make a clone of this validator (or return NULL) - currently necessary
+  // if you're passing a reference to a validator.
+  // Another possibility is to always pass a pointer to a new validator
+  // (so the calling code can use a copy constructor of the relevant class).
+  virtual wxValidator *Clone(void) const { return NULL; }
+  inline bool Copy(const wxValidator& val) { m_validatorWindow = val.m_validatorWindow; return TRUE; }
+
+  // Called when the value in the window must be validated.
+  // This function can pop up an error message.
+  virtual bool Validate(wxWindow *WXUNUSED(parent)) { return FALSE; };
+
+  // Called to transfer data to the window
+  virtual bool TransferToWindow(void) { return FALSE; }
+
+  // Called to transfer data from the window
+  virtual bool TransferFromWindow(void) { return FALSE; };
+
+  // ACCESSORS
+  inline wxWindow *GetWindow(void) const { return m_validatorWindow; }
+  inline void SetWindow(wxWindow *win) { m_validatorWindow = win; }
+
+protected:
+    wxWindow *m_validatorWindow;
+};
+
+WXDLLEXPORT_DATA(extern const wxValidator) wxDefaultValidator;
+
+#endif
+    // __VALIDATEH__
diff --git a/include/wx/valtext.h b/include/wx/valtext.h
new file mode 100644
index 0000000000..f7ee50eec4
--- /dev/null
+++ b/include/wx/valtext.h
@@ -0,0 +1,77 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        valtext.h
+// Purpose:     wxTextValidator class
+// Author:      Julian Smart
+// Modified by:
+// Created:     29/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Julian Smart
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __VALTEXTH__
+#define __VALTEXTH__
+
+#ifdef __GNUG__
+#pragma interface "valtext.h"
+#endif
+
+#include "wx/validate.h"
+
+#define wxFILTER_NONE           0x0000
+#define wxFILTER_ASCII          0x0001
+#define wxFILTER_ALPHA          0x0002
+#define wxFILTER_ALPHANUMERIC   0x0004
+#define wxFILTER_NUMERIC        0x0008
+#define wxFILTER_INCLUDE_LIST   0x0010
+#define wxFILTER_EXCLUDE_LIST   0x0020
+
+class WXDLLEXPORT wxTextValidator: public wxValidator
+{
+DECLARE_DYNAMIC_CLASS(wxTextValidator)
+public:
+  wxTextValidator(const long style = wxFILTER_NONE, wxString *val = NULL);
+  wxTextValidator(const wxTextValidator& val);
+
+  ~wxTextValidator();
+
+  // Make a clone of this validator (or return NULL) - currently necessary
+  // if you're passing a reference to a validator.
+  // Another possibility is to always pass a pointer to a new validator
+  // (so the calling code can use a copy constructor of the relevant class).
+  virtual wxValidator *Clone(void) const { return new wxTextValidator(*this); }
+  bool Copy(const wxTextValidator& val);
+
+  // Called when the value in the window must be validated.
+  // This function can pop up an error message.
+  virtual bool Validate(wxWindow *parent);
+
+  // Called to transfer data to the window
+  virtual bool TransferToWindow(void);
+
+  // Called to transfer data to the window
+  virtual bool TransferFromWindow(void);
+
+  // ACCESSORS
+  inline long GetStyle(void) const { return m_validatorStyle; }
+  inline void SetStyle(const long style) { m_validatorStyle = style; }
+
+  void SetIncludeList(const wxStringList& list);
+  inline wxStringList& GetIncludeList(void) { return m_includeList; }
+
+  void SetExcludeList(const wxStringList& list);
+  inline wxStringList& GetExcludeList(void) { return m_excludeList; }
+
+  // Filter keystrokes
+  void OnChar(wxKeyEvent& event);
+
+DECLARE_EVENT_TABLE()
+
+protected:
+    long            m_validatorStyle;
+    wxString *      m_stringValue;
+    wxStringList    m_includeList;
+    wxStringList    m_excludeList;
+};
+
+#endif
diff --git a/include/wx/version.h b/include/wx/version.h
new file mode 100644
index 0000000000..9e1a8e5728
--- /dev/null
+++ b/include/wx/version.h
@@ -0,0 +1,25 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        version.h
+// Purpose:     wxWindows version numbers
+// Author:      Julian Smart
+// Modified by:
+// Created:     29/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Julian Smart
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __VERSIONH__
+#define __VERSIONH__
+
+/* Bump-up with each new version */
+#define wxMAJOR_VERSION    2
+#define wxMINOR_VERSION    0
+#define wxRELEASE_NUMBER   0
+#define wxVERSION_STRING "wxWindows 2.0"
+#define wxVERSION_NUMBER (wxMAJOR_VERSION * 1000) + (wxMINOR_VERSION * 100) + wxRELEASE_NUMBER
+#define wxBETA_NUMBER      12
+#define wxVERSION_FLOAT float(wxMAJOR_VERSION + (wxMINOR_VERSION/10.0) + (wxRELEASE_NUMBER/100.0) + (wxBETA_NUMBER/10000.0))
+
+#endif
+	// __VERSIONH__
diff --git a/include/wx/window.h b/include/wx/window.h
new file mode 100644
index 0000000000..578ba0881b
--- /dev/null
+++ b/include/wx/window.h
@@ -0,0 +1,13 @@
+#ifndef __WINDOWH_BASE__
+#define __WINDOWH_BASE__
+
+#if defined(__WINDOWS__)
+#include "wx/msw/window.h"
+#elif defined(__MOTIF__)
+#include "wx/xt/window.h"
+#elif defined(__GTK__)
+#include "wx/gtk/window.h"
+#endif
+
+#endif
+    // __WINDOWH_BASE__
diff --git a/include/wx/wx.h b/include/wx/wx.h
new file mode 100644
index 0000000000..4a8529e696
--- /dev/null
+++ b/include/wx/wx.h
@@ -0,0 +1,70 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        wx.h
+// Purpose:     wxWindows main include file
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c)
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __WXH__
+#define __WXH__
+
+#include "wx/setup.h"           // Which features to include - user editable
+#include "wx/defs.h"
+#include "wx/string.h"
+#include "wx/window.h"
+#include "wx/panel.h"
+#include "wx/frame.h"
+#include "wx/dc.h"
+#include "wx/dcclient.h"
+#include "wx/dcmemory.h"
+#include "wx/dcprint.h"
+#include "wx/dcscreen.h"
+#include "wx/postscrp.h"
+#include "wx/button.h"
+#include "wx/bmpbuttn.h"
+#include "wx/checkbox.h"
+#include "wx/choice.h"
+#include "wx/scrolbar.h"
+#include "wx/stattext.h"
+#include "wx/statbmp.h"
+#include "wx/statbox.h"
+#include "wx/listbox.h"
+#include "wx/radiobox.h"
+#include "wx/radiobut.h"
+#include "wx/textctrl.h"
+#include "wx/slider.h"
+#include "wx/gauge.h"
+#include "wx/combobox.h"
+#include "wx/menu.h"
+#include "wx/app.h"
+#include "wx/event.h"
+#include "wx/list.h"
+#include "wx/pen.h"
+#include "wx/brush.h"
+#include "wx/palette.h"
+#include "wx/icon.h"
+#include "wx/cursor.h"
+#include "wx/dialog.h"
+#include "wx/timer.h"
+#include "wx/utils.h"
+#include "wx/settings.h"
+#include "wx/layout.h"
+#include "wx/memory.h"
+#include "wx/mdi.h"
+#include "wx/scrolwin.h"
+#include "wx/statusbr.h"
+#include "wx/scrolbar.h"
+#include "wx/msgdlg.h"
+#include "wx/choicdlg.h"
+#include "wx/textdlg.h"
+#include "wx/filedlg.h"
+#include "wx/dirdlg.h"
+#include "wx/cmndata.h"
+#include "wx/intl.h"
+
+#endif
+    // __WXH__
diff --git a/include/wx/wxprec.h b/include/wx/wxprec.h
new file mode 100644
index 0000000000..71018481a8
--- /dev/null
+++ b/include/wx/wxprec.h
@@ -0,0 +1,61 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        wxprec.h
+// Purpose:     Includes the appropriate files for precompiled headers
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c)
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+// check if to use precompiled headers
+#if (defined(__BORLANDC__) || defined(_MSC_VER) || defined(__WATCOMC__) || defined(__GNUWIN32__)) // && !defined(WXMAKINGDLL)
+#if !NOPCH
+#define WX_PRECOMP
+#endif
+#endif
+
+// For some reason, this must be defined for common dialogs to work.
+#ifdef __WATCOMC__
+#define INCLUDE_COMMDLG_H	1
+#endif
+
+// include the wx definitions
+#ifdef WX_PRECOMP
+#include "wx/wx.h"
+
+// Comment this out if you don't mind slower compilation of the wxWindows
+// library
+#include <windows.h>
+
+#ifdef GetClassInfo
+#undef GetClassInfo
+#endif
+
+#ifdef GetClassName
+#undef GetClassName
+#endif
+
+#ifdef DrawText
+#undef DrawText
+#endif
+
+#ifdef GetCharWidth
+#undef GetCharWidth
+#endif
+
+#ifdef StartDoc
+#undef StartDoc
+#endif
+
+#ifdef FindWindow
+#undef FindWindow
+#endif
+
+#ifdef FindResource
+#undef FindResource
+#endif
+
+#endif
+
diff --git a/install-sh b/install-sh
new file mode 100755
index 0000000000..ebc66913e9
--- /dev/null
+++ b/install-sh
@@ -0,0 +1,250 @@
+#! /bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd="$cpprog"
+	    shift
+	    continue;;
+
+	-d) dir_arg=true
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd="$stripprog"
+	    shift
+	    continue;;
+
+	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
+	    shift
+	    continue;;
+
+	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		# this colon is to work around a 386BSD /bin/sh bug
+		:
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "install:	no input file specified"
+	exit 1
+else
+	true
+fi
+
+if [ x"$dir_arg" != x ]; then
+	dst=$src
+	src=""
+	
+	if [ -d $dst ]; then
+		instcmd=:
+	else
+		instcmd=mkdir
+	fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+	if [ -f $src -o -d $src ]
+	then
+		true
+	else
+		echo "install:  $src does not exist"
+		exit 1
+	fi
+	
+	if [ x"$dst" = x ]
+	then
+		echo "install:	no destination specified"
+		exit 1
+	else
+		true
+	fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+	if [ -d $dst ]
+	then
+		dst="$dst"/`basename $src`
+	else
+		true
+	fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='	
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+	pathcomp="${pathcomp}${1}"
+	shift
+
+	if [ ! -d "${pathcomp}" ] ;
+        then
+		$mkdirprog "${pathcomp}"
+	else
+		true
+	fi
+
+	pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+	$doit $instcmd $dst &&
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+	if [ x"$transformarg" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		dstfile=`basename $dst $transformbasename | 
+			sed $transformarg`$transformbasename
+	fi
+
+# don't allow the sed command to completely eliminate the filename
+
+	if [ x"$dstfile" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		true
+	fi
+
+# Make a temp file name in the proper directory.
+
+	dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+	$doit $instcmd $src $dsttmp &&
+
+	trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+	$doit $rmcmd -f $dstdir/$dstfile &&
+	$doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
diff --git a/lib/dummy b/lib/dummy
new file mode 100644
index 0000000000..bfdf726d49
--- /dev/null
+++ b/lib/dummy
@@ -0,0 +1 @@
+I'm just here to force the creation of a LIB directory.
diff --git a/misc/afm/Cour.afm b/misc/afm/Cour.afm
new file mode 100644
index 0000000000..f54e284ba7
--- /dev/null
+++ b/misc/afm/Cour.afm
@@ -0,0 +1,341 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1984 Adobe Systems Incorporated. 	All Rights Reserved.
+Comment Creation Date:Wed Feb 25 16:01:10 PST 1987
+FontName Courier
+EncodingScheme AdobeStandardEncoding
+FullName Courier
+FamilyName Courier
+Weight Medium
+ItalicAngle 0.0
+IsFixedPitch true
+UnderlinePosition -82
+UnderlineThickness 40
+Version 001.003
+FontBBox -40 -290 640 795
+CapHeight 583
+XHeight 437
+Descender -207
+Ascender 624
+StartCharMetrics 260
+C 32 ; WX 600 ; N space ; B 560 -40 640 40 ;
+C 33 ; WX 600 ; N exclam ; B 240 -5 360 639 ;
+C 34 ; WX 600 ; N quotedbl ; B 126 314 474 603 ;
+C 35 ; WX 600 ; N numbersign ; B 72 -82 528 665 ;
+C 36 ; WX 600 ; N dollar ; B 93 -113 507 675 ;
+C 37 ; WX 600 ; N percent ; B 67 -35 533 639 ;
+C 38 ; WX 600 ; N ampersand ; B 85 -35 498 540 ;
+C 39 ; WX 600 ; N quoteright ; B 135 304 340 613 ;
+C 40 ; WX 600 ; N parenleft ; B 274 -144 478 623 ;
+C 41 ; WX 600 ; N parenright ; B 127 -144 331 623 ;
+C 42 ; WX 600 ; N asterisk ; B 93 210 507 624 ;
+C 43 ; WX 600 ; N plus ; B 52 12 548 550 ;
+C 44 ; WX 600 ; N comma ; B 135 -155 340 155 ;
+C 45 ; WX 600 ; N hyphen ; B 52 241 548 321 ;
+C 46 ; WX 600 ; N period ; B 250 10 350 90 ;
+C 47 ; WX 600 ; N slash ; B 93 -103 507 686 ;
+C 48 ; WX 600 ; N zero ; B 93 -35 507 639 ;
+C 49 ; WX 600 ; N one ; B 93 -20 507 624 ;
+C 50 ; WX 600 ; N two ; B 64 -20 498 639 ;
+C 51 ; WX 600 ; N three ; B 76 -35 519 639 ;
+C 52 ; WX 600 ; N four ; B 85 -20 498 624 ;
+C 53 ; WX 600 ; N five ; B 76 -35 519 624 ;
+C 54 ; WX 600 ; N six ; B 116 -35 530 639 ;
+C 55 ; WX 600 ; N seven ; B 85 -20 498 624 ;
+C 56 ; WX 600 ; N eight ; B 93 -35 507 639 ;
+C 57 ; WX 600 ; N nine ; B 116 -35 530 639 ;
+C 58 ; WX 600 ; N colon ; B 250 10 350 392 ;
+C 59 ; WX 600 ; N semicolon ; B 139 -116 350 392 ;
+C 60 ; WX 600 ; N less ; B 52 12 548 550 ;
+C 61 ; WX 600 ; N equal ; B 31 168 569 394 ;
+C 62 ; WX 600 ; N greater ; B 52 12 548 550 ;
+C 63 ; WX 600 ; N question ; B 114 -5 507 598 ;
+C 64 ; WX 600 ; N at ; B 85 -82 498 644 ;
+C 65 ; WX 600 ; N A ; B -11 -20 611 583 ;
+C 66 ; WX 600 ; N B ; B 23 -20 561 583 ;
+C 67 ; WX 600 ; N C ; B 43 -35 554 598 ;
+C 68 ; WX 600 ; N D ; B 23 -20 540 583 ;
+C 69 ; WX 600 ; N E ; B 23 -20 540 583 ;
+C 70 ; WX 600 ; N F ; B 23 -20 540 583 ;
+C 71 ; WX 600 ; N G ; B 43 -35 582 598 ;
+C 72 ; WX 600 ; N H ; B 33 -20 571 583 ;
+C 73 ; WX 600 ; N I ; B 93 -20 507 583 ;
+C 74 ; WX 600 ; N J ; B 64 -35 603 583 ;
+C 75 ; WX 600 ; N K ; B 23 -20 592 583 ;
+C 76 ; WX 600 ; N L ; B 43 -20 561 583 ;
+C 77 ; WX 600 ; N M ; B -9 -20 613 583 ;
+C 78 ; WX 600 ; N N ; B 2 -20 582 583 ;
+C 79 ; WX 600 ; N O ; B 31 -35 569 598 ;
+C 80 ; WX 600 ; N P ; B 23 -20 519 583 ;
+C 81 ; WX 600 ; N Q ; B 31 -136 569 598 ;
+C 82 ; WX 600 ; N R ; B 23 -20 609 583 ;
+C 83 ; WX 600 ; N S ; B 72 -35 528 598 ;
+C 84 ; WX 600 ; N T ; B 52 -20 548 583 ;
+C 85 ; WX 600 ; N U ; B 20 -35 580 583 ;
+C 86 ; WX 600 ; N V ; B -11 -20 611 583 ;
+C 87 ; WX 600 ; N W ; B 0 -20 600 583 ;
+C 88 ; WX 600 ; N X ; B 20 -20 580 583 ;
+C 89 ; WX 600 ; N Y ; B 31 -20 569 583 ;
+C 90 ; WX 600 ; N Z ; B 83 -20 517 583 ;
+C 91 ; WX 600 ; N bracketleft ; B 260 -144 465 624 ;
+C 92 ; WX 600 ; N backslash ; B 93 -103 507 686 ;
+C 93 ; WX 600 ; N bracketright ; B 135 -144 340 624 ;
+C 94 ; WX 600 ; N asciicircum ; B 93 335 507 624 ;
+C 95 ; WX 600 ; N underscore ; B -32 -290 632 -210 ;
+C 96 ; WX 600 ; N quoteleft ; B 260 304 465 613 ;
+C 97 ; WX 600 ; N a ; B 52 -35 561 452 ;
+C 98 ; WX 600 ; N b ; B 2 -35 561 624 ;
+C 99 ; WX 600 ; N c ; B 64 -35 555 452 ;
+C 100 ; WX 600 ; N d ; B 43 -35 603 624 ;
+C 101 ; WX 600 ; N e ; B 43 -35 540 452 ;
+C 102 ; WX 600 ; N f ; B 85 -20 561 624 ; L i fi ; L l fl ;
+C 103 ; WX 600 ; N g ; B 43 -207 582 452 ;
+C 104 ; WX 600 ; N h ; B 23 -20 571 624 ;
+C 105 ; WX 600 ; N i ; B 72 -20 528 665 ;
+C 106 ; WX 600 ; N j ; B 127 -207 478 665 ;
+C 107 ; WX 600 ; N k ; B 43 -20 561 624 ;
+C 108 ; WX 600 ; N l ; B 72 -20 528 624 ;
+C 109 ; WX 600 ; N m ; B -9 -20 613 452 ;
+C 110 ; WX 600 ; N n ; B 33 -20 561 452 ;
+C 111 ; WX 600 ; N o ; B 52 -35 548 452 ;
+C 112 ; WX 600 ; N p ; B 2 -207 561 452 ;
+C 113 ; WX 600 ; N q ; B 43 -207 603 452 ;
+C 114 ; WX 600 ; N r ; B 64 -20 561 448 ;
+C 115 ; WX 600 ; N s ; B 83 -35 517 452 ;
+C 116 ; WX 600 ; N t ; B 23 -35 519 582 ;
+C 117 ; WX 600 ; N u ; B 23 -35 561 437 ;
+C 118 ; WX 600 ; N v ; B 10 -20 590 437 ;
+C 119 ; WX 600 ; N w ; B 10 -20 590 437 ;
+C 120 ; WX 600 ; N x ; B 31 -20 569 437 ;
+C 121 ; WX 600 ; N y ; B 31 -207 569 437 ;
+C 122 ; WX 600 ; N z ; B 95 -20 509 437 ;
+C 123 ; WX 600 ; N braceleft ; B 177 -144 423 624 ;
+C 124 ; WX 600 ; N bar ; B 260 -144 340 624 ;
+C 125 ; WX 600 ; N braceright ; B 177 -144 423 624 ;
+C 126 ; WX 600 ; N asciitilde ; B 72 189 528 373 ;
+C 161 ; WX 600 ; N exclamdown ; B 240 -207 360 415 ;
+C 162 ; WX 600 ; N cent ; B 93 -19 489 665 ;
+C 163 ; WX 600 ; N sterling ; B 43 -20 540 598 ;
+C 164 ; WX 600 ; N fraction ; B 31 120 569 492 ;
+C 165 ; WX 600 ; N yen ; B 31 -20 569 583 ;
+C 166 ; WX 600 ; N florin ; B 67 -113 538 639 ;
+C 167 ; WX 600 ; N section ; B 46 -87 554 629 ;
+C 168 ; WX 600 ; N currency ; B 83 75 517 509 ;
+C 169 ; WX 600 ; N quotesingle ; B 230 304 370 613 ;
+C 170 ; WX 600 ; N quotedblleft ; B 93 340 507 619 ;
+C 171 ; WX 600 ; N guillemotleft ; B 43 -20 561 437 ;
+C 172 ; WX 600 ; N guilsinglleft ; B 43 -20 332 437 ;
+C 173 ; WX 600 ; N guilsinglright ; B 273 -20 561 437 ;
+C 174 ; WX 600 ; N fi ; B -10 -20 610 665 ;
+C 175 ; WX 600 ; N fl ; B -10 -20 610 624 ;
+C 177 ; WX 600 ; N endash ; B 52 241 548 321 ;
+C 178 ; WX 600 ; N dagger ; B 104 -82 496 624 ;
+C 179 ; WX 600 ; N daggerdbl ; B 104 -82 496 624 ;
+C 180 ; WX 600 ; N periodcentered ; B 250 266 350 346 ;
+C 182 ; WX 600 ; N paragraph ; B 59 -87 545 629 ;
+C 183 ; WX 600 ; N bullet ; B 260 266 340 346 ;
+C 184 ; WX 600 ; N quotesinglbase ; B 135 -165 340 144 ;
+C 185 ; WX 600 ; N quotedblbase ; B 93 -139 507 139 ;
+C 186 ; WX 600 ; N quotedblright ; B 93 340 507 619 ;
+C 187 ; WX 600 ; N guillemotright ; B 43 -20 561 437 ;
+C 188 ; WX 600 ; N ellipsis ; B 60 -5 540 75 ;
+C 189 ; WX 600 ; N perthousand ; B 10 -35 590 639 ;
+C 191 ; WX 600 ; N questiondown ; B 93 -207 486 415 ;
+C 193 ; WX 600 ; N grave ; B 135 450 340 639 ;
+C 194 ; WX 600 ; N acute ; B 260 450 465 639 ;
+C 195 ; WX 600 ; N circumflex ; B 135 450 465 624 ;
+C 196 ; WX 600 ; N tilde ; B 125 441 475 580 ;
+C 197 ; WX 600 ; N macron ; B 135 476 465 556 ;
+C 198 ; WX 600 ; N breve ; B 135 450 465 624 ;
+C 199 ; WX 600 ; N dotaccent ; B 260 491 340 571 ;
+C 200 ; WX 600 ; N dieresis ; B 156 491 444 571 ;
+C 202 ; WX 600 ; N ring ; B 187 413 413 634 ;
+C 203 ; WX 600 ; N cedilla ; B 190 -186 397 40 ;
+C 205 ; WX 600 ; N hungarumlaut ; B 135 450 465 639 ;
+C 206 ; WX 600 ; N ogonek ; B 260 -165 453 40 ;
+C 207 ; WX 600 ; N caron ; B 135 450 465 624 ;
+C 208 ; WX 600 ; N emdash ; B -19 241 619 321 ;
+C 225 ; WX 600 ; N AE ; B -10 -20 610 583 ;
+C 227 ; WX 600 ; N ordfeminine ; B 127 179 478 598 ;
+C 232 ; WX 600 ; N Lslash ; B 23 -20 561 583 ;
+C 233 ; WX 600 ; N Oslash ; B 20 -61 580 623 ;
+C 234 ; WX 600 ; N OE ; B -10 -20 610 583 ;
+C 235 ; WX 600 ; N ordmasculine ; B 131 179 469 598 ;
+C 241 ; WX 600 ; N ae ; B -10 -35 600 452 ;
+C 245 ; WX 600 ; N dotlessi ; B 72 -20 528 437 ;
+C 248 ; WX 600 ; N lslash ; B 72 -20 528 624 ;
+C 249 ; WX 600 ; N oslash ; B 33 -61 563 478 ;
+C 250 ; WX 600 ; N oe ; B -10 -35 600 452 ;
+C 251 ; WX 600 ; N germandbls ; B 23 -35 519 624 ;
+C -1 ; WX 600 ; N Aacute ; B -11 -20 611 789 ;
+C -1 ; WX 600 ; N Acircumflex ; B -11 -20 611 774 ;
+C -1 ; WX 600 ; N Adieresis ; B -11 -20 611 721 ;
+C -1 ; WX 600 ; N Agrave ; B -11 -20 611 789 ;
+C -1 ; WX 600 ; N Aring ; B -11 -20 611 795 ;
+C -1 ; WX 600 ; N Atilde ; B -11 -20 611 730 ;
+C -1 ; WX 600 ; N Ccedilla ; B 43 -186 554 598 ;
+C -1 ; WX 600 ; N Eacute ; B 23 -20 540 789 ;
+C -1 ; WX 600 ; N Ecircumflex ; B 23 -20 540 774 ;
+C -1 ; WX 600 ; N Edieresis ; B 23 -20 540 721 ;
+C -1 ; WX 600 ; N Egrave ; B 23 -20 540 789 ;
+C -1 ; WX 600 ; N Eth ; B 23 -20 540 583 ;
+C -1 ; WX 600 ; N Gcaron ; B 43 -35 582 774 ;
+C -1 ; WX 600 ; N IJ ; B -10 -35 610 583 ;
+C -1 ; WX 600 ; N Iacute ; B 93 -20 507 789 ;
+C -1 ; WX 600 ; N Icircumflex ; B 93 -20 507 774 ;
+C -1 ; WX 600 ; N Idieresis ; B 93 -20 507 721 ;
+C -1 ; WX 600 ; N Idot ; B 93 -20 507 721 ;
+C -1 ; WX 600 ; N Igrave ; B 93 -20 507 789 ;
+C -1 ; WX 600 ; N LL ; B -20 -20 620 583 ;
+C -1 ; WX 600 ; N Ntilde ; B 2 -20 582 730 ;
+C -1 ; WX 600 ; N Oacute ; B 31 -35 569 789 ;
+C -1 ; WX 600 ; N Ocircumflex ; B 31 -35 569 774 ;
+C -1 ; WX 600 ; N Odieresis ; B 31 -35 569 721 ;
+C -1 ; WX 600 ; N Ograve ; B 31 -35 569 789 ;
+C -1 ; WX 600 ; N Otilde ; B 31 -35 569 730 ;
+C -1 ; WX 600 ; N Scaron ; B 72 -35 528 774 ;
+C -1 ; WX 600 ; N Scedilla ; B 72 -186 528 598 ;
+C -1 ; WX 600 ; N Thorn ; B 23 -20 539 583 ;
+C -1 ; WX 600 ; N Uacute ; B 20 -35 580 789 ;
+C -1 ; WX 600 ; N Ucircumflex ; B 20 -35 580 774 ;
+C -1 ; WX 600 ; N Udieresis ; B 20 -35 580 721 ;
+C -1 ; WX 600 ; N Ugrave ; B 20 -35 580 789 ;
+C -1 ; WX 600 ; N Yacute ; B 31 -20 569 789 ;
+C -1 ; WX 600 ; N Ydieresis ; B 31 -20 569 721 ;
+C -1 ; WX 600 ; N Zcaron ; B 83 -20 517 774 ;
+C -1 ; WX 600 ; N aacute ; B 52 -35 561 660 ;
+C -1 ; WX 600 ; N acircumflex ; B 52 -35 561 653 ;
+C -1 ; WX 600 ; N adieresis ; B 52 -35 561 592 ;
+C -1 ; WX 600 ; N agrave ; B 52 -35 561 660 ;
+C -1 ; WX 600 ; N aring ; B 52 -35 561 686 ;
+C -1 ; WX 600 ; N arrowboth ; B -40 110 640 490 ;
+C -1 ; WX 600 ; N arrowdown ; B 110 -20 490 639 ;
+C -1 ; WX 600 ; N arrowleft ; B -40 110 640 490 ;
+C -1 ; WX 600 ; N arrowright ; B -40 110 640 490 ;
+C -1 ; WX 600 ; N arrowup ; B 110 -20 490 639 ;
+C -1 ; WX 600 ; N atilde ; B 52 -35 561 618 ;
+C -1 ; WX 600 ; N brokenbar ; B 260 -144 340 624 ;
+C -1 ; WX 600 ; N ccedilla ; B 64 -186 555 452 ;
+C -1 ; WX 600 ; N center ; B 0 -20 600 624 ;
+C -1 ; WX 600 ; N copyright ; B -20 -35 620 598 ;
+C -1 ; WX 600 ; N dectab ; B -5 -20 605 248 ;
+C -1 ; WX 600 ; N degree ; B 135 294 465 624 ;
+C -1 ; WX 600 ; N divide ; B 52 51 548 531 ;
+C -1 ; WX 600 ; N down ; B 154 -20 446 452 ;
+C -1 ; WX 600 ; N eacute ; B 43 -35 540 664 ;
+C -1 ; WX 600 ; N ecircumflex ; B 43 -35 540 653 ;
+C -1 ; WX 600 ; N edieresis ; B 43 -35 540 592 ;
+C -1 ; WX 600 ; N egrave ; B 43 -35 540 664 ;
+C -1 ; WX 600 ; N eth ; B 52 -35 548 639 ;
+C -1 ; WX 600 ; N format ; B -15 -207 65 624 ;
+C -1 ; WX 600 ; N gcaron ; B 43 -207 582 645 ;
+C -1 ; WX 600 ; N graybox ; B 35 -40 565 640 ;
+C -1 ; WX 600 ; N iacute ; B 72 -20 528 660 ;
+C -1 ; WX 600 ; N icircumflex ; B 72 -20 528 634 ;
+C -1 ; WX 600 ; N idieresis ; B 72 -20 528 592 ;
+C -1 ; WX 600 ; N igrave ; B 72 -20 528 656 ;
+C -1 ; WX 600 ; N ij ; B 10 -207 550 665 ;
+C -1 ; WX 600 ; N indent ; B 54 60 546 352 ;
+C -1 ; WX 600 ; N largebullet ; B 260 266 340 346 ;
+C -1 ; WX 600 ; N left ; B 54 60 546 352 ;
+C -1 ; WX 600 ; N lira ; B 43 -20 540 598 ;
+C -1 ; WX 600 ; N ll ; B 0 -20 600 624 ;
+C -1 ; WX 600 ; N logicalnot ; B 52 154 548 394 ;
+C -1 ; WX 600 ; N merge ; B 154 -20 446 452 ;
+C -1 ; WX 600 ; N minus ; B 52 241 548 321 ;
+C -1 ; WX 600 ; N mu ; B 23 -207 561 437 ;
+C -1 ; WX 600 ; N multiply ; B 82 12 518 470 ;
+C -1 ; WX 600 ; N notegraphic ; B 150 -5 450 639 ;
+C -1 ; WX 600 ; N ntilde ; B 33 -20 561 618 ;
+C -1 ; WX 600 ; N oacute ; B 52 -35 548 649 ;
+C -1 ; WX 600 ; N ocircumflex ; B 52 -35 548 653 ;
+C -1 ; WX 600 ; N odieresis ; B 52 -35 548 592 ;
+C -1 ; WX 600 ; N ograve ; B 52 -35 548 649 ;
+C -1 ; WX 600 ; N onehalf ; B -10 -20 610 624 ;
+C -1 ; WX 600 ; N onequarter ; B -10 -20 610 624 ;
+C -1 ; WX 600 ; N onesuperior ; B 160 200 440 624 ;
+C -1 ; WX 600 ; N otilde ; B 52 -35 548 597 ;
+C -1 ; WX 600 ; N overscore ; B -32 559 632 639 ;
+C -1 ; WX 600 ; N plusminus ; B 52 -20 548 550 ;
+C -1 ; WX 600 ; N prescription ; B 23 -20 609 583 ;
+C -1 ; WX 600 ; N registered ; B -20 -35 620 598 ;
+C -1 ; WX 600 ; N return ; B -24 -20 624 608 ;
+C -1 ; WX 600 ; N scaron ; B 83 -35 517 645 ;
+C -1 ; WX 600 ; N scedilla ; B 83 -186 517 452 ;
+C -1 ; WX 600 ; N square ; B -24 -20 624 608 ;
+C -1 ; WX 600 ; N stop ; B -24 -20 624 608 ;
+C -1 ; WX 600 ; N tab ; B -24 -20 624 608 ;
+C -1 ; WX 600 ; N thorn ; B 2 -207 561 624 ;
+C -1 ; WX 600 ; N threequarters ; B -10 -20 610 639 ;
+C -1 ; WX 600 ; N threesuperior ; B 155 191 452 639 ;
+C -1 ; WX 600 ; N trademark ; B -20 230 620 583 ;
+C -1 ; WX 600 ; N twosuperior ; B 140 200 431 639 ;
+C -1 ; WX 600 ; N uacute ; B 23 -35 561 656 ;
+C -1 ; WX 600 ; N ucircumflex ; B 23 -35 561 634 ;
+C -1 ; WX 600 ; N udieresis ; B 23 -35 561 592 ;
+C -1 ; WX 600 ; N ugrave ; B 23 -35 561 656 ;
+C -1 ; WX 600 ; N up ; B 154 -20 446 452 ;
+C -1 ; WX 600 ; N yacute ; B 31 -207 569 656 ;
+C -1 ; WX 600 ; N ydieresis ; B 31 -207 569 571 ;
+C -1 ; WX 600 ; N zcaron ; B 95 -20 509 645 ;
+EndCharMetrics
+StartComposites 58
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 0 146 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 0 0 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 0 146 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 0 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 0 0 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 0 146 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 0 0 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 0 146 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 0 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 0 146 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 0 146 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 0 146 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 0 146 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 0 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 0 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 0 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 0 0 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 146 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 0 146 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 0 146 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 146 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex 0 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis 0 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 0 146 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 0 146 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 0 146 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 0 146 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ;
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 0 146 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 0 146 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 0 146 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 0 146 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 0 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 0 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 0 0 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 0 146 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 0 146 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 0 146 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 0 146 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 0 146 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 0 146 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 0 146 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 0 146 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ;
+EndComposites
+EndFontMetrics
diff --git a/misc/afm/CourBo.afm b/misc/afm/CourBo.afm
new file mode 100644
index 0000000000..5a2fbdc071
--- /dev/null
+++ b/misc/afm/CourBo.afm
@@ -0,0 +1,341 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1984 Adobe Systems Incorporated. 	All Rights Reserved.
+Comment Creation Date:Wed Feb 25 16:06:47 PST 1987
+FontName Courier-Bold
+EncodingScheme AdobeStandardEncoding
+FullName Courier Bold
+FamilyName Courier
+Weight Bold
+ItalicAngle 0.0
+IsFixedPitch true
+UnderlinePosition -85
+UnderlineThickness 100
+Version 001.003
+FontBBox -100 -350 700 855
+CapHeight 633
+XHeight 487
+Descender -257
+Ascender 674
+StartCharMetrics 260
+C 32 ; WX 600 ; N space ; B 500 -100 700 100 ;
+C 33 ; WX 600 ; N exclam ; B 170 -65 430 689 ;
+C 34 ; WX 600 ; N quotedbl ; B 66 254 534 663 ;
+C 35 ; WX 600 ; N numbersign ; B 12 -142 588 725 ;
+C 36 ; WX 600 ; N dollar ; B 33 -173 567 735 ;
+C 37 ; WX 600 ; N percent ; B 7 -65 593 689 ;
+C 38 ; WX 600 ; N ampersand ; B 25 -65 558 600 ;
+C 39 ; WX 600 ; N quoteright ; B 75 244 400 674 ;
+C 40 ; WX 600 ; N parenleft ; B 214 -204 538 683 ;
+C 41 ; WX 600 ; N parenright ; B 67 -204 391 683 ;
+C 42 ; WX 600 ; N asterisk ; B 33 150 567 674 ;
+C 43 ; WX 600 ; N plus ; B -8 -48 608 610 ;
+C 44 ; WX 600 ; N comma ; B 75 -215 400 215 ;
+C 45 ; WX 600 ; N hyphen ; B -8 181 608 381 ;
+C 46 ; WX 600 ; N period ; B 190 -50 410 150 ;
+C 47 ; WX 600 ; N slash ; B 33 -163 567 746 ;
+C 48 ; WX 600 ; N zero ; B 33 -65 567 689 ;
+C 49 ; WX 600 ; N one ; B 33 -50 567 674 ;
+C 50 ; WX 600 ; N two ; B 4 -50 558 689 ;
+C 51 ; WX 600 ; N three ; B 16 -65 579 689 ;
+C 52 ; WX 600 ; N four ; B 25 -50 558 674 ;
+C 53 ; WX 600 ; N five ; B 16 -65 579 674 ;
+C 54 ; WX 600 ; N six ; B 56 -65 590 689 ;
+C 55 ; WX 600 ; N seven ; B 25 -50 558 674 ;
+C 56 ; WX 600 ; N eight ; B 33 -65 567 689 ;
+C 57 ; WX 600 ; N nine ; B 56 -65 590 689 ;
+C 58 ; WX 600 ; N colon ; B 190 -50 410 472 ;
+C 59 ; WX 600 ; N semicolon ; B 79 -176 410 472 ;
+C 60 ; WX 600 ; N less ; B -8 -48 608 610 ;
+C 61 ; WX 600 ; N equal ; B -29 88 629 474 ;
+C 62 ; WX 600 ; N greater ; B -8 -48 608 610 ;
+C 63 ; WX 600 ; N question ; B 54 -65 567 648 ;
+C 64 ; WX 600 ; N at ; B 26 -142 559 705 ;
+C 65 ; WX 600 ; N A ; B -71 -50 671 633 ;
+C 66 ; WX 600 ; N B ; B -37 -50 621 633 ;
+C 67 ; WX 600 ; N C ; B -17 -65 614 648 ;
+C 68 ; WX 600 ; N D ; B -37 -50 600 633 ;
+C 69 ; WX 600 ; N E ; B -37 -50 600 633 ;
+C 70 ; WX 600 ; N F ; B -37 -50 600 633 ;
+C 71 ; WX 600 ; N G ; B -17 -65 642 648 ;
+C 72 ; WX 600 ; N H ; B -27 -50 631 633 ;
+C 73 ; WX 600 ; N I ; B 33 -50 567 633 ;
+C 74 ; WX 600 ; N J ; B 4 -65 663 633 ;
+C 75 ; WX 600 ; N K ; B -37 -50 652 633 ;
+C 76 ; WX 600 ; N L ; B -17 -50 621 633 ;
+C 77 ; WX 600 ; N M ; B -69 -50 673 633 ;
+C 78 ; WX 600 ; N N ; B -58 -50 642 633 ;
+C 79 ; WX 600 ; N O ; B -29 -65 629 648 ;
+C 80 ; WX 600 ; N P ; B -37 -50 579 633 ;
+C 81 ; WX 600 ; N Q ; B -29 -196 629 648 ;
+C 82 ; WX 600 ; N R ; B -37 -50 669 633 ;
+C 83 ; WX 600 ; N S ; B 12 -65 588 648 ;
+C 84 ; WX 600 ; N T ; B -8 -50 608 633 ;
+C 85 ; WX 600 ; N U ; B -40 -65 640 633 ;
+C 86 ; WX 600 ; N V ; B -71 -50 671 633 ;
+C 87 ; WX 600 ; N W ; B -60 -50 660 633 ;
+C 88 ; WX 600 ; N X ; B -40 -50 640 633 ;
+C 89 ; WX 600 ; N Y ; B -29 -50 629 633 ;
+C 90 ; WX 600 ; N Z ; B 23 -50 577 633 ;
+C 91 ; WX 600 ; N bracketleft ; B 200 -204 525 674 ;
+C 92 ; WX 600 ; N backslash ; B 33 -163 567 746 ;
+C 93 ; WX 600 ; N bracketright ; B 75 -204 400 674 ;
+C 94 ; WX 600 ; N asciicircum ; B 33 275 567 674 ;
+C 95 ; WX 600 ; N underscore ; B -92 -350 692 -150 ;
+C 96 ; WX 600 ; N quoteleft ; B 200 244 525 674 ;
+C 97 ; WX 600 ; N a ; B -8 -65 621 502 ;
+C 98 ; WX 600 ; N b ; B -58 -65 621 674 ;
+C 99 ; WX 600 ; N c ; B 4 -65 615 502 ;
+C 100 ; WX 600 ; N d ; B -17 -65 663 674 ;
+C 101 ; WX 600 ; N e ; B -17 -65 600 502 ;
+C 102 ; WX 600 ; N f ; B 25 -50 621 674 ; L i fi ; L l fl ;
+C 103 ; WX 600 ; N g ; B -17 -257 642 502 ;
+C 104 ; WX 600 ; N h ; B -37 -50 631 674 ;
+C 105 ; WX 600 ; N i ; B 12 -50 588 725 ;
+C 106 ; WX 600 ; N j ; B 67 -257 538 725 ;
+C 107 ; WX 600 ; N k ; B -17 -50 621 674 ;
+C 108 ; WX 600 ; N l ; B 12 -50 588 674 ;
+C 109 ; WX 600 ; N m ; B -69 -50 673 502 ;
+C 110 ; WX 600 ; N n ; B -27 -50 621 502 ;
+C 111 ; WX 600 ; N o ; B -8 -65 608 502 ;
+C 112 ; WX 600 ; N p ; B -58 -257 621 502 ;
+C 113 ; WX 600 ; N q ; B -17 -257 663 502 ;
+C 114 ; WX 600 ; N r ; B 4 -50 621 501 ;
+C 115 ; WX 600 ; N s ; B 23 -65 577 502 ;
+C 116 ; WX 600 ; N t ; B -37 -65 579 642 ;
+C 117 ; WX 600 ; N u ; B -37 -65 621 487 ;
+C 118 ; WX 600 ; N v ; B -50 -50 650 487 ;
+C 119 ; WX 600 ; N w ; B -50 -50 650 487 ;
+C 120 ; WX 600 ; N x ; B -29 -50 629 487 ;
+C 121 ; WX 600 ; N y ; B -29 -257 629 487 ;
+C 122 ; WX 600 ; N z ; B 35 -50 569 487 ;
+C 123 ; WX 600 ; N braceleft ; B 117 -204 483 674 ;
+C 124 ; WX 600 ; N bar ; B 200 -204 400 674 ;
+C 125 ; WX 600 ; N braceright ; B 117 -204 483 674 ;
+C 126 ; WX 600 ; N asciitilde ; B 12 129 588 433 ;
+C 161 ; WX 600 ; N exclamdown ; B 170 -257 430 475 ;
+C 162 ; WX 600 ; N cent ; B 33 -79 549 725 ;
+C 163 ; WX 600 ; N sterling ; B -17 -50 600 648 ;
+C 164 ; WX 600 ; N fraction ; B -29 60 629 552 ;
+C 165 ; WX 600 ; N yen ; B -29 -50 629 633 ;
+C 166 ; WX 600 ; N florin ; B 7 -173 598 689 ;
+C 167 ; WX 600 ; N section ; B -14 -147 614 689 ;
+C 168 ; WX 600 ; N currency ; B 23 15 577 569 ;
+C 169 ; WX 600 ; N quotesingle ; B 170 244 430 674 ;
+C 170 ; WX 600 ; N quotedblleft ; B 33 280 567 678 ;
+C 171 ; WX 600 ; N guillemotleft ; B -17 -50 621 487 ;
+C 172 ; WX 600 ; N guilsinglleft ; B -17 -50 392 487 ;
+C 173 ; WX 600 ; N guilsinglright ; B 213 -50 621 487 ;
+C 174 ; WX 600 ; N fi ; B -70 -50 670 725 ;
+C 175 ; WX 600 ; N fl ; B -70 -50 670 674 ;
+C 177 ; WX 600 ; N endash ; B -8 181 608 381 ;
+C 178 ; WX 600 ; N dagger ; B 44 -142 556 674 ;
+C 179 ; WX 600 ; N daggerdbl ; B 44 -142 556 674 ;
+C 180 ; WX 600 ; N periodcentered ; B 190 206 410 406 ;
+C 182 ; WX 600 ; N paragraph ; B -1 -147 605 689 ;
+C 183 ; WX 600 ; N bullet ; B 200 206 400 406 ;
+C 184 ; WX 600 ; N quotesinglbase ; B 75 -225 400 204 ;
+C 185 ; WX 600 ; N quotedblbase ; B 33 -199 567 199 ;
+C 186 ; WX 600 ; N quotedblright ; B 33 280 567 678 ;
+C 187 ; WX 600 ; N guillemotright ; B -17 -50 621 487 ;
+C 188 ; WX 600 ; N ellipsis ; B 0 -65 600 135 ;
+C 189 ; WX 600 ; N perthousand ; B -50 -65 650 689 ;
+C 191 ; WX 600 ; N questiondown ; B 33 -257 546 475 ;
+C 193 ; WX 600 ; N grave ; B 75 390 400 689 ;
+C 194 ; WX 600 ; N acute ; B 200 390 525 689 ;
+C 195 ; WX 600 ; N circumflex ; B 75 390 525 674 ;
+C 196 ; WX 600 ; N tilde ; B 65 381 535 640 ;
+C 197 ; WX 600 ; N macron ; B 75 416 525 616 ;
+C 198 ; WX 600 ; N breve ; B 75 390 525 674 ;
+C 199 ; WX 600 ; N dotaccent ; B 200 431 400 631 ;
+C 200 ; WX 600 ; N dieresis ; B 96 431 504 631 ;
+C 202 ; WX 600 ; N ring ; B 127 353 473 694 ;
+C 203 ; WX 600 ; N cedilla ; B 130 -246 457 100 ;
+C 205 ; WX 600 ; N hungarumlaut ; B 75 390 525 689 ;
+C 206 ; WX 600 ; N ogonek ; B 200 -225 513 100 ;
+C 207 ; WX 600 ; N caron ; B 75 390 525 674 ;
+C 208 ; WX 600 ; N emdash ; B -79 181 679 381 ;
+C 225 ; WX 600 ; N AE ; B -70 -50 670 633 ;
+C 227 ; WX 600 ; N ordfeminine ; B 68 120 539 649 ;
+C 232 ; WX 600 ; N Lslash ; B -37 -50 621 633 ;
+C 233 ; WX 600 ; N Oslash ; B -40 -121 640 683 ;
+C 234 ; WX 600 ; N OE ; B -70 -50 670 633 ;
+C 235 ; WX 600 ; N ordmasculine ; B 72 120 530 649 ;
+C 241 ; WX 600 ; N ae ; B -70 -65 660 502 ;
+C 245 ; WX 600 ; N dotlessi ; B 12 -50 588 487 ;
+C 248 ; WX 600 ; N lslash ; B 12 -50 588 674 ;
+C 249 ; WX 600 ; N oslash ; B -27 -121 623 538 ;
+C 250 ; WX 600 ; N oe ; B -70 -65 660 502 ;
+C 251 ; WX 600 ; N germandbls ; B -37 -65 579 674 ;
+C -1 ; WX 600 ; N Aacute ; B -71 -50 671 839 ;
+C -1 ; WX 600 ; N Acircumflex ; B -71 -50 671 824 ;
+C -1 ; WX 600 ; N Adieresis ; B -71 -50 671 781 ;
+C -1 ; WX 600 ; N Agrave ; B -71 -50 671 839 ;
+C -1 ; WX 600 ; N Aring ; B -71 -50 671 855 ;
+C -1 ; WX 600 ; N Atilde ; B -71 -50 671 790 ;
+C -1 ; WX 600 ; N Ccedilla ; B -17 -246 614 648 ;
+C -1 ; WX 600 ; N Eacute ; B -37 -50 600 839 ;
+C -1 ; WX 600 ; N Ecircumflex ; B -37 -50 600 824 ;
+C -1 ; WX 600 ; N Edieresis ; B -37 -50 600 781 ;
+C -1 ; WX 600 ; N Egrave ; B -37 -50 600 839 ;
+C -1 ; WX 600 ; N Eth ; B -37 -50 600 633 ;
+C -1 ; WX 600 ; N Gcaron ; B -17 -65 642 824 ;
+C -1 ; WX 600 ; N IJ ; B -70 -65 670 633 ;
+C -1 ; WX 600 ; N Iacute ; B 33 -50 567 839 ;
+C -1 ; WX 600 ; N Icircumflex ; B 33 -50 567 824 ;
+C -1 ; WX 600 ; N Idieresis ; B 33 -50 567 781 ;
+C -1 ; WX 600 ; N Idot ; B 33 -50 567 781 ;
+C -1 ; WX 600 ; N Igrave ; B 33 -50 567 839 ;
+C -1 ; WX 600 ; N LL ; B -80 -50 680 633 ;
+C -1 ; WX 600 ; N Ntilde ; B -58 -50 642 790 ;
+C -1 ; WX 600 ; N Oacute ; B -29 -65 629 839 ;
+C -1 ; WX 600 ; N Ocircumflex ; B -29 -65 629 824 ;
+C -1 ; WX 600 ; N Odieresis ; B -29 -65 629 781 ;
+C -1 ; WX 600 ; N Ograve ; B -29 -65 629 839 ;
+C -1 ; WX 600 ; N Otilde ; B -29 -65 629 790 ;
+C -1 ; WX 600 ; N Scaron ; B 12 -65 588 824 ;
+C -1 ; WX 600 ; N Scedilla ; B 12 -246 588 648 ;
+C -1 ; WX 600 ; N Thorn ; B -37 -50 599 633 ;
+C -1 ; WX 600 ; N Uacute ; B -40 -65 640 839 ;
+C -1 ; WX 600 ; N Ucircumflex ; B -40 -65 640 824 ;
+C -1 ; WX 600 ; N Udieresis ; B -40 -65 640 781 ;
+C -1 ; WX 600 ; N Ugrave ; B -40 -65 640 839 ;
+C -1 ; WX 600 ; N Yacute ; B -29 -50 629 839 ;
+C -1 ; WX 600 ; N Ydieresis ; B -29 -50 629 781 ;
+C -1 ; WX 600 ; N Zcaron ; B 23 -50 577 824 ;
+C -1 ; WX 600 ; N aacute ; B -8 -65 621 710 ;
+C -1 ; WX 600 ; N acircumflex ; B -8 -65 621 703 ;
+C -1 ; WX 600 ; N adieresis ; B -8 -65 621 652 ;
+C -1 ; WX 600 ; N agrave ; B -8 -65 621 710 ;
+C -1 ; WX 600 ; N aring ; B -8 -65 621 746 ;
+C -1 ; WX 600 ; N arrowboth ; B -100 50 700 550 ;
+C -1 ; WX 600 ; N arrowdown ; B 50 -50 550 689 ;
+C -1 ; WX 600 ; N arrowleft ; B -100 50 700 550 ;
+C -1 ; WX 600 ; N arrowright ; B -100 50 700 550 ;
+C -1 ; WX 600 ; N arrowup ; B 50 -50 550 689 ;
+C -1 ; WX 600 ; N atilde ; B -8 -65 621 678 ;
+C -1 ; WX 600 ; N brokenbar ; B 200 -204 400 674 ;
+C -1 ; WX 600 ; N ccedilla ; B 4 -246 615 502 ;
+C -1 ; WX 600 ; N center ; B -60 -50 660 684 ;
+C -1 ; WX 600 ; N copyright ; B -80 -65 680 648 ;
+C -1 ; WX 600 ; N dectab ; B -65 -50 665 308 ;
+C -1 ; WX 600 ; N degree ; B 75 234 525 674 ;
+C -1 ; WX 600 ; N divide ; B -8 -9 608 591 ;
+C -1 ; WX 600 ; N down ; B 94 -50 506 502 ;
+C -1 ; WX 600 ; N eacute ; B -17 -65 600 714 ;
+C -1 ; WX 600 ; N ecircumflex ; B -17 -65 600 703 ;
+C -1 ; WX 600 ; N edieresis ; B -17 -65 600 652 ;
+C -1 ; WX 600 ; N egrave ; B -17 -65 600 714 ;
+C -1 ; WX 600 ; N eth ; B -8 -65 608 689 ;
+C -1 ; WX 600 ; N format ; B -75 -257 125 674 ;
+C -1 ; WX 600 ; N gcaron ; B -17 -257 642 695 ;
+C -1 ; WX 600 ; N graybox ; B -25 -100 625 700 ;
+C -1 ; WX 600 ; N iacute ; B 12 -50 588 710 ;
+C -1 ; WX 600 ; N icircumflex ; B 12 -50 588 684 ;
+C -1 ; WX 600 ; N idieresis ; B 12 -50 588 652 ;
+C -1 ; WX 600 ; N igrave ; B 12 -50 588 706 ;
+C -1 ; WX 600 ; N ij ; B -50 -257 610 725 ;
+C -1 ; WX 600 ; N indent ; B -6 0 606 412 ;
+C -1 ; WX 600 ; N largebullet ; B 200 206 400 406 ;
+C -1 ; WX 600 ; N left ; B -6 0 606 412 ;
+C -1 ; WX 600 ; N lira ; B -17 -50 600 648 ;
+C -1 ; WX 600 ; N ll ; B -60 -50 660 674 ;
+C -1 ; WX 600 ; N logicalnot ; B -8 94 608 454 ;
+C -1 ; WX 600 ; N merge ; B 94 -50 506 502 ;
+C -1 ; WX 600 ; N minus ; B -8 181 608 381 ;
+C -1 ; WX 600 ; N mu ; B -37 -257 621 487 ;
+C -1 ; WX 600 ; N multiply ; B 22 -48 578 530 ;
+C -1 ; WX 600 ; N notegraphic ; B 80 -65 520 689 ;
+C -1 ; WX 600 ; N ntilde ; B -27 -50 621 678 ;
+C -1 ; WX 600 ; N oacute ; B -8 -65 608 699 ;
+C -1 ; WX 600 ; N ocircumflex ; B -8 -65 608 703 ;
+C -1 ; WX 600 ; N odieresis ; B -8 -65 608 652 ;
+C -1 ; WX 600 ; N ograve ; B -8 -65 608 699 ;
+C -1 ; WX 600 ; N onehalf ; B -70 -65 670 674 ;
+C -1 ; WX 600 ; N onequarter ; B -70 -50 670 674 ;
+C -1 ; WX 600 ; N onesuperior ; B 100 140 500 674 ;
+C -1 ; WX 600 ; N otilde ; B -8 -65 608 657 ;
+C -1 ; WX 600 ; N overscore ; B -92 489 692 689 ;
+C -1 ; WX 600 ; N plusminus ; B -8 -50 608 610 ;
+C -1 ; WX 600 ; N prescription ; B -37 -50 669 633 ;
+C -1 ; WX 600 ; N registered ; B -80 -65 680 648 ;
+C -1 ; WX 600 ; N return ; B -84 -50 684 668 ;
+C -1 ; WX 600 ; N scaron ; B 23 -65 577 695 ;
+C -1 ; WX 600 ; N scedilla ; B 23 -246 577 502 ;
+C -1 ; WX 600 ; N square ; B -84 -50 684 668 ;
+C -1 ; WX 600 ; N stop ; B -84 -50 684 668 ;
+C -1 ; WX 600 ; N tab ; B -84 -50 684 668 ;
+C -1 ; WX 600 ; N thorn ; B -58 -257 621 674 ;
+C -1 ; WX 600 ; N threequarters ; B -70 -50 670 689 ;
+C -1 ; WX 600 ; N threesuperior ; B 95 131 512 689 ;
+C -1 ; WX 600 ; N trademark ; B -80 170 680 633 ;
+C -1 ; WX 600 ; N twosuperior ; B 80 140 491 689 ;
+C -1 ; WX 600 ; N uacute ; B -37 -65 621 706 ;
+C -1 ; WX 600 ; N ucircumflex ; B -37 -65 621 684 ;
+C -1 ; WX 600 ; N udieresis ; B -37 -65 621 652 ;
+C -1 ; WX 600 ; N ugrave ; B -37 -65 621 706 ;
+C -1 ; WX 600 ; N up ; B 94 -50 506 502 ;
+C -1 ; WX 600 ; N yacute ; B -29 -257 629 706 ;
+C -1 ; WX 600 ; N ydieresis ; B -29 -257 629 631 ;
+C -1 ; WX 600 ; N zcaron ; B 35 -50 569 695 ;
+EndCharMetrics
+StartComposites 58
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 0 146 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 0 0 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 0 146 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 0 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 0 0 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 0 146 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 0 0 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 0 146 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 0 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 0 146 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 0 146 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 0 146 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 0 146 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 0 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 0 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 0 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 0 0 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 146 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 0 146 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 0 146 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 146 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex 0 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis 0 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 0 146 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 0 146 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 0 146 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 0 146 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ;
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 0 146 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 0 146 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 0 146 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 0 146 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 0 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 0 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 0 0 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 0 146 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 0 146 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 0 146 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 0 146 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 0 146 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 0 146 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 0 146 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 0 146 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ;
+EndComposites
+EndFontMetrics
diff --git a/misc/afm/CourBoO.afm b/misc/afm/CourBoO.afm
new file mode 100644
index 0000000000..603eab5278
--- /dev/null
+++ b/misc/afm/CourBoO.afm
@@ -0,0 +1,341 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1984 Adobe Systems Incorporated. 	All Rights Reserved.
+Comment Creation Date:Wed Feb 25 16:19:52 PST 1987
+FontName Courier-BoldOblique
+EncodingScheme AdobeStandardEncoding
+FullName Courier Bold Oblique
+FamilyName Courier
+Weight Bold
+ItalicAngle -12.0
+IsFixedPitch true
+UnderlinePosition -85
+UnderlineThickness 100
+Version 001.003
+FontBBox -145 -350 817 855
+CapHeight 633
+XHeight 487
+Descender -257
+Ascender 674
+StartCharMetrics 260
+C 32 ; WX 600 ; N space ; B 500 -100 700 100 ;
+C 33 ; WX 600 ; N exclam ; B 197 -65 549 689 ;
+C 34 ; WX 600 ; N quotedbl ; B 171 254 654 663 ;
+C 35 ; WX 600 ; N numbersign ; B 52 -142 672 725 ;
+C 36 ; WX 600 ; N dollar ; B 51 -173 659 735 ;
+C 37 ; WX 600 ; N percent ; B 58 -65 671 689 ;
+C 38 ; WX 600 ; N ampersand ; B 52 -65 607 600 ;
+C 39 ; WX 600 ; N quoteright ; B 148 244 522 674 ;
+C 40 ; WX 600 ; N parenleft ; B 255 -204 662 683 ;
+C 41 ; WX 600 ; N parenright ; B 45 -204 452 683 ;
+C 42 ; WX 600 ; N asterisk ; B 131 150 665 674 ;
+C 43 ; WX 600 ; N plus ; B 52 -48 668 610 ;
+C 44 ; WX 600 ; N comma ; B 51 -215 424 215 ;
+C 45 ; WX 600 ; N hyphen ; B 52 181 668 381 ;
+C 46 ; WX 600 ; N period ; B 201 -50 421 150 ;
+C 47 ; WX 600 ; N slash ; B 20 -163 704 746 ;
+C 48 ; WX 600 ; N zero ; B 82 -65 649 689 ;
+C 49 ; WX 600 ; N one ; B 44 -50 578 674 ;
+C 50 ; WX 600 ; N two ; B 15 -50 656 689 ;
+C 51 ; WX 600 ; N three ; B 30 -65 659 689 ;
+C 52 ; WX 600 ; N four ; B 65 -50 618 674 ;
+C 53 ; WX 600 ; N five ; B 33 -65 660 674 ;
+C 54 ; WX 600 ; N six ; B 108 -65 712 689 ;
+C 55 ; WX 600 ; N seven ; B 136 -50 680 674 ;
+C 56 ; WX 600 ; N eight ; B 64 -65 655 689 ;
+C 57 ; WX 600 ; N nine ; B 67 -65 665 689 ;
+C 58 ; WX 600 ; N colon ; B 201 -50 489 472 ;
+C 59 ; WX 600 ; N semicolon ; B 63 -176 489 472 ;
+C 60 ; WX 600 ; N less ; B 52 -48 716 610 ;
+C 61 ; WX 600 ; N equal ; B 11 88 708 474 ;
+C 62 ; WX 600 ; N greater ; B 3 -48 668 610 ;
+C 63 ; WX 600 ; N question ; B 148 -65 657 648 ;
+C 64 ; WX 600 ; N at ; B 61 -142 640 705 ;
+C 65 ; WX 600 ; N A ; B -60 -50 682 633 ;
+C 66 ; WX 600 ; N B ; B -26 -50 670 633 ;
+C 67 ; WX 600 ; N C ; B 31 -65 713 648 ;
+C 68 ; WX 600 ; N D ; B -26 -50 670 633 ;
+C 69 ; WX 600 ; N E ; B -26 -50 692 633 ;
+C 70 ; WX 600 ; N F ; B -26 -50 713 633 ;
+C 71 ; WX 600 ; N G ; B 29 -65 713 648 ;
+C 72 ; WX 600 ; N H ; B -16 -50 723 633 ;
+C 73 ; WX 600 ; N I ; B 44 -50 680 633 ;
+C 74 ; WX 600 ; N J ; B 22 -65 776 633 ;
+C 75 ; WX 600 ; N K ; B -26 -50 744 633 ;
+C 76 ; WX 600 ; N L ; B -6 -50 665 633 ;
+C 77 ; WX 600 ; N M ; B -58 -50 776 633 ;
+C 78 ; WX 600 ; N N ; B -26 -50 755 633 ;
+C 79 ; WX 600 ; N O ; B 26 -65 696 648 ;
+C 80 ; WX 600 ; N P ; B -26 -50 666 633 ;
+C 81 ; WX 600 ; N Q ; B 26 -196 696 648 ;
+C 82 ; WX 600 ; N R ; B -26 -50 680 633 ;
+C 83 ; WX 600 ; N S ; B 23 -65 680 648 ;
+C 84 ; WX 600 ; N T ; B 72 -50 721 633 ;
+C 85 ; WX 600 ; N U ; B 61 -65 753 633 ;
+C 86 ; WX 600 ; N V ; B 42 -50 784 633 ;
+C 87 ; WX 600 ; N W ; B 50 -50 773 633 ;
+C 88 ; WX 600 ; N X ; B -29 -50 742 633 ;
+C 89 ; WX 600 ; N Y ; B 76 -50 742 633 ;
+C 90 ; WX 600 ; N Z ; B 34 -50 669 633 ;
+C 91 ; WX 600 ; N bracketleft ; B 178 -204 647 674 ;
+C 92 ; WX 600 ; N backslash ; B 170 -163 554 746 ;
+C 93 ; WX 600 ; N bracketright ; B 53 -204 522 674 ;
+C 94 ; WX 600 ; N asciicircum ; B 113 275 647 674 ;
+C 95 ; WX 600 ; N underscore ; B -145 -350 639 -150 ;
+C 96 ; WX 600 ; N quoteleft ; B 322 244 598 674 ;
+C 97 ; WX 600 ; N a ; B 16 -65 632 502 ;
+C 98 ; WX 600 ; N b ; B -47 -65 670 674 ;
+C 99 ; WX 600 ; N c ; B 44 -65 672 502 ;
+C 100 ; WX 600 ; N d ; B 23 -65 701 674 ;
+C 101 ; WX 600 ; N e ; B 25 -65 650 502 ;
+C 102 ; WX 600 ; N f ; B 36 -50 740 674 ; L i fi ; L l fl ;
+C 103 ; WX 600 ; N g ; B 25 -257 724 502 ;
+C 104 ; WX 600 ; N h ; B -16 -50 642 674 ;
+C 105 ; WX 600 ; N i ; B 23 -50 599 725 ;
+C 106 ; WX 600 ; N j ; B 34 -257 620 725 ;
+C 107 ; WX 600 ; N k ; B -6 -50 661 674 ;
+C 108 ; WX 600 ; N l ; B 23 -50 599 674 ;
+C 109 ; WX 600 ; N m ; B -58 -50 684 502 ;
+C 110 ; WX 600 ; N n ; B -16 -50 632 502 ;
+C 111 ; WX 600 ; N o ; B 34 -65 656 502 ;
+C 112 ; WX 600 ; N p ; B -91 -257 671 502 ;
+C 113 ; WX 600 ; N q ; B 27 -257 745 502 ;
+C 114 ; WX 600 ; N r ; B 15 -50 699 501 ;
+C 115 ; WX 600 ; N s ; B 34 -65 638 502 ;
+C 116 ; WX 600 ; N t ; B 45 -65 599 642 ;
+C 117 ; WX 600 ; N u ; B 45 -65 640 487 ;
+C 118 ; WX 600 ; N v ; B 32 -50 732 487 ;
+C 119 ; WX 600 ; N w ; B 32 -50 732 487 ;
+C 120 ; WX 600 ; N x ; B -18 -50 690 487 ;
+C 121 ; WX 600 ; N y ; B -62 -257 711 487 ;
+C 122 ; WX 600 ; N z ; B 46 -50 640 487 ;
+C 123 ; WX 600 ; N braceleft ; B 168 -204 605 674 ;
+C 124 ; WX 600 ; N bar ; B 178 -204 522 674 ;
+C 125 ; WX 600 ; N braceright ; B 95 -204 534 674 ;
+C 126 ; WX 600 ; N asciitilde ; B 67 129 652 433 ;
+C 161 ; WX 600 ; N exclamdown ; B 143 -257 490 475 ;
+C 162 ; WX 600 ; N cent ; B 96 -79 643 725 ;
+C 163 ; WX 600 ; N sterling ; B 15 -50 620 648 ;
+C 164 ; WX 600 ; N fraction ; B 5 60 725 552 ;
+C 165 ; WX 600 ; N yen ; B 77 -50 742 633 ;
+C 166 ; WX 600 ; N florin ; B -6 -173 720 689 ;
+C 167 ; WX 600 ; N section ; B 18 -147 697 689 ;
+C 168 ; WX 600 ; N currency ; B 47 15 677 569 ;
+C 169 ; WX 600 ; N quotesingle ; B 273 244 552 674 ;
+C 170 ; WX 600 ; N quotedblleft ; B 156 280 648 678 ;
+C 171 ; WX 600 ; N guillemotleft ; B 27 -50 703 487 ;
+C 172 ; WX 600 ; N guilsinglleft ; B 27 -50 474 487 ;
+C 173 ; WX 600 ; N guilsinglright ; B 224 -50 665 487 ;
+C 174 ; WX 600 ; N fi ; B -59 -50 681 725 ;
+C 175 ; WX 600 ; N fl ; B -59 -50 687 674 ;
+C 177 ; WX 600 ; N endash ; B 52 181 668 381 ;
+C 178 ; WX 600 ; N dagger ; B 126 -142 638 674 ;
+C 179 ; WX 600 ; N daggerdbl ; B 75 -142 638 674 ;
+C 180 ; WX 600 ; N periodcentered ; B 255 206 475 406 ;
+C 182 ; WX 600 ; N paragraph ; B 72 -147 730 689 ;
+C 183 ; WX 600 ; N bullet ; B 265 206 465 406 ;
+C 184 ; WX 600 ; N quotesinglbase ; B 48 -225 422 204 ;
+C 185 ; WX 600 ; N quotedblbase ; B 12 -199 588 199 ;
+C 186 ; WX 600 ; N quotedblright ; B 114 280 690 678 ;
+C 187 ; WX 600 ; N guillemotright ; B -6 -50 665 487 ;
+C 188 ; WX 600 ; N ellipsis ; B 7 -65 607 135 ;
+C 189 ; WX 600 ; N perthousand ; B 55 -65 679 689 ;
+C 191 ; WX 600 ; N questiondown ; B 26 -257 533 475 ;
+C 193 ; WX 600 ; N grave ; B 200 390 504 689 ;
+C 194 ; WX 600 ; N acute ; B 304 390 650 689 ;
+C 195 ; WX 600 ; N circumflex ; B 179 390 629 674 ;
+C 196 ; WX 600 ; N tilde ; B 171 381 646 640 ;
+C 197 ; WX 600 ; N macron ; B 185 416 635 616 ;
+C 198 ; WX 600 ; N breve ; B 196 390 647 674 ;
+C 199 ; WX 600 ; N dotaccent ; B 313 431 513 631 ;
+C 200 ; WX 600 ; N dieresis ; B 209 431 617 631 ;
+C 202 ; WX 600 ; N ring ; B 237 353 586 694 ;
+C 203 ; WX 600 ; N cedilla ; B 103 -246 436 100 ;
+C 205 ; WX 600 ; N hungarumlaut ; B 179 390 650 689 ;
+C 206 ; WX 600 ; N ogonek ; B 184 -225 490 100 ;
+C 207 ; WX 600 ; N caron ; B 197 390 647 674 ;
+C 208 ; WX 600 ; N emdash ; B -19 181 739 381 ;
+C 225 ; WX 600 ; N AE ; B -59 -50 763 633 ;
+C 227 ; WX 600 ; N ordfeminine ; B 114 120 590 649 ;
+C 232 ; WX 600 ; N Lslash ; B -6 -50 665 633 ;
+C 233 ; WX 600 ; N Oslash ; B -44 -121 764 683 ;
+C 234 ; WX 600 ; N OE ; B -16 -50 763 633 ;
+C 235 ; WX 600 ; N ordmasculine ; B 118 120 623 649 ;
+C 241 ; WX 600 ; N ae ; B -39 -65 711 502 ;
+C 245 ; WX 600 ; N dotlessi ; B 23 -50 599 487 ;
+C 248 ; WX 600 ; N lslash ; B 23 -50 604 674 ;
+C 249 ; WX 600 ; N oslash ; B -31 -121 716 538 ;
+C 250 ; WX 600 ; N oe ; B -30 -65 711 502 ;
+C 251 ; WX 600 ; N germandbls ; B -26 -65 618 674 ;
+C -1 ; WX 600 ; N Aacute ; B -60 -50 682 839 ;
+C -1 ; WX 600 ; N Acircumflex ; B -60 -50 682 824 ;
+C -1 ; WX 600 ; N Adieresis ; B -60 -50 682 781 ;
+C -1 ; WX 600 ; N Agrave ; B -60 -50 682 839 ;
+C -1 ; WX 600 ; N Aring ; B -60 -50 682 855 ;
+C -1 ; WX 600 ; N Atilde ; B -60 -50 682 790 ;
+C -1 ; WX 600 ; N Ccedilla ; B 31 -246 713 648 ;
+C -1 ; WX 600 ; N Eacute ; B -26 -50 692 839 ;
+C -1 ; WX 600 ; N Ecircumflex ; B -26 -50 692 824 ;
+C -1 ; WX 600 ; N Edieresis ; B -26 -50 692 781 ;
+C -1 ; WX 600 ; N Egrave ; B -26 -50 692 839 ;
+C -1 ; WX 600 ; N Eth ; B -26 -50 670 633 ;
+C -1 ; WX 600 ; N Gcaron ; B 29 -65 713 824 ;
+C -1 ; WX 600 ; N IJ ; B -59 -65 783 633 ;
+C -1 ; WX 600 ; N Iacute ; B 44 -50 680 839 ;
+C -1 ; WX 600 ; N Icircumflex ; B 44 -50 680 824 ;
+C -1 ; WX 600 ; N Idieresis ; B 44 -50 680 781 ;
+C -1 ; WX 600 ; N Idot ; B 44 -50 680 781 ;
+C -1 ; WX 600 ; N Igrave ; B 44 -50 680 839 ;
+C -1 ; WX 600 ; N LL ; B -69 -50 712 633 ;
+C -1 ; WX 600 ; N Ntilde ; B -26 -50 755 790 ;
+C -1 ; WX 600 ; N Oacute ; B 26 -65 696 839 ;
+C -1 ; WX 600 ; N Ocircumflex ; B 26 -65 696 824 ;
+C -1 ; WX 600 ; N Odieresis ; B 26 -65 696 781 ;
+C -1 ; WX 600 ; N Ograve ; B 26 -65 696 839 ;
+C -1 ; WX 600 ; N Otilde ; B 26 -65 696 790 ;
+C -1 ; WX 600 ; N Scaron ; B 23 -65 680 824 ;
+C -1 ; WX 600 ; N Scedilla ; B 23 -246 680 648 ;
+C -1 ; WX 600 ; N Thorn ; B -26 -50 663 633 ;
+C -1 ; WX 600 ; N Uacute ; B 61 -65 753 839 ;
+C -1 ; WX 600 ; N Ucircumflex ; B 61 -65 753 824 ;
+C -1 ; WX 600 ; N Udieresis ; B 61 -65 753 781 ;
+C -1 ; WX 600 ; N Ugrave ; B 61 -65 753 839 ;
+C -1 ; WX 600 ; N Yacute ; B 76 -50 742 839 ;
+C -1 ; WX 600 ; N Ydieresis ; B 76 -50 742 781 ;
+C -1 ; WX 600 ; N Zcaron ; B 34 -50 679 824 ;
+C -1 ; WX 600 ; N aacute ; B 16 -65 632 710 ;
+C -1 ; WX 600 ; N acircumflex ; B 16 -65 635 703 ;
+C -1 ; WX 600 ; N adieresis ; B 16 -65 632 652 ;
+C -1 ; WX 600 ; N agrave ; B 16 -65 632 710 ;
+C -1 ; WX 600 ; N aring ; B 16 -65 632 746 ;
+C -1 ; WX 600 ; N arrowboth ; B -36 50 764 550 ;
+C -1 ; WX 600 ; N arrowdown ; B 93 -50 593 689 ;
+C -1 ; WX 600 ; N arrowleft ; B -36 50 764 550 ;
+C -1 ; WX 600 ; N arrowright ; B -36 50 764 550 ;
+C -1 ; WX 600 ; N arrowup ; B 143 -50 643 689 ;
+C -1 ; WX 600 ; N atilde ; B 16 -65 654 678 ;
+C -1 ; WX 600 ; N brokenbar ; B 178 -204 522 674 ;
+C -1 ; WX 600 ; N ccedilla ; B 44 -246 672 502 ;
+C -1 ; WX 600 ; N center ; B 2 -50 722 684 ;
+C -1 ; WX 600 ; N copyright ; B -27 -65 743 648 ;
+C -1 ; WX 600 ; N dectab ; B -54 -50 676 308 ;
+C -1 ; WX 600 ; N degree ; B 171 234 624 674 ;
+C -1 ; WX 600 ; N divide ; B 52 -9 668 591 ;
+C -1 ; WX 600 ; N down ; B 127 -50 539 502 ;
+C -1 ; WX 600 ; N eacute ; B 25 -65 650 714 ;
+C -1 ; WX 600 ; N ecircumflex ; B 25 -65 650 703 ;
+C -1 ; WX 600 ; N edieresis ; B 25 -65 650 652 ;
+C -1 ; WX 600 ; N egrave ; B 25 -65 650 714 ;
+C -1 ; WX 600 ; N eth ; B 28 -65 695 689 ;
+C -1 ; WX 600 ; N format ; B -108 -257 247 674 ;
+C -1 ; WX 600 ; N gcaron ; B 25 -257 724 695 ;
+C -1 ; WX 600 ; N graybox ; B -25 -100 753 700 ;
+C -1 ; WX 600 ; N iacute ; B 23 -50 599 710 ;
+C -1 ; WX 600 ; N icircumflex ; B 23 -50 599 684 ;
+C -1 ; WX 600 ; N idieresis ; B 23 -50 599 652 ;
+C -1 ; WX 600 ; N igrave ; B 23 -50 599 706 ;
+C -1 ; WX 600 ; N ij ; B -39 -257 692 725 ;
+C -1 ; WX 600 ; N indent ; B 38 0 650 412 ;
+C -1 ; WX 600 ; N largebullet ; B 265 206 465 406 ;
+C -1 ; WX 600 ; N left ; B 38 0 650 412 ;
+C -1 ; WX 600 ; N lira ; B 15 -50 620 648 ;
+C -1 ; WX 600 ; N ll ; B -49 -50 682 674 ;
+C -1 ; WX 600 ; N logicalnot ; B 67 94 683 454 ;
+C -1 ; WX 600 ; N merge ; B 127 -50 569 502 ;
+C -1 ; WX 600 ; N minus ; B 52 181 668 381 ;
+C -1 ; WX 600 ; N mu ; B 13 -257 640 487 ;
+C -1 ; WX 600 ; N multiply ; B 33 -48 669 530 ;
+C -1 ; WX 600 ; N notegraphic ; B 107 -65 639 689 ;
+C -1 ; WX 600 ; N ntilde ; B -16 -50 632 678 ;
+C -1 ; WX 600 ; N oacute ; B 34 -65 656 699 ;
+C -1 ; WX 600 ; N ocircumflex ; B 34 -65 656 703 ;
+C -1 ; WX 600 ; N odieresis ; B 34 -65 656 652 ;
+C -1 ; WX 600 ; N ograve ; B 34 -65 656 699 ;
+C -1 ; WX 600 ; N onehalf ; B -14 -65 725 674 ;
+C -1 ; WX 600 ; N onequarter ; B -14 -50 741 674 ;
+C -1 ; WX 600 ; N onesuperior ; B 151 140 551 674 ;
+C -1 ; WX 600 ; N otilde ; B 34 -65 656 657 ;
+C -1 ; WX 600 ; N overscore ; B 33 489 817 689 ;
+C -1 ; WX 600 ; N plusminus ; B 3 -50 677 610 ;
+C -1 ; WX 600 ; N prescription ; B -26 -50 680 633 ;
+C -1 ; WX 600 ; N registered ; B -27 -65 743 648 ;
+C -1 ; WX 600 ; N return ; B -24 -50 805 668 ;
+C -1 ; WX 600 ; N scaron ; B 34 -65 651 695 ;
+C -1 ; WX 600 ; N scedilla ; B 34 -246 638 502 ;
+C -1 ; WX 600 ; N square ; B -73 -50 805 668 ;
+C -1 ; WX 600 ; N stop ; B -73 -50 805 668 ;
+C -1 ; WX 600 ; N tab ; B -73 -50 744 668 ;
+C -1 ; WX 600 ; N thorn ; B -91 -257 671 674 ;
+C -1 ; WX 600 ; N threequarters ; B -3 -50 711 689 ;
+C -1 ; WX 600 ; N threesuperior ; B 155 131 612 689 ;
+C -1 ; WX 600 ; N trademark ; B 18 170 793 633 ;
+C -1 ; WX 600 ; N twosuperior ; B 131 140 601 689 ;
+C -1 ; WX 600 ; N uacute ; B 45 -65 640 706 ;
+C -1 ; WX 600 ; N ucircumflex ; B 45 -65 640 684 ;
+C -1 ; WX 600 ; N udieresis ; B 45 -65 640 652 ;
+C -1 ; WX 600 ; N ugrave ; B 45 -65 640 706 ;
+C -1 ; WX 600 ; N up ; B 157 -50 569 502 ;
+C -1 ; WX 600 ; N yacute ; B -62 -257 711 706 ;
+C -1 ; WX 600 ; N ydieresis ; B -62 -257 711 631 ;
+C -1 ; WX 600 ; N zcaron ; B 46 -50 651 695 ;
+EndCharMetrics
+StartComposites 58
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 0 146 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 0 0 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 0 146 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 0 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 0 0 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 0 146 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 0 0 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 0 146 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 0 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 0 146 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 0 146 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 0 146 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 0 146 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 0 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 0 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 0 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 0 0 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 146 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 0 146 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 0 146 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 146 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex 0 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis 0 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 0 146 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 0 146 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 0 146 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 0 146 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ;
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 0 146 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 0 146 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 0 146 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 0 146 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 0 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 0 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 0 0 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 0 146 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 0 146 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 0 146 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 0 146 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 0 146 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 0 146 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 0 146 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 0 146 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ;
+EndComposites
+EndFontMetrics
diff --git a/misc/afm/CourO.afm b/misc/afm/CourO.afm
new file mode 100644
index 0000000000..0911df46f9
--- /dev/null
+++ b/misc/afm/CourO.afm
@@ -0,0 +1,341 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1984 Adobe Systems Incorporated. 	All Rights Reserved.
+Comment Creation Date:Wed Feb 25 16:13:37 PST 1987
+FontName Courier-Oblique
+EncodingScheme AdobeStandardEncoding
+FullName Courier Oblique
+FamilyName Courier
+Weight Medium
+ItalicAngle -12.0
+IsFixedPitch true
+UnderlinePosition -82
+UnderlineThickness 40
+Version 001.003
+FontBBox -85 -290 759 795
+CapHeight 583
+XHeight 437
+Descender -207
+Ascender 624
+StartCharMetrics 260
+C 32 ; WX 600 ; N space ; B 560 -40 640 40 ;
+C 33 ; WX 600 ; N exclam ; B 257 -5 483 639 ;
+C 34 ; WX 600 ; N quotedbl ; B 231 314 594 603 ;
+C 35 ; WX 600 ; N numbersign ; B 116 -82 608 665 ;
+C 36 ; WX 600 ; N dollar ; B 111 -113 601 675 ;
+C 37 ; WX 600 ; N percent ; B 118 -35 611 639 ;
+C 38 ; WX 600 ; N ampersand ; B 112 -35 547 540 ;
+C 39 ; WX 600 ; N quoteright ; B 208 304 462 613 ;
+C 40 ; WX 600 ; N parenleft ; B 315 -144 602 623 ;
+C 41 ; WX 600 ; N parenright ; B 105 -144 392 623 ;
+C 42 ; WX 600 ; N asterisk ; B 191 210 605 624 ;
+C 43 ; WX 600 ; N plus ; B 112 12 608 550 ;
+C 44 ; WX 600 ; N comma ; B 111 -155 364 155 ;
+C 45 ; WX 600 ; N hyphen ; B 112 241 608 321 ;
+C 46 ; WX 600 ; N period ; B 261 10 361 90 ;
+C 47 ; WX 600 ; N slash ; B 80 -103 644 686 ;
+C 48 ; WX 600 ; N zero ; B 139 -35 590 639 ;
+C 49 ; WX 600 ; N one ; B 97 -20 511 624 ;
+C 50 ; WX 600 ; N two ; B 68 -20 596 639 ;
+C 51 ; WX 600 ; N three ; B 90 -35 599 639 ;
+C 52 ; WX 600 ; N four ; B 125 -20 560 624 ;
+C 53 ; WX 600 ; N five ; B 93 -35 602 624 ;
+C 54 ; WX 600 ; N six ; B 167 -35 654 639 ;
+C 55 ; WX 600 ; N seven ; B 196 -20 622 624 ;
+C 56 ; WX 600 ; N eight ; B 124 -35 595 639 ;
+C 57 ; WX 600 ; N nine ; B 120 -35 606 639 ;
+C 58 ; WX 600 ; N colon ; B 261 10 425 392 ;
+C 59 ; WX 600 ; N semicolon ; B 123 -116 425 392 ;
+C 60 ; WX 600 ; N less ; B 112 12 656 550 ;
+C 61 ; WX 600 ; N equal ; B 75 168 644 394 ;
+C 62 ; WX 600 ; N greater ; B 63 12 608 550 ;
+C 63 ; WX 600 ; N question ; B 211 -5 597 598 ;
+C 64 ; WX 600 ; N at ; B 120 -82 580 644 ;
+C 65 ; WX 600 ; N A ; B -7 -20 615 583 ;
+C 66 ; WX 600 ; N B ; B 27 -20 610 583 ;
+C 67 ; WX 600 ; N C ; B 91 -35 655 598 ;
+C 68 ; WX 600 ; N D ; B 27 -20 610 583 ;
+C 69 ; WX 600 ; N E ; B 27 -20 634 583 ;
+C 70 ; WX 600 ; N F ; B 27 -20 655 583 ;
+C 71 ; WX 600 ; N G ; B 89 -35 655 598 ;
+C 72 ; WX 600 ; N H ; B 37 -20 665 583 ;
+C 73 ; WX 600 ; N I ; B 97 -20 622 583 ;
+C 74 ; WX 600 ; N J ; B 82 -35 718 583 ;
+C 75 ; WX 600 ; N K ; B 27 -20 686 583 ;
+C 76 ; WX 600 ; N L ; B 47 -20 605 583 ;
+C 77 ; WX 600 ; N M ; B -5 -20 718 583 ;
+C 78 ; WX 600 ; N N ; B 27 -20 697 583 ;
+C 79 ; WX 600 ; N O ; B 83 -35 636 598 ;
+C 80 ; WX 600 ; N P ; B 27 -20 606 583 ;
+C 81 ; WX 600 ; N Q ; B 84 -136 636 598 ;
+C 82 ; WX 600 ; N R ; B 27 -20 613 583 ;
+C 83 ; WX 600 ; N S ; B 76 -35 622 598 ;
+C 84 ; WX 600 ; N T ; B 129 -20 663 583 ;
+C 85 ; WX 600 ; N U ; B 119 -35 695 583 ;
+C 86 ; WX 600 ; N V ; B 104 -20 726 583 ;
+C 87 ; WX 600 ; N W ; B 103 -20 715 583 ;
+C 88 ; WX 600 ; N X ; B 24 -20 684 583 ;
+C 89 ; WX 600 ; N Y ; B 129 -20 684 583 ;
+C 90 ; WX 600 ; N Z ; B 87 -20 611 583 ;
+C 91 ; WX 600 ; N bracketleft ; B 238 -144 589 624 ;
+C 92 ; WX 600 ; N backslash ; B 230 -103 494 686 ;
+C 93 ; WX 600 ; N bracketright ; B 113 -144 464 624 ;
+C 94 ; WX 600 ; N asciicircum ; B 173 335 587 624 ;
+C 95 ; WX 600 ; N underscore ; B -85 -290 579 -210 ;
+C 96 ; WX 600 ; N quoteleft ; B 382 304 538 613 ;
+C 97 ; WX 600 ; N a ; B 74 -35 565 452 ;
+C 98 ; WX 600 ; N b ; B 6 -35 610 624 ;
+C 99 ; WX 600 ; N c ; B 104 -35 614 452 ;
+C 100 ; WX 600 ; N d ; B 83 -35 643 624 ;
+C 101 ; WX 600 ; N e ; B 85 -35 590 452 ;
+C 102 ; WX 600 ; N f ; B 89 -20 682 624 ; L i fi ; L l fl ;
+C 103 ; WX 600 ; N g ; B 85 -207 666 452 ;
+C 104 ; WX 600 ; N h ; B 37 -20 575 624 ;
+C 105 ; WX 600 ; N i ; B 76 -20 532 665 ;
+C 106 ; WX 600 ; N j ; B 92 -207 562 665 ;
+C 107 ; WX 600 ; N k ; B 47 -20 603 624 ;
+C 108 ; WX 600 ; N l ; B 76 -20 532 624 ;
+C 109 ; WX 600 ; N m ; B -5 -20 621 452 ;
+C 110 ; WX 600 ; N n ; B 37 -20 565 452 ;
+C 111 ; WX 600 ; N o ; B 91 -35 597 452 ;
+C 112 ; WX 600 ; N p ; B -33 -207 612 452 ;
+C 113 ; WX 600 ; N q ; B 85 -207 687 452 ;
+C 114 ; WX 600 ; N r ; B 68 -20 639 448 ;
+C 115 ; WX 600 ; N s ; B 87 -35 580 452 ;
+C 116 ; WX 600 ; N t ; B 107 -35 541 582 ;
+C 117 ; WX 600 ; N u ; B 107 -35 582 437 ;
+C 118 ; WX 600 ; N v ; B 94 -20 674 437 ;
+C 119 ; WX 600 ; N w ; B 94 -20 674 437 ;
+C 120 ; WX 600 ; N x ; B 35 -20 632 437 ;
+C 121 ; WX 600 ; N y ; B -4 -207 653 437 ;
+C 122 ; WX 600 ; N z ; B 99 -20 582 437 ;
+C 123 ; WX 600 ; N braceleft ; B 228 -144 547 624 ;
+C 124 ; WX 600 ; N bar ; B 238 -144 464 624 ;
+C 125 ; WX 600 ; N braceright ; B 155 -144 474 624 ;
+C 126 ; WX 600 ; N asciitilde ; B 127 189 592 373 ;
+C 161 ; WX 600 ; N exclamdown ; B 209 -207 430 415 ;
+C 162 ; WX 600 ; N cent ; B 156 -19 583 665 ;
+C 163 ; WX 600 ; N sterling ; B 68 -20 560 598 ;
+C 164 ; WX 600 ; N fraction ; B 65 120 665 492 ;
+C 165 ; WX 600 ; N yen ; B 137 -20 684 583 ;
+C 166 ; WX 600 ; N florin ; B 54 -113 663 639 ;
+C 167 ; WX 600 ; N section ; B 78 -87 637 629 ;
+C 168 ; WX 600 ; N currency ; B 107 75 617 509 ;
+C 169 ; WX 600 ; N quotesingle ; B 333 304 492 613 ;
+C 170 ; WX 600 ; N quotedblleft ; B 216 340 588 619 ;
+C 171 ; WX 600 ; N guillemotleft ; B 87 -20 645 437 ;
+C 172 ; WX 600 ; N guilsinglleft ; B 87 -20 416 437 ;
+C 173 ; WX 600 ; N guilsinglright ; B 277 -20 605 437 ;
+C 174 ; WX 600 ; N fi ; B -6 -20 628 665 ;
+C 175 ; WX 600 ; N fl ; B -6 -20 629 624 ;
+C 177 ; WX 600 ; N endash ; B 112 241 608 321 ;
+C 178 ; WX 600 ; N dagger ; B 188 -82 580 624 ;
+C 179 ; WX 600 ; N daggerdbl ; B 135 -82 580 624 ;
+C 180 ; WX 600 ; N periodcentered ; B 315 266 415 346 ;
+C 182 ; WX 600 ; N paragraph ; B 132 -87 670 629 ;
+C 183 ; WX 600 ; N bullet ; B 325 266 405 346 ;
+C 184 ; WX 600 ; N quotesinglbase ; B 108 -165 362 144 ;
+C 185 ; WX 600 ; N quotedblbase ; B 72 -139 528 139 ;
+C 186 ; WX 600 ; N quotedblright ; B 174 340 630 619 ;
+C 187 ; WX 600 ; N guillemotright ; B 47 -20 605 437 ;
+C 188 ; WX 600 ; N ellipsis ; B 67 -5 547 75 ;
+C 189 ; WX 600 ; N perthousand ; B 117 -35 619 639 ;
+C 191 ; WX 600 ; N questiondown ; B 85 -207 470 415 ;
+C 193 ; WX 600 ; N grave ; B 262 450 444 639 ;
+C 194 ; WX 600 ; N acute ; B 364 450 592 639 ;
+C 195 ; WX 600 ; N circumflex ; B 239 450 569 624 ;
+C 196 ; WX 600 ; N tilde ; B 231 441 586 580 ;
+C 197 ; WX 600 ; N macron ; B 245 476 575 556 ;
+C 198 ; WX 600 ; N breve ; B 258 450 589 624 ;
+C 199 ; WX 600 ; N dotaccent ; B 373 491 453 571 ;
+C 200 ; WX 600 ; N dieresis ; B 269 491 557 571 ;
+C 202 ; WX 600 ; N ring ; B 297 413 526 634 ;
+C 203 ; WX 600 ; N cedilla ; B 163 -186 376 40 ;
+C 205 ; WX 600 ; N hungarumlaut ; B 239 450 592 639 ;
+C 206 ; WX 600 ; N ogonek ; B 244 -165 430 40 ;
+C 207 ; WX 600 ; N caron ; B 259 450 589 624 ;
+C 208 ; WX 600 ; N emdash ; B 41 241 679 321 ;
+C 225 ; WX 600 ; N AE ; B -6 -20 705 583 ;
+C 227 ; WX 600 ; N ordfeminine ; B 174 179 529 598 ;
+C 232 ; WX 600 ; N Lslash ; B 47 -20 605 583 ;
+C 233 ; WX 600 ; N Oslash ; B 16 -61 704 623 ;
+C 234 ; WX 600 ; N OE ; B 42 -20 705 583 ;
+C 235 ; WX 600 ; N ordmasculine ; B 178 179 563 598 ;
+C 241 ; WX 600 ; N ae ; B 19 -35 651 452 ;
+C 245 ; WX 600 ; N dotlessi ; B 76 -20 532 437 ;
+C 248 ; WX 600 ; N lslash ; B 76 -20 544 624 ;
+C 249 ; WX 600 ; N oslash ; B 29 -61 656 478 ;
+C 250 ; WX 600 ; N oe ; B 28 -35 651 452 ;
+C 251 ; WX 600 ; N germandbls ; B 27 -35 558 624 ;
+C -1 ; WX 600 ; N Aacute ; B -7 -20 615 789 ;
+C -1 ; WX 600 ; N Acircumflex ; B -7 -20 615 774 ;
+C -1 ; WX 600 ; N Adieresis ; B -7 -20 615 721 ;
+C -1 ; WX 600 ; N Agrave ; B -7 -20 615 789 ;
+C -1 ; WX 600 ; N Aring ; B -7 -20 615 795 ;
+C -1 ; WX 600 ; N Atilde ; B -7 -20 615 730 ;
+C -1 ; WX 600 ; N Ccedilla ; B 91 -186 655 598 ;
+C -1 ; WX 600 ; N Eacute ; B 27 -20 634 789 ;
+C -1 ; WX 600 ; N Ecircumflex ; B 27 -20 634 774 ;
+C -1 ; WX 600 ; N Edieresis ; B 27 -20 634 721 ;
+C -1 ; WX 600 ; N Egrave ; B 27 -20 634 789 ;
+C -1 ; WX 600 ; N Eth ; B 27 -20 610 583 ;
+C -1 ; WX 600 ; N Gcaron ; B 89 -35 655 774 ;
+C -1 ; WX 600 ; N IJ ; B -6 -35 725 583 ;
+C -1 ; WX 600 ; N Iacute ; B 97 -20 622 789 ;
+C -1 ; WX 600 ; N Icircumflex ; B 97 -20 622 774 ;
+C -1 ; WX 600 ; N Idieresis ; B 97 -20 622 721 ;
+C -1 ; WX 600 ; N Idot ; B 97 -20 622 721 ;
+C -1 ; WX 600 ; N Igrave ; B 97 -20 622 789 ;
+C -1 ; WX 600 ; N LL ; B -16 -20 652 583 ;
+C -1 ; WX 600 ; N Ntilde ; B 27 -20 697 730 ;
+C -1 ; WX 600 ; N Oacute ; B 83 -35 636 789 ;
+C -1 ; WX 600 ; N Ocircumflex ; B 83 -35 636 774 ;
+C -1 ; WX 600 ; N Odieresis ; B 83 -35 636 721 ;
+C -1 ; WX 600 ; N Ograve ; B 83 -35 636 789 ;
+C -1 ; WX 600 ; N Otilde ; B 83 -35 636 730 ;
+C -1 ; WX 600 ; N Scaron ; B 76 -35 622 774 ;
+C -1 ; WX 600 ; N Scedilla ; B 76 -186 622 598 ;
+C -1 ; WX 600 ; N Thorn ; B 27 -20 603 583 ;
+C -1 ; WX 600 ; N Uacute ; B 119 -35 695 789 ;
+C -1 ; WX 600 ; N Ucircumflex ; B 119 -35 695 774 ;
+C -1 ; WX 600 ; N Udieresis ; B 119 -35 695 721 ;
+C -1 ; WX 600 ; N Ugrave ; B 119 -35 695 789 ;
+C -1 ; WX 600 ; N Yacute ; B 129 -20 684 789 ;
+C -1 ; WX 600 ; N Ydieresis ; B 129 -20 684 721 ;
+C -1 ; WX 600 ; N Zcaron ; B 87 -20 621 774 ;
+C -1 ; WX 600 ; N aacute ; B 74 -35 565 660 ;
+C -1 ; WX 600 ; N acircumflex ; B 74 -35 575 653 ;
+C -1 ; WX 600 ; N adieresis ; B 74 -35 565 592 ;
+C -1 ; WX 600 ; N agrave ; B 74 -35 565 660 ;
+C -1 ; WX 600 ; N aring ; B 74 -35 565 686 ;
+C -1 ; WX 600 ; N arrowboth ; B 24 110 704 490 ;
+C -1 ; WX 600 ; N arrowdown ; B 146 -20 526 639 ;
+C -1 ; WX 600 ; N arrowleft ; B 24 110 704 490 ;
+C -1 ; WX 600 ; N arrowright ; B 24 110 704 490 ;
+C -1 ; WX 600 ; N arrowup ; B 205 -20 585 639 ;
+C -1 ; WX 600 ; N atilde ; B 74 -35 594 618 ;
+C -1 ; WX 600 ; N brokenbar ; B 238 -144 464 624 ;
+C -1 ; WX 600 ; N ccedilla ; B 104 -186 614 452 ;
+C -1 ; WX 600 ; N center ; B 62 -20 662 624 ;
+C -1 ; WX 600 ; N copyright ; B 33 -35 683 598 ;
+C -1 ; WX 600 ; N dectab ; B -1 -20 609 248 ;
+C -1 ; WX 600 ; N degree ; B 231 294 564 624 ;
+C -1 ; WX 600 ; N divide ; B 112 51 608 531 ;
+C -1 ; WX 600 ; N down ; B 181 -20 473 452 ;
+C -1 ; WX 600 ; N eacute ; B 85 -35 590 664 ;
+C -1 ; WX 600 ; N ecircumflex ; B 85 -35 590 653 ;
+C -1 ; WX 600 ; N edieresis ; B 85 -35 590 592 ;
+C -1 ; WX 600 ; N egrave ; B 85 -35 590 664 ;
+C -1 ; WX 600 ; N eth ; B 87 -35 637 639 ;
+C -1 ; WX 600 ; N format ; B -50 -207 189 624 ;
+C -1 ; WX 600 ; N gcaron ; B 85 -207 666 645 ;
+C -1 ; WX 600 ; N graybox ; B 35 -40 693 640 ;
+C -1 ; WX 600 ; N iacute ; B 76 -20 532 660 ;
+C -1 ; WX 600 ; N icircumflex ; B 76 -20 532 634 ;
+C -1 ; WX 600 ; N idieresis ; B 76 -20 532 592 ;
+C -1 ; WX 600 ; N igrave ; B 76 -20 532 656 ;
+C -1 ; WX 600 ; N ij ; B 14 -207 634 665 ;
+C -1 ; WX 600 ; N indent ; B 98 60 590 352 ;
+C -1 ; WX 600 ; N largebullet ; B 325 266 405 346 ;
+C -1 ; WX 600 ; N left ; B 98 60 590 352 ;
+C -1 ; WX 600 ; N lira ; B 68 -20 560 598 ;
+C -1 ; WX 600 ; N ll ; B 4 -20 624 624 ;
+C -1 ; WX 600 ; N logicalnot ; B 127 154 623 394 ;
+C -1 ; WX 600 ; N merge ; B 181 -20 511 452 ;
+C -1 ; WX 600 ; N minus ; B 112 241 608 321 ;
+C -1 ; WX 600 ; N mu ; B 71 -207 582 437 ;
+C -1 ; WX 600 ; N multiply ; B 93 12 609 470 ;
+C -1 ; WX 600 ; N notegraphic ; B 167 -5 573 639 ;
+C -1 ; WX 600 ; N ntilde ; B 37 -20 569 618 ;
+C -1 ; WX 600 ; N oacute ; B 91 -35 597 649 ;
+C -1 ; WX 600 ; N ocircumflex ; B 91 -35 597 653 ;
+C -1 ; WX 600 ; N odieresis ; B 91 -35 597 592 ;
+C -1 ; WX 600 ; N ograve ; B 91 -35 597 649 ;
+C -1 ; WX 600 ; N onehalf ; B 46 -20 665 624 ;
+C -1 ; WX 600 ; N onequarter ; B 46 -20 681 624 ;
+C -1 ; WX 600 ; N onesuperior ; B 211 200 491 624 ;
+C -1 ; WX 600 ; N otilde ; B 91 -35 597 597 ;
+C -1 ; WX 600 ; N overscore ; B 95 559 759 639 ;
+C -1 ; WX 600 ; N plusminus ; B 56 -20 617 550 ;
+C -1 ; WX 600 ; N prescription ; B 27 -20 613 583 ;
+C -1 ; WX 600 ; N registered ; B 33 -35 683 598 ;
+C -1 ; WX 600 ; N return ; B 36 -20 745 608 ;
+C -1 ; WX 600 ; N scaron ; B 87 -35 593 645 ;
+C -1 ; WX 600 ; N scedilla ; B 87 -186 580 452 ;
+C -1 ; WX 600 ; N square ; B -20 -20 745 608 ;
+C -1 ; WX 600 ; N stop ; B -20 -20 745 608 ;
+C -1 ; WX 600 ; N tab ; B -20 -20 684 608 ;
+C -1 ; WX 600 ; N thorn ; B -33 -207 612 624 ;
+C -1 ; WX 600 ; N threequarters ; B 57 -20 651 639 ;
+C -1 ; WX 600 ; N threesuperior ; B 215 191 552 639 ;
+C -1 ; WX 600 ; N trademark ; B 78 230 735 583 ;
+C -1 ; WX 600 ; N twosuperior ; B 191 200 541 639 ;
+C -1 ; WX 600 ; N uacute ; B 107 -35 582 656 ;
+C -1 ; WX 600 ; N ucircumflex ; B 107 -35 582 634 ;
+C -1 ; WX 600 ; N udieresis ; B 107 -35 582 592 ;
+C -1 ; WX 600 ; N ugrave ; B 107 -35 582 656 ;
+C -1 ; WX 600 ; N up ; B 219 -20 511 452 ;
+C -1 ; WX 600 ; N yacute ; B -4 -207 653 656 ;
+C -1 ; WX 600 ; N ydieresis ; B -4 -207 653 571 ;
+C -1 ; WX 600 ; N zcaron ; B 99 -20 593 645 ;
+EndCharMetrics
+StartComposites 58
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 0 146 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 0 0 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 0 146 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 0 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 0 0 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 0 146 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 0 0 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 0 146 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 0 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 0 146 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 0 146 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 0 146 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 0 146 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 0 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 0 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 0 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 0 0 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 146 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 0 146 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 0 146 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 146 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex 0 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis 0 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 0 146 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 0 146 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 0 146 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 0 146 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ;
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 0 146 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 0 146 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 0 146 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 0 146 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 0 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 0 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 0 0 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 0 146 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 0 146 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 0 146 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 0 146 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 0 146 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 0 146 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 0 146 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 0 146 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ;
+EndComposites
+EndFontMetrics
diff --git a/misc/afm/Helv.afm b/misc/afm/Helv.afm
new file mode 100644
index 0000000000..b17a3909d4
--- /dev/null
+++ b/misc/afm/Helv.afm
@@ -0,0 +1,435 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1984 Adobe Systems Incorporated. 	All Rights Reserved.
+Comment Creation Date:Tue Aug 5 11:33:55 PDT 1986
+FontName Helvetica
+EncodingScheme AdobeStandardEncoding
+FullName Helvetica
+FamilyName Helvetica
+Weight Medium
+ItalicAngle 0.0
+IsFixedPitch false
+UnderlinePosition -97
+UnderlineThickness 73
+Version 001.001
+Notice Helvetica is a registered trademark of Allied Corporation.
+FontBBox -174 -220 1001 944
+CapHeight 729
+XHeight 525
+Descender -219
+Ascender 729
+StartCharMetrics 228
+C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 278 ; N exclam ; B 124 0 208 729 ;
+C 34 ; WX 355 ; N quotedbl ; B 52 462 305 708 ;
+C 35 ; WX 556 ; N numbersign ; B 14 -20 542 698 ;
+C 36 ; WX 556 ; N dollar ; B 33 -125 518 770 ;
+C 37 ; WX 889 ; N percent ; B 29 -20 859 708 ;
+C 38 ; WX 667 ; N ampersand ; B 52 -23 637 710 ;
+C 39 ; WX 222 ; N quoteright ; B 64 476 158 708 ;
+C 40 ; WX 333 ; N parenleft ; B 73 -213 291 729 ;
+C 41 ; WX 333 ; N parenright ; B 38 -213 256 729 ;
+C 42 ; WX 389 ; N asterisk ; B 40 452 343 740 ;
+C 43 ; WX 584 ; N plus ; B 50 -10 534 474 ;
+C 44 ; WX 278 ; N comma ; B 87 -150 192 104 ;
+C 45 ; WX 333 ; N hyphen ; B 46 240 284 313 ;
+C 46 ; WX 278 ; N period ; B 87 0 191 104 ;
+C 47 ; WX 278 ; N slash ; B -8 -21 284 708 ;
+C 48 ; WX 556 ; N zero ; B 43 -23 507 709 ;
+C 49 ; WX 556 ; N one ; B 102 0 347 709 ;
+C 50 ; WX 556 ; N two ; B 34 0 511 710 ;
+C 51 ; WX 556 ; N three ; B 32 -23 506 709 ;
+C 52 ; WX 556 ; N four ; B 28 0 520 709 ;
+C 53 ; WX 556 ; N five ; B 35 -23 513 709 ;
+C 54 ; WX 556 ; N six ; B 43 -23 513 709 ;
+C 55 ; WX 556 ; N seven ; B 46 0 520 709 ;
+C 56 ; WX 556 ; N eight ; B 37 -23 513 709 ;
+C 57 ; WX 556 ; N nine ; B 38 -23 509 709 ;
+C 58 ; WX 278 ; N colon ; B 110 0 214 525 ;
+C 59 ; WX 278 ; N semicolon ; B 110 -150 215 516 ;
+C 60 ; WX 584 ; N less ; B 45 -10 534 474 ;
+C 61 ; WX 584 ; N equal ; B 50 112 534 352 ;
+C 62 ; WX 584 ; N greater ; B 50 -10 539 474 ;
+C 63 ; WX 556 ; N question ; B 77 0 509 738 ;
+C 64 ; WX 1015 ; N at ; B 34 -146 951 737 ;
+C 65 ; WX 667 ; N A ; B 17 0 653 729 ;
+C 66 ; WX 667 ; N B ; B 79 0 623 729 ;
+C 67 ; WX 722 ; N C ; B 48 -23 677 741 ;
+C 68 ; WX 722 ; N D ; B 89 0 667 729 ;
+C 69 ; WX 667 ; N E ; B 90 0 613 729 ;
+C 70 ; WX 611 ; N F ; B 90 0 579 729 ;
+C 71 ; WX 778 ; N G ; B 44 -23 709 741 ;
+C 72 ; WX 722 ; N H ; B 83 0 644 729 ;
+C 73 ; WX 278 ; N I ; B 100 0 194 729 ;
+C 74 ; WX 500 ; N J ; B 17 -26 426 729 ;
+C 75 ; WX 667 ; N K ; B 79 0 658 729 ;
+C 76 ; WX 556 ; N L ; B 80 0 533 729 ;
+C 77 ; WX 833 ; N M ; B 75 0 761 729 ;
+C 78 ; WX 722 ; N N ; B 76 0 646 729 ;
+C 79 ; WX 778 ; N O ; B 38 -23 742 741 ;
+C 80 ; WX 667 ; N P ; B 91 0 617 730 ;
+C 81 ; WX 778 ; N Q ; B 38 -59 742 741 ;
+C 82 ; WX 722 ; N R ; B 93 0 679 729 ;
+C 83 ; WX 667 ; N S ; B 48 -23 621 741 ;
+C 84 ; WX 611 ; N T ; B 21 0 593 729 ;
+C 85 ; WX 722 ; N U ; B 85 -23 645 729 ;
+C 86 ; WX 667 ; N V ; B 30 0 645 729 ;
+C 87 ; WX 944 ; N W ; B 22 0 929 729 ;
+C 88 ; WX 667 ; N X ; B 22 0 649 729 ;
+C 89 ; WX 667 ; N Y ; B 13 0 661 729 ;
+C 90 ; WX 611 ; N Z ; B 28 0 583 729 ;
+C 91 ; WX 278 ; N bracketleft ; B 64 -214 250 729 ;
+C 92 ; WX 278 ; N backslash ; B -8 -20 284 729 ;
+C 93 ; WX 278 ; N bracketright ; B 23 -215 209 729 ;
+C 94 ; WX 469 ; N asciicircum ; B 44 333 425 713 ;
+C 95 ; WX 556 ; N underscore ; B -22 -175 578 -125 ;
+C 96 ; WX 222 ; N quoteleft ; B 65 459 158 708 ;
+C 97 ; WX 556 ; N a ; B 42 -23 535 540 ;
+C 98 ; WX 556 ; N b ; B 54 -23 523 729 ;
+C 99 ; WX 500 ; N c ; B 31 -23 477 540 ;
+C 100 ; WX 556 ; N d ; B 26 -23 495 729 ;
+C 101 ; WX 556 ; N e ; B 40 -23 513 541 ;
+C 102 ; WX 278 ; N f ; B 18 0 258 733 ; L i fi ; L l fl ;
+C 103 ; WX 556 ; N g ; B 29 -220 489 540 ;
+C 104 ; WX 556 ; N h ; B 70 0 486 729 ;
+C 105 ; WX 222 ; N i ; B 66 0 150 729 ;
+C 106 ; WX 222 ; N j ; B -18 -220 153 729 ;
+C 107 ; WX 500 ; N k ; B 58 0 502 729 ;
+C 108 ; WX 222 ; N l ; B 68 0 152 729 ;
+C 109 ; WX 833 ; N m ; B 71 0 763 540 ;
+C 110 ; WX 556 ; N n ; B 70 0 487 540 ;
+C 111 ; WX 556 ; N o ; B 36 -23 510 540 ;
+C 112 ; WX 556 ; N p ; B 54 -219 523 540 ;
+C 113 ; WX 556 ; N q ; B 26 -219 495 540 ;
+C 114 ; WX 333 ; N r ; B 69 0 321 540 ;
+C 115 ; WX 500 ; N s ; B 34 -24 459 540 ;
+C 116 ; WX 278 ; N t ; B 14 -24 254 667 ;
+C 117 ; WX 556 ; N u ; B 65 -23 482 525 ;
+C 118 ; WX 500 ; N v ; B 10 0 486 525 ;
+C 119 ; WX 722 ; N w ; B 6 0 708 525 ;
+C 120 ; WX 500 ; N x ; B 17 0 473 525 ;
+C 121 ; WX 500 ; N y ; B 20 -219 478 525 ;
+C 122 ; WX 500 ; N z ; B 31 0 457 525 ;
+C 123 ; WX 334 ; N braceleft ; B 43 -214 276 731 ;
+C 124 ; WX 260 ; N bar ; B 100 -215 160 729 ;
+C 125 ; WX 334 ; N braceright ; B 29 -214 262 731 ;
+C 126 ; WX 584 ; N asciitilde ; B 75 267 508 438 ;
+C 161 ; WX 333 ; N exclamdown ; B 121 -214 205 525 ;
+C 162 ; WX 556 ; N cent ; B 52 -120 510 628 ;
+C 163 ; WX 556 ; N sterling ; B 26 -21 535 726 ;
+C 164 ; WX 167 ; N fraction ; B -174 -21 336 708 ;
+C 165 ; WX 556 ; N yen ; B 11 0 545 710 ;
+C 166 ; WX 556 ; N florin ; B 11 -214 542 742 ;
+C 167 ; WX 556 ; N section ; B 44 -215 506 729 ;
+C 168 ; WX 556 ; N currency ; B 67 126 489 554 ;
+C 169 ; WX 191 ; N quotesingle ; B 48 462 142 708 ;
+C 170 ; WX 333 ; N quotedblleft ; B 48 459 299 708 ;
+C 171 ; WX 556 ; N guillemotleft ; B 98 106 455 438 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 91 112 243 436 ;
+C 173 ; WX 333 ; N guilsinglright ; B 85 112 239 436 ;
+C 174 ; WX 500 ; N fi ; B 12 0 436 733 ;
+C 175 ; WX 500 ; N fl ; B 17 0 430 733 ;
+C 177 ; WX 556 ; N endash ; B -5 240 561 313 ;
+C 178 ; WX 556 ; N dagger ; B 38 -178 513 710 ;
+C 179 ; WX 556 ; N daggerdbl ; B 38 -178 513 710 ;
+C 180 ; WX 278 ; N periodcentered ; B 87 318 211 442 ;
+C 182 ; WX 537 ; N paragraph ; B 48 -178 522 729 ;
+C 183 ; WX 350 ; N bullet ; B 50 220 300 470 ;
+C 184 ; WX 222 ; N quotesinglbase ; B 64 -129 158 103 ;
+C 185 ; WX 333 ; N quotedblbase ; B 47 -129 300 103 ;
+C 186 ; WX 333 ; N quotedblright ; B 49 476 302 708 ;
+C 187 ; WX 556 ; N guillemotright ; B 98 106 451 438 ;
+C 188 ; WX 1000 ; N ellipsis ; B 115 0 885 104 ;
+C 189 ; WX 1000 ; N perthousand ; B 9 -20 993 740 ;
+C 191 ; WX 611 ; N questiondown ; B 95 -213 528 525 ;
+C 193 ; WX 333 ; N grave ; B 22 592 231 740 ;
+C 194 ; WX 333 ; N acute ; B 92 592 301 740 ;
+C 195 ; WX 333 ; N circumflex ; B 20 591 307 741 ;
+C 196 ; WX 333 ; N tilde ; B 5 589 319 716 ;
+C 197 ; WX 333 ; N macron ; B 28 621 302 694 ;
+C 198 ; WX 333 ; N breve ; B 15 594 316 729 ;
+C 199 ; WX 333 ; N dotaccent ; B 115 605 219 709 ;
+C 200 ; WX 333 ; N dieresis ; B 30 605 296 708 ;
+C 202 ; WX 333 ; N ring ; B 79 566 255 741 ;
+C 203 ; WX 333 ; N cedilla ; B 39 -214 287 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B -35 592 348 740 ;
+C 206 ; WX 333 ; N ogonek ; B 57 -189 265 15 ;
+C 207 ; WX 333 ; N caron ; B 19 590 306 740 ;
+C 208 ; WX 1000 ; N emdash ; B -9 240 1001 313 ;
+C 225 ; WX 1000 ; N AE ; B 11 0 950 729 ;
+C 227 ; WX 370 ; N ordfeminine ; B 37 301 333 740 ;
+C 232 ; WX 556 ; N Lslash ; B 0 0 552 729 ;
+C 233 ; WX 778 ; N Oslash ; B 30 -23 744 742 ;
+C 234 ; WX 1000 ; N OE ; B 43 -20 959 739 ;
+C 235 ; WX 365 ; N ordmasculine ; B 40 301 324 741 ;
+C 241 ; WX 889 ; N ae ; B 34 -20 845 546 ;
+C 245 ; WX 278 ; N dotlessi ; B 94 0 178 525 ;
+C 248 ; WX 222 ; N lslash ; B 0 0 212 729 ;
+C 249 ; WX 611 ; N oslash ; B 18 -27 529 548 ;
+C 250 ; WX 944 ; N oe ; B 40 -22 899 540 ;
+C 251 ; WX 611 ; N germandbls ; B 126 -20 566 729 ;
+C -1 ; WX 667 ; N Aacute ; B 17 0 653 939 ;
+C -1 ; WX 667 ; N Acircumflex ; B 17 0 653 940 ;
+C -1 ; WX 667 ; N Adieresis ; B 17 0 653 907 ;
+C -1 ; WX 667 ; N Agrave ; B 17 0 653 939 ;
+C -1 ; WX 667 ; N Aring ; B 17 0 653 940 ;
+C -1 ; WX 667 ; N Atilde ; B 17 0 653 915 ;
+C -1 ; WX 722 ; N Ccedilla ; B 48 -214 677 741 ;
+C -1 ; WX 667 ; N Eacute ; B 90 0 613 939 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 90 0 613 940 ;
+C -1 ; WX 667 ; N Edieresis ; B 90 0 613 907 ;
+C -1 ; WX 667 ; N Egrave ; B 90 0 613 939 ;
+C -1 ; WX 722 ; N Eth ; B 0 0 667 729 ;
+C -1 ; WX 278 ; N Iacute ; B 71 0 280 939 ;
+C -1 ; WX 278 ; N Icircumflex ; B -1 0 286 940 ;
+C -1 ; WX 278 ; N Idieresis ; B 9 0 275 907 ;
+C -1 ; WX 278 ; N Igrave ; B 1 0 210 939 ;
+C -1 ; WX 722 ; N Ntilde ; B 76 0 646 915 ;
+C -1 ; WX 778 ; N Oacute ; B 38 -23 742 939 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 38 -23 742 940 ;
+C -1 ; WX 778 ; N Odieresis ; B 38 -23 742 907 ;
+C -1 ; WX 778 ; N Ograve ; B 38 -23 742 939 ;
+C -1 ; WX 778 ; N Otilde ; B 38 -23 742 915 ;
+C -1 ; WX 667 ; N Scaron ; B 48 -23 621 939 ;
+C -1 ; WX 667 ; N Thorn ; B 91 0 617 729 ;
+C -1 ; WX 722 ; N Uacute ; B 85 -23 645 939 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 85 -23 645 940 ;
+C -1 ; WX 722 ; N Udieresis ; B 85 -23 645 907 ;
+C -1 ; WX 722 ; N Ugrave ; B 85 -23 645 939 ;
+C -1 ; WX 667 ; N Yacute ; B 13 0 661 944 ;
+C -1 ; WX 667 ; N Ydieresis ; B 13 0 661 907 ;
+C -1 ; WX 611 ; N Zcaron ; B 28 0 583 939 ;
+C -1 ; WX 556 ; N aacute ; B 42 -23 535 740 ;
+C -1 ; WX 556 ; N acircumflex ; B 42 -23 535 741 ;
+C -1 ; WX 556 ; N adieresis ; B 42 -23 535 708 ;
+C -1 ; WX 556 ; N agrave ; B 42 -23 535 740 ;
+C -1 ; WX 556 ; N aring ; B 42 -23 535 741 ;
+C -1 ; WX 556 ; N atilde ; B 42 -23 535 716 ;
+C -1 ; WX 260 ; N brokenbar ; B 100 -215 160 729 ;
+C -1 ; WX 500 ; N ccedilla ; B 31 -214 477 540 ;
+C -1 ; WX 737 ; N copyright ; B -13 -23 751 741 ;
+C -1 ; WX 400 ; N degree ; B 50 409 350 709 ;
+C -1 ; WX 584 ; N divide ; B 50 -10 534 474 ;
+C -1 ; WX 556 ; N eacute ; B 40 -23 513 740 ;
+C -1 ; WX 556 ; N ecircumflex ; B 40 -23 513 741 ;
+C -1 ; WX 556 ; N edieresis ; B 40 -23 513 708 ;
+C -1 ; WX 556 ; N egrave ; B 40 -23 513 740 ;
+C -1 ; WX 556 ; N eth ; B 36 -23 510 729 ;
+C -1 ; WX 278 ; N iacute ; B 65 0 274 740 ;
+C -1 ; WX 278 ; N icircumflex ; B -7 0 280 741 ;
+C -1 ; WX 278 ; N idieresis ; B 3 0 269 708 ;
+C -1 ; WX 278 ; N igrave ; B -5 0 204 740 ;
+C -1 ; WX 584 ; N logicalnot ; B 40 82 544 352 ;
+C -1 ; WX 584 ; N minus ; B 40 194 544 270 ;
+C -1 ; WX 556 ; N mu ; B 65 -219 482 525 ;
+C -1 ; WX 584 ; N multiply ; B 50 -10 534 476 ;
+C -1 ; WX 556 ; N ntilde ; B 70 0 487 716 ;
+C -1 ; WX 556 ; N oacute ; B 36 -23 510 740 ;
+C -1 ; WX 556 ; N ocircumflex ; B 36 -23 510 741 ;
+C -1 ; WX 556 ; N odieresis ; B 36 -23 510 708 ;
+C -1 ; WX 556 ; N ograve ; B 36 -23 510 740 ;
+C -1 ; WX 834 ; N onehalf ; B 30 -21 804 709 ;
+C -1 ; WX 834 ; N onequarter ; B 30 -21 804 709 ;
+C -1 ; WX 333 ; N onesuperior ; B 60 284 219 709 ;
+C -1 ; WX 556 ; N otilde ; B 36 -23 510 716 ;
+C -1 ; WX 584 ; N plusminus ; B 40 0 544 618 ;
+C -1 ; WX 737 ; N registered ; B -13 -23 751 741 ;
+C -1 ; WX 500 ; N scaron ; B 34 -24 459 740 ;
+C -1 ; WX 556 ; N thorn ; B 54 -219 523 729 ;
+C -1 ; WX 834 ; N threequarters ; B 30 -21 804 709 ;
+C -1 ; WX 333 ; N threesuperior ; B 12 270 320 709 ;
+C -1 ; WX 1000 ; N trademark ; B 63 320 938 741 ;
+C -1 ; WX 333 ; N twosuperior ; B 11 284 321 710 ;
+C -1 ; WX 556 ; N uacute ; B 65 -23 482 740 ;
+C -1 ; WX 556 ; N ucircumflex ; B 65 -23 482 741 ;
+C -1 ; WX 556 ; N udieresis ; B 65 -23 482 708 ;
+C -1 ; WX 556 ; N ugrave ; B 65 -23 482 740 ;
+C -1 ; WX 500 ; N yacute ; B 20 -219 478 740 ;
+C -1 ; WX 500 ; N ydieresis ; B 20 -219 478 708 ;
+C -1 ; WX 500 ; N zcaron ; B 31 0 457 740 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 105
+
+KPX A y -18
+KPX A w -18
+KPX A v -18
+KPX A space -55
+KPX A quoteright -74
+KPX A Y -74
+KPX A W -37
+KPX A V -74
+KPX A T -74
+
+KPX F period -111
+KPX F comma -111
+KPX F A -55
+
+KPX L y -37
+KPX L space -37
+KPX L quoteright -55
+KPX L Y -74
+KPX L W -74
+KPX L V -74
+KPX L T -74
+
+KPX P space -18
+KPX P period -129
+KPX P comma -129
+KPX P A -74
+
+KPX R Y -18
+KPX R W -18
+KPX R V -18
+KPX R T -18
+
+KPX T y -55
+KPX T w -55
+KPX T u -37
+KPX T space -18
+KPX T semicolon -111
+KPX T s -111
+KPX T r -37
+KPX T period -111
+KPX T o -111
+KPX T i -37
+KPX T hyphen -55
+KPX T e -111
+KPX T comma -111
+KPX T colon -111
+KPX T c -111
+KPX T a -111
+KPX T O -18
+KPX T A -74
+
+KPX V y -37
+KPX V u -37
+KPX V semicolon -37
+KPX V r -37
+KPX V period -92
+KPX V o -55
+KPX V i -18
+KPX V hyphen -55
+KPX V e -55
+KPX V comma -92
+KPX V colon -37
+KPX V a -74
+KPX V A -74
+
+KPX W y -9
+KPX W u -18
+KPX W semicolon -18
+KPX W r -18
+KPX W period -55
+KPX W o -18
+KPX W i 0
+KPX W hyphen -18
+KPX W e -18
+KPX W comma -55
+KPX W colon -18
+KPX W a -37
+KPX W A -37
+
+KPX Y v -55
+KPX Y u -55
+KPX Y space -18
+KPX Y semicolon -65
+KPX Y q -92
+KPX Y period -129
+KPX Y p -74
+KPX Y o -92
+KPX Y i -37
+KPX Y hyphen -92
+KPX Y e -92
+KPX Y comma -129
+KPX Y colon -55
+KPX Y a -74
+KPX Y A -74
+
+KPX f quoteright 18
+KPX f f -18
+
+KPX one one -74
+
+KPX quoteleft quoteleft -18
+
+KPX quoteright space -37
+KPX quoteright s -18
+KPX quoteright quoteright -18
+
+KPX r quoteright 37
+KPX r period -55
+KPX r comma -55
+
+KPX space Y -18
+KPX space T -18
+KPX space A -55
+
+KPX v period -74
+KPX v comma -74
+
+KPX w period -55
+KPX w comma -55
+
+KPX y period -74
+KPX y comma -74
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 199 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 83 0 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 167 199 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 83 0 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 207 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 96 0 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 167 199 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 83 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 194 199 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 194 199 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 194 199 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 194 199 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 111 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 111 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 111 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 111 0 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute -21 199 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -21 199 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -21 199 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave -21 199 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 188 199 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 188 199 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 188 199 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 188 199 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 117 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 117 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 117 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 117 0 ;
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 167 199 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 167 199 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 167 199 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 167 199 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 111 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 111 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 111 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 111 0 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 222 199 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 222 199 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 222 199 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 222 199 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 111 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 111 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 111 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 111 0 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 167 199 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 111 0 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 200 199 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 117 0 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 222 199 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 111 0 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 167 199 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 111 0 ;
+EndComposites
+EndFontMetrics
diff --git a/misc/afm/HelvBo.afm b/misc/afm/HelvBo.afm
new file mode 100644
index 0000000000..5f14f52069
--- /dev/null
+++ b/misc/afm/HelvBo.afm
@@ -0,0 +1,431 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1984 Adobe Systems Incorporated. 	All Rights Reserved.
+Comment Creation Date:Tue Aug 5 11:40:08 PDT 1986
+FontName Helvetica-Bold
+EncodingScheme AdobeStandardEncoding
+FullName Helvetica Bold
+FamilyName Helvetica
+Weight Bold
+ItalicAngle 0.0
+IsFixedPitch false
+UnderlinePosition -106
+UnderlineThickness 73
+Version 001.001
+Notice Helvetica is a registered trademark of Allied Corporation.
+FontBBox -173 -221 1003 936
+CapHeight 729
+XHeight 542
+Descender -219
+Ascender 729
+StartCharMetrics 228
+C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 112 0 262 729 ;
+C 34 ; WX 474 ; N quotedbl ; B 50 470 424 729 ;
+C 35 ; WX 556 ; N numbersign ; B 3 -30 553 696 ;
+C 36 ; WX 556 ; N dollar ; B 22 -125 526 765 ;
+C 37 ; WX 889 ; N percent ; B 22 -18 863 708 ;
+C 38 ; WX 722 ; N ampersand ; B 55 -20 694 729 ;
+C 39 ; WX 278 ; N quoteright ; B 66 469 201 729 ;
+C 40 ; WX 333 ; N parenleft ; B 40 -202 303 729 ;
+C 41 ; WX 333 ; N parenright ; B 22 -202 285 729 ;
+C 42 ; WX 389 ; N asterisk ; B 23 385 356 730 ;
+C 43 ; WX 584 ; N plus ; B 50 -10 534 474 ;
+C 44 ; WX 278 ; N comma ; B 64 -174 214 146 ;
+C 45 ; WX 333 ; N hyphen ; B 26 208 298 344 ;
+C 46 ; WX 278 ; N period ; B 64 0 214 146 ;
+C 47 ; WX 278 ; N slash ; B 2 -14 275 715 ;
+C 48 ; WX 556 ; N zero ; B 29 -23 517 725 ;
+C 49 ; WX 556 ; N one ; B 68 0 378 709 ;
+C 50 ; WX 556 ; N two ; B 30 0 515 726 ;
+C 51 ; WX 556 ; N three ; B 29 -23 516 726 ;
+C 52 ; WX 556 ; N four ; B 24 0 522 709 ;
+C 53 ; WX 556 ; N five ; B 27 -24 517 709 ;
+C 54 ; WX 556 ; N six ; B 32 -23 519 727 ;
+C 55 ; WX 556 ; N seven ; B 29 0 528 709 ;
+C 56 ; WX 556 ; N eight ; B 22 -23 525 726 ;
+C 57 ; WX 556 ; N nine ; B 28 -23 516 728 ;
+C 58 ; WX 333 ; N colon ; B 113 0 263 521 ;
+C 59 ; WX 333 ; N semicolon ; B 113 -174 263 521 ;
+C 60 ; WX 584 ; N less ; B 40 -10 529 474 ;
+C 61 ; WX 584 ; N equal ; B 50 52 534 412 ;
+C 62 ; WX 584 ; N greater ; B 40 -10 529 474 ;
+C 63 ; WX 611 ; N question ; B 64 0 556 744 ;
+C 64 ; WX 975 ; N at ; B 27 -136 947 746 ;
+C 65 ; WX 722 ; N A ; B 26 0 703 729 ;
+C 66 ; WX 722 ; N B ; B 82 0 666 729 ;
+C 67 ; WX 722 ; N C ; B 44 -23 685 741 ;
+C 68 ; WX 722 ; N D ; B 77 0 681 729 ;
+C 69 ; WX 667 ; N E ; B 79 0 624 729 ;
+C 70 ; WX 611 ; N F ; B 74 0 586 729 ;
+C 71 ; WX 778 ; N G ; B 42 -24 711 741 ;
+C 72 ; WX 722 ; N H ; B 68 0 657 729 ;
+C 73 ; WX 278 ; N I ; B 63 0 213 729 ;
+C 74 ; WX 556 ; N J ; B 24 -23 486 729 ;
+C 75 ; WX 722 ; N K ; B 74 0 717 729 ;
+C 76 ; WX 611 ; N L ; B 80 0 579 729 ;
+C 77 ; WX 833 ; N M ; B 66 0 776 729 ;
+C 78 ; WX 722 ; N N ; B 68 0 661 729 ;
+C 79 ; WX 778 ; N O ; B 40 -23 742 741 ;
+C 80 ; WX 667 ; N P ; B 76 0 633 729 ;
+C 81 ; WX 778 ; N Q ; B 43 -54 745 741 ;
+C 82 ; WX 722 ; N R ; B 80 0 677 729 ;
+C 83 ; WX 667 ; N S ; B 32 -23 633 741 ;
+C 84 ; WX 611 ; N T ; B 14 0 598 729 ;
+C 85 ; WX 722 ; N U ; B 76 -23 654 729 ;
+C 86 ; WX 667 ; N V ; B 24 0 647 729 ;
+C 87 ; WX 944 ; N W ; B 13 0 932 729 ;
+C 88 ; WX 667 ; N X ; B 22 0 653 729 ;
+C 89 ; WX 667 ; N Y ; B 27 0 650 729 ;
+C 90 ; WX 611 ; N Z ; B 30 0 578 729 ;
+C 91 ; WX 333 ; N bracketleft ; B 66 -202 308 729 ;
+C 92 ; WX 278 ; N backslash ; B -12 -21 289 708 ;
+C 93 ; WX 333 ; N bracketright ; B 18 -202 260 729 ;
+C 94 ; WX 584 ; N asciicircum ; B 61 271 522 696 ;
+C 95 ; WX 556 ; N underscore ; B -22 -200 578 -130 ;
+C 96 ; WX 278 ; N quoteleft ; B 67 469 202 729 ;
+C 97 ; WX 556 ; N a ; B 27 -24 524 551 ;
+C 98 ; WX 611 ; N b ; B 59 -23 575 729 ;
+C 99 ; WX 556 ; N c ; B 34 -23 522 551 ;
+C 100 ; WX 611 ; N d ; B 29 -23 545 729 ;
+C 101 ; WX 556 ; N e ; B 22 -23 525 551 ;
+C 102 ; WX 333 ; N f ; B 14 0 313 729 ; L i fi ; L l fl ;
+C 103 ; WX 611 ; N g ; B 34 -220 541 551 ;
+C 104 ; WX 611 ; N h ; B 67 0 541 729 ;
+C 105 ; WX 278 ; N i ; B 67 0 207 729 ;
+C 106 ; WX 278 ; N j ; B 4 -219 210 729 ;
+C 107 ; WX 556 ; N k ; B 59 0 548 729 ;
+C 108 ; WX 278 ; N l ; B 67 0 207 729 ;
+C 109 ; WX 889 ; N m ; B 60 0 824 553 ;
+C 110 ; WX 611 ; N n ; B 63 0 546 551 ;
+C 111 ; WX 611 ; N o ; B 35 -23 569 551 ;
+C 112 ; WX 611 ; N p ; B 58 -219 574 551 ;
+C 113 ; WX 611 ; N q ; B 28 -219 544 551 ;
+C 114 ; WX 389 ; N r ; B 63 0 370 553 ;
+C 115 ; WX 556 ; N s ; B 29 -23 520 551 ;
+C 116 ; WX 333 ; N t ; B 14 -23 301 678 ;
+C 117 ; WX 611 ; N u ; B 58 -23 541 542 ;
+C 118 ; WX 556 ; N v ; B 14 0 536 542 ;
+C 119 ; WX 778 ; N w ; B 5 0 766 542 ;
+C 120 ; WX 556 ; N x ; B 16 0 535 542 ;
+C 121 ; WX 556 ; N y ; B 9 -219 538 542 ;
+C 122 ; WX 500 ; N z ; B 21 0 468 542 ;
+C 123 ; WX 389 ; N braceleft ; B 37 -202 317 729 ;
+C 124 ; WX 280 ; N bar ; B 100 -202 180 729 ;
+C 125 ; WX 389 ; N braceright ; B 72 -202 352 729 ;
+C 126 ; WX 584 ; N asciitilde ; B 60 144 519 322 ;
+C 161 ; WX 333 ; N exclamdown ; B 66 -187 216 542 ;
+C 162 ; WX 556 ; N cent ; B 37 -122 522 637 ;
+C 163 ; WX 556 ; N sterling ; B 31 -20 537 717 ;
+C 164 ; WX 167 ; N fraction ; B -173 -20 337 715 ;
+C 165 ; WX 556 ; N yen ; B 5 0 552 705 ;
+C 166 ; WX 556 ; N florin ; B 21 -221 535 745 ;
+C 167 ; WX 556 ; N section ; B 33 -201 518 728 ;
+C 168 ; WX 556 ; N currency ; B 26 105 530 604 ;
+C 169 ; WX 238 ; N quotesingle ; B 50 469 188 729 ;
+C 170 ; WX 500 ; N quotedblleft ; B 71 469 433 729 ;
+C 171 ; WX 556 ; N guillemotleft ; B 88 71 468 484 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 83 73 250 476 ;
+C 173 ; WX 333 ; N guilsinglright ; B 80 73 247 476 ;
+C 174 ; WX 611 ; N fi ; B 9 0 548 729 ;
+C 175 ; WX 611 ; N fl ; B 12 0 546 729 ;
+C 177 ; WX 556 ; N endash ; B -9 208 557 313 ;
+C 178 ; WX 556 ; N dagger ; B 31 -195 523 708 ;
+C 179 ; WX 556 ; N daggerdbl ; B 28 -195 520 708 ;
+C 180 ; WX 278 ; N periodcentered ; B 64 318 188 442 ;
+C 182 ; WX 556 ; N paragraph ; B 20 -195 529 729 ;
+C 183 ; WX 350 ; N bullet ; B 50 175 300 425 ;
+C 184 ; WX 278 ; N quotesinglbase ; B 66 -135 201 125 ;
+C 185 ; WX 500 ; N quotedblbase ; B 72 -164 432 141 ;
+C 186 ; WX 500 ; N quotedblright ; B 73 469 440 729 ;
+C 187 ; WX 556 ; N guillemotright ; B 88 71 462 482 ;
+C 188 ; WX 1000 ; N ellipsis ; B 92 0 908 146 ;
+C 189 ; WX 1000 ; N perthousand ; B 11 -20 990 745 ;
+C 191 ; WX 611 ; N questiondown ; B 51 -192 544 542 ;
+C 193 ; WX 333 ; N grave ; B 17 595 213 745 ;
+C 194 ; WX 333 ; N acute ; B 121 595 317 745 ;
+C 195 ; WX 333 ; N circumflex ; B 8 598 326 745 ;
+C 196 ; WX 333 ; N tilde ; B -9 595 345 729 ;
+C 197 ; WX 333 ; N macron ; B 16 629 315 717 ;
+C 198 ; WX 333 ; N breve ; B 35 593 299 736 ;
+C 199 ; WX 333 ; N dotaccent ; B 112 607 222 729 ;
+C 200 ; WX 333 ; N dieresis ; B 18 609 314 731 ;
+C 202 ; WX 333 ; N ring ; B 77 565 257 745 ;
+C 203 ; WX 333 ; N cedilla ; B 27 -220 294 -9 ;
+C 205 ; WX 333 ; N hungarumlaut ; B -44 595 340 745 ;
+C 206 ; WX 333 ; N ogonek ; B 45 -195 268 38 ;
+C 207 ; WX 333 ; N caron ; B 9 598 327 745 ;
+C 208 ; WX 1000 ; N emdash ; B -7 208 1003 313 ;
+C 225 ; WX 1000 ; N AE ; B 1 0 966 729 ;
+C 227 ; WX 370 ; N ordfeminine ; B 31 277 329 746 ;
+C 232 ; WX 611 ; N Lslash ; B 0 0 597 729 ;
+C 233 ; WX 778 ; N Oslash ; B 31 -34 755 754 ;
+C 234 ; WX 1000 ; N OE ; B 28 -20 970 741 ;
+C 235 ; WX 365 ; N ordmasculine ; B 23 276 343 745 ;
+C 241 ; WX 889 ; N ae ; B 27 -20 857 555 ;
+C 245 ; WX 278 ; N dotlessi ; B 67 0 207 542 ;
+C 248 ; WX 278 ; N lslash ; B 0 0 252 729 ;
+C 249 ; WX 611 ; N oslash ; B 11 -34 598 561 ;
+C 250 ; WX 944 ; N oe ; B 23 -21 920 554 ;
+C 251 ; WX 611 ; N germandbls ; B 67 -16 575 730 ;
+C -1 ; WX 722 ; N Aacute ; B 26 0 703 936 ;
+C -1 ; WX 722 ; N Acircumflex ; B 26 0 703 936 ;
+C -1 ; WX 722 ; N Adieresis ; B 26 0 703 922 ;
+C -1 ; WX 722 ; N Agrave ; B 26 0 703 936 ;
+C -1 ; WX 722 ; N Aring ; B 26 0 703 936 ;
+C -1 ; WX 722 ; N Atilde ; B 26 0 703 920 ;
+C -1 ; WX 722 ; N Ccedilla ; B 44 -220 685 741 ;
+C -1 ; WX 667 ; N Eacute ; B 79 0 624 936 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 79 0 624 936 ;
+C -1 ; WX 667 ; N Edieresis ; B 79 0 624 922 ;
+C -1 ; WX 667 ; N Egrave ; B 79 0 624 936 ;
+C -1 ; WX 722 ; N Eth ; B -18 0 681 729 ;
+C -1 ; WX 278 ; N Iacute ; B 63 0 290 936 ;
+C -1 ; WX 278 ; N Icircumflex ; B -19 0 299 936 ;
+C -1 ; WX 278 ; N Idieresis ; B -9 0 287 922 ;
+C -1 ; WX 278 ; N Igrave ; B -10 0 213 936 ;
+C -1 ; WX 722 ; N Ntilde ; B 68 0 661 920 ;
+C -1 ; WX 778 ; N Oacute ; B 40 -23 742 936 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 40 -23 742 936 ;
+C -1 ; WX 778 ; N Odieresis ; B 40 -23 742 922 ;
+C -1 ; WX 778 ; N Ograve ; B 40 -23 742 936 ;
+C -1 ; WX 778 ; N Otilde ; B 40 -23 742 920 ;
+C -1 ; WX 667 ; N Scaron ; B 32 -23 633 936 ;
+C -1 ; WX 667 ; N Thorn ; B 76 0 633 729 ;
+C -1 ; WX 722 ; N Uacute ; B 76 -23 654 936 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 76 -23 654 936 ;
+C -1 ; WX 722 ; N Udieresis ; B 76 -23 654 922 ;
+C -1 ; WX 722 ; N Ugrave ; B 76 -23 654 936 ;
+C -1 ; WX 667 ; N Yacute ; B 27 0 650 932 ;
+C -1 ; WX 667 ; N Ydieresis ; B 27 0 650 922 ;
+C -1 ; WX 611 ; N Zcaron ; B 30 0 578 936 ;
+C -1 ; WX 556 ; N aacute ; B 27 -24 524 745 ;
+C -1 ; WX 556 ; N acircumflex ; B 27 -24 524 745 ;
+C -1 ; WX 556 ; N adieresis ; B 27 -24 524 731 ;
+C -1 ; WX 556 ; N agrave ; B 27 -24 524 745 ;
+C -1 ; WX 556 ; N aring ; B 27 -24 524 745 ;
+C -1 ; WX 556 ; N atilde ; B 27 -24 524 729 ;
+C -1 ; WX 280 ; N brokenbar ; B 100 -202 180 729 ;
+C -1 ; WX 556 ; N ccedilla ; B 34 -220 522 551 ;
+C -1 ; WX 737 ; N copyright ; B -14 -20 751 745 ;
+C -1 ; WX 400 ; N degree ; B 50 425 350 725 ;
+C -1 ; WX 584 ; N divide ; B 50 -10 534 474 ;
+C -1 ; WX 556 ; N eacute ; B 22 -23 525 745 ;
+C -1 ; WX 556 ; N ecircumflex ; B 22 -23 525 745 ;
+C -1 ; WX 556 ; N edieresis ; B 22 -23 525 731 ;
+C -1 ; WX 556 ; N egrave ; B 22 -23 525 745 ;
+C -1 ; WX 611 ; N eth ; B 35 -23 569 730 ;
+C -1 ; WX 278 ; N iacute ; B 67 0 290 745 ;
+C -1 ; WX 278 ; N icircumflex ; B -19 0 299 745 ;
+C -1 ; WX 278 ; N idieresis ; B -9 0 287 731 ;
+C -1 ; WX 278 ; N igrave ; B -10 0 207 745 ;
+C -1 ; WX 584 ; N logicalnot ; B 40 121 544 412 ;
+C -1 ; WX 584 ; N minus ; B 40 174 544 290 ;
+C -1 ; WX 611 ; N mu ; B 58 -219 541 542 ;
+C -1 ; WX 584 ; N multiply ; B 50 -10 534 474 ;
+C -1 ; WX 611 ; N ntilde ; B 63 0 546 729 ;
+C -1 ; WX 611 ; N oacute ; B 35 -23 569 745 ;
+C -1 ; WX 611 ; N ocircumflex ; B 35 -23 569 745 ;
+C -1 ; WX 611 ; N odieresis ; B 35 -23 569 731 ;
+C -1 ; WX 611 ; N ograve ; B 35 -23 569 745 ;
+C -1 ; WX 834 ; N onehalf ; B 30 -20 803 715 ;
+C -1 ; WX 834 ; N onequarter ; B 30 -20 804 715 ;
+C -1 ; WX 333 ; N onesuperior ; B 46 284 247 709 ;
+C -1 ; WX 611 ; N otilde ; B 35 -23 569 729 ;
+C -1 ; WX 584 ; N plusminus ; B 40 0 544 674 ;
+C -1 ; WX 737 ; N registered ; B -14 -20 751 745 ;
+C -1 ; WX 556 ; N scaron ; B 29 -23 520 745 ;
+C -1 ; WX 611 ; N thorn ; B 58 -219 574 729 ;
+C -1 ; WX 834 ; N threequarters ; B 30 -20 804 725 ;
+C -1 ; WX 333 ; N threesuperior ; B 8 271 325 720 ;
+C -1 ; WX 1000 ; N trademark ; B 71 341 929 745 ;
+C -1 ; WX 333 ; N twosuperior ; B 9 284 324 719 ;
+C -1 ; WX 611 ; N uacute ; B 58 -23 541 745 ;
+C -1 ; WX 611 ; N ucircumflex ; B 58 -23 541 745 ;
+C -1 ; WX 611 ; N udieresis ; B 58 -23 541 731 ;
+C -1 ; WX 611 ; N ugrave ; B 58 -23 541 745 ;
+C -1 ; WX 556 ; N yacute ; B 9 -219 538 745 ;
+C -1 ; WX 556 ; N ydieresis ; B 9 -219 538 731 ;
+C -1 ; WX 500 ; N zcaron ; B 21 0 468 745 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 101
+
+KPX A y -37
+KPX A w -18
+KPX A v -37
+KPX A space -37
+KPX A quoteright -55
+KPX A Y -92
+KPX A W -55
+KPX A V -74
+KPX A T -74
+
+KPX F period -111
+KPX F comma -111
+KPX F A -55
+
+KPX L y -37
+KPX L space -18
+KPX L quoteright -55
+KPX L Y -92
+KPX L W -55
+KPX L V -74
+KPX L T -74
+
+KPX P space -18
+KPX P period -129
+KPX P comma -129
+KPX P A -74
+
+KPX R Y -37
+KPX R W -18
+KPX R V -18
+
+KPX T y -74
+KPX T w -74
+KPX T u -74
+KPX T semicolon -111
+KPX T s -74
+KPX T r -55
+KPX T period -111
+KPX T o -74
+KPX T i -18
+KPX T hyphen -55
+KPX T e -74
+KPX T comma -111
+KPX T colon -111
+KPX T c -74
+KPX T a -74
+KPX T O -18
+KPX T A -74
+
+KPX V y -37
+KPX V u -37
+KPX V semicolon -55
+KPX V r -55
+KPX V period -92
+KPX V o -74
+KPX V i -18
+KPX V hyphen -55
+KPX V e -55
+KPX V comma -92
+KPX V colon -55
+KPX V a -55
+KPX V A -74
+
+KPX W y -18
+KPX W u -18
+KPX W semicolon -18
+KPX W r -18
+KPX W period -55
+KPX W o -18
+KPX W i -9
+KPX W hyphen -20
+KPX W e -18
+KPX W comma -55
+KPX W colon -18
+KPX W a -37
+KPX W A -55
+
+KPX Y v -55
+KPX Y u -55
+KPX Y space -18
+KPX Y semicolon -74
+KPX Y q -74
+KPX Y period -111
+KPX Y p -55
+KPX Y o -74
+KPX Y i -37
+KPX Y hyphen -55
+KPX Y e -55
+KPX Y comma -111
+KPX Y colon -74
+KPX Y a -55
+KPX Y A -92
+
+KPX f quoteright 18
+
+KPX one one -55
+
+KPX quoteleft quoteleft -37
+
+KPX quoteright space -55
+KPX quoteright s -37
+KPX quoteright quoteright -37
+
+KPX r quoteright 37
+KPX r period -55
+KPX r comma -55
+
+KPX space Y -18
+KPX space A -37
+
+KPX v period -74
+KPX v comma -74
+
+KPX w period -37
+KPX w comma -37
+
+KPX y period -74
+KPX y comma -74
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 191 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 83 0 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 167 191 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 111 0 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 207 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 117 0 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 167 191 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 111 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 197 191 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 197 191 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 197 191 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 197 191 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 139 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 139 0 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute -27 191 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -27 191 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -27 191 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave -27 191 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 188 191 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 188 191 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 188 191 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 188 191 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 111 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 111 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 111 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 111 0 ;
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 197 191 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 197 191 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 197 191 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 197 191 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 111 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 111 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 111 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 111 0 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 222 191 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 222 191 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 222 191 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 222 191 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 139 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 139 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 139 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 197 191 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 111 0 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 200 191 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 146 0 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 222 191 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 139 0 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 197 191 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 111 0 ;
+EndComposites
+EndFontMetrics
diff --git a/misc/afm/HelvBoO.afm b/misc/afm/HelvBoO.afm
new file mode 100644
index 0000000000..dfe3bef5cc
--- /dev/null
+++ b/misc/afm/HelvBoO.afm
@@ -0,0 +1,429 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1984 Adobe Systems Incorporated. 	All Rights Reserved.
+Comment Creation Date:Tue Aug 5 11:51:40 PDT 1986
+FontName Helvetica-BoldOblique
+EncodingScheme AdobeStandardEncoding
+FullName Helvetica Bold Oblique
+FamilyName Helvetica
+Weight Bold
+ItalicAngle -12.0
+IsFixedPitch false
+UnderlinePosition -106
+UnderlineThickness 105
+Version 001.001
+Notice Helvetica is a registered trademark of Allied Corporation
+FontBBox -177 -221 1107 936
+CapHeight 729
+XHeight 542
+Descender -219
+Ascender 729
+StartCharMetrics 228
+C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 112 0 417 729 ;
+C 34 ; WX 474 ; N quotedbl ; B 177 470 579 729 ;
+C 35 ; WX 556 ; N numbersign ; B 33 -30 660 696 ;
+C 36 ; WX 556 ; N dollar ; B 59 -125 628 765 ;
+C 37 ; WX 889 ; N percent ; B 129 -18 903 708 ;
+C 38 ; WX 722 ; N ampersand ; B 89 -20 720 729 ;
+C 39 ; WX 278 ; N quoteright ; B 166 469 356 729 ;
+C 40 ; WX 333 ; N parenleft ; B 84 -202 458 729 ;
+C 41 ; WX 333 ; N parenright ; B -21 -202 356 729 ;
+C 42 ; WX 389 ; N asterisk ; B 145 385 478 730 ;
+C 43 ; WX 584 ; N plus ; B 87 -10 596 474 ;
+C 44 ; WX 278 ; N comma ; B 27 -174 245 146 ;
+C 45 ; WX 333 ; N hyphen ; B 70 208 371 344 ;
+C 46 ; WX 278 ; N period ; B 64 0 245 146 ;
+C 47 ; WX 278 ; N slash ; B -1 -14 427 715 ;
+C 48 ; WX 556 ; N zero ; B 81 -23 614 725 ;
+C 49 ; WX 556 ; N one ; B 172 0 529 709 ;
+C 50 ; WX 556 ; N two ; B 30 0 628 726 ;
+C 51 ; WX 556 ; N three ; B 67 -23 613 726 ;
+C 52 ; WX 556 ; N four ; B 57 0 599 709 ;
+C 53 ; WX 556 ; N five ; B 59 -24 641 709 ;
+C 54 ; WX 556 ; N six ; B 85 -23 625 727 ;
+C 55 ; WX 556 ; N seven ; B 131 0 679 709 ;
+C 56 ; WX 556 ; N eight ; B 60 -23 620 726 ;
+C 57 ; WX 556 ; N nine ; B 68 -23 611 728 ;
+C 58 ; WX 333 ; N colon ; B 113 0 374 521 ;
+C 59 ; WX 333 ; N semicolon ; B 76 -174 374 521 ;
+C 60 ; WX 584 ; N less ; B 77 -10 630 474 ;
+C 61 ; WX 584 ; N equal ; B 61 52 622 412 ;
+C 62 ; WX 584 ; N greater ; B 38 -10 591 474 ;
+C 63 ; WX 611 ; N question ; B 168 0 672 744 ;
+C 64 ; WX 975 ; N at ; B 73 -136 1032 746 ;
+C 65 ; WX 722 ; N A ; B 26 0 703 729 ;
+C 66 ; WX 722 ; N B ; B 82 0 762 729 ;
+C 67 ; WX 722 ; N C ; B 107 -23 793 741 ;
+C 68 ; WX 722 ; N D ; B 77 0 776 729 ;
+C 69 ; WX 667 ; N E ; B 79 0 762 729 ;
+C 70 ; WX 611 ; N F ; B 74 0 741 729 ;
+C 71 ; WX 778 ; N G ; B 107 -24 819 741 ;
+C 72 ; WX 722 ; N H ; B 68 0 812 729 ;
+C 73 ; WX 278 ; N I ; B 63 0 368 729 ;
+C 74 ; WX 556 ; N J ; B 59 -23 641 729 ;
+C 75 ; WX 722 ; N K ; B 74 0 843 729 ;
+C 76 ; WX 611 ; N L ; B 80 0 606 729 ;
+C 77 ; WX 833 ; N M ; B 66 0 931 729 ;
+C 78 ; WX 722 ; N N ; B 68 0 816 729 ;
+C 79 ; WX 778 ; N O ; B 106 -23 828 741 ;
+C 80 ; WX 667 ; N P ; B 76 0 747 729 ;
+C 81 ; WX 778 ; N Q ; B 109 -54 831 741 ;
+C 82 ; WX 722 ; N R ; B 80 0 785 729 ;
+C 83 ; WX 667 ; N S ; B 76 -23 725 741 ;
+C 84 ; WX 611 ; N T ; B 142 0 753 729 ;
+C 85 ; WX 722 ; N U ; B 119 -23 809 729 ;
+C 86 ; WX 667 ; N V ; B 179 0 802 729 ;
+C 87 ; WX 944 ; N W ; B 168 0 1087 729 ;
+C 88 ; WX 667 ; N X ; B 22 0 802 729 ;
+C 89 ; WX 667 ; N Y ; B 182 0 805 729 ;
+C 90 ; WX 611 ; N Z ; B 30 0 733 729 ;
+C 91 ; WX 333 ; N bracketleft ; B 23 -202 463 729 ;
+C 92 ; WX 278 ; N backslash ; B 138 -21 285 708 ;
+C 93 ; WX 333 ; N bracketright ; B -25 -202 415 729 ;
+C 94 ; WX 584 ; N asciicircum ; B 119 271 580 696 ;
+C 95 ; WX 556 ; N underscore ; B -65 -200 550 -130 ;
+C 96 ; WX 278 ; N quoteleft ; B 167 469 357 729 ;
+C 97 ; WX 556 ; N a ; B 50 -24 578 551 ;
+C 98 ; WX 611 ; N b ; B 59 -23 640 729 ;
+C 99 ; WX 556 ; N c ; B 77 -23 597 551 ;
+C 100 ; WX 611 ; N d ; B 79 -23 700 729 ;
+C 101 ; WX 556 ; N e ; B 64 -23 591 551 ;
+C 102 ; WX 333 ; N f ; B 90 0 464 729 ; L i fi ; L l fl ;
+C 103 ; WX 611 ; N g ; B 26 -220 656 551 ;
+C 104 ; WX 611 ; N h ; B 67 0 629 729 ;
+C 105 ; WX 278 ; N i ; B 67 0 362 729 ;
+C 106 ; WX 278 ; N j ; B -43 -219 365 729 ;
+C 107 ; WX 556 ; N k ; B 59 0 651 729 ;
+C 108 ; WX 278 ; N l ; B 67 0 362 729 ;
+C 109 ; WX 889 ; N m ; B 60 0 911 553 ;
+C 110 ; WX 611 ; N n ; B 63 0 629 551 ;
+C 111 ; WX 611 ; N o ; B 82 -23 634 551 ;
+C 112 ; WX 611 ; N p ; B 11 -219 637 551 ;
+C 113 ; WX 611 ; N q ; B 72 -219 659 551 ;
+C 114 ; WX 389 ; N r ; B 63 0 487 553 ;
+C 115 ; WX 556 ; N s ; B 60 -23 589 551 ;
+C 116 ; WX 333 ; N t ; B 101 -23 414 678 ;
+C 117 ; WX 611 ; N u ; B 88 -23 656 542 ;
+C 118 ; WX 556 ; N v ; B 129 0 651 542 ;
+C 119 ; WX 778 ; N w ; B 120 0 881 542 ;
+C 120 ; WX 556 ; N x ; B 16 0 648 542 ;
+C 121 ; WX 556 ; N y ; B 37 -219 653 542 ;
+C 122 ; WX 500 ; N z ; B 21 0 575 542 ;
+C 123 ; WX 389 ; N braceleft ; B 84 -202 472 729 ;
+C 124 ; WX 280 ; N bar ; B 57 -202 335 729 ;
+C 125 ; WX 389 ; N braceright ; B 29 -202 419 729 ;
+C 126 ; WX 584 ; N asciitilde ; B 97 144 581 322 ;
+C 161 ; WX 333 ; N exclamdown ; B 26 -187 331 542 ;
+C 162 ; WX 556 ; N cent ; B 79 -122 598 637 ;
+C 163 ; WX 556 ; N sterling ; B 49 -20 629 717 ;
+C 164 ; WX 167 ; N fraction ; B -177 -20 489 715 ;
+C 165 ; WX 556 ; N yen ; B 107 0 702 705 ;
+C 166 ; WX 556 ; N florin ; B -21 -221 690 745 ;
+C 167 ; WX 556 ; N section ; B 56 -201 596 728 ;
+C 168 ; WX 556 ; N currency ; B 66 105 644 604 ;
+C 169 ; WX 238 ; N quotesingle ; B 177 469 343 729 ;
+C 170 ; WX 500 ; N quotedblleft ; B 171 469 588 729 ;
+C 171 ; WX 556 ; N guillemotleft ; B 135 71 571 484 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 128 73 351 476 ;
+C 173 ; WX 333 ; N guilsinglright ; B 96 73 319 476 ;
+C 174 ; WX 611 ; N fi ; B 85 0 703 729 ;
+C 175 ; WX 611 ; N fl ; B 88 0 701 729 ;
+C 177 ; WX 556 ; N endash ; B 35 208 624 313 ;
+C 178 ; WX 556 ; N dagger ; B 109 -195 626 708 ;
+C 179 ; WX 556 ; N daggerdbl ; B 35 -195 623 708 ;
+C 180 ; WX 278 ; N periodcentered ; B 143 318 270 442 ;
+C 182 ; WX 556 ; N paragraph ; B 121 -195 684 729 ;
+C 183 ; WX 350 ; N bullet ; B 111 175 367 425 ;
+C 184 ; WX 278 ; N quotesinglbase ; B 37 -135 228 125 ;
+C 185 ; WX 500 ; N quotedblbase ; B 37 -164 462 141 ;
+C 186 ; WX 500 ; N quotedblright ; B 173 469 595 729 ;
+C 187 ; WX 556 ; N guillemotright ; B 103 71 533 482 ;
+C 188 ; WX 1000 ; N ellipsis ; B 92 0 939 146 ;
+C 189 ; WX 1000 ; N perthousand ; B 72 -20 1021 745 ;
+C 191 ; WX 611 ; N questiondown ; B 52 -192 556 542 ;
+C 193 ; WX 333 ; N grave ; B 175 595 339 745 ;
+C 194 ; WX 333 ; N acute ; B 247 595 475 745 ;
+C 195 ; WX 333 ; N circumflex ; B 135 598 453 745 ;
+C 196 ; WX 333 ; N tilde ; B 117 595 500 729 ;
+C 197 ; WX 333 ; N macron ; B 150 629 467 717 ;
+C 198 ; WX 333 ; N breve ; B 188 593 455 736 ;
+C 199 ; WX 333 ; N dotaccent ; B 241 607 377 729 ;
+C 200 ; WX 333 ; N dieresis ; B 147 609 469 731 ;
+C 202 ; WX 333 ; N ring ; B 214 565 398 745 ;
+C 203 ; WX 333 ; N cedilla ; B -13 -220 270 -9 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 82 595 498 745 ;
+C 206 ; WX 333 ; N ogonek ; B 23 -195 248 38 ;
+C 207 ; WX 333 ; N caron ; B 167 598 485 745 ;
+C 208 ; WX 1000 ; N emdash ; B 37 208 1070 313 ;
+C 225 ; WX 1000 ; N AE ; B 1 0 1104 729 ;
+C 227 ; WX 370 ; N ordfeminine ; B 96 277 451 746 ;
+C 232 ; WX 611 ; N Lslash ; B 54 0 624 729 ;
+C 233 ; WX 778 ; N Oslash ; B 34 -34 906 754 ;
+C 234 ; WX 1000 ; N OE ; B 90 -20 1107 741 ;
+C 235 ; WX 365 ; N ordmasculine ; B 92 276 471 745 ;
+C 241 ; WX 889 ; N ae ; B 54 -20 927 555 ;
+C 245 ; WX 278 ; N dotlessi ; B 67 0 322 542 ;
+C 248 ; WX 278 ; N lslash ; B 50 0 372 729 ;
+C 249 ; WX 611 ; N oslash ; B 12 -34 709 561 ;
+C 250 ; WX 944 ; N oe ; B 71 -21 986 554 ;
+C 251 ; WX 611 ; N germandbls ; B 67 -16 654 730 ;
+C -1 ; WX 722 ; N Aacute ; B 26 0 714 936 ;
+C -1 ; WX 722 ; N Acircumflex ; B 26 0 703 936 ;
+C -1 ; WX 722 ; N Adieresis ; B 26 0 708 922 ;
+C -1 ; WX 722 ; N Agrave ; B 26 0 703 936 ;
+C -1 ; WX 722 ; N Aring ; B 26 0 703 936 ;
+C -1 ; WX 722 ; N Atilde ; B 26 0 739 920 ;
+C -1 ; WX 722 ; N Ccedilla ; B 107 -220 793 741 ;
+C -1 ; WX 667 ; N Eacute ; B 79 0 762 936 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 79 0 762 936 ;
+C -1 ; WX 667 ; N Edieresis ; B 79 0 762 922 ;
+C -1 ; WX 667 ; N Egrave ; B 79 0 762 936 ;
+C -1 ; WX 722 ; N Eth ; B 53 0 776 729 ;
+C -1 ; WX 278 ; N Iacute ; B 63 0 489 936 ;
+C -1 ; WX 278 ; N Icircumflex ; B 63 0 467 936 ;
+C -1 ; WX 278 ; N Idieresis ; B 63 0 483 922 ;
+C -1 ; WX 278 ; N Igrave ; B 63 0 368 936 ;
+C -1 ; WX 722 ; N Ntilde ; B 68 0 816 920 ;
+C -1 ; WX 778 ; N Oacute ; B 106 -23 828 936 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 106 -23 828 936 ;
+C -1 ; WX 778 ; N Odieresis ; B 106 -23 828 922 ;
+C -1 ; WX 778 ; N Ograve ; B 106 -23 828 936 ;
+C -1 ; WX 778 ; N Otilde ; B 106 -23 828 920 ;
+C -1 ; WX 667 ; N Scaron ; B 76 -23 725 936 ;
+C -1 ; WX 667 ; N Thorn ; B 76 0 730 729 ;
+C -1 ; WX 722 ; N Uacute ; B 119 -23 809 936 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 119 -23 809 936 ;
+C -1 ; WX 722 ; N Udieresis ; B 119 -23 809 922 ;
+C -1 ; WX 722 ; N Ugrave ; B 119 -23 809 936 ;
+C -1 ; WX 667 ; N Yacute ; B 182 0 805 932 ;
+C -1 ; WX 667 ; N Ydieresis ; B 182 0 805 922 ;
+C -1 ; WX 611 ; N Zcaron ; B 30 0 733 936 ;
+C -1 ; WX 556 ; N aacute ; B 50 -24 587 745 ;
+C -1 ; WX 556 ; N acircumflex ; B 50 -24 578 745 ;
+C -1 ; WX 556 ; N adieresis ; B 50 -24 581 731 ;
+C -1 ; WX 556 ; N agrave ; B 50 -24 578 745 ;
+C -1 ; WX 556 ; N aring ; B 50 -24 578 745 ;
+C -1 ; WX 556 ; N atilde ; B 50 -24 612 729 ;
+C -1 ; WX 280 ; N brokenbar ; B 57 -202 335 729 ;
+C -1 ; WX 556 ; N ccedilla ; B 77 -220 597 551 ;
+C -1 ; WX 737 ; N copyright ; B 54 -20 837 745 ;
+C -1 ; WX 400 ; N degree ; B 169 425 476 725 ;
+C -1 ; WX 584 ; N divide ; B 87 -10 596 474 ;
+C -1 ; WX 556 ; N eacute ; B 64 -23 591 745 ;
+C -1 ; WX 556 ; N ecircumflex ; B 64 -23 591 745 ;
+C -1 ; WX 556 ; N edieresis ; B 64 -23 591 731 ;
+C -1 ; WX 556 ; N egrave ; B 64 -23 591 745 ;
+C -1 ; WX 611 ; N eth ; B 82 -23 633 730 ;
+C -1 ; WX 278 ; N iacute ; B 67 0 448 745 ;
+C -1 ; WX 278 ; N icircumflex ; B 67 0 426 745 ;
+C -1 ; WX 278 ; N idieresis ; B 67 0 442 731 ;
+C -1 ; WX 278 ; N igrave ; B 67 0 322 745 ;
+C -1 ; WX 584 ; N logicalnot ; B 103 121 632 412 ;
+C -1 ; WX 584 ; N minus ; B 77 174 606 290 ;
+C -1 ; WX 611 ; N mu ; B 11 -219 656 542 ;
+C -1 ; WX 584 ; N multiply ; B 66 -10 617 474 ;
+C -1 ; WX 611 ; N ntilde ; B 63 0 646 729 ;
+C -1 ; WX 611 ; N oacute ; B 82 -23 634 745 ;
+C -1 ; WX 611 ; N ocircumflex ; B 82 -23 634 745 ;
+C -1 ; WX 611 ; N odieresis ; B 82 -23 634 731 ;
+C -1 ; WX 611 ; N ograve ; B 82 -23 634 745 ;
+C -1 ; WX 834 ; N onehalf ; B 120 -20 871 715 ;
+C -1 ; WX 834 ; N onequarter ; B 151 -20 846 715 ;
+C -1 ; WX 333 ; N onesuperior ; B 169 284 398 709 ;
+C -1 ; WX 611 ; N otilde ; B 82 -23 639 729 ;
+C -1 ; WX 584 ; N plusminus ; B 40 0 639 674 ;
+C -1 ; WX 737 ; N registered ; B 55 -20 837 745 ;
+C -1 ; WX 556 ; N scaron ; B 60 -23 597 745 ;
+C -1 ; WX 611 ; N thorn ; B 11 -219 641 729 ;
+C -1 ; WX 834 ; N threequarters ; B 116 -20 863 725 ;
+C -1 ; WX 333 ; N threesuperior ; B 92 271 442 720 ;
+C -1 ; WX 1000 ; N trademark ; B 213 341 1087 745 ;
+C -1 ; WX 333 ; N twosuperior ; B 69 284 452 719 ;
+C -1 ; WX 611 ; N uacute ; B 88 -23 656 745 ;
+C -1 ; WX 611 ; N ucircumflex ; B 88 -23 656 745 ;
+C -1 ; WX 611 ; N udieresis ; B 88 -23 656 731 ;
+C -1 ; WX 611 ; N ugrave ; B 88 -23 656 745 ;
+C -1 ; WX 556 ; N yacute ; B 37 -219 653 745 ;
+C -1 ; WX 556 ; N ydieresis ; B 37 -219 653 731 ;
+C -1 ; WX 500 ; N zcaron ; B 21 0 575 745 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 99
+
+KPX A space -37
+KPX A quoteright -55
+KPX A Y -74
+KPX A W -55
+KPX A V -74
+KPX A T -74
+
+KPX F period -111
+KPX F comma -111
+KPX F A -55
+
+KPX L space -18
+KPX L quoteright -74
+KPX L Y -74
+KPX L W -55
+KPX L V -55
+KPX L T -74
+
+KPX P space -37
+KPX P period -129
+KPX P comma -129
+KPX P A -74
+
+KPX R Y -18
+KPX R W -18
+KPX R T -18
+
+KPX T y -37
+KPX T w -37
+KPX T u -18
+KPX T semicolon -74
+KPX T s -37
+KPX T r -18
+KPX T period -74
+KPX T o -37
+KPX T i -18
+KPX T hyphen -55
+KPX T e -37
+KPX T comma -74
+KPX T colon -74
+KPX T c -37
+KPX T a -37
+KPX T O -18
+KPX T A -74
+
+KPX V y -18
+KPX V u -18
+KPX V semicolon -37
+KPX V r -18
+KPX V period -92
+KPX V o -37
+KPX V i -37
+KPX V hyphen -37
+KPX V e -37
+KPX V comma -92
+KPX V colon -37
+KPX V a -37
+KPX V A -74
+
+KPX W y -18
+KPX W u -18
+KPX W semicolon -37
+KPX W r -18
+KPX W period -74
+KPX W o -18
+KPX W i -9
+KPX W hyphen -37
+KPX W e -18
+KPX W comma -74
+KPX W colon -37
+KPX W a -18
+KPX W A -55
+
+KPX Y v -37
+KPX Y u -37
+KPX Y space -18
+KPX Y semicolon -55
+KPX Y q -37
+KPX Y period -92
+KPX Y p -37
+KPX Y i -37
+KPX Y o -37
+KPX Y hyphen -74
+KPX Y e -37
+KPX Y comma -92
+KPX Y colon -55
+KPX Y a -37
+KPX Y A -74
+
+KPX f quoteright 18
+KPX f f -18
+
+KPX one one -74
+
+KPX quoteleft quoteleft -37
+
+KPX quoteright t 18
+KPX quoteright space -37
+KPX quoteright s -18
+KPX quoteright quoteright -37
+
+KPX r quoteright 37
+KPX r period -55
+KPX r comma -55
+
+KPX space Y -18
+KPX space A -37
+
+KPX v period -55
+KPX v comma -55
+
+KPX w period -37
+KPX w comma -37
+
+KPX y period -37
+KPX y comma -37
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 187 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 83 0 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 167 187 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 111 0 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 194 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 111 0 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 167 187 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 111 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 194 187 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 194 187 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 194 187 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 194 187 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 139 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 139 0 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute -27 187 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -27 187 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -27 187 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave -27 187 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 167 187 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 167 187 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 167 187 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 167 187 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 111 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 111 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 111 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 111 0 ;
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 194 187 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 194 187 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 194 187 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 194 187 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 111 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 111 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 111 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 111 0 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 222 187 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 222 187 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 222 187 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 222 187 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 139 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 139 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 139 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 194 187 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 111 0 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 194 187 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 139 0 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 222 187 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 139 0 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 194 187 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 111 0 ;
+EndComposites
+EndFontMetrics
diff --git a/misc/afm/HelvO.afm b/misc/afm/HelvO.afm
new file mode 100644
index 0000000000..c24bdc1c20
--- /dev/null
+++ b/misc/afm/HelvO.afm
@@ -0,0 +1,428 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1984 Adobe Systems Incorporated. 	All Rights Reserved.
+Comment Creation Date:Tue Aug 5 11:45:36 PDT 1986
+FontName Helvetica-Oblique
+EncodingScheme AdobeStandardEncoding
+FullName Helvetica Oblique
+FamilyName Helvetica
+Weight Medium
+ItalicAngle -12.0
+IsFixedPitch false
+UnderlinePosition -106
+UnderlineThickness 73
+Version 001.001
+Notice Helvetica is a registered trademark of Allied Corporation.
+FontBBox -178 -220 1108 944
+CapHeight 729
+XHeight 525
+Descender -219
+Ascender 729
+StartCharMetrics 228
+C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 278 ; N exclam ; B 124 0 363 729 ;
+C 34 ; WX 355 ; N quotedbl ; B 177 462 455 708 ;
+C 35 ; WX 556 ; N numbersign ; B 54 -20 649 698 ;
+C 36 ; WX 556 ; N dollar ; B 69 -125 613 770 ;
+C 37 ; WX 889 ; N percent ; B 134 -20 895 708 ;
+C 38 ; WX 667 ; N ampersand ; B 83 -23 644 710 ;
+C 39 ; WX 222 ; N quoteright ; B 165 476 308 708 ;
+C 40 ; WX 333 ; N parenleft ; B 113 -213 446 729 ;
+C 41 ; WX 333 ; N parenright ; B -7 -213 325 729 ;
+C 42 ; WX 389 ; N asterisk ; B 169 452 471 740 ;
+C 43 ; WX 584 ; N plus ; B 92 -10 591 474 ;
+C 44 ; WX 278 ; N comma ; B 55 -150 214 104 ;
+C 45 ; WX 333 ; N hyphen ; B 97 240 351 313 ;
+C 46 ; WX 278 ; N period ; B 87 0 213 104 ;
+C 47 ; WX 278 ; N slash ; B -12 -21 434 708 ;
+C 48 ; WX 556 ; N zero ; B 98 -23 598 709 ;
+C 49 ; WX 556 ; N one ; B 208 0 498 709 ;
+C 50 ; WX 556 ; N two ; B 34 0 620 710 ;
+C 51 ; WX 556 ; N three ; B 71 -23 599 709 ;
+C 52 ; WX 556 ; N four ; B 63 0 573 709 ;
+C 53 ; WX 556 ; N five ; B 70 -23 629 709 ;
+C 54 ; WX 556 ; N six ; B 93 -23 611 709 ;
+C 55 ; WX 556 ; N seven ; B 137 0 671 709 ;
+C 56 ; WX 556 ; N eight ; B 74 -23 604 709 ;
+C 57 ; WX 556 ; N nine ; B 83 -23 599 709 ;
+C 58 ; WX 278 ; N colon ; B 110 0 326 525 ;
+C 59 ; WX 278 ; N semicolon ; B 78 -150 325 516 ;
+C 60 ; WX 584 ; N less ; B 87 -10 635 474 ;
+C 61 ; WX 584 ; N equal ; B 74 112 609 352 ;
+C 62 ; WX 584 ; N greater ; B 48 -10 596 474 ;
+C 63 ; WX 556 ; N question ; B 184 0 630 738 ;
+C 64 ; WX 1015 ; N at ; B 80 -146 1036 737 ;
+C 65 ; WX 667 ; N A ; B 17 0 653 729 ;
+C 66 ; WX 667 ; N B ; B 79 0 711 729 ;
+C 67 ; WX 722 ; N C ; B 112 -23 770 741 ;
+C 68 ; WX 722 ; N D ; B 89 0 759 729 ;
+C 69 ; WX 667 ; N E ; B 90 0 751 729 ;
+C 70 ; WX 611 ; N F ; B 90 0 734 729 ;
+C 71 ; WX 778 ; N G ; B 109 -23 809 741 ;
+C 72 ; WX 722 ; N H ; B 83 0 799 729 ;
+C 73 ; WX 278 ; N I ; B 100 0 349 729 ;
+C 74 ; WX 500 ; N J ; B 47 -26 581 729 ;
+C 75 ; WX 667 ; N K ; B 79 0 813 729 ;
+C 76 ; WX 556 ; N L ; B 80 0 551 729 ;
+C 77 ; WX 833 ; N M ; B 75 0 916 729 ;
+C 78 ; WX 722 ; N N ; B 76 0 801 729 ;
+C 79 ; WX 778 ; N O ; B 104 -23 828 741 ;
+C 80 ; WX 667 ; N P ; B 91 0 733 730 ;
+C 81 ; WX 778 ; N Q ; B 104 -59 828 741 ;
+C 82 ; WX 722 ; N R ; B 93 0 770 729 ;
+C 83 ; WX 667 ; N S ; B 89 -23 714 741 ;
+C 84 ; WX 611 ; N T ; B 158 0 748 729 ;
+C 85 ; WX 722 ; N U ; B 124 -23 800 729 ;
+C 86 ; WX 667 ; N V ; B 185 0 800 729 ;
+C 87 ; WX 944 ; N W ; B 177 0 1084 729 ;
+C 88 ; WX 667 ; N X ; B 22 0 794 729 ;
+C 89 ; WX 667 ; N Y ; B 168 0 816 729 ;
+C 90 ; WX 611 ; N Z ; B 28 0 737 729 ;
+C 91 ; WX 278 ; N bracketleft ; B 19 -214 405 729 ;
+C 92 ; WX 278 ; N backslash ; B 147 -20 280 729 ;
+C 93 ; WX 278 ; N bracketright ; B -23 -215 364 729 ;
+C 94 ; WX 469 ; N asciicircum ; B 115 333 496 713 ;
+C 95 ; WX 556 ; N underscore ; B -59 -175 551 -125 ;
+C 96 ; WX 222 ; N quoteleft ; B 163 459 308 708 ;
+C 97 ; WX 556 ; N a ; B 65 -23 568 540 ;
+C 98 ; WX 556 ; N b ; B 54 -23 588 729 ;
+C 99 ; WX 500 ; N c ; B 76 -23 554 540 ;
+C 100 ; WX 556 ; N d ; B 73 -23 650 729 ;
+C 101 ; WX 556 ; N e ; B 84 -23 580 541 ;
+C 102 ; WX 278 ; N f ; B 89 0 413 733 ; L i fi ; L l fl ;
+C 103 ; WX 556 ; N g ; B 32 -220 601 540 ;
+C 104 ; WX 556 ; N h ; B 70 0 574 729 ;
+C 105 ; WX 222 ; N i ; B 66 0 305 729 ;
+C 106 ; WX 222 ; N j ; B -65 -220 308 729 ;
+C 107 ; WX 500 ; N k ; B 58 0 584 729 ;
+C 108 ; WX 222 ; N l ; B 68 0 307 729 ;
+C 109 ; WX 833 ; N m ; B 71 0 852 540 ;
+C 110 ; WX 556 ; N n ; B 70 0 574 540 ;
+C 111 ; WX 556 ; N o ; B 80 -23 576 540 ;
+C 112 ; WX 556 ; N p ; B 7 -219 586 540 ;
+C 113 ; WX 556 ; N q ; B 71 -219 607 540 ;
+C 114 ; WX 333 ; N r ; B 69 0 436 540 ;
+C 115 ; WX 500 ; N s ; B 61 -24 520 540 ;
+C 116 ; WX 278 ; N t ; B 97 -24 366 667 ;
+C 117 ; WX 556 ; N u ; B 88 -23 594 525 ;
+C 118 ; WX 500 ; N v ; B 122 0 598 525 ;
+C 119 ; WX 722 ; N w ; B 118 0 820 525 ;
+C 120 ; WX 500 ; N x ; B 17 0 583 525 ;
+C 121 ; WX 500 ; N y ; B 8 -219 590 525 ;
+C 122 ; WX 500 ; N z ; B 31 0 557 525 ;
+C 123 ; WX 334 ; N braceleft ; B 91 -214 431 731 ;
+C 124 ; WX 260 ; N bar ; B 54 -215 315 729 ;
+C 125 ; WX 334 ; N braceright ; B -16 -214 324 731 ;
+C 126 ; WX 584 ; N asciitilde ; B 137 267 594 438 ;
+C 161 ; WX 333 ; N exclamdown ; B 76 -214 317 525 ;
+C 162 ; WX 556 ; N cent ; B 96 -120 585 628 ;
+C 163 ; WX 556 ; N sterling ; B 44 -21 628 726 ;
+C 164 ; WX 167 ; N fraction ; B -178 -21 486 708 ;
+C 165 ; WX 556 ; N yen ; B 100 0 696 710 ;
+C 166 ; WX 556 ; N florin ; B -32 -214 696 742 ;
+C 167 ; WX 556 ; N section ; B 63 -215 589 729 ;
+C 168 ; WX 556 ; N currency ; B 110 126 593 554 ;
+C 169 ; WX 191 ; N quotesingle ; B 173 462 292 708 ;
+C 170 ; WX 333 ; N quotedblleft ; B 146 459 449 708 ;
+C 171 ; WX 556 ; N guillemotleft ; B 147 106 548 438 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 140 112 336 436 ;
+C 173 ; WX 333 ; N guilsinglright ; B 109 112 307 436 ;
+C 174 ; WX 500 ; N fi ; B 83 0 591 733 ;
+C 175 ; WX 500 ; N fl ; B 88 0 585 733 ;
+C 177 ; WX 556 ; N endash ; B 46 240 628 313 ;
+C 178 ; WX 556 ; N dagger ; B 127 -178 620 710 ;
+C 179 ; WX 556 ; N daggerdbl ; B 51 -178 620 710 ;
+C 180 ; WX 278 ; N periodcentered ; B 166 318 293 442 ;
+C 182 ; WX 537 ; N paragraph ; B 145 -178 677 729 ;
+C 183 ; WX 350 ; N bullet ; B 120 220 376 470 ;
+C 184 ; WX 222 ; N quotesinglbase ; B 37 -129 180 103 ;
+C 185 ; WX 333 ; N quotedblbase ; B 20 -129 322 103 ;
+C 186 ; WX 333 ; N quotedblright ; B 150 476 452 708 ;
+C 187 ; WX 556 ; N guillemotright ; B 121 106 518 438 ;
+C 188 ; WX 1000 ; N ellipsis ; B 115 0 907 104 ;
+C 189 ; WX 1000 ; N perthousand ; B 93 -20 1024 740 ;
+C 191 ; WX 611 ; N questiondown ; B 86 -213 531 525 ;
+C 193 ; WX 333 ; N grave ; B 179 592 357 740 ;
+C 194 ; WX 333 ; N acute ; B 218 592 458 740 ;
+C 195 ; WX 333 ; N circumflex ; B 146 591 433 741 ;
+C 196 ; WX 333 ; N tilde ; B 130 589 471 716 ;
+C 197 ; WX 333 ; N macron ; B 160 621 450 694 ;
+C 198 ; WX 333 ; N breve ; B 165 594 471 729 ;
+C 199 ; WX 333 ; N dotaccent ; B 244 605 370 709 ;
+C 200 ; WX 333 ; N dieresis ; B 159 605 446 708 ;
+C 202 ; WX 333 ; N ring ; B 216 566 396 741 ;
+C 203 ; WX 333 ; N cedilla ; B 1 -214 264 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 91 592 505 740 ;
+C 206 ; WX 333 ; N ogonek ; B 35 -189 246 15 ;
+C 207 ; WX 333 ; N caron ; B 176 590 463 740 ;
+C 208 ; WX 1000 ; N emdash ; B 42 240 1068 313 ;
+C 225 ; WX 1000 ; N AE ; B 11 0 1087 729 ;
+C 227 ; WX 370 ; N ordfeminine ; B 107 301 441 740 ;
+C 232 ; WX 556 ; N Lslash ; B 61 0 570 729 ;
+C 233 ; WX 778 ; N Oslash ; B 32 -23 867 742 ;
+C 234 ; WX 1000 ; N OE ; B 101 -20 1108 739 ;
+C 235 ; WX 365 ; N ordmasculine ; B 114 301 452 741 ;
+C 241 ; WX 889 ; N ae ; B 59 -20 915 546 ;
+C 245 ; WX 278 ; N dotlessi ; B 94 0 290 525 ;
+C 248 ; WX 222 ; N lslash ; B 62 0 312 729 ;
+C 249 ; WX 611 ; N oslash ; B 19 -27 639 548 ;
+C 250 ; WX 944 ; N oe ; B 85 -22 966 540 ;
+C 251 ; WX 611 ; N germandbls ; B 126 -20 655 729 ;
+C -1 ; WX 667 ; N Aacute ; B 17 0 667 939 ;
+C -1 ; WX 667 ; N Acircumflex ; B 17 0 653 940 ;
+C -1 ; WX 667 ; N Adieresis ; B 17 0 655 907 ;
+C -1 ; WX 667 ; N Agrave ; B 17 0 653 939 ;
+C -1 ; WX 667 ; N Aring ; B 17 0 653 940 ;
+C -1 ; WX 667 ; N Atilde ; B 17 0 680 915 ;
+C -1 ; WX 722 ; N Ccedilla ; B 112 -214 770 741 ;
+C -1 ; WX 667 ; N Eacute ; B 90 0 751 939 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 90 0 751 940 ;
+C -1 ; WX 667 ; N Edieresis ; B 90 0 751 907 ;
+C -1 ; WX 667 ; N Egrave ; B 90 0 751 939 ;
+C -1 ; WX 722 ; N Eth ; B 73 0 759 729 ;
+C -1 ; WX 278 ; N Iacute ; B 100 0 479 939 ;
+C -1 ; WX 278 ; N Icircumflex ; B 100 0 454 940 ;
+C -1 ; WX 278 ; N Idieresis ; B 100 0 467 907 ;
+C -1 ; WX 278 ; N Igrave ; B 100 0 378 939 ;
+C -1 ; WX 722 ; N Ntilde ; B 76 0 801 915 ;
+C -1 ; WX 778 ; N Oacute ; B 104 -23 828 939 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 104 -23 828 940 ;
+C -1 ; WX 778 ; N Odieresis ; B 104 -23 828 907 ;
+C -1 ; WX 778 ; N Ograve ; B 104 -23 828 939 ;
+C -1 ; WX 778 ; N Otilde ; B 104 -23 828 915 ;
+C -1 ; WX 667 ; N Scaron ; B 89 -23 714 939 ;
+C -1 ; WX 667 ; N Thorn ; B 91 0 707 729 ;
+C -1 ; WX 722 ; N Uacute ; B 124 -23 800 939 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 124 -23 800 940 ;
+C -1 ; WX 722 ; N Udieresis ; B 124 -23 800 907 ;
+C -1 ; WX 722 ; N Ugrave ; B 124 -23 800 939 ;
+C -1 ; WX 667 ; N Yacute ; B 168 0 816 944 ;
+C -1 ; WX 667 ; N Ydieresis ; B 168 0 816 907 ;
+C -1 ; WX 611 ; N Zcaron ; B 28 0 737 939 ;
+C -1 ; WX 556 ; N aacute ; B 65 -23 570 740 ;
+C -1 ; WX 556 ; N acircumflex ; B 65 -23 568 741 ;
+C -1 ; WX 556 ; N adieresis ; B 65 -23 568 708 ;
+C -1 ; WX 556 ; N agrave ; B 65 -23 568 740 ;
+C -1 ; WX 556 ; N aring ; B 65 -23 568 741 ;
+C -1 ; WX 556 ; N atilde ; B 65 -23 583 716 ;
+C -1 ; WX 260 ; N brokenbar ; B 54 -215 315 729 ;
+C -1 ; WX 500 ; N ccedilla ; B 76 -214 554 540 ;
+C -1 ; WX 737 ; N copyright ; B 55 -23 836 741 ;
+C -1 ; WX 400 ; N degree ; B 165 409 472 709 ;
+C -1 ; WX 584 ; N divide ; B 92 -10 591 474 ;
+C -1 ; WX 556 ; N eacute ; B 84 -23 580 740 ;
+C -1 ; WX 556 ; N ecircumflex ; B 84 -23 580 741 ;
+C -1 ; WX 556 ; N edieresis ; B 84 -23 580 708 ;
+C -1 ; WX 556 ; N egrave ; B 84 -23 580 740 ;
+C -1 ; WX 556 ; N eth ; B 80 -23 572 729 ;
+C -1 ; WX 278 ; N iacute ; B 94 0 431 740 ;
+C -1 ; WX 278 ; N icircumflex ; B 94 0 406 741 ;
+C -1 ; WX 278 ; N idieresis ; B 94 0 419 708 ;
+C -1 ; WX 278 ; N igrave ; B 94 0 330 740 ;
+C -1 ; WX 584 ; N logicalnot ; B 99 82 619 352 ;
+C -1 ; WX 584 ; N minus ; B 81 194 601 270 ;
+C -1 ; WX 556 ; N mu ; B 18 -219 594 525 ;
+C -1 ; WX 584 ; N multiply ; B 59 -10 625 476 ;
+C -1 ; WX 556 ; N ntilde ; B 70 0 589 716 ;
+C -1 ; WX 556 ; N oacute ; B 80 -23 576 740 ;
+C -1 ; WX 556 ; N ocircumflex ; B 80 -23 576 741 ;
+C -1 ; WX 556 ; N odieresis ; B 80 -23 576 708 ;
+C -1 ; WX 556 ; N ograve ; B 80 -23 576 740 ;
+C -1 ; WX 834 ; N onehalf ; B 116 -21 869 709 ;
+C -1 ; WX 834 ; N onequarter ; B 147 -21 836 709 ;
+C -1 ; WX 333 ; N onesuperior ; B 184 284 370 709 ;
+C -1 ; WX 556 ; N otilde ; B 80 -23 583 716 ;
+C -1 ; WX 584 ; N plusminus ; B 40 0 621 618 ;
+C -1 ; WX 737 ; N registered ; B 55 -23 836 741 ;
+C -1 ; WX 500 ; N scaron ; B 61 -24 547 740 ;
+C -1 ; WX 556 ; N thorn ; B 7 -219 588 729 ;
+C -1 ; WX 834 ; N threequarters ; B 114 -21 868 709 ;
+C -1 ; WX 333 ; N threesuperior ; B 96 270 435 709 ;
+C -1 ; WX 1000 ; N trademark ; B 208 320 1096 741 ;
+C -1 ; WX 333 ; N twosuperior ; B 71 284 447 710 ;
+C -1 ; WX 556 ; N uacute ; B 88 -23 594 740 ;
+C -1 ; WX 556 ; N ucircumflex ; B 88 -23 594 741 ;
+C -1 ; WX 556 ; N udieresis ; B 88 -23 594 708 ;
+C -1 ; WX 556 ; N ugrave ; B 88 -23 594 740 ;
+C -1 ; WX 500 ; N yacute ; B 8 -219 590 740 ;
+C -1 ; WX 500 ; N ydieresis ; B 8 -219 590 708 ;
+C -1 ; WX 500 ; N zcaron ; B 31 0 557 740 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 98
+
+KPX A y -9
+KPX A w -18
+KPX A v -18
+KPX A space -37
+KPX A quoteright -37
+KPX A Y -74
+KPX A W -18
+KPX A V -55
+KPX A T -74
+
+KPX F space -18
+KPX F period -129
+KPX F comma -129
+KPX F A -74
+
+KPX L y -18
+KPX L space -18
+KPX L quoteright -55
+KPX L Y -92
+KPX L W -37
+KPX L V -55
+KPX L T -74
+
+KPX P space -37
+KPX P period -129
+KPX P comma -129
+KPX P A -74
+
+KPX R Y -37
+KPX R W -18
+KPX R V -18
+KPX R T -18
+
+KPX T y -74
+KPX T w -74
+KPX T u -74
+KPX T semicolon -74
+KPX T s -92
+KPX T r -74
+KPX T period -92
+KPX T o -92
+KPX T i -9
+KPX T hyphen -92
+KPX T e -92
+KPX T comma -92
+KPX T colon -74
+KPX T c -92
+KPX T a -92
+KPX T O -18
+KPX T A -74
+
+KPX V y -18
+KPX V u -18
+KPX V semicolon -18
+KPX V r -18
+KPX V period -74
+KPX V o -37
+KPX V i -18
+KPX V hyphen -37
+KPX V e -37
+KPX V comma -74
+KPX V colon -18
+KPX V a -37
+KPX V A -55
+
+KPX W period -37
+KPX W i -9
+KPX W hyphen -18
+KPX W e -18
+KPX W comma -37
+KPX W a -18
+KPX W A -18
+
+KPX Y v -37
+KPX Y u -37
+KPX Y space -18
+KPX Y semicolon -37
+KPX Y q -55
+KPX Y period -92
+KPX Y p -55
+KPX Y o -55
+KPX Y i -18
+KPX Y hyphen -74
+KPX Y e -55
+KPX Y comma -92
+KPX Y colon -37
+KPX Y a -74
+KPX Y A -55
+
+KPX f quoteright 37
+
+KPX one one -74
+
+KPX quoteleft quoteleft -37
+
+KPX quoteright space -55
+KPX quoteright s -18
+KPX quoteright quoteright -37
+
+KPX r quoteright 37
+KPX r period -37
+KPX r hyphen -18
+KPX r comma -55
+
+KPX space Y -18
+KPX space A -37
+
+KPX v period -74
+KPX v comma -74
+
+KPX w period -55
+KPX w comma -55
+
+KPX y period -74
+KPX y comma -74
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 204 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 83 0 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 167 204 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 83 0 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 194 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 83 0 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 167 204 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 83 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 194 204 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 194 204 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 194 204 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 194 204 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 111 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 111 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 111 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 111 0 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute -27 204 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -27 204 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -27 204 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave -27 204 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 167 204 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 167 204 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 167 204 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 167 204 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 111 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 111 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 111 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 111 0 ;
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 167 204 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 167 204 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 167 204 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 167 204 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 111 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 111 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 111 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 111 0 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 222 204 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 222 204 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 222 204 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 222 204 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 111 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 111 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 111 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 111 0 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 167 204 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 111 0 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 194 204 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 111 0 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 222 204 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 111 0 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 167 204 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 111 0 ;
+EndComposites
+EndFontMetrics
diff --git a/misc/afm/TimesBo.afm b/misc/afm/TimesBo.afm
new file mode 100644
index 0000000000..a821d74c50
--- /dev/null
+++ b/misc/afm/TimesBo.afm
@@ -0,0 +1,454 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1984 Adobe Systems Incorporated. 	All Rights Reserved.
+Comment Creation Date:Tue Aug 5 11:02:18 PDT 1986
+FontName Times-Bold
+EncodingScheme AdobeStandardEncoding
+FullName Times Bold
+FamilyName Times
+Weight Bold
+ItalicAngle 0.0
+IsFixedPitch false
+UnderlinePosition -99
+UnderlineThickness 95
+Version 001.001
+Notice Times is a trademark of Allied Corporation.
+FontBBox -172 -256 1008 965
+CapHeight 681
+XHeight 460
+Descender -210
+Ascender 670
+StartCharMetrics 228
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 84 -18 248 690 ;
+C 34 ; WX 555 ; N quotedbl ; B 67 371 425 690 ;
+C 35 ; WX 500 ; N numbersign ; B -13 -17 514 684 ;
+C 36 ; WX 500 ; N dollar ; B 28 -116 474 732 ;
+C 37 ; WX 1000 ; N percent ; B 122 -11 881 692 ;
+C 38 ; WX 833 ; N ampersand ; B 54 -17 773 690 ;
+C 39 ; WX 333 ; N quoteright ; B 77 347 257 680 ;
+C 40 ; WX 333 ; N parenleft ; B 49 -169 301 699 ;
+C 41 ; WX 333 ; N parenright ; B 26 -169 278 699 ;
+C 42 ; WX 500 ; N asterisk ; B 57 262 445 690 ;
+C 43 ; WX 570 ; N plus ; B 50 -10 520 460 ;
+C 44 ; WX 250 ; N comma ; B 37 -181 214 157 ;
+C 45 ; WX 333 ; N hyphen ; B 48 170 283 285 ;
+C 46 ; WX 250 ; N period ; B 43 -19 207 145 ;
+C 47 ; WX 278 ; N slash ; B 1 -17 279 750 ;
+C 48 ; WX 500 ; N zero ; B 26 -18 472 690 ;
+C 49 ; WX 500 ; N one ; B 61 0 448 690 ;
+C 50 ; WX 500 ; N two ; B 18 0 473 683 ;
+C 51 ; WX 500 ; N three ; B 17 -19 463 683 ;
+C 52 ; WX 500 ; N four ; B 23 0 472 681 ;
+C 53 ; WX 500 ; N five ; B 23 -17 465 681 ;
+C 54 ; WX 500 ; N six ; B 30 -18 470 684 ;
+C 55 ; WX 500 ; N seven ; B 23 0 468 679 ;
+C 56 ; WX 500 ; N eight ; B 22 -17 470 685 ;
+C 57 ; WX 500 ; N nine ; B 26 -18 468 684 ;
+C 58 ; WX 333 ; N colon ; B 83 -18 247 473 ;
+C 59 ; WX 333 ; N semicolon ; B 85 -181 262 472 ;
+C 60 ; WX 570 ; N less ; B 45 -10 520 460 ;
+C 61 ; WX 570 ; N equal ; B 50 91 520 375 ;
+C 62 ; WX 570 ; N greater ; B 50 -10 525 460 ;
+C 63 ; WX 500 ; N question ; B 57 -17 438 681 ;
+C 64 ; WX 930 ; N at ; B 50 -147 889 677 ;
+C 65 ; WX 722 ; N A ; B 22 0 696 681 ;
+C 66 ; WX 667 ; N B ; B 24 0 609 681 ;
+C 67 ; WX 722 ; N C ; B 42 -17 669 690 ;
+C 68 ; WX 722 ; N D ; B 22 0 684 681 ;
+C 69 ; WX 667 ; N E ; B 21 0 637 681 ;
+C 70 ; WX 611 ; N F ; B 17 0 582 681 ;
+C 71 ; WX 778 ; N G ; B 41 -17 748 690 ;
+C 72 ; WX 778 ; N H ; B 26 0 748 681 ;
+C 73 ; WX 389 ; N I ; B 17 0 366 680 ;
+C 74 ; WX 500 ; N J ; B 9 -89 475 681 ;
+C 75 ; WX 778 ; N K ; B 29 0 761 681 ;
+C 76 ; WX 667 ; N L ; B 21 0 633 681 ;
+C 77 ; WX 944 ; N M ; B 21 0 914 681 ;
+C 78 ; WX 722 ; N N ; B 20 -10 697 681 ;
+C 79 ; WX 778 ; N O ; B 43 -18 733 690 ;
+C 80 ; WX 611 ; N P ; B 24 0 593 681 ;
+C 81 ; WX 778 ; N Q ; B 24 -182 751 690 ;
+C 82 ; WX 722 ; N R ; B 26 0 695 681 ;
+C 83 ; WX 556 ; N S ; B 43 -19 506 690 ;
+C 84 ; WX 667 ; N T ; B 30 0 629 681 ;
+C 85 ; WX 722 ; N U ; B 20 -19 700 681 ;
+C 86 ; WX 722 ; N V ; B 22 -18 696 681 ;
+C 87 ; WX 1000 ; N W ; B 19 -18 979 680 ;
+C 88 ; WX 722 ; N X ; B 23 0 695 681 ;
+C 89 ; WX 722 ; N Y ; B 19 0 697 680 ;
+C 90 ; WX 667 ; N Z ; B 37 0 624 681 ;
+C 91 ; WX 333 ; N bracketleft ; B 73 -142 296 674 ;
+C 92 ; WX 278 ; N backslash ; B 1 -17 279 750 ;
+C 93 ; WX 333 ; N bracketright ; B 38 -142 261 674 ;
+C 94 ; WX 581 ; N asciicircum ; B 102 290 486 690 ;
+C 95 ; WX 500 ; N underscore ; B -2 -256 502 -182 ;
+C 96 ; WX 333 ; N quoteleft ; B 72 357 252 691 ;
+C 97 ; WX 500 ; N a ; B 25 -19 484 472 ;
+C 98 ; WX 556 ; N b ; B 29 -18 512 670 ;
+C 99 ; WX 444 ; N c ; B 24 -17 423 472 ;
+C 100 ; WX 556 ; N d ; B 31 -17 523 670 ;
+C 101 ; WX 444 ; N e ; B 25 -18 415 474 ;
+C 102 ; WX 333 ; N f ; B 20 0 386 690 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B 25 -210 474 472 ;
+C 104 ; WX 556 ; N h ; B 29 0 523 670 ;
+C 105 ; WX 278 ; N i ; B 27 0 249 690 ;
+C 106 ; WX 333 ; N j ; B -57 -212 256 690 ;
+C 107 ; WX 556 ; N k ; B 24 0 528 670 ;
+C 108 ; WX 278 ; N l ; B 25 0 247 670 ;
+C 109 ; WX 833 ; N m ; B 28 0 804 471 ;
+C 110 ; WX 556 ; N n ; B 28 0 523 473 ;
+C 111 ; WX 500 ; N o ; B 25 -18 473 472 ;
+C 112 ; WX 556 ; N p ; B 30 -210 513 473 ;
+C 113 ; WX 556 ; N q ; B 32 -210 535 472 ;
+C 114 ; WX 444 ; N r ; B 29 0 417 473 ;
+C 115 ; WX 389 ; N s ; B 29 -17 359 472 ;
+C 116 ; WX 333 ; N t ; B 22 -19 320 627 ;
+C 117 ; WX 556 ; N u ; B 23 -17 524 460 ;
+C 118 ; WX 500 ; N v ; B 20 -14 479 460 ;
+C 119 ; WX 722 ; N w ; B 10 -14 709 460 ;
+C 120 ; WX 500 ; N x ; B 11 0 488 460 ;
+C 121 ; WX 500 ; N y ; B 19 -212 475 460 ;
+C 122 ; WX 444 ; N z ; B 25 0 414 460 ;
+C 123 ; WX 394 ; N braceleft ; B 44 -142 342 674 ;
+C 124 ; WX 220 ; N bar ; B 77 -195 151 720 ;
+C 125 ; WX 394 ; N braceright ; B 38 -142 336 674 ;
+C 126 ; WX 520 ; N asciitilde ; B 19 237 493 461 ;
+C 161 ; WX 333 ; N exclamdown ; B 85 -210 249 498 ;
+C 162 ; WX 500 ; N cent ; B 44 -148 460 586 ;
+C 163 ; WX 500 ; N sterling ; B 25 -17 471 682 ;
+C 164 ; WX 167 ; N fraction ; B -172 -17 335 690 ;
+C 165 ; WX 500 ; N yen ; B -20 0 521 681 ;
+C 166 ; WX 500 ; N florin ; B 2 -157 496 713 ;
+C 167 ; WX 500 ; N section ; B 63 -148 438 677 ;
+C 168 ; WX 500 ; N currency ; B 3 105 498 604 ;
+C 169 ; WX 278 ; N quotesingle ; B 69 371 205 690 ;
+C 170 ; WX 500 ; N quotedblleft ; B 33 346 479 679 ;
+C 171 ; WX 500 ; N guillemotleft ; B 25 44 471 436 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 51 44 302 436 ;
+C 173 ; WX 333 ; N guilsinglright ; B 26 44 277 436 ;
+C 174 ; WX 556 ; N fi ; B 24 0 532 690 ;
+C 175 ; WX 556 ; N fl ; B 25 0 529 691 ;
+C 177 ; WX 500 ; N endash ; B -4 179 500 270 ;
+C 178 ; WX 500 ; N dagger ; B 52 -141 446 690 ;
+C 179 ; WX 500 ; N daggerdbl ; B 57 -138 451 681 ;
+C 180 ; WX 250 ; N periodcentered ; B 43 270 167 394 ;
+C 182 ; WX 540 ; N paragraph ; B 30 -190 533 681 ;
+C 183 ; WX 350 ; N bullet ; B 50 175 300 425 ;
+C 184 ; WX 333 ; N quotesinglbase ; B 77 -179 257 154 ;
+C 185 ; WX 500 ; N quotedblbase ; B 31 -179 477 154 ;
+C 186 ; WX 500 ; N quotedblright ; B 31 347 477 680 ;
+C 187 ; WX 500 ; N guillemotright ; B 24 44 470 436 ;
+C 188 ; WX 1000 ; N ellipsis ; B 85 -18 915 146 ;
+C 189 ; WX 1000 ; N perthousand ; B 1 -55 993 718 ;
+C 191 ; WX 500 ; N questiondown ; B 56 -210 437 488 ;
+C 193 ; WX 333 ; N grave ; B 26 523 242 695 ;
+C 194 ; WX 333 ; N acute ; B 83 523 299 695 ;
+C 195 ; WX 333 ; N circumflex ; B 28 520 304 690 ;
+C 196 ; WX 333 ; N tilde ; B 34 559 298 671 ;
+C 197 ; WX 333 ; N macron ; B 34 543 297 600 ;
+C 198 ; WX 333 ; N breve ; B 32 529 300 667 ;
+C 199 ; WX 333 ; N dotaccent ; B 112 515 222 625 ;
+C 200 ; WX 333 ; N dieresis ; B 33 556 297 652 ;
+C 202 ; WX 333 ; N ring ; B 55 522 279 746 ;
+C 203 ; WX 333 ; N cedilla ; B 42 -211 293 -10 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 32 539 320 753 ;
+C 206 ; WX 333 ; N ogonek ; B 60 -179 277 70 ;
+C 207 ; WX 333 ; N caron ; B 32 520 298 690 ;
+C 208 ; WX 1000 ; N emdash ; B -2 185 1008 280 ;
+C 225 ; WX 1000 ; N AE ; B 19 0 954 681 ;
+C 227 ; WX 300 ; N ordfeminine ; B 12 286 288 685 ;
+C 232 ; WX 667 ; N Lslash ; B 0 0 612 681 ;
+C 233 ; WX 778 ; N Oslash ; B 45 -75 735 740 ;
+C 234 ; WX 1000 ; N OE ; B 24 -7 979 683 ;
+C 235 ; WX 330 ; N ordmasculine ; B 31 286 299 685 ;
+C 241 ; WX 722 ; N ae ; B 30 -17 691 474 ;
+C 245 ; WX 278 ; N dotlessi ; B 28 0 250 460 ;
+C 248 ; WX 278 ; N lslash ; B 0 0 326 670 ;
+C 249 ; WX 500 ; N oslash ; B 27 -95 474 550 ;
+C 250 ; WX 722 ; N oe ; B 26 -17 689 473 ;
+C 251 ; WX 556 ; N germandbls ; B 22 -18 513 689 ;
+C -1 ; WX 722 ; N Aacute ; B 22 0 696 914 ;
+C -1 ; WX 722 ; N Acircumflex ; B 22 0 696 909 ;
+C -1 ; WX 722 ; N Adieresis ; B 22 0 696 871 ;
+C -1 ; WX 722 ; N Agrave ; B 22 0 696 914 ;
+C -1 ; WX 722 ; N Aring ; B 22 0 696 965 ;
+C -1 ; WX 722 ; N Atilde ; B 22 0 696 890 ;
+C -1 ; WX 722 ; N Ccedilla ; B 42 -211 669 690 ;
+C -1 ; WX 667 ; N Eacute ; B 21 0 637 914 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 21 0 637 909 ;
+C -1 ; WX 667 ; N Edieresis ; B 21 0 637 871 ;
+C -1 ; WX 667 ; N Egrave ; B 21 0 637 914 ;
+C -1 ; WX 722 ; N Eth ; B 22 0 685 681 ;
+C -1 ; WX 389 ; N Iacute ; B 17 0 366 914 ;
+C -1 ; WX 389 ; N Icircumflex ; B 17 0 366 909 ;
+C -1 ; WX 389 ; N Idieresis ; B 17 0 366 871 ;
+C -1 ; WX 389 ; N Igrave ; B 17 0 366 914 ;
+C -1 ; WX 722 ; N Ntilde ; B 20 -10 697 890 ;
+C -1 ; WX 778 ; N Oacute ; B 43 -18 733 914 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 43 -18 733 909 ;
+C -1 ; WX 778 ; N Odieresis ; B 43 -18 733 871 ;
+C -1 ; WX 778 ; N Ograve ; B 43 -18 733 914 ;
+C -1 ; WX 778 ; N Otilde ; B 43 -18 733 890 ;
+C -1 ; WX 556 ; N Scaron ; B 43 -19 506 909 ;
+C -1 ; WX 611 ; N Thorn ; B 24 0 594 681 ;
+C -1 ; WX 722 ; N Uacute ; B 20 -19 700 914 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 20 -19 700 909 ;
+C -1 ; WX 722 ; N Udieresis ; B 20 -19 700 871 ;
+C -1 ; WX 722 ; N Ugrave ; B 20 -19 700 914 ;
+C -1 ; WX 722 ; N Yacute ; B 19 0 697 916 ;
+C -1 ; WX 722 ; N Ydieresis ; B 19 0 697 871 ;
+C -1 ; WX 667 ; N Zcaron ; B 37 0 624 909 ;
+C -1 ; WX 500 ; N aacute ; B 25 -19 484 695 ;
+C -1 ; WX 500 ; N acircumflex ; B 25 -19 484 690 ;
+C -1 ; WX 500 ; N adieresis ; B 25 -19 484 652 ;
+C -1 ; WX 500 ; N agrave ; B 25 -19 484 695 ;
+C -1 ; WX 500 ; N aring ; B 25 -19 484 746 ;
+C -1 ; WX 500 ; N atilde ; B 25 -19 484 671 ;
+C -1 ; WX 220 ; N brokenbar ; B 77 -195 151 720 ;
+C -1 ; WX 444 ; N ccedilla ; B 24 -211 423 472 ;
+C -1 ; WX 747 ; N copyright ; B 16 -17 730 690 ;
+C -1 ; WX 400 ; N degree ; B 50 390 350 690 ;
+C -1 ; WX 570 ; N divide ; B 50 -10 520 460 ;
+C -1 ; WX 444 ; N eacute ; B 25 -18 415 695 ;
+C -1 ; WX 444 ; N ecircumflex ; B 25 -18 415 690 ;
+C -1 ; WX 444 ; N edieresis ; B 25 -18 415 652 ;
+C -1 ; WX 444 ; N egrave ; B 25 -18 415 695 ;
+C -1 ; WX 500 ; N eth ; B 26 -17 474 670 ;
+C -1 ; WX 278 ; N iacute ; B 28 0 265 695 ;
+C -1 ; WX 278 ; N icircumflex ; B -6 0 270 690 ;
+C -1 ; WX 278 ; N idieresis ; B -1 0 263 652 ;
+C -1 ; WX 278 ; N igrave ; B -8 0 250 695 ;
+C -1 ; WX 570 ; N logicalnot ; B 50 94 520 375 ;
+C -1 ; WX 570 ; N minus ; B 50 188 520 262 ;
+C -1 ; WX 556 ; N mu ; B 23 -210 524 460 ;
+C -1 ; WX 570 ; N multiply ; B 50 -10 520 460 ;
+C -1 ; WX 556 ; N ntilde ; B 28 0 523 671 ;
+C -1 ; WX 500 ; N oacute ; B 25 -18 473 695 ;
+C -1 ; WX 500 ; N ocircumflex ; B 25 -18 473 690 ;
+C -1 ; WX 500 ; N odieresis ; B 25 -18 473 652 ;
+C -1 ; WX 500 ; N ograve ; B 25 -18 473 695 ;
+C -1 ; WX 750 ; N onehalf ; B 30 -18 720 690 ;
+C -1 ; WX 750 ; N onequarter ; B 30 -18 720 690 ;
+C -1 ; WX 300 ; N onesuperior ; B 24 276 275 690 ;
+C -1 ; WX 500 ; N otilde ; B 25 -18 473 671 ;
+C -1 ; WX 570 ; N plusminus ; B 50 0 520 600 ;
+C -1 ; WX 747 ; N registered ; B 16 -17 730 690 ;
+C -1 ; WX 389 ; N scaron ; B 29 -17 359 690 ;
+C -1 ; WX 556 ; N thorn ; B 30 -210 513 670 ;
+C -1 ; WX 750 ; N threequarters ; B 30 -18 720 690 ;
+C -1 ; WX 300 ; N threesuperior ; B 5 269 294 690 ;
+C -1 ; WX 1000 ; N trademark ; B 30 277 970 681 ;
+C -1 ; WX 300 ; N twosuperior ; B 2 276 298 686 ;
+C -1 ; WX 556 ; N uacute ; B 23 -17 524 695 ;
+C -1 ; WX 556 ; N ucircumflex ; B 23 -17 524 690 ;
+C -1 ; WX 556 ; N udieresis ; B 23 -17 524 652 ;
+C -1 ; WX 556 ; N ugrave ; B 23 -17 524 695 ;
+C -1 ; WX 500 ; N yacute ; B 19 -212 475 695 ;
+C -1 ; WX 500 ; N ydieresis ; B 19 -212 475 652 ;
+C -1 ; WX 444 ; N zcaron ; B 25 0 414 690 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 124
+
+KPX A y -74
+KPX A w -74
+KPX A v -74
+KPX A space -55
+KPX A quoteright -74
+KPX A Y -92
+KPX A W -111
+KPX A V -129
+KPX A T -74
+
+KPX F space -37
+KPX F period -92
+KPX F comma -92
+KPX F A -74
+
+KPX L y -55
+KPX L space -55
+KPX L quoteright -92
+KPX L Y -92
+KPX L W -92
+KPX L V -92
+KPX L T -92
+
+KPX P space -55
+KPX P period -92
+KPX P comma -92
+KPX P A -74
+
+KPX R y -35
+KPX R Y -35
+KPX R W -35
+KPX R V -35
+KPX R T -35
+
+KPX T y -74
+KPX T w -74
+KPX T u -92
+KPX T space -18
+KPX T semicolon -74
+KPX T s -92
+KPX T r -74
+KPX T period -74
+KPX T o -92
+KPX T i -18
+KPX T hyphen -92
+KPX T e -92
+KPX T comma -74
+KPX T colon -74
+KPX T c -92
+KPX T a -92
+KPX T O -18
+KPX T A -74
+
+KPX V y -92
+KPX V u -92
+KPX V space -18
+KPX V semicolon -92
+KPX V r -74
+KPX V period -129
+KPX V o -92
+KPX V i -37
+KPX V hyphen -74
+KPX V e -92
+KPX V comma -129
+KPX V colon -92
+KPX V a -92
+KPX V O -20
+KPX V A -129
+
+KPX W y -37
+KPX W u -18
+KPX W space -18
+KPX W semicolon -55
+KPX W r -18
+KPX W period -92
+KPX W o -55
+KPX W i -18
+KPX W hyphen -37
+KPX W e -55
+KPX W comma -92
+KPX W colon -55
+KPX W a -55
+KPX W A -111
+
+KPX Y v -111
+KPX Y u -92
+KPX Y space -37
+KPX Y semicolon -92
+KPX Y q -111
+KPX Y period -92
+KPX Y p -92
+KPX Y o -111
+KPX Y i -37
+KPX Y hyphen -92
+KPX Y e -111
+KPX Y comma -92
+KPX Y colon -92
+KPX Y a -111
+KPX Y A -92
+
+KPX f quoteright 55
+KPX f f 0
+
+KPX one one -55
+
+KPX quoteleft quoteleft -74
+
+KPX quoteright space -74
+KPX quoteright s -37
+KPX quoteright quoteright -74
+
+KPX r z 0
+KPX r y 0
+KPX r x 0
+KPX r w 0
+KPX r t 0
+KPX r space -18
+KPX r quoteright 18
+KPX r q -18
+KPX r period -92
+KPX r o -18
+KPX r hyphen -37
+KPX r h 0
+KPX r e -18
+KPX r comma -92
+KPX r c -18
+
+KPX space Y -37
+KPX space W -18
+KPX space V -18
+KPX space T -18
+KPX space A -55
+
+KPX v period -55
+KPX v comma -55
+
+KPX w period -55
+KPX w comma -55
+
+KPX y period -55
+KPX y comma -55
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 167 219 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 55 0 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 111 219 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 207 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 68 0 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 194 219 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 83 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 221 219 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 221 219 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 221 219 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 221 219 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 104 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 104 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 104 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 104 0 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 28 219 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 28 219 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 28 219 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 28 219 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -34 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -34 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -34 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -34 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 174 219 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 174 219 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 174 219 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 174 219 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 61 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 61 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 61 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 61 0 ;
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 187 219 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 187 219 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 187 219 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 187 219 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 76 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 76 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 76 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 76 0 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 222 219 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 222 219 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 222 219 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 222 219 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 83 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 83 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 83 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 83 0 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 187 219 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 76 0 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 194 219 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 111 0 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 222 219 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 83 0 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 187 219 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 76 0 ;
+EndComposites
+EndFontMetrics
diff --git a/misc/afm/TimesBoO.afm b/misc/afm/TimesBoO.afm
new file mode 100644
index 0000000000..cf4ca76a17
--- /dev/null
+++ b/misc/afm/TimesBoO.afm
@@ -0,0 +1,438 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1984 Adobe Systems Incorporated. 	All Rights Reserved.
+Comment Creation Date:Tue Aug 5 11:23:15 PDT 1986
+FontName Times-BoldItalic
+EncodingScheme AdobeStandardEncoding
+FullName Times Bold Italic
+FamilyName Times
+Weight Bold
+ItalicAngle -15.0
+IsFixedPitch false
+UnderlinePosition -98
+UnderlineThickness 54
+Version 001.001
+Notice Times is a trademark of Allied Corporation.
+FontBBox -168 -232 1014 894
+CapHeight 662
+XHeight 458
+Descender -203
+Ascender 682
+StartCharMetrics 228
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 389 ; N exclam ; B 66 -13 367 676 ;
+C 34 ; WX 555 ; N quotedbl ; B 142 367 549 693 ;
+C 35 ; WX 500 ; N numbersign ; B 4 0 496 662 ;
+C 36 ; WX 500 ; N dollar ; B -20 -101 492 723 ;
+C 37 ; WX 833 ; N percent ; B 39 -8 784 685 ;
+C 38 ; WX 778 ; N ampersand ; B 41 -19 727 676 ;
+C 39 ; WX 333 ; N quoteright ; B 80 362 282 675 ;
+C 40 ; WX 333 ; N parenleft ; B 28 -179 340 676 ;
+C 41 ; WX 333 ; N parenright ; B -44 -179 268 676 ;
+C 42 ; WX 500 ; N asterisk ; B 56 244 445 676 ;
+C 43 ; WX 570 ; N plus ; B 33 0 537 505 ;
+C 44 ; WX 250 ; N comma ; B -10 -181 192 132 ;
+C 45 ; WX 333 ; N hyphen ; B 33 167 299 282 ;
+C 46 ; WX 250 ; N period ; B 23 -13 170 133 ;
+C 47 ; WX 278 ; N slash ; B -11 -18 289 682 ;
+C 48 ; WX 500 ; N zero ; B 17 -13 472 676 ;
+C 49 ; WX 500 ; N one ; B 5 0 415 676 ;
+C 50 ; WX 500 ; N two ; B -27 0 441 676 ;
+C 51 ; WX 500 ; N three ; B -15 -13 445 676 ;
+C 52 ; WX 500 ; N four ; B -15 0 498 676 ;
+C 53 ; WX 500 ; N five ; B -11 -13 482 662 ;
+C 54 ; WX 500 ; N six ; B 23 -13 504 676 ;
+C 55 ; WX 500 ; N seven ; B 51 0 519 662 ;
+C 56 ; WX 500 ; N eight ; B 3 -13 471 676 ;
+C 57 ; WX 500 ; N nine ; B -12 -13 470 676 ;
+C 58 ; WX 333 ; N colon ; B 52 -13 291 458 ;
+C 59 ; WX 333 ; N semicolon ; B 13 -181 291 458 ;
+C 60 ; WX 570 ; N less ; B 31 -14 540 524 ;
+C 61 ; WX 570 ; N equal ; B 33 116 537 401 ;
+C 62 ; WX 570 ; N greater ; B 31 -14 540 524 ;
+C 63 ; WX 500 ; N question ; B 78 -13 465 676 ;
+C 64 ; WX 832 ; N at ; B -9 -150 838 691 ;
+C 65 ; WX 667 ; N A ; B -51 0 602 676 ;
+C 66 ; WX 667 ; N B ; B -24 0 618 662 ;
+C 67 ; WX 667 ; N C ; B 22 -18 660 677 ;
+C 68 ; WX 722 ; N D ; B -31 0 693 662 ;
+C 69 ; WX 667 ; N E ; B -27 0 646 662 ;
+C 70 ; WX 667 ; N F ; B -20 0 646 662 ;
+C 71 ; WX 722 ; N G ; B 21 -18 699 676 ;
+C 72 ; WX 778 ; N H ; B -24 0 791 662 ;
+C 73 ; WX 389 ; N I ; B -22 0 412 662 ;
+C 74 ; WX 500 ; N J ; B -45 -98 519 662 ;
+C 75 ; WX 667 ; N K ; B -31 0 685 662 ;
+C 76 ; WX 611 ; N L ; B -22 0 584 662 ;
+C 77 ; WX 889 ; N M ; B -29 -12 907 662 ;
+C 78 ; WX 722 ; N N ; B -27 -18 740 662 ;
+C 79 ; WX 722 ; N O ; B 27 -18 684 676 ;
+C 80 ; WX 611 ; N P ; B -27 0 608 662 ;
+C 81 ; WX 722 ; N Q ; B 27 -203 684 676 ;
+C 82 ; WX 667 ; N R ; B -29 0 616 662 ;
+C 83 ; WX 556 ; N S ; B 6 -18 524 676 ;
+C 84 ; WX 611 ; N T ; B 39 0 632 662 ;
+C 85 ; WX 722 ; N U ; B 66 -18 736 662 ;
+C 86 ; WX 667 ; N V ; B 48 -18 692 662 ;
+C 87 ; WX 889 ; N W ; B 48 -18 914 662 ;
+C 88 ; WX 667 ; N X ; B -24 0 687 662 ;
+C 89 ; WX 611 ; N Y ; B 46 0 625 662 ;
+C 90 ; WX 611 ; N Z ; B -1 0 594 662 ;
+C 91 ; WX 333 ; N bracketleft ; B -7 -157 388 682 ;
+C 92 ; WX 278 ; N backslash ; B 1 0 465 682 ;
+C 93 ; WX 333 ; N bracketright ; B -65 -157 330 682 ;
+C 94 ; WX 570 ; N asciicircum ; B 34 259 536 662 ;
+C 95 ; WX 500 ; N underscore ; B 0 -127 500 -89 ;
+C 96 ; WX 333 ; N quoteleft ; B 117 363 319 676 ;
+C 97 ; WX 500 ; N a ; B 9 -14 480 458 ;
+C 98 ; WX 500 ; N b ; B 21 -13 474 682 ;
+C 99 ; WX 444 ; N c ; B 25 -13 418 458 ;
+C 100 ; WX 500 ; N d ; B 9 -13 541 682 ;
+C 101 ; WX 444 ; N e ; B 25 -13 413 458 ;
+C 102 ; WX 333 ; N f ; B -146 -203 460 682 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B -27 -203 498 458 ;
+C 104 ; WX 556 ; N h ; B 12 -13 518 682 ;
+C 105 ; WX 278 ; N i ; B 25 -13 284 676 ;
+C 106 ; WX 278 ; N j ; B -152 -203 311 676 ;
+C 107 ; WX 500 ; N k ; B 10 -13 511 682 ;
+C 108 ; WX 278 ; N l ; B 31 -13 312 682 ;
+C 109 ; WX 778 ; N m ; B 16 -13 744 458 ;
+C 110 ; WX 556 ; N n ; B 24 -13 518 458 ;
+C 111 ; WX 500 ; N o ; B 27 -13 467 458 ;
+C 112 ; WX 500 ; N p ; B -79 -203 481 458 ;
+C 113 ; WX 500 ; N q ; B 21 -203 486 459 ;
+C 114 ; WX 389 ; N r ; B 9 0 415 458 ;
+C 115 ; WX 389 ; N s ; B 16 -13 364 459 ;
+C 116 ; WX 278 ; N t ; B 16 -14 305 592 ;
+C 117 ; WX 556 ; N u ; B 48 -13 521 458 ;
+C 118 ; WX 444 ; N v ; B 50 -13 432 458 ;
+C 119 ; WX 667 ; N w ; B 50 -13 642 458 ;
+C 120 ; WX 500 ; N x ; B -5 -13 498 458 ;
+C 121 ; WX 444 ; N y ; B -60 -203 423 458 ;
+C 122 ; WX 389 ; N z ; B -24 -58 394 448 ;
+C 123 ; WX 348 ; N braceleft ; B 31 -154 381 686 ;
+C 124 ; WX 220 ; N bar ; B 70 0 151 682 ;
+C 125 ; WX 348 ; N braceright ; B -31 -161 319 679 ;
+C 126 ; WX 570 ; N asciitilde ; B 33 158 537 353 ;
+C 161 ; WX 389 ; N exclamdown ; B 21 -232 321 458 ;
+C 162 ; WX 500 ; N cent ; B 50 -142 443 570 ;
+C 163 ; WX 500 ; N sterling ; B -32 -13 505 676 ;
+C 164 ; WX 167 ; N fraction ; B -161 0 327 662 ;
+C 165 ; WX 500 ; N yen ; B -15 0 565 662 ;
+C 166 ; WX 500 ; N florin ; B -86 -154 530 682 ;
+C 167 ; WX 500 ; N section ; B 36 -143 454 676 ;
+C 168 ; WX 500 ; N currency ; B -3 110 503 612 ;
+C 169 ; WX 278 ; N quotesingle ; B 126 367 295 693 ;
+C 170 ; WX 500 ; N quotedblleft ; B 57 363 513 676 ;
+C 171 ; WX 500 ; N guillemotleft ; B 21 33 474 416 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 42 33 310 416 ;
+C 173 ; WX 333 ; N guilsinglright ; B 23 38 291 421 ;
+C 174 ; WX 556 ; N fi ; B -157 -203 538 682 ;
+C 175 ; WX 556 ; N fl ; B -149 -203 577 682 ;
+C 177 ; WX 500 ; N endash ; B -11 176 511 266 ;
+C 178 ; WX 500 ; N dagger ; B 90 -146 489 676 ;
+C 179 ; WX 500 ; N daggerdbl ; B 11 -143 487 675 ;
+C 180 ; WX 250 ; N periodcentered ; B 51 179 200 328 ;
+C 182 ; WX 500 ; N paragraph ; B 61 -189 592 682 ;
+C 183 ; WX 350 ; N bullet ; B 50 175 300 425 ;
+C 184 ; WX 333 ; N quotesinglbase ; B 66 -181 268 132 ;
+C 185 ; WX 500 ; N quotedblbase ; B -57 -181 398 132 ;
+C 186 ; WX 500 ; N quotedblright ; B 56 362 509 675 ;
+C 187 ; WX 500 ; N guillemotright ; B 21 38 474 421 ;
+C 188 ; WX 1000 ; N ellipsis ; B 93 -13 906 133 ;
+C 189 ; WX 1000 ; N perthousand ; B 7 -49 985 699 ;
+C 191 ; WX 500 ; N questiondown ; B 30 -203 417 487 ;
+C 193 ; WX 333 ; N grave ; B 115 511 325 690 ;
+C 194 ; WX 333 ; N acute ; B 168 511 405 690 ;
+C 195 ; WX 333 ; N circumflex ; B 70 510 394 682 ;
+C 196 ; WX 333 ; N tilde ; B 69 530 424 648 ;
+C 197 ; WX 333 ; N macron ; B 81 547 420 616 ;
+C 198 ; WX 333 ; N breve ; B 99 511 414 671 ;
+C 199 ; WX 333 ; N dotaccent ; B 180 519 308 648 ;
+C 200 ; WX 333 ; N dieresis ; B 85 519 424 648 ;
+C 202 ; WX 333 ; N ring ; B 141 466 352 676 ;
+C 203 ; WX 333 ; N cedilla ; B 32 -216 264 5 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 28 538 339 750 ;
+C 206 ; WX 333 ; N ogonek ; B -37 -173 192 44 ;
+C 207 ; WX 333 ; N caron ; B 109 511 437 683 ;
+C 208 ; WX 1000 ; N emdash ; B -14 176 1014 266 ;
+C 225 ; WX 944 ; N AE ; B -41 0 931 662 ;
+C 227 ; WX 266 ; N ordfeminine ; B -24 286 291 676 ;
+C 232 ; WX 611 ; N Lslash ; B -22 0 584 662 ;
+C 233 ; WX 722 ; N Oslash ; B 27 -124 684 754 ;
+C 234 ; WX 944 ; N OE ; B 23 -8 936 670 ;
+C 235 ; WX 300 ; N ordmasculine ; B 1 286 300 676 ;
+C 241 ; WX 722 ; N ae ; B 15 -13 685 458 ;
+C 245 ; WX 278 ; N dotlessi ; B 27 -13 260 458 ;
+C 248 ; WX 278 ; N lslash ; B 12 -13 326 682 ;
+C 249 ; WX 500 ; N oslash ; B 27 -118 467 556 ;
+C 250 ; WX 722 ; N oe ; B 26 -13 687 458 ;
+C 251 ; WX 500 ; N germandbls ; B -168 -203 497 682 ;
+C -1 ; WX 667 ; N Aacute ; B -51 0 602 894 ;
+C -1 ; WX 667 ; N Acircumflex ; B -51 0 602 886 ;
+C -1 ; WX 667 ; N Adieresis ; B -51 0 602 852 ;
+C -1 ; WX 667 ; N Agrave ; B -51 0 602 894 ;
+C -1 ; WX 667 ; N Aring ; B -51 0 602 880 ;
+C -1 ; WX 667 ; N Atilde ; B -51 0 602 852 ;
+C -1 ; WX 667 ; N Ccedilla ; B 22 -216 660 677 ;
+C -1 ; WX 667 ; N Eacute ; B -27 0 646 894 ;
+C -1 ; WX 667 ; N Ecircumflex ; B -27 0 646 886 ;
+C -1 ; WX 667 ; N Edieresis ; B -27 0 646 852 ;
+C -1 ; WX 667 ; N Egrave ; B -27 0 646 894 ;
+C -1 ; WX 722 ; N Eth ; B -31 0 693 662 ;
+C -1 ; WX 389 ; N Iacute ; B -22 0 433 894 ;
+C -1 ; WX 389 ; N Icircumflex ; B -22 0 422 886 ;
+C -1 ; WX 389 ; N Idieresis ; B -22 0 452 852 ;
+C -1 ; WX 389 ; N Igrave ; B -22 0 412 894 ;
+C -1 ; WX 722 ; N Ntilde ; B -27 -18 740 852 ;
+C -1 ; WX 722 ; N Oacute ; B 27 -18 684 894 ;
+C -1 ; WX 722 ; N Ocircumflex ; B 27 -18 684 886 ;
+C -1 ; WX 722 ; N Odieresis ; B 27 -18 684 852 ;
+C -1 ; WX 722 ; N Ograve ; B 27 -18 684 894 ;
+C -1 ; WX 722 ; N Otilde ; B 27 -18 684 852 ;
+C -1 ; WX 556 ; N Scaron ; B 6 -18 549 887 ;
+C -1 ; WX 611 ; N Thorn ; B -27 0 572 662 ;
+C -1 ; WX 722 ; N Uacute ; B 66 -18 736 894 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 66 -18 736 886 ;
+C -1 ; WX 722 ; N Udieresis ; B 66 -18 736 852 ;
+C -1 ; WX 722 ; N Ugrave ; B 66 -18 736 894 ;
+C -1 ; WX 611 ; N Yacute ; B 46 0 625 894 ;
+C -1 ; WX 611 ; N Ydieresis ; B 46 0 625 852 ;
+C -1 ; WX 611 ; N Zcaron ; B -1 0 594 887 ;
+C -1 ; WX 500 ; N aacute ; B 9 -14 489 690 ;
+C -1 ; WX 500 ; N acircumflex ; B 9 -14 480 682 ;
+C -1 ; WX 500 ; N adieresis ; B 9 -14 508 648 ;
+C -1 ; WX 500 ; N agrave ; B 9 -14 480 690 ;
+C -1 ; WX 500 ; N aring ; B 9 -14 480 676 ;
+C -1 ; WX 500 ; N atilde ; B 9 -14 508 648 ;
+C -1 ; WX 220 ; N brokenbar ; B 70 0 151 682 ;
+C -1 ; WX 444 ; N ccedilla ; B 25 -216 418 458 ;
+C -1 ; WX 747 ; N copyright ; B 23 -18 723 676 ;
+C -1 ; WX 400 ; N degree ; B 70 376 370 676 ;
+C -1 ; WX 570 ; N divide ; B 33 0 537 505 ;
+C -1 ; WX 444 ; N eacute ; B 25 -13 461 690 ;
+C -1 ; WX 444 ; N ecircumflex ; B 25 -13 450 682 ;
+C -1 ; WX 444 ; N edieresis ; B 25 -13 480 648 ;
+C -1 ; WX 444 ; N egrave ; B 25 -13 413 690 ;
+C -1 ; WX 500 ; N eth ; B 27 -13 498 682 ;
+C -1 ; WX 278 ; N iacute ; B 27 -13 378 690 ;
+C -1 ; WX 278 ; N icircumflex ; B 27 -13 367 682 ;
+C -1 ; WX 278 ; N idieresis ; B 27 -13 397 648 ;
+C -1 ; WX 278 ; N igrave ; B 27 -13 298 690 ;
+C -1 ; WX 606 ; N logicalnot ; B 51 120 555 401 ;
+C -1 ; WX 606 ; N minus ; B 51 210 555 300 ;
+C -1 ; WX 576 ; N mu ; B -63 -210 521 458 ;
+C -1 ; WX 570 ; N multiply ; B 33 0 537 504 ;
+C -1 ; WX 556 ; N ntilde ; B 24 -13 536 648 ;
+C -1 ; WX 500 ; N oacute ; B 27 -13 489 690 ;
+C -1 ; WX 500 ; N ocircumflex ; B 27 -13 478 682 ;
+C -1 ; WX 500 ; N odieresis ; B 27 -13 508 648 ;
+C -1 ; WX 500 ; N ograve ; B 27 -13 467 690 ;
+C -1 ; WX 750 ; N onehalf ; B 30 0 720 676 ;
+C -1 ; WX 750 ; N onequarter ; B 30 0 720 676 ;
+C -1 ; WX 300 ; N onesuperior ; B 17 270 283 676 ;
+C -1 ; WX 500 ; N otilde ; B 27 -13 508 648 ;
+C -1 ; WX 570 ; N plusminus ; B 33 0 537 665 ;
+C -1 ; WX 747 ; N registered ; B 23 -18 723 676 ;
+C -1 ; WX 389 ; N scaron ; B 16 -13 465 683 ;
+C -1 ; WX 500 ; N thorn ; B -79 -203 474 682 ;
+C -1 ; WX 750 ; N threequarters ; B 30 0 720 676 ;
+C -1 ; WX 300 ; N threesuperior ; B 0 263 299 676 ;
+C -1 ; WX 1000 ; N trademark ; B 40 272 980 676 ;
+C -1 ; WX 300 ; N twosuperior ; B -2 270 302 676 ;
+C -1 ; WX 556 ; N uacute ; B 48 -13 521 690 ;
+C -1 ; WX 556 ; N ucircumflex ; B 48 -13 521 682 ;
+C -1 ; WX 556 ; N udieresis ; B 48 -13 536 648 ;
+C -1 ; WX 556 ; N ugrave ; B 48 -13 521 690 ;
+C -1 ; WX 444 ; N yacute ; B -60 -203 461 690 ;
+C -1 ; WX 444 ; N ydieresis ; B -60 -203 480 648 ;
+C -1 ; WX 389 ; N zcaron ; B -24 -58 465 683 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 108
+
+KPX A y -74
+KPX A w -74
+KPX A v -74
+KPX A space -55
+KPX A quoteright -74
+KPX A Y -55
+KPX A W -92
+KPX A V -74
+KPX A T -55
+
+KPX F space -18
+KPX F period -129
+KPX F comma -129
+KPX F A -92
+
+KPX L y -37
+KPX L space -37
+KPX L quoteright -55
+KPX L Y -37
+KPX L W -37
+KPX L V -37
+KPX L T -18
+
+KPX P space -37
+KPX P period -129
+KPX P comma -129
+KPX P A -74
+
+KPX R y -18
+KPX R Y -18
+KPX R W -18
+KPX R V -18
+
+KPX T y -37
+KPX T w -37
+KPX T u -37
+KPX T semicolon -74
+KPX T s -92
+KPX T r -37
+KPX T period -92
+KPX T o -92
+KPX T i -37
+KPX T hyphen -92
+KPX T e -92
+KPX T comma -92
+KPX T colon -74
+KPX T c -92
+KPX T a -92
+KPX T O -18
+KPX T A -55
+
+KPX V y -74
+KPX V u -55
+KPX V space -18
+KPX V semicolon -74
+KPX V r -55
+KPX V period -129
+KPX V o -111
+KPX V i -55
+KPX V hyphen -55
+KPX V e -111
+KPX V comma -129
+KPX V colon -74
+KPX V a -111
+KPX V A -74
+
+KPX W y -55
+KPX W u -55
+KPX W space -18
+KPX W semicolon -55
+KPX W r -74
+KPX W period -74
+KPX W o -74
+KPX W i -37
+KPX W hyphen -37
+KPX W e -74
+KPX W comma -74
+KPX W colon -55
+KPX W a -74
+KPX W A -74
+
+KPX Y v -92
+KPX Y u -92
+KPX Y space -37
+KPX Y semicolon -92
+KPX Y q -111
+KPX Y period -74
+KPX Y p -74
+KPX Y o -111
+KPX Y i -55
+KPX Y hyphen -92
+KPX Y e -111
+KPX Y comma -92
+KPX Y colon -92
+KPX Y a -92
+KPX Y A -74
+
+KPX f quoteright 55
+KPX f f -18
+
+KPX one one -55
+
+KPX quoteleft quoteleft -74
+
+KPX quoteright t -37
+KPX quoteright space -74
+KPX quoteright s -74
+KPX quoteright quoteright -74
+
+KPX r quoteright 37
+KPX r period -55
+KPX r comma -55
+
+KPX space Y -18
+KPX space W -18
+KPX space A -37
+
+KPX v period -37
+KPX v comma -37
+
+KPX w period -37
+KPX w comma -37
+
+KPX y period -37
+KPX y comma -37
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 204 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 28 0 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 111 204 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 167 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 55 0 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 139 204 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 55 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 194 204 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 194 204 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 194 204 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 194 204 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 111 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 111 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 111 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 111 0 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 28 204 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 28 204 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 28 204 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 28 204 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 167 204 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 167 204 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 167 204 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 167 204 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 55 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 55 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 55 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 55 0 ;
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 167 204 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 167 204 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 167 204 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 167 204 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 83 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 83 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 83 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 83 0 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 194 204 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 194 204 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 194 204 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 194 204 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 83 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 83 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 83 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 83 0 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 167 204 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 83 0 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 194 204 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 111 0 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 194 204 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 83 0 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 167 204 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 83 0 ;
+EndComposites
+EndFontMetrics
diff --git a/misc/afm/TimesO.afm b/misc/afm/TimesO.afm
new file mode 100644
index 0000000000..b8ffc6a0f3
--- /dev/null
+++ b/misc/afm/TimesO.afm
@@ -0,0 +1,450 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1984 Adobe Systems Incorporated. 	All Rights Reserved.
+Comment Creation Date:Tue Aug 5 11:12:17 PDT 1986
+FontName Times-Italic
+EncodingScheme AdobeStandardEncoding
+FullName Times Italic
+FamilyName Times
+Weight Medium
+ItalicAngle -15.5
+IsFixedPitch false
+UnderlinePosition -96
+UnderlineThickness 48
+Version 001.001
+Notice Times is a trademark of Allied Corporation.
+FontBBox -176 -252 990 930
+CapHeight 660
+XHeight 446
+Descender -206
+Ascender 684
+StartCharMetrics 228
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 46 -10 296 670 ;
+C 34 ; WX 420 ; N quotedbl ; B 107 442 402 673 ;
+C 35 ; WX 500 ; N numbersign ; B -7 -6 508 683 ;
+C 36 ; WX 500 ; N dollar ; B 13 -102 481 735 ;
+C 37 ; WX 833 ; N percent ; B 63 -14 770 682 ;
+C 38 ; WX 778 ; N ampersand ; B 60 -22 698 673 ;
+C 39 ; WX 333 ; N quoteright ; B 69 458 206 678 ;
+C 40 ; WX 333 ; N parenleft ; B 41 -180 312 662 ;
+C 41 ; WX 333 ; N parenright ; B 19 -178 286 664 ;
+C 42 ; WX 500 ; N asterisk ; B 60 268 434 684 ;
+C 43 ; WX 675 ; N plus ; B 85 0 589 505 ;
+C 44 ; WX 250 ; N comma ; B 57 -126 194 94 ;
+C 45 ; WX 333 ; N hyphen ; B 55 192 276 254 ;
+C 46 ; WX 250 ; N period ; B 75 -10 175 90 ;
+C 47 ; WX 278 ; N slash ; B 2 -14 252 641 ;
+C 48 ; WX 500 ; N zero ; B 19 -9 470 683 ;
+C 49 ; WX 500 ; N one ; B 31 0 390 684 ;
+C 50 ; WX 500 ; N two ; B -7 0 429 682 ;
+C 51 ; WX 500 ; N three ; B -7 -12 443 682 ;
+C 52 ; WX 500 ; N four ; B -8 0 454 681 ;
+C 53 ; WX 500 ; N five ; B -12 -15 462 666 ;
+C 54 ; WX 500 ; N six ; B 24 -8 497 685 ;
+C 55 ; WX 500 ; N seven ; B 56 -12 512 666 ;
+C 56 ; WX 500 ; N eight ; B 12 -7 475 681 ;
+C 57 ; WX 500 ; N nine ; B 10 -18 470 684 ;
+C 58 ; WX 333 ; N colon ; B 86 -10 284 444 ;
+C 59 ; WX 333 ; N semicolon ; B 63 -124 292 441 ;
+C 60 ; WX 675 ; N less ; B 83 -7 592 515 ;
+C 61 ; WX 675 ; N equal ; B 85 125 589 383 ;
+C 62 ; WX 675 ; N greater ; B 82 -7 591 515 ;
+C 63 ; WX 500 ; N question ; B 105 -10 439 670 ;
+C 64 ; WX 920 ; N at ; B 39 -191 866 648 ;
+C 65 ; WX 611 ; N A ; B -45 0 564 672 ;
+C 66 ; WX 611 ; N B ; B -28 0 562 660 ;
+C 67 ; WX 667 ; N C ; B 33 -23 653 672 ;
+C 68 ; WX 722 ; N D ; B -27 0 671 660 ;
+C 69 ; WX 611 ; N E ; B -17 0 609 660 ;
+C 70 ; WX 611 ; N F ; B -17 0 609 660 ;
+C 71 ; WX 722 ; N G ; B 31 -23 701 672 ;
+C 72 ; WX 722 ; N H ; B -26 0 742 660 ;
+C 73 ; WX 333 ; N I ; B -26 0 357 660 ;
+C 74 ; WX 444 ; N J ; B -36 -22 479 660 ;
+C 75 ; WX 667 ; N K ; B -15 0 702 660 ;
+C 76 ; WX 556 ; N L ; B -32 0 535 660 ;
+C 77 ; WX 833 ; N M ; B -24 0 850 660 ;
+C 78 ; WX 667 ; N N ; B -36 -12 698 660 ;
+C 79 ; WX 722 ; N O ; B 42 -23 676 671 ;
+C 80 ; WX 611 ; N P ; B -16 0 582 660 ;
+C 81 ; WX 722 ; N Q ; B 41 -186 681 671 ;
+C 82 ; WX 611 ; N R ; B -32 0 566 660 ;
+C 83 ; WX 500 ; N S ; B 9 -22 483 674 ;
+C 84 ; WX 556 ; N T ; B 32 0 602 660 ;
+C 85 ; WX 722 ; N U ; B 77 -21 747 660 ;
+C 86 ; WX 611 ; N V ; B 44 -20 659 660 ;
+C 87 ; WX 833 ; N W ; B 35 -20 875 660 ;
+C 88 ; WX 611 ; N X ; B -45 0 633 660 ;
+C 89 ; WX 556 ; N Y ; B 44 0 600 660 ;
+C 90 ; WX 556 ; N Z ; B -19 0 581 660 ;
+C 91 ; WX 389 ; N bracketleft ; B 22 -170 391 654 ;
+C 92 ; WX 278 ; N backslash ; B 2 -12 252 651 ;
+C 93 ; WX 389 ; N bracketright ; B -31 -170 341 654 ;
+C 94 ; WX 422 ; N asciicircum ; B 0 254 503 660 ;
+C 95 ; WX 500 ; N underscore ; B -9 -252 510 -206 ;
+C 96 ; WX 333 ; N quoteleft ; B 149 457 286 677 ;
+C 97 ; WX 500 ; N a ; B 15 -11 474 446 ;
+C 98 ; WX 500 ; N b ; B 24 -12 475 682 ;
+C 99 ; WX 444 ; N c ; B 32 -11 420 446 ;
+C 100 ; WX 500 ; N d ; B 15 -11 521 684 ;
+C 101 ; WX 444 ; N e ; B 34 -13 412 446 ;
+C 102 ; WX 278 ; N f ; B -148 -207 415 684 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B 10 -209 471 445 ;
+C 104 ; WX 500 ; N h ; B 23 -10 473 684 ;
+C 105 ; WX 278 ; N i ; B 43 -10 263 660 ;
+C 106 ; WX 278 ; N j ; B -109 -207 287 660 ;
+C 107 ; WX 444 ; N k ; B 16 -12 460 685 ;
+C 108 ; WX 278 ; N l ; B 41 -10 276 685 ;
+C 109 ; WX 722 ; N m ; B 11 -10 698 447 ;
+C 110 ; WX 500 ; N n ; B 23 -10 471 447 ;
+C 111 ; WX 500 ; N o ; B 27 -13 467 448 ;
+C 112 ; WX 500 ; N p ; B -75 -206 465 446 ;
+C 113 ; WX 500 ; N q ; B 20 -206 483 445 ;
+C 114 ; WX 389 ; N r ; B 24 0 392 446 ;
+C 115 ; WX 389 ; N s ; B 16 -14 367 446 ;
+C 116 ; WX 278 ; N t ; B 38 -10 288 548 ;
+C 117 ; WX 500 ; N u ; B 42 -11 472 447 ;
+C 118 ; WX 444 ; N v ; B 24 -11 423 444 ;
+C 119 ; WX 667 ; N w ; B 14 -10 650 447 ;
+C 120 ; WX 444 ; N x ; B -31 -10 450 446 ;
+C 121 ; WX 444 ; N y ; B -27 -209 420 445 ;
+C 122 ; WX 389 ; N z ; B 2 0 380 434 ;
+C 123 ; WX 400 ; N braceleft ; B 65 -179 411 675 ;
+C 124 ; WX 275 ; N bar ; B -22 -188 251 670 ;
+C 125 ; WX 400 ; N braceright ; B -66 -179 300 675 ;
+C 126 ; WX 541 ; N asciitilde ; B 18 169 522 340 ;
+C 161 ; WX 389 ; N exclamdown ; B 59 -213 317 468 ;
+C 162 ; WX 500 ; N cent ; B 62 -146 449 564 ;
+C 163 ; WX 500 ; N sterling ; B -5 -9 498 672 ;
+C 164 ; WX 167 ; N fraction ; B -176 -15 338 672 ;
+C 165 ; WX 500 ; N yen ; B 13 0 609 684 ;
+C 166 ; WX 500 ; N florin ; B 3 -189 492 688 ;
+C 167 ; WX 500 ; N section ; B 42 -96 455 743 ;
+C 168 ; WX 500 ; N currency ; B 3 105 498 604 ;
+C 169 ; WX 214 ; N quotesingle ; B 99 453 247 678 ;
+C 170 ; WX 556 ; N quotedblleft ; B 166 457 510 677 ;
+C 171 ; WX 500 ; N guillemotleft ; B 54 39 444 400 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 60 39 285 400 ;
+C 173 ; WX 333 ; N guilsinglright ; B 49 34 269 406 ;
+C 174 ; WX 500 ; N fi ; B -136 -207 468 684 ;
+C 175 ; WX 500 ; N fl ; B -140 -207 509 684 ;
+C 177 ; WX 500 ; N endash ; B -3 194 501 242 ;
+C 178 ; WX 500 ; N dagger ; B 92 -93 480 734 ;
+C 179 ; WX 500 ; N daggerdbl ; B 20 -93 482 743 ;
+C 180 ; WX 250 ; N periodcentered ; B 75 192 199 316 ;
+C 182 ; WX 523 ; N paragraph ; B 87 -196 533 675 ;
+C 183 ; WX 350 ; N bullet ; B 50 175 300 425 ;
+C 184 ; WX 333 ; N quotesinglbase ; B 83 -126 220 94 ;
+C 185 ; WX 556 ; N quotedblbase ; B 63 -126 407 94 ;
+C 186 ; WX 556 ; N quotedblright ; B 68 458 412 678 ;
+C 187 ; WX 500 ; N guillemotright ; B 59 34 442 406 ;
+C 188 ; WX 889 ; N ellipsis ; B 62 -10 828 90 ;
+C 189 ; WX 1000 ; N perthousand ; B 9 -65 990 690 ;
+C 191 ; WX 500 ; N questiondown ; B 55 -215 395 462 ;
+C 193 ; WX 333 ; N grave ; B 160 491 333 659 ;
+C 194 ; WX 333 ; N acute ; B 154 501 375 680 ;
+C 195 ; WX 333 ; N circumflex ; B 96 495 374 669 ;
+C 196 ; WX 333 ; N tilde ; B 114 518 386 639 ;
+C 197 ; WX 333 ; N macron ; B 120 543 380 603 ;
+C 198 ; WX 333 ; N breve ; B 140 512 401 645 ;
+C 199 ; WX 333 ; N dotaccent ; B 112 515 222 625 ;
+C 200 ; WX 333 ; N dieresis ; B 117 534 389 634 ;
+C 202 ; WX 333 ; N ring ; B 239 509 433 703 ;
+C 203 ; WX 333 ; N cedilla ; B -30 -206 214 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 62 532 348 749 ;
+C 206 ; WX 333 ; N ogonek ; B -44 -159 169 40 ;
+C 207 ; WX 333 ; N caron ; B 138 495 422 669 ;
+C 208 ; WX 889 ; N emdash ; B -65 194 945 242 ;
+C 225 ; WX 889 ; N AE ; B -46 0 889 660 ;
+C 227 ; WX 276 ; N ordfeminine ; B 32 300 310 677 ;
+C 232 ; WX 556 ; N Lslash ; B 0 0 567 660 ;
+C 233 ; WX 722 ; N Oslash ; B 40 -110 683 738 ;
+C 234 ; WX 944 ; N OE ; B 30 -10 943 668 ;
+C 235 ; WX 310 ; N ordmasculine ; B 45 301 310 679 ;
+C 241 ; WX 667 ; N ae ; B 24 -12 638 448 ;
+C 245 ; WX 278 ; N dotlessi ; B 47 -10 226 447 ;
+C 248 ; WX 278 ; N lslash ; B 0 -10 264 685 ;
+C 249 ; WX 500 ; N oslash ; B 28 -132 468 560 ;
+C 250 ; WX 667 ; N oe ; B 26 -15 643 445 ;
+C 251 ; WX 500 ; N germandbls ; B -167 -209 492 684 ;
+C -1 ; WX 611 ; N Aacute ; B -45 0 564 907 ;
+C -1 ; WX 611 ; N Acircumflex ; B -45 0 564 896 ;
+C -1 ; WX 611 ; N Adieresis ; B -45 0 564 861 ;
+C -1 ; WX 611 ; N Agrave ; B -45 0 564 886 ;
+C -1 ; WX 611 ; N Aring ; B -45 0 564 930 ;
+C -1 ; WX 611 ; N Atilde ; B -45 0 564 866 ;
+C -1 ; WX 667 ; N Ccedilla ; B 33 -206 653 672 ;
+C -1 ; WX 611 ; N Eacute ; B -17 0 609 907 ;
+C -1 ; WX 611 ; N Ecircumflex ; B -17 0 609 896 ;
+C -1 ; WX 611 ; N Edieresis ; B -17 0 609 861 ;
+C -1 ; WX 611 ; N Egrave ; B -17 0 609 886 ;
+C -1 ; WX 722 ; N Eth ; B -27 0 671 660 ;
+C -1 ; WX 333 ; N Iacute ; B -26 0 389 907 ;
+C -1 ; WX 333 ; N Icircumflex ; B -26 0 388 896 ;
+C -1 ; WX 333 ; N Idieresis ; B -26 0 403 861 ;
+C -1 ; WX 333 ; N Igrave ; B -26 0 357 886 ;
+C -1 ; WX 667 ; N Ntilde ; B -36 -12 698 866 ;
+C -1 ; WX 722 ; N Oacute ; B 42 -23 676 907 ;
+C -1 ; WX 722 ; N Ocircumflex ; B 42 -23 676 896 ;
+C -1 ; WX 722 ; N Odieresis ; B 42 -23 676 861 ;
+C -1 ; WX 722 ; N Ograve ; B 42 -23 676 886 ;
+C -1 ; WX 722 ; N Otilde ; B 42 -23 676 866 ;
+C -1 ; WX 500 ; N Scaron ; B 9 -22 506 896 ;
+C -1 ; WX 611 ; N Thorn ; B -16 0 547 660 ;
+C -1 ; WX 722 ; N Uacute ; B 77 -21 747 907 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 77 -21 747 896 ;
+C -1 ; WX 722 ; N Udieresis ; B 77 -21 747 861 ;
+C -1 ; WX 722 ; N Ugrave ; B 77 -21 747 886 ;
+C -1 ; WX 556 ; N Yacute ; B 44 0 600 894 ;
+C -1 ; WX 556 ; N Ydieresis ; B 44 0 600 861 ;
+C -1 ; WX 556 ; N Zcaron ; B -19 0 581 896 ;
+C -1 ; WX 500 ; N aacute ; B 15 -11 474 680 ;
+C -1 ; WX 500 ; N acircumflex ; B 15 -11 474 669 ;
+C -1 ; WX 500 ; N adieresis ; B 15 -11 479 634 ;
+C -1 ; WX 500 ; N agrave ; B 15 -11 474 659 ;
+C -1 ; WX 500 ; N aring ; B 15 -11 474 703 ;
+C -1 ; WX 500 ; N atilde ; B 15 -11 476 639 ;
+C -1 ; WX 275 ; N brokenbar ; B -22 -188 251 670 ;
+C -1 ; WX 444 ; N ccedilla ; B 32 -206 420 446 ;
+C -1 ; WX 760 ; N copyright ; B 40 -22 719 672 ;
+C -1 ; WX 400 ; N degree ; B 70 384 370 684 ;
+C -1 ; WX 675 ; N divide ; B 85 0 589 505 ;
+C -1 ; WX 444 ; N eacute ; B 34 -13 444 680 ;
+C -1 ; WX 444 ; N ecircumflex ; B 34 -13 443 669 ;
+C -1 ; WX 444 ; N edieresis ; B 34 -13 458 634 ;
+C -1 ; WX 444 ; N egrave ; B 34 -13 412 659 ;
+C -1 ; WX 500 ; N eth ; B 27 -13 487 682 ;
+C -1 ; WX 278 ; N iacute ; B 47 -10 341 680 ;
+C -1 ; WX 278 ; N icircumflex ; B 47 -10 340 669 ;
+C -1 ; WX 278 ; N idieresis ; B 47 -10 355 634 ;
+C -1 ; WX 278 ; N igrave ; B 47 -10 299 659 ;
+C -1 ; WX 675 ; N logicalnot ; B 85 113 589 383 ;
+C -1 ; WX 675 ; N minus ; B 85 222 589 286 ;
+C -1 ; WX 500 ; N mu ; B -60 -206 472 446 ;
+C -1 ; WX 675 ; N multiply ; B 85 0 589 504 ;
+C -1 ; WX 500 ; N ntilde ; B 23 -10 471 639 ;
+C -1 ; WX 500 ; N oacute ; B 27 -13 467 680 ;
+C -1 ; WX 500 ; N ocircumflex ; B 27 -13 467 669 ;
+C -1 ; WX 500 ; N odieresis ; B 27 -13 479 634 ;
+C -1 ; WX 500 ; N ograve ; B 27 -13 467 659 ;
+C -1 ; WX 750 ; N onehalf ; B 30 -15 720 684 ;
+C -1 ; WX 750 ; N onequarter ; B 30 -15 720 684 ;
+C -1 ; WX 300 ; N onesuperior ; B 43 274 277 683 ;
+C -1 ; WX 500 ; N otilde ; B 27 -13 476 639 ;
+C -1 ; WX 675 ; N plusminus ; B 85 0 589 645 ;
+C -1 ; WX 760 ; N registered ; B 40 -22 719 672 ;
+C -1 ; WX 389 ; N scaron ; B 16 -14 450 669 ;
+C -1 ; WX 500 ; N thorn ; B -75 -206 465 682 ;
+C -1 ; WX 750 ; N threequarters ; B 30 -15 720 684 ;
+C -1 ; WX 300 ; N threesuperior ; B 13 267 306 684 ;
+C -1 ; WX 980 ; N trademark ; B 35 268 945 672 ;
+C -1 ; WX 300 ; N twosuperior ; B 8 274 292 684 ;
+C -1 ; WX 500 ; N uacute ; B 42 -11 472 680 ;
+C -1 ; WX 500 ; N ucircumflex ; B 42 -11 472 669 ;
+C -1 ; WX 500 ; N udieresis ; B 42 -11 473 634 ;
+C -1 ; WX 500 ; N ugrave ; B 42 -11 472 659 ;
+C -1 ; WX 444 ; N yacute ; B -27 -209 431 680 ;
+C -1 ; WX 444 ; N ydieresis ; B -27 -209 445 634 ;
+C -1 ; WX 389 ; N zcaron ; B 2 0 450 669 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 120
+
+KPX A y -55
+KPX A w -55
+KPX A v -55
+KPX A space -18
+KPX A quoteright -37
+KPX A Y -55
+KPX A W -37
+KPX A V -50
+KPX A T -37
+
+KPX F period -129
+KPX F comma -129
+KPX F A -129
+
+KPX L y -30
+KPX L space -18
+KPX L quoteright -37
+KPX L Y -20
+KPX L W -37
+KPX L V -37
+KPX L T -20
+
+KPX P space -18
+KPX P period -129
+KPX P comma -129
+KPX P A -129
+
+KPX R y -18
+KPX R Y -18
+KPX R W -18
+KPX R V -18
+KPX R T 0
+
+KPX T y -74
+KPX T w -74
+KPX T u -55
+KPX T space -18
+KPX T semicolon -65
+KPX T s -92
+KPX T r -55
+KPX T period -74
+KPX T o -92
+KPX T i -55
+KPX T hyphen -74
+KPX T e -92
+KPX T comma -74
+KPX T colon -55
+KPX T c -92
+KPX T a -92
+KPX T O -18
+KPX T A -74
+
+KPX V y -92
+KPX V u -74
+KPX V space -18
+KPX V semicolon -74
+KPX V r -74
+KPX V period -129
+KPX V o -111
+KPX V i -74
+KPX V hyphen -55
+KPX V e -111
+KPX V comma -129
+KPX V colon -65
+KPX V a -111
+KPX V O -30
+KPX V A -74
+
+KPX W y -92
+KPX W u -55
+KPX W semicolon -65
+KPX W r -55
+KPX W period -92
+KPX W o -92
+KPX W i -55
+KPX W hyphen -37
+KPX W e -92
+KPX W comma -92
+KPX W colon -65
+KPX W a -92
+KPX W A -70
+
+KPX Y v -92
+KPX Y u -92
+KPX Y semicolon -65
+KPX Y q -111
+KPX Y period -92
+KPX Y p -92
+KPX Y o -92
+KPX Y i -74
+KPX Y hyphen -74
+KPX Y e -92
+KPX Y comma -92
+KPX Y colon -65
+KPX Y a -92
+KPX Y A -70
+
+KPX f quoteright 92
+
+KPX one one -74
+
+KPX quoteleft quoteleft -111
+
+KPX quoteright t -111
+KPX quoteright space -111
+KPX quoteright s -129
+KPX quoteright quoteright -111
+
+KPX r y 0
+KPX r x 0
+KPX r w 0
+KPX r v 0
+KPX r u 0
+KPX r t 0
+KPX r r 0
+KPX r quoteright 37
+KPX r q -37
+KPX r period -111
+KPX r o -37
+KPX r hyphen -20
+KPX r h -18
+KPX r g -37
+KPX r e -37
+KPX r d -37
+KPX r comma -111
+KPX r c -37
+
+KPX space A -18
+
+KPX v period -74
+KPX v comma -74
+
+KPX w period -74
+KPX w comma -74
+
+KPX y period -55
+KPX y comma -55
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 111 227 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 28 0 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 83 227 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 188 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 61 0 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 111 227 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 55 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 228 227 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 228 227 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 228 227 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 228 227 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 83 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 83 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 83 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 83 0 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 14 227 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 14 227 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 14 227 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 14 227 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -34 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -34 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -34 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -34 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 160 227 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 160 227 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 160 227 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 160 227 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 68 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 68 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 68 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 68 0 ;
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 146 227 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 146 227 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 146 227 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 146 227 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 89 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 89 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 89 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 89 0 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 221 227 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 221 227 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 221 227 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 221 227 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 89 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 89 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 89 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 89 0 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 146 227 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 89 0 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 181 227 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 76 0 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 221 227 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 89 0 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 80 227 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 29 0 ;
+EndComposites
+EndFontMetrics
diff --git a/misc/afm/TimesRo.afm b/misc/afm/TimesRo.afm
new file mode 100644
index 0000000000..3f8ce6b22a
--- /dev/null
+++ b/misc/afm/TimesRo.afm
@@ -0,0 +1,443 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1984 Adobe Systems Incorporated. 	All Rights Reserved.
+Comment Creation Date:Tue Aug 5 10:51:57 PDT 1986
+FontName Times-Roman
+EncodingScheme AdobeStandardEncoding
+FullName Times Roman
+FamilyName Times
+Weight Roman
+ItalicAngle 0.0
+IsFixedPitch false
+UnderlinePosition -109
+UnderlineThickness 49
+Version 001.001
+Notice Times Roman is a trademark of Allied Corporation.
+FontBBox -170 -223 1024 896
+CapHeight 662
+XHeight 448
+Descender -217
+Ascender 682
+StartCharMetrics 228
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 109 -14 224 676 ;
+C 34 ; WX 408 ; N quotedbl ; B 70 445 337 685 ;
+C 35 ; WX 500 ; N numbersign ; B 4 0 495 662 ;
+C 36 ; WX 500 ; N dollar ; B 44 -87 456 727 ;
+C 37 ; WX 833 ; N percent ; B 61 -14 772 676 ;
+C 38 ; WX 778 ; N ampersand ; B 42 -14 750 676 ;
+C 39 ; WX 333 ; N quoteright ; B 103 432 242 676 ;
+C 40 ; WX 333 ; N parenleft ; B 49 -177 304 676 ;
+C 41 ; WX 333 ; N parenright ; B 29 -177 284 676 ;
+C 42 ; WX 500 ; N asterisk ; B 64 265 437 683 ;
+C 43 ; WX 564 ; N plus ; B 30 7 534 512 ;
+C 44 ; WX 250 ; N comma ; B 63 -143 202 101 ;
+C 45 ; WX 333 ; N hyphen ; B 43 194 289 257 ;
+C 46 ; WX 250 ; N period ; B 68 -14 183 101 ;
+C 47 ; WX 278 ; N slash ; B -12 -108 302 682 ;
+C 48 ; WX 500 ; N zero ; B 24 -14 476 676 ;
+C 49 ; WX 500 ; N one ; B 111 0 394 676 ;
+C 50 ; WX 500 ; N two ; B 30 0 475 676 ;
+C 51 ; WX 500 ; N three ; B 44 -14 431 676 ;
+C 52 ; WX 500 ; N four ; B 12 0 472 676 ;
+C 53 ; WX 500 ; N five ; B 32 -14 438 688 ;
+C 54 ; WX 500 ; N six ; B 35 -14 468 682 ;
+C 55 ; WX 500 ; N seven ; B 20 -14 449 662 ;
+C 56 ; WX 500 ; N eight ; B 53 -14 442 676 ;
+C 57 ; WX 500 ; N nine ; B 30 -22 460 676 ;
+C 58 ; WX 278 ; N colon ; B 81 -14 196 458 ;
+C 59 ; WX 278 ; N semicolon ; B 63 -143 202 458 ;
+C 60 ; WX 564 ; N less ; B 27 0 536 522 ;
+C 61 ; WX 564 ; N equal ; B 30 132 534 390 ;
+C 62 ; WX 564 ; N greater ; B 27 0 536 522 ;
+C 63 ; WX 444 ; N question ; B 49 -14 395 676 ;
+C 64 ; WX 921 ; N at ; B 0 -155 819 675 ;
+C 65 ; WX 722 ; N A ; B 15 0 706 676 ;
+C 66 ; WX 667 ; N B ; B 20 0 596 662 ;
+C 67 ; WX 667 ; N C ; B 33 -14 637 676 ;
+C 68 ; WX 722 ; N D ; B 20 0 689 662 ;
+C 69 ; WX 611 ; N E ; B 12 0 597 662 ;
+C 70 ; WX 556 ; N F ; B 12 0 544 662 ;
+C 71 ; WX 722 ; N G ; B 27 -14 704 676 ;
+C 72 ; WX 722 ; N H ; B 20 0 703 662 ;
+C 73 ; WX 333 ; N I ; B 18 0 316 662 ;
+C 74 ; WX 389 ; N J ; B 10 -14 376 662 ;
+C 75 ; WX 722 ; N K ; B 20 0 709 662 ;
+C 76 ; WX 611 ; N L ; B 12 0 598 662 ;
+C 77 ; WX 889 ; N M ; B 19 0 871 662 ;
+C 78 ; WX 722 ; N N ; B 12 -14 709 662 ;
+C 79 ; WX 722 ; N O ; B 33 -14 688 676 ;
+C 80 ; WX 556 ; N P ; B 11 0 542 662 ;
+C 81 ; WX 722 ; N Q ; B 33 -177 701 676 ;
+C 82 ; WX 667 ; N R ; B 12 0 654 662 ;
+C 83 ; WX 556 ; N S ; B 42 -14 491 676 ;
+C 84 ; WX 611 ; N T ; B 18 0 594 662 ;
+C 85 ; WX 722 ; N U ; B 16 -14 705 662 ;
+C 86 ; WX 722 ; N V ; B 20 -14 701 662 ;
+C 87 ; WX 944 ; N W ; B 9 -14 936 662 ;
+C 88 ; WX 722 ; N X ; B 12 0 706 662 ;
+C 89 ; WX 722 ; N Y ; B 22 0 703 662 ;
+C 90 ; WX 611 ; N Z ; B 7 0 597 662 ;
+C 91 ; WX 333 ; N bracketleft ; B 88 -156 299 662 ;
+C 92 ; WX 278 ; N backslash ; B -83 0 361 682 ;
+C 93 ; WX 333 ; N bracketright ; B 34 -156 245 662 ;
+C 94 ; WX 469 ; N asciicircum ; B 13 256 456 662 ;
+C 95 ; WX 500 ; N underscore ; B 0 -133 500 -84 ;
+C 96 ; WX 333 ; N quoteleft ; B 91 432 230 676 ;
+C 97 ; WX 444 ; N a ; B 37 -10 442 458 ;
+C 98 ; WX 500 ; N b ; B 9 -10 474 682 ;
+C 99 ; WX 444 ; N c ; B 25 -10 412 458 ;
+C 100 ; WX 500 ; N d ; B 26 -13 491 682 ;
+C 101 ; WX 444 ; N e ; B 22 -10 421 458 ;
+C 102 ; WX 333 ; N f ; B 20 0 383 682 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B 27 -217 470 458 ;
+C 104 ; WX 500 ; N h ; B 9 0 490 682 ;
+C 105 ; WX 278 ; N i ; B 22 0 259 682 ;
+C 106 ; WX 278 ; N j ; B -54 -217 212 682 ;
+C 107 ; WX 500 ; N k ; B 1 0 500 682 ;
+C 108 ; WX 278 ; N l ; B 20 0 259 682 ;
+C 109 ; WX 778 ; N m ; B 13 0 764 458 ;
+C 110 ; WX 500 ; N n ; B 9 0 490 458 ;
+C 111 ; WX 500 ; N o ; B 30 -10 470 458 ;
+C 112 ; WX 500 ; N p ; B 2 -217 470 458 ;
+C 113 ; WX 500 ; N q ; B 24 -217 498 459 ;
+C 114 ; WX 333 ; N r ; B 4 0 335 458 ;
+C 115 ; WX 389 ; N s ; B 51 -10 348 458 ;
+C 116 ; WX 278 ; N t ; B 13 -10 279 580 ;
+C 117 ; WX 500 ; N u ; B 9 -10 479 448 ;
+C 118 ; WX 500 ; N v ; B 10 -10 468 448 ;
+C 119 ; WX 722 ; N w ; B 21 -10 694 448 ;
+C 120 ; WX 500 ; N x ; B 17 0 479 448 ;
+C 121 ; WX 500 ; N y ; B 15 -217 476 448 ;
+C 122 ; WX 444 ; N z ; B 25 0 418 448 ;
+C 123 ; WX 480 ; N braceleft ; B 110 -165 341 682 ;
+C 124 ; WX 200 ; N bar ; B 68 0 132 682 ;
+C 125 ; WX 480 ; N braceright ; B 139 -165 370 682 ;
+C 126 ; WX 541 ; N asciitilde ; B 18 176 522 347 ;
+C 161 ; WX 333 ; N exclamdown ; B 109 -217 224 458 ;
+C 162 ; WX 500 ; N cent ; B 53 -138 448 579 ;
+C 163 ; WX 500 ; N sterling ; B 11 -14 491 676 ;
+C 164 ; WX 167 ; N fraction ; B -170 -14 346 676 ;
+C 165 ; WX 500 ; N yen ; B -43 0 502 662 ;
+C 166 ; WX 500 ; N florin ; B 6 -185 490 676 ;
+C 167 ; WX 500 ; N section ; B 72 -148 426 676 ;
+C 168 ; WX 500 ; N currency ; B -2 99 503 600 ;
+C 169 ; WX 180 ; N quotesingle ; B 47 445 133 685 ;
+C 170 ; WX 444 ; N quotedblleft ; B 27 432 399 676 ;
+C 171 ; WX 500 ; N guillemotleft ; B 32 35 449 422 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 45 35 271 422 ;
+C 173 ; WX 333 ; N guilsinglright ; B 62 36 288 423 ;
+C 174 ; WX 556 ; N fi ; B 33 0 521 678 ;
+C 175 ; WX 556 ; N fl ; B 29 0 521 682 ;
+C 177 ; WX 500 ; N endash ; B -7 201 507 250 ;
+C 178 ; WX 500 ; N dagger ; B 54 -149 440 676 ;
+C 179 ; WX 500 ; N daggerdbl ; B 54 -153 439 676 ;
+C 180 ; WX 250 ; N periodcentered ; B 68 204 183 319 ;
+C 182 ; WX 453 ; N paragraph ; B 0 -207 373 662 ;
+C 183 ; WX 350 ; N bullet ; B 50 175 300 425 ;
+C 184 ; WX 333 ; N quotesinglbase ; B 103 -143 242 101 ;
+C 185 ; WX 444 ; N quotedblbase ; B 45 -143 417 101 ;
+C 186 ; WX 444 ; N quotedblright ; B 45 432 417 676 ;
+C 187 ; WX 500 ; N guillemotright ; B 51 35 468 422 ;
+C 188 ; WX 1000 ; N ellipsis ; B 110 -14 891 101 ;
+C 189 ; WX 1000 ; N perthousand ; B 3 -14 1024 676 ;
+C 191 ; WX 444 ; N questiondown ; B 49 -217 395 458 ;
+C 193 ; WX 333 ; N grave ; B 16 507 243 678 ;
+C 194 ; WX 333 ; N acute ; B 93 507 317 678 ;
+C 195 ; WX 333 ; N circumflex ; B 11 507 323 674 ;
+C 196 ; WX 333 ; N tilde ; B 1 532 332 638 ;
+C 197 ; WX 333 ; N macron ; B 11 547 323 601 ;
+C 198 ; WX 333 ; N breve ; B 26 507 308 664 ;
+C 199 ; WX 333 ; N dotaccent ; B 116 523 216 623 ;
+C 200 ; WX 333 ; N dieresis ; B 18 523 316 623 ;
+C 202 ; WX 333 ; N ring ; B 67 483 266 682 ;
+C 203 ; WX 333 ; N cedilla ; B 53 -215 262 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 8 528 372 700 ;
+C 206 ; WX 333 ; N ogonek ; B 68 -155 245 -10 ;
+C 207 ; WX 333 ; N caron ; B 11 507 323 674 ;
+C 208 ; WX 1000 ; N emdash ; B -8 201 1007 250 ;
+C 225 ; WX 889 ; N AE ; B 5 0 869 662 ;
+C 227 ; WX 276 ; N ordfeminine ; B 15 307 278 676 ;
+C 232 ; WX 611 ; N Lslash ; B 12 0 598 662 ;
+C 233 ; WX 722 ; N Oslash ; B 33 -80 688 734 ;
+C 234 ; WX 889 ; N OE ; B 21 -7 877 669 ;
+C 235 ; WX 310 ; N ordmasculine ; B 15 307 301 676 ;
+C 241 ; WX 667 ; N ae ; B 38 -10 634 458 ;
+C 245 ; WX 278 ; N dotlessi ; B 22 0 259 458 ;
+C 248 ; WX 278 ; N lslash ; B 20 0 259 682 ;
+C 249 ; WX 500 ; N oslash ; B 30 -108 470 549 ;
+C 250 ; WX 722 ; N oe ; B 30 -10 690 458 ;
+C 251 ; WX 500 ; N germandbls ; B 12 -10 468 682 ;
+C -1 ; WX 722 ; N Aacute ; B 15 0 706 892 ;
+C -1 ; WX 722 ; N Acircumflex ; B 15 0 706 888 ;
+C -1 ; WX 722 ; N Adieresis ; B 15 0 706 837 ;
+C -1 ; WX 722 ; N Agrave ; B 15 0 706 892 ;
+C -1 ; WX 722 ; N Aring ; B 15 0 706 896 ;
+C -1 ; WX 722 ; N Atilde ; B 15 0 706 852 ;
+C -1 ; WX 667 ; N Ccedilla ; B 33 -215 637 676 ;
+C -1 ; WX 611 ; N Eacute ; B 12 0 597 892 ;
+C -1 ; WX 611 ; N Ecircumflex ; B 12 0 597 888 ;
+C -1 ; WX 611 ; N Edieresis ; B 12 0 597 837 ;
+C -1 ; WX 611 ; N Egrave ; B 12 0 597 892 ;
+C -1 ; WX 722 ; N Eth ; B 20 0 689 662 ;
+C -1 ; WX 333 ; N Iacute ; B 18 0 317 892 ;
+C -1 ; WX 333 ; N Icircumflex ; B 11 0 323 888 ;
+C -1 ; WX 333 ; N Idieresis ; B 18 0 316 837 ;
+C -1 ; WX 333 ; N Igrave ; B 16 0 316 892 ;
+C -1 ; WX 722 ; N Ntilde ; B 12 -14 709 852 ;
+C -1 ; WX 722 ; N Oacute ; B 33 -14 688 892 ;
+C -1 ; WX 722 ; N Ocircumflex ; B 33 -14 688 888 ;
+C -1 ; WX 722 ; N Odieresis ; B 33 -14 688 837 ;
+C -1 ; WX 722 ; N Ograve ; B 33 -14 688 892 ;
+C -1 ; WX 722 ; N Otilde ; B 33 -14 688 852 ;
+C -1 ; WX 556 ; N Scaron ; B 42 -14 491 888 ;
+C -1 ; WX 556 ; N Thorn ; B 11 0 542 662 ;
+C -1 ; WX 722 ; N Uacute ; B 16 -14 705 892 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 16 -14 705 888 ;
+C -1 ; WX 722 ; N Udieresis ; B 16 -14 705 837 ;
+C -1 ; WX 722 ; N Ugrave ; B 16 -14 705 892 ;
+C -1 ; WX 722 ; N Yacute ; B 22 0 703 892 ;
+C -1 ; WX 722 ; N Ydieresis ; B 22 0 703 837 ;
+C -1 ; WX 611 ; N Zcaron ; B 7 0 597 888 ;
+C -1 ; WX 444 ; N aacute ; B 37 -10 442 678 ;
+C -1 ; WX 444 ; N acircumflex ; B 37 -10 442 674 ;
+C -1 ; WX 444 ; N adieresis ; B 37 -10 442 623 ;
+C -1 ; WX 444 ; N agrave ; B 37 -10 442 678 ;
+C -1 ; WX 444 ; N aring ; B 37 -10 442 682 ;
+C -1 ; WX 444 ; N atilde ; B 37 -10 442 638 ;
+C -1 ; WX 200 ; N brokenbar ; B 68 0 132 682 ;
+C -1 ; WX 444 ; N ccedilla ; B 25 -215 412 458 ;
+C -1 ; WX 760 ; N copyright ; B 42 -14 717 676 ;
+C -1 ; WX 400 ; N degree ; B 50 376 350 676 ;
+C -1 ; WX 564 ; N divide ; B 30 10 534 512 ;
+C -1 ; WX 444 ; N eacute ; B 22 -10 421 678 ;
+C -1 ; WX 444 ; N ecircumflex ; B 22 -10 421 674 ;
+C -1 ; WX 444 ; N edieresis ; B 22 -10 421 623 ;
+C -1 ; WX 444 ; N egrave ; B 22 -10 421 678 ;
+C -1 ; WX 500 ; N eth ; B 30 -10 470 682 ;
+C -1 ; WX 278 ; N iacute ; B 22 0 290 678 ;
+C -1 ; WX 278 ; N icircumflex ; B -16 0 296 674 ;
+C -1 ; WX 278 ; N idieresis ; B -9 0 289 623 ;
+C -1 ; WX 278 ; N igrave ; B -11 0 259 678 ;
+C -1 ; WX 564 ; N logicalnot ; B 30 120 534 390 ;
+C -1 ; WX 564 ; N minus ; B 30 229 534 293 ;
+C -1 ; WX 500 ; N mu ; B 9 -223 479 448 ;
+C -1 ; WX 564 ; N multiply ; B 30 8 534 512 ;
+C -1 ; WX 500 ; N ntilde ; B 9 0 490 638 ;
+C -1 ; WX 500 ; N oacute ; B 30 -10 470 678 ;
+C -1 ; WX 500 ; N ocircumflex ; B 30 -10 470 674 ;
+C -1 ; WX 500 ; N odieresis ; B 30 -10 470 623 ;
+C -1 ; WX 500 ; N ograve ; B 30 -10 470 678 ;
+C -1 ; WX 750 ; N onehalf ; B 30 -14 720 676 ;
+C -1 ; WX 750 ; N onequarter ; B 30 -14 720 676 ;
+C -1 ; WX 300 ; N onesuperior ; B 58 270 242 676 ;
+C -1 ; WX 500 ; N otilde ; B 30 -10 470 638 ;
+C -1 ; WX 564 ; N plusminus ; B 30 0 534 612 ;
+C -1 ; WX 760 ; N registered ; B 43 -14 718 676 ;
+C -1 ; WX 389 ; N scaron ; B 39 -10 351 674 ;
+C -1 ; WX 500 ; N thorn ; B 2 -217 470 682 ;
+C -1 ; WX 750 ; N threequarters ; B 30 -14 720 676 ;
+C -1 ; WX 300 ; N threesuperior ; B 24 262 275 676 ;
+C -1 ; WX 980 ; N trademark ; B 35 258 945 662 ;
+C -1 ; WX 300 ; N twosuperior ; B 5 270 294 676 ;
+C -1 ; WX 500 ; N uacute ; B 9 -10 479 678 ;
+C -1 ; WX 500 ; N ucircumflex ; B 9 -10 479 674 ;
+C -1 ; WX 500 ; N udieresis ; B 9 -10 479 623 ;
+C -1 ; WX 500 ; N ugrave ; B 9 -10 479 678 ;
+C -1 ; WX 500 ; N yacute ; B 15 -217 476 678 ;
+C -1 ; WX 500 ; N ydieresis ; B 15 -217 476 623 ;
+C -1 ; WX 444 ; N zcaron ; B 25 0 418 674 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 113
+
+KPX A y -92
+KPX A w -92
+KPX A v -74
+KPX A space -55
+KPX A quoteright -111
+KPX A Y -92
+KPX A W -80
+KPX A V -129
+KPX A T -111
+
+KPX F period -80
+KPX F comma -80
+KPX F A -74
+
+KPX L y -55
+KPX L space -37
+KPX L quoteright -92
+KPX L Y -100
+KPX L W -74
+KPX L V -92
+KPX L T -92
+
+KPX P space -37
+KPX P period -111
+KPX P comma -111
+KPX P A -92
+
+KPX R y -40
+KPX R Y -55
+KPX R W -55
+KPX R V -80
+KPX R T -60
+
+KPX T y -70
+KPX T w -70
+KPX T u -35
+KPX T space -18
+KPX T semicolon -55
+KPX T s -70
+KPX T r -35
+KPX T period -74
+KPX T o -70
+KPX T i -35
+KPX T hyphen -92
+KPX T e -70
+KPX T comma -74
+KPX T colon -50
+KPX T c -70
+KPX T a -70
+KPX T O -18
+KPX T A -80
+
+KPX V y -111
+KPX V u -60
+KPX V space -18
+KPX V semicolon -74
+KPX V r -60
+KPX V period -129
+KPX V o -129
+KPX V i -60
+KPX V hyphen -92
+KPX V e -111
+KPX V comma -129
+KPX V colon -74
+KPX V a -111
+KPX V A -129
+
+KPX W y -60
+KPX W u -40
+KPX W space -18
+KPX W semicolon -37
+KPX W r -40
+KPX W period -92
+KPX W o -80
+KPX W i -40
+KPX W hyphen -55
+KPX W e -80
+KPX W comma -92
+KPX W colon -37
+KPX W a -80
+KPX W A -111
+
+KPX Y v -100
+KPX Y u -111
+KPX Y space -37
+KPX Y semicolon -92
+KPX Y q -111
+KPX Y period -129
+KPX Y p -92
+KPX Y o -100
+KPX Y i -55
+KPX Y hyphen -111
+KPX Y e -100
+KPX Y comma -129
+KPX Y colon -92
+KPX Y a -100
+KPX Y A -111
+
+KPX f quoteright 55
+KPX f f -18
+
+KPX one one -37
+
+KPX quoteleft quoteleft -74
+
+KPX quoteright t -18
+KPX quoteright space -74
+KPX quoteright s -55
+KPX quoteright quoteright -74
+
+KPX r quoteright 37
+KPX r period -55
+KPX r hyphen -20
+KPX r g -18
+KPX r comma -40
+
+KPX space Y -37
+KPX space W -18
+KPX space V -18
+KPX space T -18
+KPX space A -55
+
+KPX v period -65
+KPX v comma -65
+
+KPX w period -65
+KPX w comma -65
+
+KPX y period -65
+KPX y comma -65
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 214 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 55 0 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 111 214 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 167 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 55 0 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 194 214 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 83 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 194 214 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 194 214 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 194 214 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 194 214 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 83 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 83 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 83 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 83 0 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 214 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 0 214 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 0 214 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 214 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 139 214 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 139 214 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 139 214 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 139 214 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 55 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 55 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 55 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 55 0 ;
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 194 214 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 194 214 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 194 214 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 194 214 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 55 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 55 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 55 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 55 0 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 194 214 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 194 214 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 194 214 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 194 214 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 83 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 83 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 83 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 83 0 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 194 214 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 55 0 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 194 214 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 83 0 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 194 214 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 83 0 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 194 214 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 55 0 ;
+EndComposites
+EndFontMetrics
diff --git a/misc/gs_afm/Cour.afm b/misc/gs_afm/Cour.afm
new file mode 100644
index 0000000000..2ccfea4b0f
--- /dev/null
+++ b/misc/gs_afm/Cour.afm
@@ -0,0 +1,255 @@
+StartFontMetrics 3.0
+Comment Copyright URW Software, Copyright 1994 by URW
+Comment Creation Date: 8/19/1994
+Comment See the file PUBLIC (Aladdin Free Public License) for license conditions.
+FontName NimbusMonL-Regu
+FullName Nimbus Mono L Regular
+FamilyName Nimbus Mono L
+Weight Regular
+ItalicAngle 0.0
+IsFixedPitch false
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.005
+Notice URW Software, Copyright 1994 by URW
+EncodingScheme AdobeStandardEncoding
+FontBBox -12 -216 612 811
+CapHeight 563
+XHeight 417
+Descender -186
+Ascender 604
+StartCharMetrics 232
+C 32 ; WX 600 ; N space ; B 295 0 295 0 ;
+C 33 ; WX 600 ; N exclam ; B 240 -15 360 618 ;
+C 34 ; WX 600 ; N quotedbl ; B 146 315 454 604 ;
+C 35 ; WX 600 ; N numbersign ; B 92 -62 508 647 ;
+C 36 ; WX 600 ; N dollar ; B 113 -92 487 655 ;
+C 37 ; WX 600 ; N percent ; B 87 -12 513 611 ;
+C 38 ; WX 600 ; N ampersand ; B 105 -16 478 519 ;
+C 39 ; WX 600 ; N quoteright ; B 135 314 340 604 ;
+C 40 ; WX 600 ; N parenleft ; B 294 -124 458 604 ;
+C 41 ; WX 600 ; N parenright ; B 147 -124 311 604 ;
+C 42 ; WX 600 ; N asterisk ; B 113 250 487 604 ;
+C 43 ; WX 600 ; N plus ; B 72 32 528 530 ;
+C 44 ; WX 600 ; N comma ; B 135 -145 340 145 ;
+C 45 ; WX 600 ; N hyphen ; B 72 258 528 299 ;
+C 46 ; WX 600 ; N period ; B 226 -15 374 116 ;
+C 47 ; WX 600 ; N slash ; B 113 -81 487 668 ;
+C 48 ; WX 600 ; N zero ; B 113 -15 487 618 ;
+C 49 ; WX 600 ; N one ; B 113 0 487 612 ;
+C 50 ; WX 600 ; N two ; B 84 0 478 618 ;
+C 51 ; WX 600 ; N three ; B 96 -15 499 618 ;
+C 52 ; WX 600 ; N four ; B 105 0 478 604 ;
+C 53 ; WX 600 ; N five ; B 96 -15 499 604 ;
+C 54 ; WX 600 ; N six ; B 136 -15 510 618 ;
+C 55 ; WX 600 ; N seven ; B 105 -1 478 604 ;
+C 56 ; WX 600 ; N eight ; B 113 -15 487 618 ;
+C 57 ; WX 600 ; N nine ; B 136 -15 510 618 ;
+C 58 ; WX 600 ; N colon ; B 226 -15 374 417 ;
+C 59 ; WX 600 ; N semicolon ; B 139 -145 350 417 ;
+C 60 ; WX 600 ; N less ; B 72 44 522 518 ;
+C 61 ; WX 600 ; N equal ; B 51 190 549 375 ;
+C 62 ; WX 600 ; N greater ; B 78 44 528 518 ;
+C 63 ; WX 600 ; N question ; B 134 -15 487 577 ;
+C 64 ; WX 600 ; N at ; B 105 -62 478 624 ;
+C 65 ; WX 600 ; N A ; B 9 0 591 563 ;
+C 66 ; WX 600 ; N B ; B 43 0 541 563 ;
+C 67 ; WX 600 ; N C ; B 63 -16 534 576 ;
+C 68 ; WX 600 ; N D ; B 43 0 520 563 ;
+C 69 ; WX 600 ; N E ; B 43 0 520 563 ;
+C 70 ; WX 600 ; N F ; B 43 0 520 563 ;
+C 71 ; WX 600 ; N G ; B 63 -16 562 576 ;
+C 72 ; WX 600 ; N H ; B 53 0 551 563 ;
+C 73 ; WX 600 ; N I ; B 113 0 487 563 ;
+C 74 ; WX 600 ; N J ; B 84 -16 583 563 ;
+C 75 ; WX 600 ; N K ; B 43 0 572 563 ;
+C 76 ; WX 600 ; N L ; B 63 0 541 563 ;
+C 77 ; WX 600 ; N M ; B 11 0 593 563 ;
+C 78 ; WX 600 ; N N ; B 22 0 562 563 ;
+C 79 ; WX 600 ; N O ; B 51 -16 549 576 ;
+C 80 ; WX 600 ; N P ; B 43 0 499 563 ;
+C 81 ; WX 600 ; N Q ; B 51 -115 549 576 ;
+C 82 ; WX 600 ; N R ; B 43 0 589 563 ;
+C 83 ; WX 600 ; N S ; B 92 -16 508 576 ;
+C 84 ; WX 600 ; N T ; B 72 0 528 563 ;
+C 85 ; WX 600 ; N U ; B 40 -16 560 563 ;
+C 86 ; WX 600 ; N V ; B 9 0 591 563 ;
+C 87 ; WX 600 ; N W ; B 20 0 580 563 ;
+C 88 ; WX 600 ; N X ; B 40 0 560 563 ;
+C 89 ; WX 600 ; N Y ; B 51 0 549 563 ;
+C 90 ; WX 600 ; N Z ; B 103 0 497 563 ;
+C 91 ; WX 600 ; N bracketleft ; B 280 -124 445 604 ;
+C 92 ; WX 600 ; N backslash ; B 113 -81 487 668 ;
+C 93 ; WX 600 ; N bracketright ; B 155 -124 320 604 ;
+C 94 ; WX 600 ; N asciicircum ; B 113 354 487 615 ;
+C 95 ; WX 600 ; N underscore ; B -12 -125 612 -75 ;
+C 96 ; WX 600 ; N quoteleft ; B 260 343 465 604 ;
+C 97 ; WX 600 ; N a ; B 72 -16 541 431 ;
+C 98 ; WX 600 ; N b ; B 22 -16 541 604 ;
+C 99 ; WX 600 ; N c ; B 84 -16 535 431 ;
+C 100 ; WX 600 ; N d ; B 63 -16 583 604 ;
+C 101 ; WX 600 ; N e ; B 63 -16 520 431 ;
+C 102 ; WX 600 ; N f ; B 105 0 541 604 ;
+C 103 ; WX 600 ; N g ; B 63 -186 562 431 ;
+C 104 ; WX 600 ; N h ; B 43 0 551 604 ;
+C 105 ; WX 600 ; N i ; B 92 0 508 624 ;
+C 106 ; WX 600 ; N j ; B 147 -186 458 624 ;
+C 107 ; WX 600 ; N k ; B 63 0 541 604 ;
+C 108 ; WX 600 ; N l ; B 92 0 508 604 ;
+C 109 ; WX 600 ; N m ; B 11 0 593 431 ;
+C 110 ; WX 600 ; N n ; B 53 0 541 431 ;
+C 111 ; WX 600 ; N o ; B 72 -16 528 431 ;
+C 112 ; WX 600 ; N p ; B 22 -186 541 431 ;
+C 113 ; WX 600 ; N q ; B 63 -186 583 431 ;
+C 114 ; WX 600 ; N r ; B 84 0 541 427 ;
+C 115 ; WX 600 ; N s ; B 103 -16 497 431 ;
+C 116 ; WX 600 ; N t ; B 43 -16 499 563 ;
+C 117 ; WX 600 ; N u ; B 43 -16 541 417 ;
+C 118 ; WX 600 ; N v ; B 30 0 570 417 ;
+C 119 ; WX 600 ; N w ; B 30 0 570 417 ;
+C 120 ; WX 600 ; N x ; B 51 0 549 417 ;
+C 121 ; WX 600 ; N y ; B 51 -186 549 417 ;
+C 122 ; WX 600 ; N z ; B 115 0 489 417 ;
+C 123 ; WX 600 ; N braceleft ; B 197 -124 403 604 ;
+C 124 ; WX 600 ; N bar ; B 280 -124 320 604 ;
+C 125 ; WX 600 ; N braceright ; B 197 -124 403 604 ;
+C 126 ; WX 600 ; N asciitilde ; B 92 212 508 348 ;
+C 161 ; WX 600 ; N exclamdown ; B 240 -216 360 417 ;
+C 162 ; WX 600 ; N cent ; B 113 -13 469 630 ;
+C 163 ; WX 600 ; N sterling ; B 63 0 520 578 ;
+C 164 ; WX 600 ; N fraction ; B 50 139 549 470 ;
+C 165 ; WX 600 ; N yen ; B 51 0 549 563 ;
+C 166 ; WX 600 ; N florin ; B 87 -93 518 618 ;
+C 167 ; WX 600 ; N section ; B 66 -62 534 603 ;
+C 168 ; WX 600 ; N currency ; B 103 95 497 489 ;
+C 169 ; WX 600 ; N quotesingle ; B 236 315 364 604 ;
+C 170 ; WX 600 ; N quotedblleft ; B 93 343 507 604 ;
+C 171 ; WX 600 ; N guillemotleft ; B 63 0 541 417 ;
+C 172 ; WX 600 ; N guilsinglleft ; B 63 0 312 417 ;
+C 173 ; WX 600 ; N guilsinglright ; B 293 0 541 417 ;
+C 174 ; WX 600 ; N fi ; B 10 0 585 624 ;
+C 175 ; WX 600 ; N fl ; B 10 0 587 604 ;
+C 177 ; WX 600 ; N endash ; B 72 261 528 302 ;
+C 178 ; WX 600 ; N dagger ; B 124 -63 476 604 ;
+C 179 ; WX 600 ; N daggerdbl ; B 124 -62 476 604 ;
+C 180 ; WX 600 ; N periodcentered ; B 226 217 374 348 ;
+C 182 ; WX 600 ; N paragraph ; B 79 -62 525 604 ;
+C 183 ; WX 600 ; N bullet ; B 202 141 398 337 ;
+C 184 ; WX 600 ; N quotesinglbase ; B 135 -145 340 145 ;
+C 185 ; WX 600 ; N quotedblbase ; B 93 -116 507 145 ;
+C 186 ; WX 600 ; N quotedblright ; B 93 343 507 604 ;
+C 187 ; WX 600 ; N guillemotright ; B 63 0 541 417 ;
+C 188 ; WX 600 ; N ellipsis ; B 51 -15 549 84 ;
+C 189 ; WX 600 ; N perthousand ; B 34 -9 564 614 ;
+C 191 ; WX 600 ; N questiondown ; B 113 -175 466 417 ;
+C 193 ; WX 600 ; N grave ; B 155 490 320 639 ;
+C 194 ; WX 600 ; N acute ; B 280 490 445 639 ;
+C 195 ; WX 600 ; N circumflex ; B 155 490 445 639 ;
+C 196 ; WX 600 ; N tilde ; B 145 516 455 605 ;
+C 197 ; WX 600 ; N macron ; B 155 536 445 576 ;
+C 198 ; WX 600 ; N breve ; B 155 490 445 620 ;
+C 199 ; WX 600 ; N dotaccent ; B 250 511 350 611 ;
+C 200 ; WX 600 ; N dieresis ; B 140 511 461 611 ;
+C 202 ; WX 600 ; N ring ; B 207 480 393 661 ;
+C 203 ; WX 600 ; N cedilla ; B 210 -173 377 0 ;
+C 205 ; WX 600 ; N hungarumlaut ; B 155 490 445 633 ;
+C 206 ; WX 600 ; N ogonek ; B 280 -155 433 0 ;
+C 207 ; WX 600 ; N caron ; B 155 490 445 639 ;
+C 208 ; WX 600 ; N emdash ; B 1 261 599 302 ;
+C 225 ; WX 600 ; N AE ; B 10 0 590 563 ;
+C 227 ; WX 600 ; N ordfeminine ; B 155 279 447 574 ;
+C 232 ; WX 600 ; N Lslash ; B 43 0 541 563 ;
+C 233 ; WX 600 ; N Oslash ; B 40 -43 560 605 ;
+C 234 ; WX 600 ; N OE ; B 10 0 590 563 ;
+C 235 ; WX 600 ; N ordmasculine ; B 154 284 448 577 ;
+C 241 ; WX 600 ; N ae ; B 12 -16 578 431 ;
+C 245 ; WX 600 ; N dotlessi ; B 92 0 508 417 ;
+C 248 ; WX 600 ; N lslash ; B 92 0 508 604 ;
+C 249 ; WX 600 ; N oslash ; B 53 -43 543 458 ;
+C 250 ; WX 600 ; N oe ; B 12 -16 578 431 ;
+C 251 ; WX 600 ; N germandbls ; B 43 -16 499 604 ;
+C -1 ; WX 600 ; N Yacute ; B 51 0 549 789 ;
+C -1 ; WX 600 ; N Ucircumflex ; B 40 -16 560 789 ;
+C -1 ; WX 600 ; N Ugrave ; B 40 -16 560 789 ;
+C -1 ; WX 600 ; N Zcaron ; B 103 0 497 789 ;
+C -1 ; WX 600 ; N Ydieresis ; B 51 0 549 761 ;
+C -1 ; WX 600 ; N threesuperior ; B 181 251 416 612 ;
+C -1 ; WX 600 ; N Uacute ; B 40 -16 560 789 ;
+C -1 ; WX 600 ; N twosuperior ; B 175 259 405 612 ;
+C -1 ; WX 600 ; N Udieresis ; B 40 -16 560 761 ;
+C -1 ; WX 600 ; N middot ; B 226 217 374 348 ;
+C -1 ; WX 600 ; N onesuperior ; B 191 259 410 612 ;
+C -1 ; WX 600 ; N aacute ; B 72 -16 541 639 ;
+C -1 ; WX 600 ; N agrave ; B 72 -16 541 639 ;
+C -1 ; WX 600 ; N acircumflex ; B 72 -16 541 639 ;
+C -1 ; WX 600 ; N Scaron ; B 92 -16 508 789 ;
+C -1 ; WX 600 ; N Otilde ; B 51 -16 549 755 ;
+C -1 ; WX 600 ; N sfthyphen ; B 72 258 528 299 ;
+C -1 ; WX 600 ; N atilde ; B 72 -16 541 605 ;
+C -1 ; WX 600 ; N aring ; B 72 -16 541 661 ;
+C -1 ; WX 600 ; N adieresis ; B 72 -16 541 611 ;
+C -1 ; WX 600 ; N Ograve ; B 51 -16 549 789 ;
+C -1 ; WX 600 ; N Ocircumflex ; B 51 -16 549 789 ;
+C -1 ; WX 600 ; N Odieresis ; B 51 -16 549 761 ;
+C -1 ; WX 600 ; N Ntilde ; B 22 0 562 755 ;
+C -1 ; WX 600 ; N edieresis ; B 63 -16 520 611 ;
+C -1 ; WX 600 ; N eacute ; B 63 -16 520 639 ;
+C -1 ; WX 600 ; N egrave ; B 63 -16 520 639 ;
+C -1 ; WX 600 ; N Icircumflex ; B 113 0 487 789 ;
+C -1 ; WX 600 ; N ecircumflex ; B 63 -16 520 639 ;
+C -1 ; WX 600 ; N Igrave ; B 113 0 487 789 ;
+C -1 ; WX 600 ; N Iacute ; B 113 0 487 789 ;
+C -1 ; WX 600 ; N Idieresis ; B 113 0 487 761 ;
+C -1 ; WX 600 ; N degree ; B 155 346 445 636 ;
+C -1 ; WX 600 ; N Ecircumflex ; B 43 0 520 789 ;
+C -1 ; WX 600 ; N minus ; B 72 261 528 302 ;
+C -1 ; WX 600 ; N multiply ; B 118 100 482 464 ;
+C -1 ; WX 600 ; N divide ; B 72 25 528 540 ;
+C -1 ; WX 600 ; N Egrave ; B 43 0 520 789 ;
+C -1 ; WX 600 ; N trademark ; B 4 243 598 563 ;
+C -1 ; WX 600 ; N Oacute ; B 51 -16 549 789 ;
+C -1 ; WX 600 ; N thorn ; B 22 -186 541 590 ;
+C -1 ; WX 600 ; N eth ; B 72 -17 528 620 ;
+C -1 ; WX 600 ; N Eacute ; B 43 0 520 789 ;
+C -1 ; WX 600 ; N ccedilla ; B 84 -173 535 431 ;
+C -1 ; WX 600 ; N idieresis ; B 92 0 508 611 ;
+C -1 ; WX 600 ; N iacute ; B 92 0 508 639 ;
+C -1 ; WX 600 ; N igrave ; B 92 0 508 639 ;
+C -1 ; WX 600 ; N plusminus ; B 72 0 528 529 ;
+C -1 ; WX 600 ; N onehalf ; B 23 0 573 612 ;
+C -1 ; WX 600 ; N onequarter ; B 16 0 580 612 ;
+C -1 ; WX 600 ; N threequarters ; B 6 0 580 612 ;
+C -1 ; WX 600 ; N icircumflex ; B 92 0 508 639 ;
+C -1 ; WX 600 ; N Edieresis ; B 43 0 520 761 ;
+C -1 ; WX 600 ; N ntilde ; B 53 0 541 605 ;
+C -1 ; WX 600 ; N Aring ; B 9 0 591 811 ;
+C -1 ; WX 600 ; N odieresis ; B 72 -16 528 611 ;
+C -1 ; WX 600 ; N oacute ; B 72 -16 528 639 ;
+C -1 ; WX 600 ; N ograve ; B 72 -16 528 639 ;
+C -1 ; WX 600 ; N ocircumflex ; B 72 -16 528 639 ;
+C -1 ; WX 600 ; N otilde ; B 72 -16 528 605 ;
+C -1 ; WX 600 ; N scaron ; B 103 -16 497 639 ;
+C -1 ; WX 600 ; N udieresis ; B 43 -16 541 611 ;
+C -1 ; WX 600 ; N uacute ; B 43 -16 541 639 ;
+C -1 ; WX 600 ; N ugrave ; B 43 -16 541 639 ;
+C -1 ; WX 600 ; N ucircumflex ; B 43 -16 541 639 ;
+C -1 ; WX 600 ; N yacute ; B 51 -186 549 639 ;
+C -1 ; WX 600 ; N zcaron ; B 115 0 489 639 ;
+C -1 ; WX 600 ; N ydieresis ; B 51 -186 549 611 ;
+C -1 ; WX 600 ; N copyright ; B 3 -15 596 578 ;
+C -1 ; WX 600 ; N registered ; B 3 -15 596 578 ;
+C -1 ; WX 600 ; N Atilde ; B 9 0 591 755 ;
+C -1 ; WX 600 ; N nbspace ; B 295 0 295 0 ;
+C -1 ; WX 600 ; N Ccedilla ; B 63 -173 534 576 ;
+C -1 ; WX 600 ; N Acircumflex ; B 9 0 591 789 ;
+C -1 ; WX 600 ; N Agrave ; B 9 0 591 789 ;
+C -1 ; WX 600 ; N logicalnot ; B 72 168 528 438 ;
+C -1 ; WX 600 ; N Aacute ; B 9 0 591 789 ;
+C -1 ; WX 600 ; N Eth ; B 0 0 520 563 ;
+C -1 ; WX 600 ; N brokenbar ; B 280 -124 320 604 ;
+C -1 ; WX 600 ; N Thorn ; B 43 0 499 563 ;
+C -1 ; WX 600 ; N Adieresis ; B 9 0 591 761 ;
+C -1 ; WX 600 ; N mu ; B 43 -200 541 417 ;
+C -1 ; WX 600 ; N .notdef ; B 295 0 295 0 ;
+EndCharMetrics
+EndFontMetrics
diff --git a/misc/gs_afm/CourBo.afm b/misc/gs_afm/CourBo.afm
new file mode 100644
index 0000000000..2ea312d1fb
--- /dev/null
+++ b/misc/gs_afm/CourBo.afm
@@ -0,0 +1,255 @@
+StartFontMetrics 3.0
+Comment Copyright URW Software, Copyright 1994 by URW
+Comment Creation Date: 8/3/1994
+Comment See the file PUBLIC (Aladdin Free Public License) for license conditions.
+FontName NimbusMonL-Bold
+FullName Nimbus Mono L Bold
+FamilyName Nimbus Mono L
+Weight Bold
+ItalicAngle 0.0
+IsFixedPitch false
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.005
+Notice URW Software, Copyright 1994 by URW
+EncodingScheme AdobeStandardEncoding
+FontBBox -43 -229 630 871
+CapHeight 583
+XHeight 437
+Descender -205
+Ascender 624
+StartCharMetrics 232
+C 32 ; WX 600 ; N space ; B 375 0 375 0 ;
+C 33 ; WX 600 ; N exclam ; B 220 -15 381 638 ;
+C 34 ; WX 600 ; N quotedbl ; B 136 312 464 602 ;
+C 35 ; WX 600 ; N numbersign ; B 62 -92 538 675 ;
+C 36 ; WX 600 ; N dollar ; B 83 -123 517 684 ;
+C 37 ; WX 600 ; N percent ; B 80 -15 521 617 ;
+C 38 ; WX 600 ; N ampersand ; B 75 -14 508 550 ;
+C 39 ; WX 600 ; N quoteright ; B 147 331 351 623 ;
+C 40 ; WX 600 ; N parenleft ; B 264 -153 488 632 ;
+C 41 ; WX 600 ; N parenright ; B 117 -153 341 632 ;
+C 42 ; WX 600 ; N asterisk ; B 83 208 517 622 ;
+C 43 ; WX 600 ; N plus ; B 42 0 558 560 ;
+C 44 ; WX 600 ; N comma ; B 147 -158 351 134 ;
+C 45 ; WX 600 ; N hyphen ; B 42 229 558 329 ;
+C 46 ; WX 600 ; N period ; B 225 -15 375 117 ;
+C 47 ; WX 600 ; N slash ; B 83 -113 517 695 ;
+C 48 ; WX 600 ; N zero ; B 83 -15 517 638 ;
+C 49 ; WX 600 ; N one ; B 83 0 517 638 ;
+C 50 ; WX 600 ; N two ; B 54 0 508 638 ;
+C 51 ; WX 600 ; N three ; B 66 -15 529 638 ;
+C 52 ; WX 600 ; N four ; B 75 0 508 622 ;
+C 53 ; WX 600 ; N five ; B 66 -15 529 622 ;
+C 54 ; WX 600 ; N six ; B 105 -15 540 638 ;
+C 55 ; WX 600 ; N seven ; B 75 -1 508 622 ;
+C 56 ; WX 600 ; N eight ; B 83 -15 517 638 ;
+C 57 ; WX 600 ; N nine ; B 106 -15 541 638 ;
+C 58 ; WX 600 ; N colon ; B 225 -15 375 437 ;
+C 59 ; WX 600 ; N semicolon ; B 147 -158 351 437 ;
+C 60 ; WX 600 ; N less ; B 42 54 544 501 ;
+C 61 ; WX 600 ; N equal ; B 42 138 558 422 ;
+C 62 ; WX 600 ; N greater ; B 56 53 558 500 ;
+C 63 ; WX 600 ; N question ; B 104 -15 517 598 ;
+C 64 ; WX 600 ; N at ; B 76 -151 509 620 ;
+C 65 ; WX 600 ; N A ; B -21 0 621 583 ;
+C 66 ; WX 600 ; N B ; B 13 0 571 583 ;
+C 67 ; WX 600 ; N C ; B 33 -14 564 597 ;
+C 68 ; WX 600 ; N D ; B 13 0 550 583 ;
+C 69 ; WX 600 ; N E ; B 13 0 550 583 ;
+C 70 ; WX 600 ; N F ; B 13 0 550 583 ;
+C 71 ; WX 600 ; N G ; B 33 -14 592 597 ;
+C 72 ; WX 600 ; N H ; B 23 0 581 583 ;
+C 73 ; WX 600 ; N I ; B 83 0 517 583 ;
+C 74 ; WX 600 ; N J ; B 54 -14 613 583 ;
+C 75 ; WX 600 ; N K ; B 13 0 602 584 ;
+C 76 ; WX 600 ; N L ; B 33 0 571 583 ;
+C 77 ; WX 600 ; N M ; B -19 0 623 584 ;
+C 78 ; WX 600 ; N N ; B -8 0 592 583 ;
+C 79 ; WX 600 ; N O ; B 21 -14 579 597 ;
+C 80 ; WX 600 ; N P ; B 13 0 529 583 ;
+C 81 ; WX 600 ; N Q ; B 21 -145 579 597 ;
+C 82 ; WX 600 ; N R ; B 13 0 619 583 ;
+C 83 ; WX 600 ; N S ; B 62 -14 538 597 ;
+C 84 ; WX 600 ; N T ; B 42 0 558 583 ;
+C 85 ; WX 600 ; N U ; B 10 -14 590 583 ;
+C 86 ; WX 600 ; N V ; B -21 0 621 583 ;
+C 87 ; WX 600 ; N W ; B -10 0 610 583 ;
+C 88 ; WX 600 ; N X ; B 10 0 590 584 ;
+C 89 ; WX 600 ; N Y ; B 21 0 579 584 ;
+C 90 ; WX 600 ; N Z ; B 73 0 527 583 ;
+C 91 ; WX 600 ; N bracketleft ; B 250 -148 475 627 ;
+C 92 ; WX 600 ; N backslash ; B 83 -113 517 695 ;
+C 93 ; WX 600 ; N bracketright ; B 125 -148 350 627 ;
+C 94 ; WX 600 ; N asciicircum ; B 83 325 517 652 ;
+C 95 ; WX 600 ; N underscore ; B -12 -125 612 -75 ;
+C 96 ; WX 600 ; N quoteleft ; B 249 348 453 602 ;
+C 97 ; WX 600 ; N a ; B 42 -16 571 450 ;
+C 98 ; WX 600 ; N b ; B -8 -14 571 624 ;
+C 99 ; WX 600 ; N c ; B 54 -16 565 450 ;
+C 100 ; WX 600 ; N d ; B 33 -14 613 624 ;
+C 101 ; WX 600 ; N e ; B 33 -16 550 450 ;
+C 102 ; WX 600 ; N f ; B 75 0 571 623 ;
+C 103 ; WX 600 ; N g ; B 33 -205 592 451 ;
+C 104 ; WX 600 ; N h ; B 13 0 581 624 ;
+C 105 ; WX 600 ; N i ; B 62 0 538 623 ;
+C 106 ; WX 600 ; N j ; B 117 -205 488 623 ;
+C 107 ; WX 600 ; N k ; B 33 0 571 624 ;
+C 108 ; WX 600 ; N l ; B 62 0 538 624 ;
+C 109 ; WX 600 ; N m ; B -19 0 623 450 ;
+C 110 ; WX 600 ; N n ; B 23 0 571 450 ;
+C 111 ; WX 600 ; N o ; B 42 -16 558 450 ;
+C 112 ; WX 600 ; N p ; B -8 -205 571 450 ;
+C 113 ; WX 600 ; N q ; B 33 -205 613 450 ;
+C 114 ; WX 600 ; N r ; B 54 0 571 449 ;
+C 115 ; WX 600 ; N s ; B 73 -16 527 450 ;
+C 116 ; WX 600 ; N t ; B 13 -16 529 591 ;
+C 117 ; WX 600 ; N u ; B 13 -13 571 437 ;
+C 118 ; WX 600 ; N v ; B 0 0 600 437 ;
+C 119 ; WX 600 ; N w ; B 0 0 600 437 ;
+C 120 ; WX 600 ; N x ; B 21 0 579 437 ;
+C 121 ; WX 600 ; N y ; B 21 -205 579 437 ;
+C 122 ; WX 600 ; N z ; B 85 0 519 437 ;
+C 123 ; WX 600 ; N braceleft ; B 167 -153 433 623 ;
+C 124 ; WX 600 ; N bar ; B 250 -153 350 622 ;
+C 125 ; WX 600 ; N braceright ; B 167 -153 433 623 ;
+C 126 ; WX 600 ; N asciitilde ; B 62 179 538 385 ;
+C 161 ; WX 600 ; N exclamdown ; B 220 -227 381 426 ;
+C 162 ; WX 600 ; N cent ; B 83 -44 499 661 ;
+C 163 ; WX 600 ; N sterling ; B 33 0 550 598 ;
+C 164 ; WX 600 ; N fraction ; B 21 102 580 500 ;
+C 165 ; WX 600 ; N yen ; B 21 0 579 580 ;
+C 166 ; WX 600 ; N florin ; B 57 -123 548 638 ;
+C 167 ; WX 600 ; N section ; B 36 -170 564 583 ;
+C 168 ; WX 600 ; N currency ; B 73 64 527 519 ;
+C 169 ; WX 600 ; N quotesingle ; B 236 312 364 602 ;
+C 170 ; WX 600 ; N quotedblleft ; B 98 348 502 602 ;
+C 171 ; WX 600 ; N guillemotleft ; B 33 20 571 415 ;
+C 172 ; WX 600 ; N guilsinglleft ; B 33 20 342 415 ;
+C 173 ; WX 600 ; N guilsinglright ; B 263 20 571 415 ;
+C 174 ; WX 600 ; N fi ; B -14 0 619 624 ;
+C 175 ; WX 600 ; N fl ; B -17 0 617 623 ;
+C 177 ; WX 600 ; N endash ; B 42 229 558 329 ;
+C 178 ; WX 600 ; N dagger ; B 94 -92 506 622 ;
+C 179 ; WX 600 ; N daggerdbl ; B 94 -92 506 622 ;
+C 180 ; WX 600 ; N periodcentered ; B 225 214 375 346 ;
+C 182 ; WX 600 ; N paragraph ; B 49 -174 558 583 ;
+C 183 ; WX 600 ; N bullet ; B 150 154 449 453 ;
+C 184 ; WX 600 ; N quotesinglbase ; B 147 -158 351 134 ;
+C 185 ; WX 600 ; N quotedblbase ; B 87 -120 491 134 ;
+C 186 ; WX 600 ; N quotedblright ; B 87 348 491 602 ;
+C 187 ; WX 600 ; N guillemotright ; B 33 20 571 415 ;
+C 188 ; WX 600 ; N ellipsis ; B 25 -15 575 117 ;
+C 189 ; WX 600 ; N perthousand ; B 0 0 600 618 ;
+C 191 ; WX 600 ; N questiondown ; B 83 -227 496 386 ;
+C 193 ; WX 600 ; N grave ; B 125 496 350 696 ;
+C 194 ; WX 600 ; N acute ; B 250 496 475 696 ;
+C 195 ; WX 600 ; N circumflex ; B 125 497 476 696 ;
+C 196 ; WX 600 ; N tilde ; B 115 523 485 656 ;
+C 197 ; WX 600 ; N macron ; B 125 546 475 626 ;
+C 198 ; WX 600 ; N breve ; B 125 503 475 687 ;
+C 199 ; WX 600 ; N dotaccent ; B 240 534 360 654 ;
+C 200 ; WX 600 ; N dieresis ; B 136 534 464 654 ;
+C 202 ; WX 600 ; N ring ; B 177 486 423 727 ;
+C 203 ; WX 600 ; N cedilla ; B 180 -229 407 0 ;
+C 205 ; WX 600 ; N hungarumlaut ; B 125 496 475 694 ;
+C 206 ; WX 600 ; N ogonek ; B 250 -208 463 0 ;
+C 207 ; WX 600 ; N caron ; B 125 497 476 696 ;
+C 208 ; WX 600 ; N emdash ; B -29 229 629 329 ;
+C 225 ; WX 600 ; N AE ; B -20 0 614 583 ;
+C 227 ; WX 600 ; N ordfeminine ; B 118 182 489 595 ;
+C 232 ; WX 600 ; N Lslash ; B 12 0 571 583 ;
+C 233 ; WX 600 ; N Oslash ; B 9 -70 590 638 ;
+C 234 ; WX 600 ; N OE ; B -20 0 612 583 ;
+C 235 ; WX 600 ; N ordmasculine ; B 122 182 480 595 ;
+C 241 ; WX 600 ; N ae ; B -13 -16 612 450 ;
+C 245 ; WX 600 ; N dotlessi ; B 62 0 538 437 ;
+C 248 ; WX 600 ; N lslash ; B 62 0 538 624 ;
+C 249 ; WX 600 ; N oslash ; B 23 -70 573 494 ;
+C 250 ; WX 600 ; N oe ; B -11 -16 613 450 ;
+C 251 ; WX 600 ; N germandbls ; B 13 -16 529 623 ;
+C -1 ; WX 600 ; N Yacute ; B 21 0 579 839 ;
+C -1 ; WX 600 ; N Ucircumflex ; B 10 -14 590 839 ;
+C -1 ; WX 600 ; N Ugrave ; B 10 -14 590 839 ;
+C -1 ; WX 600 ; N Zcaron ; B 73 0 527 839 ;
+C -1 ; WX 600 ; N Ydieresis ; B 21 0 579 798 ;
+C -1 ; WX 600 ; N threesuperior ; B 157 238 442 637 ;
+C -1 ; WX 600 ; N Uacute ; B 10 -14 590 839 ;
+C -1 ; WX 600 ; N twosuperior ; B 149 247 429 637 ;
+C -1 ; WX 600 ; N Udieresis ; B 10 -14 590 798 ;
+C -1 ; WX 600 ; N middot ; B 225 214 375 346 ;
+C -1 ; WX 600 ; N onesuperior ; B 166 247 434 638 ;
+C -1 ; WX 600 ; N aacute ; B 42 -16 571 696 ;
+C -1 ; WX 600 ; N agrave ; B 42 -16 571 696 ;
+C -1 ; WX 600 ; N acircumflex ; B 42 -16 571 696 ;
+C -1 ; WX 600 ; N Scaron ; B 62 -14 538 839 ;
+C -1 ; WX 600 ; N Otilde ; B 21 -14 579 799 ;
+C -1 ; WX 600 ; N sfthyphen ; B 42 229 558 329 ;
+C -1 ; WX 600 ; N atilde ; B 42 -16 571 656 ;
+C -1 ; WX 600 ; N aring ; B 42 -16 571 727 ;
+C -1 ; WX 600 ; N adieresis ; B 42 -16 571 654 ;
+C -1 ; WX 600 ; N Ograve ; B 21 -14 579 839 ;
+C -1 ; WX 600 ; N Ocircumflex ; B 21 -14 579 839 ;
+C -1 ; WX 600 ; N Odieresis ; B 21 -14 579 798 ;
+C -1 ; WX 600 ; N Ntilde ; B -8 0 592 799 ;
+C -1 ; WX 600 ; N edieresis ; B 33 -16 550 654 ;
+C -1 ; WX 600 ; N eacute ; B 33 -16 550 696 ;
+C -1 ; WX 600 ; N egrave ; B 33 -16 550 696 ;
+C -1 ; WX 600 ; N Icircumflex ; B 83 0 517 839 ;
+C -1 ; WX 600 ; N ecircumflex ; B 33 -16 550 696 ;
+C -1 ; WX 600 ; N Igrave ; B 83 0 517 839 ;
+C -1 ; WX 600 ; N Iacute ; B 83 0 517 839 ;
+C -1 ; WX 600 ; N Idieresis ; B 83 0 517 798 ;
+C -1 ; WX 600 ; N degree ; B 125 243 475 596 ;
+C -1 ; WX 600 ; N Ecircumflex ; B 13 0 550 839 ;
+C -1 ; WX 600 ; N minus ; B 42 230 558 330 ;
+C -1 ; WX 600 ; N multiply ; B 100 80 500 480 ;
+C -1 ; WX 600 ; N divide ; B 42 28 558 533 ;
+C -1 ; WX 600 ; N Egrave ; B 13 0 550 839 ;
+C -1 ; WX 600 ; N trademark ; B -33 220 620 583 ;
+C -1 ; WX 600 ; N Oacute ; B 21 -14 579 839 ;
+C -1 ; WX 600 ; N thorn ; B -8 -205 571 624 ;
+C -1 ; WX 600 ; N eth ; B 42 -16 558 646 ;
+C -1 ; WX 600 ; N Eacute ; B 13 0 550 839 ;
+C -1 ; WX 600 ; N ccedilla ; B 54 -229 565 450 ;
+C -1 ; WX 600 ; N idieresis ; B 62 0 538 654 ;
+C -1 ; WX 600 ; N iacute ; B 62 0 538 696 ;
+C -1 ; WX 600 ; N igrave ; B 62 0 538 696 ;
+C -1 ; WX 600 ; N plusminus ; B 42 0 558 624 ;
+C -1 ; WX 600 ; N onehalf ; B -34 0 629 638 ;
+C -1 ; WX 600 ; N onequarter ; B -34 0 629 638 ;
+C -1 ; WX 600 ; N threequarters ; B -43 0 630 637 ;
+C -1 ; WX 600 ; N icircumflex ; B 62 0 538 696 ;
+C -1 ; WX 600 ; N Edieresis ; B 13 0 550 798 ;
+C -1 ; WX 600 ; N ntilde ; B 23 0 571 656 ;
+C -1 ; WX 600 ; N Aring ; B -21 0 621 871 ;
+C -1 ; WX 600 ; N odieresis ; B 42 -16 558 654 ;
+C -1 ; WX 600 ; N oacute ; B 42 -16 558 696 ;
+C -1 ; WX 600 ; N ograve ; B 42 -16 558 696 ;
+C -1 ; WX 600 ; N ocircumflex ; B 42 -16 558 696 ;
+C -1 ; WX 600 ; N otilde ; B 42 -16 558 656 ;
+C -1 ; WX 600 ; N scaron ; B 73 -16 527 696 ;
+C -1 ; WX 600 ; N udieresis ; B 13 -13 571 654 ;
+C -1 ; WX 600 ; N uacute ; B 13 -13 571 696 ;
+C -1 ; WX 600 ; N ugrave ; B 13 -13 571 696 ;
+C -1 ; WX 600 ; N ucircumflex ; B 13 -13 571 696 ;
+C -1 ; WX 600 ; N yacute ; B 21 -205 579 696 ;
+C -1 ; WX 600 ; N zcaron ; B 85 0 519 696 ;
+C -1 ; WX 600 ; N ydieresis ; B 21 -205 579 654 ;
+C -1 ; WX 600 ; N copyright ; B -7 -15 606 598 ;
+C -1 ; WX 600 ; N registered ; B -7 -15 606 598 ;
+C -1 ; WX 600 ; N Atilde ; B -21 0 621 799 ;
+C -1 ; WX 600 ; N nbspace ; B 375 0 375 0 ;
+C -1 ; WX 600 ; N Ccedilla ; B 33 -229 564 597 ;
+C -1 ; WX 600 ; N Acircumflex ; B -21 0 621 839 ;
+C -1 ; WX 600 ; N Agrave ; B -21 0 621 839 ;
+C -1 ; WX 600 ; N logicalnot ; B 42 115 465 445 ;
+C -1 ; WX 600 ; N Aacute ; B -21 0 621 839 ;
+C -1 ; WX 600 ; N Eth ; B 0 0 550 583 ;
+C -1 ; WX 600 ; N brokenbar ; B 250 -153 354 622 ;
+C -1 ; WX 600 ; N Thorn ; B 14 0 523 583 ;
+C -1 ; WX 600 ; N Adieresis ; B -21 0 621 798 ;
+C -1 ; WX 600 ; N mu ; B 13 -153 571 437 ;
+C -1 ; WX 600 ; N .notdef ; B 375 0 375 0 ;
+EndCharMetrics
+EndFontMetrics
diff --git a/misc/gs_afm/CourBoO.afm b/misc/gs_afm/CourBoO.afm
new file mode 100644
index 0000000000..6b37f99b2a
--- /dev/null
+++ b/misc/gs_afm/CourBoO.afm
@@ -0,0 +1,255 @@
+StartFontMetrics 3.0
+Comment Copyright URW Software, Copyright 1994 by URW
+Comment Creation Date: 8/3/1994
+Comment See the file PUBLIC (Aladdin Free Public License) for license conditions.
+FontName NimbusMonL-BoldObli
+FullName Nimbus Mono L Bold Oblique
+FamilyName Nimbus Mono L
+Weight Bold
+ItalicAngle -12.0
+IsFixedPitch false
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.005
+Notice URW Software, Copyright 1994 by URW
+EncodingScheme AdobeStandardEncoding
+FontBBox -61 -229 735 871
+CapHeight 583
+XHeight 437
+Descender -205
+Ascender 624
+StartCharMetrics 232
+C 32 ; WX 600 ; N space ; B 386 0 386 0 ;
+C 33 ; WX 600 ; N exclam ; B 234 -15 501 638 ;
+C 34 ; WX 600 ; N quotedbl ; B 243 312 592 602 ;
+C 35 ; WX 600 ; N numbersign ; B 101 -92 623 675 ;
+C 36 ; WX 600 ; N dollar ; B 100 -123 610 684 ;
+C 37 ; WX 600 ; N percent ; B 131 -15 599 617 ;
+C 38 ; WX 600 ; N ampersand ; B 102 -14 557 550 ;
+C 39 ; WX 600 ; N quoteright ; B 222 331 483 623 ;
+C 40 ; WX 600 ; N parenleft ; B 304 -153 613 632 ;
+C 41 ; WX 600 ; N parenright ; B 94 -153 403 632 ;
+C 42 ; WX 600 ; N asterisk ; B 178 208 614 622 ;
+C 43 ; WX 600 ; N plus ; B 101 0 619 560 ;
+C 44 ; WX 600 ; N comma ; B 118 -158 379 134 ;
+C 45 ; WX 600 ; N hyphen ; B 101 229 619 329 ;
+C 46 ; WX 600 ; N period ; B 234 -15 387 117 ;
+C 47 ; WX 600 ; N slash ; B 69 -113 656 695 ;
+C 48 ; WX 600 ; N zero ; B 130 -15 602 638 ;
+C 49 ; WX 600 ; N one ; B 93 0 529 638 ;
+C 50 ; WX 600 ; N two ; B 54 0 602 638 ;
+C 51 ; WX 600 ; N three ; B 80 -15 609 638 ;
+C 52 ; WX 600 ; N four ; B 104 0 579 622 ;
+C 53 ; WX 600 ; N five ; B 83 -15 610 622 ;
+C 54 ; WX 600 ; N six ; B 154 -15 663 638 ;
+C 55 ; WX 600 ; N seven ; B 184 -1 640 622 ;
+C 56 ; WX 600 ; N eight ; B 114 -15 608 638 ;
+C 57 ; WX 600 ; N nine ; B 115 -15 624 638 ;
+C 58 ; WX 600 ; N colon ; B 234 -15 455 437 ;
+C 59 ; WX 600 ; N semicolon ; B 118 -158 431 437 ;
+C 60 ; WX 600 ; N less ; B 102 54 642 501 ;
+C 61 ; WX 600 ; N equal ; B 81 138 638 422 ;
+C 62 ; WX 600 ; N greater ; B 76 53 616 500 ;
+C 63 ; WX 600 ; N question ; B 197 -15 608 598 ;
+C 64 ; WX 600 ; N at ; B 98 -151 582 620 ;
+C 65 ; WX 600 ; N A ; B -11 0 633 583 ;
+C 66 ; WX 600 ; N B ; B 22 0 620 583 ;
+C 67 ; WX 600 ; N C ; B 80 -14 663 597 ;
+C 68 ; WX 600 ; N D ; B 23 0 622 583 ;
+C 69 ; WX 600 ; N E ; B 23 0 652 583 ;
+C 70 ; WX 600 ; N F ; B 23 0 674 583 ;
+C 71 ; WX 600 ; N G ; B 79 -14 667 597 ;
+C 72 ; WX 600 ; N H ; B 32 0 675 583 ;
+C 73 ; WX 600 ; N I ; B 93 0 632 583 ;
+C 74 ; WX 600 ; N J ; B 64 -14 727 583 ;
+C 75 ; WX 600 ; N K ; B 22 0 687 583 ;
+C 76 ; WX 600 ; N L ; B 42 0 616 583 ;
+C 77 ; WX 600 ; N M ; B -10 0 728 583 ;
+C 78 ; WX 600 ; N N ; B 21 0 706 583 ;
+C 79 ; WX 600 ; N O ; B 75 -14 649 597 ;
+C 80 ; WX 600 ; N P ; B 23 0 617 583 ;
+C 81 ; WX 600 ; N Q ; B 75 -145 649 597 ;
+C 82 ; WX 600 ; N R ; B 23 0 631 583 ;
+C 83 ; WX 600 ; N S ; B 72 -14 634 597 ;
+C 84 ; WX 600 ; N T ; B 121 0 682 583 ;
+C 85 ; WX 600 ; N U ; B 110 -14 705 583 ;
+C 86 ; WX 600 ; N V ; B 91 0 735 583 ;
+C 87 ; WX 600 ; N W ; B 98 0 725 583 ;
+C 88 ; WX 600 ; N X ; B 19 0 692 583 ;
+C 89 ; WX 600 ; N Y ; B 128 0 694 583 ;
+C 90 ; WX 600 ; N Z ; B 73 0 628 583 ;
+C 91 ; WX 600 ; N bracketleft ; B 219 -148 598 627 ;
+C 92 ; WX 600 ; N backslash ; B 219 -113 504 695 ;
+C 93 ; WX 600 ; N bracketright ; B 104 -148 483 627 ;
+C 94 ; WX 600 ; N asciicircum ; B 161 325 598 652 ;
+C 95 ; WX 600 ; N underscore ; B -61 -125 564 -75 ;
+C 96 ; WX 600 ; N quoteleft ; B 377 348 534 602 ;
+C 97 ; WX 600 ; N a ; B 65 -16 583 450 ;
+C 98 ; WX 600 ; N b ; B 2 -14 623 624 ;
+C 99 ; WX 600 ; N c ; B 93 -16 626 450 ;
+C 100 ; WX 600 ; N d ; B 74 -14 664 624 ;
+C 101 ; WX 600 ; N e ; B 74 -16 600 450 ;
+C 102 ; WX 600 ; N f ; B 84 0 691 623 ;
+C 103 ; WX 600 ; N g ; B 73 -205 675 451 ;
+C 104 ; WX 600 ; N h ; B 33 0 593 624 ;
+C 105 ; WX 600 ; N i ; B 72 0 550 623 ;
+C 106 ; WX 600 ; N j ; B 83 -205 581 623 ;
+C 107 ; WX 600 ; N k ; B 42 0 606 624 ;
+C 108 ; WX 600 ; N l ; B 72 0 550 624 ;
+C 109 ; WX 600 ; N m ; B -9 0 635 450 ;
+C 110 ; WX 600 ; N n ; B 33 0 583 450 ;
+C 111 ; WX 600 ; N o ; B 84 -16 609 450 ;
+C 112 ; WX 600 ; N p ; B -42 -205 623 450 ;
+C 113 ; WX 600 ; N q ; B 75 -205 696 450 ;
+C 114 ; WX 600 ; N r ; B 64 0 650 449 ;
+C 115 ; WX 600 ; N s ; B 83 -16 592 450 ;
+C 116 ; WX 600 ; N t ; B 94 -16 547 591 ;
+C 117 ; WX 600 ; N u ; B 94 -13 603 437 ;
+C 118 ; WX 600 ; N v ; B 81 0 683 437 ;
+C 119 ; WX 600 ; N w ; B 82 0 684 437 ;
+C 120 ; WX 600 ; N x ; B 30 0 641 437 ;
+C 121 ; WX 600 ; N y ; B -13 -205 662 437 ;
+C 122 ; WX 600 ; N z ; B 85 0 599 437 ;
+C 123 ; WX 600 ; N braceleft ; B 217 -153 556 623 ;
+C 124 ; WX 600 ; N bar ; B 227 -153 472 622 ;
+C 125 ; WX 600 ; N braceright ; B 144 -153 483 623 ;
+C 126 ; WX 600 ; N asciitilde ; B 114 179 606 385 ;
+C 161 ; WX 600 ; N exclamdown ; B 186 -227 453 426 ;
+C 162 ; WX 600 ; N cent ; B 144 -44 593 661 ;
+C 163 ; WX 600 ; N sterling ; B 64 0 571 598 ;
+C 164 ; WX 600 ; N fraction ; B 52 102 676 500 ;
+C 165 ; WX 600 ; N yen ; B 133 0 693 580 ;
+C 166 ; WX 600 ; N florin ; B 43 -123 672 638 ;
+C 167 ; WX 600 ; N section ; B 45 -170 643 583 ;
+C 168 ; WX 600 ; N currency ; B 96 64 626 519 ;
+C 169 ; WX 600 ; N quotesingle ; B 343 312 492 602 ;
+C 170 ; WX 600 ; N quotedblleft ; B 226 348 583 602 ;
+C 171 ; WX 600 ; N guillemotleft ; B 80 20 654 415 ;
+C 172 ; WX 600 ; N guilsinglleft ; B 80 20 425 415 ;
+C 173 ; WX 600 ; N guilsinglright ; B 273 20 617 415 ;
+C 174 ; WX 600 ; N fi ; B -4 0 633 624 ;
+C 175 ; WX 600 ; N fl ; B -8 0 645 623 ;
+C 177 ; WX 600 ; N endash ; B 101 229 619 329 ;
+C 178 ; WX 600 ; N dagger ; B 175 -92 589 622 ;
+C 179 ; WX 600 ; N daggerdbl ; B 123 -92 589 622 ;
+C 180 ; WX 600 ; N periodcentered ; B 283 214 436 346 ;
+C 182 ; WX 600 ; N paragraph ; B 108 -174 672 583 ;
+C 183 ; WX 600 ; N bullet ; B 211 154 517 453 ;
+C 184 ; WX 600 ; N quotesinglbase ; B 118 -158 379 134 ;
+C 185 ; WX 600 ; N quotedblbase ; B 66 -120 519 134 ;
+C 186 ; WX 600 ; N quotedblright ; B 166 348 619 602 ;
+C 187 ; WX 600 ; N guillemotright ; B 43 20 617 415 ;
+C 188 ; WX 600 ; N ellipsis ; B 34 -15 587 117 ;
+C 189 ; WX 600 ; N perthousand ; B 104 0 627 618 ;
+C 191 ; WX 600 ; N questiondown ; B 70 -227 481 386 ;
+C 193 ; WX 600 ; N grave ; B 264 496 464 696 ;
+C 194 ; WX 600 ; N acute ; B 362 496 616 696 ;
+C 195 ; WX 600 ; N circumflex ; B 237 497 590 696 ;
+C 196 ; WX 600 ; N tilde ; B 233 523 619 656 ;
+C 197 ; WX 600 ; N macron ; B 249 546 600 626 ;
+C 198 ; WX 600 ; N breve ; B 261 503 614 687 ;
+C 199 ; WX 600 ; N dotaccent ; B 365 534 487 656 ;
+C 200 ; WX 600 ; N dieresis ; B 261 534 590 655 ;
+C 202 ; WX 600 ; N ring ; B 303 486 554 727 ;
+C 203 ; WX 600 ; N cedilla ; B 143 -229 381 0 ;
+C 205 ; WX 600 ; N hungarumlaut ; B 237 496 616 694 ;
+C 206 ; WX 600 ; N ogonek ; B 222 -208 433 0 ;
+C 207 ; WX 600 ; N caron ; B 264 497 617 696 ;
+C 208 ; WX 600 ; N emdash ; B 30 229 690 329 ;
+C 225 ; WX 600 ; N AE ; B -10 0 717 583 ;
+C 227 ; WX 600 ; N ordfeminine ; B 170 182 559 595 ;
+C 232 ; WX 600 ; N Lslash ; B 43 0 616 583 ;
+C 233 ; WX 600 ; N Oslash ; B 4 -70 717 638 ;
+C 234 ; WX 600 ; N OE ; B 34 0 717 583 ;
+C 235 ; WX 600 ; N ordmasculine ; B 168 182 566 595 ;
+C 241 ; WX 600 ; N ae ; B 14 -16 665 450 ;
+C 245 ; WX 600 ; N dotlessi ; B 72 0 550 437 ;
+C 248 ; WX 600 ; N lslash ; B 72 0 557 624 ;
+C 249 ; WX 600 ; N oslash ; B 17 -70 669 494 ;
+C 250 ; WX 600 ; N oe ; B 28 -16 666 450 ;
+C 251 ; WX 600 ; N germandbls ; B 22 -16 569 623 ;
+C -1 ; WX 600 ; N Yacute ; B 128 0 694 839 ;
+C -1 ; WX 600 ; N Ucircumflex ; B 110 -14 705 839 ;
+C -1 ; WX 600 ; N Ugrave ; B 110 -14 705 839 ;
+C -1 ; WX 600 ; N Zcaron ; B 73 0 644 839 ;
+C -1 ; WX 600 ; N Ydieresis ; B 128 0 694 800 ;
+C -1 ; WX 600 ; N threesuperior ; B 218 238 543 637 ;
+C -1 ; WX 600 ; N Uacute ; B 110 -14 705 839 ;
+C -1 ; WX 600 ; N twosuperior ; B 202 247 538 637 ;
+C -1 ; WX 600 ; N Udieresis ; B 110 -14 705 800 ;
+C -1 ; WX 600 ; N middot ; B 283 214 436 346 ;
+C -1 ; WX 600 ; N onesuperior ; B 224 247 494 638 ;
+C -1 ; WX 600 ; N aacute ; B 66 -16 584 696 ;
+C -1 ; WX 600 ; N agrave ; B 65 -16 583 696 ;
+C -1 ; WX 600 ; N acircumflex ; B 65 -16 583 696 ;
+C -1 ; WX 600 ; N Scaron ; B 72 -14 657 839 ;
+C -1 ; WX 600 ; N Otilde ; B 75 -14 656 799 ;
+C -1 ; WX 600 ; N sfthyphen ; B 101 229 619 329 ;
+C -1 ; WX 600 ; N atilde ; B 65 -16 612 656 ;
+C -1 ; WX 600 ; N aring ; B 65 -16 583 727 ;
+C -1 ; WX 600 ; N adieresis ; B 65 -16 583 655 ;
+C -1 ; WX 600 ; N Ograve ; B 75 -14 649 839 ;
+C -1 ; WX 600 ; N Ocircumflex ; B 75 -14 649 839 ;
+C -1 ; WX 600 ; N Odieresis ; B 75 -14 649 800 ;
+C -1 ; WX 600 ; N Ntilde ; B 21 0 706 799 ;
+C -1 ; WX 600 ; N edieresis ; B 74 -16 600 655 ;
+C -1 ; WX 600 ; N eacute ; B 74 -16 600 696 ;
+C -1 ; WX 600 ; N egrave ; B 74 -16 600 696 ;
+C -1 ; WX 600 ; N Icircumflex ; B 93 0 632 839 ;
+C -1 ; WX 600 ; N ecircumflex ; B 74 -16 600 696 ;
+C -1 ; WX 600 ; N Igrave ; B 93 0 632 839 ;
+C -1 ; WX 600 ; N Iacute ; B 93 0 632 839 ;
+C -1 ; WX 600 ; N Idieresis ; B 93 0 632 800 ;
+C -1 ; WX 600 ; N degree ; B 210 243 568 596 ;
+C -1 ; WX 600 ; N Ecircumflex ; B 23 0 652 839 ;
+C -1 ; WX 600 ; N minus ; B 101 230 619 330 ;
+C -1 ; WX 600 ; N multiply ; B 126 80 592 480 ;
+C -1 ; WX 600 ; N divide ; B 101 28 619 533 ;
+C -1 ; WX 600 ; N Egrave ; B 23 0 652 839 ;
+C -1 ; WX 600 ; N trademark ; B 60 220 732 583 ;
+C -1 ; WX 600 ; N Oacute ; B 75 -14 649 839 ;
+C -1 ; WX 600 ; N thorn ; B -42 -205 623 624 ;
+C -1 ; WX 600 ; N eth ; B 83 -16 617 646 ;
+C -1 ; WX 600 ; N Eacute ; B 23 0 652 839 ;
+C -1 ; WX 600 ; N ccedilla ; B 92 -229 626 450 ;
+C -1 ; WX 600 ; N idieresis ; B 72 0 575 656 ;
+C -1 ; WX 600 ; N iacute ; B 71 0 574 696 ;
+C -1 ; WX 600 ; N igrave ; B 72 0 550 696 ;
+C -1 ; WX 600 ; N plusminus ; B 52 0 640 624 ;
+C -1 ; WX 600 ; N onehalf ; B 25 0 685 638 ;
+C -1 ; WX 600 ; N onequarter ; B 25 0 673 638 ;
+C -1 ; WX 600 ; N threequarters ; B 18 0 673 637 ;
+C -1 ; WX 600 ; N icircumflex ; B 72 0 573 696 ;
+C -1 ; WX 600 ; N Edieresis ; B 23 0 652 800 ;
+C -1 ; WX 600 ; N ntilde ; B 33 0 613 656 ;
+C -1 ; WX 600 ; N Aring ; B -11 0 633 871 ;
+C -1 ; WX 600 ; N odieresis ; B 84 -16 609 655 ;
+C -1 ; WX 600 ; N oacute ; B 84 -16 609 696 ;
+C -1 ; WX 600 ; N ograve ; B 84 -16 609 696 ;
+C -1 ; WX 600 ; N ocircumflex ; B 84 -16 609 696 ;
+C -1 ; WX 600 ; N otilde ; B 84 -16 626 656 ;
+C -1 ; WX 600 ; N scaron ; B 83 -16 627 696 ;
+C -1 ; WX 600 ; N udieresis ; B 94 -13 603 655 ;
+C -1 ; WX 600 ; N uacute ; B 94 -13 603 696 ;
+C -1 ; WX 600 ; N ugrave ; B 94 -13 603 696 ;
+C -1 ; WX 600 ; N ucircumflex ; B 94 -13 603 696 ;
+C -1 ; WX 600 ; N yacute ; B -13 -205 662 696 ;
+C -1 ; WX 600 ; N zcaron ; B 85 0 619 696 ;
+C -1 ; WX 600 ; N ydieresis ; B -13 -205 662 655 ;
+C -1 ; WX 600 ; N copyright ; B 48 -15 675 598 ;
+C -1 ; WX 600 ; N registered ; B 48 -15 675 598 ;
+C -1 ; WX 600 ; N Atilde ; B -11 0 633 799 ;
+C -1 ; WX 600 ; N nbspace ; B 386 0 386 0 ;
+C -1 ; WX 600 ; N Ccedilla ; B 80 -229 663 597 ;
+C -1 ; WX 600 ; N Acircumflex ; B -11 0 633 839 ;
+C -1 ; WX 600 ; N Agrave ; B -11 0 633 839 ;
+C -1 ; WX 600 ; N logicalnot ; B 125 115 560 445 ;
+C -1 ; WX 600 ; N Aacute ; B -11 0 633 839 ;
+C -1 ; WX 600 ; N Eth ; B 23 0 622 583 ;
+C -1 ; WX 600 ; N brokenbar ; B 227 -153 472 622 ;
+C -1 ; WX 600 ; N Thorn ; B 23 0 588 583 ;
+C -1 ; WX 600 ; N Adieresis ; B -11 0 633 800 ;
+C -1 ; WX 600 ; N mu ; B 72 -153 603 440 ;
+C -1 ; WX 600 ; N .notdef ; B 386 0 386 0 ;
+EndCharMetrics
+EndFontMetrics
diff --git a/misc/gs_afm/CourO.afm b/misc/gs_afm/CourO.afm
new file mode 100644
index 0000000000..51e4ee6b81
--- /dev/null
+++ b/misc/gs_afm/CourO.afm
@@ -0,0 +1,255 @@
+StartFontMetrics 3.0
+Comment Copyright URW Software, Copyright 1994 by URW
+Comment Creation Date: 8/19/1994
+Comment See the file PUBLIC (Aladdin Free Public License) for license conditions.
+FontName NimbusMonL-ReguObli
+FullName Nimbus Mono L Regular Oblique
+FamilyName Nimbus Mono L
+Weight Regular
+ItalicAngle -12.0
+IsFixedPitch false
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.005
+Notice URW Software, Copyright 1994 by URW
+EncodingScheme AdobeStandardEncoding
+FontBBox -61 -216 710 811
+CapHeight 563
+XHeight 417
+Descender -186
+Ascender 604
+StartCharMetrics 232
+C 32 ; WX 600 ; N space ; B 319 0 319 0 ;
+C 33 ; WX 600 ; N exclam ; B 246 -15 463 618 ;
+C 34 ; WX 600 ; N quotedbl ; B 254 315 582 604 ;
+C 35 ; WX 600 ; N numbersign ; B 137 -62 589 647 ;
+C 36 ; WX 600 ; N dollar ; B 131 -92 582 655 ;
+C 37 ; WX 600 ; N percent ; B 137 -12 591 611 ;
+C 38 ; WX 600 ; N ampersand ; B 132 -16 527 519 ;
+C 39 ; WX 600 ; N quoteright ; B 207 314 468 604 ;
+C 40 ; WX 600 ; N parenleft ; B 335 -124 583 604 ;
+C 41 ; WX 600 ; N parenright ; B 124 -124 372 604 ;
+C 42 ; WX 600 ; N asterisk ; B 211 250 586 604 ;
+C 43 ; WX 600 ; N plus ; B 131 32 588 530 ;
+C 44 ; WX 600 ; N comma ; B 110 -145 371 145 ;
+C 45 ; WX 600 ; N hyphen ; B 131 258 588 299 ;
+C 46 ; WX 600 ; N period ; B 235 -15 386 116 ;
+C 47 ; WX 600 ; N slash ; B 99 -81 625 668 ;
+C 48 ; WX 600 ; N zero ; B 156 -15 571 618 ;
+C 49 ; WX 600 ; N one ; B 117 0 492 612 ;
+C 50 ; WX 600 ; N two ; B 84 0 572 618 ;
+C 51 ; WX 600 ; N three ; B 110 -15 579 618 ;
+C 52 ; WX 600 ; N four ; B 141 0 545 604 ;
+C 53 ; WX 600 ; N five ; B 113 -15 584 604 ;
+C 54 ; WX 600 ; N six ; B 184 -15 631 618 ;
+C 55 ; WX 600 ; N seven ; B 215 -1 606 604 ;
+C 56 ; WX 600 ; N eight ; B 143 -15 576 618 ;
+C 57 ; WX 600 ; N nine ; B 142 -15 589 618 ;
+C 58 ; WX 600 ; N colon ; B 235 -15 450 417 ;
+C 59 ; WX 600 ; N semicolon ; B 114 -145 426 417 ;
+C 60 ; WX 600 ; N less ; B 131 44 627 518 ;
+C 61 ; WX 600 ; N equal ; B 95 190 625 375 ;
+C 62 ; WX 600 ; N greater ; B 92 44 588 518 ;
+C 63 ; WX 600 ; N question ; B 231 -15 581 577 ;
+C 64 ; WX 600 ; N at ; B 139 -62 561 624 ;
+C 65 ; WX 600 ; N A ; B 13 0 596 563 ;
+C 66 ; WX 600 ; N B ; B 47 0 591 563 ;
+C 67 ; WX 600 ; N C ; B 110 -16 635 576 ;
+C 68 ; WX 600 ; N D ; B 47 0 592 563 ;
+C 69 ; WX 600 ; N E ; B 47 0 619 563 ;
+C 70 ; WX 600 ; N F ; B 47 0 640 563 ;
+C 71 ; WX 600 ; N G ; B 108 -16 636 576 ;
+C 72 ; WX 600 ; N H ; B 57 0 646 563 ;
+C 73 ; WX 600 ; N I ; B 117 0 603 563 ;
+C 74 ; WX 600 ; N J ; B 100 -16 699 563 ;
+C 75 ; WX 600 ; N K ; B 47 0 662 563 ;
+C 76 ; WX 600 ; N L ; B 67 0 585 563 ;
+C 77 ; WX 600 ; N M ; B 15 0 700 563 ;
+C 78 ; WX 600 ; N N ; B 46 0 678 563 ;
+C 79 ; WX 600 ; N O ; B 102 -16 616 576 ;
+C 80 ; WX 600 ; N P ; B 47 0 587 563 ;
+C 81 ; WX 600 ; N Q ; B 102 -115 616 576 ;
+C 82 ; WX 600 ; N R ; B 47 0 594 563 ;
+C 83 ; WX 600 ; N S ; B 96 -16 602 576 ;
+C 84 ; WX 600 ; N T ; B 152 0 648 563 ;
+C 85 ; WX 600 ; N U ; B 136 -16 676 563 ;
+C 86 ; WX 600 ; N V ; B 124 0 707 563 ;
+C 87 ; WX 600 ; N W ; B 122 0 696 563 ;
+C 88 ; WX 600 ; N X ; B 44 0 662 563 ;
+C 89 ; WX 600 ; N Y ; B 153 0 665 563 ;
+C 90 ; WX 600 ; N Z ; B 103 0 590 563 ;
+C 91 ; WX 600 ; N bracketleft ; B 254 -124 570 604 ;
+C 92 ; WX 600 ; N backslash ; B 250 -81 474 668 ;
+C 93 ; WX 600 ; N bracketright ; B 132 -124 448 604 ;
+C 94 ; WX 600 ; N asciicircum ; B 192 354 567 615 ;
+C 95 ; WX 600 ; N underscore ; B -61 -125 564 -75 ;
+C 96 ; WX 600 ; N quoteleft ; B 388 343 544 604 ;
+C 97 ; WX 600 ; N a ; B 93 -16 546 431 ;
+C 98 ; WX 600 ; N b ; B 26 -16 591 604 ;
+C 99 ; WX 600 ; N c ; B 122 -16 596 431 ;
+C 100 ; WX 600 ; N d ; B 102 -16 630 604 ;
+C 101 ; WX 600 ; N e ; B 104 -16 570 431 ;
+C 102 ; WX 600 ; N f ; B 109 0 663 604 ;
+C 103 ; WX 600 ; N g ; B 105 -186 647 431 ;
+C 104 ; WX 600 ; N h ; B 55 0 556 604 ;
+C 105 ; WX 600 ; N i ; B 96 0 513 624 ;
+C 106 ; WX 600 ; N j ; B 112 -186 547 624 ;
+C 107 ; WX 600 ; N k ; B 67 0 578 604 ;
+C 108 ; WX 600 ; N l ; B 96 0 513 604 ;
+C 109 ; WX 600 ; N m ; B 15 0 603 431 ;
+C 110 ; WX 600 ; N n ; B 57 0 546 431 ;
+C 111 ; WX 600 ; N o ; B 111 -16 577 431 ;
+C 112 ; WX 600 ; N p ; B -13 -186 593 431 ;
+C 113 ; WX 600 ; N q ; B 105 -186 668 431 ;
+C 114 ; WX 600 ; N r ; B 88 0 619 427 ;
+C 115 ; WX 600 ; N s ; B 108 -16 558 431 ;
+C 116 ; WX 600 ; N t ; B 127 -16 518 563 ;
+C 117 ; WX 600 ; N u ; B 127 -16 569 417 ;
+C 118 ; WX 600 ; N v ; B 114 0 655 417 ;
+C 119 ; WX 600 ; N w ; B 114 0 655 417 ;
+C 120 ; WX 600 ; N x ; B 55 0 611 417 ;
+C 121 ; WX 600 ; N y ; B 22 -186 634 417 ;
+C 122 ; WX 600 ; N z ; B 115 0 563 417 ;
+C 123 ; WX 600 ; N braceleft ; B 248 -124 528 604 ;
+C 124 ; WX 600 ; N bar ; B 257 -124 444 604 ;
+C 125 ; WX 600 ; N braceright ; B 175 -124 455 604 ;
+C 126 ; WX 600 ; N asciitilde ; B 145 212 575 348 ;
+C 161 ; WX 600 ; N exclamdown ; B 222 -216 439 417 ;
+C 162 ; WX 600 ; N cent ; B 175 -13 563 630 ;
+C 163 ; WX 600 ; N sterling ; B 90 0 541 578 ;
+C 164 ; WX 600 ; N fraction ; B 84 139 645 470 ;
+C 165 ; WX 600 ; N yen ; B 161 0 665 563 ;
+C 166 ; WX 600 ; N florin ; B 74 -93 643 618 ;
+C 167 ; WX 600 ; N section ; B 91 -62 624 603 ;
+C 168 ; WX 600 ; N currency ; B 127 95 597 489 ;
+C 169 ; WX 600 ; N quotesingle ; B 344 315 492 604 ;
+C 170 ; WX 600 ; N quotedblleft ; B 221 343 586 604 ;
+C 171 ; WX 600 ; N guillemotleft ; B 108 0 626 417 ;
+C 172 ; WX 600 ; N guilsinglleft ; B 108 0 397 417 ;
+C 173 ; WX 600 ; N guilsinglright ; B 297 0 585 417 ;
+C 174 ; WX 600 ; N fi ; B 14 0 615 624 ;
+C 175 ; WX 600 ; N fl ; B 14 0 611 604 ;
+C 177 ; WX 600 ; N endash ; B 131 261 588 302 ;
+C 178 ; WX 600 ; N dagger ; B 208 -63 561 604 ;
+C 179 ; WX 600 ; N daggerdbl ; B 154 -62 561 604 ;
+C 180 ; WX 600 ; N periodcentered ; B 285 217 436 348 ;
+C 182 ; WX 600 ; N paragraph ; B 152 -62 648 604 ;
+C 183 ; WX 600 ; N bullet ; B 253 141 449 337 ;
+C 184 ; WX 600 ; N quotesinglbase ; B 110 -145 371 145 ;
+C 185 ; WX 600 ; N quotedblbase ; B 73 -116 538 145 ;
+C 186 ; WX 600 ; N quotedblright ; B 170 343 635 604 ;
+C 187 ; WX 600 ; N guillemotright ; B 67 0 585 417 ;
+C 188 ; WX 600 ; N ellipsis ; B 57 -15 556 85 ;
+C 189 ; WX 600 ; N perthousand ; B 91 -9 598 614 ;
+C 191 ; WX 600 ; N questiondown ; B 105 -175 455 417 ;
+C 193 ; WX 600 ; N grave ; B 286 490 429 639 ;
+C 194 ; WX 600 ; N acute ; B 388 490 577 639 ;
+C 195 ; WX 600 ; N circumflex ; B 263 490 554 639 ;
+C 196 ; WX 600 ; N tilde ; B 258 516 579 605 ;
+C 197 ; WX 600 ; N macron ; B 273 536 564 576 ;
+C 198 ; WX 600 ; N breve ; B 281 490 573 620 ;
+C 199 ; WX 600 ; N dotaccent ; B 368 511 469 612 ;
+C 200 ; WX 600 ; N dieresis ; B 258 511 580 612 ;
+C 202 ; WX 600 ; N ring ; B 326 480 516 661 ;
+C 203 ; WX 600 ; N cedilla ; B 181 -173 356 0 ;
+C 205 ; WX 600 ; N hungarumlaut ; B 263 490 576 633 ;
+C 206 ; WX 600 ; N ogonek ; B 258 -155 408 0 ;
+C 207 ; WX 600 ; N caron ; B 286 490 577 639 ;
+C 208 ; WX 600 ; N emdash ; B 60 261 659 302 ;
+C 225 ; WX 600 ; N AE ; B 14 0 690 563 ;
+C 227 ; WX 600 ; N ordfeminine ; B 229 279 511 574 ;
+C 232 ; WX 600 ; N Lslash ; B 66 0 586 563 ;
+C 233 ; WX 600 ; N Oslash ; B 34 -43 685 605 ;
+C 234 ; WX 600 ; N OE ; B 62 0 690 563 ;
+C 235 ; WX 600 ; N ordmasculine ; B 243 284 543 577 ;
+C 241 ; WX 600 ; N ae ; B 36 -16 630 431 ;
+C 245 ; WX 600 ; N dotlessi ; B 96 0 513 417 ;
+C 248 ; WX 600 ; N lslash ; B 96 0 524 604 ;
+C 249 ; WX 600 ; N oslash ; B 47 -43 637 458 ;
+C 250 ; WX 600 ; N oe ; B 50 -16 630 431 ;
+C 251 ; WX 600 ; N germandbls ; B 47 -16 539 604 ;
+C -1 ; WX 600 ; N Yacute ; B 153 0 665 789 ;
+C -1 ; WX 600 ; N Ucircumflex ; B 136 -16 676 789 ;
+C -1 ; WX 600 ; N Ugrave ; B 136 -16 676 789 ;
+C -1 ; WX 600 ; N Zcaron ; B 103 0 605 789 ;
+C -1 ; WX 600 ; N Ydieresis ; B 153 0 665 762 ;
+C -1 ; WX 600 ; N threesuperior ; B 245 251 516 612 ;
+C -1 ; WX 600 ; N Uacute ; B 136 -16 676 789 ;
+C -1 ; WX 600 ; N twosuperior ; B 230 259 514 612 ;
+C -1 ; WX 600 ; N Udieresis ; B 136 -16 676 762 ;
+C -1 ; WX 600 ; N middot ; B 285 217 436 348 ;
+C -1 ; WX 600 ; N onesuperior ; B 249 259 469 612 ;
+C -1 ; WX 600 ; N aacute ; B 93 -16 546 639 ;
+C -1 ; WX 600 ; N agrave ; B 93 -16 546 639 ;
+C -1 ; WX 600 ; N acircumflex ; B 93 -16 546 639 ;
+C -1 ; WX 600 ; N Scaron ; B 96 -16 618 789 ;
+C -1 ; WX 600 ; N Otilde ; B 103 -16 618 755 ;
+C -1 ; WX 600 ; N sfthyphen ; B 131 258 588 299 ;
+C -1 ; WX 600 ; N atilde ; B 93 -16 570 605 ;
+C -1 ; WX 600 ; N aring ; B 93 -16 546 661 ;
+C -1 ; WX 600 ; N adieresis ; B 93 -16 570 612 ;
+C -1 ; WX 600 ; N Ograve ; B 102 -16 616 789 ;
+C -1 ; WX 600 ; N Ocircumflex ; B 102 -16 616 789 ;
+C -1 ; WX 600 ; N Odieresis ; B 102 -16 616 762 ;
+C -1 ; WX 600 ; N Ntilde ; B 46 0 678 755 ;
+C -1 ; WX 600 ; N edieresis ; B 104 -16 585 612 ;
+C -1 ; WX 600 ; N eacute ; B 104 -16 570 639 ;
+C -1 ; WX 600 ; N egrave ; B 104 -16 570 639 ;
+C -1 ; WX 600 ; N Icircumflex ; B 117 0 603 789 ;
+C -1 ; WX 600 ; N ecircumflex ; B 104 -16 570 639 ;
+C -1 ; WX 600 ; N Igrave ; B 117 0 603 789 ;
+C -1 ; WX 600 ; N Iacute ; B 117 0 603 789 ;
+C -1 ; WX 600 ; N Idieresis ; B 117 0 611 762 ;
+C -1 ; WX 600 ; N degree ; B 257 346 553 636 ;
+C -1 ; WX 600 ; N Ecircumflex ; B 47 0 619 789 ;
+C -1 ; WX 600 ; N minus ; B 131 261 588 302 ;
+C -1 ; WX 600 ; N multiply ; B 143 100 577 464 ;
+C -1 ; WX 600 ; N divide ; B 131 25 588 541 ;
+C -1 ; WX 600 ; N Egrave ; B 47 0 619 789 ;
+C -1 ; WX 600 ; N trademark ; B 90 243 710 563 ;
+C -1 ; WX 600 ; N Oacute ; B 102 -16 616 789 ;
+C -1 ; WX 600 ; N thorn ; B -13 -186 593 590 ;
+C -1 ; WX 600 ; N eth ; B 111 -17 582 620 ;
+C -1 ; WX 600 ; N Eacute ; B 47 0 619 789 ;
+C -1 ; WX 600 ; N ccedilla ; B 122 -173 596 431 ;
+C -1 ; WX 600 ; N idieresis ; B 96 0 567 612 ;
+C -1 ; WX 600 ; N iacute ; B 96 0 535 639 ;
+C -1 ; WX 600 ; N igrave ; B 96 0 513 639 ;
+C -1 ; WX 600 ; N plusminus ; B 76 0 597 529 ;
+C -1 ; WX 600 ; N onehalf ; B 82 0 627 612 ;
+C -1 ; WX 600 ; N onequarter ; B 74 0 619 612 ;
+C -1 ; WX 600 ; N threequarters ; B 70 0 619 612 ;
+C -1 ; WX 600 ; N icircumflex ; B 95 0 536 639 ;
+C -1 ; WX 600 ; N Edieresis ; B 47 0 619 762 ;
+C -1 ; WX 600 ; N ntilde ; B 57 0 570 605 ;
+C -1 ; WX 600 ; N Aring ; B 13 0 596 811 ;
+C -1 ; WX 600 ; N odieresis ; B 111 -16 580 612 ;
+C -1 ; WX 600 ; N oacute ; B 111 -16 577 639 ;
+C -1 ; WX 600 ; N ograve ; B 111 -16 577 639 ;
+C -1 ; WX 600 ; N ocircumflex ; B 111 -16 577 639 ;
+C -1 ; WX 600 ; N otilde ; B 111 -16 586 605 ;
+C -1 ; WX 600 ; N scaron ; B 107 -16 584 639 ;
+C -1 ; WX 600 ; N udieresis ; B 127 -16 572 612 ;
+C -1 ; WX 600 ; N uacute ; B 127 -16 569 639 ;
+C -1 ; WX 600 ; N ugrave ; B 127 -16 569 639 ;
+C -1 ; WX 600 ; N ucircumflex ; B 127 -16 569 639 ;
+C -1 ; WX 600 ; N yacute ; B 22 -186 634 639 ;
+C -1 ; WX 600 ; N zcaron ; B 115 0 576 639 ;
+C -1 ; WX 600 ; N ydieresis ; B 22 -186 634 612 ;
+C -1 ; WX 600 ; N copyright ; B 57 -15 663 578 ;
+C -1 ; WX 600 ; N registered ; B 57 -15 663 578 ;
+C -1 ; WX 600 ; N Atilde ; B 13 0 596 755 ;
+C -1 ; WX 600 ; N nbspace ; B 319 0 319 0 ;
+C -1 ; WX 600 ; N Ccedilla ; B 110 -173 635 576 ;
+C -1 ; WX 600 ; N Acircumflex ; B 13 0 596 789 ;
+C -1 ; WX 600 ; N Agrave ; B 13 0 596 789 ;
+C -1 ; WX 600 ; N logicalnot ; B 160 168 621 438 ;
+C -1 ; WX 600 ; N Aacute ; B 13 0 596 789 ;
+C -1 ; WX 600 ; N Eth ; B 47 0 592 563 ;
+C -1 ; WX 600 ; N brokenbar ; B 257 -124 444 604 ;
+C -1 ; WX 600 ; N Thorn ; B 47 0 566 563 ;
+C -1 ; WX 600 ; N Adieresis ; B 13 0 596 762 ;
+C -1 ; WX 600 ; N mu ; B 86 -200 569 417 ;
+C -1 ; WX 600 ; N .notdef ; B 319 0 319 0 ;
+EndCharMetrics
+EndFontMetrics
diff --git a/misc/gs_afm/Helv.afm b/misc/gs_afm/Helv.afm
new file mode 100644
index 0000000000..56de4d61bb
--- /dev/null
+++ b/misc/gs_afm/Helv.afm
@@ -0,0 +1,1257 @@
+StartFontMetrics 3.0
+Comment Copyright URW Software, Copyright 1994 by URW
+Comment Creation Date: 8/3/1994
+Comment See the file PUBLIC (Aladdin Free Public License) for license conditions.
+FontName NimbusSanL-ReguCond
+FullName Nimbus Sans L Regular Condensed
+FamilyName Nimbus Sans L
+Weight Regular
+ItalicAngle 0.0
+IsFixedPitch false
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.005
+Notice URW Software, Copyright 1994 by URW
+EncodingScheme AdobeStandardEncoding
+FontBBox -136 -225 820 944
+CapHeight 718
+XHeight 523
+Descender -207
+Ascender 718
+StartCharMetrics 232
+C 32 ; WX 228 ; N space ; B 21 0 21 0 ;
+C 33 ; WX 228 ; N exclam ; B 74 0 153 718 ;
+C 34 ; WX 291 ; N quotedbl ; B 57 463 234 718 ;
+C 35 ; WX 456 ; N numbersign ; B 23 0 434 688 ;
+C 36 ; WX 456 ; N dollar ; B 26 -115 426 775 ;
+C 37 ; WX 729 ; N percent ; B 32 -19 697 703 ;
+C 38 ; WX 547 ; N ampersand ; B 36 -15 529 718 ;
+C 39 ; WX 182 ; N quoteright ; B 43 462 129 718 ;
+C 40 ; WX 273 ; N parenleft ; B 56 -207 245 733 ;
+C 41 ; WX 273 ; N parenright ; B 28 -207 217 733 ;
+C 42 ; WX 319 ; N asterisk ; B 32 431 286 718 ;
+C 43 ; WX 479 ; N plus ; B 32 0 447 505 ;
+C 44 ; WX 228 ; N comma ; B 71 -147 157 107 ;
+C 45 ; WX 273 ; N hyphen ; B 36 232 237 322 ;
+C 46 ; WX 228 ; N period ; B 71 0 157 107 ;
+C 47 ; WX 228 ; N slash ; B -14 -19 242 737 ;
+C 48 ; WX 456 ; N zero ; B 30 -19 426 703 ;
+C 49 ; WX 456 ; N one ; B 83 0 294 703 ;
+C 50 ; WX 456 ; N two ; B 21 0 416 703 ;
+C 51 ; WX 456 ; N three ; B 28 -19 428 703 ;
+C 52 ; WX 456 ; N four ; B 20 0 429 703 ;
+C 53 ; WX 456 ; N five ; B 26 -19 421 688 ;
+C 54 ; WX 456 ; N six ; B 31 -19 425 703 ;
+C 55 ; WX 456 ; N seven ; B 30 0 429 688 ;
+C 56 ; WX 456 ; N eight ; B 31 -19 424 703 ;
+C 57 ; WX 456 ; N nine ; B 34 -19 421 703 ;
+C 58 ; WX 228 ; N colon ; B 71 0 157 516 ;
+C 59 ; WX 228 ; N semicolon ; B 71 -147 157 516 ;
+C 60 ; WX 479 ; N less ; B 39 10 440 496 ;
+C 61 ; WX 479 ; N equal ; B 32 115 447 390 ;
+C 62 ; WX 479 ; N greater ; B 39 10 440 496 ;
+C 63 ; WX 456 ; N question ; B 46 0 403 727 ;
+C 64 ; WX 832 ; N at ; B 121 -19 712 737 ;
+C 65 ; WX 547 ; N A ; B 11 0 536 718 ;
+C 66 ; WX 547 ; N B ; B 61 0 514 718 ;
+C 67 ; WX 592 ; N C ; B 36 -19 558 737 ;
+C 68 ; WX 592 ; N D ; B 66 0 553 718 ;
+C 69 ; WX 547 ; N E ; B 71 0 505 718 ;
+C 70 ; WX 501 ; N F ; B 71 0 478 718 ;
+C 71 ; WX 638 ; N G ; B 39 -19 577 737 ;
+C 72 ; WX 592 ; N H ; B 63 0 530 718 ;
+C 73 ; WX 228 ; N I ; B 75 0 154 718 ;
+C 74 ; WX 410 ; N J ; B 14 -19 351 718 ;
+C 75 ; WX 547 ; N K ; B 62 0 544 718 ;
+C 76 ; WX 456 ; N L ; B 62 0 440 718 ;
+C 77 ; WX 683 ; N M ; B 60 0 624 718 ;
+C 78 ; WX 592 ; N N ; B 62 0 530 718 ;
+C 79 ; WX 638 ; N O ; B 32 -19 606 737 ;
+C 80 ; WX 547 ; N P ; B 71 0 510 718 ;
+C 81 ; WX 638 ; N Q ; B 32 -56 606 737 ;
+C 82 ; WX 592 ; N R ; B 72 0 561 718 ;
+C 83 ; WX 547 ; N S ; B 40 -19 508 737 ;
+C 84 ; WX 501 ; N T ; B 11 0 490 718 ;
+C 85 ; WX 592 ; N U ; B 65 -19 528 718 ;
+C 86 ; WX 547 ; N V ; B 16 0 531 718 ;
+C 87 ; WX 774 ; N W ; B 13 0 761 718 ;
+C 88 ; WX 547 ; N X ; B 16 0 531 718 ;
+C 89 ; WX 547 ; N Y ; B 11 0 535 718 ;
+C 90 ; WX 501 ; N Z ; B 19 0 482 718 ;
+C 91 ; WX 228 ; N bracketleft ; B 52 -196 205 722 ;
+C 92 ; WX 228 ; N backslash ; B -14 -19 242 737 ;
+C 93 ; WX 228 ; N bracketright ; B 23 -196 176 722 ;
+C 94 ; WX 385 ; N asciicircum ; B -11 264 396 688 ;
+C 95 ; WX 456 ; N underscore ; B 0 -125 456 -75 ;
+C 96 ; WX 182 ; N quoteleft ; B 53 469 139 725 ;
+C 97 ; WX 456 ; N a ; B 30 -15 435 538 ;
+C 98 ; WX 456 ; N b ; B 48 -15 424 718 ;
+C 99 ; WX 410 ; N c ; B 25 -15 391 538 ;
+C 100 ; WX 456 ; N d ; B 29 -15 409 718 ;
+C 101 ; WX 456 ; N e ; B 33 -15 423 538 ;
+C 102 ; WX 228 ; N f ; B 11 0 215 728 ;
+C 103 ; WX 456 ; N g ; B 33 -220 409 538 ;
+C 104 ; WX 456 ; N h ; B 53 0 403 718 ;
+C 105 ; WX 182 ; N i ; B 55 0 127 718 ;
+C 106 ; WX 182 ; N j ; B -13 -210 127 718 ;
+C 107 ; WX 410 ; N k ; B 55 0 411 718 ;
+C 108 ; WX 182 ; N l ; B 55 0 127 718 ;
+C 109 ; WX 683 ; N m ; B 53 0 631 538 ;
+C 110 ; WX 456 ; N n ; B 53 0 403 538 ;
+C 111 ; WX 456 ; N o ; B 29 -14 427 538 ;
+C 112 ; WX 456 ; N p ; B 48 -207 424 538 ;
+C 113 ; WX 456 ; N q ; B 29 -207 405 538 ;
+C 114 ; WX 273 ; N r ; B 63 0 272 538 ;
+C 115 ; WX 410 ; N s ; B 26 -15 380 538 ;
+C 116 ; WX 228 ; N t ; B 11 -7 211 669 ;
+C 117 ; WX 456 ; N u ; B 56 -15 401 523 ;
+C 118 ; WX 410 ; N v ; B 7 0 403 523 ;
+C 119 ; WX 592 ; N w ; B 11 0 581 523 ;
+C 120 ; WX 410 ; N x ; B 9 0 402 523 ;
+C 121 ; WX 410 ; N y ; B 9 -214 401 523 ;
+C 122 ; WX 410 ; N z ; B 25 0 385 523 ;
+C 123 ; WX 274 ; N braceleft ; B 34 -196 239 722 ;
+C 124 ; WX 213 ; N bar ; B 77 -19 137 737 ;
+C 125 ; WX 274 ; N braceright ; B 34 -196 239 722 ;
+C 126 ; WX 479 ; N asciitilde ; B 50 181 429 322 ;
+C 161 ; WX 273 ; N exclamdown ; B 97 -195 176 523 ;
+C 162 ; WX 456 ; N cent ; B 42 -115 421 623 ;
+C 163 ; WX 456 ; N sterling ; B 27 -16 442 718 ;
+C 164 ; WX 137 ; N fraction ; B -136 -19 273 703 ;
+C 165 ; WX 456 ; N yen ; B 2 0 453 688 ;
+C 166 ; WX 456 ; N florin ; B -9 -207 411 737 ;
+C 167 ; WX 456 ; N section ; B 35 -191 420 737 ;
+C 168 ; WX 456 ; N currency ; B 23 99 433 603 ;
+C 169 ; WX 157 ; N quotesingle ; B 48 463 108 718 ;
+C 170 ; WX 273 ; N quotedblleft ; B 31 469 252 725 ;
+C 171 ; WX 456 ; N guillemotleft ; B 80 108 376 446 ;
+C 172 ; WX 273 ; N guilsinglleft ; B 72 108 201 446 ;
+C 173 ; WX 273 ; N guilsinglright ; B 72 108 201 446 ;
+C 174 ; WX 410 ; N fi ; B 11 0 356 728 ;
+C 175 ; WX 410 ; N fl ; B 11 0 354 728 ;
+C 177 ; WX 456 ; N endash ; B 0 240 456 313 ;
+C 178 ; WX 456 ; N dagger ; B 35 -159 421 718 ;
+C 179 ; WX 456 ; N daggerdbl ; B 35 -159 421 718 ;
+C 180 ; WX 228 ; N periodcentered ; B 63 190 166 315 ;
+C 182 ; WX 440 ; N paragraph ; B 15 -173 408 718 ;
+C 183 ; WX 287 ; N bullet ; B 15 202 273 517 ;
+C 184 ; WX 182 ; N quotesinglbase ; B 43 -149 129 107 ;
+C 185 ; WX 273 ; N quotedblbase ; B 21 -149 242 107 ;
+C 186 ; WX 273 ; N quotedblright ; B 21 462 242 718 ;
+C 187 ; WX 456 ; N guillemotright ; B 80 108 376 446 ;
+C 188 ; WX 820 ; N ellipsis ; B 94 0 726 107 ;
+C 189 ; WX 820 ; N perthousand ; B 6 -19 815 703 ;
+C 191 ; WX 501 ; N questiondown ; B 75 -201 432 525 ;
+C 193 ; WX 273 ; N grave ; B 11 593 173 734 ;
+C 194 ; WX 273 ; N acute ; B 100 593 262 734 ;
+C 195 ; WX 273 ; N circumflex ; B 17 593 256 734 ;
+C 196 ; WX 273 ; N tilde ; B -3 606 276 722 ;
+C 197 ; WX 273 ; N macron ; B 8 627 265 684 ;
+C 198 ; WX 273 ; N breve ; B 11 595 263 731 ;
+C 199 ; WX 273 ; N dotaccent ; B 99 604 174 706 ;
+C 200 ; WX 273 ; N dieresis ; B 33 604 240 706 ;
+C 202 ; WX 273 ; N ring ; B 61 572 212 756 ;
+C 203 ; WX 273 ; N cedilla ; B 37 -225 212 0 ;
+C 205 ; WX 273 ; N hungarumlaut ; B 25 593 335 734 ;
+C 206 ; WX 273 ; N ogonek ; B 60 -225 235 0 ;
+C 207 ; WX 273 ; N caron ; B 17 593 256 734 ;
+C 208 ; WX 820 ; N emdash ; B 0 240 820 313 ;
+C 225 ; WX 820 ; N AE ; B 7 0 780 718 ;
+C 227 ; WX 303 ; N ordfeminine ; B 20 304 284 737 ;
+C 232 ; WX 456 ; N Lslash ; B -16 0 440 718 ;
+C 233 ; WX 638 ; N Oslash ; B 32 -19 607 737 ;
+C 234 ; WX 820 ; N OE ; B 30 -19 791 737 ;
+C 235 ; WX 299 ; N ordmasculine ; B 20 304 280 737 ;
+C 241 ; WX 729 ; N ae ; B 30 -15 695 538 ;
+C 245 ; WX 228 ; N dotlessi ; B 78 0 150 523 ;
+C 248 ; WX 182 ; N lslash ; B -16 0 198 718 ;
+C 249 ; WX 501 ; N oslash ; B 23 -22 440 545 ;
+C 250 ; WX 774 ; N oe ; B 29 -15 740 538 ;
+C 251 ; WX 501 ; N germandbls ; B 55 -15 468 728 ;
+C -1 ; WX 547 ; N Yacute ; B 11 0 535 929 ;
+C -1 ; WX 592 ; N Ucircumflex ; B 65 -19 528 929 ;
+C -1 ; WX 592 ; N Ugrave ; B 65 -19 528 929 ;
+C -1 ; WX 501 ; N Zcaron ; B 19 0 482 929 ;
+C -1 ; WX 547 ; N Ydieresis ; B 11 0 535 901 ;
+C -1 ; WX 273 ; N threesuperior ; B 4 270 266 714 ;
+C -1 ; WX 592 ; N Uacute ; B 65 -19 528 929 ;
+C -1 ; WX 273 ; N twosuperior ; B 3 280 265 714 ;
+C -1 ; WX 592 ; N Udieresis ; B 65 -19 528 901 ;
+C -1 ; WX 228 ; N middot ; B 63 190 166 315 ;
+C -1 ; WX 273 ; N onesuperior ; B 35 281 182 703 ;
+C -1 ; WX 456 ; N aacute ; B 30 -15 435 734 ;
+C -1 ; WX 456 ; N agrave ; B 30 -15 435 734 ;
+C -1 ; WX 456 ; N acircumflex ; B 30 -15 435 734 ;
+C -1 ; WX 547 ; N Scaron ; B 40 -19 508 929 ;
+C -1 ; WX 638 ; N Otilde ; B 32 -19 606 917 ;
+C -1 ; WX 273 ; N sfthyphen ; B 36 232 237 322 ;
+C -1 ; WX 456 ; N atilde ; B 30 -15 435 722 ;
+C -1 ; WX 456 ; N aring ; B 30 -15 435 769 ;
+C -1 ; WX 456 ; N adieresis ; B 30 -15 435 706 ;
+C -1 ; WX 638 ; N Ograve ; B 32 -19 606 929 ;
+C -1 ; WX 638 ; N Ocircumflex ; B 32 -19 606 929 ;
+C -1 ; WX 638 ; N Odieresis ; B 32 -19 606 901 ;
+C -1 ; WX 592 ; N Ntilde ; B 62 0 530 917 ;
+C -1 ; WX 456 ; N edieresis ; B 33 -15 423 706 ;
+C -1 ; WX 456 ; N eacute ; B 33 -15 423 734 ;
+C -1 ; WX 456 ; N egrave ; B 33 -15 423 734 ;
+C -1 ; WX 228 ; N Icircumflex ; B -5 0 234 929 ;
+C -1 ; WX 456 ; N ecircumflex ; B 33 -15 423 734 ;
+C -1 ; WX 228 ; N Igrave ; B -11 0 153 929 ;
+C -1 ; WX 228 ; N Iacute ; B 75 0 240 903 ;
+C -1 ; WX 228 ; N Idieresis ; B 11 0 218 901 ;
+C -1 ; WX 328 ; N degree ; B 44 411 284 703 ;
+C -1 ; WX 547 ; N Ecircumflex ; B 71 0 505 929 ;
+C -1 ; WX 479 ; N minus ; B 32 216 447 289 ;
+C -1 ; WX 479 ; N multiply ; B 32 0 447 506 ;
+C -1 ; WX 479 ; N divide ; B 32 -19 447 524 ;
+C -1 ; WX 547 ; N Egrave ; B 71 0 505 929 ;
+C -1 ; WX 820 ; N trademark ; B 38 306 740 718 ;
+C -1 ; WX 638 ; N Oacute ; B 32 -19 606 929 ;
+C -1 ; WX 456 ; N thorn ; B 48 -207 424 718 ;
+C -1 ; WX 456 ; N eth ; B 29 -15 428 737 ;
+C -1 ; WX 547 ; N Eacute ; B 71 0 505 929 ;
+C -1 ; WX 410 ; N ccedilla ; B 25 -225 391 538 ;
+C -1 ; WX 228 ; N idieresis ; B 11 0 218 706 ;
+C -1 ; WX 228 ; N iacute ; B 78 0 240 734 ;
+C -1 ; WX 228 ; N igrave ; B -11 0 151 734 ;
+C -1 ; WX 479 ; N plusminus ; B 32 0 447 561 ;
+C -1 ; WX 684 ; N onehalf ; B 35 -19 634 703 ;
+C -1 ; WX 684 ; N onequarter ; B 60 -19 620 703 ;
+C -1 ; WX 684 ; N threequarters ; B 37 -19 664 714 ;
+C -1 ; WX 228 ; N icircumflex ; B -5 0 234 734 ;
+C -1 ; WX 547 ; N Edieresis ; B 71 0 505 901 ;
+C -1 ; WX 456 ; N ntilde ; B 53 0 403 722 ;
+C -1 ; WX 547 ; N Aring ; B 11 0 536 944 ;
+C -1 ; WX 456 ; N odieresis ; B 29 -14 427 706 ;
+C -1 ; WX 456 ; N oacute ; B 29 -14 427 734 ;
+C -1 ; WX 456 ; N ograve ; B 29 -14 427 734 ;
+C -1 ; WX 456 ; N ocircumflex ; B 29 -14 427 734 ;
+C -1 ; WX 456 ; N otilde ; B 29 -14 427 722 ;
+C -1 ; WX 410 ; N scaron ; B 26 -15 380 734 ;
+C -1 ; WX 456 ; N udieresis ; B 56 -15 401 706 ;
+C -1 ; WX 456 ; N uacute ; B 56 -15 401 734 ;
+C -1 ; WX 456 ; N ugrave ; B 56 -15 401 734 ;
+C -1 ; WX 456 ; N ucircumflex ; B 56 -15 401 734 ;
+C -1 ; WX 410 ; N yacute ; B 9 -214 401 734 ;
+C -1 ; WX 410 ; N zcaron ; B 25 0 385 734 ;
+C -1 ; WX 410 ; N ydieresis ; B 9 -214 401 706 ;
+C -1 ; WX 604 ; N copyright ; B -11 -19 617 737 ;
+C -1 ; WX 604 ; N registered ; B -11 -19 617 737 ;
+C -1 ; WX 547 ; N Atilde ; B 11 0 536 917 ;
+C -1 ; WX 228 ; N nbspace ; B 21 0 21 0 ;
+C -1 ; WX 592 ; N Ccedilla ; B 36 -225 558 737 ;
+C -1 ; WX 547 ; N Acircumflex ; B 11 0 536 929 ;
+C -1 ; WX 547 ; N Agrave ; B 11 0 536 929 ;
+C -1 ; WX 479 ; N logicalnot ; B 32 108 447 390 ;
+C -1 ; WX 547 ; N Aacute ; B 11 0 536 929 ;
+C -1 ; WX 592 ; N Eth ; B 0 0 553 718 ;
+C -1 ; WX 213 ; N brokenbar ; B 77 -19 137 737 ;
+C -1 ; WX 547 ; N Thorn ; B 71 0 510 718 ;
+C -1 ; WX 547 ; N Adieresis ; B 11 0 536 901 ;
+C -1 ; WX 456 ; N mu ; B 56 -207 401 523 ;
+C -1 ; WX 228 ; N .notdef ; B 21 0 21 0 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 998
+KPX A C -28
+KPX A Ccedilla -29
+KPX A G -30
+KPX A O -28
+KPX A Odieresis -28
+KPX A Q -28
+KPX A T -74
+KPX A U -29
+KPX A Uacute -29
+KPX A Ucircumflex -29
+KPX A Udieresis -29
+KPX A Ugrave -29
+KPX A V -56
+KPX A W -39
+KPX A Y -78
+KPX A a -3
+KPX A b 0
+KPX A c -10
+KPX A ccedilla -11
+KPX A comma 5
+KPX A d -11
+KPX A e -14
+KPX A g -14
+KPX A guillemotleft -40
+KPX A guilsinglleft -36
+KPX A hyphen -2
+KPX A o -14
+KPX A period 5
+KPX A q -11
+KPX A quotedblright -37
+KPX A quoteright -48
+KPX A t -15
+KPX A u -12
+KPX A v -27
+KPX A w -21
+KPX A y -28
+KPX Aacute C -28
+KPX Aacute G -30
+KPX Aacute O -28
+KPX Aacute Q -28
+KPX Aacute T -74
+KPX Aacute U -29
+KPX Aacute V -56
+KPX Aacute W -39
+KPX Aacute Y -78
+KPX Aacute a -3
+KPX Aacute b 0
+KPX Aacute c -10
+KPX Aacute comma 5
+KPX Aacute d -11
+KPX Aacute e -14
+KPX Aacute g -14
+KPX Aacute guillemotleft -40
+KPX Aacute guilsinglleft -36
+KPX Aacute hyphen -2
+KPX Aacute o -14
+KPX Aacute period 5
+KPX Aacute q -11
+KPX Aacute quoteright -48
+KPX Aacute t -15
+KPX Aacute u -12
+KPX Aacute v -27
+KPX Aacute w -21
+KPX Aacute y -28
+KPX Acircumflex C -28
+KPX Acircumflex G -30
+KPX Acircumflex O -28
+KPX Acircumflex Q -28
+KPX Acircumflex T -74
+KPX Acircumflex U -29
+KPX Acircumflex V -56
+KPX Acircumflex W -39
+KPX Acircumflex Y -78
+KPX Acircumflex comma 5
+KPX Acircumflex period 5
+KPX Adieresis C -28
+KPX Adieresis G -30
+KPX Adieresis O -28
+KPX Adieresis Q -28
+KPX Adieresis T -74
+KPX Adieresis U -29
+KPX Adieresis V -56
+KPX Adieresis W -39
+KPX Adieresis Y -78
+KPX Adieresis a -3
+KPX Adieresis b 0
+KPX Adieresis c -10
+KPX Adieresis comma 5
+KPX Adieresis d -11
+KPX Adieresis g -14
+KPX Adieresis guillemotleft -40
+KPX Adieresis guilsinglleft -36
+KPX Adieresis hyphen -2
+KPX Adieresis o -14
+KPX Adieresis period 5
+KPX Adieresis q -11
+KPX Adieresis quotedblright -37
+KPX Adieresis quoteright -48
+KPX Adieresis t -15
+KPX Adieresis u -12
+KPX Adieresis v -27
+KPX Adieresis w -21
+KPX Adieresis y -28
+KPX Agrave C -28
+KPX Agrave G -30
+KPX Agrave O -28
+KPX Agrave Q -28
+KPX Agrave T -74
+KPX Agrave U -29
+KPX Agrave V -56
+KPX Agrave W -39
+KPX Agrave Y -78
+KPX Agrave comma 5
+KPX Agrave period 5
+KPX Aring C -28
+KPX Aring G -30
+KPX Aring O -28
+KPX Aring Q -28
+KPX Aring T -74
+KPX Aring U -29
+KPX Aring V -56
+KPX Aring W -39
+KPX Aring Y -78
+KPX Aring a -3
+KPX Aring b 0
+KPX Aring c -10
+KPX Aring comma 5
+KPX Aring d -11
+KPX Aring e -14
+KPX Aring g -14
+KPX Aring guillemotleft -40
+KPX Aring guilsinglleft -36
+KPX Aring hyphen -2
+KPX Aring o -14
+KPX Aring period 5
+KPX Aring q -11
+KPX Aring quotedblright -37
+KPX Aring quoteright -48
+KPX Aring t -15
+KPX Aring u -12
+KPX Aring v -27
+KPX Aring w -21
+KPX Aring y -28
+KPX Atilde C -28
+KPX Atilde G -30
+KPX Atilde O -28
+KPX Atilde Q -28
+KPX Atilde T -74
+KPX Atilde U -29
+KPX Atilde V -56
+KPX Atilde W -39
+KPX Atilde Y -78
+KPX Atilde comma 5
+KPX Atilde period 5
+KPX B A -15
+KPX B AE -14
+KPX B Aacute -15
+KPX B Acircumflex -15
+KPX B Adieresis -15
+KPX B Aring -15
+KPX B Atilde -15
+KPX B O -3
+KPX B OE 0
+KPX B Oacute -3
+KPX B Ocircumflex -3
+KPX B Odieresis -3
+KPX B Ograve -3
+KPX B Oslash 0
+KPX B V -25
+KPX B W -15
+KPX B Y -31
+KPX C A -25
+KPX C AE -24
+KPX C Aacute -25
+KPX C Adieresis -25
+KPX C Aring -25
+KPX C H -6
+KPX C K -5
+KPX C O -4
+KPX C Oacute -4
+KPX C Odieresis -4
+KPX Ccedilla A -28
+KPX D A -33
+KPX D Aacute -33
+KPX D Acircumflex -33
+KPX D Adieresis -33
+KPX D Agrave -33
+KPX D Aring -33
+KPX D Atilde -33
+KPX D J -1
+KPX D T -30
+KPX D V -32
+KPX D W -18
+KPX D X -38
+KPX D Y -44
+KPX F A -55
+KPX F Aacute -55
+KPX F Acircumflex -55
+KPX F Adieresis -55
+KPX F Agrave -55
+KPX F Aring -55
+KPX F Atilde -55
+KPX F J -50
+KPX F O -15
+KPX F Odieresis -15
+KPX F a -26
+KPX F aacute -26
+KPX F adieresis -26
+KPX F ae -26
+KPX F aring -26
+KPX F comma -102
+KPX F e -19
+KPX F eacute -19
+KPX F hyphen -12
+KPX F i -8
+KPX F j -8
+KPX F o -17
+KPX F oacute -17
+KPX F odieresis -17
+KPX F oe -17
+KPX F oslash -17
+KPX F period -102
+KPX F r -32
+KPX F u -28
+KPX G A -4
+KPX G AE -2
+KPX G Aacute -4
+KPX G Acircumflex -4
+KPX G Adieresis -4
+KPX G Agrave -4
+KPX G Aring -4
+KPX G Atilde -4
+KPX G T -31
+KPX G V -36
+KPX G W -20
+KPX G Y -47
+KPX J A -22
+KPX J AE -21
+KPX J Adieresis -22
+KPX J Aring -22
+KPX K C -37
+KPX K G -40
+KPX K O -37
+KPX K OE -33
+KPX K Oacute -37
+KPX K Odieresis -37
+KPX K S -27
+KPX K T 22
+KPX K a -6
+KPX K adieresis -6
+KPX K ae -6
+KPX K aring -6
+KPX K e -26
+KPX K hyphen -38
+KPX K o -26
+KPX K oacute -26
+KPX K odieresis -26
+KPX K u -21
+KPX K udieresis -21
+KPX K y -52
+KPX L A 18
+KPX L AE 20
+KPX L Aacute 18
+KPX L Adieresis 18
+KPX L Aring 18
+KPX L C -28
+KPX L Ccedilla -32
+KPX L G -31
+KPX L O -29
+KPX L Oacute -29
+KPX L Ocircumflex -29
+KPX L Odieresis -29
+KPX L Ograve -29
+KPX L Otilde -29
+KPX L S -11
+KPX L T -81
+KPX L U -25
+KPX L Udieresis -25
+KPX L V -78
+KPX L W -50
+KPX L Y -92
+KPX L hyphen -110
+KPX L quotedblright -105
+KPX L quoteright -116
+KPX L u -9
+KPX L udieresis -9
+KPX L y -47
+KPX N A -4
+KPX N AE -2
+KPX N Aacute -4
+KPX N Adieresis -4
+KPX N Aring -4
+KPX N C 1
+KPX N Ccedilla 0
+KPX N G -1
+KPX N O 1
+KPX N Oacute 1
+KPX N Odieresis 1
+KPX N a -1
+KPX N aacute -1
+KPX N adieresis -1
+KPX N ae -1
+KPX N aring -1
+KPX N comma -4
+KPX N e 1
+KPX N eacute 1
+KPX N o 1
+KPX N oacute 1
+KPX N odieresis 1
+KPX N oslash 4
+KPX N period -4
+KPX N u 0
+KPX N udieresis 0
+KPX O A -29
+KPX O AE -29
+KPX O Aacute -29
+KPX O Adieresis -29
+KPX O Aring -29
+KPX O T -27
+KPX O V -30
+KPX O W -14
+KPX O X -34
+KPX O Y -42
+KPX Oacute A -29
+KPX Oacute T -27
+KPX Oacute V -30
+KPX Oacute W -14
+KPX Oacute Y -42
+KPX Ocircumflex T -27
+KPX Ocircumflex V -30
+KPX Ocircumflex Y -42
+KPX Odieresis A -29
+KPX Odieresis T -27
+KPX Odieresis V -30
+KPX Odieresis W -14
+KPX Odieresis X -34
+KPX Odieresis Y -42
+KPX Ograve T -27
+KPX Ograve V -30
+KPX Ograve Y -42
+KPX Oslash A -27
+KPX Otilde T -27
+KPX Otilde V -30
+KPX Otilde Y -42
+KPX P A -62
+KPX P AE -64
+KPX P Aacute -62
+KPX P Adieresis -62
+KPX P Aring -62
+KPX P J -70
+KPX P a -21
+KPX P aacute -21
+KPX P adieresis -21
+KPX P ae -21
+KPX P aring -21
+KPX P comma -123
+KPX P e -24
+KPX P eacute -24
+KPX P hyphen -28
+KPX P o -24
+KPX P oacute -24
+KPX P odieresis -24
+KPX P oe -22
+KPX P oslash -22
+KPX P period -123
+KPX R C -7
+KPX R Ccedilla -7
+KPX R G -9
+KPX R O -6
+KPX R OE -3
+KPX R Oacute -6
+KPX R Odieresis -6
+KPX R T -11
+KPX R U -8
+KPX R Udieresis -8
+KPX R V -22
+KPX R W -15
+KPX R Y -28
+KPX R a -6
+KPX R aacute -6
+KPX R adieresis -6
+KPX R ae -6
+KPX R aring -6
+KPX R e -5
+KPX R eacute -5
+KPX R hyphen 4
+KPX R o -5
+KPX R oacute -5
+KPX R odieresis -5
+KPX R oe -5
+KPX R u -4
+KPX R uacute -5
+KPX R udieresis -5
+KPX R y -1
+KPX S A -15
+KPX S AE -14
+KPX S Aacute -15
+KPX S Adieresis -15
+KPX S Aring -15
+KPX S T -14
+KPX S V -25
+KPX S W -17
+KPX S Y -31
+KPX S t -2
+KPX T A -78
+KPX T AE -76
+KPX T Aacute -78
+KPX T Acircumflex -78
+KPX T Adieresis -78
+KPX T Agrave -78
+KPX T Aring -78
+KPX T Atilde -78
+KPX T C -27
+KPX T G -31
+KPX T J -80
+KPX T O -26
+KPX T OE -21
+KPX T Oacute -26
+KPX T Ocircumflex -26
+KPX T Odieresis -26
+KPX T Ograve -26
+KPX T Oslash -27
+KPX T Otilde -26
+KPX T S -15
+KPX T V 17
+KPX T W 19
+KPX T Y 19
+KPX T a -79
+KPX T ae -79
+KPX T c -73
+KPX T colon -95
+KPX T comma -80
+KPX T e -77
+KPX T g -76
+KPX T guillemotleft -100
+KPX T guilsinglleft -96
+KPX T hyphen -60
+KPX T i -2
+KPX T j -2
+KPX T o -77
+KPX T oslash -72
+KPX T period -80
+KPX T r -77
+KPX T s -74
+KPX T semicolon -93
+KPX T u -75
+KPX T v -79
+KPX T w -80
+KPX T y -79
+KPX U A -32
+KPX U AE -32
+KPX U Aacute -32
+KPX U Acircumflex -32
+KPX U Adieresis -32
+KPX U Aring -32
+KPX U Atilde -32
+KPX U comma -24
+KPX U m -1
+KPX U n -1
+KPX U p 0
+KPX U period -22
+KPX U r -6
+KPX Uacute A -32
+KPX Uacute comma -24
+KPX Uacute m -1
+KPX Uacute n -1
+KPX Uacute p 0
+KPX Uacute period -22
+KPX Uacute r -6
+KPX Ucircumflex A -32
+KPX Udieresis A -32
+KPX Udieresis b 0
+KPX Udieresis comma -24
+KPX Udieresis m -1
+KPX Udieresis n -1
+KPX Udieresis p 0
+KPX Udieresis period -22
+KPX Udieresis r -6
+KPX Ugrave A -32
+KPX V A -58
+KPX V AE -60
+KPX V Aacute -58
+KPX V Acircumflex -58
+KPX V Adieresis -58
+KPX V Agrave -58
+KPX V Aring -58
+KPX V Atilde -58
+KPX V C -30
+KPX V G -34
+KPX V O -30
+KPX V Oacute -30
+KPX V Ocircumflex -30
+KPX V Odieresis -30
+KPX V Ograve -30
+KPX V Oslash -27
+KPX V Otilde -30
+KPX V S -26
+KPX V T 18
+KPX V a -47
+KPX V ae -47
+KPX V colon -41
+KPX V comma -73
+KPX V e -46
+KPX V g -44
+KPX V guillemotleft -68
+KPX V guilsinglleft -64
+KPX V hyphen -29
+KPX V i -5
+KPX V o -46
+KPX V oslash -41
+KPX V period -73
+KPX V r -37
+KPX V semicolon -41
+KPX V u -35
+KPX V y -12
+KPX W A -42
+KPX W AE -43
+KPX W Aacute -42
+KPX W Acircumflex -42
+KPX W Adieresis -42
+KPX W Agrave -42
+KPX W Aring -42
+KPX W Atilde -42
+KPX W C -15
+KPX W G -18
+KPX W O -15
+KPX W Oacute -15
+KPX W Ocircumflex -15
+KPX W Odieresis -15
+KPX W Ograve -15
+KPX W Oslash -12
+KPX W Otilde -15
+KPX W S -19
+KPX W T 20
+KPX W a -29
+KPX W ae -29
+KPX W colon -31
+KPX W comma -46
+KPX W e -26
+KPX W g -24
+KPX W guillemotleft -48
+KPX W guilsinglleft -44
+KPX W hyphen -9
+KPX W i -3
+KPX W o -26
+KPX W oslash -21
+KPX W period -46
+KPX W r -26
+KPX W semicolon -31
+KPX W u -24
+KPX W y -2
+KPX X C -33
+KPX X O -33
+KPX X Odieresis -33
+KPX X Q -33
+KPX X a -12
+KPX X e -31
+KPX X hyphen -40
+KPX X o -31
+KPX X u -27
+KPX X y -42
+KPX Y A -80
+KPX Y AE -82
+KPX Y Aacute -80
+KPX Y Acircumflex -80
+KPX Y Adieresis -80
+KPX Y Agrave -80
+KPX Y Aring -80
+KPX Y Atilde -80
+KPX Y C -42
+KPX Y G -47
+KPX Y O -43
+KPX Y Oacute -43
+KPX Y Ocircumflex -43
+KPX Y Odieresis -43
+KPX Y Ograve -43
+KPX Y Oslash -44
+KPX Y Otilde -43
+KPX Y S -33
+KPX Y T 20
+KPX Y a -73
+KPX Y ae -73
+KPX Y colon -60
+KPX Y comma -92
+KPX Y e -74
+KPX Y g -73
+KPX Y guillemotleft -103
+KPX Y guilsinglleft -99
+KPX Y hyphen -68
+KPX Y i -3
+KPX Y o -74
+KPX Y oslash -69
+KPX Y p -48
+KPX Y period -92
+KPX Y semicolon -60
+KPX Y u -54
+KPX Y v -31
+KPX Z v -24
+KPX Z y -25
+KPX a j -6
+KPX a quoteright -10
+KPX a v -19
+KPX a w -14
+KPX a y -20
+KPX aacute v -19
+KPX aacute w -14
+KPX aacute y -20
+KPX adieresis v -19
+KPX adieresis w -14
+KPX adieresis y -20
+KPX ae v -17
+KPX ae w -11
+KPX ae y -19
+KPX agrave v -19
+KPX agrave w -14
+KPX agrave y -20
+KPX aring v -19
+KPX aring w -14
+KPX aring y -20
+KPX b v -13
+KPX b w -8
+KPX b y -15
+KPX c h 2
+KPX c k 1
+KPX comma one -83
+KPX comma quotedblright -22
+KPX comma quoteright -33
+KPX e quoteright -5
+KPX e t -9
+KPX e v -16
+KPX e w -11
+KPX e x -19
+KPX e y -18
+KPX eacute v -16
+KPX eacute w -11
+KPX eacute y -18
+KPX ecircumflex v -16
+KPX ecircumflex w -11
+KPX ecircumflex y -18
+KPX eight four 6
+KPX eight one -36
+KPX eight seven -16
+KPX f a -9
+KPX f aacute -9
+KPX f adieresis -9
+KPX f ae -9
+KPX f aring -9
+KPX f e -13
+KPX f eacute -13
+KPX f f 17
+KPX f i -5
+KPX f j -5
+KPX f l -5
+KPX f o -12
+KPX f oacute -12
+KPX f odieresis -12
+KPX f oe -12
+KPX f oslash -8
+KPX f quoteright 12
+KPX f s -4
+KPX f t 17
+KPX five four 4
+KPX five one -56
+KPX five seven -16
+KPX four four 8
+KPX four one -65
+KPX four seven -39
+KPX g a 1
+KPX g adieresis 1
+KPX g ae 1
+KPX g aring 1
+KPX g e 4
+KPX g eacute 4
+KPX g l 4
+KPX g oacute 4
+KPX g odieresis 4
+KPX g r 0
+KPX guillemotright A -42
+KPX guillemotright AE -43
+KPX guillemotright Aacute -42
+KPX guillemotright Adieresis -42
+KPX guillemotright Aring -42
+KPX guillemotright T -101
+KPX guillemotright V -68
+KPX guillemotright W -48
+KPX guillemotright Y -102
+KPX guilsinglright A -38
+KPX guilsinglright AE -39
+KPX guilsinglright Aacute -38
+KPX guilsinglright Adieresis -38
+KPX guilsinglright Aring -38
+KPX guilsinglright T -96
+KPX guilsinglright V -64
+KPX guilsinglright W -44
+KPX guilsinglright Y -98
+KPX h quoteright -3
+KPX h y -14
+KPX hyphen A -3
+KPX hyphen AE -4
+KPX hyphen Aacute -3
+KPX hyphen Adieresis -3
+KPX hyphen Aring -3
+KPX hyphen T -61
+KPX hyphen V -29
+KPX hyphen W -9
+KPX hyphen Y -67
+KPX i T -2
+KPX i j 0
+KPX k a -5
+KPX k aacute -5
+KPX k adieresis -5
+KPX k ae -5
+KPX k aring -5
+KPX k comma 1
+KPX k e -19
+KPX k eacute -19
+KPX k g -18
+KPX k hyphen -31
+KPX k o -19
+KPX k oacute -19
+KPX k odieresis -19
+KPX k period 1
+KPX k s -9
+KPX k u -3
+KPX k udieresis -3
+KPX l v -3
+KPX l y -3
+KPX m p 4
+KPX m v -13
+KPX m w -7
+KPX m y -14
+KPX n T -75
+KPX n p 4
+KPX n quoteright -3
+KPX n v -14
+KPX n w -8
+KPX n y -14
+KPX nine four 1
+KPX nine one -31
+KPX nine seven -19
+KPX o T -77
+KPX o quoteright -8
+KPX o t -7
+KPX o v -15
+KPX o w -9
+KPX o x -18
+KPX o y -17
+KPX oacute v -15
+KPX oacute w -9
+KPX oacute y -17
+KPX ocircumflex t -7
+KPX odieresis t -7
+KPX odieresis v -15
+KPX odieresis w -9
+KPX odieresis x -18
+KPX odieresis y -17
+KPX ograve v -15
+KPX ograve w -9
+KPX ograve y -17
+KPX one comma -54
+KPX one eight -46
+KPX one five -49
+KPX one four -59
+KPX one nine -47
+KPX one one -90
+KPX one period -54
+KPX one seven -64
+KPX one six -44
+KPX one three -51
+KPX one two -50
+KPX one zero -43
+KPX p t -6
+KPX p y -15
+KPX period one -83
+KPX period quotedblright -22
+KPX period quoteright -33
+KPX q c 5
+KPX q u 1
+KPX quotedblbase A 24
+KPX quotedblbase AE 25
+KPX quotedblbase T -60
+KPX quotedblbase V -53
+KPX quotedblbase W -25
+KPX quotedblbase Y -71
+KPX quotedblleft A -41
+KPX quotedblleft AE -45
+KPX quotedblleft Aacute -41
+KPX quotedblleft Adieresis -41
+KPX quotedblleft Aring -41
+KPX quotedblleft T 16
+KPX quotedblleft V 24
+KPX quotedblleft W 31
+KPX quotedblleft Y 14
+KPX quotedblright A -49
+KPX quotedblright AE -52
+KPX quotedblright Aacute -49
+KPX quotedblright Adieresis -49
+KPX quotedblright Aring -49
+KPX quotedblright T 11
+KPX quotedblright V 16
+KPX quotedblright W 23
+KPX quotedblright Y 9
+KPX quoteleft A -52
+KPX quoteleft AE -56
+KPX quoteleft Aacute -52
+KPX quoteleft Adieresis -52
+KPX quoteleft Aring -52
+KPX quoteleft T 5
+KPX quoteleft V 13
+KPX quoteleft W 20
+KPX quoteleft Y 3
+KPX quoteright A -60
+KPX quoteright AE -63
+KPX quoteright Aacute -60
+KPX quoteright Adieresis -60
+KPX quoteright Aring -60
+KPX quoteright comma -48
+KPX quoteright d -16
+KPX quoteright o -24
+KPX quoteright period -48
+KPX quoteright r -15
+KPX quoteright s -13
+KPX quoteright t -3
+KPX quoteright v 0
+KPX quoteright w 1
+KPX quoteright y 0
+KPX r a -3
+KPX r aacute -3
+KPX r acircumflex -3
+KPX r adieresis -3
+KPX r ae -3
+KPX r agrave -3
+KPX r aring -3
+KPX r c -6
+KPX r ccedilla -3
+KPX r colon -5
+KPX r comma -48
+KPX r d -3
+KPX r e -10
+KPX r eacute -10
+KPX r ecircumflex -10
+KPX r egrave -10
+KPX r f 23
+KPX r g -4
+KPX r h 2
+KPX r hyphen -30
+KPX r i 1
+KPX r j 0
+KPX r k 1
+KPX r l 1
+KPX r m 2
+KPX r n 2
+KPX r o -11
+KPX r oacute -11
+KPX r ocircumflex -11
+KPX r odieresis -11
+KPX r oe -7
+KPX r ograve -11
+KPX r oslash -7
+KPX r p 4
+KPX r period -48
+KPX r q -4
+KPX r quoteright 13
+KPX r r -3
+KPX r s 2
+KPX r semicolon -5
+KPX r t 23
+KPX r u 0
+KPX r v 24
+KPX r w 22
+KPX r x 19
+KPX r y 23
+KPX r z 6
+KPX s quoteright -5
+KPX s t -5
+KPX seven colon -47
+KPX seven comma -95
+KPX seven eight -15
+KPX seven five -22
+KPX seven four -72
+KPX seven one -34
+KPX seven period -95
+KPX seven seven 3
+KPX seven six -24
+KPX seven three -14
+KPX seven two -13
+KPX six four 6
+KPX six one -31
+KPX six seven -13
+KPX t S -8
+KPX t a 1
+KPX t aacute 1
+KPX t adieresis 1
+KPX t ae 1
+KPX t aring 1
+KPX t colon -13
+KPX t e -10
+KPX t eacute -10
+KPX t h 1
+KPX t o -10
+KPX t oacute -10
+KPX t odieresis -10
+KPX t quoteright 10
+KPX t semicolon -13
+KPX three four 8
+KPX three one -34
+KPX three seven -15
+KPX two four -38
+KPX two one -29
+KPX two seven -13
+KPX u quoteright 5
+KPX v a -16
+KPX v aacute -16
+KPX v acircumflex -16
+KPX v adieresis -16
+KPX v ae -16
+KPX v agrave -16
+KPX v aring -16
+KPX v atilde -16
+KPX v c -12
+KPX v colon -8
+KPX v comma -51
+KPX v e -16
+KPX v eacute -16
+KPX v ecircumflex -16
+KPX v egrave -16
+KPX v g -15
+KPX v hyphen -3
+KPX v l -2
+KPX v o -16
+KPX v oacute -16
+KPX v odieresis -16
+KPX v ograve -16
+KPX v oslash -12
+KPX v period -51
+KPX v s -10
+KPX v semicolon -8
+KPX w a -13
+KPX w aacute -13
+KPX w acircumflex -13
+KPX w adieresis -13
+KPX w ae -13
+KPX w agrave -13
+KPX w aring -13
+KPX w atilde -13
+KPX w c -5
+KPX w colon -10
+KPX w comma -37
+KPX w e -9
+KPX w eacute -9
+KPX w ecircumflex -9
+KPX w egrave -9
+KPX w g -8
+KPX w hyphen 3
+KPX w l -4
+KPX w o -9
+KPX w oacute -9
+KPX w odieresis -9
+KPX w ograve -9
+KPX w oslash -5
+KPX w period -37
+KPX w s -7
+KPX w semicolon -10
+KPX x a -10
+KPX x c -13
+KPX x e -17
+KPX x eacute -17
+KPX x o -17
+KPX x q -14
+KPX y a -16
+KPX y aacute -16
+KPX y acircumflex -16
+KPX y adieresis -16
+KPX y ae -16
+KPX y agrave -16
+KPX y aring -16
+KPX y atilde -16
+KPX y c -13
+KPX y colon -9
+KPX y comma -50
+KPX y e -17
+KPX y eacute -17
+KPX y ecircumflex -17
+KPX y egrave -17
+KPX y g -15
+KPX y hyphen -2
+KPX y l -3
+KPX y o -17
+KPX y oacute -17
+KPX y odieresis -17
+KPX y ograve -17
+KPX y oslash -12
+KPX y period -49
+KPX y s -11
+KPX y semicolon -9
+KPX zero four 5
+KPX zero one -31
+KPX zero seven -21
+EndKernPairs
+EndKernData
+EndFontMetrics
diff --git a/misc/gs_afm/HelvBo.afm b/misc/gs_afm/HelvBo.afm
new file mode 100644
index 0000000000..a1100ae8d8
--- /dev/null
+++ b/misc/gs_afm/HelvBo.afm
@@ -0,0 +1,1257 @@
+StartFontMetrics 3.0
+Comment Copyright URW Software, Copyright 1994 by URW
+Comment Creation Date: 8/3/1994
+Comment See the file PUBLIC (Aladdin Free Public License) for license conditions.
+FontName NimbusSanL-BoldCond
+FullName Nimbus Sans L Bold Condensed
+FamilyName Nimbus Sans L
+Weight Bold
+ItalicAngle 0.0
+IsFixedPitch false
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.005
+Notice URW Software, Copyright 1994 by URW
+EncodingScheme AdobeStandardEncoding
+FontBBox -139 -228 822 975
+CapHeight 718
+XHeight 532
+Descender -207
+Ascender 718
+StartCharMetrics 232
+C 32 ; WX 228 ; N space ; B 21 0 21 0 ;
+C 33 ; WX 273 ; N exclam ; B 74 0 200 718 ;
+C 34 ; WX 389 ; N quotedbl ; B 80 447 308 718 ;
+C 35 ; WX 456 ; N numbersign ; B 15 0 441 698 ;
+C 36 ; WX 456 ; N dollar ; B 24 -115 429 775 ;
+C 37 ; WX 729 ; N percent ; B 23 -19 706 710 ;
+C 38 ; WX 592 ; N ampersand ; B 44 -19 575 718 ;
+C 39 ; WX 228 ; N quoteright ; B 57 445 171 718 ;
+C 40 ; WX 273 ; N parenleft ; B 29 -207 257 734 ;
+C 41 ; WX 273 ; N parenright ; B 16 -207 244 734 ;
+C 42 ; WX 319 ; N asterisk ; B 22 387 297 718 ;
+C 43 ; WX 479 ; N plus ; B 33 0 446 506 ;
+C 44 ; WX 228 ; N comma ; B 52 -168 175 147 ;
+C 45 ; WX 273 ; N hyphen ; B 22 215 251 345 ;
+C 46 ; WX 228 ; N period ; B 52 0 175 147 ;
+C 47 ; WX 228 ; N slash ; B -27 -19 255 737 ;
+C 48 ; WX 456 ; N zero ; B 26 -19 430 710 ;
+C 49 ; WX 456 ; N one ; B 57 0 310 710 ;
+C 50 ; WX 456 ; N two ; B 21 0 419 710 ;
+C 51 ; WX 456 ; N three ; B 22 -19 423 710 ;
+C 52 ; WX 456 ; N four ; B 22 0 431 710 ;
+C 53 ; WX 456 ; N five ; B 22 -19 423 698 ;
+C 54 ; WX 456 ; N six ; B 25 -19 426 710 ;
+C 55 ; WX 456 ; N seven ; B 20 0 433 698 ;
+C 56 ; WX 456 ; N eight ; B 26 -19 430 710 ;
+C 57 ; WX 456 ; N nine ; B 25 -19 428 710 ;
+C 58 ; WX 273 ; N colon ; B 75 0 198 512 ;
+C 59 ; WX 273 ; N semicolon ; B 75 -168 198 512 ;
+C 60 ; WX 479 ; N less ; B 31 -15 448 521 ;
+C 61 ; WX 479 ; N equal ; B 33 87 446 419 ;
+C 62 ; WX 479 ; N greater ; B 31 -15 448 521 ;
+C 63 ; WX 501 ; N question ; B 49 0 456 727 ;
+C 64 ; WX 800 ; N at ; B 97 -19 702 737 ;
+C 65 ; WX 592 ; N A ; B 16 0 576 718 ;
+C 66 ; WX 592 ; N B ; B 62 0 549 718 ;
+C 67 ; WX 592 ; N C ; B 36 -19 561 737 ;
+C 68 ; WX 592 ; N D ; B 62 0 562 718 ;
+C 69 ; WX 547 ; N E ; B 62 0 509 718 ;
+C 70 ; WX 501 ; N F ; B 62 0 481 718 ;
+C 71 ; WX 638 ; N G ; B 36 -19 585 737 ;
+C 72 ; WX 592 ; N H ; B 58 0 534 718 ;
+C 73 ; WX 228 ; N I ; B 52 0 175 718 ;
+C 74 ; WX 456 ; N J ; B 18 -18 397 718 ;
+C 75 ; WX 592 ; N K ; B 71 0 592 718 ;
+C 76 ; WX 501 ; N L ; B 62 0 478 718 ;
+C 77 ; WX 683 ; N M ; B 57 0 627 718 ;
+C 78 ; WX 592 ; N N ; B 57 0 536 718 ;
+C 79 ; WX 638 ; N O ; B 36 -19 602 737 ;
+C 80 ; WX 547 ; N P ; B 62 0 514 718 ;
+C 81 ; WX 638 ; N Q ; B 36 -52 604 737 ;
+C 82 ; WX 592 ; N R ; B 62 0 555 718 ;
+C 83 ; WX 547 ; N S ; B 32 -19 516 737 ;
+C 84 ; WX 501 ; N T ; B 11 0 490 718 ;
+C 85 ; WX 592 ; N U ; B 59 -19 534 718 ;
+C 86 ; WX 547 ; N V ; B 16 0 531 718 ;
+C 87 ; WX 774 ; N W ; B 13 0 762 718 ;
+C 88 ; WX 547 ; N X ; B 11 0 535 718 ;
+C 89 ; WX 547 ; N Y ; B 12 0 535 718 ;
+C 90 ; WX 501 ; N Z ; B 20 0 481 718 ;
+C 91 ; WX 273 ; N bracketleft ; B 52 -196 253 722 ;
+C 92 ; WX 228 ; N backslash ; B -27 -19 255 737 ;
+C 93 ; WX 273 ; N bracketright ; B 20 -196 221 722 ;
+C 94 ; WX 479 ; N asciicircum ; B 51 323 428 698 ;
+C 95 ; WX 456 ; N underscore ; B 0 -125 456 -75 ;
+C 96 ; WX 228 ; N quoteleft ; B 57 454 171 727 ;
+C 97 ; WX 456 ; N a ; B 24 -14 432 546 ;
+C 98 ; WX 501 ; N b ; B 50 -14 474 718 ;
+C 99 ; WX 456 ; N c ; B 28 -14 430 546 ;
+C 100 ; WX 501 ; N d ; B 28 -14 452 718 ;
+C 101 ; WX 456 ; N e ; B 19 -14 433 546 ;
+C 102 ; WX 273 ; N f ; B 8 0 261 727 ;
+C 103 ; WX 501 ; N g ; B 33 -217 453 546 ;
+C 104 ; WX 501 ; N h ; B 53 0 448 718 ;
+C 105 ; WX 228 ; N i ; B 57 0 171 725 ;
+C 106 ; WX 228 ; N j ; B 2 -214 171 725 ;
+C 107 ; WX 456 ; N k ; B 57 0 461 718 ;
+C 108 ; WX 228 ; N l ; B 57 0 171 718 ;
+C 109 ; WX 729 ; N m ; B 52 0 677 546 ;
+C 110 ; WX 501 ; N n ; B 53 0 448 546 ;
+C 111 ; WX 501 ; N o ; B 28 -14 474 546 ;
+C 112 ; WX 501 ; N p ; B 51 -207 474 546 ;
+C 113 ; WX 501 ; N q ; B 28 -207 453 546 ;
+C 114 ; WX 319 ; N r ; B 52 0 306 546 ;
+C 115 ; WX 456 ; N s ; B 25 -14 426 546 ;
+C 116 ; WX 273 ; N t ; B 8 -6 253 676 ;
+C 117 ; WX 501 ; N u ; B 54 -14 447 532 ;
+C 118 ; WX 456 ; N v ; B 11 0 445 532 ;
+C 119 ; WX 638 ; N w ; B 8 0 631 532 ;
+C 120 ; WX 456 ; N x ; B 12 0 444 532 ;
+C 121 ; WX 456 ; N y ; B 8 -214 442 532 ;
+C 122 ; WX 410 ; N z ; B 16 0 394 532 ;
+C 123 ; WX 319 ; N braceleft ; B 39 -196 299 722 ;
+C 124 ; WX 230 ; N bar ; B 69 -19 161 737 ;
+C 125 ; WX 319 ; N braceright ; B 20 -196 280 722 ;
+C 126 ; WX 479 ; N asciitilde ; B 50 173 429 336 ;
+C 161 ; WX 273 ; N exclamdown ; B 74 -186 200 532 ;
+C 162 ; WX 456 ; N cent ; B 28 -118 430 628 ;
+C 163 ; WX 456 ; N sterling ; B 23 -16 444 718 ;
+C 164 ; WX 137 ; N fraction ; B -139 -19 276 710 ;
+C 165 ; WX 456 ; N yen ; B -7 0 463 698 ;
+C 166 ; WX 456 ; N florin ; B -8 -210 423 737 ;
+C 167 ; WX 456 ; N section ; B 28 -184 428 727 ;
+C 168 ; WX 456 ; N currency ; B -2 76 458 636 ;
+C 169 ; WX 195 ; N quotesingle ; B 57 447 138 718 ;
+C 170 ; WX 410 ; N quotedblleft ; B 52 454 358 727 ;
+C 171 ; WX 456 ; N guillemotleft ; B 72 76 384 484 ;
+C 172 ; WX 273 ; N guilsinglleft ; B 68 76 205 484 ;
+C 173 ; WX 273 ; N guilsinglright ; B 68 76 205 484 ;
+C 174 ; WX 501 ; N fi ; B 8 0 444 727 ;
+C 175 ; WX 501 ; N fl ; B 8 0 444 727 ;
+C 177 ; WX 456 ; N endash ; B 0 226 456 333 ;
+C 178 ; WX 456 ; N dagger ; B 30 -171 426 718 ;
+C 179 ; WX 456 ; N daggerdbl ; B 30 -171 426 718 ;
+C 180 ; WX 228 ; N periodcentered ; B 48 172 180 334 ;
+C 182 ; WX 456 ; N paragraph ; B -7 -191 442 700 ;
+C 183 ; WX 287 ; N bullet ; B 8 194 279 524 ;
+C 184 ; WX 228 ; N quotesinglbase ; B 57 -146 171 127 ;
+C 185 ; WX 410 ; N quotedblbase ; B 52 -146 358 127 ;
+C 186 ; WX 410 ; N quotedblright ; B 52 445 358 718 ;
+C 187 ; WX 456 ; N guillemotright ; B 72 76 384 484 ;
+C 188 ; WX 820 ; N ellipsis ; B 75 0 745 147 ;
+C 189 ; WX 820 ; N perthousand ; B -2 -19 822 710 ;
+C 191 ; WX 501 ; N questiondown ; B 45 -195 452 532 ;
+C 193 ; WX 273 ; N grave ; B -19 604 184 750 ;
+C 194 ; WX 273 ; N acute ; B 89 604 292 750 ;
+C 195 ; WX 273 ; N circumflex ; B -8 604 281 750 ;
+C 196 ; WX 273 ; N tilde ; B -14 610 287 737 ;
+C 197 ; WX 273 ; N macron ; B -5 605 278 678 ;
+C 198 ; WX 273 ; N breve ; B -2 604 275 750 ;
+C 199 ; WX 273 ; N dotaccent ; B 85 614 189 729 ;
+C 200 ; WX 273 ; N dieresis ; B 5 614 268 729 ;
+C 202 ; WX 273 ; N ring ; B 48 568 225 776 ;
+C 203 ; WX 273 ; N cedilla ; B 5 -228 201 0 ;
+C 205 ; WX 273 ; N hungarumlaut ; B 7 604 399 750 ;
+C 206 ; WX 273 ; N ogonek ; B 58 -228 249 0 ;
+C 207 ; WX 273 ; N caron ; B -8 604 281 750 ;
+C 208 ; WX 820 ; N emdash ; B 0 226 820 333 ;
+C 225 ; WX 820 ; N AE ; B 4 0 782 718 ;
+C 227 ; WX 303 ; N ordfeminine ; B 18 276 285 737 ;
+C 232 ; WX 501 ; N Lslash ; B -16 0 478 718 ;
+C 233 ; WX 638 ; N Oslash ; B 27 -27 610 745 ;
+C 234 ; WX 820 ; N OE ; B 30 -19 788 737 ;
+C 235 ; WX 299 ; N ordmasculine ; B 5 276 295 737 ;
+C 241 ; WX 729 ; N ae ; B 24 -14 704 546 ;
+C 245 ; WX 228 ; N dotlessi ; B 57 0 171 532 ;
+C 248 ; WX 228 ; N lslash ; B -15 0 243 718 ;
+C 249 ; WX 501 ; N oslash ; B 18 -29 483 560 ;
+C 250 ; WX 774 ; N oe ; B 28 -14 748 546 ;
+C 251 ; WX 501 ; N germandbls ; B 57 -14 475 731 ;
+C -1 ; WX 547 ; N Yacute ; B 12 0 535 936 ;
+C -1 ; WX 592 ; N Ucircumflex ; B 59 -19 534 936 ;
+C -1 ; WX 592 ; N Ugrave ; B 59 -19 534 936 ;
+C -1 ; WX 501 ; N Zcaron ; B 20 0 481 936 ;
+C -1 ; WX 547 ; N Ydieresis ; B 12 0 535 915 ;
+C -1 ; WX 273 ; N threesuperior ; B 7 271 267 722 ;
+C -1 ; WX 592 ; N Uacute ; B 59 -19 534 936 ;
+C -1 ; WX 273 ; N twosuperior ; B 7 283 266 722 ;
+C -1 ; WX 592 ; N Udieresis ; B 59 -19 534 915 ;
+C -1 ; WX 228 ; N middot ; B 48 172 180 334 ;
+C -1 ; WX 273 ; N onesuperior ; B 21 283 194 710 ;
+C -1 ; WX 456 ; N aacute ; B 24 -14 432 750 ;
+C -1 ; WX 456 ; N agrave ; B 24 -14 432 750 ;
+C -1 ; WX 456 ; N acircumflex ; B 24 -14 432 750 ;
+C -1 ; WX 547 ; N Scaron ; B 32 -19 516 936 ;
+C -1 ; WX 638 ; N Otilde ; B 36 -19 602 923 ;
+C -1 ; WX 273 ; N sfthyphen ; B 22 215 251 345 ;
+C -1 ; WX 456 ; N atilde ; B 24 -14 432 737 ;
+C -1 ; WX 456 ; N aring ; B 24 -14 432 803 ;
+C -1 ; WX 456 ; N adieresis ; B 24 -14 432 729 ;
+C -1 ; WX 638 ; N Ograve ; B 36 -19 602 936 ;
+C -1 ; WX 638 ; N Ocircumflex ; B 36 -19 602 936 ;
+C -1 ; WX 638 ; N Odieresis ; B 36 -19 602 915 ;
+C -1 ; WX 592 ; N Ntilde ; B 57 0 536 923 ;
+C -1 ; WX 456 ; N edieresis ; B 19 -14 433 729 ;
+C -1 ; WX 456 ; N eacute ; B 19 -14 433 750 ;
+C -1 ; WX 456 ; N egrave ; B 19 -14 433 750 ;
+C -1 ; WX 228 ; N Icircumflex ; B -30 0 259 936 ;
+C -1 ; WX 456 ; N ecircumflex ; B 19 -14 433 750 ;
+C -1 ; WX 228 ; N Igrave ; B -41 0 175 936 ;
+C -1 ; WX 228 ; N Iacute ; B 52 0 270 936 ;
+C -1 ; WX 228 ; N Idieresis ; B -17 0 246 915 ;
+C -1 ; WX 328 ; N degree ; B 47 426 281 712 ;
+C -1 ; WX 547 ; N Ecircumflex ; B 62 0 509 936 ;
+C -1 ; WX 479 ; N minus ; B 33 197 446 309 ;
+C -1 ; WX 479 ; N multiply ; B 33 1 447 505 ;
+C -1 ; WX 479 ; N divide ; B 33 -42 446 548 ;
+C -1 ; WX 547 ; N Egrave ; B 62 0 509 936 ;
+C -1 ; WX 820 ; N trademark ; B 36 306 784 718 ;
+C -1 ; WX 638 ; N Oacute ; B 36 -19 602 936 ;
+C -1 ; WX 501 ; N thorn ; B 51 -207 474 718 ;
+C -1 ; WX 501 ; N eth ; B 28 -14 474 737 ;
+C -1 ; WX 547 ; N Eacute ; B 62 0 509 936 ;
+C -1 ; WX 456 ; N ccedilla ; B 28 -228 430 546 ;
+C -1 ; WX 228 ; N idieresis ; B -17 0 246 729 ;
+C -1 ; WX 228 ; N iacute ; B 57 0 270 750 ;
+C -1 ; WX 228 ; N igrave ; B -41 0 171 750 ;
+C -1 ; WX 479 ; N plusminus ; B 33 0 446 578 ;
+C -1 ; WX 684 ; N onehalf ; B 21 -19 651 710 ;
+C -1 ; WX 684 ; N onequarter ; B 21 -19 628 710 ;
+C -1 ; WX 684 ; N threequarters ; B 13 -19 655 722 ;
+C -1 ; WX 228 ; N icircumflex ; B -30 0 259 750 ;
+C -1 ; WX 547 ; N Edieresis ; B 62 0 509 915 ;
+C -1 ; WX 501 ; N ntilde ; B 53 0 448 737 ;
+C -1 ; WX 592 ; N Aring ; B 16 0 576 975 ;
+C -1 ; WX 501 ; N odieresis ; B 28 -14 474 729 ;
+C -1 ; WX 501 ; N oacute ; B 28 -14 474 750 ;
+C -1 ; WX 501 ; N ograve ; B 28 -14 474 750 ;
+C -1 ; WX 501 ; N ocircumflex ; B 28 -14 474 750 ;
+C -1 ; WX 501 ; N otilde ; B 28 -14 474 737 ;
+C -1 ; WX 456 ; N scaron ; B 25 -14 426 750 ;
+C -1 ; WX 501 ; N udieresis ; B 54 -14 447 729 ;
+C -1 ; WX 501 ; N uacute ; B 54 -14 447 750 ;
+C -1 ; WX 501 ; N ugrave ; B 54 -14 447 750 ;
+C -1 ; WX 501 ; N ucircumflex ; B 54 -14 447 750 ;
+C -1 ; WX 456 ; N yacute ; B 8 -214 442 750 ;
+C -1 ; WX 410 ; N zcaron ; B 16 0 394 750 ;
+C -1 ; WX 456 ; N ydieresis ; B 8 -214 442 729 ;
+C -1 ; WX 604 ; N copyright ; B -9 -19 614 737 ;
+C -1 ; WX 604 ; N registered ; B -9 -19 613 737 ;
+C -1 ; WX 592 ; N Atilde ; B 16 0 576 923 ;
+C -1 ; WX 228 ; N nbspace ; B 21 0 21 0 ;
+C -1 ; WX 592 ; N Ccedilla ; B 36 -228 561 737 ;
+C -1 ; WX 592 ; N Acircumflex ; B 16 0 576 936 ;
+C -1 ; WX 592 ; N Agrave ; B 16 0 576 936 ;
+C -1 ; WX 479 ; N logicalnot ; B 33 108 446 419 ;
+C -1 ; WX 592 ; N Aacute ; B 16 0 576 936 ;
+C -1 ; WX 592 ; N Eth ; B -4 0 562 718 ;
+C -1 ; WX 230 ; N brokenbar ; B 69 -19 161 737 ;
+C -1 ; WX 547 ; N Thorn ; B 62 0 514 718 ;
+C -1 ; WX 592 ; N Adieresis ; B 16 0 576 915 ;
+C -1 ; WX 501 ; N mu ; B 54 -207 447 532 ;
+C -1 ; WX 228 ; N .notdef ; B 21 0 21 0 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 998
+KPX A C -26
+KPX A Ccedilla -26
+KPX A G -27
+KPX A O -27
+KPX A Odieresis -27
+KPX A Q -27
+KPX A T -62
+KPX A U -24
+KPX A Uacute -24
+KPX A Ucircumflex -24
+KPX A Udieresis -24
+KPX A Ugrave -24
+KPX A V -50
+KPX A W -41
+KPX A Y -69
+KPX A a -1
+KPX A b -1
+KPX A c -11
+KPX A ccedilla -11
+KPX A comma 17
+KPX A d -11
+KPX A e -7
+KPX A g -16
+KPX A guillemotleft -35
+KPX A guilsinglleft -33
+KPX A hyphen 7
+KPX A o -14
+KPX A period 17
+KPX A q -12
+KPX A quotedblright -48
+KPX A quoteright -50
+KPX A t -13
+KPX A u -12
+KPX A v -29
+KPX A w -19
+KPX A y -27
+KPX Aacute C -26
+KPX Aacute G -27
+KPX Aacute O -27
+KPX Aacute Q -27
+KPX Aacute T -62
+KPX Aacute U -24
+KPX Aacute V -50
+KPX Aacute W -41
+KPX Aacute Y -69
+KPX Aacute a -1
+KPX Aacute b -1
+KPX Aacute c -11
+KPX Aacute comma 17
+KPX Aacute d -11
+KPX Aacute e -7
+KPX Aacute g -16
+KPX Aacute guillemotleft -35
+KPX Aacute guilsinglleft -33
+KPX Aacute hyphen 7
+KPX Aacute o -14
+KPX Aacute period 17
+KPX Aacute q -12
+KPX Aacute quoteright -50
+KPX Aacute t -13
+KPX Aacute u -12
+KPX Aacute v -29
+KPX Aacute w -19
+KPX Aacute y -27
+KPX Acircumflex C -26
+KPX Acircumflex G -27
+KPX Acircumflex O -27
+KPX Acircumflex Q -27
+KPX Acircumflex T -62
+KPX Acircumflex U -24
+KPX Acircumflex V -50
+KPX Acircumflex W -41
+KPX Acircumflex Y -69
+KPX Acircumflex comma 17
+KPX Acircumflex period 17
+KPX Adieresis C -26
+KPX Adieresis G -27
+KPX Adieresis O -27
+KPX Adieresis Q -27
+KPX Adieresis T -62
+KPX Adieresis U -24
+KPX Adieresis V -50
+KPX Adieresis W -41
+KPX Adieresis Y -69
+KPX Adieresis a -1
+KPX Adieresis b -1
+KPX Adieresis c -11
+KPX Adieresis comma 17
+KPX Adieresis d -11
+KPX Adieresis g -16
+KPX Adieresis guillemotleft -35
+KPX Adieresis guilsinglleft -33
+KPX Adieresis hyphen 7
+KPX Adieresis o -14
+KPX Adieresis period 17
+KPX Adieresis q -12
+KPX Adieresis quotedblright -48
+KPX Adieresis quoteright -50
+KPX Adieresis t -13
+KPX Adieresis u -12
+KPX Adieresis v -29
+KPX Adieresis w -19
+KPX Adieresis y -27
+KPX Agrave C -26
+KPX Agrave G -27
+KPX Agrave O -27
+KPX Agrave Q -27
+KPX Agrave T -62
+KPX Agrave U -24
+KPX Agrave V -50
+KPX Agrave W -41
+KPX Agrave Y -69
+KPX Agrave comma 17
+KPX Agrave period 17
+KPX Aring C -26
+KPX Aring G -27
+KPX Aring O -27
+KPX Aring Q -27
+KPX Aring T -62
+KPX Aring U -24
+KPX Aring V -50
+KPX Aring W -41
+KPX Aring Y -69
+KPX Aring a -1
+KPX Aring b -1
+KPX Aring c -11
+KPX Aring comma 17
+KPX Aring d -11
+KPX Aring e -7
+KPX Aring g -16
+KPX Aring guillemotleft -35
+KPX Aring guilsinglleft -33
+KPX Aring hyphen 7
+KPX Aring o -14
+KPX Aring period 17
+KPX Aring q -12
+KPX Aring quotedblright -48
+KPX Aring quoteright -50
+KPX Aring t -13
+KPX Aring u -12
+KPX Aring v -29
+KPX Aring w -19
+KPX Aring y -27
+KPX Atilde C -26
+KPX Atilde G -27
+KPX Atilde O -27
+KPX Atilde Q -27
+KPX Atilde T -62
+KPX Atilde U -24
+KPX Atilde V -50
+KPX Atilde W -41
+KPX Atilde Y -69
+KPX Atilde comma 17
+KPX Atilde period 17
+KPX B A -17
+KPX B AE -11
+KPX B Aacute -17
+KPX B Acircumflex -17
+KPX B Adieresis -17
+KPX B Aring -17
+KPX B Atilde -17
+KPX B O -4
+KPX B OE 1
+KPX B Oacute -4
+KPX B Ocircumflex -4
+KPX B Odieresis -4
+KPX B Ograve -4
+KPX B Oslash 0
+KPX B V -22
+KPX B W -17
+KPX B Y -29
+KPX C A -19
+KPX C AE -14
+KPX C Aacute -19
+KPX C Adieresis -19
+KPX C Aring -19
+KPX C H 1
+KPX C K -5
+KPX C O -2
+KPX C Oacute -2
+KPX C Odieresis -2
+KPX Ccedilla A -21
+KPX D A -24
+KPX D Aacute -24
+KPX D Acircumflex -24
+KPX D Adieresis -24
+KPX D Agrave -24
+KPX D Aring -24
+KPX D Atilde -24
+KPX D J 8
+KPX D T -3
+KPX D V -20
+KPX D W -13
+KPX D X -22
+KPX D Y -31
+KPX F A -43
+KPX F Aacute -43
+KPX F Acircumflex -43
+KPX F Adieresis -43
+KPX F Agrave -43
+KPX F Aring -43
+KPX F Atilde -43
+KPX F J -14
+KPX F O -10
+KPX F Odieresis -10
+KPX F a -15
+KPX F aacute -15
+KPX F adieresis -15
+KPX F ae -16
+KPX F aring -15
+KPX F comma -71
+KPX F e -6
+KPX F eacute -6
+KPX F hyphen 8
+KPX F i -6
+KPX F j -6
+KPX F o -11
+KPX F oacute -11
+KPX F odieresis -11
+KPX F oe -11
+KPX F oslash -11
+KPX F period -71
+KPX F r -22
+KPX F u -23
+KPX G A 1
+KPX G AE 7
+KPX G Aacute 1
+KPX G Acircumflex 1
+KPX G Adieresis 1
+KPX G Agrave 1
+KPX G Aring 1
+KPX G Atilde 1
+KPX G T -7
+KPX G V -24
+KPX G W -15
+KPX G Y -35
+KPX J A -21
+KPX J AE -15
+KPX J Adieresis -21
+KPX J Aring -21
+KPX K C -35
+KPX K G -36
+KPX K O -36
+KPX K OE -30
+KPX K Oacute -36
+KPX K Odieresis -36
+KPX K S -18
+KPX K T 23
+KPX K a 0
+KPX K adieresis 0
+KPX K ae -1
+KPX K aring 0
+KPX K e -17
+KPX K hyphen -26
+KPX K o -25
+KPX K oacute -25
+KPX K odieresis -25
+KPX K u -19
+KPX K udieresis -19
+KPX K y -48
+KPX L A 16
+KPX L AE 22
+KPX L Aacute 16
+KPX L Adieresis 16
+KPX L Aring 16
+KPX L C -13
+KPX L Ccedilla -16
+KPX L G -15
+KPX L O -16
+KPX L Oacute -16
+KPX L Ocircumflex -16
+KPX L Odieresis -16
+KPX L Ograve -16
+KPX L Otilde -16
+KPX L S 3
+KPX L T -70
+KPX L U -12
+KPX L Udieresis -12
+KPX L V -64
+KPX L W -50
+KPX L Y -83
+KPX L hyphen -8
+KPX L quotedblright -116
+KPX L quoteright -118
+KPX L u -7
+KPX L udieresis -7
+KPX L y -41
+KPX N A 0
+KPX N AE 6
+KPX N Aacute 0
+KPX N Adieresis 0
+KPX N Aring 0
+KPX N C 6
+KPX N Ccedilla 6
+KPX N G 5
+KPX N O 6
+KPX N Oacute 6
+KPX N Odieresis 6
+KPX N a 7
+KPX N aacute 7
+KPX N adieresis 7
+KPX N ae 6
+KPX N aring 7
+KPX N comma 12
+KPX N e 12
+KPX N eacute 12
+KPX N o 5
+KPX N oacute 5
+KPX N odieresis 5
+KPX N oslash 7
+KPX N period 12
+KPX N u 5
+KPX N udieresis 5
+KPX O A -27
+KPX O AE -22
+KPX O Aacute -27
+KPX O Adieresis -27
+KPX O Aring -27
+KPX O T -9
+KPX O V -26
+KPX O W -17
+KPX O X -26
+KPX O Y -38
+KPX Oacute A -27
+KPX Oacute T -9
+KPX Oacute V -26
+KPX Oacute W -17
+KPX Oacute Y -38
+KPX Ocircumflex T -9
+KPX Ocircumflex V -26
+KPX Ocircumflex Y -38
+KPX Odieresis A -27
+KPX Odieresis T -9
+KPX Odieresis V -26
+KPX Odieresis W -17
+KPX Odieresis X -26
+KPX Odieresis Y -38
+KPX Ograve T -9
+KPX Ograve V -26
+KPX Ograve Y -38
+KPX Oslash A -24
+KPX Otilde T -9
+KPX Otilde V -26
+KPX Otilde Y -38
+KPX P A -51
+KPX P AE -47
+KPX P Aacute -51
+KPX P Adieresis -51
+KPX P Aring -51
+KPX P J -36
+KPX P a -12
+KPX P aacute -12
+KPX P adieresis -12
+KPX P ae -13
+KPX P aring -12
+KPX P comma -92
+KPX P e -10
+KPX P eacute -10
+KPX P hyphen -3
+KPX P o -16
+KPX P oacute -16
+KPX P odieresis -16
+KPX P oe -16
+KPX P oslash -16
+KPX P period -92
+KPX R C -2
+KPX R Ccedilla -2
+KPX R G -3
+KPX R O -3
+KPX R OE 1
+KPX R Oacute -3
+KPX R Odieresis -3
+KPX R T 3
+KPX R U -1
+KPX R Udieresis -1
+KPX R V -16
+KPX R W -12
+KPX R Y -24
+KPX R a 0
+KPX R aacute 0
+KPX R adieresis 0
+KPX R ae -1
+KPX R aring 0
+KPX R e 2
+KPX R eacute 2
+KPX R hyphen 14
+KPX R o -4
+KPX R oacute -4
+KPX R odieresis -4
+KPX R oe -4
+KPX R u -1
+KPX R uacute -2
+KPX R udieresis -2
+KPX R y 3
+KPX S A -10
+KPX S AE -5
+KPX S Aacute -10
+KPX S Adieresis -10
+KPX S Aring -10
+KPX S T 0
+KPX S V -20
+KPX S W -15
+KPX S Y -27
+KPX S t 2
+KPX T A -63
+KPX T AE -59
+KPX T Aacute -63
+KPX T Acircumflex -63
+KPX T Adieresis -63
+KPX T Agrave -63
+KPX T Aring -63
+KPX T Atilde -63
+KPX T C -8
+KPX T G -10
+KPX T J -67
+KPX T O -9
+KPX T OE -3
+KPX T Oacute -9
+KPX T Ocircumflex -9
+KPX T Odieresis -9
+KPX T Ograve -9
+KPX T Oslash -9
+KPX T Otilde -9
+KPX T S 6
+KPX T V 22
+KPX T W 23
+KPX T Y 23
+KPX T a -62
+KPX T ae -63
+KPX T c -62
+KPX T colon -73
+KPX T comma -55
+KPX T e -58
+KPX T g -65
+KPX T guillemotleft -84
+KPX T guilsinglleft -82
+KPX T hyphen -40
+KPX T i -2
+KPX T j -2
+KPX T o -65
+KPX T oslash -61
+KPX T period -55
+KPX T r -59
+KPX T s -63
+KPX T semicolon -73
+KPX T u -63
+KPX T v -68
+KPX T w -67
+KPX T y -67
+KPX U A -24
+KPX U AE -20
+KPX U Aacute -24
+KPX U Acircumflex -24
+KPX U Adieresis -24
+KPX U Aring -24
+KPX U Atilde -24
+KPX U comma -6
+KPX U m 4
+KPX U n 3
+KPX U p 4
+KPX U period -3
+KPX U r 4
+KPX Uacute A -24
+KPX Uacute comma -6
+KPX Uacute m 4
+KPX Uacute n 3
+KPX Uacute p 4
+KPX Uacute period -3
+KPX Uacute r 4
+KPX Ucircumflex A -24
+KPX Udieresis A -24
+KPX Udieresis b 4
+KPX Udieresis comma -6
+KPX Udieresis m 4
+KPX Udieresis n 3
+KPX Udieresis p 4
+KPX Udieresis period -3
+KPX Udieresis r 4
+KPX Ugrave A -24
+KPX V A -51
+KPX V AE -46
+KPX V Aacute -51
+KPX V Acircumflex -51
+KPX V Adieresis -51
+KPX V Agrave -51
+KPX V Aring -51
+KPX V Atilde -51
+KPX V C -25
+KPX V G -26
+KPX V O -26
+KPX V Oacute -26
+KPX V Ocircumflex -26
+KPX V Odieresis -26
+KPX V Ograve -26
+KPX V Oslash -22
+KPX V Otilde -26
+KPX V S -13
+KPX V T 22
+KPX V a -38
+KPX V ae -39
+KPX V colon -38
+KPX V comma -52
+KPX V e -34
+KPX V g -40
+KPX V guillemotleft -59
+KPX V guilsinglleft -57
+KPX V hyphen -14
+KPX V i -4
+KPX V o -41
+KPX V oslash -37
+KPX V period -52
+KPX V r -27
+KPX V semicolon -38
+KPX V u -31
+KPX V y -7
+KPX W A -40
+KPX W AE -36
+KPX W Aacute -40
+KPX W Acircumflex -40
+KPX W Adieresis -40
+KPX W Agrave -40
+KPX W Aring -40
+KPX W Atilde -40
+KPX W C -15
+KPX W G -16
+KPX W O -16
+KPX W Oacute -16
+KPX W Ocircumflex -16
+KPX W Odieresis -16
+KPX W Ograve -16
+KPX W Oslash -12
+KPX W Otilde -16
+KPX W S -8
+KPX W T 24
+KPX W a -26
+KPX W ae -27
+KPX W colon -31
+KPX W comma -36
+KPX W e -21
+KPX W g -28
+KPX W guillemotleft -47
+KPX W guilsinglleft -45
+KPX W hyphen -2
+KPX W i -2
+KPX W o -28
+KPX W oslash -25
+KPX W period -36
+KPX W r -21
+KPX W semicolon -31
+KPX W u -24
+KPX W y -1
+KPX X C -26
+KPX X O -27
+KPX X Odieresis -27
+KPX X Q -27
+KPX X a -5
+KPX X e -20
+KPX X hyphen -21
+KPX X o -27
+KPX X u -24
+KPX X y -35
+KPX Y A -67
+KPX Y AE -62
+KPX Y Aacute -67
+KPX Y Acircumflex -67
+KPX Y Adieresis -67
+KPX Y Agrave -67
+KPX Y Aring -67
+KPX Y Atilde -67
+KPX Y C -36
+KPX Y G -38
+KPX Y O -37
+KPX Y Oacute -37
+KPX Y Ocircumflex -37
+KPX Y Odieresis -37
+KPX Y Ograve -37
+KPX Y Oslash -37
+KPX Y Otilde -37
+KPX Y S -19
+KPX Y T 24
+KPX Y a -58
+KPX Y ae -59
+KPX Y colon -52
+KPX Y comma -65
+KPX Y e -54
+KPX Y g -61
+KPX Y guillemotleft -83
+KPX Y guilsinglleft -81
+KPX Y hyphen -42
+KPX Y i -2
+KPX Y o -61
+KPX Y oslash -57
+KPX Y p -39
+KPX Y period -65
+KPX Y semicolon -52
+KPX Y u -45
+KPX Y v -22
+KPX Z v -9
+KPX Z y -8
+KPX a j 0
+KPX a quoteright -7
+KPX a v -15
+KPX a w -5
+KPX a y -13
+KPX aacute v -15
+KPX aacute w -5
+KPX aacute y -13
+KPX adieresis v -15
+KPX adieresis w -5
+KPX adieresis y -13
+KPX ae v -16
+KPX ae w -6
+KPX ae y -15
+KPX agrave v -15
+KPX agrave w -5
+KPX agrave y -13
+KPX aring v -15
+KPX aring w -5
+KPX aring y -13
+KPX b v -15
+KPX b w -5
+KPX b y -14
+KPX c h 0
+KPX c k -2
+KPX comma one -59
+KPX comma quotedblright -18
+KPX comma quoteright -20
+KPX e quoteright -8
+KPX e t -2
+KPX e v -15
+KPX e w -6
+KPX e x -16
+KPX e y -14
+KPX eacute v -15
+KPX eacute w -6
+KPX eacute y -14
+KPX ecircumflex v -15
+KPX ecircumflex w -6
+KPX ecircumflex y -14
+KPX eight four 12
+KPX eight one -15
+KPX eight seven 0
+KPX f a -4
+KPX f aacute -4
+KPX f adieresis -4
+KPX f ae -6
+KPX f aring -4
+KPX f e -5
+KPX f eacute -5
+KPX f f 17
+KPX f i -3
+KPX f j -7
+KPX f l -3
+KPX f o -12
+KPX f oacute -12
+KPX f odieresis -12
+KPX f oe -12
+KPX f oslash -9
+KPX f quoteright 11
+KPX f s -5
+KPX f t 17
+KPX five four 8
+KPX five one -20
+KPX five seven -2
+KPX four four 12
+KPX four one -37
+KPX four seven -19
+KPX g a 5
+KPX g adieresis 5
+KPX g ae 4
+KPX g aring 5
+KPX g e 10
+KPX g eacute 10
+KPX g l 3
+KPX g oacute 4
+KPX g odieresis 4
+KPX g r 6
+KPX guillemotright A -36
+KPX guillemotright AE -31
+KPX guillemotright Aacute -36
+KPX guillemotright Adieresis -36
+KPX guillemotright Aring -36
+KPX guillemotright T -84
+KPX guillemotright V -59
+KPX guillemotright W -48
+KPX guillemotright Y -86
+KPX guilsinglright A -33
+KPX guilsinglright AE -28
+KPX guilsinglright Aacute -33
+KPX guilsinglright Adieresis -33
+KPX guilsinglright Aring -33
+KPX guilsinglright T -82
+KPX guilsinglright V -57
+KPX guilsinglright W -45
+KPX guilsinglright Y -84
+KPX h quoteright -7
+KPX h y -14
+KPX hyphen A 6
+KPX hyphen AE 12
+KPX hyphen Aacute 6
+KPX hyphen Adieresis 6
+KPX hyphen Aring 6
+KPX hyphen T -40
+KPX hyphen V -14
+KPX hyphen W -3
+KPX hyphen Y -45
+KPX i T -2
+KPX i j -1
+KPX k a 0
+KPX k aacute 0
+KPX k adieresis 0
+KPX k ae 0
+KPX k aring 0
+KPX k comma 15
+KPX k e -6
+KPX k eacute -6
+KPX k g -14
+KPX k hyphen -10
+KPX k o -13
+KPX k oacute -13
+KPX k odieresis -13
+KPX k period 15
+KPX k s -8
+KPX k u -4
+KPX k udieresis 0
+KPX l v -7
+KPX l y -5
+KPX m p 3
+KPX m v -16
+KPX m w -7
+KPX m y -14
+KPX n T -63
+KPX n p 3
+KPX n quoteright -7
+KPX n v -16
+KPX n w -7
+KPX n y -14
+KPX nine four 10
+KPX nine one -11
+KPX nine seven -4
+KPX o T -64
+KPX o quoteright -13
+KPX o t -5
+KPX o v -18
+KPX o w -8
+KPX o x -20
+KPX o y -17
+KPX oacute v -18
+KPX oacute w -8
+KPX oacute y -17
+KPX ocircumflex t -5
+KPX odieresis t -5
+KPX odieresis v -18
+KPX odieresis w -8
+KPX odieresis x -20
+KPX odieresis y -17
+KPX ograve v -18
+KPX ograve w -8
+KPX ograve y -17
+KPX one comma -32
+KPX one eight -32
+KPX one five -33
+KPX one four -47
+KPX one nine -32
+KPX one one -65
+KPX one period -32
+KPX one seven -47
+KPX one six -28
+KPX one three -36
+KPX one two -37
+KPX one zero -28
+KPX p t -1
+KPX p y -14
+KPX period one -59
+KPX period quotedblright -18
+KPX period quoteright -20
+KPX q c 6
+KPX q u 4
+KPX quotedblbase A 16
+KPX quotedblbase AE 21
+KPX quotedblbase T -56
+KPX quotedblbase V -53
+KPX quotedblbase W -38
+KPX quotedblbase Y -69
+KPX quotedblleft A -49
+KPX quotedblleft AE -45
+KPX quotedblleft Aacute -49
+KPX quotedblleft Adieresis -49
+KPX quotedblleft Aring -49
+KPX quotedblleft T 3
+KPX quotedblleft V 10
+KPX quotedblleft W 15
+KPX quotedblleft Y 2
+KPX quotedblright A -52
+KPX quotedblright AE -48
+KPX quotedblright Aacute -52
+KPX quotedblright Adieresis -52
+KPX quotedblright Aring -52
+KPX quotedblright T 4
+KPX quotedblright V 7
+KPX quotedblright W 12
+KPX quotedblright Y 0
+KPX quoteleft A -51
+KPX quoteleft AE -47
+KPX quoteleft Aacute -51
+KPX quoteleft Adieresis -51
+KPX quoteleft Aring -51
+KPX quoteleft T 1
+KPX quoteleft V 7
+KPX quoteleft W 12
+KPX quoteleft Y 0
+KPX quoteright A -55
+KPX quoteright AE -51
+KPX quoteright Aacute -55
+KPX quoteright Adieresis -55
+KPX quoteright Aring -55
+KPX quoteright comma -31
+KPX quoteright d -18
+KPX quoteright o -24
+KPX quoteright period -31
+KPX quoteright r -7
+KPX quoteright s -15
+KPX quoteright t 4
+KPX quoteright v 0
+KPX quoteright w 5
+KPX quoteright y 2
+KPX r a -1
+KPX r aacute -1
+KPX r acircumflex -1
+KPX r adieresis -1
+KPX r ae -2
+KPX r agrave -1
+KPX r aring -1
+KPX r c -4
+KPX r ccedilla -1
+KPX r colon -12
+KPX r comma -42
+KPX r d -2
+KPX r e 0
+KPX r eacute 0
+KPX r ecircumflex 0
+KPX r egrave 0
+KPX r f 17
+KPX r g -2
+KPX r h -5
+KPX r hyphen -25
+KPX r i -7
+KPX r j -7
+KPX r k -7
+KPX r l -7
+KPX r m -5
+KPX r n -5
+KPX r o -6
+KPX r oacute -6
+KPX r ocircumflex -6
+KPX r odieresis -6
+KPX r oe -6
+KPX r ograve -6
+KPX r oslash -6
+KPX r p -4
+KPX r period -42
+KPX r q -3
+KPX r quoteright 13
+KPX r r -5
+KPX r s -1
+KPX r semicolon -12
+KPX r t 17
+KPX r u -6
+KPX r v 15
+KPX r w 16
+KPX r x 10
+KPX r y 16
+KPX r z 5
+KPX s quoteright -11
+KPX s t -5
+KPX seven colon -40
+KPX seven comma -71
+KPX seven eight -2
+KPX seven five -9
+KPX seven four -53
+KPX seven one -4
+KPX seven period -71
+KPX seven seven 14
+KPX seven six -6
+KPX seven three 1
+KPX seven two 1
+KPX six four 10
+KPX six one -13
+KPX six seven 1
+KPX t S 1
+KPX t a 4
+KPX t aacute 4
+KPX t adieresis 4
+KPX t ae 4
+KPX t aring 4
+KPX t colon -5
+KPX t e -1
+KPX t eacute -1
+KPX t h 5
+KPX t o -8
+KPX t oacute -8
+KPX t odieresis -8
+KPX t quoteright 7
+KPX t semicolon -4
+KPX three four 8
+KPX three one -18
+KPX three seven -3
+KPX two four -11
+KPX two one -11
+KPX two seven 0
+KPX u quoteright 1
+KPX v a -17
+KPX v aacute -17
+KPX v acircumflex -17
+KPX v adieresis -17
+KPX v ae -18
+KPX v agrave -17
+KPX v aring -17
+KPX v atilde -17
+KPX v c -16
+KPX v colon -13
+KPX v comma -35
+KPX v e -12
+KPX v eacute -12
+KPX v ecircumflex -12
+KPX v egrave -12
+KPX v g -18
+KPX v hyphen 5
+KPX v l -7
+KPX v o -19
+KPX v oacute -19
+KPX v odieresis -19
+KPX v ograve -19
+KPX v oslash -16
+KPX v period -35
+KPX v s -17
+KPX v semicolon -13
+KPX w a -7
+KPX w aacute -7
+KPX w acircumflex -7
+KPX w adieresis -7
+KPX w ae -8
+KPX w agrave -7
+KPX w aring -7
+KPX w atilde -7
+KPX w c -6
+KPX w colon -10
+KPX w comma -20
+KPX w e -2
+KPX w eacute -2
+KPX w ecircumflex -2
+KPX w egrave -2
+KPX w g -8
+KPX w hyphen 14
+KPX w l -3
+KPX w o -9
+KPX w oacute -9
+KPX w odieresis -9
+KPX w ograve -9
+KPX w oslash -6
+KPX w period -20
+KPX w s -8
+KPX w semicolon -10
+KPX x a -10
+KPX x c -17
+KPX x e -13
+KPX x eacute -13
+KPX x o -20
+KPX x q -17
+KPX y a -18
+KPX y aacute -18
+KPX y acircumflex -18
+KPX y adieresis -18
+KPX y ae -19
+KPX y agrave -18
+KPX y aring -18
+KPX y atilde -18
+KPX y c -18
+KPX y colon -14
+KPX y comma -36
+KPX y e -14
+KPX y eacute -14
+KPX y ecircumflex -14
+KPX y egrave -14
+KPX y g -20
+KPX y hyphen 4
+KPX y l -8
+KPX y o -20
+KPX y oacute -20
+KPX y odieresis -20
+KPX y ograve -20
+KPX y oslash -17
+KPX y period -35
+KPX y s -19
+KPX y semicolon -14
+KPX zero four 11
+KPX zero one -10
+KPX zero seven -1
+EndKernPairs
+EndKernData
+EndFontMetrics
diff --git a/misc/gs_afm/HelvBoO.afm b/misc/gs_afm/HelvBoO.afm
new file mode 100644
index 0000000000..37efe8a3b8
--- /dev/null
+++ b/misc/gs_afm/HelvBoO.afm
@@ -0,0 +1,1257 @@
+StartFontMetrics 3.0
+Comment Copyright URW Software, Copyright 1994 by URW
+Comment Creation Date: 8/3/1994
+Comment See the file PUBLIC (Aladdin Free Public License) for license conditions.
+FontName NimbusSanL-BoldCondItal
+FullName Nimbus Sans L Bold Condensed Italic
+FamilyName Nimbus Sans L
+Weight Bold
+ItalicAngle -9.0
+IsFixedPitch false
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.005
+Notice URW Software, Copyright 1994 by URW
+EncodingScheme AdobeStandardEncoding
+FontBBox -143 -228 913 989
+CapHeight 718
+XHeight 532
+Descender -207
+Ascender 718
+StartCharMetrics 232
+C 32 ; WX 228 ; N space ; B 21 0 21 0 ;
+C 33 ; WX 273 ; N exclam ; B 77 0 325 718 ;
+C 34 ; WX 389 ; N quotedbl ; B 158 447 433 718 ;
+C 35 ; WX 456 ; N numbersign ; B 49 0 528 698 ;
+C 36 ; WX 456 ; N dollar ; B 55 -115 510 775 ;
+C 37 ; WX 729 ; N percent ; B 112 -19 739 710 ;
+C 38 ; WX 592 ; N ampersand ; B 73 -19 600 718 ;
+C 39 ; WX 228 ; N quoteright ; B 137 445 297 718 ;
+C 40 ; WX 273 ; N parenleft ; B 62 -207 385 734 ;
+C 41 ; WX 273 ; N parenright ; B -21 -207 302 734 ;
+C 42 ; WX 319 ; N asterisk ; B 120 387 394 718 ;
+C 43 ; WX 479 ; N plus ; B 67 0 500 506 ;
+C 44 ; WX 228 ; N comma ; B 23 -168 201 146 ;
+C 45 ; WX 273 ; N hyphen ; B 60 215 311 345 ;
+C 46 ; WX 228 ; N period ; B 52 0 201 146 ;
+C 47 ; WX 228 ; N slash ; B -30 -19 383 737 ;
+C 48 ; WX 456 ; N zero ; B 71 -19 506 710 ;
+C 49 ; WX 456 ; N one ; B 142 0 434 710 ;
+C 50 ; WX 456 ; N two ; B 21 0 508 710 ;
+C 51 ; WX 456 ; N three ; B 54 -19 499 710 ;
+C 52 ; WX 456 ; N four ; B 50 0 490 710 ;
+C 53 ; WX 456 ; N five ; B 53 -19 522 698 ;
+C 54 ; WX 456 ; N six ; B 70 -19 507 710 ;
+C 55 ; WX 456 ; N seven ; B 102 0 555 698 ;
+C 56 ; WX 456 ; N eight ; B 57 -19 505 710 ;
+C 57 ; WX 456 ; N nine ; B 64 -19 504 710 ;
+C 58 ; WX 273 ; N colon ; B 75 0 288 512 ;
+C 59 ; WX 273 ; N semicolon ; B 46 -168 288 512 ;
+C 60 ; WX 479 ; N less ; B 67 -15 537 521 ;
+C 61 ; WX 479 ; N equal ; B 48 87 519 419 ;
+C 62 ; WX 479 ; N greater ; B 30 -15 500 521 ;
+C 63 ; WX 501 ; N question ; B 135 0 550 727 ;
+C 64 ; WX 800 ; N at ; B 152 -19 782 737 ;
+C 65 ; WX 592 ; N A ; B 16 0 576 718 ;
+C 66 ; WX 592 ; N B ; B 62 0 626 718 ;
+C 67 ; WX 592 ; N C ; B 88 -19 647 737 ;
+C 68 ; WX 592 ; N D ; B 62 0 637 718 ;
+C 69 ; WX 547 ; N E ; B 62 0 620 718 ;
+C 70 ; WX 501 ; N F ; B 62 0 606 718 ;
+C 71 ; WX 638 ; N G ; B 89 -19 670 737 ;
+C 72 ; WX 592 ; N H ; B 58 0 659 718 ;
+C 73 ; WX 228 ; N I ; B 52 0 301 718 ;
+C 74 ; WX 456 ; N J ; B 49 -18 522 718 ;
+C 75 ; WX 592 ; N K ; B 71 0 703 718 ;
+C 76 ; WX 501 ; N L ; B 62 0 501 718 ;
+C 77 ; WX 683 ; N M ; B 57 0 752 718 ;
+C 78 ; WX 592 ; N N ; B 57 0 661 718 ;
+C 79 ; WX 638 ; N O ; B 88 -19 675 737 ;
+C 80 ; WX 547 ; N P ; B 62 0 605 718 ;
+C 81 ; WX 638 ; N Q ; B 88 -52 675 737 ;
+C 82 ; WX 592 ; N R ; B 62 0 638 718 ;
+C 83 ; WX 547 ; N S ; B 66 -19 588 737 ;
+C 84 ; WX 501 ; N T ; B 114 0 615 718 ;
+C 85 ; WX 592 ; N U ; B 96 -19 659 718 ;
+C 86 ; WX 547 ; N V ; B 141 0 656 718 ;
+C 87 ; WX 774 ; N W ; B 138 0 887 718 ;
+C 88 ; WX 547 ; N X ; B 11 0 648 718 ;
+C 89 ; WX 547 ; N Y ; B 137 0 661 718 ;
+C 90 ; WX 501 ; N Z ; B 20 0 604 718 ;
+C 91 ; WX 273 ; N bracketleft ; B 17 -196 379 722 ;
+C 92 ; WX 228 ; N backslash ; B 101 -19 252 737 ;
+C 93 ; WX 273 ; N bracketright ; B -14 -196 347 722 ;
+C 94 ; WX 479 ; N asciicircum ; B 107 323 484 698 ;
+C 95 ; WX 456 ; N underscore ; B -22 -125 443 -75 ;
+C 96 ; WX 228 ; N quoteleft ; B 136 454 296 727 ;
+C 97 ; WX 456 ; N a ; B 45 -14 478 546 ;
+C 98 ; WX 501 ; N b ; B 50 -14 529 718 ;
+C 99 ; WX 456 ; N c ; B 65 -14 491 546 ;
+C 100 ; WX 501 ; N d ; B 67 -14 577 718 ;
+C 101 ; WX 456 ; N e ; B 58 -14 486 546 ;
+C 102 ; WX 273 ; N f ; B 71 0 385 727 ;
+C 103 ; WX 501 ; N g ; B 31 -217 546 546 ;
+C 104 ; WX 501 ; N h ; B 53 0 516 718 ;
+C 105 ; WX 228 ; N i ; B 57 0 298 725 ;
+C 106 ; WX 228 ; N j ; B -35 -214 298 725 ;
+C 107 ; WX 456 ; N k ; B 57 0 549 718 ;
+C 108 ; WX 228 ; N l ; B 57 0 297 718 ;
+C 109 ; WX 729 ; N m ; B 52 0 746 546 ;
+C 110 ; WX 501 ; N n ; B 53 0 516 546 ;
+C 111 ; WX 501 ; N o ; B 67 -14 527 546 ;
+C 112 ; WX 501 ; N p ; B 15 -207 529 546 ;
+C 113 ; WX 501 ; N q ; B 66 -207 545 546 ;
+C 114 ; WX 319 ; N r ; B 52 0 401 546 ;
+C 115 ; WX 456 ; N s ; B 52 -14 479 546 ;
+C 116 ; WX 273 ; N t ; B 82 -6 346 676 ;
+C 117 ; WX 501 ; N u ; B 80 -14 540 532 ;
+C 118 ; WX 456 ; N v ; B 103 0 538 532 ;
+C 119 ; WX 638 ; N w ; B 101 0 723 532 ;
+C 120 ; WX 456 ; N x ; B 12 0 531 532 ;
+C 121 ; WX 456 ; N y ; B 34 -214 535 532 ;
+C 122 ; WX 410 ; N z ; B 16 0 478 532 ;
+C 123 ; WX 319 ; N braceleft ; B 77 -196 425 722 ;
+C 124 ; WX 230 ; N bar ; B 66 -19 289 737 ;
+C 125 ; WX 319 ; N braceright ; B -14 -196 333 722 ;
+C 126 ; WX 479 ; N asciitilde ; B 94 173 473 336 ;
+C 161 ; WX 273 ; N exclamdown ; B 41 -186 290 532 ;
+C 162 ; WX 456 ; N cent ; B 65 -118 491 628 ;
+C 163 ; WX 456 ; N sterling ; B 41 -16 520 718 ;
+C 164 ; WX 137 ; N fraction ; B -143 -19 399 710 ;
+C 165 ; WX 456 ; N yen ; B 49 0 585 698 ;
+C 166 ; WX 456 ; N florin ; B -41 -210 548 737 ;
+C 167 ; WX 456 ; N section ; B 50 -184 491 727 ;
+C 168 ; WX 456 ; N currency ; B 22 76 558 636 ;
+C 169 ; WX 195 ; N quotesingle ; B 135 447 263 718 ;
+C 170 ; WX 410 ; N quotedblleft ; B 132 454 482 727 ;
+C 171 ; WX 456 ; N guillemotleft ; B 111 76 468 484 ;
+C 172 ; WX 273 ; N guilsinglleft ; B 106 76 289 484 ;
+C 173 ; WX 273 ; N guilsinglright ; B 81 76 264 484 ;
+C 174 ; WX 501 ; N fi ; B 71 0 571 727 ;
+C 175 ; WX 501 ; N fl ; B 71 0 570 727 ;
+C 177 ; WX 456 ; N endash ; B 40 227 514 333 ;
+C 178 ; WX 456 ; N dagger ; B 97 -171 513 718 ;
+C 179 ; WX 456 ; N daggerdbl ; B 38 -171 515 718 ;
+C 180 ; WX 228 ; N periodcentered ; B 90 172 226 334 ;
+C 182 ; WX 456 ; N paragraph ; B 80 -191 564 700 ;
+C 183 ; WX 287 ; N bullet ; B 68 194 345 524 ;
+C 184 ; WX 228 ; N quotesinglbase ; B 34 -146 194 127 ;
+C 185 ; WX 410 ; N quotedblbase ; B 29 -146 380 127 ;
+C 186 ; WX 410 ; N quotedblright ; B 132 445 483 718 ;
+C 187 ; WX 456 ; N guillemotright ; B 85 76 443 484 ;
+C 188 ; WX 820 ; N ellipsis ; B 75 0 770 146 ;
+C 189 ; WX 820 ; N perthousand ; B 62 -19 851 710 ;
+C 191 ; WX 501 ; N questiondown ; B 44 -195 459 532 ;
+C 193 ; WX 273 ; N grave ; B 112 604 290 750 ;
+C 194 ; WX 273 ; N acute ; B 194 604 423 750 ;
+C 195 ; WX 273 ; N circumflex ; B 97 604 387 750 ;
+C 196 ; WX 273 ; N tilde ; B 92 610 415 737 ;
+C 197 ; WX 273 ; N macron ; B 100 604 396 678 ;
+C 198 ; WX 273 ; N breve ; B 128 604 405 750 ;
+C 199 ; WX 273 ; N dotaccent ; B 192 614 316 729 ;
+C 200 ; WX 273 ; N dieresis ; B 112 614 395 729 ;
+C 202 ; WX 273 ; N ring ; B 164 568 344 776 ;
+C 203 ; WX 273 ; N cedilla ; B -30 -228 180 0 ;
+C 205 ; WX 273 ; N hungarumlaut ; B 113 604 529 750 ;
+C 206 ; WX 273 ; N ogonek ; B 33 -228 216 0 ;
+C 207 ; WX 273 ; N caron ; B 123 604 412 750 ;
+C 208 ; WX 820 ; N emdash ; B 40 227 878 333 ;
+C 225 ; WX 820 ; N AE ; B 4 0 902 718 ;
+C 227 ; WX 303 ; N ordfeminine ; B 75 276 381 737 ;
+C 232 ; WX 501 ; N Lslash ; B 28 0 501 718 ;
+C 233 ; WX 638 ; N Oslash ; B 29 -27 733 745 ;
+C 234 ; WX 820 ; N OE ; B 81 -19 913 737 ;
+C 235 ; WX 299 ; N ordmasculine ; B 75 276 398 737 ;
+C 241 ; WX 729 ; N ae ; B 46 -14 757 546 ;
+C 245 ; WX 228 ; N dotlessi ; B 57 0 264 532 ;
+C 248 ; WX 228 ; N lslash ; B 33 0 334 718 ;
+C 249 ; WX 501 ; N oslash ; B 18 -29 575 560 ;
+C 250 ; WX 774 ; N oe ; B 67 -14 801 546 ;
+C 251 ; WX 501 ; N germandbls ; B 57 -14 539 731 ;
+C -1 ; WX 547 ; N Yacute ; B 137 0 661 936 ;
+C -1 ; WX 592 ; N Ucircumflex ; B 96 -19 659 936 ;
+C -1 ; WX 592 ; N Ugrave ; B 96 -19 659 936 ;
+C -1 ; WX 501 ; N Zcaron ; B 20 0 604 936 ;
+C -1 ; WX 547 ; N Ydieresis ; B 137 0 661 915 ;
+C -1 ; WX 273 ; N threesuperior ; B 75 271 361 722 ;
+C -1 ; WX 592 ; N Uacute ; B 96 -19 659 936 ;
+C -1 ; WX 273 ; N twosuperior ; B 57 283 368 722 ;
+C -1 ; WX 592 ; N Udieresis ; B 96 -19 659 915 ;
+C -1 ; WX 228 ; N middot ; B 90 172 226 334 ;
+C -1 ; WX 273 ; N onesuperior ; B 121 283 318 710 ;
+C -1 ; WX 456 ; N aacute ; B 45 -14 514 750 ;
+C -1 ; WX 456 ; N agrave ; B 45 -14 478 750 ;
+C -1 ; WX 456 ; N acircumflex ; B 45 -14 478 750 ;
+C -1 ; WX 547 ; N Scaron ; B 66 -19 588 936 ;
+C -1 ; WX 638 ; N Otilde ; B 88 -19 675 923 ;
+C -1 ; WX 273 ; N sfthyphen ; B 60 215 311 345 ;
+C -1 ; WX 456 ; N atilde ; B 45 -14 507 737 ;
+C -1 ; WX 456 ; N aring ; B 45 -14 478 803 ;
+C -1 ; WX 456 ; N adieresis ; B 45 -14 487 729 ;
+C -1 ; WX 638 ; N Ograve ; B 88 -19 675 936 ;
+C -1 ; WX 638 ; N Ocircumflex ; B 88 -19 675 936 ;
+C -1 ; WX 638 ; N Odieresis ; B 88 -19 675 915 ;
+C -1 ; WX 592 ; N Ntilde ; B 57 0 661 923 ;
+C -1 ; WX 456 ; N edieresis ; B 58 -14 488 729 ;
+C -1 ; WX 456 ; N eacute ; B 58 -14 515 750 ;
+C -1 ; WX 456 ; N egrave ; B 58 -14 486 750 ;
+C -1 ; WX 228 ; N Icircumflex ; B 52 0 397 936 ;
+C -1 ; WX 456 ; N ecircumflex ; B 58 -14 486 750 ;
+C -1 ; WX 228 ; N Igrave ; B 52 0 301 936 ;
+C -1 ; WX 228 ; N Iacute ; B 52 0 433 936 ;
+C -1 ; WX 228 ; N Idieresis ; B 52 0 405 915 ;
+C -1 ; WX 328 ; N degree ; B 143 426 383 712 ;
+C -1 ; WX 547 ; N Ecircumflex ; B 62 0 620 936 ;
+C -1 ; WX 479 ; N minus ; B 67 197 500 309 ;
+C -1 ; WX 479 ; N multiply ; B 47 1 520 505 ;
+C -1 ; WX 479 ; N divide ; B 67 -42 500 548 ;
+C -1 ; WX 547 ; N Egrave ; B 62 0 620 936 ;
+C -1 ; WX 820 ; N trademark ; B 146 306 909 718 ;
+C -1 ; WX 638 ; N Oacute ; B 88 -19 675 936 ;
+C -1 ; WX 501 ; N thorn ; B 15 -207 529 718 ;
+C -1 ; WX 501 ; N eth ; B 67 -14 549 737 ;
+C -1 ; WX 547 ; N Eacute ; B 62 0 620 936 ;
+C -1 ; WX 456 ; N ccedilla ; B 65 -228 491 546 ;
+C -1 ; WX 228 ; N idieresis ; B 57 0 373 729 ;
+C -1 ; WX 228 ; N iacute ; B 57 0 401 750 ;
+C -1 ; WX 228 ; N igrave ; B 57 0 268 750 ;
+C -1 ; WX 479 ; N plusminus ; B 33 0 512 578 ;
+C -1 ; WX 684 ; N onehalf ; B 108 -19 704 710 ;
+C -1 ; WX 684 ; N onequarter ; B 108 -19 661 710 ;
+C -1 ; WX 684 ; N threequarters ; B 82 -19 688 722 ;
+C -1 ; WX 228 ; N icircumflex ; B 57 0 365 750 ;
+C -1 ; WX 547 ; N Edieresis ; B 62 0 620 915 ;
+C -1 ; WX 501 ; N ntilde ; B 53 0 529 737 ;
+C -1 ; WX 592 ; N Aring ; B 16 0 576 989 ;
+C -1 ; WX 501 ; N odieresis ; B 67 -14 527 729 ;
+C -1 ; WX 501 ; N oacute ; B 67 -14 537 750 ;
+C -1 ; WX 501 ; N ograve ; B 67 -14 527 750 ;
+C -1 ; WX 501 ; N ocircumflex ; B 67 -14 527 750 ;
+C -1 ; WX 501 ; N otilde ; B 67 -14 529 737 ;
+C -1 ; WX 456 ; N scaron ; B 52 -14 503 750 ;
+C -1 ; WX 501 ; N udieresis ; B 80 -14 540 729 ;
+C -1 ; WX 501 ; N uacute ; B 80 -14 540 750 ;
+C -1 ; WX 501 ; N ugrave ; B 80 -14 540 750 ;
+C -1 ; WX 501 ; N ucircumflex ; B 80 -14 540 750 ;
+C -1 ; WX 456 ; N yacute ; B 34 -214 535 750 ;
+C -1 ; WX 410 ; N zcaron ; B 16 0 480 750 ;
+C -1 ; WX 456 ; N ydieresis ; B 34 -214 535 729 ;
+C -1 ; WX 604 ; N copyright ; B 46 -19 685 737 ;
+C -1 ; WX 604 ; N registered ; B 45 -19 684 737 ;
+C -1 ; WX 592 ; N Atilde ; B 16 0 607 923 ;
+C -1 ; WX 228 ; N nbspace ; B 21 0 21 0 ;
+C -1 ; WX 592 ; N Ccedilla ; B 88 -228 647 737 ;
+C -1 ; WX 592 ; N Acircumflex ; B 16 0 579 936 ;
+C -1 ; WX 592 ; N Agrave ; B 16 0 576 936 ;
+C -1 ; WX 479 ; N logicalnot ; B 86 108 519 419 ;
+C -1 ; WX 592 ; N Aacute ; B 16 0 615 936 ;
+C -1 ; WX 592 ; N Eth ; B 51 0 637 718 ;
+C -1 ; WX 230 ; N brokenbar ; B 66 -19 289 737 ;
+C -1 ; WX 547 ; N Thorn ; B 62 0 588 718 ;
+C -1 ; WX 592 ; N Adieresis ; B 16 0 587 915 ;
+C -1 ; WX 501 ; N mu ; B 18 -207 540 532 ;
+C -1 ; WX 228 ; N .notdef ; B 21 0 21 0 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 998
+KPX A C -30
+KPX A Ccedilla -29
+KPX A G -31
+KPX A O -31
+KPX A Odieresis -31
+KPX A Q -30
+KPX A T -72
+KPX A U -29
+KPX A Uacute -29
+KPX A Ucircumflex -29
+KPX A Udieresis -29
+KPX A Ugrave -29
+KPX A V -56
+KPX A W -46
+KPX A Y -74
+KPX A a -11
+KPX A b -11
+KPX A c -15
+KPX A ccedilla -14
+KPX A comma 9
+KPX A d -14
+KPX A e -11
+KPX A g -19
+KPX A guillemotleft -41
+KPX A guilsinglleft -39
+KPX A hyphen 1
+KPX A o -17
+KPX A period 11
+KPX A q -14
+KPX A quotedblright -54
+KPX A quoteright -56
+KPX A t -16
+KPX A u -16
+KPX A v -34
+KPX A w -24
+KPX A y -32
+KPX Aacute C -31
+KPX Aacute G -32
+KPX Aacute O -32
+KPX Aacute Q -32
+KPX Aacute T -72
+KPX Aacute U -30
+KPX Aacute V -56
+KPX Aacute W -46
+KPX Aacute Y -74
+KPX Aacute a -11
+KPX Aacute b -11
+KPX Aacute c -16
+KPX Aacute comma 9
+KPX Aacute d -15
+KPX Aacute e -12
+KPX Aacute g -19
+KPX Aacute guillemotleft -42
+KPX Aacute guilsinglleft -39
+KPX Aacute hyphen 1
+KPX Aacute o -19
+KPX Aacute period 10
+KPX Aacute q -15
+KPX Aacute quoteright -56
+KPX Aacute t -17
+KPX Aacute u -17
+KPX Aacute v -33
+KPX Aacute w -24
+KPX Aacute y -32
+KPX Acircumflex C -29
+KPX Acircumflex G -30
+KPX Acircumflex O -30
+KPX Acircumflex Q -30
+KPX Acircumflex T -72
+KPX Acircumflex U -29
+KPX Acircumflex V -56
+KPX Acircumflex W -46
+KPX Acircumflex Y -74
+KPX Acircumflex comma 10
+KPX Acircumflex period 11
+KPX Adieresis C -30
+KPX Adieresis G -31
+KPX Adieresis O -31
+KPX Adieresis Q -31
+KPX Adieresis T -72
+KPX Adieresis U -30
+KPX Adieresis V -56
+KPX Adieresis W -46
+KPX Adieresis Y -74
+KPX Adieresis a -11
+KPX Adieresis b -11
+KPX Adieresis c -15
+KPX Adieresis comma 9
+KPX Adieresis d -15
+KPX Adieresis g -19
+KPX Adieresis guillemotleft -42
+KPX Adieresis guilsinglleft -39
+KPX Adieresis hyphen 1
+KPX Adieresis o -18
+KPX Adieresis period 10
+KPX Adieresis q -15
+KPX Adieresis quotedblright -54
+KPX Adieresis quoteright -56
+KPX Adieresis t -16
+KPX Adieresis u -16
+KPX Adieresis v -34
+KPX Adieresis w -24
+KPX Adieresis y -32
+KPX Agrave C -30
+KPX Agrave G -31
+KPX Agrave O -31
+KPX Agrave Q -30
+KPX Agrave T -72
+KPX Agrave U -29
+KPX Agrave V -56
+KPX Agrave W -46
+KPX Agrave Y -74
+KPX Agrave comma 9
+KPX Agrave period 11
+KPX Aring C -30
+KPX Aring G -31
+KPX Aring O -31
+KPX Aring Q -30
+KPX Aring T -72
+KPX Aring U -29
+KPX Aring V -56
+KPX Aring W -46
+KPX Aring Y -74
+KPX Aring a -11
+KPX Aring b -11
+KPX Aring c -15
+KPX Aring comma 9
+KPX Aring d -14
+KPX Aring e -11
+KPX Aring g -19
+KPX Aring guillemotleft -41
+KPX Aring guilsinglleft -39
+KPX Aring hyphen 1
+KPX Aring o -17
+KPX Aring period 11
+KPX Aring q -14
+KPX Aring quotedblright -54
+KPX Aring quoteright -56
+KPX Aring t -16
+KPX Aring u -16
+KPX Aring v -34
+KPX Aring w -24
+KPX Aring y -32
+KPX Atilde C -31
+KPX Atilde G -32
+KPX Atilde O -32
+KPX Atilde Q -32
+KPX Atilde T -73
+KPX Atilde U -31
+KPX Atilde V -56
+KPX Atilde W -46
+KPX Atilde Y -74
+KPX Atilde comma 9
+KPX Atilde period 9
+KPX B A -26
+KPX B AE -21
+KPX B Aacute -26
+KPX B Acircumflex -26
+KPX B Adieresis -26
+KPX B Aring -26
+KPX B Atilde -26
+KPX B O -12
+KPX B OE -6
+KPX B Oacute -12
+KPX B Ocircumflex -12
+KPX B Odieresis -12
+KPX B Ograve -12
+KPX B Oslash -8
+KPX B V -30
+KPX B W -21
+KPX B Y -40
+KPX C A -29
+KPX C AE -23
+KPX C Aacute -29
+KPX C Adieresis -29
+KPX C Aring -29
+KPX C H -7
+KPX C K -13
+KPX C O -12
+KPX C Oacute -12
+KPX C Odieresis -12
+KPX Ccedilla A -31
+KPX D A -31
+KPX D Aacute -31
+KPX D Acircumflex -31
+KPX D Adieresis -31
+KPX D Agrave -31
+KPX D Aring -31
+KPX D Atilde -31
+KPX D J -1
+KPX D T -14
+KPX D V -25
+KPX D W -15
+KPX D X -28
+KPX D Y -43
+KPX F A -53
+KPX F Aacute -53
+KPX F Acircumflex -53
+KPX F Adieresis -53
+KPX F Agrave -53
+KPX F Aring -53
+KPX F Atilde -53
+KPX F J -24
+KPX F O -19
+KPX F Odieresis -19
+KPX F a -24
+KPX F aacute -24
+KPX F adieresis -24
+KPX F ae -24
+KPX F aring -24
+KPX F comma -77
+KPX F e -15
+KPX F eacute -15
+KPX F hyphen 0
+KPX F i -14
+KPX F j -13
+KPX F o -20
+KPX F oacute -20
+KPX F odieresis -20
+KPX F oe -19
+KPX F oslash -20
+KPX F period -77
+KPX F r -30
+KPX F u -31
+KPX G A -8
+KPX G AE -2
+KPX G Aacute -8
+KPX G Acircumflex -8
+KPX G Adieresis -8
+KPX G Agrave -8
+KPX G Aring -8
+KPX G Atilde -8
+KPX G T -18
+KPX G V -29
+KPX G W -20
+KPX G Y -47
+KPX J A -30
+KPX J AE -25
+KPX J Adieresis -30
+KPX J Aring -30
+KPX K C -41
+KPX K G -43
+KPX K O -42
+KPX K OE -36
+KPX K Oacute -42
+KPX K Odieresis -42
+KPX K S -30
+KPX K T 14
+KPX K a -10
+KPX K adieresis -10
+KPX K ae -11
+KPX K aring -10
+KPX K e -27
+KPX K hyphen -34
+KPX K o -35
+KPX K oacute -35
+KPX K odieresis -35
+KPX K u -30
+KPX K udieresis -30
+KPX K y -57
+KPX L A 6
+KPX L AE 12
+KPX L Aacute 6
+KPX L Adieresis 6
+KPX L Aring 6
+KPX L C -25
+KPX L Ccedilla -26
+KPX L G -27
+KPX L O -26
+KPX L Oacute -26
+KPX L Ocircumflex -26
+KPX L Odieresis -26
+KPX L Ograve -26
+KPX L Otilde -26
+KPX L S -8
+KPX L T -79
+KPX L U -23
+KPX L Udieresis -23
+KPX L V -75
+KPX L W -60
+KPX L Y -92
+KPX L hyphen -19
+KPX L quotedblright -123
+KPX L quoteright -125
+KPX L u -17
+KPX L udieresis -17
+KPX L y -50
+KPX N A -10
+KPX N AE -4
+KPX N Aacute -10
+KPX N Adieresis -10
+KPX N Aring -10
+KPX N C -3
+KPX N Ccedilla -2
+KPX N G -4
+KPX N O -4
+KPX N Oacute -4
+KPX N Odieresis -4
+KPX N a -1
+KPX N aacute -1
+KPX N adieresis -1
+KPX N ae -2
+KPX N aring -1
+KPX N comma 5
+KPX N e 2
+KPX N eacute 2
+KPX N o -3
+KPX N oacute -3
+KPX N odieresis -3
+KPX N oslash 0
+KPX N period 5
+KPX N u -2
+KPX N udieresis -2
+KPX O A -35
+KPX O AE -29
+KPX O Aacute -35
+KPX O Adieresis -35
+KPX O Aring -35
+KPX O T -21
+KPX O V -29
+KPX O W -20
+KPX O X -32
+KPX O Y -50
+KPX Oacute A -35
+KPX Oacute T -21
+KPX Oacute V -29
+KPX Oacute W -20
+KPX Oacute Y -50
+KPX Ocircumflex T -21
+KPX Ocircumflex V -29
+KPX Ocircumflex Y -50
+KPX Odieresis A -35
+KPX Odieresis T -21
+KPX Odieresis V -29
+KPX Odieresis W -20
+KPX Odieresis X -32
+KPX Odieresis Y -50
+KPX Ograve T -21
+KPX Ograve V -29
+KPX Ograve Y -50
+KPX Oslash A -31
+KPX Otilde T -21
+KPX Otilde V -29
+KPX Otilde Y -50
+KPX P A -61
+KPX P AE -56
+KPX P Aacute -61
+KPX P Adieresis -61
+KPX P Aring -61
+KPX P J -45
+KPX P a -22
+KPX P aacute -22
+KPX P adieresis -22
+KPX P ae -22
+KPX P aring -22
+KPX P comma -98
+KPX P e -20
+KPX P eacute -20
+KPX P hyphen -13
+KPX P o -25
+KPX P oacute -25
+KPX P odieresis -25
+KPX P oe -25
+KPX P oslash -25
+KPX P period -98
+KPX R C -9
+KPX R Ccedilla -8
+KPX R G -10
+KPX R O -10
+KPX R OE -4
+KPX R Oacute -10
+KPX R Odieresis -10
+KPX R T -9
+KPX R U -8
+KPX R Udieresis -8
+KPX R V -27
+KPX R W -18
+KPX R Y -36
+KPX R a -6
+KPX R aacute -6
+KPX R adieresis -6
+KPX R ae -7
+KPX R aring -6
+KPX R e -3
+KPX R eacute -3
+KPX R hyphen 7
+KPX R o -9
+KPX R oacute -9
+KPX R odieresis -9
+KPX R oe -9
+KPX R u -7
+KPX R uacute -7
+KPX R udieresis -7
+KPX R y -6
+KPX S A -20
+KPX S AE -14
+KPX S Aacute -20
+KPX S Adieresis -20
+KPX S Aring -20
+KPX S T -12
+KPX S V -29
+KPX S W -19
+KPX S Y -39
+KPX S t -5
+KPX T A -72
+KPX T AE -68
+KPX T Aacute -72
+KPX T Acircumflex -72
+KPX T Adieresis -72
+KPX T Agrave -72
+KPX T Aring -72
+KPX T Atilde -72
+KPX T C -17
+KPX T G -18
+KPX T J -77
+KPX T O -19
+KPX T OE -12
+KPX T Oacute -19
+KPX T Ocircumflex -19
+KPX T Odieresis -19
+KPX T Ograve -19
+KPX T Oslash -19
+KPX T Otilde -19
+KPX T S -2
+KPX T V 11
+KPX T W 13
+KPX T Y 13
+KPX T a -68
+KPX T ae -69
+KPX T c -68
+KPX T colon -78
+KPX T comma -61
+KPX T e -64
+KPX T g -69
+KPX T guillemotleft -92
+KPX T guilsinglleft -89
+KPX T hyphen -46
+KPX T i -9
+KPX T j -9
+KPX T o -71
+KPX T oslash -67
+KPX T period -61
+KPX T r -64
+KPX T s -69
+KPX T semicolon -79
+KPX T u -68
+KPX T v -77
+KPX T w -72
+KPX T y -76
+KPX U A -32
+KPX U AE -27
+KPX U Aacute -32
+KPX U Acircumflex -32
+KPX U Adieresis -32
+KPX U Aring -32
+KPX U Atilde -32
+KPX U comma -14
+KPX U m -5
+KPX U n -5
+KPX U p -5
+KPX U period -11
+KPX U r -5
+KPX Uacute A -32
+KPX Uacute comma -14
+KPX Uacute m -5
+KPX Uacute n -5
+KPX Uacute p -5
+KPX Uacute period -11
+KPX Uacute r -5
+KPX Ucircumflex A -32
+KPX Udieresis A -32
+KPX Udieresis b -5
+KPX Udieresis comma -14
+KPX Udieresis m -5
+KPX Udieresis n -5
+KPX Udieresis p -5
+KPX Udieresis period -11
+KPX Udieresis r -5
+KPX Ugrave A -32
+KPX V A -57
+KPX V AE -52
+KPX V Aacute -57
+KPX V Acircumflex -57
+KPX V Adieresis -57
+KPX V Agrave -57
+KPX V Aring -57
+KPX V Atilde -57
+KPX V C -32
+KPX V G -33
+KPX V O -33
+KPX V Oacute -33
+KPX V Ocircumflex -33
+KPX V Odieresis -33
+KPX V Ograve -33
+KPX V Oslash -29
+KPX V Otilde -33
+KPX V S -22
+KPX V T 13
+KPX V a -45
+KPX V ae -46
+KPX V colon -47
+KPX V comma -58
+KPX V e -41
+KPX V g -45
+KPX V guillemotleft -67
+KPX V guilsinglleft -65
+KPX V hyphen -21
+KPX V i -12
+KPX V o -47
+KPX V oslash -44
+KPX V period -58
+KPX V r -36
+KPX V semicolon -47
+KPX V u -40
+KPX V y -17
+KPX W A -47
+KPX W AE -42
+KPX W Aacute -47
+KPX W Acircumflex -47
+KPX W Adieresis -47
+KPX W Agrave -47
+KPX W Aring -47
+KPX W Atilde -47
+KPX W C -22
+KPX W G -23
+KPX W O -23
+KPX W Oacute -23
+KPX W Ocircumflex -23
+KPX W Odieresis -23
+KPX W Ograve -23
+KPX W Oslash -19
+KPX W Otilde -23
+KPX W S -17
+KPX W T 15
+KPX W a -32
+KPX W ae -33
+KPX W colon -40
+KPX W comma -42
+KPX W e -28
+KPX W g -32
+KPX W guillemotleft -55
+KPX W guilsinglleft -52
+KPX W hyphen -9
+KPX W i -10
+KPX W o -34
+KPX W oslash -31
+KPX W period -42
+KPX W r -27
+KPX W semicolon -41
+KPX W u -32
+KPX W y -11
+KPX X C -32
+KPX X O -33
+KPX X Odieresis -33
+KPX X Q -33
+KPX X a -15
+KPX X e -31
+KPX X hyphen -27
+KPX X o -37
+KPX X u -34
+KPX X y -44
+KPX Y A -73
+KPX Y AE -68
+KPX Y Aacute -73
+KPX Y Acircumflex -73
+KPX Y Adieresis -73
+KPX Y Agrave -73
+KPX Y Aring -73
+KPX Y Atilde -73
+KPX Y C -45
+KPX Y G -46
+KPX Y O -46
+KPX Y Oacute -46
+KPX Y Ocircumflex -46
+KPX Y Odieresis -46
+KPX Y Ograve -46
+KPX Y Oslash -45
+KPX Y Otilde -46
+KPX Y S -27
+KPX Y T 16
+KPX Y a -64
+KPX Y ae -65
+KPX Y colon -61
+KPX Y comma -70
+KPX Y e -60
+KPX Y g -64
+KPX Y guillemotleft -91
+KPX Y guilsinglleft -88
+KPX Y hyphen -49
+KPX Y i -9
+KPX Y o -66
+KPX Y oslash -63
+KPX Y p -48
+KPX Y period -70
+KPX Y semicolon -61
+KPX Y u -54
+KPX Y v -31
+KPX Z v -19
+KPX Z y -18
+KPX a j -2
+KPX a quoteright -11
+KPX a v -16
+KPX a w -7
+KPX a y -17
+KPX aacute v -17
+KPX aacute w -8
+KPX aacute y -17
+KPX adieresis v -17
+KPX adieresis w -8
+KPX adieresis y -17
+KPX ae v -17
+KPX ae w -7
+KPX ae y -19
+KPX agrave v -16
+KPX agrave w -7
+KPX agrave y -17
+KPX aring v -16
+KPX aring w -7
+KPX aring y -17
+KPX b v -16
+KPX b w -6
+KPX b y -17
+KPX c h -6
+KPX c k -8
+KPX comma one -64
+KPX comma quotedblright -27
+KPX comma quoteright -29
+KPX e quoteright -12
+KPX e t -4
+KPX e v -16
+KPX e w -6
+KPX e x -19
+KPX e y -18
+KPX eacute v -17
+KPX eacute w -8
+KPX eacute y -18
+KPX ecircumflex v -16
+KPX ecircumflex w -6
+KPX ecircumflex y -18
+KPX eight four 2
+KPX eight one -24
+KPX eight seven -10
+KPX f a -12
+KPX f aacute -12
+KPX f adieresis -12
+KPX f ae -13
+KPX f aring -12
+KPX f e -10
+KPX f eacute -10
+KPX f f 12
+KPX f i -11
+KPX f j -11
+KPX f l -11
+KPX f o -16
+KPX f oacute -16
+KPX f odieresis -16
+KPX f oe -16
+KPX f oslash -13
+KPX f quoteright 0
+KPX f s -13
+KPX f t 12
+KPX five four 0
+KPX five one -30
+KPX five seven -10
+KPX four four 3
+KPX four one -46
+KPX four seven -27
+KPX g a -2
+KPX g adieresis -2
+KPX g ae -3
+KPX g aring -2
+KPX g e 1
+KPX g eacute 1
+KPX g l 0
+KPX g oacute -5
+KPX g odieresis -5
+KPX g r 1
+KPX guillemotright A -41
+KPX guillemotright AE -36
+KPX guillemotright Aacute -41
+KPX guillemotright Adieresis -41
+KPX guillemotright Aring -41
+KPX guillemotright T -89
+KPX guillemotright V -63
+KPX guillemotright W -51
+KPX guillemotright Y -91
+KPX guilsinglright A -40
+KPX guilsinglright AE -34
+KPX guilsinglright Aacute -40
+KPX guilsinglright Adieresis -40
+KPX guilsinglright Aring -40
+KPX guilsinglright T -87
+KPX guilsinglright V -61
+KPX guilsinglright W -49
+KPX guilsinglright Y -89
+KPX h quoteright -13
+KPX h y -19
+KPX hyphen A 1
+KPX hyphen AE 6
+KPX hyphen Aacute 1
+KPX hyphen Adieresis 1
+KPX hyphen Aring 1
+KPX hyphen T -45
+KPX hyphen V -19
+KPX hyphen W -8
+KPX hyphen Y -51
+KPX i T -9
+KPX i j -3
+KPX k a -9
+KPX k aacute -9
+KPX k adieresis -9
+KPX k ae -9
+KPX k aring -9
+KPX k comma 6
+KPX k e -12
+KPX k eacute -12
+KPX k g -17
+KPX k hyphen -16
+KPX k o -18
+KPX k oacute -18
+KPX k odieresis -18
+KPX k period 7
+KPX k s -16
+KPX k u -12
+KPX k udieresis -6
+KPX l v -14
+KPX l y -13
+KPX m p -2
+KPX m v -17
+KPX m w -8
+KPX m y -18
+KPX n T -67
+KPX n p -3
+KPX n quoteright -13
+KPX n v -18
+KPX n w -9
+KPX n y -19
+KPX nine four 0
+KPX nine one -21
+KPX nine seven -14
+KPX o T -68
+KPX o quoteright -17
+KPX o t -7
+KPX o v -19
+KPX o w -9
+KPX o x -23
+KPX o y -21
+KPX oacute v -19
+KPX oacute w -9
+KPX oacute y -21
+KPX ocircumflex t -7
+KPX odieresis t -7
+KPX odieresis v -19
+KPX odieresis w -9
+KPX odieresis x -23
+KPX odieresis y -21
+KPX ograve v -19
+KPX ograve w -9
+KPX ograve y -21
+KPX one comma -39
+KPX one eight -41
+KPX one five -40
+KPX one four -57
+KPX one nine -41
+KPX one one -74
+KPX one period -39
+KPX one seven -55
+KPX one six -39
+KPX one three -46
+KPX one two -47
+KPX one zero -38
+KPX p t -4
+KPX p y -18
+KPX period one -64
+KPX period quotedblright -27
+KPX period quoteright -29
+KPX q c -2
+KPX q u -2
+KPX quotedblbase A 9
+KPX quotedblbase AE 15
+KPX quotedblbase T -61
+KPX quotedblbase V -58
+KPX quotedblbase W -43
+KPX quotedblbase Y -74
+KPX quotedblleft A -55
+KPX quotedblleft AE -50
+KPX quotedblleft Aacute -55
+KPX quotedblleft Adieresis -55
+KPX quotedblleft Aring -55
+KPX quotedblleft T -6
+KPX quotedblleft V 4
+KPX quotedblleft W 9
+KPX quotedblleft Y -6
+KPX quotedblright A -57
+KPX quotedblright AE -53
+KPX quotedblright Aacute -57
+KPX quotedblright Adieresis -57
+KPX quotedblright Aring -57
+KPX quotedblright T -4
+KPX quotedblright V 2
+KPX quotedblright W 8
+KPX quotedblright Y -8
+KPX quoteleft A -57
+KPX quoteleft AE -52
+KPX quoteleft Aacute -57
+KPX quoteleft Adieresis -57
+KPX quoteleft Aring -57
+KPX quoteleft T -8
+KPX quoteleft V 2
+KPX quoteleft W 7
+KPX quoteleft Y -8
+KPX quoteright A -59
+KPX quoteright AE -55
+KPX quoteright Aacute -59
+KPX quoteright Adieresis -59
+KPX quoteright Aring -59
+KPX quoteright comma -35
+KPX quoteright d -23
+KPX quoteright o -29
+KPX quoteright period -35
+KPX quoteright r -11
+KPX quoteright s -21
+KPX quoteright t -1
+KPX quoteright v -3
+KPX quoteright w 0
+KPX quoteright y -2
+KPX r a -9
+KPX r aacute -9
+KPX r acircumflex -9
+KPX r adieresis -9
+KPX r ae -9
+KPX r agrave -9
+KPX r aring -9
+KPX r c -12
+KPX r ccedilla -7
+KPX r colon -19
+KPX r comma -47
+KPX r d -9
+KPX r e -8
+KPX r eacute -8
+KPX r ecircumflex -8
+KPX r egrave -8
+KPX r f 12
+KPX r g -6
+KPX r h -10
+KPX r hyphen -30
+KPX r i -13
+KPX r j -12
+KPX r k -12
+KPX r l -12
+KPX r m -10
+KPX r n -11
+KPX r o -13
+KPX r oacute -13
+KPX r ocircumflex -13
+KPX r odieresis -13
+KPX r oe -12
+KPX r ograve -13
+KPX r oslash -12
+KPX r p -10
+KPX r period -47
+KPX r q -8
+KPX r quoteright 4
+KPX r r -10
+KPX r s -8
+KPX r semicolon -19
+KPX r t 12
+KPX r u -12
+KPX r v 8
+KPX r w 10
+KPX r x 4
+KPX r y 9
+KPX r z 0
+KPX s quoteright -12
+KPX s t -8
+KPX seven colon -48
+KPX seven comma -77
+KPX seven eight -11
+KPX seven five -20
+KPX seven four -59
+KPX seven one -14
+KPX seven period -77
+KPX seven seven 5
+KPX seven six -16
+KPX seven three -8
+KPX seven two -8
+KPX six four 0
+KPX six one -23
+KPX six seven -9
+KPX t S -5
+KPX t a -3
+KPX t aacute -3
+KPX t adieresis -3
+KPX t ae -3
+KPX t aring -3
+KPX t colon -19
+KPX t e -6
+KPX t eacute -6
+KPX t h -4
+KPX t o -12
+KPX t oacute -12
+KPX t odieresis -12
+KPX t quoteright -1
+KPX t semicolon -19
+KPX three four 0
+KPX three one -27
+KPX three seven -13
+KPX two four -21
+KPX two one -21
+KPX two seven -10
+KPX u quoteright -4
+KPX v a -21
+KPX v aacute -21
+KPX v acircumflex -21
+KPX v adieresis -21
+KPX v ae -22
+KPX v agrave -21
+KPX v aring -21
+KPX v atilde -21
+KPX v c -21
+KPX v colon -20
+KPX v comma -40
+KPX v e -17
+KPX v eacute -17
+KPX v ecircumflex -17
+KPX v egrave -17
+KPX v g -21
+KPX v hyphen 0
+KPX v l -12
+KPX v o -23
+KPX v oacute -23
+KPX v odieresis -23
+KPX v ograve -23
+KPX v oslash -20
+KPX v period -40
+KPX v s -22
+KPX v semicolon -20
+KPX w a -12
+KPX w aacute -12
+KPX w acircumflex -12
+KPX w adieresis -12
+KPX w ae -13
+KPX w agrave -12
+KPX w aring -12
+KPX w atilde -12
+KPX w c -11
+KPX w colon -18
+KPX w comma -25
+KPX w e -8
+KPX w eacute -8
+KPX w ecircumflex -8
+KPX w egrave -8
+KPX w g -12
+KPX w hyphen 8
+KPX w l -9
+KPX w o -14
+KPX w oacute -14
+KPX w odieresis -14
+KPX w ograve -14
+KPX w oslash -11
+KPX w period -25
+KPX w s -13
+KPX w semicolon -18
+KPX x a -19
+KPX x c -22
+KPX x e -18
+KPX x eacute -18
+KPX x o -25
+KPX x q -21
+KPX y a -23
+KPX y aacute -23
+KPX y acircumflex -23
+KPX y adieresis -23
+KPX y ae -24
+KPX y agrave -23
+KPX y aring -23
+KPX y atilde -23
+KPX y c -23
+KPX y colon -21
+KPX y comma -41
+KPX y e -19
+KPX y eacute -19
+KPX y ecircumflex -19
+KPX y egrave -19
+KPX y g -24
+KPX y hyphen 0
+KPX y l -14
+KPX y o -25
+KPX y oacute -25
+KPX y odieresis -25
+KPX y ograve -25
+KPX y oslash -21
+KPX y period -40
+KPX y s -24
+KPX y semicolon -22
+KPX zero four 2
+KPX zero one -20
+KPX zero seven -12
+EndKernPairs
+EndKernData
+EndFontMetrics
diff --git a/misc/gs_afm/HelvO.afm b/misc/gs_afm/HelvO.afm
new file mode 100644
index 0000000000..4bb7bf2079
--- /dev/null
+++ b/misc/gs_afm/HelvO.afm
@@ -0,0 +1,1257 @@
+StartFontMetrics 3.0
+Comment Copyright URW Software, Copyright 1994 by URW
+Comment Creation Date: 8/3/1994
+Comment See the file PUBLIC (Aladdin Free Public License) for license conditions.
+FontName NimbusSanL-ReguCondItal
+FullName Nimbus Sans L Regular Condensed Italic
+FamilyName Nimbus Sans L
+Weight Regular
+ItalicAngle -9.0
+IsFixedPitch false
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.005
+Notice URW Software, Copyright 1994 by URW
+EncodingScheme AdobeStandardEncoding
+FontBBox -139 -225 915 944
+CapHeight 718
+XHeight 523
+Descender -207
+Ascender 718
+StartCharMetrics 232
+C 32 ; WX 228 ; N space ; B 21 0 21 0 ;
+C 33 ; WX 228 ; N exclam ; B 74 0 278 718 ;
+C 34 ; WX 291 ; N quotedbl ; B 138 463 359 718 ;
+C 35 ; WX 456 ; N numbersign ; B 60 0 517 688 ;
+C 36 ; WX 456 ; N dollar ; B 57 -115 506 775 ;
+C 37 ; WX 729 ; N percent ; B 120 -19 729 703 ;
+C 38 ; WX 547 ; N ampersand ; B 63 -15 530 718 ;
+C 39 ; WX 182 ; N quoteright ; B 124 463 254 718 ;
+C 40 ; WX 273 ; N parenleft ; B 89 -207 372 733 ;
+C 41 ; WX 273 ; N parenright ; B -7 -207 276 733 ;
+C 42 ; WX 319 ; N asterisk ; B 135 431 389 718 ;
+C 43 ; WX 479 ; N plus ; B 70 0 497 505 ;
+C 44 ; WX 228 ; N comma ; B 46 -147 175 106 ;
+C 45 ; WX 273 ; N hyphen ; B 77 232 293 322 ;
+C 46 ; WX 228 ; N period ; B 71 0 175 106 ;
+C 47 ; WX 228 ; N slash ; B -17 -19 370 737 ;
+C 48 ; WX 456 ; N zero ; B 77 -19 499 703 ;
+C 49 ; WX 456 ; N one ; B 170 0 417 703 ;
+C 50 ; WX 456 ; N two ; B 21 0 506 703 ;
+C 51 ; WX 456 ; N three ; B 61 -19 500 703 ;
+C 52 ; WX 456 ; N four ; B 50 0 472 703 ;
+C 53 ; WX 456 ; N five ; B 55 -19 509 688 ;
+C 54 ; WX 456 ; N six ; B 74 -19 504 703 ;
+C 55 ; WX 456 ; N seven ; B 112 0 549 688 ;
+C 56 ; WX 456 ; N eight ; B 60 -19 497 703 ;
+C 57 ; WX 456 ; N nine ; B 67 -19 499 703 ;
+C 58 ; WX 228 ; N colon ; B 71 0 247 516 ;
+C 59 ; WX 228 ; N semicolon ; B 46 -147 247 516 ;
+C 60 ; WX 479 ; N less ; B 77 10 526 496 ;
+C 61 ; WX 479 ; N equal ; B 52 115 515 390 ;
+C 62 ; WX 479 ; N greater ; B 41 10 490 496 ;
+C 63 ; WX 456 ; N question ; B 132 0 500 727 ;
+C 64 ; WX 832 ; N at ; B 176 -19 791 737 ;
+C 65 ; WX 547 ; N A ; B 11 0 536 718 ;
+C 66 ; WX 547 ; N B ; B 61 0 583 718 ;
+C 67 ; WX 592 ; N C ; B 88 -19 640 737 ;
+C 68 ; WX 592 ; N D ; B 66 0 626 718 ;
+C 69 ; WX 547 ; N E ; B 71 0 625 718 ;
+C 70 ; WX 501 ; N F ; B 71 0 603 718 ;
+C 71 ; WX 638 ; N G ; B 91 -19 655 737 ;
+C 72 ; WX 592 ; N H ; B 63 0 655 718 ;
+C 73 ; WX 228 ; N I ; B 75 0 279 718 ;
+C 74 ; WX 410 ; N J ; B 39 -19 476 718 ;
+C 75 ; WX 547 ; N K ; B 62 0 662 718 ;
+C 76 ; WX 456 ; N L ; B 62 0 455 718 ;
+C 77 ; WX 683 ; N M ; B 60 0 749 718 ;
+C 78 ; WX 592 ; N N ; B 62 0 655 718 ;
+C 79 ; WX 638 ; N O ; B 86 -19 677 737 ;
+C 80 ; WX 547 ; N P ; B 71 0 604 718 ;
+C 81 ; WX 638 ; N Q ; B 86 -56 677 737 ;
+C 82 ; WX 592 ; N R ; B 72 0 634 718 ;
+C 83 ; WX 547 ; N S ; B 74 -19 584 737 ;
+C 84 ; WX 501 ; N T ; B 122 0 615 718 ;
+C 85 ; WX 592 ; N U ; B 101 -19 653 718 ;
+C 86 ; WX 547 ; N V ; B 142 0 656 718 ;
+C 87 ; WX 774 ; N W ; B 138 0 886 718 ;
+C 88 ; WX 547 ; N X ; B 16 0 647 718 ;
+C 89 ; WX 547 ; N Y ; B 137 0 661 718 ;
+C 90 ; WX 501 ; N Z ; B 19 0 607 718 ;
+C 91 ; WX 228 ; N bracketleft ; B 17 -196 331 722 ;
+C 92 ; WX 228 ; N backslash ; B 115 -19 239 737 ;
+C 93 ; WX 228 ; N bracketright ; B -11 -196 302 722 ;
+C 94 ; WX 385 ; N asciicircum ; B 35 264 442 688 ;
+C 95 ; WX 456 ; N underscore ; B -22 -125 443 -75 ;
+C 96 ; WX 182 ; N quoteleft ; B 135 470 265 725 ;
+C 97 ; WX 456 ; N a ; B 50 -15 458 538 ;
+C 98 ; WX 456 ; N b ; B 48 -15 479 718 ;
+C 99 ; WX 410 ; N c ; B 61 -15 454 538 ;
+C 100 ; WX 456 ; N d ; B 69 -15 534 718 ;
+C 101 ; WX 456 ; N e ; B 69 -15 474 538 ;
+C 102 ; WX 228 ; N f ; B 71 0 341 728 ;
+C 103 ; WX 456 ; N g ; B 34 -220 500 538 ;
+C 104 ; WX 456 ; N h ; B 53 0 470 718 ;
+C 105 ; WX 182 ; N i ; B 55 0 252 718 ;
+C 106 ; WX 182 ; N j ; B -49 -210 252 718 ;
+C 107 ; WX 410 ; N k ; B 55 0 492 718 ;
+C 108 ; WX 182 ; N l ; B 55 0 252 718 ;
+C 109 ; WX 683 ; N m ; B 53 0 699 538 ;
+C 110 ; WX 456 ; N n ; B 53 0 470 538 ;
+C 111 ; WX 456 ; N o ; B 68 -14 479 538 ;
+C 112 ; WX 456 ; N p ; B 11 -207 479 538 ;
+C 113 ; WX 456 ; N q ; B 69 -207 496 538 ;
+C 114 ; WX 273 ; N r ; B 63 0 365 538 ;
+C 115 ; WX 410 ; N s ; B 52 -15 434 538 ;
+C 116 ; WX 228 ; N t ; B 84 -7 302 669 ;
+C 117 ; WX 456 ; N u ; B 77 -15 492 523 ;
+C 118 ; WX 410 ; N v ; B 98 0 495 523 ;
+C 119 ; WX 592 ; N w ; B 103 0 673 523 ;
+C 120 ; WX 410 ; N x ; B 9 0 487 523 ;
+C 121 ; WX 410 ; N y ; B 12 -214 492 523 ;
+C 122 ; WX 410 ; N z ; B 25 0 468 523 ;
+C 123 ; WX 274 ; N braceleft ; B 75 -196 365 722 ;
+C 124 ; WX 213 ; N bar ; B 74 -19 265 737 ;
+C 125 ; WX 274 ; N braceright ; B 0 -196 291 722 ;
+C 126 ; WX 479 ; N asciitilde ; B 91 181 476 322 ;
+C 161 ; WX 273 ; N exclamdown ; B 63 -195 267 523 ;
+C 162 ; WX 456 ; N cent ; B 78 -115 479 623 ;
+C 163 ; WX 456 ; N sterling ; B 40 -16 520 718 ;
+C 164 ; WX 137 ; N fraction ; B -139 -19 396 703 ;
+C 165 ; WX 456 ; N yen ; B 67 0 573 688 ;
+C 166 ; WX 456 ; N florin ; B -43 -207 537 737 ;
+C 167 ; WX 456 ; N section ; B 63 -191 479 737 ;
+C 168 ; WX 456 ; N currency ; B 49 99 530 603 ;
+C 169 ; WX 157 ; N quotesingle ; B 129 463 233 718 ;
+C 170 ; WX 273 ; N quotedblleft ; B 113 470 378 725 ;
+C 171 ; WX 456 ; N guillemotleft ; B 120 108 454 446 ;
+C 172 ; WX 273 ; N guilsinglleft ; B 112 108 279 446 ;
+C 173 ; WX 273 ; N guilsinglright ; B 91 108 257 446 ;
+C 174 ; WX 410 ; N fi ; B 71 0 481 728 ;
+C 175 ; WX 410 ; N fl ; B 71 0 479 728 ;
+C 177 ; WX 456 ; N endash ; B 42 240 510 313 ;
+C 178 ; WX 456 ; N dagger ; B 110 -159 510 718 ;
+C 179 ; WX 456 ; N daggerdbl ; B 43 -159 511 718 ;
+C 180 ; WX 228 ; N periodcentered ; B 106 190 211 315 ;
+C 182 ; WX 440 ; N paragraph ; B 103 -173 533 718 ;
+C 183 ; WX 287 ; N bullet ; B 74 202 339 517 ;
+C 184 ; WX 182 ; N quotesinglbase ; B 17 -149 147 106 ;
+C 185 ; WX 273 ; N quotedblbase ; B -5 -149 260 106 ;
+C 186 ; WX 273 ; N quotedblright ; B 102 463 367 718 ;
+C 187 ; WX 456 ; N guillemotright ; B 98 108 433 446 ;
+C 188 ; WX 820 ; N ellipsis ; B 94 0 744 106 ;
+C 189 ; WX 820 ; N perthousand ; B 72 -19 844 703 ;
+C 191 ; WX 501 ; N questiondown ; B 70 -201 438 525 ;
+C 193 ; WX 273 ; N grave ; B 139 593 276 734 ;
+C 194 ; WX 273 ; N acute ; B 203 593 390 734 ;
+C 195 ; WX 273 ; N circumflex ; B 121 593 359 734 ;
+C 196 ; WX 273 ; N tilde ; B 102 606 402 722 ;
+C 197 ; WX 273 ; N macron ; B 117 627 384 684 ;
+C 198 ; WX 273 ; N breve ; B 137 595 391 731 ;
+C 199 ; WX 273 ; N dotaccent ; B 204 604 297 706 ;
+C 200 ; WX 273 ; N dieresis ; B 138 604 363 706 ;
+C 202 ; WX 273 ; N ring ; B 175 572 330 756 ;
+C 203 ; WX 273 ; N cedilla ; B 2 -225 191 0 ;
+C 205 ; WX 273 ; N hungarumlaut ; B 129 593 463 734 ;
+C 206 ; WX 273 ; N ogonek ; B 35 -225 204 0 ;
+C 207 ; WX 273 ; N caron ; B 145 593 384 734 ;
+C 208 ; WX 820 ; N emdash ; B 42 240 875 313 ;
+C 225 ; WX 820 ; N AE ; B 7 0 899 718 ;
+C 227 ; WX 303 ; N ordfeminine ; B 82 304 368 737 ;
+C 232 ; WX 456 ; N Lslash ; B 34 0 455 718 ;
+C 233 ; WX 638 ; N Oslash ; B 35 -19 730 737 ;
+C 234 ; WX 820 ; N OE ; B 80 -19 915 737 ;
+C 235 ; WX 299 ; N ordmasculine ; B 82 304 384 737 ;
+C 241 ; WX 729 ; N ae ; B 50 -15 746 538 ;
+C 245 ; WX 228 ; N dotlessi ; B 78 0 241 523 ;
+C 248 ; WX 182 ; N lslash ; B 34 0 284 718 ;
+C 249 ; WX 501 ; N oslash ; B 24 -22 531 545 ;
+C 250 ; WX 774 ; N oe ; B 68 -15 791 538 ;
+C 251 ; WX 501 ; N germandbls ; B 55 -15 539 728 ;
+C -1 ; WX 547 ; N Yacute ; B 137 0 661 929 ;
+C -1 ; WX 592 ; N Ucircumflex ; B 101 -19 653 929 ;
+C -1 ; WX 592 ; N Ugrave ; B 101 -19 653 929 ;
+C -1 ; WX 501 ; N Zcaron ; B 19 0 607 929 ;
+C -1 ; WX 547 ; N Ydieresis ; B 137 0 661 901 ;
+C -1 ; WX 273 ; N threesuperior ; B 74 270 358 714 ;
+C -1 ; WX 592 ; N Uacute ; B 101 -19 653 929 ;
+C -1 ; WX 273 ; N twosuperior ; B 52 281 368 714 ;
+C -1 ; WX 592 ; N Udieresis ; B 101 -19 653 901 ;
+C -1 ; WX 228 ; N middot ; B 106 190 211 315 ;
+C -1 ; WX 273 ; N onesuperior ; B 136 281 305 703 ;
+C -1 ; WX 456 ; N aacute ; B 50 -15 482 734 ;
+C -1 ; WX 456 ; N agrave ; B 50 -15 458 734 ;
+C -1 ; WX 456 ; N acircumflex ; B 50 -15 458 734 ;
+C -1 ; WX 547 ; N Scaron ; B 74 -19 584 929 ;
+C -1 ; WX 638 ; N Otilde ; B 86 -19 677 917 ;
+C -1 ; WX 273 ; N sfthyphen ; B 77 232 293 322 ;
+C -1 ; WX 456 ; N atilde ; B 50 -15 486 722 ;
+C -1 ; WX 456 ; N aring ; B 50 -15 458 769 ;
+C -1 ; WX 456 ; N adieresis ; B 50 -15 458 706 ;
+C -1 ; WX 638 ; N Ograve ; B 86 -19 677 929 ;
+C -1 ; WX 638 ; N Ocircumflex ; B 86 -19 677 929 ;
+C -1 ; WX 638 ; N Odieresis ; B 86 -19 677 901 ;
+C -1 ; WX 592 ; N Ntilde ; B 62 0 655 917 ;
+C -1 ; WX 456 ; N edieresis ; B 69 -15 474 706 ;
+C -1 ; WX 456 ; N eacute ; B 69 -15 482 734 ;
+C -1 ; WX 456 ; N egrave ; B 69 -15 474 734 ;
+C -1 ; WX 228 ; N Icircumflex ; B 75 0 370 929 ;
+C -1 ; WX 456 ; N ecircumflex ; B 69 -15 474 734 ;
+C -1 ; WX 228 ; N Igrave ; B 75 0 288 929 ;
+C -1 ; WX 228 ; N Iacute ; B 75 0 401 929 ;
+C -1 ; WX 228 ; N Idieresis ; B 75 0 375 901 ;
+C -1 ; WX 328 ; N degree ; B 138 411 384 703 ;
+C -1 ; WX 547 ; N Ecircumflex ; B 71 0 625 929 ;
+C -1 ; WX 479 ; N minus ; B 70 216 497 289 ;
+C -1 ; WX 479 ; N multiply ; B 41 0 526 506 ;
+C -1 ; WX 479 ; N divide ; B 70 -19 497 524 ;
+C -1 ; WX 547 ; N Egrave ; B 71 0 625 929 ;
+C -1 ; WX 820 ; N trademark ; B 152 306 866 718 ;
+C -1 ; WX 638 ; N Oacute ; B 86 -19 677 929 ;
+C -1 ; WX 456 ; N thorn ; B 11 -207 479 718 ;
+C -1 ; WX 456 ; N eth ; B 67 -15 506 737 ;
+C -1 ; WX 547 ; N Eacute ; B 71 0 625 929 ;
+C -1 ; WX 410 ; N ccedilla ; B 61 -225 454 538 ;
+C -1 ; WX 228 ; N idieresis ; B 78 0 341 706 ;
+C -1 ; WX 228 ; N iacute ; B 78 0 368 734 ;
+C -1 ; WX 228 ; N igrave ; B 78 0 254 734 ;
+C -1 ; WX 479 ; N plusminus ; B 32 0 507 561 ;
+C -1 ; WX 684 ; N onehalf ; B 93 -19 688 703 ;
+C -1 ; WX 684 ; N onequarter ; B 123 -19 658 703 ;
+C -1 ; WX 684 ; N threequarters ; B 106 -19 706 714 ;
+C -1 ; WX 228 ; N icircumflex ; B 78 0 336 734 ;
+C -1 ; WX 547 ; N Edieresis ; B 71 0 625 901 ;
+C -1 ; WX 456 ; N ntilde ; B 53 0 486 722 ;
+C -1 ; WX 547 ; N Aring ; B 11 0 536 944 ;
+C -1 ; WX 456 ; N odieresis ; B 68 -14 479 706 ;
+C -1 ; WX 456 ; N oacute ; B 68 -14 482 734 ;
+C -1 ; WX 456 ; N ograve ; B 68 -14 479 734 ;
+C -1 ; WX 456 ; N ocircumflex ; B 68 -14 479 734 ;
+C -1 ; WX 456 ; N otilde ; B 68 -14 494 722 ;
+C -1 ; WX 410 ; N scaron ; B 52 -15 453 734 ;
+C -1 ; WX 456 ; N udieresis ; B 77 -15 492 706 ;
+C -1 ; WX 456 ; N uacute ; B 77 -15 492 734 ;
+C -1 ; WX 456 ; N ugrave ; B 77 -15 492 734 ;
+C -1 ; WX 456 ; N ucircumflex ; B 77 -15 492 734 ;
+C -1 ; WX 410 ; N yacute ; B 12 -214 492 734 ;
+C -1 ; WX 410 ; N zcaron ; B 25 0 468 734 ;
+C -1 ; WX 410 ; N ydieresis ; B 12 -214 492 706 ;
+C -1 ; WX 604 ; N copyright ; B 44 -19 687 737 ;
+C -1 ; WX 604 ; N registered ; B 44 -19 687 737 ;
+C -1 ; WX 547 ; N Atilde ; B 11 0 573 917 ;
+C -1 ; WX 228 ; N nbspace ; B 21 0 21 0 ;
+C -1 ; WX 592 ; N Ccedilla ; B 88 -225 640 737 ;
+C -1 ; WX 547 ; N Acircumflex ; B 11 0 536 929 ;
+C -1 ; WX 547 ; N Agrave ; B 11 0 536 929 ;
+C -1 ; WX 479 ; N logicalnot ; B 87 108 515 390 ;
+C -1 ; WX 547 ; N Aacute ; B 11 0 561 929 ;
+C -1 ; WX 592 ; N Eth ; B 57 0 626 718 ;
+C -1 ; WX 213 ; N brokenbar ; B 74 -19 265 737 ;
+C -1 ; WX 547 ; N Thorn ; B 71 0 584 718 ;
+C -1 ; WX 547 ; N Adieresis ; B 11 0 536 901 ;
+C -1 ; WX 456 ; N mu ; B 20 -207 492 523 ;
+C -1 ; WX 228 ; N .notdef ; B 21 0 21 0 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 998
+KPX A C -30
+KPX A Ccedilla -30
+KPX A G -33
+KPX A O -30
+KPX A Odieresis -30
+KPX A Q -30
+KPX A T -81
+KPX A U -32
+KPX A Uacute -32
+KPX A Ucircumflex -32
+KPX A Udieresis -32
+KPX A Ugrave -32
+KPX A V -61
+KPX A W -43
+KPX A Y -82
+KPX A a -11
+KPX A b -6
+KPX A c -11
+KPX A ccedilla -11
+KPX A comma 0
+KPX A d -13
+KPX A e -15
+KPX A g -16
+KPX A guillemotleft -43
+KPX A guilsinglleft -39
+KPX A hyphen -6
+KPX A o -16
+KPX A period 1
+KPX A q -13
+KPX A quotedblright -40
+KPX A quoteright -51
+KPX A t -17
+KPX A u -15
+KPX A v -30
+KPX A w -25
+KPX A y -31
+KPX Aacute C -31
+KPX Aacute G -34
+KPX Aacute O -31
+KPX Aacute Q -31
+KPX Aacute T -81
+KPX Aacute U -33
+KPX Aacute V -61
+KPX Aacute W -43
+KPX Aacute Y -82
+KPX Aacute a -12
+KPX Aacute b -6
+KPX Aacute c -12
+KPX Aacute comma 0
+KPX Aacute d -14
+KPX Aacute e -16
+KPX Aacute g -16
+KPX Aacute guillemotleft -44
+KPX Aacute guilsinglleft -40
+KPX Aacute hyphen -6
+KPX Aacute o -17
+KPX Aacute period 0
+KPX Aacute q -14
+KPX Aacute quoteright -52
+KPX Aacute t -18
+KPX Aacute u -16
+KPX Aacute v -31
+KPX Aacute w -25
+KPX Aacute y -31
+KPX Acircumflex C -30
+KPX Acircumflex G -33
+KPX Acircumflex O -30
+KPX Acircumflex Q -30
+KPX Acircumflex T -81
+KPX Acircumflex U -32
+KPX Acircumflex V -61
+KPX Acircumflex W -43
+KPX Acircumflex Y -82
+KPX Acircumflex comma 0
+KPX Acircumflex period 1
+KPX Adieresis C -30
+KPX Adieresis G -33
+KPX Adieresis O -30
+KPX Adieresis Q -30
+KPX Adieresis T -81
+KPX Adieresis U -32
+KPX Adieresis V -61
+KPX Adieresis W -43
+KPX Adieresis Y -82
+KPX Adieresis a -11
+KPX Adieresis b -6
+KPX Adieresis c -11
+KPX Adieresis comma 0
+KPX Adieresis d -13
+KPX Adieresis g -16
+KPX Adieresis guillemotleft -43
+KPX Adieresis guilsinglleft -39
+KPX Adieresis hyphen -6
+KPX Adieresis o -16
+KPX Adieresis period 1
+KPX Adieresis q -13
+KPX Adieresis quotedblright -40
+KPX Adieresis quoteright -51
+KPX Adieresis t -17
+KPX Adieresis u -15
+KPX Adieresis v -30
+KPX Adieresis w -25
+KPX Adieresis y -31
+KPX Agrave C -30
+KPX Agrave G -33
+KPX Agrave O -30
+KPX Agrave Q -30
+KPX Agrave T -81
+KPX Agrave U -32
+KPX Agrave V -61
+KPX Agrave W -43
+KPX Agrave Y -82
+KPX Agrave comma 0
+KPX Agrave period 1
+KPX Aring C -30
+KPX Aring G -33
+KPX Aring O -30
+KPX Aring Q -30
+KPX Aring T -81
+KPX Aring U -32
+KPX Aring V -61
+KPX Aring W -43
+KPX Aring Y -82
+KPX Aring a -11
+KPX Aring b -6
+KPX Aring c -11
+KPX Aring comma 0
+KPX Aring d -13
+KPX Aring e -15
+KPX Aring g -16
+KPX Aring guillemotleft -43
+KPX Aring guilsinglleft -39
+KPX Aring hyphen -6
+KPX Aring o -16
+KPX Aring period 1
+KPX Aring q -13
+KPX Aring quotedblright -40
+KPX Aring quoteright -51
+KPX Aring t -17
+KPX Aring u -15
+KPX Aring v -30
+KPX Aring w -25
+KPX Aring y -31
+KPX Atilde C -31
+KPX Atilde G -35
+KPX Atilde O -31
+KPX Atilde Q -31
+KPX Atilde T -81
+KPX Atilde U -34
+KPX Atilde V -61
+KPX Atilde W -43
+KPX Atilde Y -82
+KPX Atilde comma -1
+KPX Atilde period 0
+KPX B A -22
+KPX B AE -21
+KPX B Aacute -22
+KPX B Acircumflex -22
+KPX B Adieresis -22
+KPX B Aring -22
+KPX B Atilde -22
+KPX B O -9
+KPX B OE -5
+KPX B Oacute -9
+KPX B Ocircumflex -9
+KPX B Odieresis -9
+KPX B Ograve -9
+KPX B Oslash -7
+KPX B V -34
+KPX B W -17
+KPX B Y -42
+KPX C A -33
+KPX C AE -32
+KPX C Aacute -33
+KPX C Adieresis -33
+KPX C Aring -33
+KPX C H -13
+KPX C K -13
+KPX C O -13
+KPX C Oacute -13
+KPX C Odieresis -13
+KPX Ccedilla A -37
+KPX D A -40
+KPX D Aacute -40
+KPX D Acircumflex -40
+KPX D Adieresis -40
+KPX D Agrave -40
+KPX D Aring -40
+KPX D Atilde -40
+KPX D J -9
+KPX D T -36
+KPX D V -37
+KPX D W -19
+KPX D X -43
+KPX D Y -55
+KPX F A -64
+KPX F Aacute -64
+KPX F Acircumflex -64
+KPX F Adieresis -64
+KPX F Agrave -64
+KPX F Aring -64
+KPX F Atilde -64
+KPX F J -59
+KPX F O -22
+KPX F Odieresis -22
+KPX F a -32
+KPX F aacute -32
+KPX F adieresis -32
+KPX F ae -32
+KPX F aring -32
+KPX F comma -107
+KPX F e -26
+KPX F eacute -26
+KPX F hyphen -18
+KPX F i -15
+KPX F j -15
+KPX F o -26
+KPX F oacute -26
+KPX F odieresis -26
+KPX F oe -24
+KPX F oslash -24
+KPX F period -107
+KPX F r -38
+KPX F u -34
+KPX G A -11
+KPX G AE -9
+KPX G Aacute -11
+KPX G Acircumflex -11
+KPX G Adieresis -11
+KPX G Agrave -11
+KPX G Aring -11
+KPX G Atilde -11
+KPX G T -38
+KPX G V -40
+KPX G W -23
+KPX G Y -58
+KPX J A -30
+KPX J AE -29
+KPX J Adieresis -30
+KPX J Aring -30
+KPX K C -41
+KPX K G -45
+KPX K O -41
+KPX K OE -37
+KPX K Oacute -41
+KPX K Odieresis -41
+KPX K S -37
+KPX K T 15
+KPX K a -15
+KPX K adieresis -15
+KPX K ae -15
+KPX K aring -15
+KPX K e -35
+KPX K hyphen -43
+KPX K o -36
+KPX K oacute -36
+KPX K odieresis -36
+KPX K u -29
+KPX K udieresis -29
+KPX K y -59
+KPX L A 10
+KPX L AE 12
+KPX L Aacute 10
+KPX L Adieresis 10
+KPX L Aring 10
+KPX L C -36
+KPX L Ccedilla -39
+KPX L G -40
+KPX L O -38
+KPX L Oacute -38
+KPX L Ocircumflex -38
+KPX L Odieresis -38
+KPX L Ograve -38
+KPX L Otilde -38
+KPX L S -20
+KPX L T -87
+KPX L U -34
+KPX L Udieresis -34
+KPX L V -87
+KPX L W -58
+KPX L Y -99
+KPX L hyphen -114
+KPX L quotedblright -108
+KPX L quoteright -120
+KPX L u -16
+KPX L udieresis -16
+KPX L y -53
+KPX N A -12
+KPX N AE -10
+KPX N Aacute -12
+KPX N Adieresis -12
+KPX N Aring -12
+KPX N C -6
+KPX N Ccedilla -5
+KPX N G -10
+KPX N O -6
+KPX N Oacute -6
+KPX N Odieresis -6
+KPX N a -8
+KPX N aacute -8
+KPX N adieresis -8
+KPX N ae -8
+KPX N aring -8
+KPX N comma -10
+KPX N e -5
+KPX N eacute -5
+KPX N o -6
+KPX N oacute -6
+KPX N odieresis -6
+KPX N oslash -1
+KPX N period -10
+KPX N u -5
+KPX N udieresis -5
+KPX O A -36
+KPX O AE -36
+KPX O Aacute -36
+KPX O Adieresis -36
+KPX O Aring -36
+KPX O T -34
+KPX O V -34
+KPX O W -16
+KPX O X -39
+KPX O Y -53
+KPX Oacute A -36
+KPX Oacute T -34
+KPX Oacute V -34
+KPX Oacute W -16
+KPX Oacute Y -53
+KPX Ocircumflex T -34
+KPX Ocircumflex V -34
+KPX Ocircumflex Y -53
+KPX Odieresis A -36
+KPX Odieresis T -34
+KPX Odieresis V -34
+KPX Odieresis W -16
+KPX Odieresis X -39
+KPX Odieresis Y -53
+KPX Ograve T -34
+KPX Ograve V -34
+KPX Ograve Y -53
+KPX Oslash A -33
+KPX Otilde T -34
+KPX Otilde V -34
+KPX Otilde Y -53
+KPX P A -70
+KPX P AE -72
+KPX P Aacute -70
+KPX P Adieresis -70
+KPX P Aring -70
+KPX P J -78
+KPX P a -27
+KPX P aacute -27
+KPX P adieresis -27
+KPX P ae -27
+KPX P aring -27
+KPX P comma -126
+KPX P e -30
+KPX P eacute -30
+KPX P hyphen -35
+KPX P o -31
+KPX P oacute -31
+KPX P odieresis -31
+KPX P oe -29
+KPX P oslash -29
+KPX P period -126
+KPX R C -11
+KPX R Ccedilla -10
+KPX R G -15
+KPX R O -11
+KPX R OE -7
+KPX R Oacute -11
+KPX R Odieresis -11
+KPX R T -19
+KPX R U -13
+KPX R Udieresis -13
+KPX R V -33
+KPX R W -17
+KPX R Y -39
+KPX R a -11
+KPX R aacute -11
+KPX R adieresis -11
+KPX R ae -11
+KPX R aring -11
+KPX R e -9
+KPX R eacute -9
+KPX R hyphen 0
+KPX R o -10
+KPX R oacute -10
+KPX R odieresis -10
+KPX R oe -9
+KPX R u -8
+KPX R uacute -9
+KPX R udieresis -9
+KPX R y -10
+KPX S A -22
+KPX S AE -21
+KPX S Aacute -22
+KPX S Adieresis -22
+KPX S Aring -22
+KPX S T -22
+KPX S V -36
+KPX S W -20
+KPX S Y -42
+KPX S t -10
+KPX T A -86
+KPX T AE -84
+KPX T Aacute -86
+KPX T Acircumflex -86
+KPX T Adieresis -86
+KPX T Agrave -86
+KPX T Aring -86
+KPX T Atilde -86
+KPX T C -33
+KPX T G -39
+KPX T J -88
+KPX T O -34
+KPX T OE -28
+KPX T Oacute -34
+KPX T Ocircumflex -34
+KPX T Odieresis -34
+KPX T Ograve -34
+KPX T Oslash -35
+KPX T Otilde -34
+KPX T S -23
+KPX T V 7
+KPX T W 10
+KPX T Y 9
+KPX T a -83
+KPX T ae -83
+KPX T c -76
+KPX T colon -106
+KPX T comma -84
+KPX T e -80
+KPX T g -78
+KPX T guillemotleft -104
+KPX T guilsinglleft -100
+KPX T hyphen -65
+KPX T i -9
+KPX T j -9
+KPX T o -81
+KPX T oslash -76
+KPX T period -84
+KPX T r -81
+KPX T s -78
+KPX T semicolon -102
+KPX T u -79
+KPX T v -87
+KPX T w -85
+KPX T y -88
+KPX U A -37
+KPX U AE -38
+KPX U Aacute -37
+KPX U Acircumflex -37
+KPX U Adieresis -37
+KPX U Aring -37
+KPX U Atilde -37
+KPX U comma -30
+KPX U m -9
+KPX U n -9
+KPX U p -7
+KPX U period -27
+KPX U r -14
+KPX Uacute A -37
+KPX Uacute comma -30
+KPX Uacute m -9
+KPX Uacute n -9
+KPX Uacute p -7
+KPX Uacute period -27
+KPX Uacute r -14
+KPX Ucircumflex A -37
+KPX Udieresis A -37
+KPX Udieresis b -7
+KPX Udieresis comma -30
+KPX Udieresis m -9
+KPX Udieresis n -9
+KPX Udieresis p -7
+KPX Udieresis period -27
+KPX Udieresis r -14
+KPX Ugrave A -37
+KPX V A -63
+KPX V AE -64
+KPX V Aacute -63
+KPX V Acircumflex -63
+KPX V Adieresis -63
+KPX V Agrave -63
+KPX V Aring -63
+KPX V Atilde -63
+KPX V C -36
+KPX V G -39
+KPX V O -35
+KPX V Oacute -35
+KPX V Ocircumflex -35
+KPX V Odieresis -35
+KPX V Ograve -35
+KPX V Oslash -33
+KPX V Otilde -35
+KPX V S -33
+KPX V T 12
+KPX V a -52
+KPX V ae -52
+KPX V colon -48
+KPX V comma -77
+KPX V e -49
+KPX V g -47
+KPX V guillemotleft -72
+KPX V guilsinglleft -68
+KPX V hyphen -34
+KPX V i -10
+KPX V o -51
+KPX V oslash -45
+KPX V period -77
+KPX V r -43
+KPX V semicolon -48
+KPX V u -40
+KPX V y -19
+KPX W A -46
+KPX W AE -47
+KPX W Aacute -46
+KPX W Acircumflex -46
+KPX W Adieresis -46
+KPX W Agrave -46
+KPX W Aring -46
+KPX W Atilde -46
+KPX W C -20
+KPX W G -23
+KPX W O -20
+KPX W Oacute -20
+KPX W Ocircumflex -20
+KPX W Odieresis -20
+KPX W Ograve -20
+KPX W Oslash -17
+KPX W Otilde -20
+KPX W S -25
+KPX W T 13
+KPX W a -32
+KPX W ae -32
+KPX W colon -38
+KPX W comma -50
+KPX W e -29
+KPX W g -27
+KPX W guillemotleft -52
+KPX W guilsinglleft -48
+KPX W hyphen -14
+KPX W i -9
+KPX W o -31
+KPX W oslash -25
+KPX W period -50
+KPX W r -30
+KPX W semicolon -38
+KPX W u -28
+KPX W y -10
+KPX X C -37
+KPX X O -37
+KPX X Odieresis -37
+KPX X Q -37
+KPX X a -20
+KPX X e -40
+KPX X hyphen -45
+KPX X o -41
+KPX X u -35
+KPX X y -50
+KPX Y A -85
+KPX Y AE -86
+KPX Y Aacute -85
+KPX Y Acircumflex -85
+KPX Y Adieresis -85
+KPX Y Agrave -85
+KPX Y Aring -85
+KPX Y Atilde -85
+KPX Y C -48
+KPX Y G -53
+KPX Y O -48
+KPX Y Oacute -48
+KPX Y Ocircumflex -48
+KPX Y Odieresis -48
+KPX Y Ograve -48
+KPX Y Oslash -50
+KPX Y Otilde -48
+KPX Y S -39
+KPX Y T 14
+KPX Y a -78
+KPX Y ae -79
+KPX Y colon -67
+KPX Y comma -95
+KPX Y e -77
+KPX Y g -75
+KPX Y guillemotleft -106
+KPX Y guilsinglleft -102
+KPX Y hyphen -72
+KPX Y i -8
+KPX Y o -78
+KPX Y oslash -72
+KPX Y p -53
+KPX Y period -95
+KPX Y semicolon -67
+KPX Y u -60
+KPX Y v -38
+KPX Z v -32
+KPX Z y -33
+KPX a j -9
+KPX a quoteright -13
+KPX a v -21
+KPX a w -16
+KPX a y -24
+KPX aacute v -22
+KPX aacute w -17
+KPX aacute y -24
+KPX adieresis v -21
+KPX adieresis w -16
+KPX adieresis y -24
+KPX ae v -18
+KPX ae w -13
+KPX ae y -23
+KPX agrave v -21
+KPX agrave w -16
+KPX agrave y -24
+KPX aring v -21
+KPX aring w -16
+KPX aring y -24
+KPX b v -15
+KPX b w -9
+KPX b y -19
+KPX c h -3
+KPX c k -4
+KPX comma one -88
+KPX comma quotedblright -27
+KPX comma quoteright -38
+KPX e quoteright -8
+KPX e t -12
+KPX e v -18
+KPX e w -12
+KPX e x -22
+KPX e y -22
+KPX eacute v -18
+KPX eacute w -13
+KPX eacute y -22
+KPX ecircumflex v -18
+KPX ecircumflex w -12
+KPX ecircumflex y -22
+KPX eight four -1
+KPX eight one -43
+KPX eight seven -24
+KPX f a -14
+KPX f aacute -14
+KPX f adieresis -14
+KPX f ae -14
+KPX f aring -14
+KPX f e -16
+KPX f eacute -16
+KPX f f 11
+KPX f i -10
+KPX f j -10
+KPX f l -10
+KPX f o -17
+KPX f oacute -17
+KPX f odieresis -17
+KPX f oe -15
+KPX f oslash -11
+KPX f quoteright 1
+KPX f s -10
+KPX f t 11
+KPX five four -3
+KPX five one -63
+KPX five seven -23
+KPX four four 1
+KPX four one -72
+KPX four seven -47
+KPX g a -5
+KPX g adieresis -5
+KPX g ae -5
+KPX g aring -5
+KPX g e -3
+KPX g eacute -3
+KPX g l 0
+KPX g oacute -3
+KPX g odieresis -3
+KPX g r -3
+KPX guillemotright A -47
+KPX guillemotright AE -47
+KPX guillemotright Aacute -47
+KPX guillemotright Adieresis -47
+KPX guillemotright Aring -47
+KPX guillemotright T -104
+KPX guillemotright V -72
+KPX guillemotright W -50
+KPX guillemotright Y -107
+KPX guilsinglright A -43
+KPX guilsinglright AE -44
+KPX guilsinglright Aacute -43
+KPX guilsinglright Adieresis -43
+KPX guilsinglright Aring -43
+KPX guilsinglright T -100
+KPX guilsinglright V -68
+KPX guilsinglright W -46
+KPX guilsinglright Y -103
+KPX h quoteright -7
+KPX h y -18
+KPX hyphen A -8
+KPX hyphen AE -8
+KPX hyphen Aacute -8
+KPX hyphen Adieresis -8
+KPX hyphen Aring -8
+KPX hyphen T -65
+KPX hyphen V -34
+KPX hyphen W -13
+KPX hyphen Y -72
+KPX i T -9
+KPX i j -3
+KPX k a -12
+KPX k aacute -12
+KPX k adieresis -12
+KPX k ae -12
+KPX k aring -12
+KPX k comma -5
+KPX k e -21
+KPX k eacute -21
+KPX k g -20
+KPX k hyphen -35
+KPX k o -23
+KPX k oacute -23
+KPX k odieresis -23
+KPX k period -4
+KPX k s -16
+KPX k u -8
+KPX k udieresis -8
+KPX l v -9
+KPX l y -10
+KPX m p 0
+KPX m v -15
+KPX m w -10
+KPX m y -18
+KPX n T -79
+KPX n p -1
+KPX n quoteright -7
+KPX n v -16
+KPX n w -11
+KPX n y -18
+KPX nine four -6
+KPX nine one -40
+KPX nine seven -27
+KPX o T -80
+KPX o quoteright -10
+KPX o t -10
+KPX o v -16
+KPX o w -10
+KPX o x -20
+KPX o y -20
+KPX oacute v -16
+KPX oacute w -10
+KPX oacute y -20
+KPX ocircumflex t -10
+KPX odieresis t -10
+KPX odieresis v -16
+KPX odieresis w -10
+KPX odieresis x -20
+KPX odieresis y -20
+KPX ograve v -16
+KPX ograve w -10
+KPX ograve y -20
+KPX one comma -59
+KPX one eight -53
+KPX one five -53
+KPX one four -65
+KPX one nine -54
+KPX one one -96
+KPX one period -59
+KPX one seven -71
+KPX one six -51
+KPX one three -57
+KPX one two -57
+KPX one zero -51
+KPX p t -9
+KPX p y -19
+KPX period one -88
+KPX period quotedblright -28
+KPX period quoteright -39
+KPX q c 0
+KPX q u -3
+KPX quotedblbase A 18
+KPX quotedblbase AE 19
+KPX quotedblbase T -65
+KPX quotedblbase V -58
+KPX quotedblbase W -30
+KPX quotedblbase Y -76
+KPX quotedblleft A -46
+KPX quotedblleft AE -49
+KPX quotedblleft Aacute -46
+KPX quotedblleft Adieresis -46
+KPX quotedblleft Aring -46
+KPX quotedblleft T 9
+KPX quotedblleft V 18
+KPX quotedblleft W 26
+KPX quotedblleft Y 7
+KPX quotedblright A -54
+KPX quotedblright AE -56
+KPX quotedblright Aacute -54
+KPX quotedblright Adieresis -54
+KPX quotedblright Aring -54
+KPX quotedblright T 3
+KPX quotedblright V 11
+KPX quotedblright W 18
+KPX quotedblright Y 0
+KPX quoteleft A -57
+KPX quoteleft AE -60
+KPX quoteleft Aacute -57
+KPX quoteleft Adieresis -57
+KPX quoteleft Aring -57
+KPX quoteleft T -2
+KPX quoteleft V 7
+KPX quoteleft W 15
+KPX quoteleft Y -4
+KPX quoteright A -65
+KPX quoteright AE -67
+KPX quoteright Aacute -65
+KPX quoteright Adieresis -65
+KPX quoteright Aring -65
+KPX quoteright comma -52
+KPX quoteright d -20
+KPX quoteright o -29
+KPX quoteright period -52
+KPX quoteright r -19
+KPX quoteright s -17
+KPX quoteright t -9
+KPX quoteright v -3
+KPX quoteright w -3
+KPX quoteright y -4
+KPX r a -9
+KPX r aacute -9
+KPX r acircumflex -9
+KPX r adieresis -9
+KPX r ae -9
+KPX r agrave -9
+KPX r aring -9
+KPX r c -11
+KPX r ccedilla -8
+KPX r colon -12
+KPX r comma -52
+KPX r d -9
+KPX r e -15
+KPX r eacute -15
+KPX r ecircumflex -15
+KPX r egrave -15
+KPX r f 17
+KPX r g -8
+KPX r h -4
+KPX r hyphen -34
+KPX r i -5
+KPX r j -5
+KPX r k -5
+KPX r l -5
+KPX r m -4
+KPX r n -4
+KPX r o -18
+KPX r oacute -18
+KPX r ocircumflex -18
+KPX r odieresis -18
+KPX r oe -15
+KPX r ograve -18
+KPX r oslash -15
+KPX r p -1
+KPX r period -52
+KPX r q -9
+KPX r quoteright 3
+KPX r r -9
+KPX r s -4
+KPX r semicolon -12
+KPX r t 17
+KPX r u -5
+KPX r v 17
+KPX r w 15
+KPX r x 12
+KPX r y 16
+KPX r z 0
+KPX s quoteright -6
+KPX s t -11
+KPX seven colon -55
+KPX seven comma -99
+KPX seven eight -24
+KPX seven five -30
+KPX seven four -77
+KPX seven one -42
+KPX seven period -99
+KPX seven seven -3
+KPX seven six -32
+KPX seven three -22
+KPX seven two -22
+KPX six four -1
+KPX six one -39
+KPX six seven -21
+KPX t S -14
+KPX t a -5
+KPX t aacute -5
+KPX t adieresis -5
+KPX t ae -5
+KPX t aring -5
+KPX t colon -19
+KPX t e -12
+KPX t eacute -12
+KPX t h -6
+KPX t o -13
+KPX t oacute -13
+KPX t odieresis -13
+KPX t quoteright 2
+KPX t semicolon -19
+KPX three four 0
+KPX three one -41
+KPX three seven -23
+KPX two four -46
+KPX two one -37
+KPX two seven -21
+KPX u quoteright 0
+KPX v a -20
+KPX v aacute -20
+KPX v acircumflex -20
+KPX v adieresis -20
+KPX v ae -20
+KPX v agrave -20
+KPX v aring -20
+KPX v atilde -20
+KPX v c -15
+KPX v colon -14
+KPX v comma -54
+KPX v e -19
+KPX v eacute -19
+KPX v ecircumflex -19
+KPX v egrave -19
+KPX v g -17
+KPX v hyphen -7
+KPX v l -7
+KPX v o -20
+KPX v oacute -20
+KPX v odieresis -20
+KPX v ograve -20
+KPX v oslash -16
+KPX v period -54
+KPX v s -15
+KPX v semicolon -14
+KPX w a -16
+KPX w aacute -16
+KPX w acircumflex -16
+KPX w adieresis -16
+KPX w ae -16
+KPX w agrave -16
+KPX w aring -16
+KPX w atilde -16
+KPX w c -8
+KPX w colon -16
+KPX w comma -40
+KPX w e -12
+KPX w eacute -12
+KPX w ecircumflex -12
+KPX w egrave -12
+KPX w g -10
+KPX w hyphen 0
+KPX w l -9
+KPX w o -13
+KPX w oacute -13
+KPX w odieresis -13
+KPX w ograve -13
+KPX w oslash -8
+KPX w period -40
+KPX w s -11
+KPX w semicolon -16
+KPX x a -17
+KPX x c -16
+KPX x e -20
+KPX x eacute -20
+KPX x o -21
+KPX x q -17
+KPX y a -21
+KPX y aacute -21
+KPX y acircumflex -21
+KPX y adieresis -21
+KPX y ae -21
+KPX y agrave -21
+KPX y aring -21
+KPX y atilde -21
+KPX y c -16
+KPX y colon -15
+KPX y comma -54
+KPX y e -20
+KPX y eacute -20
+KPX y ecircumflex -20
+KPX y egrave -20
+KPX y g -18
+KPX y hyphen -6
+KPX y l -8
+KPX y o -21
+KPX y oacute -21
+KPX y odieresis -21
+KPX y ograve -21
+KPX y oslash -16
+KPX y period -53
+KPX y s -16
+KPX y semicolon -15
+KPX zero four -2
+KPX zero one -40
+KPX zero seven -28
+EndKernPairs
+EndKernData
+EndFontMetrics
diff --git a/misc/gs_afm/TimesBo.afm b/misc/gs_afm/TimesBo.afm
new file mode 100644
index 0000000000..1947d3ab1d
--- /dev/null
+++ b/misc/gs_afm/TimesBo.afm
@@ -0,0 +1,1257 @@
+StartFontMetrics 3.0
+Comment Copyright URW Software, Copyright 1994 by URW
+Comment Creation Date: 11/17/1994
+Comment See the file PUBLIC (Aladdin Free Public License) for license conditions.
+FontName NimbusRomNo9L-Medi
+FullName Nimbus Roman No9 L Medium
+FamilyName Nimbus Roman No9 L
+Weight Bold
+ItalicAngle 0.0
+IsFixedPitch false
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.005
+Notice URW Software, Copyright 1994 by URW
+EncodingScheme AdobeStandardEncoding
+FontBBox -168 -218 1000 948
+CapHeight 676
+XHeight 461
+Descender -205
+Ascender 676
+StartCharMetrics 232
+C 32 ; WX 250 ; N space ; B 125 0 125 0 ;
+C 33 ; WX 333 ; N exclam ; B 81 -13 251 691 ;
+C 34 ; WX 555 ; N quotedbl ; B 83 404 472 691 ;
+C 35 ; WX 500 ; N numbersign ; B 4 0 496 700 ;
+C 36 ; WX 500 ; N dollar ; B 29 -99 472 750 ;
+C 37 ; WX 1000 ; N percent ; B 124 -14 877 692 ;
+C 38 ; WX 833 ; N ampersand ; B 62 -16 787 691 ;
+C 39 ; WX 333 ; N quoteright ; B 79 356 263 691 ;
+C 40 ; WX 333 ; N parenleft ; B 46 -168 306 694 ;
+C 41 ; WX 333 ; N parenright ; B 27 -168 287 694 ;
+C 42 ; WX 500 ; N asterisk ; B 56 255 447 691 ;
+C 43 ; WX 570 ; N plus ; B 33 0 537 506 ;
+C 44 ; WX 250 ; N comma ; B 39 -180 223 155 ;
+C 45 ; WX 333 ; N hyphen ; B 44 171 287 287 ;
+C 46 ; WX 250 ; N period ; B 41 -13 210 156 ;
+C 47 ; WX 278 ; N slash ; B -24 -19 302 691 ;
+C 48 ; WX 500 ; N zero ; B 24 -13 476 688 ;
+C 49 ; WX 500 ; N one ; B 65 0 442 688 ;
+C 50 ; WX 500 ; N two ; B 17 0 478 688 ;
+C 51 ; WX 500 ; N three ; B 16 -14 468 688 ;
+C 52 ; WX 500 ; N four ; B 19 0 475 688 ;
+C 53 ; WX 500 ; N five ; B 22 -8 470 676 ;
+C 54 ; WX 500 ; N six ; B 28 -13 475 688 ;
+C 55 ; WX 500 ; N seven ; B 17 0 477 676 ;
+C 56 ; WX 500 ; N eight ; B 28 -13 472 688 ;
+C 57 ; WX 500 ; N nine ; B 26 -13 473 688 ;
+C 58 ; WX 333 ; N colon ; B 82 -13 251 472 ;
+C 59 ; WX 333 ; N semicolon ; B 82 -180 266 472 ;
+C 60 ; WX 570 ; N less ; B 31 -12 539 518 ;
+C 61 ; WX 570 ; N equal ; B 33 107 537 399 ;
+C 62 ; WX 570 ; N greater ; B 31 -12 539 518 ;
+C 63 ; WX 500 ; N question ; B 57 -13 445 689 ;
+C 64 ; WX 930 ; N at ; B 108 -19 822 691 ;
+C 65 ; WX 722 ; N A ; B 9 0 689 690 ;
+C 66 ; WX 667 ; N B ; B 16 0 619 676 ;
+C 67 ; WX 722 ; N C ; B 49 -19 687 691 ;
+C 68 ; WX 722 ; N D ; B 14 0 690 676 ;
+C 69 ; WX 667 ; N E ; B 16 0 641 676 ;
+C 70 ; WX 611 ; N F ; B 16 0 583 676 ;
+C 71 ; WX 778 ; N G ; B 37 -19 755 691 ;
+C 72 ; WX 778 ; N H ; B 21 0 759 676 ;
+C 73 ; WX 389 ; N I ; B 20 0 370 676 ;
+C 74 ; WX 500 ; N J ; B 3 -96 479 676 ;
+C 75 ; WX 778 ; N K ; B 30 0 769 676 ;
+C 76 ; WX 667 ; N L ; B 19 0 638 676 ;
+C 77 ; WX 944 ; N M ; B 14 0 921 676 ;
+C 78 ; WX 722 ; N N ; B 16 -18 701 676 ;
+C 79 ; WX 778 ; N O ; B 35 -19 743 691 ;
+C 80 ; WX 611 ; N P ; B 16 0 600 676 ;
+C 81 ; WX 778 ; N Q ; B 35 -176 743 691 ;
+C 82 ; WX 722 ; N R ; B 26 0 715 676 ;
+C 83 ; WX 556 ; N S ; B 35 -19 513 692 ;
+C 84 ; WX 667 ; N T ; B 31 0 636 676 ;
+C 85 ; WX 722 ; N U ; B 16 -19 701 676 ;
+C 86 ; WX 722 ; N V ; B 16 -18 701 676 ;
+C 87 ; WX 1000 ; N W ; B 19 -15 981 676 ;
+C 88 ; WX 722 ; N X ; B 16 0 699 676 ;
+C 89 ; WX 722 ; N Y ; B 15 0 699 676 ;
+C 90 ; WX 667 ; N Z ; B 28 0 634 676 ;
+C 91 ; WX 333 ; N bracketleft ; B 67 -149 301 678 ;
+C 92 ; WX 278 ; N backslash ; B -25 -19 303 691 ;
+C 93 ; WX 333 ; N bracketright ; B 32 -149 266 678 ;
+C 94 ; WX 581 ; N asciicircum ; B 73 311 509 676 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 333 ; N quoteleft ; B 70 356 254 691 ;
+C 97 ; WX 500 ; N a ; B 25 -14 488 473 ;
+C 98 ; WX 556 ; N b ; B 17 -14 521 676 ;
+C 99 ; WX 444 ; N c ; B 25 -14 430 473 ;
+C 100 ; WX 556 ; N d ; B 25 -14 534 676 ;
+C 101 ; WX 444 ; N e ; B 25 -14 426 473 ;
+C 102 ; WX 333 ; N f ; B 14 0 389 691 ;
+C 103 ; WX 500 ; N g ; B 28 -206 483 473 ;
+C 104 ; WX 556 ; N h ; B 16 0 534 676 ;
+C 105 ; WX 278 ; N i ; B 16 0 255 691 ;
+C 106 ; WX 333 ; N j ; B -57 -203 263 691 ;
+C 107 ; WX 556 ; N k ; B 22 0 543 676 ;
+C 108 ; WX 278 ; N l ; B 16 0 255 676 ;
+C 109 ; WX 833 ; N m ; B 16 0 814 473 ;
+C 110 ; WX 556 ; N n ; B 21 0 539 473 ;
+C 111 ; WX 500 ; N o ; B 25 -14 476 473 ;
+C 112 ; WX 556 ; N p ; B 19 -205 524 473 ;
+C 113 ; WX 556 ; N q ; B 34 -205 536 473 ;
+C 114 ; WX 444 ; N r ; B 29 0 434 473 ;
+C 115 ; WX 389 ; N s ; B 25 -14 361 473 ;
+C 116 ; WX 333 ; N t ; B 20 -12 332 630 ;
+C 117 ; WX 556 ; N u ; B 16 -14 537 461 ;
+C 118 ; WX 500 ; N v ; B 21 -14 485 461 ;
+C 119 ; WX 722 ; N w ; B 23 -14 707 461 ;
+C 120 ; WX 500 ; N x ; B 12 0 484 461 ;
+C 121 ; WX 500 ; N y ; B 16 -205 480 461 ;
+C 122 ; WX 444 ; N z ; B 21 0 420 461 ;
+C 123 ; WX 394 ; N braceleft ; B 22 -175 340 698 ;
+C 124 ; WX 220 ; N bar ; B 66 -19 154 691 ;
+C 125 ; WX 394 ; N braceright ; B 54 -175 372 698 ;
+C 126 ; WX 520 ; N asciitilde ; B 29 175 491 331 ;
+C 161 ; WX 333 ; N exclamdown ; B 82 -203 252 501 ;
+C 162 ; WX 500 ; N cent ; B 53 -140 458 588 ;
+C 163 ; WX 500 ; N sterling ; B 21 -14 477 684 ;
+C 164 ; WX 167 ; N fraction ; B -168 -12 329 688 ;
+C 165 ; WX 500 ; N yen ; B -64 0 547 676 ;
+C 166 ; WX 500 ; N florin ; B 0 -155 498 706 ;
+C 167 ; WX 500 ; N section ; B 57 -132 443 691 ;
+C 168 ; WX 500 ; N currency ; B -26 61 526 613 ;
+C 169 ; WX 278 ; N quotesingle ; B 75 404 204 691 ;
+C 170 ; WX 500 ; N quotedblleft ; B 32 356 486 691 ;
+C 171 ; WX 500 ; N guillemotleft ; B 23 36 473 415 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 51 36 305 415 ;
+C 173 ; WX 333 ; N guilsinglright ; B 28 36 282 415 ;
+C 174 ; WX 556 ; N fi ; B 14 0 536 691 ;
+C 175 ; WX 556 ; N fl ; B 14 0 536 691 ;
+C 177 ; WX 500 ; N endash ; B 0 181 500 271 ;
+C 178 ; WX 500 ; N dagger ; B 47 -134 453 691 ;
+C 179 ; WX 500 ; N daggerdbl ; B 45 -132 456 691 ;
+C 180 ; WX 250 ; N periodcentered ; B 41 248 210 417 ;
+C 182 ; WX 540 ; N paragraph ; B 0 -186 519 676 ;
+C 183 ; WX 350 ; N bullet ; B 35 198 315 478 ;
+C 184 ; WX 333 ; N quotesinglbase ; B 79 -180 263 155 ;
+C 185 ; WX 500 ; N quotedblbase ; B 14 -180 468 155 ;
+C 186 ; WX 500 ; N quotedblright ; B 14 356 468 691 ;
+C 187 ; WX 500 ; N guillemotright ; B 27 36 477 415 ;
+C 188 ; WX 1000 ; N ellipsis ; B 82 -13 917 156 ;
+C 189 ; WX 1000 ; N perthousand ; B 7 -29 995 706 ;
+C 191 ; WX 500 ; N questiondown ; B 55 -201 443 501 ;
+C 193 ; WX 333 ; N grave ; B 8 528 246 713 ;
+C 194 ; WX 333 ; N acute ; B 86 528 324 713 ;
+C 195 ; WX 333 ; N circumflex ; B -2 528 335 704 ;
+C 196 ; WX 333 ; N tilde ; B -16 547 349 674 ;
+C 197 ; WX 333 ; N macron ; B 1 565 331 637 ;
+C 198 ; WX 333 ; N breve ; B 15 528 318 691 ;
+C 199 ; WX 333 ; N dotaccent ; B 103 537 232 666 ;
+C 200 ; WX 333 ; N dieresis ; B -2 537 337 666 ;
+C 202 ; WX 333 ; N ring ; B 60 537 273 750 ;
+C 203 ; WX 333 ; N cedilla ; B 68 -218 294 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B -13 528 425 713 ;
+C 206 ; WX 333 ; N ogonek ; B 90 -173 319 44 ;
+C 207 ; WX 333 ; N caron ; B -2 528 335 704 ;
+C 208 ; WX 1000 ; N emdash ; B 0 181 1000 271 ;
+C 225 ; WX 1000 ; N AE ; B 4 0 951 676 ;
+C 227 ; WX 300 ; N ordfeminine ; B -1 397 301 688 ;
+C 232 ; WX 667 ; N Lslash ; B 19 0 638 676 ;
+C 233 ; WX 778 ; N Oslash ; B 35 -74 743 737 ;
+C 234 ; WX 1000 ; N OE ; B 22 -5 981 684 ;
+C 235 ; WX 330 ; N ordmasculine ; B 18 397 312 688 ;
+C 241 ; WX 722 ; N ae ; B 33 -14 693 473 ;
+C 245 ; WX 278 ; N dotlessi ; B 16 0 255 461 ;
+C 248 ; WX 278 ; N lslash ; B -22 0 303 676 ;
+C 249 ; WX 500 ; N oslash ; B 25 -92 476 549 ;
+C 250 ; WX 722 ; N oe ; B 22 -14 696 473 ;
+C 251 ; WX 556 ; N germandbls ; B 19 -12 517 691 ;
+C -1 ; WX 722 ; N Yacute ; B 15 0 699 923 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 16 -19 701 914 ;
+C -1 ; WX 722 ; N Ugrave ; B 16 -19 701 923 ;
+C -1 ; WX 667 ; N Zcaron ; B 28 0 634 914 ;
+C -1 ; WX 722 ; N Ydieresis ; B 15 0 699 876 ;
+C -1 ; WX 300 ; N threesuperior ; B 3 268 297 688 ;
+C -1 ; WX 722 ; N Uacute ; B 16 -19 701 923 ;
+C -1 ; WX 300 ; N twosuperior ; B 0 275 300 688 ;
+C -1 ; WX 722 ; N Udieresis ; B 16 -19 701 876 ;
+C -1 ; WX 250 ; N middot ; B 41 248 210 417 ;
+C -1 ; WX 300 ; N onesuperior ; B 28 275 273 688 ;
+C -1 ; WX 500 ; N aacute ; B 25 -14 488 713 ;
+C -1 ; WX 500 ; N agrave ; B 25 -14 488 713 ;
+C -1 ; WX 500 ; N acircumflex ; B 25 -14 488 704 ;
+C -1 ; WX 556 ; N Scaron ; B 35 -19 513 914 ;
+C -1 ; WX 778 ; N Otilde ; B 35 -19 743 884 ;
+C -1 ; WX 333 ; N sfthyphen ; B 44 171 287 287 ;
+C -1 ; WX 500 ; N atilde ; B 25 -14 488 674 ;
+C -1 ; WX 500 ; N aring ; B 25 -14 488 750 ;
+C -1 ; WX 500 ; N adieresis ; B 25 -14 488 666 ;
+C -1 ; WX 778 ; N Ograve ; B 35 -19 743 923 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 35 -19 743 914 ;
+C -1 ; WX 778 ; N Odieresis ; B 35 -19 743 876 ;
+C -1 ; WX 722 ; N Ntilde ; B 16 -18 701 884 ;
+C -1 ; WX 444 ; N edieresis ; B 25 -14 426 666 ;
+C -1 ; WX 444 ; N eacute ; B 25 -14 426 713 ;
+C -1 ; WX 444 ; N egrave ; B 25 -14 426 713 ;
+C -1 ; WX 389 ; N Icircumflex ; B 20 0 370 914 ;
+C -1 ; WX 444 ; N ecircumflex ; B 25 -14 426 704 ;
+C -1 ; WX 389 ; N Igrave ; B 20 0 370 923 ;
+C -1 ; WX 389 ; N Iacute ; B 20 0 370 923 ;
+C -1 ; WX 389 ; N Idieresis ; B 20 0 370 876 ;
+C -1 ; WX 400 ; N degree ; B 57 402 343 688 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 16 0 641 914 ;
+C -1 ; WX 570 ; N minus ; B 33 209 537 297 ;
+C -1 ; WX 570 ; N multiply ; B 48 16 522 490 ;
+C -1 ; WX 570 ; N divide ; B 33 -31 537 537 ;
+C -1 ; WX 667 ; N Egrave ; B 16 0 641 923 ;
+C -1 ; WX 1000 ; N trademark ; B 24 271 977 676 ;
+C -1 ; WX 778 ; N Oacute ; B 35 -19 743 923 ;
+C -1 ; WX 556 ; N thorn ; B 19 -205 524 676 ;
+C -1 ; WX 500 ; N eth ; B 25 -14 476 691 ;
+C -1 ; WX 667 ; N Eacute ; B 16 0 641 923 ;
+C -1 ; WX 444 ; N ccedilla ; B 25 -218 430 473 ;
+C -1 ; WX 278 ; N idieresis ; B -36 0 303 666 ;
+C -1 ; WX 278 ; N iacute ; B 16 0 290 713 ;
+C -1 ; WX 278 ; N igrave ; B -26 0 255 713 ;
+C -1 ; WX 570 ; N plusminus ; B 33 0 537 568 ;
+C -1 ; WX 750 ; N onehalf ; B -7 -12 775 688 ;
+C -1 ; WX 750 ; N onequarter ; B 28 -12 743 688 ;
+C -1 ; WX 750 ; N threequarters ; B 23 -12 733 688 ;
+C -1 ; WX 278 ; N icircumflex ; B -36 0 301 704 ;
+C -1 ; WX 667 ; N Edieresis ; B 16 0 641 876 ;
+C -1 ; WX 556 ; N ntilde ; B 21 0 539 674 ;
+C -1 ; WX 722 ; N Aring ; B 9 0 689 948 ;
+C -1 ; WX 500 ; N odieresis ; B 25 -14 476 666 ;
+C -1 ; WX 500 ; N oacute ; B 25 -14 476 713 ;
+C -1 ; WX 500 ; N ograve ; B 25 -14 476 713 ;
+C -1 ; WX 500 ; N ocircumflex ; B 25 -14 476 704 ;
+C -1 ; WX 500 ; N otilde ; B 25 -14 476 674 ;
+C -1 ; WX 389 ; N scaron ; B 25 -14 363 704 ;
+C -1 ; WX 556 ; N udieresis ; B 16 -14 537 666 ;
+C -1 ; WX 556 ; N uacute ; B 16 -14 537 713 ;
+C -1 ; WX 556 ; N ugrave ; B 16 -14 537 713 ;
+C -1 ; WX 556 ; N ucircumflex ; B 16 -14 537 704 ;
+C -1 ; WX 500 ; N yacute ; B 16 -205 480 713 ;
+C -1 ; WX 444 ; N zcaron ; B 21 0 420 704 ;
+C -1 ; WX 500 ; N ydieresis ; B 16 -205 480 666 ;
+C -1 ; WX 747 ; N copyright ; B 26 -19 721 691 ;
+C -1 ; WX 747 ; N registered ; B 26 -19 721 691 ;
+C -1 ; WX 722 ; N Atilde ; B 9 0 689 884 ;
+C -1 ; WX 250 ; N nbspace ; B 125 0 125 0 ;
+C -1 ; WX 722 ; N Ccedilla ; B 49 -218 687 691 ;
+C -1 ; WX 722 ; N Acircumflex ; B 9 0 689 914 ;
+C -1 ; WX 722 ; N Agrave ; B 9 0 689 923 ;
+C -1 ; WX 570 ; N logicalnot ; B 33 108 537 399 ;
+C -1 ; WX 722 ; N Aacute ; B 9 0 689 923 ;
+C -1 ; WX 722 ; N Eth ; B 6 0 690 676 ;
+C -1 ; WX 220 ; N brokenbar ; B 66 -19 154 691 ;
+C -1 ; WX 611 ; N Thorn ; B 16 0 600 676 ;
+C -1 ; WX 722 ; N Adieresis ; B 9 0 689 876 ;
+C -1 ; WX 556 ; N mu ; B 33 -206 536 461 ;
+C -1 ; WX 250 ; N .notdef ; B 125 0 125 0 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 998
+KPX A C -73
+KPX A Ccedilla -78
+KPX A G -68
+KPX A O -68
+KPX A Odieresis -68
+KPX A Q -68
+KPX A T -59
+KPX A U -66
+KPX A Uacute -66
+KPX A Ucircumflex -66
+KPX A Udieresis -66
+KPX A Ugrave -66
+KPX A V -130
+KPX A W -116
+KPX A Y -74
+KPX A a -5
+KPX A b -22
+KPX A c -34
+KPX A ccedilla -43
+KPX A comma 1
+KPX A d -28
+KPX A e -32
+KPX A g -7
+KPX A guillemotleft -53
+KPX A guilsinglleft -67
+KPX A hyphen -30
+KPX A o -36
+KPX A period 0
+KPX A q -38
+KPX A quotedblright -76
+KPX A quoteright -108
+KPX A t -27
+KPX A u -30
+KPX A v -84
+KPX A w -80
+KPX A y -84
+KPX Aacute C -73
+KPX Aacute G -68
+KPX Aacute O -68
+KPX Aacute Q -68
+KPX Aacute T -59
+KPX Aacute U -66
+KPX Aacute V -130
+KPX Aacute W -116
+KPX Aacute Y -74
+KPX Aacute a -5
+KPX Aacute b -22
+KPX Aacute c -34
+KPX Aacute comma 1
+KPX Aacute d -28
+KPX Aacute e -32
+KPX Aacute g -7
+KPX Aacute guillemotleft -53
+KPX Aacute guilsinglleft -67
+KPX Aacute hyphen -30
+KPX Aacute o -36
+KPX Aacute period 0
+KPX Aacute q -38
+KPX Aacute quoteright -108
+KPX Aacute t -27
+KPX Aacute u -30
+KPX Aacute v -84
+KPX Aacute w -80
+KPX Aacute y -84
+KPX Acircumflex C -73
+KPX Acircumflex G -68
+KPX Acircumflex O -68
+KPX Acircumflex Q -68
+KPX Acircumflex T -59
+KPX Acircumflex U -66
+KPX Acircumflex V -130
+KPX Acircumflex W -116
+KPX Acircumflex Y -74
+KPX Acircumflex comma 1
+KPX Acircumflex period 0
+KPX Adieresis C -73
+KPX Adieresis G -68
+KPX Adieresis O -68
+KPX Adieresis Q -68
+KPX Adieresis T -59
+KPX Adieresis U -66
+KPX Adieresis V -130
+KPX Adieresis W -116
+KPX Adieresis Y -74
+KPX Adieresis a -5
+KPX Adieresis b -22
+KPX Adieresis c -34
+KPX Adieresis comma 1
+KPX Adieresis d -28
+KPX Adieresis g -7
+KPX Adieresis guillemotleft -53
+KPX Adieresis guilsinglleft -67
+KPX Adieresis hyphen -30
+KPX Adieresis o -36
+KPX Adieresis period 0
+KPX Adieresis q -38
+KPX Adieresis quotedblright -76
+KPX Adieresis quoteright -108
+KPX Adieresis t -27
+KPX Adieresis u -30
+KPX Adieresis v -84
+KPX Adieresis w -80
+KPX Adieresis y -84
+KPX Agrave C -73
+KPX Agrave G -68
+KPX Agrave O -68
+KPX Agrave Q -68
+KPX Agrave T -59
+KPX Agrave U -66
+KPX Agrave V -130
+KPX Agrave W -116
+KPX Agrave Y -74
+KPX Agrave comma 1
+KPX Agrave period 0
+KPX Aring C -73
+KPX Aring G -68
+KPX Aring O -68
+KPX Aring Q -68
+KPX Aring T -59
+KPX Aring U -66
+KPX Aring V -130
+KPX Aring W -116
+KPX Aring Y -74
+KPX Aring a -5
+KPX Aring b -22
+KPX Aring c -34
+KPX Aring comma 1
+KPX Aring d -28
+KPX Aring e -32
+KPX Aring g -7
+KPX Aring guillemotleft -53
+KPX Aring guilsinglleft -67
+KPX Aring hyphen -30
+KPX Aring o -36
+KPX Aring period 0
+KPX Aring q -38
+KPX Aring quotedblright -76
+KPX Aring quoteright -108
+KPX Aring t -27
+KPX Aring u -30
+KPX Aring v -84
+KPX Aring w -80
+KPX Aring y -84
+KPX Atilde C -73
+KPX Atilde G -68
+KPX Atilde O -68
+KPX Atilde Q -68
+KPX Atilde T -59
+KPX Atilde U -66
+KPX Atilde V -130
+KPX Atilde W -116
+KPX Atilde Y -74
+KPX Atilde comma 1
+KPX Atilde period 0
+KPX B A -34
+KPX B AE -32
+KPX B Aacute -34
+KPX B Acircumflex -34
+KPX B Adieresis -34
+KPX B Aring -34
+KPX B Atilde -34
+KPX B O -12
+KPX B OE -4
+KPX B Oacute -12
+KPX B Ocircumflex -12
+KPX B Odieresis -12
+KPX B Ograve -12
+KPX B Oslash -11
+KPX B V -45
+KPX B W -46
+KPX B Y -44
+KPX C A -25
+KPX C AE -22
+KPX C Aacute -25
+KPX C Adieresis -25
+KPX C Aring -25
+KPX C H -2
+KPX C K -6
+KPX C O -14
+KPX C Oacute -14
+KPX C Odieresis -14
+KPX Ccedilla A -33
+KPX D A -55
+KPX D Aacute -55
+KPX D Acircumflex -55
+KPX D Adieresis -55
+KPX D Agrave -55
+KPX D Aring -55
+KPX D Atilde -55
+KPX D J -38
+KPX D T -6
+KPX D V -60
+KPX D W -50
+KPX D X -50
+KPX D Y -59
+KPX F A -80
+KPX F Aacute -80
+KPX F Acircumflex -80
+KPX F Adieresis -80
+KPX F Agrave -80
+KPX F Aring -80
+KPX F Atilde -80
+KPX F J -42
+KPX F O -7
+KPX F Odieresis -7
+KPX F a -50
+KPX F aacute -50
+KPX F adieresis -22
+KPX F ae -53
+KPX F aring -50
+KPX F comma -59
+KPX F e -51
+KPX F eacute -51
+KPX F hyphen -34
+KPX F i -1
+KPX F j -26
+KPX F o -54
+KPX F oacute -54
+KPX F odieresis -25
+KPX F oe -52
+KPX F oslash -53
+KPX F period -60
+KPX F r -7
+KPX F u -10
+KPX G A -27
+KPX G AE -24
+KPX G Aacute -27
+KPX G Acircumflex -27
+KPX G Adieresis -27
+KPX G Agrave -27
+KPX G Aring -27
+KPX G Atilde -27
+KPX G T -41
+KPX G V -33
+KPX G W -35
+KPX G Y -33
+KPX J A -30
+KPX J AE -27
+KPX J Adieresis -30
+KPX J Aring -30
+KPX K C -61
+KPX K G -56
+KPX K O -56
+KPX K OE -45
+KPX K Oacute -56
+KPX K Odieresis -56
+KPX K S 13
+KPX K T -2
+KPX K a 6
+KPX K adieresis 6
+KPX K ae 3
+KPX K aring 6
+KPX K e -20
+KPX K hyphen -47
+KPX K o -24
+KPX K oacute -24
+KPX K odieresis -24
+KPX K u -18
+KPX K udieresis -18
+KPX K y -83
+KPX L A -1
+KPX L AE 1
+KPX L Aacute -1
+KPX L Adieresis -1
+KPX L Aring -1
+KPX L C -11
+KPX L Ccedilla -14
+KPX L G -5
+KPX L O -5
+KPX L Oacute -5
+KPX L Ocircumflex -5
+KPX L Odieresis -5
+KPX L Ograve -5
+KPX L Otilde -5
+KPX L S 2
+KPX L T -74
+KPX L U -29
+KPX L Udieresis -29
+KPX L V -106
+KPX L W -87
+KPX L Y -89
+KPX L hyphen 24
+KPX L quotedblright -37
+KPX L quoteright -69
+KPX L u -11
+KPX L udieresis -13
+KPX L y -49
+KPX N A -19
+KPX N AE -16
+KPX N Aacute -19
+KPX N Adieresis -19
+KPX N Aring -19
+KPX N C -22
+KPX N Ccedilla -22
+KPX N G -16
+KPX N O -15
+KPX N Oacute -15
+KPX N Odieresis -15
+KPX N a -16
+KPX N aacute -16
+KPX N adieresis -16
+KPX N ae -19
+KPX N aring -16
+KPX N comma 1
+KPX N e -14
+KPX N eacute -14
+KPX N o -16
+KPX N oacute -16
+KPX N odieresis -16
+KPX N oslash -15
+KPX N period 0
+KPX N u -17
+KPX N udieresis -17
+KPX O A -56
+KPX O AE -54
+KPX O Aacute -56
+KPX O Adieresis -56
+KPX O Aring -56
+KPX O T -9
+KPX O V -60
+KPX O W -54
+KPX O X -51
+KPX O Y -59
+KPX Oacute A -56
+KPX Oacute T -9
+KPX Oacute V -60
+KPX Oacute W -54
+KPX Oacute Y -59
+KPX Ocircumflex T -9
+KPX Ocircumflex V -60
+KPX Ocircumflex Y -59
+KPX Odieresis A -56
+KPX Odieresis T -9
+KPX Odieresis V -60
+KPX Odieresis W -54
+KPX Odieresis X -51
+KPX Odieresis Y -59
+KPX Ograve T -9
+KPX Ograve V -60
+KPX Ograve Y -59
+KPX Oslash A -52
+KPX Otilde T -9
+KPX Otilde V -60
+KPX Otilde Y -59
+KPX P A -82
+KPX P AE -94
+KPX P Aacute -82
+KPX P Adieresis -82
+KPX P Aring -82
+KPX P J -68
+KPX P a -20
+KPX P aacute -20
+KPX P adieresis -19
+KPX P ae -23
+KPX P aring -20
+KPX P comma -86
+KPX P e -30
+KPX P eacute -30
+KPX P hyphen -39
+KPX P o -33
+KPX P oacute -33
+KPX P odieresis -22
+KPX P oe -31
+KPX P oslash -34
+KPX P period -87
+KPX R C -36
+KPX R Ccedilla -37
+KPX R G -30
+KPX R O -29
+KPX R OE -22
+KPX R Oacute -29
+KPX R Odieresis -29
+KPX R T -26
+KPX R U -37
+KPX R Udieresis -37
+KPX R V -53
+KPX R W -54
+KPX R Y -52
+KPX R a 7
+KPX R aacute 7
+KPX R adieresis 7
+KPX R ae 4
+KPX R aring 7
+KPX R e -19
+KPX R eacute -19
+KPX R hyphen -30
+KPX R o -23
+KPX R oacute -23
+KPX R odieresis -23
+KPX R oe -21
+KPX R u -17
+KPX R uacute -17
+KPX R udieresis -17
+KPX R y -27
+KPX S A -24
+KPX S AE -21
+KPX S Aacute -24
+KPX S Adieresis -24
+KPX S Aring -24
+KPX S T -16
+KPX S V -9
+KPX S W -10
+KPX S Y -8
+KPX S t -10
+KPX T A -46
+KPX T AE -44
+KPX T Aacute -46
+KPX T Acircumflex -46
+KPX T Adieresis -46
+KPX T Agrave -46
+KPX T Aring -46
+KPX T Atilde -46
+KPX T C -17
+KPX T G -11
+KPX T J -43
+KPX T O -9
+KPX T OE -3
+KPX T Oacute -9
+KPX T Ocircumflex -9
+KPX T Odieresis -9
+KPX T Ograve -9
+KPX T Oslash -11
+KPX T Otilde -9
+KPX T S -2
+KPX T V 11
+KPX T W 9
+KPX T Y 11
+KPX T a -65
+KPX T ae -69
+KPX T c -88
+KPX T colon -85
+KPX T comma -63
+KPX T e -86
+KPX T g -68
+KPX T guillemotleft -99
+KPX T guilsinglleft -113
+KPX T hyphen -73
+KPX T i -16
+KPX T j -40
+KPX T o -88
+KPX T oslash -87
+KPX T period -64
+KPX T r -61
+KPX T s -59
+KPX T semicolon -85
+KPX T u -89
+KPX T v -106
+KPX T w -107
+KPX T y -104
+KPX U A -55
+KPX U AE -52
+KPX U Aacute -55
+KPX U Acircumflex -55
+KPX U Adieresis -55
+KPX U Aring -55
+KPX U Atilde -55
+KPX U comma -17
+KPX U m -23
+KPX U n -25
+KPX U p -28
+KPX U period -18
+KPX U r -29
+KPX Uacute A -55
+KPX Uacute comma -17
+KPX Uacute m -23
+KPX Uacute n -25
+KPX Uacute p -28
+KPX Uacute period -18
+KPX Uacute r -29
+KPX Ucircumflex A -55
+KPX Udieresis A -55
+KPX Udieresis b 10
+KPX Udieresis comma -17
+KPX Udieresis m -23
+KPX Udieresis n -25
+KPX Udieresis p -28
+KPX Udieresis period -18
+KPX Udieresis r -29
+KPX Ugrave A -55
+KPX V A -114
+KPX V AE -113
+KPX V Aacute -114
+KPX V Acircumflex -114
+KPX V Adieresis -114
+KPX V Agrave -114
+KPX V Aring -114
+KPX V Atilde -114
+KPX V C -70
+KPX V G -64
+KPX V O -63
+KPX V Oacute -63
+KPX V Ocircumflex -63
+KPX V Odieresis -63
+KPX V Ograve -63
+KPX V Oslash -65
+KPX V Otilde -63
+KPX V S -25
+KPX V T 8
+KPX V a -87
+KPX V ae -90
+KPX V colon -94
+KPX V comma -94
+KPX V e -86
+KPX V g -87
+KPX V guillemotleft -98
+KPX V guilsinglleft -112
+KPX V hyphen -68
+KPX V i -12
+KPX V o -89
+KPX V oslash -87
+KPX V period -95
+KPX V r -60
+KPX V semicolon -94
+KPX V u -58
+KPX V y -56
+KPX W A -99
+KPX W AE -102
+KPX W Aacute -99
+KPX W Acircumflex -99
+KPX W Adieresis -99
+KPX W Agrave -99
+KPX W Aring -99
+KPX W Atilde -99
+KPX W C -58
+KPX W G -52
+KPX W O -51
+KPX W Oacute -51
+KPX W Ocircumflex -51
+KPX W Odieresis -51
+KPX W Ograve -51
+KPX W Oslash -50
+KPX W Otilde -51
+KPX W S -24
+KPX W T 9
+KPX W a -70
+KPX W ae -73
+KPX W colon -80
+KPX W comma -72
+KPX W e -68
+KPX W g -70
+KPX W guillemotleft -79
+KPX W guilsinglleft -93
+KPX W hyphen -49
+KPX W i -11
+KPX W o -70
+KPX W oslash -69
+KPX W period -73
+KPX W r -49
+KPX W semicolon -80
+KPX W u -45
+KPX W y -44
+KPX X C -63
+KPX X O -56
+KPX X Odieresis -56
+KPX X Q -57
+KPX X a 0
+KPX X e -27
+KPX X hyphen -43
+KPX X o -31
+KPX X u -25
+KPX X y -90
+KPX Y A -64
+KPX Y AE -62
+KPX Y Aacute -64
+KPX Y Acircumflex -64
+KPX Y Adieresis -64
+KPX Y Agrave -64
+KPX Y Aring -64
+KPX Y Atilde -64
+KPX Y C -71
+KPX Y G -65
+KPX Y O -64
+KPX Y Oacute -64
+KPX Y Ocircumflex -64
+KPX Y Odieresis -64
+KPX Y Ograve -64
+KPX Y Oslash -68
+KPX Y Otilde -64
+KPX Y S -26
+KPX Y T 7
+KPX Y a -83
+KPX Y ae -87
+KPX Y colon -103
+KPX Y comma -80
+KPX Y e -93
+KPX Y g -86
+KPX Y guillemotleft -111
+KPX Y guilsinglleft -125
+KPX Y hyphen -87
+KPX Y i -13
+KPX Y o -96
+KPX Y oslash -95
+KPX Y p -72
+KPX Y period -81
+KPX Y semicolon -103
+KPX Y u -76
+KPX Y v -78
+KPX Z v -45
+KPX Z y -45
+KPX a j -39
+KPX a quoteright -34
+KPX a v -39
+KPX a w -40
+KPX a y -44
+KPX aacute v -39
+KPX aacute w -40
+KPX aacute y -44
+KPX adieresis v -39
+KPX adieresis w -40
+KPX adieresis y -44
+KPX ae v -33
+KPX ae w -34
+KPX ae y -37
+KPX agrave v -39
+KPX agrave w -40
+KPX agrave y -44
+KPX aring v -39
+KPX aring w -40
+KPX aring y -44
+KPX b v -39
+KPX b w -40
+KPX b y -42
+KPX c h -17
+KPX c k -18
+KPX comma one -12
+KPX comma quotedblright 9
+KPX comma quoteright -23
+KPX e quoteright -20
+KPX e t -11
+KPX e v -30
+KPX e w -31
+KPX e x -19
+KPX e y -32
+KPX eacute v -30
+KPX eacute w -31
+KPX eacute y -32
+KPX ecircumflex v -30
+KPX ecircumflex w -31
+KPX ecircumflex y -32
+KPX eight four 11
+KPX eight one -19
+KPX eight seven 0
+KPX f a -17
+KPX f aacute -17
+KPX f adieresis 14
+KPX f ae -20
+KPX f aring -14
+KPX f e -29
+KPX f eacute -29
+KPX f f 12
+KPX f i 22
+KPX f j -1
+KPX f l 33
+KPX f o -32
+KPX f oacute -32
+KPX f odieresis 11
+KPX f oe -30
+KPX f oslash -31
+KPX f quoteright 18
+KPX f s -8
+KPX f t -3
+KPX five four 1
+KPX five one -28
+KPX five seven -9
+KPX four four 13
+KPX four one -35
+KPX four seven -16
+KPX g a -15
+KPX g adieresis -15
+KPX g ae -18
+KPX g aring -15
+KPX g e -20
+KPX g eacute -20
+KPX g l 0
+KPX g oacute -20
+KPX g odieresis -20
+KPX g r 1
+KPX guillemotright A -41
+KPX guillemotright AE -46
+KPX guillemotright Aacute -41
+KPX guillemotright Adieresis -41
+KPX guillemotright Aring -41
+KPX guillemotright T -100
+KPX guillemotright V -102
+KPX guillemotright W -84
+KPX guillemotright Y -106
+KPX guilsinglright A -55
+KPX guilsinglright AE -60
+KPX guilsinglright Aacute -55
+KPX guilsinglright Adieresis -55
+KPX guilsinglright Aring -55
+KPX guilsinglright T -114
+KPX guilsinglright V -116
+KPX guilsinglright W -98
+KPX guilsinglright Y -120
+KPX h quoteright -30
+KPX h y -34
+KPX hyphen A -18
+KPX hyphen AE -24
+KPX hyphen Aacute -18
+KPX hyphen Adieresis -18
+KPX hyphen Aring -18
+KPX hyphen T -74
+KPX hyphen V -72
+KPX hyphen W -54
+KPX hyphen Y -83
+KPX i T -18
+KPX i j -36
+KPX k a -3
+KPX k aacute -3
+KPX k adieresis -3
+KPX k ae -6
+KPX k aring -3
+KPX k comma 0
+KPX k e -33
+KPX k eacute -33
+KPX k g -4
+KPX k hyphen -47
+KPX k o -38
+KPX k oacute -38
+KPX k odieresis -38
+KPX k period 0
+KPX k s 5
+KPX k u -5
+KPX k udieresis -5
+KPX l v -22
+KPX l y -19
+KPX m p -16
+KPX m v -32
+KPX m w -33
+KPX m y -33
+KPX n T -56
+KPX n p -15
+KPX n quoteright -28
+KPX n v -31
+KPX n w -32
+KPX n y -32
+KPX nine four 2
+KPX nine one -26
+KPX nine seven 10
+KPX o T -88
+KPX o quoteright -28
+KPX o t -11
+KPX o v -42
+KPX o w -38
+KPX o x -29
+KPX o y -43
+KPX oacute v -42
+KPX oacute w -38
+KPX oacute y -43
+KPX ocircumflex t -11
+KPX odieresis t -11
+KPX odieresis v -42
+KPX odieresis w -38
+KPX odieresis x -29
+KPX odieresis y -43
+KPX ograve v -42
+KPX ograve w -38
+KPX ograve y -43
+KPX one comma -16
+KPX one eight -34
+KPX one five -16
+KPX one four -56
+KPX one nine -9
+KPX one one -27
+KPX one period -17
+KPX one seven -56
+KPX one six -47
+KPX one three -9
+KPX one two -2
+KPX one zero -35
+KPX p t -11
+KPX p y -33
+KPX period one -21
+KPX period quotedblright 4
+KPX period quoteright -27
+KPX q c -14
+KPX q u -15
+KPX quotedblbase A 18
+KPX quotedblbase AE 20
+KPX quotedblbase T -59
+KPX quotedblbase V -98
+KPX quotedblbase W -75
+KPX quotedblbase Y -73
+KPX quotedblleft A -59
+KPX quotedblleft AE -78
+KPX quotedblleft Aacute -59
+KPX quotedblleft Adieresis -59
+KPX quotedblleft Aring -59
+KPX quotedblleft T 9
+KPX quotedblleft V 15
+KPX quotedblleft W 13
+KPX quotedblleft Y 15
+KPX quotedblright A -72
+KPX quotedblright AE -91
+KPX quotedblright Aacute -72
+KPX quotedblright Adieresis -72
+KPX quotedblright Aring -72
+KPX quotedblright T 4
+KPX quotedblright V 5
+KPX quotedblright W 4
+KPX quotedblright Y 6
+KPX quoteleft A -92
+KPX quoteleft AE -111
+KPX quoteleft Aacute -92
+KPX quoteleft Adieresis -92
+KPX quoteleft Aring -92
+KPX quoteleft T -22
+KPX quoteleft V -17
+KPX quoteleft W -19
+KPX quoteleft Y -17
+KPX quoteright A -91
+KPX quoteright AE -110
+KPX quoteright Aacute -91
+KPX quoteright Adieresis -91
+KPX quoteright Aring -91
+KPX quoteright comma -34
+KPX quoteright d -31
+KPX quoteright o -34
+KPX quoteright period -35
+KPX quoteright r -27
+KPX quoteright s -17
+KPX quoteright t -19
+KPX quoteright v -25
+KPX quoteright w -23
+KPX quoteright y -22
+KPX r a -6
+KPX r aacute -6
+KPX r acircumflex -6
+KPX r adieresis -6
+KPX r ae -8
+KPX r agrave -6
+KPX r aring -6
+KPX r c -15
+KPX r ccedilla -10
+KPX r colon -16
+KPX r comma -67
+KPX r d -13
+KPX r e -11
+KPX r eacute -11
+KPX r ecircumflex -11
+KPX r egrave -11
+KPX r f 11
+KPX r g -5
+KPX r h -15
+KPX r hyphen -18
+KPX r i 6
+KPX r j -12
+KPX r k -15
+KPX r l -14
+KPX r m 6
+KPX r n 3
+KPX r o -14
+KPX r oacute -14
+KPX r ocircumflex -14
+KPX r odieresis -14
+KPX r oe -12
+KPX r ograve -14
+KPX r oslash -14
+KPX r p 3
+KPX r period -68
+KPX r q -15
+KPX r quoteright -8
+KPX r r 0
+KPX r s 0
+KPX r semicolon -16
+KPX r t 9
+KPX r u 8
+KPX r v 8
+KPX r w 7
+KPX r x 10
+KPX r y 8
+KPX r z -1
+KPX s quoteright -17
+KPX s t -7
+KPX seven colon -64
+KPX seven comma -57
+KPX seven eight -18
+KPX seven five -34
+KPX seven four -54
+KPX seven one -25
+KPX seven period -58
+KPX seven seven -6
+KPX seven six -36
+KPX seven three -20
+KPX seven two -21
+KPX six four 13
+KPX six one -43
+KPX six seven -7
+KPX t S 11
+KPX t a 11
+KPX t aacute 11
+KPX t adieresis 11
+KPX t ae 7
+KPX t aring 11
+KPX t colon -12
+KPX t e -1
+KPX t eacute -1
+KPX t h -4
+KPX t o -3
+KPX t oacute -3
+KPX t odieresis -3
+KPX t quoteright -31
+KPX t semicolon -12
+KPX three four 9
+KPX three one -33
+KPX three seven -15
+KPX two four 14
+KPX two one -29
+KPX two seven -7
+KPX u quoteright -25
+KPX v a -23
+KPX v aacute -23
+KPX v acircumflex -23
+KPX v adieresis -23
+KPX v ae -25
+KPX v agrave -23
+KPX v aring -23
+KPX v atilde -23
+KPX v c -40
+KPX v colon -23
+KPX v comma -56
+KPX v e -35
+KPX v eacute -35
+KPX v ecircumflex -35
+KPX v egrave -35
+KPX v g -23
+KPX v hyphen -28
+KPX v l -16
+KPX v o -40
+KPX v oacute -40
+KPX v odieresis -40
+KPX v ograve -40
+KPX v oslash -39
+KPX v period -57
+KPX v s -16
+KPX v semicolon -23
+KPX w a -23
+KPX w aacute -23
+KPX w acircumflex -23
+KPX w adieresis -23
+KPX w ae -25
+KPX w agrave -23
+KPX w aring -23
+KPX w atilde -23
+KPX w c -36
+KPX w colon -23
+KPX w comma -51
+KPX w e -34
+KPX w eacute -34
+KPX w ecircumflex -34
+KPX w egrave -34
+KPX w g -23
+KPX w hyphen -23
+KPX w l -16
+KPX w o -36
+KPX w oacute -36
+KPX w odieresis -36
+KPX w ograve -36
+KPX w oslash -35
+KPX w period -52
+KPX w s -16
+KPX w semicolon -23
+KPX x a -2
+KPX x c -30
+KPX x e -28
+KPX x eacute -28
+KPX x o -30
+KPX x q -32
+KPX y a -32
+KPX y aacute -32
+KPX y acircumflex -32
+KPX y adieresis -32
+KPX y ae -34
+KPX y agrave -32
+KPX y aring -32
+KPX y atilde -32
+KPX y c -43
+KPX y colon -28
+KPX y comma -56
+KPX y e -40
+KPX y eacute -40
+KPX y ecircumflex -40
+KPX y egrave -40
+KPX y g -31
+KPX y hyphen -29
+KPX y l -19
+KPX y o -43
+KPX y oacute -43
+KPX y odieresis -43
+KPX y ograve -43
+KPX y oslash -42
+KPX y period -57
+KPX y s -24
+KPX y semicolon -28
+KPX zero four 11
+KPX zero one -31
+KPX zero seven 7
+EndKernPairs
+EndKernData
+EndFontMetrics
diff --git a/misc/gs_afm/TimesBoO.afm b/misc/gs_afm/TimesBoO.afm
new file mode 100644
index 0000000000..a31acdadc5
--- /dev/null
+++ b/misc/gs_afm/TimesBoO.afm
@@ -0,0 +1,1253 @@
+StartFontMetrics 3.0
+Comment Copyright URW Software, Copyright 1994 by URW
+Comment Creation Date: 2/11/1994
+Comment See the file PUBLIC (Aladdin Free Public License) for license conditions.
+FontName NimbusRomNo9L-MediItal
+FullName Nimbus Roman No9 L Medium Italic
+FamilyName Nimbus Roman No9 L
+Weight Bold
+ItalicAngle -15.0
+IsFixedPitch false
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.005
+Notice URW Software, Copyright 1994 by URW
+EncodingScheme AdobeStandardEncoding
+FontBBox -200 -218 996 949
+CapHeight 669
+XHeight 449
+Descender -205
+Ascender 699
+StartCharMetrics 232
+C 32 ; WX 250 ; N space ; B 125 0 125 0 ;
+C 33 ; WX 389 ; N exclam ; B 67 -13 370 684 ;
+C 34 ; WX 555 ; N quotedbl ; B 136 398 536 685 ;
+C 35 ; WX 500 ; N numbersign ; B -33 0 533 700 ;
+C 36 ; WX 500 ; N dollar ; B -20 -100 497 733 ;
+C 37 ; WX 833 ; N percent ; B 39 -10 793 692 ;
+C 38 ; WX 778 ; N ampersand ; B 5 -19 699 682 ;
+C 39 ; WX 333 ; N quoteright ; B 98 369 302 685 ;
+C 40 ; WX 333 ; N parenleft ; B 28 -179 344 685 ;
+C 41 ; WX 333 ; N parenright ; B -44 -179 271 685 ;
+C 42 ; WX 500 ; N asterisk ; B 65 252 456 685 ;
+C 43 ; WX 570 ; N plus ; B 33 0 537 506 ;
+C 44 ; WX 250 ; N comma ; B -60 -182 144 134 ;
+C 45 ; WX 333 ; N hyphen ; B 2 166 271 282 ;
+C 46 ; WX 250 ; N period ; B -9 -13 139 135 ;
+C 47 ; WX 278 ; N slash ; B -64 -18 342 685 ;
+C 48 ; WX 500 ; N zero ; B 17 -14 477 683 ;
+C 49 ; WX 500 ; N one ; B 5 0 419 683 ;
+C 50 ; WX 500 ; N two ; B -27 0 446 683 ;
+C 51 ; WX 500 ; N three ; B -15 -13 450 683 ;
+C 52 ; WX 500 ; N four ; B -15 0 503 683 ;
+C 53 ; WX 500 ; N five ; B -11 -13 487 669 ;
+C 54 ; WX 500 ; N six ; B 23 -15 509 679 ;
+C 55 ; WX 500 ; N seven ; B 52 0 525 669 ;
+C 56 ; WX 500 ; N eight ; B 3 -13 476 683 ;
+C 57 ; WX 500 ; N nine ; B -12 -10 475 683 ;
+C 58 ; WX 333 ; N colon ; B 23 -13 264 459 ;
+C 59 ; WX 333 ; N semicolon ; B -25 -183 264 459 ;
+C 60 ; WX 570 ; N less ; B 31 -12 539 518 ;
+C 61 ; WX 570 ; N equal ; B 33 107 537 399 ;
+C 62 ; WX 570 ; N greater ; B 31 -12 539 518 ;
+C 63 ; WX 500 ; N question ; B 79 -13 470 684 ;
+C 64 ; WX 832 ; N at ; B 63 -18 770 685 ;
+C 65 ; WX 667 ; N A ; B -67 0 593 683 ;
+C 66 ; WX 667 ; N B ; B -24 0 624 669 ;
+C 67 ; WX 667 ; N C ; B 32 -18 677 685 ;
+C 68 ; WX 722 ; N D ; B -46 0 685 669 ;
+C 69 ; WX 667 ; N E ; B -27 0 653 669 ;
+C 70 ; WX 667 ; N F ; B -13 0 660 669 ;
+C 71 ; WX 722 ; N G ; B 21 -18 706 685 ;
+C 72 ; WX 778 ; N H ; B -24 0 799 669 ;
+C 73 ; WX 389 ; N I ; B -32 0 406 669 ;
+C 74 ; WX 500 ; N J ; B -46 -99 524 669 ;
+C 75 ; WX 667 ; N K ; B -21 0 702 669 ;
+C 76 ; WX 611 ; N L ; B -22 0 590 669 ;
+C 77 ; WX 889 ; N M ; B -29 -12 917 669 ;
+C 78 ; WX 722 ; N N ; B -27 -15 748 669 ;
+C 79 ; WX 722 ; N O ; B 27 -18 691 685 ;
+C 80 ; WX 611 ; N P ; B -27 0 613 669 ;
+C 81 ; WX 722 ; N Q ; B 27 -208 691 685 ;
+C 82 ; WX 667 ; N R ; B -29 0 623 669 ;
+C 83 ; WX 556 ; N S ; B 2 -18 526 685 ;
+C 84 ; WX 611 ; N T ; B 50 0 650 669 ;
+C 85 ; WX 722 ; N U ; B 67 -18 744 669 ;
+C 86 ; WX 667 ; N V ; B 65 -18 715 669 ;
+C 87 ; WX 889 ; N W ; B 65 -18 940 669 ;
+C 88 ; WX 667 ; N X ; B -24 0 694 669 ;
+C 89 ; WX 611 ; N Y ; B 73 0 659 669 ;
+C 90 ; WX 611 ; N Z ; B -11 0 590 669 ;
+C 91 ; WX 333 ; N bracketleft ; B -37 -159 362 674 ;
+C 92 ; WX 278 ; N backslash ; B -1 -18 279 685 ;
+C 93 ; WX 333 ; N bracketright ; B -56 -157 343 674 ;
+C 94 ; WX 570 ; N asciicircum ; B 67 304 503 669 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 333 ; N quoteleft ; B 128 369 332 685 ;
+C 97 ; WX 500 ; N a ; B -21 -14 455 462 ;
+C 98 ; WX 500 ; N b ; B -14 -13 444 699 ;
+C 99 ; WX 444 ; N c ; B -5 -13 392 462 ;
+C 100 ; WX 500 ; N d ; B -21 -13 517 699 ;
+C 101 ; WX 444 ; N e ; B 5 -13 398 462 ;
+C 102 ; WX 333 ; N f ; B -169 -205 446 698 ;
+C 103 ; WX 500 ; N g ; B -52 -203 478 462 ;
+C 104 ; WX 556 ; N h ; B -13 -9 498 699 ;
+C 105 ; WX 278 ; N i ; B 2 -9 262 684 ;
+C 106 ; WX 278 ; N j ; B -189 -207 279 685 ;
+C 107 ; WX 500 ; N k ; B -23 -8 483 699 ;
+C 108 ; WX 278 ; N l ; B 2 -9 290 699 ;
+C 109 ; WX 778 ; N m ; B -14 -9 722 462 ;
+C 110 ; WX 556 ; N n ; B -6 -9 493 462 ;
+C 111 ; WX 500 ; N o ; B -3 -13 441 462 ;
+C 112 ; WX 500 ; N p ; B -120 -205 446 462 ;
+C 113 ; WX 500 ; N q ; B 1 -205 471 462 ;
+C 114 ; WX 389 ; N r ; B -21 0 389 462 ;
+C 115 ; WX 389 ; N s ; B -19 -13 333 462 ;
+C 116 ; WX 278 ; N t ; B -11 -9 281 594 ;
+C 117 ; WX 556 ; N u ; B 15 -9 492 462 ;
+C 118 ; WX 444 ; N v ; B 16 -13 401 462 ;
+C 119 ; WX 667 ; N w ; B 16 -13 614 462 ;
+C 120 ; WX 500 ; N x ; B -46 -13 469 462 ;
+C 121 ; WX 444 ; N y ; B -94 -205 392 462 ;
+C 122 ; WX 389 ; N z ; B -43 -78 368 449 ;
+C 123 ; WX 348 ; N braceleft ; B 5 -187 436 686 ;
+C 124 ; WX 220 ; N bar ; B 66 -18 154 685 ;
+C 125 ; WX 348 ; N braceright ; B -129 -187 302 686 ;
+C 126 ; WX 570 ; N asciitilde ; B 54 175 516 331 ;
+C 161 ; WX 389 ; N exclamdown ; B 19 -205 320 494 ;
+C 162 ; WX 500 ; N cent ; B 42 -143 439 576 ;
+C 163 ; WX 500 ; N sterling ; B -32 -12 510 683 ;
+C 164 ; WX 167 ; N fraction ; B -169 -14 324 683 ;
+C 165 ; WX 500 ; N yen ; B 33 0 628 669 ;
+C 166 ; WX 500 ; N florin ; B -87 -156 537 707 ;
+C 167 ; WX 500 ; N section ; B 36 -143 459 685 ;
+C 168 ; WX 500 ; N currency ; B -26 34 526 586 ;
+C 169 ; WX 278 ; N quotesingle ; B 128 398 268 685 ;
+C 170 ; WX 500 ; N quotedblleft ; B 53 369 513 685 ;
+C 171 ; WX 500 ; N guillemotleft ; B 12 32 468 415 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 32 32 303 415 ;
+C 173 ; WX 333 ; N guilsinglright ; B 10 32 281 415 ;
+C 174 ; WX 556 ; N fi ; B -188 -205 514 703 ;
+C 175 ; WX 556 ; N fl ; B -186 -205 553 704 ;
+C 177 ; WX 500 ; N endash ; B -40 178 477 269 ;
+C 178 ; WX 500 ; N dagger ; B 91 -145 494 685 ;
+C 179 ; WX 500 ; N daggerdbl ; B 10 -139 493 685 ;
+C 180 ; WX 250 ; N periodcentered ; B 51 257 199 405 ;
+C 182 ; WX 500 ; N paragraph ; B -57 -193 562 669 ;
+C 183 ; WX 350 ; N bullet ; B 0 175 350 525 ;
+C 184 ; WX 333 ; N quotesinglbase ; B -5 -182 199 134 ;
+C 185 ; WX 500 ; N quotedblbase ; B -57 -182 403 134 ;
+C 186 ; WX 500 ; N quotedblright ; B 53 369 513 685 ;
+C 187 ; WX 500 ; N guillemotright ; B 12 32 468 415 ;
+C 188 ; WX 1000 ; N ellipsis ; B 40 -13 852 135 ;
+C 189 ; WX 1000 ; N perthousand ; B 7 -29 996 706 ;
+C 191 ; WX 500 ; N questiondown ; B 30 -205 421 492 ;
+C 193 ; WX 333 ; N grave ; B 85 516 297 697 ;
+C 194 ; WX 333 ; N acute ; B 139 516 379 697 ;
+C 195 ; WX 333 ; N circumflex ; B 40 516 367 690 ;
+C 196 ; WX 333 ; N tilde ; B 48 536 407 655 ;
+C 197 ; WX 333 ; N macron ; B 51 553 393 623 ;
+C 198 ; WX 333 ; N breve ; B 71 516 387 678 ;
+C 199 ; WX 333 ; N dotaccent ; B 163 525 293 655 ;
+C 200 ; WX 333 ; N dieresis ; B 55 525 397 655 ;
+C 202 ; WX 333 ; N ring ; B 127 541 340 754 ;
+C 203 ; WX 333 ; N cedilla ; B -80 -218 156 5 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 69 516 498 697 ;
+C 206 ; WX 333 ; N ogonek ; B -40 -173 189 44 ;
+C 207 ; WX 333 ; N caron ; B 79 516 411 690 ;
+C 208 ; WX 1000 ; N emdash ; B -40 178 977 269 ;
+C 225 ; WX 944 ; N AE ; B -64 0 918 669 ;
+C 227 ; WX 266 ; N ordfeminine ; B 16 399 330 685 ;
+C 232 ; WX 611 ; N Lslash ; B -22 0 590 669 ;
+C 233 ; WX 722 ; N Oslash ; B 27 -125 691 764 ;
+C 234 ; WX 944 ; N OE ; B 23 -8 946 677 ;
+C 235 ; WX 300 ; N ordmasculine ; B 56 400 350 685 ;
+C 241 ; WX 722 ; N ae ; B -5 -13 673 462 ;
+C 245 ; WX 278 ; N dotlessi ; B 2 -9 238 462 ;
+C 248 ; WX 278 ; N lslash ; B -13 -9 301 699 ;
+C 249 ; WX 500 ; N oslash ; B -3 -119 441 560 ;
+C 250 ; WX 722 ; N oe ; B 6 -13 674 462 ;
+C 251 ; WX 500 ; N germandbls ; B -200 -200 473 705 ;
+C -1 ; WX 611 ; N Yacute ; B 73 0 659 904 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 67 -18 744 897 ;
+C -1 ; WX 722 ; N Ugrave ; B 67 -18 744 904 ;
+C -1 ; WX 611 ; N Zcaron ; B -11 0 590 897 ;
+C -1 ; WX 611 ; N Ydieresis ; B 73 0 659 862 ;
+C -1 ; WX 300 ; N threesuperior ; B 17 265 321 683 ;
+C -1 ; WX 722 ; N Uacute ; B 67 -18 744 904 ;
+C -1 ; WX 300 ; N twosuperior ; B 2 274 313 683 ;
+C -1 ; WX 722 ; N Udieresis ; B 67 -18 744 862 ;
+C -1 ; WX 250 ; N middot ; B 51 257 199 405 ;
+C -1 ; WX 300 ; N onesuperior ; B 30 274 301 683 ;
+C -1 ; WX 500 ; N aacute ; B -21 -14 463 697 ;
+C -1 ; WX 500 ; N agrave ; B -21 -14 455 697 ;
+C -1 ; WX 500 ; N acircumflex ; B -21 -14 455 690 ;
+C -1 ; WX 556 ; N Scaron ; B 2 -18 526 897 ;
+C -1 ; WX 722 ; N Otilde ; B 27 -18 691 862 ;
+C -1 ; WX 333 ; N sfthyphen ; B 2 166 271 282 ;
+C -1 ; WX 500 ; N atilde ; B -21 -14 491 655 ;
+C -1 ; WX 500 ; N aring ; B -21 -14 455 754 ;
+C -1 ; WX 500 ; N adieresis ; B -21 -14 471 655 ;
+C -1 ; WX 722 ; N Ograve ; B 27 -18 691 904 ;
+C -1 ; WX 722 ; N Ocircumflex ; B 27 -18 691 897 ;
+C -1 ; WX 722 ; N Odieresis ; B 27 -18 691 862 ;
+C -1 ; WX 722 ; N Ntilde ; B -27 -15 748 862 ;
+C -1 ; WX 444 ; N edieresis ; B 5 -13 443 655 ;
+C -1 ; WX 444 ; N eacute ; B 5 -13 435 697 ;
+C -1 ; WX 444 ; N egrave ; B 5 -13 398 697 ;
+C -1 ; WX 389 ; N Icircumflex ; B -32 0 420 897 ;
+C -1 ; WX 444 ; N ecircumflex ; B 5 -13 423 690 ;
+C -1 ; WX 389 ; N Igrave ; B -32 0 406 904 ;
+C -1 ; WX 389 ; N Iacute ; B -32 0 407 907 ;
+C -1 ; WX 389 ; N Idieresis ; B -32 0 445 862 ;
+C -1 ; WX 400 ; N degree ; B 83 397 369 683 ;
+C -1 ; WX 667 ; N Ecircumflex ; B -27 0 653 897 ;
+C -1 ; WX 606 ; N minus ; B 51 209 555 297 ;
+C -1 ; WX 570 ; N multiply ; B 48 16 522 490 ;
+C -1 ; WX 570 ; N divide ; B 33 -29 537 535 ;
+C -1 ; WX 667 ; N Egrave ; B -27 0 653 904 ;
+C -1 ; WX 1000 ; N trademark ; B 32 263 968 669 ;
+C -1 ; WX 722 ; N Oacute ; B 27 -18 691 904 ;
+C -1 ; WX 500 ; N thorn ; B -120 -205 446 699 ;
+C -1 ; WX 500 ; N eth ; B -3 -13 454 699 ;
+C -1 ; WX 667 ; N Eacute ; B -27 0 653 904 ;
+C -1 ; WX 444 ; N ccedilla ; B -24 -218 392 462 ;
+C -1 ; WX 278 ; N idieresis ; B 2 -9 360 655 ;
+C -1 ; WX 278 ; N iacute ; B 2 -9 352 697 ;
+C -1 ; WX 278 ; N igrave ; B 2 -9 260 697 ;
+C -1 ; WX 570 ; N plusminus ; B 33 0 537 568 ;
+C -1 ; WX 750 ; N onehalf ; B -9 -14 723 683 ;
+C -1 ; WX 750 ; N onequarter ; B 7 -14 721 683 ;
+C -1 ; WX 750 ; N threequarters ; B 7 -14 726 683 ;
+C -1 ; WX 278 ; N icircumflex ; B -2 -9 325 690 ;
+C -1 ; WX 667 ; N Edieresis ; B -27 0 653 862 ;
+C -1 ; WX 556 ; N ntilde ; B -6 -9 504 655 ;
+C -1 ; WX 667 ; N Aring ; B -67 0 593 949 ;
+C -1 ; WX 500 ; N odieresis ; B -3 -13 466 655 ;
+C -1 ; WX 500 ; N oacute ; B -3 -13 463 697 ;
+C -1 ; WX 500 ; N ograve ; B -3 -13 441 697 ;
+C -1 ; WX 500 ; N ocircumflex ; B -3 -13 451 690 ;
+C -1 ; WX 500 ; N otilde ; B -3 -13 491 655 ;
+C -1 ; WX 389 ; N scaron ; B -19 -13 439 690 ;
+C -1 ; WX 556 ; N udieresis ; B 15 -9 494 655 ;
+C -1 ; WX 556 ; N uacute ; B 15 -9 492 697 ;
+C -1 ; WX 556 ; N ugrave ; B 15 -9 492 697 ;
+C -1 ; WX 556 ; N ucircumflex ; B 15 -9 492 690 ;
+C -1 ; WX 444 ; N yacute ; B -94 -205 435 697 ;
+C -1 ; WX 389 ; N zcaron ; B -43 -78 424 690 ;
+C -1 ; WX 444 ; N ydieresis ; B -94 -205 438 655 ;
+C -1 ; WX 747 ; N copyright ; B 30 -18 718 685 ;
+C -1 ; WX 747 ; N registered ; B 30 -18 718 685 ;
+C -1 ; WX 667 ; N Atilde ; B -67 0 593 862 ;
+C -1 ; WX 250 ; N nbspace ; B 125 0 125 0 ;
+C -1 ; WX 667 ; N Ccedilla ; B 32 -218 677 685 ;
+C -1 ; WX 667 ; N Acircumflex ; B -67 0 593 897 ;
+C -1 ; WX 667 ; N Agrave ; B -67 0 593 904 ;
+C -1 ; WX 606 ; N logicalnot ; B 51 108 555 399 ;
+C -1 ; WX 667 ; N Aacute ; B -67 0 593 904 ;
+C -1 ; WX 722 ; N Eth ; B -31 0 700 669 ;
+C -1 ; WX 220 ; N brokenbar ; B 66 -18 154 685 ;
+C -1 ; WX 611 ; N Thorn ; B -27 0 573 669 ;
+C -1 ; WX 667 ; N Adieresis ; B -67 0 593 862 ;
+C -1 ; WX 576 ; N mu ; B -60 -207 516 449 ;
+C -1 ; WX 250 ; N .notdef ; B 125 0 125 0 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 994
+KPX A C -61
+KPX A Ccedilla -63
+KPX A G -59
+KPX A O -53
+KPX A Odieresis -53
+KPX A Q -55
+KPX A T -33
+KPX A U -61
+KPX A Uacute -61
+KPX A Ucircumflex -61
+KPX A Udieresis -61
+KPX A Ugrave -61
+KPX A V -109
+KPX A W -107
+KPX A Y -44
+KPX A a -6
+KPX A b -1
+KPX A c -20
+KPX A ccedilla -29
+KPX A comma 0
+KPX A d -5
+KPX A e -25
+KPX A g -21
+KPX A guillemotleft -58
+KPX A guilsinglleft -68
+KPX A hyphen -22
+KPX A o -23
+KPX A period 2
+KPX A q -18
+KPX A quotedblright -78
+KPX A quoteright -101
+KPX A t -4
+KPX A u -17
+KPX A v -51
+KPX A w -56
+KPX A y -67
+KPX Aacute C -61
+KPX Aacute G -59
+KPX Aacute O -53
+KPX Aacute Q -55
+KPX Aacute T -33
+KPX Aacute U -61
+KPX Aacute V -109
+KPX Aacute W -107
+KPX Aacute Y -44
+KPX Aacute a -6
+KPX Aacute b -1
+KPX Aacute c -20
+KPX Aacute comma 0
+KPX Aacute d -5
+KPX Aacute e -25
+KPX Aacute g -21
+KPX Aacute guillemotleft -58
+KPX Aacute guilsinglleft -68
+KPX Aacute hyphen -22
+KPX Aacute o -23
+KPX Aacute period 2
+KPX Aacute q -18
+KPX Aacute quoteright -101
+KPX Aacute t -4
+KPX Aacute u -17
+KPX Aacute v -51
+KPX Aacute w -56
+KPX Aacute y -67
+KPX Acircumflex C -61
+KPX Acircumflex G -59
+KPX Acircumflex O -53
+KPX Acircumflex Q -55
+KPX Acircumflex T -33
+KPX Acircumflex U -61
+KPX Acircumflex V -109
+KPX Acircumflex W -107
+KPX Acircumflex Y -44
+KPX Acircumflex comma 0
+KPX Acircumflex period 2
+KPX Adieresis C -61
+KPX Adieresis G -59
+KPX Adieresis O -53
+KPX Adieresis Q -55
+KPX Adieresis T -33
+KPX Adieresis U -61
+KPX Adieresis V -109
+KPX Adieresis W -107
+KPX Adieresis Y -44
+KPX Adieresis a -6
+KPX Adieresis b -1
+KPX Adieresis c -20
+KPX Adieresis comma 0
+KPX Adieresis d -5
+KPX Adieresis g -21
+KPX Adieresis guillemotleft -58
+KPX Adieresis guilsinglleft -68
+KPX Adieresis hyphen -22
+KPX Adieresis o -23
+KPX Adieresis period 2
+KPX Adieresis q -18
+KPX Adieresis quotedblright -78
+KPX Adieresis quoteright -101
+KPX Adieresis t -4
+KPX Adieresis u -17
+KPX Adieresis v -51
+KPX Adieresis w -56
+KPX Adieresis y -67
+KPX Agrave C -61
+KPX Agrave G -59
+KPX Agrave O -53
+KPX Agrave Q -55
+KPX Agrave T -33
+KPX Agrave U -61
+KPX Agrave V -109
+KPX Agrave W -107
+KPX Agrave Y -44
+KPX Agrave comma 0
+KPX Agrave period 2
+KPX Aring C -61
+KPX Aring G -59
+KPX Aring O -53
+KPX Aring Q -55
+KPX Aring T -33
+KPX Aring U -61
+KPX Aring V -109
+KPX Aring W -107
+KPX Aring Y -44
+KPX Aring a -6
+KPX Aring b -1
+KPX Aring c -20
+KPX Aring comma 0
+KPX Aring d -5
+KPX Aring e -25
+KPX Aring g -21
+KPX Aring guillemotleft -58
+KPX Aring guilsinglleft -68
+KPX Aring hyphen -22
+KPX Aring o -23
+KPX Aring period 2
+KPX Aring q -18
+KPX Aring quotedblright -78
+KPX Aring quoteright -101
+KPX Aring t -4
+KPX Aring u -17
+KPX Aring v -51
+KPX Aring w -56
+KPX Aring y -67
+KPX Atilde C -61
+KPX Atilde G -59
+KPX Atilde O -53
+KPX Atilde Q -55
+KPX Atilde T -33
+KPX Atilde U -61
+KPX Atilde V -109
+KPX Atilde W -107
+KPX Atilde Y -44
+KPX Atilde comma 0
+KPX Atilde period 2
+KPX B A -33
+KPX B AE -34
+KPX B Aacute -33
+KPX B Acircumflex -33
+KPX B Adieresis -33
+KPX B Aring -33
+KPX B Atilde -33
+KPX B O -22
+KPX B OE -19
+KPX B Oacute -22
+KPX B Ocircumflex -22
+KPX B Odieresis -22
+KPX B Ograve -22
+KPX B Oslash -22
+KPX B V -48
+KPX B W -51
+KPX B Y -52
+KPX C A -24
+KPX C AE -26
+KPX C Aacute -24
+KPX C Adieresis -24
+KPX C Aring -24
+KPX C H -26
+KPX C K -28
+KPX C O -25
+KPX C Oacute -25
+KPX C Odieresis -25
+KPX Ccedilla A -30
+KPX D A -52
+KPX D Aacute -52
+KPX D Acircumflex -52
+KPX D Adieresis -52
+KPX D Agrave -52
+KPX D Aring -52
+KPX D Atilde -52
+KPX D J -66
+KPX D T -27
+KPX D V -60
+KPX D W -58
+KPX D X -63
+KPX D Y -63
+KPX F A -99
+KPX F Aacute -99
+KPX F Acircumflex -99
+KPX F Adieresis -99
+KPX F Agrave -99
+KPX F Aring -99
+KPX F Atilde -99
+KPX F J -88
+KPX F O -48
+KPX F Odieresis -48
+KPX F a -74
+KPX F aacute -75
+KPX F adieresis -48
+KPX F ae -83
+KPX F aring -75
+KPX F comma -96
+KPX F e -85
+KPX F eacute -86
+KPX F hyphen -54
+KPX F i -29
+KPX F j -34
+KPX F o -81
+KPX F oacute -82
+KPX F odieresis -45
+KPX F oe -86
+KPX F oslash -82
+KPX F period -97
+KPX F r -32
+KPX F u -36
+KPX G A -14
+KPX G AE -15
+KPX G Aacute -14
+KPX G Acircumflex -14
+KPX G Adieresis -14
+KPX G Agrave -14
+KPX G Aring -14
+KPX G Atilde -14
+KPX G T -42
+KPX G V -27
+KPX G W -27
+KPX G Y -31
+KPX J A -39
+KPX J AE -41
+KPX J Adieresis -39
+KPX J Aring -39
+KPX K C -49
+KPX K G -45
+KPX K O -44
+KPX K OE -43
+KPX K Oacute -44
+KPX K Odieresis -44
+KPX K S -1
+KPX K T 0
+KPX K a 3
+KPX K adieresis 3
+KPX K ae -4
+KPX K aring 3
+KPX K e -15
+KPX K hyphen -30
+KPX K o -13
+KPX K oacute -13
+KPX K odieresis -13
+KPX K u -8
+KPX K udieresis -8
+KPX K y -68
+KPX L A 28
+KPX L AE 26
+KPX L Aacute 28
+KPX L Adieresis 28
+KPX L Aring 28
+KPX L C 0
+KPX L Ccedilla 0
+KPX L G 5
+KPX L O 4
+KPX L Oacute 4
+KPX L Ocircumflex 4
+KPX L Odieresis 4
+KPX L Ograve 4
+KPX L Otilde 4
+KPX L S 1
+KPX L T -30
+KPX L U -17
+KPX L Udieresis -17
+KPX L V -77
+KPX L W -75
+KPX L Y -41
+KPX L hyphen 41
+KPX L quotedblright -46
+KPX L quoteright -68
+KPX L u 6
+KPX L udieresis 6
+KPX L y -23
+KPX N A -39
+KPX N AE -40
+KPX N Aacute -39
+KPX N Adieresis -39
+KPX N Aring -39
+KPX N C -31
+KPX N Ccedilla -30
+KPX N G -27
+KPX N O -32
+KPX N Oacute -32
+KPX N Odieresis -32
+KPX N a -25
+KPX N aacute -26
+KPX N adieresis -26
+KPX N ae -33
+KPX N aring -26
+KPX N comma -24
+KPX N e -36
+KPX N eacute -38
+KPX N o -32
+KPX N oacute -34
+KPX N odieresis -34
+KPX N oslash -34
+KPX N period -25
+KPX N u -32
+KPX N udieresis -32
+KPX O A -56
+KPX O AE -65
+KPX O Aacute -56
+KPX O Adieresis -56
+KPX O Aring -56
+KPX O T -18
+KPX O V -52
+KPX O W -55
+KPX O X -61
+KPX O Y -56
+KPX Oacute A -56
+KPX Oacute T -18
+KPX Oacute V -52
+KPX Oacute W -55
+KPX Oacute Y -56
+KPX Ocircumflex T -18
+KPX Ocircumflex V -52
+KPX Ocircumflex Y -56
+KPX Odieresis A -56
+KPX Odieresis T -18
+KPX Odieresis V -52
+KPX Odieresis W -55
+KPX Odieresis X -61
+KPX Odieresis Y -56
+KPX Ograve T -18
+KPX Ograve V -52
+KPX Ograve Y -56
+KPX Oslash A -56
+KPX Otilde T -18
+KPX Otilde V -52
+KPX Otilde Y -56
+KPX P A -89
+KPX P AE -104
+KPX P Aacute -89
+KPX P Adieresis -89
+KPX P Aring -89
+KPX P J -105
+KPX P a -53
+KPX P aacute -53
+KPX P adieresis -38
+KPX P ae -61
+KPX P aring -53
+KPX P comma -108
+KPX P e -60
+KPX P eacute -60
+KPX P hyphen -57
+KPX P o -55
+KPX P oacute -55
+KPX P odieresis -35
+KPX P oe -60
+KPX P oslash -55
+KPX P period -109
+KPX R C -33
+KPX R Ccedilla -32
+KPX R G -28
+KPX R O -33
+KPX R OE -31
+KPX R Oacute -33
+KPX R Odieresis -33
+KPX R T -24
+KPX R U -43
+KPX R Udieresis -43
+KPX R V -46
+KPX R W -49
+KPX R Y -40
+KPX R a -1
+KPX R aacute -1
+KPX R adieresis -1
+KPX R ae -9
+KPX R aring -1
+KPX R e -20
+KPX R eacute -20
+KPX R hyphen -30
+KPX R o -18
+KPX R oacute -18
+KPX R odieresis -18
+KPX R oe -23
+KPX R u -13
+KPX R uacute -13
+KPX R udieresis -13
+KPX R y -12
+KPX S A -11
+KPX S AE -12
+KPX S Aacute -11
+KPX S Adieresis -11
+KPX S Aring -11
+KPX S T -33
+KPX S V -20
+KPX S W -20
+KPX S Y -24
+KPX S t -6
+KPX T A -52
+KPX T AE -54
+KPX T Aacute -52
+KPX T Acircumflex -52
+KPX T Adieresis -52
+KPX T Agrave -52
+KPX T Aring -52
+KPX T Atilde -52
+KPX T C -16
+KPX T G -10
+KPX T J -63
+KPX T O -21
+KPX T OE -18
+KPX T Oacute -21
+KPX T Ocircumflex -21
+KPX T Odieresis -21
+KPX T Ograve -21
+KPX T Oslash -22
+KPX T Otilde -21
+KPX T S -17
+KPX T V 15
+KPX T W 15
+KPX T Y 11
+KPX T a -83
+KPX T ae -91
+KPX T c -89
+KPX T colon -98
+KPX T comma -77
+KPX T e -94
+KPX T g -95
+KPX T guillemotleft -110
+KPX T guilsinglleft -120
+KPX T hyphen -74
+KPX T i -19
+KPX T j -27
+KPX T o -90
+KPX T oslash -92
+KPX T period -78
+KPX T r -76
+KPX T s -78
+KPX T semicolon -98
+KPX T u -90
+KPX T v -89
+KPX T w -89
+KPX T y -86
+KPX U A -65
+KPX U AE -66
+KPX U Aacute -65
+KPX U Acircumflex -65
+KPX U Adieresis -65
+KPX U Aring -65
+KPX U Atilde -65
+KPX U comma -39
+KPX U m -34
+KPX U n -38
+KPX U p -28
+KPX U period -40
+KPX U r -30
+KPX Uacute A -65
+KPX Uacute comma -39
+KPX Uacute m -34
+KPX Uacute n -38
+KPX Uacute p -28
+KPX Uacute period -40
+KPX Uacute r -30
+KPX Ucircumflex A -65
+KPX Udieresis A -65
+KPX Udieresis b 1
+KPX Udieresis comma -39
+KPX Udieresis m -34
+KPX Udieresis n -38
+KPX Udieresis p -28
+KPX Udieresis period -40
+KPX Udieresis r -30
+KPX Ugrave A -65
+KPX V A -98
+KPX V AE -111
+KPX V Aacute -98
+KPX V Acircumflex -98
+KPX V Adieresis -98
+KPX V Agrave -98
+KPX V Aring -98
+KPX V Atilde -98
+KPX V C -59
+KPX V G -54
+KPX V O -63
+KPX V Oacute -63
+KPX V Ocircumflex -63
+KPX V Odieresis -63
+KPX V Ograve -63
+KPX V Oslash -63
+KPX V Otilde -63
+KPX V S -28
+KPX V T 7
+KPX V a -75
+KPX V ae -84
+KPX V colon -95
+KPX V comma -95
+KPX V e -86
+KPX V g -82
+KPX V guillemotleft -98
+KPX V guilsinglleft -108
+KPX V hyphen -61
+KPX V i -12
+KPX V o -82
+KPX V oslash -83
+KPX V period -97
+KPX V r -39
+KPX V semicolon -95
+KPX V u -43
+KPX V y -33
+KPX W A -82
+KPX W AE -85
+KPX W Aacute -82
+KPX W Acircumflex -82
+KPX W Adieresis -82
+KPX W Agrave -82
+KPX W Aring -82
+KPX W Atilde -82
+KPX W C -47
+KPX W G -42
+KPX W O -48
+KPX W Oacute -48
+KPX W Ocircumflex -48
+KPX W Odieresis -48
+KPX W Ograve -48
+KPX W Oslash -48
+KPX W Otilde -48
+KPX W S -32
+KPX W T 7
+KPX W a -51
+KPX W ae -60
+KPX W colon -78
+KPX W comma -62
+KPX W e -63
+KPX W g -63
+KPX W guillemotleft -74
+KPX W guilsinglleft -84
+KPX W hyphen -37
+KPX W i -12
+KPX W o -58
+KPX W oslash -60
+KPX W period -63
+KPX W r -32
+KPX W semicolon -79
+KPX W u -36
+KPX W y -26
+KPX X C -56
+KPX X O -57
+KPX X Odieresis -57
+KPX X Q -57
+KPX X a -9
+KPX X e -28
+KPX X hyphen -45
+KPX X o -26
+KPX X u -21
+KPX X y -81
+KPX Y A -45
+KPX Y AE -47
+KPX Y Aacute -45
+KPX Y Acircumflex -45
+KPX Y Adieresis -45
+KPX Y Agrave -45
+KPX Y Aring -45
+KPX Y Atilde -45
+KPX Y C -59
+KPX Y G -55
+KPX Y O -60
+KPX Y Oacute -60
+KPX Y Ocircumflex -60
+KPX Y Odieresis -60
+KPX Y Ograve -60
+KPX Y Oslash -60
+KPX Y Otilde -60
+KPX Y S -28
+KPX Y T 7
+KPX Y a -69
+KPX Y ae -77
+KPX Y colon -91
+KPX Y comma -67
+KPX Y e -80
+KPX Y g -81
+KPX Y guillemotleft -97
+KPX Y guilsinglleft -107
+KPX Y hyphen -64
+KPX Y i -12
+KPX Y o -76
+KPX Y oslash -77
+KPX Y p -50
+KPX Y period -69
+KPX Y semicolon -91
+KPX Y u -56
+KPX Y v -54
+KPX Z v -27
+KPX Z y -38
+KPX a j -2
+KPX a quoteright -22
+KPX a v -5
+KPX a w -5
+KPX a y -3
+KPX aacute v -5
+KPX aacute w -5
+KPX aacute y -3
+KPX adieresis v -5
+KPX adieresis w -5
+KPX adieresis y -3
+KPX ae v -5
+KPX ae w -5
+KPX ae y -8
+KPX agrave v -5
+KPX agrave w -5
+KPX agrave y -3
+KPX aring v -5
+KPX aring w -5
+KPX aring y -3
+KPX b v -12
+KPX b w -12
+KPX b y -17
+KPX c h -20
+KPX c k -16
+KPX comma one -26
+KPX comma quotedblright -3
+KPX comma quoteright -25
+KPX e quoteright -13
+KPX e t -3
+KPX e v -3
+KPX e w -3
+KPX e x -15
+KPX e y -6
+KPX eacute v -3
+KPX eacute w -3
+KPX eacute y -6
+KPX ecircumflex v -3
+KPX ecircumflex w -3
+KPX ecircumflex y -6
+KPX eight four -4
+KPX eight one -52
+KPX eight seven -13
+KPX f a -23
+KPX f aacute -24
+KPX f adieresis 17
+KPX f ae -31
+KPX f aring -21
+KPX f e -35
+KPX f eacute -36
+KPX f f 2
+KPX f i 20
+KPX f j 12
+KPX f l 43
+KPX f o -30
+KPX f oacute -31
+KPX f odieresis 20
+KPX f oe -35
+KPX f oslash -31
+KPX f quoteright 12
+KPX f s -14
+KPX f t 9
+KPX five four -13
+KPX five one -56
+KPX five seven -37
+KPX four four 1
+KPX four one -50
+KPX four seven -21
+KPX g a -25
+KPX g adieresis -25
+KPX g ae -34
+KPX g aring -25
+KPX g e -32
+KPX g eacute -32
+KPX g l -21
+KPX g oacute -27
+KPX g odieresis -27
+KPX g r 3
+KPX guillemotright A -28
+KPX guillemotright AE -37
+KPX guillemotright Aacute -28
+KPX guillemotright Adieresis -28
+KPX guillemotright Aring -28
+KPX guillemotright T -75
+KPX guillemotright V -79
+KPX guillemotright W -75
+KPX guillemotright Y -82
+KPX guilsinglright A -38
+KPX guilsinglright AE -47
+KPX guilsinglright Aacute -38
+KPX guilsinglright Adieresis -38
+KPX guilsinglright Aring -38
+KPX guilsinglright T -85
+KPX guilsinglright V -89
+KPX guilsinglright W -85
+KPX guilsinglright Y -92
+KPX h quoteright -33
+KPX h y -20
+KPX hyphen A -11
+KPX hyphen AE -20
+KPX hyphen Aacute -11
+KPX hyphen Adieresis -11
+KPX hyphen Aring -11
+KPX hyphen T -59
+KPX hyphen V -62
+KPX hyphen W -59
+KPX hyphen Y -69
+KPX i T -21
+KPX i j -5
+KPX k a 10
+KPX k aacute 10
+KPX k adieresis 10
+KPX k ae 2
+KPX k aring 10
+KPX k comma 19
+KPX k e -2
+KPX k eacute -2
+KPX k g -13
+KPX k hyphen 0
+KPX k o 1
+KPX k oacute 1
+KPX k odieresis 1
+KPX k period 17
+KPX k s 1
+KPX k u 2
+KPX k udieresis 2
+KPX l v -12
+KPX l y -8
+KPX m p 0
+KPX m v -16
+KPX m w -16
+KPX m y -16
+KPX n T -57
+KPX n p -3
+KPX n quoteright -33
+KPX n v -20
+KPX n w -20
+KPX n y -20
+KPX nine four -18
+KPX nine one -67
+KPX nine seven -12
+KPX o T -75
+KPX o quoteright -22
+KPX o t -2
+KPX o v -21
+KPX o w -21
+KPX o x -26
+KPX o y -28
+KPX oacute v -21
+KPX oacute w -21
+KPX oacute y -28
+KPX ocircumflex t -4
+KPX odieresis t -4
+KPX odieresis v -21
+KPX odieresis w -21
+KPX odieresis x -26
+KPX odieresis y -28
+KPX ograve v -21
+KPX ograve w -21
+KPX ograve y -28
+KPX one comma -38
+KPX one eight -55
+KPX one five -45
+KPX one four -74
+KPX one nine -40
+KPX one one -48
+KPX one period -39
+KPX one seven -65
+KPX one six -62
+KPX one three -43
+KPX one two -32
+KPX one zero -48
+KPX p t -3
+KPX p y -12
+KPX period one -32
+KPX period quotedblright -7
+KPX period quoteright -29
+KPX q c -6
+KPX q u -3
+KPX quotedblbase A 25
+KPX quotedblbase AE 23
+KPX quotedblbase T -38
+KPX quotedblbase V -79
+KPX quotedblbase W -75
+KPX quotedblbase Y -48
+KPX quotedblleft A -75
+KPX quotedblleft AE -98
+KPX quotedblleft Aacute -75
+KPX quotedblleft Adieresis -75
+KPX quotedblleft Aring -75
+KPX quotedblleft T -11
+KPX quotedblleft V 3
+KPX quotedblleft W 3
+KPX quotedblleft Y 0
+KPX quotedblright A -71
+KPX quotedblright AE -94
+KPX quotedblright Aacute -71
+KPX quotedblright Adieresis -71
+KPX quotedblright Aring -71
+KPX quotedblright T -1
+KPX quotedblright V 6
+KPX quotedblright W 6
+KPX quotedblright Y 2
+KPX quoteleft A -82
+KPX quoteleft AE -105
+KPX quoteleft Aacute -82
+KPX quoteleft Adieresis -82
+KPX quoteleft Aring -82
+KPX quoteleft T -18
+KPX quoteleft V -3
+KPX quoteleft W -3
+KPX quoteleft Y -7
+KPX quoteright A -93
+KPX quoteright AE -115
+KPX quoteright Aacute -93
+KPX quoteright Adieresis -93
+KPX quoteright Aring -93
+KPX quoteright comma -55
+KPX quoteright d -50
+KPX quoteright o -49
+KPX quoteright period -57
+KPX quoteright r -24
+KPX quoteright s -25
+KPX quoteright t -19
+KPX quoteright v -23
+KPX quoteright w -23
+KPX quoteright y -17
+KPX r a -13
+KPX r aacute -13
+KPX r acircumflex -13
+KPX r adieresis -13
+KPX r ae -22
+KPX r agrave -13
+KPX r aring -13
+KPX r c -15
+KPX r ccedilla -8
+KPX r colon -30
+KPX r comma -68
+KPX r d -14
+KPX r e -20
+KPX r eacute -20
+KPX r ecircumflex -20
+KPX r egrave -20
+KPX r f 8
+KPX r g -4
+KPX r h -16
+KPX r hyphen -13
+KPX r i 17
+KPX r j 12
+KPX r k -12
+KPX r l -13
+KPX r m 10
+KPX r n 6
+KPX r o -15
+KPX r oacute -15
+KPX r ocircumflex -15
+KPX r odieresis -15
+KPX r oe -19
+KPX r ograve -15
+KPX r oslash -15
+KPX r p 16
+KPX r period -69
+KPX r q -19
+KPX r quoteright 0
+KPX r r 14
+KPX r s 1
+KPX r semicolon -30
+KPX r t 12
+KPX r u 10
+KPX r v 20
+KPX r w 20
+KPX r x 7
+KPX r y 20
+KPX r z 10
+KPX s quoteright -22
+KPX s t -6
+KPX seven colon -90
+KPX seven comma -79
+KPX seven four -79
+KPX seven one -43
+KPX seven period -81
+KPX seven seven -27
+KPX seven six -59
+KPX six four 2
+KPX six one -52
+KPX six seven -32
+KPX t S -11
+KPX t a 10
+KPX t aacute 10
+KPX t adieresis 10
+KPX t ae 2
+KPX t aring 10
+KPX t colon -22
+KPX t e -2
+KPX t eacute -2
+KPX t h -5
+KPX t o 1
+KPX t oacute 1
+KPX t odieresis 1
+KPX t quoteright -19
+KPX t semicolon -23
+KPX three four -15
+KPX three one -67
+KPX three seven -27
+KPX two four -8
+KPX two one -48
+KPX two seven -27
+KPX u quoteright -34
+KPX v a -20
+KPX v aacute -20
+KPX v acircumflex -20
+KPX v adieresis -20
+KPX v ae -28
+KPX v agrave -20
+KPX v aring -20
+KPX v atilde -20
+KPX v c -24
+KPX v colon -51
+KPX v comma -51
+KPX v e -28
+KPX v eacute -28
+KPX v ecircumflex -28
+KPX v egrave -28
+KPX v g -20
+KPX v hyphen -1
+KPX v l -24
+KPX v o -24
+KPX v oacute -24
+KPX v odieresis -24
+KPX v ograve -24
+KPX v oslash -24
+KPX v period -51
+KPX v s -18
+KPX v semicolon -51
+KPX w a -24
+KPX w aacute -24
+KPX w acircumflex -24
+KPX w adieresis -24
+KPX w ae -32
+KPX w agrave -24
+KPX w aring -24
+KPX w atilde -24
+KPX w c -30
+KPX w colon -56
+KPX w comma -53
+KPX w e -34
+KPX w eacute -34
+KPX w ecircumflex -34
+KPX w egrave -34
+KPX w g -26
+KPX w hyphen -7
+KPX w l -29
+KPX w o -30
+KPX w oacute -30
+KPX w odieresis -30
+KPX w ograve -30
+KPX w oslash -30
+KPX w period -53
+KPX w s -24
+KPX w semicolon -56
+KPX x a -1
+KPX x c -9
+KPX x e -13
+KPX x eacute -13
+KPX x o -10
+KPX x q -11
+KPX y a -11
+KPX y aacute -12
+KPX y acircumflex -12
+KPX y adieresis -12
+KPX y ae -19
+KPX y agrave -12
+KPX y aring -12
+KPX y atilde -12
+KPX y c -17
+KPX y colon -43
+KPX y comma -25
+KPX y e -22
+KPX y eacute -23
+KPX y ecircumflex -23
+KPX y egrave -23
+KPX y g -23
+KPX y hyphen 2
+KPX y l -16
+KPX y o -17
+KPX y oacute -19
+KPX y odieresis -19
+KPX y ograve -19
+KPX y oslash -19
+KPX y period -26
+KPX y s -13
+KPX y semicolon -44
+KPX zero four -1
+KPX zero one -50
+KPX zero seven -12
+EndKernPairs
+EndKernData
+EndFontMetrics
diff --git a/misc/gs_afm/TimesO.afm b/misc/gs_afm/TimesO.afm
new file mode 100644
index 0000000000..b643994a97
--- /dev/null
+++ b/misc/gs_afm/TimesO.afm
@@ -0,0 +1,1253 @@
+StartFontMetrics 3.0
+Comment Copyright URW Software, Copyright 1994 by URW
+Comment Creation Date: 2/11/1994
+Comment See the file PUBLIC (Aladdin Free Public License) for license conditions.
+FontName NimbusRomNo9L-ReguItal
+FullName Nimbus Roman No9 L Regular Italic
+FamilyName Nimbus Roman No9 L
+Weight Regular
+ItalicAngle -15.0
+IsFixedPitch false
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.005
+Notice URW Software, Copyright 1994 by URW
+EncodingScheme AdobeStandardEncoding
+FontBBox -169 -217 1010 904
+CapHeight 653
+XHeight 432
+Descender -205
+Ascender 683
+StartCharMetrics 232
+C 32 ; WX 250 ; N space ; B 125 0 125 0 ;
+C 33 ; WX 333 ; N exclam ; B 39 -11 302 667 ;
+C 34 ; WX 420 ; N quotedbl ; B 144 421 432 666 ;
+C 35 ; WX 500 ; N numbersign ; B 2 0 540 676 ;
+C 36 ; WX 500 ; N dollar ; B 31 -89 497 731 ;
+C 37 ; WX 833 ; N percent ; B 79 -13 790 676 ;
+C 38 ; WX 778 ; N ampersand ; B 76 -18 723 666 ;
+C 39 ; WX 333 ; N quoteright ; B 151 436 290 666 ;
+C 40 ; WX 333 ; N parenleft ; B 42 -181 315 669 ;
+C 41 ; WX 333 ; N parenright ; B 16 -180 289 669 ;
+C 42 ; WX 500 ; N asterisk ; B 128 255 492 666 ;
+C 43 ; WX 675 ; N plus ; B 86 0 590 506 ;
+C 44 ; WX 250 ; N comma ; B -4 -129 135 101 ;
+C 45 ; WX 333 ; N hyphen ; B 49 192 282 255 ;
+C 46 ; WX 250 ; N period ; B 27 -11 138 100 ;
+C 47 ; WX 278 ; N slash ; B -65 -18 386 666 ;
+C 48 ; WX 500 ; N zero ; B 32 -7 497 676 ;
+C 49 ; WX 500 ; N one ; B 49 0 409 676 ;
+C 50 ; WX 500 ; N two ; B 12 0 452 676 ;
+C 51 ; WX 500 ; N three ; B 15 -7 465 676 ;
+C 52 ; WX 500 ; N four ; B 1 0 479 676 ;
+C 53 ; WX 500 ; N five ; B 15 -7 491 666 ;
+C 54 ; WX 500 ; N six ; B 30 -7 521 686 ;
+C 55 ; WX 500 ; N seven ; B 75 -8 537 666 ;
+C 56 ; WX 500 ; N eight ; B 30 -7 493 676 ;
+C 57 ; WX 500 ; N nine ; B 23 -17 492 676 ;
+C 58 ; WX 333 ; N colon ; B 50 -11 261 441 ;
+C 59 ; WX 333 ; N semicolon ; B 27 -129 261 441 ;
+C 60 ; WX 675 ; N less ; B 84 -10 592 516 ;
+C 61 ; WX 675 ; N equal ; B 86 120 590 386 ;
+C 62 ; WX 675 ; N greater ; B 84 -10 592 516 ;
+C 63 ; WX 500 ; N question ; B 132 -12 472 664 ;
+C 64 ; WX 920 ; N at ; B 118 -18 806 666 ;
+C 65 ; WX 611 ; N A ; B -51 0 564 668 ;
+C 66 ; WX 611 ; N B ; B -8 0 588 653 ;
+C 67 ; WX 667 ; N C ; B 66 -18 689 666 ;
+C 68 ; WX 722 ; N D ; B -8 0 700 653 ;
+C 69 ; WX 611 ; N E ; B -1 0 634 653 ;
+C 70 ; WX 611 ; N F ; B 8 0 645 653 ;
+C 71 ; WX 722 ; N G ; B 52 -18 722 666 ;
+C 72 ; WX 722 ; N H ; B -8 0 767 653 ;
+C 73 ; WX 333 ; N I ; B -8 0 384 653 ;
+C 74 ; WX 444 ; N J ; B -6 -18 491 653 ;
+C 75 ; WX 667 ; N K ; B 7 0 722 653 ;
+C 76 ; WX 556 ; N L ; B -8 0 559 653 ;
+C 77 ; WX 833 ; N M ; B -18 0 873 653 ;
+C 78 ; WX 667 ; N N ; B -20 -15 727 653 ;
+C 79 ; WX 722 ; N O ; B 60 -18 706 666 ;
+C 80 ; WX 611 ; N P ; B 0 0 605 653 ;
+C 81 ; WX 722 ; N Q ; B 59 -182 699 666 ;
+C 82 ; WX 611 ; N R ; B -13 0 588 653 ;
+C 83 ; WX 500 ; N S ; B 17 -18 508 667 ;
+C 84 ; WX 556 ; N T ; B 59 0 633 653 ;
+C 85 ; WX 722 ; N U ; B 102 -18 765 653 ;
+C 86 ; WX 611 ; N V ; B 76 -18 688 653 ;
+C 87 ; WX 833 ; N W ; B 71 -18 906 653 ;
+C 88 ; WX 611 ; N X ; B -29 0 655 653 ;
+C 89 ; WX 556 ; N Y ; B 78 0 633 653 ;
+C 90 ; WX 556 ; N Z ; B -6 0 606 653 ;
+C 91 ; WX 389 ; N bracketleft ; B 21 -153 391 663 ;
+C 92 ; WX 278 ; N backslash ; B -41 -18 319 666 ;
+C 93 ; WX 389 ; N bracketright ; B 12 -153 382 663 ;
+C 94 ; WX 422 ; N asciicircum ; B 0 301 422 666 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 333 ; N quoteleft ; B 171 436 310 666 ;
+C 97 ; WX 500 ; N a ; B 17 -11 476 441 ;
+C 98 ; WX 500 ; N b ; B 23 -11 473 683 ;
+C 99 ; WX 444 ; N c ; B 30 -11 425 441 ;
+C 100 ; WX 500 ; N d ; B 15 -13 527 683 ;
+C 101 ; WX 444 ; N e ; B 31 -11 412 441 ;
+C 102 ; WX 278 ; N f ; B -147 -207 424 678 ;
+C 103 ; WX 500 ; N g ; B 8 -206 472 441 ;
+C 104 ; WX 500 ; N h ; B 19 -9 478 683 ;
+C 105 ; WX 278 ; N i ; B 49 -11 264 654 ;
+C 106 ; WX 278 ; N j ; B -124 -207 276 654 ;
+C 107 ; WX 444 ; N k ; B 14 -11 461 683 ;
+C 108 ; WX 278 ; N l ; B 41 -11 279 683 ;
+C 109 ; WX 722 ; N m ; B 12 -9 704 441 ;
+C 110 ; WX 500 ; N n ; B 14 -9 474 441 ;
+C 111 ; WX 500 ; N o ; B 27 -11 468 441 ;
+C 112 ; WX 500 ; N p ; B -75 -205 469 441 ;
+C 113 ; WX 500 ; N q ; B 25 -209 483 441 ;
+C 114 ; WX 389 ; N r ; B 45 0 412 441 ;
+C 115 ; WX 389 ; N s ; B 16 -13 366 442 ;
+C 116 ; WX 278 ; N t ; B 37 -11 296 546 ;
+C 117 ; WX 500 ; N u ; B 42 -11 475 441 ;
+C 118 ; WX 444 ; N v ; B 21 -18 426 441 ;
+C 119 ; WX 667 ; N w ; B 16 -18 648 441 ;
+C 120 ; WX 444 ; N x ; B -27 -11 447 441 ;
+C 121 ; WX 444 ; N y ; B -24 -206 426 441 ;
+C 122 ; WX 389 ; N z ; B -2 -81 380 428 ;
+C 123 ; WX 400 ; N braceleft ; B 51 -177 407 687 ;
+C 124 ; WX 275 ; N bar ; B 105 -18 171 666 ;
+C 125 ; WX 400 ; N braceright ; B -7 -177 349 687 ;
+C 126 ; WX 541 ; N asciitilde ; B 40 186 502 320 ;
+C 161 ; WX 389 ; N exclamdown ; B 59 -205 321 474 ;
+C 162 ; WX 500 ; N cent ; B 77 -143 472 560 ;
+C 163 ; WX 500 ; N sterling ; B 10 -6 517 670 ;
+C 164 ; WX 167 ; N fraction ; B -169 -10 337 676 ;
+C 165 ; WX 500 ; N yen ; B 27 0 603 653 ;
+C 166 ; WX 500 ; N florin ; B 25 -182 507 682 ;
+C 167 ; WX 500 ; N section ; B 53 -162 461 666 ;
+C 168 ; WX 500 ; N currency ; B -22 53 522 597 ;
+C 169 ; WX 214 ; N quotesingle ; B 132 421 241 666 ;
+C 170 ; WX 556 ; N quotedblleft ; B 166 436 514 666 ;
+C 171 ; WX 500 ; N guillemotleft ; B 53 37 445 403 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 51 37 281 403 ;
+C 173 ; WX 333 ; N guilsinglright ; B 52 37 282 403 ;
+C 174 ; WX 500 ; N fi ; B -141 -207 481 681 ;
+C 175 ; WX 500 ; N fl ; B -141 -204 518 682 ;
+C 177 ; WX 500 ; N endash ; B -6 197 505 243 ;
+C 178 ; WX 500 ; N dagger ; B 101 -159 488 666 ;
+C 179 ; WX 500 ; N daggerdbl ; B 22 -143 491 666 ;
+C 180 ; WX 250 ; N periodcentered ; B 70 199 181 310 ;
+C 182 ; WX 523 ; N paragraph ; B 55 -123 616 653 ;
+C 183 ; WX 350 ; N bullet ; B 40 191 310 461 ;
+C 184 ; WX 333 ; N quotesinglbase ; B 44 -129 183 101 ;
+C 185 ; WX 556 ; N quotedblbase ; B 57 -129 405 101 ;
+C 186 ; WX 556 ; N quotedblright ; B 151 436 499 666 ;
+C 187 ; WX 500 ; N guillemotright ; B 55 37 447 403 ;
+C 188 ; WX 889 ; N ellipsis ; B 57 -11 762 100 ;
+C 189 ; WX 1000 ; N perthousand ; B 25 -19 1010 706 ;
+C 191 ; WX 500 ; N questiondown ; B 28 -205 367 473 ;
+C 193 ; WX 333 ; N grave ; B 121 492 311 664 ;
+C 194 ; WX 333 ; N acute ; B 180 494 403 664 ;
+C 195 ; WX 333 ; N circumflex ; B 91 492 385 661 ;
+C 196 ; WX 333 ; N tilde ; B 100 517 427 624 ;
+C 197 ; WX 333 ; N macron ; B 99 532 411 583 ;
+C 198 ; WX 333 ; N breve ; B 117 492 418 650 ;
+C 199 ; WX 333 ; N dotaccent ; B 207 508 305 606 ;
+C 200 ; WX 333 ; N dieresis ; B 107 508 405 606 ;
+C 202 ; WX 333 ; N ring ; B 155 508 355 707 ;
+C 203 ; WX 333 ; N cedilla ; B -30 -217 182 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 93 494 486 664 ;
+C 206 ; WX 333 ; N ogonek ; B -20 -169 200 40 ;
+C 207 ; WX 333 ; N caron ; B 121 492 426 661 ;
+C 208 ; WX 889 ; N emdash ; B -6 197 894 243 ;
+C 225 ; WX 889 ; N AE ; B -27 0 911 653 ;
+C 227 ; WX 276 ; N ordfeminine ; B 42 406 352 676 ;
+C 232 ; WX 556 ; N Lslash ; B -8 0 559 653 ;
+C 233 ; WX 722 ; N Oslash ; B 60 -105 699 722 ;
+C 234 ; WX 944 ; N OE ; B 49 -8 964 666 ;
+C 235 ; WX 310 ; N ordmasculine ; B 67 406 362 676 ;
+C 241 ; WX 667 ; N ae ; B 23 -11 640 441 ;
+C 245 ; WX 278 ; N dotlessi ; B 49 -11 235 441 ;
+C 248 ; WX 278 ; N lslash ; B 37 -11 307 683 ;
+C 249 ; WX 500 ; N oslash ; B 28 -135 469 554 ;
+C 250 ; WX 667 ; N oe ; B 20 -12 646 441 ;
+C 251 ; WX 500 ; N germandbls ; B -168 -207 493 679 ;
+C -1 ; WX 556 ; N Yacute ; B 78 0 633 876 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 102 -18 765 873 ;
+C -1 ; WX 722 ; N Ugrave ; B 102 -18 765 876 ;
+C -1 ; WX 556 ; N Zcaron ; B -6 0 606 873 ;
+C -1 ; WX 556 ; N Ydieresis ; B 78 0 633 818 ;
+C -1 ; WX 300 ; N threesuperior ; B 43 268 339 676 ;
+C -1 ; WX 722 ; N Uacute ; B 102 -18 765 876 ;
+C -1 ; WX 300 ; N twosuperior ; B 33 271 324 676 ;
+C -1 ; WX 722 ; N Udieresis ; B 102 -18 765 818 ;
+C -1 ; WX 250 ; N middot ; B 70 199 181 310 ;
+C -1 ; WX 300 ; N onesuperior ; B 43 271 284 676 ;
+C -1 ; WX 500 ; N aacute ; B 17 -11 487 664 ;
+C -1 ; WX 500 ; N agrave ; B 17 -11 476 664 ;
+C -1 ; WX 500 ; N acircumflex ; B 17 -11 476 661 ;
+C -1 ; WX 500 ; N Scaron ; B 17 -18 520 873 ;
+C -1 ; WX 722 ; N Otilde ; B 60 -18 706 836 ;
+C -1 ; WX 333 ; N sfthyphen ; B 49 192 282 255 ;
+C -1 ; WX 500 ; N atilde ; B 17 -11 511 624 ;
+C -1 ; WX 500 ; N aring ; B 17 -11 476 707 ;
+C -1 ; WX 500 ; N adieresis ; B 17 -11 489 606 ;
+C -1 ; WX 722 ; N Ograve ; B 60 -18 706 876 ;
+C -1 ; WX 722 ; N Ocircumflex ; B 60 -18 706 873 ;
+C -1 ; WX 722 ; N Odieresis ; B 60 -18 706 818 ;
+C -1 ; WX 667 ; N Ntilde ; B -20 -15 727 836 ;
+C -1 ; WX 444 ; N edieresis ; B 31 -11 451 606 ;
+C -1 ; WX 444 ; N eacute ; B 31 -11 459 664 ;
+C -1 ; WX 444 ; N egrave ; B 31 -11 412 664 ;
+C -1 ; WX 333 ; N Icircumflex ; B -8 0 425 873 ;
+C -1 ; WX 444 ; N ecircumflex ; B 31 -11 441 661 ;
+C -1 ; WX 333 ; N Igrave ; B -8 0 384 876 ;
+C -1 ; WX 333 ; N Iacute ; B -8 0 403 876 ;
+C -1 ; WX 333 ; N Idieresis ; B -8 0 435 818 ;
+C -1 ; WX 400 ; N degree ; B 101 390 387 676 ;
+C -1 ; WX 611 ; N Ecircumflex ; B -1 0 634 873 ;
+C -1 ; WX 675 ; N minus ; B 86 220 590 286 ;
+C -1 ; WX 675 ; N multiply ; B 93 8 582 497 ;
+C -1 ; WX 675 ; N divide ; B 86 -11 590 517 ;
+C -1 ; WX 611 ; N Egrave ; B -1 0 634 876 ;
+C -1 ; WX 980 ; N trademark ; B 30 247 957 653 ;
+C -1 ; WX 722 ; N Oacute ; B 60 -18 706 876 ;
+C -1 ; WX 500 ; N thorn ; B -75 -205 469 683 ;
+C -1 ; WX 500 ; N eth ; B 27 -11 482 683 ;
+C -1 ; WX 611 ; N Eacute ; B -1 0 634 876 ;
+C -1 ; WX 444 ; N ccedilla ; B 26 -217 425 441 ;
+C -1 ; WX 278 ; N idieresis ; B 49 -11 353 606 ;
+C -1 ; WX 278 ; N iacute ; B 49 -11 356 664 ;
+C -1 ; WX 278 ; N igrave ; B 49 -11 284 664 ;
+C -1 ; WX 675 ; N plusminus ; B 86 0 590 568 ;
+C -1 ; WX 750 ; N onehalf ; B 34 -10 749 676 ;
+C -1 ; WX 750 ; N onequarter ; B 33 -10 736 676 ;
+C -1 ; WX 750 ; N threequarters ; B 23 -10 736 676 ;
+C -1 ; WX 278 ; N icircumflex ; B 34 -11 328 661 ;
+C -1 ; WX 611 ; N Edieresis ; B -1 0 634 818 ;
+C -1 ; WX 500 ; N ntilde ; B 14 -9 476 624 ;
+C -1 ; WX 611 ; N Aring ; B -51 0 564 904 ;
+C -1 ; WX 500 ; N odieresis ; B 27 -11 489 606 ;
+C -1 ; WX 500 ; N oacute ; B 27 -11 487 664 ;
+C -1 ; WX 500 ; N ograve ; B 27 -11 468 664 ;
+C -1 ; WX 500 ; N ocircumflex ; B 27 -11 468 661 ;
+C -1 ; WX 500 ; N otilde ; B 27 -11 496 624 ;
+C -1 ; WX 389 ; N scaron ; B 16 -13 454 661 ;
+C -1 ; WX 500 ; N udieresis ; B 42 -11 479 606 ;
+C -1 ; WX 500 ; N uacute ; B 42 -11 477 664 ;
+C -1 ; WX 500 ; N ugrave ; B 42 -11 475 664 ;
+C -1 ; WX 500 ; N ucircumflex ; B 42 -11 475 661 ;
+C -1 ; WX 444 ; N yacute ; B -24 -206 459 664 ;
+C -1 ; WX 389 ; N zcaron ; B -2 -81 434 661 ;
+C -1 ; WX 444 ; N ydieresis ; B -24 -206 441 606 ;
+C -1 ; WX 760 ; N copyright ; B 41 -18 719 666 ;
+C -1 ; WX 760 ; N registered ; B 41 -18 719 666 ;
+C -1 ; WX 611 ; N Atilde ; B -51 0 566 836 ;
+C -1 ; WX 250 ; N nbspace ; B 125 0 125 0 ;
+C -1 ; WX 667 ; N Ccedilla ; B 66 -217 689 666 ;
+C -1 ; WX 611 ; N Acircumflex ; B -51 0 564 873 ;
+C -1 ; WX 611 ; N Agrave ; B -51 0 564 876 ;
+C -1 ; WX 675 ; N logicalnot ; B 86 108 590 386 ;
+C -1 ; WX 611 ; N Aacute ; B -51 0 564 876 ;
+C -1 ; WX 722 ; N Eth ; B -8 0 700 653 ;
+C -1 ; WX 275 ; N brokenbar ; B 105 -18 171 666 ;
+C -1 ; WX 611 ; N Thorn ; B 0 0 569 653 ;
+C -1 ; WX 611 ; N Adieresis ; B -51 0 564 818 ;
+C -1 ; WX 500 ; N mu ; B -30 -209 497 428 ;
+C -1 ; WX 250 ; N .notdef ; B 125 0 125 0 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 994
+KPX A C -50
+KPX A Ccedilla -49
+KPX A G -44
+KPX A O -45
+KPX A Odieresis -45
+KPX A Q -43
+KPX A T -14
+KPX A U -56
+KPX A Uacute -56
+KPX A Ucircumflex -56
+KPX A Udieresis -56
+KPX A Ugrave -56
+KPX A V -81
+KPX A W -74
+KPX A Y -21
+KPX A a -3
+KPX A b 0
+KPX A c -18
+KPX A ccedilla -28
+KPX A comma 8
+KPX A d -3
+KPX A e -17
+KPX A g -25
+KPX A guillemotleft -44
+KPX A guilsinglleft -43
+KPX A hyphen -12
+KPX A o -17
+KPX A period 9
+KPX A q -12
+KPX A quotedblright -92
+KPX A quoteright -92
+KPX A t -6
+KPX A u -9
+KPX A v -50
+KPX A w -43
+KPX A y -57
+KPX Aacute C -50
+KPX Aacute G -44
+KPX Aacute O -45
+KPX Aacute Q -43
+KPX Aacute T -14
+KPX Aacute U -56
+KPX Aacute V -81
+KPX Aacute W -74
+KPX Aacute Y -21
+KPX Aacute a -3
+KPX Aacute b 0
+KPX Aacute c -18
+KPX Aacute comma 8
+KPX Aacute d -3
+KPX Aacute e -17
+KPX Aacute g -25
+KPX Aacute guillemotleft -44
+KPX Aacute guilsinglleft -43
+KPX Aacute hyphen -12
+KPX Aacute o -17
+KPX Aacute period 9
+KPX Aacute q -12
+KPX Aacute quoteright -92
+KPX Aacute t -6
+KPX Aacute u -9
+KPX Aacute v -50
+KPX Aacute w -43
+KPX Aacute y -57
+KPX Acircumflex C -50
+KPX Acircumflex G -44
+KPX Acircumflex O -45
+KPX Acircumflex Q -43
+KPX Acircumflex T -14
+KPX Acircumflex U -56
+KPX Acircumflex V -81
+KPX Acircumflex W -74
+KPX Acircumflex Y -21
+KPX Acircumflex comma 8
+KPX Acircumflex period 9
+KPX Adieresis C -50
+KPX Adieresis G -44
+KPX Adieresis O -45
+KPX Adieresis Q -43
+KPX Adieresis T -14
+KPX Adieresis U -56
+KPX Adieresis V -81
+KPX Adieresis W -74
+KPX Adieresis Y -21
+KPX Adieresis a -3
+KPX Adieresis b 0
+KPX Adieresis c -18
+KPX Adieresis comma 8
+KPX Adieresis d -3
+KPX Adieresis g -25
+KPX Adieresis guillemotleft -44
+KPX Adieresis guilsinglleft -43
+KPX Adieresis hyphen -12
+KPX Adieresis o -17
+KPX Adieresis period 9
+KPX Adieresis q -12
+KPX Adieresis quotedblright -92
+KPX Adieresis quoteright -92
+KPX Adieresis t -6
+KPX Adieresis u -9
+KPX Adieresis v -50
+KPX Adieresis w -43
+KPX Adieresis y -57
+KPX Agrave C -50
+KPX Agrave G -44
+KPX Agrave O -45
+KPX Agrave Q -43
+KPX Agrave T -14
+KPX Agrave U -56
+KPX Agrave V -81
+KPX Agrave W -74
+KPX Agrave Y -21
+KPX Agrave comma 8
+KPX Agrave period 9
+KPX Aring C -50
+KPX Aring G -44
+KPX Aring O -45
+KPX Aring Q -43
+KPX Aring T -14
+KPX Aring U -56
+KPX Aring V -81
+KPX Aring W -74
+KPX Aring Y -21
+KPX Aring a -3
+KPX Aring b 0
+KPX Aring c -18
+KPX Aring comma 8
+KPX Aring d -3
+KPX Aring e -17
+KPX Aring g -25
+KPX Aring guillemotleft -44
+KPX Aring guilsinglleft -43
+KPX Aring hyphen -12
+KPX Aring o -17
+KPX Aring period 9
+KPX Aring q -12
+KPX Aring quotedblright -92
+KPX Aring quoteright -92
+KPX Aring t -6
+KPX Aring u -9
+KPX Aring v -50
+KPX Aring w -43
+KPX Aring y -57
+KPX Atilde C -50
+KPX Atilde G -44
+KPX Atilde O -45
+KPX Atilde Q -43
+KPX Atilde T -14
+KPX Atilde U -56
+KPX Atilde V -81
+KPX Atilde W -74
+KPX Atilde Y -21
+KPX Atilde comma 8
+KPX Atilde period 8
+KPX B A -22
+KPX B AE -34
+KPX B Aacute -22
+KPX B Acircumflex -22
+KPX B Adieresis -22
+KPX B Aring -22
+KPX B Atilde -22
+KPX B O -13
+KPX B OE -5
+KPX B Oacute -13
+KPX B Ocircumflex -13
+KPX B Odieresis -13
+KPX B Ograve -13
+KPX B Oslash -13
+KPX B V -32
+KPX B W -29
+KPX B Y -39
+KPX C A -13
+KPX C AE -28
+KPX C Aacute -13
+KPX C Adieresis -13
+KPX C Aring -13
+KPX C H -13
+KPX C K -21
+KPX C O -19
+KPX C Oacute -19
+KPX C Odieresis -19
+KPX Ccedilla A -16
+KPX D A -35
+KPX D Aacute -35
+KPX D Acircumflex -35
+KPX D Adieresis -35
+KPX D Agrave -35
+KPX D Aring -35
+KPX D Atilde -35
+KPX D J -32
+KPX D T -9
+KPX D V -41
+KPX D W -35
+KPX D X -39
+KPX D Y -49
+KPX F A -72
+KPX F Aacute -72
+KPX F Acircumflex -72
+KPX F Adieresis -72
+KPX F Agrave -72
+KPX F Aring -72
+KPX F Atilde -72
+KPX F J -60
+KPX F O -40
+KPX F Odieresis -40
+KPX F a -76
+KPX F aacute -77
+KPX F adieresis -52
+KPX F ae -81
+KPX F aring -70
+KPX F comma -95
+KPX F e -82
+KPX F eacute -83
+KPX F hyphen -45
+KPX F i -36
+KPX F j -41
+KPX F o -79
+KPX F oacute -80
+KPX F odieresis -52
+KPX F oe -74
+KPX F oslash -80
+KPX F period -98
+KPX F r -52
+KPX F u -50
+KPX G A -17
+KPX G AE -29
+KPX G Aacute -17
+KPX G Acircumflex -17
+KPX G Adieresis -17
+KPX G Agrave -17
+KPX G Aring -17
+KPX G Atilde -17
+KPX G T -13
+KPX G V -5
+KPX G W -2
+KPX G Y -12
+KPX J A -40
+KPX J AE -52
+KPX J Adieresis -40
+KPX J Aring -40
+KPX K C -55
+KPX K G -53
+KPX K O -46
+KPX K OE -45
+KPX K Oacute -46
+KPX K Odieresis -46
+KPX K S 6
+KPX K T 21
+KPX K a -4
+KPX K adieresis -4
+KPX K ae -5
+KPX K aring -4
+KPX K e -18
+KPX K hyphen -57
+KPX K o -18
+KPX K oacute -18
+KPX K odieresis -18
+KPX K u -10
+KPX K udieresis -10
+KPX K y -87
+KPX L A 44
+KPX L AE 32
+KPX L Aacute 44
+KPX L Adieresis 44
+KPX L Aring 44
+KPX L C 6
+KPX L Ccedilla 4
+KPX L G 11
+KPX L O 10
+KPX L Oacute 10
+KPX L Ocircumflex 10
+KPX L Odieresis 10
+KPX L Ograve 10
+KPX L Otilde 10
+KPX L S 20
+KPX L T -13
+KPX L U -8
+KPX L Udieresis -8
+KPX L V -55
+KPX L W -48
+KPX L Y -20
+KPX L hyphen 47
+KPX L quotedblright -92
+KPX L quoteright -92
+KPX L u 12
+KPX L udieresis 10
+KPX L y -29
+KPX N A -20
+KPX N AE -32
+KPX N Aacute -20
+KPX N Adieresis -20
+KPX N Aring -20
+KPX N C -20
+KPX N Ccedilla -19
+KPX N G -14
+KPX N O -20
+KPX N Oacute -20
+KPX N Odieresis -20
+KPX N a -22
+KPX N aacute -23
+KPX N adieresis -23
+KPX N ae -26
+KPX N aring -23
+KPX N comma -13
+KPX N e -28
+KPX N eacute -30
+KPX N o -25
+KPX N oacute -26
+KPX N odieresis -26
+KPX N oslash -27
+KPX N period -16
+KPX N u -24
+KPX N udieresis -25
+KPX O A -37
+KPX O AE -68
+KPX O Aacute -37
+KPX O Adieresis -37
+KPX O Aring -37
+KPX O T -3
+KPX O V -45
+KPX O W -39
+KPX O X -40
+KPX O Y -50
+KPX Oacute A -37
+KPX Oacute T -3
+KPX Oacute V -45
+KPX Oacute W -39
+KPX Oacute Y -50
+KPX Ocircumflex T -3
+KPX Ocircumflex V -45
+KPX Ocircumflex Y -50
+KPX Odieresis A -37
+KPX Odieresis T -3
+KPX Odieresis V -45
+KPX Odieresis W -39
+KPX Odieresis X -40
+KPX Odieresis Y -50
+KPX Ograve T -3
+KPX Ograve V -45
+KPX Ograve Y -50
+KPX Oslash A -37
+KPX Otilde T -3
+KPX Otilde V -45
+KPX Otilde Y -50
+KPX P A -78
+KPX P AE -115
+KPX P Aacute -78
+KPX P Adieresis -78
+KPX P Aring -78
+KPX P J -89
+KPX P a -73
+KPX P aacute -73
+KPX P adieresis -64
+KPX P ae -79
+KPX P aring -73
+KPX P comma -117
+KPX P e -78
+KPX P eacute -78
+KPX P hyphen -64
+KPX P o -72
+KPX P oacute -72
+KPX P odieresis -64
+KPX P oe -66
+KPX P oslash -73
+KPX P period -120
+KPX R C -25
+KPX R Ccedilla -24
+KPX R G -19
+KPX R O -26
+KPX R OE -17
+KPX R Oacute -26
+KPX R Odieresis -26
+KPX R T 0
+KPX R U -35
+KPX R Udieresis -35
+KPX R V -31
+KPX R W -28
+KPX R Y -19
+KPX R a -2
+KPX R aacute -2
+KPX R adieresis -2
+KPX R ae -3
+KPX R aring -2
+KPX R e -15
+KPX R eacute -15
+KPX R hyphen -29
+KPX R o -15
+KPX R oacute -15
+KPX R odieresis -15
+KPX R oe -15
+KPX R u -7
+KPX R uacute -7
+KPX R udieresis -7
+KPX R y 3
+KPX S A -2
+KPX S AE -14
+KPX S Aacute -2
+KPX S Adieresis -2
+KPX S Aring -2
+KPX S T 1
+KPX S V 5
+KPX S W 8
+KPX S Y -1
+KPX S t -13
+KPX T A -33
+KPX T AE -45
+KPX T Aacute -33
+KPX T Acircumflex -33
+KPX T Adieresis -33
+KPX T Agrave -33
+KPX T Aring -33
+KPX T Atilde -33
+KPX T C -14
+KPX T G -7
+KPX T J -39
+KPX T O -21
+KPX T OE -8
+KPX T Oacute -21
+KPX T Ocircumflex -21
+KPX T Odieresis -21
+KPX T Ograve -21
+KPX T Oslash -21
+KPX T Otilde -21
+KPX T S -2
+KPX T V 41
+KPX T W 43
+KPX T Y 33
+KPX T a -80
+KPX T ae -81
+KPX T c -87
+KPX T colon -84
+KPX T comma -70
+KPX T e -90
+KPX T g -102
+KPX T guillemotleft -103
+KPX T guilsinglleft -102
+KPX T hyphen -68
+KPX T i -16
+KPX T j -20
+KPX T o -87
+KPX T oslash -89
+KPX T period -71
+KPX T r -87
+KPX T s -74
+KPX T semicolon -92
+KPX T u -86
+KPX T v -73
+KPX T w -69
+KPX T y -69
+KPX U A -49
+KPX U AE -69
+KPX U Aacute -49
+KPX U Acircumflex -49
+KPX U Adieresis -49
+KPX U Aring -49
+KPX U Atilde -49
+KPX U comma -35
+KPX U m -28
+KPX U n -29
+KPX U p -32
+KPX U period -39
+KPX U r -41
+KPX Uacute A -49
+KPX Uacute comma -35
+KPX Uacute m -28
+KPX Uacute n -29
+KPX Uacute p -32
+KPX Uacute period -39
+KPX Uacute r -41
+KPX Ucircumflex A -49
+KPX Udieresis A -49
+KPX Udieresis b 1
+KPX Udieresis comma -35
+KPX Udieresis m -28
+KPX Udieresis n -29
+KPX Udieresis p -32
+KPX Udieresis period -39
+KPX Udieresis r -41
+KPX Ugrave A -49
+KPX V A -65
+KPX V AE -101
+KPX V Aacute -65
+KPX V Acircumflex -65
+KPX V Adieresis -65
+KPX V Agrave -65
+KPX V Aring -65
+KPX V Atilde -65
+KPX V C -47
+KPX V G -41
+KPX V O -47
+KPX V Oacute -47
+KPX V Ocircumflex -47
+KPX V Odieresis -47
+KPX V Ograve -47
+KPX V Oslash -47
+KPX V Otilde -47
+KPX V S -15
+KPX V T 32
+KPX V a -66
+KPX V ae -71
+KPX V colon -81
+KPX V comma -76
+KPX V e -73
+KPX V g -83
+KPX V guillemotleft -81
+KPX V guilsinglleft -80
+KPX V hyphen -44
+KPX V i -16
+KPX V o -69
+KPX V oslash -71
+KPX V period -80
+KPX V r -44
+KPX V semicolon -78
+KPX V u -39
+KPX V y -12
+KPX W A -56
+KPX W AE -85
+KPX W Aacute -56
+KPX W Acircumflex -56
+KPX W Adieresis -56
+KPX W Agrave -56
+KPX W Aring -56
+KPX W Atilde -56
+KPX W C -38
+KPX W G -32
+KPX W O -39
+KPX W Oacute -39
+KPX W Ocircumflex -39
+KPX W Odieresis -39
+KPX W Ograve -39
+KPX W Oslash -39
+KPX W Otilde -39
+KPX W S -17
+KPX W T 30
+KPX W a -53
+KPX W ae -58
+KPX W colon -76
+KPX W comma -58
+KPX W e -59
+KPX W g -74
+KPX W guillemotleft -68
+KPX W guilsinglleft -67
+KPX W hyphen -31
+KPX W i -18
+KPX W o -56
+KPX W oslash -58
+KPX W period -61
+KPX W r -39
+KPX W semicolon -73
+KPX W u -34
+KPX W y -7
+KPX X C -48
+KPX X O -44
+KPX X Odieresis -44
+KPX X Q -42
+KPX X a -2
+KPX X e -15
+KPX X hyphen -41
+KPX X o -15
+KPX X u -7
+KPX X y -62
+KPX Y A -27
+KPX Y AE -39
+KPX Y Aacute -27
+KPX Y Acircumflex -27
+KPX Y Adieresis -27
+KPX Y Agrave -27
+KPX Y Aring -27
+KPX Y Atilde -27
+KPX Y C -51
+KPX Y G -45
+KPX Y O -52
+KPX Y Oacute -52
+KPX Y Ocircumflex -52
+KPX Y Odieresis -52
+KPX Y Ograve -52
+KPX Y Oslash -51
+KPX Y Otilde -52
+KPX Y S -15
+KPX Y T 32
+KPX Y a -72
+KPX Y ae -75
+KPX Y colon -78
+KPX Y comma -64
+KPX Y e -78
+KPX Y g -94
+KPX Y guillemotleft -93
+KPX Y guilsinglleft -92
+KPX Y hyphen -60
+KPX Y i -16
+KPX Y o -75
+KPX Y oslash -77
+KPX Y p -52
+KPX Y period -65
+KPX Y semicolon -86
+KPX Y u -58
+KPX Y v -35
+KPX Z v -12
+KPX Z y -30
+KPX a j -22
+KPX a quoteright -29
+KPX a v 0
+KPX a w 4
+KPX a y 4
+KPX aacute v 0
+KPX aacute w 4
+KPX aacute y 4
+KPX adieresis v 0
+KPX adieresis w 4
+KPX adieresis y 4
+KPX ae v 2
+KPX ae w 5
+KPX ae y 5
+KPX agrave v 0
+KPX agrave w 4
+KPX agrave y 4
+KPX aring v 0
+KPX aring w 4
+KPX aring y 4
+KPX b v -10
+KPX b w -7
+KPX b y -7
+KPX c h -30
+KPX c k -29
+KPX comma one -42
+KPX comma quotedblright -40
+KPX comma quoteright -40
+KPX e quoteright -21
+KPX e t -16
+KPX e v 0
+KPX e w 2
+KPX e x -10
+KPX e y 2
+KPX eacute v 0
+KPX eacute w 2
+KPX eacute y 2
+KPX ecircumflex v 0
+KPX ecircumflex w 2
+KPX ecircumflex y 2
+KPX eight four 13
+KPX eight one -58
+KPX eight seven -1
+KPX f a -26
+KPX f aacute -27
+KPX f adieresis -2
+KPX f ae -30
+KPX f aring -17
+KPX f e -32
+KPX f eacute -33
+KPX f f 30
+KPX f i 17
+KPX f j 13
+KPX f l 42
+KPX f o -29
+KPX f oacute -30
+KPX f odieresis -2
+KPX f oe -25
+KPX f oslash -31
+KPX f quoteright 18
+KPX f s -20
+KPX f t 18
+KPX five four -5
+KPX five one -71
+KPX five seven -28
+KPX four four 12
+KPX four one -71
+KPX four seven -27
+KPX g a -41
+KPX g adieresis -42
+KPX g ae -46
+KPX g aring -42
+KPX g e -45
+KPX g eacute -45
+KPX g l -46
+KPX g oacute -41
+KPX g odieresis -41
+KPX g r -21
+KPX guillemotright A -24
+KPX guillemotright AE -49
+KPX guillemotright Aacute -24
+KPX guillemotright Adieresis -24
+KPX guillemotright Aring -24
+KPX guillemotright T -76
+KPX guillemotright V -75
+KPX guillemotright W -66
+KPX guillemotright Y -80
+KPX guilsinglright A -23
+KPX guilsinglright AE -48
+KPX guilsinglright Aacute -23
+KPX guilsinglright Adieresis -23
+KPX guilsinglright Aring -23
+KPX guilsinglright T -75
+KPX guilsinglright V -74
+KPX guilsinglright W -65
+KPX guilsinglright Y -79
+KPX h quoteright -31
+KPX h y -5
+KPX hyphen A 3
+KPX hyphen AE -22
+KPX hyphen Aacute 3
+KPX hyphen Adieresis 3
+KPX hyphen Aring 3
+KPX hyphen T -45
+KPX hyphen V -43
+KPX hyphen W -34
+KPX hyphen Y -53
+KPX i T -10
+KPX i j -31
+KPX k a 12
+KPX k aacute 12
+KPX k adieresis 12
+KPX k ae 9
+KPX k aring 12
+KPX k comma 27
+KPX k e 5
+KPX k eacute 5
+KPX k g -27
+KPX k hyphen -27
+KPX k o 6
+KPX k oacute 6
+KPX k odieresis 6
+KPX k period 26
+KPX k s 7
+KPX k u 8
+KPX k udieresis 8
+KPX l v -13
+KPX l y -9
+KPX m p -4
+KPX m v -6
+KPX m w -4
+KPX m y -3
+KPX n T -40
+KPX n p -7
+KPX n quoteright -34
+KPX n v -10
+KPX n w -7
+KPX n y -7
+KPX nine four 1
+KPX nine one -65
+KPX nine seven -5
+KPX o T -62
+KPX o quoteright -24
+KPX o t -14
+KPX o v -18
+KPX o w -15
+KPX o x -32
+KPX o y -15
+KPX oacute v -18
+KPX oacute w -15
+KPX oacute y -15
+KPX ocircumflex t -16
+KPX odieresis t -16
+KPX odieresis v -18
+KPX odieresis w -15
+KPX odieresis x -32
+KPX odieresis y -15
+KPX ograve v -18
+KPX ograve w -15
+KPX ograve y -15
+KPX one comma -52
+KPX one eight -57
+KPX one five -55
+KPX one four -69
+KPX one nine -61
+KPX one one -69
+KPX one period -56
+KPX one seven -61
+KPX one six -50
+KPX one three -55
+KPX one two -50
+KPX one zero -42
+KPX p t -14
+KPX p y -7
+KPX period one -43
+KPX period quotedblright -39
+KPX period quoteright -39
+KPX q c -13
+KPX q u -11
+KPX quotedblbase A 3
+KPX quotedblbase AE -11
+KPX quotedblbase T -62
+KPX quotedblbase V -96
+KPX quotedblbase W -84
+KPX quotedblbase Y -68
+KPX quotedblleft A -87
+KPX quotedblleft AE -141
+KPX quotedblleft Aacute -87
+KPX quotedblleft Adieresis -87
+KPX quotedblleft Aring -87
+KPX quotedblleft T -18
+KPX quotedblleft V -17
+KPX quotedblleft W -15
+KPX quotedblleft Y -25
+KPX quotedblright A -94
+KPX quotedblright AE -148
+KPX quotedblright Aacute -94
+KPX quotedblright Adieresis -94
+KPX quotedblright Aring -94
+KPX quotedblright T -21
+KPX quotedblright V -21
+KPX quotedblright W -18
+KPX quotedblright Y -30
+KPX quoteleft A -78
+KPX quoteleft AE -132
+KPX quoteleft Aacute -78
+KPX quoteleft Adieresis -78
+KPX quoteleft Aring -78
+KPX quoteleft T -9
+KPX quoteleft V -8
+KPX quoteleft W -5
+KPX quoteleft Y -15
+KPX quoteright A -87
+KPX quoteright AE -141
+KPX quoteright Aacute -87
+KPX quoteright Adieresis -87
+KPX quoteright Aring -87
+KPX quoteright comma -74
+KPX quoteright d -80
+KPX quoteright o -78
+KPX quoteright period -78
+KPX quoteright r -57
+KPX quoteright s -63
+KPX quoteright t -49
+KPX quoteright v -31
+KPX quoteright w -26
+KPX quoteright y -25
+KPX r a -27
+KPX r aacute -27
+KPX r acircumflex -27
+KPX r adieresis -27
+KPX r ae -34
+KPX r agrave -27
+KPX r aring -27
+KPX r c -24
+KPX r ccedilla -15
+KPX r colon -28
+KPX r comma -68
+KPX r d -30
+KPX r e -32
+KPX r eacute -32
+KPX r ecircumflex -32
+KPX r egrave -32
+KPX r f 23
+KPX r g -19
+KPX r h -16
+KPX r hyphen -51
+KPX r i 8
+KPX r j 3
+KPX r k -15
+KPX r l -21
+KPX r m 17
+KPX r n 16
+KPX r o -26
+KPX r oacute -26
+KPX r ocircumflex -26
+KPX r odieresis -26
+KPX r oe -21
+KPX r ograve -26
+KPX r oslash -27
+KPX r p 13
+KPX r period -72
+KPX r q -29
+KPX r quoteright -4
+KPX r r 4
+KPX r s -16
+KPX r semicolon -28
+KPX r t 12
+KPX r u 11
+KPX r v 29
+KPX r w 32
+KPX r x 8
+KPX r y 32
+KPX r z 0
+KPX s quoteright -21
+KPX s t -12
+KPX seven colon -88
+KPX seven comma -79
+KPX seven four -64
+KPX seven one -47
+KPX seven period -82
+KPX seven seven -11
+KPX seven six -37
+KPX six four 17
+KPX six one -70
+KPX six seven -37
+KPX t S -9
+KPX t a -6
+KPX t aacute -6
+KPX t adieresis -6
+KPX t ae -10
+KPX t aring -6
+KPX t colon -29
+KPX t e -13
+KPX t eacute -13
+KPX t h -12
+KPX t o -11
+KPX t oacute -11
+KPX t odieresis -11
+KPX t quoteright -21
+KPX t semicolon -26
+KPX three four -9
+KPX three one -77
+KPX three seven -15
+KPX two four -12
+KPX two one -48
+KPX two seven -22
+KPX u quoteright -32
+KPX v a -24
+KPX v aacute -26
+KPX v acircumflex -26
+KPX v adieresis -26
+KPX v ae -29
+KPX v agrave -26
+KPX v aring -26
+KPX v atilde -26
+KPX v c -26
+KPX v colon -48
+KPX v comma -47
+KPX v e -30
+KPX v eacute -32
+KPX v ecircumflex -32
+KPX v egrave -32
+KPX v g -36
+KPX v hyphen 0
+KPX v l -29
+KPX v o -26
+KPX v oacute -28
+KPX v odieresis -28
+KPX v ograve -28
+KPX v oslash -29
+KPX v period -51
+KPX v s -30
+KPX v semicolon -48
+KPX w a -26
+KPX w aacute -27
+KPX w acircumflex -27
+KPX w adieresis -27
+KPX w ae -31
+KPX w agrave -27
+KPX w aring -27
+KPX w atilde -27
+KPX w c -28
+KPX w colon -49
+KPX w comma -46
+KPX w e -32
+KPX w eacute -33
+KPX w ecircumflex -33
+KPX w egrave -33
+KPX w g -38
+KPX w hyphen -3
+KPX w l -30
+KPX w o -28
+KPX w oacute -30
+KPX w odieresis -30
+KPX w ograve -30
+KPX w oslash -30
+KPX w period -51
+KPX w s -32
+KPX w semicolon -49
+KPX x a 5
+KPX x c -2
+KPX x e -2
+KPX x eacute -2
+KPX x o 0
+KPX x q 1
+KPX y a -14
+KPX y aacute -16
+KPX y acircumflex -16
+KPX y adieresis -16
+KPX y ae -19
+KPX y agrave -16
+KPX y aring -16
+KPX y atilde -16
+KPX y c -16
+KPX y colon -48
+KPX y comma -23
+KPX y e -20
+KPX y eacute -22
+KPX y ecircumflex -22
+KPX y egrave -22
+KPX y g -36
+KPX y hyphen 5
+KPX y l -20
+KPX y o -16
+KPX y oacute -18
+KPX y odieresis -18
+KPX y ograve -18
+KPX y oslash -19
+KPX y period -27
+KPX y s -20
+KPX y semicolon -46
+KPX zero four 14
+KPX zero one -51
+KPX zero seven -3
+EndKernPairs
+EndKernData
+EndFontMetrics
diff --git a/misc/gs_afm/TimesRo.afm b/misc/gs_afm/TimesRo.afm
new file mode 100644
index 0000000000..a272b449b5
--- /dev/null
+++ b/misc/gs_afm/TimesRo.afm
@@ -0,0 +1,1257 @@
+StartFontMetrics 3.0
+Comment Copyright URW Software, Copyright 1994 by URW
+Comment Creation Date: 11/17/1994
+Comment See the file PUBLIC (Aladdin Free Public License) for license conditions.
+FontName NimbusRomNo9L-Regu
+FullName Nimbus Roman No9 L Regular
+FamilyName Nimbus Roman No9 L
+Weight Regular
+ItalicAngle 0.0
+IsFixedPitch false
+UnderlinePosition -100
+UnderlineThickness 50
+Version 001.005
+Notice URW Software, Copyright 1994 by URW
+EncodingScheme AdobeStandardEncoding
+FontBBox -168 -218 1000 915
+CapHeight 662
+XHeight 450
+Descender -217
+Ascender 683
+StartCharMetrics 232
+C 32 ; WX 250 ; N space ; B 125 0 125 0 ;
+C 33 ; WX 333 ; N exclam ; B 130 -9 236 676 ;
+C 34 ; WX 408 ; N quotedbl ; B 77 431 331 676 ;
+C 35 ; WX 500 ; N numbersign ; B 5 0 496 662 ;
+C 36 ; WX 500 ; N dollar ; B 44 -87 457 727 ;
+C 37 ; WX 833 ; N percent ; B 61 -13 772 676 ;
+C 38 ; WX 778 ; N ampersand ; B 42 -13 750 676 ;
+C 39 ; WX 333 ; N quoteright ; B 79 433 218 676 ;
+C 40 ; WX 333 ; N parenleft ; B 48 -177 304 676 ;
+C 41 ; WX 333 ; N parenright ; B 29 -177 285 676 ;
+C 42 ; WX 500 ; N asterisk ; B 69 265 432 676 ;
+C 43 ; WX 564 ; N plus ; B 30 0 534 506 ;
+C 44 ; WX 250 ; N comma ; B 56 -141 195 102 ;
+C 45 ; WX 333 ; N hyphen ; B 39 194 285 257 ;
+C 46 ; WX 250 ; N period ; B 70 -11 181 100 ;
+C 47 ; WX 278 ; N slash ; B -9 -14 287 676 ;
+C 48 ; WX 500 ; N zero ; B 24 -14 476 676 ;
+C 49 ; WX 500 ; N one ; B 111 0 394 676 ;
+C 50 ; WX 500 ; N two ; B 30 0 475 676 ;
+C 51 ; WX 500 ; N three ; B 43 -14 431 676 ;
+C 52 ; WX 500 ; N four ; B 12 0 472 676 ;
+C 53 ; WX 500 ; N five ; B 32 -14 438 688 ;
+C 54 ; WX 500 ; N six ; B 34 -14 468 684 ;
+C 55 ; WX 500 ; N seven ; B 20 -8 449 662 ;
+C 56 ; WX 500 ; N eight ; B 56 -14 445 676 ;
+C 57 ; WX 500 ; N nine ; B 30 -22 459 676 ;
+C 58 ; WX 278 ; N colon ; B 81 -11 192 459 ;
+C 59 ; WX 278 ; N semicolon ; B 80 -141 219 459 ;
+C 60 ; WX 564 ; N less ; B 28 -10 536 516 ;
+C 61 ; WX 564 ; N equal ; B 30 120 534 386 ;
+C 62 ; WX 564 ; N greater ; B 28 -10 536 516 ;
+C 63 ; WX 444 ; N question ; B 68 -8 414 676 ;
+C 64 ; WX 921 ; N at ; B 116 -14 809 676 ;
+C 65 ; WX 722 ; N A ; B 15 0 706 674 ;
+C 66 ; WX 667 ; N B ; B 17 0 593 662 ;
+C 67 ; WX 667 ; N C ; B 28 -14 633 676 ;
+C 68 ; WX 722 ; N D ; B 16 0 685 662 ;
+C 69 ; WX 611 ; N E ; B 12 0 597 662 ;
+C 70 ; WX 556 ; N F ; B 12 0 546 662 ;
+C 71 ; WX 722 ; N G ; B 32 -14 709 676 ;
+C 72 ; WX 722 ; N H ; B 19 0 702 662 ;
+C 73 ; WX 333 ; N I ; B 18 0 315 662 ;
+C 74 ; WX 389 ; N J ; B 10 -14 370 662 ;
+C 75 ; WX 722 ; N K ; B 34 0 723 662 ;
+C 76 ; WX 611 ; N L ; B 12 0 598 662 ;
+C 77 ; WX 889 ; N M ; B 12 0 863 662 ;
+C 78 ; WX 722 ; N N ; B 12 -11 707 662 ;
+C 79 ; WX 722 ; N O ; B 34 -14 688 676 ;
+C 80 ; WX 556 ; N P ; B 16 0 542 662 ;
+C 81 ; WX 722 ; N Q ; B 34 -178 701 676 ;
+C 82 ; WX 667 ; N R ; B 17 0 659 662 ;
+C 83 ; WX 556 ; N S ; B 42 -14 491 676 ;
+C 84 ; WX 611 ; N T ; B 17 0 593 662 ;
+C 85 ; WX 722 ; N U ; B 14 -14 705 662 ;
+C 86 ; WX 722 ; N V ; B 16 -11 697 662 ;
+C 87 ; WX 944 ; N W ; B 5 -11 932 662 ;
+C 88 ; WX 722 ; N X ; B 10 0 704 662 ;
+C 89 ; WX 722 ; N Y ; B 22 0 703 662 ;
+C 90 ; WX 611 ; N Z ; B 9 0 597 662 ;
+C 91 ; WX 333 ; N bracketleft ; B 88 -156 299 662 ;
+C 92 ; WX 278 ; N backslash ; B -9 -14 287 676 ;
+C 93 ; WX 333 ; N bracketright ; B 34 -156 245 662 ;
+C 94 ; WX 469 ; N asciicircum ; B 24 297 446 662 ;
+C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
+C 96 ; WX 333 ; N quoteleft ; B 115 433 254 676 ;
+C 97 ; WX 444 ; N a ; B 37 -10 442 460 ;
+C 98 ; WX 500 ; N b ; B 3 -10 468 683 ;
+C 99 ; WX 444 ; N c ; B 25 -10 412 460 ;
+C 100 ; WX 500 ; N d ; B 27 -10 491 683 ;
+C 101 ; WX 444 ; N e ; B 25 -10 424 460 ;
+C 102 ; WX 333 ; N f ; B 20 0 383 683 ;
+C 103 ; WX 500 ; N g ; B 28 -218 470 460 ;
+C 104 ; WX 500 ; N h ; B 9 0 487 683 ;
+C 105 ; WX 278 ; N i ; B 16 0 253 683 ;
+C 106 ; WX 278 ; N j ; B -70 -218 194 683 ;
+C 107 ; WX 500 ; N k ; B 7 0 505 683 ;
+C 108 ; WX 278 ; N l ; B 19 0 257 683 ;
+C 109 ; WX 778 ; N m ; B 16 0 775 460 ;
+C 110 ; WX 500 ; N n ; B 16 0 485 460 ;
+C 111 ; WX 500 ; N o ; B 29 -10 470 460 ;
+C 112 ; WX 500 ; N p ; B 5 -217 470 460 ;
+C 113 ; WX 500 ; N q ; B 24 -217 488 461 ;
+C 114 ; WX 333 ; N r ; B 5 0 335 460 ;
+C 115 ; WX 389 ; N s ; B 51 -10 348 459 ;
+C 116 ; WX 278 ; N t ; B 13 -10 279 579 ;
+C 117 ; WX 500 ; N u ; B 9 -10 479 450 ;
+C 118 ; WX 500 ; N v ; B 19 -14 477 450 ;
+C 119 ; WX 722 ; N w ; B 21 -14 694 450 ;
+C 120 ; WX 500 ; N x ; B 17 0 479 450 ;
+C 121 ; WX 500 ; N y ; B 14 -218 475 450 ;
+C 122 ; WX 444 ; N z ; B 27 0 418 450 ;
+C 123 ; WX 480 ; N braceleft ; B 100 -181 350 680 ;
+C 124 ; WX 200 ; N bar ; B 67 -14 133 676 ;
+C 125 ; WX 480 ; N braceright ; B 130 -181 380 680 ;
+C 126 ; WX 541 ; N asciitilde ; B 40 186 502 320 ;
+C 161 ; WX 333 ; N exclamdown ; B 97 -218 203 468 ;
+C 162 ; WX 500 ; N cent ; B 53 -138 448 579 ;
+C 163 ; WX 500 ; N sterling ; B 12 -8 490 676 ;
+C 164 ; WX 167 ; N fraction ; B -168 -14 331 676 ;
+C 165 ; WX 500 ; N yen ; B -53 0 512 662 ;
+C 166 ; WX 500 ; N florin ; B 7 -189 490 676 ;
+C 167 ; WX 500 ; N section ; B 70 -148 426 676 ;
+C 168 ; WX 500 ; N currency ; B -22 58 522 602 ;
+C 169 ; WX 180 ; N quotesingle ; B 48 431 133 676 ;
+C 170 ; WX 444 ; N quotedblleft ; B 43 433 414 676 ;
+C 171 ; WX 500 ; N guillemotleft ; B 42 33 456 416 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 63 33 285 416 ;
+C 173 ; WX 333 ; N guilsinglright ; B 48 33 270 416 ;
+C 174 ; WX 556 ; N fi ; B 31 0 521 683 ;
+C 175 ; WX 556 ; N fl ; B 32 0 521 683 ;
+C 177 ; WX 500 ; N endash ; B 0 201 500 250 ;
+C 178 ; WX 500 ; N dagger ; B 59 -149 442 676 ;
+C 179 ; WX 500 ; N daggerdbl ; B 58 -153 442 676 ;
+C 180 ; WX 250 ; N periodcentered ; B 70 199 181 310 ;
+C 182 ; WX 453 ; N paragraph ; B -22 -154 450 662 ;
+C 183 ; WX 350 ; N bullet ; B 40 196 310 466 ;
+C 184 ; WX 333 ; N quotesinglbase ; B 79 -141 218 102 ;
+C 185 ; WX 444 ; N quotedblbase ; B 45 -141 416 102 ;
+C 186 ; WX 444 ; N quotedblright ; B 30 433 401 676 ;
+C 187 ; WX 500 ; N guillemotright ; B 44 33 458 416 ;
+C 188 ; WX 1000 ; N ellipsis ; B 111 -11 888 100 ;
+C 189 ; WX 1000 ; N perthousand ; B 7 -19 994 706 ;
+C 191 ; WX 444 ; N questiondown ; B 30 -218 376 467 ;
+C 193 ; WX 333 ; N grave ; B 19 507 242 678 ;
+C 194 ; WX 333 ; N acute ; B 93 507 317 678 ;
+C 195 ; WX 333 ; N circumflex ; B 11 507 322 674 ;
+C 196 ; WX 333 ; N tilde ; B 1 532 331 638 ;
+C 197 ; WX 333 ; N macron ; B 11 547 322 601 ;
+C 198 ; WX 333 ; N breve ; B 26 507 307 664 ;
+C 199 ; WX 333 ; N dotaccent ; B 118 523 217 622 ;
+C 200 ; WX 333 ; N dieresis ; B 18 523 316 622 ;
+C 202 ; WX 333 ; N ring ; B 67 512 266 711 ;
+C 203 ; WX 333 ; N cedilla ; B 52 -215 261 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B -3 507 377 678 ;
+C 206 ; WX 333 ; N ogonek ; B 64 -165 249 0 ;
+C 207 ; WX 333 ; N caron ; B 11 507 322 674 ;
+C 208 ; WX 1000 ; N emdash ; B 0 201 1000 250 ;
+C 225 ; WX 889 ; N AE ; B 0 0 863 662 ;
+C 227 ; WX 276 ; N ordfeminine ; B 4 394 270 676 ;
+C 232 ; WX 611 ; N Lslash ; B 12 0 598 662 ;
+C 233 ; WX 722 ; N Oslash ; B 34 -80 688 734 ;
+C 234 ; WX 889 ; N OE ; B 30 -6 885 668 ;
+C 235 ; WX 310 ; N ordmasculine ; B 6 394 304 676 ;
+C 241 ; WX 667 ; N ae ; B 38 -10 632 460 ;
+C 245 ; WX 278 ; N dotlessi ; B 16 0 253 460 ;
+C 248 ; WX 278 ; N lslash ; B 19 0 259 683 ;
+C 249 ; WX 500 ; N oslash ; B 29 -112 470 551 ;
+C 250 ; WX 722 ; N oe ; B 30 -10 690 460 ;
+C 251 ; WX 500 ; N germandbls ; B 12 -9 468 683 ;
+C -1 ; WX 722 ; N Yacute ; B 22 0 703 890 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 14 -14 705 886 ;
+C -1 ; WX 722 ; N Ugrave ; B 14 -14 705 890 ;
+C -1 ; WX 611 ; N Zcaron ; B 9 0 597 886 ;
+C -1 ; WX 722 ; N Ydieresis ; B 22 0 703 834 ;
+C -1 ; WX 300 ; N threesuperior ; B 15 262 291 676 ;
+C -1 ; WX 722 ; N Uacute ; B 14 -14 705 890 ;
+C -1 ; WX 300 ; N twosuperior ; B 1 270 296 676 ;
+C -1 ; WX 722 ; N Udieresis ; B 14 -14 705 834 ;
+C -1 ; WX 250 ; N middot ; B 70 199 181 310 ;
+C -1 ; WX 300 ; N onesuperior ; B 57 270 248 676 ;
+C -1 ; WX 444 ; N aacute ; B 37 -10 442 678 ;
+C -1 ; WX 444 ; N agrave ; B 37 -10 442 678 ;
+C -1 ; WX 444 ; N acircumflex ; B 37 -10 442 674 ;
+C -1 ; WX 556 ; N Scaron ; B 42 -14 491 886 ;
+C -1 ; WX 722 ; N Otilde ; B 34 -14 688 850 ;
+C -1 ; WX 333 ; N sfthyphen ; B 39 194 285 257 ;
+C -1 ; WX 444 ; N atilde ; B 37 -10 442 638 ;
+C -1 ; WX 444 ; N aring ; B 37 -10 442 722 ;
+C -1 ; WX 444 ; N adieresis ; B 37 -10 442 622 ;
+C -1 ; WX 722 ; N Ograve ; B 34 -14 688 890 ;
+C -1 ; WX 722 ; N Ocircumflex ; B 34 -14 688 886 ;
+C -1 ; WX 722 ; N Odieresis ; B 34 -14 688 834 ;
+C -1 ; WX 722 ; N Ntilde ; B 12 -11 707 850 ;
+C -1 ; WX 444 ; N edieresis ; B 25 -10 424 622 ;
+C -1 ; WX 444 ; N eacute ; B 25 -10 424 678 ;
+C -1 ; WX 444 ; N egrave ; B 25 -10 424 678 ;
+C -1 ; WX 333 ; N Icircumflex ; B 11 0 322 886 ;
+C -1 ; WX 444 ; N ecircumflex ; B 25 -10 424 674 ;
+C -1 ; WX 333 ; N Igrave ; B 18 0 315 890 ;
+C -1 ; WX 333 ; N Iacute ; B 18 0 317 890 ;
+C -1 ; WX 333 ; N Idieresis ; B 18 0 316 834 ;
+C -1 ; WX 400 ; N degree ; B 57 390 343 676 ;
+C -1 ; WX 611 ; N Ecircumflex ; B 12 0 597 886 ;
+C -1 ; WX 564 ; N minus ; B 30 220 534 286 ;
+C -1 ; WX 564 ; N multiply ; B 38 8 527 497 ;
+C -1 ; WX 564 ; N divide ; B 30 -10 534 516 ;
+C -1 ; WX 611 ; N Egrave ; B 12 0 597 890 ;
+C -1 ; WX 980 ; N trademark ; B 30 256 957 662 ;
+C -1 ; WX 722 ; N Oacute ; B 34 -14 688 890 ;
+C -1 ; WX 500 ; N thorn ; B 5 -217 470 683 ;
+C -1 ; WX 500 ; N eth ; B 29 -10 471 686 ;
+C -1 ; WX 611 ; N Eacute ; B 12 0 597 890 ;
+C -1 ; WX 444 ; N ccedilla ; B 25 -215 412 460 ;
+C -1 ; WX 278 ; N idieresis ; B 11 0 269 622 ;
+C -1 ; WX 278 ; N iacute ; B 16 0 290 678 ;
+C -1 ; WX 278 ; N igrave ; B -8 0 253 678 ;
+C -1 ; WX 564 ; N plusminus ; B 30 0 534 568 ;
+C -1 ; WX 750 ; N onehalf ; B 31 -14 746 676 ;
+C -1 ; WX 750 ; N onequarter ; B 37 -14 718 676 ;
+C -1 ; WX 750 ; N threequarters ; B 15 -14 718 676 ;
+C -1 ; WX 278 ; N icircumflex ; B -16 0 295 674 ;
+C -1 ; WX 611 ; N Edieresis ; B 12 0 597 834 ;
+C -1 ; WX 500 ; N ntilde ; B 16 0 485 638 ;
+C -1 ; WX 722 ; N Aring ; B 15 0 706 915 ;
+C -1 ; WX 500 ; N odieresis ; B 29 -10 470 622 ;
+C -1 ; WX 500 ; N oacute ; B 29 -10 470 678 ;
+C -1 ; WX 500 ; N ograve ; B 29 -10 470 678 ;
+C -1 ; WX 500 ; N ocircumflex ; B 29 -10 470 674 ;
+C -1 ; WX 500 ; N otilde ; B 29 -10 470 638 ;
+C -1 ; WX 389 ; N scaron ; B 39 -10 350 674 ;
+C -1 ; WX 500 ; N udieresis ; B 9 -10 479 622 ;
+C -1 ; WX 500 ; N uacute ; B 9 -10 479 678 ;
+C -1 ; WX 500 ; N ugrave ; B 9 -10 479 678 ;
+C -1 ; WX 500 ; N ucircumflex ; B 9 -10 479 674 ;
+C -1 ; WX 500 ; N yacute ; B 14 -218 475 678 ;
+C -1 ; WX 444 ; N zcaron ; B 27 0 418 674 ;
+C -1 ; WX 500 ; N ydieresis ; B 14 -218 475 622 ;
+C -1 ; WX 760 ; N copyright ; B 38 -14 722 676 ;
+C -1 ; WX 760 ; N registered ; B 38 -14 722 676 ;
+C -1 ; WX 722 ; N Atilde ; B 15 0 706 850 ;
+C -1 ; WX 250 ; N nbspace ; B 125 0 125 0 ;
+C -1 ; WX 667 ; N Ccedilla ; B 28 -215 633 676 ;
+C -1 ; WX 722 ; N Acircumflex ; B 15 0 706 886 ;
+C -1 ; WX 722 ; N Agrave ; B 15 0 706 890 ;
+C -1 ; WX 564 ; N logicalnot ; B 30 108 534 386 ;
+C -1 ; WX 722 ; N Aacute ; B 15 0 706 890 ;
+C -1 ; WX 722 ; N Eth ; B 16 0 685 662 ;
+C -1 ; WX 200 ; N brokenbar ; B 67 -14 133 676 ;
+C -1 ; WX 556 ; N Thorn ; B 16 0 542 662 ;
+C -1 ; WX 722 ; N Adieresis ; B 15 0 706 834 ;
+C -1 ; WX 500 ; N mu ; B 36 -218 512 450 ;
+C -1 ; WX 250 ; N .notdef ; B 125 0 125 0 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 998
+KPX A C -53
+KPX A Ccedilla -57
+KPX A G -57
+KPX A O -58
+KPX A Odieresis -58
+KPX A Q -60
+KPX A T -54
+KPX A U -62
+KPX A Uacute -62
+KPX A Ucircumflex -62
+KPX A Udieresis -62
+KPX A Ugrave -62
+KPX A V -132
+KPX A W -113
+KPX A Y -81
+KPX A a -6
+KPX A b -19
+KPX A c -29
+KPX A ccedilla -29
+KPX A comma -3
+KPX A d -28
+KPX A e -27
+KPX A g -19
+KPX A guillemotleft -64
+KPX A guilsinglleft -74
+KPX A hyphen -23
+KPX A o -40
+KPX A period -10
+KPX A q -21
+KPX A quotedblright -91
+KPX A quoteright -116
+KPX A t -20
+KPX A u -28
+KPX A v -82
+KPX A w -73
+KPX A y -83
+KPX Aacute C -53
+KPX Aacute G -57
+KPX Aacute O -58
+KPX Aacute Q -60
+KPX Aacute T -54
+KPX Aacute U -62
+KPX Aacute V -132
+KPX Aacute W -113
+KPX Aacute Y -81
+KPX Aacute a -6
+KPX Aacute b -19
+KPX Aacute c -29
+KPX Aacute comma -3
+KPX Aacute d -28
+KPX Aacute e -27
+KPX Aacute g -19
+KPX Aacute guillemotleft -64
+KPX Aacute guilsinglleft -74
+KPX Aacute hyphen -23
+KPX Aacute o -40
+KPX Aacute period -10
+KPX Aacute q -21
+KPX Aacute quoteright -116
+KPX Aacute t -20
+KPX Aacute u -28
+KPX Aacute v -82
+KPX Aacute w -73
+KPX Aacute y -83
+KPX Acircumflex C -53
+KPX Acircumflex G -57
+KPX Acircumflex O -58
+KPX Acircumflex Q -60
+KPX Acircumflex T -54
+KPX Acircumflex U -62
+KPX Acircumflex V -132
+KPX Acircumflex W -113
+KPX Acircumflex Y -81
+KPX Acircumflex comma -3
+KPX Acircumflex period -10
+KPX Adieresis C -53
+KPX Adieresis G -57
+KPX Adieresis O -58
+KPX Adieresis Q -60
+KPX Adieresis T -54
+KPX Adieresis U -62
+KPX Adieresis V -132
+KPX Adieresis W -113
+KPX Adieresis Y -81
+KPX Adieresis a -6
+KPX Adieresis b -19
+KPX Adieresis c -29
+KPX Adieresis comma -3
+KPX Adieresis d -28
+KPX Adieresis g -19
+KPX Adieresis guillemotleft -64
+KPX Adieresis guilsinglleft -74
+KPX Adieresis hyphen -23
+KPX Adieresis o -40
+KPX Adieresis period -10
+KPX Adieresis q -21
+KPX Adieresis quotedblright -91
+KPX Adieresis quoteright -116
+KPX Adieresis t -20
+KPX Adieresis u -28
+KPX Adieresis v -82
+KPX Adieresis w -73
+KPX Adieresis y -83
+KPX Agrave C -53
+KPX Agrave G -57
+KPX Agrave O -58
+KPX Agrave Q -60
+KPX Agrave T -54
+KPX Agrave U -62
+KPX Agrave V -132
+KPX Agrave W -113
+KPX Agrave Y -81
+KPX Agrave comma -3
+KPX Agrave period -10
+KPX Aring C -53
+KPX Aring G -57
+KPX Aring O -58
+KPX Aring Q -60
+KPX Aring T -54
+KPX Aring U -62
+KPX Aring V -132
+KPX Aring W -113
+KPX Aring Y -81
+KPX Aring a -6
+KPX Aring b -19
+KPX Aring c -29
+KPX Aring comma -3
+KPX Aring d -28
+KPX Aring e -27
+KPX Aring g -19
+KPX Aring guillemotleft -64
+KPX Aring guilsinglleft -74
+KPX Aring hyphen -23
+KPX Aring o -40
+KPX Aring period -10
+KPX Aring q -21
+KPX Aring quotedblright -91
+KPX Aring quoteright -116
+KPX Aring t -20
+KPX Aring u -28
+KPX Aring v -82
+KPX Aring w -73
+KPX Aring y -83
+KPX Atilde C -53
+KPX Atilde G -57
+KPX Atilde O -58
+KPX Atilde Q -60
+KPX Atilde T -54
+KPX Atilde U -62
+KPX Atilde V -132
+KPX Atilde W -113
+KPX Atilde Y -81
+KPX Atilde comma -3
+KPX Atilde period -10
+KPX B A -51
+KPX B AE -43
+KPX B Aacute -51
+KPX B Acircumflex -51
+KPX B Adieresis -51
+KPX B Aring -51
+KPX B Atilde -51
+KPX B O -24
+KPX B OE -19
+KPX B Oacute -24
+KPX B Ocircumflex -24
+KPX B Odieresis -24
+KPX B Ograve -24
+KPX B Oslash -23
+KPX B V -65
+KPX B W -59
+KPX B Y -68
+KPX C A -23
+KPX C AE -15
+KPX C Aacute -23
+KPX C Adieresis -23
+KPX C Aring -23
+KPX C H -2
+KPX C K -10
+KPX C O -12
+KPX C Oacute -12
+KPX C Odieresis -12
+KPX Ccedilla A -27
+KPX D A -67
+KPX D Aacute -67
+KPX D Acircumflex -67
+KPX D Adieresis -67
+KPX D Agrave -67
+KPX D Aring -67
+KPX D Atilde -67
+KPX D J -41
+KPX D T -9
+KPX D V -70
+KPX D W -57
+KPX D X -64
+KPX D Y -73
+KPX F A -71
+KPX F Aacute -71
+KPX F Acircumflex -71
+KPX F Adieresis -71
+KPX F Agrave -71
+KPX F Aring -71
+KPX F Atilde -71
+KPX F J -13
+KPX F O -10
+KPX F Odieresis -10
+KPX F a -34
+KPX F aacute -34
+KPX F adieresis -10
+KPX F ae -36
+KPX F aring -34
+KPX F comma -51
+KPX F e -19
+KPX F eacute -19
+KPX F hyphen 3
+KPX F i -13
+KPX F j -20
+KPX F o -21
+KPX F oacute -21
+KPX F odieresis -21
+KPX F oe -21
+KPX F oslash -21
+KPX F period -58
+KPX F r -10
+KPX F u -11
+KPX G A -26
+KPX G AE -19
+KPX G Aacute -26
+KPX G Acircumflex -26
+KPX G Adieresis -26
+KPX G Agrave -26
+KPX G Aring -26
+KPX G Atilde -26
+KPX G T -21
+KPX G V -23
+KPX G W -18
+KPX G Y -26
+KPX J A -53
+KPX J AE -46
+KPX J Adieresis -53
+KPX J Aring -53
+KPX K C -44
+KPX K G -49
+KPX K O -50
+KPX K OE -44
+KPX K Oacute -50
+KPX K Odieresis -50
+KPX K S 1
+KPX K T 0
+KPX K a 2
+KPX K adieresis 2
+KPX K ae 0
+KPX K aring 2
+KPX K e -19
+KPX K hyphen -63
+KPX K o -31
+KPX K oacute -31
+KPX K odieresis -31
+KPX K u -19
+KPX K udieresis -19
+KPX K y -87
+KPX L A 0
+KPX L AE 6
+KPX L Aacute 0
+KPX L Adieresis 0
+KPX L Aring 0
+KPX L C 1
+KPX L Ccedilla 0
+KPX L G 0
+KPX L O -3
+KPX L Oacute -3
+KPX L Ocircumflex -3
+KPX L Odieresis -3
+KPX L Ograve -3
+KPX L Otilde -3
+KPX L S 5
+KPX L T -73
+KPX L U -26
+KPX L Udieresis -26
+KPX L V -115
+KPX L W -89
+KPX L Y -100
+KPX L hyphen 25
+KPX L quotedblright -100
+KPX L quoteright -125
+KPX L u -10
+KPX L udieresis -10
+KPX L y -57
+KPX N A -28
+KPX N AE -21
+KPX N Aacute -28
+KPX N Adieresis -28
+KPX N Aring -28
+KPX N C -17
+KPX N Ccedilla -17
+KPX N G -20
+KPX N O -20
+KPX N Oacute -20
+KPX N Odieresis -20
+KPX N a -27
+KPX N aacute -27
+KPX N adieresis -27
+KPX N ae -27
+KPX N aring -27
+KPX N comma -14
+KPX N e -17
+KPX N eacute -17
+KPX N o -21
+KPX N oacute -21
+KPX N odieresis -21
+KPX N oslash -20
+KPX N period -21
+KPX N u -25
+KPX N udieresis -25
+KPX O A -58
+KPX O AE -51
+KPX O Aacute -58
+KPX O Adieresis -58
+KPX O Aring -58
+KPX O T -9
+KPX O V -69
+KPX O W -55
+KPX O X -56
+KPX O Y -72
+KPX Oacute A -58
+KPX Oacute T -9
+KPX Oacute V -69
+KPX Oacute W -55
+KPX Oacute Y -72
+KPX Ocircumflex T -9
+KPX Ocircumflex V -69
+KPX Ocircumflex Y -72
+KPX Odieresis A -58
+KPX Odieresis T -9
+KPX Odieresis V -69
+KPX Odieresis W -55
+KPX Odieresis X -56
+KPX Odieresis Y -72
+KPX Ograve T -9
+KPX Ograve V -69
+KPX Ograve Y -72
+KPX Oslash A -58
+KPX Otilde T -9
+KPX Otilde V -69
+KPX Otilde Y -72
+KPX P A -90
+KPX P AE -91
+KPX P Aacute -90
+KPX P Adieresis -90
+KPX P Aring -90
+KPX P J -51
+KPX P a -18
+KPX P aacute -18
+KPX P adieresis -18
+KPX P ae -18
+KPX P aring -18
+KPX P comma -94
+KPX P e -23
+KPX P eacute -23
+KPX P hyphen -38
+KPX P o -25
+KPX P oacute -25
+KPX P odieresis -25
+KPX P oe -25
+KPX P oslash -25
+KPX P period -101
+KPX R C -42
+KPX R Ccedilla -42
+KPX R G -44
+KPX R O -45
+KPX R OE -40
+KPX R Oacute -45
+KPX R Odieresis -45
+KPX R T -34
+KPX R U -56
+KPX R Udieresis -56
+KPX R V -73
+KPX R W -68
+KPX R Y -76
+KPX R a -2
+KPX R aacute -2
+KPX R adieresis -2
+KPX R ae -5
+KPX R aring -2
+KPX R e -23
+KPX R eacute -23
+KPX R hyphen -52
+KPX R o -36
+KPX R oacute -36
+KPX R odieresis -36
+KPX R oe -31
+KPX R u -24
+KPX R uacute -24
+KPX R udieresis -24
+KPX R y -36
+KPX S A -37
+KPX S AE -30
+KPX S Aacute -37
+KPX S Adieresis -37
+KPX S Aring -37
+KPX S T -19
+KPX S V -27
+KPX S W -21
+KPX S Y -30
+KPX S t -20
+KPX T A -53
+KPX T AE -45
+KPX T Aacute -53
+KPX T Acircumflex -53
+KPX T Adieresis -53
+KPX T Agrave -53
+KPX T Aring -53
+KPX T Atilde -53
+KPX T C -8
+KPX T G -10
+KPX T J -18
+KPX T O -10
+KPX T OE -3
+KPX T Oacute -10
+KPX T Ocircumflex -10
+KPX T Odieresis -10
+KPX T Ograve -10
+KPX T Oslash -10
+KPX T Otilde -10
+KPX T S -10
+KPX T V 14
+KPX T W 20
+KPX T Y 11
+KPX T a -77
+KPX T ae -80
+KPX T c -87
+KPX T colon -88
+KPX T comma -74
+KPX T e -86
+KPX T g -91
+KPX T guillemotleft -115
+KPX T guilsinglleft -125
+KPX T hyphen -73
+KPX T i -18
+KPX T j -25
+KPX T o -90
+KPX T oslash -89
+KPX T period -82
+KPX T r -50
+KPX T s -73
+KPX T semicolon -87
+KPX T u -93
+KPX T v -105
+KPX T w -106
+KPX T y -102
+KPX U A -65
+KPX U AE -58
+KPX U Aacute -65
+KPX U Acircumflex -65
+KPX U Adieresis -65
+KPX U Aring -65
+KPX U Atilde -65
+KPX U comma -32
+KPX U m -33
+KPX U n -31
+KPX U p -28
+KPX U period -37
+KPX U r -27
+KPX Uacute A -65
+KPX Uacute comma -32
+KPX Uacute m -33
+KPX Uacute n -31
+KPX Uacute p -28
+KPX Uacute period -37
+KPX Uacute r -27
+KPX Ucircumflex A -65
+KPX Udieresis A -65
+KPX Udieresis b 21
+KPX Udieresis comma -32
+KPX Udieresis m -33
+KPX Udieresis n -31
+KPX Udieresis p -28
+KPX Udieresis period -37
+KPX Udieresis r -27
+KPX Ugrave A -65
+KPX V A -124
+KPX V AE -104
+KPX V Aacute -124
+KPX V Acircumflex -124
+KPX V Adieresis -124
+KPX V Agrave -124
+KPX V Aring -124
+KPX V Atilde -124
+KPX V C -64
+KPX V G -67
+KPX V O -67
+KPX V Oacute -67
+KPX V Ocircumflex -67
+KPX V Odieresis -67
+KPX V Ograve -67
+KPX V Oslash -66
+KPX V Otilde -67
+KPX V S -47
+KPX V T 10
+KPX V a -89
+KPX V ae -89
+KPX V colon -89
+KPX V comma -105
+KPX V e -85
+KPX V g -101
+KPX V guillemotleft -109
+KPX V guilsinglleft -119
+KPX V hyphen -69
+KPX V i -20
+KPX V o -89
+KPX V oslash -88
+KPX V period -112
+KPX V r -56
+KPX V semicolon -89
+KPX V u -51
+KPX V y -54
+KPX W A -113
+KPX W AE -98
+KPX W Aacute -113
+KPX W Acircumflex -113
+KPX W Adieresis -113
+KPX W Agrave -113
+KPX W Aring -113
+KPX W Atilde -113
+KPX W C -53
+KPX W G -56
+KPX W O -56
+KPX W Oacute -56
+KPX W Ocircumflex -56
+KPX W Odieresis -56
+KPX W Ograve -56
+KPX W Oslash -55
+KPX W Otilde -56
+KPX W S -41
+KPX W T 17
+KPX W a -80
+KPX W ae -81
+KPX W colon -81
+KPX W comma -89
+KPX W e -72
+KPX W g -91
+KPX W guillemotleft -97
+KPX W guilsinglleft -107
+KPX W hyphen -57
+KPX W i -13
+KPX W o -76
+KPX W oslash -75
+KPX W period -96
+KPX W r -47
+KPX W semicolon -81
+KPX W u -43
+KPX W y -45
+KPX X C -54
+KPX X O -59
+KPX X Odieresis -59
+KPX X Q -61
+KPX X a -7
+KPX X e -28
+KPX X hyphen -55
+KPX X o -41
+KPX X u -29
+KPX X y -96
+KPX Y A -74
+KPX Y AE -67
+KPX Y Aacute -74
+KPX Y Acircumflex -74
+KPX Y Adieresis -74
+KPX Y Agrave -74
+KPX Y Aring -74
+KPX Y Atilde -74
+KPX Y C -68
+KPX Y G -71
+KPX Y O -69
+KPX Y Oacute -69
+KPX Y Ocircumflex -69
+KPX Y Odieresis -69
+KPX Y Ograve -69
+KPX Y Oslash -69
+KPX Y Otilde -69
+KPX Y S -44
+KPX Y T 13
+KPX Y a -99
+KPX Y ae -102
+KPX Y colon -109
+KPX Y comma -96
+KPX Y e -103
+KPX Y g -112
+KPX Y guillemotleft -135
+KPX Y guilsinglleft -145
+KPX Y hyphen -98
+KPX Y i -17
+KPX Y o -107
+KPX Y oslash -106
+KPX Y p -88
+KPX Y period -103
+KPX Y semicolon -108
+KPX Y u -78
+KPX Y v -86
+KPX Z v -48
+KPX Z y -50
+KPX a j -26
+KPX a quoteright -40
+KPX a v -30
+KPX a w -31
+KPX a y -32
+KPX aacute v -30
+KPX aacute w -31
+KPX aacute y -32
+KPX adieresis v -30
+KPX adieresis w -31
+KPX adieresis y -32
+KPX ae v -27
+KPX ae w -28
+KPX ae y -30
+KPX agrave v -30
+KPX agrave w -31
+KPX agrave y -32
+KPX aring v -30
+KPX aring w -31
+KPX aring y -32
+KPX b v -27
+KPX b w -28
+KPX b y -32
+KPX c h -15
+KPX c k -20
+KPX comma one -52
+KPX comma quotedblright -29
+KPX comma quoteright -53
+KPX e quoteright -30
+KPX e t -10
+KPX e v -27
+KPX e w -28
+KPX e x -35
+KPX e y -30
+KPX eacute v -27
+KPX eacute w -28
+KPX eacute y -30
+KPX ecircumflex v -27
+KPX ecircumflex w -28
+KPX ecircumflex y -30
+KPX eight four 0
+KPX eight one -63
+KPX eight seven -15
+KPX f a -24
+KPX f aacute -24
+KPX f adieresis 12
+KPX f ae -25
+KPX f aring -7
+KPX f e -34
+KPX f eacute -34
+KPX f f 6
+KPX f i 15
+KPX f j 8
+KPX f l 44
+KPX f o -38
+KPX f oacute -38
+KPX f odieresis -1
+KPX f oe -37
+KPX f oslash -38
+KPX f quoteright 17
+KPX f s -21
+KPX f t 10
+KPX five four -9
+KPX five one -70
+KPX five seven -36
+KPX four four 14
+KPX four one -75
+KPX four seven -42
+KPX g a -18
+KPX g adieresis -18
+KPX g ae -18
+KPX g aring -18
+KPX g e -24
+KPX g eacute -24
+KPX g l -7
+KPX g oacute -26
+KPX g odieresis -26
+KPX g r 11
+KPX guillemotright A -62
+KPX guillemotright AE -61
+KPX guillemotright Aacute -62
+KPX guillemotright Adieresis -62
+KPX guillemotright Aring -62
+KPX guillemotright T -114
+KPX guillemotright V -117
+KPX guillemotright W -95
+KPX guillemotright Y -138
+KPX guilsinglright A -72
+KPX guilsinglright AE -71
+KPX guilsinglright Aacute -72
+KPX guilsinglright Adieresis -72
+KPX guilsinglright Aring -72
+KPX guilsinglright T -124
+KPX guilsinglright V -128
+KPX guilsinglright W -105
+KPX guilsinglright Y -149
+KPX h quoteright -38
+KPX h y -30
+KPX hyphen A -27
+KPX hyphen AE -25
+KPX hyphen Aacute -27
+KPX hyphen Adieresis -27
+KPX hyphen Aring -27
+KPX hyphen T -77
+KPX hyphen V -82
+KPX hyphen W -59
+KPX hyphen Y -108
+KPX i T -28
+KPX i j -36
+KPX k a 1
+KPX k aacute 1
+KPX k adieresis 1
+KPX k ae -1
+KPX k aring 1
+KPX k comma 4
+KPX k e -19
+KPX k eacute -19
+KPX k g -11
+KPX k hyphen -64
+KPX k o -32
+KPX k oacute -32
+KPX k odieresis -32
+KPX k period -2
+KPX k s 5
+KPX k u 14
+KPX k udieresis 14
+KPX l v -28
+KPX l y -25
+KPX m p -9
+KPX m v -30
+KPX m w -31
+KPX m y -31
+KPX n T -55
+KPX n p -13
+KPX n quoteright -40
+KPX n v -30
+KPX n w -31
+KPX n y -31
+KPX nine four -7
+KPX nine one -63
+KPX nine seven -6
+KPX o T -91
+KPX o quoteright -34
+KPX o t -9
+KPX o v -36
+KPX o w -36
+KPX o x -36
+KPX o y -39
+KPX oacute v -36
+KPX oacute w -36
+KPX oacute y -39
+KPX ocircumflex t -9
+KPX odieresis t -9
+KPX odieresis v -36
+KPX odieresis w -36
+KPX odieresis x -36
+KPX odieresis y -39
+KPX ograve v -36
+KPX ograve w -36
+KPX ograve y -39
+KPX one comma -48
+KPX one eight -68
+KPX one five -37
+KPX one four -72
+KPX one nine -61
+KPX one one -78
+KPX one period -55
+KPX one seven -78
+KPX one six -66
+KPX one three -41
+KPX one two -34
+KPX one zero -54
+KPX p t -6
+KPX p y -28
+KPX period one -61
+KPX period quotedblright -34
+KPX period quoteright -58
+KPX q c -8
+KPX q u -12
+KPX quotedblbase A 12
+KPX quotedblbase AE 19
+KPX quotedblbase T -60
+KPX quotedblbase V -105
+KPX quotedblbase W -76
+KPX quotedblbase Y -87
+KPX quotedblleft A -86
+KPX quotedblleft AE -91
+KPX quotedblleft Aacute -86
+KPX quotedblleft Adieresis -86
+KPX quotedblleft Aring -86
+KPX quotedblleft T 14
+KPX quotedblleft V 1
+KPX quotedblleft W 7
+KPX quotedblleft Y -1
+KPX quotedblright A -94
+KPX quotedblright AE -99
+KPX quotedblright Aacute -94
+KPX quotedblright Adieresis -94
+KPX quotedblright Aring -94
+KPX quotedblright T 11
+KPX quotedblright V 0
+KPX quotedblright W 6
+KPX quotedblright Y -2
+KPX quoteleft A -111
+KPX quoteleft AE -115
+KPX quoteleft Aacute -111
+KPX quoteleft Adieresis -111
+KPX quoteleft Aring -111
+KPX quoteleft T -9
+KPX quoteleft V -23
+KPX quoteleft W -17
+KPX quoteleft Y -26
+KPX quoteright A -130
+KPX quoteright AE -135
+KPX quoteright Aacute -130
+KPX quoteright Adieresis -130
+KPX quoteright Aring -130
+KPX quoteright comma -71
+KPX quoteright d -57
+KPX quoteright o -54
+KPX quoteright period -78
+KPX quoteright r -44
+KPX quoteright s -47
+KPX quoteright t -44
+KPX quoteright v -47
+KPX quoteright w -47
+KPX quoteright y -45
+KPX r a -2
+KPX r aacute -2
+KPX r acircumflex -2
+KPX r adieresis -2
+KPX r ae -3
+KPX r agrave -2
+KPX r aring -2
+KPX r c -9
+KPX r ccedilla -8
+KPX r colon -7
+KPX r comma -41
+KPX r d -10
+KPX r e -5
+KPX r eacute -5
+KPX r ecircumflex -5
+KPX r egrave -5
+KPX r f 19
+KPX r g -15
+KPX r h -6
+KPX r hyphen -46
+KPX r i 20
+KPX r j 14
+KPX r k -10
+KPX r l -18
+KPX r m 20
+KPX r n 22
+KPX r o -8
+KPX r oacute -8
+KPX r ocircumflex -8
+KPX r odieresis -8
+KPX r oe -7
+KPX r ograve -8
+KPX r oslash -7
+KPX r p 25
+KPX r period -48
+KPX r q -10
+KPX r quoteright -19
+KPX r r 26
+KPX r s 0
+KPX r semicolon -7
+KPX r t 23
+KPX r u 19
+KPX r v 20
+KPX r w 19
+KPX r x 17
+KPX r y 22
+KPX r z 2
+KPX s quoteright -38
+KPX s t -15
+KPX seven colon -68
+KPX seven comma -72
+KPX seven eight -40
+KPX seven five -59
+KPX seven four -63
+KPX seven one -56
+KPX seven period -79
+KPX seven seven -20
+KPX seven six -46
+KPX seven three -35
+KPX seven two -31
+KPX six four 12
+KPX six one -74
+KPX six seven -29
+KPX t S 2
+KPX t a 10
+KPX t aacute 10
+KPX t adieresis 10
+KPX t ae 9
+KPX t aring 10
+KPX t colon -8
+KPX t e 0
+KPX t eacute 0
+KPX t h 10
+KPX t o -8
+KPX t oacute -8
+KPX t odieresis -8
+KPX t quoteright -29
+KPX t semicolon -8
+KPX three four -6
+KPX three one -76
+KPX three seven -29
+KPX two four 0
+KPX two one -60
+KPX two seven -16
+KPX u quoteright -36
+KPX v a -24
+KPX v aacute -24
+KPX v acircumflex -24
+KPX v adieresis -24
+KPX v ae -24
+KPX v agrave -24
+KPX v aring -24
+KPX v atilde -24
+KPX v c -37
+KPX v colon -20
+KPX v comma -69
+KPX v e -35
+KPX v eacute -35
+KPX v ecircumflex -35
+KPX v egrave -35
+KPX v g -41
+KPX v hyphen -28
+KPX v l -31
+KPX v o -37
+KPX v oacute -37
+KPX v odieresis -37
+KPX v ograve -37
+KPX v oslash -38
+KPX v period -76
+KPX v s -20
+KPX v semicolon -20
+KPX w a -26
+KPX w aacute -26
+KPX w acircumflex -26
+KPX w adieresis -26
+KPX w ae -27
+KPX w agrave -26
+KPX w aring -26
+KPX w atilde -26
+KPX w c -33
+KPX w colon -23
+KPX w comma -64
+KPX w e -31
+KPX w eacute -31
+KPX w ecircumflex -31
+KPX w egrave -31
+KPX w g -43
+KPX w hyphen -24
+KPX w l -33
+KPX w o -36
+KPX w oacute -36
+KPX w odieresis -36
+KPX w ograve -36
+KPX w oslash -34
+KPX w period -71
+KPX w s -23
+KPX w semicolon -23
+KPX x a -11
+KPX x c -34
+KPX x e -32
+KPX x eacute -32
+KPX x o -45
+KPX x q -26
+KPX y a -30
+KPX y aacute -30
+KPX y acircumflex -30
+KPX y adieresis -30
+KPX y ae -31
+KPX y agrave -30
+KPX y aring -30
+KPX y atilde -30
+KPX y c -37
+KPX y colon -23
+KPX y comma -66
+KPX y e -35
+KPX y eacute -35
+KPX y ecircumflex -35
+KPX y egrave -35
+KPX y g -48
+KPX y hyphen -27
+KPX y l -32
+KPX y o -39
+KPX y oacute -39
+KPX y odieresis -39
+KPX y ograve -39
+KPX y oslash -38
+KPX y period -73
+KPX y s -26
+KPX y semicolon -23
+KPX zero four 12
+KPX zero one -55
+KPX zero seven -5
+EndKernPairs
+EndKernData
+EndFontMetrics
diff --git a/samples/Makefile b/samples/Makefile
new file mode 100644
index 0000000000..58aefc246f
--- /dev/null
+++ b/samples/Makefile
@@ -0,0 +1 @@
+include ../src/gtk/setup/general/makedirs
diff --git a/samples/grid/Makefile b/samples/grid/Makefile
new file mode 100644
index 0000000000..027d82ae19
--- /dev/null
+++ b/samples/grid/Makefile
@@ -0,0 +1 @@
+include ../../src/gtk/setup/general/makeapp
diff --git a/samples/grid/Makefile.in b/samples/grid/Makefile.in
new file mode 100644
index 0000000000..fd1b9963fa
--- /dev/null
+++ b/samples/grid/Makefile.in
@@ -0,0 +1,26 @@
+# WXXT base directory
+WXBASEDIR=@WXBASEDIR@
+
+# set the OS type for compilation
+OS=@OS@
+# compile a library only
+RULE=bin
+
+# define library name
+BIN_TARGET=test
+# define library sources
+BIN_SRC=\
+test.cpp
+
+#define library objects
+BIN_OBJ=\
+test.o
+
+# additional things needed to link
+BIN_LINK=
+
+# additional things needed to compile
+ADD_COMPILE=
+
+# include the definitions now
+include ../../../template.mak
diff --git a/samples/grid/aiai.ico b/samples/grid/aiai.ico
new file mode 100644
index 0000000000000000000000000000000000000000..a3db6563cc0b9f4588e1e994fe54b90a3cb1d6c1
GIT binary patch
literal 766
zcmc(bJ930T3`Bcft}@v=+L+MC@X_W5#I6lE$3$=(hlEfB<Ja@?LOIyb0!^!t)JP*;
zc>4Zbw(l3|27cf@{)u1o%88L{R;n8d60briz)7fio<S#4ewC6VoX4NcpV>a{V~VK)
z)$t4e1%j>c0*T7ZEBuvb0Ndch+2BCx7U^mZHa?iIh11ZPGV>8*oPzc{HmcjEM7U^(
z*rd)gSRm_`KJo;dxt={X3#3|q&kYE;ul$En1WJC3UOX%3ev8=<z}j41;VP{UzUs~U
s)wx~DuB_~?Y=Qe|v5`BV=<&%~$Nt1hCmx0~Ul2L;AGObMz1)9;A6NK_vj6}9

literal 0
HcmV?d00001

diff --git a/samples/grid/aiai.xbm b/samples/grid/aiai.xbm
new file mode 100644
index 0000000000..1a6f0a31b1
--- /dev/null
+++ b/samples/grid/aiai.xbm
@@ -0,0 +1,38 @@
+#define aiai_width 64
+#define aiai_height 64
+static char aiai_bits[] = {
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x44,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x44,0x44,0x44,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x44,0x44,0x44,0x42,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x47,0x44,0x44,0x44,0x44,0x11,0x11,0x11,0x17,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x91,0x1f,0x11,0x11,0x11,0x11,0x44,0x44,0xc4,0x4f,0x44,0x44,0x44,0x44,
+ 0x44,0x44,0xc4,0x5f,0x44,0xf4,0x45,0x44,0x11,0x11,0xf1,0x1f,0x11,0xf9,0x13,
+ 0x11,0x11,0x11,0xf1,0x3f,0x11,0xfd,0x13,0x11,0x44,0x44,0xf4,0x7f,0x44,0xfc,
+ 0x47,0x44,0x44,0x44,0xf4,0x7f,0x44,0xfc,0x47,0x44,0x11,0x11,0xf9,0x7f,0x11,
+ 0xf9,0x13,0x11,0x11,0x11,0xfd,0xff,0x11,0xf1,0x11,0x11,0x44,0x44,0xfc,0xff,
+ 0x44,0x44,0x44,0x44,0x44,0x44,0xfe,0xff,0x45,0x44,0x44,0x44,0x11,0x11,0xff,
+ 0xff,0x11,0xfd,0x13,0x11,0x11,0x11,0xff,0xff,0x13,0xfd,0x13,0x11,0x44,0xc4,
+ 0xff,0xff,0x07,0xfc,0x43,0x44,0x44,0xff,0xff,0xf9,0xff,0xfd,0xfb,0xff,0x11,
+ 0xc0,0xff,0x00,0x00,0xfc,0x03,0x00,0x11,0xc0,0x7f,0x00,0x00,0xfc,0x03,0x00,
+ 0x04,0xe0,0x7f,0x00,0x00,0xfc,0x03,0x00,0xf4,0xf7,0xbf,0xff,0xff,0xfd,0xfb,
+ 0x7f,0x01,0xf0,0x1f,0x00,0x00,0xfc,0x03,0x00,0x01,0xf8,0x1f,0x00,0x00,0xfc,
+ 0x03,0x00,0x00,0xfc,0x0f,0x00,0x00,0xfc,0x03,0x40,0xfe,0xfd,0xef,0xff,0xff,
+ 0xfd,0xfb,0x4f,0x00,0xfe,0x07,0x00,0x00,0xfc,0x03,0x10,0x00,0xfe,0x03,0x00,
+ 0x00,0xfc,0x03,0x10,0x00,0xff,0x03,0x00,0x00,0xfc,0x03,0x44,0x7f,0xff,0x01,
+ 0x00,0x00,0xfc,0xfb,0x44,0x91,0xff,0xff,0xff,0xff,0xff,0x13,0x11,0xd1,0xff,
+ 0xff,0xff,0xff,0xff,0x13,0x11,0xe4,0xff,0xff,0xff,0xff,0xff,0x47,0x44,0xe4,
+ 0xff,0xff,0xff,0xff,0xff,0x47,0x44,0xf1,0xff,0xff,0xff,0xff,0xff,0x13,0x11,
+ 0xf1,0xff,0xff,0xff,0xff,0xff,0x13,0x11,0xfc,0xff,0xff,0xff,0xff,0xff,0x47,
+ 0x44,0xfc,0xff,0xff,0xff,0xff,0xff,0x47,0x44,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x11,0x44,0x44,0xc4,0x44,0x44,
+ 0xc4,0x44,0x44,0x44,0x4e,0xc4,0x44,0x4e,0xc4,0x44,0x44,0x11,0x1f,0xd1,0x11,
+ 0x1f,0xd1,0x11,0x11,0x91,0x31,0xd1,0x91,0x31,0xd1,0x11,0x11,0xc4,0x64,0xcc,
+ 0xcc,0x64,0xcc,0x44,0x44,0x64,0xc4,0xcc,0x6c,0xc4,0xcc,0x44,0x44,0xf1,0xff,
+ 0xd1,0xf1,0xff,0xd1,0x11,0x11,0xf9,0xff,0xd3,0xf9,0xff,0xd3,0x11,0x11,0x4c,
+ 0x44,0xc6,0x4c,0x44,0xc6,0x44,0x44,0x4c,0x44,0xc6,0x4c,0x44,0xc6,0x44,0x44,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x44};
diff --git a/samples/grid/bitmap1.bmp b/samples/grid/bitmap1.bmp
new file mode 100644
index 0000000000000000000000000000000000000000..a9a567613347e3e32dca66a9a630df9cbfefe561
GIT binary patch
literal 406
zcmZ?royN!j24z4}1BfM{n2~`6EUo~R2XO?T7%aiCp8<pz_V0&KKoZDgIB?(qLqkIY
zP~txrG5r4zVgWG_f`mYPY63w)L3yZoKqidy5zH0@OCYl$!Vn#}*vRUU+5f>BkSv2S
Jq1IE40stId_;>&S

literal 0
HcmV?d00001

diff --git a/samples/grid/bitmap2.bmp b/samples/grid/bitmap2.bmp
new file mode 100644
index 0000000000000000000000000000000000000000..ae825f1bedd3525153ffd6eebffa4e160cbfeec3
GIT binary patch
literal 238
zcmZ9FF%AMD6hy~_Xt4zz!((jBw%);tdMjhH4M(!u5>8~e!S{VgjPb+F{NWF9y}dQ+
zfn2~DL~u}mrDx|sK68vJ5?iGVfoWB1RnD1#^(`~+0Lzcu|5Q`#?wIbbEu|D2c~=X|
g+_iP(URcPzh|SWpl8>i-$D2*t=HC82PksOU03ju0Qvd(}

literal 0
HcmV?d00001

diff --git a/samples/grid/test.cpp b/samples/grid/test.cpp
new file mode 100644
index 0000000000..6cfcf2b9b6
--- /dev/null
+++ b/samples/grid/test.cpp
@@ -0,0 +1,318 @@
+/*
+ * File:	test.cpp
+ * Purpose:	wxGrid test
+ * Author:	Julian Smart
+ * Created:	1995
+ * Updated:	
+ * Copyright:   (c) 1995, AIAI, University of Edinburgh
+ */
+
+static const char sccsid[] = "%W% %G%";
+
+#ifdef __GNUG__
+#pragma implementation
+#pragma interface
+#endif
+
+// For compilers that support precompilation, includes "wx/wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include "wx/grid.h"
+#include "wx/colordlg.h"
+
+// Define a new application type
+class MyApp: public wxApp
+{ public:
+    bool OnInit(void);
+};
+
+// Define a new frame type
+class MyFrame: public wxFrame
+{ public:
+    wxGrid *grid;
+    MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size);
+
+    bool OnClose(void) { return TRUE; }
+
+    void ToggleEditable(wxCommandEvent& event);
+    void ToggleRowLabel(wxCommandEvent& event);
+    void ToggleColLabel(wxCommandEvent& event);
+    void ToggleDividers(wxCommandEvent& event);
+    void LeftCell(wxCommandEvent& event);
+    void CentreCell(wxCommandEvent& event);
+    void RightCell(wxCommandEvent& event);
+    void ColourLabelBackground(wxCommandEvent& event);
+    void ColourLabelText(wxCommandEvent& event);
+    void NormalLabelColouring(wxCommandEvent& event);
+    void ColourCellBackground(wxCommandEvent& event);
+    void ColourCellText(wxCommandEvent& event);
+    void NormalCellColouring(wxCommandEvent& event);
+    void Quit(wxCommandEvent& event);
+
+    void OnActivate(wxActivateEvent& event);
+
+DECLARE_EVENT_TABLE()
+};
+
+wxBitmap *cellBitmap1 = NULL;
+wxBitmap *cellBitmap2 = NULL;
+
+// ID for the menu quit command
+#define GRID_QUIT 1
+#define GRID_TOGGLE_EDITABLE 2
+#define GRID_LEFT_CELL       3
+#define GRID_CENTRE_CELL     4
+#define GRID_RIGHT_CELL      5
+#define GRID_TOGGLE_ROW_LABEL 6
+#define GRID_TOGGLE_COL_LABEL 7
+#define GRID_COLOUR_LABEL_BACKGROUND 8
+#define GRID_COLOUR_LABEL_TEXT       9
+#define GRID_NORMAL_LABEL_COLOURING  10
+#define GRID_COLOUR_CELL_BACKGROUND 11
+#define GRID_COLOUR_CELL_TEXT       12
+#define GRID_NORMAL_CELL_COLOURING  13
+#define GRID_TOGGLE_DIVIDERS        14
+
+// Main proc
+
+IMPLEMENT_APP(MyApp)
+
+// `Main program' equivalent, creating windows and returning main app frame
+bool MyApp::OnInit(void)
+{
+#ifdef __WINDOWS__
+  cellBitmap1 = new wxBitmap("bitmap1");
+  cellBitmap2 = new wxBitmap("bitmap2");
+#endif
+
+  // Create the main frame window
+  MyFrame *frame = new MyFrame(NULL, "wxGrid Sample", wxPoint(50, 50), wxSize(450, 300));
+  
+  // Give it an icon
+#ifdef __WINDOWS__
+  frame->SetIcon(wxIcon("mondrian"));
+#endif
+#ifdef __X__
+  frame->SetIcon(wxIcon("aiai.xbm"));
+#endif
+
+  // Make a menubar
+  wxMenu *file_menu = new wxMenu;
+  file_menu->Append(GRID_QUIT, "E&xit");
+
+  wxMenu *settings_menu = new wxMenu;
+  settings_menu->Append(GRID_TOGGLE_EDITABLE, "&Toggle editable");
+  settings_menu->Append(GRID_TOGGLE_ROW_LABEL, "Toggle ro&w label");
+  settings_menu->Append(GRID_TOGGLE_COL_LABEL, "Toggle co&l label");
+  settings_menu->Append(GRID_TOGGLE_DIVIDERS, "Toggle &dividers");
+  settings_menu->AppendSeparator();
+  settings_menu->Append(GRID_LEFT_CELL, "&Left cell alignment ");
+  settings_menu->Append(GRID_CENTRE_CELL, "&Centre cell alignment ");
+  settings_menu->Append(GRID_RIGHT_CELL, "&Right cell alignment ");
+  settings_menu->AppendSeparator();
+  settings_menu->Append(GRID_COLOUR_LABEL_BACKGROUND, "Choose a label &background colour");
+  settings_menu->Append(GRID_COLOUR_LABEL_TEXT, "Choose a label fore&ground colour");
+  settings_menu->Append(GRID_NORMAL_LABEL_COLOURING, "&Normal label colouring");
+  settings_menu->AppendSeparator();
+  settings_menu->Append(GRID_COLOUR_CELL_BACKGROUND, "Choo&se a cell &background colour");
+  settings_menu->Append(GRID_COLOUR_CELL_TEXT, "Choose &a cell foreground colour");
+  settings_menu->Append(GRID_NORMAL_CELL_COLOURING, "N&ormal cell colouring");
+
+  wxMenuBar *menu_bar = new wxMenuBar;
+  menu_bar->Append(file_menu, "&File");
+  menu_bar->Append(settings_menu, "&Settings");
+  frame->SetMenuBar(menu_bar);
+
+  // Make a grid
+  frame->grid = new wxGrid(frame, 0, 0, 400, 400);
+
+  frame->grid->CreateGrid(10, 8);
+  frame->grid->SetColumnWidth(3, 200);
+  frame->grid->SetRowHeight(4, 45);
+  frame->grid->SetCellValue("First cell", 0, 0);
+  frame->grid->SetCellValue("Another cell", 1, 1);
+  frame->grid->SetCellValue("Yet another cell", 2, 2);
+  frame->grid->SetCellTextFont(wxTheFontList->FindOrCreateFont(10, wxROMAN, wxITALIC, wxNORMAL), 0, 0);
+  frame->grid->SetCellTextColour(*wxRED, 1, 1);
+  frame->grid->SetCellBackgroundColour(*wxCYAN, 2, 2);
+  if (cellBitmap1 && cellBitmap2)
+  {
+    frame->grid->SetCellAlignment(wxCENTRE, 5, 0);
+    frame->grid->SetCellAlignment(wxCENTRE, 6, 0);
+    frame->grid->SetCellBitmap(cellBitmap1, 5, 0);
+    frame->grid->SetCellBitmap(cellBitmap2, 6, 0);
+  }
+  
+  frame->grid->UpdateDimensions();
+  
+  // Show the frame
+  frame->Show(TRUE);
+
+  SetTopWindow(frame);
+  return TRUE;
+}
+
+// My frame constructor
+MyFrame::MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size):
+  wxFrame(frame, -1, title, pos, size)
+{
+  grid = NULL;
+}
+
+BEGIN_EVENT_TABLE(MyFrame, wxFrame)
+  EVT_MENU(GRID_TOGGLE_EDITABLE, MyFrame::ToggleEditable)
+  EVT_MENU(GRID_TOGGLE_ROW_LABEL, MyFrame::ToggleRowLabel)
+  EVT_MENU(GRID_TOGGLE_COL_LABEL, MyFrame::ToggleColLabel)
+  EVT_MENU(GRID_TOGGLE_DIVIDERS, MyFrame::ToggleDividers)
+  EVT_MENU(GRID_LEFT_CELL, MyFrame::LeftCell)
+  EVT_MENU(GRID_CENTRE_CELL, MyFrame::CentreCell)
+  EVT_MENU(GRID_RIGHT_CELL, MyFrame::RightCell)
+  EVT_MENU(GRID_COLOUR_LABEL_BACKGROUND, MyFrame::ColourLabelBackground)
+  EVT_MENU(GRID_COLOUR_LABEL_TEXT, MyFrame::ColourLabelText)
+  EVT_MENU(GRID_NORMAL_LABEL_COLOURING, MyFrame::NormalLabelColouring)
+  EVT_MENU(GRID_COLOUR_CELL_BACKGROUND, MyFrame::ColourCellBackground)
+  EVT_MENU(GRID_COLOUR_CELL_TEXT, MyFrame::ColourCellText)
+  EVT_MENU(GRID_NORMAL_CELL_COLOURING, MyFrame::NormalCellColouring)
+  EVT_MENU(GRID_QUIT, MyFrame::Quit)
+END_EVENT_TABLE()
+
+void MyFrame::ToggleEditable(wxCommandEvent& event)
+{
+      grid->SetEditable(!grid->GetEditable());
+      grid->Refresh();
+}
+
+void MyFrame::ToggleRowLabel(wxCommandEvent& event)
+{
+      if (grid->GetLabelSize(wxVERTICAL) > 0)
+        grid->SetLabelSize(wxVERTICAL, 0);
+      else
+        grid->SetLabelSize(wxVERTICAL, 40);
+      grid->Refresh();
+}
+
+void MyFrame::ToggleColLabel(wxCommandEvent& event)
+{
+      if (grid->GetLabelSize(wxHORIZONTAL) > 0)
+        grid->SetLabelSize(wxHORIZONTAL, 0);
+      else
+        grid->SetLabelSize(wxHORIZONTAL, 20);
+      grid->Refresh();
+}
+
+void MyFrame::ToggleDividers(wxCommandEvent& event)
+{
+      if (!grid->GetDividerPen())
+        grid->SetDividerPen(wxThePenList->FindOrCreatePen("LIGHT GREY", 1, wxSOLID));
+      else
+        grid->SetDividerPen(NULL);
+      grid->Refresh();
+}
+
+void MyFrame::LeftCell(wxCommandEvent& event)
+{
+      grid->SetCellAlignment(wxLEFT);
+      grid->Refresh();
+}
+
+void MyFrame::CentreCell(wxCommandEvent& event)
+{
+      grid->SetCellAlignment(wxCENTRE);
+      grid->Refresh();
+}
+
+void MyFrame::RightCell(wxCommandEvent& event)
+{
+      grid->SetCellAlignment(wxRIGHT);
+      grid->Refresh();
+}
+
+void MyFrame::ColourLabelBackground(wxCommandEvent& event)
+{
+      wxColourData data;
+      data.SetChooseFull(TRUE);
+      wxColourDialog dialog(this, &data);
+      if (dialog.ShowModal() != wxID_CANCEL)
+      {
+        wxColourData retData = dialog.GetColourData();
+        wxColour col = retData.GetColour();
+        grid->SetLabelBackgroundColour(col);
+        grid->Refresh();
+      }
+}
+
+void MyFrame::ColourLabelText(wxCommandEvent& event)
+{
+      wxColourData data;
+      data.SetChooseFull(TRUE);
+      wxColourDialog dialog(this, &data);
+      if (dialog.ShowModal() != wxID_CANCEL)
+      {
+        wxColourData retData = dialog.GetColourData();
+        wxColour col = retData.GetColour();
+        grid->SetLabelTextColour(col);
+        grid->Refresh();
+      }
+}
+
+void MyFrame::NormalLabelColouring(wxCommandEvent& event)
+{
+      grid->SetLabelBackgroundColour(*wxLIGHT_GREY);
+      grid->SetLabelTextColour(*wxBLACK);
+      grid->Refresh();
+}
+
+void MyFrame::ColourCellBackground(wxCommandEvent& event)
+{
+      wxColourData data;
+      data.SetChooseFull(TRUE);
+      wxColourDialog dialog(this, &data);
+      if (dialog.ShowModal() != wxID_CANCEL)
+      {
+        wxColourData retData = dialog.GetColourData();
+        wxColour col = retData.GetColour();
+        grid->SetCellBackgroundColour(col);
+        grid->Refresh();
+      }
+}
+
+void MyFrame::ColourCellText(wxCommandEvent& event)
+{
+      wxColourData data;
+      data.SetChooseFull(TRUE);
+      wxColourDialog dialog(this, &data);
+      if (dialog.ShowModal() != wxID_CANCEL)
+      {
+        wxColourData retData = dialog.GetColourData();
+        wxColour col = retData.GetColour();
+        grid->SetCellTextColour(col);
+        grid->Refresh();
+      }
+}
+
+void MyFrame::NormalCellColouring(wxCommandEvent& event)
+{
+      grid->SetCellBackgroundColour(*wxWHITE);
+      grid->SetCellTextColour(*wxBLACK);
+      grid->Refresh();
+}
+
+void MyFrame::Quit(wxCommandEvent& event)
+{
+      this->Close(TRUE);
+}
+
+// Ensure that the grid's edit control always has the focus.
+void MyFrame::OnActivate(wxActivateEvent& event)
+{
+  if (grid) grid->OnActivate(event.GetActive());
+}
+
diff --git a/samples/grid/test.def b/samples/grid/test.def
new file mode 100644
index 0000000000..3dd3b7a033
--- /dev/null
+++ b/samples/grid/test.def
@@ -0,0 +1,8 @@
+NAME         Test
+DESCRIPTION  'wxTableWindow Test'
+EXETYPE      WINDOWS
+STUB         'WINSTUB.EXE'
+CODE         PRELOAD MOVEABLE DISCARDABLE
+DATA         PRELOAD MOVEABLE MULTIPLE
+HEAPSIZE     1024
+STACKSIZE    16192
diff --git a/samples/grid/test.rc b/samples/grid/test.rc
new file mode 100644
index 0000000000..571ada1f2a
--- /dev/null
+++ b/samples/grid/test.rc
@@ -0,0 +1,5 @@
+#include "wx/msw/wx.rc"
+
+bitmap1 BITMAP "bitmap1.bmp"
+bitmap2 BITMAP "bitmap2.bmp"
+
diff --git a/samples/internat/Makefile b/samples/internat/Makefile
new file mode 100644
index 0000000000..027d82ae19
--- /dev/null
+++ b/samples/internat/Makefile
@@ -0,0 +1 @@
+include ../../src/gtk/setup/general/makeapp
diff --git a/samples/internat/Makefile.in b/samples/internat/Makefile.in
new file mode 100644
index 0000000000..774cdbd778
--- /dev/null
+++ b/samples/internat/Makefile.in
@@ -0,0 +1,26 @@
+# WXXT base directory
+WXBASEDIR=@WXBASEDIR@
+
+# set the OS type for compilation
+OS=@OS@
+# compile a library only
+RULE=bin
+
+# define library name
+BIN_TARGET=test
+# define library sources
+BIN_SRC=\
+internat.cpp
+
+#define library objects
+BIN_OBJ=\
+internat.o
+
+# additional things needed to link
+BIN_LINK=
+
+# additional things needed to compile
+ADD_COMPILE=
+
+# include the definitions now
+include ../../../template.mak
diff --git a/samples/internat/aiai.ico b/samples/internat/aiai.ico
new file mode 100644
index 0000000000000000000000000000000000000000..a3db6563cc0b9f4588e1e994fe54b90a3cb1d6c1
GIT binary patch
literal 766
zcmc(bJ930T3`Bcft}@v=+L+MC@X_W5#I6lE$3$=(hlEfB<Ja@?LOIyb0!^!t)JP*;
zc>4Zbw(l3|27cf@{)u1o%88L{R;n8d60briz)7fio<S#4ewC6VoX4NcpV>a{V~VK)
z)$t4e1%j>c0*T7ZEBuvb0Ndch+2BCx7U^mZHa?iIh11ZPGV>8*oPzc{HmcjEM7U^(
z*rd)gSRm_`KJo;dxt={X3#3|q&kYE;ul$En1WJC3UOX%3ev8=<z}j41;VP{UzUs~U
s)wx~DuB_~?Y=Qe|v5`BV=<&%~$Nt1hCmx0~Ul2L;AGObMz1)9;A6NK_vj6}9

literal 0
HcmV?d00001

diff --git a/samples/internat/aiai.xbm b/samples/internat/aiai.xbm
new file mode 100644
index 0000000000..1a6f0a31b1
--- /dev/null
+++ b/samples/internat/aiai.xbm
@@ -0,0 +1,38 @@
+#define aiai_width 64
+#define aiai_height 64
+static char aiai_bits[] = {
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x44,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x44,0x44,0x44,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x44,0x44,0x44,0x42,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x47,0x44,0x44,0x44,0x44,0x11,0x11,0x11,0x17,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x91,0x1f,0x11,0x11,0x11,0x11,0x44,0x44,0xc4,0x4f,0x44,0x44,0x44,0x44,
+ 0x44,0x44,0xc4,0x5f,0x44,0xf4,0x45,0x44,0x11,0x11,0xf1,0x1f,0x11,0xf9,0x13,
+ 0x11,0x11,0x11,0xf1,0x3f,0x11,0xfd,0x13,0x11,0x44,0x44,0xf4,0x7f,0x44,0xfc,
+ 0x47,0x44,0x44,0x44,0xf4,0x7f,0x44,0xfc,0x47,0x44,0x11,0x11,0xf9,0x7f,0x11,
+ 0xf9,0x13,0x11,0x11,0x11,0xfd,0xff,0x11,0xf1,0x11,0x11,0x44,0x44,0xfc,0xff,
+ 0x44,0x44,0x44,0x44,0x44,0x44,0xfe,0xff,0x45,0x44,0x44,0x44,0x11,0x11,0xff,
+ 0xff,0x11,0xfd,0x13,0x11,0x11,0x11,0xff,0xff,0x13,0xfd,0x13,0x11,0x44,0xc4,
+ 0xff,0xff,0x07,0xfc,0x43,0x44,0x44,0xff,0xff,0xf9,0xff,0xfd,0xfb,0xff,0x11,
+ 0xc0,0xff,0x00,0x00,0xfc,0x03,0x00,0x11,0xc0,0x7f,0x00,0x00,0xfc,0x03,0x00,
+ 0x04,0xe0,0x7f,0x00,0x00,0xfc,0x03,0x00,0xf4,0xf7,0xbf,0xff,0xff,0xfd,0xfb,
+ 0x7f,0x01,0xf0,0x1f,0x00,0x00,0xfc,0x03,0x00,0x01,0xf8,0x1f,0x00,0x00,0xfc,
+ 0x03,0x00,0x00,0xfc,0x0f,0x00,0x00,0xfc,0x03,0x40,0xfe,0xfd,0xef,0xff,0xff,
+ 0xfd,0xfb,0x4f,0x00,0xfe,0x07,0x00,0x00,0xfc,0x03,0x10,0x00,0xfe,0x03,0x00,
+ 0x00,0xfc,0x03,0x10,0x00,0xff,0x03,0x00,0x00,0xfc,0x03,0x44,0x7f,0xff,0x01,
+ 0x00,0x00,0xfc,0xfb,0x44,0x91,0xff,0xff,0xff,0xff,0xff,0x13,0x11,0xd1,0xff,
+ 0xff,0xff,0xff,0xff,0x13,0x11,0xe4,0xff,0xff,0xff,0xff,0xff,0x47,0x44,0xe4,
+ 0xff,0xff,0xff,0xff,0xff,0x47,0x44,0xf1,0xff,0xff,0xff,0xff,0xff,0x13,0x11,
+ 0xf1,0xff,0xff,0xff,0xff,0xff,0x13,0x11,0xfc,0xff,0xff,0xff,0xff,0xff,0x47,
+ 0x44,0xfc,0xff,0xff,0xff,0xff,0xff,0x47,0x44,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x11,0x44,0x44,0xc4,0x44,0x44,
+ 0xc4,0x44,0x44,0x44,0x4e,0xc4,0x44,0x4e,0xc4,0x44,0x44,0x11,0x1f,0xd1,0x11,
+ 0x1f,0xd1,0x11,0x11,0x91,0x31,0xd1,0x91,0x31,0xd1,0x11,0x11,0xc4,0x64,0xcc,
+ 0xcc,0x64,0xcc,0x44,0x44,0x64,0xc4,0xcc,0x6c,0xc4,0xcc,0x44,0x44,0xf1,0xff,
+ 0xd1,0xf1,0xff,0xd1,0x11,0x11,0xf9,0xff,0xd3,0xf9,0xff,0xd3,0x11,0x11,0x4c,
+ 0x44,0xc6,0x4c,0x44,0xc6,0x44,0x44,0x4c,0x44,0xc6,0x4c,0x44,0xc6,0x44,0x44,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x44};
diff --git a/samples/internat/internat.cpp b/samples/internat/internat.cpp
new file mode 100644
index 0000000000..e8e4fd5812
--- /dev/null
+++ b/samples/internat/internat.cpp
@@ -0,0 +1,151 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        internat.cpp
+// Purpose:     Demonstrates internationalisation support
+// Author:      Vadim Zeitlin/Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation
+#pragma interface
+#endif
+
+// For compilers that support precompilation, includes "wx/wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include "wx/intl.h"
+#include "wx/log.h"
+
+// Define a new application type
+class MyApp: public wxApp
+{
+public:
+    MyApp();
+    bool OnInit(void);
+protected:
+	wxLocale		m_locale;			  // locale we'll be using
+};
+
+// Define a new frame type
+class MyFrame: public wxFrame
+{ public:
+    MyFrame(wxFrame *frame, char *title, int x, int y, int w, int h);
+    
+ public:
+    void OnQuit(wxCommandEvent& event);
+    void OnAbout(wxCommandEvent& event);
+	bool OnClose(void) { return TRUE; }
+
+   DECLARE_EVENT_TABLE()
+    
+};
+
+// ID for the menu commands
+#define MINIMAL_QUIT 	1
+#define MINIMAL_TEXT 	101
+#define MINIMAL_ABOUT 	102
+
+BEGIN_EVENT_TABLE(MyFrame, wxFrame)
+	EVT_MENU(MINIMAL_QUIT, MyFrame::OnQuit)
+	EVT_MENU(MINIMAL_ABOUT, MyFrame::OnAbout)
+END_EVENT_TABLE()
+
+IMPLEMENT_APP(MyApp)
+
+
+MyApp::MyApp():
+  m_locale("french", "fr", "C")
+{
+  // catalogs we'll be using:
+  /* not needed any more, done in wxLocale ctor
+  m_locale.AddCatalog("wxstd");      // 1) for library messages
+  */
+  m_locale.AddCatalog("internat");      // 2) our private one
+  /* this catalog is installed in standard location on Liux systems,
+     it might not be installed on yours - just ignore the errrors
+     or comment out this line then */
+  m_locale.AddCatalog("fileutils");  // 3) and another just for testing
+  
+}
+
+// `Main program' equivalent, creating windows and returning main app frame
+bool MyApp::OnInit(void)
+{
+  // Create the main frame window
+  MyFrame *frame = new MyFrame(NULL, "Minimal wxWindows App", 50, 50, 450, 340);
+
+  // Give it an icon
+#ifdef __WINDOWS__
+  frame->SetIcon(wxIcon("mondrian"));
+#endif
+#ifdef __X__
+  frame->SetIcon(wxIcon("aiai.xbm"));
+#endif
+
+  // Make a menubar
+  wxMenu *file_menu = new wxMenu;
+
+  file_menu->Append(MINIMAL_ABOUT, "&About");
+  file_menu->Append(MINIMAL_QUIT, "E&xit");
+  wxMenuBar *menu_bar = new wxMenuBar;
+  menu_bar->Append(file_menu, "&File");
+  frame->SetMenuBar(menu_bar);
+
+  // Make a panel with a message
+  wxPanel *panel = new wxPanel(frame, -1, wxPoint(0, 0), wxSize(400, 200), wxTAB_TRAVERSAL);
+
+  wxString msgString;
+  int num = 2;
+  if ( num == 0 )
+    msgString = wxTString("you've probably entered an invalid number.");
+  else if ( num == 9 ) // this message is not translated
+    msgString = wxTString("You've found a bug in this program!");
+  else if ( num != 17 )
+    msgString = wxTString("bad luck! try again...");
+  else {
+    msgString = wxTString("congratulations! you've won. Here is the magic phrase:");
+  }
+
+  wxStaticText *msg = new wxStaticText(panel, 311, msgString, wxPoint(10, 10), wxSize(-1, -1),
+    0);
+
+  // Show the frame
+  frame->Show(TRUE);
+  
+
+  SetTopWindow(frame);
+
+  return TRUE;
+}
+
+// My frame constructor
+MyFrame::MyFrame(wxFrame *frame, char *title, int x, int y, int w, int h):
+  wxFrame(frame, -1, title, wxPoint(x, y), wxSize(w, h))
+{}
+
+void MyFrame::OnQuit(wxCommandEvent& event)
+{
+  Close(TRUE);
+}
+
+void MyFrame::OnAbout(wxCommandEvent& event)
+{
+  wxMessageDialog dialog(this, "This is a minimal sample\nA second line in the message box",
+  	"About Minimal", wxYES_NO|wxCANCEL);
+
+  dialog.ShowModal();
+}
+
+
diff --git a/samples/internat/internat.def b/samples/internat/internat.def
new file mode 100644
index 0000000000..060bfe3fce
--- /dev/null
+++ b/samples/internat/internat.def
@@ -0,0 +1,8 @@
+NAME         Minimal
+DESCRIPTION  'Minimal wxWindows application'
+EXETYPE      WINDOWS
+STUB         'WINSTUB.EXE'
+CODE         PRELOAD MOVEABLE DISCARDABLE
+DATA         PRELOAD MOVEABLE MULTIPLE
+HEAPSIZE     4048
+STACKSIZE    16000
diff --git a/samples/internat/internat.po b/samples/internat/internat.po
new file mode 100644
index 0000000000..cc285481e7
--- /dev/null
+++ b/samples/internat/internat.po
@@ -0,0 +1,74 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Free Software Foundation, Inc.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#: hello.cpp:44
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 1997-12-19 17:46+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: ENCODING\n"
+
+#: hello.cpp:31 hello.cpp:38
+msgid "bad luck! try again..."
+msgstr "pas de chance! essayez encore..."
+
+#: hello.cpp:23 hello.cpp:24
+#, c-format
+msgid "usage: %s <number>"
+msgstr "syntaxe: %s <nombre>"
+
+#: hello.cpp:29 hello.cpp:34
+msgid "you've probably entered an invalid number."
+msgstr "vous avez du entrer un nombre invalide."
+
+#: hello.cpp:33 hello.cpp:40
+msgid "congratulations! you've won. Here is the magic phrase:"
+msgstr "felicitations! vous avez gagne. Voici la phrase magique:"
+
+#: hello.cpp:17
+msgid "wxstd"
+msgstr ""
+
+#: hello.cpp:18
+msgid "hello"
+msgstr ""
+
+#: hello.cpp:19
+msgid "fileutils"
+msgstr ""
+
+#: hello.cpp:20
+msgid "french"
+msgstr ""
+
+#: hello.cpp:20
+msgid "fr"
+msgstr ""
+
+#: hello.cpp:20
+msgid "C"
+msgstr ""
+
+#: hello.cpp:27
+msgid "nosuchfi.le"
+msgstr ""
+
+#: hello.cpp:36
+msgid "You've found a bug in this program!"
+msgstr ""
+
+#: hello.cpp:43
+#, c-format
+msgid "cannot create fifo `%s'"
+msgstr ""
+
+#: hello.cpp:43
+msgid "foo"
+msgstr ""
diff --git a/samples/internat/internat.rc b/samples/internat/internat.rc
new file mode 100644
index 0000000000..7655c62a4c
--- /dev/null
+++ b/samples/internat/internat.rc
@@ -0,0 +1,3 @@
+mondrian ICON "mondrian.ico"
+#include "wx/msw/wx.rc"
+
diff --git a/samples/internat/makefile.b32 b/samples/internat/makefile.b32
new file mode 100644
index 0000000000..3396034cc7
--- /dev/null
+++ b/samples/internat/makefile.b32
@@ -0,0 +1,64 @@
+#
+# File:		makefile.bcc
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds internat example (DOS).
+
+# WXWIN and BCCDIR are set by parent make
+
+WXDIR = $(WXWIN)
+!include $(WXDIR)\src\makeb32.env
+
+WXLIBDIR = $(WXDIR)\lib
+WXINC = $(WXDIR)\include\msw
+WXLIB = $(WXLIBDIR)\wx32.lib
+LIBS=$(WXLIB) cw32 import32
+
+TARGET=internat
+
+!if "$(FINAL)" == "0"
+LINKFLAGS=/v /Tpe /L$(WXLIBDIR);$(BCCDIR)\lib
+OPT = -Od
+DEBUG_FLAGS= -v
+!else
+LINKFLAGS=/Tpe /L$(WXLIBDIR);$(BCCDIR)\lib
+OPT = -Od
+DEBUG_FLAGS =
+!endif
+CPPFLAGS=$(DEBUG_FLAGS) $(OPT) @$(CFG)
+
+OBJECTS = internat.obj
+
+$(TARGET).exe:	$(OBJECTS) $(TARGET).def $(TARGET).res
+  tlink32 $(LINKFLAGS) @&&!
+c0w32.obj $(OBJECTS)
+$(TARGET)
+nul
+$(LIBS)
+$(TARGET).def
+!
+        brc32 -K $(TARGET).res
+
+.$(SRCSUFF).obj:
+	bcc32 $(CPPFLAGS) -c {$< }
+
+.c.obj:
+	bcc32 $(CPPFLAGS) -P- -c {$< }
+
+internat.obj:      internat.$(SRCSUFF)
+
+$(TARGET).res :      $(TARGET).rc $(WXDIR)\include\wx\msw\wx.rc
+    brc32 -r /i$(BCCDIR)\include /i$(WXDIR)\include $(TARGET)
+
+clean:
+        -erase *.obj
+        -erase *.exe
+        -erase *.res
+        -erase *.map
+        -erase *.rws
+
diff --git a/samples/internat/makefile.bcc b/samples/internat/makefile.bcc
new file mode 100644
index 0000000000..a8a68ccbe4
--- /dev/null
+++ b/samples/internat/makefile.bcc
@@ -0,0 +1,73 @@
+#
+# File:		makefile.bcc
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds internat example (DOS).
+
+!if "$(BCCDIR)" == ""
+!error You must define the BCCDIR variable in autoexec.bat, e.g. BCCDIR=d:\bc4
+!endif
+
+!if "$(WXWIN)" == ""
+!error You must define the WXWIN variable in autoexec.bat, e.g. WXWIN=c:\wx
+!endif
+
+WXDIR = $(WXWIN)
+!include $(WXDIR)\src\makebcc.env
+
+THISDIR = $(WXDIR)\samples\internat
+WXLIB = $(WXDIR)\lib\wx.lib
+LIBS=$(WXLIB) mathwl cwl import
+INC=-I$(WXDIR)\include\base -I$(WXDIR)\include\msw
+CFG=$(WXDIR)\src\wxwin.cfg
+
+!ifndef FINAL
+FINAL=0
+!endif
+
+!if "$(FINAL)" == "0"
+LINKFLAGS=/v/Vt /Twe /L$(WXDIR)\lib;$(BCCDIR)\lib
+OPT = -Od
+DEBUG_FLAGS= -v
+!else
+LINKFLAGS=/Twe /L$(WXDIR)\lib;$(BCCDIR)\lib
+OPT = -O2
+DEBUG_FLAGS=
+!endif
+CPPFLAGS=$(DEBUG_FLAGS) $(OPT) @$(CFG)
+
+OBJECTS = internat.obj
+
+internat:    internat.exe
+
+all:    internat.exe
+
+internat.exe:    $(WXLIB) internat.obj internat.def internat.res
+        tlink $(LINKFLAGS) @&&!
+c0wl.obj internat.obj
+internat
+nul
+$(LIBS)
+internat.def
+!
+        rc -31 -K internat.res
+
+.$(SRCSUFF).obj:
+	bcc $(CPPFLAGS) -c {$< }
+
+internat.obj:      internat.$(SRCSUFF)
+
+internat.res :      internat.rc $(WXDIR)\include\msw\wx.rc
+    rc -r /i$(BCCDIR)\include /i$(WXDIR)\include\msw /i$(WXDIR)\contrib\fafa internat
+
+clean:
+        -erase *.obj
+        -erase *.exe
+        -erase *.res
+        -erase *.map
+        -erase *.rws
diff --git a/samples/internat/makefile.dos b/samples/internat/makefile.dos
new file mode 100644
index 0000000000..99b18d8075
--- /dev/null
+++ b/samples/internat/makefile.dos
@@ -0,0 +1,65 @@
+#
+# File:		makefile.dos
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds internat example (DOS).
+# Use FINAL=1 argument to nmake to build final version with no debugging
+# info
+
+WXDIR = $(WXWIN)
+
+!include $(WXDIR)\src\makemsc.env
+
+THISDIR = $(WXDIR)\samples\internat
+
+!ifndef FINAL
+FINAL=0
+!endif
+
+HEADERS =
+SOURCES = internat.$(SRCSUFF)
+OBJECTS = internat.obj
+
+all:    internat.exe
+
+wx:
+        cd $(WXDIR)\src\msw
+        nmake -f makefile.dos FINAL=$(FINAL)
+        cd $(THISDIR)
+
+wxclean:
+        cd $(WXDIR)\src\msw
+        nmake -f makefile.dos clean
+        cd $(THISDIR)
+
+internat.exe:      $(WXDIR)\src\msw\dummy.obj $(WXLIB) internat.obj internat.def internat.res
+        link $(LINKFLAGS) @<<
+internat.obj $(WXDIR)\src\msw\dummy.obj,
+internat,
+NUL,
+$(LIBS),
+internat.def
+;
+<<
+        rc -K internat.res
+
+internat.obj:      internat.$(SRCSUFF)
+        cl @<<
+$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
+<<
+
+internat.res :      internat.rc $(WXDIR)\include\wx\msw\wx.rc
+    rc -r /i$(WXDIR)\include internat
+
+clean:
+        -erase *.obj
+        -erase *.exe
+        -erase *.res
+        -erase *.map
+        -erase *.sbr
+        -erase *.pdb
diff --git a/samples/internat/makefile.g95 b/samples/internat/makefile.g95
new file mode 100644
index 0000000000..c877d3ca8c
--- /dev/null
+++ b/samples/internat/makefile.g95
@@ -0,0 +1,36 @@
+#
+# File:		makefile.unx
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile for internat example (UNIX).
+
+WXDIR = ../..
+
+# All common UNIX compiler flags and options are now in
+# this central makefile.
+include $(WXDIR)/src/makeg95.env
+
+OBJECTS = $(OBJDIR)/internat.$(OBJSUFF)
+
+all:    $(OBJDIR) internat$(GUISUFFIX)$(EXESUFF)
+
+wx:
+
+$(OBJDIR):
+	mkdir $(OBJDIR)
+
+internat$(GUISUFFIX)$(EXESUFF):	$(OBJDIR)/internat.$(OBJSUFF) internat.res internat.$(RSCSUFF) $(WXLIB)
+	$(CC) $(LDFLAGS) -o internat$(GUISUFFIX)$(EXESUFF) internat.$(RSCSUFF) $(OBJDIR)/internat.$(OBJSUFF) $(XVIEW_LINK) $(LDLIBS)
+
+$(OBJDIR)/internat.$(OBJSUFF):	internat.$(SRCSUFF)
+	$(CC) -c $(CPPFLAGS) -o $@ internat.$(SRCSUFF)
+
+internat.res:  internat.rc
+
+clean:
+	rm -f $(OBJECTS) internat$(GUISUFFIX).exe core *.rsc *.res
diff --git a/samples/internat/makefile.nt b/samples/internat/makefile.nt
new file mode 100644
index 0000000000..22d7e49d62
--- /dev/null
+++ b/samples/internat/makefile.nt
@@ -0,0 +1,64 @@
+#
+# File:		makefile.nt
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds internat example (MS VC++).
+# Use FINAL=1 argument to nmake to build final version with no debugging
+# info
+
+# Set WXDIR for your system
+WXDIR = $(WXWIN)
+
+WXUSINGDLL=0
+
+!include $(WXDIR)\src\ntwxwin.mak
+
+THISDIR = $(WXDIR)\samples\internat
+PROGRAM=internat
+
+OBJECTS = $(PROGRAM).obj
+
+$(PROGRAM):    $(PROGRAM).exe
+
+all:    wx $(PROGRAM).exe
+
+wx:
+        cd $(WXDIR)\src\msw
+        nmake -f makefile.nt FINAL=$(FINAL)
+        cd $(THISDIR)
+
+wxclean:
+        cd $(WXDIR)\src\msw
+        nmake -f makefile.nt clean
+        cd $(THISDIR)
+
+$(PROGRAM).exe:      $(DUMMYOBJ) $(WXLIB) $(OBJECTS) $(PROGRAM).res
+	$(link) @<<
+-out:$(PROGRAM).exe
+$(LINKFLAGS)
+$(DUMMYOBJ) $(OBJECTS) $(PROGRAM).res
+$(LIBS)
+<<
+
+
+$(PROGRAM).obj:      $(PROGRAM).$(SRCSUFF) $(DUMMYOBJ)
+        $(cc) @<<
+$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
+<<
+
+$(PROGRAM).res :      $(PROGRAM).rc $(WXDIR)\include\wx\msw\wx.rc
+    $(rc) -r /i$(WXDIR)\include -fo$@ $(PROGRAM).rc
+
+
+clean:
+        -erase *.obj
+        -erase *.exe
+        -erase *.res
+        -erase *.map
+        -erase *.sbr
+        -erase *.pdb
diff --git a/samples/internat/makefile.sc b/samples/internat/makefile.sc
new file mode 100644
index 0000000000..8709d2ca0f
--- /dev/null
+++ b/samples/internat/makefile.sc
@@ -0,0 +1,35 @@
+# Symantec C++ makefile for minimal example
+# NOTE that peripheral libraries are now dealt in main wxWindows makefile.
+
+WXDIR = $(WXWIN)
+!include $(WXDIR)\src\makesc.env
+
+WXLIB = $(WXDIR)\lib\wx.lib
+INCDIR = $(WXDIR)\include
+MSWINC = $(INCDIR)\msw
+BASEINC = $(INCDIR)\base
+
+CC=sc
+RC=rc
+CFLAGS = -o -ml -W -Dwx_msw
+LDFLAGS = -ml -W
+
+INCLUDE=$(BASEINC);$(MSWINC)
+
+LIBS=$(WXLIB) libw.lib commdlg.lib shell.lib
+
+.$(SRCSUFF).obj:
+	*$(CC) -c $(CFLAGS) -I$(INCLUDE) $<
+
+.rc.res:
+	*$(RC) -r -I$(INCLUDE) $<
+
+minimal.exe: minimal.obj minimal.def minimal.res
+	*$(CC) $(LDFLAGS) -o$@ $** $(LIBS)
+
+clean:
+        -del *.obj
+	-del *.exe
+	-del *.res
+	-del *.map
+	-del *.rws
diff --git a/samples/internat/makefile.unx b/samples/internat/makefile.unx
new file mode 100644
index 0000000000..9685d06789
--- /dev/null
+++ b/samples/internat/makefile.unx
@@ -0,0 +1,58 @@
+#
+# File:		makefile.unx
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile for minimal example (UNIX).
+
+WXDIR = ../..
+
+# All common UNIX compiler flags and options are now in
+# this central makefile.
+include $(WXDIR)/src/make.env
+
+OBJECTS = $(OBJDIR)/minimal.$(OBJSUFF)
+
+.SUFFIXES:
+
+all:    $(OBJDIR) minimal$(GUISUFFIX)
+
+wx:
+
+
+motif:
+	$(MAKE) -f makefile.unx GUISUFFIX=_motif GUI=-Dwx_motif GUISUFFIX=_motif OPT='$(OPT)' LDLIBS='$(MOTIFLDLIBS)' WXLIB=$(WXDIR)/lib/libwx_motif.a  OPTIONS='$(OPTIONS)' DEBUG='$(DEBUG)' WARN='$(WARN)' XLIB='$(XLIB)' XINCLUDE='$(XINCLUDE)' XVIEW_LINK=
+
+xview:
+	cd $(WXDIR)/src/x; $(MAKE) -f makefile.unx xview
+	$(MAKE) -f makefile.unx GUI=-Dwx_xview GUISUFFIX=_ol CC=$(CC) OPTIONS='$(OPTIONS)' DEBUG='$(DEBUG)' WARN='$(WARN)' XLIB='$(XLIB)' XINCLUDE='$(XINCLUDE)'
+
+hp:
+	cd $(WXDIR)/src/x; $(MAKE) -f makefile.unx hp
+	$(MAKE) -f makefile.unx GUI=-Dwx_motif GUISUFFIX=_hp CC=CC DEBUG='$(DEBUG)' WARN='-w' \
+         XINCLUDE='$(HPXINCLUDE)' XLIB='$(HPXLIB)' XVIEW_LINK='' LDLIBS='$(HPLDLIBS)'
+
+$(OBJDIR):
+	mkdir $(OBJDIR)
+
+minimal$(GUISUFFIX):	$(OBJDIR)/minimal.$(OBJSUFF) $(WXLIB)
+	$(CC) $(LDFLAGS) -o minimal$(GUISUFFIX) $(OBJDIR)/minimal.$(OBJSUFF) $(XVIEW_LINK) $(LDLIBS)
+
+$(OBJDIR)/minimal.$(OBJSUFF):	minimal.$(SRCSUFF)
+	$(CC) -c $(CPPFLAGS) -o $@ minimal.$(SRCSUFF)
+
+clean_motif:
+	$(MAKE) -f makefile.unx GUISUFFIX=_motif cleanany
+
+clean_ol:
+	$(MAKE) -f makefile.unx GUISUFFIX=_ol cleanany
+
+clean_hp:
+	$(MAKE) -f makefile.unx GUISUFFIX=_hp cleanany
+
+cleanany:
+	rm -f $(OBJECTS) minimal$(GUISUFFIX) core
diff --git a/samples/internat/makefile.vms b/samples/internat/makefile.vms
new file mode 100644
index 0000000000..9b76b144f3
--- /dev/null
+++ b/samples/internat/makefile.vms
@@ -0,0 +1,38 @@
+#************************************************************************
+# Makefile for MINIMAL under VMS
+# by Stefan Hammes
+# (incomplete) update history:
+# 11.04.95
+#************************************************************************
+
+#************************************************************************
+# Definition section
+# (cave: definitions and includes must begin with ',')
+#************************************************************************
+
+APPOPTS = 
+APPDEFS = 
+APPINCS = 
+
+#************************************************************************
+# Module section
+#************************************************************************
+
+# Name of main module
+MAIN = minimal
+
+# Object modules of the application.
+OBJS = minimal.obj
+OBJLIST =minimal.obj
+
+.include [--.src]makevms.env
+
+# main dependency
+$(MAIN).exe : $(OBJS)
+    $(LINK) $(LINKFLAGS) /exec=$(MAIN).exe $(OBJLIST),$(WXLIB)/lib,$(OPTSFILE)/option
+    - purge *.exe
+
+#************************************************************************
+# Header file depedencies following
+#************************************************************************
+
diff --git a/samples/internat/makefile.wat b/samples/internat/makefile.wat
new file mode 100644
index 0000000000..21219d7a0e
--- /dev/null
+++ b/samples/internat/makefile.wat
@@ -0,0 +1,43 @@
+#
+# Makefile for WATCOM
+#
+# Created by D.Chubraev, chubraev@iem.ee.ethz.ch
+# 8 Nov 1994
+#
+
+WXDIR = ..\.. 
+
+!include $(WXDIR)\src\makewat.env
+
+WXLIB = $(WXDIR)\lib
+NAME = minimal
+LNK = $(name).lnk
+OBJS = $(name).obj 
+
+all: $(name).exe
+
+$(name).exe : $(OBJS) $(name).res $(LNK) $(WXLIB)\wx$(LEVEL).lib
+    wlink @$(LNK)
+    $(BINDCOMMAND) $(name).res
+
+$(name).res :      $(name).rc $(WXDIR)\include\msw\wx.rc
+     $(RC) $(RESFLAGS1) $(name).rc
+
+$(LNK) : makefile.wat
+    %create $(LNK)
+    @%append $(LNK) debug all
+    @%append $(LNK) system $(LINKOPTION)
+    @%append $(LNK) $(MINDATA)
+    @%append $(LNK) $(MAXDATA)
+    @%append $(LNK) $(STACK)
+    @%append $(LNK) name $(name)
+    @%append $(LNK) file $(WXLIB)\wx$(LEVEL).lib
+    @for %i in ($(EXTRALIBS)) do @%append $(LNK) file %i
+    @for %i in ($(OBJS)) do @%append $(LNK) file %i
+
+thing: .SYMBOLIC
+    echo $(WATLIBDIR)
+
+clean:   .SYMBOLIC
+    -erase *.obj *.bak *.err *.pch *.lib *.lnk *.res *.exe
+
diff --git a/samples/internat/mondrian.ico b/samples/internat/mondrian.ico
new file mode 100644
index 0000000000000000000000000000000000000000..2310c5d275a87af295d5ea8dc79ea417a5e74c53
GIT binary patch
literal 766
zcmZQzU<5)11px*Sc)`TLAO@s0fLH;D9e|jTfdxnc0Z<M**w4TKL=5})Lnt5#WHKB$
zaDbtqp#doIAB-6O{|B*v7zjZ^AOa2W|NsACHyAJ}De?dRKnp(HN~rljcR;{k;{zQE
i@;}UZ|9Q?Fpp*~yJCwmWbLIrN`9Qm9%}2L?p!oo$cZ4ed

literal 0
HcmV?d00001

diff --git a/samples/internat/wxstd.po b/samples/internat/wxstd.po
new file mode 100644
index 0000000000..100109b3b7
--- /dev/null
+++ b/samples/internat/wxstd.po
@@ -0,0 +1,131 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Free Software Foundation, Inc.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 1997-12-19 17:46+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: ENCODING\n"
+
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Free Software Foundation, Inc.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#: file.cpp:182 hello.cpp:38
+#, fuzzy, c-format
+msgid "can't create file '%s'"
+msgstr "impossible de créer le fichier '%s'"
+
+#: file.cpp:213
+#, c-format
+msgid "can't open file '%s'"
+msgstr "impossible d'ouvrir le fichier '%s'"
+
+#: file.cpp:227
+#, c-format
+msgid "can't close file descriptor %d"
+msgstr "impossible de fermer le descripteur %d"
+
+#: file.cpp:244
+#, c-format
+msgid "can't read from file descriptor %d"
+msgstr "impossible de lire à partir de descripteur %d"
+
+#: file.cpp:258
+#, c-format
+msgid "can't write to file descriptor %d"
+msgstr "impossible d'écrire sur le descripteur %d"
+
+#: file.cpp:271
+#, c-format
+msgid "can't flush file descriptor %d"
+msgstr "impossible de mettre à jour le descripteur %d"
+
+#: file.cpp:308
+#, c-format
+msgid "can't seek on file descriptor %d"
+msgstr "impossible de changer la position sur le descripteur %d"
+
+#: file.cpp:322
+#, c-format
+msgid "can't get seek position on file descriptor %d"
+msgstr "impossible d'obtenir la position courante sur le descripteur %d"
+
+#: file.cpp:355
+#, c-format
+msgid "can't find length of file on file descriptor %d"
+msgstr ""
+"impossible de trouver la taille du fichier ouvert sur le descripteur %d"
+
+#: intl.cpp:139
+#, c-format
+msgid "catalog file for domain '%s' not found."
+msgstr "impossible de trouver le catalogue de messages pour le domaine '%s'."
+
+#: intl.cpp:177
+#, c-format
+msgid "'%s' is not a valid message catalog."
+msgstr "'%s' n'est pas un catalogue de messages valid."
+
+#: intl.cpp:330 intl.cpp:334
+#, c-format
+msgid "locale '%s' can not be set."
+msgstr "impossible de passer à locale '%s'."
+
+#: intl.cpp:431 intl.cpp:435
+#, c-format
+msgid "string '%s' not found in domain '%s' for locale '%s'."
+msgstr "chaîne '%s' n'a pas été trouvé dans le domaine '%s' pour le locale '%s'."
+
+#: intl.cpp:434 intl.cpp:438
+#, c-format
+msgid "string '%s' not found in locale '%s'."
+msgstr "chaîne '%s' n'a pas été trouvé dans le locale '%s'."
+
+#: log.cpp:104
+#, c-format
+msgid " (error %ld: %s)"
+msgstr " (erreur %ld: %s)"
+
+#: log.cpp:165
+msgid "Debug: "
+msgstr "Debug: "
+
+#: log.cpp:171
+msgid "Fatal error: "
+msgstr "Erreur fatale: "
+
+#: log.cpp:172
+msgid "Program aborted.\n"
+msgstr "Programme abandonné.\n"
+
+#: log.cpp:177
+msgid "Error: "
+msgstr "Erreur: "
+
+#: log.cpp:181
+msgid "Warning: "
+msgstr "Attention: "
+
+#: log.cpp:268
+#, c-format
+msgid "Assert failed in file %s at line %d"
+msgstr "Assertion est fausse dans le fichier %s à la ligne %d"
+
+#: file.cpp:303
+msgid "unknown seek origin"
+msgstr ""
+
+msgid "looking for catalog '%s' in path '%s'."
+msgstr ""
+
+#: intl.cpp:378
+msgid "no message catalog list"
+msgstr ""
diff --git a/samples/layout/Makefile b/samples/layout/Makefile
new file mode 100644
index 0000000000..027d82ae19
--- /dev/null
+++ b/samples/layout/Makefile
@@ -0,0 +1 @@
+include ../../src/gtk/setup/general/makeapp
diff --git a/samples/layout/Makefile.in b/samples/layout/Makefile.in
new file mode 100644
index 0000000000..65e4932f02
--- /dev/null
+++ b/samples/layout/Makefile.in
@@ -0,0 +1,26 @@
+# WXXT base directory
+WXBASEDIR=@WXBASEDIR@
+
+# set the OS type for compilation
+OS=@OS@
+# compile a library only
+RULE=bin
+
+# define library name
+BIN_TARGET=test
+# define library sources
+BIN_SRC=\
+layout.cpp
+
+#define library objects
+BIN_OBJ=\
+layout.o
+
+# additional things needed to link
+BIN_LINK=
+
+# additional things needed to compile
+ADD_COMPILE=
+
+# include the definitions now
+include ../../../template.mak
diff --git a/samples/layout/aiai.ico b/samples/layout/aiai.ico
new file mode 100644
index 0000000000000000000000000000000000000000..a3db6563cc0b9f4588e1e994fe54b90a3cb1d6c1
GIT binary patch
literal 766
zcmc(bJ930T3`Bcft}@v=+L+MC@X_W5#I6lE$3$=(hlEfB<Ja@?LOIyb0!^!t)JP*;
zc>4Zbw(l3|27cf@{)u1o%88L{R;n8d60briz)7fio<S#4ewC6VoX4NcpV>a{V~VK)
z)$t4e1%j>c0*T7ZEBuvb0Ndch+2BCx7U^mZHa?iIh11ZPGV>8*oPzc{HmcjEM7U^(
z*rd)gSRm_`KJo;dxt={X3#3|q&kYE;ul$En1WJC3UOX%3ev8=<z}j41;VP{UzUs~U
s)wx~DuB_~?Y=Qe|v5`BV=<&%~$Nt1hCmx0~Ul2L;AGObMz1)9;A6NK_vj6}9

literal 0
HcmV?d00001

diff --git a/samples/layout/aiai.xbm b/samples/layout/aiai.xbm
new file mode 100644
index 0000000000..1a6f0a31b1
--- /dev/null
+++ b/samples/layout/aiai.xbm
@@ -0,0 +1,38 @@
+#define aiai_width 64
+#define aiai_height 64
+static char aiai_bits[] = {
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x44,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x44,0x44,0x44,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x44,0x44,0x44,0x42,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x47,0x44,0x44,0x44,0x44,0x11,0x11,0x11,0x17,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x91,0x1f,0x11,0x11,0x11,0x11,0x44,0x44,0xc4,0x4f,0x44,0x44,0x44,0x44,
+ 0x44,0x44,0xc4,0x5f,0x44,0xf4,0x45,0x44,0x11,0x11,0xf1,0x1f,0x11,0xf9,0x13,
+ 0x11,0x11,0x11,0xf1,0x3f,0x11,0xfd,0x13,0x11,0x44,0x44,0xf4,0x7f,0x44,0xfc,
+ 0x47,0x44,0x44,0x44,0xf4,0x7f,0x44,0xfc,0x47,0x44,0x11,0x11,0xf9,0x7f,0x11,
+ 0xf9,0x13,0x11,0x11,0x11,0xfd,0xff,0x11,0xf1,0x11,0x11,0x44,0x44,0xfc,0xff,
+ 0x44,0x44,0x44,0x44,0x44,0x44,0xfe,0xff,0x45,0x44,0x44,0x44,0x11,0x11,0xff,
+ 0xff,0x11,0xfd,0x13,0x11,0x11,0x11,0xff,0xff,0x13,0xfd,0x13,0x11,0x44,0xc4,
+ 0xff,0xff,0x07,0xfc,0x43,0x44,0x44,0xff,0xff,0xf9,0xff,0xfd,0xfb,0xff,0x11,
+ 0xc0,0xff,0x00,0x00,0xfc,0x03,0x00,0x11,0xc0,0x7f,0x00,0x00,0xfc,0x03,0x00,
+ 0x04,0xe0,0x7f,0x00,0x00,0xfc,0x03,0x00,0xf4,0xf7,0xbf,0xff,0xff,0xfd,0xfb,
+ 0x7f,0x01,0xf0,0x1f,0x00,0x00,0xfc,0x03,0x00,0x01,0xf8,0x1f,0x00,0x00,0xfc,
+ 0x03,0x00,0x00,0xfc,0x0f,0x00,0x00,0xfc,0x03,0x40,0xfe,0xfd,0xef,0xff,0xff,
+ 0xfd,0xfb,0x4f,0x00,0xfe,0x07,0x00,0x00,0xfc,0x03,0x10,0x00,0xfe,0x03,0x00,
+ 0x00,0xfc,0x03,0x10,0x00,0xff,0x03,0x00,0x00,0xfc,0x03,0x44,0x7f,0xff,0x01,
+ 0x00,0x00,0xfc,0xfb,0x44,0x91,0xff,0xff,0xff,0xff,0xff,0x13,0x11,0xd1,0xff,
+ 0xff,0xff,0xff,0xff,0x13,0x11,0xe4,0xff,0xff,0xff,0xff,0xff,0x47,0x44,0xe4,
+ 0xff,0xff,0xff,0xff,0xff,0x47,0x44,0xf1,0xff,0xff,0xff,0xff,0xff,0x13,0x11,
+ 0xf1,0xff,0xff,0xff,0xff,0xff,0x13,0x11,0xfc,0xff,0xff,0xff,0xff,0xff,0x47,
+ 0x44,0xfc,0xff,0xff,0xff,0xff,0xff,0x47,0x44,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x11,0x44,0x44,0xc4,0x44,0x44,
+ 0xc4,0x44,0x44,0x44,0x4e,0xc4,0x44,0x4e,0xc4,0x44,0x44,0x11,0x1f,0xd1,0x11,
+ 0x1f,0xd1,0x11,0x11,0x91,0x31,0xd1,0x91,0x31,0xd1,0x11,0x11,0xc4,0x64,0xcc,
+ 0xcc,0x64,0xcc,0x44,0x44,0x64,0xc4,0xcc,0x6c,0xc4,0xcc,0x44,0x44,0xf1,0xff,
+ 0xd1,0xf1,0xff,0xd1,0x11,0x11,0xf9,0xff,0xd3,0xf9,0xff,0xd3,0x11,0x11,0x4c,
+ 0x44,0xc6,0x4c,0x44,0xc6,0x44,0x44,0x4c,0x44,0xc6,0x4c,0x44,0xc6,0x44,0x44,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x44};
diff --git a/samples/layout/expt.cpp b/samples/layout/expt.cpp
new file mode 100644
index 0000000000..af2c089b84
--- /dev/null
+++ b/samples/layout/expt.cpp
@@ -0,0 +1,161 @@
+/*
+ * Experimental code to use operators for constraint specification.
+ * In the end, the syntax didn't look much clearer than
+ * the original, so abandoned.
+
+ Example:
+ 
+  wxConstrain(frame->panel,
+  
+    ( leftOf   (frame->panel) = leftOf   (frame),
+      topOf    (frame->panel) = topOf    (frame),
+      rightOf  (frame->panel) = rightOf  (frame),
+      heightOf (frame->panel) = 50 % heightOf (frame)
+    )
+  );
+ */
+
+// Operator experiments
+#define wxCONSTRAINT_OP_REL   1
+#define wxCONSTRAINT_OP_PERCENT 2
+#define wxCONSTRAINT_OP_EDGE  3
+#define wxCONSTRAINT_OP_ABS   4
+#define wxCONSTRAINT_OP_AND   5
+
+class wxConstraintOp: public wxObject
+{
+ public:
+   int opType;
+   wxEdge edge;
+   wxRelationship relationship;
+   wxWindow *win;
+   int value;
+   int margin;
+   wxConstraintOp *lhs;
+   wxConstraintOp *rhs;
+   wxConstraintOp(int typ)
+   {
+     opType = typ;
+     edge = wxLeft;
+     win = NULL;
+     value = 0;
+     margin = 0;
+     relationship = wxSameAs;
+     lhs = 0; rhs = 0;
+   }
+   wxConstraintOp(const wxConstraintOp& op)
+   {
+     opType = op.opType;
+     edge = op.edge;
+     relationship = op.relationship;
+     win = op.win;
+     value = op.value;
+     margin = op.margin;
+     if (op.lhs)
+       lhs = new wxConstraintOp(*op.lhs);
+     else
+       lhs = NULL;
+     if (op.rhs)
+       rhs = new wxConstraintOp(*op.rhs);
+     else
+       rhs = NULL;
+   }
+   ~wxConstraintOp(void)
+   {
+     if (lhs)
+       delete lhs;
+     if (rhs)
+       delete rhs;
+   }
+
+  wxConstraintOp operator = (const wxConstraintOp& arg2);
+  wxConstraintOp operator = (const int value);
+  
+  friend wxConstraintOp operator % (const int perCent, const wxConstraintOp& arg2);
+  friend wxConstraintOp operator + (wxConstraintOp& arg1, int margin);
+  friend wxConstraintOp operator - (wxConstraintOp& arg1, int margin);
+  friend wxConstraintOp operator , (const wxConstraintOp& arg1, const wxConstraintOp& arg2);
+};
+
+wxConstraintOp leftOf(wxWindow *win)
+{
+  wxConstraintOp thing(wxCONSTRAINT_OP_EDGE);
+  thing.win = win;
+  thing.edge = wxLeft;
+  return thing;
+}
+
+wxConstraintOp topOf(wxWindow *win)
+{
+  wxConstraintOp thing(wxCONSTRAINT_OP_EDGE);
+  thing.win = win;
+  thing.edge = wxTop;
+  return thing;
+}
+
+wxConstraintOp widthOf(wxWindow *win)
+{
+  wxConstraintOp thing(wxCONSTRAINT_OP_EDGE);
+  thing.win = win;
+  thing.edge = wxWidth;
+  return thing;
+}
+
+wxConstraintOp wxConstraintOp::operator = (const wxConstraintOp& arg2)
+{
+  wxConstraintOp op3(wxCONSTRAINT_OP_REL);
+  op3.relationship = wxPercentOf;
+  op3.value = 100;
+  if ((op3.relationship == wxPercentOf) && (op3.value > 0))
+    op3.value = this->value;
+  op3.lhs = new wxConstraintOp(*this);
+  op3.rhs = new wxConstraintOp(arg2);
+
+  return op3;
+}
+
+wxConstraintOp wxConstraintOp::operator = (const int value)
+{
+  wxConstraintOp op3(wxCONSTRAINT_OP_REL);
+  op3.relationship = wxAbsolute;
+
+  op3.lhs = new wxConstraintOp(*this);
+  op3.rhs = new wxConstraintOp(wxCONSTRAINT_OP_ABS);
+  op3.value = value;
+
+  return op3;
+}
+
+wxConstraintOp operator % (const int perCent, const wxConstraintOp& arg2)
+{
+  wxConstraintOp op3(arg2);
+  op3.opType = wxCONSTRAINT_OP_EDGE;
+  op3.value = perCent;
+  if (op3.value > 0)
+    op3.value = arg2.value;
+
+  return op3;
+}
+
+wxConstraintOp operator + (wxConstraintOp& arg1, int margin)
+{
+  wxConstraintOp op3(arg1);
+  op3.margin = margin;
+  return op3;
+}
+
+wxConstraintOp operator - (wxConstraintOp& arg1, int margin)
+{
+  wxConstraintOp op3(arg1);
+  op3.margin = - margin;
+  return op3;
+}
+
+wxConstraintOp operator , (const wxConstraintOp& arg1, const wxConstraintOp& arg2)
+{
+  wxConstraintOp op3(wxCONSTRAINT_OP_AND);
+  op3.lhs = new wxConstraintOp(arg1);
+  op3.rhs = new wxConstraintOp(arg2);
+
+  return op3;
+}
diff --git a/samples/layout/fload.xbm b/samples/layout/fload.xbm
new file mode 100644
index 0000000000..27af1f939b
--- /dev/null
+++ b/samples/layout/fload.xbm
@@ -0,0 +1,11 @@
+#define fload_width 30
+#define fload_height 30
+static char fload_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x0f,0xf8,0xff,0xfb,0x0f,0x08,0x00,0xf0,
+ 0x0f,0xc8,0xff,0xef,0x0f,0x48,0x00,0xf0,0x0f,0x48,0x00,0xf8,0x0f,0x48,0x00,
+ 0xfc,0x0e,0x48,0x00,0x7f,0x0c,0x48,0xc0,0xbf,0x00,0x48,0xf0,0x9f,0x04,0x48,
+ 0xfe,0x8f,0x04,0x48,0xff,0x87,0x04,0x48,0x00,0x80,0x04,0x48,0x00,0x80,0x04,
+ 0x48,0x00,0x80,0x04,0x48,0x00,0x80,0x04,0xc8,0xff,0xff,0x04,0x08,0x00,0x00,
+ 0x04,0x08,0x00,0x00,0x04,0x08,0xff,0x1f,0x04,0x08,0x01,0x10,0x04,0x08,0x1d,
+ 0x10,0x04,0x08,0x15,0x10,0x04,0x08,0x15,0x10,0x04,0x08,0x15,0x10,0x04,0x08,
+ 0x15,0x10,0x04,0x10,0x1d,0x10,0x04,0xe0,0xff,0xff,0x07,0x00,0x00,0x00,0x00};
diff --git a/samples/layout/layout.cpp b/samples/layout/layout.cpp
new file mode 100644
index 0000000000..7cf0458e7b
--- /dev/null
+++ b/samples/layout/layout.cpp
@@ -0,0 +1,367 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        layout.cpp
+// Purpose:     Layout sample
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+// For compilers that support precompilation, includes "wx/wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#if !USE_CONSTRAINTS
+#error You must set USE_CONSTRAINTS to 1 in wx_setup.h!
+#endif
+
+#include <ctype.h>
+#include "layout.h"
+
+// Declare two frames
+MyFrame   *frame = NULL;
+wxMenuBar *menu_bar = NULL;
+
+IMPLEMENT_APP(MyApp)
+
+#ifdef __X__
+#include "aiai.xbm"
+#endif
+
+MyApp::MyApp()
+{
+}
+
+bool MyApp::OnInit(void)
+{
+  // Create the main frame window
+  frame = new MyFrame(NULL, "wxWindows Layout Demo", 0, 0, 550, 500);
+
+  frame->SetAutoLayout(TRUE);
+
+  // Give it a status line
+  frame->CreateStatusBar(2);
+
+  // Load icon and bitmap
+#ifdef __WINDOWS__
+  frame->SetIcon(wxIcon("aiai_icn"));
+#endif
+#ifdef __X__
+  frame->SetIcon(wxIcon(aiai_bits, aiai_width, aiai_height));
+#endif
+
+  // Make a menubar
+  wxMenu *file_menu = new wxMenu;
+
+  file_menu->Append(LAYOUT_LOAD_FILE, "&Load file",      "Load a text file");
+  file_menu->Append(LAYOUT_TEST, "&Test sizers",      "Test sizer code");
+
+  file_menu->AppendSeparator();
+  file_menu->Append(LAYOUT_QUIT, "E&xit",                "Quit program");
+
+  wxMenu *help_menu = new wxMenu;
+  help_menu->Append(LAYOUT_ABOUT, "&About",              "About layout demo");
+
+  menu_bar = new wxMenuBar;
+
+  menu_bar->Append(file_menu, "&File");
+  menu_bar->Append(help_menu, "&Help");
+
+  // Associate the menu bar with the frame
+  frame->SetMenuBar(menu_bar);
+
+  // Make a panel
+  frame->panel = new wxPanel(frame, 0, 0, 1000, 500, wxTAB_TRAVERSAL);
+  frame->panel->SetBackgroundColour(wxColour(192, 192, 192));
+//  frame->panel->SetAutoLayout(TRUE);
+
+  // Create some panel items
+  wxButton *btn1 = new wxButton(frame->panel, -1, "A button (1)") ;
+
+  wxLayoutConstraints *b1 = new wxLayoutConstraints;
+  b1->centreX.SameAs    (frame->panel, wxCentreX);
+  b1->top.SameAs        (frame->panel, wxTop, 5);
+  b1->width.PercentOf   (frame->panel, wxWidth, 80);
+  b1->height.PercentOf  (frame->panel, wxHeight, 10);
+  btn1->SetConstraints(b1);
+
+  wxListBox *list = new wxListBox(frame->panel, -1,
+                                  wxPoint(-1, -1), wxSize(200, 100));
+  list->Append("Apple");
+  list->Append("Pear");
+  list->Append("Orange");
+  list->Append("Banana");
+  list->Append("Fruit");
+
+  wxLayoutConstraints *b2 = new wxLayoutConstraints;
+  b2->top.Below         (btn1, 5);
+  b2->left.SameAs       (frame->panel, wxLeft, 5);
+  b2->width.PercentOf   (frame->panel, wxWidth, 40);
+  b2->bottom.SameAs     (frame->panel, wxBottom, 5);
+  list->SetConstraints(b2);
+
+  wxTextCtrl *mtext = new wxTextCtrl(frame->panel, -1, "Some text",
+                        wxPoint(-1, -1), wxSize(150, 100));
+
+  wxLayoutConstraints *b3 = new wxLayoutConstraints;
+  b3->top.Below         (btn1, 5);
+  b3->left.RightOf      (list, 5);
+  b3->right.SameAs      (frame->panel, wxRight, 5);
+  b3->bottom.SameAs     (frame->panel, wxBottom, 5);
+  mtext->SetConstraints(b3);
+
+  frame->canvas = new MyWindow(frame, 0, 0, 400, 400, wxRETAINED);
+
+  // Give it scrollbars: the virtual canvas is 20 * 50 = 1000 pixels in each direction
+//  canvas->SetScrollbars(20, 20, 50, 50, 4, 4);
+
+  // Make a text window
+  frame->text_window = new MyTextWindow(frame, 0, 250, 400, 250);
+
+  // Set constraints for panel subwindow
+  wxLayoutConstraints *c1 = new wxLayoutConstraints;
+
+  c1->left.SameAs       (frame, wxLeft);
+  c1->top.SameAs        (frame, wxTop);
+  c1->right.PercentOf   (frame, wxWidth, 50);
+  c1->height.PercentOf  (frame, wxHeight, 50);
+
+  frame->panel->SetConstraints(c1);
+
+  // Set constraints for canvas subwindow
+  wxLayoutConstraints *c2 = new wxLayoutConstraints;
+
+  c2->left.SameAs       (frame->panel, wxRight);
+  c2->top.SameAs        (frame, wxTop);
+  c2->right.SameAs      (frame, wxRight);
+  c2->height.PercentOf  (frame, wxHeight, 50);
+
+  frame->canvas->SetConstraints(c2);
+
+  // Set constraints for text subwindow
+  wxLayoutConstraints *c3 = new wxLayoutConstraints;
+  c3->left.SameAs       (frame, wxLeft);
+  c3->top.Below         (frame->panel);
+  c3->right.SameAs      (frame, wxRight);
+  c3->bottom.SameAs     (frame, wxBottom);
+
+  frame->text_window->SetConstraints(c3);
+
+  frame->Show(TRUE);
+
+  frame->SetStatusText("wxWindows layout demo");
+
+  SetTopWindow(frame);
+  return TRUE;
+}
+
+// Define my frame constructor
+MyFrame::MyFrame(wxFrame *frame, char *title, int x, int y, int w, int h):
+  wxFrame(frame, -1, title, wxPoint(x, y), wxSize(w, h))
+{
+  panel = NULL;
+  text_window = NULL;
+  canvas = NULL;
+}
+
+BEGIN_EVENT_TABLE(MyFrame, wxFrame)
+  EVT_MENU(LAYOUT_LOAD_FILE, MyFrame::LoadFile)
+  EVT_MENU(LAYOUT_QUIT, MyFrame::Quit)
+  EVT_MENU(LAYOUT_TEST, MyFrame::TestSizers)
+  EVT_MENU(LAYOUT_ABOUT, MyFrame::About)
+  EVT_SIZE(MyFrame::OnSize)
+END_EVENT_TABLE()
+
+void MyFrame::LoadFile(wxCommandEvent& event)
+{
+      char *s = wxFileSelector("Load text file", NULL, NULL, NULL, "*.txt");
+      if (s)
+      {
+#ifdef __WINDOWS__
+        frame->text_window->LoadFile(s);
+#endif
+      }
+}
+
+void MyFrame::Quit(wxCommandEvent& event)
+{
+      this->Close(TRUE);
+}
+
+void MyFrame::TestSizers(wxCommandEvent& event)
+{
+  SizerFrame *newFrame = new SizerFrame(NULL, "Sizer Test Frame", 50, 50, 500, 500);
+  newFrame->Show(TRUE);
+}
+
+void MyFrame::About(wxCommandEvent& event)
+{
+      (void)wxMessageBox("wxWindows GUI library layout demo\n",
+            "About Layout Demo", wxOK|wxCENTRE);
+}
+
+// Size the subwindows when the frame is resized
+void MyFrame::OnSize(wxSizeEvent& event)
+{
+    Layout();
+}
+
+void MyFrame::Draw(wxDC& dc, bool draw_bitmaps)
+{
+  dc.SetPen(wxGREEN_PEN);
+  dc.DrawLine(0.0, 0.0, 200.0, 200.0);
+  dc.DrawLine(200.0, 0.0, 0.0, 200.0);
+
+  dc.SetBrush(wxCYAN_BRUSH);
+  dc.SetPen(wxRED_PEN);
+
+  dc.DrawRectangle(100.0, 100.0, 100.0, 50.0);
+  dc.DrawRoundedRectangle(150.0, 150.0, 100.0, 50.0,20.0);
+
+  dc.DrawEllipse(250.0, 250.0, 100.0, 50.0);
+  dc.DrawSpline(50.0, 200.0, 50.0, 100.0, 200.0, 10.0);
+  dc.DrawLine(50.0, 230.0, 200.0, 230.0);
+
+  dc.SetPen(wxBLACK_PEN);
+  dc.DrawArc(50.0, 300.0, 100.0, 250.0, 100.0, 300.0);
+}
+
+BEGIN_EVENT_TABLE(MyWindow, wxWindow)
+    EVT_PAINT(MyWindow::OnPaint)
+END_EVENT_TABLE()
+
+// Define a constructor for my canvas
+MyWindow::MyWindow(wxFrame *frame, int x, int y, int w, int h, long style):
+ wxWindow(frame, -1, wxPoint(x, y), wxSize(w, h), style)
+{
+}
+
+MyWindow::~MyWindow(void)
+{
+}
+
+// Define the repainting behaviour
+void MyWindow::OnPaint(wxPaintEvent& event)
+{
+  wxPaintDC dc(this);
+  frame->Draw(dc,TRUE);
+}
+
+// Define the behaviour for the frame closing
+// - must delete all frames except for the main one.
+bool MyFrame::OnClose(void)
+{
+  Show(FALSE);
+
+  return TRUE;
+}
+
+SizerFrame::SizerFrame(wxFrame *frame, char *title, int x, int y, int w, int h):
+  wxFrame(frame, -1, title, wxPoint(x, y), wxSize(w, h))
+{
+  panel = new wxPanel(this, -1, wxPoint(0, 0), wxSize(-1, -1), wxTAB_TRAVERSAL);
+  panel->SetBackgroundColour(wxColour(192, 192, 192));
+
+  // A sizer to fit the whole panel, plus two sizers, one
+  // above the other. A button is centred on the lower
+  // sizer; a rowcol containing 3 buttons is centred on the upper
+  // sizer.
+  wxSizer *expandSizer = new wxSizer(panel, wxSizerExpand);
+  expandSizer->SetName("expandSizer");
+
+  wxLayoutConstraints *c;
+
+  /////// TOP OF PANEL
+  ///////
+  wxSizer *topSizer = new wxSizer(expandSizer);
+  topSizer->SetName("topSizer");
+
+  // Specify constraints for the top sizer
+  c = new wxLayoutConstraints;
+  c->left.SameAs       (expandSizer, wxLeft);
+  c->top.SameAs        (expandSizer, wxTop);
+  c->right.SameAs      (expandSizer, wxRight);
+  c->height.PercentOf  (expandSizer, wxHeight, 50);
+
+  topSizer->SetConstraints(c);
+
+ /*
+  * Add a row-col sizer and some buttons
+  */
+
+  // Default is layout by rows, 20 columns per row, shrink to fit.
+  wxRowColSizer *rowCol = new wxRowColSizer(topSizer);
+  rowCol->SetName("rowCol");
+  
+  wxButton *button = new wxButton(panel, -1, "Button 1");
+  rowCol->AddSizerChild(button);
+
+  button = new wxButton(panel, -1, "Button 2");
+  rowCol->AddSizerChild(button);
+
+  button = new wxButton(panel, -1, "Button 3");
+  rowCol->AddSizerChild(button);
+
+  // Centre the rowcol in the middle of the upper sizer
+  c = new wxLayoutConstraints;
+  c->centreX.SameAs    (topSizer, wxCentreX);
+  c->centreY.SameAs    (topSizer, wxCentreY);
+  c->width.AsIs();
+  c->height.AsIs();
+  rowCol->SetConstraints(c);
+
+  /////// BOTTOM OF PANEL
+  ///////
+  wxSizer *bottomSizer = new wxSizer(expandSizer);
+
+  // Specify constraints for the bottom sizer
+  c = new wxLayoutConstraints;
+  c->left.SameAs       (expandSizer, wxLeft);
+  c->top.PercentOf     (expandSizer, wxHeight, 50);
+  c->right.SameAs      (expandSizer, wxRight);
+  c->height.PercentOf  (expandSizer, wxHeight, 50);
+
+  bottomSizer->SetConstraints(c);
+
+  wxButton *button2 = new wxButton(panel, -1, "Test button");
+
+  // The button should be a child of the bottom sizer
+  bottomSizer->AddSizerChild(button2);
+
+  // Centre the button on the sizer
+  c = new wxLayoutConstraints;
+  c->centreX.SameAs    (bottomSizer, wxCentreX);
+  c->centreY.SameAs    (bottomSizer, wxCentreY);
+  c->width.PercentOf   (bottomSizer, wxWidth, 20);
+  c->height.PercentOf  (bottomSizer, wxHeight, 20);
+  button2->SetConstraints(c);
+}
+
+BEGIN_EVENT_TABLE(SizerFrame, wxFrame)
+  EVT_SIZE(SizerFrame::OnSize)
+END_EVENT_TABLE()
+
+
+// Size the subwindows when the frame is resized
+void SizerFrame::OnSize(wxSizeEvent& event)
+{
+  wxFrame::OnSize(event);
+  panel->Layout();
+}
+
+bool SizerFrame::OnClose(void)
+{
+  Show(FALSE);
+
+  return TRUE;
+}
+
diff --git a/samples/layout/layout.def b/samples/layout/layout.def
new file mode 100644
index 0000000000..0a7e3cb840
--- /dev/null
+++ b/samples/layout/layout.def
@@ -0,0 +1,9 @@
+NAME         Layout
+DESCRIPTION  'Layout'
+EXETYPE      WINDOWS
+STUB         'WINSTUB.EXE'
+CODE         PRELOAD MOVEABLE DISCARDABLE
+DATA         PRELOAD MOVEABLE MULTIPLE
+HEAPSIZE     1024
+STACKSIZE    16192
+
diff --git a/samples/layout/layout.h b/samples/layout/layout.h
new file mode 100644
index 0000000000..83aca0d956
--- /dev/null
+++ b/samples/layout/layout.h
@@ -0,0 +1,79 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        layout.h
+// Purpose:     Layout sample
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+// Define a new application
+class MyApp: public wxApp
+{
+  public:
+    MyApp(void) ;
+    bool OnInit(void);
+};
+
+// Define a new frame
+class MyTextWindow;
+class MyWindow;
+
+class MyFrame: public wxFrame
+{
+  public:
+    wxPanel *panel;
+    MyTextWindow *text_window;
+    MyWindow *canvas;
+    MyFrame(wxFrame *frame, char *title, int x, int y, int w, int h);
+    void OnSize(wxSizeEvent& event);
+    bool OnClose(void);
+    void Draw(wxDC& dc, bool draw_bitmaps = TRUE);
+
+    void LoadFile(wxCommandEvent& event);
+    void Quit(wxCommandEvent& event);
+    void TestSizers(wxCommandEvent& event);
+    void About(wxCommandEvent& event);
+
+  DECLARE_EVENT_TABLE()
+};
+
+// Define a new text subwindow that can respond to drag-and-drop
+class MyTextWindow: public wxTextCtrl
+{
+  public:
+  MyTextWindow(wxFrame *frame, int x=-1, int y=-1, int width=-1, int height=-1,
+               long style=wxTE_MULTILINE):
+    wxTextCtrl(frame, -1, "", wxPoint(x, y), wxSize(width, height), style)
+  {
+  }
+};
+
+// Define a new canvas which can receive some events
+class MyWindow: public wxWindow
+{
+  public:
+    MyWindow(wxFrame *frame, int x, int y, int w, int h, long style = wxRETAINED);
+    ~MyWindow(void) ;
+    void OnPaint(wxPaintEvent& event);
+    
+    DECLARE_EVENT_TABLE()
+};
+
+class SizerFrame: public wxFrame
+{
+  public:
+    wxPanel *panel;
+    SizerFrame(wxFrame *frame, char *title, int x, int y, int w, int h);
+    void OnSize(wxSizeEvent& event);
+    bool OnClose(void);
+
+   DECLARE_EVENT_TABLE()
+};
+
+#define LAYOUT_QUIT       100
+#define LAYOUT_TEST       101
+#define LAYOUT_ABOUT      102
+#define LAYOUT_LOAD_FILE  103
diff --git a/samples/layout/layout.rc b/samples/layout/layout.rc
new file mode 100644
index 0000000000..ac6e44cd4f
--- /dev/null
+++ b/samples/layout/layout.rc
@@ -0,0 +1,3 @@
+aiai_icn ICON "aiai.ico"
+
+#include "wx/msw/wx.rc"
diff --git a/samples/layout/makefile.b32 b/samples/layout/makefile.b32
new file mode 100644
index 0000000000..765fe58400
--- /dev/null
+++ b/samples/layout/makefile.b32
@@ -0,0 +1,63 @@
+#
+# File:		makefile.bcc
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds layout example (DOS).
+
+# WXWIN and BCCDIR are set by parent make
+
+WXDIR = $(WXWIN)
+!include $(WXDIR)\src\makeb32.env
+
+WXLIBDIR = $(WXDIR)\lib
+WXLIB = $(WXLIBDIR)\wx32.lib
+LIBS=$(WXLIB) cw32 import32
+
+TARGET=layout
+
+!if "$(FINAL)" == "0"
+LINKFLAGS=/v /Tpe /L$(WXLIBDIR);$(BCCDIR)\lib
+OPT = -Od
+DEBUG_FLAGS= -v
+!else
+LINKFLAGS=/Tpe /L$(WXLIBDIR);$(BCCDIR)\lib
+OPT = -Od
+DEBUG_FLAGS =
+!endif
+CPPFLAGS=$(DEBUG_FLAGS) $(OPT) @$(CFG)
+
+OBJECTS = layout.obj
+
+$(TARGET).exe:	$(OBJECTS) $(TARGET).def $(TARGET).res
+  tlink32 $(LINKFLAGS) @&&!
+c0w32.obj $(OBJECTS)
+$(TARGET)
+nul
+$(LIBS)
+$(TARGET).def
+!
+        brc32 -K $(TARGET).res
+
+.$(SRCSUFF).obj:
+	bcc32 $(CPPFLAGS) -c {$< }
+
+.c.obj:
+	bcc32 $(CPPFLAGS) -P- -c {$< }
+
+layout.obj:      layout.$(SRCSUFF) layout.h
+
+$(TARGET).res :      $(TARGET).rc $(WXDIR)\include\wx\msw\wx.rc
+    brc32 -r /i$(BCCDIR)\include /i$(WXDIR)\include $(TARGET)
+
+clean:
+        -erase *.obj
+        -erase *.exe
+        -erase *.res
+        -erase *.map
+        -erase *.rws
+
diff --git a/samples/layout/makefile.bcc b/samples/layout/makefile.bcc
new file mode 100644
index 0000000000..1538f447dd
--- /dev/null
+++ b/samples/layout/makefile.bcc
@@ -0,0 +1,76 @@
+#
+# File:		makefile.bcc
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds layout example (DOS).
+
+!if "$(BCCDIR)" == ""
+!error You must define the BCCDIR variable in autoexec.bat, e.g. BCCDIR=d:\bc4
+!endif
+
+!if "$(WXWIN)" == ""
+!error You must define the WXWIN variable in autoexec.bat, e.g. WXWIN=c:\wx
+!endif
+
+WXDIR = $(WXWIN)
+!include $(WXDIR)\src\makebcc.env
+
+THISDIR = $(WXDIR)\samples\layout
+WXLIB = $(WXDIR)\lib\wx.lib
+
+LIBS=$(WXLIB) mathwl cwl import
+INC=-I$(WXDIR)\include\base -I$(WXDIR)\include\msw
+CFG=$(WXDIR)\src\wxwin.cfg
+
+!ifndef FINAL
+FINAL=0
+!endif
+
+!if "$(FINAL)" == "0"
+LINKFLAGS=/v/Vt /Twe /L$(WXDIR)\lib;$(BCCDIR)\lib
+OPT = -Od
+DEBUG_FLAGS= -v
+!else
+LINKFLAGS=/Twe /L$(WXDIR)\lib;$(BCCDIR)\lib
+OPT = -O2
+DEBUG_FLAGS =
+!endif
+CPPFLAGS=$(DEBUG_FLAGS) $(OPT) @$(CFG)
+
+HEADERS = layout.h
+SOURCES = layout.$(SRCSUFF)
+OBJECTS = layout.obj
+
+layout:    layout.exe
+
+all:    layout.exe
+
+layout.exe:      $(WXLIB) layout.obj layout.def layout.res
+        tlink $(LINKFLAGS) @&&!
+c0wl.obj layout.obj
+layout
+nul
+$(LIBS)
+layout.def
+!
+        rc -30 -K layout.res
+
+.$(SRCSUFF).obj:
+	bcc $(CPPFLAGS) -c {$< }
+
+layout.obj:      layout.$(SRCSUFF)
+
+layout.res :      layout.rc $(WXDIR)\include\msw\wx.rc
+    rc -r /i$(BCCDIR)\include /i$(WXDIR)\include\msw /i$(WXDIR)\contrib\fafa layout
+
+clean:
+        -erase *.obj
+        -erase *.exe
+        -erase *.res
+        -erase *.map
+        -erase *.rws
diff --git a/samples/layout/makefile.dos b/samples/layout/makefile.dos
new file mode 100644
index 0000000000..8ecd7c5608
--- /dev/null
+++ b/samples/layout/makefile.dos
@@ -0,0 +1,85 @@
+#
+# File:		makefile.dos
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds layout example (DOS).
+# Use FINAL=1 argument to nmake to build final version with no debugging
+# info.
+
+# Set WXDIR for your system
+WXDIR = $(WXWIN)
+
+!include $(WXDIR)\src\makemsc.env
+
+THISDIR = $(WXDIR)\samples\layout
+WXLIB = $(WXDIR)\lib\wx.lib
+LIBS=$(WXLIB) oldnames libw llibcew commdlg ddeml shell mmsystem
+INC=-I$(WXDIR)\include\base -I$(WXDIR)\include\msw
+DUMMY=$(WXDIR)\src\msw\dummy.obj
+
+# Set this to nothing if using MS C++ 7
+ZOPTION=/Z7
+
+!ifndef FINAL
+FINAL=0
+!endif
+
+!if "$(FINAL)" == "0"
+CPPFLAGS=/AL /W3 /Zi $(ZOPTION) /G2sw /Od $(INC) /YuWX_PREC.H /Dwx_msw /Fp$(WXDIR)\src\msw\wx.pch
+LINKFLAGS=/NOD /CO /ONERROR:NOEXE /SEG:512
+!else
+CPPFLAGS=/AL /W3 /G2sw $(INC) /Ox /YuWX_PREC.H /Dwx_msw /Fp$(WXDIR)\src\msw\wx.pch
+LINKFLAGS=/NOD /ONERROR:NOEXE /SEG:512
+!endif
+
+HEADERS = layout.h
+SOURCES = layout.$(SRCSUFF)
+OBJECTS = layout.obj
+
+layout:    layout.exe
+
+all:    wx layout.exe
+
+wx:
+        cd $(WXDIR)\src\msw
+        nmake -f makefile.dos FINAL=$(FINAL)
+        cd $(THISDIR)
+
+wxclean:
+        cd $(WXDIR)\src\msw
+        nmake -f makefile.dos clean
+        cd $(THISDIR)
+
+
+layout.exe:      $(DUMMY) $(WXLIB) layout.obj layout.def layout.res
+        link $(LINKFLAGS) @<<
+$(DUMMY) layout.obj,
+layout,
+NUL,
+$(LIBS),
+layout.def
+;
+<<
+        rc -31 -K layout.res
+
+layout.obj:      layout.h layout.$(SRCSUFF) $(DUMMY)
+        cl @<<
+$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
+<<
+
+layout.res :      layout.rc $(WXDIR)\include\msw\wx.rc
+    rc -r /i$(WXDIR)\include\msw /i$(WXDIR)\contrib\fafa layout
+
+clean:
+        -erase *.obj
+        -erase *.exe
+        -erase *.res
+        -erase *.map
+        -erase *.sbr
+        -erase *.pdb
+
diff --git a/samples/layout/makefile.g95 b/samples/layout/makefile.g95
new file mode 100644
index 0000000000..df9f97e246
--- /dev/null
+++ b/samples/layout/makefile.g95
@@ -0,0 +1,35 @@
+#
+# File:		makefile.unx
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile for layout example (UNIX).
+
+WXDIR = ../..
+
+# All common UNIX compiler flags and options are now in
+# this central makefile.
+include $(WXDIR)/src/makeg95.env
+
+OBJECTS=$(OBJDIR)/layout.$(OBJSUFF) $(OBJDIR)/layout_resources.o
+
+all:	$(OBJDIR) layout.exe
+
+$(OBJDIR):
+	mkdir $(OBJDIR)
+
+layout.exe: $(OBJECTS) $(WXLIB)
+	$(CC) $(LDFLAGS) -o layout$(GUISUFFIX)$(EXESUFF) $(OBJECTS) $(LDLIBS)
+
+$(OBJDIR)/layout.$(OBJSUFF):        layout.$(SRCSUFF) layout.h
+	$(CC) -c $(CPPFLAGS) -o $@ layout.$(SRCSUFF)
+
+$(OBJDIR)/layout_resources.o:  layout.rc
+	$(RESCOMP) -i layout.rc -o $(OBJDIR)/layout_resources.o $(RESFLAGS)
+
+clean:
+	rm -f $(OBJECTS) layout$(GUISUFFIX).exe core *.res *.rsc
diff --git a/samples/layout/makefile.nt b/samples/layout/makefile.nt
new file mode 100644
index 0000000000..03d63b800b
--- /dev/null
+++ b/samples/layout/makefile.nt
@@ -0,0 +1,63 @@
+#
+# File:		makefile.nt
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds layout example (MS VC++).
+# Use FINAL=1 argument to nmake to build final version with no debugging
+# info
+
+# Set WXDIR for your system
+WXDIR = $(WXWIN)
+
+!include $(WXDIR)\src\ntwxwin.mak
+
+THISDIR = $(WXDIR)\samples\layout
+PROGRAM=layout
+ 
+OBJECTS = $(PROGRAM).obj
+
+$(PROGRAM):    $(PROGRAM).exe
+
+all:    wx $(PROGRAM).exe
+
+wx:
+        cd $(WXDIR)\src\msw
+        nmake -f makefile.nt FINAL=$(FINAL)
+        cd $(THISDIR)
+
+wxclean:
+        cd $(WXDIR)\src\msw
+        nmake -f makefile.nt clean
+        cd $(THISDIR)
+
+$(PROGRAM).exe:      $(DUMMYOBJ) $(WXLIB) $(OBJECTS) $(PROGRAM).res
+	$(link) @<<
+-out:$(PROGRAM).exe
+$(LINKFLAGS)
+$(DUMMYOBJ) $(OBJECTS) $(PROGRAM).res
+$(LIBS)
+<<
+
+
+$(PROGRAM).obj:      $(PROGRAM).h $(PROGRAM).$(SRCSUFF) $(DUMMYOBJ)
+        $(cc) @<<
+$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
+<<
+
+$(PROGRAM).res :      $(PROGRAM).rc $(WXDIR)\include\wx\msw\wx.rc
+    $(rc) -r /i$(WXDIR)\include -fo$@ $(PROGRAM).rc
+
+
+clean:
+        -erase *.obj
+        -erase *.sbr
+        -erase *.exe
+        -erase *.res
+        -erase *.map
+        -erase *.pdb
+
diff --git a/samples/layout/makefile.sc b/samples/layout/makefile.sc
new file mode 100644
index 0000000000..0b28430453
--- /dev/null
+++ b/samples/layout/makefile.sc
@@ -0,0 +1,37 @@
+# Symantec C++ makefile for layout example
+# NOTE that peripheral libraries are now dealt in main wxWindows makefile.
+
+WXDIR = $(WXWIN)
+!include $(WXDIR)\src\makesc.env
+
+WXLIB = $(WXDIR)\lib\wx.lib
+INCDIR = $(WXDIR)\include
+MSWINC = $(INCDIR)\msw
+BASEINC = $(INCDIR)\base
+
+CC=sc
+RC=rc
+CFLAGS = -o -ml -W -Dwx_msw
+LDFLAGS = -ml -W
+
+INCLUDE=$(BASEINC);$(MSWINC)
+
+LIBS=$(WXLIB) libw.lib commdlg.lib shell.lib
+
+.$(SRCSUFF).obj:
+	*$(CC) -c $(CFLAGS) -I$(INCLUDE) $<
+
+.rc.res:
+	*$(RC) -r -I$(INCLUDE) $<
+
+layout.exe: layout.obj layout.def layout.res
+	*$(CC) $(LDFLAGS) -o$@ layout.obj layout.def $(LIBS)
+        *$(RC) -k layout.res
+
+clean:
+        -del *.obj
+	-del *.exe
+	-del *.res
+	-del *.map
+	-del *.rws
+
diff --git a/samples/layout/makefile.unx b/samples/layout/makefile.unx
new file mode 100644
index 0000000000..3f9aad0ac2
--- /dev/null
+++ b/samples/layout/makefile.unx
@@ -0,0 +1,76 @@
+#
+# File:		makefile.unx
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile for layout example (UNIX).
+
+WXDIR = ../..
+
+# All common UNIX compiler flags and options are now in
+# this central makefile.
+include $(WXDIR)/src/make.env
+
+OBJECTS=$(OBJDIR)/layout.$(OBJSUFF)
+
+.SUFFIXES:
+
+all:	$(OBJDIR) layout$(GUISUFFIX)
+
+wxmotif:
+	cd $(WXDIR)/src/x; $(MAKE) -f makefile.unx motif
+
+wxxview:
+	cd $(WXDIR)/src/x; $(MAKE) -f makefile.unx xview
+
+wxhp:
+	cd $(WXDIR)/src/x; $(MAKE) -f makefile.unx hp
+
+# For SGI, include -lPW on your LDLIBS
+motif:	wxmotif
+	$(MAKE) -f makefile.unx all GUISUFFIX=_motif GUI=-Dwx_motif GUISUFFIX=_motif OPT='$(OPT)' LDLIBS='$(MOTIFLDLIBS)' WXLIB=$(WXDIR)/lib/libwx_motif.a OPTIONS='$(OPTIONS)' DEBUG='$(DEBUG)' WARN='$(WARN)' XLIB='$(XLIB)' XINCLUDE='$(XINCLUDE)' XVIEW_LINK=
+
+xview:	wxxview
+	$(MAKE) -f makefile.unx GUI=-Dwx_xview GUISUFFIX=_ol CC=$(CC) OPTIONS='$(OPTIONS)' DEBUG='$(DEBUG)' WARN='$(WARN)' XLIB='$(XLIB)' XINCLUDE='$(XINCLUDE)' LDLIBS='$(XVIEWLDLIBS)'
+
+hp:	wxhp
+	$(MAKE) -f makefile.unx GUI=-Dwx_motif GUISUFFIX=_hp CC=CC OPT='' DEBUG='$(DEBUG)' WARN='-w' \
+           XINCLUDE='$(HPXINCLUDE)' \
+           XLIB='$(HPXLIB)' \
+           XVIEW_LINK='' \
+           LDLIBS='$(HPLDLIBS)'
+
+$(OBJDIR):
+	mkdir $(OBJDIR)
+
+layout$(GUISUFFIX): $(OBJDIR)/layout.$(OBJSUFF) $(WXLIB)
+	$(CC) $(LDFLAGS) -o layout$(GUISUFFIX) $(OBJDIR)/layout.$(OBJSUFF) $(XVIEW_LINK) $(LDLIBS)
+
+$(OBJDIR)/layout.$(OBJSUFF):        layout.$(SRCSUFF) layout.h
+	$(CC) -c $(CPPFLAGS) -o $@ layout.$(SRCSUFF)
+
+clean_motif:
+	$(MAKE) -f makefile.unx GUISUFFIX=_motif cleanany
+
+clean_ol:
+	$(MAKE) -f makefile.unx GUISUFFIX=_ol cleanany
+
+clean_hp:
+	$(MAKE) -f makefile.unx GUISUFFIX=_hp cleanany
+
+cleanany:
+	rm -f $(OBJECTS) layout$(GUISUFFIX) core
+
+wxclean_ol:
+	cd $(WXDIR)/src/x; $(MAKE) -f makefile.unx clean_ol
+
+wxclean_motif:
+	cd $(WXDIR)/src/x; $(MAKE) -f makefile.unx clean_motif
+
+wxclean_hp:
+	cd $(WXDIR)/src/x; $(MAKE) -f makefile.unx clean_hp
+
diff --git a/samples/layout/makefile.vms b/samples/layout/makefile.vms
new file mode 100644
index 0000000000..f47d52031b
--- /dev/null
+++ b/samples/layout/makefile.vms
@@ -0,0 +1,41 @@
+#************************************************************************
+# Makefile for LAYOUT under VMS
+# by Stefan Hammes
+# (incomplete) update history:
+# 14.05.95
+#************************************************************************
+
+#************************************************************************
+# Definition section
+# (cave: definitions and includes must begin with ',')
+#************************************************************************
+
+APPOPTS = 
+APPDEFS = 
+APPINCS = 
+
+#************************************************************************
+# Module section
+#************************************************************************
+
+# Name of main module
+MAIN = layout
+
+# Object modules of the application.
+OBJS = layout.obj
+OBJLIST =layout.obj
+
+.include [--.src]makevms.env
+
+# main dependency
+$(MAIN).exe : $(OBJS)
+    $(LINK) $(LINKFLAGS) /exec=$(MAIN).exe $(OBJLIST),$(WXLIB)/lib,$(OPTSFILE)/option
+    - purge *.exe
+
+#************************************************************************
+# Header file depedencies following
+#************************************************************************
+
+layout.obj : layout.cc layout.h
+
+
diff --git a/samples/layout/makefile.wat b/samples/layout/makefile.wat
new file mode 100644
index 0000000000..5c55c4d9c0
--- /dev/null
+++ b/samples/layout/makefile.wat
@@ -0,0 +1,44 @@
+#
+# Makefile for WATCOM
+#
+# Created by D.Chubraev, chubraev@iem.ee.ethz.ch
+# 8 Nov 1994
+#
+
+WXDIR = ..\.. 
+
+!include $(WXDIR)\src\makewat.env
+
+WXLIB = $(WXDIR)\lib
+NAME = layout
+LNK = $(name).lnk
+OBJS = $(name).obj
+
+all:    $(name).exe
+
+$(name).exe : $(OBJS) $(name).res $(LNK) $(WXLIB)\wx$(LEVEL).lib
+    wlink @$(LNK)
+    $(BINDCOMMAND) $(name).res
+
+$(name).res :      $(name).rc $(WXDIR)\include\msw\wx.rc
+     $(RC) $(RESFLAGS1) $(name).rc
+
+$(LNK) : makefile.wat
+    %create $(LNK)
+    @%append $(LNK) debug all
+    @%append $(LNK) system $(LINKOPTION)
+    @%append $(LNK) $(MINDATA)
+    @%append $(LNK) $(MAXDATA)
+    @%append $(LNK) $(STACK)
+    @%append $(LNK) name $(name)
+    @%append $(LNK) file $(WXLIB)\wx$(LEVEL).lib
+    @for %i in ($(EXTRALIBS)) do @%append $(LNK) file %i
+    @for %i in ($(OBJS)) do @%append $(LNK) file %i
+
+thing: .SYMBOLIC
+    echo $(WATLIBDIR)
+
+clean:   .SYMBOLIC
+    -erase *.obj *.bak *.err *.pch *.lib *.lnk *.res *.exe *.rex
+
+
diff --git a/samples/mdi/Makefile b/samples/mdi/Makefile
new file mode 100644
index 0000000000..027d82ae19
--- /dev/null
+++ b/samples/mdi/Makefile
@@ -0,0 +1 @@
+include ../../src/gtk/setup/general/makeapp
diff --git a/samples/mdi/Makefile.in b/samples/mdi/Makefile.in
new file mode 100644
index 0000000000..d7dab468aa
--- /dev/null
+++ b/samples/mdi/Makefile.in
@@ -0,0 +1,26 @@
+# WXXT base directory
+WXBASEDIR=@WXBASEDIR@
+
+# set the OS type for compilation
+OS=@OS@
+# compile a library only
+RULE=bin
+
+# define library name
+BIN_TARGET=test
+# define library sources
+BIN_SRC=\
+mdi.cpp
+
+#define library objects
+BIN_OBJ=\
+mdi.o
+
+# additional things needed to link
+BIN_LINK=
+
+# additional things needed to compile
+ADD_COMPILE=
+
+# include the definitions now
+include ../../../template.mak
diff --git a/samples/mdi/aiai.ico b/samples/mdi/aiai.ico
new file mode 100644
index 0000000000000000000000000000000000000000..a3db6563cc0b9f4588e1e994fe54b90a3cb1d6c1
GIT binary patch
literal 766
zcmc(bJ930T3`Bcft}@v=+L+MC@X_W5#I6lE$3$=(hlEfB<Ja@?LOIyb0!^!t)JP*;
zc>4Zbw(l3|27cf@{)u1o%88L{R;n8d60briz)7fio<S#4ewC6VoX4NcpV>a{V~VK)
z)$t4e1%j>c0*T7ZEBuvb0Ndch+2BCx7U^mZHa?iIh11ZPGV>8*oPzc{HmcjEM7U^(
z*rd)gSRm_`KJo;dxt={X3#3|q&kYE;ul$En1WJC3UOX%3ev8=<z}j41;VP{UzUs~U
s)wx~DuB_~?Y=Qe|v5`BV=<&%~$Nt1hCmx0~Ul2L;AGObMz1)9;A6NK_vj6}9

literal 0
HcmV?d00001

diff --git a/samples/mdi/aiai.xbm b/samples/mdi/aiai.xbm
new file mode 100644
index 0000000000..1a6f0a31b1
--- /dev/null
+++ b/samples/mdi/aiai.xbm
@@ -0,0 +1,38 @@
+#define aiai_width 64
+#define aiai_height 64
+static char aiai_bits[] = {
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x44,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x44,0x44,0x44,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x44,0x44,0x44,0x42,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x47,0x44,0x44,0x44,0x44,0x11,0x11,0x11,0x17,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x91,0x1f,0x11,0x11,0x11,0x11,0x44,0x44,0xc4,0x4f,0x44,0x44,0x44,0x44,
+ 0x44,0x44,0xc4,0x5f,0x44,0xf4,0x45,0x44,0x11,0x11,0xf1,0x1f,0x11,0xf9,0x13,
+ 0x11,0x11,0x11,0xf1,0x3f,0x11,0xfd,0x13,0x11,0x44,0x44,0xf4,0x7f,0x44,0xfc,
+ 0x47,0x44,0x44,0x44,0xf4,0x7f,0x44,0xfc,0x47,0x44,0x11,0x11,0xf9,0x7f,0x11,
+ 0xf9,0x13,0x11,0x11,0x11,0xfd,0xff,0x11,0xf1,0x11,0x11,0x44,0x44,0xfc,0xff,
+ 0x44,0x44,0x44,0x44,0x44,0x44,0xfe,0xff,0x45,0x44,0x44,0x44,0x11,0x11,0xff,
+ 0xff,0x11,0xfd,0x13,0x11,0x11,0x11,0xff,0xff,0x13,0xfd,0x13,0x11,0x44,0xc4,
+ 0xff,0xff,0x07,0xfc,0x43,0x44,0x44,0xff,0xff,0xf9,0xff,0xfd,0xfb,0xff,0x11,
+ 0xc0,0xff,0x00,0x00,0xfc,0x03,0x00,0x11,0xc0,0x7f,0x00,0x00,0xfc,0x03,0x00,
+ 0x04,0xe0,0x7f,0x00,0x00,0xfc,0x03,0x00,0xf4,0xf7,0xbf,0xff,0xff,0xfd,0xfb,
+ 0x7f,0x01,0xf0,0x1f,0x00,0x00,0xfc,0x03,0x00,0x01,0xf8,0x1f,0x00,0x00,0xfc,
+ 0x03,0x00,0x00,0xfc,0x0f,0x00,0x00,0xfc,0x03,0x40,0xfe,0xfd,0xef,0xff,0xff,
+ 0xfd,0xfb,0x4f,0x00,0xfe,0x07,0x00,0x00,0xfc,0x03,0x10,0x00,0xfe,0x03,0x00,
+ 0x00,0xfc,0x03,0x10,0x00,0xff,0x03,0x00,0x00,0xfc,0x03,0x44,0x7f,0xff,0x01,
+ 0x00,0x00,0xfc,0xfb,0x44,0x91,0xff,0xff,0xff,0xff,0xff,0x13,0x11,0xd1,0xff,
+ 0xff,0xff,0xff,0xff,0x13,0x11,0xe4,0xff,0xff,0xff,0xff,0xff,0x47,0x44,0xe4,
+ 0xff,0xff,0xff,0xff,0xff,0x47,0x44,0xf1,0xff,0xff,0xff,0xff,0xff,0x13,0x11,
+ 0xf1,0xff,0xff,0xff,0xff,0xff,0x13,0x11,0xfc,0xff,0xff,0xff,0xff,0xff,0x47,
+ 0x44,0xfc,0xff,0xff,0xff,0xff,0xff,0x47,0x44,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x11,0x44,0x44,0xc4,0x44,0x44,
+ 0xc4,0x44,0x44,0x44,0x4e,0xc4,0x44,0x4e,0xc4,0x44,0x44,0x11,0x1f,0xd1,0x11,
+ 0x1f,0xd1,0x11,0x11,0x91,0x31,0xd1,0x91,0x31,0xd1,0x11,0x11,0xc4,0x64,0xcc,
+ 0xcc,0x64,0xcc,0x44,0x44,0x64,0xc4,0xcc,0x6c,0xc4,0xcc,0x44,0x44,0xf1,0xff,
+ 0xd1,0xf1,0xff,0xd1,0x11,0x11,0xf9,0xff,0xd3,0xf9,0xff,0xd3,0x11,0x11,0x4c,
+ 0x44,0xc6,0x4c,0x44,0xc6,0x44,0x44,0x4c,0x44,0xc6,0x4c,0x44,0xc6,0x44,0x44,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x44};
diff --git a/samples/mdi/chart.ico b/samples/mdi/chart.ico
new file mode 100644
index 0000000000000000000000000000000000000000..16d4a585fd3246e7a8dc43c45e010c006e643dd6
GIT binary patch
literal 766
zcmc&wF%H5o40I7AQkYn&nArFNzsi_=qf@@p2UOx4jHOFdsgk)%D>cxHj+|r1*R$Ou
zA_c50k3u|mA}8!ucnQD53)v%zcxdbJ5TSTKZiq<XUh2ArplOLJGdPT&$QOt<gJWF=
zaFcbkE1dI<Xe+InHGQkUIKN=yPv-tkZ&>7qFu*Pe;O)q})Br9M@2fs2xG_OluNwM{
zcSECEB^`=VZ-!Clq`-NP$D|`q^P8EoNK<|GI(*Wt>lv#s7a1^aS#Q-v=NLJDsYfc-
TMvJ?z=wHXdA%Ehd{14;}SbUVL

literal 0
HcmV?d00001

diff --git a/samples/mdi/makefile.b32 b/samples/mdi/makefile.b32
new file mode 100644
index 0000000000..85fad37374
--- /dev/null
+++ b/samples/mdi/makefile.b32
@@ -0,0 +1,64 @@
+#
+# File:		makefile.b32
+# Author:	Patrick Halke
+# Created:	1995
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds 32bit MDI example.
+
+# WXWIN and BCCDIR are set by parent make
+
+WXDIR = $(WXWIN)
+!include $(WXDIR)\src\makeb32.env
+
+WXLIBDIR = $(WXDIR)\lib
+WXLIB = $(WXLIBDIR)\wx32.lib
+LIBS=$(WXLIB) cw32 import32
+
+TARGET=mdi
+
+!if "$(FINAL)" == "0"
+LINKFLAGS=/v /Tpe /L$(WXLIBDIR);$(BCCDIR)\lib
+OPT = -Od
+DEBUG_FLAGS= -v
+!else
+LINKFLAGS=/Tpe /L$(WXLIBDIR);$(BCCDIR)\lib
+OPT = -Od
+DEBUG_FLAGS =
+!endif
+CPPFLAGS=$(DEBUG_FLAGS) $(OPT) @$(CFG)
+
+OBJECTS = mdi.obj
+
+$(TARGET).exe:	$(OBJECTS) $(TARGET).def $(TARGET).res
+  tlink32 $(LINKFLAGS) @&&!
+c0w32.obj $(OBJECTS)
+$(TARGET)
+nul
+$(LIBS)
+$(TARGET).def
+!
+        brc32 -K $(TARGET).res
+
+.$(SRCSUFF).obj:
+	bcc32 $(CPPFLAGS) -c {$< }
+
+.c.obj:
+	bcc32 $(CPPFLAGS) -P- -c {$< }
+
+mdi.obj:      mdi.$(SRCSUFF) mdi.h
+
+$(TARGET).res :      $(TARGET).rc $(WXDIR)\include\wx\msw\wx.rc
+    brc32 -r /i$(BCCDIR)\include /i$(WXDIR)\include $(TARGET)
+
+clean:
+        -erase *.obj
+        -erase *.exe
+        -erase *.res
+        -erase *.map
+        -erase *.rws
+
+
diff --git a/samples/mdi/makefile.bcc b/samples/mdi/makefile.bcc
new file mode 100644
index 0000000000..47a053f24b
--- /dev/null
+++ b/samples/mdi/makefile.bcc
@@ -0,0 +1,75 @@
+#
+# File:		makefile.bcc
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds mdi example (DOS).
+
+!if "$(BCCDIR)" == ""
+!error You must define the BCCDIR variable in autoexec.bat, e.g. BCCDIR=d:\bc4
+!endif
+
+!if "$(WXWIN)" == ""
+!error You must define the WXWIN variable in autoexec.bat, e.g. WXWIN=c:\wx
+!endif
+
+!ifndef FINAL
+FINAL=0
+!endif
+
+WXDIR = $(WXWIN)
+!include $(WXDIR)\src\makebcc.env
+
+THISDIR = $(WXDIR)\samples\mdi
+WXLIB = $(WXDIR)\lib\wx.lib
+LIBS=$(WXLIB) mathwl cwl import
+INC=-I$(WXDIR)\include\base -I$(WXDIR)\include\msw
+CFG=$(WXDIR)\src\wxwin.cfg
+
+!if "$(FINAL)" == "0"
+LINKFLAGS=/v/Vt /Twe /L$(WXDIR)\lib;$(BCCDIR)\lib
+OPT = -Od
+DEBUG_FLAGS= -v
+!else
+LINKFLAGS=/Twe /L$(WXDIR)\lib;$(BCCDIR)\lib
+OPT = -O2
+DEBUG_FLAGS =
+!endif
+CPPFLAGS=$(DEBUG_FLAGS) $(OPT) @$(CFG)
+
+HEADERS = mdi.h
+SOURCES = mdi.$(SRCSUFF)
+OBJECTS = mdi.obj
+
+mdi:    mdi.exe
+
+all:    mdi.exe
+
+mdi.exe:      $(WXLIB) mdi.obj mdi.def mdi.res
+        tlink $(LINKFLAGS) @&&!
+c0wl.obj mdi.obj
+mdi
+nul
+$(LIBS)
+mdi.def
+!
+        rc -30 -K mdi.res
+
+.$(SRCSUFF).obj:
+	bcc $(CPPFLAGS) -c {$< }
+
+mdi.obj:      mdi.$(SRCSUFF)
+
+mdi.res :      mdi.rc $(WXDIR)\include\msw\wx.rc
+    rc -r /i$(BCCDIR)\include /i$(WXDIR)\include\msw /i$(WXDIR)\contrib\fafa mdi
+
+clean:
+        -erase *.obj
+        -erase *.exe
+        -erase *.res
+        -erase *.map
+        -erase *.rws
diff --git a/samples/mdi/makefile.dos b/samples/mdi/makefile.dos
new file mode 100644
index 0000000000..ee2b9154b3
--- /dev/null
+++ b/samples/mdi/makefile.dos
@@ -0,0 +1,63 @@
+#
+# File:		makefile.dos
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds mdi example (DOS).
+# Use FINAL=1 argument to nmake to build final version with no debugging
+# info
+
+WXDIR = $(WXWIN)
+
+!include $(WXDIR)\src\makemsc.env
+
+THISDIR = $(WXDIR)\samples\mdi
+INC=/I$(WXDIR)\include
+
+HEADERS = mdi.h
+SOURCES = mdi.$(SRCSUFF)
+OBJECTS = mdi.obj
+
+all:    mdi.exe
+
+wx:
+        cd $(WXDIR)\src\msw
+        nmake -f makefile.dos
+        cd $(THISDIR)
+
+wxclean:
+        cd $(WXDIR)\src\msw
+        nmake -f makefile.dos clean
+        cd $(THISDIR)
+
+
+mdi.exe:      $(WXDIR)\src\msw\dummy.obj $(WXLIB) mdi.obj mdi.def mdi.res
+        link $(LINKFLAGS) @<<
+$(WXDIR)\src\msw\dummy.obj mdi.obj,
+mdi,
+NUL,
+$(LIBS),
+mdi.def
+;
+<<
+        rc -K mdi.res
+
+mdi.obj:      mdi.h mdi.$(SRCSUFF)
+        cl @<<
+$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
+<<
+
+mdi.res :      mdi.rc $(WXDIR)\include\wx\msw\wx.rc
+    rc -r /i$(WXDIR)\include mdi
+
+clean:
+        -erase *.obj
+        -erase *.exe
+        -erase *.res
+        -erase *.map
+        -erase *.sbr
+        -erase *.pdb
diff --git a/samples/mdi/makefile.g95 b/samples/mdi/makefile.g95
new file mode 100644
index 0000000000..045751ea89
--- /dev/null
+++ b/samples/mdi/makefile.g95
@@ -0,0 +1,35 @@
+#
+# File:		makefile.unx
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile for mdi example (UNIX).
+
+WXDIR = ../..
+
+# All common UNIX compiler flags and options are now in
+# this central makefile.
+include $(WXDIR)/src/makeg95.env
+
+OBJECTS = $(OBJDIR)/mdi.$(OBJSUFF) $(OBJDIR)/mdi_resources.$(OBJSUFF)
+
+all:    $(OBJDIR) mdi.exe
+
+$(OBJDIR):
+	mkdir $(OBJDIR)
+
+mdi.exe: $(OBJECTS) $(WXLIB)
+	$(CC) $(LDFLAGS) -o mdi.exe $(OBJECTS) $(LDLIBS)
+
+$(OBJDIR)/mdi.$(OBJSUFF):        mdi.$(SRCSUFF) mdi.h
+	$(CC) -c $(CPPFLAGS) -o $@ mdi.$(SRCSUFF)
+
+$(OBJDIR)/mdi_resources.o:  mdi.rc
+	$(RESCOMP) -i mdi.rc -o $(OBJDIR)/mdi_resources.o $(RESFLAGS)
+
+clean:
+	rm -f $(OBJECTS) mdi$(GUISUFFIX).exe core *.res *.rsc
diff --git a/samples/mdi/makefile.nt b/samples/mdi/makefile.nt
new file mode 100644
index 0000000000..c79a4f8d78
--- /dev/null
+++ b/samples/mdi/makefile.nt
@@ -0,0 +1,63 @@
+#
+# File:		makefile.nt
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds mdi example (MS VC++).
+# Use FINAL=1 argument to nmake to build final version with no debugging
+# info
+
+# Set WXDIR for your system
+WXDIR = $(WXWIN)
+WXUSINGDLL=0
+
+!include $(WXDIR)\src\ntwxwin.mak
+
+THISDIR = $(WXDIR)\samples\mdi
+PROGRAM=mdi
+
+OBJECTS = $(PROGRAM).obj
+
+$(PROGRAM):    $(PROGRAM).exe
+
+all:    wx $(PROGRAM).exe
+
+wx:
+        cd $(WXDIR)\src\msw
+        nmake -f makefile.nt FINAL=$(FINAL)
+        cd $(THISDIR)
+
+wxclean:
+        cd $(WXDIR)\src\msw
+        nmake -f makefile.nt clean
+        cd $(THISDIR)
+
+$(PROGRAM).exe:      $(DUMMYOBJ) $(WXLIB) $(OBJECTS) $(PROGRAM).res
+	$(link) @<<
+-out:$(PROGRAM).exe
+$(LINKFLAGS)
+$(DUMMYOBJ) $(OBJECTS) $(PROGRAM).res
+$(LIBS)
+<<
+
+
+$(PROGRAM).obj:      $(PROGRAM).$(SRCSUFF) $(DUMMYOBJ)
+        $(cc) @<<
+$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
+<<
+
+$(PROGRAM).res :      $(PROGRAM).rc $(WXDIR)\include\wx\msw\wx.rc
+    $(rc) -r /i$(WXDIR)\include -fo$@ $(PROGRAM).rc
+
+
+clean:
+        -erase *.obj
+        -erase *.exe
+        -erase *.res
+        -erase *.map
+        -erase *.sbr
+        -erase *.pdb
diff --git a/samples/mdi/makefile.sc b/samples/mdi/makefile.sc
new file mode 100644
index 0000000000..a90487946a
--- /dev/null
+++ b/samples/mdi/makefile.sc
@@ -0,0 +1,36 @@
+# Symantec C++ makefile for mdi example
+# NOTE that peripheral libraries are now dealt in main wxWindows makefile.
+
+WXDIR = $(WXWIN)
+!include $(WXDIR)\src\makesc.env
+
+WXLIB = $(WXDIR)\lib\wx.lib
+INCDIR = $(WXDIR)\include
+MSWINC = $(INCDIR)\msw
+BASEINC = $(INCDIR)\base
+
+CC=sc
+RC=rc
+CFLAGS = -o -ml -W -Dwx_msw
+LDFLAGS = -ml -W
+
+INCLUDE=$(BASEINC);$(MSWINC)
+
+LIBS=$(WXLIB) libw.lib commdlg.lib shell.lib
+
+.$(SRCSUFF).obj:
+	*$(CC) -c $(CFLAGS) -I$(INCLUDE) $<
+
+.rc.res:
+	*$(RC) -r -I$(INCLUDE) $<
+
+mdi.exe: mdi.obj mdi.def mdi.res
+	*$(CC) $(LDFLAGS) -o$@ mdi.obj mdi.def $(LIBS)
+	*$(RC) -k mdi.res
+
+clean:
+        -del *.obj
+	-del *.exe
+	-del *.res
+	-del *.map
+	-del *.rws
diff --git a/samples/mdi/makefile.unx b/samples/mdi/makefile.unx
new file mode 100644
index 0000000000..24b30ac061
--- /dev/null
+++ b/samples/mdi/makefile.unx
@@ -0,0 +1,55 @@
+#
+# File:		makefile.unx
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile for mdi example (UNIX).
+
+WXDIR = ../..
+
+# All common UNIX compiler flags and options are now in
+# this central makefile.
+include $(WXDIR)/src/make.env
+
+OBJECTS = $(OBJDIR)/mdi.$(OBJSUFF)
+
+.SUFFIXES:
+
+all:    $(OBJDIR) mdi$(GUISUFFIX)
+
+wx:
+#	cd $(WXDIR)/src/x; $(MAKE) -f makefile.unx
+motif:
+	$(MAKE) -f makefile.unx GUISUFFIX=_motif GUI=-Dwx_motif GUISUFFIX=_motif OPT='$(OPT)' LDLIBS='$(MOTIFLDLIBS)' OPTIONS='$(OPTIONS)' DEBUG='$(DEBUG)' WARN='$(WARN)' XLIB='$(XLIB)' XINCLUDE='$(XINCLUDE)' XVIEW_LINK=
+
+xview:
+	$(MAKE) -f makefile.unx GUI=-Dwx_xview GUISUFFIX=_ol CC=$(CC) OPTIONS='$(OPTIONS)' DEBUG='$(DEBUG)' WARN='$(WARN)' XLIB='$(XLIB)' XINCLUDE='$(XINCLUDE)'
+
+hp:
+	$(MAKE) -f makefile.unx GUI=-Dwx_motif GUISUFFIX=_hp CC=CC DEBUG='$(DEBUG)' WARN='-w' \
+         XINCLUDE='$(HPXINCLUDE)' XLIB='$(HPXLIB)' XVIEW_LINK='' LDLIBS='$(HPLDLIBS)'
+
+$(OBJDIR):
+	mkdir $(OBJDIR)
+
+mdi$(GUISUFFIX): $(OBJDIR)/mdi.$(OBJSUFF) $(WXLIB)
+	$(CC) $(LDFLAGS) -o mdi$(GUISUFFIX) $(OBJDIR)/mdi.$(OBJSUFF) $(XVIEW_LINK) $(LDLIBS)
+
+$(OBJDIR)/mdi.$(OBJSUFF):        mdi.$(SRCSUFF) mdi.h
+	$(CC) -c $(CPPFLAGS) -o $@ mdi.$(SRCSUFF)
+
+clean_motif:
+	$(MAKE) -f makefile.unx GUISUFFIX=_motif cleanany
+
+clean_ol:
+	$(MAKE) -f makefile.unx GUISUFFIX=_ol cleanany
+
+clean_hp:
+	$(MAKE) -f makefile.unx GUISUFFIX=_hp cleanany
+
+cleanany:
+	rm -f $(OBJECTS) mdi$(GUISUFFIX) core
diff --git a/samples/mdi/makefile.vms b/samples/mdi/makefile.vms
new file mode 100644
index 0000000000..41d193c077
--- /dev/null
+++ b/samples/mdi/makefile.vms
@@ -0,0 +1,38 @@
+#************************************************************************
+# Makefile for MDI under VMS
+# by Stefan Hammes
+# (incomplete) update history:
+# 11.04.95
+#************************************************************************
+
+#************************************************************************
+# Definition section
+# (cave: definitions and includes must begin with ',')
+#************************************************************************
+
+APPOPTS = 
+APPDEFS = 
+APPINCS = 
+
+#************************************************************************
+# Module section
+#************************************************************************
+
+# Name of main module
+MAIN = mdi
+
+# Object modules of the application.
+OBJS = mdi.obj
+OBJLIST =mdi.obj
+
+.include [--.src]makevms.env
+
+# main dependency
+$(MAIN).exe : $(OBJS)
+    $(LINK) $(LINKFLAGS) /exec=$(MAIN).exe $(OBJLIST),$(WXLIB)/lib,$(OPTSFILE)/option
+    - purge *.exe
+
+#************************************************************************
+# Header file depedencies following
+#************************************************************************
+
diff --git a/samples/mdi/makefile.wat b/samples/mdi/makefile.wat
new file mode 100644
index 0000000000..f959acdb52
--- /dev/null
+++ b/samples/mdi/makefile.wat
@@ -0,0 +1,43 @@
+#
+# Makefile for WATCOM
+#
+# Created by D.Chubraev, chubraev@iem.ee.ethz.ch
+# 8 Nov 1994
+#
+
+WXDIR = ..\.. 
+
+!include $(WXDIR)\src\makewat.env
+
+WXLIB = $(WXDIR)\lib
+NAME = mdi
+LNK = $(name).lnk
+OBJS = $(name).obj
+
+all:    $(name).exe
+
+$(name).exe : $(OBJS) $(name).res $(LNK) $(WXLIB)\wx$(LEVEL).lib
+    wlink @$(LNK)
+    $(BINDCOMMAND) $(name).res
+
+$(name).res :      $(name).rc $(WXDIR)\include\msw\wx.rc
+     $(RC) $(RESFLAGS1) $(name).rc
+
+$(LNK) : makefile.wat
+    %create $(LNK)
+    @%append $(LNK) debug all
+    @%append $(LNK) system $(LINKOPTION)
+    @%append $(LNK) $(MINDATA)
+    @%append $(LNK) $(MAXDATA)
+    @%append $(LNK) $(STACK)
+    @%append $(LNK) name $(name)
+    @%append $(LNK) file $(WXLIB)\wx$(LEVEL).lib
+    @for %i in ($(EXTRALIBS)) do @%append $(LNK) file %i
+    @for %i in ($(OBJS)) do @%append $(LNK) file %i
+
+thing: .SYMBOLIC
+    echo $(WATLIBDIR)
+
+clean:   .SYMBOLIC
+    -erase *.obj *.bak *.err *.pch *.lib *.lnk *.res *.exe *.rex
+
diff --git a/samples/mdi/mdi.cpp b/samples/mdi/mdi.cpp
new file mode 100644
index 0000000000..217d943ab0
--- /dev/null
+++ b/samples/mdi/mdi.cpp
@@ -0,0 +1,381 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        mdi.cpp
+// Purpose:     MDI sample
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+// For compilers that support precompilation, includes "wx/wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#include "wx/mdi.h"
+#endif
+
+#ifdef __WINDOWS__
+#include <wx/tbar95.h>
+#endif
+
+#include "mdi.h"
+
+MyFrame *frame = NULL;
+wxList my_children;
+
+IMPLEMENT_APP(MyApp)
+
+// For drawing lines in a canvas
+long xpos = -1;
+long ypos = -1;
+
+int winNumber = 1;
+
+// Initialise this in OnInit, not statically
+bool MyApp::OnInit(void)
+{
+  // Create the main frame window
+
+  frame = new MyFrame(NULL, -1, "MDI Demo", wxPoint(0, 0), wxSize(500, 400),
+   wxDEFAULT_FRAME | wxHSCROLL | wxVSCROLL);
+
+  // Give it an icon (this is ignored in MDI mode: uses resources)
+#ifdef __WINDOWS__
+  frame->SetIcon(wxIcon("mdi_icn"));
+#endif
+#ifdef __X__
+  frame->SetIcon(wxIcon("aiai.xbm"));
+#endif
+
+  // Make a menubar
+  wxMenu *file_menu = new wxMenu;
+
+  file_menu->Append(MDI_NEW_WINDOW, "&New window");
+  file_menu->Append(MDI_QUIT, "&Exit");
+
+  wxMenu *help_menu = new wxMenu;
+  help_menu->Append(MDI_ABOUT, "&About");
+
+  wxMenuBar *menu_bar = new wxMenuBar;
+
+  menu_bar->Append(file_menu, "&File");
+  menu_bar->Append(help_menu, "&Help");
+
+  // Associate the menu bar with the frame
+  frame->SetMenuBar(menu_bar);
+
+  frame->CreateStatusBar();
+
+  frame->Show(TRUE);
+
+  SetTopWindow(frame);
+
+  return TRUE;
+}
+
+BEGIN_EVENT_TABLE(MyFrame, wxMDIParentFrame)
+    EVT_MENU(MDI_QUIT, MyFrame::OnQuit)
+    EVT_MENU(MDI_ABOUT, MyFrame::OnAbout)
+    EVT_MENU(MDI_NEW_WINDOW, MyFrame::OnNewWindow)
+    EVT_SIZE(MyFrame::OnSize)
+END_EVENT_TABLE()
+
+// Define my frame constructor
+MyFrame::MyFrame(wxWindow *parent, const wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size,
+	const long style):
+  wxMDIParentFrame(parent, id, title, pos, size, style)
+{
+    textWindow = new wxTextCtrl(this, -1, "", wxDefaultPosition, wxDefaultSize,
+        wxTE_MULTILINE|wxSUNKEN_BORDER);
+    textWindow->SetValue("A help window");
+
+#ifdef __WINDOWS__
+    toolBar = new TestRibbon(this, 0, 0, 100, 30, wxNO_BORDER, wxVERTICAL, 1);
+    SetToolBar(toolBar);
+#endif
+}
+
+void MyFrame::OnQuit(wxCommandEvent& event)
+{
+      Close(TRUE);
+}
+
+void MyFrame::OnAbout(wxCommandEvent& event)
+{
+      (void)wxMessageBox("wxWindows 2.0 MDI Demo\nAuthor: Julian Smart (c) 1997\nUsage: mdi.exe", "About MDI Demo");
+}
+
+void MyFrame::OnNewWindow(wxCommandEvent& event)
+{
+      // Make another frame, containing a canvas
+      MyChild *subframe = new MyChild(frame, "Canvas Frame", wxPoint(10, 10), wxSize(300, 300),
+                             wxDEFAULT_FRAME);
+
+      char titleBuf[100];
+      sprintf(titleBuf, "Canvas Frame %d", winNumber);
+      subframe->SetTitle(titleBuf);
+      winNumber ++;
+
+      // Give it an icon (this is ignored in MDI mode: uses resources)
+#ifdef __WINDOWS__
+      subframe->SetIcon(wxIcon("chrt_icn"));
+#endif
+#ifdef __X__
+      subframe->SetIcon(wxIcon("aiai.xbm"));
+#endif
+
+      // Give it a status line
+      subframe->CreateStatusBar();
+
+      // Make a menubar
+      wxMenu *file_menu = new wxMenu;
+
+      file_menu->Append(MDI_NEW_WINDOW, "&New window");
+      file_menu->Append(MDI_CHILD_QUIT, "&Close child");
+      file_menu->Append(MDI_QUIT, "&Exit");
+
+      wxMenu *option_menu = new wxMenu;
+
+      // Dummy option
+      option_menu->Append(MDI_REFRESH, "&Refresh picture");
+
+      wxMenu *help_menu = new wxMenu;
+      help_menu->Append(MDI_ABOUT, "&About");
+
+      wxMenuBar *menu_bar = new wxMenuBar;
+
+      menu_bar->Append(file_menu, "&File");
+      menu_bar->Append(option_menu, "&Options");
+      menu_bar->Append(help_menu, "&Help");
+
+      // Associate the menu bar with the frame
+      subframe->SetMenuBar(menu_bar);
+
+      int width, height;
+      subframe->GetClientSize(&width, &height);
+      MyCanvas *canvas = new MyCanvas(subframe, wxPoint(0, 0), wxSize(width, height));
+      canvas->SetCursor(wxCursor(wxCURSOR_PENCIL));
+      subframe->canvas = canvas;
+
+      // Give it scrollbars
+      canvas->SetScrollbars(20, 20, 50, 50);
+
+      subframe->Show(TRUE);
+}
+
+BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
+	EVT_MOUSE_EVENTS(MyCanvas::OnEvent)
+END_EVENT_TABLE()
+
+// Define a constructor for my canvas
+MyCanvas::MyCanvas(wxWindow *parent, const wxPoint& pos, const wxSize& size):
+ wxScrolledWindow(parent, -1, pos, size, wxSUNKEN_BORDER)
+{
+}
+
+// Define the repainting behaviour
+void MyCanvas::OnDraw(wxDC& dc)
+{
+  dc.SetFont(*wxSWISS_FONT);
+  dc.SetPen(*wxGREEN_PEN);
+  dc.DrawLine(0, 0, 200, 200);
+  dc.DrawLine(200, 0, 0, 200);
+
+  dc.SetBrush(*wxCYAN_BRUSH);
+  dc.SetPen(*wxRED_PEN);
+  dc.DrawRectangle(100, 100, 100, 50);
+  dc.DrawRoundedRectangle(150, 150, 100, 50, 20);
+
+  dc.DrawEllipse(250, 250, 100, 50);
+  dc.DrawSpline(50, 200, 50, 100, 200, 10);
+  dc.DrawLine(50, 230, 200, 230);
+  dc.DrawText("This is a test string", 50, 230);
+}
+
+// This implements a tiny doodling program! Drag the mouse using
+// the left button.
+void MyCanvas::OnEvent(wxMouseEvent& event)
+{
+  wxClientDC dc(this);
+  PrepareDC(dc);
+
+  wxPoint pt(event.GetLogicalPosition(dc));
+
+  if (xpos > -1 && ypos > -1 && event.Dragging())
+  {
+    dc.SetPen(*wxBLACK_PEN);
+    dc.DrawLine(xpos, ypos, pt.x, pt.y);
+  }
+  xpos = pt.x;
+  ypos = pt.y;
+}
+
+// Define the behaviour for the frame closing
+// - must delete all frames except for the main one.
+bool MyFrame::OnClose(void)
+{
+  // Must delete children
+  wxNode *node = my_children.First();
+  while (node)
+  {
+    MyChild *child = (MyChild *)node->Data();
+    wxNode *next = node->Next();
+    child->OnClose();
+    delete child;
+    node = next;
+  }
+  return TRUE;
+}
+
+void MyFrame::OnSize(wxSizeEvent& event)
+{
+    int w, h;
+    GetClientSize(&w, &h);
+    int tw = 0;
+    int th = 0;
+    
+#ifdef __WINDOWS__
+    wxWindow* tbar = GetToolBar();
+    if (tbar)
+    {
+        tbar->GetSize(&tw, &th);
+        tbar->SetSize(w, th);
+    }
+#endif
+
+    textWindow->SetSize(0, th, 200, h-th);
+    GetClientWindow()->SetSize(200, th, w - 200, h-th);
+}
+
+// Note that MDI_NEW_WINDOW and MDI_ABOUT commands get passed
+// to the parent window for processing, so no need to
+// duplicate event handlers here.
+
+BEGIN_EVENT_TABLE(MyChild, wxMDIChildFrame)
+  EVT_MENU(MDI_CHILD_QUIT, MyChild::OnQuit)
+END_EVENT_TABLE()
+
+MyChild::MyChild(wxMDIParentFrame *parent, const wxString& title, const wxPoint& pos, const wxSize& size,
+const long style):
+  wxMDIChildFrame(parent, -1, title, pos, size, style)
+{
+  canvas = NULL;
+  my_children.Append(this);
+}
+
+MyChild::~MyChild(void)
+{
+  my_children.DeleteObject(this);
+}
+
+void MyChild::OnQuit(wxCommandEvent& event)
+{
+      Close(TRUE);
+}
+
+void MyChild::OnActivate(wxActivateEvent& event)
+{
+  if (event.GetActive() && canvas)
+    canvas->SetFocus();
+}
+
+bool MyChild::OnClose(void)
+{
+  return TRUE;
+}
+
+#ifdef __WINDOWS__
+
+BEGIN_EVENT_TABLE(TestRibbon, wxToolBar95)
+    EVT_PAINT(TestRibbon::OnPaint)
+END_EVENT_TABLE()
+
+TestRibbon::TestRibbon(wxFrame *frame, int x, int y, int w, int h,
+            long style, int direction, int RowsOrColumns):
+  wxToolBar95(frame, -1, wxPoint(x, y), wxSize(w, h), style, direction, RowsOrColumns)
+{
+    wxBitmap* bitmaps[8];
+
+    bitmaps[0] = new wxBitmap("icon1", wxBITMAP_TYPE_RESOURCE);
+    bitmaps[1] = new wxBitmap("icon2", wxBITMAP_TYPE_RESOURCE);
+    bitmaps[2] = new wxBitmap("icon3", wxBITMAP_TYPE_RESOURCE);
+    bitmaps[3] = new wxBitmap("icon4", wxBITMAP_TYPE_RESOURCE);
+    bitmaps[4] = new wxBitmap("icon5", wxBITMAP_TYPE_RESOURCE);
+    bitmaps[5] = new wxBitmap("icon6", wxBITMAP_TYPE_RESOURCE);
+    bitmaps[6] = new wxBitmap("icon7", wxBITMAP_TYPE_RESOURCE);
+    bitmaps[7] = new wxBitmap("icon8", wxBITMAP_TYPE_RESOURCE);
+
+#ifdef __WINDOWS__
+  int width = 24;
+#else
+  int width = 16;
+#endif
+  int offX = 5;
+  int currentX = 5;
+
+  AddTool(0, bitmaps[0], wxNullBitmap, FALSE, (float)currentX, -1, NULL, "New file");
+  currentX += width + 5;
+  AddTool(1, bitmaps[1], wxNullBitmap, FALSE, (float)currentX, -1, NULL, "Open file");
+  currentX += width + 5;
+  AddTool(2, bitmaps[2], wxNullBitmap, FALSE, (float)currentX, -1, NULL, "Save file");
+  currentX += width + 5;
+  AddSeparator();
+  AddTool(3, bitmaps[3], wxNullBitmap, FALSE, (float)currentX, -1, NULL, "Copy");
+  currentX += width + 5;
+  AddTool(4, bitmaps[4], wxNullBitmap, FALSE, (float)currentX, -1, NULL, "Cut");
+  currentX += width + 5;
+  AddTool(5, bitmaps[5], wxNullBitmap, FALSE, (float)currentX, -1, NULL, "Paste");
+  currentX += width + 5;
+  AddSeparator();
+  AddTool(6, bitmaps[6], wxNullBitmap, FALSE, (float)currentX, -1, NULL, "Print");
+  currentX += width + 5;
+  AddSeparator();
+  AddTool(7, bitmaps[7], wxNullBitmap, TRUE, currentX, -1, NULL, "Help");
+
+  CreateTools();
+
+  int i;
+  for (i = 0; i < 8; i++)
+    delete bitmaps[i];
+}
+
+bool TestRibbon::OnLeftClick(int toolIndex, bool toggled)
+{
+  char buf[200];
+  sprintf(buf, "Clicked on tool %d", toolIndex);
+  frame->SetStatusText(buf);
+  return TRUE;
+}
+
+void TestRibbon::OnMouseEnter(int toolIndex)
+{
+  char buf[200];
+  if (toolIndex > -1)
+  {
+    sprintf(buf, "This is tool number %d", toolIndex);
+    frame->SetStatusText(buf);
+  }
+  else frame->SetStatusText("");
+}
+
+void TestRibbon::OnPaint(wxPaintEvent& event)
+{
+  wxToolBar95::OnPaint(event);
+
+  wxPaintDC dc(this);
+  
+  int w, h;
+  GetSize(&w, &h);
+  dc.SetPen(wxBLACK_PEN);
+  dc.SetBrush(wxTRANSPARENT_BRUSH);
+  dc.DrawLine(0, h-1, w, h-1);
+}
+
+#endif
diff --git a/samples/mdi/mdi.def b/samples/mdi/mdi.def
new file mode 100644
index 0000000000..1d2353702e
--- /dev/null
+++ b/samples/mdi/mdi.def
@@ -0,0 +1,8 @@
+NAME         Mdi
+DESCRIPTION  'MDI/SDI Test Program'
+EXETYPE      WINDOWS
+STUB         'WINSTUB.EXE'
+CODE         PRELOAD MOVEABLE DISCARDABLE
+DATA         PRELOAD MOVEABLE MULTIPLE
+HEAPSIZE     6000
+STACKSIZE    48000
diff --git a/samples/mdi/mdi.h b/samples/mdi/mdi.h
new file mode 100644
index 0000000000..073eac04e1
--- /dev/null
+++ b/samples/mdi/mdi.h
@@ -0,0 +1,82 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        mdi.cpp
+// Purpose:     MDI sample
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+// Define a new application
+class MyApp: public wxApp
+{
+  public:
+    bool OnInit(void);
+};
+
+class MyCanvas: public wxScrolledWindow
+{
+  public:
+    MyCanvas(wxWindow *parent, const wxPoint& pos, const wxSize& size);
+    virtual void OnDraw(wxDC& dc);
+    void OnEvent(wxMouseEvent& event);
+
+    DECLARE_EVENT_TABLE()
+};
+
+#ifdef __WINDOWS__
+
+class TestRibbon: public wxToolBar95
+{
+  public:
+  TestRibbon(wxFrame *frame, int x = 0, int y = 0, int w = -1, int h = -1,
+            long style = wxNO_BORDER, int direction = wxVERTICAL, int RowsOrColumns = 2);
+  bool OnLeftClick(int toolIndex, bool toggled);
+  void OnMouseEnter(int toolIndex);
+  void OnPaint(wxPaintEvent& event);
+  
+  DECLARE_EVENT_TABLE()
+};
+
+#endif
+
+// Define a new frame
+class MyFrame: public wxMDIParentFrame
+{
+  public:
+    wxTextCtrl *textWindow;
+    
+#ifdef __WINDOWS__    
+    TestRibbon* toolBar;
+#endif
+
+    MyFrame(wxWindow *parent, const wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, const long style);
+    bool OnClose(void);
+    void OnSize(wxSizeEvent& event);
+    void OnAbout(wxCommandEvent& event);
+    void OnNewWindow(wxCommandEvent& event);
+    void OnQuit(wxCommandEvent& event);
+
+DECLARE_EVENT_TABLE()
+};
+
+class MyChild: public wxMDIChildFrame
+{
+  public:
+    MyCanvas *canvas;
+    MyChild(wxMDIParentFrame *parent, const wxString& title, const wxPoint& pos, const wxSize& size, const long style);
+    ~MyChild(void);
+    bool OnClose(void);
+    void OnActivate(wxActivateEvent& event);
+    void OnQuit(wxCommandEvent& event);
+
+DECLARE_EVENT_TABLE()
+};
+
+#define MDI_QUIT        1
+#define MDI_NEW_WINDOW  2
+#define MDI_REFRESH     3
+#define MDI_CHILD_QUIT  4
+#define MDI_ABOUT       5
diff --git a/samples/mdi/mdi.ico b/samples/mdi/mdi.ico
new file mode 100644
index 0000000000000000000000000000000000000000..2dc1bde40cf921731fb2f7c6534054c6fb8d96d1
GIT binary patch
literal 766
zcmah{IgY|W5G*e%tq=i3o32BCvHXmAf>Zy(`6TlchZ{QF05Mc`&y2+((WbBJ>H`DN
z@#*^mB!3^kH~o>?Q%}?mpR_<=?X?6JSqZ@%EkkNRN{NMRALOiv%14mQONo@Vuu~f2
zR1r@bqoxHgHqbgO7{>y8VLOh4a849H4Zzj{FAJP(g5{I-n)O_*F$%SIE3<<+Nj^dZ
zMrsmnqFCH}{&VhK#xlN*^s!HQyVC2cT_ZcBoK?PWy+p6H9A{2%_%Scn3ie-MC5TR`
zfM>p<u^XdS?|okOIfpJ^f%66U{Re&)U_S$23D`&j|AJNVMk-G}mHwHtG*h#+L%Xz7
FyKkN>7Bv6>

literal 0
HcmV?d00001

diff --git a/samples/mdi/mdi.rc b/samples/mdi/mdi.rc
new file mode 100644
index 0000000000..173542b99b
--- /dev/null
+++ b/samples/mdi/mdi.rc
@@ -0,0 +1,24 @@
+aaaa                    ICON    "mondrian.ico"
+
+/* Useful if PROVIDE_DEFAULT_ICONS is set in wx_setup.h */
+#define IHaveMDIParentIcon
+#define IHaveMDIChildIcon
+
+wxSTD_MDIPARENTFRAME    ICON    "mondrian.ico"
+wxSTD_MDICHILDFRAME     ICON    "chart.ico"
+
+mdi_icn                 ICON    "mondrian.ico"
+chrt_icn                ICON    "chart.ico"
+
+icon1 BITMAP "bitmaps/new.bmp"
+icon2 BITMAP "bitmaps/open.bmp"
+icon3 BITMAP "bitmaps/save.bmp"
+icon4 BITMAP "bitmaps/copy.bmp"
+icon5 BITMAP "bitmaps/cut.bmp"
+icon6 BITMAP "bitmaps/paste.bmp"
+icon7 BITMAP "bitmaps/print.bmp"
+
+icon8 BITMAP "bitmaps/help.bmp"
+
+#include "wx/msw/wx.rc"
+
diff --git a/samples/mdi/mondrian.ico b/samples/mdi/mondrian.ico
new file mode 100644
index 0000000000000000000000000000000000000000..2310c5d275a87af295d5ea8dc79ea417a5e74c53
GIT binary patch
literal 766
zcmZQzU<5)11px*Sc)`TLAO@s0fLH;D9e|jTfdxnc0Z<M**w4TKL=5})Lnt5#WHKB$
zaDbtqp#doIAB-6O{|B*v7zjZ^AOa2W|NsACHyAJ}De?dRKnp(HN~rljcR;{k;{zQE
i@;}UZ|9Q?Fpp*~yJCwmWbLIrN`9Qm9%}2L?p!oo$cZ4ed

literal 0
HcmV?d00001

diff --git a/samples/minimal/Makefile b/samples/minimal/Makefile
new file mode 100644
index 0000000000..027d82ae19
--- /dev/null
+++ b/samples/minimal/Makefile
@@ -0,0 +1 @@
+include ../../src/gtk/setup/general/makeapp
diff --git a/samples/minimal/Makefile.in b/samples/minimal/Makefile.in
new file mode 100644
index 0000000000..13d042e5ef
--- /dev/null
+++ b/samples/minimal/Makefile.in
@@ -0,0 +1,26 @@
+# WXXT base directory
+WXBASEDIR=@WXBASEDIR@
+
+# set the OS type for compilation
+OS=@OS@
+# compile a library only
+RULE=bin
+
+# define library name
+BIN_TARGET=test
+# define library sources
+BIN_SRC=\
+minimal.cpp
+
+#define library objects
+BIN_OBJ=\
+minimal.o
+
+# additional things needed to link
+BIN_LINK=
+
+# additional things needed to compile
+ADD_COMPILE=
+
+# include the definitions now
+include ../../../template.mak
diff --git a/samples/minimal/aiai.ico b/samples/minimal/aiai.ico
new file mode 100644
index 0000000000000000000000000000000000000000..a3db6563cc0b9f4588e1e994fe54b90a3cb1d6c1
GIT binary patch
literal 766
zcmc(bJ930T3`Bcft}@v=+L+MC@X_W5#I6lE$3$=(hlEfB<Ja@?LOIyb0!^!t)JP*;
zc>4Zbw(l3|27cf@{)u1o%88L{R;n8d60briz)7fio<S#4ewC6VoX4NcpV>a{V~VK)
z)$t4e1%j>c0*T7ZEBuvb0Ndch+2BCx7U^mZHa?iIh11ZPGV>8*oPzc{HmcjEM7U^(
z*rd)gSRm_`KJo;dxt={X3#3|q&kYE;ul$En1WJC3UOX%3ev8=<z}j41;VP{UzUs~U
s)wx~DuB_~?Y=Qe|v5`BV=<&%~$Nt1hCmx0~Ul2L;AGObMz1)9;A6NK_vj6}9

literal 0
HcmV?d00001

diff --git a/samples/minimal/aiai.xbm b/samples/minimal/aiai.xbm
new file mode 100644
index 0000000000..1a6f0a31b1
--- /dev/null
+++ b/samples/minimal/aiai.xbm
@@ -0,0 +1,38 @@
+#define aiai_width 64
+#define aiai_height 64
+static char aiai_bits[] = {
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x44,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x44,0x44,0x44,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x44,0x44,0x44,0x42,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x47,0x44,0x44,0x44,0x44,0x11,0x11,0x11,0x17,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x91,0x1f,0x11,0x11,0x11,0x11,0x44,0x44,0xc4,0x4f,0x44,0x44,0x44,0x44,
+ 0x44,0x44,0xc4,0x5f,0x44,0xf4,0x45,0x44,0x11,0x11,0xf1,0x1f,0x11,0xf9,0x13,
+ 0x11,0x11,0x11,0xf1,0x3f,0x11,0xfd,0x13,0x11,0x44,0x44,0xf4,0x7f,0x44,0xfc,
+ 0x47,0x44,0x44,0x44,0xf4,0x7f,0x44,0xfc,0x47,0x44,0x11,0x11,0xf9,0x7f,0x11,
+ 0xf9,0x13,0x11,0x11,0x11,0xfd,0xff,0x11,0xf1,0x11,0x11,0x44,0x44,0xfc,0xff,
+ 0x44,0x44,0x44,0x44,0x44,0x44,0xfe,0xff,0x45,0x44,0x44,0x44,0x11,0x11,0xff,
+ 0xff,0x11,0xfd,0x13,0x11,0x11,0x11,0xff,0xff,0x13,0xfd,0x13,0x11,0x44,0xc4,
+ 0xff,0xff,0x07,0xfc,0x43,0x44,0x44,0xff,0xff,0xf9,0xff,0xfd,0xfb,0xff,0x11,
+ 0xc0,0xff,0x00,0x00,0xfc,0x03,0x00,0x11,0xc0,0x7f,0x00,0x00,0xfc,0x03,0x00,
+ 0x04,0xe0,0x7f,0x00,0x00,0xfc,0x03,0x00,0xf4,0xf7,0xbf,0xff,0xff,0xfd,0xfb,
+ 0x7f,0x01,0xf0,0x1f,0x00,0x00,0xfc,0x03,0x00,0x01,0xf8,0x1f,0x00,0x00,0xfc,
+ 0x03,0x00,0x00,0xfc,0x0f,0x00,0x00,0xfc,0x03,0x40,0xfe,0xfd,0xef,0xff,0xff,
+ 0xfd,0xfb,0x4f,0x00,0xfe,0x07,0x00,0x00,0xfc,0x03,0x10,0x00,0xfe,0x03,0x00,
+ 0x00,0xfc,0x03,0x10,0x00,0xff,0x03,0x00,0x00,0xfc,0x03,0x44,0x7f,0xff,0x01,
+ 0x00,0x00,0xfc,0xfb,0x44,0x91,0xff,0xff,0xff,0xff,0xff,0x13,0x11,0xd1,0xff,
+ 0xff,0xff,0xff,0xff,0x13,0x11,0xe4,0xff,0xff,0xff,0xff,0xff,0x47,0x44,0xe4,
+ 0xff,0xff,0xff,0xff,0xff,0x47,0x44,0xf1,0xff,0xff,0xff,0xff,0xff,0x13,0x11,
+ 0xf1,0xff,0xff,0xff,0xff,0xff,0x13,0x11,0xfc,0xff,0xff,0xff,0xff,0xff,0x47,
+ 0x44,0xfc,0xff,0xff,0xff,0xff,0xff,0x47,0x44,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x11,0x44,0x44,0xc4,0x44,0x44,
+ 0xc4,0x44,0x44,0x44,0x4e,0xc4,0x44,0x4e,0xc4,0x44,0x44,0x11,0x1f,0xd1,0x11,
+ 0x1f,0xd1,0x11,0x11,0x91,0x31,0xd1,0x91,0x31,0xd1,0x11,0x11,0xc4,0x64,0xcc,
+ 0xcc,0x64,0xcc,0x44,0x44,0x64,0xc4,0xcc,0x6c,0xc4,0xcc,0x44,0x44,0xf1,0xff,
+ 0xd1,0xf1,0xff,0xd1,0x11,0x11,0xf9,0xff,0xd3,0xf9,0xff,0xd3,0x11,0x11,0x4c,
+ 0x44,0xc6,0x4c,0x44,0xc6,0x44,0x44,0x4c,0x44,0xc6,0x4c,0x44,0xc6,0x44,0x44,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x44};
diff --git a/samples/minimal/makefile.b32 b/samples/minimal/makefile.b32
new file mode 100644
index 0000000000..06d7deff50
--- /dev/null
+++ b/samples/minimal/makefile.b32
@@ -0,0 +1,64 @@
+#
+# File:		makefile.bcc
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds minimal example (DOS).
+
+# WXWIN and BCCDIR are set by parent make
+
+WXDIR = $(WXWIN)
+!include $(WXDIR)\src\makeb32.env
+
+WXLIBDIR = $(WXDIR)\lib
+WXINC = $(WXDIR)\include\msw
+WXLIB = $(WXLIBDIR)\wx32.lib
+LIBS=$(WXLIB) cw32 import32 ole2w32
+
+TARGET=minimal
+
+!if "$(FINAL)" == "0"
+LINKFLAGS=/v /Tpe /L$(WXLIBDIR);$(BCCDIR)\lib
+OPT = -Od
+DEBUG_FLAGS= -v
+!else
+LINKFLAGS=/Tpe /L$(WXLIBDIR);$(BCCDIR)\lib
+OPT = -Od
+DEBUG_FLAGS =
+!endif
+CPPFLAGS=$(DEBUG_FLAGS) $(OPT) @$(CFG)
+
+OBJECTS = minimal.obj
+
+$(TARGET).exe:	$(OBJECTS) $(TARGET).def $(TARGET).res
+  tlink32 $(LINKFLAGS) @&&!
+c0w32.obj $(OBJECTS)
+$(TARGET)
+nul
+$(LIBS)
+$(TARGET).def
+!
+        brc32 -K $(TARGET).res
+
+.$(SRCSUFF).obj:
+	bcc32 $(CPPFLAGS) -c {$< }
+
+.c.obj:
+	bcc32 $(CPPFLAGS) -P- -c {$< }
+
+minimal.obj:      minimal.$(SRCSUFF)
+
+$(TARGET).res :      $(TARGET).rc $(WXDIR)\include\wx\msw\wx.rc
+    brc32 -r /i$(BCCDIR)\include /i$(WXDIR)\include $(TARGET)
+
+clean:
+        -erase *.obj
+        -erase *.exe
+        -erase *.res
+        -erase *.map
+        -erase *.rws
+
diff --git a/samples/minimal/makefile.bcc b/samples/minimal/makefile.bcc
new file mode 100644
index 0000000000..b68a9b6d21
--- /dev/null
+++ b/samples/minimal/makefile.bcc
@@ -0,0 +1,73 @@
+#
+# File:		makefile.bcc
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds minimal example (DOS).
+
+!if "$(BCCDIR)" == ""
+!error You must define the BCCDIR variable in autoexec.bat, e.g. BCCDIR=d:\bc4
+!endif
+
+!if "$(WXWIN)" == ""
+!error You must define the WXWIN variable in autoexec.bat, e.g. WXWIN=c:\wx
+!endif
+
+WXDIR = $(WXWIN)
+!include $(WXDIR)\src\makebcc.env
+
+THISDIR = $(WXDIR)\samples\minimal
+WXLIB = $(WXDIR)\lib\wx.lib
+LIBS=$(WXLIB) mathwl cwl import
+INC=-I$(WXDIR)\include\base -I$(WXDIR)\include\msw
+CFG=$(WXDIR)\src\wxwin.cfg
+
+!ifndef FINAL
+FINAL=0
+!endif
+
+!if "$(FINAL)" == "0"
+LINKFLAGS=/v/Vt /Twe /L$(WXDIR)\lib;$(BCCDIR)\lib
+OPT = -Od
+DEBUG_FLAGS= -v
+!else
+LINKFLAGS=/Twe /L$(WXDIR)\lib;$(BCCDIR)\lib
+OPT = -O2
+DEBUG_FLAGS=
+!endif
+CPPFLAGS=$(DEBUG_FLAGS) $(OPT) @$(CFG)
+
+OBJECTS = minimal.obj
+
+minimal:    minimal.exe
+
+all:    minimal.exe
+
+minimal.exe:    $(WXLIB) minimal.obj minimal.def minimal.res
+        tlink $(LINKFLAGS) @&&!
+c0wl.obj minimal.obj
+minimal
+nul
+$(LIBS)
+minimal.def
+!
+        rc -31 -K minimal.res
+
+.$(SRCSUFF).obj:
+	bcc $(CPPFLAGS) -c {$< }
+
+minimal.obj:      minimal.$(SRCSUFF)
+
+minimal.res :      minimal.rc $(WXDIR)\include\msw\wx.rc
+    rc -r /i$(BCCDIR)\include /i$(WXDIR)\include\msw /i$(WXDIR)\contrib\fafa minimal
+
+clean:
+        -erase *.obj
+        -erase *.exe
+        -erase *.res
+        -erase *.map
+        -erase *.rws
diff --git a/samples/minimal/makefile.dos b/samples/minimal/makefile.dos
new file mode 100644
index 0000000000..aa7e6ddf53
--- /dev/null
+++ b/samples/minimal/makefile.dos
@@ -0,0 +1,65 @@
+#
+# File:		makefile.dos
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds minimal example (DOS).
+# Use FINAL=1 argument to nmake to build final version with no debugging
+# info
+
+WXDIR = $(WXWIN)
+
+!include $(WXDIR)\src\makemsc.env
+
+THISDIR = $(WXDIR)\samples\minimal
+
+!ifndef FINAL
+FINAL=0
+!endif
+
+HEADERS =
+SOURCES = minimal.$(SRCSUFF)
+OBJECTS = minimal.obj
+
+all:    minimal.exe
+
+wx:
+        cd $(WXDIR)\src\msw
+        nmake -f makefile.dos FINAL=$(FINAL)
+        cd $(THISDIR)
+
+wxclean:
+        cd $(WXDIR)\src\msw
+        nmake -f makefile.dos clean
+        cd $(THISDIR)
+
+minimal.exe:      $(WXDIR)\src\msw\dummy.obj $(WXLIB) minimal.obj minimal.def minimal.res
+        link $(LINKFLAGS) @<<
+minimal.obj $(WXDIR)\src\msw\dummy.obj,
+minimal,
+NUL,
+$(LIBS),
+minimal.def
+;
+<<
+        rc -K minimal.res
+
+minimal.obj:      minimal.$(SRCSUFF)
+        cl @<<
+$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
+<<
+
+minimal.res :      minimal.rc $(WXDIR)\include\wx\msw\wx.rc
+    rc -r /i$(WXDIR)\include minimal
+
+clean:
+        -erase *.obj
+        -erase *.exe
+        -erase *.res
+        -erase *.map
+        -erase *.sbr
+        -erase *.pdb
diff --git a/samples/minimal/makefile.g95 b/samples/minimal/makefile.g95
new file mode 100644
index 0000000000..6ad1b1b2ad
--- /dev/null
+++ b/samples/minimal/makefile.g95
@@ -0,0 +1,37 @@
+#
+# File:		makefile.unx
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile for minimal example (UNIX).
+
+WXDIR = ../..
+
+# All common UNIX compiler flags and options are now in
+# this central makefile.
+include $(WXDIR)/src/makeg95.env
+
+OBJECTS = $(OBJDIR)/minimal.$(OBJSUFF) $(OBJDIR)/minimal_resources.$(OBJSUFF)
+
+all:    $(OBJDIR) minimal$(GUISUFFIX)$(EXESUFF)
+
+wx:
+
+$(OBJDIR):
+	mkdir $(OBJDIR)
+
+minimal$(GUISUFFIX)$(EXESUFF):	$(OBJECTS) $(WXLIB)
+	$(CC) $(LDFLAGS) -o minimal$(GUISUFFIX)$(EXESUFF) $(OBJECTS) $(LDLIBS)
+
+$(OBJDIR)/minimal.$(OBJSUFF):	minimal.$(SRCSUFF)
+	$(CC) -c $(CPPFLAGS) -o $@ minimal.$(SRCSUFF)
+
+$(OBJDIR)/minimal_resources.o:  minimal.rc
+	$(RESCOMP) -i minimal.rc -o $(OBJDIR)/minimal_resources.o $(RESFLAGS)
+
+clean:
+	rm -f $(OBJECTS) minimal$(GUISUFFIX).exe core *.rsc *.res
diff --git a/samples/minimal/makefile.nt b/samples/minimal/makefile.nt
new file mode 100644
index 0000000000..276311e09c
--- /dev/null
+++ b/samples/minimal/makefile.nt
@@ -0,0 +1,64 @@
+#
+# File:		makefile.nt
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds minimal example (MS VC++).
+# Use FINAL=1 argument to nmake to build final version with no debugging
+# info
+
+# Set WXDIR for your system
+WXDIR = $(WXWIN)
+
+WXUSINGDLL=0
+
+!include $(WXDIR)\src\ntwxwin.mak
+
+THISDIR = $(WXDIR)\samples\minimal
+PROGRAM=minimal
+ 
+OBJECTS = $(PROGRAM).obj
+
+$(PROGRAM):    $(PROGRAM).exe
+
+all:    wx $(PROGRAM).exe
+
+wx:
+        cd $(WXDIR)\src\msw
+        nmake -f makefile.nt FINAL=$(FINAL)
+        cd $(THISDIR)
+
+wxclean:
+        cd $(WXDIR)\src\msw
+        nmake -f makefile.nt clean
+        cd $(THISDIR)
+
+$(PROGRAM).exe:      $(DUMMYOBJ) $(WXLIB) $(OBJECTS) $(PROGRAM).res
+	$(link) @<<
+-out:$(PROGRAM).exe
+$(LINKFLAGS)
+$(DUMMYOBJ) $(OBJECTS) $(PROGRAM).res
+$(LIBS)
+<<
+
+
+$(PROGRAM).obj:      $(PROGRAM).$(SRCSUFF) $(DUMMYOBJ)
+        $(cc) @<<
+$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
+<<
+
+$(PROGRAM).res :      $(PROGRAM).rc $(WXDIR)\include\wx\msw\wx.rc
+    $(rc) -r /i$(WXDIR)\include -fo$@ $(PROGRAM).rc
+
+
+clean:
+        -erase *.obj
+        -erase *.exe
+        -erase *.res
+        -erase *.map
+        -erase *.sbr
+        -erase *.pdb
diff --git a/samples/minimal/makefile.sc b/samples/minimal/makefile.sc
new file mode 100644
index 0000000000..8709d2ca0f
--- /dev/null
+++ b/samples/minimal/makefile.sc
@@ -0,0 +1,35 @@
+# Symantec C++ makefile for minimal example
+# NOTE that peripheral libraries are now dealt in main wxWindows makefile.
+
+WXDIR = $(WXWIN)
+!include $(WXDIR)\src\makesc.env
+
+WXLIB = $(WXDIR)\lib\wx.lib
+INCDIR = $(WXDIR)\include
+MSWINC = $(INCDIR)\msw
+BASEINC = $(INCDIR)\base
+
+CC=sc
+RC=rc
+CFLAGS = -o -ml -W -Dwx_msw
+LDFLAGS = -ml -W
+
+INCLUDE=$(BASEINC);$(MSWINC)
+
+LIBS=$(WXLIB) libw.lib commdlg.lib shell.lib
+
+.$(SRCSUFF).obj:
+	*$(CC) -c $(CFLAGS) -I$(INCLUDE) $<
+
+.rc.res:
+	*$(RC) -r -I$(INCLUDE) $<
+
+minimal.exe: minimal.obj minimal.def minimal.res
+	*$(CC) $(LDFLAGS) -o$@ $** $(LIBS)
+
+clean:
+        -del *.obj
+	-del *.exe
+	-del *.res
+	-del *.map
+	-del *.rws
diff --git a/samples/minimal/makefile.unx b/samples/minimal/makefile.unx
new file mode 100644
index 0000000000..9685d06789
--- /dev/null
+++ b/samples/minimal/makefile.unx
@@ -0,0 +1,58 @@
+#
+# File:		makefile.unx
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile for minimal example (UNIX).
+
+WXDIR = ../..
+
+# All common UNIX compiler flags and options are now in
+# this central makefile.
+include $(WXDIR)/src/make.env
+
+OBJECTS = $(OBJDIR)/minimal.$(OBJSUFF)
+
+.SUFFIXES:
+
+all:    $(OBJDIR) minimal$(GUISUFFIX)
+
+wx:
+
+
+motif:
+	$(MAKE) -f makefile.unx GUISUFFIX=_motif GUI=-Dwx_motif GUISUFFIX=_motif OPT='$(OPT)' LDLIBS='$(MOTIFLDLIBS)' WXLIB=$(WXDIR)/lib/libwx_motif.a  OPTIONS='$(OPTIONS)' DEBUG='$(DEBUG)' WARN='$(WARN)' XLIB='$(XLIB)' XINCLUDE='$(XINCLUDE)' XVIEW_LINK=
+
+xview:
+	cd $(WXDIR)/src/x; $(MAKE) -f makefile.unx xview
+	$(MAKE) -f makefile.unx GUI=-Dwx_xview GUISUFFIX=_ol CC=$(CC) OPTIONS='$(OPTIONS)' DEBUG='$(DEBUG)' WARN='$(WARN)' XLIB='$(XLIB)' XINCLUDE='$(XINCLUDE)'
+
+hp:
+	cd $(WXDIR)/src/x; $(MAKE) -f makefile.unx hp
+	$(MAKE) -f makefile.unx GUI=-Dwx_motif GUISUFFIX=_hp CC=CC DEBUG='$(DEBUG)' WARN='-w' \
+         XINCLUDE='$(HPXINCLUDE)' XLIB='$(HPXLIB)' XVIEW_LINK='' LDLIBS='$(HPLDLIBS)'
+
+$(OBJDIR):
+	mkdir $(OBJDIR)
+
+minimal$(GUISUFFIX):	$(OBJDIR)/minimal.$(OBJSUFF) $(WXLIB)
+	$(CC) $(LDFLAGS) -o minimal$(GUISUFFIX) $(OBJDIR)/minimal.$(OBJSUFF) $(XVIEW_LINK) $(LDLIBS)
+
+$(OBJDIR)/minimal.$(OBJSUFF):	minimal.$(SRCSUFF)
+	$(CC) -c $(CPPFLAGS) -o $@ minimal.$(SRCSUFF)
+
+clean_motif:
+	$(MAKE) -f makefile.unx GUISUFFIX=_motif cleanany
+
+clean_ol:
+	$(MAKE) -f makefile.unx GUISUFFIX=_ol cleanany
+
+clean_hp:
+	$(MAKE) -f makefile.unx GUISUFFIX=_hp cleanany
+
+cleanany:
+	rm -f $(OBJECTS) minimal$(GUISUFFIX) core
diff --git a/samples/minimal/makefile.vms b/samples/minimal/makefile.vms
new file mode 100644
index 0000000000..9b76b144f3
--- /dev/null
+++ b/samples/minimal/makefile.vms
@@ -0,0 +1,38 @@
+#************************************************************************
+# Makefile for MINIMAL under VMS
+# by Stefan Hammes
+# (incomplete) update history:
+# 11.04.95
+#************************************************************************
+
+#************************************************************************
+# Definition section
+# (cave: definitions and includes must begin with ',')
+#************************************************************************
+
+APPOPTS = 
+APPDEFS = 
+APPINCS = 
+
+#************************************************************************
+# Module section
+#************************************************************************
+
+# Name of main module
+MAIN = minimal
+
+# Object modules of the application.
+OBJS = minimal.obj
+OBJLIST =minimal.obj
+
+.include [--.src]makevms.env
+
+# main dependency
+$(MAIN).exe : $(OBJS)
+    $(LINK) $(LINKFLAGS) /exec=$(MAIN).exe $(OBJLIST),$(WXLIB)/lib,$(OPTSFILE)/option
+    - purge *.exe
+
+#************************************************************************
+# Header file depedencies following
+#************************************************************************
+
diff --git a/samples/minimal/makefile.wat b/samples/minimal/makefile.wat
new file mode 100644
index 0000000000..21219d7a0e
--- /dev/null
+++ b/samples/minimal/makefile.wat
@@ -0,0 +1,43 @@
+#
+# Makefile for WATCOM
+#
+# Created by D.Chubraev, chubraev@iem.ee.ethz.ch
+# 8 Nov 1994
+#
+
+WXDIR = ..\.. 
+
+!include $(WXDIR)\src\makewat.env
+
+WXLIB = $(WXDIR)\lib
+NAME = minimal
+LNK = $(name).lnk
+OBJS = $(name).obj 
+
+all: $(name).exe
+
+$(name).exe : $(OBJS) $(name).res $(LNK) $(WXLIB)\wx$(LEVEL).lib
+    wlink @$(LNK)
+    $(BINDCOMMAND) $(name).res
+
+$(name).res :      $(name).rc $(WXDIR)\include\msw\wx.rc
+     $(RC) $(RESFLAGS1) $(name).rc
+
+$(LNK) : makefile.wat
+    %create $(LNK)
+    @%append $(LNK) debug all
+    @%append $(LNK) system $(LINKOPTION)
+    @%append $(LNK) $(MINDATA)
+    @%append $(LNK) $(MAXDATA)
+    @%append $(LNK) $(STACK)
+    @%append $(LNK) name $(name)
+    @%append $(LNK) file $(WXLIB)\wx$(LEVEL).lib
+    @for %i in ($(EXTRALIBS)) do @%append $(LNK) file %i
+    @for %i in ($(OBJS)) do @%append $(LNK) file %i
+
+thing: .SYMBOLIC
+    echo $(WATLIBDIR)
+
+clean:   .SYMBOLIC
+    -erase *.obj *.bak *.err *.pch *.lib *.lnk *.res *.exe
+
diff --git a/samples/minimal/minimal.cpp b/samples/minimal/minimal.cpp
new file mode 100644
index 0000000000..86a0e89965
--- /dev/null
+++ b/samples/minimal/minimal.cpp
@@ -0,0 +1,116 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        minimal.cpp
+// Purpose:     Minimal wxWindows sample
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "minimal.cpp"
+#pragma interface "minimal.cpp"
+#endif
+
+// For compilers that support precompilation, includes "wx/wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+// Define a new application type
+class MyApp: public wxApp
+{ public:
+    bool OnInit(void);
+};
+
+// Define a new frame type
+class MyFrame: public wxFrame
+{ public:
+    MyFrame(wxFrame *frame, char *title, int x, int y, int w, int h);
+    
+ public:
+    void OnQuit(wxCommandEvent& event);
+    void OnAbout(wxCommandEvent& event);
+	bool OnClose(void) { return TRUE; }
+
+   DECLARE_EVENT_TABLE()
+    
+};
+
+// ID for the menu commands
+#define MINIMAL_QUIT 	1
+#define MINIMAL_TEXT 	101
+#define MINIMAL_ABOUT 	102
+
+BEGIN_EVENT_TABLE(MyFrame, wxFrame)
+	EVT_MENU(MINIMAL_QUIT, MyFrame::OnQuit)
+	EVT_MENU(MINIMAL_ABOUT, MyFrame::OnAbout)
+END_EVENT_TABLE()
+
+// Create a new application object
+IMPLEMENT_APP	(MyApp)
+
+// `Main program' equivalent, creating windows and returning main app frame
+bool MyApp::OnInit(void)
+{
+  // Create the main frame window
+  MyFrame *frame = new MyFrame(NULL, "Minimal wxWindows App", 50, 50, 450, 340);
+
+  // Give it an icon
+#ifdef __WINDOWS__
+  frame->SetIcon(wxIcon("mondrian"));
+#endif
+#ifdef __X__
+  frame->SetIcon(wxIcon("aiai.xbm"));
+#endif
+
+  // Make a menubar
+  wxMenu *file_menu = new wxMenu;
+
+  file_menu->Append(MINIMAL_ABOUT, "&About");
+  file_menu->Append(MINIMAL_QUIT, "E&xit");
+  wxMenuBar *menu_bar = new wxMenuBar;
+  menu_bar->Append(file_menu, "&File");
+  frame->SetMenuBar(menu_bar);
+
+  // Make a panel with a message
+  wxPanel *panel = new wxPanel(frame, -1, wxPoint(0, 0), wxSize(400, 200), wxTAB_TRAVERSAL);
+
+  wxStaticText *msg = new wxStaticText(panel, 311, "Hello!", wxPoint(10, 10), wxSize(-1, -1),
+    0);
+
+  // Show the frame
+  frame->Show(TRUE);
+  
+  SetTopWindow(frame);
+
+  return TRUE;
+}
+
+// My frame constructor
+MyFrame::MyFrame(wxFrame *frame, char *title, int x, int y, int w, int h):
+  wxFrame(frame, -1, title, wxPoint(x, y), wxSize(w, h))
+{}
+
+void MyFrame::OnQuit(wxCommandEvent& event)
+{
+  Close(TRUE);
+}
+
+void MyFrame::OnAbout(wxCommandEvent& event)
+{
+  wxMessageDialog dialog(this, "This is a minimal sample\nA second line in the message box",
+  	"About Minimal", wxYES_NO|wxCANCEL);
+
+  dialog.ShowModal();
+}
+
+
diff --git a/samples/minimal/minimal.def b/samples/minimal/minimal.def
new file mode 100644
index 0000000000..060bfe3fce
--- /dev/null
+++ b/samples/minimal/minimal.def
@@ -0,0 +1,8 @@
+NAME         Minimal
+DESCRIPTION  'Minimal wxWindows application'
+EXETYPE      WINDOWS
+STUB         'WINSTUB.EXE'
+CODE         PRELOAD MOVEABLE DISCARDABLE
+DATA         PRELOAD MOVEABLE MULTIPLE
+HEAPSIZE     4048
+STACKSIZE    16000
diff --git a/samples/minimal/minimal.rc b/samples/minimal/minimal.rc
new file mode 100644
index 0000000000..7655c62a4c
--- /dev/null
+++ b/samples/minimal/minimal.rc
@@ -0,0 +1,3 @@
+mondrian ICON "mondrian.ico"
+#include "wx/msw/wx.rc"
+
diff --git a/samples/minimal/mondrian.ico b/samples/minimal/mondrian.ico
new file mode 100644
index 0000000000000000000000000000000000000000..2310c5d275a87af295d5ea8dc79ea417a5e74c53
GIT binary patch
literal 766
zcmZQzU<5)11px*Sc)`TLAO@s0fLH;D9e|jTfdxnc0Z<M**w4TKL=5})Lnt5#WHKB$
zaDbtqp#doIAB-6O{|B*v7zjZ^AOa2W|NsACHyAJ}De?dRKnp(HN~rljcR;{k;{zQE
i@;}UZ|9Q?Fpp*~yJCwmWbLIrN`9Qm9%}2L?p!oo$cZ4ed

literal 0
HcmV?d00001

diff --git a/samples/png/Makefile b/samples/png/Makefile
new file mode 100644
index 0000000000..027d82ae19
--- /dev/null
+++ b/samples/png/Makefile
@@ -0,0 +1 @@
+include ../../src/gtk/setup/general/makeapp
diff --git a/samples/png/Makefile.in b/samples/png/Makefile.in
new file mode 100644
index 0000000000..4bd9898e0a
--- /dev/null
+++ b/samples/png/Makefile.in
@@ -0,0 +1,26 @@
+# WXXT base directory
+WXBASEDIR=@WXBASEDIR@
+
+# set the OS type for compilation
+OS=@OS@
+# compile a library only
+RULE=bin
+
+# define library name
+BIN_TARGET=test
+# define library sources
+BIN_SRC=\
+pngdemo.cpp
+
+#define library objects
+BIN_OBJ=\
+pngdemo.o
+
+# additional things needed to link
+BIN_LINK=
+
+# additional things needed to compile
+ADD_COMPILE=
+
+# include the definitions now
+include ../../../template.mak
diff --git a/samples/png/makefile.nt b/samples/png/makefile.nt
new file mode 100644
index 0000000000..81a3e4df06
--- /dev/null
+++ b/samples/png/makefile.nt
@@ -0,0 +1,66 @@
+#
+# File:		makefile.nt
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds pngdemo example (MS VC++).
+# Use FINAL=1 argument to nmake to build final version with no debugging
+# info
+
+# Set WXDIR for your system
+WXDIR = $(WXWIN)
+
+WXUSINGDLL=0
+
+EXTRALIBS=$(WXDIR)\lib\winpng.lib $(WXDIR)\lib\zlib.lib
+
+!include $(WXDIR)\src\ntwxwin.mak
+
+THISDIR = $(WXDIR)\samples\png
+PROGRAM=pngdemo
+
+OBJECTS = $(PROGRAM).obj
+
+$(PROGRAM):    $(PROGRAM).exe
+
+all:    wx $(PROGRAM).exe
+
+wx:
+        cd $(WXDIR)\src\msw
+        nmake -f makefile.nt FINAL=$(FINAL)
+        cd $(THISDIR)
+
+wxclean:
+        cd $(WXDIR)\src\msw
+        nmake -f makefile.nt clean
+        cd $(THISDIR)
+
+$(PROGRAM).exe:      $(DUMMYOBJ) $(WXLIB) $(OBJECTS) $(PROGRAM).res
+	$(link) @<<
+-out:$(PROGRAM).exe
+$(LINKFLAGS)
+$(DUMMYOBJ) $(OBJECTS) $(PROGRAM).res
+$(LIBS)
+<<
+
+
+$(PROGRAM).obj:      $(PROGRAM).$(SRCSUFF) $(DUMMYOBJ)
+        $(cc) @<<
+$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
+<<
+
+$(PROGRAM).res :      $(PROGRAM).rc $(WXDIR)\include\wx\msw\wx.rc
+    $(rc) -r /i$(WXDIR)\include -fo$@ $(PROGRAM).rc
+
+
+clean:
+        -erase *.obj
+        -erase *.exe
+        -erase *.res
+        -erase *.map
+        -erase *.sbr
+        -erase *.pdb
diff --git a/samples/png/pngdemo.cpp b/samples/png/pngdemo.cpp
new file mode 100644
index 0000000000..0106b34ed9
--- /dev/null
+++ b/samples/png/pngdemo.cpp
@@ -0,0 +1,186 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        pngdemo.cpp
+// Purpose:     Demos PNG reading
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "pngdemo.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifdef __WINDOWS__
+#include <wx/pnghand.h>
+#endif
+
+#include "pngdemo.h"
+
+MyFrame   *frame = NULL;
+wxBitmap  *g_TestBitmap = NULL;
+
+IMPLEMENT_APP(MyApp)
+
+MyApp::MyApp()
+{
+}
+
+bool MyApp::OnInit(void)
+{
+#ifdef __WINDOWS__
+  wxBitmap::AddHandler(new wxPNGFileHandler);
+#endif
+
+  // Create the main frame window
+  frame = new MyFrame(NULL, "wxPNGBitmap Demo", wxPoint(0, 0), wxSize(300, 300));
+
+  // Give it a status line
+  frame->CreateStatusBar(2);
+
+  // Make a menubar
+  wxMenu *file_menu = new wxMenu;
+  wxMenu *help_menu = new wxMenu;
+
+  file_menu->Append(PNGDEMO_LOAD_FILE, "&Load file",                "Load file");
+  file_menu->Append(PNGDEMO_QUIT, "E&xit",                "Quit program");
+  help_menu->Append(PNGDEMO_ABOUT, "&About",              "About PNG demo");
+
+  wxMenuBar *menu_bar = new wxMenuBar;
+
+  menu_bar->Append(file_menu, "&File");
+  menu_bar->Append(help_menu, "&Help");
+
+  // Associate the menu bar with the frame
+  frame->SetMenuBar(menu_bar);
+
+  MyCanvas *canvas = new MyCanvas(frame, wxPoint(0, 0), wxSize(100, 100));
+
+  // Give it scrollbars: the virtual canvas is 20 * 50 = 1000 pixels in each direction
+//  canvas->SetScrollbars(20, 20, 50, 50, 4, 4);
+  frame->canvas = canvas;
+
+  frame->Show(TRUE);
+
+  frame->SetStatusText("Hello, wxWindows");
+
+  return TRUE;
+}
+
+BEGIN_EVENT_TABLE(MyFrame, wxFrame)
+    EVT_MENU(PNGDEMO_QUIT,      MyFrame::OnQuit)
+    EVT_MENU(PNGDEMO_ABOUT,     MyFrame::OnAbout)
+    EVT_MENU(PNGDEMO_LOAD_FILE, MyFrame::OnLoadFile)
+END_EVENT_TABLE()
+
+// Define my frame constructor
+MyFrame::MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size):
+  wxFrame(frame, -1, title, pos, size)
+{
+  canvas = NULL;
+}
+
+void MyFrame::OnQuit(wxCommandEvent& event)
+{
+    Close(TRUE);
+}
+
+void MyFrame::OnAbout(wxCommandEvent& event)
+{
+    (void)wxMessageBox("PNG demo\nJulian Smart (c) 1998",
+            "About PNG Demo", wxOK);
+}
+
+void MyFrame::OnLoadFile(wxCommandEvent& event)
+{
+	// Show file selector.
+	char *f = wxFileSelector("Open Image", NULL, NULL,"png",
+		  "PNG files (*.png)|*.png");
+
+	if (!f)
+	  return;
+
+    if ( g_TestBitmap )
+        delete g_TestBitmap;
+    g_TestBitmap = new wxBitmap(f, wxBITMAP_TYPE_PNG);
+    if (!g_TestBitmap->Ok())
+    {
+        delete g_TestBitmap;
+        g_TestBitmap = NULL;
+    }
+
+    canvas->Refresh();
+}
+
+BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
+    EVT_PAINT(MyCanvas::OnPaint)
+END_EVENT_TABLE()
+
+// Define a constructor for my canvas
+MyCanvas::MyCanvas(wxWindow *parent, const wxPoint& pos, const wxSize& size):
+ wxScrolledWindow(parent, -1, pos, size)
+{
+}
+
+MyCanvas::~MyCanvas(void)
+{
+}
+
+// Define the repainting behaviour
+void MyCanvas::OnPaint(wxPaintEvent& event)
+{
+  wxPaintDC dc(this);
+  dc.SetPen(wxRED_PEN);
+
+  int i;
+  for ( i = 0; i < 500; i += 10)
+  {
+    dc.DrawLine(0, i, 800, i);
+  }
+  if ( g_TestBitmap && g_TestBitmap->Ok() )
+  {
+    wxMemoryDC memDC;
+    if ( g_TestBitmap->GetColourMap() )
+    {
+        memDC.SetColourMap(g_TestBitmap->GetColourMap());
+        dc.SetColourMap(g_TestBitmap->GetColourMap());
+    }
+    memDC.SelectObject(g_TestBitmap);
+
+    // Normal, non-transparent blitting
+    dc.Blit(20, 20, g_TestBitmap->GetWidth(), g_TestBitmap->GetHeight(), & memDC, 0, 0, wxCOPY, FALSE);
+
+    memDC.SelectObject(NULL);
+  }
+
+  if ( g_TestBitmap && g_TestBitmap->Ok() )
+  {
+    wxMemoryDC memDC;
+    memDC.SelectObject(g_TestBitmap);
+
+    // Transparent blitting if there's a mask in the bitmap
+    dc.Blit(20 + g_TestBitmap->GetWidth() + 20, 20, g_TestBitmap->GetWidth(), g_TestBitmap->GetHeight(), & memDC,
+      0, 0, wxCOPY, TRUE);
+
+    memDC.SelectObject(NULL);
+  }
+}
+
+// Define the behaviour for the frame closing
+// - must delete all frames except for the main one.
+bool MyFrame::OnClose(void)
+{
+  Show(FALSE);
+
+  return TRUE;
+}
+
diff --git a/samples/png/pngdemo.h b/samples/png/pngdemo.h
new file mode 100644
index 0000000000..e4be03ed4b
--- /dev/null
+++ b/samples/png/pngdemo.h
@@ -0,0 +1,57 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        bitmap.h
+// Purpose:     wxBitmap class
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/wx.h"
+
+// Define a new application
+class MyApp: public wxApp
+{
+  public:
+    MyApp(void) ;
+    bool OnInit(void);
+};
+
+// Define a new frame
+class MyCanvas;
+
+class MyFrame: public wxFrame
+{
+  public:
+    MyCanvas *canvas;
+    MyFrame(wxFrame *parent, const wxString& title, const wxPoint& pos, const wxSize& size);
+
+    bool OnClose(void);
+    void OnActivate(bool) {}
+    void OnLoadFile(wxCommandEvent& event);
+    void OnQuit(wxCommandEvent& event);
+    void OnAbout(wxCommandEvent& event);
+DECLARE_EVENT_TABLE()
+};
+
+// Define a new canvas which can receive some events
+class MyCanvas: public wxScrolledWindow
+{
+  public:
+    MyCanvas(wxWindow *parent, const wxPoint& pos, const wxSize& size);
+    ~MyCanvas(void) ;
+
+    void OnPaint(wxPaintEvent& event);
+DECLARE_EVENT_TABLE()
+};
+
+#define PNGDEMO_QUIT       100
+#define PNGDEMO_ABOUT      101
+#define PNGDEMO_LOAD_FILE  102
+
diff --git a/samples/png/pngdemo.rc b/samples/png/pngdemo.rc
new file mode 100644
index 0000000000..82bdf07561
--- /dev/null
+++ b/samples/png/pngdemo.rc
@@ -0,0 +1,2 @@
+#include "wx/msw/wx.rc"
+
diff --git a/samples/printing/Cour.afm b/samples/printing/Cour.afm
new file mode 100644
index 0000000000..f54e284ba7
--- /dev/null
+++ b/samples/printing/Cour.afm
@@ -0,0 +1,341 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1984 Adobe Systems Incorporated. 	All Rights Reserved.
+Comment Creation Date:Wed Feb 25 16:01:10 PST 1987
+FontName Courier
+EncodingScheme AdobeStandardEncoding
+FullName Courier
+FamilyName Courier
+Weight Medium
+ItalicAngle 0.0
+IsFixedPitch true
+UnderlinePosition -82
+UnderlineThickness 40
+Version 001.003
+FontBBox -40 -290 640 795
+CapHeight 583
+XHeight 437
+Descender -207
+Ascender 624
+StartCharMetrics 260
+C 32 ; WX 600 ; N space ; B 560 -40 640 40 ;
+C 33 ; WX 600 ; N exclam ; B 240 -5 360 639 ;
+C 34 ; WX 600 ; N quotedbl ; B 126 314 474 603 ;
+C 35 ; WX 600 ; N numbersign ; B 72 -82 528 665 ;
+C 36 ; WX 600 ; N dollar ; B 93 -113 507 675 ;
+C 37 ; WX 600 ; N percent ; B 67 -35 533 639 ;
+C 38 ; WX 600 ; N ampersand ; B 85 -35 498 540 ;
+C 39 ; WX 600 ; N quoteright ; B 135 304 340 613 ;
+C 40 ; WX 600 ; N parenleft ; B 274 -144 478 623 ;
+C 41 ; WX 600 ; N parenright ; B 127 -144 331 623 ;
+C 42 ; WX 600 ; N asterisk ; B 93 210 507 624 ;
+C 43 ; WX 600 ; N plus ; B 52 12 548 550 ;
+C 44 ; WX 600 ; N comma ; B 135 -155 340 155 ;
+C 45 ; WX 600 ; N hyphen ; B 52 241 548 321 ;
+C 46 ; WX 600 ; N period ; B 250 10 350 90 ;
+C 47 ; WX 600 ; N slash ; B 93 -103 507 686 ;
+C 48 ; WX 600 ; N zero ; B 93 -35 507 639 ;
+C 49 ; WX 600 ; N one ; B 93 -20 507 624 ;
+C 50 ; WX 600 ; N two ; B 64 -20 498 639 ;
+C 51 ; WX 600 ; N three ; B 76 -35 519 639 ;
+C 52 ; WX 600 ; N four ; B 85 -20 498 624 ;
+C 53 ; WX 600 ; N five ; B 76 -35 519 624 ;
+C 54 ; WX 600 ; N six ; B 116 -35 530 639 ;
+C 55 ; WX 600 ; N seven ; B 85 -20 498 624 ;
+C 56 ; WX 600 ; N eight ; B 93 -35 507 639 ;
+C 57 ; WX 600 ; N nine ; B 116 -35 530 639 ;
+C 58 ; WX 600 ; N colon ; B 250 10 350 392 ;
+C 59 ; WX 600 ; N semicolon ; B 139 -116 350 392 ;
+C 60 ; WX 600 ; N less ; B 52 12 548 550 ;
+C 61 ; WX 600 ; N equal ; B 31 168 569 394 ;
+C 62 ; WX 600 ; N greater ; B 52 12 548 550 ;
+C 63 ; WX 600 ; N question ; B 114 -5 507 598 ;
+C 64 ; WX 600 ; N at ; B 85 -82 498 644 ;
+C 65 ; WX 600 ; N A ; B -11 -20 611 583 ;
+C 66 ; WX 600 ; N B ; B 23 -20 561 583 ;
+C 67 ; WX 600 ; N C ; B 43 -35 554 598 ;
+C 68 ; WX 600 ; N D ; B 23 -20 540 583 ;
+C 69 ; WX 600 ; N E ; B 23 -20 540 583 ;
+C 70 ; WX 600 ; N F ; B 23 -20 540 583 ;
+C 71 ; WX 600 ; N G ; B 43 -35 582 598 ;
+C 72 ; WX 600 ; N H ; B 33 -20 571 583 ;
+C 73 ; WX 600 ; N I ; B 93 -20 507 583 ;
+C 74 ; WX 600 ; N J ; B 64 -35 603 583 ;
+C 75 ; WX 600 ; N K ; B 23 -20 592 583 ;
+C 76 ; WX 600 ; N L ; B 43 -20 561 583 ;
+C 77 ; WX 600 ; N M ; B -9 -20 613 583 ;
+C 78 ; WX 600 ; N N ; B 2 -20 582 583 ;
+C 79 ; WX 600 ; N O ; B 31 -35 569 598 ;
+C 80 ; WX 600 ; N P ; B 23 -20 519 583 ;
+C 81 ; WX 600 ; N Q ; B 31 -136 569 598 ;
+C 82 ; WX 600 ; N R ; B 23 -20 609 583 ;
+C 83 ; WX 600 ; N S ; B 72 -35 528 598 ;
+C 84 ; WX 600 ; N T ; B 52 -20 548 583 ;
+C 85 ; WX 600 ; N U ; B 20 -35 580 583 ;
+C 86 ; WX 600 ; N V ; B -11 -20 611 583 ;
+C 87 ; WX 600 ; N W ; B 0 -20 600 583 ;
+C 88 ; WX 600 ; N X ; B 20 -20 580 583 ;
+C 89 ; WX 600 ; N Y ; B 31 -20 569 583 ;
+C 90 ; WX 600 ; N Z ; B 83 -20 517 583 ;
+C 91 ; WX 600 ; N bracketleft ; B 260 -144 465 624 ;
+C 92 ; WX 600 ; N backslash ; B 93 -103 507 686 ;
+C 93 ; WX 600 ; N bracketright ; B 135 -144 340 624 ;
+C 94 ; WX 600 ; N asciicircum ; B 93 335 507 624 ;
+C 95 ; WX 600 ; N underscore ; B -32 -290 632 -210 ;
+C 96 ; WX 600 ; N quoteleft ; B 260 304 465 613 ;
+C 97 ; WX 600 ; N a ; B 52 -35 561 452 ;
+C 98 ; WX 600 ; N b ; B 2 -35 561 624 ;
+C 99 ; WX 600 ; N c ; B 64 -35 555 452 ;
+C 100 ; WX 600 ; N d ; B 43 -35 603 624 ;
+C 101 ; WX 600 ; N e ; B 43 -35 540 452 ;
+C 102 ; WX 600 ; N f ; B 85 -20 561 624 ; L i fi ; L l fl ;
+C 103 ; WX 600 ; N g ; B 43 -207 582 452 ;
+C 104 ; WX 600 ; N h ; B 23 -20 571 624 ;
+C 105 ; WX 600 ; N i ; B 72 -20 528 665 ;
+C 106 ; WX 600 ; N j ; B 127 -207 478 665 ;
+C 107 ; WX 600 ; N k ; B 43 -20 561 624 ;
+C 108 ; WX 600 ; N l ; B 72 -20 528 624 ;
+C 109 ; WX 600 ; N m ; B -9 -20 613 452 ;
+C 110 ; WX 600 ; N n ; B 33 -20 561 452 ;
+C 111 ; WX 600 ; N o ; B 52 -35 548 452 ;
+C 112 ; WX 600 ; N p ; B 2 -207 561 452 ;
+C 113 ; WX 600 ; N q ; B 43 -207 603 452 ;
+C 114 ; WX 600 ; N r ; B 64 -20 561 448 ;
+C 115 ; WX 600 ; N s ; B 83 -35 517 452 ;
+C 116 ; WX 600 ; N t ; B 23 -35 519 582 ;
+C 117 ; WX 600 ; N u ; B 23 -35 561 437 ;
+C 118 ; WX 600 ; N v ; B 10 -20 590 437 ;
+C 119 ; WX 600 ; N w ; B 10 -20 590 437 ;
+C 120 ; WX 600 ; N x ; B 31 -20 569 437 ;
+C 121 ; WX 600 ; N y ; B 31 -207 569 437 ;
+C 122 ; WX 600 ; N z ; B 95 -20 509 437 ;
+C 123 ; WX 600 ; N braceleft ; B 177 -144 423 624 ;
+C 124 ; WX 600 ; N bar ; B 260 -144 340 624 ;
+C 125 ; WX 600 ; N braceright ; B 177 -144 423 624 ;
+C 126 ; WX 600 ; N asciitilde ; B 72 189 528 373 ;
+C 161 ; WX 600 ; N exclamdown ; B 240 -207 360 415 ;
+C 162 ; WX 600 ; N cent ; B 93 -19 489 665 ;
+C 163 ; WX 600 ; N sterling ; B 43 -20 540 598 ;
+C 164 ; WX 600 ; N fraction ; B 31 120 569 492 ;
+C 165 ; WX 600 ; N yen ; B 31 -20 569 583 ;
+C 166 ; WX 600 ; N florin ; B 67 -113 538 639 ;
+C 167 ; WX 600 ; N section ; B 46 -87 554 629 ;
+C 168 ; WX 600 ; N currency ; B 83 75 517 509 ;
+C 169 ; WX 600 ; N quotesingle ; B 230 304 370 613 ;
+C 170 ; WX 600 ; N quotedblleft ; B 93 340 507 619 ;
+C 171 ; WX 600 ; N guillemotleft ; B 43 -20 561 437 ;
+C 172 ; WX 600 ; N guilsinglleft ; B 43 -20 332 437 ;
+C 173 ; WX 600 ; N guilsinglright ; B 273 -20 561 437 ;
+C 174 ; WX 600 ; N fi ; B -10 -20 610 665 ;
+C 175 ; WX 600 ; N fl ; B -10 -20 610 624 ;
+C 177 ; WX 600 ; N endash ; B 52 241 548 321 ;
+C 178 ; WX 600 ; N dagger ; B 104 -82 496 624 ;
+C 179 ; WX 600 ; N daggerdbl ; B 104 -82 496 624 ;
+C 180 ; WX 600 ; N periodcentered ; B 250 266 350 346 ;
+C 182 ; WX 600 ; N paragraph ; B 59 -87 545 629 ;
+C 183 ; WX 600 ; N bullet ; B 260 266 340 346 ;
+C 184 ; WX 600 ; N quotesinglbase ; B 135 -165 340 144 ;
+C 185 ; WX 600 ; N quotedblbase ; B 93 -139 507 139 ;
+C 186 ; WX 600 ; N quotedblright ; B 93 340 507 619 ;
+C 187 ; WX 600 ; N guillemotright ; B 43 -20 561 437 ;
+C 188 ; WX 600 ; N ellipsis ; B 60 -5 540 75 ;
+C 189 ; WX 600 ; N perthousand ; B 10 -35 590 639 ;
+C 191 ; WX 600 ; N questiondown ; B 93 -207 486 415 ;
+C 193 ; WX 600 ; N grave ; B 135 450 340 639 ;
+C 194 ; WX 600 ; N acute ; B 260 450 465 639 ;
+C 195 ; WX 600 ; N circumflex ; B 135 450 465 624 ;
+C 196 ; WX 600 ; N tilde ; B 125 441 475 580 ;
+C 197 ; WX 600 ; N macron ; B 135 476 465 556 ;
+C 198 ; WX 600 ; N breve ; B 135 450 465 624 ;
+C 199 ; WX 600 ; N dotaccent ; B 260 491 340 571 ;
+C 200 ; WX 600 ; N dieresis ; B 156 491 444 571 ;
+C 202 ; WX 600 ; N ring ; B 187 413 413 634 ;
+C 203 ; WX 600 ; N cedilla ; B 190 -186 397 40 ;
+C 205 ; WX 600 ; N hungarumlaut ; B 135 450 465 639 ;
+C 206 ; WX 600 ; N ogonek ; B 260 -165 453 40 ;
+C 207 ; WX 600 ; N caron ; B 135 450 465 624 ;
+C 208 ; WX 600 ; N emdash ; B -19 241 619 321 ;
+C 225 ; WX 600 ; N AE ; B -10 -20 610 583 ;
+C 227 ; WX 600 ; N ordfeminine ; B 127 179 478 598 ;
+C 232 ; WX 600 ; N Lslash ; B 23 -20 561 583 ;
+C 233 ; WX 600 ; N Oslash ; B 20 -61 580 623 ;
+C 234 ; WX 600 ; N OE ; B -10 -20 610 583 ;
+C 235 ; WX 600 ; N ordmasculine ; B 131 179 469 598 ;
+C 241 ; WX 600 ; N ae ; B -10 -35 600 452 ;
+C 245 ; WX 600 ; N dotlessi ; B 72 -20 528 437 ;
+C 248 ; WX 600 ; N lslash ; B 72 -20 528 624 ;
+C 249 ; WX 600 ; N oslash ; B 33 -61 563 478 ;
+C 250 ; WX 600 ; N oe ; B -10 -35 600 452 ;
+C 251 ; WX 600 ; N germandbls ; B 23 -35 519 624 ;
+C -1 ; WX 600 ; N Aacute ; B -11 -20 611 789 ;
+C -1 ; WX 600 ; N Acircumflex ; B -11 -20 611 774 ;
+C -1 ; WX 600 ; N Adieresis ; B -11 -20 611 721 ;
+C -1 ; WX 600 ; N Agrave ; B -11 -20 611 789 ;
+C -1 ; WX 600 ; N Aring ; B -11 -20 611 795 ;
+C -1 ; WX 600 ; N Atilde ; B -11 -20 611 730 ;
+C -1 ; WX 600 ; N Ccedilla ; B 43 -186 554 598 ;
+C -1 ; WX 600 ; N Eacute ; B 23 -20 540 789 ;
+C -1 ; WX 600 ; N Ecircumflex ; B 23 -20 540 774 ;
+C -1 ; WX 600 ; N Edieresis ; B 23 -20 540 721 ;
+C -1 ; WX 600 ; N Egrave ; B 23 -20 540 789 ;
+C -1 ; WX 600 ; N Eth ; B 23 -20 540 583 ;
+C -1 ; WX 600 ; N Gcaron ; B 43 -35 582 774 ;
+C -1 ; WX 600 ; N IJ ; B -10 -35 610 583 ;
+C -1 ; WX 600 ; N Iacute ; B 93 -20 507 789 ;
+C -1 ; WX 600 ; N Icircumflex ; B 93 -20 507 774 ;
+C -1 ; WX 600 ; N Idieresis ; B 93 -20 507 721 ;
+C -1 ; WX 600 ; N Idot ; B 93 -20 507 721 ;
+C -1 ; WX 600 ; N Igrave ; B 93 -20 507 789 ;
+C -1 ; WX 600 ; N LL ; B -20 -20 620 583 ;
+C -1 ; WX 600 ; N Ntilde ; B 2 -20 582 730 ;
+C -1 ; WX 600 ; N Oacute ; B 31 -35 569 789 ;
+C -1 ; WX 600 ; N Ocircumflex ; B 31 -35 569 774 ;
+C -1 ; WX 600 ; N Odieresis ; B 31 -35 569 721 ;
+C -1 ; WX 600 ; N Ograve ; B 31 -35 569 789 ;
+C -1 ; WX 600 ; N Otilde ; B 31 -35 569 730 ;
+C -1 ; WX 600 ; N Scaron ; B 72 -35 528 774 ;
+C -1 ; WX 600 ; N Scedilla ; B 72 -186 528 598 ;
+C -1 ; WX 600 ; N Thorn ; B 23 -20 539 583 ;
+C -1 ; WX 600 ; N Uacute ; B 20 -35 580 789 ;
+C -1 ; WX 600 ; N Ucircumflex ; B 20 -35 580 774 ;
+C -1 ; WX 600 ; N Udieresis ; B 20 -35 580 721 ;
+C -1 ; WX 600 ; N Ugrave ; B 20 -35 580 789 ;
+C -1 ; WX 600 ; N Yacute ; B 31 -20 569 789 ;
+C -1 ; WX 600 ; N Ydieresis ; B 31 -20 569 721 ;
+C -1 ; WX 600 ; N Zcaron ; B 83 -20 517 774 ;
+C -1 ; WX 600 ; N aacute ; B 52 -35 561 660 ;
+C -1 ; WX 600 ; N acircumflex ; B 52 -35 561 653 ;
+C -1 ; WX 600 ; N adieresis ; B 52 -35 561 592 ;
+C -1 ; WX 600 ; N agrave ; B 52 -35 561 660 ;
+C -1 ; WX 600 ; N aring ; B 52 -35 561 686 ;
+C -1 ; WX 600 ; N arrowboth ; B -40 110 640 490 ;
+C -1 ; WX 600 ; N arrowdown ; B 110 -20 490 639 ;
+C -1 ; WX 600 ; N arrowleft ; B -40 110 640 490 ;
+C -1 ; WX 600 ; N arrowright ; B -40 110 640 490 ;
+C -1 ; WX 600 ; N arrowup ; B 110 -20 490 639 ;
+C -1 ; WX 600 ; N atilde ; B 52 -35 561 618 ;
+C -1 ; WX 600 ; N brokenbar ; B 260 -144 340 624 ;
+C -1 ; WX 600 ; N ccedilla ; B 64 -186 555 452 ;
+C -1 ; WX 600 ; N center ; B 0 -20 600 624 ;
+C -1 ; WX 600 ; N copyright ; B -20 -35 620 598 ;
+C -1 ; WX 600 ; N dectab ; B -5 -20 605 248 ;
+C -1 ; WX 600 ; N degree ; B 135 294 465 624 ;
+C -1 ; WX 600 ; N divide ; B 52 51 548 531 ;
+C -1 ; WX 600 ; N down ; B 154 -20 446 452 ;
+C -1 ; WX 600 ; N eacute ; B 43 -35 540 664 ;
+C -1 ; WX 600 ; N ecircumflex ; B 43 -35 540 653 ;
+C -1 ; WX 600 ; N edieresis ; B 43 -35 540 592 ;
+C -1 ; WX 600 ; N egrave ; B 43 -35 540 664 ;
+C -1 ; WX 600 ; N eth ; B 52 -35 548 639 ;
+C -1 ; WX 600 ; N format ; B -15 -207 65 624 ;
+C -1 ; WX 600 ; N gcaron ; B 43 -207 582 645 ;
+C -1 ; WX 600 ; N graybox ; B 35 -40 565 640 ;
+C -1 ; WX 600 ; N iacute ; B 72 -20 528 660 ;
+C -1 ; WX 600 ; N icircumflex ; B 72 -20 528 634 ;
+C -1 ; WX 600 ; N idieresis ; B 72 -20 528 592 ;
+C -1 ; WX 600 ; N igrave ; B 72 -20 528 656 ;
+C -1 ; WX 600 ; N ij ; B 10 -207 550 665 ;
+C -1 ; WX 600 ; N indent ; B 54 60 546 352 ;
+C -1 ; WX 600 ; N largebullet ; B 260 266 340 346 ;
+C -1 ; WX 600 ; N left ; B 54 60 546 352 ;
+C -1 ; WX 600 ; N lira ; B 43 -20 540 598 ;
+C -1 ; WX 600 ; N ll ; B 0 -20 600 624 ;
+C -1 ; WX 600 ; N logicalnot ; B 52 154 548 394 ;
+C -1 ; WX 600 ; N merge ; B 154 -20 446 452 ;
+C -1 ; WX 600 ; N minus ; B 52 241 548 321 ;
+C -1 ; WX 600 ; N mu ; B 23 -207 561 437 ;
+C -1 ; WX 600 ; N multiply ; B 82 12 518 470 ;
+C -1 ; WX 600 ; N notegraphic ; B 150 -5 450 639 ;
+C -1 ; WX 600 ; N ntilde ; B 33 -20 561 618 ;
+C -1 ; WX 600 ; N oacute ; B 52 -35 548 649 ;
+C -1 ; WX 600 ; N ocircumflex ; B 52 -35 548 653 ;
+C -1 ; WX 600 ; N odieresis ; B 52 -35 548 592 ;
+C -1 ; WX 600 ; N ograve ; B 52 -35 548 649 ;
+C -1 ; WX 600 ; N onehalf ; B -10 -20 610 624 ;
+C -1 ; WX 600 ; N onequarter ; B -10 -20 610 624 ;
+C -1 ; WX 600 ; N onesuperior ; B 160 200 440 624 ;
+C -1 ; WX 600 ; N otilde ; B 52 -35 548 597 ;
+C -1 ; WX 600 ; N overscore ; B -32 559 632 639 ;
+C -1 ; WX 600 ; N plusminus ; B 52 -20 548 550 ;
+C -1 ; WX 600 ; N prescription ; B 23 -20 609 583 ;
+C -1 ; WX 600 ; N registered ; B -20 -35 620 598 ;
+C -1 ; WX 600 ; N return ; B -24 -20 624 608 ;
+C -1 ; WX 600 ; N scaron ; B 83 -35 517 645 ;
+C -1 ; WX 600 ; N scedilla ; B 83 -186 517 452 ;
+C -1 ; WX 600 ; N square ; B -24 -20 624 608 ;
+C -1 ; WX 600 ; N stop ; B -24 -20 624 608 ;
+C -1 ; WX 600 ; N tab ; B -24 -20 624 608 ;
+C -1 ; WX 600 ; N thorn ; B 2 -207 561 624 ;
+C -1 ; WX 600 ; N threequarters ; B -10 -20 610 639 ;
+C -1 ; WX 600 ; N threesuperior ; B 155 191 452 639 ;
+C -1 ; WX 600 ; N trademark ; B -20 230 620 583 ;
+C -1 ; WX 600 ; N twosuperior ; B 140 200 431 639 ;
+C -1 ; WX 600 ; N uacute ; B 23 -35 561 656 ;
+C -1 ; WX 600 ; N ucircumflex ; B 23 -35 561 634 ;
+C -1 ; WX 600 ; N udieresis ; B 23 -35 561 592 ;
+C -1 ; WX 600 ; N ugrave ; B 23 -35 561 656 ;
+C -1 ; WX 600 ; N up ; B 154 -20 446 452 ;
+C -1 ; WX 600 ; N yacute ; B 31 -207 569 656 ;
+C -1 ; WX 600 ; N ydieresis ; B 31 -207 569 571 ;
+C -1 ; WX 600 ; N zcaron ; B 95 -20 509 645 ;
+EndCharMetrics
+StartComposites 58
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 0 146 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 0 0 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 0 146 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 0 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 0 0 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 0 146 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 0 0 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 0 146 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 0 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 0 146 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 0 146 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 0 146 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 0 146 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 0 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 0 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 0 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 0 0 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 146 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 0 146 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 0 146 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 146 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex 0 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis 0 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 0 146 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 0 146 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 0 146 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 0 146 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ;
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 0 146 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 0 146 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 0 146 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 0 146 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 0 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 0 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 0 0 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 0 146 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 0 146 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 0 146 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 0 146 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 0 146 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 0 146 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 0 146 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 0 146 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ;
+EndComposites
+EndFontMetrics
diff --git a/samples/printing/CourBo.afm b/samples/printing/CourBo.afm
new file mode 100644
index 0000000000..5a2fbdc071
--- /dev/null
+++ b/samples/printing/CourBo.afm
@@ -0,0 +1,341 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1984 Adobe Systems Incorporated. 	All Rights Reserved.
+Comment Creation Date:Wed Feb 25 16:06:47 PST 1987
+FontName Courier-Bold
+EncodingScheme AdobeStandardEncoding
+FullName Courier Bold
+FamilyName Courier
+Weight Bold
+ItalicAngle 0.0
+IsFixedPitch true
+UnderlinePosition -85
+UnderlineThickness 100
+Version 001.003
+FontBBox -100 -350 700 855
+CapHeight 633
+XHeight 487
+Descender -257
+Ascender 674
+StartCharMetrics 260
+C 32 ; WX 600 ; N space ; B 500 -100 700 100 ;
+C 33 ; WX 600 ; N exclam ; B 170 -65 430 689 ;
+C 34 ; WX 600 ; N quotedbl ; B 66 254 534 663 ;
+C 35 ; WX 600 ; N numbersign ; B 12 -142 588 725 ;
+C 36 ; WX 600 ; N dollar ; B 33 -173 567 735 ;
+C 37 ; WX 600 ; N percent ; B 7 -65 593 689 ;
+C 38 ; WX 600 ; N ampersand ; B 25 -65 558 600 ;
+C 39 ; WX 600 ; N quoteright ; B 75 244 400 674 ;
+C 40 ; WX 600 ; N parenleft ; B 214 -204 538 683 ;
+C 41 ; WX 600 ; N parenright ; B 67 -204 391 683 ;
+C 42 ; WX 600 ; N asterisk ; B 33 150 567 674 ;
+C 43 ; WX 600 ; N plus ; B -8 -48 608 610 ;
+C 44 ; WX 600 ; N comma ; B 75 -215 400 215 ;
+C 45 ; WX 600 ; N hyphen ; B -8 181 608 381 ;
+C 46 ; WX 600 ; N period ; B 190 -50 410 150 ;
+C 47 ; WX 600 ; N slash ; B 33 -163 567 746 ;
+C 48 ; WX 600 ; N zero ; B 33 -65 567 689 ;
+C 49 ; WX 600 ; N one ; B 33 -50 567 674 ;
+C 50 ; WX 600 ; N two ; B 4 -50 558 689 ;
+C 51 ; WX 600 ; N three ; B 16 -65 579 689 ;
+C 52 ; WX 600 ; N four ; B 25 -50 558 674 ;
+C 53 ; WX 600 ; N five ; B 16 -65 579 674 ;
+C 54 ; WX 600 ; N six ; B 56 -65 590 689 ;
+C 55 ; WX 600 ; N seven ; B 25 -50 558 674 ;
+C 56 ; WX 600 ; N eight ; B 33 -65 567 689 ;
+C 57 ; WX 600 ; N nine ; B 56 -65 590 689 ;
+C 58 ; WX 600 ; N colon ; B 190 -50 410 472 ;
+C 59 ; WX 600 ; N semicolon ; B 79 -176 410 472 ;
+C 60 ; WX 600 ; N less ; B -8 -48 608 610 ;
+C 61 ; WX 600 ; N equal ; B -29 88 629 474 ;
+C 62 ; WX 600 ; N greater ; B -8 -48 608 610 ;
+C 63 ; WX 600 ; N question ; B 54 -65 567 648 ;
+C 64 ; WX 600 ; N at ; B 26 -142 559 705 ;
+C 65 ; WX 600 ; N A ; B -71 -50 671 633 ;
+C 66 ; WX 600 ; N B ; B -37 -50 621 633 ;
+C 67 ; WX 600 ; N C ; B -17 -65 614 648 ;
+C 68 ; WX 600 ; N D ; B -37 -50 600 633 ;
+C 69 ; WX 600 ; N E ; B -37 -50 600 633 ;
+C 70 ; WX 600 ; N F ; B -37 -50 600 633 ;
+C 71 ; WX 600 ; N G ; B -17 -65 642 648 ;
+C 72 ; WX 600 ; N H ; B -27 -50 631 633 ;
+C 73 ; WX 600 ; N I ; B 33 -50 567 633 ;
+C 74 ; WX 600 ; N J ; B 4 -65 663 633 ;
+C 75 ; WX 600 ; N K ; B -37 -50 652 633 ;
+C 76 ; WX 600 ; N L ; B -17 -50 621 633 ;
+C 77 ; WX 600 ; N M ; B -69 -50 673 633 ;
+C 78 ; WX 600 ; N N ; B -58 -50 642 633 ;
+C 79 ; WX 600 ; N O ; B -29 -65 629 648 ;
+C 80 ; WX 600 ; N P ; B -37 -50 579 633 ;
+C 81 ; WX 600 ; N Q ; B -29 -196 629 648 ;
+C 82 ; WX 600 ; N R ; B -37 -50 669 633 ;
+C 83 ; WX 600 ; N S ; B 12 -65 588 648 ;
+C 84 ; WX 600 ; N T ; B -8 -50 608 633 ;
+C 85 ; WX 600 ; N U ; B -40 -65 640 633 ;
+C 86 ; WX 600 ; N V ; B -71 -50 671 633 ;
+C 87 ; WX 600 ; N W ; B -60 -50 660 633 ;
+C 88 ; WX 600 ; N X ; B -40 -50 640 633 ;
+C 89 ; WX 600 ; N Y ; B -29 -50 629 633 ;
+C 90 ; WX 600 ; N Z ; B 23 -50 577 633 ;
+C 91 ; WX 600 ; N bracketleft ; B 200 -204 525 674 ;
+C 92 ; WX 600 ; N backslash ; B 33 -163 567 746 ;
+C 93 ; WX 600 ; N bracketright ; B 75 -204 400 674 ;
+C 94 ; WX 600 ; N asciicircum ; B 33 275 567 674 ;
+C 95 ; WX 600 ; N underscore ; B -92 -350 692 -150 ;
+C 96 ; WX 600 ; N quoteleft ; B 200 244 525 674 ;
+C 97 ; WX 600 ; N a ; B -8 -65 621 502 ;
+C 98 ; WX 600 ; N b ; B -58 -65 621 674 ;
+C 99 ; WX 600 ; N c ; B 4 -65 615 502 ;
+C 100 ; WX 600 ; N d ; B -17 -65 663 674 ;
+C 101 ; WX 600 ; N e ; B -17 -65 600 502 ;
+C 102 ; WX 600 ; N f ; B 25 -50 621 674 ; L i fi ; L l fl ;
+C 103 ; WX 600 ; N g ; B -17 -257 642 502 ;
+C 104 ; WX 600 ; N h ; B -37 -50 631 674 ;
+C 105 ; WX 600 ; N i ; B 12 -50 588 725 ;
+C 106 ; WX 600 ; N j ; B 67 -257 538 725 ;
+C 107 ; WX 600 ; N k ; B -17 -50 621 674 ;
+C 108 ; WX 600 ; N l ; B 12 -50 588 674 ;
+C 109 ; WX 600 ; N m ; B -69 -50 673 502 ;
+C 110 ; WX 600 ; N n ; B -27 -50 621 502 ;
+C 111 ; WX 600 ; N o ; B -8 -65 608 502 ;
+C 112 ; WX 600 ; N p ; B -58 -257 621 502 ;
+C 113 ; WX 600 ; N q ; B -17 -257 663 502 ;
+C 114 ; WX 600 ; N r ; B 4 -50 621 501 ;
+C 115 ; WX 600 ; N s ; B 23 -65 577 502 ;
+C 116 ; WX 600 ; N t ; B -37 -65 579 642 ;
+C 117 ; WX 600 ; N u ; B -37 -65 621 487 ;
+C 118 ; WX 600 ; N v ; B -50 -50 650 487 ;
+C 119 ; WX 600 ; N w ; B -50 -50 650 487 ;
+C 120 ; WX 600 ; N x ; B -29 -50 629 487 ;
+C 121 ; WX 600 ; N y ; B -29 -257 629 487 ;
+C 122 ; WX 600 ; N z ; B 35 -50 569 487 ;
+C 123 ; WX 600 ; N braceleft ; B 117 -204 483 674 ;
+C 124 ; WX 600 ; N bar ; B 200 -204 400 674 ;
+C 125 ; WX 600 ; N braceright ; B 117 -204 483 674 ;
+C 126 ; WX 600 ; N asciitilde ; B 12 129 588 433 ;
+C 161 ; WX 600 ; N exclamdown ; B 170 -257 430 475 ;
+C 162 ; WX 600 ; N cent ; B 33 -79 549 725 ;
+C 163 ; WX 600 ; N sterling ; B -17 -50 600 648 ;
+C 164 ; WX 600 ; N fraction ; B -29 60 629 552 ;
+C 165 ; WX 600 ; N yen ; B -29 -50 629 633 ;
+C 166 ; WX 600 ; N florin ; B 7 -173 598 689 ;
+C 167 ; WX 600 ; N section ; B -14 -147 614 689 ;
+C 168 ; WX 600 ; N currency ; B 23 15 577 569 ;
+C 169 ; WX 600 ; N quotesingle ; B 170 244 430 674 ;
+C 170 ; WX 600 ; N quotedblleft ; B 33 280 567 678 ;
+C 171 ; WX 600 ; N guillemotleft ; B -17 -50 621 487 ;
+C 172 ; WX 600 ; N guilsinglleft ; B -17 -50 392 487 ;
+C 173 ; WX 600 ; N guilsinglright ; B 213 -50 621 487 ;
+C 174 ; WX 600 ; N fi ; B -70 -50 670 725 ;
+C 175 ; WX 600 ; N fl ; B -70 -50 670 674 ;
+C 177 ; WX 600 ; N endash ; B -8 181 608 381 ;
+C 178 ; WX 600 ; N dagger ; B 44 -142 556 674 ;
+C 179 ; WX 600 ; N daggerdbl ; B 44 -142 556 674 ;
+C 180 ; WX 600 ; N periodcentered ; B 190 206 410 406 ;
+C 182 ; WX 600 ; N paragraph ; B -1 -147 605 689 ;
+C 183 ; WX 600 ; N bullet ; B 200 206 400 406 ;
+C 184 ; WX 600 ; N quotesinglbase ; B 75 -225 400 204 ;
+C 185 ; WX 600 ; N quotedblbase ; B 33 -199 567 199 ;
+C 186 ; WX 600 ; N quotedblright ; B 33 280 567 678 ;
+C 187 ; WX 600 ; N guillemotright ; B -17 -50 621 487 ;
+C 188 ; WX 600 ; N ellipsis ; B 0 -65 600 135 ;
+C 189 ; WX 600 ; N perthousand ; B -50 -65 650 689 ;
+C 191 ; WX 600 ; N questiondown ; B 33 -257 546 475 ;
+C 193 ; WX 600 ; N grave ; B 75 390 400 689 ;
+C 194 ; WX 600 ; N acute ; B 200 390 525 689 ;
+C 195 ; WX 600 ; N circumflex ; B 75 390 525 674 ;
+C 196 ; WX 600 ; N tilde ; B 65 381 535 640 ;
+C 197 ; WX 600 ; N macron ; B 75 416 525 616 ;
+C 198 ; WX 600 ; N breve ; B 75 390 525 674 ;
+C 199 ; WX 600 ; N dotaccent ; B 200 431 400 631 ;
+C 200 ; WX 600 ; N dieresis ; B 96 431 504 631 ;
+C 202 ; WX 600 ; N ring ; B 127 353 473 694 ;
+C 203 ; WX 600 ; N cedilla ; B 130 -246 457 100 ;
+C 205 ; WX 600 ; N hungarumlaut ; B 75 390 525 689 ;
+C 206 ; WX 600 ; N ogonek ; B 200 -225 513 100 ;
+C 207 ; WX 600 ; N caron ; B 75 390 525 674 ;
+C 208 ; WX 600 ; N emdash ; B -79 181 679 381 ;
+C 225 ; WX 600 ; N AE ; B -70 -50 670 633 ;
+C 227 ; WX 600 ; N ordfeminine ; B 68 120 539 649 ;
+C 232 ; WX 600 ; N Lslash ; B -37 -50 621 633 ;
+C 233 ; WX 600 ; N Oslash ; B -40 -121 640 683 ;
+C 234 ; WX 600 ; N OE ; B -70 -50 670 633 ;
+C 235 ; WX 600 ; N ordmasculine ; B 72 120 530 649 ;
+C 241 ; WX 600 ; N ae ; B -70 -65 660 502 ;
+C 245 ; WX 600 ; N dotlessi ; B 12 -50 588 487 ;
+C 248 ; WX 600 ; N lslash ; B 12 -50 588 674 ;
+C 249 ; WX 600 ; N oslash ; B -27 -121 623 538 ;
+C 250 ; WX 600 ; N oe ; B -70 -65 660 502 ;
+C 251 ; WX 600 ; N germandbls ; B -37 -65 579 674 ;
+C -1 ; WX 600 ; N Aacute ; B -71 -50 671 839 ;
+C -1 ; WX 600 ; N Acircumflex ; B -71 -50 671 824 ;
+C -1 ; WX 600 ; N Adieresis ; B -71 -50 671 781 ;
+C -1 ; WX 600 ; N Agrave ; B -71 -50 671 839 ;
+C -1 ; WX 600 ; N Aring ; B -71 -50 671 855 ;
+C -1 ; WX 600 ; N Atilde ; B -71 -50 671 790 ;
+C -1 ; WX 600 ; N Ccedilla ; B -17 -246 614 648 ;
+C -1 ; WX 600 ; N Eacute ; B -37 -50 600 839 ;
+C -1 ; WX 600 ; N Ecircumflex ; B -37 -50 600 824 ;
+C -1 ; WX 600 ; N Edieresis ; B -37 -50 600 781 ;
+C -1 ; WX 600 ; N Egrave ; B -37 -50 600 839 ;
+C -1 ; WX 600 ; N Eth ; B -37 -50 600 633 ;
+C -1 ; WX 600 ; N Gcaron ; B -17 -65 642 824 ;
+C -1 ; WX 600 ; N IJ ; B -70 -65 670 633 ;
+C -1 ; WX 600 ; N Iacute ; B 33 -50 567 839 ;
+C -1 ; WX 600 ; N Icircumflex ; B 33 -50 567 824 ;
+C -1 ; WX 600 ; N Idieresis ; B 33 -50 567 781 ;
+C -1 ; WX 600 ; N Idot ; B 33 -50 567 781 ;
+C -1 ; WX 600 ; N Igrave ; B 33 -50 567 839 ;
+C -1 ; WX 600 ; N LL ; B -80 -50 680 633 ;
+C -1 ; WX 600 ; N Ntilde ; B -58 -50 642 790 ;
+C -1 ; WX 600 ; N Oacute ; B -29 -65 629 839 ;
+C -1 ; WX 600 ; N Ocircumflex ; B -29 -65 629 824 ;
+C -1 ; WX 600 ; N Odieresis ; B -29 -65 629 781 ;
+C -1 ; WX 600 ; N Ograve ; B -29 -65 629 839 ;
+C -1 ; WX 600 ; N Otilde ; B -29 -65 629 790 ;
+C -1 ; WX 600 ; N Scaron ; B 12 -65 588 824 ;
+C -1 ; WX 600 ; N Scedilla ; B 12 -246 588 648 ;
+C -1 ; WX 600 ; N Thorn ; B -37 -50 599 633 ;
+C -1 ; WX 600 ; N Uacute ; B -40 -65 640 839 ;
+C -1 ; WX 600 ; N Ucircumflex ; B -40 -65 640 824 ;
+C -1 ; WX 600 ; N Udieresis ; B -40 -65 640 781 ;
+C -1 ; WX 600 ; N Ugrave ; B -40 -65 640 839 ;
+C -1 ; WX 600 ; N Yacute ; B -29 -50 629 839 ;
+C -1 ; WX 600 ; N Ydieresis ; B -29 -50 629 781 ;
+C -1 ; WX 600 ; N Zcaron ; B 23 -50 577 824 ;
+C -1 ; WX 600 ; N aacute ; B -8 -65 621 710 ;
+C -1 ; WX 600 ; N acircumflex ; B -8 -65 621 703 ;
+C -1 ; WX 600 ; N adieresis ; B -8 -65 621 652 ;
+C -1 ; WX 600 ; N agrave ; B -8 -65 621 710 ;
+C -1 ; WX 600 ; N aring ; B -8 -65 621 746 ;
+C -1 ; WX 600 ; N arrowboth ; B -100 50 700 550 ;
+C -1 ; WX 600 ; N arrowdown ; B 50 -50 550 689 ;
+C -1 ; WX 600 ; N arrowleft ; B -100 50 700 550 ;
+C -1 ; WX 600 ; N arrowright ; B -100 50 700 550 ;
+C -1 ; WX 600 ; N arrowup ; B 50 -50 550 689 ;
+C -1 ; WX 600 ; N atilde ; B -8 -65 621 678 ;
+C -1 ; WX 600 ; N brokenbar ; B 200 -204 400 674 ;
+C -1 ; WX 600 ; N ccedilla ; B 4 -246 615 502 ;
+C -1 ; WX 600 ; N center ; B -60 -50 660 684 ;
+C -1 ; WX 600 ; N copyright ; B -80 -65 680 648 ;
+C -1 ; WX 600 ; N dectab ; B -65 -50 665 308 ;
+C -1 ; WX 600 ; N degree ; B 75 234 525 674 ;
+C -1 ; WX 600 ; N divide ; B -8 -9 608 591 ;
+C -1 ; WX 600 ; N down ; B 94 -50 506 502 ;
+C -1 ; WX 600 ; N eacute ; B -17 -65 600 714 ;
+C -1 ; WX 600 ; N ecircumflex ; B -17 -65 600 703 ;
+C -1 ; WX 600 ; N edieresis ; B -17 -65 600 652 ;
+C -1 ; WX 600 ; N egrave ; B -17 -65 600 714 ;
+C -1 ; WX 600 ; N eth ; B -8 -65 608 689 ;
+C -1 ; WX 600 ; N format ; B -75 -257 125 674 ;
+C -1 ; WX 600 ; N gcaron ; B -17 -257 642 695 ;
+C -1 ; WX 600 ; N graybox ; B -25 -100 625 700 ;
+C -1 ; WX 600 ; N iacute ; B 12 -50 588 710 ;
+C -1 ; WX 600 ; N icircumflex ; B 12 -50 588 684 ;
+C -1 ; WX 600 ; N idieresis ; B 12 -50 588 652 ;
+C -1 ; WX 600 ; N igrave ; B 12 -50 588 706 ;
+C -1 ; WX 600 ; N ij ; B -50 -257 610 725 ;
+C -1 ; WX 600 ; N indent ; B -6 0 606 412 ;
+C -1 ; WX 600 ; N largebullet ; B 200 206 400 406 ;
+C -1 ; WX 600 ; N left ; B -6 0 606 412 ;
+C -1 ; WX 600 ; N lira ; B -17 -50 600 648 ;
+C -1 ; WX 600 ; N ll ; B -60 -50 660 674 ;
+C -1 ; WX 600 ; N logicalnot ; B -8 94 608 454 ;
+C -1 ; WX 600 ; N merge ; B 94 -50 506 502 ;
+C -1 ; WX 600 ; N minus ; B -8 181 608 381 ;
+C -1 ; WX 600 ; N mu ; B -37 -257 621 487 ;
+C -1 ; WX 600 ; N multiply ; B 22 -48 578 530 ;
+C -1 ; WX 600 ; N notegraphic ; B 80 -65 520 689 ;
+C -1 ; WX 600 ; N ntilde ; B -27 -50 621 678 ;
+C -1 ; WX 600 ; N oacute ; B -8 -65 608 699 ;
+C -1 ; WX 600 ; N ocircumflex ; B -8 -65 608 703 ;
+C -1 ; WX 600 ; N odieresis ; B -8 -65 608 652 ;
+C -1 ; WX 600 ; N ograve ; B -8 -65 608 699 ;
+C -1 ; WX 600 ; N onehalf ; B -70 -65 670 674 ;
+C -1 ; WX 600 ; N onequarter ; B -70 -50 670 674 ;
+C -1 ; WX 600 ; N onesuperior ; B 100 140 500 674 ;
+C -1 ; WX 600 ; N otilde ; B -8 -65 608 657 ;
+C -1 ; WX 600 ; N overscore ; B -92 489 692 689 ;
+C -1 ; WX 600 ; N plusminus ; B -8 -50 608 610 ;
+C -1 ; WX 600 ; N prescription ; B -37 -50 669 633 ;
+C -1 ; WX 600 ; N registered ; B -80 -65 680 648 ;
+C -1 ; WX 600 ; N return ; B -84 -50 684 668 ;
+C -1 ; WX 600 ; N scaron ; B 23 -65 577 695 ;
+C -1 ; WX 600 ; N scedilla ; B 23 -246 577 502 ;
+C -1 ; WX 600 ; N square ; B -84 -50 684 668 ;
+C -1 ; WX 600 ; N stop ; B -84 -50 684 668 ;
+C -1 ; WX 600 ; N tab ; B -84 -50 684 668 ;
+C -1 ; WX 600 ; N thorn ; B -58 -257 621 674 ;
+C -1 ; WX 600 ; N threequarters ; B -70 -50 670 689 ;
+C -1 ; WX 600 ; N threesuperior ; B 95 131 512 689 ;
+C -1 ; WX 600 ; N trademark ; B -80 170 680 633 ;
+C -1 ; WX 600 ; N twosuperior ; B 80 140 491 689 ;
+C -1 ; WX 600 ; N uacute ; B -37 -65 621 706 ;
+C -1 ; WX 600 ; N ucircumflex ; B -37 -65 621 684 ;
+C -1 ; WX 600 ; N udieresis ; B -37 -65 621 652 ;
+C -1 ; WX 600 ; N ugrave ; B -37 -65 621 706 ;
+C -1 ; WX 600 ; N up ; B 94 -50 506 502 ;
+C -1 ; WX 600 ; N yacute ; B -29 -257 629 706 ;
+C -1 ; WX 600 ; N ydieresis ; B -29 -257 629 631 ;
+C -1 ; WX 600 ; N zcaron ; B 35 -50 569 695 ;
+EndCharMetrics
+StartComposites 58
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 0 146 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 0 0 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 0 146 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 0 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 0 0 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 0 146 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 0 0 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 0 146 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 0 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 0 146 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 0 146 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 0 146 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 0 146 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 0 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 0 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 0 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 0 0 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 146 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 0 146 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 0 146 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 146 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex 0 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis 0 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 0 146 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 0 146 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 0 146 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 0 146 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ;
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 0 146 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 0 146 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 0 146 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 0 146 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 0 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 0 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 0 0 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 0 146 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 0 146 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 0 146 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 0 146 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 0 146 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 0 146 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 0 146 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 0 146 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ;
+EndComposites
+EndFontMetrics
diff --git a/samples/printing/CourBoO.afm b/samples/printing/CourBoO.afm
new file mode 100644
index 0000000000..603eab5278
--- /dev/null
+++ b/samples/printing/CourBoO.afm
@@ -0,0 +1,341 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1984 Adobe Systems Incorporated. 	All Rights Reserved.
+Comment Creation Date:Wed Feb 25 16:19:52 PST 1987
+FontName Courier-BoldOblique
+EncodingScheme AdobeStandardEncoding
+FullName Courier Bold Oblique
+FamilyName Courier
+Weight Bold
+ItalicAngle -12.0
+IsFixedPitch true
+UnderlinePosition -85
+UnderlineThickness 100
+Version 001.003
+FontBBox -145 -350 817 855
+CapHeight 633
+XHeight 487
+Descender -257
+Ascender 674
+StartCharMetrics 260
+C 32 ; WX 600 ; N space ; B 500 -100 700 100 ;
+C 33 ; WX 600 ; N exclam ; B 197 -65 549 689 ;
+C 34 ; WX 600 ; N quotedbl ; B 171 254 654 663 ;
+C 35 ; WX 600 ; N numbersign ; B 52 -142 672 725 ;
+C 36 ; WX 600 ; N dollar ; B 51 -173 659 735 ;
+C 37 ; WX 600 ; N percent ; B 58 -65 671 689 ;
+C 38 ; WX 600 ; N ampersand ; B 52 -65 607 600 ;
+C 39 ; WX 600 ; N quoteright ; B 148 244 522 674 ;
+C 40 ; WX 600 ; N parenleft ; B 255 -204 662 683 ;
+C 41 ; WX 600 ; N parenright ; B 45 -204 452 683 ;
+C 42 ; WX 600 ; N asterisk ; B 131 150 665 674 ;
+C 43 ; WX 600 ; N plus ; B 52 -48 668 610 ;
+C 44 ; WX 600 ; N comma ; B 51 -215 424 215 ;
+C 45 ; WX 600 ; N hyphen ; B 52 181 668 381 ;
+C 46 ; WX 600 ; N period ; B 201 -50 421 150 ;
+C 47 ; WX 600 ; N slash ; B 20 -163 704 746 ;
+C 48 ; WX 600 ; N zero ; B 82 -65 649 689 ;
+C 49 ; WX 600 ; N one ; B 44 -50 578 674 ;
+C 50 ; WX 600 ; N two ; B 15 -50 656 689 ;
+C 51 ; WX 600 ; N three ; B 30 -65 659 689 ;
+C 52 ; WX 600 ; N four ; B 65 -50 618 674 ;
+C 53 ; WX 600 ; N five ; B 33 -65 660 674 ;
+C 54 ; WX 600 ; N six ; B 108 -65 712 689 ;
+C 55 ; WX 600 ; N seven ; B 136 -50 680 674 ;
+C 56 ; WX 600 ; N eight ; B 64 -65 655 689 ;
+C 57 ; WX 600 ; N nine ; B 67 -65 665 689 ;
+C 58 ; WX 600 ; N colon ; B 201 -50 489 472 ;
+C 59 ; WX 600 ; N semicolon ; B 63 -176 489 472 ;
+C 60 ; WX 600 ; N less ; B 52 -48 716 610 ;
+C 61 ; WX 600 ; N equal ; B 11 88 708 474 ;
+C 62 ; WX 600 ; N greater ; B 3 -48 668 610 ;
+C 63 ; WX 600 ; N question ; B 148 -65 657 648 ;
+C 64 ; WX 600 ; N at ; B 61 -142 640 705 ;
+C 65 ; WX 600 ; N A ; B -60 -50 682 633 ;
+C 66 ; WX 600 ; N B ; B -26 -50 670 633 ;
+C 67 ; WX 600 ; N C ; B 31 -65 713 648 ;
+C 68 ; WX 600 ; N D ; B -26 -50 670 633 ;
+C 69 ; WX 600 ; N E ; B -26 -50 692 633 ;
+C 70 ; WX 600 ; N F ; B -26 -50 713 633 ;
+C 71 ; WX 600 ; N G ; B 29 -65 713 648 ;
+C 72 ; WX 600 ; N H ; B -16 -50 723 633 ;
+C 73 ; WX 600 ; N I ; B 44 -50 680 633 ;
+C 74 ; WX 600 ; N J ; B 22 -65 776 633 ;
+C 75 ; WX 600 ; N K ; B -26 -50 744 633 ;
+C 76 ; WX 600 ; N L ; B -6 -50 665 633 ;
+C 77 ; WX 600 ; N M ; B -58 -50 776 633 ;
+C 78 ; WX 600 ; N N ; B -26 -50 755 633 ;
+C 79 ; WX 600 ; N O ; B 26 -65 696 648 ;
+C 80 ; WX 600 ; N P ; B -26 -50 666 633 ;
+C 81 ; WX 600 ; N Q ; B 26 -196 696 648 ;
+C 82 ; WX 600 ; N R ; B -26 -50 680 633 ;
+C 83 ; WX 600 ; N S ; B 23 -65 680 648 ;
+C 84 ; WX 600 ; N T ; B 72 -50 721 633 ;
+C 85 ; WX 600 ; N U ; B 61 -65 753 633 ;
+C 86 ; WX 600 ; N V ; B 42 -50 784 633 ;
+C 87 ; WX 600 ; N W ; B 50 -50 773 633 ;
+C 88 ; WX 600 ; N X ; B -29 -50 742 633 ;
+C 89 ; WX 600 ; N Y ; B 76 -50 742 633 ;
+C 90 ; WX 600 ; N Z ; B 34 -50 669 633 ;
+C 91 ; WX 600 ; N bracketleft ; B 178 -204 647 674 ;
+C 92 ; WX 600 ; N backslash ; B 170 -163 554 746 ;
+C 93 ; WX 600 ; N bracketright ; B 53 -204 522 674 ;
+C 94 ; WX 600 ; N asciicircum ; B 113 275 647 674 ;
+C 95 ; WX 600 ; N underscore ; B -145 -350 639 -150 ;
+C 96 ; WX 600 ; N quoteleft ; B 322 244 598 674 ;
+C 97 ; WX 600 ; N a ; B 16 -65 632 502 ;
+C 98 ; WX 600 ; N b ; B -47 -65 670 674 ;
+C 99 ; WX 600 ; N c ; B 44 -65 672 502 ;
+C 100 ; WX 600 ; N d ; B 23 -65 701 674 ;
+C 101 ; WX 600 ; N e ; B 25 -65 650 502 ;
+C 102 ; WX 600 ; N f ; B 36 -50 740 674 ; L i fi ; L l fl ;
+C 103 ; WX 600 ; N g ; B 25 -257 724 502 ;
+C 104 ; WX 600 ; N h ; B -16 -50 642 674 ;
+C 105 ; WX 600 ; N i ; B 23 -50 599 725 ;
+C 106 ; WX 600 ; N j ; B 34 -257 620 725 ;
+C 107 ; WX 600 ; N k ; B -6 -50 661 674 ;
+C 108 ; WX 600 ; N l ; B 23 -50 599 674 ;
+C 109 ; WX 600 ; N m ; B -58 -50 684 502 ;
+C 110 ; WX 600 ; N n ; B -16 -50 632 502 ;
+C 111 ; WX 600 ; N o ; B 34 -65 656 502 ;
+C 112 ; WX 600 ; N p ; B -91 -257 671 502 ;
+C 113 ; WX 600 ; N q ; B 27 -257 745 502 ;
+C 114 ; WX 600 ; N r ; B 15 -50 699 501 ;
+C 115 ; WX 600 ; N s ; B 34 -65 638 502 ;
+C 116 ; WX 600 ; N t ; B 45 -65 599 642 ;
+C 117 ; WX 600 ; N u ; B 45 -65 640 487 ;
+C 118 ; WX 600 ; N v ; B 32 -50 732 487 ;
+C 119 ; WX 600 ; N w ; B 32 -50 732 487 ;
+C 120 ; WX 600 ; N x ; B -18 -50 690 487 ;
+C 121 ; WX 600 ; N y ; B -62 -257 711 487 ;
+C 122 ; WX 600 ; N z ; B 46 -50 640 487 ;
+C 123 ; WX 600 ; N braceleft ; B 168 -204 605 674 ;
+C 124 ; WX 600 ; N bar ; B 178 -204 522 674 ;
+C 125 ; WX 600 ; N braceright ; B 95 -204 534 674 ;
+C 126 ; WX 600 ; N asciitilde ; B 67 129 652 433 ;
+C 161 ; WX 600 ; N exclamdown ; B 143 -257 490 475 ;
+C 162 ; WX 600 ; N cent ; B 96 -79 643 725 ;
+C 163 ; WX 600 ; N sterling ; B 15 -50 620 648 ;
+C 164 ; WX 600 ; N fraction ; B 5 60 725 552 ;
+C 165 ; WX 600 ; N yen ; B 77 -50 742 633 ;
+C 166 ; WX 600 ; N florin ; B -6 -173 720 689 ;
+C 167 ; WX 600 ; N section ; B 18 -147 697 689 ;
+C 168 ; WX 600 ; N currency ; B 47 15 677 569 ;
+C 169 ; WX 600 ; N quotesingle ; B 273 244 552 674 ;
+C 170 ; WX 600 ; N quotedblleft ; B 156 280 648 678 ;
+C 171 ; WX 600 ; N guillemotleft ; B 27 -50 703 487 ;
+C 172 ; WX 600 ; N guilsinglleft ; B 27 -50 474 487 ;
+C 173 ; WX 600 ; N guilsinglright ; B 224 -50 665 487 ;
+C 174 ; WX 600 ; N fi ; B -59 -50 681 725 ;
+C 175 ; WX 600 ; N fl ; B -59 -50 687 674 ;
+C 177 ; WX 600 ; N endash ; B 52 181 668 381 ;
+C 178 ; WX 600 ; N dagger ; B 126 -142 638 674 ;
+C 179 ; WX 600 ; N daggerdbl ; B 75 -142 638 674 ;
+C 180 ; WX 600 ; N periodcentered ; B 255 206 475 406 ;
+C 182 ; WX 600 ; N paragraph ; B 72 -147 730 689 ;
+C 183 ; WX 600 ; N bullet ; B 265 206 465 406 ;
+C 184 ; WX 600 ; N quotesinglbase ; B 48 -225 422 204 ;
+C 185 ; WX 600 ; N quotedblbase ; B 12 -199 588 199 ;
+C 186 ; WX 600 ; N quotedblright ; B 114 280 690 678 ;
+C 187 ; WX 600 ; N guillemotright ; B -6 -50 665 487 ;
+C 188 ; WX 600 ; N ellipsis ; B 7 -65 607 135 ;
+C 189 ; WX 600 ; N perthousand ; B 55 -65 679 689 ;
+C 191 ; WX 600 ; N questiondown ; B 26 -257 533 475 ;
+C 193 ; WX 600 ; N grave ; B 200 390 504 689 ;
+C 194 ; WX 600 ; N acute ; B 304 390 650 689 ;
+C 195 ; WX 600 ; N circumflex ; B 179 390 629 674 ;
+C 196 ; WX 600 ; N tilde ; B 171 381 646 640 ;
+C 197 ; WX 600 ; N macron ; B 185 416 635 616 ;
+C 198 ; WX 600 ; N breve ; B 196 390 647 674 ;
+C 199 ; WX 600 ; N dotaccent ; B 313 431 513 631 ;
+C 200 ; WX 600 ; N dieresis ; B 209 431 617 631 ;
+C 202 ; WX 600 ; N ring ; B 237 353 586 694 ;
+C 203 ; WX 600 ; N cedilla ; B 103 -246 436 100 ;
+C 205 ; WX 600 ; N hungarumlaut ; B 179 390 650 689 ;
+C 206 ; WX 600 ; N ogonek ; B 184 -225 490 100 ;
+C 207 ; WX 600 ; N caron ; B 197 390 647 674 ;
+C 208 ; WX 600 ; N emdash ; B -19 181 739 381 ;
+C 225 ; WX 600 ; N AE ; B -59 -50 763 633 ;
+C 227 ; WX 600 ; N ordfeminine ; B 114 120 590 649 ;
+C 232 ; WX 600 ; N Lslash ; B -6 -50 665 633 ;
+C 233 ; WX 600 ; N Oslash ; B -44 -121 764 683 ;
+C 234 ; WX 600 ; N OE ; B -16 -50 763 633 ;
+C 235 ; WX 600 ; N ordmasculine ; B 118 120 623 649 ;
+C 241 ; WX 600 ; N ae ; B -39 -65 711 502 ;
+C 245 ; WX 600 ; N dotlessi ; B 23 -50 599 487 ;
+C 248 ; WX 600 ; N lslash ; B 23 -50 604 674 ;
+C 249 ; WX 600 ; N oslash ; B -31 -121 716 538 ;
+C 250 ; WX 600 ; N oe ; B -30 -65 711 502 ;
+C 251 ; WX 600 ; N germandbls ; B -26 -65 618 674 ;
+C -1 ; WX 600 ; N Aacute ; B -60 -50 682 839 ;
+C -1 ; WX 600 ; N Acircumflex ; B -60 -50 682 824 ;
+C -1 ; WX 600 ; N Adieresis ; B -60 -50 682 781 ;
+C -1 ; WX 600 ; N Agrave ; B -60 -50 682 839 ;
+C -1 ; WX 600 ; N Aring ; B -60 -50 682 855 ;
+C -1 ; WX 600 ; N Atilde ; B -60 -50 682 790 ;
+C -1 ; WX 600 ; N Ccedilla ; B 31 -246 713 648 ;
+C -1 ; WX 600 ; N Eacute ; B -26 -50 692 839 ;
+C -1 ; WX 600 ; N Ecircumflex ; B -26 -50 692 824 ;
+C -1 ; WX 600 ; N Edieresis ; B -26 -50 692 781 ;
+C -1 ; WX 600 ; N Egrave ; B -26 -50 692 839 ;
+C -1 ; WX 600 ; N Eth ; B -26 -50 670 633 ;
+C -1 ; WX 600 ; N Gcaron ; B 29 -65 713 824 ;
+C -1 ; WX 600 ; N IJ ; B -59 -65 783 633 ;
+C -1 ; WX 600 ; N Iacute ; B 44 -50 680 839 ;
+C -1 ; WX 600 ; N Icircumflex ; B 44 -50 680 824 ;
+C -1 ; WX 600 ; N Idieresis ; B 44 -50 680 781 ;
+C -1 ; WX 600 ; N Idot ; B 44 -50 680 781 ;
+C -1 ; WX 600 ; N Igrave ; B 44 -50 680 839 ;
+C -1 ; WX 600 ; N LL ; B -69 -50 712 633 ;
+C -1 ; WX 600 ; N Ntilde ; B -26 -50 755 790 ;
+C -1 ; WX 600 ; N Oacute ; B 26 -65 696 839 ;
+C -1 ; WX 600 ; N Ocircumflex ; B 26 -65 696 824 ;
+C -1 ; WX 600 ; N Odieresis ; B 26 -65 696 781 ;
+C -1 ; WX 600 ; N Ograve ; B 26 -65 696 839 ;
+C -1 ; WX 600 ; N Otilde ; B 26 -65 696 790 ;
+C -1 ; WX 600 ; N Scaron ; B 23 -65 680 824 ;
+C -1 ; WX 600 ; N Scedilla ; B 23 -246 680 648 ;
+C -1 ; WX 600 ; N Thorn ; B -26 -50 663 633 ;
+C -1 ; WX 600 ; N Uacute ; B 61 -65 753 839 ;
+C -1 ; WX 600 ; N Ucircumflex ; B 61 -65 753 824 ;
+C -1 ; WX 600 ; N Udieresis ; B 61 -65 753 781 ;
+C -1 ; WX 600 ; N Ugrave ; B 61 -65 753 839 ;
+C -1 ; WX 600 ; N Yacute ; B 76 -50 742 839 ;
+C -1 ; WX 600 ; N Ydieresis ; B 76 -50 742 781 ;
+C -1 ; WX 600 ; N Zcaron ; B 34 -50 679 824 ;
+C -1 ; WX 600 ; N aacute ; B 16 -65 632 710 ;
+C -1 ; WX 600 ; N acircumflex ; B 16 -65 635 703 ;
+C -1 ; WX 600 ; N adieresis ; B 16 -65 632 652 ;
+C -1 ; WX 600 ; N agrave ; B 16 -65 632 710 ;
+C -1 ; WX 600 ; N aring ; B 16 -65 632 746 ;
+C -1 ; WX 600 ; N arrowboth ; B -36 50 764 550 ;
+C -1 ; WX 600 ; N arrowdown ; B 93 -50 593 689 ;
+C -1 ; WX 600 ; N arrowleft ; B -36 50 764 550 ;
+C -1 ; WX 600 ; N arrowright ; B -36 50 764 550 ;
+C -1 ; WX 600 ; N arrowup ; B 143 -50 643 689 ;
+C -1 ; WX 600 ; N atilde ; B 16 -65 654 678 ;
+C -1 ; WX 600 ; N brokenbar ; B 178 -204 522 674 ;
+C -1 ; WX 600 ; N ccedilla ; B 44 -246 672 502 ;
+C -1 ; WX 600 ; N center ; B 2 -50 722 684 ;
+C -1 ; WX 600 ; N copyright ; B -27 -65 743 648 ;
+C -1 ; WX 600 ; N dectab ; B -54 -50 676 308 ;
+C -1 ; WX 600 ; N degree ; B 171 234 624 674 ;
+C -1 ; WX 600 ; N divide ; B 52 -9 668 591 ;
+C -1 ; WX 600 ; N down ; B 127 -50 539 502 ;
+C -1 ; WX 600 ; N eacute ; B 25 -65 650 714 ;
+C -1 ; WX 600 ; N ecircumflex ; B 25 -65 650 703 ;
+C -1 ; WX 600 ; N edieresis ; B 25 -65 650 652 ;
+C -1 ; WX 600 ; N egrave ; B 25 -65 650 714 ;
+C -1 ; WX 600 ; N eth ; B 28 -65 695 689 ;
+C -1 ; WX 600 ; N format ; B -108 -257 247 674 ;
+C -1 ; WX 600 ; N gcaron ; B 25 -257 724 695 ;
+C -1 ; WX 600 ; N graybox ; B -25 -100 753 700 ;
+C -1 ; WX 600 ; N iacute ; B 23 -50 599 710 ;
+C -1 ; WX 600 ; N icircumflex ; B 23 -50 599 684 ;
+C -1 ; WX 600 ; N idieresis ; B 23 -50 599 652 ;
+C -1 ; WX 600 ; N igrave ; B 23 -50 599 706 ;
+C -1 ; WX 600 ; N ij ; B -39 -257 692 725 ;
+C -1 ; WX 600 ; N indent ; B 38 0 650 412 ;
+C -1 ; WX 600 ; N largebullet ; B 265 206 465 406 ;
+C -1 ; WX 600 ; N left ; B 38 0 650 412 ;
+C -1 ; WX 600 ; N lira ; B 15 -50 620 648 ;
+C -1 ; WX 600 ; N ll ; B -49 -50 682 674 ;
+C -1 ; WX 600 ; N logicalnot ; B 67 94 683 454 ;
+C -1 ; WX 600 ; N merge ; B 127 -50 569 502 ;
+C -1 ; WX 600 ; N minus ; B 52 181 668 381 ;
+C -1 ; WX 600 ; N mu ; B 13 -257 640 487 ;
+C -1 ; WX 600 ; N multiply ; B 33 -48 669 530 ;
+C -1 ; WX 600 ; N notegraphic ; B 107 -65 639 689 ;
+C -1 ; WX 600 ; N ntilde ; B -16 -50 632 678 ;
+C -1 ; WX 600 ; N oacute ; B 34 -65 656 699 ;
+C -1 ; WX 600 ; N ocircumflex ; B 34 -65 656 703 ;
+C -1 ; WX 600 ; N odieresis ; B 34 -65 656 652 ;
+C -1 ; WX 600 ; N ograve ; B 34 -65 656 699 ;
+C -1 ; WX 600 ; N onehalf ; B -14 -65 725 674 ;
+C -1 ; WX 600 ; N onequarter ; B -14 -50 741 674 ;
+C -1 ; WX 600 ; N onesuperior ; B 151 140 551 674 ;
+C -1 ; WX 600 ; N otilde ; B 34 -65 656 657 ;
+C -1 ; WX 600 ; N overscore ; B 33 489 817 689 ;
+C -1 ; WX 600 ; N plusminus ; B 3 -50 677 610 ;
+C -1 ; WX 600 ; N prescription ; B -26 -50 680 633 ;
+C -1 ; WX 600 ; N registered ; B -27 -65 743 648 ;
+C -1 ; WX 600 ; N return ; B -24 -50 805 668 ;
+C -1 ; WX 600 ; N scaron ; B 34 -65 651 695 ;
+C -1 ; WX 600 ; N scedilla ; B 34 -246 638 502 ;
+C -1 ; WX 600 ; N square ; B -73 -50 805 668 ;
+C -1 ; WX 600 ; N stop ; B -73 -50 805 668 ;
+C -1 ; WX 600 ; N tab ; B -73 -50 744 668 ;
+C -1 ; WX 600 ; N thorn ; B -91 -257 671 674 ;
+C -1 ; WX 600 ; N threequarters ; B -3 -50 711 689 ;
+C -1 ; WX 600 ; N threesuperior ; B 155 131 612 689 ;
+C -1 ; WX 600 ; N trademark ; B 18 170 793 633 ;
+C -1 ; WX 600 ; N twosuperior ; B 131 140 601 689 ;
+C -1 ; WX 600 ; N uacute ; B 45 -65 640 706 ;
+C -1 ; WX 600 ; N ucircumflex ; B 45 -65 640 684 ;
+C -1 ; WX 600 ; N udieresis ; B 45 -65 640 652 ;
+C -1 ; WX 600 ; N ugrave ; B 45 -65 640 706 ;
+C -1 ; WX 600 ; N up ; B 157 -50 569 502 ;
+C -1 ; WX 600 ; N yacute ; B -62 -257 711 706 ;
+C -1 ; WX 600 ; N ydieresis ; B -62 -257 711 631 ;
+C -1 ; WX 600 ; N zcaron ; B 46 -50 651 695 ;
+EndCharMetrics
+StartComposites 58
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 0 146 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 0 0 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 0 146 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 0 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 0 0 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 0 146 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 0 0 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 0 146 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 0 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 0 146 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 0 146 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 0 146 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 0 146 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 0 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 0 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 0 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 0 0 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 146 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 0 146 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 0 146 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 146 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex 0 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis 0 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 0 146 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 0 146 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 0 146 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 0 146 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ;
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 0 146 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 0 146 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 0 146 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 0 146 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 0 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 0 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 0 0 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 0 146 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 0 146 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 0 146 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 0 146 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 0 146 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 0 146 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 0 146 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 0 146 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ;
+EndComposites
+EndFontMetrics
diff --git a/samples/printing/CourO.afm b/samples/printing/CourO.afm
new file mode 100644
index 0000000000..0911df46f9
--- /dev/null
+++ b/samples/printing/CourO.afm
@@ -0,0 +1,341 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1984 Adobe Systems Incorporated. 	All Rights Reserved.
+Comment Creation Date:Wed Feb 25 16:13:37 PST 1987
+FontName Courier-Oblique
+EncodingScheme AdobeStandardEncoding
+FullName Courier Oblique
+FamilyName Courier
+Weight Medium
+ItalicAngle -12.0
+IsFixedPitch true
+UnderlinePosition -82
+UnderlineThickness 40
+Version 001.003
+FontBBox -85 -290 759 795
+CapHeight 583
+XHeight 437
+Descender -207
+Ascender 624
+StartCharMetrics 260
+C 32 ; WX 600 ; N space ; B 560 -40 640 40 ;
+C 33 ; WX 600 ; N exclam ; B 257 -5 483 639 ;
+C 34 ; WX 600 ; N quotedbl ; B 231 314 594 603 ;
+C 35 ; WX 600 ; N numbersign ; B 116 -82 608 665 ;
+C 36 ; WX 600 ; N dollar ; B 111 -113 601 675 ;
+C 37 ; WX 600 ; N percent ; B 118 -35 611 639 ;
+C 38 ; WX 600 ; N ampersand ; B 112 -35 547 540 ;
+C 39 ; WX 600 ; N quoteright ; B 208 304 462 613 ;
+C 40 ; WX 600 ; N parenleft ; B 315 -144 602 623 ;
+C 41 ; WX 600 ; N parenright ; B 105 -144 392 623 ;
+C 42 ; WX 600 ; N asterisk ; B 191 210 605 624 ;
+C 43 ; WX 600 ; N plus ; B 112 12 608 550 ;
+C 44 ; WX 600 ; N comma ; B 111 -155 364 155 ;
+C 45 ; WX 600 ; N hyphen ; B 112 241 608 321 ;
+C 46 ; WX 600 ; N period ; B 261 10 361 90 ;
+C 47 ; WX 600 ; N slash ; B 80 -103 644 686 ;
+C 48 ; WX 600 ; N zero ; B 139 -35 590 639 ;
+C 49 ; WX 600 ; N one ; B 97 -20 511 624 ;
+C 50 ; WX 600 ; N two ; B 68 -20 596 639 ;
+C 51 ; WX 600 ; N three ; B 90 -35 599 639 ;
+C 52 ; WX 600 ; N four ; B 125 -20 560 624 ;
+C 53 ; WX 600 ; N five ; B 93 -35 602 624 ;
+C 54 ; WX 600 ; N six ; B 167 -35 654 639 ;
+C 55 ; WX 600 ; N seven ; B 196 -20 622 624 ;
+C 56 ; WX 600 ; N eight ; B 124 -35 595 639 ;
+C 57 ; WX 600 ; N nine ; B 120 -35 606 639 ;
+C 58 ; WX 600 ; N colon ; B 261 10 425 392 ;
+C 59 ; WX 600 ; N semicolon ; B 123 -116 425 392 ;
+C 60 ; WX 600 ; N less ; B 112 12 656 550 ;
+C 61 ; WX 600 ; N equal ; B 75 168 644 394 ;
+C 62 ; WX 600 ; N greater ; B 63 12 608 550 ;
+C 63 ; WX 600 ; N question ; B 211 -5 597 598 ;
+C 64 ; WX 600 ; N at ; B 120 -82 580 644 ;
+C 65 ; WX 600 ; N A ; B -7 -20 615 583 ;
+C 66 ; WX 600 ; N B ; B 27 -20 610 583 ;
+C 67 ; WX 600 ; N C ; B 91 -35 655 598 ;
+C 68 ; WX 600 ; N D ; B 27 -20 610 583 ;
+C 69 ; WX 600 ; N E ; B 27 -20 634 583 ;
+C 70 ; WX 600 ; N F ; B 27 -20 655 583 ;
+C 71 ; WX 600 ; N G ; B 89 -35 655 598 ;
+C 72 ; WX 600 ; N H ; B 37 -20 665 583 ;
+C 73 ; WX 600 ; N I ; B 97 -20 622 583 ;
+C 74 ; WX 600 ; N J ; B 82 -35 718 583 ;
+C 75 ; WX 600 ; N K ; B 27 -20 686 583 ;
+C 76 ; WX 600 ; N L ; B 47 -20 605 583 ;
+C 77 ; WX 600 ; N M ; B -5 -20 718 583 ;
+C 78 ; WX 600 ; N N ; B 27 -20 697 583 ;
+C 79 ; WX 600 ; N O ; B 83 -35 636 598 ;
+C 80 ; WX 600 ; N P ; B 27 -20 606 583 ;
+C 81 ; WX 600 ; N Q ; B 84 -136 636 598 ;
+C 82 ; WX 600 ; N R ; B 27 -20 613 583 ;
+C 83 ; WX 600 ; N S ; B 76 -35 622 598 ;
+C 84 ; WX 600 ; N T ; B 129 -20 663 583 ;
+C 85 ; WX 600 ; N U ; B 119 -35 695 583 ;
+C 86 ; WX 600 ; N V ; B 104 -20 726 583 ;
+C 87 ; WX 600 ; N W ; B 103 -20 715 583 ;
+C 88 ; WX 600 ; N X ; B 24 -20 684 583 ;
+C 89 ; WX 600 ; N Y ; B 129 -20 684 583 ;
+C 90 ; WX 600 ; N Z ; B 87 -20 611 583 ;
+C 91 ; WX 600 ; N bracketleft ; B 238 -144 589 624 ;
+C 92 ; WX 600 ; N backslash ; B 230 -103 494 686 ;
+C 93 ; WX 600 ; N bracketright ; B 113 -144 464 624 ;
+C 94 ; WX 600 ; N asciicircum ; B 173 335 587 624 ;
+C 95 ; WX 600 ; N underscore ; B -85 -290 579 -210 ;
+C 96 ; WX 600 ; N quoteleft ; B 382 304 538 613 ;
+C 97 ; WX 600 ; N a ; B 74 -35 565 452 ;
+C 98 ; WX 600 ; N b ; B 6 -35 610 624 ;
+C 99 ; WX 600 ; N c ; B 104 -35 614 452 ;
+C 100 ; WX 600 ; N d ; B 83 -35 643 624 ;
+C 101 ; WX 600 ; N e ; B 85 -35 590 452 ;
+C 102 ; WX 600 ; N f ; B 89 -20 682 624 ; L i fi ; L l fl ;
+C 103 ; WX 600 ; N g ; B 85 -207 666 452 ;
+C 104 ; WX 600 ; N h ; B 37 -20 575 624 ;
+C 105 ; WX 600 ; N i ; B 76 -20 532 665 ;
+C 106 ; WX 600 ; N j ; B 92 -207 562 665 ;
+C 107 ; WX 600 ; N k ; B 47 -20 603 624 ;
+C 108 ; WX 600 ; N l ; B 76 -20 532 624 ;
+C 109 ; WX 600 ; N m ; B -5 -20 621 452 ;
+C 110 ; WX 600 ; N n ; B 37 -20 565 452 ;
+C 111 ; WX 600 ; N o ; B 91 -35 597 452 ;
+C 112 ; WX 600 ; N p ; B -33 -207 612 452 ;
+C 113 ; WX 600 ; N q ; B 85 -207 687 452 ;
+C 114 ; WX 600 ; N r ; B 68 -20 639 448 ;
+C 115 ; WX 600 ; N s ; B 87 -35 580 452 ;
+C 116 ; WX 600 ; N t ; B 107 -35 541 582 ;
+C 117 ; WX 600 ; N u ; B 107 -35 582 437 ;
+C 118 ; WX 600 ; N v ; B 94 -20 674 437 ;
+C 119 ; WX 600 ; N w ; B 94 -20 674 437 ;
+C 120 ; WX 600 ; N x ; B 35 -20 632 437 ;
+C 121 ; WX 600 ; N y ; B -4 -207 653 437 ;
+C 122 ; WX 600 ; N z ; B 99 -20 582 437 ;
+C 123 ; WX 600 ; N braceleft ; B 228 -144 547 624 ;
+C 124 ; WX 600 ; N bar ; B 238 -144 464 624 ;
+C 125 ; WX 600 ; N braceright ; B 155 -144 474 624 ;
+C 126 ; WX 600 ; N asciitilde ; B 127 189 592 373 ;
+C 161 ; WX 600 ; N exclamdown ; B 209 -207 430 415 ;
+C 162 ; WX 600 ; N cent ; B 156 -19 583 665 ;
+C 163 ; WX 600 ; N sterling ; B 68 -20 560 598 ;
+C 164 ; WX 600 ; N fraction ; B 65 120 665 492 ;
+C 165 ; WX 600 ; N yen ; B 137 -20 684 583 ;
+C 166 ; WX 600 ; N florin ; B 54 -113 663 639 ;
+C 167 ; WX 600 ; N section ; B 78 -87 637 629 ;
+C 168 ; WX 600 ; N currency ; B 107 75 617 509 ;
+C 169 ; WX 600 ; N quotesingle ; B 333 304 492 613 ;
+C 170 ; WX 600 ; N quotedblleft ; B 216 340 588 619 ;
+C 171 ; WX 600 ; N guillemotleft ; B 87 -20 645 437 ;
+C 172 ; WX 600 ; N guilsinglleft ; B 87 -20 416 437 ;
+C 173 ; WX 600 ; N guilsinglright ; B 277 -20 605 437 ;
+C 174 ; WX 600 ; N fi ; B -6 -20 628 665 ;
+C 175 ; WX 600 ; N fl ; B -6 -20 629 624 ;
+C 177 ; WX 600 ; N endash ; B 112 241 608 321 ;
+C 178 ; WX 600 ; N dagger ; B 188 -82 580 624 ;
+C 179 ; WX 600 ; N daggerdbl ; B 135 -82 580 624 ;
+C 180 ; WX 600 ; N periodcentered ; B 315 266 415 346 ;
+C 182 ; WX 600 ; N paragraph ; B 132 -87 670 629 ;
+C 183 ; WX 600 ; N bullet ; B 325 266 405 346 ;
+C 184 ; WX 600 ; N quotesinglbase ; B 108 -165 362 144 ;
+C 185 ; WX 600 ; N quotedblbase ; B 72 -139 528 139 ;
+C 186 ; WX 600 ; N quotedblright ; B 174 340 630 619 ;
+C 187 ; WX 600 ; N guillemotright ; B 47 -20 605 437 ;
+C 188 ; WX 600 ; N ellipsis ; B 67 -5 547 75 ;
+C 189 ; WX 600 ; N perthousand ; B 117 -35 619 639 ;
+C 191 ; WX 600 ; N questiondown ; B 85 -207 470 415 ;
+C 193 ; WX 600 ; N grave ; B 262 450 444 639 ;
+C 194 ; WX 600 ; N acute ; B 364 450 592 639 ;
+C 195 ; WX 600 ; N circumflex ; B 239 450 569 624 ;
+C 196 ; WX 600 ; N tilde ; B 231 441 586 580 ;
+C 197 ; WX 600 ; N macron ; B 245 476 575 556 ;
+C 198 ; WX 600 ; N breve ; B 258 450 589 624 ;
+C 199 ; WX 600 ; N dotaccent ; B 373 491 453 571 ;
+C 200 ; WX 600 ; N dieresis ; B 269 491 557 571 ;
+C 202 ; WX 600 ; N ring ; B 297 413 526 634 ;
+C 203 ; WX 600 ; N cedilla ; B 163 -186 376 40 ;
+C 205 ; WX 600 ; N hungarumlaut ; B 239 450 592 639 ;
+C 206 ; WX 600 ; N ogonek ; B 244 -165 430 40 ;
+C 207 ; WX 600 ; N caron ; B 259 450 589 624 ;
+C 208 ; WX 600 ; N emdash ; B 41 241 679 321 ;
+C 225 ; WX 600 ; N AE ; B -6 -20 705 583 ;
+C 227 ; WX 600 ; N ordfeminine ; B 174 179 529 598 ;
+C 232 ; WX 600 ; N Lslash ; B 47 -20 605 583 ;
+C 233 ; WX 600 ; N Oslash ; B 16 -61 704 623 ;
+C 234 ; WX 600 ; N OE ; B 42 -20 705 583 ;
+C 235 ; WX 600 ; N ordmasculine ; B 178 179 563 598 ;
+C 241 ; WX 600 ; N ae ; B 19 -35 651 452 ;
+C 245 ; WX 600 ; N dotlessi ; B 76 -20 532 437 ;
+C 248 ; WX 600 ; N lslash ; B 76 -20 544 624 ;
+C 249 ; WX 600 ; N oslash ; B 29 -61 656 478 ;
+C 250 ; WX 600 ; N oe ; B 28 -35 651 452 ;
+C 251 ; WX 600 ; N germandbls ; B 27 -35 558 624 ;
+C -1 ; WX 600 ; N Aacute ; B -7 -20 615 789 ;
+C -1 ; WX 600 ; N Acircumflex ; B -7 -20 615 774 ;
+C -1 ; WX 600 ; N Adieresis ; B -7 -20 615 721 ;
+C -1 ; WX 600 ; N Agrave ; B -7 -20 615 789 ;
+C -1 ; WX 600 ; N Aring ; B -7 -20 615 795 ;
+C -1 ; WX 600 ; N Atilde ; B -7 -20 615 730 ;
+C -1 ; WX 600 ; N Ccedilla ; B 91 -186 655 598 ;
+C -1 ; WX 600 ; N Eacute ; B 27 -20 634 789 ;
+C -1 ; WX 600 ; N Ecircumflex ; B 27 -20 634 774 ;
+C -1 ; WX 600 ; N Edieresis ; B 27 -20 634 721 ;
+C -1 ; WX 600 ; N Egrave ; B 27 -20 634 789 ;
+C -1 ; WX 600 ; N Eth ; B 27 -20 610 583 ;
+C -1 ; WX 600 ; N Gcaron ; B 89 -35 655 774 ;
+C -1 ; WX 600 ; N IJ ; B -6 -35 725 583 ;
+C -1 ; WX 600 ; N Iacute ; B 97 -20 622 789 ;
+C -1 ; WX 600 ; N Icircumflex ; B 97 -20 622 774 ;
+C -1 ; WX 600 ; N Idieresis ; B 97 -20 622 721 ;
+C -1 ; WX 600 ; N Idot ; B 97 -20 622 721 ;
+C -1 ; WX 600 ; N Igrave ; B 97 -20 622 789 ;
+C -1 ; WX 600 ; N LL ; B -16 -20 652 583 ;
+C -1 ; WX 600 ; N Ntilde ; B 27 -20 697 730 ;
+C -1 ; WX 600 ; N Oacute ; B 83 -35 636 789 ;
+C -1 ; WX 600 ; N Ocircumflex ; B 83 -35 636 774 ;
+C -1 ; WX 600 ; N Odieresis ; B 83 -35 636 721 ;
+C -1 ; WX 600 ; N Ograve ; B 83 -35 636 789 ;
+C -1 ; WX 600 ; N Otilde ; B 83 -35 636 730 ;
+C -1 ; WX 600 ; N Scaron ; B 76 -35 622 774 ;
+C -1 ; WX 600 ; N Scedilla ; B 76 -186 622 598 ;
+C -1 ; WX 600 ; N Thorn ; B 27 -20 603 583 ;
+C -1 ; WX 600 ; N Uacute ; B 119 -35 695 789 ;
+C -1 ; WX 600 ; N Ucircumflex ; B 119 -35 695 774 ;
+C -1 ; WX 600 ; N Udieresis ; B 119 -35 695 721 ;
+C -1 ; WX 600 ; N Ugrave ; B 119 -35 695 789 ;
+C -1 ; WX 600 ; N Yacute ; B 129 -20 684 789 ;
+C -1 ; WX 600 ; N Ydieresis ; B 129 -20 684 721 ;
+C -1 ; WX 600 ; N Zcaron ; B 87 -20 621 774 ;
+C -1 ; WX 600 ; N aacute ; B 74 -35 565 660 ;
+C -1 ; WX 600 ; N acircumflex ; B 74 -35 575 653 ;
+C -1 ; WX 600 ; N adieresis ; B 74 -35 565 592 ;
+C -1 ; WX 600 ; N agrave ; B 74 -35 565 660 ;
+C -1 ; WX 600 ; N aring ; B 74 -35 565 686 ;
+C -1 ; WX 600 ; N arrowboth ; B 24 110 704 490 ;
+C -1 ; WX 600 ; N arrowdown ; B 146 -20 526 639 ;
+C -1 ; WX 600 ; N arrowleft ; B 24 110 704 490 ;
+C -1 ; WX 600 ; N arrowright ; B 24 110 704 490 ;
+C -1 ; WX 600 ; N arrowup ; B 205 -20 585 639 ;
+C -1 ; WX 600 ; N atilde ; B 74 -35 594 618 ;
+C -1 ; WX 600 ; N brokenbar ; B 238 -144 464 624 ;
+C -1 ; WX 600 ; N ccedilla ; B 104 -186 614 452 ;
+C -1 ; WX 600 ; N center ; B 62 -20 662 624 ;
+C -1 ; WX 600 ; N copyright ; B 33 -35 683 598 ;
+C -1 ; WX 600 ; N dectab ; B -1 -20 609 248 ;
+C -1 ; WX 600 ; N degree ; B 231 294 564 624 ;
+C -1 ; WX 600 ; N divide ; B 112 51 608 531 ;
+C -1 ; WX 600 ; N down ; B 181 -20 473 452 ;
+C -1 ; WX 600 ; N eacute ; B 85 -35 590 664 ;
+C -1 ; WX 600 ; N ecircumflex ; B 85 -35 590 653 ;
+C -1 ; WX 600 ; N edieresis ; B 85 -35 590 592 ;
+C -1 ; WX 600 ; N egrave ; B 85 -35 590 664 ;
+C -1 ; WX 600 ; N eth ; B 87 -35 637 639 ;
+C -1 ; WX 600 ; N format ; B -50 -207 189 624 ;
+C -1 ; WX 600 ; N gcaron ; B 85 -207 666 645 ;
+C -1 ; WX 600 ; N graybox ; B 35 -40 693 640 ;
+C -1 ; WX 600 ; N iacute ; B 76 -20 532 660 ;
+C -1 ; WX 600 ; N icircumflex ; B 76 -20 532 634 ;
+C -1 ; WX 600 ; N idieresis ; B 76 -20 532 592 ;
+C -1 ; WX 600 ; N igrave ; B 76 -20 532 656 ;
+C -1 ; WX 600 ; N ij ; B 14 -207 634 665 ;
+C -1 ; WX 600 ; N indent ; B 98 60 590 352 ;
+C -1 ; WX 600 ; N largebullet ; B 325 266 405 346 ;
+C -1 ; WX 600 ; N left ; B 98 60 590 352 ;
+C -1 ; WX 600 ; N lira ; B 68 -20 560 598 ;
+C -1 ; WX 600 ; N ll ; B 4 -20 624 624 ;
+C -1 ; WX 600 ; N logicalnot ; B 127 154 623 394 ;
+C -1 ; WX 600 ; N merge ; B 181 -20 511 452 ;
+C -1 ; WX 600 ; N minus ; B 112 241 608 321 ;
+C -1 ; WX 600 ; N mu ; B 71 -207 582 437 ;
+C -1 ; WX 600 ; N multiply ; B 93 12 609 470 ;
+C -1 ; WX 600 ; N notegraphic ; B 167 -5 573 639 ;
+C -1 ; WX 600 ; N ntilde ; B 37 -20 569 618 ;
+C -1 ; WX 600 ; N oacute ; B 91 -35 597 649 ;
+C -1 ; WX 600 ; N ocircumflex ; B 91 -35 597 653 ;
+C -1 ; WX 600 ; N odieresis ; B 91 -35 597 592 ;
+C -1 ; WX 600 ; N ograve ; B 91 -35 597 649 ;
+C -1 ; WX 600 ; N onehalf ; B 46 -20 665 624 ;
+C -1 ; WX 600 ; N onequarter ; B 46 -20 681 624 ;
+C -1 ; WX 600 ; N onesuperior ; B 211 200 491 624 ;
+C -1 ; WX 600 ; N otilde ; B 91 -35 597 597 ;
+C -1 ; WX 600 ; N overscore ; B 95 559 759 639 ;
+C -1 ; WX 600 ; N plusminus ; B 56 -20 617 550 ;
+C -1 ; WX 600 ; N prescription ; B 27 -20 613 583 ;
+C -1 ; WX 600 ; N registered ; B 33 -35 683 598 ;
+C -1 ; WX 600 ; N return ; B 36 -20 745 608 ;
+C -1 ; WX 600 ; N scaron ; B 87 -35 593 645 ;
+C -1 ; WX 600 ; N scedilla ; B 87 -186 580 452 ;
+C -1 ; WX 600 ; N square ; B -20 -20 745 608 ;
+C -1 ; WX 600 ; N stop ; B -20 -20 745 608 ;
+C -1 ; WX 600 ; N tab ; B -20 -20 684 608 ;
+C -1 ; WX 600 ; N thorn ; B -33 -207 612 624 ;
+C -1 ; WX 600 ; N threequarters ; B 57 -20 651 639 ;
+C -1 ; WX 600 ; N threesuperior ; B 215 191 552 639 ;
+C -1 ; WX 600 ; N trademark ; B 78 230 735 583 ;
+C -1 ; WX 600 ; N twosuperior ; B 191 200 541 639 ;
+C -1 ; WX 600 ; N uacute ; B 107 -35 582 656 ;
+C -1 ; WX 600 ; N ucircumflex ; B 107 -35 582 634 ;
+C -1 ; WX 600 ; N udieresis ; B 107 -35 582 592 ;
+C -1 ; WX 600 ; N ugrave ; B 107 -35 582 656 ;
+C -1 ; WX 600 ; N up ; B 219 -20 511 452 ;
+C -1 ; WX 600 ; N yacute ; B -4 -207 653 656 ;
+C -1 ; WX 600 ; N ydieresis ; B -4 -207 653 571 ;
+C -1 ; WX 600 ; N zcaron ; B 99 -20 593 645 ;
+EndCharMetrics
+StartComposites 58
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 0 146 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 0 0 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 0 146 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 0 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 0 0 ;
+CC Yacute 2 ; PCC Y 0 0 ; PCC acute 0 146 ;
+CC yacute 2 ; PCC y 0 0 ; PCC acute 0 0 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 0 146 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 0 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 0 146 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 0 146 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 0 146 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 0 146 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 0 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 0 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 0 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 0 0 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 146 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 0 146 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 0 146 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 146 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex 0 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis 0 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 0 146 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 0 146 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 0 146 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 0 146 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ;
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 0 146 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 0 146 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 0 146 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 0 146 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 0 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 0 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 0 0 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 0 146 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 0 146 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 0 146 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 0 146 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 0 146 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 0 146 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 0 146 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 0 146 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ;
+EndComposites
+EndFontMetrics
diff --git a/samples/printing/Helv.afm b/samples/printing/Helv.afm
new file mode 100644
index 0000000000..b17a3909d4
--- /dev/null
+++ b/samples/printing/Helv.afm
@@ -0,0 +1,435 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1984 Adobe Systems Incorporated. 	All Rights Reserved.
+Comment Creation Date:Tue Aug 5 11:33:55 PDT 1986
+FontName Helvetica
+EncodingScheme AdobeStandardEncoding
+FullName Helvetica
+FamilyName Helvetica
+Weight Medium
+ItalicAngle 0.0
+IsFixedPitch false
+UnderlinePosition -97
+UnderlineThickness 73
+Version 001.001
+Notice Helvetica is a registered trademark of Allied Corporation.
+FontBBox -174 -220 1001 944
+CapHeight 729
+XHeight 525
+Descender -219
+Ascender 729
+StartCharMetrics 228
+C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 278 ; N exclam ; B 124 0 208 729 ;
+C 34 ; WX 355 ; N quotedbl ; B 52 462 305 708 ;
+C 35 ; WX 556 ; N numbersign ; B 14 -20 542 698 ;
+C 36 ; WX 556 ; N dollar ; B 33 -125 518 770 ;
+C 37 ; WX 889 ; N percent ; B 29 -20 859 708 ;
+C 38 ; WX 667 ; N ampersand ; B 52 -23 637 710 ;
+C 39 ; WX 222 ; N quoteright ; B 64 476 158 708 ;
+C 40 ; WX 333 ; N parenleft ; B 73 -213 291 729 ;
+C 41 ; WX 333 ; N parenright ; B 38 -213 256 729 ;
+C 42 ; WX 389 ; N asterisk ; B 40 452 343 740 ;
+C 43 ; WX 584 ; N plus ; B 50 -10 534 474 ;
+C 44 ; WX 278 ; N comma ; B 87 -150 192 104 ;
+C 45 ; WX 333 ; N hyphen ; B 46 240 284 313 ;
+C 46 ; WX 278 ; N period ; B 87 0 191 104 ;
+C 47 ; WX 278 ; N slash ; B -8 -21 284 708 ;
+C 48 ; WX 556 ; N zero ; B 43 -23 507 709 ;
+C 49 ; WX 556 ; N one ; B 102 0 347 709 ;
+C 50 ; WX 556 ; N two ; B 34 0 511 710 ;
+C 51 ; WX 556 ; N three ; B 32 -23 506 709 ;
+C 52 ; WX 556 ; N four ; B 28 0 520 709 ;
+C 53 ; WX 556 ; N five ; B 35 -23 513 709 ;
+C 54 ; WX 556 ; N six ; B 43 -23 513 709 ;
+C 55 ; WX 556 ; N seven ; B 46 0 520 709 ;
+C 56 ; WX 556 ; N eight ; B 37 -23 513 709 ;
+C 57 ; WX 556 ; N nine ; B 38 -23 509 709 ;
+C 58 ; WX 278 ; N colon ; B 110 0 214 525 ;
+C 59 ; WX 278 ; N semicolon ; B 110 -150 215 516 ;
+C 60 ; WX 584 ; N less ; B 45 -10 534 474 ;
+C 61 ; WX 584 ; N equal ; B 50 112 534 352 ;
+C 62 ; WX 584 ; N greater ; B 50 -10 539 474 ;
+C 63 ; WX 556 ; N question ; B 77 0 509 738 ;
+C 64 ; WX 1015 ; N at ; B 34 -146 951 737 ;
+C 65 ; WX 667 ; N A ; B 17 0 653 729 ;
+C 66 ; WX 667 ; N B ; B 79 0 623 729 ;
+C 67 ; WX 722 ; N C ; B 48 -23 677 741 ;
+C 68 ; WX 722 ; N D ; B 89 0 667 729 ;
+C 69 ; WX 667 ; N E ; B 90 0 613 729 ;
+C 70 ; WX 611 ; N F ; B 90 0 579 729 ;
+C 71 ; WX 778 ; N G ; B 44 -23 709 741 ;
+C 72 ; WX 722 ; N H ; B 83 0 644 729 ;
+C 73 ; WX 278 ; N I ; B 100 0 194 729 ;
+C 74 ; WX 500 ; N J ; B 17 -26 426 729 ;
+C 75 ; WX 667 ; N K ; B 79 0 658 729 ;
+C 76 ; WX 556 ; N L ; B 80 0 533 729 ;
+C 77 ; WX 833 ; N M ; B 75 0 761 729 ;
+C 78 ; WX 722 ; N N ; B 76 0 646 729 ;
+C 79 ; WX 778 ; N O ; B 38 -23 742 741 ;
+C 80 ; WX 667 ; N P ; B 91 0 617 730 ;
+C 81 ; WX 778 ; N Q ; B 38 -59 742 741 ;
+C 82 ; WX 722 ; N R ; B 93 0 679 729 ;
+C 83 ; WX 667 ; N S ; B 48 -23 621 741 ;
+C 84 ; WX 611 ; N T ; B 21 0 593 729 ;
+C 85 ; WX 722 ; N U ; B 85 -23 645 729 ;
+C 86 ; WX 667 ; N V ; B 30 0 645 729 ;
+C 87 ; WX 944 ; N W ; B 22 0 929 729 ;
+C 88 ; WX 667 ; N X ; B 22 0 649 729 ;
+C 89 ; WX 667 ; N Y ; B 13 0 661 729 ;
+C 90 ; WX 611 ; N Z ; B 28 0 583 729 ;
+C 91 ; WX 278 ; N bracketleft ; B 64 -214 250 729 ;
+C 92 ; WX 278 ; N backslash ; B -8 -20 284 729 ;
+C 93 ; WX 278 ; N bracketright ; B 23 -215 209 729 ;
+C 94 ; WX 469 ; N asciicircum ; B 44 333 425 713 ;
+C 95 ; WX 556 ; N underscore ; B -22 -175 578 -125 ;
+C 96 ; WX 222 ; N quoteleft ; B 65 459 158 708 ;
+C 97 ; WX 556 ; N a ; B 42 -23 535 540 ;
+C 98 ; WX 556 ; N b ; B 54 -23 523 729 ;
+C 99 ; WX 500 ; N c ; B 31 -23 477 540 ;
+C 100 ; WX 556 ; N d ; B 26 -23 495 729 ;
+C 101 ; WX 556 ; N e ; B 40 -23 513 541 ;
+C 102 ; WX 278 ; N f ; B 18 0 258 733 ; L i fi ; L l fl ;
+C 103 ; WX 556 ; N g ; B 29 -220 489 540 ;
+C 104 ; WX 556 ; N h ; B 70 0 486 729 ;
+C 105 ; WX 222 ; N i ; B 66 0 150 729 ;
+C 106 ; WX 222 ; N j ; B -18 -220 153 729 ;
+C 107 ; WX 500 ; N k ; B 58 0 502 729 ;
+C 108 ; WX 222 ; N l ; B 68 0 152 729 ;
+C 109 ; WX 833 ; N m ; B 71 0 763 540 ;
+C 110 ; WX 556 ; N n ; B 70 0 487 540 ;
+C 111 ; WX 556 ; N o ; B 36 -23 510 540 ;
+C 112 ; WX 556 ; N p ; B 54 -219 523 540 ;
+C 113 ; WX 556 ; N q ; B 26 -219 495 540 ;
+C 114 ; WX 333 ; N r ; B 69 0 321 540 ;
+C 115 ; WX 500 ; N s ; B 34 -24 459 540 ;
+C 116 ; WX 278 ; N t ; B 14 -24 254 667 ;
+C 117 ; WX 556 ; N u ; B 65 -23 482 525 ;
+C 118 ; WX 500 ; N v ; B 10 0 486 525 ;
+C 119 ; WX 722 ; N w ; B 6 0 708 525 ;
+C 120 ; WX 500 ; N x ; B 17 0 473 525 ;
+C 121 ; WX 500 ; N y ; B 20 -219 478 525 ;
+C 122 ; WX 500 ; N z ; B 31 0 457 525 ;
+C 123 ; WX 334 ; N braceleft ; B 43 -214 276 731 ;
+C 124 ; WX 260 ; N bar ; B 100 -215 160 729 ;
+C 125 ; WX 334 ; N braceright ; B 29 -214 262 731 ;
+C 126 ; WX 584 ; N asciitilde ; B 75 267 508 438 ;
+C 161 ; WX 333 ; N exclamdown ; B 121 -214 205 525 ;
+C 162 ; WX 556 ; N cent ; B 52 -120 510 628 ;
+C 163 ; WX 556 ; N sterling ; B 26 -21 535 726 ;
+C 164 ; WX 167 ; N fraction ; B -174 -21 336 708 ;
+C 165 ; WX 556 ; N yen ; B 11 0 545 710 ;
+C 166 ; WX 556 ; N florin ; B 11 -214 542 742 ;
+C 167 ; WX 556 ; N section ; B 44 -215 506 729 ;
+C 168 ; WX 556 ; N currency ; B 67 126 489 554 ;
+C 169 ; WX 191 ; N quotesingle ; B 48 462 142 708 ;
+C 170 ; WX 333 ; N quotedblleft ; B 48 459 299 708 ;
+C 171 ; WX 556 ; N guillemotleft ; B 98 106 455 438 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 91 112 243 436 ;
+C 173 ; WX 333 ; N guilsinglright ; B 85 112 239 436 ;
+C 174 ; WX 500 ; N fi ; B 12 0 436 733 ;
+C 175 ; WX 500 ; N fl ; B 17 0 430 733 ;
+C 177 ; WX 556 ; N endash ; B -5 240 561 313 ;
+C 178 ; WX 556 ; N dagger ; B 38 -178 513 710 ;
+C 179 ; WX 556 ; N daggerdbl ; B 38 -178 513 710 ;
+C 180 ; WX 278 ; N periodcentered ; B 87 318 211 442 ;
+C 182 ; WX 537 ; N paragraph ; B 48 -178 522 729 ;
+C 183 ; WX 350 ; N bullet ; B 50 220 300 470 ;
+C 184 ; WX 222 ; N quotesinglbase ; B 64 -129 158 103 ;
+C 185 ; WX 333 ; N quotedblbase ; B 47 -129 300 103 ;
+C 186 ; WX 333 ; N quotedblright ; B 49 476 302 708 ;
+C 187 ; WX 556 ; N guillemotright ; B 98 106 451 438 ;
+C 188 ; WX 1000 ; N ellipsis ; B 115 0 885 104 ;
+C 189 ; WX 1000 ; N perthousand ; B 9 -20 993 740 ;
+C 191 ; WX 611 ; N questiondown ; B 95 -213 528 525 ;
+C 193 ; WX 333 ; N grave ; B 22 592 231 740 ;
+C 194 ; WX 333 ; N acute ; B 92 592 301 740 ;
+C 195 ; WX 333 ; N circumflex ; B 20 591 307 741 ;
+C 196 ; WX 333 ; N tilde ; B 5 589 319 716 ;
+C 197 ; WX 333 ; N macron ; B 28 621 302 694 ;
+C 198 ; WX 333 ; N breve ; B 15 594 316 729 ;
+C 199 ; WX 333 ; N dotaccent ; B 115 605 219 709 ;
+C 200 ; WX 333 ; N dieresis ; B 30 605 296 708 ;
+C 202 ; WX 333 ; N ring ; B 79 566 255 741 ;
+C 203 ; WX 333 ; N cedilla ; B 39 -214 287 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B -35 592 348 740 ;
+C 206 ; WX 333 ; N ogonek ; B 57 -189 265 15 ;
+C 207 ; WX 333 ; N caron ; B 19 590 306 740 ;
+C 208 ; WX 1000 ; N emdash ; B -9 240 1001 313 ;
+C 225 ; WX 1000 ; N AE ; B 11 0 950 729 ;
+C 227 ; WX 370 ; N ordfeminine ; B 37 301 333 740 ;
+C 232 ; WX 556 ; N Lslash ; B 0 0 552 729 ;
+C 233 ; WX 778 ; N Oslash ; B 30 -23 744 742 ;
+C 234 ; WX 1000 ; N OE ; B 43 -20 959 739 ;
+C 235 ; WX 365 ; N ordmasculine ; B 40 301 324 741 ;
+C 241 ; WX 889 ; N ae ; B 34 -20 845 546 ;
+C 245 ; WX 278 ; N dotlessi ; B 94 0 178 525 ;
+C 248 ; WX 222 ; N lslash ; B 0 0 212 729 ;
+C 249 ; WX 611 ; N oslash ; B 18 -27 529 548 ;
+C 250 ; WX 944 ; N oe ; B 40 -22 899 540 ;
+C 251 ; WX 611 ; N germandbls ; B 126 -20 566 729 ;
+C -1 ; WX 667 ; N Aacute ; B 17 0 653 939 ;
+C -1 ; WX 667 ; N Acircumflex ; B 17 0 653 940 ;
+C -1 ; WX 667 ; N Adieresis ; B 17 0 653 907 ;
+C -1 ; WX 667 ; N Agrave ; B 17 0 653 939 ;
+C -1 ; WX 667 ; N Aring ; B 17 0 653 940 ;
+C -1 ; WX 667 ; N Atilde ; B 17 0 653 915 ;
+C -1 ; WX 722 ; N Ccedilla ; B 48 -214 677 741 ;
+C -1 ; WX 667 ; N Eacute ; B 90 0 613 939 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 90 0 613 940 ;
+C -1 ; WX 667 ; N Edieresis ; B 90 0 613 907 ;
+C -1 ; WX 667 ; N Egrave ; B 90 0 613 939 ;
+C -1 ; WX 722 ; N Eth ; B 0 0 667 729 ;
+C -1 ; WX 278 ; N Iacute ; B 71 0 280 939 ;
+C -1 ; WX 278 ; N Icircumflex ; B -1 0 286 940 ;
+C -1 ; WX 278 ; N Idieresis ; B 9 0 275 907 ;
+C -1 ; WX 278 ; N Igrave ; B 1 0 210 939 ;
+C -1 ; WX 722 ; N Ntilde ; B 76 0 646 915 ;
+C -1 ; WX 778 ; N Oacute ; B 38 -23 742 939 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 38 -23 742 940 ;
+C -1 ; WX 778 ; N Odieresis ; B 38 -23 742 907 ;
+C -1 ; WX 778 ; N Ograve ; B 38 -23 742 939 ;
+C -1 ; WX 778 ; N Otilde ; B 38 -23 742 915 ;
+C -1 ; WX 667 ; N Scaron ; B 48 -23 621 939 ;
+C -1 ; WX 667 ; N Thorn ; B 91 0 617 729 ;
+C -1 ; WX 722 ; N Uacute ; B 85 -23 645 939 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 85 -23 645 940 ;
+C -1 ; WX 722 ; N Udieresis ; B 85 -23 645 907 ;
+C -1 ; WX 722 ; N Ugrave ; B 85 -23 645 939 ;
+C -1 ; WX 667 ; N Yacute ; B 13 0 661 944 ;
+C -1 ; WX 667 ; N Ydieresis ; B 13 0 661 907 ;
+C -1 ; WX 611 ; N Zcaron ; B 28 0 583 939 ;
+C -1 ; WX 556 ; N aacute ; B 42 -23 535 740 ;
+C -1 ; WX 556 ; N acircumflex ; B 42 -23 535 741 ;
+C -1 ; WX 556 ; N adieresis ; B 42 -23 535 708 ;
+C -1 ; WX 556 ; N agrave ; B 42 -23 535 740 ;
+C -1 ; WX 556 ; N aring ; B 42 -23 535 741 ;
+C -1 ; WX 556 ; N atilde ; B 42 -23 535 716 ;
+C -1 ; WX 260 ; N brokenbar ; B 100 -215 160 729 ;
+C -1 ; WX 500 ; N ccedilla ; B 31 -214 477 540 ;
+C -1 ; WX 737 ; N copyright ; B -13 -23 751 741 ;
+C -1 ; WX 400 ; N degree ; B 50 409 350 709 ;
+C -1 ; WX 584 ; N divide ; B 50 -10 534 474 ;
+C -1 ; WX 556 ; N eacute ; B 40 -23 513 740 ;
+C -1 ; WX 556 ; N ecircumflex ; B 40 -23 513 741 ;
+C -1 ; WX 556 ; N edieresis ; B 40 -23 513 708 ;
+C -1 ; WX 556 ; N egrave ; B 40 -23 513 740 ;
+C -1 ; WX 556 ; N eth ; B 36 -23 510 729 ;
+C -1 ; WX 278 ; N iacute ; B 65 0 274 740 ;
+C -1 ; WX 278 ; N icircumflex ; B -7 0 280 741 ;
+C -1 ; WX 278 ; N idieresis ; B 3 0 269 708 ;
+C -1 ; WX 278 ; N igrave ; B -5 0 204 740 ;
+C -1 ; WX 584 ; N logicalnot ; B 40 82 544 352 ;
+C -1 ; WX 584 ; N minus ; B 40 194 544 270 ;
+C -1 ; WX 556 ; N mu ; B 65 -219 482 525 ;
+C -1 ; WX 584 ; N multiply ; B 50 -10 534 476 ;
+C -1 ; WX 556 ; N ntilde ; B 70 0 487 716 ;
+C -1 ; WX 556 ; N oacute ; B 36 -23 510 740 ;
+C -1 ; WX 556 ; N ocircumflex ; B 36 -23 510 741 ;
+C -1 ; WX 556 ; N odieresis ; B 36 -23 510 708 ;
+C -1 ; WX 556 ; N ograve ; B 36 -23 510 740 ;
+C -1 ; WX 834 ; N onehalf ; B 30 -21 804 709 ;
+C -1 ; WX 834 ; N onequarter ; B 30 -21 804 709 ;
+C -1 ; WX 333 ; N onesuperior ; B 60 284 219 709 ;
+C -1 ; WX 556 ; N otilde ; B 36 -23 510 716 ;
+C -1 ; WX 584 ; N plusminus ; B 40 0 544 618 ;
+C -1 ; WX 737 ; N registered ; B -13 -23 751 741 ;
+C -1 ; WX 500 ; N scaron ; B 34 -24 459 740 ;
+C -1 ; WX 556 ; N thorn ; B 54 -219 523 729 ;
+C -1 ; WX 834 ; N threequarters ; B 30 -21 804 709 ;
+C -1 ; WX 333 ; N threesuperior ; B 12 270 320 709 ;
+C -1 ; WX 1000 ; N trademark ; B 63 320 938 741 ;
+C -1 ; WX 333 ; N twosuperior ; B 11 284 321 710 ;
+C -1 ; WX 556 ; N uacute ; B 65 -23 482 740 ;
+C -1 ; WX 556 ; N ucircumflex ; B 65 -23 482 741 ;
+C -1 ; WX 556 ; N udieresis ; B 65 -23 482 708 ;
+C -1 ; WX 556 ; N ugrave ; B 65 -23 482 740 ;
+C -1 ; WX 500 ; N yacute ; B 20 -219 478 740 ;
+C -1 ; WX 500 ; N ydieresis ; B 20 -219 478 708 ;
+C -1 ; WX 500 ; N zcaron ; B 31 0 457 740 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 105
+
+KPX A y -18
+KPX A w -18
+KPX A v -18
+KPX A space -55
+KPX A quoteright -74
+KPX A Y -74
+KPX A W -37
+KPX A V -74
+KPX A T -74
+
+KPX F period -111
+KPX F comma -111
+KPX F A -55
+
+KPX L y -37
+KPX L space -37
+KPX L quoteright -55
+KPX L Y -74
+KPX L W -74
+KPX L V -74
+KPX L T -74
+
+KPX P space -18
+KPX P period -129
+KPX P comma -129
+KPX P A -74
+
+KPX R Y -18
+KPX R W -18
+KPX R V -18
+KPX R T -18
+
+KPX T y -55
+KPX T w -55
+KPX T u -37
+KPX T space -18
+KPX T semicolon -111
+KPX T s -111
+KPX T r -37
+KPX T period -111
+KPX T o -111
+KPX T i -37
+KPX T hyphen -55
+KPX T e -111
+KPX T comma -111
+KPX T colon -111
+KPX T c -111
+KPX T a -111
+KPX T O -18
+KPX T A -74
+
+KPX V y -37
+KPX V u -37
+KPX V semicolon -37
+KPX V r -37
+KPX V period -92
+KPX V o -55
+KPX V i -18
+KPX V hyphen -55
+KPX V e -55
+KPX V comma -92
+KPX V colon -37
+KPX V a -74
+KPX V A -74
+
+KPX W y -9
+KPX W u -18
+KPX W semicolon -18
+KPX W r -18
+KPX W period -55
+KPX W o -18
+KPX W i 0
+KPX W hyphen -18
+KPX W e -18
+KPX W comma -55
+KPX W colon -18
+KPX W a -37
+KPX W A -37
+
+KPX Y v -55
+KPX Y u -55
+KPX Y space -18
+KPX Y semicolon -65
+KPX Y q -92
+KPX Y period -129
+KPX Y p -74
+KPX Y o -92
+KPX Y i -37
+KPX Y hyphen -92
+KPX Y e -92
+KPX Y comma -129
+KPX Y colon -55
+KPX Y a -74
+KPX Y A -74
+
+KPX f quoteright 18
+KPX f f -18
+
+KPX one one -74
+
+KPX quoteleft quoteleft -18
+
+KPX quoteright space -37
+KPX quoteright s -18
+KPX quoteright quoteright -18
+
+KPX r quoteright 37
+KPX r period -55
+KPX r comma -55
+
+KPX space Y -18
+KPX space T -18
+KPX space A -55
+
+KPX v period -74
+KPX v comma -74
+
+KPX w period -55
+KPX w comma -55
+
+KPX y period -74
+KPX y comma -74
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 199 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 83 0 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 167 199 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 83 0 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 207 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 96 0 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 167 199 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 83 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 194 199 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 194 199 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 194 199 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 194 199 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 111 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 111 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 111 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 111 0 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute -21 199 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -21 199 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -21 199 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave -21 199 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 188 199 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 188 199 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 188 199 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 188 199 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 117 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 117 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 117 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 117 0 ;
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 167 199 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 167 199 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 167 199 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 167 199 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 111 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 111 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 111 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 111 0 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 222 199 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 222 199 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 222 199 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 222 199 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 111 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 111 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 111 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 111 0 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 167 199 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 111 0 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 200 199 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 117 0 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 222 199 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 111 0 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 167 199 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 111 0 ;
+EndComposites
+EndFontMetrics
diff --git a/samples/printing/HelvBo.afm b/samples/printing/HelvBo.afm
new file mode 100644
index 0000000000..5f14f52069
--- /dev/null
+++ b/samples/printing/HelvBo.afm
@@ -0,0 +1,431 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1984 Adobe Systems Incorporated. 	All Rights Reserved.
+Comment Creation Date:Tue Aug 5 11:40:08 PDT 1986
+FontName Helvetica-Bold
+EncodingScheme AdobeStandardEncoding
+FullName Helvetica Bold
+FamilyName Helvetica
+Weight Bold
+ItalicAngle 0.0
+IsFixedPitch false
+UnderlinePosition -106
+UnderlineThickness 73
+Version 001.001
+Notice Helvetica is a registered trademark of Allied Corporation.
+FontBBox -173 -221 1003 936
+CapHeight 729
+XHeight 542
+Descender -219
+Ascender 729
+StartCharMetrics 228
+C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 112 0 262 729 ;
+C 34 ; WX 474 ; N quotedbl ; B 50 470 424 729 ;
+C 35 ; WX 556 ; N numbersign ; B 3 -30 553 696 ;
+C 36 ; WX 556 ; N dollar ; B 22 -125 526 765 ;
+C 37 ; WX 889 ; N percent ; B 22 -18 863 708 ;
+C 38 ; WX 722 ; N ampersand ; B 55 -20 694 729 ;
+C 39 ; WX 278 ; N quoteright ; B 66 469 201 729 ;
+C 40 ; WX 333 ; N parenleft ; B 40 -202 303 729 ;
+C 41 ; WX 333 ; N parenright ; B 22 -202 285 729 ;
+C 42 ; WX 389 ; N asterisk ; B 23 385 356 730 ;
+C 43 ; WX 584 ; N plus ; B 50 -10 534 474 ;
+C 44 ; WX 278 ; N comma ; B 64 -174 214 146 ;
+C 45 ; WX 333 ; N hyphen ; B 26 208 298 344 ;
+C 46 ; WX 278 ; N period ; B 64 0 214 146 ;
+C 47 ; WX 278 ; N slash ; B 2 -14 275 715 ;
+C 48 ; WX 556 ; N zero ; B 29 -23 517 725 ;
+C 49 ; WX 556 ; N one ; B 68 0 378 709 ;
+C 50 ; WX 556 ; N two ; B 30 0 515 726 ;
+C 51 ; WX 556 ; N three ; B 29 -23 516 726 ;
+C 52 ; WX 556 ; N four ; B 24 0 522 709 ;
+C 53 ; WX 556 ; N five ; B 27 -24 517 709 ;
+C 54 ; WX 556 ; N six ; B 32 -23 519 727 ;
+C 55 ; WX 556 ; N seven ; B 29 0 528 709 ;
+C 56 ; WX 556 ; N eight ; B 22 -23 525 726 ;
+C 57 ; WX 556 ; N nine ; B 28 -23 516 728 ;
+C 58 ; WX 333 ; N colon ; B 113 0 263 521 ;
+C 59 ; WX 333 ; N semicolon ; B 113 -174 263 521 ;
+C 60 ; WX 584 ; N less ; B 40 -10 529 474 ;
+C 61 ; WX 584 ; N equal ; B 50 52 534 412 ;
+C 62 ; WX 584 ; N greater ; B 40 -10 529 474 ;
+C 63 ; WX 611 ; N question ; B 64 0 556 744 ;
+C 64 ; WX 975 ; N at ; B 27 -136 947 746 ;
+C 65 ; WX 722 ; N A ; B 26 0 703 729 ;
+C 66 ; WX 722 ; N B ; B 82 0 666 729 ;
+C 67 ; WX 722 ; N C ; B 44 -23 685 741 ;
+C 68 ; WX 722 ; N D ; B 77 0 681 729 ;
+C 69 ; WX 667 ; N E ; B 79 0 624 729 ;
+C 70 ; WX 611 ; N F ; B 74 0 586 729 ;
+C 71 ; WX 778 ; N G ; B 42 -24 711 741 ;
+C 72 ; WX 722 ; N H ; B 68 0 657 729 ;
+C 73 ; WX 278 ; N I ; B 63 0 213 729 ;
+C 74 ; WX 556 ; N J ; B 24 -23 486 729 ;
+C 75 ; WX 722 ; N K ; B 74 0 717 729 ;
+C 76 ; WX 611 ; N L ; B 80 0 579 729 ;
+C 77 ; WX 833 ; N M ; B 66 0 776 729 ;
+C 78 ; WX 722 ; N N ; B 68 0 661 729 ;
+C 79 ; WX 778 ; N O ; B 40 -23 742 741 ;
+C 80 ; WX 667 ; N P ; B 76 0 633 729 ;
+C 81 ; WX 778 ; N Q ; B 43 -54 745 741 ;
+C 82 ; WX 722 ; N R ; B 80 0 677 729 ;
+C 83 ; WX 667 ; N S ; B 32 -23 633 741 ;
+C 84 ; WX 611 ; N T ; B 14 0 598 729 ;
+C 85 ; WX 722 ; N U ; B 76 -23 654 729 ;
+C 86 ; WX 667 ; N V ; B 24 0 647 729 ;
+C 87 ; WX 944 ; N W ; B 13 0 932 729 ;
+C 88 ; WX 667 ; N X ; B 22 0 653 729 ;
+C 89 ; WX 667 ; N Y ; B 27 0 650 729 ;
+C 90 ; WX 611 ; N Z ; B 30 0 578 729 ;
+C 91 ; WX 333 ; N bracketleft ; B 66 -202 308 729 ;
+C 92 ; WX 278 ; N backslash ; B -12 -21 289 708 ;
+C 93 ; WX 333 ; N bracketright ; B 18 -202 260 729 ;
+C 94 ; WX 584 ; N asciicircum ; B 61 271 522 696 ;
+C 95 ; WX 556 ; N underscore ; B -22 -200 578 -130 ;
+C 96 ; WX 278 ; N quoteleft ; B 67 469 202 729 ;
+C 97 ; WX 556 ; N a ; B 27 -24 524 551 ;
+C 98 ; WX 611 ; N b ; B 59 -23 575 729 ;
+C 99 ; WX 556 ; N c ; B 34 -23 522 551 ;
+C 100 ; WX 611 ; N d ; B 29 -23 545 729 ;
+C 101 ; WX 556 ; N e ; B 22 -23 525 551 ;
+C 102 ; WX 333 ; N f ; B 14 0 313 729 ; L i fi ; L l fl ;
+C 103 ; WX 611 ; N g ; B 34 -220 541 551 ;
+C 104 ; WX 611 ; N h ; B 67 0 541 729 ;
+C 105 ; WX 278 ; N i ; B 67 0 207 729 ;
+C 106 ; WX 278 ; N j ; B 4 -219 210 729 ;
+C 107 ; WX 556 ; N k ; B 59 0 548 729 ;
+C 108 ; WX 278 ; N l ; B 67 0 207 729 ;
+C 109 ; WX 889 ; N m ; B 60 0 824 553 ;
+C 110 ; WX 611 ; N n ; B 63 0 546 551 ;
+C 111 ; WX 611 ; N o ; B 35 -23 569 551 ;
+C 112 ; WX 611 ; N p ; B 58 -219 574 551 ;
+C 113 ; WX 611 ; N q ; B 28 -219 544 551 ;
+C 114 ; WX 389 ; N r ; B 63 0 370 553 ;
+C 115 ; WX 556 ; N s ; B 29 -23 520 551 ;
+C 116 ; WX 333 ; N t ; B 14 -23 301 678 ;
+C 117 ; WX 611 ; N u ; B 58 -23 541 542 ;
+C 118 ; WX 556 ; N v ; B 14 0 536 542 ;
+C 119 ; WX 778 ; N w ; B 5 0 766 542 ;
+C 120 ; WX 556 ; N x ; B 16 0 535 542 ;
+C 121 ; WX 556 ; N y ; B 9 -219 538 542 ;
+C 122 ; WX 500 ; N z ; B 21 0 468 542 ;
+C 123 ; WX 389 ; N braceleft ; B 37 -202 317 729 ;
+C 124 ; WX 280 ; N bar ; B 100 -202 180 729 ;
+C 125 ; WX 389 ; N braceright ; B 72 -202 352 729 ;
+C 126 ; WX 584 ; N asciitilde ; B 60 144 519 322 ;
+C 161 ; WX 333 ; N exclamdown ; B 66 -187 216 542 ;
+C 162 ; WX 556 ; N cent ; B 37 -122 522 637 ;
+C 163 ; WX 556 ; N sterling ; B 31 -20 537 717 ;
+C 164 ; WX 167 ; N fraction ; B -173 -20 337 715 ;
+C 165 ; WX 556 ; N yen ; B 5 0 552 705 ;
+C 166 ; WX 556 ; N florin ; B 21 -221 535 745 ;
+C 167 ; WX 556 ; N section ; B 33 -201 518 728 ;
+C 168 ; WX 556 ; N currency ; B 26 105 530 604 ;
+C 169 ; WX 238 ; N quotesingle ; B 50 469 188 729 ;
+C 170 ; WX 500 ; N quotedblleft ; B 71 469 433 729 ;
+C 171 ; WX 556 ; N guillemotleft ; B 88 71 468 484 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 83 73 250 476 ;
+C 173 ; WX 333 ; N guilsinglright ; B 80 73 247 476 ;
+C 174 ; WX 611 ; N fi ; B 9 0 548 729 ;
+C 175 ; WX 611 ; N fl ; B 12 0 546 729 ;
+C 177 ; WX 556 ; N endash ; B -9 208 557 313 ;
+C 178 ; WX 556 ; N dagger ; B 31 -195 523 708 ;
+C 179 ; WX 556 ; N daggerdbl ; B 28 -195 520 708 ;
+C 180 ; WX 278 ; N periodcentered ; B 64 318 188 442 ;
+C 182 ; WX 556 ; N paragraph ; B 20 -195 529 729 ;
+C 183 ; WX 350 ; N bullet ; B 50 175 300 425 ;
+C 184 ; WX 278 ; N quotesinglbase ; B 66 -135 201 125 ;
+C 185 ; WX 500 ; N quotedblbase ; B 72 -164 432 141 ;
+C 186 ; WX 500 ; N quotedblright ; B 73 469 440 729 ;
+C 187 ; WX 556 ; N guillemotright ; B 88 71 462 482 ;
+C 188 ; WX 1000 ; N ellipsis ; B 92 0 908 146 ;
+C 189 ; WX 1000 ; N perthousand ; B 11 -20 990 745 ;
+C 191 ; WX 611 ; N questiondown ; B 51 -192 544 542 ;
+C 193 ; WX 333 ; N grave ; B 17 595 213 745 ;
+C 194 ; WX 333 ; N acute ; B 121 595 317 745 ;
+C 195 ; WX 333 ; N circumflex ; B 8 598 326 745 ;
+C 196 ; WX 333 ; N tilde ; B -9 595 345 729 ;
+C 197 ; WX 333 ; N macron ; B 16 629 315 717 ;
+C 198 ; WX 333 ; N breve ; B 35 593 299 736 ;
+C 199 ; WX 333 ; N dotaccent ; B 112 607 222 729 ;
+C 200 ; WX 333 ; N dieresis ; B 18 609 314 731 ;
+C 202 ; WX 333 ; N ring ; B 77 565 257 745 ;
+C 203 ; WX 333 ; N cedilla ; B 27 -220 294 -9 ;
+C 205 ; WX 333 ; N hungarumlaut ; B -44 595 340 745 ;
+C 206 ; WX 333 ; N ogonek ; B 45 -195 268 38 ;
+C 207 ; WX 333 ; N caron ; B 9 598 327 745 ;
+C 208 ; WX 1000 ; N emdash ; B -7 208 1003 313 ;
+C 225 ; WX 1000 ; N AE ; B 1 0 966 729 ;
+C 227 ; WX 370 ; N ordfeminine ; B 31 277 329 746 ;
+C 232 ; WX 611 ; N Lslash ; B 0 0 597 729 ;
+C 233 ; WX 778 ; N Oslash ; B 31 -34 755 754 ;
+C 234 ; WX 1000 ; N OE ; B 28 -20 970 741 ;
+C 235 ; WX 365 ; N ordmasculine ; B 23 276 343 745 ;
+C 241 ; WX 889 ; N ae ; B 27 -20 857 555 ;
+C 245 ; WX 278 ; N dotlessi ; B 67 0 207 542 ;
+C 248 ; WX 278 ; N lslash ; B 0 0 252 729 ;
+C 249 ; WX 611 ; N oslash ; B 11 -34 598 561 ;
+C 250 ; WX 944 ; N oe ; B 23 -21 920 554 ;
+C 251 ; WX 611 ; N germandbls ; B 67 -16 575 730 ;
+C -1 ; WX 722 ; N Aacute ; B 26 0 703 936 ;
+C -1 ; WX 722 ; N Acircumflex ; B 26 0 703 936 ;
+C -1 ; WX 722 ; N Adieresis ; B 26 0 703 922 ;
+C -1 ; WX 722 ; N Agrave ; B 26 0 703 936 ;
+C -1 ; WX 722 ; N Aring ; B 26 0 703 936 ;
+C -1 ; WX 722 ; N Atilde ; B 26 0 703 920 ;
+C -1 ; WX 722 ; N Ccedilla ; B 44 -220 685 741 ;
+C -1 ; WX 667 ; N Eacute ; B 79 0 624 936 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 79 0 624 936 ;
+C -1 ; WX 667 ; N Edieresis ; B 79 0 624 922 ;
+C -1 ; WX 667 ; N Egrave ; B 79 0 624 936 ;
+C -1 ; WX 722 ; N Eth ; B -18 0 681 729 ;
+C -1 ; WX 278 ; N Iacute ; B 63 0 290 936 ;
+C -1 ; WX 278 ; N Icircumflex ; B -19 0 299 936 ;
+C -1 ; WX 278 ; N Idieresis ; B -9 0 287 922 ;
+C -1 ; WX 278 ; N Igrave ; B -10 0 213 936 ;
+C -1 ; WX 722 ; N Ntilde ; B 68 0 661 920 ;
+C -1 ; WX 778 ; N Oacute ; B 40 -23 742 936 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 40 -23 742 936 ;
+C -1 ; WX 778 ; N Odieresis ; B 40 -23 742 922 ;
+C -1 ; WX 778 ; N Ograve ; B 40 -23 742 936 ;
+C -1 ; WX 778 ; N Otilde ; B 40 -23 742 920 ;
+C -1 ; WX 667 ; N Scaron ; B 32 -23 633 936 ;
+C -1 ; WX 667 ; N Thorn ; B 76 0 633 729 ;
+C -1 ; WX 722 ; N Uacute ; B 76 -23 654 936 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 76 -23 654 936 ;
+C -1 ; WX 722 ; N Udieresis ; B 76 -23 654 922 ;
+C -1 ; WX 722 ; N Ugrave ; B 76 -23 654 936 ;
+C -1 ; WX 667 ; N Yacute ; B 27 0 650 932 ;
+C -1 ; WX 667 ; N Ydieresis ; B 27 0 650 922 ;
+C -1 ; WX 611 ; N Zcaron ; B 30 0 578 936 ;
+C -1 ; WX 556 ; N aacute ; B 27 -24 524 745 ;
+C -1 ; WX 556 ; N acircumflex ; B 27 -24 524 745 ;
+C -1 ; WX 556 ; N adieresis ; B 27 -24 524 731 ;
+C -1 ; WX 556 ; N agrave ; B 27 -24 524 745 ;
+C -1 ; WX 556 ; N aring ; B 27 -24 524 745 ;
+C -1 ; WX 556 ; N atilde ; B 27 -24 524 729 ;
+C -1 ; WX 280 ; N brokenbar ; B 100 -202 180 729 ;
+C -1 ; WX 556 ; N ccedilla ; B 34 -220 522 551 ;
+C -1 ; WX 737 ; N copyright ; B -14 -20 751 745 ;
+C -1 ; WX 400 ; N degree ; B 50 425 350 725 ;
+C -1 ; WX 584 ; N divide ; B 50 -10 534 474 ;
+C -1 ; WX 556 ; N eacute ; B 22 -23 525 745 ;
+C -1 ; WX 556 ; N ecircumflex ; B 22 -23 525 745 ;
+C -1 ; WX 556 ; N edieresis ; B 22 -23 525 731 ;
+C -1 ; WX 556 ; N egrave ; B 22 -23 525 745 ;
+C -1 ; WX 611 ; N eth ; B 35 -23 569 730 ;
+C -1 ; WX 278 ; N iacute ; B 67 0 290 745 ;
+C -1 ; WX 278 ; N icircumflex ; B -19 0 299 745 ;
+C -1 ; WX 278 ; N idieresis ; B -9 0 287 731 ;
+C -1 ; WX 278 ; N igrave ; B -10 0 207 745 ;
+C -1 ; WX 584 ; N logicalnot ; B 40 121 544 412 ;
+C -1 ; WX 584 ; N minus ; B 40 174 544 290 ;
+C -1 ; WX 611 ; N mu ; B 58 -219 541 542 ;
+C -1 ; WX 584 ; N multiply ; B 50 -10 534 474 ;
+C -1 ; WX 611 ; N ntilde ; B 63 0 546 729 ;
+C -1 ; WX 611 ; N oacute ; B 35 -23 569 745 ;
+C -1 ; WX 611 ; N ocircumflex ; B 35 -23 569 745 ;
+C -1 ; WX 611 ; N odieresis ; B 35 -23 569 731 ;
+C -1 ; WX 611 ; N ograve ; B 35 -23 569 745 ;
+C -1 ; WX 834 ; N onehalf ; B 30 -20 803 715 ;
+C -1 ; WX 834 ; N onequarter ; B 30 -20 804 715 ;
+C -1 ; WX 333 ; N onesuperior ; B 46 284 247 709 ;
+C -1 ; WX 611 ; N otilde ; B 35 -23 569 729 ;
+C -1 ; WX 584 ; N plusminus ; B 40 0 544 674 ;
+C -1 ; WX 737 ; N registered ; B -14 -20 751 745 ;
+C -1 ; WX 556 ; N scaron ; B 29 -23 520 745 ;
+C -1 ; WX 611 ; N thorn ; B 58 -219 574 729 ;
+C -1 ; WX 834 ; N threequarters ; B 30 -20 804 725 ;
+C -1 ; WX 333 ; N threesuperior ; B 8 271 325 720 ;
+C -1 ; WX 1000 ; N trademark ; B 71 341 929 745 ;
+C -1 ; WX 333 ; N twosuperior ; B 9 284 324 719 ;
+C -1 ; WX 611 ; N uacute ; B 58 -23 541 745 ;
+C -1 ; WX 611 ; N ucircumflex ; B 58 -23 541 745 ;
+C -1 ; WX 611 ; N udieresis ; B 58 -23 541 731 ;
+C -1 ; WX 611 ; N ugrave ; B 58 -23 541 745 ;
+C -1 ; WX 556 ; N yacute ; B 9 -219 538 745 ;
+C -1 ; WX 556 ; N ydieresis ; B 9 -219 538 731 ;
+C -1 ; WX 500 ; N zcaron ; B 21 0 468 745 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 101
+
+KPX A y -37
+KPX A w -18
+KPX A v -37
+KPX A space -37
+KPX A quoteright -55
+KPX A Y -92
+KPX A W -55
+KPX A V -74
+KPX A T -74
+
+KPX F period -111
+KPX F comma -111
+KPX F A -55
+
+KPX L y -37
+KPX L space -18
+KPX L quoteright -55
+KPX L Y -92
+KPX L W -55
+KPX L V -74
+KPX L T -74
+
+KPX P space -18
+KPX P period -129
+KPX P comma -129
+KPX P A -74
+
+KPX R Y -37
+KPX R W -18
+KPX R V -18
+
+KPX T y -74
+KPX T w -74
+KPX T u -74
+KPX T semicolon -111
+KPX T s -74
+KPX T r -55
+KPX T period -111
+KPX T o -74
+KPX T i -18
+KPX T hyphen -55
+KPX T e -74
+KPX T comma -111
+KPX T colon -111
+KPX T c -74
+KPX T a -74
+KPX T O -18
+KPX T A -74
+
+KPX V y -37
+KPX V u -37
+KPX V semicolon -55
+KPX V r -55
+KPX V period -92
+KPX V o -74
+KPX V i -18
+KPX V hyphen -55
+KPX V e -55
+KPX V comma -92
+KPX V colon -55
+KPX V a -55
+KPX V A -74
+
+KPX W y -18
+KPX W u -18
+KPX W semicolon -18
+KPX W r -18
+KPX W period -55
+KPX W o -18
+KPX W i -9
+KPX W hyphen -20
+KPX W e -18
+KPX W comma -55
+KPX W colon -18
+KPX W a -37
+KPX W A -55
+
+KPX Y v -55
+KPX Y u -55
+KPX Y space -18
+KPX Y semicolon -74
+KPX Y q -74
+KPX Y period -111
+KPX Y p -55
+KPX Y o -74
+KPX Y i -37
+KPX Y hyphen -55
+KPX Y e -55
+KPX Y comma -111
+KPX Y colon -74
+KPX Y a -55
+KPX Y A -92
+
+KPX f quoteright 18
+
+KPX one one -55
+
+KPX quoteleft quoteleft -37
+
+KPX quoteright space -55
+KPX quoteright s -37
+KPX quoteright quoteright -37
+
+KPX r quoteright 37
+KPX r period -55
+KPX r comma -55
+
+KPX space Y -18
+KPX space A -37
+
+KPX v period -74
+KPX v comma -74
+
+KPX w period -37
+KPX w comma -37
+
+KPX y period -74
+KPX y comma -74
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 191 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 83 0 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 167 191 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 111 0 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 207 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 117 0 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 167 191 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 111 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 197 191 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 197 191 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 197 191 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 197 191 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 139 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 139 0 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute -27 191 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -27 191 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -27 191 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave -27 191 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 188 191 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 188 191 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 188 191 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 188 191 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 111 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 111 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 111 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 111 0 ;
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 197 191 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 197 191 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 197 191 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 197 191 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 111 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 111 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 111 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 111 0 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 222 191 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 222 191 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 222 191 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 222 191 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 139 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 139 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 139 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 197 191 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 111 0 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 200 191 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 146 0 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 222 191 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 139 0 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 197 191 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 111 0 ;
+EndComposites
+EndFontMetrics
diff --git a/samples/printing/HelvBoO.afm b/samples/printing/HelvBoO.afm
new file mode 100644
index 0000000000..dfe3bef5cc
--- /dev/null
+++ b/samples/printing/HelvBoO.afm
@@ -0,0 +1,429 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1984 Adobe Systems Incorporated. 	All Rights Reserved.
+Comment Creation Date:Tue Aug 5 11:51:40 PDT 1986
+FontName Helvetica-BoldOblique
+EncodingScheme AdobeStandardEncoding
+FullName Helvetica Bold Oblique
+FamilyName Helvetica
+Weight Bold
+ItalicAngle -12.0
+IsFixedPitch false
+UnderlinePosition -106
+UnderlineThickness 105
+Version 001.001
+Notice Helvetica is a registered trademark of Allied Corporation
+FontBBox -177 -221 1107 936
+CapHeight 729
+XHeight 542
+Descender -219
+Ascender 729
+StartCharMetrics 228
+C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 112 0 417 729 ;
+C 34 ; WX 474 ; N quotedbl ; B 177 470 579 729 ;
+C 35 ; WX 556 ; N numbersign ; B 33 -30 660 696 ;
+C 36 ; WX 556 ; N dollar ; B 59 -125 628 765 ;
+C 37 ; WX 889 ; N percent ; B 129 -18 903 708 ;
+C 38 ; WX 722 ; N ampersand ; B 89 -20 720 729 ;
+C 39 ; WX 278 ; N quoteright ; B 166 469 356 729 ;
+C 40 ; WX 333 ; N parenleft ; B 84 -202 458 729 ;
+C 41 ; WX 333 ; N parenright ; B -21 -202 356 729 ;
+C 42 ; WX 389 ; N asterisk ; B 145 385 478 730 ;
+C 43 ; WX 584 ; N plus ; B 87 -10 596 474 ;
+C 44 ; WX 278 ; N comma ; B 27 -174 245 146 ;
+C 45 ; WX 333 ; N hyphen ; B 70 208 371 344 ;
+C 46 ; WX 278 ; N period ; B 64 0 245 146 ;
+C 47 ; WX 278 ; N slash ; B -1 -14 427 715 ;
+C 48 ; WX 556 ; N zero ; B 81 -23 614 725 ;
+C 49 ; WX 556 ; N one ; B 172 0 529 709 ;
+C 50 ; WX 556 ; N two ; B 30 0 628 726 ;
+C 51 ; WX 556 ; N three ; B 67 -23 613 726 ;
+C 52 ; WX 556 ; N four ; B 57 0 599 709 ;
+C 53 ; WX 556 ; N five ; B 59 -24 641 709 ;
+C 54 ; WX 556 ; N six ; B 85 -23 625 727 ;
+C 55 ; WX 556 ; N seven ; B 131 0 679 709 ;
+C 56 ; WX 556 ; N eight ; B 60 -23 620 726 ;
+C 57 ; WX 556 ; N nine ; B 68 -23 611 728 ;
+C 58 ; WX 333 ; N colon ; B 113 0 374 521 ;
+C 59 ; WX 333 ; N semicolon ; B 76 -174 374 521 ;
+C 60 ; WX 584 ; N less ; B 77 -10 630 474 ;
+C 61 ; WX 584 ; N equal ; B 61 52 622 412 ;
+C 62 ; WX 584 ; N greater ; B 38 -10 591 474 ;
+C 63 ; WX 611 ; N question ; B 168 0 672 744 ;
+C 64 ; WX 975 ; N at ; B 73 -136 1032 746 ;
+C 65 ; WX 722 ; N A ; B 26 0 703 729 ;
+C 66 ; WX 722 ; N B ; B 82 0 762 729 ;
+C 67 ; WX 722 ; N C ; B 107 -23 793 741 ;
+C 68 ; WX 722 ; N D ; B 77 0 776 729 ;
+C 69 ; WX 667 ; N E ; B 79 0 762 729 ;
+C 70 ; WX 611 ; N F ; B 74 0 741 729 ;
+C 71 ; WX 778 ; N G ; B 107 -24 819 741 ;
+C 72 ; WX 722 ; N H ; B 68 0 812 729 ;
+C 73 ; WX 278 ; N I ; B 63 0 368 729 ;
+C 74 ; WX 556 ; N J ; B 59 -23 641 729 ;
+C 75 ; WX 722 ; N K ; B 74 0 843 729 ;
+C 76 ; WX 611 ; N L ; B 80 0 606 729 ;
+C 77 ; WX 833 ; N M ; B 66 0 931 729 ;
+C 78 ; WX 722 ; N N ; B 68 0 816 729 ;
+C 79 ; WX 778 ; N O ; B 106 -23 828 741 ;
+C 80 ; WX 667 ; N P ; B 76 0 747 729 ;
+C 81 ; WX 778 ; N Q ; B 109 -54 831 741 ;
+C 82 ; WX 722 ; N R ; B 80 0 785 729 ;
+C 83 ; WX 667 ; N S ; B 76 -23 725 741 ;
+C 84 ; WX 611 ; N T ; B 142 0 753 729 ;
+C 85 ; WX 722 ; N U ; B 119 -23 809 729 ;
+C 86 ; WX 667 ; N V ; B 179 0 802 729 ;
+C 87 ; WX 944 ; N W ; B 168 0 1087 729 ;
+C 88 ; WX 667 ; N X ; B 22 0 802 729 ;
+C 89 ; WX 667 ; N Y ; B 182 0 805 729 ;
+C 90 ; WX 611 ; N Z ; B 30 0 733 729 ;
+C 91 ; WX 333 ; N bracketleft ; B 23 -202 463 729 ;
+C 92 ; WX 278 ; N backslash ; B 138 -21 285 708 ;
+C 93 ; WX 333 ; N bracketright ; B -25 -202 415 729 ;
+C 94 ; WX 584 ; N asciicircum ; B 119 271 580 696 ;
+C 95 ; WX 556 ; N underscore ; B -65 -200 550 -130 ;
+C 96 ; WX 278 ; N quoteleft ; B 167 469 357 729 ;
+C 97 ; WX 556 ; N a ; B 50 -24 578 551 ;
+C 98 ; WX 611 ; N b ; B 59 -23 640 729 ;
+C 99 ; WX 556 ; N c ; B 77 -23 597 551 ;
+C 100 ; WX 611 ; N d ; B 79 -23 700 729 ;
+C 101 ; WX 556 ; N e ; B 64 -23 591 551 ;
+C 102 ; WX 333 ; N f ; B 90 0 464 729 ; L i fi ; L l fl ;
+C 103 ; WX 611 ; N g ; B 26 -220 656 551 ;
+C 104 ; WX 611 ; N h ; B 67 0 629 729 ;
+C 105 ; WX 278 ; N i ; B 67 0 362 729 ;
+C 106 ; WX 278 ; N j ; B -43 -219 365 729 ;
+C 107 ; WX 556 ; N k ; B 59 0 651 729 ;
+C 108 ; WX 278 ; N l ; B 67 0 362 729 ;
+C 109 ; WX 889 ; N m ; B 60 0 911 553 ;
+C 110 ; WX 611 ; N n ; B 63 0 629 551 ;
+C 111 ; WX 611 ; N o ; B 82 -23 634 551 ;
+C 112 ; WX 611 ; N p ; B 11 -219 637 551 ;
+C 113 ; WX 611 ; N q ; B 72 -219 659 551 ;
+C 114 ; WX 389 ; N r ; B 63 0 487 553 ;
+C 115 ; WX 556 ; N s ; B 60 -23 589 551 ;
+C 116 ; WX 333 ; N t ; B 101 -23 414 678 ;
+C 117 ; WX 611 ; N u ; B 88 -23 656 542 ;
+C 118 ; WX 556 ; N v ; B 129 0 651 542 ;
+C 119 ; WX 778 ; N w ; B 120 0 881 542 ;
+C 120 ; WX 556 ; N x ; B 16 0 648 542 ;
+C 121 ; WX 556 ; N y ; B 37 -219 653 542 ;
+C 122 ; WX 500 ; N z ; B 21 0 575 542 ;
+C 123 ; WX 389 ; N braceleft ; B 84 -202 472 729 ;
+C 124 ; WX 280 ; N bar ; B 57 -202 335 729 ;
+C 125 ; WX 389 ; N braceright ; B 29 -202 419 729 ;
+C 126 ; WX 584 ; N asciitilde ; B 97 144 581 322 ;
+C 161 ; WX 333 ; N exclamdown ; B 26 -187 331 542 ;
+C 162 ; WX 556 ; N cent ; B 79 -122 598 637 ;
+C 163 ; WX 556 ; N sterling ; B 49 -20 629 717 ;
+C 164 ; WX 167 ; N fraction ; B -177 -20 489 715 ;
+C 165 ; WX 556 ; N yen ; B 107 0 702 705 ;
+C 166 ; WX 556 ; N florin ; B -21 -221 690 745 ;
+C 167 ; WX 556 ; N section ; B 56 -201 596 728 ;
+C 168 ; WX 556 ; N currency ; B 66 105 644 604 ;
+C 169 ; WX 238 ; N quotesingle ; B 177 469 343 729 ;
+C 170 ; WX 500 ; N quotedblleft ; B 171 469 588 729 ;
+C 171 ; WX 556 ; N guillemotleft ; B 135 71 571 484 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 128 73 351 476 ;
+C 173 ; WX 333 ; N guilsinglright ; B 96 73 319 476 ;
+C 174 ; WX 611 ; N fi ; B 85 0 703 729 ;
+C 175 ; WX 611 ; N fl ; B 88 0 701 729 ;
+C 177 ; WX 556 ; N endash ; B 35 208 624 313 ;
+C 178 ; WX 556 ; N dagger ; B 109 -195 626 708 ;
+C 179 ; WX 556 ; N daggerdbl ; B 35 -195 623 708 ;
+C 180 ; WX 278 ; N periodcentered ; B 143 318 270 442 ;
+C 182 ; WX 556 ; N paragraph ; B 121 -195 684 729 ;
+C 183 ; WX 350 ; N bullet ; B 111 175 367 425 ;
+C 184 ; WX 278 ; N quotesinglbase ; B 37 -135 228 125 ;
+C 185 ; WX 500 ; N quotedblbase ; B 37 -164 462 141 ;
+C 186 ; WX 500 ; N quotedblright ; B 173 469 595 729 ;
+C 187 ; WX 556 ; N guillemotright ; B 103 71 533 482 ;
+C 188 ; WX 1000 ; N ellipsis ; B 92 0 939 146 ;
+C 189 ; WX 1000 ; N perthousand ; B 72 -20 1021 745 ;
+C 191 ; WX 611 ; N questiondown ; B 52 -192 556 542 ;
+C 193 ; WX 333 ; N grave ; B 175 595 339 745 ;
+C 194 ; WX 333 ; N acute ; B 247 595 475 745 ;
+C 195 ; WX 333 ; N circumflex ; B 135 598 453 745 ;
+C 196 ; WX 333 ; N tilde ; B 117 595 500 729 ;
+C 197 ; WX 333 ; N macron ; B 150 629 467 717 ;
+C 198 ; WX 333 ; N breve ; B 188 593 455 736 ;
+C 199 ; WX 333 ; N dotaccent ; B 241 607 377 729 ;
+C 200 ; WX 333 ; N dieresis ; B 147 609 469 731 ;
+C 202 ; WX 333 ; N ring ; B 214 565 398 745 ;
+C 203 ; WX 333 ; N cedilla ; B -13 -220 270 -9 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 82 595 498 745 ;
+C 206 ; WX 333 ; N ogonek ; B 23 -195 248 38 ;
+C 207 ; WX 333 ; N caron ; B 167 598 485 745 ;
+C 208 ; WX 1000 ; N emdash ; B 37 208 1070 313 ;
+C 225 ; WX 1000 ; N AE ; B 1 0 1104 729 ;
+C 227 ; WX 370 ; N ordfeminine ; B 96 277 451 746 ;
+C 232 ; WX 611 ; N Lslash ; B 54 0 624 729 ;
+C 233 ; WX 778 ; N Oslash ; B 34 -34 906 754 ;
+C 234 ; WX 1000 ; N OE ; B 90 -20 1107 741 ;
+C 235 ; WX 365 ; N ordmasculine ; B 92 276 471 745 ;
+C 241 ; WX 889 ; N ae ; B 54 -20 927 555 ;
+C 245 ; WX 278 ; N dotlessi ; B 67 0 322 542 ;
+C 248 ; WX 278 ; N lslash ; B 50 0 372 729 ;
+C 249 ; WX 611 ; N oslash ; B 12 -34 709 561 ;
+C 250 ; WX 944 ; N oe ; B 71 -21 986 554 ;
+C 251 ; WX 611 ; N germandbls ; B 67 -16 654 730 ;
+C -1 ; WX 722 ; N Aacute ; B 26 0 714 936 ;
+C -1 ; WX 722 ; N Acircumflex ; B 26 0 703 936 ;
+C -1 ; WX 722 ; N Adieresis ; B 26 0 708 922 ;
+C -1 ; WX 722 ; N Agrave ; B 26 0 703 936 ;
+C -1 ; WX 722 ; N Aring ; B 26 0 703 936 ;
+C -1 ; WX 722 ; N Atilde ; B 26 0 739 920 ;
+C -1 ; WX 722 ; N Ccedilla ; B 107 -220 793 741 ;
+C -1 ; WX 667 ; N Eacute ; B 79 0 762 936 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 79 0 762 936 ;
+C -1 ; WX 667 ; N Edieresis ; B 79 0 762 922 ;
+C -1 ; WX 667 ; N Egrave ; B 79 0 762 936 ;
+C -1 ; WX 722 ; N Eth ; B 53 0 776 729 ;
+C -1 ; WX 278 ; N Iacute ; B 63 0 489 936 ;
+C -1 ; WX 278 ; N Icircumflex ; B 63 0 467 936 ;
+C -1 ; WX 278 ; N Idieresis ; B 63 0 483 922 ;
+C -1 ; WX 278 ; N Igrave ; B 63 0 368 936 ;
+C -1 ; WX 722 ; N Ntilde ; B 68 0 816 920 ;
+C -1 ; WX 778 ; N Oacute ; B 106 -23 828 936 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 106 -23 828 936 ;
+C -1 ; WX 778 ; N Odieresis ; B 106 -23 828 922 ;
+C -1 ; WX 778 ; N Ograve ; B 106 -23 828 936 ;
+C -1 ; WX 778 ; N Otilde ; B 106 -23 828 920 ;
+C -1 ; WX 667 ; N Scaron ; B 76 -23 725 936 ;
+C -1 ; WX 667 ; N Thorn ; B 76 0 730 729 ;
+C -1 ; WX 722 ; N Uacute ; B 119 -23 809 936 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 119 -23 809 936 ;
+C -1 ; WX 722 ; N Udieresis ; B 119 -23 809 922 ;
+C -1 ; WX 722 ; N Ugrave ; B 119 -23 809 936 ;
+C -1 ; WX 667 ; N Yacute ; B 182 0 805 932 ;
+C -1 ; WX 667 ; N Ydieresis ; B 182 0 805 922 ;
+C -1 ; WX 611 ; N Zcaron ; B 30 0 733 936 ;
+C -1 ; WX 556 ; N aacute ; B 50 -24 587 745 ;
+C -1 ; WX 556 ; N acircumflex ; B 50 -24 578 745 ;
+C -1 ; WX 556 ; N adieresis ; B 50 -24 581 731 ;
+C -1 ; WX 556 ; N agrave ; B 50 -24 578 745 ;
+C -1 ; WX 556 ; N aring ; B 50 -24 578 745 ;
+C -1 ; WX 556 ; N atilde ; B 50 -24 612 729 ;
+C -1 ; WX 280 ; N brokenbar ; B 57 -202 335 729 ;
+C -1 ; WX 556 ; N ccedilla ; B 77 -220 597 551 ;
+C -1 ; WX 737 ; N copyright ; B 54 -20 837 745 ;
+C -1 ; WX 400 ; N degree ; B 169 425 476 725 ;
+C -1 ; WX 584 ; N divide ; B 87 -10 596 474 ;
+C -1 ; WX 556 ; N eacute ; B 64 -23 591 745 ;
+C -1 ; WX 556 ; N ecircumflex ; B 64 -23 591 745 ;
+C -1 ; WX 556 ; N edieresis ; B 64 -23 591 731 ;
+C -1 ; WX 556 ; N egrave ; B 64 -23 591 745 ;
+C -1 ; WX 611 ; N eth ; B 82 -23 633 730 ;
+C -1 ; WX 278 ; N iacute ; B 67 0 448 745 ;
+C -1 ; WX 278 ; N icircumflex ; B 67 0 426 745 ;
+C -1 ; WX 278 ; N idieresis ; B 67 0 442 731 ;
+C -1 ; WX 278 ; N igrave ; B 67 0 322 745 ;
+C -1 ; WX 584 ; N logicalnot ; B 103 121 632 412 ;
+C -1 ; WX 584 ; N minus ; B 77 174 606 290 ;
+C -1 ; WX 611 ; N mu ; B 11 -219 656 542 ;
+C -1 ; WX 584 ; N multiply ; B 66 -10 617 474 ;
+C -1 ; WX 611 ; N ntilde ; B 63 0 646 729 ;
+C -1 ; WX 611 ; N oacute ; B 82 -23 634 745 ;
+C -1 ; WX 611 ; N ocircumflex ; B 82 -23 634 745 ;
+C -1 ; WX 611 ; N odieresis ; B 82 -23 634 731 ;
+C -1 ; WX 611 ; N ograve ; B 82 -23 634 745 ;
+C -1 ; WX 834 ; N onehalf ; B 120 -20 871 715 ;
+C -1 ; WX 834 ; N onequarter ; B 151 -20 846 715 ;
+C -1 ; WX 333 ; N onesuperior ; B 169 284 398 709 ;
+C -1 ; WX 611 ; N otilde ; B 82 -23 639 729 ;
+C -1 ; WX 584 ; N plusminus ; B 40 0 639 674 ;
+C -1 ; WX 737 ; N registered ; B 55 -20 837 745 ;
+C -1 ; WX 556 ; N scaron ; B 60 -23 597 745 ;
+C -1 ; WX 611 ; N thorn ; B 11 -219 641 729 ;
+C -1 ; WX 834 ; N threequarters ; B 116 -20 863 725 ;
+C -1 ; WX 333 ; N threesuperior ; B 92 271 442 720 ;
+C -1 ; WX 1000 ; N trademark ; B 213 341 1087 745 ;
+C -1 ; WX 333 ; N twosuperior ; B 69 284 452 719 ;
+C -1 ; WX 611 ; N uacute ; B 88 -23 656 745 ;
+C -1 ; WX 611 ; N ucircumflex ; B 88 -23 656 745 ;
+C -1 ; WX 611 ; N udieresis ; B 88 -23 656 731 ;
+C -1 ; WX 611 ; N ugrave ; B 88 -23 656 745 ;
+C -1 ; WX 556 ; N yacute ; B 37 -219 653 745 ;
+C -1 ; WX 556 ; N ydieresis ; B 37 -219 653 731 ;
+C -1 ; WX 500 ; N zcaron ; B 21 0 575 745 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 99
+
+KPX A space -37
+KPX A quoteright -55
+KPX A Y -74
+KPX A W -55
+KPX A V -74
+KPX A T -74
+
+KPX F period -111
+KPX F comma -111
+KPX F A -55
+
+KPX L space -18
+KPX L quoteright -74
+KPX L Y -74
+KPX L W -55
+KPX L V -55
+KPX L T -74
+
+KPX P space -37
+KPX P period -129
+KPX P comma -129
+KPX P A -74
+
+KPX R Y -18
+KPX R W -18
+KPX R T -18
+
+KPX T y -37
+KPX T w -37
+KPX T u -18
+KPX T semicolon -74
+KPX T s -37
+KPX T r -18
+KPX T period -74
+KPX T o -37
+KPX T i -18
+KPX T hyphen -55
+KPX T e -37
+KPX T comma -74
+KPX T colon -74
+KPX T c -37
+KPX T a -37
+KPX T O -18
+KPX T A -74
+
+KPX V y -18
+KPX V u -18
+KPX V semicolon -37
+KPX V r -18
+KPX V period -92
+KPX V o -37
+KPX V i -37
+KPX V hyphen -37
+KPX V e -37
+KPX V comma -92
+KPX V colon -37
+KPX V a -37
+KPX V A -74
+
+KPX W y -18
+KPX W u -18
+KPX W semicolon -37
+KPX W r -18
+KPX W period -74
+KPX W o -18
+KPX W i -9
+KPX W hyphen -37
+KPX W e -18
+KPX W comma -74
+KPX W colon -37
+KPX W a -18
+KPX W A -55
+
+KPX Y v -37
+KPX Y u -37
+KPX Y space -18
+KPX Y semicolon -55
+KPX Y q -37
+KPX Y period -92
+KPX Y p -37
+KPX Y i -37
+KPX Y o -37
+KPX Y hyphen -74
+KPX Y e -37
+KPX Y comma -92
+KPX Y colon -55
+KPX Y a -37
+KPX Y A -74
+
+KPX f quoteright 18
+KPX f f -18
+
+KPX one one -74
+
+KPX quoteleft quoteleft -37
+
+KPX quoteright t 18
+KPX quoteright space -37
+KPX quoteright s -18
+KPX quoteright quoteright -37
+
+KPX r quoteright 37
+KPX r period -55
+KPX r comma -55
+
+KPX space Y -18
+KPX space A -37
+
+KPX v period -55
+KPX v comma -55
+
+KPX w period -37
+KPX w comma -37
+
+KPX y period -37
+KPX y comma -37
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 187 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 83 0 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 167 187 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 111 0 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 194 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 111 0 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 167 187 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 111 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 194 187 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 194 187 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 194 187 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 194 187 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 139 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 139 0 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute -27 187 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -27 187 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -27 187 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave -27 187 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 167 187 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 167 187 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 167 187 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 167 187 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 111 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 111 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 111 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 111 0 ;
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 194 187 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 194 187 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 194 187 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 194 187 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 111 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 111 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 111 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 111 0 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 222 187 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 222 187 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 222 187 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 222 187 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 139 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 139 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 139 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 194 187 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 111 0 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 194 187 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 139 0 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 222 187 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 139 0 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 194 187 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 111 0 ;
+EndComposites
+EndFontMetrics
diff --git a/samples/printing/HelvO.afm b/samples/printing/HelvO.afm
new file mode 100644
index 0000000000..c24bdc1c20
--- /dev/null
+++ b/samples/printing/HelvO.afm
@@ -0,0 +1,428 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1984 Adobe Systems Incorporated. 	All Rights Reserved.
+Comment Creation Date:Tue Aug 5 11:45:36 PDT 1986
+FontName Helvetica-Oblique
+EncodingScheme AdobeStandardEncoding
+FullName Helvetica Oblique
+FamilyName Helvetica
+Weight Medium
+ItalicAngle -12.0
+IsFixedPitch false
+UnderlinePosition -106
+UnderlineThickness 73
+Version 001.001
+Notice Helvetica is a registered trademark of Allied Corporation.
+FontBBox -178 -220 1108 944
+CapHeight 729
+XHeight 525
+Descender -219
+Ascender 729
+StartCharMetrics 228
+C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 278 ; N exclam ; B 124 0 363 729 ;
+C 34 ; WX 355 ; N quotedbl ; B 177 462 455 708 ;
+C 35 ; WX 556 ; N numbersign ; B 54 -20 649 698 ;
+C 36 ; WX 556 ; N dollar ; B 69 -125 613 770 ;
+C 37 ; WX 889 ; N percent ; B 134 -20 895 708 ;
+C 38 ; WX 667 ; N ampersand ; B 83 -23 644 710 ;
+C 39 ; WX 222 ; N quoteright ; B 165 476 308 708 ;
+C 40 ; WX 333 ; N parenleft ; B 113 -213 446 729 ;
+C 41 ; WX 333 ; N parenright ; B -7 -213 325 729 ;
+C 42 ; WX 389 ; N asterisk ; B 169 452 471 740 ;
+C 43 ; WX 584 ; N plus ; B 92 -10 591 474 ;
+C 44 ; WX 278 ; N comma ; B 55 -150 214 104 ;
+C 45 ; WX 333 ; N hyphen ; B 97 240 351 313 ;
+C 46 ; WX 278 ; N period ; B 87 0 213 104 ;
+C 47 ; WX 278 ; N slash ; B -12 -21 434 708 ;
+C 48 ; WX 556 ; N zero ; B 98 -23 598 709 ;
+C 49 ; WX 556 ; N one ; B 208 0 498 709 ;
+C 50 ; WX 556 ; N two ; B 34 0 620 710 ;
+C 51 ; WX 556 ; N three ; B 71 -23 599 709 ;
+C 52 ; WX 556 ; N four ; B 63 0 573 709 ;
+C 53 ; WX 556 ; N five ; B 70 -23 629 709 ;
+C 54 ; WX 556 ; N six ; B 93 -23 611 709 ;
+C 55 ; WX 556 ; N seven ; B 137 0 671 709 ;
+C 56 ; WX 556 ; N eight ; B 74 -23 604 709 ;
+C 57 ; WX 556 ; N nine ; B 83 -23 599 709 ;
+C 58 ; WX 278 ; N colon ; B 110 0 326 525 ;
+C 59 ; WX 278 ; N semicolon ; B 78 -150 325 516 ;
+C 60 ; WX 584 ; N less ; B 87 -10 635 474 ;
+C 61 ; WX 584 ; N equal ; B 74 112 609 352 ;
+C 62 ; WX 584 ; N greater ; B 48 -10 596 474 ;
+C 63 ; WX 556 ; N question ; B 184 0 630 738 ;
+C 64 ; WX 1015 ; N at ; B 80 -146 1036 737 ;
+C 65 ; WX 667 ; N A ; B 17 0 653 729 ;
+C 66 ; WX 667 ; N B ; B 79 0 711 729 ;
+C 67 ; WX 722 ; N C ; B 112 -23 770 741 ;
+C 68 ; WX 722 ; N D ; B 89 0 759 729 ;
+C 69 ; WX 667 ; N E ; B 90 0 751 729 ;
+C 70 ; WX 611 ; N F ; B 90 0 734 729 ;
+C 71 ; WX 778 ; N G ; B 109 -23 809 741 ;
+C 72 ; WX 722 ; N H ; B 83 0 799 729 ;
+C 73 ; WX 278 ; N I ; B 100 0 349 729 ;
+C 74 ; WX 500 ; N J ; B 47 -26 581 729 ;
+C 75 ; WX 667 ; N K ; B 79 0 813 729 ;
+C 76 ; WX 556 ; N L ; B 80 0 551 729 ;
+C 77 ; WX 833 ; N M ; B 75 0 916 729 ;
+C 78 ; WX 722 ; N N ; B 76 0 801 729 ;
+C 79 ; WX 778 ; N O ; B 104 -23 828 741 ;
+C 80 ; WX 667 ; N P ; B 91 0 733 730 ;
+C 81 ; WX 778 ; N Q ; B 104 -59 828 741 ;
+C 82 ; WX 722 ; N R ; B 93 0 770 729 ;
+C 83 ; WX 667 ; N S ; B 89 -23 714 741 ;
+C 84 ; WX 611 ; N T ; B 158 0 748 729 ;
+C 85 ; WX 722 ; N U ; B 124 -23 800 729 ;
+C 86 ; WX 667 ; N V ; B 185 0 800 729 ;
+C 87 ; WX 944 ; N W ; B 177 0 1084 729 ;
+C 88 ; WX 667 ; N X ; B 22 0 794 729 ;
+C 89 ; WX 667 ; N Y ; B 168 0 816 729 ;
+C 90 ; WX 611 ; N Z ; B 28 0 737 729 ;
+C 91 ; WX 278 ; N bracketleft ; B 19 -214 405 729 ;
+C 92 ; WX 278 ; N backslash ; B 147 -20 280 729 ;
+C 93 ; WX 278 ; N bracketright ; B -23 -215 364 729 ;
+C 94 ; WX 469 ; N asciicircum ; B 115 333 496 713 ;
+C 95 ; WX 556 ; N underscore ; B -59 -175 551 -125 ;
+C 96 ; WX 222 ; N quoteleft ; B 163 459 308 708 ;
+C 97 ; WX 556 ; N a ; B 65 -23 568 540 ;
+C 98 ; WX 556 ; N b ; B 54 -23 588 729 ;
+C 99 ; WX 500 ; N c ; B 76 -23 554 540 ;
+C 100 ; WX 556 ; N d ; B 73 -23 650 729 ;
+C 101 ; WX 556 ; N e ; B 84 -23 580 541 ;
+C 102 ; WX 278 ; N f ; B 89 0 413 733 ; L i fi ; L l fl ;
+C 103 ; WX 556 ; N g ; B 32 -220 601 540 ;
+C 104 ; WX 556 ; N h ; B 70 0 574 729 ;
+C 105 ; WX 222 ; N i ; B 66 0 305 729 ;
+C 106 ; WX 222 ; N j ; B -65 -220 308 729 ;
+C 107 ; WX 500 ; N k ; B 58 0 584 729 ;
+C 108 ; WX 222 ; N l ; B 68 0 307 729 ;
+C 109 ; WX 833 ; N m ; B 71 0 852 540 ;
+C 110 ; WX 556 ; N n ; B 70 0 574 540 ;
+C 111 ; WX 556 ; N o ; B 80 -23 576 540 ;
+C 112 ; WX 556 ; N p ; B 7 -219 586 540 ;
+C 113 ; WX 556 ; N q ; B 71 -219 607 540 ;
+C 114 ; WX 333 ; N r ; B 69 0 436 540 ;
+C 115 ; WX 500 ; N s ; B 61 -24 520 540 ;
+C 116 ; WX 278 ; N t ; B 97 -24 366 667 ;
+C 117 ; WX 556 ; N u ; B 88 -23 594 525 ;
+C 118 ; WX 500 ; N v ; B 122 0 598 525 ;
+C 119 ; WX 722 ; N w ; B 118 0 820 525 ;
+C 120 ; WX 500 ; N x ; B 17 0 583 525 ;
+C 121 ; WX 500 ; N y ; B 8 -219 590 525 ;
+C 122 ; WX 500 ; N z ; B 31 0 557 525 ;
+C 123 ; WX 334 ; N braceleft ; B 91 -214 431 731 ;
+C 124 ; WX 260 ; N bar ; B 54 -215 315 729 ;
+C 125 ; WX 334 ; N braceright ; B -16 -214 324 731 ;
+C 126 ; WX 584 ; N asciitilde ; B 137 267 594 438 ;
+C 161 ; WX 333 ; N exclamdown ; B 76 -214 317 525 ;
+C 162 ; WX 556 ; N cent ; B 96 -120 585 628 ;
+C 163 ; WX 556 ; N sterling ; B 44 -21 628 726 ;
+C 164 ; WX 167 ; N fraction ; B -178 -21 486 708 ;
+C 165 ; WX 556 ; N yen ; B 100 0 696 710 ;
+C 166 ; WX 556 ; N florin ; B -32 -214 696 742 ;
+C 167 ; WX 556 ; N section ; B 63 -215 589 729 ;
+C 168 ; WX 556 ; N currency ; B 110 126 593 554 ;
+C 169 ; WX 191 ; N quotesingle ; B 173 462 292 708 ;
+C 170 ; WX 333 ; N quotedblleft ; B 146 459 449 708 ;
+C 171 ; WX 556 ; N guillemotleft ; B 147 106 548 438 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 140 112 336 436 ;
+C 173 ; WX 333 ; N guilsinglright ; B 109 112 307 436 ;
+C 174 ; WX 500 ; N fi ; B 83 0 591 733 ;
+C 175 ; WX 500 ; N fl ; B 88 0 585 733 ;
+C 177 ; WX 556 ; N endash ; B 46 240 628 313 ;
+C 178 ; WX 556 ; N dagger ; B 127 -178 620 710 ;
+C 179 ; WX 556 ; N daggerdbl ; B 51 -178 620 710 ;
+C 180 ; WX 278 ; N periodcentered ; B 166 318 293 442 ;
+C 182 ; WX 537 ; N paragraph ; B 145 -178 677 729 ;
+C 183 ; WX 350 ; N bullet ; B 120 220 376 470 ;
+C 184 ; WX 222 ; N quotesinglbase ; B 37 -129 180 103 ;
+C 185 ; WX 333 ; N quotedblbase ; B 20 -129 322 103 ;
+C 186 ; WX 333 ; N quotedblright ; B 150 476 452 708 ;
+C 187 ; WX 556 ; N guillemotright ; B 121 106 518 438 ;
+C 188 ; WX 1000 ; N ellipsis ; B 115 0 907 104 ;
+C 189 ; WX 1000 ; N perthousand ; B 93 -20 1024 740 ;
+C 191 ; WX 611 ; N questiondown ; B 86 -213 531 525 ;
+C 193 ; WX 333 ; N grave ; B 179 592 357 740 ;
+C 194 ; WX 333 ; N acute ; B 218 592 458 740 ;
+C 195 ; WX 333 ; N circumflex ; B 146 591 433 741 ;
+C 196 ; WX 333 ; N tilde ; B 130 589 471 716 ;
+C 197 ; WX 333 ; N macron ; B 160 621 450 694 ;
+C 198 ; WX 333 ; N breve ; B 165 594 471 729 ;
+C 199 ; WX 333 ; N dotaccent ; B 244 605 370 709 ;
+C 200 ; WX 333 ; N dieresis ; B 159 605 446 708 ;
+C 202 ; WX 333 ; N ring ; B 216 566 396 741 ;
+C 203 ; WX 333 ; N cedilla ; B 1 -214 264 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 91 592 505 740 ;
+C 206 ; WX 333 ; N ogonek ; B 35 -189 246 15 ;
+C 207 ; WX 333 ; N caron ; B 176 590 463 740 ;
+C 208 ; WX 1000 ; N emdash ; B 42 240 1068 313 ;
+C 225 ; WX 1000 ; N AE ; B 11 0 1087 729 ;
+C 227 ; WX 370 ; N ordfeminine ; B 107 301 441 740 ;
+C 232 ; WX 556 ; N Lslash ; B 61 0 570 729 ;
+C 233 ; WX 778 ; N Oslash ; B 32 -23 867 742 ;
+C 234 ; WX 1000 ; N OE ; B 101 -20 1108 739 ;
+C 235 ; WX 365 ; N ordmasculine ; B 114 301 452 741 ;
+C 241 ; WX 889 ; N ae ; B 59 -20 915 546 ;
+C 245 ; WX 278 ; N dotlessi ; B 94 0 290 525 ;
+C 248 ; WX 222 ; N lslash ; B 62 0 312 729 ;
+C 249 ; WX 611 ; N oslash ; B 19 -27 639 548 ;
+C 250 ; WX 944 ; N oe ; B 85 -22 966 540 ;
+C 251 ; WX 611 ; N germandbls ; B 126 -20 655 729 ;
+C -1 ; WX 667 ; N Aacute ; B 17 0 667 939 ;
+C -1 ; WX 667 ; N Acircumflex ; B 17 0 653 940 ;
+C -1 ; WX 667 ; N Adieresis ; B 17 0 655 907 ;
+C -1 ; WX 667 ; N Agrave ; B 17 0 653 939 ;
+C -1 ; WX 667 ; N Aring ; B 17 0 653 940 ;
+C -1 ; WX 667 ; N Atilde ; B 17 0 680 915 ;
+C -1 ; WX 722 ; N Ccedilla ; B 112 -214 770 741 ;
+C -1 ; WX 667 ; N Eacute ; B 90 0 751 939 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 90 0 751 940 ;
+C -1 ; WX 667 ; N Edieresis ; B 90 0 751 907 ;
+C -1 ; WX 667 ; N Egrave ; B 90 0 751 939 ;
+C -1 ; WX 722 ; N Eth ; B 73 0 759 729 ;
+C -1 ; WX 278 ; N Iacute ; B 100 0 479 939 ;
+C -1 ; WX 278 ; N Icircumflex ; B 100 0 454 940 ;
+C -1 ; WX 278 ; N Idieresis ; B 100 0 467 907 ;
+C -1 ; WX 278 ; N Igrave ; B 100 0 378 939 ;
+C -1 ; WX 722 ; N Ntilde ; B 76 0 801 915 ;
+C -1 ; WX 778 ; N Oacute ; B 104 -23 828 939 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 104 -23 828 940 ;
+C -1 ; WX 778 ; N Odieresis ; B 104 -23 828 907 ;
+C -1 ; WX 778 ; N Ograve ; B 104 -23 828 939 ;
+C -1 ; WX 778 ; N Otilde ; B 104 -23 828 915 ;
+C -1 ; WX 667 ; N Scaron ; B 89 -23 714 939 ;
+C -1 ; WX 667 ; N Thorn ; B 91 0 707 729 ;
+C -1 ; WX 722 ; N Uacute ; B 124 -23 800 939 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 124 -23 800 940 ;
+C -1 ; WX 722 ; N Udieresis ; B 124 -23 800 907 ;
+C -1 ; WX 722 ; N Ugrave ; B 124 -23 800 939 ;
+C -1 ; WX 667 ; N Yacute ; B 168 0 816 944 ;
+C -1 ; WX 667 ; N Ydieresis ; B 168 0 816 907 ;
+C -1 ; WX 611 ; N Zcaron ; B 28 0 737 939 ;
+C -1 ; WX 556 ; N aacute ; B 65 -23 570 740 ;
+C -1 ; WX 556 ; N acircumflex ; B 65 -23 568 741 ;
+C -1 ; WX 556 ; N adieresis ; B 65 -23 568 708 ;
+C -1 ; WX 556 ; N agrave ; B 65 -23 568 740 ;
+C -1 ; WX 556 ; N aring ; B 65 -23 568 741 ;
+C -1 ; WX 556 ; N atilde ; B 65 -23 583 716 ;
+C -1 ; WX 260 ; N brokenbar ; B 54 -215 315 729 ;
+C -1 ; WX 500 ; N ccedilla ; B 76 -214 554 540 ;
+C -1 ; WX 737 ; N copyright ; B 55 -23 836 741 ;
+C -1 ; WX 400 ; N degree ; B 165 409 472 709 ;
+C -1 ; WX 584 ; N divide ; B 92 -10 591 474 ;
+C -1 ; WX 556 ; N eacute ; B 84 -23 580 740 ;
+C -1 ; WX 556 ; N ecircumflex ; B 84 -23 580 741 ;
+C -1 ; WX 556 ; N edieresis ; B 84 -23 580 708 ;
+C -1 ; WX 556 ; N egrave ; B 84 -23 580 740 ;
+C -1 ; WX 556 ; N eth ; B 80 -23 572 729 ;
+C -1 ; WX 278 ; N iacute ; B 94 0 431 740 ;
+C -1 ; WX 278 ; N icircumflex ; B 94 0 406 741 ;
+C -1 ; WX 278 ; N idieresis ; B 94 0 419 708 ;
+C -1 ; WX 278 ; N igrave ; B 94 0 330 740 ;
+C -1 ; WX 584 ; N logicalnot ; B 99 82 619 352 ;
+C -1 ; WX 584 ; N minus ; B 81 194 601 270 ;
+C -1 ; WX 556 ; N mu ; B 18 -219 594 525 ;
+C -1 ; WX 584 ; N multiply ; B 59 -10 625 476 ;
+C -1 ; WX 556 ; N ntilde ; B 70 0 589 716 ;
+C -1 ; WX 556 ; N oacute ; B 80 -23 576 740 ;
+C -1 ; WX 556 ; N ocircumflex ; B 80 -23 576 741 ;
+C -1 ; WX 556 ; N odieresis ; B 80 -23 576 708 ;
+C -1 ; WX 556 ; N ograve ; B 80 -23 576 740 ;
+C -1 ; WX 834 ; N onehalf ; B 116 -21 869 709 ;
+C -1 ; WX 834 ; N onequarter ; B 147 -21 836 709 ;
+C -1 ; WX 333 ; N onesuperior ; B 184 284 370 709 ;
+C -1 ; WX 556 ; N otilde ; B 80 -23 583 716 ;
+C -1 ; WX 584 ; N plusminus ; B 40 0 621 618 ;
+C -1 ; WX 737 ; N registered ; B 55 -23 836 741 ;
+C -1 ; WX 500 ; N scaron ; B 61 -24 547 740 ;
+C -1 ; WX 556 ; N thorn ; B 7 -219 588 729 ;
+C -1 ; WX 834 ; N threequarters ; B 114 -21 868 709 ;
+C -1 ; WX 333 ; N threesuperior ; B 96 270 435 709 ;
+C -1 ; WX 1000 ; N trademark ; B 208 320 1096 741 ;
+C -1 ; WX 333 ; N twosuperior ; B 71 284 447 710 ;
+C -1 ; WX 556 ; N uacute ; B 88 -23 594 740 ;
+C -1 ; WX 556 ; N ucircumflex ; B 88 -23 594 741 ;
+C -1 ; WX 556 ; N udieresis ; B 88 -23 594 708 ;
+C -1 ; WX 556 ; N ugrave ; B 88 -23 594 740 ;
+C -1 ; WX 500 ; N yacute ; B 8 -219 590 740 ;
+C -1 ; WX 500 ; N ydieresis ; B 8 -219 590 708 ;
+C -1 ; WX 500 ; N zcaron ; B 31 0 557 740 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 98
+
+KPX A y -9
+KPX A w -18
+KPX A v -18
+KPX A space -37
+KPX A quoteright -37
+KPX A Y -74
+KPX A W -18
+KPX A V -55
+KPX A T -74
+
+KPX F space -18
+KPX F period -129
+KPX F comma -129
+KPX F A -74
+
+KPX L y -18
+KPX L space -18
+KPX L quoteright -55
+KPX L Y -92
+KPX L W -37
+KPX L V -55
+KPX L T -74
+
+KPX P space -37
+KPX P period -129
+KPX P comma -129
+KPX P A -74
+
+KPX R Y -37
+KPX R W -18
+KPX R V -18
+KPX R T -18
+
+KPX T y -74
+KPX T w -74
+KPX T u -74
+KPX T semicolon -74
+KPX T s -92
+KPX T r -74
+KPX T period -92
+KPX T o -92
+KPX T i -9
+KPX T hyphen -92
+KPX T e -92
+KPX T comma -92
+KPX T colon -74
+KPX T c -92
+KPX T a -92
+KPX T O -18
+KPX T A -74
+
+KPX V y -18
+KPX V u -18
+KPX V semicolon -18
+KPX V r -18
+KPX V period -74
+KPX V o -37
+KPX V i -18
+KPX V hyphen -37
+KPX V e -37
+KPX V comma -74
+KPX V colon -18
+KPX V a -37
+KPX V A -55
+
+KPX W period -37
+KPX W i -9
+KPX W hyphen -18
+KPX W e -18
+KPX W comma -37
+KPX W a -18
+KPX W A -18
+
+KPX Y v -37
+KPX Y u -37
+KPX Y space -18
+KPX Y semicolon -37
+KPX Y q -55
+KPX Y period -92
+KPX Y p -55
+KPX Y o -55
+KPX Y i -18
+KPX Y hyphen -74
+KPX Y e -55
+KPX Y comma -92
+KPX Y colon -37
+KPX Y a -74
+KPX Y A -55
+
+KPX f quoteright 37
+
+KPX one one -74
+
+KPX quoteleft quoteleft -37
+
+KPX quoteright space -55
+KPX quoteright s -18
+KPX quoteright quoteright -37
+
+KPX r quoteright 37
+KPX r period -37
+KPX r hyphen -18
+KPX r comma -55
+
+KPX space Y -18
+KPX space A -37
+
+KPX v period -74
+KPX v comma -74
+
+KPX w period -55
+KPX w comma -55
+
+KPX y period -74
+KPX y comma -74
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 204 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 83 0 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 167 204 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 83 0 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 194 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 83 0 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 167 204 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 83 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 194 204 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 194 204 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 194 204 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 194 204 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 111 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 111 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 111 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 111 0 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute -27 204 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -27 204 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -27 204 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave -27 204 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 167 204 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 167 204 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 167 204 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 167 204 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 111 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 111 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 111 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 111 0 ;
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 167 204 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 167 204 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 167 204 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 167 204 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 111 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 111 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 111 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 111 0 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 222 204 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 222 204 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 222 204 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 222 204 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 111 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 111 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 111 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 111 0 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 167 204 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 111 0 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 194 204 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 111 0 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 222 204 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 111 0 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 167 204 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 111 0 ;
+EndComposites
+EndFontMetrics
diff --git a/samples/printing/Makefile b/samples/printing/Makefile
new file mode 100644
index 0000000000..027d82ae19
--- /dev/null
+++ b/samples/printing/Makefile
@@ -0,0 +1 @@
+include ../../src/gtk/setup/general/makeapp
diff --git a/samples/printing/Makefile.in b/samples/printing/Makefile.in
new file mode 100644
index 0000000000..96b25e414e
--- /dev/null
+++ b/samples/printing/Makefile.in
@@ -0,0 +1,26 @@
+# WXXT base directory
+WXBASEDIR=@WXBASEDIR@
+
+# set the OS type for compilation
+OS=@OS@
+# compile a library only
+RULE=bin
+
+# define library name
+BIN_TARGET=TEST
+# define library sources
+BIN_SRC=\
+printing.cpp
+
+#define library objects
+BIN_OBJ=\
+printing.o
+
+# additional things needed to link
+BIN_LINK=
+
+# additional things needed to compile
+ADD_COMPILE=
+
+# include the definitions now
+include ../../../template.mak
diff --git a/samples/printing/TimesBo.afm b/samples/printing/TimesBo.afm
new file mode 100644
index 0000000000..a821d74c50
--- /dev/null
+++ b/samples/printing/TimesBo.afm
@@ -0,0 +1,454 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1984 Adobe Systems Incorporated. 	All Rights Reserved.
+Comment Creation Date:Tue Aug 5 11:02:18 PDT 1986
+FontName Times-Bold
+EncodingScheme AdobeStandardEncoding
+FullName Times Bold
+FamilyName Times
+Weight Bold
+ItalicAngle 0.0
+IsFixedPitch false
+UnderlinePosition -99
+UnderlineThickness 95
+Version 001.001
+Notice Times is a trademark of Allied Corporation.
+FontBBox -172 -256 1008 965
+CapHeight 681
+XHeight 460
+Descender -210
+Ascender 670
+StartCharMetrics 228
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 84 -18 248 690 ;
+C 34 ; WX 555 ; N quotedbl ; B 67 371 425 690 ;
+C 35 ; WX 500 ; N numbersign ; B -13 -17 514 684 ;
+C 36 ; WX 500 ; N dollar ; B 28 -116 474 732 ;
+C 37 ; WX 1000 ; N percent ; B 122 -11 881 692 ;
+C 38 ; WX 833 ; N ampersand ; B 54 -17 773 690 ;
+C 39 ; WX 333 ; N quoteright ; B 77 347 257 680 ;
+C 40 ; WX 333 ; N parenleft ; B 49 -169 301 699 ;
+C 41 ; WX 333 ; N parenright ; B 26 -169 278 699 ;
+C 42 ; WX 500 ; N asterisk ; B 57 262 445 690 ;
+C 43 ; WX 570 ; N plus ; B 50 -10 520 460 ;
+C 44 ; WX 250 ; N comma ; B 37 -181 214 157 ;
+C 45 ; WX 333 ; N hyphen ; B 48 170 283 285 ;
+C 46 ; WX 250 ; N period ; B 43 -19 207 145 ;
+C 47 ; WX 278 ; N slash ; B 1 -17 279 750 ;
+C 48 ; WX 500 ; N zero ; B 26 -18 472 690 ;
+C 49 ; WX 500 ; N one ; B 61 0 448 690 ;
+C 50 ; WX 500 ; N two ; B 18 0 473 683 ;
+C 51 ; WX 500 ; N three ; B 17 -19 463 683 ;
+C 52 ; WX 500 ; N four ; B 23 0 472 681 ;
+C 53 ; WX 500 ; N five ; B 23 -17 465 681 ;
+C 54 ; WX 500 ; N six ; B 30 -18 470 684 ;
+C 55 ; WX 500 ; N seven ; B 23 0 468 679 ;
+C 56 ; WX 500 ; N eight ; B 22 -17 470 685 ;
+C 57 ; WX 500 ; N nine ; B 26 -18 468 684 ;
+C 58 ; WX 333 ; N colon ; B 83 -18 247 473 ;
+C 59 ; WX 333 ; N semicolon ; B 85 -181 262 472 ;
+C 60 ; WX 570 ; N less ; B 45 -10 520 460 ;
+C 61 ; WX 570 ; N equal ; B 50 91 520 375 ;
+C 62 ; WX 570 ; N greater ; B 50 -10 525 460 ;
+C 63 ; WX 500 ; N question ; B 57 -17 438 681 ;
+C 64 ; WX 930 ; N at ; B 50 -147 889 677 ;
+C 65 ; WX 722 ; N A ; B 22 0 696 681 ;
+C 66 ; WX 667 ; N B ; B 24 0 609 681 ;
+C 67 ; WX 722 ; N C ; B 42 -17 669 690 ;
+C 68 ; WX 722 ; N D ; B 22 0 684 681 ;
+C 69 ; WX 667 ; N E ; B 21 0 637 681 ;
+C 70 ; WX 611 ; N F ; B 17 0 582 681 ;
+C 71 ; WX 778 ; N G ; B 41 -17 748 690 ;
+C 72 ; WX 778 ; N H ; B 26 0 748 681 ;
+C 73 ; WX 389 ; N I ; B 17 0 366 680 ;
+C 74 ; WX 500 ; N J ; B 9 -89 475 681 ;
+C 75 ; WX 778 ; N K ; B 29 0 761 681 ;
+C 76 ; WX 667 ; N L ; B 21 0 633 681 ;
+C 77 ; WX 944 ; N M ; B 21 0 914 681 ;
+C 78 ; WX 722 ; N N ; B 20 -10 697 681 ;
+C 79 ; WX 778 ; N O ; B 43 -18 733 690 ;
+C 80 ; WX 611 ; N P ; B 24 0 593 681 ;
+C 81 ; WX 778 ; N Q ; B 24 -182 751 690 ;
+C 82 ; WX 722 ; N R ; B 26 0 695 681 ;
+C 83 ; WX 556 ; N S ; B 43 -19 506 690 ;
+C 84 ; WX 667 ; N T ; B 30 0 629 681 ;
+C 85 ; WX 722 ; N U ; B 20 -19 700 681 ;
+C 86 ; WX 722 ; N V ; B 22 -18 696 681 ;
+C 87 ; WX 1000 ; N W ; B 19 -18 979 680 ;
+C 88 ; WX 722 ; N X ; B 23 0 695 681 ;
+C 89 ; WX 722 ; N Y ; B 19 0 697 680 ;
+C 90 ; WX 667 ; N Z ; B 37 0 624 681 ;
+C 91 ; WX 333 ; N bracketleft ; B 73 -142 296 674 ;
+C 92 ; WX 278 ; N backslash ; B 1 -17 279 750 ;
+C 93 ; WX 333 ; N bracketright ; B 38 -142 261 674 ;
+C 94 ; WX 581 ; N asciicircum ; B 102 290 486 690 ;
+C 95 ; WX 500 ; N underscore ; B -2 -256 502 -182 ;
+C 96 ; WX 333 ; N quoteleft ; B 72 357 252 691 ;
+C 97 ; WX 500 ; N a ; B 25 -19 484 472 ;
+C 98 ; WX 556 ; N b ; B 29 -18 512 670 ;
+C 99 ; WX 444 ; N c ; B 24 -17 423 472 ;
+C 100 ; WX 556 ; N d ; B 31 -17 523 670 ;
+C 101 ; WX 444 ; N e ; B 25 -18 415 474 ;
+C 102 ; WX 333 ; N f ; B 20 0 386 690 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B 25 -210 474 472 ;
+C 104 ; WX 556 ; N h ; B 29 0 523 670 ;
+C 105 ; WX 278 ; N i ; B 27 0 249 690 ;
+C 106 ; WX 333 ; N j ; B -57 -212 256 690 ;
+C 107 ; WX 556 ; N k ; B 24 0 528 670 ;
+C 108 ; WX 278 ; N l ; B 25 0 247 670 ;
+C 109 ; WX 833 ; N m ; B 28 0 804 471 ;
+C 110 ; WX 556 ; N n ; B 28 0 523 473 ;
+C 111 ; WX 500 ; N o ; B 25 -18 473 472 ;
+C 112 ; WX 556 ; N p ; B 30 -210 513 473 ;
+C 113 ; WX 556 ; N q ; B 32 -210 535 472 ;
+C 114 ; WX 444 ; N r ; B 29 0 417 473 ;
+C 115 ; WX 389 ; N s ; B 29 -17 359 472 ;
+C 116 ; WX 333 ; N t ; B 22 -19 320 627 ;
+C 117 ; WX 556 ; N u ; B 23 -17 524 460 ;
+C 118 ; WX 500 ; N v ; B 20 -14 479 460 ;
+C 119 ; WX 722 ; N w ; B 10 -14 709 460 ;
+C 120 ; WX 500 ; N x ; B 11 0 488 460 ;
+C 121 ; WX 500 ; N y ; B 19 -212 475 460 ;
+C 122 ; WX 444 ; N z ; B 25 0 414 460 ;
+C 123 ; WX 394 ; N braceleft ; B 44 -142 342 674 ;
+C 124 ; WX 220 ; N bar ; B 77 -195 151 720 ;
+C 125 ; WX 394 ; N braceright ; B 38 -142 336 674 ;
+C 126 ; WX 520 ; N asciitilde ; B 19 237 493 461 ;
+C 161 ; WX 333 ; N exclamdown ; B 85 -210 249 498 ;
+C 162 ; WX 500 ; N cent ; B 44 -148 460 586 ;
+C 163 ; WX 500 ; N sterling ; B 25 -17 471 682 ;
+C 164 ; WX 167 ; N fraction ; B -172 -17 335 690 ;
+C 165 ; WX 500 ; N yen ; B -20 0 521 681 ;
+C 166 ; WX 500 ; N florin ; B 2 -157 496 713 ;
+C 167 ; WX 500 ; N section ; B 63 -148 438 677 ;
+C 168 ; WX 500 ; N currency ; B 3 105 498 604 ;
+C 169 ; WX 278 ; N quotesingle ; B 69 371 205 690 ;
+C 170 ; WX 500 ; N quotedblleft ; B 33 346 479 679 ;
+C 171 ; WX 500 ; N guillemotleft ; B 25 44 471 436 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 51 44 302 436 ;
+C 173 ; WX 333 ; N guilsinglright ; B 26 44 277 436 ;
+C 174 ; WX 556 ; N fi ; B 24 0 532 690 ;
+C 175 ; WX 556 ; N fl ; B 25 0 529 691 ;
+C 177 ; WX 500 ; N endash ; B -4 179 500 270 ;
+C 178 ; WX 500 ; N dagger ; B 52 -141 446 690 ;
+C 179 ; WX 500 ; N daggerdbl ; B 57 -138 451 681 ;
+C 180 ; WX 250 ; N periodcentered ; B 43 270 167 394 ;
+C 182 ; WX 540 ; N paragraph ; B 30 -190 533 681 ;
+C 183 ; WX 350 ; N bullet ; B 50 175 300 425 ;
+C 184 ; WX 333 ; N quotesinglbase ; B 77 -179 257 154 ;
+C 185 ; WX 500 ; N quotedblbase ; B 31 -179 477 154 ;
+C 186 ; WX 500 ; N quotedblright ; B 31 347 477 680 ;
+C 187 ; WX 500 ; N guillemotright ; B 24 44 470 436 ;
+C 188 ; WX 1000 ; N ellipsis ; B 85 -18 915 146 ;
+C 189 ; WX 1000 ; N perthousand ; B 1 -55 993 718 ;
+C 191 ; WX 500 ; N questiondown ; B 56 -210 437 488 ;
+C 193 ; WX 333 ; N grave ; B 26 523 242 695 ;
+C 194 ; WX 333 ; N acute ; B 83 523 299 695 ;
+C 195 ; WX 333 ; N circumflex ; B 28 520 304 690 ;
+C 196 ; WX 333 ; N tilde ; B 34 559 298 671 ;
+C 197 ; WX 333 ; N macron ; B 34 543 297 600 ;
+C 198 ; WX 333 ; N breve ; B 32 529 300 667 ;
+C 199 ; WX 333 ; N dotaccent ; B 112 515 222 625 ;
+C 200 ; WX 333 ; N dieresis ; B 33 556 297 652 ;
+C 202 ; WX 333 ; N ring ; B 55 522 279 746 ;
+C 203 ; WX 333 ; N cedilla ; B 42 -211 293 -10 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 32 539 320 753 ;
+C 206 ; WX 333 ; N ogonek ; B 60 -179 277 70 ;
+C 207 ; WX 333 ; N caron ; B 32 520 298 690 ;
+C 208 ; WX 1000 ; N emdash ; B -2 185 1008 280 ;
+C 225 ; WX 1000 ; N AE ; B 19 0 954 681 ;
+C 227 ; WX 300 ; N ordfeminine ; B 12 286 288 685 ;
+C 232 ; WX 667 ; N Lslash ; B 0 0 612 681 ;
+C 233 ; WX 778 ; N Oslash ; B 45 -75 735 740 ;
+C 234 ; WX 1000 ; N OE ; B 24 -7 979 683 ;
+C 235 ; WX 330 ; N ordmasculine ; B 31 286 299 685 ;
+C 241 ; WX 722 ; N ae ; B 30 -17 691 474 ;
+C 245 ; WX 278 ; N dotlessi ; B 28 0 250 460 ;
+C 248 ; WX 278 ; N lslash ; B 0 0 326 670 ;
+C 249 ; WX 500 ; N oslash ; B 27 -95 474 550 ;
+C 250 ; WX 722 ; N oe ; B 26 -17 689 473 ;
+C 251 ; WX 556 ; N germandbls ; B 22 -18 513 689 ;
+C -1 ; WX 722 ; N Aacute ; B 22 0 696 914 ;
+C -1 ; WX 722 ; N Acircumflex ; B 22 0 696 909 ;
+C -1 ; WX 722 ; N Adieresis ; B 22 0 696 871 ;
+C -1 ; WX 722 ; N Agrave ; B 22 0 696 914 ;
+C -1 ; WX 722 ; N Aring ; B 22 0 696 965 ;
+C -1 ; WX 722 ; N Atilde ; B 22 0 696 890 ;
+C -1 ; WX 722 ; N Ccedilla ; B 42 -211 669 690 ;
+C -1 ; WX 667 ; N Eacute ; B 21 0 637 914 ;
+C -1 ; WX 667 ; N Ecircumflex ; B 21 0 637 909 ;
+C -1 ; WX 667 ; N Edieresis ; B 21 0 637 871 ;
+C -1 ; WX 667 ; N Egrave ; B 21 0 637 914 ;
+C -1 ; WX 722 ; N Eth ; B 22 0 685 681 ;
+C -1 ; WX 389 ; N Iacute ; B 17 0 366 914 ;
+C -1 ; WX 389 ; N Icircumflex ; B 17 0 366 909 ;
+C -1 ; WX 389 ; N Idieresis ; B 17 0 366 871 ;
+C -1 ; WX 389 ; N Igrave ; B 17 0 366 914 ;
+C -1 ; WX 722 ; N Ntilde ; B 20 -10 697 890 ;
+C -1 ; WX 778 ; N Oacute ; B 43 -18 733 914 ;
+C -1 ; WX 778 ; N Ocircumflex ; B 43 -18 733 909 ;
+C -1 ; WX 778 ; N Odieresis ; B 43 -18 733 871 ;
+C -1 ; WX 778 ; N Ograve ; B 43 -18 733 914 ;
+C -1 ; WX 778 ; N Otilde ; B 43 -18 733 890 ;
+C -1 ; WX 556 ; N Scaron ; B 43 -19 506 909 ;
+C -1 ; WX 611 ; N Thorn ; B 24 0 594 681 ;
+C -1 ; WX 722 ; N Uacute ; B 20 -19 700 914 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 20 -19 700 909 ;
+C -1 ; WX 722 ; N Udieresis ; B 20 -19 700 871 ;
+C -1 ; WX 722 ; N Ugrave ; B 20 -19 700 914 ;
+C -1 ; WX 722 ; N Yacute ; B 19 0 697 916 ;
+C -1 ; WX 722 ; N Ydieresis ; B 19 0 697 871 ;
+C -1 ; WX 667 ; N Zcaron ; B 37 0 624 909 ;
+C -1 ; WX 500 ; N aacute ; B 25 -19 484 695 ;
+C -1 ; WX 500 ; N acircumflex ; B 25 -19 484 690 ;
+C -1 ; WX 500 ; N adieresis ; B 25 -19 484 652 ;
+C -1 ; WX 500 ; N agrave ; B 25 -19 484 695 ;
+C -1 ; WX 500 ; N aring ; B 25 -19 484 746 ;
+C -1 ; WX 500 ; N atilde ; B 25 -19 484 671 ;
+C -1 ; WX 220 ; N brokenbar ; B 77 -195 151 720 ;
+C -1 ; WX 444 ; N ccedilla ; B 24 -211 423 472 ;
+C -1 ; WX 747 ; N copyright ; B 16 -17 730 690 ;
+C -1 ; WX 400 ; N degree ; B 50 390 350 690 ;
+C -1 ; WX 570 ; N divide ; B 50 -10 520 460 ;
+C -1 ; WX 444 ; N eacute ; B 25 -18 415 695 ;
+C -1 ; WX 444 ; N ecircumflex ; B 25 -18 415 690 ;
+C -1 ; WX 444 ; N edieresis ; B 25 -18 415 652 ;
+C -1 ; WX 444 ; N egrave ; B 25 -18 415 695 ;
+C -1 ; WX 500 ; N eth ; B 26 -17 474 670 ;
+C -1 ; WX 278 ; N iacute ; B 28 0 265 695 ;
+C -1 ; WX 278 ; N icircumflex ; B -6 0 270 690 ;
+C -1 ; WX 278 ; N idieresis ; B -1 0 263 652 ;
+C -1 ; WX 278 ; N igrave ; B -8 0 250 695 ;
+C -1 ; WX 570 ; N logicalnot ; B 50 94 520 375 ;
+C -1 ; WX 570 ; N minus ; B 50 188 520 262 ;
+C -1 ; WX 556 ; N mu ; B 23 -210 524 460 ;
+C -1 ; WX 570 ; N multiply ; B 50 -10 520 460 ;
+C -1 ; WX 556 ; N ntilde ; B 28 0 523 671 ;
+C -1 ; WX 500 ; N oacute ; B 25 -18 473 695 ;
+C -1 ; WX 500 ; N ocircumflex ; B 25 -18 473 690 ;
+C -1 ; WX 500 ; N odieresis ; B 25 -18 473 652 ;
+C -1 ; WX 500 ; N ograve ; B 25 -18 473 695 ;
+C -1 ; WX 750 ; N onehalf ; B 30 -18 720 690 ;
+C -1 ; WX 750 ; N onequarter ; B 30 -18 720 690 ;
+C -1 ; WX 300 ; N onesuperior ; B 24 276 275 690 ;
+C -1 ; WX 500 ; N otilde ; B 25 -18 473 671 ;
+C -1 ; WX 570 ; N plusminus ; B 50 0 520 600 ;
+C -1 ; WX 747 ; N registered ; B 16 -17 730 690 ;
+C -1 ; WX 389 ; N scaron ; B 29 -17 359 690 ;
+C -1 ; WX 556 ; N thorn ; B 30 -210 513 670 ;
+C -1 ; WX 750 ; N threequarters ; B 30 -18 720 690 ;
+C -1 ; WX 300 ; N threesuperior ; B 5 269 294 690 ;
+C -1 ; WX 1000 ; N trademark ; B 30 277 970 681 ;
+C -1 ; WX 300 ; N twosuperior ; B 2 276 298 686 ;
+C -1 ; WX 556 ; N uacute ; B 23 -17 524 695 ;
+C -1 ; WX 556 ; N ucircumflex ; B 23 -17 524 690 ;
+C -1 ; WX 556 ; N udieresis ; B 23 -17 524 652 ;
+C -1 ; WX 556 ; N ugrave ; B 23 -17 524 695 ;
+C -1 ; WX 500 ; N yacute ; B 19 -212 475 695 ;
+C -1 ; WX 500 ; N ydieresis ; B 19 -212 475 652 ;
+C -1 ; WX 444 ; N zcaron ; B 25 0 414 690 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 124
+
+KPX A y -74
+KPX A w -74
+KPX A v -74
+KPX A space -55
+KPX A quoteright -74
+KPX A Y -92
+KPX A W -111
+KPX A V -129
+KPX A T -74
+
+KPX F space -37
+KPX F period -92
+KPX F comma -92
+KPX F A -74
+
+KPX L y -55
+KPX L space -55
+KPX L quoteright -92
+KPX L Y -92
+KPX L W -92
+KPX L V -92
+KPX L T -92
+
+KPX P space -55
+KPX P period -92
+KPX P comma -92
+KPX P A -74
+
+KPX R y -35
+KPX R Y -35
+KPX R W -35
+KPX R V -35
+KPX R T -35
+
+KPX T y -74
+KPX T w -74
+KPX T u -92
+KPX T space -18
+KPX T semicolon -74
+KPX T s -92
+KPX T r -74
+KPX T period -74
+KPX T o -92
+KPX T i -18
+KPX T hyphen -92
+KPX T e -92
+KPX T comma -74
+KPX T colon -74
+KPX T c -92
+KPX T a -92
+KPX T O -18
+KPX T A -74
+
+KPX V y -92
+KPX V u -92
+KPX V space -18
+KPX V semicolon -92
+KPX V r -74
+KPX V period -129
+KPX V o -92
+KPX V i -37
+KPX V hyphen -74
+KPX V e -92
+KPX V comma -129
+KPX V colon -92
+KPX V a -92
+KPX V O -20
+KPX V A -129
+
+KPX W y -37
+KPX W u -18
+KPX W space -18
+KPX W semicolon -55
+KPX W r -18
+KPX W period -92
+KPX W o -55
+KPX W i -18
+KPX W hyphen -37
+KPX W e -55
+KPX W comma -92
+KPX W colon -55
+KPX W a -55
+KPX W A -111
+
+KPX Y v -111
+KPX Y u -92
+KPX Y space -37
+KPX Y semicolon -92
+KPX Y q -111
+KPX Y period -92
+KPX Y p -92
+KPX Y o -111
+KPX Y i -37
+KPX Y hyphen -92
+KPX Y e -111
+KPX Y comma -92
+KPX Y colon -92
+KPX Y a -111
+KPX Y A -92
+
+KPX f quoteright 55
+KPX f f 0
+
+KPX one one -55
+
+KPX quoteleft quoteleft -74
+
+KPX quoteright space -74
+KPX quoteright s -37
+KPX quoteright quoteright -74
+
+KPX r z 0
+KPX r y 0
+KPX r x 0
+KPX r w 0
+KPX r t 0
+KPX r space -18
+KPX r quoteright 18
+KPX r q -18
+KPX r period -92
+KPX r o -18
+KPX r hyphen -37
+KPX r h 0
+KPX r e -18
+KPX r comma -92
+KPX r c -18
+
+KPX space Y -37
+KPX space W -18
+KPX space V -18
+KPX space T -18
+KPX space A -55
+
+KPX v period -55
+KPX v comma -55
+
+KPX w period -55
+KPX w comma -55
+
+KPX y period -55
+KPX y comma -55
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 167 219 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 55 0 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 111 219 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 207 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 68 0 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 194 219 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 83 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 221 219 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 221 219 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 221 219 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 221 219 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 104 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 104 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 104 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 104 0 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 28 219 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 28 219 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 28 219 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 28 219 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -34 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -34 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -34 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -34 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 174 219 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 174 219 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 174 219 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 174 219 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 61 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 61 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 61 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 61 0 ;
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 187 219 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 187 219 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 187 219 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 187 219 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 76 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 76 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 76 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 76 0 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 222 219 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 222 219 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 222 219 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 222 219 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 83 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 83 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 83 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 83 0 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 187 219 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 76 0 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 194 219 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 111 0 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 222 219 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 83 0 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 187 219 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 76 0 ;
+EndComposites
+EndFontMetrics
diff --git a/samples/printing/TimesBoO.afm b/samples/printing/TimesBoO.afm
new file mode 100644
index 0000000000..cf4ca76a17
--- /dev/null
+++ b/samples/printing/TimesBoO.afm
@@ -0,0 +1,438 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1984 Adobe Systems Incorporated. 	All Rights Reserved.
+Comment Creation Date:Tue Aug 5 11:23:15 PDT 1986
+FontName Times-BoldItalic
+EncodingScheme AdobeStandardEncoding
+FullName Times Bold Italic
+FamilyName Times
+Weight Bold
+ItalicAngle -15.0
+IsFixedPitch false
+UnderlinePosition -98
+UnderlineThickness 54
+Version 001.001
+Notice Times is a trademark of Allied Corporation.
+FontBBox -168 -232 1014 894
+CapHeight 662
+XHeight 458
+Descender -203
+Ascender 682
+StartCharMetrics 228
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 389 ; N exclam ; B 66 -13 367 676 ;
+C 34 ; WX 555 ; N quotedbl ; B 142 367 549 693 ;
+C 35 ; WX 500 ; N numbersign ; B 4 0 496 662 ;
+C 36 ; WX 500 ; N dollar ; B -20 -101 492 723 ;
+C 37 ; WX 833 ; N percent ; B 39 -8 784 685 ;
+C 38 ; WX 778 ; N ampersand ; B 41 -19 727 676 ;
+C 39 ; WX 333 ; N quoteright ; B 80 362 282 675 ;
+C 40 ; WX 333 ; N parenleft ; B 28 -179 340 676 ;
+C 41 ; WX 333 ; N parenright ; B -44 -179 268 676 ;
+C 42 ; WX 500 ; N asterisk ; B 56 244 445 676 ;
+C 43 ; WX 570 ; N plus ; B 33 0 537 505 ;
+C 44 ; WX 250 ; N comma ; B -10 -181 192 132 ;
+C 45 ; WX 333 ; N hyphen ; B 33 167 299 282 ;
+C 46 ; WX 250 ; N period ; B 23 -13 170 133 ;
+C 47 ; WX 278 ; N slash ; B -11 -18 289 682 ;
+C 48 ; WX 500 ; N zero ; B 17 -13 472 676 ;
+C 49 ; WX 500 ; N one ; B 5 0 415 676 ;
+C 50 ; WX 500 ; N two ; B -27 0 441 676 ;
+C 51 ; WX 500 ; N three ; B -15 -13 445 676 ;
+C 52 ; WX 500 ; N four ; B -15 0 498 676 ;
+C 53 ; WX 500 ; N five ; B -11 -13 482 662 ;
+C 54 ; WX 500 ; N six ; B 23 -13 504 676 ;
+C 55 ; WX 500 ; N seven ; B 51 0 519 662 ;
+C 56 ; WX 500 ; N eight ; B 3 -13 471 676 ;
+C 57 ; WX 500 ; N nine ; B -12 -13 470 676 ;
+C 58 ; WX 333 ; N colon ; B 52 -13 291 458 ;
+C 59 ; WX 333 ; N semicolon ; B 13 -181 291 458 ;
+C 60 ; WX 570 ; N less ; B 31 -14 540 524 ;
+C 61 ; WX 570 ; N equal ; B 33 116 537 401 ;
+C 62 ; WX 570 ; N greater ; B 31 -14 540 524 ;
+C 63 ; WX 500 ; N question ; B 78 -13 465 676 ;
+C 64 ; WX 832 ; N at ; B -9 -150 838 691 ;
+C 65 ; WX 667 ; N A ; B -51 0 602 676 ;
+C 66 ; WX 667 ; N B ; B -24 0 618 662 ;
+C 67 ; WX 667 ; N C ; B 22 -18 660 677 ;
+C 68 ; WX 722 ; N D ; B -31 0 693 662 ;
+C 69 ; WX 667 ; N E ; B -27 0 646 662 ;
+C 70 ; WX 667 ; N F ; B -20 0 646 662 ;
+C 71 ; WX 722 ; N G ; B 21 -18 699 676 ;
+C 72 ; WX 778 ; N H ; B -24 0 791 662 ;
+C 73 ; WX 389 ; N I ; B -22 0 412 662 ;
+C 74 ; WX 500 ; N J ; B -45 -98 519 662 ;
+C 75 ; WX 667 ; N K ; B -31 0 685 662 ;
+C 76 ; WX 611 ; N L ; B -22 0 584 662 ;
+C 77 ; WX 889 ; N M ; B -29 -12 907 662 ;
+C 78 ; WX 722 ; N N ; B -27 -18 740 662 ;
+C 79 ; WX 722 ; N O ; B 27 -18 684 676 ;
+C 80 ; WX 611 ; N P ; B -27 0 608 662 ;
+C 81 ; WX 722 ; N Q ; B 27 -203 684 676 ;
+C 82 ; WX 667 ; N R ; B -29 0 616 662 ;
+C 83 ; WX 556 ; N S ; B 6 -18 524 676 ;
+C 84 ; WX 611 ; N T ; B 39 0 632 662 ;
+C 85 ; WX 722 ; N U ; B 66 -18 736 662 ;
+C 86 ; WX 667 ; N V ; B 48 -18 692 662 ;
+C 87 ; WX 889 ; N W ; B 48 -18 914 662 ;
+C 88 ; WX 667 ; N X ; B -24 0 687 662 ;
+C 89 ; WX 611 ; N Y ; B 46 0 625 662 ;
+C 90 ; WX 611 ; N Z ; B -1 0 594 662 ;
+C 91 ; WX 333 ; N bracketleft ; B -7 -157 388 682 ;
+C 92 ; WX 278 ; N backslash ; B 1 0 465 682 ;
+C 93 ; WX 333 ; N bracketright ; B -65 -157 330 682 ;
+C 94 ; WX 570 ; N asciicircum ; B 34 259 536 662 ;
+C 95 ; WX 500 ; N underscore ; B 0 -127 500 -89 ;
+C 96 ; WX 333 ; N quoteleft ; B 117 363 319 676 ;
+C 97 ; WX 500 ; N a ; B 9 -14 480 458 ;
+C 98 ; WX 500 ; N b ; B 21 -13 474 682 ;
+C 99 ; WX 444 ; N c ; B 25 -13 418 458 ;
+C 100 ; WX 500 ; N d ; B 9 -13 541 682 ;
+C 101 ; WX 444 ; N e ; B 25 -13 413 458 ;
+C 102 ; WX 333 ; N f ; B -146 -203 460 682 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B -27 -203 498 458 ;
+C 104 ; WX 556 ; N h ; B 12 -13 518 682 ;
+C 105 ; WX 278 ; N i ; B 25 -13 284 676 ;
+C 106 ; WX 278 ; N j ; B -152 -203 311 676 ;
+C 107 ; WX 500 ; N k ; B 10 -13 511 682 ;
+C 108 ; WX 278 ; N l ; B 31 -13 312 682 ;
+C 109 ; WX 778 ; N m ; B 16 -13 744 458 ;
+C 110 ; WX 556 ; N n ; B 24 -13 518 458 ;
+C 111 ; WX 500 ; N o ; B 27 -13 467 458 ;
+C 112 ; WX 500 ; N p ; B -79 -203 481 458 ;
+C 113 ; WX 500 ; N q ; B 21 -203 486 459 ;
+C 114 ; WX 389 ; N r ; B 9 0 415 458 ;
+C 115 ; WX 389 ; N s ; B 16 -13 364 459 ;
+C 116 ; WX 278 ; N t ; B 16 -14 305 592 ;
+C 117 ; WX 556 ; N u ; B 48 -13 521 458 ;
+C 118 ; WX 444 ; N v ; B 50 -13 432 458 ;
+C 119 ; WX 667 ; N w ; B 50 -13 642 458 ;
+C 120 ; WX 500 ; N x ; B -5 -13 498 458 ;
+C 121 ; WX 444 ; N y ; B -60 -203 423 458 ;
+C 122 ; WX 389 ; N z ; B -24 -58 394 448 ;
+C 123 ; WX 348 ; N braceleft ; B 31 -154 381 686 ;
+C 124 ; WX 220 ; N bar ; B 70 0 151 682 ;
+C 125 ; WX 348 ; N braceright ; B -31 -161 319 679 ;
+C 126 ; WX 570 ; N asciitilde ; B 33 158 537 353 ;
+C 161 ; WX 389 ; N exclamdown ; B 21 -232 321 458 ;
+C 162 ; WX 500 ; N cent ; B 50 -142 443 570 ;
+C 163 ; WX 500 ; N sterling ; B -32 -13 505 676 ;
+C 164 ; WX 167 ; N fraction ; B -161 0 327 662 ;
+C 165 ; WX 500 ; N yen ; B -15 0 565 662 ;
+C 166 ; WX 500 ; N florin ; B -86 -154 530 682 ;
+C 167 ; WX 500 ; N section ; B 36 -143 454 676 ;
+C 168 ; WX 500 ; N currency ; B -3 110 503 612 ;
+C 169 ; WX 278 ; N quotesingle ; B 126 367 295 693 ;
+C 170 ; WX 500 ; N quotedblleft ; B 57 363 513 676 ;
+C 171 ; WX 500 ; N guillemotleft ; B 21 33 474 416 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 42 33 310 416 ;
+C 173 ; WX 333 ; N guilsinglright ; B 23 38 291 421 ;
+C 174 ; WX 556 ; N fi ; B -157 -203 538 682 ;
+C 175 ; WX 556 ; N fl ; B -149 -203 577 682 ;
+C 177 ; WX 500 ; N endash ; B -11 176 511 266 ;
+C 178 ; WX 500 ; N dagger ; B 90 -146 489 676 ;
+C 179 ; WX 500 ; N daggerdbl ; B 11 -143 487 675 ;
+C 180 ; WX 250 ; N periodcentered ; B 51 179 200 328 ;
+C 182 ; WX 500 ; N paragraph ; B 61 -189 592 682 ;
+C 183 ; WX 350 ; N bullet ; B 50 175 300 425 ;
+C 184 ; WX 333 ; N quotesinglbase ; B 66 -181 268 132 ;
+C 185 ; WX 500 ; N quotedblbase ; B -57 -181 398 132 ;
+C 186 ; WX 500 ; N quotedblright ; B 56 362 509 675 ;
+C 187 ; WX 500 ; N guillemotright ; B 21 38 474 421 ;
+C 188 ; WX 1000 ; N ellipsis ; B 93 -13 906 133 ;
+C 189 ; WX 1000 ; N perthousand ; B 7 -49 985 699 ;
+C 191 ; WX 500 ; N questiondown ; B 30 -203 417 487 ;
+C 193 ; WX 333 ; N grave ; B 115 511 325 690 ;
+C 194 ; WX 333 ; N acute ; B 168 511 405 690 ;
+C 195 ; WX 333 ; N circumflex ; B 70 510 394 682 ;
+C 196 ; WX 333 ; N tilde ; B 69 530 424 648 ;
+C 197 ; WX 333 ; N macron ; B 81 547 420 616 ;
+C 198 ; WX 333 ; N breve ; B 99 511 414 671 ;
+C 199 ; WX 333 ; N dotaccent ; B 180 519 308 648 ;
+C 200 ; WX 333 ; N dieresis ; B 85 519 424 648 ;
+C 202 ; WX 333 ; N ring ; B 141 466 352 676 ;
+C 203 ; WX 333 ; N cedilla ; B 32 -216 264 5 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 28 538 339 750 ;
+C 206 ; WX 333 ; N ogonek ; B -37 -173 192 44 ;
+C 207 ; WX 333 ; N caron ; B 109 511 437 683 ;
+C 208 ; WX 1000 ; N emdash ; B -14 176 1014 266 ;
+C 225 ; WX 944 ; N AE ; B -41 0 931 662 ;
+C 227 ; WX 266 ; N ordfeminine ; B -24 286 291 676 ;
+C 232 ; WX 611 ; N Lslash ; B -22 0 584 662 ;
+C 233 ; WX 722 ; N Oslash ; B 27 -124 684 754 ;
+C 234 ; WX 944 ; N OE ; B 23 -8 936 670 ;
+C 235 ; WX 300 ; N ordmasculine ; B 1 286 300 676 ;
+C 241 ; WX 722 ; N ae ; B 15 -13 685 458 ;
+C 245 ; WX 278 ; N dotlessi ; B 27 -13 260 458 ;
+C 248 ; WX 278 ; N lslash ; B 12 -13 326 682 ;
+C 249 ; WX 500 ; N oslash ; B 27 -118 467 556 ;
+C 250 ; WX 722 ; N oe ; B 26 -13 687 458 ;
+C 251 ; WX 500 ; N germandbls ; B -168 -203 497 682 ;
+C -1 ; WX 667 ; N Aacute ; B -51 0 602 894 ;
+C -1 ; WX 667 ; N Acircumflex ; B -51 0 602 886 ;
+C -1 ; WX 667 ; N Adieresis ; B -51 0 602 852 ;
+C -1 ; WX 667 ; N Agrave ; B -51 0 602 894 ;
+C -1 ; WX 667 ; N Aring ; B -51 0 602 880 ;
+C -1 ; WX 667 ; N Atilde ; B -51 0 602 852 ;
+C -1 ; WX 667 ; N Ccedilla ; B 22 -216 660 677 ;
+C -1 ; WX 667 ; N Eacute ; B -27 0 646 894 ;
+C -1 ; WX 667 ; N Ecircumflex ; B -27 0 646 886 ;
+C -1 ; WX 667 ; N Edieresis ; B -27 0 646 852 ;
+C -1 ; WX 667 ; N Egrave ; B -27 0 646 894 ;
+C -1 ; WX 722 ; N Eth ; B -31 0 693 662 ;
+C -1 ; WX 389 ; N Iacute ; B -22 0 433 894 ;
+C -1 ; WX 389 ; N Icircumflex ; B -22 0 422 886 ;
+C -1 ; WX 389 ; N Idieresis ; B -22 0 452 852 ;
+C -1 ; WX 389 ; N Igrave ; B -22 0 412 894 ;
+C -1 ; WX 722 ; N Ntilde ; B -27 -18 740 852 ;
+C -1 ; WX 722 ; N Oacute ; B 27 -18 684 894 ;
+C -1 ; WX 722 ; N Ocircumflex ; B 27 -18 684 886 ;
+C -1 ; WX 722 ; N Odieresis ; B 27 -18 684 852 ;
+C -1 ; WX 722 ; N Ograve ; B 27 -18 684 894 ;
+C -1 ; WX 722 ; N Otilde ; B 27 -18 684 852 ;
+C -1 ; WX 556 ; N Scaron ; B 6 -18 549 887 ;
+C -1 ; WX 611 ; N Thorn ; B -27 0 572 662 ;
+C -1 ; WX 722 ; N Uacute ; B 66 -18 736 894 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 66 -18 736 886 ;
+C -1 ; WX 722 ; N Udieresis ; B 66 -18 736 852 ;
+C -1 ; WX 722 ; N Ugrave ; B 66 -18 736 894 ;
+C -1 ; WX 611 ; N Yacute ; B 46 0 625 894 ;
+C -1 ; WX 611 ; N Ydieresis ; B 46 0 625 852 ;
+C -1 ; WX 611 ; N Zcaron ; B -1 0 594 887 ;
+C -1 ; WX 500 ; N aacute ; B 9 -14 489 690 ;
+C -1 ; WX 500 ; N acircumflex ; B 9 -14 480 682 ;
+C -1 ; WX 500 ; N adieresis ; B 9 -14 508 648 ;
+C -1 ; WX 500 ; N agrave ; B 9 -14 480 690 ;
+C -1 ; WX 500 ; N aring ; B 9 -14 480 676 ;
+C -1 ; WX 500 ; N atilde ; B 9 -14 508 648 ;
+C -1 ; WX 220 ; N brokenbar ; B 70 0 151 682 ;
+C -1 ; WX 444 ; N ccedilla ; B 25 -216 418 458 ;
+C -1 ; WX 747 ; N copyright ; B 23 -18 723 676 ;
+C -1 ; WX 400 ; N degree ; B 70 376 370 676 ;
+C -1 ; WX 570 ; N divide ; B 33 0 537 505 ;
+C -1 ; WX 444 ; N eacute ; B 25 -13 461 690 ;
+C -1 ; WX 444 ; N ecircumflex ; B 25 -13 450 682 ;
+C -1 ; WX 444 ; N edieresis ; B 25 -13 480 648 ;
+C -1 ; WX 444 ; N egrave ; B 25 -13 413 690 ;
+C -1 ; WX 500 ; N eth ; B 27 -13 498 682 ;
+C -1 ; WX 278 ; N iacute ; B 27 -13 378 690 ;
+C -1 ; WX 278 ; N icircumflex ; B 27 -13 367 682 ;
+C -1 ; WX 278 ; N idieresis ; B 27 -13 397 648 ;
+C -1 ; WX 278 ; N igrave ; B 27 -13 298 690 ;
+C -1 ; WX 606 ; N logicalnot ; B 51 120 555 401 ;
+C -1 ; WX 606 ; N minus ; B 51 210 555 300 ;
+C -1 ; WX 576 ; N mu ; B -63 -210 521 458 ;
+C -1 ; WX 570 ; N multiply ; B 33 0 537 504 ;
+C -1 ; WX 556 ; N ntilde ; B 24 -13 536 648 ;
+C -1 ; WX 500 ; N oacute ; B 27 -13 489 690 ;
+C -1 ; WX 500 ; N ocircumflex ; B 27 -13 478 682 ;
+C -1 ; WX 500 ; N odieresis ; B 27 -13 508 648 ;
+C -1 ; WX 500 ; N ograve ; B 27 -13 467 690 ;
+C -1 ; WX 750 ; N onehalf ; B 30 0 720 676 ;
+C -1 ; WX 750 ; N onequarter ; B 30 0 720 676 ;
+C -1 ; WX 300 ; N onesuperior ; B 17 270 283 676 ;
+C -1 ; WX 500 ; N otilde ; B 27 -13 508 648 ;
+C -1 ; WX 570 ; N plusminus ; B 33 0 537 665 ;
+C -1 ; WX 747 ; N registered ; B 23 -18 723 676 ;
+C -1 ; WX 389 ; N scaron ; B 16 -13 465 683 ;
+C -1 ; WX 500 ; N thorn ; B -79 -203 474 682 ;
+C -1 ; WX 750 ; N threequarters ; B 30 0 720 676 ;
+C -1 ; WX 300 ; N threesuperior ; B 0 263 299 676 ;
+C -1 ; WX 1000 ; N trademark ; B 40 272 980 676 ;
+C -1 ; WX 300 ; N twosuperior ; B -2 270 302 676 ;
+C -1 ; WX 556 ; N uacute ; B 48 -13 521 690 ;
+C -1 ; WX 556 ; N ucircumflex ; B 48 -13 521 682 ;
+C -1 ; WX 556 ; N udieresis ; B 48 -13 536 648 ;
+C -1 ; WX 556 ; N ugrave ; B 48 -13 521 690 ;
+C -1 ; WX 444 ; N yacute ; B -60 -203 461 690 ;
+C -1 ; WX 444 ; N ydieresis ; B -60 -203 480 648 ;
+C -1 ; WX 389 ; N zcaron ; B -24 -58 465 683 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 108
+
+KPX A y -74
+KPX A w -74
+KPX A v -74
+KPX A space -55
+KPX A quoteright -74
+KPX A Y -55
+KPX A W -92
+KPX A V -74
+KPX A T -55
+
+KPX F space -18
+KPX F period -129
+KPX F comma -129
+KPX F A -92
+
+KPX L y -37
+KPX L space -37
+KPX L quoteright -55
+KPX L Y -37
+KPX L W -37
+KPX L V -37
+KPX L T -18
+
+KPX P space -37
+KPX P period -129
+KPX P comma -129
+KPX P A -74
+
+KPX R y -18
+KPX R Y -18
+KPX R W -18
+KPX R V -18
+
+KPX T y -37
+KPX T w -37
+KPX T u -37
+KPX T semicolon -74
+KPX T s -92
+KPX T r -37
+KPX T period -92
+KPX T o -92
+KPX T i -37
+KPX T hyphen -92
+KPX T e -92
+KPX T comma -92
+KPX T colon -74
+KPX T c -92
+KPX T a -92
+KPX T O -18
+KPX T A -55
+
+KPX V y -74
+KPX V u -55
+KPX V space -18
+KPX V semicolon -74
+KPX V r -55
+KPX V period -129
+KPX V o -111
+KPX V i -55
+KPX V hyphen -55
+KPX V e -111
+KPX V comma -129
+KPX V colon -74
+KPX V a -111
+KPX V A -74
+
+KPX W y -55
+KPX W u -55
+KPX W space -18
+KPX W semicolon -55
+KPX W r -74
+KPX W period -74
+KPX W o -74
+KPX W i -37
+KPX W hyphen -37
+KPX W e -74
+KPX W comma -74
+KPX W colon -55
+KPX W a -74
+KPX W A -74
+
+KPX Y v -92
+KPX Y u -92
+KPX Y space -37
+KPX Y semicolon -92
+KPX Y q -111
+KPX Y period -74
+KPX Y p -74
+KPX Y o -111
+KPX Y i -55
+KPX Y hyphen -92
+KPX Y e -111
+KPX Y comma -92
+KPX Y colon -92
+KPX Y a -92
+KPX Y A -74
+
+KPX f quoteright 55
+KPX f f -18
+
+KPX one one -55
+
+KPX quoteleft quoteleft -74
+
+KPX quoteright t -37
+KPX quoteright space -74
+KPX quoteright s -74
+KPX quoteright quoteright -74
+
+KPX r quoteright 37
+KPX r period -55
+KPX r comma -55
+
+KPX space Y -18
+KPX space W -18
+KPX space A -37
+
+KPX v period -37
+KPX v comma -37
+
+KPX w period -37
+KPX w comma -37
+
+KPX y period -37
+KPX y comma -37
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 204 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 28 0 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 111 204 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 167 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 55 0 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 139 204 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 55 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 194 204 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 194 204 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 194 204 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 194 204 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 111 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 111 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 111 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 111 0 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 28 204 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 28 204 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 28 204 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 28 204 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 167 204 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 167 204 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 167 204 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 167 204 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 55 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 55 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 55 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 55 0 ;
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 167 204 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 167 204 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 167 204 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 167 204 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 83 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 83 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 83 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 83 0 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 194 204 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 194 204 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 194 204 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 194 204 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 83 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 83 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 83 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 83 0 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 167 204 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 83 0 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 194 204 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 111 0 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 194 204 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 83 0 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 167 204 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 83 0 ;
+EndComposites
+EndFontMetrics
diff --git a/samples/printing/TimesO.afm b/samples/printing/TimesO.afm
new file mode 100644
index 0000000000..b8ffc6a0f3
--- /dev/null
+++ b/samples/printing/TimesO.afm
@@ -0,0 +1,450 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1984 Adobe Systems Incorporated. 	All Rights Reserved.
+Comment Creation Date:Tue Aug 5 11:12:17 PDT 1986
+FontName Times-Italic
+EncodingScheme AdobeStandardEncoding
+FullName Times Italic
+FamilyName Times
+Weight Medium
+ItalicAngle -15.5
+IsFixedPitch false
+UnderlinePosition -96
+UnderlineThickness 48
+Version 001.001
+Notice Times is a trademark of Allied Corporation.
+FontBBox -176 -252 990 930
+CapHeight 660
+XHeight 446
+Descender -206
+Ascender 684
+StartCharMetrics 228
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 46 -10 296 670 ;
+C 34 ; WX 420 ; N quotedbl ; B 107 442 402 673 ;
+C 35 ; WX 500 ; N numbersign ; B -7 -6 508 683 ;
+C 36 ; WX 500 ; N dollar ; B 13 -102 481 735 ;
+C 37 ; WX 833 ; N percent ; B 63 -14 770 682 ;
+C 38 ; WX 778 ; N ampersand ; B 60 -22 698 673 ;
+C 39 ; WX 333 ; N quoteright ; B 69 458 206 678 ;
+C 40 ; WX 333 ; N parenleft ; B 41 -180 312 662 ;
+C 41 ; WX 333 ; N parenright ; B 19 -178 286 664 ;
+C 42 ; WX 500 ; N asterisk ; B 60 268 434 684 ;
+C 43 ; WX 675 ; N plus ; B 85 0 589 505 ;
+C 44 ; WX 250 ; N comma ; B 57 -126 194 94 ;
+C 45 ; WX 333 ; N hyphen ; B 55 192 276 254 ;
+C 46 ; WX 250 ; N period ; B 75 -10 175 90 ;
+C 47 ; WX 278 ; N slash ; B 2 -14 252 641 ;
+C 48 ; WX 500 ; N zero ; B 19 -9 470 683 ;
+C 49 ; WX 500 ; N one ; B 31 0 390 684 ;
+C 50 ; WX 500 ; N two ; B -7 0 429 682 ;
+C 51 ; WX 500 ; N three ; B -7 -12 443 682 ;
+C 52 ; WX 500 ; N four ; B -8 0 454 681 ;
+C 53 ; WX 500 ; N five ; B -12 -15 462 666 ;
+C 54 ; WX 500 ; N six ; B 24 -8 497 685 ;
+C 55 ; WX 500 ; N seven ; B 56 -12 512 666 ;
+C 56 ; WX 500 ; N eight ; B 12 -7 475 681 ;
+C 57 ; WX 500 ; N nine ; B 10 -18 470 684 ;
+C 58 ; WX 333 ; N colon ; B 86 -10 284 444 ;
+C 59 ; WX 333 ; N semicolon ; B 63 -124 292 441 ;
+C 60 ; WX 675 ; N less ; B 83 -7 592 515 ;
+C 61 ; WX 675 ; N equal ; B 85 125 589 383 ;
+C 62 ; WX 675 ; N greater ; B 82 -7 591 515 ;
+C 63 ; WX 500 ; N question ; B 105 -10 439 670 ;
+C 64 ; WX 920 ; N at ; B 39 -191 866 648 ;
+C 65 ; WX 611 ; N A ; B -45 0 564 672 ;
+C 66 ; WX 611 ; N B ; B -28 0 562 660 ;
+C 67 ; WX 667 ; N C ; B 33 -23 653 672 ;
+C 68 ; WX 722 ; N D ; B -27 0 671 660 ;
+C 69 ; WX 611 ; N E ; B -17 0 609 660 ;
+C 70 ; WX 611 ; N F ; B -17 0 609 660 ;
+C 71 ; WX 722 ; N G ; B 31 -23 701 672 ;
+C 72 ; WX 722 ; N H ; B -26 0 742 660 ;
+C 73 ; WX 333 ; N I ; B -26 0 357 660 ;
+C 74 ; WX 444 ; N J ; B -36 -22 479 660 ;
+C 75 ; WX 667 ; N K ; B -15 0 702 660 ;
+C 76 ; WX 556 ; N L ; B -32 0 535 660 ;
+C 77 ; WX 833 ; N M ; B -24 0 850 660 ;
+C 78 ; WX 667 ; N N ; B -36 -12 698 660 ;
+C 79 ; WX 722 ; N O ; B 42 -23 676 671 ;
+C 80 ; WX 611 ; N P ; B -16 0 582 660 ;
+C 81 ; WX 722 ; N Q ; B 41 -186 681 671 ;
+C 82 ; WX 611 ; N R ; B -32 0 566 660 ;
+C 83 ; WX 500 ; N S ; B 9 -22 483 674 ;
+C 84 ; WX 556 ; N T ; B 32 0 602 660 ;
+C 85 ; WX 722 ; N U ; B 77 -21 747 660 ;
+C 86 ; WX 611 ; N V ; B 44 -20 659 660 ;
+C 87 ; WX 833 ; N W ; B 35 -20 875 660 ;
+C 88 ; WX 611 ; N X ; B -45 0 633 660 ;
+C 89 ; WX 556 ; N Y ; B 44 0 600 660 ;
+C 90 ; WX 556 ; N Z ; B -19 0 581 660 ;
+C 91 ; WX 389 ; N bracketleft ; B 22 -170 391 654 ;
+C 92 ; WX 278 ; N backslash ; B 2 -12 252 651 ;
+C 93 ; WX 389 ; N bracketright ; B -31 -170 341 654 ;
+C 94 ; WX 422 ; N asciicircum ; B 0 254 503 660 ;
+C 95 ; WX 500 ; N underscore ; B -9 -252 510 -206 ;
+C 96 ; WX 333 ; N quoteleft ; B 149 457 286 677 ;
+C 97 ; WX 500 ; N a ; B 15 -11 474 446 ;
+C 98 ; WX 500 ; N b ; B 24 -12 475 682 ;
+C 99 ; WX 444 ; N c ; B 32 -11 420 446 ;
+C 100 ; WX 500 ; N d ; B 15 -11 521 684 ;
+C 101 ; WX 444 ; N e ; B 34 -13 412 446 ;
+C 102 ; WX 278 ; N f ; B -148 -207 415 684 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B 10 -209 471 445 ;
+C 104 ; WX 500 ; N h ; B 23 -10 473 684 ;
+C 105 ; WX 278 ; N i ; B 43 -10 263 660 ;
+C 106 ; WX 278 ; N j ; B -109 -207 287 660 ;
+C 107 ; WX 444 ; N k ; B 16 -12 460 685 ;
+C 108 ; WX 278 ; N l ; B 41 -10 276 685 ;
+C 109 ; WX 722 ; N m ; B 11 -10 698 447 ;
+C 110 ; WX 500 ; N n ; B 23 -10 471 447 ;
+C 111 ; WX 500 ; N o ; B 27 -13 467 448 ;
+C 112 ; WX 500 ; N p ; B -75 -206 465 446 ;
+C 113 ; WX 500 ; N q ; B 20 -206 483 445 ;
+C 114 ; WX 389 ; N r ; B 24 0 392 446 ;
+C 115 ; WX 389 ; N s ; B 16 -14 367 446 ;
+C 116 ; WX 278 ; N t ; B 38 -10 288 548 ;
+C 117 ; WX 500 ; N u ; B 42 -11 472 447 ;
+C 118 ; WX 444 ; N v ; B 24 -11 423 444 ;
+C 119 ; WX 667 ; N w ; B 14 -10 650 447 ;
+C 120 ; WX 444 ; N x ; B -31 -10 450 446 ;
+C 121 ; WX 444 ; N y ; B -27 -209 420 445 ;
+C 122 ; WX 389 ; N z ; B 2 0 380 434 ;
+C 123 ; WX 400 ; N braceleft ; B 65 -179 411 675 ;
+C 124 ; WX 275 ; N bar ; B -22 -188 251 670 ;
+C 125 ; WX 400 ; N braceright ; B -66 -179 300 675 ;
+C 126 ; WX 541 ; N asciitilde ; B 18 169 522 340 ;
+C 161 ; WX 389 ; N exclamdown ; B 59 -213 317 468 ;
+C 162 ; WX 500 ; N cent ; B 62 -146 449 564 ;
+C 163 ; WX 500 ; N sterling ; B -5 -9 498 672 ;
+C 164 ; WX 167 ; N fraction ; B -176 -15 338 672 ;
+C 165 ; WX 500 ; N yen ; B 13 0 609 684 ;
+C 166 ; WX 500 ; N florin ; B 3 -189 492 688 ;
+C 167 ; WX 500 ; N section ; B 42 -96 455 743 ;
+C 168 ; WX 500 ; N currency ; B 3 105 498 604 ;
+C 169 ; WX 214 ; N quotesingle ; B 99 453 247 678 ;
+C 170 ; WX 556 ; N quotedblleft ; B 166 457 510 677 ;
+C 171 ; WX 500 ; N guillemotleft ; B 54 39 444 400 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 60 39 285 400 ;
+C 173 ; WX 333 ; N guilsinglright ; B 49 34 269 406 ;
+C 174 ; WX 500 ; N fi ; B -136 -207 468 684 ;
+C 175 ; WX 500 ; N fl ; B -140 -207 509 684 ;
+C 177 ; WX 500 ; N endash ; B -3 194 501 242 ;
+C 178 ; WX 500 ; N dagger ; B 92 -93 480 734 ;
+C 179 ; WX 500 ; N daggerdbl ; B 20 -93 482 743 ;
+C 180 ; WX 250 ; N periodcentered ; B 75 192 199 316 ;
+C 182 ; WX 523 ; N paragraph ; B 87 -196 533 675 ;
+C 183 ; WX 350 ; N bullet ; B 50 175 300 425 ;
+C 184 ; WX 333 ; N quotesinglbase ; B 83 -126 220 94 ;
+C 185 ; WX 556 ; N quotedblbase ; B 63 -126 407 94 ;
+C 186 ; WX 556 ; N quotedblright ; B 68 458 412 678 ;
+C 187 ; WX 500 ; N guillemotright ; B 59 34 442 406 ;
+C 188 ; WX 889 ; N ellipsis ; B 62 -10 828 90 ;
+C 189 ; WX 1000 ; N perthousand ; B 9 -65 990 690 ;
+C 191 ; WX 500 ; N questiondown ; B 55 -215 395 462 ;
+C 193 ; WX 333 ; N grave ; B 160 491 333 659 ;
+C 194 ; WX 333 ; N acute ; B 154 501 375 680 ;
+C 195 ; WX 333 ; N circumflex ; B 96 495 374 669 ;
+C 196 ; WX 333 ; N tilde ; B 114 518 386 639 ;
+C 197 ; WX 333 ; N macron ; B 120 543 380 603 ;
+C 198 ; WX 333 ; N breve ; B 140 512 401 645 ;
+C 199 ; WX 333 ; N dotaccent ; B 112 515 222 625 ;
+C 200 ; WX 333 ; N dieresis ; B 117 534 389 634 ;
+C 202 ; WX 333 ; N ring ; B 239 509 433 703 ;
+C 203 ; WX 333 ; N cedilla ; B -30 -206 214 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 62 532 348 749 ;
+C 206 ; WX 333 ; N ogonek ; B -44 -159 169 40 ;
+C 207 ; WX 333 ; N caron ; B 138 495 422 669 ;
+C 208 ; WX 889 ; N emdash ; B -65 194 945 242 ;
+C 225 ; WX 889 ; N AE ; B -46 0 889 660 ;
+C 227 ; WX 276 ; N ordfeminine ; B 32 300 310 677 ;
+C 232 ; WX 556 ; N Lslash ; B 0 0 567 660 ;
+C 233 ; WX 722 ; N Oslash ; B 40 -110 683 738 ;
+C 234 ; WX 944 ; N OE ; B 30 -10 943 668 ;
+C 235 ; WX 310 ; N ordmasculine ; B 45 301 310 679 ;
+C 241 ; WX 667 ; N ae ; B 24 -12 638 448 ;
+C 245 ; WX 278 ; N dotlessi ; B 47 -10 226 447 ;
+C 248 ; WX 278 ; N lslash ; B 0 -10 264 685 ;
+C 249 ; WX 500 ; N oslash ; B 28 -132 468 560 ;
+C 250 ; WX 667 ; N oe ; B 26 -15 643 445 ;
+C 251 ; WX 500 ; N germandbls ; B -167 -209 492 684 ;
+C -1 ; WX 611 ; N Aacute ; B -45 0 564 907 ;
+C -1 ; WX 611 ; N Acircumflex ; B -45 0 564 896 ;
+C -1 ; WX 611 ; N Adieresis ; B -45 0 564 861 ;
+C -1 ; WX 611 ; N Agrave ; B -45 0 564 886 ;
+C -1 ; WX 611 ; N Aring ; B -45 0 564 930 ;
+C -1 ; WX 611 ; N Atilde ; B -45 0 564 866 ;
+C -1 ; WX 667 ; N Ccedilla ; B 33 -206 653 672 ;
+C -1 ; WX 611 ; N Eacute ; B -17 0 609 907 ;
+C -1 ; WX 611 ; N Ecircumflex ; B -17 0 609 896 ;
+C -1 ; WX 611 ; N Edieresis ; B -17 0 609 861 ;
+C -1 ; WX 611 ; N Egrave ; B -17 0 609 886 ;
+C -1 ; WX 722 ; N Eth ; B -27 0 671 660 ;
+C -1 ; WX 333 ; N Iacute ; B -26 0 389 907 ;
+C -1 ; WX 333 ; N Icircumflex ; B -26 0 388 896 ;
+C -1 ; WX 333 ; N Idieresis ; B -26 0 403 861 ;
+C -1 ; WX 333 ; N Igrave ; B -26 0 357 886 ;
+C -1 ; WX 667 ; N Ntilde ; B -36 -12 698 866 ;
+C -1 ; WX 722 ; N Oacute ; B 42 -23 676 907 ;
+C -1 ; WX 722 ; N Ocircumflex ; B 42 -23 676 896 ;
+C -1 ; WX 722 ; N Odieresis ; B 42 -23 676 861 ;
+C -1 ; WX 722 ; N Ograve ; B 42 -23 676 886 ;
+C -1 ; WX 722 ; N Otilde ; B 42 -23 676 866 ;
+C -1 ; WX 500 ; N Scaron ; B 9 -22 506 896 ;
+C -1 ; WX 611 ; N Thorn ; B -16 0 547 660 ;
+C -1 ; WX 722 ; N Uacute ; B 77 -21 747 907 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 77 -21 747 896 ;
+C -1 ; WX 722 ; N Udieresis ; B 77 -21 747 861 ;
+C -1 ; WX 722 ; N Ugrave ; B 77 -21 747 886 ;
+C -1 ; WX 556 ; N Yacute ; B 44 0 600 894 ;
+C -1 ; WX 556 ; N Ydieresis ; B 44 0 600 861 ;
+C -1 ; WX 556 ; N Zcaron ; B -19 0 581 896 ;
+C -1 ; WX 500 ; N aacute ; B 15 -11 474 680 ;
+C -1 ; WX 500 ; N acircumflex ; B 15 -11 474 669 ;
+C -1 ; WX 500 ; N adieresis ; B 15 -11 479 634 ;
+C -1 ; WX 500 ; N agrave ; B 15 -11 474 659 ;
+C -1 ; WX 500 ; N aring ; B 15 -11 474 703 ;
+C -1 ; WX 500 ; N atilde ; B 15 -11 476 639 ;
+C -1 ; WX 275 ; N brokenbar ; B -22 -188 251 670 ;
+C -1 ; WX 444 ; N ccedilla ; B 32 -206 420 446 ;
+C -1 ; WX 760 ; N copyright ; B 40 -22 719 672 ;
+C -1 ; WX 400 ; N degree ; B 70 384 370 684 ;
+C -1 ; WX 675 ; N divide ; B 85 0 589 505 ;
+C -1 ; WX 444 ; N eacute ; B 34 -13 444 680 ;
+C -1 ; WX 444 ; N ecircumflex ; B 34 -13 443 669 ;
+C -1 ; WX 444 ; N edieresis ; B 34 -13 458 634 ;
+C -1 ; WX 444 ; N egrave ; B 34 -13 412 659 ;
+C -1 ; WX 500 ; N eth ; B 27 -13 487 682 ;
+C -1 ; WX 278 ; N iacute ; B 47 -10 341 680 ;
+C -1 ; WX 278 ; N icircumflex ; B 47 -10 340 669 ;
+C -1 ; WX 278 ; N idieresis ; B 47 -10 355 634 ;
+C -1 ; WX 278 ; N igrave ; B 47 -10 299 659 ;
+C -1 ; WX 675 ; N logicalnot ; B 85 113 589 383 ;
+C -1 ; WX 675 ; N minus ; B 85 222 589 286 ;
+C -1 ; WX 500 ; N mu ; B -60 -206 472 446 ;
+C -1 ; WX 675 ; N multiply ; B 85 0 589 504 ;
+C -1 ; WX 500 ; N ntilde ; B 23 -10 471 639 ;
+C -1 ; WX 500 ; N oacute ; B 27 -13 467 680 ;
+C -1 ; WX 500 ; N ocircumflex ; B 27 -13 467 669 ;
+C -1 ; WX 500 ; N odieresis ; B 27 -13 479 634 ;
+C -1 ; WX 500 ; N ograve ; B 27 -13 467 659 ;
+C -1 ; WX 750 ; N onehalf ; B 30 -15 720 684 ;
+C -1 ; WX 750 ; N onequarter ; B 30 -15 720 684 ;
+C -1 ; WX 300 ; N onesuperior ; B 43 274 277 683 ;
+C -1 ; WX 500 ; N otilde ; B 27 -13 476 639 ;
+C -1 ; WX 675 ; N plusminus ; B 85 0 589 645 ;
+C -1 ; WX 760 ; N registered ; B 40 -22 719 672 ;
+C -1 ; WX 389 ; N scaron ; B 16 -14 450 669 ;
+C -1 ; WX 500 ; N thorn ; B -75 -206 465 682 ;
+C -1 ; WX 750 ; N threequarters ; B 30 -15 720 684 ;
+C -1 ; WX 300 ; N threesuperior ; B 13 267 306 684 ;
+C -1 ; WX 980 ; N trademark ; B 35 268 945 672 ;
+C -1 ; WX 300 ; N twosuperior ; B 8 274 292 684 ;
+C -1 ; WX 500 ; N uacute ; B 42 -11 472 680 ;
+C -1 ; WX 500 ; N ucircumflex ; B 42 -11 472 669 ;
+C -1 ; WX 500 ; N udieresis ; B 42 -11 473 634 ;
+C -1 ; WX 500 ; N ugrave ; B 42 -11 472 659 ;
+C -1 ; WX 444 ; N yacute ; B -27 -209 431 680 ;
+C -1 ; WX 444 ; N ydieresis ; B -27 -209 445 634 ;
+C -1 ; WX 389 ; N zcaron ; B 2 0 450 669 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 120
+
+KPX A y -55
+KPX A w -55
+KPX A v -55
+KPX A space -18
+KPX A quoteright -37
+KPX A Y -55
+KPX A W -37
+KPX A V -50
+KPX A T -37
+
+KPX F period -129
+KPX F comma -129
+KPX F A -129
+
+KPX L y -30
+KPX L space -18
+KPX L quoteright -37
+KPX L Y -20
+KPX L W -37
+KPX L V -37
+KPX L T -20
+
+KPX P space -18
+KPX P period -129
+KPX P comma -129
+KPX P A -129
+
+KPX R y -18
+KPX R Y -18
+KPX R W -18
+KPX R V -18
+KPX R T 0
+
+KPX T y -74
+KPX T w -74
+KPX T u -55
+KPX T space -18
+KPX T semicolon -65
+KPX T s -92
+KPX T r -55
+KPX T period -74
+KPX T o -92
+KPX T i -55
+KPX T hyphen -74
+KPX T e -92
+KPX T comma -74
+KPX T colon -55
+KPX T c -92
+KPX T a -92
+KPX T O -18
+KPX T A -74
+
+KPX V y -92
+KPX V u -74
+KPX V space -18
+KPX V semicolon -74
+KPX V r -74
+KPX V period -129
+KPX V o -111
+KPX V i -74
+KPX V hyphen -55
+KPX V e -111
+KPX V comma -129
+KPX V colon -65
+KPX V a -111
+KPX V O -30
+KPX V A -74
+
+KPX W y -92
+KPX W u -55
+KPX W semicolon -65
+KPX W r -55
+KPX W period -92
+KPX W o -92
+KPX W i -55
+KPX W hyphen -37
+KPX W e -92
+KPX W comma -92
+KPX W colon -65
+KPX W a -92
+KPX W A -70
+
+KPX Y v -92
+KPX Y u -92
+KPX Y semicolon -65
+KPX Y q -111
+KPX Y period -92
+KPX Y p -92
+KPX Y o -92
+KPX Y i -74
+KPX Y hyphen -74
+KPX Y e -92
+KPX Y comma -92
+KPX Y colon -65
+KPX Y a -92
+KPX Y A -70
+
+KPX f quoteright 92
+
+KPX one one -74
+
+KPX quoteleft quoteleft -111
+
+KPX quoteright t -111
+KPX quoteright space -111
+KPX quoteright s -129
+KPX quoteright quoteright -111
+
+KPX r y 0
+KPX r x 0
+KPX r w 0
+KPX r v 0
+KPX r u 0
+KPX r t 0
+KPX r r 0
+KPX r quoteright 37
+KPX r q -37
+KPX r period -111
+KPX r o -37
+KPX r hyphen -20
+KPX r h -18
+KPX r g -37
+KPX r e -37
+KPX r d -37
+KPX r comma -111
+KPX r c -37
+
+KPX space A -18
+
+KPX v period -74
+KPX v comma -74
+
+KPX w period -74
+KPX w comma -74
+
+KPX y period -55
+KPX y comma -55
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 111 227 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 28 0 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 83 227 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 188 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 61 0 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 111 227 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 55 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 228 227 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 228 227 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 228 227 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 228 227 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 83 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 83 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 83 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 83 0 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 14 227 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 14 227 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 14 227 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 14 227 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -34 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -34 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -34 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -34 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 160 227 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 160 227 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 160 227 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 160 227 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 68 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 68 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 68 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 68 0 ;
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 146 227 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 146 227 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 146 227 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 146 227 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 89 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 89 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 89 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 89 0 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 221 227 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 221 227 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 221 227 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 221 227 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 89 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 89 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 89 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 89 0 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 146 227 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 89 0 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 181 227 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 76 0 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 221 227 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 89 0 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 80 227 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 29 0 ;
+EndComposites
+EndFontMetrics
diff --git a/samples/printing/TimesRo.afm b/samples/printing/TimesRo.afm
new file mode 100644
index 0000000000..3f8ce6b22a
--- /dev/null
+++ b/samples/printing/TimesRo.afm
@@ -0,0 +1,443 @@
+StartFontMetrics 2.0
+Comment Copyright (c) 1984 Adobe Systems Incorporated. 	All Rights Reserved.
+Comment Creation Date:Tue Aug 5 10:51:57 PDT 1986
+FontName Times-Roman
+EncodingScheme AdobeStandardEncoding
+FullName Times Roman
+FamilyName Times
+Weight Roman
+ItalicAngle 0.0
+IsFixedPitch false
+UnderlinePosition -109
+UnderlineThickness 49
+Version 001.001
+Notice Times Roman is a trademark of Allied Corporation.
+FontBBox -170 -223 1024 896
+CapHeight 662
+XHeight 448
+Descender -217
+Ascender 682
+StartCharMetrics 228
+C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
+C 33 ; WX 333 ; N exclam ; B 109 -14 224 676 ;
+C 34 ; WX 408 ; N quotedbl ; B 70 445 337 685 ;
+C 35 ; WX 500 ; N numbersign ; B 4 0 495 662 ;
+C 36 ; WX 500 ; N dollar ; B 44 -87 456 727 ;
+C 37 ; WX 833 ; N percent ; B 61 -14 772 676 ;
+C 38 ; WX 778 ; N ampersand ; B 42 -14 750 676 ;
+C 39 ; WX 333 ; N quoteright ; B 103 432 242 676 ;
+C 40 ; WX 333 ; N parenleft ; B 49 -177 304 676 ;
+C 41 ; WX 333 ; N parenright ; B 29 -177 284 676 ;
+C 42 ; WX 500 ; N asterisk ; B 64 265 437 683 ;
+C 43 ; WX 564 ; N plus ; B 30 7 534 512 ;
+C 44 ; WX 250 ; N comma ; B 63 -143 202 101 ;
+C 45 ; WX 333 ; N hyphen ; B 43 194 289 257 ;
+C 46 ; WX 250 ; N period ; B 68 -14 183 101 ;
+C 47 ; WX 278 ; N slash ; B -12 -108 302 682 ;
+C 48 ; WX 500 ; N zero ; B 24 -14 476 676 ;
+C 49 ; WX 500 ; N one ; B 111 0 394 676 ;
+C 50 ; WX 500 ; N two ; B 30 0 475 676 ;
+C 51 ; WX 500 ; N three ; B 44 -14 431 676 ;
+C 52 ; WX 500 ; N four ; B 12 0 472 676 ;
+C 53 ; WX 500 ; N five ; B 32 -14 438 688 ;
+C 54 ; WX 500 ; N six ; B 35 -14 468 682 ;
+C 55 ; WX 500 ; N seven ; B 20 -14 449 662 ;
+C 56 ; WX 500 ; N eight ; B 53 -14 442 676 ;
+C 57 ; WX 500 ; N nine ; B 30 -22 460 676 ;
+C 58 ; WX 278 ; N colon ; B 81 -14 196 458 ;
+C 59 ; WX 278 ; N semicolon ; B 63 -143 202 458 ;
+C 60 ; WX 564 ; N less ; B 27 0 536 522 ;
+C 61 ; WX 564 ; N equal ; B 30 132 534 390 ;
+C 62 ; WX 564 ; N greater ; B 27 0 536 522 ;
+C 63 ; WX 444 ; N question ; B 49 -14 395 676 ;
+C 64 ; WX 921 ; N at ; B 0 -155 819 675 ;
+C 65 ; WX 722 ; N A ; B 15 0 706 676 ;
+C 66 ; WX 667 ; N B ; B 20 0 596 662 ;
+C 67 ; WX 667 ; N C ; B 33 -14 637 676 ;
+C 68 ; WX 722 ; N D ; B 20 0 689 662 ;
+C 69 ; WX 611 ; N E ; B 12 0 597 662 ;
+C 70 ; WX 556 ; N F ; B 12 0 544 662 ;
+C 71 ; WX 722 ; N G ; B 27 -14 704 676 ;
+C 72 ; WX 722 ; N H ; B 20 0 703 662 ;
+C 73 ; WX 333 ; N I ; B 18 0 316 662 ;
+C 74 ; WX 389 ; N J ; B 10 -14 376 662 ;
+C 75 ; WX 722 ; N K ; B 20 0 709 662 ;
+C 76 ; WX 611 ; N L ; B 12 0 598 662 ;
+C 77 ; WX 889 ; N M ; B 19 0 871 662 ;
+C 78 ; WX 722 ; N N ; B 12 -14 709 662 ;
+C 79 ; WX 722 ; N O ; B 33 -14 688 676 ;
+C 80 ; WX 556 ; N P ; B 11 0 542 662 ;
+C 81 ; WX 722 ; N Q ; B 33 -177 701 676 ;
+C 82 ; WX 667 ; N R ; B 12 0 654 662 ;
+C 83 ; WX 556 ; N S ; B 42 -14 491 676 ;
+C 84 ; WX 611 ; N T ; B 18 0 594 662 ;
+C 85 ; WX 722 ; N U ; B 16 -14 705 662 ;
+C 86 ; WX 722 ; N V ; B 20 -14 701 662 ;
+C 87 ; WX 944 ; N W ; B 9 -14 936 662 ;
+C 88 ; WX 722 ; N X ; B 12 0 706 662 ;
+C 89 ; WX 722 ; N Y ; B 22 0 703 662 ;
+C 90 ; WX 611 ; N Z ; B 7 0 597 662 ;
+C 91 ; WX 333 ; N bracketleft ; B 88 -156 299 662 ;
+C 92 ; WX 278 ; N backslash ; B -83 0 361 682 ;
+C 93 ; WX 333 ; N bracketright ; B 34 -156 245 662 ;
+C 94 ; WX 469 ; N asciicircum ; B 13 256 456 662 ;
+C 95 ; WX 500 ; N underscore ; B 0 -133 500 -84 ;
+C 96 ; WX 333 ; N quoteleft ; B 91 432 230 676 ;
+C 97 ; WX 444 ; N a ; B 37 -10 442 458 ;
+C 98 ; WX 500 ; N b ; B 9 -10 474 682 ;
+C 99 ; WX 444 ; N c ; B 25 -10 412 458 ;
+C 100 ; WX 500 ; N d ; B 26 -13 491 682 ;
+C 101 ; WX 444 ; N e ; B 22 -10 421 458 ;
+C 102 ; WX 333 ; N f ; B 20 0 383 682 ; L i fi ; L l fl ;
+C 103 ; WX 500 ; N g ; B 27 -217 470 458 ;
+C 104 ; WX 500 ; N h ; B 9 0 490 682 ;
+C 105 ; WX 278 ; N i ; B 22 0 259 682 ;
+C 106 ; WX 278 ; N j ; B -54 -217 212 682 ;
+C 107 ; WX 500 ; N k ; B 1 0 500 682 ;
+C 108 ; WX 278 ; N l ; B 20 0 259 682 ;
+C 109 ; WX 778 ; N m ; B 13 0 764 458 ;
+C 110 ; WX 500 ; N n ; B 9 0 490 458 ;
+C 111 ; WX 500 ; N o ; B 30 -10 470 458 ;
+C 112 ; WX 500 ; N p ; B 2 -217 470 458 ;
+C 113 ; WX 500 ; N q ; B 24 -217 498 459 ;
+C 114 ; WX 333 ; N r ; B 4 0 335 458 ;
+C 115 ; WX 389 ; N s ; B 51 -10 348 458 ;
+C 116 ; WX 278 ; N t ; B 13 -10 279 580 ;
+C 117 ; WX 500 ; N u ; B 9 -10 479 448 ;
+C 118 ; WX 500 ; N v ; B 10 -10 468 448 ;
+C 119 ; WX 722 ; N w ; B 21 -10 694 448 ;
+C 120 ; WX 500 ; N x ; B 17 0 479 448 ;
+C 121 ; WX 500 ; N y ; B 15 -217 476 448 ;
+C 122 ; WX 444 ; N z ; B 25 0 418 448 ;
+C 123 ; WX 480 ; N braceleft ; B 110 -165 341 682 ;
+C 124 ; WX 200 ; N bar ; B 68 0 132 682 ;
+C 125 ; WX 480 ; N braceright ; B 139 -165 370 682 ;
+C 126 ; WX 541 ; N asciitilde ; B 18 176 522 347 ;
+C 161 ; WX 333 ; N exclamdown ; B 109 -217 224 458 ;
+C 162 ; WX 500 ; N cent ; B 53 -138 448 579 ;
+C 163 ; WX 500 ; N sterling ; B 11 -14 491 676 ;
+C 164 ; WX 167 ; N fraction ; B -170 -14 346 676 ;
+C 165 ; WX 500 ; N yen ; B -43 0 502 662 ;
+C 166 ; WX 500 ; N florin ; B 6 -185 490 676 ;
+C 167 ; WX 500 ; N section ; B 72 -148 426 676 ;
+C 168 ; WX 500 ; N currency ; B -2 99 503 600 ;
+C 169 ; WX 180 ; N quotesingle ; B 47 445 133 685 ;
+C 170 ; WX 444 ; N quotedblleft ; B 27 432 399 676 ;
+C 171 ; WX 500 ; N guillemotleft ; B 32 35 449 422 ;
+C 172 ; WX 333 ; N guilsinglleft ; B 45 35 271 422 ;
+C 173 ; WX 333 ; N guilsinglright ; B 62 36 288 423 ;
+C 174 ; WX 556 ; N fi ; B 33 0 521 678 ;
+C 175 ; WX 556 ; N fl ; B 29 0 521 682 ;
+C 177 ; WX 500 ; N endash ; B -7 201 507 250 ;
+C 178 ; WX 500 ; N dagger ; B 54 -149 440 676 ;
+C 179 ; WX 500 ; N daggerdbl ; B 54 -153 439 676 ;
+C 180 ; WX 250 ; N periodcentered ; B 68 204 183 319 ;
+C 182 ; WX 453 ; N paragraph ; B 0 -207 373 662 ;
+C 183 ; WX 350 ; N bullet ; B 50 175 300 425 ;
+C 184 ; WX 333 ; N quotesinglbase ; B 103 -143 242 101 ;
+C 185 ; WX 444 ; N quotedblbase ; B 45 -143 417 101 ;
+C 186 ; WX 444 ; N quotedblright ; B 45 432 417 676 ;
+C 187 ; WX 500 ; N guillemotright ; B 51 35 468 422 ;
+C 188 ; WX 1000 ; N ellipsis ; B 110 -14 891 101 ;
+C 189 ; WX 1000 ; N perthousand ; B 3 -14 1024 676 ;
+C 191 ; WX 444 ; N questiondown ; B 49 -217 395 458 ;
+C 193 ; WX 333 ; N grave ; B 16 507 243 678 ;
+C 194 ; WX 333 ; N acute ; B 93 507 317 678 ;
+C 195 ; WX 333 ; N circumflex ; B 11 507 323 674 ;
+C 196 ; WX 333 ; N tilde ; B 1 532 332 638 ;
+C 197 ; WX 333 ; N macron ; B 11 547 323 601 ;
+C 198 ; WX 333 ; N breve ; B 26 507 308 664 ;
+C 199 ; WX 333 ; N dotaccent ; B 116 523 216 623 ;
+C 200 ; WX 333 ; N dieresis ; B 18 523 316 623 ;
+C 202 ; WX 333 ; N ring ; B 67 483 266 682 ;
+C 203 ; WX 333 ; N cedilla ; B 53 -215 262 0 ;
+C 205 ; WX 333 ; N hungarumlaut ; B 8 528 372 700 ;
+C 206 ; WX 333 ; N ogonek ; B 68 -155 245 -10 ;
+C 207 ; WX 333 ; N caron ; B 11 507 323 674 ;
+C 208 ; WX 1000 ; N emdash ; B -8 201 1007 250 ;
+C 225 ; WX 889 ; N AE ; B 5 0 869 662 ;
+C 227 ; WX 276 ; N ordfeminine ; B 15 307 278 676 ;
+C 232 ; WX 611 ; N Lslash ; B 12 0 598 662 ;
+C 233 ; WX 722 ; N Oslash ; B 33 -80 688 734 ;
+C 234 ; WX 889 ; N OE ; B 21 -7 877 669 ;
+C 235 ; WX 310 ; N ordmasculine ; B 15 307 301 676 ;
+C 241 ; WX 667 ; N ae ; B 38 -10 634 458 ;
+C 245 ; WX 278 ; N dotlessi ; B 22 0 259 458 ;
+C 248 ; WX 278 ; N lslash ; B 20 0 259 682 ;
+C 249 ; WX 500 ; N oslash ; B 30 -108 470 549 ;
+C 250 ; WX 722 ; N oe ; B 30 -10 690 458 ;
+C 251 ; WX 500 ; N germandbls ; B 12 -10 468 682 ;
+C -1 ; WX 722 ; N Aacute ; B 15 0 706 892 ;
+C -1 ; WX 722 ; N Acircumflex ; B 15 0 706 888 ;
+C -1 ; WX 722 ; N Adieresis ; B 15 0 706 837 ;
+C -1 ; WX 722 ; N Agrave ; B 15 0 706 892 ;
+C -1 ; WX 722 ; N Aring ; B 15 0 706 896 ;
+C -1 ; WX 722 ; N Atilde ; B 15 0 706 852 ;
+C -1 ; WX 667 ; N Ccedilla ; B 33 -215 637 676 ;
+C -1 ; WX 611 ; N Eacute ; B 12 0 597 892 ;
+C -1 ; WX 611 ; N Ecircumflex ; B 12 0 597 888 ;
+C -1 ; WX 611 ; N Edieresis ; B 12 0 597 837 ;
+C -1 ; WX 611 ; N Egrave ; B 12 0 597 892 ;
+C -1 ; WX 722 ; N Eth ; B 20 0 689 662 ;
+C -1 ; WX 333 ; N Iacute ; B 18 0 317 892 ;
+C -1 ; WX 333 ; N Icircumflex ; B 11 0 323 888 ;
+C -1 ; WX 333 ; N Idieresis ; B 18 0 316 837 ;
+C -1 ; WX 333 ; N Igrave ; B 16 0 316 892 ;
+C -1 ; WX 722 ; N Ntilde ; B 12 -14 709 852 ;
+C -1 ; WX 722 ; N Oacute ; B 33 -14 688 892 ;
+C -1 ; WX 722 ; N Ocircumflex ; B 33 -14 688 888 ;
+C -1 ; WX 722 ; N Odieresis ; B 33 -14 688 837 ;
+C -1 ; WX 722 ; N Ograve ; B 33 -14 688 892 ;
+C -1 ; WX 722 ; N Otilde ; B 33 -14 688 852 ;
+C -1 ; WX 556 ; N Scaron ; B 42 -14 491 888 ;
+C -1 ; WX 556 ; N Thorn ; B 11 0 542 662 ;
+C -1 ; WX 722 ; N Uacute ; B 16 -14 705 892 ;
+C -1 ; WX 722 ; N Ucircumflex ; B 16 -14 705 888 ;
+C -1 ; WX 722 ; N Udieresis ; B 16 -14 705 837 ;
+C -1 ; WX 722 ; N Ugrave ; B 16 -14 705 892 ;
+C -1 ; WX 722 ; N Yacute ; B 22 0 703 892 ;
+C -1 ; WX 722 ; N Ydieresis ; B 22 0 703 837 ;
+C -1 ; WX 611 ; N Zcaron ; B 7 0 597 888 ;
+C -1 ; WX 444 ; N aacute ; B 37 -10 442 678 ;
+C -1 ; WX 444 ; N acircumflex ; B 37 -10 442 674 ;
+C -1 ; WX 444 ; N adieresis ; B 37 -10 442 623 ;
+C -1 ; WX 444 ; N agrave ; B 37 -10 442 678 ;
+C -1 ; WX 444 ; N aring ; B 37 -10 442 682 ;
+C -1 ; WX 444 ; N atilde ; B 37 -10 442 638 ;
+C -1 ; WX 200 ; N brokenbar ; B 68 0 132 682 ;
+C -1 ; WX 444 ; N ccedilla ; B 25 -215 412 458 ;
+C -1 ; WX 760 ; N copyright ; B 42 -14 717 676 ;
+C -1 ; WX 400 ; N degree ; B 50 376 350 676 ;
+C -1 ; WX 564 ; N divide ; B 30 10 534 512 ;
+C -1 ; WX 444 ; N eacute ; B 22 -10 421 678 ;
+C -1 ; WX 444 ; N ecircumflex ; B 22 -10 421 674 ;
+C -1 ; WX 444 ; N edieresis ; B 22 -10 421 623 ;
+C -1 ; WX 444 ; N egrave ; B 22 -10 421 678 ;
+C -1 ; WX 500 ; N eth ; B 30 -10 470 682 ;
+C -1 ; WX 278 ; N iacute ; B 22 0 290 678 ;
+C -1 ; WX 278 ; N icircumflex ; B -16 0 296 674 ;
+C -1 ; WX 278 ; N idieresis ; B -9 0 289 623 ;
+C -1 ; WX 278 ; N igrave ; B -11 0 259 678 ;
+C -1 ; WX 564 ; N logicalnot ; B 30 120 534 390 ;
+C -1 ; WX 564 ; N minus ; B 30 229 534 293 ;
+C -1 ; WX 500 ; N mu ; B 9 -223 479 448 ;
+C -1 ; WX 564 ; N multiply ; B 30 8 534 512 ;
+C -1 ; WX 500 ; N ntilde ; B 9 0 490 638 ;
+C -1 ; WX 500 ; N oacute ; B 30 -10 470 678 ;
+C -1 ; WX 500 ; N ocircumflex ; B 30 -10 470 674 ;
+C -1 ; WX 500 ; N odieresis ; B 30 -10 470 623 ;
+C -1 ; WX 500 ; N ograve ; B 30 -10 470 678 ;
+C -1 ; WX 750 ; N onehalf ; B 30 -14 720 676 ;
+C -1 ; WX 750 ; N onequarter ; B 30 -14 720 676 ;
+C -1 ; WX 300 ; N onesuperior ; B 58 270 242 676 ;
+C -1 ; WX 500 ; N otilde ; B 30 -10 470 638 ;
+C -1 ; WX 564 ; N plusminus ; B 30 0 534 612 ;
+C -1 ; WX 760 ; N registered ; B 43 -14 718 676 ;
+C -1 ; WX 389 ; N scaron ; B 39 -10 351 674 ;
+C -1 ; WX 500 ; N thorn ; B 2 -217 470 682 ;
+C -1 ; WX 750 ; N threequarters ; B 30 -14 720 676 ;
+C -1 ; WX 300 ; N threesuperior ; B 24 262 275 676 ;
+C -1 ; WX 980 ; N trademark ; B 35 258 945 662 ;
+C -1 ; WX 300 ; N twosuperior ; B 5 270 294 676 ;
+C -1 ; WX 500 ; N uacute ; B 9 -10 479 678 ;
+C -1 ; WX 500 ; N ucircumflex ; B 9 -10 479 674 ;
+C -1 ; WX 500 ; N udieresis ; B 9 -10 479 623 ;
+C -1 ; WX 500 ; N ugrave ; B 9 -10 479 678 ;
+C -1 ; WX 500 ; N yacute ; B 15 -217 476 678 ;
+C -1 ; WX 500 ; N ydieresis ; B 15 -217 476 623 ;
+C -1 ; WX 444 ; N zcaron ; B 25 0 418 674 ;
+EndCharMetrics
+StartKernData
+StartKernPairs 113
+
+KPX A y -92
+KPX A w -92
+KPX A v -74
+KPX A space -55
+KPX A quoteright -111
+KPX A Y -92
+KPX A W -80
+KPX A V -129
+KPX A T -111
+
+KPX F period -80
+KPX F comma -80
+KPX F A -74
+
+KPX L y -55
+KPX L space -37
+KPX L quoteright -92
+KPX L Y -100
+KPX L W -74
+KPX L V -92
+KPX L T -92
+
+KPX P space -37
+KPX P period -111
+KPX P comma -111
+KPX P A -92
+
+KPX R y -40
+KPX R Y -55
+KPX R W -55
+KPX R V -80
+KPX R T -60
+
+KPX T y -70
+KPX T w -70
+KPX T u -35
+KPX T space -18
+KPX T semicolon -55
+KPX T s -70
+KPX T r -35
+KPX T period -74
+KPX T o -70
+KPX T i -35
+KPX T hyphen -92
+KPX T e -70
+KPX T comma -74
+KPX T colon -50
+KPX T c -70
+KPX T a -70
+KPX T O -18
+KPX T A -80
+
+KPX V y -111
+KPX V u -60
+KPX V space -18
+KPX V semicolon -74
+KPX V r -60
+KPX V period -129
+KPX V o -129
+KPX V i -60
+KPX V hyphen -92
+KPX V e -111
+KPX V comma -129
+KPX V colon -74
+KPX V a -111
+KPX V A -129
+
+KPX W y -60
+KPX W u -40
+KPX W space -18
+KPX W semicolon -37
+KPX W r -40
+KPX W period -92
+KPX W o -80
+KPX W i -40
+KPX W hyphen -55
+KPX W e -80
+KPX W comma -92
+KPX W colon -37
+KPX W a -80
+KPX W A -111
+
+KPX Y v -100
+KPX Y u -111
+KPX Y space -37
+KPX Y semicolon -92
+KPX Y q -111
+KPX Y period -129
+KPX Y p -92
+KPX Y o -100
+KPX Y i -55
+KPX Y hyphen -111
+KPX Y e -100
+KPX Y comma -129
+KPX Y colon -92
+KPX Y a -100
+KPX Y A -111
+
+KPX f quoteright 55
+KPX f f -18
+
+KPX one one -37
+
+KPX quoteleft quoteleft -74
+
+KPX quoteright t -18
+KPX quoteright space -74
+KPX quoteright s -55
+KPX quoteright quoteright -74
+
+KPX r quoteright 37
+KPX r period -55
+KPX r hyphen -20
+KPX r g -18
+KPX r comma -40
+
+KPX space Y -37
+KPX space W -18
+KPX space V -18
+KPX space T -18
+KPX space A -55
+
+KPX v period -65
+KPX v comma -65
+
+KPX w period -65
+KPX w comma -65
+
+KPX y period -65
+KPX y comma -65
+EndKernPairs
+EndKernData
+StartComposites 56
+CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 214 ;
+CC zcaron 2 ; PCC z 0 0 ; PCC caron 55 0 ;
+CC Scaron 2 ; PCC S 0 0 ; PCC caron 111 214 ;
+CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ;
+CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 167 0 ;
+CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 55 0 ;
+CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 194 214 ;
+CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 83 0 ;
+CC Uacute 2 ; PCC U 0 0 ; PCC acute 194 214 ;
+CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 194 214 ;
+CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 194 214 ;
+CC Ugrave 2 ; PCC U 0 0 ; PCC grave 194 214 ;
+CC uacute 2 ; PCC u 0 0 ; PCC acute 83 0 ;
+CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 83 0 ;
+CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 83 0 ;
+CC ugrave 2 ; PCC u 0 0 ; PCC grave 83 0 ;
+CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 214 ;
+CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 0 214 ;
+CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 0 214 ;
+CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 214 ;
+CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
+CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
+CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
+CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
+CC Eacute 2 ; PCC E 0 0 ; PCC acute 139 214 ;
+CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 139 214 ;
+CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 139 214 ;
+CC Egrave 2 ; PCC E 0 0 ; PCC grave 139 214 ;
+CC eacute 2 ; PCC e 0 0 ; PCC acute 55 0 ;
+CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 55 0 ;
+CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 55 0 ;
+CC egrave 2 ; PCC e 0 0 ; PCC grave 55 0 ;
+CC Aacute 2 ; PCC A 0 0 ; PCC acute 194 214 ;
+CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 194 214 ;
+CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 194 214 ;
+CC Agrave 2 ; PCC A 0 0 ; PCC grave 194 214 ;
+CC aacute 2 ; PCC a 0 0 ; PCC acute 55 0 ;
+CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 55 0 ;
+CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 55 0 ;
+CC agrave 2 ; PCC a 0 0 ; PCC grave 55 0 ;
+CC Oacute 2 ; PCC O 0 0 ; PCC acute 194 214 ;
+CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 194 214 ;
+CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 194 214 ;
+CC Ograve 2 ; PCC O 0 0 ; PCC grave 194 214 ;
+CC oacute 2 ; PCC o 0 0 ; PCC acute 83 0 ;
+CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 83 0 ;
+CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 83 0 ;
+CC ograve 2 ; PCC o 0 0 ; PCC grave 83 0 ;
+CC Atilde 2 ; PCC A 0 0 ; PCC tilde 194 214 ;
+CC atilde 2 ; PCC a 0 0 ; PCC tilde 55 0 ;
+CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 194 214 ;
+CC ntilde 2 ; PCC n 0 0 ; PCC tilde 83 0 ;
+CC Otilde 2 ; PCC O 0 0 ; PCC tilde 194 214 ;
+CC otilde 2 ; PCC o 0 0 ; PCC tilde 83 0 ;
+CC Aring 2 ; PCC A 0 0 ; PCC ring 194 214 ;
+CC aring 2 ; PCC a 0 0 ; PCC ring 55 0 ;
+EndComposites
+EndFontMetrics
diff --git a/samples/printing/aiai.ico b/samples/printing/aiai.ico
new file mode 100644
index 0000000000000000000000000000000000000000..a3db6563cc0b9f4588e1e994fe54b90a3cb1d6c1
GIT binary patch
literal 766
zcmc(bJ930T3`Bcft}@v=+L+MC@X_W5#I6lE$3$=(hlEfB<Ja@?LOIyb0!^!t)JP*;
zc>4Zbw(l3|27cf@{)u1o%88L{R;n8d60briz)7fio<S#4ewC6VoX4NcpV>a{V~VK)
z)$t4e1%j>c0*T7ZEBuvb0Ndch+2BCx7U^mZHa?iIh11ZPGV>8*oPzc{HmcjEM7U^(
z*rd)gSRm_`KJo;dxt={X3#3|q&kYE;ul$En1WJC3UOX%3ev8=<z}j41;VP{UzUs~U
s)wx~DuB_~?Y=Qe|v5`BV=<&%~$Nt1hCmx0~Ul2L;AGObMz1)9;A6NK_vj6}9

literal 0
HcmV?d00001

diff --git a/samples/printing/aiai.xbm b/samples/printing/aiai.xbm
new file mode 100644
index 0000000000..1a6f0a31b1
--- /dev/null
+++ b/samples/printing/aiai.xbm
@@ -0,0 +1,38 @@
+#define aiai_width 64
+#define aiai_height 64
+static char aiai_bits[] = {
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x44,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x44,0x44,0x44,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x44,0x44,0x44,0x42,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x47,0x44,0x44,0x44,0x44,0x11,0x11,0x11,0x17,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x91,0x1f,0x11,0x11,0x11,0x11,0x44,0x44,0xc4,0x4f,0x44,0x44,0x44,0x44,
+ 0x44,0x44,0xc4,0x5f,0x44,0xf4,0x45,0x44,0x11,0x11,0xf1,0x1f,0x11,0xf9,0x13,
+ 0x11,0x11,0x11,0xf1,0x3f,0x11,0xfd,0x13,0x11,0x44,0x44,0xf4,0x7f,0x44,0xfc,
+ 0x47,0x44,0x44,0x44,0xf4,0x7f,0x44,0xfc,0x47,0x44,0x11,0x11,0xf9,0x7f,0x11,
+ 0xf9,0x13,0x11,0x11,0x11,0xfd,0xff,0x11,0xf1,0x11,0x11,0x44,0x44,0xfc,0xff,
+ 0x44,0x44,0x44,0x44,0x44,0x44,0xfe,0xff,0x45,0x44,0x44,0x44,0x11,0x11,0xff,
+ 0xff,0x11,0xfd,0x13,0x11,0x11,0x11,0xff,0xff,0x13,0xfd,0x13,0x11,0x44,0xc4,
+ 0xff,0xff,0x07,0xfc,0x43,0x44,0x44,0xff,0xff,0xf9,0xff,0xfd,0xfb,0xff,0x11,
+ 0xc0,0xff,0x00,0x00,0xfc,0x03,0x00,0x11,0xc0,0x7f,0x00,0x00,0xfc,0x03,0x00,
+ 0x04,0xe0,0x7f,0x00,0x00,0xfc,0x03,0x00,0xf4,0xf7,0xbf,0xff,0xff,0xfd,0xfb,
+ 0x7f,0x01,0xf0,0x1f,0x00,0x00,0xfc,0x03,0x00,0x01,0xf8,0x1f,0x00,0x00,0xfc,
+ 0x03,0x00,0x00,0xfc,0x0f,0x00,0x00,0xfc,0x03,0x40,0xfe,0xfd,0xef,0xff,0xff,
+ 0xfd,0xfb,0x4f,0x00,0xfe,0x07,0x00,0x00,0xfc,0x03,0x10,0x00,0xfe,0x03,0x00,
+ 0x00,0xfc,0x03,0x10,0x00,0xff,0x03,0x00,0x00,0xfc,0x03,0x44,0x7f,0xff,0x01,
+ 0x00,0x00,0xfc,0xfb,0x44,0x91,0xff,0xff,0xff,0xff,0xff,0x13,0x11,0xd1,0xff,
+ 0xff,0xff,0xff,0xff,0x13,0x11,0xe4,0xff,0xff,0xff,0xff,0xff,0x47,0x44,0xe4,
+ 0xff,0xff,0xff,0xff,0xff,0x47,0x44,0xf1,0xff,0xff,0xff,0xff,0xff,0x13,0x11,
+ 0xf1,0xff,0xff,0xff,0xff,0xff,0x13,0x11,0xfc,0xff,0xff,0xff,0xff,0xff,0x47,
+ 0x44,0xfc,0xff,0xff,0xff,0xff,0xff,0x47,0x44,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x11,0x44,0x44,0xc4,0x44,0x44,
+ 0xc4,0x44,0x44,0x44,0x4e,0xc4,0x44,0x4e,0xc4,0x44,0x44,0x11,0x1f,0xd1,0x11,
+ 0x1f,0xd1,0x11,0x11,0x91,0x31,0xd1,0x91,0x31,0xd1,0x11,0x11,0xc4,0x64,0xcc,
+ 0xcc,0x64,0xcc,0x44,0x44,0x64,0xc4,0xcc,0x6c,0xc4,0xcc,0x44,0x44,0xf1,0xff,
+ 0xd1,0xf1,0xff,0xd1,0x11,0x11,0xf9,0xff,0xd3,0xf9,0xff,0xd3,0x11,0x11,0x4c,
+ 0x44,0xc6,0x4c,0x44,0xc6,0x44,0x44,0x4c,0x44,0xc6,0x4c,0x44,0xc6,0x44,0x44,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x44};
diff --git a/samples/printing/fload.xbm b/samples/printing/fload.xbm
new file mode 100644
index 0000000000..27af1f939b
--- /dev/null
+++ b/samples/printing/fload.xbm
@@ -0,0 +1,11 @@
+#define fload_width 30
+#define fload_height 30
+static char fload_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x0f,0xf8,0xff,0xfb,0x0f,0x08,0x00,0xf0,
+ 0x0f,0xc8,0xff,0xef,0x0f,0x48,0x00,0xf0,0x0f,0x48,0x00,0xf8,0x0f,0x48,0x00,
+ 0xfc,0x0e,0x48,0x00,0x7f,0x0c,0x48,0xc0,0xbf,0x00,0x48,0xf0,0x9f,0x04,0x48,
+ 0xfe,0x8f,0x04,0x48,0xff,0x87,0x04,0x48,0x00,0x80,0x04,0x48,0x00,0x80,0x04,
+ 0x48,0x00,0x80,0x04,0x48,0x00,0x80,0x04,0xc8,0xff,0xff,0x04,0x08,0x00,0x00,
+ 0x04,0x08,0x00,0x00,0x04,0x08,0xff,0x1f,0x04,0x08,0x01,0x10,0x04,0x08,0x1d,
+ 0x10,0x04,0x08,0x15,0x10,0x04,0x08,0x15,0x10,0x04,0x08,0x15,0x10,0x04,0x08,
+ 0x15,0x10,0x04,0x10,0x1d,0x10,0x04,0xe0,0xff,0xff,0x07,0x00,0x00,0x00,0x00};
diff --git a/samples/printing/printing.cpp b/samples/printing/printing.cpp
new file mode 100644
index 0000000000..d11143d205
--- /dev/null
+++ b/samples/printing/printing.cpp
@@ -0,0 +1,550 @@
+/*
+ * File:	printing.cc
+ * Purpose:	Printing demo for wxWindows class library
+ * Author:	Julian Smart
+ * Created:	1995
+ * Updated:	
+ * Copyright:   (c) 1995, AIAI, University of Edinburgh
+ */
+
+/* static const char sccsid[] = "%W% %G%"; */
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+// For compilers that support precompilation, includes "wx/wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#include "wx/postscrp.h"
+#endif
+
+#if !USE_PRINTING_ARCHITECTURE
+#error You must set USE_PRINTING_ARCHITECTURE to 1 in wx_setup.h to compile this demo.
+#endif
+
+#include <ctype.h>
+#include "wx/metafile.h"
+#include "wx/print.h"
+#include "wx/printdlg.h"
+#include "wx/generic/printps.h"
+#include "wx/generic/prntdlgg.h"
+
+#include "printing.h"
+
+// Declare a frame
+MyFrame   *frame = NULL;
+int orientation = wxPORTRAIT;
+
+// Main proc
+IMPLEMENT_APP(MyApp)
+
+// Must initialise these in OnInit, not statically
+wxPen     *red_pen;
+wxFont    *labelFont;
+wxFont    *itemFont;
+
+float     zoom_factor = 1.0;
+
+#ifdef __X__
+#include "aiai.xbm"
+#endif
+
+// Writes a header on a page. Margin units are in millimetres.
+bool WritePageHeader(wxPrintout *printout, wxDC *dc, char *text, float mmToLogical);
+
+MyApp::MyApp()
+{
+}
+
+// The `main program' equivalent, creating the windows and returning the
+// main frame
+bool MyApp::OnInit(void)
+{
+  // Create a red pen
+  red_pen = new wxPen("RED", 3, wxSOLID);
+
+  // Create a small font
+  itemFont = new wxFont(11, wxROMAN, wxNORMAL, wxNORMAL);
+  labelFont = new wxFont(12, wxROMAN, wxITALIC, wxBOLD);
+
+  // Create the main frame window
+  frame = new MyFrame(NULL, "wxWindows Printing Demo", wxPoint(0, 0), wxSize(400, 400));
+
+  // Give it a status line
+  frame->CreateStatusBar(2);
+
+  // Load icon and bitmap
+#ifdef __WINDOWS__
+  frame->SetIcon(wxIcon("aiai_icn"));
+#endif
+#ifdef __X__
+  frame->SetIcon(wxIcon(aiai_bits, aiai_width, aiai_height));
+#endif
+
+  // Make a menubar
+  wxMenu *file_menu = new wxMenu;
+
+  file_menu->Append(WXPRINT_PRINT, "&Print...",              "Print");
+  file_menu->Append(WXPRINT_PRINT_SETUP, "Print &Setup...",              "Setup printer properties");
+  file_menu->Append(WXPRINT_PAGE_SETUP, "Page Set&up...",              "Page setup");
+  file_menu->Append(WXPRINT_PREVIEW, "Print Pre&view",              "Preview");
+
+#ifdef __WINDOWS__
+  file_menu->AppendSeparator();
+  file_menu->Append(WXPRINT_PRINT_PS, "Print PostScript...",              "Print (PostScript)");
+  file_menu->Append(WXPRINT_PRINT_SETUP_PS, "Print Setup PostScript...",              "Setup printer properties (PostScript)");
+  file_menu->Append(WXPRINT_PAGE_SETUP_PS, "Page Setup PostScript...",              "Page setup (PostScript)");
+  file_menu->Append(WXPRINT_PREVIEW_PS, "Print Preview PostScript",              "Preview (PostScript)");
+#endif
+  file_menu->AppendSeparator();
+  file_menu->Append(WXPRINT_QUIT, "E&xit",                "Exit program");
+
+  wxMenu *help_menu = new wxMenu;
+  help_menu->Append(WXPRINT_ABOUT, "&About",              "About this demo");
+
+  wxMenuBar *menu_bar = new wxMenuBar;
+
+  menu_bar->Append(file_menu, "&File");
+  menu_bar->Append(help_menu, "&Help");
+
+  // Associate the menu bar with the frame
+  frame->SetMenuBar(menu_bar);
+
+  MyCanvas *canvas = new MyCanvas(frame, wxPoint(0, 0), wxSize(100, 100), wxRETAINED|wxHSCROLL|wxVSCROLL);
+
+  // Give it scrollbars: the virtual canvas is 20 * 50 = 1000 pixels in each direction
+  canvas->SetScrollbars(20, 20, 50, 50);
+
+  // This ensures that the fonts get created as _screen_
+  // fonts, not printer fonts.
+  canvas->SetFont(itemFont);
+  canvas->SetFont(labelFont);
+
+  frame->canvas = canvas;
+
+  frame->Centre(wxBOTH);
+  frame->Show(TRUE);
+
+  frame->SetStatusText("Printing demo");
+
+  SetTopWindow(frame);
+
+  return TRUE;
+}
+
+BEGIN_EVENT_TABLE(MyFrame, wxFrame)
+    EVT_MENU(WXPRINT_QUIT, MyFrame::OnExit)
+    EVT_MENU(WXPRINT_PRINT, MyFrame::OnPrint)
+    EVT_MENU(WXPRINT_PREVIEW, MyFrame::OnPrintPreview)
+    EVT_MENU(WXPRINT_PRINT_SETUP, MyFrame::OnPrintSetup)
+    EVT_MENU(WXPRINT_PAGE_SETUP, MyFrame::OnPageSetup)
+    EVT_MENU(WXPRINT_PRINT_PS, MyFrame::OnPrintPS)
+    EVT_MENU(WXPRINT_PREVIEW_PS, MyFrame::OnPrintPreviewPS)
+    EVT_MENU(WXPRINT_PRINT_SETUP_PS, MyFrame::OnPrintSetupPS)
+    EVT_MENU(WXPRINT_PAGE_SETUP_PS, MyFrame::OnPageSetupPS)
+    EVT_MENU(WXPRINT_ABOUT, MyFrame::OnPrintAbout)
+END_EVENT_TABLE()
+
+// Define my frame constructor
+MyFrame::MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size):
+  wxFrame(frame, -1, title, pos, size)
+{
+  canvas = NULL;
+}
+
+void MyFrame::OnExit(wxCommandEvent& event)
+{
+      Close(TRUE);
+}
+
+void MyFrame::OnPrint(wxCommandEvent& event)
+{
+#ifdef __WINDOWS__
+      wxGetApp().SetPrintMode(wxPRINT_WINDOWS);
+#else
+      wxGetApp().SetPrintMode(wxPRINT_POSTSCRIPT);
+#endif
+      wxPrinter printer;
+      MyPrintout printout("My printout");
+      if (!printer.Print(this, &printout, TRUE))
+        wxMessageBox("There was a problem printing.\nPerhaps your current printer is not set correctly?", "Printing", wxOK);
+}
+
+void MyFrame::OnPrintPS(wxCommandEvent& event)
+{
+      wxGetApp().SetPrintMode(wxPRINT_POSTSCRIPT);
+
+      wxPostScriptPrinter printer;
+      MyPrintout printout("My printout");
+      printer.Print(this, &printout, TRUE);
+}
+
+void MyFrame::OnPrintPreview(wxCommandEvent& event)
+{
+#ifdef __WINDOWS__
+      wxGetApp().SetPrintMode(wxPRINT_WINDOWS);
+#else
+      wxGetApp().SetPrintMode(wxPRINT_POSTSCRIPT);
+#endif
+      wxPrintData printData;
+      printData.SetOrientation(orientation);
+
+      // Pass two printout objects: for preview, and possible printing.
+      wxPrintPreview *preview = new wxPrintPreview(new MyPrintout, new MyPrintout, & printData);
+      if (!preview->Ok())
+      {
+        delete preview;
+        wxMessageBox("There was a problem previewing.\nPerhaps your current printer is not set correctly?", "Previewing", wxOK);
+        return;
+      }
+      
+      wxPreviewFrame *frame = new wxPreviewFrame(preview, this, "Demo Print Preview", wxPoint(100, 100), wxSize(600, 650));
+      frame->Centre(wxBOTH);
+      frame->Initialize();
+      frame->Show(TRUE);
+}
+
+void MyFrame::OnPrintPreviewPS(wxCommandEvent& event)
+{
+      wxGetApp().SetPrintMode(wxPRINT_POSTSCRIPT);
+
+      wxPrintData printData;
+      printData.SetOrientation(orientation);
+
+      // Pass two printout objects: for preview, and possible printing.
+      wxPrintPreview *preview = new wxPrintPreview(new MyPrintout, new MyPrintout, & printData);
+      wxPreviewFrame *frame = new wxPreviewFrame(preview, this, "Demo Print Preview", wxPoint(100, 100), wxSize(600, 650));
+      frame->Centre(wxBOTH);
+      frame->Initialize();
+      frame->Show(TRUE);
+}
+
+void MyFrame::OnPrintSetup(wxCommandEvent& event)
+{
+#ifdef __WINDOWS__
+      wxGetApp().SetPrintMode(wxPRINT_WINDOWS);
+#else
+      wxGetApp().SetPrintMode(wxPRINT_POSTSCRIPT);
+#endif
+      wxPrintData data;
+      data.SetOrientation(orientation);
+
+#ifdef __WINDOWS__
+      wxPrintDialog printerDialog(this, & data);
+#else
+      wxGenericPrintDialog printerDialog(this, & data);
+#endif
+      printerDialog.GetPrintData().SetSetupDialog(TRUE);
+      printerDialog.ShowModal();
+
+      orientation = printerDialog.GetPrintData().GetOrientation();
+}
+
+void MyFrame::OnPageSetup(wxCommandEvent& event)
+{
+#ifdef __WINDOWS__
+      wxGetApp().SetPrintMode(wxPRINT_WINDOWS);
+#else
+      wxGetApp().SetPrintMode(wxPRINT_POSTSCRIPT);
+#endif
+      wxPageSetupData data;
+      data.SetOrientation(orientation);
+
+#ifdef __WINDOWS__
+      wxPageSetupDialog pageSetupDialog(this, & data);
+#else
+      wxGenericPageSetupDialog pageSetupDialog(this, & data);
+#endif
+      pageSetupDialog.ShowModal();
+
+      data = pageSetupDialog.GetPageSetupData();
+      orientation = data.GetOrientation();
+}
+
+void MyFrame::OnPrintSetupPS(wxCommandEvent& event)
+{
+      wxGetApp().SetPrintMode(wxPRINT_POSTSCRIPT);
+
+      wxPrintData data;
+      data.SetOrientation(orientation);
+
+      wxGenericPrintDialog printerDialog(this, & data);
+      printerDialog.GetPrintData().SetSetupDialog(TRUE);
+      printerDialog.ShowModal();
+
+      orientation = printerDialog.GetPrintData().GetOrientation();
+}
+
+void MyFrame::OnPageSetupPS(wxCommandEvent& event)
+{
+      wxGetApp().SetPrintMode(wxPRINT_POSTSCRIPT);
+
+      wxPageSetupData data;
+      data.SetOrientation(orientation);
+
+      wxGenericPageSetupDialog pageSetupDialog(this, & data);
+      pageSetupDialog.ShowModal();
+
+      orientation = pageSetupDialog.GetPageSetupData().GetOrientation();
+}
+
+void MyFrame::OnPrintAbout(wxCommandEvent& event)
+{
+      (void)wxMessageBox("wxWindows printing demo\nAuthor: Julian Smart julian.smart@ukonline.co.uk",
+            "About wxWindows printing demo", wxOK|wxCENTRE);
+}
+
+void MyFrame::Draw(wxDC& dc)
+{
+  dc.SetFont(itemFont);
+  dc.SetBackgroundMode(wxTRANSPARENT);
+
+  dc.SetBrush(wxCYAN_BRUSH);
+  dc.SetPen(wxRED_PEN);
+
+  dc.DrawRectangle(0.0, 30.0, 200.0, 100.0);
+  dc.DrawText("Rectangle 200 by 100", 40.0, 40.0);
+
+  dc.DrawEllipse(50.0, 140.0, 100.0, 50.0);
+
+  dc.DrawText("Test message: this is in 11 point text", 10.0, 180.0);
+
+  dc.SetPen(wxBLACK_PEN);
+  dc.DrawLine(0.0, 0.0, 200.0, 200.0);
+  dc.DrawLine(200.0, 0.0, 0.0, 200.0);
+}
+
+void MyFrame::OnSize(wxSizeEvent& event)
+{
+    wxFrame::OnSize(event);
+}
+
+BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
+	EVT_MOUSE_EVENTS(MyCanvas::OnEvent)
+END_EVENT_TABLE()
+
+// Define a constructor for my canvas
+MyCanvas::MyCanvas(wxFrame *frame, const wxPoint& pos, const wxSize& size, long style):
+ wxScrolledWindow(frame, -1, pos, size, style)
+{
+}
+
+MyCanvas::~MyCanvas(void)
+{
+}
+
+// Define the repainting behaviour
+void MyCanvas::OnDraw(wxDC& dc)
+{
+  frame->Draw(dc);
+}
+
+void MyCanvas::OnEvent(wxMouseEvent& event)
+{
+}
+
+// Define the behaviour for the frame closing
+// - must delete all frames except for the main one.
+bool MyFrame::OnClose(void)
+{
+  Show(FALSE);
+
+  return TRUE;
+}
+
+bool MyPrintout::OnPrintPage(int page)
+{
+  wxDC *dc = GetDC();
+  if (dc)
+  {
+    if (page == 1)
+      DrawPageOne(dc);
+    else if (page == 2)
+      DrawPageTwo(dc);
+
+    dc->SetDeviceOrigin(0, 0);
+
+    char buf[200];
+    sprintf(buf, "PAGE %d", page);
+    dc->DrawText(buf, 10.0, 10.0);
+    
+    return TRUE;
+  }
+  else
+    return FALSE;
+}
+
+bool MyPrintout::OnBeginDocument(int startPage, int endPage)
+{
+  if (!wxPrintout::OnBeginDocument(startPage, endPage))
+    return FALSE;
+
+  return TRUE;
+}
+
+void MyPrintout::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo)
+{
+  *minPage = 1;
+  *maxPage = 2;
+  *selPageFrom = 1;
+  *selPageTo = 2;
+}
+
+bool MyPrintout::HasPage(int pageNum)
+{
+  return (pageNum == 1 || pageNum == 2);
+}
+
+void MyPrintout::DrawPageOne(wxDC *dc)
+{
+/* You might use THIS code if you were scaling
+ * graphics of known size to fit on the page.
+ */
+  int w, h;
+
+  // We know the graphic is 200x200. If we didn't know this,
+  // we'd need to calculate it.
+  float maxX = 200;
+  float maxY = 200;
+  
+  // Let's have at least 50 device units margin
+  float marginX = 50;
+  float marginY = 50;
+
+  // Add the margin to the graphic size
+  maxX += (2*marginX);
+  maxY += (2*marginY);
+  
+  // Get the size of the DC in pixels
+  dc->GetSize(&w, &h);
+
+  // Calculate a suitable scaling factor
+  float scaleX=(float)(w/maxX);
+  float scaleY=(float)(h/maxY);
+
+  // Use x or y scaling factor, whichever fits on the DC
+  float actualScale = wxMin(scaleX,scaleY);
+
+  // Calculate the position on the DC for centring the graphic
+  float posX = (float)((w - (200*actualScale))/2.0);
+  float posY = (float)((h - (200*actualScale))/2.0);
+
+  // Set the scale and origin
+  dc->SetUserScale(actualScale, actualScale);
+  dc->SetDeviceOrigin(posX, posY);
+
+  frame->Draw(*dc);
+}
+
+void MyPrintout::DrawPageTwo(wxDC *dc)
+{
+/* You might use THIS code to set the printer DC to ROUGHLY reflect
+ * the screen text size. This page also draws lines of actual length 5cm
+ * on the page.
+ */
+  // Get the logical pixels per inch of screen and printer
+  int ppiScreenX, ppiScreenY;
+  GetPPIScreen(&ppiScreenX, &ppiScreenY);
+  int ppiPrinterX, ppiPrinterY;
+  GetPPIPrinter(&ppiPrinterX, &ppiPrinterY);
+
+  // This scales the DC so that the printout roughly represents the
+  // the screen scaling. The text point size _should_ be the right size
+  // but in fact is too small for some reason. This is a detail that will
+  // need to be addressed at some point but can be fudged for the
+  // moment.
+  float scale = (float)((float)ppiPrinterX/(float)ppiScreenX);
+
+  // Now we have to check in case our real page size is reduced
+  // (e.g. because we're drawing to a print preview memory DC)
+  int pageWidth, pageHeight;
+  int w, h;
+  dc->GetSize(&w, &h);
+  GetPageSizePixels(&pageWidth, &pageHeight);
+
+  // If printer pageWidth == current DC width, then this doesn't
+  // change. But w might be the preview bitmap width, so scale down.
+  float overallScale = scale * (float)(w/(float)pageWidth);
+  dc->SetUserScale(overallScale, overallScale);
+  
+  // Calculate conversion factor for converting millimetres into
+  // logical units.
+  // There are approx. 25.1 mm to the inch. There are ppi
+  // device units to the inch. Therefore 1 mm corresponds to
+  // ppi/25.1 device units. We also divide by the
+  // screen-to-printer scaling factor, because we need to
+  // unscale to pass logical units to DrawLine.
+
+  // Draw 50 mm by 50 mm L shape
+  float logUnitsFactor = (float)(ppiPrinterX/(scale*25.1));
+  float logUnits = (float)(50*logUnitsFactor);
+  dc->SetPen(wxBLACK_PEN);
+  dc->DrawLine(50.0, 50.0, (float)(50.0 + logUnits), 50.0);
+  dc->DrawLine(50.0, 50.0, 50.0, (float)(50.0 + logUnits));
+
+  dc->SetFont(itemFont);
+  dc->SetBackgroundMode(wxTRANSPARENT);
+
+  dc->DrawText("Some test text", 200.0, 200.0);
+
+  // TESTING
+  
+  int leftMargin = 20;
+  int rightMargin = 20;
+  int topMargin = 20;
+  int bottomMargin = 20;
+
+  int pageWidthMM, pageHeightMM;
+  GetPageSizeMM(&pageWidthMM, &pageHeightMM);
+
+  float leftMarginLogical = (float)(logUnitsFactor*leftMargin);
+  float topMarginLogical = (float)(logUnitsFactor*topMargin);
+  float bottomMarginLogical = (float)(logUnitsFactor*(pageHeightMM - bottomMargin));
+  float rightMarginLogical = (float)(logUnitsFactor*(pageWidthMM - rightMargin));
+
+  dc->SetPen(wxBLACK_PEN);
+  dc->DrawLine(leftMarginLogical, topMarginLogical, rightMarginLogical, topMarginLogical);
+  dc->DrawLine(leftMarginLogical, bottomMarginLogical, rightMarginLogical, bottomMarginLogical);
+
+  WritePageHeader(this, dc, "A header", logUnitsFactor);
+}
+
+// Writes a header on a page. Margin units are in millimetres.
+bool WritePageHeader(wxPrintout *printout, wxDC *dc, char *text, float mmToLogical)
+{
+  static wxFont *headerFont = NULL;
+  if (!headerFont)
+  {
+    headerFont = wxTheFontList->FindOrCreateFont(16, wxSWISS, wxNORMAL, wxBOLD);
+  }
+  dc->SetFont(headerFont);
+
+  int pageWidthMM, pageHeightMM;
+  
+  printout->GetPageSizeMM(&pageWidthMM, &pageHeightMM);
+
+  int leftMargin = 10;
+  int topMargin = 10;
+  int rightMargin = 10;
+
+  float leftMarginLogical = (float)(mmToLogical*leftMargin);
+  float topMarginLogical = (float)(mmToLogical*topMargin);
+  float rightMarginLogical = (float)(mmToLogical*(pageWidthMM - rightMargin));
+
+  long xExtent, yExtent;
+  dc->GetTextExtent(text, &xExtent, &yExtent);
+  float xPos = (float)(((((pageWidthMM - leftMargin - rightMargin)/2.0)+leftMargin)*mmToLogical) - (xExtent/2.0));
+  dc->DrawText(text, (long)xPos, topMarginLogical);
+
+  dc->SetPen(wxBLACK_PEN);
+  dc->DrawLine(leftMarginLogical, topMarginLogical+yExtent, rightMarginLogical, topMarginLogical+yExtent);
+
+  return TRUE;
+}
diff --git a/samples/printing/printing.def b/samples/printing/printing.def
new file mode 100644
index 0000000000..e880656894
--- /dev/null
+++ b/samples/printing/printing.def
@@ -0,0 +1,9 @@
+NAME         Printing
+DESCRIPTION  'Printing'
+EXETYPE      WINDOWS
+STUB         'WINSTUB.EXE'
+CODE         PRELOAD MOVEABLE DISCARDABLE
+DATA         PRELOAD MOVEABLE MULTIPLE
+HEAPSIZE     1024
+STACKSIZE    16192
+
diff --git a/samples/printing/printing.h b/samples/printing/printing.h
new file mode 100644
index 0000000000..5c948a731f
--- /dev/null
+++ b/samples/printing/printing.h
@@ -0,0 +1,89 @@
+/*
+ * File:	printing.h
+ * Purpose:	Printing demo for wxWindows class library
+ * Author:	Julian Smart
+ * Created:	1995
+ * Updated:	
+ * Copyright:   (c) 1995, AIAI, University of Edinburgh
+ */
+
+/* sccsid[] = "%W% %G%" */
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+// Define a new application
+class MyApp: public wxApp
+{
+  public:
+    MyApp(void) ;
+    bool OnInit(void);
+};
+
+class MyCanvas;
+
+// Define a new canvas and frame
+class MyFrame: public wxFrame
+{
+  public:
+    MyCanvas *canvas;
+    MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size);
+
+    bool OnClose(void);
+
+    void Draw(wxDC& dc);
+
+    void OnSize(wxSizeEvent& event);
+    void OnPrint(wxCommandEvent& event);
+    void OnPrintPreview(wxCommandEvent& event);
+    void OnPrintSetup(wxCommandEvent& event);
+    void OnPageSetup(wxCommandEvent& event);
+    void OnPrintPS(wxCommandEvent& event);
+    void OnPrintPreviewPS(wxCommandEvent& event);
+    void OnPrintSetupPS(wxCommandEvent& event);
+    void OnPageSetupPS(wxCommandEvent& event);
+    void OnExit(wxCommandEvent& event);
+    void OnPrintAbout(wxCommandEvent& event);
+DECLARE_EVENT_TABLE()
+};
+
+// Define a new canvas which can receive some events
+class MyCanvas: public wxScrolledWindow
+{
+  public:
+    MyCanvas(wxFrame *frame, const wxPoint& pos, const wxSize& size, long style = wxRETAINED);
+    ~MyCanvas(void) ;
+
+    virtual void OnDraw(wxDC& dc);
+    void OnEvent(wxMouseEvent& event);
+
+DECLARE_EVENT_TABLE()
+};
+
+class MyPrintout: public wxPrintout
+{
+ public:
+  MyPrintout(char *title = "My printout"):wxPrintout(title) {}
+  bool OnPrintPage(int page);
+  bool HasPage(int page);
+  bool OnBeginDocument(int startPage, int endPage);
+  void GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo);
+
+  void DrawPageOne(wxDC *dc);
+  void DrawPageTwo(wxDC *dc);
+};
+
+#define WXPRINT_QUIT            100
+#define WXPRINT_PRINT           101
+#define WXPRINT_PRINT_SETUP     102
+#define WXPRINT_PAGE_SETUP      103
+#define WXPRINT_PREVIEW         104
+
+#define WXPRINT_PRINT_PS        105
+#define WXPRINT_PRINT_SETUP_PS  106
+#define WXPRINT_PAGE_SETUP_PS   107
+#define WXPRINT_PREVIEW_PS      108
+
+#define WXPRINT_ABOUT           109
+
diff --git a/samples/printing/printing.rc b/samples/printing/printing.rc
new file mode 100644
index 0000000000..233da61284
--- /dev/null
+++ b/samples/printing/printing.rc
@@ -0,0 +1,3 @@
+aiai_icn ICON "aiai.ico"
+#include "wx/msw/wx.rc"
+
diff --git a/samples/splitter/Makefile b/samples/splitter/Makefile
new file mode 100644
index 0000000000..027d82ae19
--- /dev/null
+++ b/samples/splitter/Makefile
@@ -0,0 +1 @@
+include ../../src/gtk/setup/general/makeapp
diff --git a/samples/splitter/Makefile.in b/samples/splitter/Makefile.in
new file mode 100644
index 0000000000..fd1b9963fa
--- /dev/null
+++ b/samples/splitter/Makefile.in
@@ -0,0 +1,26 @@
+# WXXT base directory
+WXBASEDIR=@WXBASEDIR@
+
+# set the OS type for compilation
+OS=@OS@
+# compile a library only
+RULE=bin
+
+# define library name
+BIN_TARGET=test
+# define library sources
+BIN_SRC=\
+test.cpp
+
+#define library objects
+BIN_OBJ=\
+test.o
+
+# additional things needed to link
+BIN_LINK=
+
+# additional things needed to compile
+ADD_COMPILE=
+
+# include the definitions now
+include ../../../template.mak
diff --git a/samples/splitter/aiai.xbm b/samples/splitter/aiai.xbm
new file mode 100644
index 0000000000..1a6f0a31b1
--- /dev/null
+++ b/samples/splitter/aiai.xbm
@@ -0,0 +1,38 @@
+#define aiai_width 64
+#define aiai_height 64
+static char aiai_bits[] = {
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x44,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x44,0x44,0x44,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x44,0x44,0x44,0x42,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x47,0x44,0x44,0x44,0x44,0x11,0x11,0x11,0x17,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x91,0x1f,0x11,0x11,0x11,0x11,0x44,0x44,0xc4,0x4f,0x44,0x44,0x44,0x44,
+ 0x44,0x44,0xc4,0x5f,0x44,0xf4,0x45,0x44,0x11,0x11,0xf1,0x1f,0x11,0xf9,0x13,
+ 0x11,0x11,0x11,0xf1,0x3f,0x11,0xfd,0x13,0x11,0x44,0x44,0xf4,0x7f,0x44,0xfc,
+ 0x47,0x44,0x44,0x44,0xf4,0x7f,0x44,0xfc,0x47,0x44,0x11,0x11,0xf9,0x7f,0x11,
+ 0xf9,0x13,0x11,0x11,0x11,0xfd,0xff,0x11,0xf1,0x11,0x11,0x44,0x44,0xfc,0xff,
+ 0x44,0x44,0x44,0x44,0x44,0x44,0xfe,0xff,0x45,0x44,0x44,0x44,0x11,0x11,0xff,
+ 0xff,0x11,0xfd,0x13,0x11,0x11,0x11,0xff,0xff,0x13,0xfd,0x13,0x11,0x44,0xc4,
+ 0xff,0xff,0x07,0xfc,0x43,0x44,0x44,0xff,0xff,0xf9,0xff,0xfd,0xfb,0xff,0x11,
+ 0xc0,0xff,0x00,0x00,0xfc,0x03,0x00,0x11,0xc0,0x7f,0x00,0x00,0xfc,0x03,0x00,
+ 0x04,0xe0,0x7f,0x00,0x00,0xfc,0x03,0x00,0xf4,0xf7,0xbf,0xff,0xff,0xfd,0xfb,
+ 0x7f,0x01,0xf0,0x1f,0x00,0x00,0xfc,0x03,0x00,0x01,0xf8,0x1f,0x00,0x00,0xfc,
+ 0x03,0x00,0x00,0xfc,0x0f,0x00,0x00,0xfc,0x03,0x40,0xfe,0xfd,0xef,0xff,0xff,
+ 0xfd,0xfb,0x4f,0x00,0xfe,0x07,0x00,0x00,0xfc,0x03,0x10,0x00,0xfe,0x03,0x00,
+ 0x00,0xfc,0x03,0x10,0x00,0xff,0x03,0x00,0x00,0xfc,0x03,0x44,0x7f,0xff,0x01,
+ 0x00,0x00,0xfc,0xfb,0x44,0x91,0xff,0xff,0xff,0xff,0xff,0x13,0x11,0xd1,0xff,
+ 0xff,0xff,0xff,0xff,0x13,0x11,0xe4,0xff,0xff,0xff,0xff,0xff,0x47,0x44,0xe4,
+ 0xff,0xff,0xff,0xff,0xff,0x47,0x44,0xf1,0xff,0xff,0xff,0xff,0xff,0x13,0x11,
+ 0xf1,0xff,0xff,0xff,0xff,0xff,0x13,0x11,0xfc,0xff,0xff,0xff,0xff,0xff,0x47,
+ 0x44,0xfc,0xff,0xff,0xff,0xff,0xff,0x47,0x44,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x11,0x44,0x44,0xc4,0x44,0x44,
+ 0xc4,0x44,0x44,0x44,0x4e,0xc4,0x44,0x4e,0xc4,0x44,0x44,0x11,0x1f,0xd1,0x11,
+ 0x1f,0xd1,0x11,0x11,0x91,0x31,0xd1,0x91,0x31,0xd1,0x11,0x11,0xc4,0x64,0xcc,
+ 0xcc,0x64,0xcc,0x44,0x44,0x64,0xc4,0xcc,0x6c,0xc4,0xcc,0x44,0x44,0xf1,0xff,
+ 0xd1,0xf1,0xff,0xd1,0x11,0x11,0xf9,0xff,0xd3,0xf9,0xff,0xd3,0x11,0x11,0x4c,
+ 0x44,0xc6,0x4c,0x44,0xc6,0x44,0x44,0x4c,0x44,0xc6,0x4c,0x44,0xc6,0x44,0x44,
+ 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+ 0x11,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
+ 0x44,0x44};
diff --git a/samples/splitter/makefile.b32 b/samples/splitter/makefile.b32
new file mode 100644
index 0000000000..9fd8e32307
--- /dev/null
+++ b/samples/splitter/makefile.b32
@@ -0,0 +1,64 @@
+#
+# File:		makefile.bcc
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds splitter example (DOS).
+
+# WXWIN and BCCDIR are set by parent make
+
+WXDIR = $(WXWIN)
+!include $(WXDIR)\src\makeb32.env
+
+WXLIBDIR = $(WXDIR)\lib
+WXINC = $(WXDIR)\include\msw
+WXLIB = $(WXLIBDIR)\wx32.lib
+LIBS=$(WXLIB) cw32 import32
+
+TARGET=test
+
+!if "$(FINAL)" == "0"
+LINKFLAGS=/v /Tpe /L$(WXLIBDIR);$(BCCDIR)\lib
+OPT = -Od
+DEBUG_FLAGS= -v
+!else
+LINKFLAGS=/Tpe /L$(WXLIBDIR);$(BCCDIR)\lib
+OPT = -Od
+DEBUG_FLAGS =
+!endif
+CPPFLAGS=$(DEBUG_FLAGS) $(OPT) @$(CFG)
+
+OBJECTS = test.obj
+
+$(TARGET).exe:	$(OBJECTS) $(TARGET).def $(TARGET).res
+  tlink32 $(LINKFLAGS) @&&!
+c0w32.obj $(OBJECTS)
+$(TARGET)
+nul
+$(LIBS)
+$(TARGET).def
+!
+        brc32 -K $(TARGET).res
+
+.$(SRCSUFF).obj:
+	bcc32 $(CPPFLAGS) -c {$< }
+
+.c.obj:
+	bcc32 $(CPPFLAGS) -P- -c {$< }
+
+test.obj:      test.$(SRCSUFF)
+
+$(TARGET).res :      $(TARGET).rc $(WXDIR)\include\wx\msw\wx.rc
+    brc32 -r /i$(BCCDIR)\include /i$(WXDIR)\include $(TARGET)
+
+clean:
+        -erase *.obj
+        -erase *.exe
+        -erase *.res
+        -erase *.map
+        -erase *.rws
+
diff --git a/samples/splitter/makefile.g95 b/samples/splitter/makefile.g95
new file mode 100644
index 0000000000..2ae60d6fc2
--- /dev/null
+++ b/samples/splitter/makefile.g95
@@ -0,0 +1,37 @@
+#
+# File:		makefile.unx
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile for splitter example (UNIX).
+
+WXDIR = ../..
+
+# All common UNIX compiler flags and options are now in
+# this central makefile.
+include $(WXDIR)/src/makeg95.env
+
+OBJECTS = $(OBJDIR)/test.$(OBJSUFF)
+
+all:    $(OBJDIR) test$(GUISUFFIX)$(EXESUFF)
+
+wx:
+
+$(OBJDIR):
+	mkdir $(OBJDIR)
+
+test$(GUISUFFIX)$(EXESUFF):	$(OBJDIR)/test.$(OBJSUFF) test.res $(WXLIB)
+	$(CC) $(LDFLAGS) -o test$(GUISUFFIX)$(EXESUFF) $(OBJDIR)/test.$(OBJSUFF) $(XVIEW_LINK) $(LDLIBS)
+	$(RSRC) test.$(RESSUFF) test.exe
+
+$(OBJDIR)/test.$(OBJSUFF):	test.$(SRCSUFF)
+	$(CC) -c $(CPPFLAGS) -o $@ test.$(SRCSUFF)
+
+test.res:  test.rc
+
+clean:
+	rm -f $(OBJECTS) test$(GUISUFFIX).exe core *.rsc *.res
diff --git a/samples/splitter/makefile.nt b/samples/splitter/makefile.nt
new file mode 100644
index 0000000000..2f0685d4c8
--- /dev/null
+++ b/samples/splitter/makefile.nt
@@ -0,0 +1,63 @@
+#
+# File:		makefile.nt
+# Author:	Julian Smart
+# Created:	1997
+# Updated:	
+# Copyright:	(c) 1997, Julian Smart
+#
+# "%W% %G%"
+#
+# Makefile : Builds wxSplitterWindow sample MS VC++).
+# Use FINAL=1 argument to nmake to build final version with no debugging
+# info
+
+# Set WXDIR for your system
+WXDIR = $(WXWIN)
+WXSPLITDIR = $(WXDIR)\samples\splitter
+THISDIR = $(WXDIR)\samples\splitter
+
+!include $(WXDIR)\src\ntwxwin.mak
+
+PROGRAM=test
+ 
+PROGOBJECTS = $(PROGRAM).obj
+
+all:    $(PROGRAM)
+
+$(PROGRAM):    $(PROGRAM).exe
+
+wx:
+        cd $(WXDIR)\src\msw
+        nmake -f makefile.nt FINAL=$(FINAL)
+        cd $(THISDIR)
+
+wxclean:
+        cd $(WXDIR)\src\msw
+        nmake -f makefile.nt clean
+        cd $(THISDIR)
+
+$(PROGRAM).exe:      $(DUMMYOBJ) $(WXLIB) $(PROGOBJECTS) $(PROGRAM).res
+	$(link) @<<
+-out:$(PROGRAM).exe
+$(LINKFLAGS)
+$(DUMMYOBJ) $(PROGOBJECTS) $(PROGRAM).res
+$(LIBS)
+<<
+
+$(PROGRAM).obj:      $(PROGRAM).$(SRCSUFF) $(DUMMYOBJ)
+        $(cc) @<<
+$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
+<<
+
+$(PROGRAM).res :      $(PROGRAM).rc $(WXDIR)\include\wx\msw\wx.rc
+    $(rc) -r /i$(WXDIR)\include -fo$@ $(PROGRAM).rc
+
+
+clean:
+        -erase *.obj
+        -erase *.sbr
+        -erase *.exe
+        -erase *.res
+        -erase *.map
+        -erase *.pdb
+
diff --git a/samples/splitter/mondrian.ico b/samples/splitter/mondrian.ico
new file mode 100644
index 0000000000000000000000000000000000000000..2310c5d275a87af295d5ea8dc79ea417a5e74c53
GIT binary patch
literal 766
zcmZQzU<5)11px*Sc)`TLAO@s0fLH;D9e|jTfdxnc0Z<M**w4TKL=5})Lnt5#WHKB$
zaDbtqp#doIAB-6O{|B*v7zjZ^AOa2W|NsACHyAJ}De?dRKnp(HN~rljcR;{k;{zQE
i@;}UZ|9Q?Fpp*~yJCwmWbLIrN`9Qm9%}2L?p!oo$cZ4ed

literal 0
HcmV?d00001

diff --git a/samples/splitter/test.cpp b/samples/splitter/test.cpp
new file mode 100644
index 0000000000..8a81d60bef
--- /dev/null
+++ b/samples/splitter/test.cpp
@@ -0,0 +1,230 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        splitter.cpp
+// Purpose:     wxSplitterWindow sample
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+// For compilers that support precompilation, includes "wx/wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include "wx/splitter.h"
+
+class MyApp;
+class MyFrame;
+class MyCanvas;
+
+class MyApp: public wxApp
+{
+public:
+	bool OnInit();
+};
+
+class MyFrame: public wxFrame
+{
+public:
+	MyFrame(wxFrame* frame, const wxString& title, const wxPoint& pos, const wxSize& size);
+	virtual ~MyFrame();
+
+	bool OnClose();
+
+	// Menu commands
+	void SplitHorizontal(wxCommandEvent& event);
+	void SplitVertical(wxCommandEvent& event);
+	void Unsplit(wxCommandEvent& event);
+	void Quit(wxCommandEvent& event);
+
+	// Menu command update functions
+	void UpdateUIHorizontal(wxUpdateUIEvent& event);
+	void UpdateUIVertical(wxUpdateUIEvent& event);
+	void UpdateUIUnsplit(wxUpdateUIEvent& event);
+
+    void OnIdle(wxIdleEvent& event);
+
+private:
+	wxMenu*		fileMenu;
+	wxMenuBar*	menuBar;
+	MyCanvas*	leftCanvas;
+	MyCanvas*	rightCanvas;
+    wxSplitterWindow* splitter;
+
+DECLARE_EVENT_TABLE()
+};
+
+class MyCanvas: public wxScrolledWindow
+{
+public:
+	MyCanvas(wxWindow* parent, int x, int y, int w, int h);
+	virtual ~MyCanvas();
+
+	virtual void OnDraw(wxDC& dc);
+
+DECLARE_EVENT_TABLE()
+};
+
+BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
+END_EVENT_TABLE()
+
+// ID for the menu quit command
+#define SPLIT_QUIT          1
+#define SPLIT_HORIZONTAL    2
+#define SPLIT_VERTICAL      3
+#define SPLIT_UNSPLIT       4
+
+IMPLEMENT_APP(MyApp)
+
+bool MyApp::OnInit(void)
+{
+	MyFrame* frame = new MyFrame(NULL, "wxSplitterWindow Example", wxPoint(50, 50), wxSize(400, 300));
+
+	// Show the frame
+	frame->Show(TRUE);
+  
+	SetTopWindow(frame);
+
+	return TRUE;
+}
+
+BEGIN_EVENT_TABLE(MyFrame, wxFrame)
+	EVT_MENU(SPLIT_VERTICAL, MyFrame::SplitVertical)
+	EVT_MENU(SPLIT_HORIZONTAL, MyFrame::SplitHorizontal)
+	EVT_MENU(SPLIT_UNSPLIT, MyFrame::Unsplit)
+	EVT_MENU(SPLIT_QUIT, MyFrame::Quit)
+	EVT_UPDATE_UI(SPLIT_VERTICAL, MyFrame::UpdateUIVertical)
+	EVT_UPDATE_UI(SPLIT_HORIZONTAL, MyFrame::UpdateUIHorizontal)
+	EVT_UPDATE_UI(SPLIT_UNSPLIT, MyFrame::UpdateUIUnsplit)
+	EVT_IDLE(MyFrame::OnIdle)
+END_EVENT_TABLE()
+
+// My frame constructor
+MyFrame::MyFrame(wxFrame* frame, const wxString& title, const wxPoint& pos, const wxSize& size):
+	wxFrame(frame, -1, title, pos, size)
+{
+	// set the icon
+#ifdef __WINDOWS__
+	SetIcon(wxIcon("mondrian"));
+#endif
+#ifdef __X__
+	SetIcon(wxIcon("aiai.xbm"));
+#endif
+
+	// Make a menubar
+	fileMenu = new wxMenu;
+	fileMenu->Append(SPLIT_VERTICAL, "Split &Vertically", "Split vertically");
+	fileMenu->Append(SPLIT_HORIZONTAL, "Split &Horizontally", "Split horizontally");
+	fileMenu->Append(SPLIT_UNSPLIT, "&Unsplit", "Unsplit");
+	fileMenu->Append(SPLIT_QUIT, "E&xit", "Exit");
+
+	menuBar = new wxMenuBar;
+	menuBar->Append(fileMenu, "&File");
+
+	SetMenuBar(menuBar);
+
+    splitter = new wxSplitterWindow(this, -1, wxPoint(0, 0), wxSize(400, 400),
+//            wxSP_BORDER);
+            wxSP_3D);
+//            wxSP_NOBORDER);
+
+	leftCanvas = new MyCanvas(splitter, 0, 0, 400, 400);
+    leftCanvas->SetBackgroundColour(*wxRED);
+    leftCanvas->SetScrollbars(20, 20, 50, 50);
+
+	rightCanvas = new MyCanvas(splitter, 0, 0, 400, 400);
+    rightCanvas->SetBackgroundColour(*wxCYAN);
+    rightCanvas->SetScrollbars(20, 20, 50, 50);
+    rightCanvas->Show(FALSE);
+
+    splitter->Initialize(leftCanvas);
+
+    // Set this to prevent unsplitting
+//    splitter->SetMinimumPaneSize(20);
+    CreateStatusBar();
+}
+
+MyFrame::~MyFrame()
+{
+}
+
+bool MyFrame::OnClose()
+{
+	return TRUE;
+}
+
+void MyFrame::Quit(wxCommandEvent& event)
+{
+	Close(TRUE);
+}
+
+void MyFrame::SplitHorizontal(wxCommandEvent& event)
+{
+    if ( splitter->IsSplit() )
+        splitter->Unsplit();
+    leftCanvas->Show(TRUE);
+    rightCanvas->Show(TRUE);
+    splitter->SplitHorizontally( leftCanvas, rightCanvas );
+}
+
+void MyFrame::SplitVertical(wxCommandEvent& event)
+{
+    if ( splitter->IsSplit() )
+        splitter->Unsplit();
+    leftCanvas->Show(TRUE);
+    rightCanvas->Show(TRUE);
+    splitter->SplitVertically( leftCanvas, rightCanvas );
+}
+
+void MyFrame::Unsplit(wxCommandEvent& event)
+{
+    if ( splitter->IsSplit() )
+        splitter->Unsplit();
+}
+
+void MyFrame::UpdateUIHorizontal(wxUpdateUIEvent& event)
+{
+	event.Enable( ( (!splitter->IsSplit()) || (splitter->GetSplitMode() != wxSPLIT_HORIZONTAL) ) );
+}
+
+void MyFrame::UpdateUIVertical(wxUpdateUIEvent& event)
+{
+	event.Enable( ( (!splitter->IsSplit()) || (splitter->GetSplitMode() != wxSPLIT_VERTICAL) ) );
+}
+
+void MyFrame::UpdateUIUnsplit(wxUpdateUIEvent& event)
+{
+	event.Enable( splitter->IsSplit() );
+}
+
+void MyFrame::OnIdle(wxIdleEvent& event)
+{
+    if ( GetStatusBar()->GetStatusText(0) != "Ready" )
+        SetStatusText("Ready");
+}
+
+MyCanvas::MyCanvas(wxWindow* parent, int x, int y, int w, int h) :
+	wxScrolledWindow(parent, -1, wxPoint(x, y), wxSize(w, h))
+{
+}
+
+MyCanvas::~MyCanvas()
+{
+}
+
+void MyCanvas::OnDraw(wxDC& dc)
+{
+	dc.DrawLine(0, 0, 100, 100);
+
+    dc.SetBackgroundMode(wxTRANSPARENT);
+	dc.DrawText("Testing", 50, 50);
+}
diff --git a/samples/splitter/test.def b/samples/splitter/test.def
new file mode 100644
index 0000000000..3dd3b7a033
--- /dev/null
+++ b/samples/splitter/test.def
@@ -0,0 +1,8 @@
+NAME         Test
+DESCRIPTION  'wxTableWindow Test'
+EXETYPE      WINDOWS
+STUB         'WINSTUB.EXE'
+CODE         PRELOAD MOVEABLE DISCARDABLE
+DATA         PRELOAD MOVEABLE MULTIPLE
+HEAPSIZE     1024
+STACKSIZE    16192
diff --git a/samples/splitter/test.rc b/samples/splitter/test.rc
new file mode 100644
index 0000000000..dde0d5ae7f
--- /dev/null
+++ b/samples/splitter/test.rc
@@ -0,0 +1,4 @@
+mondrian ICON "mondrian.ico"
+
+#include "wx/msw/wx.rc"
+
diff --git a/samples/tab/Makefile b/samples/tab/Makefile
new file mode 100644
index 0000000000..027d82ae19
--- /dev/null
+++ b/samples/tab/Makefile
@@ -0,0 +1 @@
+include ../../src/gtk/setup/general/makeapp
diff --git a/samples/tab/Makefile.in b/samples/tab/Makefile.in
new file mode 100644
index 0000000000..fd1b9963fa
--- /dev/null
+++ b/samples/tab/Makefile.in
@@ -0,0 +1,26 @@
+# WXXT base directory
+WXBASEDIR=@WXBASEDIR@
+
+# set the OS type for compilation
+OS=@OS@
+# compile a library only
+RULE=bin
+
+# define library name
+BIN_TARGET=test
+# define library sources
+BIN_SRC=\
+test.cpp
+
+#define library objects
+BIN_OBJ=\
+test.o
+
+# additional things needed to link
+BIN_LINK=
+
+# additional things needed to compile
+ADD_COMPILE=
+
+# include the definitions now
+include ../../../template.mak
diff --git a/samples/tab/makefile.b32 b/samples/tab/makefile.b32
new file mode 100644
index 0000000000..ea1478ac72
--- /dev/null
+++ b/samples/tab/makefile.b32
@@ -0,0 +1,64 @@
+#
+# File:		makefile.bcc
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds tab example
+
+# WXWIN and BCCDIR are set by parent make
+
+WXDIR = $(WXWIN)
+!include $(WXDIR)\src\makeb32.env
+
+WXLIBDIR = $(WXDIR)\lib
+WXINC = $(WXDIR)\include\msw
+WXLIB = $(WXLIBDIR)\wx32.lib
+LIBS=$(WXLIB) cw32 import32 ole2w32
+
+TARGET=test
+
+!if "$(FINAL)" == "0"
+LINKFLAGS=/v /Tpe /L$(WXLIBDIR);$(BCCDIR)\lib
+OPT = -Od
+DEBUG_FLAGS= -v
+!else
+LINKFLAGS=/Tpe /L$(WXLIBDIR);$(BCCDIR)\lib
+OPT = -Od
+DEBUG_FLAGS =
+!endif
+CPPFLAGS=$(DEBUG_FLAGS) $(OPT) @$(CFG)
+
+OBJECTS = test.obj
+
+$(TARGET).exe:	$(OBJECTS) $(TARGET).def $(TARGET).res
+  tlink32 $(LINKFLAGS) @&&!
+c0w32.obj $(OBJECTS)
+$(TARGET)
+nul
+$(LIBS)
+$(TARGET).def
+!
+        brc32 -K $(TARGET).res
+
+.$(SRCSUFF).obj:
+	bcc32 $(CPPFLAGS) -c {$< }
+
+.c.obj:
+	bcc32 $(CPPFLAGS) -P- -c {$< }
+
+test.obj:      test.$(SRCSUFF)
+
+$(TARGET).res :      $(TARGET).rc $(WXDIR)\include\wx\msw\wx.rc
+    brc32 -r /i$(BCCDIR)\include /i$(WXDIR)\include $(TARGET)
+
+clean:
+        -erase *.obj
+        -erase *.exe
+        -erase *.res
+        -erase *.map
+        -erase *.rws
+
diff --git a/samples/tab/makefile.bcc b/samples/tab/makefile.bcc
new file mode 100644
index 0000000000..b68a9b6d21
--- /dev/null
+++ b/samples/tab/makefile.bcc
@@ -0,0 +1,73 @@
+#
+# File:		makefile.bcc
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds minimal example (DOS).
+
+!if "$(BCCDIR)" == ""
+!error You must define the BCCDIR variable in autoexec.bat, e.g. BCCDIR=d:\bc4
+!endif
+
+!if "$(WXWIN)" == ""
+!error You must define the WXWIN variable in autoexec.bat, e.g. WXWIN=c:\wx
+!endif
+
+WXDIR = $(WXWIN)
+!include $(WXDIR)\src\makebcc.env
+
+THISDIR = $(WXDIR)\samples\minimal
+WXLIB = $(WXDIR)\lib\wx.lib
+LIBS=$(WXLIB) mathwl cwl import
+INC=-I$(WXDIR)\include\base -I$(WXDIR)\include\msw
+CFG=$(WXDIR)\src\wxwin.cfg
+
+!ifndef FINAL
+FINAL=0
+!endif
+
+!if "$(FINAL)" == "0"
+LINKFLAGS=/v/Vt /Twe /L$(WXDIR)\lib;$(BCCDIR)\lib
+OPT = -Od
+DEBUG_FLAGS= -v
+!else
+LINKFLAGS=/Twe /L$(WXDIR)\lib;$(BCCDIR)\lib
+OPT = -O2
+DEBUG_FLAGS=
+!endif
+CPPFLAGS=$(DEBUG_FLAGS) $(OPT) @$(CFG)
+
+OBJECTS = minimal.obj
+
+minimal:    minimal.exe
+
+all:    minimal.exe
+
+minimal.exe:    $(WXLIB) minimal.obj minimal.def minimal.res
+        tlink $(LINKFLAGS) @&&!
+c0wl.obj minimal.obj
+minimal
+nul
+$(LIBS)
+minimal.def
+!
+        rc -31 -K minimal.res
+
+.$(SRCSUFF).obj:
+	bcc $(CPPFLAGS) -c {$< }
+
+minimal.obj:      minimal.$(SRCSUFF)
+
+minimal.res :      minimal.rc $(WXDIR)\include\msw\wx.rc
+    rc -r /i$(BCCDIR)\include /i$(WXDIR)\include\msw /i$(WXDIR)\contrib\fafa minimal
+
+clean:
+        -erase *.obj
+        -erase *.exe
+        -erase *.res
+        -erase *.map
+        -erase *.rws
diff --git a/samples/tab/makefile.dos b/samples/tab/makefile.dos
new file mode 100644
index 0000000000..032e661e15
--- /dev/null
+++ b/samples/tab/makefile.dos
@@ -0,0 +1,65 @@
+#
+# File:		makefile.dos
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds tab example (DOS).
+# Use FINAL=1 argument to nmake to build final version with no debugging
+# info
+
+WXDIR = $(WXWIN)
+
+!include $(WXDIR)\src\makemsc.env
+
+THISDIR = $(WXDIR)\samples\tab
+
+!ifndef FINAL
+FINAL=0
+!endif
+
+HEADERS =
+SOURCES = test.$(SRCSUFF)
+OBJECTS = test.obj
+
+all:    test.exe
+
+wx:
+        cd $(WXDIR)\src\msw
+        nmake -f makefile.dos FINAL=$(FINAL)
+        cd $(THISDIR)
+
+wxclean:
+        cd $(WXDIR)\src\msw
+        nmake -f makefile.dos clean
+        cd $(THISDIR)
+
+test.exe:      $(WXDIR)\src\msw\dummy.obj $(WXLIB) test.obj test.def test.res
+        link $(LINKFLAGS) @<<
+test.obj $(WXDIR)\src\msw\dummy.obj,
+test,
+NUL,
+$(LIBS),
+test.def
+;
+<<
+        rc -K test.res
+
+test.obj:      test.$(SRCSUFF)
+        cl @<<
+$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
+<<
+
+test.res :      test.rc $(WXDIR)\include\wx\msw\wx.rc
+    rc -r /i$(WXDIR)\include test
+
+clean:
+        -erase *.obj
+        -erase *.exe
+        -erase *.res
+        -erase *.map
+        -erase *.sbr
+        -erase *.pdb
diff --git a/samples/tab/makefile.g95 b/samples/tab/makefile.g95
new file mode 100644
index 0000000000..75576c053a
--- /dev/null
+++ b/samples/tab/makefile.g95
@@ -0,0 +1,37 @@
+#
+# File:		makefile.unx
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile for tab example
+
+WXDIR = ../..
+
+# All common UNIX compiler flags and options are now in
+# this central makefile.
+include $(WXDIR)/src/makeg95.env
+
+OBJECTS = $(OBJDIR)/test.$(OBJSUFF) $(OBJDIR)/test_resources.$(OBJSUFF)
+
+all:    $(OBJDIR) test$(GUISUFFIX)$(EXESUFF)
+
+wx:
+
+$(OBJDIR):
+	mkdir $(OBJDIR)
+
+test$(GUISUFFIX)$(EXESUFF):	$(OBJECTS) $(WXLIB)
+	$(CC) $(LDFLAGS) -o test$(GUISUFFIX)$(EXESUFF) $(OBJECTS) $(LDLIBS)
+
+$(OBJDIR)/test.$(OBJSUFF):	test.$(SRCSUFF)
+	$(CC) -c $(CPPFLAGS) -o $@ test.$(SRCSUFF)
+
+$(OBJDIR)/test_resources.o:  test.rc
+	$(RESCOMP) -i test.rc -o $(OBJDIR)/test_resources.o $(RESFLAGS)
+
+clean:
+	rm -f $(OBJECTS) test$(GUISUFFIX).exe core *.rsc *.res
diff --git a/samples/tab/makefile.nt b/samples/tab/makefile.nt
new file mode 100644
index 0000000000..fa9f825902
--- /dev/null
+++ b/samples/tab/makefile.nt
@@ -0,0 +1,64 @@
+#
+# File:		makefile.nt
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds tab example (MS VC++).
+# Use FINAL=1 argument to nmake to build final version with no debugging
+# info
+
+# Set WXDIR for your system
+WXDIR = $(WXWIN)
+
+WXUSINGDLL=0
+
+!include $(WXDIR)\src\ntwxwin.mak
+
+THISDIR = $(WXDIR)\samples\tab
+PROGRAM=test
+
+OBJECTS = $(PROGRAM).obj
+
+$(PROGRAM):    $(PROGRAM).exe
+
+all:    wx $(PROGRAM).exe
+
+wx:
+        cd $(WXDIR)\src\msw
+        nmake -f makefile.nt FINAL=$(FINAL)
+        cd $(THISDIR)
+
+wxclean:
+        cd $(WXDIR)\src\msw
+        nmake -f makefile.nt clean
+        cd $(THISDIR)
+
+$(PROGRAM).exe:      $(DUMMYOBJ) $(WXLIB) $(OBJECTS) $(PROGRAM).res
+	$(link) @<<
+-out:$(PROGRAM).exe
+$(LINKFLAGS)
+$(DUMMYOBJ) $(OBJECTS) $(PROGRAM).res
+$(LIBS)
+<<
+
+
+$(PROGRAM).obj:      $(PROGRAM).$(SRCSUFF) $(DUMMYOBJ)
+        $(cc) @<<
+$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
+<<
+
+$(PROGRAM).res :      $(PROGRAM).rc $(WXDIR)\include\wx\msw\wx.rc
+    $(rc) -r /i$(WXDIR)\include -fo$@ $(PROGRAM).rc
+
+
+clean:
+        -erase *.obj
+        -erase *.exe
+        -erase *.res
+        -erase *.map
+        -erase *.sbr
+        -erase *.pdb
diff --git a/samples/tab/makefile.sc b/samples/tab/makefile.sc
new file mode 100644
index 0000000000..8709d2ca0f
--- /dev/null
+++ b/samples/tab/makefile.sc
@@ -0,0 +1,35 @@
+# Symantec C++ makefile for minimal example
+# NOTE that peripheral libraries are now dealt in main wxWindows makefile.
+
+WXDIR = $(WXWIN)
+!include $(WXDIR)\src\makesc.env
+
+WXLIB = $(WXDIR)\lib\wx.lib
+INCDIR = $(WXDIR)\include
+MSWINC = $(INCDIR)\msw
+BASEINC = $(INCDIR)\base
+
+CC=sc
+RC=rc
+CFLAGS = -o -ml -W -Dwx_msw
+LDFLAGS = -ml -W
+
+INCLUDE=$(BASEINC);$(MSWINC)
+
+LIBS=$(WXLIB) libw.lib commdlg.lib shell.lib
+
+.$(SRCSUFF).obj:
+	*$(CC) -c $(CFLAGS) -I$(INCLUDE) $<
+
+.rc.res:
+	*$(RC) -r -I$(INCLUDE) $<
+
+minimal.exe: minimal.obj minimal.def minimal.res
+	*$(CC) $(LDFLAGS) -o$@ $** $(LIBS)
+
+clean:
+        -del *.obj
+	-del *.exe
+	-del *.res
+	-del *.map
+	-del *.rws
diff --git a/samples/tab/makefile.unx b/samples/tab/makefile.unx
new file mode 100644
index 0000000000..9685d06789
--- /dev/null
+++ b/samples/tab/makefile.unx
@@ -0,0 +1,58 @@
+#
+# File:		makefile.unx
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile for minimal example (UNIX).
+
+WXDIR = ../..
+
+# All common UNIX compiler flags and options are now in
+# this central makefile.
+include $(WXDIR)/src/make.env
+
+OBJECTS = $(OBJDIR)/minimal.$(OBJSUFF)
+
+.SUFFIXES:
+
+all:    $(OBJDIR) minimal$(GUISUFFIX)
+
+wx:
+
+
+motif:
+	$(MAKE) -f makefile.unx GUISUFFIX=_motif GUI=-Dwx_motif GUISUFFIX=_motif OPT='$(OPT)' LDLIBS='$(MOTIFLDLIBS)' WXLIB=$(WXDIR)/lib/libwx_motif.a  OPTIONS='$(OPTIONS)' DEBUG='$(DEBUG)' WARN='$(WARN)' XLIB='$(XLIB)' XINCLUDE='$(XINCLUDE)' XVIEW_LINK=
+
+xview:
+	cd $(WXDIR)/src/x; $(MAKE) -f makefile.unx xview
+	$(MAKE) -f makefile.unx GUI=-Dwx_xview GUISUFFIX=_ol CC=$(CC) OPTIONS='$(OPTIONS)' DEBUG='$(DEBUG)' WARN='$(WARN)' XLIB='$(XLIB)' XINCLUDE='$(XINCLUDE)'
+
+hp:
+	cd $(WXDIR)/src/x; $(MAKE) -f makefile.unx hp
+	$(MAKE) -f makefile.unx GUI=-Dwx_motif GUISUFFIX=_hp CC=CC DEBUG='$(DEBUG)' WARN='-w' \
+         XINCLUDE='$(HPXINCLUDE)' XLIB='$(HPXLIB)' XVIEW_LINK='' LDLIBS='$(HPLDLIBS)'
+
+$(OBJDIR):
+	mkdir $(OBJDIR)
+
+minimal$(GUISUFFIX):	$(OBJDIR)/minimal.$(OBJSUFF) $(WXLIB)
+	$(CC) $(LDFLAGS) -o minimal$(GUISUFFIX) $(OBJDIR)/minimal.$(OBJSUFF) $(XVIEW_LINK) $(LDLIBS)
+
+$(OBJDIR)/minimal.$(OBJSUFF):	minimal.$(SRCSUFF)
+	$(CC) -c $(CPPFLAGS) -o $@ minimal.$(SRCSUFF)
+
+clean_motif:
+	$(MAKE) -f makefile.unx GUISUFFIX=_motif cleanany
+
+clean_ol:
+	$(MAKE) -f makefile.unx GUISUFFIX=_ol cleanany
+
+clean_hp:
+	$(MAKE) -f makefile.unx GUISUFFIX=_hp cleanany
+
+cleanany:
+	rm -f $(OBJECTS) minimal$(GUISUFFIX) core
diff --git a/samples/tab/makefile.vms b/samples/tab/makefile.vms
new file mode 100644
index 0000000000..9b76b144f3
--- /dev/null
+++ b/samples/tab/makefile.vms
@@ -0,0 +1,38 @@
+#************************************************************************
+# Makefile for MINIMAL under VMS
+# by Stefan Hammes
+# (incomplete) update history:
+# 11.04.95
+#************************************************************************
+
+#************************************************************************
+# Definition section
+# (cave: definitions and includes must begin with ',')
+#************************************************************************
+
+APPOPTS = 
+APPDEFS = 
+APPINCS = 
+
+#************************************************************************
+# Module section
+#************************************************************************
+
+# Name of main module
+MAIN = minimal
+
+# Object modules of the application.
+OBJS = minimal.obj
+OBJLIST =minimal.obj
+
+.include [--.src]makevms.env
+
+# main dependency
+$(MAIN).exe : $(OBJS)
+    $(LINK) $(LINKFLAGS) /exec=$(MAIN).exe $(OBJLIST),$(WXLIB)/lib,$(OPTSFILE)/option
+    - purge *.exe
+
+#************************************************************************
+# Header file depedencies following
+#************************************************************************
+
diff --git a/samples/tab/makefile.wat b/samples/tab/makefile.wat
new file mode 100644
index 0000000000..21219d7a0e
--- /dev/null
+++ b/samples/tab/makefile.wat
@@ -0,0 +1,43 @@
+#
+# Makefile for WATCOM
+#
+# Created by D.Chubraev, chubraev@iem.ee.ethz.ch
+# 8 Nov 1994
+#
+
+WXDIR = ..\.. 
+
+!include $(WXDIR)\src\makewat.env
+
+WXLIB = $(WXDIR)\lib
+NAME = minimal
+LNK = $(name).lnk
+OBJS = $(name).obj 
+
+all: $(name).exe
+
+$(name).exe : $(OBJS) $(name).res $(LNK) $(WXLIB)\wx$(LEVEL).lib
+    wlink @$(LNK)
+    $(BINDCOMMAND) $(name).res
+
+$(name).res :      $(name).rc $(WXDIR)\include\msw\wx.rc
+     $(RC) $(RESFLAGS1) $(name).rc
+
+$(LNK) : makefile.wat
+    %create $(LNK)
+    @%append $(LNK) debug all
+    @%append $(LNK) system $(LINKOPTION)
+    @%append $(LNK) $(MINDATA)
+    @%append $(LNK) $(MAXDATA)
+    @%append $(LNK) $(STACK)
+    @%append $(LNK) name $(name)
+    @%append $(LNK) file $(WXLIB)\wx$(LEVEL).lib
+    @for %i in ($(EXTRALIBS)) do @%append $(LNK) file %i
+    @for %i in ($(OBJS)) do @%append $(LNK) file %i
+
+thing: .SYMBOLIC
+    echo $(WATLIBDIR)
+
+clean:   .SYMBOLIC
+    -erase *.obj *.bak *.err *.pch *.lib *.lnk *.res *.exe
+
diff --git a/samples/tab/mondrian.ico b/samples/tab/mondrian.ico
new file mode 100644
index 0000000000000000000000000000000000000000..2310c5d275a87af295d5ea8dc79ea417a5e74c53
GIT binary patch
literal 766
zcmZQzU<5)11px*Sc)`TLAO@s0fLH;D9e|jTfdxnc0Z<M**w4TKL=5})Lnt5#WHKB$
zaDbtqp#doIAB-6O{|B*v7zjZ^AOa2W|NsACHyAJ}De?dRKnp(HN~rljcR;{k;{zQE
i@;}UZ|9Q?Fpp*~yJCwmWbLIrN`9Qm9%}2L?p!oo$cZ4ed

literal 0
HcmV?d00001

diff --git a/samples/tab/test.cpp b/samples/tab/test.cpp
new file mode 100644
index 0000000000..2b2064a29d
--- /dev/null
+++ b/samples/tab/test.cpp
@@ -0,0 +1,147 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        test.cpp
+// Purpose:     Tab demo
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c)
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include "wx/tab.h"
+#include "test.h"
+
+// Declare two frames
+MyDialog   *dialog = NULL;
+
+IMPLEMENT_APP(MyApp)
+
+bool MyApp::OnInit(void)
+{
+  // Create the main frame window
+  dialog = new MyDialog(NULL, -1, "Tabbed Dialog", wxPoint(-1, -1), wxSize(365, 390), wxDIALOG_MODAL|wxDEFAULT_DIALOG_STYLE);
+
+  dialog->ShowModal();
+
+  // Quit immediately the dialog has been dismissed
+  return FALSE;
+}
+
+BEGIN_EVENT_TABLE(MyDialog, wxTabbedDialog)
+    EVT_BUTTON(wxID_OK, MyDialog::OnOK)
+    EVT_BUTTON(wxID_CANCEL, MyDialog::OnOK)
+//    EVT_MENU(TEST_ABOUT, MyDialog::OnAbout)
+END_EVENT_TABLE()
+
+MyDialog::MyDialog(wxWindow* parent, const wxWindowID id, const wxString& title,
+    const wxPoint& pos, const wxSize& size, const long windowStyle):
+  wxTabbedDialog(parent, id, title, pos, size, windowStyle)
+{
+    Init();
+}
+
+void MyDialog::OnOK(wxCommandEvent& event)
+{
+    EndModal(wxID_OK);
+}
+
+void MyDialog::OnCloseWindow(wxCloseEvent& event)
+{
+    EndModal(wxID_CANCEL);
+}
+
+void MyDialog::Init(void)
+{
+  int dialogWidth = 365;
+  int dialogHeight = 390;
+  
+  wxButton *okButton = new wxButton(this, wxID_OK, "Close", wxPoint(100, 330), wxSize(80, 25));
+  wxButton *cancelButton = new wxButton(this, wxID_CANCEL, "Cancel", wxPoint(185, 330), wxSize(80, 25));
+  wxButton *HelpButton = new wxButton(this, wxID_HELP, "Help", wxPoint(270, 330), wxSize(80, 25));
+  okButton->SetDefault();
+
+  // Note, omit the wxTAB_STYLE_COLOUR_INTERIOR, so we will guarantee a match
+  // with the panel background, and save a bit of time.
+  wxPanelTabView *view = new wxPanelTabView((wxPanel*)this, wxTAB_STYLE_DRAW_BOX);
+
+  wxRectangle rect;
+  rect.x = 5;
+  rect.y = 70;
+  // Could calculate the view width from the tab width and spacing,
+  // as below, but let's assume we have a fixed view width.
+//  rect.width = view->GetTabWidth()*4 + 3*view->GetHorizontalTabSpacing();
+  rect.width = 326;
+  rect.height = 250;
+  
+  view->SetViewRect(rect);
+
+  // Calculate the tab width for 4 tabs, based on a view width of 326 and
+  // the current horizontal spacing. Adjust the view width to exactly fit
+  // the tabs.
+  view->CalculateTabWidth(4, TRUE);
+
+  if (!view->AddTab(TEST_TAB_CAT,        wxString("Cat")))
+    return;
+
+  if (!view->AddTab(TEST_TAB_DOG,        wxString("Dog")))
+    return;
+  if (!view->AddTab(TEST_TAB_GUINEAPIG,  wxString("Guinea Pig")))
+    return;
+  if (!view->AddTab(TEST_TAB_GOAT,       wxString("Goat")))
+    return;
+  if (!view->AddTab(TEST_TAB_ANTEATER,   wxString("Ant-eater")))
+    return;
+  if (!view->AddTab(TEST_TAB_SHEEP,      wxString("Sheep")))
+    return;
+  if (!view->AddTab(TEST_TAB_COW,        wxString("Cow")))
+    return;
+  if (!view->AddTab(TEST_TAB_HORSE,      wxString("Horse")))
+    return;
+  if (!view->AddTab(TEST_TAB_PIG,        wxString("Pig")))
+    return;
+  if (!view->AddTab(TEST_TAB_OSTRICH,    wxString("Ostrich")))
+    return;
+  if (!view->AddTab(TEST_TAB_AARDVARK,   wxString("Aardvark")))
+    return;
+  if (!view->AddTab(TEST_TAB_HUMMINGBIRD,wxString("Hummingbird")))
+    return;
+    
+  // Add some panels
+  wxPanel *panel1 = new wxPanel(this, -1, wxPoint(rect.x + 20, rect.y + 10), wxSize(290, 220), wxTAB_TRAVERSAL);
+  (void)new wxButton(panel1, -1, "Press me", wxPoint(10, 10));
+  (void)new wxTextCtrl(panel1, -1, "1234", wxPoint(10, 40), wxSize(120, 150));
+  
+  view->AddTabWindow(TEST_TAB_CAT, panel1);
+
+  wxPanel *panel2 = new wxPanel(this, -1, wxPoint(rect.x + 20, rect.y + 10), wxSize(290, 220));
+
+  wxString animals[] = { "Fox", "Hare", "Rabbit", "Sabre-toothed tiger", "T Rex" };
+  (void)new wxListBox(panel2, -1, wxPoint(5, 5), wxSize(170, 80), 5, animals);
+
+  (void)new wxTextCtrl(panel2, -1, "Some notes about the animals in this house", wxPoint(5, 100), wxSize(170, 100)),
+    wxTE_MULTILINE;
+  
+  view->AddTabWindow(TEST_TAB_DOG, panel2);
+  
+  // Don't know why this is necessary under Motif...
+#ifdef wx_motif
+  this->SetSize(dialogWidth, dialogHeight-20);
+#endif
+
+  view->SetTabSelection(TEST_TAB_CAT);
+  
+  this->Centre(wxBOTH);
+}
+
diff --git a/samples/tab/test.def b/samples/tab/test.def
new file mode 100644
index 0000000000..bacb3d4dda
--- /dev/null
+++ b/samples/tab/test.def
@@ -0,0 +1,8 @@
+NAME         Test
+DESCRIPTION  'Tab test'
+EXETYPE      WINDOWS
+STUB         'WINSTUB.EXE'
+CODE         PRELOAD MOVEABLE DISCARDABLE
+DATA         PRELOAD MOVEABLE MULTIPLE
+HEAPSIZE     1024
+STACKSIZE    16192
diff --git a/samples/tab/test.h b/samples/tab/test.h
new file mode 100644
index 0000000000..2cbdeb60a1
--- /dev/null
+++ b/samples/tab/test.h
@@ -0,0 +1,49 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        test.h
+// Purpose:     Tab demo
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c)
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+// Define a new application
+class MyApp: public wxApp
+{
+public:
+    bool OnInit(void);
+};
+
+class MyDialog: public wxTabbedDialog
+{
+public:
+    MyDialog(wxWindow* parent, const wxWindowID id, const wxString& title,
+        const wxPoint& pos, const wxSize& size, const long windowStyle = wxDEFAULT_DIALOG_STYLE);
+
+    void OnOK(wxCommandEvent& event);
+    void OnCloseWindow(wxCloseEvent& event);
+//    void OnAbout(wxCommandEvent& event);
+    void Init(void);
+
+DECLARE_EVENT_TABLE()
+};
+
+// File ids
+#define TEST_ABOUT          2
+
+// Tab ids
+#define TEST_TAB_DOG        1
+#define TEST_TAB_CAT        2
+#define TEST_TAB_GOAT       3
+#define TEST_TAB_GUINEAPIG  4
+#define TEST_TAB_ANTEATER   5
+#define TEST_TAB_HUMMINGBIRD 6
+#define TEST_TAB_SHEEP      7
+#define TEST_TAB_COW        8
+#define TEST_TAB_HORSE      9
+#define TEST_TAB_PIG        10
+#define TEST_TAB_OSTRICH    11
+#define TEST_TAB_AARDVARK   12
+
diff --git a/samples/tab/test.rc b/samples/tab/test.rc
new file mode 100644
index 0000000000..a05f21065a
--- /dev/null
+++ b/samples/tab/test.rc
@@ -0,0 +1,3 @@
+mondrian_icon ICON "mondrian.ico"
+#include "wx/msw/wx.rc"
+
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 0000000000..eb1f2ad5f1
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1 @@
+include gtk/setup/general/makeapp
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644
index 0000000000..10507f8fb4
--- /dev/null
+++ b/src/Makefile.in
@@ -0,0 +1,183 @@
+#
+#  wxGTK main source makefile
+#
+#  Copyright 1998, Markus Holzhem and Robert Roebling
+#
+
+# wxGTK base directory
+WXBASEDIR=@WXBASEDIR@
+
+# set the OS type for compilation
+OS=@OS@
+
+# compile a library only
+RULE=gslib
+
+# define common stuff
+
+# needed for unactivated
+NONE =
+
+# define library name
+LIB_TARGET=wx_gtk
+LIB_MAJOR=0
+LIB_MINOR=12
+
+# define library sources
+
+LIB_CPP_SRC=\
+\
+ common/cmndata.cpp \
+ common/config.cpp \
+ common/date.cpp \
+ common/docview.cpp \
+ common/dynarray.cpp \
+ common/event.cpp \
+ common/file.cpp \
+ common/fileconf.cpp \
+ common/filefn.cpp \
+ common/gdicmn.cpp \
+ common/hash.cpp \
+ common/helpbase.cpp \
+ common/intl.cpp \
+ common/ipcbase.cpp \
+ common/layout.cpp \
+ common/list.cpp \
+ common/log.cpp \
+ common/matrix.cpp \
+ common/memory.cpp \
+ common/module.cpp \
+ common/object.cpp \
+ common/postscrp.cpp \
+ common/prntbase.cpp \
+ common/string.cpp \
+ common/textfile.cpp \
+ common/time.cpp \
+ common/timercmn.cpp \
+ common/utilscmn.cpp \
+\
+ gtk/app.cpp \
+ gtk/bitmap.cpp \
+ gtk/brush.cpp \
+ gtk/button.cpp \
+ gtk/checkbox.cpp \
+ gtk/choice.cpp \
+ gtk/colour.cpp \
+ gtk/control.cpp \
+ gtk/cursor.cpp \
+ gtk/data.cpp \
+ gtk/dc.cpp \
+ gtk/dcclient.cpp \
+ gtk/dcmemory.cpp \
+ gtk/dcscreen.cpp \
+ gtk/dnd.cpp \
+ gtk/dialog.cpp \
+ gtk/filedlg.cpp \
+ gtk/font.cpp \
+ gtk/frame.cpp \
+ gtk/gdiobj.cpp \
+ gtk/icon.cpp \
+ gtk/listbox.cpp \
+ gtk/mdi.cpp \
+ gtk/menu.cpp \
+ gtk/palette.cpp \
+ gtk/pen.cpp \
+ gtk/radiobox.cpp \
+ gtk/radiobut.cpp \
+ gtk/region.cpp \
+ gtk/scrolbar.cpp \
+ gtk/settings.cpp \
+ gtk/slider.cpp \
+ gtk/statbox.cpp \
+ gtk/stattext.cpp \
+ gtk/tbargtk.cpp \
+ gtk/textctrl.cpp \
+ gtk/timer.cpp \
+ gtk/utilsgtk.cpp \
+ gtk/utilsres.cpp \
+ gtk/window.cpp \
+\
+ generic/choicdgg.cpp \
+ generic/colrdlgg.cpp \
+ generic/fontdlgg.cpp \
+ generic/gridg.cpp \
+ generic/imaglist.cpp \
+ generic/listctrl.cpp \
+ generic/msgdlgg.cpp \
+ generic/panelg.cpp \
+ generic/printps.cpp \
+ generic/prntdlgg.cpp \
+ generic/scrolwin.cpp \
+ generic/splitter.cpp \
+ generic/statusbr.cpp \
+ generic/tabg.cpp \
+ generic/textdlgg.cpp \
+ generic/treectrl.cpp
+ 
+LIB_C_SRC=\
+\
+ gtk/win_gtk.c \
+\
+ png/png.c \
+ png/pngset.c \
+ png/pngget.c \
+ png/pngrutil.c \
+ png/pngtrans.c \
+ png/pngwutil.c \
+ png/pngread.c \
+ png/pngrio.c \
+ png/pngwio.c \
+ png/pngwrite.c \
+ png/pngrtran.c \
+ png/pngwtran.c \
+ png/pngmem.c \
+ png/pngerror.c \
+ png/pngpread.c \
+\
+ zlib/adler32.c \
+ zlib/compress.c \
+ zlib/crc32.c \
+ zlib/gzio.c \
+ zlib/uncompr.c \
+ zlib/deflate.c \
+ zlib/trees.c \
+ zlib/zutil.c \
+ zlib/inflate.c \
+ zlib/infblock.c \
+ zlib/inftrees.c \
+ zlib/infcodes.c \
+ zlib/infutil.c \
+ zlib/inffast.c \
+\
+ gdk_imlib/cache.c \
+ gdk_imlib/colors.c \
+ gdk_imlib/globals.c \
+ gdk_imlib/load.c \
+ gdk_imlib/misc.c \
+ gdk_imlib/rend.c \
+ gdk_imlib/save.c \
+ gdk_imlib/utils.c
+
+ 
+#define library objects
+LIB_OBJ=\
+ $(LIB_CPP_SRC:.cpp=.o) \
+ $(LIB_C_SRC:.c=.o)
+
+all::
+	-../mkdirs
+
+clean::
+	$(RM) -rf gtk
+	$(RM) -rf common
+	$(RM) -rf generic
+	$(RM) -rf png
+	$(RM) -rf zlib
+	$(RM) -rf gdk_imlib
+
+#additional things needed for compile
+ADD_COMPILE= \
+   -DHAVE_LIBPNG -DDJPEG_PROG=\"\" -DCJPEG_PROG=\"\"
+
+# include the definitions now
+include ../../template.mak
diff --git a/src/common/cmndata.cpp b/src/common/cmndata.cpp
new file mode 100644
index 0000000000..100112b331
--- /dev/null
+++ b/src/common/cmndata.cpp
@@ -0,0 +1,473 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        cmndata.cpp
+// Purpose:     Common GDI data
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "cmndata.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include <stdio.h>
+#include "wx/utils.h"
+#include "wx/app.h"
+#endif
+
+#include "wx/gdicmn.h"
+#include "wx/cmndata.h"
+
+#ifdef __WINDOWS__
+#include <windows.h>
+
+#ifndef __WIN32__
+#include <print.h>
+#include <commdlg.h>
+#endif
+#endif
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxPrintData, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxPageSetupData, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxFontData, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxColourData, wxObject)
+#endif
+
+/*
+ * wxColourData
+ */
+
+wxColourData::wxColourData(void)
+{
+  int i;
+  for (i = 0; i < 16; i++)
+    custColours[i].Set(255, 255, 255);
+
+  chooseFull = FALSE;
+  dataColour.Set(0,0,0);
+} 
+
+wxColourData::~wxColourData(void)
+{
+}
+
+void wxColourData::SetCustomColour(int i, wxColour& colour)
+{
+  if (i > 15 || i < 0)
+    return;
+
+  custColours[i] = colour;
+}
+
+wxColour wxColourData::GetCustomColour(int i)
+{
+  if (i > 15 || i < 0)
+    return wxColour(0,0,0);
+
+  return custColours[i];
+}
+
+void wxColourData::operator=(const wxColourData& data)
+{
+  int i;
+  for (i = 0; i < 16; i++)
+    custColours[i] = data.custColours[i];
+
+  dataColour = (wxColour&)data.dataColour;
+  chooseFull = data.chooseFull;
+}
+
+/*
+ * Font data
+ */
+
+wxFontData::wxFontData(void)
+{
+  // Intialize colour to black.
+  fontColour.Set(0, 0, 0);
+
+  showHelp = FALSE;
+  allowSymbols = TRUE;
+  enableEffects = TRUE;
+  minSize = 0;
+  maxSize = 0;
+}
+
+wxFontData::~wxFontData(void)
+{
+}
+
+void wxFontData::operator=(const wxFontData& data)
+{
+   fontColour = data.fontColour;
+   showHelp = data.showHelp;
+   allowSymbols = data.allowSymbols;
+   enableEffects = data.enableEffects;
+   initialFont = data.initialFont;
+   chosenFont = data.chosenFont;
+   minSize = data.minSize;
+   maxSize = data.maxSize;
+}
+
+/*
+ * Print data
+ */
+
+wxPrintData::wxPrintData(void)
+{
+#ifdef __WINDOWS__
+    printData = NULL;
+#endif
+    printOrientation = wxPORTRAIT;
+    printFromPage = 0;
+    printToPage = 0;
+    printMinPage = 0;
+    printMaxPage = 0;
+    printNoCopies = 1;
+    printAllPages = FALSE;
+    printCollate = FALSE;
+    printToFile = FALSE;
+    printEnableSelection = FALSE;
+    printEnablePageNumbers = TRUE;
+    printEnablePrintToFile = TRUE;
+    printEnableHelp = FALSE;
+    printSetupDialog = FALSE;
+}
+
+wxPrintData::~wxPrintData(void)
+{
+#ifdef __WINDOWS__
+    PRINTDLG *pd = (PRINTDLG *)printData;
+    if ( pd && pd->hDevMode )
+        GlobalFree(pd->hDevMode);
+    if ( pd )
+        delete pd;
+#endif
+}
+
+#ifdef __WINDOWS__
+void wxPrintData::ConvertToNative(void)
+{
+    PRINTDLG *pd = (PRINTDLG*) printData;
+    if ( pd == NULL )
+    {
+        pd = new PRINTDLG;
+        printData = (void*) pd;
+
+        // GNU-WIN32 has the wrong size PRINTDLG - can't work out why.
+//        pd->lStructSize    = sizeof(PRINTDLG);
+        pd->lStructSize    = 66 ;
+        pd->hwndOwner      = (HWND)NULL;
+        pd->hDevMode       = NULL; // Will be created by PrintDlg
+        pd->hDevNames      = NULL; // Ditto
+
+        // Why had I put this #ifdef in?? Seems fine to me.
+#if 1
+        pd->Flags          = PD_RETURNDEFAULT;
+        pd->nCopies        = 1;
+
+        // Fill out the DEVMODE structure
+        // so we can use it as input in the 'real' PrintDlg
+        if (!PrintDlg(pd))
+        {
+            if ( pd->hDevMode )
+                GlobalFree(pd->hDevMode);
+            if ( pd->hDevNames )
+                GlobalFree(pd->hDevNames);
+            pd->hDevMode = NULL;
+            pd->hDevNames = NULL;
+        }
+        else
+        {
+            if ( pd->hDevNames )
+                GlobalFree(pd->hDevNames);
+            pd->hDevNames = NULL;
+        }
+#endif
+    }
+
+    if ( pd->hDevMode )
+    {
+        DEVMODE *devMode = (DEVMODE*) GlobalLock(pd->hDevMode);
+        devMode->dmOrientation = printOrientation;
+        devMode->dmFields = DM_ORIENTATION;
+        GlobalUnlock(pd->hDevMode);
+    }
+    pd->hDC = (HDC) NULL;
+    pd->nFromPage = (UINT)printFromPage;
+    pd->nToPage = (UINT)printToPage;
+    pd->nMinPage = (UINT)printMinPage;
+    pd->nMaxPage = (UINT)printMaxPage;
+    pd->nCopies = (UINT)printNoCopies;
+
+    pd->Flags = PD_RETURNDC ;
+//    pd->lStructSize = sizeof( PRINTDLG );
+    pd->lStructSize = 66 ;
+    pd->hwndOwner=(HANDLE)NULL;
+    pd->hDevNames=(HANDLE)NULL;
+    pd->hInstance=(HINSTANCE)NULL;
+    pd->lCustData = (LPARAM) NULL;
+    pd->lpfnPrintHook = NULL;
+    pd->lpfnSetupHook = NULL;
+    pd->lpPrintTemplateName = NULL;
+    pd->lpSetupTemplateName = NULL;
+    pd->hPrintTemplate = (HGLOBAL) NULL;
+    pd->hSetupTemplate = (HGLOBAL) NULL;
+
+    if ( printAllPages )
+        pd->Flags |= PD_ALLPAGES;
+    if ( printCollate )
+        pd->Flags |= PD_COLLATE;
+    if ( printToFile )
+        pd->Flags |= PD_PRINTTOFILE;
+    if ( !printEnablePrintToFile )
+        pd->Flags |= PD_DISABLEPRINTTOFILE;
+    if ( !printEnableSelection )
+      pd->Flags |= PD_NOSELECTION;
+    if ( !printEnablePageNumbers )
+      pd->Flags |= PD_NOPAGENUMS;
+    if ( printEnableHelp )
+      pd->Flags |= PD_SHOWHELP;
+    if ( printSetupDialog )
+      pd->Flags |= PD_PRINTSETUP;
+}
+
+void wxPrintData::ConvertFromNative(void)
+{
+    PRINTDLG *pd = (PRINTDLG*) printData;
+    if ( pd == NULL )
+        return;
+
+    if ( pd->hDevMode )
+    {
+        DEVMODE *devMode = (DEVMODE*) GlobalLock(pd->hDevMode);
+        printOrientation = devMode->dmOrientation;
+        GlobalUnlock(pd->hDevMode);
+    }
+    printFromPage = pd->nFromPage ;
+    printToPage = pd->nToPage ;
+    printMinPage = pd->nMinPage ;
+    printMaxPage = pd->nMaxPage ;
+    printNoCopies = pd->nCopies ;
+
+    printAllPages = ((pd->Flags & PD_ALLPAGES) == PD_ALLPAGES);
+    printCollate = ((pd->Flags & PD_COLLATE) == PD_COLLATE);
+    printToFile = ((pd->Flags & PD_PRINTTOFILE) == PD_PRINTTOFILE);
+    printEnablePrintToFile = ((pd->Flags & PD_DISABLEPRINTTOFILE) != PD_DISABLEPRINTTOFILE);
+    printEnableSelection = ((pd->Flags & PD_NOSELECTION) != PD_NOSELECTION);
+    printEnablePageNumbers = ((pd->Flags & PD_NOPAGENUMS) != PD_NOPAGENUMS);
+    printEnableHelp = ((pd->Flags & PD_SHOWHELP) == PD_SHOWHELP);
+    printSetupDialog = ((pd->Flags & PD_PRINTSETUP) == PD_PRINTSETUP);
+}
+
+void wxPrintData::SetOwnerWindow(wxWindow* win)
+{
+    if ( printData == NULL )
+        ConvertToNative();
+
+    if ( printData != NULL && win != NULL)
+    {
+      PRINTDLG *pd = (PRINTDLG *) printData ;
+      pd->hwndOwner=(HWND) win->GetHWND();
+    }
+}
+#endif
+
+void wxPrintData::operator=(const wxPrintData& data)
+{
+    printFromPage = data.printFromPage;
+    printToPage = data.printToPage;
+    printMinPage = data.printMinPage;
+    printMaxPage = data.printMaxPage;
+    printNoCopies = data.printNoCopies;
+    printAllPages = data.printAllPages;
+    printCollate = data.printCollate;
+    printToFile = data.printToFile;
+    printEnableSelection = data.printEnableSelection;
+    printEnablePageNumbers = data.printEnablePageNumbers;
+    printEnableHelp = data.printEnableHelp;
+    printEnablePrintToFile = data.printEnablePrintToFile;
+    printSetupDialog = data.printSetupDialog;
+    printOrientation = data.printOrientation;
+}
+
+/*
+ * wxPageSetupData
+ */
+
+wxPageSetupData::wxPageSetupData(void)
+{
+#if defined(__WIN95__)
+  m_pageSetupData = NULL;
+#endif
+  m_paperSize = wxPoint(0, 0);
+  m_minMarginTopLeft = wxPoint(0, 0);
+  m_minMarginBottomRight = wxPoint(0, 0);
+  m_marginTopLeft = wxPoint(0, 0);
+  m_marginBottomRight = wxPoint(0, 0);
+  m_orientation = wxPORTRAIT;
+
+  // Flags
+  m_defaultMinMargins = FALSE;
+  m_enableMargins = TRUE;
+  m_enableOrientation = TRUE;
+  m_enablePaper = TRUE;
+  m_enablePrinter = TRUE;
+  m_enableHelp = FALSE;
+  m_getDefaultInfo = FALSE;
+}
+
+wxPageSetupData::~wxPageSetupData(void)
+{
+#if defined(__WIN95__)
+    PAGESETUPDLG *pd = (PAGESETUPDLG *)m_pageSetupData;
+    if ( pd && pd->hDevMode )
+        GlobalFree(pd->hDevMode);
+    if ( pd )
+        delete pd;
+#endif
+}
+
+void wxPageSetupData::operator=(const wxPageSetupData& data)
+{
+  m_paperSize = data.m_paperSize;
+  m_minMarginTopLeft = data.m_minMarginTopLeft;
+  m_minMarginBottomRight = data.m_minMarginBottomRight;
+  m_marginTopLeft = data.m_marginTopLeft;
+  m_marginBottomRight = data.m_marginBottomRight;
+  m_orientation = data.m_orientation;
+
+  m_defaultMinMargins = data.m_defaultMinMargins;
+  m_enableMargins = data.m_enableMargins;
+  m_enableOrientation = data.m_enableOrientation;
+  m_enablePaper = data.m_enablePaper;
+  m_enablePrinter = data.m_enablePrinter;
+  m_getDefaultInfo = data.m_getDefaultInfo;;
+  m_enableHelp = data.m_enableHelp;
+}
+
+#if defined(__WIN95__)
+void wxPageSetupData::ConvertToNative(void)
+{
+    PAGESETUPDLG *pd = (PAGESETUPDLG*) m_pageSetupData;
+    if ( m_pageSetupData == NULL )
+    {
+      pd = new PAGESETUPDLG;
+      pd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, sizeof(DEVMODE));
+      m_pageSetupData = (void *)pd;
+    }
+  
+    pd->Flags = PSD_MARGINS|PSD_MINMARGINS;
+
+    if ( m_defaultMinMargins )
+        pd->Flags |= PSD_DEFAULTMINMARGINS;
+    if ( !m_enableMargins )
+        pd->Flags |= PSD_DISABLEMARGINS;
+    if ( !m_enableOrientation )
+        pd->Flags |= PSD_DISABLEORIENTATION;
+    if ( !m_enablePaper )
+        pd->Flags |= PSD_DISABLEPAPER;
+    if ( !m_enablePrinter )
+        pd->Flags |= PSD_DISABLEPRINTER;
+    if ( m_getDefaultInfo )
+        pd->Flags |= PSD_RETURNDEFAULT;
+    if ( m_enableHelp )
+        pd->Flags |= PSD_SHOWHELP;
+
+    pd->lStructSize = sizeof( PAGESETUPDLG );
+    pd->hwndOwner=(HANDLE)NULL;
+    pd->hDevNames=(HWND)NULL;
+    pd->hInstance=(HINSTANCE)NULL;
+
+    pd->ptPaperSize.x = m_paperSize.x;
+    pd->ptPaperSize.y = m_paperSize.y;
+
+    pd->rtMinMargin.left = m_minMarginTopLeft.x;
+    pd->rtMinMargin.top = m_minMarginTopLeft.y;
+    pd->rtMinMargin.right = m_minMarginBottomRight.x;
+    pd->rtMinMargin.bottom = m_minMarginBottomRight.y;
+
+    pd->rtMargin.left = m_marginTopLeft.x;
+    pd->rtMargin.top = m_marginTopLeft.y;
+    pd->rtMargin.right = m_marginBottomRight.x;
+    pd->rtMargin.bottom = m_marginBottomRight.y;
+
+    pd->lCustData = 0;
+    pd->lpfnPageSetupHook = NULL;
+    pd->lpfnPagePaintHook = NULL;
+    pd->hPageSetupTemplate = NULL;
+    pd->lpPageSetupTemplateName = NULL;
+
+    if ( pd->hDevMode )
+    {
+        DEVMODE *devMode = (DEVMODE*) GlobalLock(pd->hDevMode);
+        memset(devMode, 0, sizeof(DEVMODE));
+        devMode->dmSize = sizeof(DEVMODE);
+        devMode->dmOrientation = m_orientation;
+        devMode->dmFields = DM_ORIENTATION;
+        GlobalUnlock(pd->hDevMode);
+    }
+}
+
+void wxPageSetupData::ConvertFromNative(void)
+{
+    PAGESETUPDLG *pd = (PAGESETUPDLG *) m_pageSetupData ;
+    if ( !pd )
+        return;
+
+    pd->Flags = PSD_MARGINS|PSD_MINMARGINS;
+
+    m_defaultMinMargins = ((pd->Flags & PSD_DEFAULTMINMARGINS) == PSD_DEFAULTMINMARGINS);
+    m_enableMargins = ((pd->Flags & PSD_DISABLEMARGINS) != PSD_DISABLEMARGINS);
+    m_enableOrientation = ((pd->Flags & PSD_DISABLEORIENTATION) != PSD_DISABLEORIENTATION);
+    m_enablePaper = ((pd->Flags & PSD_DISABLEPAPER) != PSD_DISABLEPAPER);
+    m_enablePrinter = ((pd->Flags & PSD_DISABLEPRINTER) != PSD_DISABLEPRINTER);
+    m_getDefaultInfo = ((pd->Flags & PSD_RETURNDEFAULT) == PSD_RETURNDEFAULT);
+    m_enableHelp = ((pd->Flags & PSD_SHOWHELP) == PSD_SHOWHELP);
+
+    m_paperSize.x = pd->ptPaperSize.x ;
+    m_paperSize.y = pd->ptPaperSize.y ;
+
+    m_minMarginTopLeft.x = pd->rtMinMargin.left ;
+    m_minMarginTopLeft.y = pd->rtMinMargin.top ;
+    m_minMarginBottomRight.x = pd->rtMinMargin.right ;
+    m_minMarginBottomRight.y = pd->rtMinMargin.bottom ;
+
+    m_marginTopLeft.x = pd->rtMargin.left ;
+    m_marginTopLeft.y = pd->rtMargin.top ;
+    m_marginBottomRight.x = pd->rtMargin.right ;
+    m_marginBottomRight.y = pd->rtMargin.bottom ;
+
+    if ( pd->hDevMode )
+    {
+        DEVMODE *devMode = (DEVMODE*) GlobalLock(pd->hDevMode);
+        m_orientation = devMode->dmOrientation ;
+        GlobalUnlock(pd->hDevMode);
+    }
+}
+
+void wxPageSetupData::SetOwnerWindow(wxWindow* win)
+{
+    if ( m_pageSetupData == NULL )
+        ConvertToNative();
+
+    if ( m_pageSetupData != NULL && win != NULL)
+    {
+      PAGESETUPDLG *pd = (PAGESETUPDLG *) m_pageSetupData ;
+      pd->hwndOwner=(HWND) win->GetHWND();
+    }
+}
+#endif
+
diff --git a/src/common/config.cpp b/src/common/config.cpp
new file mode 100644
index 0000000000..ddb5a9d716
--- /dev/null
+++ b/src/common/config.cpp
@@ -0,0 +1,153 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        config.cpp
+// Purpose:     implementation of wxConfig class
+// Author:      Vadim Zeitlin
+// Modified by: 
+// Created:     07.04.98
+// RCS-ID:      $Id$
+// Copyright:   (c) 1997 Karsten Ballüder   Ballueder@usa.net  
+//                       Vadim Zeitlin      <zeitlin@dptmaths.ens-cachan.fr>
+// Licence:     wxWindows license
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// headers
+// ============================================================================
+#ifdef __GNUG__
+#pragma implementation "app.h"
+#endif
+
+#include  "wx/wxprec.h"
+
+#ifdef    __BORLANDC__
+  #pragma hdrstop
+#endif  //__BORLANDC__
+
+#include  <wx/string.h>
+#include  <wx/intl.h>
+#include  <wx/file.h>
+#include  <wx/log.h>
+#include  <wx/textfile.h>
+#include  <wx/config.h>
+
+#include <stdlib.h>
+#include <ctype.h>
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxConfig
+// ----------------------------------------------------------------------------
+wxConfig::~wxConfig()
+{
+}
+
+// ----------------------------------------------------------------------------
+// static & global functions
+// ----------------------------------------------------------------------------
+
+// understands both Unix and Windows (but only under Windows) environment
+// variables expansion: i.e. $var, $(var) and ${var} are always understood
+// and in addition under Windows %var% is also.
+wxString ExpandEnvVars(const wxString& str)
+{
+  wxString strResult;
+
+  // don't change the values the enum elements: they must be equal
+  // to the matching [closing] delimiter.
+  enum Bracket
+  { 
+    Bracket_None, 
+    Bracket_Normal  = ')', 
+    Bracket_Curly   = '}',
+#ifdef  __WINDOWS__
+    Bracket_Windows = '%'     // yeah, Windows people are a bit strange ;-)
+#endif
+  };
+
+  uint m;
+  for ( uint n = 0; n < str.Len(); n++ ) {
+    switch ( str[n] ) {
+#ifdef  __WINDOWS__
+      case '%':
+#endif  //WINDOWS
+      case '$':
+        {
+          Bracket bracket;
+          #ifdef  __WINDOWS__
+            if ( str[n] == '%' )
+              bracket = Bracket_Windows;
+            else
+          #endif  //WINDOWS
+          if ( n == str.Len() - 1 ) {
+            bracket = Bracket_None;
+          }
+          else {
+            switch ( str[n + 1] ) {
+              case '(': 
+                bracket = Bracket_Normal; 
+                n++;                   // skip the bracket
+                break;
+
+              case '{':
+                bracket = Bracket_Curly;
+                n++;                   // skip the bracket
+                break;
+
+              default:
+                bracket = Bracket_None;
+            }
+          }
+
+          m = n + 1;
+
+          while ( m < str.Len() && (isalnum(str[m]) || str[m] == '_') )
+            m++;
+
+          wxString strVarName(str.c_str() + n + 1, m - n - 1);
+
+          const char *pszValue = getenv(strVarName);
+          if ( pszValue != NULL ) {
+            strResult += pszValue;
+          }
+          else {
+            // variable doesn't exist => don't change anything
+            #ifdef  __WINDOWS__
+              if ( bracket != Bracket_Windows )
+            #endif
+                if ( bracket != Bracket_None )
+                  strResult << str[n - 1];
+            strResult << str[n] << strVarName;
+          }
+
+          // check the closing bracket
+          if ( bracket != Bracket_None ) {
+            if ( m == str.Len() || str[m] != (char)bracket ) {
+              wxLogWarning("missing '%c' at position %d in '%s'.",
+                           (char)bracket, m + 1, str.c_str());
+            }
+            else {
+              // skip closing bracket
+              if ( pszValue == NULL )
+                strResult << (char)bracket;
+              m++;
+            }
+          }
+
+          n = m - 1;  // skip variable name
+        }
+        break;
+
+      case '\\':
+        n++;
+        // fall through
+
+      default:
+        strResult += str[n];
+    }
+  }
+
+  return strResult;
+}
diff --git a/src/common/date.cpp b/src/common/date.cpp
new file mode 100644
index 0000000000..c0a1495af2
--- /dev/null
+++ b/src/common/date.cpp
@@ -0,0 +1,650 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        date.cpp
+// Purpose:     wxDate class
+// Author:
+//    Originally inspired by Steve Marcus (CIS 72007,1233)  6/16/91
+//    Enhanced by Eric Simon (CIS 70540,1522)               6/29/91
+//    Further Enhanced by Chris Hill (CIS 72030,2606)       7/11/91
+//    Still Further Enhanced by Hill & Simon  v3.10         8/05/91
+//    Version 4 by Charles D. Price                         6/27/92
+//    Integrated into wxWindows by Julian Smart             9th July 1995
+// Modified by:	
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "date.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#include "wx/setup.h"
+
+#if USE_TIMEDATE
+
+#include "wx/date.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#if USE_IOSTREAMH
+#include <iostream.h>
+#else
+#include <iostream>
+#endif
+
+#include <time.h>
+#include <string.h>
+
+#define ABBR_LENGTH 3
+
+static const char *dayname[] = {"Sunday","Monday","Tuesday","Wednesday",
+	   "Thursday","Friday","Saturday"} ;
+
+static const char *mname[] = {"January","February","March","April","May",
+	   "June","July","August","September","October","November","December"};
+
+static int GauDays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxDate, wxObject)
+#endif
+
+////////////////////////////////////////////////////////////
+// Constructors
+////////////////////////////////////////////////////////////
+
+wxDate::wxDate()
+{
+  DisplayFormat=wxMDY;
+  DisplayOptions='\0';
+  month = day = year = day_of_week = 0;
+  julian = 0;
+}
+
+wxDate::wxDate (const long j) : julian(j)
+{
+  DisplayFormat=wxMDY;
+  DisplayOptions='\0';
+  julian_to_mdy ();
+}
+
+wxDate::wxDate (const int m, const int d, const int y) : month(m), day(d), year(y)
+{
+  DisplayFormat=wxMDY;
+  DisplayOptions='\0';
+  mdy_to_julian ();
+}
+
+wxDate::wxDate (const wxString& dat)
+{
+  DisplayFormat=wxMDY;
+  DisplayOptions='\0';
+  if (strcmp(dat, "TODAY") == 0 || strcmp(dat, "today") == 0)
+  {
+    // Sets the current date
+    Set();
+  }
+  else
+  {
+    char buf[100];
+    strcpy(buf, (char *) (const char *)dat);
+
+    char *token = strtok(buf,"/-");
+    month = atoi(token);
+    day   = atoi(strtok(NULL,"/-"));
+    year  = atoi(strtok(NULL," "));
+  }
+
+  mdy_to_julian ();
+}
+
+wxDate::wxDate (const wxDate &dt)
+{
+  DisplayFormat=dt.DisplayFormat;
+  DisplayOptions=dt.DisplayOptions;
+  month = dt.month;
+  day   = dt.day;
+  year  = dt.year;
+  mdy_to_julian ();
+}
+
+void wxDate::operator = (const wxDate &dt)
+{
+  DisplayFormat=dt.DisplayFormat;
+  DisplayOptions=dt.DisplayOptions;
+  month = dt.month;
+  day   = dt.day;
+  year  = dt.year;
+  mdy_to_julian ();
+}
+
+void wxDate::operator = (const wxString& dat)
+{
+  DisplayFormat=wxMDY;
+  DisplayOptions='\0';
+  if (strcmp(dat, "TODAY") == 0 || strcmp(dat, "today") == 0)
+  {
+    // Sets the current date
+    Set();
+  }
+  else
+  {
+    char buf[100];
+    strcpy(buf, (char *)(const char *)dat);
+
+    char *token = strtok(buf,"/-");
+    month = atoi(token);
+    day   = atoi(strtok(NULL,"/-"));
+    year  = atoi(strtok(NULL," "));
+  }
+
+  mdy_to_julian ();
+}
+
+//////////////////////////////////////////////////////////////
+// Conversion operations
+//////////////////////////////////////////////////////////////
+
+wxDate::operator wxString( void )
+{
+  return FormatDate();
+}
+
+//////////////////////////////////////////////////////////////
+// Date Arithmetic
+//////////////////////////////////////////////////////////////
+
+wxDate wxDate::operator + (const long i)
+{
+  wxDate dp(julian + i);
+  return dp;
+}
+
+wxDate wxDate::operator + (const int i)
+{
+  wxDate dp(julian + (long)i);
+  return dp;
+}
+
+wxDate wxDate::operator - (const long i)
+{
+  wxDate dp(julian - i);
+  return dp;
+}
+
+wxDate wxDate::operator - (const int i)
+{
+  wxDate dp(julian - (long)i);
+  return dp;
+}
+
+long wxDate::operator - (const wxDate &dt)
+{
+	return ( julian - dt.julian );
+}
+
+wxDate &wxDate::operator += (const long i)
+{
+	 julian += i;
+     julian_to_mdy();
+	 return *this;
+}
+
+wxDate &wxDate::operator -= (const long i)
+{
+	 julian -= i;
+     julian_to_mdy();
+	 return *this;
+}
+
+wxDate &wxDate::operator ++()
+{
+	julian++;
+    julian_to_mdy();
+	return *this;
+}
+
+wxDate &wxDate::operator ++(int)
+{
+	julian++;
+    julian_to_mdy();
+	return *this;
+}
+
+wxDate &wxDate::operator --()
+{
+	julian--;
+    julian_to_mdy();
+	return *this;
+}
+
+wxDate &wxDate::operator --(int)
+{
+	julian--;
+    julian_to_mdy();
+	return *this;
+}
+
+//////////////////////////////////////////////////////////////
+// Date comparison
+//////////////////////////////////////////////////////////////
+
+bool operator <  (const wxDate &dt1, const wxDate &dt2)
+{
+	return ( dt1.julian < dt2.julian );
+}
+
+bool operator <= (const wxDate &dt1, const wxDate &dt2)
+{
+	return ( (dt1.julian == dt2.julian) || (dt1.julian < dt2.julian) );
+}
+
+bool operator >  (const wxDate &dt1, const wxDate &dt2)
+{
+	return ( dt1.julian > dt2.julian );
+}
+
+bool operator >= (const wxDate &dt1, const wxDate &dt2)
+{
+	return ( (dt1.julian == dt2.julian) || (dt1.julian > dt2.julian) );
+}
+
+bool operator == (const wxDate &dt1, const wxDate &dt2)
+{
+	return ( dt1.julian == dt2.julian );
+}
+
+bool operator != (const wxDate &dt1, const wxDate &dt2)
+{
+	return ( dt1.julian != dt2.julian );
+}
+
+////////////////////////////////////////////////////////////////
+// Ostream operations
+////////////////////////////////////////////////////////////////
+
+ostream &operator << (ostream &os, const wxDate &dt)
+{
+	return os << (const char *) dt.FormatDate();
+}
+
+//////////////////////////////////////////////////////////////
+// Conversion routines
+//////////////////////////////////////////////////////////////
+
+void wxDate::julian_to_wday (void)
+{
+	day_of_week = (int) ((julian + 2) % 7 + 1);
+}
+
+void wxDate::julian_to_mdy ()
+{
+	long a,b,c,d,e,z,alpha;
+	z = julian+1;
+	// dealing with Gregorian calendar reform
+    if (z < 2299161L)
+       a = z;
+    else {
+       alpha = (long) ((z-1867216.25) / 36524.25);
+       a = z + 1 + alpha - alpha/4;
+    }
+	b = ( a > 1721423 ? a + 1524 : a + 1158 );
+	c = (long) ((b - 122.1) / 365.25);
+	d = (long) (365.25 * c);
+	e = (long) ((b - d) / 30.6001);
+    day = (int)(b - d - (long)(30.6001 * e));
+    month = (int)((e < 13.5) ? e - 1 : e - 13);
+    year = (int)((month > 2.5 ) ? (c - 4716) : c - 4715);
+	julian_to_wday ();
+}
+
+void wxDate::mdy_to_julian (void)
+{
+	int a,b=0;
+	int work_month=month, work_day=day, work_year=year;
+	// correct for negative year
+    if (work_year < 0)
+		work_year++;
+	if (work_month <= 2)
+		{ work_year--; work_month +=12; }
+
+	// deal with Gregorian calendar
+	if (work_year*10000. + work_month*100. + work_day >= 15821015.)
+		{
+        a = (int)(work_year/100.);
+		b = 2 - a + a/4;
+		}
+	julian = (long) (365.25*work_year) +
+			 (long) (30.6001 * (work_month+1))  +  work_day + 1720994L + b;
+	julian_to_wday ();
+}
+
+////////////////////////////////////////////////////////////////
+// Format routine
+////////////////////////////////////////////////////////////////
+
+wxString wxDate::FormatDate (const int type) const
+{
+  int actualType = type;
+  if (actualType == -1)
+    actualType = DisplayFormat;
+
+    char buf[40];
+
+    memset( buf, '\0', sizeof(buf) );
+	switch ( actualType )
+	{
+		case wxDAY:
+			if ( (day_of_week < 1) || (day_of_week > 7) )
+				strcpy(buf,"invalid day");
+			else
+				strncpy( buf, dayname[day_of_week-1],
+					(DisplayOptions & wxDATE_ABBR) ? ABBR_LENGTH : 9);
+			return wxString(buf);
+
+		case wxMONTH:
+			if ( (month < 1) || (month > 12) )
+				strcpy(buf,"invalid month");
+			else
+				strncpy( buf, mname[month-1],
+					(DisplayOptions & wxDATE_ABBR) ? ABBR_LENGTH : 9);
+			return wxString(buf);
+
+		case wxFULL:
+			if ( (month < 1) || (month > 12) || (day_of_week < 0) ||
+				 (day_of_week > 7) )
+			{
+				strcpy(buf,"invalid date");
+				return wxString(buf);
+			}
+			strncpy( buf, dayname[day_of_week-1],
+				(DisplayOptions & wxDATE_ABBR) ? ABBR_LENGTH : 9);
+			strcat( buf, ", ");
+			strncat( buf, mname[month-1],
+				(DisplayOptions & wxDATE_ABBR) ? ABBR_LENGTH : 9);
+			strcat( buf, " ");
+			sprintf( buf+strlen(buf), "%d, %d", day, abs(year) );
+			if (year < 0)
+				strcat(buf," B.C.");
+			return wxString(buf);
+
+		case wxEUROPEAN:
+			if ( (month < 1) || (month > 12) || (day_of_week < 0) ||
+				 (day_of_week > 7) )
+			{
+				strcpy(buf,"invalid date");
+				return wxString(buf);
+			}
+			sprintf(buf,"%d ",	day);
+			strncat(buf, mname[month-1],
+				(DisplayOptions & wxDATE_ABBR) ? ABBR_LENGTH : 9);
+			sprintf( buf+strlen(buf), " %d", abs(year) );
+			if (year < 0)
+				strcat(buf," B.C.");
+			return wxString(buf);
+
+		case wxMDY:
+		default:
+			if (day==0 || month==0 || year==0)
+				strcpy(buf,"invalid date");
+			else
+				sprintf( buf+strlen(buf), "%1d/%1d/%02d", month, day,
+					(DisplayOptions & wxNO_CENTURY) && (abs(year) > 1899)
+					? (abs(year) - (abs(year) / 100 * 100))
+					: (abs(year))  );
+			return wxString(buf);
+	}
+  return wxString("");
+}
+
+void wxDate::SetFormat( const int format )
+{
+	DisplayFormat = format;
+}
+
+int wxDate::SetOption( const int option, const bool action )
+{
+	switch ( option )
+	{
+		case wxNO_CENTURY:
+			if ( action )
+				DisplayOptions |= wxNO_CENTURY;
+			else
+			{
+				DisplayOptions &= (~wxNO_CENTURY);
+			}
+			return 1;
+		case wxDATE_ABBR:
+			if ( action )
+				DisplayOptions |= wxDATE_ABBR;
+			else
+			{
+				DisplayOptions &= (~wxDATE_ABBR);
+			}
+			return 1;
+		default:
+			return 0;
+	}
+  return 0;
+}
+
+///////////////////////////////////////////////////////////////
+//  Miscellaneous Routines
+///////////////////////////////////////////////////////////////
+
+long wxDate::GetJulianDate( void ) const
+{
+	return julian;
+}
+
+int wxDate::GetDayOfYear( void ) const
+{
+	wxDate temp( 1, 1, year );
+
+	return (int) (julian - temp.julian + 1);
+}
+
+
+bool wxDate::IsLeapYear( void ) const
+{
+	return  ( (year >= 1582) ?
+			  (year % 4 == 0  &&  year % 100 != 0  ||  year % 400 == 0 ):
+			  (year % 4 == 0) );
+}
+
+// Version 4.0 Extension to Public Interface - CDP
+
+wxDate& wxDate::Set()
+{
+//#ifdef __WINDOWS__
+#if 0
+    struct _dosdate_t sDate;
+    _dos_getdate(&sDate);
+
+    month = sDate.month;
+    day   = sDate.day;
+    year  = sDate.year;
+
+    mdy_to_julian();
+#else
+    time_t now = time(NULL);
+    struct tm *localTime = localtime(&now);
+
+    month = localTime->tm_mon + 1;
+    day = localTime->tm_mday;
+    year = localTime->tm_year + 1900;
+
+    mdy_to_julian ();
+#endif
+    return *this;
+}
+
+wxDate& wxDate::Set(
+	int	nMonth,
+	int	nDay,
+	int	nYear)
+{
+    month = nMonth;
+    year  = nYear < 0 ? 9999 : nYear;
+    year  = nYear > 9999 ? 0 : nYear;
+    day   = nDay < GetDaysInMonth() ? nDay : GetDaysInMonth();
+
+    mdy_to_julian();
+	return *this;
+}
+
+wxDate &
+wxDate::Set(long j)
+{
+  julian = j;
+
+  julian_to_mdy();
+  return *this;
+}
+
+
+int wxDate::GetDaysInMonth()
+{
+    return GauDays[month-1] + (month==2 && IsLeapYear());
+}
+
+int wxDate::GetFirstDayOfMonth() const
+{
+    return wxDate(month, 1, year).GetDayOfWeek();
+}
+
+int wxDate::GetDay() const
+{
+    return day;
+}
+
+int wxDate::GetDayOfWeek() const
+{
+    return day_of_week;
+}
+
+int wxDate::GetYear() const
+{
+    return year;
+}
+
+int wxDate::GetMonth() const
+{
+    return month;
+}
+
+wxDate& wxDate::AddWeeks(int nCount)
+{
+    Set(julian + (long)nCount*7);
+    return *this;
+}
+
+wxDate& wxDate::AddMonths(int nCount)
+{
+    month += nCount;
+
+    if (month < 1) {
+        month = 12;
+        year--;
+	}
+
+    if (month > 12) {
+        month = 1;
+        year++;
+	}
+    mdy_to_julian();
+    return *this;
+}
+
+wxDate& wxDate::AddYears(int nCount)
+{
+    year += nCount;
+    mdy_to_julian();
+    return *this;
+}
+
+int wxDate::GetWeekOfMonth()
+{
+  // Abs day includes the days from previous month that fills up
+  // the begin. of the week.
+  int nAbsDay = day + GetFirstDayOfMonth()-1;
+  return (nAbsDay-GetDayOfWeek())/7 + 1;
+}
+
+int wxDate::GetWeekOfYear()
+{
+    wxDate   doTemp(1, 1, year);
+    return (int)(((julian - doTemp.julian+1)/7) + 1);
+}
+
+wxDate wxDate::GetMonthStart()
+{
+    return(wxDate(month, 1, year));
+}
+
+wxDate wxDate::GetMonthEnd()
+{
+    return(wxDate(month+1, 1, year)-1);
+}
+
+wxDate wxDate::GetYearStart()
+{
+    return(wxDate(1, 1, year));
+}
+
+wxDate wxDate::GetYearEnd()
+{
+    return(wxDate(1, 1, year+1)-1);
+}
+
+wxString wxDate::GetMonthName()
+{
+    return(FormatDate(wxMONTH));
+}
+
+wxString wxDate::GetDayOfWeekName()
+{
+    return(FormatDate(wxDAY));
+}
+
+bool wxDate::IsBetween(const wxDate& first, const wxDate& second) const
+{
+  return (julian >= first.julian && julian <= second.julian);
+}
+
+// This function is from NIHCL
+wxDate wxDate::Previous(const int dayOfWeek) const
+{
+        int this_day_Of_Week, desired_day_Of_Week;
+        long j;
+
+//      Set the desired and current day of week to start at 0 (Monday)
+//      and end at 6 (Sunday).
+
+        desired_day_Of_Week = dayOfWeek - 1; // These functions return a value
+        this_day_Of_Week    = GetDayOfWeek() - 1;            // from 1-7.  Subtract 1 for 0-6.
+        j = julian;
+
+//      Have to determine how many days difference from current day back to
+//      desired, if any.  Special calculation under the 'if' statement to
+//      effect the wraparound counting from Monday (0) back to Sunday (6).
+
+        if (desired_day_Of_Week > this_day_Of_Week)
+                this_day_Of_Week += 7 - desired_day_Of_Week;
+        else
+                this_day_Of_Week -= desired_day_Of_Week;
+        j -= this_day_Of_Week; // Adjust j to set it at the desired day of week.
+        return wxDate(j);
+}
+
+#endif
diff --git a/src/common/docview.cpp b/src/common/docview.cpp
new file mode 100644
index 0000000000..e22c78dd14
--- /dev/null
+++ b/src/common/docview.cpp
@@ -0,0 +1,1898 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        docview.cpp
+// Purpose:     Document/view classes
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "docview.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/defs.h"
+#endif
+
+#if USE_DOC_VIEW_ARCHITECTURE
+
+#ifndef WX_PRECOMP
+#include "wx/utils.h"
+#include "wx/app.h"
+#include "wx/dc.h"
+#include "wx/dialog.h"
+#include "wx/menu.h"
+#include "wx/list.h"
+#include "wx/filedlg.h"
+#endif
+
+#include "wx/msgdlg.h"
+#include "wx/choicdlg.h"
+#include "wx/docview.h"
+#include "wx/printdlg.h"
+#include "wx/generic/prntdlgg.h"
+#include "wx/generic/printps.h"
+
+/*
+#ifdef __WINDOWS__
+#include "wx/mdi.h"
+#endif
+*/
+
+#include <stdio.h>
+#include <string.h>
+
+#if USE_IOSTREAMH
+#include <iostream.h>
+#else
+#include <iostream>
+#endif
+
+#include "fstream.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_ABSTRACT_CLASS(wxDocument, wxEvtHandler)
+IMPLEMENT_ABSTRACT_CLASS(wxView, wxEvtHandler)
+IMPLEMENT_ABSTRACT_CLASS(wxDocTemplate, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxDocManager, wxEvtHandler)
+IMPLEMENT_CLASS(wxDocChildFrame, wxFrame)
+IMPLEMENT_CLASS(wxDocParentFrame, wxFrame)
+#if USE_PRINTING_ARCHITECTURE
+IMPLEMENT_DYNAMIC_CLASS(wxDocPrintout, wxPrintout)
+#endif
+IMPLEMENT_CLASS(wxCommand, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxCommandProcessor, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxFileHistory, wxObject)
+// IMPLEMENT_DYNAMIC_CLASS(wxPrintInfo, wxObject)
+#endif
+
+/*
+ * Definition of wxDocument
+ */
+
+wxDocument::wxDocument(wxDocument *parent)
+{
+  m_documentModified=FALSE;
+  m_documentFile="";
+  m_documentTitle="";
+  m_documentParent=parent;
+  m_documentTemplate = NULL;
+  m_documentTypeName = "";
+  m_savedYet = FALSE;
+}
+
+bool wxDocument::DeleteContents(void)
+{
+  return TRUE;
+}
+
+wxDocument::~wxDocument(void)
+{
+  DeleteContents();
+
+  if (m_commandProcessor)
+    delete m_commandProcessor;
+
+  GetDocumentManager()->RemoveDocument(this);
+
+  // Not safe to do here, since it'll
+  // invoke virtual view functions expecting to see
+  // valid derived objects: and by the time we get
+  // here, we've called destructors higher up.
+//  DeleteAllViews();
+}
+	
+bool wxDocument::Close(void)
+{
+  if (OnSaveModified())
+    return OnCloseDocument();
+  else
+    return FALSE;
+}
+	
+bool wxDocument::OnCloseDocument(void)
+{
+  DeleteContents();
+  Modify(FALSE);
+  return TRUE;
+}
+
+// Note that this implicitly deletes the document when
+// the last view is deleted.
+bool wxDocument::DeleteAllViews(void)
+{
+  wxNode *node = m_documentViews.First();
+  while (node)
+  {
+    wxView *view = (wxView *)node->Data();
+    if (!view->Close())
+      return FALSE;
+
+    wxNode *next = node->Next();
+      
+    delete view; // Deletes node implicitly
+    node = next;
+  }
+  return TRUE;
+}
+
+wxView *wxDocument::GetFirstView(void) const
+{
+  if (m_documentViews.Number() == 0)
+    return NULL;
+  return (wxView *)m_documentViews.First()->Data();
+}
+
+wxDocManager *wxDocument::GetDocumentManager(void) const
+{
+  return m_documentTemplate->GetDocumentManager();
+}
+
+bool wxDocument::OnNewDocument(void)
+{
+  if (!OnSaveModified())
+    return FALSE;
+    
+  if (OnCloseDocument()==FALSE) return FALSE;
+  DeleteContents();
+  Modify(FALSE);
+  SetDocumentSaved(FALSE);
+
+  wxString name;
+  GetDocumentManager()->MakeDefaultName(name);
+  SetTitle(name);
+  SetFilename(name, TRUE);
+
+  return TRUE;
+}
+
+bool wxDocument::Save(void)
+{
+  bool ret = FALSE;
+
+  if (!IsModified()) return TRUE;
+  if (m_documentFile == "" || !m_savedYet)
+    ret = SaveAs();
+  else
+    ret = OnSaveDocument(m_documentFile);
+  if ( ret )
+    SetDocumentSaved(TRUE);
+  return ret;
+}
+	
+bool wxDocument::SaveAs(void)
+{
+  wxDocTemplate *docTemplate = GetDocumentTemplate();
+  if (!docTemplate)
+    return FALSE;
+  
+  char *tmp = wxFileSelector("Save as", docTemplate->GetDirectory(), GetFilename(),
+    docTemplate->GetDefaultExtension(), docTemplate->GetFileFilter(),
+    0, GetDocumentWindow());
+    
+  if (!tmp)
+    return FALSE;
+  else
+  {
+    SetFilename(tmp);
+    SetTitle(wxFileNameFromPath(tmp));
+    
+    GetDocumentManager()->AddFileToHistory(tmp);
+
+    // Notify the views that the filename has changed
+    wxNode *node = m_documentViews.First();
+    while (node)
+    {
+      wxView *view = (wxView *)node->Data();
+      view->OnChangeFilename();
+      node = node->Next();
+    }
+  }
+  return OnSaveDocument(m_documentFile);
+}
+	
+bool wxDocument::OnSaveDocument(const wxString& file)
+{
+  if (file == "")
+    return FALSE;
+
+  wxString msgTitle;
+  if (wxTheApp->GetAppName() != "")
+    msgTitle = wxTheApp->GetAppName();
+  else
+    msgTitle = wxString("File error");
+
+  ofstream store(file);
+  if (store.fail() || store.bad())
+  {
+    (void)wxMessageBox("Sorry, could not open this file for saving.", msgTitle, wxOK | wxICON_EXCLAMATION,
+      GetDocumentWindow());
+    // Saving error
+    return FALSE;
+  }
+  if (SaveObject(store)==FALSE)
+  {
+    (void)wxMessageBox("Sorry, could not save this file.", msgTitle, wxOK | wxICON_EXCLAMATION,
+      GetDocumentWindow());
+    // Saving error
+    return FALSE;
+  }
+  Modify(FALSE);
+  SetFilename(file);
+  return TRUE;
+}
+	
+bool wxDocument::OnOpenDocument(const wxString& file)
+{
+  if (!OnSaveModified())
+    return FALSE;
+
+  wxString msgTitle;
+  if (wxTheApp->GetAppName() != "")
+    msgTitle = wxTheApp->GetAppName();
+  else
+    msgTitle = wxString("File error");
+
+  ifstream store(file);
+  if (store.fail() || store.bad())
+  {
+    (void)wxMessageBox("Sorry, could not open this file.", msgTitle, wxOK|wxICON_EXCLAMATION,
+     GetDocumentWindow());
+    return FALSE;
+  }
+  if (LoadObject(store)==FALSE)
+  {
+    (void)wxMessageBox("Sorry, could not open this file.", msgTitle, wxOK|wxICON_EXCLAMATION,
+      GetDocumentWindow());
+    return FALSE;
+  }
+  SetFilename(file, TRUE);
+  Modify(FALSE);
+
+  UpdateAllViews();
+  
+  return TRUE;
+}
+	
+istream& wxDocument::LoadObject(istream& stream)
+{
+//  wxObject::LoadObject(stream);
+
+  return stream;
+}
+
+ostream& wxDocument::SaveObject(ostream& stream)
+{
+//  wxObject::SaveObject(stream);
+  
+  return stream;
+}
+
+bool wxDocument::Revert(void)
+{
+  return FALSE;
+}
+
+
+// Get title, or filename if no title, else unnamed
+bool wxDocument::GetPrintableName(wxString& buf) const
+{
+  if (m_documentTitle != "")
+  {
+    buf = m_documentTitle;
+    return TRUE;
+  }
+  else if (m_documentFile != "")
+  {
+    buf = wxFileNameFromPath(m_documentFile);
+    return TRUE;
+  }
+  else
+  {
+    buf = "unnamed";
+    return TRUE;
+  }
+}
+
+wxWindow *wxDocument::GetDocumentWindow(void) const
+{
+  wxView *view = GetFirstView();
+  if (view)
+    return view->GetFrame();
+  else
+    return wxTheApp->GetTopWindow();
+}
+
+wxCommandProcessor *wxDocument::OnCreateCommandProcessor(void)
+{
+  return new wxCommandProcessor;
+}
+
+// TRUE if safe to close
+bool wxDocument::OnSaveModified(void)
+{
+  if (IsModified())
+  {
+    char buf[400];
+    wxString title;
+    GetPrintableName(title);
+
+    wxString msgTitle;
+    if (wxTheApp->GetAppName() != "")
+      msgTitle = wxTheApp->GetAppName();
+    else
+      msgTitle = wxString("Warning");
+
+    sprintf(buf, "Do you want to save changes to document %s?", (const char *)title);
+    int res = wxMessageBox(buf, msgTitle, wxYES_NO|wxCANCEL|wxICON_QUESTION,
+      GetDocumentWindow());
+    if (res == wxNO)
+    {
+      Modify(FALSE);
+      return TRUE;
+    }
+    else if (res == wxYES)
+      return Save();
+    else if (res == wxCANCEL)
+      return FALSE;
+  }
+  return TRUE;
+}
+
+bool wxDocument::Draw(wxDC& WXUNUSED(context))
+{
+  return TRUE;
+}
+
+bool wxDocument::AddView(wxView *view)
+{
+  if (!m_documentViews.Member(view))
+  {
+    m_documentViews.Append(view);
+    OnChangedViewList();
+  }
+  return TRUE;
+}
+
+bool wxDocument::RemoveView(wxView *view)
+{
+  (void)m_documentViews.DeleteObject(view);
+  OnChangedViewList();
+  return TRUE;
+}
+
+bool wxDocument::OnCreate(const wxString& WXUNUSED(path), long flags)
+{
+  if (GetDocumentTemplate()->CreateView(this, flags))
+    return TRUE;
+  else
+    return FALSE;
+}
+
+// Called after a view is added or removed.
+// The default implementation deletes the document if
+// there are no more views.
+void wxDocument::OnChangedViewList(void)
+{
+  if (m_documentViews.Number() == 0)
+  {
+    if (OnSaveModified())
+    {
+      delete this;
+    }
+  }
+}
+
+void wxDocument::UpdateAllViews(wxView *sender, wxObject *hint)
+{
+  wxNode *node = m_documentViews.First();
+  while (node)
+  {
+    wxView *view = (wxView *)node->Data();
+    view->OnUpdate(sender, hint);
+    node = node->Next();
+  }
+}
+
+void wxDocument::SetFilename(const wxString& filename, bool notifyViews)
+{
+  m_documentFile = filename;
+  if ( notifyViews )
+  {
+    // Notify the views that the filename has changed
+    wxNode *node = m_documentViews.First();
+    while (node)
+    {
+      wxView *view = (wxView *)node->Data();
+      view->OnChangeFilename();
+      node = node->Next();
+    }
+  }
+}
+
+
+/*
+ * Document view
+ */
+ 
+wxView::wxView(wxDocument *doc)
+{
+  SetDocument(doc);
+  
+  m_viewTypeName = "";
+  m_viewFrame = NULL;
+}
+
+wxView::~wxView(void)
+{
+  GetDocumentManager()->ActivateView(this, FALSE, TRUE);
+  m_viewDocument->RemoveView(this);
+}
+
+// Extend event processing to search the document's event table
+bool wxView::ProcessEvent(wxEvent& event)
+{
+	if ( !GetDocument() || !GetDocument()->ProcessEvent(event) )
+		return wxEvtHandler::ProcessEvent(event);
+	else
+		return TRUE;
+}
+
+void wxView::OnActivateView(bool WXUNUSED(activate), wxView *WXUNUSED(activeView), wxView *WXUNUSED(deactiveView))
+{
+}
+
+void wxView::OnPrint(wxDC *dc, wxObject *WXUNUSED(info))
+{
+  OnDraw(dc);
+}
+
+void wxView::OnUpdate(wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint))
+{
+}
+
+void wxView::OnChangeFilename(void)
+{
+  if (GetFrame() && GetDocument())
+  {
+    wxString name;
+    GetDocument()->GetPrintableName(name);
+
+    // If the frame is an MDI child, just set the title
+    // to the name.
+    // Otherwise, append the document name to the name of the application
+#ifdef __WINDOWS__
+    if (GetFrame()->IsKindOf(CLASSINFO(wxMDIChildFrame)))
+#else
+    if (FALSE)
+#endif
+    {
+      GetFrame()->SetTitle(name);
+    }
+    else
+    {
+      if (wxTheApp->GetAppName() != "")
+      {
+        char buf[400];
+        sprintf(buf, "%s - %s", (const char *)wxTheApp->GetAppName(), (const char *)name);
+        GetFrame()->SetTitle(buf);
+      }
+      else
+        GetFrame()->SetTitle(name);
+    }
+  }
+}
+
+void wxView::SetDocument(wxDocument *doc)
+{
+  m_viewDocument = doc;
+  if (doc)
+    doc->AddView(this);
+}
+
+bool wxView::Close(bool deleteWindow)
+{
+  if (OnClose(deleteWindow))
+    return TRUE;
+  else
+    return FALSE;
+}
+
+void wxView::Activate(bool activate)
+{
+  if (GetDocumentManager())
+  {
+    OnActivateView(activate, this, GetDocumentManager()->GetCurrentView());
+    GetDocumentManager()->ActivateView(this, activate);
+  }
+}
+
+bool wxView::OnClose(bool WXUNUSED(deleteWindow))
+{
+  return GetDocument() ? GetDocument()->Close() : TRUE;
+}
+
+#if USE_PRINTING_ARCHITECTURE
+wxPrintout *wxView::OnCreatePrintout(void)
+{
+  return new wxDocPrintout(this);
+}
+#endif
+
+
+/*
+ * wxDocTemplate
+ */
+
+wxDocTemplate::wxDocTemplate(wxDocManager *manager, const wxString& descr,
+  const wxString& filter, const wxString& dir, const wxString& ext,
+  const wxString& docTypeName, const wxString& viewTypeName,
+  wxClassInfo *docClassInfo, wxClassInfo *viewClassInfo, long flags)
+{
+  m_documentManager = manager;
+  m_flags = flags;
+  m_description = descr;
+  m_directory = dir;
+  m_defaultExt = ext;
+  m_fileFilter = filter;
+  m_flags = flags;
+  m_docTypeName = docTypeName;
+  m_viewTypeName = viewTypeName;
+  m_documentManager->AssociateTemplate(this);
+
+  m_docClassInfo = docClassInfo;
+  m_viewClassInfo = viewClassInfo;
+}
+
+wxDocTemplate::~wxDocTemplate(void)
+{
+  m_documentManager->DisassociateTemplate(this);
+}
+  
+// Tries to dynamically construct an object of the right
+// class.
+wxDocument *wxDocTemplate::CreateDocument(const wxString& path, long flags)
+{
+  if (!m_docClassInfo)
+    return NULL;
+  wxDocument *doc = (wxDocument *)m_docClassInfo->CreateObject();
+  doc->SetFilename(path);
+  doc->SetDocumentTemplate(this);
+  GetDocumentManager()->AddDocument(doc);
+  doc->SetCommandProcessor(doc->OnCreateCommandProcessor());
+  
+  if (doc->OnCreate(path, flags))
+    return doc;
+  else
+  {
+    delete doc;
+    return NULL;
+  }
+}
+
+wxView *wxDocTemplate::CreateView(wxDocument *doc, long flags)
+{
+  if (!m_viewClassInfo)
+    return NULL;
+  wxView *view = (wxView *)m_viewClassInfo->CreateObject();
+  view->SetDocument(doc);
+  if (view->OnCreate(doc, flags))
+  {
+    return view;
+  }
+  else
+  {
+    delete view;
+    return NULL;
+  }
+}
+
+BEGIN_EVENT_TABLE(wxDocManager, wxEvtHandler)
+    EVT_MENU(wxID_OPEN, wxDocManager::OnFileOpen)
+    EVT_MENU(wxID_CLOSE, wxDocManager::OnFileClose)
+    EVT_MENU(wxID_REVERT, wxDocManager::OnFileRevert)
+    EVT_MENU(wxID_NEW, wxDocManager::OnFileNew)
+    EVT_MENU(wxID_SAVE, wxDocManager::OnFileSave)
+    EVT_MENU(wxID_SAVEAS, wxDocManager::OnFileSaveAs)
+    EVT_MENU(wxID_UNDO, wxDocManager::OnUndo)
+    EVT_MENU(wxID_REDO, wxDocManager::OnRedo)
+    EVT_MENU(wxID_PRINT, wxDocManager::OnPrint)
+    EVT_MENU(wxID_PRINT_SETUP, wxDocManager::OnPrintSetup)
+    EVT_MENU(wxID_PREVIEW, wxDocManager::OnPreview)
+END_EVENT_TABLE()
+
+wxDocManager::wxDocManager(long flags, bool initialize)
+{
+  m_defaultDocumentNameCounter = 1;
+  m_flags = flags;
+  m_currentView = NULL;
+  m_maxDocsOpen = 10000;
+  m_fileHistory = NULL;
+  if (initialize)
+    Initialize();
+}
+
+wxDocManager::~wxDocManager(void)
+{
+  Clear();
+  if (m_fileHistory)
+    delete m_fileHistory;
+}
+
+bool wxDocManager::Clear(bool force)
+{
+  wxNode *node = m_docs.First();
+  while (node)
+  {
+    wxDocument *doc = (wxDocument *)node->Data();
+    wxNode *next = node->Next();
+
+    if (!doc->Close() && !force)
+      return FALSE;
+
+    // Implicitly deletes the document when the last
+    // view is removed (deleted)
+    doc->DeleteAllViews();
+
+    // Check document is deleted
+    if (m_docs.Member(doc))
+      delete doc;
+
+    // This assumes that documents are not connected in
+    // any way, i.e. deleting one document does NOT
+    // delete another.
+    node = next;
+  }
+  node = m_templates.First();
+  while (node)
+  {
+        wxDocTemplate *templ = (wxDocTemplate*) node->Data();
+        wxNode* next = node->Next();
+        delete templ;
+        node = next;
+  }
+  return TRUE;
+}
+
+bool wxDocManager::Initialize(void)
+{
+  m_fileHistory = OnCreateFileHistory();
+  return TRUE;
+}
+
+wxFileHistory *wxDocManager::OnCreateFileHistory(void)
+{
+  return new wxFileHistory;
+}
+
+void wxDocManager::OnFileClose(wxCommandEvent& WXUNUSED(event))
+{
+  wxDocument *doc = GetCurrentDocument();
+  if (!doc)
+    return;
+  if (doc->Close())
+  {
+    doc->DeleteAllViews();
+    if (m_docs.Member(doc))
+      delete doc;
+  }
+}
+
+void wxDocManager::OnFileNew(wxCommandEvent& WXUNUSED(event))
+{
+  CreateDocument(wxString(""), wxDOC_NEW);
+}
+
+void wxDocManager::OnFileOpen(wxCommandEvent& WXUNUSED(event))
+{
+  CreateDocument(wxString(""), 0);
+}
+
+void wxDocManager::OnFileRevert(wxCommandEvent& WXUNUSED(event))
+{
+  wxDocument *doc = GetCurrentDocument();
+  if (!doc)
+    return;
+  doc->Revert();
+}
+
+void wxDocManager::OnFileSave(wxCommandEvent& WXUNUSED(event))
+{
+  wxDocument *doc = GetCurrentDocument();
+  if (!doc)
+    return;
+  doc->Save();
+}
+
+void wxDocManager::OnFileSaveAs(wxCommandEvent& WXUNUSED(event))
+{
+  wxDocument *doc = GetCurrentDocument();
+  if (!doc)
+    return;
+  doc->SaveAs();
+}
+
+void wxDocManager::OnPrint(wxCommandEvent& WXUNUSED(event))
+{
+  wxView *view = GetCurrentView();
+  if (!view)
+    return;
+
+  wxPrintout *printout = view->OnCreatePrintout();
+  if (printout)
+  {
+    // TODO: trouble about this is that it pulls in the postscript
+    // code unecessarily
+#ifdef __WINDOWS__
+    if ( wxTheApp->GetPrintMode() == wxPRINT_WINDOWS )
+    {
+      wxWindowsPrinter printer;
+      printer.Print(view->GetFrame(), printout, TRUE);
+    }
+    else
+#endif
+    {
+      wxPostScriptPrinter printer;
+      printer.Print(view->GetFrame(), printout, TRUE);
+    }
+
+    delete printout;
+  }
+}
+
+void wxDocManager::OnPrintSetup(wxCommandEvent& WXUNUSED(event))
+{
+  wxWindow *parentWin = wxTheApp->GetTopWindow();
+  wxView *view = GetCurrentView();
+  if (view)
+    parentWin = view->GetFrame();
+
+  wxPrintData data;
+
+#ifdef __WINDOWS__
+  if ( wxTheApp->GetPrintMode() == wxPRINT_WINDOWS )
+  {
+    wxPrintDialog printerDialog(parentWin, & data);
+    printerDialog.GetPrintData().SetSetupDialog(TRUE);
+    printerDialog.ShowModal();
+  }
+  else
+#endif
+  {
+    wxGenericPrintDialog printerDialog(parentWin, & data);
+    printerDialog.GetPrintData().SetSetupDialog(TRUE);
+    printerDialog.ShowModal();
+  }
+}
+
+void wxDocManager::OnPreview(wxCommandEvent& WXUNUSED(event))
+{
+  wxView *view = GetCurrentView();
+  if (!view)
+    return;
+
+  wxPrintout *printout = view->OnCreatePrintout();
+  if (printout)
+  {
+    // Pass two printout objects: for preview, and possible printing.
+    wxPrintPreviewBase *preview = NULL;
+#ifdef __WINDOWS__
+    if ( wxTheApp->GetPrintMode() == wxPRINT_WINDOWS )
+        preview = new wxWindowsPrintPreview(printout, view->OnCreatePrintout());
+    else
+#endif
+        preview = new wxPostScriptPrintPreview(printout, view->OnCreatePrintout());
+
+    wxPreviewFrame *frame = new wxPreviewFrame(preview, (wxFrame *)wxTheApp->GetTopWindow(), "Print Preview",
+		wxPoint(100, 100), wxSize(600, 650));
+    frame->Centre(wxBOTH);
+    frame->Initialize();
+    frame->Show(TRUE);
+  }
+}
+
+void wxDocManager::OnUndo(wxCommandEvent& WXUNUSED(event))
+{
+  wxDocument *doc = GetCurrentDocument();
+  if (!doc)
+    return;
+  if (doc->GetCommandProcessor())
+    doc->GetCommandProcessor()->Undo();
+}
+
+void wxDocManager::OnRedo(wxCommandEvent& WXUNUSED(event))
+{
+  wxDocument *doc = GetCurrentDocument();
+  if (!doc)
+    return;
+  if (doc->GetCommandProcessor())
+    doc->GetCommandProcessor()->Redo();
+}
+
+wxDocument *wxDocManager::CreateDocument(const wxString& path, long flags)
+{
+  wxDocTemplate **templates = new wxDocTemplate *[m_templates.Number()];
+  int i;
+  int n = 0;
+  for (i = 0; i < m_templates.Number(); i++)
+  {
+    wxDocTemplate *temp = (wxDocTemplate *)(m_templates.Nth(i)->Data());
+    if (temp->IsVisible())
+    {
+      templates[n] = temp;
+      n ++;
+    }
+  }
+  if (n == 0)
+  {
+    delete[] templates;
+    return NULL;
+  }
+
+  // If we've reached the max number of docs, close the
+  // first one.
+  if (GetDocuments().Number() >= m_maxDocsOpen)
+  {
+    wxDocument *doc = (wxDocument *)GetDocuments().First()->Data();
+    if (doc->Close())
+    {
+      // Implicitly deletes the document when
+      // the last view is deleted
+      doc->DeleteAllViews();
+
+      // Check we're really deleted
+      if (m_docs.Member(doc))
+        delete doc;
+    }
+    else
+      return NULL;
+  }
+  
+  // New document: user chooses a template, unless there's only one.
+  if (flags & wxDOC_NEW)
+  {
+    if (n == 1)
+    {
+      wxDocTemplate *temp = templates[0];
+      delete[] templates;
+      wxDocument *newDoc = temp->CreateDocument(path, flags);
+      if (newDoc)
+      {
+        newDoc->SetDocumentName(temp->GetDocumentName());
+        newDoc->SetDocumentTemplate(temp);
+        newDoc->OnNewDocument();
+      }
+      return newDoc;
+    }
+
+    wxDocTemplate *temp = SelectDocumentType(templates, n);
+    delete[] templates;
+    if (temp)
+    {
+      wxDocument *newDoc = temp->CreateDocument(path, flags);
+      if (newDoc)
+      {
+        newDoc->SetDocumentName(temp->GetDocumentName());
+        newDoc->SetDocumentTemplate(temp);
+        newDoc->OnNewDocument();
+      }
+      return newDoc;
+    }
+    else
+      return NULL;
+  }
+
+  // Existing document
+  wxDocTemplate *temp = NULL;
+
+  wxString path2("");
+  if (path != "")
+    path2 = path;
+
+  if (flags & wxDOC_SILENT)
+    temp = FindTemplateForPath(path2);
+  else
+    temp = SelectDocumentPath(templates, n, path2, flags);
+
+  delete[] templates;
+
+  if (temp)
+  {
+    wxDocument *newDoc = temp->CreateDocument(path2, flags);
+    if (newDoc)
+    {
+      newDoc->SetDocumentName(temp->GetDocumentName());
+      newDoc->SetDocumentTemplate(temp);
+      if (!newDoc->OnOpenDocument(path2))
+      {
+        delete newDoc;
+        return NULL;
+      }
+      AddFileToHistory(path2);
+    }
+    return newDoc;
+  }
+  else
+    return NULL;
+}
+
+wxView *wxDocManager::CreateView(wxDocument *doc, long flags)
+{
+  wxDocTemplate **templates = new wxDocTemplate *[m_templates.Number()];
+  int n =0;
+  int i;
+  for (i = 0; i < m_templates.Number(); i++)
+  {
+    wxDocTemplate *temp = (wxDocTemplate *)(m_templates.Nth(i)->Data());
+    if (temp->IsVisible())
+    {
+      if (temp->GetDocumentName() == doc->GetDocumentName())
+      {
+        templates[n] = temp;
+        n ++;
+      }
+    }
+  }
+  if (n == 0)
+  {
+    delete[] templates;
+    return NULL;
+  }
+  if (n == 1)
+  {
+    wxDocTemplate *temp = templates[0];
+    delete[] templates;
+    wxView *view = temp->CreateView(doc, flags);
+    if (view)
+      view->SetViewName(temp->GetViewName());
+    return view;
+  }
+  
+  wxDocTemplate *temp = SelectViewType(templates, n);
+  delete[] templates;
+  if (temp)
+  {
+    wxView *view = temp->CreateView(doc, flags);
+    if (view)
+      view->SetViewName(temp->GetViewName());
+    return view;
+  }
+  else
+    return NULL;
+}
+
+// Not yet implemented
+void wxDocManager::DeleteTemplate(wxDocTemplate *WXUNUSED(temp), long WXUNUSED(flags))
+{
+}
+
+// Not yet implemented
+bool wxDocManager::FlushDoc(wxDocument *WXUNUSED(doc))
+{
+  return FALSE;
+}
+
+wxDocument *wxDocManager::GetCurrentDocument(void) const
+{
+  if (m_currentView)
+    return m_currentView->GetDocument();
+  else
+    return NULL;
+}
+
+// Make a default document name
+bool wxDocManager::MakeDefaultName(wxString& name)
+{
+  char buf[256];
+  sprintf(buf, "unnamed%d", m_defaultDocumentNameCounter);
+  m_defaultDocumentNameCounter ++;
+  name = buf;
+  return TRUE;
+}
+
+// Not yet implemented
+wxDocTemplate *wxDocManager::MatchTemplate(const wxString& WXUNUSED(path))
+{
+  return NULL;
+}
+
+// File history management
+void wxDocManager::AddFileToHistory(const wxString& file)
+{
+  if (m_fileHistory)
+    m_fileHistory->AddFileToHistory(file);
+}
+
+wxString wxDocManager::GetHistoryFile(int i) const
+{
+  if (m_fileHistory)
+    return wxString(m_fileHistory->GetHistoryFile(i));
+  else
+    return wxString("");
+}
+
+void wxDocManager::FileHistoryUseMenu(wxMenu *menu)
+{
+  if (m_fileHistory)
+    m_fileHistory->FileHistoryUseMenu(menu);
+}
+
+void wxDocManager::FileHistoryLoad(const wxString& resourceFile, const wxString& section)
+{
+  if (m_fileHistory)
+    m_fileHistory->FileHistoryLoad(resourceFile, section);
+}
+
+void wxDocManager::FileHistorySave(const wxString& resourceFile, const wxString& section)
+{
+  if (m_fileHistory)
+    m_fileHistory->FileHistorySave(resourceFile, section);
+}
+
+int wxDocManager::GetNoHistoryFiles(void) const
+{
+  if (m_fileHistory)
+    return m_fileHistory->GetNoHistoryFiles();
+  else
+    return 0;
+}
+
+static char *FindExtension(char *path)
+{
+  static char ext[10];
+  int len = strlen(path);
+  if (path)
+  {
+    int i = 0;
+    for (i = (len-1); i > 0; i --)
+      if (path[i] == '.')
+        break;
+    if (path[i] == '.')
+    {
+      int j;
+      for (j = i+1; j < len; j++)
+        ext[(int)(j-(i+1))] = (char)wxToLower(path[j]); // NOTE Should not use tolower under UNIX
+      ext[j-(i+1)] = 0;
+      return ext;
+    }
+    else
+      return NULL;
+  }
+  else return NULL;
+}
+
+
+// Given a path, try to find a matching template. Won't
+// always work, of course.
+wxDocTemplate *wxDocManager::FindTemplateForPath(const wxString& path)
+{
+  char *theExt = FindExtension((char *)(const char *)path);
+  if (!theExt)
+    return NULL;
+  wxDocTemplate *theTemplate = NULL;
+
+  if (m_templates.Number() == 1)
+    return (wxDocTemplate *)m_templates.First()->Data();
+
+  // Find the template which this extension corresponds to
+  int i;
+  for (i = 0; i < m_templates.Number(); i++)
+  {
+    wxDocTemplate *temp = (wxDocTemplate *)m_templates.Nth(i)->Data();
+    if (strcmp(temp->GetDefaultExtension(), theExt) == 0)
+    {
+      theTemplate = temp;
+      break;
+    }
+  }
+  return theTemplate;
+}
+
+// Prompts user to open a file, using file specs in templates.
+// How to implement in wxWindows? Must extend the file selector
+// dialog or implement own; OR match the extension to the
+// template extension.
+wxDocTemplate *wxDocManager::SelectDocumentPath(wxDocTemplate **templates,
+    int noTemplates, wxString& path, long WXUNUSED(flags), bool WXUNUSED(save))
+{
+  // We can only have multiple filters in Windows
+#ifdef __WINDOWS__
+  char *descrBuf = new char[1000];
+  descrBuf[0] = 0;
+  int i;
+  for (i = 0; i < noTemplates; i++)
+  {
+    if (templates[i]->IsVisible())
+    {
+      strcat(descrBuf, templates[i]->GetDescription());
+      strcat(descrBuf, " (");
+      strcat(descrBuf, templates[i]->GetFileFilter());
+      strcat(descrBuf, ") ");
+      strcat(descrBuf, "|");
+      strcat(descrBuf, templates[i]->GetFileFilter());
+      strcat(descrBuf, "|");
+    }
+  }
+  int len = strlen(descrBuf);
+  if (len > 0)
+    // Omit final "|"
+    descrBuf[len-1] = 0;
+
+  char *pathTmp = wxFileSelector("Select a file", "", "", "", descrBuf, 0, wxTheApp->GetTopWindow());
+  delete[] descrBuf;
+  if (pathTmp)
+  {
+    path = pathTmp;
+    char *theExt = FindExtension((char *)(const char *)path);
+    if (!theExt)
+      return NULL;
+
+    // This is dodgy in that we're selecting the template on the
+    // basis of the file extension, which may not be a standard
+    // one. We really want to know exactly which template was
+    // chosen by using a more advanced file selector.
+    wxDocTemplate *theTemplate = FindTemplateForPath(path);
+    return theTemplate;
+  }
+  else
+  {
+    path = "";
+    return NULL;
+  }
+#else
+  // In all other windowing systems, until we have more advanced
+  // file selectors, we must select the document type (template) first, and
+  // _then_ pop up the file selector.
+  wxDocTemplate *temp = SelectDocumentType(templates, noTemplates);
+  if (!temp)
+    return NULL;
+
+  char *pathTmp = wxFileSelector("Select a file", "", "",
+     temp->GetDefaultExtension(),
+     temp->GetFileFilter(),
+     0, wxTheApp->GetTopWindow());
+
+  if (pathTmp)
+  {
+    path = pathTmp;
+    return temp;
+  }
+  else
+    return NULL;
+#endif
+}
+
+wxDocTemplate *wxDocManager::SelectDocumentType(wxDocTemplate **templates,
+    int noTemplates)
+{
+  char **strings = new char *[noTemplates];
+  char **data = new char *[noTemplates];
+  int i;
+  int n = 0;
+  for (i = 0; i < noTemplates; i++)
+  {
+    if (templates[i]->IsVisible())
+    {
+      strings[n] = WXSTRINGCAST templates[i]->m_description;
+      data[n] = (char *)templates[i];
+      n ++;
+    }
+  }
+  if (n == 0)
+  {
+    delete[] strings;
+    delete[] data;
+    return NULL;
+  }
+  else if (n == 1)
+  {
+    wxDocTemplate *temp = (wxDocTemplate *)data[0];
+    delete[] strings;
+    delete[] data;
+    return temp;
+  }
+  
+  wxDocTemplate *theTemplate = (wxDocTemplate *)wxGetSingleChoiceData("Select a document template", "Templates", n,
+    strings, data);
+  delete[] strings;
+  delete[] data;
+  return theTemplate;
+}
+
+wxDocTemplate *wxDocManager::SelectViewType(wxDocTemplate **templates,
+    int noTemplates)
+{
+  char **strings = new char *[noTemplates];
+  char **data = new char *[noTemplates];
+  int i;
+  int n = 0;
+  for (i = 0; i < noTemplates; i++)
+  {
+    if (templates[i]->IsVisible() && templates[i]->GetViewName())
+    {
+      strings[n] = WXSTRINGCAST templates[i]->m_viewTypeName;
+      data[n] = (char *)templates[i];
+      n ++;
+    }
+  }
+  wxDocTemplate *theTemplate = (wxDocTemplate *)wxGetSingleChoiceData("Select a document view", "Views", n,
+    strings, data);
+  delete[] strings;
+  delete[] data;
+  return theTemplate;
+}
+
+void wxDocManager::AssociateTemplate(wxDocTemplate *temp)
+{
+  if (!m_templates.Member(temp))
+    m_templates.Append(temp);
+}
+
+void wxDocManager::DisassociateTemplate(wxDocTemplate *temp)
+{
+  m_templates.DeleteObject(temp);
+}
+
+// Add and remove a document from the manager's list
+void wxDocManager::AddDocument(wxDocument *doc)
+{
+  if (!m_docs.Member(doc))
+    m_docs.Append(doc);
+}
+
+void wxDocManager::RemoveDocument(wxDocument *doc)
+{
+  m_docs.DeleteObject(doc);
+}
+
+// Views or windows should inform the document manager
+// when a view is going in or out of focus
+void wxDocManager::ActivateView(wxView *view, bool activate, bool WXUNUSED(deleting))
+{
+  // If we're deactiving, and if we're not actually deleting the view, then
+  // don't reset the current view because we may be going to
+  // a window without a view.
+  // WHAT DID I MEAN BY THAT EXACTLY?
+/*
+  if (deleting)
+  {
+    if (m_currentView == view)
+      m_currentView = NULL;
+  }
+  else
+*/
+  {
+    if (activate)
+      m_currentView = view;
+    else
+      m_currentView = NULL;
+  }
+}
+
+/*
+ * Default document child frame
+ */
+
+BEGIN_EVENT_TABLE(wxDocChildFrame, wxFrame)
+    EVT_ACTIVATE(wxDocChildFrame::OnActivate)
+END_EVENT_TABLE()
+
+wxDocChildFrame::wxDocChildFrame(wxDocument *doc, wxView *view, wxFrame *frame, const wxString& title,
+  const wxPoint& pos, const wxSize& size, const long style, const wxString& name):
+    wxFrame(frame, -1, title, pos, size, style, name)
+{
+  m_childDocument = doc;
+  m_childView = view;
+  if (view)
+    view->SetFrame(this);
+}
+
+wxDocChildFrame::~wxDocChildFrame(void)
+{
+}
+
+// Extend event processing to search the view's event table
+bool wxDocChildFrame::ProcessEvent(wxEvent& event)
+{
+    if (m_childView)
+        m_childView->Activate(TRUE);
+
+	if ( !m_childView || ! m_childView->ProcessEvent(event) )
+    {
+        // Only hand up to the parent if it's a menu command
+        if (!event.IsKindOf(CLASSINFO(wxCommandEvent)) || !GetParent() || !GetParent()->ProcessEvent(event))
+		    return wxEvtHandler::ProcessEvent(event);
+        else
+            return TRUE;
+    }
+	else
+		return TRUE;
+}
+
+/*
+// Intercept menu commands
+void wxDocChildFrame::OldOnMenuCommand(int id)
+{
+  if (m_childView)
+    m_childView->Activate(TRUE);
+
+  if (GetParent())
+    ((wxFrame *)GetParent())->OldOnMenuCommand(id);
+}
+*/
+
+void wxDocChildFrame::OnActivate(wxActivateEvent& event)
+{
+  wxFrame::OnActivate(event);
+
+  if (m_childView)
+    m_childView->Activate(event.GetActive());
+}
+
+bool wxDocChildFrame::OnClose(void)
+{
+  // Close view but don't delete the frame while doing so!
+  // ...since it will be deleted by wxWindows if we return TRUE.
+  if (m_childView)
+  {
+    bool ans = m_childView->Close(FALSE); // FALSE means don't delete associated window
+    if (ans)
+    {
+      m_childView->Activate(FALSE);
+      delete m_childView;
+      m_childView = NULL;
+      m_childDocument = NULL;
+    }
+    
+    return ans;
+  }
+  else return TRUE;
+}
+
+/*
+ * Default parent frame
+ */
+
+BEGIN_EVENT_TABLE(wxDocParentFrame, wxFrame)
+    EVT_MENU(wxID_EXIT, wxDocParentFrame::OnExit)
+    EVT_MENU_RANGE(wxID_FILE1, wxID_FILE2, wxDocParentFrame::OnMRUFile)
+END_EVENT_TABLE()
+
+wxDocParentFrame::wxDocParentFrame(wxDocManager *manager, wxFrame *frame, const wxString& title,
+  const wxPoint& pos, const wxSize& size, const long style, const wxString& name):
+  wxFrame(frame, -1, title, pos, size, style, name)
+{
+  m_docManager = manager;
+}
+
+void wxDocParentFrame::OnExit(wxCommandEvent& WXUNUSED(event))
+{
+    Close();
+}
+
+void wxDocParentFrame::OnMRUFile(wxCommandEvent& event)
+{
+      wxString f(m_docManager->GetHistoryFile(event.GetSelection() - wxID_FILE1));
+      if (f != "")
+        (void)m_docManager->CreateDocument(f, wxDOC_SILENT);
+}
+
+// Extend event processing to search the view's event table
+bool wxDocParentFrame::ProcessEvent(wxEvent& event)
+{
+    // Try the document manager, then do default processing
+    if (!m_docManager || !m_docManager->ProcessEvent(event))
+        return wxEvtHandler::ProcessEvent(event);
+    else
+        return TRUE;
+}
+
+/*
+// Intercept menu commands
+void wxDocParentFrame::OldOnMenuCommand(int id)
+{
+  switch (id)
+  {
+    case wxID_EXIT:
+    {
+      Close();
+      break;
+    }
+    case wxID_FILE1:
+    case wxID_FILE2:
+    case wxID_FILE3:
+    case wxID_FILE4:
+    case wxID_FILE5:
+    case wxID_FILE6:
+    case wxID_FILE7:
+    case wxID_FILE8:
+    case wxID_FILE9:
+    {
+      wxString f(m_docManager->GetHistoryFile(id-wxID_FILE1));
+      if (f != "")
+        (void)m_docManager->CreateDocument(f, wxDOC_SILENT);
+      break;
+    }
+    default:
+    {
+      m_docManager->OldOnMenuCommand(id);
+    }
+  }
+}
+*/
+
+// Define the behaviour for the frame closing
+// - must delete all frames except for the main one.
+bool wxDocParentFrame::OnClose(void)
+{
+  return m_docManager->Clear(FALSE);
+}
+
+#if USE_PRINTING_ARCHITECTURE
+
+wxDocPrintout::wxDocPrintout(wxView *view, const wxString& title):
+  wxPrintout(WXSTRINGCAST title)
+{
+  m_printoutView = view;
+}
+
+bool wxDocPrintout::OnPrintPage(int WXUNUSED(page))
+{
+  wxDC *dc = GetDC();
+  
+  // Get the logical pixels per inch of screen and printer
+  int ppiScreenX, ppiScreenY;
+  GetPPIScreen(&ppiScreenX, &ppiScreenY);
+  int ppiPrinterX, ppiPrinterY;
+  GetPPIPrinter(&ppiPrinterX, &ppiPrinterY);
+
+  // This scales the DC so that the printout roughly represents the
+  // the screen scaling. The text point size _should_ be the right size
+  // but in fact is too small for some reason. This is a detail that will
+  // need to be addressed at some point but can be fudged for the
+  // moment.
+  float scale = (float)((float)ppiPrinterX/(float)ppiScreenX);
+
+  // Now we have to check in case our real page size is reduced
+  // (e.g. because we're drawing to a print preview memory DC)
+  int pageWidth, pageHeight;
+  int w, h;
+  dc->GetSize(&w, &h);
+  GetPageSizePixels(&pageWidth, &pageHeight);
+
+  // If printer pageWidth == current DC width, then this doesn't
+  // change. But w might be the preview bitmap width, so scale down.
+  float overallScale = scale * (float)(w/(float)pageWidth);
+  dc->SetUserScale(overallScale, overallScale);
+
+  if (m_printoutView)
+  {
+    m_printoutView->OnDraw(dc);
+  }
+  return TRUE;
+}
+
+bool wxDocPrintout::HasPage(int pageNum)
+{
+  return (pageNum == 1);
+}
+
+bool wxDocPrintout::OnBeginDocument(int startPage, int endPage)
+{
+  if (!wxPrintout::OnBeginDocument(startPage, endPage))
+    return FALSE;
+
+  return TRUE;
+}
+
+void wxDocPrintout::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo)
+{
+  *minPage = 1;
+  *maxPage = 1;
+  *selPageFrom = 1;
+  *selPageTo = 1;
+}
+
+#endif
+
+/*
+ * Command processing framework
+ */
+
+wxCommand::wxCommand(bool canUndoIt, const wxString& name)
+{
+  m_canUndo = canUndoIt;
+  m_commandName = name;
+}
+
+wxCommand::~wxCommand(void)
+{
+}
+
+// Command processor
+wxCommandProcessor::wxCommandProcessor(int maxCommands)
+{
+  m_maxNoCommands = maxCommands;
+  m_currentCommand = NULL;
+  m_commandEditMenu = NULL;
+}
+
+wxCommandProcessor::~wxCommandProcessor(void)
+{
+  ClearCommands();
+}
+
+// Pass a command to the processor. The processor calls Do();
+// if successful, is appended to the command history unless
+// storeIt is FALSE.
+bool wxCommandProcessor::Submit(wxCommand *command, bool storeIt)
+{
+  bool success = command->Do();
+  if (success && storeIt)
+  {
+    if (m_commands.Number() == m_maxNoCommands)
+    {
+      wxNode *firstNode = m_commands.First();
+      wxCommand *firstCommand = (wxCommand *)firstNode->Data();
+      delete firstCommand;
+      delete firstNode;
+    }
+
+    // Correct a bug: we must chop off the current 'branch'
+    // so that we're at the end of the command list.
+    if (!m_currentCommand)
+      ClearCommands();
+    else
+    {
+      wxNode *node = m_currentCommand->Next();
+      while (node)
+      {
+        wxNode *next = node->Next();
+        delete (wxCommand *)node->Data();
+        delete node;
+        node = next;
+      }
+    }
+    
+    m_commands.Append(command);
+    m_currentCommand = m_commands.Last();
+    SetMenuStrings();
+  }
+  return success;
+}
+
+bool wxCommandProcessor::Undo(void)
+{
+  if (m_currentCommand)
+  {
+    wxCommand *command = (wxCommand *)m_currentCommand->Data();
+    if (command->CanUndo())
+    {
+      bool success = command->Undo();
+      if (success)
+      {
+        m_currentCommand = m_currentCommand->Previous();
+        SetMenuStrings();
+        return TRUE;
+      }
+    }
+  }
+  return FALSE;
+}
+
+bool wxCommandProcessor::Redo(void)
+{
+  wxCommand *redoCommand = NULL;
+  wxNode *redoNode = NULL;
+  if (m_currentCommand && m_currentCommand->Next())
+  {
+    redoCommand = (wxCommand *)m_currentCommand->Next()->Data();
+    redoNode = m_currentCommand->Next();
+  }
+  else
+  {
+    if (m_commands.Number() > 0)
+    {
+      redoCommand = (wxCommand *)m_commands.First()->Data();
+      redoNode = m_commands.First();
+    }
+  }
+
+  if (redoCommand)
+  {
+    bool success = redoCommand->Do();
+    if (success)
+    {
+      m_currentCommand = redoNode;
+      SetMenuStrings();
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+bool wxCommandProcessor::CanUndo(void)
+{
+  if (m_currentCommand)
+    return ((wxCommand *)m_currentCommand->Data())->CanUndo();
+  return FALSE;
+}
+
+void wxCommandProcessor::Initialize(void)
+{
+  m_currentCommand = m_commands.Last();
+  SetMenuStrings();
+}
+
+void wxCommandProcessor::SetMenuStrings(void)
+{
+  if (m_commandEditMenu)
+  {
+    wxString buf;
+    if (m_currentCommand)
+    {
+      wxCommand *command = (wxCommand *)m_currentCommand->Data();
+      wxString commandName(command->GetName());
+      if (commandName == "") commandName = "Unnamed command";
+      bool canUndo = command->CanUndo();
+      if (canUndo)
+        buf = wxString("&Undo ") + commandName;
+      else
+        buf = wxString("Can't &Undo ") + commandName;
+        
+      m_commandEditMenu->SetLabel(wxID_UNDO, buf);
+      m_commandEditMenu->Enable(wxID_UNDO, canUndo);
+      
+      // We can redo, if we're not at the end of the history.
+      if (m_currentCommand->Next())
+      {
+        wxCommand *redoCommand = (wxCommand *)m_currentCommand->Next()->Data();
+        wxString redoCommandName(redoCommand->GetName());
+        if (redoCommandName == "") redoCommandName = "Unnamed command";
+        buf = wxString("&Redo ") + redoCommandName;
+        m_commandEditMenu->SetLabel(wxID_REDO, buf);
+        m_commandEditMenu->Enable(wxID_REDO, TRUE);
+      }
+      else
+      {
+        m_commandEditMenu->SetLabel(wxID_REDO, "&Redo");
+        m_commandEditMenu->Enable(wxID_REDO, FALSE);
+      }
+    }
+    else
+    {
+      m_commandEditMenu->SetLabel(wxID_UNDO, "&Undo");
+      m_commandEditMenu->Enable(wxID_UNDO, FALSE);
+
+      if (m_commands.Number() == 0)
+      {
+        m_commandEditMenu->SetLabel(wxID_REDO, "&Redo");
+        m_commandEditMenu->Enable(wxID_REDO, FALSE);
+      }
+      else
+      {
+        // currentCommand is NULL but there are commands: this means that
+        // we've undone to the start of the list, but can redo the first.
+        wxCommand *redoCommand = (wxCommand *)m_commands.First()->Data();
+        wxString redoCommandName(redoCommand->GetName());
+        if (!redoCommandName) redoCommandName = "Unnamed command";
+        buf = wxString("&Redo ") + redoCommandName;
+        m_commandEditMenu->SetLabel(wxID_REDO, buf);
+        m_commandEditMenu->Enable(wxID_REDO, TRUE);
+      }
+    }
+  }
+}
+
+void wxCommandProcessor::ClearCommands(void)
+{
+  wxNode *node = m_commands.First();
+  while (node)
+  {
+    wxCommand *command = (wxCommand *)node->Data();
+    delete command;
+    delete node;
+    node = m_commands.First();
+  }
+  m_currentCommand = NULL;
+}
+
+
+/*
+ * File history processor
+ */
+
+wxFileHistory::wxFileHistory(int maxFiles)
+{
+  m_fileMaxFiles = maxFiles;
+  m_fileMenu = NULL;
+  m_fileHistoryN = 0;
+  m_fileHistory = new char *[m_fileMaxFiles];
+}
+
+wxFileHistory::~wxFileHistory(void)
+{
+  int i;
+  for (i = 0; i < m_fileHistoryN; i++)
+    delete[] m_fileHistory[i];
+  delete[] m_fileHistory;
+}
+
+// File history management
+void wxFileHistory::AddFileToHistory(const wxString& file)
+{
+  if (!m_fileMenu)
+    return;
+    
+  int i;
+
+  // Check we don't already have this file
+  for (i = 0; i < m_fileHistoryN; i++)
+  {
+    if (m_fileHistory[i] && wxString(m_fileHistory[i]) == file)
+      return;
+  }
+  
+  // Add to the project file history:
+  // Move existing files (if any) down so we can insert file at beginning.
+  
+  // First delete filename that has popped off the end of the array (if any)
+  if (m_fileHistoryN == m_fileMaxFiles)
+  {
+    delete[] m_fileHistory[m_fileMaxFiles-1];
+    m_fileHistory[m_fileMaxFiles-1] = NULL;
+  }
+  if (m_fileHistoryN < m_fileMaxFiles)
+  {
+    if (m_fileHistoryN == 0)
+      m_fileMenu->AppendSeparator();
+    m_fileMenu->Append(wxID_FILE1+m_fileHistoryN, "[EMPTY]");
+    m_fileHistoryN ++;
+  }
+  // Shuffle filenames down
+  for (i = (m_fileHistoryN-1); i > 0; i--)
+  {
+    m_fileHistory[i] = m_fileHistory[i-1];
+  }
+  m_fileHistory[0] = copystring(file);
+
+  for (i = 0; i < m_fileHistoryN; i++)
+    if (m_fileHistory[i])
+    {
+      char buf[400];
+      sprintf(buf, "&%d %s", i+1, m_fileHistory[i]);
+      m_fileMenu->SetLabel(wxID_FILE1+i, buf);
+    }
+}
+
+wxString wxFileHistory::GetHistoryFile(int i) const
+{
+  if (i < m_fileHistoryN)
+    return wxString(m_fileHistory[i]);
+  else
+    return wxString("");
+}
+
+void wxFileHistory::FileHistoryUseMenu(wxMenu *menu)
+{
+  m_fileMenu = menu;
+}
+
+void wxFileHistory::FileHistoryLoad(const wxString& resourceFile, const wxString& section)
+{
+#if USE_RESOURCES
+  m_fileHistoryN = 0;
+  char buf[400];
+  sprintf(buf, "file%d", m_fileHistoryN+1);
+  char *historyFile = NULL;
+  while ((m_fileHistoryN <= m_fileMaxFiles) && wxGetResource(section, buf, &historyFile, resourceFile) && historyFile)
+  {
+    // wxGetResource allocates memory so this is o.k.
+    m_fileHistory[m_fileHistoryN] = historyFile;
+    m_fileHistoryN ++;
+    sprintf(buf, "file%d", m_fileHistoryN+1);
+    historyFile = NULL;
+  }
+#endif
+}
+
+void wxFileHistory::FileHistorySave(const wxString& resourceFile, const wxString& section)
+{
+#if USE_RESOURCES
+  char buf[400];
+  int i;
+  for (i = 0; i < m_fileHistoryN; i++)
+  {
+    sprintf(buf, "file%d", i+1);
+    wxWriteResource(section, buf, m_fileHistory[i], resourceFile);
+  }
+#endif
+}
+
+#if 0
+/*
+ * wxPrintInfo
+ */
+
+wxPrintInfo::wxPrintInfo(void)
+{
+  pageNumber = 1;
+}
+
+wxPrintInfo::~wxPrintInfo(void)
+{
+}
+#endif
+
+/*
+ * Permits compatibility with existing file formats and functions
+ * that manipulate files directly
+ */
+ 
+bool wxTransferFileToStream(const wxString& filename, ostream& stream)
+{
+  FILE *fd1;
+  int ch;
+
+  if ((fd1 = fopen (WXSTRINGCAST filename, "rb")) == NULL)
+    return FALSE;
+
+  while ((ch = getc (fd1)) != EOF)
+    stream << (unsigned char)ch;
+
+  fclose (fd1);
+  return TRUE;
+}
+
+bool wxTransferStreamToFile(istream& stream, const wxString& filename)
+{
+  FILE *fd1;
+  int ch;
+
+  if ((fd1 = fopen (WXSTRINGCAST filename, "wb")) == NULL)
+    {
+      return FALSE;
+    }
+
+  while (!stream.eof())
+  {
+    ch = stream.get();
+    if (!stream.eof())
+      putc (ch, fd1);
+  }
+  fclose (fd1);
+  return TRUE;
+}
+
+#endif
+  // End USE_DOC_VIEW_ARCHITECTURE
diff --git a/src/common/dynarray.cpp b/src/common/dynarray.cpp
new file mode 100644
index 0000000000..cf2334db57
--- /dev/null
+++ b/src/common/dynarray.cpp
@@ -0,0 +1,216 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        dynarray.cpp
+// Purpose:     implementation of wxBaseArray class
+// Author:      Vadim Zeitlin
+// Modified by: 
+// Created:     12.09.97
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// Licence:     wxWindows license
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// headers
+// ============================================================================
+
+#ifdef __GNUG__
+#pragma implementation "dynarray.h"
+#endif
+
+#include  <wx/wxprec.h>
+
+#ifdef __BORLANDC__
+  #pragma hdrstop
+#endif
+
+#include "wx/dynarray.h"
+
+#include <stdlib.h>
+
+#ifndef max
+  #define max(a, b)   (((a) > (b)) ? (a) : (b))
+#endif
+
+// ============================================================================
+// constants
+// ============================================================================
+
+// size increment = max(50% of current size, ARRAY_MAXSIZE_INCREMENT)
+#define   ARRAY_MAXSIZE_INCREMENT    4096
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxBaseArray - dynamice array of 'long's
+// ----------------------------------------------------------------------------
+
+// ctor
+wxBaseArray::wxBaseArray()
+{
+  m_uiSize  =
+  m_uiCount = 0;
+  m_pItems  = NULL;
+}
+
+// copy ctor
+wxBaseArray::wxBaseArray(const wxBaseArray& src)
+{
+  m_uiSize  = src.m_uiSize;
+  m_uiCount = src.m_uiCount;
+
+  if ( m_uiSize != 0 )
+    m_pItems = new long[m_uiSize];
+  else
+    m_pItems = NULL;
+
+  if ( m_uiCount != 0 )
+    memcpy(m_pItems, src.m_pItems, m_uiCount*sizeof(long));
+}
+
+// copy operator
+wxBaseArray& wxBaseArray::operator=(const wxBaseArray& src)
+{
+  DELETEA(m_pItems);
+
+  m_uiSize  = src.m_uiSize;
+  m_uiCount = src.m_uiCount;
+
+  if ( m_uiSize != 0 )
+    m_pItems = new long[m_uiSize];
+  else
+    m_pItems = NULL;
+
+  if ( m_uiCount != 0 )
+    memcpy(m_pItems, src.m_pItems, m_uiCount*sizeof(long));
+
+  return *this;
+}
+
+// grow the array
+void wxBaseArray::Grow()
+{
+  // only do it if no more place
+  if( m_uiCount == m_uiSize ) {
+    if( m_uiSize == 0 ) {
+      // was empty, alloc some memory
+      m_uiSize = WX_ARRAY_DEFAULT_INITIAL_SIZE;
+      m_pItems = new long[m_uiSize];
+    }
+    else
+    {
+      // add 50% but not too much
+      uint uiIncrement = m_uiSize >> 1;
+      if ( uiIncrement > ARRAY_MAXSIZE_INCREMENT )
+        uiIncrement = ARRAY_MAXSIZE_INCREMENT;
+      m_uiSize += uiIncrement;
+      long *pNew = new long[m_uiSize];
+
+      // copy data to new location
+      memcpy(pNew, m_pItems, m_uiCount*sizeof(long));
+      delete [] m_pItems;
+      m_pItems = pNew;
+    }
+  }
+}
+
+// dtor
+wxBaseArray::~wxBaseArray()
+{
+  DELETEA(m_pItems);
+}
+
+// clears the list
+void wxBaseArray::Clear()
+{
+  m_uiSize  = 
+  m_uiCount = 0;
+
+  DELETEA(m_pItems);
+  m_pItems = NULL;
+}
+
+// pre-allocates memory (frees the previous data!)
+void wxBaseArray::Alloc(uint uiSize)
+{
+  wxASSERT( uiSize > 0 );
+
+  // only if old buffer was not big enough
+  if ( uiSize > m_uiSize ) {
+    DELETEA(m_pItems);
+    m_pItems = new long[uiSize];
+    m_uiSize  = uiSize;
+  }
+
+  m_uiCount = 0;
+}
+
+// searches the array for an item (forward or backwards)
+int wxBaseArray::Index(long lItem, Bool bFromEnd) const
+{
+  if ( bFromEnd ) {
+    if ( m_uiCount > 0 ) {
+      uint ui = m_uiCount;
+      do {
+        if ( m_pItems[--ui] == lItem )
+          return ui;
+      }
+      while ( ui != 0 );
+    }
+  }
+  else {
+    for( uint ui = 0; ui < m_uiCount; ui++ ) {
+      if( m_pItems[ui] == lItem )
+        return ui;
+    }
+  }
+
+  return NOT_FOUND;
+}
+
+// add item at the end
+void wxBaseArray::Add(long lItem)
+{
+  Grow();
+  m_pItems[m_uiCount++] = lItem;
+}
+
+// add item at the given position
+void wxBaseArray::Insert(long lItem, uint uiIndex)
+{
+  wxCHECK( uiIndex <= m_uiCount );
+
+  Grow();
+
+  memmove(&m_pItems[uiIndex + 1], &m_pItems[uiIndex], 
+          (m_uiCount - uiIndex)*sizeof(long));
+  m_pItems[uiIndex] = lItem;
+  m_uiCount++;
+}
+
+// removes item from array (by index)
+void wxBaseArray::Remove(uint uiIndex)
+{
+  wxCHECK( uiIndex <= m_uiCount );
+
+  memmove(&m_pItems[uiIndex], &m_pItems[uiIndex + 1], 
+          (m_uiCount - uiIndex - 1)*sizeof(long));
+  m_uiCount--;
+}
+
+// removes item from array (by value)
+void wxBaseArray::Remove(long lItem)
+{
+  int iIndex = Index(lItem);
+
+  wxCHECK( iIndex != NOT_FOUND );
+
+  Remove((uint)iIndex);
+}
+
+// sort array elements using passed comparaison function
+void wxBaseArray::Sort(CMPFUNC fCmp)
+{
+  qsort(m_pItems, m_uiCount, sizeof(long), fCmp);
+}
diff --git a/src/common/event.cpp b/src/common/event.cpp
new file mode 100644
index 0000000000..963aa42d42
--- /dev/null
+++ b/src/common/event.cpp
@@ -0,0 +1,442 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        event.cpp
+// Purpose:     Event classes
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "event.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/defs.h"
+#include "wx/control.h"
+#include "wx/utils.h"
+#include "wx/app.h"
+#include "wx/dc.h"
+#endif
+
+#include "wx/event.h"
+#include "wx/validate.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxEvtHandler, wxObject)
+IMPLEMENT_ABSTRACT_CLASS(wxEvent, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxCommandEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxScrollEvent, wxCommandEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxMouseEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxKeyEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxSizeEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxPaintEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxEraseEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxMoveEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxFocusEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxCloseEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxShowEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxMaximizeEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxIconizeEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxMenuEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxJoystickEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxDropFilesEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxActivateEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxInitDialogEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxSysColourChangedEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxIdleEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxUpdateUIEvent, wxEvent)
+
+const wxEventTable *wxEvtHandler::GetEventTable() const { return &wxEvtHandler::sm_eventTable; }
+
+const wxEventTable wxEvtHandler::sm_eventTable =
+	{ NULL, &wxEvtHandler::sm_eventTableEntries[0] };
+
+const wxEventTableEntry wxEvtHandler::sm_eventTableEntries[] = { { 0, 0, 0, NULL } };
+
+#endif
+
+/*
+ * General wxWindows events, covering
+ * all interesting things that might happen (button clicking, resizing,
+ * setting text in widgets, etc.).
+ *
+ * For each completely new event type, derive a new event class.
+ *
+ */
+
+wxEvent::wxEvent(int theId)
+{
+  m_eventType = 0;
+  m_eventObject = NULL;
+  m_eventHandle = NULL;
+  m_timeStamp = 0;
+  m_id = theId;
+  m_skipped = FALSE;
+}
+
+/*
+ * Command events
+ *
+ */
+
+wxCommandEvent::wxCommandEvent(WXTYPE commandType, int theId)
+{
+  m_eventType = commandType;
+  m_clientData = NULL;
+  m_extraLong = 0;
+  m_commandInt = 0;
+  m_id = theId;
+  m_commandString = NULL;
+}
+
+/*
+ * Scroll events
+ */
+
+wxScrollEvent::wxScrollEvent(WXTYPE commandType, int id, int pos, int orient):
+  wxCommandEvent(commandType, id)
+{
+  m_extraLong = orient;
+  m_commandInt = pos;
+}
+
+
+/*
+ * Mouse events
+ *
+ */
+
+wxMouseEvent::wxMouseEvent(WXTYPE commandType)
+{
+  m_eventType = commandType;
+  m_metaDown = FALSE;
+  m_altDown = FALSE;
+  m_controlDown = FALSE;
+  m_shiftDown = FALSE;
+}
+
+// True if was a button dclick event (1 = left, 2 = middle, 3 = right)
+// or any button dclick event (but = -1)
+bool wxMouseEvent::ButtonDClick(int but) const
+{
+  switch (but) {
+    case -1:
+      return (LeftDClick() || MiddleDClick() || RightDClick());
+    case 1:
+      return LeftDClick();
+    case 2:
+      return MiddleDClick();
+    case 3:
+      return RightDClick();
+    default:
+      return FALSE;
+  }
+  // NOTREACHED
+}
+
+// True if was a button down event (1 = left, 2 = middle, 3 = right)
+// or any button down event (but = -1)
+bool wxMouseEvent::ButtonDown(int but) const
+{
+  switch (but) {
+    case -1:
+      return (LeftDown() || MiddleDown() || RightDown());
+    case 1:
+      return LeftDown();
+    case 2:
+      return MiddleDown();
+    case 3:
+      return RightDown();
+    default:
+      return FALSE;
+  }
+  // NOTREACHED
+}
+
+// True if was a button up event (1 = left, 2 = middle, 3 = right)
+// or any button up event (but = -1)
+bool wxMouseEvent::ButtonUp(int but) const
+{
+  switch (but) {
+    case -1:
+      return (LeftUp() || MiddleUp() || RightUp());
+    case 1:
+      return LeftUp();
+    case 2:
+      return MiddleUp();
+    case 3:
+      return RightUp();
+    default:
+      return FALSE;
+  }
+  // NOTREACHED
+}
+
+// True if the given button is currently changing state
+bool wxMouseEvent::Button(int but) const
+{
+  switch (but) {
+    case -1:
+      return (ButtonUp(-1) || ButtonDown(-1) || ButtonDClick(-1)) ;
+    case 1:
+      return (LeftDown() || LeftUp() || LeftDClick());
+    case 2:
+      return (MiddleDown() || MiddleUp() || MiddleDClick());
+    case 3:
+      return (RightDown() || RightUp() || RightDClick());
+    default:
+      return FALSE;
+  }
+  // NOTREACHED
+}
+
+bool wxMouseEvent::ButtonIsDown(int but) const
+{
+  switch (but) {
+    case -1:
+      return (LeftIsDown() || MiddleIsDown() || RightIsDown());
+    case 1:
+      return LeftIsDown();
+    case 2:
+      return MiddleIsDown();
+    case 3:
+      return RightIsDown();
+    default:
+      return FALSE;
+  }
+  // NOTREACHED
+}
+
+// Find the logical position of the event given the DC
+wxPoint wxMouseEvent::GetLogicalPosition(const wxDC& dc) const
+{
+	wxPoint pt(dc.DeviceToLogicalX(m_x), dc.DeviceToLogicalY(m_y));
+	return pt;
+}
+
+
+/*
+ * Keyboard events
+ *
+ */
+
+wxKeyEvent::wxKeyEvent(WXTYPE type)
+{
+  m_eventType = type;
+  m_shiftDown = FALSE;
+  m_controlDown = FALSE;
+  m_metaDown = FALSE;
+  m_altDown = FALSE;
+  m_keyCode = 0;
+}
+
+/*
+ * Event handler
+ */
+
+wxEvtHandler::wxEvtHandler(void)
+{
+  m_clientData = NULL;
+  m_nextHandler = NULL;
+  m_previousHandler = NULL;
+  m_enabled = TRUE;
+}
+
+wxEvtHandler::~wxEvtHandler(void)
+{
+  // Takes itself out of the list of handlers
+  if (m_previousHandler)
+    m_previousHandler->m_nextHandler = m_nextHandler;
+
+  if (m_nextHandler)
+    m_nextHandler->m_previousHandler = m_previousHandler;
+}
+
+/*
+ * Event table stuff
+ */
+
+bool wxEvtHandler::ProcessEvent(wxEvent& event)
+{
+  // An event handler can be enabled or disabled
+  if ( GetEvtHandlerEnabled() )
+  {
+    const wxEventTable *table = GetEventTable();
+
+    // Try the associated validator first, if this is a window.
+    // Problem: if the event handler of the window has been replaced,
+    // this wxEvtHandler may no longer be a window.
+    // Therefore validators won't be processed if the handler
+    // has been replaced with SetEventHandler.
+    // THIS CAN BE CURED if PushEventHandler is used instead of
+    // SetEventHandler, and then processing will be passed down the
+    // chain of event handlers.
+    if (IsKindOf(CLASSINFO(wxWindow)))
+    {
+  	  wxWindow *win = (wxWindow *)this;
+
+	  // Can only use the validator of the window which
+	  // is receiving the event
+	  if ( (win == event.GetEventObject()) &&
+	      win->GetValidator() &&
+		  win->GetValidator()->ProcessEvent(event))
+        	return TRUE;
+    }
+
+    // Search upwards through the inheritance hierarchy
+    while (table)
+    {
+      if (SearchEventTable((wxEventTable&)*table, event))
+          return TRUE;
+      table = table->baseTable;
+    }
+  }
+
+  // Try going down the event handler chain
+  if ( GetNextHandler() )
+  {
+	    if ( GetNextHandler()->ProcessEvent(event) )
+			return TRUE;
+  }
+
+  // Carry on up the parent-child hierarchy,
+  // but only if event is a command event: it wouldn't
+  // make sense for a parent to receive a child's size event, for example
+  if (IsKindOf(CLASSINFO(wxWindow)) && event.IsKindOf(CLASSINFO(wxCommandEvent)))
+  {
+    wxWindow *win = (wxWindow *)this;
+	wxWindow *parent = win->GetParent();
+    if (parent && !parent->IsBeingDeleted())
+      return win->GetParent()->GetEventHandler()->ProcessEvent(event);
+  }
+
+  // Last try - application object
+  if (wxTheApp && this != wxTheApp && wxTheApp->ProcessEvent(event))
+    return TRUE;
+  else
+    return FALSE;
+}
+
+bool wxEvtHandler::SearchEventTable(wxEventTable& table, wxEvent& event)
+{
+  int i = 0;
+  int commandId = event.GetId();
+  
+  while (table.entries[i].m_fn != NULL)
+  {
+    if ((event.GetEventType() == table.entries[i].m_eventType) &&
+        (table.entries[i].m_id == -1 || // Match, if event spec says any id will do (id == -1)
+          (table.entries[i].m_lastId == -1 && commandId == table.entries[i].m_id) ||
+          (table.entries[i].m_lastId != -1 &&
+            (commandId >= table.entries[i].m_id && commandId <= table.entries[i].m_lastId))))
+    {
+	  	event.Skip(FALSE);
+
+        (this->*((wxEventFunction) (table.entries[i].m_fn)))(event);
+
+		if ( event.GetSkipped() )
+			return FALSE;
+		  else
+            return TRUE;
+    }
+    i ++;
+  }
+  return FALSE;
+}
+
+#if WXWIN_COMPATIBILITY
+void wxEvtHandler::OldOnMenuCommand(int cmd)
+{
+    if (GetNextHandler()) GetNextHandler()->OldOnMenuCommand(cmd);
+}
+
+void wxEvtHandler::OldOnMenuSelect(int cmd)
+{
+    if (GetNextHandler()) GetNextHandler()->OldOnMenuSelect(cmd);
+}
+
+void wxEvtHandler::OldOnInitMenuPopup(int pos)
+{
+    if (GetNextHandler()) GetNextHandler()->OldOnInitMenuPopup(pos);
+}
+
+void wxEvtHandler::OldOnScroll(wxCommandEvent& event)
+{
+    if (GetNextHandler()) GetNextHandler()->OldOnScroll(event);
+}
+
+void wxEvtHandler::OldOnPaint(void)
+{
+    if (GetNextHandler()) GetNextHandler()->OldOnPaint();
+}
+void wxEvtHandler::OldOnSize(int width, int height)
+{
+    if (GetNextHandler()) GetNextHandler()->OldOnSize(width, height);
+}
+
+void wxEvtHandler::OldOnMove(int x, int y)
+{
+    if (GetNextHandler()) GetNextHandler()->OldOnMove(x, y);
+}
+
+void wxEvtHandler::OldOnMouseEvent(wxMouseEvent& event)
+{
+    if (GetNextHandler()) GetNextHandler()->OldOnMouseEvent(event);
+}
+
+void wxEvtHandler::OldOnChar(wxKeyEvent& event)
+{
+    if (GetNextHandler()) GetNextHandler()->OldOnChar(event);
+}
+
+// Under Windows, we can intercept character input per dialog or frame
+bool wxEvtHandler::OldOnCharHook(wxKeyEvent& event)
+{
+    if (GetNextHandler()) return GetNextHandler()->OldOnCharHook(event);
+ 	else return FALSE;
+}
+
+void wxEvtHandler::OldOnActivate(bool active)
+{
+    if (GetNextHandler()) GetNextHandler()->OldOnActivate(active);
+}
+
+void wxEvtHandler::OldOnSetFocus(void)
+{
+    if (GetNextHandler()) GetNextHandler()->OldOnSetFocus();
+}
+
+void wxEvtHandler::OldOnKillFocus(void)
+{
+    if (GetNextHandler()) GetNextHandler()->OldOnKillFocus();
+}
+
+bool wxEvtHandler::OldOnSysColourChange(void)
+{
+    if (GetNextHandler()) return GetNextHandler()->OldOnSysColourChange();
+    return FALSE;
+}
+
+void wxEvtHandler::OldOnDropFiles(int n, char *files[], int x, int y)
+{
+    if (GetNextHandler()) GetNextHandler()->OldOnDropFiles(n, files, x, y);
+}
+#endif
+
+bool wxEvtHandler::OnClose(void)
+{
+    if (GetNextHandler()) return GetNextHandler()->OnClose();
+    else return FALSE;
+}
+
+
diff --git a/src/common/file.cpp b/src/common/file.cpp
new file mode 100644
index 0000000000..6c6ae4acc5
--- /dev/null
+++ b/src/common/file.cpp
@@ -0,0 +1,399 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        file.cpp
+// Purpose:     wxFile - encapsulates low-level "file descriptor"
+//              wxTempFile
+// Author:      Vadim Zeitlin
+// Modified by:
+// Created:     29/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#ifdef __GNUG__
+#pragma implementation "file.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+#include "wx/defs.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+// standard
+#if 	defined(__WINDOWS__) && !defined(__GNUWIN32__)
+  #include  <io.h>
+#elif (defined(__UNIX__) || defined(__GNUWIN32__))
+  #include  <unistd.h>
+#else
+	#error	"Please specify the header with file functions declarations."
+#endif  //Win/UNIX
+
+#include  <stdio.h>       // SEEK_xxx constants
+#include  <fcntl.h>       // O_RDONLY &c
+#include  <sys/types.h>   // needed for stat
+#include  <sys/stat.h>    // stat
+
+// Microsoft compiler loves underscores, feed them to it
+#ifdef    _MSC_VER
+  // functions
+  #define   open        _open
+  #define   close       _close
+  #define   read        _read
+  #define   write       _write
+  #define   lseek       _lseek
+  #define   fsync       _commit
+  #define   access      _access
+  #define   eof         _eof
+
+  // types
+  #define   stat        _stat
+
+  // constants
+  #define   O_RDONLY    _O_RDONLY
+  #define   O_WRONLY    _O_WRONLY
+  #define   O_RDWR      _O_RDWR
+  #define   O_EXCL      _O_EXCL
+  #define   O_CREAT     _O_CREAT
+  #define   O_BINARY    _O_BINARY
+
+  #define   S_IFDIR     _S_IFDIR
+  #define   S_IFREG     _S_IFREG
+
+  #define   S_IREAD     _S_IREAD
+  #define   S_IWRITE    _S_IWRITE
+#else
+  #define   tell(fd)    lseek(fd, 0, SEEK_CUR)
+#endif  //_MSC_VER
+
+// there is no distinction between text and binary files under Unix
+#ifdef		__UNIX__
+	#define 	O_BINARY		(0)
+#endif	//__UNIX__
+
+// wxWindows
+#include  <wx/string.h>
+#include  <wx/intl.h>
+#include  <wx/file.h>
+#include  <wx/log.h>
+
+
+// ============================================================================
+// implementation of wxFile
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// static functions
+// ----------------------------------------------------------------------------
+bool wxFile::Exists(const char *sz)
+{ 
+  struct stat st; 
+  return !access(sz, 0) && !stat(sz, &st) && (st.st_mode & S_IFREG);
+}
+
+// ----------------------------------------------------------------------------
+// opening/closing
+// ----------------------------------------------------------------------------
+
+// ctors
+wxFile::wxFile(const char *szFileName, OpenMode mode)
+{
+  m_fd = fd_invalid;
+
+  Open(szFileName, mode);
+}
+
+// dtor
+wxFile::~wxFile()
+{
+  Close();
+}
+
+// create the file, fail if it already exists and bOverwrite
+bool wxFile::Create(const char *szFileName, bool bOverwrite)
+{
+  // if bOverwrite we create a new file or truncate the existing one,
+  // otherwise we only create the new file and fail if it already exists
+  int fd = bOverwrite ? creat(szFileName, 0) 
+                      : open(szFileName, O_CREAT | O_EXCL);
+
+  if ( fd == -1 ) {
+    wxLogSysError("can't create file '%s'", szFileName);
+    return FALSE;
+  }
+  else {
+    Attach(fd);
+    return TRUE;
+  }
+}
+
+// open the file
+bool wxFile::Open(const char *szFileName, OpenMode mode)
+{
+  int flags = O_BINARY;
+
+  switch ( mode ) {
+    case read:      
+      flags |= O_RDONLY; 
+      break;
+
+    case write:     
+      flags |= O_WRONLY | O_CREAT; 
+      break;
+
+    case read_write: 
+      flags |= O_RDWR;
+      break;
+  }
+
+  int fd = open(szFileName, flags, S_IREAD | S_IWRITE);
+
+  if ( fd == -1 ) {
+    wxLogSysError("can't open file '%s'", szFileName);
+    return FALSE;
+  }
+  else {
+    Attach(fd);
+    return TRUE;
+  }
+}
+
+// close
+void wxFile::Close()
+{
+  if ( IsOpened() ) {
+    if ( close(m_fd) == -1 )
+      wxLogSysError("can't close file descriptor %d", m_fd);
+
+    m_fd = fd_invalid;
+  }
+}
+
+// ----------------------------------------------------------------------------
+// read/write
+// ----------------------------------------------------------------------------
+
+// read
+off_t wxFile::Read(void *pBuf, off_t nCount)
+{
+  wxCHECK_RET( (pBuf != NULL) && IsOpened(), 0 );
+
+  int iRc = ::read(m_fd, pBuf, nCount);
+  if ( iRc == -1 ) {
+    wxLogSysError("can't read from file descriptor %d", m_fd);
+    return ofsInvalid;
+  }
+  else
+    return (uint)iRc;
+}
+
+// write
+bool wxFile::Write(const void *pBuf, uint nCount)
+{
+  wxCHECK_RET( (pBuf != NULL) && IsOpened(), 0 );
+
+  int iRc = ::write(m_fd, pBuf, nCount);
+  if ( iRc == -1 ) {
+    wxLogSysError("can't write to file descriptor %d", m_fd);
+    return FALSE;
+  }
+  else
+    return TRUE;
+}
+
+// flush
+bool wxFile::Flush()
+{
+  if ( IsOpened() ) {
+		// ## fsync() is not ANSI (BSDish)
+//    if ( fsync(m_fd) == -1 ) { // TODO
+      if (TRUE) {
+      wxLogSysError("can't flush file descriptor %d", m_fd);
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+}
+
+// ----------------------------------------------------------------------------
+// seek
+// ----------------------------------------------------------------------------
+
+// seek
+off_t wxFile::Seek(off_t ofs, SeekMode mode)
+{
+  wxASSERT( IsOpened() );
+
+  int flag = -1;
+  switch ( mode ) {
+    case FromStart:
+      flag = SEEK_SET;
+      break;
+
+    case FromCurrent:
+      flag = SEEK_CUR;
+      break;
+
+    case FromEnd:
+      flag = SEEK_END;
+      break;
+
+    default:
+      wxFAIL_MSG("unknown seek origin");
+  }
+
+  int iRc = lseek(m_fd, ofs, flag);
+  if ( iRc == -1 ) {
+    wxLogSysError("can't seek on file descriptor %d", m_fd);
+    return ofsInvalid;
+  }
+  else
+    return (off_t)iRc;
+}
+
+// get current off_t
+off_t wxFile::Tell() const
+{
+  wxASSERT( IsOpened() );
+
+  int iRc = tell(m_fd);
+  if ( iRc == -1 ) {
+    wxLogSysError("can't get seek position on file descriptor %d", m_fd);
+    return ofsInvalid;
+  }
+  else
+    return (off_t)iRc;
+}
+
+// get current file length
+off_t wxFile::Length() const
+{
+  wxASSERT( IsOpened() );
+
+  #ifdef  _MSC_VER
+    int iRc = _filelength(m_fd);
+  #else
+    int iRc = tell(m_fd);
+    if ( iRc != -1 ) {
+			// # have to use const_cast :-(
+      int iLen = ((wxFile *)this)->SeekEnd();
+      if ( iLen != -1 ) {
+        // restore old position
+        if ( ((wxFile *)this)->Seek(iRc) == -1 ) {
+          // error
+          iLen = -1;
+        }
+      }
+
+      iRc = iLen;
+    }
+
+  #endif  //_MSC_VER
+
+  if ( iRc == -1 ) {
+    wxLogSysError("can't find length of file on file descriptor %d", m_fd);
+    return ofsInvalid;
+  }
+  else
+    return (off_t)iRc;
+}
+
+// is end of file reached?
+bool wxFile::Eof() const
+{
+  wxASSERT( IsOpened() );
+
+  // TODO: no eof in GnuWin32
+  
+#ifdef __LINUX__
+
+  int iRc = Tell() == Length();
+
+#else  
+  
+#if defined(__GNUWIN32__)
+  int iRc = -1;
+#else
+  int iRc = eof(m_fd);
+#endif
+
+#endif
+
+  switch ( iRc ) {
+    case 1:
+      break;
+
+    case 0:
+      return FALSE;
+
+    case -1:
+      wxLogSysError("can't determine if the end of file is reached on "
+                    "descriptor %d", m_fd);
+      break;
+
+    default:
+      wxFAIL_MSG("invalid eof() return value.");
+  }
+
+  return TRUE;
+}
+
+// ============================================================================
+// implementation of wxTempFile
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// construction
+// ----------------------------------------------------------------------------
+wxTempFile::wxTempFile(const wxString& strName)
+{
+  Open(strName);
+}
+
+bool wxTempFile::Open(const wxString& strName)
+{
+  m_strName = strName;
+  m_strTemp = tmpnam(NULL);
+  return m_file.Open(m_strTemp, wxFile::write);
+}
+
+// ----------------------------------------------------------------------------
+// destruction
+// ----------------------------------------------------------------------------
+
+wxTempFile::~wxTempFile()
+{
+  if ( IsOpened() )
+    Discard();
+}
+
+bool wxTempFile::Commit()
+{
+  m_file.Close();
+
+  if ( wxFile::Exists(m_strName) && remove(m_strName) != 0 ) {
+    wxLogSysError("can't remove file '%s'", m_strName.c_str());
+    return FALSE;
+  }
+
+  if ( rename(m_strTemp, m_strName) != 0 ) {
+    wxLogSysError("can't commit changes to file '%s'", m_strName.c_str());
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+void wxTempFile::Discard()
+{
+  m_file.Close();
+  if ( remove(m_strTemp) != 0 )
+    wxLogSysError("can't remove temporary file '%s'", m_strTemp.c_str());
+}
diff --git a/src/common/fileconf.cpp b/src/common/fileconf.cpp
new file mode 100644
index 0000000000..d12bc8bf80
--- /dev/null
+++ b/src/common/fileconf.cpp
@@ -0,0 +1,1248 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        fileconf.cpp
+// Purpose:     implementation of wxFileConfig derivation of wxConfig
+// Author:      Vadim Zeitlin
+// Modified by: 
+// Created:     07.04.98 (adapted from appconf.cpp)
+// RCS-ID:      $Id$
+// Copyright:   (c) 1997 Karsten Ballüder   &  Vadim Zeitlin
+//                       Ballueder@usa.net     <zeitlin@dptmaths.ens-cachan.fr>
+// Licence:     wxWindows license
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+#include  "wx/wxprec.h"
+
+#ifdef    __BORLANDC__
+  #pragma hdrstop
+#endif  //__BORLANDC__
+
+#ifndef   WX_PRECOMP
+  #include  <wx/string.h>
+  #include  <wx/intl.h>
+#endif  //WX_PRECOMP
+
+#include  <wx/dynarray.h>
+#include  <wx/file.h>
+#include  <wx/log.h>
+#include  <wx/textfile.h>
+#include  <wx/config.h>
+
+#ifdef __WINDOWS__
+#include <windows.h>
+#endif
+
+#include <stdlib.h>
+#include <ctype.h>
+
+// ----------------------------------------------------------------------------
+// global functions declarations
+// ----------------------------------------------------------------------------
+
+// is 'c' a valid character in group name?
+// NB: APPCONF_IMMUTABLE_PREFIX and APPCONF_PATH_SEPARATOR must be valid chars,
+//     but _not_ ']' (group name delimiter)
+inline bool IsValid(char c) { return isalnum(c) || strchr("_/-!.*%", c); }
+
+// get the system wide and user configuration file full path
+static const char *GetGlobalFileName(const char *szFile);
+static const char *GetLocalFileName(const char *szFile);
+
+// split path into parts removing '..' in progress
+static void SplitPath(wxArrayString& aParts, const char *sz);
+
+// filter strings
+static wxString FilterIn(const wxString& str);
+static wxString FilterOut(const wxString& str);
+
+// ----------------------------------------------------------------------------
+// wxFileConfig
+// ----------------------------------------------------------------------------
+
+/*
+  FileConfig derives from BaseConfig and implements file based config class, 
+  i.e. it uses ASCII disk files to store the information. These files are
+  alternatively called INI, .conf or .rc in the documentation. They are 
+  organized in groups or sections, which can nest (i.e. a group contains
+  subgroups, which contain their own subgroups &c). Each group has some
+  number of entries, which are "key = value" pairs. More precisely, the format 
+  is:
+
+  # comments are allowed after either ';' or '#' (Win/UNIX standard)
+
+  # blank lines (as above) are ignored
+
+  # global entries are members of special (no name) top group
+  written_for = wxWindows
+  platform    = Linux
+
+  # the start of the group 'Foo'
+  [Foo]                           # may put comments like this also
+  # following 3 lines are entries
+  key = value
+  another_key = "  strings with spaces in the beginning should be quoted, \
+                   otherwise the spaces are lost"
+  last_key = but you don't have to put " normally (nor quote them, like here)
+
+  # subgroup of the group 'Foo'
+  # (order is not important, only the name is: separator is '/', as in paths)
+  [Foo/Bar]
+  # entries prefixed with "!" are immutable, i.e. can't be changed if they are
+  # set in the system-wide config file
+  !special_key = value
+  bar_entry = whatever
+
+  [Foo/Bar/Fubar]   # depth is (theoretically :-) unlimited
+  # may have the same name as key in another section
+  bar_entry = whatever not
+
+  You have {read/write/delete}Entry functions (guess what they do) and also
+  setCurrentPath to select current group. enum{Subgroups/Entries} allow you
+  to get all entries in the config file (in the current group). Finally,
+  flush() writes immediately all changed entries to disk (otherwise it would
+  be done automatically in dtor)
+
+  FileConfig manages not less than 2 config files for each program: global
+  and local (or system and user if you prefer). Entries are read from both of
+  them and the local entries override the global ones unless the latter is
+  immutable (prefixed with '!') in which case a warning message is generated
+  and local value is ignored. Of course, the changes are always written to local
+  file only.
+*/
+
+class wxFileConfig : public wxConfig
+{
+public:
+  // ctor & dtor
+    // the config file is searched in the following locations
+    //            global                local
+    // Unix   /etc/file.ext           ~/.file
+    // Win    %windir%\file.ext   %USERPROFILE%\file.ext
+    //
+    // where file is the basename of strFile, ext is it's extension
+    // or .conf (Unix) or .ini (Win) if it has none
+  wxFileConfig(const wxString& strFile, bool bLocalOnly = FALSE);
+    // dtor will save unsaved data
+  virtual ~wxFileConfig();
+
+  // implement inherited pure virtual functions
+  virtual void SetPath(const wxString& strPath);
+  virtual const wxString& GetPath() const { return m_strPath; }
+
+  virtual bool GetFirstGroup(wxString& str, long& lIndex);
+  virtual bool GetNextGroup (wxString& str, long& lIndex);
+  virtual bool GetFirstEntry(wxString& str, long& lIndex);
+  virtual bool GetNextEntry (wxString& str, long& lIndex);
+
+  virtual const char *Read(const char *szKey, const char *szDefault = 0) const;
+  virtual long        Read(const char *szKey, long lDefault) const;
+  virtual bool Write(const char *szKey, const char *szValue);
+  virtual bool Write(const char *szKey, long Value);
+  virtual bool Flush(bool bCurrentOnly = FALSE);
+
+  virtual bool DeleteEntry(const char *szKey, bool bGroupIfEmptyAlso);
+  virtual bool DeleteGroup(const char *szKey);
+  virtual bool DeleteAll();
+
+public:
+  // fwd decl
+  class ConfigGroup;
+  class ConfigEntry;
+
+  // we store all lines of the local config file as a linked list in memory
+  class LineList
+  {
+  public:
+    // ctor
+    LineList(const wxString& str, LineList *pNext = NULL) : m_strLine(str) 
+      { SetNext(pNext); }
+    
+    // 
+    LineList *Next() const              { return m_pNext;  }
+    void      SetNext(LineList *pNext)  { m_pNext = pNext; }
+
+    //
+    void SetText(const wxString& str) { m_strLine = str;  }
+    const wxString& Text() const      { return m_strLine; }
+
+  private:
+    wxString  m_strLine;      // line contents
+    LineList *m_pNext;        // next node
+  };
+  
+  // functions to work with this list
+  LineList *LineListAppend(const wxString& str);
+  LineList *LineListInsert(const wxString& str, 
+                           LineList *pLine);    // NULL => Append()
+  bool      LineListIsEmpty();
+
+private:
+  // put the object in the initial state
+  void Init();
+
+  // parse the whole file
+  void Parse(wxTextFile& file, bool bLocal);
+
+  // the same as SetPath("/")
+  void SetRootPath();
+
+  // member variables
+  // ----------------
+  LineList   *m_linesHead,        // head of the linked list
+             *m_linesTail;        // tail
+
+  wxString    m_strFile;          // file name passed to ctor
+  wxString    m_strPath;          // current path (not '/' terminated)
+
+  ConfigGroup *m_pRootGroup,      // the top (unnamed) group
+              *m_pCurrentGroup;   // the current group
+
+  // a handy little class which changes current path to the path of given entry
+  // and restores it in dtor: so if you declare a local variable of this type,
+  // you work in the entry directory and the path is automatically restored
+  // when function returns
+  class PathChanger
+  {
+  public:
+    // ctor/dtor do path changing/restorin
+    PathChanger(const wxFileConfig *pContainer, const wxString& strEntry);
+   ~PathChanger();
+
+    // get the key name
+   const wxString& Name() const { return m_strName; }
+
+  private:
+    wxFileConfig *m_pContainer;   // object we live in
+    wxString      m_strName,      // name of entry (i.e. name only)
+                  m_strOldPath;   // saved path
+    bool          m_bChanged;     // was the path changed?
+  };
+
+//protected: --- if FileConfig::ConfigEntry is not public, functions in
+//               ConfigGroup such as Find/AddEntry can't return "ConfigEntry *"
+public:
+  WX_DEFINE_ARRAY(ConfigEntry *, ArrayEntries);
+  WX_DEFINE_ARRAY(ConfigGroup *, ArrayGroups);
+
+  class ConfigEntry
+  {
+  private:
+    ConfigGroup  *m_pParent;      // group that contains us
+    wxString      m_strName,      // entry name
+                  m_strValue;     //       value
+    bool          m_bDirty,       // changed since last read?
+                  m_bImmutable;   // can be overriden locally?
+    int           m_nLine;        // used if m_pLine == NULL only
+    LineList     *m_pLine;        // pointer to our line in the linked list
+                                  // or NULL if it was found in global file
+
+  public:
+    ConfigEntry(ConfigGroup *pParent, const wxString& strName, int nLine);
+
+    // simple accessors
+    const wxString& Name()        const { return m_strName;    }
+    const wxString& Value()       const { return m_strValue;   }
+    ConfigGroup    *Group()       const { return m_pParent;    }
+    bool            IsDirty()     const { return m_bDirty;     }
+    bool            IsImmutable() const { return m_bImmutable; }
+    bool            IsLocal()     const { return m_pLine != 0; }
+    int             Line()        const { return m_nLine;      }
+    LineList       *GetLine()     const { return m_pLine;      }
+
+    // modify entry attributes
+    void SetValue(const wxString& strValue, bool bUser = TRUE);
+    void SetDirty();
+    void SetLine(LineList *pLine);
+  };
+
+protected:
+  class ConfigGroup
+  {
+  private:
+    wxFileConfig *m_pConfig;      // config object we belong to
+    ConfigGroup  *m_pParent;      // parent group (NULL for root group)
+    ArrayEntries  m_aEntries;     // entries in this group
+    ArrayGroups   m_aSubgroups;   // subgroups
+    wxString      m_strName;      // group's name
+    bool          m_bDirty;       // if FALSE => all subgroups are not dirty
+    LineList     *m_pLine;        // pointer to our line in the linked list
+    int           m_nLastEntry,   // last here means "last added"
+                  m_nLastGroup;   // 
+
+  public:
+    // ctor
+    ConfigGroup(ConfigGroup *pParent, const wxString& strName, wxFileConfig *);
+
+    // dtor deletes all entries and subgroups also
+    ~ConfigGroup();
+
+    // simple accessors
+    const wxString& Name()    const { return m_strName; }
+    ConfigGroup    *Parent()  const { return m_pParent; }
+    wxFileConfig   *Config()  const { return m_pConfig; }
+    bool            IsDirty() const { return m_bDirty;  }
+
+    bool  IsEmpty() const { return Entries().IsEmpty() && Groups().IsEmpty(); }
+    const ArrayEntries& Entries() const { return m_aEntries;   }
+    const ArrayGroups&  Groups()  const { return m_aSubgroups; }
+
+    // find entry/subgroup (NULL if not found)
+    ConfigGroup *FindSubgroup(const char *szName) const;
+    ConfigEntry *FindEntry   (const char *szName) const;
+
+    // delete entry/subgroup, return FALSE if doesn't exist
+    bool DeleteSubgroup(const char *szName);
+    bool DeleteEntry(const char *szName);
+
+    // create new entry/subgroup returning pointer to newly created element
+    ConfigGroup *AddSubgroup(const wxString& strName);
+    ConfigEntry *AddEntry   (const wxString& strName, int nLine = NOT_FOUND);
+
+    // will also recursively set parent's dirty flag
+    void SetDirty();
+    void SetLine(LineList *pLine);
+
+    wxString GetFullName() const;
+
+    // get the last line belonging to an entry/subgroup of this group
+    LineList *GetGroupLine();
+    LineList *GetLastEntryLine();
+    LineList *GetLastGroupLine();
+  };
+};
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// ctor
+// ----------------------------------------------------------------------------
+
+void wxFileConfig::Init()
+{
+  m_pCurrentGroup = 
+  m_pRootGroup    = new ConfigGroup(NULL, "", this);
+
+  m_linesHead =
+  m_linesTail = NULL;
+
+  m_bExpandEnvVars = TRUE;
+
+  m_strPath.Empty();
+}
+
+wxFileConfig::wxFileConfig(const wxString& strFile, bool bLocalOnly) 
+            : m_strFile(strFile)
+{
+  Init();
+
+  const char *szFile;
+
+  // it's not an error if (one of the) file(s) doesn't exist
+
+  // parse the global file
+  if ( !bLocalOnly ) {
+    szFile = GetGlobalFileName(strFile);
+    if ( wxFile::Exists(szFile) ) {
+      wxTextFile fileGlobal(szFile);
+
+      if ( fileGlobal.Open() ) {
+        Parse(fileGlobal, FALSE /* global */);
+        SetRootPath();
+      }
+      else
+        wxLogWarning("Can't open global configuration file.");
+    }
+  }
+
+  // parse the local file
+  szFile = GetLocalFileName(strFile);
+  if ( wxFile::Exists(szFile) ) {
+    wxTextFile fileLocal(szFile);
+    if ( fileLocal.Open() ) {
+      Parse(fileLocal, TRUE /* local */);
+      SetRootPath();
+    }
+    else
+      wxLogWarning("Can't open user configuration file.");
+  }
+}
+
+wxFileConfig::~wxFileConfig()
+{
+  Flush();
+  delete m_pRootGroup;
+}
+
+// ----------------------------------------------------------------------------
+// parse a config file
+// ----------------------------------------------------------------------------
+
+void wxFileConfig::Parse(wxTextFile& file, bool bLocal)
+{
+  const char *pStart;
+  const char *pEnd;
+  
+  for ( uint n = 0; n < file.GetLineCount(); n++ ) {
+    // add the line to linked list
+    if ( bLocal )
+      LineListAppend(file[n]);
+
+    // skip leading spaces
+    for ( pStart = file[n]; isspace(*pStart); pStart++ )
+      ;
+
+    // skip blank/comment lines
+    if ( *pStart == '\0'|| *pStart == ';' || *pStart == '#' )
+      continue;
+
+    if ( *pStart == '[' ) {          // a new group
+      pEnd = pStart;
+
+      while ( *++pEnd != ']' ) {
+        if ( !IsValid(*pEnd) && *pEnd != ' ' )  // allow spaces in group names
+          break;
+      }
+
+      if ( *pEnd != ']' ) {
+        wxLogError("file '%s': unexpected character at line %d (missing ']'?)",
+		                file.GetName(), n + 1);
+        continue; // skip this line
+      }
+
+      // group name here is always considered as abs path
+      wxString strGroup;
+      pStart++;
+      strGroup << APPCONF_PATH_SEPARATOR << wxString(pStart, pEnd - pStart);
+
+      // will create it if doesn't yet exist
+      SetPath(strGroup);
+
+      if ( bLocal )
+        m_pCurrentGroup->SetLine(m_linesTail);
+
+      // check that there is nothing except comments left on this line
+      bool bCont = TRUE;
+      while ( *++pEnd != '\0' && bCont ) {
+        switch ( *pEnd ) {
+          case '#':
+          case ';':
+            bCont = FALSE;
+            break;
+        
+          case ' ':
+          case '\t':
+            // ignore whitespace ('\n' impossible here)
+            break;
+          
+          default:
+            wxLogWarning("file '%s', line %d: '%s' ignored after group header.",
+                         file.GetName(), n + 1, pEnd);
+            bCont = FALSE;
+        }
+      }
+    }
+    else {                        // a key
+      const char *pEnd = pStart;
+      while ( IsValid(*pEnd) )
+        pEnd++;
+
+      wxString strKey(pStart, pEnd);
+
+      // skip whitespace
+      while ( isspace(*pEnd) ) 
+        pEnd++;
+
+      if ( *pEnd++ != '=' ) {
+        wxLogError("file '%s', line %d: '=' expected.", file.GetName(), n + 1);
+      }
+      else {
+        ConfigEntry *pEntry = m_pCurrentGroup->FindEntry(strKey);
+
+        if ( pEntry == NULL ) {
+          // new entry
+          pEntry = m_pCurrentGroup->AddEntry(strKey, n);
+
+          if ( bLocal )
+            pEntry->SetLine(m_linesTail);
+        }
+        else {
+          if ( bLocal && pEntry->IsImmutable() ) {
+            // immutable keys can't be changed by user
+            wxLogWarning("file '%s', line %d: value for immutable key '%s' ignored.",
+                         file.GetName(), n + 1, strKey.c_str());
+            continue;
+          }
+          // the condition below catches the cases (a) and (b) but not (c):
+          //  (a) global key found second time in global file
+          //  (b) key found second (or more) time in local file
+          //  (c) key from global file now found in local one
+          // which is exactly what we want.
+          else if ( !bLocal || pEntry->IsLocal() ) {
+            wxLogWarning("file '%s', line %d: key '%s' was first found at line %d.", 
+                         file.GetName(), n + 1, strKey.c_str(), pEntry->Line());
+
+            if ( bLocal )
+              pEntry->SetLine(m_linesTail);
+          }
+        }
+
+        // skip whitespace
+        while ( isspace(*pEnd) ) 
+          pEnd++;
+
+        wxString strValue;
+        if (m_bExpandEnvVars)
+            strValue = ExpandEnvVars(FilterIn(pEnd));
+        else
+            strValue = FilterIn(pEnd);
+        pEntry->SetValue(strValue, FALSE);
+      }
+    }
+  }
+}
+
+// ----------------------------------------------------------------------------
+// set/retrieve path
+// ----------------------------------------------------------------------------
+
+void wxFileConfig::SetRootPath()
+{
+  m_strPath.Empty();
+  m_pCurrentGroup = m_pRootGroup;
+}
+
+void wxFileConfig::SetPath(const wxString& strPath)
+{
+  wxArrayString aParts;
+
+  if ( strPath.IsEmpty() )
+    return;
+
+  if ( strPath[0] == APPCONF_PATH_SEPARATOR ) {
+    // absolute path
+    SplitPath(aParts, strPath);
+  }
+  else {
+    // relative path, combine with current one
+    wxString strFullPath = m_strPath;
+    strFullPath << APPCONF_PATH_SEPARATOR << strPath;
+    SplitPath(aParts, strFullPath);
+  }
+
+  // change current group
+  uint n;
+  m_pCurrentGroup = m_pRootGroup;
+  for ( n = 0; n < aParts.Count(); n++ ) {
+    ConfigGroup *pNextGroup = m_pCurrentGroup->FindSubgroup(aParts[n]);
+    if ( pNextGroup == NULL )
+      pNextGroup = m_pCurrentGroup->AddSubgroup(aParts[n]);
+    m_pCurrentGroup = pNextGroup;
+  }
+
+  // recombine path parts in one variable
+  m_strPath.Empty();
+  for ( n = 0; n < aParts.Count(); n++ ) {
+    m_strPath << APPCONF_PATH_SEPARATOR << aParts[n];
+  }
+}
+
+// ----------------------------------------------------------------------------
+// enumeration
+// ----------------------------------------------------------------------------
+
+bool wxFileConfig::GetFirstGroup(wxString& str, long& lIndex)
+{
+  lIndex = 0;
+  return GetNextGroup(str, lIndex);
+}
+
+bool wxFileConfig::GetNextGroup (wxString& str, long& lIndex)
+{
+  if ( uint(lIndex) < m_pCurrentGroup->Groups().Count() ) {
+    str = m_pCurrentGroup->Groups()[lIndex++]->Name();
+    return TRUE;
+  }
+  else
+    return FALSE;
+}
+
+bool wxFileConfig::GetFirstEntry(wxString& str, long& lIndex)
+{
+  lIndex = 0;
+  return GetNextEntry(str, lIndex);
+}
+
+bool wxFileConfig::GetNextEntry (wxString& str, long& lIndex)
+{
+  if ( uint(lIndex) < m_pCurrentGroup->Entries().Count() ) {
+    str = m_pCurrentGroup->Entries()[lIndex++]->Name();
+    return TRUE;
+  }
+  else
+    return FALSE;
+}
+
+// ----------------------------------------------------------------------------
+// read/write values
+// ----------------------------------------------------------------------------
+
+const char *wxFileConfig::Read(const char *szKey, const char *szDefault) const
+{
+  PathChanger path(this, szKey);
+
+  ConfigEntry *pEntry = m_pCurrentGroup->FindEntry(path.Name());
+  if (pEntry == NULL)
+    return szDefault;
+  else
+    return pEntry->Value();
+//  return pEntry == NULL ? szDefault : pEntry->Value();
+}
+
+long wxFileConfig::Read(const char *szKey, long lDefault) const
+{
+  const char *pc = Read(szKey);
+  return pc == NULL ? lDefault : atol(pc);
+}
+
+bool wxFileConfig::Write(const char *szKey, const char *szValue)
+{
+  PathChanger path(this, szKey);
+
+  ConfigEntry *pEntry = m_pCurrentGroup->FindEntry(path.Name());
+  if ( pEntry == NULL )
+    pEntry = m_pCurrentGroup->AddEntry(path.Name());
+  pEntry->SetValue(szValue);
+
+  return TRUE;
+}
+
+bool wxFileConfig::Write(const char *szKey, long lValue)
+{
+  // ltoa() is not ANSI :-(
+  char szBuf[40];   // should be good for sizeof(long) <= 16 (128 bits)
+  sprintf(szBuf, "%ld", lValue);
+  return Write(szKey, szBuf);
+}
+
+bool wxFileConfig::Flush(bool /* bCurrentOnly */)
+{
+  if ( LineListIsEmpty() || !m_pRootGroup->IsDirty() )
+    return TRUE;
+
+  wxTempFile file(GetLocalFileName(m_strFile));
+
+  if ( !file.IsOpened() ) {
+    wxLogError("Can't open user configuration file.");
+    return FALSE;
+  }
+
+  // write all strings to file
+  for ( LineList *p = m_linesHead; p != NULL; p = p->Next() ) {
+    if ( !file.Write(p->Text() + wxTextFile::GetEOL()) ) {
+      wxLogError("Can't write user configuration file.");
+      return FALSE;
+    }
+  }
+
+  return file.Commit();
+}
+
+// ----------------------------------------------------------------------------
+// delete groups/entries
+// ----------------------------------------------------------------------------
+
+bool wxFileConfig::DeleteEntry(const char *szKey, bool bGroupIfEmptyAlso)
+{
+  PathChanger path(this, szKey);
+
+  if ( !m_pCurrentGroup->DeleteEntry(path.Name()) )
+    return FALSE;
+
+  if ( bGroupIfEmptyAlso && m_pCurrentGroup->IsEmpty() ) {
+    if ( m_pCurrentGroup != m_pRootGroup ) {
+      ConfigGroup *pGroup = m_pCurrentGroup;
+      SetPath("..");  // changes m_pCurrentGroup!
+      m_pCurrentGroup->DeleteSubgroup(pGroup->Name());
+    }
+    //else: never delete the root group
+  }
+
+  return TRUE;
+}
+
+bool wxFileConfig::DeleteGroup(const char *szKey)
+{
+  PathChanger path(this, szKey);
+
+  return m_pCurrentGroup->DeleteSubgroup(path.Name());
+}
+
+bool wxFileConfig::DeleteAll()
+{
+  const char *szFile = GetLocalFileName(m_strFile);
+  delete m_pRootGroup;
+  Init();
+
+  if ( remove(szFile) == -1 )
+    wxLogSysError("Can't delete user configuration file '%s'", szFile);
+
+  szFile = GetGlobalFileName(m_strFile);
+  if ( remove(szFile) )
+    wxLogSysError("Can't delete system configuration file '%s'", szFile);
+
+  return TRUE;
+}
+
+// ----------------------------------------------------------------------------
+// linked list functions
+// ----------------------------------------------------------------------------
+
+// append a new line to the end of the list
+wxFileConfig::LineList *wxFileConfig::LineListAppend(const wxString& str)
+{
+  LineList *pLine = new LineList(str);
+
+  if ( m_linesTail == NULL ) {
+    // list is empty
+    m_linesHead = pLine;
+  }
+  else {
+    // adjust pointers
+    m_linesTail->SetNext(pLine);
+  }
+
+  m_linesTail = pLine;
+  return m_linesTail;
+}
+
+// insert a new line after the given one
+wxFileConfig::LineList *wxFileConfig::LineListInsert(const wxString& str, 
+                                                     LineList *pLine)
+{
+  if ( pLine == NULL )
+    return LineListAppend(str);
+
+  LineList *pNewLine = new LineList(str, pLine->Next());
+  pLine->SetNext(pNewLine);
+
+  return pNewLine;
+}
+
+bool wxFileConfig::LineListIsEmpty()
+{
+  return m_linesHead == NULL;
+}
+
+// ============================================================================
+// wxFileConfig::ConfigGroup
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// ctor/dtor
+// ----------------------------------------------------------------------------
+
+// ctor
+wxFileConfig::ConfigGroup::ConfigGroup(wxFileConfig::ConfigGroup *pParent,
+                                       const wxString& strName,
+                                       wxFileConfig *pConfig)
+                         : m_strName(strName)
+{
+  m_pConfig = pConfig;
+  m_pParent = pParent;
+  m_pLine   = NULL;
+  m_bDirty  = FALSE;
+
+  m_nLastEntry = 
+  m_nLastGroup = NOT_FOUND;
+}
+
+// dtor deletes all children
+wxFileConfig::ConfigGroup::~ConfigGroup()
+{
+  // entries
+  uint n, nCount = m_aEntries.Count();
+  for ( n = 0; n < nCount; n++ )
+    delete m_aEntries[n];
+
+  // subgroups
+  nCount = m_aSubgroups.Count();
+  for ( n = 0; n < nCount; n++ )
+    delete m_aSubgroups[n];
+}
+
+// ----------------------------------------------------------------------------
+// line
+// ----------------------------------------------------------------------------
+
+void wxFileConfig::ConfigGroup::SetLine(LineList *pLine)
+{
+  wxASSERT( m_pLine == NULL ); // shouldn't be called twice
+
+  m_pLine = pLine;
+}
+
+// return the line which contains "[our name]"
+wxFileConfig::LineList *wxFileConfig::ConfigGroup::GetGroupLine()
+{
+  if ( m_pLine == NULL ) {
+    // this group wasn't present in local config file, add it now
+    if ( Parent() != NULL ) {
+      wxString strFullName;
+      strFullName << "[" << GetFullName().c_str() + 1 << "]"; // +1: no '/'
+      m_pLine = m_pConfig->LineListInsert(strFullName, 
+                                          Parent()->GetLastGroupLine());
+    }
+    else {
+      // we're the root group, yet we were not in the local file => there were
+      // only comments and blank lines in config file or nothing at all
+      // we return NULL, so that LineListInsert() will do Append()
+    }
+  }
+
+  return m_pLine;
+}
+
+// return the last line belonging to the subgroups of this group
+// (after which we can add a new subgroup)
+wxFileConfig::LineList *wxFileConfig::ConfigGroup::GetLastGroupLine()
+{
+  // if we have any subgroups, our last line is the last line of the last
+  // subgroup
+  if ( m_nLastGroup != NOT_FOUND ) {
+    return m_aSubgroups[m_nLastGroup]->GetLastGroupLine();
+  }
+
+  // if we have any entries, our last line is the last entry
+  if ( m_nLastEntry != NOT_FOUND ) {
+    return m_aEntries[m_nLastEntry]->GetLine();
+  }
+
+  // nothing at all: last line is the first one
+  return GetGroupLine();
+}
+
+// return the last line belonging to the entries of this group
+// (after which we can add a new entry)
+wxFileConfig::LineList *wxFileConfig::ConfigGroup::GetLastEntryLine()
+{
+  if ( m_nLastEntry != NOT_FOUND )
+    return m_aEntries[m_nLastEntry]->GetLine();
+  else
+    return GetGroupLine();
+}
+
+// ----------------------------------------------------------------------------
+// group name
+// ----------------------------------------------------------------------------
+
+wxString wxFileConfig::ConfigGroup::GetFullName() const
+{
+  if ( Parent() )
+    return Parent()->GetFullName() + APPCONF_PATH_SEPARATOR + Name();
+  else
+    return "";
+}
+
+// ----------------------------------------------------------------------------
+// find an item
+// ----------------------------------------------------------------------------
+
+wxFileConfig::ConfigEntry *
+wxFileConfig::ConfigGroup::FindEntry(const char *szName) const
+{
+  uint nCount = m_aEntries.Count();
+  for ( uint n = 0; n < nCount; n++ ) {
+    if ( m_aEntries[n]->Name().IsSameAs(szName, APPCONF_CASE_SENSITIVE) )
+      return m_aEntries[n];
+  }
+
+  return NULL;
+}
+
+wxFileConfig::ConfigGroup *
+wxFileConfig::ConfigGroup::FindSubgroup(const char *szName) const
+{
+  uint nCount = m_aSubgroups.Count();
+  for ( uint n = 0; n < nCount; n++ ) {
+    if ( m_aSubgroups[n]->Name().IsSameAs(szName, APPCONF_CASE_SENSITIVE) )
+      return m_aSubgroups[n];
+  }
+
+  return NULL;
+}
+
+// ----------------------------------------------------------------------------
+// create a new item
+// ----------------------------------------------------------------------------
+
+// create a new entry and add it to the current group
+wxFileConfig::ConfigEntry *
+wxFileConfig::ConfigGroup::AddEntry(const wxString& strName, int nLine)
+{
+  wxASSERT( FindEntry(strName) == NULL );
+
+  ConfigEntry *pEntry = new ConfigEntry(this, strName, nLine);
+  m_aEntries.Add(pEntry);
+
+  return pEntry;
+}
+
+// create a new group and add it to the current group
+wxFileConfig::ConfigGroup *
+wxFileConfig::ConfigGroup::AddSubgroup(const wxString& strName)
+{
+  wxASSERT( FindSubgroup(strName) == NULL );
+
+  ConfigGroup *pGroup = new ConfigGroup(this, strName, m_pConfig);
+  m_aSubgroups.Add(pGroup);
+
+  return pGroup;
+}
+
+// ----------------------------------------------------------------------------
+// delete an item
+// ----------------------------------------------------------------------------
+
+bool wxFileConfig::ConfigGroup::DeleteSubgroup(const char *szName)
+{
+  uint n, nCount = m_aSubgroups.Count();
+  for ( n = 0; n < nCount; n++ ) {
+    if ( m_aSubgroups[n]->Name().IsSameAs(szName, APPCONF_CASE_SENSITIVE) )
+      break;
+  }
+
+  if ( n == nCount )
+    return FALSE;
+
+  delete m_aSubgroups[n];
+  m_aSubgroups.Remove(n);
+  return TRUE;
+}
+
+bool wxFileConfig::ConfigGroup::DeleteEntry(const char *szName)
+{
+  uint n, nCount = m_aEntries.Count();
+  for ( n = 0; n < nCount; n++ ) {
+    if ( m_aEntries[n]->Name().IsSameAs(szName, APPCONF_CASE_SENSITIVE) )
+      break;
+  }
+
+  if ( n == nCount )
+    return FALSE;
+
+  delete m_aEntries[n];
+  m_aEntries.Remove(n);
+  return TRUE;
+}
+
+// ----------------------------------------------------------------------------
+// 
+// ----------------------------------------------------------------------------
+void wxFileConfig::ConfigGroup::SetDirty()
+{
+  m_bDirty = TRUE;
+  if ( Parent() != NULL )             // propagate upwards
+    Parent()->SetDirty();
+}
+
+// ============================================================================
+// wxFileConfig::ConfigEntry
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// ctor
+// ----------------------------------------------------------------------------
+wxFileConfig::ConfigEntry::ConfigEntry(wxFileConfig::ConfigGroup *pParent, 
+                                       const wxString& strName,
+                                       int nLine)
+                         : m_strName(strName)
+{
+  m_pParent = pParent;
+  m_nLine   = nLine;
+  m_pLine   = NULL;
+
+  m_bDirty  = FALSE;
+
+  m_bImmutable = strName[0] == APPCONF_IMMUTABLE_PREFIX;
+  if ( m_bImmutable )
+    m_strName.erase(0, 1);  // remove first character
+}
+
+// ----------------------------------------------------------------------------
+// set value
+// ----------------------------------------------------------------------------
+
+void wxFileConfig::ConfigEntry::SetLine(LineList *pLine)
+{
+  wxASSERT( m_pLine == NULL );
+
+  m_pLine = pLine;
+}
+
+// second parameter is FALSE if we read the value from file and prevents the
+// entry from being marked as 'dirty'
+void wxFileConfig::ConfigEntry::SetValue(const wxString& strValue, bool bUser)
+{
+  if ( bUser && IsImmutable() ) {
+    wxLogWarning("Attempt to change immutable key '%s' ignored.", 
+                 Name().c_str());
+    return;
+  }
+
+  // do nothing if it's the same value
+  if ( strValue == m_strValue )
+    return;
+
+  m_strValue = strValue;
+
+  if ( bUser ) {
+    wxString strVal = FilterOut(strValue);
+    wxString strLine;
+    strLine << m_strName << " = " << strVal;
+
+    if ( m_pLine != NULL ) {
+      // entry was read from the local config file, just modify the line
+      m_pLine->SetText(strLine);
+    }
+    else {
+      // add a new line to the file
+      wxASSERT( m_nLine == NOT_FOUND );   // consistency check
+
+      Group()->Config()->LineListInsert(strLine, Group()->GetLastEntryLine());
+    }
+
+    SetDirty();
+  }
+}
+
+void wxFileConfig::ConfigEntry::SetDirty()
+{
+  m_bDirty = TRUE;
+  Group()->SetDirty();
+}
+
+// ============================================================================
+// wxFileConfig::PathChanger
+// ============================================================================
+
+wxFileConfig::PathChanger::PathChanger(const wxFileConfig *pContainer,
+                                       const wxString& strEntry)
+{
+  m_pContainer = (wxFileConfig *)pContainer;
+  wxString strPath = strEntry.Before(APPCONF_PATH_SEPARATOR);
+  if ( !strPath.IsEmpty() ) {
+    // do change the path
+    m_bChanged = TRUE;
+    m_strName = strEntry.Right(APPCONF_PATH_SEPARATOR);
+    m_strOldPath = m_pContainer->GetPath();
+    m_strOldPath += APPCONF_PATH_SEPARATOR;
+    m_pContainer->SetPath(strPath);
+  }
+  else {
+    // it's a name only, without path - nothing to do
+    m_bChanged = FALSE;
+    m_strName = strEntry;
+  }
+}
+
+wxFileConfig::PathChanger::~PathChanger()
+{
+  // only restore path if it was changed
+  if ( m_bChanged ) {
+    m_pContainer->SetPath(m_strOldPath);
+  }
+}
+
+// ============================================================================
+// global functions
+// ============================================================================
+
+const char *GetGlobalFileName(const char *szFile)
+{
+  static wxString s_str;
+  s_str.Empty();
+
+  bool bNoExt = strchr(szFile, '.') == NULL;
+
+  #ifdef  __UNIX__
+    s_str << "/etc/" << szFile;
+    if ( bNoExt )
+      s_str << ".conf";
+  #else   // Windows
+#ifndef _MAX_PATH
+#define _MAX_PATH 512
+#endif
+    char szWinDir[_MAX_PATH];
+    ::GetWindowsDirectory(szWinDir, _MAX_PATH);
+    s_str << szWinDir <<  "\\" << szFile;
+    if ( bNoExt )
+      s_str << ".INI";
+  #endif  // UNIX/Win
+
+  return s_str.c_str();
+}
+
+const char *GetLocalFileName(const char *szFile)
+{
+  static wxString s_str;
+  s_str.Empty();
+
+  #ifdef  __UNIX__
+    const char *szHome = getenv("HOME");
+    if ( szHome == NULL ) {
+      // we're homeless...
+      wxLogWarning("can't find user's HOME, using current directory.");
+      szHome = ".";
+    }
+    s_str << szHome << "/." << szFile;
+  #else   // Windows
+    #ifdef  __WIN32__
+      const char *szHome = getenv("HOMEDRIVE");
+      if ( szHome == NULL )
+        szHome = "";
+      s_str << szHome;
+      szHome = getenv("HOMEPATH");
+      s_str << ( szHome == NULL ? "." : szHome ) << szFile;
+      if ( strchr(szFile, '.') == NULL )
+        s_str << ".INI";
+    #else   // Win16
+      // Win16 has no idea about home, so use the current directory instead
+      s_str << ".\\" << szFile;
+    #endif  // WIN16/32
+  #endif  // UNIX/Win
+
+  return s_str.c_str();
+}
+
+void SplitPath(wxArrayString& aParts, const char *sz)
+{
+  aParts.Empty();
+
+  wxString strCurrent;
+  const char *pc = sz;
+  for ( ;; ) {
+    if ( *pc == '\0' || *pc == APPCONF_PATH_SEPARATOR ) {
+      if ( strCurrent == "." ) {
+        // ignore
+      }
+      else if ( strCurrent == ".." ) {
+        // go up one level
+        if ( aParts.IsEmpty() )
+          wxLogWarning("'%s' has extra '..', ignored.", sz);
+        else
+          aParts.Remove(aParts.Count() - 1);
+      }
+      else if ( !strCurrent.IsEmpty() ) {
+        aParts.Add(strCurrent);
+        strCurrent.Empty();
+      }
+      //else:
+        // could log an error here, but we prefer to ignore extra '/'
+
+      if ( *pc == '\0' )
+        return;
+    }
+    else
+      strCurrent += *pc;
+
+    pc++;
+  }
+}
+
+// undo FilterOut
+wxString FilterIn(const wxString& str)
+{
+  wxString strResult;
+
+  bool bQuoted = str[0] == '"';
+
+  for ( uint n = bQuoted ? 1 : 0; n < str.Len(); n++ ) {
+    if ( str[n] == '\\' ) {
+      switch ( str[++n] ) {
+        case 'n':
+          strResult += '\n';
+          break;
+
+        case 't':
+          strResult += '\t';
+          break;
+
+        case '\\':
+          strResult += '\\';
+          break;
+
+        case '"':
+          strResult += '"';
+          break;
+      }
+    }
+    else {
+      if ( str[n] != '"' || !bQuoted )
+        strResult += str[n];
+      else if ( n != str.Len() - 1 )
+        wxLogWarning("unexpected \" at position %d in '%s'.", n, str.c_str());
+      //else: it's the last quote of a quoted string, ok
+    }
+  }
+
+  return strResult;
+}
+
+// quote the string before writing it to file
+wxString FilterOut(const wxString& str)
+{
+  wxString strResult;
+
+  // quoting is necessary to preserve spaces in the beginning of the string
+  bool bQuote = isspace(str[0]) || str[0] == '"';
+
+  if ( bQuote )
+    strResult += '"';
+
+  char c;
+  for ( uint n = 0; n < str.Len(); n++ ) {
+    switch ( str[n] ) {
+      case '\n':
+        c = 'n';
+        break;
+
+      case '\t':
+        c = 't';
+        break;
+
+      case '\\':
+        c = '\\';
+        break;
+
+      case '"':
+        if ( bQuote )
+          c = '"';
+        //else: fall through
+
+      default:
+        strResult += str[n];
+        continue;   // nothing special to do
+    }
+
+    // we get here only for special characters
+    strResult << '\\' << c;
+  }
+
+  if ( bQuote )
+    strResult += '"';
+
+  return strResult;
+}
+
+wxConfig *CreateFileConfig(const wxString& strFile, bool bLocalOnly)
+{
+  return new wxFileConfig(strFile, bLocalOnly);
+}
\ No newline at end of file
diff --git a/src/common/filefn.cpp b/src/common/filefn.cpp
new file mode 100644
index 0000000000..0c3cb57f31
--- /dev/null
+++ b/src/common/filefn.cpp
@@ -0,0 +1,1314 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        filefn.cpp
+// Purpose:     File- and directory-related functions
+// Author:      Julian Smart
+// Modified by:
+// Created:     29/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Julian Smart
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "filefn.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+#include "wx/defs.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/defs.h"
+#endif
+
+#include "wx/utils.h"
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if !defined(__WATCOMC__)
+#if !(defined(_MSC_VER) && (_MSC_VER > 800))
+#include <errno.h>
+#endif
+#endif
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <unistd.h>
+#include <dirent.h>
+
+#ifdef __WINDOWS__
+#ifndef __GNUWIN32__
+#include <direct.h>
+#include <dos.h>
+#endif
+#endif
+
+#ifdef __GNUWIN32__
+#include <sys/unistd.h>
+// #include <sys/stat.h>
+
+#ifndef __MINGW32__
+#include <std.h>
+#endif
+
+#define stricmp strcasecmp
+#endif
+
+#ifdef __BORLANDC__ // Please someone tell me which version of Borland needs
+                    // this (3.1 I believe) and how to test for it.
+                    // If this works for Borland 4.0 as well, then no worries.
+#include <dir.h>
+#endif
+
+#ifdef __WINDOWS__
+#include "windows.h"
+#endif
+
+#define _MAXPATHLEN 500
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxPathList, wxStringList)
+#endif
+
+extern char *wxBuffer;
+
+void wxPathList::Add (const wxString& path)
+{
+  wxStringList::Add ((char *)(const char *)path);
+}
+
+// Add paths e.g. from the PATH environment variable
+void wxPathList::AddEnvList (const wxString& envVariable)
+{
+  static const char PATH_TOKS[] =
+#ifdef __WINDOWS__
+	" ;"; // Don't seperate with colon in DOS (used for drive)
+#else
+	" :;";
+#endif
+
+  char *val = getenv (WXSTRINGCAST envVariable);
+  if (val && *val)
+    {
+      char *s = copystring (val);
+      char *token = strtok (s, PATH_TOKS);
+
+      if (token)
+	{
+	  Add (copystring (token));
+	  while (token)
+	    {
+	      if ((token = strtok (NULL, PATH_TOKS)) != NULL)
+		Add (wxString(token));
+	    }
+	}
+      delete[]s;
+    }
+}
+
+// Given a full filename (with path), ensure that that file can
+// be accessed again USING FILENAME ONLY by adding the path
+// to the list if not already there.
+void wxPathList::EnsureFileAccessible (const wxString& path)
+{
+  wxString path1(path);
+  char *path_only = wxPathOnly (WXSTRINGCAST path1);
+  if (path_only)
+  {
+      if (!Member (wxString(path_only)))
+	    Add (wxString(path_only));
+  }
+}
+
+bool wxPathList::Member (const wxString& path)
+{
+  for (wxNode * node = First (); node != NULL; node = node->Next ())
+  {
+      wxString path2((char *) node->Data ());
+      if (
+#if defined(__WINDOWS__) || defined(__VMS__)
+      // Case INDEPENDENT
+	  path.CompareTo (path2, wxString::ignoreCase) == 0
+#else
+      // Case sensitive File System 
+	  path.CompareTo (path2) == 0
+#endif
+	)
+	return TRUE;
+  }
+  return FALSE;
+}
+
+wxString wxPathList::FindValidPath (const wxString& file)
+{
+  if (wxFileExists (wxExpandPath(wxBuffer, file)))
+    return wxString(wxBuffer);
+
+  char buf[_MAXPATHLEN];
+  strcpy(buf, wxBuffer);
+
+  char *filename = IsAbsolutePath (buf) ? wxFileNameFromPath (buf) : (char *)buf;
+
+  for (wxNode * node = First (); node; node = node->Next ())
+    {
+      char *path = (char *) node->Data ();
+      strcpy (wxBuffer, path);
+      char ch = wxBuffer[strlen(wxBuffer)-1];
+      if (ch != '\\' && ch != '/')
+        strcat (wxBuffer, "/");
+      strcat (wxBuffer, filename);
+#ifdef __WINDOWS__
+      Unix2DosFilename (wxBuffer);
+#endif
+      if (wxFileExists (wxBuffer))
+      {
+	return wxString(wxBuffer);	// Found!
+      }
+    }				// for()
+
+  return wxString("");			// Not found
+}
+
+wxString wxPathList::FindAbsoluteValidPath (const wxString& file)
+{
+  wxString f = FindValidPath(file);
+  if (wxIsAbsolutePath(f))
+    return f;
+  else
+  {
+    char buf[500];
+    wxGetWorkingDirectory(buf, 499);
+    int len = (int)strlen(buf);
+    char lastCh = 0;
+    if (len > 0)
+      lastCh = buf[len-1];
+    if (lastCh != '/' && lastCh != '\\')
+    {
+#ifdef __WINDOWS__
+      strcat(buf, "\\");
+#else
+      strcat(buf, "/");
+#endif
+    }
+    strcat(buf, (const char *)f);
+    strcpy(wxBuffer, buf);
+    return wxString(wxBuffer);
+  }
+}
+
+bool 
+wxFileExists (const wxString& filename)
+{
+  struct stat stbuf;
+
+  if (filename && stat ((char *)(const char *)filename, &stbuf) == 0)
+    return TRUE;
+  return FALSE;
+}
+
+/* Vadim's alternative implementation
+
+// does the file exist?
+bool wxFileExists(const char *pszFileName)
+{
+  struct stat st;
+  return !access(pszFileName, 0) &&
+         !stat(pszFileName, &st) &&
+         (st.st_mode & S_IFREG);
+}
+*/
+
+bool 
+wxIsAbsolutePath (const wxString& filename)
+{
+  if (filename != "")
+    {
+      if (filename[0] == '/'
+#ifdef __VMS__
+      || (filename[0] == '[' && filename[1] != '.')
+#endif
+#ifdef __WINDOWS__
+      /* MSDOS */
+      || filename[0] == '\\' || (isalpha (filename[0]) && filename[1] == ':')
+#endif
+	)
+	return TRUE;
+    }
+  return FALSE;
+}
+
+/*
+ * Strip off any extension (dot something) from end of file,
+ * IF one exists. Inserts zero into buffer.
+ *
+ */
+ 
+void wxStripExtension(char *buffer)
+{
+  int len = strlen(buffer);
+  int i = len-1;
+  while (i > 0)
+  {
+    if (buffer[i] == '.')
+    {
+      buffer[i] = 0;
+      break;
+    }
+    i --;
+  }
+}
+
+// Destructive removal of /./ and /../ stuff
+char *wxRealPath (char *path)
+{
+#ifdef __WINDOWS__
+  static const char SEP = '\\';
+  Unix2DosFilename(path);
+#else
+  static const char SEP = '/';
+#endif
+  if (path[0] && path[1]) {
+    /* MATTHEW: special case "/./x" */
+    char *p;
+    if (path[2] == SEP && path[1] == '.')
+      p = &path[0];
+    else
+      p = &path[2];
+    for (; *p; p++)
+      {
+	if (*p == SEP)
+	  {
+	    if (p[1] == '.' && p[2] == '.' && (p[3] == SEP || p[3] == '\0'))
+	      {
+                char *q;
+		for (q = p - 1; q >= path && *q != SEP; q--);
+		if (q[0] == SEP && (q[1] != '.' || q[2] != '.' || q[3] != SEP)
+		    && (q - 1 <= path || q[-1] != SEP))
+		  {
+		    strcpy (q, p + 3);
+		    if (path[0] == '\0')
+		      {
+			path[0] = SEP;
+			path[1] = '\0';
+		      }
+#ifdef __WINDOWS__
+		    /* Check that path[2] is NULL! */
+		    else if (path[1] == ':' && !path[2])
+		      {
+			path[2] = SEP;
+			path[3] = '\0';
+		      }
+#endif
+		    p = q - 1;
+		  }
+	      }
+	    else if (p[1] == '.' && (p[2] == SEP || p[2] == '\0'))
+	      strcpy (p, p + 2);
+	  }
+      }
+  }
+  return path;
+}
+
+// Must be destroyed
+char *wxCopyAbsolutePath(const wxString& filename)
+{
+  if (filename == "")
+    return NULL;
+
+  if (! IsAbsolutePath(wxExpandPath(wxBuffer, filename))) {
+    char    buf[_MAXPATHLEN];
+    buf[0] = '\0';
+    wxGetWorkingDirectory(buf, sizeof(buf)/sizeof(char));
+    char ch = buf[strlen(buf) - 1];
+#ifdef __WINDOWS__
+    if (ch != '\\' && ch != '/')
+	strcat(buf, "\\");
+#else
+    if (ch != '/')
+	strcat(buf, "/");
+#endif
+    strcat(buf, wxBuffer);
+    return copystring( wxRealPath(buf) );
+  }
+  return copystring( wxBuffer );
+}
+
+/*-
+ Handles:
+   ~/ => home dir
+   ~user/ => user's home dir
+   If the environment variable a = "foo" and b = "bar" then:
+   Unix:
+	$a	=>	foo
+	$a$b	=>	foobar
+	$a.c	=>	foo.c
+	xxx$a	=>	xxxfoo
+	${a}!	=>	foo!
+	$(b)!	=>	bar!
+	\$a	=>	\$a
+   MSDOS:
+	$a	==>	$a
+	$(a)	==>	foo
+	$(a)$b	==>	foo$b
+	$(a)$(b)==>	foobar
+	test.$$	==>	test.$$
+ */
+
+/* input name in name, pathname output to buf. */
+
+char *wxExpandPath(char *buf, const char *name)
+{
+    register char  *d, *s, *nm;
+    char            lnm[_MAXPATHLEN];
+    int				q;
+
+    // Some compilers don't like this line.
+//    const char      trimchars[] = "\n \t";
+
+    char      trimchars[4];
+    trimchars[0] = '\n';
+    trimchars[1] = ' ';
+    trimchars[2] = '\t';
+    trimchars[3] = 0;
+
+#ifdef __WINDOWS__
+     const char     SEP = '\\';
+#else
+     const char     SEP = '/';
+#endif
+    buf[0] = '\0';
+    if (name == NULL || *name == '\0')
+	return buf;
+    nm = copystring(name); // Make a scratch copy
+    char *nm_tmp = nm;
+
+    /* Skip leading whitespace and cr */
+    while (strchr((char *)trimchars, *nm) != NULL)
+	nm++;
+    /* And strip off trailing whitespace and cr */
+    s = nm + (q = strlen(nm)) - 1;
+    while (q-- && strchr((char *)trimchars, *s) != NULL)
+	*s = '\0';
+
+    s = nm;
+    d = lnm;
+#ifdef __WINDOWS__
+    q = FALSE;
+#else
+    q = nm[0] == '\\' && nm[1] == '~';
+#endif
+
+    /* Expand inline environment variables */
+    while ((*d++ = *s)) {
+#ifndef __WINDOWS__
+	if (*s == '\\') {
+	    if ((*(d - 1) = *++s)) {
+		s++;
+		continue;
+	    } else
+		break;
+	} else
+#endif
+#ifdef __WINDOWS__
+	if (*s++ == '$' && (*s == '{' || *s == ')'))
+#else
+	if (*s++ == '$')
+#endif
+	{
+	    register char  *start = d;
+	    register        braces = (*s == '{' || *s == '(');
+	    register char  *value;
+	    while ((*d++ = *s))
+		if (braces ? (*s == '}' || *s == ')') : !(isalnum(*s) || *s == '_') )
+		    break;
+		else
+		    s++;
+	    *--d = 0;
+	    value = getenv(braces ? start + 1 : start);
+	    if (value) {
+		for ((d = start - 1); (*d++ = *value++););
+		d--;
+		if (braces && *s)
+		    s++;
+	    }
+	}
+    }
+
+    /* Expand ~ and ~user */
+    nm = lnm;
+    s = "";
+    if (nm[0] == '~' && !q)
+    {
+	/* prefix ~ */
+	if (nm[1] == SEP || nm[1] == 0)
+        {	/* ~/filename */
+	    if ((s = wxGetUserHome("")) != NULL) {
+		if (*++nm)
+		    nm++;
+	    }
+        } else
+        {		/* ~user/filename */
+	    register char  *nnm;
+	    register char  *home;
+	    for (s = nm; *s && *s != SEP; s++);
+	    int was_sep; /* MATTHEW: Was there a separator, or NULL? */
+            was_sep = (*s == SEP);
+	    nnm = *s ? s + 1 : s;
+	    *s = 0;
+	    if ((home = wxGetUserHome(wxString(nm + 1))) == NULL) {
+               if (was_sep) /* replace only if it was there: */
+ 		  *s = SEP;
+		s = "";
+	    } else {
+		nm = nnm;
+		s = home;
+	    }
+	}
+    }
+
+    d = buf;
+    if (s && *s) { /* MATTHEW: s could be NULL if user '~' didn't exist */
+	/* Copy home dir */
+	while ('\0' != (*d++ = *s++))
+	  /* loop */;
+	// Handle root home
+	if (d - 1 > buf && *(d - 2) != SEP)
+	  *(d - 1) = SEP;
+    }
+    s = nm;
+    while ((*d++ = *s++));
+
+    delete[] nm_tmp; // clean up alloc
+    /* Now clean up the buffer */
+    return wxRealPath(buf);
+}
+
+
+/* Contract Paths to be build upon an environment variable
+   component:
+
+   example: "/usr/openwin/lib", OPENWINHOME --> ${OPENWINHOME}/lib
+
+   The call wxExpandPath can convert these back!
+ */
+char *
+wxContractPath (const wxString& filename, const wxString& envname, const wxString& user)
+{
+  static char dest[_MAXPATHLEN];
+
+  if (filename == "")
+    return NULL;
+
+  strcpy (dest, WXSTRINGCAST filename);
+#ifdef __WINDOWS__
+  Unix2DosFilename(dest);
+#endif
+
+  // Handle environment
+  char *val = NULL;
+  char *tcp = NULL;
+  if (envname != NULL && (val = getenv (WXSTRINGCAST envname)) != NULL &&
+     (tcp = strstr (dest, val)) != NULL)
+    {
+        strcpy (wxBuffer, tcp + strlen (val));
+        *tcp++ = '$';
+        *tcp++ = '{';
+        strcpy (tcp, WXSTRINGCAST envname);
+        strcat (tcp, "}");
+        strcat (tcp, wxBuffer);
+    }
+
+  // Handle User's home (ignore root homes!)
+  size_t len = 0;
+  if ((val = wxGetUserHome (user)) != NULL &&
+      (len = strlen(val)) > 2 &&
+      strncmp(dest, val, len) == 0)
+    {
+      strcpy(wxBuffer, "~");
+      if (user && *user)
+	strcat(wxBuffer, user);
+#ifdef __WINDOWS__
+//      strcat(wxBuffer, "\\");
+#else
+//      strcat(wxBuffer, "/");
+#endif
+      strcat(wxBuffer, dest + len);
+      strcpy (dest, wxBuffer);
+    }
+
+  return dest;
+}
+
+// Return just the filename, not the path
+// (basename)
+char *wxFileNameFromPath (char *path)
+{
+  if (path)
+    {
+      register char *tcp;
+
+      tcp = path + strlen (path);
+      while (--tcp >= path)
+	{
+	  if (*tcp == '/' || *tcp == '\\'
+#ifdef __VMS__
+     || *tcp == ':' || *tcp == ']')
+#else
+     )
+#endif
+	    return tcp + 1;
+	}			/* while */
+#ifdef __WINDOWS__
+      if (isalpha (*path) && *(path + 1) == ':')
+	return path + 2;
+#endif
+    }
+  return path;
+}
+
+wxString wxFileNameFromPath (const wxString& path1)
+{
+  if (path1 != "")
+  {
+
+      char *path = WXSTRINGCAST path1 ;
+      register char *tcp;
+
+      tcp = path + strlen (path);
+      while (--tcp >= path)
+	  {
+	    if (*tcp == '/' || *tcp == '\\'
+#ifdef __VMS__
+        || *tcp == ':' || *tcp == ']')
+#else
+        )
+#endif
+	        return wxString(tcp + 1);
+	    }			/* while */
+#ifdef __WINDOWS__
+      if (isalpha (*path) && *(path + 1) == ':')
+	    return wxString(path + 2);
+#endif
+    }
+  return wxString("");
+}
+
+// Return just the directory, or NULL if no directory
+char *
+wxPathOnly (char *path)
+{
+  if (path && *path)
+    {
+      static char buf[_MAXPATHLEN];
+
+      // Local copy
+      strcpy (buf, path);
+
+      int l = strlen(path);
+      bool done = FALSE;
+
+      int i = l - 1;
+
+      // Search backward for a backward or forward slash
+      while (!done && i > -1)
+      {
+        // ] is for VMS
+        if (path[i] == '/' || path[i] == '\\' || path[i] == ']')
+        {
+          done = TRUE;
+#ifdef __VMS__
+          buf[i+1] = 0;
+#else
+          buf[i] = 0;
+#endif
+
+          return buf;
+        }
+        else i --;
+      }
+
+#ifdef __WINDOWS__
+      // Try Drive specifier
+      if (isalpha (buf[0]) && buf[1] == ':')
+	{
+	  // A:junk --> A:. (since A:.\junk Not A:\junk)
+	  buf[2] = '.';
+	  buf[3] = '\0';
+	  return buf;
+	}
+#endif
+    }
+
+  return NULL;
+}
+
+// Return just the directory, or NULL if no directory
+wxString wxPathOnly (const wxString& path)
+{
+  if (path != "")
+    {
+      char buf[_MAXPATHLEN];
+
+      // Local copy
+      strcpy (buf, WXSTRINGCAST path);
+
+      int l = path.Length();
+      bool done = FALSE;
+
+      int i = l - 1;
+
+      // Search backward for a backward or forward slash
+      while (!done && i > -1)
+      {
+        // ] is for VMS
+        if (path[i] == '/' || path[i] == '\\' || path[i] == ']')
+        {
+          done = TRUE;
+#ifdef __VMS__
+          buf[i+1] = 0;
+#else
+          buf[i] = 0;
+#endif
+
+          return wxString(buf);
+        }
+        else i --;
+      }
+
+#ifdef __WINDOWS__
+      // Try Drive specifier
+      if (isalpha (buf[0]) && buf[1] == ':')
+	{
+	  // A:junk --> A:. (since A:.\junk Not A:\junk)
+	  buf[2] = '.';
+	  buf[3] = '\0';
+	  return wxString(buf);
+	}
+#endif
+    }
+
+  return wxString("");
+}
+
+// Utility for converting delimiters in DOS filenames to UNIX style
+// and back again - or we get nasty problems with delimiters.
+// Also, convert to lower case, since case is significant in UNIX.
+
+void 
+wxDos2UnixFilename (char *s)
+{
+  if (s)
+    while (*s)
+      {
+	if (*s == '\\')
+	  *s = '/';
+#ifdef __WINDOWS__
+	else
+	  *s = wxToLower (*s);	// Case INDEPENDENT
+#endif
+	s++;
+      }
+}
+
+void 
+wxUnix2DosFilename (char *WXUNUSED(s))
+{
+// Yes, I really mean this to happen under DOS only! JACS
+#ifdef __WINDOWS__
+  if (s)
+    while (*s)
+      {
+	if (*s == '/')
+	  *s = '\\';
+	s++;
+      }
+#endif
+}
+
+// Concatenate two files to form third
+bool 
+wxConcatFiles (const wxString& file1, const wxString& file2, const wxString& file3)
+{
+  char *outfile = wxGetTempFileName("cat");
+
+  FILE *fp1 = NULL;
+  FILE *fp2 = NULL;
+  FILE *fp3 = NULL;
+  // Open the inputs and outputs
+  if ((fp1 = fopen (WXSTRINGCAST file1, "rb")) == NULL ||
+      (fp2 = fopen (WXSTRINGCAST file2, "rb")) == NULL ||
+      (fp3 = fopen (outfile, "wb")) == NULL)
+    {
+      if (fp1)
+	fclose (fp1);
+      if (fp2)
+	fclose (fp2);
+      if (fp3)
+	fclose (fp3);
+      return FALSE;
+    }
+
+  int ch;
+  while ((ch = getc (fp1)) != EOF)
+    (void) putc (ch, fp3);
+  fclose (fp1);
+
+  while ((ch = getc (fp2)) != EOF)
+    (void) putc (ch, fp3);
+  fclose (fp2);
+
+  fclose (fp3);
+  bool result = wxRenameFile(outfile, file3);
+  delete[] outfile;
+  return result;
+}
+
+// Copy files
+bool 
+wxCopyFile (const wxString& file1, const wxString& file2)
+{
+  FILE *fd1;
+  FILE *fd2;
+  int ch;
+
+  if ((fd1 = fopen (WXSTRINGCAST file1, "rb")) == NULL)
+    return FALSE;
+  if ((fd2 = fopen (WXSTRINGCAST file2, "wb")) == NULL)
+    {
+      fclose (fd1);
+      return FALSE;
+    }
+
+  while ((ch = getc (fd1)) != EOF)
+    (void) putc (ch, fd2);
+
+  fclose (fd1);
+  fclose (fd2);
+  return TRUE;
+}
+
+bool 
+wxRenameFile (const wxString& file1, const wxString& file2)
+{
+  // Normal system call
+  if (0 == rename (WXSTRINGCAST file1, WXSTRINGCAST file2))
+    return TRUE;
+  // Try to copy
+  if (wxCopyFile(file1, file2)) {
+    wxRemoveFile(file1);
+    return TRUE;
+  }
+  // Give up
+  return FALSE;
+}
+
+bool wxRemoveFile(const wxString& file)
+{
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+  int flag = remove(WXSTRINGCAST file);
+#else
+  int flag = unlink(WXSTRINGCAST file);
+#endif
+  return (flag == 0) ;
+}
+
+bool wxMkdir(const wxString& dir)
+{
+#ifdef __VMS__
+	return FALSE;
+#elif (defined(__GNUWIN32__) && !defined(__MINGW32__)) || !defined(__WINDOWS__)
+  return (mkdir (WXSTRINGCAST dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0);
+#else
+  return (mkdir(WXSTRINGCAST dir) == 0);
+#endif
+}
+
+bool wxRmdir(const wxString& dir, int WXUNUSED(flags))
+{
+#ifdef __VMS__
+  return FALSE;
+#else
+  return (rmdir(WXSTRINGCAST dir) == 0);
+#endif
+}
+
+#if 0
+bool wxDirExists(const wxString& dir)
+{
+#ifdef __VMS__
+  return FALSE;
+#elif !defined(__WINDOWS__)
+  struct stat sbuf;
+  return (stat(dir, &sbuf) != -1) && S_ISDIR(sbuf.st_mode) ? TRUE : FALSE;
+#else
+
+  /* MATTHEW: [6] Always use same code for Win32, call FindClose */
+#if defined(__WIN32__)
+  WIN32_FIND_DATA fileInfo;
+#else
+#ifdef __BORLANDC__
+  struct ffblk fileInfo;
+#else
+  struct find_t fileInfo;
+#endif
+#endif
+
+#if defined(__WIN32__)
+	HANDLE h = FindFirstFile((LPTSTR) WXSTRINGCAST dir,(LPWIN32_FIND_DATA)&fileInfo);
+
+	if (h==INVALID_HANDLE_VALUE)
+	 return FALSE;
+	else {
+	 FindClose(h);
+	 return ((fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
+	}
+#else
+  // In Borland findfirst has a different argument
+  // ordering from _dos_findfirst. But _dos_findfirst
+  // _should_ be ok in both MS and Borland... why not?
+#ifdef __BORLANDC__
+  return ((findfirst(WXSTRINGCAST dir, &fileInfo, _A_SUBDIR) == 0  && (fileInfo.ff_attrib & _A_SUBDIR) != 0));
+#else
+  return (((_dos_findfirst(WXSTRINGCAST dir, _A_SUBDIR, &fileInfo) == 0) && (fileInfo.attrib & _A_SUBDIR)) != 0);
+#endif
+#endif
+
+#endif
+}
+
+#endif
+
+// does the path exists? (may have or not '/' or '\\' at the end)
+bool wxPathExists(const char *pszPathName)
+{
+  // Windows API returns -1 from stat for "c:\dir\" if "c:\dir" exists
+  // OTOH, we should change "d:" to "d:\" and leave "\" as is.
+  wxString strPath(pszPathName);
+  if ( wxEndsWithPathSeparator(pszPathName) && pszPathName[1] != '\0' )
+    strPath.Last() = '\0';
+
+  struct stat st;
+  return stat(strPath, &st) == 0 && (st.st_mode & S_IFDIR);
+}
+
+// Get a temporary filename, opening and closing the file.
+char *wxGetTempFileName(const wxString& prefix, char *buf)
+{
+#ifdef __WINDOWS__
+
+#ifndef	__WIN32__
+  char tmp[144];
+  ::GetTempFileName(0, WXSTRINGCAST prefix, 0, tmp);
+#else
+  char tmp[MAX_PATH];
+  char tmpPath[MAX_PATH];
+  ::GetTempPath(MAX_PATH, tmpPath);
+  ::GetTempFileName(tmpPath, WXSTRINGCAST prefix, 0, tmp);
+#endif
+  if (buf) strcpy(buf, tmp);
+  else buf = copystring(tmp);
+  return buf;
+
+#else
+  static short last_temp = 0;	// cache last to speed things a bit
+  // At most 1000 temp files to a process! We use a ring count.
+  char tmp[100];
+
+  for (short suffix = last_temp + 1; suffix != last_temp; ++suffix %= 1000)
+    {
+      sprintf (tmp, "/tmp/%s%d.%03x", WXSTRINGCAST prefix, (int) getpid (), (int) suffix);
+      if (!wxFileExists( tmp ))
+	{
+	  // Touch the file to create it (reserve name)
+	  FILE *fd = fopen (tmp, "w");
+	  if (fd)
+	    fclose (fd);
+	  last_temp = suffix;
+          if (buf)
+	    strcpy( buf, tmp);
+	  else
+	    buf = copystring( tmp );
+	  return buf;
+	}
+    }
+  cerr << "wxWindows: error finding temporary file name.\n";
+  if (buf) buf[0] = 0;
+  return NULL;
+#endif
+}
+
+// Get first file name matching given wild card.
+
+#ifdef __UNIX__
+
+// Get first file name matching given wild card.
+// Flags are reserved for future use.
+
+#ifndef __VMS__
+static DIR *wxDirStream = NULL;
+static char *wxFileSpec = NULL;
+static int wxFindFileFlags = 0;
+#endif
+
+char *wxFindFirstFile(const char *spec, int flags)
+{
+#ifndef __VMS__
+  if (wxDirStream)
+    closedir(wxDirStream); // edz 941103: better housekeping
+
+  wxFindFileFlags = flags;
+
+  if (wxFileSpec)
+    delete[] wxFileSpec;
+  wxFileSpec = copystring(spec);
+
+  // Find path only so we can concatenate
+  // found file onto path
+  char *p = wxPathOnly(wxFileSpec);
+
+  /* MATTHEW: special case: path is really "/" */
+  if (p && !*p && *wxFileSpec == '/')
+    p = "/";
+  /* MATTHEW: p is NULL => Local directory */
+  if (!p)
+    p = ".";
+    
+  if ((wxDirStream=opendir(p))==NULL)
+    return NULL;
+
+ /* MATTHEW: [5] wxFindNextFile can do the rest of the work */
+  return wxFindNextFile();
+#endif
+ // ifndef __VMS__
+  return NULL;
+}
+
+char *wxFindNextFile(void)
+{
+#ifndef __VMS__
+  static char buf[400];
+
+  /* MATTHEW: [2] Don't crash if we read too many times */
+  if (!wxDirStream)
+    return NULL;
+
+  // Find path only so we can concatenate
+  // found file onto path
+  char *p = wxPathOnly(wxFileSpec);
+  char *n = wxFileNameFromPath(wxFileSpec);
+
+  /* MATTHEW: special case: path is really "/" */
+  if (p && !*p && *wxFileSpec == '/')
+    p = "/";
+
+  // Do the reading
+  struct dirent *nextDir;
+  for (nextDir = readdir(wxDirStream); nextDir != NULL; nextDir = readdir(wxDirStream))
+  {
+
+    /* MATTHEW: [5] Only return "." and ".." when they match, and only return
+       directories when flags & wxDIR */
+    if (wxMatchWild(n, nextDir->d_name)) {
+      bool isdir;
+
+      buf[0] = 0;
+      if (p && *p) {
+        strcpy(buf, p);
+        if (strcmp(p, "/") != 0)
+          strcat(buf, "/");
+      }
+      strcat(buf, nextDir->d_name);
+
+      if ((strcmp(nextDir->d_name, ".") == 0) ||
+	  (strcmp(nextDir->d_name, "..") == 0)) {
+	if (wxFindFileFlags && !(wxFindFileFlags & wxDIR))
+	  continue;
+	isdir = TRUE;
+      } else
+	isdir = wxDirExists(buf);
+      
+      if (!wxFindFileFlags
+	  || ((wxFindFileFlags & wxDIR) && isdir)
+	  || ((wxFindFileFlags & wxFILE) && !isdir))
+	return buf;
+    }
+  }
+  closedir(wxDirStream);
+  wxDirStream = NULL;
+#endif
+ // ifndef __VMS__
+
+  return NULL;
+}
+
+#elif defined(__WINDOWS__)
+
+#ifdef __WIN32__
+HANDLE wxFileStrucHandle = INVALID_HANDLE_VALUE;
+WIN32_FIND_DATA wxFileStruc;
+#else
+#ifdef __BORLANDC__
+static struct ffblk wxFileStruc;
+#else
+static struct _find_t wxFileStruc;
+#endif
+#endif
+static wxString wxFileSpec = "";
+static int wxFindFileFlags;
+
+char *wxFindFirstFile(const wxString& spec, int flags)
+{
+  wxFileSpec = spec;
+  wxFindFileFlags = flags; /* MATTHEW: [5] Remember flags */
+
+  // Find path only so we can concatenate
+  // found file onto path
+  wxString path1(wxFileSpec);
+  char *p = wxPathOnly(WXSTRINGCAST path1);
+  if (p && (strlen(p) > 0))
+	 strcpy(wxBuffer, p);
+  else
+	 wxBuffer[0] = 0;
+
+#ifdef __WIN32__
+  if (wxFileStrucHandle != INVALID_HANDLE_VALUE)
+	 FindClose(wxFileStrucHandle);
+
+  wxFileStrucHandle = ::FindFirstFile(WXSTRINGCAST spec, &wxFileStruc);
+
+  if (wxFileStrucHandle == INVALID_HANDLE_VALUE)
+	 return NULL;
+
+  bool isdir = !!(wxFileStruc.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
+
+  if (isdir && !(flags & wxDIR))
+	 return wxFindNextFile();
+  else if (!isdir && flags && !(flags & wxFILE))
+	 return wxFindNextFile();
+
+  if (wxBuffer[0] != 0)
+	 strcat(wxBuffer, "\\");
+  strcat(wxBuffer, wxFileStruc.cFileName);
+  return wxBuffer;
+#else
+
+  int flag = _A_NORMAL;
+  if (flags & wxDIR) /* MATTHEW: [5] Use & */
+    flag = _A_SUBDIR;
+
+#ifdef __BORLANDC__
+  if (findfirst(WXSTRINGCAST spec, &wxFileStruc, flag) == 0)
+#else
+  if (_dos_findfirst(WXSTRINGCAST spec, flag, &wxFileStruc) == 0)
+#endif
+  {
+    /* MATTHEW: [5] Check directory flag */
+    char attrib;
+
+#ifdef __BORLANDC__
+    attrib = wxFileStruc.ff_attrib;
+#else
+    attrib = wxFileStruc.attrib;
+#endif
+
+    if (attrib & _A_SUBDIR) {
+      if (!(wxFindFileFlags & wxDIR))
+	return wxFindNextFile();
+    } else if (wxFindFileFlags && !(wxFindFileFlags & wxFILE))
+		return wxFindNextFile();
+
+	 if (wxBuffer[0] != 0)
+		strcat(wxBuffer, "\\");
+
+#ifdef __BORLANDC__
+	 strcat(wxBuffer, wxFileStruc.ff_name);
+#else
+	 strcat(wxBuffer, wxFileStruc.name);
+#endif
+	 return wxBuffer;
+  }
+  else
+    return NULL;
+#endif // __WIN32__
+}
+
+char *wxFindNextFile(void)
+{
+  // Find path only so we can concatenate
+  // found file onto path
+  wxString p2(wxFileSpec);
+  char *p = wxPathOnly(WXSTRINGCAST p2);
+  if (p && (strlen(p) > 0))
+	 strcpy(wxBuffer, p);
+  else
+	 wxBuffer[0] = 0;
+  
+ try_again:
+
+#ifdef __WIN32__
+  if (wxFileStrucHandle == INVALID_HANDLE_VALUE)
+	 return NULL;
+
+  bool success = (FindNextFile(wxFileStrucHandle, &wxFileStruc) != 0);
+  if (!success) {
+		FindClose(wxFileStrucHandle);
+      wxFileStrucHandle = INVALID_HANDLE_VALUE;
+		return NULL;
+  }
+
+  bool isdir = !!(wxFileStruc.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
+
+  if (isdir && !(wxFindFileFlags & wxDIR))
+    goto try_again;
+  else if (!isdir && wxFindFileFlags && !(wxFindFileFlags & wxFILE))
+	 goto try_again;
+
+  if (wxBuffer[0] != 0)
+    strcat(wxBuffer, "\\");
+  strcat(wxBuffer, wxFileStruc.cFileName);
+  return wxBuffer;  
+#else
+
+#ifdef __BORLANDC__
+  if (findnext(&wxFileStruc) == 0)
+#else
+  if (_dos_findnext(&wxFileStruc) == 0)
+#endif
+  {
+    /* MATTHEW: [5] Check directory flag */
+    char attrib;
+
+#ifdef __BORLANDC__
+    attrib = wxFileStruc.ff_attrib;
+#else
+    attrib = wxFileStruc.attrib;
+#endif
+
+    if (attrib & _A_SUBDIR) {
+      if (!(wxFindFileFlags & wxDIR))
+	goto try_again;
+    } else if (wxFindFileFlags && !(wxFindFileFlags & wxFILE))
+      goto try_again;
+
+
+	 if (wxBuffer[0] != 0)
+      strcat(wxBuffer, "\\");
+#ifdef __BORLANDC__
+	 strcat(wxBuffer, wxFileStruc.ff_name);
+#else
+	 strcat(wxBuffer, wxFileStruc.name);
+#endif
+	 return wxBuffer;
+  }
+  else
+    return NULL;
+#endif
+}
+
+#endif
+ // __WINDOWS__
+
+// Get current working directory.
+// If buf is NULL, allocates space using new, else
+// copies into buf.
+char *wxGetWorkingDirectory(char *buf, int sz)
+{
+  if (!buf)
+    buf = new char[sz+1];
+#ifdef _MSC_VER
+  if (_getcwd(buf, sz) == NULL) {
+#else
+  if (getcwd(buf, sz) == NULL) {
+#endif
+    buf[0] = '.';
+    buf[1] = '\0';
+  }
+  return buf;
+}
+
+bool wxSetWorkingDirectory(const wxString& d)
+{
+#ifdef __UNIX__
+  return (chdir(d) == 0);
+#elif defined(__WINDOWS__)
+
+#ifdef __WIN32__
+  return (bool)(SetCurrentDirectory(d) != 0);
+#else
+  // Must change drive, too.
+  bool isDriveSpec = ((strlen(d) > 1) && (d[1] == ':'));
+  if (isDriveSpec)
+  {
+    char firstChar = d[0];
+
+    // To upper case
+    if (firstChar > 90)
+      firstChar = firstChar - 32;
+
+    // To a drive number
+    unsigned int driveNo = firstChar - 64;
+    if (driveNo > 0)
+    {
+       unsigned int noDrives;
+       _dos_setdrive(driveNo, &noDrives);
+    }
+  }
+  bool success = (chdir(WXSTRINGCAST d) == 0);
+
+  return success;
+#endif
+
+#endif
+}
+
+bool wxEndsWithPathSeparator(const char *pszFileName)
+{
+  size_t len = Strlen(pszFileName);
+  if ( len == 0 )
+    return FALSE;
+  else
+    return wxIsPathSeparator(pszFileName[len - 1]);
+}
+
+// find a file in a list of directories, returns false if not found
+bool wxFindFileInPath(wxString *pStr, const char *pszPath, const char *pszFile)
+{
+  // we assume that it's not empty
+  wxCHECK_RET( Strlen(pszFile) != 0, FALSE);
+
+  // skip path separator in the beginning of the file name if present
+  if ( wxIsPathSeparator(*pszFile) )
+    pszFile++;
+
+  // copy the path (strtok will modify it)
+  char *szPath = new char[strlen(pszPath) + 1];
+  strcpy(szPath, pszPath);
+
+  wxString strFile;
+  char *pc;
+  for ( pc = strtok(szPath, PATH_SEP); pc; pc = strtok(NULL, PATH_SEP) ) {
+    // search for the file in this directory
+    strFile = pc;
+    if ( !wxEndsWithPathSeparator(pc) )
+      strFile += FILE_SEP_PATH;
+    strFile += pszFile;
+
+    if ( FileExists(strFile) ) {
+      *pStr = strFile;
+      break;
+    }
+  }
+
+  delete [] szPath;
+
+  return pc != NULL;  // if true => we breaked from the loop
+}
+
diff --git a/src/common/gdicmn.cpp b/src/common/gdicmn.cpp
new file mode 100644
index 0000000000..edf16d508e
--- /dev/null
+++ b/src/common/gdicmn.cpp
@@ -0,0 +1,603 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        gdicmn.cpp
+// Purpose:     Common GDI classes
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "gdicmn.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#include "wx/gdicmn.h"
+#include "wx/brush.h"
+#include "wx/pen.h"
+#include "wx/bitmap.h"
+#include "wx/icon.h"
+#include "wx/cursor.h"
+#include "wx/font.h"
+#include "wx/palette.h"
+
+#include <string.h>
+
+#ifdef __WINDOWS__
+#include <windows.h>
+#endif
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxRect, wxObject)
+IMPLEMENT_CLASS(wxColourDatabase, wxList)
+IMPLEMENT_DYNAMIC_CLASS(wxFontList, wxList)
+IMPLEMENT_DYNAMIC_CLASS(wxPenList, wxList)
+IMPLEMENT_DYNAMIC_CLASS(wxBrushList, wxList)
+IMPLEMENT_DYNAMIC_CLASS(wxBitmapList, wxList)
+IMPLEMENT_DYNAMIC_CLASS(wxPoint, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxRealPoint, wxObject)
+#endif
+
+wxRect::wxRect(void)
+{
+    x = 0; y = 0; width = 0; height = 0;
+}
+
+wxRect::wxRect(const long xx, const long yy, const long w, const long h)
+{
+    x = xx; y = yy; width = w; height = h;
+}
+
+wxRect::wxRect(const wxPoint& topLeft, const wxPoint& bottomRight)
+{
+  x = topLeft.x;
+  y = topLeft.y;
+  width = bottomRight.x - topLeft.x;
+  height = bottomRight.y - topLeft.y;
+  
+  if (width < 0)
+  {
+    width = -width;
+    x -= width;
+  }
+  
+  if (height < 0)
+  {
+    height = -height;
+    x -= height;
+  }
+}
+
+wxRect::wxRect(const wxPoint& point, const wxSize& size)
+{
+    x = point.x; y = point.y;
+    width = size.x; height = size.y;
+}
+
+wxRect::wxRect(const wxRect& rect)
+{
+    x = rect.x; 
+    y = rect.y; 
+    width = rect.width; 
+    height = rect.height;
+}
+
+wxRect& wxRect::operator = (const wxRect& rect)
+{
+    x = rect.x; y = rect.y; width = rect.width; height = rect.height;
+    return *this;
+}
+
+bool wxRect::operator == (const wxRect& rect)
+{
+  return ((x == rect.x) &&
+          (y == rect.y) &&
+          (width == rect.width) &&
+          (height == rect.height));
+}
+
+bool wxRect::operator != (const wxRect& rect)
+{
+  return ((x != rect.x) ||
+          (y != rect.y) ||
+          (width != rect.width) ||
+          (height != rect.height));
+}
+
+wxColourDatabase::wxColourDatabase (int type):
+wxList (type)
+{
+}
+
+wxColourDatabase::~wxColourDatabase (void)
+{
+  // Cleanup Colour allocated in Initialize()
+  wxNode *node = First ();
+  while (node)
+    {
+      wxColour *col = (wxColour *) node->Data ();
+      wxNode *next = node->Next ();
+      delete col;
+      node = next;
+    }
+}
+
+// Colour database stuff
+void wxColourDatabase::Initialize (void)
+{
+  // Don't initialize for X: colours are found
+  // in FindColour below.
+  // Added: Not all
+  
+  struct cdef {
+   char *name;
+   int r,g,b;
+  };
+  cdef cc;
+  static cdef table[]={
+  
+#ifdef __WINDOWS__
+   {"AQUAMARINE",112, 219, 147},
+   {"BLACK",0, 0, 0},
+   {"BLUE", 0, 0, 255},
+   {"BLUE VIOLET", 159, 95, 159},
+   {"BROWN", 165, 42, 42},
+   {"CADET BLUE", 95, 159, 159},
+   {"CORAL", 255, 127, 0},
+   {"CORNFLOWER BLUE", 66, 66, 111},
+   {"CYAN", 0, 255, 255},
+   {"DARK GREY", 47, 47, 47},   // ?
+
+   {"DARK GREEN", 47, 79, 47},
+   {"DARK OLIVE GREEN", 79, 79, 47},
+   {"DARK ORCHID", 153, 50, 204},
+   {"DARK SLATE BLUE", 107, 35, 142},
+   {"DARK SLATE GREY", 47, 79, 79},
+   {"DARK TURQUOISE", 112, 147, 219},
+   {"DIM GREY", 84, 84, 84},
+   {"FIREBRICK", 142, 35, 35},
+   {"FOREST GREEN", 35, 142, 35},
+   {"GOLD", 204, 127, 50},
+   {"GOLDENROD", 219, 219, 112},
+   {"GREY", 128, 128, 128},
+   {"GREEN", 0, 255, 0},
+   {"GREEN YELLOW", 147, 219, 112},
+   {"INDIAN RED", 79, 47, 47},
+   {"KHAKI", 159, 159, 95},
+   {"LIGHT BLUE", 191, 216, 216},
+   {"LIGHT GREY", 192, 192, 192},
+   {"LIGHT STEEL BLUE", 143, 143, 188},
+   {"LIME GREEN", 50, 204, 50},
+   {"LIGHT MAGENTA", 255, 0, 255},
+   {"MAGENTA", 255, 0, 255},
+   {"MAROON", 142, 35, 107},
+   {"MEDIUM AQUAMARINE", 50, 204, 153},
+   {"MEDIUM GREY", 100, 100, 100},
+   {"MEDIUM BLUE", 50, 50, 204},
+   {"MEDIUM FOREST GREEN", 107, 142, 35},
+   {"MEDIUM GOLDENROD", 234, 234, 173},
+   {"MEDIUM ORCHID", 147, 112, 219},
+   {"MEDIUM SEA GREEN", 66, 111, 66},
+   {"MEDIUM SLATE BLUE", 127, 0, 255},
+   {"MEDIUM SPRING GREEN", 127, 255, 0},
+   {"MEDIUM TURQUOISE", 112, 219, 219},
+   {"MEDIUM VIOLET RED", 219, 112, 147},
+   {"MIDNIGHT BLUE", 47, 47, 79},
+   {"NAVY", 35, 35, 142},
+   {"ORANGE", 204, 50, 50},
+   {"ORANGE RED", 255, 0, 127},
+   {"ORCHID", 219, 112, 219},
+   {"PALE GREEN", 143, 188, 143},
+   {"PINK", 188, 143, 234},
+   {"PLUM", 234, 173, 234},
+   {"PURPLE", 176, 0, 255},
+   {"RED", 255, 0, 0},
+   {"SALMON", 111, 66, 66},
+   {"SEA GREEN", 35, 142, 107},
+   {"SIENNA", 142, 107, 35},
+   {"SKY BLUE", 50, 153, 204},
+   {"SLATE BLUE", 0, 127, 255},
+   {"SPRING GREEN", 0, 255, 127},
+   {"STEEL BLUE", 35, 107, 142},
+   {"TAN", 219, 147, 112},
+   {"THISTLE", 216, 191, 216},
+   {"TURQUOISE", 173, 234, 234},
+   {"VIOLET", 79, 47, 79},
+   {"VIOLET RED", 204, 50, 153},
+   {"WHEAT", 216, 216, 191},
+   {"WHITE", 255, 255, 255},
+   {"YELLOW", 255, 255, 0},
+   {"YELLOW GREEN", 153, 204, 50},
+#endif
+
+#if defined(__GTK__) || defined(__X__)
+   {"MEDIUM GOLDENROD", 234, 234, 173},
+   {"MEDIUM FOREST GREEN", 107, 142, 35},
+   {"LIGHT MAGENTA", 255, 0, 255},
+   {"MEDIUM GREY", 100, 100, 100},
+#endif
+   
+   {0,0,0,0}
+  };
+  int i;
+  for (i=0;cc=table[i],cc.name!=0;i++)
+  {
+    Append(cc.name,new wxColour(cc.r,cc.g,cc.b));
+  }
+
+}
+
+/*
+ * Changed by Ian Brown, July 1994.
+ *
+ * When running under X, the Colour Database starts off empty. The X server
+ * is queried for the colour first time after which it is entered into the
+ * database. This allows our client to use the server colour database which
+ * is hopefully gamma corrected for the display being used.
+ */
+
+wxColour *wxColourDatabase::FindColour(const wxString& colour)
+{
+  wxNode *node = Find((char *) (const char *)colour);
+  if (node)
+    return (wxColour *)node->Data();
+    
+#ifdef __WINDOWS__
+  else return NULL;
+#endif
+
+#ifdef __GTK__
+  else {
+    wxColour *col = new wxColour( colour );
+    
+    if (!(col->Ok())) {
+      delete col;
+      return NULL;
+    }
+    Append( colour, col );
+    return col;
+  }
+#endif
+
+#ifdef __X__
+  else {
+    XColor xcolour;
+
+#ifdef __MOTIF__
+    Display *display = XtDisplay(wxTheApp->topLevel) ;
+#endif
+#ifdef __XVIEW__
+    Xv_Screen screen = xv_get(xview_server, SERVER_NTH_SCREEN, 0);
+    Xv_opaque root_window = xv_get(screen, XV_ROOT);
+    Display *display = (Display *)xv_get(root_window, XV_DISPLAY);
+#endif
+
+    /* MATTHEW: [4] Use wxGetMainColormap */
+    if (!XParseColor(display, wxGetMainColormap(display), colour,&xcolour))
+      return NULL;
+
+    unsigned char r = (unsigned char)(xcolour.red >> 8);
+    unsigned char g = (unsigned char)(xcolour.green >> 8);
+    unsigned char b = (unsigned char)(xcolour.blue >> 8);
+
+    wxColour *col = new wxColour(r, g, b);
+    Append(colour, col);
+
+    return col;
+  }
+#endif
+}
+
+wxString wxColourDatabase::FindName (const wxColour& colour) const
+{
+  unsigned char red = colour.Red ();
+  unsigned char green = colour.Green ();
+  unsigned char blue = colour.Blue ();
+
+  for (wxNode * node = First (); node; node = node->Next ())
+  {
+      wxColour *col = (wxColour *) node->Data ();
+      if (col->Red () == red && col->Green () == green && col->Blue () == blue)
+	{
+	  char *found = node->key.string;
+	  if (found)
+	    return wxString(found);
+	}
+  }
+  return wxString("");			// Not Found
+
+}
+
+void 
+wxInitializeStockObjects (void)
+{
+  wxTheBrushList = new wxBrushList;
+  wxThePenList = new wxPenList;
+  wxTheFontList = new wxFontList;
+  wxTheBitmapList = new wxBitmapList;
+
+#ifdef __MOTIF__
+#endif
+#ifdef __X__
+  wxFontPool = new XFontPool;
+#endif
+
+  wxNORMAL_FONT = new wxFont (12, wxMODERN, wxNORMAL, wxNORMAL);
+  wxSMALL_FONT = new wxFont (10, wxSWISS, wxNORMAL, wxNORMAL);
+  wxITALIC_FONT = new wxFont (12, wxROMAN, wxITALIC, wxNORMAL);
+  wxSWISS_FONT = new wxFont (12, wxSWISS, wxNORMAL, wxNORMAL);
+
+  wxRED_PEN = new wxPen ("RED", 1, wxSOLID);
+  wxCYAN_PEN = new wxPen ("CYAN", 1, wxSOLID);
+  wxGREEN_PEN = new wxPen ("GREEN", 1, wxSOLID);
+  wxBLACK_PEN = new wxPen ("BLACK", 1, wxSOLID);
+  wxWHITE_PEN = new wxPen ("WHITE", 1, wxSOLID);
+  wxTRANSPARENT_PEN = new wxPen ("BLACK", 1, wxTRANSPARENT);
+  wxBLACK_DASHED_PEN = new wxPen ("BLACK", 1, wxSHORT_DASH);
+  wxGREY_PEN = new wxPen ("GREY", 1, wxSOLID);
+  wxMEDIUM_GREY_PEN = new wxPen ("MEDIUM GREY", 1, wxSOLID);
+  wxLIGHT_GREY_PEN = new wxPen ("LIGHT GREY", 1, wxSOLID);
+
+  wxBLUE_BRUSH = new wxBrush ("BLUE", wxSOLID);
+  wxGREEN_BRUSH = new wxBrush ("GREEN", wxSOLID);
+  wxWHITE_BRUSH = new wxBrush ("WHITE", wxSOLID);
+  wxBLACK_BRUSH = new wxBrush ("BLACK", wxSOLID);
+  wxTRANSPARENT_BRUSH = new wxBrush ("BLACK", wxTRANSPARENT);
+  wxCYAN_BRUSH = new wxBrush ("CYAN", wxSOLID);
+  wxRED_BRUSH = new wxBrush ("RED", wxSOLID);
+  wxGREY_BRUSH = new wxBrush ("GREY", wxSOLID);
+  wxMEDIUM_GREY_BRUSH = new wxBrush ("MEDIUM GREY", wxSOLID);
+  wxLIGHT_GREY_BRUSH = new wxBrush ("LIGHT GREY", wxSOLID);
+
+  wxBLACK = new wxColour ("BLACK");
+  wxWHITE = new wxColour ("WHITE");
+  wxRED = new wxColour ("RED");
+  wxBLUE = new wxColour ("BLUE");
+  wxGREEN = new wxColour ("GREEN");
+  wxCYAN = new wxColour ("CYAN");
+  wxLIGHT_GREY = new wxColour ("LIGHT GREY");
+
+  wxSTANDARD_CURSOR = new wxCursor (wxCURSOR_ARROW);
+  wxHOURGLASS_CURSOR = new wxCursor (wxCURSOR_WAIT);
+  wxCROSS_CURSOR = new wxCursor (wxCURSOR_CROSS);
+}
+
+void 
+wxDeleteStockObjects (void)
+{
+  DELETEP(wxNORMAL_FONT);
+  DELETEP(wxSMALL_FONT);
+  DELETEP(wxITALIC_FONT);
+  DELETEP(wxSWISS_FONT);
+
+  DELETEP(wxRED_PEN);
+  DELETEP(wxCYAN_PEN);
+  DELETEP(wxGREEN_PEN);
+  DELETEP(wxBLACK_PEN);
+  DELETEP(wxWHITE_PEN);
+  DELETEP(wxTRANSPARENT_PEN);
+  DELETEP(wxBLACK_DASHED_PEN);
+  DELETEP(wxGREY_PEN);
+  DELETEP(wxMEDIUM_GREY_PEN);
+  DELETEP(wxLIGHT_GREY_PEN);
+
+  DELETEP(wxBLUE_BRUSH);
+  DELETEP(wxGREEN_BRUSH);
+  DELETEP(wxWHITE_BRUSH);
+  DELETEP(wxBLACK_BRUSH);
+  DELETEP(wxTRANSPARENT_BRUSH);
+  DELETEP(wxCYAN_BRUSH);
+  DELETEP(wxRED_BRUSH);
+  DELETEP(wxGREY_BRUSH);
+  DELETEP(wxMEDIUM_GREY_BRUSH);
+  DELETEP(wxLIGHT_GREY_BRUSH);
+
+  DELETEP(wxBLACK);
+  DELETEP(wxWHITE);
+  DELETEP(wxRED);
+  DELETEP(wxBLUE);
+  DELETEP(wxGREEN);
+  DELETEP(wxCYAN);
+  DELETEP(wxLIGHT_GREY);
+
+  DELETEP(wxSTANDARD_CURSOR);
+  DELETEP(wxHOURGLASS_CURSOR);
+  DELETEP(wxCROSS_CURSOR);
+}
+
+wxBitmapList::wxBitmapList (void)
+{
+}
+
+wxBitmapList::~wxBitmapList (void)
+{
+  wxNode *node = First ();
+  while (node)
+    {
+      wxBitmap *bitmap = (wxBitmap *) node->Data ();
+      wxNode *next = node->Next ();
+      delete bitmap;
+//      bitmap->FreeResource(TRUE);
+      node = next;
+    }
+}
+
+// Pen and Brush lists
+wxPenList::~wxPenList (void)
+{
+  wxNode *node = First ();
+  while (node)
+    {
+      wxPen *pen = (wxPen *) node->Data ();
+      wxNode *next = node->Next ();
+      delete pen;
+//      pen->FreeResource(TRUE);
+      node = next;
+    }
+}
+
+void wxPenList::AddPen (wxPen * pen)
+{
+  Append (pen);
+}
+
+void wxPenList::RemovePen (wxPen * pen)
+{
+  DeleteObject (pen);
+}
+
+wxPen *wxPenList::FindOrCreatePen (const wxColour& colour, const int width, const int style)
+{
+  for (wxNode * node = First (); node; node = node->Next ())
+    {
+      wxPen *each_pen = (wxPen *) node->Data ();
+      if (each_pen && each_pen->GetVisible() &&
+	  each_pen->GetWidth () == width &&
+	  each_pen->GetStyle () == style &&
+	  each_pen->GetColour ().Red () == colour.Red () &&
+	  each_pen->GetColour ().Green () == colour.Green () &&
+	  each_pen->GetColour ().Blue () == colour.Blue ())
+	return each_pen;
+    }
+  wxPen *pen = new wxPen (colour, width, style);
+
+  // Yes, we can return a pointer to this in a later FindOrCreatePen call,
+  // because we created it within FindOrCreatePen. Safeguards against
+  // returning a pointer to an automatic variable and hanging on to it
+  // (dangling pointer).
+  pen->SetVisible(TRUE);
+  return pen;
+}
+
+wxPen *wxPenList::FindOrCreatePen (const wxString& colour, const int width, const int style)
+{
+  wxColour *the_colour = wxTheColourDatabase->FindColour (colour);
+  if (the_colour)
+    return FindOrCreatePen (*the_colour, width, style);
+  else
+    return NULL;
+}
+
+wxBrushList::~wxBrushList (void)
+{
+  wxNode *node = First ();
+  while (node)
+    {
+      wxBrush *brush = (wxBrush *) node->Data ();
+      wxNode *next = node->Next ();
+      delete brush;
+      node = next;
+    }
+}
+
+void wxBrushList::AddBrush (wxBrush * brush)
+{
+  Append (brush);
+}
+
+wxBrush *wxBrushList::FindOrCreateBrush (const wxColour& colour, const int style)
+{
+  for (wxNode * node = First (); node; node = node->Next ())
+    {
+      wxBrush *each_brush = (wxBrush *) node->Data ();
+      if (each_brush && each_brush->GetVisible() &&
+	  each_brush->GetStyle () == style &&
+	  each_brush->GetColour ().Red () == colour.Red () &&
+	  each_brush->GetColour ().Green () == colour.Green () &&
+	  each_brush->GetColour ().Blue () == colour.Blue ())
+	return each_brush;
+    }
+  // Yes, we can return a pointer to this in a later FindOrCreateBrush call,
+  // because we created it within FindOrCreateBrush. Safeguards against
+  // returning a pointer to an automatic variable and hanging on to it
+  // (dangling pointer).
+  wxBrush *brush = new wxBrush (colour, style);
+  brush->SetVisible(TRUE);
+  return brush;
+}
+
+wxBrush *wxBrushList::FindOrCreateBrush (const wxString& colour, const int style)
+{
+  wxColour *the_colour = wxTheColourDatabase->FindColour (colour);
+  if (the_colour)
+    return FindOrCreateBrush (*the_colour, style);
+  else
+    return NULL;
+}
+
+void wxBrushList::RemoveBrush (wxBrush * brush)
+{
+  DeleteObject (brush);
+}
+
+wxFontList::~wxFontList (void)
+{
+#ifdef __WINDOWS__
+  wxNode *node = First ();
+  while (node)
+    {
+/*
+      wxFont *font = (wxFont *) node->Data ();
+      wxNode *next = node->Next ();
+      delete font;
+      node = next;
+*/
+	  // New for 2.0: don't delete the font (it may be a member
+	  // of a wxDC, for example)
+      wxFont *font = (wxFont *) node->Data ();
+      wxNode *next = node->Next ();
+
+	  // Force the font to be deleted
+      font->FreeResource(TRUE);
+      node = next;
+    }
+#endif
+}
+
+void wxFontList::AddFont (wxFont * font)
+{
+  Append (font);
+}
+
+void wxFontList::RemoveFont (wxFont * font)
+{
+  DeleteObject (font);
+}
+
+wxFont *wxFontList::
+	FindOrCreateFont (const int PointSize, const int FamilyOrFontId, const int Style, const int Weight, const bool underline, const wxString& Face)
+{
+  for (wxNode * node = First (); node; node = node->Next ())
+    {
+      wxFont *each_font = (wxFont *) node->Data ();
+      if (each_font && each_font->GetVisible() && each_font->Ok() &&
+	  each_font->GetPointSize () == PointSize &&
+	  each_font->GetStyle () == Style &&
+	  each_font->GetWeight () == Weight &&
+	  each_font->GetUnderlined () == underline &&
+#if defined(__X__) || (defined(__WINDOWS__) && USE_PORTABLE_FONTS_IN_MSW)
+	  each_font->GetFontId () == FamilyOrFontId) /* New font system */
+#else
+	  each_font->GetFamily () == FamilyOrFontId &&
+          (!each_font->GetFaceName() || each_font->GetFaceName() == Face))
+#endif
+	return each_font;
+    }
+  wxFont *font = new wxFont (PointSize, FamilyOrFontId, Style, Weight, underline, Face);
+  font->SetVisible(TRUE);
+  return font;
+}
+
+void wxBitmapList::AddBitmap(wxBitmap *bitmap)
+{ Append(bitmap); }
+void wxBitmapList::RemoveBitmap(wxBitmap *bitmap)
+{ DeleteObject(bitmap); }
+
diff --git a/src/common/glob.inc b/src/common/glob.inc
new file mode 100644
index 0000000000..c8a821d32e
--- /dev/null
+++ b/src/common/glob.inc
@@ -0,0 +1,361 @@
+/*
+ * File and other globbing (included by wb_utils.cc)
+ */
+
+// This file includes:
+//	wxIsWild(const char *pattern)
+//	wxMatchWild(const char *pattern, const char *str, bool dot_special)
+//
+
+
+//---------------------------------------------------------------------------------
+#ifndef UNIX_GLOB
+# ifdef wx_x
+#  define UNIX_GLOB 1
+# else
+#  define UNIX_GLOB 0
+# endif
+#endif
+
+#if UNIX_GLOB
+# ifdef wx_msw
+#  error "Can't use Unix file globbing under Windows!"
+# endif
+#endif
+
+/*************************************************************************
+ *
+ * wxIsWild checks whether the pattern contains wildcards, and
+ * returns TRUE if it does, and FALSE if it does not (or if the 
+ * pattern is NULL -- i.e. no string).
+ *
+ * The argument is:
+ *   
+ * 1) pattern - a character string
+ */
+bool 
+wxIsWild (const char *pattern)
+{
+  while (*pattern)
+    {
+      switch (*pattern++)
+	{
+	case '?':
+	case '*':
+#if UNIX_GLOB
+	case '[':
+	case '{':		/* } */
+#endif
+	  return TRUE;
+#if UNIX_GLOB
+	case '\\':
+	  if (!*pattern++)
+	    return FALSE;
+#endif
+	}			/* switch() */
+    }				/* while() */
+  return FALSE;
+}
+
+
+
+#if UNIX_GLOB
+
+// Unix Glob()
+//
+// Pattern        Function
+// -----------------------------------------------------
+//  '*'         = match 0 or more occurances of anything
+// "[abc]"      = match anyof "abc" (ranges supported)
+// "{xx,yy,zz}" = match anyof "xx", "yy", or "zz"
+// '?'          = match any character
+//
+//  '\'  is used to "escape" special characters
+// Recursive
+
+bool 
+wxMatchWild (const char *pattern, const char *str, bool dot_special)
+{
+  char c;
+  const char *cp;
+  bool done = FALSE, ret_code, ok;
+  // Below is for vi fans
+  const char OB = '{', CB = '}';
+
+#if 0
+  if (strcmp(pattern, "*.*") == 0)
+    pattern = "*"; // Hack for MS-DOS compat.
+#endif
+
+  // dot_special means '.' only matches '.'
+  if (dot_special && *str == '.' && *pattern != *str)
+    return FALSE;
+
+  while ((*pattern != '\0') && (!done) && (((*str == '\0') &&
+	       ((*pattern == OB) || (*pattern == '*'))) || (*str != '\0')))
+    {
+      switch (*pattern)
+	{
+	case '\\':
+	  pattern++;
+	  if (*pattern != '\0')
+	    pattern++;
+	  break;
+	case '*':
+	  pattern++;
+	  ret_code = FALSE;
+	  while ((*str != '\0') && (!(ret_code = wxMatchWild (pattern, str++, FALSE))));
+	  if (ret_code)
+	    {
+	      while (*str != '\0')
+		str++;
+	      while (*pattern != '\0')
+		pattern++;
+	    }
+	  break;
+	case '[':
+	  pattern++;
+	repeat:
+	  if ((*pattern == '\0') || (*pattern == ']'))
+	    {
+	      done = TRUE;
+	      break;
+	    }
+	  if (*pattern == '\\')
+	    {
+	      pattern++;
+	      if (*pattern == '\0')
+		{
+		  done = TRUE;
+		  break;
+		}
+	    }
+	  if (*(pattern + 1) == '-')
+	    {
+	      c = *pattern;
+	      pattern += 2;
+	      if (*pattern == ']')
+		{
+		  done = TRUE;
+		  break;
+		}
+	      if (*pattern == '\\')
+		{
+		  pattern++;
+		  if (*pattern == '\0')
+		    {
+		      done = TRUE;
+		      break;
+		    }
+		}
+	      if ((*str < c) || (*str > *pattern))
+		{
+		  pattern++;
+		  goto repeat;
+		}
+	    }
+	  else if (*pattern != *str)
+	    {
+	      pattern++;
+	      goto repeat;
+	    }
+	  pattern++;
+	  while ((*pattern != ']') && (*pattern != '\0'))
+	    {
+	      if ((*pattern == '\\') && (*(pattern + 1) != '\0'))
+		pattern++;
+	      pattern++;
+	    }			// while()
+	  if (*pattern != '\0')
+	    {
+	      pattern++, str++;
+	    }
+	  break;
+	case '?':
+	  pattern++;
+	  str++;
+	  break;
+	case OB:
+	  pattern++;
+         while ((*pattern != CB) && (*pattern != '\0'))
+	    {
+	      cp = str;
+	      ok = TRUE;
+	      while (ok && (*cp != '\0') && (*pattern != '\0') &&
+                 (*pattern != ',') && (*pattern != CB))
+		{
+		  if (*pattern == '\\')
+		    pattern++;
+		  ok = (*pattern++ == *cp++);
+		}		// while()
+	      if (*pattern == '\0')
+		{
+		  ok = FALSE;
+		  done = TRUE;
+		  break;
+		}
+	      else if (ok)
+		{
+		  str = cp;
+                   while ((*pattern != CB) && (*pattern != '\0'))
+		    {
+		      if (*++pattern == '\\')
+			{
+                      if (*++pattern == CB)
+			    pattern++;
+			}
+		    }		// while()
+		}
+	      else
+		{
+                 while (*pattern != CB && *pattern != ',' && *pattern != '\0')
+		    {
+		      if (*++pattern == '\\')
+			{
+                            if (*++pattern == CB || *pattern == ',')
+			    pattern++;
+			}
+		    }		// while()
+		}
+	      if (*pattern != '\0')
+		pattern++;
+	    }			// while()
+	  break;
+	default:
+	  if (*str == *pattern)
+	    {
+	      str++, pattern++;
+	    }
+	  else
+	    {
+	      done = TRUE;
+	    }
+	}			// switch()
+    }				// while()
+  while (*pattern == '*')
+    pattern++;
+  return ((*str == '\0') && (*pattern == '\0'));
+}
+
+#else /* MS-DOS/Windows glob() */
+/*************************************************************************
+ *
+ *  wxMatchWild matches the given pattern string against 
+ *  a text string, and returns TRUE if it matches, FALSE otherwise.
+ *
+ *  A match means that the entire text string is used up in the matching.
+ *  The pattern can contain the following wildcards.
+ * 
+ *  * -- matches any sequence of characters
+ *  ? -- matches one character
+ *
+ * If one or other or both of the string arguments to wxMatchWild function is  
+ * NULL (i.e. there isn't a string), then the function returns FALSE.
+ *
+ */
+static bool wxPatternMatch (const char *pattern, const char *text, size_t i, size_t j);
+
+// @@@@ dotSpecial is ignored by MS-DOS
+bool 
+wxMatchWild (const char *pattern, const char *text, bool /* dotSpecial */ )
+{
+  if (pattern == NULL || text == NULL || *pattern == '\0' || *text == '\0')
+    return FALSE;
+  return wxPatternMatch (pattern, text, 0, 0);
+}
+
+/*************************************************************************
+ *
+ *  wxPatternMatch does the work for wxMatchWild. wxPatternMatch  matches 
+ *  the given pattern string against a text string, and returns TRUE if 
+ *  it matches, FALSE otherwise. It is assumed that the string arguments
+ *  to wxPatternMatch exist.
+ *
+ *  A match means that the entire text string is used up in the matching.
+ *  The pattern can contain the following wildcards.
+ * 
+ *  * -- matches any sequence of characters
+ *  ? -- matches one character
+ *
+ *  wxPatternMatch works by going down the pattern trying to match the
+ *  the same index character in the pattern and string arrays, and stops
+ *  when the end of the pattern or text string is reached. However, if a
+ *  '*' wildcard is met, the algorithm checks to see whether the remaining 
+ *  pattern (after the wildcard) matches the rest of the text (i.e. the 
+ *  wxPatternMatch function is called recursively).
+ */
+// Recursive
+static bool 
+wxPatternMatch (const char *pattern, const char *text, size_t i, size_t j)
+{
+  size_t pattern_length = strlen (pattern);
+  size_t text_length = strlen (text);
+  bool match = FALSE;
+
+#ifdef wx_msw
+// MS-DOS file system is case INDEPENDENT
+# define EQU(x,y) (wxToLower(x) == wxToLower(y))
+#else
+# define EQU(x,y) ((x) == (y))
+#endif
+
+  while (j < pattern_length && i < text_length)
+    {
+      if (EQU(text[i], pattern[j]) || pattern[j] == '?')
+	{
+	  match = TRUE;
+	  i++, j++;
+	}
+      else if (pattern[j] == '*')
+	{
+	  // If pattern ends in '*'
+	  if (++j == pattern_length)
+	    {
+	      match = TRUE;
+	      i = text_length;
+	    }
+	  else
+	    {
+	      match = FALSE;
+// after wildcard check to see whether rest of pattern matches 
+	      // up with rest of text
+	      while (i < text_length && match != TRUE)
+		{
+		  match = wxPatternMatch (pattern, text, i, j);
+		  i++;
+		}
+// text index is decremented so that it points to where 
+	      // the text string starts to match the rest of the pattern
+	      i--;
+	    }
+	}
+      else if (! EQU(text[i], pattern[j]))
+	{
+	  j = pattern_length;
+	  match = FALSE;
+	}
+    }
+  if (j == pattern_length && i == text_length && match == TRUE)
+    {
+      return TRUE;
+    }
+  else
+// special case where pattern and text are the same except that pattern
+    // also only has '*' wildcards on the end
+  if (i == text_length && pattern[j] == '*' && match == TRUE)
+    {
+      for (; j < pattern_length; j++)
+	{
+	  if (pattern[j] != '*')
+	    return FALSE;
+	}
+      return TRUE;
+    }
+  else
+    {
+      return FALSE;
+    }
+}
+
+#endif /* UNIX_GLOB */
+//-----------------------------------------------------------------------------
diff --git a/src/common/hash.cpp b/src/common/hash.cpp
new file mode 100644
index 0000000000..1aba64563c
--- /dev/null
+++ b/src/common/hash.cpp
@@ -0,0 +1,350 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        hash.cpp
+// Purpose:     wxHashTable implementation
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "hash.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/list.h"
+#endif
+
+#include "wx/hash.h"
+
+#include <string.h>
+#include <stdarg.h>
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxHashTable, wxObject)
+#endif
+
+wxHashTable::wxHashTable (const int the_key_type, const int size)
+{
+  n = size;
+  current_position = -1;
+  current_node = NULL;
+
+  key_type = the_key_type;
+  hash_table = new wxList *[size];
+  int i;
+  for (i = 0; i < size; i++)
+    hash_table[i] = NULL;
+}
+
+wxHashTable::~wxHashTable (void)
+{
+  int i;
+  for (i = 0; i < n; i++)
+    if (hash_table[i])
+      delete hash_table[i];
+  delete[] hash_table;
+}
+
+bool wxHashTable::Create(const int the_key_type, const int size)
+{
+  n = size;
+  current_position = -1;
+  current_node = NULL;
+
+  key_type = the_key_type;
+  if (hash_table)
+    delete[] hash_table;
+  hash_table = new wxList *[size];
+  int i;
+  for (i = 0; i < size; i++)
+    hash_table[i] = NULL;
+  return TRUE;
+}
+
+void wxHashTable::Put (const long key, const long value, wxObject * object)
+{
+  // Should NEVER be
+  long k = (long) key;
+  if (k < 0)
+    k = -k;
+
+  int position = (int) (k % n);
+  if (!hash_table[position])
+    hash_table[position] = new wxList (wxKEY_INTEGER);
+
+  hash_table[position]->Append (value, object);
+}
+
+void wxHashTable::Put (const long key, const char *value, wxObject * object)
+{
+  // Should NEVER be
+  long k = (long) key;
+  if (k < 0)
+    k = -k;
+
+  int position = (int) (k % n);
+  if (!hash_table[position])
+    hash_table[position] = new wxList (wxKEY_INTEGER);
+
+  hash_table[position]->Append (value, object);
+}
+
+void wxHashTable::Put (const long key, wxObject * object)
+{
+  // Should NEVER be
+  long k = (long) key;
+  if (k < 0)
+    k = -k;
+
+  int position = (int) (k % n);
+  if (!hash_table[position])
+    hash_table[position] = new wxList (wxKEY_INTEGER);
+
+  hash_table[position]->Append (k, object);
+}
+
+void wxHashTable::Put (const char *key, wxObject * object)
+{
+  int position = (int) (MakeKey (key) % n);
+
+  if (!hash_table[position])
+    hash_table[position] = new wxList (wxKEY_STRING);
+
+  hash_table[position]->Append (key, object);
+}
+
+wxObject *wxHashTable::Get (const long key, const long value) const
+{
+  // Should NEVER be
+  long k = (long) key;
+  if (k < 0)
+    k = -k;
+
+  int position = (int) (k % n);
+  if (!hash_table[position])
+    return NULL;
+  else
+    {
+      wxNode *node = hash_table[position]->Find (value);
+      if (node)
+	return node->Data ();
+      else
+	return NULL;
+    }
+}
+
+wxObject *wxHashTable::Get (const long key, const char *value) const
+{
+  // Should NEVER be
+  long k = (long) key;
+  if (k < 0)
+    k = -k;
+
+  int position = (int) (k % n);
+  if (!hash_table[position])
+    return NULL;
+  else
+    {
+      wxNode *node = hash_table[position]->Find (value);
+      if (node)
+	return node->Data ();
+      else
+	return NULL;
+    }
+}
+
+wxObject *wxHashTable::Get (const long key) const
+{
+  // Should NEVER be
+  long k = (long) key;
+  if (k < 0)
+    k = -k;
+
+  int position = (int) (k % n);
+  if (!hash_table[position])
+    return NULL;
+  else
+    {
+      wxNode *node = hash_table[position]->Find (k);
+      return node ? node->Data () : (wxObject*)NULL;
+    }
+}
+
+wxObject *wxHashTable::Get (const char *key) const
+{
+  int position = (int) (MakeKey (key) % n);
+
+  if (!hash_table[position])
+    return NULL;
+  else
+    {
+      wxNode *node = hash_table[position]->Find (key);
+      return node ? node->Data () : (wxObject*)NULL;
+    }
+}
+
+wxObject *wxHashTable::Delete (const long key)
+{
+  // Should NEVER be
+  long k = (long) key;
+  if (k < 0)
+    k = -k;
+
+  int position = (int) (k % n);
+  if (!hash_table[position])
+    return NULL;
+  else
+    {
+      wxNode *node = hash_table[position]->Find (k);
+      if (node)
+	{
+	  wxObject *data = node->Data ();
+	  delete node;
+	  return data;
+	}
+      else
+	return NULL;
+    }
+}
+
+wxObject *wxHashTable::Delete (const char *key)
+{
+  int position = (int) (MakeKey (key) % n);
+  if (!hash_table[position])
+    return NULL;
+  else
+    {
+      wxNode *node = hash_table[position]->Find (key);
+      if (node)
+	{
+	  wxObject *data = node->Data ();
+	  delete node;
+	  return data;
+	}
+      else
+	return NULL;
+    }
+}
+
+wxObject *wxHashTable::Delete (const long key, const int value)
+{
+  // Should NEVER be
+  long k = (long) key;
+  if (k < 0)
+    k = -k;
+
+  int position = (int) (k % n);
+  if (!hash_table[position])
+    return NULL;
+  else
+    {
+      wxNode *node = hash_table[position]->Find (value);
+      if (node)
+	{
+	  wxObject *data = node->Data ();
+	  delete node;
+	  return data;
+	}
+      else
+	return NULL;
+    }
+}
+
+wxObject *wxHashTable::Delete (const long key, const char *value)
+{
+  int position = (int) (key % n);
+  if (!hash_table[position])
+    return NULL;
+  else
+    {
+      wxNode *node = hash_table[position]->Find (value);
+      if (node)
+	{
+	  wxObject *data = node->Data ();
+	  delete node;
+	  return data;
+	}
+      else
+	return NULL;
+    }
+}
+
+long wxHashTable::MakeKey (const char *string) const
+{
+  long int_key = 0;
+
+  while (*string)
+    int_key += (unsigned char) *string++;
+
+  return int_key;
+}
+
+void wxHashTable::BeginFind (void)
+{
+  current_position = -1;
+  current_node = NULL;
+}
+
+wxNode *wxHashTable::Next (void)
+{
+  wxNode *found = NULL;
+  bool end = FALSE;
+  while (!end && !found)
+    {
+      if (!current_node)
+	{
+	  current_position++;
+	  if (current_position >= n)
+	    {
+	      current_position = -1;
+	      current_node = NULL;
+	      end = TRUE;
+	    }
+	  else
+	    {
+	      if (hash_table[current_position])
+		{
+		  current_node = hash_table[current_position]->First ();
+		  found = current_node;
+		}
+	    }
+	}
+      else
+	{
+	  current_node = current_node->Next ();
+	  found = current_node;
+	}
+    }
+  return found;
+}
+
+void wxHashTable::DeleteContents (const bool flag)
+{
+  int i;
+  for (i = 0; i < n; i++)
+    {
+      if (hash_table[i])
+	hash_table[i]->DeleteContents (flag);
+    }
+}
+
+void wxHashTable::Clear (void)
+{
+  int i;
+  for (i = 0; i < n; i++)
+    {
+      if (hash_table[i])
+	hash_table[i]->Clear ();
+    }
+}
+
diff --git a/src/common/helpbase.cpp b/src/common/helpbase.cpp
new file mode 100644
index 0000000000..b10db8b4c1
--- /dev/null
+++ b/src/common/helpbase.cpp
@@ -0,0 +1,35 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        helpbase.cpp
+// Purpose:     Help system base classes
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "helpbase.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/defs.h"
+#endif
+
+#include "wx/helpbase.h"
+
+#if USE_HELP
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_CLASS(wxHelpControllerBase, wxObject)
+#endif
+
+#endif // USE_HELP
diff --git a/src/common/intl.cpp b/src/common/intl.cpp
new file mode 100644
index 0000000000..b5520e58b7
--- /dev/null
+++ b/src/common/intl.cpp
@@ -0,0 +1,538 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        intl.cpp
+// Purpose:     Internationalization and localisation for wxWindows
+// Author:      Vadim Zeitlin
+// Modified by:
+// Created:     29/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declaration
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#ifdef __GNUG__
+#pragma implementation "intl.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+// standard headers
+#include  <locale.h>
+
+// wxWindows
+#include "wx/defs.h"
+#include "wx/string.h"
+#include "wx/intl.h"
+#include "wx/file.h"
+#include "wx/log.h"
+#include "wx/utils.h"
+
+#include <stdlib.h>
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+// magic number identifying the .mo format file
+const uint32 MSGCATALOG_MAGIC    = 0x950412de;
+const uint32 MSGCATALOG_MAGIC_SW = 0xde120495;
+
+// extension of ".mo" files
+#define MSGCATALOG_EXTENSION  ".mo"
+
+// ----------------------------------------------------------------------------
+// global functions
+// ----------------------------------------------------------------------------
+
+// suppress further error messages about missing translations
+// (if you don't have one catalog file, you wouldn't like to see the
+//  error message for each string in it, so normally it's given only
+//  once)
+void wxSuppressTransErrors();
+
+// restore the logging
+void wxRestoreTransErrors();
+
+// get the current state
+bool wxIsLoggingTransErrors();
+
+// get the current locale object (## may be NULL!)
+extern wxLocale *wxSetLocale(wxLocale *pLocale);
+
+// ----------------------------------------------------------------------------
+// wxMsgCatalog corresponds to one disk-file message catalog.
+//
+// This is a "low-level" class and is used only by wxLocale (that's why
+// it's designed to be stored in a linked list)
+// ----------------------------------------------------------------------------
+
+class wxMsgCatalog
+{
+public:
+  // ctor & dtor
+  wxMsgCatalog();
+ ~wxMsgCatalog();
+
+  // load the catalog from disk (szDirPrefix corresponds to language)
+  bool Load(const char *szDirPrefix, const char *szName);
+  bool IsLoaded() const { return m_pData != NULL; }
+
+  // get name of the catalog
+  const char *GetName() const { return m_pszName; }
+
+  // get the translated string: returns NULL if not found
+  const char *GetString(const char *sz) const;
+
+  // public variable pointing to the next element in a linked list (or NULL)
+  wxMsgCatalog *m_pNext;
+  
+private:
+  // this implementation is binary compatible with GNU gettext() version 0.10
+
+  // an entry in the string table
+  struct wxMsgTableEntry
+  {
+    uint32   nLen;           // length of the string
+    uint32   ofsString;      // pointer to the string
+  };
+
+  // header of a .mo file
+  struct wxMsgCatalogHeader
+  {
+    uint32  magic,          // offset +00:  magic id
+            revision,       //        +04:  revision
+            numStrings;     //        +08:  number of strings in the file
+    uint32  ofsOrigTable,   //        +0C:  start of original string table
+            ofsTransTable;  //        +10:  start of translated string table
+    uint32  nHashSize,      //        +14:  hash table size
+            ofsHashTable;   //        +18:  offset of hash table start
+  };                     
+  
+  // all data is stored here, NULL if no data loaded
+  uint8 *m_pData;
+  
+  // data description
+  uint32            m_numStrings,   // number of strings in this domain
+                    m_nHashSize;    // number of entries in hash table
+  uint32           *m_pHashTable;   // pointer to hash table
+  wxMsgTableEntry  *m_pOrigTable,   // pointer to original   strings
+                   *m_pTransTable;  //            translated
+
+  const char *StringAtOfs(wxMsgTableEntry *pTable, uint32 index) const
+    { return (const char *)(m_pData + Swap(pTable[index].ofsString)); }
+
+  // utility functions
+    // calculate the hash value of given string
+  static inline uint32 GetHash(const char *sz);
+    // big<->little endian
+  inline uint32 Swap(uint32 ui) const;
+
+  // internal state
+  bool HasHashTable() const // true if hash table is present
+    { return m_nHashSize > 2 && m_pHashTable != NULL; }
+
+  bool          m_bSwapped;   // wrong endianness?
+
+  char         *m_pszName;    // name of the domain
+};
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxMsgCatalog class
+// ----------------------------------------------------------------------------
+
+// calculate hash value using the so called hashpjw function by P.J. Weinberger
+// [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools]
+uint32 wxMsgCatalog::GetHash(const char *sz)
+{
+  #define HASHWORDBITS 32     // the length of uint32
+
+  uint32 hval = 0;
+  uint32 g;
+  while ( *sz != '\0' ) {
+    hval <<= 4;
+    hval += (uint32)*sz++;
+    g = hval & ((uint32)0xf << (HASHWORDBITS - 4));
+    if ( g != 0 ) {
+      hval ^= g >> (HASHWORDBITS - 8);
+      hval ^= g;
+    }
+  }
+
+  return hval;
+}
+
+// swap the 2 halves of 32 bit integer if needed
+uint32 wxMsgCatalog::Swap(uint32 ui) const
+{
+  return m_bSwapped ? (ui << 24) | ((ui & 0xff00) << 8) | 
+                      ((ui >> 8) & 0xff00) | (ui >> 24)
+                    : ui;
+}
+
+wxMsgCatalog::wxMsgCatalog() 
+{ 
+  m_pData   = NULL;
+  m_pszName = NULL;
+}
+
+wxMsgCatalog::~wxMsgCatalog() 
+{ 
+  DELETEA(m_pData); 
+  DELETEA(m_pszName); 
+}
+
+class NoTransErr
+{
+  public:
+    NoTransErr() { wxSuppressTransErrors(); }
+   ~NoTransErr() { wxRestoreTransErrors();  }
+};
+    
+// open disk file and read in it's contents
+bool wxMsgCatalog::Load(const char *szDirPrefix, const char *szName)
+{
+  // search order (assume language 'foo') is
+  // 1) $LC_PATH/foo/LC_MESSAGES          (if LC_PATH set)
+  // 2) ./foo/LC_MESSAGES
+  // 3) ./foo
+  // 4) . (Added by JACS)
+  //
+  // under UNIX we search also in:
+  // 5) /usr/share/locale/foo/LC_MESSAGES (Linux)
+  // 6) /usr/lib/locale/foo/LC_MESSAGES   (Solaris)
+  #define MSG_PATH FILE_SEP_PATH + "LC_MESSAGES" PATH_SEP
+          
+  wxString strPath("");
+  const char *pszLcPath = getenv("LC_PATH");
+  if ( pszLcPath != NULL )
+      strPath += pszLcPath + wxString(szDirPrefix) + MSG_PATH;        // (1)
+  
+  // NB: '<<' is unneeded between too literal strings: 
+  //     they are concatenated at compile time
+  strPath += "./" + wxString(szDirPrefix) + MSG_PATH                  // (2)
+          + "./" + szDirPrefix + FILE_SEP_PATH + PATH_SEP // (3)
+		  + "." + PATH_SEP
+  #ifdef  __UNIX__
+             "/usr/share/locale/" + szDirPrefix + MSG_PATH  // (5)
+             "/usr/lib/locale/"  + szDirPrefix + MSG_PATH  // (6)
+  #endif  //UNIX
+          ;
+  
+  wxString strFile = szName;
+  strFile += MSGCATALOG_EXTENSION;
+
+  // don't give translation errors here because the wxstd catalog might
+  // not yet be loaded (and it's normal)
+  //
+  // (we're using an object because we have several return paths)
+  NoTransErr noTransErr;
+
+  wxLogVerbose("looking for catalog '%s' in path '%s'.",
+             szName, strPath.c_str());
+
+  wxString strFullName;
+  if ( !wxFindFileInPath(&strFullName, strPath, strFile) ) {
+    wxLogWarning("catalog file for domain '%s' not found.", szName);
+    return FALSE;
+  }
+
+  // open file
+  wxLogVerbose("using catalog '%s' from '%s'.",
+             szName, strFullName.c_str());
+  
+  wxFile fileMsg(strFullName);
+  if ( !fileMsg.IsOpened() )
+    return FALSE;
+
+  // get the file size
+  off_t nSize = fileMsg.Length();
+  if ( nSize == ofsInvalid )
+    return FALSE;
+
+  // read the whole file in memory
+  m_pData = new uint8[nSize];
+  if ( fileMsg.Read(m_pData, nSize) != nSize ) {
+    DELETEA(m_pData);
+    m_pData = NULL;
+    return FALSE;
+  }
+    
+  // examine header
+  bool bValid = (size_t)nSize > sizeof(wxMsgCatalogHeader);
+  
+  wxMsgCatalogHeader *pHeader;
+  if ( bValid ) {
+    pHeader = (wxMsgCatalogHeader *)m_pData;
+
+    // we'll have to swap all the integers if it's true
+    m_bSwapped = pHeader->magic == MSGCATALOG_MAGIC_SW;
+
+    // check the magic number
+    bValid = m_bSwapped || pHeader->magic == MSGCATALOG_MAGIC;
+  }
+  
+  if ( !bValid ) {
+    // it's either too short or has incorrect magic number
+    wxLogWarning("'%s' is not a valid message catalog.", strFullName.c_str());
+    
+    DELETEA(m_pData);
+    m_pData = NULL;
+    return FALSE;
+  }
+      
+  // initialize
+  m_numStrings  = Swap(pHeader->numStrings);
+  m_pOrigTable  = (wxMsgTableEntry *)(m_pData + 
+                   Swap(pHeader->ofsOrigTable));
+  m_pTransTable = (wxMsgTableEntry *)(m_pData + 
+                   Swap(pHeader->ofsTransTable));
+
+  m_nHashSize   = Swap(pHeader->nHashSize);
+  m_pHashTable  = (uint32 *)(m_pData + Swap(pHeader->ofsHashTable));
+
+  m_pszName = new char[strlen(szName) + 1];
+  strcpy(m_pszName, szName);
+
+  // everything is fine
+  return TRUE;
+}
+
+// search for a string
+const char *wxMsgCatalog::GetString(const char *szOrig) const
+{
+  if ( szOrig == NULL )
+    return NULL;
+
+  if ( HasHashTable() ) {   // use hash table for lookup if possible
+    uint32 nHashVal = GetHash(szOrig); 
+    uint32 nIndex   = nHashVal % m_nHashSize;
+
+    uint32 nIncr = 1 + (nHashVal % (m_nHashSize - 2));
+    
+    while ( TRUE ) {
+      uint32 nStr = Swap(m_pHashTable[nIndex]);
+      if ( nStr == 0 )
+        return NULL;
+      
+      if ( strcmp(szOrig, StringAtOfs(m_pOrigTable, nStr - 1)) == 0 )
+        return StringAtOfs(m_pTransTable, nStr - 1);
+
+      if ( nIndex >= m_nHashSize - nIncr)
+        nIndex -= m_nHashSize - nIncr;
+      else
+        nIndex += nIncr;
+    }
+  }
+  else {                    // no hash table: use default binary search
+    uint32 bottom = 0,
+           top    = m_numStrings,
+           current;
+    while ( bottom < top ) {
+      current = (bottom + top) / 2;
+      int res = strcmp(szOrig, StringAtOfs(m_pOrigTable, current));
+      if ( res < 0 )
+        top = current;
+      else if ( res > 0 )
+        bottom = current + 1;
+      else    // found!
+        return StringAtOfs(m_pTransTable, current);
+    }
+  }
+
+  // not found
+  return NULL;
+}
+
+// ----------------------------------------------------------------------------
+// wxLocale
+// ----------------------------------------------------------------------------
+
+// NB: ctor has (desired) side effect of changing current locale
+wxLocale::wxLocale(const char *szName, 
+                   const char *szShort, 
+                   const char *szLocale,
+                   bool        bLoadDefault)
+        : m_strLocale(szName), m_strShort(szShort)
+{
+  // change current locale (default: same as long name)
+  if ( szLocale == NULL )
+    szLocale = szName;
+  m_pszOldLocale = setlocale(LC_ALL, szLocale);
+  if ( m_pszOldLocale == NULL )
+    wxLogError("locale '%s' can not be set.", szLocale);
+
+  // the short name will be used to look for catalog files as well,
+  // so we need something here
+  if ( m_strShort.IsEmpty() ) {
+    // #### I don't know how these 2 letter abbreviations are formed,
+    //      this wild guess is almost surely wrong
+    m_strShort = wxToLower(szLocale[0]) + wxToLower(szLocale[1]);
+  }
+  
+  // save the old locale to be able to restore it later
+	m_pOldLocale = wxSetLocale(this);
+  
+  // load the default catalog with wxWindows standard messages
+  m_pMsgCat = NULL;
+  if ( bLoadDefault )
+    AddCatalog("wxstd");
+}
+
+// clean up
+wxLocale::~wxLocale()
+{
+  // free memory
+  wxMsgCatalog *pTmpCat;
+  while ( m_pMsgCat != NULL ) {
+    pTmpCat = m_pMsgCat;
+    m_pMsgCat = m_pMsgCat->m_pNext;
+    delete pTmpCat;
+  }
+  
+  // restore old locale
+	wxSetLocale(m_pOldLocale);
+  setlocale(LC_ALL, m_pszOldLocale);
+}
+
+// get the translation of given string in current locale
+const char *wxLocale::GetString(const char *szOrigString, 
+                                const char *szDomain) const
+{
+  wxASSERT( szOrigString != NULL ); // would be pretty silly
+
+  const char *pszTrans = NULL;
+
+  wxMsgCatalog *pMsgCat;
+  if ( szDomain != NULL ) {
+    pMsgCat = FindCatalog(szDomain);
+    
+    // does the catalog exist?
+    if ( pMsgCat != NULL )
+      pszTrans = pMsgCat->GetString(szOrigString);
+  }
+  else {
+    // search in all domains
+    for ( pMsgCat = m_pMsgCat; pMsgCat != NULL; pMsgCat = pMsgCat->m_pNext ) {
+      pszTrans = pMsgCat->GetString(szOrigString);
+      if ( pszTrans != NULL )   // take the first found
+        break;
+    }
+  }
+
+  if ( pszTrans == NULL ) {
+    if ( wxIsLoggingTransErrors() ) {
+      // suppress further error messages
+      // (do it before LogWarning to prevent infinite recursion!)
+      wxSuppressTransErrors();
+      
+      if ( szDomain != NULL )
+        wxLogWarning("string '%s' not found in domain '%s' for locale '%s'.",
+                    szOrigString, szDomain, m_strLocale.c_str());
+      else
+        wxLogWarning("string '%s' not found in locale '%s'.",
+                   szOrigString, m_strLocale.c_str());
+    }
+
+    return szOrigString;
+  }
+  else
+    return pszTrans;
+}
+
+// find catalog by name in a linked list, return NULL if !found
+wxMsgCatalog *wxLocale::FindCatalog(const char *szDomain) const
+{
+// linear search in the linked list
+  wxMsgCatalog *pMsgCat;
+  for ( pMsgCat = m_pMsgCat; pMsgCat != NULL; pMsgCat = pMsgCat->m_pNext ) {
+    if ( Stricmp(pMsgCat->GetName(), szDomain) == 0 )
+      return pMsgCat;
+  }
+  
+  return NULL;
+}
+
+// check if the given catalog is loaded
+bool wxLocale::IsLoaded(const char *szDomain) const
+{
+  return FindCatalog(szDomain) != NULL;
+}
+
+// add a catalog to our linked list
+bool wxLocale::AddCatalog(const char *szDomain)
+{
+  wxMsgCatalog *pMsgCat = new wxMsgCatalog;
+  
+  if ( pMsgCat->Load(m_strShort, szDomain) ) {
+    // add it to the head of the list so that in GetString it will
+    // be searched before the catalogs added earlier
+    pMsgCat->m_pNext = m_pMsgCat;
+    m_pMsgCat = pMsgCat;
+    
+    return TRUE;
+  }
+  else {
+    // don't add it because it couldn't be loaded anyway
+    delete pMsgCat;
+    
+    return FALSE;
+  }
+}
+
+// ----------------------------------------------------------------------------
+// global functions and variables
+// ----------------------------------------------------------------------------
+
+// translation errors logging
+// --------------------------
+
+static bool gs_bGiveTransErrors = TRUE;
+
+void wxSuppressTransErrors()
+{
+  gs_bGiveTransErrors = FALSE;
+}
+
+void wxRestoreTransErrors()
+{
+  gs_bGiveTransErrors = TRUE;
+}
+
+bool wxIsLoggingTransErrors()
+{
+  return gs_bGiveTransErrors;
+}
+
+// retrieve/change current locale
+// ------------------------------
+
+// the current locale object
+wxLocale *g_pLocale = NULL;
+
+wxLocale *wxGetLocale()
+{
+	return g_pLocale;
+}
+
+wxLocale *wxSetLocale(wxLocale *pLocale)
+{
+	wxLocale *pOld = g_pLocale;
+	g_pLocale = pLocale;
+	return pOld;
+}
diff --git a/src/common/ipcbase.cpp b/src/common/ipcbase.cpp
new file mode 100644
index 0000000000..717eb20c60
--- /dev/null
+++ b/src/common/ipcbase.cpp
@@ -0,0 +1,35 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        ipcbase.cpp
+// Purpose:     IPC base classes
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "ipcbase.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/defs.h"
+#endif
+
+#include "wx/ipcbase.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_CLASS(wxServerBase, wxObject)
+IMPLEMENT_CLASS(wxClientBase, wxObject)
+IMPLEMENT_CLASS(wxConnectionBase, wxObject)
+#endif
+
+
diff --git a/src/common/layout.cpp b/src/common/layout.cpp
new file mode 100644
index 0000000000..abb7f9bb7b
--- /dev/null
+++ b/src/common/layout.cpp
@@ -0,0 +1,1747 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        layout.cpp
+// Purpose:     Constraint layout system classes
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "layout.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#include "wx/defs.h"
+
+#if USE_CONSTRAINTS
+
+#ifndef WX_PRECOMP
+#include "wx/window.h"
+#include "wx/utils.h"
+#include "wx/dialog.h"
+#include "wx/msgdlg.h"
+#endif
+
+#include "wx/layout.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxIndividualLayoutConstraint, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxLayoutConstraints, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxSizer, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxRowColSizer, wxSizer)
+IMPLEMENT_DYNAMIC_CLASS(wxSpacingSizer, wxSizer)
+#endif
+
+/*
+TODO:
+ - Non shrink-to-fit row-col behaviour.
+ - Give justification styles, so can e.g. centre
+ the rows & cols, distribute the available space...
+ - Shrink-to-fit: should resize outer window (e.g. dialog box)
+ if directly associated with this kind of window.
+ - How to deal with a rowcol that stretches in one direction
+ but shrinks-to-fit in other. E.g. a horizontal toolbar: the width
+ stretches to fit the frame, but the height is constant
+ or wraps around contents. The algorithm currently assumes
+ both dimensions have the same behaviour. Could assume a constant
+ height (absolute value).
+ - rowcol where each row or column is aligned (length of
+   largest element determines spacing)
+ - Groupbox sizer
+ - Analyze aesthetic dialog boxes and implement using sizers.
+ - What reuseable components can we provide? E.g. Ok/Cancel/Help
+   group of buttons.
+ - use wxStaticItems for aesthetic dialogs.
+
+*/
+
+// Find margin sizes if a sizer, or zero otherwise
+int wxSizerMarginX(wxWindow *win)
+{
+	if ( win->IsKindOf(CLASSINFO(wxSizer)) )
+	{
+		wxSizer *sizer = (wxSizer *)win;
+		return sizer->GetBorderX();
+	}
+	else
+		return 0;
+}
+
+int wxSizerMarginY(wxWindow *win)
+{
+	if ( win->IsKindOf(CLASSINFO(wxSizer)) )
+	{
+		wxSizer *sizer = (wxSizer *)win;
+		return sizer->GetBorderY();
+	}
+	else
+		return 0;
+}
+
+
+wxIndividualLayoutConstraint::wxIndividualLayoutConstraint(void)
+{
+  myEdge = wxTop; relationship = wxUnconstrained; margin = 0; value = 0; percent = 0; otherEdge = wxTop;
+  done = FALSE; otherWin = NULL;
+}
+
+wxIndividualLayoutConstraint::~wxIndividualLayoutConstraint(void)
+{
+}
+
+void wxIndividualLayoutConstraint::Set(wxRelationship rel, wxWindow *otherW, wxEdge otherE, int val, int marg)
+{
+  relationship = rel; otherWin = otherW; otherEdge = otherE; value = val; margin = marg;
+}
+
+void wxIndividualLayoutConstraint::LeftOf(wxWindow *sibling, int marg)
+{ Set(wxLeftOf, sibling, wxLeft, 0, marg); }
+
+void wxIndividualLayoutConstraint::RightOf(wxWindow *sibling, int marg)
+{ Set(wxRightOf, sibling, wxRight, 0, marg); }
+
+void wxIndividualLayoutConstraint::Above(wxWindow *sibling, int marg)
+{ Set(wxAbove, sibling, wxTop, 0, marg); }
+
+void wxIndividualLayoutConstraint::Below(wxWindow *sibling, int marg)
+{ Set(wxBelow, sibling, wxBottom, 0, marg); }
+
+//
+// 'Same edge' alignment
+//
+void wxIndividualLayoutConstraint::SameAs(wxWindow *otherW, wxEdge edge, int marg)
+{ Set(wxPercentOf, otherW, edge, 0, marg); percent = 100; }
+
+// The edge is a percentage of the other window's edge
+void wxIndividualLayoutConstraint::PercentOf(wxWindow *otherW, wxEdge wh, int per)
+{ otherWin = otherW; relationship = wxPercentOf; percent = per;
+  otherEdge = wh;
+}
+
+//
+// Edge has absolute value
+//
+void wxIndividualLayoutConstraint::Absolute(int val)
+{ value = val; relationship = wxAbsolute; }
+
+// Reset constraint if it mentions otherWin
+bool wxIndividualLayoutConstraint::ResetIfWin(wxWindow *otherW)
+{
+  if (otherW == otherWin)
+  {
+    myEdge = wxTop; relationship = wxAsIs; margin = 0; value = 0; percent = 0; otherEdge = wxTop;
+    otherWin = NULL;
+    return TRUE;
+  }
+  else
+    return FALSE;
+}
+
+// Try to satisfy constraint
+bool wxIndividualLayoutConstraint::SatisfyConstraint(wxLayoutConstraints *constraints, wxWindow *win)
+{
+  if (relationship == wxAbsolute)
+  {
+    done = TRUE;
+    return TRUE;
+  }
+  
+  switch (myEdge)
+  {
+    case wxLeft:
+    {
+      switch (relationship)
+      {
+        case wxLeftOf:
+        {
+          // We can know this edge if: otherWin is win's parent,
+          // or otherWin has a satisfied constraint, or
+          // otherWin has no constraint.
+          int edgePos = GetEdge(otherEdge, win, otherWin);
+          if (edgePos != -1)
+          {
+            value = edgePos - margin;
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        case wxRightOf:
+        {
+          int edgePos = GetEdge(otherEdge, win, otherWin);
+          if (edgePos != -1)
+          {
+            value = edgePos + margin;
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        case wxPercentOf:
+        {
+          int edgePos = GetEdge(otherEdge, win, otherWin);
+          if (edgePos != -1)
+          {
+            value = (int)(edgePos*(((float)percent)*0.01) + margin);
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        case wxUnconstrained:
+        {
+          // We know the left-hand edge position if we know
+          // the right-hand edge and we know the width; OR if we know the centre and the width.
+          if (constraints->right.GetDone() && constraints->width.GetDone())
+          {
+            value = (constraints->right.GetValue() - constraints->width.GetValue() + margin);
+            done = TRUE;
+            return TRUE;
+          }
+          else if (constraints->centreX.GetDone() && constraints->width.GetDone())
+          {
+            value = (int)(constraints->centreX.GetValue() - (constraints->width.GetValue()/2) + margin);
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        case wxAsIs:
+        {
+          int y;
+          win->GetPosition(&value, &y);
+          done = TRUE;
+          return TRUE;
+        }
+        default:
+          break;
+      }
+      break;
+    }
+    case wxRight:
+    {
+      switch (relationship)
+      {
+        case wxLeftOf:
+        {
+          // We can know this edge if: otherWin is win's parent,
+          // or otherWin has a satisfied constraint, or
+          // otherWin has no constraint.
+          int edgePos = GetEdge(otherEdge, win, otherWin);
+          if (edgePos != -1)
+          {
+            value = edgePos - margin;
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        case wxRightOf:
+        {
+          int edgePos = GetEdge(otherEdge, win, otherWin);
+          if (edgePos != -1)
+          {
+            value = edgePos + margin;
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        case wxPercentOf:
+        {
+          int edgePos = GetEdge(otherEdge, win, otherWin);
+          if (edgePos != -1)
+          {
+            value = (int)(edgePos*(((float)percent)*0.01) - margin);
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        case wxUnconstrained:
+        {
+          // We know the right-hand edge position if we know
+          // the left-hand edge and we know the width, OR if we know the
+          // centre edge and the width.
+          if (constraints->left.GetDone() && constraints->width.GetDone())
+          {
+            value = (constraints->left.GetValue() + constraints->width.GetValue() - margin);
+            done = TRUE;
+            return TRUE;
+          }
+          else if (constraints->centreX.GetDone() && constraints->width.GetDone())
+          {
+            value = (int)(constraints->centreX.GetValue() + (constraints->width.GetValue()/2) - margin);
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        case wxAsIs:
+        {
+          int x, y;
+          int w, h;
+          win->GetSize(&w, &h);
+          win->GetPosition(&x, &y);
+          value = x + w;
+          done = TRUE;
+          return TRUE;
+        }
+        default:
+          break;
+      }
+      break;
+    }
+    case wxTop:
+    {
+      switch (relationship)
+      {
+        case wxAbove:
+        {
+          // We can know this edge if: otherWin is win's parent,
+          // or otherWin has a satisfied constraint, or
+          // otherWin has no constraint.
+          int edgePos = GetEdge(otherEdge, win, otherWin);
+          if (edgePos != -1)
+          {
+            value = edgePos - margin;
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        case wxBelow:
+        {
+          int edgePos = GetEdge(otherEdge, win, otherWin);
+          if (edgePos != -1)
+          {
+            value = edgePos + margin;
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        case wxPercentOf:
+        {
+          int edgePos = GetEdge(otherEdge, win, otherWin);
+          if (edgePos != -1)
+          {
+            value = (int)(edgePos*(((float)percent)*0.01) + margin);
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        case wxUnconstrained:
+        {
+          // We know the top edge position if we know
+          // the bottom edge and we know the height; OR if we know the centre
+          // edge and the height.
+          if (constraints->bottom.GetDone() && constraints->height.GetDone())
+          {
+            value = (constraints->bottom.GetValue() - constraints->height.GetValue() + margin);
+            done = TRUE;
+            return TRUE;
+          }
+          else if (constraints->centreY.GetDone() && constraints->height.GetDone())
+          {
+            value = (constraints->centreY.GetValue() - (constraints->height.GetValue()/2) + margin);
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        case wxAsIs:
+        {
+          int x;
+          win->GetPosition(&x, &value);
+          done = TRUE;
+          return TRUE;
+        }
+        default:
+          break;
+      }
+      break;
+    }
+    case wxBottom:
+    {
+      switch (relationship)
+      {
+        case wxAbove:
+        {
+          // We can know this edge if: otherWin is win's parent,
+          // or otherWin has a satisfied constraint, or
+          // otherWin has no constraint.
+          int edgePos = GetEdge(otherEdge, win, otherWin);
+          if (edgePos != -1)
+          {
+            value = edgePos + margin;
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        case wxBelow:
+        {
+          int edgePos = GetEdge(otherEdge, win, otherWin);
+          if (edgePos != -1)
+          {
+            value = edgePos - margin;
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        case wxPercentOf:
+        {
+          int edgePos = GetEdge(otherEdge, win, otherWin);
+          if (edgePos != -1)
+          {
+            value = (int)(edgePos*(((float)percent)*0.01) - margin);
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        case wxUnconstrained:
+        {
+          // We know the bottom edge position if we know
+          // the top edge and we know the height; OR if we know the
+          // centre edge and the height.
+          if (constraints->top.GetDone() && constraints->height.GetDone())
+          {
+            value = (constraints->top.GetValue() + constraints->height.GetValue() - margin);
+            done = TRUE;
+            return TRUE;
+          }
+          else if (constraints->centreY.GetDone() && constraints->height.GetDone())
+          {
+            value = (constraints->centreY.GetValue() + (constraints->height.GetValue()/2) - margin);
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        case wxAsIs:
+        {
+          int x, y;
+          int w, h;
+          win->GetSize(&w, &h);
+          win->GetPosition(&x, &y);
+          value = h + y;
+          done = TRUE;
+          return TRUE;
+        }
+        default:
+          break;
+      }
+      break;
+    }
+    case wxCentreX:
+    {
+      switch (relationship)
+      {
+        case wxLeftOf:
+        {
+          // We can know this edge if: otherWin is win's parent,
+          // or otherWin has a satisfied constraint, or
+          // otherWin has no constraint.
+          int edgePos = GetEdge(otherEdge, win, otherWin);
+          if (edgePos != -1)
+          {
+            value = edgePos - margin;
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        case wxRightOf:
+        {
+          int edgePos = GetEdge(otherEdge, win, otherWin);
+          if (edgePos != -1)
+          {
+            value = edgePos + margin;
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        case wxPercentOf:
+        {
+          int edgePos = GetEdge(otherEdge, win, otherWin);
+          if (edgePos != -1)
+          {
+            value = (int)(edgePos*(((float)percent)*0.01) + margin);
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        case wxUnconstrained:
+        {
+          // We know the centre position if we know
+          // the left-hand edge and we know the width, OR
+          // the right-hand edge and the width
+          if (constraints->left.GetDone() && constraints->width.GetDone())
+          {
+            value = (int)(constraints->left.GetValue() + (constraints->width.GetValue()/2) + margin);
+            done = TRUE;
+            return TRUE;
+          }
+          else if (constraints->right.GetDone() && constraints->width.GetDone())
+          {
+            value = (int)(constraints->left.GetValue() - (constraints->width.GetValue()/2) + margin);
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        default:
+          break;
+      }
+      break;
+    }
+    case wxCentreY:
+    {
+      switch (relationship)
+      {
+        case wxAbove:
+        {
+          // We can know this edge if: otherWin is win's parent,
+          // or otherWin has a satisfied constraint, or
+          // otherWin has no constraint.
+          int edgePos = GetEdge(otherEdge, win, otherWin);
+          if (edgePos != -1)
+          {
+            value = edgePos - margin;
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        case wxBelow:
+        {
+          int edgePos = GetEdge(otherEdge, win, otherWin);
+          if (edgePos != -1)
+          {
+            value = edgePos + margin;
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        case wxPercentOf:
+        {
+          int edgePos = GetEdge(otherEdge, win, otherWin);
+          if (edgePos != -1)
+          {
+            value = (int)(edgePos*(((float)percent)*0.01) + margin);
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        case wxUnconstrained:
+        {
+          // We know the centre position if we know
+          // the top edge and we know the height, OR
+          // the bottom edge and the height.
+          if (constraints->bottom.GetDone() && constraints->height.GetDone())
+          {
+            value = (int)(constraints->bottom.GetValue() - (constraints->height.GetValue()/2) + margin);
+            done = TRUE;
+            return TRUE;
+          }
+          else if (constraints->top.GetDone() && constraints->height.GetDone())
+          {
+            value = (int)(constraints->top.GetValue() + (constraints->height.GetValue()/2) + margin);
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        default:
+          break;
+      }
+      break;
+    }
+    case wxWidth:
+    {
+      switch (relationship)
+      {
+        case wxPercentOf:
+        {
+          int edgePos = GetEdge(otherEdge, win, otherWin);
+          if (edgePos != -1)
+          {
+            value = (int)(edgePos*(((float)percent)*0.01));
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        case wxAsIs:
+        {
+          if (win)
+          {
+            int h;
+            win->GetSize(&value, &h);
+            done = TRUE;
+            return TRUE;
+          }
+          else return FALSE;
+        }
+        case wxUnconstrained:
+        {
+          // We know the width if we know the left edge and the right edge, OR
+          // if we know the left edge and the centre, OR
+          // if we know the right edge and the centre
+          if (constraints->left.GetDone() && constraints->right.GetDone())
+          {
+            value = constraints->right.GetValue() - constraints->left.GetValue();
+            done = TRUE;
+            return TRUE;
+          }
+          else if (constraints->centreX.GetDone() && constraints->left.GetDone())
+          {
+            value = (int)(2*(constraints->centreX.GetValue() - constraints->left.GetValue()));
+            done = TRUE;
+            return TRUE;
+          }
+          else if (constraints->centreX.GetDone() && constraints->right.GetDone())
+          {
+            value = (int)(2*(constraints->right.GetValue() - constraints->centreX.GetValue()));
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        default:
+          break;
+      }
+      break;
+    }
+    case wxHeight:
+    {
+      switch (relationship)
+      {
+        case wxPercentOf:
+        {
+          int edgePos = GetEdge(otherEdge, win, otherWin);
+          if (edgePos != -1)
+          {
+            value = (int)(edgePos*(((float)percent)*0.01));
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        case wxAsIs:
+        {
+          if (win)
+          {
+            int w;
+            win->GetSize(&w, &value);
+            done = TRUE;
+            return TRUE;
+          }
+          else return FALSE;
+        }
+        case wxUnconstrained:
+        {
+          // We know the height if we know the top edge and the bottom edge, OR
+          // if we know the top edge and the centre, OR
+          // if we know the bottom edge and the centre
+          if (constraints->top.GetDone() && constraints->bottom.GetDone())
+          {
+            value = constraints->bottom.GetValue() - constraints->top.GetValue();
+            done = TRUE;
+            return TRUE;
+          }
+          else if (constraints->top.GetDone() && constraints->centreY.GetDone())
+          {
+            value = (int)(2*(constraints->centreY.GetValue() - constraints->top.GetValue()));
+            done = TRUE;
+            return TRUE;
+          }
+          else if (constraints->bottom.GetDone() && constraints->centreY.GetDone())
+          {
+            value = (int)(2*(constraints->bottom.GetValue() - constraints->centreY.GetValue()));
+            done = TRUE;
+            return TRUE;
+          }
+          else
+            return FALSE;
+        }
+        default:
+          break;
+      }
+      break;
+    }
+    default:
+      break;
+  }
+  return FALSE;
+}
+
+// Get the value of this edge or dimension, or if this
+// is not determinable, -1.
+int wxIndividualLayoutConstraint::GetEdge(wxEdge which, wxWindow *thisWin, wxWindow *other)
+{
+  // If the edge or dimension belongs to the parent, then we
+  // know the dimension is obtainable immediately.
+  // E.g. a wxExpandSizer may contain a button (but the button's
+  // true parent is a panel, not the sizer)
+  if (other->GetChildren()->Member(thisWin))
+  {
+    switch (which)
+    {
+      case wxLeft:
+	  {
+		return wxSizerMarginX(other);
+	  }
+      case wxTop:
+      {
+        return wxSizerMarginY(other);
+      }
+      case wxRight:
+	  {
+        int w, h;
+        other->GetClientSizeConstraint(&w, &h);
+        return w - wxSizerMarginX(other);
+	  }
+      case wxBottom:
+	  {
+        int w, h;
+        other->GetClientSizeConstraint(&w, &h);
+        return h - wxSizerMarginY(other);
+	  }
+      case wxWidth:
+	  {
+        int w, h;
+        other->GetClientSizeConstraint(&w, &h);
+        return w - 2*wxSizerMarginX(other);
+	  }
+      case wxHeight:
+      {
+        int w, h;
+        other->GetClientSizeConstraint(&w, &h);
+        return h - 2*wxSizerMarginY(other);
+      }
+      case wxCentreX:
+      case wxCentreY:
+      {
+        int w, h;
+        other->GetClientSizeConstraint(&w, &h);
+        if (which == wxCentreX)
+          return (int)(w/2);
+        else
+          return (int)(h/2);
+      }
+      default:
+        return -1;
+    }
+  }
+  switch (which)
+  {
+    case wxLeft:
+    {
+      wxLayoutConstraints *constr = other->GetConstraints();
+      // If no constraints, it means the window is not dependent
+      // on anything, and therefore we know its value immediately
+      if (constr)
+      {
+        if (constr->left.GetDone())
+          return constr->left.GetValue();
+        else
+          return -1;
+      }
+      else
+      {
+        int x, y;
+        other->GetPosition(&x, &y);
+        return x;
+      }
+    }
+    case wxTop:
+    {
+      wxLayoutConstraints *constr = other->GetConstraints();
+      // If no constraints, it means the window is not dependent
+      // on anything, and therefore we know its value immediately
+      if (constr)
+      {
+        if (constr->top.GetDone())
+          return constr->top.GetValue();
+        else
+          return -1;
+      }
+      else
+      {
+        int x, y;
+        other->GetPosition(&x, &y);
+        return y;
+      }
+    }
+    case wxRight:
+    {
+      wxLayoutConstraints *constr = other->GetConstraints();
+      // If no constraints, it means the window is not dependent
+      // on anything, and therefore we know its value immediately
+      if (constr)
+      {
+        if (constr->right.GetDone())
+          return constr->right.GetValue();
+        else
+          return -1;
+      }
+      else
+      {
+        int x, y, w, h;
+        other->GetPosition(&x, &y);
+        other->GetSize(&w, &h);
+        return (int)(x + w);
+      }
+    }
+    case wxBottom:
+    {
+      wxLayoutConstraints *constr = other->GetConstraints();
+      // If no constraints, it means the window is not dependent
+      // on anything, and therefore we know its value immediately
+      if (constr)
+      {
+        if (constr->bottom.GetDone())
+          return constr->bottom.GetValue();
+        else
+          return -1;
+      }
+      else
+      {
+        int x, y, w, h;
+        other->GetPosition(&x, &y);
+        other->GetSize(&w, &h);
+        return (int)(y + h);
+      }
+    }
+    case wxWidth:
+    {
+      wxLayoutConstraints *constr = other->GetConstraints();
+      // If no constraints, it means the window is not dependent
+      // on anything, and therefore we know its value immediately
+      if (constr)
+      {
+        if (constr->width.GetDone())
+          return constr->width.GetValue();
+        else
+          return -1;
+      }
+      else
+      {
+        int w, h;
+        other->GetSize(&w, &h);
+        return w;
+      }
+    }
+    case wxHeight:
+    {
+      wxLayoutConstraints *constr = other->GetConstraints();
+      // If no constraints, it means the window is not dependent
+      // on anything, and therefore we know its value immediately
+      if (constr)
+      {
+        if (constr->height.GetDone())
+          return constr->height.GetValue();
+        else
+          return -1;
+      }
+      else
+      {
+        int w, h;
+        other->GetSize(&w, &h);
+        return h;
+      }
+    }
+    case wxCentreX:
+    {
+      wxLayoutConstraints *constr = other->GetConstraints();
+      // If no constraints, it means the window is not dependent
+      // on anything, and therefore we know its value immediately
+      if (constr)
+      {
+        if (constr->centreX.GetDone())
+          return constr->centreX.GetValue();
+        else
+          return -1;
+      }
+      else
+      {
+        int x, y, w, h;
+        other->GetPosition(&x, &y);
+        other->GetSize(&w, &h);
+        return (int)(x + (w/2));
+      }
+    }
+    case wxCentreY:
+    {
+      wxLayoutConstraints *constr = other->GetConstraints();
+      // If no constraints, it means the window is not dependent
+      // on anything, and therefore we know its value immediately
+      if (constr)
+      {
+        if (constr->centreY.GetDone())
+          return constr->centreY.GetValue();
+        else
+          return -1;
+      }
+      else
+      {
+        int x, y, w, h;
+        other->GetPosition(&x, &y);
+        other->GetSize(&w, &h);
+        return (int)(y + (h/2));
+      }
+    }
+    default:
+      break;
+  }
+  return -1;
+}
+
+wxLayoutConstraints::wxLayoutConstraints(void)
+{
+  left.SetEdge(wxLeft);
+  top.SetEdge(wxTop);
+  right.SetEdge(wxRight);
+  bottom.SetEdge(wxBottom);
+  centreX.SetEdge(wxCentreX);
+  centreY.SetEdge(wxCentreY);
+  width.SetEdge(wxWidth);
+  height.SetEdge(wxHeight);
+}
+
+wxLayoutConstraints::~wxLayoutConstraints(void)
+{
+}
+
+bool wxLayoutConstraints::SatisfyConstraints(wxWindow *win, int *nChanges)
+{
+  int noChanges = 0;
+  
+  bool done = width.GetDone();
+  bool newDone = (done ? TRUE : width.SatisfyConstraint(this, win));
+  if (newDone != done)
+    noChanges ++;
+
+  done = height.GetDone();
+  newDone = (done ? TRUE : height.SatisfyConstraint(this, win));
+  if (newDone != done)
+    noChanges ++;
+
+  done = left.GetDone();
+  newDone = (done ? TRUE : left.SatisfyConstraint(this, win));
+  if (newDone != done)
+    noChanges ++;
+
+  done = top.GetDone();
+  newDone = (done ? TRUE : top.SatisfyConstraint(this, win));
+  if (newDone != done)
+    noChanges ++;
+
+  done = right.GetDone();
+  newDone = (done ? TRUE : right.SatisfyConstraint(this, win));
+  if (newDone != done)
+    noChanges ++;
+          
+  done = bottom.GetDone();
+  newDone = (done ? TRUE : bottom.SatisfyConstraint(this, win));
+  if (newDone != done)
+    noChanges ++;
+
+  done = centreX.GetDone();
+  newDone = (done ? TRUE : centreX.SatisfyConstraint(this, win));
+  if (newDone != done)
+    noChanges ++;
+
+  done = centreY.GetDone();
+  newDone = (done ? TRUE : centreY.SatisfyConstraint(this, win));
+  if (newDone != done)
+    noChanges ++;
+
+  *nChanges = noChanges;
+
+  return (left.GetDone() && top.GetDone() && right.GetDone() && bottom.GetDone() &&
+    centreX.GetDone() && centreY.GetDone());
+}
+
+/*
+ * Main constrained layout algorithm. Look at all the child
+ * windows, and their constraints (if any).
+ * The idea is to keep iterating through the constraints
+ * until all left, right, bottom and top edges, and widths and heights,
+ * are known (or no change occurs and we've failed to resolve all
+ * constraints).
+ *
+ * If the user has not specified a dimension or edge, it will be
+ * be calculated from the other known values. E.g. If we know
+ * the right hand edge and the left hand edge, we now know the width.
+ * The snag here is that this means we must specify absolute dimensions
+ * twice (in constructor and in constraint), if we wish to use the
+ * constraint notation to just set the position, for example.
+ * Otherwise, if we only set ONE edge and no dimension, it would never
+ * find the other edge.
+ *
+ * Algorithm:
+
+  Mark all constraints as not done.
+
+  iterations = 0;
+  until no change or iterations >= max iterations
+    For each child:
+    {
+      Calculate all constraints
+    }
+    iterations ++;
+
+  For each child
+    Set each calculated position and size
+
+ */
+ 
+bool wxOldDoLayout(wxWindow *win)
+{
+  // Make sure this isn't called recursively from below
+  static wxList doneSoFar;
+
+  if (doneSoFar.Member(win))
+    return TRUE;
+
+  doneSoFar.Append(win);
+
+  wxNode *node = win->GetChildren()->First();
+  while (node)
+  {
+    wxWindow *child = (wxWindow *)node->Data();
+    wxLayoutConstraints *constr = child->GetConstraints();
+    if (constr)
+    {
+      constr->left.SetDone(FALSE);
+      constr->top.SetDone(FALSE);
+      constr->right.SetDone(FALSE);
+      constr->bottom.SetDone(FALSE);
+      constr->width.SetDone(FALSE);
+      constr->height.SetDone(FALSE);
+      constr->centreX.SetDone(FALSE);
+      constr->centreY.SetDone(FALSE);
+    }
+    node = node->Next();
+  }
+  int noIterations = 0;
+  int maxIterations = 500;
+  int noChanges = 1;
+
+  while ((noChanges > 0) && (noIterations < maxIterations))
+  {
+    noChanges = 0;
+    wxNode *node = win->GetChildren()->First();
+    while (node)
+    {
+      wxWindow *child = (wxWindow *)node->Data();
+      wxLayoutConstraints *constr = child->GetConstraints();
+      if (constr)
+      {
+        int tempNoChanges = 0;
+        (void) constr->SatisfyConstraints(child, &tempNoChanges);
+        noChanges += tempNoChanges;
+      }
+      node = node->Next();
+    }
+    noIterations ++;
+  }
+/*
+  // Would be nice to have a test here to see _which_ constraint(s)
+  // failed, so we can print a specific diagnostic message.
+  if (noFailures > 0)
+  {
+    wxDebugMsg("wxWindow::Layout() failed.\n");
+  }
+*/
+  // Now set the sizes and positions of the children, and
+  // recursively call Layout().
+  node = win->GetChildren()->First();
+  while (node)
+  {
+    wxWindow *child = (wxWindow *)node->Data();
+    wxLayoutConstraints *constr = child->GetConstraints();
+    if (constr && constr->left.GetDone() && constr->right.GetDone() &&
+                  constr->width.GetDone() && constr->height.GetDone())
+    {
+      int x = constr->left.GetValue();
+      int y = constr->top.GetValue();
+      int w = constr->width.GetValue();
+      int h = constr->height.GetValue();
+
+      // If we don't want to resize this window, just move it...
+      if ((constr->width.GetRelationship() != wxAsIs) ||
+          (constr->height.GetRelationship() != wxAsIs))
+      {
+        // _Should_ call Layout() recursively.
+        child->SetSize(x, y, w, h);
+      }
+      else
+      {
+        child->Move(x, y);
+      }
+    }
+    else
+      child->Layout();
+    node = node->Next();
+  }
+  doneSoFar.DeleteObject(win);
+
+  return TRUE;
+}
+
+wxSizer::wxSizer(void)
+{
+  sizerBehaviour = wxSizerNone;
+  borderX = 2;
+  borderY = 2;
+  sizerX = 0;
+  sizerY = 0;
+  sizerWidth = 0;
+  sizerHeight = 0;
+}
+
+wxSizer::wxSizer(wxWindow *parent, wxSizerBehaviour behav)
+{
+  Create(parent, behav);
+}
+
+bool wxSizer::Create(wxWindow *parent, wxSizerBehaviour behav)
+{
+  sizerBehaviour = behav;
+  borderX = 2;
+  borderY = 2;
+  m_sizerParent = parent;
+  sizerX = 0;
+  sizerY = 0;
+  sizerWidth = 0;
+  sizerHeight = 0;
+
+  // A normal window can have just one top-level sizer
+  // associated with it.
+  if (!parent->IsKindOf(CLASSINFO(wxSizer)))
+  {
+    parent->SetSizer(this);
+  }
+  else
+    ((wxSizer *)parent)->AddSizerChild(this);
+
+  switch (sizerBehaviour)
+  {
+    case wxSizerExpand:
+    {
+      // Defines a set of constraints
+      // to expand the sizer to fit the parent window
+      wxLayoutConstraints *c = new wxLayoutConstraints;
+
+      c->left.SameAs(parent, wxLeft, 0);
+      c->top.SameAs(parent, wxTop, 0);
+      c->right.SameAs(parent, wxRight, 0);
+      c->bottom.SameAs(parent, wxBottom, 0);
+
+      SetConstraints(c);
+      break;
+    }
+    case wxSizerShrink:
+    case wxSizerNone:
+    default:
+    {
+    }
+  }
+  return TRUE;
+}
+
+wxSizer::~wxSizer(void)
+{
+  // Remove all children without deleting them,
+  // or ~wxbWindow will delete proper windows _twice_
+  wxNode *node = GetChildren()->First();
+  while (node)
+  {
+    wxNode *next = node->Next();
+    wxWindow *win = (wxWindow *)node->Data();
+    if (!win->IsKindOf(CLASSINFO(wxSizer)))
+	{
+      	delete node;
+  		win->SetSizerParent(NULL);
+	}
+    else
+    {
+      RemoveSizerChild(win);
+      delete win;
+    }
+    node = next;
+  }
+
+  if (m_sizerParent) // && !m_sizerParent->IsKindOf(CLASSINFO(wxSizer)))
+  {
+    m_sizerParent->SetSizer(NULL);
+	m_sizerParent = NULL;
+  }
+
+}
+
+void wxSizer::SetBorder(int x, int y)
+{
+	borderX = x;
+	borderY = y;
+/* No: the margin is for inside, not outside (expansion)
+
+	if ( GetConstraints() )
+	{
+		GetConstraints()->left.SetMargin(x);
+		GetConstraints()->right.SetMargin(x);
+		GetConstraints()->top.SetMargin(y);
+		GetConstraints()->bottom.SetMargin(y);
+	}
+*/
+
+}
+
+void wxSizer::AddSizerChild(wxWindow *child)
+{
+  child->SetSizerParent(this);
+  GetChildren()->Append(child);
+
+  // Add some constraints for the purpose of storing
+  // the relative position of the window/sizer
+  // during layout calculations.
+  if (!child->GetConstraints())
+  {
+    wxLayoutConstraints *c = new wxLayoutConstraints;
+    c->left.AsIs();
+    c->top.AsIs();
+    c->width.AsIs();
+    c->height.AsIs();
+    int w, h;
+    child->GetSize(&w, &h);
+    c->width.SetValue(w);
+    c->height.SetValue(h);
+    
+    child->SetConstraints(c);
+  }
+}
+
+void wxSizer::RemoveSizerChild(wxWindow *child)
+{
+  GetChildren()->DeleteObject(child);
+}
+
+void wxSizer::SetSize(const int x, const int y, const int w, const int h, const int WXUNUSED(flags))
+{
+  wxLayoutConstraints *constr = GetConstraints();
+  if (x != -1)
+  {
+    sizerX = x;
+    if (constr)
+      constr->left.SetValue(x);
+  }
+  if (y != -1)
+  {
+    sizerY = y;
+    if (constr)
+      constr->top.SetValue(y);
+  }
+  if (w != -1)
+  {
+    sizerWidth = w;
+    if (constr)
+      constr->width.SetValue(w);
+  }
+  if (h != -1)
+  {
+    sizerHeight = h;
+    if (constr)
+      constr->height.SetValue(h);
+  }
+}
+
+void wxSizer::Move(const int x, const int y)
+{
+  wxLayoutConstraints *constr = GetConstraints();
+  if (x != -1)
+  {
+    sizerX = x;
+    if (constr)
+      constr->left.SetValue(x);
+  }
+  if (y != -1)
+  {
+    sizerY = y;
+    if (constr)
+      constr->top.SetValue(y);
+  }
+}
+
+void wxSizer::GetSize(int *w, int *h) const
+{
+  *w = sizerWidth;
+  *h = sizerHeight;
+}
+
+void wxSizer::GetPosition(int *x, int *y) const
+{
+  *x = sizerX;
+  *y = sizerY;
+}
+
+bool wxSizer::LayoutPhase1(int *noChanges)
+{
+  *noChanges = 0;
+  switch (sizerBehaviour)
+  {
+    case wxSizerExpand:
+    {
+      if (!m_sizerParent)
+      {
+        wxMessageBox("wxExpandSizer has no parent!", "Sizer error", wxOK);
+        return TRUE;
+      }
+
+      // Set the size to fill the parent client area
+      int pw, ph;
+      m_sizerParent->GetClientSize(&pw, &ph);
+      SetSize(GetBorderX(), GetBorderY(), pw - 2*GetBorderX(), ph - 2*GetBorderY());
+      wxLayoutConstraints *constr = GetConstraints();
+
+      // Fill in the constraints
+      if (constr)
+      {
+        constr->left.SetValue(0); constr->left.SetDone(TRUE);
+        constr->top.SetValue(0); constr->right.SetDone(TRUE);
+        constr->width.SetValue(pw); constr->width.SetDone(TRUE);
+        constr->height.SetValue(ph); constr->height.SetDone(TRUE);
+      }
+  
+      return TRUE;
+      break;
+    }
+    case wxSizerShrink:
+    {
+      wxLayoutConstraints *constr = GetConstraints();
+
+      if (constr)
+      {
+        // Force the constraint to have as-is width and height
+        // if we're in shrink-to-fit mode, because if left unconstrained,
+        // SatisfyConstraints will fail. The shrink-to-fit option
+        // essentially specifies the width and height as 'whatever I calculate'.
+        constr->width.AsIs();
+        constr->height.AsIs();
+      }
+      DoPhase(1);
+      DoPhase(2);
+      // Find the bounding box and set own size
+      int maxX = 0;
+      int maxY = 0;
+      wxNode *node = GetChildren()->First();
+      while (node)
+      {
+        int x, y, width, height;
+        wxWindow *win = (wxWindow *)node->Data();
+        win->GetSizeConstraint(&width, &height);
+        win->GetPositionConstraint(&x, &y);
+        if ((x+width) > maxX)
+          maxX = (x + width);
+        if ((y+height) > maxY)
+          maxY = (y + height);
+        node = node->Next();
+      }
+      SetSize(GetBorderX(), GetBorderY(), maxX, maxY);
+
+	  // If this is the only sizer for the parent, size the parent to this sizer.
+	  if ( m_sizerParent && (m_sizerParent->GetSizer() == this) )
+		m_sizerParent->SetClientSize(maxX + 2*GetBorderX(), maxY + 2*GetBorderY());
+
+      return TRUE;
+      break;
+    }
+    case wxSizerNone:
+    {
+      wxLayoutConstraints *constr = GetConstraints();
+      if (constr)
+      {
+        bool success = constr->SatisfyConstraints(this, noChanges);
+        if (success)
+        {
+          int x = constr->left.GetValue();
+          int y = constr->top.GetValue();
+          int w = constr->width.GetValue();
+          int h = constr->height.GetValue();
+          SetSize(x, y, w, h);
+        }
+        return success;
+      }
+      else
+        return TRUE;
+      break;
+    }
+  }
+  return TRUE;
+
+}
+
+bool wxSizer::LayoutPhase2(int *noChanges)
+{
+  *noChanges = 0;
+
+  switch (sizerBehaviour)
+  {
+    case wxSizerExpand:
+    {
+      // Layout children
+      DoPhase(1);
+      DoPhase(2);
+      return TRUE;
+    }
+    case wxSizerShrink:
+    {
+      wxLayoutConstraints *constr = GetConstraints();
+      if (constr)
+      {
+        bool success = constr->SatisfyConstraints(this, noChanges);
+        if (success)
+        {
+          int x = constr->left.GetValue();
+          int y = constr->top.GetValue();
+          Move(x, y);
+        }
+        return success;
+      }
+      break;
+    }
+    case wxSizerNone:
+    {
+      // Layout children
+      DoPhase(1);
+      DoPhase(2);
+
+	  // Is this a dumb fix for lack of constraint evaluation?
+      wxLayoutConstraints *constr = GetConstraints();
+      if (constr)
+      {
+        bool success = constr->SatisfyConstraints(this, noChanges);
+        if (success)
+        {
+          int x = constr->left.GetValue();
+          int y = constr->top.GetValue();
+          int w = constr->width.GetValue();
+          int h = constr->height.GetValue();
+          SetSize(x, y, w, h);
+        }
+        return success;
+      }
+      else
+        return TRUE;
+    }
+  }
+  return TRUE;
+}
+
+/*
+ * wxRowColSizer
+ */
+ 
+wxRowColSizer::wxRowColSizer(void)
+{
+  rowOrCol = TRUE;
+  rowOrColSize = 20;
+  xSpacing = 2;
+  ySpacing = 2;
+}
+
+wxRowColSizer::wxRowColSizer(wxWindow *parent, bool rc, int n, wxSizerBehaviour behav)
+{
+  Create(parent, rc, n, behav);
+}
+
+bool wxRowColSizer::Create(wxWindow *parent, bool rc, int n, wxSizerBehaviour behav)
+{
+  wxSizer::Create(parent, behav);
+  
+  rowOrCol = rc;
+  rowOrColSize = n;
+  xSpacing = 2;
+  ySpacing = 2;
+
+  return TRUE;
+}
+
+wxRowColSizer::~wxRowColSizer(void)
+{
+}
+
+void wxRowColSizer::SetSize(const int x, const int y, const int w, const int h, const int flags)
+{
+  wxSizer::SetSize(x, y, w, h, flags);
+}
+
+bool wxRowColSizer::LayoutPhase1(int *noChanges)
+{
+  *noChanges = 0;
+  wxLayoutConstraints *constr = GetConstraints();
+
+  if (constr)
+  {
+    // Force the constraint to have as-is width and height
+    // if we're in shrink-to-fit mode, because if left unconstrained,
+    // SatisfyConstraints will fail. The shrink-to-fit option
+    // essentially specifies the width and height as 'whatever I calculate'.
+    if (sizerBehaviour == wxSizerShrink)
+    {
+      constr->width.AsIs();
+      constr->height.AsIs();
+    }
+
+    // Only evaluate the constraints FIRST if we're NOT
+    // in shrink-to-fit mode, i.e. we want to size the rowcol
+    // first, then lay the children out in the space we've calculated.
+    if (sizerBehaviour != wxSizerShrink)
+    {
+      bool success = constr->SatisfyConstraints(this, noChanges);
+      if (success)
+      {
+        int x = constr->left.GetValue();
+        int y = constr->top.GetValue();
+        int w = constr->width.GetValue();
+        int h = constr->height.GetValue();
+        SetSize(x, y, w, h);
+      }
+      else
+        return FALSE;
+
+      // Continue to do the rest of the phase when the constraints have been
+      // satisfied, i.e. we're on the last iteration of phase 1 and
+      // can now do the actual rowcol laying out.
+    }
+  }
+
+  // If we ARE in shrink-to-fit mode, we must now
+  // calculate the child sizes BEFORE laying out in rows or columns.
+  if (sizerBehaviour == wxSizerShrink)
+  {
+    DoPhase(1);
+    DoPhase(2);
+
+    // WILL THE WINDOW BE SIZED CORRECTLY AT THIS POINT?
+    // CHECK CONSTRAINTS IF ANY...
+    int noRows = 0;
+    int noCols = 0;
+    int currentX = borderX;
+    int currentY = borderY;
+    int maxX = currentX;
+    int maxY = currentY;
+    
+    wxNode *node = GetChildren()->First();
+    while (node)
+    {
+      wxWindow *win = (wxWindow *)node->Data();
+      int childWidth, childHeight;
+      if (win->GetConstraints() &&
+          win->GetConstraints()->width.GetDone() &&
+          win->GetConstraints()->height.GetDone())
+      {
+        childWidth = win->GetConstraints()->width.GetValue();
+        childHeight = win->GetConstraints()->height.GetValue();
+      }
+      else
+        win->GetSize(&childWidth, &childHeight);
+
+      win->MoveConstraint(currentX, currentY);
+
+      if ((currentX + childWidth) > maxX)
+        maxX = (currentX + childWidth);
+      if ((currentY + childHeight) > maxY)
+        maxY = (currentY + childHeight);
+
+      if (rowOrCol)
+      {
+        currentX += childWidth + xSpacing;
+        noCols ++;
+
+        // Reset to start of row
+        if (noCols == rowOrColSize)
+        {
+          currentX = borderX;
+          currentY += childHeight + ySpacing;
+          noCols = 0;
+        }
+      }
+      else
+      {
+        currentY += childHeight + ySpacing;
+        noRows ++;
+
+        // Reset to start of col
+        if (noRows == rowOrColSize)
+        {
+          currentY = borderY;
+          currentX += childWidth + xSpacing;
+          noRows = 0;
+        }
+      }
+      
+      node = node->Next();
+    }
+    maxX += borderX;
+    maxY += borderY;
+
+    SetSize(-1, -1, maxX, maxY);
+  }
+  return TRUE;
+}
+
+bool wxRowColSizer::LayoutPhase2(int *noChanges)
+{
+  *noChanges = 0;
+  
+  // If shrink-to-fit, it's only at Phase 2 that we know the size of
+  // the wxRowColSizer, and now we can evaluate the
+  // constraints and pass result back up to parent.
+  // This implements a depth-first strategy
+  if (sizerBehaviour == wxSizerShrink)
+  {
+    wxLayoutConstraints *constr = GetConstraints();
+    if (constr)
+    {
+      bool success = constr->SatisfyConstraints(this, noChanges);
+      if (success)
+      {
+        int x = constr->left.GetValue();
+        int y = constr->top.GetValue();
+        Move(x, y);
+      }
+      return success;
+    }
+    else return TRUE;
+  }
+  else
+  {
+    // Lay out the children: breadth-first strategy.
+    DoPhase(1);
+    DoPhase(2);
+
+    // Space them
+  }
+  return TRUE;
+}
+
+
+/*
+ * wxSpacingSizer
+ */
+ 
+wxSpacingSizer::wxSpacingSizer(void)
+{
+}
+
+wxSpacingSizer::wxSpacingSizer(wxWindow *parent)
+{
+  Create(parent);
+}
+
+wxSpacingSizer::wxSpacingSizer(wxWindow *parent, wxRelationship rel, wxWindow *other, int spacing)
+{
+  Create(parent, rel, other, spacing);
+}
+
+bool wxSpacingSizer::Create(wxWindow *parent)
+{
+  wxSizer::Create(parent);
+  return TRUE;
+}
+
+bool wxSpacingSizer::Create(wxWindow *parent, wxRelationship rel, wxWindow *other, int spacing)
+{
+  wxLayoutConstraints *c = new wxLayoutConstraints;
+
+  wxSizer::Create(parent);
+
+  switch ( rel )
+  {
+	case wxLeftOf :
+  		c->width.Absolute	(spacing);
+		c->top.SameAs		(other, wxTop);
+		c->bottom.SameAs	(other, wxBottom);
+		c->right.LeftOf		(other);
+		break;
+	case wxRightOf :
+  		c->width.Absolute	(spacing);
+		c->top.SameAs		(other, wxTop);
+		c->bottom.SameAs	(other, wxBottom);
+		c->left.RightOf		(other);
+		break;
+	case wxBelow :
+  		c->height.Absolute	(spacing);
+		c->left.SameAs		(other, wxLeft);
+		c->right.SameAs		(other, wxRight);
+		c->top.Below		(other);
+		break;
+	case wxAbove :
+  		c->height.Absolute	(spacing);
+		c->left.SameAs		(other, wxLeft);
+		c->right.SameAs		(other, wxRight);
+		c->bottom.Above		(other);
+		break;
+
+	default :
+		break;
+  }
+  SetConstraints(c);
+
+  return TRUE;
+}
+
+wxSpacingSizer::~wxSpacingSizer(void)
+{
+}
+
+
+
+#endif
diff --git a/src/common/list.cpp b/src/common/list.cpp
new file mode 100644
index 0000000000..ac936bb265
--- /dev/null
+++ b/src/common/list.cpp
@@ -0,0 +1,640 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        list.cpp
+// Purpose:     wxList implementation
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "list.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/defs.h"
+#include "wx/list.h"
+#include "wx/utils.h"
+#endif
+
+// Sun CC compatibility (interference with xview/pkg.h, apparently...)
+#if defined(SUN_CC) && defined(__XVIEW__)
+#undef va_start
+#undef va_end
+#undef va_arg
+#undef va_list
+#endif
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxNode, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxList, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxStringList, wxList)
+#endif
+
+wxNode::wxNode (wxList * the_list, wxNode * last_one, wxNode * next_one,
+	wxObject * object)
+{
+  data = object;
+  previous = last_one;
+  next = next_one;
+  list = the_list;
+  key.string = NULL;
+
+  if (previous)
+    previous->next = this;
+
+  if (next)
+    next->previous = this;
+}
+
+// Keyed constructor
+wxNode::wxNode (wxList * the_list, wxNode * last_one, wxNode * next_one,
+	wxObject * object, long the_key)
+{
+  data = object;
+  previous = last_one;
+  next = next_one;
+  list = the_list;
+  key.integer = the_key;
+
+  if (previous)
+    previous->next = this;
+
+  if (next)
+    next->previous = this;
+}
+
+wxNode::wxNode (wxList * the_list, wxNode * last_one, wxNode * next_one,
+	wxObject * object, const char *the_key)
+{
+  data = object;
+  previous = last_one;
+  next = next_one;
+  list = the_list;
+  key.string = copystring (the_key);
+
+  if (previous)
+    previous->next = this;
+
+  if (next)
+    next->previous = this;
+}
+
+
+wxNode::~wxNode (void)
+{
+  if (list)
+    list->n--;
+
+  if (list && list->destroy_data)
+    delete data;
+
+  if (list && list->key_type == wxKEY_STRING && key.string)
+    delete[]key.string;
+
+  // Make next node point back to the previous node from here
+  if (next)
+    next->previous = previous;
+  else if (list)
+    // If there's a new end of list (deleting the last one)
+    // make sure the list knows about it.
+    list->last_node = previous;
+
+  // Make the previous node point to the next node from here
+  if (previous)
+    previous->next = next;
+
+  // Or if no previous node (start of list), make sure list points at
+  // the next node which becomes the first!.
+  else if (list)
+    list->first_node = next;
+}
+
+wxList::wxList (void)
+{
+  first_node = NULL;
+  last_node = NULL;
+  n = 0;
+  destroy_data = 0;
+  key_type = wxKEY_NONE;
+}
+
+wxList::wxList (const int N, wxObject * Objects[])
+{
+  wxNode *last = NULL;
+
+  int i;
+  for (i = 0; i < N; i++)
+    {
+      wxNode *next = new wxNode (this, last, NULL, Objects[i]);
+      last = next;
+      if (i == 0)
+	first_node = next;
+    }
+  last_node = last;
+  n = N;
+  key_type = wxKEY_NONE;
+}
+
+wxList::wxList (const unsigned int the_key_type)
+{
+  n = 0;
+  destroy_data = 0;
+  first_node = NULL;
+  last_node = NULL;
+  key_type = the_key_type;
+}
+
+// Variable argument list, terminated by a zero
+wxList::wxList (wxObject * first_one...)
+{
+// #ifndef __SGI__
+  va_list ap;
+
+  va_start (ap, first_one);
+
+  wxNode *last = new wxNode (this, NULL, NULL, first_one);
+  first_node = last;
+  n = 1;
+
+  for (;;)
+    {
+      wxObject *object = va_arg (ap, wxObject *);
+//    if (object == NULL) // Doesn't work in Windows -- segment is non-zero for NULL!
+#ifdef __WINDOWS__
+      if ((int) object == 0)
+#else
+      if ((long) object == 0)
+#endif
+	break;
+      else
+	{
+	  wxNode *node = new wxNode (this, last, NULL, object);
+	  last = node;
+	  n++;
+	}
+    }
+  last_node = last;
+  va_end (ap);
+
+  destroy_data = 0;
+  key_type = wxKEY_NONE;
+/*
+#else
+  fprintf (stderr, "Error: cannot use variable-argument functions on SGI!\n");
+#endif
+*/
+}
+
+wxList::~wxList (void)
+{
+  wxNode *each = first_node;
+  while (each)
+    {
+      wxNode *next = each->Next ();
+      delete each;
+      each = next;
+    }
+}
+
+#ifdef USE_STORABLE_CLASSES
+wxList::wxList( istream &stream, char *WXUNUSED(data) )
+{
+  char buf[200];
+  unsigned int num;
+  stream.read( (char*)(&num), sizeof(num) );
+  for (unsigned int i = 0; i < num; i++)
+  {
+    int len;
+    stream.read( (char*)(&len), sizeof(len) );
+    stream.read( (char*)(&buf), len );
+    buf[len] = 0;
+    Append( wxCreateStoredObject( buf, stream, NULL ) );
+  };
+};
+
+void wxList::StoreObject( ostream &stream )
+{
+  unsigned int num = Number();
+  stream.write( (char*)(&num), sizeof(num) );
+  wxNode *node = First();
+  while (node)
+  {
+    wxObject *obj = (wxObject*) node->Data();
+    wxClassInfo *obj_info = obj->GetClassInfo();
+    int len = strlen(obj_info->className);
+    stream.write( (char*)(&len), sizeof(len) );
+    stream.write( obj_info->className, len );
+    obj->StoreObject( stream );
+    node = node->Next();
+  };
+};
+#endif
+  
+wxNode *wxList::Append(wxObject *object)
+{
+    wxNode *node = new wxNode(this, last_node, NULL, object);
+    if (!first_node)
+      first_node = node;
+    last_node = node;
+    n ++;
+    return node;
+}
+
+wxNode *wxList::Nth (const int i) const
+{
+  int j = 0;
+  for (wxNode * current = First (); current; current = current->Next ())
+    {
+      if (j++ == i)
+	return current;
+    }
+  return NULL;			// No such element
+
+}
+
+wxNode *wxList::Find (const long key) const
+{
+  wxNode *current = First();
+  while (current)
+  {
+    if (current->key.integer == key)
+      return current;
+    current = current->Next();
+  }
+    
+  return NULL;			// Not found!
+}
+
+wxNode *wxList::Find (const char *key) const
+{
+  wxNode *current = First();
+  while (current)
+  {
+      if (!current->key.string)
+	{
+	  wxFatalError ("wxList: string key not present, probably did not Append correctly!");
+	  break;
+	}
+      if (strcmp (current->key.string, key) == 0)
+	return current;
+      current = current->Next();
+  }
+
+  return NULL;			// Not found!
+
+}
+
+wxNode *wxList::Member (wxObject * object) const
+{
+  for (wxNode * current = First (); current; current = current->Next ())
+    {
+      wxObject *each = current->Data ();
+      if (each == object)
+	return current;
+    }
+  return NULL;
+}
+
+bool wxList::DeleteNode (wxNode * node)
+{
+  if (node)
+    {
+      delete node;
+      return TRUE;
+    }
+  return FALSE;
+}
+
+bool wxList::DeleteObject (wxObject * object)
+{
+  // Search list for object
+  for (wxNode * current = first_node; current; current = current->Next ())
+    {
+      if (current->Data () == object)
+	{
+	  delete current;
+	  return TRUE;
+	}
+    }
+  return FALSE;			// Did not find the object
+
+}
+
+
+// Insert new node at front of list
+wxNode *wxList::Insert (wxObject * object)
+{
+  wxNode *node = new wxNode (this, NULL, First (), object);
+  first_node = node;
+
+  if (!(node->Next ()))
+    last_node = node;
+
+  n++;
+  return node;
+}
+
+
+// Insert new node before given node.
+wxNode *wxList::Insert (wxNode * position, wxObject * object)
+{
+  wxNode *prev = NULL;
+  if (position)
+    prev = position->Previous ();
+
+  wxNode *node = new wxNode (this, prev, position, object);
+  if (!first_node)
+    {
+      first_node = node;
+      last_node = node;
+    }
+  if (!prev)
+    first_node = node;
+
+  n++;
+  return node;
+}
+
+// Keyed append
+wxNode *wxList::Append (const long key, wxObject * object)
+{
+  wxNode *node = new wxNode (this, last_node, NULL, object, key);
+  if (!first_node)
+    first_node = node;
+  last_node = node;
+  n++;
+  return node;
+}
+
+wxNode *wxList::Append (const char *key, wxObject * object)
+{
+  wxNode *node = new wxNode (this, last_node, NULL, object, key);
+  if (!first_node)
+    first_node = node;
+  last_node = node;
+  n++;
+  return node;
+}
+
+void wxList::Clear (void)
+{
+  wxNode *current = first_node;
+  while (current)
+    {
+      wxNode *next = current->Next ();
+      delete current;
+      current = next;
+    }
+  first_node = NULL;
+  last_node = NULL;
+  n = 0;
+}
+
+//Executes function F with all items present in the list
+void wxList::ForEach(wxListIterateFunction F)
+{
+  wxNode *each = first_node;
+  while (each)
+    { (*F)( each->Data ());
+      each = each->Next();
+    }
+}
+// Returns a pointer to the item which returns TRUE with function F
+// or NULL if no such item found
+wxObject *wxList::FirstThat(wxListIterateFunction F)
+{
+  wxNode *each = first_node;
+  while (each)
+    { if ((*F)( each->Data ())) return each->Data();
+      each = each->Next();
+    }
+  return NULL;
+}
+// Like FirstThat, but proceeds from the end backward
+wxObject *wxList::LastThat(wxListIterateFunction F)
+{
+  wxNode *each = last_node;
+  while (each)
+    { if ((*F)( each->Data ())) return each->Data();
+      each = each->Previous();
+    }
+  return NULL;
+}
+
+// (stefan.hammes@urz.uni-heidelberg.de)
+//
+// function for sorting lists. the concept is borrowed from 'qsort'.
+// by giving a sort function, arbitrary lists can be sorted.
+// method:
+// - put wxObject pointers into an array
+// - sort the array with qsort
+// - put back the sorted wxObject pointers into the list
+//
+// CAVE: the sort function receives pointers to wxObject pointers (wxObject **),
+//       so dereference right!
+// EXAMPLE:
+//   int listcompare(const void *arg1, const void *arg2)
+//   {
+//      return(compare(**(wxString **)arg1,
+//                     **(wxString **)arg2));
+//   }
+//
+//   void main()
+//   { 
+//     wxList list;
+//
+//     list.Append(new wxString("DEF"));
+//     list.Append(new wxString("GHI"));
+//     list.Append(new wxString("ABC"));
+//     list.Sort(listcompare);
+//   }
+
+void wxList::Sort(const wxSortCompareFunction compfunc)
+{
+  // allocate an array for the wxObject pointers of the list
+  const size_t num = Number();
+  wxObject **objArray = new wxObject *[num];
+  wxObject **objPtr = objArray;
+  
+  // go through the list and put the pointers into the array
+  wxNode *node = First();
+  while(node!=NULL){
+    *objPtr++ = node->Data();
+    node = node->Next();
+  }
+  // sort the array
+  qsort((void *)objArray,num,sizeof(wxObject *),compfunc);
+  // put the sorted pointers back into the list  
+  objPtr = objArray;
+  node = First();
+  while(node!=NULL){
+    node->SetData(*objPtr++);
+    node = node->Next();
+  }
+  // free the array
+  delete[] objArray;
+}
+
+/*
+ * String list
+ *
+ */
+
+wxStringList::wxStringList (void):
+wxList ()
+{
+}
+
+// Variable argument list, terminated by a zero
+// Makes new storage for the strings
+wxStringList::wxStringList (const char *first...)
+{
+// #ifndef __SGI__
+  n = 0;
+  destroy_data = 0;
+  key_type = wxKEY_NONE;
+  first_node = NULL;
+  last_node = NULL;
+
+  if (!first)
+    return;
+
+  va_list ap;
+
+  va_start (ap, first);
+
+  wxNode *last = new wxNode (this, NULL, NULL, (wxObject *) copystring (first));
+  first_node = last;
+  n = 1;
+
+  for (;;)
+    {
+      char *s = va_arg (ap, char *);
+//    if (s == NULL)
+#ifdef __WINDOWS__
+      if ((int) s == 0)
+#else
+      if ((long) s == 0)
+#endif
+	break;
+      else
+	{
+	  wxNode *node = new wxNode (this, last, NULL, (wxObject *) copystring (s));
+	  last = node;
+	  n++;
+	}
+    }
+  last_node = last;
+  va_end (ap);
+/*
+#else
+  fprintf (stderr, "Error: cannot use variable-argument functions on SGI!\n");
+#endif
+*/
+}
+
+wxStringList::~wxStringList (void)
+{
+  wxNode *each = first_node;
+  while (each)
+    {
+      char *s = (char *) each->Data ();
+      delete[]s;
+      wxNode *next = each->Next ();
+      delete each;
+      each = next;
+    }
+}
+
+wxNode *wxStringList::Add (const char *s)
+{
+  return Append ((wxObject *) (copystring (s)));
+}
+
+void wxStringList::Delete (const char *s)
+{
+  for (wxNode * node = First (); node; node = node->Next ())
+    {
+      char *string = (char *) node->Data ();
+      if (string == s || strcmp (string, s) == 0)
+	{
+	  delete[]string;
+	  delete node;
+	  break;		// Done!
+
+	}
+    }				// for
+
+}
+
+// Only makes new strings if arg is TRUE
+char **wxStringList::ListToArray (const bool new_copies) const
+{
+  char **string_array = new char *[Number ()];
+  wxNode *node = First ();
+  int i;
+  for (i = 0; i < n; i++)
+    {
+      char *s = (char *) node->Data ();
+      if (new_copies)
+	string_array[i] = copystring (s);
+      else
+	string_array[i] = s;
+      node = node->Next ();
+    }
+  return string_array;
+}
+
+static int 
+wx_comparestrings (const void *arg1, const void *arg2)
+{
+  char **s1 = (char **) arg1;
+  char **s2 = (char **) arg2;
+
+  return strcmp (*s1, *s2);
+}
+
+// Sort a list of strings - deallocates old nodes, allocates new
+void wxStringList::Sort (void)
+{
+  size_t N = n;
+  char **array = new char *[N];
+
+  size_t i = 0;
+  for (wxNode * node = First (); node; node = node->Next ())
+    array[i++] = (char *) node->Data ();
+
+  qsort (array, N, sizeof (char *), wx_comparestrings);
+  Clear ();
+
+  for (i = 0; i < N; i++)
+    Append ((wxObject *) (array[i]));
+
+  delete[]array;
+}
+
+// Checks whether s is a member of the list
+bool wxStringList::Member (const char *s) const
+{
+  for (wxNode * node = First (); node; node = node->Next ())
+    {
+      const char *s1 = (const char *) node->Data ();
+      if (s == s1 || strcmp (s, s1) == 0)
+	return TRUE;
+    }
+  return FALSE;
+}
diff --git a/src/common/log.cpp b/src/common/log.cpp
new file mode 100644
index 0000000000..27f5f20ce1
--- /dev/null
+++ b/src/common/log.cpp
@@ -0,0 +1,611 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        log.cpp
+// Purpose:     Assorted wxLogXXX functions, and wxLog (sink for logs)
+// Author:      Vadim Zeitlin
+// Modified by:
+// Created:     29/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+#ifdef __GNUG__
+  #pragma implementation "log.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+  #pragma hdrstop
+#endif
+
+// wxWindows
+#ifndef WX_PRECOMP
+  #include  <wx/string.h>
+  #include  <wx/app.h>
+  #include  <wx/generic/msgdlgg.h>
+#endif
+
+#include  <wx/intl.h>
+#include  <wx/log.h>
+
+// other standard headers
+#include  <errno.h>
+#include  <stdlib.h>
+#include  <time.h>
+
+// C++ headers
+#include  <iostream.h>
+
+// _WINDOWS_ is defined when windows.h is included,
+// __WINDOWS__ is defined for MS Windows compilation
+#if       defined(__WINDOWS__) && !defined(_WINDOWS_)
+#include  <windows.h>
+#endif  //windows.h
+
+// ----------------------------------------------------------------------------
+// non member functions
+// ----------------------------------------------------------------------------
+
+// define this to enable wrapping of log messages
+//#define LOG_PRETTY_WRAP
+
+#ifdef LOG_PRETTY_WRAP
+  static void wxLogWrap(FILE *f, const char *pszPrefix, const char *psz);
+#endif
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// implementation of Log functions
+//
+// NB: unfortunately we need all these distinct functions, we can't make them
+//     macros and not all compilers inline vararg functions.
+// ----------------------------------------------------------------------------
+
+// log functions can't allocate memory (LogError("out of memory...") should
+// work!), so we use a static buffer for all log messages
+#define LOG_BUFFER_SIZE   (4096)
+
+// static buffer for error messages (@@@ MT-unsafe)
+static char s_szBuf[LOG_BUFFER_SIZE];
+
+// generic log function
+void wxLogGeneric(wxLog::Level level, wxTString strFormat, ...)
+{
+  if ( wxLog::GetActiveTarget() != NULL ) {               
+    va_list argptr;                                             
+    va_start(argptr, strFormat);                                
+    vsprintf(s_szBuf, strFormat, argptr);                       
+    va_end(argptr);                                             
+                                                                
+    wxLog::OnLog(level, s_szBuf);                         
+  }                                                             
+}
+
+#define IMPLEMENT_LOG_FUNCTION(level)                             \
+  void wxLog##level(wxTString strFormat, ...)                     \
+  {                                                               \
+    if ( wxLog::GetActiveTarget() != NULL ) {                     \
+      va_list argptr;                                             \
+      va_start(argptr, strFormat);                                \
+      vsprintf(s_szBuf, strFormat, argptr);                       \
+      va_end(argptr);                                             \
+                                                                  \
+      wxLog::OnLog(wxLog::level, s_szBuf);                        \
+    }                                                             \
+  }
+
+IMPLEMENT_LOG_FUNCTION(FatalError)
+IMPLEMENT_LOG_FUNCTION(Error)
+IMPLEMENT_LOG_FUNCTION(Warning)
+IMPLEMENT_LOG_FUNCTION(Message)
+IMPLEMENT_LOG_FUNCTION(Info)
+IMPLEMENT_LOG_FUNCTION(Status)
+
+// debug functions don't use wxTString
+#undef  IMPLEMENT_LOG_FUNCTION
+#define IMPLEMENT_LOG_FUNCTION(level)                             \
+  void wxLog##level(const char *szFormat, ...)                    \
+  {                                                               \
+    if ( wxLog::GetActiveTarget() != NULL ) {                     \
+      va_list argptr;                                             \
+      va_start(argptr, szFormat);                                 \
+      vsprintf(s_szBuf, szFormat, argptr);                        \
+      va_end(argptr);                                             \
+                                                                  \
+      wxLog::OnLog(wxLog::level, s_szBuf);                        \
+    }                                                             \
+  }
+
+IMPLEMENT_LOG_FUNCTION(Debug)
+IMPLEMENT_LOG_FUNCTION(Trace)
+
+void wxLogVerbose(wxTString strFormat, ...)
+{                                            
+  if ( wxLog::GetVerbose() && wxLog::GetActiveTarget() != NULL ) {
+    va_list argptr;                              
+    va_start(argptr, strFormat);                 
+    vsprintf(s_szBuf, strFormat, argptr);        
+    va_end(argptr);                              
+                                                 
+    wxLog::OnLog(wxLog::Info, s_szBuf);
+  }                                              
+}
+  
+void wxLogSysError(wxTString str, ...)
+{
+  if ( wxLog::GetActiveTarget() != NULL ) {
+    va_list argptr;
+    va_start(argptr, str);
+    vsprintf(s_szBuf, str, argptr);
+    va_end(argptr);
+
+    char szErrMsg[LOG_BUFFER_SIZE / 2];
+    sprintf(szErrMsg, _(" (error %ld: %s)"), wxSysErrorCode(), wxSysErrorMsg());
+    strncat(s_szBuf, szErrMsg, WXSIZEOF(s_szBuf) - strlen(s_szBuf));
+
+    wxLog::OnLog(wxLog::Error, s_szBuf);
+  }
+}
+
+void WXDLLEXPORT wxLogSysError(long lErrCode, wxTString strFormat, ...)
+{
+  if ( wxLog::GetActiveTarget() != NULL ) {
+    va_list argptr;
+    va_start(argptr, strFormat);
+    vsprintf(s_szBuf, strFormat, argptr);
+    va_end(argptr);
+
+    char szErrMsg[LOG_BUFFER_SIZE / 2];
+    sprintf(szErrMsg, _(" (error %ld: %s)"), lErrCode, wxSysErrorMsg(lErrCode));
+    strncat(s_szBuf, szErrMsg, WXSIZEOF(s_szBuf) - strlen(s_szBuf));
+
+    wxLog::OnLog(wxLog::Error, s_szBuf);
+  }
+}
+
+// ----------------------------------------------------------------------------
+// wxLog class implementation
+// ----------------------------------------------------------------------------
+
+wxLog::wxLog()
+{
+  m_bHasMessages = FALSE;
+}
+
+wxLog *wxLog::GetActiveTarget() 
+{ 
+  if ( !ms_bInitialized ) {
+    // prevent infinite recursion if someone calls wxLogXXX() from wxApp
+    ms_bInitialized = TRUE;
+
+    // ask the application to create a log target for us if it exists
+    if ( wxTheApp != NULL )
+      ms_pLogger = wxTheApp->CreateLogTarget();
+    else
+      ms_pLogger = new wxLogStderr; 
+
+    // do nothing if it fails - what can we do?
+  }
+
+  return ms_pLogger; 
+}
+
+wxLog *wxLog::SetActiveTarget(wxLog *pLogger)
+{ 
+  // flush the old messages before changing
+  if ( ms_pLogger != NULL )
+    ms_pLogger->Flush();
+
+  ms_bInitialized = TRUE;
+
+  wxLog *pOldLogger = ms_pLogger; 
+  ms_pLogger = pLogger; 
+  return pOldLogger; 
+}
+
+void wxLog::DoLog(Level level, const char *szString)
+{
+  char szBuf[128];
+  time_t timeNow;
+  struct tm *ptmNow;
+
+  time(&timeNow);
+  ptmNow = localtime(&timeNow);
+
+  strftime(szBuf, WXSIZEOF(szBuf), ms_szTimeFormat, ptmNow);
+  wxString str = szBuf;
+
+  switch ( level ) {
+    case FatalError:
+      DoLogString(str << _("Fatal error: ") << szString);
+      DoLogString(_("Program aborted."));
+      Flush();
+      abort();
+      break;
+
+    case Error:
+      DoLogString(str << _("Error: ") << szString);
+      break;
+
+    case Warning:
+      DoLogString(str << _("Warning: ") << szString);
+      break;
+
+    case Info:
+      if ( GetVerbose() )
+    case Message:
+        DoLogString(str + szString);
+      // fall through
+
+    case Status:
+      // nothing to do
+      break;
+
+    case Trace:
+    case Debug:
+      #ifdef __DEBUG__
+        #ifdef  __WIN32__
+          // in addition to normal logging, also send the string to debugger
+          // (don't prepend "Debug" here: it will go to debug window anyhow)
+          ::OutputDebugString(str + szString + "\n\r");
+        #endif  //Win32
+        DoLogString(str << (level == Trace ? _("Trace") : _("Debug"))
+                        << ": " << szString);
+      #endif
+            
+      break;
+
+    default:
+      wxFAIL_MSG("unknown log level in wxLog::DoLog");
+  }
+}
+
+void wxLog::DoLogString(const char *WXUNUSED(szString))
+{
+  wxFAIL_MSG("DoLogString must be overrided if it's called.");
+}
+
+void wxLog::Flush()
+{
+  // do nothing
+}
+
+// ----------------------------------------------------------------------------
+// wxLogStderr class implementation
+// ----------------------------------------------------------------------------
+
+wxLogStderr::wxLogStderr(FILE *fp)
+{
+  if ( fp == NULL )
+    m_fp = stderr;
+  else
+    m_fp = fp;
+}
+
+void wxLogStderr::DoLogString(const char *szString)
+{
+  fputs(szString, m_fp);
+  fputc('\n', m_fp);
+  fflush(m_fp);
+}
+
+// ----------------------------------------------------------------------------
+// wxLogStream implementation
+// ----------------------------------------------------------------------------
+
+wxLogStream::wxLogStream(ostream *ostr)
+{
+  if ( ostr == NULL )
+    m_ostr = &cerr;
+  else
+    m_ostr = ostr;
+}
+
+void wxLogStream::DoLogString(const char *szString)
+{
+  (*m_ostr) << szString << endl << flush;
+}
+
+// ----------------------------------------------------------------------------
+// wxLogTextCtrl implementation
+// ----------------------------------------------------------------------------
+
+/*
+wxLogTextCtrl::wxLogTextCtrl(wxTextCtrl *pTextCtrl)
+             : wxLogStream(new ostream(pTextCtrl))
+{
+}
+
+wxLogTextCtrl::~wxLogTextCtrl()
+{
+  delete m_ostr;
+}
+*/
+
+// ----------------------------------------------------------------------------
+// wxLogGui implementation
+// ----------------------------------------------------------------------------
+
+#ifndef   WX_TEST_MINIMAL
+
+wxLogGui::wxLogGui()
+{
+  m_bErrors = FALSE;
+}
+
+void wxLogGui::Flush()
+{
+  if ( !m_bHasMessages )
+    return;
+
+  // @@@ ugly...
+  
+  // concatenate all strings (but not too many to not overfill the msg box)
+  wxString str;
+  uint nLines    = 0, 
+       nMsgCount = m_aMessages.Count();
+
+  // start from the most recent message
+  for ( uint n = nMsgCount; n > 0; n-- ) {
+    // for Windows strings longer than this value are wrapped (NT 4.0)
+    const uint nMsgLineWidth = 156;
+
+    nLines += (m_aMessages[n - 1].Len() + nMsgLineWidth - 1) / nMsgLineWidth;
+
+    if ( nLines > 25 )  // don't put too many lines in message box
+      break;
+
+    str << m_aMessages[n - 1] << "\n";
+  }
+
+  if ( m_bErrors ) {
+    wxMessageBox(str, _("Error"), wxOK | wxICON_EXCLAMATION);
+  }
+  else {
+    wxMessageBox(str, _("Information"), wxOK | wxICON_INFORMATION);
+  }
+
+  // no undisplayed messages whatsoever
+  m_bHasMessages =
+  m_bErrors      = FALSE;
+  m_aMessages.Empty();
+}
+
+// the default behaviour is to discard all informational messages if there
+// are any errors/warnings.
+void wxLogGui::DoLog(Level level, const char *szString)
+{
+  switch ( level ) {
+    case Info:
+      if ( GetVerbose() )
+    case Message:
+        if ( !m_bErrors ) {
+          m_aMessages.Add(szString);
+          m_bHasMessages = TRUE;
+        }
+      break;
+
+    case Status:
+      {
+        // find the top window and set it's status text if it has any
+        wxWindow *pWin = wxTheApp->GetTopWindow();
+        if ( pWin != NULL && pWin->IsKindOf(CLASSINFO(wxFrame)) ) {
+          wxFrame *pFrame = (wxFrame *)pWin;
+          pFrame->SetStatusText(szString);
+        }
+      }
+      break;
+
+    case Trace:
+    case Debug:
+      #ifdef __DEBUG__
+        #ifdef  __WIN32__
+          OutputDebugString(szString);
+          OutputDebugString("\n\r");
+        #else   //!WIN32
+          // send them to stderr
+          printf(stderr, level == Trace ? "Trace: %s\n" 
+                                        : "Debug: %s\n", szString);
+          fflush(stderr);
+        #endif  // WIN32
+      #endif
+      break;
+
+    case FatalError:
+      // show this one immediately
+      wxMessageBox(szString, "Fatal error", wxICON_HAND);
+      break;
+
+    case Error:
+    case Warning:
+      // discard earlier informational messages if this is the 1st error
+      if ( !m_bErrors ) {
+        m_aMessages.Empty();
+        m_bHasMessages = TRUE;
+        m_bErrors = TRUE;
+      }
+
+      m_aMessages.Add(szString);
+      break;
+    
+    default:
+      wxFAIL_MSG("unknown log level in wxLogGui::DoLog");
+  }
+}
+
+#endif  //WX_TEST_MINIMAL
+
+// ============================================================================
+// Global functions/variables
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// static variables
+// ----------------------------------------------------------------------------
+wxLog      *wxLog::ms_pLogger      = NULL;
+bool        wxLog::ms_bInitialized = FALSE;
+bool        wxLog::ms_bVerbose     = FALSE;
+const char *wxLog::ms_szTimeFormat = "[%d/%b/%y %H:%M:%S] ";
+
+// ----------------------------------------------------------------------------
+// stdout error logging helper
+// ----------------------------------------------------------------------------
+
+// helper function: wraps the message and justifies it under given position
+// (looks more pretty on the terminal). Also adds newline at the end.
+//
+// @@ this is now disabled until I find a portable way of determining the
+//    terminal window size
+
+#ifdef    LOG_PRETTY_WRAP
+static void wxLogWrap(FILE *f, const char *pszPrefix, const char *psz)
+{
+  size_t nMax = 80; // @@@@
+  size_t nStart = strlen(pszPrefix);
+  fputs(pszPrefix, f);
+
+  size_t n;
+  while ( *psz != '\0' ) {
+    for ( n = nStart; (n < nMax) && (*psz != '\0'); n++ )
+      putc(*psz++, f);
+
+    // wrapped?
+    if ( *psz != '\0' ) {
+      /*putc('\n', f);*/
+      for ( n = 0; n < nStart; n++ )
+        putc(' ', f);
+
+      // as we wrapped, squeeze all white space
+      while ( isspace(*psz) )
+        psz++;
+    }
+  }
+
+  putc('\n', f);
+}
+#endif  //LOG_PRETTY_WRAP
+
+// ----------------------------------------------------------------------------
+// error code/error message retrieval functions
+// ----------------------------------------------------------------------------
+
+// get error code from syste
+unsigned long wxSysErrorCode()
+{
+  #ifdef  __WINDOWS__
+    #ifdef  __WIN32__
+      return ::GetLastError();
+    #else   //WIN16
+      // @@@@ what to do on Windows 3.1?
+      return 0;
+    #endif  //WIN16/32
+  #else   //Unix
+    return errno;
+  #endif  //Win/Unix
+}
+
+// get error message from system
+const char *wxSysErrorMsg(unsigned long nErrCode)
+{
+  if ( nErrCode == 0 )
+    nErrCode = wxSysErrorCode();
+
+#ifdef  __WINDOWS__
+#ifdef  __WIN32__
+  static char s_szBuf[LOG_BUFFER_SIZE / 2];
+
+  // get error message from system
+  LPVOID lpMsgBuf;
+  FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+                NULL, nErrCode, 
+                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                (LPTSTR)&lpMsgBuf,
+                0, NULL);
+
+  // copy it to our buffer and free memory
+  strncpy(s_szBuf, (const char *)lpMsgBuf, SIZEOF(s_szBuf) - 1);
+  s_szBuf[SIZEOF(s_szBuf) - 1] = '\0';
+  LocalFree(lpMsgBuf);
+
+  // returned string is capitalized and ended with '\r\n' - bad
+  s_szBuf[0] = (char)tolower(s_szBuf[0]);
+  size_t len = strlen(s_szBuf);
+  if ( len > 0 ) {
+    // truncate string
+    if ( s_szBuf[len - 2] == '\r' )
+      s_szBuf[len - 2] = '\0';
+  }
+
+  return s_szBuf;
+#else
+  // TODO: Windows 3.1
+  return NULL;
+#endif
+#else
+  return strerror(nErrCode);
+#endif
+}
+
+// ----------------------------------------------------------------------------
+// debug helper
+// ----------------------------------------------------------------------------
+
+#ifdef  __DEBUG__
+
+// this function is called when an assert fails
+void wxOnAssert(const char *szFile, int nLine, const char *szMsg)
+{
+  // this variable can be set to true to suppress "assert failure" messages
+  static s_bNoAsserts = FALSE;
+
+  char szBuf[LOG_BUFFER_SIZE];
+  sprintf(szBuf, _("Assert failed in file %s at line %d"), szFile, nLine);
+  if ( szMsg != NULL ) {
+    strcat(szBuf, ": ");
+    strcat(szBuf, szMsg);
+  }
+  else {
+    strcat(szBuf, ".");
+  }
+
+  // send it to the normal log destination
+  wxLogDebug(szBuf);
+
+  #ifdef  __WINDOWS__
+    if ( !s_bNoAsserts ) {
+      strcat(szBuf, _("\nDo you want to stop the program?"
+                      "\nYou can also choose [Cancel] to suppress "
+                      "further warnings."));
+
+      switch ( ::MessageBox(NULL, szBuf, _("Debug"), 
+                            MB_YESNOCANCEL | MB_ICONINFORMATION) ) {
+        case IDYES:
+          DebugBreak();
+          break;
+
+        case IDCANCEL:
+          s_bNoAsserts = TRUE;
+          break;
+      }
+    }
+  #else   
+    // @@@@ don't know how to start the debugger under generic Unix
+    s_bNoAsserts = TRUE; // suppress 'unused var' warning
+    abort();
+  #endif
+}
+
+#endif  //DEBUG
+
diff --git a/src/common/matrix.cpp b/src/common/matrix.cpp
new file mode 100644
index 0000000000..84beee3b61
--- /dev/null
+++ b/src/common/matrix.cpp
@@ -0,0 +1,267 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        matrix.cpp
+// Purpose:     wxTransformMatrix class
+// Author:      Chris Breeze, Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "matrix.h"
+#endif
+
+// Note: this is intended to be used in wxDC at some point to replace
+// the current system of scaling/translation. It is not yet used.
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/defs.h"
+#endif
+
+#include "wx/matrix.h"
+#include <math.h>
+
+const double pi = 3.1415926535;
+
+wxTransformMatrix::wxTransformMatrix(void)
+{
+	m_isIdentity = FALSE;
+
+	Identity();
+}
+
+wxTransformMatrix::wxTransformMatrix(const wxTransformMatrix& mat)
+{
+	(*this) = mat;
+}
+
+double wxTransformMatrix::GetValue(int row, int col) const
+{
+	if (row < 0 || row > 2 || col < 0 || col > 2)
+		return 0.0;
+
+	return m_matrix[row][col];
+}
+
+void wxTransformMatrix::SetValue(int row, int col, double value)
+{
+	if (row < 0 || row > 2 || col < 0 || col > 2)
+		return;
+
+	m_matrix[row][col] = value;
+}
+
+void wxTransformMatrix::operator = (const wxTransformMatrix& mat)
+{
+	int i, j;
+	for (i = 0; i < 3; i++)
+	{
+		for (j = 0; j < 3; j++)
+		{
+			m_matrix[i][j] = mat.m_matrix[i][j];
+		}
+	}
+	m_isIdentity = mat.m_isIdentity;
+}
+
+bool wxTransformMatrix::operator == (const wxTransformMatrix& mat)
+{
+	int i, j;
+	for (i = 0; i < 3; i++)
+	{
+		for (j = 0; j < 3; j++)
+		{
+			if (m_matrix[i][j] != mat.m_matrix[i][j])
+				return FALSE;
+		}
+	}
+	return TRUE;
+}
+
+bool wxTransformMatrix::operator != (const wxTransformMatrix& mat)
+{
+	return (! ((*this) == mat));
+}
+
+double& wxTransformMatrix::operator()(int row, int col)
+{
+	if (row < 0 || row > 2 || col < 0 || col > 2)
+		return m_matrix[0][0];
+
+	return m_matrix[row][col];
+}
+
+double wxTransformMatrix::operator()(int row, int col) const
+{
+	if (row < 0 || row > 2 || col < 0 || col > 2)
+		return 0.0;
+
+	return m_matrix[row][col];
+}
+
+// Invert matrix
+bool wxTransformMatrix::Invert(void)
+{
+	double inverseMatrix[3][3];
+
+	// calculate the adjoint
+	inverseMatrix[0][0] =  wxCalculateDet(m_matrix[1][1],m_matrix[2][1],m_matrix[1][2],m_matrix[2][2]);
+	inverseMatrix[0][1] = -wxCalculateDet(m_matrix[0][1],m_matrix[2][1],m_matrix[0][2],m_matrix[2][2]);
+	inverseMatrix[0][2] =  wxCalculateDet(m_matrix[0][1],m_matrix[1][1],m_matrix[0][2],m_matrix[1][2]);
+
+	inverseMatrix[1][0] = -wxCalculateDet(m_matrix[1][0],m_matrix[2][0],m_matrix[1][2],m_matrix[2][2]);
+	inverseMatrix[1][1] =  wxCalculateDet(m_matrix[0][0],m_matrix[2][0],m_matrix[0][2],m_matrix[2][2]);
+	inverseMatrix[1][2] = -wxCalculateDet(m_matrix[0][0],m_matrix[1][0],m_matrix[0][2],m_matrix[1][2]);
+
+	inverseMatrix[2][0] =  wxCalculateDet(m_matrix[1][0],m_matrix[2][0],m_matrix[1][1],m_matrix[2][1]);
+	inverseMatrix[2][1] = -wxCalculateDet(m_matrix[0][0],m_matrix[2][0],m_matrix[0][1],m_matrix[2][1]);
+	inverseMatrix[2][2] =  wxCalculateDet(m_matrix[0][0],m_matrix[1][0],m_matrix[0][1],m_matrix[1][1]);
+
+	// now divide by the determinant
+	double det = m_matrix[0][0] * inverseMatrix[0][0] + m_matrix[0][1] * inverseMatrix[1][0] + m_matrix[0][2] * inverseMatrix[2][0];
+	if (det != 0.0)
+	{
+		inverseMatrix[0][0] /= det; inverseMatrix[1][0] /= det; inverseMatrix[2][0] /= det;
+		inverseMatrix[0][1] /= det; inverseMatrix[1][1] /= det; inverseMatrix[2][1] /= det;
+		inverseMatrix[0][2] /= det; inverseMatrix[1][2] /= det; inverseMatrix[2][2] /= det;
+
+		int i, j;
+		for (i = 0; i < 3; i++)
+		{
+			for (j = 0; j < 3; j++)
+			{
+				m_matrix[i][j] = inverseMatrix[i][j];
+			}
+		}
+		m_isIdentity = IsIdentity1();
+		return TRUE;
+	}
+	else
+	{
+		return FALSE;
+	}
+}
+
+// Make into identity matrix
+bool wxTransformMatrix::Identity(void)
+{
+	m_matrix[0][0] = m_matrix[1][1] = m_matrix[2][2] = 1.0;
+	m_matrix[1][0] = m_matrix[2][0] = m_matrix[0][1] = m_matrix[2][1] = m_matrix[0][2] = m_matrix[1][2] = 0.0;
+	m_isIdentity = TRUE;
+
+	return TRUE;
+}
+
+// Scale by scale (isotropic scaling i.e. the same in x and y):
+//           | scale  0      0      |
+// matrix' = |  0     scale  0      | x matrix
+//           |  0     0      scale  |
+//
+bool wxTransformMatrix::Scale(double scale)
+{
+	int i, j;
+	for (i = 0; i < 3; i++)
+	{
+		for (j = 0; j < 3; j++)
+		{
+			m_matrix[i][j] *= scale;
+		}
+	}
+	m_isIdentity = IsIdentity1();
+
+	return TRUE;
+}
+
+// Translate by dx, dy:
+//           | 1  0 dx |
+// matrix' = | 0  1 dy | x matrix
+//           | 0  0  1 |
+//
+bool wxTransformMatrix::Translate(double dx, double dy)
+{
+	int i;
+	for (i = 0; i < 3; i++)
+		m_matrix[i][0] += dx * m_matrix[i][2];
+	for (i = 0; i < 3; i++)
+		m_matrix[i][1] += dy * m_matrix[i][2];
+
+	m_isIdentity = IsIdentity1();
+
+	return TRUE;
+}
+
+// Rotate by the given number of degrees:
+//           |  cos sin 0 |
+// matrix' = | -sin cos 0 | x matrix
+//           |   0   0  1 |
+//
+bool wxTransformMatrix::Rotate(double degrees)
+{
+	double angle = degrees * pi / 180.0;
+	double s = sin(angle);
+	double c = cos(angle);
+
+	m_matrix[0][0] = c * m_matrix[0][0] + s * m_matrix[0][1];
+	m_matrix[1][0] = c * m_matrix[1][0] + s * m_matrix[1][1];
+	m_matrix[2][0] = c * m_matrix[2][0] + s * m_matrix[2][1];
+	m_matrix[0][2] = c * m_matrix[0][1] - s * m_matrix[0][0];
+	m_matrix[1][2] = c * m_matrix[1][1] - s * m_matrix[1][0];
+	m_matrix[2][2] = c * m_matrix[2][1] - s * m_matrix[2][0];
+
+	m_isIdentity = IsIdentity1();
+
+	return TRUE;
+}
+
+// Transform a point from logical to device coordinates
+bool wxTransformMatrix::TransformPoint(double x, double y, double& tx, double& ty) const
+{
+	if (IsIdentity())
+	{
+		tx = x;	ty = y;	return TRUE;
+	}
+
+	tx = x * m_matrix[0][0] + y * m_matrix[1][0] + m_matrix[2][0];
+	ty = x * m_matrix[0][1] + y * m_matrix[1][1] + m_matrix[2][1];
+
+	return TRUE;
+}
+
+// Transform a point from device to logical coordinates.
+
+// Example of use:
+//   wxTransformMatrix mat = dc.GetTransformation();
+//   mat.Invert();
+//   mat.InverseTransformPoint(x, y, x1, y1);
+// OR (shorthand:)
+//   dc.LogicalToDevice(x, y, x1, y1);
+// The latter is slightly less efficient if we're doing several
+// conversions, since the matrix is inverted several times.
+
+bool wxTransformMatrix::InverseTransformPoint(double x, double y, double& tx, double& ty) const
+{
+	if (IsIdentity())
+	{
+		tx = x;	ty = y;	return TRUE;
+	}
+
+	double z = (1.0 - m_matrix[0][2] * x - m_matrix[1][2] * y) / m_matrix[2][2];
+	if (z == 0.0)
+	{
+//		z = 0.0000001;
+		return FALSE;
+	}
+	tx = x * m_matrix[0][0] + y * m_matrix[1][0] + z * m_matrix[2][0];
+	ty = x * m_matrix[0][1] + y * m_matrix[1][1] + z * m_matrix[2][1];
+	return TRUE;
+}
+
diff --git a/src/common/memory.cpp b/src/common/memory.cpp
new file mode 100644
index 0000000000..28256329b4
--- /dev/null
+++ b/src/common/memory.cpp
@@ -0,0 +1,1082 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        memory.cpp
+// Purpose:     Memory checking implementation
+// Author:      Arthur Seaton, Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "memory.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/defs.h"
+#endif
+
+#if (DEBUG && USE_MEMORY_TRACING) || USE_DEBUG_CONTEXT
+
+#ifdef __GNUG__
+// #pragma implementation
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/utils.h"
+#include "wx/app.h"
+#endif
+
+#include <stdlib.h>
+
+#if USE_IOSTREAMH
+#include <iostream.h>
+#else
+#include <iostream>
+#endif
+#include <fstream.h>
+
+#if !defined(__WATCOMC__) && !defined(__VMS__)
+#include <memory.h>
+#endif
+
+#include <stdarg.h>
+#include <string.h>
+
+#ifdef __WINDOWS__
+#include <windows.h>
+
+#ifdef GetClassInfo
+#undef GetClassInfo
+#endif
+
+#ifdef GetClassName
+#undef GetClassName
+#endif
+
+#endif
+
+#include "wx/memory.h"
+
+/*
+#ifdef new
+#undef new
+#endif
+*/
+
+// wxDebugContext wxTheDebugContext;
+/*
+  Redefine new and delete so that we can pick up situations where:
+	- we overwrite or underwrite areas of malloc'd memory.
+	- we use uninitialise variables
+  Only do this in debug mode.
+
+  We change new to get enough memory to allocate a struct, followed
+  by the caller's requested memory, followed by a tag. The struct
+  is used to create a doubly linked list of these areas and also
+  contains another tag. The tags are used to determine when the area
+  has been over/under written.
+*/
+
+
+/*
+  Values which are used to set the markers which will be tested for
+  under/over write. There are 3 of these, one in the struct, one
+  immediately after the struct but before the caller requested memory and
+  one immediately after the requested memory.
+*/
+#define MemStartCheck  0x23A8
+#define MemMidCheck  0xA328
+#define MemEndCheck 0x8A32
+#define MemFillChar 0xAF
+#define MemStructId  0x666D
+
+/*
+  External interface for the wxMemStruct class. Others are
+  defined inline within the class def. Here we only need to be able
+  to add and delete nodes from the list and handle errors in some way.
+*/
+
+/*
+  Used for internal "this shouldn't happen" type of errors.
+*/
+void wxMemStruct::ErrorMsg (const char * mesg)
+{
+  wxTrace("wxWindows memory checking error: %s\n", mesg);
+  PrintNode ();
+
+//	 << m_fileName << ' ' << m_lineNum << endl;
+}
+
+/*
+  Used when we find an overwrite or an underwrite error.
+*/
+void wxMemStruct::ErrorMsg ()
+{
+  wxTrace("wxWindows over/underwrite memory error: \n");
+  PrintNode ();
+    
+//    cerr << m_fileName << ' ' << m_lineNum << endl;
+}
+
+
+/*
+  We want to find out if pointers have been overwritten as soon as is
+  possible, so test everything before we dereference it. Of course it's still
+  quite possible that, if things have been overwritten, this function will
+  fall over, but the only way of dealing with that would cost too much in terms
+  of time.
+*/
+int wxMemStruct::AssertList ()
+{
+    if (wxDebugContext::GetHead () != 0 && ! (wxDebugContext::GetHead ())->AssertIt () ||
+	wxDebugContext::GetTail () != 0 && ! wxDebugContext::GetTail ()->AssertIt ()) {
+	ErrorMsg ("Head or tail pointers trashed");
+	return 0;
+    }
+    return 1;
+}
+
+
+/*
+  Check that the thing we're pointing to has the correct id for a wxMemStruct
+  object and also that it's previous and next pointers are pointing at objects
+  which have valid ids.
+  This is definitely not perfect since we could fall over just trying to access
+  any of the slots which we use here, but I think it's about the best that I
+  can do without doing something like taking all new wxMemStruct pointers and
+  comparing them against all known pointer within the list and then only
+  doing this sort of check _after_ you've found the pointer in the list. That
+  would be safer, but also much more time consuming.
+*/
+int wxMemStruct::AssertIt ()
+{
+    return (m_id == MemStructId &&
+	    (m_prev == 0 || m_prev->m_id == MemStructId) &&
+	    (m_next == 0 || m_next->m_id == MemStructId));
+}
+
+
+/*
+  Additions are always at the tail of the list.
+  Returns 0 on error, non-zero on success.
+*/
+int wxMemStruct::Append ()
+{
+    if (! AssertList ())
+	return 0;
+
+    if (wxDebugContext::GetHead () == 0) {
+	if (wxDebugContext::GetTail () != 0) {
+	    ErrorMsg ("Null list should have a null tail pointer");
+	    return 0;
+	}
+	(void) wxDebugContext::SetHead (this);
+	(void) wxDebugContext::SetTail (this);
+    } else {
+	wxDebugContext::GetTail ()->m_next = this;
+	this->m_prev = wxDebugContext::GetTail ();
+	(void) wxDebugContext::SetTail (this);
+    }
+    return 1;
+}
+
+
+/*
+  Don't actually free up anything here as the space which is used
+  by the node will be free'd up when the whole block is free'd.
+  Returns 0 on error, non-zero on success.
+*/
+int wxMemStruct::Unlink ()
+{
+    if (! AssertList ())
+	return 0;
+
+    if (wxDebugContext::GetHead () == 0 || wxDebugContext::GetTail () == 0) {
+	ErrorMsg ("Trying to remove node from empty list");
+	return 0;
+    }
+
+    // Handle the part of the list before this node.
+    if (m_prev == 0) {
+	if (this != wxDebugContext::GetHead ()) {
+	    ErrorMsg ("No previous node for non-head node");
+	    return 0;
+	}
+	(void) wxDebugContext::SetHead (m_next);
+    } else {
+	if (! m_prev->AssertIt ()) {
+	    ErrorMsg ("Trashed previous pointer");
+	    return 0;
+	}
+	
+	if (m_prev->m_next != this) {
+	    ErrorMsg ("List is inconsistent");
+	    return 0;
+	}
+	m_prev->m_next = m_next;
+    }
+
+    // Handle the part of the list after this node.
+    if (m_next == 0) {
+	if (this != wxDebugContext::GetTail ()) {
+	    ErrorMsg ("No next node for non-tail node");
+	    return 0;
+	}
+	(void) wxDebugContext::SetTail (m_prev);
+    } else {
+	if (! m_next->AssertIt ()) {
+	    ErrorMsg ("Trashed next pointer");
+	    return 0;
+	}
+
+	if (m_next->m_prev != this) {
+	    ErrorMsg ("List is inconsistent");
+	    return 0;
+	}
+	m_next->m_prev = m_prev;
+    }
+
+    return 1;
+}
+
+
+
+/*
+  Checks a node and block of memory to see that the markers are still
+  intact.
+*/
+int wxMemStruct::CheckBlock ()
+{
+    int nFailures = 0;
+
+    if (m_firstMarker != MemStartCheck) {
+	nFailures++;
+	ErrorMsg ();
+    }
+    
+    char * pointer = wxDebugContext::MidMarkerPos ((char *) this);
+    if (* (wxMarkerType *) pointer != MemMidCheck) {
+	nFailures++;
+	ErrorMsg ();
+    }
+    
+    pointer = wxDebugContext::EndMarkerPos ((char *) this, RequestSize ());
+    if (* (wxMarkerType *) pointer != MemEndCheck) {
+	nFailures++;
+	ErrorMsg ();
+    }
+    
+    return nFailures;
+}
+
+
+/*
+  Check the list of nodes to see if they are all ok.
+*/
+int wxMemStruct::CheckAllPrevious ()
+{
+    int nFailures = 0;
+    
+    for (wxMemStruct * st = this->m_prev; st != 0; st = st->m_prev) {
+	if (st->AssertIt ())
+	    nFailures += st->CheckBlock ();
+	else
+	    return -1;
+    }
+
+    return nFailures;
+}
+
+
+/*
+  When we delete a node we set the id slot to a specific value and then test
+  against this to see if a nodes have been deleted previously. I don't
+  just set the entire memory to the fillChar because then I'd be overwriting
+  useful stuff like the vtbl which may be needed to output the error message
+  including the file name and line numbers. Without this info the whole point
+  of this class is lost!
+*/
+void wxMemStruct::SetDeleted ()
+{
+    m_id = MemFillChar;
+}
+
+int wxMemStruct::IsDeleted ()
+{
+    return (m_id == MemFillChar);
+}
+
+
+/*
+  Print out a single node. There are many far better ways of doing this
+  but this will suffice for now.
+*/
+void wxMemStruct::PrintNode ()
+{
+  if (m_isObject)
+  {
+    wxObject *obj = (wxObject *)m_actualData;
+    wxClassInfo *info = obj->GetClassInfo();
+
+    if (info && info->GetClassName())
+      wxTrace("%s", info->GetClassName());
+    else
+      wxTrace("Object");
+
+    if (m_fileName)
+      wxTrace(" (%s %d)", m_fileName, (int)m_lineNum);
+
+    wxTrace(" at $%lX, size %d\n", (long)GetActualData(), (int)RequestSize());
+  }
+  else
+  {
+    wxTrace("Non-object data");
+    if (m_fileName)
+      wxTrace(" (%s %d)", m_fileName, (int)m_lineNum);
+    wxTrace(" at $%lX, size %d\n", (long)GetActualData(), (int)RequestSize());
+  }
+}
+
+void wxMemStruct::Dump ()
+{
+  if (!ValidateNode()) return;
+  
+  if (m_isObject)
+  {
+    wxObject *obj = (wxObject *)m_actualData;
+//    wxClassInfo *info = obj->GetClassInfo();
+
+    if (m_fileName)
+      wxTrace("Item (%s %d)", m_fileName, (int)m_lineNum);
+    else
+      wxTrace("Item");
+
+    wxTrace(" at $%lX, size %d: ", (long)GetActualData(), (int)RequestSize());
+//    wxTrace(info->GetClassName());
+    obj->Dump(wxDebugContext::GetStream());
+    wxTrace("\n");
+  }
+  else
+  {
+    wxTrace("Non-object data");
+    if (m_fileName)
+      wxTrace(" (%s %d)", m_fileName, (int)m_lineNum);
+    wxTrace(" at $%lX, size %d\n", (long)GetActualData(), (int)RequestSize());
+  }
+}
+
+
+/*
+  Validate a node. Check to see that the node is "clean" in the sense
+  that nothing has over/underwritten it etc.
+*/
+int wxMemStruct::ValidateNode ()
+{
+    char * startPointer = (char *) this;
+    if (!AssertIt ()) {
+	if (IsDeleted ())
+	    ErrorMsg ("Object already deleted");
+	else {
+	    // Can't use the error routines as we have no recognisable object.
+	    wxTrace("Can't verify memory struct - all bets are off!\n");
+	}
+	return 0;
+    }
+
+/*
+    int i;
+    for (i = 0; i < wxDebugContext::TotSize (requestSize ()); i++)
+      cout << startPointer [i];
+    cout << endl;
+*/
+    if (Marker () != MemStartCheck)
+      ErrorMsg ();
+    if (* (wxMarkerType *) wxDebugContext::MidMarkerPos (startPointer) != MemMidCheck)
+      ErrorMsg ();
+    if (* (wxMarkerType *) wxDebugContext::EndMarkerPos (startPointer,
+					      RequestSize ()) !=
+	MemEndCheck)
+      ErrorMsg ();
+
+    // Back to before the extra buffer and check that
+    // we can still read what we originally wrote.
+    if (Marker () != MemStartCheck ||
+	* (wxMarkerType *) wxDebugContext::MidMarkerPos (startPointer)
+	                 != MemMidCheck ||
+	* (wxMarkerType *) wxDebugContext::EndMarkerPos (startPointer,
+					      RequestSize ()) != MemEndCheck)
+    {
+	ErrorMsg ();
+	return 0;
+    }
+
+    return 1;
+}
+
+/*
+  The wxDebugContext class.
+*/
+
+wxMemStruct *wxDebugContext::m_head = NULL;
+wxMemStruct *wxDebugContext::m_tail = NULL;
+// ostream *wxDebugContext::m_debugStream = NULL;
+// streambuf *wxDebugContext::m_streamBuf = NULL;
+
+// Must initialise these in wxEntry, and then delete them just before wxEntry exits
+streambuf *wxDebugContext::m_streamBuf = NULL;
+ostream *wxDebugContext::m_debugStream = NULL;
+
+bool wxDebugContext::m_checkPrevious = FALSE;
+int wxDebugContext::debugLevel = 1;
+bool wxDebugContext::debugOn = TRUE;
+wxMemStruct *wxDebugContext::checkPoint = NULL;
+
+wxDebugContext::wxDebugContext(void)
+{
+//  m_streamBuf = new wxDebugStreamBuf;
+//  m_debugStream = new ostream(m_streamBuf);
+}
+
+wxDebugContext::~wxDebugContext(void)
+{
+  SetStream(NULL, NULL);
+}
+
+/*
+ * It's bizarre, but with BC++ 4.5, the value of str changes
+ * between SetFile and SetStream.
+ */
+
+void wxDebugContext::SetStream(ostream *str, streambuf *buf)
+{
+/*
+  if (str)
+  {
+    char buff[128];
+    sprintf(buff, "SetStream (1): str is %ld", (long) str);
+    MessageBox(NULL, buff, "Memory", MB_OK);
+  }
+*/
+
+  if (m_debugStream)
+  {
+    m_debugStream->flush();
+    delete m_debugStream;
+  }
+  m_debugStream = NULL;
+
+  // Not allowed in Watcom (~streambuf is protected).
+  // Is this trying to say something significant to us??
+#ifndef __WATCOMC__
+  if (m_streamBuf)
+  {
+    streambuf* oldBuf = m_streamBuf;
+    m_streamBuf = NULL;
+    delete oldBuf;
+  }
+#endif
+  m_streamBuf = buf;
+  m_debugStream = str;
+}
+
+bool wxDebugContext::SetFile(const wxString& file)
+{
+  ofstream *str = new ofstream((char *) (const char *)file);
+
+  if (str->bad())
+  {
+    delete str;
+    return FALSE;
+  }
+  else
+  {
+/*
+  char buf[40];
+  sprintf(buf, "SetFile: str is %ld", (long) str);
+  MessageBox(NULL, buf, "Memory", MB_OK);
+*/
+    SetStream(str);
+    return TRUE;
+  }
+}
+
+bool wxDebugContext::SetStandardError(void)
+{
+#if !defined(_WINDLL)
+  wxDebugStreamBuf *buf = new wxDebugStreamBuf;
+  ostream *stream = new ostream(m_streamBuf);
+  SetStream(stream, buf);
+  return TRUE;
+#else
+  return FALSE;
+#endif
+}
+
+
+/*
+  Work out the positions of the markers by creating an array of 2 markers
+  and comparing the addresses of the 2 elements. Use this number as the
+  alignment for markers.
+*/
+size_t wxDebugContext::CalcAlignment ()
+{
+    wxMarkerType ar[2];
+    return (char *) &ar[1] - (char *) &ar[0];
+}
+
+
+char * wxDebugContext::StructPos (const char * buf)
+{
+    return (char *) buf;
+}
+
+char * wxDebugContext::MidMarkerPos (const char * buf)
+{
+    return StructPos (buf) + PaddedSize (sizeof (wxMemStruct));
+}
+
+char * wxDebugContext::CallerMemPos (const char * buf)
+{
+    return MidMarkerPos (buf) + PaddedSize (sizeof(wxMarkerType));
+}
+
+
+char * wxDebugContext::EndMarkerPos (const char * buf, const size_t size)
+{
+    return CallerMemPos (buf) + PaddedSize (size);
+}
+
+
+/*
+  Slightly different as this takes a pointer to the start of the caller
+  requested region and returns a pointer to the start of the buffer.
+  */
+char * wxDebugContext::StartPos (const char * caller)
+{
+    return ((char *) (caller - wxDebugContext::PaddedSize (sizeof(wxMarkerType)) -
+	    wxDebugContext::PaddedSize (sizeof (wxMemStruct))));
+}
+
+/*
+  We may need padding between various parts of the allocated memory.
+  Given a size of memory, this returns the amount of memory which should
+  be allocated in order to allow for alignment of the following object.
+
+  I don't know how portable this stuff is, but it seems to work for me at
+  the moment. It would be real nice if I knew more about this!
+*/
+size_t wxDebugContext::GetPadding (const size_t size)
+{
+    size_t pad = size % CalcAlignment ();
+    return (pad) ? sizeof(wxMarkerType) - pad : 0;
+}
+
+
+
+size_t wxDebugContext::PaddedSize (const size_t size)
+{
+    return size + GetPadding (size);
+}
+
+/*
+  Returns the total amount of memory which we need to get from the system
+  in order to satisfy a caller request. This includes space for the struct
+  plus markers and the caller's memory as well.
+*/
+size_t wxDebugContext::TotSize (const size_t reqSize)
+{
+    return (PaddedSize (sizeof (wxMemStruct)) + PaddedSize (reqSize) +
+	    2 * sizeof(wxMarkerType));
+}
+
+
+/*
+  Traverse the list of nodes executing the given function on each node.
+*/
+void wxDebugContext::TraverseList (PmSFV func, wxMemStruct *from)
+{
+  if (!from)
+    from = wxDebugContext::GetHead ();
+    
+  for (wxMemStruct * st = from; st != 0; st = st->m_next)
+  {
+      void* data = st->GetActualData();
+      if ((data != (void*)m_debugStream) && (data != (void*) m_streamBuf))
+      {
+        (st->*func) ();
+      }
+  }
+}
+
+
+/*
+  Print out the list.
+  */
+bool wxDebugContext::PrintList (void)
+{
+#if DEBUG
+  if (!HasStream())
+    return FALSE;
+
+  TraverseList ((PmSFV)&wxMemStruct::PrintNode, (checkPoint ? checkPoint->m_next : NULL));
+
+  return TRUE;
+#else
+  return FALSE;
+#endif
+}
+
+bool wxDebugContext::Dump(void)
+{
+#if DEBUG
+  if (!HasStream())
+    return FALSE;
+
+  if (TRUE)
+  {
+    char* appName = "application";
+    wxString appNameStr("");
+    if (wxTheApp)
+    {
+        appNameStr = wxTheApp->GetAppName();
+        appName = (char*) (const char*) appNameStr;
+        wxTrace("Memory dump of %s at %s:\n", appName, wxNow());
+    }
+  }
+  TraverseList ((PmSFV)&wxMemStruct::Dump, (checkPoint ? checkPoint->m_next : NULL));
+
+  return TRUE;
+#else
+  return FALSE;
+#endif
+}
+
+struct wxDebugStatsStruct
+{
+  long instanceCount;
+  long totalSize;
+  char *instanceClass;
+  wxDebugStatsStruct *next;
+};
+
+static wxDebugStatsStruct *FindStatsStruct(wxDebugStatsStruct *st, char *name)
+{
+  while (st)
+  {
+    if (strcmp(st->instanceClass, name) == 0)
+      return st;
+    st = st->next;
+  }
+  return NULL;
+}
+
+static wxDebugStatsStruct *InsertStatsStruct(wxDebugStatsStruct *head, wxDebugStatsStruct *st)
+{
+  st->next = head;
+  return st;
+}
+
+bool wxDebugContext::PrintStatistics(bool detailed)
+{
+#if DEBUG
+  if (!HasStream())
+    return FALSE;
+
+  bool currentMode = GetDebugMode();
+  SetDebugMode(FALSE);
+  
+  long noNonObjectNodes = 0;
+  long noObjectNodes = 0;
+  long totalSize = 0;
+
+  wxDebugStatsStruct *list = NULL;
+
+  wxMemStruct *from = (checkPoint ? checkPoint->m_next : NULL);
+  if (!from)
+    from = wxDebugContext::GetHead ();
+
+  wxMemStruct *st;    
+  for (st = from; st != 0; st = st->m_next)
+  {
+    void* data = st->GetActualData();
+    if (detailed && (data != (void*)m_debugStream) && (data != (void*) m_streamBuf))
+    {
+      char *className = "nonobject";
+      if (st->m_isObject && st->GetActualData())
+      {
+        wxObject *obj = (wxObject *)st->GetActualData();
+        if (obj->GetClassInfo()->GetClassName())
+          className = obj->GetClassInfo()->GetClassName();
+      }
+      wxDebugStatsStruct *stats = FindStatsStruct(list, className);
+      if (!stats)
+      {
+        stats = (wxDebugStatsStruct *)malloc(sizeof(wxDebugStatsStruct));
+        stats->instanceClass = className;
+        stats->instanceCount = 0;
+        stats->totalSize = 0;
+        list = InsertStatsStruct(list, stats);
+      }
+      stats->instanceCount ++;
+      stats->totalSize += st->RequestSize();
+    }
+
+    if ((data != (void*)m_debugStream) && (data != (void*) m_streamBuf))
+    {
+        totalSize += st->RequestSize();
+        if (st->m_isObject)
+            noObjectNodes ++;
+        else
+            noNonObjectNodes ++;
+    }
+  }
+
+  if (detailed)
+  {
+    while (list)
+    {
+      wxTrace("%ld objects of class %s, total size %ld\n",
+          list->instanceCount, list->instanceClass, list->totalSize);
+      wxDebugStatsStruct *old = list;
+      list = old->next;
+      free((char *)old);
+    }
+    wxTrace("\n");
+  }
+  
+  SetDebugMode(currentMode);
+
+  wxTrace("Number of object items: %ld\n", noObjectNodes);
+  wxTrace("Number of non-object items: %ld\n", noNonObjectNodes);
+  wxTrace("Total allocated size: %ld\n", totalSize);
+
+  return TRUE;
+#else
+  return FALSE;
+#endif
+}    
+
+bool wxDebugContext::PrintClasses(void)
+{
+  if (!HasStream())
+    return FALSE;
+
+  if (TRUE)
+  {
+    char* appName = "application";
+    wxString appNameStr("");
+    if (wxTheApp)
+    {
+        appNameStr = wxTheApp->GetAppName();
+        appName = (char*) (const char*) appNameStr;
+        wxTrace("Classes in %s:\n\n", appName);
+    }
+  }
+
+  int n = 0;
+  wxClassInfo *info = wxClassInfo::first;
+  while (info)
+  {
+    if (info->GetClassName())
+    {
+      wxTrace("%s ", info->GetClassName());
+
+      if (info->GetBaseClassName1() && !info->GetBaseClassName2())
+        wxTrace("is a %s", info->GetBaseClassName1());
+      else if (info->GetBaseClassName1() && info->GetBaseClassName2())
+        wxTrace("is a %s, %s", info->GetBaseClassName1(), info->GetBaseClassName2());
+      if (info->objectConstructor)
+        wxTrace(": dynamic\n");
+      else
+        wxTrace("\n");
+    }
+    info = info->next;
+    n ++;
+  }
+  wxTrace("\nThere are %d classes derived from wxObject.\n", n);
+  return TRUE;
+}    
+
+void wxDebugContext::SetCheckpoint(bool all)
+{
+  if (all)
+    checkPoint = NULL;
+  else
+    checkPoint = m_tail;
+}
+
+// Checks all nodes since checkpoint, or since start.
+int wxDebugContext::Check(bool checkAll)
+{
+  int nFailures = 0;
+    
+  wxMemStruct *from = (checkPoint ? checkPoint->m_next : NULL);
+  if (!from || checkAll)
+    from = wxDebugContext::GetHead ();
+
+  for (wxMemStruct * st = from; st != 0; st = st->m_next)
+  {
+    if (st->AssertIt ())
+      nFailures += st->CheckBlock ();
+    else
+      return -1;
+  }
+
+  return nFailures;
+}
+
+// Count the number of non-wxDebugContext-related objects
+// that are outstanding
+int wxDebugContext::CountObjectsLeft(void)
+{
+  int n = 0;
+    
+  wxMemStruct *from = wxDebugContext::GetHead ();
+
+  for (wxMemStruct * st = from; st != 0; st = st->m_next)
+  {
+      void* data = st->GetActualData();
+      if ((data != (void*)m_debugStream) && (data != (void*) m_streamBuf))
+          n ++;
+  }
+
+  return n ;
+}
+
+/*
+  The global operator new used for everything apart from getting
+  dynamic storage within this function itself.
+*/
+
+// We'll only do malloc and free for the moment: leave the interesting
+// stuff for the wxObject versions.
+
+#if DEBUG && USE_GLOBAL_MEMORY_OPERATORS
+
+#ifdef new
+#undef new
+#endif
+
+// Seems OK all of a sudden. Maybe to do with linking with multithreaded library?
+#if 0 // def _MSC_VER
+#define NO_DEBUG_ALLOCATION
+#endif
+
+// Unfortunately ~wxDebugStreamBuf doesn't work (VC++ 5) when we enable the debugging
+// code. I have no idea why. In BC++ 4.5, we have a similar problem the debug
+// stream myseriously changing pointer address between being passed from SetFile to SetStream.
+// See docs/msw/issues.txt.
+void * operator new (size_t size, char * fileName, int lineNum)
+{
+#ifdef NO_DEBUG_ALLOCATION
+  return malloc(size);
+#else
+  return wxDebugAlloc(size, fileName, lineNum, FALSE, FALSE);
+#endif
+}
+
+void * operator new[] (size_t size, char * fileName, int lineNum)
+{
+#ifdef NO_DEBUG_ALLOCATION
+  return malloc(size);
+#else
+  return wxDebugAlloc(size, fileName, lineNum, FALSE, TRUE);
+#endif
+}
+
+void operator delete (void * buf)
+{
+#ifdef NO_DEBUG_ALLOCATION
+  free((char*) buf);
+#else
+  wxDebugFree(buf);
+#endif
+}
+
+void operator delete[] (void * buf)
+{
+#ifdef NO_DEBUG_ALLOCATION
+  free((char*) buf);
+#else
+  wxDebugFree(buf, TRUE);
+#endif
+}
+
+#endif
+
+// TODO: store whether this is a vector or not.
+void * wxDebugAlloc(size_t size, char * fileName, int lineNum, bool isObject, bool isVect)
+{
+  // If not in debugging allocation mode, do the normal thing
+  // so we don't leave any trace of ourselves in the node list.
+
+  if (!wxDebugContext::GetDebugMode())
+  {
+    return (void *)malloc(size);
+  }
+  
+    char * buf = (char *) malloc(wxDebugContext::TotSize (size));
+    if (!buf) {
+	wxTrace("Call to malloc (%ld) failed.\n", (long)size);
+	return 0;
+    }
+    wxMemStruct * st = (wxMemStruct *)buf;
+    st->m_firstMarker = MemStartCheck;
+    st->m_reqSize = size;
+    st->m_fileName = fileName;
+    st->m_lineNum = lineNum;
+    st->m_id = MemStructId;
+    st->m_prev = 0;
+    st->m_next = 0;
+    st->m_isObject = isObject;
+
+    // Errors from Append() shouldn't really happen - but just in case!
+    if (st->Append () == 0) {
+	st->ErrorMsg ("Trying to append new node");
+    }
+    
+    if (wxDebugContext::GetCheckPrevious ()) {
+	if (st->CheckAllPrevious () < 0) {
+	    st->ErrorMsg ("Checking previous nodes");
+	}
+    }
+    
+    // Set up the extra markers at the middle and end.
+    char * ptr = wxDebugContext::MidMarkerPos (buf);
+    * (wxMarkerType *) ptr = MemMidCheck;
+    ptr = wxDebugContext::EndMarkerPos (buf, size);
+    * (wxMarkerType *) ptr = MemEndCheck;
+
+    // pointer returned points to the start of the caller's
+    // usable area.
+    void *m_actualData = (void *) wxDebugContext::CallerMemPos (buf);
+    st->m_actualData = m_actualData;
+
+    return m_actualData;
+}
+
+// TODO: check whether was allocated as a vector
+void wxDebugFree(void * buf, bool isVect)
+{
+  if (!buf)
+    return;
+    
+  // If not in debugging allocation mode, do the normal thing
+  // so we don't leave any trace of ourselves in the node list.
+  if (!wxDebugContext::GetDebugMode())
+  {
+    free((char *)buf);
+    return;
+  }
+
+    // Points to the start of the entire allocated area.
+    char * startPointer = wxDebugContext::StartPos ((char *) buf);
+    // Find the struct and make sure that it's identifiable.
+    wxMemStruct * st = (wxMemStruct *) wxDebugContext::StructPos (startPointer);
+
+    if (! st->ValidateNode ())
+	return;
+
+    // If this is the current checkpoint, we need to
+    // move the checkpoint back so it points to a valid
+    // node.
+    if (st == wxDebugContext::checkPoint)
+      wxDebugContext::checkPoint = wxDebugContext::checkPoint->m_prev;
+
+    if (! st->Unlink ())
+    {
+      st->ErrorMsg ("Unlinking deleted node");
+    }
+    
+    // Now put in the fill char into the id slot and the caller requested
+    // memory locations.
+    st->SetDeleted ();
+    (void) memset (wxDebugContext::CallerMemPos (startPointer), MemFillChar,
+		   st->RequestSize ());
+
+    // Don't allow delayed freeing of memory in this version
+//    if (!wxDebugContext::GetDelayFree())
+//    free((void *)st);
+    free((char *)st);
+}
+
+// Trace: send output to the current debugging stream
+void wxTrace(const char *fmt ...)
+{
+  va_list ap;
+  static char buffer[512];
+
+  va_start(ap, fmt);
+
+#ifdef __WINDOWS__
+  wvsprintf(buffer,fmt,ap) ;
+#else
+  vsprintf(buffer,fmt,ap) ;
+#endif
+
+  va_end(ap);
+
+  if (wxDebugContext::HasStream())
+  {
+    wxDebugContext::GetStream() << buffer;
+    wxDebugContext::GetStream().flush();
+  }
+  else
+#ifdef __WINDOWS__
+    OutputDebugString((LPCSTR)buffer) ;
+#else
+    fprintf(stderr, buffer);
+#endif
+}
+
+// Trace with level
+void wxTraceLevel(int level, const char *fmt ...)
+{
+  if (wxDebugContext::GetLevel() < level)
+    return;
+    
+  va_list ap;
+  static char buffer[512];
+
+  va_start(ap, fmt);
+
+#ifdef __WINDOWS__
+  wvsprintf(buffer,fmt,ap) ;
+#else
+  vsprintf(buffer,fmt,ap) ;
+#endif
+
+  va_end(ap);
+
+  if (wxDebugContext::HasStream())
+  {
+    wxDebugContext::GetStream() << buffer;
+    wxDebugContext::GetStream().flush();
+  }
+  else
+#ifdef __WINDOWS__
+    OutputDebugString((LPCSTR)buffer) ;
+#else
+    fprintf(stderr, buffer);
+#endif
+}
+
+#else // USE_MEMORY_TRACING && DEBUG
+void wxTrace(const char *WXUNUSED(fmt) ...)
+{
+}
+
+void wxTraceLevel(int WXUNUSED(level), const char *WXUNUSED(fmt) ...)
+{
+}
+#endif
+
diff --git a/src/common/module.cpp b/src/common/module.cpp
new file mode 100644
index 0000000000..bd2b82d782
--- /dev/null
+++ b/src/common/module.cpp
@@ -0,0 +1,73 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        module.cpp
+// Purpose:     Modules initialization/destruction
+// Author:      Wolfram Gloger/adapted by Guilhem Lavaux
+// Modified by:
+// Created:     04/11/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Wolfram Gloger and Guilhem Lavaux
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "module.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#include "wx/module.h"
+
+IMPLEMENT_CLASS(wxModule, wxObject)
+
+wxList wxModule::m_modules;
+
+void wxModule::RegisterModule(wxModule* module)
+{
+  m_modules.Append(module);
+}
+
+// Collect up all module-derived classes, create an instance of each,
+// and register them.
+bool wxModule::RegisterModules(void)
+{
+    wxClassInfo* classInfo = wxClassInfo::first;
+    while (classInfo)
+    {
+        if ((classInfo != (& (wxModule::classwxModule))) &&
+            classInfo->IsKindOf(CLASSINFO(wxModule)))
+        {
+            wxModule* module = (wxModule*) classInfo->CreateObject();
+            RegisterModule(module);
+        }
+        classInfo = classInfo->next;
+    }
+    return TRUE;
+}
+
+bool wxModule::InitializeModules(void)
+{
+  // Initialize user-defined modules
+    for (wxNode *node = m_modules.First(); node; node = node->Next())
+    {
+      if (!((wxModule*)(node->Data()))->Init())
+        return FALSE;
+    }
+    return TRUE;
+}
+
+void wxModule::CleanUpModules(void)
+{
+  // Cleanup user-defined modules
+    for(wxNode* node = m_modules.Last(); node; node = node->Previous())
+    {
+      ((wxModule*)(node->Data()))->Exit();
+      delete (wxModule*)(node->Data());
+    }
+    m_modules.Clear();
+}
+
diff --git a/src/common/object.cpp b/src/common/object.cpp
new file mode 100644
index 0000000000..4dc8b093b3
--- /dev/null
+++ b/src/common/object.cpp
@@ -0,0 +1,304 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        object.cpp
+// Purpose:     wxObject implementation
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "object.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#include "wx/hash.h"
+
+#include <string.h>
+#include <assert.h>
+
+#if (DEBUG && USE_MEMORY_TRACING) || USE_DEBUG_CONTEXT
+#include "wx/memory.h"
+#endif
+
+#if DEBUG || USE_DEBUG_CONTEXT
+  // for wxObject::Dump
+  #include <iostream.h>
+#endif
+
+#if !USE_SHARED_LIBRARY
+wxClassInfo wxObject::classwxObject("wxObject", NULL, NULL, sizeof(wxObject), NULL);
+wxClassInfo *wxClassInfo::first = NULL;
+#endif
+
+/*
+ * wxWindows root object.
+ */
+
+wxObject::wxObject(void)
+{
+  m_refData = NULL;
+}
+
+wxObject::~wxObject(void)
+{
+	UnRef();
+}
+
+/*
+ * Is this object a kind of (a subclass of) 'info'?
+ * E.g. is wxWindow a kind of wxObject?
+ * Go from this class to superclass, taking into account
+ * two possible base classes.
+ */
+ 
+bool wxObject::IsKindOf(wxClassInfo *info)
+{
+  wxClassInfo *thisInfo = GetClassInfo();
+  if (thisInfo)
+    return thisInfo->IsKindOf(info);
+  else
+    return FALSE;
+}
+
+#if DEBUG || USE_DEBUG_CONTEXT
+void wxObject::Dump(ostream& str)
+{
+  if (GetClassInfo() && GetClassInfo()->GetClassName())
+    str << GetClassInfo()->GetClassName();
+  else
+    str << "unknown object class";
+}
+#endif
+
+#if DEBUG && USE_MEMORY_TRACING
+
+#ifdef new
+#undef new
+#endif
+
+void * wxObject::operator new (size_t size, char * fileName, int lineNum)
+{
+  return wxDebugAlloc(size, fileName, lineNum, TRUE);
+}
+
+void wxObject::operator delete (void * buf)
+{
+  wxDebugFree(buf);
+}
+
+// Cause problems for VC++ - crashes
+#ifndef _MSC_VER
+void * wxObject::operator new[] (size_t size, char * fileName, int lineNum)
+{
+  return wxDebugAlloc(size, fileName, lineNum, TRUE, TRUE);
+}
+
+void wxObject::operator delete[] (void * buf)
+{
+  wxDebugFree(buf, TRUE);
+}
+#endif
+
+#endif
+
+/*
+ * Class info: provides run-time class type information.
+ */
+
+#ifdef USE_STORABLE_CLASSES
+
+wxClassInfo::wxClassInfo(char *cName, char *baseName1, char *baseName2, int sz, wxObjectConstructorFn fn,
+     wxStorableConstructorFn stoFn )
+{
+  className = cName;
+  baseClassName1 = baseName1;
+  baseClassName2 = baseName2;
+
+  objectSize = sz;
+  objectConstructor = fn;
+  storableConstructor = stoFn;
+  
+  next = first;
+  first = this;
+
+  baseInfo1 = NULL;
+  baseInfo2 = NULL;
+}
+   
+wxObject* wxClassInfo::CreateObject( istream &stream, char *data )
+{
+  if (storableConstructor)
+    return (wxObject *)(*storableConstructor)( stream, data );
+  else
+    return NULL;
+}
+
+#else
+  
+wxClassInfo::wxClassInfo(char *cName, char *baseName1, char *baseName2, int sz, wxObjectConstructorFn constr)
+{
+  className = cName;
+  baseClassName1 = baseName1;
+  baseClassName2 = baseName2;
+
+  objectSize = sz;
+  objectConstructor = constr;
+  
+  next = first;
+  first = this;
+
+  baseInfo1 = NULL;
+  baseInfo2 = NULL;
+}
+
+#endif
+
+wxObject *wxClassInfo::CreateObject(void)
+{
+  if (objectConstructor)
+    return (wxObject *)(*objectConstructor)();
+  else
+    return NULL;
+}
+
+wxClassInfo *wxClassInfo::FindClass(char *c)
+{
+  wxClassInfo *p = first;
+  while (p)
+  {
+    if (p && p->GetClassName() && strcmp(p->GetClassName(), c) == 0)
+      return p;
+    p = p->next;
+  }
+  return NULL;
+}
+
+// Climb upwards through inheritance hierarchy.
+// Dual inheritance is catered for.
+bool wxClassInfo::IsKindOf(wxClassInfo *info)
+{
+  if (info == NULL)
+    return FALSE;
+
+  // For some reason, when making/using a DLL, static data has to be included
+  // in both the DLL and the application. This can lead to duplicate
+  // wxClassInfo objects, so we have to test the name instead of the pointers.
+#if WXMAKINGDLL
+  if (GetClassName() && info->GetClassName() && (strcmp(GetClassName(), info->GetClassName()) == 0))
+    return TRUE;
+#else
+  if (this == info)
+    return TRUE;
+#endif
+
+  if (baseInfo1)
+    if (baseInfo1->IsKindOf(info))
+      return TRUE;
+
+  if (baseInfo2)
+    return baseInfo2->IsKindOf(info);
+
+  return FALSE;
+}
+
+// Set pointers to base class(es) to speed up IsKindOf
+void wxClassInfo::InitializeClasses(void)
+{
+  wxHashTable table(wxKEY_STRING);
+
+  // Index all class infos by their class name
+  wxClassInfo *info = first;
+  while (info)
+  {
+    if (info->className)
+      table.Put(info->className, (wxObject *)info);
+    info = info->next;
+  }
+
+  // Set base pointers for each wxClassInfo
+  info = first;
+  while (info)
+  {
+    if (info->GetBaseClassName1())
+      info->baseInfo1 = (wxClassInfo *)table.Get(info->GetBaseClassName1());
+    if (info->GetBaseClassName2())
+      info->baseInfo2 = (wxClassInfo *)table.Get(info->GetBaseClassName2());
+    info = info->next;
+  }
+}
+
+wxObject *wxCreateDynamicObject(char *name)
+{
+  wxClassInfo *info = wxClassInfo::first;
+  while (info)
+  {
+    if (info->className && strcmp(info->className, name) == 0)
+      return info->CreateObject();
+    info = info->next;
+  }
+  return NULL;
+}
+
+#ifdef USE_STORABLE_CLASSES
+
+wxObject* wxCreateStoredObject( char *name, istream &stream, char *data )
+{
+  wxClassInfo *info = wxClassInfo::first;
+  while (info)
+  {
+    if (info->className && strcmp(info->className, name) == 0)
+      return info->CreateObject( stream, data );
+    info = info->next;
+  }
+  return NULL;
+};
+
+#endif
+
+/*
+ * wxObject: cloning of objects
+ */
+
+void wxObject::Ref(const wxObject& clone)
+{
+    // delete reference to old data
+    UnRef();
+    // reference new data
+    if (clone.m_refData) {
+        m_refData = clone.m_refData;
+        ++(m_refData->m_count);
+    }
+}
+
+void wxObject::UnRef(void)
+{
+    if (m_refData) {
+        assert(m_refData->m_count > 0);
+        --(m_refData->m_count);
+        if (m_refData->m_count == 0)
+            delete m_refData;
+    }
+    m_refData = NULL;
+}
+
+/*
+ * wxObjectData
+ */
+
+wxObjectRefData::wxObjectRefData(void) : m_count(1)
+{
+}
+
+wxObjectRefData::~wxObjectRefData(void)
+{
+}
+
diff --git a/src/common/odbc.cpp b/src/common/odbc.cpp
new file mode 100644
index 0000000000..7335397b84
--- /dev/null
+++ b/src/common/odbc.cpp
@@ -0,0 +1,1829 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        odbc.cpp
+// Purpose:     ODBC implementation
+// Author:      Julian Smart, Olaf Klein (oklein@smallo.ruhr.de),
+//               Patrick Halke (patrick@zaphod.ruhr.de)
+// Modified by:	
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "odbc.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#include "wx/defs.h"
+
+#if USE_ODBC
+
+#ifndef WX_PRECOMP
+#include "wx/utils.h"
+#include "wx/dialog.h"
+#endif
+
+#include "wx/string.h"
+#include "wx/odbc.h"
+
+#include <math.h>
+#include <stdlib.h>
+
+#if defined(__WINDOWS__) && !defined(__WIN32__)
+#include <print.h>
+#endif
+
+HENV wxDatabase::hEnv = 0;
+int wxDatabase::refCount = 0;
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxDatabase, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxQueryCol, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxQueryField, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxRecordSet, wxObject)
+#endif
+
+wxDatabase::wxDatabase(void)
+{
+  hDBC = 0;
+  username = NULL;
+  password = NULL;
+  datasource = NULL;
+  dbname = NULL;
+  connectstring = NULL;
+  isOpen = FALSE;
+  refCount ++;
+  retcode = 0;
+  username = NULL;
+  password = NULL;
+  err_occured = FALSE;
+
+  memset(sqlstate, 0, sizeof sqlstate);
+  memset(errmsg, 0, sizeof errmsg);
+  
+  if (hEnv == 0)
+  {
+    retcode = SQLAllocEnv(&hEnv);
+
+    if (retcode != SQL_SUCCESS)
+      hEnv = 0;
+  }
+}
+
+wxDatabase::~wxDatabase(void)
+{
+  Close();
+  DeleteRecordSets(); // Added JACS
+
+  if (connectstring)
+    delete[] connectstring;
+  if (datasource)
+    delete[] datasource;
+  if (username)
+    delete[] username;
+  if (password)
+    delete[] password;
+  if (dbname)
+    delete[] dbname;
+  
+  refCount --;
+  if (!refCount && hEnv)
+  {
+    retcode = SQLFreeEnv(hEnv);
+    hEnv = 0; // JACS 17/6
+  }
+}
+
+void wxDatabase::ErrorSnapshot(HSTMT hstmt)
+{
+  SWORD len = 0; // JACS: sometimes doesn't get filled in by SQLError.
+  
+  err_occured = TRUE;
+  SQLError(hEnv, hDBC, hstmt, (unsigned char *)sqlstate, &nat_err, (unsigned char *)errmsg, SQL_MAX_MESSAGE_LENGTH-1, &len);
+  errmsg[len] = '\0';
+}
+
+bool wxDatabase::ErrorOccured(void) 
+{
+  return err_occured;
+}
+
+char* wxDatabase::GetErrorMessage(void)
+{
+  return errmsg;
+}
+
+long wxDatabase::GetErrorNumber(void) 
+{
+  return nat_err;
+}
+
+char* wxDatabase::GetErrorClass(void) {
+  return sqlstate;
+}
+
+bool wxDatabase::Open(char *thedatasource, bool exclusive, bool readOnly, char *username, char *password)
+{
+  err_occured = FALSE;
+  
+  if (isOpen)
+    return FALSE;
+  
+  SetUsername(username);
+  SetPassword(password);
+  SetDataSource(thedatasource);
+  
+  if (!hEnv)
+    return FALSE;
+
+  retcode = SQLAllocConnect(hEnv, &hDBC);
+  if (retcode != SQL_SUCCESS) {
+    hDBC = 0;
+    return FALSE;
+  }
+  
+  retcode = SQLConnect(hDBC, (UCHAR FAR*)thedatasource, strlen(thedatasource), (UCHAR FAR*)username, strlen(username),
+		       (UCHAR FAR*)password, strlen(password));
+  
+  if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
+    ErrorSnapshot();
+    return FALSE;
+  }
+
+  isOpen = TRUE;
+  
+  return TRUE;
+}
+
+bool wxDatabase::Close(void)
+{
+  // JACS: make sure the record set statements are all released.
+  ResetRecordSets();
+  
+  err_occured = FALSE;
+  if (hDBC != 0)
+  {
+    retcode = SQLDisconnect(hDBC);
+
+    if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
+      ErrorSnapshot();      
+      return FALSE;
+    }
+
+    retcode = SQLFreeConnect(hDBC);
+
+    hDBC = 0;
+    isOpen = FALSE;
+    
+    return TRUE;
+  }
+  
+  return FALSE;
+}
+
+// Database attributes
+char *wxDatabase::GetDatabaseName(void)
+{
+  err_occured = FALSE;
+  if (hDBC == 0)
+    return NULL;
+    
+  char nameBuf[400];
+  int nameSize = 0;
+
+  retcode = SQLGetInfo(hDBC, SQL_DATABASE_NAME, nameBuf, sizeof(nameBuf), (short *)&nameSize);
+
+  if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
+    return NULL;
+
+  delete[] dbname;
+  dbname = NULL;
+  
+  if (nameSize > 0)
+  {
+    dbname = copystring(nameBuf);
+    return dbname;
+  }
+  else
+    return NULL;
+}
+  
+bool wxDatabase::CanUpdate(void)
+{
+  return FALSE;
+}
+
+bool wxDatabase::CanTransact(void)
+{
+  return FALSE;
+}
+
+bool wxDatabase::InWaitForDataSource(void)
+{
+  return FALSE;
+}
+
+void wxDatabase::SetLoginTimeout(long seconds)
+{
+}
+
+void wxDatabase::SetQueryTimeout(long seconds)
+{
+}
+
+void wxDatabase::SetSynchronousMode(bool synchronous)
+{
+}
+
+// Database operations
+bool wxDatabase::BeginTrans(void)
+{
+  return FALSE;
+}
+
+bool wxDatabase::CommitTrans(void)
+{
+  return FALSE;
+}
+
+bool wxDatabase::RollbackTrans(void)
+{
+  return FALSE;
+}
+
+void wxDatabase::Cancel(void)
+{
+}
+
+// Overridables
+void wxDatabase::OnSetOptions(wxRecordSet *recordSet)
+{
+}
+
+void wxDatabase::OnWaitForDataSource(bool stillExecuting)
+{
+}
+
+void wxDatabase::SetPassword(char *s)
+{
+  if (password)
+    delete[] password;
+  if (s)
+  {
+    password = copystring(s);
+  }
+  else
+    password = NULL;
+}
+
+void wxDatabase::SetUsername(char *s)
+{
+  delete[] username;
+  
+  if (s)
+    username = copystring(s);
+  else
+    username = NULL;
+}
+
+void wxDatabase::SetDataSource(char *s)
+{
+  delete[] datasource;
+  
+  if (s)
+    datasource = copystring(s);
+  else
+    datasource = NULL;
+}
+
+/*
+ * Added by JACS
+ */
+
+void wxDatabase::DeleteRecordSets(void)
+{
+  wxNode *node = recordSets.First();
+  while (node)
+  {
+    wxNode *next = node->Next();
+    wxRecordSet *rec = (wxRecordSet *)node->Data();
+    delete rec;
+    // The node is implicitly deleted by ~wxRecordSet
+    node = next;
+  }
+}
+
+void wxDatabase::ResetRecordSets(void)
+{
+  wxNode *node = recordSets.First();
+  while (node)
+  {
+    wxRecordSet *rec = (wxRecordSet *)node->Data();
+    rec->ReleaseHandle();
+
+    node = node->Next();
+  }
+}
+
+bool wxDatabase::GetInfo(long infoType, long *buf)
+{
+  short sz = 0;
+  retcode = SQLGetInfo(hDBC, (UWORD)infoType, (char *)buf, sizeof(buf), &sz);
+  
+  if (retcode != SQL_ERROR)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+bool wxDatabase::GetInfo(long infoType, char *buf, int bufSize)
+{
+  if (bufSize == -1)
+    bufSize = sizeof(buf);
+    
+  short sz = 0;
+  retcode = SQLGetInfo(hDBC, (UWORD)infoType, buf, bufSize, &sz);
+  
+  if (retcode != SQL_ERROR)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+wxString wxDatabase::GetODBCVersionString(bool implementation)
+{
+  char buf[50];
+  if (!implementation)
+  {
+#ifdef SQL_SPEC_MAJOR
+    sprintf(buf, "%d%d.%d", (int)(SQL_SPEC_MAJOR/10), (int)(SQL_SPEC_MAJOR - (((int)(SQL_SPEC_MAJOR/10))*10)),
+             SQL_SPEC_MINOR);
+    return wxString(buf);
+#else
+    return wxString("00.00");
+#endif
+  }
+  
+  bool noDBC = FALSE;
+  if (hDBC == 0)
+  {
+    noDBC = TRUE;
+    retcode = SQLAllocConnect(hEnv, &hDBC);
+    if (retcode != SQL_SUCCESS)
+    {
+      hDBC = 0;
+      return wxString("00.00");
+    }
+  }
+
+  int bufSize = sizeof(buf);
+    
+  short sz = 0;
+  retcode = SQLGetInfo(hDBC, (UWORD)SQL_ODBC_VER, buf, bufSize, &sz);
+  
+  if (hDBC != 0 && noDBC)
+  {
+    retcode = SQLFreeConnect(hDBC);
+    hDBC = 0;
+  }
+
+  if (retcode == SQL_ERROR)
+    return wxString("");
+  else
+    return wxString(buf);
+}
+
+float wxDatabase::GetODBCVersionFloat(bool implementation)
+{
+  if (!implementation)
+  {
+#ifdef SQL_SPEC_MAJOR
+    return (float)(SQL_SPEC_MAJOR + (SQL_SPEC_MINOR/100.0));
+#else
+    return 0.0;
+#endif
+  }
+
+  bool noDBC = FALSE;
+  if (hDBC == 0)
+  {
+    noDBC = TRUE;
+    retcode = SQLAllocConnect(hEnv, &hDBC);
+    if (retcode != SQL_SUCCESS)
+    {
+      hDBC = 0;
+      return (float)0.0;
+    }
+  }
+
+  char buf[50];
+  int bufSize = sizeof(buf);
+ 
+  short sz = 0;
+  retcode = SQLGetInfo(hDBC, (UWORD)SQL_ODBC_VER, buf, bufSize, &sz);
+
+  if (hDBC != 0 && noDBC)
+  {
+    retcode = SQLFreeConnect(hDBC);
+    hDBC = 0;
+  }
+
+  if (retcode == SQL_ERROR)
+    return 0.0;
+  else
+    return atof(buf);
+}
+
+/*
+ * wxRecordSet
+ */
+ 
+wxRecordSet::wxRecordSet(wxDatabase *db, int typ, int opt):
+    cols(wxKEY_STRING)
+{
+  parentdb = db;
+  hStmt = 0;
+  nFields = 0;
+  nParams = 0;
+  recordFilter = NULL;
+  sortString = NULL;
+  retcode = 0;
+  cursor = 0;
+  tablename = NULL;
+  nCols = 0;
+  nRecords = 0;
+  
+  type = typ;
+  options = opt;
+
+  // Added JACS
+  if (parentdb)
+    parentdb->GetRecordSets().Append(this);
+}
+
+wxRecordSet::~wxRecordSet(void)
+{
+  ReleaseHandle();
+  
+  // JACS
+  if (parentdb)
+    parentdb->GetRecordSets().DeleteObject(this);
+    
+  if (recordFilter)
+    delete[] recordFilter;
+  if (sortString)
+    delete[] sortString;
+  if (tablename)
+    delete[] tablename;
+}
+
+// If SQL is non-NULL, table and columns can be NULL.
+bool wxRecordSet::BeginQuery(int openType, char *sql, int options)
+{
+  // Needs to construct an appropriate SQL statement. By default
+  // (i.e. if table and columns are provided) then
+  // SELECT <columns> FROM <table>
+  // will be used.
+  if (!parentdb)
+    return FALSE;
+  if (!parentdb->GetHDBC())
+    return FALSE;
+    
+  if (hStmt)
+  {
+    retcode = SQLFreeStmt(hStmt, SQL_DROP);
+    if (retcode == SQL_ERROR)
+    {
+      parentdb->ErrorSnapshot(hStmt);
+      return FALSE;
+    }
+    hStmt = 0;
+  }
+
+  retcode = SQLAllocStmt(parentdb->GetHDBC(), &hStmt);
+  if (retcode != SQL_SUCCESS)
+    return FALSE;
+
+  return TRUE;
+}
+
+bool wxRecordSet::Query(char *columns, char *table, char *filter)
+{
+  // Needs to construct an appropriate SQL statement. By default
+  // (i.e. if table and columns are provided) then
+  // SELECT <columns> FROM <table>
+  // will be used.
+
+  char* thetable = table ? table : tablename;
+  
+  if (!thetable)
+    return FALSE;
+  if (!columns)
+    return FALSE;
+    
+  wxString query;
+
+  query += "SELECT ";
+  query += columns;
+  query += " FROM ";
+  query += thetable;
+
+  if (filter)  {
+    query += " WHERE ";
+    query += filter;
+  }
+  retcode = SQLPrepare(hStmt, (UCHAR FAR *)query.GetData(), strlen(query.GetData()));
+  if (retcode != SQL_SUCCESS) {
+    parentdb->ErrorSnapshot(hStmt);
+    return FALSE;
+  }
+
+  retcode = SQLExecute(hStmt);
+
+  if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
+    parentdb->ErrorSnapshot(hStmt);
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+bool wxRecordSet::EndQuery(void)
+{
+  return TRUE;
+}
+
+void wxRecordSet::FillVars(int recnum) {
+  wxNode* node = cols.First();
+  
+  do {
+    ((wxQueryCol*)node->Data())->FillVar(recnum);
+  } while (node = node->Next());
+}
+
+bool wxRecordSet::GetResultSet(void)
+{
+//  long trash = SQL_NULL_DATA; // value added by JACS
+  long trash;
+               // contains the number of bytes transferred by SQLFetch()
+               // who needs this ?
+  wxNode *currow, *fetch, *curcol;
+  
+  retcode = SQLNumResultCols(hStmt, &nCols);
+
+  if (!nCols)
+    return TRUE;
+  
+  // delete old data first
+  cols.DeleteContents(TRUE);
+  cols.Clear();
+  fetchbuf.DeleteContents(TRUE);
+  fetchbuf.Clear();
+  
+  nRecords = 0;
+  cursor = 0;
+
+  int i;
+  for (i=0; i<nCols; i++) {
+    char name[512];
+    short type, scale, nullable, namelen;
+    unsigned long len;
+    
+    retcode = SQLDescribeCol(hStmt, i+1, (unsigned char *)name, 511, &namelen, &type, &len, &scale, &nullable);
+    if (SQL_SUCCESS != retcode && SQL_SUCCESS_WITH_INFO != retcode)  {
+      parentdb->ErrorSnapshot(hStmt);
+      return FALSE;
+    }
+
+    wxQueryCol *col1 = new wxQueryCol;
+    curcol = cols.Append(name, col1);
+    col1->SetName(name);
+    col1->SetType(type);
+    col1->SetNullable(nullable);
+
+    wxQueryField *field1 = new wxQueryField;
+    fetch = fetchbuf.Append(field1);
+    field1->SetType(type);
+    field1->SetSize(len);
+    
+    SQLBindCol(hStmt, i+1, SQL_C_BINARY, field1->GetData(), field1->GetSize(), &trash);
+  }
+  
+  switch (type) {
+    case wxOPEN_TYPE_SNAPSHOT:
+    // get it all !
+    // After we've done an SQLFetch, copy the data in the fetch buffer into
+    // new fields, for each column.
+    while (SQL_SUCCESS == (retcode = SQLFetch(hStmt)) || SQL_SUCCESS_WITH_INFO == retcode) {
+      nRecords++;
+      
+      curcol = cols.First();
+      fetch = fetchbuf.First();
+      for (i=0; i<nCols; i++) {
+
+        wxQueryField *fetchField = (wxQueryField *)fetch->Data();
+        wxQueryCol *col = (wxQueryCol *)curcol->Data();
+        wxQueryField *field = new wxQueryField;
+
+	currow = col->fields.Append(field);
+	
+	field->SetType(fetchField->GetType());
+	field->SetData(fetchField->GetData(), fetchField->GetSize());
+        curcol = curcol->Next();
+        fetchField->ClearData(); // Runs ok if this commented out and SetData commented out
+	fetch = fetch->Next();
+      }
+    }
+    // while loop should only be left, when no more data was found;
+    // otherwise it seems, that there was an error
+    if (SQL_NO_DATA_FOUND != retcode) {
+      parentdb->ErrorSnapshot(hStmt);
+      return FALSE;
+    }
+    break;
+    case wxOPEN_TYPE_DYNASET:
+    // get first record only
+    if (SQL_SUCCESS == (retcode = SQLFetch(hStmt)) || retcode == SQL_SUCCESS_WITH_INFO) {
+      nRecords = 1;  // TO DO! # of records in the ODBC result set should be set here.
+      
+      curcol = cols.First();
+      fetch = fetchbuf.First();
+      for (i=0; i<nCols; i++) {
+	currow = ((wxQueryCol*)curcol->Data())->fields.Append(new wxQueryField);
+	
+	((wxQueryField*)currow->Data())->SetType(((wxQueryField*)fetch->Data())->GetType());
+	((wxQueryField*)currow->Data())->SetData(((wxQueryField*)fetch->Data())->GetData(), ((wxQueryField*)fetch->Data())->GetSize());
+        curcol = curcol->Next();
+        ((wxQueryField*)fetch->Data())->ClearData();
+	fetch = fetch->Next();
+      }
+    }
+    if (SQL_NO_DATA_FOUND != retcode) {
+      parentdb->ErrorSnapshot(hStmt);
+      return FALSE;
+    }
+    break;
+    default:
+    return FALSE;
+  }
+
+  FillVars(0);
+  
+  return TRUE;
+}
+
+bool wxRecordSet::ExecuteSQL(char *sql)
+{
+  if (hStmt)
+  {
+    retcode = SQLFreeStmt(hStmt, SQL_DROP);
+    if (retcode == SQL_ERROR)
+    {
+      parentdb->ErrorSnapshot(hStmt);
+      return FALSE;
+    }
+    hStmt = NULL;
+  }
+  
+  retcode = SQLAllocStmt(parentdb->GetHDBC(), &hStmt);
+  
+  if (SQL_SUCCESS != retcode) {
+    parentdb->ErrorSnapshot(hStmt);
+    return FALSE;
+  }
+
+  retcode = SQLExecDirect(hStmt, (UCHAR FAR*)sql, SQL_NTS);
+  
+  if (SQL_SUCCESS != retcode && SQL_SUCCESS_WITH_INFO != retcode)  {
+    parentdb->ErrorSnapshot(hStmt);
+    return FALSE;
+  }
+
+  return GetResultSet();
+}
+
+bool wxRecordSet::GetDataSources(void) {
+
+  char *dsname = "Name", *dsdesc = "Description";
+  char namebuf[64];
+  char descbuf[512];
+  short namelen, desclen;
+  
+  cursor = 0;
+  
+  // delete old data first
+  cols.DeleteContents(TRUE);
+  cols.Clear();
+  nRecords = 0;
+
+  // JACS This is a snapshot, not a dynaset.
+  type = wxOPEN_TYPE_SNAPSHOT;
+  
+  wxNode *namecol, *desccol;
+  
+  namecol = cols.Append(dsname, new wxQueryCol);
+  ((wxQueryCol*)namecol->Data())->SetName(dsname);
+  ((wxQueryCol*)namecol->Data())->SetType(SQL_CHAR);
+  desccol = cols.Append(dsdesc, new wxQueryCol);
+  ((wxQueryCol*)desccol->Data())->SetName(dsdesc);
+  ((wxQueryCol*)desccol->Data())->SetType(SQL_CHAR);
+  
+  retcode = SQLDataSources(parentdb->GetHENV(), SQL_FETCH_FIRST, (unsigned char *)namebuf, 63, &namelen, (unsigned char *)descbuf, 511, &desclen);
+  while (SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode) {
+    nRecords++;
+    ((wxQueryCol*)namecol->Data())->AppendField(namebuf, namelen);
+    ((wxQueryCol*)desccol->Data())->AppendField(descbuf, desclen);
+    retcode = SQLDataSources(parentdb->GetHENV(), SQL_FETCH_NEXT, (unsigned char *)namebuf, 63, &namelen, (unsigned char *)descbuf, 511, &desclen);
+  }
+
+  if (SQL_SUCCESS != retcode && SQL_SUCCESS_WITH_INFO != retcode && SQL_NO_DATA_FOUND != retcode)  {
+    parentdb->ErrorSnapshot();
+    return FALSE;
+  }
+
+  cursor = 0;
+  
+  return TRUE;
+}
+
+// Attributes
+void wxRecordSet::SetTableName(char* name) {
+  delete[] tablename;
+  tablename = NULL;
+  
+  if (name)
+    tablename = copystring(name);
+}
+
+bool wxRecordSet::GetTables(void)
+{
+  if (hStmt)
+  {
+    retcode = SQLFreeStmt(hStmt, SQL_DROP);
+    if (retcode == SQL_ERROR)
+    {
+      parentdb->ErrorSnapshot(hStmt);
+      return FALSE;
+    }
+      
+    hStmt = NULL;
+  }
+  
+  retcode = SQLAllocStmt(parentdb->GetHDBC(), &hStmt);
+  
+  if (SQL_SUCCESS != retcode) {
+    parentdb->ErrorSnapshot();
+    return FALSE;
+  }
+
+  retcode = SQLTables(hStmt, NULL, 0, NULL, 0, NULL, 0, NULL, 0);
+  
+  if (SQL_SUCCESS != retcode && SQL_SUCCESS_WITH_INFO != retcode)  {
+    parentdb->ErrorSnapshot(hStmt);
+    return FALSE;
+  }
+
+  return GetResultSet();
+}
+
+bool wxRecordSet::GetColumns(char* table)
+{
+  char* name=NULL;
+  char* wildcard = "%";
+
+  name = table ? table : tablename;
+  
+  if (!name)
+    return FALSE;
+
+  if (hStmt)
+  {
+    retcode = SQLFreeStmt(hStmt, SQL_DROP);
+    if (retcode == SQL_ERROR)
+    {
+      parentdb->ErrorSnapshot(hStmt);
+      return FALSE;
+    }
+    hStmt = NULL;
+  }
+  
+  retcode = SQLAllocStmt(parentdb->GetHDBC(), &hStmt);
+  
+  if (SQL_SUCCESS != retcode) {
+    parentdb->ErrorSnapshot();
+    return FALSE;
+  }
+
+  //retcode = SQLColumns(hstmt, (unsigned char*)parentdb->GetDataSource(), strlen(parentdb->GetDataSource()), wildcard, 1, name, strlen(name), wildcard, 1);
+  retcode = SQLColumns(hStmt, NULL, 0, NULL, 0, (unsigned char *)name, strlen(name), NULL, 0);
+  
+  if (SQL_SUCCESS != retcode && SQL_SUCCESS_WITH_INFO != retcode)  {
+    parentdb->ErrorSnapshot(hStmt);
+    return FALSE;
+  }
+
+  return GetResultSet();
+}
+
+// It is derived from previous GetColumns
+bool wxRecordSet::GetPrimaryKeys(char* table)
+{
+  char* name=NULL;
+  char* wildcard = "%";
+
+  name = table ? table : tablename;
+  
+  if (!name)
+    return FALSE;
+
+  if (hStmt)
+  {
+    retcode = SQLFreeStmt(hStmt, SQL_DROP);
+    if (retcode == SQL_ERROR)
+    {
+      parentdb->ErrorSnapshot(hStmt);
+      return FALSE;
+    }
+    hStmt = NULL;
+  }
+  
+  retcode = SQLAllocStmt(parentdb->GetHDBC(), &hStmt);
+  
+  if (SQL_SUCCESS != retcode) {
+    parentdb->ErrorSnapshot();
+    return FALSE;
+  }
+
+  retcode = SQLPrimaryKeys(hStmt, NULL, 0, NULL, 0, (unsigned char *)name, SQL_NTS);  
+
+  if (SQL_SUCCESS != retcode && SQL_SUCCESS_WITH_INFO != retcode)  {
+    parentdb->ErrorSnapshot(hStmt);
+    return FALSE;
+  }
+
+  return GetResultSet();
+}
+
+bool wxRecordSet::GetForeignKeys(char* PkTableName, char * FkTableName)
+{
+  char* Pkname=NULL;
+  char* Fkname=NULL;
+  char* wildcard = "%";
+
+// Try to disable situation: both PkTableName and FkTableName are NULL 
+//   set Pkname from tablename
+  if( !PkTableName && !FkTableName ) {
+     Pkname = PkTableName ? PkTableName : tablename;
+     Fkname = FkTableName ;
+     if (!Pkname )
+       return FALSE;
+  } else {
+     Pkname = PkTableName ;
+     Fkname = FkTableName ;
+  }
+
+  if (hStmt)
+  {
+    retcode = SQLFreeStmt(hStmt, SQL_DROP);
+    if (retcode == SQL_ERROR)
+    {
+      parentdb->ErrorSnapshot(hStmt);
+      return FALSE;
+    }
+    hStmt = NULL;
+  }
+  
+  retcode = SQLAllocStmt(parentdb->GetHDBC(), &hStmt);
+  
+  if (SQL_SUCCESS != retcode) {
+    parentdb->ErrorSnapshot();
+    return FALSE;
+  }
+
+  retcode = SQLForeignKeys(hStmt, NULL, 0, NULL, 0, (unsigned char *)Pkname,
+    (Pkname ? SQL_NTS : 0), NULL, 0, NULL, 0, (unsigned char *)Fkname ,(Fkname ?SQL_NTS : 0) );  
+
+  if (SQL_SUCCESS != retcode && SQL_SUCCESS_WITH_INFO != retcode)  {
+    parentdb->ErrorSnapshot(hStmt);
+    return FALSE;
+  }
+
+  return GetResultSet();
+}
+
+long wxRecordSet::GetNumberRecords(void) 
+{
+  return nRecords;
+}
+
+long wxRecordSet::GetNumberCols(void)
+{
+  return nCols;
+}
+
+char* wxRecordSet::GetColName(int col)
+{
+  wxNode* node = cols.Nth(col);
+    
+  if (!node)
+    return NULL;
+    
+  return ((wxQueryCol*)node->Data())->GetName();
+}
+
+short wxRecordSet::GetColType(int col)
+{
+  wxNode* node = cols.Nth(col);
+    
+  if (!node)
+    return SQL_TYPE_NULL;
+    
+  return ((wxQueryCol*)node->Data())->GetType();
+}
+
+short wxRecordSet::GetColType(const char *col)
+{
+  wxNode* node = cols.Find(col);
+    
+  if (!node)
+    return SQL_TYPE_NULL;
+    
+  return ((wxQueryCol*)node->Data())->GetType();
+}
+
+bool wxRecordSet::GetFieldData(int col, int type, void* data)
+{
+  wxNode* node = cols.Nth(col);
+
+  if (!node)
+    return FALSE;
+  
+  if (((wxQueryCol*)node->Data())->GetType() != type)
+    return FALSE;
+
+  void* src = ((wxQueryCol*)node->Data())->GetData(cursor);
+
+  if (!src)
+    return FALSE;
+  
+  memcpy(data, src, ((wxQueryCol*)node->Data())->GetSize(cursor));
+  
+  return TRUE;
+}
+
+bool wxRecordSet::GetFieldData(const char* name, int type, void *data)
+{
+  wxNode* node = cols.Find(name);
+
+  if (!node)
+    return FALSE;
+  
+  if (((wxQueryCol*)node->Data())->GetType() != type)
+    return FALSE;
+
+  void* src = ((wxQueryCol*)node->Data())->GetData(cursor);
+
+  if (!src)
+    return FALSE;
+  
+  memcpy(data, src, ((wxQueryCol*)node->Data())->GetSize(cursor));
+  
+  return TRUE;
+}
+
+void* wxRecordSet::GetFieldDataPtr(int col, int type)
+{
+  wxNode* node = cols.Nth(col);
+
+  if (!node)
+    return NULL;
+  
+  if (((wxQueryCol*)node->Data())->GetType() != type)
+    return NULL;
+
+  return ((wxQueryCol*)node->Data())->GetData(cursor);
+}
+
+void* wxRecordSet::GetFieldDataPtr(const char* name, int type)
+{
+  wxNode* node = cols.Find(name);
+
+  if (!node)
+    return NULL;
+  
+  if (((wxQueryCol*)node->Data())->GetType() != type)
+    return NULL;
+
+  return ((wxQueryCol*)node->Data())->GetData(cursor);
+}
+
+void* wxRecordSet::BindVar(int col, void* var, long size) {
+  wxNode* node = cols.Nth(col);
+  
+  if (!node)
+    return NULL;
+  
+  return ((wxQueryCol*)node->Data())->BindVar(var, size);
+}
+
+void* wxRecordSet::BindVar(const char* name, void* var, long size) {
+  wxNode* node = cols.Find(name);
+  
+  if (!node)
+    return NULL;
+  
+  return ((wxQueryCol*)node->Data())->BindVar(var, size);
+}
+
+void wxRecordSet::SetType(int typ) {
+  type = typ;
+}
+
+int wxRecordSet::GetType(void) {
+  return type;
+}
+
+void wxRecordSet::SetOptions(int opts) {
+  options = opts;
+}
+
+int wxRecordSet::GetOptions(void) {
+  return options;
+}
+
+bool wxRecordSet::CanAppend(void)
+{
+  return FALSE;
+}
+
+bool wxRecordSet::CanRestart(void)
+{
+  return FALSE;
+}
+
+bool wxRecordSet::CanScroll(void)
+{
+  return FALSE;
+}
+
+bool wxRecordSet::CanTransact(void)
+{
+  return FALSE;
+}
+
+bool wxRecordSet::CanUpdate(void)
+{
+  return FALSE;
+}
+
+long wxRecordSet::GetCurrentRecord(void)
+{
+  return -1L;
+}
+
+bool wxRecordSet::RecordCountFinal(void)
+{
+  return FALSE;
+}
+
+char* wxRecordSet::GetTableName(void)
+{
+  return tablename;
+}
+
+char *wxRecordSet::GetSQL(void)
+{
+  return NULL;
+}
+
+bool wxRecordSet::IsOpen(void)
+{
+  return parentdb->IsOpen();
+}
+
+bool wxRecordSet::IsBOF(void)
+{
+  return cursor < 0;
+}
+
+bool wxRecordSet::IsEOF(void)
+{
+  return cursor >= nRecords;
+}
+
+bool wxRecordSet::IsDeleted(void)
+{
+  return FALSE;
+}
+
+// Update operations
+void wxRecordSet::AddNew(void)
+{
+}
+
+bool wxRecordSet::Delete(void)
+{
+  return FALSE;
+}
+
+void wxRecordSet::Edit(void)
+{
+}
+
+bool wxRecordSet::Update(void)
+{
+  return FALSE;
+}
+
+// Record navigation
+bool wxRecordSet::Move(long rows)
+{
+  if (!nRecords) {
+    cursor = -1;
+    return FALSE;
+  }
+  
+  switch (type) {
+    case wxOPEN_TYPE_SNAPSHOT:
+    cursor += (int)rows;
+    if (cursor < 0) {
+      cursor = -1;
+      return FALSE;
+    }
+    if (cursor > nRecords-1) {
+      cursor = nRecords;
+      return FALSE;
+    }
+    return TRUE;
+      
+    case wxOPEN_TYPE_DYNASET:
+    return FALSE;
+    default:
+    return FALSE;
+  }
+}
+
+bool wxRecordSet::GoTo(long row)
+{
+  if (!nRecords) {
+    cursor = -1;
+    return FALSE;
+  }
+  
+  switch (type) {
+    case wxOPEN_TYPE_SNAPSHOT:
+    cursor = (int)row;
+    if (cursor < 0) {
+      cursor = -1;
+      return FALSE;
+    }
+    if (cursor > nRecords-1) {
+      cursor = nRecords;
+      return FALSE;
+    }
+    return TRUE;
+      
+    case wxOPEN_TYPE_DYNASET:
+    return FALSE;
+    default:
+    return FALSE;
+  }
+}
+
+bool wxRecordSet::MoveFirst(void)
+{
+  if (!nRecords) {
+    cursor = -1;
+    return FALSE;
+  }
+  
+  switch (type) {
+    case wxOPEN_TYPE_SNAPSHOT:
+    cursor = 0;
+    return TRUE;
+    
+    case wxOPEN_TYPE_DYNASET:
+    return FALSE;
+    default:
+    return FALSE;
+  }
+}
+
+bool wxRecordSet::MoveLast(void)
+{
+  if (!nRecords) {
+    cursor = -1;
+    return FALSE;
+  }
+  
+  switch (type) {
+    case wxOPEN_TYPE_SNAPSHOT:
+    cursor = nRecords-1;
+    return TRUE;
+    
+    case wxOPEN_TYPE_DYNASET:
+    return FALSE;
+    default:
+    return FALSE;
+  }
+}
+
+bool wxRecordSet::MoveNext(void)
+{
+  if (!nRecords) {
+    cursor = -1;
+    return FALSE;
+  }
+  
+  switch (type) {
+    case wxOPEN_TYPE_SNAPSHOT:
+    cursor++;
+    if (cursor >= nRecords) {
+      cursor = nRecords;
+      return FALSE;
+    }
+    return TRUE;
+    
+    case wxOPEN_TYPE_DYNASET:
+    return FALSE;
+    default:
+    return FALSE;
+  }
+}
+
+bool wxRecordSet::MovePrev(void)
+{
+  if (!nRecords) {
+    cursor = -1;
+    return FALSE;
+  }
+  
+  switch (type) {
+    case wxOPEN_TYPE_SNAPSHOT:
+    cursor--;
+    if (cursor < 0) {
+      cursor = 0;
+      return FALSE;
+    }
+    return TRUE;
+
+    case wxOPEN_TYPE_DYNASET:
+    return FALSE;
+    default:
+    return FALSE;
+  }
+}
+
+// Others
+void wxRecordSet::Cancel(void)
+{
+}
+
+bool wxRecordSet::IsFieldDirty(int col)
+{
+  wxNode* node = cols.Nth(col);
+    
+  if (!node)
+    return FALSE;
+    
+  return ((wxQueryCol*)node->Data())->IsFieldDirty(cursor);
+}
+
+bool wxRecordSet::IsFieldDirty(const char* name)
+{
+  wxNode* node = cols.Find(name);
+    
+  if (!node)
+    return FALSE;
+    
+  return ((wxQueryCol*)node->Data())->IsFieldDirty(cursor);
+}
+
+bool wxRecordSet::IsFieldNull(int col)
+{
+  wxNode* node = cols.Nth(col);
+    
+  if (!node)
+    return TRUE;
+    
+  return NULL != ((wxQueryCol*)node->Data())->GetData(cursor);
+}
+
+bool wxRecordSet::IsFieldNull(const char* name)
+{
+  wxNode* node = cols.Find(name);
+    
+  if (!node)
+    return TRUE;
+    
+  return NULL != ((wxQueryCol*)node->Data())->GetData(cursor);
+}
+
+bool wxRecordSet::IsColNullable(int col)
+{
+  wxNode* node = cols.Nth(col);
+    
+  if (!node)
+    return FALSE;
+    
+  return ((wxQueryCol*)node->Data())->IsNullable();
+}
+
+bool wxRecordSet::IsColNullable(const char* name)
+{
+  wxNode* node = cols.Find(name);
+    
+  if (!node)
+    return FALSE;
+    
+  return ((wxQueryCol*)node->Data())->IsNullable();
+}
+
+bool wxRecordSet::Requery(void)
+{
+  return FALSE;
+}
+
+void wxRecordSet::SetFieldDirty(int col, bool dirty)
+{
+  wxNode* node = cols.Nth(col);
+    
+  if (!node)
+    return;
+    
+  ((wxQueryCol*)node->Data())->SetFieldDirty(cursor, dirty);
+}
+
+void wxRecordSet::SetFieldDirty(const char* name, bool dirty)
+{
+  wxNode* node = cols.Find(name);
+    
+  if (!node)
+    return;
+    
+  ((wxQueryCol*)node->Data())->SetFieldDirty(cursor, dirty);
+}
+
+void wxRecordSet::SetFieldNull(void *p, bool isNull)
+{
+}
+   
+// Overridables
+char *wxRecordSet::GetDefaultConnect(void)
+{
+  return NULL;
+}
+
+char *wxRecordSet::GetDefaultSQL(void)
+{
+  return NULL;
+}
+
+void wxRecordSet::SetDefaultSQL(char *s)
+{
+  delete[] defaultSQL;
+  
+  if (s)
+    defaultSQL = copystring(s);
+  else
+    defaultSQL = NULL;
+}
+
+// Build SQL query from column specification
+bool wxRecordSet::ConstructDefaultSQL(void)
+{
+//  if (queryCols.Number() == 0)
+    return FALSE;
+}
+
+bool wxRecordSet::ReleaseHandle(void)
+{
+  if (hStmt)
+  {
+    retcode = SQLFreeStmt(hStmt, SQL_DROP);
+    if (retcode == SQL_ERROR)
+    {
+      if (parentdb)
+        parentdb->ErrorSnapshot(hStmt);
+      return FALSE;
+    }
+    hStmt = 0;
+  }
+  return TRUE;
+}
+
+wxQueryCol::wxQueryCol(void) {
+//  __type = wxTYPE_QUERYCOL;
+  name = NULL;
+  type = SQL_TYPE_NULL;
+  nullable = FALSE;
+  var = NULL;
+  varsize = 0;
+}
+
+wxQueryCol::~wxQueryCol(void) {
+  // delete all data
+  fields.DeleteContents(TRUE);
+  fields.Clear();
+
+  if (name)
+    delete[] name;
+}
+
+void wxQueryCol::SetName(char* n) {
+  name = new char[strlen(n)+1];
+  strcpy(name, n);
+}
+
+bool wxQueryCol::SetData(int row, void* buf, long len) {
+  wxNode* node = fields.Nth(row);
+  
+  if (!node)
+    return FALSE;
+  
+  return ((wxQueryField*)node->Data())->SetData(buf, len);
+}
+
+void wxQueryCol::SetFieldDirty(int row, bool dirty) {
+  wxNode* node = fields.Nth(row);
+  
+  if (!node)
+    return;
+  
+  ((wxQueryField*)node->Data())->SetDirty(dirty);
+}
+
+void wxQueryCol::AppendField(void* buf, long len) {
+  wxNode* node = fields.Append(new wxQueryField);
+  ((wxQueryField*)node->Data())->SetType(type);
+  ((wxQueryField*)node->Data())->SetData(buf, len);
+}
+
+void wxQueryCol::SetType(short t) {
+  type = t;
+}
+
+void* wxQueryCol::BindVar(void* v, long s) {
+  void* oldvar = var;
+  
+  var = v;
+  varsize = s;
+  
+  return oldvar;
+}
+
+void wxQueryCol::FillVar(int recnum) {
+  if (!var)
+    return;
+  
+  wxNode* node = fields.Nth(recnum);
+  
+  if (!node)
+    return;
+
+  long actsize = ((wxQueryField*)node->Data())->GetSize();
+  if (actsize > varsize)
+    actsize = varsize;
+
+  memcpy(var, ((wxQueryField*)node->Data())->GetData(), actsize);
+}
+
+void wxQueryCol::SetNullable(bool n) {
+  nullable = n;
+}
+  
+char* wxQueryCol::GetName(void) {
+  return name;
+}
+
+short wxQueryCol::GetType(void)  {
+  return type;
+}
+
+bool wxQueryCol::IsNullable(void) {
+  return nullable;
+}
+
+
+bool wxQueryCol::IsFieldDirty(int row) {
+  wxNode* node = fields.Nth(row);
+  
+  if (!node)
+    return FALSE;
+  
+  return ((wxQueryField*)node->Data())->IsDirty();
+}
+
+void* wxQueryCol::GetData(int row) {
+  wxNode* node = fields.Nth(row);
+  
+  if (!node)
+    return NULL;
+  
+  return ((wxQueryField*)node->Data())->GetData();
+}
+
+long wxQueryCol::GetSize(int row) {
+  wxNode* node = fields.Nth(row);
+  
+  if (!node)
+    return NULL;
+  
+  return ((wxQueryField*)node->Data())->GetSize();
+}
+
+wxQueryField::wxQueryField(void) {
+//  __type = wxTYPE_QUERYROW;
+  data = NULL;
+  type = SQL_TYPE_NULL;
+  size = 0;
+  dirty = FALSE;
+}
+
+wxQueryField::~wxQueryField(void) {
+  switch (type)
+  {
+    case SQL_NUMERIC:
+    case SQL_DECIMAL:
+    case SQL_CHAR:
+    case SQL_VARCHAR:
+      if (data) // JACS
+        delete[] (char*)data;
+      break;
+    case SQL_INTEGER:
+      if (data) // JACS
+        delete (long*)data;
+      break;
+    case SQL_SMALLINT:
+      if (data)
+        delete (short*)data;
+      break;
+    case SQL_FLOAT:
+    case SQL_DOUBLE:
+      if (data)
+        delete (double*)data;
+      break;
+    case SQL_REAL:
+      if (data)
+        delete (float*)data;
+      break;
+    case SQL_TIME:
+      if (data)
+        delete (TIME_STRUCT *)data;
+      break;
+    case SQL_DATE:
+      if (data)
+        delete (DATE_STRUCT *)data;
+      break;
+    case SQL_TIMESTAMP:
+      if (data)
+        delete (TIMESTAMP_STRUCT *)data;
+      break;
+  }
+}
+
+bool wxQueryField::AllocData(void) {
+  switch (type)
+  {
+    case SQL_NUMERIC:
+    case SQL_DECIMAL:
+    case SQL_CHAR:
+    case SQL_VARCHAR:
+    {
+      if (data) // JACS
+        delete[] (char*)data;
+      if (data = new char[size+1])
+      {
+        char *str = (char *)data;
+        int i;
+        for (i = 0; i < size; i++)
+          str[i] = 0;
+//      memset(data, 0, size+1);
+      }
+      break;
+    }
+    case SQL_INTEGER:
+    {
+      if (data) // JACS
+        delete (long*)data;
+      if (data = new long)
+        *(long*)data = 0L;
+      break;
+    }
+    case SQL_SMALLINT:
+    {
+      if (data)
+        delete (short*)data;
+      if (data = new short)
+        *(short*)data = 0;
+      break;
+    }
+    case SQL_FLOAT:
+    case SQL_DOUBLE:
+    {
+      if (data)
+        delete (double*)data;
+      if (data = new double)
+        *(double*)data = 0;
+      break;
+    }
+    case SQL_REAL:
+    {
+      if (data)
+        delete (float*)data;
+      if (data = new float)
+        *(float*)data = (float)0;
+      break;
+    }
+    case SQL_TIME:
+    {
+      if (data)
+        delete (TIME_STRUCT *)data;
+      data = new TIME_STRUCT;
+      memset(data, 0, sizeof(TIME_STRUCT));
+      break;
+    }
+    case SQL_DATE:
+    {
+      if (data)
+        delete (DATE_STRUCT *)data;
+      data = new DATE_STRUCT;
+      memset(data, 0, sizeof(DATE_STRUCT));
+      break;
+    }
+    case SQL_TIMESTAMP:
+    {
+      if (data)
+        delete (TIMESTAMP_STRUCT *)data;
+      data = new TIMESTAMP_STRUCT;
+      memset(data, 0, sizeof(TIMESTAMP_STRUCT));
+      break;
+    }
+    default:
+      return FALSE;
+  }
+  
+  return TRUE;
+}
+
+bool wxQueryField::SetData(void* d, long s) {
+  size = s;
+  if (AllocData() && d)
+  {
+//    memcpy(data, d, s);
+    switch (type)
+    {
+      case SQL_NUMERIC:
+      case SQL_DECIMAL:
+      case SQL_CHAR:
+      case SQL_VARCHAR:
+      {
+        char *str = (char *)data;
+        int i;
+        for (i = 0; i < size; i++)
+          str[i] = 0;
+          
+        strncpy(str, (char *)d, (int)size);
+        str[size] = 0;
+        break;
+      }
+      case SQL_INTEGER:
+      {
+        *(long*)data = *((long *)d);
+        break;
+      }
+      case SQL_SMALLINT:
+      {
+        *(short*)data = *((short*)d);
+        break;
+      }
+      case SQL_FLOAT:
+      case SQL_DOUBLE:
+      {
+        *(double*)data = *((double*)d);
+        break;
+      }
+      case SQL_REAL:
+      {
+        *(float*)data = *((float*)d);
+        break;
+      }
+      case SQL_TIME:
+      {
+        *(TIME_STRUCT *)data = *((TIME_STRUCT*)d);
+        break;
+      }
+      case SQL_TIMESTAMP:
+      {
+        *(TIMESTAMP_STRUCT *)data = *((TIMESTAMP_STRUCT*)d);
+        break;
+      }
+      case SQL_DATE:
+      {
+        *(DATE_STRUCT *)data = *((DATE_STRUCT*)d);
+        break;
+      }
+      default:
+        return FALSE;
+    }
+    return TRUE;
+  }
+  return FALSE;
+}
+
+void wxQueryField::ClearData(void) {
+  if (data)
+  {
+  //    memset(data, 0, size);
+    switch (type)
+    {
+      case SQL_NUMERIC:
+      case SQL_DECIMAL:
+      case SQL_CHAR:
+      case SQL_VARCHAR:
+      {
+        char *str = (char *)data;
+        int i;
+        for (i = 0; i < size; i++)
+          str[i] = 0;
+        break;
+      }
+      case SQL_INTEGER:
+      {
+        *(long*)data = 0L;
+        break;
+      }
+      case SQL_SMALLINT:
+      {
+        *(short*)data = 0;
+        break;
+      }
+      case SQL_FLOAT:
+      case SQL_DOUBLE:
+      {
+        *(double*)data = (double)0.0;
+        break;
+      }
+      case SQL_REAL:
+      {
+        *(float*)data = (float)0.0;
+        break;
+      }
+      case SQL_TIME:
+      {
+        memset(data, 0, sizeof(TIME_STRUCT));
+        break;
+      }
+      case SQL_DATE:
+      {
+        memset(data, 0, sizeof(DATE_STRUCT));
+        break;
+      }
+      case SQL_TIMESTAMP:
+      {
+        memset(data, 0, sizeof(TIMESTAMP_STRUCT));
+        break;
+      }
+      default:
+        return;
+    }
+  }
+}
+
+void wxQueryField::SetDirty(bool d) {
+  dirty = d;
+}
+
+void wxQueryField::SetType(short t) {
+  type = t;
+}
+
+void wxQueryField::SetSize(long s) {
+  size = s;
+  AllocData();
+}
+
+void* wxQueryField::GetData(void) {
+  return data;
+}
+
+short wxQueryField::GetType(void)  {
+  return type;
+}
+
+long wxQueryField::GetSize(void) {
+  return size;
+}
+
+bool wxQueryField::IsDirty(void) {
+  return dirty;
+}
+
+#endif // USE_ODBC
diff --git a/src/common/postscrp.cpp b/src/common/postscrp.cpp
new file mode 100644
index 0000000000..376acc9dd9
--- /dev/null
+++ b/src/common/postscrp.cpp
@@ -0,0 +1,2577 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        postscrp.cpp
+// Purpose:     wxPostScriptDC implementation
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "postscrp.h"
+#pragma implementation
+#pragma interface
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#include "wx/defs.h"
+
+#if USE_POSTSCRIPT
+
+#ifndef WX_PRECOMP
+#include "wx/intl.h"
+#include "wx/frame.h"
+#include "wx/postscrp.h"
+#include "wx/utils.h"
+#include "wx/filedlg.h"
+#include "wx/msgdlg.h"
+#include "wx/app.h"
+#include "wx/button.h"
+#include "wx/radiobox.h"
+#include "wx/textctrl.h"
+#include "wx/stattext.h"
+#include "wx/icon.h"
+#include "wx/list.h"
+#endif
+
+#include "wx/dcmemory.h"
+
+#ifdef __WINDOWS__
+#include "wx/msw/private.h"
+#endif
+
+#if USE_IOSTREAMH
+#include <iostream.h>
+#else
+#include <iostream>
+#endif
+
+#include <fstream.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <assert.h>
+
+#ifdef __GTK__
+
+#include "gdk/gdkx.h"        // GDK_DISPLAY
+#include "gdk/gdkprivate.h"  // XImage
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#endif
+
+#ifdef __WINDOWS__
+
+#ifdef DrawText
+#undef DrawText
+#endif
+
+#ifdef StartDoc
+#undef StartDoc
+#endif
+
+#ifdef GetCharWidth
+#undef GetCharWidth
+#endif
+
+#ifdef FindWindow
+#undef FindWindow
+#endif
+
+#endif
+
+// Declarations local to this file
+#define YSCALE(y) (m_yOrigin / m_scaleFactor - (y))
+
+// Determine the Default Postscript Previewer
+// available on the platform
+#if defined(__SUN__) && defined(__XVIEW__)
+// OpenWindow/NeWS's Postscript Previewer
+# define PS_VIEWER_PROG "pageview"
+#elif defined(__VMS__)
+#define PS_VIEWER_PROG "view/format=ps/select=x_display"
+#elif defined(__SGI__)
+// SGI's Display Postscript Previewer
+//# define PS_VIEWER_PROG "dps"
+# define PS_VIEWER_PROG "xpsview"
+#elif defined(__X__) || defined(__GTK__)
+// Front-end to ghostscript
+# define PS_VIEWER_PROG "ghostview"
+#else
+// Windows ghostscript/ghostview
+# define PS_VIEWER_PROG NULL
+#endif
+
+wxPrintSetupData *wxThePrintSetupData = NULL;
+
+// these should move into wxPostscriptDC:
+double UnderlinePosition = 0.0F;
+double UnderlineThickness = 0.0F;
+
+#define _MAXPATHLEN 500
+
+/* See "wxspline.inc" and "xfspline.inc" */
+#if USE_XFIG_SPLINE_CODE
+static const char *wxPostScriptHeaderSpline = " \
+/DrawSplineSection {\n\
+	/y3 exch def\n\
+	/x3 exch def\n\
+	/y2 exch def\n\
+	/x2 exch def\n\
+	/y1 exch def\n\
+	/x1 exch def\n\
+	/xa x1 x2 x1 sub 0.666667 mul add def\n\
+	/ya y1 y2 y1 sub 0.666667 mul add def\n\
+	/xb x3 x2 x3 sub 0.666667 mul add def\n\
+	/yb y3 y2 y3 sub 0.666667 mul add def\n\
+	x1 y1 lineto\n\
+	xa ya xb yb x3 y3 curveto\n\
+	} def\n\
+";
+#else
+// No extra PS header for this spline implementation.
+static const char *wxPostScriptHeaderSpline = NULL;
+
+#endif /* USE_XFIG_SPLINE_CODE */
+
+// steve, 05.09.94
+// VMS has a bug in the ofstream class.
+// the buffering doesn't work correctly. therefore
+// we will allocate (temporarily) a very big buffer (1MB), so
+// that a buffer overflow will not occur.
+#ifdef __VMS__
+#define VMS_BUFSIZ (1024L*1024L)
+static char *fileBuffer = NULL;
+#endif
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxPostScriptDC, wxDC)
+IMPLEMENT_DYNAMIC_CLASS(wxPrintSetupData, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxPrintPaperType, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxPrintPaperDatabase, wxList)
+#endif
+
+wxPostScriptDC::wxPostScriptDC (void)
+{
+//  m_yOrigin = 792;		            // For EPS output
+  m_yOrigin = 842;		            // For A4 output
+
+  m_minX = 1000;
+  m_minY = 1000;
+  m_maxX = -1000;
+  m_maxY = -1000;
+  m_title = "";
+
+  m_pstream = NULL;
+
+#ifdef __WINDOWS__
+  // Can only send to file in Windows
+  wxThePrintSetupData->SetPrinterMode(PS_FILE);
+#endif
+
+  m_currentRed = 255;
+  m_currentGreen = 255;
+  m_currentBlue = 0;
+}
+
+wxPostScriptDC::wxPostScriptDC (const wxString& file, bool interactive, wxWindow *parent)
+{
+  Create(file, interactive, parent);
+}
+
+bool wxPostScriptDC::Create(const wxString& file, bool interactive, wxWindow *parent)
+{
+  m_isInteractive = interactive;
+
+  m_yOrigin = 792;		            // For EPS output
+//  m_yOrigin = 842;		            // For A4 output
+
+  m_minX = 1000;
+  m_minY = 1000;
+  m_maxX = -1000;
+  m_maxY = -1000;
+  m_title = "";
+  m_filename = file;
+  m_pstream = NULL;
+
+#ifdef __WINDOWS__
+  // Can only send to file in Windows
+  wxThePrintSetupData->SetPrinterMode(PS_FILE);
+#endif
+
+  if (m_isInteractive)
+  {
+    if ((m_ok = PrinterDialog (parent) ) == FALSE) return FALSE;
+  }
+  else
+    m_ok = TRUE;
+
+  m_currentRed = 255;
+  m_currentGreen = 255;
+  m_currentBlue = 0;
+
+  m_scaleFactor = 1.0;
+
+  return m_ok;
+}
+
+wxPostScriptDC::~wxPostScriptDC (void)
+{
+  if (m_pstream)
+    delete m_pstream;
+}
+
+bool wxPostScriptDC::PrinterDialog(wxWindow *parent)
+{
+  wxPostScriptPrintDialog dialog (parent, "Printer Settings", wxPoint(150, 150), wxSize(400, 400), wxDEFAULT_DIALOG_STYLE | wxDIALOG_MODAL);
+  m_ok = (dialog.ShowModal () == wxID_OK) ;
+
+  if (!m_ok)
+    return FALSE;
+
+  if ((m_filename == "") && (wxThePrintSetupData->GetPrinterMode() == PS_PREVIEW  || wxThePrintSetupData->GetPrinterMode() == PS_PRINTER))
+    {
+// steve, 05.09.94
+#ifdef __VMS__
+      wxThePrintSetupData->SetPrinterFile("preview");
+#else
+      // For PS_PRINTER action this depends on a Unix-style print spooler
+      // since the wx_printer_file can be destroyed during a session
+      // @@@ TODO: a Windows-style answer for non-Unix
+      char userId[256];
+      wxGetUserId (userId, sizeof (userId) / sizeof (char));
+      char tmp[256];
+      strcpy (tmp, "/tmp/preview_");
+      strcat (tmp, userId);
+      wxThePrintSetupData->SetPrinterFile(tmp);
+#endif
+      char tmp2[256];
+      strcpy(tmp2, wxThePrintSetupData->GetPrinterFile());
+      strcat (tmp2, ".ps");
+      wxThePrintSetupData->SetPrinterFile(tmp2);
+      m_filename = tmp2;
+    }
+    else if ((m_filename == "") && (wxThePrintSetupData->GetPrinterMode() == PS_FILE))
+    {
+      char *file = wxSaveFileSelector ("PostScript", "ps");
+      if (!file)
+      {
+        m_ok = FALSE;
+        return FALSE;
+      }
+      wxThePrintSetupData->SetPrinterFile(file);
+      m_filename = file;
+      m_ok = TRUE;
+    }
+
+  return m_ok;
+}
+
+void wxPostScriptDC::SetClippingRegion (long cx, long cy, long cw, long ch)
+{
+  if (m_clipping)
+    return;
+  if (!m_pstream)
+    return;
+
+  m_clipping = TRUE;
+  *m_pstream << "gsave\n";
+  *m_pstream << "newpath\n";
+  *m_pstream << cx << " " << YSCALE (cy) << " moveto\n";
+  *m_pstream << cx + cw << " " << YSCALE (cy) << " lineto\n";
+  *m_pstream << cx + cw << " " << YSCALE (cy + ch) << " lineto\n";
+  *m_pstream << cx << " " << YSCALE (cy + ch) << " lineto\n";
+  *m_pstream << "closepath clip newpath\n";
+}
+
+void wxPostScriptDC::DestroyClippingRegion (void)
+{
+  if (!m_pstream)
+    return;
+  if (m_clipping)
+    {
+      m_clipping = FALSE;
+      *m_pstream << "grestore\n";
+    }
+}
+
+void wxPostScriptDC::Clear (void)
+{
+}
+
+void wxPostScriptDC::FloodFill (long WXUNUSED(x), long WXUNUSED(y), wxColour * WXUNUSED(col), int WXUNUSED(style))
+{
+}
+
+bool wxPostScriptDC::GetPixel (long WXUNUSED(x), long WXUNUSED(y), wxColour * WXUNUSED(col)) const
+{
+  return FALSE;
+}
+
+void wxPostScriptDC::CrossHair (long WXUNUSED(x), long WXUNUSED(y))
+{
+}
+
+void wxPostScriptDC::DrawLine (long x1, long y1, long x2, long y2)
+{
+  if (!m_pstream)
+    return;
+  if (m_pen.Ok())
+    SetPen (m_pen);
+  *m_pstream << "newpath\n";
+  *m_pstream << x1 << " " << YSCALE (y1) << " moveto\n";
+  *m_pstream << x2 << " " << YSCALE (y2) << " lineto\n";
+  *m_pstream << "stroke\n";
+  CalcBoundingBox (x1, (long)YSCALE (y1));
+  CalcBoundingBox (x2, (long)YSCALE (y2));
+}
+
+#define RAD2DEG 57.29577951308
+
+void wxPostScriptDC::DrawArc (long x1, long y1, long x2, long y2, long xc, long yc)
+{
+    if (!m_pstream)
+		return;
+
+    long dx = x1 - xc;
+    long dy = y1 - yc;
+    long radius = (long) sqrt(dx*dx+dy*dy);
+    double alpha1, alpha2;
+
+    if (x1 == x2 && y1 == y2) {
+	alpha1 = 0.0;
+	alpha2 = 360.0;
+    } else if (radius == 0.0) {
+	alpha1 = alpha2 = 0.0;
+    } else {
+	alpha1 = (x1 - xc == 0) ?
+	    (y1 - yc < 0) ? 90.0 : -90.0 :
+	    -atan2(double(y1-yc), double(x1-xc)) * RAD2DEG;
+	alpha2 = (x2 - xc == 0) ?
+	    (y2 - yc < 0) ? 90.0 : -90.0 :
+	    -atan2(double(y2-yc), double(x2-xc)) * RAD2DEG;
+    }
+    while (alpha1 <= 0)   alpha1 += 360;
+    while (alpha2 <= 0)   alpha2 += 360; // adjust angles to be between
+    while (alpha1 > 360)  alpha1 -= 360; // 0 and 360 degree
+    while (alpha2 > 360)  alpha2 -= 360;
+
+    if (m_brush.Ok() && m_brush.GetStyle() != wxTRANSPARENT) {
+	SetBrush(m_brush);
+	*m_pstream << "newpath\n"
+	         << xc      << " " << YSCALE(yc) << " "
+	         << radius  << " " << radius     << " "
+		 << alpha1  << " " << alpha2     << " ellipse\n"
+		 << xc      << " " << YSCALE(yc) << " lineto\n"
+		 << "closepath\n"
+	         << "fill\n";
+    }
+    if (m_pen.Ok() && m_pen.GetStyle() != wxTRANSPARENT) {
+	SetPen(m_pen);
+	*m_pstream << "newpath\n"
+	         << xc      << " " << YSCALE(yc) << " "
+	         << radius  << " " << radius     << " "
+		 << alpha1  << " " << alpha2     << " ellipse\n"
+	         << "stroke\n";
+    }
+    CalcBoundingBox(x1, (long)YSCALE(y1));
+    CalcBoundingBox(x2, (long)YSCALE(y2));
+}
+
+void wxPostScriptDC::DrawEllipticArc(long x,long y,long w,long h,double sa,double ea)
+{
+  if (!m_pstream)
+    return;
+
+  if (sa>=360 || sa<=-360) sa=sa-int(sa/360)*360;
+  if (ea>=360 || ea<=-360) ea=ea-int(ea/360)*360;
+  if (sa<0) sa+=360;
+  if (ea<0) ea+=360;
+  if (sa==ea)
+  {
+    DrawEllipse(x,y,w,h);
+    return;
+  }
+
+  if (m_brush.Ok() && m_brush.GetStyle () != wxTRANSPARENT)
+    {
+      SetBrush (m_brush);
+
+      *m_pstream << 
+         "newpath\n" <<
+         x+w/2 << " " << YSCALE (y+h/2) << " " <<
+         w/2 << " " << h/2 << " " <<
+         int(sa) <<" "<< int(ea)<<" true ellipticarc\n";
+
+      CalcBoundingBox (x , (long)YSCALE (y ));
+      CalcBoundingBox (x+w,(long)YSCALE(y+h));
+    }
+  if (m_pen.Ok() && m_pen.GetStyle () != wxTRANSPARENT)
+    {
+      SetPen (m_pen);
+
+      *m_pstream << 
+         "newpath\n" <<
+         x+w/2 << " " << YSCALE (y+h/2) << " " <<
+         w/2 << " " << h/2 << " " <<
+         int(sa) <<" "<< int(ea)<<" false ellipticarc\n";
+
+      CalcBoundingBox (x , (long)YSCALE (y ));
+      CalcBoundingBox (x+w,(long)YSCALE(y+h));
+    }
+}
+
+void wxPostScriptDC::DrawPoint (long x, long y)
+{
+  if (!m_pstream)
+    return;
+  if (m_pen.Ok())
+    SetPen (m_pen);
+  *m_pstream << "newpath\n";
+  *m_pstream << x << " " << YSCALE (y) << " moveto\n";
+  *m_pstream << (x+1) << " " << YSCALE (y) << " lineto\n";
+  *m_pstream << "stroke\n";
+  CalcBoundingBox (x, (long)YSCALE (y));
+}
+
+void wxPostScriptDC::DrawPolygon (int n, wxPoint points[], long xoffset, long yoffset, int WXUNUSED(fillStyle))
+{
+  if (!m_pstream)
+    return;
+  if (n > 0)
+    {
+      if (m_brush.Ok() && m_brush.GetStyle () != wxTRANSPARENT)
+	{
+	  SetBrush (m_brush);
+	  *m_pstream << "newpath\n";
+
+	  long xx = points[0].x + xoffset;
+	  long yy = (long) YSCALE (points[0].y + yoffset);
+	  *m_pstream << xx << " " << yy << " moveto\n";
+	  CalcBoundingBox (xx, yy);
+
+	  int i;
+	  for (i = 1; i < n; i++)
+	    {
+	      xx = points[i].x + xoffset;
+	      yy = (long) YSCALE (points[i].y + yoffset);
+	      *m_pstream << xx << " " << yy << " lineto\n";
+	      CalcBoundingBox (xx, yy);
+	    }
+	  *m_pstream << "fill\n";
+	}
+
+      if (m_pen.Ok() && m_pen.GetStyle () != wxTRANSPARENT)
+	{
+	  SetPen (m_pen);
+	  *m_pstream << "newpath\n";
+
+	  long xx = points[0].x + xoffset;
+	  long yy = (long) YSCALE (points[0].y + yoffset);
+	  *m_pstream << xx << " " << yy << " moveto\n";
+	  CalcBoundingBox (xx, yy);
+
+	  int i;
+	  for (i = 1; i < n; i++)
+	    {
+	      xx = points[i].x + xoffset;
+	      yy = (long) YSCALE (points[i].y + yoffset);
+	      *m_pstream << xx << " " << yy << " lineto\n";
+	      CalcBoundingBox (xx, yy);
+	    }
+
+	  // Close the polygon
+	  xx = points[0].x + xoffset;
+	  yy = (long) YSCALE (points[0].y + yoffset);
+	  *m_pstream << xx << " " << yy << " lineto\n";
+
+	  // Output the line
+	  *m_pstream << "stroke\n";
+	}
+    }
+}
+
+void wxPostScriptDC::DrawLines (int n, wxPoint points[], long xoffset, long yoffset)
+{
+  if (!m_pstream)
+    return;
+  if (n > 0)
+    {
+      if (m_pen.Ok())
+		SetPen (m_pen);
+
+      *m_pstream << "newpath\n";
+
+      long xx = points[0].x + xoffset;
+      long yy = (long) YSCALE (points[0].y + yoffset);
+      *m_pstream << xx << " " << yy << " moveto\n";
+      CalcBoundingBox (xx, yy);
+
+      int i;
+      for (i = 1; i < n; i++)
+	{
+	  xx = points[i].x + xoffset;
+	  yy = (long) YSCALE (points[i].y + yoffset);
+	  *m_pstream << xx << " " << yy << " lineto\n";
+	  CalcBoundingBox (xx, yy);
+	}
+      *m_pstream << "stroke\n";
+    }
+}
+
+void wxPostScriptDC::DrawRectangle (long x, long y, long width, long height)
+{
+  if (!m_pstream)
+    return;
+  if (m_brush.Ok() && m_brush.GetStyle () != wxTRANSPARENT)
+    {
+      SetBrush (m_brush);
+
+      *m_pstream << "newpath\n";
+      *m_pstream << x << " " << YSCALE (y) << " moveto\n";
+      *m_pstream << x + width << " " << YSCALE (y) << " lineto\n";
+      *m_pstream << x + width << " " << YSCALE (y + height) << " lineto\n";
+      *m_pstream << x << " " << YSCALE (y + height) << " lineto\n";
+      *m_pstream << "closepath\n";
+      *m_pstream << "fill\n";
+
+      CalcBoundingBox (x, (long)YSCALE (y));
+      CalcBoundingBox (x + width, (long)YSCALE (y + height));
+    }
+  if (m_pen.Ok() && m_pen.GetStyle () != wxTRANSPARENT)
+    {
+      SetPen (m_pen);
+
+      *m_pstream << "newpath\n";
+      *m_pstream << x << " " << YSCALE (y) << " moveto\n";
+      *m_pstream << x + width << " " << YSCALE (y) << " lineto\n";
+      *m_pstream << x + width << " " << YSCALE (y + height) << " lineto\n";
+      *m_pstream << x << " " << YSCALE (y + height) << " lineto\n";
+      *m_pstream << "closepath\n";
+      *m_pstream << "stroke\n";
+
+      CalcBoundingBox (x, (long)YSCALE (y));
+      CalcBoundingBox (x + width, (long)YSCALE (y + height));
+    }
+}
+
+void wxPostScriptDC::DrawRoundedRectangle (long x, long y, long width, long height, double radius)
+{
+  if (!m_pstream)
+    return;
+
+  if (radius < 0.0)
+    {
+      // Now, a negative radius is interpreted to mean
+      // 'the proportion of the smallest X or Y dimension'
+      double smallest = 0.0;
+      if (width < height)
+	smallest = width;
+      else
+	smallest = height;
+      radius =  (-radius * smallest);
+    }
+
+  if (m_brush.Ok() && m_brush.GetStyle () != wxTRANSPARENT)
+    {
+      SetBrush (m_brush);
+      // Draw rectangle anticlockwise
+      *m_pstream << "newpath\n";
+      *m_pstream << x + radius << " " << YSCALE (y + radius) << " " << radius << " 90 180 arc\n";
+
+      *m_pstream << x << " " << YSCALE (y + radius) << " moveto\n";
+
+      *m_pstream << x + radius << " " << YSCALE (y + height - radius) << " " << radius << " 180 270 arc\n";
+      *m_pstream << x + width - radius << " " << YSCALE (y + height) << " lineto\n";
+
+      *m_pstream << x + width - radius << " " << YSCALE (y + height - radius) << " " << radius << " 270 0 arc\n";
+      *m_pstream << x + width << " " << YSCALE (y + radius) << " lineto\n";
+
+      *m_pstream << x + width - radius << " " << YSCALE (y + radius) << " " << radius << " 0 90 arc\n";
+
+      *m_pstream << x + radius << " " << YSCALE (y) << " lineto\n";
+
+      *m_pstream << "closepath\n";
+
+      *m_pstream << "fill\n";
+
+      CalcBoundingBox (x, (long)YSCALE (y));
+      CalcBoundingBox (x + width, (long)YSCALE (y + height));
+    }
+  if (m_pen.Ok() && m_pen.GetStyle () != wxTRANSPARENT)
+    {
+      SetPen (m_pen);
+      // Draw rectangle anticlockwise
+      *m_pstream << "newpath\n";
+      *m_pstream << x + radius << " " << YSCALE (y + radius) << " " << radius << " 90 180 arc\n";
+
+      *m_pstream << x << " " << YSCALE (y + height - radius) << " lineto\n";
+
+      *m_pstream << x + radius << " " << YSCALE (y + height - radius) << " " << radius << " 180 270 arc\n";
+      *m_pstream << x + width - radius << " " << YSCALE (y + height) << " lineto\n";
+
+      *m_pstream << x + width - radius << " " << YSCALE (y + height - radius) << " " << radius << " 270 0 arc\n";
+      *m_pstream << x + width << " " << YSCALE (y + radius) << " lineto\n";
+
+      *m_pstream << x + width - radius << " " << YSCALE (y + radius) << " " << radius << " 0 90 arc\n";
+
+      *m_pstream << x + radius << " " << YSCALE (y) << " lineto\n";
+
+      *m_pstream << "closepath\n";
+
+      *m_pstream << "stroke\n";
+
+      CalcBoundingBox (x, (long)YSCALE (y));
+      CalcBoundingBox (x + width, (long)YSCALE (y + height));
+    }
+}
+
+void wxPostScriptDC::DrawEllipse (long x, long y, long width, long height)
+{
+  if (!m_pstream)
+    return;
+  if (m_brush.Ok() && m_brush.GetStyle () != wxTRANSPARENT)
+    {
+      SetBrush (m_brush);
+
+      *m_pstream << "newpath\n";
+      *m_pstream << x + width / 2 << " " << YSCALE (y + height / 2) << " ";
+      *m_pstream << width / 2 << " " << height / 2 << " 0 360 ellipse\n";
+      *m_pstream << "fill\n";
+
+      CalcBoundingBox (x - width, (long)YSCALE (y - height));
+      CalcBoundingBox (x + width, (long)YSCALE (y + height));
+    }
+  if (m_pen.Ok() && m_pen.GetStyle () != wxTRANSPARENT)
+    {
+      SetPen (m_pen);
+
+      *m_pstream << "newpath\n";
+      *m_pstream << x + width / 2 << " " << YSCALE (y + height / 2) << " ";
+      *m_pstream << width / 2 << " " << height / 2 << " 0 360 ellipse\n";
+      *m_pstream << "stroke\n";
+
+      CalcBoundingBox (x - width, (long)YSCALE (y - height));
+      CalcBoundingBox (x + width, (long)YSCALE (y + height));
+    }
+}
+
+void wxPostScriptDC::DrawIcon (const wxIcon& icon, long x, long y)
+{
+#if defined(__X__) || defined(__GTK__)
+  wxMemoryDC memDC;
+  memDC.SelectObject(icon);
+  Blit(x, y, icon.GetWidth(), icon.GetHeight(), &memDC, 0, 0);
+#endif
+}
+
+void wxPostScriptDC::SetFont (const wxFont& the_font)
+{
+  if (!m_pstream)
+    return;
+
+  if (m_font == the_font)
+    return;
+
+  m_font = the_font;
+
+  if ( !m_font.Ok() )
+	return;
+
+  char buf[100];
+  char *name;
+  char *style = "";
+  int Style = m_font.GetStyle ();
+  int Weight = m_font.GetWeight ();
+
+  switch (m_font.GetFamily ())
+    {
+    case wxTELETYPE:
+    case wxMODERN:
+      name = "/Courier";
+      break;
+    case wxSWISS:
+      name = "/Helvetica";
+      break;
+    case wxROMAN:
+//      name = "/Times-Roman";
+      name = "/Times"; // Altered by EDZ
+      break;
+    case wxSCRIPT:
+      name = "/Zapf-Chancery-MediumItalic";
+      Style  = wxNORMAL;
+      Weight = wxNORMAL;
+      break;
+    default:
+    case wxDEFAULT: // Sans Serif Font
+      name = "/LucidaSans";
+    }
+
+  if (Style == wxNORMAL && (Weight == wxNORMAL || Weight == wxLIGHT))
+    {
+      if (m_font.GetFamily () == wxROMAN)
+	style = "-Roman";
+      else
+	style = "";
+    }
+  else if (Style == wxNORMAL && Weight == wxBOLD)
+    style = "-Bold";
+
+  else if (Style == wxITALIC && (Weight == wxNORMAL || Weight == wxLIGHT))
+    {
+      if (m_font.GetFamily () == wxROMAN)
+	style = "-Italic";
+      else
+	style = "-Oblique";
+    }
+  else if (Style == wxITALIC && Weight == wxBOLD)
+    {
+      if (m_font.GetFamily () == wxROMAN)
+	style = "-BoldItalic";
+      else
+	style = "-BoldOblique";
+    }
+  else if (Style == wxSLANT && (Weight == wxNORMAL || Weight == wxLIGHT))
+    {
+      if (m_font.GetFamily () == wxROMAN)
+	style = "-Italic";
+      else
+	style = "-Oblique";
+    }
+  else if (Style == wxSLANT && Weight == wxBOLD)
+    {
+      if (m_font.GetFamily () == wxROMAN)
+	style = "-BoldItalic";
+      else
+	style = "-BoldOblique";
+    }
+  else
+    style = "";
+
+  strcpy (buf, name);
+  strcat (buf, style);
+  *m_pstream << buf << " findfont\n";
+  *m_pstream << m_font.GetPointSize() * m_scaleFactor << " scalefont setfont\n";
+}
+
+void wxPostScriptDC::SetPen (const wxPen& pen)
+{
+  if (!m_pstream)
+    return;
+
+  int oldStyle = m_pen.GetStyle();
+
+  m_pen = pen;
+
+  if (!m_pen.Ok())
+    return;
+
+  // Line width
+  *m_pstream << m_pen.GetWidth () << " setlinewidth\n";
+
+  // Line style - WRONG: 2nd arg is OFFSET
+  /*
+     Here, I'm afraid you do not conceive meaning of parameters of 'setdash'
+     operator correctly. You should look-up this in the Red Book: the 2nd parame-
+     ter is not number of values in the array of the first one, but an offset
+     into this description of the pattern. I mean a real *offset* not index
+     into array. I.e. If the command is [3 4] 1 setdash   is used, then there
+     will be first black line *2* units long, then space 4 units, then the
+     pattern of *3* units black, 4 units space will be repeated.
+   */
+  static char *dotted = "[2 5] 2";
+  static char *short_dashed = "[4 4] 2";
+  static char *long_dashed = "[4 8] 2";
+  static char *dotted_dashed = "[6 6 2 6] 4";
+
+  char *psdash = NULL;
+  switch (m_pen.GetStyle ())
+    {
+    case wxDOT:
+      psdash = dotted;
+      break;
+    case wxSHORT_DASH:
+      psdash = short_dashed;
+      break;
+    case wxLONG_DASH:
+      psdash = long_dashed;
+      break;
+    case wxDOT_DASH:
+      psdash = dotted_dashed;
+      break;
+    case wxSOLID:
+    case wxTRANSPARENT:
+    default:
+      psdash = "[] 0";
+      break;
+    }
+  if (oldStyle != m_pen.GetStyle())
+    *m_pstream << psdash << " setdash\n";
+
+  // Line colour
+  unsigned char red = m_pen.GetColour ().Red ();
+  unsigned char blue = m_pen.GetColour ().Blue ();
+  unsigned char green = m_pen.GetColour ().Green ();
+
+  if (!m_colour)
+    {
+      // Anything not white is black
+      if (!(red == (unsigned char) 255 && blue == (unsigned char) 255
+	    && green == (unsigned char) 255))
+	{
+	  red = (unsigned char) 0;
+	  green = (unsigned char) 0;
+	  blue = (unsigned char) 0;
+	}
+    }
+
+  if (!(red == m_currentRed && green == m_currentGreen && blue == m_currentBlue))
+  {
+    long redPS = (long) (((int) red) / 255.0);
+    long bluePS = (long) (((int) blue) / 255.0);
+    long greenPS = (long) (((int) green) / 255.0);
+
+    *m_pstream << redPS << " " << greenPS << " " << bluePS << " setrgbcolor\n";
+
+    m_currentRed = red;
+    m_currentBlue = blue;
+    m_currentGreen = green;
+  }
+}
+
+void wxPostScriptDC::SetBrush (const wxBrush& brush)
+{
+  if (!m_pstream)
+    return;
+
+  m_brush = brush;
+
+  if ( !m_brush.Ok() )
+	return;
+
+  // Brush colour
+  unsigned char red = m_brush.GetColour ().Red ();
+  unsigned char blue = m_brush.GetColour ().Blue ();
+  unsigned char green = m_brush.GetColour ().Green ();
+
+  if (!m_colour)
+    {
+      // Anything not black is white
+      if (!(red == (unsigned char) 0 && blue == (unsigned char) 0
+	    && green == (unsigned char) 0))
+	{
+	  red = (unsigned char) 255;
+	  green = (unsigned char) 255;
+	  blue = (unsigned char) 255;
+	}
+    }
+
+  if (!(red == m_currentRed && green == m_currentGreen && blue == m_currentBlue))
+  {
+    long redPS = (long) (((int) red) / 255.0);
+    long bluePS = (long) (((int) blue) / 255.0);
+    long greenPS = (long) (((int) green) / 255.0);
+    *m_pstream << redPS << " " << greenPS << " " << bluePS << " setrgbcolor\n";
+    m_currentRed = red;
+    m_currentBlue = blue;
+    m_currentGreen = green;
+  }
+}
+
+void wxPostScriptDC::DrawText (const wxString& text, long x, long y, bool WXUNUSED(use16bit))
+{
+  if (!m_pstream)
+    return;
+
+  // TODO: SetFont checks for identity so this will always be a NULL operation
+  if (m_font.Ok())
+    SetFont (m_font);
+
+  if (m_textForegroundColour.Ok ())
+    {
+      unsigned char red = m_textForegroundColour.Red ();
+      unsigned char blue = m_textForegroundColour.Blue ();
+      unsigned char green = m_textForegroundColour.Green ();
+
+      if (!m_colour)
+	{
+	  // Anything not white is black
+	  if (!(red == (unsigned char) 255 && blue == (unsigned char) 255
+		&& green == (unsigned char) 255))
+	    {
+	      red = (unsigned char) 0;
+	      green = (unsigned char) 0;
+	      blue = (unsigned char) 0;
+	    }
+	}
+      if (!(red == m_currentRed && green == m_currentGreen && blue == m_currentBlue))
+      {
+        long redPS = (long) (((int) red) / 255.0);
+        long bluePS = (long) (((int) blue) / 255.0);
+        long greenPS = (long) (((int) green) / 255.0);
+        *m_pstream << redPS << " " << greenPS << " " << bluePS << " setrgbcolor\n";
+
+        m_currentRed = red;
+        m_currentBlue = blue;
+        m_currentGreen = green;
+      }
+    }
+
+  int size = 10;
+  if (m_font.Ok())
+    size = m_font.GetPointSize ();
+
+  *m_pstream << x << " " << YSCALE (y + size) << " moveto\n";
+
+//  *m_pstream << "(" << text << ")" << " show\n";
+  *m_pstream << "(";
+  int len = strlen ((char *)(const char *)text);
+  int i;
+  for (i = 0; i < len; i++)
+    {
+/*
+      char ch = text[i];
+      if (ch == ')' || ch == '(' || ch == '\\')
+	*m_pstream << "\\";
+      *m_pstream << ch;
+*/
+      int c = (unsigned char) text[i];
+      if ( c == ')' || c == '(' || c == '\\')
+      {
+        *m_pstream << "\\" << (char) c;
+      }
+      else if ( c >= 128 )
+      {
+        // Cope with character codes > 127
+        char tmp[5];
+        sprintf(tmp, "\\%o", c);
+        *m_pstream << tmp;
+      }
+      else
+        *m_pstream << (char) c;
+    }
+
+  *m_pstream << ")" << " show\n";
+
+  if (m_font.GetUnderlined())
+  {
+      long w, h;
+      GetTextExtent(text, &w, &h);
+      *m_pstream << "gsave " << x << " " << YSCALE (y + size - UnderlinePosition)
+               << " moveto\n"
+               << UnderlineThickness << " setlinewidth "
+               << x + w << " " << YSCALE (y + size - UnderlinePosition)
+               << " lineto stroke grestore\n";
+  }
+  
+  CalcBoundingBox (x, (long)YSCALE (y + size));
+  CalcBoundingBox (x + size * strlen ((char *)(const char *)text), (long)YSCALE (y));
+}
+
+
+void wxPostScriptDC::SetBackground (const wxBrush& brush)
+{
+  m_backgroundBrush = brush;
+}
+
+void wxPostScriptDC::SetLogicalFunction (int WXUNUSED(function))
+{
+}
+
+static const char *wxPostScriptHeaderEllipse = "\
+/ellipsedict 8 dict def\n\
+ellipsedict /mtrx matrix put\n\
+/ellipse\n\
+{ ellipsedict begin\n\
+  /endangle exch def\n\
+  /startangle exch def\n\
+  /yrad exch def\n\
+  /xrad exch def\n\
+  /y exch def\n\
+  /x exch def\n\
+  /savematrix mtrx currentmatrix def\n\
+  x y translate\n\
+  xrad yrad scale\n\
+  0 0 1 startangle endangle arc\n\
+  savematrix setmatrix\n\
+  end\n\
+  } def\n\
+";
+
+static const char *wxPostScriptHeaderEllipticArc= "\
+/ellipticarcdict 8 dict def\n\
+ellipticarcdict /mtrx matrix put\n\
+/ellipticarc\n\
+{ ellipticarcdict begin\n\
+  /do_fill exch def\n\
+  /endangle exch def\n\
+  /startangle exch def\n\
+  /yrad exch def\n\
+  /xrad exch def \n\
+  /y exch def\n\
+  /x exch def\n\
+  /savematrix mtrx currentmatrix def\n\
+  x y translate\n\
+  xrad yrad scale\n\
+  do_fill { 0 0 moveto } if\n\
+  0 0 1 startangle endangle arc\n\
+  savematrix setmatrix\n\
+  do_fill { fill }{ stroke } ifelse\n\
+  end\n\
+} def\n";
+
+bool wxPostScriptDC::StartDoc (const wxString& message)
+{
+    if (m_filename == "")
+	{
+#ifdef __VMS__
+          m_filename = "wxtmp.ps";
+#else
+          m_filename = wxGetTempFileName("ps");
+#endif
+	  wxThePrintSetupData->SetPrinterFile((char *)(const char *)m_filename);
+	  m_ok = TRUE;
+	}
+      else
+	wxThePrintSetupData->SetPrinterFile((char *)(const char *)m_filename);
+
+#ifdef __VMS__
+      // steve, 05.09.94
+      // VMS is sh*t!
+      m_pstream = new ofstream;
+      if(fileBuffer) delete[] fileBuffer;
+      fileBuffer = new char[VMS_BUFSIZ]; 
+      m_pstream->setbuf(fileBuffer,VMS_BUFSIZ);
+      m_pstream->open(wxThePrintSetupData->GetPrinterFile());
+#else
+      m_pstream = new ofstream (wxThePrintSetupData->GetPrinterFile());
+#endif
+      if (!m_pstream || !m_pstream->good())
+	{
+	  wxMessageBox (_("Cannot open file!"), _("Error"), wxOK);
+	  m_ok = FALSE;
+	  return FALSE;
+	}
+  m_ok = TRUE;
+
+  SetBrush (*wxBLACK_BRUSH);
+  SetPen (*wxBLACK_PEN);
+
+  wxPageNumber = 1;
+  m_title = message;
+  return TRUE;
+}
+
+
+void wxPostScriptDC::EndDoc (void)
+{
+    static char wxPostScriptHeaderReencodeISO1[] =
+    "\n/reencodeISO {\n"
+"dup dup findfont dup length dict begin\n"
+"{ 1 index /FID ne { def }{ pop pop } ifelse } forall\n"
+"/Encoding ISOLatin1Encoding def\n"
+"currentdict end definefont\n"
+"} def\n"
+"/ISOLatin1Encoding [\n"
+"/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n"
+"/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n"
+"/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n"
+"/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n"
+"/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright\n"
+"/parenleft/parenright/asterisk/plus/comma/minus/period/slash\n"
+"/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon\n"
+"/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N\n"
+"/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright\n"
+"/asciicircum/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m\n"
+"/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde\n"
+"/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n"
+"/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n"
+"/.notdef/dotlessi/grave/acute/circumflex/tilde/macron/breve\n"
+"/dotaccent/dieresis/.notdef/ring/cedilla/.notdef/hungarumlaut\n";
+
+    static char wxPostScriptHeaderReencodeISO2[] =
+"/ogonek/caron/space/exclamdown/cent/sterling/currency/yen/brokenbar\n"
+"/section/dieresis/copyright/ordfeminine/guillemotleft/logicalnot\n"
+"/hyphen/registered/macron/degree/plusminus/twosuperior/threesuperior\n"
+"/acute/mu/paragraph/periodcentered/cedilla/onesuperior/ordmasculine\n"
+"/guillemotright/onequarter/onehalf/threequarters/questiondown\n"
+"/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla\n"
+"/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex\n"
+"/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis\n"
+"/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute\n"
+"/Thorn/germandbls/agrave/aacute/acircumflex/atilde/adieresis\n"
+"/aring/ae/ccedilla/egrave/eacute/ecircumflex/edieresis/igrave\n"
+"/iacute/icircumflex/idieresis/eth/ntilde/ograve/oacute/ocircumflex\n"
+"/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex/udieresis\n"
+"/yacute/thorn/ydieresis\n"
+        "] def\n\n";
+
+    if (!m_pstream)
+    	return;
+  if (m_clipping)
+    {
+      m_clipping = FALSE;
+      *m_pstream << "grestore\n";
+    }
+
+  // Will reuse m_pstream for header
+#ifdef __VMS__
+  // see the definition of fileBuffer for explanation
+  m_pstream->close(); // steve, 05.09.94
+  if(fileBuffer) delete[] fileBuffer;
+#endif
+  if (m_pstream)
+    {
+      delete m_pstream;
+      m_pstream = NULL;
+    }
+
+  // Write header now
+// steve, 05.09.94
+#ifdef __VMS__
+  char *header_file = "header.ps";
+#else
+  char *header_file = wxGetTempFileName("ps");
+#endif
+  m_pstream = new ofstream (header_file);
+
+  *m_pstream << "%!PS-Adobe-2.0\n";	/* PostScript magic strings */
+  *m_pstream << "%%Title: " << (const char *) m_title << "\n";
+  *m_pstream << "%%Creator: " << wxTheApp->argv[0] << "\n";
+//  time_t when; time (&when);
+//  *m_pstream << "%%CreationDate: " << ctime (&when);
+  *m_pstream << "%%CreationDate: " << wxNow() << "\n";
+
+  // User Id information
+  char userID[256];
+  if ( wxGetEmailAddress(userID, sizeof(userID)) )
+  {
+    *m_pstream << "%%For: " << (char *)userID;
+    char userName[245];
+    if (wxGetUserName(userName, sizeof(userName)))
+      *m_pstream << " (" << (char *)userName << ")";
+    *m_pstream << "\n";
+  }
+  else if ( wxGetUserName(userID, sizeof(userID)) )
+  {
+    *m_pstream << "%%For: " << (char *)userID << "\n";
+  }
+
+  // THE FOLLOWING HAS BEEN CONTRIBUTED BY Andy Fyfe <andy@hyperparallel.com>
+
+  long wx_printer_translate_x, wx_printer_translate_y;
+  double wx_printer_scale_x, wx_printer_scale_y;
+  wxThePrintSetupData->GetPrinterTranslation(&wx_printer_translate_x, &wx_printer_translate_y);
+  wxThePrintSetupData->GetPrinterScaling(&wx_printer_scale_x, &wx_printer_scale_y);
+
+	if (wxThePrintSetupData->GetPrinterOrientation() == PS_LANDSCAPE)
+	{
+		*m_pstream << "%%Orientation: Landscape\n";
+	}
+	else
+	{
+		*m_pstream << "%%Orientation: Portrait\n";
+	}
+
+  // Compute the bounding box.  Note that it is in the default user
+  // coordinate system, thus we have to convert the values.
+  long llx = (long) ((m_minX+wx_printer_translate_x)*wx_printer_scale_x);
+  long lly = (long) ((m_minY+wx_printer_translate_y)*wx_printer_scale_y);
+  long urx = (long) ((m_maxX+wx_printer_translate_x)*wx_printer_scale_x);
+  long ury = (long) ((m_maxY+wx_printer_translate_y)*wx_printer_scale_y);
+
+#if 0
+  // If we're landscape, our sense of "x" and "y" is reversed.
+  if (wxThePrintSetupData->GetPrinterOrientation() == PS_LANDSCAPE)
+    {
+      double tmp;
+      tmp = llx; llx = lly; lly = tmp;
+      tmp = urx; urx = ury; ury = tmp;
+
+      // We need either the two lines that follow, or we need to subtract
+      // min_x from real_translate_y, which is commented out below.
+      llx = llx - m_minX*wx_printer_scale_y;
+      urx = urx - m_minX*wx_printer_scale_y;
+    }
+#endif
+
+  // The Adobe specifications call for integers; we round as to make
+  // the bounding larger.
+  *m_pstream << "%%BoundingBox: "
+      << floor(llx) << " " << floor(lly) << " "
+      << ceil(urx)  << " " << ceil(ury)  << "\n";
+  *m_pstream << "%%Pages: " << wxPageNumber - 1 << "\n";
+  *m_pstream << "%%EndComments\n\n";
+
+  // To check the correctness of the bounding box, postscript commands
+  // to draw a box corresponding to the bounding box are generated below.
+  // But since we typically don't want to print such a box, the postscript
+  // commands are generated within comments.  These lines appear before any
+  // adjustment of scale, rotation, or translation, and hence are in the
+  // default user coordinates.
+  *m_pstream << "% newpath\n";
+  *m_pstream << "% " << llx << " " << lly << " moveto\n";
+  *m_pstream << "% " << urx << " " << lly << " lineto\n";
+  *m_pstream << "% " << urx << " " << ury << " lineto\n";
+  *m_pstream << "% " << llx << " " << ury << " lineto closepath stroke\n";
+
+#if 0
+  // Output scaling
+  long real_translate_y = wx_printer_translate_y;
+  if (wxThePrintSetupData->GetPrinterOrientation() == PS_LANDSCAPE)
+    {
+      real_translate_y -= m_maxY;
+      // The following line can be used instead of the adjustment to 
+      // llx and urx above.
+      // real_translate_y -= m_minX;
+      *m_pstream << "90 rotate\n";
+    }
+
+/* Probably don't want this now we have it in EndPage, below.
+ * We should rationalise the scaling code to one place. JACS, October 1995
+ * Do we take the next 2 lines out or not?
+ */
+ 
+  *m_pstream << wx_printer_scale_x << " " << wx_printer_scale_y << " scale\n";
+  *m_pstream << wx_printer_translate_x << " " << real_translate_y << " translate\n";
+#endif
+
+  *m_pstream << "%%BeginProlog\n";
+  *m_pstream << wxPostScriptHeaderEllipse;
+  *m_pstream << wxPostScriptHeaderEllipticArc;
+  *m_pstream << wxPostScriptHeaderReencodeISO1;
+  *m_pstream << wxPostScriptHeaderReencodeISO2;
+
+  if (wxPostScriptHeaderSpline)
+    *m_pstream << wxPostScriptHeaderSpline;
+  *m_pstream << "%%EndProlog\n";
+
+  delete m_pstream;
+  m_pstream = NULL;
+
+#ifdef __VMS__
+  char *tmp_file = "tmp.ps";
+#else
+  char *tmp_file = wxGetTempFileName("ps");
+#endif
+
+  // Paste header Before wx_printer_file
+  wxConcatFiles (header_file, wxThePrintSetupData->GetPrinterFile(), tmp_file);
+  wxRemoveFile (header_file);
+  wxRemoveFile (wxThePrintSetupData->GetPrinterFile());
+  wxRenameFile(tmp_file, wxThePrintSetupData->GetPrinterFile());
+
+#if defined(__X__) || defined(__GTK__)
+  if (m_ok)
+    {
+      switch (wxThePrintSetupData->GetPrinterMode()) {
+	case PS_PREVIEW:
+	{
+          char *argv[3];
+          argv[0] = wxThePrintSetupData->GetPrintPreviewCommand();
+          argv[1] = wxThePrintSetupData->GetPrinterFile();
+          argv[2] = NULL;
+	  wxExecute (argv, TRUE);
+          wxRemoveFile(wxThePrintSetupData->GetPrinterFile());
+	}
+	break;
+
+	case PS_PRINTER:
+	{
+          char *argv[4];
+          int argc = 0;
+          argv[argc++] = wxThePrintSetupData->GetPrinterCommand();
+
+          // !SM! If we simply assign to argv[1] here, if printer options
+          // are blank, we get an annoying and confusing message from lpr.
+          char * opts = wxThePrintSetupData->GetPrinterOptions();
+          if (opts && *opts)
+              argv[argc++] = opts;
+              
+          argv[argc++] = wxThePrintSetupData->GetPrinterFile();
+          argv[argc++] = NULL;
+	  wxExecute (argv, TRUE);
+          wxRemoveFile(wxThePrintSetupData->GetPrinterFile());
+	}
+	break;
+
+	case PS_FILE:
+	  break;
+	}
+    }
+#endif
+}
+
+void wxPostScriptDC::StartPage (void)
+{
+  if (!m_pstream)
+    return;
+  *m_pstream << "%%Page: " << wxPageNumber++ << "\n";
+//  *m_pstream << "matrix currentmatrix\n";
+
+    // Added by Chris Breeze
+
+	// Each page starts with an "initgraphics" which resets the
+	// transformation and so we need to reset the origin
+	// (and rotate the page for landscape printing)
+	m_scaleFactor = 1.0;
+	m_logicalOriginX = 0;
+	m_logicalOriginY = 0;
+
+	// Output scaling
+	long translate_x, translate_y;
+	double scale_x, scale_y;
+	wxThePrintSetupData->GetPrinterTranslation(&translate_x, &translate_y);
+	wxThePrintSetupData->GetPrinterScaling(&scale_x, &scale_y);
+
+	if (wxThePrintSetupData->GetPrinterOrientation() == PS_LANDSCAPE)
+	{
+		translate_y -= GetYOrigin();
+		*m_pstream << "90 rotate\n";
+	}
+
+	*m_pstream << scale_x << " " << scale_y << " scale\n";
+	*m_pstream << translate_x << " " << translate_y << " translate\n";
+}
+
+void wxPostScriptDC::EndPage (void)
+{
+  if (!m_pstream)
+    return;
+  *m_pstream << "showpage\n";
+
+  // Removed by	Chris Breeze
+#if 0
+  *m_pstream << "setmatrix\n";
+
+  // THE FOLLOWING HAS BEEN CONTRIBUTED BY Andy Fyfe <andy@hyperparallel.com>
+
+  long wx_printer_translate_x, wx_printer_translate_y;
+  double wx_printer_scale_x, wx_printer_scale_y;
+  wxThePrintSetupData->GetPrinterTranslation(&wx_printer_translate_x, &wx_printer_translate_y);
+  wxThePrintSetupData->GetPrinterScaling(&wx_printer_scale_x, &wx_printer_scale_y);
+
+  // Compute the bounding box.  Note that it is in the default user
+  // coordinate system, thus we have to convert the values.
+  long llx = (m_minX+wx_printer_translate_x)*wx_printer_scale_x;
+  long lly = (m_minY+wx_printer_translate_y)*wx_printer_scale_y;
+  long urx = (m_maxX+wx_printer_translate_x)*wx_printer_scale_x;
+  long ury = (m_maxY+wx_printer_translate_y)*wx_printer_scale_y;
+
+  // If we're landscape, our sense of "x" and "y" is reversed.
+  if (wxThePrintSetupData->GetPrinterOrientation() == PS_LANDSCAPE)
+    {
+      long tmp;
+      tmp = llx; llx = lly; lly = tmp;
+      tmp = urx; urx = ury; ury = tmp;
+
+      // We need either the two lines that follow, or we need to subtract
+      // m_minX from real_translate_y, which is commented out below.
+      llx = llx - m_minX*wx_printer_scale_y;
+      urx = urx - m_minX*wx_printer_scale_y;
+    }
+
+  // Output scaling
+  long real_translate_y = wx_printer_translate_y;
+  if (wxThePrintSetupData->GetPrinterOrientation() == PS_LANDSCAPE)
+    {
+      real_translate_y -= m_maxY;
+      // The following line can be used instead of the adjustment to
+      // llx and urx above.
+      // real_translate_y -= m_minX;
+      *m_pstream << "90 rotate\n";
+    }
+
+  *m_pstream << wx_printer_scale_x << " " << wx_printer_scale_y << " scale\n";
+  *m_pstream << wx_printer_translate_x << " " << real_translate_y << " translate\n";
+#endif
+}
+
+/* MATTHEW: Implement Blit: */
+/* MATTHEW: [4] Re-wrote to use colormap */
+bool wxPostScriptDC::
+Blit (long xdest, long ydest, long fwidth, long fheight,
+      wxDC *source, long xsrc, long ysrc, int WXUNUSED(rop), bool WXUNUSED(useMask))
+{
+  long width, height, x, y;
+
+#if !defined(__X__) && !defined(__GTK__)
+  return FALSE;
+#endif
+
+  if (!source->IsKindOf(CLASSINFO(wxPaintDC))) return FALSE;
+
+  width = (long)floor(fwidth);
+  height = (long)floor(fheight);
+  x = (long)floor(xsrc);
+  y = (long)floor(ysrc);
+
+  /* PostScript setup: */
+  *m_pstream << "gsave\n";
+  *m_pstream << xdest << " " << YSCALE(ydest + fheight) << " translate\n";
+  *m_pstream << fwidth << " " << fheight << " scale\n";
+  *m_pstream << "/DataString " << width << " string def\n";
+  *m_pstream << width << " " << height << " 8 [ ";
+  *m_pstream << width << " 0 0 " << (-height) << " 0 " << height;
+  *m_pstream << " ]\n{\n";
+  *m_pstream << "  currentfile DataString readhexstring pop\n";
+  *m_pstream << "} bind image\n";
+
+#if defined(__X__) || defined(__GTK__)
+
+  /* Output data as hex digits: */
+  Display *d;
+  Colormap cm;
+  XImage *image;
+  long j, i;
+  char s[3];
+  
+#ifdef __GTK__
+
+  d = gdk_display;
+  cm = ((GdkColormapPrivate*)gdk_colormap_get_system())->xcolormap;
+  GdkWindow *gwin = ((wxClientDC*)source)->GetWindow();
+  image = XGetImage(d, ((GdkWindowPrivate*)gwin)->xwindow, x, y, width, height, AllPlanes, ZPixmap);
+
+#else  
+
+#ifdef __MOTIF__
+  d = source->display;
+#else
+  d = wxGetDisplay();
+#endif
+
+  cm = wxGetMainColormap(d);
+  image = XGetImage(d, source->pixmap, x, y, width, height, AllPlanes, ZPixmap);
+  
+#endif
+
+
+  s[2] = 0;
+
+#define CM_CACHE_SIZE 256
+  unsigned long cachesrc[CM_CACHE_SIZE];
+  int cachedest[CM_CACHE_SIZE], cache_pos = 0, all_cache = FALSE;
+
+  for (j = 0; j < height; j++) {
+    for (i = 0; i < width; i++) {
+      XColor xcol;
+      unsigned long spixel;
+      int pixel, k;
+      const unsigned short MAX_COLOR = 0xFFFF;
+
+      spixel = XGetPixel(image, i, j);
+
+      for (k = cache_pos; k--; )
+	if (cachesrc[k] == spixel) {
+	  pixel = cachedest[k];
+	  goto install;
+	}
+      if (all_cache)
+	for (k = CM_CACHE_SIZE; k-- > cache_pos; )
+	  if (cachesrc[k] == spixel) {
+	    pixel = cachedest[k];
+	    goto install;
+	  }
+      
+      cachesrc[cache_pos] = xcol.pixel = spixel;
+      XQueryColor(d, cm, &xcol);
+      
+      long r, g, b;
+
+      r = (long)((double)(xcol.red) / MAX_COLOR);
+      g = (long)((double)(xcol.green) / MAX_COLOR);
+      b = (long)((double)(xcol.blue) / MAX_COLOR);
+
+      pixel = (int)(255 * sqrt(((r * r) + (g * g) + (b * b)) / 3));
+
+      cachedest[cache_pos] = pixel;
+      
+      if (++cache_pos >= CM_CACHE_SIZE) {
+	cache_pos = 0;
+	all_cache = TRUE;
+      }
+
+    install:      
+      int h, l;
+
+      h = (pixel >> 4) & 0xF;
+      l = pixel & 0xF;
+
+      if (h <= 9)
+	s[0] = '0' + h;
+      else
+	s[0] = 'a' + (h - 10);
+      if (l <= 9)
+	s[1] = '0' + l;
+      else
+	s[1] = 'a' + (l - 10);
+      
+      *m_pstream << s;
+    }
+    *m_pstream << "\n";
+  }
+
+  XDestroyImage(image);
+#endif
+
+  *m_pstream << "grestore\n";
+
+  CalcBoundingBox(xdest, (long)YSCALE(ydest));
+  CalcBoundingBox(xdest + fwidth, (long)YSCALE(ydest + fheight));
+
+  return TRUE;
+}
+
+long wxPostScriptDC::GetCharHeight (void)
+{
+  if (m_font.Ok())
+    return  m_font.GetPointSize ();
+  else
+    return 12;
+}
+
+void wxPostScriptDC::GetTextExtent (const wxString& string, long *x, long *y,
+	       long *descent, long *externalLeading, wxFont *theFont,
+				    bool WXUNUSED(use16))
+{
+  wxFont *fontToUse = theFont;
+  if (!fontToUse)
+    fontToUse = (wxFont*) &m_font;
+
+  if (!m_pstream)
+    return;
+#if !USE_AFM_FOR_POSTSCRIPT
+  // Provide a VERY rough estimate (avoid using it)
+	// Chris Breeze 5/11/97: produces accurate results for mono-spaced
+	// font such as Courier (aka wxMODERN)
+	int height = 12;
+	if (fontToUse)
+	{
+		height = fontToUse->GetPointSize();
+	}
+	*x = strlen (string) * height * 72 / 120;
+	*y = (long) (height * 1.32);	// allow for descender
+
+  if (descent)
+    *descent = 0;
+  if (externalLeading)
+    *externalLeading = 0;
+#else
+  // +++++ start of contributed code +++++
+  
+  // ************************************************************
+  // method for calculating string widths in postscript:
+  // read in the AFM (adobe font metrics) file for the
+  // actual font, parse it and extract the character widths
+  // and also the descender. this may be improved, but for now
+  // it works well. the AFM file is only read in if the
+  // font is changed. this may be chached in the future.
+  // calls to GetTextExtent with the font unchanged are rather
+  // efficient!!!
+  //
+  // for each font and style used there is an AFM file necessary.
+  // currently i have only files for the roman font family.
+  // i try to get files for the other ones!
+  //
+  // CAVE: the size of the string is currently always calculated
+  //       in 'points' (1/72 of an inch). this should later on be
+  //       changed to depend on the mapping mode.
+  // CAVE: the path to the AFM files must be set before calling this
+  //       function. this is usually done by a call like the following:
+  //       wxSetAFMPath("d:\\wxw161\\afm\\");
+  //
+  // example:
+  //
+  //    wxPostScriptDC dc(NULL, TRUE);
+  //    if (dc.Ok()){
+  //      wxSetAFMPath("d:\\wxw161\\afm\\");
+  //      dc.StartDoc("Test");
+  //      dc.StartPage();
+  //      long w,h;
+  //      dc.SetFont(new wxFont(10, wxROMAN, wxNORMAL, wxNORMAL));
+  //      dc.GetTextExtent("Hallo",&w,&h);
+  //      dc.EndPage();
+  //      dc.EndDoc();
+  //    }
+  //
+  // by steve (stefan.hammes@urz.uni-heidelberg.de)
+  // created: 10.09.94
+  // updated: 14.05.95
+
+  assert(fontToUse && "void wxPostScriptDC::GetTextExtent: no font defined");
+  assert(x && "void wxPostScriptDC::GetTextExtent: x == NULL");
+  assert(y && "void wxPostScriptDC::GetTextExtent: y == NULL");
+
+  // these static vars are for storing the state between calls
+  static int lastFamily= INT_MIN;
+  static int lastSize= INT_MIN;
+  static int lastStyle= INT_MIN;
+  static int lastWeight= INT_MIN;
+  static int lastDescender = INT_MIN;
+  static int lastWidths[256]; // widths of the characters
+
+  // get actual parameters
+  const int Family = fontToUse->GetFamily();
+  const int Size =   fontToUse->GetPointSize();
+  const int Style =  fontToUse->GetStyle();
+  const int Weight = fontToUse->GetWeight();
+
+  // if we have another font, read the font-metrics
+  if(Family!=lastFamily||Size!=lastSize||Style!=lastStyle||Weight!=lastWeight){
+    // store actual values
+    lastFamily = Family;
+    lastSize =   Size;
+    lastStyle =  Style;
+    lastWeight = Weight;
+
+    // read in new font metrics **************************************
+
+    // 1. construct filename ******************************************
+    /* MATTHEW: [2] Use wxTheFontNameDirectory */
+    char *name;
+
+	// Julian - we'll need to do this a different way now we've removed the
+	// font directory system. Must find Stefan's original code.
+
+    name = wxTheFontNameDirectory.GetAFMName(Family, Weight, Style);
+    if (!name)
+      name = "unknown";
+
+    // get the directory of the AFM files
+    char afmName[256];
+    afmName[0] = 0;
+    if (wxGetAFMPath())
+      strcpy(afmName,wxGetAFMPath());
+
+    // 2. open and process the file **********************************
+
+    // a short explanation of the AFM format:
+    // we have for each character a line, which gives its size
+    // e.g.:
+    //
+    //   C 63 ; WX 444 ; N question ; B 49 -14 395 676 ;
+    //
+    // that means, we have a character with ascii code 63, and width 
+    // (444/1000 * fontSize) points.
+    // the other data is ignored for now!
+    //
+    // when the font has changed, we read in the right AFM file and store the
+    // character widths in an array, which is processed below (see point 3.).
+    
+        // new elements JC Sun Aug 25 23:21:44 MET DST 1996
+
+    
+    strcat(afmName,name);
+    strcat(afmName,".afm");
+    FILE *afmFile = fopen(afmName,"r");
+    if(afmFile==NULL){
+      wxDebugMsg("GetTextExtent: can't open AFM file '%s'\n",afmName);
+      wxDebugMsg("               using approximate values\n");
+      int i;
+      for (i=0; i<256; i++) lastWidths[i] = 500; // an approximate value
+      lastDescender = -150; // dito.
+    }else{
+      int i;
+      // init the widths array
+      for(i=0; i<256; i++) lastWidths[i]= INT_MIN;
+      // some variables for holding parts of a line
+      char cString[10],semiString[10],WXString[10],descString[20];
+      char upString[30], utString[30], encString[50];
+      char line[256];
+      int ascii,cWidth;
+      // read in the file and parse it
+      while(fgets(line,sizeof(line),afmFile)!=NULL){
+        // A.) check for descender definition
+        if(strncmp(line,"Descender",9)==0){
+          if((sscanf(line,"%s%d",descString,&lastDescender)!=2)
+	     || (strcmp(descString,"Descender")!=0)) {
+	    wxDebugMsg("AFM-file '%s': line '%s' has error (bad descender)\n",
+		       afmName,line);
+          }
+        }
+            // JC 1.) check for UnderlinePosition
+        else if(strncmp(line,"UnderlinePosition",17)==0){
+          if((sscanf(line,"%s%f",upString,&UnderlinePosition)!=2)
+	     || (strcmp(upString,"UnderlinePosition")!=0)) {
+	    wxDebugMsg("AFM-file '%s': line '%s' has error (bad UnderlinePosition)\n",
+		       afmName,line);
+          }
+        }
+	// JC 2.) check for UnderlineThickness
+        else if(strncmp(line,"UnderlineThickness",18)==0){
+          if((sscanf(line,"%s%f",utString,&UnderlineThickness)!=2)
+	     || (strcmp(utString,"UnderlineThickness")!=0)) {
+	    wxDebugMsg("AFM-file '%s': line '%s' has error (bad UnderlineThickness)\n",
+		       afmName,line);
+          }
+        }
+	// JC 3.) check for EncodingScheme
+        else if(strncmp(line,"EncodingScheme",14)==0){
+          if((sscanf(line,"%s%s",utString,encString)!=2)
+	     || (strcmp(utString,"EncodingScheme")!=0)) {
+	    wxDebugMsg("AFM-file '%s': line '%s' has error (bad EncodingScheme)\n",
+		       afmName,line);
+          }
+          else if (strncmp(encString, "AdobeStandardEncoding", 21))
+          {
+	    wxDebugMsg("AFM-file '%s': line '%s' has error (unsupported EncodingScheme %s)\n",
+		       afmName,line, encString);
+          }
+        }
+            // B.) check for char-width
+        else if(strncmp(line,"C ",2)==0){
+          if(sscanf(line,"%s%d%s%s%d",
+              cString,&ascii,semiString,WXString,&cWidth)!=5){
+             wxDebugMsg("AFM-file '%s': line '%s' has an error (bad character width)\n",afmName,line);
+          }
+          if(strcmp(cString,"C")!=0 || strcmp(semiString,";")!=0 ||
+             strcmp(WXString,"WX")!=0){
+             wxDebugMsg("AFM-file '%s': line '%s' has a format error\n",afmName,line);
+          }
+          //printf("            char '%c'=%d has width '%d'\n",ascii,ascii,cWidth);
+          if(ascii>=0 && ascii<256){
+            lastWidths[ascii] = cWidth; // store width
+          }else{
+	    /* MATTHEW: this happens a lot; don't print an error */
+            // wxDebugMsg("AFM-file '%s': ASCII value %d out of range\n",afmName,ascii);
+          }
+        }
+        // C.) ignore other entries.
+      }
+      fclose(afmFile);
+    }
+        // hack to compute correct values for german 'Umlaute'
+        // the correct way would be to map the character names
+        // like 'adieresis' to corresp. positions of ISOEnc and read
+        // these values from AFM files, too. Maybe later ...
+    lastWidths[196] = lastWidths['A'];  // Ä
+    lastWidths[228] = lastWidths['a'];  // ä
+    lastWidths[214] = lastWidths['O'];  // Ö
+    lastWidths[246] = lastWidths['o'];  // ö
+    lastWidths[220] = lastWidths['U'];  // Ü
+    lastWidths[252] = lastWidths['u'];  // ü
+    lastWidths[223] = lastWidths[251];  // ß
+  }
+
+      // JC: calculate UnderlineThickness/UnderlinePosition
+  UnderlinePosition = UnderlinePosition * fontToUse->GetPointSize() / 1000.0f;
+  UnderlineThickness = UnderlineThickness * fontToUse->GetPointSize() / 1000.0f * m_scaleFactor;
+
+  // 3. now the font metrics are read in, calc size *******************
+  // this is done by adding the widths of the characters in the
+  // string. they are given in 1/1000 of the size!
+
+  long widthSum=0;
+  long height=Size; // by default
+  unsigned char *p;
+  for(p=(unsigned char *)(const char *)string; *p; p++){
+    if(lastWidths[*p]== INT_MIN){
+      wxDebugMsg("GetTextExtent: undefined width for character '%c' (%d)\n",
+                 *p,*p);
+      widthSum += (long)(lastWidths[' ']/1000.0F * Size); // assume space
+    }else{
+      widthSum += (long)((lastWidths[*p]/1000.0F)*Size);
+    }
+  }
+  // add descender to height (it is usually a negative value)
+  if(lastDescender!=INT_MIN){
+    height += (long)(((-lastDescender)/1000.0F) * Size); /* MATTHEW: forgot scale */
+  }
+  
+  // return size values
+  *x = widthSum;
+  *y = height;
+
+  // return other parameters
+  if (descent){
+    if(lastDescender!=INT_MIN){
+      *descent = (long)(((-lastDescender)/1000.0F) * Size); /* MATTHEW: forgot scale */
+    }else{
+      *descent = 0;
+    }
+  }
+
+  // currently no idea how to calculate this!
+  // if (externalLeading) *externalLeading = 0;
+  if (externalLeading)
+    *externalLeading = 0;
+
+  // ----- end of contributed code -----
+#endif
+}
+
+void wxPostScriptDC::DrawOpenSpline( wxList *points )
+{
+	double		a, b, c, d, x1, y1, x2, y2, x3, y3;
+        wxPoint *p, *q;
+
+        wxNode *node = points->First();
+        p = (wxPoint *)node->Data();
+
+	x1 = p->x; y1 = p->y;
+
+        node = node->Next();
+        p = (wxPoint *)node->Data();
+	c = p->x; d = p->y;
+        x3 = a = (double)(x1 + c) / 2;
+        y3 = b = (double)(y1 + d) / 2;
+
+        *(GetStream()) << "newpath " << x1 << " " << GetYOrigin() - y1 << " moveto " << x3 << " " << GetYOrigin() - y3;
+        *(GetStream()) << " lineto\n";
+        CalcBoundingBox( (long)x1, (long)(GetYOrigin() - y1));
+        CalcBoundingBox( (long)x3, (long)(GetYOrigin() - y3));
+
+        while ((node = node->Next()) != NULL)
+	{
+          q = (wxPoint *)node->Data();
+
+	  x1 = x3; y1 = y3;
+	  x2 = c;  y2 = d;
+	  c = q->x; d = q->y;
+          x3 = (double)(x2 + c) / 2;
+          y3 = (double)(y2 + d) / 2;
+          *(GetStream()) << x1 << " " << GetYOrigin() - y1 << " " << x2 << " " << GetYOrigin() - y2 << " ";
+          *(GetStream()) << x3 << " " << GetYOrigin() - y3 << " DrawSplineSection\n";
+
+          CalcBoundingBox( (long)x1, (long)(GetYOrigin() - y1));
+          CalcBoundingBox( (long)x3, (long)(GetYOrigin() - y3));
+        }
+	/*
+	* At this point, (x2,y2) and (c,d) are the position of the 
+	* next-to-last and last point respectively, in the point list
+	*/
+        *(GetStream()) << c << " " << GetYOrigin() - d << " lineto stroke\n";
+}
+
+long wxPostScriptDC::GetCharWidth (void)
+{
+	// Chris Breeze: reasonable approximation using wxMODERN/Courier
+	return (long) (GetCharHeight() * 72.0 / 120.0);
+}
+
+
+void wxPostScriptDC::SetMapMode (int mode)
+{
+  	m_mappingMode = mode;
+	SetLogicalOrigin(0, 0);
+	if(m_mappingMode == MM_METRIC)
+	{
+		SetUserScale(72.0f / 25.4f, 72.0f / 25.4f);
+	}
+	else
+	{
+		SetUserScale(1.0, 1.0);
+	}
+  return;
+}
+
+/*
+ * Set the logical origin.
+ * Actually we are setting the printer's origin and since
+ * postscript transformations are cumulative we need to reset
+ * the previous origin. We also need to allow for the user scale
+ * factor (which affects printer coords but not logical)
+ */
+void wxPostScriptDC::SetLogicalOrigin(long x, long y)
+{
+	if (m_scaleFactor)
+	{
+		long xOffset = (long) ((m_logicalOriginX - x) / m_scaleFactor);
+		long yOffset = (long) ((y - m_logicalOriginY) / m_scaleFactor);
+
+		if (m_pstream)
+		{
+			*m_pstream << xOffset << " " << yOffset << " translate\n";
+		}
+	}
+  	m_logicalOriginX = x;
+  	m_logicalOriginY = y;
+}
+
+/*
+ * Obsolete - now performed by SetUserScale() and SetLogicalOrigin()
+ */
+void
+wxPostScriptDC::SetupCTM()
+{
+}
+
+/*
+ * Set the user scale.
+ * NB: Postscript transformations are cumulative and so we
+ * need to take into account the current scale. Also, this
+ * affects the logical origin
+ */
+void wxPostScriptDC::SetUserScale (double x, double y)
+{
+	// reset logical origin
+	long xOrg = m_logicalOriginX;
+	long yOrg = m_logicalOriginY;
+	SetLogicalOrigin(0, 0);
+
+	// set new scale factor
+	double factor = x;
+	if (m_scaleFactor)
+	{
+		factor /= m_scaleFactor;
+	}
+	if (m_pstream)
+	{
+		*m_pstream << factor << " " << factor << " scale\n";
+	}
+
+	// set logical origin at new scale
+	SetLogicalOrigin(xOrg, yOrg);
+
+  	m_userScaleX = x;
+  	m_userScaleY = y;
+
+  	m_scaleFactor = m_userScaleX;
+}
+
+long wxPostScriptDC::DeviceToLogicalX (int x) const
+{
+  return  x;
+}
+
+long wxPostScriptDC::DeviceToLogicalXRel (int x) const
+{
+  return  x;
+}
+
+long wxPostScriptDC::DeviceToLogicalY (int y) const
+{
+  return  y;
+}
+
+long wxPostScriptDC::DeviceToLogicalYRel (int y) const
+{
+  return  y;
+}
+
+long wxPostScriptDC::LogicalToDeviceX (long x) const
+{
+  return x;
+}
+
+long wxPostScriptDC::LogicalToDeviceXRel (long x) const
+{
+  return x;
+}
+
+long wxPostScriptDC::LogicalToDeviceY (long y) const
+{
+  return y;
+}
+
+long wxPostScriptDC::LogicalToDeviceYRel (long y) const
+{
+  return y;
+}
+
+void wxPostScriptDC::GetSize(int* width, int* height) const
+{
+  char *paperType = wxThePrintSetupData->GetPaperName();
+  if (!paperType)
+    paperType = "A4 210 x 297 mm";
+
+  wxPrintPaperType *paper = wxThePrintPaperDatabase->FindPaperType(paperType);
+  if (!paper)
+    paper = wxThePrintPaperDatabase->FindPaperType("A4 210 x 297 mm");
+  if (paper)
+  {
+    *width = paper->widthPixels;
+    *height = paper->heightPixels;
+  }
+  else
+  {
+    *width = 1000;
+    *height = 1000;
+  }
+}
+
+void wxPostScriptDC::GetSizeMM(long *width, long *height) const
+{
+  char *paperType = wxThePrintSetupData->GetPaperName();
+  if (!paperType)
+    paperType = "A4 210 x 297 mm";
+
+  wxPrintPaperType *paper = wxThePrintPaperDatabase->FindPaperType(paperType);
+  if (!paper)
+    paper = wxThePrintPaperDatabase->FindPaperType("A4 210 x 297 mm");
+  if (paper)
+  {
+    *width = paper->widthMM;
+    *height = paper->heightMM;
+  }
+  else
+  {
+    *width = 1000;
+    *height = 1000;
+  }
+}
+
+void wxPostScriptDC::CalcBoundingBox(long x, long y)
+{
+    long device_x = (long) (x - m_logicalOriginX * m_scaleFactor);
+    long device_y = (long) (y + m_logicalOriginY * m_scaleFactor);
+
+    if (device_x < m_minX) m_minX = device_x;
+    if (device_y < m_minY) m_minY = device_y;
+    if (device_x > m_maxX) m_maxX = device_x;
+    if (device_y > m_maxY) m_maxY = device_y;
+}
+
+IMPLEMENT_CLASS(wxPostScriptPrintDialog, wxDialog)
+
+wxPostScriptPrintDialog::wxPostScriptPrintDialog (wxWindow *parent, const wxString& title,
+		    const wxPoint& pos, const wxSize& size, const long style):
+wxDialog(parent, -1, title, pos, size, style)
+{
+  wxBeginBusyCursor();
+  char buf[100];
+
+  wxButton *okBut = new wxButton (this, wxID_OK, _("OK"), wxPoint(5, 5));
+  (void) new wxButton (this, wxID_CANCEL, _("Cancel"), wxPoint(40, 5));
+  okBut->SetDefault();
+
+  int yPos = 30;
+
+#ifdef __X__
+  (void) new wxStaticText(this, -1, "Printer Command: ", wxPoint(5, yPos));
+  wxTextCtrl *text_prt = new wxTextCtrl(this, wxID_PRINTER_COMMAND, wxThePrintSetupData->GetPrinterCommand(), wxPoint(100, yPos), wxSize(100, -1));
+
+  (void) new wxStaticText(this, -1, "Printer Options: ", wxPoint(210, yPos));
+  wxTextCtrl *text0 = new wxTextCtrl(this, wxID_PRINTER_OPTIONS, wxThePrintSetupData->GetPrinterOptions(), wxPoint(305, -1), wxSize(150, -1));
+
+  yPos += 25;
+#endif
+
+  wxString orientation[2];
+  orientation[0] = "Portrait";
+  orientation[1] = "Landscape";
+
+  wxRadioBox *radio0 = new wxRadioBox(this, wxID_PRINTER_ORIENTATION, "Orientation: ", wxPoint(5, yPos), wxSize(-1,-1),
+  		2,orientation,2,0);
+  radio0->SetSelection((int)wxThePrintSetupData->GetPrinterOrientation());
+
+  // @@@ Configuration hook
+  if (wxThePrintSetupData->GetPrintPreviewCommand() == NULL)
+    wxThePrintSetupData->SetPrintPreviewCommand(PS_VIEWER_PROG);
+
+  wxGetResource ("wxWindows", "PSView", &wxThePrintSetupData->previewCommand);
+
+  wxString print_modes[3];
+  print_modes[0] = "Send to Printer";
+  print_modes[1] = "Print to File";
+  print_modes[2] = "Preview Only";
+
+  int features = (wxThePrintSetupData->GetPrintPreviewCommand() && *wxThePrintSetupData->GetPrintPreviewCommand()) ? 3 : 2;
+  wxRadioBox *radio1 = new wxRadioBox(this, wxID_PRINTER_MODES, "PostScript:",
+    wxPoint(150, yPos), wxSize(-1,-1), features, print_modes, features, 0);
+
+#ifdef __WINDOWS__
+  radio1->Enable(0, FALSE);
+  if (wxThePrintSetupData->GetPrintPreviewCommand() && *wxThePrintSetupData->GetPrintPreviewCommand())
+    radio1->Enable(2, FALSE);
+#endif
+
+  radio1->SetSelection((int)wxThePrintSetupData->GetPrinterMode());
+  
+  long wx_printer_translate_x, wx_printer_translate_y;
+  double wx_printer_scale_x, wx_printer_scale_y;
+  wxThePrintSetupData->GetPrinterTranslation(&wx_printer_translate_x, &wx_printer_translate_y);
+  wxThePrintSetupData->GetPrinterScaling(&wx_printer_scale_x, &wx_printer_scale_y);
+
+  sprintf (buf, "%.2f", wx_printer_scale_x);
+
+  yPos += 60;
+
+  (void) new wxStaticText(this, -1, "X Scaling", wxPoint(5, yPos));
+  /* wxTextCtrl *text1 = */ (void) new wxTextCtrl(this, wxID_PRINTER_X_SCALE, buf, wxPoint(100, -1), wxSize(100, -1));
+
+  sprintf (buf, "%.2f", wx_printer_scale_y);
+  (void) new wxStaticText(this, -1, "Y Scaling", wxPoint(120, yPos));
+  /* wxTextCtrl *text2 = */ (void) new wxTextCtrl(this, wxID_PRINTER_Y_SCALE, buf, wxPoint(230, -1), wxSize(100, -1));
+
+  yPos += 25;
+
+  (void) new wxStaticText(this, -1, "X Translation", wxPoint(5, yPos));
+  sprintf (buf, "%.2f", wx_printer_translate_x);
+  /* wxTextCtrl *text3 = */ (void) new wxTextCtrl(this, wxID_PRINTER_X_TRANS, buf, wxPoint(100, -1), wxSize(100, -1));
+
+  (void) new wxStaticText(this, -1, "Y Translation", wxPoint(120, yPos));
+  sprintf (buf, "%.2f", wx_printer_translate_y);
+  /* wxTextCtrl *text4 = */ (void) new wxTextCtrl(this, wxID_PRINTER_Y_TRANS, buf, wxPoint(230, -1), wxSize(100, -1));
+
+  Fit ();
+
+  wxEndBusyCursor();
+}
+
+int wxPostScriptPrintDialog::ShowModal (void)
+{
+  if ( wxDialog::ShowModal() == wxID_OK )
+  {
+//	  wxTextCtrl *text0 = (wxTextCtrl *)FindWindow(wxID_PRINTER_OPTIONS);
+	  wxTextCtrl *text1 = (wxTextCtrl *)FindWindow(wxID_PRINTER_X_SCALE);
+	  wxTextCtrl *text2 = (wxTextCtrl *)FindWindow(wxID_PRINTER_Y_SCALE);
+	  wxTextCtrl *text3 = (wxTextCtrl *)FindWindow(wxID_PRINTER_X_TRANS);
+	  wxTextCtrl *text4 = (wxTextCtrl *)FindWindow(wxID_PRINTER_Y_TRANS);
+//	  wxTextCtrl *text_prt = (wxTextCtrl *)FindWindow(wxID_PRINTER_COMMAND);
+	  wxRadioBox *radio0 = (wxRadioBox *)FindWindow(wxID_PRINTER_ORIENTATION);
+	  wxRadioBox *radio1 = (wxRadioBox *)FindWindow(wxID_PRINTER_MODES);
+
+      StringToDouble (WXSTRINGCAST text1->GetValue (), &wxThePrintSetupData->printerScaleX);
+      StringToDouble (WXSTRINGCAST text2->GetValue (), &wxThePrintSetupData->printerScaleY);
+      StringToLong (WXSTRINGCAST text3->GetValue (), &wxThePrintSetupData->printerTranslateX);
+      StringToLong (WXSTRINGCAST text4->GetValue (), &wxThePrintSetupData->printerTranslateY);
+
+#ifdef __X__
+      wxThePrintSetupData->SetPrinterOptions(WXSTRINGCAST text0->GetValue ());
+      wxThePrintSetupData->SetPrinterCommand(WXSTRINGCAST text_prt->GetValue ());
+#endif
+
+      wxThePrintSetupData->SetPrinterOrientation((radio0->GetSelection() == PS_LANDSCAPE ? PS_LANDSCAPE : PS_PORTRAIT));
+
+      // C++ wants this
+      switch ( radio1->GetSelection() ) {
+		case PS_PREVIEW: wxThePrintSetupData->SetPrinterMode(PS_PREVIEW); break;
+		case PS_FILE:    wxThePrintSetupData->SetPrinterMode(PS_FILE);    break;
+		case PS_PRINTER: wxThePrintSetupData->SetPrinterMode(PS_PRINTER); break;
+      }
+	  return wxID_OK;
+  }
+  return wxID_CANCEL;
+}
+
+// PostScript printer settings
+// RETAINED FOR BACKWARD COMPATIBILITY
+void wxSetPrinterCommand(char *cmd)
+{
+  wxThePrintSetupData->SetPrinterCommand(cmd);
+}
+
+void wxSetPrintPreviewCommand(char *cmd)
+{
+  wxThePrintSetupData->SetPrintPreviewCommand(cmd);
+}
+
+void wxSetPrinterOptions(char *flags)
+{
+  wxThePrintSetupData->SetPrinterOptions(flags);
+}
+
+void wxSetPrinterFile(char *f)
+{
+  wxThePrintSetupData->SetPrinterFile(f);
+}
+
+void wxSetPrinterOrientation(int orient)
+{
+  wxThePrintSetupData->SetPrinterOrientation(orient);
+}
+
+void wxSetPrinterScaling(double x, double y)
+{
+  wxThePrintSetupData->SetPrinterScaling(x, y);
+}
+
+void wxSetPrinterTranslation(long x, long y)
+{
+  wxThePrintSetupData->SetPrinterTranslation(x, y);
+}
+
+// 1 = Preview, 2 = print to file, 3 = send to printer
+void wxSetPrinterMode(int mode)
+{
+  wxThePrintSetupData->SetPrinterMode(mode);
+}
+
+void wxSetAFMPath(char *f)
+{
+  wxThePrintSetupData->SetAFMPath(f);
+}
+
+// Get current values
+char *wxGetPrinterCommand(void)
+{
+  return wxThePrintSetupData->GetPrinterCommand();
+}
+
+char *wxGetPrintPreviewCommand(void)
+{
+  return wxThePrintSetupData->GetPrintPreviewCommand();
+}
+
+char *wxGetPrinterOptions(void)
+{
+  return wxThePrintSetupData->GetPrinterOptions();
+}
+
+char *wxGetPrinterFile(void)
+{
+  return wxThePrintSetupData->GetPrinterFile();
+}
+
+int wxGetPrinterOrientation(void)
+{
+  return wxThePrintSetupData->GetPrinterOrientation();
+}
+
+void wxGetPrinterScaling(double* x, double* y)
+{
+  wxThePrintSetupData->GetPrinterScaling(x, y);
+}
+
+void wxGetPrinterTranslation(long *x, long *y)
+{
+  wxThePrintSetupData->GetPrinterTranslation(x, y);
+}
+
+int wxGetPrinterMode(void)
+{
+  return wxThePrintSetupData->GetPrinterMode();
+}
+
+char *wxGetAFMPath(void)
+{
+  return wxThePrintSetupData->GetAFMPath();
+}
+
+/*
+ * Print setup data
+ */
+
+wxPrintSetupData::wxPrintSetupData(void)
+{
+  printerCommand = NULL;
+  previewCommand = NULL;
+  printerFlags = NULL;
+  printerOrient = PS_PORTRAIT;
+  printerScaleX = (double)1.0;
+  printerScaleY = (double)1.0;
+  printerTranslateX = 0;
+  printerTranslateY = 0;
+  // 1 = Preview, 2 = print to file, 3 = send to printer
+  printerMode = 3;
+  afmPath = NULL;
+  paperName = NULL;
+  printColour = TRUE;
+  printerFile = NULL;
+}
+
+wxPrintSetupData::~wxPrintSetupData(void)
+{
+  if (printerCommand)
+    delete[] printerCommand;
+  if (previewCommand)
+    delete[] previewCommand;
+  if (printerFlags)
+    delete[] printerFlags;
+  if (afmPath)
+    delete[] afmPath;
+  if (paperName)
+    delete[] paperName;
+  if (printerFile)
+    delete[] printerFile;
+}
+
+void wxPrintSetupData::SetPrinterCommand(char *cmd)
+{
+  if (cmd == printerCommand)
+    return;
+
+  if (printerCommand)
+    delete[] printerCommand;
+  if (cmd)
+    printerCommand = copystring(cmd);
+  else
+    printerCommand = NULL;
+}
+
+void wxPrintSetupData::SetPrintPreviewCommand(char *cmd)
+{
+  if (cmd == previewCommand)
+    return;
+    
+  if (previewCommand)
+    delete[] previewCommand;
+  if (cmd)
+    previewCommand = copystring(cmd);
+  else
+    previewCommand = NULL;
+}
+
+void wxPrintSetupData::SetPaperName(char *name)
+{
+  if (name == paperName)
+    return;
+
+  if (paperName)
+    delete[] paperName;
+  if (name)
+    paperName = copystring(name);
+  else
+    paperName = NULL;
+}
+
+void wxPrintSetupData::SetPrinterOptions(char *flags)
+{
+  if (printerFlags == flags)
+    return;
+   
+  if (printerFlags)
+    delete[] printerFlags;
+  if (flags)
+    printerFlags = copystring(flags);
+  else
+    printerFlags = NULL;
+}
+
+void wxPrintSetupData::SetPrinterFile(char *f)
+{
+  if (f == printerFile)
+    return;
+    
+  if (printerFile)
+    delete[] printerFile;
+  if (f)
+    printerFile = copystring(f);
+  else
+    printerFile = NULL;
+}
+
+void wxPrintSetupData::SetPrinterOrientation(int orient)
+{
+  printerOrient = orient;
+}
+
+void wxPrintSetupData::SetPrinterScaling(double x, double y)
+{
+  printerScaleX = x;
+  printerScaleY = y;
+}
+
+void wxPrintSetupData::SetPrinterTranslation(long x, long y)
+{
+  printerTranslateX = x;
+  printerTranslateY = y;
+}
+
+// 1 = Preview, 2 = print to file, 3 = send to printer
+void wxPrintSetupData::SetPrinterMode(int mode)
+{
+  printerMode = mode;
+}
+
+void wxPrintSetupData::SetAFMPath(char *f)
+{
+  if (f == afmPath)
+    return;
+    
+  if (afmPath)
+    delete[] afmPath;
+  if (f)
+    afmPath = copystring(f);
+  else
+    afmPath = NULL;
+}
+
+void wxPrintSetupData::SetColour(bool col)
+{
+  printColour = col;
+}
+
+// Get current values
+char *wxPrintSetupData::GetPrinterCommand(void)
+{
+  return printerCommand;
+}
+
+char *wxPrintSetupData::GetPrintPreviewCommand(void)
+{
+  return previewCommand;
+}
+
+char *wxPrintSetupData::GetPrinterOptions(void)
+{
+  return printerFlags;
+}
+
+char *wxPrintSetupData::GetPrinterFile(void)
+{
+  return printerFile;
+}
+
+char *wxPrintSetupData::GetPaperName(void)
+{
+  return paperName;
+}
+
+int wxPrintSetupData::GetPrinterOrientation(void)
+{
+  return printerOrient;
+}
+
+void wxPrintSetupData::GetPrinterScaling(double *x, double *y)
+{
+  *x = printerScaleX;
+  *y = printerScaleY;
+}
+
+void wxPrintSetupData::GetPrinterTranslation(long *x, long *y)
+{
+  *x = printerTranslateX;
+  *y = printerTranslateY;
+}
+
+int wxPrintSetupData::GetPrinterMode(void)
+{
+  return printerMode;
+}
+
+char *wxPrintSetupData::GetAFMPath(void)
+{
+  return afmPath;
+}
+
+bool wxPrintSetupData::GetColour(void)
+{
+  return printColour;
+}
+
+void wxPrintSetupData::operator=(wxPrintSetupData& data)
+{
+  SetPrinterCommand(data.GetPrinterCommand());
+  SetPrintPreviewCommand(data.GetPrintPreviewCommand());
+  SetPrinterOptions(data.GetPrinterOptions());
+  long x, y;
+  data.GetPrinterTranslation(&x, &y);
+  SetPrinterTranslation(x, y);
+
+  double x1, y1;
+  data.GetPrinterScaling(&x1, &y1);
+  SetPrinterScaling(x1, y1);
+
+  SetPrinterOrientation(data.GetPrinterOrientation());
+  SetPrinterMode(data.GetPrinterMode());
+  SetAFMPath(data.GetAFMPath());
+  SetPaperName(data.GetPaperName());
+  SetColour(data.GetColour());
+}
+
+void wxInitializePrintSetupData(bool init)
+{
+  if (init)
+  {
+    wxThePrintSetupData = new wxPrintSetupData;
+
+    wxThePrintSetupData->SetPrintPreviewCommand(PS_VIEWER_PROG);
+    wxThePrintSetupData->SetPrinterOrientation(PS_PORTRAIT);
+    wxThePrintSetupData->SetPrinterMode(PS_PREVIEW);
+    wxThePrintSetupData->SetPaperName("A4 210 x 297 mm");
+
+    // Could have a .ini file to read in some defaults
+    // - and/or use environment variables, e.g. WXWIN
+#ifdef __VMS__
+    wxThePrintSetupData->SetPrinterCommand("print");
+    wxThePrintSetupData->SetPrinterOptions("/nonotify/queue=psqueue");
+    wxThePrintSetupData->SetAFMPath("sys$ps_font_metrics:");
+#endif
+#ifdef __WINDOWS__
+    wxThePrintSetupData->SetPrinterCommand("print");
+    wxThePrintSetupData->SetAFMPath("c:\\windows\\system\\");
+    wxThePrintSetupData->SetPrinterOptions(NULL);
+#endif
+#if !defined(__VMS__) && !defined(__WINDOWS__)
+    wxThePrintSetupData->SetPrinterCommand("lpr");
+    wxThePrintSetupData->SetPrinterOptions(NULL);
+    wxThePrintSetupData->SetAFMPath(NULL);
+#endif
+  }
+  else
+  {
+    if (wxThePrintSetupData)
+      delete wxThePrintSetupData;
+     wxThePrintSetupData = NULL;
+  }
+}
+
+/*
+ * Paper size database for PostScript
+ */
+
+wxPrintPaperType::wxPrintPaperType(char *name, int wmm, int hmm, int wp, int hp)
+{
+  widthMM = wmm;
+  heightMM = hmm;
+  widthPixels = wp;
+  heightPixels = hp;
+  pageName = copystring(name);
+}
+
+wxPrintPaperType::~wxPrintPaperType(void)
+{
+  delete[] pageName;
+}
+
+wxPrintPaperDatabase::wxPrintPaperDatabase(void):wxList(wxKEY_STRING)
+{
+  DeleteContents(TRUE);
+}
+
+wxPrintPaperDatabase::~wxPrintPaperDatabase(void)
+{
+}
+
+void wxPrintPaperDatabase::CreateDatabase(void)
+{
+  // Need correct values for page size in pixels.
+  // Each unit is one 'point' = 1/72 of an inch.
+  // NOTE: WE NEED ALSO TO MAKE ADJUSTMENTS WHEN TRANSLATING
+  // in wxPostScriptDC code, so we can start from top left.
+  // So access this database and translate by appropriate number
+  // of points for this paper size. OR IS IT OK ALREADY?
+  // Can't remember where the PostScript origin is by default.
+  // Heck, someone will know how to make it hunky-dory...
+  // JACS 25/5/95
+  
+  AddPaperType("A4 210 x 297 mm", 210, 297,         595, 842);
+  AddPaperType("A3 297 x 420 mm", 297, 420,         842, 1191);
+  AddPaperType("Letter 8 1/2 x 11 in", 216, 279,    612, 791);
+  AddPaperType("Legal 8 1/2 x 14 in", 216, 356,     612, 1009);
+}
+
+void wxPrintPaperDatabase::ClearDatabase(void)
+{
+  Clear();
+}
+
+void wxPrintPaperDatabase::AddPaperType(char *name, int wmm, int hmm, int wp, int hp)
+{
+  Append(name, new wxPrintPaperType(name, wmm, hmm, wp, hp));
+}
+
+wxPrintPaperType *wxPrintPaperDatabase::FindPaperType(char *name)
+{
+  wxNode *node = Find(name);
+  if (node)
+    return (wxPrintPaperType *)node->Data();
+  else
+    return NULL;
+}
+
+#endif
diff --git a/src/common/prntbase.cpp b/src/common/prntbase.cpp
new file mode 100644
index 0000000000..f4548a401d
--- /dev/null
+++ b/src/common/prntbase.cpp
@@ -0,0 +1,784 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        prntbase.cpp
+// Purpose:     Printing framework base class implementation
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "prntbase.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+// #define __GOOD_COMPILER__
+
+#include "wx/defs.h"
+
+#ifndef WX_PRECOMP
+#include "wx/utils.h"
+#include "wx/dc.h"
+#include "wx/app.h"
+#include "wx/msgdlg.h"
+#include "wx/layout.h"
+#include "wx/choice.h"
+#include "wx/button.h"
+#include "wx/settings.h"
+#include "wx/dcmemory.h"
+#include "wx/stattext.h"
+#include "wx/intl.h"
+#endif
+
+#include "wx/prntbase.h"
+#include "wx/dcprint.h"
+#include "wx/printdlg.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __WINDOWS__
+#include <windows.h>
+#include <commdlg.h>
+
+// Clash with Windows header files
+#ifdef StartDoc
+#undef StartDoc
+#endif
+
+#ifndef __WIN32__
+#include <print.h>
+#endif
+
+#if !defined(APIENTRY)	// NT defines APIENTRY, 3.x not
+#define APIENTRY FAR PASCAL
+#endif
+ 
+#ifdef __WIN32__
+#define _EXPORT /**/
+#else
+#define _EXPORT _export
+typedef signed short int SHORT ;
+#endif
+ 
+#if !defined(__WIN32__)	// 3.x uses FARPROC for dialogs
+#define DLGPROC FARPROC
+#endif
+
+LONG APIENTRY _EXPORT wxAbortProc(HDC hPr, int Code);
+#endif
+ // End __WINDOWS__
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_CLASS(wxPrinterBase, wxObject)
+IMPLEMENT_ABSTRACT_CLASS(wxPrintout, wxObject)
+IMPLEMENT_CLASS(wxPreviewCanvas, wxWindow)
+IMPLEMENT_CLASS(wxPreviewControlBar, wxWindow)
+IMPLEMENT_CLASS(wxPreviewFrame, wxFrame)
+IMPLEMENT_CLASS(wxPrintPreviewBase, wxObject)
+
+BEGIN_EVENT_TABLE(wxPrintAbortDialog, wxDialog)
+	EVT_BUTTON(wxID_CANCEL, wxPrintAbortDialog::OnCancel)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxPreviewCanvas, wxScrolledWindow)
+    EVT_PAINT(wxPreviewCanvas::OnPaint)
+    EVT_SYS_COLOUR_CHANGED(wxPreviewCanvas::OnSysColourChanged)
+END_EVENT_TABLE()
+#endif
+
+/*
+ * Printer
+ */
+ 
+wxPrinterBase::wxPrinterBase(wxPrintData *data)
+{
+  currentPrintout = NULL;
+  abortWindow = NULL;
+  abortIt = FALSE;
+  if (data)
+    printData = (*data);
+}
+
+wxWindow *wxPrinterBase::abortWindow = NULL;
+bool wxPrinterBase::abortIt = FALSE;
+
+wxPrinterBase::~wxPrinterBase(void)
+{
+}
+
+void wxPrintAbortDialog::OnCancel(wxCommandEvent& WXUNUSED(event))
+{
+  wxPrinterBase::abortIt = TRUE;
+  wxPrinterBase::abortWindow->Show(FALSE);
+  wxPrinterBase::abortWindow->Close(TRUE);
+  wxPrinterBase::abortWindow = NULL;
+}
+
+wxWindow *wxPrinterBase::CreateAbortWindow(wxWindow *parent, wxPrintout *WXUNUSED(printout))
+{
+  wxPrintAbortDialog *dialog = new wxPrintAbortDialog(parent, _("Printing"), wxPoint(0, 0), wxSize(400, 400));
+  (void) new wxStaticText(dialog, -1, _("Please wait..."), wxPoint(5, 5));
+
+  wxButton *button = new wxButton(dialog, wxID_CANCEL, _("Cancel"), wxPoint(5, 30));
+
+  dialog->Fit();
+  button->Centre(wxHORIZONTAL);
+
+  dialog->Centre();
+  return dialog;
+}
+
+void wxPrinterBase::ReportError(wxWindow *parent, wxPrintout *WXUNUSED(printout), char *message)
+{
+  wxMessageBox(message, "Printing Error", wxOK, parent);
+}
+
+/*
+ * Printout class
+ */
+ 
+wxPrintout::wxPrintout(char *title)
+{
+  printoutTitle = title ? copystring(title) : (char*)NULL;
+  printoutDC = NULL;
+  pageWidthMM = 0;
+  pageHeightMM = 0;
+  pageWidthPixels = 0;
+  pageHeightPixels = 0;
+  PPIScreenX = 0;
+  PPIScreenY = 0;
+  PPIPrinterX = 0;
+  PPIPrinterY = 0;
+  isPreview = FALSE;
+}
+
+wxPrintout::~wxPrintout(void)
+{
+  if (printoutTitle)
+    delete[] printoutTitle;
+}
+
+bool wxPrintout::OnBeginDocument(int WXUNUSED(startPage), int WXUNUSED(endPage))
+{
+  return GetDC()->StartDoc("Printing");
+}
+
+void wxPrintout::OnEndDocument(void)
+{
+  GetDC()->EndDoc();
+}
+
+void wxPrintout::OnBeginPrinting(void)
+{
+}
+
+void wxPrintout::OnEndPrinting(void)
+{
+}
+
+bool wxPrintout::HasPage(int page)
+{
+  return (page == 1);
+}
+
+void wxPrintout::GetPageInfo(int *minPage, int *maxPage, int *fromPage, int *toPage)
+{
+  *minPage = 1;
+  *maxPage = 32000;
+  *fromPage = 1;
+  *toPage = 1;
+}
+
+/*
+ * Preview canvas
+ */
+ 
+wxPreviewCanvas::wxPreviewCanvas(wxPrintPreviewBase *preview, wxWindow *parent,
+		const wxPoint& pos, const wxSize& size, long style, const wxString& name):
+ wxScrolledWindow(parent, -1, pos, size, style, name)
+{
+  printPreview = preview;
+  SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
+
+  SetScrollbars(40, 40, 100, 100);
+}
+
+wxPreviewCanvas::~wxPreviewCanvas(void)
+{
+}
+
+void wxPreviewCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
+{
+  wxPaintDC dc(this);
+
+  if (printPreview)
+  {
+    printPreview->PaintPage(this, dc);
+  }
+}
+
+// Responds to colour changes, and passes event on to children.
+void wxPreviewCanvas::OnSysColourChanged(wxSysColourChangedEvent& event)
+{
+  SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
+  Refresh();
+
+  // Propagate the event to the non-top-level children
+  wxWindow::OnSysColourChanged(event);
+}
+
+/*
+ * Preview control bar
+ */
+
+BEGIN_EVENT_TABLE(wxPreviewControlBar, wxPanel)
+	EVT_BUTTON(wxID_PREVIEW_CLOSE, 		wxPreviewControlBar::OnClose)
+	EVT_BUTTON(wxID_PREVIEW_PRINT, 		wxPreviewControlBar::OnPrint)
+	EVT_BUTTON(wxID_PREVIEW_PREVIOUS, 	wxPreviewControlBar::OnPrevious)
+	EVT_BUTTON(wxID_PREVIEW_NEXT, 		wxPreviewControlBar::OnNext)
+	EVT_CHOICE(wxID_PREVIEW_ZOOM, 		wxPreviewControlBar::OnZoom)
+    EVT_PAINT(wxPreviewControlBar::OnPaint)
+END_EVENT_TABLE()
+ 
+wxPreviewControlBar::wxPreviewControlBar(wxPrintPreviewBase *preview, long buttons,
+    wxWindow *parent, const wxPoint& pos, const wxSize& size,
+    long style, const wxString& name):
+  wxPanel(parent, -1, pos, size, style, name)
+{
+  printPreview = preview;
+  closeButton = NULL;
+  nextPageButton = NULL;
+  previousPageButton = NULL;
+  printButton = NULL;
+  zoomControl = NULL;
+  buttonFlags = buttons;
+}
+
+wxFont *wxPreviewControlBar::buttonFont = NULL;
+
+wxPreviewControlBar::~wxPreviewControlBar(void)
+{
+}
+
+void wxPreviewControlBar::OnPaint(wxPaintEvent& WXUNUSED(event))
+{
+  wxPaintDC dc(this);
+
+  int w, h;
+  GetSize(&w, &h);
+  dc.SetPen(*wxBLACK_PEN);
+  dc.SetBrush(*wxTRANSPARENT_BRUSH);
+  dc.DrawLine( 0, h-1, w, h-1 );
+}
+
+void wxPreviewControlBar::OnClose(wxCommandEvent& WXUNUSED(event))
+{
+  wxPreviewFrame *frame = (wxPreviewFrame *)GetParent();
+  frame->Close(TRUE);
+}
+
+void wxPreviewControlBar::OnPrint(wxCommandEvent& WXUNUSED(event))
+{
+  wxPrintPreviewBase *preview = GetPrintPreview();
+  preview->Print(TRUE);
+}
+
+void wxPreviewControlBar::OnNext(wxCommandEvent& WXUNUSED(event))
+{
+  wxPrintPreviewBase *preview = GetPrintPreview();
+  if (preview)
+  {
+    int currentPage = preview->GetCurrentPage();
+    if ((preview->GetMaxPage() > 0) &&
+        (currentPage < preview->GetMaxPage()) &&
+        preview->GetPrintout()->HasPage(currentPage + 1))
+    {
+      preview->SetCurrentPage(currentPage + 1);
+    }
+  }
+}
+
+void wxPreviewControlBar::OnPrevious(wxCommandEvent& WXUNUSED(event))
+{
+  wxPrintPreviewBase *preview = GetPrintPreview();
+  if (preview)
+  {
+    int currentPage = preview->GetCurrentPage();
+    if ((preview->GetMinPage() > 0) &&
+        (currentPage > preview->GetMinPage()) &&
+        preview->GetPrintout()->HasPage(currentPage - 1))
+    {
+      preview->SetCurrentPage(currentPage - 1);
+    }
+  }
+}
+
+void wxPreviewControlBar::OnZoom(wxCommandEvent& WXUNUSED(event))
+{
+  int zoom = GetZoomControl();
+  if (GetPrintPreview())
+    GetPrintPreview()->SetZoom(zoom);
+}
+
+void wxPreviewControlBar::CreateButtons(void)
+{
+#ifdef __GOOD_COMPILER__ // Robert Roebling
+
+  SetSize(0, 0, 400, 40);
+
+#ifdef __WINDOWS__
+  int fontSize = 9;
+#else
+  int fontSize = 10;
+#endif
+
+  if (!buttonFont)
+    buttonFont = wxTheFontList->FindOrCreateFont(fontSize, wxSWISS, wxNORMAL, wxBOLD);
+  SetButtonFont(*buttonFont);
+
+  int buttonWidth = 65;
+  int buttonHeight = 24;
+
+  int x = 5;
+  int y = 5;
+  int gap = 5;
+
+  closeButton = new wxButton(this, wxID_PREVIEW_CLOSE, "Close",
+  	wxPoint(x, y), wxSize(buttonWidth, buttonHeight));
+
+  x += gap + buttonWidth;
+  
+  if (buttonFlags & wxPREVIEW_PRINT)
+  {
+    printButton =  new wxButton(this, wxID_PREVIEW_PRINT, "Print...", wxPoint(x, y),
+		wxSize(buttonWidth, buttonHeight));
+	x += gap + buttonWidth;
+  }
+
+  if (buttonFlags & wxPREVIEW_PREVIOUS)
+  {
+    previousPageButton = new wxButton(this, wxID_PREVIEW_PREVIOUS, "<<", wxPoint(x, y),
+		wxSize(buttonWidth, buttonHeight));
+	x += gap + buttonWidth;
+  }
+
+  if (buttonFlags & wxPREVIEW_NEXT)
+  {
+    nextPageButton = new wxButton(this, wxID_PREVIEW_NEXT, ">>",
+	 	wxPoint(x, y), wxSize(buttonWidth, buttonHeight));
+	x += gap + buttonWidth;
+  }
+
+  static wxString choices[] = { "10%", "20%", "25%", "30%", "35%", "40%", "45%", "50%", "55%", "60%",
+    "65%", "70%", "75%", "80%", "85%", "90%", "95%", "100%", "110%", "120%", "150%", "200%" };
+  int n = 22;
+  if (buttonFlags & wxPREVIEW_ZOOM)
+  {
+    zoomControl = new wxChoice(this, wxID_PREVIEW_ZOOM, wxPoint(x, y),
+		wxSize(100, -1), n, (wxString *)choices);
+    SetZoomControl(printPreview->GetZoom());
+  }
+
+  closeButton->SetDefault();
+  
+#endif
+}
+
+void wxPreviewControlBar::SetZoomControl(int zoom)
+{
+#ifdef __GOOD_COMPILER__ // Robert Roebling
+  char buf[20];
+  sprintf(buf, "%d%%", zoom);
+  if (zoomControl)
+    zoomControl->SetStringSelection(buf);
+#endif
+}
+
+int wxPreviewControlBar::GetZoomControl(void)
+{
+#ifdef __GOOD_COMPILER__ // Robert Roebling
+  char buf[20];
+  if (zoomControl && zoomControl->GetStringSelection())
+  {
+    strcpy(buf, zoomControl->GetStringSelection());
+    buf[strlen(buf) - 1] = 0;
+    return (int)atoi(buf);
+  }
+  else return 0;
+#endif
+}
+
+
+/*
+ * Preview frame
+ */
+
+wxPreviewFrame::wxPreviewFrame(wxPrintPreviewBase *preview, wxFrame *parent, const wxString& title,
+    const wxPoint& pos, const wxSize& size, long style, const wxString& name):
+ wxFrame(parent, -1, title, pos, size, style, name)
+{
+#ifdef __GOOD_COMPILER__ // Robert Roebling
+
+  printPreview = preview;
+  controlBar = NULL;
+  previewCanvas = NULL;
+#endif
+}
+
+wxPreviewFrame::~wxPreviewFrame(void)
+{
+}
+
+bool wxPreviewFrame::OnClose(void)
+{
+#ifdef __GOOD_COMPILER__ // Robert Roebling
+
+  MakeModal(FALSE);
+  
+  // Need to delete the printout and the print preview
+  wxPrintout *printout = printPreview->GetPrintout();
+  if (printout)
+  {
+    delete printout;
+    printPreview->SetPrintout(NULL);
+    printPreview->SetCanvas(NULL);
+    printPreview->SetFrame(NULL);
+  }
+  delete printPreview;
+  return TRUE;
+#endif
+}
+
+void wxPreviewFrame::Initialize(void)
+{
+
+#ifdef __GOOD_COMPILER__ // Robert Roebling
+
+  CreateStatusBar();
+  
+  CreateCanvas();
+  CreateControlBar();
+
+  printPreview->SetCanvas(previewCanvas);
+  printPreview->SetFrame(this);
+
+  // Set layout constraints here
+
+  // Control bar constraints
+  wxLayoutConstraints *c1 = new wxLayoutConstraints;
+//  int w, h;
+//  controlBar->GetSize(&w, &h);
+  int h;
+#ifdef __WINDOWS__
+  h = 40;
+#else
+  h = 60;
+#endif
+
+  c1->left.SameAs       (this, wxLeft);
+  c1->top.SameAs        (this, wxTop);
+  c1->right.SameAs      (this, wxRight);
+  c1->height.Absolute   (h);
+
+  controlBar->SetConstraints(c1);
+
+  // Canvas constraints
+  wxLayoutConstraints *c2 = new wxLayoutConstraints;
+
+  c2->left.SameAs       (this, wxLeft);
+  c2->top.Below         (controlBar);
+  c2->right.SameAs      (this, wxRight);
+  c2->bottom.SameAs     (this, wxBottom);
+
+  previewCanvas->SetConstraints(c2);
+
+  SetAutoLayout(TRUE);
+
+  MakeModal(TRUE);
+
+  Layout();
+  
+#endif  
+}
+
+void wxPreviewFrame::CreateCanvas(void)
+{
+#ifdef __GOOD_COMPILER__ // Robert Roebling
+
+  previewCanvas = new wxPreviewCanvas(printPreview, this);
+  
+#endif
+}
+
+void wxPreviewFrame::CreateControlBar(void)
+{
+#ifdef __GOOD_COMPILER__ // Robert Roebling
+
+  long buttons = wxPREVIEW_DEFAULT;
+  if (printPreview->GetPrintoutForPrinting())
+    buttons |= wxPREVIEW_PRINT;
+    
+  controlBar = new wxPreviewControlBar(printPreview, buttons, this, wxPoint(0, 0), wxSize(400, 40));
+  controlBar->CreateButtons();
+#endif
+}
+ 
+/*
+ * Print preview
+ */
+
+wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout *printout, wxPrintout *printoutForPrinting, wxPrintData *data)
+{
+
+#ifdef __GOOD_COMPILER__ // Robert Roebling
+
+  isOk = TRUE;
+  previewPrintout = printout;
+  if (previewPrintout)
+    previewPrintout->SetIsPreview(TRUE);
+    
+  printPrintout = printoutForPrinting;
+  if (data)
+    printData = (*data);
+
+  previewCanvas = NULL;
+  previewFrame = NULL;
+  previewBitmap = NULL;
+  currentPage = 1;
+  currentZoom = 30;
+  topMargin = 40;
+  leftMargin = 40;
+  pageWidth = 0;
+  pageHeight = 0;
+
+  printout->OnPreparePrinting();
+
+  // Get some parameters from the printout, if defined
+  int selFrom, selTo;
+  printout->GetPageInfo(&minPage, &maxPage, &selFrom, &selTo);
+  
+#endif  
+}
+
+wxPrintPreviewBase::~wxPrintPreviewBase(void)
+{
+#ifdef __GOOD_COMPILER__ // Robert Roebling
+
+  if (previewPrintout)
+    delete previewPrintout;
+  if (previewBitmap)
+    delete previewBitmap;
+  if (printPrintout)
+    delete printPrintout;
+    
+#endif
+}
+
+bool wxPrintPreviewBase::SetCurrentPage(int pageNum)
+{
+#ifdef __GOOD_COMPILER__ // Robert Roebling
+  if (currentPage == pageNum)
+    return TRUE;
+
+  currentPage = pageNum;
+  if (previewBitmap)
+  {
+    delete previewBitmap;
+    previewBitmap = NULL;
+  }
+
+  if (previewCanvas)
+  {
+    RenderPage(pageNum);
+    previewCanvas->Refresh();
+  }
+  
+#endif
+  return TRUE;
+}
+
+bool wxPrintPreviewBase::PaintPage(wxWindow *canvas, wxDC& dc)
+{
+
+#ifdef __GOOD_COMPILER__  // Robert Roebling
+
+  DrawBlankPage(canvas, dc);
+
+  if (!previewBitmap)
+    RenderPage(currentPage);
+    
+  if (!previewBitmap)
+    return FALSE;
+
+  if (!canvas)
+    return FALSE;
+
+  int canvasWidth, canvasHeight;
+  canvas->GetSize(&canvasWidth, &canvasHeight);
+  
+  float zoomScale = (float)((float)currentZoom/(float)100);
+  float actualWidth = (float)(zoomScale*pageWidth*previewScale);
+//  float actualHeight = (float)(zoomScale*pageHeight*previewScale);
+
+  float x = (float)((canvasWidth - actualWidth)/2.0);
+  if (x < leftMargin)
+    x = (float)leftMargin;
+  float y = (float)topMargin;
+
+  wxMemoryDC temp_dc;
+  temp_dc.SelectObject(*previewBitmap);
+
+  dc.Blit((float)x, (float)y, (float)previewBitmap->GetWidth(), (float)previewBitmap->GetHeight(), &temp_dc, (float)0, (float)0);
+
+  temp_dc.SelectObject(wxNullBitmap);
+
+#endif  
+  
+  return TRUE;
+}
+
+bool wxPrintPreviewBase::RenderPage(int pageNum)
+{
+  int canvasWidth, canvasHeight;
+  
+#ifdef __GOOD_COMPILER__  // Robert Roebling
+
+  if (!previewCanvas)
+  {
+    wxMessageBox("wxPrintPreviewBase::RenderPage: must use wxPrintPreviewBase::SetCanvas to let me know about the canvas!",
+      "Print Preview Failure", wxOK);
+    return FALSE;
+  }
+  previewCanvas->GetSize(&canvasWidth, &canvasHeight);
+  
+  float zoomScale = (float)((float)currentZoom/(float)100);
+  float actualWidth = (float)(zoomScale*pageWidth*previewScale);
+  float actualHeight = (float)(zoomScale*pageHeight*previewScale);
+
+  float x = (float)((canvasWidth - actualWidth)/2.0);
+  if (x < leftMargin)
+    x = (float)leftMargin;
+//  float y = topMargin;
+
+
+  if (!previewBitmap)
+  {
+    previewBitmap = new wxBitmap((int)actualWidth, (int)actualHeight);
+    if (!previewBitmap || !previewBitmap->Ok())
+    {
+      if (previewBitmap)
+        delete previewBitmap;
+      wxMessageBox("Sorry, not enough memory to create a preview.", "Print Preview Failure", wxOK);
+      return FALSE;
+    }
+  }
+  
+  wxMemoryDC memoryDC;
+  memoryDC.SelectObject(*previewBitmap);
+
+  memoryDC.Clear();
+
+  previewPrintout->SetDC(&memoryDC);
+  previewPrintout->SetPageSizePixels(pageWidth, pageHeight);
+
+  previewPrintout->OnBeginPrinting();
+  
+
+  if (!previewPrintout->OnBeginDocument(printData.GetFromPage(), printData.GetToPage()))
+  {
+    wxMessageBox("Could not start document preview.", "Print Preview Failure", wxOK);
+    
+    memoryDC.SelectObject(wxNullBitmap);
+
+    delete previewBitmap;
+    return FALSE;
+  }
+  
+  previewPrintout->OnPrintPage(pageNum);
+  previewPrintout->OnEndDocument();
+  previewPrintout->OnEndPrinting();
+
+  previewPrintout->SetDC(NULL);
+  
+  memoryDC.SelectObject(wxNullBitmap);
+#endif
+
+  char buf[200];
+  if (maxPage != 0)
+    sprintf(buf, "Page %d of %d", pageNum, maxPage);
+  else
+    sprintf(buf, "Page %d", pageNum);
+
+  if (previewFrame)
+    previewFrame->SetStatusText(buf);
+
+  return TRUE;
+}
+
+
+bool wxPrintPreviewBase::DrawBlankPage(wxWindow *canvas, wxDC& dc)
+{
+
+#ifdef __GOOD_COMPILER__ // Robert Roebling
+
+  int canvasWidth, canvasHeight;
+  canvas->GetSize(&canvasWidth, &canvasHeight);
+  
+  float zoomScale = (float)((float)currentZoom/(float)100);
+  float actualWidth = zoomScale*pageWidth*previewScale;
+  float actualHeight = zoomScale*pageHeight*previewScale;
+
+  float x = (float)((canvasWidth - actualWidth)/2.0);
+  if (x < leftMargin)
+    x = (float)leftMargin;
+  float y = (float)topMargin;
+
+  // Draw shadow, allowing for 1-pixel border AROUND the actual page
+  int shadowOffset = 4;
+  dc.SetPen(*wxBLACK_PEN);
+  dc.SetBrush(*wxBLACK_BRUSH);
+  dc.DrawRectangle(x-1 + shadowOffset, y-1 + shadowOffset, actualWidth+2, actualHeight+2);
+
+  // Draw blank page allowing for 1-pixel border AROUND the actual page
+  dc.SetPen(*wxBLACK_PEN);
+  dc.SetBrush(*wxWHITE_BRUSH);
+  
+
+  dc.DrawRectangle(x-1, y-1, actualWidth+2, actualHeight+2);
+  
+#endif
+
+  return TRUE;
+}
+
+void wxPrintPreviewBase::SetZoom(int percent)
+{
+#ifdef __GOOD_COMPILER__ // Robert Roebling
+  if (currentZoom == percent)
+    return;
+    
+  currentZoom = percent;
+  if (previewBitmap)
+  {
+    delete previewBitmap;
+    previewBitmap = NULL;
+  }
+  RenderPage(currentPage);
+  
+  if (previewCanvas)
+  {
+    previewCanvas->Clear();
+    previewCanvas->Refresh();
+  }
+#endif  
+  
+}
diff --git a/src/common/string.cpp b/src/common/string.cpp
new file mode 100644
index 0000000000..611b5969de
--- /dev/null
+++ b/src/common/string.cpp
@@ -0,0 +1,1210 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        string.cpp
+// Purpose:     wxString class
+// Author:      Vadim Zeitlin
+// Modified by:
+// Created:     29/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "string.h"
+#endif
+
+/*
+ * About ref counting:
+ *  1) all empty strings use g_strEmpty, nRefs = -1 (set in Init())
+ *  2) AllocBuffer() sets nRefs to 1, Lock() increments it by one
+ *  3) Unlock() decrements nRefs and frees memory if it goes to 0
+ */
+
+// ===========================================================================
+// headers, declarations, constants
+// ===========================================================================
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/defs.h"
+#include "wx/string.h"
+#endif
+
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef  WXSTRING_IS_WXOBJECT
+  IMPLEMENT_DYNAMIC_CLASS(wxString, wxObject)
+#endif  //WXSTRING_IS_WXOBJECT
+
+// ---------------------------------------------------------------------------
+// static class variables definition
+// ---------------------------------------------------------------------------
+
+#ifdef  STD_STRING_COMPATIBILITY
+  const size_t wxString::npos = STRING_MAXLEN;
+#endif
+
+// ===========================================================================
+// static class data, special inlines
+// ===========================================================================
+
+// for an empty string, GetStringData() will return this address
+static int g_strEmpty[] = { -1,     // ref count (locked)
+                             0,     // current length
+                             0,     // allocated memory
+                             0 };   // string data
+// empty string shares memory with g_strEmpty
+static wxStringData *g_strNul = (wxStringData*)&g_strEmpty;
+// empty C style string: points to 'string data' byte of g_strEmpty
+extern const char *g_szNul = (const char *)(&g_strEmpty[3]);
+
+// ===========================================================================
+// global functions
+// ===========================================================================
+
+#ifdef  STD_STRING_COMPATIBILITY
+
+// MS Visual C++ version 5.0 provides the new STL headers as well as the old
+// iostream ones.
+//
+// ATTN: you can _not_ use both of these in the same program!
+#if 0 // def  _MSC_VER
+  #include  <iostream>
+  #define   NAMESPACE   std::
+#else
+  #include  <iostream.h>
+  #define   NAMESPACE
+#endif  //Visual C++
+
+NAMESPACE istream& operator>>(NAMESPACE istream& is, wxString& WXUNUSED(str))
+{
+#if 0
+  int w = is.width(0);
+  if ( is.ipfx(0) ) {
+    NAMESPACE streambuf *sb = is.rdbuf();
+    str.erase();
+    while ( true ) {
+      int ch = sb->sbumpc ();
+      if ( ch == EOF ) {
+        is.setstate(NAMESPACE ios::eofbit);
+        break;
+      }
+      else if ( isspace(ch) ) {
+        sb->sungetc();
+        break;
+      }
+      
+      str += ch;
+      if ( --w == 1 )
+        break;
+    }
+  }
+
+  is.isfx();
+  if ( str.length() == 0 )
+    is.setstate(NAMESPACE ios::failbit);
+#endif
+  return is;
+}
+
+#endif  //std::string compatibility
+
+// ===========================================================================
+// wxString class core
+// ===========================================================================
+
+// ---------------------------------------------------------------------------
+// construction
+// ---------------------------------------------------------------------------
+
+// construct an empty string
+wxString::wxString()
+{
+  Init();
+}
+
+// copy constructor
+wxString::wxString(const wxString& stringSrc)
+{
+  wxASSERT( stringSrc.GetStringData()->IsValid() );
+
+  if ( stringSrc.IsEmpty() ) {
+    // nothing to do for an empty string
+    Init();
+  }
+  else {
+    m_pchData = stringSrc.m_pchData;            // share same data
+    GetStringData()->Lock();                    // => one more copy
+  }
+}
+
+// constructs string of <nLength> copies of character <ch>
+wxString::wxString(char ch, size_t nLength)
+{
+  Init();
+
+  if ( nLength > 0 ) {
+    AllocBuffer(nLength);
+    
+    wxASSERT( sizeof(char) == 1 );  // can't use memset if not
+
+    memset(m_pchData, ch, nLength);
+  }
+}
+
+// takes nLength elements of psz starting at nPos
+void wxString::InitWith(const char *psz, size_t nPos, size_t nLength)
+{
+  Init();
+
+  wxASSERT( nPos <= Strlen(psz) );
+
+  if ( nLength == STRING_MAXLEN )
+    nLength = Strlen(psz + nPos);
+
+  if ( nLength > 0 ) {
+    // trailing '\0' is written in AllocBuffer()
+    AllocBuffer(nLength);
+    memcpy(m_pchData, psz + nPos, nLength*sizeof(char));
+  }
+}
+        
+// take first nLength characters of C string psz
+// (default value of STRING_MAXLEN means take all the string)
+wxString::wxString(const char *psz, size_t nLength)
+{
+  InitWith(psz, 0, nLength);
+}
+
+// the same as previous constructor, but for compilers using unsigned char
+wxString::wxString(const unsigned char* psz, size_t nLength)
+{
+  InitWith((const char *)psz, 0, nLength);
+} 
+ 
+#ifdef  STD_STRING_COMPATIBILITY
+
+// ctor from a substring
+wxString::wxString(const wxString& s, size_t nPos, size_t nLen)
+{
+  InitWith(s.c_str(), nPos, nLen == npos ? 0 : nLen);
+}
+
+// poor man's iterators are "void *" pointers
+wxString::wxString(const void *pStart, const void *pEnd)
+{
+  InitWith((const char *)pStart, 0, 
+           (const char *)pEnd - (const char *)pStart);
+}
+
+#endif  //std::string compatibility
+
+// from wide string
+wxString::wxString(const wchar_t *pwz)
+{
+  // first get necessary size
+  size_t nLen = wcstombs(NULL, pwz, 0);
+
+  // empty?
+  if ( nLen != 0 ) {
+    AllocBuffer(nLen);
+    wcstombs(m_pchData, pwz, nLen);
+  }
+  else {
+    Init();
+  }
+}
+
+// ---------------------------------------------------------------------------
+// memory allocation
+// ---------------------------------------------------------------------------
+
+// allocates memory needed to store a C string of length nLen
+void wxString::AllocBuffer(size_t nLen)
+{
+  wxASSERT( nLen >  0         );    //
+  wxASSERT( nLen <= INT_MAX-1 );    // max size (enough room for 1 extra)
+
+  // allocate memory:
+  // 1) one extra character for '\0' termination
+  // 2) sizeof(wxStringData) for housekeeping info
+  wxStringData* pData = (wxStringData*)new char[sizeof(wxStringData) +
+                                                (nLen + 1)*sizeof(char)];
+  pData->nRefs        = 1;
+  pData->data()[nLen] = '\0';
+  pData->nDataLength  = nLen;
+  pData->nAllocLength = nLen;
+  m_pchData           = pData->data();  // data starts after wxStringData
+}
+
+// releases the string memory and reinits it
+void wxString::Reinit()
+{
+  GetStringData()->Unlock();
+  Init();
+}
+
+// wrapper around wxString::Reinit
+void wxString::Empty()
+{
+  if ( GetStringData()->nDataLength != 0 )
+    Reinit();
+
+  wxASSERT( GetStringData()->nDataLength == 0 );
+  wxASSERT( GetStringData()->nAllocLength == 0 );
+}
+
+// must be called before changing this string
+void wxString::CopyBeforeWrite()
+{
+  wxStringData* pData = GetStringData();
+
+  if ( pData->IsShared() ) {
+    pData->Unlock();                // memory not freed because shared
+    AllocBuffer(pData->nDataLength);
+    memcpy(m_pchData, pData->data(), (pData->nDataLength + 1)*sizeof(char));
+  }
+
+  wxASSERT( !pData->IsShared() );  // we must be the only owner
+}
+
+// must be called before replacing contents of this string
+void wxString::AllocBeforeWrite(size_t nLen)
+{
+  wxASSERT( nLen != 0 );  // doesn't make any sense
+
+  // must not share string and must have enough space
+  register wxStringData* pData = GetStringData();  
+  if ( pData->IsShared() || (nLen > pData->nAllocLength) ) {
+    // can't work with old buffer, get new one
+    pData->Unlock();
+    AllocBuffer(nLen);
+  }
+
+  wxASSERT( !pData->IsShared() );  // we must be the only owner
+}
+
+// get the pointer to writable buffer of (at least) nLen bytes
+char *wxString::GetWriteBuf(size_t nLen)
+{
+  AllocBeforeWrite(nLen);
+  return m_pchData;
+}
+
+// dtor frees memory if no other strings use it
+wxString::~wxString()
+{
+  GetStringData()->Unlock();
+}
+
+// ---------------------------------------------------------------------------
+// data access
+// ---------------------------------------------------------------------------
+
+// all functions are inline in string.h
+
+// ---------------------------------------------------------------------------
+// assignment operators
+// ---------------------------------------------------------------------------
+
+// helper function: does real copy 
+void wxString::AssignCopy(size_t nSrcLen, const char *pszSrcData)
+{
+  if ( nSrcLen == 0 ) {
+    Reinit();
+  }
+  else {
+    AllocBeforeWrite(nSrcLen);
+    memcpy(m_pchData, pszSrcData, nSrcLen*sizeof(char));
+    GetStringData()->nDataLength = nSrcLen;
+    m_pchData[nSrcLen] = '\0';
+  }
+}
+
+// assigns one string to another
+wxString& wxString::operator=(const wxString& stringSrc)
+{
+  // don't copy string over itself
+  if ( m_pchData != stringSrc.m_pchData ) {
+    if ( stringSrc.GetStringData()->IsEmpty() ) {
+      Reinit();
+    }
+    else {
+      // adjust references
+      GetStringData()->Unlock();
+      m_pchData = stringSrc.m_pchData;
+      GetStringData()->Lock();
+    }
+  }
+
+  return *this;
+}
+
+// assigns a single character
+wxString& wxString::operator=(char ch)
+{
+  AssignCopy(1, &ch);
+  return *this;
+}
+
+// assigns C string
+wxString& wxString::operator=(const char *psz)
+{
+  AssignCopy(Strlen(psz), psz);
+  return *this;
+}
+
+// same as 'signed char' variant
+wxString& wxString::operator=(const unsigned char* psz)
+{
+  *this = (const char *)psz;
+  return *this;
+}
+
+wxString& wxString::operator=(const wchar_t *pwz)
+{
+  wxString str(pwz);
+  *this = str;
+  return *this;
+}
+
+// ---------------------------------------------------------------------------
+// string concatenation
+// ---------------------------------------------------------------------------
+
+// concatenate two sources
+// NB: assume that 'this' is a new wxString object
+void wxString::ConcatCopy(int nSrc1Len, const char *pszSrc1Data,
+                        int nSrc2Len, const char *pszSrc2Data)
+{
+  int nNewLen = nSrc1Len + nSrc2Len;
+  if ( nNewLen != 0 )
+  {
+    AllocBuffer(nNewLen);
+    memcpy(m_pchData, pszSrc1Data, nSrc1Len*sizeof(char));
+    memcpy(m_pchData + nSrc1Len, pszSrc2Data, nSrc2Len*sizeof(char));
+  }
+}
+
+// add something to this string
+void wxString::ConcatSelf(int nSrcLen, const char *pszSrcData)
+{
+  // concatenating an empty string is a NOP
+  if ( nSrcLen != 0 ) {
+    register wxStringData *pData = GetStringData();
+
+    // alloc new buffer if current is too small
+    if ( pData->IsShared() || 
+         pData->nDataLength + nSrcLen > pData->nAllocLength ) {
+      // we have to grow the buffer, use the ConcatCopy routine
+      // (which will allocate memory)
+      wxStringData* pOldData = GetStringData();
+      ConcatCopy(pOldData->nDataLength, m_pchData, nSrcLen, pszSrcData);
+      pOldData->Unlock();
+    }
+    else {
+      // fast concatenation when buffer big enough
+      memcpy(m_pchData + pData->nDataLength, pszSrcData, nSrcLen*sizeof(char));
+      pData->nDataLength += nSrcLen;
+
+      // should be enough space
+      wxASSERT( pData->nDataLength <= pData->nAllocLength );
+
+      m_pchData[pData->nDataLength] = '\0';   // put terminating '\0'
+    }
+  }
+}
+
+/*
+ * string may be concatenated with other string, C string or a character
+ */
+
+void wxString::operator+=(const wxString& string)
+{
+  ConcatSelf(string.Len(), string);
+}
+
+void wxString::operator+=(const char *psz)
+{
+  ConcatSelf(Strlen(psz), psz);
+}
+
+void wxString::operator+=(char ch)
+{
+  ConcatSelf(1, &ch);
+}
+
+/*
+ * Same as above but return the result
+ */  
+
+wxString& wxString::operator<<(const wxString& string)
+{
+  ConcatSelf(string.Len(), string);
+  return *this;
+}
+
+wxString& wxString::operator<<(const char *psz)
+{
+  ConcatSelf(Strlen(psz), psz);
+  return *this;
+}
+
+wxString& wxString::operator<<(char ch)
+{
+  ConcatSelf(1, &ch);
+  return *this;
+}
+
+/* 
+ * concatenation functions come in 5 flavours:
+ *  string + string
+ *  char   + string      and      string + char
+ *  C str  + string      and      string + C str
+ */
+
+wxString operator+(const wxString& string1, const wxString& string2)
+{
+  wxString s;
+  s.ConcatCopy(string1.GetStringData()->nDataLength, string1.m_pchData,
+               string2.GetStringData()->nDataLength, string2.m_pchData);
+  return s;
+}
+
+wxString operator+(const wxString& string1, char ch)
+{
+  wxString s;
+  s.ConcatCopy(string1.GetStringData()->nDataLength, string1.m_pchData, 1, &ch);
+  return s;
+}
+
+wxString operator+(char ch, const wxString& string)
+{
+  wxString s;
+  s.ConcatCopy(1, &ch, string.GetStringData()->nDataLength, string.m_pchData);
+  return s;
+}
+
+wxString operator+(const wxString& string, const char *psz)
+{
+  wxString s;
+  s.ConcatCopy(string.GetStringData()->nDataLength, string.m_pchData,
+               Strlen(psz), psz);
+  return s;
+}
+
+wxString operator+(const char *psz, const wxString& string)
+{
+  wxString s;
+  s.ConcatCopy(Strlen(psz), psz,
+               string.GetStringData()->nDataLength, string.m_pchData);
+  return s;
+}
+
+// ===========================================================================
+// other common string functions
+// ===========================================================================
+
+// ---------------------------------------------------------------------------
+// simple sub-string extraction
+// ---------------------------------------------------------------------------
+
+// helper function: clone the data attached to this string
+void wxString::AllocCopy(wxString& dest, int nCopyLen, int nCopyIndex) const
+{
+  if ( nCopyLen == 0 )
+  {
+    dest.Init();
+  }
+  else
+  {
+    dest.AllocBuffer(nCopyLen);
+    memcpy(dest.m_pchData, m_pchData + nCopyIndex, nCopyLen*sizeof(char));
+  }
+}
+
+// extract string of length nCount starting at nFirst
+// default value of nCount is 0 and means "till the end"
+wxString wxString::Mid(size_t nFirst, size_t nCount) const
+{
+  // out-of-bounds requests return sensible things
+  if ( nCount == 0 )
+    nCount = GetStringData()->nDataLength - nFirst;
+
+  if ( nFirst + nCount > (size_t)GetStringData()->nDataLength )
+    nCount = GetStringData()->nDataLength - nFirst;
+  if ( nFirst > (size_t)GetStringData()->nDataLength )
+    nCount = 0;
+
+  wxString dest;
+  AllocCopy(dest, nCount, nFirst);
+  return dest;
+}
+
+// extract nCount last (rightmost) characters
+wxString wxString::Right(size_t nCount) const
+{
+  if ( nCount > (size_t)GetStringData()->nDataLength )
+    nCount = GetStringData()->nDataLength;
+
+  wxString dest;
+  AllocCopy(dest, nCount, GetStringData()->nDataLength - nCount);
+  return dest;
+}
+
+// get all characters after the last occurence of ch
+// (returns the whole string if ch not found)
+wxString wxString::Right(char ch) const
+{
+  wxString str;
+  int iPos = Find(ch, TRUE);
+  if ( iPos == NOT_FOUND )
+    str = *this;
+  else
+    str = c_str() + iPos;
+
+  return str;
+}
+
+// extract nCount first (leftmost) characters
+wxString wxString::Left(size_t nCount) const
+{
+  if ( nCount > (size_t)GetStringData()->nDataLength )
+    nCount = GetStringData()->nDataLength;
+
+  wxString dest;
+  AllocCopy(dest, nCount, 0);
+  return dest;
+}
+
+// get all characters before the first occurence of ch
+// (returns the whole string if ch not found)
+wxString wxString::Left(char ch) const
+{
+  wxString str;
+  for ( const char *pc = m_pchData; *pc != '\0' && *pc != ch; pc++ )
+    str += *pc;
+
+  return str;
+}
+
+/// get all characters before the last occurence of ch
+/// (returns empty string if ch not found)
+wxString wxString::Before(char ch) const
+{
+  wxString str;
+  int iPos = Find(ch, TRUE);
+  if ( iPos != NOT_FOUND && iPos != 0 )
+    str = wxString(c_str(), iPos - 1);
+
+  return str;
+}
+
+/// get all characters after the first occurence of ch
+/// (returns empty string if ch not found)
+wxString wxString::After(char ch) const
+{
+  wxString str;
+  int iPos = Find(ch);
+  if ( iPos != NOT_FOUND )
+    str = c_str() + iPos + 1;
+
+  return str;
+}
+
+// replace first (or all) occurences of some substring with another one
+uint wxString::Replace(const char *szOld, const char *szNew, bool bReplaceAll)
+{
+  uint uiCount = 0;   // count of replacements made
+
+  uint uiOldLen = Strlen(szOld);
+
+  wxString strTemp;
+  const char *pCurrent = m_pchData;
+  const char *pSubstr;           
+  while ( *pCurrent != '\0' ) {
+    pSubstr = strstr(pCurrent, szOld);
+    if ( pSubstr == NULL ) {
+      // strTemp is unused if no replacements were made, so avoid the copy
+      if ( uiCount == 0 )
+        return 0;
+
+      strTemp += pCurrent;    // copy the rest
+      break;                  // exit the loop
+    }
+    else {
+      // take chars before match
+      strTemp.ConcatSelf(pSubstr - pCurrent, pCurrent);
+      strTemp += szNew;
+      pCurrent = pSubstr + uiOldLen;  // restart after match
+
+      uiCount++;
+
+      // stop now?
+      if ( !bReplaceAll ) {
+        strTemp += pCurrent;    // copy the rest
+        break;                  // exit the loop
+      }
+    }
+  }
+
+  // only done if there were replacements, otherwise would have returned above
+  *this = strTemp;
+
+  return uiCount;
+}
+
+bool wxString::IsAscii() const
+{
+  const char *s = (const char*) *this;
+  while(*s){
+    if(!isascii(*s)) return(FALSE);
+    s++;
+  }
+  return(TRUE);
+}
+  
+bool wxString::IsWord() const
+{
+  const char *s = (const char*) *this;
+  while(*s){
+    if(!isalpha(*s)) return(FALSE);
+    s++;
+  }
+  return(TRUE);
+}
+  
+bool wxString::IsNumber() const
+{
+  const char *s = (const char*) *this;
+  while(*s){
+    if(!isdigit(*s)) return(FALSE);
+    s++;
+  }
+  return(TRUE);
+}
+
+// kludge: we don't have declaraton of wxStringData here, so we add offsets
+//         manually to get to the "length" field of wxStringData structure
+bool   wxString::IsEmpty() const  { return Len() == 0;                        }
+
+wxString wxString::Strip(stripType w) const
+{
+    wxString s = *this;
+    if ( w & leading ) s.Trim(FALSE);
+    if ( w & trailing ) s.Trim(TRUE);
+    return s;
+}
+
+/// case-insensitive strcmp() (platform independent)
+int Stricmp(const char *psz1, const char *psz2)
+{
+#if     defined(_MSC_VER)
+  return _stricmp(psz1, psz2);
+#elif defined(__BORLANDC__)
+  return stricmp(psz1, psz2);
+#elif   defined(__UNIX__) || defined(__GNUWIN32__)
+  return strcasecmp(psz1, psz2);
+#else
+  // almost all compilers/libraries provide this function (unfortunately under
+  // different names), that's why we don't implement our own which will surely
+  // be more efficient than this code (uncomment to use):
+  /*
+    register char c1, c2;
+    do {
+      c1 = tolower(*psz1++);
+      c2 = tolower(*psz2++);
+    } while ( c1 && (c1 == c2) );
+
+    return c1 - c2;
+  */
+  
+  #error  "Please define string case-insensitive compare for your OS/compiler"
+#endif  // OS/compiler
+}
+
+// ---------------------------------------------------------------------------
+// case conversion
+// ---------------------------------------------------------------------------
+
+wxString& wxString::MakeUpper()
+{
+  CopyBeforeWrite();
+
+  for ( char *p = m_pchData; *p; p++ )
+    *p = (char)toupper(*p);
+
+  return *this;
+}
+
+wxString& wxString::MakeLower()
+{
+  CopyBeforeWrite();
+  
+  for ( char *p = m_pchData; *p; p++ )
+    *p = (char)tolower(*p);
+
+  return *this;
+}
+
+// ---------------------------------------------------------------------------
+// trimming and padding
+// ---------------------------------------------------------------------------
+
+// trims spaces (in the sense of isspace) from left or right side
+wxString& wxString::Trim(bool bFromRight)
+{
+  CopyBeforeWrite();
+
+  if ( bFromRight )
+  {
+    // find last non-space character
+    char *psz = m_pchData + GetStringData()->nDataLength - 1;
+    while ( isspace(*psz) && (psz >= m_pchData) )
+      psz--;
+
+    // truncate at trailing space start
+    *++psz = '\0';
+    GetStringData()->nDataLength = psz - m_pchData;
+  }
+  else
+  {
+    // find first non-space character
+    const char *psz = m_pchData;
+    while ( isspace(*psz) )
+      psz++;
+
+    // fix up data and length
+    int nDataLength = GetStringData()->nDataLength - (psz - m_pchData);
+    memmove(m_pchData, psz, (nDataLength + 1)*sizeof(char));
+    GetStringData()->nDataLength = nDataLength;
+  }
+
+  return *this;
+}
+
+// adds nCount characters chPad to the string from either side
+wxString& wxString::Pad(size_t nCount, char chPad, bool bFromRight)
+{
+  wxString s(chPad, nCount);
+
+  if ( bFromRight )
+    *this += s;
+  else
+  {
+    s += *this;
+    *this = s;
+  }
+
+  return *this;
+}
+
+// truncate the string
+wxString& wxString::Truncate(size_t uiLen)
+{
+  *(m_pchData + uiLen) = '\0';
+  GetStringData()->nDataLength = uiLen;
+
+  return *this;
+}
+
+// ---------------------------------------------------------------------------
+// finding (return NOT_FOUND if not found and index otherwise)
+// ---------------------------------------------------------------------------
+
+// find a character
+int wxString::Find(char ch, bool bFromEnd) const
+{
+  const char *psz = bFromEnd ? strrchr(m_pchData, ch) : strchr(m_pchData, ch);
+
+  return (psz == NULL) ? NOT_FOUND : psz - m_pchData;
+}
+
+// find a sub-string (like strstr)
+int wxString::Find(const char *pszSub) const
+{
+  const char *psz = strstr(m_pchData, pszSub);
+
+  return (psz == NULL) ? NOT_FOUND : psz - m_pchData;
+}
+
+// ---------------------------------------------------------------------------
+// formatted output
+// ---------------------------------------------------------------------------
+int wxString::Printf(const char *pszFormat, ...)
+{
+  va_list argptr;
+  va_start(argptr, pszFormat);
+
+  int iLen = PrintfV(pszFormat, argptr);
+
+  va_end(argptr);
+
+  return iLen;
+}
+
+int wxString::PrintfV(const char* pszFormat, va_list argptr)
+{
+  static char s_szScratch[1024];
+
+  int iLen = vsprintf(s_szScratch, pszFormat, argptr);
+  AllocBeforeWrite(iLen);
+  strcpy(m_pchData, s_szScratch);
+
+  return iLen;
+}
+
+// ---------------------------------------------------------------------------
+// standard C++ library string functions
+// ---------------------------------------------------------------------------
+#ifdef  STD_STRING_COMPATIBILITY
+
+wxString& wxString::insert(size_t nPos, const wxString& str)
+{
+  wxASSERT( nPos <= Len() );
+
+  wxString strTmp;
+  char *pc = strTmp.GetWriteBuf(Len() + str.Len() + 1);
+  strncpy(pc, c_str(), nPos);
+  strcpy(pc + nPos, str);
+  strcpy(pc + nPos + str.Len(), c_str() + nPos);
+  *this = strTmp;
+    
+  return *this; 
+}
+
+size_t wxString::find(const wxString& str, size_t nStart) const
+{
+  wxASSERT( nStart <= Len() );
+
+  const char *p = strstr(c_str() + nStart, str);
+  
+  return p == NULL ? npos : p - c_str();
+}
+
+size_t wxString::find(const char* sz, size_t nStart, size_t n) const
+{
+  return find(wxString(sz, n == npos ? 0 : n), nStart);
+}
+        
+size_t wxString::find(char ch, size_t nStart) const
+{
+  wxASSERT( nStart <= Len() );
+
+  const char *p = strchr(c_str() + nStart, ch);
+  
+  return p == NULL ? npos : p - c_str();
+}
+
+size_t wxString::rfind(const wxString& str, size_t nStart) const
+{
+  wxASSERT( nStart <= Len() );
+
+  // # could be quicker than that
+  const char *p = c_str() + (nStart == npos ? Len() : nStart);
+  while ( p >= c_str() + str.Len() ) {
+    if ( strncmp(p - str.Len(), str, str.Len()) == 0 )
+      return p - str.Len() - c_str();
+    p--;
+  }
+  
+  return npos;
+}
+        
+size_t wxString::rfind(const char* sz, size_t nStart, size_t n) const
+{
+  return rfind(wxString(sz, n == npos ? 0 : n), nStart);
+}
+
+size_t wxString::rfind(char ch, size_t nStart) const
+{
+  wxASSERT( nStart <= Len() );
+
+  const char *p = strrchr(c_str() + nStart, ch);
+  
+  return p == NULL ? npos : p - c_str();
+}
+
+wxString wxString::substr(size_t nStart, size_t nLen) const
+{
+  // npos means 'take all'
+  if ( nLen == npos )
+    nLen = 0;
+
+  wxASSERT( nStart + nLen <= Len() );
+
+  return wxString(c_str() + nStart, nLen == npos ? 0 : nLen);
+}
+
+wxString& wxString::erase(size_t nStart, size_t nLen)
+{
+  wxString strTmp(c_str(), nStart);
+  if ( nLen != npos ) {
+    wxASSERT( nStart + nLen <= Len() );
+
+    strTmp.append(c_str() + nStart + nLen);
+  }
+
+  *this = strTmp;
+  return *this;
+}
+
+wxString& wxString::replace(size_t nStart, size_t nLen, const char *sz)
+{
+  wxASSERT( nStart + nLen <= Strlen(sz) );
+
+  wxString strTmp;
+  if ( nStart != 0 )
+    strTmp.append(c_str(), nStart);
+  strTmp += sz;
+  strTmp.append(c_str() + nStart + nLen);
+  
+  *this = strTmp;
+  return *this;
+}
+
+wxString& wxString::replace(size_t nStart, size_t nLen, size_t nCount, char ch)
+{
+  return replace(nStart, nLen, wxString(ch, nCount));
+}
+
+wxString& wxString::replace(size_t nStart, size_t nLen, 
+                        const wxString& str, size_t nStart2, size_t nLen2)
+{
+  return replace(nStart, nLen, str.substr(nStart2, nLen2));
+}
+
+wxString& wxString::replace(size_t nStart, size_t nLen, 
+                        const char* sz, size_t nCount)
+{
+  return replace(nStart, nLen, wxString(sz, nCount));
+}
+
+#endif  //std::string compatibility
+
+// ============================================================================
+// ArrayString
+// ============================================================================
+
+// size increment = max(50% of current size, ARRAY_MAXSIZE_INCREMENT)
+#define   ARRAY_MAXSIZE_INCREMENT       4096
+#ifndef   ARRAY_DEFAULT_INITIAL_SIZE    // also defined in dynarray.h
+  #define   ARRAY_DEFAULT_INITIAL_SIZE    (16)
+#endif
+
+#define   STRING(p)   ((wxString *)(&(p)))
+
+// ctor
+wxArrayString::wxArrayString()
+{
+  m_nSize  =
+  m_nCount = 0;
+  m_pItems = NULL;
+}
+
+// copy ctor
+wxArrayString::wxArrayString(const wxArrayString& src)
+{
+  m_nSize  = src.m_nSize;
+  m_nCount = src.m_nCount;
+
+  if ( m_nSize != 0 )
+    m_pItems = new char *[m_nSize];
+  else
+    m_pItems = NULL;
+
+  if ( m_nCount != 0 )
+    memcpy(m_pItems, src.m_pItems, m_nCount*sizeof(char *));
+}
+
+// copy operator
+wxArrayString& wxArrayString::operator=(const wxArrayString& src)
+{
+  DELETEA(m_pItems);
+
+  m_nSize  = src.m_nSize;
+  m_nCount = src.m_nCount;
+
+  if ( m_nSize != 0 )
+    m_pItems = new char *[m_nSize];
+  else
+    m_pItems = NULL;
+
+  if ( m_nCount != 0 )
+    memcpy(m_pItems, src.m_pItems, m_nCount*sizeof(char *));
+
+  return *this;
+}
+
+// grow the array
+void wxArrayString::Grow()
+{
+  // only do it if no more place
+  if( m_nCount == m_nSize ) {
+    if( m_nSize == 0 ) {
+      // was empty, alloc some memory
+      m_nSize = ARRAY_DEFAULT_INITIAL_SIZE;
+      m_pItems = new char *[m_nSize];
+    }
+    else {
+      // add 50% but not too much
+      size_t nIncrement = m_nSize >> 1;
+      if ( nIncrement > ARRAY_MAXSIZE_INCREMENT )
+        nIncrement = ARRAY_MAXSIZE_INCREMENT;
+      m_nSize += nIncrement;
+      char **pNew = new char *[m_nSize];
+
+      // copy data to new location
+      memcpy(pNew, m_pItems, m_nCount*sizeof(char *));
+
+      // delete old memory (but do not release the strings!)
+      DELETEA(m_pItems);
+
+      m_pItems = pNew;
+    }
+  }
+}
+
+void wxArrayString::Free()
+{
+  for ( size_t n = 0; n < m_nCount; n++ ) {
+    STRING(m_pItems[n])->GetStringData()->Unlock();
+  }
+}
+
+// deletes all the strings from the list
+void wxArrayString::Empty()
+{
+  Free();
+
+  m_nCount = 0;
+}
+
+// as Empty, but also frees memory
+void wxArrayString::Clear()
+{
+  Free();
+
+  m_nSize  = 
+  m_nCount = 0;
+
+  DELETEA(m_pItems);
+  m_pItems = NULL;
+}
+
+// dtor
+wxArrayString::~wxArrayString()
+{
+  Free();
+
+  DELETEA(m_pItems);
+}
+
+// pre-allocates memory (frees the previous data!)
+void wxArrayString::Alloc(size_t nSize)
+{
+  wxASSERT( nSize > 0 );
+
+  // only if old buffer was not big enough
+  if ( nSize > m_nSize ) {
+    Free();
+    DELETEA(m_pItems);
+    m_pItems = new char *[nSize];
+    m_nSize  = nSize;
+  }
+
+  m_nCount = 0;
+}
+
+// searches the array for an item (forward or backwards)
+
+// Robert Roebling (changed to bool from Bool)
+
+int wxArrayString::Index(const char *sz, bool bCase, bool bFromEnd) const
+{
+  if ( bFromEnd ) {
+    if ( m_nCount > 0 ) {
+      uint ui = m_nCount;
+      do {
+        if ( STRING(m_pItems[--ui])->IsSameAs(sz, bCase) )
+          return ui;
+      }
+      while ( ui != 0 );
+    }
+  }
+  else {
+    for( uint ui = 0; ui < m_nCount; ui++ ) {
+      if( STRING(m_pItems[ui])->IsSameAs(sz, bCase) )
+        return ui;
+    }
+  }
+
+  return NOT_FOUND;
+}
+
+// add item at the end
+void wxArrayString::Add(const wxString& src)
+{
+  Grow();
+
+  // the string data must not be deleted!
+  src.GetStringData()->Lock();
+  m_pItems[m_nCount++] = (char *)src.c_str();
+}
+
+// add item at the given position
+void wxArrayString::Insert(const wxString& src, size_t nIndex)
+{
+  wxCHECK( nIndex <= m_nCount );
+
+  Grow();
+
+  memmove(&m_pItems[nIndex + 1], &m_pItems[nIndex], 
+          (m_nCount - nIndex)*sizeof(char *));
+
+  src.GetStringData()->Lock();
+  m_pItems[nIndex] = (char *)src.c_str();
+
+  m_nCount++;
+}
+
+// removes item from array (by index)
+void wxArrayString::Remove(size_t nIndex)
+{
+  wxCHECK( nIndex <= m_nCount );
+
+  // release our lock
+  Item(nIndex).GetStringData()->Unlock();
+
+  memmove(&m_pItems[nIndex], &m_pItems[nIndex + 1], 
+          (m_nCount - nIndex - 1)*sizeof(char *));
+  m_nCount--;
+}
+
+// removes item from array (by value)
+void wxArrayString::Remove(const char *sz)
+{
+  int iIndex = Index(sz);
+
+  wxCHECK( iIndex != NOT_FOUND );
+
+  Remove((size_t)iIndex);
+}
+
+// sort array elements using passed comparaison function
+
+// Robert Roebling (changed to bool from Bool)
+
+void wxArrayString::Sort(bool bCase, bool bReverse)
+{
+  //@@@@ TO DO
+  //qsort(m_pItems, m_nCount, sizeof(char *), fCmp);
+}
diff --git a/src/common/textfile.cpp b/src/common/textfile.cpp
new file mode 100644
index 0000000000..ca7235c4e9
--- /dev/null
+++ b/src/common/textfile.cpp
@@ -0,0 +1,233 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        textfile.cpp
+// Purpose:     implementation of wxTextFile class
+// Author:      Vadim Zeitlin
+// Modified by: 
+// Created:     03.04.98
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// Licence:     wxWindows license
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// headers
+// ============================================================================
+
+#ifdef __GNUG__
+#pragma implementation "textfile.h"
+#endif
+
+#include  "wx/wxprec.h"
+
+#ifdef    __BORLANDC__
+  #pragma hdrstop
+#endif  //__BORLANDC__
+
+#include  <wx/string.h>
+#include  <wx/intl.h>
+#include  <wx/file.h>
+#include  <wx/log.h>
+#include  <wx/textfile.h>
+
+// ============================================================================
+// wxTextFile class implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// static variables
+// ----------------------------------------------------------------------------
+  
+// default type is the native one
+const wxTextFile::Type wxTextFile::typeDefault = wxTextFile::
+#if   defined(__WINDOWS__)
+  Type_Dos;
+#elif defined(__UNIX__)
+  Type_Unix;
+#elif defined(__MAC__)
+  Type_Mac;
+  // if you feel brave, remove the next line
+  #error  "wxTextFile: code for Mac files is untested."
+#else
+  Type_None;
+  #error  "wxTextFile: unsupported platform."
+#endif
+
+
+// ----------------------------------------------------------------------------
+// ctors & dtor
+// ----------------------------------------------------------------------------
+
+wxTextFile::wxTextFile(const wxString& strFile) : m_strFile(strFile)
+{
+}
+
+wxTextFile::~wxTextFile()
+{
+  // m_file dtor called automatically
+}
+
+// ----------------------------------------------------------------------------
+// file operations
+// ----------------------------------------------------------------------------
+
+bool wxTextFile::Open(const wxString& strFile)
+{
+  m_strFile = strFile;
+  return Open();
+}
+
+bool wxTextFile::Open()
+{
+  // file name must be either given in ctor or in Open(const wxString&)
+  wxASSERT( !m_strFile.IsEmpty() );
+
+  // open file in read-only mode
+  if ( !m_file.Open(m_strFile) )
+    return FALSE;
+
+  // read file into memory
+  bool bRet = Read();
+
+  m_file.Close();
+
+  return bRet;
+}
+
+// analyse some lines of the file trying to guess it's type.
+// if it fails, it assumes the native type for our platform.
+wxTextFile::Type wxTextFile::GuessType() const
+{
+  // file should be opened and we must be in it's beginning
+  wxASSERT( m_file.IsOpened() && m_file.Tell() == 0 );
+
+  // scan the file lines
+  uint nUnix = 0,     // number of '\n's alone
+       nDos  = 0,     // number of '\r\n'
+       nMac  = 0;     // number of '\r's
+
+  // we take MAX_LINES_SCAN in the beginning, middle and the end of file
+  #define MAX_LINES_SCAN    (10)
+  uint nCount = m_aLines.Count() / 3,
+       nScan =  nCount > 3*MAX_LINES_SCAN ? MAX_LINES_SCAN : nCount / 3;
+
+  #define   AnalyseLine(n)              \
+    switch ( m_aTypes[n] ) {            \
+      case Type_Unix: nUnix++; break;   \
+      case Type_Dos:  nDos++;  break;   \
+      case Type_Mac:  nMac++;  break;   \
+    }
+
+  uint n;
+  for ( n = 0; n < nScan; n++ )     // the beginning
+    AnalyseLine(n);
+  for ( n = (nCount - nScan)/2; n < (nCount + nScan)/2; n++ )
+    AnalyseLine(n);
+  for ( n = nCount - nScan; n < nCount; n++ )
+    AnalyseLine(n);
+
+  #undef   AnalyseLine
+
+  // interpret the results (@@ far from being even 50% fool proof)
+  if ( nDos + nUnix + nMac == 0 ) {
+    // no newlines at all
+    wxLogWarning("'%s' is probably a binary file.", m_strFile.c_str());
+  }
+  else {
+    #define   GREATER_OF(t1, t2) n##t1 == n##t2 ? typeDefault               \
+                                                : n##t1 > n##t2 ? Type_##t1 \
+                                                                : Type_##t2
+
+    if ( nDos > nUnix )
+      return GREATER_OF(Dos, Mac);
+    else if ( nDos < nUnix )
+      return GREATER_OF(Unix, Mac);
+    else {
+      // nDos == nUnix
+      return nMac > nDos ? Type_Mac : typeDefault;
+    }
+
+    #undef    GREATER_OF
+  }
+
+  return typeDefault;
+}
+
+bool wxTextFile::Read()
+{
+  // file should be opened and we must be in it's beginning
+  wxASSERT( m_file.IsOpened() && m_file.Tell() == 0 );
+
+  wxString str;
+  char ch, chLast = '\0';
+  while ( !m_file.Eof() ) {
+    // @@ should really use a buffer for efficiency
+    if ( m_file.Read(&ch, sizeof(ch)) == ofsInvalid ) {
+      // read error
+      m_file.Close();
+      return FALSE;
+    }
+
+    #ifdef  __MAC__
+      #pragma message("wxTextFile::Read() hasn't been tested with Mac files.")
+    #endif
+
+    switch ( ch ) {
+      case '\n':
+        // Dos/Unix line termination
+        m_aLines.Add(str);
+        m_aTypes.Add(chLast == '\r' ? Type_Dos : Type_Unix);
+        str.Empty();
+        chLast = '\n';
+        break;
+
+      case '\r':
+        if ( chLast == '\r' ) {
+          // Mac empty line
+          m_aLines.Add("");
+          m_aTypes.Add(Type_Mac);
+        }
+        else
+          chLast = '\r';
+        break;
+
+      default:
+        if ( chLast == '\r' ) {
+          // Mac line termination
+          m_aLines.Add(str);
+          m_aTypes.Add(Type_Mac);
+          str = ch;
+        }
+        else {
+          // add to the current line
+          str += ch;
+        }
+    }
+  }
+
+  // anything in the last line?
+  if ( !str.IsEmpty() ) {
+    m_aTypes.Add(Type_None);  // no line terminator
+    m_aLines.Add(str);
+  }
+
+  return TRUE;
+}
+
+bool wxTextFile::Write(Type typeNew)
+{
+  wxTempFile fileTmp(m_strFile);
+
+  if ( !fileTmp.IsOpened() ) {
+    wxLogError("can't write file '%s' to disk.", m_strFile.c_str());
+    return FALSE;
+  }
+
+  uint nCount = m_aLines.Count();
+  for ( uint n = 0; n < nCount; n++ ) {
+    fileTmp.Write(m_aLines[n] + 
+                  GetEOL(typeNew == Type_None ? m_aTypes[n] : typeNew));
+  }
+
+  // replace the old file with this one
+  return fileTmp.Commit();
+}
\ No newline at end of file
diff --git a/src/common/time.cpp b/src/common/time.cpp
new file mode 100644
index 0000000000..852de83041
--- /dev/null
+++ b/src/common/time.cpp
@@ -0,0 +1,383 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        time.cpp
+// Purpose:     wxTime class, from NIHCL
+// Author:      Julian Smart, after K. E. Gorlen
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "time.h"
+#endif
+
+/*
+Provides an object that represents a Time, stored as the number of
+seconds since January 1, 1901, GMT.
+*/
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#include "wx/setup.h"
+
+#if USE_TIMEDATE
+
+#include "wx/time.h"
+#include "wx/date.h"
+#include "wx/utils.h"
+
+#if USE_IOSTREAMH
+#include <iostream.h>
+#else
+#include <iostream>
+#endif
+
+#include <iomanip.h>
+#include <string.h>
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxTime, wxObject)
+#endif
+
+
+extern bool wxGetLocalTime(long *timeZone, int *dstObserved);
+extern long wxGetCurrentTime(void);
+
+static long TIME_ZONE;          /* seconds west of GMT */
+static int DST_OBSERVED;        /* flags U.S. daylight saving time observed */
+
+static bool wxTimeInitialized = FALSE;
+
+wxTime::tFormat		wxTime::Format		= wxTime::wx12h;
+wxTime::tPrecision	wxTime::Precision	= wxTime::wxStdMinSec;
+
+static const unsigned long seconds_in_day = 24*60*60L;
+static const wxDate refDate(1,1,1901);
+// static const wxDate maxDate(49709L);      /* ((2**32)-1)/seconds_in_day -1 */
+
+wxTime wxTime::GetLocalTime(const wxDate& date, hourTy h, minuteTy m, secondTy s)
+/*
+		  Return a local wxTime for the specified Standard Time date, hour, minute,
+		  and second.
+*/
+{
+  if (!wxTimeInitialized)
+  {
+	 wxGetLocalTime(&TIME_ZONE, &DST_OBSERVED);
+	 wxTimeInitialized = TRUE;
+  }
+/*
+		  if (!date.IsBetween(refDate,maxDate))
+					 setError(NIHCL_DATERANGE,DEFAULT,
+								date.dayOfMonth(),date.nameOfMonth(),date.year());
+*/
+  // The following line causes an error in GCC 2.1
+//   long daysBetween = date-refDate;
+  // ... but this seems to get round it.
+  wxDate tmp1(date);
+  wxDate tmp2(refDate);
+  long daysBetween = tmp1 - tmp2;
+
+  return wxTime(seconds_in_day*daysBetween + 60*60L*h + 60*m + s);
+}
+
+wxTime::wxTime()
+/*
+		  Construct a wxTime for this instant.
+*/
+{
+  if (!wxTimeInitialized)
+  {
+	 wxGetLocalTime(&TIME_ZONE, &DST_OBSERVED);
+	 wxTimeInitialized = TRUE;
+  }
+  sec = wxGetCurrentTime();
+  sec += 2177452800L;     /* seconds from 1/1/01 to 1/1/70 */
+}
+
+wxTime::wxTime(hourTy h, minuteTy m, secondTy s, bool dst)
+/*
+		  Construct a wxTime for today at the specified (local) hour, minute, and
+		  second.
+*/
+{
+  if (!wxTimeInitialized)
+  {
+	 wxGetLocalTime(&TIME_ZONE, &DST_OBSERVED);
+	 wxTimeInitialized = TRUE;
+  }
+
+  sec = wxTime(wxDate(),h,m,s,dst).sec;
+}
+
+
+wxTime::wxTime(const wxDate& date, hourTy h, minuteTy m, secondTy s, bool dst)
+/*
+        Construct a wxTime for the specified (local) Date, hour, minute, and
+        second.
+*/
+{
+  if (!wxTimeInitialized)
+  {
+    wxGetLocalTime(&TIME_ZONE, &DST_OBSERVED);
+	 wxTimeInitialized = TRUE;
+  }
+  sec = GetLocalTime(date,h,m,s).sec-3600;
+  if (IsDST())
+  {
+    sec += 3600;
+    if (IsDST() || dst) sec -= 3600;
+  }
+  else
+  {
+    sec += 3600;
+/*
+                if (IsDST()) setError(NIHCL_BADTIME,DEFAULT,
+								date.dayOfMonth(),date.nameOfMonth(),date.year(),
+								h,m,s,(dst?"DST":""));
+*/
+  }
+  sec += TIME_ZONE;                               // adjust to GMT
+}
+
+wxTime::operator wxDate() const
+/*
+		  Convert a wxTime to a local wxDate
+*/
+{
+//      return wxDate((int)(GetLocalTime().sec/seconds_in_day));     4.2 cc bug
+		  long daycount = (long)(GetLocalTime().sec/seconds_in_day);
+
+        wxDate date(1,1,1901);
+        date += daycount;
+        return date;
+}
+
+bool wxTime::IsBetween(const wxTime& a, const wxTime& b) const
+{
+        return *this >= a && *this <= b;
+}
+
+hourTy wxTime::GetHour() const
+/*
+		  Return the hour of this wxTime in local time; i.e., adjust for
+        time zone and Daylight Savings Time.
+*/
+{
+		  return GetLocalTime().GetHourGMT();
+}
+
+hourTy wxTime::GetHourGMT() const
+/*
+        Return the hour of this Time in GMT.
+*/
+{
+		  return (hourTy)((sec % 86400) / 3600);
+}
+
+wxTime wxTime::GetBeginDST(unsigned year)
+/*
+		  Return the local Standard Time at which Daylight Savings Time
+        begins in the specified year.
+*/
+{
+        // Previous Sunday
+        wxTime DSTtime(GetLocalTime(wxDate(3,31,year).Previous(1)+7,2));
+        if (year<=1986) {
+                // Previous Sunday
+					 DSTtime = GetLocalTime(wxDate(4,30,year).Previous(1),2);
+					 if (year==1974) DSTtime = GetLocalTime(wxDate(1,6,1974),2);
+                if (year==1975) DSTtime = GetLocalTime(wxDate(2,23,1975),2);
+        }
+        return DSTtime;
+}
+
+wxTime wxTime::GetEndDST(unsigned year)
+/*
+        Return the local Standard Time at which Daylight Savings Time
+        ends in the specified year.
+*/
+{
+		  wxTime STDtime(GetLocalTime(wxDate(10,31,year).Previous(1),2-1));
+		  return STDtime;
+}
+
+bool wxTime::IsDST() const
+/*
+        Return TRUE if this local Standard Time should be adjusted
+        for Daylight Savings Time.
+*/
+{
+        long daycount = (long)(sec/seconds_in_day);
+
+        // At this point, daycount is the number of days from 1/1/1901.
+		  // Need to convert to julian date (which starts at 1/1/4713 B.C.)
+		  wxDate date(1,1,1901);
+        date += daycount;
+
+        unsigned year = date.GetYear();
+		  if (DST_OBSERVED)
+        {
+                if (*this >= GetBeginDST(year))
+                        if (*this < GetEndDST(year)) return TRUE;
+        }
+        return FALSE;
+}
+
+wxTime wxTime::GetLocalTime() const
+/*
+        Adjusts this GM Time for local time zone and Daylight Savings Time.
+*/
+{
+		  wxTime local_time(sec-TIME_ZONE);
+        if (local_time.IsDST()) local_time.sec += 3600;
+        return local_time;
+}
+
+minuteTy wxTime::GetMinute() const
+/*
+        Return the minute of this wxTime in local time; i.e., adjust
+		  for time zone and Daylight Savings Time.
+*/
+{
+        return GetLocalTime().GetMinuteGMT();
+}
+
+minuteTy wxTime::GetMinuteGMT() const
+/*
+        Return the minute of this wxTime in GMT.
+*/
+{
+		  return (minuteTy)(((sec % 86400) % 3600) / 60);
+}
+
+secondTy wxTime::GetSecond() const
+/*
+        Return the second of this wxTime.
+*/
+{
+		  return (secondTy)(((sec % 86400) % 3600) % 60);
+}
+
+wxTime wxTime::Max(const wxTime& t) const
+{
+        if (t < *this) return *this;
+        return t;
+}
+
+wxTime wxTime::Min(const wxTime& t) const
+{
+        if (t > *this) return *this;
+		  return t;
+}
+
+wxTime::operator char *(void)
+{
+  return FormatTime();
+}
+
+void wxTime::SetFormat(const wxTime::tFormat lFormat,
+							  const wxTime::tPrecision lPrecision) {
+
+	wxTime::Format		= lFormat;
+	wxTime::Precision	= lPrecision;
+}
+
+char *wxTime::FormatTime() const {
+	static char	timeBuf[30];
+	unsigned		hh(GetHour());
+
+	switch (Format) {
+	case wx12h:
+		hh	-= 12;
+		break;
+	case wx24h:
+		break;
+	}
+
+	switch (Precision) {
+	case wxStdMinSec:
+		sprintf(timeBuf,"%2d:%02d:%02d",hh,GetMinute(),GetSecond());
+		break;
+	case wxStdMin:
+		sprintf(timeBuf,"%2d:%02d",hh,GetMinute());
+		break;
+	}
+
+	if (Format == wx12h)
+		if (GetHour() <= 12)
+			strcat(timeBuf,"am");
+		else
+			strcat(timeBuf,"pm");
+
+	return timeBuf;
+}
+
+/*
+int wxTime::compare(const Object& ob) const
+{
+		  assertArgSpecies(ob,classDesc,"compare");
+        register clockTy t = castdown(ob).sec;
+        if (sec < t) return -1;
+        if (sec > t) return 1;
+        return 0;
+}
+
+void wxTime::deepenShallowCopy()  {}
+
+unsigned wxTime::hash() const     { return sec; }
+
+bool wxTime::isEqual(const Object& ob) const
+{
+        return ob.isSpecies(classDesc) && *this==castdown(ob);
+}
+
+const Class* wxTime::species() const { return &classDesc; }
+
+void wxTime::printOn(ostream& strm) const
+{
+        register unsigned hh = GetHour();
+        wxDate(*this).printOn(strm);
+        strm << ' ' << ((hh <= 12) ? hh : hh-12) << ':'
+             << setfill('0') << setw(2) << GetMinute() << ':'
+				 << setfill('0') << setw(2) << GetSecond() << ' ';
+        if (hh < 12) strm << "am";
+        else strm << "pm";
+}
+
+wxTime::wxTime(OIOin& strm)
+		  : BASE(strm)
+{
+		  unsigned long usec;
+		  strm >> sec >> usec;
+}
+
+void wxTime::storer(OIOout& strm) const
+{
+        BASE::storer(strm);
+        strm << sec << 0l;
+}
+
+
+wxTime::wxTime(OIOifd& fd)
+		  : BASE(fd)
+{
+		  unsigned long usec;
+		  fd >> sec >> usec;
+}
+
+void wxTime::storer(OIOofd& fd) const
+{
+		  BASE::storer(fd);
+		  fd << sec << 0l;
+}
+*/
+
+#endif
diff --git a/src/common/timercmn.cpp b/src/common/timercmn.cpp
new file mode 100644
index 0000000000..a13496beff
--- /dev/null
+++ b/src/common/timercmn.cpp
@@ -0,0 +1,207 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        timercmn.cpp
+// Purpose:     Common timer implementation
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+//#pragma implementation "timercmn.h"
+#pragma implementation
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/defs.h"
+#include "wx/list.h"
+#endif
+
+#include "wx/timer.h"
+
+#ifdef __SVR4__
+#define __SYSV__
+#endif
+
+#include <time.h>
+#include <sys/types.h>
+
+#if (!defined(__SC__) && !defined(__SGI__) && !defined(__GNUWIN32__)) || defined(__MINGW32__)
+#include <sys/timeb.h>
+#endif
+
+#if defined(__linux__) || defined(__SVR4__) || defined(__SYSV__) || defined(__SGI__) || defined(__ALPHA__) || defined(__GNUWIN32__)
+#include <sys/time.h>
+#endif
+
+#ifdef __MINGW32__
+#include "windows.h"
+#endif
+
+#if defined(__SUN__) || defined(__OSF__)
+// At least on Sun, ftime is undeclared.
+// Need to be verified on other platforms.
+extern "C" int ftime(struct timeb *tp);
+// extern "C" time_t time(time_t);
+// #include <sys/timeb.h>
+#if defined(__SVR4__) && !defined(__ALPHA__)
+// ditto for gettimeofday on Solaris 2.x.
+extern "C" int gettimeofday(struct timeval *tp, void *);
+#endif
+#endif
+
+/*
+ * Timer functions
+ *
+ */
+
+long wxStartTime = 0;
+void wxStartTimer(void)
+{
+#if defined(__xlC__) || defined(__AIX__) || defined(__SVR4__) || defined(__SYSV__) || (defined(__GNUWIN32__) && !defined(__MINGW32__)) // || defined(__AIXV3__)
+  struct timeval tp;
+#ifdef __SYSV__
+  gettimeofday(&tp, (struct timezone *)NULL);
+#else
+  gettimeofday(&tp);
+#endif
+  wxStartTime = 1000*tp.tv_sec + tp.tv_usec/1000;
+#elif (defined(__SC__) || defined(__SGI__) || defined(___BSDI__) || defined(__ALPHA__) || defined(__MINGW32__))
+  time_t t0;
+  struct tm *tp;
+  time(&t0);
+  tp = localtime(&t0);
+  wxStartTime = 1000*(60*(60*tp->tm_hour+tp->tm_min)+tp->tm_sec);
+#else
+  struct timeb tp;
+  ftime(&tp);
+  wxStartTime = 1000*tp.time + tp.millitm;
+#endif
+}
+
+// Returns elapsed time in milliseconds
+long wxGetElapsedTime(bool resetTimer)
+{
+#if defined(__xlC__) || defined(__AIX__) || defined(__SVR4__) || defined(__SYSV__) || (defined(__GNUWIN32__) && !defined(__MINGW32__)) // || defined(__AIXV3__)
+  struct timeval tp;
+#ifdef __SYSV__
+  gettimeofday(&tp, (struct timezone *)NULL);
+#else
+  gettimeofday(&tp);
+#endif
+  long oldTime = wxStartTime;
+  long newTime = 1000*tp.tv_sec + tp.tv_usec / 1000;
+  if (resetTimer)
+    wxStartTime = newTime;
+#elif (defined(__SC__) || defined(__SGI__) || defined(___BSDI__) || defined(__ALPHA__) || defined(__MINGW32__))
+  time_t t0;
+  struct tm *tp;
+  time(&t0);
+  tp = localtime(&t0);
+  long oldTime = wxStartTime;
+  long newTime = 1000*(60*(60*tp->tm_hour+tp->tm_min)+tp->tm_sec);
+  if (resetTimer)
+    wxStartTime = newTime;
+#else
+  struct timeb tp;
+  ftime(&tp);
+  long oldTime = wxStartTime;
+  long newTime = 1000*tp.time + tp.millitm;
+  if (resetTimer)
+    wxStartTime = newTime;
+#endif
+  return newTime - oldTime;
+}
+
+// EXPERIMENTAL: comment this out if it doesn't compile.
+#ifndef __VMS__
+bool wxGetLocalTime(long *timeZone, int *dstObserved)
+{
+#if defined(__MINGW32__) && defined(__EGCS__)
+  time_t t0;
+  struct tm *tp;
+  time(&t0);
+  tp = localtime(&t0);
+  *timeZone = timezone; // tp->tm_gmtoff; // ???
+  *dstObserved = tp->tm_isdst;
+#elif defined(__MINGW32__)
+  time_t t0;
+  struct tm *tp;
+  time(&t0);
+  tp = localtime(&t0);
+  timeb tz;
+  ftime(& tz);
+  *timeZone = tz._timezone;
+  *dstObserved = tp->tm_isdst;
+#else
+
+#if (((defined(__SYSV__) && !defined(__HPUX__)) || defined(__MSDOS__) || defined(__WINDOWS__)) && !defined(__GNUWIN32__))
+#ifdef __BORLANDC__
+  /* Borland uses underscores */
+  *timeZone = _timezone;
+  *dstObserved = _daylight;
+#else
+  *timeZone = timezone;
+  *dstObserved = daylight;
+#endif
+#elif defined(__xlC__) || defined(__AIX__) || defined(__SVR4__) || defined(__SYSV__) || (defined(__GNUWIN32__) && !defined(__MINGW32__)) // || defined(__AIXV3__)
+  struct timeval tp;
+#if defined(__SYSV__) || (defined(__GNUWIN32__) && !defined(__MINGW32))
+  struct timezone tz;
+  gettimeofday(&tp, &tz);
+  *timeZone = 60*(tz.tz_minuteswest);
+  *dstObserved = tz.tz_dsttime;
+#else
+  time_t t0;
+  struct tm *tp;
+  time(&t0);
+  tp = localtime(&t0);
+  *timeZone = tp->tm_gmtoff; // ???
+  *dstObserved = tp->tm_isdst;
+#endif
+#else
+// #error wxGetLocalTime not implemented.
+  struct timeval tp;
+  struct timezone tz;
+  gettimeofday(&tp, &tz);
+  *timeZone = 60*(tz.tz_minuteswest);
+  *dstObserved = tz.tz_dsttime;
+#endif
+#endif
+  // __MINGW32__
+  return TRUE;
+}
+#endif
+
+// Get number of seconds since 00:00:00 GMT, Jan 1st 1970.
+long wxGetCurrentTime(void)
+{
+#if defined(__xlC__) || defined(__AIX__) || defined(__SVR4__) || defined(__SYSV__) // || defined(__AIXV3__)
+  struct timeval tp;
+#ifdef __SYSV__
+  gettimeofday(&tp, (struct timezone *)NULL);
+#else
+  gettimeofday(&tp);
+#endif
+  return tp.tv_sec;
+#else // (defined(__SC__) || defined(__SGI__) || defined(___BSDI__) || defined(__ALPHA__))
+  return time(0);
+#endif
+/*
+#else
+  struct timeb tp;
+  ftime(&tp);
+  return tp.time;
+#endif
+*/
+}
+
diff --git a/src/common/utilscmn.cpp b/src/common/utilscmn.cpp
new file mode 100644
index 0000000000..349d6f04a0
--- /dev/null
+++ b/src/common/utilscmn.cpp
@@ -0,0 +1,742 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        utilscmn.cpp
+// Purpose:     Miscellaneous utility functions and classes
+// Author:      Julian Smart
+// Modified by:
+// Created:     29/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) 1998 Julian Smart
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "utils.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/defs.h"
+#include "wx/utils.h"
+#include "wx/window.h"
+#include "wx/menu.h"
+#include "wx/frame.h"
+#endif
+
+#if USE_IOSTREAMH
+#include <iostream.h>
+#else
+#include <iostream>
+#endif
+
+#include <fstream.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if !defined(__WATCOMC__)
+#if !(defined(_MSC_VER) && (_MSC_VER > 800))
+#include <errno.h>
+#endif
+#endif
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+// Pattern matching code.
+// Yes, this path is deliberate (for Borland compilation)
+#ifdef wx_mac /* MATTHEW: [5] Mac doesn't like paths with "/" */
+#include "glob.inc"
+#else
+#include "../common/glob.inc"
+#endif
+
+#ifdef __WINDOWS__
+#include "windows.h"
+#endif
+
+#define _MAXPATHLEN 500
+
+extern char *wxBuffer;
+
+#ifdef __VMS__
+// we have no strI functions under VMS, therefore I have implemented
+// an inefficient but portable version: convert copies of strings to lowercase
+// and then use the normal comparison
+static void myLowerString(char *s)
+{
+  while(*s){
+    if(isalpha(*s)) *s = (char)tolower(*s);
+    s++;
+  }
+}
+
+int strcasecmp(const char *str_1, const char *str_2)
+{
+  char *temp1 = new char[strlen(str_1)+1];
+  char *temp2 = new char[strlen(str_2)+1];
+  strcpy(temp1,str_1);
+  strcpy(temp2,str_2);
+  myLowerString(temp1);
+  myLowerString(temp2);
+
+  int result = strcmp(temp1,temp2);
+  delete[] temp1;
+  delete[] temp2;
+
+  return(result);
+}
+
+int strncasecmp(const char *str_1, const char *str_2, size_t maxchar)
+{
+  char *temp1 = new char[strlen(str_1)+1];
+  char *temp2 = new char[strlen(str_2)+1];
+  strcpy(temp1,str_1);
+  strcpy(temp2,str_2);
+  myLowerString(temp1);
+  myLowerString(temp2);
+
+  int result = strncmp(temp1,temp2,maxchar);
+  delete[] temp1;
+  delete[] temp2;
+
+  return(result);
+}
+#endif
+
+#ifdef __WINDOWS__
+
+#ifndef __GNUWIN32__
+#define strcasecmp stricmp
+#define strncasecmp strnicmp
+#endif
+
+#ifdef _MSC_VER
+#pragma warning (disable : 4245)
+#endif
+
+#ifdef _MSC_VER
+#pragma warning (default : 4245)
+#endif
+
+#else
+// This declaration is missing in SunOS!
+// (Yes, I know it is NOT ANSI-C but its in BSD libc)
+#if defined(__xlC) || defined(__AIX__) || defined(__GNUG__)
+extern "C"
+{
+  int strcasecmp (const char *, const char *);
+  int strncasecmp (const char *, const char *, size_t);
+}
+#endif
+#endif				/* __WINDOWS__ */
+
+
+char *
+copystring (const char *s)
+{
+  if (s == NULL) s = "";
+  size_t len = strlen (s) + 1;
+
+  char *news = new char[len];
+  memcpy (news, s, len);	// Should be the fastest
+
+  return news;
+}
+
+// Id generation
+static long wxCurrentId = 100;
+
+long 
+wxNewId (void)
+{
+  return wxCurrentId++;
+}
+
+long
+wxGetCurrentId(void) { return wxCurrentId; }
+
+void 
+wxRegisterId (long id)
+{
+  if (id >= wxCurrentId)
+    wxCurrentId = id + 1;
+}
+
+void 
+StringToFloat (char *s, float *number)
+{
+  if (s && *s && number)
+    *number = (float) strtod (s, NULL);
+}
+
+void 
+StringToDouble (char *s, double *number)
+{
+  if (s && *s && number)
+    *number = strtod (s, NULL);
+}
+
+char *
+FloatToString (float number, const char *fmt)
+{
+  static char buf[256];
+
+//  sprintf (buf, "%.2f", number);
+  sprintf (buf, fmt, number);
+  return buf;
+}
+
+char *
+DoubleToString (double number, const char *fmt)
+{
+  static char buf[256];
+
+  sprintf (buf, fmt, number);
+  return buf;
+}
+
+void 
+StringToInt (char *s, int *number)
+{
+  if (s && *s && number)
+    *number = (int) strtol (s, NULL, 10);
+}
+
+void 
+StringToLong (char *s, long *number)
+{
+  if (s && *s && number)
+    *number = strtol (s, NULL, 10);
+}
+
+char *
+IntToString (int number)
+{
+  static char buf[20];
+
+  sprintf (buf, "%d", number);
+  return buf;
+}
+
+char *
+LongToString (long number)
+{
+  static char buf[20];
+
+  sprintf (buf, "%ld", number);
+  return buf;
+}
+
+// Array used in DecToHex conversion routine.
+static char hexArray[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B',
+  'C', 'D', 'E', 'F' };
+
+// Convert 2-digit hex number to decimal
+int wxHexToDec(char *buf)
+{
+  int firstDigit, secondDigit;
+  
+  if (buf[0] >= 'A')
+    firstDigit = buf[0] - 'A' + 10;
+  else
+    firstDigit = buf[0] - '0';
+
+  if (buf[1] >= 'A')
+    secondDigit = buf[1] - 'A' + 10;
+  else
+    secondDigit = buf[1] - '0';
+    
+  return firstDigit * 16 + secondDigit;
+}
+
+// Convert decimal integer to 2-character hex string
+void wxDecToHex(int dec, char *buf)
+{
+  int firstDigit = (int)(dec/16.0);
+  int secondDigit = (int)(dec - (firstDigit*16.0));
+  buf[0] = hexArray[firstDigit];
+  buf[1] = hexArray[secondDigit];
+  buf[2] = 0;
+}
+
+// Match a string INDEPENDENT OF CASE
+bool 
+StringMatch (char *str1, char *str2, bool subString, bool exact)
+{
+  if (str1 == NULL || str2 == NULL)
+    return FALSE;
+  if (str1 == str2)
+    return TRUE;
+
+  if (subString)
+    {
+      int len1 = strlen (str1);
+      int len2 = strlen (str2);
+      int i;
+
+      // Search for str1 in str2
+      // Slow .... but acceptable for short strings
+      for (i = 0; i <= len2 - len1; i++)
+	{
+	  if (strncasecmp (str1, str2 + i, len1) == 0)
+	    return TRUE;
+	}
+    }
+  else if (exact)
+    {
+      if (strcasecmp (str1, str2) == 0)
+	return TRUE;
+    }
+  else
+    {
+      int len1 = strlen (str1);
+      int len2 = strlen (str2);
+
+      if (strncasecmp (str1, str2, wxMin (len1, len2)) == 0)
+	return TRUE;
+    }
+
+  return FALSE;
+}
+
+// Return the current date/time
+// [volatile]
+wxString wxNow( void )
+{
+  time_t now = time(NULL);
+  char *date = ctime(&now); 
+  date[24] = '\0';
+  return wxString(date);
+}
+
+/* Get Full RFC822 style email address */
+bool
+wxGetEmailAddress (char *address, int maxSize)
+{
+  char host[65];
+  char user[65];
+
+  if (wxGetHostName(host, 64) == FALSE)
+    return FALSE;
+  if (wxGetUserId(user, 64) == FALSE)
+    return FALSE;
+
+  char tmp[130];
+  strcpy(tmp, user);
+  strcat(tmp, "@");
+  strcat(tmp, host);
+
+  strncpy(address, tmp, maxSize - 1);
+  address[maxSize-1] = '\0';
+  return TRUE;
+}
+
+/*
+ * Strip out any menu codes
+ */
+
+char *wxStripMenuCodes (char *in, char *out)
+{
+  if (!in)
+    return NULL;
+    
+  if (!out)
+    out = copystring(in);
+
+  char *tmpOut = out;
+  
+  while (*in)
+    {
+      if (*in == '&')
+	{
+	  // Check && -> &, &x -> x
+	  if (*++in == '&')
+	    *out++ = *in++;
+	}
+      else if (*in == '\t')
+	{
+          // Remove all stuff after \t in X mode, and let the stuff as is
+          // in Windows mode.
+          // Accelerators are handled in wx_item.cc for Motif, and are not
+          // YET supported in XView
+	  break;
+	}
+      else
+	*out++ = *in++;
+    }				// while
+
+  *out = '\0';
+
+  return tmpOut;
+}
+
+
+/*
+ * Window search functions
+ *
+ */
+
+/*
+ * If parent is non-NULL, look through children for a label or title
+ * matching the specified string. If NULL, look through all top-level windows.
+ *
+ */
+
+static wxWindow *wxFindWindowByLabel1 (const wxString& title, wxWindow * parent);
+
+wxWindow *
+wxFindWindowByLabel (const wxString& title, wxWindow * parent)
+{
+  if (parent)
+    {
+      return wxFindWindowByLabel1 (title, parent);
+    }
+  else
+    {
+      for (wxNode * node = wxTopLevelWindows.First (); node; node = node->Next ())
+	{
+	  wxWindow *win = (wxWindow *) node->Data ();
+	  wxWindow *retwin = wxFindWindowByLabel1 (title, win);
+	  if (retwin)
+	    return retwin;
+	}			// for()
+
+    }
+  return NULL;
+}
+
+// Recursive
+static wxWindow *
+wxFindWindowByLabel1 (const wxString& title, wxWindow * parent)
+{
+  if (parent)
+    {
+      if (parent->GetLabel() == title)
+		return parent;
+    }
+
+  if (parent)
+    {
+      for (wxNode * node = parent->GetChildren()->First (); node; node = node->Next ())
+	{
+	  wxWindow *win = (wxWindow *) node->Data ();
+	  wxWindow *retwin = wxFindWindowByLabel1 (title, win);
+	  if (retwin)
+	    return retwin;
+	}			// for()
+
+    }
+
+  return NULL;			// Not found
+
+}
+
+/*
+ * If parent is non-NULL, look through children for a name
+ * matching the specified string. If NULL, look through all top-level windows.
+ *
+ */
+
+static wxWindow *wxFindWindowByName1 (const wxString& title, wxWindow * parent);
+
+wxWindow *
+wxFindWindowByName (const wxString& title, wxWindow * parent)
+{
+  if (parent)
+    {
+      return wxFindWindowByName1 (title, parent);
+    }
+  else
+    {
+      for (wxNode * node = wxTopLevelWindows.First (); node; node = node->Next ())
+	{
+	  wxWindow *win = (wxWindow *) node->Data ();
+	  wxWindow *retwin = wxFindWindowByName1 (title, win);
+	  if (retwin)
+	    return retwin;
+	}			// for()
+
+    }
+  // Failed? Try by label instead.
+  return wxFindWindowByLabel(title, parent);
+}
+
+// Recursive
+static wxWindow *
+wxFindWindowByName1 (const wxString& title, wxWindow * parent)
+{
+  if (parent)
+    {
+    	if ( parent->GetName() == title )
+			return parent;
+    }
+
+  if (parent)
+    {
+      for (wxNode * node = parent->GetChildren()->First (); node; node = node->Next ())
+	{
+	  wxWindow *win = (wxWindow *) node->Data ();
+	  wxWindow *retwin = wxFindWindowByName1 (title, win);
+	  if (retwin)
+	    return retwin;
+	}			// for()
+
+    }
+
+  return NULL;			// Not found
+
+}
+
+// Returns menu item id or -1 if none.
+int 
+wxFindMenuItemId (wxFrame * frame, const wxString& menuString, const wxString& itemString)
+{
+  wxMenuBar *menuBar = frame->GetMenuBar ();
+  if (!menuBar)
+    return -1;
+  return menuBar->FindMenuItem (menuString, itemString);
+}
+
+/*
+ * wxDebugStreamBuf
+ */
+#if !defined(_WINDLL)
+ 
+wxDebugStreamBuf::wxDebugStreamBuf(void)
+{
+  if (allocate()) setp(base(),ebuf());
+}
+
+int wxDebugStreamBuf::overflow(int WXUNUSED(i))
+{
+  int len = pptr() - pbase();
+  char *txt = new char[len+1];
+  strncpy(txt, pbase(), len);
+  txt[len] = '\0';
+#ifdef __WINDOWS__
+  OutputDebugString((LPCSTR)txt);
+#else
+  fprintf(stderr, txt);
+#endif
+  setp(pbase(), epptr());
+  delete[] txt;
+  return EOF;
+}
+
+int wxDebugStreamBuf::sync(void)
+{
+  int len = pptr() - pbase();
+  char *txt = new char[len+1];
+  strncpy(txt, pbase(), len);
+  txt[len] = '\0';
+#ifdef __WINDOWS__
+  OutputDebugString((LPCSTR)txt);
+#else
+  fprintf(stderr, txt);
+#endif
+  setp(pbase(), epptr());
+  delete[] txt;
+  return 0;
+}
+
+#endif
+
+/*
+On Fri, 21 Jul 1995, Paul Craven wrote:
+
+> Is there a way to find the path of running program's executable? I can get
+> my home directory, and the current directory, but I don't know how to get the
+> executable directory.
+> 
+
+The code below (warty as it is), does what you want on most Unix,
+DOS, and Mac platforms (it's from the ALS Prolog main).
+
+|| Ken Bowen      Applied Logic Systems, Inc.         PO Box 180,     
+||====            Voice:  +1 (617)965-9191            Newton Centre,
+||                FAX:    +1 (617)965-1636            MA  02159  USA
+                  Email:  ken@als.com        WWW: http://www.als.com
+------------------------------------------------------------------------
+*/
+
+// This code is commented out but it may be integrated with wxWin at
+// a later date, after testing. Thanks Ken!
+#if 0
+
+/*--------------------------------------------------------------------*
+ | whereami is given a filename f in the form:  whereami(argv[0])
+ | It returns the directory in which the executable file (containing 
+ | this code [main.c] ) may be found.  A dot will be returned to indicate 
+ | the current directory.
+ *--------------------------------------------------------------------*/
+
+static void
+whereami(name)
+    char *name;
+{
+    register char *cutoff = NULL;	/* stifle -Wall */
+    register char *s;
+    register char *t;
+    int   cc;
+    char  ebuf[4096];
+
+    /*
+     * See if the file is accessible either through the current directory
+     * or through an absolute path.
+     */
+
+    if (access(name, R_OK) == 0) {
+
+	/*-------------------------------------------------------------*
+	 * The file was accessible without any other work.  But the current
+	 * working directory might change on us, so if it was accessible
+	 * through the cwd, then we should get it for later accesses.
+	 *-------------------------------------------------------------*/
+
+	t = imagedir;
+	if (!absolute_pathname(name)) {
+#if defined(DOS) || defined(__WIN32__)
+	    int   drive;
+	    char *newrbuf;
+
+	    newrbuf = imagedir;
+#ifndef __DJGPP__
+	    if (*(name + 1) == ':') {
+		if (*name >= 'a' && *name <= 'z')
+		    drive = (int) (*name - 'a' + 1);
+		else
+		    drive = (int) (*name - 'A' + 1);
+		*newrbuf++ = *name;
+		*newrbuf++ = *(name + 1);
+		*newrbuf++ = DIR_SEPARATOR;
+	    }
+	    else {
+		drive = 0;
+		*newrbuf++ = DIR_SEPARATOR;
+	    }
+	    if (getcwd(newrbuf, drive) == 0) {	/* } */
+#else
+	    if (getcwd(newrbuf, 1024) == 0) {	/* } */
+#endif
+#else  /* DOS */
+#ifdef HAVE_GETWD
+	    if (getwd(imagedir) == 0) {		/* } */
+#else  /* !HAVE_GETWD */
+	    if (getcwd(imagedir, 1024) == 0) {
+#endif /* !HAVE_GETWD */
+#endif /* DOS */
+		fatal_error(FE_GETCWD, 0);
+	    }
+	    for (; *t; t++)	/* Set t to end of buffer */
+		;
+	    if (*(t - 1) == DIR_SEPARATOR)	/* leave slash if already
+						 * last char
+						 */
+		cutoff = t - 1;
+	    else {
+		cutoff = t;	/* otherwise put one in */
+		*t++ = DIR_SEPARATOR;
+	    }
+	}
+#if (!defined(__MAC__) && !defined(__DJGPP__) && !defined(__GO32__) && !defined(__WIN32__))
+	else
+		(*t++ = DIR_SEPARATOR);
+#endif
+
+	/*-------------------------------------------------------------*
+	 * Copy the rest of the string and set the cutoff if it was not
+	 * already set.  If the first character of name is a slash, cutoff
+	 * is not presently set but will be on the first iteration of the
+	 * loop below.
+	 *-------------------------------------------------------------*/
+
+	for ((*name == DIR_SEPARATOR ? (s = name+1) : (s = name));;) {
+	    if (*s == DIR_SEPARATOR)
+			cutoff = t;
+	    if (!(*t++ = *s++))
+			break;
+	}
+
+    }
+    else {
+
+	/*-------------------------------------------------------------*
+	 * Get the path list from the environment.  If the path list is
+	 * inaccessible for any reason, leave with fatal error.
+	 *-------------------------------------------------------------*/
+
+#ifdef __MAC__
+	if ((s = getenv("Commands")) == (char *) 0)
+#else
+	if ((s = getenv("PATH")) == (char *) 0)
+#endif
+	    fatal_error(FE_PATH, 0);
+
+	/*
+	 * Copy path list into ebuf and set the source pointer to the
+	 * beginning of this buffer.
+	 */
+
+	strcpy(ebuf, s);
+	s = ebuf;
+
+	for (;;) {
+	    t = imagedir;
+	    while (*s && *s != PATH_SEPARATOR)
+		*t++ = *s++;
+	    if (t > imagedir && *(t - 1) == DIR_SEPARATOR) 
+		;		/* do nothing -- slash already is in place */
+	    else
+		*t++ = DIR_SEPARATOR;	/* put in the slash */
+	    cutoff = t - 1;	/* set cutoff */
+	    strcpy(t, name);
+	    if (access(imagedir, R_OK) == 0)
+		break;
+
+	    if (*s)
+		s++;		/* advance source pointer */
+	    else
+		fatal_error(FE_INFND, 0);
+	}
+
+    }
+
+    /*-------------------------------------------------------------*
+     | At this point the full pathname should exist in imagedir and
+     | cutoff should be set to the final slash.  We must now determine
+     | whether the file name is a symbolic link or not and chase it down
+     | if it is.  Note that we reuse ebuf for getting the link.
+     *-------------------------------------------------------------*/
+
+#ifdef HAVE_SYMLINK
+    while ((cc = readlink(imagedir, ebuf, 512)) != -1) {
+	ebuf[cc] = 0;
+	s = ebuf;
+	if (*s == DIR_SEPARATOR) {
+	    t = imagedir;
+	}
+	else {
+	    t = cutoff + 1;
+	}
+	for (;;) {
+	    if (*s == DIR_SEPARATOR)
+		cutoff = t;	/* mark the last slash seen */
+	    if (!(*t++ = *s++))	/* copy the character */
+		break;
+	}
+    }
+
+#endif /* HAVE_SYMLINK */
+
+    strcpy(imagename, cutoff + 1);	/* keep the image name */
+    *(cutoff + 1) = 0;		/* chop off the filename part */
+}
+
+#endif
+
diff --git a/src/common/validate.cpp b/src/common/validate.cpp
new file mode 100644
index 0000000000..af5104d428
--- /dev/null
+++ b/src/common/validate.cpp
@@ -0,0 +1,44 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        validate.cpp
+// Purpose:     wxValidator
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "validate.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx.h"
+#endif
+
+#include "wx/validate.h"
+
+const wxValidator wxDefaultValidator;
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxValidator, wxEvtHandler)
+#endif
+
+wxValidator::wxValidator(void)
+{
+  m_validatorWindow = NULL;
+}
+
+wxValidator::~wxValidator()
+{
+}
+
+
diff --git a/src/common/valtext.cpp b/src/common/valtext.cpp
new file mode 100644
index 0000000000..6346404d47
--- /dev/null
+++ b/src/common/valtext.cpp
@@ -0,0 +1,293 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        valtext.cpp
+// Purpose:     wxTextValidator
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "valtext.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include <stdio.h>
+#include "wx/textctrl.h"
+#include "wx/utils.h"
+#include "wx/msgbxdlg.h"
+#endif
+
+#include "wx/valtext.h"
+
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxTextValidator, wxValidator)
+
+BEGIN_EVENT_TABLE(wxTextValidator, wxValidator)
+	EVT_CHAR(wxTextValidator::OnChar)
+END_EVENT_TABLE()
+#endif
+
+wxTextValidator::wxTextValidator(const long style, wxString *val)
+{
+	m_validatorStyle = style ;
+	m_stringValue = val ;
+/*
+    m_refData = new wxVTextRefData;
+
+	M_VTEXTDATA->m_validatorStyle = style ;
+	M_VTEXTDATA->m_stringValue = val ;
+*/
+}
+
+wxTextValidator::wxTextValidator(const wxTextValidator& val)
+{
+    Copy(val);
+}
+
+bool wxTextValidator::Copy(const wxTextValidator& val)
+{
+    wxValidator::Copy(val);
+
+	m_validatorStyle = val.m_validatorStyle ;
+	m_stringValue = val.m_stringValue ;
+
+	wxNode *node = val.m_includeList.First() ;
+	while ( node )
+	{
+		char *s = (char *)node->Data();
+		m_includeList.Add(s);
+		node = node->Next();
+	}
+	node = val.m_excludeList.First() ;
+	while ( node )
+	{
+		char *s = (char *)node->Data();
+		m_excludeList.Add(s);
+		node = node->Next();
+	}
+    return TRUE;
+}
+
+wxTextValidator::~wxTextValidator()
+{
+}
+
+static bool wxIsAlpha(const wxString& val)
+{
+	int i;
+	for ( i = 0; i < (int)val.Length(); i++)
+	{
+		if (!isalpha(val[i]))
+			return FALSE;
+	}
+	return TRUE;
+}
+
+static bool wxIsAlphaNumeric(const wxString& val)
+{
+	int i;
+	for ( i = 0; i < (int)val.Length(); i++)
+	{
+		if (!isalnum(val[i]))
+			return FALSE;
+	}
+	return TRUE;
+}
+
+// Called when the value in the window must be validated.
+// This function can pop up an error message.
+bool wxTextValidator::Validate(wxWindow *parent)
+{
+	if ( !m_validatorWindow )
+		return FALSE;
+	if ( !m_validatorWindow->IsKindOf(CLASSINFO(wxTextCtrl)) )
+		return FALSE;
+	if ( !m_stringValue )
+		return FALSE;
+
+	wxTextCtrl *control = (wxTextCtrl *) m_validatorWindow ;
+
+	// If window is disabled, don't validate
+	if ( !control->Enabled() )
+		return FALSE;
+
+	wxString val(control->GetValue());
+
+	if ( m_validatorStyle & wxFILTER_INCLUDE_LIST )
+	{
+		if ( !m_includeList.Member(val) )
+		{
+			char buf[512];
+			sprintf(buf, "%s is invalid.", (const char *)val);
+			wxMessageBox(buf, "Validation conflict", wxOK | wxICON_EXCLAMATION, parent);
+			return FALSE;
+		}
+	}
+	if ( m_validatorStyle & wxFILTER_EXCLUDE_LIST )
+	{
+		if ( m_excludeList.Member(val) )
+		{
+			char buf[512];
+			sprintf(buf, "%s is invalid.", (const char *)val);
+			wxMessageBox(buf, "Validation conflict", wxOK | wxICON_EXCLAMATION, parent);
+			return FALSE;
+		}
+	}
+	if ( (m_validatorStyle & wxFILTER_ASCII) && !val.IsAscii() )
+	{
+			char buf[512];
+			sprintf(buf, "%s should only contain ASCII characters.", (const char *)val);
+			wxMessageBox(buf, "Validation conflict", wxOK | wxICON_EXCLAMATION, parent);
+			return FALSE;
+	}
+	if ( (m_validatorStyle & wxFILTER_ALPHA) && !wxIsAlpha(val) )
+	{
+			char buf[512];
+			sprintf(buf, "%s should only contain alphabetic characters.", (const char *)val);
+			wxMessageBox(buf, "Validation conflict", wxOK | wxICON_EXCLAMATION, parent);
+			return FALSE;
+	}
+	if ( (m_validatorStyle & wxFILTER_ALPHANUMERIC) && !wxIsAlphaNumeric(val))
+	{
+			char buf[512];
+			sprintf(buf, "%s should only contain alphabetic or numeric characters.", (const char *)val);
+			wxMessageBox(buf, "Validation conflict", wxOK | wxICON_EXCLAMATION, parent);
+			return FALSE;
+	}
+	if ( (m_validatorStyle & wxFILTER_NUMERIC) && !val.IsNumber())
+	{
+			char buf[512];
+			sprintf(buf, "%s should be numeric.", (const char *)val);
+			wxMessageBox(buf, "Validation conflict", wxOK | wxICON_EXCLAMATION, parent);
+			return FALSE;
+	}
+
+	return TRUE ;
+}
+
+// Called to transfer data to the window
+bool wxTextValidator::TransferToWindow(void)
+{
+	if ( !m_validatorWindow )
+		return FALSE;
+	if ( !m_validatorWindow->IsKindOf(CLASSINFO(wxTextCtrl)) )
+		return FALSE;
+	if ( !m_stringValue )
+		return FALSE;
+
+	wxTextCtrl *control = (wxTextCtrl *) m_validatorWindow ;
+	control->SetValue(* m_stringValue) ;
+
+	return TRUE;
+}
+
+// Called to transfer data to the window
+bool wxTextValidator::TransferFromWindow(void)
+{
+	if ( !m_validatorWindow )
+		return FALSE;
+	if ( !m_validatorWindow->IsKindOf(CLASSINFO(wxTextCtrl)) )
+		return FALSE;
+	if ( !m_stringValue )
+		return FALSE;
+
+	wxTextCtrl *control = (wxTextCtrl *) m_validatorWindow ;
+	* m_stringValue = control->GetValue() ;
+
+	return TRUE;
+}
+
+void wxTextValidator::SetIncludeList(const wxStringList& list)
+{
+/*
+	if ( !M_VTEXTDATA )
+		return;
+*/
+
+	m_includeList.Clear();
+	// TODO: replace with =
+	wxNode *node = list.First() ;
+	while ( node )
+	{
+		char *s = (char *)node->Data();
+		m_includeList.Add(s);
+		node = node->Next();
+	}
+}
+
+void wxTextValidator::SetExcludeList(const wxStringList& list)
+{
+/*
+	if ( !M_VTEXTDATA )
+		return;
+*/
+
+	m_excludeList.Clear();
+	// TODO: replace with =
+	wxNode *node = list.First() ;
+	while ( node )
+	{
+		char *s = (char *)node->Data();
+		m_excludeList.Add(s);
+		node = node->Next();
+	}
+}
+
+void wxTextValidator::OnChar(wxKeyEvent& event)
+{
+/*
+	if ( !M_VTEXTDATA )
+		return;
+*/
+
+	if ( !m_validatorWindow )
+		return;
+
+	wxTextCtrl *textCtrl = (wxTextCtrl *)m_validatorWindow;
+
+	int keyCode = event.KeyCode();
+	if ( keyCode == WXK_DELETE || keyCode == WXK_RETURN || keyCode == WXK_BACK)
+	{
+		textCtrl->wxTextCtrl::OnChar(event);
+		return ;
+	}
+
+	if ( (m_validatorStyle & wxFILTER_ASCII) && !isascii(keyCode) )
+	{
+		wxBell();
+		return;
+	}
+	if ( (m_validatorStyle & wxFILTER_ALPHA) && !isalpha(keyCode) )
+	{
+		wxBell();
+		return;
+	}
+	if ( (m_validatorStyle & wxFILTER_ALPHANUMERIC) && !isalnum(keyCode) )
+	{
+		wxBell();
+		return;
+	}
+	if ( (m_validatorStyle & wxFILTER_NUMERIC) && !isdigit(keyCode) && keyCode != '.' )
+	{
+		wxBell();
+		return;
+	}
+
+	textCtrl->wxTextCtrl::OnChar(event);
+}
+
+
diff --git a/src/gdk_imlib/AUDIT b/src/gdk_imlib/AUDIT
new file mode 100644
index 0000000000..e69b50738d
--- /dev/null
+++ b/src/gdk_imlib/AUDIT
@@ -0,0 +1,26 @@
+Audit status of gdk_imlib so far:
+
+cache.c appears clean
+globals.c appears clean
+
+load.c:
+	JPEG, PNG, GIF and TIFF loaders seem safe but the underlying
+		yet libraries have not been checked
+	Helper stuff should now be safe.
+
+misc.c
+	The obvious screwups have been remedied with the usual 
+	length checking sscanfs and snprintfs.
+	Rewrote a little of the parsing code to avoid future problems.
+
+rend.c
+	Appears ok
+
+save.c 
+	Some stuff has been fixed. The helpers should be safe but
+	are incomplete
+
+utils.c
+	Ok this seems clean now. There's a few  FIXME's but they are
+	either new features (helper needs %Q) or bogus but non fatal
+	stuff
diff --git a/src/gdk_imlib/AUTHORS b/src/gdk_imlib/AUTHORS
new file mode 100644
index 0000000000..2c8f9861b2
--- /dev/null
+++ b/src/gdk_imlib/AUTHORS
@@ -0,0 +1 @@
+Rasterdude :-) <raster@redhat.com>
diff --git a/src/gdk_imlib/COPYING.LIB b/src/gdk_imlib/COPYING.LIB
new file mode 100644
index 0000000000..eb685a5ec9
--- /dev/null
+++ b/src/gdk_imlib/COPYING.LIB
@@ -0,0 +1,481 @@
+		  GNU LIBRARY GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+                    675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL.  It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it.  You can use it for
+your libraries, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library.  If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software.  To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+  Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs.  This
+license, the GNU Library General Public License, applies to certain
+designated libraries.  This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+  The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it.  Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program.  However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+  Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries.  We
+concluded that weaker conditions might promote sharing better.
+
+  However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves.  This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them.  (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.)  The hope is that this
+will lead to faster development of free libraries.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+  Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+		  GNU LIBRARY GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License").  Each licensee is
+addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    c) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    d) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+     Appendix: How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/src/gdk_imlib/ChangeLog b/src/gdk_imlib/ChangeLog
new file mode 100644
index 0000000000..67cab52052
--- /dev/null
+++ b/src/gdk_imlib/ChangeLog
@@ -0,0 +1,74 @@
+1998-05-07  Raja R Harinath  <harinath@cs.umn.edu>
+
+	* save.c (gdk_imlib_save_image): Replaces `snprintf' with
+	`g_snprintf' calls. 
+	* utils.c (gdk_imlib_create_image_from_data): Likewise.
+
+Tue May  5 15:11:59 1998  Radek Doulik  <gis@academy.cas.cz>
+
+	* replaced snprintf calls with g_snprintf ones, so it
+	compiles now on SunOS 
+
+Sat Apr 11 12:30:13 1998  George Lebl  <jirka@5z.com>
+
+	* utils.c: fixed yet one more SIGFPE on alpha
+
+Fri Mar 20 00:02:43 1998  Tom Tromey  <tromey@cygnus.com>
+
+	* gdk_imlib.h: Replaced `()' with `(void)'.
+
+Sun Mar 15 12:34:45 1998  Owen Taylor <owt1@cornell.edu>
+
+	* Makefile.am (INCLUDES): Added GTK_CFLAGS
+
+1998-02-25  Raja R Harinath  <harinath@cs.umn.edu>
+
+	* Makefile.am (DEFS): Define `SYSTEM_IMRC' too.
+
+1998-02-25  Federico Mena Quintero  <federico@nuclecu.unam.mx>
+
+	* misc.c (gdk_imlib_copy_image): The drawable passed to gdk_gc_new
+	should be the dest drawable, not the base imlib window.  This
+	caused BadMatches all over the place (especially in copy_mask).
+	(gdk_imlib_copy_mask): Likewise.
+
+1998-02-24  Raja R Harinath  <harinath@cs.umn.edu>
+
+	* Makefile.am (DEFS): New var.  Moved stuff from CFLAGS.
+	(INCLUDES): New var.
+
+1998-02-24  Mark Galassi  <rosalia@cygnus.com>
+
+	* Makefile.am (libgdk_imlib_la_SOURCES):
+	(lib_LTLIBRARIES): changed gdk_imlib to use the libtool+automake
+	formalisms.
+
+	* load.c (gdk_imlib_load_image): changed JPEG_PATH to DJPEG_PROG
+	and removed %s/djpeg, sine DJPEG_PROG is the full program path.
+
+1998-02-17  Federico Mena Quintero  <federico@nuclecu.unam.mx>
+
+	* Makefile.in (install): Make directory for config files.
+
+	* configure.in: Fixed ENL_LIB_SUPPORT function for non-existing libraries.
+
+1998-02-16  Federico Mena Quintero  <federico@nuclecu.unam.mx>
+
+	* misc.c (gdk_imlib_init): I create a colormap specific to the
+	visual the base_window will be using.  This fixes BadMatch errors
+	on machines with multiple visual/depth combinations.
+
+1998-02-17 The Rasterman <raster@redhat.com>
+
+        * misc.c (gdk_imlib_init) Fixed visual stuff slightly, and Colormap 
+	creation (so it only does so if the visual for the default and the 
+	chosen visual mismatch), added function calls to retrieve Imlib's 
+	visual and Colormap, plus endianess fixes for network displaying.
+
+1998-02-17 The Rasterman <raster@redhat.com>
+
+	added system imrc config return function
+
+1998-02-18 The Rasterman <raster@redhat.com>
+
+	Fixed load.c - missed a not (!) in an if clause
diff --git a/src/gdk_imlib/README b/src/gdk_imlib/README
new file mode 100644
index 0000000000..ac167f6462
--- /dev/null
+++ b/src/gdk_imlib/README
@@ -0,0 +1,29 @@
+-------------------------------------------------------------------------------
+                                I   M   L   I   B
+				       1.4
+-------------------------------------------------------------------------------
+
+This software is Copyright (C) 1998 By The Rasterman (Carsten Haitzler). I
+accept no responsability for anythign this software may or may not do to
+your system - you use it completely at your own risk. This software comes
+under the LGPL and GPL licences. The library itself is LGPL (all software in
+Imlib and gdk_imlib directories) see the COPYING and COPYING.LIB files for
+full legal details.
+
+-------------------------------------------------------------------------------
+
+If you have picked up a net release of imlib you should be able to
+just follow the instructions in the INSTALL file.
+
+If you are using imlib out of the CVS repository, then you need to
+have some extra tools installed, and the configuration process is
+lengthier.  the HACKING file has all the details for building from a
+CVS checkout.
+
+Imlib will run MARKEDLY better if you get certain libraries. Notably,
+libjpeg, libpng, libtiff and libgif. For more information please go look at:
+
+http://www.labs.redhat.com/imlib/
+
+This will give links to everything you need or may want for Imlib's optimal
+functionality.
diff --git a/src/gdk_imlib/cache.c b/src/gdk_imlib/cache.c
new file mode 100644
index 0000000000..4e750df20c
--- /dev/null
+++ b/src/gdk_imlib/cache.c
@@ -0,0 +1,496 @@
+#define _GNU_SOURCE
+#include "gdk_imlib.h"
+#include "gdk_imlib_private.h"
+
+/* uncomment this to compile imlib's cahce with pixmap accounting output */
+/*#define PIXMAP_ACCOUNTING */
+
+void
+gdirty_pixmaps(GdkImlibImage * im)
+{
+   struct pixmap_cache *ptr;
+
+   ptr = id->cache.pixmap;
+   while (ptr)
+     {
+	if ((ptr->im == im) && ((!ptr->file) || (!strcmp(im->filename, ptr->file))))
+	   ptr->dirty = 1;
+	ptr = ptr->next;
+     }
+}
+
+void
+gdirty_images(GdkImlibImage * im)
+{
+   struct image_cache *ptr;
+
+   ptr = id->cache.image;
+   while (ptr)
+     {
+	if ((!strcmp(im->filename, ptr->file)) && (im == ptr->im))
+	  {
+	     ptr->dirty = 1;
+	     return;
+	  }
+	ptr = ptr->next;
+     }
+}
+
+void
+gfind_pixmap(GdkImlibImage * im, int width, int height, GdkPixmap ** pmap, GdkBitmap ** mask)
+{
+   struct pixmap_cache *ptr;
+
+   ptr = id->cache.pixmap;
+   while (ptr)
+     {
+	if ((ptr->im == im) && (ptr->width == width) && (ptr->height == height) &&
+	    ((!ptr->file) || (!strcmp(im->filename, ptr->file))) &&
+	    (!ptr->dirty))
+	  {
+	     if (ptr->refnum > 0)
+		ptr->refnum++;
+	     else
+	       {
+		  ptr->refnum++;
+		  id->cache.num_pixmap++;
+		  if (ptr->pmap)
+		     id->cache.used_pixmap -= width * height * id->x.depth;
+		  if (ptr->shape_mask)
+		     id->cache.used_pixmap -= width * height;
+		  if (id->cache.used_pixmap < 0)
+		    {
+		       id->cache.used_pixmap = 0;
+		       fprintf(stderr, "IMLIB: uhoh.. caching problems.... meep meep\n");
+		    }
+	       }
+	     if (ptr->prev)
+	       {
+		  ptr->prev->next = ptr->next;
+		  if (ptr->next)
+		     ptr->next->prev = ptr->prev;
+		  ptr->next = id->cache.pixmap;
+		  ptr->next->prev = ptr;
+		  id->cache.pixmap = ptr;
+		  ptr->prev = NULL;
+	       }
+	     *pmap = ptr->pmap;
+	     *mask = ptr->shape_mask;
+	     return;
+	  }
+	ptr = ptr->next;
+     }
+   *pmap = NULL;
+   *mask = NULL;
+}
+
+GdkImlibImage      *
+gfind_image(char *file)
+{
+   struct image_cache *ptr;
+
+   ptr = id->cache.image;
+   while (ptr)
+     {
+	if ((!strcmp(file, ptr->file)) && (!ptr->dirty))
+	  {
+	     if (ptr->refnum)
+		ptr->refnum++;
+	     else
+	       {
+		  ptr->refnum++;
+		  id->cache.num_image++;
+		  id->cache.used_image -= ptr->im->rgb_width * ptr->im->rgb_height * 3;
+		  if (id->cache.used_image < 0)
+		    {
+		       id->cache.used_image = 0;
+		       fprintf(stderr, "IMLIB: uhoh.. caching problems.... meep meep\n");
+		    }
+	       }
+	     if (ptr->prev)
+	       {
+		  ptr->prev->next = ptr->next;
+		  if (ptr->next)
+		     ptr->next->prev = ptr->prev;
+		  ptr->next = id->cache.image;
+		  ptr->next->prev = ptr;
+		  id->cache.image = ptr;
+		  ptr->prev = NULL;
+	       }
+	     return ptr->im;
+	  }
+	ptr = ptr->next;
+     }
+   return NULL;
+}
+
+void
+gfree_pixmappmap(GdkPixmap * pmap)
+{
+   struct pixmap_cache *ptr;
+
+   ptr = id->cache.pixmap;
+   while (ptr)
+     {
+	if ((ptr->pmap == pmap) || (ptr->shape_mask == pmap))
+	  {
+	     if (ptr->shape_mask == pmap)
+		return;
+	     if (ptr->refnum > 0)
+	       {
+		  ptr->refnum--;
+		  if (ptr->refnum == 0)
+		    {
+		       id->cache.num_pixmap--;
+		       if (ptr->pmap)
+			  id->cache.used_pixmap += ptr->width * ptr->height * id->x.depth;
+		       if (ptr->shape_mask)
+			  id->cache.used_pixmap += ptr->width * ptr->height;
+		    }
+	       }
+	     return;
+	  }
+	ptr = ptr->next;
+     }
+   gdk_pixmap_unref(pmap);
+}
+
+void
+gfree_image(GdkImlibImage * im)
+{
+   struct image_cache *ptr;
+
+   ptr = id->cache.image;
+   while (ptr)
+     {
+	if (im == ptr->im)
+	  {
+	     if (ptr->refnum)
+	       {
+		  ptr->refnum--;
+		  if (!ptr->refnum)
+		    {
+		       id->cache.num_image--;
+		       id->cache.used_image += ptr->im->rgb_width * ptr->im->rgb_height * 3;
+		    }
+	       }
+	     return;
+	  }
+	ptr = ptr->next;
+     }
+   gnullify_image(im);
+}
+
+void
+gflush_image(GdkImlibImage * im)
+{
+   if (im)
+      im->cache = 0;
+}
+
+void
+gadd_image(GdkImlibImage * im, char *file)
+{
+   struct image_cache *ptr;
+   struct image_cache *n;
+
+   if ((!im) || (!file))
+      return;
+   ptr = id->cache.image;
+   n = malloc(sizeof(struct image_cache));
+
+   if (!n)
+      return;
+   n->prev = NULL;
+   n->next = ptr;
+   n->file = malloc(strlen(file) + 1);
+   if (!n->file)
+     {
+	free(n);
+	return;
+     }
+   strcpy(n->file, file);
+   n->im = im;
+   n->refnum = 1;
+   n->dirty = 0;
+   if (n->next)
+      n->next->prev = n;
+   id->cache.image = n;
+   id->cache.num_image++;
+}
+
+void
+gadd_pixmap(GdkImlibImage * im, int width, int height, XImage * xim, XImage * sxim)
+{
+   struct pixmap_cache *ptr;
+   struct pixmap_cache *n;
+
+   if (!im)
+      return;
+   ptr = id->cache.pixmap;
+   n = malloc(sizeof(struct pixmap_cache));
+
+   if (!n)
+      return;
+   n->prev = NULL;
+   n->next = ptr;
+   n->im = im;
+   if (im->filename)
+     {
+	n->file = malloc(strlen(im->filename) + 1);
+	if (n->file)
+	   strcpy(n->file, im->filename);
+     }
+   else
+      n->file = NULL;
+   n->refnum = 1;
+   n->dirty = 0;
+   n->width = width;
+   n->height = height;
+   n->pmap = im->pixmap;
+   n->shape_mask = im->shape_mask;
+   n->xim = xim;
+   n->sxim = sxim;
+   if (n->next)
+      n->next->prev = n;
+   id->cache.pixmap = n;
+   id->cache.num_pixmap++;
+}
+
+void
+gclean_caches()
+{
+   {
+      struct image_cache *ptr = NULL;
+      struct image_cache *pptr = NULL;
+      struct image_cache *last = NULL;
+      int                 newlast;
+
+      /* find the back of the list */
+      ptr = id->cache.image;
+      while (ptr)
+	{
+	   last = ptr;
+	   ptr = ptr->next;
+	}
+      newlast = 0;
+      ptr = last;
+      /* remove all images that are tagged non-cachable, and have 0 */
+      /* references , even if the cache has spare room. */
+      while (ptr)
+	{
+	   if (!ptr->refnum)
+	     {
+		if (!ptr->im->cache)
+		  {
+		     if (ptr == last)
+			newlast = 1;
+		     id->cache.used_image -= ptr->im->rgb_width * ptr->im->rgb_height * 3;
+		     gnullify_image(ptr->im);
+		     if (pptr)
+			ptr = pptr->prev;
+		     if (ptr->prev)
+			ptr->prev->next = ptr->next;
+		     else
+			id->cache.image = ptr->next;
+		     if (ptr->next)
+			ptr->next->prev = ptr->prev;
+		     if (ptr->file)
+			free(ptr->file);
+		     free(ptr);
+		     ptr = NULL;
+		  }
+	     }
+	   if (ptr)
+	      ptr = ptr->prev;
+	   if (newlast)
+	     {
+		last = NULL;
+		ptr = id->cache.image;
+		while (ptr)
+		  {
+		     last = ptr;
+		     ptr = ptr->next;
+		  }
+		newlast = 0;
+		ptr = last;
+	     }
+	}
+      /* find the back of the list */
+      ptr = id->cache.image;
+      last = NULL;
+      while (ptr)
+	{
+	   last = ptr;
+	   ptr = ptr->next;
+	}
+      newlast = 0;
+      ptr = last;
+      /* while the amount of data in the cache is greater than the set */
+      /* amount, delete the last entry (last used) from the unreferenced */
+      /* cached 24-bit images */
+      while (id->cache.used_image > id->cache.size_image)
+	{
+	   while (ptr)
+	     {
+		if (ptr->refnum < 1)
+		  {
+		     if (ptr == last)
+			newlast = 1;
+		     id->cache.used_image -= ptr->im->rgb_width * ptr->im->rgb_height * 3;
+		     gnullify_image(ptr->im);
+		     if (ptr->prev)
+			ptr->prev->next = ptr->next;
+		     else
+			id->cache.image = ptr->next;
+		     if (ptr->next)
+			ptr->next->prev = ptr->prev;
+		     if (ptr->file)
+			free(ptr->file);
+		     free(ptr);
+		     ptr = NULL;
+		     break;
+		  }
+		if (ptr)
+		   ptr = ptr->prev;
+	     }
+	   if (newlast)
+	     {
+		last = NULL;
+		ptr = id->cache.image;
+		while (ptr)
+		  {
+		     last = ptr;
+		     ptr = ptr->next;
+		  }
+		newlast = 0;
+		ptr = last;
+	     }
+	   if (!ptr)
+	      break;
+	}
+   }
+   {
+      struct pixmap_cache *ptr;
+      struct pixmap_cache *last;
+      int                 newlast;
+
+#ifdef PIXMAP_ACCOUNTING
+      int                 total, total2, num, num2;
+
+      printf("--------- Pixmap cashe zise %i / %i with %i pixmaps referenced\n",
+	     id->cache.used_pixmap, id->cache.size_pixmap,
+	     id->cache.num_pixmap);
+      ptr = id->cache.pixmap;
+      total = 0;
+      total2 = 0;
+      num = 0;
+      num2 = 0;
+      while (ptr)
+	{
+	   printf("Pmap for file %s REFNUM %3i SIZE %4ix%4i PMAP %8x MASK %8x\n",
+		  ptr->file, ptr->refnum, ptr->width, ptr->height, ptr->pmap,
+		  ptr->shape_mask);
+	   if (ptr->refnum > 0)
+	     {
+		total += (ptr->width * ptr->height * id->x.depth);
+		if (ptr->shape_mask)
+		   total += (ptr->width * ptr->height);
+		num++;
+	     }
+	   else
+	     {
+		total2 += (ptr->width * ptr->height * id->x.depth);
+		if (ptr->shape_mask)
+		   total2 += (ptr->width * ptr->height);
+		num2++;
+	     }
+	   ptr = ptr->next;
+	}
+      printf("Accounting Data:\n");
+      printf("*** total pixmap's in cache %i with %i pixmaps\n",
+	     total, num);
+      printf("*** total unreffed pixmap's in cache %i with %i pixmaps\n\n",
+	     total2, num2);
+#endif
+      /* find the back of the list */
+      ptr = id->cache.pixmap;
+      last = NULL;
+      while (ptr)
+	{
+	   last = ptr;
+	   ptr = ptr->next;
+	}
+      newlast = 0;
+      ptr = last;
+      /* while the amount of data in the cache is greater than the set */
+      /* amount, delete the last entry (last used) from the unreferenced */
+      /* cached pixmaps */
+      while (id->cache.used_pixmap > id->cache.size_pixmap)
+	{
+	   while (ptr)
+	     {
+		if (ptr->refnum < 1)
+		  {
+		     if (ptr == last)
+			newlast = 1;
+		     if (ptr->pmap)
+			id->cache.used_pixmap -= ptr->width * ptr->height * id->x.depth;
+		     if (ptr->shape_mask)
+			id->cache.used_pixmap -= ptr->width * ptr->height;
+		     if (ptr->pmap)
+			gdk_pixmap_unref(ptr->pmap);
+		     if (ptr->shape_mask)
+			gdk_pixmap_unref(ptr->shape_mask);
+		     if (ptr->xim)
+			XDestroyImage(ptr->xim);
+		     if (ptr->sxim)
+			XDestroyImage(ptr->sxim);
+		     if (ptr->prev)
+			ptr->prev->next = ptr->next;
+		     else
+			id->cache.pixmap = ptr->next;
+		     if (ptr->next)
+			ptr->next->prev = ptr->prev;
+		     if (ptr->file)
+			free(ptr->file);
+		     free(ptr);
+		     ptr = NULL;
+		     break;
+		  }
+		if (ptr)
+		   ptr = ptr->prev;
+	     }
+	   if (newlast)
+	     {
+		last = NULL;
+		ptr = id->cache.pixmap;
+		while (ptr)
+		  {
+		     last = ptr;
+		     ptr = ptr->next;
+		  }
+		newlast = 0;
+		ptr = last;
+	     }
+	   if (!ptr)
+	      break;
+	}
+   }
+}
+
+void
+gnullify_image(GdkImlibImage * im)
+{
+   if (!im)
+      return;
+   if (im->rgb_data)
+      free(im->rgb_data);
+   if (im->alpha_data)
+      free(im->alpha_data);
+   if (im->pixmap)
+      gfree_pixmappmap(im->pixmap);
+   if (im->filename)
+      free(im->filename);
+   free(im);
+}
diff --git a/src/gdk_imlib/colors.c b/src/gdk_imlib/colors.c
new file mode 100644
index 0000000000..b27207c600
--- /dev/null
+++ b/src/gdk_imlib/colors.c
@@ -0,0 +1,113 @@
+#define _GNU_SOURCE
+#include "gdk_imlib.h"
+#include "gdk_imlib_private.h"
+
+void
+g_PaletteAlloc(int num, int *cols)
+{
+   XColor              xcl;
+   int                 i;
+   int                 r, g, b;
+
+   if (id->palette)
+      free(id->palette);
+   id->palette = malloc(sizeof(GdkImlibColor) * num);
+   if (id->palette_orig)
+      free(id->palette_orig);
+   id->palette_orig = malloc(sizeof(GdkImlibColor) * num);
+   for (i = 0; i < num; i++)
+     {
+	r = cols[(i * 3) + 0];
+	g = cols[(i * 3) + 1];
+	b = cols[(i * 3) + 2];
+	xcl.red = (unsigned short)((r << 8) | (r));
+	xcl.green = (unsigned short)((g << 8) | (g));
+	xcl.blue = (unsigned short)((b << 8) | (b));
+	xcl.flags = DoRed | DoGreen | DoBlue;
+	XAllocColor(id->x.disp, id->x.root_cmap, &xcl);
+	id->palette[i].r = xcl.red >> 8;
+	id->palette[i].g = xcl.green >> 8;
+	id->palette[i].b = xcl.blue >> 8;
+	id->palette[i].pixel = xcl.pixel;
+	id->palette_orig[i].r = r;
+	id->palette_orig[i].g = g;
+	id->palette_orig[i].b = b;
+	id->palette_orig[i].pixel = xcl.pixel;
+     }
+   id->num_colors = num;
+}
+
+gint
+gdk_imlib_load_colors(char *file)
+{
+   FILE               *f;
+   char                s[256];
+   int                 i;
+   int                 pal[768];
+   int                 r, g, b;
+   int                 rr, gg, bb;
+
+   f = fopen(file, "r");
+   if (!f)
+     {
+	fprintf(stderr, "GImLib ERROR: Cannot find palette file %s\n", file);
+	return 0;
+     }
+   i = 0;
+   while (fgets(s, 256, f))
+     {
+	if (s[0] == '0')
+	  {
+	     sscanf(s, "%x %x %x", &r, &g, &b);
+	     if (r < 0)
+		r = 0;
+	     if (r > 255)
+		r = 255;
+	     if (g < 0)
+		g = 0;
+	     if (g > 255)
+		g = 255;
+	     if (b < 0)
+		b = 0;
+	     if (b > 255)
+		b = 255;
+	     pal[i++] = r;
+	     pal[i++] = g;
+	     pal[i++] = b;
+	  }
+	if (i >= 768)
+	   break;
+     }
+   fclose(f);
+   g_PaletteAlloc((i / 3), pal);
+   if (id->fast_rgb)
+      free(id->fast_rgb);
+   id->fast_rgb = malloc(sizeof(int) * 32 * 32 * 32);
+
+   for (r = 0; r < 32; r++)
+     {
+	for (g = 0; g < 32; g++)
+	  {
+	     for (b = 0; b < 32; b++)
+	       {
+		  rr = (r << 3) | (r >> 2);
+		  gg = (g << 3) | (g >> 2);
+		  bb = (b << 3) | (b >> 2);
+		  INDEX_RGB(r, g, b) = gindex_best_color_match(&rr, &gg, &bb);
+	       }
+	  }
+     }
+   return 1;
+}
+
+void
+gdk_imlib_free_colors()
+{
+   int                 i;
+   unsigned long       pixels[256];
+
+   for (i = 0; i < id->num_colors; i++)
+      pixels[i] = id->palette[i].pixel;
+   XFreeColors(id->x.disp, id->x.root_cmap, pixels, id->num_colors, 0);
+   id->num_colors = 0;
+}
diff --git a/src/gdk_imlib/config.h b/src/gdk_imlib/config.h
new file mode 100644
index 0000000000..225d595547
--- /dev/null
+++ b/src/gdk_imlib/config.h
@@ -0,0 +1,2 @@
+#undef PACKAGE
+#undef VERSION
diff --git a/src/gdk_imlib/gdk_imlib.h b/src/gdk_imlib/gdk_imlib.h
new file mode 100644
index 0000000000..5af1cd580e
--- /dev/null
+++ b/src/gdk_imlib/gdk_imlib.h
@@ -0,0 +1,76 @@
+
+#ifndef __GDK_IMLIB_H__
+#define __GDK_IMLIB_H__
+
+#include <gdk_imlib_types.h>
+
+#ifdef __cplusplus
+extern              "C"
+{
+#endif				/* __cplusplus */
+
+   void                gdk_imlib_init(void);
+   void                gdk_imlib_init_params(GdkImlibInitParams * p);
+   gint                gdk_imlib_get_render_type(void);
+   void                gdk_imlib_set_render_type(gint rend_type);
+   gint                gdk_imlib_load_colors(char *file);
+   GdkImlibImage      *gdk_imlib_load_image(char *file);
+   gint                gdk_imlib_best_color_match(gint * r, gint * g, gint * b);
+   gint                gdk_imlib_render(GdkImlibImage * image, gint width, gint height);
+   GdkPixmap          *gdk_imlib_copy_image(GdkImlibImage * image);
+   GdkBitmap          *gdk_imlib_copy_mask(GdkImlibImage * image);
+   GdkPixmap          *gdk_imlib_move_image(GdkImlibImage * image);
+   GdkBitmap          *gdk_imlib_move_mask(GdkImlibImage * image);
+   void                gdk_imlib_destroy_image(GdkImlibImage * image);
+   void                gdk_imlib_kill_image(GdkImlibImage * image);
+   void                gdk_imlib_free_colors(void);
+   void                gdk_imlib_free_pixmap(GdkPixmap * pixmap);
+   void                gdk_imlib_free_bitmap(GdkBitmap * bitmap);
+   void                gdk_imlib_get_image_border(GdkImlibImage * image, GdkImlibBorder * border);
+   void                gdk_imlib_set_image_border(GdkImlibImage * image, GdkImlibBorder * border);
+   void                gdk_imlib_get_image_shape(GdkImlibImage * image, GdkImlibColor * color);
+   void                gdk_imlib_set_image_shape(GdkImlibImage * image, GdkImlibColor * color);
+   gint                gdk_imlib_save_image_to_eim(GdkImlibImage * image, char *file);
+   gint                gdk_imlib_add_image_to_eim(GdkImlibImage * image, char *file);
+   gint                gdk_imlib_save_image_to_ppm(GdkImlibImage * image, char *file);
+   gint                gdk_imlib_load_file_to_pixmap(char *filename, GdkPixmap ** pmap, GdkBitmap ** mask);
+   void                gdk_imlib_set_image_modifier(GdkImlibImage * im, GdkImlibColorModifier * mod);
+   void                gdk_imlib_set_image_red_modifier(GdkImlibImage * im, GdkImlibColorModifier * mod);
+   void                gdk_imlib_set_image_green_modifier(GdkImlibImage * im, GdkImlibColorModifier * mod);
+   void                gdk_imlib_set_image_blue_modifier(GdkImlibImage * im, GdkImlibColorModifier * mod);
+   void                gdk_imlib_get_image_modifier(GdkImlibImage * im, GdkImlibColorModifier * mod);
+   void                gdk_imlib_get_image_red_modifier(GdkImlibImage * im, GdkImlibColorModifier * mod);
+   void                gdk_imlib_get_image_green_modifier(GdkImlibImage * im, GdkImlibColorModifier * mod);
+   void                gdk_imlib_get_image_blue_modifier(GdkImlibImage * im, GdkImlibColorModifier * mod);
+   void                gdk_imlib_set_image_red_curve(GdkImlibImage * im, unsigned char *mod);
+   void                gdk_imlib_set_image_green_curve(GdkImlibImage * im, unsigned char *mod);
+   void                gdk_imlib_set_image_blue_curve(GdkImlibImage * im, unsigned char *mod);
+   void                gdk_imlib_get_image_red_curve(GdkImlibImage * im, unsigned char *mod);
+   void                gdk_imlib_get_image_green_curve(GdkImlibImage * im, unsigned char *mod);
+   void                gdk_imlib_get_image_blue_curve(GdkImlibImage * im, unsigned char *mod);
+   void                gdk_imlib_apply_modifiers_to_rgb(GdkImlibImage * im);
+   void                gdk_imlib_changed_image(GdkImlibImage * im);
+   void                gdk_imlib_apply_image(GdkImlibImage * im, GdkWindow * p);
+   void                gdk_imlib_paste_image(GdkImlibImage * im, GdkWindow * p, gint x, gint y, gint w, gint h);
+   void                gdk_imlib_paste_image_border(GdkImlibImage * im, GdkWindow * p, gint x, gint y, gint w, gint h);
+   void                gdk_imlib_flip_image_horizontal(GdkImlibImage * im);
+   void                gdk_imlib_flip_image_vertical(GdkImlibImage * im);
+   void                gdk_imlib_rotate_image(GdkImlibImage * im, gint d);
+   GdkImlibImage      *gdk_imlib_create_image_from_data(unsigned char *data, unsigned char *alpha, gint w, gint h);
+   GdkImlibImage      *gdk_imlib_clone_image(GdkImlibImage * im);
+   GdkImlibImage      *gdk_imlib_clone_scaled_image(GdkImlibImage * im, int w, int h);
+   gint                gdk_imlib_get_fallback(void);
+   void                gdk_imlib_set_fallback(gint fallback);
+   GdkVisual          *gdk_imlib_get_visual(void);
+   GdkColormap        *gdk_imlib_get_colormap(void);
+   gchar              *gdk_imlib_get_sysconfig(void);
+   GdkImlibImage      *gdk_imlib_create_image_from_xpm_data(char **data);
+   gint                gdk_imlib_data_to_pixmap(char **data, GdkPixmap ** pmap, GdkBitmap ** mask);
+   void                gdk_imlib_crop_image(GdkImlibImage * im, gint x, gint y, gint w, gint h);
+   gint                gdk_imlib_save_image(GdkImlibImage * im, char *file, GdkImlibSaveInfo * info);
+
+#ifdef __cplusplus
+}
+#endif				/* __cplusplus */
+
+#endif
diff --git a/src/gdk_imlib/gdk_imlib_private.h b/src/gdk_imlib/gdk_imlib_private.h
new file mode 100644
index 0000000000..3da5c6d9bb
--- /dev/null
+++ b/src/gdk_imlib/gdk_imlib_private.h
@@ -0,0 +1,226 @@
+#ifdef _HAVE_STRING_H
+#include <string.h>
+#elif _HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#ifndef CONVERT_PATH
+#define CONVERT_PATH "/usr/local/bin"
+#endif
+
+#ifndef NETPBM_PATH
+#define NETPBM_PATH  "/usr/local/bin"
+#endif
+
+#ifndef CJPEG_PROG
+#define CJPEG_PROG "/usr/bin/cjpeg"
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <math.h>
+#include <ctype.h>
+#include <time.h>
+#include <netinet/in.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/time.h>
+#include <sys/types.h>
+
+#ifdef _HAVE_STRING_H
+#include <string.h>
+#elif _HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/Xos.h>
+#include <X11/extensions/XShm.h>
+#include <X11/extensions/shape.h>
+#include <X11/cursorfont.h>
+#include <gdk/gdkprivate.h>
+
+#ifdef HAVE_LIBJPEG
+#include <jpeglib.h>
+#endif
+#ifdef HAVE_LIBPNG
+#include <png.h>
+#endif
+#ifdef HAVE_LIBTIFF
+#include <tiffio.h>
+#endif
+#ifdef HAVE_LIBGIF
+#include <gif_lib.h>
+#endif
+
+#define BYTE_ORD_24_RGB 0
+#define BYTE_ORD_24_RBG 1
+#define BYTE_ORD_24_BRG 2
+#define BYTE_ORD_24_BGR 3
+#define BYTE_ORD_24_GRB 4
+#define BYTE_ORD_24_GBR 5
+
+struct image_cache
+  {
+     gchar              *file;
+     GdkImlibImage      *im;
+     gint                refnum;
+     gchar               dirty;
+     struct image_cache *prev;
+     struct image_cache *next;
+  };
+
+struct pixmap_cache
+  {
+     GdkImlibImage      *im;
+     gchar              *file;
+     gchar               dirty;
+     gint                width, height;
+     GdkPixmap          *pmap;
+     GdkBitmap          *shape_mask;
+     XImage             *xim, *sxim;
+     gint                refnum;
+     struct pixmap_cache *prev;
+     struct pixmap_cache *next;
+  };
+
+typedef struct _xdata
+  {
+     Display            *disp;
+     gint                screen;
+     Window              root;
+     Visual             *visual;
+     gint                depth;
+     gint                render_depth;
+     Colormap            root_cmap;
+     gchar               shm;
+     gchar               shmp;
+     gint                shm_event;
+     XImage             *last_xim;
+     XImage             *last_sxim;
+     XShmSegmentInfo     last_shminfo;
+     XShmSegmentInfo     last_sshminfo;
+     Window              base_window;
+     GdkWindow          *gdk_win;
+     GdkColormap        *gdk_cmap;
+  }
+Xdata;
+
+typedef struct _imlibdata
+  {
+     gint                num_colors;
+     GdkImlibColor      *palette;
+     GdkImlibColor      *palette_orig;
+     unsigned char      *fast_rgb;
+     gint               *fast_err;
+     gint               *fast_erg;
+     gint               *fast_erb;
+     gint                render_type;
+     gint                max_shm;
+     Xdata               x;
+     gint                byte_order;
+     struct _cache
+       {
+	  gchar               on_image;
+	  gint                size_image;
+	  gint                num_image;
+	  gint                used_image;
+	  struct image_cache *image;
+	  gchar               on_pixmap;
+	  gint                size_pixmap;
+	  gint                num_pixmap;
+	  gint                used_pixmap;
+	  struct pixmap_cache *pixmap;
+       }
+     cache;
+     gchar               fastrend;
+     gchar               hiq;
+     GdkImlibColorModifier mod, rmod, gmod, bmod;
+     unsigned char       rmap[256], gmap[256], bmap[256];
+     gchar               fallback;
+     gchar               ordered_dither;
+  }
+ImlibData;
+
+extern ImlibData   *id;
+
+gint                gindex_best_color_match(gint * r, gint * g, gint * b);
+
+void                gdirty_pixmaps(GdkImlibImage * im);
+void                gdirty_images(GdkImlibImage * im);
+void                gfind_pixmap(GdkImlibImage * im, int width, int height, GdkPixmap ** pmap, GdkBitmap ** mask);
+GdkImlibImage      *gfind_image(char *file);
+void                gfree_pixmappmap(GdkPixmap * pmap);
+void                gfree_image(GdkImlibImage * im);
+void                gflush_image(GdkImlibImage * im);
+void                gadd_image(GdkImlibImage * im, char *file);
+void                gadd_pixmap(GdkImlibImage * im, int width, int height, XImage * xim, XImage * sxim);
+void                gclean_caches();
+void                gnullify_image(GdkImlibImage * im);
+
+/* char *g_SplitID(char *file); */
+char               *g_GetExtension(char *file);
+
+#ifdef HAVE_LIBJPEG
+unsigned char      *g_LoadJPEG(FILE * f, int *w, int *h);
+
+#endif /* HAVE_LIBJPEG */
+#ifdef HAVE_LIBPNG
+unsigned char      *g_LoadPNG(FILE * f, int *w, int *h, int *t);
+
+#endif /* HAVE_LIBPNG */
+#ifdef HAVE_LIBTIFF
+unsigned char      *g_LoadTIFF(char *f, int *w, int *h, int *t);
+
+#endif /* HAVE_LIBTIFF */
+#ifdef HAVE_LIBGIF
+unsigned char      *g_LoadGIF(char *f, int *w, int *h, int *t);
+
+#endif /* HAVE_LIBGIF */
+unsigned char      *g_LoadXPM(char *f, int *w, int *h, int *t);
+unsigned char      *g_LoadPPM(FILE * f, int *w, int *h);
+
+/*
+static int          gispnm(char *file);
+static int          gisjpeg(char *file);
+static int          gispng(char *file);
+static int          gistiff(char *file);
+static int          giseim(char *file);
+static int          gisgif(char *file);
+static int          gisxpm(char *file);
+*/
+
+GdkPixmap          *gdk_imlib_pixmap_foreign_new(gint width, gint height, gint depth, Pixmap pmap);
+
+void                gcalc_map_tables(GdkImlibImage * im);
+
+void                g_PaletteAlloc(int num, int *cols);
+
+FILE               *open_helper(const char *, const char *, const char *);
+int                 close_helper(FILE *);
+
+#define INDEX_RGB(r,g,b)  id->fast_rgb[(r<<10)|(g<<5)|(b)]
+#define COLOR_INDEX(i)    id->palette[i].pixel
+#define COLOR_RGB(r,g,b)  id->palette[INDEX_RGB(r,g,b)].pixel
+#define ERROR_RED(rr,i)   rr-id->palette[i].r;
+#define ERROR_GRN(gg,i)   gg-id->palette[i].g;
+#define ERROR_BLU(bb,i)   bb-id->palette[i].b;
+
+#define DITHER_ERROR(Der1,Der2,Dex,Der,Deg,Deb) \
+ter=&(Der1[Dex]);\
+(*ter)+=(Der*7)>>4;ter++;\
+(*ter)+=(Deg*7)>>4;ter++;\
+(*ter)+=(Deb*7)>>4;\
+ter=&(Der2[Dex-6]);\
+(*ter)+=(Der*3)>>4;ter++;\
+(*ter)+=(Deg*3)>>4;ter++;\
+(*ter)+=(Deb*3)>>4;ter++;\
+(*ter)+=(Der*5)>>4;ter++;\
+(*ter)+=(Deg*5)>>4;ter++;\
+(*ter)+=(Deb*5)>>4;ter++;\
+(*ter)+=Der>>4;ter++;\
+(*ter)+=Deg>>4;ter++;\
+(*ter)+=Deb>>4;
diff --git a/src/gdk_imlib/gdk_imlib_types.h b/src/gdk_imlib/gdk_imlib_types.h
new file mode 100644
index 0000000000..fa3d894080
--- /dev/null
+++ b/src/gdk_imlib/gdk_imlib_types.h
@@ -0,0 +1,101 @@
+#include <gdk/gdk.h>
+
+#ifndef SYSTEM_IMRC
+#define SYSTEM_IMRC "/etc/imrc"
+#endif /* endef SYSTEM_IMRC */
+
+typedef struct _GdkImlibBorder
+  {
+     gint                left, right;
+     gint                top, bottom;
+  }
+GdkImlibBorder;
+
+typedef struct _GdkImlibColor
+  {
+     gint                r, g, b;
+     gint                pixel;
+  }
+GdkImlibColor;
+
+typedef struct _GdkImlibColorModifier
+  {
+     gint                gamma;
+     gint                brightness;
+     gint                contrast;
+  }
+GdkImlibColorModifier;
+
+typedef struct _GdkImlibImage
+  {
+     gint                rgb_width, rgb_height;
+     unsigned char      *rgb_data;
+     unsigned char      *alpha_data;
+     gchar              *filename;
+/* the below information is private */
+     gint                width, height;
+     GdkImlibColor       shape_color;
+     GdkImlibBorder      border;
+     GdkPixmap          *pixmap;
+     GdkBitmap          *shape_mask;
+     gchar               cache;
+     GdkImlibColorModifier mod, rmod, gmod, bmod;
+     unsigned char       rmap[256], gmap[256], bmap[256];
+  }
+GdkImlibImage;
+
+typedef struct _GdkImlibSaveInfo
+  {
+     int                 quality;
+     int                 scaling;
+     int                 xjustification;
+     int                 yjustification;
+     int                 page_size;
+     char                color;
+  }
+GdkImlibSaveInfo;
+
+typedef struct _GdkImlibInitParams
+  {
+     int                 flags;
+     int                 visualid;
+     char               *palettefile;
+     char                sharedmem;
+     char                sharedpixmaps;
+     char                paletteoverride;
+     char                remap;
+     char                fastrender;
+     char                hiquality;
+     char                dither;
+     int                 imagecachesize;
+     int                 pixmapcachesize;
+  }
+GdkImlibInitParams;
+
+#define PARAMS_VISUALID        1<<0
+#define PARAMS_PALETTEFILE     1<<1
+#define PARAMS_SHAREDMEM       1<<2
+#define PARAMS_SHAREDPIXMAPS   1<<3
+#define PARAMS_PALETTEOVERRIDE 1<<4
+#define PARAMS_REMAP           1<<5
+#define PARAMS_FASTRENDER      1<<6
+#define PARAMS_HIQUALITY       1<<7
+#define PARAMS_DITHER          1<<8
+#define PARAMS_IMAGECACHESIZE  1<<9
+#define PARAMS_PIXMAPCACHESIZE 1<<10
+
+#define PAGE_SIZE_EXECUTIVE    0
+#define PAGE_SIZE_LETTER       1
+#define PAGE_SIZE_LEGAL        2
+#define PAGE_SIZE_A4           3
+#define PAGE_SIZE_A3           4
+#define PAGE_SIZE_A5           5
+#define PAGE_SIZE_FOLIO        6
+
+#define RT_PLAIN_PALETTE       0
+#define RT_PLAIN_PALETTE_FAST  1
+#define RT_DITHER_PALETTE      2
+#define RT_DITHER_PALETTE_FAST 3
+#define RT_PLAIN_TRUECOL       4
+/* a special high-quality renderer for people with 15 and 16bpp that dithers */
+#define RT_DITHER_TRUECOL      5
diff --git a/src/gdk_imlib/globals.c b/src/gdk_imlib/globals.c
new file mode 100644
index 0000000000..d92b993247
--- /dev/null
+++ b/src/gdk_imlib/globals.c
@@ -0,0 +1,6 @@
+
+#define _GNU_SOURCE
+#include "gdk_imlib.h"
+#include "gdk_imlib_private.h"
+
+ImlibData          *id;
diff --git a/src/gdk_imlib/load.c b/src/gdk_imlib/load.c
new file mode 100644
index 0000000000..e37495f743
--- /dev/null
+++ b/src/gdk_imlib/load.c
@@ -0,0 +1,1494 @@
+
+#define _GNU_SOURCE
+#include <config.h>
+
+#include "gdk_imlib.h"
+#include "gdk_imlib_private.h"
+
+/*      Split the ID - damages input    */
+
+static char        *
+g_SplitID(char *file)
+{
+   char               *p = strrchr(file, ':');
+
+   if (p == NULL)
+      return "";
+   else
+     {
+	*p++ = 0;
+	return p;
+     }
+}
+
+/*
+ *     Doesn't damage the input
+ */
+
+char               *
+g_GetExtension(char *file)
+{
+   char               *p = strrchr(file, '.');
+
+   if (p == NULL)
+      return "";
+   else
+      return p + 1;
+}
+
+#ifdef HAVE_LIBJPEG
+unsigned char      *
+g_LoadJPEG(FILE * f, int *w, int *h)
+{
+   struct jpeg_decompress_struct cinfo;
+   struct jpeg_error_mgr jerr;
+   unsigned char      *data, *line[16], *ptr;
+   int                 x, y, i;
+
+   cinfo.err = jpeg_std_error(&jerr);
+   jpeg_create_decompress(&cinfo);
+   jpeg_stdio_src(&cinfo, f);
+   jpeg_read_header(&cinfo, TRUE);
+   cinfo.do_fancy_upsampling = FALSE;
+   cinfo.do_block_smoothing = FALSE;
+   jpeg_start_decompress(&cinfo);
+   *w = cinfo.output_width;
+   *h = cinfo.output_height;
+   data = malloc(*w ** h * 3);
+   if (!data)
+     {
+	jpeg_destroy_decompress(&cinfo);
+	return NULL;
+     }
+   ptr = data;
+
+   if (cinfo.rec_outbuf_height > 16)
+     {
+	fprintf(stderr, "gdk_imlib ERROR: JPEG uses line buffers > 16. Cannot load.\n");
+	return NULL;
+     }
+   if (cinfo.output_components == 3)
+     {
+	for (y = 0; y < *h; y += cinfo.rec_outbuf_height)
+	  {
+	     for (i = 0; i < cinfo.rec_outbuf_height; i++)
+	       {
+		  line[i] = ptr;
+		  ptr += *w * 3;
+	       }
+	     jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
+	  }
+     }
+   else if (cinfo.output_components == 1)
+     {
+	for (i = 0; i < cinfo.rec_outbuf_height; i++)
+	  {
+	     if ((line[i] = malloc(*w)) == NULL)
+	       {
+		  int                 t = 0;
+
+		  for (t = 0; t < i; t++)
+		     free(line[t]);
+		  jpeg_destroy_decompress(&cinfo);
+		  return NULL;
+	       }
+	  }
+	for (y = 0; y < *h; y += cinfo.rec_outbuf_height)
+	  {
+	     jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
+	     for (i = 0; i < cinfo.rec_outbuf_height; i++)
+	       {
+		  for (x = 0; x < *w; x++)
+		    {
+		       *ptr++ = line[i][x];
+		       *ptr++ = line[i][x];
+		       *ptr++ = line[i][x];
+		    }
+	       }
+	  }
+	for (i = 0; i < cinfo.rec_outbuf_height; i++)
+	   free(line[i]);
+     }
+   jpeg_finish_decompress(&cinfo);
+   jpeg_destroy_decompress(&cinfo);
+   return data;
+}
+#endif /* HAVE_LIBJPEG */
+
+#ifdef HAVE_LIBPNG
+unsigned char      *
+g_LoadPNG(FILE * f, int *w, int *h, int *t)
+{
+   png_structp         png_ptr;
+   png_infop           info_ptr;
+   unsigned char      *data, *ptr, **lines, *ptr2, r, g, b, a;
+   int                 i, x, y, transp, bit_depth, color_type, interlace_type;
+   png_uint_32        *ww, *hh;
+
+   /* Init PNG Reader */
+   transp = 0;
+   png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+   if (!png_ptr)
+      return NULL;
+
+   info_ptr = png_create_info_struct(png_ptr);
+   if (!info_ptr)
+     {
+	png_destroy_read_struct(&png_ptr, NULL, NULL);
+	return NULL;
+     }
+
+   if (setjmp(png_ptr->jmpbuf))
+     {
+	png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+	return NULL;
+     }
+
+   if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+     {
+	png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+	return NULL;
+     }
+   png_init_io(png_ptr, f);
+   /* Read Header */
+   png_read_info(png_ptr, info_ptr);
+   ww = (png_uint_32 *) w;
+   hh = (png_uint_32 *) h;
+   png_get_IHDR(png_ptr, info_ptr, ww, hh, &bit_depth, &color_type, &interlace_type,
+		NULL, NULL);
+   /* Setup Translators */
+   if (color_type == PNG_COLOR_TYPE_PALETTE)
+      png_set_expand(png_ptr);
+   png_set_strip_16(png_ptr);
+   png_set_packing(png_ptr);
+   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
+      png_set_expand(png_ptr);
+   png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
+   *w = info_ptr->width;
+   *h = info_ptr->height;
+   data = malloc(*w ** h * 3);
+   if (!data)
+     {
+	png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+	return NULL;
+     }
+   lines = (unsigned char **)malloc(*h * sizeof(unsigned char *));
+
+   if (lines == NULL)
+     {
+	free(data);
+	png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+	return NULL;
+     }
+   for (i = 0; i < *h; i++)
+     {
+	if ((lines[i] = malloc(*w * (sizeof(unsigned char) * 4))) == NULL)
+	  {
+	     int                 n;
+
+	     free(data);
+	     for (n = 0; n < i; n++)
+		free(lines[n]);
+	     free(lines);
+	     png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+	     return NULL;
+	  }
+     }
+   png_read_image(png_ptr, lines);
+   png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+   ptr = data;
+   if (color_type == PNG_COLOR_TYPE_GRAY)
+     {
+	for (y = 0; y < *h; y++)
+	  {
+	     ptr2 = lines[y];
+	     for (x = 0; x < *w; x++)
+	       {
+		  r = *ptr2++;
+		  *ptr++ = r;
+		  *ptr++ = r;
+		  *ptr++ = r;
+	       }
+	  }
+     }
+   else
+     {
+	for (y = 0; y < *h; y++)
+	  {
+	     ptr2 = lines[y];
+	     for (x = 0; x < *w; x++)
+	       {
+		  r = *ptr2++;
+		  g = *ptr2++;
+		  b = *ptr2++;
+		  a = *ptr2++;
+		  if (a < 128)
+		    {
+		       *ptr++ = 255;
+		       *ptr++ = 0;
+		       *ptr++ = 255;
+		       transp = 1;
+		    }
+		  else
+		    {
+		       if ((r == 255) && (g == 0) && (b == 255))
+			  r = 254;
+		       *ptr++ = r;
+		       *ptr++ = g;
+		       *ptr++ = b;
+		    }
+	       }
+	  }
+     }
+   for (i = 0; i < *h; i++)
+      free(lines[i]);
+   free(lines);
+   *t = transp;
+   return data;
+}
+#endif /* HAVE_LIBPNG */
+
+#ifdef HAVE_LIBTIFF
+unsigned char      *
+g_LoadTIFF(char *f, int *w, int *h, int *t)
+{
+   TIFF               *tif;
+   unsigned char      *data, *ptr, r, g, b, a;
+   int                 x, y;
+   uint32              ww, hh, *rast, *tptr;
+   size_t              npix;
+   int                 istransp;
+
+   istransp = 0;
+   if (!f)
+      return NULL;
+
+   tif = TIFFOpen(f, "r");
+   if (!tif)
+      return NULL;
+
+   TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &ww);
+   TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &hh);
+   npix = ww * hh;
+   *w = (int)ww;
+   *h = (int)hh;
+   rast = (uint32 *) _TIFFmalloc(npix * sizeof(uint32));
+   if (!rast)
+     {
+	TIFFClose(tif);
+	return NULL;
+     }
+   data = NULL;
+   if (TIFFReadRGBAImage(tif, ww, hh, rast, 0))
+     {
+	data = (unsigned char *)malloc(*w ** h * 3);
+	if (!data)
+	  {
+	     _TIFFfree(rast);
+	     TIFFClose(tif);
+	     return NULL;
+	  }
+	ptr = data;
+	for (y = 0; y < *h; y++)
+	  {
+	     tptr = rast;
+	     tptr += ((*h - y - 1) ** w);
+	     for (x = 0; x < *w; x++)
+	       {
+		  a = TIFFGetA(*tptr);
+		  b = TIFFGetB(*tptr);
+		  g = TIFFGetG(*tptr);
+		  r = TIFFGetR(*tptr);
+		  tptr++;
+		  if (a < 128)
+		    {
+		       *ptr++ = 255;
+		       *ptr++ = 0;
+		       *ptr++ = 255;
+		       istransp = 1;
+		    }
+		  else
+		    {
+		       if ((r == 255) && (g == 0) && (b == 255))
+			  r = 254;
+		       *ptr++ = r;
+		       *ptr++ = g;
+		       *ptr++ = b;
+		    }
+	       }
+	  }
+     }
+   _TIFFfree(rast);
+   TIFFClose(tif);
+   *t = istransp;
+   return data;
+}
+
+#endif /* HAVE_LIBTIFF */
+
+#ifdef HAVE_LIBGIF
+unsigned char      *
+g_LoadGIF(char *f, int *w, int *h, int *t)
+{
+   unsigned char      *data, *ptr;
+   GifFileType        *gif;
+   GifRowType         *rows;
+   GifRecordType       rec;
+   ColorMapObject     *cmap;
+   int                 i, j, done, bg, csize, r, g, b;
+   int                 intoffset[] =
+   {0, 4, 2, 1};
+   int                 intjump[] =
+   {8, 8, 4, 2};
+   int                 istransp, transp;
+
+   done = 0;
+   istransp = 0;
+   gif = DGifOpenFileName(f);
+   if (!gif)
+      return NULL;
+
+   do
+     {
+	DGifGetRecordType(gif, &rec);
+	if ((rec == IMAGE_DESC_RECORD_TYPE) && (!done))
+	  {
+	     DGifGetImageDesc(gif);
+	     *w = gif->Image.Width;
+	     *h = gif->Image.Height;
+	     rows = malloc(*h * sizeof(GifRowType *));
+	     if (!rows)
+	       {
+		  DGifCloseFile(gif);
+		  return NULL;
+	       }
+	     data = malloc(*w ** h * 3);
+	     if (!data)
+	       {
+		  DGifCloseFile(gif);
+		  free(rows);
+		  return NULL;
+	       }
+	     for (i = 0; i < *h; i++)
+		rows[i] = NULL;
+	     for (i = 0; i < *h; i++)
+	       {
+		  rows[i] = malloc(*w * sizeof(GifPixelType));
+		  if (!rows[i])
+		    {
+		       DGifCloseFile(gif);
+		       for (i = 0; i < *h; i++)
+			  if (rows[i])
+			     free(rows[i]);
+		       free(rows);
+		       free(data);
+		       return NULL;
+		    }
+	       }
+	     if (gif->Image.Interlace)
+	       {
+		  for (i = 0; i < 4; i++)
+		    {
+		       for (j = intoffset[i]; j < *h; j += intjump[i])
+			  DGifGetLine(gif, rows[j], *w);
+		    }
+	       }
+	     else
+	       {
+		  for (i = 0; i < *h; i++)
+		     DGifGetLine(gif, rows[i], *w);
+	       }
+	     done = 1;
+	  }
+	else if (rec == EXTENSION_RECORD_TYPE)
+	  {
+	     int                 ext_code;
+	     GifByteType        *ext;
+
+	     DGifGetExtension(gif, &ext_code, &ext);
+	     if (ext)
+	       {
+		  if ((ext[1] & 1))
+		    {
+		       istransp = 1;
+		       transp = (int)ext[4];
+		    }
+	       }
+	     do
+	       {
+		  DGifGetExtensionNext(gif, &ext);
+	       }
+	     while (ext);
+	  }
+     }
+   while (rec != TERMINATE_RECORD_TYPE);
+   bg = gif->SBackGroundColor;
+   cmap = (gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap);
+   csize = cmap->ColorCount;
+   ptr = data;
+   if (!istransp)
+     {
+	for (i = 0; i < *h; i++)
+	  {
+	     for (j = 0; j < *w; j++)
+	       {
+		  r = cmap->Colors[rows[i][j]].Red;
+		  g = cmap->Colors[rows[i][j]].Green;
+		  b = cmap->Colors[rows[i][j]].Blue;
+		  *ptr++ = r;
+		  *ptr++ = g;
+		  *ptr++ = b;
+	       }
+	  }
+     }
+   else
+     {
+	for (i = 0; i < *h; i++)
+	  {
+	     for (j = 0; j < *w; j++)
+	       {
+		  if (rows[i][j] == transp)
+		    {
+		       *ptr++ = 255;
+		       *ptr++ = 0;
+		       *ptr++ = 255;
+		    }
+		  else
+		    {
+		       r = cmap->Colors[rows[i][j]].Red;
+		       g = cmap->Colors[rows[i][j]].Green;
+		       b = cmap->Colors[rows[i][j]].Blue;
+		       if (r == 255 && g == 0 && b == 255)
+			  r = 254;
+		       *ptr++ = r;
+		       *ptr++ = g;
+		       *ptr++ = b;
+		    }
+	       }
+	  }
+     }
+   DGifCloseFile(gif);
+   for (i = 0; i < *h; i++)
+      free(rows[i]);
+   free(rows);
+   *t = istransp;
+   return data;
+}
+
+#endif /* HAVE_LIBGIF */
+
+unsigned char      *
+g_LoadXPM(char *f, int *w, int *h, int *t)
+{
+   FILE               *file;
+   unsigned char      *data, *ptr;
+   int                 pc, c, i, j, k, ncolors, cpp, comment, transp, quote,
+                       context, len, token, done;
+   char                line[65536], s[65536], tok[65536], col[65536];
+   XColor              xcol;
+   struct _cmap
+     {
+	char                str[8];
+	char                transp;
+	int                 r, g, b;
+     }
+                      *cmap;
+   int                 lookup[128][128];
+
+   transp = 0;
+   done = 0;
+
+   file = fopen(f, "r");
+   if (!file)
+      return NULL;
+
+   *w = 10;
+   *h = 10;
+
+   ptr = NULL;
+   data = NULL;
+   c = ' ';
+   comment = 0;
+   quote = 0;
+   context = 0;
+
+   while (!done)
+     {
+	pc = c;
+	c = fgetc(file);
+	if (c == EOF)
+	   break;
+	if (!quote)
+	  {
+	     if (pc == '/' && c == '*')
+		comment = 1;
+	     else if (pc == '*' && c == '/' && comment)
+		comment = 0;
+	  }
+	if (!comment)
+	  {
+	     if (!quote && c == '"')
+	       {
+		  quote = 1;
+		  i = 0;
+	       }
+	     else if (quote && c == '"')
+	       {
+		  line[i] = 0;
+		  quote = 0;
+		  if (context == 0)
+		    {
+		       /* Header */
+		       sscanf(line, "%i %i %i %i", w, h, &ncolors, &cpp);
+		       if (cpp > 7)
+			 {
+			    fprintf(stderr, "gdk_imlib ERROR: XPM files with characters per pixel > 7 not supported\n");
+			    return NULL;
+			 }
+		       if (*w > 32767)
+			 {
+			    fprintf(stderr, "gdk_imlib ERROR: Image width > 32767 pixels for file\n");
+			    return NULL;
+			 }
+		       if (*h > 32767)
+			 {
+			    fprintf(stderr, "gdk_imlib ERROR: Image height > 32767 pixels for file\n");
+			    return NULL;
+			 }
+		       cmap = malloc(sizeof(struct _cmap) * ncolors);
+
+		       if (!cmap)
+			  return NULL;
+		       data = malloc(*w ** h * 3);
+		       if (!data)
+			 {
+			    free(cmap);
+			    return NULL;
+			 }
+		       ptr = data;
+		       j = 0;
+		       context++;
+		    }
+		  else if (context == 1)
+		    {
+		       /* Color Table */
+		       if (j < ncolors)
+			 {
+			    int                 colptr = 0;
+			    int                 slen;
+
+			    tok[0] = 0;
+			    col[0] = 0;
+			    s[0] = 0;
+			    len = strlen(line);
+			    strncpy(cmap[j].str, line, cpp);
+			    cmap[j].str[cpp] = 0;
+			    cmap[j].r = -1;
+			    cmap[j].transp = 0;
+			    for (k = cpp; k < len; k++)
+			      {
+				 if (line[k] != ' ')
+				   {
+				      s[0] = 0;
+				      sscanf(&line[k], "%65535s", s);
+				      slen = strlen(s);
+				      k += slen;
+				      if ((!strcmp(s, "m")) || (!strcmp(s, "s")) ||
+					  (!strcmp(s, "g4")) || (!strcmp(s, "g")) ||
+					  (!strcmp(s, "c")) || (k >= len))
+					{
+					   if (k >= len)
+					     {
+						if (col[0])
+						   strcat(col, " ");
+						strcat(col, s);
+					     }
+					   if (col[0])
+					     {
+						if (!strcasecmp(col, "none"))
+						  {
+						     transp = 1;
+						     cmap[j].transp = 1;
+						  }
+						else
+						  {
+						     if ((cmap[j].r < 0) ||
+							 (!strcmp(tok, "c")))
+						       {
+							  XParseColor(id->x.disp,
+							      id->x.root_cmap,
+								  col, &xcol);
+							  cmap[j].r = xcol.red >> 8;
+							  cmap[j].g = xcol.green >> 8;
+							  cmap[j].b = xcol.blue >> 8;
+							  if ((cmap[j].r == 255) &&
+							   (cmap[j].g == 0) &&
+							   (cmap[j].b == 255))
+							     cmap[j].r = 254;
+						       }
+						  }
+					     }
+					   strcpy(tok, s);
+					   col[0] = 0;
+					}
+				      else
+					{
+					   if (col[0])
+					      strcat(col, " ");
+					   strcat(col, s);
+					}
+				   }
+			      }
+			 }
+		       j++;
+		       if (j >= ncolors)
+			 {
+			    if (cpp == 1)
+			       for (i = 0; i < ncolors; i++)
+				  lookup[cmap[i].str[0]][cmap[i].str[1]] = i;
+			    if (cpp == 2)
+			       for (i = 0; i < ncolors; i++)
+				  lookup[cmap[i].str[0]][cmap[i].str[1]] = i;
+			    context++;
+			 }
+		    }
+		  else
+		    {
+		       /* Image Data */
+		       i = 0;
+		       if (cpp == 0)
+			 {
+			    /* Chars per pixel = 0? well u never know */
+			 }
+		       if (cpp == 1)
+			 {
+			    if (transp)
+			      {
+				 for (i = 0; ((i < 65536) && (line[i])); i++)
+				   {
+				      col[0] = line[i];
+				      if (cmap[lookup[col[0]][0]].transp)
+					{
+					   *ptr++ = 255;
+					   *ptr++ = 0;
+					   *ptr++ = 255;
+					}
+				      else
+					{
+					   *ptr++ = (unsigned char)cmap[lookup[col[0]][0]].r;
+					   *ptr++ = (unsigned char)cmap[lookup[col[0]][0]].g;
+					   *ptr++ = (unsigned char)cmap[lookup[col[0]][0]].b;
+					}
+				   }
+			      }
+			    else
+			      {
+				 for (i = 0; ((i < 65536) && (line[i])); i++)
+				   {
+				      col[0] = line[i];
+				      *ptr++ = (unsigned char)cmap[lookup[col[0]][0]].r;
+				      *ptr++ = (unsigned char)cmap[lookup[col[0]][0]].g;
+				      *ptr++ = (unsigned char)cmap[lookup[col[0]][0]].b;
+				   }
+			      }
+			 }
+		       else if (cpp == 2)
+			 {
+			    if (transp)
+			      {
+				 for (i = 0; ((i < 65536) && (line[i])); i++)
+				   {
+				      col[0] = line[i++];
+				      col[1] = line[i];
+				      if (cmap[lookup[col[0]][col[1]]].transp)
+					{
+					   *ptr++ = 255;
+					   *ptr++ = 0;
+					   *ptr++ = 255;
+					}
+				      else
+					{
+					   *ptr++ = (unsigned char)cmap[lookup[col[0]][col[1]]].r;
+					   *ptr++ = (unsigned char)cmap[lookup[col[0]][col[1]]].g;
+					   *ptr++ = (unsigned char)cmap[lookup[col[0]][col[1]]].b;
+					}
+				   }
+			      }
+			    else
+			      {
+				 for (i = 0; ((i < 65536) && (line[i])); i++)
+				   {
+				      col[0] = line[i++];
+				      col[1] = line[i];
+				      *ptr++ = (unsigned char)cmap[lookup[col[0]][col[1]]].r;
+				      *ptr++ = (unsigned char)cmap[lookup[col[0]][col[1]]].g;
+				      *ptr++ = (unsigned char)cmap[lookup[col[0]][col[1]]].b;
+				   }
+			      }
+			 }
+		       else
+			 {
+			    if (transp)
+			      {
+				 for (i = 0; ((i < 65536) && (line[i])); i++)
+				   {
+				      for (j = 0; j < cpp; j++, i++)
+					{
+					   col[j] = line[i];
+					}
+				      col[j] = 0;
+				      i--;
+				      for (j = 0; j < ncolors; j++)
+					{
+					   if (!strcmp(col, cmap[j].str))
+					     {
+						if (cmap[j].transp)
+						  {
+						     *ptr++ = 255;
+						     *ptr++ = 0;
+						     *ptr++ = 255;
+						  }
+						else
+						  {
+						     *ptr++ = (unsigned char)cmap[j].r;
+						     *ptr++ = (unsigned char)cmap[j].g;
+						     *ptr++ = (unsigned char)cmap[j].b;
+						  }
+						j = ncolors;
+					     }
+					}
+				   }
+			      }
+			    else
+			      {
+				 for (i = 0; ((i < 65536) && (line[i])); i++)
+				   {
+				      for (j = 0; j < cpp; j++, i++)
+					{
+					   col[j] = line[i];
+					}
+				      col[j] = 0;
+				      i--;
+				      for (j = 0; j < ncolors; j++)
+					{
+					   if (!strcmp(col, cmap[j].str))
+					     {
+						*ptr++ = (unsigned char)cmap[j].r;
+						*ptr++ = (unsigned char)cmap[j].g;
+						*ptr++ = (unsigned char)cmap[j].b;
+						j = ncolors;
+					     }
+					}
+				   }
+			      }
+			 }
+		    }
+	       }
+	  }
+	/* Scan in line from XPM file (limit line length 65k) */
+	if (i < 65536)
+	  {
+	     if ((!comment) && (quote) && (c != '"'))
+	       {
+		  line[i++] = c;
+	       }
+	  }
+	if ((ptr) && ((ptr - data) >= *w ** h * 3))
+	   done = 1;
+     }
+   fclose(file);
+   if (transp)
+      *t = 1;
+   else
+      *t = 0;
+   free(cmap);
+   return data;
+}
+
+unsigned char      *
+g_LoadPPM(FILE * f, int *w, int *h)
+{
+   int                 done;
+   unsigned char      *ptr;
+   unsigned char       chr;
+   char                s[256];
+   int                 a, b;
+   int                 color, scale;
+
+   a = b = scale = 0;
+   fgets(s, 256, f);
+   s[strlen(s) - 1] = 0;
+
+   if (!strcmp(s, "P6"))
+      color = 1;
+   else if (!strcmp(s, "P5"))
+      color = 0;
+   else
+      return NULL;
+
+   done = 1;
+   ptr = NULL;
+   while (done)
+     {
+	if (fgets(s, 256, f) == NULL)
+	   break;
+
+	s[strlen(s) - 1] = 0;
+	if (s[0] != '#')
+	  {
+	     done = 0;
+	     sscanf(s, "%i %i", w, h);
+	     a = *w;
+	     b = *h;
+	     if (a > 32767)
+	       {
+		  fprintf(stderr, "gdk_imlib ERROR: Image width > 32767 pixels for file\n");
+		  return NULL;
+	       }
+	     if (b > 32767)
+	       {
+		  fprintf(stderr, "gdk_imlib ERROR: Image height > 32767 pixels for file\n");
+		  return NULL;
+	       }
+	     fgets(s, 256, f);
+	     sscanf(s, "%i", &scale);
+	     s[strlen(s) - 1] = 0;
+	     ptr = (unsigned char *)malloc(a * b * 3);
+	     if (!ptr)
+	       {
+		  fprintf(stderr, "gdk_imlib ERROR: Cannot allocate RAM for RGB data in file");
+		  return ptr;
+	       }
+	     if (color)
+	       {
+		  if (!fread(ptr, a * b * 3, 1, f))
+		    {
+		       free(ptr);
+		       return NULL;
+		    }
+	       }
+	     else
+	       {
+		  b = (a * b * 3);
+		  a = 0;
+		  while ((fread(&chr, 1, 1, f)) && (a < b))
+		    {
+		       ptr[a++] = chr;
+		       ptr[a++] = chr;
+		       ptr[a++] = chr;
+		    }
+	       }
+	  }
+     }
+   if (scale == 0)
+     {
+	free(ptr);
+	return NULL;
+     }
+   if (scale < 255)
+     {
+	int                 rot;
+	unsigned char      *po;
+
+	if (scale <= 1)
+	   rot = 7;
+	else if (scale <= 3)
+	   rot = 6;
+	else if (scale <= 7)
+	   rot = 5;
+	else if (scale <= 15)
+	   rot = 4;
+	else if (scale <= 31)
+	   rot = 3;
+	else if (scale <= 63)
+	   rot = 2;
+	else
+	   rot = 1;
+
+	if (rot > 0)
+	  {
+	     po = ptr;
+	     while (po < (ptr + (*w ** h * 3)))
+	       {
+		  *po++ <<= rot;
+		  *po++ <<= rot;
+		  *po++ <<= rot;
+	       }
+	  }
+     }
+   return ptr;
+}
+
+static int
+gispnm(char *file)
+{
+   FILE               *f;
+   char                buf[8];
+
+   f = fopen(file, "rb");
+   if (!f)
+      return 0;
+   fgets(buf, 8, f);
+   fclose(f);
+   if (!strcmp("P6\n", buf))
+      return 1;
+   if (!strcmp("P5\n", buf))
+      return 1;
+   return 0;
+}
+
+static int
+gisjpeg(char *file)
+{
+   FILE               *f;
+   unsigned char       buf[8];
+
+   f = fopen(file, "rb");
+   if (!f)
+      return 0;
+   fread(buf, 1, 2, f);
+   fclose(f);
+   if ((buf[0] == 0xff) && (buf[1] == 0xd8))
+      return 1;
+   return 0;
+}
+
+static int
+gispng(char *file)
+{
+#ifdef HAVE_LIBPNG
+   FILE               *f;
+   unsigned char       buf[8];
+
+   f = fopen(file, "rb");
+   if (!f)
+      return 0;
+   fread(buf, 1, 8, f);
+   fclose(f);
+   return (int)png_check_sig(buf, 8);
+#else
+   return 0;
+#endif
+}
+
+static int
+gistiff(char *file)
+{
+   FILE               *f;
+   char                buf[8];
+
+   f = fopen(file, "rb");
+   if (!f)
+      return 0;
+   fgets(buf, 5, f);
+   fclose(f);
+   if ((buf[0] == 'M') && (buf[1] == 'M') && (buf[2] == 0x00) && (buf[3] == 0x2a))
+      return 1;
+   if ((buf[0] == 'I') && (buf[1] == 'I') && (buf[2] == 0x2a) && (buf[3] == 0x00))
+      return 1;
+   return 0;
+}
+
+static int
+giseim(char *file)
+{
+   FILE               *f;
+   char                buf[8];
+
+   f = fopen(file, "rb");
+   if (!f)
+      return 0;
+   fread(buf, 1, 4, f);
+   fclose(f);
+   if (!strncmp("EIM ", buf, 4))
+      return 1;
+   return 0;
+}
+
+static int
+gisgif(char *file)
+{
+   FILE               *f;
+   char                buf[8];
+
+   f = fopen(file, "rb");
+   if (!f)
+      return 0;
+   fread(buf, 1, 4, f);
+   fclose(f);
+   buf[4] = 0;
+   if (!strcmp("GIF8", buf))
+      return 1;
+   return 0;
+}
+
+static int
+gisxpm(char *file)
+{
+   FILE               *f;
+   char                buf[11];
+
+   f = fopen(file, "rb");
+   if (!f)
+      return 0;
+   fread(buf, 1, 9, f);
+   fclose(f);
+   buf[9] = 0;
+   if (!strcmp("/* XPM */", buf))
+      return 1;
+   return 0;
+}
+
+GdkImlibImage      *
+gdk_imlib_load_image(char *file)
+{
+   int                 w, h;
+   int                 needs_conv = 1;
+   unsigned char      *data;
+   GdkImlibImage      *im;
+   char                s[4096];
+   char                fil[4096];
+   char               *iden;
+   char               *e;
+   char                cmd[4096];
+   FILE               *p;
+   int                 eim;
+   int                 fmt;
+   int                 trans;
+
+   eim = 0;
+   fmt = 0;
+   p = NULL;
+   data = NULL;
+
+   if (!file)
+      return NULL;
+   if (id->cache.on_image)
+      if ((im = gfind_image(file)))
+	 return im;
+
+   strncpy(fil, file, sizeof(fil));
+   iden = g_SplitID(fil);
+   e = g_GetExtension(fil);
+
+   if (gispnm(fil))
+     {
+	needs_conv = 0;
+	fmt = 0;
+     }
+   else if (gisjpeg(fil))
+     {
+#ifdef HAVE_LIBJPEG
+	needs_conv = 0;
+	fmt = 2;
+#else
+	needs_conv = 1;
+	fmt = 0;
+#endif
+     }
+   else if (gistiff(fil))
+     {
+#ifdef HAVE_LIBTIFF
+	needs_conv = 0;
+	fmt = 3;
+#else
+	needs_conv = 1;
+	fmt = 0;
+#endif
+     }
+   else if (giseim(fil))
+     {
+	needs_conv = 0;
+	eim = 1;
+	fmt = 9999;
+     }
+   else if (gisxpm(fil))
+     {
+	needs_conv = 0;
+	fmt = 5;
+     }
+   else if (gispng(fil))
+     {
+#ifdef HAVE_LIBPNG
+	needs_conv = 0;
+	fmt = 1;
+#else
+	needs_conv = 1;
+	fmt = 0;
+#endif
+     }
+   else if (gisgif(fil))
+     {
+#ifdef HAVE_LIBGIF
+	needs_conv = 0;
+	fmt = 4;
+#else
+	needs_conv = 1;
+	fmt = 0;
+#endif
+     }
+   if (needs_conv && id->fallback)
+     {
+	p = open_helper("%C/convert %s pnm:-", fil, "rb");
+     }
+   else if ((fmt == 2) || (fmt == 1) || (fmt == 0))
+      p = fopen(fil, "rb");
+
+   trans = 0;
+   if (!eim && !data)
+     {
+	switch (fmt)
+	  {
+	  case 5:
+	     data = g_LoadXPM(fil, &w, &h, &trans);
+	     break;
+#ifdef HAVE_LIBGIF
+	  case 4:
+	     data = g_LoadGIF(fil, &w, &h, &trans);
+	     break;
+#endif
+#ifdef HAVE_LIBTIFF
+	  case 3:
+	     data = g_LoadTIFF(fil, &w, &h, &trans);
+	     break;
+#endif
+#ifdef HAVE_LIBJPEG
+	  case 2:
+	     if (p)
+		data = g_LoadJPEG(p, &w, &h);
+	     break;
+#endif
+#ifdef HAVE_LIBPNG
+	  case 1:
+	     if (p)
+		data = g_LoadPNG(p, &w, &h, &trans);
+	     break;
+#endif
+	  default:
+	     if (p)
+		data = g_LoadPPM(p, &w, &h);
+	     break;
+	  }
+     }
+
+   if (p && !needs_conv)
+      fclose(p);
+   else if (p)
+      close_helper(p);
+
+   if ((!data) && (id->fallback))
+     {
+	p = open_helper("%C/convert %s pnm:-", fil, "rb");
+	if (p)
+	  {
+	     data = g_LoadPPM(p, &w, &h);
+	     close_helper(p);
+	  }
+     }
+   if ((!eim) && (!data) && (id->fallback))
+     {
+	if (!strcasecmp(s, "jpeg"))
+	   strcpy(cmd, "%J %s");
+	else if (!strcasecmp(s, "jpg"))
+	   strcpy(cmd, "%J %s");
+	else if (!strcasecmp(s, "bmp"))
+	   strcpy(cmd, "%P/bmptoppm %s");
+	else if (!strcasecmp(s, "ilbm"))
+	   strcpy(cmd, "%P/ilbmtoppm %s");
+	else if (!strcasecmp(s, "ilb"))
+	   strcpy(cmd, "%P/ilbmtoppm %s");
+	else if (!strcasecmp(s, "iff"))
+	   strcpy(cmd, "%P/ilbmtoppm %s");
+	else if (!strcasecmp(s, "img"))
+	   strcpy(cmd, "%P/imgtoppm %s");
+	else if (!strcasecmp(s, "mtv"))
+	   strcpy(cmd, "%P/mtvtoppm %s");
+	else if (!strcasecmp(s, "pcx"))
+	   strcpy(cmd, "%P/pcxtoppm %s");
+	else if (!strcasecmp(s, "pgm"))
+	   strcpy(cmd, "%P/pgmtoppm rgb:ffff/ffff/ffff %s");
+	else if (!strcasecmp(s, "pi1"))
+	   strcpy(cmd, "%P/pi1toppm %s");
+	else if (!strcasecmp(s, "pict"))
+	   strcpy(cmd, "%P/picttoppm %s");
+	else if (!strcasecmp(s, "pic"))
+	   strcpy(cmd, "%P/picttoppm %s");
+	else if (!strcasecmp(s, "pj"))
+	   strcpy(cmd, "%P/pjtoppm %s");
+	else if (!strcasecmp(s, "qrt"))
+	   strcpy(cmd, "%P/qrttoppm %s");
+	else if (!strcasecmp(s, "sld"))
+	   strcpy(cmd, "%P/sldtoppm %s");
+	else if (!strcasecmp(s, "spc"))
+	   strcpy(cmd, "%P/spctoppm %s");
+	else if (!strcasecmp(s, "spu"))
+	   strcpy(cmd, "%P/sputoppm %s");
+	else if (!strcasecmp(s, "tga"))
+	   strcpy(cmd, "%P/tgatoppm %s");
+	else if (!strcasecmp(s, "xim"))
+	   strcpy(cmd, "%P/ximtoppm %s");
+	else if (!strcasecmp(s, "xpm"))
+	   strcpy(cmd, "%P/xpmtoppm %s");
+	else if (!strcasecmp(s, "gif"))
+	   strcpy(cmd, "%P/giftopnm %s");
+	else if (!strcasecmp(s, "rast"))
+	   strcpy(cmd, "%P/rasttopnm %s");
+	else if (!strcasecmp(s, "ras"))
+	   strcpy(cmd, "%P/rasttopnm %s");
+	else if (!strcasecmp(s, "sgi"))
+	   strcpy(cmd, "%P/sgitopnm %s");
+	else if (!strcasecmp(s, "sir"))
+	   strcpy(cmd, "%P/sirtopnm %s");
+	else if (!strcasecmp(s, "tiff"))
+	   strcpy(cmd, "%P/tifftopnm %s");
+	else if (!strcasecmp(s, "tif"))
+	   strcpy(cmd, "%P/tifftopnm %s");
+	else if (!strcasecmp(s, "wxd"))
+	   strcpy(cmd, "%P/wxdtopnm %s");
+	else if (!strcasecmp(s, "zeiss"))
+	   strcpy(cmd, "%P/zeisstopnm -ppm %s");
+	else if (!strcasecmp(s, "zei"))
+	   strcpy(cmd, "%P/zeisstopnm -ppm %s");
+	else if (!strcasecmp(s, "zis"))
+	   strcpy(cmd, "%P/zeisstopnm -ppm %s");
+	else
+	   strcpy(cmd, "%P/anytopnm %s");
+	p = open_helper(cmd, fil, "rb");
+	if (p)
+	  {
+	     data = g_LoadPPM(p, &w, &h);
+	     close_helper(p);
+	  }
+     }
+
+   if (!eim && !data)
+     {
+	fprintf(stderr, "gdk_imlib ERROR: Cannot load image: %s\nAll fallbacks failed.\n", fil);
+	return NULL;
+     }
+
+   im = (GdkImlibImage *) malloc(sizeof(GdkImlibImage));
+   if (!im)
+     {
+	fprintf(stderr, "gdk_imlib ERROR: Cannot allocate RAM for image data\n");
+	if (data)
+	   free(data);
+	return NULL;
+     }
+   im->alpha_data = NULL;
+   if (trans)
+     {
+	im->shape_color.r = 255;
+	im->shape_color.g = 0;
+	im->shape_color.b = 255;
+     }
+   else
+     {
+	im->shape_color.r = -1;
+	im->shape_color.g = -1;
+	im->shape_color.b = -1;
+     }
+   im->border.left = 0;
+   im->border.right = 0;
+   im->border.top = 0;
+   im->border.bottom = 0;
+   im->cache = 1;
+   im->rgb_data = data;
+   im->rgb_width = w;
+   im->rgb_height = h;
+   im->pixmap = NULL;
+   im->shape_mask = NULL;
+   if (eim)
+     {
+	char                s1[256], s2[256];
+	int                 num, size;
+	int                 r, g, b;
+	int                 br, bl, bt, bb;
+
+	/* Load Native-as-can-be EIM format (Enlightenment IMlib format) */
+	p = fopen(fil, "r");
+	if (!p)
+	  {
+	     free(im);
+	     return NULL;
+	  }
+	fgets(s, 4096, p);
+	if ((s[0] != 'E') && (s[1] != 'I') && (s[2] != 'M') && (s[3] != ' '))
+	  {
+	     fclose(p);
+	     free(im);
+	     return NULL;
+	  }
+	sscanf(s, "%256s %i", s1, &num);
+	if (num <= 0)
+	  {
+	     fclose(p);
+	     free(im);
+	     return NULL;
+	  }
+	while (fgets(s, 4096, p))
+	  {
+	     sscanf(s, "%256s", s1);
+	     if (!strcmp("IMAGE", s1))
+	       {
+		  sscanf(s, "%256s %i %256s %i %i %i %i %i %i %i %i %i", s1, &size, s2, &w, &h, &r, &g, &b, &bl, &br, &bt, &bb);
+		  if (!iden[0])
+		     break;
+		  else if (!strcmp(iden, s2))
+		     break;
+		  if (size > 0)
+		     fseek(p, size, SEEK_CUR);
+	       }
+	  }
+	im->rgb_data = malloc(w * h * 3);
+	if (!im->rgb_data)
+	  {
+	     fclose(p);
+	     free(im);
+	     return NULL;
+	  }
+	im->shape_color.r = r;
+	im->shape_color.g = g;
+	im->shape_color.b = b;
+	im->rgb_width = w;
+	im->rgb_height = h;
+	im->border.left = bl;
+	im->border.right = br;
+	im->border.top = bt;
+	im->border.bottom = bb;
+	fread(im->rgb_data, 1, w * h * 3, p);
+	fclose(p);
+	if (iden[0])
+	  {
+	     strncat(fil, ":", sizeof(fil) - strlen(fil));
+	     strncat(fil, iden, sizeof(fil) - strlen(fil));
+	  }
+     }
+   im->mod.gamma = id->mod.gamma;
+   im->mod.brightness = id->mod.brightness;
+   im->mod.contrast = id->mod.contrast;
+   im->rmod.gamma = id->rmod.gamma;
+   im->rmod.brightness = id->rmod.brightness;
+   im->rmod.contrast = id->rmod.contrast;
+   im->gmod.gamma = id->gmod.gamma;
+   im->gmod.brightness = id->gmod.brightness;
+   im->gmod.contrast = id->gmod.contrast;
+   im->bmod.gamma = id->bmod.gamma;
+   im->bmod.brightness = id->bmod.brightness;
+   im->bmod.contrast = id->bmod.contrast;
+   im->filename = malloc(strlen(file) + 1);
+   if (im->filename)
+      strcpy(im->filename, file);
+   if ((id->cache.on_image && im))
+      gadd_image(im, fil);
+   gcalc_map_tables(im);
+   return im;
+}
+
+gint
+gdk_imlib_save_image_to_eim(GdkImlibImage * im, char *file)
+{
+   char                fil[4096];
+   char               *iden;
+   FILE               *f;
+   int                 size;
+
+   if ((!id) || (!im) || (!file))
+      return 0;
+   strncpy(fil, file, sizeof(fil));
+   iden = g_SplitID(fil);
+   if (!iden[0])
+      iden = "default";
+   f = fopen(fil, "w");
+   if (!f)
+      return 0;
+
+   size = im->rgb_width * im->rgb_height * 3;
+   fprintf(f, "EIM 1\n");
+   fprintf(f, "IMAGE %i %s %i %i %i %i %i %i %i %i %i\n",
+	   size,
+	   iden,
+	   im->rgb_width,
+	   im->rgb_height,
+	   im->shape_color.r,
+	   im->shape_color.g,
+	   im->shape_color.b,
+	   im->border.left,
+	   im->border.right,
+	   im->border.top,
+	   im->border.bottom);
+   if (fwrite(im->rgb_data, size, 1, f) != 1)
+     {
+	fclose(f);
+	return 0;
+     }
+   fclose(f);
+   return 1;
+}
+
+gint
+gdk_imlib_add_image_to_eim(GdkImlibImage * im, char *file)
+{
+   char                fil[4096];
+   char               *iden;
+   FILE               *f;
+   int                 size;
+
+   if ((!id) || (!im) || (!file))
+      return 0;
+   strncpy(fil, file, sizeof(fil));
+
+   iden = g_SplitID(file);
+   if (!iden[0])
+      strcpy(iden, "default");
+
+   f = fopen(fil, "a");
+   if (!f)
+      return 0;
+
+   size = im->rgb_width * im->rgb_height * 3;
+   fprintf(f, "IMAGE %i %s %i %i %i %i %i %i %i %i %i\n",
+	   size,
+	   iden,
+	   im->rgb_width,
+	   im->rgb_height,
+	   im->shape_color.r,
+	   im->shape_color.g,
+	   im->shape_color.b,
+	   im->border.left,
+	   im->border.right,
+	   im->border.top,
+	   im->border.bottom);
+
+   if (fwrite(im->rgb_data, size, 1, f) != 1)
+     {
+	fclose(f);
+	return 0;
+     }
+   fclose(f);
+   return 1;
+}
+
+gint
+gdk_imlib_save_image_to_ppm(GdkImlibImage * im, char *file)
+{
+   FILE               *f;
+
+   if ((!id) || (!im) || (!file))
+      return 0;
+   f = fopen(file, "w");
+   if (!f)
+      return 0;
+
+   fprintf(f, "P6\n");
+   fprintf(f, "%i %i\n255\n",
+	   im->rgb_width,
+	   im->rgb_height);
+   if (fwrite(im->rgb_data, im->rgb_width * im->rgb_height * 3, 1, f) != 1)
+     {
+	fclose(f);
+	return 0;
+     }
+   fclose(f);
+   return 1;
+}
diff --git a/src/gdk_imlib/misc.c b/src/gdk_imlib/misc.c
new file mode 100644
index 0000000000..e5fe025037
--- /dev/null
+++ b/src/gdk_imlib/misc.c
@@ -0,0 +1,1165 @@
+#define _GNU_SOURCE
+#include "gdk_imlib.h"
+#include "gdk_imlib_private.h"
+
+gint
+gdk_imlib_get_render_type()
+{
+   if (id)
+      return id->render_type;
+   else
+      return -1;
+}
+
+void
+gdk_imlib_set_render_type(gint rend_type)
+{
+   if (id)
+     {
+	if (id->x.depth > 8)
+	   id->render_type = rend_type;
+	else
+	  {
+	     if ((rend_type == RT_PLAIN_TRUECOL) ||
+		 (rend_type == RT_DITHER_TRUECOL))
+		id->render_type = RT_DITHER_PALETTE_FAST;
+	     else
+		id->render_type = rend_type;
+	  }
+	return;
+     }
+   else
+      return;
+}
+
+static void
+gdk_imlib_set_fast_render(ImlibData * id, Display * disp)
+{
+   /* Turn off fastrender if there is an endianess diff between */
+   /* client and Xserver */
+   int                 byt, bit;
+
+   byt = ImageByteOrder(id->x.disp);	/* LSBFirst | MSBFirst */
+   bit = BitmapBitOrder(id->x.disp);	/* LSBFirst | MSBFirst */
+   /* if little endian && server big */
+   if (htonl(1) != 1 && byt == MSBFirst)
+      id->fastrend = 0;
+   /* if big endian && server little */
+   if (htonl(1) == 1 && byt == LSBFirst)
+      id->fastrend = 0;
+}
+
+static int
+gdk_imlib_set_color_map(ImlibData * id, Display * disp)
+{
+   XSetWindowAttributes at;
+   unsigned long       mask;
+   int                 newcm = 0;
+
+   at.border_pixel = 0;
+   at.backing_store = NotUseful;
+   at.background_pixel = 0;
+   at.save_under = False;
+   at.override_redirect = True;
+   mask = CWOverrideRedirect | CWBackPixel | CWBorderPixel |
+      CWBackingStore | CWSaveUnder;
+   newcm = 0;
+   if (id->x.visual != DefaultVisual(disp, id->x.screen))
+     {
+	Colormap            cm;
+
+	cm = XCreateColormap(id->x.disp, id->x.root,
+			     id->x.visual, AllocNone);
+	if (cm)
+	  {
+	     mask |= CWColormap;
+	     id->x.root_cmap = cm;
+	     at.colormap = cm;
+	     newcm = 1;
+	  }
+     }
+   id->x.base_window = XCreateWindow(id->x.disp, id->x.root,
+				     -100, -100, 10, 10, 0,
+				     id->x.depth, InputOutput,
+				     id->x.visual, mask, &at);
+   id->x.gdk_win = gdk_window_foreign_new(id->x.base_window);
+   if (newcm)
+      id->x.gdk_cmap = gdk_colormap_new(gdk_window_get_visual
+					(id->x.gdk_win), FALSE);
+   else
+      id->x.gdk_cmap = gdk_colormap_get_system();
+   return newcm;
+}
+
+void
+gdk_imlib_init()
+{
+   Display            *disp;
+   XWindowAttributes   xwa;
+   XVisualInfo         xvi, *xvir;
+   char               *homedir;
+   char                s[4096];
+   char               *s1;
+   char               *s2;
+   FILE               *f;
+   int                 override = 0;
+   int                 dither = 0;
+   int                 remap = 1;
+   int                 num;
+   int                 i, max, maxn;
+   int                 clas;
+   char               *palfile = NULL;
+   int                 loadpal;
+   int                 vis;
+   int                 newcm;
+
+   disp = (Display *) gdk_display;
+   if (!disp)
+     {
+	fprintf(stderr, "gdk_imlib ERROR: gdk has not connected to the display\n");
+	return;
+     }
+   vis = -1;
+   loadpal = 0;
+   if (id)
+      return;
+   id = (ImlibData *) malloc(sizeof(ImlibData));
+   if (!id)
+     {
+	fprintf(stderr, "gdk_imlib ERROR: Cannot alloc RAM for Initial data struct\n");
+	return;
+     }
+   id->palette = NULL;
+   id->palette_orig = NULL;
+   id->fast_rgb = NULL;
+   id->fast_err = NULL;
+   id->fast_erg = NULL;
+   id->fast_erb = NULL;
+   id->x.disp = disp;
+   id->x.screen = DefaultScreen(disp);	/* the screen number */
+   id->x.root = DefaultRootWindow(disp);	/* the root window id */
+   id->x.visual = DefaultVisual(disp, id->x.screen);	/* the visual type */
+   id->x.depth = DefaultDepth(disp, id->x.screen);	/* the depth of the screen in bpp */
+   if (XShmQueryExtension(id->x.disp))
+     {
+	id->x.shm = 1;
+	id->x.shm_event = XShmGetEventBase(id->x.disp) + ShmCompletion;
+	id->x.last_xim = NULL;
+	id->x.last_sxim = NULL;
+	id->max_shm = 0x7fffffff;
+	if (XShmPixmapFormat(id->x.disp) == ZPixmap)
+	   id->x.shmp = 1;
+     }
+   else
+     {
+	id->x.shm = 0;
+	id->x.shmp = 0;
+     }
+   id->cache.on_image = 0;
+   id->cache.size_image = 0;
+   id->cache.num_image = 0;
+   id->cache.used_image = 0;
+   id->cache.image = NULL;
+   id->cache.on_pixmap = 0;
+   id->cache.size_pixmap = 0;
+   id->cache.num_pixmap = 0;
+   id->cache.used_pixmap = 0;
+   id->cache.pixmap = NULL;
+   id->byte_order = 0;
+   id->fastrend = 0;
+   id->hiq = 0;
+   id->fallback = 1;
+   id->mod.gamma = 256;
+   id->mod.brightness = 256;
+   id->mod.contrast = 256;
+   id->rmod.gamma = 256;
+   id->rmod.brightness = 256;
+   id->rmod.contrast = 256;
+   id->gmod.gamma = 256;
+   id->gmod.brightness = 256;
+   id->gmod.contrast = 256;
+   id->bmod.gamma = 256;
+   id->bmod.brightness = 256;
+   id->bmod.contrast = 256;
+   id->ordered_dither = 1;
+
+   if (XGetWindowAttributes(disp, id->x.root, &xwa))
+     {
+	if (xwa.colormap)
+	   id->x.root_cmap = xwa.colormap;
+	else
+	   id->x.root_cmap = 0;
+     }
+   else
+      id->x.root_cmap = 0;
+
+   id->num_colors = 0;
+   homedir = getenv("HOME");
+   g_snprintf(s, sizeof(s), "%s/.imrc", homedir);
+   f = fopen(s, "r");
+   if (!f)
+      f = fopen(SYSTEM_IMRC, "r");
+   if (f)
+     {
+	while (fgets(s, 4096, f))
+	  {
+	     if (s[0] == '#')
+		continue;
+
+	     s1 = strtok(s, " \t\n");
+
+	     /* Blank line ? */
+
+	     if (s1 == NULL)
+		continue;
+
+	     s2 = strtok(NULL, " \t\n");
+	     if (s2 == NULL)
+		s2 = "";	/* NULL argument */
+
+	     if (!strcasecmp("PaletteFile", s1))
+	       {
+		  palfile = strdup(s2);
+	       }
+	     else if (!strcasecmp("PaletteOverride", s1))
+	       {
+		  if (!strcasecmp("yes", s2))
+		     override = 1;
+		  else
+		     override = 0;
+	       }
+	     else if (!strcasecmp("Dither", s1))
+	       {
+		  if (!strcasecmp("yes", s2))
+		     dither = 1;
+		  else
+		     dither = 0;
+	       }
+	     else if (!strcasecmp("Remap", s1))
+	       {
+		  if (!strcasecmp("fast", s2))
+		     remap = 1;
+		  else
+		     remap = 0;
+	       }
+	     else if (!strcasecmp("Mit-Shm", s1))
+	       {
+		  if (!strcasecmp("off", s2))
+		    {
+		       id->x.shm = 0;
+		       id->x.shmp = 0;
+		    }
+	       }
+	     else if (!strcasecmp("SharedPixmaps", s1))
+	       {
+		  if (!strcasecmp("off", s2))
+		     id->x.shmp = 0;
+	       }
+	     else if (!strcasecmp("FastRender", s1))
+	       {
+		  if (!strcasecmp("on", s2))
+		     id->fastrend = 1;
+	       }
+	     else if (!strcasecmp("HighQuality", s1))
+	       {
+		  if (!strcasecmp("on", s2))
+		     id->hiq = 1;
+	       }
+	     else if (!strcasecmp("Shm_Max_Size", s1))
+	       {
+		  num = atoi(s2);
+		  id->max_shm = num;
+	       }
+	     else if (!strcasecmp("Image_Cache_Size", s1))
+	       {
+		  num = atoi(s2);
+		  id->cache.size_image = num;
+	       }
+	     else if (!strcasecmp("Pixmap_Cache_Size", s1))
+	       {
+		  num = atoi(s2);
+		  id->cache.size_pixmap = num;
+	       }
+	     else if (!strcasecmp("Image_Cache", s1))
+	       {
+		  if (!strcasecmp("on", s2))
+		     id->cache.on_image = 1;
+	       }
+	     else if (!strcasecmp("Pixmap_Cache", s1))
+	       {
+		  if (!strcasecmp("on", s2))
+		     id->cache.on_pixmap = 1;
+	       }
+	     else if (!strcasecmp("ForceVisualID", s1))
+	       {
+		  sscanf(s, "%1024s %x", s1, &num);
+		  vis = num;
+	       }
+	     else if (!strcasecmp("Fallback", s1))
+	       {
+		  if (!strcasecmp("off", s2))
+		     id->fallback = 0;
+		  else
+		     id->fallback = 1;
+	       }
+	     else if (!strcasecmp("Gamma", s1))
+	       {
+		  id->mod.gamma = (int)(256.0 * atof(s2));
+	       }
+	     else if (!strcasecmp("Brightness", s1))
+	       {
+		  id->mod.brightness = (int)(256.0 * atof(s2));
+	       }
+	     else if (!strcasecmp("Contrast", s1))
+	       {
+		  id->mod.contrast = (int)(256.0 * atof(s2));
+	       }
+	     else if (!strcasecmp("Red_Gamma", s1))
+	       {
+		  id->rmod.gamma = (int)(256.0 * atof(s2));
+	       }
+	     else if (!strcasecmp("Red_Brightness", s1))
+	       {
+		  id->rmod.brightness = (int)(256.0 * atof(s2));
+	       }
+	     else if (!strcasecmp("Red_Contrast", s1))
+	       {
+		  id->rmod.contrast = (int)(256.0 * atof(s2));
+	       }
+	     else if (!strcasecmp("Green_Gamma", s1))
+	       {
+		  id->gmod.gamma = (int)(256.0 * atof(s2));
+	       }
+	     else if (!strcasecmp("Green_Brightness", s1))
+	       {
+		  id->gmod.brightness = (int)(256.0 * atof(s2));
+	       }
+	     else if (!strcasecmp("Green_Contrast", s1))
+	       {
+		  id->gmod.contrast = (int)(256.0 * atof(s2));
+	       }
+	     else if (!strcasecmp("Blue_Gamma", s1))
+	       {
+		  id->bmod.gamma = (int)(256.0 * atof(s2));
+	       }
+	     else if (!strcasecmp("Blue_Brightness", s1))
+	       {
+		  id->bmod.brightness = (int)(256.0 * atof(s2));
+	       }
+	     else if (!strcasecmp("Blue_Contrast", s1))
+	       {
+		  id->bmod.contrast = (int)(256.0 * atof(s2));
+	       }
+	     else if (!strcasecmp("Ordered_Dither", s1))
+	       {
+		  if (!strcasecmp("off", s2))
+		     id->ordered_dither = 0;
+		  else
+		     id->ordered_dither = 1;
+	       }
+	  }
+	fclose(f);
+     }
+   /* list all visuals for the default screen */
+   xvi.screen = id->x.screen;
+   xvir = XGetVisualInfo(disp, VisualScreenMask, &xvi, &num);
+   if (vis >= 0)
+     {
+	/* use the forced visual id */
+	maxn = 0;
+	for (i = 0; i < num; i++)
+	  {
+	     if (xvir[i].visualid == (VisualID) vis)
+		maxn = i;
+	  }
+	if (maxn >= 0)
+	  {
+	     unsigned long       rmsk, gmsk, bmsk;
+
+	     id->x.depth = xvir[maxn].depth;
+	     id->x.visual = xvir[maxn].visual;
+	     rmsk = xvir[maxn].red_mask;
+	     gmsk = xvir[maxn].green_mask;
+	     bmsk = xvir[maxn].blue_mask;
+
+	     if ((rmsk > gmsk) && (gmsk > bmsk))
+		id->byte_order = BYTE_ORD_24_RGB;
+	     else if ((rmsk > bmsk) && (bmsk > gmsk))
+		id->byte_order = BYTE_ORD_24_RBG;
+	     else if ((bmsk > rmsk) && (rmsk > gmsk))
+		id->byte_order = BYTE_ORD_24_BRG;
+	     else if ((bmsk > gmsk) && (gmsk > rmsk))
+		id->byte_order = BYTE_ORD_24_BGR;
+	     else if ((gmsk > rmsk) && (rmsk > bmsk))
+		id->byte_order = BYTE_ORD_24_GRB;
+	     else if ((gmsk > bmsk) && (bmsk > rmsk))
+		id->byte_order = BYTE_ORD_24_GBR;
+	     else
+		id->byte_order = 0;
+	  }
+	else
+	   fprintf(stderr, "Visual Id no 0x%x specified in the imrc file is invalid on this display.\nUsing Default Visual.\n", vis);
+     }
+   else
+     {
+	if (xvir)
+	  {
+	     /* find the highest bit-depth supported by visuals */
+	     max = 0;
+	     for (i = 0; i < num; i++)
+	       {
+		  if (xvir[i].depth > max)
+		     max = xvir[i].depth;
+	       }
+	     if (max > 8)
+	       {
+		  id->x.depth = max;
+		  clas = -1;
+		  maxn = -1;
+		  for (i = 0; i < num; i++)
+		    {
+		       if (xvir[i].depth == id->x.depth)
+			 {
+			    if ((xvir[i].class > clas) && (xvir[i].class != DirectColor))
+			      {
+				 maxn = i;
+				 clas = xvir[i].class;
+			      }
+			 }
+		    }
+		  if (maxn >= 0)
+		    {
+		       unsigned long       rmsk, gmsk, bmsk;
+
+		       id->x.visual = xvir[maxn].visual;
+		       rmsk = xvir[maxn].red_mask;
+		       gmsk = xvir[maxn].green_mask;
+		       bmsk = xvir[maxn].blue_mask;
+
+		       if ((rmsk > gmsk) && (gmsk > bmsk))
+			  id->byte_order = BYTE_ORD_24_RGB;
+		       else if ((rmsk > bmsk) && (bmsk > gmsk))
+			  id->byte_order = BYTE_ORD_24_RBG;
+		       else if ((bmsk > rmsk) && (rmsk > gmsk))
+			  id->byte_order = BYTE_ORD_24_BRG;
+		       else if ((bmsk > gmsk) && (gmsk > rmsk))
+			  id->byte_order = BYTE_ORD_24_BGR;
+		       else if ((gmsk > rmsk) && (rmsk > bmsk))
+			  id->byte_order = BYTE_ORD_24_GRB;
+		       else if ((gmsk > bmsk) && (bmsk > rmsk))
+			  id->byte_order = BYTE_ORD_24_GBR;
+		       else
+			  id->byte_order = 0;
+		    }
+	       }
+	  }
+     }
+   id->x.render_depth = id->x.depth;
+   XFree(xvir);
+
+   if (id->x.depth == 16)
+     {
+	xvi.visual = id->x.visual;
+	xvi.visualid = XVisualIDFromVisual(id->x.visual);
+	xvir = XGetVisualInfo(disp, VisualIDMask, &xvi, &num);
+	if (xvir)
+	  {
+	     if (xvir->red_mask != 0xf800)
+		id->x.render_depth = 15;
+	     XFree(xvir);
+	  }
+     }
+   if (id->x.depth <= 8 || override == 1)
+      loadpal = 1;
+
+   if (loadpal)
+     {
+	if (dither == 1)
+	  {
+	     if (remap == 1)
+		id->render_type = RT_DITHER_PALETTE_FAST;
+	     else
+		id->render_type = RT_DITHER_PALETTE;
+	  }
+	else
+	  {
+	     if (remap == 1)
+		id->render_type = RT_PLAIN_PALETTE_FAST;
+	     else
+		id->render_type = RT_PLAIN_PALETTE;
+	  }
+	/* Should we error this case or default it nicely */
+	if (palfile != NULL)
+	   gdk_imlib_load_colors(palfile);
+	if (id->num_colors == 0)
+	  {
+	     fprintf(stderr, "gdk_imlib: Cannot Find Palette. A Palette is required for this mode\n");
+	     free(id);
+	     id = NULL;
+	     if (palfile)
+		free(palfile);
+	     return;
+	  }
+     }
+   else
+     {
+	if (id->hiq == 1)
+	   id->render_type = RT_DITHER_TRUECOL;
+	else
+	   id->render_type = RT_PLAIN_TRUECOL;
+     }
+
+   newcm = gdk_imlib_set_color_map(id, disp);
+
+   gdk_imlib_set_fast_render(id, disp);
+
+   if (palfile)
+      free(palfile);
+}
+
+void
+gdk_imlib_init_params(GdkImlibInitParams * p)
+{
+   Display            *disp;
+   XWindowAttributes   xwa;
+   XVisualInfo         xvi, *xvir;
+   char               *homedir;
+   char                file[4096];
+   char                s[4096], *s1, *s2;
+   FILE               *f;
+   int                 override = 0;
+   int                 dither = 0;
+   int                 remap = 1;
+   int                 num;
+   int                 i, max, maxn;
+   int                 clas;
+   char               *palfile;
+   int                 loadpal;
+   int                 vis;
+   int                 newcm;
+
+   disp = (Display *) gdk_display;
+   if (!disp)
+     {
+	fprintf(stderr, "gdk_imlib ERROR: gdk has not connected to the display\n");
+	return;
+     }
+   vis = -1;
+   loadpal = 0;
+   if (id)
+      return;
+   id = (ImlibData *) malloc(sizeof(ImlibData));
+   if (!id)
+     {
+	fprintf(stderr, "gdk_imlib ERROR: Cannot alloc RAM for Initial data struct\n");
+	return;
+     }
+   id->palette = NULL;
+   id->palette_orig = NULL;
+   id->fast_rgb = NULL;
+   id->fast_err = NULL;
+   id->fast_erg = NULL;
+   id->fast_erb = NULL;
+   id->x.disp = disp;
+   id->x.screen = DefaultScreen(disp);	/* the screen number */
+   id->x.root = DefaultRootWindow(disp);	/* the root window id */
+   id->x.visual = DefaultVisual(disp, id->x.screen);	/* the visual type */
+   id->x.depth = DefaultDepth(disp, id->x.screen);	/* the depth of the screen in bpp */
+   if (XShmQueryExtension(id->x.disp))
+     {
+	id->x.shm = 1;
+	id->x.shm_event = XShmGetEventBase(id->x.disp) + ShmCompletion;
+	id->x.last_xim = NULL;
+	id->x.last_sxim = NULL;
+	id->max_shm = 0x7fffffff;
+	if (XShmPixmapFormat(id->x.disp) == ZPixmap)
+	   id->x.shmp = 1;
+     }
+   else
+     {
+	id->x.shm = 0;
+	id->x.shmp = 0;
+     }
+   id->cache.on_image = 0;
+   id->cache.size_image = 0;
+   id->cache.num_image = 0;
+   id->cache.used_image = 0;
+   id->cache.image = NULL;
+   id->cache.on_pixmap = 0;
+   id->cache.size_pixmap = 0;
+   id->cache.num_pixmap = 0;
+   id->cache.used_pixmap = 0;
+   id->cache.pixmap = NULL;
+   id->byte_order = 0;
+   id->fastrend = 0;
+   id->hiq = 0;
+   id->fallback = 1;
+   id->mod.gamma = 256;
+   id->mod.brightness = 256;
+   id->mod.contrast = 256;
+   id->rmod.gamma = 256;
+   id->rmod.brightness = 256;
+   id->rmod.contrast = 256;
+   id->gmod.gamma = 256;
+   id->gmod.brightness = 256;
+   id->gmod.contrast = 256;
+   id->bmod.gamma = 256;
+   id->bmod.brightness = 256;
+   id->bmod.contrast = 256;
+
+   if (XGetWindowAttributes(disp, id->x.root, &xwa))
+     {
+	if (xwa.colormap)
+	   id->x.root_cmap = xwa.colormap;
+	else
+	   id->x.root_cmap = 0;
+     }
+   else
+      id->x.root_cmap = 0;
+   id->num_colors = 0;
+   homedir = getenv("HOME");
+   g_snprintf(s, sizeof(s), "%s/.imrc", homedir);
+   f = fopen(s, "r");
+   if (!f)
+      f = fopen(SYSTEM_IMRC, "r");
+   if (f)
+     {
+	while (fgets(s, 4096, f))
+	  {
+	     if (s[0] == '#')
+		continue;
+
+	     s1 = strtok(s, " \t\n");
+
+	     /* Blank line ? */
+
+	     if (s1 == NULL)
+		continue;
+
+	     s2 = strtok(NULL, " \t\n");
+	     if (s2 == NULL)
+		s2 = "";	/* NULL argument */
+
+	     if (!strcasecmp("PaletteFile", s1))
+	       {
+		  palfile = strdup(s2);
+	       }
+	     else if (!strcasecmp("PaletteOverride", s1))
+	       {
+		  if (!strcasecmp("yes", s2))
+		     override = 1;
+		  else
+		     override = 0;
+	       }
+	     else if (!strcasecmp("Dither", s1))
+	       {
+		  if (!strcasecmp("yes", s2))
+		     dither = 1;
+		  else
+		     dither = 0;
+	       }
+	     else if (!strcasecmp("Remap", s1))
+	       {
+		  if (!strcasecmp("fast", s2))
+		     remap = 1;
+		  else
+		     remap = 0;
+	       }
+	     else if (!strcasecmp("Mit-Shm", s1))
+	       {
+		  if (!strcasecmp("off", s2))
+		    {
+		       id->x.shm = 0;
+		       id->x.shmp = 0;
+		    }
+	       }
+	     else if (!strcasecmp("SharedPixmaps", s1))
+	       {
+		  if (!strcasecmp("off", s2))
+		     id->x.shmp = 0;
+	       }
+	     else if (!strcasecmp("FastRender", s1))
+	       {
+		  if (!strcasecmp("on", s2))
+		     id->fastrend = 1;
+	       }
+	     else if (!strcasecmp("HighQuality", s1))
+	       {
+		  if (!strcasecmp("on", s2))
+		     id->hiq = 1;
+	       }
+	     else if (!strcasecmp("Shm_Max_Size", s1))
+	       {
+		  num = atoi(s2);
+		  id->max_shm = num;
+	       }
+	     if (!strcasecmp("Image_Cache_Size", s1))
+	       {
+		  num = atoi(s2);
+		  id->cache.size_image = num;
+	       }
+	     else if (!strcasecmp("Pixmap_Cache_Size", s1))
+	       {
+		  num = atoi(s2);
+		  id->cache.size_pixmap = num;
+	       }
+	     else if (!strcasecmp("Image_Cache", s1))
+	       {
+		  if (!strcasecmp("on", s2))
+		     id->cache.on_image = 1;
+	       }
+	     else if (!strcasecmp("Pixmap_Cache", s1))
+	       {
+		  if (!strcasecmp("on", s2))
+		     id->cache.on_pixmap = 1;
+	       }
+	     else if (!strcasecmp("ForceVisualID", s1))
+	       {
+		  sscanf(s, "%1024s %x", s1, &num);
+		  vis = num;
+	       }
+	     else if (!strcasecmp("Fallback", s1))
+	       {
+		  if (!strcasecmp("off", s2))
+		     id->fallback = 0;
+		  else
+		     id->fallback = 1;
+	       }
+	     else if (!strcasecmp("Gamma", s1))
+	       {
+		  id->mod.gamma = (int)(256.0 * atof(s2));
+	       }
+	     else if (!strcasecmp("Brightness", s1))
+	       {
+		  id->mod.brightness = (int)(256.0 * atof(s2));
+	       }
+	     else if (!strcasecmp("Contrast", s1))
+	       {
+		  id->mod.contrast = (int)(256.0 * atof(s2));
+	       }
+	     else if (!strcasecmp("Red_Gamma", s1))
+	       {
+		  id->rmod.gamma = (int)(256.0 * atof(s2));
+	       }
+	     else if (!strcasecmp("Red_Brightness", s1))
+	       {
+		  id->rmod.brightness = (int)(256.0 * atof(s2));
+	       }
+	     else if (!strcasecmp("Red_Contrast", s1))
+	       {
+		  id->rmod.contrast = (int)(256.0 * atof(s2));
+	       }
+	     else if (!strcasecmp("Green_Gamma", s1))
+	       {
+		  id->gmod.gamma = (int)(256.0 * atof(s2));
+	       }
+	     else if (!strcasecmp("Green_Brightness", s1))
+	       {
+		  id->gmod.brightness = (int)(256.0 * atof(s2));
+	       }
+	     else if (!strcasecmp("Green_Contrast", s1))
+	       {
+		  id->gmod.contrast = (int)(256.0 * atof(s2));
+	       }
+	     else if (!strcasecmp("Blue_Gamma", s1))
+	       {
+		  id->bmod.gamma = (int)(256.0 * atof(s2));
+	       }
+	     else if (!strcasecmp("Blue_Brightness", s1))
+	       {
+		  id->bmod.brightness = (int)(256.0 * atof(s2));
+	       }
+	     else if (!strcasecmp("Blue_Contrast", s1))
+	       {
+		  id->bmod.contrast = (int)(256.0 * atof(s2));
+	       }
+	     else if (!strcasecmp("Ordered_Dither", s1))
+	       {
+		  if (!strcasecmp("off", s2))
+		     id->ordered_dither = 0;
+		  else
+		     id->ordered_dither = 1;
+	       }
+	  }
+	fclose(f);
+     }
+   if (p)
+     {
+	if (p->flags & PARAMS_VISUALID)
+	   vis = p->visualid;
+	if (p->flags & PARAMS_PALETTEFILE)
+	   palfile = strdup(p->palettefile);
+	if (p->flags & PARAMS_SHAREDMEM)
+	  {
+	     if (!p->sharedmem)
+	       {
+		  id->x.shm = 0;
+		  id->x.shmp = 0;
+	       }
+	     else
+	       {
+		  id->x.shm = 1;
+		  id->x.shmp = 0;
+	       }
+	  }
+	if (p->flags & PARAMS_SHAREDPIXMAPS)
+	  {
+	     if (id->x.shm)
+		id->x.shmp = p->sharedpixmaps;
+	  }
+	if (p->flags & PARAMS_PALETTEOVERRIDE)
+	   override = p->paletteoverride;
+	if (p->flags & PARAMS_REMAP)
+	   remap = p->remap;
+	if (p->flags & PARAMS_FASTRENDER)
+	   id->fastrend = p->fastrender;
+	if (p->flags & PARAMS_HIQUALITY)
+	   id->hiq = p->hiquality;
+	if (p->flags & PARAMS_DITHER)
+	   dither = p->dither;
+	if (p->flags & PARAMS_IMAGECACHESIZE)
+	   id->cache.size_image = p->imagecachesize;
+	if (p->flags & PARAMS_PIXMAPCACHESIZE)
+	   id->cache.size_pixmap = p->pixmapcachesize;
+     }
+   /* list all visuals for the default screen */
+   xvi.screen = id->x.screen;
+   xvir = XGetVisualInfo(disp, VisualScreenMask, &xvi, &num);
+   if (vis >= 0)
+     {
+	/* use the forced visual id */
+	maxn = 0;
+	for (i = 0; i < num; i++)
+	  {
+	     if (xvir[i].visualid == (VisualID) vis)
+		maxn = i;
+	  }
+	if (maxn >= 0)
+	  {
+	     unsigned long       rmsk, gmsk, bmsk;
+
+	     id->x.depth = xvir[maxn].depth;
+	     id->x.visual = xvir[maxn].visual;
+	     rmsk = xvir[maxn].red_mask;
+	     gmsk = xvir[maxn].green_mask;
+	     bmsk = xvir[maxn].blue_mask;
+
+	     if ((rmsk > gmsk) && (gmsk > bmsk))
+		id->byte_order = BYTE_ORD_24_RGB;
+	     else if ((rmsk > bmsk) && (bmsk > gmsk))
+		id->byte_order = BYTE_ORD_24_RBG;
+	     else if ((bmsk > rmsk) && (rmsk > gmsk))
+		id->byte_order = BYTE_ORD_24_BRG;
+	     else if ((bmsk > gmsk) && (gmsk > rmsk))
+		id->byte_order = BYTE_ORD_24_BGR;
+	     else if ((gmsk > rmsk) && (rmsk > bmsk))
+		id->byte_order = BYTE_ORD_24_GRB;
+	     else if ((gmsk > bmsk) && (bmsk > rmsk))
+		id->byte_order = BYTE_ORD_24_GBR;
+	     else
+		id->byte_order = 0;
+	  }
+	else
+	   fprintf(stderr, "Visual Id no 0x%x specified in the imrc file is invalid on this display.\nUsing Default Visual.\n", vis);
+     }
+   else
+     {
+	if (xvir)
+	  {
+	     /* find the highest bit-depth supported by visuals */
+	     max = 0;
+	     for (i = 0; i < num; i++)
+	       {
+		  if (xvir[i].depth > max)
+		     max = xvir[i].depth;
+	       }
+	     if (max > 8)
+	       {
+		  id->x.depth = max;
+		  clas = -1;
+		  maxn = -1;
+		  for (i = 0; i < num; i++)
+		    {
+		       if (xvir[i].depth == id->x.depth)
+			 {
+			    if ((xvir[i].class > clas) && (xvir[i].class != DirectColor))
+			      {
+				 maxn = i;
+				 clas = xvir[i].class;
+			      }
+			 }
+		    }
+		  if (maxn >= 0)
+		    {
+		       unsigned long       rmsk, gmsk, bmsk;
+
+		       id->x.visual = xvir[maxn].visual;
+		       rmsk = xvir[maxn].red_mask;
+		       gmsk = xvir[maxn].green_mask;
+		       bmsk = xvir[maxn].blue_mask;
+
+		       if ((rmsk > gmsk) && (gmsk > bmsk))
+			  id->byte_order = BYTE_ORD_24_RGB;
+		       else if ((rmsk > bmsk) && (bmsk > gmsk))
+			  id->byte_order = BYTE_ORD_24_RBG;
+		       else if ((bmsk > rmsk) && (rmsk > gmsk))
+			  id->byte_order = BYTE_ORD_24_BRG;
+		       else if ((bmsk > gmsk) && (gmsk > rmsk))
+			  id->byte_order = BYTE_ORD_24_BGR;
+		       else if ((gmsk > rmsk) && (rmsk > bmsk))
+			  id->byte_order = BYTE_ORD_24_GRB;
+		       else if ((gmsk > bmsk) && (bmsk > rmsk))
+			  id->byte_order = BYTE_ORD_24_GBR;
+		       else
+			  id->byte_order = 0;
+		    }
+	       }
+	  }
+     }
+   id->x.render_depth = id->x.depth;
+   XFree(xvir);
+   if (id->x.depth == 16)
+     {
+	xvi.visual = id->x.visual;
+	xvi.visualid = XVisualIDFromVisual(id->x.visual);
+	xvir = XGetVisualInfo(disp, VisualIDMask, &xvi, &num);
+	if (xvir)
+	  {
+	     if (xvir->red_mask != 0xf800)
+		id->x.render_depth = 15;
+	     XFree(xvir);
+	  }
+     }
+   if ((id->x.depth <= 8) || (override == 1))
+      loadpal = 1;
+   if (loadpal)
+     {
+	if (dither == 1)
+	  {
+	     if (remap == 1)
+		id->render_type = RT_DITHER_PALETTE_FAST;
+	     else
+		id->render_type = RT_DITHER_PALETTE;
+	  }
+	else
+	  {
+	     if (remap == 1)
+		id->render_type = RT_PLAIN_PALETTE_FAST;
+	     else
+		id->render_type = RT_PLAIN_PALETTE;
+	  }
+	gdk_imlib_load_colors(palfile);
+	if (id->num_colors == 0)
+	  {
+	     fprintf(stderr, "gdk_imlib: Cannot Find Palette. A Palette is required for this mode\n");
+	     free(id);
+	     id = NULL;
+	     if (palfile)
+		free(palfile);
+	     return;
+	  }
+     }
+   else
+     {
+	if (id->hiq == 1)
+	   id->render_type = RT_DITHER_TRUECOL;
+	else
+	   id->render_type = RT_PLAIN_TRUECOL;
+     }
+
+   newcm = gdk_imlib_set_color_map(id, disp);
+   gdk_imlib_set_fast_render(id, disp);
+   if (palfile)
+      free(palfile);
+}
+
+GdkPixmap          *
+gdk_imlib_copy_image(GdkImlibImage * im)
+{
+   GdkPixmap          *p;
+   GdkGC              *gc;
+
+   if ((!im) || (!im->pixmap))
+      return NULL;
+   p = gdk_pixmap_new(id->x.gdk_win, im->width, im->height, id->x.depth);
+   gc = gdk_gc_new(p);
+   gdk_draw_pixmap(p, gc, im->pixmap, 0, 0, 0, 0, im->width, im->height);
+   gdk_gc_destroy(gc);
+   return p;
+}
+
+GdkPixmap          *
+gdk_imlib_move_image(GdkImlibImage * im)
+{
+   GdkPixmap          *p;
+
+   if (!im)
+      return NULL;
+   p = im->pixmap;
+   im->pixmap = NULL;
+   return p;
+}
+
+GdkBitmap          *
+gdk_imlib_copy_mask(GdkImlibImage * im)
+{
+   GdkBitmap          *p;
+   GdkGC              *gc;
+
+   if ((!im) || (!im->shape_mask))
+      return NULL;
+   p = gdk_pixmap_new(id->x.gdk_win, im->width, im->height, 1);
+   gc = gdk_gc_new(p);
+   gdk_draw_pixmap(p, gc, im->shape_mask, 0, 0, 0, 0, im->width, im->height);
+   gdk_gc_destroy(gc);
+   return p;
+}
+
+GdkBitmap          *
+gdk_imlib_move_mask(GdkImlibImage * im)
+{
+   GdkBitmap          *p;
+
+   if (!im)
+      return NULL;
+   p = im->shape_mask;
+   im->shape_mask = NULL;
+   return p;
+}
+
+void
+gdk_imlib_destroy_image(GdkImlibImage * im)
+{
+   if (im)
+     {
+	if (id->cache.on_image)
+	  {
+	     gfree_image(im);
+	     gclean_caches();
+	  }
+	else
+	   gnullify_image(im);
+     }
+}
+
+void
+gdk_imlib_kill_image(GdkImlibImage * im)
+{
+   if (im)
+     {
+	if (id->cache.on_image)
+	  {
+	     gfree_image(im);
+	     gflush_image(im);
+	     gclean_caches();
+	  }
+	else
+	   gnullify_image(im);
+     }
+}
+
+void
+gdk_imlib_free_pixmap(GdkPixmap * pmap)
+{
+   if (pmap)
+     {
+	gfree_pixmappmap(pmap);
+	gclean_caches();
+     }
+}
+
+void
+gdk_imlib_free_bitmap(GdkBitmap * pmap)
+{
+   if (pmap)
+     {
+	gfree_pixmappmap(pmap);
+	gclean_caches();
+     }
+}
+
+void
+gdk_imlib_set_image_border(GdkImlibImage * im, GdkImlibBorder * border)
+{
+   if ((im) && (border))
+     {
+	im->border.left = border->left;
+	im->border.right = border->right;
+	im->border.top = border->top;
+	im->border.bottom = border->bottom;
+	gdirty_pixmaps(im);
+     }
+}
+
+void
+gdk_imlib_get_image_border(GdkImlibImage * im, GdkImlibBorder * border)
+{
+   if ((im) && (border))
+     {
+	border->left = im->border.left;
+	border->right = im->border.right;
+	border->top = im->border.top;
+	border->bottom = im->border.bottom;
+     }
+}
+
+void
+gdk_imlib_get_image_shape(GdkImlibImage * im, GdkImlibColor * color)
+{
+   if ((!im) || (!color))
+      return;
+   color->r = im->shape_color.r;
+   color->g = im->shape_color.g;
+   color->b = im->shape_color.b;
+}
+
+void
+gdk_imlib_set_image_shape(GdkImlibImage * im, GdkImlibColor * color)
+{
+   if ((!im) || (!color))
+      return;
+   im->shape_color.r = color->r;
+   im->shape_color.g = color->g;
+   im->shape_color.b = color->b;
+   gdirty_pixmaps(im);
+}
+
+gint
+gdk_imlib_get_fallback()
+{
+   if (!id)
+      return 0;
+   return id->fallback;
+}
+
+void
+gdk_imlib_set_fallback(gint fallback)
+{
+   if (!id)
+      return;
+   id->fallback = fallback;
+}
+
+GdkVisual          *
+gdk_imlib_get_visual()
+{
+   if (!id)
+      return NULL;
+   return gdk_window_get_visual(id->x.gdk_win);
+}
+
+GdkColormap        *
+gdk_imlib_get_colormap()
+{
+   if (!id)
+      return NULL;
+   return (id->x.gdk_cmap);
+}
+
+gchar              *
+gdk_imlib_get_sysconfig()
+{
+   if (!id)
+      return NULL;
+   return strdup(SYSTEM_IMRC);
+}
diff --git a/src/gdk_imlib/rend.c b/src/gdk_imlib/rend.c
new file mode 100644
index 0000000000..7cdabc01b4
--- /dev/null
+++ b/src/gdk_imlib/rend.c
@@ -0,0 +1,6170 @@
+#define _GNU_SOURCE
+#include "gdk_imlib.h"
+#include "gdk_imlib_private.h"
+
+GdkPixmap          *
+gdk_imlib_pixmap_foreign_new(gint width, gint height,
+			     gint depth, Pixmap pmap)
+{
+   GdkPixmap          *pixmap;
+   GdkWindowPrivate   *private;
+   GdkWindowPrivate   *window_private;
+
+   private = g_new(GdkWindowPrivate, 1);
+   pixmap = (GdkPixmap *) private;
+
+   window_private = (GdkWindowPrivate *) id->x.gdk_win;
+
+   private->xdisplay = window_private->xdisplay;
+   private->window_type = GDK_WINDOW_PIXMAP;
+   private->xwindow = pmap;
+   private->colormap = id->x.gdk_cmap;
+   private->children = NULL;
+   private->parent = NULL;
+   private->x = 0;
+   private->y = 0;
+   private->width = width;
+   private->height = height;
+   private->resize_count = 0;
+   private->ref_count = 1;
+   private->destroyed = 0;
+
+   gdk_xid_table_insert(&private->xwindow, pixmap);
+
+   return pixmap;
+}
+
+gint
+gdk_imlib_best_color_match(gint * r, gint * g, gint * b)
+{
+   int                 i;
+   int                 dif;
+   int                 dr, dg, db;
+   int                 col;
+   int                 mindif = 0x7fffffff;
+   XColor              xcl;
+
+   col = 0;
+   if (!id)
+     {
+	fprintf(stderr, "ImLib ERROR: No ImlibData initialised\n");
+	return -1;
+     }
+   if ((id->render_type == RT_PLAIN_TRUECOL) ||
+       (id->render_type == RT_DITHER_TRUECOL))
+     {
+	xcl.red = (unsigned short)((*r << 8) | (*r));
+	xcl.green = (unsigned short)((*g << 8) | (*g));
+	xcl.blue = (unsigned short)((*b << 8) | (*b));
+	xcl.flags = DoRed | DoGreen | DoBlue;
+	XAllocColor(id->x.disp, id->x.root_cmap, &xcl);
+	*r = xcl.red >> 8;
+	*g = xcl.green >> 8;
+	*b = xcl.blue >> 8;
+	return xcl.pixel;
+     }
+   for (i = 0; i < id->num_colors; i++)
+     {
+	dr = *r - id->palette[i].r;
+	if (dr < 0)
+	   dr = -dr;
+	dg = *g - id->palette[i].g;
+	if (dg < 0)
+	   dg = -dg;
+	db = *b - id->palette[i].b;
+	if (db < 0)
+	   db = -db;
+	dif = dr + dg + db;
+	if (dif < mindif)
+	  {
+	     mindif = dif;
+	     col = i;
+	  }
+     }
+   *r -= id->palette[col].r;
+   *g -= id->palette[col].g;
+   *b -= id->palette[col].b;
+   col = id->palette[col].pixel;
+   return col;
+}
+
+gint
+gindex_best_color_match(gint * r, gint * g, gint * b)
+{
+   int                 i;
+   int                 dif;
+   int                 dr, dg, db;
+   int                 col;
+   int                 mindif = 0x7fffffff;
+   XColor              xcl;
+
+   col = 0;
+   if (!id)
+     {
+	fprintf(stderr, "ImLib ERROR: No ImlibData initialised\n");
+	return -1;
+     }
+   if ((id->render_type == RT_PLAIN_TRUECOL) ||
+       (id->render_type == RT_DITHER_TRUECOL))
+     {
+	xcl.red = (unsigned short)((*r << 8) | (*r));
+	xcl.green = (unsigned short)((*g << 8) | (*g));
+	xcl.blue = (unsigned short)((*b << 8) | (*b));
+	xcl.flags = DoRed | DoGreen | DoBlue;
+	XAllocColor(id->x.disp, id->x.root_cmap, &xcl);
+	*r = xcl.red >> 8;
+	*g = xcl.green >> 8;
+	*b = xcl.blue >> 8;
+	return xcl.pixel;
+     }
+   for (i = 0; i < id->num_colors; i++)
+     {
+	dr = *r - id->palette[i].r;
+	if (dr < 0)
+	   dr = -dr;
+	dg = *g - id->palette[i].g;
+	if (dg < 0)
+	   dg = -dg;
+	db = *b - id->palette[i].b;
+	if (db < 0)
+	   db = -db;
+	dif = dr + dg + db;
+	if (dif < mindif)
+	  {
+	     mindif = dif;
+	     col = i;
+	  }
+     }
+   *r -= id->palette[col].r;
+   *g -= id->palette[col].g;
+   *b -= id->palette[col].b;
+   return col;
+}
+
+void
+grender_shaped_15_fast_dither(GdkImlibImage * im, int w, int h, XImage * xim,
+			      XImage * sxim, int *er1, int *er2, int *xarray,
+			      unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+   unsigned short     *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line >> 1) - w;
+   img = (unsigned short *)xim->data;
+   for (y = 0; y < h; y++)
+     {
+	ter = er1;
+	er1 = er2;
+	er2 = ter;
+	for (ex = 0; ex < (w + 2) * 3; ex++)
+	   er2[ex] = 0;
+	ex = 3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     if ((r == im->shape_color.r) &&
+		 (g == im->shape_color.g) &&
+		 (b == im->shape_color.b))
+	       {
+		  XPutPixel(sxim, x, y, 0);
+		  img++;
+		  ex += 3;
+	       }
+	     else
+	       {
+		  XPutPixel(sxim, x, y, 1);
+		  er = r + er1[ex++];
+		  eg = g + er1[ex++];
+		  eb = b + er1[ex++];
+		  if (er > 255)
+		     er = 255;
+		  if (eg > 255)
+		     eg = 255;
+		  if (eb > 255)
+		     eb = 255;
+		  val = ((er & 0xf8) << 7) | ((eg & 0xf8) << 2) | ((eb & 0xf8) >> 3);
+		  er = er & 0x07;
+		  eg = eg & 0x07;
+		  eb = eb & 0x07;
+		  DITHER_ERROR(er1, er2, ex, er, eg, eb);
+		  *img++ = val;
+	       }
+	  }
+	img += jmp;
+     }
+}
+
+void
+grender_shaped_15_fast_dither_ordered(GdkImlibImage * im, int w, int h, XImage * xim,
+			       XImage * sxim, int *er1, int *er2, int *xarray,
+				      unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+   unsigned short     *img;
+   int                 jmp;
+
+   unsigned char       dither[4][4] =
+   {
+      {0, 4, 6, 5},
+      {6, 2, 7, 3},
+      {2, 6, 1, 5},
+      {7, 4, 7, 3}
+   };
+   int                 dithy, dithx;
+
+   jmp = (xim->bytes_per_line >> 1) - w;
+   img = (unsigned short *)xim->data;
+   for (y = 0; y < h; y++)
+     {
+	dithy = y & 0x3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     if ((r == im->shape_color.r) &&
+		 (g == im->shape_color.g) &&
+		 (b == im->shape_color.b))
+	       {
+		  XPutPixel(sxim, x, y, 0);
+		  img++;
+	       }
+	     else
+	       {
+		  XPutPixel(sxim, x, y, 1);
+		  er = r & 0x07;
+		  eg = g & 0x07;
+		  eb = b & 0x07;
+		  dithx = x & 0x3;
+		  if ((dither[dithy][dithx] < er) && (r < (256 - 8)))
+		     r += 8;
+		  if ((dither[dithy][dithx] < eg) && (g < (256 - 8)))
+		     g += 8;
+		  if ((dither[dithy][dithx] < eb) && (b < (256 - 8)))
+		     b += 8;
+		  val = ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
+		  *img++ = val;
+	       }
+	  }
+	img += jmp;
+     }
+}
+
+void
+grender_15_fast_dither(GdkImlibImage * im, int w, int h, XImage * xim,
+		       XImage * sxim, int *er1, int *er2, int *xarray,
+		       unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+   unsigned short     *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line >> 1) - w;
+   img = (unsigned short *)xim->data;
+   for (y = 0; y < h; y++)
+     {
+	ter = er1;
+	er1 = er2;
+	er2 = ter;
+	for (ex = 0; ex < (w + 2) * 3; ex++)
+	   er2[ex] = 0;
+	ex = 3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     er = r + er1[ex++];
+	     eg = g + er1[ex++];
+	     eb = b + er1[ex++];
+	     if (er > 255)
+		er = 255;
+	     if (eg > 255)
+		eg = 255;
+	     if (eb > 255)
+		eb = 255;
+	     val = ((er & 0xf8) << 7) | ((eg & 0xf8) << 2) | ((eb & 0xf8) >> 3);
+	     er = er & 0x07;
+	     eg = eg & 0x07;
+	     eb = eb & 0x07;
+	     DITHER_ERROR(er1, er2, ex, er, eg, eb);
+	     *img++ = val;
+	  }
+	img += jmp;
+     }
+}
+
+void
+grender_15_fast_dither_ordered(GdkImlibImage * im, int w, int h, XImage * xim,
+			       XImage * sxim, int *er1, int *er2, int *xarray,
+			       unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+
+   unsigned short     *img;
+   int                 jmp;
+
+   unsigned char       dither[4][4] =
+   {
+      {0, 4, 6, 5},
+      {6, 2, 7, 3},
+      {2, 6, 1, 5},
+      {7, 4, 7, 3}
+   };
+   int                 dithy, dithx;
+
+   jmp = (xim->bytes_per_line >> 1) - w;
+   img = (unsigned short *)xim->data;
+   for (y = 0; y < h; y++)
+     {
+	dithy = y & 0x3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     er = r & 0x07;
+	     eg = g & 0x07;
+	     eb = b & 0x07;
+	     dithx = x & 0x3;
+	     if ((dither[dithy][dithx] < er) && (r < (256 - 8)))
+		r += 8;
+	     if ((dither[dithy][dithx] < eg) && (g < (256 - 8)))
+		g += 8;
+	     if ((dither[dithy][dithx] < eb) && (b < (256 - 8)))
+		b += 8;
+	     val = ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
+	     *img++ = val;
+	  }
+	img += jmp;
+     }
+}
+
+void
+grender_shaped_16_fast_dither(GdkImlibImage * im, int w, int h, XImage * xim,
+			      XImage * sxim, int *er1, int *er2, int *xarray,
+			      unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+   unsigned short     *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line >> 1) - w;
+   img = (unsigned short *)xim->data;
+   for (y = 0; y < h; y++)
+     {
+	ter = er1;
+	er1 = er2;
+	er2 = ter;
+	for (ex = 0; ex < (w + 2) * 3; ex++)
+	   er2[ex] = 0;
+	ex = 3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     if ((r == im->shape_color.r) &&
+		 (g == im->shape_color.g) &&
+		 (b == im->shape_color.b))
+	       {
+		  XPutPixel(sxim, x, y, 0);
+		  img++;
+		  ex += 3;
+	       }
+	     else
+	       {
+		  XPutPixel(sxim, x, y, 1);
+		  er = r + er1[ex++];
+		  eg = g + er1[ex++];
+		  eb = b + er1[ex++];
+		  if (er > 255)
+		     er = 255;
+		  if (eg > 255)
+		     eg = 255;
+		  if (eb > 255)
+		     eb = 255;
+		  val = ((er & 0xf8) << 8) | ((eg & 0xfc) << 3) | ((eb & 0xf8) >> 3);
+		  er = er & 0x07;
+		  eg = eg & 0x03;
+		  eb = eb & 0x07;
+		  DITHER_ERROR(er1, er2, ex, er, eg, eb);
+		  *img++ = val;
+	       }
+	  }
+	img += jmp;
+     }
+}
+
+void 
+grender_shaped_16_fast_dither_ordered(GdkImlibImage * im, int w, int h, XImage * xim,
+			       XImage * sxim, int *er1, int *er2, int *xarray,
+				      unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+   unsigned short     *img;
+   int                 jmp;
+
+   unsigned char       dither[4][4] =
+   {
+      {0, 4, 6, 5},
+      {6, 2, 7, 3},
+      {2, 6, 1, 5},
+      {7, 4, 7, 3}
+   };
+   int                 dithy, dithx;
+
+   jmp = (xim->bytes_per_line >> 1) - w;
+   img = (unsigned short *)xim->data;
+   for (y = 0; y < h; y++)
+     {
+	dithy = y & 0x3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     if ((r == im->shape_color.r) &&
+		 (g == im->shape_color.g) &&
+		 (b == im->shape_color.b))
+	       {
+		  XPutPixel(sxim, x, y, 0);
+		  img++;
+	       }
+	     else
+	       {
+		  XPutPixel(sxim, x, y, 1);
+		  er = r & 0x07;
+		  eg = g & 0x03;
+		  eb = b & 0x07;
+		  dithx = x & 0x3;
+		  if ((dither[dithy][dithx] < er) && (r < (256 - 8)))
+		     r += 8;
+		  if ((dither[dithy][dithx] < (eg << 1)) && (g < (256 - 4)))
+		     g += 4;
+		  if ((dither[dithy][dithx] < eb) && (b < (256 - 8)))
+		     b += 8;
+		  val = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3);
+		  *img++ = val;
+	       }
+	  }
+	img += jmp;
+     }
+}
+
+void
+grender_16_fast_dither(GdkImlibImage * im, int w, int h, XImage * xim,
+		       XImage * sxim, int *er1, int *er2, int *xarray,
+		       unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+
+   unsigned short     *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line >> 1) - w;
+   img = (unsigned short *)xim->data;
+   for (y = 0; y < h; y++)
+     {
+	ter = er1;
+	er1 = er2;
+	er2 = ter;
+	for (ex = 0; ex < (w + 2) * 3; ex++)
+	   er2[ex] = 0;
+	ex = 3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     er = r + er1[ex++];
+	     eg = g + er1[ex++];
+	     eb = b + er1[ex++];
+	     if (er > 255)
+		er = 255;
+	     if (eg > 255)
+		eg = 255;
+	     if (eb > 255)
+		eb = 255;
+	     val = ((er & 0xf8) << 8) | ((eg & 0xfc) << 3) | ((eb & 0xf8) >> 3);
+	     er = er & 0x07;
+	     eg = eg & 0x03;
+	     eb = eb & 0x07;
+	     DITHER_ERROR(er1, er2, ex, er, eg, eb);
+	     *img++ = val;
+	  }
+	img += jmp;
+     }
+}
+
+void 
+grender_16_fast_dither_ordered(GdkImlibImage * im, int w, int h, XImage * xim,
+			       XImage * sxim, int *er1, int *er2, int *xarray,
+			       unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+
+   unsigned short     *img;
+   int                 jmp;
+
+   unsigned char       dither[4][4] =
+   {
+      {0, 4, 6, 5},
+      {6, 2, 7, 3},
+      {2, 6, 1, 5},
+      {7, 4, 7, 3}
+   };
+   int                 dithy, dithx;
+
+   jmp = (xim->bytes_per_line >> 1) - w;
+   img = (unsigned short *)xim->data;
+   for (y = 0; y < h; y++)
+     {
+	dithy = y & 0x3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     er = r & 0x07;
+	     eg = g & 0x03;
+	     eb = b & 0x07;
+	     dithx = x & 0x3;
+	     if ((dither[dithy][dithx] < er) && (r < (256 - 8)))
+		r += 8;
+	     if ((dither[dithy][dithx] < (eg << 1)) && (g < (256 - 4)))
+		g += 4;
+	     if ((dither[dithy][dithx] < eb) && (b < (256 - 8)))
+		b += 8;
+	     val = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3);
+	     *img++ = val;
+	  }
+	img += jmp;
+     }
+}
+
+void
+grender_shaped_15_dither(GdkImlibImage * im, int w, int h, XImage * xim,
+			 XImage * sxim, int *er1, int *er2, int *xarray,
+			 unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+
+   for (y = 0; y < h; y++)
+     {
+	ter = er1;
+	er1 = er2;
+	er2 = ter;
+	for (ex = 0; ex < (w + 2) * 3; ex++)
+	   er2[ex] = 0;
+	ex = 3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     if ((r == im->shape_color.r) &&
+		 (g == im->shape_color.g) &&
+		 (b == im->shape_color.b))
+	       {
+		  XPutPixel(sxim, x, y, 0);
+		  ex += 3;
+	       }
+	     else
+	       {
+		  XPutPixel(sxim, x, y, 1);
+		  er = r + er1[ex++];
+		  eg = g + er1[ex++];
+		  eb = b + er1[ex++];
+		  if (er > 255)
+		     er = 255;
+		  if (eg > 255)
+		     eg = 255;
+		  if (eb > 255)
+		     eb = 255;
+		  val = ((er & 0xf8) << 7) | ((eg & 0xf8) << 2) | ((eb & 0xf8) >> 3);
+		  er = er & 0x07;
+		  eg = eg & 0x07;
+		  eb = eb & 0x07;
+		  if (er > 255)
+		     er = 255;
+		  else if (er < 0)
+		     er = 0;
+		  if (eg > 255)
+		     eg = 255;
+		  else if (eg < 0)
+		     eg = 0;
+		  if (eb > 255)
+		     eb = 255;
+		  else if (eb < 0)
+		     eb = 0;
+		  val = ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
+		  er = r & 0x07;
+		  eg = g & 0x07;
+		  eb = b & 0x07;
+		  DITHER_ERROR(er1, er2, ex, er, eg, eb);
+		  XPutPixel(xim, x, y, val);
+	       }
+	  }
+     }
+}
+
+void 
+grender_shaped_15_dither_ordered(GdkImlibImage * im, int w, int h, XImage * xim,
+			       XImage * sxim, int *er1, int *er2, int *xarray,
+				 unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+
+   unsigned char       dither[4][4] =
+   {
+      {0, 4, 6, 5},
+      {6, 2, 7, 3},
+      {2, 6, 1, 5},
+      {7, 4, 7, 3}
+   };
+   int                 dithy, dithx;
+
+   for (y = 0; y < h; y++)
+     {
+	dithy = y & 0x3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     if ((r == im->shape_color.r) &&
+		 (g == im->shape_color.g) &&
+		 (b == im->shape_color.b))
+	       {
+		  XPutPixel(sxim, x, y, 0);
+	       }
+	     else
+	       {
+		  XPutPixel(sxim, x, y, 1);
+		  er = r & 0x07;
+		  eg = g & 0x07;
+		  eb = b & 0x07;
+		  dithx = x & 0x3;
+		  if ((dither[dithy][dithx] < er) && (r < (256 - 8)))
+		     r += 8;
+		  if ((dither[dithy][dithx] < eg) && (g < (256 - 8)))
+		     g += 8;
+		  if ((dither[dithy][dithx] < eb) && (b < (256 - 8)))
+		     b += 8;
+		  val = ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
+		  XPutPixel(xim, x, y, val);
+	       }
+	  }
+     }
+}
+
+void
+grender_15_dither(GdkImlibImage * im, int w, int h, XImage * xim,
+		  XImage * sxim, int *er1, int *er2, int *xarray,
+		  unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+
+   for (y = 0; y < h; y++)
+     {
+	ter = er1;
+	er1 = er2;
+	er2 = ter;
+	for (ex = 0; ex < (w + 2) * 3; ex++)
+	   er2[ex] = 0;
+	ex = 3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     er = r + er1[ex++];
+	     eg = g + er1[ex++];
+	     eb = b + er1[ex++];
+	     if (er > 255)
+		er = 255;
+	     if (eg > 255)
+		eg = 255;
+	     if (eb > 255)
+		eb = 255;
+	     val = ((er & 0xf8) << 7) | ((eg & 0xf8) << 2) | ((eb & 0xf8) >> 3);
+	     er = er & 0x07;
+	     eg = eg & 0x07;
+	     eb = eb & 0x07;
+	     DITHER_ERROR(er1, er2, ex, er, eg, eb);
+	     XPutPixel(xim, x, y, val);
+	  }
+     }
+}
+
+void
+grender_15_dither_ordered(GdkImlibImage * im, int w, int h, XImage * xim,
+			  XImage * sxim, int *er1, int *er2, int *xarray,
+			  unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+
+   unsigned char       dither[4][4] =
+   {
+      {0, 4, 6, 5},
+      {6, 2, 7, 3},
+      {2, 6, 1, 5},
+      {7, 4, 7, 3}
+   };
+   int                 dithy, dithx;
+
+   for (y = 0; y < h; y++)
+     {
+	dithy = y & 0x3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     er = r & 0x07;
+	     eg = g & 0x07;
+	     eb = b & 0x07;
+	     dithx = x & 0x3;
+	     if ((dither[dithy][dithx] < er) && (r < (256 - 8)))
+		r += 8;
+	     if ((dither[dithy][dithx] < eg) && (g < (256 - 8)))
+		g += 8;
+	     if ((dither[dithy][dithx] < eb) && (b < (256 - 8)))
+		b += 8;
+	     val = ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
+	     XPutPixel(xim, x, y, val);
+	  }
+     }
+}
+
+void
+grender_shaped_16_dither(GdkImlibImage * im, int w, int h, XImage * xim,
+			 XImage * sxim, int *er1, int *er2, int *xarray,
+			 unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+
+   for (y = 0; y < h; y++)
+     {
+	ter = er1;
+	er1 = er2;
+	er2 = ter;
+	for (ex = 0; ex < (w + 2) * 3; ex++)
+	   er2[ex] = 0;
+	ex = 3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     if ((r == im->shape_color.r) &&
+		 (g == im->shape_color.g) &&
+		 (b == im->shape_color.b))
+	       {
+		  XPutPixel(sxim, x, y, 0);
+		  ex += 3;
+	       }
+	     else
+	       {
+		  XPutPixel(sxim, x, y, 1);
+		  er = r + er1[ex++];
+		  eg = g + er1[ex++];
+		  eb = b + er1[ex++];
+		  if (er > 255)
+		     er = 255;
+		  if (eg > 255)
+		     eg = 255;
+		  if (eb > 255)
+		     eb = 255;
+		  val = ((er & 0xf8) << 8) | ((eg & 0xfc) << 3) | ((eb & 0xf8) >> 3);
+		  er = er & 0x07;
+		  eg = eg & 0x03;
+		  eb = eb & 0x07;
+		  DITHER_ERROR(er1, er2, ex, er, eg, eb);
+		  XPutPixel(xim, x, y, val);
+	       }
+	  }
+     }
+}
+
+void
+grender_shaped_16_dither_ordered(GdkImlibImage * im, int w, int h, XImage * xim,
+			       XImage * sxim, int *er1, int *er2, int *xarray,
+				 unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+
+   unsigned char       dither[4][4] =
+   {
+      {0, 4, 6, 5},
+      {6, 2, 7, 3},
+      {2, 6, 1, 5},
+      {7, 4, 7, 3}
+   };
+   int                 dithy, dithx;
+
+   for (y = 0; y < h; y++)
+     {
+	dithy = y & 0x3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     if ((r == im->shape_color.r) &&
+		 (g == im->shape_color.g) &&
+		 (b == im->shape_color.b))
+	       {
+		  XPutPixel(sxim, x, y, 0);
+	       }
+	     else
+	       {
+		  XPutPixel(sxim, x, y, 1);
+		  er = r & 0x07;
+		  eg = g & 0x03;
+		  eb = b & 0x07;
+		  dithx = x & 0x3;
+		  if ((dither[dithy][dithx] < er) && (r < (256 - 8)))
+		     r += 8;
+		  if ((dither[dithy][dithx] < (eg << 1)) && (g < (256 - 4)))
+		     g += 4;
+		  if ((dither[dithy][dithx] < eb) && (b < (256 - 8)))
+		     b += 8;
+		  val = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3);
+		  XPutPixel(xim, x, y, val);
+	       }
+	  }
+     }
+}
+
+void
+grender_16_dither(GdkImlibImage * im, int w, int h, XImage * xim,
+		  XImage * sxim, int *er1, int *er2, int *xarray,
+		  unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+
+   for (y = 0; y < h; y++)
+     {
+	ter = er1;
+	er1 = er2;
+	er2 = ter;
+	for (ex = 0; ex < (w + 2) * 3; ex++)
+	   er2[ex] = 0;
+	ex = 3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     er = r + er1[ex++];
+	     eg = g + er1[ex++];
+	     eb = b + er1[ex++];
+	     if (er > 255)
+		er = 255;
+	     if (eg > 255)
+		eg = 255;
+	     if (eb > 255)
+		eb = 255;
+	     val = ((er & 0xf8) << 8) | ((eg & 0xfc) << 3) | ((eb & 0xf8) >> 3);
+	     er = er & 0x07;
+	     eg = eg & 0x03;
+	     eb = eb & 0x07;
+	     DITHER_ERROR(er1, er2, ex, er, eg, eb);
+	     XPutPixel(xim, x, y, val);
+	  }
+     }
+}
+
+void
+grender_16_dither_ordered(GdkImlibImage * im, int w, int h, XImage * xim,
+			  XImage * sxim, int *er1, int *er2, int *xarray,
+			  unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+
+   unsigned char       dither[4][4] =
+   {
+      {0, 4, 6, 5},
+      {6, 2, 7, 3},
+      {2, 6, 1, 5},
+      {7, 4, 7, 3}
+   };
+   int                 dithy, dithx;
+
+   for (y = 0; y < h; y++)
+     {
+	dithy = y & 0x3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     er = r & 0x07;
+	     eg = g & 0x03;
+	     eb = b & 0x07;
+	     dithx = x & 0x3;
+	     if ((dither[dithy][dithx] < er) && (r < (256 - 8)))
+		r += 8;
+	     if ((dither[dithy][dithx] < (eg << 1)) && (g < (256 - 4)))
+		g += 4;
+	     if ((dither[dithy][dithx] < eb) && (b < (256 - 8)))
+		b += 8;
+	     val = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3);
+	     XPutPixel(xim, x, y, val);
+	  }
+     }
+}
+
+void
+grender_shaped_15_fast(GdkImlibImage * im, int w, int h, XImage * xim,
+		       XImage * sxim, int *er1, int *er2, int *xarray,
+		       unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b;
+   unsigned char      *ptr2;
+   unsigned short     *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line >> 1) - w;
+   img = (unsigned short *)xim->data;
+   for (y = 0; y < h; y++)
+     {
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     if ((r == im->shape_color.r) &&
+		 (g == im->shape_color.g) &&
+		 (b == im->shape_color.b))
+	       {
+		  XPutPixel(sxim, x, y, 0);
+		  img++;
+	       }
+	     else
+	       {
+		  XPutPixel(sxim, x, y, 1);
+		  val = ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
+		  *img++ = val;
+	       }
+	  }
+	img += jmp;
+     }
+}
+
+void
+grender_15_fast(GdkImlibImage * im, int w, int h, XImage * xim,
+		XImage * sxim, int *er1, int *er2, int *xarray,
+		unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b;
+   unsigned char      *ptr2;
+   unsigned short     *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line >> 1) - w;
+   img = (unsigned short *)xim->data;
+   for (y = 0; y < h; y++)
+     {
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     val = ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
+	     *img++ = val;
+	  }
+	img += jmp;
+     }
+}
+
+void
+grender_shaped_16_fast(GdkImlibImage * im, int w, int h, XImage * xim,
+		       XImage * sxim, int *er1, int *er2, int *xarray,
+		       unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b;
+   unsigned char      *ptr2;
+   unsigned short     *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line >> 1) - w;
+   img = (unsigned short *)xim->data;
+   for (y = 0; y < h; y++)
+     {
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     if ((r == im->shape_color.r) &&
+		 (g == im->shape_color.g) &&
+		 (b == im->shape_color.b))
+	       {
+		  XPutPixel(sxim, x, y, 0);
+		  img++;
+	       }
+	     else
+	       {
+		  XPutPixel(sxim, x, y, 1);
+		  val = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3);
+		  *img++ = val;
+	       }
+	  }
+	img += jmp;
+     }
+}
+
+void
+grender_16_fast(GdkImlibImage * im, int w, int h, XImage * xim,
+		XImage * sxim, int *er1, int *er2, int *xarray,
+		unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b;
+   unsigned char      *ptr2;
+
+   unsigned short     *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line >> 1) - w;
+   img = (unsigned short *)xim->data;
+   for (y = 0; y < h; y++)
+     {
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     val = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3);
+	     *img++ = val;
+	  }
+	img += jmp;
+     }
+}
+
+void
+grender_shaped_24_fast(GdkImlibImage * im, int w, int h, XImage * xim,
+		       XImage * sxim, int *er1, int *er2, int *xarray,
+		       unsigned char **yarray)
+{
+   int                 x, y, r, g, b;
+   unsigned char      *ptr2;
+   unsigned char      *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line) - w;
+   img = (unsigned char *)xim->data;
+   if (id->byte_order == BYTE_ORD_24_RGB)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		    {
+		       XPutPixel(sxim, x, y, 0);
+		       img += 3;
+		    }
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       *img++ = r;
+		       *img++ = g;
+		       *img++ = b;
+		    }
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_RBG)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		    {
+		       XPutPixel(sxim, x, y, 0);
+		       img += 3;
+		    }
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       *img++ = r;
+		       *img++ = b;
+		       *img++ = g;
+		    }
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_BRG)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		    {
+		       XPutPixel(sxim, x, y, 0);
+		       img += 3;
+		    }
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       *img++ = b;
+		       *img++ = r;
+		       *img++ = g;
+		    }
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_BGR)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		    {
+		       XPutPixel(sxim, x, y, 0);
+		       img += 3;
+		    }
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       *img++ = b;
+		       *img++ = g;
+		       *img++ = r;
+		    }
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_GRB)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		    {
+		       XPutPixel(sxim, x, y, 0);
+		       img += 3;
+		    }
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       *img++ = g;
+		       *img++ = r;
+		       *img++ = b;
+		    }
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_GBR)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		    {
+		       XPutPixel(sxim, x, y, 0);
+		       img += 3;
+		    }
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       *img++ = g;
+		       *img++ = b;
+		       *img++ = r;
+		    }
+	       }
+	     img += jmp;
+	  }
+     }
+}
+
+void
+grender_24_fast(GdkImlibImage * im, int w, int h, XImage * xim,
+		XImage * sxim, int *er1, int *er2, int *xarray,
+		unsigned char **yarray)
+{
+   int                 x, y, r, g, b;
+   unsigned char      *ptr2;
+   unsigned char      *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line) - w;
+   img = (unsigned char *)xim->data;
+   if (id->byte_order == BYTE_ORD_24_RGB)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  *img++ = r;
+		  *img++ = g;
+		  *img++ = b;
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_RBG)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  *img++ = r;
+		  *img++ = b;
+		  *img++ = g;
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_BRG)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  *img++ = b;
+		  *img++ = r;
+		  *img++ = g;
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_BGR)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  *img++ = b;
+		  *img++ = g;
+		  *img++ = r;
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_GRB)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  *img++ = g;
+		  *img++ = r;
+		  *img++ = b;
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_GBR)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  *img++ = g;
+		  *img++ = b;
+		  *img++ = r;
+	       }
+	     img += jmp;
+	  }
+     }
+}
+
+void
+grender_shaped_32_fast(GdkImlibImage * im, int w, int h, XImage * xim,
+		       XImage * sxim, int *er1, int *er2, int *xarray,
+		       unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b;
+   unsigned char      *ptr2;
+   unsigned int       *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line >> 2) - w;
+   img = (unsigned int *)xim->data;
+   if (id->byte_order == BYTE_ORD_24_RGB)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		    {
+		       XPutPixel(sxim, x, y, 0);
+		       img++;
+		    }
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       val = (r << 16) | (g << 8) | b;
+		       *img++ = val;
+		    }
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_RBG)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		    {
+		       XPutPixel(sxim, x, y, 0);
+		       img++;
+		    }
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       val = (r << 16) | (b << 8) | g;
+		       *img++ = val;
+		    }
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_BRG)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		    {
+		       XPutPixel(sxim, x, y, 0);
+		       img++;
+		    }
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       val = (b << 16) | (r << 8) | g;
+		       *img++ = val;
+		    }
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_BGR)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		    {
+		       XPutPixel(sxim, x, y, 0);
+		       img++;
+		    }
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       val = (b << 16) | (g << 8) | r;
+		       *img++ = val;
+		    }
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_GRB)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		    {
+		       XPutPixel(sxim, x, y, 0);
+		       img++;
+		    }
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       val = (g << 16) | (r << 8) | b;
+		       *img++ = val;
+		    }
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_GBR)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		    {
+		       XPutPixel(sxim, x, y, 0);
+		       img++;
+		    }
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       val = (g << 16) | (b << 8) | r;
+		       *img++ = val;
+		    }
+	       }
+	     img += jmp;
+	  }
+     }
+}
+
+void
+grender_32_fast(GdkImlibImage * im, int w, int h, XImage * xim,
+		XImage * sxim, int *er1, int *er2, int *xarray,
+		unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b;
+   unsigned char      *ptr2;
+   unsigned int       *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line >> 2) - w;
+   img = (unsigned int *)xim->data;
+   if (id->byte_order == BYTE_ORD_24_RGB)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  val = (r << 16) | (g << 8) | b;
+		  *img++ = val;
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_RBG)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  val = (r << 16) | (b << 8) | g;
+		  *img++ = val;
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_BRG)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  val = (b << 16) | (r << 8) | g;
+		  *img++ = val;
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_BGR)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  val = (b << 16) | (g << 8) | r;
+		  *img++ = val;
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_GRB)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  val = (g << 16) | (r << 8) | b;
+		  *img++ = val;
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_GBR)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  val = (g << 16) | (b << 8) | r;
+		  *img++ = val;
+	       }
+	     img += jmp;
+	  }
+     }
+}
+
+void
+grender_shaped_15(GdkImlibImage * im, int w, int h, XImage * xim,
+		  XImage * sxim, int *er1, int *er2, int *xarray,
+		  unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b;
+   unsigned char      *ptr2;
+
+   for (y = 0; y < h; y++)
+     {
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     if ((r == im->shape_color.r) &&
+		 (g == im->shape_color.g) &&
+		 (b == im->shape_color.b))
+		XPutPixel(sxim, x, y, 0);
+	     else
+	       {
+		  XPutPixel(sxim, x, y, 1);
+		  val = ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
+		  XPutPixel(xim, x, y, val);
+	       }
+	  }
+     }
+}
+
+void
+grender_15(GdkImlibImage * im, int w, int h, XImage * xim,
+	   XImage * sxim, int *er1, int *er2, int *xarray,
+	   unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b;
+   unsigned char      *ptr2;
+
+   for (y = 0; y < h; y++)
+     {
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     val = ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
+	     XPutPixel(xim, x, y, val);
+	  }
+     }
+}
+
+void
+grender_shaped_16(GdkImlibImage * im, int w, int h, XImage * xim,
+		  XImage * sxim, int *er1, int *er2, int *xarray,
+		  unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b;
+   unsigned char      *ptr2;
+
+   for (y = 0; y < h; y++)
+     {
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     if ((r == im->shape_color.r) &&
+		 (g == im->shape_color.g) &&
+		 (b == im->shape_color.b))
+		XPutPixel(sxim, x, y, 0);
+	     else
+	       {
+		  XPutPixel(sxim, x, y, 1);
+		  val = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3);
+		  XPutPixel(xim, x, y, val);
+	       }
+	  }
+     }
+}
+
+void
+grender_16(GdkImlibImage * im, int w, int h, XImage * xim,
+	   XImage * sxim, int *er1, int *er2, int *xarray,
+	   unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b;
+   unsigned char      *ptr2;
+
+   for (y = 0; y < h; y++)
+     {
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     val = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3);
+	     XPutPixel(xim, x, y, val);
+	  }
+     }
+}
+
+void
+grender_shaped_24(GdkImlibImage * im, int w, int h, XImage * xim,
+		  XImage * sxim, int *er1, int *er2, int *xarray,
+		  unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b;
+   unsigned char      *ptr2;
+
+   if (id->byte_order == BYTE_ORD_24_RGB)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		     XPutPixel(sxim, x, y, 0);
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       val = (r << 16) | (g << 8) | b;
+		       XPutPixel(xim, x, y, val);
+		    }
+	       }
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_RBG)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		     XPutPixel(sxim, x, y, 0);
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       val = (r << 16) | (b << 8) | g;
+		       XPutPixel(xim, x, y, val);
+		    }
+	       }
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_BRG)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		     XPutPixel(sxim, x, y, 0);
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       val = (b << 16) | (r << 8) | g;
+		       XPutPixel(xim, x, y, val);
+		    }
+	       }
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_BGR)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		     XPutPixel(sxim, x, y, 0);
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       val = (b << 16) | (g << 8) | r;
+		       XPutPixel(xim, x, y, val);
+		    }
+	       }
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_GRB)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		     XPutPixel(sxim, x, y, 0);
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       val = (g << 16) | (r << 8) | b;
+		       XPutPixel(xim, x, y, val);
+		    }
+	       }
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_GBR)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		     XPutPixel(sxim, x, y, 0);
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       val = (g << 16) | (b << 8) | r;
+		       XPutPixel(xim, x, y, val);
+		    }
+	       }
+	  }
+     }
+}
+
+void
+grender_24(GdkImlibImage * im, int w, int h, XImage * xim,
+	   XImage * sxim, int *er1, int *er2, int *xarray,
+	   unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b;
+   unsigned char      *ptr2;
+
+   if (id->byte_order == BYTE_ORD_24_RGB)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  val = (r << 16) | (g << 8) | b;
+		  XPutPixel(xim, x, y, val);
+	       }
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_RBG)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  val = (r << 16) | (b << 8) | g;
+		  XPutPixel(xim, x, y, val);
+	       }
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_BRG)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  val = (b << 16) | (r << 8) | g;
+		  XPutPixel(xim, x, y, val);
+	       }
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_BGR)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  val = (b << 16) | (g << 8) | r;
+		  XPutPixel(xim, x, y, val);
+	       }
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_GRB)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  val = (g << 16) | (r << 8) | b;
+		  XPutPixel(xim, x, y, val);
+	       }
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_GBR)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  val = (g << 16) | (b << 8) | r;
+		  XPutPixel(xim, x, y, val);
+	       }
+	  }
+     }
+}
+
+void
+grender_shaped(GdkImlibImage * im, int w, int h, XImage * xim,
+	       XImage * sxim, int *er1, int *er2, int *xarray,
+	       unsigned char **yarray, int bpp)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+   unsigned char      *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line) - w;
+   img = (unsigned char *)xim->data;
+   switch (id->render_type)
+     {
+     case RT_PLAIN_PALETTE:
+	if ((id->fastrend) && (xim->bits_per_pixel == 8))
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       if ((r == im->shape_color.r) &&
+			   (g == im->shape_color.g) &&
+			   (b == im->shape_color.b))
+			 {
+			    XPutPixel(sxim, x, y, 0);
+			    img++;
+			 }
+		       else
+			 {
+			    XPutPixel(sxim, x, y, 1);
+			    val = gdk_imlib_best_color_match(&r, &g, &b);
+			    *img++ = val;
+			 }
+		    }
+		  img += jmp;
+	       }
+	  }
+	else
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       if ((r == im->shape_color.r) &&
+			   (g == im->shape_color.g) &&
+			   (b == im->shape_color.b))
+			  XPutPixel(sxim, x, y, 0);
+		       else
+			 {
+			    XPutPixel(sxim, x, y, 1);
+			    val = gdk_imlib_best_color_match(&r, &g, &b);
+			    XPutPixel(xim, x, y, val);
+			 }
+		    }
+	       }
+	  }
+	break;
+     case RT_PLAIN_PALETTE_FAST:
+	if ((id->fastrend) && (xim->bits_per_pixel == 8))
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       if ((r == im->shape_color.r) &&
+			   (g == im->shape_color.g) &&
+			   (b == im->shape_color.b))
+			 {
+			    XPutPixel(sxim, x, y, 0);
+			    img++;
+			 }
+		       else
+			 {
+			    XPutPixel(sxim, x, y, 1);
+			    val = COLOR_RGB(r >> 3, g >> 3, b >> 3);
+			    *img++ = val;
+			 }
+		    }
+		  img += jmp;
+	       }
+	  }
+	else
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       if ((r == im->shape_color.r) &&
+			   (g == im->shape_color.g) &&
+			   (b == im->shape_color.b))
+			  XPutPixel(sxim, x, y, 0);
+		       else
+			 {
+			    XPutPixel(sxim, x, y, 1);
+			    val = COLOR_RGB(r >> 3, g >> 3, b >> 3);
+			    XPutPixel(xim, x, y, val);
+			 }
+		    }
+	       }
+	  }
+	break;
+     case RT_DITHER_PALETTE:
+	if ((id->fastrend) && (xim->bits_per_pixel == 8))
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  ter = er1;
+		  er1 = er2;
+		  er2 = ter;
+		  for (ex = 0; ex < (w + 2) * 3; ex++)
+		     er2[ex] = 0;
+		  ex = 3;
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       if ((r == im->shape_color.r) &&
+			   (g == im->shape_color.g) &&
+			   (b == im->shape_color.b))
+			 {
+			    {
+			       XPutPixel(sxim, x, y, 0);
+			       img++;
+			    }
+			    ex += 3;
+			 }
+		       else
+			 {
+			    XPutPixel(sxim, x, y, 1);
+			    er = r + er1[ex++];
+			    eg = g + er1[ex++];
+			    eb = b + er1[ex++];
+			    if (er > 255)
+			       er = 255;
+			    else if (er < 0)
+			       er = 0;
+			    if (eg > 255)
+			       eg = 255;
+			    else if (eg < 0)
+			       eg = 0;
+			    if (eb > 255)
+			       eb = 255;
+			    else if (eb < 0)
+			       eb = 0;
+			    val = gdk_imlib_best_color_match(&er, &eg, &eb);
+			    DITHER_ERROR(er1, er2, ex, er, eg, eb);
+			    *img++ = val;
+			 }
+		    }
+		  img += jmp;
+	       }
+	  }
+	else
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  ter = er1;
+		  er1 = er2;
+		  er2 = ter;
+		  for (ex = 0; ex < (w + 2) * 3; ex++)
+		     er2[ex] = 0;
+		  ex = 3;
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       if ((r == im->shape_color.r) &&
+			   (g == im->shape_color.g) &&
+			   (b == im->shape_color.b))
+			 {
+			    XPutPixel(sxim, x, y, 0);
+			    ex += 3;
+			 }
+		       else
+			 {
+			    XPutPixel(sxim, x, y, 1);
+			    er = r + er1[ex++];
+			    eg = g + er1[ex++];
+			    eb = b + er1[ex++];
+			    if (er > 255)
+			       er = 255;
+			    else if (er < 0)
+			       er = 0;
+			    if (eg > 255)
+			       eg = 255;
+			    else if (eg < 0)
+			       eg = 0;
+			    if (eb > 255)
+			       eb = 255;
+			    else if (eb < 0)
+			       eb = 0;
+			    val = gdk_imlib_best_color_match(&er, &eg, &eb);
+			    DITHER_ERROR(er1, er2, ex, er, eg, eb);
+			    XPutPixel(xim, x, y, val);
+			 }
+		    }
+	       }
+	  }
+	break;
+     case RT_DITHER_PALETTE_FAST:
+	if ((id->fastrend) && (xim->bits_per_pixel == 8))
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  ter = er1;
+		  er1 = er2;
+		  er2 = ter;
+		  for (ex = 0; ex < (w + 2) * 3; ex++)
+		     er2[ex] = 0;
+		  ex = 3;
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       if ((r == im->shape_color.r) &&
+			   (g == im->shape_color.g) &&
+			   (b == im->shape_color.b))
+			 {
+			    {
+			       XPutPixel(sxim, x, y, 0);
+			       img++;
+			    }
+			    ex += 3;
+			 }
+		       else
+			 {
+			    XPutPixel(sxim, x, y, 1);
+			    er = r + er1[ex++];
+			    eg = g + er1[ex++];
+			    eb = b + er1[ex++];
+			    if (er > 255)
+			       er = 255;
+			    else if (er < 0)
+			       er = 0;
+			    if (eg > 255)
+			       eg = 255;
+			    else if (eg < 0)
+			       eg = 0;
+			    if (eb > 255)
+			       eb = 255;
+			    else if (eb < 0)
+			       eb = 0;
+			    val = INDEX_RGB(er >> 3, eg >> 3, eb >> 3);
+			    er = ERROR_RED(er, val);
+			    eg = ERROR_GRN(eg, val);
+			    eb = ERROR_BLU(eb, val);
+			    DITHER_ERROR(er1, er2, ex, er, eg, eb);
+			    *img++ = COLOR_INDEX(val);
+			 }
+		    }
+		  img += jmp;
+	       }
+	  }
+	else
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  ter = er1;
+		  er1 = er2;
+		  er2 = ter;
+		  for (ex = 0; ex < (w + 2) * 3; ex++)
+		     er2[ex] = 0;
+		  ex = 3;
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       if ((r == im->shape_color.r) &&
+			   (g == im->shape_color.g) &&
+			   (b == im->shape_color.b))
+			 {
+			    XPutPixel(sxim, x, y, 0);
+			    ex += 3;
+			 }
+		       else
+			 {
+			    XPutPixel(sxim, x, y, 1);
+			    er = r + er1[ex++];
+			    eg = g + er1[ex++];
+			    eb = b + er1[ex++];
+			    if (er > 255)
+			       er = 255;
+			    else if (er < 0)
+			       er = 0;
+			    if (eg > 255)
+			       eg = 255;
+			    else if (eg < 0)
+			       eg = 0;
+			    if (eb > 255)
+			       eb = 255;
+			    else if (eb < 0)
+			       eb = 0;
+			    val = INDEX_RGB(er >> 3, eg >> 3, eb >> 3);
+			    er = ERROR_RED(er, val);
+			    eg = ERROR_GRN(eg, val);
+			    eb = ERROR_BLU(eb, val);
+			    DITHER_ERROR(er1, er2, ex, er, eg, eb);
+			    XPutPixel(xim, x, y, COLOR_INDEX(val));
+			 }
+		    }
+	       }
+	  }
+	break;
+     default:
+	if (id->fastrend)
+	  {
+	     switch (bpp)
+	       {
+	       case 8:
+		  break;
+	       case 15:
+		  if (id->render_type == RT_DITHER_TRUECOL)
+		    {
+		       if (id->ordered_dither)
+			  grender_shaped_15_fast_dither_ordered(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		       else
+			  grender_shaped_15_fast_dither(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		    }
+		  else
+		     grender_shaped_15_fast(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       case 16:
+		  if (id->render_type == RT_DITHER_TRUECOL)
+		    {
+		       if (id->ordered_dither)
+			  grender_shaped_16_fast_dither_ordered(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		       else
+			  grender_shaped_16_fast_dither(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		    }
+		  else
+		     grender_shaped_16_fast(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       case 24:
+	       case 32:
+		  if (xim->bits_per_pixel == 24)
+		     grender_shaped_24_fast(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  else
+		     grender_shaped_32_fast(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       default:
+		  break;
+	       }
+	  }
+	else
+	  {
+	     switch (bpp)
+	       {
+	       case 8:
+		  break;
+	       case 15:
+		  if (id->render_type == RT_DITHER_TRUECOL)
+		    {
+		       if (id->ordered_dither)
+			  grender_shaped_15_dither_ordered(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		       else
+			  grender_shaped_15_dither(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		    }
+		  else
+		     grender_shaped_15(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       case 16:
+		  if (id->render_type == RT_DITHER_TRUECOL)
+		    {
+		       if (id->ordered_dither)
+			  grender_shaped_16_dither_ordered(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		       else
+			  grender_shaped_16_dither(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		    }
+		  else
+		     grender_shaped_16(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       case 24:
+		  grender_shaped_24(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+	       case 32:
+		  grender_shaped_24(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       default:
+		  break;
+	       }
+	  }
+	break;
+     }
+}
+
+void
+grender(GdkImlibImage * im, int w, int h, XImage * xim,
+	XImage * sxim, int *er1, int *er2, int *xarray,
+	unsigned char **yarray, int bpp)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+   unsigned char      *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line) - w;
+   img = (unsigned char *)xim->data;
+   switch (id->render_type)
+     {
+     case RT_PLAIN_PALETTE:
+	if ((id->fastrend) && (xim->bits_per_pixel == 8))
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       val = gdk_imlib_best_color_match(&r, &g, &b);
+		       *img++ = val;
+		    }
+		  img += jmp;
+	       }
+	  }
+	else
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       val = gdk_imlib_best_color_match(&r, &g, &b);
+		       XPutPixel(xim, x, y, val);
+		    }
+	       }
+	  }
+	break;
+     case RT_PLAIN_PALETTE_FAST:
+	if ((id->fastrend) && (xim->bits_per_pixel == 8))
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       val = COLOR_RGB(r >> 3, g >> 3, b >> 3);
+		       *img++ = val;
+		    }
+		  img += jmp;
+	       }
+	  }
+	else
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       val = COLOR_RGB(r >> 3, g >> 3, b >> 3);
+		       XPutPixel(xim, x, y, val);
+		    }
+	       }
+	  }
+	break;
+     case RT_DITHER_PALETTE:
+	if ((id->fastrend) && (xim->bits_per_pixel == 8))
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  ter = er1;
+		  er1 = er2;
+		  er2 = ter;
+		  for (ex = 0; ex < (w + 2) * 3; ex++)
+		     er2[ex] = 0;
+		  ex = 3;
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       er = r + er1[ex++];
+		       eg = g + er1[ex++];
+		       eb = b + er1[ex++];
+		       if (er > 255)
+			  er = 255;
+		       else if (er < 0)
+			  er = 0;
+		       if (eg > 255)
+			  eg = 255;
+		       else if (eg < 0)
+			  eg = 0;
+		       if (eb > 255)
+			  eb = 255;
+		       else if (eb < 0)
+			  eb = 0;
+		       val = gdk_imlib_best_color_match(&er, &eg, &eb);
+		       DITHER_ERROR(er1, er2, ex, er, eg, eb);
+		       *img++ = val;
+		    }
+		  img += jmp;
+	       }
+	  }
+	else
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  ter = er1;
+		  er1 = er2;
+		  er2 = ter;
+		  for (ex = 0; ex < (w + 2) * 3; ex++)
+		     er2[ex] = 0;
+		  ex = 3;
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       er = r + er1[ex++];
+		       eg = g + er1[ex++];
+		       eb = b + er1[ex++];
+		       if (er > 255)
+			  er = 255;
+		       else if (er < 0)
+			  er = 0;
+		       if (eg > 255)
+			  eg = 255;
+		       else if (eg < 0)
+			  eg = 0;
+		       if (eb > 255)
+			  eb = 255;
+		       else if (eb < 0)
+			  eb = 0;
+		       val = gdk_imlib_best_color_match(&er, &eg, &eb);
+		       DITHER_ERROR(er1, er2, ex, er, eg, eb);
+		       XPutPixel(xim, x, y, val);
+		    }
+	       }
+	  }
+	break;
+     case RT_DITHER_PALETTE_FAST:
+	if ((id->fastrend) && (xim->bits_per_pixel == 8))
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  ter = er1;
+		  er1 = er2;
+		  er2 = ter;
+		  for (ex = 0; ex < (w + 2) * 3; ex++)
+		     er2[ex] = 0;
+		  ex = 3;
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       er = r + er1[ex++];
+		       eg = g + er1[ex++];
+		       eb = b + er1[ex++];
+		       if (er > 255)
+			  er = 255;
+		       else if (er < 0)
+			  er = 0;
+		       if (eg > 255)
+			  eg = 255;
+		       else if (eg < 0)
+			  eg = 0;
+		       if (eb > 255)
+			  eb = 255;
+		       else if (eb < 0)
+			  eb = 0;
+		       val = INDEX_RGB(er >> 3, eg >> 3, eb >> 3);
+		       er = ERROR_RED(er, val);
+		       eg = ERROR_GRN(eg, val);
+		       eb = ERROR_BLU(eb, val);
+		       DITHER_ERROR(er1, er2, ex, er, eg, eb);
+		       *img++ = COLOR_INDEX(val);
+		    }
+		  img += jmp;
+	       }
+	  }
+	else
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  ter = er1;
+		  er1 = er2;
+		  er2 = ter;
+		  for (ex = 0; ex < (w + 2) * 3; ex++)
+		     er2[ex] = 0;
+		  ex = 3;
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       er = r + er1[ex++];
+		       eg = g + er1[ex++];
+		       eb = b + er1[ex++];
+		       if (er > 255)
+			  er = 255;
+		       else if (er < 0)
+			  er = 0;
+		       if (eg > 255)
+			  eg = 255;
+		       else if (eg < 0)
+			  eg = 0;
+		       if (eb > 255)
+			  eb = 255;
+		       else if (eb < 0)
+			  eb = 0;
+		       val = INDEX_RGB(er >> 3, eg >> 3, eb >> 3);
+		       er = ERROR_RED(er, val);
+		       eg = ERROR_GRN(eg, val);
+		       eb = ERROR_BLU(eb, val);
+		       DITHER_ERROR(er1, er2, ex, er, eg, eb);
+		       XPutPixel(xim, x, y, COLOR_INDEX(val));
+		    }
+	       }
+	  }
+	break;
+     default:
+	if (id->fastrend)
+	  {
+	     switch (bpp)
+	       {
+	       case 8:
+		  break;
+	       case 15:
+		  if (id->render_type == RT_DITHER_TRUECOL)
+		    {
+		       if (id->ordered_dither)
+			  grender_15_fast_dither_ordered(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		       else
+			  grender_15_fast_dither(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		    }
+		  else
+		     grender_15_fast(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       case 16:
+		  if (id->render_type == RT_DITHER_TRUECOL)
+		    {
+		       if (id->ordered_dither)
+			  grender_16_fast_dither_ordered(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		       else
+			  grender_16_fast_dither(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		    }
+		  else
+		     grender_16_fast(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       case 24:
+	       case 32:
+		  if (xim->bits_per_pixel == 24)
+		     grender_24_fast(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  else
+		     grender_32_fast(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       default:
+		  break;
+	       }
+	  }
+	else
+	  {
+	     switch (bpp)
+	       {
+	       case 8:
+		  break;
+	       case 15:
+		  if (id->render_type == RT_DITHER_TRUECOL)
+		    {
+		       if (id->ordered_dither)
+			  grender_15_dither_ordered(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		       else
+			  grender_15_dither(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		    }
+		  else
+		     grender_15(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       case 16:
+		  if (id->render_type == RT_DITHER_TRUECOL)
+		    {
+		       if (id->ordered_dither)
+			  grender_16_dither_ordered(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		       else
+			  grender_16_dither(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		    }
+		  else
+		     grender_16(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       case 24:
+		  grender_24(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       case 32:
+		  grender_24(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       default:
+		  break;
+	       }
+	     break;
+	  }
+     }
+}
+
+void
+grender_shaped_15_fast_dither_mod(GdkImlibImage * im, int w, int h, XImage * xim,
+			       XImage * sxim, int *er1, int *er2, int *xarray,
+				  unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+   unsigned short     *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line >> 1) - w;
+   img = (unsigned short *)xim->data;
+   for (y = 0; y < h; y++)
+     {
+	ter = er1;
+	er1 = er2;
+	er2 = ter;
+	for (ex = 0; ex < (w + 2) * 3; ex++)
+	   er2[ex] = 0;
+	ex = 3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     if ((r == im->shape_color.r) &&
+		 (g == im->shape_color.g) &&
+		 (b == im->shape_color.b))
+	       {
+		  XPutPixel(sxim, x, y, 0);
+		  img++;
+		  ex += 3;
+	       }
+	     else
+	       {
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  XPutPixel(sxim, x, y, 1);
+		  er = r + er1[ex++];
+		  eg = g + er1[ex++];
+		  eb = b + er1[ex++];
+		  if (er > 255)
+		     er = 255;
+		  if (eg > 255)
+		     eg = 255;
+		  if (eb > 255)
+		     eb = 255;
+		  val = ((er & 0xf8) << 7) | ((eg & 0xf8) << 2) | ((eb & 0xf8) >> 3);
+		  er = er & 0x07;
+		  eg = eg & 0x07;
+		  eb = eb & 0x07;
+		  DITHER_ERROR(er1, er2, ex, er, eg, eb);
+		  *img++ = val;
+	       }
+	  }
+	img += jmp;
+     }
+}
+
+void 
+grender_shaped_15_fast_dither_mod_ordered(GdkImlibImage * im, int w, int h, XImage * xim,
+			       XImage * sxim, int *er1, int *er2, int *xarray,
+					  unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+   unsigned short     *img;
+   int                 jmp;
+
+   unsigned char       dither[4][4] =
+   {
+      {0, 4, 6, 5},
+      {6, 2, 7, 3},
+      {2, 6, 1, 5},
+      {7, 4, 7, 3}
+   };
+   int                 dithy, dithx;
+
+   jmp = (xim->bytes_per_line >> 1) - w;
+   img = (unsigned short *)xim->data;
+   for (y = 0; y < h; y++)
+     {
+	dithy = y & 0x3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     if ((r == im->shape_color.r) &&
+		 (g == im->shape_color.g) &&
+		 (b == im->shape_color.b))
+	       {
+		  XPutPixel(sxim, x, y, 0);
+		  img++;
+	       }
+	     else
+	       {
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  XPutPixel(sxim, x, y, 1);
+		  er = r & 0x07;
+		  eg = g & 0x07;
+		  eb = b & 0x07;
+		  dithx = x & 0x3;
+		  if ((dither[dithy][dithx] < er) && (r < (256 - 8)))
+		     r += 8;
+		  if ((dither[dithy][dithx] < eg) && (g < (256 - 8)))
+		     g += 8;
+		  if ((dither[dithy][dithx] < eb) && (b < (256 - 8)))
+		     b += 8;
+		  val = ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
+		  *img++ = val;
+	       }
+	  }
+	img += jmp;
+     }
+}
+
+void
+grender_15_fast_dither_mod(GdkImlibImage * im, int w, int h, XImage * xim,
+			   XImage * sxim, int *er1, int *er2, int *xarray,
+			   unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+   unsigned short     *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line >> 1) - w;
+   img = (unsigned short *)xim->data;
+   for (y = 0; y < h; y++)
+     {
+	ter = er1;
+	er1 = er2;
+	er2 = ter;
+	for (ex = 0; ex < (w + 2) * 3; ex++)
+	   er2[ex] = 0;
+	ex = 3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     r = im->rmap[r];
+	     g = im->gmap[g];
+	     b = im->bmap[b];
+	     er = r + er1[ex++];
+	     eg = g + er1[ex++];
+	     eb = b + er1[ex++];
+	     if (er > 255)
+		er = 255;
+	     if (eg > 255)
+		eg = 255;
+	     if (eb > 255)
+		eb = 255;
+	     val = ((er & 0xf8) << 7) | ((eg & 0xf8) << 2) | ((eb & 0xf8) >> 3);
+	     er = er & 0x07;
+	     eg = eg & 0x07;
+	     eb = eb & 0x07;
+	     DITHER_ERROR(er1, er2, ex, er, eg, eb);
+	     *img++ = val;
+	  }
+	img += jmp;
+     }
+}
+
+void 
+grender_15_fast_dither_mod_ordered(GdkImlibImage * im, int w, int h, XImage * xim,
+			       XImage * sxim, int *er1, int *er2, int *xarray,
+				   unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+
+   unsigned short     *img;
+   int                 jmp;
+
+   unsigned char       dither[4][4] =
+   {
+      {0, 4, 6, 5},
+      {6, 2, 7, 3},
+      {2, 6, 1, 5},
+      {7, 4, 7, 3}
+   };
+   int                 dithy, dithx;
+
+   jmp = (xim->bytes_per_line >> 1) - w;
+   img = (unsigned short *)xim->data;
+   for (y = 0; y < h; y++)
+     {
+	dithy = y & 0x3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     r = im->rmap[r];
+	     g = im->gmap[g];
+	     b = im->bmap[b];
+	     er = r & 0x07;
+	     eg = g & 0x07;
+	     eb = b & 0x07;
+	     dithx = x & 0x3;
+	     if ((dither[dithy][dithx] < er) && (r < (256 - 8)))
+		r += 8;
+	     if ((dither[dithy][dithx] < eg) && (g < (256 - 8)))
+		g += 8;
+	     if ((dither[dithy][dithx] < eb) && (b < (256 - 8)))
+		b += 8;
+	     val = ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
+	     *img++ = val;
+	  }
+	img += jmp;
+     }
+}
+
+void
+grender_shaped_16_fast_dither_mod(GdkImlibImage * im, int w, int h, XImage * xim,
+			       XImage * sxim, int *er1, int *er2, int *xarray,
+				  unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+   unsigned short     *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line >> 1) - w;
+   img = (unsigned short *)xim->data;
+   for (y = 0; y < h; y++)
+     {
+	ter = er1;
+	er1 = er2;
+	er2 = ter;
+	for (ex = 0; ex < (w + 2) * 3; ex++)
+	   er2[ex] = 0;
+	ex = 3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     if ((r == im->shape_color.r) &&
+		 (g == im->shape_color.g) &&
+		 (b == im->shape_color.b))
+	       {
+		  XPutPixel(sxim, x, y, 0);
+		  img++;
+		  ex += 3;
+	       }
+	     else
+	       {
+		  XPutPixel(sxim, x, y, 1);
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  er = r + er1[ex++];
+		  eg = g + er1[ex++];
+		  eb = b + er1[ex++];
+		  if (er > 255)
+		     er = 255;
+		  if (eg > 255)
+		     eg = 255;
+		  if (eb > 255)
+		     eb = 255;
+		  val = ((er & 0xf8) << 8) | ((eg & 0xfc) << 3) | ((eb & 0xf8) >> 3);
+		  er = er & 0x07;
+		  eg = eg & 0x03;
+		  eb = eb & 0x07;
+		  DITHER_ERROR(er1, er2, ex, er, eg, eb);
+		  *img++ = val;
+	       }
+	  }
+	img += jmp;
+     }
+}
+
+void 
+grender_shaped_16_fast_dither_mod_ordered(GdkImlibImage * im, int w, int h, XImage * xim,
+			       XImage * sxim, int *er1, int *er2, int *xarray,
+					  unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+   unsigned short     *img;
+   int                 jmp;
+
+   unsigned char       dither[4][4] =
+   {
+      {0, 4, 6, 5},
+      {6, 2, 7, 3},
+      {2, 6, 1, 5},
+      {7, 4, 7, 3}
+   };
+   int                 dithy, dithx;
+
+   jmp = (xim->bytes_per_line >> 1) - w;
+   img = (unsigned short *)xim->data;
+   for (y = 0; y < h; y++)
+     {
+	dithy = y & 0x3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     if ((r == im->shape_color.r) &&
+		 (g == im->shape_color.g) &&
+		 (b == im->shape_color.b))
+	       {
+		  XPutPixel(sxim, x, y, 0);
+		  img++;
+	       }
+	     else
+	       {
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  XPutPixel(sxim, x, y, 1);
+		  er = r & 0x07;
+		  eg = g & 0x03;
+		  eb = b & 0x07;
+		  dithx = x & 0x3;
+		  if ((dither[dithy][dithx] < er) && (r < (256 - 8)))
+		     r += 8;
+		  if ((dither[dithy][dithx] < (eg << 1)) && (g < (256 - 4)))
+		     g += 4;
+		  if ((dither[dithy][dithx] < eb) && (b < (256 - 8)))
+		     b += 8;
+		  val = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3);
+		  *img++ = val;
+	       }
+	  }
+	img += jmp;
+     }
+}
+
+void
+grender_16_fast_dither_mod(GdkImlibImage * im, int w, int h, XImage * xim,
+			   XImage * sxim, int *er1, int *er2, int *xarray,
+			   unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+
+   unsigned short     *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line >> 1) - w;
+   img = (unsigned short *)xim->data;
+   for (y = 0; y < h; y++)
+     {
+	ter = er1;
+	er1 = er2;
+	er2 = ter;
+	for (ex = 0; ex < (w + 2) * 3; ex++)
+	   er2[ex] = 0;
+	ex = 3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     r = im->rmap[r];
+	     g = im->gmap[g];
+	     b = im->bmap[b];
+	     er = r + er1[ex++];
+	     eg = g + er1[ex++];
+	     eb = b + er1[ex++];
+	     if (er > 255)
+		er = 255;
+	     if (eg > 255)
+		eg = 255;
+	     if (eb > 255)
+		eb = 255;
+	     val = ((er & 0xf8) << 8) | ((eg & 0xfc) << 3) | ((eb & 0xf8) >> 3);
+	     er = er & 0x07;
+	     eg = eg & 0x03;
+	     eb = eb & 0x07;
+	     DITHER_ERROR(er1, er2, ex, er, eg, eb);
+	     *img++ = val;
+	  }
+	img += jmp;
+     }
+}
+
+void 
+grender_16_fast_dither_mod_ordered(GdkImlibImage * im, int w, int h, XImage * xim,
+			       XImage * sxim, int *er1, int *er2, int *xarray,
+				   unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+
+   unsigned short     *img;
+   int                 jmp;
+
+   unsigned char       dither[4][4] =
+   {
+      {0, 4, 6, 5},
+      {6, 2, 7, 3},
+      {2, 6, 1, 5},
+      {7, 4, 7, 3}
+   };
+   int                 dithy, dithx;
+
+   jmp = (xim->bytes_per_line >> 1) - w;
+   img = (unsigned short *)xim->data;
+   for (y = 0; y < h; y++)
+     {
+	dithy = y & 0x3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     r = im->rmap[r];
+	     g = im->gmap[g];
+	     b = im->bmap[b];
+	     er = r & 0x07;
+	     eg = g & 0x03;
+	     eb = b & 0x07;
+	     dithx = x & 0x3;
+	     if ((dither[dithy][dithx] < er) && (r < (256 - 8)))
+		r += 8;
+	     if ((dither[dithy][dithx] < (eg << 1)) && (g < (256 - 4)))
+		g += 4;
+	     if ((dither[dithy][dithx] < eb) && (b < (256 - 8)))
+		b += 8;
+	     val = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3);
+	     *img++ = val;
+	  }
+	img += jmp;
+     }
+}
+
+void 
+grender_shaped_15_dither_mod_ordered(GdkImlibImage * im, int w, int h, XImage * xim,
+			       XImage * sxim, int *er1, int *er2, int *xarray,
+				     unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+
+   unsigned char       dither[4][4] =
+   {
+      {0, 4, 6, 5},
+      {6, 2, 7, 3},
+      {2, 6, 1, 5},
+      {7, 4, 7, 3}
+   };
+   int                 dithy, dithx;
+
+   for (y = 0; y < h; y++)
+     {
+	dithy = y & 0x3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     if ((r == im->shape_color.r) &&
+		 (g == im->shape_color.g) &&
+		 (b == im->shape_color.b))
+	       {
+		  XPutPixel(sxim, x, y, 0);
+	       }
+	     else
+	       {
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  XPutPixel(sxim, x, y, 1);
+		  er = r & 0x07;
+		  eg = g & 0x07;
+		  eb = b & 0x07;
+		  dithx = x & 0x3;
+		  if ((dither[dithy][dithx] < er) && (r < (256 - 8)))
+		     r += 8;
+		  if ((dither[dithy][dithx] < eg) && (g < (256 - 8)))
+		     g += 8;
+		  if ((dither[dithy][dithx] < eb) && (b < (256 - 8)))
+		     b += 8;
+		  val = ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
+		  XPutPixel(xim, x, y, val);
+	       }
+	  }
+     }
+}
+
+void 
+grender_15_dither_mod_ordered(GdkImlibImage * im, int w, int h, XImage * xim,
+			      XImage * sxim, int *er1, int *er2, int *xarray,
+			      unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+
+   unsigned char       dither[4][4] =
+   {
+      {0, 4, 6, 5},
+      {6, 2, 7, 3},
+      {2, 6, 1, 5},
+      {7, 4, 7, 3}
+   };
+   int                 dithy, dithx;
+
+   for (y = 0; y < h; y++)
+     {
+	dithy = y & 0x3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     r = im->rmap[r];
+	     g = im->gmap[g];
+	     b = im->bmap[b];
+	     er = r & 0x07;
+	     eg = g & 0x07;
+	     eb = b & 0x07;
+	     dithx = x & 0x3;
+	     if ((dither[dithy][dithx] < er) && (r < (256 - 8)))
+		r += 8;
+	     if ((dither[dithy][dithx] < eg) && (g < (256 - 8)))
+		g += 8;
+	     if ((dither[dithy][dithx] < eb) && (b < (256 - 8)))
+		b += 8;
+	     val = ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
+	     XPutPixel(xim, x, y, val);
+	  }
+     }
+}
+
+void 
+grender_shaped_16_dither_mod_ordered(GdkImlibImage * im, int w, int h, XImage * xim,
+			       XImage * sxim, int *er1, int *er2, int *xarray,
+				     unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+
+   unsigned char       dither[4][4] =
+   {
+      {0, 4, 6, 5},
+      {6, 2, 7, 3},
+      {2, 6, 1, 5},
+      {7, 4, 7, 3}
+   };
+   int                 dithy, dithx;
+
+   for (y = 0; y < h; y++)
+     {
+	dithy = y & 0x3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     if ((r == im->shape_color.r) &&
+		 (g == im->shape_color.g) &&
+		 (b == im->shape_color.b))
+	       {
+		  XPutPixel(sxim, x, y, 0);
+	       }
+	     else
+	       {
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  XPutPixel(sxim, x, y, 1);
+		  er = r & 0x07;
+		  eg = g & 0x03;
+		  eb = b & 0x07;
+		  dithx = x & 0x3;
+		  if ((dither[dithy][dithx] < er) && (r < (256 - 8)))
+		     r += 8;
+		  if ((dither[dithy][dithx] < (eg << 1)) && (g < (256 - 4)))
+		     g += 4;
+		  if ((dither[dithy][dithx] < eb) && (b < (256 - 8)))
+		     b += 8;
+		  val = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3);
+		  XPutPixel(xim, x, y, val);
+	       }
+	  }
+     }
+}
+
+void 
+grender_16_dither_mod_ordered(GdkImlibImage * im, int w, int h, XImage * xim,
+			      XImage * sxim, int *er1, int *er2, int *xarray,
+			      unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+
+   unsigned char       dither[4][4] =
+   {
+      {0, 4, 6, 5},
+      {6, 2, 7, 3},
+      {2, 6, 1, 5},
+      {7, 4, 7, 3}
+   };
+   int                 dithy, dithx;
+
+   for (y = 0; y < h; y++)
+     {
+	dithy = y & 0x3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     r = im->rmap[r];
+	     g = im->gmap[g];
+	     b = im->bmap[b];
+	     er = r & 0x07;
+	     eg = g & 0x03;
+	     eb = b & 0x07;
+	     dithx = x & 0x3;
+	     if ((dither[dithy][dithx] < er) && (r < (256 - 8)))
+		r += 8;
+	     if ((dither[dithy][dithx] < (eg << 1)) && (g < (256 - 4)))
+		g += 4;
+	     if ((dither[dithy][dithx] < eb) && (b < (256 - 8)))
+		b += 8;
+	     val = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3);
+	     XPutPixel(xim, x, y, val);
+	  }
+     }
+}
+
+void
+grender_shaped_15_dither_mod(GdkImlibImage * im, int w, int h, XImage * xim,
+			     XImage * sxim, int *er1, int *er2, int *xarray,
+			     unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+
+   for (y = 0; y < h; y++)
+     {
+	ter = er1;
+	er1 = er2;
+	er2 = ter;
+	for (ex = 0; ex < (w + 2) * 3; ex++)
+	   er2[ex] = 0;
+	ex = 3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     if ((r == im->shape_color.r) &&
+		 (g == im->shape_color.g) &&
+		 (b == im->shape_color.b))
+	       {
+		  XPutPixel(sxim, x, y, 0);
+		  ex += 3;
+	       }
+	     else
+	       {
+		  XPutPixel(sxim, x, y, 1);
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  er = r + er1[ex++];
+		  eg = g + er1[ex++];
+		  eb = b + er1[ex++];
+		  if (er > 255)
+		     er = 255;
+		  if (eg > 255)
+		     eg = 255;
+		  if (eb > 255)
+		     eb = 255;
+		  val = ((er & 0xf8) << 7) | ((eg & 0xf8) << 2) | ((eb & 0xf8) >> 3);
+		  er = er & 0x07;
+		  eg = eg & 0x07;
+		  eb = eb & 0x07;
+		  if (er > 255)
+		     er = 255;
+		  else if (er < 0)
+		     er = 0;
+		  if (eg > 255)
+		     eg = 255;
+		  else if (eg < 0)
+		     eg = 0;
+		  if (eb > 255)
+		     eb = 255;
+		  else if (eb < 0)
+		     eb = 0;
+		  val = ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
+		  er = r & 0x07;
+		  eg = g & 0x07;
+		  eb = b & 0x07;
+		  DITHER_ERROR(er1, er2, ex, er, eg, eb);
+		  XPutPixel(xim, x, y, val);
+	       }
+	  }
+     }
+}
+
+void
+grender_15_dither_mod(GdkImlibImage * im, int w, int h, XImage * xim,
+		      XImage * sxim, int *er1, int *er2, int *xarray,
+		      unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+
+   for (y = 0; y < h; y++)
+     {
+	ter = er1;
+	er1 = er2;
+	er2 = ter;
+	for (ex = 0; ex < (w + 2) * 3; ex++)
+	   er2[ex] = 0;
+	ex = 3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     r = im->rmap[r];
+	     g = im->gmap[g];
+	     b = im->bmap[b];
+	     er = r + er1[ex++];
+	     eg = g + er1[ex++];
+	     eb = b + er1[ex++];
+	     if (er > 255)
+		er = 255;
+	     if (eg > 255)
+		eg = 255;
+	     if (eb > 255)
+		eb = 255;
+	     val = ((er & 0xf8) << 7) | ((eg & 0xf8) << 2) | ((eb & 0xf8) >> 3);
+	     er = er & 0x07;
+	     eg = eg & 0x07;
+	     eb = eb & 0x07;
+	     DITHER_ERROR(er1, er2, ex, er, eg, eb);
+	     XPutPixel(xim, x, y, val);
+	  }
+     }
+}
+
+void
+grender_shaped_16_dither_mod(GdkImlibImage * im, int w, int h, XImage * xim,
+			     XImage * sxim, int *er1, int *er2, int *xarray,
+			     unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+
+   for (y = 0; y < h; y++)
+     {
+	ter = er1;
+	er1 = er2;
+	er2 = ter;
+	for (ex = 0; ex < (w + 2) * 3; ex++)
+	   er2[ex] = 0;
+	ex = 3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     if ((r == im->shape_color.r) &&
+		 (g == im->shape_color.g) &&
+		 (b == im->shape_color.b))
+	       {
+		  XPutPixel(sxim, x, y, 0);
+		  ex += 3;
+	       }
+	     else
+	       {
+		  XPutPixel(sxim, x, y, 1);
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  er = r + er1[ex++];
+		  eg = g + er1[ex++];
+		  eb = b + er1[ex++];
+		  if (er > 255)
+		     er = 255;
+		  if (eg > 255)
+		     eg = 255;
+		  if (eb > 255)
+		     eb = 255;
+		  val = ((er & 0xf8) << 8) | ((eg & 0xfc) << 3) | ((eb & 0xf8) >> 3);
+		  er = er & 0x07;
+		  eg = eg & 0x03;
+		  eb = eb & 0x07;
+		  DITHER_ERROR(er1, er2, ex, er, eg, eb);
+		  XPutPixel(xim, x, y, val);
+	       }
+	  }
+     }
+}
+
+void
+grender_16_dither_mod(GdkImlibImage * im, int w, int h, XImage * xim,
+		      XImage * sxim, int *er1, int *er2, int *xarray,
+		      unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+
+   for (y = 0; y < h; y++)
+     {
+	ter = er1;
+	er1 = er2;
+	er2 = ter;
+	for (ex = 0; ex < (w + 2) * 3; ex++)
+	   er2[ex] = 0;
+	ex = 3;
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     r = im->rmap[r];
+	     g = im->gmap[g];
+	     b = im->bmap[b];
+	     er = r + er1[ex++];
+	     eg = g + er1[ex++];
+	     eb = b + er1[ex++];
+	     if (er > 255)
+		er = 255;
+	     if (eg > 255)
+		eg = 255;
+	     if (eb > 255)
+		eb = 255;
+	     val = ((er & 0xf8) << 8) | ((eg & 0xfc) << 3) | ((eb & 0xf8) >> 3);
+	     er = er & 0x07;
+	     eg = eg & 0x03;
+	     eb = eb & 0x07;
+	     DITHER_ERROR(er1, er2, ex, er, eg, eb);
+	     XPutPixel(xim, x, y, val);
+	  }
+     }
+}
+
+void
+grender_shaped_15_fast_mod(GdkImlibImage * im, int w, int h, XImage * xim,
+			   XImage * sxim, int *er1, int *er2, int *xarray,
+			   unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b;
+   unsigned char      *ptr2;
+   unsigned short     *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line >> 1) - w;
+   img = (unsigned short *)xim->data;
+   for (y = 0; y < h; y++)
+     {
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     if ((r == im->shape_color.r) &&
+		 (g == im->shape_color.g) &&
+		 (b == im->shape_color.b))
+	       {
+		  XPutPixel(sxim, x, y, 0);
+		  img++;
+	       }
+	     else
+	       {
+		  XPutPixel(sxim, x, y, 1);
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  val = ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
+		  *img++ = val;
+	       }
+	  }
+	img += jmp;
+     }
+}
+
+void
+grender_15_fast_mod(GdkImlibImage * im, int w, int h, XImage * xim,
+		    XImage * sxim, int *er1, int *er2, int *xarray,
+		    unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b;
+   unsigned char      *ptr2;
+   unsigned short     *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line >> 1) - w;
+   img = (unsigned short *)xim->data;
+   for (y = 0; y < h; y++)
+     {
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     r = im->rmap[r];
+	     g = im->gmap[g];
+	     b = im->bmap[b];
+	     val = ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
+	     *img++ = val;
+	  }
+	img += jmp;
+     }
+}
+
+void
+grender_shaped_16_fast_mod(GdkImlibImage * im, int w, int h, XImage * xim,
+			   XImage * sxim, int *er1, int *er2, int *xarray,
+			   unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b;
+   unsigned char      *ptr2;
+   unsigned short     *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line >> 1) - w;
+   img = (unsigned short *)xim->data;
+   for (y = 0; y < h; y++)
+     {
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     if ((r == im->shape_color.r) &&
+		 (g == im->shape_color.g) &&
+		 (b == im->shape_color.b))
+	       {
+		  XPutPixel(sxim, x, y, 0);
+		  img++;
+	       }
+	     else
+	       {
+		  XPutPixel(sxim, x, y, 1);
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  val = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3);
+		  *img++ = val;
+	       }
+	  }
+	img += jmp;
+     }
+}
+
+void
+grender_16_fast_mod(GdkImlibImage * im, int w, int h, XImage * xim,
+		    XImage * sxim, int *er1, int *er2, int *xarray,
+		    unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b;
+   unsigned char      *ptr2;
+
+   unsigned short     *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line >> 1) - w;
+   img = (unsigned short *)xim->data;
+   for (y = 0; y < h; y++)
+     {
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     r = im->rmap[r];
+	     g = im->gmap[g];
+	     b = im->bmap[b];
+	     val = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3);
+	     *img++ = val;
+	  }
+	img += jmp;
+     }
+}
+
+void
+grender_shaped_24_fast_mod(GdkImlibImage * im, int w, int h, XImage * xim,
+			   XImage * sxim, int *er1, int *er2, int *xarray,
+			   unsigned char **yarray)
+{
+   int                 x, y, r, g, b;
+   unsigned char      *ptr2;
+   unsigned char      *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line) - w;
+   img = (unsigned char *)xim->data;
+   if (id->byte_order == BYTE_ORD_24_RGB)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		    {
+		       XPutPixel(sxim, x, y, 0);
+		       img += 3;
+		    }
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		       *img++ = r;
+		       *img++ = g;
+		       *img++ = b;
+		    }
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_RBG)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		    {
+		       XPutPixel(sxim, x, y, 0);
+		       img += 3;
+		    }
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		       *img++ = r;
+		       *img++ = b;
+		       *img++ = g;
+		    }
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_BRG)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		    {
+		       XPutPixel(sxim, x, y, 0);
+		       img += 3;
+		    }
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		       *img++ = b;
+		       *img++ = r;
+		       *img++ = g;
+		    }
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_BGR)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		    {
+		       XPutPixel(sxim, x, y, 0);
+		       img += 3;
+		    }
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		       *img++ = b;
+		       *img++ = g;
+		       *img++ = r;
+		    }
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_GRB)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		    {
+		       XPutPixel(sxim, x, y, 0);
+		       img += 3;
+		    }
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       *img++ = g;
+		       *img++ = r;
+		       *img++ = b;
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		    }
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_GBR)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		    {
+		       XPutPixel(sxim, x, y, 0);
+		       img += 3;
+		    }
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       *img++ = g;
+		       *img++ = b;
+		       *img++ = r;
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		    }
+	       }
+	     img += jmp;
+	  }
+     }
+}
+
+void
+grender_24_fast_mod(GdkImlibImage * im, int w, int h, XImage * xim,
+		    XImage * sxim, int *er1, int *er2, int *xarray,
+		    unsigned char **yarray)
+{
+   int                 x, y, r, g, b;
+   unsigned char      *ptr2;
+   unsigned char      *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line) - w;
+   img = (unsigned char *)xim->data;
+   if (id->byte_order == BYTE_ORD_24_RGB)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  *img++ = r;
+		  *img++ = g;
+		  *img++ = b;
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_RBG)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  *img++ = r;
+		  *img++ = b;
+		  *img++ = g;
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_BRG)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  *img++ = b;
+		  *img++ = r;
+		  *img++ = g;
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_BGR)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  *img++ = b;
+		  *img++ = g;
+		  *img++ = r;
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_GRB)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  *img++ = g;
+		  *img++ = r;
+		  *img++ = b;
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_GBR)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  *img++ = g;
+		  *img++ = b;
+		  *img++ = r;
+	       }
+	     img += jmp;
+	  }
+     }
+}
+
+void
+grender_shaped_32_fast_mod(GdkImlibImage * im, int w, int h, XImage * xim,
+			   XImage * sxim, int *er1, int *er2, int *xarray,
+			   unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b;
+   unsigned char      *ptr2;
+   unsigned int       *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line >> 2) - w;
+   img = (unsigned int *)xim->data;
+   if (id->byte_order == BYTE_ORD_24_RGB)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		    {
+		       XPutPixel(sxim, x, y, 0);
+		       img++;
+		    }
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		       val = (r << 16) | (g << 8) | b;
+		       *img++ = val;
+		    }
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_RBG)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		    {
+		       XPutPixel(sxim, x, y, 0);
+		       img++;
+		    }
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		       val = (r << 16) | (b << 8) | g;
+		       *img++ = val;
+		    }
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_BRG)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		    {
+		       XPutPixel(sxim, x, y, 0);
+		       img++;
+		    }
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		       val = (b << 16) | (r << 8) | g;
+		       *img++ = val;
+		    }
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_BGR)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		    {
+		       XPutPixel(sxim, x, y, 0);
+		       img++;
+		    }
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		       val = (b << 16) | (g << 8) | r;
+		       *img++ = val;
+		    }
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_GRB)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		    {
+		       XPutPixel(sxim, x, y, 0);
+		       img++;
+		    }
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		       val = (g << 16) | (r << 8) | b;
+		       *img++ = val;
+		    }
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_GBR)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		    {
+		       XPutPixel(sxim, x, y, 0);
+		       img++;
+		    }
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		       val = (g << 16) | (b << 8) | r;
+		       *img++ = val;
+		    }
+	       }
+	     img += jmp;
+	  }
+     }
+}
+
+void
+grender_32_fast_mod(GdkImlibImage * im, int w, int h, XImage * xim,
+		    XImage * sxim, int *er1, int *er2, int *xarray,
+		    unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b;
+   unsigned char      *ptr2;
+   unsigned int       *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line >> 2) - w;
+   img = (unsigned int *)xim->data;
+   if (id->byte_order == BYTE_ORD_24_RGB)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  val = (r << 16) | (g << 8) | b;
+		  *img++ = val;
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_RBG)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  val = (r << 16) | (b << 8) | g;
+		  *img++ = val;
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_BRG)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  val = (b << 16) | (r << 8) | g;
+		  *img++ = val;
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_BGR)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  val = (b << 16) | (g << 8) | r;
+		  *img++ = val;
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_GRB)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  val = (g << 16) | (r << 8) | b;
+		  *img++ = val;
+	       }
+	     img += jmp;
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_GBR)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  val = (g << 16) | (b << 8) | r;
+		  *img++ = val;
+	       }
+	     img += jmp;
+	  }
+     }
+}
+
+void
+grender_shaped_15_mod(GdkImlibImage * im, int w, int h, XImage * xim,
+		      XImage * sxim, int *er1, int *er2, int *xarray,
+		      unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b;
+   unsigned char      *ptr2;
+
+   for (y = 0; y < h; y++)
+     {
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     if ((r == im->shape_color.r) &&
+		 (g == im->shape_color.g) &&
+		 (b == im->shape_color.b))
+		XPutPixel(sxim, x, y, 0);
+	     else
+	       {
+		  XPutPixel(sxim, x, y, 1);
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  val = ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
+		  XPutPixel(xim, x, y, val);
+	       }
+	  }
+     }
+}
+
+void
+grender_15_mod(GdkImlibImage * im, int w, int h, XImage * xim,
+	       XImage * sxim, int *er1, int *er2, int *xarray,
+	       unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b;
+   unsigned char      *ptr2;
+
+   for (y = 0; y < h; y++)
+     {
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     r = im->rmap[r];
+	     g = im->gmap[g];
+	     b = im->bmap[b];
+	     val = ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
+	     XPutPixel(xim, x, y, val);
+	  }
+     }
+}
+
+void
+grender_shaped_16_mod(GdkImlibImage * im, int w, int h, XImage * xim,
+		      XImage * sxim, int *er1, int *er2, int *xarray,
+		      unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b;
+   unsigned char      *ptr2;
+
+   for (y = 0; y < h; y++)
+     {
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     if ((r == im->shape_color.r) &&
+		 (g == im->shape_color.g) &&
+		 (b == im->shape_color.b))
+		XPutPixel(sxim, x, y, 0);
+	     else
+	       {
+		  XPutPixel(sxim, x, y, 1);
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  val = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3);
+		  XPutPixel(xim, x, y, val);
+	       }
+	  }
+     }
+}
+
+void
+grender_16_mod(GdkImlibImage * im, int w, int h, XImage * xim,
+	       XImage * sxim, int *er1, int *er2, int *xarray,
+	       unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b;
+   unsigned char      *ptr2;
+
+   for (y = 0; y < h; y++)
+     {
+	for (x = 0; x < w; x++)
+	  {
+	     ptr2 = yarray[y] + xarray[x];
+	     r = (int)*ptr2++;
+	     g = (int)*ptr2++;
+	     b = (int)*ptr2;
+	     r = im->rmap[r];
+	     g = im->gmap[g];
+	     b = im->bmap[b];
+	     val = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3);
+	     XPutPixel(xim, x, y, val);
+	  }
+     }
+}
+
+void
+grender_shaped_24_mod(GdkImlibImage * im, int w, int h, XImage * xim,
+		      XImage * sxim, int *er1, int *er2, int *xarray,
+		      unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b;
+   unsigned char      *ptr2;
+
+   if (id->byte_order == BYTE_ORD_24_RGB)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		     XPutPixel(sxim, x, y, 0);
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		       val = (r << 16) | (g << 8) | b;
+		       XPutPixel(xim, x, y, val);
+		    }
+	       }
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_RBG)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		     XPutPixel(sxim, x, y, 0);
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		       val = (r << 16) | (b << 8) | g;
+		       XPutPixel(xim, x, y, val);
+		    }
+	       }
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_BRG)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		     XPutPixel(sxim, x, y, 0);
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		       val = (b << 16) | (r << 8) | g;
+		       XPutPixel(xim, x, y, val);
+		    }
+	       }
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_BGR)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		     XPutPixel(sxim, x, y, 0);
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		       val = (b << 16) | (g << 8) | r;
+		       XPutPixel(xim, x, y, val);
+		    }
+	       }
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_GRB)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		     XPutPixel(sxim, x, y, 0);
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		       val = (g << 16) | (r << 8) | b;
+		       XPutPixel(xim, x, y, val);
+		    }
+	       }
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_GBR)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  if ((r == im->shape_color.r) &&
+		      (g == im->shape_color.g) &&
+		      (b == im->shape_color.b))
+		     XPutPixel(sxim, x, y, 0);
+		  else
+		    {
+		       XPutPixel(sxim, x, y, 1);
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		       val = (g << 16) | (b << 8) | r;
+		       XPutPixel(xim, x, y, val);
+		    }
+	       }
+	  }
+     }
+}
+
+void
+grender_24_mod(GdkImlibImage * im, int w, int h, XImage * xim,
+	       XImage * sxim, int *er1, int *er2, int *xarray,
+	       unsigned char **yarray)
+{
+   int                 x, y, val, r, g, b;
+   unsigned char      *ptr2;
+
+   if (id->byte_order == BYTE_ORD_24_RGB)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  val = (r << 16) | (g << 8) | b;
+		  XPutPixel(xim, x, y, val);
+	       }
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_RBG)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  val = (r << 16) | (b << 8) | g;
+		  XPutPixel(xim, x, y, val);
+	       }
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_BRG)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  val = (b << 16) | (r << 8) | g;
+		  XPutPixel(xim, x, y, val);
+	       }
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_BGR)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  val = (b << 16) | (g << 8) | r;
+		  XPutPixel(xim, x, y, val);
+	       }
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_GRB)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  val = (g << 16) | (r << 8) | b;
+		  XPutPixel(xim, x, y, val);
+	       }
+	  }
+     }
+   else if (id->byte_order == BYTE_ORD_24_GBR)
+     {
+	for (y = 0; y < h; y++)
+	  {
+	     for (x = 0; x < w; x++)
+	       {
+		  ptr2 = yarray[y] + xarray[x];
+		  r = (int)*ptr2++;
+		  g = (int)*ptr2++;
+		  b = (int)*ptr2;
+		  r = im->rmap[r];
+		  g = im->gmap[g];
+		  b = im->bmap[b];
+		  val = (g << 16) | (b << 8) | r;
+		  XPutPixel(xim, x, y, val);
+	       }
+	  }
+     }
+}
+
+void
+grender_shaped_mod(GdkImlibImage * im, int w, int h, XImage * xim,
+		   XImage * sxim, int *er1, int *er2, int *xarray,
+		   unsigned char **yarray, int bpp)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+   unsigned char      *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line) - w;
+   img = (unsigned char *)xim->data;
+   switch (id->render_type)
+     {
+     case RT_PLAIN_PALETTE:
+	if ((id->fastrend) && (xim->bits_per_pixel == 8))
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       if ((r == im->shape_color.r) &&
+			   (g == im->shape_color.g) &&
+			   (b == im->shape_color.b))
+			 {
+			    XPutPixel(sxim, x, y, 0);
+			    img++;
+			 }
+		       else
+			 {
+			    XPutPixel(sxim, x, y, 1);
+			    r = im->rmap[r];
+			    g = im->gmap[g];
+			    b = im->bmap[b];
+			    val = gdk_imlib_best_color_match(&r, &g, &b);
+			    *img++ = val;
+			 }
+		    }
+		  img += jmp;
+	       }
+	  }
+	else
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       if ((r == im->shape_color.r) &&
+			   (g == im->shape_color.g) &&
+			   (b == im->shape_color.b))
+			  XPutPixel(sxim, x, y, 0);
+		       else
+			 {
+			    XPutPixel(sxim, x, y, 1);
+			    r = im->rmap[r];
+			    g = im->gmap[g];
+			    b = im->bmap[b];
+			    val = gdk_imlib_best_color_match(&r, &g, &b);
+			    XPutPixel(xim, x, y, val);
+			 }
+		    }
+	       }
+	  }
+	break;
+     case RT_PLAIN_PALETTE_FAST:
+	if ((id->fastrend) && (xim->bits_per_pixel == 8))
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       if ((r == im->shape_color.r) &&
+			   (g == im->shape_color.g) &&
+			   (b == im->shape_color.b))
+			 {
+			    XPutPixel(sxim, x, y, 0);
+			    img++;
+			 }
+		       else
+			 {
+			    XPutPixel(sxim, x, y, 1);
+			    r = im->rmap[r];
+			    g = im->gmap[g];
+			    b = im->bmap[b];
+			    val = COLOR_RGB(r >> 3, g >> 3, b >> 3);
+			    *img++ = val;
+			 }
+		    }
+		  img += jmp;
+	       }
+	  }
+	else
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       if ((r == im->shape_color.r) &&
+			   (g == im->shape_color.g) &&
+			   (b == im->shape_color.b))
+			  XPutPixel(sxim, x, y, 0);
+		       else
+			 {
+			    XPutPixel(sxim, x, y, 1);
+			    r = im->rmap[r];
+			    g = im->gmap[g];
+			    b = im->bmap[b];
+			    val = COLOR_RGB(r >> 3, g >> 3, b >> 3);
+			    XPutPixel(xim, x, y, val);
+			 }
+		    }
+	       }
+	  }
+	break;
+     case RT_DITHER_PALETTE:
+	if ((id->fastrend) && (xim->bits_per_pixel == 8))
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  ter = er1;
+		  er1 = er2;
+		  er2 = ter;
+		  for (ex = 0; ex < (w + 2) * 3; ex++)
+		     er2[ex] = 0;
+		  ex = 3;
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       if ((r == im->shape_color.r) &&
+			   (g == im->shape_color.g) &&
+			   (b == im->shape_color.b))
+			 {
+			    {
+			       XPutPixel(sxim, x, y, 0);
+			       img++;
+			    }
+			    ex += 3;
+			 }
+		       else
+			 {
+			    XPutPixel(sxim, x, y, 1);
+			    r = im->rmap[r];
+			    g = im->gmap[g];
+			    b = im->bmap[b];
+			    er = r + er1[ex++];
+			    eg = g + er1[ex++];
+			    eb = b + er1[ex++];
+			    if (er > 255)
+			       er = 255;
+			    else if (er < 0)
+			       er = 0;
+			    if (eg > 255)
+			       eg = 255;
+			    else if (eg < 0)
+			       eg = 0;
+			    if (eb > 255)
+			       eb = 255;
+			    else if (eb < 0)
+			       eb = 0;
+			    val = gdk_imlib_best_color_match(&er, &eg, &eb);
+			    DITHER_ERROR(er1, er2, ex, er, eg, eb);
+			    *img++ = val;
+			 }
+		    }
+		  img += jmp;
+	       }
+	  }
+	else
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  ter = er1;
+		  er1 = er2;
+		  er2 = ter;
+		  for (ex = 0; ex < (w + 2) * 3; ex++)
+		     er2[ex] = 0;
+		  ex = 3;
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       if ((r == im->shape_color.r) &&
+			   (g == im->shape_color.g) &&
+			   (b == im->shape_color.b))
+			 {
+			    XPutPixel(sxim, x, y, 0);
+			    ex += 3;
+			 }
+		       else
+			 {
+			    XPutPixel(sxim, x, y, 1);
+			    r = im->rmap[r];
+			    g = im->gmap[g];
+			    b = im->bmap[b];
+			    er = r + er1[ex++];
+			    eg = g + er1[ex++];
+			    eb = b + er1[ex++];
+			    if (er > 255)
+			       er = 255;
+			    else if (er < 0)
+			       er = 0;
+			    if (eg > 255)
+			       eg = 255;
+			    else if (eg < 0)
+			       eg = 0;
+			    if (eb > 255)
+			       eb = 255;
+			    else if (eb < 0)
+			       eb = 0;
+			    val = gdk_imlib_best_color_match(&er, &eg, &eb);
+			    DITHER_ERROR(er1, er2, ex, er, eg, eb);
+			    XPutPixel(xim, x, y, val);
+			 }
+		    }
+	       }
+	  }
+	break;
+     case RT_DITHER_PALETTE_FAST:
+	if ((id->fastrend) && (xim->bits_per_pixel == 8))
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  ter = er1;
+		  er1 = er2;
+		  er2 = ter;
+		  for (ex = 0; ex < (w + 2) * 3; ex++)
+		     er2[ex] = 0;
+		  ex = 3;
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       if ((r == im->shape_color.r) &&
+			   (g == im->shape_color.g) &&
+			   (b == im->shape_color.b))
+			 {
+			    {
+			       XPutPixel(sxim, x, y, 0);
+			       img++;
+			    }
+			    ex += 3;
+			 }
+		       else
+			 {
+			    XPutPixel(sxim, x, y, 1);
+			    r = im->rmap[r];
+			    g = im->gmap[g];
+			    b = im->bmap[b];
+			    er = r + er1[ex++];
+			    eg = g + er1[ex++];
+			    eb = b + er1[ex++];
+			    if (er > 255)
+			       er = 255;
+			    else if (er < 0)
+			       er = 0;
+			    if (eg > 255)
+			       eg = 255;
+			    else if (eg < 0)
+			       eg = 0;
+			    if (eb > 255)
+			       eb = 255;
+			    else if (eb < 0)
+			       eb = 0;
+			    val = INDEX_RGB(er >> 3, eg >> 3, eb >> 3);
+			    er = ERROR_RED(er, val);
+			    eg = ERROR_GRN(eg, val);
+			    eb = ERROR_BLU(eb, val);
+			    DITHER_ERROR(er1, er2, ex, er, eg, eb);
+			    *img++ = COLOR_INDEX(val);
+			 }
+		    }
+		  img += jmp;
+	       }
+	  }
+	else
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  ter = er1;
+		  er1 = er2;
+		  er2 = ter;
+		  for (ex = 0; ex < (w + 2) * 3; ex++)
+		     er2[ex] = 0;
+		  ex = 3;
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       if ((r == im->shape_color.r) &&
+			   (g == im->shape_color.g) &&
+			   (b == im->shape_color.b))
+			 {
+			    XPutPixel(sxim, x, y, 0);
+			    ex += 3;
+			 }
+		       else
+			 {
+			    XPutPixel(sxim, x, y, 1);
+			    r = im->rmap[r];
+			    g = im->gmap[g];
+			    b = im->bmap[b];
+			    er = r + er1[ex++];
+			    eg = g + er1[ex++];
+			    eb = b + er1[ex++];
+			    if (er > 255)
+			       er = 255;
+			    else if (er < 0)
+			       er = 0;
+			    if (eg > 255)
+			       eg = 255;
+			    else if (eg < 0)
+			       eg = 0;
+			    if (eb > 255)
+			       eb = 255;
+			    else if (eb < 0)
+			       eb = 0;
+			    val = INDEX_RGB(er >> 3, eg >> 3, eb >> 3);
+			    er = ERROR_RED(er, val);
+			    eg = ERROR_GRN(eg, val);
+			    eb = ERROR_BLU(eb, val);
+			    DITHER_ERROR(er1, er2, ex, er, eg, eb);
+			    XPutPixel(xim, x, y, COLOR_INDEX(val));
+			 }
+		    }
+	       }
+	  }
+	break;
+     default:
+	if (id->fastrend)
+	  {
+	     switch (bpp)
+	       {
+	       case 8:
+		  break;
+	       case 15:
+		  if (id->render_type == RT_DITHER_TRUECOL)
+		    {
+		       if (id->ordered_dither)
+			  grender_shaped_15_fast_dither_mod_ordered(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		       else
+			  grender_shaped_15_fast_dither_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		    }
+		  else
+		     grender_shaped_15_fast_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       case 16:
+		  if (id->render_type == RT_DITHER_TRUECOL)
+		    {
+		       if (id->ordered_dither)
+			  grender_shaped_16_fast_dither_mod_ordered(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		       else
+			  grender_shaped_16_fast_dither_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		    }
+		  else
+		     grender_shaped_16_fast_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       case 24:
+	       case 32:
+		  if (xim->bits_per_pixel == 24)
+		     grender_shaped_24_fast_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  else
+		     grender_shaped_32_fast_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       default:
+		  break;
+	       }
+	  }
+	else
+	  {
+	     switch (bpp)
+	       {
+	       case 8:
+		  break;
+	       case 15:
+		  if (id->render_type == RT_DITHER_TRUECOL)
+		    {
+		       if (id->ordered_dither)
+			  grender_shaped_15_dither_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		       grender_shaped_15_dither_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		    }
+		  else
+		     grender_shaped_15_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       case 16:
+		  if (id->render_type == RT_DITHER_TRUECOL)
+		    {
+		       if (id->ordered_dither)
+			  grender_shaped_16_dither_mod_ordered(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		       else
+			  grender_shaped_16_dither_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		    }
+		  else
+		     grender_shaped_16_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       case 24:
+		  grender_shaped_24_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+	       case 32:
+		  grender_shaped_24_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       default:
+		  break;
+	       }
+	  }
+	break;
+     }
+}
+
+void
+grender_mod(GdkImlibImage * im, int w, int h, XImage * xim,
+	    XImage * sxim, int *er1, int *er2, int *xarray,
+	    unsigned char **yarray, int bpp)
+{
+   int                 x, y, val, r, g, b, *ter, ex, er, eg, eb;
+   unsigned char      *ptr2;
+   unsigned char      *img;
+   int                 jmp;
+
+   jmp = (xim->bytes_per_line) - w;
+   img = (unsigned char *)xim->data;
+   switch (id->render_type)
+     {
+     case RT_PLAIN_PALETTE:
+	if ((id->fastrend) && (xim->bits_per_pixel == 8))
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		       val = gdk_imlib_best_color_match(&r, &g, &b);
+		       *img++ = val;
+		    }
+		  img += jmp;
+	       }
+	  }
+	else
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		       val = gdk_imlib_best_color_match(&r, &g, &b);
+		       XPutPixel(xim, x, y, val);
+		    }
+	       }
+	  }
+	break;
+     case RT_PLAIN_PALETTE_FAST:
+	if ((id->fastrend) && (xim->bits_per_pixel == 8))
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		       val = COLOR_RGB(r >> 3, g >> 3, b >> 3);
+		       *img++ = val;
+		    }
+		  img += jmp;
+	       }
+	  }
+	else
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		       val = COLOR_RGB(r >> 3, g >> 3, b >> 3);
+		       XPutPixel(xim, x, y, val);
+		    }
+	       }
+	  }
+	break;
+     case RT_DITHER_PALETTE:
+	if ((id->fastrend) && (xim->bits_per_pixel == 8))
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  ter = er1;
+		  er1 = er2;
+		  er2 = ter;
+		  for (ex = 0; ex < (w + 2) * 3; ex++)
+		     er2[ex] = 0;
+		  ex = 3;
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		       er = r + er1[ex++];
+		       eg = g + er1[ex++];
+		       eb = b + er1[ex++];
+		       if (er > 255)
+			  er = 255;
+		       else if (er < 0)
+			  er = 0;
+		       if (eg > 255)
+			  eg = 255;
+		       else if (eg < 0)
+			  eg = 0;
+		       if (eb > 255)
+			  eb = 255;
+		       else if (eb < 0)
+			  eb = 0;
+		       val = gdk_imlib_best_color_match(&er, &eg, &eb);
+		       DITHER_ERROR(er1, er2, ex, er, eg, eb);
+		       *img++ = val;
+		    }
+		  img += jmp;
+	       }
+	  }
+	else
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  ter = er1;
+		  er1 = er2;
+		  er2 = ter;
+		  for (ex = 0; ex < (w + 2) * 3; ex++)
+		     er2[ex] = 0;
+		  ex = 3;
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		       er = r + er1[ex++];
+		       eg = g + er1[ex++];
+		       eb = b + er1[ex++];
+		       if (er > 255)
+			  er = 255;
+		       else if (er < 0)
+			  er = 0;
+		       if (eg > 255)
+			  eg = 255;
+		       else if (eg < 0)
+			  eg = 0;
+		       if (eb > 255)
+			  eb = 255;
+		       else if (eb < 0)
+			  eb = 0;
+		       val = gdk_imlib_best_color_match(&er, &eg, &eb);
+		       DITHER_ERROR(er1, er2, ex, er, eg, eb);
+		       XPutPixel(xim, x, y, val);
+		    }
+	       }
+	  }
+	break;
+     case RT_DITHER_PALETTE_FAST:
+	if ((id->fastrend) && (xim->bits_per_pixel == 8))
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  ter = er1;
+		  er1 = er2;
+		  er2 = ter;
+		  for (ex = 0; ex < (w + 2) * 3; ex++)
+		     er2[ex] = 0;
+		  ex = 3;
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		       er = r + er1[ex++];
+		       eg = g + er1[ex++];
+		       eb = b + er1[ex++];
+		       if (er > 255)
+			  er = 255;
+		       else if (er < 0)
+			  er = 0;
+		       if (eg > 255)
+			  eg = 255;
+		       else if (eg < 0)
+			  eg = 0;
+		       if (eb > 255)
+			  eb = 255;
+		       else if (eb < 0)
+			  eb = 0;
+		       val = INDEX_RGB(er >> 3, eg >> 3, eb >> 3);
+		       er = ERROR_RED(er, val);
+		       eg = ERROR_GRN(eg, val);
+		       eb = ERROR_BLU(eb, val);
+		       DITHER_ERROR(er1, er2, ex, er, eg, eb);
+		       *img++ = COLOR_INDEX(val);
+		    }
+		  img += jmp;
+	       }
+	  }
+	else
+	  {
+	     for (y = 0; y < h; y++)
+	       {
+		  ter = er1;
+		  er1 = er2;
+		  er2 = ter;
+		  for (ex = 0; ex < (w + 2) * 3; ex++)
+		     er2[ex] = 0;
+		  ex = 3;
+		  for (x = 0; x < w; x++)
+		    {
+		       ptr2 = yarray[y] + xarray[x];
+		       r = (int)*ptr2++;
+		       g = (int)*ptr2++;
+		       b = (int)*ptr2;
+		       r = im->rmap[r];
+		       g = im->gmap[g];
+		       b = im->bmap[b];
+		       er = r + er1[ex++];
+		       eg = g + er1[ex++];
+		       eb = b + er1[ex++];
+		       if (er > 255)
+			  er = 255;
+		       else if (er < 0)
+			  er = 0;
+		       if (eg > 255)
+			  eg = 255;
+		       else if (eg < 0)
+			  eg = 0;
+		       if (eb > 255)
+			  eb = 255;
+		       else if (eb < 0)
+			  eb = 0;
+		       val = INDEX_RGB(er >> 3, eg >> 3, eb >> 3);
+		       er = ERROR_RED(er, val);
+		       eg = ERROR_GRN(eg, val);
+		       eb = ERROR_BLU(eb, val);
+		       DITHER_ERROR(er1, er2, ex, er, eg, eb);
+		       XPutPixel(xim, x, y, COLOR_INDEX(val));
+		    }
+	       }
+	  }
+	break;
+     default:
+	if (id->fastrend)
+	  {
+	     switch (bpp)
+	       {
+	       case 8:
+		  break;
+	       case 15:
+		  if (id->render_type == RT_DITHER_TRUECOL)
+		    {
+		       if (id->ordered_dither)
+			  grender_15_fast_dither_mod_ordered(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		       else
+			  grender_15_fast_dither_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		    }
+		  else
+		     grender_15_fast_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       case 16:
+		  if (id->render_type == RT_DITHER_TRUECOL)
+		    {
+		       if (id->ordered_dither)
+			  grender_16_fast_dither_mod_ordered(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		       else
+			  grender_16_fast_dither_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		    }
+		  else
+		     grender_16_fast_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       case 24:
+	       case 32:
+		  if (xim->bits_per_pixel == 24)
+		     grender_24_fast_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  else
+		     grender_32_fast_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       default:
+		  break;
+	       }
+	  }
+	else
+	  {
+	     switch (bpp)
+	       {
+	       case 8:
+		  break;
+	       case 15:
+		  if (id->render_type == RT_DITHER_TRUECOL)
+		    {
+		       if (id->ordered_dither)
+			  grender_15_dither_mod_ordered(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		       else
+			  grender_15_dither_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		    }
+		  else
+		     grender_15_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       case 16:
+		  if (id->render_type == RT_DITHER_TRUECOL)
+		    {
+		       if (id->ordered_dither)
+			  grender_16_dither_mod_ordered(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		       else
+			  grender_16_dither_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		    }
+		  else
+		     grender_16_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       case 24:
+		  grender_24_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       case 32:
+		  grender_24_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray);
+		  break;
+	       default:
+		  break;
+	       }
+	     break;
+	  }
+     }
+}
+
+gint
+gdk_imlib_render(GdkImlibImage * im, gint w, gint h)
+{
+   XImage             *xim, *sxim;
+   GC                  tgc, stgc;
+   XGCValues           gcv;
+   unsigned char      *tmp, *stmp, **yarray, *ptr22;
+   int                 w3, x, inc, pos, *error, *er1, *er2, *xarray, ex,
+                       bpp, huge;
+   Pixmap              pmap, mask;
+   GdkPixmap          *pm, *mm;
+   int                 shared_pixmap, shared_image, ok;
+
+   sxim = NULL;
+   xim = NULL;
+   tmp = NULL;
+   stmp = NULL;
+   pmap = 0;
+   mask = 0;
+   tgc = 0;
+   stgc = 0;
+   inc = 0;
+   if (!im)
+      return 0;
+   if (w <= 0)
+      return 0;
+   if (h <= 0)
+      return 0;
+   gcv.graphics_exposures = False;
+
+/* look for the pixmap in cache first */
+   if (id->cache.on_pixmap)
+     {
+	pmap = 0;
+	gfind_pixmap(im, w, h, &pm, &mm);
+	if (pm)
+	  {
+	     im->width = w;
+	     im->height = h;
+	     im->pixmap = pm;
+	     if (mm)
+		im->shape_mask = mm;
+	     else
+		im->shape_mask = NULL;
+	     return 1;
+	  }
+     }
+
+   if (im->pixmap)
+      gfree_pixmappmap(im->pixmap);
+   im->pixmap = NULL;
+   im->shape_mask = NULL;
+/* setup stuff */
+   huge = 0;
+   if (id->x.depth <= 8)
+      bpp = 1;
+   else if (id->x.depth <= 16)
+      bpp = 2;
+   else
+      bpp = 4;
+   if ((id->max_shm) && ((bpp * w * h) > id->max_shm))
+      huge = 1;
+   im->width = w;
+   im->height = h;
+
+/* dithering array */
+   error = (int *)malloc(sizeof(int) * (w + 2) * 2 * 3);
+
+   if (!error)
+     {
+	fprintf(stderr, "ERROR: Cannot allocate RAM for image dither buffer\n");
+	return 0;
+     }
+
+/* setup pointers to point right */
+   er1 = error;
+   er2 = error + ((w + 2) * 3);
+   w3 = im->rgb_width * 3;
+   ptr22 = im->rgb_data;
+
+/* setup coord-mapping array (specially for border scaling) */
+   xarray = malloc(sizeof(int) * w);
+
+   if (!xarray)
+     {
+	fprintf(stderr, "ERROR: Cannot allocate X co-ord buffer\n");
+	free(error);
+	return 0;
+     }
+   yarray = malloc(sizeof(unsigned char *) * h);
+
+   if (!yarray)
+     {
+	fprintf(stderr, "ERROR: Cannot allocate Y co-ord buffer\n");
+	free(xarray);
+	free(error);
+	return 0;
+     }
+   for (ex = 0; ex < ((w + 2) * 3 * 2); ex++)
+      error[ex] = 0;
+   {
+      int                 l, r, m;
+
+      if (w < im->border.left + im->border.right)
+	{
+	   l = w >> 1;
+	   r = w - l;
+	   m = 0;
+	}
+      else
+	{
+	   l = im->border.left;
+	   r = im->border.right;
+	   m = w - l - r;
+	}
+      if (m > 0)
+	 inc = ((im->rgb_width - im->border.left - im->border.right) << 16) / m;
+      pos = 0;
+      if (l)
+	 for (x = 0; x < l; x++)
+	   {
+	      xarray[x] = (pos >> 16) + (pos >> 16) + (pos >> 16);
+	      pos += 0x10000;
+	   }
+      if (m)
+	{
+	   for (x = l; x < l + m; x++)
+	     {
+		xarray[x] = (pos >> 16) + (pos >> 16) + (pos >> 16);
+		pos += inc;
+	     }
+	}
+      pos = (im->rgb_width - r) << 16;
+      for (x = w - r; x < w; x++)
+	{
+	   xarray[x] = (pos >> 16) + (pos >> 16) + (pos >> 16);
+	   pos += 0x10000;
+	}
+
+      if (h < im->border.top + im->border.bottom)
+	{
+	   l = h >> 1;
+	   r = h - l;
+	   m = 0;
+	}
+      else
+	{
+	   l = im->border.top;
+	   r = im->border.bottom;
+	   m = h - l - r;
+	}
+      if (m > 0)
+	 inc = ((im->rgb_height - im->border.top - im->border.bottom) << 16) / m;
+      pos = 0;
+      for (x = 0; x < l; x++)
+	{
+	   yarray[x] = ptr22 + ((pos >> 16) * w3);
+	   pos += 0x10000;
+	}
+      if (m)
+	{
+	   for (x = l; x < l + m; x++)
+	     {
+		yarray[x] = ptr22 + ((pos >> 16) * w3);
+		pos += inc;
+	     }
+	}
+      pos = (im->rgb_height - r) << 16;
+      for (x = h - r; x < h; x++)
+	{
+	   yarray[x] = ptr22 + ((pos >> 16) * w3);
+	   pos += 0x10000;
+	}
+   }
+
+/* work out if we should use shared pixmap. images etc */
+   shared_pixmap = 0;
+   shared_image = 0;
+   if ((id->x.shmp) && (id->x.shm) && (!huge))
+     {
+	shared_pixmap = 1;
+	shared_image = 0;
+     }
+   else if ((id->x.shm) && (!huge))
+     {
+	shared_pixmap = 0;
+	shared_image = 1;
+     }
+   else
+      shared_pixmap = 0;
+   shared_image = 0;
+
+/* init images and pixmaps */
+   ok = 1;
+   if (shared_pixmap)
+     {
+	xim = XShmCreateImage(id->x.disp, id->x.visual, id->x.depth, ZPixmap, NULL, &id->x.last_shminfo, w, h);
+	if (!xim)
+	  {
+	     fprintf(stderr, "IMLIB ERROR: Mit-SHM can't create XImage for Shared Pixmap Wrapper\n");
+	     fprintf(stderr, "             Falling back on Shared XImages\n");
+	     shared_pixmap = 0;
+	     shared_image = 1;
+	     ok = 0;
+	  }
+	if (ok)
+	  {
+	     id->x.last_shminfo.shmid = shmget(IPC_PRIVATE, xim->bytes_per_line * xim->height, IPC_CREAT | 0777);
+	     if (id->x.last_shminfo.shmid == -1)
+	       {
+		  fprintf(stderr, "IMLIB ERROR: SHM can't get SHM Identifier for Shared Pixmap Wrapper\n");
+		  fprintf(stderr, "             Falling back on Shared XImages\n");
+		  XDestroyImage(xim);
+		  shared_pixmap = 0;
+		  shared_image = 1;
+		  ok = 1;
+	       }
+	     if (ok)
+	       {
+		  id->x.last_shminfo.shmaddr = xim->data = shmat(id->x.last_shminfo.shmid, 0, 0);
+		  id->x.last_shminfo.readOnly = False;
+		  XShmAttach(id->x.disp, &id->x.last_shminfo);
+		  tmp = (unsigned char *)xim->data;
+		  id->x.last_xim = xim;
+		  pmap = XShmCreatePixmap(id->x.disp, id->x.base_window,
+					  id->x.last_shminfo.shmaddr,
+				      &id->x.last_shminfo, w, h, id->x.depth);
+		  tgc = XCreateGC(id->x.disp, pmap, GCGraphicsExposures, &gcv);
+		  if ((im->shape_color.r >= 0) && (im->shape_color.g >= 0) && (im->shape_color.b >= 0))
+		    {
+		       sxim = XShmCreateImage(id->x.disp, id->x.visual, 1, ZPixmap, NULL, &id->x.last_sshminfo, w, h);
+		       if (!sxim)
+			 {
+			    fprintf(stderr, "IMLIB ERROR: Mit-SHM can't create XImage for Shared Pixmap mask Wrapper\n");
+			    fprintf(stderr, "             Falling back on Shared XImages\n");
+			    XShmDetach(id->x.disp, &id->x.last_shminfo);
+			    XDestroyImage(xim);
+			    shmdt(id->x.last_shminfo.shmaddr);
+			    shmctl(id->x.last_shminfo.shmid, IPC_RMID, 0);
+			    shared_pixmap = 0;
+			    shared_image = 1;
+			    ok = 0;
+			 }
+		       if (ok)
+			 {
+			    id->x.last_sshminfo.shmid = shmget(IPC_PRIVATE, sxim->bytes_per_line * sxim->height, IPC_CREAT | 0777);
+			    if (id->x.last_sshminfo.shmid == -1)
+			      {
+				 fprintf(stderr, "IMLIB ERROR: SHM can't get SHM Identifier for Shared Pixmap mask Wrapper\n");
+				 fprintf(stderr, "             Falling back on Shared XImages\n");
+				 XShmDetach(id->x.disp, &id->x.last_shminfo);
+				 XDestroyImage(xim);
+				 shmdt(id->x.last_shminfo.shmaddr);
+				 shmctl(id->x.last_shminfo.shmid, IPC_RMID, 0);
+				 XDestroyImage(sxim);
+				 shared_pixmap = 0;
+				 shared_image = 1;
+				 ok = 0;
+			      }
+			    id->x.last_sshminfo.shmaddr = sxim->data = shmat(id->x.last_sshminfo.shmid, 0, 0);
+			    id->x.last_sshminfo.readOnly = False;
+			    XShmAttach(id->x.disp, &id->x.last_sshminfo);
+			    stmp = (unsigned char *)sxim->data;
+			    id->x.last_sxim = sxim;
+			    mask = XShmCreatePixmap(id->x.disp, id->x.base_window,
+						  id->x.last_sshminfo.shmaddr,
+					       &id->x.last_sshminfo, w, h, 1);
+			    stgc = XCreateGC(id->x.disp, mask, GCGraphicsExposures, &gcv);
+			 }
+		    }
+	       }
+	  }
+     }
+   ok = 1;
+   if (shared_image)
+     {
+	xim = XShmCreateImage(id->x.disp, id->x.visual, id->x.depth, ZPixmap, NULL, &id->x.last_shminfo, w, h);
+	if (!xim)
+	  {
+	     fprintf(stderr, "IMLIB ERROR: Mit-SHM can't create Shared XImage\n");
+	     fprintf(stderr, "             Falling back on XImages\n");
+	     shared_pixmap = 0;
+	     shared_image = 0;
+	     ok = 0;
+	  }
+	if (ok)
+	  {
+	     id->x.last_shminfo.shmid = shmget(IPC_PRIVATE, xim->bytes_per_line * xim->height, IPC_CREAT | 0777);
+	     if (id->x.last_shminfo.shmid == -1)
+	       {
+		  fprintf(stderr, "IMLIB ERROR: SHM can't get SHM Identifier for Shared XImage\n");
+		  fprintf(stderr, "             Falling back on XImages\n");
+		  XDestroyImage(xim);
+		  shared_pixmap = 0;
+		  shared_image = 0;
+		  ok = 0;
+	       }
+	     if (ok)
+	       {
+		  id->x.last_shminfo.shmaddr = xim->data = shmat(id->x.last_shminfo.shmid, 0, 0);
+		  id->x.last_shminfo.readOnly = False;
+		  XShmAttach(id->x.disp, &id->x.last_shminfo);
+		  tmp = (unsigned char *)xim->data;
+		  id->x.last_xim = xim;
+		  pmap = XCreatePixmap(id->x.disp, id->x.base_window, w, h, id->x.depth);
+		  tgc = XCreateGC(id->x.disp, pmap, GCGraphicsExposures, &gcv);
+		  if ((im->shape_color.r >= 0) && (im->shape_color.g >= 0) && (im->shape_color.b >= 0))
+		    {
+		       sxim = XShmCreateImage(id->x.disp, id->x.visual, 1, ZPixmap, NULL, &id->x.last_sshminfo, w, h);
+		       if (!sxim)
+			 {
+			    fprintf(stderr, "IMLIB ERROR: Mit-SHM can't create Shared XImage mask\n");
+			    fprintf(stderr, "             Falling back on XImages\n");
+			    XShmDetach(id->x.disp, &id->x.last_shminfo);
+			    XDestroyImage(xim);
+			    shmdt(id->x.last_shminfo.shmaddr);
+			    shmctl(id->x.last_shminfo.shmid, IPC_RMID, 0);
+			    shared_pixmap = 0;
+			    shared_image = 0;
+			    ok = 0;
+			 }
+		       if (ok)
+			 {
+			    id->x.last_sshminfo.shmid = shmget(IPC_PRIVATE, sxim->bytes_per_line * sxim->height, IPC_CREAT | 0777);
+			    if (id->x.last_sshminfo.shmid == -1)
+			      {
+				 fprintf(stderr, "Imlib ERROR: SHM can't get SHM Identifierfor Shared XImage mask\n");
+				 fprintf(stderr, "             Falling back on XImages\n");
+				 XShmDetach(id->x.disp, &id->x.last_shminfo);
+				 XDestroyImage(xim);
+				 shmdt(id->x.last_shminfo.shmaddr);
+				 shmctl(id->x.last_shminfo.shmid, IPC_RMID, 0);
+				 XDestroyImage(sxim);
+				 shared_pixmap = 0;
+				 shared_image = 0;
+				 ok = 0;
+			      }
+			    if (ok)
+			      {
+				 id->x.last_sshminfo.shmaddr = sxim->data = shmat(id->x.last_sshminfo.shmid, 0, 0);
+				 id->x.last_sshminfo.readOnly = False;
+				 XShmAttach(id->x.disp, &id->x.last_sshminfo);
+				 stmp = (unsigned char *)sxim->data;
+				 id->x.last_sxim = sxim;
+				 mask = XCreatePixmap(id->x.disp, id->x.base_window, w, h, 1);
+				 stgc = XCreateGC(id->x.disp, mask, GCGraphicsExposures, &gcv);
+			      }
+			 }
+		    }
+	       }
+	  }
+     }
+   ok = 1;
+   if ((!shared_pixmap) && (!shared_image))
+     {
+	tmp = (unsigned char *)malloc(w * h * bpp);
+	if (!tmp)
+	  {
+	     fprintf(stderr, "IMLIB ERROR: Cannot allocate RAM for XImage data\n");
+	     free(xarray);
+	     free(yarray);
+	     free(error);
+	     return 0;
+	  }
+	xim = XCreateImage(id->x.disp, id->x.visual, id->x.depth, ZPixmap, 0, (char *)tmp, w, h, 8, 0);
+	if (!xim)
+	  {
+	     fprintf(stderr, "IMLIB ERROR: Cannot allocate XImage buffer\n");
+	     free(xarray);
+	     free(yarray);
+	     free(error);
+	     free(tmp);
+	     return 0;
+	  }
+	pmap = XCreatePixmap(id->x.disp, id->x.base_window, w, h, id->x.depth);
+	if (!pmap)
+	  {
+	     fprintf(stderr, "IMLIB ERROR: Cannot create pixmap\n");
+	     free(xarray);
+	     free(yarray);
+	     free(error);
+	     XDestroyImage(xim);
+	     return 0;
+	  }
+	tgc = XCreateGC(id->x.disp, pmap, GCGraphicsExposures, &gcv);
+	if ((im->shape_color.r >= 0) && (im->shape_color.g >= 0) && (im->shape_color.b >= 0))
+	  {
+	     stmp = (unsigned char *)malloc(((w >> 3) + 8) * h);
+	     if (!stmp)
+	       {
+		  fprintf(stderr, "IMLIB ERROR: Cannot allocate RAM for shape XImage data\n");
+		  free(xarray);
+		  free(yarray);
+		  free(error);
+		  XDestroyImage(xim);
+		  return 0;
+	       }
+	     sxim = XCreateImage(id->x.disp, id->x.visual, 1, ZPixmap, 0, (char *)stmp, w, h, 8, 0);
+	     if (!sxim)
+	       {
+		  fprintf(stderr, "IMLIB ERROR: Cannot allocate XImage shape buffer\n");
+		  free(xarray);
+		  free(yarray);
+		  free(error);
+		  free(stmp);
+		  XDestroyImage(xim);
+		  return 0;
+	       }
+	     mask = XCreatePixmap(id->x.disp, id->x.base_window, w, h, 1);
+	     if (!mask)
+	       {
+		  fprintf(stderr, "IMLIB ERROR: Cannot create shape pixmap\n");
+		  free(xarray);
+		  free(yarray);
+		  free(error);
+		  XDestroyImage(sxim);
+		  XDestroyImage(xim);
+		  return 0;
+	       }
+	     stgc = XCreateGC(id->x.disp, mask, GCGraphicsExposures, &gcv);
+	  }
+     }
+
+/* copy XImage to the pixmap, if not a shared pixmap */
+   if ((im->shape_color.r >= 0) && (im->shape_color.g >= 0) && (im->shape_color.b >= 0))
+     {
+	if ((im->mod.gamma == 256) && (im->mod.brightness == 256) && (im->mod.contrast == 256) &&
+	    (im->rmod.gamma == 256) && (im->rmod.brightness == 256) && (im->rmod.contrast == 256) &&
+	    (im->gmod.gamma == 256) && (im->gmod.brightness == 256) && (im->gmod.contrast == 256) &&
+	    (im->bmod.gamma == 256) && (im->bmod.brightness == 256) && (im->bmod.contrast == 256))
+	  {
+	     if (id->x.depth <= 8)
+		grender_shaped(im, w, h, xim, sxim, er1, er2, xarray, yarray, 8);
+	     else
+		grender_shaped(im, w, h, xim, sxim, er1, er2, xarray, yarray, id->x.render_depth);
+	  }
+	else
+	  {
+	     if (id->x.depth <= 8)
+		grender_shaped_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray, 8);
+	     else
+		grender_shaped_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray, id->x.render_depth);
+	  }
+	if (shared_image)
+	  {
+	     XShmPutImage(id->x.disp, pmap, tgc, xim, 0, 0, 0, 0, w, h, False);
+	     XShmPutImage(id->x.disp, mask, stgc, sxim, 0, 0, 0, 0, w, h, False);
+	     XSync(id->x.disp, False);
+	     im->pixmap = gdk_imlib_pixmap_foreign_new(w, h, id->x.depth, pmap);
+	     im->shape_mask = gdk_imlib_pixmap_foreign_new(w, h, 1, mask);
+	     XShmDetach(id->x.disp, &id->x.last_shminfo);
+	     XDestroyImage(xim);
+	     shmdt(id->x.last_shminfo.shmaddr);
+	     shmctl(id->x.last_shminfo.shmid, IPC_RMID, 0);
+	     XShmDetach(id->x.disp, &id->x.last_sshminfo);
+	     XDestroyImage(sxim);
+	     shmdt(id->x.last_sshminfo.shmaddr);
+	     shmctl(id->x.last_sshminfo.shmid, IPC_RMID, 0);
+	     id->x.last_xim = NULL;
+	     id->x.last_sxim = NULL;
+	     xim = NULL;
+	     sxim = NULL;
+	     XFreeGC(id->x.disp, tgc);
+	     XFreeGC(id->x.disp, stgc);
+	  }
+	else if (shared_pixmap)
+	  {
+	     Pixmap              p2, m2;
+
+	     p2 = XCreatePixmap(id->x.disp, id->x.base_window, w, h, id->x.depth);
+	     m2 = XCreatePixmap(id->x.disp, id->x.base_window, w, h, 1);
+	     XCopyArea(id->x.disp, pmap, p2, tgc, 0, 0, w, h, 0, 0);
+	     XCopyArea(id->x.disp, mask, m2, stgc, 0, 0, w, h, 0, 0);
+	     im->pixmap = gdk_imlib_pixmap_foreign_new(w, h, id->x.depth, p2);
+	     im->shape_mask = gdk_imlib_pixmap_foreign_new(w, h, 1, m2);
+	     XFreeGC(id->x.disp, tgc);
+	     XFreeGC(id->x.disp, stgc);
+	     XFreePixmap(id->x.disp, pmap);
+	     XFreePixmap(id->x.disp, mask);
+	     XSync(id->x.disp, False);
+	     XShmDetach(id->x.disp, &id->x.last_shminfo);
+	     XDestroyImage(xim);
+	     shmdt(id->x.last_shminfo.shmaddr);
+	     shmctl(id->x.last_shminfo.shmid, IPC_RMID, 0);
+	     XShmDetach(id->x.disp, &id->x.last_sshminfo);
+	     XDestroyImage(sxim);
+	     shmdt(id->x.last_sshminfo.shmaddr);
+	     shmctl(id->x.last_sshminfo.shmid, IPC_RMID, 0);
+	     id->x.last_xim = NULL;
+	     id->x.last_sxim = NULL;
+	     xim = NULL;
+	     sxim = NULL;
+	  }
+	else
+	  {
+	     XPutImage(id->x.disp, pmap, tgc, xim, 0, 0, 0, 0, w, h);
+	     XPutImage(id->x.disp, mask, stgc, sxim, 0, 0, 0, 0, w, h);
+	     im->pixmap = gdk_imlib_pixmap_foreign_new(w, h, id->x.depth, pmap);
+	     im->shape_mask = gdk_imlib_pixmap_foreign_new(w, h, 1, mask);
+	     XDestroyImage(xim);
+	     XDestroyImage(sxim);
+	     xim = NULL;
+	     sxim = NULL;
+	     XFreeGC(id->x.disp, tgc);
+	     XFreeGC(id->x.disp, stgc);
+	  }
+     }
+   else
+     {
+	if ((im->mod.gamma == 256) && (im->mod.brightness == 256) && (im->mod.contrast == 256) &&
+	    (im->rmod.gamma == 256) && (im->rmod.brightness == 256) && (im->rmod.contrast == 256) &&
+	    (im->gmod.gamma == 256) && (im->gmod.brightness == 256) && (im->gmod.contrast == 256) &&
+	    (im->bmod.gamma == 256) && (im->bmod.brightness == 256) && (im->bmod.contrast == 256))
+	  {
+	     if (id->x.depth <= 8)
+		grender(im, w, h, xim, sxim, er1, er2, xarray, yarray, 8);
+	     else
+		grender(im, w, h, xim, sxim, er1, er2, xarray, yarray, id->x.render_depth);
+	  }
+	else
+	  {
+	     if (id->x.depth <= 8)
+		grender_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray, 8);
+	     else
+		grender_mod(im, w, h, xim, sxim, er1, er2, xarray, yarray, id->x.render_depth);
+	  }
+	if (shared_image)
+	  {
+	     XShmPutImage(id->x.disp, pmap, tgc, xim, 0, 0, 0, 0, w, h, False);
+	     im->pixmap = gdk_imlib_pixmap_foreign_new(w, h, id->x.depth, pmap);
+	     im->shape_mask = NULL;
+	     XSync(id->x.disp, False);
+	     XShmDetach(id->x.disp, &id->x.last_shminfo);
+	     XDestroyImage(xim);
+	     shmdt(id->x.last_shminfo.shmaddr);
+	     shmctl(id->x.last_shminfo.shmid, IPC_RMID, 0);
+	     id->x.last_xim = NULL;
+	     xim = NULL;
+	     sxim = NULL;
+	     XFreeGC(id->x.disp, tgc);
+	  }
+	else if (shared_pixmap)
+	  {
+	     Pixmap              p2;
+
+	     p2 = XCreatePixmap(id->x.disp, id->x.base_window, w, h, id->x.depth);
+	     XCopyArea(id->x.disp, pmap, p2, tgc, 0, 0, w, h, 0, 0);
+	     im->pixmap = gdk_imlib_pixmap_foreign_new(w, h, id->x.depth, p2);
+	     im->shape_mask = NULL;
+	     XFreeGC(id->x.disp, tgc);
+	     XFreePixmap(id->x.disp, pmap);
+	     XSync(id->x.disp, False);
+	     XShmDetach(id->x.disp, &id->x.last_shminfo);
+	     XDestroyImage(xim);
+	     shmdt(id->x.last_shminfo.shmaddr);
+	     shmctl(id->x.last_shminfo.shmid, IPC_RMID, 0);
+	     id->x.last_xim = NULL;
+	     xim = NULL;
+	     sxim = NULL;
+	  }
+	else
+	  {
+	     XPutImage(id->x.disp, pmap, tgc, xim, 0, 0, 0, 0, w, h);
+	     im->pixmap = gdk_imlib_pixmap_foreign_new(w, h, id->x.depth, pmap);
+	     im->shape_mask = NULL;
+	     XDestroyImage(xim);
+	     xim = NULL;
+	     sxim = NULL;
+	     XFreeGC(id->x.disp, tgc);
+	  }
+     }
+
+/* cleanup */
+   XSync(id->x.disp, False);
+   free(error);
+   free(xarray);
+   free(yarray);
+
+/* add this pixmap to the cache */
+   gadd_pixmap(im, w, h, xim, sxim);
+   return 1;
+}
diff --git a/src/gdk_imlib/save.c b/src/gdk_imlib/save.c
new file mode 100644
index 0000000000..7b16007b4d
--- /dev/null
+++ b/src/gdk_imlib/save.c
@@ -0,0 +1,538 @@
+#define _GNU_SOURCE
+#include <config.h>
+
+#include "gdk_imlib.h"
+#include "gdk_imlib_private.h"
+
+gint
+gdk_imlib_save_image(GdkImlibImage * im, char *file, GdkImlibSaveInfo * info)
+{
+   char               *ext;
+   char                cmd[10240];
+   FILE               *f;
+   GdkImlibSaveInfo    defaults;
+
+   if (!im || !file)
+      return 0;
+
+   defaults.quality = 208;
+   defaults.scaling = 1024;
+   defaults.xjustification = 512;
+   defaults.yjustification = 512;
+   defaults.page_size = PAGE_SIZE_LETTER;
+   defaults.color = 1;
+
+   if (!info)
+      info = &defaults;
+   ext = g_GetExtension(file);
+
+   if ((!strcasecmp(ext, "ppm")) || (!strcasecmp(ext, "pnm")))
+     {
+	f = fopen(file, "wb");
+	if (f)
+	  {
+	     if (!fprintf(f, "P6\n# Created by Imlib\n%i %i\n255\n", im->rgb_width, im->rgb_height))
+	       {
+		  fclose(f);
+		  return 0;
+	       }
+	     if (!fwrite(im->rgb_data, 1, (im->rgb_width * im->rgb_height * 3), f))
+	       {
+		  fclose(f);
+		  return 0;
+	       }
+	     fclose(f);
+	     return 1;
+	  }
+     }
+   else if (!strcasecmp(ext, "pgm"))
+     {
+	int                 x, y;
+	unsigned char      *ptr, val;
+	int                 v;
+
+	f = fopen(file, "wb");
+	if (f)
+	  {
+	     if (!fprintf(f, "P5\n# Created by Imlib\n%i %i\n255\n", im->rgb_width, im->rgb_height))
+	       {
+		  fclose(f);
+		  return 0;
+	       }
+	     ptr = im->rgb_data;
+	     for (y = 0; y < im->rgb_height; y++)
+	       {
+		  for (x = 0; x < im->rgb_width; x++)
+		    {
+		       v = (int)(*ptr++);
+		       v += (int)(*ptr++);
+		       v += (int)(*ptr++);
+		       val = (unsigned char)(v / 3);
+		       if (!fwrite(&val, 1, 1, f))
+			 {
+			    fclose(f);
+			    return 0;
+			 }
+		    }
+	       }
+	     fclose(f);
+	     return 1;
+	  }
+     }
+   else if (!strcasecmp(ext, "ps"))
+     {
+	int                 bx, by, bxx, byy;
+	int                 w, h;
+	int                 sx, sy;
+	int                 tx = 35, ty = 35;
+	int                 x, y;
+	unsigned char      *ptr;
+	int                 v;
+
+	f = fopen(file, "wb");
+
+	if (f == NULL)
+	   return 0;
+
+	w = im->rgb_width;
+	h = im->rgb_height;
+
+	switch (info->page_size)
+	  {
+	  case PAGE_SIZE_EXECUTIVE:
+	     sx = 540;
+	     sy = 720;
+	     break;
+	  case PAGE_SIZE_LETTER:
+	     sx = 612;
+	     sy = 792;
+	     break;
+	  case PAGE_SIZE_LEGAL:
+	     sx = 612;
+	     sy = 1008;
+	     break;
+	  case PAGE_SIZE_A4:
+	     sx = 595;
+	     sy = 842;
+	     break;
+	  case PAGE_SIZE_A3:
+	     sx = 842;
+	     sy = 1190;
+	     break;
+	  case PAGE_SIZE_A5:
+	     sx = 420;
+	     sy = 595;
+	     break;
+	  case PAGE_SIZE_FOLIO:
+	     sx = 612;
+	     sy = 936;
+	     break;
+	  }
+	bxx = ((sx - (tx * 2)) * info->scaling) >> 10;
+	byy = ((h * bxx / w) * info->scaling) >> 10;
+	if ((((sy - (ty * 2)) * info->scaling) >> 10) < byy)
+	  {
+	     byy = ((sy - (ty * 2)) * info->scaling) >> 10;
+	     bxx = ((w * byy / h) * info->scaling) >> 10;
+	  }
+	bx = tx + ((((sx - (tx * 2)) - bxx) * info->xjustification) >> 10);
+	by = ty + ((((sy - (ty * 2)) - byy) * info->yjustification) >> 10);
+	if (f)
+	  {
+	     fprintf(f, "%%!PS-Adobe-2.0 EPSF-2.0\n");
+	     fprintf(f, "%%%%Title: %s\n", file);
+	     fprintf(f, "%%%%Creator: Imlib by The Rasterman\n");
+	     fprintf(f, "%%%%BoundingBox: %i %i %i %i\n", bx, by, bxx, byy);
+	     fprintf(f, "%%%%Pages: 1\n");
+	     fprintf(f, "%%%%DocumentFonts:\n");
+	     fprintf(f, "%%%%EndComments\n");
+	     fprintf(f, "%%%%EndProlog\n");
+	     fprintf(f, "%%%%Page: 1 1\n");
+	     fprintf(f, "/origstate save def\n");
+	     fprintf(f, "20 dict begin\n");
+	     if (info->color)
+	       {
+		  fprintf(f, "/pix %i string def\n", w * 3);
+		  fprintf(f, "/grays %i string def\n", w);
+		  fprintf(f, "/npixls 0 def\n");
+		  fprintf(f, "/rgbindx 0 def\n");
+		  fprintf(f, "%i %i translate\n", bx, by);
+		  fprintf(f, "%i %i scale\n", bxx, byy);
+		  fprintf(f,
+			  "/colorimage where\n"
+			  "{ pop }\n"
+			  "{\n"
+			  "/colortogray {\n"
+			  "/rgbdata exch store\n"
+			  "rgbdata length 3 idiv\n"
+			  "/npixls exch store\n"
+			  "/rgbindx 0 store\n"
+			  "0 1 npixls 1 sub {\n"
+			  "grays exch\n"
+			  "rgbdata rgbindx       get 20 mul\n"
+			  "rgbdata rgbindx 1 add get 32 mul\n"
+			  "rgbdata rgbindx 2 add get 12 mul\n"
+			  "add add 64 idiv\n"
+			  "put\n"
+			  "/rgbindx rgbindx 3 add store\n"
+			  "} for\n"
+			  "grays 0 npixls getinterval\n"
+			  "} bind def\n"
+			  "/mergeprocs {\n"
+			  "dup length\n"
+			  "3 -1 roll\n"
+			  "dup\n"
+			  "length\n"
+			  "dup\n"
+			  "5 1 roll\n"
+			  "3 -1 roll\n"
+			  "add\n"
+			  "array cvx\n"
+			  "dup\n"
+			  "3 -1 roll\n"
+			  "0 exch\n"
+			  "putinterval\n"
+			  "dup\n"
+			  "4 2 roll\n"
+			  "putinterval\n"
+			  "} bind def\n"
+			  "/colorimage {\n"
+			  "pop pop\n"
+			  "{colortogray} mergeprocs\n"
+			  "image\n"
+			  "} bind def\n"
+			  "} ifelse\n");
+		  fprintf(f, "%i %i 8\n", w, h);
+		  fprintf(f, "[%i 0 0 -%i 0 %i]\n", w, h, h);
+		  fprintf(f, "{currentfile pix readhexstring pop}\n");
+		  fprintf(f, "false 3 colorimage\n");
+		  fprintf(f, "\n");
+		  ptr = im->rgb_data;
+		  for (y = 0; y < h; y++)
+		    {
+		       for (x = 0; x < w; x++)
+			 {
+			    v = (int)(*ptr++);
+			    if (v < 0x10)
+			       fprintf(f, "0%x", v);
+			    else
+			       fprintf(f, "%x", v);
+			    v = (int)(*ptr++);
+			    if (v < 0x10)
+			       fprintf(f, "0%x", v);
+			    else
+			       fprintf(f, "%x", v);
+			    v = (int)(*ptr++);
+			    if (v < 0x10)
+			       fprintf(f, "0%x", v);
+			    else
+			       fprintf(f, "%x", v);
+			 }
+		       fprintf(f, "\n");
+		    }
+	       }
+	     else
+	       {
+		  fprintf(f, "/pix %i string def\n", w);
+		  fprintf(f, "/grays %i string def\n", w);
+		  fprintf(f, "/npixls 0 def\n");
+		  fprintf(f, "/rgbindx 0 def\n");
+		  fprintf(f, "%i %i translate\n", bx, by);
+		  fprintf(f, "%i %i scale\n", bxx, byy);
+		  fprintf(f, "%i %i 8\n", w, h);
+		  fprintf(f, "[%i 0 0 -%i 0 %i]\n", w, h, h);
+		  fprintf(f, "{currentfile pix readhexstring pop}\n");
+		  fprintf(f, "image\n");
+		  fprintf(f, "\n");
+		  ptr = im->rgb_data;
+		  for (y = 0; y < h; y++)
+		    {
+		       for (x = 0; x < w; x++)
+			 {
+			    v = (int)(*ptr++);
+			    v += (int)(*ptr++);
+			    v += (int)(*ptr++);
+			    v /= 3;
+			    if (v < 0x10)
+			       fprintf(f, "0%x", v);
+			    else
+			       fprintf(f, "%x", v);
+			 }
+		       fprintf(f, "\n");
+		    }
+	       }
+	     fprintf(f, "\n");
+	     fprintf(f, "showpage\n");
+	     fprintf(f, "end\n");
+	     fprintf(f, "origstate restore\n");
+	     fprintf(f, "%%%%Trailer\n");
+	     fclose(f);
+	     return 1;
+	  }
+     }
+   else if ((!strcasecmp(ext, "jpeg")) || (!strcasecmp(ext, "jpg")))
+     {
+#ifdef HAVE_LIBJPEG
+	struct jpeg_compress_struct cinfo;
+	struct jpeg_error_mgr jerr;
+	JSAMPROW            row_pointer[1];
+	int                 row_stride;
+	int                 y;
+
+	f = fopen(file, "wb");
+	if (f)
+	  {
+	     cinfo.err = jpeg_std_error(&jerr);
+	     jpeg_create_compress(&cinfo);
+	     jpeg_stdio_dest(&cinfo, f);
+	     cinfo.image_width = im->rgb_width;
+	     cinfo.image_height = im->rgb_height;
+	     cinfo.input_components = 3;
+	     cinfo.in_color_space = JCS_RGB;
+	     jpeg_set_defaults(&cinfo);
+	     jpeg_set_quality(&cinfo, (100 * info->quality) >> 8, TRUE);
+	     jpeg_start_compress(&cinfo, TRUE);
+	     row_stride = cinfo.image_width * 3;
+	     while (cinfo.next_scanline < cinfo.image_height)
+	       {
+		  row_pointer[0] = im->rgb_data + (cinfo.next_scanline * row_stride);
+		  jpeg_write_scanlines(&cinfo, row_pointer, 1);
+	       }
+	     jpeg_finish_compress(&cinfo);
+	     fclose(f);
+	     return 1;
+	  }
+#endif
+     }
+   else if (!strcasecmp(ext, "png"))
+     {
+#ifdef HAVE_LIBPNG
+	png_structp         png_ptr;
+	png_infop           info_ptr;
+	unsigned char      *data, *ptr;
+	int                 x, y;
+	png_bytep           row_ptr;
+	png_color_8         sig_bit;
+
+	f = fopen(file, "wb");
+	if (f)
+	  {
+	     png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
+					       NULL, NULL, NULL);
+	     if (!png_ptr)
+	       {
+		  fclose(f);
+		  return 0;
+	       }
+	     info_ptr = png_create_info_struct(png_ptr);
+	     if (info_ptr == NULL)
+	       {
+		  fclose(f);
+		  png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
+		  return 0;
+	       }
+	     if (setjmp(png_ptr->jmpbuf))
+	       {
+		  fclose(f);
+		  png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
+		  return 0;
+	       }
+	     png_init_io(png_ptr, f);
+	     png_set_IHDR(png_ptr, info_ptr, im->rgb_width, im->rgb_height, 8,
+			  PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
+			  PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+	     sig_bit.red = 8;
+	     sig_bit.green = 8;
+	     sig_bit.blue = 8;
+	     sig_bit.alpha = 8;
+	     png_set_sBIT(png_ptr, info_ptr, &sig_bit);
+	     png_write_info(png_ptr, info_ptr);
+	     png_set_shift(png_ptr, &sig_bit);
+	     png_set_packing(png_ptr);
+	     data = malloc(im->rgb_width * 4);
+	     if (!data)
+	       {
+		  fclose(f);
+		  png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
+		  return 0;
+	       }
+	     for (y = 0; y < im->rgb_height; y++)
+	       {
+		  ptr = im->rgb_data + (y * im->rgb_width * 3);
+		  for (x = 0; x < im->rgb_width; x++)
+		    {
+		       data[(x << 2) + 0] = *ptr++;
+		       data[(x << 2) + 1] = *ptr++;
+		       data[(x << 2) + 2] = *ptr++;
+		       if ((data[(x << 2) + 0] == im->shape_color.r) &&
+			   (data[(x << 2) + 1] == im->shape_color.g) &&
+			   (data[(x << 2) + 2] == im->shape_color.b))
+			  data[(x << 2) + 3] = 0;
+		       else
+			  data[(x << 2) + 3] = 255;
+		    }
+		  row_ptr = data;
+		  png_write_rows(png_ptr, &row_ptr, 1);
+	       }
+	     free(data);
+	     png_write_end(png_ptr, info_ptr);
+	     png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
+
+	     fclose(f);
+	     return 1;
+	  }
+#endif
+     }
+   else if ((!strcasecmp(ext, "tiff")) || (!strcasecmp(ext, "tif")))
+     {
+#ifdef HAVE_LIBTIFF
+	TIFF               *tif;
+	unsigned char      *ptr, *data;
+	int                 x, y;
+	int                 w;
+
+	tif = TIFFOpen(file, "w");
+	if (tif)
+	  {
+	     TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, im->rgb_width);
+	     TIFFSetField(tif, TIFFTAG_IMAGELENGTH, im->rgb_height);
+	     TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
+	     TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
+	     TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+	     TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
+	     {
+		TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
+		TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
+		w = TIFFScanlineSize(tif);
+		TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP,
+			     TIFFDefaultStripSize(tif, -1));
+		for (y = 0; y < im->rgb_height; y++)
+		  {
+		     data = im->rgb_data + (y * im->rgb_width * 3);
+		     TIFFWriteScanline(tif, data, y, 0);
+		  }
+	     }
+	     TIFFClose(tif);
+	     return 1;
+	  }
+#endif
+     }
+   if (id->fallback)
+     {
+	f = open_helper("%C/convert pnm:- %s", file, "wb");
+	if (f)
+	  {
+	     if (!fprintf(f, "P6\n# Created by Imlib\n%i %i\n255\n", im->rgb_width, im->rgb_height))
+	       {
+		  close_helper(f);
+		  return 0;
+	       }
+	     if (!fwrite(im->rgb_data, 1, (im->rgb_width * im->rgb_height * 3), f))
+	       {
+		  close_helper(f);
+		  return 0;
+	       }
+	     if (close_helper(f))
+		return 0;
+	     return 1;
+	  }
+
+	if (!strcasecmp(ext, "jpeg"))
+	   g_snprintf(cmd, sizeof(cmd), "%%H -quality %i -progressive -outfile %%s", 100 * info->quality / 256);
+	else if (!strcasecmp(ext, "jpg"))
+	   g_snprintf(cmd, sizeof(cmd), "%%H -quality %i -progressive -outfile %%s", 100 * info->quality / 256);
+	else if (!strcasecmp(ext, "bmp"))
+	   strcpy(cmd, "%Q %N/ppmtobmp >%s");
+	else if (!strcasecmp(ext, "gif"))
+	   strcpy(cmd, "%Q %N/ppmtogif -interlace >%s");
+	else if (!strcasecmp(ext, "ilbm"))
+	   strcpy(cmd, "%N/ppmtoilbm -24if -hires -lace -compress >%s");
+	else if (!strcasecmp(ext, "ilb"))
+	   strcpy(cmd, "%N/ppmtoilbm -24if -hires -lace -compress >%s");
+	else if (!strcasecmp(ext, "iff"))
+	   strcpy(cmd, "%N/ppmtoilbm -24if -hires -lace -compress >%s");
+	else if (!strcasecmp(ext, "icr"))
+	   strcpy(cmd, "%N/ppmtoicr >%s");
+	else if (!strcasecmp(ext, "map"))
+	   strcpy(cmd, "%N/ppmtomap >%s");
+	else if (!strcasecmp(ext, "mit"))
+	   strcpy(cmd, "%N/ppmtomitsu -sharpness 4 >%s");
+	else if (!strcasecmp(ext, "mitsu"))
+	   strcpy(cmd, "%N/ppmtomitsu -sharpness 4 >%s");
+	else if (!strcasecmp(ext, "pcx"))
+	   strcpy(cmd, "%N/ppmtopcx -24bit -packed >%s");
+	else if (!strcasecmp(ext, "pgm"))
+	   strcpy(cmd, "%N/ppmtopgm >%s");
+	else if (!strcasecmp(ext, "pi1"))
+	   strcpy(cmd, "%N/ppmtopi1 >%s");
+	else if (!strcasecmp(ext, "pic"))
+	   strcpy(cmd, "%Q %N/ppmtopict >%s");
+	else if (!strcasecmp(ext, "pict"))
+	   strcpy(cmd, "%Q %N/ppmtopict >%s");
+	else if (!strcasecmp(ext, "pj"))
+	   strcpy(cmd, "%N/ppmtopj >%s");
+	else if (!strcasecmp(ext, "pjxl"))
+	   strcpy(cmd, "%N/ppmtopjxl >%s");
+	else if (!strcasecmp(ext, "puz"))
+	   strcpy(cmd, "%N/ppmtopuzz >%s");
+	else if (!strcasecmp(ext, "puzz"))
+	   strcpy(cmd, "%N/ppmtopuzz >%s");
+	else if (!strcasecmp(ext, "rgb3"))
+	   strcpy(cmd, "%N/ppmtorgb3 >%s");
+	else if (!strcasecmp(ext, "six"))
+	   strcpy(cmd, "%N/ppmtosixel >%s");
+	else if (!strcasecmp(ext, "sixel"))
+	   strcpy(cmd, "%N/ppmtosizel >%s");
+	else if (!strcasecmp(ext, "tga"))
+	   strcpy(cmd, "%N/ppmtotga -rgb >%s");
+	else if (!strcasecmp(ext, "targa"))
+	   strcpy(cmd, "%N/ppmtotga -rgb >%s");
+	else if (!strcasecmp(ext, "uil"))
+	   strcpy(cmd, "%N/ppmtouil >%s");
+	else if (!strcasecmp(ext, "xpm"))
+	   strcpy(cmd, "%Q %N/ppmtoxpm >%s");
+	else if (!strcasecmp(ext, "yuv"))
+	   strcpy(cmd, "%N/ppmtoyuv >%s");
+	else if (!strcasecmp(ext, "png"))
+	   strcpy(cmd, "%N/pnmtopng >%s");
+	else if (!strcasecmp(ext, "ps"))
+	   strcpy(cmd, "%N/pnmtops -center -scale 100 >%s");
+	else if (!strcasecmp(ext, "rast"))
+	   strcpy(cmd, "%N/pnmtorast -rle >%s");
+	else if (!strcasecmp(ext, "ras"))
+	   strcpy(cmd, "%N/pnmtorast -rle >%s");
+	else if (!strcasecmp(ext, "sgi"))
+	   strcpy(cmd, "%N/pnmtosgi >%s");
+	else if (!strcasecmp(ext, "sir"))
+	   strcpy(cmd, "%N/pnmtosir >%s");
+	else if (!strcasecmp(ext, "tif"))
+	   strcpy(cmd, "%N/pnmtotiff -lzw >%s");
+	else if (!strcasecmp(ext, "tiff"))
+	   strcpy(cmd, "%N/pnmtotiff -lzw >%s");
+	else if (!strcasecmp(ext, "xwd"))
+	   strcpy(cmd, "%N/pnmtoxwd >%s");
+	else
+	   ext = "";
+	if (ext[0])
+	  {
+	     f = open_helper(cmd, file, "wb");
+	     if (f)
+	       {
+		  if (!fprintf(f, "P6\n# Created by Imlib\n%i %i\n255\n", im->rgb_width, im->rgb_height))
+		    {
+		       close_helper(f);
+		       return 0;
+		    }
+		  if (!fwrite(im->rgb_data, 1, (im->rgb_width * im->rgb_height * 3), f))
+		    {
+		       close_helper(f);
+		       return 0;
+		    }
+		  if (close_helper(f))
+		     return 0;
+		  return 1;
+	       }
+	  }
+     }
+   return 0;
+}
diff --git a/src/gdk_imlib/utils.c b/src/gdk_imlib/utils.c
new file mode 100644
index 0000000000..961ec908f4
--- /dev/null
+++ b/src/gdk_imlib/utils.c
@@ -0,0 +1,1518 @@
+#define _GNU_SOURCE
+
+#include "gdk_imlib.h"
+#include "gdk_imlib_private.h"
+
+void
+gcalc_map_tables(GdkImlibImage * im)
+{
+   int                 i;
+   double              g, b, c, ii, v;
+
+   if (!im)
+      return;
+
+   g = ((double)im->mod.gamma) / 256;
+   b = ((double)im->mod.brightness) / 256;
+   c = ((double)im->mod.contrast) / 256;
+   if (g < 0.01)
+      g = 0.01;
+
+   for (i = 0; i < 256; i++)
+     {
+	ii = ((double)i) / 256;
+	v = ((ii - 0.5) * c) + 0.5 + (b - 1);
+	if (v > 0)
+	   v = pow(((ii - 0.5) * c) + 0.5 + (b - 1), 1 / g) * 256;
+	else
+	   v = 0;
+	if (v > 255)
+	   v = 255;
+	else if (v < 0)
+	   v = 0;
+	im->rmap[i] = (unsigned char)v;
+	im->gmap[i] = (unsigned char)v;
+	im->bmap[i] = (unsigned char)v;
+     }
+   g = ((double)im->rmod.gamma) / 256;
+   b = ((double)im->rmod.brightness) / 256;
+   c = ((double)im->rmod.contrast) / 256;
+   if (g < 0.01)
+      g = 0.01;
+
+   for (i = 0; i < 256; i++)
+     {
+	ii = ((double)im->rmap[i]) / 256;
+	v = ((ii - 0.5) * c) + 0.5 + (b - 1);
+	if (v > 0)
+	   v = pow(((ii - 0.5) * c) + 0.5 + (b - 1), 1 / g) * 256;
+	else
+	   v = 0;
+	if (v > 255)
+	   v = 255;
+	else if (v < 0)
+	   v = 0;
+	im->rmap[i] = (unsigned char)v;
+     }
+   g = ((double)im->gmod.gamma) / 256;
+   b = ((double)im->gmod.brightness) / 256;
+   c = ((double)im->gmod.contrast) / 256;
+   if (g < 0.01)
+      g = 0.01;
+
+   for (i = 0; i < 256; i++)
+     {
+	ii = ((double)im->gmap[i]) / 256;
+	v = ((ii - 0.5) * c) + 0.5 + (b - 1);
+	if (v > 0)
+	   v = pow(((ii - 0.5) * c) + 0.5 + (b - 1), 1 / g) * 256;
+	else
+	   v = 0;
+	if (v > 255)
+	   v = 255;
+	else if (v < 0)
+	   v = 0;
+	im->gmap[i] = (unsigned char)v;
+     }
+   g = ((double)im->bmod.gamma) / 256;
+   b = ((double)im->bmod.brightness) / 256;
+   c = ((double)im->bmod.contrast) / 256;
+   if (g < 0.01)
+      g = 0.01;
+   for (i = 0; i < 256; i++)
+     {
+	ii = ((double)im->bmap[i]) / 256;
+	v = ((ii - 0.5) * c) + 0.5 + (b - 1);
+	if (v > 0)
+	   v = pow(((ii - 0.5) * c) + 0.5 + (b - 1), 1 / g) * 256;
+	else
+	   v = 0;
+	if (v > 255)
+	   v = 255;
+	else if (v < 0)
+	   v = 0;
+	im->bmap[i] = (unsigned char)v;
+     }
+   gdirty_pixmaps(im);
+}
+
+gint
+gdk_imlib_load_file_to_pixmap(char *filename, GdkPixmap ** pmap, GdkBitmap ** mask)
+{
+   GdkImlibImage      *im;
+
+   im = gdk_imlib_load_image(filename);
+   if (!im)
+     {
+	if (pmap)
+	   *pmap = NULL;
+	if (mask)
+	   *mask = NULL;
+	return 0;
+     }
+   if (!gdk_imlib_render(im, im->rgb_width, im->rgb_height))
+     {
+	gdk_imlib_destroy_image(im);
+	if (pmap)
+	   *pmap = NULL;
+	if (mask)
+	   *mask = NULL;
+	return 0;
+     }
+   if (pmap)
+      *pmap = gdk_imlib_move_image(im);
+   if (mask)
+      *mask = gdk_imlib_move_mask(im);
+   gdk_imlib_destroy_image(im);
+   return 1;
+}
+
+void
+gdk_imlib_set_image_modifier(GdkImlibImage * im, GdkImlibColorModifier * mod)
+{
+   if (!im || !mod)
+      return;
+   im->mod.gamma = mod->gamma;
+   im->mod.brightness = mod->brightness;
+   im->mod.contrast = mod->contrast;
+   gcalc_map_tables(im);
+}
+
+void
+gdk_imlib_set_image_red_modifier(GdkImlibImage * im, GdkImlibColorModifier * mod)
+{
+   if (!im || !mod)
+      return;
+   im->rmod.gamma = mod->gamma;
+   im->rmod.brightness = mod->brightness;
+   im->rmod.contrast = mod->contrast;
+   gcalc_map_tables(im);
+}
+
+void
+gdk_imlib_set_image_green_modifier(GdkImlibImage * im, GdkImlibColorModifier * mod)
+{
+   if (!im || !mod)
+      return;
+   im->gmod.gamma = mod->gamma;
+   im->gmod.brightness = mod->brightness;
+   im->gmod.contrast = mod->contrast;
+   gcalc_map_tables(im);
+}
+
+void
+gdk_imlib_set_image_blue_modifier(GdkImlibImage * im, GdkImlibColorModifier * mod)
+{
+   if (!im | !mod)
+      return;
+   im->bmod.gamma = mod->gamma;
+   im->bmod.brightness = mod->brightness;
+   im->bmod.contrast = mod->contrast;
+   gcalc_map_tables(im);
+}
+
+void
+gdk_imlib_get_image_modifier(GdkImlibImage * im, GdkImlibColorModifier * mod)
+{
+   if (!im || !mod)
+      return;
+   mod->gamma = im->mod.gamma;
+   mod->brightness = im->mod.brightness;
+   mod->contrast = im->mod.contrast;
+   gcalc_map_tables(im);
+}
+
+void
+gdk_imlib_get_image_red_modifier(GdkImlibImage * im, GdkImlibColorModifier * mod)
+{
+   if (!im || !mod)
+      return;
+   mod->gamma = im->rmod.gamma;
+   mod->brightness = im->rmod.brightness;
+   mod->contrast = im->rmod.contrast;
+}
+
+void
+gdk_imlib_get_image_green_modifier(GdkImlibImage * im, GdkImlibColorModifier * mod)
+{
+   if (!im || !mod)
+      return;
+   mod->gamma = im->gmod.gamma;
+   mod->brightness = im->gmod.brightness;
+   mod->contrast = im->gmod.contrast;
+}
+
+void
+gdk_imlib_get_image_blue_modifier(GdkImlibImage * im, GdkImlibColorModifier * mod)
+{
+   if (!im || !mod)
+      return;
+   mod->gamma = im->bmod.gamma;
+   mod->brightness = im->bmod.brightness;
+   mod->contrast = im->bmod.contrast;
+}
+
+void
+gdk_imlib_set_image_red_curve(GdkImlibImage * im, unsigned char *mod)
+{
+   int                 i;
+
+   if (!im || !mod)
+      return;
+   for (i = 0; i < 256; i++)
+      im->rmap[i] = mod[i];
+   gdirty_pixmaps(im);
+   im->mod.contrast = 257;
+}
+
+void
+gdk_imlib_set_image_green_curve(GdkImlibImage * im, unsigned char *mod)
+{
+   int                 i;
+
+   if (!im || !mod)
+      return;
+   for (i = 0; i < 256; i++)
+      im->gmap[i] = mod[i];
+   gdirty_pixmaps(im);
+   im->mod.contrast = 257;
+}
+
+void
+gdk_imlib_set_image_blue_curve(GdkImlibImage * im, unsigned char *mod)
+{
+   int                 i;
+
+   if (!im || !mod)
+      return;
+   for (i = 0; i < 256; i++)
+      im->bmap[i] = mod[i];
+   gdirty_pixmaps(im);
+   im->mod.contrast = 257;
+}
+
+void
+gdk_imlib_get_image_red_curve(GdkImlibImage * im, unsigned char *mod)
+{
+   int                 i;
+
+   if ((!im) || (!mod))
+      return;
+   for (i = 0; i < 256; i++)
+      mod[i] = im->rmap[i];
+}
+
+void
+gdk_imlib_get_image_green_curve(GdkImlibImage * im, unsigned char *mod)
+{
+   int                 i;
+
+   if (!im || !mod)
+      return;
+   for (i = 0; i < 256; i++)
+      mod[i] = im->gmap[i];
+}
+
+void
+gdk_imlib_get_image_blue_curve(GdkImlibImage * im, unsigned char *mod)
+{
+   int                 i;
+
+   if (!im || !mod)
+      return;
+   for (i = 0; i < 256; i++)
+      mod[i] = im->bmap[i];
+}
+
+void
+gdk_imlib_apply_modifiers_to_rgb(GdkImlibImage * im)
+{
+   int                 x, y;
+   unsigned char      *ptr;
+
+   if (!im)
+      return;
+   ptr = im->rgb_data;
+   for (y = 0; y < im->rgb_height; y++)
+     {
+	for (x = 0; x < im->rgb_width; x++)
+	  {
+	     *ptr = im->rmap[*ptr];
+	     ptr++;
+	     *ptr = im->gmap[*ptr];
+	     ptr++;
+	     *ptr = im->bmap[*ptr];
+	     ptr++;
+	  }
+     }
+   im->mod.gamma = 256;
+   im->mod.brightness = 256;
+   im->mod.contrast = 256;
+   im->rmod.gamma = 256;
+   im->rmod.brightness = 256;
+   im->rmod.contrast = 256;
+   im->gmod.gamma = 256;
+   im->gmod.brightness = 256;
+   im->gmod.contrast = 256;
+   im->bmod.gamma = 256;
+   im->bmod.brightness = 256;
+   im->bmod.contrast = 256;
+   gcalc_map_tables(im);
+   gdirty_images(im);
+   gdirty_pixmaps(im);
+}
+
+void
+gdk_imlib_crop_image(GdkImlibImage * im, gint x, gint y, gint w, gint h)
+{
+   unsigned char      *data;
+   int                 xx, yy, w3, w4;
+   unsigned char      *ptr1, *ptr2;
+
+   if (!im)
+      return;
+   if (x < 0)
+     {
+	w += x;
+	x = 0;
+     }
+   if (y < 0)
+     {
+	h += y;
+	y = 0;
+     }
+   if (x >= im->rgb_width)
+      return;
+   if (y >= im->rgb_height)
+      return;
+   if (w <= 0)
+      return;
+   if (h <= 0)
+      return;
+   if (x + w > im->rgb_width)
+      w = im->rgb_width - x;
+   if (y + h > im->rgb_height)
+      h = im->rgb_height - y;
+   if (w <= 0)
+      return;
+   if (h <= 0)
+      return;
+
+   w3 = im->rgb_width * 3;
+   w4 = (im->rgb_width - w) * 3;
+   data = malloc(w * h * 3);
+   if (data == NULL)
+      return;
+   ptr1 = im->rgb_data + (y * w3) + (x * 3);
+   ptr2 = data;
+   for (yy = 0; yy < h; yy++)
+     {
+	for (xx = 0; xx < w; xx++)
+	  {
+	     *ptr2++ = *ptr1++;
+	     *ptr2++ = *ptr1++;
+	     *ptr2++ = *ptr1++;
+	  }
+	ptr1 += w4;
+     }
+   free(im->rgb_data);
+   im->rgb_data = data;
+   if (im->border.left > x)
+      im->border.left = im->border.left - x;
+   else
+      im->border.left = 0;
+   if (im->border.top > y)
+      im->border.top = im->border.top - y;
+   else
+      im->border.top = 0;
+   if (im->rgb_width - im->border.right < x + w)
+      im->border.right = im->border.right - (im->rgb_width - (x + w));
+   else
+      im->border.right = 0;
+   if (im->rgb_height - im->border.bottom < y + h)
+      im->border.bottom = im->border.bottom - (im->rgb_height - (y + h));
+   else
+      im->border.bottom = 0;
+   im->rgb_width = w;
+   im->rgb_height = h;
+   gdirty_images(im);
+   gdirty_pixmaps(im);
+}
+
+void
+gdk_imlib_changed_image(GdkImlibImage * im)
+{
+   if (!im)
+      return;
+   gdirty_images(im);
+   gdirty_pixmaps(im);
+}
+
+void
+gdk_imlib_apply_image(GdkImlibImage * im, GdkWindow * p)
+{
+   GdkPixmap          *pp, *mm;
+   int                 w, h;
+
+   if (!im || !p)
+      return;
+   gdk_window_get_size(p, &w, &h);
+   if (w <= 0 || h <= 0)
+      return;
+   gdk_imlib_render(im, w, h);
+   pp = gdk_imlib_move_image(im);
+   mm = gdk_imlib_move_mask(im);
+   gdk_window_set_back_pixmap(p, pp, 0);
+   if (mm)
+      gdk_window_shape_combine_mask(p, mm, 0, 0);
+   gdk_window_clear(p);
+   gdk_imlib_free_pixmap(pp);
+}
+
+void
+gdk_imlib_paste_image(GdkImlibImage * im, GdkWindow * p, gint x, gint y, gint w, gint h)
+{
+   GdkGC              *gc;
+   GdkPixmap          *pp, *mm;
+
+   if (!im || !p)
+      return;
+   if ((w <= 0) || (h <= 0))
+      return;
+   gc = gdk_gc_new(p);
+   gdk_imlib_render(im, w, h);
+   pp = gdk_imlib_move_image(im);
+   mm = gdk_imlib_move_mask(im);
+   if (mm)
+     {
+	gdk_gc_set_clip_mask(gc, mm);
+	gdk_gc_set_clip_origin(gc, x, y);
+     }
+   gdk_draw_pixmap(p, gc, pp, 0, 0, x, y, w, h);
+   gdk_imlib_free_pixmap(pp);
+   gdk_gc_destroy(gc);
+}
+
+void
+gdk_imlib_paste_image_border(GdkImlibImage * im, GdkWindow * p, gint x, gint y, gint w, gint h)
+{
+   GdkGC              *gc;
+   GdkPixmap          *pp, *mm;
+
+   if (!im)
+      return;
+
+   if (w <= 0 || h <= 0)
+      return;
+   gc = gdk_gc_new(p);
+   gdk_imlib_render(im, w, h);
+   pp = gdk_imlib_move_image(im);
+   mm = gdk_imlib_move_mask(im);
+   if (mm)
+     {
+	gdk_gc_set_clip_mask(gc, mm);
+	gdk_gc_set_clip_origin(gc, x, y);
+     }
+   if ((w <= (im->border.left + im->border.right)) ||
+       (h <= (im->border.top + im->border.bottom)))
+      gdk_draw_pixmap(p, gc, pp, 0, 0, x, y, w, h);
+   else
+     {
+	gdk_draw_pixmap(p, gc, pp, 0, 0, x, y, w, im->border.top);
+	gdk_draw_pixmap(p, gc, pp, 0, h - im->border.bottom,
+			x, y + (h - im->border.bottom),
+			w, im->border.bottom);
+	gdk_draw_pixmap(p, gc, pp, 0, im->border.top,
+			x, y + im->border.top,
+		   im->border.left, h - (im->border.top + im->border.bottom));
+	gdk_draw_pixmap(p, gc, pp, w - im->border.right, h - im->border.bottom,
+		      x + (w - im->border.right), y + (h - im->border.bottom),
+		  im->border.right, h - (im->border.top + im->border.bottom));
+     }
+   gdk_imlib_free_pixmap(pp);
+   gdk_gc_destroy(gc);
+}
+
+void
+gdk_imlib_flip_image_horizontal(GdkImlibImage * im)
+{
+   unsigned char      *ptr1, *ptr2, r, rr;
+   int                 x, y;
+   int                 w3;
+
+   if (!im)
+      return;
+   w3 = im->rgb_width * 3;
+   for (y = 0; y < im->rgb_height; y++)
+     {
+	ptr1 = im->rgb_data + (y * w3);
+	ptr2 = im->rgb_data + (y * w3) + w3 - 3;
+	for (x = 0; x < im->rgb_width >> 1; x++)
+	  {
+	     r = *ptr1;
+	     rr = *ptr2;
+	     *ptr2++ = r;
+	     *ptr1++ = rr;
+
+	     r = *ptr1;
+	     rr = *ptr2;
+	     *ptr2++ = r;
+	     *ptr1++ = rr;
+
+	     r = *ptr1;
+	     rr = *ptr2;
+	     *ptr2 = r;
+	     *ptr1++ = rr;
+
+	     ptr2 -= 5;
+	  }
+     }
+   w3 = im->border.left;
+   im->border.left = im->border.right;
+   im->border.right = w3;
+   gdirty_images(im);
+   gdirty_pixmaps(im);
+}
+
+void
+gdk_imlib_flip_image_vertical(GdkImlibImage * im)
+{
+   unsigned char      *ptr1, *ptr2, r, rr;
+   int                 x, y, yy;
+   int                 w3;
+
+   if (!im)
+      return;
+
+   w3 = im->rgb_width * 3;
+   for (yy = im->rgb_height - 1, y = 0; y < im->rgb_height >> 1; y++, yy--)
+     {
+	ptr1 = im->rgb_data + (y * w3);
+	ptr2 = im->rgb_data + (yy * w3);
+	for (x = 0; x < im->rgb_width; x++)
+	  {
+	     r = *ptr1;
+	     rr = *ptr2;
+	     *ptr2++ = r;
+	     *ptr1++ = rr;
+	     r = *ptr1;
+	     rr = *ptr2;
+	     *ptr2++ = r;
+	     *ptr1++ = rr;
+	     r = *ptr1;
+	     rr = *ptr2;
+	     *ptr2++ = r;
+	     *ptr1++ = rr;
+	  }
+     }
+   w3 = im->border.top;
+   im->border.top = im->border.bottom;
+   im->border.bottom = w3;
+   gdirty_images(im);
+   gdirty_pixmaps(im);
+}
+
+void
+gdk_imlib_rotate_image(GdkImlibImage * im, gint d)
+{
+   unsigned char      *data;
+   int                 x, y, w3, w4;
+   unsigned char      *ptr1, *ptr2;
+
+   if (!im)
+      return;
+   w3 = im->rgb_width * 3;
+   w4 = im->rgb_height * 3;
+
+   data = malloc(im->rgb_width * im->rgb_height * 3);
+   if (data == NULL)
+      return;
+
+   for (y = 0; y < im->rgb_height; y++)
+     {
+	ptr1 = im->rgb_data + (y * w3);
+	ptr2 = data + (y * 3);
+	for (x = 0; x < im->rgb_width; x++)
+	  {
+	     *ptr2++ = *ptr1++;
+	     *ptr2++ = *ptr1++;
+	     *ptr2 = *ptr1++;
+	     ptr2 += w4 - 2;
+	  }
+     }
+   free(im->rgb_data);
+   im->rgb_data = data;
+   w3 = im->rgb_width;
+   im->rgb_width = im->rgb_height;
+   im->rgb_height = w3;
+   w3 = im->border.top;
+   im->border.top = im->border.left;
+   im->border.left = w3;
+   w3 = im->border.bottom;
+   im->border.bottom = im->border.right;
+   im->border.right = w3;
+   gdirty_images(im);
+   gdirty_pixmaps(im);
+}
+
+GdkImlibImage      *
+gdk_imlib_create_image_from_data(unsigned char *data, unsigned char *alpha, gint w, gint h)
+{
+   GdkImlibImage      *im;
+   char                s[128];
+
+   if (!data || w <= 0 || h <= 0)
+      return NULL;
+
+   im = malloc(sizeof(GdkImlibImage));
+   if (!im)
+      return NULL;
+
+   im->rgb_width = w;
+   im->rgb_height = h;
+   im->rgb_data = malloc(im->rgb_width * im->rgb_height * 3);
+   if (!im->rgb_data)
+     {
+	free(im);
+	return NULL;
+     }
+
+   memcpy(im->rgb_data, data, im->rgb_width * im->rgb_height * 3);
+/*      im->alpha_data=alpha; */
+   im->alpha_data = NULL;
+   g_snprintf(s, sizeof(s), "creat_%x_%x", (int)time(NULL), (int)rand());
+   im->filename = malloc(strlen(s) + 1);
+   if (im->filename)
+      strcpy(im->filename, s);
+   im->width = 0;
+   im->height = 0;
+   im->shape_color.r = -1;
+   im->shape_color.g = -1;
+   im->shape_color.b = -1;
+   im->border.left = 0;
+   im->border.right = 0;
+   im->border.top = 0;
+   im->border.bottom = 0;
+   im->pixmap = NULL;
+   im->shape_mask = NULL;
+   im->cache = 1;
+   im->mod.gamma = id->mod.gamma;
+   im->mod.brightness = id->mod.brightness;
+   im->mod.contrast = id->mod.contrast;
+   im->rmod.gamma = id->rmod.gamma;
+   im->rmod.brightness = id->rmod.brightness;
+   im->rmod.contrast = id->rmod.contrast;
+   im->gmod.gamma = id->gmod.gamma;
+   im->gmod.brightness = id->gmod.brightness;
+   im->gmod.contrast = id->gmod.contrast;
+   im->bmod.gamma = id->bmod.gamma;
+   im->bmod.brightness = id->bmod.brightness;
+   im->bmod.contrast = id->bmod.contrast;
+   if (id->cache.on_image)
+      gadd_image(im, im->filename);
+   gcalc_map_tables(im);
+   return im;
+}
+
+GdkImlibImage      *
+gdk_imlib_clone_image(GdkImlibImage * im)
+{
+   GdkImlibImage      *im2;
+   char               *s;
+
+   if (!im)
+      return NULL;
+   im2 = malloc(sizeof(GdkImlibImage));
+   if (!im2)
+      return NULL;
+   im2->rgb_width = im->rgb_width;
+   im2->rgb_height = im->rgb_height;
+   im2->rgb_data = malloc(im2->rgb_width * im2->rgb_height * 3);
+   if (!im2->rgb_data)
+     {
+	free(im2);
+	return NULL;
+     }
+
+   memcpy(im2->rgb_data, im->rgb_data, im2->rgb_width * im2->rgb_height * 3);
+   if (im->alpha_data)
+     {
+	im2->alpha_data = malloc(im2->rgb_width * im2->rgb_height);
+	if (!im2->alpha_data)
+	  {
+	     free(im2->rgb_data);
+	     free(im2);
+	     return NULL;
+	  }
+	memcpy(im2->alpha_data, im->alpha_data, im2->rgb_width * im2->rgb_height);
+     }
+   else
+      im2->alpha_data = NULL;
+   s = malloc(strlen(im->filename) + 320);
+   if (s)
+     {
+	g_snprintf(s, sizeof(s), "%s_%x_%x", im->filename, (int)time(NULL), (int)rand());
+	im2->filename = malloc(strlen(s) + 1);
+	if (im2->filename)
+	   strcpy(im2->filename, s);
+	free(s);
+     }
+   else
+      im2->filename = NULL;
+   im2->width = 0;
+   im2->height = 0;
+   im2->shape_color.r = im->shape_color.r;
+   im2->shape_color.g = im->shape_color.g;
+   im2->shape_color.b = im->shape_color.b;
+   im2->border.left = im->border.left;
+   im2->border.right = im->border.right;
+   im2->border.top = im->border.top;
+   im2->border.bottom = im->border.bottom;
+   im2->pixmap = NULL;
+   im2->shape_mask = NULL;
+   im2->cache = 1;
+   im2->mod.gamma = im->mod.gamma;
+   im2->mod.brightness = im->mod.brightness;
+   im2->mod.contrast = im->mod.contrast;
+   im2->rmod.gamma = im->rmod.gamma;
+   im2->rmod.brightness = im->rmod.brightness;
+   im2->rmod.contrast = im->rmod.contrast;
+   im2->gmod.gamma = im->gmod.gamma;
+   im2->gmod.brightness = im->gmod.brightness;
+   im2->gmod.contrast = im->gmod.contrast;
+   im2->bmod.gamma = im->bmod.gamma;
+   im2->bmod.brightness = im->bmod.brightness;
+   im2->bmod.contrast = im->bmod.contrast;
+   gcalc_map_tables(im2);
+   if (id->cache.on_image)
+      gadd_image(im2, im2->filename);
+   return im2;
+}
+
+GdkImlibImage      *
+gdk_imlib_clone_scaled_image(GdkImlibImage * im, int w, int h)
+{
+   GdkImlibImage      *im2;
+   char               *s;
+
+   if (!im || w <= 0 || h <= 0)
+      return NULL;
+
+   im2 = malloc(sizeof(GdkImlibImage));
+   if (!im2)
+      return NULL;
+   im2->rgb_width = w;
+   im2->rgb_height = h;
+   im2->rgb_data = malloc(w * h * 3);
+   if (!im2->rgb_data)
+     {
+	free(im2);
+	return NULL;
+     }
+   {
+      int                 x, y, *xarray;
+      unsigned char     **yarray, *ptr, *ptr2, *ptr22;
+      int                 l, r, m, pos, inc, w3;
+
+      xarray = malloc(sizeof(int) * w);
+
+      if (!xarray)
+	{
+	   fprintf(stderr, "ERROR: Cannot allocate X co-ord buffer\n");
+	   free(im2->rgb_data);
+	   free(im2);
+	   return NULL;
+	}
+      yarray = malloc(sizeof(unsigned char *) * h);
+
+      if (!yarray)
+	{
+	   fprintf(stderr, "ERROR: Cannot allocate Y co-ord buffer\n");
+	   free(xarray);
+	   free(im2->rgb_data);
+	   free(im2);
+	   return NULL;
+	}
+      ptr22 = im->rgb_data;
+      w3 = im->rgb_width * 3;
+      inc = 0;
+      if (w < im->border.left + im->border.right)
+	{
+	   l = w >> 1;
+	   r = w - l;
+	   m = 0;
+	}
+      else
+	{
+	   l = im->border.left;
+	   r = im->border.right;
+	   m = w - l - r;
+	}
+      if (m > 0)
+	 inc = ((im->rgb_width - im->border.left - im->border.right) << 16) / m;
+      pos = 0;
+      if (l)
+	{
+	   for (x = 0; x < l; x++)
+	     {
+		xarray[x] = (pos >> 16) + (pos >> 16) + (pos >> 16);
+		pos += 0x10000;
+	     }
+	}
+      if (m)
+	{
+	   for (x = l; x < l + m; x++)
+	     {
+		xarray[x] = (pos >> 16) + (pos >> 16) + (pos >> 16);
+		pos += inc;
+	     }
+	}
+      pos = (im->rgb_width - r) << 16;
+      for (x = w - r; x < w; x++)
+	{
+	   xarray[x] = (pos >> 16) + (pos >> 16) + (pos >> 16);
+	   pos += 0x10000;
+	}
+
+      if (h < im->border.top + im->border.bottom)
+	{
+	   l = h >> 1;
+	   r = h - l;
+	   m = 0;
+	}
+      else
+	{
+	   l = im->border.top;
+	   r = im->border.bottom;
+	   m = h - l - r;
+	}
+      if (m > 0)
+	 inc = ((im->rgb_height - im->border.top - im->border.bottom) << 16) / m;
+      pos = 0;
+      for (x = 0; x < l; x++)
+	{
+	   yarray[x] = ptr22 + ((pos >> 16) * w3);
+	   pos += 0x10000;
+	}
+      if (m)
+	{
+	   for (x = l; x < l + m; x++)
+	     {
+		yarray[x] = ptr22 + ((pos >> 16) * w3);
+		pos += inc;
+	     }
+	}
+      pos = (im->rgb_height - r) << 16;
+      for (x = h - r; x < h; x++)
+	{
+	   yarray[x] = ptr22 + ((pos >> 16) * w3);
+	   pos += 0x10000;
+	}
+
+      ptr = im2->rgb_data;
+      for (y = 0; y < h; y++)
+	{
+	   for (x = 0; x < w; x++)
+	     {
+		ptr2 = yarray[y] + xarray[x];
+		*ptr++ = (int)*ptr2++;
+		*ptr++ = (int)*ptr2++;
+		*ptr++ = (int)*ptr2;
+	     }
+	}
+   }
+   if (im->alpha_data)
+     {
+	im2->alpha_data = NULL;
+	/* yet to be filled in */
+     }
+   else
+      im2->alpha_data = NULL;
+
+   s = malloc(strlen(im->filename) + 320);
+   if (s)
+     {
+	g_snprintf(s, sizeof(s), "%s_%x_%x_%x_%x", im->filename, (int)time(NULL), w, h, (int)rand());
+	im2->filename = malloc(strlen(s) + 1);
+	if (im2->filename)
+	   strcpy(im2->filename, s);
+	free(s);
+     }
+   else
+      im2->filename = NULL;
+   im2->width = 0;
+   im2->height = 0;
+   im2->shape_color.r = im->shape_color.r;
+   im2->shape_color.g = im->shape_color.g;
+   im2->shape_color.b = im->shape_color.b;
+   im2->border.left = im->border.left;
+   im2->border.right = im->border.right;
+   im2->border.top = im->border.top;
+   im2->border.bottom = im->border.bottom;
+   im2->pixmap = NULL;
+   im2->shape_mask = NULL;
+   im2->cache = 1;
+   im2->mod.gamma = im->mod.gamma;
+   im2->mod.brightness = im->mod.brightness;
+   im2->mod.contrast = im->mod.contrast;
+   im2->rmod.gamma = im->rmod.gamma;
+   im2->rmod.brightness = im->rmod.brightness;
+   im2->rmod.contrast = im->rmod.contrast;
+   im2->gmod.gamma = im->gmod.gamma;
+   im2->gmod.brightness = im->gmod.brightness;
+   im2->gmod.contrast = im->gmod.contrast;
+   im2->bmod.gamma = im->bmod.gamma;
+   im2->bmod.brightness = im->bmod.brightness;
+   im2->bmod.contrast = im->bmod.contrast;
+   gcalc_map_tables(im2);
+   if (id->cache.on_image)
+      gadd_image(im2, im2->filename);
+   return im2;
+}
+
+GdkImlibImage      *
+gdk_imlib_create_image_from_xpm_data(char **data)
+{
+   GdkImlibImage      *im;
+   unsigned char      *ptr;
+   int                 pc, c, i, j, k, ncolors, cpp, comment, transp, quote,
+                       context, len, count, done;
+   int                 w, h;
+   char               *line, s[65536], tok[65536], col[65536];
+   XColor              xcol;
+   struct _cmap
+     {
+	char                str[8];
+	char                transp;
+	int                 r, g, b;
+     }
+                      *cmap;
+   int                 lookup[128][128];
+
+   if (!data)
+      return NULL;
+   im = malloc(sizeof(GdkImlibImage));
+   if (!im)
+      return NULL;
+   count = 0;
+   transp = 0;
+   done = 0;
+
+   c = ' ';
+   comment = 0;
+   quote = 0;
+   context = 0;
+   ptr = NULL;
+
+   while (!done)
+     {
+	line = data[count++];
+	if (context == 0)
+	  {
+	     /* Header */
+	     sscanf(line, "%i %i %i %i", &w, &h, &ncolors, &cpp);
+	     if (cpp > 7)
+	       {
+		  fprintf(stderr, "gdk_imlib ERROR: XPM data with characters per pixel > 7 not supported\n");
+		  free(im);
+		  return NULL;
+	       }
+	     if (w > 32767)
+	       {
+		  fprintf(stderr, "gdk_imlib ERROR: Image width > 32767 pixels for data\n");
+		  free(im);
+		  return NULL;
+	       }
+	     if (h > 32767)
+	       {
+		  fprintf(stderr, "gdk_imlib ERROR: Image height > 32767 pixels for data\n");
+		  free(im);
+		  return NULL;
+	       }
+	     cmap = malloc(sizeof(struct _cmap) * ncolors);
+
+	     if (!cmap)
+	       {
+		  free(im);
+		  return NULL;
+	       }
+	     im->rgb_width = w;
+	     im->rgb_height = h;
+	     im->rgb_data = malloc(im->rgb_width * im->rgb_height * 3);
+	     if (!im->rgb_data)
+	       {
+		  free(cmap);
+		  free(im);
+		  return NULL;
+	       }
+	     im->alpha_data = NULL;
+	     g_snprintf(s, sizeof(s), "creat_%x_%x", (int)time(NULL), (int)rand());
+	     im->filename = malloc(strlen(s) + 1);
+	     if (im->filename)
+		strcpy(im->filename, s);
+	     im->width = 0;
+	     im->height = 0;
+	     im->border.left = 0;
+	     im->border.right = 0;
+	     im->border.top = 0;
+	     im->border.bottom = 0;
+	     im->pixmap = NULL;
+	     im->shape_mask = NULL;
+	     im->cache = 1;
+	     im->mod.gamma = id->mod.gamma;
+	     im->mod.brightness = id->mod.brightness;
+	     im->mod.contrast = id->mod.contrast;
+	     im->rmod.gamma = id->rmod.gamma;
+	     im->rmod.brightness = id->rmod.brightness;
+	     im->rmod.contrast = id->rmod.contrast;
+	     im->gmod.gamma = id->gmod.gamma;
+	     im->gmod.brightness = id->gmod.brightness;
+	     im->gmod.contrast = id->gmod.contrast;
+	     im->bmod.gamma = id->bmod.gamma;
+	     im->bmod.brightness = id->bmod.brightness;
+	     im->bmod.contrast = id->bmod.contrast;
+	     ptr = im->rgb_data;
+	     j = 0;
+	     context++;
+	  }
+	else if (context == 1)
+	  {
+	     int                 colptr;
+
+	     /* Color Table */
+	     if (j < ncolors)
+	       {
+		  tok[0] = 0;
+		  col[0] = 0;
+		  s[0] = 0;
+		  colptr = 0;
+		  len = strlen(line);
+		  strncpy(cmap[j].str, line, cpp);
+		  cmap[j].str[cpp] = 0;
+		  cmap[j].r = -1;
+		  cmap[j].transp = 0;
+		  for (k = cpp; k < len; k++)
+		    {
+		       if (line[k] != ' ')
+			 {
+			    sscanf(&line[k], "%65536s", s);
+			    k += strlen(s);
+			    if ((!strcmp(s, "m")) || (!strcmp(s, "s")) ||
+				(!strcmp(s, "g4")) || (!strcmp(s, "g")) ||
+				(!strcmp(s, "c")) || (k >= len))
+			      {
+				 if (k >= len)
+				   {
+				      int                 ls;
+
+				      ls = strlen(s);
+
+				      if (col[0] && colptr < sizeof(col))
+					{
+					   strcpy(col + colptr, " ");
+					   colptr++;
+					}
+				      if (colptr + ls <= sizeof(col))
+					{
+					   strcpy(col + colptr, s);
+					   colptr += ls;
+					}
+
+				   }
+				 if (col[0])
+				   {
+				      if (!strcasecmp(col, "none"))
+					{
+					   transp = 1;
+					   cmap[j].transp = 1;
+					}
+				      else
+					{
+					   if ((cmap[j].r < 0) ||
+					       (!strcmp(tok, "c")))
+					     {
+						XParseColor(id->x.disp,
+							    id->x.root_cmap,
+							    col, &xcol);
+						cmap[j].r = xcol.red >> 8;
+						cmap[j].g = xcol.green >> 8;
+						cmap[j].b = xcol.blue >> 8;
+						if ((cmap[j].r == 255) &&
+						    (cmap[j].g == 0) &&
+						    (cmap[j].b == 255))
+						   cmap[j].r = 254;
+					     }
+					}
+				   }
+				 if (strlen(s) < sizeof(tok))
+				    strcpy(tok, s);
+				 col[0] = 0;
+			      }
+			    else
+			      {
+				 int                 ls;
+
+				 ls = strlen(s);
+
+				 if (col[0] && colptr < sizeof(col))
+				   {
+				      strcpy(col + colptr, " ");
+				      colptr++;
+				   }
+				 if (ls + colptr < sizeof(col))
+				   {
+				      strcpy(col + colptr, s);
+				      colptr += ls;
+				   }
+			      }
+			 }
+		    }
+	       }
+	     j++;
+	     if (j >= ncolors)
+	       {
+		  if (cpp == 1)
+		     for (i = 0; i < ncolors; i++)
+			lookup[cmap[i].str[0]][cmap[i].str[1]] = i;
+		  if (cpp == 2)
+		     for (i = 0; i < ncolors; i++)
+			lookup[cmap[i].str[0]][cmap[i].str[1]] = i;
+		  context++;
+	       }
+	  }
+	else
+	  {
+	     /* Image Data */
+	     i = 0;
+	     if (cpp == 0)
+	       {
+	       }
+	     else if (cpp == 1)
+	       {
+		  if (transp)
+		    {
+		       for (i = 0; ((i < 65536) && (line[i])); i++)
+			 {
+			    col[0] = line[i];
+			    if (cmap[lookup[col[0]][0]].transp)
+			      {
+				 *ptr++ = 255;
+				 *ptr++ = 0;
+				 *ptr++ = 255;
+			      }
+			    else
+			      {
+				 *ptr++ = (unsigned char)cmap[lookup[col[0]][0]].r;
+				 *ptr++ = (unsigned char)cmap[lookup[col[0]][0]].g;
+				 *ptr++ = (unsigned char)cmap[lookup[col[0]][0]].b;
+			      }
+			 }
+		    }
+		  else
+		    {
+		       for (i = 0; ((i < 65536) && (line[i])); i++)
+			 {
+			    col[0] = line[i];
+			    *ptr++ = (unsigned char)cmap[lookup[col[0]][0]].r;
+			    *ptr++ = (unsigned char)cmap[lookup[col[0]][0]].g;
+			    *ptr++ = (unsigned char)cmap[lookup[col[0]][0]].b;
+			 }
+		    }
+	       }
+	     else if (cpp == 2)
+	       {
+		  if (transp)
+		    {
+		       for (i = 0; ((i < 65536) && (line[i])); i++)
+			 {
+			    col[0] = line[i++];
+			    col[1] = line[i];
+			    if (cmap[lookup[col[0]][col[1]]].transp)
+			      {
+				 *ptr++ = 255;
+				 *ptr++ = 0;
+				 *ptr++ = 255;
+			      }
+			    else
+			      {
+				 *ptr++ = (unsigned char)cmap[lookup[col[0]][col[1]]].r;
+				 *ptr++ = (unsigned char)cmap[lookup[col[0]][col[1]]].g;
+				 *ptr++ = (unsigned char)cmap[lookup[col[0]][col[1]]].b;
+			      }
+			 }
+		    }
+		  else
+		    {
+		       for (i = 0; ((i < 65536) && (line[i])); i++)
+			 {
+			    col[0] = line[i++];
+			    col[1] = line[i];
+			    *ptr++ = (unsigned char)cmap[lookup[col[0]][col[1]]].r;
+			    *ptr++ = (unsigned char)cmap[lookup[col[0]][col[1]]].g;
+			    *ptr++ = (unsigned char)cmap[lookup[col[0]][col[1]]].b;
+			 }
+		    }
+	       }
+	     else
+	       {
+		  if (transp)
+		    {
+		       for (i = 0; ((i < 65536) && (line[i])); i++)
+			 {
+			    for (j = 0; j < cpp; j++, i++)
+			      {
+				 col[j] = line[i];
+			      }
+			    col[j] = 0;
+			    i--;
+			    for (j = 0; j < ncolors; j++)
+			      {
+				 if (!strcmp(col, cmap[j].str))
+				   {
+				      if (cmap[j].transp)
+					{
+					   *ptr++ = 255;
+					   *ptr++ = 0;
+					   *ptr++ = 255;
+					}
+				      else
+					{
+					   *ptr++ = (unsigned char)cmap[j].r;
+					   *ptr++ = (unsigned char)cmap[j].g;
+					   *ptr++ = (unsigned char)cmap[j].b;
+					}
+				      j = ncolors;
+				   }
+			      }
+			 }
+		    }
+		  else
+		    {
+		       for (i = 0; ((i < 65536) && (line[i])); i++)
+			 {
+			    for (j = 0; j < cpp; j++, i++)
+			      {
+				 col[j] = line[i];
+			      }
+			    col[j] = 0;
+			    i--;
+			    for (j = 0; j < ncolors; j++)
+			      {
+				 if (!strcmp(col, cmap[j].str))
+				   {
+				      *ptr++ = (unsigned char)cmap[j].r;
+				      *ptr++ = (unsigned char)cmap[j].g;
+				      *ptr++ = (unsigned char)cmap[j].b;
+				      j = ncolors;
+				   }
+			      }
+			 }
+		    }
+	       }
+	  }
+	if ((ptr) && ((ptr - im->rgb_data) >= w * h * 3))
+	   done = 1;
+     }
+   if (!transp)
+     {
+	im->shape_color.r = -1;
+	im->shape_color.g = -1;
+	im->shape_color.b = -1;
+     }
+   else
+     {
+	im->shape_color.r = 255;
+	im->shape_color.g = 0;
+	im->shape_color.b = 255;
+     }
+   if (id->cache.on_image)
+      gadd_image(im, im->filename);
+   gcalc_map_tables(im);
+   free(cmap);
+   return im;
+}
+
+gint
+gdk_imlib_data_to_pixmap(char **data, GdkPixmap ** pmap, GdkBitmap ** mask)
+{
+   GdkImlibImage      *im;
+
+   im = gdk_imlib_create_image_from_xpm_data(data);
+   if (!im)
+     {
+	if (pmap)
+	   *pmap = NULL;
+	if (mask)
+	   *mask = NULL;
+	return 0;
+     }
+   if (!gdk_imlib_render(im, im->rgb_width, im->rgb_height))
+     {
+	gdk_imlib_destroy_image(im);
+	if (pmap)
+	   *pmap = NULL;
+	if (mask)
+	   *mask = NULL;
+	return 0;
+     }
+   if (pmap)
+      *pmap = gdk_imlib_move_image(im);
+   if (mask)
+      *mask = gdk_imlib_move_mask(im);
+   gdk_imlib_kill_image(im);
+   return 1;
+}
+
+#include <signal.h>
+#include <sys/wait.h>
+
+/*
+ *    Helper library
+ */
+
+static int          hpid;
+void               *oldpiper;	/* actually sighandler_t but BSD uses sig_t. */
+
+FILE               *
+open_helper(const char *instring, const char *fn, const char *mode)
+{
+   char                buf[256];	/* This is safe since our input strings
+
+					 * 
+					 * * are bounded */
+   static char        *vec[16];
+   char               *p = strdup(instring);
+   char               *pp;
+   char               *ep;
+   int                 vn = 0;
+   int                 pid;
+   FILE               *fp = NULL;
+   char               *ofil = NULL;
+   int                 ofd = -1;
+
+   int                 pfd[2];
+
+   if (p == NULL)
+      return NULL;
+
+   if (strncmp(instring, "%Q", 2) == 0)
+     {
+	/*
+	 *    Generate a quanting pipeline
+	 */
+	fprintf(stderr, "Not currently supported: install ImageMagic.\n");
+	return NULL;
+     }
+   /*
+    *    Ok split the instring on spaces and translate
+    *      %C %P %F and %s
+    *
+    *      FIXME: We need to handle a format string that begins
+    *      %Q to indicate an 8bit quant in the pipeline first.
+    */
+
+   pp = p;
+
+   while (vn < 15)
+     {
+	while (*pp && isspace(*pp))
+	   pp++;
+	ep = pp;
+	while (*ep && !isspace(*ep))
+	   ep++;
+	if (*pp == 0)
+	   break;
+	/* pp->ep is now the input string block */
+	if (*ep)
+	   *ep++ = 0;
+
+	if (strcmp(pp, "%s") == 0)
+	   vec[vn] = strdup(fn);
+	else if (strncmp(pp, "%P/", 3) == 0)
+	  {
+	     strcpy(buf, NETPBM_PATH);
+	     strcat(buf, pp + 2);
+	     if ((vec[vn] = strdup(buf)) == NULL)
+		break;
+	  }
+	else if (strncmp(pp, "%J", 3) == 0)
+	  {
+	     if ((vec[vn] = strdup(DJPEG_PROG)) == NULL)
+		break;
+	  }
+	else if (strncmp(pp, "%H", 3) == 0)
+	  {
+	     if ((vec[vn] = strdup(CJPEG_PROG)) == NULL)
+		break;
+	  }
+	else if (strncmp(pp, "%C/", 3) == 0)
+	  {
+	     strcpy(buf, CONVERT_PATH);
+	     strcat(buf, pp + 2);
+	     if ((vec[vn] = strdup(buf)) == NULL)
+		break;
+	  }
+	else if (strncmp(pp, ">%s", 3) == 0)
+	  {
+	     ofil = pp;
+	     vn++;
+	     pp = ep;
+	     continue;
+	  }
+	else
+	  {
+	     if ((vec[vn] = strdup(pp)) == NULL)
+		break;
+	  }
+	vn++;
+	pp = ep;
+     }
+
+   vec[vn] = NULL;
+
+   if (pipe(pfd) == -1)
+      goto oops;
+
+   if (*mode == 'r')
+     {
+	fp = fdopen(pfd[0], "r");
+	if (fp == NULL)
+	   goto oops;
+     }
+   else if (*mode == 'w')
+     {
+	fp = fdopen(pfd[1], "w");
+	if (fp == NULL)
+	   goto oops;
+     }
+   else
+      goto oops;
+
+   if (ofil != NULL)
+      if ((ofd = open(ofil, O_WRONLY | O_TRUNC | O_CREAT)) == -1)
+	 goto oops;
+
+   switch (pid = fork())
+     {
+     case -1:
+	break;
+     case 0:
+	signal(SIGPIPE, SIG_DFL);
+	if (*mode == 'r')
+	   dup2(pfd[1], 1);
+	if (*mode == 'w')
+	  {
+	     dup2(pfd[0], 0);
+	     if (ofd != -1)
+	       {
+		  dup2(ofd, 1);
+		  close(1);
+	       }
+	  }
+	close(pfd[0]);
+	close(pfd[1]);
+	execv(vec[0], vec);
+	perror(vec[0]);
+	/*
+	 *    This MUST be _exit or we will hit the SIGPIPE
+	 *      handler in ways we dont want. We want our parent
+	 *      to flush the inherited file buffers not us.
+	 */
+	_exit(1);
+     default:
+	hpid = pid;
+
+	if (ofd != -1)
+	   close(ofd);
+	if (*mode == 'r')
+	   close(pfd[1]);
+	else
+	   close(pfd[0]);
+     }
+   for (vn = 0; vn < 16; vn++)
+      if (vec[vn])
+	 free(vec[vn]);
+   oldpiper = signal(SIGPIPE, SIG_IGN);
+   return fp;
+
+ oops:
+   if (ofd != -1)
+      close(ofd);
+   if (fp)
+      fclose(fp);
+   for (vn = 0; vn < 16; vn++)
+      if (vec[vn])
+	 free(vec[vn]);
+   return NULL;
+}
+
+int
+close_helper(FILE * fp)
+{
+   int                 info;
+
+   fclose(fp);
+   signal(SIGPIPE, oldpiper);
+   waitpid(hpid, &info, 0);
+   return WEXITSTATUS(info);
+}
diff --git a/src/generic/choicdgg.cpp b/src/generic/choicdgg.cpp
new file mode 100644
index 0000000000..e6997e0511
--- /dev/null
+++ b/src/generic/choicdgg.cpp
@@ -0,0 +1,303 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        choicesg.cpp
+// Purpose:     Choice dialogs
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "choicdgg.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include <stdio.h>
+#include "wx/utils.h"
+#include "wx/dialog.h"
+#include "wx/listbox.h"
+#include "wx/button.h"
+#include "wx/stattext.h"
+#include "wx/layout.h"
+#include "wx/intl.h"
+#endif
+
+#include "wx/generic/choicdgg.h"
+
+extern void wxSplitMessage2(const char *message, wxList *messageList, wxWindow *parent, wxRowColSizer *sizer);
+
+wxString wxGetSingleChoice( const wxString& message, const wxString& caption, const int n, 
+                            const wxString *choices, wxWindow *parent, 
+			    const int WXUNUSED(x), const int WXUNUSED(y), const bool WXUNUSED(centre), 
+			    const int WXUNUSED(width), const int WXUNUSED(height) )
+{
+	wxSingleChoiceDialog dialog(parent, message, caption, n, choices);
+	if ( dialog.ShowModal() == wxID_OK )
+	{
+		return dialog.GetStringSelection();
+	}
+	else
+		return "";
+}
+
+// Overloaded for backward compatibility
+wxString wxGetSingleChoice( const wxString& message, const wxString& caption, const int n, 
+                            char *choices[], wxWindow *parent, 
+			    const int x, const int y, const bool centre, 
+			    const int width, const int height )
+{
+	wxString *strings = new wxString[n];
+	int i;
+	for ( i = 0; i < n; i++)
+	{
+		strings[i] = choices[i];
+	}
+	wxString ans(wxGetSingleChoice(message, caption, n, (const wxString *)strings, parent,
+		x, y, centre, width, height));
+	delete[] strings;
+	return ans;
+}
+
+int wxGetSingleChoiceIndex( const wxString& message, const wxString& caption, const int n, 
+                            const wxString *choices, wxWindow *parent, 
+			    const int WXUNUSED(x), const int WXUNUSED(y), const bool WXUNUSED(centre), 
+			    const int WXUNUSED(width), const int WXUNUSED(height) )
+{
+	wxSingleChoiceDialog dialog(parent, message, caption, n, choices);
+	if ( dialog.ShowModal() == wxID_OK )
+	{
+		return dialog.GetSelection();
+	}
+	else
+		return -1;
+}
+
+// Overloaded for backward compatibility
+int wxGetSingleChoiceIndex( const wxString& message, const wxString& caption, const int n, 
+                            char *choices[], wxWindow *parent, 
+			    const int x, const int y, const bool centre, 
+			    const int width, const int height )
+{
+	wxString *strings = new wxString[n];
+	int i;
+	for ( i = 0; i < n; i++)
+	{
+		strings[i] = choices[i];
+	}
+	int ans = wxGetSingleChoiceIndex(message, caption, n, (const wxString *)strings, parent,
+		x, y, centre, width, height);
+	delete[] strings;
+	return ans;
+}
+
+char *wxGetSingleChoiceData( const wxString& message, const wxString& caption, const int n,
+                             const wxString *choices, char **client_data, wxWindow *parent, 
+			     const int WXUNUSED(x), const int WXUNUSED(y), const bool WXUNUSED(centre), 
+			     const int WXUNUSED(width), const int WXUNUSED(height) )
+{
+	wxSingleChoiceDialog dialog(parent, message, caption, n, choices, client_data);
+	if ( dialog.ShowModal() == wxID_OK )
+	{
+		return dialog.GetSelectionClientData();
+	}
+	else
+		return NULL;
+}
+
+// Overloaded for backward compatibility
+char *wxGetSingleChoiceData( const wxString& message, const wxString& caption, const int n, 
+                             char *choices[], char **client_data, wxWindow *parent, 
+			     const int x, const int y, const bool centre, 
+			     const int width, const int height )
+{
+	wxString *strings = new wxString[n];
+	int i;
+	for ( i = 0; i < n; i++)
+	{
+		strings[i] = choices[i];
+	}
+	char *data = wxGetSingleChoiceData(message, caption, n, (const wxString *)strings, client_data, parent,
+		x, y, centre, width, height);
+	delete[] strings;
+	return data;
+}
+
+
+/* Multiple choice dialog contributed by Robert Cowell
+ *
+
+The new data passed are in the "int nsel" and "int * selection"
+
+The idea is to make a multiple selection from list of strings.
+The returned value is the total number selected. initialily there
+are nsel selected, with indices stored in
+selection[0],...,selection[nsel-1] which appear highlighted to
+begin with. On exit with value i
+selection[0..i-1] contains the indices of the selected items.
+(Some prior selectecions might be deselected.)
+Thus selection must be as big as choices, in case all items are
+selected.
+
+*/
+/*
+int wxGetMultipleChoice(const wxString& message, const wxString& caption,
+			  const int n, const wxString *choices,
+			  const int nsel, int * selection,
+			  wxWindow *parent , const int x , const int y, const bool centre,
+			  const int width, const int height)
+{
+	return -1;
+}
+*/
+
+// wxSingleChoiceDialog
+
+#if !USE_SHARED_LIBRARY
+BEGIN_EVENT_TABLE(wxSingleChoiceDialog, wxDialog)
+	EVT_BUTTON(wxID_OK, wxSingleChoiceDialog::OnOK)
+END_EVENT_TABLE()
+
+IMPLEMENT_CLASS(wxSingleChoiceDialog, wxDialog)
+#endif
+
+wxSingleChoiceDialog::wxSingleChoiceDialog(wxWindow *parent, const wxString& message, const wxString& caption,
+        const int n, const wxString *choices, char **clientData, long style, const wxPoint& pos):
+	  wxDialog(parent, -1, caption, pos, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxDIALOG_MODAL)
+{
+        Create(parent, message, caption, n, choices, clientData, style);
+}
+
+wxSingleChoiceDialog::wxSingleChoiceDialog(wxWindow *parent, const wxString& message, const wxString& caption,
+        const wxStringList& choices, char **clientData, long style, const wxPoint& pos):
+	  wxDialog(parent, -1, caption, pos, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxDIALOG_MODAL)
+{
+        Create(parent, message, caption, choices, clientData, style);
+}
+
+bool wxSingleChoiceDialog::Create(wxWindow *parent, const wxString& message, const wxString& caption,
+        const wxStringList& choices, char **clientData, long style, const wxPoint& pos)
+{
+	wxString *strings = new wxString[choices.Number()];
+	int i;
+	for ( i = 0; i < choices.Number(); i++)
+	{
+		strings[i] = (char *)choices.Nth(i)->Data();
+	}
+	bool ans = Create(parent, message, caption, choices.Number(), strings, clientData, style, pos);
+	delete[] strings;
+	return ans;
+}
+
+bool wxSingleChoiceDialog::Create( wxWindow *WXUNUSED(parent), const wxString& message, 
+                                   const wxString& WXUNUSED(caption), const int n, 
+			           const wxString *choices, char **clientData, long style, 
+				   const wxPoint& WXUNUSED(pos) )
+{
+	m_dialogStyle = style;
+	m_selection = 0;
+	m_stringSelection = "";
+	m_clientData = NULL;
+
+	wxBeginBusyCursor();
+
+	wxSizer *topSizer = new wxSizer(this, wxSizerShrink);
+	topSizer->SetBorder(10, 10);
+
+	wxRowColSizer *messageSizer = new wxRowColSizer(topSizer, wxSIZER_COLS, 100);
+	messageSizer->SetName("messageSizer");
+
+//    bool centre = ((style & wxCENTRE) == wxCENTRE);
+
+	wxList messageList;
+	wxSplitMessage2(message, &messageList, this, messageSizer);
+
+	// Insert a spacer
+	wxSpacingSizer *spacingSizer = new wxSpacingSizer(topSizer, wxBelow, messageSizer, 10);
+
+	wxListBox *listBox = new wxListBox(this, wxID_LISTBOX, wxPoint(-1, -1), wxSize(240, 160),
+		n, choices);
+	if ( clientData )
+	{
+		int i;
+		for ( i = 0; i < n; i++)
+		{
+				listBox->SetClientData(i, clientData[i]);
+		}
+	}
+
+	wxRowColSizer *listBoxSizer = new wxRowColSizer(topSizer, wxSIZER_ROWS);
+	listBoxSizer->AddSizerChild(listBox);
+	listBoxSizer->SetName("listBoxSizer");
+
+	// Create constraints for the text sizer
+	wxLayoutConstraints *textC = new wxLayoutConstraints;
+	textC->left.SameAs		(messageSizer, wxLeft);
+	textC->top.Below		(spacingSizer);
+	listBoxSizer->SetConstraints(textC);
+
+	// Insert another spacer
+	wxSpacingSizer *spacingSizer2 = new wxSpacingSizer(topSizer, wxBelow, listBoxSizer, 10);
+	spacingSizer->SetName("spacingSizer2");
+
+	// Insert a sizer for the buttons
+	wxRowColSizer *buttonSizer = new wxRowColSizer(topSizer, wxSIZER_ROWS);
+	buttonSizer->SetName("buttonSizer");
+
+  	// Specify constraints for the button sizer
+  	wxLayoutConstraints *c = new wxLayoutConstraints;
+  	c->width.AsIs		();
+  	c->height.AsIs		();
+	c->top.Below		(spacingSizer2);
+	c->centreX.SameAs	(listBoxSizer, wxCentreX);
+  	buttonSizer->SetConstraints(c);
+
+    wxButton *ok = NULL;
+  	wxButton *cancel = NULL;
+
+  if (style & wxOK) {
+    ok = new wxButton(this, wxID_OK, _("OK"));
+	buttonSizer->AddSizerChild(ok);
+  }
+
+  if (style & wxCANCEL) {
+    cancel = new wxButton(this, wxID_CANCEL, _("Cancel"));
+	buttonSizer->AddSizerChild(cancel);
+  }
+
+  if (ok)
+  {
+    ok->SetDefault();
+    ok->SetFocus();
+  }
+
+  Layout();
+  Centre(wxBOTH);
+
+  wxEndBusyCursor();
+
+  return TRUE;
+}
+
+void wxSingleChoiceDialog::OnOK(wxCommandEvent& WXUNUSED(event))
+{
+	wxListBox *listBox = (wxListBox *)FindWindow(wxID_LISTBOX);
+	if ( listBox )
+	{
+		m_selection = listBox->GetSelection();
+		m_stringSelection = listBox->GetStringSelection();
+		m_clientData = listBox->GetClientData(m_selection);
+	}
+
+	EndModal(wxID_OK);
+}
+
+
diff --git a/src/generic/colrdlgg.cpp b/src/generic/colrdlgg.cpp
new file mode 100644
index 0000000000..9080ef2b02
--- /dev/null
+++ b/src/generic/colrdlgg.cpp
@@ -0,0 +1,487 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        colrdlgg.cpp
+// Purpose:     Choice dialogs
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "colrdlgg.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include <stdio.h>
+#include <stdio.h>
+#include "wx/utils.h"
+#include "wx/intl.h"
+#include "wx/dialog.h"
+#include "wx/listbox.h"
+#include "wx/button.h"
+#include "wx/stattext.h"
+#include "wx/layout.h"
+#include "wx/dcclient.h"
+#include "wx/slider.h"
+#endif
+
+#include "wx/generic/colrdlgg.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxGenericColourDialog, wxDialog)
+
+BEGIN_EVENT_TABLE(wxGenericColourDialog, wxDialog)
+	EVT_BUTTON(wxID_ADD_CUSTOM, wxGenericColourDialog::OnAddCustom)
+	EVT_SLIDER(wxID_RED_SLIDER, wxGenericColourDialog::OnRedSlider)
+	EVT_SLIDER(wxID_GREEN_SLIDER, wxGenericColourDialog::OnGreenSlider)
+	EVT_SLIDER(wxID_BLUE_SLIDER, wxGenericColourDialog::OnBlueSlider)
+	EVT_PAINT(wxGenericColourDialog::OnPaint)
+	EVT_MOUSE_EVENTS(wxGenericColourDialog::OnMouseEvent)
+END_EVENT_TABLE()
+
+#endif
+
+/*
+ * Generic wxColourDialog
+ */
+
+#define NUM_COLS 48
+static wxString wxColourDialogNames[NUM_COLS]={"ORANGE",
+				    "GOLDENROD",
+				    "WHEAT",
+				    "SPRING GREEN",
+				    "SKY BLUE",
+				    "SLATE BLUE",
+				    "MEDIUM VIOLET RED",
+				    "PURPLE",
+
+				    "RED",
+				    "YELLOW",
+				    "MEDIUM SPRING GREEN",
+				    "PALE GREEN",
+				    "CYAN",
+				    "LIGHT STEEL BLUE",
+				    "ORCHID",
+				    "LIGHT MAGENTA",
+				    
+				    "BROWN",
+				    "YELLOW",
+				    "GREEN",
+				    "CADET BLUE",
+				    "MEDIUM BLUE",
+				    "MAGENTA",
+				    "MAROON",
+				    "ORANGE RED",
+
+				    "FIREBRICK",
+				    "CORAL",
+				    "FOREST GREEN",
+				    "AQUARAMINE",
+				    "BLUE",
+				    "NAVY",
+				    "THISTLE",
+				    "MEDIUM VIOLET RED",
+				    
+				    "INDIAN RED",
+				    "GOLD",
+				    "MEDIUM SEA GREEN",
+				    "MEDIUM BLUE",
+				    "MIDNIGHT BLUE",
+				    "GREY",
+				    "PURPLE",
+				    "KHAKI",
+				    
+				    "BLACK",
+				    "MEDIUM FOREST GREEN",
+				    "KHAKI",
+				    "DARK GREY",
+				    "SEA GREEN",
+				    "LIGHT GREY",
+				    "MEDIUM SLATE BLUE",
+				    "WHITE"
+				    };
+
+wxGenericColourDialog::wxGenericColourDialog(void)
+{
+  dialogParent = NULL;
+  whichKind = 1;
+  colourSelection = 0;
+}
+
+wxGenericColourDialog::wxGenericColourDialog(wxWindow *parent, wxColourData *data):
+  wxDialog(parent, -1, "Colour", wxPoint(0, 0), wxSize(900, 900), wxDEFAULT_DIALOG_STYLE|wxDIALOG_MODAL)
+{
+  whichKind = 1;
+  colourSelection = 0;
+  Create(parent, data);
+}
+
+wxGenericColourDialog::~wxGenericColourDialog(void)
+{
+}
+
+bool wxGenericColourDialog::OnClose(void)
+{
+  Show(FALSE);
+  return FALSE;
+}
+
+bool wxGenericColourDialog::Create(wxWindow *parent, wxColourData *data)
+{
+  dialogParent = parent;
+  
+  if (data)
+    colourData = *data;
+
+  InitializeColours();
+  CalculateMeasurements();
+  CreateWidgets();
+  
+  return TRUE;
+}
+
+int wxGenericColourDialog::ShowModal(void)
+{
+  return wxDialog::ShowModal();
+}
+
+
+// Internal functions
+void wxGenericColourDialog::OnMouseEvent(wxMouseEvent& event)
+{
+  if (event.ButtonDown(1))
+  {
+    int x = (int)event.GetX();
+    int y = (int)event.GetY();
+
+    if ((x >= standardColoursRect.x && x <= (standardColoursRect.x + standardColoursRect.width)) &&
+        (y >= standardColoursRect.y && y <= (standardColoursRect.y + standardColoursRect.height)))
+    {
+      int selX = (int)(x - standardColoursRect.x)/(smallRectangleSize.x + gridSpacing);
+      int selY = (int)(y - standardColoursRect.y)/(smallRectangleSize.y + gridSpacing);
+      int ptr = (int)(selX + selY*8);
+      OnBasicColourClick(ptr);
+    }
+    else if ((x >= customColoursRect.x && x <= (customColoursRect.x + customColoursRect.width)) &&
+        (y >= customColoursRect.y && y <= (customColoursRect.y + customColoursRect.height)))
+    {
+      int selX = (int)(x - customColoursRect.x)/(smallRectangleSize.x + gridSpacing);
+      int selY = (int)(y - customColoursRect.y)/(smallRectangleSize.y + gridSpacing);
+      int ptr = (int)(selX + selY*8);
+      OnCustomColourClick(ptr);
+    }
+  }
+}
+
+void wxGenericColourDialog::OnPaint(wxPaintEvent& event)
+{
+  wxDialog::OnPaint(event);
+
+  wxPaintDC dc(this);
+
+  PaintBasicColours(dc);
+  PaintCustomColours(dc);
+  PaintCustomColour(dc);
+  PaintHighlight(dc, TRUE);
+}
+
+void wxGenericColourDialog::CalculateMeasurements(void)
+{
+  smallRectangleSize.x = 18;
+  smallRectangleSize.y = 14;
+  customRectangleSize.x = 40;
+  customRectangleSize.y = 40;
+
+  gridSpacing = 6;
+  sectionSpacing = 15;
+
+  standardColoursRect.x = 10;
+  standardColoursRect.y = 15;
+  standardColoursRect.width = (8*smallRectangleSize.x) + (7*gridSpacing);
+  standardColoursRect.height = (6*smallRectangleSize.y) + (5*gridSpacing);
+
+  customColoursRect.x = standardColoursRect.x;
+  customColoursRect.y = standardColoursRect.y + standardColoursRect.height  + 20;
+  customColoursRect.width = (8*smallRectangleSize.x) + (7*gridSpacing);
+  customColoursRect.height = (2*smallRectangleSize.y) + (1*gridSpacing);
+
+  singleCustomColourRect.x = customColoursRect.width + customColoursRect.x + sectionSpacing;
+  singleCustomColourRect.y = 80;
+  singleCustomColourRect.width = customRectangleSize.x;
+  singleCustomColourRect.height = customRectangleSize.y;
+
+  okButtonX = 10;
+  customButtonX = singleCustomColourRect.x ;
+  buttonY = customColoursRect.y + customColoursRect.height + 10;
+}
+
+void wxGenericColourDialog::CreateWidgets(void)
+{
+  wxBeginBusyCursor();
+  
+  wxButton *okButton = new wxButton(this, wxID_OK, "OK", wxPoint(okButtonX, buttonY));
+  int bw, bh;
+  okButton->GetSize(&bw, &bh);
+
+  (void) new wxButton(this, wxID_CANCEL, "Cancel", wxPoint(okButtonX + bw + 10, buttonY));
+  (void) new wxButton(this, wxID_ADD_CUSTOM, "Add to custom colours",
+     wxPoint(customButtonX, buttonY));
+
+  int sliderX = singleCustomColourRect.x + singleCustomColourRect.width + sectionSpacing;
+#ifdef __X__
+  int sliderSpacing = 75;
+  int sliderHeight = 160;
+#else
+  int sliderSpacing = 45;
+  int sliderHeight = 160;
+#endif
+  
+  redSlider = new wxSlider(this, wxID_RED_SLIDER, 0, 0, 255,
+   wxPoint(sliderX, 10), wxSize(-1, sliderHeight), wxVERTICAL|wxSL_LABELS);
+  greenSlider = new wxSlider(this, wxID_GREEN_SLIDER, 0, 0, 255,
+   wxPoint(sliderX + sliderSpacing, 10), wxSize(-1, sliderHeight), wxVERTICAL|wxSL_LABELS);
+  blueSlider = new wxSlider(this, wxID_BLUE_SLIDER, 0, 0, 255,
+   wxPoint(sliderX + 2*sliderSpacing, 10), wxSize(-1, sliderHeight), wxVERTICAL|wxSL_LABELS);
+
+  SetClientSize(sliderX + 3*sliderSpacing, buttonY + 30);
+  okButton->SetDefault();
+
+  Centre(wxBOTH);
+
+  wxEndBusyCursor();
+}
+
+void wxGenericColourDialog::InitializeColours(void)
+{
+  int i;
+  for (i = 0; i < 48; i++)
+  {
+    wxColour *col = wxTheColourDatabase->FindColour(wxColourDialogNames[i]);
+    if (col)
+      standardColours[i].Set(col->Red(), col->Green(), col->Blue());
+    else
+      standardColours[i].Set(0, 0, 0);
+  }
+
+  for (i = 0; i < 16; i++)
+    customColours[i] =
+/*
+#ifndef __VMS__
+     (wxColour&)
+#endif
+*/
+       colourData.GetCustomColour(i);
+
+  singleCustomColour.Set(0, 0, 0);
+}
+
+void wxGenericColourDialog::PaintBasicColours(wxDC& dc)
+{
+  dc.BeginDrawing();
+
+  int i;
+  for (i = 0; i < 6; i++)
+  {
+    int j;
+    for (j = 0; j < 8; j++)
+    {
+      int ptr = i*8 + j;
+      
+      int x = (j*(smallRectangleSize.x+gridSpacing) + standardColoursRect.x);
+      int y = (i*(smallRectangleSize.y+gridSpacing) + standardColoursRect.y);
+
+      dc.SetPen(*wxBLACK_PEN);
+      wxBrush brush(standardColours[ptr], wxSOLID);
+      dc.SetBrush(brush);
+
+      dc.DrawRectangle( x, y, smallRectangleSize.x, smallRectangleSize.y);
+    }
+  }
+  dc.EndDrawing();
+}
+
+void wxGenericColourDialog::PaintCustomColours(wxDC& dc)
+{
+  dc.BeginDrawing();
+
+  int i;
+  for (i = 0; i < 2; i++)
+  {
+    int j;
+    for (j = 0; j < 8; j++)
+    {
+      int ptr = i*8 + j;
+      
+      int x = (j*(smallRectangleSize.x+gridSpacing)) + customColoursRect.x;
+      int y = (i*(smallRectangleSize.y+gridSpacing)) + customColoursRect.y;
+
+      dc.SetPen(*wxBLACK_PEN);
+
+      wxBrush brush(customColours[ptr], wxSOLID);
+      dc.SetBrush(brush);
+
+      dc.DrawRectangle( x, y, smallRectangleSize.x, smallRectangleSize.y);
+    }
+  }
+  dc.EndDrawing();
+}
+
+void wxGenericColourDialog::PaintHighlight(wxDC& dc, bool draw)
+{
+  dc.BeginDrawing();
+
+  // Number of pixels bigger than the standard rectangle size
+  // for drawing a highlight
+  int deltaX = 2;
+  int deltaY = 2;
+
+  if (whichKind == 1)
+  {
+    // Standard colours
+    int y = (int)(colourSelection / 8);
+    int x = (int)(colourSelection - (y*8));
+
+    x = (x*(smallRectangleSize.x + gridSpacing) + standardColoursRect.x) - deltaX;
+    y = (y*(smallRectangleSize.y + gridSpacing) + standardColoursRect.y) - deltaY;
+
+    if (draw)
+      dc.SetPen(*wxBLACK_PEN);
+    else
+      dc.SetPen(*wxLIGHT_GREY_PEN);
+
+    dc.SetBrush(*wxTRANSPARENT_BRUSH);
+    dc.DrawRectangle( x, y, (smallRectangleSize.x + (2*deltaX)), (smallRectangleSize.y + (2*deltaY)));
+  }
+  else
+  {
+    // User-defined colours
+    int y = (int)(colourSelection / 8);
+    int x = (int)(colourSelection - (y*8));
+
+    x = (x*(smallRectangleSize.x + gridSpacing) + customColoursRect.x) - deltaX;
+    y = (y*(smallRectangleSize.y + gridSpacing) + customColoursRect.y) - deltaY;
+
+    if (draw)
+      dc.SetPen(*wxBLACK_PEN);
+    else
+      dc.SetPen(*wxLIGHT_GREY_PEN);
+      
+    dc.SetBrush(*wxTRANSPARENT_BRUSH);
+    dc.DrawRectangle( x, y, (smallRectangleSize.x + (2*deltaX)), (smallRectangleSize.y + (2*deltaY)));
+  }
+  
+  dc.EndDrawing();
+}
+
+void wxGenericColourDialog::PaintCustomColour(wxDC& dc)
+{
+  dc.BeginDrawing();
+  
+  dc.SetPen(*wxBLACK_PEN);
+
+  wxBrush *brush = new wxBrush(singleCustomColour, wxSOLID);
+  dc.SetBrush(*brush);
+
+  dc.DrawRectangle( singleCustomColourRect.x, singleCustomColourRect.y,
+                    customRectangleSize.x, customRectangleSize.y);
+
+  dc.SetBrush(wxNullBrush);
+  delete brush;
+
+  dc.EndDrawing();
+}
+
+void wxGenericColourDialog::OnBasicColourClick(int which)
+{
+  wxClientDC dc(this);
+
+  PaintHighlight(dc, FALSE);
+  whichKind = 1;
+  colourSelection = which;
+  colourData.SetColour(standardColours[colourSelection]);
+
+  PaintHighlight(dc, TRUE);
+}
+
+void wxGenericColourDialog::OnCustomColourClick(int which)
+{
+  wxClientDC dc(this);
+  PaintHighlight(dc, FALSE);
+  whichKind = 2;
+  colourSelection = which;
+  colourData.SetColour(customColours[colourSelection]);
+
+  PaintHighlight(dc, TRUE);
+}
+
+/*
+void wxGenericColourDialog::OnOk(void)
+{
+  Show(FALSE);
+}
+
+void wxGenericColourDialog::OnCancel(void)
+{
+  colourDialogCancelled = TRUE;
+  Show(FALSE);
+}
+*/
+
+void wxGenericColourDialog::OnAddCustom(wxCommandEvent& WXUNUSED(event))
+{
+  wxClientDC dc(this);
+  if (whichKind != 2)
+  {
+    PaintHighlight(dc, FALSE);
+    whichKind = 2;
+    colourSelection = 0;
+    PaintHighlight(dc, TRUE);
+  }
+
+  customColours[colourSelection].Set(singleCustomColour.Red(), singleCustomColour.Green(), singleCustomColour.Blue());
+  colourData.SetColour(customColours[colourSelection]);
+  colourData.SetCustomColour(colourSelection, customColours[colourSelection]);
+  
+  PaintCustomColours(dc);
+}
+
+void wxGenericColourDialog::OnRedSlider(wxCommandEvent& WXUNUSED(event))
+{
+  if (!redSlider)
+    return;
+    
+  wxClientDC dc(this);
+  singleCustomColour.Set(redSlider->GetValue(), singleCustomColour.Green(), singleCustomColour.Blue());
+  PaintCustomColour(dc);
+}
+
+void wxGenericColourDialog::OnGreenSlider(wxCommandEvent& WXUNUSED(event))
+{
+  if (!greenSlider)
+    return;
+
+  wxClientDC dc(this);
+  singleCustomColour.Set(singleCustomColour.Red(), greenSlider->GetValue(), singleCustomColour.Blue());
+  PaintCustomColour(dc);
+}
+
+void wxGenericColourDialog::OnBlueSlider(wxCommandEvent& WXUNUSED(event))
+{
+  if (!blueSlider)
+    return;
+
+  wxClientDC dc(this);
+  singleCustomColour.Set(singleCustomColour.Red(), singleCustomColour.Green(), blueSlider->GetValue());
+  PaintCustomColour(dc);
+}
+
+
diff --git a/src/generic/fontdlgg.cpp b/src/generic/fontdlgg.cpp
new file mode 100644
index 0000000000..5d0ea78fbd
--- /dev/null
+++ b/src/generic/fontdlgg.cpp
@@ -0,0 +1,425 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        fontdlgg.cpp
+// Purpose:     Generic font dialog
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "fontdlgg.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include <stdio.h>
+#include "wx/utils.h"
+#include "wx/dialog.h"
+#include "wx/listbox.h"
+#include "wx/button.h"
+#include "wx/stattext.h"
+#include "wx/layout.h"
+#include "wx/dcclient.h"
+#include "wx/choice.h"
+#include "wx/checkbox.h"
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "wx/cmndata.h"
+#include "wx/generic/fontdlgg.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxGenericFontDialog, wxDialog)
+
+BEGIN_EVENT_TABLE(wxGenericFontDialog, wxDialog)
+	EVT_CHECKBOX(wxID_FONT_UNDERLINE, wxGenericFontDialog::OnChangeFont)
+	EVT_CHOICE(wxID_FONT_STYLE, wxGenericFontDialog::OnChangeFont)
+	EVT_CHOICE(wxID_FONT_WEIGHT, wxGenericFontDialog::OnChangeFont)
+	EVT_CHOICE(wxID_FONT_FAMILY, wxGenericFontDialog::OnChangeFont)
+	EVT_CHOICE(wxID_FONT_COLOUR, wxGenericFontDialog::OnChangeFont)
+	EVT_CHOICE(wxID_FONT_SIZE, wxGenericFontDialog::OnChangeFont)
+	EVT_PAINT(wxGenericFontDialog::OnPaint)
+END_EVENT_TABLE()
+
+#endif
+
+#define NUM_COLS 48
+static wxString wxColourDialogNames[NUM_COLS]={"ORANGE",
+				    "GOLDENROD",
+				    "WHEAT",
+				    "SPRING GREEN",
+				    "SKY BLUE",
+				    "SLATE BLUE",
+				    "MEDIUM VIOLET RED",
+				    "PURPLE",
+
+				    "RED",
+				    "YELLOW",
+				    "MEDIUM SPRING GREEN",
+				    "PALE GREEN",
+				    "CYAN",
+				    "LIGHT STEEL BLUE",
+				    "ORCHID",
+				    "LIGHT MAGENTA",
+				    
+				    "BROWN",
+				    "YELLOW",
+				    "GREEN",
+				    "CADET BLUE",
+				    "MEDIUM BLUE",
+				    "MAGENTA",
+				    "MAROON",
+				    "ORANGE RED",
+
+				    "FIREBRICK",
+				    "CORAL",
+				    "FOREST GREEN",
+				    "AQUARAMINE",
+				    "BLUE",
+				    "NAVY",
+				    "THISTLE",
+				    "MEDIUM VIOLET RED",
+				    
+				    "INDIAN RED",
+				    "GOLD",
+				    "MEDIUM SEA GREEN",
+				    "MEDIUM BLUE",
+				    "MIDNIGHT BLUE",
+				    "GREY",
+				    "PURPLE",
+				    "KHAKI",
+				    
+				    "BLACK",
+				    "MEDIUM FOREST GREEN",
+				    "KHAKI",
+				    "DARK GREY",
+				    "SEA GREEN",
+				    "LIGHT GREY",
+				    "MEDIUM SLATE BLUE",
+				    "WHITE"
+				    };
+
+/*
+ * Generic wxFontDialog
+ */
+
+wxGenericFontDialog::wxGenericFontDialog(void)
+{
+  dialogParent = NULL;
+}
+
+wxGenericFontDialog::wxGenericFontDialog(wxWindow *parent, wxFontData *data):
+  wxDialog(parent, -1, "Font", wxPoint(0, 0), wxSize(600, 600), wxDEFAULT_DIALOG_STYLE|wxDIALOG_MODAL)
+{
+  Create(parent, data);
+}
+
+wxGenericFontDialog::~wxGenericFontDialog(void)
+{
+}
+
+bool wxGenericFontDialog::OnClose(void)
+{
+  Show(FALSE);
+  return FALSE;
+}
+ 
+bool wxGenericFontDialog::Create(wxWindow *parent, wxFontData *data)
+{
+  dialogParent = parent;
+  
+  if (data)
+    fontData = *data;
+
+  InitializeFont();
+  CreateWidgets();
+  
+  return TRUE;
+}
+
+int wxGenericFontDialog::ShowModal(void)
+{
+  int ret = wxDialog::ShowModal();
+
+    if (ret != wxID_CANCEL)
+    {
+      fontData.chosenFont = dialogFont;
+    }
+
+	return ret;
+}
+
+
+void wxGenericFontDialog::OnPaint(wxPaintEvent& event)
+{
+  wxDialog::OnPaint(event);
+
+  wxPaintDC dc(this);
+  PaintFontBackground(dc);
+  PaintFont(dc);
+}
+
+/*
+static void wxGenericChangeFontText(wxTextCtrl& text, wxCommandEvent& event)
+{
+  if (event.GetEventType() == wxEVENT_TYPE_TEXT_ENTER_COMMAND)
+  {
+    wxGenericFontDialog *dialog = (wxGenericFontDialog *)text.GetParent();
+    dialog->OnChangeFont();
+  }
+}
+*/
+
+void wxGenericFontDialog::CreateWidgets(void)
+{
+  wxBeginBusyCursor();
+
+  fontRect.x = 5;
+#ifdef __X__
+  fontRect.y = 125;
+#else
+  fontRect.y = 115;
+#endif
+  fontRect.width = 350;
+  fontRect.height = 100;
+
+/*
+  static char *families[] = { "Roman", "Decorative", "Modern", "Script", "Swiss" };
+  static char *styles[] = { "Normal", "Italic", "Slant" };
+  static char *weights[] = { "Normal", "Light", "Bold" };
+*/
+  static wxString families[] = { "Roman", "Decorative", "Modern", "Script", "Swiss" };
+  static wxString styles[] = { "Normal", "Italic", "Slant" };
+  static wxString weights[] = { "Normal", "Light", "Bold" };
+
+  int x=-1;
+  int y=40;
+  familyChoice = new wxChoice(this, wxID_FONT_FAMILY, wxPoint(10, 10), wxSize(120, -1), 5, families);
+  styleChoice = new wxChoice(this, wxID_FONT_STYLE, wxPoint(140, 10), wxSize(120, -1), 3, styles);
+  weightChoice = new wxChoice(this, wxID_FONT_WEIGHT, wxPoint(270, 10), wxSize(120, -1), 3, weights);
+
+  colourChoice = new wxChoice(this, wxID_FONT_COLOUR, wxPoint(10, 40), wxSize(190, -1), NUM_COLS, wxColourDialogNames);
+#ifdef __MOTIF__
+  // We want the pointSizeText to line up on the y axis with the colourChoice
+  colourChoice->GetPosition(&fontRect.x, &y); //NL mod
+  y+=3;	//NL mod
+#endif
+
+  wxString pointSizes[40];
+  int i;
+  for ( i = 0; i < 40; i++)
+  {
+	char buf[5];
+	sprintf(buf, "%d", i + 1);
+	pointSizes[i] = buf;
+  }
+
+  pointSizeChoice = new wxChoice(this, wxID_FONT_SIZE, wxPoint(210, y), wxSize(50, -1), 40, pointSizes);
+  underLineCheckBox = new wxCheckBox(this, wxID_FONT_UNDERLINE, "Underline", wxPoint(280, y));
+
+  int rectY;
+  pointSizeChoice->GetPosition(&x, &rectY); //NL mod
+  fontRect.y = rectY;
+  pointSizeChoice->GetSize(&x, &y); //NL mod
+
+  // Calculate the position of the bottom of the pointSizeChoice, and place
+  // the fontRect there  (+5 for a nice gap) 
+
+  fontRect.y+=y+5; //NL mod
+
+  int by = (fontRect.y + fontRect.height + 5);
+
+  wxButton *okButton = new wxButton(this, wxID_OK, "OK", wxPoint(5, by));
+  (void) new wxButton(this, wxID_OK, "Cancel", wxPoint(50, by));
+
+  familyChoice->SetStringSelection(wxFontFamilyIntToString(dialogFont.GetFamily()));
+  styleChoice->SetStringSelection(wxFontStyleIntToString(dialogFont.GetStyle()));
+  weightChoice->SetStringSelection(wxFontWeightIntToString(dialogFont.GetWeight()));
+  wxString name(wxTheColourDatabase->FindName(fontData.fontColour));
+  colourChoice->SetStringSelection(name);
+    
+  underLineCheckBox->SetValue(dialogFont.GetUnderlined());
+
+  pointSizeChoice->SetSelection(dialogFont.GetPointSize());
+
+  okButton->SetDefault();
+
+  SetClientSize(400, by + 30);
+
+  Centre(wxBOTH);
+
+  wxEndBusyCursor();
+}
+
+void wxGenericFontDialog::InitializeFont(void)
+{
+  int fontFamily = wxSWISS;
+  int fontWeight = wxNORMAL;
+  int fontStyle = wxNORMAL;
+  int fontSize = 12;
+  int fontUnderline = FALSE;
+  if (fontData.initialFont.Ok())
+  {
+    fontFamily = fontData.initialFont.GetFamily();
+    fontWeight = fontData.initialFont.GetWeight();
+    fontStyle = fontData.initialFont.GetStyle();
+    fontSize = fontData.initialFont.GetPointSize();
+    fontUnderline = fontData.initialFont.GetUnderlined();
+  }
+  dialogFont = wxFont(fontSize, fontFamily, fontStyle, fontWeight, (fontUnderline != 0));
+
+}
+
+void wxGenericFontDialog::PaintFontBackground(wxDC& dc)
+{
+  dc.BeginDrawing();
+
+  dc.SetPen(*wxBLACK_PEN);
+  dc.SetBrush(*wxWHITE_BRUSH);
+  dc.DrawRectangle( fontRect.x, fontRect.y, fontRect.width, fontRect.height);
+  dc.EndDrawing();
+}
+
+void wxGenericFontDialog::PaintFont(wxDC& dc)
+{
+  dc.BeginDrawing();
+  if (dialogFont.Ok())
+  {
+    dc.SetFont(dialogFont);
+    // Calculate vertical centre
+    long w, h;
+    dc.GetTextExtent("X", &w, &h);
+    float cx = (float)(fontRect.x + 10);
+    float cy = (float)(fontRect.y + (fontRect.height/2.0) - (h/2.0));
+    dc.SetTextForeground(fontData.fontColour);
+    dc.SetClippingRegion( fontRect.x, fontRect.y, (long)(fontRect.width-2.0), (long)(fontRect.height-2.0));
+    dc.DrawText("ABCDEFGabcdefg12345", (long)cx, (long)cy);
+    dc.DestroyClippingRegion();
+	dc.SetFont(wxNullFont);
+  }
+  dc.EndDrawing();
+}
+
+void wxGenericFontDialog::OnChangeFont(wxCommandEvent& WXUNUSED(event))
+{
+  int fontFamily = wxFontFamilyStringToInt(WXSTRINGCAST familyChoice->GetStringSelection());
+  int fontWeight = wxFontWeightStringToInt(WXSTRINGCAST weightChoice->GetStringSelection());
+  int fontStyle = wxFontStyleStringToInt(WXSTRINGCAST styleChoice->GetStringSelection());
+  int fontSize = atoi(pointSizeChoice->GetStringSelection());
+  int fontUnderline = underLineCheckBox->GetValue();
+
+  dialogFont = wxFont(fontSize, fontFamily, fontStyle, fontWeight, (fontUnderline != 0));
+  if (colourChoice->GetStringSelection() != "")
+  {
+    wxColour *col = wxTheColourDatabase->FindColour(colourChoice->GetStringSelection());
+    if (col)
+    {
+      fontData.fontColour = *col;
+    }
+  }
+  wxClientDC dc(this);
+  PaintFontBackground(dc);
+  PaintFont(dc);
+}
+
+char *wxFontWeightIntToString(int weight)
+{
+  switch (weight)
+  {
+    case wxLIGHT:
+      return "Light";
+    case wxBOLD:
+      return "Bold";
+    case wxNORMAL:
+    default:
+      return "Normal";
+  }
+  return "Normal";
+}
+
+char *wxFontStyleIntToString(int style)
+{
+  switch (style)
+  {
+    case wxITALIC:
+      return "Italic";
+    case wxSLANT:
+      return "Slant";
+    case wxNORMAL:
+    default:
+      return "Normal";
+  }
+  return "Normal";
+}
+
+char *wxFontFamilyIntToString(int family)
+{
+  switch (family)
+  {
+    case wxROMAN:
+      return "Roman";
+    case wxDECORATIVE:
+      return "Decorative";
+    case wxMODERN:
+      return "Modern";
+    case wxSCRIPT:
+      return "Script";
+    case wxSWISS:
+    default:
+      return "Swiss";
+  }
+  return "Swiss";
+}
+
+int wxFontFamilyStringToInt(char *family)
+{
+  if (!family)
+    return wxSWISS;
+    
+  if (strcmp(family, "Roman") == 0)
+    return wxROMAN;
+  else if (strcmp(family, "Decorative") == 0)
+    return wxDECORATIVE;
+  else if (strcmp(family, "Modern") == 0)
+    return wxMODERN;
+  else if (strcmp(family, "Script") == 0)
+    return wxSCRIPT;
+  else return wxSWISS;
+}
+
+int wxFontStyleStringToInt(char *style)
+{
+  if (!style)
+    return wxNORMAL;
+  if (strcmp(style, "Italic") == 0)
+    return wxITALIC;
+  else if (strcmp(style, "Slant") == 0)
+    return wxSLANT;
+  else
+    return wxNORMAL;
+}
+
+int wxFontWeightStringToInt(char *weight)
+{
+  if (!weight)
+    return wxNORMAL;
+  if (strcmp(weight, "Bold") == 0)
+    return wxBOLD;
+  else if (strcmp(weight, "Light") == 0)
+    return wxLIGHT;
+  else
+    return wxNORMAL;
+}
+
+
diff --git a/src/generic/gridg.cpp b/src/generic/gridg.cpp
new file mode 100644
index 0000000000..2043f5e7a2
--- /dev/null
+++ b/src/generic/gridg.cpp
@@ -0,0 +1,2365 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        gridg.cpp
+// Purpose:     wxGenericGrid
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "gridg.h"
+#pragma interface
+#endif
+
+// For compilers that support precompilation, includes "wx/wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include <string.h>
+
+#include "wx/string.h"
+#include "wx/generic/gridg.h"
+#include "wx/settings.h"
+
+static wxFont *wxGridEntryFont = NULL;
+
+#define wxGRID_DRAG_NONE       0
+#define wxGRID_DRAG_LEFT_RIGHT 1
+#define wxGRID_DRAG_UP_DOWN    2
+
+IMPLEMENT_DYNAMIC_CLASS(wxGenericGrid, wxPanel)
+
+BEGIN_EVENT_TABLE(wxGenericGrid, wxPanel)
+	EVT_SIZE(wxGenericGrid::OnSize)
+	EVT_PAINT(wxGenericGrid::OnPaint)
+	EVT_MOUSE_EVENTS(wxGenericGrid::OnMouseEvent)
+    EVT_TEXT(wxGRID_TEXT_CTRL, wxGenericGrid::OnText)
+    EVT_COMMAND_SCROLL(wxGRID_HSCROLL, wxGenericGrid::OnGridScroll)
+    EVT_COMMAND_SCROLL(wxGRID_VSCROLL, wxGenericGrid::OnGridScroll)
+END_EVENT_TABLE()
+
+wxCursor *wxGenericGrid::horizontalSashCursor = NULL;
+wxCursor *wxGenericGrid::verticalSashCursor = NULL;
+
+wxGenericGrid::wxGenericGrid(void)
+{
+  hScrollBar = NULL;
+  vScrollBar = NULL;
+  batchCount = 0;
+  cellTextColour = *wxBLACK;
+  cellBackgroundColour = *wxWHITE;
+  labelTextColour = *wxBLACK;
+  labelBackgroundColour = *wxLIGHT_GREY;
+  labelBackgroundBrush = NULL;
+  labelTextFont = NULL;
+  cellTextFont = NULL;
+  textItem = NULL;
+  currentRectVisible = FALSE;
+  editable = TRUE;
+#if defined(__WIN95__)
+  scrollWidth = wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X);
+#else
+  scrollWidth = 16;
+#endif
+  dragStatus = wxGRID_DRAG_NONE;
+  dragRowOrCol = 0;
+  dragStartPosition = 0;
+  dragLastPosition = 0;
+  divisionPen = NULL;
+  wxGridEntryFont = NULL;
+  leftOfSheet = wxGRID_DEFAULT_SHEET_LEFT;
+  topOfSheet = wxGRID_DEFAULT_SHEET_TOP;
+  cellHeight = wxGRID_DEFAULT_CELL_HEIGHT;
+  totalGridWidth = 0;
+  totalGridHeight = 0;
+  colWidths = NULL;
+  rowHeights = NULL;
+  verticalLabelWidth = wxGRID_DEFAULT_VERTICAL_LABEL_WIDTH;
+  horizontalLabelHeight = wxGRID_DEFAULT_HORIZONAL_LABEL_HEIGHT;
+  verticalLabelAlignment = wxCENTRE;
+  horizontalLabelAlignment = wxCENTRE;
+  editControlPosition.x = wxGRID_DEFAULT_EDIT_X;
+  editControlPosition.y = wxGRID_DEFAULT_EDIT_Y;
+  editControlPosition.width = wxGRID_DEFAULT_EDIT_WIDTH;
+  editControlPosition.height = wxGRID_DEFAULT_EDIT_HEIGHT;
+  wCursorRow = 0;
+  wCursorColumn = 0;
+  scrollPosX = 0;
+  scrollPosY = 0;
+  bEditCreated = FALSE;
+  totalRows = 0;
+  totalCols = 0;
+  gridCells = NULL;
+  rowLabelCells = NULL;
+  colLabelCells = NULL;
+  textItem = NULL;
+}
+
+bool wxGenericGrid::Create(wxWindow *parent, const wxWindowID id, const wxPoint& pos, const wxSize& size,
+ const long style, const wxString& name)
+{
+  hScrollBar = NULL;
+  vScrollBar = NULL;
+  
+  batchCount = 0;
+  cellTextColour = *wxBLACK;
+  cellBackgroundColour = *wxWHITE;
+  labelTextColour = *wxBLACK;
+  labelBackgroundColour = *wxLIGHT_GREY;
+  labelBackgroundBrush = NULL;
+  labelTextFont = wxTheFontList->FindOrCreateFont(10, wxSWISS, wxNORMAL, wxBOLD);
+  cellTextFont = wxTheFontList->FindOrCreateFont(10, wxSWISS, wxNORMAL, wxNORMAL);
+  textItem = NULL;
+  currentRectVisible = FALSE;
+  editable = TRUE;
+#if defined(__WIN95__)
+  scrollWidth = wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X);
+#else
+  scrollWidth = 16;
+#endif
+  dragStatus = wxGRID_DRAG_NONE;
+  dragRowOrCol = 0;
+  dragStartPosition = 0;
+  dragLastPosition = 0;
+  divisionPen = wxThePenList->FindOrCreatePen("LIGHT GREY", 1, wxSOLID);
+  
+  if (!wxGridEntryFont)
+    wxGridEntryFont = new wxFont(9, wxSWISS, wxNORMAL, wxBOLD);
+
+  if (!horizontalSashCursor)
+  {
+    horizontalSashCursor = new wxCursor(wxCURSOR_SIZEWE);
+    verticalSashCursor = new wxCursor(wxCURSOR_SIZENS);
+  }
+    
+  SetLabelBackgroundColour(labelBackgroundColour);
+
+  leftOfSheet = wxGRID_DEFAULT_SHEET_LEFT;
+  topOfSheet = wxGRID_DEFAULT_SHEET_TOP;
+  cellHeight = wxGRID_DEFAULT_CELL_HEIGHT;
+  totalGridWidth = 0;
+  totalGridHeight = 0;
+  colWidths = NULL;
+  rowHeights = NULL;
+
+  verticalLabelWidth = wxGRID_DEFAULT_VERTICAL_LABEL_WIDTH;
+  horizontalLabelHeight = wxGRID_DEFAULT_HORIZONAL_LABEL_HEIGHT;
+  verticalLabelAlignment = wxCENTRE;
+  horizontalLabelAlignment = wxCENTRE;
+  editControlPosition.x = wxGRID_DEFAULT_EDIT_X;
+  editControlPosition.y = wxGRID_DEFAULT_EDIT_Y;
+  editControlPosition.width = wxGRID_DEFAULT_EDIT_WIDTH;
+  editControlPosition.height = wxGRID_DEFAULT_EDIT_HEIGHT;
+
+  wCursorRow = 0;
+  wCursorColumn = 0;
+  
+  scrollPosX = 0;
+  scrollPosY = 0;
+
+  /* Store the rect. coordinates for the current cell */
+  SetCurrentRect(wCursorRow, wCursorColumn);
+
+  bEditCreated = FALSE;
+
+  totalRows = 0;
+  totalCols = 0;
+  gridCells = NULL;
+  rowLabelCells = NULL;
+  colLabelCells = NULL;
+  textItem = NULL;
+
+  wxPanel::Create(parent, id, pos, size, style, name);
+
+  SetButtonFont(*wxGridEntryFont);
+  SetLabelFont(*wxGridEntryFont);
+  
+  textItem = new wxTextCtrl(this, wxGRID_TEXT_CTRL, "",
+     wxPoint(editControlPosition.x, editControlPosition.y), wxSize(editControlPosition.width, -1),
+     0);
+  textItem->Show(TRUE);
+//  textItem->SetLabel("");
+  textItem->SetFocus();
+  int controlW, controlH;
+  
+  textItem->GetSize(&controlW, &controlH);
+  editControlPosition.height = controlH;
+  
+  topOfSheet = editControlPosition.x + controlH + 2;
+
+  bEditCreated = TRUE;
+  
+  hScrollBar = new wxScrollBar(this, wxGRID_HSCROLL, wxPoint(0, 0), wxSize(20, 100), wxHORIZONTAL);
+  vScrollBar = new wxScrollBar(this, wxGRID_VSCROLL, wxPoint(0, 0), wxSize(100, 20), wxVERTICAL);
+//  hScrollBar->Show(FALSE);
+//  vScrollBar->Show(FALSE);
+  AllowDoubleClick(TRUE);
+
+  return TRUE;
+}
+
+wxGenericGrid::~wxGenericGrid(void)
+{
+  ClearGrid();
+}
+
+void wxGenericGrid::ClearGrid(void)
+{
+  int i,j;
+  if (gridCells)
+  {
+    for (i = 0; i < totalRows; i++)
+    {
+      for (j = 0; j < totalCols; j++)
+        if (gridCells[i][j])
+          delete gridCells[i][j];
+      delete[] gridCells[i];
+    }
+    delete[] gridCells;
+    gridCells = NULL;
+  }
+  if (colWidths)
+    delete[] colWidths;
+  colWidths = NULL;
+  if (rowHeights)
+    delete[] rowHeights;
+  rowHeights = NULL;
+  
+  if (rowLabelCells)
+  {
+    for (i = 0; i < totalRows; i++)
+      delete rowLabelCells[i];
+    delete[] rowLabelCells;
+    rowLabelCells = NULL;
+  }
+  if (colLabelCells)
+  {
+    for (i = 0; i < totalCols; i++)
+      delete colLabelCells[i];
+    delete[] colLabelCells;
+    colLabelCells = NULL;
+  }
+}
+
+bool wxGenericGrid::CreateGrid(int nRows, int nCols, wxString **cellValues, short *widths,
+     short defaultWidth, short defaultHeight)
+{
+  totalRows = nRows;
+  totalCols = nCols;
+
+  int i,j;
+  colWidths = new short[nCols];
+  rowHeights = new short[nRows];
+  for (i = 0; i < nCols; i++)
+    if (widths)
+      colWidths[i] = widths[i];
+    else
+      colWidths[i] = defaultWidth;
+  for (i = 0; i < nRows; i++)
+    rowHeights[i] = defaultHeight;
+  
+  gridCells = new wxGridCell **[nRows];
+  
+  for (i = 0; i < nRows; i++)
+    gridCells[i] = new wxGridCell *[nCols];
+    
+  for (i = 0; i < nRows; i++)
+    for (j = 0; j < nCols; j++)
+      if (cellValues)
+      {
+        gridCells[i][j] = OnCreateCell();
+        gridCells[i][j]->SetTextValue(cellValues[i][j]);
+      }
+      else
+        gridCells[i][j] = NULL;
+        
+  rowLabelCells = new wxGridCell *[nRows];
+  for (i = 0; i < nRows; i++)
+    rowLabelCells[i] = new wxGridCell(this);
+  colLabelCells = new wxGridCell *[nCols];
+  for (i = 0; i < nCols; i++)
+    colLabelCells[i] = new wxGridCell(this);
+
+  wCursorRow = wCursorColumn = 0;
+  SetCurrentRect(0, 0);
+
+  // Need to determine various dimensions
+  UpdateDimensions();
+
+  // Number of 'lines'
+  int objectSizeX = totalCols;
+  int pageSizeX = 1;
+  int viewLengthX = totalCols;
+  hScrollBar->SetViewLength(viewLengthX);
+  hScrollBar->SetObjectLength(objectSizeX);
+  hScrollBar->SetPageSize(pageSizeX);
+
+  int objectSizeY = totalRows;
+  int pageSizeY = 1;
+  int viewLengthY = totalRows;
+
+  vScrollBar->SetViewLength(viewLengthY);
+  vScrollBar->SetObjectLength(objectSizeY);
+  vScrollBar->SetPageSize(pageSizeY);
+
+  AdjustScrollbars();
+
+  OnChangeLabels();
+  OnChangeSelectionLabel();
+  
+  return TRUE;
+}
+
+// Need to determine various dimensions
+void wxGenericGrid::UpdateDimensions(void)
+{
+  int canvasWidth, canvasHeight;
+  GetSize(&canvasWidth, &canvasHeight);
+  
+  if (editable)
+  {
+    int controlW, controlH;
+    GetTextItem()->GetSize(&controlW, &controlH);
+    topOfSheet = editControlPosition.x + controlH + 2;
+  }
+  else
+    topOfSheet = 0;
+  rightOfSheet = leftOfSheet + verticalLabelWidth;
+  int i;
+  for (i = scrollPosX; i < totalCols; i++)
+  {
+    if (rightOfSheet > canvasWidth)
+      break;
+    else
+      rightOfSheet += colWidths[i];
+  }
+  bottomOfSheet = topOfSheet + horizontalLabelHeight;
+  for (i = scrollPosY; i < totalRows; i++)
+  {
+    if (bottomOfSheet > canvasHeight)
+      break;
+    else
+      bottomOfSheet += rowHeights[i];
+  }
+    
+  totalGridWidth = leftOfSheet + verticalLabelWidth;
+  for (i = 0; i < totalCols; i++)
+  {
+    totalGridWidth += colWidths[i];
+  }
+  totalGridHeight = topOfSheet + horizontalLabelHeight;
+  for (i = 0; i < totalRows; i++)
+  {
+    totalGridHeight += rowHeights[i];
+  }
+}
+
+wxGridCell *wxGenericGrid::GetCell(int row, int col)
+{
+  if (!gridCells)
+    return NULL;
+
+  if ((row >= totalRows) || (col >= totalCols))
+    return NULL;
+    
+  wxGridCell *cell = gridCells[row][col];
+  if (!cell)
+  {
+    gridCells[row][col] = OnCreateCell();
+    return gridCells[row][col];
+  }
+  else
+    return cell;
+}
+
+void wxGenericGrid::SetGridClippingRegion(wxDC *dc)
+{
+  int scrollWidthHoriz = 0;
+  int scrollWidthVert = 0;
+  int cw, ch;
+  GetClientSize(&cw, &ch);
+
+  if (hScrollBar && hScrollBar->IsShown())
+    scrollWidthHoriz = scrollWidth;
+  if (vScrollBar && vScrollBar->IsShown())
+    scrollWidthVert = scrollWidth;
+
+  // Don't paint over the scrollbars
+  dc->SetClippingRegion(leftOfSheet, topOfSheet,
+     cw - scrollWidthVert - leftOfSheet, ch - scrollWidthHoriz - topOfSheet);
+}
+
+void wxGenericGrid::OnPaint(wxPaintEvent& WXUNUSED(event))
+{
+/*
+  static bool inPaint = FALSE;
+
+  if ( inPaint )
+	return;
+
+  inPaint = TRUE;
+*/
+
+  wxRectangle rect;
+
+  wxPaintDC dc(this);
+  dc.BeginDrawing();
+  dc.SetOptimization(FALSE);
+  
+  SetGridClippingRegion(&dc);
+
+  DrawLabelAreas(&dc);
+  DrawEditableArea(&dc);
+  DrawColumnLabels(&dc);
+  DrawRowLabels(&dc);
+  DrawCells(&dc);
+  DrawGridLines(&dc);
+
+  /* Hilight present cell */
+  SetCurrentRect(wCursorRow, wCursorColumn);
+  if (currentRectVisible)
+    HighlightCell(&dc);
+
+  dc.DestroyClippingRegion();
+  dc.SetOptimization(TRUE);
+  dc.EndDrawing();
+
+//  inPaint = FALSE;
+}
+
+void wxGenericGrid::DrawLabelAreas(wxDC *dc)
+{
+  int cw, ch;
+  GetClientSize(&cw, &ch);
+
+  dc->SetPen(*wxTRANSPARENT_PEN);
+//  dc->SetBrush(*dc->GetBackground());
+
+  // Should blank out any area which isn't going to be painted over.
+//  dc->DrawRectangle(leftOfSheet, bottomOfSheet, cw - leftOfSheet, ch - bottomOfSheet);
+//  dc->DrawRectangle(rightOfSheet, topOfSheet, cw - rightOfSheet, ch - topOfSheet);
+
+  // Paint the label areas
+  dc->SetBrush(*labelBackgroundBrush);
+//  dc->DrawRectangle(leftOfSheet, topOfSheet, rightOfSheet - leftOfSheet + 1, horizontalLabelHeight + 1);
+  dc->DrawRectangle(leftOfSheet, topOfSheet, cw-leftOfSheet, horizontalLabelHeight + 1);
+//  dc->DrawRectangle(leftOfSheet, topOfSheet, verticalLabelWidth + 1, bottomOfSheet - topOfSheet + 1);
+  dc->DrawRectangle(leftOfSheet, topOfSheet, verticalLabelWidth + 1, ch-topOfSheet);
+}
+
+void wxGenericGrid::DrawEditableArea(wxDC *dc)
+{
+  int cw, ch;
+  GetClientSize(&cw, &ch);
+
+  dc->SetPen(*wxTRANSPARENT_PEN);
+  dc->SetBrush(*wxTheBrushList->FindOrCreateBrush(cellBackgroundColour, wxSOLID));
+//  dc->DrawRectangle(leftOfSheet+verticalLabelWidth, topOfSheet+horizontalLabelHeight,
+//      rightOfSheet-(leftOfSheet+verticalLabelWidth) + 1, bottomOfSheet - (topOfSheet+horizontalLabelHeight) + 1);
+  dc->DrawRectangle(leftOfSheet+verticalLabelWidth, topOfSheet+horizontalLabelHeight,
+      cw-(leftOfSheet+verticalLabelWidth), ch - (topOfSheet+horizontalLabelHeight));
+}
+
+void wxGenericGrid::DrawGridLines(wxDC *dc)
+{
+  int cw, ch;
+  GetClientSize(&cw, &ch);
+  
+  int i;
+
+  if (divisionPen)
+  {
+    dc->SetPen(*divisionPen);
+
+    int heightCount = topOfSheet + horizontalLabelHeight;
+
+    // Draw horizontal grey lines for cells
+    for (i = scrollPosY; i < (totalRows+1); i++)
+    {
+      if (heightCount > ch)
+        break;
+      else
+      {
+        dc->DrawLine(leftOfSheet, heightCount,
+                   cw, heightCount);
+        if (i < totalRows)
+          heightCount += rowHeights[i];
+      }
+    }
+  }
+
+  if (verticalLabelWidth > 0)
+  {
+    dc->SetPen(*wxBLACK_PEN);
+
+    // Draw horizontal black lines for row labels
+    int heightCount = topOfSheet + horizontalLabelHeight;
+    for (i = scrollPosY; i < (totalRows+1); i++)
+    {
+      if (heightCount > ch)
+        break;
+      else
+      {
+        dc->DrawLine(leftOfSheet, heightCount,
+                     verticalLabelWidth, heightCount);
+        if (i < totalRows)
+          heightCount += rowHeights[i];
+      }
+    }
+    // Draw a black vertical line for row number cells
+    dc->DrawLine(leftOfSheet + verticalLabelWidth, topOfSheet,
+      leftOfSheet + verticalLabelWidth, ch);
+    // First vertical line
+    dc->DrawLine(leftOfSheet, topOfSheet, leftOfSheet, ch);
+
+    dc->SetPen(*wxWHITE_PEN);
+
+    // Draw highlights on row labels
+    heightCount = topOfSheet + horizontalLabelHeight;
+    for (i = scrollPosY; i < totalRows; i++)
+    {
+      if (heightCount > ch)
+        break;
+      else
+      {
+        dc->DrawLine(leftOfSheet+1, heightCount+1,
+                     verticalLabelWidth, heightCount+1);
+        dc->DrawLine(leftOfSheet+1, heightCount+1,
+                     leftOfSheet+1, heightCount + rowHeights[i] - 1);
+        heightCount += rowHeights[i];
+      }
+    }
+    // Last one - down to the floor.
+    dc->DrawLine(leftOfSheet+1, heightCount+1,
+                 verticalLabelWidth, heightCount+1);
+    dc->DrawLine(leftOfSheet+1, heightCount+1,
+                   leftOfSheet+1, ch);
+
+  }
+
+  if (divisionPen)
+  {
+    dc->SetPen(*divisionPen);
+
+    // Draw vertical grey lines for cells
+    int widthCount = leftOfSheet + verticalLabelWidth;
+    for (i = scrollPosX; i < totalCols; i++)
+    {
+      if (widthCount > cw)
+        break;
+      else
+      {
+        // Skip the first one
+        if (i != scrollPosX)
+        {
+         dc->DrawLine(widthCount, topOfSheet + horizontalLabelHeight,
+                       widthCount, bottomOfSheet);
+        }
+        widthCount += colWidths[i];
+      }
+    }
+    // Last one
+    dc->DrawLine(widthCount, topOfSheet + horizontalLabelHeight,
+                    widthCount, bottomOfSheet);
+  }
+
+  dc->SetPen(*wxBLACK_PEN);
+
+  // Draw two black horizontal lines for column number cells
+  dc->DrawLine(
+          leftOfSheet, topOfSheet,
+          cw, topOfSheet);
+  dc->DrawLine(leftOfSheet,  topOfSheet + horizontalLabelHeight,
+               cw, topOfSheet + horizontalLabelHeight);
+
+  if (horizontalLabelHeight > 0)
+  {
+    int widthCount = leftOfSheet + verticalLabelWidth;
+  
+    // Draw black vertical lines for column number cells
+    for (i = scrollPosX; i < totalCols; i++)
+    {
+      if (widthCount > cw)
+        break;
+      else
+      {
+        dc->DrawLine(widthCount, topOfSheet,
+                      widthCount, topOfSheet + horizontalLabelHeight);
+        widthCount += colWidths[i];
+      }
+    }
+
+    // Last one
+    dc->DrawLine(widthCount, topOfSheet,
+                    widthCount, topOfSheet + horizontalLabelHeight);
+
+    // Draw highlights
+    dc->SetPen(*wxWHITE_PEN);
+    widthCount = leftOfSheet + verticalLabelWidth;
+  
+    for (i = scrollPosX; i < totalCols; i++)
+    {
+      if (widthCount > cw)
+        break;
+      else
+      {
+        dc->DrawLine(widthCount+1, topOfSheet+1,
+                     widthCount+colWidths[i], topOfSheet+1);
+        dc->DrawLine(widthCount+1, topOfSheet+1,
+                     widthCount+1, topOfSheet+horizontalLabelHeight);
+        widthCount += colWidths[i];
+      }
+    }
+    // Last one - to the right side of the canvas.
+    dc->DrawLine(widthCount+1, topOfSheet+1,
+                   cw, topOfSheet+1);
+    dc->DrawLine(widthCount+1, topOfSheet+1,
+                   widthCount+1, topOfSheet+horizontalLabelHeight);
+
+  }
+}
+
+void wxGenericGrid::DrawColumnLabels(wxDC *dc)
+{
+  int cw, ch;
+  GetClientSize(&cw, &ch);
+
+  if (horizontalLabelHeight == 0)
+    return;
+    
+  int i;
+  wxRectangle rect;
+
+  // Draw letters for columns
+  rect.y = topOfSheet + 1;
+  rect.height = horizontalLabelHeight - 1;
+
+  dc->SetTextBackground(labelBackgroundColour);
+  dc->SetBackgroundMode(wxTRANSPARENT);
+//  dc->SetTextForeground(labelTextColour);
+  
+  int widthCount = leftOfSheet + verticalLabelWidth;
+  for (i = scrollPosX; i < totalCols; i++)
+  {
+     if (widthCount > cw)
+       break;
+     else
+     {
+       rect.x = 1 + widthCount;
+       rect.width = colWidths[i];
+       DrawColumnLabel(dc, &rect, i);
+
+       widthCount += colWidths[i];
+     }
+  }
+}
+
+void wxGenericGrid::DrawColumnLabel(wxDC *dc, wxRectangle *rect, int col)
+{
+  wxGridCell *cell = GetLabelCell(wxHORIZONTAL, col);
+  if (cell)
+  {
+    wxRectangle rect2;
+    rect2 = *rect;
+    rect2.x += 3;
+    rect2.y += 2;
+    rect2.width -= 5;
+    rect2.height -= 4;
+    dc->SetTextForeground(GetLabelTextColour());
+    dc->SetFont(*GetLabelTextFont());
+	if ( !cell->GetTextValue().IsNull() )
+    	DrawTextRect(dc, cell->GetTextValue(), &rect2, GetLabelAlignment(wxHORIZONTAL));
+  }
+}
+
+void wxGenericGrid::DrawRowLabels(wxDC *dc)
+{
+  int cw, ch;
+  GetClientSize(&cw, &ch);
+
+  if (verticalLabelWidth == 0)
+    return;
+
+  int i;
+  wxRectangle rect;
+  
+  // Draw numbers for rows
+  rect.x = leftOfSheet;
+  rect.width = verticalLabelWidth;
+
+  int heightCount = topOfSheet + horizontalLabelHeight;
+
+  dc->SetTextBackground(labelBackgroundColour);
+  dc->SetBackgroundMode(wxTRANSPARENT);
+
+  for (i = scrollPosY; i < totalRows; i++)
+  {
+     if (heightCount > ch)
+       break;
+     else
+     {
+       rect.y = 1 + heightCount;
+       rect.height = rowHeights[i];
+       DrawRowLabel(dc, &rect, i);
+     
+       heightCount += rowHeights[i];
+     }
+  }
+}
+
+void wxGenericGrid::DrawRowLabel(wxDC *dc, wxRectangle *rect, int row)
+{
+  wxGridCell *cell = GetLabelCell(wxVERTICAL, row);
+  if (cell)
+  {
+    wxRectangle rect2;
+    rect2 = *rect;
+    rect2.x += 3;
+    rect2.y += 2;
+    rect2.width -= 5;
+    rect2.height -= 4;
+    dc->SetTextForeground(GetLabelTextColour());
+    dc->SetFont(*GetLabelTextFont());
+	if ( !cell->GetTextValue().IsNull() )
+    	DrawTextRect(dc, cell->GetTextValue(), &rect2, GetLabelAlignment(wxVERTICAL));
+  }
+}
+
+void wxGenericGrid::DrawCells(wxDC *dc)
+{
+  int cw, ch;
+  GetClientSize(&cw, &ch);
+
+  int i,j;
+  
+  // Draw value corresponding to each cell
+  for (i = scrollPosY; i < totalRows; i++)
+  {
+    for (j = scrollPosX; j < totalCols; j++)
+    {
+      SetCurrentRect(i, j, cw, ch);
+      if (currentRectVisible)
+      {
+        DrawCellBackground(dc, &CurrentRect, i, j);
+        DrawCellValue(dc, &CurrentRect, i, j);
+      }
+      if (CurrentRect.x > cw)
+        break;
+    }
+    if (CurrentRect.y > ch)
+      break;
+  }
+  dc->SetBackgroundMode(wxSOLID);
+  dc->SetPen(*wxBLACK_PEN);
+}
+
+void wxGenericGrid::DrawCellBackground(wxDC *dc, wxRectangle *rect, int row, int col)
+{
+  wxGridCell *cell = GetCell(row, col);
+  if (cell)
+  {
+    dc->SetBrush(*cell->GetBackgroundBrush());
+    dc->SetPen(*wxTRANSPARENT_PEN);
+#ifdef __MOTIF__
+    dc->DrawRectangle(rect->x+1, rect->y+1, rect->width-1, rect->height-1);
+#else
+    dc->DrawRectangle(rect->x+1, rect->y+1, rect->width, rect->height);
+#endif
+    dc->SetPen(*wxBLACK_PEN);
+  }
+}
+
+void wxGenericGrid::DrawCellValue(wxDC *dc, wxRectangle *rect, int row, int col)
+{
+  wxGridCell *cell = GetCell(row, col);
+  if (cell)
+  {
+    wxBitmap *bitmap = cell->GetCellBitmap();
+    wxRectangle rect2;
+    rect2 = *rect;
+    rect2.x += 3;
+    rect2.y += 2;
+    rect2.width -= 5;
+    rect2.height -= 4;
+
+    if (bitmap)
+    {
+      DrawBitmapRect(dc, bitmap, &rect2, cell->GetAlignment());
+    }
+    else
+    {
+      dc->SetBackgroundMode(wxTRANSPARENT);
+      dc->SetTextForeground(cell->GetTextColour());
+      dc->SetFont(*cell->GetFont());
+
+	  if ( !cell->GetTextValue().IsNull() )
+      	DrawTextRect(dc, cell->GetTextValue(), &rect2, cell->GetAlignment());
+    }
+  }
+}
+
+void wxGenericGrid::AdjustScrollbars(void)
+{
+  int cw, ch;
+  GetClientSize(&cw, &ch);
+  
+  // To calculate the number of steps for each scrollbar,
+  // we need to see how much will fit onto the canvas
+  // at the present size. So:
+  // 1) Find the *last* row r1 such that when it's at the top of the
+  //    window, all the remaining rows are visible.
+  // 2) There should therefore be r1 - 1 steps in the scrollbar.
+  // Similarly with columns.
+
+  // IGNORE THE ABOVE, it's crap.
+  // We find the view size by seeing how many rows/cols fit on
+  // the current view.
+  // BUT... this means that the scrollbar should be adjusted every time
+  // it's scrolled, as well as when sized, because with variable size rows/cols,
+  // the number of rows/col visible on the view differs according to what bit
+  // you're looking at. The object length is always the same, but the
+  // view length differs.
+
+  // Since this may not be known until the end of this function, we should probably call AdjustScrollbars
+  // twice.
+  int vertScrollBarWidth = scrollWidth;
+  int horizScrollBarHeight = scrollWidth;
+  if (vScrollBar && !vScrollBar->IsShown())
+    vertScrollBarWidth = 0;
+  if (hScrollBar && !hScrollBar->IsShown())
+    horizScrollBarHeight = 0;
+  
+  int noHorizSteps = 0;
+  int noVertSteps = 0;
+  
+  if (totalGridWidth <= cw)
+    noHorizSteps = 0;
+  else
+  {
+    noHorizSteps = 0;
+    int widthCount = 0;
+/*
+    if (GetLabelSize(wxVERTICAL) > 0)
+      noHorizSteps ++;
+*/
+
+    int i;
+	int nx = 0;
+    for (i = scrollPosX ; i < totalCols; i++)
+    {
+      widthCount += colWidths[i];
+	  // A partial bit doesn't count, we still have to scroll to see the
+	  // rest of it
+      if (widthCount + leftOfSheet + verticalLabelWidth > (cw-vertScrollBarWidth))
+        break;
+	  else
+   	    nx ++;
+
+    }
+    
+    noHorizSteps += nx;
+  }
+  if (totalGridHeight <= ch)
+    noVertSteps = 0;
+  else
+  {
+    noVertSteps = 0;
+    int heightCount = 0;
+/*
+    if (GetLabelSize(wxHORIZONTAL) > 0)
+      noVertSteps ++;
+*/
+
+    int i;
+	int ny = 0;
+    for (i = scrollPosY ; i < totalRows; i++)
+    {
+      heightCount += rowHeights[i];
+	  // A partial bit doesn't count, we still have to scroll to see the
+	  // rest of it
+      if (heightCount + topOfSheet + horizontalLabelHeight > (ch-horizScrollBarHeight))
+        break;
+	  else
+	    ny ++;
+    }
+    
+    noVertSteps += ny;
+  }
+  
+  if (totalGridWidth <= cw)
+  {
+	if ( hScrollBar )
+    	hScrollBar->Show(FALSE);
+    SetScrollPosX(0);
+  }
+  else
+  {
+	if ( hScrollBar )
+    	hScrollBar->Show(TRUE);
+  }
+
+  if (totalGridHeight <= ch)
+  {
+	if ( vScrollBar )
+    	vScrollBar->Show(FALSE);
+    SetScrollPosY(0);
+  }
+  else
+  {
+	if ( vScrollBar )
+    	vScrollBar->Show(TRUE);
+  }
+
+  UpdateDimensions(); // Necessary in case scrollPosX/Y changed
+
+  vertScrollBarWidth = scrollWidth;
+  horizScrollBarHeight = scrollWidth;
+  if (vScrollBar && !vScrollBar->IsShown())
+    vertScrollBarWidth = 0;
+  if (hScrollBar && !hScrollBar->IsShown())
+    horizScrollBarHeight = 0;
+
+  if (hScrollBar)
+  {
+    int nCols = GetCols();
+/*
+    hScrollBar->SetPageSize(wxMax(noHorizSteps, 1));
+    hScrollBar->SetViewLength(wxMax(noHorizSteps, 1));
+    hScrollBar->SetObjectLength(nCols);
+*/
+    hScrollBar->SetScrollbar(hScrollBar->GetPosition(), wxMax(noHorizSteps, 1), nCols, wxMax(noHorizSteps, 1));
+
+    hScrollBar->SetSize(leftOfSheet, ch - scrollWidth,
+      cw - vertScrollBarWidth - leftOfSheet, scrollWidth);
+  }
+       
+  if (vScrollBar)
+  {
+    int nRows = GetRows();
+/*
+    vScrollBar->SetPageSize(wxMax(noVertSteps, 1));
+    vScrollBar->SetViewLength(wxMax(noVertSteps, 1));
+    vScrollBar->SetObjectLength(nRows);
+*/
+
+    vScrollBar->SetScrollbar(vScrollBar->GetPosition(), wxMax(noVertSteps, 1), nRows, wxMax(noVertSteps, 1));
+    vScrollBar->SetSize(cw - scrollWidth, topOfSheet,
+       scrollWidth, ch - topOfSheet - horizScrollBarHeight);
+  }
+}
+
+void wxGenericGrid::OnSize(wxSizeEvent& WXUNUSED(event) )
+{
+  if (!vScrollBar || !hScrollBar)
+	  return;
+
+  AdjustScrollbars();
+  
+  int cw, ch;
+  GetClientSize(&cw, &ch);
+
+  if (GetTextItem() && GetTextItem()->IsShown())
+  {
+    GetTextItem()->SetSize(editControlPosition.x, editControlPosition.y,
+      cw - editControlPosition.x, editControlPosition.height);
+  }
+}
+
+bool wxGenericGrid::CellHitTest(int x, int y, int *row, int *col)
+{
+      // Find the selected cell and call OnSelectCell
+      if (x >= (leftOfSheet + verticalLabelWidth) && y >= (topOfSheet + horizontalLabelHeight) &&
+          x <= rightOfSheet && y <= bottomOfSheet)
+      {
+         // Calculate the cell number from x and y
+         x -= (verticalLabelWidth + leftOfSheet);
+         y -= (topOfSheet + horizontalLabelHeight);
+
+         int i;
+         
+         // Now we need to do a hit test for which row we're on
+         int currentHeight = 0;
+         for (i = scrollPosY; i < totalRows; i++)
+         {
+            if (y >= currentHeight && y <= (currentHeight + rowHeights[i]))
+            {
+              *row = i;
+              break;
+            }
+            currentHeight += rowHeights[i];
+         }
+         
+         // Now we need to do a hit test for which column we're on
+         int currentWidth = 0;
+         for (i = scrollPosX; i < totalCols; i++)
+         {
+            if (x >= currentWidth && x <= (currentWidth + colWidths[i]))
+            {
+              *col = i;
+              break;
+            }
+            currentWidth += colWidths[i];
+         }
+         return TRUE;
+       }
+  return FALSE;
+}
+
+bool wxGenericGrid::LabelSashHitTest(int x, int y, int *orientation, int *rowOrCol, int *startPos)
+{
+  int i;
+  int tolerance = 3;
+  
+  if (x >= (leftOfSheet + verticalLabelWidth) && y >= topOfSheet &&
+      x <= rightOfSheet && y <= (topOfSheet + horizontalLabelHeight))
+  {
+    // We may be on a column label sash.
+    int currentWidth = leftOfSheet + verticalLabelWidth;
+    for (i = scrollPosX; i < totalCols; i++)
+    {
+      if (x >= (currentWidth + colWidths[i] - tolerance) && x <= (currentWidth + colWidths[i] + tolerance))
+      {
+        *orientation = wxHORIZONTAL;
+        *rowOrCol = i;
+        *startPos = currentWidth;
+        return TRUE;
+      }
+      currentWidth += colWidths[i];
+    }
+    return FALSE;
+  }
+  else if (x >= leftOfSheet && y >= (topOfSheet + horizontalLabelHeight) &&
+      x <= (leftOfSheet + verticalLabelWidth) && y <= bottomOfSheet)
+  {
+    // We may be on a row label sash.
+    int currentHeight = topOfSheet + horizontalLabelHeight;
+    for (i = scrollPosY; i < totalRows; i++)
+    {
+      if (y >= (currentHeight + rowHeights[i] - tolerance) && y <= (currentHeight + rowHeights[i] + tolerance))
+      {
+        *orientation = wxVERTICAL;
+        *rowOrCol = i;
+        *startPos = currentHeight;
+        return TRUE;
+      }
+      currentHeight += rowHeights[i];
+    }
+    return FALSE;
+  }
+  return FALSE;
+}
+
+bool wxGenericGrid::LabelHitTest(int x, int y, int *row, int *col)
+{
+      // Find the selected label
+      if (x >= leftOfSheet && y >= topOfSheet &&
+          x <= rightOfSheet && y <= bottomOfSheet)
+      {
+         // Calculate the cell number from x and y
+         x -= leftOfSheet;
+         y -= topOfSheet;
+
+         int i;
+
+         // Now we need to do a hit test for which row we're on
+         int currentHeight = horizontalLabelHeight;
+         for (i = scrollPosY; i < totalRows; i++)
+         {
+            if (y >= currentHeight && y <= (currentHeight + rowHeights[i]))
+            {
+              *row = i;
+              break;
+            }
+            currentHeight += rowHeights[i];
+         }
+         if (y >= 0 && y <= horizontalLabelHeight)
+         {
+             *row = -1;
+         }
+
+         // Now we need to do a hit test for which column we're on
+         int currentWidth = verticalLabelWidth;
+         for (i = scrollPosX; i < totalCols; i++)
+         {
+            if (x >= currentWidth && x <= (currentWidth + colWidths[i]))
+            {
+              *col = i;
+              break;
+            }
+            currentWidth += colWidths[i];
+         }
+         if (x >= 0 && x <= verticalLabelWidth)
+         {
+             *col = -1;
+         }
+
+         if ((*col == -1) || (*row == -1))
+         {
+             return TRUE;
+         }
+       }
+  return FALSE;
+}
+
+void wxGenericGrid::OnMouseEvent(wxMouseEvent& ev)
+{
+  if (ev.LeftDown())
+  {
+    wxClientDC dc(this);
+    dc.BeginDrawing();
+    
+    int row, col;
+    if (CellHitTest((int)ev.GetX(), (int)ev.GetY(), &row, &col))
+    {
+      OnSelectCellImplementation(& dc, row, col);
+      OnCellLeftClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
+    }
+    if (LabelHitTest((int)ev.GetX(), (int)ev.GetY(), &row, &col))
+    {
+      OnLabelLeftClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
+    }
+    dc.EndDrawing();
+  }
+  else if (ev.Dragging() && ev.LeftIsDown())
+  {
+    switch (dragStatus)
+    {
+      case wxGRID_DRAG_NONE:
+      {
+        int orientation;
+        if (LabelSashHitTest((int)ev.GetX(), (int)ev.GetY(), &orientation, &dragRowOrCol, &dragStartPosition))
+        {
+          if (orientation == wxHORIZONTAL)
+          {
+            dragStatus = wxGRID_DRAG_LEFT_RIGHT;
+            SetCursor(*horizontalSashCursor);
+            dragLastPosition = (int)ev.GetX();
+          }
+          else
+          {
+            dragStatus = wxGRID_DRAG_UP_DOWN;
+            SetCursor(*verticalSashCursor);
+            dragLastPosition = (int)ev.GetY();
+          }
+          wxClientDC dc(this);
+          dc.BeginDrawing();
+          dc.SetLogicalFunction(wxINVERT);
+          if (orientation == wxHORIZONTAL)
+            dc.DrawLine((int)ev.GetX(), topOfSheet, (int)ev.GetX(), bottomOfSheet);
+          else
+            dc.DrawLine(leftOfSheet, (int)ev.GetY(), rightOfSheet, (int)ev.GetY());
+          dc.EndDrawing();
+          
+          CaptureMouse();
+        }
+        break;
+      }
+      case wxGRID_DRAG_LEFT_RIGHT:
+      {
+        wxClientDC dc(this);
+        dc.BeginDrawing();
+        dc.SetLogicalFunction(wxINVERT);
+        dc.DrawLine(dragLastPosition, topOfSheet, dragLastPosition, bottomOfSheet);
+
+        dc.DrawLine((int)ev.GetX(), topOfSheet, (int)ev.GetX(), bottomOfSheet);
+        dc.EndDrawing();
+
+        dragLastPosition = (int)ev.GetX();
+        SetCursor(*horizontalSashCursor);
+        break;
+      }
+      case wxGRID_DRAG_UP_DOWN:
+      {
+        wxClientDC dc(this);
+        dc.BeginDrawing();
+        dc.SetLogicalFunction(wxINVERT);
+        dc.DrawLine(leftOfSheet, dragLastPosition, rightOfSheet, dragLastPosition);
+
+        dc.DrawLine(leftOfSheet, (int)ev.GetY(), rightOfSheet, (int)ev.GetY());
+        dc.EndDrawing();
+
+        dragLastPosition = (int)ev.GetY();
+        SetCursor(*verticalSashCursor);
+        break;
+      }
+    }
+  }
+  else if (ev.Moving())
+  {
+    int rowOrCol, orientation, startPos;
+    if (LabelSashHitTest((int)ev.GetX(), (int)ev.GetY(), &orientation, &rowOrCol, &startPos))
+    {
+      if (orientation == wxHORIZONTAL)
+        SetCursor(*horizontalSashCursor);
+       else
+        SetCursor(*verticalSashCursor);
+    }
+    else
+      SetCursor(*wxSTANDARD_CURSOR);
+  }
+  else if (ev.LeftUp())
+  {
+    switch (dragStatus)
+    {
+      case wxGRID_DRAG_LEFT_RIGHT:
+      {
+        wxClientDC dc(this);
+        dc.BeginDrawing();
+        dc.SetLogicalFunction(wxINVERT);
+        dc.DrawLine(dragLastPosition, topOfSheet, dragLastPosition, bottomOfSheet);
+        dc.SetLogicalFunction(wxCOPY);
+        dc.EndDrawing();
+
+        ReleaseMouse();
+        if (ev.GetX() > dragStartPosition)
+        {
+          colWidths[dragRowOrCol] = (short)(ev.GetX() - dragStartPosition);
+          UpdateDimensions();
+          AdjustScrollbars();
+          Refresh();
+        }
+        SetCursor(*wxSTANDARD_CURSOR);
+        int cw, ch;
+        GetClientSize(&cw, &ch);
+		wxSizeEvent evt;
+        OnSize(evt);
+        break;
+      }
+      case wxGRID_DRAG_UP_DOWN:
+      {
+        wxClientDC dc(this);
+        dc.BeginDrawing();
+        dc.SetLogicalFunction(wxINVERT);
+        dc.DrawLine(leftOfSheet, dragLastPosition, rightOfSheet, dragLastPosition);
+        dc.SetLogicalFunction(wxCOPY);
+        dc.EndDrawing();
+
+        ReleaseMouse();
+        if (ev.GetY() > dragStartPosition)
+        {
+          rowHeights[dragRowOrCol] = (short)(ev.GetY() - dragStartPosition);
+          UpdateDimensions();
+          AdjustScrollbars();
+          Refresh();
+        }
+        SetCursor(*wxSTANDARD_CURSOR);
+        break;
+      }
+    }
+    dragStatus = wxGRID_DRAG_NONE;
+  }
+  else if (ev.RightDown())
+  {
+    int row, col;
+    if (CellHitTest((int)ev.GetX(), (int)ev.GetY(), &row, &col))
+    {
+      OnCellRightClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
+    }
+    if (LabelHitTest((int)ev.GetX(), (int)ev.GetY(), &row, &col))
+    {
+      OnLabelRightClick(row, col, (int)ev.GetX(), (int)ev.GetY(), ev.ControlDown(), ev.ShiftDown());
+    }
+  }
+}
+
+void wxGenericGrid::OnSelectCellImplementation(wxDC *dc, int row, int col)
+{
+  wCursorColumn = col;
+  wCursorRow = row;
+  
+  OnChangeSelectionLabel();
+
+  SetGridClippingRegion(dc);
+
+  // Remove the highlight from the old cell
+  if (currentRectVisible)
+     HighlightCell(dc);
+
+  // Highlight the new cell and copy its content to the edit control
+  SetCurrentRect(wCursorRow, wCursorColumn);
+  wxGridCell *cell = GetCell(wCursorRow, wCursorColumn);
+  if (cell)
+  {
+	if ( cell->GetTextValue().IsNull() )
+		textItem->SetValue("");
+	else
+    	textItem->SetValue(cell->GetTextValue());
+  }
+
+  SetGridClippingRegion(dc);
+
+  // Why isn't this needed for Windows??
+  // Probably because of the SetValue??
+#ifndef __WINDOWS__
+  HighlightCell(dc);
+#endif
+  dc->DestroyClippingRegion();
+  
+  OnSelectCell(row, col);
+}
+
+wxGridCell *wxGenericGrid::OnCreateCell(void)
+{
+  return new wxGridCell(this);
+}
+
+void wxGenericGrid::OnChangeLabels(void)
+{
+  char buf[100];
+  int i;
+  for (i = 0; i < totalRows; i++)
+  {
+    sprintf(buf, "%d", i+1);
+    SetLabelValue(wxVERTICAL, buf, i);
+  }
+  // A...Z,AA...ZZ,AAA...ZZZ, etc.
+  for (i = 0; i < totalCols; i++)
+  {
+    int j;
+    int noTimes = (i/26 + 1);
+    int ch = (i % 26) + 65;
+    buf[0] = 0;
+    for (j = 0; j < noTimes; j++)
+    {
+      char buf2[20];
+      sprintf(buf2, "%c", (char)ch);
+      strcat(buf, buf2);
+    }
+    SetLabelValue(wxHORIZONTAL, buf, i);
+  }
+}
+
+void wxGenericGrid::OnChangeSelectionLabel(void)
+{
+  if (!GetEditable())
+    return;
+    
+  wxString rowLabel(GetLabelValue(wxVERTICAL, GetCursorRow()));
+  wxString colLabel(GetLabelValue(wxHORIZONTAL, GetCursorColumn()));
+  
+  wxString newLabel = colLabel + rowLabel;
+  if ((newLabel.Length() > 0) && (newLabel.Length() <= 8) && GetTextItem())
+  {
+//    GetTextItem()->SetLabel(newLabel);
+  }
+}
+
+void wxGenericGrid::HighlightCell(wxDC *dc)
+{
+  dc->SetLogicalFunction(wxINVERT);
+  // Top
+  dc->DrawLine(CurrentRect.x + 1, CurrentRect.y + 1, CurrentRect.x + CurrentRect.width - 1, CurrentRect.y + 1);
+  // Right
+  dc->DrawLine(CurrentRect.x + CurrentRect.width - 1, CurrentRect.y + 1,
+      CurrentRect.x + CurrentRect.width - 1, CurrentRect.y +CurrentRect.height - 1);
+  // Bottom
+  dc->DrawLine(CurrentRect.x + CurrentRect.width - 1, CurrentRect.y + CurrentRect.height - 1,
+         CurrentRect.x + 1, CurrentRect.y + CurrentRect.height - 1);
+  // Left
+  dc->DrawLine(CurrentRect.x + 1, CurrentRect.y + CurrentRect.height - 1, CurrentRect.x + 1, CurrentRect.y + 1);
+
+  dc->SetLogicalFunction(wxCOPY);
+}
+
+void wxGenericGrid::DrawCellText(void)
+{
+  if (!currentRectVisible)
+    return;
+  
+  wxGridCell *cell = GetCell(GetCursorRow(), GetCursorColumn());
+  if (!cell)
+    return;
+    
+  static char szEdit[300];
+
+  wxClientDC dc(this);
+  dc.BeginDrawing();
+
+  SetGridClippingRegion(& dc);
+
+  dc.SetBackgroundMode(wxTRANSPARENT);
+  dc.SetBrush(*cell->GetBackgroundBrush());
+
+  strcpy(szEdit, textItem->GetValue());
+  
+  wxRectangle rect;
+  rect = CurrentRect;
+  rect.x += 3;
+  rect.y += 2;
+  rect.width -= 5;
+  rect.height -= 4;
+
+  DrawTextRect(& dc, "                                    ", &rect, wxLEFT);
+  DrawTextRect(& dc, szEdit, &rect, cell->GetAlignment());
+  
+  dc.DestroyClippingRegion();
+  
+  dc.SetBackgroundMode(wxSOLID);
+
+  dc.EndDrawing();
+}
+
+void wxGenericGrid::SetCurrentRect(int Row, int Column, int canvasW, int canvasH)
+{
+  int currentWidth = leftOfSheet + verticalLabelWidth;
+  int i;
+  for (i = scrollPosX; i < Column; i++)
+    currentWidth += colWidths[i];
+
+  int currentHeight = topOfSheet + horizontalLabelHeight;
+  for (i = scrollPosY; i < Row; i++)
+    currentHeight += rowHeights[i];
+
+  CurrentRect.x = currentWidth;
+  CurrentRect.y = currentHeight;
+  CurrentRect.width = colWidths ? (colWidths[Column]) : 0;
+  CurrentRect.height = rowHeights ? (rowHeights[Row]) : 0;
+  
+  if (Row < scrollPosY || Column < scrollPosX)
+    currentRectVisible = FALSE;
+  else if ((canvasW != -1 && canvasH != -1) && (CurrentRect.x > canvasW || CurrentRect.y > canvasH))
+    currentRectVisible = FALSE;
+  else currentRectVisible = TRUE;
+}
+
+static bool wxRectIntersection(wxRectangle *rect1, wxRectangle *rect2, wxRectangle *rect3)
+{
+  int x2_1 = rect1->x + rect1->width;
+  int y2_1 = rect1->y + rect1->height;
+
+  int x2_2 = rect2->x + rect2->width;
+  int y2_2 = rect2->y + rect2->height;
+  
+  int x2_3, y2_3;
+  
+  // Check for intersection
+  if ((rect1->x > x2_2) || (rect2->x > x2_1) ||
+      (rect1->y > y2_2) || (rect2->y > y2_1))
+  {
+    // No intersection
+    rect3->x = rect3->y = rect3->width = rect3->height = 0;
+    return FALSE;
+  }
+
+  if (rect1->x > rect2->x)
+    rect3->x = rect1->x;
+  else
+    rect3->x = rect2->x;
+  if (rect1->y > rect2->y)
+    rect3->y = rect1->y;
+  else
+    rect3->y = rect2->y;
+  
+  if (x2_1 > x2_2)
+    x2_3 = x2_2;
+  else
+    x2_3 = x2_1;
+  if (y2_1 > y2_2)
+    y2_3 = y2_2;
+  else
+    y2_3 = y2_1;
+    
+  rect3->width = (int)(x2_3 - rect3->x);
+  rect3->height = (int)(y2_3 - rect3->y);
+  return TRUE;
+}
+
+void wxGenericGrid::DrawTextRect(wxDC *dc, const wxString& text, wxRectangle *rect, int flag)
+{
+  dc->BeginDrawing();
+  
+  // Ultimately, this functionality should be built into wxWindows,
+  // and optimized for each platform. E.g. on Windows, use DrawText
+  // passing a clipping rectangle, so that the wxWindows clipping region
+  // does not have to be used to implement this.
+  
+  // If we're already clipping, we need to find the intersection
+  // between current clipping area and text clipping area.
+  
+  wxRectangle clipRect;
+  wxRectangle clipRect2;
+  long clipX, clipY, clipW, clipH;
+  dc->GetClippingBox(&clipX, &clipY, &clipW, &clipH);
+  clipRect.x = (int)clipX; clipRect.y = (int)clipY;
+  clipRect.width = (int)clipW; clipRect.height = (int)clipH;
+  
+  bool alreadyClipping = TRUE;
+
+  if (clipRect.x == 0 && clipRect.y == 0 && clipRect.width == 0 && clipRect.height == 0)
+  {
+    alreadyClipping = FALSE;
+    clipRect2.x = rect->x; clipRect2.y = rect->y;
+    clipRect2.width = rect->width; clipRect2.height = rect->height;
+  }
+  else
+  {
+    // Find intersection.
+    if (!wxRectIntersection(rect, &clipRect, &clipRect2))
+      return;
+  }
+
+  if (alreadyClipping)
+    dc->DestroyClippingRegion();
+  
+  dc->SetClippingRegion(clipRect2.x, clipRect2.y, clipRect2.width, clipRect2.height);
+  long textWidth, textHeight;
+  
+  dc->GetTextExtent(text, &textWidth, &textHeight);
+  
+  // Do alignment
+  float x,y;
+  switch (flag)
+  {
+    case wxRIGHT:
+    {
+      x = (rect->x + rect->width - textWidth - 1.0);
+      y = (rect->y + (rect->height - textHeight)/2.0);
+      break;
+    }
+    case wxCENTRE:
+    {
+      x = (rect->x + (rect->width - textWidth)/2.0);
+      y = (rect->y + (rect->height - textHeight)/2.0);
+      break;
+    }
+    case wxLEFT:
+    default:
+    {
+      x = (rect->x + 1.0);
+      y = (rect->y + (rect->height - textHeight)/2.0);
+      break;
+    }
+  }
+  dc->DrawText(text, (long)x, (long)y );
+  
+  dc->DestroyClippingRegion();
+
+  // Restore old clipping
+  if (alreadyClipping)
+    dc->SetClippingRegion(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
+
+  dc->EndDrawing();
+}
+
+void wxGenericGrid::DrawBitmapRect(wxDC *dc, wxBitmap *bitmap, wxRectangle *rect, int flag)
+{
+  dc->BeginDrawing();
+  
+  // Ultimately, this functionality should be built into wxWindows,
+  // and optimized for each platform. E.g. on Windows, use DrawText
+  // passing a clipping rectangle, so that the wxWindows clipping region
+  // does not have to be used to implement this.
+  
+  // If we're already clipping, we need to find the intersection
+  // between current clipping area and text clipping area.
+  
+  wxRectangle clipRect;
+  wxRectangle clipRect2;
+  long clipX, clipY, clipW, clipH;
+  dc->GetClippingBox(&clipX, &clipY, &clipW, &clipH);
+  clipRect.x = (int)clipX; clipRect.y = (int)clipY;
+  clipRect.width = (int)clipW; clipRect.height = (int)clipH;
+  
+  bool alreadyClipping = TRUE;
+
+  if (clipRect.x == 0 && clipRect.y == 0 && clipRect.width == 0 && clipRect.height == 0)
+  {
+    alreadyClipping = FALSE;
+    clipRect2.x = rect->x; clipRect2.y = rect->y;
+    clipRect2.width = rect->width; clipRect2.height = rect->height;
+  }
+  else
+  {
+    // Find intersection.
+    if (!wxRectIntersection(rect, &clipRect, &clipRect2))
+      return;
+  }
+
+  if (alreadyClipping)
+    dc->DestroyClippingRegion();
+  
+  dc->SetClippingRegion(clipRect2.x, clipRect2.y, clipRect2.width, clipRect2.height);
+  float bitmapWidth, bitmapHeight;
+  
+  bitmapWidth = bitmap->GetWidth();
+  bitmapHeight = bitmap->GetHeight();
+  
+  // Do alignment
+  long x,y;
+  switch (flag)
+  {
+    case wxRIGHT:
+    {
+      x = (long)(rect->x + rect->width - bitmapWidth - 1);
+      y = (long)(rect->y + (rect->height - bitmapHeight)/2.0);
+      break;
+    }
+    case wxCENTRE:
+    {
+      x = (long)(rect->x + (rect->width - bitmapWidth)/2.0);
+      y = (long)(rect->y + (rect->height - bitmapHeight)/2.0);
+      break;
+    }
+    case wxLEFT:
+    default:
+    {
+      x = (long)(rect->x + 1);
+      y = (long)(rect->y + (rect->height - bitmapHeight)/2.0);
+      break;
+    }
+  }
+  wxMemoryDC dcTemp;
+  dcTemp.SelectObject(*bitmap);
+  
+  dc->Blit( (long)x, (long)y, (long)bitmapWidth, (long)bitmapHeight, &dcTemp, 0, 0);
+  dcTemp.SelectObject(wxNullBitmap);
+  
+  dc->DestroyClippingRegion();
+
+  // Restore old clipping
+  if (alreadyClipping)
+    dc->SetClippingRegion(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
+
+  dc->EndDrawing();
+}
+
+void wxGenericGrid::OnActivate(bool active)
+{
+  if (active)
+  {
+    // Edit control should always have the focus
+    if (GetTextItem() && GetEditable())
+    {
+      GetTextItem()->SetFocus();
+      wxGridCell *cell = GetCell(GetCursorRow(), GetCursorColumn());
+      if (cell)
+        GetTextItem()->SetValue(cell->GetTextValue());
+    }
+  }
+}
+
+void wxGenericGrid::SetCellValue(const wxString& val, int row, int col)
+{
+  wxGridCell *cell = GetCell(row, col);
+  if (cell)
+  {
+    cell->SetTextValue(val);
+
+    RefreshCell(row, col, TRUE);
+  }
+}
+
+void wxGenericGrid::RefreshCell(int row, int col, bool setText)
+{
+    // Don't refresh within a pair of batch brackets
+    if (GetBatchCount() > 0)
+        return;
+      
+    int cw, ch;
+    GetClientSize(&cw, &ch);
+
+    SetCurrentRect(row, col, cw, ch);
+    if (currentRectVisible)
+    {
+      wxGridCell *cell = GetCell(row, col);
+
+      bool currentPos = FALSE;
+      if (row == wCursorRow && col == wCursorColumn && GetTextItem() && GetTextItem()->IsShown() && setText)
+      {
+        GetTextItem()->SetValue(cell->GetTextValue());
+        currentPos = TRUE;
+      }
+      // Gets refreshed anyway in MSW
+#ifdef __WINDOWS__
+      if (!currentPos)
+#endif
+      {
+        wxClientDC dc(this);
+        dc.BeginDrawing();
+        DrawCellBackground(& dc, &CurrentRect, row, col);
+        DrawCellValue(& dc, &CurrentRect, row, col);
+        dc.EndDrawing();
+      }
+    }
+}
+
+wxString& wxGenericGrid::GetCellValue(int row, int col)
+{
+  static wxString emptyString("");
+ 
+  wxGridCell *cell = GetCell(row, col);
+  if (cell)
+    return cell->GetTextValue();
+  else
+    return emptyString;
+}
+
+void wxGenericGrid::SetColumnWidth(int col, int width)
+{
+  if (col <= totalCols)
+    colWidths[col] = width;
+}
+
+int wxGenericGrid::GetColumnWidth(int col)
+{
+  if (col <= totalCols)
+    return colWidths[col];
+  else
+    return 0;
+}
+
+void wxGenericGrid::SetRowHeight(int row, int height)
+{
+  if (row <= totalRows)
+    rowHeights[row] = height;
+}
+
+int wxGenericGrid::GetRowHeight(int row)
+{
+  if (row <= totalRows)
+    return rowHeights[row];
+  else
+    return 0;
+}
+
+void wxGenericGrid::SetLabelSize(int orientation, int sz)
+{
+  if (orientation == wxHORIZONTAL)
+    horizontalLabelHeight = sz;
+  else
+    verticalLabelWidth = sz;
+  UpdateDimensions();
+  SetCurrentRect(GetCursorRow(), GetCursorColumn());
+}
+
+int wxGenericGrid::GetLabelSize(int orientation)
+{
+  if (orientation == wxHORIZONTAL)
+    return horizontalLabelHeight;
+  else
+    return verticalLabelWidth;
+}
+
+wxGridCell *wxGenericGrid::GetLabelCell(int orientation, int pos)
+{
+  if (orientation == wxHORIZONTAL)
+  {
+    if (colLabelCells && pos < totalCols)
+      return colLabelCells[pos];
+    else
+      return NULL;
+  }
+  else
+  {
+    if (rowLabelCells && pos < totalRows)
+      return rowLabelCells[pos];
+    else
+      return NULL;
+  }
+}
+
+void wxGenericGrid::SetLabelValue(int orientation, const wxString& val, int pos)
+{
+  wxGridCell *cell = GetLabelCell(orientation, pos);
+  if (cell)
+    cell->SetTextValue(val);
+}
+
+wxString& wxGenericGrid::GetLabelValue(int orientation, int pos)
+{
+ static wxString emptyString = "";
+  wxGridCell *cell = GetLabelCell(orientation, pos);
+  if (cell)
+    return cell->GetTextValue();
+  else
+    return emptyString;
+}
+
+void wxGenericGrid::SetLabelAlignment(int orientation, int align)
+{
+  if (orientation == wxHORIZONTAL)
+    horizontalLabelAlignment = align;
+  else
+    verticalLabelAlignment = align;
+  UpdateDimensions();
+  SetCurrentRect(GetCursorRow(), GetCursorColumn());
+}
+
+int wxGenericGrid::GetLabelAlignment(int orientation)
+{
+  if (orientation == wxHORIZONTAL)
+    return horizontalLabelAlignment;
+  else
+    return verticalLabelAlignment;
+}
+
+void wxGenericGrid::SetLabelTextColour(const wxColour& colour)
+{
+  labelTextColour = colour;
+
+}
+
+void wxGenericGrid::SetLabelBackgroundColour(const wxColour& colour)
+{
+  labelBackgroundColour = colour;
+  labelBackgroundBrush = wxTheBrushList->FindOrCreateBrush(labelBackgroundColour, wxSOLID);
+}
+
+void wxGenericGrid::SetEditable(bool edit)
+{
+  editable = edit;
+  if (edit)
+  {
+    int controlW, controlH;
+    textItem->GetSize(&controlW, &controlH);
+    editControlPosition.height = controlH;
+  
+    topOfSheet = editControlPosition.x + controlH + 2;
+    if (textItem)
+    {
+      textItem->Show(TRUE);
+      // Bug fix
+#if defined(__WINDOWS__) && (wxMINOR_VERSION == 6 && wxRELEASE_NUMBER < 6)
+      ::ShowWindow(textItem->GetLabelHWND(), TRUE);
+#endif
+      textItem->SetFocus();
+    }
+  }
+  else
+  {
+    topOfSheet = 0;
+    if (textItem)
+    {
+      textItem->Show(FALSE);
+      // Bug fix
+#if defined(__WINDOWS__) && (wxMINOR_VERSION == 6 && wxRELEASE_NUMBER < 6)
+      ::ShowWindow(textItem->GetLabelHWND(), FALSE);
+#endif
+    }
+  }
+  UpdateDimensions();
+  SetCurrentRect(GetCursorRow(), GetCursorColumn());
+
+  int cw, ch;
+  GetClientSize(&cw, &ch);
+  wxSizeEvent evt;
+  OnSize(evt);
+/*
+  int cw, ch;
+  int scrollWidth = 16;
+  GetClientSize(&cw, &ch);
+  
+  if (vScrollBar)
+    vScrollBar->SetSize(cw - scrollWidth, topOfSheet,
+       scrollWidth, ch - topOfSheet - scrollWidth);
+*/
+}
+
+void wxGenericGrid::SetCellAlignment(int flag, int row, int col)
+{
+  wxGridCell *cell = GetCell(row, col);
+  if (cell)
+    cell->SetAlignment(flag);
+}
+
+int wxGenericGrid::GetCellAlignment(int row, int col)
+{
+  wxGridCell *cell = GetCell(row, col);
+  if (cell)
+    return cell->GetAlignment();
+  else
+    return cellAlignment;
+}
+
+void wxGenericGrid::SetCellAlignment(int flag)
+{
+  cellAlignment = flag;
+  int i,j;
+  for (i = 0; i < GetRows(); i++)
+    for (j = 0; j < GetCols(); j++)
+      if (GetCell(i, j))
+        GetCell(i, j)->SetAlignment(flag);
+}
+
+int wxGenericGrid::GetCellAlignment(void)
+{
+  return cellAlignment;
+}
+
+void wxGenericGrid::SetCellBackgroundColour(const wxColour& col)
+{
+  cellBackgroundColour = col;
+  int i,j;
+  for (i = 0; i < GetRows(); i++)
+    for (j = 0; j < GetCols(); j++)
+      if (GetCell(i, j))
+        GetCell(i, j)->SetBackgroundColour(col);
+}
+
+void wxGenericGrid::SetCellBackgroundColour(const wxColour& val, int row, int col)
+{
+  wxGridCell *cell = GetCell(row, col);
+  if (cell)
+  {
+    cell->SetBackgroundColour(val);
+    RefreshCell(row, col);
+  }
+}
+
+wxColour& wxGenericGrid::GetCellBackgroundColour(int row, int col)
+{
+  wxGridCell *cell = GetCell(row, col);
+  if (cell)
+    return cell->GetBackgroundColour();
+  else
+    return cellBackgroundColour;
+}
+
+void wxGenericGrid::SetCellTextColour(const wxColour& val, int row, int col)
+{
+  wxGridCell *cell = GetCell(row, col);
+  if (cell)
+  {
+    cell->SetTextColour(val);
+    RefreshCell(row, col);
+  }
+}
+
+void wxGenericGrid::SetCellTextFont(wxFont *fnt, int row, int col)
+{
+  wxGridCell *cell = GetCell(row, col);
+  if (cell)
+  {
+    cell->SetFont(fnt);
+    RefreshCell(row, col);
+  }
+}
+
+wxFont *wxGenericGrid::GetCellTextFont(int row, int col)
+{
+  wxGridCell *cell = GetCell(row, col);
+  if (cell)
+    return cell->GetFont();
+  else
+    return cellTextFont;
+}
+
+wxColour& wxGenericGrid::GetCellTextColour(int row, int col)
+{
+  wxGridCell *cell = GetCell(row, col);
+  if (cell)
+    return cell->GetTextColour();
+  else
+    return cellTextColour;
+}
+
+void wxGenericGrid::SetCellTextColour(const wxColour& val)
+{
+  cellTextColour = val;
+  int i,j;
+  for (i = 0; i < GetRows(); i++)
+    for (j = 0; j < GetCols(); j++)
+      if (GetCell(i, j))
+        GetCell(i, j)->SetTextColour(val);
+}
+
+void wxGenericGrid::SetCellTextFont(wxFont *fnt)
+{
+  cellTextFont = fnt;
+  int i,j;
+  for (i = 0; i < GetRows(); i++)
+    for (j = 0; j < GetCols(); j++)
+      if (GetCell(i, j))
+        GetCell(i, j)->SetFont(fnt);
+}
+
+void wxGenericGrid::SetCellBitmap(wxBitmap *bitmap, int row, int col)
+{
+  wxGridCell *cell = GetCell(row, col);
+  if (cell)
+  {
+    cell->SetCellBitmap(bitmap);
+    RefreshCell(row, col);
+  }
+}
+
+wxBitmap *wxGenericGrid::GetCellBitmap(int row, int col)
+{
+  wxGridCell *cell = GetCell(row, col);
+  if (cell)
+  {
+    return cell->GetCellBitmap();
+  }
+  else
+    return NULL;
+}
+
+bool wxGenericGrid::InsertCols(int pos, int n, bool updateLabels)
+{
+  if (pos > totalCols)
+    return FALSE;
+    
+  if (!gridCells)
+    return CreateGrid(1, n);
+  else
+  {
+    int i, j;
+    // Cells
+    for (i = 0; i < totalRows; i++)
+    {
+      wxGridCell **cols = gridCells[i];
+      wxGridCell **newCols = new wxGridCell *[totalCols + n];
+      for (j = 0; j < pos; j++)
+        newCols[j] = cols[j];
+      for (j = pos; j < pos + n; j++)
+        newCols[j] = new wxGridCell(this);
+      for (j = pos + n; j < totalCols + n; j++)
+        newCols[j] = cols[j - n];
+        
+      delete[] cols;
+      gridCells[i] = newCols;
+    }
+
+    // Column widths
+    short *newColWidths = new short[totalCols + n];
+    for (j = 0; j < pos; j++)
+      newColWidths[j] = colWidths[j];
+    for (j = pos; j < pos + n; j++)
+      newColWidths[j] = wxGRID_DEFAULT_CELL_WIDTH;
+    for (j = pos + n; j < totalCols + n; j++)
+      newColWidths[j] = colWidths[j - n];
+    delete[] colWidths;
+    colWidths = newColWidths;
+
+    // Column labels
+    wxGridCell **newLabels = new wxGridCell *[totalCols + n];
+    for (j = 0; j < pos; j++)
+      newLabels[j] = colLabelCells[j];
+    for (j = pos; j < pos + n; j++)
+      newLabels[j] = new wxGridCell(this);
+    for (j = pos + n; j < totalCols + n; j++)
+      newLabels[j] = colLabelCells[j - n];
+        
+    delete[] colLabelCells;
+    colLabelCells = newLabels;
+      
+    totalCols += n;
+
+    if (updateLabels)
+      OnChangeLabels();
+    UpdateDimensions();
+    AdjustScrollbars();
+    return TRUE;
+  }
+}
+
+bool wxGenericGrid::InsertRows(int pos, int n, bool updateLabels)
+{
+  if (pos > totalRows)
+    return FALSE;
+    
+  if (!gridCells)
+    return CreateGrid(n, 1);
+  else
+  {
+    int i, j;
+    
+    wxGridCell ***rows = new wxGridCell **[totalRows + n];
+
+    // Cells
+    for (i = 0; i < pos; i++)
+      rows[i] = gridCells[i];
+
+    for (i = pos; i < pos + n; i++)
+    {
+      rows[i] = new wxGridCell *[totalCols];
+      for (j = 0; j < totalCols; j++)
+        rows[i][j] = new wxGridCell(this);
+    }
+    
+    for (i = pos + n; i < totalRows + n; i++)
+      rows[i] = gridCells[i - n];
+      
+    delete[] gridCells;
+    gridCells = rows;
+
+    // Row heights
+    short *newRowHeights = new short[totalRows + n];
+    for (i = 0; i < pos; i++)
+      newRowHeights[i] = rowHeights[i];
+    for (i = pos; i < pos + n; i++)
+      newRowHeights[i] = wxGRID_DEFAULT_CELL_HEIGHT;
+    for (i = pos + n; i < totalRows + n; i++)
+      newRowHeights[i] = rowHeights[i - n];
+    delete[] rowHeights;
+    rowHeights = newRowHeights;
+
+    // Column labels
+    wxGridCell **newLabels = new wxGridCell *[totalRows + n];
+    for (i = 0; i < pos; i++)
+      newLabels[i] = rowLabelCells[i];
+    for (i = pos; i < pos + n; i++)
+      newLabels[i] = new wxGridCell(this);
+    for (i = pos + n; i < totalRows + n; i++)
+      newLabels[i] = rowLabelCells[i - n];
+        
+    delete[] rowLabelCells;
+    rowLabelCells = newLabels;
+      
+    totalRows += n;
+
+    if (updateLabels)
+      OnChangeLabels();
+    UpdateDimensions();
+    AdjustScrollbars();
+    return TRUE;
+  }
+}
+
+bool wxGenericGrid::AppendCols(int n, bool updateLabels)
+{
+  return InsertCols(GetCols(), n, updateLabels);
+}
+
+bool wxGenericGrid::AppendRows(int n, bool updateLabels)
+{
+  return InsertRows(GetRows(), n, updateLabels);
+}
+
+bool wxGenericGrid::DeleteRows(int pos, int n, bool updateLabels)
+{
+  if (pos > totalRows)
+    return FALSE;
+  if (!gridCells)
+    return FALSE;
+
+  int i;
+    
+  wxGridCell ***rows = new wxGridCell **[totalRows - n];
+
+  // Cells
+  for (i = 0; i < pos; i++)
+    rows[i] = gridCells[i];
+
+  for (i = pos + n; i < totalRows; i++)
+    rows[i-n] = gridCells[i];
+      
+  delete[] gridCells;
+  gridCells = rows;
+
+  // Row heights
+  short *newRowHeights = new short[totalRows - n];
+  for (i = 0; i < pos; i++)
+    newRowHeights[i] = rowHeights[i];
+  for (i = pos + n; i < totalRows; i++)
+    newRowHeights[i-n] = rowHeights[i];
+  delete[] rowHeights;
+  rowHeights = newRowHeights;
+
+  // Column labels
+  wxGridCell **newLabels = new wxGridCell *[totalRows - n];
+  for (i = 0; i < pos; i++)
+    newLabels[i] = rowLabelCells[i];
+  for (i = pos + n; i < totalRows; i++)
+    newLabels[i-n] = rowLabelCells[i];
+        
+  delete[] rowLabelCells;
+  rowLabelCells = newLabels;
+      
+  totalRows -= n;
+
+  if (updateLabels)
+    OnChangeLabels();
+  UpdateDimensions();
+  AdjustScrollbars();
+  return TRUE;
+}
+
+bool wxGenericGrid::DeleteCols(int pos, int n, bool updateLabels)
+{
+  if (pos + n > totalCols)
+    return FALSE;
+  if (!gridCells)
+    return FALSE;
+
+  int i, j;
+
+  // Cells
+  for (i = 0; i < totalRows; i++)
+  {
+      wxGridCell **cols = gridCells[i];
+      wxGridCell **newCols = new wxGridCell *[totalCols - n];
+      for (j = 0; j < pos; j++)
+        newCols[j] = cols[j];
+      for (j = pos; j < pos + n; j++)
+        delete cols[j];
+      for (j = pos + n; j < totalCols; j++)
+        newCols[j-n] = cols[j];
+        
+      delete[] cols;
+      gridCells[i] = newCols;
+  }
+
+  // Column widths
+  short *newColWidths = new short[totalCols - n];
+  for (j = 0; j < pos; j++)
+    newColWidths[j] = colWidths[j];
+  for (j = pos + n; j < totalCols; j++)
+    newColWidths[j-n] = colWidths[j];
+  delete[] colWidths;
+  colWidths = newColWidths;
+
+  // Column labels
+  wxGridCell **newLabels = new wxGridCell *[totalCols - n];
+  for (j = 0; j < pos; j++)
+    newLabels[j] = colLabelCells[j];
+  for (j = pos + n; j < totalCols; j++)
+    newLabels[j-n] = colLabelCells[j];
+        
+  delete[] colLabelCells;
+  colLabelCells = newLabels;
+      
+  totalCols -= n;
+
+  if (updateLabels)
+    OnChangeLabels();
+  UpdateDimensions();
+  AdjustScrollbars();
+  return TRUE;
+}
+
+void wxGenericGrid::SetGridCursor(int row, int col)
+{
+  if (row >= totalRows || col >= totalCols)
+    return;
+    
+  if (row == GetCursorRow() && col == GetCursorColumn())
+    return;
+    
+  wxClientDC dc(this);
+  dc.BeginDrawing();
+  
+  SetGridClippingRegion(& dc);
+
+  if (currentRectVisible)
+    HighlightCell(& dc);
+  
+  wCursorRow = row;
+  wCursorColumn = col;
+  SetCurrentRect(row, col);
+  if (currentRectVisible)
+    HighlightCell(& dc);
+
+  dc.DestroyClippingRegion();
+  dc.EndDrawing();
+}
+
+/*
+ * Grid cell
+ */
+ 
+wxGridCell::wxGridCell(wxGenericGrid *window)
+{
+  cellBitmap = NULL;
+  font = NULL;
+  backgroundBrush = NULL;
+  if (window)
+    textColour = window->GetCellTextColour();
+  else
+    textColour.Set(0,0,0);
+  if (window)
+    backgroundColour = window->GetCellBackgroundColour();
+  else
+    backgroundColour.Set(255,255,255);
+    
+  if (window)
+    font = window->GetCellTextFont();
+  else
+    font = wxTheFontList->FindOrCreateFont(12, wxSWISS, wxNORMAL, wxNORMAL);
+    
+  SetBackgroundColour(backgroundColour);
+  
+  if (window)
+    alignment = window->GetCellAlignment();
+  else
+    alignment = wxLEFT;
+}
+
+wxGridCell::~wxGridCell(void)
+{
+}
+
+void wxGridCell::SetBackgroundColour(const wxColour& colour)
+{
+  backgroundColour = colour;
+  backgroundBrush = wxTheBrushList->FindOrCreateBrush(backgroundColour, wxSOLID);
+}
+
+void wxGenericGrid::OnText(wxCommandEvent& WXUNUSED(ev) )
+{
+  wxGenericGrid *grid = this;
+  wxGridCell *cell = grid->GetCell(grid->GetCursorRow(), grid->GetCursorColumn());
+  if (cell && grid->CurrentCellVisible())
+  {
+    cell->SetTextValue(grid->GetTextItem()->GetValue());
+    wxClientDC dc(grid);
+
+    dc.BeginDrawing();
+    grid->SetGridClippingRegion(& dc);
+    grid->DrawCellBackground(& dc, &grid->GetCurrentRect(), grid->GetCursorRow(), grid->GetCursorColumn());
+    grid->DrawCellValue(& dc, &grid->GetCurrentRect(), grid->GetCursorRow(), grid->GetCursorColumn());
+    grid->HighlightCell(& dc);
+    dc.DestroyClippingRegion();
+    dc.EndDrawing();
+      
+    grid->OnCellChange(grid->GetCursorRow(), grid->GetCursorColumn());
+      
+//    grid->DrawCellText();
+  }
+}
+
+void wxGenericGrid::OnGridScroll(wxScrollEvent& ev)
+{
+  static bool inScroll = FALSE;
+
+  if ( inScroll )
+	return;
+
+  inScroll = TRUE;
+  wxGenericGrid *win = this;
+
+  bool change = FALSE;
+  
+  if (ev.GetEventObject() == win->GetHorizScrollBar())
+  {
+    change = (ev.GetPosition() != scrollPosX);
+    win->SetScrollPosX(ev.GetPosition());
+  }
+  else
+  {
+    change = (ev.GetPosition() != scrollPosY);
+    win->SetScrollPosY(ev.GetPosition());
+  }
+
+  win->UpdateDimensions();
+  win->SetCurrentRect(win->GetCursorRow(), win->GetCursorColumn());
+
+  // Because rows and columns can be arbitrary sizes,
+  // the scrollbars will need to be adjusted to reflect the
+  // current view.
+  AdjustScrollbars();
+
+  if (change) win->Refresh(FALSE);
+  inScroll = FALSE;
+  
+}
diff --git a/src/generic/helpxlp.cpp b/src/generic/helpxlp.cpp
new file mode 100644
index 0000000000..0631f6d80a
--- /dev/null
+++ b/src/generic/helpxlp.cpp
@@ -0,0 +1,257 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        helpxlp.cpp
+// Purpose:     Help system: wxHelp implementation
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "helpxlp.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/defs.h"
+#endif
+
+#include "wx/generic/helpxlp.h"
+
+#if USE_HELP
+#include <time.h>
+
+#ifdef __X__
+#include <netdb.h>
+
+#ifdef SUN_CC
+#include <sysent.h>
+#endif // SUN_CC
+#ifdef ____HPUX__
+#include <sys/unistd.h>
+#endif // ____HPUX__
+#endif // __X__
+
+#include <string.h>
+
+// Timeout in seconds
+#define WX_HELP_TIMEOUT 15 /* was 30 */
+
+// MAX path length
+#define _MAXPATHLEN 500
+
+// MAX length of Help descriptor
+#define _MAX_HELP_LEN 500
+
+#include "wx/generic/helpxlp.h"
+
+#if !USE_SHARED_LIBRARY
+
+#ifdef __WINDOWS__
+IMPLEMENT_CLASS(wxXLPHelpClient, wxDDEClient)
+IMPLEMENT_CLASS(wxXLPHelpConnection, wxDDEConnection)
+#else
+IMPLEMENT_CLASS(wxXLPHelpClient, wxTCPClient)
+IMPLEMENT_CLASS(wxXLPHelpConnection, wxTCPConnection)
+#endif
+
+IMPLEMENT_CLASS(wxXLPHelpController, wxHelpControllerBase)
+#endif
+
+wxXLPHelpController::wxXLPHelpController(void):
+  helpClient(this)
+{
+  helpFile = ""; helpServer = -1; helpHost = "";
+  helpRunning = FALSE; helpConnection = NULL;
+}
+
+wxXLPHelpController::~wxXLPHelpController(void)
+{
+}
+
+bool wxXLPHelpController::Initialize(const wxString& filename, int server)
+{
+#ifdef __X__
+  char host_buf[255];
+  if (wxGetHostName(host_buf, sizeof(host_buf)))
+    helpHost = host_buf;
+  else helpHost = "";
+#endif
+
+  helpFile = filename;
+  helpServer = server;
+  wxIPCInitialize();
+  return TRUE;
+}
+
+bool wxXLPHelpController::LoadFile(const wxString& file)
+{
+  helpFile = file;
+
+  if (!helpRunning)
+  {
+      if (!Run())
+        return FALSE;
+  }
+  char buf[_MAX_HELP_LEN];
+  sprintf(buf, "f %s", (const char*) file);
+  if (helpConnection)
+    return helpConnection->Execute(buf);
+  else return FALSE;
+}
+
+bool wxXLPHelpController::DisplayContents(void)
+{
+	if (!helpRunning)
+	{
+      if (!Run())
+        return FALSE;
+    }
+    if (helpConnection)
+      	return helpConnection->Execute("s -1");
+    else
+	    return FALSE;
+}
+
+bool wxXLPHelpController::DisplaySection(int section)
+{
+    if (!helpRunning)
+	{
+      if (!Run())
+        return FALSE;
+    }
+    char buf[_MAX_HELP_LEN];
+    sprintf(buf, "s %d", section);
+    if (helpConnection)
+      return helpConnection->Execute(buf);
+    else return FALSE;
+}
+
+bool wxXLPHelpController::DisplayBlock(long block)
+{
+    if (!helpRunning)
+	{
+      if (!Run())
+        return FALSE;
+    }
+    char buf[_MAX_HELP_LEN];
+    sprintf(buf, "b %ld", block);
+    if (helpConnection)
+      return helpConnection->Execute(buf);
+    else return FALSE;
+}
+
+bool wxXLPHelpController::KeywordSearch(const wxString& k)
+{
+    if (!helpRunning)
+	{
+      if (!Run())
+        return FALSE;
+    }
+    char buf[500];
+    sprintf(buf, "k %s", (const char*) k);
+    if (helpConnection)
+      return helpConnection->Execute(buf);
+    else return FALSE;
+}
+
+bool wxXLPHelpController::Quit(void)
+{
+  if (helpConnection)
+    return helpConnection->Disconnect(); // Calls OnQuit via OnDisconnect
+  else return TRUE;
+}
+
+void wxXLPHelpController::OnQuit(void)
+{
+}
+
+bool wxXLPHelpController::Run(void)
+{
+#ifdef __X__
+  if (!helpFile || !helpHost || helpRunning)
+    return FALSE;
+#endif
+#ifdef __WINDOWS__
+  if (!helpFile || helpRunning)
+    return FALSE;
+#endif
+
+  time_t current_time;
+#ifdef __X__
+  // Invent a server name that's likely to be unique but different from
+  // last time
+  (void)time(&current_time);
+  if (helpServer == -1)
+    helpServer = (int)(4000 + (current_time % 4000));
+#else
+  // Only one instance of wxHelp at a time
+  helpServer = 4000;
+#endif
+
+  char server[32];
+  sprintf(server, "%d", helpServer);
+#ifdef __WINDOWS__
+  // Only one instance of wxHelp under Windows.
+  // See if there's already an instance of wxHelp
+  if ((helpConnection = (wxXLPHelpConnection *)helpClient.MakeConnection(helpHost, server, "WXHELP")))
+  {
+    helpRunning = TRUE;
+    return TRUE;
+  }
+#endif
+
+  // Start help process in server modus
+//  char *argv[] = {"wxhelp", "-server", server, NULL}; // HP compiler complains
+  char *argv[4];
+  argv[0] = "wxhelp";
+  argv[1] = "-server";
+  argv[2] = server;
+  argv[3] = NULL;
+
+  if (wxExecute((char **)argv) == FALSE)
+    return FALSE; // Maybe we should print a message?
+
+  time_t start_time;
+  (void)time(&start_time);
+  // Give it some time to respond
+  do {
+    wxSleep(1);
+    helpConnection = (wxXLPHelpConnection *)helpClient.MakeConnection(helpHost, server, "WXHELP");
+    (void)time(&current_time);
+  } while (!helpConnection && ((current_time - start_time) < WX_HELP_TIMEOUT));
+
+  if (helpConnection == NULL) {
+    char buf[100];
+    sprintf(buf, (const char *) _("Connection to wxHelp timed out in %d seconds"), WX_HELP_TIMEOUT);
+    (void)wxMessageBox(buf, _("Error"));
+    return FALSE;
+  }
+  helpRunning = TRUE;
+  return TRUE;
+}
+
+wxXLPHelpConnection::wxXLPHelpConnection(wxXLPHelpController *instance)
+{
+  helpInstance = instance;
+}
+
+bool wxXLPHelpConnection::OnDisconnect(void)
+{
+  helpInstance->OnQuit();
+  helpInstance->helpRunning = FALSE;
+  helpInstance->helpConnection = NULL;
+  helpInstance->helpServer = -1;
+  delete this;
+  return TRUE;
+}
+
+#endif // USE_HELP
diff --git a/src/generic/imaglist.cpp b/src/generic/imaglist.cpp
new file mode 100644
index 0000000000..368a72735a
--- /dev/null
+++ b/src/generic/imaglist.cpp
@@ -0,0 +1,112 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        imaglist.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "imaglist.h"
+#endif
+ 
+#include "wx/imaglist.h"
+
+//-----------------------------------------------------------------------------
+//  wxImageList
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxImageList, wxObject)
+
+wxImageList::wxImageList(void)
+{
+  Create();
+};
+
+wxImageList::~wxImageList(void)
+{
+};
+
+int wxImageList::GetImageCount(void) const
+{
+  return m_images.Number();
+};
+
+bool wxImageList::Create(void)
+{
+  m_images.DeleteContents( TRUE );
+  return TRUE;
+};
+
+int wxImageList::Add( const wxBitmap &bitmap )
+{
+  m_images.Append( new wxBitmap(bitmap) );
+  return m_images.Number();
+};
+
+bool wxImageList::Replace( const int index, const wxBitmap &bitmap )
+{
+  wxNode *node = m_images.Nth( index );
+  if (!node) return FALSE;
+  
+  if (index == m_images.Number()-1)
+  {
+    m_images.DeleteNode( node );
+    m_images.Append( new wxBitmap(bitmap) );
+  }
+  else
+  {
+    wxNode *next = node->Next();
+    m_images.DeleteNode( node );
+    m_images.Insert( next, new wxBitmap(bitmap) );
+  };
+  
+  return TRUE;
+};
+
+bool wxImageList::Remove( const int index )
+{
+  wxNode *node = m_images.Nth( index );
+  if (node) m_images.DeleteNode( node );
+  return (node != NULL);
+};
+
+bool wxImageList::RemoveAll(void)
+{
+  m_images.Clear();
+  return TRUE;
+};
+
+bool wxImageList::GetSize( const int index, int &width, int &height ) const
+{
+  wxNode *node = m_images.Nth( index );
+  if (node)
+  {
+    wxBitmap *bm = (wxBitmap*)node->Data();
+    width = bm->GetWidth();
+    height = bm->GetHeight();
+    return TRUE;
+  }
+  else
+  {
+    width = 0;
+    height = 0;
+    return FALSE;
+  };
+};
+
+bool wxImageList::Draw( const int index, wxDC &dc, 
+                        const int x, const int y,
+                        const int WXUNUSED(flags), const bool WXUNUSED(solidBackground) )
+{
+  wxNode *node = m_images.Nth( index );
+  if (!node) return FALSE;
+  wxBitmap *bm = (wxBitmap*)node->Data();
+  wxIcon *icon = (wxIcon*)bm;
+  dc.DrawIcon( *icon, x, y );
+  return TRUE;
+};
+
+
diff --git a/src/generic/listctrl.cpp b/src/generic/listctrl.cpp
new file mode 100644
index 0000000000..a1090aff83
--- /dev/null
+++ b/src/generic/listctrl.cpp
@@ -0,0 +1,2454 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        listctrl.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "listctrl.h"
+#endif
+
+#include "wx/listctrl.h"
+
+//-----------------------------------------------------------------------------
+//  wxListItemData
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxListItemData,wxObject);
+
+wxListItemData::wxListItemData(void)
+{
+  m_image = -1;
+  m_data = 0;
+  m_xpos = 0;
+  m_ypos = 0;
+  m_width = 0;
+  m_height = 0;
+  m_colour = wxBLACK;
+};
+
+wxListItemData::wxListItemData( const wxListItem &info )
+{
+  m_image = -1;
+  m_data = 0;
+  m_colour = info.m_colour;
+  SetItem( info );
+};
+
+void wxListItemData::SetItem( const wxListItem &info )
+{
+  if (info.m_mask & wxLIST_MASK_TEXT) m_text = info.m_text;
+  if (info.m_mask & wxLIST_MASK_IMAGE) m_image = info.m_image;
+  if (info.m_mask & wxLIST_MASK_DATA) m_data = info.m_data;
+  m_colour = info.m_colour;
+  m_xpos = 0;
+  m_ypos = 0;
+  m_width = info.m_width;
+  m_height = 0;
+};
+
+void wxListItemData::SetText( const wxString &s )
+{
+  m_text = s;
+};
+
+void wxListItemData::SetImage( const int image )
+{
+  m_image = image;
+};
+
+void wxListItemData::SetData( const long data )
+{
+  m_data = data;
+};
+
+void wxListItemData::SetPosition( const int x, const int y )
+{
+  m_xpos = x;
+  m_ypos = y;
+};
+
+void wxListItemData::SetSize( int const width, const int height )
+{
+  m_width = width;
+  m_height = height;
+};
+
+void wxListItemData::SetColour( wxColour *col )
+{
+  m_colour = col;
+};
+
+bool wxListItemData::HasImage(void) const
+{
+  return (m_image >= 0);
+};
+
+bool wxListItemData::HasText(void) const
+{
+  return (!m_text.IsNull());
+};
+
+bool wxListItemData::IsHit( const int x, const int y ) const
+{
+  return ((x >= m_xpos) && (x <= m_xpos+m_width) && (y >= m_ypos) && (y <= m_ypos+m_height));
+};
+
+void wxListItemData::GetText( wxString &s )
+{
+  s = m_text;
+};
+
+int wxListItemData::GetX( void ) const
+{
+  return m_xpos;
+};
+
+int wxListItemData::GetY( void ) const
+{
+  return m_ypos;
+};
+
+int wxListItemData::GetWidth(void) const
+{
+  return m_width;
+};
+
+int wxListItemData::GetHeight(void) const
+{
+  return m_height;
+};
+
+int wxListItemData::GetImage(void) const
+{
+  return m_image;
+};
+
+void wxListItemData::GetItem( wxListItem &info )
+{
+  info.m_text = m_text;
+  info.m_image = m_image;
+  info.m_data = m_data;
+};
+
+wxColour *wxListItemData::GetColour(void)
+{
+  return m_colour;
+};
+
+//-----------------------------------------------------------------------------
+//  wxListHeaderData
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxListHeaderData,wxObject);
+
+wxListHeaderData::wxListHeaderData(void)
+{
+  m_mask = 0;
+  m_image = 0;
+  m_format = 0;
+  m_width = 0;
+  m_xpos = 0;
+  m_ypos = 0;
+  m_height = 0;
+};
+
+wxListHeaderData::wxListHeaderData( const wxListItem &item )
+{
+  SetItem( item );
+  m_xpos = 0;
+  m_ypos = 0;
+  m_height = 0;
+};
+
+void wxListHeaderData::SetItem( const wxListItem &item )
+{
+  m_mask = item.m_mask;
+  m_text = item.m_text;
+  m_image = item.m_image;
+  m_format = item.m_format;
+  m_width = item.m_width;
+  if (m_width < 0) m_width = 80;
+  if (m_width < 6) m_width = 6;
+};
+
+void wxListHeaderData::SetPosition( const int x, const int y )
+{
+  m_xpos = x;
+  m_ypos = y;
+};
+
+void wxListHeaderData::SetHeight( const int h )
+{
+  m_height = h;
+};
+
+void wxListHeaderData::SetWidth( const int w )
+{
+  m_width = w;
+  if (m_width < 0) m_width = 80;
+  if (m_width < 6) m_width = 6;
+};
+
+void wxListHeaderData::SetFormat( const int format )
+{
+  m_format = format;
+};
+
+bool wxListHeaderData::HasImage(void) const
+{
+  return (m_image != 0);
+};
+
+bool wxListHeaderData::HasText(void) const
+{
+  return (m_text.Length() > 0);
+};
+
+bool wxListHeaderData::IsHit( int x, int y ) const
+{
+  return ((x >= m_xpos) && (x <= m_xpos+m_width) && (y >= m_ypos) && (y <= m_ypos+m_height));
+};
+
+void wxListHeaderData::GetItem( wxListItem &item )
+{
+  item.m_mask = m_mask;
+  item.m_text = m_text;
+  item.m_image = m_image;
+  item.m_format = m_format;
+  item.m_width = m_width;
+};
+
+void wxListHeaderData::GetText( wxString &s )
+{
+  s =  m_text;
+};
+
+int wxListHeaderData::GetImage(void) const
+{
+  return m_image;
+};
+
+int wxListHeaderData::GetWidth(void) const
+{
+  return m_width;
+};
+
+int wxListHeaderData::GetFormat(void) const
+{
+  return m_format;
+};
+
+//-----------------------------------------------------------------------------
+//  wxListLineData
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxListLineData,wxObject);
+
+wxListLineData::wxListLineData( wxListMainWindow *owner, const int mode, wxBrush *hilightBrush )
+{
+  m_mode = mode;
+  m_hilighted = FALSE;
+  m_owner = owner;
+  m_hilightBrush = hilightBrush;
+  m_items.DeleteContents( TRUE );
+  m_spacing = 0;
+};
+
+void wxListLineData::CalculateSize( wxPaintDC *dc, const int spacing )
+{
+  m_spacing = spacing;
+  switch (m_mode)
+  {
+    case wxLC_ICON:
+    {
+      m_bound_all.width = m_spacing;
+      m_bound_all.height = m_spacing+13;
+      wxNode *node = m_items.First();
+      if (node)
+      {
+        wxListItemData *item = (wxListItemData*)node->Data();
+        wxString s;
+        item->GetText( s );
+        long lw,lh;
+        dc->GetTextExtent( s, &lw, &lh );
+        if (lw > m_spacing) m_bound_all.width = lw;
+      };
+      break;
+    };
+    case wxLC_LIST:
+    {
+      wxNode *node = m_items.First();
+      if (node)
+      {
+        wxListItemData *item = (wxListItemData*)node->Data();
+        wxString s;
+        item->GetText( s );
+        long lw,lh;
+        dc->GetTextExtent( s, &lw, &lh );
+        m_bound_all.width = lw;
+        m_bound_all.height = lh;
+      };
+      break;
+    };
+    case wxLC_REPORT:
+    {
+      m_bound_all.width = 0;
+      m_bound_all.height = 0;
+      wxNode *node = m_items.First();
+      while (node)
+      {
+        wxListItemData *item = (wxListItemData*)node->Data();
+        wxString s;
+        item->GetText( s );
+        if (s.IsNull()) s = "H";
+        long lw,lh;
+        dc->GetTextExtent( s, &lw, &lh );
+        item->SetSize( item->GetWidth(), lh );
+        m_bound_all.width += lw;
+        m_bound_all.height = lh;
+        node = node->Next();
+      };
+      break;
+    };
+  };
+};
+
+void wxListLineData::SetPosition( wxPaintDC *dc, const int x, const int y, const int window_width )
+{
+  m_bound_all.x = x;
+  m_bound_all.y = y;
+  switch (m_mode)
+  {
+    case wxLC_ICON:
+    {
+      AssignRect( m_bound_icon, 0, 0, 0, 0 );
+      AssignRect( m_bound_label, 0, 0, 0, 0 );
+      AssignRect( m_bound_hilight, m_bound_all );
+      wxNode *node = m_items.First();
+      if (node)
+      {
+        wxListItemData *item = (wxListItemData*)node->Data();
+        if (item->HasImage())
+        {
+          wxListItemData *item = (wxListItemData*)node->Data();
+          int w = 0;
+          int h = 0;
+          m_owner->GetImageSize( item->GetImage(), w, h );
+          m_bound_icon.x = m_bound_all.x + (m_spacing/2) - (w/2);
+          m_bound_icon.y = m_bound_all.y + m_spacing - h - 5;
+          m_bound_icon.width = w;
+          m_bound_icon.height = h;
+          if (!item->HasText())
+          {
+            AssignRect( m_bound_hilight, m_bound_icon );
+            m_bound_hilight.x -= 3;
+            m_bound_hilight.y -= 3;
+            m_bound_hilight.width += 7;
+            m_bound_hilight.height += 7;
+          };
+        };
+        if (item->HasText())
+        {
+          wxString s;
+          item->GetText( s );
+          long lw,lh;
+          dc->GetTextExtent( s, &lw, &lh );
+          if (m_bound_all.width > m_spacing)
+            m_bound_label.x = m_bound_all.x;
+          else
+            m_bound_label.x = m_bound_all.x +  (m_spacing/2) - lw/2;
+          m_bound_label.y = m_bound_all.y + m_bound_all.height - lh;
+          m_bound_label.width = lw;
+          m_bound_label.height = lh;
+          AssignRect( m_bound_hilight, m_bound_label );
+        };
+      };
+      break;
+    };
+    case wxLC_LIST:
+    {
+      AssignRect( m_bound_label, m_bound_all );
+      AssignRect( m_bound_hilight, m_bound_all );
+      AssignRect( m_bound_icon, 0, 0, 0, 0 );
+      break;
+    };
+    case wxLC_REPORT:
+    {
+      long lw,lh;
+      dc->GetTextExtent( "H", &lw, &lh );
+      m_bound_all.height = lh;
+      m_bound_all.width = window_width;
+      AssignRect( m_bound_label, m_bound_all );
+      AssignRect( m_bound_hilight, m_bound_all );
+      AssignRect( m_bound_icon, 0, 0, 0, 0 );
+      m_bound_hilight.width = window_width-10;
+      m_bound_label.width = window_width-10;
+      break;
+    };
+  };
+};
+
+void wxListLineData::SetColumnPosition( const int index, const int x )
+{
+  int i = index;
+  wxNode *node = m_items.Nth( i );
+  if (node)
+  {
+    wxListItemData *item = (wxListItemData*)node->Data();
+    item->SetPosition( x, m_bound_all.y );
+  };  
+};
+
+void wxListLineData::GetSize( int &width, int &height )
+{
+  width = m_bound_all.width;
+  height = m_bound_all.height;
+};
+
+void wxListLineData::GetExtent( int &x, int &y, int &width, int &height )
+{
+  x = m_bound_all.x;
+  y = m_bound_all.y;
+  width = m_bound_all.width;
+  height = m_bound_all.height;
+};
+
+void wxListLineData::GetLabelExtent( int &x, int &y, int &width, int &height )
+{
+  x = m_bound_label.x;
+  y = m_bound_label.y;
+  width = m_bound_label.width;
+  height = m_bound_label.height;
+};
+
+void wxListLineData::GetRect( wxRectangle &rect )
+{
+  AssignRect( rect, m_bound_all );
+};
+
+long wxListLineData::IsHit( const int x, const int y )
+{
+  wxNode *node = m_items.First();
+  if (node)
+  {
+    wxListItemData *item = (wxListItemData*)node->Data();
+    if (item->HasImage() && IsInRect( x, y, m_bound_icon )) return wxLIST_HITTEST_ONITEMICON;
+    if (item->HasText() && IsInRect( x, y, m_bound_label )) return wxLIST_HITTEST_ONITEMLABEL;
+    if (!(item->HasImage() || item->HasText())) return 0;
+  };
+  // if there is no icon or text = empty
+  if (IsInRect( x, y, m_bound_all )) return wxLIST_HITTEST_ONITEMICON;
+  return 0;
+};
+
+void wxListLineData::InitItems( const int num )
+{
+  for (int i = 0; i < num; i++) m_items.Append( new wxListItemData() );
+};
+
+void wxListLineData::SetItem( const int index, const wxListItem &info )
+{
+  wxNode *node = m_items.Nth( index );
+  if (node)
+  {
+    wxListItemData *item = (wxListItemData*)node->Data();
+    item->SetItem( info );
+  };
+};
+
+void wxListLineData::GetItem( int const index, wxListItem &info )
+{
+  int i = index;
+  wxNode *node = m_items.Nth( i );
+  if (node)
+  {
+    wxListItemData *item = (wxListItemData*)node->Data();
+    item->GetItem( info );
+  };
+};
+
+void wxListLineData::GetText( const int index, wxString &s )
+{
+  int i = index;
+  wxNode *node = m_items.Nth( i );
+  s = "";
+  if (node)
+  {
+    wxListItemData *item = (wxListItemData*)node->Data();
+    item->GetText( s );
+  };
+};
+
+void wxListLineData::SetText( const int index, const wxString s )
+{
+  int i = index;
+  wxNode *node = m_items.Nth( i );
+  if (node)
+  {
+    wxListItemData *item = (wxListItemData*)node->Data();
+    item->SetText( s );
+  };
+};
+
+int wxListLineData::GetImage( const int index )
+{
+  int i = index;
+  wxNode *node = m_items.Nth( i );
+  if (node)
+  {
+    wxListItemData *item = (wxListItemData*)node->Data();
+    return item->GetImage();
+  };
+  return -1;
+};
+
+void wxListLineData::DoDraw( wxPaintDC *dc, const bool hilight, const bool paintBG )
+{
+  long dev_x = dc->LogicalToDeviceX( m_bound_all.x-2 );
+  long dev_y = dc->LogicalToDeviceY( m_bound_all.y-2 );
+  long dev_w = dc->LogicalToDeviceXRel( m_bound_all.width+4 );
+  long dev_h = dc->LogicalToDeviceYRel( m_bound_all.height+4 );
+  if (!m_owner->IsExposed( dev_x, dev_y, dev_w, dev_h ) ) return;
+  
+  if (paintBG)
+  {
+    if (hilight)
+    {
+      dc->SetBrush( m_hilightBrush );
+      dc->SetPen( wxTRANSPARENT_PEN );
+    }
+    else
+    {
+      dc->SetBrush( wxWHITE_BRUSH );
+      dc->SetPen( wxTRANSPARENT_PEN );
+    };
+    dc->DrawRectangle( m_bound_hilight.x-2, m_bound_hilight.y-2,
+                       m_bound_hilight.width+4, m_bound_hilight.height+4 );
+  };
+  if (m_mode == wxLC_REPORT)
+  {
+    wxString s;
+    wxNode *node = m_items.First();
+    while (node)
+    {
+      wxListItemData *info = (wxListItemData*)node->Data();
+      dc->SetClippingRegion( info->GetX(), info->GetY(), info->GetWidth(), info->GetHeight() );
+      info->GetText( s );
+	if (hilight)
+	  dc->SetTextForeground( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_HIGHLIGHTTEXT ) );
+	else
+          dc->SetTextForeground( info->GetColour() );
+      dc->DrawText( s, info->GetX()+2, info->GetY() );
+      dc->DestroyClippingRegion();
+      node = node->Next();
+    };
+  }
+  else
+  {
+    wxNode *node = m_items.First();
+    if (node)
+    {
+      wxListItemData *item = (wxListItemData*)node->Data();
+      if (item->HasImage())
+      {
+        m_owner->DrawImage( item->GetImage(), dc, m_bound_icon.x, m_bound_icon.y );
+      };
+      if (item->HasText())
+      {
+        wxString s;
+        item->GetText( s );
+	if (hilight)
+	  dc->SetTextForeground( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_HIGHLIGHTTEXT ) );
+	else
+          dc->SetTextForeground( item->GetColour() );
+        dc->DrawText( s, m_bound_label.x, m_bound_label.y );
+      };
+    };
+  };
+};
+
+void wxListLineData::Hilight( const bool on )
+{
+  if (on == m_hilighted) return;
+  if (on) 
+    m_owner->SelectLine( this );
+  else
+    m_owner->DeselectLine( this );
+  m_hilighted = on;
+};
+
+void wxListLineData::ReverseHilight( void )
+{
+  m_hilighted = !m_hilighted;
+  if (m_hilighted) 
+    m_owner->SelectLine( this );
+  else
+    m_owner->DeselectLine( this );
+};
+
+void wxListLineData::DrawRubberBand( wxPaintDC *dc, const bool on )
+{
+  if (on)
+  {
+    dc->SetPen( wxBLACK_PEN );
+    dc->SetBrush( wxTRANSPARENT_BRUSH );
+    dc->DrawRectangle( m_bound_hilight.x-2, m_bound_hilight.y-2,
+                       m_bound_hilight.width+4, m_bound_hilight.height+4 );
+  };
+};
+
+void wxListLineData::Draw( wxPaintDC *dc )
+{
+  DoDraw( dc, m_hilighted, m_hilighted );
+};
+
+bool wxListLineData::IsInRect( const int x, const int y, const wxRectangle &rect )
+{
+  return ((x >= rect.x) && (x <= rect.x+rect.width) && (y >= rect.y) && (y <= rect.y+rect.height));
+};
+
+bool wxListLineData::IsHilighted( void )
+{
+  return m_hilighted;
+};
+
+void wxListLineData::AssignRect( wxRectangle &dest, const int x, const int y, const int width, const int height )
+{
+  dest.x = x;
+  dest.y = y;
+  dest.width = width;
+  dest.height = height;
+};
+
+void wxListLineData::AssignRect( wxRectangle &dest, const wxRectangle &source )
+{
+  dest.x = source.x;
+  dest.y = source.y;
+  dest.width = source.width;
+  dest.height = source.height;
+};
+
+//-----------------------------------------------------------------------------
+//  wxListHeaderWindow
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxListHeaderWindow,wxWindow);
+
+BEGIN_EVENT_TABLE(wxListHeaderWindow,wxWindow)
+  EVT_PAINT         (wxListHeaderWindow::OnPaint)
+  EVT_MOUSE_EVENTS  (wxListHeaderWindow::OnMouse)
+  EVT_SET_FOCUS     (wxListHeaderWindow::OnSetFocus)
+END_EVENT_TABLE()
+
+wxListHeaderWindow::wxListHeaderWindow( void )
+{
+  m_owner = NULL;
+  m_currentCursor = NULL;
+  m_resizeCursor = NULL;
+};
+
+wxListHeaderWindow::wxListHeaderWindow( wxWindow *win, const wxWindowID id, wxListMainWindow *owner, 
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name ) :
+  wxWindow( win, id, pos, size, style, name )
+{
+  m_owner = owner;
+//  m_currentCursor = wxSTANDARD_CURSOR;
+  m_currentCursor = NULL;
+  m_resizeCursor = new wxCursor( wxCURSOR_SIZEWE );
+};
+
+void wxListHeaderWindow::DoDrawRect( wxPaintDC *dc, int x, int y, int w, int h )
+{
+  const m_corner = 1;
+
+  dc->SetBrush( *wxTRANSPARENT_BRUSH );
+
+  dc->SetPen( *wxBLACK_PEN );
+  dc->DrawLine( x+w-m_corner+1, y, x+w, y+h );  // right (outer)
+  dc->DrawRectangle( x, y+h, w, 1 );            // bottom (outer)
+  
+  dc->SetPen( *wxMEDIUM_GREY_PEN );
+  dc->DrawLine( x+w-m_corner, y, x+w-1, y+h );  // right (inner)
+  dc->DrawRectangle( x+1, y+h-1, w-2, 1 );      // bottom (inner)
+  
+  dc->SetPen( *wxWHITE_PEN );
+  dc->DrawRectangle( x, y, w-m_corner+1, 1 );   // top (outer)
+//  dc->DrawRectangle( x, y+1, w-m_corner, 1 );   // top (inner)
+  dc->DrawRectangle( x, y, 1, h );              // left (outer)
+//  dc->DrawRectangle( x+1, y, 1, h-1 );          // left (inner)
+};
+
+void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
+{
+  wxPaintDC dc( this );
+  PrepareDC( dc );
+  
+  dc.BeginDrawing();
+     
+  dc.SetFont( wxSystemSettings::GetSystemFont( wxSYS_SYSTEM_FONT ) );
+
+  int w = 0;
+  int h = 0;
+  int x = 0;
+  int y = 0;
+  GetClientSize( &w, &h );
+
+  dc.SetTextForeground( *wxBLACK );
+
+  x = 1;
+  y = 1;
+  int numColumns = m_owner->GetColumnCount();
+  wxListItem item;
+  for (int i = 0; i < numColumns; i++)
+  {
+    m_owner->GetColumn( i, item );
+    int cw = item.m_width-2;
+    if ((i+1 == numColumns) || (x+item.m_width > w-5)) cw = w-x-1;
+    dc.SetPen( *wxWHITE_PEN );
+    
+    DoDrawRect( &dc, x, y, cw, h-2 );
+    dc.SetClippingRegion( x, y, cw-5, h-4 );
+    dc.DrawText( item.m_text, x+4, y+3 );
+    dc.DestroyClippingRegion();
+    x += item.m_width;
+    if (x > w+5) break;
+  }; 
+  dc.EndDrawing();
+};
+
+void wxListHeaderWindow::OnMouse( wxMouseEvent &event )
+{
+  float fx = 0;
+  float fy = 0;
+  event.Position( &fx, &fy );
+  int x = (int)fx;
+  int y = (int)fy;
+  if (event.Moving())
+  {
+    bool hit = FALSE;
+    int xpos = 0;
+    for (int j = 0; j < m_owner->GetColumnCount(); j++)
+    {
+      xpos += m_owner->GetColumnWidth( j );
+      if ((abs(x-xpos) < 2) && (y < 14)) { hit = TRUE; break; }
+    };
+    if (hit)
+    {
+//      if (m_currentCursor == wxSTANDARD_CURSOR) SetCursor( m_resizeCursor );
+//      m_currentCursor = m_resizeCursor;
+    }
+    else
+    {
+//      if (m_currentCursor != wxSTANDARD_CURSOR) SetCursor( wxSTANDARD_CURSOR );
+//      m_currentCursor = wxSTANDARD_CURSOR;
+    };
+  };
+};
+
+void wxListHeaderWindow::OnSetFocus( wxFocusEvent &WXUNUSED(event) )
+{
+  m_owner->SetFocus();
+};
+
+//-----------------------------------------------------------------------------
+// wxListRenameTimer (internal)
+//-----------------------------------------------------------------------------
+
+wxListRenameTimer::wxListRenameTimer( wxListMainWindow *owner ) 
+{ 
+  m_owner = owner; 
+};
+
+void wxListRenameTimer::Notify() 
+{ 
+  m_owner->OnRenameTimer();
+};
+
+//-----------------------------------------------------------------------------
+//  wxListMainWindow
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxListMainWindow,wxScrolledWindow);
+    
+BEGIN_EVENT_TABLE(wxListMainWindow,wxScrolledWindow)
+  EVT_PAINT          (wxListMainWindow::OnPaint)
+  EVT_SIZE           (wxListMainWindow::OnSize)
+  EVT_MOUSE_EVENTS   (wxListMainWindow::OnMouse)
+  EVT_CHAR           (wxListMainWindow::OnChar)
+  EVT_SET_FOCUS      (wxListMainWindow::OnSetFocus)
+  EVT_KILL_FOCUS     (wxListMainWindow::OnKillFocus)
+END_EVENT_TABLE()
+
+wxListMainWindow::wxListMainWindow( void )
+{
+  m_mode = 0;
+  m_lines.DeleteContents( TRUE );
+  m_columns.DeleteContents( TRUE );
+  m_current = NULL;
+  m_visibleLines = 0;
+  m_hilightBrush = NULL;
+  m_myFont = NULL;
+  m_xScroll = 0;
+  m_yScroll = 0;
+  m_dirty = TRUE;
+  m_small_image_list = NULL;
+  m_normal_image_list = NULL;
+  m_small_spacing = 30;
+  m_normal_spacing = 40;
+  m_hasFocus = FALSE;
+  m_usedKeys = TRUE;
+  m_lastOnSame = FALSE;
+//  m_renameTimer = new wxRenameTimer( this );
+  m_isCreated = FALSE;
+  m_isDragging = FALSE;
+};
+
+wxListMainWindow::wxListMainWindow( wxWindow *parent, const wxWindowID id, 
+      const wxPoint &pos, const wxSize &size,
+      const long style, const wxString &name ) :
+  wxScrolledWindow( parent, id, pos, size, style, name ) 
+{
+  m_mode = style;
+  m_lines.DeleteContents( TRUE );
+  m_columns.DeleteContents( TRUE );
+  m_current = NULL;
+  m_dirty = TRUE;
+  m_visibleLines = 0;
+  m_hilightBrush = new wxBrush( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHT), wxSOLID );
+  m_small_image_list = NULL;
+  m_normal_image_list = NULL;
+  m_small_spacing = 30;
+  m_normal_spacing = 40;
+//  AllowDoubleClick( TRUE );
+  m_myFont = wxNORMAL_FONT;
+  m_hasFocus = FALSE;
+  m_isDragging = FALSE;
+  m_isCreated = FALSE;
+  wxSize sz = size;
+  sz.y = 25;
+  
+  if (m_mode & wxLC_REPORT)
+  {
+    m_xScroll = 0;
+    m_yScroll = 15;
+  }
+  else
+  {
+    m_xScroll = 15;
+    m_yScroll = 0;
+  };
+  SetScrollbars( m_xScroll, m_yScroll, 0, 0, 0, 0 );
+  
+  m_usedKeys = TRUE;
+  m_lastOnSame = FALSE;
+  m_renameTimer = new wxListRenameTimer( this );
+  m_renameAccept = FALSE;
+//  m_text = new wxRawListTextCtrl( GetParent(), "", &m_renameAccept, &m_renameRes, this, 10, 10, 40, 10 );
+//  m_text->Show( FALSE );
+
+  SetBackgroundColour( *wxWHITE );
+  
+/*
+  char *accepted_drop_types[] = { "text/plain" };
+  gtk_widget_dnd_drag_set( m_wxwindow, TRUE, accepted_drop_types, 1 );
+*/  
+};
+
+wxListMainWindow::~wxListMainWindow( void )
+{
+//  if (m_hilightColour) delete m_hilightColour;
+//  if (m_hilightBrush) delete m_hilightBrush;
+//  if (m_myFont) delete m_myFont;
+  delete m_renameTimer;
+//  delete m_text;
+};
+
+void wxListMainWindow::RefreshLine( wxListLineData *line )
+{
+  int x = 0;
+  int y = 0;
+  int w = 0;
+  int h = 0;
+  if (line)
+  {
+    wxClientDC dc(this);
+    PrepareDC( dc );
+    line->GetExtent( x, y, w, h );
+    wxRectangle rect( 
+      dc.LogicalToDeviceX(x-3), 
+      dc.LogicalToDeviceY(y-3), 
+      dc.LogicalToDeviceXRel(w+6), 
+      dc.LogicalToDeviceXRel(h+6) );
+    Refresh( TRUE, &rect );
+  };
+};
+
+void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
+{
+  if (m_dirty) return;
+  
+  wxPaintDC dc( this );
+  PrepareDC( dc );
+  
+  dc.BeginDrawing();
+
+//  dc.SetFont( *m_myFont );
+  dc.SetFont( wxSystemSettings::GetSystemFont( wxSYS_SYSTEM_FONT ) );
+
+  wxNode *node = m_lines.First();
+  while (node) 
+  {
+    wxListLineData *line = (wxListLineData*)node->Data();
+    line->Draw( &dc );
+    node = node->Next();
+  };
+  if (m_current) m_current->DrawRubberBand( &dc, m_hasFocus );
+
+  dc.EndDrawing();
+};
+
+void wxListMainWindow::HilightAll( const bool on )
+{
+  wxNode *node = m_lines.First();
+  while (node)
+  {
+    wxListLineData *line = (wxListLineData *)node->Data();
+    if (line->IsHilighted() != on)
+    {
+      line->Hilight( on );
+      RefreshLine( line );
+    };
+    node = node->Next();
+  };
+};
+
+void wxListMainWindow::ActivateLine( wxListLineData *line )
+{
+  if (!m_parent) return;
+  wxListEvent le( wxEVT_COMMAND_LIST_KEY_DOWN, m_parent->GetId() );
+  le.SetEventObject( m_parent );
+  le.m_code = 0;
+  le.m_itemIndex = GetIndexOfLine( line );
+  le.m_col = 0;
+  line->GetItem( 0, le.m_item );
+  OnListNotify( le );
+};
+
+void wxListMainWindow::SendNotify( wxListLineData *line, long command )
+{
+  if (!m_parent) return;
+  wxListEvent le( command, m_parent->GetId() );
+  le.SetEventObject( m_parent );
+  le.m_code = 0;
+  le.m_itemIndex = GetIndexOfLine( line );
+  le.m_col = 0;
+  line->GetItem( 0, le.m_item );
+  OnListNotify( le );
+};
+
+void wxListMainWindow::FocusLine( wxListLineData *WXUNUSED(line) )
+{
+//  SendNotify( line, wxEVT_COMMAND_LIST_ITEM_FOCUSSED );
+};
+
+void wxListMainWindow::UnfocusLine( wxListLineData *WXUNUSED(line) )
+{
+//  SendNotify( line, wxEVT_COMMAND_LIST_ITEM_UNFOCUSSED );
+};
+
+void wxListMainWindow::SelectLine( wxListLineData *line )
+{
+  SendNotify( line, wxEVT_COMMAND_LIST_ITEM_SELECTED );
+};
+
+void wxListMainWindow::DeselectLine( wxListLineData *line )
+{
+  SendNotify( line, wxEVT_COMMAND_LIST_ITEM_DESELECTED );
+};
+
+void wxListMainWindow::DeleteLine( wxListLineData *line )
+{
+  SendNotify( line, wxEVT_COMMAND_LIST_DELETE_ITEM );
+};
+
+void wxListMainWindow::RenameLine( wxListLineData *line, const wxString &newName )
+{
+  wxListEvent le( wxEVT_COMMAND_LIST_END_LABEL_EDIT );
+  le.m_code = 0;
+  le.m_itemIndex = GetIndexOfLine( line );
+  le.m_col = 0;
+  line->GetItem( 0, le.m_item );
+  le.m_item.m_text = newName;
+  OnListNotify( le );
+};
+
+void wxListMainWindow::OnRenameTimer()
+{
+  return;
+  wxString s;
+  m_current->GetText( 0, s );
+  int x = 0;
+  int y = 0;
+  int w = 0;
+  int h = 0;
+  m_current->GetLabelExtent( x, y, w, h );
+  int dx = 0;
+  int dy = 0;
+  GetPosition( &dx, &dy );
+  x += dx;
+  y += dy;
+/*
+  wxRawListTextCtrl *text = new wxRawListTextCtrl( 
+    GetParent(), s, &m_renameAccept, &m_renameRes, this, x+2, y+2, w+8, h+8 );
+  text->SetFocus();
+*/
+/*
+  m_text->SetSize( x+3, y+3, w+6, h+6 );
+  m_text->SetValue( s );
+  m_text->Show( TRUE );
+  m_text->SetFocus();
+*/
+/*
+  char *res = wxGetTextFromUser( "Enter new name:", "", s );
+  if (res)
+  {
+    m_dirty = TRUE;
+    s = res;
+    RenameLine( m_current, s );
+  };
+  */
+};
+
+void wxListMainWindow::OnRenameAccept()
+{
+  RenameLine( m_current, m_renameRes );
+};
+
+void wxListMainWindow::OnMouse( wxMouseEvent &event )
+{
+  if (!m_current) return;
+  if (m_dirty) return;
+//  wxDragCanvas::OnEvent( event );
+
+  wxClientDC dc(this);
+  PrepareDC(dc);
+  long x = dc.DeviceToLogicalX( (long)event.GetX() );
+  long y = dc.DeviceToLogicalY( (long)event.GetY() );
+  
+  long hitResult = 0;
+  wxNode *node = m_lines.First();
+  wxListLineData *line = NULL;
+  while (node)
+  {
+    line = (wxListLineData*)node->Data();
+    hitResult = line->IsHit( x, y );
+    if (hitResult) break;
+    line = NULL;
+    node = node->Next();
+  };
+  
+  if (!event.Dragging()) m_isDragging = FALSE;
+  
+  if (event.Dragging() && (!m_isDragging))
+  {
+    m_isDragging = TRUE;
+    wxListEvent le( wxEVT_COMMAND_LIST_BEGIN_DRAG, m_parent->GetId() );
+    le.SetEventObject( this );
+    le.m_code = 0;
+    le.m_itemIndex = 0;
+    le.m_col = 0;
+    OnListNotify( le );
+  };
+  
+  if (!line) return;
+  
+  if (event.ButtonDClick())
+  {
+    m_usedKeys = FALSE;
+    m_lastOnSame = FALSE;
+    m_renameTimer->Stop();
+    ActivateLine( line );
+    return;
+  };
+  
+  if (event.LeftUp() && m_lastOnSame)
+  {
+    m_usedKeys = FALSE;
+    if ((line == m_current) &&
+        (hitResult == wxLIST_HITTEST_ONITEMLABEL) /* && 
+	(m_mode & wxLC_ICON) */  )
+    {
+      m_renameTimer->Start( 330, TRUE );
+    };
+    m_lastOnSame = FALSE;
+    return;
+  };
+  
+  if (event.LeftDown())
+  {
+    m_usedKeys = FALSE;
+    wxListLineData *oldCurrent = m_current;
+    m_current = line;
+    if (!event.ShiftDown() || (m_mode & wxLC_SINGLE_SEL)) HilightAll( FALSE );
+    m_current->ReverseHilight();
+    RefreshLine( m_current );
+    if (m_current != oldCurrent)
+    {
+      UnfocusLine( oldCurrent );
+      FocusLine( m_current );
+      RefreshLine( oldCurrent );
+    };
+    m_lastOnSame = (m_current == oldCurrent);
+    return;
+  };
+  
+};
+
+void wxListMainWindow::MoveToFocus( void )
+{
+  if (!m_current) return;
+/*
+  int x = 0;
+  int y = 0;
+  int w = 0;
+  int h = 0;
+  m_current->GetExtent( x, y, w, h );
+  int w_p = 0;
+  int h_p = 0;
+  GetClientSize( &w_p, &h_p );
+  if (m_mode & wxLC_REPORT)
+  {
+    if (GetScrollPos( wxHORIZONTAL ) != 0) SetScrollPos( wxHORIZONTAL, 0);
+    int y_s = m_yScroll*GetScrollPos( wxVERTICAL );
+    if ((y > y_s) && (y+h < y_s+h_p)) return; 
+    if (y-y_s < 5) SetScrollPos( wxVERTICAL, (y-5)/m_yScroll );
+    if (y+h+5 > y_s+h_p) SetScrollPos( wxVERTICAL, (y+h-h_p+h+5)/m_yScroll );
+  }
+  else
+  {
+    if (GetScrollPos( wxVERTICAL ) != 0) SetScrollPos( wxVERTICAL, 0);
+    int x_s = m_xScroll*GetScrollPos( wxHORIZONTAL );
+    if ((x > x_s) && (x+w < x_s+w_p)) return;
+    if (x-x_s < 5) SetScrollPos( wxHORIZONTAL, (x-5)/m_xScroll );
+    if (x+w > x_s+w_p)  SetScrollPos( wxHORIZONTAL, (x+w-w_p+5)/m_xScroll );
+  };
+*/
+};
+
+void wxListMainWindow::OnArrowChar( wxListLineData *newCurrent, bool shiftDown )
+{
+  UnfocusLine( m_current );
+  if ((m_mode & wxLC_SINGLE_SEL) || (m_usedKeys == FALSE)) m_current->Hilight( FALSE );
+  wxListLineData *oldCurrent = m_current;
+  m_current = newCurrent;
+  MoveToFocus();
+  if (shiftDown || (m_mode & wxLC_SINGLE_SEL)) m_current->Hilight( TRUE );
+  FocusLine( m_current );
+  RefreshLine( m_current );
+  RefreshLine( oldCurrent );
+};
+
+void wxListMainWindow::OnChar( wxKeyEvent &event )
+{
+/*
+  if (event.KeyCode() == WXK_TAB)
+  {
+    if (event.ShiftDown())
+      TravPrev( &event );
+    else
+      TravNext( &event );
+    return;
+  };
+*/
+  if (!m_current) return;
+  switch (event.KeyCode())
+  {
+    case WXK_UP:
+    {
+      wxNode *node = m_lines.Member( m_current )->Previous();
+      if (node) OnArrowChar( (wxListLineData*)node->Data(), event.ShiftDown() );
+      break;
+    };
+    case WXK_DOWN:
+    {
+      wxNode *node = m_lines.Member( m_current )->Next();
+      if (node) OnArrowChar( (wxListLineData*)node->Data(), event.ShiftDown() );
+      break;
+    };
+    case WXK_END:
+    {
+      wxNode *node = m_lines.Last();
+      OnArrowChar( (wxListLineData*)node->Data(), event.ShiftDown() );
+      break;
+    };
+    case WXK_HOME:
+    {
+      wxNode *node = m_lines.First();
+      OnArrowChar( (wxListLineData*)node->Data(), event.ShiftDown() );
+      break;
+    };
+    case WXK_PRIOR:
+    {
+      int steps = 0;
+      if (m_mode & wxLC_REPORT) { steps = m_visibleLines-1; }
+      else
+      {
+        int pos = 0; 
+        wxNode *node = m_lines.First();
+        for (;;) { if (m_current == (wxListLineData*)node->Data()) break; pos++; node = node->Next(); };
+        steps = pos % m_visibleLines;
+      };
+      wxNode *node = m_lines.Member( m_current );
+      for (int i = 0; i < steps; i++) if (node->Previous()) node = node->Previous();
+      if (node) OnArrowChar( (wxListLineData*)node->Data(), event.ShiftDown() );
+      break;
+    };
+    case WXK_NEXT:
+    {
+      int steps = 0;
+      if (m_mode & wxLC_REPORT) { steps = m_visibleLines-1; }
+      else
+      {
+        int pos = 0; wxNode *node = m_lines.First();
+        for (;;) { if (m_current == (wxListLineData*)node->Data()) break; pos++; node = node->Next(); };
+        steps = m_visibleLines-(pos % m_visibleLines)-1;
+      };
+      wxNode *node = m_lines.Member( m_current );
+      for (int i = 0; i < steps; i++) if (node->Next()) node = node->Next();
+      if (node) OnArrowChar( (wxListLineData*)node->Data(), event.ShiftDown() );
+      break;
+    };
+    case WXK_LEFT:
+    {
+      if (!(m_mode & wxLC_REPORT))
+      {
+        wxNode *node = m_lines.Member( m_current );
+        for (int i = 0; i <m_visibleLines; i++) if (node->Previous()) node = node->Previous();
+        if (node) OnArrowChar( (wxListLineData*)node->Data(), event.ShiftDown() );
+      };
+      break;
+    };
+    case WXK_RIGHT:
+    {
+      if (!(m_mode & wxLC_REPORT))
+      {
+        wxNode *node = m_lines.Member( m_current );
+        for (int i = 0; i <m_visibleLines; i++) if (node->Next()) node = node->Next();
+        if (node) OnArrowChar( (wxListLineData*)node->Data(), event.ShiftDown() );
+      };
+      break;
+    };
+    case WXK_INSERT:
+    {
+      if (!(m_mode & wxLC_SINGLE_SEL))
+      {
+        wxListLineData *oldCurrent = m_current;
+        UnfocusLine( m_current );
+        m_current->ReverseHilight();
+        wxNode *node = m_lines.Member( m_current )->Next();       
+        if (node) m_current = (wxListLineData*)node->Data();
+        MoveToFocus();
+        FocusLine( m_current );
+	RefreshLine( m_current );
+	RefreshLine( oldCurrent );
+      };
+    };
+    break;
+    case WXK_RETURN:
+    case WXK_EXECUTE:
+    {
+      ActivateLine( m_current );
+    };
+    break;
+    default:
+    {
+      event.Skip();
+      return;
+    };
+  };
+  m_usedKeys = TRUE;
+};
+
+void wxListMainWindow::OnSetFocus( wxFocusEvent &WXUNUSED(event) )
+{
+  m_hasFocus = TRUE;
+  RefreshLine( m_current );
+  
+  if (!m_parent) return;
+  
+  wxFocusEvent event( wxEVT_SET_FOCUS, m_parent->GetId() );
+  event.SetEventObject( m_parent );
+  m_parent->ProcessEvent( event );
+};
+
+void wxListMainWindow::OnKillFocus( wxFocusEvent &WXUNUSED(event) )
+{
+  m_hasFocus = FALSE;
+  RefreshLine( m_current );
+};
+
+void wxListMainWindow::OnSize( wxSizeEvent &WXUNUSED(event) )
+{
+/*
+  We don't even allow the wxScrolledWindow::AdjustScrollbars() call
+
+  CalculatePositions();
+  printf( "OnSize::Refresh.\n" );
+  Refresh();
+  event.Skip();
+*/
+};
+
+wxFont *wxListMainWindow::GetMyFont( void )
+{
+  return m_myFont;
+};
+
+void wxListMainWindow::DrawImage( int index, wxPaintDC *dc, int x, int y )
+{
+  if ((m_mode & wxLC_ICON) && (m_normal_image_list))
+  {
+    m_normal_image_list->Draw( index, *dc, x, y );
+    return;
+  };
+  if ((m_mode & wxLC_SMALL_ICON) && (m_small_image_list))
+  {
+    m_small_image_list->Draw( index, *dc, x, y );
+  };
+};
+
+void wxListMainWindow::GetImageSize( int index, int &width, int &height )
+{
+  if ((m_mode & wxLC_ICON) && (m_normal_image_list))
+  {
+    m_normal_image_list->GetSize( index, width, height );
+    return;
+  };
+  if ((m_mode & wxLC_SMALL_ICON) && (m_small_image_list))
+  {
+    m_small_image_list->GetSize( index, width, height );
+    return;
+  };
+  width = 0;
+  height = 0;
+};
+
+int wxListMainWindow::GetTextLength( wxString &s )
+{
+  wxPaintDC dc( this );
+  long lw = 0;
+  long lh = 0;
+  dc.GetTextExtent( s, &lw, &lh );
+  return lw + 6;
+};
+
+int wxListMainWindow::GetIndexOfLine( const wxListLineData *line )
+{
+  int i = 0;
+  wxNode *node = m_lines.First();
+  while (node)
+  {
+    if (line == (wxListLineData*)node->Data()) return i;
+    i++;
+    node = node->Next();
+  };
+  return -1;
+};
+
+void wxListMainWindow::SetImageList( wxImageList *imageList, const int which )
+{
+  m_dirty = TRUE;
+  if (which == wxIMAGE_LIST_NORMAL) m_normal_image_list = imageList;
+  if (which == wxIMAGE_LIST_SMALL) m_small_image_list = imageList;
+};
+
+void wxListMainWindow::SetItemSpacing( const int spacing, const bool isSmall )
+{
+  m_dirty = TRUE;
+  if (isSmall)
+  { 
+    m_small_spacing = spacing;
+  }
+  else
+  {
+    m_normal_spacing = spacing;
+  };
+};
+
+int wxListMainWindow::GetItemSpacing( const bool isSmall )
+{
+  if (isSmall) return m_small_spacing; else return m_normal_spacing;
+};
+
+void wxListMainWindow::SetColumn( const int col, wxListItem &item )
+{
+  m_dirty = TRUE;
+  wxNode *node = m_columns.Nth( col );
+  if (node)
+  {
+    if (item.m_width == wxLIST_AUTOSIZE_USEHEADER) item.m_width = GetTextLength( item.m_text )+7;
+    wxListHeaderData *column = (wxListHeaderData*)node->Data();
+    column->SetItem( item );
+  };
+};
+
+void wxListMainWindow::SetColumnWidth( const int col, const int width )
+{
+  m_dirty = TRUE;
+  wxNode *node = m_columns.Nth( col );
+  if (node)
+  {
+    wxListHeaderData *column = (wxListHeaderData*)node->Data();
+    column->SetWidth( width );
+  };
+};
+
+void wxListMainWindow::GetColumn( const int col, wxListItem &item )
+{
+  wxNode *node = m_columns.Nth( col );
+  if (node)
+  {
+    wxListHeaderData *column = (wxListHeaderData*)node->Data();
+    column->GetItem( item );
+  }
+  else
+  {
+    item.m_format = 0;
+    item.m_width = 0;
+    item.m_text = "";
+    item.m_image = 0;
+    item.m_data = 0;
+  };
+};
+
+int wxListMainWindow::GetColumnWidth( const int col ) 
+{
+  wxNode *node = m_columns.Nth( col );
+  if (node)
+  {
+    wxListHeaderData *column = (wxListHeaderData*)node->Data();
+    return column->GetWidth();
+  }
+  else
+    return 0;
+};
+
+int wxListMainWindow::GetColumnCount( void )
+{
+  return m_columns.Number();
+};
+
+int wxListMainWindow::GetCountPerPage( void )
+{
+  return m_visibleLines;
+};
+
+void wxListMainWindow::SetItem( wxListItem &item )
+{
+  m_dirty = TRUE;
+  wxNode *node = m_lines.Nth( item.m_itemId );
+  if (node) 
+  {
+    wxListLineData *line = (wxListLineData*)node->Data();
+    if (m_mode & wxLC_REPORT) item.m_width = GetColumnWidth( item.m_col )-3;
+    line->SetItem( item.m_col, item );
+  };
+};
+
+void wxListMainWindow::SetItemState( const long item, const long state, const long stateMask )
+{
+  // m_dirty = TRUE; no recalcs needed
+  wxListLineData *oldCurrent = m_current;
+  if (stateMask & wxLIST_STATE_FOCUSED) 
+  {
+    wxNode *node = m_lines.Nth( item );
+    if (node) 
+    {
+      wxListLineData *line = (wxListLineData*)node->Data();
+      UnfocusLine( m_current );
+      m_current = line;
+      FocusLine( m_current );
+      RefreshLine( m_current );
+      RefreshLine( oldCurrent );
+    };
+  };
+  if (stateMask & wxLIST_STATE_SELECTED)
+  {
+    wxNode *node = m_lines.Nth( item );
+    if (node) 
+    {
+      wxListLineData *line = (wxListLineData*)node->Data();
+      bool on = state & wxLIST_STATE_SELECTED;
+      line->Hilight( on );
+      RefreshLine( m_current );
+      RefreshLine( oldCurrent );
+    };
+  };
+};
+
+int wxListMainWindow::GetItemState( const long item, const long stateMask )
+{
+  int ret = wxLIST_STATE_DONTCARE;
+  if (stateMask & wxLIST_STATE_FOCUSED)
+  {
+    wxNode *node = m_lines.Nth( item );
+    if (node) 
+    {
+      wxListLineData *line = (wxListLineData*)node->Data();
+      if (line == m_current) ret |= wxLIST_STATE_FOCUSED;
+    };
+  };
+  if (stateMask & wxLIST_STATE_SELECTED)
+  {
+    wxNode *node = m_lines.Nth( item );
+    if (node) 
+    {
+      wxListLineData *line = (wxListLineData*)node->Data();
+      if (line->IsHilighted()) ret |= wxLIST_STATE_FOCUSED;
+    };
+  };
+  return ret;
+};
+
+void wxListMainWindow::GetItem( wxListItem &item )
+{
+  wxNode *node = m_lines.Nth( item.m_itemId );
+  if (node) 
+  {
+    wxListLineData *line = (wxListLineData*)node->Data();
+    line->GetItem( item.m_col, item );
+  }
+  else
+  {
+    item.m_mask = 0;
+    item.m_text = "";
+    item.m_image = 0;
+    item.m_data = 0;
+  };
+};
+
+int wxListMainWindow::GetItemCount( void )
+{
+  return m_lines.Number();
+};
+
+void wxListMainWindow::GetItemRect( const long index, wxRectangle &rect )
+{
+  wxNode *node = m_lines.Nth( index );
+  if (node) 
+  {
+    wxListLineData *line = (wxListLineData*)node->Data();
+    line->GetRect( rect );
+  }
+  else
+  {
+    rect.x = 0;
+    rect.y = 0;
+    rect.width = 0;
+    rect.height = 0;
+  };
+};
+
+int wxListMainWindow::GetSelectedItemCount( void )
+{
+  int ret = 0;
+  wxNode *node = m_lines.First();
+  while (node)
+  {
+    wxListLineData *line = (wxListLineData*)node->Data();
+    if (line->IsHilighted()) ret++;
+    node = node->Next();
+  };
+  return 0;
+};
+
+void wxListMainWindow::SetMode( const long mode )
+{
+  m_dirty = TRUE;
+  m_mode = mode;
+  
+  DeleteEverything();
+  
+  if (m_mode & wxLC_REPORT)
+  {
+    m_xScroll = 0;
+    m_yScroll = 15;
+  }
+  else
+  {
+    m_xScroll = 15;
+    m_yScroll = 0;
+  };
+};
+
+long wxListMainWindow::GetMode( void ) const
+{
+  return m_mode;
+};
+
+void wxListMainWindow::CalculatePositions( void )
+{
+  wxPaintDC dc( this );
+  dc.SetFont( wxSystemSettings::GetSystemFont( wxSYS_SYSTEM_FONT ) );
+
+  int iconSpacing = 0;
+  if (m_mode & wxLC_ICON) iconSpacing = m_normal_spacing;
+  if (m_mode & wxLC_SMALL_ICON) iconSpacing = m_small_spacing;
+  wxNode *node = m_lines.First();
+  while (node) 
+  {
+    wxListLineData *line = (wxListLineData*)node->Data();
+    line->CalculateSize( &dc, iconSpacing );
+    node = node->Next();
+  };
+
+  int lineWidth = 0;
+  int lineHeight = 0;
+  int lineSpacing = 0;  
+
+  node = m_lines.First();
+  if (node) 
+  {
+    wxListLineData *line = (wxListLineData*)node->Data();
+    int dummy = 0;
+    line->GetSize( dummy, lineSpacing );
+    lineSpacing += 6;
+  }
+  else
+  {
+    // just in case
+    lineSpacing = 6 + (int)dc.GetCharHeight();  
+  };
+  
+  int clientWidth = 0;
+  int clientHeight = 0;
+  
+  if (m_mode & wxLC_REPORT)
+  {
+    int x = 5;
+    int y = 6;
+    int entireHeight = m_lines.Number() * lineSpacing + 10;
+    SetScrollbars( m_xScroll, m_yScroll, 0, (entireHeight+10) / m_yScroll, 0, 0, TRUE );
+    GetClientSize( &clientWidth, &clientHeight );
+    node = m_lines.First();
+    while (node)
+    {
+      wxListLineData *line = (wxListLineData*)node->Data();
+      line->SetPosition( &dc, x, y, clientWidth );
+      int col_x = 3;
+      for (int i = 0; i < GetColumnCount(); i++)
+      {
+        line->SetColumnPosition( i, col_x );
+        col_x += GetColumnWidth( i );
+      };
+      y += lineSpacing;
+      node = node->Next();
+    };
+  }
+  else
+  {
+    // At first, we try without any scrollbar
+    GetSize( &clientWidth, &clientHeight );
+    
+    int entireWidth = 0;
+    
+    for (int tries = 0; tries < 2; tries++)
+    {
+      entireWidth = 0;
+      int x = 5;
+      int y = 6;
+      int maxWidth = 0;
+      node = m_lines.First();
+      while (node)
+      {
+        wxListLineData *line = (wxListLineData*)node->Data();
+        line->SetPosition( &dc, x, y, clientWidth );
+        line->GetSize( lineWidth, lineHeight );
+        if (lineWidth > maxWidth) maxWidth = lineWidth;
+        y += lineSpacing;
+        if (y+lineHeight > clientHeight-4) 
+        {
+          y = 6;
+          x += maxWidth+13;
+          entireWidth += maxWidth+13;
+          maxWidth = 0;
+        };
+        node = node->Next();
+	if (!node) entireWidth += maxWidth;
+	if ((tries == 0) && (entireWidth > clientWidth))
+	{
+	  clientHeight -= 14; // scrollbar height
+	  break;
+	};
+	if (!node) tries = 1;
+      };
+    };
+    SetScrollbars( m_xScroll, m_yScroll, (entireWidth+15) / m_xScroll, 0, 0, 0, TRUE );
+  };
+  m_visibleLines = (clientHeight-4) / (lineSpacing);
+};
+
+void wxListMainWindow::RealizeChanges( void )
+{
+  if (!m_current)
+  {
+    wxNode *node = m_lines.First();
+    if (node) m_current = (wxListLineData*)node->Data();
+  };
+  if (m_current)
+  { 
+    FocusLine( m_current );
+    if (m_mode & wxLC_SINGLE_SEL) m_current->Hilight( TRUE );
+  };
+};
+
+long wxListMainWindow::GetNextItem( const long item, int WXUNUSED(geometry), int state )
+{
+  long ret = 0;
+  if (item > 0) ret = item;
+  wxNode *node = m_lines.Nth( ret );
+  while (node)
+  {
+    wxListLineData *line = (wxListLineData*)node->Data();
+    if ((state & wxLIST_STATE_FOCUSED) && (line == m_current)) return ret;
+    if ((state & wxLIST_STATE_SELECTED) && (line->IsHilighted())) return ret;
+    if (!state) return ret;
+    ret++;
+    node = node->Next();
+  };
+  return -1;
+};
+
+void wxListMainWindow::DeleteItem( const long index )
+{
+  m_dirty = TRUE;
+  wxNode *node = m_lines.Nth( index );
+  if (node)
+  {
+    wxListLineData *line = (wxListLineData*)node->Data();
+    DeleteLine( line );
+    m_lines.DeleteNode( node );
+  };
+};
+
+void wxListMainWindow::DeleteColumn( const int col )
+{
+  m_dirty = TRUE;
+  wxNode *node = m_columns.Nth( col );
+  if (node) m_columns.DeleteNode( node );
+};
+
+void wxListMainWindow::DeleteAllItems( void )
+{
+  m_dirty = TRUE;
+  wxNode *node = m_lines.First();
+  while (node)
+  {
+    wxListLineData *line = (wxListLineData*)node->Data();
+    DeleteLine( line );
+    node = node->Next();
+  };
+  m_lines.Clear();
+  m_current = NULL;
+};
+
+void wxListMainWindow::DeleteEverything( void )
+{
+  m_dirty = TRUE;
+  wxNode *node = m_lines.First();
+  while (node)
+  {
+    wxListLineData *line = (wxListLineData*)node->Data();
+    DeleteLine( line );
+    node = node->Next();
+  };
+  m_lines.Clear();
+  m_current = NULL;
+  m_columns.Clear();
+};
+
+void wxListMainWindow::EnsureVisible( const long index )
+{
+  wxListLineData *oldCurrent = m_current;
+  m_current = NULL;
+  int i = index;
+  wxNode *node = m_lines.Nth( i );
+  if (node) m_current = (wxListLineData*)node->Data();
+  if (m_current) MoveToFocus();
+  m_current = oldCurrent;
+};
+
+long wxListMainWindow::FindItem(const long start, const wxString& str, const bool WXUNUSED(partial) )
+{
+  long pos = start;
+  wxString tmp = str;
+  if (pos < 0) pos = 0;
+  wxNode *node = m_lines.Nth( pos );
+  while (node)
+  {
+    wxListLineData *line = (wxListLineData*)node->Data();
+    wxString s = "";
+    line->GetText( 0, s );
+    if (s == tmp) return pos;
+    node = node->Next();
+    pos++;
+  };
+  return -1;
+};
+
+long wxListMainWindow::FindItem(const long start, const long data)
+{
+  long pos = start;
+  if (pos < 0) pos = 0;
+  wxNode *node = m_lines.Nth( pos );
+  while (node)
+  {
+    wxListLineData *line = (wxListLineData*)node->Data();
+    wxListItem item;
+    line->GetItem( 0, item );
+    if (item.m_data == data) return pos;
+    node = node->Next();
+    pos++;
+  };
+  return -1;
+};
+
+long wxListMainWindow::HitTest( const int x, const int y, int &flags )
+{
+  wxNode *node = m_lines.First();
+  int count = 0;
+  while (node)
+  {
+    wxListLineData *line = (wxListLineData*)node->Data();
+    long ret = line->IsHit( x, y );
+    if (ret & flags)
+    {
+      flags = ret;
+      return count;
+    };
+    node = node->Next();
+    count++;
+  };
+  return -1;
+};
+
+void wxListMainWindow::InsertItem( wxListItem &item )
+{
+  m_dirty = TRUE;
+  int mode = 0;
+  if (m_mode & wxLC_REPORT) mode = wxLC_REPORT;
+  else if (m_mode & wxLC_LIST) mode = wxLC_LIST;
+  else if (m_mode & wxLC_ICON) mode = wxLC_ICON;
+  else if (m_mode & wxLC_SMALL_ICON) mode = wxLC_ICON;  // no typo
+  wxListLineData *line = new wxListLineData( this, mode, m_hilightBrush );
+  if (m_mode & wxLC_REPORT)
+  {
+    line->InitItems( GetColumnCount() );
+    item.m_width = GetColumnWidth( 0 )-3;
+  }
+  else 
+    line->InitItems( 1 );
+  line->SetItem( 0, item );
+  wxNode *node = m_lines.Nth( item.m_itemId );
+  if (node)
+    m_lines.Insert( node, line );
+  else
+    m_lines.Append( line );
+};
+
+void wxListMainWindow::InsertColumn( const long col, wxListItem &item )
+{
+  m_dirty = TRUE;
+  if (m_mode & wxLC_REPORT)
+  {
+    if (item.m_width == wxLIST_AUTOSIZE_USEHEADER) item.m_width = GetTextLength( item.m_text );
+    wxListHeaderData *column = new wxListHeaderData( item );
+    wxNode *node = m_columns.Nth( col );
+    if (node)
+      m_columns.Insert( node, column );
+    else
+      m_columns.Append( column );
+  };
+};
+
+wxListCtrlCompare list_ctrl_compare_func_2;
+long              list_ctrl_compare_data;
+
+int list_ctrl_compare_func_1( const void *arg1, const void *arg2 )
+{
+  wxListLineData *line1 = *((wxListLineData**)arg1);
+  wxListLineData *line2 = *((wxListLineData**)arg2);
+  wxListItem item;
+  line1->GetItem( 0, item );
+  long data1 = item.m_data;
+  line2->GetItem( 0, item );
+  long data2 = item.m_data;
+  return list_ctrl_compare_func_2( data1, data2, list_ctrl_compare_data );
+};
+
+void wxListMainWindow::SortItems( wxListCtrlCompare fn, long data )
+{
+  list_ctrl_compare_func_2 = fn;
+  list_ctrl_compare_data = data;
+  m_lines.Sort( list_ctrl_compare_func_1 );
+};
+
+bool wxListMainWindow::OnListNotify( wxListEvent &event )
+{
+  if (m_parent) m_parent->ProcessEvent( event );
+  return FALSE;
+};
+
+// -------------------------------------------------------------------------------------
+// wxListItem
+// -------------------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxListItem, wxObject)
+
+wxListItem::wxListItem(void)
+{
+  m_mask = 0;
+  m_itemId = 0;
+  m_col = 0;
+  m_state = 0;
+  m_stateMask = 0;
+  m_image = 0;
+  m_data = 0;
+  m_format = wxLIST_FORMAT_CENTRE;
+  m_width = 0;
+  m_colour = wxBLACK;
+}
+
+// -------------------------------------------------------------------------------------
+// wxListEvent
+// -------------------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxListEvent, wxCommandEvent)
+
+wxListEvent::wxListEvent( WXTYPE commandType, int id ):
+  wxCommandEvent( commandType, id )
+{
+  m_code = 0;
+  m_itemIndex = 0;
+  m_col = 0;
+  m_cancelled = FALSE;
+};
+
+// -------------------------------------------------------------------------------------
+// wxListCtrl
+// -------------------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxListCtrl, wxControl)
+
+BEGIN_EVENT_TABLE(wxListCtrl,wxControl)
+  EVT_SIZE          (wxListCtrl::OnSize)
+END_EVENT_TABLE()
+
+wxListCtrl::wxListCtrl(void)
+{
+  m_imageListNormal = NULL;
+  m_imageListSmall = NULL;
+  m_imageListState = NULL;
+}
+
+wxListCtrl::wxListCtrl( wxWindow *parent, const wxWindowID id, 
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+
+{
+  Create( parent, id, pos, size, style, name );
+};
+
+wxListCtrl::~wxListCtrl(void)
+{
+}
+
+bool wxListCtrl::Create( wxWindow *parent, const wxWindowID id, 
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  m_imageListNormal = NULL;
+  m_imageListSmall = NULL;
+  m_imageListState = NULL;
+  
+  long s = style;
+  
+  if ((s & wxLC_REPORT == 0) &&
+      (s & wxLC_LIST == 0) &&
+      (s & wxLC_ICON == 0))
+    s = s | wxLC_LIST;
+  
+  bool ret = wxControl::Create( parent, id, pos, size, s, name );
+  
+  m_mainWin = new wxListMainWindow( this, -1, wxPoint(0,0), size, s );
+  
+  if (GetWindowStyleFlag() & wxLC_REPORT)
+    m_headerWin = new wxListHeaderWindow( this, -1, m_mainWin, wxPoint(0,0), wxSize(size.x,23) );
+  else
+    m_headerWin = NULL;
+  
+  return ret;
+};
+
+void wxListCtrl::OnSize( wxSizeEvent &WXUNUSED(event) )
+{
+  RealizeChanges();
+/*
+  wxWindow::OnSize( event );
+
+  int cw = 0;
+  int ch = 0;
+  GetClientSize( &cw, &ch );
+  
+  if (GetWindowStyleFlag() & wxLC_REPORT)
+  {
+    m_headerWin->SetSize( 0, 0, cw, 23 );
+    m_mainWin->SetSize( 0, 24, cw, ch-24 );
+  }
+  else
+  {
+    m_mainWin->SetSize( 0, 0, cw, ch );
+  };
+*/
+};
+
+void wxListCtrl::SetSingleStyle( const long style, const bool add )
+{
+  long flag = GetWindowStyleFlag();
+  
+  if (add)
+  {
+    if (style & wxLC_MASK_TYPE)	flag = flag & ~wxLC_MASK_TYPE;
+    if (style & wxLC_MASK_ALIGN) flag = flag & ~wxLC_MASK_ALIGN;
+    if (style & wxLC_MASK_SORT) flag = flag & ~wxLC_MASK_SORT;
+  };
+
+  if (add)
+  {
+    flag |= style;
+  }
+  else
+  {
+    if (flag & style) flag -= style;
+  };
+  
+  SetWindowStyleFlag( flag );
+};
+
+void wxListCtrl::SetWindowStyleFlag( const long flag )
+{
+  m_mainWin->DeleteEverything();
+
+  int width = 0;
+  int height = 0;
+  GetClientSize( &width, &height );
+
+  m_mainWin->SetMode( flag );
+  
+  if (flag & wxLC_REPORT)
+  {
+    if (!(GetWindowStyleFlag() & wxLC_REPORT))
+    {
+//      m_mainWin->SetSize( 0, 24, width, height-24 );
+      if (!m_headerWin)
+      {
+        m_headerWin = new wxListHeaderWindow( this, -1, m_mainWin, wxPoint(0,0), wxSize(width,23) );
+      }
+      else
+      {
+//        m_headerWin->SetSize( 0, 0, width, 23 );
+        m_headerWin->Show( TRUE );
+      };
+    };
+  }
+  else
+  {
+    if (GetWindowStyleFlag() & wxLC_REPORT)
+    {
+//      m_mainWin->SetSize( 0, 0, width, height );
+      m_headerWin->Show( FALSE );
+    };
+  };   
+  
+  wxWindow::SetWindowStyleFlag( flag );
+};
+
+void wxListCtrl::RealizeChanges( void )
+{ 
+  m_mainWin->m_dirty = TRUE;
+
+  int cw = 0;
+  int ch = 0;
+  GetClientSize( &cw, &ch );
+  
+  int x = 0;
+  int y = 0;
+  int w = 0;
+  int h = 0;
+  
+  if (GetWindowStyleFlag() & wxLC_REPORT)
+  {
+    m_headerWin->GetPosition( &x, &y );
+    m_headerWin->GetSize( &w, &h );
+    if ((x != 0) || (y != 0) || (w != cw) || (h != 23))
+      m_headerWin->SetSize( 0, 0, cw, 23 );
+      
+    m_mainWin->GetPosition( &x, &y );
+    m_mainWin->GetSize( &w, &h );
+    if ((x != 0) || (y != 24) || (w != cw) || (h != ch-24))
+      m_mainWin->SetSize( 0, 24, cw, ch-24 );
+  }
+  else
+  {
+    m_mainWin->GetPosition( &x, &y );
+    m_mainWin->GetSize( &w, &h );
+    if ((x != 0) || (y != 24) || (w != cw) || (h != ch))
+      m_mainWin->SetSize( 0, 0, cw, ch );
+  };
+  
+  m_mainWin->CalculatePositions();
+  m_mainWin->RealizeChanges();
+  m_mainWin->m_dirty = FALSE;
+  m_mainWin->Refresh();
+};
+
+void wxListCtrl::SetBackgroundColour(const wxColour& col)
+{
+  // This is from Julian. You know.
+  // Not in wxWin 1.xx ???
+  wxWindow::SetBackgroundColour( (wxColour&)col );
+};
+
+bool wxListCtrl::GetColumn(const int col, wxListItem &item) 
+{
+  m_mainWin->GetColumn( col, item );
+  return TRUE;
+};
+
+bool wxListCtrl::SetColumn( const int col, wxListItem& item )
+{
+  m_mainWin->SetColumn( col, item );
+  return TRUE;
+};
+
+int wxListCtrl::GetColumnWidth( const int col ) 
+{
+  return m_mainWin->GetColumnWidth( col );
+};
+
+bool wxListCtrl::SetColumnWidth( const int col, const int width )
+{
+  m_mainWin->SetColumnWidth( col, width );
+  return TRUE;
+};
+
+int wxListCtrl::GetCountPerPage(void) 
+{
+  return m_mainWin->GetCountPerPage();  // different from Windows ?
+};
+
+/*
+wxText& wxListCtrl::GetEditControl(void) const
+{
+};
+*/
+
+bool wxListCtrl::GetItem( wxListItem &info ) 
+{
+  m_mainWin->GetItem( info );
+  return TRUE;
+};
+
+bool wxListCtrl::SetItem( wxListItem &info )
+{
+  m_mainWin->SetItem( info );
+  return TRUE;
+};
+
+long wxListCtrl::SetItem( const long index, const int col, const wxString& label, const int imageId )
+{
+  wxListItem info;
+  info.m_text = label;
+  info.m_mask = wxLIST_MASK_TEXT;
+  info.m_itemId = index;
+  info.m_col = col;
+  if ( imageId > -1 )
+  {
+    info.m_image = imageId;
+    info.m_mask |= wxLIST_MASK_IMAGE;
+  }
+;
+  m_mainWin->SetItem(info);
+  return TRUE;
+};
+
+int wxListCtrl::GetItemState( const long item, const long stateMask )
+{
+  return m_mainWin->GetItemState( item, stateMask );  
+};
+
+bool wxListCtrl::SetItemState( const long item, const long state, const long stateMask )
+{
+  m_mainWin->SetItemState( item, state, stateMask );
+  return TRUE;
+};
+
+bool wxListCtrl::SetItemImage( const long item, const int image, const int WXUNUSED(selImage) )
+{
+  wxListItem info;
+  info.m_image = image;
+  info.m_mask = wxLIST_MASK_IMAGE;
+  info.m_itemId = item;
+  m_mainWin->SetItem( info );
+  return TRUE;
+};
+
+wxString wxListCtrl::GetItemText( const long item ) 
+{
+  wxListItem info;
+  info.m_itemId = item;
+  m_mainWin->GetItem( info );
+  return info.m_text;
+};
+
+void wxListCtrl::SetItemText( const long item, const wxString &str )
+{
+  wxListItem info;
+  info.m_mask = wxLIST_MASK_TEXT;
+  info.m_itemId = item;
+  info.m_text = str;
+  m_mainWin->SetItem( info );
+};
+
+long wxListCtrl::GetItemData( const long item )
+{
+  wxListItem info;
+  info.m_itemId = item;
+  m_mainWin->GetItem( info );
+  return info.m_data;
+};
+
+bool wxListCtrl::SetItemData( const long item, long data )
+{
+  wxListItem info;
+  info.m_mask = wxLIST_MASK_DATA;
+  info.m_itemId = item;
+  info.m_data = data;
+  m_mainWin->SetItem( info );
+  return TRUE;
+};
+
+bool wxListCtrl::GetItemRect( const long item, wxRectangle &rect,  const int WXUNUSED(code) )
+{
+  m_mainWin->GetItemRect( item, rect );
+  return TRUE;
+};
+
+bool wxListCtrl::GetItemPosition( const long WXUNUSED(item), wxPoint& WXUNUSED(pos) ) const
+{
+  return 0;
+};
+
+bool wxListCtrl::SetItemPosition( const long WXUNUSED(item), const wxPoint& WXUNUSED(pos) )
+{
+  return 0;
+};
+
+int wxListCtrl::GetItemCount(void) 
+{
+  return m_mainWin->GetItemCount();
+};
+
+int wxListCtrl::GetItemSpacing( bool isSmall )
+{
+  return m_mainWin->GetItemSpacing( isSmall );
+};
+
+int wxListCtrl::GetSelectedItemCount(void) 
+{
+  return m_mainWin->GetSelectedItemCount();
+};
+
+/*
+wxColour wxListCtrl::GetTextColour(void) const
+{
+};
+
+void wxListCtrl::SetTextColour(const wxColour& WXUNUSED(col))
+{
+};
+*/
+
+long wxListCtrl::GetTopItem(void)
+{
+  return 0;
+};
+
+long wxListCtrl::GetNextItem( const long item, int geom, int state )
+{
+  return m_mainWin->GetNextItem( item, geom, state );
+};
+
+wxImageList *wxListCtrl::GetImageList(const int which)
+{
+  if (which == wxIMAGE_LIST_NORMAL)
+  {
+    return m_imageListNormal;
+  }
+  else if (which == wxIMAGE_LIST_SMALL)
+  {
+    return m_imageListSmall;
+  }
+  else if (which == wxIMAGE_LIST_STATE)
+  {
+    return m_imageListState;
+  };
+  return NULL;
+};
+
+void wxListCtrl::SetImageList( wxImageList *imageList, const int which )
+{
+  m_mainWin->SetImageList( imageList, which );
+};
+
+bool wxListCtrl::Arrange( const int WXUNUSED(flag) )
+{
+  return 0;
+};
+
+bool wxListCtrl::DeleteItem( const long item )
+{
+  m_mainWin->DeleteItem( item );
+  return TRUE;
+};
+
+bool wxListCtrl::DeleteAllItems(void)
+{
+  m_mainWin->DeleteAllItems();
+  return TRUE;
+};
+
+bool wxListCtrl::DeleteColumn( const int col )
+{
+  m_mainWin->DeleteColumn( col );
+  return TRUE;
+};
+
+/*
+wxText& wxListCtrl::Edit( const long WXUNUSED(item ) )
+{
+};
+*/
+
+bool wxListCtrl::EnsureVisible( const long item )
+{
+  m_mainWin->EnsureVisible( item );
+  return TRUE;
+};
+
+long wxListCtrl::FindItem( const long start, const wxString& str,  const bool partial )
+{
+  return m_mainWin->FindItem( start, str, partial );
+};
+
+long wxListCtrl::FindItem( const long start, const long data )
+{
+  return m_mainWin->FindItem( start, data );
+};
+
+long wxListCtrl::FindItem( const long WXUNUSED(start), const wxPoint& WXUNUSED(pt), 
+                           const int WXUNUSED(direction)) 
+{
+  return 0;
+};
+
+long wxListCtrl::HitTest( const wxPoint &point, int &flags )
+{
+  return m_mainWin->HitTest( (int)point.x, (int)point.y, flags );
+};
+
+long wxListCtrl::InsertItem( wxListItem& info )
+{
+  m_mainWin->InsertItem( info );
+  return 0;
+};
+
+long wxListCtrl::InsertItem( const long index, const wxString &label )
+{
+  wxListItem info;
+  info.m_text = label;
+  info.m_mask = wxLIST_MASK_TEXT;
+  info.m_itemId = index;
+  return InsertItem( info );
+};
+
+long wxListCtrl::InsertItem( const long index, const int imageIndex )
+{
+  wxListItem info;
+  info.m_mask = wxLIST_MASK_IMAGE;
+  info.m_image = imageIndex;
+  info.m_itemId = index;
+  return InsertItem( info );
+};
+
+long wxListCtrl::InsertItem( const long index, const wxString &label, const int imageIndex )
+{
+  wxListItem info;
+  info.m_text = label;
+  info.m_image = imageIndex;
+  info.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_IMAGE;
+  info.m_itemId = index;
+  return InsertItem( info );
+};
+
+long wxListCtrl::InsertColumn( const long col, wxListItem &item )
+{
+  m_mainWin->InsertColumn( col, item );
+  return 0;
+};
+
+long wxListCtrl::InsertColumn( const long col, const wxString &heading,
+                               const int format, const int width )
+{
+  wxListItem item;
+  item.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_FORMAT;
+  item.m_text = heading;
+  if (width >= -2)
+  {
+    item.m_mask |= wxLIST_MASK_WIDTH;
+    item.m_width = width;
+  }
+;
+  item.m_format = format;
+
+  return InsertColumn( col, item );
+};
+
+bool wxListCtrl::ScrollList( const int WXUNUSED(dx), const int WXUNUSED(dy) )
+{
+  return 0;
+};
+
+// Sort items.
+// fn is a function which takes 3 long arguments: item1, item2, data.
+// item1 is the long data associated with a first item (NOT the index).
+// item2 is the long data associated with a second item (NOT the index).
+// data is the same value as passed to SortItems.
+// The return value is a negative number if the first item should precede the second
+// item, a positive number of the second item should precede the first,
+// or zero if the two items are equivalent.
+// data is arbitrary data to be passed to the sort function.
+
+bool wxListCtrl::SortItems( wxListCtrlCompare fn, long data )
+{
+  m_mainWin->SortItems( fn, data );
+  return TRUE;
+};
+
+
diff --git a/src/generic/msgdlgg.cpp b/src/generic/msgdlgg.cpp
new file mode 100644
index 0000000000..c277d899e6
--- /dev/null
+++ b/src/generic/msgdlgg.cpp
@@ -0,0 +1,201 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        msgdlgg.cpp
+// Purpose:     wxGenericMessageDialog
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "msgdlgg.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/utils.h"
+#include "wx/dialog.h"
+#include "wx/listbox.h"
+#include "wx/button.h"
+#include "wx/stattext.h"
+#include "wx/layout.h"
+#include "wx/intl.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "wx/generic/msgdlgg.h"
+
+///////////////////////////////////////////////////////////////////
+// New dialog box implementations
+
+// Split message, using constraints to position controls
+void wxSplitMessage2(const char *message, wxList *messageList, wxWindow *parent, wxRowColSizer *sizer)
+{
+  char *copyMessage = copystring(message);
+  size_t i = 0;
+  size_t len = strlen(copyMessage);
+  char *currentMessage = copyMessage;
+
+//  wxWindow *lastWindow = parent;
+
+  while (i < len) {
+    while ((i < len) && (copyMessage[i] != '\n')) i++;
+    if (i < len) copyMessage[i] = 0;
+    wxStaticText *mess = new wxStaticText(parent, -1, currentMessage);
+
+/*
+  	wxLayoutConstraints *c = new wxLayoutConstraints;
+  	c->left.SameAs       	(parent, wxLeft, 10);
+  	c->top.SameAs        	(lastWindow, wxBottom, 5);
+  	c->right.AsIs      		();
+  	c->height.AsIs			();
+
+  	mess->SetConstraints(c);
+*/
+	sizer->AddSizerChild(mess);
+
+    messageList->Append(mess);
+
+    currentMessage = copyMessage + i + 1;
+  }
+  delete[] copyMessage;
+}
+
+#if !USE_SHARED_LIBRARY
+BEGIN_EVENT_TABLE(wxGenericMessageDialog, wxDialog)
+	EVT_BUTTON(wxID_YES, wxGenericMessageDialog::OnYes)
+	EVT_BUTTON(wxID_NO, wxGenericMessageDialog::OnNo)
+	EVT_BUTTON(wxID_CANCEL, wxGenericMessageDialog::OnCancel)
+END_EVENT_TABLE()
+
+IMPLEMENT_CLASS(wxGenericMessageDialog, wxDialog)
+#endif
+
+wxGenericMessageDialog::wxGenericMessageDialog(wxWindow *parent, const wxString& message, const wxString& caption,
+        long style, const wxPoint& pos):
+	wxDialog(parent, -1, caption, pos, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxDIALOG_MODAL)
+{
+	m_dialogStyle = style;
+
+	wxBeginBusyCursor();
+
+	wxSizer *topSizer = new wxSizer(this, wxSizerShrink);
+	topSizer->SetBorder(10, 10);
+
+	wxRowColSizer *messageSizer = new wxRowColSizer(topSizer, wxSIZER_COLS, 100);
+	messageSizer->SetName("messageSizer");
+
+//    bool centre = ((style & wxCENTRE) == wxCENTRE);
+
+	wxList messageList;
+	wxSplitMessage2(message, &messageList, this, messageSizer);
+
+	// Insert a spacer
+	wxSpacingSizer *spacingSizer = new wxSpacingSizer(topSizer, wxBelow, messageSizer, 20);
+
+	wxRowColSizer *buttonSizer = new wxRowColSizer(topSizer, wxSIZER_ROWS);
+	buttonSizer->SetName("buttonSizer");
+
+  	// Specify constraints for the button sizer
+  	wxLayoutConstraints *c = new wxLayoutConstraints;
+  	c->width.AsIs		();
+  	c->height.AsIs		();
+	c->top.Below		(spacingSizer);
+	c->centreX.SameAs	(spacingSizer, wxCentreX);
+  	buttonSizer->SetConstraints(c);
+
+    wxButton *ok = NULL;
+  	wxButton *cancel = NULL;
+  	wxButton *yes = NULL;
+  	wxButton *no = NULL;
+
+  	if (style & wxYES_NO) {
+    yes = new wxButton(this, wxID_YES, _("Yes"));
+    no = new wxButton(this, wxID_NO, _("No"));
+
+	buttonSizer->AddSizerChild(yes);
+	buttonSizer->AddSizerChild(no);
+  }
+
+  if (style & wxOK) {
+    ok = new wxButton(this, wxID_OK, _("OK"));
+	buttonSizer->AddSizerChild(ok);
+  }
+
+  if (style & wxCANCEL) {
+    cancel = new wxButton(this, wxID_CANCEL, _("Cancel"));
+	buttonSizer->AddSizerChild(cancel);
+  }
+
+  if (ok)
+  {
+    ok->SetDefault();
+    ok->SetFocus();
+  }
+  else if (yes)
+  {
+    yes->SetDefault();
+    yes->SetFocus();
+  }
+
+	Layout();
+    Centre(wxBOTH);
+
+	wxEndBusyCursor();
+}
+
+void wxGenericMessageDialog::OnYes(wxCommandEvent& WXUNUSED(event))
+{
+	EndModal(wxID_YES);
+}
+
+void wxGenericMessageDialog::OnNo(wxCommandEvent& WXUNUSED(event))
+{
+	EndModal(wxID_NO);
+}
+
+void wxGenericMessageDialog::OnCancel(wxCommandEvent& WXUNUSED(event))
+{
+	// Allow cancellation via ESC/Close button except if
+	// only YES and NO are specified.
+	if ( (m_dialogStyle & wxYES_NO) != wxYES_NO || (m_dialogStyle & wxCANCEL) )
+		EndModal(wxID_CANCEL);
+}
+
+
+int wxMessageBox(const wxString& message, const wxString& caption, const long style,
+                 wxWindow *parent, const int WXUNUSED(x), const int WXUNUSED(y) )
+{
+	wxMessageDialog dialog(parent, message, caption, style);
+
+	int ans = dialog.ShowModal();
+	switch ( ans )
+	{
+		case wxID_OK:
+			return wxOK;
+			break;
+		case wxID_YES:
+			return wxYES;
+			break;
+		case wxID_NO:
+			return wxNO;
+			break;
+		default:
+		case wxID_CANCEL:
+			return wxCANCEL;
+			break;
+	}
+
+	return ans;
+}
+
diff --git a/src/generic/panelg.cpp b/src/generic/panelg.cpp
new file mode 100644
index 0000000000..f10285fe46
--- /dev/null
+++ b/src/generic/panelg.cpp
@@ -0,0 +1,82 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        panelg.cpp
+// Purpose:     wxPanel
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "panelg.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/settings.h"
+#endif
+
+#include "wx/generic/panelg.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxPanel, wxWindow)
+
+BEGIN_EVENT_TABLE(wxPanel, wxWindow)
+  EVT_SYS_COLOUR_CHANGED(wxPanel::OnSysColourChanged)
+END_EVENT_TABLE()
+
+#endif
+
+wxPanel::wxPanel(void)
+{
+  SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
+  SetDefaultBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
+}
+
+bool wxPanel::Create(wxWindow *parent, const wxWindowID id,
+           const wxPoint& pos,
+           const wxSize& size,
+           const long style,
+           const wxString& name)
+{
+  bool ret = wxWindow::Create(parent, id, pos, size, style, name);
+
+  SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
+  SetDefaultBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
+  SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT));
+  return ret;
+}
+
+void wxPanel::OnPaint(wxPaintEvent& WXUNUSED(event))
+{
+	// No: if you call the default procedure, it makes
+	// the following painting code not work.
+//	wxWindow::OnPaint(event);
+}
+
+void wxPanel::InitDialog(void)
+{
+ 	wxInitDialogEvent event(GetId());
+ 	event.SetEventObject(this);
+ 	GetEventHandler()->ProcessEvent(event);
+}
+
+// Responds to colour changes, and passes event on to children.
+void wxPanel::OnSysColourChanged(wxSysColourChangedEvent& event)
+{
+    SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
+    SetDefaultBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
+    Refresh();
+
+    // Propagate the event to the non-top-level children
+    wxWindow::OnSysColourChanged(event);
+}
+
diff --git a/src/generic/printps.cpp b/src/generic/printps.cpp
new file mode 100644
index 0000000000..0a80f46a40
--- /dev/null
+++ b/src/generic/printps.cpp
@@ -0,0 +1,264 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        printps.cpp
+// Purpose:     Postscript print/preview framework
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "printps.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#include "wx/defs.h"
+
+#ifndef WX_PRECOMP
+#include "wx/utils.h"
+#include "wx/dc.h"
+#include "wx/app.h"
+#include "wx/msgdlg.h"
+#endif
+
+#include "wx/generic/printps.h"
+#include "wx/dcprint.h"
+#include "wx/printdlg.h"
+#include "wx/generic/prntdlgg.h"
+
+#include <stdlib.h>
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxPostScriptPrinter, wxPrinterBase)
+IMPLEMENT_CLASS(wxPostScriptPrintPreview, wxPrintPreviewBase)
+#endif
+
+/*
+ * Printer
+ */
+ 
+wxPostScriptPrinter::wxPostScriptPrinter(wxPrintData *data):
+    wxPrinterBase(data)
+{
+}
+
+wxPostScriptPrinter::~wxPostScriptPrinter(void)
+{
+}
+
+bool wxPostScriptPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt)
+{
+  abortIt = FALSE;
+  abortWindow = NULL;
+
+  if (!printout)
+    return FALSE;
+    
+  printout->SetIsPreview(FALSE);
+  printout->OnPreparePrinting();
+
+  // Get some parameters from the printout, if defined
+  int fromPage, toPage;
+  int minPage, maxPage;
+  printout->GetPageInfo(&minPage, &maxPage, &fromPage, &toPage);
+
+  if (maxPage == 0)
+    return FALSE;
+
+  printData.SetMinPage(minPage);
+  printData.SetMaxPage(maxPage);
+  if (fromPage != 0)
+    printData.SetFromPage(fromPage);
+  if (toPage != 0)
+    printData.SetToPage(toPage);
+
+  if (minPage != 0)
+  {
+    printData.EnablePageNumbers(TRUE);
+    if (printData.GetFromPage() < printData.GetMinPage())
+      printData.SetFromPage(printData.GetMinPage());
+    else if (printData.GetFromPage() > printData.GetMaxPage())
+      printData.SetFromPage(printData.GetMaxPage());
+    if (printData.GetToPage() > printData.GetMaxPage())
+      printData.SetToPage(printData.GetMaxPage());
+    else if (printData.GetToPage() < printData.GetMinPage())
+      printData.SetToPage(printData.GetMinPage());
+  }
+  else
+    printData.EnablePageNumbers(FALSE);
+  
+  // Create a suitable device context  
+  wxDC *dc = NULL;
+  if (prompt)
+  {
+     wxGenericPrintDialog dialog(parent, & printData);
+     if (dialog.ShowModal() == wxID_OK)
+     {
+       dc = dialog.GetPrintDC();
+       printData = dialog.GetPrintData();
+     }
+  }
+  else
+  {
+     dc = new wxPostScriptDC(wxThePrintSetupData->GetPrinterFile(), FALSE, NULL);
+  }
+
+  // May have pressed cancel.
+  if (!dc || !dc->Ok())
+  {
+    if (dc) delete dc;
+    return FALSE;
+  }
+  
+  int logPPIScreenX = 0;
+  int logPPIScreenY = 0;
+  int logPPIPrinterX = 0;
+  int logPPIPrinterY = 0;
+
+  // Correct values for X/PostScript?
+  logPPIScreenX = 100;
+  logPPIScreenY = 100;
+  logPPIPrinterX = 100;
+  logPPIPrinterY = 100;
+
+  printout->SetPPIScreen(logPPIScreenX, logPPIScreenY);
+  printout->SetPPIPrinter(logPPIPrinterX, logPPIPrinterY);
+
+  // Set printout parameters  
+  printout->SetDC(dc);
+
+  int w, h;
+  long ww, hh;
+  dc->GetSize(&w, &h);
+  printout->SetPageSizePixels((int)w, (int)h);
+  dc->GetSizeMM(&ww, &hh);
+  printout->SetPageSizeMM((int)ww, (int)hh);
+
+  // Create an abort window
+  wxBeginBusyCursor();
+
+  printout->OnBeginPrinting();
+  
+  bool keepGoing = TRUE;
+
+  int copyCount;
+  for (copyCount = 1; copyCount <= printData.GetNoCopies(); copyCount ++)
+  {
+    if (!printout->OnBeginDocument(printData.GetFromPage(), printData.GetToPage()))
+    {
+      wxEndBusyCursor();
+      wxMessageBox("Could not start printing.", "Print Error", wxOK, parent);
+      break;
+    }
+    if (abortIt)
+      break;
+
+    int pn;
+    for (pn = printData.GetFromPage(); keepGoing && (pn <= printData.GetToPage()) && printout->HasPage(pn);
+         pn++)
+    {
+      if (abortIt)
+      {
+        keepGoing = FALSE;
+        break;
+      }
+      else
+      {
+        dc->StartPage();
+        printout->OnPrintPage(pn);
+        dc->EndPage();
+      }
+    }
+    printout->OnEndDocument();
+  }
+
+  printout->OnEndPrinting();
+
+  wxEndBusyCursor();
+
+  delete dc;
+  
+  return TRUE;
+}
+
+bool wxPostScriptPrinter::PrintDialog(wxWindow *parent)
+{
+    wxGenericPrintDialog dialog(parent, & printData);
+    return (dialog.ShowModal() == wxID_OK);
+}
+
+bool wxPostScriptPrinter::Setup(wxWindow *parent)
+{
+    wxGenericPrintDialog dialog(parent, & printData);
+    dialog.GetPrintData().SetSetupDialog(TRUE);
+    return (dialog.ShowModal() == wxID_OK);
+}
+
+/*
+ * Print preview
+ */
+
+wxPostScriptPrintPreview::wxPostScriptPrintPreview(wxPrintout *printout, wxPrintout *printoutForPrinting, wxPrintData *data):
+  wxPrintPreviewBase(printout, printoutForPrinting, data)
+{
+  // Have to call it here since base constructor can't call it
+  DetermineScaling();
+}
+
+wxPostScriptPrintPreview::~wxPostScriptPrintPreview(void)
+{
+}
+
+bool wxPostScriptPrintPreview::Print(bool interactive)
+{
+  if (!printPrintout)
+    return FALSE;
+  wxPostScriptPrinter printer(&printData);
+  return printer.Print(previewFrame, printPrintout, interactive);
+}
+
+void wxPostScriptPrintPreview::DetermineScaling(void)
+{
+    char *paperType = wxThePrintSetupData->GetPaperName();
+    if (!paperType)
+      paperType = "A4 210 x 297 mm";
+
+    wxPrintPaperType *paper = wxThePrintPaperDatabase->FindPaperType(paperType);
+    if (!paper)
+      paper = wxThePrintPaperDatabase->FindPaperType("A4 210 x 297 mm");
+    if (paper)
+    {
+      previewPrintout->SetPPIScreen(100, 100);
+      previewPrintout->SetPPIPrinter(100, 100);
+
+      // If in landscape mode, we need to swap the width and height.
+      if ( printData.GetOrientation() == wxLANDSCAPE )
+      {
+        pageWidth = paper->heightPixels;
+        pageHeight = paper->widthPixels;
+        previewPrintout->SetPageSizeMM(paper->heightMM, paper->widthMM);
+        previewPrintout->SetPageSizePixels(paper->heightPixels, paper->widthPixels);
+      }
+      else
+      {
+        pageWidth = paper->widthPixels;
+        pageHeight = paper->heightPixels;
+        previewPrintout->SetPageSizeMM(paper->widthMM, paper->heightMM);
+        previewPrintout->SetPageSizePixels(paper->widthPixels, paper->heightPixels);
+      }
+
+      // At 100%, the page should look about page-size on the screen.
+      previewScale = (float)0.8;
+//      previewScale = (float)((float)screenWidth/(float)printerWidth);
+//      previewScale = previewScale * (float)((float)screenXRes/(float)printerYRes);
+    }
+}
+
diff --git a/src/generic/prntdlgg.cpp b/src/generic/prntdlgg.cpp
new file mode 100644
index 0000000000..cfbd632c42
--- /dev/null
+++ b/src/generic/prntdlgg.cpp
@@ -0,0 +1,610 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        prntdlgg.cpp
+// Purpose:     Generic print dialogs
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "prntdlgg.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#include "wx/defs.h"
+
+#define WINDOWS_PRINTING    (wxTheApp->GetPrintMode() == wxPRINT_WINDOWS)
+
+#ifndef WX_PRECOMP
+#include "wx/utils.h"
+#include "wx/dc.h"
+#include "wx/app.h"
+#include "wx/frame.h"
+#include "wx/stattext.h"
+#include "wx/button.h"
+#include "wx/checkbox.h"
+#include "wx/textctrl.h"
+#include "wx/radiobox.h"
+#include "wx/filedlg.h"
+#include "wx/choice.h"
+#endif
+
+#include "wx/generic/prntdlgg.h"
+#include "wx/printdlg.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_CLASS(wxGenericPrintDialog, wxDialog)
+IMPLEMENT_CLASS(wxGenericPrintSetupDialog, wxDialog)
+IMPLEMENT_CLASS(wxGenericPageSetupDialog, wxDialog)
+
+BEGIN_EVENT_TABLE(wxGenericPrintDialog, wxDialog)
+    EVT_BUTTON(wxID_OK, wxGenericPrintDialog::OnOK)
+    EVT_BUTTON(wxPRINTID_SETUP, wxGenericPrintDialog::OnSetup)
+    EVT_RADIOBOX(wxPRINTID_RANGE, wxGenericPrintDialog::OnRange)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxGenericPageSetupDialog, wxDialog)
+    EVT_BUTTON(wxPRINTID_SETUP, wxGenericPageSetupDialog::OnPrinter)
+END_EVENT_TABLE()
+#endif
+
+extern wxPrintPaperDatabase *wxThePrintPaperDatabase;
+
+/*
+ * Generic print dialog for non-Windows printing use.
+ */
+
+
+wxGenericPrintDialog::wxGenericPrintDialog(wxWindow *parent, wxPrintData* data):
+  wxDialog(parent, -1, "Print", wxPoint(0, 0), wxSize(600, 600), wxDEFAULT_DIALOG_STYLE|wxDIALOG_MODAL)
+{
+  if ( data )
+    printData = *data;
+
+  int buttonWidth = 65;
+  int buttonHeight = 25;
+  int spacing = 5;
+  int yPos = 5;
+  int xPos = 5;
+
+  wxButton *okButton = new wxButton(this, wxID_OK, "OK", wxPoint(5, yPos), wxSize(buttonWidth, buttonHeight));
+  (void) new wxButton(this, wxID_CANCEL, "Cancel", wxPoint(buttonWidth + 5 + spacing, yPos), wxSize(buttonWidth, buttonHeight));
+
+  setupButton = new wxButton(this, wxPRINTID_SETUP, "Setup...", wxPoint(buttonWidth*2 + 5 + 2*spacing, yPos), wxSize(buttonWidth, buttonHeight));
+
+  okButton->SetDefault();
+  okButton->SetFocus();
+
+  yPos += 35;
+
+  wxString choices[2];
+  choices[0] = "All";
+  choices[1] = "Pages";
+
+  rangeRadioBox = new wxRadioBox(this, wxPRINTID_RANGE, "Print Range",
+    wxPoint(5, yPos), wxSize(-1, -1), 2, choices, 2);
+  rangeRadioBox->SetSelection(1);
+
+  yPos += 60;
+  xPos = 5;
+  int staticWidth = 45;
+  int textWidth = 40;
+  spacing = 10;
+
+  (void) new wxStaticText(this, wxPRINTID_STATIC, "From:", wxPoint(xPos, yPos));
+  xPos += staticWidth;
+
+  fromText = new wxTextCtrl(this, wxPRINTID_FROM, "", wxPoint(xPos, yPos), wxSize(textWidth, -1));
+  xPos += spacing + textWidth;
+
+  (void) new wxStaticText(this, wxPRINTID_STATIC, "To:", wxPoint(xPos, yPos));
+  xPos += staticWidth;
+
+  toText = new wxTextCtrl(this, wxPRINTID_TO, "", wxPoint(xPos, yPos), wxSize(textWidth, -1));
+  xPos += spacing + textWidth;
+
+  (void) new wxStaticText(this, wxPRINTID_STATIC, "Copies:", wxPoint(xPos, yPos));
+  xPos += spacing + staticWidth;
+
+  noCopiesText = new wxTextCtrl(this, wxPRINTID_COPIES, "", wxPoint(xPos, yPos), wxSize(textWidth, -1));
+
+  yPos += 30;
+  xPos = 5;
+
+  printToFileCheckBox = new wxCheckBox(this, wxPRINTID_PRINTTOFILE, "Print to File", wxPoint(xPos, yPos));
+
+  Fit();
+  Centre(wxBOTH);
+
+  // Calls wxWindow::OnInitDialog and then wxGenericPrintDialog::TransferDataToWindow
+  InitDialog();
+}
+
+int wxGenericPrintDialog::ShowModal(void)
+{
+    if ( printData.GetSetupDialog() )
+    {
+        wxGenericPrintSetupDialog *genericPrintSetupDialog =
+            new wxGenericPrintSetupDialog(GetParent(), wxThePrintSetupData);
+        int ret = genericPrintSetupDialog->ShowModal();
+        if ( ret != wxID_CANCEL )
+        {
+            *wxThePrintSetupData = genericPrintSetupDialog->printData;
+        }
+        genericPrintSetupDialog->Close(TRUE);
+        return ret;
+    }
+    else
+    {
+        return wxDialog::ShowModal();
+    }
+}
+
+wxGenericPrintDialog::~wxGenericPrintDialog(void)
+{
+}
+
+void wxGenericPrintDialog::OnOK(wxCommandEvent& WXUNUSED(event))
+{
+  TransferDataFromWindow();
+
+  // There are some interactions between the global setup data
+  // and the standard print dialog. The global printing 'mode'
+  // is determined by whether the user checks Print to file
+  // or not.
+  if (printData.GetPrintToFile())
+  {
+    wxThePrintSetupData->SetPrinterMode(PS_FILE);
+
+    char *f = wxFileSelector("PostScript file",
+        wxPathOnly(wxThePrintSetupData->GetPrinterFile()),
+        wxFileNameFromPath(wxThePrintSetupData->GetPrinterFile()),
+        "ps", "*.ps", 0, this);
+    if (f)
+      wxThePrintSetupData->SetPrinterFile(f);
+    else
+      return;
+  }
+  else
+    wxThePrintSetupData->SetPrinterMode(PS_PRINTER);
+  
+  EndModal(wxID_OK);
+}
+
+void wxGenericPrintDialog::OnRange(wxCommandEvent& event)
+{
+  if (event.GetInt() == 0)
+  {
+    fromText->Enable(FALSE);
+    toText->Enable(FALSE);
+  }
+  else if (event.GetInt() == 1)
+  {
+    fromText->Enable(TRUE);
+    toText->Enable(TRUE);
+  }
+}
+
+void wxGenericPrintDialog::OnSetup(wxCommandEvent& WXUNUSED(event))
+{
+  wxGenericPrintSetupDialog *genericPrintSetupDialog =
+          new wxGenericPrintSetupDialog(this, wxThePrintSetupData);
+  int ret = genericPrintSetupDialog->ShowModal();
+  if ( ret != wxID_CANCEL )
+  {
+    *wxThePrintSetupData = genericPrintSetupDialog->printData;
+    printData.SetOrientation(wxThePrintSetupData->GetPrinterOrientation());
+  }
+
+  genericPrintSetupDialog->Close(TRUE);
+}
+
+bool wxGenericPrintDialog::TransferDataToWindow(void)
+{
+  char buf[10];
+  if (printData.GetEnablePageNumbers())
+  {
+    fromText->Enable(TRUE);
+    toText->Enable(TRUE);
+
+    sprintf(buf, "%d", printData.GetFromPage());
+    fromText->SetValue(buf);
+    sprintf(buf, "%d", printData.GetToPage());
+    toText->SetValue(buf);
+
+    if (printData.GetAllPages())
+      rangeRadioBox->SetSelection(0);
+    else
+      rangeRadioBox->SetSelection(1);
+  }
+  else
+  {
+    fromText->Enable(FALSE);
+    toText->Enable(FALSE);
+    rangeRadioBox->SetSelection(0);
+    rangeRadioBox->wxRadioBox::Enable(1, FALSE);
+  }
+  sprintf(buf, "%d", printData.GetNoCopies());
+  noCopiesText->SetValue(buf);
+
+  printToFileCheckBox->SetValue(printData.GetPrintToFile());
+  printToFileCheckBox->Enable(printData.GetEnablePrintToFile());
+  return TRUE;
+}
+
+bool wxGenericPrintDialog::TransferDataFromWindow(void)
+{
+  if (printData.GetEnablePageNumbers())
+  {
+    printData.SetFromPage(atoi(fromText->GetValue()));
+    printData.SetToPage(atoi(toText->GetValue()));
+  }
+  if (rangeRadioBox->GetSelection() == 0)
+    printData.SetAllPages(TRUE);
+  else
+    printData.SetAllPages(FALSE);
+  printData.SetNoCopies(atoi(noCopiesText->GetValue()));
+  printData.SetPrintToFile(printToFileCheckBox->GetValue());
+
+  return TRUE;
+}
+
+wxDC *wxGenericPrintDialog::GetPrintDC(void)
+{
+  return new wxPostScriptDC(wxThePrintSetupData->GetPrinterFile(), FALSE, NULL);
+}
+
+/*
+ * Generic print setup dialog
+ */
+
+wxGenericPrintSetupDialog::wxGenericPrintSetupDialog(wxWindow *parent, wxPrintSetupData* data):
+  wxDialog(parent, -1, "Print Setup", wxPoint(0, 0), wxSize(600, 600), wxDEFAULT_DIALOG_STYLE|wxDIALOG_MODAL)
+{
+  if ( data )
+    printData = *data;
+
+  int buttonWidth = 65;
+  int buttonHeight = 25;
+  int spacing = 5;
+  int yPos = 5;
+  int xPos = 5;
+
+  wxButton *okButton = new wxButton(this, wxID_OK, "OK", wxPoint(xPos, yPos), wxSize(buttonWidth, buttonHeight));
+  xPos += buttonWidth + spacing;
+  (void) new wxButton(this, wxID_CANCEL, "Cancel", wxPoint(xPos, yPos), wxSize(buttonWidth, buttonHeight));
+
+  okButton->SetDefault();
+  okButton->SetFocus();
+
+  yPos += 35;
+  xPos = 5;
+
+  paperTypeChoice = CreatePaperTypeChoice(&xPos, &yPos);
+
+  wxString choices[2];
+  choices[0] = "Portrait";
+  choices[1] = "Landscape";
+
+  orientationRadioBox = new wxRadioBox(this, wxPRINTID_ORIENTATION, "Orientation",
+    wxPoint(xPos, yPos), wxSize(-1, -1), 2, choices, 2);
+  orientationRadioBox->SetSelection(0);
+
+  xPos += 200;
+
+  colourCheckBox = new wxCheckBox(this, wxPRINTID_PRINTCOLOUR, "Print in colour", wxPoint(xPos, yPos));
+
+  xPos = 5;
+  yPos += 60;
+
+  int staticWidth = 100;
+  int textWidth = 120;
+  spacing = 10;
+
+  (void) new wxStaticText(this, wxPRINTID_STATIC, "Printer command:", wxPoint(xPos, yPos));
+  xPos += staticWidth;
+
+  printerCommandText = new wxTextCtrl(this, wxPRINTID_COMMAND, "", wxPoint(xPos, yPos), wxSize(textWidth, -1));
+  xPos += textWidth + spacing;
+
+  (void) new wxStaticText(this, wxPRINTID_STATIC, "Printer options:", wxPoint(xPos, yPos));
+  xPos += staticWidth;
+
+  printerOptionsText = new wxTextCtrl(this, wxPRINTID_OPTIONS, "", wxPoint(xPos, yPos), wxSize(textWidth, -1));
+
+  Fit();
+  Centre(wxBOTH);
+
+  InitDialog();
+}
+
+wxGenericPrintSetupDialog::~wxGenericPrintSetupDialog(void)
+{
+}
+
+bool wxGenericPrintSetupDialog::TransferDataToWindow(void)
+{
+  if (printerCommandText && printData.GetPrinterCommand())
+    printerCommandText->SetValue(printData.GetPrinterCommand());
+  if (printerOptionsText && printData.GetPrinterOptions())
+    printerOptionsText->SetValue(printData.GetPrinterOptions());
+  if (colourCheckBox)
+    colourCheckBox->SetValue(printData.GetColour());
+
+  if (orientationRadioBox)
+  {
+    if (printData.GetPrinterOrientation() == PS_PORTRAIT)
+      orientationRadioBox->SetSelection(0);
+    else
+      orientationRadioBox->SetSelection(1);
+  }
+  return TRUE;
+}
+
+bool wxGenericPrintSetupDialog::TransferDataFromWindow(void)
+{
+  if (printerCommandText)
+    printData.SetPrinterCommand(WXSTRINGCAST printerCommandText->GetValue());
+  if (printerOptionsText)
+    printData.SetPrinterOptions(WXSTRINGCAST printerOptionsText->GetValue());
+  if (colourCheckBox)
+    printData.SetColour(colourCheckBox->GetValue());
+  if (orientationRadioBox)
+  {
+    int sel = orientationRadioBox->GetSelection();
+    if (sel == 0)
+      printData.SetPrinterOrientation(PS_PORTRAIT);
+    else
+      printData.SetPrinterOrientation(PS_LANDSCAPE);
+  }
+  if (paperTypeChoice)
+  {
+    wxString val(paperTypeChoice->GetStringSelection());
+    if (!val.IsNull() && val != "")
+      printData.SetPaperName((char *)(const char *)val);
+  }
+  return TRUE;
+}
+
+wxChoice *wxGenericPrintSetupDialog::CreatePaperTypeChoice(int *x, int *y)
+{
+  if (!wxThePrintPaperDatabase)
+  {
+    wxThePrintPaperDatabase = new wxPrintPaperDatabase;
+    wxThePrintPaperDatabase->CreateDatabase();
+  }
+  int n = wxThePrintPaperDatabase->Number();
+  wxString *choices = new wxString [n];
+  int sel = 0;
+  int i;
+  for (i = 0; i < n; i++)
+  {
+    wxPrintPaperType *paper = (wxPrintPaperType *)wxThePrintPaperDatabase->Nth(i)->Data();
+    choices[i] = paper->pageName;
+    if (printData.GetPaperName() && choices[i] == printData.GetPaperName())
+      sel = i;
+  }
+
+  (void) new wxStaticText(this, wxPRINTID_STATIC, "Paper size", wxPoint(*x, *y));
+  *y += 25;
+
+  wxChoice *choice = new wxChoice(this, wxPRINTID_PAPERSIZE, wxPoint(*x, *y), wxSize(300, -1), n,
+    choices);
+  *y += 35;
+  delete[] choices;
+
+  choice->SetSelection(sel);
+  return choice;
+}
+
+/*
+ * Generic page setup dialog
+ */
+
+void wxGenericPageSetupDialog::OnPrinter(wxCommandEvent& WXUNUSED(event))
+{
+  if (wxTheApp->GetPrintMode() == wxPRINT_POSTSCRIPT)
+  {
+    wxGenericPrintSetupDialog *genericPrintSetupDialog =
+          new wxGenericPrintSetupDialog(this, wxThePrintSetupData);
+    int ret = genericPrintSetupDialog->ShowModal();
+    if (ret == wxID_OK)
+      *wxThePrintSetupData = genericPrintSetupDialog->GetPrintData();
+
+    genericPrintSetupDialog->Close(TRUE);
+  }
+#ifdef __WINDOWS__
+  else
+  {
+    wxPrintData data;
+    data.SetSetupDialog(TRUE);
+    wxPrintDialog printDialog(this, & data);
+    printDialog.Show(TRUE);
+  }
+#endif
+}
+
+wxGenericPageSetupDialog::wxGenericPageSetupDialog(wxWindow *parent, wxPageSetupData* data):
+  wxDialog(parent, -1, "Page Setup", wxPoint(0, 0), wxSize(600, 600), wxDIALOG_MODAL|wxDEFAULT_DIALOG_STYLE)
+{
+  if ( data )
+    pageData = *data;
+
+  int buttonWidth = 75;
+  int buttonHeight = 25;
+  int spacing = 5;
+  int yPos = 5;
+  int xPos = 5;
+
+  wxButton *okButton = new wxButton(this, wxID_OK, "OK", wxPoint(5, yPos), wxSize(buttonWidth, buttonHeight));
+  (void) new wxButton(this, wxID_CANCEL, "Cancel", wxPoint(buttonWidth + 5 + spacing, yPos), wxSize(buttonWidth, buttonHeight));
+
+  printerButton = new wxButton(this, wxPRINTID_SETUP, "Printer...", wxPoint(buttonWidth*2 + 5 + 2*spacing, yPos), wxSize(buttonWidth, buttonHeight));
+
+  if ( !pageData.GetEnablePrinter() )
+    printerButton->Enable(FALSE);
+
+//  if (printData.GetEnableHelp())
+//  wxButton *helpButton = new wxButton(this, (wxFunction)wxGenericPageSetupHelpProc, "Help", -1, -1, buttonWidth, buttonHeight);
+
+  okButton->SetDefault();
+  okButton->SetFocus();
+
+  xPos = 5;
+  yPos += 35;
+
+  paperTypeChoice = CreatePaperTypeChoice(&xPos, &yPos);
+
+  xPos = 5;
+
+  wxString choices[2];
+  choices[0] = "Portrait";
+  choices[1] = "Landscape";
+  orientationRadioBox = new wxRadioBox(this, wxPRINTID_ORIENTATION, "Orientation",
+    wxPoint(xPos, yPos), wxSize(-1, -1), 2, choices, 2);
+  orientationRadioBox->SetSelection(0);
+
+  xPos = 5;
+  yPos += 60;
+
+  int staticWidth = 110;
+  int textWidth = 60;
+  spacing = 10;
+
+  (void) new wxStaticText(this, wxPRINTID_STATIC, "Left margin (mm):", wxPoint(xPos, yPos));
+  xPos += staticWidth;
+
+  marginLeftText = new wxTextCtrl(this, wxPRINTID_LEFTMARGIN, "", wxPoint(xPos, yPos), wxSize(textWidth, -1));
+  xPos += textWidth + spacing;
+
+  (void) new wxStaticText(this, wxPRINTID_STATIC, "Right margin (mm):", wxPoint(xPos, yPos));
+  xPos += staticWidth;
+
+  marginRightText = new wxTextCtrl(this, wxPRINTID_RIGHTMARGIN, "", wxPoint(xPos, yPos), wxSize(textWidth, -1));
+  xPos += textWidth + spacing;
+
+  yPos += 35;
+  xPos = 5;
+
+  (void) new wxStaticText(this, wxPRINTID_STATIC, "Top margin (mm):", wxPoint(xPos, yPos));
+  xPos += staticWidth;
+
+  marginTopText = new wxTextCtrl(this, wxPRINTID_TOPMARGIN, "", wxPoint(xPos, yPos), wxSize(textWidth, -1));
+  xPos += textWidth + spacing;
+
+  (void) new wxStaticText(this, wxPRINTID_STATIC, "Bottom margin (mm):", wxPoint(xPos, yPos));
+  xPos += staticWidth;
+
+  marginBottomText = new wxTextCtrl(this, wxPRINTID_BOTTOMMARGIN, "", wxPoint(xPos, yPos), wxSize(textWidth, -1));
+
+  Fit();
+  Centre(wxBOTH);
+
+  InitDialog();
+}
+
+wxGenericPageSetupDialog::~wxGenericPageSetupDialog(void)
+{
+}
+
+bool wxGenericPageSetupDialog::TransferDataToWindow(void)
+{
+  if (marginLeftText)
+    marginLeftText->SetValue(IntToString((int) pageData.GetMarginTopLeft().x));
+  if (marginTopText)
+    marginTopText->SetValue(IntToString((int) pageData.GetMarginTopLeft().y));
+  if (marginRightText)
+    marginRightText->SetValue(IntToString((int) pageData.GetMarginBottomRight().x));
+  if (marginBottomText)
+    marginBottomText->SetValue(IntToString((int) pageData.GetMarginBottomRight().y));
+
+  if (orientationRadioBox)
+  {
+    if (pageData.GetOrientation() == wxPORTRAIT)
+      orientationRadioBox->SetSelection(0);
+    else
+      orientationRadioBox->SetSelection(1);
+  }
+  return TRUE;
+}
+
+bool wxGenericPageSetupDialog::TransferDataFromWindow(void)
+{
+  if (marginLeftText && marginTopText)
+    pageData.SetMarginTopLeft(wxPoint(atoi((const char *)marginLeftText->GetValue()),atoi((const char *)marginTopText->GetValue())));
+  if (marginRightText && marginBottomText)
+    pageData.SetMarginBottomRight(wxPoint(atoi((const char *)marginRightText->GetValue()),atoi((const char *)marginBottomText->GetValue())));
+
+  if (orientationRadioBox)
+  {
+    int sel = orientationRadioBox->GetSelection();
+    if (sel == 0)
+    {
+      wxThePrintSetupData->SetPrinterOrientation(wxPORTRAIT);
+      pageData.SetOrientation(wxPORTRAIT);
+    }
+    else
+    {
+      wxThePrintSetupData->SetPrinterOrientation(wxLANDSCAPE);
+      pageData.SetOrientation(wxLANDSCAPE);
+    }
+  }
+  if (paperTypeChoice)
+  {
+    wxString val(paperTypeChoice->GetStringSelection());
+    if (!val.IsNull() && val != "")
+    {
+        wxPrintPaperType* paper = wxThePrintPaperDatabase->FindPaperType((char*) (const char *)val);
+        if ( paper )
+        {
+            pageData.SetPaperSize(wxPoint(paper->widthMM, paper->heightMM));
+        }
+    }
+  }
+  return TRUE;
+}
+
+wxChoice *wxGenericPageSetupDialog::CreatePaperTypeChoice(int *x, int *y)
+{
+  if (!wxThePrintPaperDatabase)
+  {
+    wxThePrintPaperDatabase = new wxPrintPaperDatabase;
+    wxThePrintPaperDatabase->CreateDatabase();
+  }
+  int n = wxThePrintPaperDatabase->Number();
+  wxString *choices = new wxString [n];
+  int sel = 0;
+  int i;
+  for (i = 0; i < n; i++)
+  {
+    wxPrintPaperType *paper = (wxPrintPaperType *)wxThePrintPaperDatabase->Nth(i)->Data();
+    choices[i] = paper->pageName;
+    if (pageData.GetPaperSize().x == paper->widthMM && pageData.GetPaperSize().y == paper->heightMM)
+      sel = i;
+  }
+
+  (void) new wxStaticText(this, wxPRINTID_STATIC, "Paper size", wxPoint(*x, *y));
+  *y += 25;
+
+  wxChoice *choice = new wxChoice(this, wxPRINTID_PAPERSIZE, wxPoint(*x, *y), wxSize(300, -1), n,
+    choices);
+  *y += 35;
+  delete[] choices;
+
+  choice->SetSelection(sel);
+  return choice;
+}
+
+
diff --git a/src/generic/scrolwin.cpp b/src/generic/scrolwin.cpp
new file mode 100644
index 0000000000..f82d3fa0d4
--- /dev/null
+++ b/src/generic/scrolwin.cpp
@@ -0,0 +1,442 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        scrolwin.cpp
+// Purpose:     wxScrolledWindow implementation
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation
+#pragma implementation "scrolwin.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#include "wx/utils.h"
+#include "wx/dcclient.h"
+
+#ifdef __WINDOWS__
+#include "windows.h"
+#endif
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#include "wx/generic/scrolwin.h"
+
+#if !USE_SHARED_LIBRARY
+BEGIN_EVENT_TABLE(wxScrolledWindow, wxWindow)
+  EVT_SCROLL(wxScrolledWindow::OnScroll)
+  EVT_SIZE(wxScrolledWindow::OnSize)
+  EVT_PAINT(wxScrolledWindow::OnPaint)
+END_EVENT_TABLE()
+
+IMPLEMENT_DYNAMIC_CLASS(wxScrolledWindow, wxWindow)
+#endif
+
+wxScrolledWindow::wxScrolledWindow(void)
+{
+  m_xScrollPixelsPerLine = 0;
+  m_yScrollPixelsPerLine = 0;
+  m_xScrollingEnabled = TRUE;
+  m_yScrollingEnabled = TRUE;
+  m_xScrollPosition = 0;
+  m_yScrollPosition = 0;
+  m_xScrollLines = 0;
+  m_yScrollLines = 0;
+  m_xScrollLinesPerPage = 0;
+  m_yScrollLinesPerPage = 0;
+}
+
+bool wxScrolledWindow::Create(wxWindow *parent, const wxWindowID id,
+           const wxPoint& pos,
+           const wxSize& size,
+           const long style,
+           const wxString& name)
+{
+  m_xScrollPixelsPerLine = 0;
+  m_yScrollPixelsPerLine = 0;
+  m_xScrollingEnabled = TRUE;
+  m_yScrollingEnabled = TRUE;
+  m_xScrollPosition = 0;
+  m_yScrollPosition = 0;
+  m_xScrollLines = 0;
+  m_yScrollLines = 0;
+  m_xScrollLinesPerPage = 0;
+  m_yScrollLinesPerPage = 0;
+
+  return wxWindow::Create(parent, id, pos, size, style, name);
+}
+
+/*
+ * pixelsPerUnitX/pixelsPerUnitY: number of pixels per unit (e.g. pixels per text line)
+ * noUnitsX/noUnitsY:        : no. units per scrollbar
+ */
+void wxScrolledWindow::SetScrollbars (const int pixelsPerUnitX, const int pixelsPerUnitY,
+	       const int noUnitsX, const int noUnitsY,
+	       const int xPos, const int yPos, const bool noRefresh )
+{
+  bool do_refresh =
+     (
+      (noUnitsX != 0 && m_xScrollLines == 0) ||
+      (noUnitsX < m_xScrollPosition) ||
+      (noUnitsY != 0 && m_yScrollLines == 0) ||
+      (noUnitsY < m_yScrollPosition) ||
+      (xPos != m_xScrollPosition) ||
+      (yPos != m_yScrollPosition) ||
+      (pixelsPerUnitX != m_xScrollPixelsPerLine) ||
+      (pixelsPerUnitY != m_yScrollPixelsPerLine)
+     );
+      
+      m_xScrollPixelsPerLine = pixelsPerUnitX;
+      m_yScrollPixelsPerLine = pixelsPerUnitY;
+      m_xScrollLines = noUnitsX;
+      m_yScrollLines = noUnitsY;
+
+   AdjustScrollbars();
+   
+   if (do_refresh && !noRefresh) Refresh();
+   
+#ifdef __WINDOWS__
+    UpdateWindow ((HWND) GetHWND());
+#endif
+}
+
+void wxScrolledWindow::OnScroll(wxScrollEvent& event)
+{
+  int orient = event.GetOrientation();
+
+  int nScrollInc = CalcScrollInc(event);
+  if (nScrollInc == 0)
+    return;
+
+    // TODO: should we store the scroll position here as well as in wxWindow?
+  if (orient == wxHORIZONTAL)
+  {
+    int newPos = m_xScrollPosition + nScrollInc;
+    SetScrollPos(wxHORIZONTAL, newPos, TRUE );
+  }
+  else
+  {
+    int newPos = m_yScrollPosition + nScrollInc;
+    SetScrollPos(wxVERTICAL, newPos, TRUE );
+  }
+
+/*
+  // TODO We need to multiply the ScrollWindow amount by the scaling
+  // factor, but how do we know what this is in wxWin 2.0???
+  float scaleX = 1.0;
+  float scaleY = 1.0;
+
+  if ( this->IsKindOf(CLASSINFO(wxCanvas)) )
+  {
+    wxDC* dc = ((wxCanvas *)this)->GetDC();
+    dc->GetUserScale(&scaleX, &scaleY);
+  }
+*/
+
+  if (orient == wxHORIZONTAL)
+  {
+    m_xScrollPosition += nScrollInc;
+  }
+  else
+  {
+    m_yScrollPosition += nScrollInc;
+  }
+  
+  if (orient == wxHORIZONTAL)
+  {
+    if (m_xScrollingEnabled)
+      ScrollWindow(-m_xScrollPixelsPerLine * nScrollInc, 0, NULL);
+    else
+      Refresh();
+  }
+  else
+  {
+    if (m_yScrollingEnabled)
+      ScrollWindow(0, -m_yScrollPixelsPerLine * nScrollInc, NULL);
+    else
+      Refresh();
+  }
+
+}
+
+int wxScrolledWindow::CalcScrollInc(wxScrollEvent& event)
+{
+  int pos = event.GetPosition();
+  int orient = event.GetOrientation();
+
+  int nScrollInc = 0;
+  switch (event.GetEventType())
+  {
+    case wxEVENT_TYPE_SCROLL_TOP:
+    {
+      if (orient == wxHORIZONTAL)
+        nScrollInc = - m_xScrollPosition;
+      else
+        nScrollInc = - m_yScrollPosition;
+      break;
+    }
+    case wxEVENT_TYPE_SCROLL_BOTTOM:
+    {
+      if (orient == wxHORIZONTAL)
+        nScrollInc = m_xScrollLines - m_xScrollPosition;
+      else
+        nScrollInc = m_yScrollLines - m_yScrollPosition;
+      break;
+    }
+    case wxEVENT_TYPE_SCROLL_LINEUP:
+    {
+      nScrollInc = -1;
+      break;
+    }
+    case wxEVENT_TYPE_SCROLL_LINEDOWN:
+    {
+      nScrollInc = 1;
+      break;
+    }
+    case wxEVENT_TYPE_SCROLL_PAGEUP:
+    {
+      if (orient == wxHORIZONTAL)
+        nScrollInc = -GetScrollPageSize(wxHORIZONTAL);
+      else
+        nScrollInc = -GetScrollPageSize(wxVERTICAL);
+      break;
+    }
+    case wxEVENT_TYPE_SCROLL_PAGEDOWN:
+    {
+      if (orient == wxHORIZONTAL)
+        nScrollInc = GetScrollPageSize(wxHORIZONTAL);
+      else
+        nScrollInc = GetScrollPageSize(wxVERTICAL);
+      break;
+    }
+    case wxEVENT_TYPE_SCROLL_THUMBTRACK:
+    {
+      if (orient == wxHORIZONTAL)
+        nScrollInc = pos - m_xScrollPosition;
+      else
+        nScrollInc = pos - m_yScrollPosition;
+      break;
+    }
+    default:
+    {
+      break;
+    }
+  }
+  if (orient == wxHORIZONTAL)
+  {
+        int w, h;
+		GetClientSize(&w, &h);
+
+    	int nMaxWidth = m_xScrollLines*m_xScrollPixelsPerLine;
+    	int noPositions = (int) ( ((nMaxWidth - w)/(float)m_xScrollPixelsPerLine) + 0.5 );
+    	if (noPositions < 0)
+      		noPositions = 0;
+
+		if ( (m_xScrollPosition + nScrollInc) < 0 )
+			nScrollInc = -m_xScrollPosition; // As -ve as we can go
+		else if ( (m_xScrollPosition + nScrollInc) > noPositions )
+			nScrollInc = noPositions - m_xScrollPosition; // As +ve as we can go
+
+        return nScrollInc;
+  }
+  else
+  {
+        int w, h;
+		GetClientSize(&w, &h);
+
+    	int nMaxHeight = m_yScrollLines*m_yScrollPixelsPerLine;
+    	int noPositions = (int) ( ((nMaxHeight - h)/(float)m_yScrollPixelsPerLine) + 0.5 );
+    	if (noPositions < 0)
+      		noPositions = 0;
+
+		if ( (m_yScrollPosition + nScrollInc) < 0 )
+			nScrollInc = -m_yScrollPosition; // As -ve as we can go
+		else if ( (m_yScrollPosition + nScrollInc) > noPositions )
+			nScrollInc = noPositions - m_yScrollPosition; // As +ve as we can go
+
+        return nScrollInc;
+  }
+}
+
+// Adjust the scrollbars - new version.
+void wxScrolledWindow::AdjustScrollbars(void)
+{
+  int w, h;
+  GetClientSize(&w, &h);
+
+  // Recalculate scroll bar range and position
+  if (m_xScrollLines > 0)
+  {
+    int nMaxWidth = m_xScrollLines*m_xScrollPixelsPerLine;
+    int newRange = (int) ( ((nMaxWidth)/(float)m_xScrollPixelsPerLine) + 0.5 );
+    if (newRange < 0)
+      newRange = 0;
+
+    m_xScrollPosition = wxMin(newRange, m_xScrollPosition);
+
+	// Calculate page size i.e. number of scroll units you get on the
+	// current client window
+    int noPagePositions = (int) ( (w/(float)m_xScrollPixelsPerLine) + 0.5 );
+    if (noPagePositions < 1)
+      noPagePositions = 1;
+
+    SetScrollbar(wxHORIZONTAL, m_xScrollPosition, noPagePositions, newRange);
+    SetScrollPageSize(wxHORIZONTAL, noPagePositions);
+  }
+  // Robert Roebling
+  else
+  { 
+    m_xScrollPosition = 0;
+    SetScrollbar (wxHORIZONTAL, 0, 0, 0, FALSE);  
+  }
+    
+  if (m_yScrollLines > 0)
+  {
+    int nMaxHeight = m_yScrollLines*m_yScrollPixelsPerLine;
+    int newRange = (int) ( ((nMaxHeight)/(float)m_yScrollPixelsPerLine) + 0.5 );
+    if (newRange < 0)
+      newRange = 0;
+
+    m_yScrollPosition = wxMin(newRange, m_yScrollPosition);
+
+	// Calculate page size i.e. number of scroll units you get on the
+	// current client window
+    int noPagePositions = (int) ( (h/(float)m_yScrollPixelsPerLine) + 0.5 );
+    if (noPagePositions < 1)
+      noPagePositions = 1;
+
+    SetScrollbar(wxVERTICAL, m_yScrollPosition, noPagePositions, newRange);
+    SetScrollPageSize(wxVERTICAL, noPagePositions);
+  }
+  else
+  {
+    m_yScrollPosition = 0;
+    SetScrollbar (wxVERTICAL, 0, 0, 0, FALSE);  // Robert Roebling
+  }
+  
+}
+
+// Default OnSize resets scrollbars, if any
+void wxScrolledWindow::OnSize(wxSizeEvent& WXUNUSED(event))
+{
+#if USE_CONSTRAINTS
+  if (GetAutoLayout())
+    Layout();
+#endif
+
+  AdjustScrollbars();
+}
+
+// This calls OnDraw, having adjusted the origin according to the current
+// scroll position
+void wxScrolledWindow::OnPaint(wxPaintEvent& WXUNUSED(event))
+{
+	wxPaintDC dc(this);
+	PrepareDC(dc);
+
+	OnDraw(dc);
+}
+
+// Override this function if you don't want to have wxScrolledWindow
+// automatically change the origin according to the scroll position.
+void wxScrolledWindow::PrepareDC(wxDC& dc)
+{
+	dc.SetDeviceOrigin(- m_xScrollPosition * m_xScrollPixelsPerLine, - m_yScrollPosition * m_yScrollPixelsPerLine);
+}
+
+#if WXWIN_COMPATIBILITY
+void wxScrolledWindow::GetScrollUnitsPerPage (int *x_page, int *y_page) const
+{
+      *x_page = GetScrollPageSize(wxHORIZONTAL);
+      *y_page = GetScrollPageSize(wxVERTICAL);
+}
+#endif
+
+void wxScrolledWindow::GetScrollPixelsPerUnit (int *x_unit, int *y_unit) const
+{
+      *x_unit = m_xScrollPixelsPerLine;
+      *y_unit = m_yScrollPixelsPerLine;
+}
+
+int wxScrolledWindow::GetScrollPageSize(int orient) const
+{
+    if ( orient == wxHORIZONTAL )
+        return m_xScrollLinesPerPage;
+    else
+        return m_yScrollLinesPerPage;
+}
+
+void wxScrolledWindow::SetScrollPageSize(int orient, int pageSize)
+{
+    if ( orient == wxHORIZONTAL )
+        m_xScrollLinesPerPage = pageSize;
+    else
+        m_yScrollLinesPerPage = pageSize;
+}
+
+/*
+ * Scroll to given position (scroll position, not pixel position)
+ */
+void wxScrolledWindow::Scroll (const int x_pos, const int y_pos)
+{
+  int old_x, old_y;
+  ViewStart (&old_x, &old_y);
+  if (((x_pos == -1) || (x_pos == old_x)) && ((y_pos == -1) || (y_pos == old_y)))
+    return;
+
+  if (x_pos > -1)
+    {
+      m_xScrollPosition = x_pos;
+      SetScrollPos (wxHORIZONTAL, x_pos, TRUE);
+    }
+  if (y_pos > -1)
+    {
+      m_yScrollPosition = y_pos;
+      SetScrollPos (wxVERTICAL, y_pos, TRUE);
+    }
+  Refresh();
+#ifdef __WINDOWS__
+  ::UpdateWindow ((HWND) GetHWND());
+#endif
+}
+
+void wxScrolledWindow::EnableScrolling (const bool x_scroll, const bool y_scroll)
+{
+  m_xScrollingEnabled = x_scroll;
+  m_yScrollingEnabled = y_scroll;
+}
+
+void wxScrolledWindow::GetVirtualSize (int *x, int *y) const
+{
+      *x = m_xScrollPixelsPerLine * m_xScrollLines;
+      *y = m_yScrollPixelsPerLine * m_yScrollLines;
+}
+
+// Where the current view starts from
+void wxScrolledWindow::ViewStart (int *x, int *y) const
+{
+  *x = m_xScrollPosition;
+  *y = m_yScrollPosition;
+}
+
+void wxScrolledWindow::CalcScrolledPosition(const int x, const int y, int *xx, int *yy) const
+{
+  *xx = x - m_xScrollPosition * m_xScrollPixelsPerLine;
+  *yy = y - m_yScrollPosition * m_yScrollPixelsPerLine;
+}
+
+void wxScrolledWindow::CalcUnscrolledPosition(const int x, const int y, float *xx, float *yy) const
+{
+  *xx = (float)(x + m_xScrollPosition * m_xScrollPixelsPerLine);
+  *yy = (float)(y + m_yScrollPosition * m_yScrollPixelsPerLine);
+}
+
+
diff --git a/src/generic/splitter.cpp b/src/generic/splitter.cpp
new file mode 100644
index 0000000000..84ec2282aa
--- /dev/null
+++ b/src/generic/splitter.cpp
@@ -0,0 +1,729 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        splitter.cpp
+// Purpose:     wxSplitterWindow implementation
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "splitter.h"
+// #pragma interface
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include <math.h>
+#include <stdlib.h>
+
+#include "wx/string.h"
+#include "wx/splitter.h"
+#include "wx/dcscreen.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxSplitterWindow, wxWindow)
+
+BEGIN_EVENT_TABLE(wxSplitterWindow, wxWindow)
+    EVT_PAINT(wxSplitterWindow::OnPaint)
+    EVT_SIZE(wxSplitterWindow::OnSize)
+    EVT_MOUSE_EVENTS(wxSplitterWindow::OnMouseEvent)
+END_EVENT_TABLE()
+#endif
+
+wxSplitterWindow::wxSplitterWindow(void)
+{
+    m_splitMode = wxSPLIT_VERTICAL;
+    m_windowOne = NULL;
+    m_windowTwo = NULL;
+    m_dragMode = wxSPLIT_DRAG_NONE;
+    m_oldX = 0;
+    m_oldY = 0;
+    m_firstX = 0;
+    m_firstY = 0;
+    m_sashSize = 7;
+    m_borderSize = 2;
+    m_sashPosition = 0;
+    m_sashCursorWE = NULL;
+    m_sashCursorNS = NULL;
+    m_sashTrackerPen = NULL;
+    m_lightShadowPen = NULL;
+    m_mediumShadowPen = NULL;
+    m_darkShadowPen = NULL;
+    m_faceBrush = NULL;
+    m_facePen = NULL;
+    m_hilightPen = NULL;
+    m_minimumPaneSize = 0;
+}
+
+wxSplitterWindow::wxSplitterWindow(wxWindow *parent, const wxWindowID id, const wxPoint& pos,
+    const wxSize& size, const long style, const wxString& name)
+  :wxWindow(parent, id, pos, size, style, name)
+{
+    m_splitMode = wxSPLIT_VERTICAL;
+    m_windowOne = NULL;
+    m_windowTwo = NULL;
+    m_dragMode = wxSPLIT_DRAG_NONE;
+    m_oldX = 0;
+    m_oldY = 0;
+    m_firstX = 0;
+    m_firstY = 0;
+    m_sashSize = 7;
+    m_borderSize = 2;
+    m_sashPosition = 0;
+    m_minimumPaneSize = 0;
+    m_sashCursorWE = new wxCursor(wxCURSOR_SIZEWE);
+    m_sashCursorNS = new wxCursor(wxCURSOR_SIZENS);
+    m_sashTrackerPen = new wxPen(*wxBLACK, 2, wxSOLID);
+    m_lightShadowPen = NULL;
+    m_mediumShadowPen = NULL;
+    m_darkShadowPen = NULL;
+    m_faceBrush = NULL;
+    m_facePen = NULL;
+    m_hilightPen = NULL;
+
+    if ( style & wxSP_3D )
+    {
+        m_borderSize = 2;
+        m_sashSize = 7;
+    }
+    else if ( style & wxSP_BORDER )
+    {
+        m_borderSize = 1;
+        m_sashSize = 3;
+    }
+    else
+    {
+        m_borderSize = 0;
+        m_sashSize = 3;
+    }
+
+    // Eventually, we'll respond to colour change messages
+    InitColours();
+
+    SetDoubleClick(TRUE);
+
+    // For debugging purposes, to see the background.
+//    SetBackground(wxBLUE_BRUSH);
+}
+
+wxSplitterWindow::~wxSplitterWindow(void)
+{
+    delete m_sashCursorWE;
+    delete m_sashCursorNS;
+    delete m_sashTrackerPen;
+    delete m_lightShadowPen;
+    delete m_darkShadowPen;
+    delete m_mediumShadowPen;
+    delete m_hilightPen;
+    delete m_facePen;
+    delete m_faceBrush;
+}
+
+void wxSplitterWindow::OnPaint(wxPaintEvent& WXUNUSED(event))
+{
+    wxPaintDC dc(this);
+
+    if ( m_borderSize > 0 )
+        DrawBorders(dc);
+    DrawSash(dc);
+}
+
+void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event)
+{
+    long x, y;
+    event.Position(&x, &y);
+
+	if (event.LeftDown())
+	{
+        if ( SashHitTest(x, y) )
+        {
+	        CaptureMouse();
+
+    	    // Required for X to specify that
+	        // that we wish to draw on top of all windows
+	        // - and we optimise by specifying the area
+	        // for creating the overlap window.
+	        wxScreenDC::StartDrawingOnTop(this);
+
+            // We don't say we're dragging yet; we leave that
+            // decision for the Dragging() branch, to ensure
+            // the user has dragged a little bit.
+            m_dragMode = wxSPLIT_DRAG_LEFT_DOWN;
+            m_firstX = x;
+            m_firstY = y;
+        }
+	}
+    else if ( event.LeftUp() && m_dragMode == wxSPLIT_DRAG_LEFT_DOWN )
+    {
+        // Wasn't a proper drag
+        ReleaseMouse();
+        wxScreenDC::EndDrawingOnTop();
+        m_dragMode = wxSPLIT_DRAG_NONE;
+
+        SetCursor(*wxSTANDARD_CURSOR);
+        wxSetCursor(*wxSTANDARD_CURSOR);
+    }
+	else if (event.LeftUp() && m_dragMode == wxSPLIT_DRAG_DRAGGING)
+	{
+        // We can stop dragging now and see what we've got.
+        m_dragMode = wxSPLIT_DRAG_NONE;
+		ReleaseMouse();
+        // Erase old tracker
+        DrawSashTracker(m_oldX, m_oldY);
+
+        // End drawing on top (frees the window used for drawing
+        // over the screen)
+        wxScreenDC::EndDrawingOnTop();
+
+        int w, h;
+		GetClientSize(&w, &h);
+        if ( m_splitMode == wxSPLIT_VERTICAL )
+        {
+            // First check if we should veto this resize because
+            // the pane size is too small
+            if ( wxMax(x, 0) < m_minimumPaneSize || wxMax((w - x), 0) < m_minimumPaneSize)
+                return;
+
+            if ( x <= 4 )
+            {
+                // We remove the first window from the view
+                wxWindow *removedWindow = m_windowOne;
+                m_windowOne = m_windowTwo;
+                m_windowTwo = NULL;
+
+                OnUnsplit(removedWindow);
+                m_sashPosition = 0;
+            }
+            else if ( x >= (w - 4) )
+            {
+                // We remove the second window from the view
+                wxWindow *removedWindow = m_windowTwo;
+                m_windowTwo = NULL;
+                OnUnsplit(removedWindow);
+                m_sashPosition = 0;
+            }
+            else
+            {
+                m_sashPosition = x;
+            }
+        }
+        else
+        {
+            // First check if we should veto this resize because
+            // the pane size is too small
+            if ( wxMax(y, 0) < m_minimumPaneSize || wxMax((h - y), 0) < m_minimumPaneSize)
+                return;
+
+            if ( y <= 4 )
+            {
+                // We remove the first window from the view
+                wxWindow *removedWindow = m_windowOne;
+                m_windowOne = m_windowTwo;
+                m_windowTwo = NULL;
+
+                OnUnsplit(removedWindow);
+                m_sashPosition = 0;
+            }
+            else if ( y >= (h - 4) )
+            {
+                // We remove the second window from the view
+                wxWindow *removedWindow = m_windowTwo;
+                m_windowTwo = NULL;
+                OnUnsplit(removedWindow);
+                m_sashPosition = 0;
+            }
+            else
+            {
+                m_sashPosition = y;
+            }
+        }
+        SizeWindows();
+	}
+	else if (event.Moving() && !event.Dragging())
+	{
+        // Just change the cursor if required
+        if ( SashHitTest(x, y) )
+        {
+            	if ( m_splitMode == wxSPLIT_VERTICAL )
+                {
+	                SetCursor(*m_sashCursorWE);
+                    // Windows needs the following
+	                wxSetCursor(*m_sashCursorWE);
+                }
+                else
+                {
+	                SetCursor(*m_sashCursorNS);
+	                wxSetCursor(*m_sashCursorNS);
+                }
+        }
+        else
+        {
+    	    SetCursor(*wxSTANDARD_CURSOR);
+    	    wxSetCursor(*wxSTANDARD_CURSOR);
+        }
+	}
+	else if ( (event.Dragging() && (m_dragMode == wxSPLIT_DRAG_DRAGGING)) ||
+              (event.Dragging() && SashHitTest(x, y, 4)) )
+	{
+         if ( m_splitMode == wxSPLIT_VERTICAL )
+         {
+	        SetCursor(*m_sashCursorWE);
+	        wxSetCursor(*m_sashCursorWE);
+         }
+         else
+         {
+	        SetCursor(*m_sashCursorNS);
+	        wxSetCursor(*m_sashCursorNS);
+         }
+
+        // Detect that this is really a drag: we've moved more than 1 pixel either way
+        if ((m_dragMode == wxSPLIT_DRAG_LEFT_DOWN) &&
+//                (abs((int)x - m_firstX) > 1 || abs((int)y - m_firstY) > 1) )
+                (abs((int)x - m_firstX) > 0 || abs((int)y - m_firstY) > 1) )
+        {
+            m_dragMode = wxSPLIT_DRAG_DRAGGING;
+            DrawSashTracker(x, y);
+        }
+        else
+        {
+          if ( m_dragMode == wxSPLIT_DRAG_DRAGGING )
+          {
+            // Erase old tracker
+            DrawSashTracker(m_oldX, m_oldY);
+
+            // Draw new one
+            DrawSashTracker(x, y);
+          }
+        }
+        m_oldX = x;
+        m_oldY = y;
+	}
+    else if ( event.LeftDClick() )
+    {
+        OnDoubleClickSash(x, y);
+    }
+    else
+    {
+        SetCursor(*wxSTANDARD_CURSOR);
+        wxSetCursor(*wxSTANDARD_CURSOR);
+    }
+}
+
+void wxSplitterWindow::OnSize(wxSizeEvent& WXUNUSED(event))
+{
+    int cw, ch;
+    GetClientSize( &cw, &ch );
+    if ( m_windowTwo )
+    {
+        if ( m_splitMode == wxSPLIT_VERTICAL )
+        {
+            if ( m_sashPosition >= (cw - 5) )
+                m_sashPosition = wxMax(10, cw - 40);
+        }
+        if ( m_splitMode == wxSPLIT_HORIZONTAL )
+        {
+            if ( m_sashPosition >= (ch - 5) )
+                m_sashPosition = wxMax(10, ch - 40);
+        }
+    }
+    SizeWindows();
+}
+
+bool wxSplitterWindow::SashHitTest(const int x, const int y, const int tolerance)
+{
+    if ( m_windowTwo == NULL || m_sashPosition == 0)
+        return FALSE; // No sash
+
+    if ( m_splitMode == wxSPLIT_VERTICAL )
+    {
+        if ( (x >= m_sashPosition - tolerance) && (x <= m_sashPosition + m_sashSize + tolerance) )
+            return TRUE;
+        else
+            return FALSE;
+    }
+    else
+    {
+        if ( (y >= (m_sashPosition- tolerance)) && (y <= (m_sashPosition + m_sashSize + tolerance)) )
+            return TRUE;
+        else
+            return FALSE;
+    }
+
+    return FALSE;
+}
+
+// Draw 3D effect borders
+void wxSplitterWindow::DrawBorders(wxDC& dc)
+{
+    int w, h;
+    GetClientSize(&w, &h);
+
+    if ( GetWindowStyleFlag() & wxSP_3D )
+    {
+        dc.SetPen(*m_mediumShadowPen);
+        dc.DrawLine(0, 0, w-1, 0);
+        dc.DrawLine(0, 0, 0, h - 1);
+
+        dc.SetPen(*m_darkShadowPen);
+        dc.DrawLine(1, 1, w-2, 1);
+        dc.DrawLine(1, 1, 1, h-2);
+
+        dc.SetPen(*m_hilightPen);
+        dc.DrawLine(0, h-1, w-1, h-1);
+        dc.DrawLine(w-1, 0, w-1, h); // Surely the maximum y pos. should be h - 1.
+                                     /// Anyway, h is required for MSW.
+
+        dc.SetPen(*m_lightShadowPen);
+        dc.DrawLine(w-2, 1, w-2, h-2); // Right hand side
+        dc.DrawLine(1, h-2, w-1, h-2);     // Bottom
+    }
+    else if ( GetWindowStyleFlag() & wxSP_BORDER )
+    {
+        dc.SetBrush(*wxTRANSPARENT_BRUSH);
+        dc.SetPen(*wxBLACK_PEN);
+        dc.DrawRectangle(0, 0, w-1, h-1);
+    }
+
+    dc.SetPen(wxNullPen);
+    dc.SetBrush(wxNullBrush);
+}
+
+// Draw the sash
+void wxSplitterWindow::DrawSash(wxDC& dc)
+{
+    if ( m_sashPosition == 0 || !m_windowTwo)
+        return;
+
+    int w, h;
+    GetClientSize(&w, &h);
+
+    if ( GetWindowStyleFlag() & wxSP_3D )
+    {
+        if ( m_splitMode == wxSPLIT_VERTICAL )
+        {
+            dc.SetPen(*m_facePen);
+            dc.SetBrush(*m_faceBrush);
+            dc.DrawRectangle(m_sashPosition + 2, 0, m_sashSize - 4, h);
+
+            dc.SetBrush(*wxTRANSPARENT_BRUSH);
+
+            dc.SetPen(*m_lightShadowPen);
+            dc.DrawLine(m_sashPosition, 1, m_sashPosition, h-2);
+
+            dc.SetPen(*m_hilightPen);
+            dc.DrawLine(m_sashPosition+1, 0, m_sashPosition+1, h);
+
+            dc.SetPen(*m_mediumShadowPen);
+            dc.DrawLine(m_sashPosition+m_sashSize-2, 1, m_sashPosition+m_sashSize-2, h-1);
+
+            dc.SetPen(*m_darkShadowPen);
+            dc.DrawLine(m_sashPosition+m_sashSize-1, 2, m_sashPosition+m_sashSize-1, h-2);
+        }
+        else
+        {
+            dc.SetPen(*m_facePen);
+            dc.SetBrush(*m_faceBrush);
+            dc.DrawRectangle(0, m_sashPosition + 2, w, m_sashSize - 4);
+
+            dc.SetBrush(*wxTRANSPARENT_BRUSH);
+
+            dc.SetPen(*m_lightShadowPen);
+            dc.DrawLine(1, m_sashPosition, w-2, m_sashPosition);
+
+            dc.SetPen(*m_hilightPen);
+            dc.DrawLine(0, m_sashPosition+1, w, m_sashPosition+1);
+
+            dc.SetPen(*m_mediumShadowPen);
+            dc.DrawLine(1, m_sashPosition+m_sashSize-2, w-1, m_sashPosition+m_sashSize-2);
+
+            dc.SetPen(*m_darkShadowPen);
+            dc.DrawLine(2, m_sashPosition+m_sashSize-1, w-2, m_sashPosition+m_sashSize-1);
+        }
+    }
+    else
+    {
+        if ( m_splitMode == wxSPLIT_VERTICAL )
+        {
+            dc.SetPen(*wxBLACK_PEN);
+            dc.SetBrush(*wxBLACK_BRUSH);
+            int h1 = h-1;
+            if ( (GetWindowStyleFlag() & wxSP_BORDER) != wxSP_BORDER )
+                h1 += 1; // Not sure why this is necessary...
+            dc.DrawRectangle(m_sashPosition, 0, m_sashSize, h1);
+        }
+        else
+        {
+            dc.SetPen(*wxBLACK_PEN);
+            dc.SetBrush(*wxBLACK_BRUSH);
+            int w1 = w-1;
+            if ( (GetWindowStyleFlag() & wxSP_BORDER) != wxSP_BORDER )
+                w1 ++;
+
+            dc.DrawRectangle(0, m_sashPosition, w1, m_sashSize);
+        }
+
+    }
+
+    dc.SetPen(wxNullPen);
+    dc.SetBrush(wxNullBrush);
+}
+
+// Draw the sash tracker (for whilst moving the sash)
+void wxSplitterWindow::DrawSashTracker(const int x, const int y)
+{
+    int w, h;
+    GetClientSize(&w, &h);
+
+    wxScreenDC screenDC;
+    int x1, y1;
+    int x2, y2;
+
+    if ( m_splitMode == wxSPLIT_VERTICAL )
+    {
+        x1 = x; y1 = 2;
+        x2 = x; y2 = h-2;
+
+        if ( x1 > w )
+        {
+            x1 = w; x2 = w;
+        }
+        else if ( x1 < 0 )
+        {
+            x1 = 0; x2 = 0;
+        }
+    }
+    else
+    {
+        x1 = 2; y1 = y;
+        x2 = w-2; y2 = y;
+
+        if ( y1 > h )
+        {
+            y1 = h;
+            y2 = h;
+        }
+        else if ( y1 < 0 )
+        {
+            y1 = 0;
+            y2 = 0;
+        }
+    }
+
+    ClientToScreen(&x1, &y1);
+    ClientToScreen(&x2, &y2);
+
+    screenDC.SetLogicalFunction(wxXOR);
+    screenDC.SetPen(*m_sashTrackerPen);
+    screenDC.SetBrush(*wxTRANSPARENT_BRUSH);
+
+    screenDC.DrawLine(x1, y1, x2, y2);
+
+    screenDC.SetLogicalFunction(wxCOPY);
+
+    screenDC.SetPen(wxNullPen);
+    screenDC.SetBrush(wxNullBrush);
+}
+
+// Position and size subwindows.
+// Note that the border size applies to each subwindow, not
+// including the edges next to the sash.
+void wxSplitterWindow::SizeWindows(void)
+{
+    int w, h;
+    GetClientSize(&w, &h);
+
+    if ( m_windowOne && !m_windowTwo )
+    {
+        m_windowOne->SetSize(m_borderSize, m_borderSize, w - 2*m_borderSize, h - 2*m_borderSize);
+    }
+    else if ( m_windowOne && m_windowTwo )
+    {
+        if (m_splitMode == wxSPLIT_VERTICAL)
+        {
+            int x1 = m_borderSize;
+            int y1 = m_borderSize;
+            int w1 = m_sashPosition - m_borderSize;
+            int h1 = h - 2*m_borderSize;
+
+            int x2 = m_sashPosition + m_sashSize;
+            int y2 = m_borderSize;
+            int w2 = w - 2*m_borderSize - m_sashSize - w1;
+            int h2 = h - 2*m_borderSize;
+
+            m_windowOne->SetSize(x1, y1,
+                w1, h1);
+            m_windowTwo->SetSize(x2, y2,
+                w2, h2);
+        }
+        else
+        {
+            m_windowOne->SetSize(m_borderSize, m_borderSize,
+                w - 2*m_borderSize, m_sashPosition - m_borderSize);
+            m_windowTwo->SetSize(m_borderSize, m_sashPosition + m_sashSize,
+                w - 2*m_borderSize, h - 2*m_borderSize - m_sashSize - (m_sashPosition - m_borderSize));
+        }
+    }
+    wxClientDC dc(this);
+    DrawBorders(dc);
+    DrawSash(dc);
+}
+
+// Set pane for unsplit window
+void wxSplitterWindow::Initialize(wxWindow *window)
+{
+    m_windowOne = window;
+    m_windowTwo = NULL;
+    m_sashPosition = 0;
+}
+
+// Associates the given window with window 2, drawing the appropriate sash
+// and changing the split mode.
+// Does nothing and returns FALSE if the window is already split.
+bool wxSplitterWindow::SplitVertically(wxWindow *window1, wxWindow *window2, const int sashPosition)
+{
+    if ( IsSplit() )
+        return FALSE;
+
+    m_splitMode = wxSPLIT_VERTICAL;
+    m_windowOne = window1;
+    m_windowTwo = window2;
+    if ( sashPosition == -1 )
+        m_sashPosition = 100;
+    else
+        m_sashPosition = sashPosition;
+
+    SizeWindows();
+
+    return TRUE;
+}
+
+bool wxSplitterWindow::SplitHorizontally(wxWindow *window1, wxWindow *window2, const int sashPosition)
+{
+    if ( IsSplit() )
+        return FALSE;
+
+    m_splitMode = wxSPLIT_HORIZONTAL;
+    m_windowOne = window1;
+    m_windowTwo = window2;
+    if ( sashPosition == -1 )
+        m_sashPosition = 100;
+    else
+        m_sashPosition = sashPosition;
+
+    SizeWindows();
+
+    return TRUE;
+}
+
+
+// Remove the specified (or second) window from the view
+// Doesn't actually delete the window.
+bool wxSplitterWindow::Unsplit(wxWindow *toRemove)
+{
+    if ( ! IsSplit() )
+        return FALSE;
+
+    if ( toRemove == NULL || toRemove == m_windowTwo)
+    {
+        wxWindow *win = m_windowTwo ;
+        m_windowTwo = NULL;
+        m_sashPosition = 0;
+        OnUnsplit(win);
+        SizeWindows();
+    }
+    else if ( toRemove == m_windowOne )
+    {
+        wxWindow *win = m_windowOne ;
+        m_windowOne = m_windowTwo;
+        m_windowTwo = NULL;
+        m_sashPosition = 0;
+        OnUnsplit(win);
+        SizeWindows();
+    }
+    else
+        return FALSE;
+
+    return TRUE;
+}
+
+void wxSplitterWindow::SetSashPosition(const int position, const bool redraw)
+{
+    m_sashPosition = position;
+
+    if ( redraw )
+    {
+        SizeWindows();
+    }
+}
+
+// Called when the sash is double-clicked.
+// The default behaviour is to remove the sash if the
+// minimum pane size is zero.
+void wxSplitterWindow::OnDoubleClickSash(int WXUNUSED(x), int WXUNUSED(y) )
+{
+    if ( GetMinimumPaneSize() == 0 )
+    {
+        Unsplit();
+    }
+}
+
+// Initialize colours
+void wxSplitterWindow::InitColours(void)
+{
+    if ( m_facePen )
+        delete m_facePen;
+    if ( m_faceBrush )
+        delete m_faceBrush;
+    if ( m_mediumShadowPen )
+        delete m_mediumShadowPen;
+    if ( m_darkShadowPen )
+        delete m_darkShadowPen;
+    if ( m_lightShadowPen )
+        delete m_lightShadowPen;
+    if ( m_hilightPen )
+        delete m_hilightPen;
+
+    // Shadow colours
+#if defined(__WIN95__)
+//    COLORREF ref = ::GetSysColor(COLOR_3DFACE); // Normally light grey
+    wxColour faceColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
+    m_facePen = new wxPen(faceColour, 1, wxSOLID);
+    m_faceBrush = new wxBrush(faceColour, wxSOLID);
+
+//    ref = ::GetSysColor(COLOR_3DSHADOW); // Normally dark grey
+    wxColour mediumShadowColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DSHADOW));
+    m_mediumShadowPen = new wxPen(mediumShadowColour, 1, wxSOLID);
+
+//    ref = ::GetSysColor(COLOR_3DDKSHADOW); // Normally black
+    wxColour darkShadowColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DDKSHADOW));
+    m_darkShadowPen = new wxPen(darkShadowColour, 1, wxSOLID);
+
+//    ref = ::GetSysColor(COLOR_3DLIGHT); // Normally light grey
+    wxColour lightShadowColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DLIGHT));
+    m_lightShadowPen = new wxPen(lightShadowColour, 1, wxSOLID);
+
+//    ref = ::GetSysColor(COLOR_3DHILIGHT); // Normally white
+    wxColour hilightColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DHILIGHT));
+    m_hilightPen = new wxPen(hilightColour, 1, wxSOLID);
+#else
+    m_facePen = new wxPen("LIGHT GREY", 1, wxSOLID);
+    m_faceBrush = new wxBrush("LIGHT GREY", wxSOLID);
+    m_mediumShadowPen = new wxPen("GREY", 1, wxSOLID);
+    m_darkShadowPen = new wxPen("BLACK", 1, wxSOLID);
+    m_lightShadowPen = new wxPen("LIGHT GREY", 1, wxSOLID);
+    m_hilightPen = new wxPen("WHITE", 1, wxSOLID);
+#endif
+}
+
diff --git a/src/generic/statusbr.cpp b/src/generic/statusbr.cpp
new file mode 100644
index 0000000000..d2f31f0096
--- /dev/null
+++ b/src/generic/statusbr.cpp
@@ -0,0 +1,332 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        statusbr.cpp
+// Purpose:     wxStatusBar class implementation
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "statusbr.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/setup.h"
+#include "wx/frame.h"
+#include "wx/settings.h"
+#include "wx/dcclient.h"
+#endif
+
+#include "wx/generic/statusbr.h"
+
+#ifdef __WINDOWS__
+#include <windows.h>
+
+#ifdef DrawText
+#undef DrawText
+#endif
+
+#endif
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxStatusBar, wxWindow)
+
+BEGIN_EVENT_TABLE(wxStatusBar, wxWindow)
+	EVT_PAINT(wxStatusBar::OnPaint)
+    EVT_SYS_COLOUR_CHANGED(wxStatusBar::OnSysColourChanged)
+END_EVENT_TABLE()
+#endif
+
+// Default status border dimensions
+#define         wxTHICK_LINE_BORDER 2
+#define         wxTHICK_LINE_WIDTH  1
+
+wxStatusBar::wxStatusBar(void)
+{
+  m_statusWidths = NULL;
+  m_statusStrings = NULL;
+  m_nFields = 0;
+  m_borderX = wxTHICK_LINE_BORDER;
+  m_borderY = wxTHICK_LINE_BORDER;
+}
+
+wxStatusBar::~wxStatusBar(void)
+{
+    SetFont(wxNullFont);
+
+	if ( m_statusWidths )
+		delete[] m_statusWidths;
+	if ( m_statusStrings )
+		delete[] m_statusStrings;
+}
+
+bool wxStatusBar::Create(wxWindow *parent, const wxWindowID id,
+           const wxPoint& pos,
+           const wxSize& size,
+           const long style,
+           const wxString& name)
+{
+  m_statusWidths = NULL;
+  m_statusStrings = NULL;
+  m_nFields = 0;
+  m_borderX = wxTHICK_LINE_BORDER;
+  m_borderY = wxTHICK_LINE_BORDER;
+
+  bool success = wxWindow::Create(parent, id, pos, size, style, name);
+
+  // Don't wish this to be found as a child
+  parent->GetChildren()->DeleteObject(this);
+
+  InitColours();
+
+  SetFont(m_defaultStatusBarFont);
+
+  return success;
+}
+
+void wxStatusBar::SetFieldsCount(const int number, const int *widths)
+{
+  m_nFields = number;
+
+  if ( m_statusWidths )
+	delete[] m_statusWidths;
+
+  if ( m_statusStrings )
+		delete[] m_statusStrings;
+
+  m_statusStrings = new wxString[number];
+
+  int i;
+  for (i = 0; i < number; i++)
+	m_statusStrings[i] = "";
+
+	if ( widths )
+  		SetStatusWidths(number, widths);
+}
+
+void wxStatusBar::SetStatusText(const wxString& text, const int number)
+{
+  if ((number < 0) || (number >= m_nFields))
+    return;
+
+  m_statusStrings[number] = text;
+
+  Refresh();
+
+#ifdef __WINDOWS__
+  // For some reason, this can cause major GDI problems - graphics
+  // all over the place. E.g. in print previewing.
+//  ::UpdateWindow((HWND) GetHWND());
+#endif
+}
+
+wxString wxStatusBar::GetStatusText(const int n) const
+{
+  if ((n < 0) || (n >= m_nFields))
+    return wxString("");
+  else
+    return m_statusStrings[n];
+}
+
+void wxStatusBar::SetStatusWidths(const int n, const int *widths_field)
+{
+  // only set status widths, when n == number of statuswindows
+  if (n == m_nFields)
+  {
+    // only set status widths,
+    // when one window (minimum) is variable (width <= 0)
+    bool is_variable = FALSE;
+    int i;
+    for (i = 0; i < m_nFields; i++)
+    {
+      if (widths_field[i] <= 0) is_variable = TRUE;
+    }
+
+    // if there are old widths, delete them
+    if (m_statusWidths)
+      delete [] m_statusWidths;
+
+    // set widths
+    m_statusWidths = new int[n];
+    for (i = 0; i < m_nFields; i++)
+    {
+      m_statusWidths[i] = widths_field[i];
+    }
+  }
+}
+
+void wxStatusBar::OnPaint(wxPaintEvent& WXUNUSED(event) )
+{
+  wxPaintDC dc(this);
+
+  int i;
+  if ( GetFont() )
+    dc.SetFont(*GetFont());
+  dc.SetBackgroundMode(wxTRANSPARENT);
+
+  for ( i = 0; i < m_nFields; i ++ )
+	DrawField(dc, i);
+}
+
+void wxStatusBar::DrawFieldText(wxDC& dc, const int i)
+{
+  int leftMargin = 2;
+
+  wxRectangle rect;
+  GetFieldRect(i, rect);
+
+  wxString text(GetStatusText(i));
+
+  long x, y;
+
+  dc.GetTextExtent(text, &x, &y);
+
+  int xpos = rect.x + leftMargin;
+  int ypos = (int) (((rect.height - y) / 2 ) + rect.y + 0.5) ;
+
+  dc.SetClippingRegion(rect.x, rect.y, rect.width, rect.height);
+
+  dc.DrawText(text, xpos, ypos);
+
+  dc.DestroyClippingRegion();
+}
+
+void wxStatusBar::DrawField(wxDC& dc, const int i)
+{
+  wxRectangle rect;
+  GetFieldRect(i, rect);
+
+    // Draw border
+    // Have grey background, plus 3-d border -
+    // One black rectangle.
+    // Inside this, left and top sides - dark grey. Bottom and right -
+    // white.
+
+	dc.SetPen(m_hilightPen);
+
+    // Right and bottom white lines
+    dc.DrawLine(rect.x + rect.width, rect.y,
+                rect.x + rect.width, rect.y + rect.height);
+    dc.DrawLine(rect.x + rect.width, rect.y + rect.height,
+				rect.x, rect.y + rect.height);
+
+	dc.SetPen(m_mediumShadowPen);
+
+    // Left and top grey lines
+    dc.DrawLine(rect.x, rect.y + rect.height,
+	   	rect.x, rect.y);
+    dc.DrawLine(rect.x, rect.y,
+		rect.x + rect.width, rect.y);
+
+	DrawFieldText(dc, i);
+}
+
+  // Get the position and size of the field's internal bounding rectangle
+bool wxStatusBar::GetFieldRect(const int n, wxRectangle& rect) const
+{
+  if ((n < 0) || (n >= m_nFields))
+    return FALSE;
+
+  int width, height;
+  GetClientSize(&width, &height);
+
+  int i;
+  int sum_of_nonvar = 0;
+  int num_of_var = 0;
+  bool do_same_width = FALSE;
+
+  int fieldWidth = 0;
+  int fieldPosition = 0;
+
+  if (m_statusWidths)
+  {
+    // if sum(not variable Windows) > c_width - (20 points per variable_window)
+    // then do_same_width = TRUE;
+    for (i = 0; i < m_nFields; i++)
+    {
+       if (m_statusWidths[i] > 0) sum_of_nonvar += m_statusWidths[i];
+        else num_of_var++;
+     }
+     if (sum_of_nonvar > (width - 20*num_of_var)) do_same_width = TRUE;
+  }
+  else do_same_width = TRUE;
+  if (do_same_width)
+  {
+    for (i = 0; i < m_nFields; i++)
+    {
+      fieldWidth = (int)(width/m_nFields);
+	  fieldPosition = i*fieldWidth;
+	  if ( i == n )
+		break;
+    }
+  }
+  else // no_same_width
+  {
+    int *tempwidth = new int[m_nFields];
+    int temppos = 0;
+    for (i = 0; i < m_nFields; i++)
+    {
+      if (m_statusWidths[i] > 0) tempwidth[i] = m_statusWidths[i];
+      else tempwidth[i] = (width - sum_of_nonvar) / num_of_var;
+    }
+    for (i = 0; i < m_nFields; i++)
+    {
+		fieldWidth = tempwidth[i];
+		fieldPosition = temppos;
+
+      	temppos += tempwidth[i];
+
+		if ( i == n )
+			break;
+    }
+    delete [] tempwidth;
+  }
+
+    rect.x = fieldPosition + wxTHICK_LINE_BORDER;
+	rect.y = wxTHICK_LINE_BORDER;
+
+	rect.width = fieldWidth - 2 * wxTHICK_LINE_BORDER ;
+	rect.height = height - 2 * wxTHICK_LINE_BORDER ;
+
+	return TRUE;
+}
+
+// Initialize colours
+void wxStatusBar::InitColours(void)
+{
+    // Shadow colours
+#if defined(__WIN95__)
+    wxColour mediumShadowColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DSHADOW));
+    m_mediumShadowPen = wxPen(mediumShadowColour, 1, wxSOLID);
+
+    wxColour hilightColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DHILIGHT));
+    m_hilightPen = wxPen(hilightColour, 1, wxSOLID);
+#else
+    m_mediumShadowPen = wxPen("GREY", 1, wxSOLID);
+    m_hilightPen = wxPen("WHITE", 1, wxSOLID);
+#endif
+
+	m_defaultStatusBarFont = wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT);
+    SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
+}
+
+// Responds to colour changes, and passes event on to children.
+void wxStatusBar::OnSysColourChanged(wxSysColourChangedEvent& event)
+{
+    InitColours();
+    Refresh();
+
+    // Propagate the event to the non-top-level children
+    wxWindow::OnSysColourChanged(event);
+}
+
diff --git a/src/generic/tabg.cpp b/src/generic/tabg.cpp
new file mode 100644
index 0000000000..216b721a0b
--- /dev/null
+++ b/src/generic/tabg.cpp
@@ -0,0 +1,1164 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        tabg.cpp
+// Purpose:     Generic tabbed dialogs
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c)
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "tabg.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <math.h>
+
+#include "wx/tab.h"
+
+IMPLEMENT_DYNAMIC_CLASS(wxTabControl, wxObject)
+
+IMPLEMENT_DYNAMIC_CLASS(wxTabLayer, wxList)
+
+wxTabControl::wxTabControl(wxTabView *v)
+{
+  m_view = v;
+  m_isSelected = FALSE;
+  m_labelFont = NULL;
+  m_offsetX = 0;
+  m_offsetY = 0;
+  m_width = 0;
+  m_height = 0;
+  m_id = 0;
+  m_rowPosition = 0;
+  m_colPosition = 0;
+}
+
+wxTabControl::~wxTabControl(void)
+{
+}
+    
+void wxTabControl::OnDraw(wxDC& dc, bool lastInRow)
+{
+    // Old, but in some ways better (drawing opaque tabs)
+#if 0
+  if (!m_view)
+    return;
+    
+  // Top-left of tab view area
+  int viewX = m_view->GetViewRect().x;
+  int viewY = m_view->GetViewRect().y;
+  
+  // Top-left of tab control
+  int tabX = GetX() + viewX;
+  int tabY = GetY() + viewY;
+  int tabHeightInc = 0;
+  if (m_isSelected)
+  {
+    tabHeightInc = (view->GetTabSelectionHeight() - view->GetTabHeight());
+    tabY -= tabHeightInc;
+  }
+  
+  dc.SetPen(wxTRANSPARENT_PEN);
+
+  // Draw grey background
+  if (view->GetTabStyle() & wxTAB_STYLE_COLOUR_INTERIOR)
+  {
+    dc.SetBrush(m_view->GetBackgroundBrush());
+
+    // Add 1 because the pen is transparent. Under Motif, may be different.
+    dc.DrawRectangle(tabX, tabY, (GetWidth()+1), (GetHeight() + 1 + tabHeightInc));
+  }
+  
+  // Draw highlight and shadow
+  dc.SetPen(m_view->GetHighlightPen());
+
+  // Calculate the top of the tab beneath. It's the height of the tab, MINUS
+  // a bit if the tab below happens to be selected. Check.
+  wxTabControl *tabBeneath = NULL;
+  int subtractThis = 0;
+  if (GetColPosition() > 0)
+    tabBeneath = m_view->FindTabControlForPosition(GetColPosition() - 1, GetRowPosition());
+  if (tabBeneath && tabBeneath->IsSelected())
+    subtractThis = (m_view->GetTabSelectionHeight() - m_view->GetTabHeight());
+
+  // Vertical highlight: if first tab, draw to bottom of view
+  if (tabX == m_view->GetViewRect().x && (m_view->GetTabStyle() & wxTAB_STYLE_DRAW_BOX))
+    dc.DrawLine(tabX, tabY, tabX, (m_view->GetViewRect().y + m_view->GetViewRect().height));
+  else if (tabX == m_view->GetViewRect().x)
+    // Not box drawing, just to top of view.
+    dc.DrawLine(tabX, tabY, tabX, (m_view->GetViewRect().y));
+  else
+    dc.DrawLine(tabX, tabY, tabX, (tabY + GetHeight() + tabHeightInc - subtractThis));
+
+  dc.DrawLine(tabX, tabY, (tabX + GetWidth()), tabY);
+  dc.SetPen(m_view->GetShadowPen());
+
+  // Test if we're outside the right-hand edge of the view area
+  if (((tabX + GetWidth()) >= m_view->GetViewRect().x + m_view->GetViewRect().width) && (m_view->GetTabStyle() & wxTAB_STYLE_DRAW_BOX))
+  {
+    int bottomY = m_view->GetViewRect().y + m_view->GetViewRect().height + GetY() + m_view->GetTabHeight() + m_view->GetTopMargin();
+    // Add a tab height since we wish to draw to the bottom of the view.
+    dc.DrawLine((tabX + GetWidth()), tabY,
+      (tabX + GetWidth()), bottomY);
+
+    // Calculate the far-right of the view, since we don't wish to
+    // draw inside that
+    int rightOfView = m_view->GetViewRect().x + m_view->GetViewRect().width + 1;
+
+    // Draw the horizontal bit to connect to the view rectangle
+    dc.DrawLine((wxMax((tabX + GetWidth() - m_view->GetHorizontalTabOffset()), rightOfView)), (bottomY-1),
+      (tabX + GetWidth()), (bottomY-1));
+
+    // Draw black line to emphasize shadow
+    dc.SetPen(wxBLACK_PEN);
+    dc.DrawLine((tabX + GetWidth() + 1), (tabY+1),
+      (tabX + GetWidth() + 1), bottomY);
+
+    // Draw the horizontal bit to connect to the view rectangle
+    dc.DrawLine((wxMax((tabX + GetWidth() - m_view->GetHorizontalTabOffset()), rightOfView)), (bottomY),
+      (tabX + GetWidth() + 1), (bottomY));
+  }
+  else
+  {
+    if (lastInRow)
+    {
+      // 25/5/97 UNLESS it's less than the max number of positions in this row
+      
+      int topY = m_view->GetViewRect().y - m_view->GetTopMargin();
+
+      int maxPositions = ((wxTabLayer *)m_view->GetLayers().Nth(0)->Data())->Number();
+
+      // Only down to the bottom of the tab, not to the top of the view
+      if ( GetColPosition() < maxPositions )
+        topY = tabY + GetHeight() + tabHeightInc;
+
+      // Shadow
+      dc.DrawLine((tabX + GetWidth()), tabY, (tabX + GetWidth()), topY);
+      // Draw black line to emphasize shadow
+      dc.SetPen(wxBLACK_PEN);
+      dc.DrawLine((tabX + GetWidth() + 1), (tabY+1), (tabX + GetWidth() + 1),
+         topY);
+    }
+    else
+    {
+      // Calculate the top of the tab beneath. It's the height of the tab, MINUS
+      // a bit if the tab below (and next col along) happens to be selected. Check.
+      wxTabControl *tabBeneath = NULL;
+      int subtractThis = 0;
+      if (GetColPosition() > 0)
+        tabBeneath = m_view->FindTabControlForPosition(GetColPosition() - 1, GetRowPosition() + 1);
+      if (tabBeneath && tabBeneath->IsSelected())
+        subtractThis = (m_view->GetTabSelectionHeight() - m_view->GetTabHeight());
+
+      // Draw only to next tab down.
+      dc.DrawLine((tabX + GetWidth()), tabY,
+         (tabX + GetWidth()), (tabY + GetHeight() + tabHeightInc - subtractThis));
+
+      // Draw black line to emphasize shadow
+      dc.SetPen(wxBLACK_PEN);
+      dc.DrawLine((tabX + GetWidth() + 1), (tabY+1), (tabX + GetWidth() + 1),
+         (tabY + GetHeight() + tabHeightInc - subtractThis));
+    }
+  }
+  
+  // Draw centered text
+  int textY = tabY + m_view->GetVerticalTabTextSpacing() + tabHeightInc;
+
+  if (m_isSelected)
+    dc.SetFont(m_view->GetSelectedTabFont());
+  else
+    dc.SetFont(GetFont());
+
+  wxColour col(m_view->GetTextColour());
+  dc.SetTextForeground(&col);
+//  dc.SetTextForeground(&(m_view->GetTextColour()));
+  dc.SetBackgroundMode(wxTRANSPARENT);
+  float textWidth, textHeight;
+  dc.GetTextExtent(GetLabel(), &textWidth, &textHeight);
+
+  int textX = (int)(tabX + (GetWidth() - textWidth)/2.0);
+  dc.DrawText(GetLabel(), textX, textY);
+
+  if (m_isSelected)
+  {
+    dc.SetPen(m_view->GetHighlightPen());
+
+    // Draw white highlight from the tab's left side to the left hand edge of the view
+    dc.DrawLine(m_view->GetViewRect().x, (tabY + GetHeight() + tabHeightInc),
+     tabX, (tabY + GetHeight() + tabHeightInc));
+
+    // Draw white highlight from the tab's right side to the right hand edge of the view
+    dc.DrawLine((tabX + GetWidth()), (tabY + GetHeight() + tabHeightInc),
+     m_view->GetViewRect().x + m_view->GetViewRect().width, (tabY + GetHeight() + tabHeightInc));
+  }
+#endif
+
+// New HEL version with rounder tabs
+#if 1
+	if (!m_view) return;
+
+	int tabInc   = 0;
+	if (m_isSelected)
+	{
+		tabInc = m_view->GetTabSelectionHeight() - m_view->GetTabHeight();
+	}
+	int tabLeft  = GetX() + m_view->GetViewRect().x;
+	int tabTop   = GetY() + m_view->GetViewRect().y - tabInc;
+	int tabRight = tabLeft + m_view->GetTabWidth();
+	int left     = m_view->GetViewRect().x;
+	int top      = tabTop + m_view->GetTabHeight() + tabInc;
+	int right    = left + m_view->GetViewRect().width;
+	int bottom   = top + m_view->GetViewRect().height;
+
+	if (m_isSelected)
+	{
+		// TAB is selected - draw TAB and the View's full outline
+
+		dc.SetPen(*(m_view->GetHighlightPen()));
+		wxPoint pnts[10];
+		int n = 0;
+		pnts[n].x = left;			pnts[n++].y = bottom;
+		pnts[n].x = left;	 		pnts[n++].y = top;
+		pnts[n].x = tabLeft; 		pnts[n++].y = top;
+		pnts[n].x = tabLeft;			pnts[n++].y = tabTop + 2;
+		pnts[n].x = tabLeft + 2;		pnts[n++].y = tabTop;
+		pnts[n].x = tabRight - 1;	pnts[n++].y = tabTop;
+		dc.DrawLines(n, pnts);
+		if (!lastInRow)
+		{
+			dc.DrawLine(
+					(tabRight + 2),
+					top,
+					right,
+					top
+					);
+		}
+
+		dc.SetPen(*(m_view->GetShadowPen()));
+		dc.DrawLine(
+				tabRight,
+				tabTop + 2,
+				tabRight,
+				top
+				);
+		dc.DrawLine(
+				right,
+				top,
+				right,
+				bottom
+				);
+		dc.DrawLine(
+				right,
+				bottom,
+				left,
+				bottom
+				);
+
+		dc.SetPen(*wxBLACK_PEN);
+		dc.DrawPoint(
+				tabRight,
+				tabTop + 1
+				);
+		dc.DrawPoint(
+				tabRight + 1,
+				tabTop + 2
+				);
+		if (lastInRow)
+		{
+			dc.DrawLine(
+				tabRight + 1,
+				bottom,
+				tabRight + 1,
+				tabTop + 1
+				);
+		}
+		else
+		{
+			dc.DrawLine(
+				tabRight + 1,
+				tabTop + 2,
+				tabRight + 1,
+				top
+				);
+			dc.DrawLine(
+				right + 1,
+				top,
+				right + 1,
+				bottom + 1
+				);
+		}
+		dc.DrawLine(
+				right + 1,
+				bottom + 1,
+				left + 1,
+				bottom + 1
+				);
+	}
+	else
+	{
+		// TAB is not selected - just draw TAB outline and RH edge
+		// if the TAB is the last in the row
+
+		int maxPositions = ((wxTabLayer*)m_view->GetLayers().Nth(0)->Data())->Number();
+		wxTabControl* tabBelow = 0;
+		wxTabControl* tabBelowRight = 0;
+		if (GetColPosition() > 0)
+		{
+			tabBelow = m_view->FindTabControlForPosition(
+						GetColPosition() - 1,
+						GetRowPosition()
+						);
+		}
+		if (!lastInRow && GetColPosition() > 0)
+		{
+			tabBelowRight = m_view->FindTabControlForPosition(
+						GetColPosition() - 1,
+						GetRowPosition() + 1
+						);
+		}
+
+		float raisedTop = top - m_view->GetTabSelectionHeight() +
+							m_view->GetTabHeight();
+
+		dc.SetPen(*(m_view->GetHighlightPen()));
+		wxPoint pnts[10];
+		int n = 0;
+
+		pnts[n].x = tabLeft;
+
+		if (tabBelow && tabBelow->IsSelected())
+		{
+			pnts[n++].y = (long)raisedTop;
+		}
+		else
+		{
+			pnts[n++].y = top;
+		}
+		pnts[n].x = tabLeft;			pnts[n++].y = tabTop + 2;
+		pnts[n].x = tabLeft + 2;		pnts[n++].y = tabTop;
+		pnts[n].x = tabRight - 1;	pnts[n++].y = tabTop;
+		dc.DrawLines(n, pnts);
+
+		dc.SetPen(*(m_view->GetShadowPen()));
+		if (GetRowPosition() >= maxPositions - 1)
+		{
+			dc.DrawLine(
+					tabRight,
+					(tabTop + 2),
+					tabRight,
+					bottom
+					);
+			dc.DrawLine(
+					tabRight,
+					bottom,
+					(tabRight - m_view->GetHorizontalTabOffset()),
+					bottom
+					);
+		}
+		else
+		{
+			if (tabBelowRight && tabBelowRight->IsSelected())
+			{
+				dc.DrawLine(
+						tabRight,
+						(long)raisedTop,
+						tabRight,
+						tabTop + 1
+						);
+			}
+			else
+			{
+				dc.DrawLine(
+						tabRight,
+						top - 1,
+						tabRight,
+						tabTop + 1
+						);
+			}
+		}
+
+		dc.SetPen(*wxBLACK_PEN);
+		dc.DrawPoint(
+				tabRight,
+				tabTop + 1
+				);
+		dc.DrawPoint(
+				tabRight + 1,
+				tabTop + 2
+				);
+		if (GetRowPosition() >= maxPositions - 1)
+		{
+			// draw right hand edge to bottom of view
+			dc.DrawLine(
+					tabRight + 1,
+					bottom + 1,
+					tabRight + 1,
+					tabTop + 2
+					);
+			dc.DrawLine(
+					tabRight + 1,
+					bottom + 1,
+					(tabRight - m_view->GetHorizontalTabOffset()),
+					bottom + 1
+					);
+		}
+		else
+		{
+			// draw right hand edge of TAB
+			if (tabBelowRight && tabBelowRight->IsSelected())
+			{
+				dc.DrawLine(
+						tabRight + 1,
+						(long)(raisedTop - 1),
+						tabRight + 1,
+						tabTop + 2
+						);
+			}
+			else
+			{
+				dc.DrawLine(
+						tabRight + 1,
+						top - 1,
+						tabRight + 1,
+						tabTop + 2
+						);
+			}
+		}
+	}
+
+	// Draw centered text
+	dc.SetPen(*wxBLACK_PEN);
+	if (m_isSelected)
+	{
+		dc.SetFont(*(m_view->GetSelectedTabFont()));
+	}
+	else
+	{
+		dc.SetFont(*(GetFont()));
+	}
+
+	wxColour col(m_view->GetTextColour());
+	dc.SetTextForeground(col);
+	dc.SetBackgroundMode(wxTRANSPARENT);
+	long textWidth, textHeight;
+	dc.GetTextExtent(GetLabel(), &textWidth, &textHeight);
+
+	float textX = (tabLeft + tabRight - textWidth) / 2;
+	float textY = (tabInc + tabTop + m_view->GetVerticalTabTextSpacing());
+	
+	dc.DrawText(GetLabel(), (long)textX, (long)textY);
+#endif
+}
+
+bool wxTabControl::HitTest(int x, int y) const
+{
+  // Top-left of tab control
+  int tabX1 = GetX() + m_view->GetViewRect().x;
+  int tabY1 = GetY() + m_view->GetViewRect().y;
+
+  // Bottom-right
+  int tabX2 = tabX1 + GetWidth();
+  int tabY2 = tabY1 + GetHeight();
+  
+  if (x >= tabX1 && y >= tabY1 && x <= tabX2 && y <= tabY2)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+IMPLEMENT_DYNAMIC_CLASS(wxTabView, wxObject)
+
+wxTabView::wxTabView(long style)
+{
+  m_noTabs = 0;
+  m_tabStyle = style;
+  m_tabSelection = -1;
+  m_tabHeight = 20;
+  m_tabSelectionHeight = m_tabHeight + 2;
+  m_tabWidth = 80;
+  m_tabHorizontalOffset = 10;
+  m_tabHorizontalSpacing = 2;
+  m_tabVerticalTextSpacing = 3;
+  m_topMargin = 5;
+  m_tabViewRect.x = 20;
+  m_tabViewRect.y = 20;
+  m_tabViewRect.width = 300;
+  m_tabViewRect.x = 300;
+  m_highlightColour = *wxWHITE;
+  m_shadowColour = wxColour(128, 128, 128);
+  m_backgroundColour = *wxLIGHT_GREY;
+  m_textColour = *wxBLACK;
+  m_highlightPen = wxWHITE_PEN;
+  m_shadowPen = wxGREY_PEN;
+  m_backgroundPen = wxLIGHT_GREY_PEN;
+  m_backgroundBrush = wxLIGHT_GREY_BRUSH;
+  m_tabFont = wxTheFontList->FindOrCreateFont(9, wxSWISS, wxNORMAL, wxNORMAL);
+  m_tabSelectedFont = wxTheFontList->FindOrCreateFont(9, wxSWISS, wxNORMAL, wxBOLD);
+  m_window = NULL;
+}
+
+wxTabView::~wxTabView()
+{
+}
+  
+// Automatically positions tabs
+wxTabControl *wxTabView::AddTab(int id, const wxString& label, wxTabControl *existingTab)
+{
+  // First, find which layer we should be adding to.
+  wxNode *node = m_layers.Last();
+  if (!node)
+  {
+    wxTabLayer *newLayer = new wxTabLayer;
+    node = m_layers.Append(newLayer);
+  }
+  // Check if adding another tab control would go off the
+  // right-hand edge of the layer.
+  wxTabLayer *tabLayer = (wxTabLayer *)node->Data();
+  wxNode *lastTabNode = tabLayer->Last();
+  if (lastTabNode)
+  {
+    wxTabControl *lastTab = (wxTabControl *)lastTabNode->Data();
+    // Start another layer (row).
+    // Tricky choice: can't just check if will be overlapping the edge, because
+    // this happens anyway for 2nd and subsequent rows.
+    // Should check this for 1st row, and then subsequent rows should not exceed 1st
+    // in length.
+    if (((tabLayer == m_layers.First()->Data()) && ((lastTab->GetX() + 2*lastTab->GetWidth() + GetHorizontalTabSpacing())
+              > GetViewRect().width)) ||
+        ((tabLayer != m_layers.First()->Data()) && (tabLayer->Number() == ((wxTabLayer *)m_layers.First()->Data())->Number())))
+    {
+      tabLayer = new wxTabLayer;
+      m_layers.Append(tabLayer);
+      lastTabNode = NULL;
+    }
+  }
+  int layer = m_layers.Number() - 1;
+  
+  wxTabControl *tabControl = existingTab;
+  if (!existingTab)
+    tabControl = OnCreateTabControl();
+  tabControl->SetRowPosition(tabLayer->Number());
+  tabControl->SetColPosition(layer);
+  
+  wxTabControl *lastTab = NULL;
+  if (lastTabNode)
+    lastTab = (wxTabControl *)lastTabNode->Data();
+  
+  // Top of new tab
+  int verticalOffset = (- GetTopMargin()) - ((layer+1)*GetTabHeight());
+  // Offset from view top-left
+  int horizontalOffset = 0;
+  if (!lastTab)
+    horizontalOffset = layer*GetHorizontalTabOffset();
+  else
+    horizontalOffset = lastTab->GetX() + GetTabWidth() + GetHorizontalTabSpacing();
+  
+  tabControl->SetPosition(horizontalOffset, verticalOffset);
+  tabControl->SetSize(GetTabWidth(), GetTabHeight());
+  tabControl->SetId(id);
+  tabControl->SetLabel(label);
+  tabControl->SetFont(GetTabFont());
+  
+  tabLayer->Append(tabControl);
+  m_noTabs ++;
+  
+  return tabControl;
+}
+  
+void wxTabView::ClearTabs(bool deleteTabs)
+{
+  wxNode *layerNode = m_layers.First();
+  while (layerNode)
+  {
+    wxTabLayer *layer = (wxTabLayer *)layerNode->Data();
+    wxNode *tabNode = layer->First();
+    while (tabNode)
+    {
+      wxTabControl *tab = (wxTabControl *)tabNode->Data();
+      if (deleteTabs)
+        delete tab;
+      wxNode *next = tabNode->Next();
+      delete tabNode;
+      tabNode = next;
+    }
+    wxNode *nextLayerNode = layerNode->Next();
+    delete layer;
+    delete layerNode;
+    layerNode = nextLayerNode;
+  }
+}
+  
+// Layout tabs (optional, e.g. if resizing window)
+void wxTabView::Layout(void)
+{
+  // Make a list of the tab controls, deleting the wxTabLayers.
+  wxList controls;
+
+  wxNode *layerNode = m_layers.First();
+  while (layerNode)
+  {
+    wxTabLayer *layer = (wxTabLayer *)layerNode->Data();
+    wxNode *tabNode = layer->First();
+    while (tabNode)
+    {
+      wxTabControl *tab = (wxTabControl *)tabNode->Data();
+      controls.Append(tab);
+      wxNode *next = tabNode->Next();
+      delete tabNode;
+      tabNode = next;
+    }
+    wxNode *nextLayerNode = layerNode->Next();
+    delete layer;
+    delete layerNode;
+    layerNode = nextLayerNode;
+  }
+  
+  wxTabControl *lastTab = NULL;
+  
+  wxTabLayer *currentLayer = new wxTabLayer;
+  m_layers.Append(currentLayer);
+  
+  wxNode *node = controls.First();
+  while (node)
+  {
+    wxTabControl *tabControl = (wxTabControl *)node->Data();
+    if (lastTab)
+    {
+      // Start another layer (row).
+      // Tricky choice: can't just check if will be overlapping the edge, because
+      // this happens anyway for 2nd and subsequent rows.
+      // Should check this for 1st row, and then subsequent rows should not exceed 1st
+      // in length.
+      if (((currentLayer == m_layers.First()->Data()) && ((lastTab->GetX() + 2*lastTab->GetWidth() + GetHorizontalTabSpacing())
+                > GetViewRect().width)) ||
+          ((currentLayer != m_layers.First()->Data()) && (currentLayer->Number() == ((wxTabLayer *)m_layers.First()->Data())->Number())))
+     {
+       currentLayer = new wxTabLayer;
+       m_layers.Append(currentLayer);
+       lastTab = NULL;
+     }
+    }
+    
+    int layer = m_layers.Number() - 1;
+
+    tabControl->SetRowPosition(currentLayer->Number());
+    tabControl->SetColPosition(layer);
+  
+    // Top of new tab
+    int verticalOffset = (- GetTopMargin()) - ((layer+1)*GetTabHeight());
+    // Offset from view top-left
+    int horizontalOffset = 0;
+    if (!lastTab)
+      horizontalOffset = layer*GetHorizontalTabOffset();
+    else
+      horizontalOffset = lastTab->GetX() + GetTabWidth() + GetHorizontalTabSpacing();
+  
+    tabControl->SetPosition(horizontalOffset, verticalOffset);
+    tabControl->SetSize(GetTabWidth(), GetTabHeight());
+
+    currentLayer->Append(tabControl);
+    lastTab = tabControl;
+
+    node = node->Next();
+  }
+
+  // Move the selected tab to the bottom
+  wxTabControl *control = FindTabControlForId(m_tabSelection);
+  if (control)
+    MoveSelectionTab(control);
+
+}
+
+// Draw all tabs
+void wxTabView::Draw(wxDC& dc)
+{
+	// Draw top margin area (beneath tabs and above view area)
+	if (GetTabStyle() & wxTAB_STYLE_COLOUR_INTERIOR)
+	{
+		dc.SetPen(*wxTRANSPARENT_PEN);
+		dc.SetBrush(*GetBackgroundBrush());
+
+		// Add 1 because the pen is transparent. Under Motif, may be different.
+		dc.DrawRectangle(
+				m_tabViewRect.x,
+				(m_tabViewRect.y - m_topMargin),
+				(m_tabViewRect.width + 1),
+				(m_topMargin + 1)
+				);
+	}
+
+	// Draw layers in reverse order
+	wxNode *node = m_layers.Last();
+	while (node)
+	{
+		wxTabLayer *layer = (wxTabLayer *)node->Data();
+		wxNode *node2 = layer->First();
+		while (node2)
+		{
+			wxTabControl *control = (wxTabControl *)node2->Data();
+			control->OnDraw(dc, (node2->Next() == NULL));
+			node2 = node2->Next();
+		}
+
+		node = node->Previous();
+	}
+
+
+#if 0
+	if (GetTabStyle() & wxTAB_STYLE_DRAW_BOX)
+	{
+		dc.SetPen(GetShadowPen());
+
+		// Draw bottom line
+		dc.DrawLine(
+				(GetViewRect().x + 1),
+				(GetViewRect().y + GetViewRect().height),
+				(GetViewRect().x + GetViewRect().width),
+				(GetViewRect().y + GetViewRect().height)
+				);
+
+		// Draw right line
+		dc.DrawLine(
+				(GetViewRect().x + GetViewRect().width),
+				(GetViewRect().y - GetTopMargin() + 1),
+				(GetViewRect().x + GetViewRect().width),
+				(GetViewRect().y + GetViewRect().height)
+				);
+
+		dc.SetPen(wxBLACK_PEN);
+
+		// Draw bottom line
+		dc.DrawLine(
+				(GetViewRect().x),
+				(GetViewRect().y + GetViewRect().height + 1),
+				(GetViewRect().x + GetViewRect().width),
+				(GetViewRect().y + GetViewRect().height + 1)
+				);
+
+		// Draw right line
+		dc.DrawLine(
+				(GetViewRect().x + GetViewRect().width + 1),
+				(GetViewRect().y - GetTopMargin()),
+				(GetViewRect().x + GetViewRect().width + 1),
+				(GetViewRect().y + GetViewRect().height + 1)
+				);
+	}
+#endif
+}
+  
+// Process mouse event, return FALSE if we didn't process it
+bool wxTabView::OnEvent(wxMouseEvent& event)
+{
+  if (!event.LeftDown())
+    return FALSE;
+    
+  float x, y;
+  event.Position(&x, &y);
+  
+  wxTabControl *hitControl = NULL;
+  
+  wxNode *node = m_layers.First();
+  while (node)
+  {
+    wxTabLayer *layer = (wxTabLayer *)node->Data();
+    wxNode *node2 = layer->First();
+    while (node2)
+    {
+      wxTabControl *control = (wxTabControl *)node2->Data();
+      if (control->HitTest((int)x, (int)y))
+      {
+        hitControl = control;
+        node = NULL;
+        node2 = NULL;
+      }
+      else
+        node2 = node2->Next();
+    }
+  
+    if (node)
+      node = node->Next();
+  }
+  
+  if (!hitControl)
+    return FALSE;
+    
+  wxTabControl *currentTab = FindTabControlForId(m_tabSelection);
+    
+  if (hitControl == currentTab)
+    return FALSE;
+    
+  ChangeTab(hitControl);
+  
+  return TRUE;
+}
+
+bool wxTabView::ChangeTab(wxTabControl *control)
+{
+  wxTabControl *currentTab = FindTabControlForId(m_tabSelection);
+  int oldTab = -1;
+  if (currentTab)
+    oldTab = currentTab->GetId();
+  
+  if (control == currentTab)
+    return TRUE;
+    
+  if (m_layers.Number() == 0)
+    return FALSE;
+    
+  if (!OnTabPreActivate(control->GetId(), oldTab))
+    return FALSE;
+
+  // Move the tab to the bottom
+  MoveSelectionTab(control);
+
+  if (currentTab)
+    currentTab->SetSelected(FALSE);
+    
+  control->SetSelected(TRUE);
+  m_tabSelection = control->GetId();
+
+  OnTabActivate(control->GetId(), oldTab);
+  
+  // Leave window refresh for the implementing window
+
+  return TRUE;
+}
+
+// Move the selected tab to the bottom layer, if necessary,
+// without calling app activation code
+bool wxTabView::MoveSelectionTab(wxTabControl *control)
+{
+  if (m_layers.Number() == 0)
+    return FALSE;
+    
+  wxTabLayer *firstLayer = (wxTabLayer *)m_layers.First()->Data();
+    
+  // Find what column this tab is at, so we can swap with the one at the bottom.
+  // If we're on the bottom layer, then no need to swap.
+  if (!firstLayer->Member(control))
+  {
+    // Do a swap
+    int col = 0;
+    wxNode *thisNode = FindTabNodeAndColumn(control, &col);
+    if (!thisNode)
+      return FALSE;
+    wxNode *otherNode = firstLayer->Nth(col);
+    if (!otherNode)
+      return FALSE;
+      
+    // If this is already in the bottom layer, return now
+    if (otherNode == thisNode)
+      return TRUE;
+      
+    wxTabControl *otherTab = (wxTabControl *)otherNode->Data();
+     
+    // We now have pointers to the tab to be changed to,
+    // and the tab on the first layer. Swap tab structures and
+    // position details.
+     
+    int thisX = control->GetX();
+    int thisY = control->GetY();
+    int thisColPos = control->GetColPosition();
+    int otherX = otherTab->GetX();
+    int otherY = otherTab->GetY();
+    int otherColPos = otherTab->GetColPosition();
+     
+    control->SetPosition(otherX, otherY);
+    control->SetColPosition(otherColPos);
+    otherTab->SetPosition(thisX, thisY);
+    otherTab->SetColPosition(thisColPos);
+     
+    // Swap the data for the nodes
+    thisNode->SetData(otherTab);
+    otherNode->SetData(control);
+  }
+  return TRUE;
+}
+
+// Called when a tab is activated
+void wxTabView::OnTabActivate(int /*activateId*/, int /*deactivateId*/)
+{
+}
+  
+void wxTabView::SetHighlightColour(const wxColour& col)
+{
+  m_highlightColour = col;
+  m_highlightPen = wxThePenList->FindOrCreatePen(col, 1, wxSOLID);
+}
+
+void wxTabView::SetShadowColour(const wxColour& col)
+{
+  m_shadowColour = col;
+  m_shadowPen = wxThePenList->FindOrCreatePen(col, 1, wxSOLID);
+}
+
+void wxTabView::SetBackgroundColour(const wxColour& col)
+{
+  m_backgroundColour = col;
+  m_backgroundPen = wxThePenList->FindOrCreatePen(col, 1, wxSOLID);
+  m_backgroundBrush = wxTheBrushList->FindOrCreateBrush(col, wxSOLID);
+}
+
+void wxTabView::SetTabSelection(int sel, bool activateTool)
+{
+  int oldSel = m_tabSelection;
+  wxTabControl *control = FindTabControlForId(sel);
+
+  if (!OnTabPreActivate(sel, oldSel))
+    return;
+    
+  if (control)
+    control->SetSelected((sel != 0)); // TODO ??
+  else
+  {
+    wxMessageBox("Could not find tab for id", "Error", wxOK);
+    return;
+  }
+    
+  m_tabSelection = sel;
+  MoveSelectionTab(control);
+  
+  if (activateTool)
+    OnTabActivate(sel, oldSel);
+}
+
+// Find tab control for id
+wxTabControl *wxTabView::FindTabControlForId(int id) const
+{
+  wxNode *node1 = m_layers.First();
+  while (node1)
+  {
+    wxTabLayer *layer = (wxTabLayer *)node1->Data();
+    wxNode *node2 = layer->First();
+    while (node2)
+    {
+      wxTabControl *control = (wxTabControl *)node2->Data();
+      if (control->GetId() == id)
+        return control;
+      node2 = node2->Next();
+    }
+    node1 = node1->Next();
+  }
+  return NULL;
+}
+
+// Find tab control for layer, position (starting from zero)
+wxTabControl *wxTabView::FindTabControlForPosition(int layer, int position) const
+{
+  wxNode *node1 = m_layers.Nth(layer);
+  if (!node1)
+    return NULL;
+  wxTabLayer *tabLayer = (wxTabLayer *)node1->Data();
+  wxNode *node2 = tabLayer->Nth(position);
+  if (!node2)
+    return NULL;
+  return (wxTabControl *)node2->Data();
+}
+
+// Find the node and the column at which this control is positioned.
+wxNode *wxTabView::FindTabNodeAndColumn(wxTabControl *control, int *col) const
+{
+  wxNode *node1 = m_layers.First();
+  while (node1)
+  {
+    wxTabLayer *layer = (wxTabLayer *)node1->Data();
+    int c = 0;
+    wxNode *node2 = layer->First();
+    while (node2)
+    {
+      wxTabControl *cnt = (wxTabControl *)node2->Data();
+      if (cnt == control)
+      {
+        *col = c;
+        return node2;
+      }
+      node2 = node2->Next();
+      c ++;
+    }
+    node1 = node1->Next();
+  }
+  return NULL;
+}
+
+int wxTabView::CalculateTabWidth(int noTabs, bool adjustView)
+{
+  m_tabWidth = (int)((m_tabViewRect.width - ((noTabs - 1)*GetHorizontalTabSpacing()))/noTabs);
+  if (adjustView)
+  {
+    m_tabViewRect.width = noTabs*m_tabWidth + ((noTabs-1)*GetHorizontalTabSpacing());
+  }
+  return m_tabWidth;
+}
+
+/*
+ * wxTabbedDialog
+ */
+ 
+IMPLEMENT_CLASS(wxTabbedDialog, wxDialog)
+
+BEGIN_EVENT_TABLE(wxTabbedDialog, wxDialog)
+    EVT_CLOSE(wxTabbedDialog::OnCloseWindow)
+    EVT_MOUSE_EVENTS(wxTabbedDialog::OnMouseEvent)
+    EVT_PAINT(wxTabbedDialog::OnPaint)
+END_EVENT_TABLE()
+
+wxTabbedDialog::wxTabbedDialog(wxWindow *parent, const wxWindowID id,
+    const wxString& title,
+    const wxPoint& pos, const wxSize& size,
+    const long windowStyle, const wxString& name):
+   wxDialog(parent, id, title, pos, size, windowStyle, name)
+{
+  m_tabView = NULL;
+}
+
+wxTabbedDialog::~wxTabbedDialog(void)
+{
+  if (m_tabView)
+    delete m_tabView;
+}
+ 
+void wxTabbedDialog::OnCloseWindow(wxCloseEvent& WXUNUSED(event) )
+{
+  Destroy();
+}
+
+void wxTabbedDialog::OnMouseEvent(wxMouseEvent& event )
+{
+  if (m_tabView)
+    m_tabView->OnEvent(event);
+}
+
+void wxTabbedDialog::OnPaint(wxPaintEvent& WXUNUSED(event) )
+{
+    wxPaintDC dc(this);
+    if (m_tabView)
+        m_tabView->Draw(dc);
+}
+
+/*
+ * wxTabbedPanel
+ */
+ 
+IMPLEMENT_CLASS(wxTabbedPanel, wxPanel)
+
+BEGIN_EVENT_TABLE(wxTabbedPanel, wxPanel)
+    EVT_MOUSE_EVENTS(wxTabbedPanel::OnMouseEvent)
+    EVT_PAINT(wxTabbedPanel::OnPaint)
+END_EVENT_TABLE()
+
+wxTabbedPanel::wxTabbedPanel(wxWindow *parent, const wxWindowID id, const wxPoint& pos,
+   const wxSize& size, const long windowStyle, const wxString& name):
+   wxPanel(parent, id, pos, size, windowStyle, name)
+{
+  m_tabView = NULL;
+}
+
+wxTabbedPanel::~wxTabbedPanel(void)
+{
+  delete m_tabView;
+}
+ 
+void wxTabbedPanel::OnMouseEvent(wxMouseEvent& event)
+{
+  if (m_tabView)
+    m_tabView->OnEvent(event);
+}
+
+void wxTabbedPanel::OnPaint(wxPaintEvent& WXUNUSED(event) )
+{
+    wxPaintDC dc(this);
+    if (m_tabView)
+        m_tabView->Draw(dc);
+}
+
+/*
+ * wxDialogTabView
+ */
+ 
+IMPLEMENT_CLASS(wxPanelTabView, wxTabView)
+ 
+wxPanelTabView::wxPanelTabView(wxPanel *pan, long style): wxTabView(style), m_tabWindows(wxKEY_INTEGER)
+{
+  m_panel = pan;
+  m_currentWindow = NULL;
+
+  if (m_panel->IsKindOf(CLASSINFO(wxTabbedDialog)))
+    ((wxTabbedDialog *)m_panel)->SetTabView(this);
+  else if (m_panel->IsKindOf(CLASSINFO(wxTabbedPanel)))
+    ((wxTabbedPanel *)m_panel)->SetTabView(this);
+
+  SetWindow(m_panel);
+}
+
+wxPanelTabView::~wxPanelTabView(void)
+{
+  ClearWindows(TRUE);
+}
+
+// Called when a tab is activated
+void wxPanelTabView::OnTabActivate(int activateId, int deactivateId)
+{
+  if (!m_panel)
+    return;
+    
+  wxWindow *oldWindow = ((deactivateId == -1) ? 0 : GetTabWindow(deactivateId));
+  wxWindow *newWindow = GetTabWindow(activateId);
+
+  if (oldWindow)
+    oldWindow->Show(FALSE);
+  if (newWindow)
+    newWindow->Show(TRUE);
+    
+  m_panel->Refresh();
+}
+
+   
+void wxPanelTabView::AddTabWindow(int id, wxWindow *window)
+{
+  m_tabWindows.Append((long)id, window);
+  window->Show(FALSE);
+}
+
+wxWindow *wxPanelTabView::GetTabWindow(int id) const
+{
+  wxNode *node = m_tabWindows.Find((long)id);
+  if (!node)
+    return NULL;
+  return (wxWindow *)node->Data();    
+}
+
+void wxPanelTabView::ClearWindows(bool deleteWindows)
+{
+  if (deleteWindows)
+    m_tabWindows.DeleteContents(TRUE);
+  m_tabWindows.Clear();
+  m_tabWindows.DeleteContents(FALSE);
+}
+
+void wxPanelTabView::ShowWindowForTab(int id)
+{
+  wxWindow *newWindow = GetTabWindow(id);
+  if (newWindow == m_currentWindow)
+    return;
+  if (m_currentWindow)
+    m_currentWindow->Show(FALSE);
+  newWindow->Show(TRUE);
+  newWindow->Refresh();
+}
+
diff --git a/src/generic/textdlgg.cpp b/src/generic/textdlgg.cpp
new file mode 100644
index 0000000000..6b6ffac7bd
--- /dev/null
+++ b/src/generic/textdlgg.cpp
@@ -0,0 +1,143 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        textdlgg.cpp
+// Purpose:     wxTextEntryDialog
+// Author:      Julian Smart
+// Modified by:
+// Created:     04/01/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "textdlgg.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include <stdio.h>
+#include "wx/utils.h"
+#include "wx/dialog.h"
+#include "wx/listbox.h"
+#include "wx/button.h"
+#include "wx/stattext.h"
+#include "wx/textctrl.h"
+#include "wx/layout.h"
+#include "wx/intl.h"
+#endif
+
+#include "wx/generic/textdlgg.h"
+
+// wxTextEntryDialog
+
+#if !USE_SHARED_LIBRARY
+BEGIN_EVENT_TABLE(wxTextEntryDialog, wxDialog)
+	EVT_BUTTON(wxID_OK, wxTextEntryDialog::OnOK)
+END_EVENT_TABLE()
+
+IMPLEMENT_CLASS(wxTextEntryDialog, wxDialog)
+#endif
+
+extern void wxSplitMessage2(const char *message, wxList *messageList, wxWindow *parent, wxRowColSizer *sizer);
+
+wxTextEntryDialog::wxTextEntryDialog(wxWindow *parent, const wxString& message, const wxString& caption,
+        const wxString& value, long style, const wxPoint& pos):
+	wxDialog(parent, -1, caption, pos, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxDIALOG_MODAL)
+{
+	m_dialogStyle = style;
+	m_value = value;
+
+	wxBeginBusyCursor();
+
+	wxSizer *topSizer = new wxSizer(this, wxSizerShrink);
+	topSizer->SetBorder(10, 10);
+
+	wxRowColSizer *messageSizer = new wxRowColSizer(topSizer, wxSIZER_COLS, 100);
+	messageSizer->SetName("messageSizer");
+
+//    bool centre = ((style & wxCENTRE) == wxCENTRE);
+
+	wxList messageList;
+	wxSplitMessage2(message, &messageList, this, messageSizer);
+
+	// Insert a spacer
+	wxSpacingSizer *spacingSizer = new wxSpacingSizer(topSizer, wxBelow, messageSizer, 10);
+
+	wxTextCtrl *textCtrl = new wxTextCtrl(this, wxID_TEXT, value, wxPoint(-1, -1), wxSize(350, -1));
+
+	wxRowColSizer *textSizer = new wxRowColSizer(topSizer, wxSIZER_ROWS);
+	textSizer->AddSizerChild(textCtrl);
+	textSizer->SetName("textSizer");
+
+	// Create constraints for the text sizer
+	wxLayoutConstraints *textC = new wxLayoutConstraints;
+	textC->left.SameAs		(messageSizer, wxLeft);
+	textC->top.Below		(spacingSizer);
+	textSizer->SetConstraints(textC);
+
+	// Insert another spacer
+	wxSpacingSizer *spacingSizer2 = new wxSpacingSizer(topSizer, wxBelow, textSizer, 10);
+	spacingSizer->SetName("spacingSizer2");
+
+	// Insert a sizer for the buttons
+	wxRowColSizer *buttonSizer = new wxRowColSizer(topSizer, wxSIZER_ROWS);
+	buttonSizer->SetName("buttonSizer");
+
+  	// Specify constraints for the button sizer
+  	wxLayoutConstraints *c = new wxLayoutConstraints;
+  	c->width.AsIs		();
+  	c->height.AsIs		();
+	c->top.Below		(spacingSizer2);
+	c->centreX.SameAs	(textSizer, wxCentreX);
+  	buttonSizer->SetConstraints(c);
+
+    wxButton *ok = NULL;
+  	wxButton *cancel = NULL;
+
+  if (style & wxOK) {
+    ok = new wxButton(this, wxID_OK, _("OK"));
+	buttonSizer->AddSizerChild(ok);
+  }
+
+  if (style & wxCANCEL) {
+    cancel = new wxButton(this, wxID_CANCEL, _("Cancel"));
+	buttonSizer->AddSizerChild(cancel);
+  }
+
+  if (ok)
+  {
+    ok->SetDefault();
+    ok->SetFocus();
+  }
+
+  Layout();
+  Centre(wxBOTH);
+
+  wxEndBusyCursor();
+}
+
+void wxTextEntryDialog::OnOK(wxCommandEvent& WXUNUSED(event) )
+{
+	wxTextCtrl *textCtrl = (wxTextCtrl *)FindWindow(wxID_TEXT);
+	if ( textCtrl )
+		m_value = textCtrl->GetValue();
+
+	EndModal(wxID_OK);
+}
+
+wxString wxGetTextFromUser(const wxString& message, const wxString& caption,
+                        const wxString& defaultValue, wxWindow *parent,
+                        int x, int y, bool WXUNUSED(centre) )
+{
+    wxTextEntryDialog dialog(parent, message, caption, defaultValue, wxOK|wxCANCEL, wxPoint(x, y));
+    if (dialog.ShowModal() == wxOK)
+        return dialog.GetValue();
+    else
+        return wxString("");
+}
diff --git a/src/generic/treectrl.cpp b/src/generic/treectrl.cpp
new file mode 100644
index 0000000000..84ae7efd04
--- /dev/null
+++ b/src/generic/treectrl.cpp
@@ -0,0 +1,932 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        treectrl.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "treectrl.h"
+#endif
+
+#include "wx/treectrl.h"
+#include "wx/settings.h"
+
+//-----------------------------------------------------------------------------
+// wxTreeItem
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxTreeItem, wxObject)
+
+wxTreeItem::wxTreeItem(void)
+{
+  m_mask = 0;
+  m_itemId = 0;
+  m_state = 0;
+  m_stateMask = 0;
+  m_image = -1;
+  m_selectedImage = -1;
+  m_children = 0;
+  m_data = 0;
+};
+
+//-----------------------------------------------------------------------------
+// wxTreeEvent
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxTreeEvent,wxCommandEvent)
+
+wxTreeEvent::wxTreeEvent( WXTYPE commandType, int id ) :
+  wxCommandEvent( commandType, id )
+{
+  m_code = 0;
+  m_oldItem = 0;
+};
+
+//-----------------------------------------------------------------------------
+// wxGenericTreeItem
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxGenericTreeItem,wxObject)
+
+wxGenericTreeItem::wxGenericTreeItem( wxGenericTreeItem *parent )
+{
+  Reset();
+  m_parent = parent;
+  m_hasHilight = FALSE;
+};
+
+wxGenericTreeItem::wxGenericTreeItem( wxGenericTreeItem *parent, const wxTreeItem& item, wxDC *dc )
+{
+  Reset();
+  SetItem( item, dc );
+  m_parent = parent;
+  m_hasHilight = FALSE;
+};
+
+void wxGenericTreeItem::SetItem( const wxTreeItem &item, wxDC *dc )
+{
+  if ((item.m_mask & wxTREE_MASK_HANDLE) == wxTREE_MASK_HANDLE) 
+    m_itemId = item.m_itemId;
+  if ((item.m_mask & wxTREE_MASK_STATE) == wxTREE_MASK_STATE)
+    m_state = item.m_state;
+  if ((item.m_mask & wxTREE_MASK_TEXT) == wxTREE_MASK_TEXT)
+    m_text = item.m_text;
+  if ((item.m_mask & wxTREE_MASK_IMAGE) == wxTREE_MASK_IMAGE)
+    m_image = item.m_image;
+  if ((item.m_mask & wxTREE_MASK_SELECTED_IMAGE) == wxTREE_MASK_SELECTED_IMAGE)
+    m_selectedImage = item.m_selectedImage;
+  if ((item.m_mask & wxTREE_MASK_CHILDREN) == wxTREE_MASK_CHILDREN)
+    m_hasChildren = (item.m_children > 0);
+  if ((item.m_mask & wxTREE_MASK_DATA) == wxTREE_MASK_DATA)
+    m_data = item.m_data;
+  long lw = 0;
+  long lh = 0;
+  dc->GetTextExtent( m_text, &lw, &lh );
+  m_width = lw;
+  m_height = lh;
+};
+
+void wxGenericTreeItem::SetText( const wxString &text, wxDC *dc )
+{
+  m_text = text;
+  long lw = 0;
+  long lh = 0;
+  dc->GetTextExtent( m_text, &lw, &lh );
+  m_width = lw;
+  m_height = lh;
+};
+
+void wxGenericTreeItem::Reset(void)
+{
+  m_itemId = -1;
+  m_state = 0;
+  m_text = "";
+  m_image = -1;
+  m_selectedImage = -1;
+//  m_children = 0;
+  m_hasChildren = FALSE;
+  m_data = 0;
+  m_x = 0;
+  m_y = 0;
+  m_height = 0;
+  m_width = 0;
+  m_xCross = 0;
+  m_yCross = 0;
+  m_level = 0;
+  m_children.DeleteContents( TRUE );
+  m_parent = NULL;
+};
+
+void wxGenericTreeItem::GetItem( wxTreeItem &item ) const
+{
+  if ((item.m_mask & wxTREE_MASK_STATE) == wxTREE_MASK_STATE)
+    item.m_state = m_state;
+  if ((item.m_mask & wxTREE_MASK_TEXT) == wxTREE_MASK_TEXT)
+    item.m_text = m_text;
+  if ((item.m_mask & wxTREE_MASK_IMAGE) == wxTREE_MASK_IMAGE)
+    item.m_image = m_image;
+  if ((item.m_mask & wxTREE_MASK_SELECTED_IMAGE) == wxTREE_MASK_SELECTED_IMAGE)
+    item.m_selectedImage = m_selectedImage;
+  if ((item.m_mask & wxTREE_MASK_CHILDREN) == wxTREE_MASK_CHILDREN)
+    item.m_children = (int)m_hasChildren;
+  if ((item.m_mask & wxTREE_MASK_DATA) == wxTREE_MASK_DATA)
+    item.m_data = m_data;
+};
+
+bool wxGenericTreeItem::HasChildren(void)
+{
+  return m_hasChildren;
+};
+
+bool wxGenericTreeItem::HasPlus(void)
+{
+  return (m_hasChildren && (m_children.Number() == 0));
+};
+
+int wxGenericTreeItem::NumberOfVisibleDescendents(void)
+{
+  int ret = m_children.Number();
+  wxNode *node = m_children.First();
+  while (node)
+  {
+    wxGenericTreeItem *item = (wxGenericTreeItem*)node->Data();
+    ret += item->NumberOfVisibleDescendents();
+    node = node->Next();
+  };
+  return ret;
+};
+
+int wxGenericTreeItem::NumberOfVisibleChildren(void)
+{
+  return m_children.Number();
+};
+
+wxGenericTreeItem *wxGenericTreeItem::FindItem( long itemId ) const
+{
+  if (m_itemId == itemId) return (wxGenericTreeItem*)(this);
+  wxNode *node = m_children.First();
+  while (node)
+  {
+    wxGenericTreeItem *item = (wxGenericTreeItem*)node->Data();
+    wxGenericTreeItem *res = item->FindItem( itemId );
+    if (res) return (wxGenericTreeItem*)(res);
+    node = node->Next();
+  };
+  return NULL;
+};
+
+void wxGenericTreeItem::AddChild( wxGenericTreeItem *child )
+{
+  m_children.Append( child );
+};
+
+void wxGenericTreeItem::SetCross( int x, int y )
+{
+  m_xCross = x;
+  m_yCross = y;
+};
+
+void wxGenericTreeItem::GetSize( int &x, int &y )
+{
+  if (y < m_y + 10) y = m_y +10;
+  int width = m_x +  m_width;
+  if (width > x) x = width;
+  wxNode *node = m_children.First();
+  while (node)
+  {
+    wxGenericTreeItem *item = (wxGenericTreeItem*)node->Data();
+    item->GetSize( x, y );
+    node = node->Next();
+  };
+};
+
+long wxGenericTreeItem::HitTest( const wxPoint& point, int &flags )
+{
+  if (m_parent && ((point.y > m_y) && (point.y < m_y+m_height)))
+  {
+    if ((point.x > m_xCross-5) &&
+        (point.x < m_xCross+5) &&
+        (point.y > m_yCross-5) &&
+        (point.y < m_yCross+5) &&
+	(m_hasChildren)
+       )
+    {
+      flags = wxTREE_HITTEST_ONITEMBUTTON;
+      return m_itemId;
+    };
+    if ((point.x > m_x) && (point.x < m_x+m_width))
+    {
+      flags = wxTREE_HITTEST_ONITEMLABEL;
+      return m_itemId;
+    };
+    if (point.x > m_x)
+    {
+      flags = wxTREE_HITTEST_ONITEMRIGHT;
+      return m_itemId;
+    };
+    flags = wxTREE_HITTEST_ONITEMINDENT;
+    return m_itemId;
+  }
+  else
+  {
+    wxNode *node = m_children.First();
+    while (node)
+    {
+      wxGenericTreeItem *child = (wxGenericTreeItem*)node->Data();
+      long res = child->HitTest( point, flags );
+      if (res != -1) return res;
+      node = node->Next();
+    };
+  };
+  return -1;
+};
+
+void wxGenericTreeItem::PrepareEvent( wxTreeEvent &event )
+{
+  event.m_item.m_itemId = m_itemId;
+  event.m_item.m_state = m_state;
+  event.m_item.m_text = m_text;
+  event.m_item.m_image = m_image;
+  event.m_item.m_selectedImage = m_selectedImage;
+  event.m_item.m_children = (int)m_hasChildren;
+  event.m_item.m_data = m_data;
+  event.m_oldItem = 0;
+  event.m_code = 0;
+  event.m_pointDrag.x = 0;
+  event.m_pointDrag.y = 0;
+};
+
+void wxGenericTreeItem::SendKeyDown( wxWindow *target )
+{
+  wxTreeEvent event( wxEVT_COMMAND_TREE_KEY_DOWN, target->GetId() );
+  PrepareEvent( event );
+  event.SetEventObject( target );
+  target->ProcessEvent( event );
+};
+
+void wxGenericTreeItem::SendSelected( wxWindow *target )
+{
+  wxTreeEvent event( wxEVT_COMMAND_TREE_SEL_CHANGED, target->GetId() );
+  PrepareEvent( event );
+  event.SetEventObject( target );
+  target->ProcessEvent( event );
+};
+
+void wxGenericTreeItem::SendDelete( wxWindow *target )
+{
+  wxTreeEvent event( wxEVT_COMMAND_TREE_DELETE_ITEM,
+ target->GetId() );
+  PrepareEvent( event );
+  event.SetEventObject( target );
+  target->ProcessEvent( event );
+};
+
+void wxGenericTreeItem::SendExpand( wxWindow *target )
+{
+  wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_EXPANDED,
+ target->GetId() );
+  PrepareEvent( event );
+  event.SetEventObject( target );
+  target->ProcessEvent( event );
+};
+
+void wxGenericTreeItem::SetHilight( bool set )
+{
+  m_hasHilight = set;
+};
+
+bool wxGenericTreeItem::HasHilight(void)
+{
+  return m_hasHilight;
+};
+
+//-----------------------------------------------------------------------------
+// wxTreeCtrl
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl,wxScrolledWindow
+)
+
+BEGIN_EVENT_TABLE(wxTreeCtrl,wxScrolledWindow)
+  EVT_PAINT          (wxTreeCtrl::OnPaint)
+  EVT_MOUSE_EVENTS   (wxTreeCtrl::OnMouse)
+  EVT_CHAR           (wxTreeCtrl::OnChar)
+  EVT_SET_FOCUS      (wxTreeCtrl::OnSetFocus)
+  EVT_KILL_FOCUS     (wxTreeCtrl::OnKillFocus)
+END_EVENT_TABLE()
+
+wxTreeCtrl::wxTreeCtrl(void)
+{
+  m_current = NULL;
+  m_anchor = NULL;
+  m_hasFocus = FALSE;
+  m_xScroll = 0;
+  m_yScroll = 0;
+  m_lastId = 0;
+  m_lineHeight = 10;
+  m_indent = 15;
+  m_isCreated = FALSE;
+  m_dc = NULL;
+  m_hilightBrush = new wxBrush( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHT), wxSOLID );
+};
+
+wxTreeCtrl::wxTreeCtrl(wxWindow *parent, const wxWindowID id,
+            const wxPoint& pos,
+ const wxSize& size,
+            const long style, const wxString& name )
+{
+  m_current = NULL;
+  m_anchor = NULL;
+  m_hasFocus = FALSE;
+  m_xScroll = 0;
+  m_yScroll = 0;
+  m_lastId = 0;
+  m_lineHeight = 10;
+  m_indent = 15;
+  m_isCreated = FALSE;
+  m_dc = NULL;
+  m_hilightBrush = new wxBrush( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHT), wxSOLID );
+  Create( parent, id, pos, size, style, name );
+};
+
+wxTreeCtrl::~wxTreeCtrl(void)
+{
+  if (m_dc) delete m_dc;
+};
+
+bool wxTreeCtrl::Create(wxWindow *parent, const wxWindowID id,
+            const wxPoint& pos,
+ const wxSize& size,
+            const long style
+, const wxString& name )
+{
+  wxScrolledWindow::Create( parent, id, pos, size, style, name );
+  SetBackgroundColour( *wxWHITE );
+  m_dottedPen = wxPen( *wxBLACK, 0, 0 );
+  return TRUE;
+};
+
+int wxTreeCtrl::GetCount(void) const
+{
+  if (!m_anchor) return 0;
+  return m_anchor->NumberOfVisibleDescendents();
+};
+
+long wxTreeCtrl::InsertItem( const long parent, const wxString& label, const int image,
+      const int selImage, const long WXUNUSED(insertAfter) )
+{
+  wxGenericTreeItem *p = NULL;
+  if (parent == 0)
+  {
+    if (m_anchor) return -1;
+  }
+  else
+  {
+    p = FindItem( parent );
+    if (!p) return -1;
+  };
+  wxTreeItem item;
+  m_lastId++;
+  item.m_mask = wxTREE_MASK_HANDLE;
+  item.m_itemId = m_lastId;
+  if (!label.IsNull() || (label == ""))
+  {
+    item.m_text = label;
+    item.m_mask |= wxTREE_MASK_TEXT;
+  };
+  if (image >= 0)
+  {
+    item.m_image = image;
+    item.m_mask |= wxTREE_MASK_IMAGE;
+  };
+  if (selImage >= 0)
+  {
+    item.m_selectedImage = selImage;
+    item.m_mask |= wxTREE_MASK_SELECTED_IMAGE;
+  };
+  
+  wxClientDC dc(this);
+  wxGenericTreeItem *new_child = new wxGenericTreeItem( p, item, &dc );
+  if (p) 
+    p->AddChild( new_child );
+  else
+    m_anchor = new_child;
+    
+  if (p)
+  {
+    CalculatePositions();
+    
+    int ch = 0;
+    GetClientSize( NULL, &ch );
+    
+    wxRectangle rect;
+    rect.x = 0; rect.y = 0;
+    rect.width = 10000; rect.height = ch;
+    
+    PrepareDC( dc );
+    if (p->m_children.Number() == 1)
+    {
+      rect.y = dc.LogicalToDeviceY( p->m_y );
+    }
+    else
+    {
+      wxNode *node = p->m_children.Member( new_child )->Previous();
+      wxGenericTreeItem* last_child = (wxGenericTreeItem*)node->Data();
+      rect.y = dc.LogicalToDeviceY( last_child->m_y );
+    };
+    
+    long doX = 0;
+    long doY = 0;
+    dc.GetDeviceOrigin( &doX, &doY );
+    rect.height = ch-rect.y-doY;
+    
+    AdjustMyScrollbars();
+    
+    if (rect.height > 0) Refresh( FALSE, &rect);
+  }
+  else
+  {
+    AdjustMyScrollbars();
+    
+    Refresh();
+  };
+  
+  return m_lastId;
+};
+
+long wxTreeCtrl::InsertItem( const long parent, wxTreeItem &info, const long WXUNUSED(insertAfter) )
+{
+  int oldMask = info.m_mask;
+  wxGenericTreeItem *p = NULL;
+  if (parent == 0)
+  {
+    if (m_anchor) return -1;
+  }
+  else
+  {
+    p = FindItem( parent );
+    if (!p)
+    {
+      printf( "TreeItem not found.\n" );
+      return -1;
+    };
+  };
+  long ret = 0;
+  if ((info.m_mask & wxTREE_MASK_HANDLE) == 0)
+  {
+    m_lastId++;
+    info.m_itemId = m_lastId;
+    info.m_mask |= wxTREE_MASK_HANDLE;
+    ret = m_lastId;
+  }
+  else
+  {
+    ret = info.m_itemId;
+  };
+  
+  wxClientDC dc(this);
+  wxGenericTreeItem *new_child = new wxGenericTreeItem( p, info, &dc );
+  if (p) 
+    p->AddChild( new_child );
+  else
+    m_anchor = new_child;
+    
+  if (p)
+  {
+    CalculatePositions();
+    
+    int ch = 0;
+    GetClientSize( NULL, &ch );
+    
+    wxRectangle rect;
+    rect.x = 0; rect.y = 0;
+    rect.width = 10000; rect.height = ch;
+    
+    PrepareDC( dc );
+    if (p->m_children.Number() == 1)
+    {
+      rect.y = dc.LogicalToDeviceY( p->m_y );
+    }
+    else
+    {
+      wxNode *node = p->m_children.Member( new_child )->Previous();
+      wxGenericTreeItem* last_child = (wxGenericTreeItem*)node->Data();
+      rect.y = dc.LogicalToDeviceY( last_child->m_y );
+    };
+    
+    long doX = 0;
+    long doY = 0;
+    dc.GetDeviceOrigin( &doX, &doY );
+    rect.height = ch-rect.y-doY;
+    
+    AdjustMyScrollbars();
+    
+    if (rect.height > 0) Refresh( FALSE, &rect);
+  }
+  else
+  {
+    AdjustMyScrollbars();
+    
+    Refresh();
+  };
+  
+  info.m_mask = oldMask;
+  return ret;
+};
+
+bool wxTreeCtrl::ExpandItem( const long item, const int action )
+{
+  wxGenericTreeItem *i = FindItem( item );
+  if (!i) return FALSE;
+  switch (action)
+  {
+    case wxTREE_EXPAND_EXPAND:
+    {
+      i->SendExpand( this );
+      break;
+    };
+    case wxTREE_EXPAND_COLLAPSE_RESET:
+    case wxTREE_EXPAND_COLLAPSE:
+    {
+      wxNode *node = i->m_children.First();
+      while (node)
+      {
+        wxGenericTreeItem *child = (wxGenericTreeItem*)node->Data();
+        child->SendDelete( this );
+	delete node;
+	node = i->m_children.First();
+      };
+      
+      int cw = 0;
+      int ch = 0;
+      GetClientSize( &cw, &ch );
+      wxRect rect;
+      rect.x = 0;
+      rect.width = cw;
+      wxClientDC dc(this);
+      PrepareDC(dc);
+      rect.y = dc.LogicalToDeviceY( i->m_y );
+      
+      long doY = 0;
+      dc.GetDeviceOrigin( NULL, &doY );
+      rect.height = ch-rect.y-doY;
+      Refresh( TRUE, &rect );
+      
+      AdjustMyScrollbars();
+      break;
+    };
+    case wxTREE_EXPAND_TOGGLE:
+    {
+      if (i->HasPlus())
+        ExpandItem( item, wxTREE_EXPAND_EXPAND );
+      else
+        ExpandItem( item, wxTREE_EXPAND_COLLAPSE );
+      break;
+    };
+  };
+  return TRUE;
+};
+
+bool wxTreeCtrl::DeleteAllItems(void)
+{
+  delete m_anchor;
+  m_anchor = NULL;
+  Refresh();
+  return TRUE;
+};
+
+bool wxTreeCtrl::GetItem( wxTreeItem &info ) const
+{
+  wxGenericTreeItem *i = FindItem( info.m_itemId );
+  if (!i) return FALSE;
+  i->GetItem( info );
+  return TRUE;
+};
+
+long wxTreeCtrl::GetItemData( const long item ) const
+{
+  wxGenericTreeItem *i = FindItem( item );
+  if (!i) return 0;
+  return i->m_data;
+};
+
+wxString wxTreeCtrl::GetItemText( const long item ) const
+{
+  wxGenericTreeItem *i = FindItem( item );
+  if (!i) return "";
+  return i->m_text;
+};
+
+long wxTreeCtrl::GetParent( const long item ) const
+{
+  wxGenericTreeItem *i = FindItem( item );
+  if (!i) return -1;
+  i = i->m_parent;
+  if (!i) return -1;
+  return i->m_parent->m_itemId;
+};
+
+long wxTreeCtrl::GetRootItem(void) const
+{
+  if (m_anchor) return m_anchor->m_itemId;
+  return -1;
+};
+
+long wxTreeCtrl::GetSelection(void) const
+{
+  return 0;
+};
+
+bool wxTreeCtrl::SelectItem( const long WXUNUSED(item) ) const
+{
+  return FALSE;
+};
+
+bool wxTreeCtrl::ItemHasChildren( const long item ) const
+{
+  wxGenericTreeItem *i = FindItem( item );
+  if (!i) return FALSE;
+  return i->m_hasChildren;
+};
+
+void wxTreeCtrl::SetIndent( const int indent )
+{
+  m_indent = indent;
+  Refresh();
+};
+
+int wxTreeCtrl::GetIndent(void) const
+{
+  return m_indent;
+};
+
+bool wxTreeCtrl::SetItem( wxTreeItem &info )
+{
+  wxGenericTreeItem *i = FindItem( info.m_itemId );
+  if (!i) return FALSE;
+  wxClientDC dc(this);
+  i->SetItem( info, &dc );
+  return TRUE;
+};
+
+bool wxTreeCtrl::SetItemData( const long item, const long data )
+{
+  wxGenericTreeItem *i = FindItem( item );
+  if (!i) return FALSE;
+  i->m_data = data;
+  return TRUE;
+};
+
+bool wxTreeCtrl::SetItemText( const long item, const wxString &text )
+{
+  wxGenericTreeItem *i = FindItem( item );
+  if (!i) return FALSE;
+  wxClientDC dc(this);
+  i->SetText( text, &dc );
+  return TRUE;
+};
+
+long wxTreeCtrl::HitTest( const wxPoint& point, int &flags )
+{
+  flags = 0;
+  if (!m_anchor) return -1;
+  return m_anchor->HitTest( point, flags );
+};
+
+void wxTreeCtrl::AdjustMyScrollbars(void)
+{
+  if (m_anchor)
+  {
+    int x = 0;
+    int y = 0;
+    m_anchor->GetSize( x, y );
+    y += 2*m_lineHeight;
+    int x_pos = GetScrollPos( wxHORIZONTAL );
+    int y_pos = GetScrollPos( wxVERTICAL );
+    SetScrollbars( 10, 10, x/10, y/10, x_pos, y_pos );
+  }
+  else
+  {
+    SetScrollbars( 0, 0, 0, 0 );
+  };
+};
+
+void wxTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxPaintDC &dc, int level, int &y )
+{
+  int horizX = level*m_indent+10;
+  int oldY = y;
+  wxNode *node = item->m_children.First();
+  while (node)
+  {
+    wxGenericTreeItem *child = (wxGenericTreeItem *)node->Data();
+    dc.SetPen( m_dottedPen );
+    
+    child->SetCross( horizX+15, y );
+    
+    if (!node->Next())
+    {
+      if (level != 0) oldY -= (m_lineHeight-5);
+      dc.DrawLine( horizX, oldY, horizX, y );
+    };
+    
+    child->m_x = horizX+33;
+    child->m_y = y-m_lineHeight/3;
+    child->m_height = m_lineHeight;
+    
+    if (IsExposed( 0, child->m_y-2, 10000, m_lineHeight+4 ))
+    {
+      int startX,endX; 
+      if ((node->Previous()) || (level != 0)) 
+        startX = horizX; else startX = horizX-10;
+      if (child->HasChildren()) 
+        endX = horizX+10; else endX = horizX+30;
+      dc.DrawLine( startX, y, endX, y );
+      
+      if  (child->HasChildren())
+      {
+        dc.DrawLine( horizX+20, y, horizX+30, y );
+        dc.SetPen( *wxGREY_PEN );
+        dc.DrawRectangle( horizX+10, y-4, 11, 9 );
+        dc.SetPen( *wxBLACK_PEN );
+        dc.DrawLine( horizX+13, y, horizX+17, y );
+        if (child->HasPlus())
+          dc.DrawLine( horizX+15, y-2, horizX+15, y+2 );
+      };
+    
+      if (child->HasHilight())
+      {
+	dc.SetTextForeground( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_HIGHLIGHTTEXT ) );
+	dc.SetBrush( *m_hilightBrush );
+	if (m_hasFocus)
+	  dc.SetPen( wxBLACK_PEN );
+	else
+	  dc.SetPen( wxTRANSPARENT_PEN );
+	long tw = 0;
+	long th = 0;
+	dc.GetTextExtent( child->m_text, &tw, &th );
+	dc.DrawRectangle( child->m_x-2, child->m_y-2, tw+4, th+4 );
+      };
+      
+      dc.DrawText( child->m_text, child->m_x, child->m_y );
+
+      if (child->HasHilight())
+      {
+	dc.SetTextForeground( *wxBLACK );
+	dc.SetBrush( *wxWHITE_BRUSH );
+	dc.SetPen( *wxBLACK_PEN );
+      };
+      
+    };
+          
+    y += m_lineHeight;
+    if (child->NumberOfVisibleChildren() > 0) 
+      PaintLevel( child, dc, level+1, y );
+    node = node->Next();
+  };
+};
+
+void wxTreeCtrl::OnPaint( const wxPaintEvent &WXUNUSED(event) )
+{
+  if (!m_anchor) return;
+
+  if (!m_dc)
+  { 
+    m_dc = new wxPaintDC(this);
+    PrepareDC( *m_dc );
+  };
+    
+  m_dc->SetFont( wxSystemSettings::GetSystemFont( wxSYS_SYSTEM_FONT ) );
+  
+  m_dc->SetPen( m_dottedPen );
+  m_lineHeight = (int)(m_dc->GetCharHeight() + 4);
+  
+  int y = m_lineHeight / 2 + 2;
+  PaintLevel( m_anchor, *m_dc, 0, y );
+};
+
+void wxTreeCtrl::OnSetFocus( const wxFocusEvent &WXUNUSED(event) )
+{
+  m_hasFocus = TRUE;
+  if (m_current) RefreshLine( m_current );
+};
+
+void wxTreeCtrl::OnKillFocus( const wxFocusEvent &WXUNUSED(event) )
+{
+  m_hasFocus = FALSE;
+  if (m_current) RefreshLine( m_current );
+};
+
+void wxTreeCtrl::OnChar( wxKeyEvent &event )
+{
+  event.Skip();
+};
+
+void wxTreeCtrl::OnMouse( const wxMouseEvent &event )
+{
+  if (!event.LeftDown() &&
+      !event.LeftDClick()) return;
+  
+  wxClientDC dc(this);
+  PrepareDC(dc);
+  long x = dc.DeviceToLogicalX( (long)event.GetX() );
+  long y = dc.DeviceToLogicalY( (long)event.GetY() );
+  
+  int flag = 0;
+  long id = HitTest( wxPoint(x,y), flag );
+  if (id == -1) return;
+  wxGenericTreeItem *item = FindItem( id );
+  
+  if (!item) return;
+  if ((flag != wxTREE_HITTEST_ONITEMBUTTON) &&
+      (flag != wxTREE_HITTEST_ONITEMLABEL)) return;
+  
+  if (m_current != item)
+  {
+    if (m_current)
+    {
+      m_current->SetHilight( FALSE );
+      RefreshLine( m_current );
+    };
+    m_current = item;
+    m_current->SetHilight( TRUE );
+    RefreshLine( m_current );
+    m_current->SendSelected( this );
+  };
+  
+  if (event.LeftDClick()) m_current->SendKeyDown( this );
+  
+  if (flag == wxTREE_HITTEST_ONITEMBUTTON)
+  {
+    ExpandItem( item->m_itemId, wxTREE_EXPAND_TOGGLE );
+    return;
+  };
+};
+
+void wxTreeCtrl::CalculateLevel( wxGenericTreeItem *item, wxPaintDC &dc, int level, int &y )
+{
+  int horizX = level*m_indent+10;
+  wxNode *node = item->m_children.First();
+  while (node)
+  {
+    wxGenericTreeItem *child = (wxGenericTreeItem *)node->Data();
+    dc.SetPen( m_dottedPen );
+    
+    int startX,endX; 
+    if ((node->Previous()) || (level != 0)) 
+      startX = horizX; else startX = horizX-10;
+    if (child->HasChildren()) 
+      endX = horizX+10; else endX = horizX+30;
+    
+    child->m_x = horizX+33;
+    child->m_y = y-m_lineHeight/3-2;
+    child->m_height = m_lineHeight;
+    
+    y += m_lineHeight;
+    if (child->NumberOfVisibleChildren() > 0) 
+      CalculateLevel( child, dc, level+1, y );
+      
+    node = node->Next();
+  };
+};
+
+void wxTreeCtrl::CalculatePositions(void)
+{
+  if (!m_anchor) return;
+ 
+  wxClientDC dc(this);
+  PrepareDC( dc );
+    
+  dc.SetFont( wxSystemSettings::GetSystemFont( wxSYS_SYSTEM_FONT ) );
+  
+  dc.SetPen( m_dottedPen );
+  m_lineHeight = (int)(dc.GetCharHeight() + 4);
+  
+  int y = m_lineHeight / 2 + 2;
+  CalculateLevel( m_anchor, dc, 0, y );
+};
+
+wxGenericTreeItem *wxTreeCtrl::FindItem( long itemId ) const
+{
+  if (!m_anchor) return NULL;
+  return m_anchor->FindItem( itemId );
+};
+
+void wxTreeCtrl::RefreshLine( wxGenericTreeItem *item )
+{
+  if (!item) return;
+  wxClientDC dc(this);
+  PrepareDC( dc );
+  wxRect rect;
+  rect.x = dc.LogicalToDeviceX( item->m_x-2 );
+  rect.y = dc.LogicalToDeviceY( item->m_y-2 );
+  rect.width = 1000;
+  rect.height = dc.GetCharHeight()+4;
+  Refresh( TRUE, &rect );
+};
+
+
+
diff --git a/src/gtk/app.cpp b/src/gtk/app.cpp
new file mode 100644
index 0000000000..47c1ee0a72
--- /dev/null
+++ b/src/gtk/app.cpp
@@ -0,0 +1,279 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        app.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "app.h"
+#endif
+
+#include "wx/app.h"
+#include "wx/gdicmn.h"
+#include "wx/utils.h"
+#include "wx/postscrp.h"
+#include "wx/intl.h"
+#include "wx/log.h"
+
+#include "unistd.h"
+
+#ifdef USE_GDK_IMLIB
+#include "gdk_imlib.h"
+#endif
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+wxApp *wxTheApp = NULL;
+wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
+
+extern wxList wxPendingDelete;
+
+//-----------------------------------------------------------------------------
+// local functions
+//-----------------------------------------------------------------------------
+
+extern void wxFlushResources(void);
+
+//-----------------------------------------------------------------------------
+// global functions
+//-----------------------------------------------------------------------------
+
+void wxExit(void)
+{
+  gtk_main_quit();
+};
+
+bool wxYield(void)
+{
+  while (gtk_events_pending() > 0) gtk_main_iteration();
+  return TRUE;
+};
+
+//-----------------------------------------------------------------------------
+// wxApp
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxApp,wxEvtHandler)
+
+gint wxapp_idle_callback( gpointer WXUNUSED(data) )
+{
+  if (wxTheApp) wxTheApp->OnIdle();
+  usleep( 10000 );
+  return TRUE;
+};
+
+wxApp::wxApp()
+{
+  m_idleTag = 0;
+  m_topWindow = NULL;
+  m_exitOnFrameDelete = TRUE;
+};
+
+wxApp::~wxApp(void)
+{
+  gtk_idle_remove( m_idleTag );
+};
+
+bool wxApp::OnInit(void)
+{
+  return TRUE;
+};
+
+bool wxApp::OnInitGui(void)
+{ 
+  m_idleTag = gtk_idle_add( wxapp_idle_callback, NULL );
+  return TRUE; 
+};
+
+int wxApp::OnRun(void) 
+{ 
+  return MainLoop(); 
+};
+
+bool wxApp::OnIdle(void)
+{
+  DeletePendingObjects();
+  return FALSE;
+};
+
+int wxApp::OnExit(void)
+{
+  return 0;
+};
+
+int wxApp::MainLoop(void)
+{
+  gtk_main();
+  return 0;
+};
+
+void wxApp::ExitMainLoop(void)
+{
+  gtk_main_quit();
+};
+
+bool wxApp::Initialized(void)
+{
+  return m_initialized;
+};
+
+bool wxApp::Pending(void) 
+{
+  return FALSE;
+};
+
+void wxApp::Dispatch(void) 
+{
+};
+
+void wxApp::DeletePendingObjects(void)
+{
+  wxNode *node = wxPendingDelete.First();
+  while (node)
+  {
+    wxObject *obj = (wxObject *)node->Data();
+    
+    delete obj;
+
+    if (wxPendingDelete.Member(obj))
+      delete node;
+
+    node = wxPendingDelete.First();
+  };
+};
+
+wxWindow *wxApp::GetTopWindow(void)
+{
+  if (m_topWindow) return m_topWindow;
+  wxNode *node = wxTopLevelWindows.First();
+  if (!node) return NULL;
+  return (wxWindow*)node->Data();
+};
+
+void wxApp::SetTopWindow( wxWindow *win )
+{
+  m_topWindow = win;
+};
+
+void wxApp::CommonInit(void)
+{
+
+/*
+#if USE_RESOURCES
+  (void) wxGetResource("wxWindows", "OsVersion", &wxOsVersion);
+#endif
+*/
+
+  wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
+  wxTheColourDatabase->Initialize();
+  wxInitializeStockObjects();
+
+  // For PostScript printing
+#if USE_POSTSCRIPT
+  wxInitializePrintSetupData();
+  wxThePrintPaperDatabase = new wxPrintPaperDatabase;
+  wxThePrintPaperDatabase->CreateDatabase();
+#endif
+
+
+/*
+  wxBitmap::InitStandardHandlers();
+
+  g_globalCursor = new wxCursor;
+*/
+
+  wxInitializeStockObjects();
+};
+
+void wxApp::CommonCleanUp(void)
+{
+  wxDeleteStockObjects();
+  
+  wxFlushResources();
+};
+    
+wxLog *wxApp::CreateLogTarget()
+{
+  return new wxLogGui;
+}
+
+//-----------------------------------------------------------------------------
+// wxEntry
+//-----------------------------------------------------------------------------
+
+int wxEntry( int argc, char *argv[] )
+{
+  wxBuffer = new char[BUFSIZ + 512];
+
+  wxClassInfo::InitializeClasses();
+  
+  if (!wxTheApp)
+  {
+    if (!wxApp::GetInitializerFunction())
+    {
+      printf( "wxWindows error: No initializer - use IMPLEMENT_APP macro.\n" );
+      return 0;
+    };
+    
+    wxAppInitializerFunction app_ini = wxApp::GetInitializerFunction();
+    
+    wxObject *test_app = app_ini();
+    
+    wxTheApp = (wxApp*) test_app;
+    
+//    wxTheApp = (wxApp*)( app_ini() );
+  };
+  
+  if (!wxTheApp) 
+  {
+    printf( "wxWindows error: wxTheApp == NULL\n" );
+    return 0;
+  };
+
+//  printf( "Programmstart.\n" );
+  
+  wxTheApp->argc = argc;
+  wxTheApp->argv = argv;
+  
+  gtk_init( &argc, &argv );
+
+#ifdef USE_GDK_IMLIB
+
+  gdk_imlib_init();
+  
+  gtk_widget_push_visual(gdk_imlib_get_visual());
+  
+  gtk_widget_push_colormap(gdk_imlib_get_colormap());
+  
+#endif  
+    
+  wxApp::CommonInit();
+
+  wxTheApp->OnInitGui();
+
+  // Here frames insert themselves automatically
+  // into wxTopLevelWindows by getting created
+  // in OnInit().
+  
+  if (!wxTheApp->OnInit()) return 0;
+
+  wxTheApp->m_initialized = (wxTopLevelWindows.Number() > 0);
+  
+  int retValue = 0;
+  
+  if (wxTheApp->Initialized()) retValue = wxTheApp->OnRun();
+  
+  wxTheApp->DeletePendingObjects();  
+  
+  wxTheApp->OnExit();
+  
+  wxApp::CommonCleanUp();
+  
+  return retValue;
+};
diff --git a/src/gtk/bdiag.xbm b/src/gtk/bdiag.xbm
new file mode 100644
index 0000000000..9ff0a1822f
--- /dev/null
+++ b/src/gtk/bdiag.xbm
@@ -0,0 +1,6 @@
+#define bdiag_width 16
+#define bdiag_height 16
+static char bdiag_bits[] = {
+   0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04,
+   0x02, 0x02, 0x01, 0x01, 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10,
+   0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x01, 0x01};
diff --git a/src/gtk/bitmap.cpp b/src/gtk/bitmap.cpp
new file mode 100644
index 0000000000..ebb2fe5d6a
--- /dev/null
+++ b/src/gtk/bitmap.cpp
@@ -0,0 +1,293 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        bitmap.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "bitmap.h"
+#endif
+
+#include "wx/bitmap.h"
+#include "gdk/gdkprivate.h"
+
+#ifdef USE_GDK_IMLIB
+#include "gdk_imlib.h"
+#endif
+
+//-----------------------------------------------------------------------------
+// wxMask
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxMask,wxObject)
+
+wxMask::wxMask(void)
+{
+  m_bitmap = NULL;
+};
+
+wxMask::wxMask( const wxBitmap& WXUNUSED(bitmap), const wxColour& WXUNUSED(colour) )
+{
+};
+
+wxMask::wxMask( const wxBitmap& WXUNUSED(bitmap), const int WXUNUSED(paletteIndex) )
+{
+};
+
+wxMask::wxMask( const wxBitmap& WXUNUSED(bitmap) )
+{
+};
+
+wxMask::~wxMask(void)
+{
+#ifdef USE_GDK_IMLIB
+  // do not delete the mask, gdk_imlib does it for you
+#else
+  if (m_bitmap) gdk_bitmap_unref( m_bitmap );
+#endif  
+};
+
+GdkBitmap *wxMask::GetBitmap(void) const
+{
+  return m_bitmap;
+};
+  
+//-----------------------------------------------------------------------------
+// wxBitmap
+//-----------------------------------------------------------------------------
+
+class wxBitmapRefData: public wxObjectRefData
+{
+  public:
+  
+    wxBitmapRefData(void);
+    ~wxBitmapRefData(void);
+  
+    GdkPixmap      *m_pixmap;
+    wxMask         *m_mask;
+    int             m_width;
+    int             m_height;
+    int             m_bpp;
+    wxPalette      *m_palette;
+};
+
+wxBitmapRefData::wxBitmapRefData(void)
+{
+  m_pixmap = NULL;
+  m_mask = NULL;
+  m_width = 0;
+  m_height = 0;
+  m_bpp = 0;
+  m_palette = NULL;
+};
+
+wxBitmapRefData::~wxBitmapRefData(void)
+{
+#ifdef USE_GDK_IMLIB
+  if (m_pixmap) gdk_imlib_free_pixmap( m_pixmap );
+#else
+  if (m_pixmap) gdk_pixmap_unref( m_pixmap );
+#endif
+  if (m_mask) delete m_mask;
+  if (m_palette) delete m_palette;
+};
+
+//-----------------------------------------------------------------------------
+
+#define M_BMPDATA ((wxBitmapRefData *)m_refData)
+
+IMPLEMENT_DYNAMIC_CLASS(wxBitmap,wxGDIObject)
+
+wxBitmap::wxBitmap(void)
+{
+  if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
+};
+  
+wxBitmap::wxBitmap( const int width, const int height, const int depth )
+{
+  m_refData = new wxBitmapRefData();
+  M_BMPDATA->m_mask = NULL;
+  M_BMPDATA->m_pixmap = 
+    gdk_pixmap_new( (GdkWindow*) &gdk_root_parent, width, height, depth );
+  gdk_window_get_size( M_BMPDATA->m_pixmap, &(M_BMPDATA->m_width), &(M_BMPDATA->m_height) );
+  M_BMPDATA->m_bpp = depth;
+   
+  if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
+};
+
+wxBitmap::wxBitmap( char **bits )
+{
+  m_refData = new wxBitmapRefData();
+  
+  GdkBitmap *mask = NULL;
+
+#ifndef USE_GDK_IMLIB
+  M_BMPDATA->m_pixmap = 
+    gdk_pixmap_create_from_xpm_d( (GdkWindow*) &gdk_root_parent, &mask, NULL, (gchar **) bits );
+#else
+  M_BMPDATA->m_pixmap = NULL;
+  int res = gdk_imlib_data_to_pixmap( bits, &M_BMPDATA->m_pixmap, &mask );
+#endif
+  
+  if (mask)
+  {
+    M_BMPDATA->m_mask = new wxMask();
+    M_BMPDATA->m_mask->m_bitmap = mask;
+  };
+				  
+  gdk_window_get_size( M_BMPDATA->m_pixmap, &(M_BMPDATA->m_width), &(M_BMPDATA->m_height) );
+  M_BMPDATA->m_bpp = 24; // ?
+   
+  if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
+};
+  
+wxBitmap::wxBitmap( const wxBitmap& bmp )
+{
+  Ref( bmp );
+   
+  if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
+};
+  
+wxBitmap::wxBitmap( const wxBitmap* bmp )
+{
+  if (bmp) Ref( *bmp );
+   
+  if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
+};
+  
+wxBitmap::wxBitmap( const wxString &filename, const int type )
+{
+  LoadFile( filename, type );
+};
+
+wxBitmap::~wxBitmap(void)
+{
+  if (wxTheBitmapList) wxTheBitmapList->DeleteObject(this);
+};
+  
+wxBitmap& wxBitmap::operator = ( const wxBitmap& bmp )
+{
+  if (*this == bmp) return (*this); 
+  Ref( bmp ); 
+  return *this; 
+};
+  
+bool wxBitmap::operator == ( const wxBitmap& bmp )
+{
+  return m_refData == bmp.m_refData; 
+};
+  
+bool wxBitmap::operator != ( const wxBitmap& bmp )
+{
+  return m_refData != bmp.m_refData; 
+};
+  
+bool wxBitmap::Ok(void) const
+{
+  return m_refData != NULL;
+};
+  
+int wxBitmap::GetHeight(void) const
+{
+  if (!Ok()) return 0;
+  return M_BMPDATA->m_height;
+};
+
+int wxBitmap::GetWidth(void) const
+{
+  if (!Ok()) return 0;
+  return M_BMPDATA->m_width;
+};
+
+int wxBitmap::GetDepth(void) const
+{
+  if (!Ok()) return 0;
+  return M_BMPDATA->m_bpp;
+};
+
+void wxBitmap::SetHeight( const int height )
+{
+  if (!Ok()) return;
+  M_BMPDATA->m_height = height;
+};
+
+void wxBitmap::SetWidth( const int width )
+{
+  if (!Ok()) return;
+  M_BMPDATA->m_width = width;
+};
+
+void wxBitmap::SetDepth( const int depth )
+{
+  if (!Ok()) return;
+  M_BMPDATA->m_bpp = depth;
+};
+
+wxMask *wxBitmap::GetMask(void) const
+{
+  if (!Ok()) return NULL;
+  return M_BMPDATA->m_mask;
+};
+
+void wxBitmap::SetMask( wxMask *mask )
+{
+  if (!Ok()) return;
+  if (M_BMPDATA->m_mask) delete M_BMPDATA->m_mask;
+  M_BMPDATA->m_mask = mask;
+};
+
+bool wxBitmap::SaveFile( const wxString &WXUNUSED(name), const int WXUNUSED(type), 
+  wxPalette *WXUNUSED(palette) )
+{
+  return FALSE;
+};
+
+bool wxBitmap::LoadFile( const wxString &name, const int WXUNUSED(type) )
+{
+#ifdef USE_GDK_IMLIB
+
+  UnRef();
+  m_refData = new wxBitmapRefData();
+  M_BMPDATA->m_mask = NULL;
+
+  GdkBitmap *mask = NULL;
+  
+  int res = gdk_imlib_load_file_to_pixmap( WXSTRINGCAST name, &M_BMPDATA->m_pixmap, &mask );
+
+  if (res != 1)
+  {
+    UnRef();
+    return FALSE;
+  };
+
+  if (mask)
+  {
+    M_BMPDATA->m_mask = new wxMask();
+    M_BMPDATA->m_mask->m_bitmap = mask;
+  }
+				  
+  gdk_window_get_size( M_BMPDATA->m_pixmap, &(M_BMPDATA->m_width), &(M_BMPDATA->m_height) );
+  M_BMPDATA->m_bpp = 24; // ?
+  
+  return TRUE;
+#endif
+
+  return FALSE;
+};
+        
+wxPalette *wxBitmap::GetPalette(void) const
+{
+  if (!Ok()) return NULL;
+  return M_BMPDATA->m_palette;
+};
+
+GdkPixmap *wxBitmap::GetPixmap(void) const
+{
+  if (!Ok()) return NULL;
+  return M_BMPDATA->m_pixmap;
+};
+  
diff --git a/src/gtk/brush.cpp b/src/gtk/brush.cpp
new file mode 100644
index 0000000000..e8bfb06968
--- /dev/null
+++ b/src/gtk/brush.cpp
@@ -0,0 +1,132 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        brush.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "brush.h"
+#endif
+
+#include "wx/brush.h"
+
+//-----------------------------------------------------------------------------
+// wxBrush
+//-----------------------------------------------------------------------------
+
+class wxBrushRefData: public wxObjectRefData
+{
+  public:
+  
+    wxBrushRefData(void);
+  
+    int        m_style;
+    wxBitmap   m_stipple;
+    wxColour   m_colour;
+};
+
+wxBrushRefData::wxBrushRefData(void)
+{
+  m_style = 0;
+};
+
+//-----------------------------------------------------------------------------
+
+#define M_BRUSHDATA ((wxBrushRefData *)m_refData)
+
+IMPLEMENT_DYNAMIC_CLASS(wxBrush,wxGDIObject)
+
+wxBrush::wxBrush(void)
+{
+  if (wxTheBrushList) wxTheBrushList->AddBrush( this );
+};
+
+wxBrush::wxBrush( const wxColour &colour, const int style )
+{
+  m_refData = new wxBrushRefData();
+  M_BRUSHDATA->m_style = style;
+  M_BRUSHDATA->m_colour = colour;
+  
+  if (wxTheBrushList) wxTheBrushList->AddBrush( this );
+};
+
+wxBrush::wxBrush( const wxString &colourName, const int style )
+{
+  m_refData = new wxBrushRefData();
+  M_BRUSHDATA->m_style = style;
+  M_BRUSHDATA->m_colour = colourName;
+  
+  if (wxTheBrushList) wxTheBrushList->AddBrush( this );
+};
+
+wxBrush::wxBrush( const wxBitmap &stippleBitmap )
+{
+  m_refData = new wxBrushRefData();
+  M_BRUSHDATA->m_style = wxSTIPPLE;
+  M_BRUSHDATA->m_colour = *wxBLACK;
+  M_BRUSHDATA->m_stipple = stippleBitmap;
+  
+  if (wxTheBrushList) wxTheBrushList->AddBrush( this );
+};
+
+wxBrush::wxBrush( const wxBrush &brush )
+{
+  Ref( brush );
+  
+  if (wxTheBrushList) wxTheBrushList->AddBrush( this );
+};
+
+wxBrush::wxBrush( const wxBrush *brush )
+{
+  if (brush) Ref( *brush );
+  
+  if (wxTheBrushList) wxTheBrushList->Append( this );
+};
+
+wxBrush::~wxBrush(void)
+{
+  if (wxTheBrushList) wxTheBrushList->RemoveBrush( this );
+};
+
+wxBrush& wxBrush::operator = ( const wxBrush& brush )
+{
+  if (*this == brush) return (*this); 
+  Ref( brush ); 
+  return *this; 
+};
+  
+bool wxBrush::operator == ( const wxBrush& brush )
+{
+  return m_refData == brush.m_refData; 
+};
+
+bool wxBrush::operator != ( const wxBrush& brush )
+{
+  return m_refData != brush.m_refData; 
+};
+
+bool wxBrush::Ok(void) const
+{
+  return ((m_refData) && M_BRUSHDATA->m_colour.Ok());
+};
+
+int wxBrush::GetStyle(void) const
+{
+  return M_BRUSHDATA->m_style;
+};
+
+wxColour &wxBrush::GetColour(void) const
+{
+  return M_BRUSHDATA->m_colour;
+};
+
+wxBitmap *wxBrush::GetStipple(void) const
+{
+  return &M_BRUSHDATA->m_stipple;
+};
+
+
diff --git a/src/gtk/button.cpp b/src/gtk/button.cpp
new file mode 100644
index 0000000000..d4361f37b8
--- /dev/null
+++ b/src/gtk/button.cpp
@@ -0,0 +1,89 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        button.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "button.h"
+#endif
+
+#include "wx/button.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxButton;
+
+//-----------------------------------------------------------------------------
+// wxButton
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxButton,wxControl)
+
+void gtk_button_clicked_callback( GtkWidget *WXUNUSED(widget), gpointer data )
+{
+  wxButton *button = (wxButton*)data;
+  wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, button->GetId());
+  event.SetEventObject(button);
+  button->ProcessEvent(event);
+};
+
+//-----------------------------------------------------------------------------
+
+wxButton::wxButton(void)
+{
+};
+
+wxButton::wxButton( wxWindow *parent, wxWindowID id, const wxString &label,
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  Create( parent, id, label, pos, size, style, name );
+};
+
+bool wxButton::Create(  wxWindow *parent, wxWindowID id, const wxString &label,
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  m_needParent = TRUE;
+  
+  wxSize newSize = size;
+
+  PreCreation( parent, id, pos, newSize, style, name );
+  
+  m_label = label;
+  m_widget = gtk_button_new_with_label( label );
+  
+  if (newSize.x == -1) newSize.x = 15+gdk_string_measure( m_widget->style->font, label );
+  if (newSize.y == -1) newSize.y = 26;
+  SetSize( newSize.x, newSize.y );
+  
+  gtk_signal_connect( GTK_OBJECT(m_widget), "clicked", 
+    GTK_SIGNAL_FUNC(gtk_button_clicked_callback), (gpointer*)this );
+
+  PostCreation();
+  
+  Show( TRUE );
+    
+  return TRUE;
+};
+      
+void wxButton::SetDefault(void)
+{
+};
+
+void wxButton::SetLabel( const wxString &label )
+{
+  wxControl::SetLabel( label );
+};
+
+wxString wxButton::GetLabel(void) const
+{
+  return wxControl::GetLabel();
+};
diff --git a/src/gtk/cdiag.xbm b/src/gtk/cdiag.xbm
new file mode 100644
index 0000000000..15dc7ba86d
--- /dev/null
+++ b/src/gtk/cdiag.xbm
@@ -0,0 +1,6 @@
+#define cdiag_width 16
+#define cdiag_height 16
+static char cdiag_bits[] = {
+   0x81, 0x81, 0x42, 0x42, 0x24, 0x24, 0x18, 0x18, 0x18, 0x18, 0x24, 0x24,
+   0x42, 0x42, 0x81, 0x81, 0x81, 0x81, 0x42, 0x42, 0x24, 0x24, 0x18, 0x18,
+   0x18, 0x18, 0x24, 0x24, 0x42, 0x42, 0x81, 0x81};
diff --git a/src/gtk/checkbox.cpp b/src/gtk/checkbox.cpp
new file mode 100644
index 0000000000..57c712db39
--- /dev/null
+++ b/src/gtk/checkbox.cpp
@@ -0,0 +1,84 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        checkbox.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "checkbox.h"
+#endif
+
+#include "wx/checkbox.h"
+
+//-----------------------------------------------------------------------------
+// wxCheckBox
+//-----------------------------------------------------------------------------
+
+void gtk_checkbox_clicked_callback( GtkWidget *WXUNUSED(widget), gpointer data )
+{
+  wxCheckBox *cb = (wxCheckBox*)data;
+  wxCommandEvent event(wxEVT_COMMAND_CHECKBOX_CLICKED, cb->GetId());
+  event.SetInt( cb->GetValue() );
+  event.SetEventObject(cb);
+  cb->ProcessEvent(event);
+};
+
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxCheckBox,wxControl)
+
+wxCheckBox::wxCheckBox(void)
+{
+};
+
+wxCheckBox::wxCheckBox( wxWindow *parent, wxWindowID id, const wxString &label,
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  Create( parent, id, label, pos, size, style, name );
+};
+
+bool wxCheckBox::Create(  wxWindow *parent, wxWindowID id, const wxString &label,
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  m_needParent = TRUE;
+  
+  PreCreation( parent, id, pos, size, style, name );
+
+  m_widget = gtk_check_button_new_with_label( label );
+ 
+  wxSize newSize = size;
+  if (newSize.x == -1) newSize.x = 25+gdk_string_measure( m_widget->style->font, label );
+  if (newSize.y == -1) newSize.y = 26;
+  SetSize( newSize.x, newSize.y );
+   
+  gtk_signal_connect( GTK_OBJECT(m_widget), "clicked", 
+    GTK_SIGNAL_FUNC(gtk_checkbox_clicked_callback), (gpointer*)this );
+    
+  PostCreation();
+  
+  Show( TRUE );
+    
+  return TRUE;
+};
+
+void wxCheckBox::SetValue( const bool state )
+{
+  if (state)
+    gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(m_widget), GTK_STATE_ACTIVE );
+  else
+    gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(m_widget), GTK_STATE_NORMAL );
+};
+
+bool wxCheckBox::GetValue(void) const
+{
+  GtkToggleButton *tb = GTK_TOGGLE_BUTTON(m_widget);
+  return tb->active;
+};
+
diff --git a/src/gtk/choice.cpp b/src/gtk/choice.cpp
new file mode 100644
index 0000000000..a7c5ff028b
--- /dev/null
+++ b/src/gtk/choice.cpp
@@ -0,0 +1,198 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        choice.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "choice.h"
+#endif
+
+#include "wx/choice.h"
+
+//-----------------------------------------------------------------------------
+// wxChoice
+//-----------------------------------------------------------------------------
+
+void gtk_choice_clicked_callback( GtkWidget *WXUNUSED(widget), gpointer data )
+{
+  wxChoice *choice = (wxChoice*)data;
+  wxCommandEvent event(wxEVT_COMMAND_CHOICE_SELECTED, choice->GetId());
+  event.SetInt( choice->GetSelection() );
+  wxString tmp( choice->GetStringSelection() );
+  event.SetString( WXSTRINGCAST(tmp) );
+  event.SetEventObject(choice);
+  choice->ProcessEvent(event);
+};
+
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxChoice,wxWindow)
+
+wxChoice::wxChoice(void)
+{
+};
+
+wxChoice::wxChoice( wxWindow *parent, const wxWindowID id,
+      const wxPoint &pos, const wxSize &size, 
+      const int n, const wxString choices[],
+      const long style, const wxString &name )
+{
+  Create( parent, id, pos, size, n, choices, style, name );
+};
+
+bool wxChoice::Create( wxWindow *parent, const wxWindowID id,
+      const wxPoint &pos, const wxSize &size, 
+      const int n, const wxString choices[],
+      const long style, const wxString &name )
+{
+  m_needParent = TRUE;
+  
+  PreCreation( parent, id, pos, size, style, name );
+  
+  m_widget = gtk_option_menu_new();
+  
+  wxSize newSize = size;
+  if (newSize.x == -1) newSize.x = 80;
+  if (newSize.y == -1) newSize.y = 26;
+  SetSize( newSize.x, newSize.y );
+  
+  GtkWidget *menu;
+  menu = gtk_menu_new();
+  
+  for (int i = 0; i < n; i++)
+  {
+    GtkWidget *item;
+    item = gtk_menu_item_new_with_label( choices[i] );
+    gtk_signal_connect( GTK_OBJECT( item ), "activate", 
+      GTK_SIGNAL_FUNC(gtk_choice_clicked_callback), (gpointer*)this );
+    gtk_menu_append( GTK_MENU(menu), item );
+    gtk_widget_show( item );
+  };
+  gtk_option_menu_set_menu( GTK_OPTION_MENU(m_widget), menu );
+  
+  PostCreation();
+  
+  Show( TRUE );
+    
+  return TRUE;
+};
+      
+void wxChoice::Append( const wxString &item )
+{
+  GtkWidget *menu = gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) );
+  GtkWidget *menu_item;
+  menu_item = gtk_menu_item_new_with_label( item );
+  gtk_signal_connect( GTK_OBJECT( menu_item ), "activate", 
+    GTK_SIGNAL_FUNC(gtk_choice_clicked_callback), (gpointer*)this );
+  gtk_menu_append( GTK_MENU(menu), menu_item );
+  gtk_widget_show( menu_item );
+};
+ 
+void wxChoice::Clear(void)
+{
+  gtk_option_menu_remove_menu( GTK_OPTION_MENU(m_widget) );
+  GtkWidget *menu = gtk_menu_new();
+  gtk_option_menu_set_menu( GTK_OPTION_MENU(m_widget), menu );
+};
+
+int wxChoice::FindString( const wxString &string ) const
+{
+  // If you read this code once and you think you undestand
+  // it, then you are very wrong. RR
+  
+  GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
+  int count = 0;
+  GList *child = menu_shell->children;
+  while (child)
+  {
+    GtkBin *bin = GTK_BIN( child->data );
+    GtkLabel *label = GTK_LABEL(bin->child);
+    if (!label) label = GTK_LABEL( GTK_BUTTON(m_widget)->child );
+    if (string == label->label) return count;
+    child = child->next;
+    count++;
+  };
+  return -1;
+};
+
+int wxChoice::GetColumns(void) const
+{
+  return 1;
+};
+
+int wxChoice::GetSelection(void)
+{
+  GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
+  int count = 0;
+  GList *child = menu_shell->children;
+  while (child)
+  {
+    GtkBin *bin = GTK_BIN( child->data );
+    if (!bin->child) return count;
+    child = child->next;
+    count++;
+  };
+  return -1;
+};
+
+wxString wxChoice::GetString( const int n ) const
+{
+  GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
+  int count = 0;
+  GList *child = menu_shell->children;
+  while (child)
+  {
+    GtkBin *bin = GTK_BIN( child->data );
+    if (count == n)
+    {
+      GtkLabel *label = GTK_LABEL(bin->child);
+      if (!label) label = GTK_LABEL( GTK_BUTTON(m_widget)->child );
+      return label->label;
+    };
+    child = child->next;
+    count++;
+  };
+  return "";
+};
+
+wxString wxChoice::GetStringSelection(void) const
+{
+  GtkLabel *label = GTK_LABEL( GTK_BUTTON(m_widget)->child );
+  return label->label;
+};
+
+int wxChoice::Number(void) const
+{
+  GtkMenu *menu = GTK_MENU( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
+  int count = 0;
+  GList *child = menu->children;
+  while (child)
+  {
+    count++;
+    child = child->next;
+  };
+  return count;
+};
+
+void wxChoice::SetColumns( const int WXUNUSED(n) )
+{
+};
+
+void wxChoice::SetSelection( const int n )
+{
+  int tmp = n;
+  gtk_option_menu_set_history( GTK_OPTION_MENU(m_widget), (gint)tmp );
+};
+
+void wxChoice::SetStringSelection( const wxString &string )
+{
+  int n = FindString( string );
+  if (n != -1) SetSelection( n );
+};
+
diff --git a/src/gtk/colour.cpp b/src/gtk/colour.cpp
new file mode 100644
index 0000000000..ba970a79ba
--- /dev/null
+++ b/src/gtk/colour.cpp
@@ -0,0 +1,225 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        colour.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "colour.h"
+#endif
+
+#include "wx/gdicmn.h"
+
+#ifdef USE_GDK_IMLIB
+#include "gdk_imlib.h"
+#endif
+
+//-----------------------------------------------------------------------------
+// wxColour
+//-----------------------------------------------------------------------------
+
+class wxColourRefData: public wxObjectRefData
+{
+  public:
+  
+    wxColourRefData(void);
+    ~wxColourRefData(void);
+    void FreeColour(void);
+  
+    GdkColor     m_color;
+    GdkColormap *m_colormap;
+    bool         m_hasPixel;
+    
+    friend wxColour;
+};
+
+wxColourRefData::wxColourRefData(void)
+{
+  m_color.red = 0;
+  m_color.green = 0;
+  m_color.blue = 0;
+  m_color.pixel = 0;
+  m_colormap = NULL;
+  m_hasPixel = FALSE;
+};
+
+wxColourRefData::~wxColourRefData(void)
+{
+  FreeColour();
+};
+
+void wxColourRefData::FreeColour(void)
+{
+//  if (m_hasPixel) gdk_colors_free( m_colormap, &m_color, 1, 0 );
+};
+
+//-----------------------------------------------------------------------------
+
+#define M_COLDATA ((wxColourRefData *)m_refData)
+
+#define SHIFT (8*(sizeof(short int)-sizeof(char)))
+
+IMPLEMENT_DYNAMIC_CLASS(wxColour,wxGDIObject)
+
+wxColour::wxColour(void)
+{
+};
+
+wxColour::wxColour( char red, char green, char blue )
+{
+  m_refData = new wxColourRefData();
+  M_COLDATA->m_color.red = ((unsigned short)red) << SHIFT;
+  M_COLDATA->m_color.green = ((unsigned short)green) << SHIFT;
+  M_COLDATA->m_color.blue = ((unsigned short)blue) << SHIFT;
+  M_COLDATA->m_color.pixel = 0;
+};
+  
+wxColour::wxColour( const wxString &colourName )
+{
+  wxNode *node = NULL;
+  if ( (wxTheColourDatabase) && (node = wxTheColourDatabase->Find(colourName)) ) 
+  {
+    wxColour *col = (wxColour*)node->Data();
+    UnRef();
+    if (col) Ref( *col );
+  } 
+  else 
+  {
+    m_refData = new wxColourRefData();
+    if (!gdk_color_parse( colourName, &M_COLDATA->m_color ))
+    {
+      delete m_refData;
+      m_refData = NULL;
+    };
+  };
+};
+
+wxColour::wxColour( const wxColour& col )
+{ 
+  Ref( col ); 
+};
+
+wxColour::wxColour( const wxColour* col ) 
+{ 
+  if (col) Ref( *col ); 
+};
+
+wxColour::~wxColour(void)
+{
+};
+
+wxColour& wxColour::operator = ( const wxColour& col ) 
+{ 
+  if (*this == col) return (*this); 
+  Ref( col ); 
+  return *this; 
+};
+
+wxColour& wxColour::operator = ( const wxString& colourName ) 
+{ 
+  UnRef();
+  wxNode *node = NULL;
+  if ((wxTheColourDatabase) && (node = wxTheColourDatabase->Find(colourName)) ) 
+  {
+    wxColour *col = (wxColour*)node->Data();
+    if (col) Ref( *col );
+  } 
+  else 
+  {
+    m_refData = new wxColourRefData();
+    if (!gdk_color_parse( colourName, &M_COLDATA->m_color ))
+    {
+      delete m_refData;
+      m_refData = NULL;
+    };
+  };
+  return *this; 
+};
+
+bool wxColour::operator == ( const wxColour& col ) 
+{ 
+  return m_refData == col.m_refData; 
+};
+
+bool wxColour::operator != ( const wxColour& col) 
+{ 
+  return m_refData != col.m_refData; 
+};
+
+void wxColour::Set( const unsigned char red, const unsigned char green, const unsigned char blue )
+{
+  UnRef();
+  m_refData = new wxColourRefData();
+  M_COLDATA->m_color.red = ((unsigned short)red) << SHIFT;
+  M_COLDATA->m_color.green = ((unsigned short)green) << SHIFT;
+  M_COLDATA->m_color.blue = ((unsigned short)blue) << SHIFT;
+  M_COLDATA->m_color.pixel = 0;
+};
+
+unsigned char wxColour::Red(void) const
+{
+  if (!Ok()) return 0;
+  return (unsigned char)(M_COLDATA->m_color.red >> SHIFT);
+};
+
+unsigned char wxColour::Green(void) const
+{
+  if (!Ok()) return 0;
+  return (unsigned char)(M_COLDATA->m_color.green >> SHIFT);
+};
+
+unsigned char wxColour::Blue(void) const
+{
+  if (!Ok()) return 0;
+  return (unsigned char)(M_COLDATA->m_color.blue >> SHIFT);
+};
+
+bool wxColour::Ok(void) const
+{
+  return (m_refData);
+};
+
+void wxColour::CalcPixel( GdkColormap *cmap )
+{
+  if (!Ok()) return;
+  
+  if ((M_COLDATA->m_hasPixel) && (M_COLDATA->m_colormap == cmap)) return;
+  M_COLDATA->FreeColour();
+  
+#ifdef USE_GDK_IMLIB
+
+  int r = M_COLDATA->m_color.red >> SHIFT;
+  int g = M_COLDATA->m_color.green >> SHIFT;
+  int b = M_COLDATA->m_color.blue >> SHIFT;
+  M_COLDATA->m_hasPixel = TRUE;
+  M_COLDATA->m_color.pixel = gdk_imlib_best_color_match( &r, &g, &b );
+
+#else
+
+  M_COLDATA->m_hasPixel = gdk_color_alloc( cmap, &M_COLDATA->m_color );
+  
+#endif
+  
+  M_COLDATA->m_colormap = cmap;
+};
+
+int wxColour::GetPixel(void)
+{
+  if (!Ok()) return 0;
+  
+  return M_COLDATA->m_color.pixel;
+};
+
+GdkColor *wxColour::GetColor(void)
+{
+  if (!Ok()) return NULL;
+  
+  return &M_COLDATA->m_color;
+};
+
+
diff --git a/src/gtk/control.cpp b/src/gtk/control.cpp
new file mode 100644
index 0000000000..510d88d0e9
--- /dev/null
+++ b/src/gtk/control.cpp
@@ -0,0 +1,51 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        control.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "control.h"
+#endif
+
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// wxControl
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxControl,wxWindow)
+
+wxControl::wxControl(void)
+{
+  m_label = "";
+  m_needParent = TRUE;
+};
+
+wxControl::wxControl( wxWindow *parent, wxWindowID id, 
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name ) :
+  wxWindow( parent, id, pos, size, style, name )
+{
+};
+
+void wxControl::Command( wxCommandEvent &WXUNUSED(event) )
+{
+};
+
+void wxControl::SetLabel( const wxString &label )
+{
+  m_label = label;
+};
+
+wxString wxControl::GetLabel(void) const
+{
+  return m_label;
+};
+
+
+
diff --git a/src/gtk/cross.xbm b/src/gtk/cross.xbm
new file mode 100644
index 0000000000..b07cbe7fcd
--- /dev/null
+++ b/src/gtk/cross.xbm
@@ -0,0 +1,6 @@
+#define cross_width 15
+#define cross_height 15
+static char cross_bits[] = {
+   0x84, 0x10, 0x84, 0x10, 0xff, 0x7f, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10,
+   0x84, 0x10, 0xff, 0x7f, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10,
+   0xff, 0x7f, 0x84, 0x10, 0x84, 0x10};
diff --git a/src/gtk/cursor.cpp b/src/gtk/cursor.cpp
new file mode 100644
index 0000000000..bb0888bdcb
--- /dev/null
+++ b/src/gtk/cursor.cpp
@@ -0,0 +1,173 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        cursor.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "cursor.h"
+#endif
+
+#include "wx/cursor.h"
+
+//-----------------------------------------------------------------------------
+// wxCursor
+//-----------------------------------------------------------------------------
+
+class wxCursorRefData: public wxObjectRefData
+{
+  public:
+  
+    wxCursorRefData(void);
+    ~wxCursorRefData(void);
+  
+    GdkCursor *m_cursor;
+};
+
+wxCursorRefData::wxCursorRefData(void)
+{
+  m_cursor = NULL;
+};
+
+wxCursorRefData::~wxCursorRefData(void)
+{
+  if (m_cursor) gdk_cursor_destroy( m_cursor );
+};
+
+//-----------------------------------------------------------------------------
+
+#define M_CURSORDATA ((wxCursorRefData *)m_refData)
+
+IMPLEMENT_DYNAMIC_CLASS(wxCursor,wxObject)
+
+wxCursor::wxCursor(void)
+{
+};
+
+wxCursor::wxCursor( const int cursorId )
+{
+  m_refData = new wxCursorRefData();
+  
+  GdkCursorType gdk_cur = GDK_LEFT_PTR;
+  switch (cursorId)
+  {
+    case wxCURSOR_HAND:       gdk_cur = GDK_HAND1; break;
+    case wxCURSOR_CROSS:      gdk_cur = GDK_CROSSHAIR; break;
+    case wxCURSOR_SIZEWE:     gdk_cur = GDK_SB_H_DOUBLE_ARROW; break;
+    case wxCURSOR_SIZENS:     gdk_cur = GDK_SB_V_DOUBLE_ARROW; break;
+    case wxCURSOR_WAIT:       gdk_cur = GDK_WATCH; break;
+    case wxCURSOR_WATCH:      gdk_cur = GDK_WATCH; break;
+    case wxCURSOR_SIZING:     gdk_cur = GDK_SIZING; break;
+    case wxCURSOR_SPRAYCAN:   gdk_cur = GDK_SPRAYCAN; break;
+    case wxCURSOR_IBEAM:      gdk_cur = GDK_XTERM; break;
+    case wxCURSOR_PENCIL:     gdk_cur = GDK_PENCIL; break;
+    case wxCURSOR_NO_ENTRY:   gdk_cur = GDK_PIRATE; break;
+  };
+  
+  M_CURSORDATA->m_cursor = gdk_cursor_new( gdk_cur );
+  
+/*
+  do that yourself
+   
+  wxCURSOR_BULLSEYE,
+  wxCURSOR_CHAR,
+  wxCURSOR_LEFT_BUTTON,
+  wxCURSOR_MAGNIFIER,
+  wxCURSOR_MIDDLE_BUTTON,
+  wxCURSOR_NO_ENTRY,
+  wxCURSOR_PAINT_BRUSH,
+  wxCURSOR_POINT_LEFT,
+  wxCURSOR_POINT_RIGHT,
+  wxCURSOR_QUESTION_ARROW,
+  wxCURSOR_RIGHT_BUTTON,
+  wxCURSOR_SIZENESW,
+  wxCURSOR_SIZENS,
+  wxCURSOR_SIZENWSE,
+  wxCURSOR_SIZEWE,
+  wxCURSOR_BLANK
+,
+  wxCURSOR_CROSS_REVERSE,
+  wxCURSOR_DOUBLE_ARROW,
+  wxCURSOR_BASED_ARROW_UP,
+  wxCURSOR_BASED_ARROW_DOWN
+*/
+   
+};
+
+wxCursor::wxCursor( const wxCursor &cursor )
+{
+  Ref( cursor );
+};
+
+wxCursor::wxCursor( const wxCursor *cursor )
+{
+  UnRef();
+  if (cursor) Ref( *cursor );
+};
+
+wxCursor::~wxCursor(void)
+{
+};
+
+wxCursor& wxCursor::operator = ( const wxCursor& cursor )
+{
+  if (*this == cursor) return (*this); 
+  Ref( cursor ); 
+  return *this; 
+};
+
+bool wxCursor::operator == ( const wxCursor& cursor )
+{
+  return m_refData == cursor.m_refData; 
+};
+
+bool wxCursor::operator != ( const wxCursor& cursor )
+{
+  return m_refData != cursor.m_refData; 
+};
+
+bool wxCursor::Ok(void) const
+{
+  return TRUE;
+};
+
+GdkCursor *wxCursor::GetCursor(void) const
+{
+  return M_CURSORDATA->m_cursor;
+};
+
+//-----------------------------------------------------------------------------
+// busy cursor routines
+//-----------------------------------------------------------------------------
+
+bool g_isBusy = FALSE;
+
+void wxEndBusyCursor(void)
+{
+  g_isBusy = FALSE;
+};
+
+void wxBeginBusyCursor( wxCursor *WXUNUSED(cursor) )
+{
+  g_isBusy = TRUE;
+};
+
+bool wxIsBusy(void)
+{
+  return g_isBusy;
+};
+
+void wxSetCursor( const wxCursor& cursor )
+{
+  extern wxCursor *g_globalCursor;
+  if (g_globalCursor) (*g_globalCursor) = cursor;
+
+  if (cursor.Ok()) {};
+};
+
+
diff --git a/src/gtk/data.cpp b/src/gtk/data.cpp
new file mode 100644
index 0000000000..cd3124b47f
--- /dev/null
+++ b/src/gtk/data.cpp
@@ -0,0 +1,705 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        data.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+// #pragma implementation
+#endif
+
+#include "wx/wx.h"
+
+#define _MAXPATHLEN 500
+
+// Used for X resources
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xresource.h>
+
+wxList wxResourceCache(wxKEY_STRING);
+XrmDatabase wxResourceDatabase;
+
+// Useful buffer, initialized in wxCommonInit
+char *wxBuffer = NULL;
+
+// Windows List
+wxList wxTopLevelWindows;
+
+// List of windows pending deletion
+wxList wxPendingDelete;
+
+// Current cursor, in order to hang on to
+// cursor handle when setting the cursor globally
+wxCursor *g_globalCursor = NULL;
+
+// Don't allow event propagation during drag
+bool g_blockEventsOnDrag = FALSE;
+
+// Message Strings for Internationalization
+char **wx_msg_str = (char**)NULL;
+
+// Custom OS version, as optionally placed in wx.ini/.wxrc
+// Currently this can be Win95, Windows, Win32s, WinNT.
+// For some systems, you can't tell until run-time what services you
+// have. See wxGetOsVersion, which uses this string if present.
+char *wxOsVersion = NULL;
+
+// For printing several pages
+int wxPageNumber;
+wxPrintPaperDatabase* wxThePrintPaperDatabase = NULL;
+
+// GDI Object Lists
+wxBrushList      *wxTheBrushList = NULL;
+wxPenList        *wxThePenList = NULL;
+wxFontList       *wxTheFontList = NULL;
+wxColourDatabase *wxTheColourDatabase = NULL;
+wxBitmapList   *wxTheBitmapList = NULL;
+  
+
+// X only font names
+wxFontNameDirectory wxTheFontNameDirectory;
+
+// Stock objects
+wxFont *wxNORMAL_FONT;
+wxFont *wxSMALL_FONT;
+wxFont *wxITALIC_FONT;
+wxFont *wxSWISS_FONT;
+
+wxPen *wxRED_PEN;
+wxPen *wxCYAN_PEN;
+wxPen *wxGREEN_PEN;
+wxPen *wxBLACK_PEN;
+wxPen *wxWHITE_PEN;
+wxPen *wxTRANSPARENT_PEN;
+wxPen *wxBLACK_DASHED_PEN;
+wxPen *wxGREY_PEN;
+wxPen *wxMEDIUM_GREY_PEN;
+wxPen *wxLIGHT_GREY_PEN;
+
+wxBrush *wxBLUE_BRUSH;
+wxBrush *wxGREEN_BRUSH;
+wxBrush *wxWHITE_BRUSH;
+wxBrush *wxBLACK_BRUSH;
+wxBrush *wxTRANSPARENT_BRUSH;
+wxBrush *wxCYAN_BRUSH;
+wxBrush *wxRED_BRUSH;
+wxBrush *wxGREY_BRUSH;
+wxBrush *wxMEDIUM_GREY_BRUSH;
+wxBrush *wxLIGHT_GREY_BRUSH;
+
+wxColour *wxBLACK;
+wxColour *wxWHITE;
+wxColour *wxGREY;            // Robert Roebling
+wxColour *wxRED;
+wxColour *wxBLUE;
+wxColour *wxGREEN;
+wxColour *wxCYAN;
+wxColour *wxLIGHT_GREY;
+
+wxCursor *wxSTANDARD_CURSOR = NULL;
+wxCursor *wxHOURGLASS_CURSOR = NULL;
+wxCursor *wxCROSS_CURSOR = NULL;
+
+// 'Null' objects
+wxBitmap wxNullBitmap;
+wxIcon   wxNullIcon;  
+wxCursor wxNullCursor;
+wxPen    wxNullPen;
+wxBrush  wxNullBrush;
+wxFont   wxNullFont;
+wxColour wxNullColour;
+wxPalette wxNullPalette; 
+
+// Default window names
+const char *wxButtonNameStr = "button";
+const char *wxCanvasNameStr = "canvas";
+const char *wxCheckBoxNameStr = "check";
+const char *wxChoiceNameStr = "choice";
+const char *wxComboBoxNameStr = "comboBox";
+const char *wxDialogNameStr = "dialog";
+const char *wxFrameNameStr = "frame";
+const char *wxGaugeNameStr = "gauge";
+const char *wxStaticBoxNameStr = "groupBox";
+const char *wxListBoxNameStr = "listBox";
+const char *wxStaticTextNameStr = "message";
+const char *wxStaticBitmapNameStr = "message";
+const char *wxMultiTextNameStr = "multitext";
+const char *wxPanelNameStr = "panel";
+const char *wxRadioBoxNameStr = "radioBox";
+const char *wxRadioButtonNameStr = "radioButton";
+const char *wxBitmapRadioButtonNameStr = "radioButton";
+const char *wxScrollBarNameStr = "scrollBar";
+const char *wxSliderNameStr = "slider";
+const char *wxStaticNameStr = "static";
+const char *wxTextCtrlWindowNameStr = "textWindow";
+const char *wxTextCtrlNameStr = "text";
+const char *wxVirtListBoxNameStr = "virtListBox";
+const char *wxButtonBarNameStr = "buttonbar";
+const char *wxEnhDialogNameStr = "Shell";
+const char *wxToolBarNameStr = "toolbar";
+const char *wxStatusLineNameStr = "status_line";
+const char *wxEmptyString = "";
+const char *wxGetTextFromUserPromptStr = "Input Text";
+const char *wxMessageBoxCaptionStr = "Message";
+const char *wxFileSelectorPromptStr = "Select a file";
+const char *wxFileSelectorDefaultWildcardStr = "*.*";
+const char *wxInternalErrorStr = "wxWindows Internal Error";
+const char *wxFatalErrorStr = "wxWindows Fatal Error";
+
+// See wx/utils.h
+const char *wxFloatToStringStr = "%.2f";
+const char *wxDoubleToStringStr = "%.2f";
+
+#ifdef wx_msw
+const char *wxUserResourceStr = "TEXT";
+#endif
+
+
+#if USE_SHARED_LIBRARY
+/*
+ * For wxWindows to be made into a dynamic library (e.g. Sun),
+ * all IMPLEMENT_... macros must be in one place.
+ * But normally, the definitions are in the appropriate places.
+ */
+
+// Hand-coded IMPLEMENT... macro for wxObject (define static data)
+wxClassInfo wxObject::classwxObject("wxObject", NULL, NULL, sizeof(wxObject), NULL);
+wxClassInfo *wxClassInfo::first = NULL;
+
+#include "wx/button.h"
+#include "wx/bmpbuttn.h"
+IMPLEMENT_DYNAMIC_CLASS(wxButton, wxControl)
+IMPLEMENT_DYNAMIC_CLASS(wxBitmapButton, wxButton)
+
+#include "wx/checkbox.h"
+IMPLEMENT_DYNAMIC_CLASS(wxCheckBox, wxControl)
+IMPLEMENT_DYNAMIC_CLASS(wxBitmapCheckBox, wxCheckBox)
+
+#include "wx/choice.h"
+IMPLEMENT_DYNAMIC_CLASS(wxChoice, wxControl)
+
+#if USE_CLIPBOARD
+#include "wx/clipbrd.h"
+IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject)
+IMPLEMENT_ABSTRACT_CLASS(wxClipboardClient, wxObject)
+#endif
+
+#if USE_COMBOBOX
+#include "wx/combobox.h"
+IMPLEMENT_DYNAMIC_CLASS(wxComboBox, wxControl)
+#endif
+
+#include "wx/dc.h"
+#include "wx/dcmemory.h"
+#include "wx/dcclient.h"
+#include "wx/dcscreen.h"
+IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxDC)
+IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC)
+IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxDC)
+IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC, wxDC)
+IMPLEMENT_DYNAMIC_CLASS(wxScreenDC, wxWindowDC)
+
+#if defined(wx_msw)
+#include "wx/dcprint.h"
+IMPLEMENT_CLASS(wxPrinterDC, wxDC)
+#endif
+
+#include "wx/dialog.h"
+IMPLEMENT_DYNAMIC_CLASS(wxDialog, wxWindow)
+
+#include "wx/frame.h"
+IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow)
+
+#include "wx/mdi.h"
+IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame, wxFrame)
+IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame, wxFrame)
+IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxWindow)
+
+#include "wx/cmndata.h"
+IMPLEMENT_DYNAMIC_CLASS(wxColourData, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxFontData, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxPrintData, wxObject)
+
+#include "wx/colordlg.h"
+#include "wx/fontdlg.h"
+
+#if !defined(wx_msw) || USE_GENERIC_DIALOGS_IN_MSW
+#include "wx/generic/colordlg.h"
+#include "wx/generic/fontdlg.h"
+IMPLEMENT_DYNAMIC_CLASS(wxGenericColourDialog, wxDialog)
+IMPLEMENT_DYNAMIC_CLASS(wxGenericFontDialog, wxDialog)
+#endif
+
+// X defines wxColourDialog to be wxGenericColourDialog
+#ifndef wx_x
+IMPLEMENT_DYNAMIC_CLASS(wxColourDialog, wxDialog)
+IMPLEMENT_DYNAMIC_CLASS(wxFontDialog, wxDialog)
+#endif
+
+#include "wx/gdicmn.h"
+#include "wx/pen.h"
+#include "wx/brush.h"
+#include "wx/font.h"
+#include "wx/palette.h"
+#include "wx/icon.h"
+#include "wx/cursor.h"
+
+IMPLEMENT_DYNAMIC_CLASS(wxColour, wxObject)
+IMPLEMENT_CLASS(wxColourDatabase, wxList)
+IMPLEMENT_DYNAMIC_CLASS(wxFontList, wxList)
+IMPLEMENT_DYNAMIC_CLASS(wxPenList, wxList)
+IMPLEMENT_DYNAMIC_CLASS(wxBrushList, wxList)
+IMPLEMENT_DYNAMIC_CLASS(wxBitmapList, wxList)
+
+#if (!USE_TYPEDEFS)
+IMPLEMENT_DYNAMIC_CLASS(wxPoint, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxIntPoint, wxObject)
+#endif
+
+#if defined(wx_x) || (defined(wx_msw) && USE_PORTABLE_FONTS_IN_MSW)
+IMPLEMENT_DYNAMIC_CLASS(wxFontNameDirectory, wxObject)
+#endif
+
+#include "wx/hash.h"
+IMPLEMENT_DYNAMIC_CLASS(wxHashTable, wxObject)
+
+#include "wx/help.h"
+IMPLEMENT_DYNAMIC_CLASS(wxHelpInstance, wxClient)
+IMPLEMENT_CLASS(wxHelpConnection, wxConnection)
+
+#include "wx/list.h"
+IMPLEMENT_DYNAMIC_CLASS(wxNode, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxList, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxStringList, wxList)
+
+#if USE_PRINTING_ARCHITECTURE
+#include "wx/print.h"
+IMPLEMENT_DYNAMIC_CLASS(wxPrintDialog, wxDialog)
+IMPLEMENT_DYNAMIC_CLASS(wxPrinterBase, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxPostScriptPrinter, wxPrinterBase)
+IMPLEMENT_DYNAMIC_CLASS(wxWindowsPrinter, wxPrinterBase)
+IMPLEMENT_ABSTRACT_CLASS(wxPrintout, wxObject)
+IMPLEMENT_CLASS(wxPreviewCanvas, wxWindow)
+IMPLEMENT_CLASS(wxPreviewControlBar, wxWindow)
+IMPLEMENT_CLASS(wxPreviewFrame, wxFrame)
+IMPLEMENT_CLASS(wxPrintPreviewBase, wxObject)
+IMPLEMENT_CLASS(wxPostScriptPrintPreview, wxPrintPreviewBase)
+IMPLEMENT_CLASS(wxWindowsPrintPreview, wxPrintPreviewBase)
+IMPLEMENT_CLASS(wxGenericPrintDialog, wxDialog)
+IMPLEMENT_CLASS(wxGenericPrintSetupDialog, wxDialog)
+#endif
+
+#if USE_POSTSCRIPT
+#include "wx/postscrp.h"
+IMPLEMENT_DYNAMIC_CLASS(wxPostScriptDC, wxDC)
+IMPLEMENT_DYNAMIC_CLASS(wxPrintSetupData, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxPageSetupData, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxPrintPaperType, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxPrintPaperDatabase, wxList)
+#endif
+
+#if USE_WX_RESOURCES
+#include "wx/resource.h"
+IMPLEMENT_DYNAMIC_CLASS(wxItemResource, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxResourceTable, wxHashTable)
+#endif
+
+#include "wx/event.h"
+IMPLEMENT_DYNAMIC_CLASS(wxEvtHandler, wxObject)
+IMPLEMENT_ABSTRACT_CLASS(wxEvent, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxCommandEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxScrollEvent, wxCommandEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxMouseEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxKeyEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxSizeEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxPaintEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxEraseEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxMoveEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxFocusEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxCloseEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxMenuEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxJoystickEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxDropFilesEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxActivateEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxInitDialogEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxSysColourChangedEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxIdleEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxUpdateUIEvent, wxEvent)
+
+#include "wx/utils.h"
+IMPLEMENT_DYNAMIC_CLASS(wxPathList, wxList)
+
+IMPLEMENT_DYNAMIC_CLASS(wxRect, wxObject)
+
+#if USE_TIMEDATE
+#include "wx/date.h"
+IMPLEMENT_DYNAMIC_CLASS(wxDate, wxObject)
+#endif
+
+#if USE_DOC_VIEW_ARCHITECTURE
+#include "wx/docview.h"
+//IMPLEMENT_ABSTRACT_CLASS(wxDocItem, wxObject)
+IMPLEMENT_ABSTRACT_CLASS(wxDocument, wxEvtHandler)
+IMPLEMENT_ABSTRACT_CLASS(wxView, wxEvtHandler)
+IMPLEMENT_ABSTRACT_CLASS(wxDocTemplate, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxDocManager, wxEvtHandler)
+IMPLEMENT_CLASS(wxDocChildFrame, wxFrame)
+IMPLEMENT_CLASS(wxDocParentFrame, wxFrame)
+#if USE_PRINTING_ARCHITECTURE
+IMPLEMENT_DYNAMIC_CLASS(wxDocPrintout, wxPrintout)
+#endif
+IMPLEMENT_CLASS(wxCommand, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxCommandProcessor, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxFileHistory, wxObject)
+#endif
+
+#if USE_CONSTRAINTS
+#include "wx/layout.h"
+IMPLEMENT_DYNAMIC_CLASS(wxIndividualLayoutConstraint, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxLayoutConstraints, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxSizer, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxRowColSizer, wxSizer)
+#endif
+
+#if USE_TOOLBAR
+#include "wx/tbarbase.h"
+IMPLEMENT_DYNAMIC_CLASS(wxToolBarTool, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxToolBarBase, wxControl)
+
+#include "wx/tbarsmpl.h"
+IMPLEMENT_DYNAMIC_CLASS(wxToolBarSimple, wxToolBarBase)
+
+#ifdef wx_msw
+#include "wx/tbarmsw.h"
+IMPLEMENT_DYNAMIC_CLASS(wxToolBarMSW, wxToolBarBase)
+
+#include "wx/tbar95.h"
+IMPLEMENT_DYNAMIC_CLASS(wxToolBar95, wxToolBarBase)
+#endif
+
+#endif
+
+#include "wx/statusbr.h"
+
+IMPLEMENT_DYNAMIC_CLASS(wxStatusBar, wxWindow)
+
+BEGIN_EVENT_TABLE(wxStatusBar, wxWindow)
+	EVT_PAINT(wxStatusBar::OnPaint)
+    EVT_SYS_COLOUR_CHANGED(wxStatusBar::OnSysColourChanged)
+END_EVENT_TABLE()
+
+#if USE_TIMEDATE
+#include "wx/time.h"
+IMPLEMENT_DYNAMIC_CLASS(wxTime, wxObject)
+#endif
+
+#if !USE_GNU_WXSTRING
+#include "wx/string.h"
+IMPLEMENT_DYNAMIC_CLASS(wxString, wxObject)
+#endif
+
+#ifdef wx_motif
+IMPLEMENT_DYNAMIC_CLASS(wxXColormap, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxXFont, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxXCursor, wxObject)
+#endif
+IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
+IMPLEMENT_DYNAMIC_CLASS(wxPalette, wxGDIObject)
+IMPLEMENT_DYNAMIC_CLASS(wxPen, wxGDIObject)
+IMPLEMENT_DYNAMIC_CLASS(wxBrush, wxGDIObject)
+IMPLEMENT_DYNAMIC_CLASS(wxIcon, wxBitmap)
+IMPLEMENT_DYNAMIC_CLASS(wxCursor, wxBitmap)
+IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
+IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
+
+// This will presumably be implemented on other platforms too
+#ifdef wx_msw
+IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
+IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler)
+IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler, wxBitmapHandler)
+IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler, wxBitmapHandler)
+IMPLEMENT_DYNAMIC_CLASS(wxICOFileHandler, wxBitmapHandler)
+IMPLEMENT_DYNAMIC_CLASS(wxICOResourceHandler, wxBitmapHandler)
+#endif
+
+#include "wx/statbox.h"
+IMPLEMENT_DYNAMIC_CLASS(wxStaticBox, wxControl)
+
+#if USE_IPC
+#include "wx/dde.h"
+IMPLEMENT_ABSTRACT_CLASS(wxDDEObject, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxDDEServer, wxDDEObject)
+IMPLEMENT_DYNAMIC_CLASS(wxDDEClient, wxDDEObject)
+IMPLEMENT_CLASS(wxDDEConnection, wxObject)
+#endif
+
+IMPLEMENT_ABSTRACT_CLASS(wxControl, wxWindow)
+
+#include "wx/listbox.h"
+IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl)
+
+IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
+
+#include "wx/menu.h"
+IMPLEMENT_DYNAMIC_CLASS(wxMenu, wxWindow)
+IMPLEMENT_DYNAMIC_CLASS(wxMenuItem, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxMenuBar, wxWindow)
+
+#include "wx/stattext.h"
+#include "wx/statbmp.h"
+IMPLEMENT_DYNAMIC_CLASS(wxStaticText, wxControl)
+IMPLEMENT_DYNAMIC_CLASS(wxStaticBitmap, wxControl)
+
+#if USE_METAFILE
+#include "wx/metafile.h"
+IMPLEMENT_DYNAMIC_CLASS(wxMetaFile, wxObject)
+IMPLEMENT_ABSTRACT_CLASS(wxMetaFileDC, wxDC)
+#endif
+
+#include "wx/radiobox.h"
+#include "wx/radiobut.h"
+IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl)
+
+IMPLEMENT_DYNAMIC_CLASS(wxRadioButton, wxControl)
+// IMPLEMENT_DYNAMIC_CLASS(wxBitmapRadioButton, wxRadioButton)
+
+#include "wx/scrolbar.h"
+IMPLEMENT_DYNAMIC_CLASS(wxScrollBar, wxControl)
+
+#if WXWIN_COMPATIBILITY
+BEGIN_EVENT_TABLE(wxScrollBar, wxControl)
+  EVT_SCROLL(wxScrollBar::OnScroll)
+END_EVENT_TABLE()
+#endif
+
+#include "wx/slider.h"
+IMPLEMENT_DYNAMIC_CLASS(wxSlider, wxControl)
+
+#if WXWIN_COMPATIBILITY
+BEGIN_EVENT_TABLE(wxSlider, wxControl)
+  EVT_SCROLL(wxSlider::OnScroll)
+END_EVENT_TABLE()
+#endif
+
+#include "wx/timer.h"
+IMPLEMENT_ABSTRACT_CLASS(wxTimer, wxObject)
+
+#include "wx/textctrl.h"
+IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
+
+#include "wx/window.h"
+IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxEvtHandler)
+
+#include "wx/scrolwin.h"
+IMPLEMENT_DYNAMIC_CLASS(wxScrolledWindow, wxWindow)
+
+#include "wx/panel.h"
+IMPLEMENT_DYNAMIC_CLASS(wxPanel, wxWindow)
+
+#include "wx/msgbxdlg.h"
+#include "wx/textdlg.h"
+#include "wx/filedlg.h"
+#include "wx/dirdlg.h"
+#include "wx/choicdlg.h"
+
+#if !defined(wx_msw) || USE_GENERIC_DIALOGS_IN_MSW
+#include "wx/generic/msgdlgg.h"
+IMPLEMENT_CLASS(wxGenericMessageDialog, wxDialog)
+#endif
+
+IMPLEMENT_CLASS(wxTextEntryDialog, wxDialog)
+IMPLEMENT_CLASS(wxSingleChoiceDialog, wxDialog)
+IMPLEMENT_CLASS(wxFileDialog, wxDialog)
+IMPLEMENT_CLASS(wxDirDialog, wxDialog)
+
+#ifdef wx_msw
+IMPLEMENT_CLASS(wxMessageDialog)
+#endif
+
+#if USE_GAUGE
+#ifdef wx_motif
+#include "../../contrib/xmgauge/gauge.h"
+#endif
+#include "wx_gauge.h"
+IMPLEMENT_DYNAMIC_CLASS(wxGauge, wxControl)
+#endif
+
+#include "wx/grid.h"
+IMPLEMENT_DYNAMIC_CLASS(wxGenericGrid, wxPanel)
+
+///// Event tables (also must be in one, statically-linked file for shared libraries)
+
+// This is the base, wxEvtHandler 'bootstrap' code which is expanded manually here
+const wxEventTable *wxEvtHandler::GetEventTable() const { return &wxEvtHandler::sm_eventTable; }
+
+const wxEventTable wxEvtHandler::sm_eventTable =
+	{ NULL, &wxEvtHandler::sm_eventTableEntries[0] };
+
+const wxEventTableEntry wxEvtHandler::sm_eventTableEntries[] = { { 0, 0, 0, NULL } };
+
+BEGIN_EVENT_TABLE(wxFrame, wxWindow)
+	EVT_ACTIVATE(wxFrame::OnActivate)
+	EVT_SIZE(wxFrame::OnSize)
+	EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight)
+    EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged)
+    EVT_IDLE(wxFrame::OnIdle)
+    EVT_CLOSE(wxFrame::OnCloseWindow)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxDialog, wxPanel)
+  EVT_BUTTON(wxID_OK, wxDialog::OnOK)
+  EVT_BUTTON(wxID_APPLY, wxDialog::OnApply)
+  EVT_BUTTON(wxID_CANCEL, wxDialog::OnCancel)
+  EVT_CHAR_HOOK(wxDialog::OnCharHook)
+  EVT_SYS_COLOUR_CHANGED(wxDialog::OnSysColourChanged)
+  EVT_CLOSE(wxDialog::OnCloseWindow)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxWindow, wxEvtHandler)
+  EVT_CHAR(wxWindow::OnChar)
+  EVT_SIZE(wxWindow::Size)
+  EVT_ERASE_BACKGROUND(wxWindow::OnEraseBackground)
+  EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged)
+  EVT_INIT_DIALOG(wxWindow::OnInitDialog)
+  EVT_IDLE(wxWindow::OnIdle)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxScrolledWindow, wxWindow)
+  EVT_SCROLL(wxScrolledWindow::OnScroll)
+  EVT_SIZE(wxScrolledWindow::OnSize)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxPanel, wxWindow)
+  EVT_SYS_COLOUR_CHANGED(wxPanel::OnSysColourChanged)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
+	EVT_CHAR(wxTextCtrl::OnChar)
+	EVT_DROP_FILES(wxTextCtrl::OnDropFiles)
+	EVT_ERASE_BACKGROUND(wxTextCtrl::OnEraseBackground)
+END_EVENT_TABLE()
+
+#ifdef wx_msw
+BEGIN_EVENT_TABLE(wxMDIParentWindow, wxFrame)
+  EVT_SIZE(wxMDIParentWindow::OnSize)
+  EVT_ACTIVATE(wxMDIParentWindow::OnActivate)
+  EVT_SYS_COLOUR_CHANGED(wxMDIParentWindow::OnSysColourChanged)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxMDIClientWindow, wxWindow)
+  EVT_SCROLL(wxMDIClientWindow::OnScroll)
+END_EVENT_TABLE()
+#endif
+
+BEGIN_EVENT_TABLE(wxToolBarBase, wxControl)
+  EVT_SCROLL(wxToolBarBase::OnScroll)
+  EVT_SIZE(wxToolBarBase::OnSize)
+  EVT_IDLE(wxToolBarBase::OnIdle)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxToolBarSimple, wxToolBarBase)
+	EVT_SIZE(wxToolBarSimple::OnSize)
+	EVT_PAINT(wxToolBarSimple::OnPaint)
+	EVT_KILL_FOCUS(wxToolBarSimple::OnKillFocus)
+	EVT_MOUSE_EVENTS(wxToolBarSimple::OnMouseEvent)
+END_EVENT_TABLE()
+
+#ifdef wx_msw
+BEGIN_EVENT_TABLE(wxToolBarMSW, wxToolBarBase)
+	EVT_SIZE(wxToolBarMSW::OnSize)
+	EVT_PAINT(wxToolBarMSW::OnPaint)
+	EVT_MOUSE_EVENTS(wxToolBarMSW::OnMouseEvent)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxToolBar95, wxToolBarBase)
+	EVT_SIZE(wxToolBar95::OnSize)
+	EVT_PAINT(wxToolBar95::OnPaint)
+	EVT_KILL_FOCUS(wxToolBar95::OnKillFocus)
+	EVT_MOUSE_EVENTS(wxToolBar95::OnMouseEvent)
+    EVT_SYS_COLOUR_CHANGED(wxToolBar95::OnSysColourChanged)
+END_EVENT_TABLE()
+#endif
+
+BEGIN_EVENT_TABLE(wxGenericGrid, wxPanel)
+	EVT_SIZE(wxGenericGrid::OnSize)
+	EVT_PAINT(wxGenericGrid::OnPaint)
+	EVT_MOUSE_EVENTS(wxGenericGrid::OnMouseEvent)
+    EVT_TEXT(wxGRID_TEXT_CTRL, wxGenericGrid::OnText)
+    EVT_COMMAND_SCROLL(wxGRID_HSCROLL, wxGenericGrid::OnGridScroll)
+    EVT_COMMAND_SCROLL(wxGRID_VSCROLL, wxGenericGrid::OnGridScroll)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxControl, wxWindow)
+  EVT_ERASE_BACKGROUND(wxControl::OnEraseBackground)
+END_EVENT_TABLE()
+
+#if !defined(wx_msw) || USE_GENERIC_DIALOGS_IN_MSW
+BEGIN_EVENT_TABLE(wxGenericMessageDialog, wxDialog)
+	EVT_BUTTON(wxID_YES, wxGenericMessageDialog::OnYes)
+	EVT_BUTTON(wxID_NO, wxGenericMessageDialog::OnNo)
+	EVT_BUTTON(wxID_CANCEL, wxGenericMessageDialog::OnCancel)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxGenericColourDialog, wxDialog)
+	EVT_BUTTON(wxID_ADD_CUSTOM, wxGenericColourDialog::OnAddCustom)
+	EVT_SLIDER(wxID_RED_SLIDER, wxGenericColourDialog::OnRedSlider)
+	EVT_SLIDER(wxID_GREEN_SLIDER, wxGenericColourDialog::OnGreenSlider)
+	EVT_SLIDER(wxID_BLUE_SLIDER, wxGenericColourDialog::OnBlueSlider)
+	EVT_PAINT(wxGenericColourDialog::OnPaint)
+	EVT_MOUSE_EVENTS(wxGenericColourDialog::OnMouseEvent)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxGenericFontDialog, wxDialog)
+	EVT_CHECKBOX(wxID_FONT_UNDERLINE, wxGenericFontDialog::OnChangeFont)
+	EVT_CHOICE(wxID_FONT_STYLE, wxGenericFontDialog::OnChangeFont)
+	EVT_CHOICE(wxID_FONT_WEIGHT, wxGenericFontDialog::OnChangeFont)
+	EVT_CHOICE(wxID_FONT_FAMILY, wxGenericFontDialog::OnChangeFont)
+	EVT_CHOICE(wxID_FONT_COLOUR, wxGenericFontDialog::OnChangeFont)
+	EVT_CHOICE(wxID_FONT_SIZE, wxGenericFontDialog::OnChangeFont)
+	EVT_PAINT(wxGenericFontDialog::OnPaint)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxGenericPrintDialog, wxDialog)
+    EVT_BUTTON(wxID_OK, wxGenericPrintDialog::OnOK)
+    EVT_BUTTON(wxPRINTID_SETUP, wxGenericPrintDialog::OnSetup)
+    EVT_RADIOBOX(wxPRINTID_RANGE, wxGenericPrintDialog::OnRange)
+END_EVENT_TABLE()
+
+#endif
+
+BEGIN_EVENT_TABLE(wxTextEntryDialog, wxDialog)
+	EVT_BUTTON(wxID_OK, wxTextEntryDialog::OnOK)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxSingleChoiceDialog, wxDialog)
+	EVT_BUTTON(wxID_OK, wxSingleChoiceDialog::OnOK)
+END_EVENT_TABLE()
+
+#include "wx/prntbase.h"
+
+BEGIN_EVENT_TABLE(wxPrintAbortDialog, wxDialog)
+	EVT_BUTTON(wxID_CANCEL, wxPrintAbortDialog::OnCancel)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxPreviewControlBar, wxWindow)
+	EVT_BUTTON(wxID_PREVIEW_CLOSE, 		wxPreviewControlBar::OnClose)
+	EVT_BUTTON(wxID_PREVIEW_PRINT, 		wxPreviewControlBar::OnPrint)
+	EVT_BUTTON(wxID_PREVIEW_PREVIOUS, 	wxPreviewControlBar::OnPrevious)
+	EVT_BUTTON(wxID_PREVIEW_NEXT, 		wxPreviewControlBar::OnNext)
+	EVT_CHOICE(wxID_PREVIEW_ZOOM, 		wxPreviewControlBar::OnZoom)
+END_EVENT_TABLE()
+
+#endif
+
+
+const wxSize wxDefaultSize(-1, -1);
+const wxPoint wxDefaultPosition(-1, -1);
diff --git a/src/gtk/dc.cpp b/src/gtk/dc.cpp
new file mode 100644
index 0000000000..c53c2d26fd
--- /dev/null
+++ b/src/gtk/dc.cpp
@@ -0,0 +1,370 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        dc.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "dc.h"
+#endif
+
+#include "wx/dc.h"
+
+//-----------------------------------------------------------------------------
+// constants
+//-----------------------------------------------------------------------------
+
+#define mm2inches		0.0393700787402
+#define inches2mm		25.4
+#define mm2twips		56.6929133859
+#define twips2mm		0.0176388888889
+#define mm2pt			2.83464566929
+#define pt2mm			0.352777777778
+
+//-----------------------------------------------------------------------------
+// wxDC
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_ABSTRACT_CLASS(wxDC,wxObject)
+
+wxDC::wxDC(void)
+{
+  m_ok = FALSE;
+  m_optimize = FALSE;
+  m_autoSetting = FALSE;
+  m_colour = TRUE;
+  m_clipping = FALSE;
+  
+  m_mm_to_pix_x = 1.0;
+  m_mm_to_pix_y = 1.0;
+  
+  m_logicalOriginX = 0;
+  m_logicalOriginY = 0;
+  m_deviceOriginX = 0;
+  m_deviceOriginY = 0;
+  m_internalDeviceOriginX = 0;
+  m_internalDeviceOriginY = 0;
+  m_externalDeviceOriginX = 0;
+  m_externalDeviceOriginY = 0;
+  
+  m_logicalScaleX = 1.0;
+  m_logicalScaleY = 1.0;
+  m_userScaleX = 1.0;
+  m_userScaleY = 1.0;
+  m_scaleX = 1.0;
+  m_scaleY = 1.0;
+  
+  m_mappingMode = MM_TEXT;
+  m_needComputeScaleX = FALSE;
+  m_needComputeScaleY = FALSE;
+  
+  m_signX = 1;  // default x-axis left to right
+  m_signY = 1;  // default y-axis top down
+
+  m_maxX = m_maxY = -100000;
+  m_minY = m_minY =  100000;
+
+  m_logicalFunction = wxCOPY;
+//  m_textAlignment = wxALIGN_TOP_LEFT;
+  m_backgroundMode = wxTRANSPARENT;
+  
+  m_textForegroundColour = *wxBLACK;
+  m_textBackgroundColour = *wxWHITE;
+  m_pen = *wxBLACK_PEN;
+  m_font = *wxNORMAL_FONT;
+  m_brush = *wxTRANSPARENT_BRUSH;
+  m_backgroundBrush = *wxWHITE_BRUSH;
+  
+//  m_palette = wxAPP_COLOURMAP;
+};
+
+wxDC::~wxDC(void)
+{
+};
+
+void wxDC::DrawArc( long WXUNUSED(x1), long WXUNUSED(y1), long WXUNUSED(x2), long WXUNUSED(y2), 
+  double WXUNUSED(xc), double WXUNUSED(yc) )
+{
+};
+
+void wxDC::DrawIcon( const wxIcon &WXUNUSED(icon), long WXUNUSED(x), long WXUNUSED(y), bool WXUNUSED(useMask) ) 
+{
+};
+
+void wxDC::DrawPoint( wxPoint& point ) 
+{ 
+  DrawPoint( point.x, point.y ); 
+};
+
+void wxDC::DrawPolygon( wxList *list, long xoffset, long yoffset, int fillStyle )
+{
+  int n = list->Number();
+  wxPoint *points = new wxPoint[n];
+
+  int i = 0;
+  for( wxNode *node = list->First(); node; node = node->Next() )
+  {
+    wxPoint *point = (wxPoint *)node->Data();
+    points[i].x = point->x;
+    points[i++].y = point->y;
+  };
+  DrawPolygon( n, points, xoffset, yoffset, fillStyle );
+  delete[] points;
+};
+
+void wxDC::DrawLines( wxList *list, long xoffset, long yoffset )
+{
+  int n = list->Number();
+  wxPoint *points = new wxPoint[n];
+
+  int i = 0;
+  for( wxNode *node = list->First(); node; node = node->Next() ) 
+  {
+    wxPoint *point = (wxPoint *)node->Data();
+    points[i].x = point->x;
+    points[i++].y = point->y;
+  };
+  DrawLines( n, points, xoffset, yoffset );
+  delete []points;
+};
+
+void wxDC::DrawSpline( long x1, long y1, long x2, long y2, long x3, long y3 )
+{
+  wxList list;
+  list.DeleteContents(TRUE);
+  list.Append( new wxPoint(x1, y1) );
+  list.Append( new wxPoint(x2, y2) );
+  list.Append( new wxPoint(x3, y3) );
+  DrawSpline(&list);
+};
+
+void wxDC::DrawSpline( wxList *points )
+{
+  DrawOpenSpline( points );
+};
+
+void wxDC::DrawSpline( int n, wxPoint points[] )
+{
+  wxList list;
+  for (int i = 0; i < n; i++) list.Append( (wxObject*)&points[i] );
+  DrawSpline( &list );
+};
+
+void wxDC::SetClippingRegion( long x, long y, long width, long height )
+{
+  m_clipping = TRUE;
+  m_clipX1 = x;
+  m_clipY1 = y;
+  m_clipX2 = x + width;
+  m_clipY2 = y + height;
+};
+
+void wxDC::DestroyClippingRegion(void)
+{
+  m_clipping = FALSE;
+};
+
+void wxDC::GetClippingBox( long *x, long *y, long *width, long *height ) const
+{
+  if (m_clipping)
+  {
+    if (x) *x = m_clipX1;
+    if (y) *y = m_clipY1;
+    if (width) *width = (m_clipX2 - m_clipX1);
+    if (height) *height = (m_clipY2 - m_clipY1);
+  }
+  else
+   *x = *y = *width = *height = 0;
+};
+
+void wxDC::GetSize( int* width, int* height ) const
+{
+  *width = m_maxX-m_minX;
+  *height = m_maxY-m_minY;
+};
+
+void wxDC::GetSizeMM( long* width, long* height ) const
+{
+  int w = 0;
+  int h = 0;
+  GetSize( &w, &h );
+  *width = long( double(w) / (m_scaleX*m_mm_to_pix_x) );
+  *height = long( double(h) / (m_scaleY*m_mm_to_pix_y) );
+};
+
+void wxDC::SetTextForeground( const wxColour &col )
+{
+  if (!Ok()) return;
+  m_textForegroundColour = col;
+};
+
+void wxDC::SetTextBackground( const wxColour &col )
+{
+  if (!Ok()) return;
+  m_textBackgroundColour = col;
+};
+
+void wxDC::SetMapMode( int mode )
+{
+  switch (mode) 
+  {
+    case MM_TWIPS:
+      SetLogicalScale( twips2mm*m_mm_to_pix_x, twips2mm*m_mm_to_pix_y );
+      break;
+    case MM_POINTS:
+      SetLogicalScale( pt2mm*m_mm_to_pix_x, pt2mm*m_mm_to_pix_y );
+      break;
+    case MM_METRIC:
+      SetLogicalScale( m_mm_to_pix_x, m_mm_to_pix_y );
+      break;
+    case MM_LOMETRIC:
+      SetLogicalScale( m_mm_to_pix_x/10.0, m_mm_to_pix_y/10.0 );
+      break;
+    default:
+    case MM_TEXT:
+      SetLogicalScale( 1.0, 1.0 );
+      break;
+  };
+  if (mode != MM_TEXT)
+  {
+    m_needComputeScaleX = TRUE;
+    m_needComputeScaleY = TRUE;
+  };
+};
+
+void wxDC::SetUserScale( double x, double y )
+{
+  // allow negative ? -> no
+  m_userScaleX = x;
+  m_userScaleY = y;
+  ComputeScaleAndOrigin();
+};
+
+void wxDC::GetUserScale( double *x, double *y )
+{
+  if (x) *x = m_userScaleX;
+  if (y) *y = m_userScaleY;
+};
+
+void wxDC::SetLogicalScale( double x, double y )
+{
+  // allow negative ?
+  m_logicalScaleX = x;
+  m_logicalScaleY = y;
+  ComputeScaleAndOrigin();
+};
+
+void wxDC::GetLogicalScale( double *x, double *y )
+{
+  if (x) *x = m_logicalScaleX;
+  if (y) *y = m_logicalScaleY;
+};
+
+void wxDC::SetLogicalOrigin( long x, long y )
+{
+  m_logicalOriginX = x * m_signX;   // is this still correct ?
+  m_logicalOriginY = y * m_signY;
+  ComputeScaleAndOrigin();
+};
+
+void wxDC::GetLogicalOrigin( long *x, long *y )
+{
+  if (x) *x = m_logicalOriginX;
+  if (y) *y = m_logicalOriginY;
+};
+
+void wxDC::SetDeviceOrigin( long x, long y )
+{
+  m_externalDeviceOriginX = x;
+  m_externalDeviceOriginY = y;
+  ComputeScaleAndOrigin();
+};
+
+void wxDC::GetDeviceOrigin( long *x, long *y )
+{
+  if (x) *x = m_externalDeviceOriginX;
+  if (y) *y = m_externalDeviceOriginY;
+};
+
+void wxDC::SetInternalDeviceOrigin( long x, long y )
+{
+  m_internalDeviceOriginX = x;
+  m_internalDeviceOriginY = y;
+  ComputeScaleAndOrigin();
+};
+
+void wxDC::GetInternalDeviceOrigin( long *x, long *y )
+{
+  if (x) *x = m_internalDeviceOriginX;
+  if (y) *y = m_internalDeviceOriginY;
+};
+
+void wxDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
+{
+  m_signX = (xLeftRight ?  1 : -1);
+  m_signY = (yBottomUp  ? -1 :  1);
+  ComputeScaleAndOrigin();
+};
+
+long wxDC::DeviceToLogicalX(long x) const
+{
+  return XDEV2LOG(x);
+};
+
+long wxDC::DeviceToLogicalY(long y) const
+{
+  return YDEV2LOG(y);
+};
+
+long wxDC::DeviceToLogicalXRel(long x) const
+{
+  return XDEV2LOGREL(x);
+};
+
+long wxDC::DeviceToLogicalYRel(long y) const
+{
+  return YDEV2LOGREL(y);
+};
+
+long wxDC::LogicalToDeviceX(long x) const
+{
+  return XLOG2DEV(x);
+};
+
+long wxDC::LogicalToDeviceY(long y) const
+{
+  return YLOG2DEV(y);
+};
+
+long wxDC::LogicalToDeviceXRel(long x) const
+{
+  return XLOG2DEVREL(x);
+};
+
+long wxDC::LogicalToDeviceYRel(long y) const
+{
+  return YLOG2DEVREL(y);
+};
+    
+void wxDC::CalcBoundingBox( long x, long y )
+{
+  if (x < m_minX) m_minX = x;
+  if (y < m_minY) m_minY = y;
+  if (x > m_maxX) m_maxX = x;
+  if (y > m_maxY) m_maxY = y;
+};
+
+void wxDC::ComputeScaleAndOrigin(void)
+{
+  m_scaleX = m_logicalScaleX * m_userScaleX;
+  m_scaleY = m_logicalScaleY * m_userScaleY;
+
+  m_deviceOriginX = m_internalDeviceOriginX + m_externalDeviceOriginX;
+  m_deviceOriginY = m_internalDeviceOriginY + m_externalDeviceOriginY;
+};
+
diff --git a/src/gtk/dcclient.cpp b/src/gtk/dcclient.cpp
new file mode 100644
index 0000000000..dbf2d639a1
--- /dev/null
+++ b/src/gtk/dcclient.cpp
@@ -0,0 +1,773 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        dcclient.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "dcclient.h"
+#endif
+
+#include "wx/dcclient.h"
+
+//-----------------------------------------------------------------------------
+// local data
+//-----------------------------------------------------------------------------
+
+#include "bdiag.xbm"
+#include "fdiag.xbm"
+#include "cdiag.xbm"
+#include "horiz.xbm"
+#include "verti.xbm"
+#include "cross.xbm"
+#define  num_hatches 6
+
+static GdkPixmap  *hatches[num_hatches];
+static GdkPixmap **hatch_bitmap = NULL;
+
+//-----------------------------------------------------------------------------
+// constants
+//-----------------------------------------------------------------------------
+
+#define RAD2DEG 57.2957795131
+
+//-----------------------------------------------------------------------------
+// wxPaintDC
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxPaintDC,wxDC)
+
+wxPaintDC::wxPaintDC(void)
+{
+};
+
+wxPaintDC::wxPaintDC( wxWindow *window )
+{
+  if (!window) return;
+  GtkWidget *widget = window->m_wxwindow;
+  if (!widget) return;
+  m_window = widget->window;
+  if (!m_window) return;
+  if (window->m_wxwindow)
+    m_cmap = gtk_widget_get_colormap( window->m_wxwindow );
+  else
+    m_cmap = gtk_widget_get_colormap( window->m_widget );
+  SetUpDC();
+  
+  long x = 0;
+  long y = 0;
+  window->GetDrawingOffset( &x, &y );
+  SetInternalDeviceOrigin( -x, -y );
+};
+
+wxPaintDC::~wxPaintDC(void)
+{
+};
+
+void wxPaintDC::FloodFill( long WXUNUSED(x1), long WXUNUSED(y1), 
+  wxColour *WXUNUSED(col), int WXUNUSED(style) )
+{
+};
+
+bool wxPaintDC::GetPixel( long WXUNUSED(x1), long WXUNUSED(y1), wxColour *WXUNUSED(col) ) const
+{
+  return FALSE;
+};
+
+void wxPaintDC::DrawLine( long x1, long y1, long x2, long y2 )
+{
+  if (!Ok()) return;
+  
+  if (m_pen.GetStyle() != wxTRANSPARENT)
+  {
+    gdk_draw_line( m_window, m_penGC, 
+      XLOG2DEV(x1), YLOG2DEV(y1), XLOG2DEV(x2), YLOG2DEV(y2) );
+  };
+};
+
+void wxPaintDC::CrossHair( long x, long y )
+{
+  if (!Ok()) return;
+  
+  if (m_pen.GetStyle() != wxTRANSPARENT)
+  {
+    int w = 0;
+    int h = 0;
+    GetSize( &w, &h );
+    long xx = XLOG2DEV(x);
+    long yy = YLOG2DEV(y);
+    gdk_draw_line( m_window, m_penGC,
+      0, yy, XLOG2DEVREL(w), yy );
+    gdk_draw_line( m_window, m_penGC,
+      xx, 0, xx, YLOG2DEVREL(h) );
+  };
+};
+
+void wxPaintDC::DrawArc( long x1, long y1, long x2, long y2, double xc, double yc )
+{
+  if (!Ok()) return;
+  
+  long xx1 = XLOG2DEV(x1); 
+  long yy1 = YLOG2DEV(y1);
+  long xx2 = XLOG2DEV(x2); 
+  long yy2 = YLOG2DEV(y2);
+  long xxc = XLOG2DEV((long)xc); 
+  long yyc = YLOG2DEV((long)yc);
+  double dx = xx1 - xxc; 
+  double dy = yy1 - yyc;
+  double radius = sqrt(dx*dx+dy*dy);
+  long   r      = (long)radius;
+  double radius1, radius2;
+
+  if (xx1 == xx2 && yy1 == yy2) 
+  {
+    radius1 = 0.0;
+    radius2 = 360.0;
+  } 
+  else 
+  if (radius == 0.0) 
+  {
+    radius1 = radius2 = 0.0;
+  } 
+  else 
+  {
+    radius1 = (xx1 - xxc == 0) ?
+	    (yy1 - yyc < 0) ? 90.0 : -90.0 :
+	    -atan2(double(yy1-yyc), double(xx1-xxc)) * RAD2DEG;
+    radius2 = (xx2 - xxc == 0) ?
+	    (yy2 - yyc < 0) ? 90.0 : -90.0 :
+	    -atan2(double(yy2-yyc), double(xx2-xxc)) * RAD2DEG;
+  };
+  long alpha1 = long(radius1 * 64.0);
+  long alpha2 = long((radius2 - radius1) * 64.0);
+  while (alpha2 <= 0) alpha2 += 360*64;
+  while (alpha1 > 360*64) alpha1 -= 360*64;
+
+  if (m_brush.GetStyle() != wxTRANSPARENT)
+    gdk_draw_arc( m_window, m_brushGC, TRUE, xxc-r, yyc-r, 2*r,2*r, alpha1, alpha2 );
+    
+  if (m_pen.GetStyle() != wxTRANSPARENT)
+    gdk_draw_arc( m_window, m_penGC, FALSE, xxc-r, yyc-r, 2*r,2*r, alpha1, alpha2 );
+  
+};
+
+void wxPaintDC::DrawEllipticArc( long x, long y, long width, long height, double sa, double ea )
+{
+  if (!Ok()) return;
+  
+  if (width<0) { width=-width; x=x-width; }
+  if (height<0) { height=-height; y=y-height; }
+
+  long xx = XLOG2DEV(x);    
+  long yy = YLOG2DEV(y);
+  long ww = XLOG2DEVREL(width); 
+  long hh = YLOG2DEVREL(height);
+  
+  if (m_brush.GetStyle() != wxTRANSPARENT)
+    gdk_draw_arc( m_window, m_brushGC, TRUE, xx, yy, ww-1, hh-1, 0, long(sa*64) );
+  
+  if (m_pen.GetStyle() != wxTRANSPARENT)
+    gdk_draw_arc( m_window, m_penGC, FALSE, xx, yy, ww, hh, 0, long(ea*64) );
+};
+
+void wxPaintDC::DrawPoint( long x, long y )
+{
+  if (!Ok()) return;
+  
+  if (m_pen.GetStyle() != wxTRANSPARENT)
+    gdk_draw_point( m_window, m_penGC, XLOG2DEV(x), YLOG2DEV(y) );
+};
+
+void wxPaintDC::DrawLines( int n, wxPoint points[], long xoffset, long yoffset )
+{
+  if (!Ok()) return;
+  
+  if (m_pen.GetStyle() == wxTRANSPARENT) return;
+  
+  for (int i = 0; i < n-1; i++)
+  {
+    long x1 = XLOG2DEV(points[i].x + xoffset);
+    long x2 = XLOG2DEV(points[i+1].x + xoffset);
+    long y1 = YLOG2DEV(points[i].y + yoffset);     // oh, what a waste
+    long y2 = YLOG2DEV(points[i+1].y + yoffset);
+    gdk_draw_line( m_window, m_brushGC, x1, y1, x2, y2 );
+  };
+};
+
+void wxPaintDC::DrawLines( wxList *points, long xoffset, long yoffset )
+{
+  if (!Ok()) return;
+  
+  if (m_pen.GetStyle() == wxTRANSPARENT) return;
+  
+  wxNode *node = points->First();
+  while (node->Next())
+  {
+    wxPoint *point = (wxPoint*)node->Data();
+    wxPoint *npoint = (wxPoint*)node->Next()->Data();
+    long x1 = XLOG2DEV(point->x + xoffset);
+    long x2 = XLOG2DEV(npoint->x + xoffset);
+    long y1 = YLOG2DEV(point->y + yoffset);    // and again...
+    long y2 = YLOG2DEV(npoint->y + yoffset);
+    gdk_draw_line( m_window, m_brushGC, x1, y1, x2, y2 );
+    node = node->Next();
+  };
+};
+
+void wxPaintDC::DrawPolygon( int WXUNUSED(n), wxPoint WXUNUSED(points)[], 
+  long WXUNUSED(xoffset), long WXUNUSED(yoffset), int WXUNUSED(fillStyle) )
+{
+  if (!Ok()) return;
+};
+
+void wxPaintDC::DrawPolygon( wxList *WXUNUSED(lines), long WXUNUSED(xoffset), 
+                             long WXUNUSED(yoffset), int WXUNUSED(fillStyle) )
+{
+  if (!Ok()) return;
+};
+
+void wxPaintDC::DrawRectangle( long x, long y, long width, long height )
+{
+  if (!Ok()) return;
+
+  long xx = XLOG2DEV(x);
+  long yy = YLOG2DEV(y);
+  long ww = XLOG2DEVREL(width);
+  long hh = YLOG2DEVREL(height);
+    
+  if (m_brush.GetStyle() != wxTRANSPARENT)
+    gdk_draw_rectangle( m_window, m_brushGC, TRUE, xx, yy, ww, hh );
+    
+  if (m_pen.GetStyle() != wxTRANSPARENT)
+    gdk_draw_rectangle( m_window, m_penGC, FALSE, xx, yy, ww-1, hh-1 );
+};
+
+void wxPaintDC::DrawRoundedRectangle( long x, long y, long width, long height, double radius )
+{
+  if (!Ok()) return;
+  
+  if (width<0) { width=-width; x=x-width; }
+  if (height<0) { height=-height; y=y-height; }
+
+  if (radius < 0.0) radius = - radius * ((width < height) ? width : height);
+  
+  long xx = XLOG2DEV(x);    
+  long yy = YLOG2DEV(y);
+  long ww = XLOG2DEVREL(width); 
+  long hh = YLOG2DEVREL(height);
+  long rr = XLOG2DEVREL((long)radius);
+  long dd = 2 * rr;
+
+  if (m_brush.GetStyle() != wxTRANSPARENT)
+  {
+    gdk_draw_rectangle( m_window, m_brushGC, TRUE, xx+rr, yy, ww-dd, hh );
+    gdk_draw_rectangle( m_window, m_brushGC, TRUE, xx, yy+rr, ww, hh-dd );
+    gdk_draw_arc( m_window, m_brushGC, TRUE, xx, yy, dd, dd, 90*64, 90*64 );
+    gdk_draw_arc( m_window, m_brushGC, TRUE, xx+ww-dd, yy, dd, dd, 0, 90*64 );
+    gdk_draw_arc( m_window, m_brushGC, TRUE, xx+ww-dd, yy+hh-dd, dd, dd, 270*64, 90*64 );
+    gdk_draw_arc( m_window, m_brushGC, TRUE, xx, yy+hh-dd, dd, dd, 180*64, 90*64 );
+  };
+  
+  if (m_pen.GetStyle() != wxTRANSPARENT)
+  {
+    gdk_draw_line( m_window, m_penGC, xx+rr, yy, xx+ww-rr, yy );
+    gdk_draw_line( m_window, m_penGC, xx+rr, yy+hh, xx+ww-rr, yy+hh );
+    gdk_draw_line( m_window, m_penGC, xx, yy+rr, xx, yy+hh-rr );
+    gdk_draw_line( m_window, m_penGC, xx+ww, yy+rr, xx+ww, yy+hh-rr );
+    gdk_draw_arc( m_window, m_penGC, FALSE, xx, yy, dd, dd, 90*64, 90*64 );
+    gdk_draw_arc( m_window, m_penGC, FALSE, xx+ww-dd, yy, dd, dd, 0, 90*64 );
+    gdk_draw_arc( m_window, m_penGC, FALSE, xx+ww-dd, yy+hh-dd, dd, dd, 270*64, 90*64 );
+    gdk_draw_arc( m_window, m_penGC, FALSE, xx, yy+hh-dd, dd, dd, 180*64, 90*64 );
+  };
+};
+
+void wxPaintDC::DrawEllipse( long x, long y, long width, long height )
+{
+  if (!Ok()) return;
+  
+  if (width<0) { width=-width; x=x-width; }
+  if (height<0) { height=-height; y=y-height; }
+
+  long xx = XLOG2DEV(x);    
+  long yy = YLOG2DEV(y);
+  long ww = XLOG2DEVREL(width); 
+  long hh = YLOG2DEVREL(height);
+  
+  if (m_brush.GetStyle() != wxTRANSPARENT)
+    gdk_draw_arc( m_window, m_brushGC, TRUE, xx, yy, ww, hh, 0, 360*64 );
+  
+  if (m_pen.GetStyle() != wxTRANSPARENT)
+    gdk_draw_arc( m_window, m_penGC, FALSE, xx, yy, ww, hh, 0, 360*64 );
+};
+
+bool wxPaintDC::CanDrawBitmap(void) const
+{
+  return TRUE;
+};
+
+void wxPaintDC::DrawIcon( const wxIcon &icon, long x, long y, bool useMask )
+{
+  if (!Ok()) return;
+  
+  if (!icon.Ok()) return;
+  
+  int xx = XLOG2DEV(x);
+  int yy = YLOG2DEV(y);
+  
+  GdkBitmap *mask = NULL;
+  if (icon.GetMask()) mask = icon.GetMask()->GetBitmap();
+    
+  if (useMask && mask) 
+  {
+    gdk_gc_set_clip_mask( m_penGC, mask );
+    gdk_gc_set_clip_origin( m_penGC, xx, yy );
+  };
+  
+  GdkPixmap *pm = icon.GetPixmap();
+  gdk_draw_pixmap( m_window, m_penGC, pm, 0, 0, xx, yy, -1, -1 );
+  
+  if (useMask && mask) 
+  {
+    gdk_gc_set_clip_mask( m_penGC, NULL );
+    gdk_gc_set_clip_origin( m_penGC, 0, 0 );
+  };
+};
+
+bool wxPaintDC::Blit( long xdest, long ydest, long width, long height,
+       wxDC *source, long xsrc, long ysrc, int WXUNUSED(logical_func), bool WXUNUSED(useMask) )
+{
+  if (!Ok()) return FALSE;
+  
+  wxClientDC *csrc = (wxClientDC*)source;
+
+  gdk_window_copy_area ( m_window, m_penGC,
+    XLOG2DEV(xdest), YLOG2DEV(ydest),
+    csrc->GetWindow(),
+    source->DeviceToLogicalX(xsrc), source->DeviceToLogicalY(ysrc),
+    source->DeviceToLogicalXRel(width), source->DeviceToLogicalYRel(height) );
+
+/*    
+  gdk_window_copy_area ( m_window, m_penGC,
+    XLOG2DEV(xdest), YLOG2DEV(ydest),
+    csrc->GetWindow(),
+    xsrc, ysrc,
+    width, height );
+*/
+    
+  return TRUE;
+};
+
+void wxPaintDC::DrawText( const wxString &text, long x, long y, bool WXUNUSED(use16) )
+{
+  if (!Ok()) return;
+  
+  GdkFont *font = m_font.GetInternalFont( m_scaleY );
+  gdk_draw_string( m_window, font, m_textGC, 
+    XLOG2DEV(x), 
+    YLOG2DEV(y) + font->ascent, text );
+};
+
+bool wxPaintDC::CanGetTextExtent(void) const
+{
+  return TRUE;
+};
+
+void wxPaintDC::GetTextExtent( const wxString &string, long *width, long *height,
+                     long *WXUNUSED(descent), long *WXUNUSED(externalLeading),
+                     wxFont *WXUNUSED(theFont), bool WXUNUSED(use16) )
+{
+  if (!Ok()) return;
+  
+  GdkFont *font = m_font.GetInternalFont( m_scaleY );
+  if (width) (*width) = gdk_string_width( font, string );
+  if (height) (*height) = font->ascent + font->descent;
+};
+
+long wxPaintDC::GetCharWidth(void)
+{
+  if (!Ok()) return 0;
+  
+  GdkFont *font = m_font.GetInternalFont( m_scaleY );
+  return gdk_string_width( font, "H" );
+};
+
+long wxPaintDC::GetCharHeight(void)
+{
+  if (!Ok()) return 0;
+  
+  GdkFont *font = m_font.GetInternalFont( m_scaleY );
+  return font->ascent + font->descent;
+};
+
+void wxPaintDC::Clear(void)
+{
+  if (!Ok()) return;
+  
+  DestroyClippingRegion();
+  gdk_window_clear( m_window );
+};
+
+void wxPaintDC::SetFont( const wxFont &font )
+{
+  if (!Ok()) return;
+  
+  m_font = font;
+};
+
+void wxPaintDC::SetPen( const wxPen &pen )
+{
+  if (!Ok()) return;
+
+  if (m_pen == pen) return;
+  
+  m_pen = pen;
+  
+  if (!m_pen.Ok()) return;
+  
+  gint width = m_pen.GetWidth();
+  
+  GdkLineStyle lineStyle = GDK_LINE_SOLID;
+  switch (m_pen.GetStyle())
+  {
+    case wxSOLID:      { lineStyle = GDK_LINE_SOLID;       break; };
+    case wxDOT:        { lineStyle = GDK_LINE_ON_OFF_DASH; break; };
+    case wxLONG_DASH:  { lineStyle = GDK_LINE_ON_OFF_DASH; break; };
+    case wxSHORT_DASH: { lineStyle = GDK_LINE_ON_OFF_DASH; break; };
+    case wxDOT_DASH:   { lineStyle = GDK_LINE_DOUBLE_DASH; break; };
+  };
+  
+  GdkCapStyle capStyle = GDK_CAP_ROUND;
+  switch (m_pen.GetCap())
+  {
+    case wxCAP_ROUND:      { capStyle = GDK_CAP_ROUND;      break; };
+    case wxCAP_PROJECTING: { capStyle = GDK_CAP_PROJECTING; break; };
+    case wxCAP_BUTT:       { capStyle = GDK_CAP_BUTT;       break; };
+  };
+  
+  GdkJoinStyle joinStyle = GDK_JOIN_ROUND;
+  switch (m_pen.GetJoin())
+  {
+    case wxJOIN_BEVEL: { joinStyle = GDK_JOIN_BEVEL; break; };
+    case wxJOIN_ROUND: { joinStyle = GDK_JOIN_ROUND; break; };
+    case wxJOIN_MITER: { joinStyle = GDK_JOIN_MITER; break; };
+  };
+  
+  gdk_gc_set_line_attributes( m_penGC, width, lineStyle, capStyle, joinStyle );
+  
+  m_pen.GetColour().CalcPixel( m_cmap );
+  gdk_gc_set_foreground( m_penGC, m_pen.GetColour().GetColor() );
+};
+
+void wxPaintDC::SetBrush( const wxBrush &brush )
+{
+  if (!Ok()) return;
+  
+  if (m_brush == brush) return;
+  
+  m_brush = brush;
+  
+  if (!m_brush.Ok()) return;
+  
+  m_brush.GetColour().CalcPixel( m_cmap );
+  gdk_gc_set_foreground( m_brushGC, m_brush.GetColour().GetColor() );
+  
+  GdkFill fillStyle = GDK_SOLID;
+  switch (m_brush.GetStyle())
+  {
+    case wxSOLID:
+    case wxTRANSPARENT:
+      break;
+    default:
+      fillStyle = GDK_STIPPLED;
+  };
+ 
+  gdk_gc_set_fill( m_brushGC, fillStyle );
+  
+  if (m_brush.GetStyle() == wxSTIPPLE)
+  {
+    gdk_gc_set_stipple( m_brushGC, m_brush.GetStipple()->GetPixmap() );
+  };
+  
+  if (IS_HATCH(m_brush.GetStyle()))
+  {
+    int num = m_brush.GetStyle() - wxBDIAGONAL_HATCH;
+    gdk_gc_set_stipple( m_brushGC, hatches[num] );
+  };
+};
+
+void wxPaintDC::SetLogicalFunction( int function )
+{
+  if (m_logicalFunction == function) return;
+  GdkFunction mode = GDK_COPY;
+  switch (function)
+  {
+    case wxXOR:    mode = GDK_INVERT; break;
+    case wxINVERT: mode = GDK_INVERT; break;
+    default:       break;
+  };
+  m_logicalFunction = function;
+  gdk_gc_set_function( m_penGC, mode );
+  gdk_gc_set_function( m_brushGC, mode );
+};
+
+void wxPaintDC::SetTextForeground( const wxColour &col )
+{
+  if (!Ok()) return;
+  
+  if (m_textForegroundColour == col) return;
+  
+  m_textForegroundColour = col;
+  if (!m_textForegroundColour.Ok()) return;
+  
+  m_textForegroundColour.CalcPixel( m_cmap );
+  gdk_gc_set_foreground( m_textGC, m_textForegroundColour.GetColor() );
+};
+
+void wxPaintDC::SetTextBackground( const wxColour &col )
+{
+  if (!Ok()) return;
+  
+  if (m_textBackgroundColour == col) return;
+  
+  m_textBackgroundColour = col;
+  if (!m_textBackgroundColour.Ok()) return;
+  
+  m_textBackgroundColour.CalcPixel( m_cmap );
+  gdk_gc_set_background( m_textGC, m_textBackgroundColour.GetColor() );
+};
+
+void wxPaintDC::SetBackgroundMode( int WXUNUSED(mode) )
+{
+};
+
+void wxPaintDC::SetPalette( const wxPalette& WXUNUSED(palette) )
+{
+};
+
+void wxPaintDC::SetClippingRegion( long x, long y, long width, long height )
+{
+  wxDC::SetClippingRegion( x, y, width, height );
+  
+  GdkRectangle rect;
+  rect.x = XLOG2DEV(x);
+  rect.y = YLOG2DEV(y);
+  rect.width = XLOG2DEV(x+width);
+  rect.height = YLOG2DEV(y+height);
+  gdk_gc_set_clip_rectangle( m_penGC, &rect );
+  gdk_gc_set_clip_rectangle( m_brushGC, &rect );
+  gdk_gc_set_clip_rectangle( m_textGC, &rect );
+  gdk_gc_set_clip_rectangle( m_bgGC, &rect );
+  
+};
+
+void wxPaintDC::DestroyClippingRegion(void)
+{
+  wxDC::DestroyClippingRegion();
+  
+  gdk_gc_set_clip_rectangle( m_penGC, NULL );
+  gdk_gc_set_clip_rectangle( m_brushGC, NULL );
+  gdk_gc_set_clip_rectangle( m_textGC, NULL );
+  gdk_gc_set_clip_rectangle( m_bgGC, NULL );
+};
+
+void wxPaintDC::SetUpDC(void)
+{
+  m_ok = TRUE;
+  m_logicalFunction = wxCOPY;
+  m_penGC = gdk_gc_new( m_window );
+  m_brushGC = gdk_gc_new( m_window );
+  m_textGC = gdk_gc_new( m_window );
+  m_bgGC = gdk_gc_new( m_window );
+  SetTextForeground( m_textForegroundColour );
+  SetTextBackground( m_textBackgroundColour );
+  SetPen( m_pen );
+  SetFont( m_font );
+  SetBrush( m_brush );
+  
+  gdk_gc_set_background( m_penGC, wxWHITE->GetColor() );
+  
+  if (!hatch_bitmap) 
+  {
+    hatch_bitmap    = hatches;
+    hatch_bitmap[0] = gdk_bitmap_create_from_data( NULL, bdiag_bits, bdiag_width, bdiag_height );
+    hatch_bitmap[1] = gdk_bitmap_create_from_data( NULL, cdiag_bits, cdiag_width, cdiag_height );
+    hatch_bitmap[2] = gdk_bitmap_create_from_data( NULL, fdiag_bits, fdiag_width, fdiag_height );
+    hatch_bitmap[3] = gdk_bitmap_create_from_data( NULL, cross_bits, cross_width, cross_height );
+    hatch_bitmap[4] = gdk_bitmap_create_from_data( NULL, horiz_bits, horiz_width, horiz_height );
+    hatch_bitmap[5] = gdk_bitmap_create_from_data( NULL, verti_bits, verti_width, verti_height );
+  };
+};
+
+GdkWindow *wxPaintDC::GetWindow(void)
+{
+  return m_window;
+};
+
+// ----------------------------------- spline code ----------------------------------------
+
+void wx_quadratic_spline(double a1, double b1, double a2, double b2,
+                         double a3, double b3, double a4, double b4);
+void wx_clear_stack(void);
+int wx_spline_pop(double *x1, double *y1, double *x2, double *y2, double *x3,
+        double *y3, double *x4, double *y4);
+void wx_spline_push(double x1, double y1, double x2, double y2, double x3, double y3,
+          double x4, double y4);
+static bool wx_spline_add_point(double x, double y);
+static void wx_spline_draw_point_array(wxDC *dc);
+
+wxList wx_spline_point_list;
+
+#define		half(z1, z2)	((z1+z2)/2.0)
+#define		THRESHOLD	5
+
+/* iterative version */
+
+void wx_quadratic_spline(double a1, double b1, double a2, double b2, double a3, double b3, double a4,
+                 double b4)
+{
+    register double  xmid, ymid;
+    double           x1, y1, x2, y2, x3, y3, x4, y4;
+
+    wx_clear_stack();
+    wx_spline_push(a1, b1, a2, b2, a3, b3, a4, b4);
+
+    while (wx_spline_pop(&x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4)) {
+        xmid = (double)half(x2, x3);
+        ymid = (double)half(y2, y3);
+	if (fabs(x1 - xmid) < THRESHOLD && fabs(y1 - ymid) < THRESHOLD &&
+	    fabs(xmid - x4) < THRESHOLD && fabs(ymid - y4) < THRESHOLD) {
+            wx_spline_add_point( x1, y1 );
+            wx_spline_add_point( xmid, ymid );
+	} else {
+            wx_spline_push(xmid, ymid, (double)half(xmid, x3), (double)half(ymid, y3),
+                 (double)half(x3, x4), (double)half(y3, y4), x4, y4);
+            wx_spline_push(x1, y1, (double)half(x1, x2), (double)half(y1, y2),
+                 (double)half(x2, xmid), (double)half(y2, ymid), xmid, ymid);
+	}
+    }
+}
+
+/* utilities used by spline drawing routines */
+
+typedef struct wx_spline_stack_struct {
+    double           x1, y1, x2, y2, x3, y3, x4, y4;
+} Stack;
+
+#define         SPLINE_STACK_DEPTH             20
+static Stack    wx_spline_stack[SPLINE_STACK_DEPTH];
+static Stack   *wx_stack_top;
+static int      wx_stack_count;
+
+void wx_clear_stack(void)
+{
+    wx_stack_top = wx_spline_stack;
+    wx_stack_count = 0;
+}
+
+void wx_spline_push(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
+{
+    wx_stack_top->x1 = x1;
+    wx_stack_top->y1 = y1;
+    wx_stack_top->x2 = x2;
+    wx_stack_top->y2 = y2;
+    wx_stack_top->x3 = x3;
+    wx_stack_top->y3 = y3;
+    wx_stack_top->x4 = x4;
+    wx_stack_top->y4 = y4;
+    wx_stack_top++;
+    wx_stack_count++;
+}
+
+int wx_spline_pop(double *x1, double *y1, double *x2, double *y2,
+                  double *x3, double *y3, double *x4, double *y4)
+{
+    if (wx_stack_count == 0)
+	return (0);
+    wx_stack_top--;
+    wx_stack_count--;
+    *x1 = wx_stack_top->x1;
+    *y1 = wx_stack_top->y1;
+    *x2 = wx_stack_top->x2;
+    *y2 = wx_stack_top->y2;
+    *x3 = wx_stack_top->x3;
+    *y3 = wx_stack_top->y3;
+    *x4 = wx_stack_top->x4;
+    *y4 = wx_stack_top->y4;
+    return (1);
+}
+
+static bool wx_spline_add_point(double x, double y)
+{
+  wxPoint *point = new wxPoint ;
+  point->x = (int) x;
+  point->y = (int) y;
+  wx_spline_point_list.Append((wxObject*)point);
+  return TRUE;
+}
+
+static void wx_spline_draw_point_array(wxDC *dc)
+{
+  dc->DrawLines(&wx_spline_point_list, 0, 0 );
+  wxNode *node = wx_spline_point_list.First();
+  while (node)
+  {
+    wxPoint *point = (wxPoint *)node->Data();
+    delete point;
+    delete node;
+    node = wx_spline_point_list.First();
+  }
+}
+
+void wxPaintDC::DrawOpenSpline( wxList *points )
+{
+    wxPoint *p;
+    double           cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
+    double           x1, y1, x2, y2;
+
+    wxNode *node = points->First();
+    p = (wxPoint *)node->Data();
+
+    x1 = p->x;
+    y1 = p->y;
+
+    node = node->Next();
+    p = (wxPoint *)node->Data();
+
+    x2 = p->x;
+    y2 = p->y;
+    cx1 = (double)((x1 + x2) / 2);
+    cy1 = (double)((y1 + y2) / 2);
+    cx2 = (double)((cx1 + x2) / 2);
+    cy2 = (double)((cy1 + y2) / 2);
+
+    wx_spline_add_point(x1, y1);
+
+    while ((node = node->Next()) != NULL)
+    {
+        p = (wxPoint *)node->Data();
+	x1 = x2;
+	y1 = y2;
+	x2 = p->x;
+	y2 = p->y;
+        cx4 = (double)(x1 + x2) / 2;
+        cy4 = (double)(y1 + y2) / 2;
+        cx3 = (double)(x1 + cx4) / 2;
+        cy3 = (double)(y1 + cy4) / 2;
+
+        wx_quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
+
+	cx1 = cx4;
+	cy1 = cy4;
+        cx2 = (double)(cx1 + x2) / 2;
+        cy2 = (double)(cy1 + y2) / 2;
+    }
+
+    wx_spline_add_point( cx1, cy1 );
+    wx_spline_add_point( x2, y2 );
+
+    wx_spline_draw_point_array( this );
+};
diff --git a/src/gtk/dcmemory.cpp b/src/gtk/dcmemory.cpp
new file mode 100644
index 0000000000..804ba3e3a3
--- /dev/null
+++ b/src/gtk/dcmemory.cpp
@@ -0,0 +1,68 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        dcmemory.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "dcmemory.h"
+#endif
+
+#include "wx/dcmemory.h"
+
+//-----------------------------------------------------------------------------
+// wxMemoryDC
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC,wxPaintDC)
+
+wxMemoryDC::wxMemoryDC(void)
+{
+  m_ok = FALSE;
+  m_cmap = gdk_colormap_get_system();
+};
+
+wxMemoryDC::wxMemoryDC( wxDC *WXUNUSED(dc) )
+{
+  m_ok = FALSE;
+  m_cmap = gdk_colormap_get_system();
+};
+
+wxMemoryDC::~wxMemoryDC(void)
+{
+};
+
+void wxMemoryDC::SelectObject( const wxBitmap& bitmap )
+{
+  m_selected = bitmap;
+  if (m_selected.Ok())
+  {
+    m_window = m_selected.GetPixmap();
+    SetUpDC();
+  }
+  else
+  {
+    m_ok = FALSE;
+    m_window = NULL;
+  };
+};
+
+void wxMemoryDC::GetSize( int *width, int *height )
+{
+  if (m_selected.Ok())
+  {
+    if (width) (*width) = m_selected.GetWidth();
+    if (height) (*height) = m_selected.GetHeight();
+  }
+  else
+  {
+    if (width) (*width) = 0;
+    if (height) (*height) = 0;
+  };
+};
+
+
diff --git a/src/gtk/dcscreen.cpp b/src/gtk/dcscreen.cpp
new file mode 100644
index 0000000000..9f5c0cacc6
--- /dev/null
+++ b/src/gtk/dcscreen.cpp
@@ -0,0 +1,121 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        dcscreen.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "dcscreen.h"
+#endif
+
+#include "wx/dcscreen.h"
+#include "wx/window.h"
+#include "gdk/gdkx.h"
+
+//-----------------------------------------------------------------------------
+// wxScreenDC
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxScreenDC,wxPaintDC)
+
+wxScreenDC::wxScreenDC(void)
+{
+  m_ok = FALSE;
+  m_window = NULL;
+  m_cmap = gdk_colormap_get_system();
+  
+  m_window = GDK_ROOT_PARENT();
+  
+  SetUpDC();
+  
+  gdk_gc_set_subwindow( m_penGC, GDK_INCLUDE_INFERIORS );
+  gdk_gc_set_subwindow( m_brushGC, GDK_INCLUDE_INFERIORS );
+  gdk_gc_set_subwindow( m_textGC, GDK_INCLUDE_INFERIORS );
+  gdk_gc_set_subwindow( m_bgGC, GDK_INCLUDE_INFERIORS );
+};
+
+wxScreenDC::~wxScreenDC(void)
+{
+  EndDrawingOnTop();
+};
+
+bool wxScreenDC::StartDrawingOnTop( wxWindow *WXUNUSED(window) )
+{
+  return TRUE;
+/*
+  if (!window)
+  {
+    StartDrawingOnTop();
+    return;
+  };
+  wxRectangle rect;
+  rect.x = 0;
+  rect.y = 0;
+  window->GetPosition( &rect.x, &rect.y );
+  rect.width = 0;
+  rect.height = 0;
+  window->GetSize( &rect.width, &rect.height );
+  window->ClientToScreen( &rect.x, &rect.y );
+  StartDrawingOnTop( &rect );
+  return TRUE;
+*/
+};
+
+bool wxScreenDC::StartDrawingOnTop( wxRectangle *WXUNUSED(rect) )
+{
+  return TRUE;
+/*
+  int x = 0;
+  int y = 0;
+  int width = gdk_screen_width();
+  int height = gdk_screen_height();
+  if (rect)
+  {
+    x = rect->x;
+    y = rect->y;
+    width = rect->width;
+    height = rect->height;
+  };
+  
+  GTK cannot set transparent backgrounds. :-(
+
+  GdkWindowAttr attr;
+  attr.x = x;
+  attr.y = y;
+  attr.width = width;
+  attr.height = height;
+  attr.override_redirect = TRUE;
+  attr.wclass = GDK_INPUT_OUTPUT;
+  attr.event_mask = 0;
+  attr.window_type = GDK_WINDOW_TEMP;
+  m_window = gdk_window_new( NULL, &attr, GDK_WA_NOREDIR | GDK_WA_X | GDK_WA_Y );
+  
+  gdk_window_show( m_window );
+
+  m_window = GDK_ROOT_PARENT();
+  
+  SetUpDC();
+  
+  gdk_gc_set_subwindow( m_penGC, GDK_INCLUDE_INFERIORS );
+  gdk_gc_set_subwindow( m_brushGC, GDK_INCLUDE_INFERIORS );
+  gdk_gc_set_subwindow( m_textGC, GDK_INCLUDE_INFERIORS );
+  gdk_gc_set_subwindow( m_bgGC, GDK_INCLUDE_INFERIORS );
+
+  return TRUE;
+*/
+};
+
+bool wxScreenDC::EndDrawingOnTop(void)
+{
+  return TRUE;
+/*
+  if (m_window) gdk_window_destroy( m_window );
+  m_window = NULL;
+  m_isOk = FALSE;
+  return TRUE;
+*/
+};
diff --git a/src/gtk/dialog.cpp b/src/gtk/dialog.cpp
new file mode 100644
index 0000000000..0c63e39f11
--- /dev/null
+++ b/src/gtk/dialog.cpp
@@ -0,0 +1,212 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        dialog.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "dialog.h"
+#endif
+
+#include "wx/dialog.h"
+#include "wx/frame.h"
+#include "wx/app.h"
+#include "wx/gtk/win_gtk.h"
+
+//-----------------------------------------------------------------------------
+// delete
+
+bool gtk_dialog_delete_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxDialog *win )
+{ 
+/*
+  printf( "OnDelete from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  win->Close();
+
+  return TRUE;
+};
+
+//-----------------------------------------------------------------------------
+// wxDialog
+//-----------------------------------------------------------------------------
+
+BEGIN_EVENT_TABLE(wxDialog,wxWindow)
+  EVT_BUTTON  (wxID_OK,       wxDialog::OnOk)
+  EVT_BUTTON  (wxID_CANCEL,   wxDialog::OnCancel)
+  EVT_BUTTON  (wxID_APPLY,    wxDialog::OnApply)
+  EVT_CLOSE   (wxDialog::OnCloseWindow)
+END_EVENT_TABLE()
+
+IMPLEMENT_DYNAMIC_CLASS(wxDialog,wxWindow)
+
+wxDialog::wxDialog(void)
+{
+  m_title = "";
+  m_modalShowing = TRUE;
+  wxTopLevelWindows.Insert( this );
+};
+
+wxDialog::wxDialog( wxWindow *parent, 
+      wxWindowID id, const wxString &title,
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  wxTopLevelWindows.Insert( this );
+  Create( parent, id, title, pos, size, style, name );
+};
+
+bool wxDialog::Create( wxWindow *parent,
+      wxWindowID id, const wxString &title,
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  m_needParent = FALSE;
+  
+  PreCreation( parent, id, pos, size, style, name );
+  
+  m_modalShowing = ((m_windowStyle & wxDIALOG_MODAL) == wxDIALOG_MODAL);
+  
+  m_widget = gtk_window_new( GTK_WINDOW_TOPLEVEL );
+  GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
+ 
+  gtk_widget_set( m_widget, "GtkWindow::allow_shrink", TRUE, NULL);
+  
+  gtk_signal_connect( GTK_OBJECT(m_widget), "delete_event", 
+    GTK_SIGNAL_FUNC(gtk_dialog_delete_callback), (gpointer)this );
+    
+  m_wxwindow = gtk_myfixed_new();
+  gtk_widget_show( m_wxwindow );
+  GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
+  
+  gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow );
+  
+  SetTitle( title );
+  
+  PostCreation();
+  
+  return TRUE;
+};
+
+wxDialog::~wxDialog(void)
+{
+  wxTopLevelWindows.DeleteObject( this );
+  if (wxTopLevelWindows.Number() == 0) wxTheApp->ExitMainLoop();
+};
+
+void wxDialog::SetTitle(const wxString& title )
+{
+  m_title = title;
+  gtk_window_set_title( GTK_WINDOW(m_widget), m_title );
+};
+
+wxString wxDialog::GetTitle(void) const
+{
+  return (wxString&)m_title;
+};
+
+void wxDialog::OnApply( wxCommandEvent &WXUNUSED(event) )
+{
+  if (Validate()) TransferDataFromWindow();
+};
+
+void wxDialog::OnCancel( wxCommandEvent &WXUNUSED(event) )
+{
+  if (IsModal())
+    EndModal(wxID_CANCEL);
+  else
+  {
+    SetReturnCode(wxID_CANCEL);
+    this->Show(FALSE);
+  };
+};
+
+void wxDialog::OnOk( wxCommandEvent &WXUNUSED(event) )
+{
+  if ( Validate() && TransferDataFromWindow())
+  {
+    if (IsModal()) 
+      EndModal(wxID_OK);
+    else
+    {
+      SetReturnCode(wxID_OK);
+      this->Show(FALSE);
+    };
+  };
+  EndModal( wxID_OK );
+};
+
+void wxDialog::OnPaint( wxPaintEvent& WXUNUSED(event) )
+{
+  // yes
+};
+
+bool wxDialog::OnClose(void)
+{
+  static wxList closing;
+
+  if (closing.Member(this)) return FALSE;   // no loops
+
+  closing.Append(this);
+
+  wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
+  cancelEvent.SetEventObject( this );
+  GetEventHandler()->ProcessEvent(cancelEvent);
+  closing.DeleteObject(this);
+  
+  return FALSE;
+}
+
+void wxDialog::OnCloseWindow(wxCloseEvent& event)
+{
+  if (GetEventHandler()->OnClose() || event.GetForce())
+  {
+    this->Destroy();
+  };
+};
+
+bool wxDialog::Show( const bool show )
+{
+  if (!show && m_modalShowing)
+  {
+    EndModal( wxID_CANCEL );
+  };
+
+  wxWindow::Show( show );
+  
+  if (show) InitDialog();
+  
+  if (show && m_modalShowing)
+  {
+    gtk_grab_add( m_widget );
+    gtk_main();
+    gtk_grab_remove( m_widget );
+  };
+  
+  return TRUE;
+};
+
+int wxDialog::ShowModal(void)
+{
+  Show( TRUE );
+  return GetReturnCode();
+};
+
+void wxDialog::EndModal( int retCode )
+{
+  gtk_main_quit();
+  SetReturnCode( retCode );
+};
+
+void wxDialog::InitDialog(void)
+{
+  wxWindow::InitDialog();
+};
+
diff --git a/src/gtk/dnd.cpp b/src/gtk/dnd.cpp
new file mode 100644
index 0000000000..cca46f3b87
--- /dev/null
+++ b/src/gtk/dnd.cpp
@@ -0,0 +1,207 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        dnd.cpp
+// Purpose:     wxDropTarget class
+// Author:      Robert Roebling
+// Copyright:   Robert Roebling
+// Licence:     wxWindows license
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "dnd.h"
+#endif
+
+#include "wx/dnd.h"
+#include "wx/window.h"
+#include "wx/app.h"
+#include "wx/gdicmn.h"
+
+#include "gdk/gdkprivate.h"
+
+#include <X11/Xlib.h>
+
+// ----------------------------------------------------------------------------
+// global
+// ----------------------------------------------------------------------------
+
+extern bool g_blockEventsOnDrag;
+
+// ----------------------------------------------------------------------------
+// wxDropTarget
+// ----------------------------------------------------------------------------
+
+wxDropTarget::wxDropTarget()
+{
+};
+
+wxDropTarget::~wxDropTarget()
+{
+};
+
+void wxDropTarget::Drop( GdkEvent *event, int x, int y )
+{
+  printf( "Drop data is of type %s.\n", event->dropdataavailable.data_type );
+  
+  OnDrop( x, y, (char *)event->dropdataavailable.data);
+};
+
+void wxDropTarget::UnregisterWidget( GtkWidget *widget )
+{
+  gtk_widget_dnd_drop_set( widget, FALSE, NULL, 0, FALSE );
+};
+
+// ----------------------------------------------------------------------------
+// wxTextDropTarget
+// ----------------------------------------------------------------------------
+
+bool wxTextDropTarget::OnDrop( long x, long y, const void *pData )
+{
+  OnDropText( x, y, (const char*)pData );
+  return TRUE;
+};
+
+bool wxTextDropTarget::OnDropText( long x, long y, const char *psz )
+{
+  printf( "Got dropped text: %s.\n", psz );
+  printf( "At x: %d, y: %d.\n", (int)x, (int)y );
+  return TRUE;
+};
+
+void wxTextDropTarget::RegisterWidget( GtkWidget *widget )
+{
+  char *accepted_drop_types[] = { "text/plain" };
+  gtk_widget_dnd_drop_set( widget, TRUE, accepted_drop_types, 1, FALSE );
+};
+
+//-------------------------------------------------------------------------
+// wxDragSource
+//-------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// drag request
+
+void gtk_drag_callback( GtkWidget *widget, GdkEvent *event, wxDragSource *drag )
+{
+  printf( "OnDragRequest.\n" );
+  
+  gtk_widget_dnd_data_set( widget, event, drag->m_data, drag->m_size );
+};
+
+wxDragSource::wxDragSource( wxWindow *win )
+{
+  g_blockEventsOnDrag = TRUE;
+
+  m_window = win;
+  m_widget = win->m_widget;
+  if (win->m_wxwindow) m_widget = win->m_wxwindow;
+ 
+  m_data = NULL;
+  m_size = 0;
+  
+  m_defaultCursor = wxCursor( wxCURSOR_NO_ENTRY );
+  m_goaheadCursor = wxCursor( wxCURSOR_HAND );
+};
+
+wxDragSource::~wxDragSource(void)
+{
+  g_blockEventsOnDrag = FALSE;
+};
+   
+void wxDragSource::SetData( char *data, const long size )
+{
+  m_size = size;
+  m_data = data;
+};
+
+void wxDragSource::Start( int x, int y )
+{
+  if (gdk_dnd.dnd_grabbed) return;
+  if (gdk_dnd.drag_really) return;
+  if (m_size == 0) return;
+  if (!m_data) return;
+  
+  GdkWindowPrivate *wp = (GdkWindowPrivate*) m_widget->window;
+  
+  RegisterWindow();
+  ConnectWindow();
+  
+  gdk_dnd.drag_perhaps = TRUE;
+
+  gdk_dnd.dnd_drag_start.x = 5;
+  gdk_dnd.dnd_drag_start.y = 5;
+  gdk_dnd.real_sw = wp;
+	  
+  if (gdk_dnd.drag_startwindows)
+  {
+    g_free( gdk_dnd.drag_startwindows );
+    gdk_dnd.drag_startwindows = NULL;
+  };
+  gdk_dnd.drag_numwindows = gdk_dnd.drag_really = 0;
+  
+  XWindowAttributes dnd_winattr;
+  XGetWindowAttributes( gdk_display, wp->xwindow, &dnd_winattr );
+  wp->dnd_drag_savedeventmask = dnd_winattr.your_event_mask;
+  
+  gdk_dnd_drag_addwindow( m_widget->window );
+  
+  GdkEventDragBegin ev;
+  ev.type = GDK_DRAG_BEGIN;
+  ev.window = m_widget->window;
+  ev.u.allflags = 0;
+  ev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
+  
+  gdk_event_put( (GdkEvent*)&ev );
+  
+  XGrabPointer( gdk_display, wp->xwindow, False, 
+                ButtonMotionMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
+		GrabModeAsync, GrabModeAsync, gdk_root_window, None, CurrentTime );
+		
+  gdk_dnd_set_drag_cursors( m_defaultCursor.GetCursor(), m_goaheadCursor.GetCursor() );
+  
+  gdk_dnd.dnd_grabbed = TRUE;
+  gdk_dnd.drag_really = 1;
+  gdk_dnd_display_drag_cursor( x, y, FALSE, TRUE );
+  
+  while (gdk_dnd.drag_really || gdk_dnd.drag_perhaps) wxYield();
+  
+  UnconnectWindow();
+  UnregisterWindow();
+};
+
+void wxDragSource::ConnectWindow(void)
+{
+  gtk_signal_connect( GTK_OBJECT(m_widget), "drag_request_event",
+    GTK_SIGNAL_FUNC(gtk_drag_callback), (gpointer)this );
+};
+
+void wxDragSource::UnconnectWindow(void)
+{
+  if (!m_widget) return;
+  
+  gtk_signal_disconnect_by_data( GTK_OBJECT(m_widget), (gpointer)this );
+};
+
+void wxDragSource::UnregisterWindow(void)
+{
+  if (!m_widget) return;
+  
+  gtk_widget_dnd_drag_set( m_widget, FALSE, NULL, 0 );
+};
+  
+//-------------------------------------------------------------------------
+// wxTextDragSource
+//-------------------------------------------------------------------------
+
+void wxTextDragSource::SetTextData( const wxString &text )
+{
+  m_tmp = text;
+  SetData( WXSTRINGCAST(m_tmp), m_tmp.Length()+1 );
+};
+
+void wxTextDragSource::RegisterWindow(void)
+{
+  if (!m_widget) return;
+  
+  char *accepted_drop_types[] = { "text/plain" };
+  gtk_widget_dnd_drag_set( m_widget, TRUE, accepted_drop_types, 1 );
+};
+
diff --git a/src/gtk/fdiag.xbm b/src/gtk/fdiag.xbm
new file mode 100644
index 0000000000..67d3b4732a
--- /dev/null
+++ b/src/gtk/fdiag.xbm
@@ -0,0 +1,6 @@
+#define fdiag_width 16
+#define fdiag_height 16
+static char fdiag_bits[] = {
+   0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20,
+   0x40, 0x40, 0x80, 0x80, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08,
+   0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80};
diff --git a/src/gtk/filedlg.cpp b/src/gtk/filedlg.cpp
new file mode 100644
index 0000000000..1f16d2d1cd
--- /dev/null
+++ b/src/gtk/filedlg.cpp
@@ -0,0 +1,146 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        filedlg.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "filedlg.h"
+#endif
+
+#include "wx/filedlg.h"
+#include "wx/utils.h"
+#include "wx/intl.h"
+
+//-----------------------------------------------------------------------------
+// wxFileDialog
+//-----------------------------------------------------------------------------
+
+void gtk_filedialog_ok_callback( GtkWidget *WXUNUSED(widget), gpointer data )
+{
+  wxFileDialog *dialog = (wxFileDialog*)data;
+  wxCommandEvent event(0);
+  dialog->OnOk( event );
+};
+
+void gtk_filedialog_cancel_callback( GtkWidget *WXUNUSED(widget), gpointer data )
+{
+  wxFileDialog *dialog = (wxFileDialog*)data;
+  wxCommandEvent event(0);
+  dialog->OnCancel( event );
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxFileDialog,wxDialog)
+
+wxFileDialog::wxFileDialog(wxWindow *parent, const wxString& message,
+        const wxString& defaultDir, const wxString& defaultFileName, 
+	const wxString& wildCard,
+        long style, const wxPoint& pos )
+{
+  m_needParent = FALSE;
+  
+  PreCreation( parent, -1, pos, wxDefaultSize, style, "filedialog" );
+  m_message = message;
+  m_path = "";
+  m_fileName = defaultFileName;
+  m_dir = defaultDir;
+  m_wildCard = wildCard;
+  m_filterIndex = 1;
+  
+  m_widget = gtk_file_selection_new( "File selection" );
+  
+  GtkFileSelection *sel = GTK_FILE_SELECTION(m_widget);
+  
+  gtk_signal_connect( GTK_OBJECT(sel->ok_button), "clicked", 
+    GTK_SIGNAL_FUNC(gtk_filedialog_ok_callback), (gpointer*)this );
+
+  gtk_signal_connect( GTK_OBJECT(sel->cancel_button), "clicked", 
+    GTK_SIGNAL_FUNC(gtk_filedialog_cancel_callback), (gpointer*)this );
+};
+
+int wxFileDialog::ShowModal(void)
+{
+  int ret = wxDialog::ShowModal();
+  if (ret == wxID_OK)
+  {
+    m_fileName = gtk_file_selection_get_filename( GTK_FILE_SELECTION(m_widget) );
+    m_path = gtk_file_selection_get_filename( GTK_FILE_SELECTION(m_widget) );
+  };
+  return ret;
+};
+    
+
+char *wxFileSelector(const char *title,
+                     const char *defaultDir, const char *defaultFileName,
+                     const char *defaultExtension, const char *filter, int flags,
+                     wxWindow *parent, int x, int y)
+{
+	wxString filter2("");
+	if ( defaultExtension && !filter )
+		filter2 = wxString("*.") + wxString(defaultExtension) ;
+	else if ( filter )
+		filter2 = filter;
+
+	wxString defaultDirString;
+	if (defaultDir)
+		defaultDirString = defaultDir;
+	else
+		defaultDirString = "";
+
+	wxString defaultFilenameString;
+	if (defaultFileName)
+		defaultFilenameString = defaultFileName;
+	else
+		defaultFilenameString = "";
+
+	wxFileDialog fileDialog(parent, title, defaultDirString, defaultFilenameString, 
+	  filter2, flags, wxPoint(x, y));
+
+	if ( fileDialog.ShowModal() == wxID_OK )
+	{
+		strcpy(wxBuffer, (const char *)fileDialog.GetPath());
+		return wxBuffer;
+	}
+	else
+		return NULL;
+};
+
+char* wxLoadFileSelector(const char *what, const char *extension, const char *default_name, 
+         wxWindow *parent )
+{
+  char *ext = (char *)extension;
+  
+  char prompt[50];
+  wxString str = _("Load %s file");
+  sprintf(prompt, str, what);
+
+  if (*ext == '.') ext++;
+  char wild[60];
+  sprintf(wild, "*.%s", ext);
+
+  return wxFileSelector (prompt, NULL, default_name, ext, wild, 0, parent);
+};
+
+char* wxSaveFileSelector(const char *what, const char *extension, const char *default_name, 
+         wxWindow *parent )
+{
+  char *ext = (char *)extension;
+  
+  char prompt[50];
+  wxString str = _("Save %s file");
+  sprintf(prompt, str, what);
+
+  if (*ext == '.') ext++;
+  char wild[60];
+  sprintf(wild, "*.%s", ext);
+
+  return wxFileSelector (prompt, NULL, default_name, ext, wild, 0, parent);
+};
+
+
+
+
diff --git a/src/gtk/font.cpp b/src/gtk/font.cpp
new file mode 100644
index 0000000000..1418bc0661
--- /dev/null
+++ b/src/gtk/font.cpp
@@ -0,0 +1,822 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        font.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "font.h"
+#endif
+
+#include "wx/font.h"
+#include "wx/utils.h"
+#include <strings.h>
+
+//-----------------------------------------------------------------------------
+// local data
+//-----------------------------------------------------------------------------
+
+static char *wx_font_family [] = {
+    "wxDEFAULT", "wxDECORATIVE", "wxMODERN", "wxROMAN", "wxSCRIPT",
+    "wxSWISS", "wxTELETYPE",
+};
+static char *wx_font_style [] = {
+    "wxDEFAULT", "wxNORMAL", "wxSLANT", "wxITALIC",
+};
+static char *wx_font_weight [] = {
+    "wxDEFAULT", "wxNORMAL", "wxBOLD", "wxLIGHT",
+};
+
+extern wxFontNameDirectory wxTheFontNameDirectory;
+
+//-----------------------------------------------------------------------------
+// wxFont
+//-----------------------------------------------------------------------------
+
+class wxFontRefData: public wxObjectRefData
+{
+  public:
+  
+    wxFontRefData(void);
+    ~wxFontRefData(void);
+ 
+    wxList   m_scaled_xfonts;
+    int      m_pointSize;
+    int      m_family, m_style, m_weight;
+    bool     m_underlined;
+    int      m_fontId;
+    char*    m_faceName;
+     
+    bool     m_byXFontName;
+    GdkFont *m_font;
+    
+    friend wxFont;
+};
+
+wxFontRefData::wxFontRefData(void) : m_scaled_xfonts(wxKEY_INTEGER)
+{
+  m_byXFontName = FALSE;
+  m_pointSize = -1;
+  m_family = -1;
+  m_style = -1;
+  m_weight = -1;
+  m_underlined = FALSE;
+  m_fontId = 0;
+  m_faceName = NULL;
+  m_font = NULL;
+};
+
+wxFontRefData::~wxFontRefData(void)
+{
+  wxNode *node = m_scaled_xfonts.First();
+  while (node) 
+  {
+    GdkFont *font = (GdkFont*)node->Data();
+    wxNode *next = node->Next();
+    gdk_font_unref( font );
+    node = next;
+  };
+  if (m_faceName) 
+  {
+    delete m_faceName;
+    m_faceName = NULL;
+  };
+  if (m_font) gdk_font_unref( m_font );
+};
+
+//-----------------------------------------------------------------------------
+
+#define M_FONTDATA ((wxFontRefData *)m_refData)
+
+IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
+
+wxFont::wxFont(void)
+{
+  if (wxTheFontList) wxTheFontList->Append( this );
+};
+
+wxFont::wxFont( char *xFontName )
+{
+  if (!xFontName) return;
+  
+  m_refData = new wxFontRefData();
+  
+  M_FONTDATA->m_byXFontName = TRUE;
+  M_FONTDATA->m_font = gdk_font_load( xFontName );
+};
+
+wxFont::wxFont(int PointSize, int FontIdOrFamily, int Style, int Weight,
+	       bool Underlined, const char* Face)
+{
+  m_refData = new wxFontRefData();
+  
+  if ((M_FONTDATA->m_faceName = (Face) ? copystring(Face) : (char*)NULL) ) 
+  {
+    M_FONTDATA->m_fontId = wxTheFontNameDirectory.FindOrCreateFontId( Face, FontIdOrFamily );
+    M_FONTDATA->m_family  = wxTheFontNameDirectory.GetFamily( FontIdOrFamily );
+  }
+  else 
+  {
+    M_FONTDATA->m_fontId = FontIdOrFamily;
+    M_FONTDATA->m_family  = wxTheFontNameDirectory.GetFamily( FontIdOrFamily );
+  };
+  M_FONTDATA->m_style = Style;
+  M_FONTDATA->m_weight = Weight;
+  M_FONTDATA->m_pointSize = PointSize;
+  M_FONTDATA->m_underlined = Underlined;
+
+  if (wxTheFontList) wxTheFontList->Append( this );
+};
+
+wxFont::wxFont(int PointSize, const char *Face, int Family, int Style, 
+	       int Weight, bool Underlined)
+{
+  m_refData = new wxFontRefData();
+
+  M_FONTDATA->m_fontId = wxTheFontNameDirectory.FindOrCreateFontId( Face, Family );
+  M_FONTDATA->m_faceName = (Face) ? copystring(Face) : (char*)NULL;
+  M_FONTDATA->m_family = wxTheFontNameDirectory.GetFamily( M_FONTDATA->m_fontId );
+  M_FONTDATA->m_style = Style;
+  M_FONTDATA->m_weight = Weight;
+  M_FONTDATA->m_pointSize = PointSize;
+  M_FONTDATA->m_underlined = Underlined;
+
+  if (wxTheFontList) wxTheFontList->Append( this );
+};
+
+wxFont::wxFont( const wxFont& font )
+{ 
+  Ref( font ); 
+};
+
+wxFont::wxFont( const wxFont* font ) 
+{ 
+  UnRef(); 
+  if (font) Ref( *font ); 
+};
+
+wxFont::~wxFont(void)
+{
+  if (wxTheFontList) wxTheFontList->DeleteObject( this );
+};
+
+wxFont& wxFont::operator = ( const wxFont& font ) 
+{ 
+  if (*this == font) return (*this); 
+  Ref( font ); 
+  return *this; 
+};
+
+bool wxFont::operator == ( const wxFont& font ) 
+{ 
+  return m_refData == font.m_refData; 
+};
+
+bool wxFont::operator != ( const wxFont& font ) 
+{ 
+  return m_refData != font.m_refData; 
+};
+
+bool wxFont::Ok()
+{
+  return (m_refData != NULL);
+};
+
+int wxFont::GetPointSize(void) const
+{
+  return M_FONTDATA->m_pointSize;
+};
+
+wxString wxFont::GetFaceString(void) const
+{
+  wxString s = wxTheFontNameDirectory.GetFontName( M_FONTDATA->m_fontId );
+  return s;
+};
+
+wxString wxFont::GetFaceName(void) const
+{
+  wxString s = wxTheFontNameDirectory.GetFontName( M_FONTDATA->m_fontId );
+  return s; 
+};
+
+int wxFont::GetFamily(void) const
+{
+  return M_FONTDATA->m_family;
+};
+
+wxString wxFont::GetFamilyString(void) const
+{
+  wxString s = wx_font_family[M_FONTDATA->m_family];
+  return s;
+};
+
+int wxFont::GetFontId(void) const
+{
+  return M_FONTDATA->m_fontId; // stub
+};
+
+int wxFont::GetStyle(void) const
+{
+  return M_FONTDATA->m_style;
+};
+
+wxString wxFont::GetStyleString(void) const
+{
+  wxString s =  wx_font_style[M_FONTDATA->m_style];
+  return s;
+};
+
+int wxFont::GetWeight(void) const
+{
+  return M_FONTDATA->m_weight;
+};
+
+wxString wxFont::GetWeightString(void) const
+{
+  wxString s = wx_font_weight[M_FONTDATA->m_weight];
+  return s;
+};
+
+bool wxFont::GetUnderlined(void) const
+{
+  return M_FONTDATA->m_underlined;
+};
+
+//-----------------------------------------------------------------------------
+// get internal representation of font
+//-----------------------------------------------------------------------------
+
+// local help function
+static GdkFont *wxLoadQueryNearestFont(int point_size, int fontid,
+					   int style, int weight, 
+					   bool underlined);
+
+GdkFont *wxFont::GetInternalFont(float scale)
+{
+  if (M_FONTDATA->m_byXFontName) return M_FONTDATA->m_font;
+   
+  long int_scale = long(scale * 100.0 + 0.5); // key for fontlist
+  int point_scale = (M_FONTDATA->m_pointSize * 10 * int_scale) / 100;
+  GdkFont *font = NULL;
+
+  wxNode *node = M_FONTDATA->m_scaled_xfonts.Find(int_scale);
+  if (node) 
+  {
+    font = (GdkFont*)node->Data(); 
+  } 
+  else 
+  {
+     font = wxLoadQueryNearestFont( point_scale, M_FONTDATA->m_fontId, M_FONTDATA->m_style,
+				    M_FONTDATA->m_weight, M_FONTDATA->m_underlined );
+     M_FONTDATA->m_scaled_xfonts.Append( int_scale, (wxObject*)font );
+  };
+  if (!font)
+	printf("could not load any font");
+//	wxError("could not load any font", "wxFont");
+  return font;
+};
+
+//-----------------------------------------------------------------------------
+// local utilities to find a X font
+//-----------------------------------------------------------------------------
+
+static GdkFont *wxLoadQueryFont(int point_size, int fontid, int style,
+				    int weight, bool WXUNUSED(underlined))
+{
+    char buffer[512];
+    char *name = wxTheFontNameDirectory.GetScreenName( fontid, weight, style );
+
+    if (!name)
+	name = "-*-*-*-*-*-*-*-%d-*-*-*-*-*-*";
+    sprintf(buffer, name, point_size);
+
+    return gdk_font_load( buffer );
+}
+
+static GdkFont *wxLoadQueryNearestFont(int point_size, int fontid,
+					   int style, int weight,
+					   bool underlined)
+{
+    GdkFont *font;
+
+    font = wxLoadQueryFont( point_size, fontid, style, weight, underlined );
+
+    if (!font) {
+	// search up and down by stepsize 10
+	int max_size = point_size + 20 * (1 + (point_size/180));
+	int min_size = point_size - 20 * (1 + (point_size/180));
+	int i;
+
+	// Search for smaller size (approx.)
+	for (i=point_size-10; !font && i >= 10 && i >= min_size; i -= 10)
+	    font = wxLoadQueryFont(i, fontid, style, weight, underlined);
+	// Search for larger size (approx.)
+	for (i=point_size+10; !font && i <= max_size; i += 10)
+	    font = wxLoadQueryFont(i, fontid, style, weight, underlined);
+	// Try default family
+	if (!font && fontid != wxDEFAULT)
+	    font = wxLoadQueryFont(point_size, wxDEFAULT, style, 
+				   weight, underlined);
+	// Bogus font
+	if (!font)
+	    font = wxLoadQueryFont(120, wxDEFAULT, wxNORMAL, wxNORMAL,
+				    underlined);
+    }
+    return font;
+}
+
+//-----------------------------------------------------------------------------
+// face names and index functions
+//-----------------------------------------------------------------------------
+
+static char *font_defaults[] = {
+    "FamilyDefault", "Default",
+    "FamilyRoman", "Roman",
+    "FamilyDecorative", "Decorative",
+    "FamilyModern", "Modern",
+    "FamilyTeletype", "Teletype",
+    "FamilySwiss", "Swiss",
+    "FamilyScript", "Script",
+
+    "AfmMedium", "",
+    "AfmBold", "Bo",
+    "AfmLight", "",
+    "AfmStraight", "",
+    "AfmItalic", "${AfmSlant}",
+    "AfmSlant", "O",
+    "AfmRoman", "Ro",
+    "AfmTimes", "Times",
+    "AfmHelvetica", "Helv",
+    "AfmCourier", "Cour",
+    
+    "Afm___", "${AfmTimes,$[weight],$[style]}",
+
+    "AfmTimes__", "${AfmTimes}${Afm$[weight]}${Afm$[style]}",
+    "AfmTimesMediumStraight", "${AfmTimes}${AfmRoman}",
+    "AfmTimesLightStraight", "${AfmTimes}${AfmRoman}",
+    "AfmTimes_Italic", "${AfmTimes}$[weight]${AfmItalic}",
+    "AfmTimes_Slant", "${AfmTimes}$[weight]${AfmItalic}",
+
+    "AfmSwiss__", "${AfmHelvetica}${Afm$[weight]}${Afm$[style]}",
+    "AfmModern__", "${AfmCourier}${Afm$[weight]}${Afm$[style]}",
+
+    "AfmTeletype__", "${AfmModern,$[weight],$[style]}",
+
+    "PostScriptMediumStraight", "",
+    "PostScriptMediumItalic", "-Oblique",
+    "PostScriptMediumSlant", "-Oblique",
+    "PostScriptLightStraight", "",
+    "PostScriptLightItalic", "-Oblique",
+    "PostScriptLightSlant", "-Oblique",
+    "PostScriptBoldStraight", "-Bold",
+    "PostScriptBoldItalic", "-BoldOblique",
+    "PostScriptBoldSlant", "-BoldOblique",
+    
+#if WX_NORMALIZED_PS_FONTS
+    "PostScript___", "${PostScriptTimes,$[weight],$[style]}",
+#else
+    "PostScriptRoman__", "${PostScriptTimes,$[weight],$[style]}",
+    "PostScript___", "LucidaSans${PostScript$[weight]$[style]}",
+#endif
+
+    "PostScriptTimesMedium", "",
+    "PostScriptTimesLight", "",
+    "PostScriptTimesBold", "Bold",
+
+    "PostScriptTimes__", "Times${PostScript$[weight]$[style]}",
+    "PostScriptTimesMediumStraight", "Times-Roman",
+    "PostScriptTimesLightStraight", "Times-Roman",
+    "PostScriptTimes_Slant", "Times-${PostScriptTimes$[weight]}Italic",
+    "PostScriptTimes_Italic", "Times-${PostScriptTimes$[weight]}Italic",
+
+    "PostScriptSwiss__", "Helvetica${PostScript$[weight]$[style]}",
+    "PostScriptModern__", "Courier${PostScript$[weight]$[style]}",
+
+    "PostScriptTeletype__", "${PostScriptModern,$[weight],$[style]}",
+
+#if !WX_NORMALIZED_PS_FONTS
+    "PostScriptScript__", "Zapf-Chancery-MediumItalic",
+#endif
+
+    "ScreenMedium", "medium",
+    "ScreenBold", "bold",
+    "ScreenLight", "light",
+    "ScreenStraight", "r",
+    "ScreenItalic", "i",
+    "ScreenSlant", "o",
+
+    "ScreenDefaultBase", "misc-fixed",
+    "ScreenRomanBase", "*-times",
+    "ScreenDecorativeBase", "*-helvetica",
+    "ScreenModernBase", "*-courier",
+    "ScreenTeletypeBase", "*-lucidatypewriter",
+    "ScreenSwissBase", "*-lucida",
+    "ScreenScriptBase", "*-zapfchancery",
+
+    "ScreenStdSuffix", "-${Screen$[weight]}-${Screen$[style]}"
+    "-normal-*-*-%d-*-*-*-*-*-*",
+
+    "Screen___",
+    "-${ScreenDefaultBase}${ScreenStdSuffix}",
+    "ScreenRoman__",
+    "-${ScreenRomanBase}${ScreenStdSuffix}",
+    "ScreenDecorative__",
+    "-${ScreenDecorativeBase}${ScreenStdSuffix}",
+    "ScreenModern__",
+    "-${ScreenModernBase}${ScreenStdSuffix}",
+    "ScreenTeletype__",
+    "-${ScreenTeletypeBase}${ScreenStdSuffix}",
+    "ScreenSwiss__",
+    "-${ScreenSwissBase}${ScreenStdSuffix}",
+    "ScreenScript__",
+    "-${ScreenScriptBase}${ScreenStdSuffix}",
+    NULL
+};
+
+enum {wxWEIGHT_NORMAL, wxWEIGHT_BOLD,  wxWEIGHT_LIGHT, wxNUM_WEIGHTS};
+enum {wxSTYLE_NORMAL,  wxSTYLE_ITALIC, wxSTYLE_SLANT,  wxNUM_STYLES};
+
+static int WCoordinate(int w)
+{
+    switch (w) {
+    case wxBOLD:   return wxWEIGHT_BOLD;
+    case wxLIGHT:  return wxWEIGHT_LIGHT;
+    case wxNORMAL:
+    default:       return wxWEIGHT_NORMAL;
+    }
+}
+
+static int SCoordinate(int s)
+{
+    switch (s) {
+    case wxITALIC: return wxSTYLE_ITALIC;
+    case wxSLANT:  return wxSTYLE_SLANT;
+    case wxNORMAL:
+    default:       return wxSTYLE_NORMAL;
+    }
+}
+
+//-----------------------------------------------------------------------------
+// wxSuffixMap
+//-----------------------------------------------------------------------------
+
+class wxSuffixMap {
+public:
+    ~wxSuffixMap(void);
+
+    inline char *GetName(int weight, int style)
+    {
+	return ( map [WCoordinate(weight)] [SCoordinate(style)] );
+    }
+
+    char *map[wxNUM_WEIGHTS][wxNUM_STYLES];
+    void Initialize(const char *, const char *);
+};
+
+//#if !USE_RESOURCES
+#define wxGetResource(a, b, c) 0
+//#endif
+
+static void SearchResource(const char *prefix, const char **names, int count, char **v)
+{
+    int k, i, j;
+    char resource[1024], **defaults, *internal;
+
+    k = 1 << count;
+    
+    *v = NULL;
+    internal = NULL;
+
+    for (i = 0; i < k; i++) {
+	strcpy(resource, prefix);
+	for (j = 0; j < count; j++) {
+	    if (!(i & (1 << j)))
+		strcat(resource, names[j]);
+	    else
+		strcat(resource, "_");
+	}
+	if (wxGetResource(wxAPP_CLASS, (char *)resource, v))
+	    return;
+	if (!internal) {
+	    defaults = font_defaults;
+	    while (*defaults) {
+		if (!strcmp(*defaults, resource)) {
+		    internal = defaults[1];
+		    break;
+		}
+		defaults += 2;
+	    }
+	}
+    }
+    if (internal)
+	*v = copystring(internal);
+}
+
+wxSuffixMap::~wxSuffixMap(void)
+{
+    int k, j;
+
+    for (k = 0; k < wxNUM_WEIGHTS; ++k)
+	for (j = 0; j < wxNUM_STYLES; ++j)
+	    if (map[k][j]) {
+		delete[] map[k][j];
+		map[k][j] = NULL;
+	    }
+}
+
+void wxSuffixMap::Initialize(const char *resname, const char *devresname)
+{
+    const char *weight, *style;
+    char *v;
+    int i, j, k;
+    const char *names[3];
+
+    for (k = 0; k < wxNUM_WEIGHTS; k++) {
+	switch (k) {
+	case wxWEIGHT_NORMAL: weight = "Medium"; break;
+	case wxWEIGHT_LIGHT:  weight = "Light"; break;
+	case wxWEIGHT_BOLD:
+	default:	      weight = "Bold";
+	}
+	for (j = 0; j < wxNUM_STYLES; j++) {
+	    switch (j) {
+	    case wxSTYLE_NORMAL: style = "Straight"; break;
+	    case wxSTYLE_ITALIC: style = "Italic"; break;
+	    case wxSTYLE_SLANT:
+	    default:		 style = "Slant";
+	    }
+	    names[0] = resname;
+	    names[1] = weight;
+	    names[2] = style;
+
+	    SearchResource(devresname, names, 3, &v);
+
+	    /* Expand macros in the found string: */
+	found:
+	    int len, closer = 0, startpos = 0;
+	    
+	    len = (v ? strlen(v) : 0);
+	    for (i = 0; i < len; i++) {
+		if (v[i] == '$' && ((v[i+1] == '[') || (v[i+1] == '{'))) {
+		    startpos = i;
+		    closer   = (v[i+1] == '[') ? ']' : '}';
+		    ++i;
+		} else if (v[i] == closer) {
+		    int newstrlen;
+		    const char *r = NULL; bool delete_r = FALSE;
+		    char *name;
+	  
+		    name = v + startpos + 2;
+		    v[i] = 0;
+
+		    if (closer == '}') {
+			int i, count, len;
+			char **names;
+
+			for (i = 0, count = 1; name[i]; i++)
+			    if (name[i] == ',')
+				count++;
+	    
+			len = i;
+
+			names = new char*[count];
+			names[0] = name;
+			for (i = 0, count = 1; i < len; i++)
+			    if (name[i] == ',') {
+				names[count++] = name + i + 1;
+				name[i] = 0;
+			    }
+
+			SearchResource("", (const char **)names, count, (char **)&r);
+			delete_r = (r != 0);
+			delete[] names;
+			
+			if (!r) {
+			    for (i = 0; i < len; i++)
+				if (!name[i])
+				    name[i] = ',';
+			    r = "";
+			    printf("Bad resource name \"%s\" in font lookup\n", name);
+			}
+		    } else if (!strcmp(name, "weight")) {
+			r = weight;
+		    } else if (!strcmp(name, "style")) {
+			r = style;
+		    } else if (!strcmp(name, "family")) {
+			r = resname;
+		    } else {
+			r = "";
+			printf("Bad font macro name \"%s\"\n", name);
+		    }
+
+		    // add r to v
+		    newstrlen = strlen(r);
+		    char *naya = new char[startpos + newstrlen + len - i];
+		    memcpy(naya, v, startpos);
+		    memcpy(naya + startpos, r, newstrlen);
+		    memcpy(naya + startpos + newstrlen, v + i + 1, len - i);
+		    if (delete_r)
+		      delete[] (char*)r;
+		    delete[] v;
+		    v = naya;
+		    
+		    goto found;
+		}
+	    }
+	    /* We have a final value: */
+	    map[k][j] = v;
+	}
+    }
+}
+
+//-----------------------------------------------------------------------------
+// wxFontNameItem
+//-----------------------------------------------------------------------------
+
+class wxFontNameItem : public wxObject {
+DECLARE_DYNAMIC_CLASS(wxFontNameItem)
+public:
+    wxFontNameItem(const char *name, int id, int family);
+    ~wxFontNameItem();
+
+    inline char* GetScreenName(int w, int s)     {return screen.GetName(w, s);}
+    inline char* GetPostScriptName(int w, int s) {return printing.GetName(w, s);}
+    inline char* GetAFMName(int w, int s)        {return afm.GetName(w, s);}
+    inline char* GetName(void)                   {return name;}
+    inline int   GetFamily(void)                 {return family;}
+    inline int   GetId(void)                     {return id;}
+    inline bool  IsRoman(void)                   {return isroman;}
+#if WXDEBUG
+    void Dump(ostream& str);
+#endif
+
+    int id;
+    int family;
+    char *name;
+    wxSuffixMap screen, printing, afm;
+    bool isroman;
+};
+
+IMPLEMENT_ABSTRACT_CLASS(wxFontNameItem, wxObject)
+
+wxFontNameItem::wxFontNameItem(const char *Name, int Id, int Family)
+{
+    name   = copystring(Name);
+    id     = Id;
+    family = Family;
+
+    screen.  Initialize(name, "Screen");
+    printing.Initialize(name, "PostScript");
+    afm.     Initialize(name, "Afm");
+}
+
+wxFontNameItem::~wxFontNameItem(void)
+{
+    if (name)
+	delete[] name;
+    name = NULL;
+}
+
+#if WXDEBUG
+void wxFontNameItem::Dump(ostream& str)
+{
+    str << "wxFontNameItem(" << name << ")";
+}
+#endif
+
+//-----------------------------------------------------------------------------
+// wxFontDirectory
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxFontNameDirectory, wxObject)
+
+wxFontNameDirectory::wxFontNameDirectory(void)
+{
+    table = new wxHashTable(wxKEY_INTEGER, 20);
+    nextFontId = -1;
+    Initialize();
+}
+
+wxFontNameDirectory::~wxFontNameDirectory()
+{
+    // Cleanup wxFontNameItems allocated
+    table->BeginFind();
+    wxNode *node = table->Next();
+    while (node) {
+	wxFontNameItem *item = (wxFontNameItem*)node->Data();
+	delete item;
+	node = table->Next();
+    }
+    delete table;
+}
+
+int wxFontNameDirectory::GetNewFontId(void)
+{
+    return (nextFontId--);
+}
+
+void wxFontNameDirectory::Initialize()
+{
+    Initialize(wxDEFAULT,    wxDEFAULT,    "Default");
+    Initialize(wxDECORATIVE, wxDECORATIVE, "Decorative");
+    Initialize(wxROMAN,      wxROMAN,      "Roman");
+    Initialize(wxMODERN,     wxMODERN,     "Modern");
+    Initialize(wxTELETYPE,   wxTELETYPE,   "Teletype");
+    Initialize(wxSWISS,      wxSWISS,      "Swiss");
+    Initialize(wxSCRIPT,     wxSCRIPT,     "Script");
+}
+
+void wxFontNameDirectory::Initialize(int fontid, int family, const char *resname)
+{
+    char *fam, resource[256];
+  
+    sprintf(resource, "Family%s", resname);
+    SearchResource((const char *)resource, NULL, 0, (char **)&fam);
+    if (fam) {
+	if      (!strcmp(fam, "Default"))	family = wxDEFAULT;
+	else if (!strcmp(fam, "Roman"))		family = wxROMAN;
+	else if (!strcmp(fam, "Decorative"))	family = wxDECORATIVE;
+	else if (!strcmp(fam, "Modern"))	family = wxMODERN;
+	else if (!strcmp(fam, "Teletype"))	family = wxTELETYPE;
+	else if (!strcmp(fam, "Swiss"))		family = wxSWISS;
+	else if (!strcmp(fam, "Script"))	family = wxSCRIPT;
+	delete[] fam; // free resource
+    }
+    table->Put(fontid, new wxFontNameItem(resname, fontid, family));
+}
+
+int wxFontNameDirectory::FindOrCreateFontId(const char *name, int family)
+{
+    int id;
+
+    // font exists -> return id
+    if ( (id = GetFontId(name)) ) return id;
+    // create new font
+    Initialize(id=GetNewFontId(), family, name);
+    return id;
+}
+
+char *wxFontNameDirectory::GetScreenName(int fontid, int weight, int style)
+{
+    wxFontNameItem *item = (wxFontNameItem*)table->Get(fontid); // find font
+    if (item)
+	return item->GetScreenName(weight, style);
+    // font does not exist
+    return NULL;
+}
+
+char *wxFontNameDirectory::GetPostScriptName(int fontid, int weight, int style)
+{
+    wxFontNameItem *item = (wxFontNameItem*)table->Get(fontid); // find font
+    if (item)
+	return item->GetPostScriptName(weight, style);
+    // font does not exist
+    return NULL;
+}
+
+char *wxFontNameDirectory::GetAFMName(int fontid, int weight, int style)
+{
+    wxFontNameItem *item = (wxFontNameItem *)table->Get(fontid); // find font
+    if (item)
+	return item->GetAFMName(weight, style);
+    // font does not exist
+    return NULL;
+}
+
+char *wxFontNameDirectory::GetFontName(int fontid)
+{
+    wxFontNameItem *item = (wxFontNameItem *)table->Get(fontid); // find font
+    if (item)
+	return item->GetName();
+    // font does not exist
+    return NULL;
+}
+
+int wxFontNameDirectory::GetFontId(const char *name)
+{
+    wxNode *node;
+
+    table->BeginFind();
+
+    while ( (node = table->Next()) ) {
+	wxFontNameItem *item = (wxFontNameItem*)node->Data();
+	if (!strcmp(name, item->name))
+	    return item->id;
+    }
+    // font does not exist
+    return 0;
+}
+
+int wxFontNameDirectory::GetFamily(int fontid)
+{
+    wxFontNameItem *item = (wxFontNameItem *)table->Get(fontid);
+  
+    if (item)
+	return item->family;
+    // font does not exist
+    return wxDEFAULT;
+}
diff --git a/src/gtk/frame.cpp b/src/gtk/frame.cpp
new file mode 100644
index 0000000000..f70d0b9f31
--- /dev/null
+++ b/src/gtk/frame.cpp
@@ -0,0 +1,353 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        frame.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "frame.h"
+#endif
+
+#include "wx/frame.h"
+#include "wx/dialog.h"
+#include "wx/control.h"
+#include "wx/app.h"
+#include "wx/gtk/win_gtk.h"
+
+const wxMENU_HEIGHT    = 28;
+const wxSTATUS_HEIGHT  = 25;
+
+extern wxList wxTopLevelWindows;
+extern wxList wxPendingDelete;
+
+//-----------------------------------------------------------------------------
+// wxFrame
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// size
+
+void gtk_frame_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxFrame *win )
+{ 
+  if (!win->HasVMT()) return;
+
+/*
+  printf( "OnFrameResize from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  win->GtkOnSize( alloc->width, alloc->height );
+};
+
+//-----------------------------------------------------------------------------
+// delete
+
+bool gtk_frame_delete_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxFrame *win )
+{ 
+/*
+  printf( "OnDelete from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  win->Close();
+
+  return TRUE;
+};
+
+//-----------------------------------------------------------------------------
+
+BEGIN_EVENT_TABLE(wxFrame, wxWindow)
+  EVT_CLOSE(wxFrame::OnCloseWindow)
+  EVT_SIZE(wxFrame::OnSize)
+END_EVENT_TABLE()
+
+IMPLEMENT_DYNAMIC_CLASS(wxFrame,wxWindow)
+
+wxFrame::wxFrame(void)
+{
+  m_doingOnSize = FALSE;
+  m_frameMenuBar = NULL;
+  m_frameStatusBar = NULL;
+  m_sizeSet = FALSE;
+  wxTopLevelWindows.Insert( this );
+};
+
+wxFrame::wxFrame( wxWindow *parent, const wxWindowID id, const wxString &title, 
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  m_sizeSet = FALSE;
+  Create( parent, id, title, pos, size, style, name );
+  wxTopLevelWindows.Insert( this );
+};
+
+bool wxFrame::Create( wxWindow *parent, const wxWindowID id, const wxString &title,
+      const wxPoint &pos, const wxSize &size,
+      const long style, const wxString &name )
+{
+  m_needParent = FALSE;
+  m_mainWindow = NULL;
+  m_wxwindow = NULL;
+  
+  PreCreation( parent, id, pos, size, style, name );
+
+  m_doingOnSize = FALSE;
+  
+  m_title = title;
+  
+  m_widget = gtk_window_new( GTK_WINDOW_TOPLEVEL );
+  if ((size.x != -1) && (size.y != -1)) 
+    gtk_widget_set_usize( m_widget, m_width, m_height );
+  if ((pos.x != -1) && (pos.y != -1)) 
+    gtk_widget_set_uposition( m_widget, m_x, m_y );
+  
+  gtk_window_set_title( GTK_WINDOW(m_widget), title );
+  GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
+  
+  gtk_widget_set( m_widget, "GtkWindow::allow_shrink", TRUE, NULL);
+  
+  gtk_signal_connect( GTK_OBJECT(m_widget), "delete_event", 
+    GTK_SIGNAL_FUNC(gtk_frame_delete_callback), (gpointer)this );
+    
+  m_mainWindow = gtk_myfixed_new();
+  gtk_widget_show( m_mainWindow );
+  GTK_WIDGET_UNSET_FLAGS( m_mainWindow, GTK_CAN_FOCUS );
+  
+  gtk_container_add( GTK_CONTAINER(m_widget), m_mainWindow );
+  gtk_widget_set_uposition( m_mainWindow, 0, 0 );
+  
+  m_wxwindow = gtk_myfixed_new();
+  gtk_widget_show( m_wxwindow );
+  GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
+  
+  gtk_container_add( GTK_CONTAINER(m_mainWindow), m_wxwindow );
+  
+  m_frameMenuBar = NULL;
+  m_frameStatusBar = NULL;
+  
+  gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate", 
+    GTK_SIGNAL_FUNC(gtk_frame_size_callback), (gpointer)this );
+  
+  PostCreation();
+  
+  gtk_widget_realize( m_mainWindow );
+  
+  return TRUE;
+};
+
+wxFrame::~wxFrame(void)
+{
+  if (m_frameMenuBar) delete m_frameMenuBar;
+  if (m_frameStatusBar) delete m_frameStatusBar;
+  
+//  if (m_mainWindow) gtk_widget_destroy( m_mainWindow );
+
+  wxTopLevelWindows.DeleteObject( this );
+  if (wxTopLevelWindows.Number() == 0) wxTheApp->ExitMainLoop();
+};
+      
+bool wxFrame::Show( const bool show )
+{
+  if (show)
+  {
+    wxSizeEvent event( wxSize(m_width,m_height), GetId() );
+    m_sizeSet = FALSE;
+    ProcessEvent( event );
+  };
+  return wxWindow::Show( show );
+};
+
+void wxFrame::Enable( const bool enable )
+{
+  wxWindow::Enable( enable );
+  gtk_widget_set_sensitive( m_mainWindow, enable );
+};
+
+void wxFrame::OnCloseWindow( wxCloseEvent& WXUNUSED(event) )
+{
+  this->Destroy();
+};
+
+bool wxFrame::Destroy(void)
+{
+  if (!wxPendingDelete.Member(this))
+    wxPendingDelete.Append(this);
+    
+  return TRUE;
+}
+
+void wxFrame::GetClientSize( int *width, int *height ) const
+{
+  wxWindow::GetClientSize( width, height );
+  if (height)
+  {
+    if (m_frameMenuBar) (*height) -= wxMENU_HEIGHT;
+    if (m_frameStatusBar) (*height) -= wxSTATUS_HEIGHT;
+  };
+};
+
+void wxFrame::GtkOnSize( int width, int height )
+{
+  if ((m_height == height) && (m_width == width) &&
+      (m_sizeSet)) return;
+  if (!m_mainWindow) return;
+  if (!m_wxwindow) return;
+
+  m_width = width;
+  m_height = height;
+  
+  gtk_widget_set_usize( m_widget, width, height );
+  
+  int main_x = 0;
+  int main_y = 0;
+  int main_height = height;
+  int main_width = width;
+  
+  // This emulates Windows behaviour:
+  // The menu bar is part of the main window, but the status bar
+  // is on the implementation side in the client area. The
+  // function GetClientSize returns the size of the client area
+  // minus the status bar height. Under wxGTK, the main window
+  // is represented by m_mainWindow. The menubar is inserted
+  // into m_mainWindow whereas the statusbar is insertes into
+  // m_wxwindow just like any other window.
+  
+//  not really needed
+  gtk_widget_set_usize( m_mainWindow, width, height );
+    
+  if (m_frameMenuBar)
+  {
+    main_y = wxMENU_HEIGHT;
+    main_height -= wxMENU_HEIGHT;
+  };
+  
+  gtk_widget_set_uposition( GTK_WIDGET(m_wxwindow), main_x, main_y );
+  gtk_widget_set_usize( GTK_WIDGET(m_wxwindow), main_width, main_height );
+  
+  if (m_frameMenuBar)
+  {
+    gtk_widget_set_uposition( m_frameMenuBar->m_widget, 1, 1 );
+    gtk_widget_set_usize( m_frameMenuBar->m_widget, width-2, wxMENU_HEIGHT-2 );
+  };
+  
+  if (m_frameStatusBar)
+  {
+    m_frameStatusBar->SetSize( 0, main_height-wxSTATUS_HEIGHT, width, wxSTATUS_HEIGHT );
+  };
+
+  m_sizeSet = TRUE;
+  
+  wxSizeEvent event( wxSize(m_width,m_height), GetId() );
+  event.SetEventObject( this );
+  ProcessEvent( event );
+};
+
+void wxFrame::OnSize( wxSizeEvent &WXUNUSED(event) )
+{
+  wxWindow *child = NULL;
+  int noChildren = 0;
+  for(wxNode *node = GetChildren()->First(); node; node = node->Next())
+  {
+    wxWindow *win = (wxWindow *)node->Data();
+    if (!win->IsKindOf(CLASSINFO(wxFrame)) && 
+        !win->IsKindOf(CLASSINFO(wxDialog)) 
+/*      && (win != m_frameMenuBar) &&
+	(win != m_frameStatusBar)    not in m_children anyway */
+       )
+    {
+      child = win;
+      noChildren ++;
+    };
+  }
+;
+
+  if ((child) && (noChildren == 1))
+  {
+    int client_x, client_y;
+
+    GetClientSize(&client_x, &client_y);
+
+    child->SetSize( 1, 1, client_x-2, client_y);
+  }
+;
+};
+
+void SetInvokingWindow( wxMenu *menu, wxWindow *win )
+{
+  menu->SetInvokingWindow( win );
+  wxNode *node = menu->m_items.First();
+  while (node)
+  {
+    wxMenuItem *menuitem = (wxMenuItem*)node->Data();
+    if (menuitem->m_isSubMenu) SetInvokingWindow( menuitem->m_subMenu, win );
+    node = node->Next();
+  };
+};
+
+void wxFrame::SetMenuBar( wxMenuBar *menuBar )
+{
+  m_frameMenuBar = menuBar;
+  
+  wxNode *node = m_frameMenuBar->m_menus.First();
+  while (node)
+  {
+    wxMenu *menu = (wxMenu*)node->Data();
+    SetInvokingWindow( menu, this );   
+    node = node->Next();
+  };
+  
+  m_frameMenuBar->m_parent = this;
+  gtk_myfixed_put( GTK_MYFIXED(m_mainWindow), 
+    m_frameMenuBar->m_widget, m_frameMenuBar->m_x, m_frameMenuBar->m_y );
+};   
+
+bool wxFrame::CreateStatusBar( const int number )
+{
+  if (m_frameStatusBar)
+  delete m_frameStatusBar;
+  
+  m_frameStatusBar = new wxStatusBar( this, -1, wxPoint(0,0), wxSize(100,20) );
+
+  m_frameStatusBar->SetFieldsCount( number );
+  return TRUE;
+};
+
+void wxFrame::SetStatusText( const wxString &text, const int number )
+{
+  if (m_frameStatusBar) m_frameStatusBar->SetStatusText( text, number );
+};
+
+void wxFrame::SetStatusWidths( const int n, const int *width )
+{
+  if (m_frameStatusBar) m_frameStatusBar->SetStatusWidths( n, width );
+};
+
+wxStatusBar *wxFrame::GetStatusBar(void)
+{
+  return m_frameStatusBar;
+};
+
+wxMenuBar *wxFrame::GetMenuBar(void)
+{
+  return m_frameMenuBar;
+};
+
+void wxFrame::SetTitle( const wxString &title )
+{
+  m_title = title;
+  gtk_window_set_title( GTK_WINDOW(m_widget), title );
+};
+
+wxString wxFrame::GetTitle(void) const
+{
+  return (wxString&)m_title;
+};
+
diff --git a/src/gtk/gdiobj.cpp b/src/gtk/gdiobj.cpp
new file mode 100644
index 0000000000..8df2e5ff09
--- /dev/null
+++ b/src/gtk/gdiobj.cpp
@@ -0,0 +1,21 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        gdiobj.cpp
+// Purpose:     wxGDIObject class
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "gdiobj.h"
+#endif
+
+#include "wx/gdiobj.h"
+
+#if !USE_SHARED_LIBRARIES
+IMPLEMENT_DYNAMIC_CLASS(wxGDIObject, wxObject)
+#endif
+
diff --git a/src/gtk/horiz.xbm b/src/gtk/horiz.xbm
new file mode 100644
index 0000000000..ff3309bcc4
--- /dev/null
+++ b/src/gtk/horiz.xbm
@@ -0,0 +1,6 @@
+#define horiz_width 15
+#define horiz_height 15
+static char horiz_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xff, 0x7f, 0x00, 0x00, 0x00, 0x00};
diff --git a/src/gtk/icon.cpp b/src/gtk/icon.cpp
new file mode 100644
index 0000000000..a65627746c
--- /dev/null
+++ b/src/gtk/icon.cpp
@@ -0,0 +1,22 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        icon.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "icon.h"
+#endif
+
+#include "wx/icon.h"
+
+//-----------------------------------------------------------------------------
+// wxIcon
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxIcon,wxBitmap)
+
diff --git a/src/gtk/listbox.cpp b/src/gtk/listbox.cpp
new file mode 100644
index 0000000000..37dd67fef3
--- /dev/null
+++ b/src/gtk/listbox.cpp
@@ -0,0 +1,266 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        listbox.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "listbox.h"
+#endif
+
+#include "wx/listbox.h"
+
+//-----------------------------------------------------------------------------
+// wxListBox
+//-----------------------------------------------------------------------------
+
+void gtk_listitem_select_callback( GtkWidget *widget, gpointer data )
+{
+  wxListBox *listbox = (wxListBox*)data;
+
+  wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, listbox->GetId() );
+  
+  event.SetInt( listbox->GetIndex( widget ) );
+  
+  GtkBin *bin = GTK_BIN( widget );
+  GtkLabel *label = GTK_LABEL( bin->child );
+  wxString tmp( label->label );
+  event.SetString( WXSTRINGCAST(tmp) );
+  
+  event.SetEventObject( listbox );
+  
+  listbox->ProcessEvent( event );
+};
+
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxListBox,wxControl)
+
+wxListBox::wxListBox(void)
+{
+  m_list = NULL;
+};
+
+wxListBox::wxListBox( wxWindow *parent, wxWindowID id, 
+      const wxPoint &pos, const wxSize &size, 
+      const int n, const wxString choices[],
+      const long style, const wxString &name )
+{
+  Create( parent, id, pos, size, n, choices, style, name );
+};
+
+bool wxListBox::Create( wxWindow *parent, wxWindowID id, 
+      const wxPoint &pos, const wxSize &size, 
+      const int n, const wxString choices[],
+      const long style, const wxString &name )
+{
+  m_needParent = TRUE;
+  
+  PreCreation( parent, id, pos, size, style, name );
+  
+  m_widget = gtk_scrolled_window_new( NULL, NULL );
+  gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(m_widget),
+    GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
+  
+  m_list = GTK_LIST( gtk_list_new() );
+  gtk_list_set_selection_mode( GTK_LIST(m_list), GTK_SELECTION_BROWSE );
+  
+  gtk_container_add (GTK_CONTAINER(m_widget), GTK_WIDGET(m_list) );
+  gtk_widget_show( GTK_WIDGET(m_list) );
+  
+  for (int i = 0; i < n; i++)
+  {
+    GtkWidget *list_item;
+    list_item = gtk_list_item_new_with_label( choices[i] ); 
+  
+    gtk_signal_connect( GTK_OBJECT(list_item), "select", 
+      GTK_SIGNAL_FUNC(gtk_listitem_select_callback), (gpointer)this );
+  
+    gtk_container_add( GTK_CONTAINER(m_list), list_item );
+    
+    gtk_widget_show( list_item );
+  };
+ 
+  PostCreation();
+  
+  Show( TRUE );
+  
+  return TRUE;
+};
+
+void wxListBox::Append( const wxString &item )
+{
+  GtkWidget *list_item;
+  list_item = gtk_list_item_new_with_label( item ); 
+  
+ gtk_signal_connect( GTK_OBJECT(list_item), "select", 
+    GTK_SIGNAL_FUNC(gtk_listitem_select_callback), (gpointer)this );
+  
+  gtk_container_add( GTK_CONTAINER(m_list), list_item );
+    
+  gtk_widget_show( list_item );
+};
+
+void wxListBox::Append( const wxString &WXUNUSED(item), char *WXUNUSED(clientData) )
+{
+};
+
+void wxListBox::Clear(void)
+{
+  gtk_list_clear_items( m_list, 0, Number() );
+};
+
+void wxListBox::Delete( int n )
+{
+  gtk_list_clear_items( m_list, n, n );
+};
+
+void wxListBox::Deselect( int n )
+{
+  gtk_list_unselect_item( m_list, n );
+};
+
+int wxListBox::FindString( const wxString &item ) const
+{
+  GList *child = m_list->children;
+  int count = 0;
+  while (child)
+  {
+    GtkBin *bin = GTK_BIN( child->data );
+    GtkLabel *label = GTK_LABEL( bin->child );
+    if (item == label->label) return count;
+    count++;
+    child = child->next;
+  };
+  return -1;
+};
+
+char *wxListBox::GetClientData( const int WXUNUSED(n) ) const
+{
+  return NULL;
+};
+
+int wxListBox::GetSelection(void) const
+{
+  GList *selection = m_list->selection;
+  if (selection)
+  {
+    GList *child = m_list->children;
+    int count = 0;
+    while (child)
+    {
+      if (child->data == selection->data) return count;
+      count++;
+      child = child->next;
+    };
+  };
+  return -1;
+};
+
+int wxListBox::GetSelections( int **WXUNUSED(selections) ) const
+{
+  return 0;
+};
+
+wxString wxListBox::GetString( int n ) const
+{
+  GList *child = g_list_nth( m_list->children, n );
+  if (child)
+  {
+    GtkBin *bin = GTK_BIN( child->data );
+    GtkLabel *label = GTK_LABEL( bin->child );
+    return label->label;
+  };
+  return "";
+};
+
+wxString wxListBox::GetStringSelection(void) const
+{
+  GList *selection = m_list->selection;
+  if (selection)
+  {
+    GtkBin *bin = GTK_BIN( selection->data );
+    wxString tmp = GTK_LABEL( bin->child )->label;
+    return tmp;
+  };
+  return "";
+};
+
+int wxListBox::Number(void)
+{
+  GList *child = m_list->children;
+  int count = 0;
+  while (child) { count++; child = child->next; };
+  return count;
+};
+
+bool wxListBox::Selected( const int n )
+{
+  GList *target = g_list_nth( m_list->children, n );
+  if (target)
+  {
+    GList *child = m_list->selection;
+    while (child)
+    {
+      if (child->data == target->data) return TRUE;
+      child = child->next;
+    };
+  };
+  return FALSE;
+};
+
+void wxListBox::Set( const int WXUNUSED(n), const wxString *WXUNUSED(choices) )
+{
+};
+
+void wxListBox::SetClientData( const int WXUNUSED(n), char *WXUNUSED(clientData) )
+{
+};
+
+void wxListBox::SetFirstItem( int WXUNUSED(n) )
+{
+};
+
+void wxListBox::SetFirstItem( const wxString &WXUNUSED(item) )
+{
+};
+
+void wxListBox::SetSelection( const int n, const bool select )
+{
+  if (select)
+    gtk_list_select_item( m_list, n );
+  else
+    gtk_list_unselect_item( m_list, n );
+};
+
+void wxListBox::SetString( const int WXUNUSED(n), const wxString &WXUNUSED(string) )
+{
+};
+
+void wxListBox::SetStringSelection( const wxString &string, const bool select )
+{
+  SetSelection( FindString(string), select );
+};
+
+int wxListBox::GetIndex( GtkWidget *item ) const
+{
+  if (item)
+  {
+    GList *child = m_list->children;
+    int count = 0;
+    while (child)
+    {
+      if (GTK_WIDGET(child->data) == item) return count;
+      count++;
+      child = child->next;
+    };
+  };
+  return -1;
+};
+
+
diff --git a/src/gtk/mdi.cpp b/src/gtk/mdi.cpp
new file mode 100644
index 0000000000..3ec3c31969
--- /dev/null
+++ b/src/gtk/mdi.cpp
@@ -0,0 +1,198 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        mdi.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "mdi.h"
+#endif
+
+#include "wx/mdi.h"
+
+//-----------------------------------------------------------------------------
+// wxMDIParentFrame
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame,wxFrame)
+
+wxMDIParentFrame::wxMDIParentFrame(void)
+{
+  m_clientWindow = NULL;
+  m_currentChild = NULL;
+  m_parentFrameActive = TRUE;
+};
+
+wxMDIParentFrame::wxMDIParentFrame( wxWindow *parent,
+      const wxWindowID id, const wxString& title,
+      const wxPoint& pos, const wxSize& size,
+      const long style, const wxString& name )
+{
+  m_clientWindow = NULL;
+  m_currentChild = NULL;
+  m_parentFrameActive = TRUE;
+  Create( parent, id, title, pos, size, style, name );
+};
+
+wxMDIParentFrame::~wxMDIParentFrame(void)
+{
+};
+
+bool wxMDIParentFrame::Create( wxWindow *parent,
+      const wxWindowID id, const wxString& title,
+      const wxPoint& pos, const wxSize& size,
+      const long style, const wxString& name )
+{
+  wxFrame::Create( parent, id, title, pos, size, style, name );
+  
+  OnCreateClient();
+  
+  return TRUE;
+};
+
+void wxMDIParentFrame::OnSize( wxSizeEvent& event )
+{
+  wxFrame::OnSize( event );
+};
+
+void wxMDIParentFrame::OnActivate( wxActivateEvent& WXUNUSED(event) )
+{
+};
+
+void wxMDIParentFrame::SetMenuBar( wxMenuBar *menu_bar )
+{
+  wxFrame::SetMenuBar( menu_bar );
+};
+
+void wxMDIParentFrame::GetClientSize(int *width, int *height ) const
+{
+  wxFrame::GetClientSize( width, height );
+};
+
+wxMDIChildFrame *wxMDIParentFrame::GetActiveChild(void) const
+{
+  return m_currentChild;
+};
+
+wxMDIClientWindow *wxMDIParentFrame::GetClientWindow(void) const
+{
+  return m_clientWindow;
+};
+
+wxMDIClientWindow *wxMDIParentFrame::OnCreateClient(void)
+{
+  m_clientWindow = new wxMDIClientWindow( this );
+  return m_clientWindow;
+};
+
+void wxMDIParentFrame::ActivateNext(void)
+{
+};
+
+void wxMDIParentFrame::ActivatePrevious(void)
+{
+};
+
+void wxMDIParentFrame::OnSysColourChanged( wxSysColourChangedEvent& WXUNUSED(event) )
+{
+};
+
+//-----------------------------------------------------------------------------
+// wxMDIChildFrame
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame,wxPanel)
+  
+wxMDIChildFrame::wxMDIChildFrame(void)
+{
+};
+
+wxMDIChildFrame::wxMDIChildFrame( wxMDIParentFrame *parent,
+      const wxWindowID id, const wxString& title,
+      const wxPoint& pos, const wxSize& size,
+      const long style, const wxString& name )
+{
+  Create( parent, id, title, pos, size, style, name );
+};
+
+wxMDIChildFrame::~wxMDIChildFrame(void)
+{
+};
+
+bool wxMDIChildFrame::Create( wxMDIParentFrame *parent,
+      const wxWindowID id, const wxString& title,
+      const wxPoint& pos, const wxSize& size,
+      const long style, const wxString& name )
+{
+  m_title = title;
+  return wxPanel::Create( parent->GetClientWindow(), id, pos, size, style, name );
+};
+
+void wxMDIChildFrame::SetMenuBar( wxMenuBar *WXUNUSED(menu_bar) )
+{
+};
+
+void wxMDIChildFrame::Activate(void)
+{
+};
+
+//-----------------------------------------------------------------------------
+// wxMDIClientWindow
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow,wxWindow)
+
+wxMDIClientWindow::wxMDIClientWindow(void)
+{
+};
+
+wxMDIClientWindow::wxMDIClientWindow( wxMDIParentFrame *parent, const long style )
+{
+  CreateClient( parent, style );
+};
+
+wxMDIClientWindow::~wxMDIClientWindow(void)
+{
+};
+
+bool wxMDIClientWindow::CreateClient( wxMDIParentFrame *parent, const long style )
+{
+  m_needParent = TRUE;
+  
+  PreCreation( parent, -1, wxPoint(10,10), wxSize(100,100), style, "wxMDIClientWindow" );
+
+  m_widget = gtk_notebook_new();
+  
+  PostCreation();
+  
+  Show( TRUE );
+  
+  return TRUE;
+};
+
+void wxMDIClientWindow::AddChild( wxWindow *child )
+{
+  m_children.Append( child );
+  
+  wxString s;
+
+  if (child->IsKindOf(CLASSINFO(wxMDIChildFrame)))
+  {
+    wxMDIChildFrame* mdi_child = (wxMDIChildFrame*) child;
+    s = mdi_child->m_title;
+  };
+  
+  if (s.IsNull()) s = "MDI child";
+  
+  GtkWidget *label_widget;
+  label_widget = gtk_label_new( s );
+  gtk_misc_set_alignment( GTK_MISC(label_widget), 0.0, 0.5 );
+
+  gtk_notebook_append_page( GTK_NOTEBOOK(m_widget), child->m_widget, label_widget );
+};
+
+
diff --git a/src/gtk/menu.cpp b/src/gtk/menu.cpp
new file mode 100644
index 0000000000..5db3904638
--- /dev/null
+++ b/src/gtk/menu.cpp
@@ -0,0 +1,293 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        menu.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "menu.h"
+#endif
+
+#include "wx/menu.h"
+
+//-----------------------------------------------------------------------------
+// wxMenuBar
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxMenuBar,wxWindow)
+
+wxMenuBar::wxMenuBar(void)
+{
+  m_needParent = FALSE; // hmmm
+  
+  PreCreation( NULL, -1, wxDefaultPosition, wxDefaultSize, 0, "menu" );
+
+  m_menus.DeleteContents( TRUE );
+  
+  m_widget = gtk_handle_box_new();
+  
+  m_menubar = gtk_menu_bar_new();
+  
+  gtk_container_add( GTK_CONTAINER(m_widget), m_menubar );
+  
+  gtk_widget_show( m_menubar );
+  
+  PostCreation();
+
+  Show( TRUE );
+};
+
+void wxMenuBar::Append( wxMenu *menu, const wxString &title )
+{
+  m_menus.Append( menu );
+  menu->m_title = title;    // ??????
+  
+  size_t pos;
+  do {
+    pos = menu->m_title.First( '&' );
+    if (pos != wxString::npos) menu->m_title.Remove( pos, 1 );
+  } while (pos != wxString::npos);
+  
+  GtkWidget *root_menu;
+  root_menu = gtk_menu_item_new_with_label( WXSTRINGCAST(menu->m_title) );
+  gtk_widget_show( root_menu );
+  gtk_menu_item_set_submenu( GTK_MENU_ITEM(root_menu), menu->m_menu );
+  
+  gtk_menu_bar_append( GTK_MENU_BAR(m_menubar), root_menu );
+};
+    
+int FindMenuItemRecursive( const wxMenu *menu, const wxString &menuString, const wxString &itemString )
+{
+  if (menu->m_title == menuString)
+  {
+    int res = menu->FindItem( itemString );
+    if (res != -1) return res;
+  };
+  wxNode *node = menu->m_items.First();
+  while (node)
+  {
+    wxMenuItem *item = (wxMenuItem*)node->Data();
+    if (item->m_subMenu) return FindMenuItemRecursive( item->m_subMenu, menuString, itemString );
+    node = node->Next();
+  };
+  return -1;
+};
+
+int wxMenuBar::FindMenuItem( const wxString &menuString, const wxString &itemString ) const
+{
+  wxNode *node = m_menus.First();
+  while (node)
+  {
+    wxMenu *menu = (wxMenu*)node->Data();
+    int res = FindMenuItemRecursive( menu, menuString, itemString);
+    if (res != -1) return res;
+    node = node->Next();
+  };
+  return -1;
+};
+
+    
+//-----------------------------------------------------------------------------
+// wxMenu
+//-----------------------------------------------------------------------------
+
+void gtk_menu_clicked_callback( GtkWidget *widget, gpointer data )
+{
+  wxMenu *menu = (wxMenu*)data;
+  int id = menu->FindMenuIdByMenuItem(widget);
+  
+  if (!menu->Enabled(id)) return;
+  
+  wxCommandEvent event( wxEVENT_TYPE_MENU_COMMAND, id );
+  event.SetEventObject( menu );
+  event.SetInt(id );
+  wxWindow *win = menu->GetInvokingWindow();
+  if (win) win->ProcessEvent( event );
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxMenuItem,wxObject)
+  
+wxMenuItem::wxMenuItem(void)
+{
+  m_id = 0;
+  m_text = "";
+  m_isCheckMenu = FALSE;
+  m_checked = FALSE;
+  m_isSubMenu = FALSE; 
+  m_subMenu = NULL;
+  m_helpStr = "";
+  m_menuItem = NULL;
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxMenu,wxEvtHandler)
+
+wxMenu::wxMenu( const wxString &title )
+{
+  m_title = title;
+  m_items.DeleteContents( TRUE );
+  m_invokingWindow = NULL;
+  m_menu = gtk_menu_new();  // Do not show!
+};
+
+void wxMenu::AppendSeparator(void)
+{
+  wxMenuItem *mitem = new wxMenuItem();
+  mitem->m_id = -1;
+  mitem->m_text = "";
+  mitem->m_helpStr = "";
+  mitem->m_isCheckMenu = FALSE;
+  mitem->m_isEnabled = TRUE;
+  mitem->m_menuItem = gtk_menu_item_new();
+  gtk_menu_append( GTK_MENU(m_menu), mitem->m_menuItem );
+  gtk_widget_show( mitem->m_menuItem );
+  m_items.Append( mitem );
+};
+
+void wxMenu::Append( const int id, const wxString &item, const wxString &helpStr, const bool checkable )
+{
+  wxMenuItem *mitem = new wxMenuItem();
+  mitem->m_id = id;
+  
+  mitem->m_text = item;
+  size_t pos;
+  do {
+    pos = mitem->m_text.First( '&' );
+    if (pos != wxString::npos) mitem->m_text.Remove( pos, 1 );
+  } while (pos != wxString::npos);
+  
+  mitem->m_helpStr = helpStr;
+  mitem->m_isCheckMenu = checkable;
+  mitem->m_isEnabled = TRUE;
+  if (checkable)
+    mitem->m_menuItem = gtk_check_menu_item_new_with_label( WXSTRINGCAST(mitem->m_text) );
+  else
+    mitem->m_menuItem = gtk_menu_item_new_with_label( WXSTRINGCAST(mitem->m_text) );
+    
+  gtk_signal_connect( GTK_OBJECT(mitem->m_menuItem), "activate", 
+    GTK_SIGNAL_FUNC(gtk_menu_clicked_callback), (gpointer*)this );
+  
+  gtk_menu_append( GTK_MENU(m_menu), mitem->m_menuItem );
+  gtk_widget_show( mitem->m_menuItem );
+  m_items.Append( mitem );
+};
+
+void wxMenu::Append( const int id, const wxString &item, wxMenu *subMenu, const wxString &helpStr )
+{
+  wxMenuItem *mitem = new wxMenuItem();
+  mitem->m_id = id;
+  mitem->m_text = item;
+  mitem->m_isEnabled = TRUE;
+  
+  size_t pos;
+  do {
+    pos = mitem->m_text.First( '&' );
+    if (pos != wxString::npos) mitem->m_text.Remove( pos, 1 );
+  } while (pos != wxString::npos);
+  
+  mitem->m_helpStr = helpStr;
+  mitem->m_menuItem = gtk_menu_item_new_with_label( WXSTRINGCAST(mitem->m_text) );
+  
+  mitem->m_subMenu = subMenu;
+  gtk_menu_item_set_submenu( GTK_MENU_ITEM(mitem->m_menuItem), subMenu->m_menu );
+  gtk_menu_append( GTK_MENU(m_menu), mitem->m_menuItem );
+  gtk_widget_show( mitem->m_menuItem );
+  m_items.Append( mitem );
+};
+
+int wxMenu::FindItem( const wxString itemString ) const
+{
+  wxString s( itemString );
+  
+  size_t pos;
+  do {
+    pos = s.First( '&' );
+    if (pos != wxString::npos) s.Remove( pos, 1 );
+  } while (pos != wxString::npos);
+  
+  wxNode *node = m_items.First();
+  while (node)
+  {
+    wxMenuItem *item = (wxMenuItem*)node->Data();
+    if (item->m_text == s) return item->m_id;
+    node = node->Next();
+  };
+  return -1;
+};
+
+void wxMenu::Enable( const int id, const bool enable )
+{
+  wxNode *node = m_items.First();
+  while (node)
+  {
+    wxMenuItem *item = (wxMenuItem*)node->Data();
+    if (item->m_id == id)
+    {
+      item->m_isEnabled = enable;
+      return;
+    };
+    node = node->Next();
+  };
+};
+
+bool wxMenu::Enabled( const int id ) const
+{
+  wxNode *node = m_items.First();
+  while (node)
+  {
+    wxMenuItem *item = (wxMenuItem*)node->Data();
+    if (item->m_id == id) return item->m_isEnabled;
+    node = node->Next();
+  };
+  return FALSE;
+};
+
+void wxMenu::SetLabel( const int id, const wxString &label )
+{
+  wxString s( label );
+  size_t pos;
+  do {
+    pos = s.First( '&' );
+    if (pos != wxString::npos) s.Remove( pos, 1 );
+  } while (pos != wxString::npos);
+  
+  wxNode *node = m_items.First();
+  while (node)
+  {
+    wxMenuItem *item = (wxMenuItem*)node->Data();
+    item->m_text = s;
+    if (item->m_id == id)
+    {
+      gtk_label_set( GTK_LABEL( GTK_BIN(item->m_menuItem)->child ), WXSTRINGCAST(s) );
+    };
+    node = node->Next();
+  };
+};
+
+int wxMenu::FindMenuIdByMenuItem( GtkWidget *menuItem ) const
+{
+  wxNode *node = m_items.First();
+  while (node)
+  {
+    wxMenuItem *item = (wxMenuItem*)node->Data();
+    if (item->m_menuItem == menuItem) return item->m_id;
+    node = node->Next();
+  };
+  return -1;
+};
+
+void wxMenu::SetInvokingWindow( wxWindow *win )
+{
+  m_invokingWindow = win;
+};
+
+wxWindow *wxMenu::GetInvokingWindow(void)
+{
+  return m_invokingWindow;
+};
+
+
diff --git a/src/gtk/palette.cpp b/src/gtk/palette.cpp
new file mode 100644
index 0000000000..162fb0effe
--- /dev/null
+++ b/src/gtk/palette.cpp
@@ -0,0 +1,106 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        palette.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "palette.h"
+#endif
+
+#include "wx/palette.h"
+
+//-----------------------------------------------------------------------------
+// wxPalette
+//-----------------------------------------------------------------------------
+
+class wxPaletteRefData: public wxObjectRefData
+{
+  public:
+  
+    wxPaletteRefData(void);
+    ~wxPaletteRefData(void);
+  
+    GdkColormap  *m_colormap;
+};
+
+wxPaletteRefData::wxPaletteRefData(void)
+{
+  m_colormap = NULL;
+};
+
+wxPaletteRefData::~wxPaletteRefData(void)
+{
+  if (m_colormap) gdk_colormap_unref( m_colormap );
+};
+
+//-----------------------------------------------------------------------------
+
+#define M_PALETTEDATA ((wxPaletteRefData *)m_refData)
+
+IMPLEMENT_DYNAMIC_CLASS(wxPalette,wxGDIObject)
+
+wxPalette::wxPalette(void)
+{
+};
+
+wxPalette::wxPalette( const int n, const unsigned char *red, const unsigned char *green, const unsigned char *blue )
+{
+  m_refData = new wxPaletteRefData();
+  Create( n, red, green, blue );
+};
+
+wxPalette::wxPalette( const wxPalette& palette )
+{
+  Ref( palette );
+};
+
+wxPalette::wxPalette( const wxPalette* palette )
+{
+  UnRef();
+  if (palette) Ref( *palette ); 
+};
+
+wxPalette::~wxPalette(void)
+{
+};
+
+wxPalette& wxPalette::operator = ( const wxPalette& palette )
+{
+  if (*this == palette) return (*this); 
+  Ref( palette ); 
+  return *this; 
+};
+
+bool wxPalette::operator == ( const wxPalette& palette )
+{
+  return m_refData == palette.m_refData; 
+};
+
+bool wxPalette::operator != ( const wxPalette& palette )
+{
+  return m_refData != palette.m_refData; 
+};
+
+bool wxPalette::Ok(void) const
+{
+  return (m_refData);
+};
+
+bool wxPalette::Create( const int n, const unsigned char *red, const unsigned char *green, const unsigned char *blue)
+{
+};
+
+int wxPalette::GetPixel( const unsigned char red, const unsigned char green, const unsigned char blue ) const
+{
+};
+
+bool wxPalette::GetRGB( const int pixel, unsigned char *red, unsigned char *green, unsigned char *blue ) const
+{
+};
+
diff --git a/src/gtk/pen.cpp b/src/gtk/pen.cpp
new file mode 100644
index 0000000000..663f7ad3db
--- /dev/null
+++ b/src/gtk/pen.cpp
@@ -0,0 +1,204 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        pen.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "pen.h"
+#endif
+
+#include "wx/pen.h"
+
+//-----------------------------------------------------------------------------
+// wxPen
+//-----------------------------------------------------------------------------
+
+class wxPenRefData: public wxObjectRefData
+{
+  public:
+  
+    wxPenRefData(void);
+  
+    int        m_width;
+    int        m_style;
+    int        m_joinStyle;
+    int        m_capStyle;
+    wxColour   m_colour;
+};
+
+wxPenRefData::wxPenRefData(void)
+{
+  m_width = 1;
+  m_style = wxSOLID;
+  m_joinStyle = wxJOIN_ROUND;
+  m_capStyle = wxCAP_ROUND;
+};
+
+//-----------------------------------------------------------------------------
+
+#define M_PENDATA ((wxPenRefData *)m_refData)
+
+IMPLEMENT_DYNAMIC_CLASS(wxPen,wxGDIObject)
+
+wxPen::wxPen(void)
+{
+  if (wxThePenList) wxThePenList->AddPen( this );
+};
+
+wxPen::wxPen( const wxColour &colour, int width, int style )
+{
+  m_refData = new wxPenRefData();
+  M_PENDATA->m_width = width;
+  M_PENDATA->m_style = style;
+  M_PENDATA->m_colour = colour;
+  if (wxThePenList) wxThePenList->AddPen( this );
+};
+
+wxPen::wxPen( const wxString &colourName, int width, int style )
+{
+  m_refData = new wxPenRefData();
+  M_PENDATA->m_width = width;
+  M_PENDATA->m_style = style;
+  M_PENDATA->m_colour = colourName;
+  if (wxThePenList) wxThePenList->AddPen( this );
+};
+
+wxPen::wxPen( const wxPen& pen )
+{
+  Ref( pen );
+  if (wxThePenList) wxThePenList->AddPen( this );
+};
+
+wxPen::wxPen( const wxPen* pen )
+{
+  UnRef();
+  if (pen) Ref( *pen ); 
+  if (wxThePenList) wxThePenList->AddPen( this );
+};
+
+wxPen::~wxPen(void)
+{
+  if (wxThePenList) wxThePenList->RemovePen( this );
+};
+
+wxPen& wxPen::operator = ( const wxPen& pen )
+{
+  if (*this == pen) return (*this); 
+  Ref( pen ); 
+  return *this; 
+};
+
+bool wxPen::operator == ( const wxPen& pen )
+{
+  return m_refData == pen.m_refData; 
+};
+
+bool wxPen::operator != ( const wxPen& pen )
+{
+  return m_refData != pen.m_refData; 
+};
+
+void wxPen::SetColour( const wxColour &colour )
+{
+  if (!m_refData)
+    m_refData = new wxPenRefData();
+
+  M_PENDATA->m_colour = colour;
+};
+
+void wxPen::SetColour( const wxString &colourName )
+{
+  if (!m_refData)
+    m_refData = new wxPenRefData();
+
+  M_PENDATA->m_colour = colourName;
+};
+
+void wxPen::SetColour( const int red, const int green, const int blue )
+{
+  if (!m_refData)
+    m_refData = new wxPenRefData();
+
+  M_PENDATA->m_colour.Set( red, green, blue );
+};
+
+void wxPen::SetCap( int capStyle )
+{
+  if (!m_refData)
+    m_refData = new wxPenRefData();
+
+  M_PENDATA->m_capStyle = capStyle;
+};
+
+void wxPen::SetJoin( int joinStyle )
+{
+  if (!m_refData)
+    m_refData = new wxPenRefData();
+
+  M_PENDATA->m_joinStyle = joinStyle;
+};
+
+void wxPen::SetStyle( int style )
+{
+  if (!m_refData)
+    m_refData = new wxPenRefData();
+
+  M_PENDATA->m_style = style;
+};
+
+void wxPen::SetWidth( int width )
+{
+  if (!m_refData)
+    m_refData = new wxPenRefData();
+
+  M_PENDATA->m_width = width;
+};
+
+int wxPen::GetCap(void) const
+{
+  return M_PENDATA->m_capStyle;
+};
+
+int wxPen::GetJoin(void) const
+{
+  if (!m_refData)
+    return 0;
+  else
+    return M_PENDATA->m_joinStyle;
+};
+
+int wxPen::GetStyle(void) const
+{
+  if (!m_refData)
+    return 0;
+  else
+    return M_PENDATA->m_style;
+};
+
+int wxPen::GetWidth(void) const
+{
+  if (!m_refData)
+    return 0;
+  else
+    return M_PENDATA->m_width;
+};
+
+wxColour &wxPen::GetColour(void) const
+{
+  if (!m_refData)
+    return wxNullColour;
+  else
+    return M_PENDATA->m_colour;
+};
+
+bool wxPen::Ok(void) const
+{
+  return (m_refData);
+};
+
diff --git a/src/gtk/radiobox.cpp b/src/gtk/radiobox.cpp
new file mode 100644
index 0000000000..5e83994194
--- /dev/null
+++ b/src/gtk/radiobox.cpp
@@ -0,0 +1,229 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        radiobox.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "radiobox.h"
+#endif
+
+#include "wx/radiobox.h"
+#include "wx/dialog.h"
+#include "wx/frame.h"
+#include "wx/gtk/win_gtk.h"
+
+//-----------------------------------------------------------------------------
+// wxRadioBox
+//-----------------------------------------------------------------------------
+
+void gtk_radiobutton_clicked_callback( GtkWidget *WXUNUSED(widget), gpointer data )
+{
+  wxRadioBox *rb = (wxRadioBox*)data;
+  wxCommandEvent event( wxEVT_COMMAND_RADIOBOX_SELECTED, rb->GetId() );
+  event.SetInt( rb->GetSelection() );
+  wxString tmp( rb->GetStringSelection() );
+  event.SetString( WXSTRINGCAST(tmp) );
+  event.SetEventObject( rb );
+  rb->ProcessEvent(event);
+};
+
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxRadioBox,wxControl)
+
+wxRadioBox::wxRadioBox(void)
+{
+};
+
+wxRadioBox::wxRadioBox( wxWindow *parent, const wxWindowID id, const wxString& title,
+      const wxPoint &pos, const wxSize &size, 
+      const int n, const wxString choices[],
+      const int majorDim, const long style,
+      const wxString &name )
+{
+  Create( parent, id, title, pos, size, n, choices, majorDim, style, name );
+};
+
+bool wxRadioBox::Create( wxWindow *parent, const wxWindowID id, const wxString& title,
+      const wxPoint &pos, const wxSize &size, 
+      const int n, const wxString choices[],
+      const int WXUNUSED(majorDim), const long style,
+      const wxString &name )
+{
+  m_needParent = TRUE;
+  
+  PreCreation( parent, id, pos, size, style, name );
+
+  m_widget = gtk_frame_new( title );
+  
+  int x = m_x+5;
+  int y = m_y+15;
+  int maxLen = 0;
+  int height = 20;
+  
+//  if (((m_style & wxRA_VERTICAL) == wxRA_VERTICAL) && (n > 0))
+  if (n > 0)
+  {
+    GSList *radio_button_group = NULL;
+    for (int i = 0; i < n; i++)
+    {
+      if (i) radio_button_group = gtk_radio_button_group( GTK_RADIO_BUTTON(m_radio) );
+      m_radio = GTK_RADIO_BUTTON( gtk_radio_button_new_with_label( radio_button_group, choices[i] ) );
+      
+      if (!i) gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(m_radio), TRUE );
+      
+      gtk_signal_connect( GTK_OBJECT(m_radio), "clicked", 
+        GTK_SIGNAL_FUNC(gtk_radiobutton_clicked_callback), (gpointer*)this );
+       
+      gtk_myfixed_put( GTK_MYFIXED(m_parent->m_wxwindow), GTK_WIDGET(m_radio), x, y );
+      
+      int tmp = 22+gdk_string_measure( GTK_WIDGET(m_radio)->style->font, choices[i] );
+      if (tmp > maxLen) maxLen = tmp;
+      
+      int width = m_width-10;
+      if (size.x == -1) width = tmp;
+      gtk_widget_set_usize( GTK_WIDGET(m_radio), width, 20 );
+      
+      y += 20;
+      height += 20;
+      
+    };
+  };
+
+  wxSize newSize = size;
+  if (newSize.x == -1) newSize.x = maxLen+10;
+  if (newSize.y == -1) newSize.y = height;
+  SetSize( newSize.x, newSize.y );
+  
+  PostCreation();
+  
+  Show( TRUE );
+    
+  return TRUE;
+};
+
+bool wxRadioBox::Show( const bool show )
+{
+  wxWindow::Show( show );
+
+  GSList *item = gtk_radio_button_group( m_radio );
+  while (item)
+  {
+    GtkWidget *w = GTK_WIDGET( item->data );
+    if (show) gtk_widget_show( w ); else gtk_widget_hide( w );
+    item = item->next;
+  };
+
+  return TRUE;
+};
+
+int wxRadioBox::FindString( const wxString& WXUNUSED(s) ) const
+{
+  return 0;
+};
+
+void wxRadioBox::SetSelection( const int WXUNUSED(n) )
+{
+};
+
+int wxRadioBox::GetSelection(void) const
+{
+  GSList *item = gtk_radio_button_group( m_radio );
+  int count = 0;
+  while (item)
+  {
+    GtkButton *button = GTK_BUTTON( item->data );
+    if (GTK_TOGGLE_BUTTON(button)->active) return count;
+    count++;
+    item = item->next;
+  };
+  return -1;
+};
+
+wxString wxRadioBox::GetString( const int WXUNUSED(n) ) const
+{
+  return "";
+};
+
+wxString wxRadioBox::GetLabel(void) const
+{
+  return wxControl::GetLabel();
+};
+
+void wxRadioBox::SetLabel( const wxString& WXUNUSED(label) )
+{
+};
+
+void wxRadioBox::SetLabel( const int WXUNUSED(item), const wxString& WXUNUSED(label) )
+{
+};
+
+void wxRadioBox::SetLabel( const int WXUNUSED(item), wxBitmap *WXUNUSED(bitmap) )
+{
+};
+
+wxString wxRadioBox::GetLabel( const int WXUNUSED(item) ) const
+{
+  return "";
+};
+
+void wxRadioBox::Enable( const bool WXUNUSED(enable) )
+{
+};
+
+void wxRadioBox::Enable( const int WXUNUSED(item), const bool WXUNUSED(enable) )
+{
+};
+
+void wxRadioBox::Show( const int WXUNUSED(item), const bool WXUNUSED(show) )
+{
+};
+
+wxString wxRadioBox::GetStringSelection(void) const
+{
+  GSList *item = gtk_radio_button_group( m_radio );
+  while (item)
+  {
+    GtkButton *button = GTK_BUTTON( item->data );
+    if (GTK_TOGGLE_BUTTON(button)->active)
+    {
+      GtkLabel *label = GTK_LABEL( button->child );
+      return label->label;
+    };
+    item = item->next;
+  };
+  return "";
+};
+
+bool wxRadioBox::SetStringSelection( const wxString& WXUNUSED(s) )
+{
+  return TRUE;
+};
+
+int wxRadioBox::Number(void) const
+{
+  int count = 0;
+  GSList *item = gtk_radio_button_group( m_radio );
+  while (item)
+  {
+    item = item->next;
+    count++;
+  };
+  return count;
+};
+
+int wxRadioBox::GetNumberOfRowsOrCols(void) const
+{
+  return 1;
+};
+
+void wxRadioBox::SetNumberOfRowsOrCols( const int WXUNUSED(n) )
+{
+};
+
diff --git a/src/gtk/radiobut.cpp b/src/gtk/radiobut.cpp
new file mode 100644
index 0000000000..e474873991
--- /dev/null
+++ b/src/gtk/radiobut.cpp
@@ -0,0 +1,17 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        radiobut.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "radiobut.h"
+#endif
+
+#include "wx/radiobut.h"
+
diff --git a/src/gtk/region.cpp b/src/gtk/region.cpp
new file mode 100644
index 0000000000..d7da03c61f
--- /dev/null
+++ b/src/gtk/region.cpp
@@ -0,0 +1,253 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        region.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/98
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "region.h"
+#endif
+
+#include "wx/region.h"
+
+//-----------------------------------------------------------------------------
+// wxRegion
+//-----------------------------------------------------------------------------
+
+class wxRegionRefData: public wxObjectRefData
+{
+  public:
+  
+    wxRegionRefData(void);
+    ~wxRegionRefData(void);
+  
+  public:    
+
+    GdkRegion  *m_region;
+};
+
+wxRegionRefData::wxRegionRefData(void)
+{
+  m_region = NULL;
+};
+
+wxRegionRefData::~wxRegionRefData(void)
+{
+  if (m_region) gdk_region_destroy( m_region );
+};
+
+//-----------------------------------------------------------------------------
+
+#define M_REGIONDATA ((wxRegionRefData *)m_refData)
+
+IMPLEMENT_DYNAMIC_CLASS(wxRegion,wxGDIObject);
+  
+wxRegion::wxRegion( long x, long y, long w, long h )
+{
+  m_refData = new wxRegionRefData();
+  GdkRegion *reg = gdk_region_new();
+  GdkRectangle rect;
+  rect.x = x;
+  rect.y = y;
+  rect.width = w;
+  rect.height = h;
+  M_REGIONDATA->m_region = gdk_region_union_with_rect( reg, &rect );
+  gdk_region_destroy( reg );
+};
+
+wxRegion::wxRegion( const wxPoint& topLeft, const wxPoint& bottomRight )
+{
+  m_refData = new wxRegionRefData();
+  GdkRegion *reg = gdk_region_new();
+  GdkRectangle rect;
+  rect.x = topLeft.x;
+  rect.y = topLeft.y;
+  rect.width = bottomRight.x - rect.x;
+  rect.height = bottomRight.y - rect.y;
+  M_REGIONDATA->m_region = gdk_region_union_with_rect( reg, &rect );
+  gdk_region_destroy( reg );
+};
+
+wxRegion::wxRegion( const wxRect& rect )
+{
+  m_refData = new wxRegionRefData();
+  GdkRegion *reg = gdk_region_new();
+  GdkRectangle g_rect;
+  g_rect.x = rect.x;
+  g_rect.y = rect.y;
+  g_rect.width = rect.width;
+  g_rect.height = rect.height;
+  M_REGIONDATA->m_region = gdk_region_union_with_rect( reg, &g_rect );
+  gdk_region_destroy( reg );
+};
+
+wxRegion::wxRegion(void)
+{
+  m_refData = new wxRegionRefData();
+  M_REGIONDATA->m_region = gdk_region_new();
+};
+
+wxRegion::~wxRegion(void)
+{
+};
+
+void wxRegion::Clear(void)
+{
+  UnRef();
+  m_refData = new wxRegionRefData();
+  M_REGIONDATA->m_region = gdk_region_new();
+};
+
+bool wxRegion::Union( long x, long y, long width, long height )
+{
+  GdkRectangle rect;
+  rect.x = x;
+  rect.y = y;
+  rect.width = width;
+  rect.height = height;
+  GdkRegion *reg = gdk_region_union_with_rect( M_REGIONDATA->m_region, &rect );
+  gdk_region_destroy( M_REGIONDATA->m_region );
+  M_REGIONDATA->m_region = reg;
+  return TRUE;
+};
+
+bool wxRegion::Union( const wxRect& rect )
+{
+  GdkRectangle g_rect;
+  g_rect.x = rect.x;
+  g_rect.y = rect.y;
+  g_rect.width = rect.width;
+  g_rect.height = rect.height;
+  GdkRegion *reg = gdk_region_union_with_rect( M_REGIONDATA->m_region, &g_rect );
+  gdk_region_destroy( M_REGIONDATA->m_region );
+  M_REGIONDATA->m_region = reg;
+  return TRUE;
+};
+
+bool wxRegion::Union( const wxRegion& region )
+{
+  GdkRegion *reg = gdk_regions_union( M_REGIONDATA->m_region, region.GetRegion() );
+  gdk_region_destroy( M_REGIONDATA->m_region );
+  M_REGIONDATA->m_region = reg;
+  return TRUE;
+};
+
+bool wxRegion::Intersect( long x, long y, long width, long height )
+{
+  wxRegion reg( x, y, width, height );
+  Intersect( reg );
+  return TRUE;
+};
+
+bool wxRegion::Intersect( const wxRect& rect )
+{
+  wxRegion reg( rect );
+  Intersect( reg );
+  return TRUE;
+};
+
+bool wxRegion::Intersect( const wxRegion& region )
+{
+  GdkRegion *reg = gdk_regions_intersect( M_REGIONDATA->m_region, region.GetRegion() );
+  gdk_region_destroy( M_REGIONDATA->m_region );
+  M_REGIONDATA->m_region = reg;
+  return TRUE;
+};
+
+bool wxRegion::Subtract( long x, long y, long width, long height )
+{
+  wxRegion reg( x, y, width, height );
+  Subtract( reg );
+  return TRUE;
+};
+
+bool wxRegion::Subtract( const wxRect& rect )
+{
+  wxRegion reg( rect );
+  Subtract( reg );
+  return TRUE;
+};
+
+bool wxRegion::Subtract( const wxRegion& region )
+{
+  GdkRegion *reg = gdk_regions_subtract( M_REGIONDATA->m_region, region.GetRegion() );
+  gdk_region_destroy( M_REGIONDATA->m_region );
+  M_REGIONDATA->m_region = reg;
+  return TRUE;
+};
+
+bool wxRegion::Xor( long x, long y, long width, long height )
+{
+  wxRegion reg( x, y, width, height );
+  Xor( reg );
+  return TRUE;
+};
+
+bool wxRegion::Xor( const wxRect& rect )
+{
+  wxRegion reg( rect );
+  Xor( reg );
+  return TRUE;
+};
+
+bool wxRegion::Xor( const wxRegion& region )
+{
+  GdkRegion *reg = gdk_regions_xor( M_REGIONDATA->m_region, region.GetRegion() );
+  gdk_region_destroy( M_REGIONDATA->m_region );
+  M_REGIONDATA->m_region = reg;
+  return TRUE;
+};
+
+void wxRegion::GetBox( long& x, long& y, long&w, long &h ) const
+{
+  x = 0;
+  y = 0;
+  w = -1;
+  h = -1;
+};
+
+wxRect wxRegion::GetBox(void) const
+{
+  return wxRect( 0, 0, -1, -1 );
+};
+
+bool wxRegion::Empty(void) const
+{
+  return gdk_region_empty( M_REGIONDATA->m_region );
+};
+
+wxRegionContain wxRegion::Contains( long x, long y ) const
+{
+  if (gdk_region_point_in( M_REGIONDATA->m_region, x, y ))
+    return wxInRegion;
+  else
+    return wxOutRegion;
+};
+
+wxRegionContain wxRegion::Contains( long x, long y, long w, long h ) const
+{
+  GdkRectangle rect;
+  rect.x = x;
+  rect.y = y;
+  rect.width = w;
+  rect.height = h;
+  GdkOverlapType res = gdk_region_rect_in( M_REGIONDATA->m_region, &rect );
+  switch (res)
+  {
+   case GDK_OVERLAP_RECTANGLE_IN:   return wxInRegion;
+   case GDK_OVERLAP_RECTANGLE_OUT:  return wxOutRegion;
+   case GDK_OVERLAP_RECTANGLE_PART: return wxPartRegion;
+  };
+  return wxOutRegion;
+};
+
+GdkRegion *wxRegion::GetRegion(void) const
+{
+  return M_REGIONDATA->m_region;
+};
+
diff --git a/src/gtk/scrolbar.cpp b/src/gtk/scrolbar.cpp
new file mode 100644
index 0000000000..cb0d32c002
--- /dev/null
+++ b/src/gtk/scrolbar.cpp
@@ -0,0 +1,216 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        scrolbar.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "scrolbar.h"
+#endif
+
+#include "wx/scrolbar.h"
+#include "wx/utils.h"
+
+//-----------------------------------------------------------------------------
+// wxScrollBar
+//-----------------------------------------------------------------------------
+
+void gtk_scrollbar_callback( GtkWidget *WXUNUSED(widget), wxScrollBar *win )
+{ 
+/*
+  printf( "OnScroll from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  if (!win->HasVMT()) return;
+    
+  float diff = win->m_adjust->value - win->m_oldPos;
+  if (fabs(diff) < 0.2) return;
+  
+  int command = 0;
+  
+  float line_step = win->m_adjust->step_increment;
+  float page_step = win->m_adjust->page_increment;
+  
+  if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN;
+  else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP;
+  else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN;
+  else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP;
+  else command = wxEVT_SCROLL_THUMBTRACK;
+
+  int value = (int)(win->m_adjust->value+0.5);
+      
+  int orient = wxHORIZONTAL;
+  if (win->GetWindowStyleFlag() & wxSB_VERTICAL == wxSB_VERTICAL) orient = wxHORIZONTAL;
+  
+  wxScrollEvent event( command, win->GetId(), value, orient );
+  event.SetEventObject( win );
+  win->ProcessEvent( event );
+  
+/*
+  wxCommandEvent cevent( wxEVT_COMMAND_SCROLLBAR_UPDATED, win->GetId() );
+  cevent.SetEventObject( win );
+  win->ProcessEvent( cevent );
+*/
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxScrollBar,wxControl)
+
+wxScrollBar::wxScrollBar(wxWindow *parent, const wxWindowID id,
+           const wxPoint& pos, const wxSize& size,
+           const long style, const wxString& name )
+{
+  Create( parent, id, pos, size, style, name );
+};
+
+wxScrollBar::~wxScrollBar(void)
+{
+};
+
+bool wxScrollBar::Create(wxWindow *parent, const wxWindowID id,
+           const wxPoint& pos, const wxSize& size,
+           const long style, const wxString& name )
+{
+  m_needParent = TRUE;
+  
+  PreCreation( parent, id, pos, size, style, name );
+  
+  m_oldPos = 0.0;
+
+  if (style & wxSB_VERTICAL == wxSB_VERTICAL)
+    m_widget = gtk_hscrollbar_new( NULL );
+  else
+    m_widget = gtk_vscrollbar_new( NULL );
+    
+  m_adjust = gtk_range_get_adjustment( GTK_RANGE(m_widget) );
+  
+  gtk_signal_connect (GTK_OBJECT (m_adjust), "value_changed",
+		      (GtkSignalFunc) gtk_scrollbar_callback, (gpointer) this );
+  
+  PostCreation();
+  
+  Show( TRUE );
+    
+  return TRUE;
+};
+
+int wxScrollBar::GetPosition(void) const
+{
+  return (int)(m_adjust->value+0.5);
+};
+
+int wxScrollBar::GetThumbSize() const
+{
+  return (int)(m_adjust->page_size+0.5);
+};
+
+int wxScrollBar::GetPageSize() const
+{
+  return (int)(m_adjust->page_increment+0.5);
+};
+
+int wxScrollBar::GetRange() const
+{
+  return (int)(m_adjust->upper+0.5);
+};
+
+void wxScrollBar::SetPosition( const int viewStart )
+{
+  float fpos = (float)viewStart;
+  m_oldPos = fpos;
+  if (fabs(fpos-m_adjust->value) < 0.2) return;
+  m_adjust->value = fpos;
+  
+  gtk_signal_emit_by_name( GTK_OBJECT(m_adjust), "value_changed" );
+};
+
+void wxScrollBar::SetScrollbar( const int position, const int thumbSize, const int range, const int pageSize,
+      const bool WXUNUSED(refresh) )
+{
+  float fpos = (float)position;
+  m_oldPos = fpos;
+  float frange = (float)range;
+  float fthumb = (float)thumbSize;
+  float fpage = (float)pageSize;
+      
+  if ((fabs(fpos-m_adjust->value) < 0.2) &&
+      (fabs(frange-m_adjust->upper) < 0.2) &&
+      (fabs(fthumb-m_adjust->page_size) < 0.2) &&
+      (fabs(fpage-m_adjust->page_increment) < 0.2))
+      return;
+      
+  m_adjust->lower = 0.0;
+  m_adjust->upper = frange;
+  m_adjust->value = fpos;
+  m_adjust->step_increment = 1.0;
+  m_adjust->page_increment = (float)(wxMax(fpage-2,0));
+  m_adjust->page_size = fthumb;
+
+  gtk_signal_emit_by_name( GTK_OBJECT(m_adjust), "changed" );
+};
+
+// Backward compatibility
+int wxScrollBar::GetValue(void) const
+{
+  return GetPosition();
+};
+
+void wxScrollBar::SetValue( const int viewStart )
+{
+  SetPosition( viewStart );
+};
+
+void wxScrollBar::GetValues( int *viewStart, int *viewLength, int *objectLength, int *pageLength ) const
+{
+  int pos = (int)(m_adjust->value+0.5);
+  int thumb = (int)(m_adjust->page_size+0.5);
+  int page = (int)(m_adjust->page_increment+0.5);
+  int range = (int)(m_adjust->upper+0.5);
+  
+  *viewStart = pos;
+  *viewLength = range;
+  *objectLength = thumb;
+  *pageLength = page;
+};
+
+int wxScrollBar::GetViewLength() const
+{
+  return (int)(m_adjust->upper+0.5);
+};
+
+int wxScrollBar::GetObjectLength() const
+{
+  return (int)(m_adjust->page_size+0.5);
+};
+
+void wxScrollBar::SetPageSize( const int pageLength )
+{
+  int pos = (int)(m_adjust->value+0.5);
+  int thumb = (int)(m_adjust->page_size+0.5);
+  int range = (int)(m_adjust->upper+0.5);
+  SetScrollbar( pos, thumb, range, pageLength );
+};
+
+void wxScrollBar::SetObjectLength( const int objectLength )
+{
+  int pos = (int)(m_adjust->value+0.5);
+  int page = (int)(m_adjust->page_increment+0.5);
+  int range = (int)(m_adjust->upper+0.5);
+  SetScrollbar( pos, objectLength, range, page );
+};
+
+void wxScrollBar::SetViewLength( const int viewLength )
+{
+  int pos = (int)(m_adjust->value+0.5);
+  int thumb = (int)(m_adjust->page_size+0.5);
+  int page = (int)(m_adjust->page_increment+0.5);
+  SetScrollbar( pos, thumb, viewLength, page );
+};
+
diff --git a/src/gtk/settings.cpp b/src/gtk/settings.cpp
new file mode 100644
index 0000000000..dfcf1d81db
--- /dev/null
+++ b/src/gtk/settings.cpp
@@ -0,0 +1,183 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        settings.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "settings.h"
+#endif
+
+#include "wx/settings.h"
+
+/*
+#define wxSYS_COLOUR_SCROLLBAR         0
+#define wxSYS_COLOUR_BACKGROUND        1
+#define wxSYS_COLOUR_ACTIVECAPTION     2
+#define wxSYS_COLOUR_INACTIVECAPTION   3
+#define wxSYS_COLOUR_MENU              4
+#define wxSYS_COLOUR_WINDOW            5
+#define wxSYS_COLOUR_WINDOWFRAME       6
+#define wxSYS_COLOUR_MENUTEXT          7
+#define wxSYS_COLOUR_WINDOWTEXT        8
+#define wxSYS_COLOUR_CAPTIONTEXT       9
+#define wxSYS_COLOUR_ACTIVEBORDER      10
+#define wxSYS_COLOUR_INACTIVEBORDER    11
+#define wxSYS_COLOUR_APPWORKSPACE      12
+#define wxSYS_COLOUR_HIGHLIGHT         13
+#define wxSYS_COLOUR_HIGHLIGHTTEXT     14
+#define wxSYS_COLOUR_BTNFACE           15
+#define wxSYS_COLOUR_BTNSHADOW         16
+#define wxSYS_COLOUR_GRAYTEXT          17
+#define wxSYS_COLOUR_BTNTEXT           18
+#define wxSYS_COLOUR_INACTIVECAPTIONTEXT 19
+#define wxSYS_COLOUR_BTNHIGHLIGHT      20
+
+#define wxSYS_COLOUR_3DDKSHADOW        21
+#define wxSYS_COLOUR_3DLIGHT           22
+#define wxSYS_COLOUR_INFOTEXT          23
+#define wxSYS_COLOUR_INFOBK            24
+
+#define wxSYS_COLOUR_DESKTOP           wxSYS_COLOUR_BACKGROUND
+#define wxSYS_COLOUR_3DFACE            wxSYS_COLOUR_BTNFACE
+#define wxSYS_COLOUR_3DSHADOW          wxSYS_COLOUR_BTNSHADOW
+#define wxSYS_COLOUR_3DHIGHLIGHT       wxSYS_COLOUR_BTNHIGHLIGHT
+#define wxSYS_COLOUR_3DHILIGHT         wxSYS_COLOUR_BTNHIGHLIGHT
+#define wxSYS_COLOUR_BTNHILIGHT        wxSYS_COLOUR_BTNHIGHLIGHT
+*/
+
+#define SHIFT (8*(sizeof(short int)-sizeof(char)))
+
+wxColour *g_systemBtnFaceColour      = NULL;
+wxColour *g_systemBtnShadowColour    = NULL;
+wxColour *g_systemBtnHighlightColour = NULL;
+wxColour *g_systemHighlightColour    = NULL;
+
+wxColour wxSystemSettings::GetSystemColour( int index )
+{
+  switch (index)
+  {
+    case wxSYS_COLOUR_SCROLLBAR:
+    case wxSYS_COLOUR_BACKGROUND:
+    case wxSYS_COLOUR_ACTIVECAPTION:
+    case wxSYS_COLOUR_INACTIVECAPTION:
+    case wxSYS_COLOUR_MENU:
+    case wxSYS_COLOUR_WINDOW:
+    case wxSYS_COLOUR_WINDOWFRAME:
+    case wxSYS_COLOUR_ACTIVEBORDER:
+    case wxSYS_COLOUR_INACTIVEBORDER:
+    case wxSYS_COLOUR_BTNFACE:
+    {
+      GtkStyle *style = gtk_widget_get_default_style();
+      if (!g_systemBtnFaceColour)
+      {
+        g_systemBtnFaceColour = 
+	  new wxColour( style->bg[0].red >> SHIFT,
+	                style->bg[0].green >> SHIFT,
+			style->bg[0].blue >> SHIFT );
+      };
+      return *g_systemBtnFaceColour;
+    };
+    case wxSYS_COLOUR_BTNSHADOW:
+    {
+      GtkStyle *style = gtk_widget_get_default_style();
+      if (!g_systemBtnShadowColour)
+      {
+        g_systemBtnShadowColour = 
+	  new wxColour( style->dark[0].red >> SHIFT,
+	                style->dark[0].green >> SHIFT,
+			style->dark[0].blue >> SHIFT );
+      };
+      return *g_systemBtnShadowColour;
+    };
+    case wxSYS_COLOUR_GRAYTEXT:
+    case wxSYS_COLOUR_BTNHIGHLIGHT:
+    {
+      GtkStyle *style = gtk_widget_get_default_style();
+      if (!g_systemBtnHighlightColour)
+      {
+        g_systemBtnHighlightColour = 
+	  new wxColour( style->light[0].red >> SHIFT,
+	                style->light[0].green >> SHIFT,
+			style->light[0].blue >> SHIFT );
+      };
+      return *g_systemBtnHighlightColour;
+    };
+    case wxSYS_COLOUR_HIGHLIGHT:
+    {
+      GtkStyle *style = gtk_widget_get_default_style();
+      if (!g_systemHighlightColour)
+      {
+        g_systemHighlightColour = 
+	  new wxColour( style->bg[GTK_STATE_SELECTED].red >> SHIFT,
+	                style->bg[GTK_STATE_SELECTED].green >> SHIFT,
+			style->bg[GTK_STATE_SELECTED].blue >> SHIFT );
+      };
+      return *g_systemHighlightColour;
+    };
+    case wxSYS_COLOUR_MENUTEXT:
+    case wxSYS_COLOUR_WINDOWTEXT:
+    case wxSYS_COLOUR_CAPTIONTEXT:
+    case wxSYS_COLOUR_INACTIVECAPTIONTEXT:
+    case wxSYS_COLOUR_INFOTEXT:
+    {
+      return *wxBLACK;
+    };
+    case wxSYS_COLOUR_HIGHLIGHTTEXT:
+    {
+      return *wxWHITE;
+    };
+    case wxSYS_COLOUR_INFOBK:
+    case wxSYS_COLOUR_APPWORKSPACE:
+    {
+      return *wxWHITE;    // ?
+    };
+  };
+  return *wxWHITE;
+};
+
+wxFont *g_systemFont = NULL;
+
+wxFont wxSystemSettings::GetSystemFont( int index ) 
+{
+  switch (index)
+  {
+    case wxSYS_OEM_FIXED_FONT:
+    case wxSYS_ANSI_FIXED_FONT:
+    case wxSYS_SYSTEM_FIXED_FONT:
+    {
+      return *wxNORMAL_FONT;
+    };
+    case wxSYS_ANSI_VAR_FONT:
+    case wxSYS_SYSTEM_FONT:
+    case wxSYS_DEVICE_DEFAULT_FONT:
+    case wxSYS_DEFAULT_GUI_FONT:
+    {
+      if (!g_systemFont)
+        g_systemFont = new wxFont( "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*" );
+      return *g_systemFont;
+    };
+  };
+
+  return wxNullFont;
+}
+;
+
+int wxSystemSettings::GetSystemMetric( int index )
+{
+  switch (index)
+  {
+    case wxSYS_SCREEN_X:
+      return gdk_screen_width();
+    case wxSYS_SCREEN_Y:
+      return gdk_screen_height();
+  };
+  return 0;
+}
+;
+
diff --git a/src/gtk/setup/general/createall b/src/gtk/setup/general/createall
new file mode 100755
index 0000000000..e912a39315
--- /dev/null
+++ b/src/gtk/setup/general/createall
@@ -0,0 +1,98 @@
+#! /bin/sh
+
+OS=$OSTYPE
+
+if test "x$OS" = x; then 
+  echo "please set the environment variable OSTYPE "
+  echo "to a value appropriate for your system."
+  echo "to do so type: setenv OSTYPE `uname`   for the csh, tcsh"
+  echo "               export OSTYPE=`uname`   for other shells"
+  exit 1
+fi
+
+TMP_CONT=`ls src`
+SRC_DIR=src
+for each in $TMP_CONT; do
+  if test -d src/$each ; then 
+    SRC_DIR="$SRC_DIR src/$each"
+  fi
+done
+
+TMP_CONT=`ls samples`
+SAMPLES_DIR=
+for each in $TMP_CONT; do
+  if test -d samples/$each ; then 
+    SAMPLES_DIR="$SAMPLES_DIR samples/$each"
+  fi
+done
+
+TMP_CONT=`ls utils`
+UTILS_DIR=
+for each in $TMP_CONT; do
+  if test -d utils/$each ; then 
+    UTILS_DIR="$UTILS_DIR utils/$each"
+  fi
+done
+
+TMP_CONT=`ls user`
+USER_DIR=
+for each in $TMP_CONT; do
+  if test -d user/$each ; then 
+    USER_DIR="$USER_DIR user/$each"
+  fi
+done
+
+ALL_DIR="$SRC_DIR $SAMPLES_DIR $UTILS_DIR $USER_DIR"
+
+echo Creating for: $OS
+
+# create defaults
+if test ! -d src/gtk/setup/$OS; then
+    mkdir src/gtk/setup/$OS
+fi
+
+SUBSTFILE=src/gtk/setup/$OS/substit
+
+# the substit file first
+if test -f src/gtk/setup/substit ; then
+  cat src/gtk/setup/substit | sed "s/*/@/g" > $SUBSTFILE;
+  rm -f src/gtk/setup/substit 
+fi
+# now the template file
+cat src/gtk/setup/maketmpl.in | sed -f $SUBSTFILE > src/gtk/setup/$OS/maketmpl
+
+# now the config header file
+#if test -f setup/wx_setup.h ; then
+#  cat setup/wx_setup.h > setup/$OS/wx_setup.h;
+#  rm -f setup/wx_setup.h
+#fi
+
+# create lib and bin directory
+if test ! -d lib; then
+  mkdir lib
+fi
+if test ! -d lib/$OS; then
+  mkdir lib/$OS
+fi
+if test ! -d bin; then
+  mkdir bin
+fi
+if test ! -d bin/$OS; then
+  mkdir bin/$OS
+fi
+
+# create makefiles
+for each in $ALL_DIR; do
+    DIR=$each/$OS
+    # create Makefile in directory
+    if test -r $each/Makefile.in ; then
+        # create directory
+        if test ! -d $DIR; then
+            echo "Creating Directory: $DIR..."
+	    mkdir $DIR
+        fi
+	echo "Creating: $DIR/Makefile..."
+	cat $each/Makefile.in | sed -f $SUBSTFILE > $DIR/Makefile
+	(cd $DIR; make subdirs > /dev/null;)
+    fi
+done
diff --git a/src/gtk/setup/general/jointar b/src/gtk/setup/general/jointar
new file mode 100755
index 0000000000..29949e1cf3
--- /dev/null
+++ b/src/gtk/setup/general/jointar
@@ -0,0 +1,67 @@
+#! /bin/sh
+#
+# Written by Martin Sperl
+# (sperl@dsn.ast.univie.ac.at)
+#
+
+
+if test $# -lt 3 ; then
+  cat <<EOF
+Usage: `basename $0` <basedir> <SOURCE-FILES> <DESTINATION-FILS>
+  copies all files from the source-tar-files to the common
+  destination-tar-file with basedir as a common base directory.
+EOF
+  exit 0
+fi
+
+BaseDir="$1"
+shift
+
+Sourcefiles="$1"
+
+while test "$#" != 2 ; do
+  shift
+  Sourcefiles="$Sourcefiles $1"
+done
+
+shift
+Final=$1
+
+Destination=/tmp/join$$.tar
+
+touch $Destination
+
+curdir=`pwd`
+
+mkdir tmp$$
+mkdir tmp$$/$BaseDir
+
+#uncompress all files
+cd tmp$$/$BaseDir
+for each in $Sourcefiles ; do
+  ( \
+  if test `basename $each gz` != `basename $each` ; then \
+    gzip -dc ../../$each;\
+  else \
+    cat ../../$each;\
+  fi; \
+  ) | tar xf -
+done
+cd ..
+#now tar everything
+tar -cf $Destination *
+
+cd ..
+
+rm -fr tmp$$
+
+# goto old directory
+cd $curdir
+
+if test `basename $Final gz` != `basename $Final` ; then
+  gzip -c $Destination > $Final
+else
+  cat $Destination > $Final
+fi
+
+rm -f $Destination
diff --git a/src/gtk/setup/general/makeapp b/src/gtk/setup/general/makeapp
new file mode 100644
index 0000000000..a413749e5f
--- /dev/null
+++ b/src/gtk/setup/general/makeapp
@@ -0,0 +1,73 @@
+SHELL=/bin/sh
+
+OS=$(OSTYPE)
+
+all::
+	-@if test "x$(OS)" = x; then \
+          echo "please set the environment variable OSTYPE ";\
+	  echo "to a value appropriate for your system.";\
+	  echo "to do so type: setenv OSTYPE `uname`   for the csh, tcsh";\
+          echo "               export OSTYPE=`uname`   for other shells";\
+        else \
+	  if test -f Makefile.in ; then \
+	    if test -f $(OS)/Makefile ; then \
+	      NEEDED=`(cd $(OS); ${MAKE} checkneeds;) | grep "needed to compile" `;\
+	      if test "x$$NEEDED" = x; then \
+	        (cd $(OS); ${MAKE} $@); \
+	      else \
+                (cd $(OS); ${MAKE} checkneeds); \
+	      fi ; \
+	    else \
+	      echo "Did you configure your system?";\
+	    fi; \
+	  fi; \
+	fi;
+
+distrib::
+	@if test ! -d ../../distrib ; then mkdir ../../distrib; fi;
+	@if test ! -f ../../system.list ; then \
+	 echo "dummy" > ../../system.list;\
+	fi
+	@(curr=`pwd`; direc=`basename $$curr`;\
+	 basedir=`dirname $$curr`;\
+         basedirname=`basename $$basedir`;\
+	 if test ! -d ../../distrib/$$basedirname ; then \
+	   mkdir ../../distrib/$$basedirname;\
+	 fi;\
+	 if test -d doc; then (cd doc; make clean;); fi;\
+	 (cd ..; \
+	  echo creating $$direc.tar from the current directory;\
+	  files="`\
+	       find $$direc -type f \
+	       | fgrep -vf ../system.list \
+	       | grep -v "~" \
+	       | grep -v "#" \
+	      ` $(DISTRIBUTE_ADDITIONAL)";\
+	  tar -cf /tmp/$$direc.tar $$files;\
+	  echo compressing $$direc.tar to $$direc.tgz;\
+	  gzip -c /tmp/$$direc.tar > ../distrib/$$basedirname/$$direc.tgz;\
+	  rm /tmp/$$direc.tar;\
+	 )\
+	)
+
+.DEFAULT:
+	-@if test "x$(OS)" = x; then \
+          echo "please set the environment variable OSTYPE ";\
+	  echo "to a value appropriate for your system.";\
+	  echo "to do so type: setenv OSTYPE `uname`   for the csh, tcsh";\
+          echo "               export OSTYPE=`uname`   for other shells";\
+        else \
+	  if test -f Makefile.in ; then \
+	    if test -f $(OS)/Makefile ; then \
+	      NEEDED=`(cd $(OS); ${MAKE} checkneeds) | grep "needed to compile" `;\
+	      if test "x$$NEEDED" = x; then \
+	        (cd $(OS); ${MAKE} $@); \
+	      else \
+                (cd $(OS); ${MAKE} checkneeds); \
+	      fi ; \
+	    else \
+	      echo "Did you configure your system?";\
+	    fi \
+	  fi \
+	fi
+
diff --git a/src/gtk/setup/general/makedirs b/src/gtk/setup/general/makedirs
new file mode 100644
index 0000000000..0e770242f1
--- /dev/null
+++ b/src/gtk/setup/general/makedirs
@@ -0,0 +1,19 @@
+SHELL=/bin/sh
+
+DIRS=`find . -print | sed "s|\./||g" | grep -v "/" | grep -v "\." `
+
+all:
+	@for i in $(DIRS) xxx; do \
+	  if test -r $$i/Makefile ; then \
+	    echo "entering directory $$i building $@";\
+	    (cd $$i ; ${MAKE} $@); \
+	  fi; \
+	done
+
+.DEFAULT:
+	@for i in $(DIRS) xxx; do \
+	  if test -r $$i/Makefile ; then \
+	    echo "entering directory $$i building $@";\
+	    (cd $$i ; ${MAKE} $@); \
+	  fi; \
+	done
diff --git a/src/gtk/setup/general/makedoc b/src/gtk/setup/general/makedoc
new file mode 100644
index 0000000000..ca0ef855e5
--- /dev/null
+++ b/src/gtk/setup/general/makedoc
@@ -0,0 +1,102 @@
+SHELL=/bin/sh
+
+FILE_BASE=$(TEX_BASE:.tex=)
+
+BMP_FILES=$(XPM_FILES:.xpm=.bmp)
+EPS_FILES=$(XPM_FILES:.xpm=.eps)
+GIF_FILES=$(XPM_FILES:.xpm=.gif)
+
+HTML_BUTTONS=back.gif forward.gif contents.gif up.gif
+
+all:: doc
+
+clean::
+	@ for each in $(DIRS) . ; do \
+	( cd $$each; \
+	  rm -f *.bmp *.eps *.gif *.aux *.dvi *.log  \
+	        *.ps  *.toc *~    *.idx *.hlp *.html \
+	        *.rtf *.ref *.xlp *.con *.win *.fts  \
+	        *.hpj *.HLP; \
+	); done 
+
+doc:: doc_ps doc_html doc_xlp doc_winhelp doc_rtf
+
+#############################################
+
+doc_ps:: $(FILE_BASE).ps
+
+$(FILE_BASE).ps: $(FILE_BASE).dvi
+	dvips $(FILE_BASE).dvi -o$@
+
+#############################################
+
+doc_dvi:: $(FILE_BASE).dvi
+
+$(FILE_BASE).dvi: $(FILE_BASE).tex $(TEX_ADDITIONAL) $(EPS_FILES)
+	latex $(FILE_BASE).tex
+	latex $(FILE_BASE).tex
+
+#############################################
+
+doc_xlp:: $(FILE_BASE).xlp
+
+$(FILE_BASE).xlp: $(FILE_BASE).tex $(TEX_ADDITIONAL)
+	../../../bin/$(OSTYPE)/tex2rtf $(FILE_BASE).tex $(FILE_BASE).xlp -twice -xlp
+
+#############################################
+
+doc_html:: $(FILE_BASE)_contents.html $(FILE_BASE).html
+
+$(FILE_BASE).html: 
+	@ln -s $(FILE_BASE)_contents.html $@
+
+$(FILE_BASE)_contents.html: $(FILE_BASE).tex $(TEX_ADDITIONAL) $(GIF_FILES) $(HTML_BUTTONS)
+	../../../bin/$(OSTYPE)/tex2rtf $(FILE_BASE).tex $(FILE_BASE) -twice -html
+
+#############################################
+
+doc_rtf:: $(FILE_BASE).rtf
+
+$(FILE_BASE).rtf: $(FILE_BASE).tex $(TEX_ADDITIONAL) $(BMP_FILES)
+	../../../bin/$(OSTYPE)/tex2rtf $(FILE_BASE).tex $(FILE_BASE).rtf -twice -rtf
+
+#############################################
+
+doc_winhelp:: $(FILE_BASE).win
+
+$(FILE_BASE).win: $(FILE_BASE).tex $(TEX_ADDITIONAL) $(BMP_FILES)
+	../../../bin/$(OSTYPE)/tex2rtf $(FILE_BASE).tex $(FILE_BASE).win -twice -winhelp
+	@echo final conversion still needs to be done by MSWin
+
+#############################################
+
+subst::
+	@if test "x$(OLD)" = x; then \
+	  echo "OLD not defined!"; exit -1; \
+	fi
+	@if test "x$(NEW)" = x; then \
+	  echo "NEW not defined!"; exit -1; \
+	fi
+	@for each in $(TEX_BASE) $(TEX_ADITIONAL) ; do \
+	  cat $$each | sed "s/$(OLD)/$(NEW)/g" > /tmp/subst; \
+	  rm $$each; cp /tmp/subst $$each; rm /tmp/subst; \
+	done
+
+#############################################
+
+.SUFFIXES:
+.SUFFIXES: .eps .xpm
+.SUFFIXES: .bmp .xpm
+.SUFFIXES: .gif .xpm
+
+.xpm.eps :
+	@$(RM) -f $@
+	xpmtoppm $< | ppmtogif | giftopnm | pnmtops -rle -center -noturn -scale 0.5 - > $@
+
+.xpm.bmp :
+	@$(RM) -f $@
+	xpmtoppm $< | ppmtobmp -windows - > $@
+
+.xpm.gif :
+	@$(RM) -f $@ 
+	xpmtoppm $< | ppmtogif -interlace - > $@
diff --git a/src/gtk/setup/general/mygrep b/src/gtk/setup/general/mygrep
new file mode 100755
index 0000000000..fcf54dcad9
--- /dev/null
+++ b/src/gtk/setup/general/mygrep
@@ -0,0 +1,3 @@
+#! /bin/sh
+grep $@
+exit 0
diff --git a/src/gtk/setup/general/needed b/src/gtk/setup/general/needed
new file mode 100755
index 0000000000..286931a793
--- /dev/null
+++ b/src/gtk/setup/general/needed
@@ -0,0 +1,10 @@
+#! /bin/sh
+
+for each in $@ ; do
+  LINE=`grep " $each " ../$OSTYPE/wx_setup.h | grep "#define" | grep 1`
+  if test "x$LINE" = x ; then
+    echo "$each needed to compile";
+    exit 1;
+  fi
+done
+
diff --git a/src/gtk/setup/linux/maketmpl b/src/gtk/setup/linux/maketmpl
new file mode 100644
index 0000000000..c4974f50d4
--- /dev/null
+++ b/src/gtk/setup/linux/maketmpl
@@ -0,0 +1,123 @@
+# Makefile for Autoconf.
+# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+#### Start of system configuration section. ####
+
+GLOBAL_LIB_DIR = $(WXBASEDIR)/lib/$(OS)
+GLOBAL_BIN_DIR = $(WXBASEDIR)/bin/$(OS)
+
+# define toolkit to use
+TOOLKIT_DEF = -D__GTK__
+
+# general compiler stuff
+OPTIMISE = -O2 
+PROFILE = 
+DEBUG = 
+
+# c-compiler stuff
+CC = gcc
+CFLAGS =   -Wall $(OPTIMISE) $(PROFILE) $(DEBUG)
+CPP = gcc -E
+
+# c++-compiler stuff
+CXX = c++
+CXXFLAGS =   -Wall $(OPTIMISE) $(PROFILE) $(DEBUG)
+CXXCPP = c++ -E
+
+# shared compile stuff
+PICFLAGS = -fPIC
+CREATE_SHARED = sharedLinux
+
+# other stuff
+RM = rm -f
+LEX = flex
+LEXLIB = -lfl
+YACC = bison -y
+RANLIB = ranlib
+INSTALL = /usr/bin/install -c
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_DATA = ${INSTALL} -m 644
+AWK = mawk
+LN_S = ln -s
+CJPEG_PROG = 
+CONVERT_PATH = /usr/bin/X11
+CONVERT_PROG = /usr/bin/X11/convert
+DJPEG_PROG = 
+GIFTOPNM_PROG = 
+NETPBM_PATH = 
+
+prefix = /usr/local
+exec_prefix = ${prefix}
+
+# Directory in which to install scripts.
+#bindir = ${exec_prefix}/bin
+
+# Directory in which to install library files.
+datadir = ${prefix}/share
+acdatadir = $(datadir)/autoconf
+
+# Directory in which to install documentation info files.
+infodir = ${prefix}/info
+
+X_CFLAGS =  -I/usr/X11R6/include
+X_LIBS =  -L/usr/X11R6/lib
+X_EXTRA_LIBS = 
+X_PRE_LIBS =  -lSM -lICE
+
+GUI_TK_INCLUDE = -I/usr/local/lib/glib/include -I/usr/local/include -I/usr/X11R6/include
+GUI_TK_LIBRARY = -L/usr/local/lib -L/usr/X11R6/lib -lgtk -lgdk -lglib -lXext -lX11 -lm
+GUI_TK_LINK = 
+
+OPENGL_INCLUDE = 
+OPENGL_LIBRARY = 
+OPENGL_LINK = 
+
+THREADS_LINK = 
+
+# INCLUDES
+WX_INCLUDES = \
+$(TOOLKIT_DEF) \
+-I. \
+-I.. \
+-I$(WXBASEDIR)/include \
+-I$(WXBASEDIR)/src/png \
+-I$(WXBASEDIR)/src/zlib \
+-I$(WXBASEDIR)/src/gdk_imlib \
+$(GUI_TK_INCLUDE) \
+$(OPENGL_INCLUDE) \
+$(X_CFLAGS)
+
+WX_LIBS = -L$(GLOBAL_LIB_DIR) -lwx_gtk
+
+OPENGL_LIBS = $(OPENGL_LIBRARY) $(OPENGL_LINK)
+
+GUI_TK_LIBS = $(GUI_TK_LIBRARY) $(GUI_TK_LINK)
+
+LINK = $(CXX) -o $@
+LINK_LIBS= \
+  $(WX_LIBS) \
+  $(GUI_TK_LIBS) \
+  $(X_EXTRA_LIBS) \
+  $(X_PRE_LIBS)
+  
+#  $(X_LIBS) -lX11 -lXext -lm      gtk-config does this for me
+
+# Don't include $(OPENGL_LIBS) or $(THREADS_LINK) in LINK_LIBS; they
+# can be conveniently added to BIN_LINK in Makefile.in.
+
+#### End of system configuration section. ####
diff --git a/src/gtk/setup/linux/substit b/src/gtk/setup/linux/substit
new file mode 100644
index 0000000000..31f305ccb8
--- /dev/null
+++ b/src/gtk/setup/linux/substit
@@ -0,0 +1,70 @@
+s|@OS@|linux|g
+s|@WXBASEDIR@|/home/karl/cvs/wxGTK|g
+s|@PROFILE@||g
+s|@DEBUG@||g
+s|@OPTIMISE@|-O2 |g
+s|@CC@|gcc|g
+s|@CFLAGS@|  -Wall|g
+s|@CPP@|gcc -E|g
+s|@CXX@|c++|g
+s|@CXXFLAGS@|  -Wall|g
+s|@CXXCPP@|c++ -E|g
+s|@PICFLAGS@|-fPIC|g
+s|@CREATE_SHARED@|sharedLinux|g
+s|@LEX@|flex|g
+s|@LEXLIB@|-lfl|g
+s|@YACC@|bison -y|g
+s|@RANLIB@|ranlib|g
+s|@INSTALL@|/usr/bin/install -c|g
+s|@INSTALL_PROGRAM@|${INSTALL}|g
+s|@INSTALL_DATA@|${INSTALL} -m 644|g
+s|@AWK@|mawk|g
+s|@LN_S@|ln -s|g
+s|@prefix@|/usr/local|g
+s|@exec_prefix@|${prefix}|g
+s|@bindir@|${exec_prefix}/bin|g
+s|@datadir@|${prefix}/share|g
+s|@infodir@|${prefix}/info|g
+s|@X_CFLAGS@| -I/usr/X11R6/include|g
+s|@X_LIBS@| -L/usr/X11R6/lib|g
+s|@X_EXTRA_LIBS@||g
+s|@X_PRE_LIBS@| -lSM -lICE|g
+s|@GUI_TK_INCLUDE@|-I/usr/local/lib/glib/include -I/usr/local/include -I/usr/X11R6/include|g
+s|@GUI_TK_LIBRARY@|-L/usr/local/lib -L/usr/X11R6/lib -lgtk -lgdk -lglib -lXext -lX11 -lm|g
+s|@GUI_TK_LINK@||g
+s|@OPENGL_INCLUDE@||g
+s|@OPENGL_LIBRARY@||g
+s|@OPENGL_LINK@||g
+s|@TOOLKIT@|GTK|g
+s|@TOOLKIT_DEF@|__GTK__|g
+s|@THREADS@|NONE|g
+s|@THREADS_LINK@||g
+s|@WXSTRING@|@WXSTRING@|g
+s|@TYPETREE@|NONE|g
+s|@METAFILE@|NONE|g
+s|@POSTSCRIPTDC@|POSTSCRIPTDC|g
+s|@WXGRAPH@|NONE|g
+s|@WXTREE@|NONE|g
+s|@DOCVIEW@|DOCVIEW|g
+s|@FORM@|NONE|g
+s|@PRINTPREVIEW@|PRINTPREVIEW|g
+s|@IPC@|IPC|g
+s|@HELP@|NONE|g
+s|@CLIPBOARD@|NONE|g
+s|@TIMEDATE@|TIMEDATE|g
+s|@FRACTION@|FRACTION|g
+s|@PROLOGIO@|NONE|g
+s|@PROLOGIOSRC@|NONE|g
+s|@ENHDIALOGBOX@|NONE|g
+s|@GAUGE@|GAUGE|g
+s|@GLCANVAS@|NONE|g
+s|@LAYOUT@|@LAYOUT@|g
+s|@WXRESOURCES@|WXRESOURCES|g
+s|@XRESOURCES@|XRESOURCES|g
+s|@SCROLLBAR@|SCROLLBAR|g
+s|@STATICITEMS@|@STATICITEMS@|g
+s|@TOOLBAR@|TOOLBAR|g
+s|@CONSTRAINTS@|CONSTRAINTS|g
+s|@RPC@|NONE|g
+s|@VIRLISTBOX@|NONE|g
+
diff --git a/src/gtk/setup/maketmpl.in b/src/gtk/setup/maketmpl.in
new file mode 100644
index 0000000000..961c31d281
--- /dev/null
+++ b/src/gtk/setup/maketmpl.in
@@ -0,0 +1,123 @@
+# Makefile for Autoconf.
+# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+#### Start of system configuration section. ####
+
+GLOBAL_LIB_DIR = $(WXBASEDIR)/lib/$(OS)
+GLOBAL_BIN_DIR = $(WXBASEDIR)/bin/$(OS)
+
+# define toolkit to use
+TOOLKIT_DEF = -D@TOOLKIT_DEF@
+
+# general compiler stuff
+OPTIMISE = @OPTIMISE@
+PROFILE = @PROFILE@
+DEBUG = @DEBUG@
+
+# c-compiler stuff
+CC = @CC@
+CFLAGS = @CFLAGS@ $(OPTIMISE) $(PROFILE) $(DEBUG)
+CPP = @CPP@
+
+# c++-compiler stuff
+CXX = @CXX@
+CXXFLAGS = @CXXFLAGS@ $(OPTIMISE) $(PROFILE) $(DEBUG)
+CXXCPP = @CXXCPP@
+
+# shared compile stuff
+PICFLAGS = @PICFLAGS@
+CREATE_SHARED = @CREATE_SHARED@
+
+# other stuff
+RM = rm -f
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+YACC = @YACC@
+RANLIB = @RANLIB@
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+AWK = @AWK@
+LN_S = @LN_S@
+CJPEG_PROG = 
+CONVERT_PATH = /usr/bin/X11
+CONVERT_PROG = /usr/bin/X11/convert
+DJPEG_PROG = 
+GIFTOPNM_PROG = 
+NETPBM_PATH = 
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+# Directory in which to install scripts.
+#bindir = @bindir@
+
+# Directory in which to install library files.
+datadir = @datadir@
+acdatadir = $(datadir)/autoconf
+
+# Directory in which to install documentation info files.
+infodir = @infodir@
+
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+
+GUI_TK_INCLUDE = @GUI_TK_INCLUDE@
+GUI_TK_LIBRARY = @GUI_TK_LIBRARY@
+GUI_TK_LINK = @GUI_TK_LINK@
+
+OPENGL_INCLUDE = @OPENGL_INCLUDE@
+OPENGL_LIBRARY = @OPENGL_LIBRARY@
+OPENGL_LINK = @OPENGL_LINK@
+
+THREADS_LINK = @THREADS_LINK@
+
+# INCLUDES
+WX_INCLUDES = \
+$(TOOLKIT_DEF) \
+-I. \
+-I.. \
+-I$(WXBASEDIR)/include \
+-I$(WXBASEDIR)/src/png \
+-I$(WXBASEDIR)/src/zlib \
+-I$(WXBASEDIR)/src/gdk_imlib \
+$(GUI_TK_INCLUDE) \
+$(OPENGL_INCLUDE) \
+$(X_CFLAGS)
+
+WX_LIBS = -L$(GLOBAL_LIB_DIR) -lwx_gtk
+
+OPENGL_LIBS = $(OPENGL_LIBRARY) $(OPENGL_LINK)
+
+GUI_TK_LIBS = $(GUI_TK_LIBRARY) $(GUI_TK_LINK)
+
+LINK = $(CXX) -o $@
+LINK_LIBS= \
+  $(WX_LIBS) \
+  $(GUI_TK_LIBS) \
+  $(X_EXTRA_LIBS) \
+  $(X_PRE_LIBS)
+  
+#  $(X_LIBS) -lX11 -lXext -lm      gtk-config does this for me
+
+# Don't include $(OPENGL_LIBS) or $(THREADS_LINK) in LINK_LIBS; they
+# can be conveniently added to BIN_LINK in Makefile.in.
+
+#### End of system configuration section. ####
diff --git a/src/gtk/setup/rules/bin b/src/gtk/setup/rules/bin
new file mode 100644
index 0000000000..c179a1bbc3
--- /dev/null
+++ b/src/gtk/setup/rules/bin
@@ -0,0 +1,13 @@
+# all that is to do
+all:: checkneeds binary
+clean:: clean_binary clean_obj
+
+# now include definite rules
+BIN_BASE_DIR=.
+
+# include rules to create library
+include $(RULES_GENERIC)/bin1
+# include rules to create objects
+include $(RULES_GENERIC)/obj
+# include rule to check for defines needed
+include $(RULES_GENERIC)/needed
diff --git a/src/gtk/setup/rules/bin2 b/src/gtk/setup/rules/bin2
new file mode 100644
index 0000000000..87c0ad8691
--- /dev/null
+++ b/src/gtk/setup/rules/bin2
@@ -0,0 +1,14 @@
+# all that is to do
+all:: checkneeds binary
+clean:: clean_binary clean_obj
+
+# now include definite rules
+BIN_BASE_DIR=.
+
+# include rules to create library
+include $(RULES_GENERIC)/bin2
+# include rules to create objects
+include $(RULES_GENERIC)/obj
+# include rule to check for defines needed
+include $(RULES_GENERIC)/needed
+
diff --git a/src/gtk/setup/rules/doc b/src/gtk/setup/rules/doc
new file mode 100644
index 0000000000..78f0f204f9
--- /dev/null
+++ b/src/gtk/setup/rules/doc
@@ -0,0 +1,90 @@
+SHELL=/bin/sh
+
+FILE_BASE=$(TEX_BASE:.tex=)
+
+BMP_FILES=$(XPM_FILES:.xpm=.bmp)
+EPS_FILES=$(XPM_FILES:.xpm=.eps)
+GIF_FILES=$(XPM_FILES:.xpm=.gif)
+
+TEX2RTF=$(WXBASEDIR)/bin/$(OSTYPE)/tex2rtf
+
+HTML_BUTTONS=back.gif forward.gif contents.gif up.gif
+
+all:: doc
+
+clean::
+	@ for each in $(DIRS) . ; do \
+	( cd $$each; \
+	  rm -f *.bmp *.eps *.gif *.aux *.dvi *.log  \
+	        *.ps  *.toc *~    *.idx *.hlp *.html \
+	        *.rtf *.ref *.xlp *.con *.win *.fts  \
+	        *.hpj *.HLP; \
+	); done 
+
+doc:: doc_ps doc_html doc_xlp doc_winhelp doc_rtf
+
+#############################################
+
+doc_ps:: $(FILE_BASE).ps
+
+$(FILE_BASE).ps: $(FILE_BASE).dvi
+	dvips $(FILE_BASE).dvi -o$@
+
+#############################################
+
+doc_dvi:: $(FILE_BASE).dvi
+
+$(FILE_BASE).dvi: $(FILE_BASE).tex $(TEX_ADDITIONAL) $(EPS_FILES)
+	latex $(FILE_BASE).tex
+	latex $(FILE_BASE).tex
+
+#############################################
+
+doc_xlp:: $(FILE_BASE).xlp
+
+$(FILE_BASE).xlp: $(FILE_BASE).tex $(TEX_ADDITIONAL)
+	$(TEX2RTF) $(FILE_BASE).tex $(FILE_BASE).xlp -twice -xlp
+
+#############################################
+
+doc_html:: $(FILE_BASE)_contents.html $(FILE_BASE).html
+
+$(FILE_BASE).html: 
+	@ln -s $(FILE_BASE)_contents.html $@
+
+$(FILE_BASE)_contents.html: $(FILE_BASE).tex $(TEX_ADDITIONAL) $(GIF_FILES) $(HTML_BUTTONS)
+	$(TEX2RTF) $(FILE_BASE).tex $(FILE_BASE) -twice -html
+
+#############################################
+
+doc_rtf:: $(FILE_BASE).rtf
+
+$(FILE_BASE).rtf: $(FILE_BASE).tex $(TEX_ADDITIONAL) $(BMP_FILES)
+	$(TEX2RTF) $(FILE_BASE).tex $(FILE_BASE).rtf -twice -rtf
+
+#############################################
+
+doc_winhelp:: $(FILE_BASE).win
+
+$(FILE_BASE).win: $(FILE_BASE).tex $(TEX_ADDITIONAL) $(BMP_FILES)
+	../../../bin/$(OSTYPE)/tex2rtf $(FILE_BASE).tex $(FILE_BASE).win -twice -winhelp
+	@echo final conversion still needs to be done by MSWin
+
+#############################################
+
+.SUFFIXES:
+.SUFFIXES: .eps .xpm
+.SUFFIXES: .bmp .xpm
+.SUFFIXES: .gif .xpm
+
+.xpm.eps :
+	@$(RM) -f $@
+	xpmtoppm $< | ppmtogif | giftopnm | pnmtops -rle -center -noturn -scale 0.5 - > $@
+
+.xpm.bmp :
+	@$(RM) -f $@
+	xpmtoppm $< | ppmtobmp -windows - > $@
+
+.xpm.gif :
+	@$(RM) -f $@ 
+	xpmtoppm $< | ppmtogif -interlace - > $@
diff --git a/src/gtk/setup/rules/gbin b/src/gtk/setup/rules/gbin
new file mode 100644
index 0000000000..1caea844d5
--- /dev/null
+++ b/src/gtk/setup/rules/gbin
@@ -0,0 +1,14 @@
+# all that is to do
+all:: checkneeds binary
+clean:: clean_binary clean_obj
+
+# now include definite rules
+BIN_BASE_DIR=$(GLOBAL_BIN_DIR)
+
+# include rules to create library
+include $(RULES_GENERIC)/bin1
+# include rules to create objects
+include $(RULES_GENERIC)/obj
+# include rule to check for defines needed
+include $(RULES_GENERIC)/needed
+
diff --git a/src/gtk/setup/rules/gbin2 b/src/gtk/setup/rules/gbin2
new file mode 100644
index 0000000000..2d12986436
--- /dev/null
+++ b/src/gtk/setup/rules/gbin2
@@ -0,0 +1,14 @@
+# all that is to do
+all:: checkneeds binary
+clean:: clean_binary clean_obj
+
+# now include definite rules
+BIN_BASE_DIR=$(GLOBAL_BIN_DIR)
+
+# include rules to create library
+include $(RULES_GENERIC)/bin2
+# include rules to create objects
+include $(RULES_GENERIC)/mkobj
+# include rule to check for defines needed
+include $(RULES_GENERIC)/needed
+
diff --git a/src/gtk/setup/rules/generic/bin1 b/src/gtk/setup/rules/generic/bin1
new file mode 100644
index 0000000000..d4c0bcdc64
--- /dev/null
+++ b/src/gtk/setup/rules/generic/bin1
@@ -0,0 +1,8 @@
+binary:: binary1
+
+depend_binary:: depend_binary1
+
+clean_binary:: clean_binary1
+
+include $(RULES_GENERIC)/bin1gen
+
diff --git a/src/gtk/setup/rules/generic/bin1gen b/src/gtk/setup/rules/generic/bin1gen
new file mode 100644
index 0000000000..c11c5a3634
--- /dev/null
+++ b/src/gtk/setup/rules/generic/bin1gen
@@ -0,0 +1,16 @@
+# create binary
+
+binary1:: $(BIN_BASE_DIR)/$(BIN_TARGET)
+
+$(BIN_BASE_DIR)/$(BIN_TARGET): $(BIN_OBJ)
+	@$(RM) -f $@
+	$(LINK) $(BIN_OBJ) -L. $(BIN_LINK) $(LINK_LIBS)
+
+# defining dependencies
+
+depend_binary1::
+
+# cleaning all files
+
+clean_binary1::
+	@$(RM) -f $(BIN_BASE_DIR)/$(BIN_TARGET)
diff --git a/src/gtk/setup/rules/generic/bin2 b/src/gtk/setup/rules/generic/bin2
new file mode 100644
index 0000000000..1394b8d050
--- /dev/null
+++ b/src/gtk/setup/rules/generic/bin2
@@ -0,0 +1,9 @@
+binary:: binary1 binary2
+
+depend_binary:: depend_binary1 depend_binary2
+
+clean_binary:: clean_binary1 clean_binary2
+
+include $(RULES_GENERIC)/bin1gen
+include $(RULES_GENERIC)/bin2gen
+
diff --git a/src/gtk/setup/rules/generic/bin2gen b/src/gtk/setup/rules/generic/bin2gen
new file mode 100644
index 0000000000..b1ab3c4260
--- /dev/null
+++ b/src/gtk/setup/rules/generic/bin2gen
@@ -0,0 +1,16 @@
+# create binary
+
+binary2:: $(BIN_BASE_DIR)/$(BIN2_TARGET)
+
+$(BIN_BASE_DIR)/$(BIN2_TARGET): $(BIN2_OBJ)
+	@$(RM) -f $@
+	$(LINK) $(BIN2_OBJ) -L. $(BIN2_LINK) $(LINK_LIBS)
+
+# defining dependencies
+
+depend_binary2::
+
+# cleaning all files
+
+clean_binary2::
+	@$(RM) -f $(BIN_BASE_DIR)/$(BIN2_TARGET)
diff --git a/src/gtk/setup/rules/generic/depend b/src/gtk/setup/rules/generic/depend
new file mode 100644
index 0000000000..0640db13c3
--- /dev/null
+++ b/src/gtk/setup/rules/generic/depend
@@ -0,0 +1,18 @@
+depend::
+	@echo "$(CXX) -MM \
+	    $(WX_INCLUDES) \
+	    $(ADD_COMPILE) \
+	    $(LIB_SRC) $(BIN_SRC) $(BIN2_SRC)"
+	@(cd .. ;\
+	    $(CXX) -MM \
+	    $(WX_INCLUDES) \
+	    $(ADD_COMPILE) \
+	    $(LIB_SRC) $(BIN_SRC) $(BIN2_SRC)\
+	) > .depend
+	@cp Makefile Makefile.bak
+	@cat Makefile.bak | awk 'BEGIN { found=0;} { if ( $$0 == "# DO NOT DELETE") {found=1} ; { if ( found==0 ) { print $$0; } } }' > Makefile1
+	@echo "# DO NOT DELETE" >> Makefile1
+	@cat .depend >> Makefile1
+	@mv Makefile1 Makefile
+	@rm .depend
+
diff --git a/src/gtk/setup/rules/generic/globals b/src/gtk/setup/rules/generic/globals
new file mode 100644
index 0000000000..3b6413a923
--- /dev/null
+++ b/src/gtk/setup/rules/generic/globals
@@ -0,0 +1,15 @@
+# creates subdirectories for object-files in case they are needed...
+
+subdirs::
+	@if test "x$(SRC_DIR)" != x ; then \
+	  echo -n "Creating necessary subdirs: "; \
+	  for each in $(SRC_DIR) xxx; do \
+	    if test "x$$each" != xxxx; then \
+	      echo -n "$$each "; \
+	      if test ! -d $$each ; then \
+	        mkdir $$each ; \
+	      fi; \
+	    fi; \
+	  done; \
+	  echo "";\
+	fi
diff --git a/src/gtk/setup/rules/generic/lib b/src/gtk/setup/rules/generic/lib
new file mode 100644
index 0000000000..589acc5822
--- /dev/null
+++ b/src/gtk/setup/rules/generic/lib
@@ -0,0 +1,17 @@
+# create library
+
+library:: $(LIB_BASE_DIR)/lib$(LIB_TARGET).a
+
+$(LIB_BASE_DIR)/lib$(LIB_TARGET).a: $(LIB_OBJ)
+	@$(RM) -f $@
+	$(AR) rv $@ $(LIB_OBJ)
+
+# defining dependencies
+
+depend_library::
+
+# cleaning all files
+
+clean_library::
+	@$(RM) -f $(LIB_BASE_DIR)/lib$(LIB_TARGET).a
+
diff --git a/src/gtk/setup/rules/generic/needed b/src/gtk/setup/rules/generic/needed
new file mode 100644
index 0000000000..5cd5975729
--- /dev/null
+++ b/src/gtk/setup/rules/generic/needed
@@ -0,0 +1,24 @@
+#SHELL=/bin/sh
+MYGREP=$(WXBASEDIR)/setup/general/mygrep
+checkneeds::
+	@if test "x$(NEEDED_DEFINES)" != x ; then \
+	  RESULT=0 ; \
+	  for each in $(NEEDED_DEFINES) xxx; do \
+	    if test "$$each" != xxx ; then \
+	      LINE=`cat $(SETUP_DIR)/wx_setup.h \
+	            | sed "s/ /,/g" \
+	            | $(MYGREP) ",$$each," \
+	            | $(MYGREP) "#define" \
+	            | $(MYGREP) "1" ` ; \
+	      if test "x$$LINE" = x ; then \
+	        (TMPVAR=`pwd`;\
+	         TMPVAR=`dirname $$TMPVAR`;\
+	         echo "$$each needed to compile "`basename $$TMPVAR`"...";\
+                );\
+	        RESULT=1 ; \
+	      fi; \
+	    fi; \
+	  done ;\
+	  exit $$RESULT; \
+	fi
+
diff --git a/src/gtk/setup/rules/generic/obj b/src/gtk/setup/rules/generic/obj
new file mode 100644
index 0000000000..92beab8180
--- /dev/null
+++ b/src/gtk/setup/rules/generic/obj
@@ -0,0 +1,30 @@
+.SUFFIXES:
+.SUFFIXES: .o .c 
+.SUFFIXES: .o .cc 
+.SUFFIXES: .o .cpp
+
+VPATH= ..
+
+.c.o :
+	@$(RM) -f $@
+	$(CC) -c -o $@ $(CFLAGS) -I.. $(WX_INCLUDES) $(ADD_COMPILE) $(WX_DEFINES) $<
+
+.cc.o :
+	@$(RM) -f $@
+	$(CXX) -c -o $@ $(CXXFLAGS) -I.. $(WX_INCLUDES) $(ADD_COMPILE) $(WX_DEFINES) $<
+
+.cpp.o :
+	@$(RM) -f $@
+	$(CXX) -c -o $@ $(CXXFLAGS) -I.. $(WX_INCLUDES) $(ADD_COMPILE) $(WX_DEFINES) $<
+
+clean_obj::
+	@$(RM) *.o *.osh
+	@if test "x$(SRC_DIR)" != x ; then \
+	  for each in $(SRC_DIR) xxx; do \
+	    if test -d $$each ; then \
+              $(RM) $$each/*.o $$each/*.osh ; \
+	    fi; \
+	  done; \
+	fi;
+
+include $(RULES_GENERIC)/depend
diff --git a/src/gtk/setup/rules/generic/slib b/src/gtk/setup/rules/generic/slib
new file mode 100644
index 0000000000..87b331d322
--- /dev/null
+++ b/src/gtk/setup/rules/generic/slib
@@ -0,0 +1,21 @@
+# create library
+
+library:: $(LIB_BASE_DIR)/lib$(LIB_TARGET).a
+
+$(LIB_BASE_DIR)/lib$(LIB_TARGET).a: $(LIB_OBJ)
+	@$(RM) -f $@ $(LIB_BASE_DIR)/lib$(LIB_TARGET).so $(LIB_BASE_DIR)/lib$(LIB_TARGET).so.*
+	@if test "x$(CREATE_SHARED)" != x; then\
+	  echo "$(SHARE_DIR)/$(CREATE_SHARED) $(CC) $(LIB_BASE_DIR)/lib$(LIB_TARGET).so $(LIB_MAJOR) $(LIB_MINOR) $(LIB_OBJ)"; \
+	  $(SHARE_DIR)/$(CREATE_SHARED) $(CC) $(LIB_BASE_DIR)/lib$(LIB_TARGET).so $(LIB_MAJOR) $(LIB_MINOR) $(LIB_OBJ); \
+	fi
+	$(AR) rv $@ $(LIB_OBJ)
+
+# defining dependencies
+
+depend_library::
+
+# cleaning all files
+
+clean_library::
+	@$(RM) -f $(LIB_BASE_DIR)/lib$(LIB_TARGET).a $(LIB_BASE_DIR)/lib$(LIB_TARGET).so.* $(LIB_BASE_DIR)/lib$(LIB_TARGET).so
+
diff --git a/src/gtk/setup/rules/generic/sobj b/src/gtk/setup/rules/generic/sobj
new file mode 100644
index 0000000000..b2d7c6aaba
--- /dev/null
+++ b/src/gtk/setup/rules/generic/sobj
@@ -0,0 +1,42 @@
+.SUFFIXES:
+.SUFFIXES: .o .c 
+.SUFFIXES: .o .cc 
+.SUFFIXES: .o .cpp
+
+VPATH= ..
+
+.c.o :
+	@$(RM) -f $@ $@sh
+	@if test "x$(PICFLAGS)" != x; then \
+	  echo "$(CC) -c -o $@sh $(PICFLAGS) $(CFLAGS) -I.. $(WX_INCLUDES) $(ADD_COMPILE) $(WX_DEFINES) $<";\
+	  $(CC) -c -o $@sh $(PICFLAGS) $(CFLAGS) -I.. $(WX_INCLUDES) $(ADD_COMPILE) $(WX_DEFINES) $<;\
+	fi
+	$(CC) -c -o $@ $(CFLAGS) -I.. $(WX_INCLUDES) $(ADD_COMPILE) $(WX_DEFINES) $<
+
+.cc.o :
+	@$(RM) -f $@ $@sh
+	@if test "x$(PICFLAGS)" != x; then \
+	  echo "$(CXX) -c -o $@sh $(PICFLAGS) $(CXXFLAGS) -I.. $(WX_INCLUDES) $(ADD_COMPILE) $(WX_DEFINES) $<";\
+	  $(CXX) -c -o $@sh $(PICFLAGS) $(CXXFLAGS) -I.. $(WX_INCLUDES) $(ADD_COMPILE) $(WX_DEFINES) $<;\
+	fi
+	$(CXX) -c -o $@ $(CXXFLAGS) -I.. $(WX_INCLUDES) $(ADD_COMPILE) $(WX_DEFINES) $<
+
+.cpp.o :
+	@$(RM) -f $@ $@sh
+	@if test "x$(PICFLAGS)" != x; then \
+	  echo "$(CXX) -c -o $@sh $(PICFLAGS) $(CXXFLAGS) -I.. $(WX_INCLUDES) $(ADD_COMPILE) $(WX_DEFINES) $<";\
+	  $(CXX) -c -o $@sh $(PICFLAGS) $(CXXFLAGS) -I.. $(WX_INCLUDES) $(ADD_COMPILE) $(WX_DEFINES) $<;\
+	fi
+	$(CXX) -c -o $@ $(CXXFLAGS) -I.. $(WX_INCLUDES) $(ADD_COMPILE) $(WX_DEFINES) $<
+
+clean_obj::
+	@$(RM) *.o *.osh
+	@if test "x$(SRC_DIR)" != x ; then \
+	  for each in $(SRC_DIR) xxx; do \
+	    if test -d $$each ; then \
+              $(RM) $$each/*.o $$each/*.osh ; \
+	    fi; \
+	  done; \
+	fi;
+
+include $(RULES_GENERIC)/depend
diff --git a/src/gtk/setup/rules/glib b/src/gtk/setup/rules/glib
new file mode 100644
index 0000000000..b0e244789c
--- /dev/null
+++ b/src/gtk/setup/rules/glib
@@ -0,0 +1,15 @@
+# all that is to do
+all:: checkneeds library
+clean:: clean_library clean_obj
+
+# now include definite rules
+LIB_BASE_DIR=$(GLOBAL_LIB_DIR)
+
+# include rules to create library
+include $(RULES_GENERIC)/lib
+# include rules to create objects
+include $(RULES_GENERIC)/obj
+# include rule to check for defines needed
+include $(RULES_GENERIC)/needed
+
+
diff --git a/src/gtk/setup/rules/glibbin b/src/gtk/setup/rules/glibbin
new file mode 100644
index 0000000000..edb0510517
--- /dev/null
+++ b/src/gtk/setup/rules/glibbin
@@ -0,0 +1,17 @@
+# all that is to do
+all:: checkneeds library binary
+clean:: clean_library clean_obj clean_binary
+
+# now include definite rules
+LIB_BASE_DIR=$(GLOBAL_LIB_DIR)
+BIN_BASE_DIR=.
+
+# include rules to create library
+include $(RULES_GENERIC)/lib
+# include rules to create binary
+include $(RULES_GENERIC)/bin1
+# include rules to create objects
+include $(RULES_GENERIC)/obj
+# include rule to check for defines needed
+include $(RULES_GENERIC)/needed
+
diff --git a/src/gtk/setup/rules/glibgbin b/src/gtk/setup/rules/glibgbin
new file mode 100644
index 0000000000..ee7a4023e3
--- /dev/null
+++ b/src/gtk/setup/rules/glibgbin
@@ -0,0 +1,18 @@
+# all that is to do
+all:: checkneeds library binary
+depend:: depend_library depend_binary 
+clean:: clean_library clean_obj clean_binary
+
+# now include definite rules
+LIB_BASE_DIR=$(GLOBAL_LIB_DIR)
+BIN_BASE_DIR=$(GLOBAL_BIN_DIR)
+
+# include rules to create library
+include $(RULES_GENERIC)/lib
+# include rules to create binary
+include $(RULES_GENERIC)/mkbin1
+# include rules to create objects
+include $(RULES_GENERIC)/obj
+# include rule to check for defines needed
+include $(RULES_GENERIC)/needed
+
diff --git a/src/gtk/setup/rules/gslib b/src/gtk/setup/rules/gslib
new file mode 100644
index 0000000000..794a2b0d23
--- /dev/null
+++ b/src/gtk/setup/rules/gslib
@@ -0,0 +1,15 @@
+# all that is to do
+all:: checkneeds library
+clean:: clean_library clean_obj
+
+# now include definite rules
+LIB_BASE_DIR=$(GLOBAL_LIB_DIR)
+
+# include rules to create shared library
+include $(RULES_GENERIC)/slib
+# include rules to create shared objects
+include $(RULES_GENERIC)/sobj
+# include rule to check for defines needed
+include $(RULES_GENERIC)/needed
+
+
diff --git a/src/gtk/setup/rules/lib b/src/gtk/setup/rules/lib
new file mode 100644
index 0000000000..7831e41a4a
--- /dev/null
+++ b/src/gtk/setup/rules/lib
@@ -0,0 +1,14 @@
+# all that is to do
+all:: checkneeds library
+clean:: clean_library clean_obj
+
+# now include definite rules
+LIB_BASE_DIR=.
+
+# include rules to create library
+include $(RULES_GENERIC)/lib
+# include rules to create objects
+include $(RULES_GENERIC)/obj
+# include rule to check for defines needed
+include $(RULES_GENERIC)/needed
+
diff --git a/src/gtk/setup/rules/libbin b/src/gtk/setup/rules/libbin
new file mode 100644
index 0000000000..97456c45f2
--- /dev/null
+++ b/src/gtk/setup/rules/libbin
@@ -0,0 +1,17 @@
+# all that is to do
+all:: checkneeds library binary
+clean:: clean_library clean_obj clean_binary
+
+# now include definite rules
+LIB_BASE_DIR=.
+BIN_BASE_DIR=.
+
+# include rules to create library
+include $(RULES_GENERIC)/lib
+# include rules to create binary
+include $(RULES_GENERIC)/bin1
+# include rules to create objects
+include $(RULES_GENERIC)/obj
+# include rule to check for defines needed
+include $(RULES_GENERIC)/needed
+
diff --git a/src/gtk/setup/rules/libgbin b/src/gtk/setup/rules/libgbin
new file mode 100644
index 0000000000..dc2ab616a9
--- /dev/null
+++ b/src/gtk/setup/rules/libgbin
@@ -0,0 +1,17 @@
+# all that is to do
+all:: checkneeds library binary
+clean:: clean_library clean_obj clean_binary
+
+# now include definite rules
+LIB_BASE_DIR=.
+BIN_BASE_DIR=$(GLOBAL_BIN_DIR)
+
+# include rules to create library
+include $(RULES_GENERIC)/lib
+# include rules to create binary
+include $(RULES_GENERIC)/mkbin1
+# include rules to create objects
+include $(RULES_GENERIC)/obj
+# include rule to check for defines needed
+include $(RULES_GENERIC)/needed
+
diff --git a/src/gtk/setup/setup.hin b/src/gtk/setup/setup.hin
new file mode 100644
index 0000000000..fe038e581a
--- /dev/null
+++ b/src/gtk/setup/setup.hin
@@ -0,0 +1,533 @@
+/* wx_setup.h
+   This file is in the public domain.
+
+   Descriptive text for the C preprocessor macros that
+   the distributed Autoconf macros can define.
+   No software package will use all of them; autoheader copies the ones
+   your configure.in uses into your configuration header file templates.
+
+   The entries are in sort -df order: alphabetical, case insensitive,
+   ignoring punctuation (such as underscores).  Although this order
+   can split up related entries, it makes it easier to check whether
+   a given entry is in the file.
+
+   Leave the following blank line there!!  Autoheader needs it.  */
+
+#ifndef __GTKSETUPH__
+#define __GTKSETUPH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+/* define the system to compile */
+#undef __GTK__
+#undef __UNIX__
+#undef __LINUX__
+#undef __SGI__
+#undef __HPUX__
+#undef __SYSV__
+#undef __SVR4__
+#undef __AIX__
+#undef __SUN__
+#undef __SOLARIS__
+#undef __SUNOS__
+#undef __ALPHA__
+#undef __OSF__
+#undef __BSD__
+#undef __FREEBSD__
+#undef __VMS__
+#undef __ULTRIX__
+#undef __DATA_GENERAL__
+
+/*
+ * Use zlib
+ */
+#undef USE_ZLIB
+/*
+ * Use gdk_imlib
+ */
+#undef USE_GDK_IMLIB
+/*
+ * Use libpng
+ */
+#undef USE_LIBPNG
+/*
+ * Use Threads
+ */
+#undef USE_THREADS
+#undef USE_THREADS_POSIX
+#undef USE_THREADS_SGI
+/*
+ * Use storable classes
+ */
+#undef USE_STORABLE_CLASSES
+/*
+ * Use automatic translation via gettext() in wxTString
+ */
+#undef USE_AUTOTRANS
+/*
+ * Use font metric files in GetTextExtent for wxPostScriptDC
+ * Use consistent PostScript fonts for AFM and printing (!)
+ */
+#undef USE_AFM_FOR_POSTSCRIPT
+#undef WX_NORMALIZED_PS_FONTS
+/*
+ * Use clipboard
+ */
+#undef USE_CLIPBOARD
+/*
+ * Use wxWindows layout constraint system
+ */
+#undef USE_CONSTRAINTS
+/*
+ * Use the document/view architecture
+ */
+#undef USE_DOC_VIEW_ARCHITECTURE
+/*
+ * Use enhanced dialog
+ */
+#undef USE_ENHANCED_DIALOG
+/*
+ * Use Form panel item placement
+ */
+#undef USE_FORM
+/*
+ * Use fraction class
+ */
+#undef USE_FRACTION
+/*
+ * Use gauge item
+ */
+#undef USE_GAUGE
+/*
+ * Implement a GLCanvas class as an interface to OpenGL, using the GLX
+ * extension to the X11 protocol.  You can use the (free) Mesa library
+ * if you don't have a 'real' OpenGL.
+ */
+#undef USE_GLX
+/*
+ * Use wxWindows help facility (needs USE_IPC 1)
+ */
+#undef USE_HELP
+/*
+ * Use iostream.h rather than iostream
+ */
+#undef USE_IOSTREAMH
+/*
+ * Use Interprocess communication
+ */
+#undef USE_IPC
+/*
+ * Use Metafile and Metafile device context
+ */
+#undef USE_METAFILE
+/*
+ * Use PostScript device context
+ */
+#undef USE_POSTSCRIPT
+/*
+ * Use the print/preview architecture
+ */
+#undef USE_PRINTING_ARCHITECTURE
+/*
+ * Use Prolog IO
+ */
+#undef USE_PROLOGIO
+/*
+ * Use Remote Procedure Call (Needs USE_IPC and USE_PROLOGIO)
+ */
+#undef USE_RPC
+/*
+ * Use wxGetResource & wxWriteResource (change .Xdefaults)
+ */
+#undef USE_RESOURCES
+/*
+ * Use scrollbar item
+ */
+#undef USE_SCROLLBAR
+/*
+ * Use time and date classes
+ */
+#undef USE_TIMEDATE
+/*
+ * Use toolbar, use Xt port toolbar (3D look)
+ */
+#undef USE_TOOLBAR
+#undef USE_XT_TOOLBAR
+/*
+ * Enables old type checking mechanism (wxSubType)
+ */
+#undef USE_TYPETREE
+/*
+ * Use virtual list box item
+ */
+#undef USE_VLBOX
+/*
+ * Use wxWindows resource loading (.wxr-files) (Needs USE_PROLOGIO 1)
+ */
+#undef USE_WX_RESOURCES
+/*
+ * Use wxGraph
+ */
+#undef USE_WXGRAPH
+/*
+ * Use wxTree
+ */
+
+/********************** DO NOT CHANGE BELOW THIS POINT **********************/
+
+/**************************** DEBUGGING FEATURES ****************************/
+
+/* Compatibility with 1.66 API.
+   Level 0: no backward compatibility, all new features
+   Level 1: wxDC, OnSize (etc.) compatibility, but
+   some new features such as event tables */
+#define WXWIN_COMPATIBILITY  1
+/*
+ * Enables debugging: memory tracing, assert, etc.
+ */
+#undef DEBUG
+/*
+ * Enables debugging version of wxObject::new and wxObject::delete (IF DEBUG)
+ * WARNING: this code may not work with all architectures, especially
+ * if alignment is an issue.
+ */
+#undef USE_MEMORY_TRACING
+/*
+ * Enable debugging version of global memory operators new and delete
+ * Disable it, If this causes problems (e.g. link errors)
+ */
+#undef USE_GLOBAL_MEMORY_OPERATORS
+/*
+ * If WXDEBUG && USE_MEMORY_TRACING && USE_GLOBAL_MEMORY_OPERATORS
+ * used to debug the memory allocation of wxWindows Xt port code
+ */
+#define USE_INTERNAL_MEMORY_TRACING 0
+/*
+ * Matthews garbage collection (used for MrEd?)
+ */
+#define WXGARBAGE_COLLECTION_ON 0
+
+/**************************** COMPILER FEATURES *****************************/
+
+/*
+ * Disable this if your compiler can't cope
+ * with omission of prototype parameters.
+ */
+#define REMOVE_UNUSED_ARG 1
+/*
+ * The const keyword is being introduced more in wxWindows.
+ * You can use this setting to maintain backward compatibility.
+ * If 0:	will use const wherever possible.
+ * If 1:	will use const only where necessary
+ *              for precompiled headers to work.
+ * If 2:	will be totally backward compatible, but precompiled
+ *	headers may not work and program size will be larger.
+ */
+#define CONST_COMPATIBILITY 0
+
+/************************ WINDOWS 3.1 COMPATIBILITY *************************/
+
+/*
+ * Normalize X drawing code to behave exactly as MSW.
+ */
+#define WX_STANDARD_GRAPHICS 0
+
+/******************* other stuff **********************************/
+/*
+ * Support image loading for wxBitmap (wxImage is needed for this)
+ */
+#define USE_IMAGE_LOADING 0
+#define WXIMAGE_INCLUDE "../../utils/image/src/wx_image.h"
+/*
+ * Use splines
+ */
+#define USE_SPLINES 1
+
+/*
+ * USE_DYNAMIC_CLASSES is TRUE for the Xt port
+ */
+#define USE_DYNAMIC_CLASSES 1
+/*
+ * USE_EXTENDED_STATICS is FALSE for the Xt port
+*/
+#define USE_EXTENDED_STATICS 0
+
+/*************************** IMAKEFILE EVALUATIOS ***************************/
+
+#if USE_XPM
+	#define USE_XPM_IN_X 1
+#else
+	#define USE_XPM_IN_X 0
+#endif
+#if USE_IMAGE_LOADING
+	#define USE_IMAGE_LOADING_IN_X 1
+#else
+	#define USE_IMAGE_LOADING_IN_X 0
+#endif
+
+/* here comes the system-specific stuff */
+
+/* acconfig.h
+   This file is in the public domain.
+
+   Descriptive text for the C preprocessor macros that
+   the distributed Autoconf macros can define.
+   No software package will use all of them; autoheader copies the ones
+   your configure.in uses into your configuration header file templates.
+
+   The entries are in sort -df order: alphabetical, case insensitive,
+   ignoring punctuation (such as underscores).  Although this order
+   can split up related entries, it makes it easier to check whether
+   a given entry is in the file. */
+
+/* Define if on AIX 3.
+   System headers sometimes define this.
+   We just want to avoid a redefinition error message.  */
+#ifndef _ALL_SOURCE
+#undef _ALL_SOURCE
+#endif
+
+/* Define if using alloca.c.  */
+#undef C_ALLOCA
+
+/* Define if type char is unsigned and you are not using gcc.  */
+#ifndef __CHAR_UNSIGNED__
+#undef __CHAR_UNSIGNED__
+#endif
+
+/* Define if the closedir function returns void instead of int.  */
+#undef CLOSEDIR_VOID
+
+/* Define to empty if the keyword does not work.  */
+#undef const
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+   This function is required for alloca.c support on those systems.  */
+#undef CRAY_STACKSEG_END
+
+/* Define for DGUX with <sys/dg_sys_info.h>.  */
+#undef DGUX
+
+/* Define if you have <dirent.h>.  */
+#undef DIRENT
+
+/* Define to the type of elements in the array set by `getgroups'.
+   Usually this is either `int' or `gid_t'.  */
+#undef GETGROUPS_T
+
+/* Define if the `getloadavg' function needs to be run setuid or setgid.  */
+#undef GETLOADAVG_PRIVILEGED
+
+/* Define if the `getpgrp' function takes no argument.  */
+#undef GETPGRP_VOID
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+#undef gid_t
+
+/* Define if you have alloca, as a function or macro.  */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix).  */
+#undef HAVE_ALLOCA_H
+
+/* Define if you don't have vprintf but do have _doprnt.  */
+#undef HAVE_DOPRNT
+
+/* Define if your system has its own `getloadavg' function.  */
+#undef HAVE_GETLOADAVG
+
+/* Define if you have the getmntent function.  */
+#undef HAVE_GETMNTENT
+
+/* Define if the `long double' type works.  */
+#undef HAVE_LONG_DOUBLE
+
+/* Define if you support file names longer than 14 characters.  */
+#undef HAVE_LONG_FILE_NAMES
+
+/* Define if you have a working `mmap' system call.  */
+#undef HAVE_MMAP
+
+/* Define if system calls automatically restart after interruption
+   by a signal.  */
+#undef HAVE_RESTARTABLE_SYSCALLS
+
+/* Define if your struct stat has st_blksize.  */
+#undef HAVE_ST_BLKSIZE
+
+/* Define if your struct stat has st_blocks.  */
+#undef HAVE_ST_BLOCKS
+
+/* Define if you have the strcoll function and it is properly defined.  */
+#undef HAVE_STRCOLL
+
+/* Define if your struct stat has st_rdev.  */
+#undef HAVE_ST_RDEV
+
+/* Define if you have the strftime function.  */
+#undef HAVE_STRFTIME
+
+/* Define if you have <sys/wait.h> that is POSIX.1 compatible.  */
+#undef HAVE_SYS_WAIT_H
+
+/* Define if your struct tm has tm_zone.  */
+#undef HAVE_TM_ZONE
+
+/* Define if you don't have tm_zone but do have the external array
+   tzname.  */
+#undef HAVE_TZNAME
+
+/* Define if you have <unistd.h>.  */
+#undef HAVE_UNISTD_H
+
+/* Define if utime(file, NULL) sets file's timestamp to the present.  */
+#undef HAVE_UTIME_NULL
+
+/* Define if you have <vfork.h>.  */
+#undef HAVE_VFORK_H
+
+/* Define if you have the vprintf function.  */
+#undef HAVE_VPRINTF
+
+/* Define if you have the wait3 system call.  */
+#undef HAVE_WAIT3
+
+/* Define as __inline if that's what the C compiler calls it.  */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define if major, minor, and makedev are declared in <mkdev.h>.  */
+#undef MAJOR_IN_MKDEV
+
+/* Define if major, minor, and makedev are declared in <sysmacros.h>.  */
+#undef MAJOR_IN_SYSMACROS
+
+/* Define if on MINIX.  */
+#undef _MINIX
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+#undef mode_t
+
+/* Define if you don't have <dirent.h>, but have <ndir.h>.  */
+#undef NDIR
+
+/* Define if you have <memory.h>, and <string.h> doesn't declare the
+   mem* functions.  */
+#undef NEED_MEMORY_H
+
+/* Define if your struct nlist has an n_un member.  */
+#undef NLIST_NAME_UNION
+
+/* Define if you have <nlist.h>.  */
+#undef NLIST_STRUCT
+
+/* Define if your C compiler doesn't accept -c and -o together.  */
+#undef NO_MINUS_C_MINUS_O
+
+/* Define to `long' if <sys/types.h> doesn't define.  */
+#undef off_t
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+#undef pid_t
+
+/* Define if the system does not provide POSIX.1 features except
+   with this defined.  */
+#undef _POSIX_1_SOURCE
+
+/* Define if you need to in order for stat and other things to work.  */
+#undef _POSIX_SOURCE
+
+/* Define as the return type of signal handlers (int or void).  */
+#undef RETSIGTYPE
+
+/* Define if the setvbuf function takes the buffering type as its second
+   argument and the buffer pointer as the third, as on System V
+   before release 3.  */
+#undef SETVBUF_REVERSED
+
+/* Define SIZESOF for some Objects  */
+#undef SIZEOF_INT
+#undef SIZEOF_INT_P
+#undef SIZEOF_LONG
+
+/* Define to `unsigned' if <sys/types.h> doesn't define.  */
+#undef size_t
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at run-time.
+	STACK_DIRECTION > 0 => grows toward higher addresses
+	STACK_DIRECTION < 0 => grows toward lower addresses
+	STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
+/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly.  */
+#undef STAT_MACROS_BROKEN
+
+/* Define if you have the ANSI C header files.  */
+#undef STDC_HEADERS
+
+/* Define on System V Release 4.  */
+#undef SVR4
+
+/* Define on BSD  */
+#undef BSD
+
+/* Define on System V */
+#undef SYSV
+
+/* Define if you don't have <dirent.h>, but have <sys/dir.h>.  */
+#undef SYSDIR
+
+/* Define if you don't have <dirent.h>, but have <sys/ndir.h>.  */
+#undef SYSNDIR
+
+/* Define if `sys_siglist' is declared by <signal.h>.  */
+#undef SYS_SIGLIST_DECLARED
+
+/* Define if you can safely include both <sys/time.h> and <time.h>.  */
+#undef TIME_WITH_SYS_TIME
+
+/* Define if your <sys/time.h> declares struct tm.  */
+#undef TM_IN_SYS_TIME
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+#undef uid_t
+
+/* Define for Encore UMAX.  */
+#undef UMAX
+
+/* Define for Encore UMAX 4.3 that has <inq_status/cpustats.h>
+   instead of <sys/cpustats.h>.  */
+#undef UMAX4_3
+
+/* Define if you do not have <strings.h>, index, bzero, etc..  */
+#undef USG
+
+/* Define if the system is System V Release 4 */
+#undef SVR4
+
+/* Define vfork as fork if vfork does not work.  */
+#undef vfork
+
+/* Define if the closedir function returns void instead of int.  */
+#undef VOID_CLOSEDIR
+
+/* Define if your processor stores words with the most significant
+   byte first (like Motorola and SPARC, unlike Intel and VAX).  */
+#undef WORDS_BIGENDIAN
+
+/* Define if lex declares yytext as a char * by default, not a char[].  */
+#undef YYTEXT_POINTER
+
+#endif /* __GTKSETUPH__ */
+
+
+/* Leave that blank line there!!  Autoheader needs it.
+   If you're adding to this file, keep in mind:
+   The entries are in sort -df order: alphabetical, case insensitive,
+   ignoring punctuation (such as underscores).  */
diff --git a/src/gtk/setup/shared/sharedAIX b/src/gtk/setup/shared/sharedAIX
new file mode 100755
index 0000000000..cc9b6e164e
--- /dev/null
+++ b/src/gtk/setup/shared/sharedAIX
@@ -0,0 +1,26 @@
+#! /bin/sh
+
+COMPILER=$1
+LIBRARY_BASE=$2
+LIBRARY_MAJOR=$3
+LIBRARY_MINOR=$4
+shift 3
+LIBRARY_OBJS=
+while (test $# -ne 1) do
+  shift;
+  LIBRARY_OBJS="$LIBRARY_OBJS $1sh";
+done
+
+LIBRARY_BASE=`echo $LIBRARY_BASE | sed 's/.so/.sa/'`
+LIBRARY_NAME=`basename $LIBRARY_BASE`
+LIBRARY_FILE=$LIBRARY_BASE
+
+echo "Creating shared library: $LIBRARY_FILE"
+
+ar cr $LIBRARY_FILE~ $LIBRARY_OBJS
+nm $LIBRARY_OBJS | awk  '/ [BD] /{print $$3}' | sort | uniq > ${LIBRARY_FILE}.syms
+ld -o shr.o $LIBRARY_FILE~ -lX11 -lXt -lc -lm -H512 -T512 -bE:${LIBRARY_FILE}.syms -bM:SRE
+rm -f $LIBRARY_FILE~
+ar ruv $LIBRARY_FILE shr.o
+chmod a+x $LIBRARY_FILE
+
diff --git a/src/gtk/setup/shared/sharedBsd b/src/gtk/setup/shared/sharedBsd
new file mode 100755
index 0000000000..4e6db1ccc7
--- /dev/null
+++ b/src/gtk/setup/shared/sharedBsd
@@ -0,0 +1,33 @@
+#! /bin/sh
+
+#LIBRARY_BASE=`echo $1 | sed 's/.a/.so/'`
+COMPILER=$1
+LIBRARY_BASE=$2
+LIBRARY_MAJOR=$3
+LIBRARY_MINOR=$4
+shift 3
+LIBRARY_OBJS=
+while (test $# -ne 1) do
+  shift;
+  LIBRARY_OBJS="$LIBRARY_OBJS $1sh";
+done
+
+LIBRARY_NAME=`basename $LIBRARY_BASE`
+LIBRARY_FILE=$LIBRARY_BASE.$LIBRARY_MAJOR.$LIBRARY_MINOR
+
+echo "Creating shared library: $LIBRARY_FILE"
+
+if test "x$COMPILER" = xgcc ; then
+  gcc -shared -o $LIBRARY_FILE $LIBRARY_OBJS
+else
+  CC -Bshareable -Bforcearchive -o $LIBRARY_FILE $LIBRARY_OBJS
+fi
+chmod a+x $LIBRARY_FILE
+rm -f $LIBRARY_BASE.$LIBRARY_MAJOR
+ln -s $LIBRARY_NAME.$LIBRARY_MAJOR.$LIBRARY_MINOR $LIBRARY_BASE.$LIBRARY_MAJOR
+rm -f $LIBRARY_BASE
+ln -s $LIBRARY_NAME.$LIBRARY_MAJOR $LIBRARY_BASE
+
+
+
+
diff --git a/src/gtk/setup/shared/sharedDgux b/src/gtk/setup/shared/sharedDgux
new file mode 100755
index 0000000000..d2bfc2a1a2
--- /dev/null
+++ b/src/gtk/setup/shared/sharedDgux
@@ -0,0 +1,29 @@
+#! /bin/sh
+
+COMPILER=$1
+LIBRARY_BASE=$2
+LIBRARY_MAJOR=$3
+LIBRARY_MINOR=$4
+shift 3
+LIBRARY_OBJS=
+while (test $# -ne 1) do
+  shift;
+  LIBRARY_OBJS="$LIBRARY_OBJS $1sh";
+done
+
+LIBRARY_BASE=`echo $LIBRARY_BASE | sed 's/.so/.sl/'`
+LIBRARY_NAME=`basename $LIBRARY_BASE`
+LIBRARY_FILE=$LIBRARY_BASE
+
+echo "Creating shared library: $LIBRARY_FILE"
+
+if test "x$COMPILER" = xgcc ; then
+  gcc -shared -h $LIBRARY_NAME -o $LIBRARY_FILE $LIBRARY_OBJS
+else
+  CC -G -h $LIBRARY_NAME -o $LIBRARY_FILE $LIBRARY_OBJS
+fi
+chmod a+x $LIBRARY_FILE
+
+
+
+
diff --git a/src/gtk/setup/shared/sharedHpux b/src/gtk/setup/shared/sharedHpux
new file mode 100755
index 0000000000..60c198d862
--- /dev/null
+++ b/src/gtk/setup/shared/sharedHpux
@@ -0,0 +1,29 @@
+#! /bin/sh
+
+COMPILER=$1
+LIBRARY_BASE=$2
+LIBRARY_MAJOR=$3
+LIBRARY_MINOR=$4
+shift 3
+LIBRARY_OBJS=
+while (test $# -ne 1) do
+  shift;
+  LIBRARY_OBJS="$LIBRARY_OBJS $1sh";
+done
+
+LIBRARY_BASE=`echo $LIBRARY_BASE | sed 's/.so/.sl/'`
+LIBRARY_NAME=`basename $LIBRARY_BASE`
+LIBRARY_FILE=$LIBRARY_BASE
+
+echo "Creating shared library: $LIBRARY_FILE"
+
+if test "x$COMPILER" = xgcc ; then
+  gcc -shared -o $LIBRARY_FILE $LIBRARY_OBJS
+else
+  CC -Wl,+s -o $LIBRARY_FILE $LIBRARY_OBJS
+fi
+chmod a+x $LIBRARY_FILE
+
+
+
+
diff --git a/src/gtk/setup/shared/sharedIrix b/src/gtk/setup/shared/sharedIrix
new file mode 100755
index 0000000000..d2b5393c3d
--- /dev/null
+++ b/src/gtk/setup/shared/sharedIrix
@@ -0,0 +1,45 @@
+#! /bin/sh
+# on Irix, position independent code is the default
+
+#LIBRARY_BASE=`echo $1 | sed 's/.a/.so/'`
+COMPILER=$1
+LIBRARY_BASE=$2
+LIBRARY_MAJOR=$3
+LIBRARY_MINOR=$4
+shift 3
+LIBRARY_OBJS=
+while (test $# -ne 1) do
+  shift;
+  LIBRARY_OBJS="$LIBRARY_OBJS $1";
+done
+
+LIBRARY_NAME=`basename $LIBRARY_BASE`
+LIBRARY_FILE=$LIBRARY_BASE.$LIBRARY_MAJOR.$LIBRARY_MINOR
+
+echo "Creating shared library: $LIBRARY_FILE"
+
+if test ! -f /tmp/so_locations; then
+  if test -f /usr/lib/so_locations; then
+    cp /usr/lib/so_locations /tmp
+  else
+    touch /tmp/so_locations
+  fi
+fi
+chmod u+w /tmp/so_locations
+
+if test "x$COMPILER" = xgcc ; then
+  gcc -shared -Wl,-update_registry,/tmp/so_locations \
+    -Wl,-soname,$LIBRARY_NAME.$LIBRARY_MAJOR -o $LIBRARY_FILE $LIBRARY_OBJS
+else
+  CC -shared -update_registry /tmp/so_locations \
+    -soname $LIBRARY_NAME.$LIBRARY_MAJOR -o $LIBRARY_FILE $LIBRARY_OBJS
+fi
+chmod a+x $LIBRARY_FILE
+rm -f $LIBRARY_BASE.$LIBRARY_MAJOR
+ln -s $LIBRARY_NAME.$LIBRARY_MAJOR.$LIBRARY_MINOR $LIBRARY_BASE.$LIBRARY_MAJOR
+rm -f $LIBRARY_BASE
+ln -s $LIBRARY_NAME.$LIBRARY_MAJOR $LIBRARY_BASE
+
+
+
+
diff --git a/src/gtk/setup/shared/sharedLinux b/src/gtk/setup/shared/sharedLinux
new file mode 100755
index 0000000000..c274903db1
--- /dev/null
+++ b/src/gtk/setup/shared/sharedLinux
@@ -0,0 +1,34 @@
+#! /bin/sh
+
+#LIBRARY_BASE=`echo $1 | sed 's/.a/.so/'`
+COMPILER=$1
+LIBRARY_BASE=$2
+LIBRARY_MAJOR=$3
+LIBRARY_MINOR=$4
+shift 3
+LIBRARY_OBJS=
+while (test $# -ne 1) do
+  shift;
+  LIBRARY_OBJS="$LIBRARY_OBJS $1sh";
+done
+
+LIBRARY_NAME=`basename $LIBRARY_BASE`
+LIBRARY_FILE=$LIBRARY_BASE.$LIBRARY_MAJOR.$LIBRARY_MINOR
+
+echo "Creating shared library: $LIBRARY_FILE"
+
+case $COMPILER in gcc*|*gcc)
+  $COMPILER -shared -Wl,-soname,$LIBRARY_NAME.$LIBRARY_MAJOR -o $LIBRARY_FILE $LIBRARY_OBJS
+  ;;
+*)
+  $COMPILER -shared -soname $LIBRARY_NAME.$LIBRARY_MAJOR -o $LIBRARY_FILE $LIBRARY_OBJS
+esac
+chmod a+x $LIBRARY_FILE
+rm -f $LIBRARY_BASE.$LIBRARY_MAJOR
+ln -s $LIBRARY_NAME.$LIBRARY_MAJOR.$LIBRARY_MINOR $LIBRARY_BASE.$LIBRARY_MAJOR
+rm -f $LIBRARY_BASE
+ln -s $LIBRARY_NAME.$LIBRARY_MAJOR $LIBRARY_BASE
+
+
+
+
diff --git a/src/gtk/setup/shared/sharedOSF b/src/gtk/setup/shared/sharedOSF
new file mode 100755
index 0000000000..03ba07eca1
--- /dev/null
+++ b/src/gtk/setup/shared/sharedOSF
@@ -0,0 +1,33 @@
+#! /bin/sh
+
+#LIBRARY_BASE=`echo $1 | sed 's/.a/.so/'`
+COMPILER=$1
+LIBRARY_BASE=$2
+LIBRARY_MAJOR=$3
+LIBRARY_MINOR=$4
+shift 3
+LIBRARY_OBJS=
+while (test $# -ne 1) do
+  shift;
+  LIBRARY_OBJS="$LIBRARY_OBJS $1sh";
+done
+
+LIBRARY_NAME=`basename $LIBRARY_BASE`
+LIBRARY_FILE=$LIBRARY_BASE.$LIBRARY_MAJOR.$LIBRARY_MINOR
+
+echo "Creating shared library: $LIBRARY_FILE"
+
+if test "x$COMPILER" = xgcc ; then
+  gcc -shared -Wl,-soname,$LIBRARY_NAME -o $LIBRARY_FILE $LIBRARY_OBJS
+else
+  $COMPILER -shared -soname $LIBRARY_NAME -o $LIBRARY_FILE $LIBRARY_OBJS
+fi
+chmod a+x $LIBRARY_FILE
+rm -f $LIBRARY_BASE.$LIBRARY_MAJOR
+ln -s $LIBRARY_NAME.$LIBRARY_MAJOR.$LIBRARY_MINOR $LIBRARY_BASE.$LIBRARY_MAJOR
+rm -f $LIBRARY_BASE
+ln -s $LIBRARY_NAME.$LIBRARY_MAJOR $LIBRARY_BASE
+
+
+
+
diff --git a/src/gtk/setup/shared/sharedSolaris2 b/src/gtk/setup/shared/sharedSolaris2
new file mode 100755
index 0000000000..52c9086ee2
--- /dev/null
+++ b/src/gtk/setup/shared/sharedSolaris2
@@ -0,0 +1,33 @@
+#! /bin/sh
+
+#LIBRARY_BASE=`echo $1 | sed 's/.a/.so/'`
+COMPILER=$1
+LIBRARY_BASE=$2
+LIBRARY_MAJOR=$3
+LIBRARY_MINOR=$4
+shift 3
+LIBRARY_OBJS=
+while (test $# -ne 1) do
+  shift;
+  LIBRARY_OBJS="$LIBRARY_OBJS $1sh";
+done
+
+LIBRARY_NAME=`basename $LIBRARY_BASE`
+LIBRARY_FILE=$LIBRARY_BASE.$LIBRARY_MAJOR.$LIBRARY_MINOR
+
+echo "Creating shared library: $LIBRARY_FILE"
+
+if test "x$COMPILER" = xgcc ; then
+  gcc -shared -h $LIBRARY_NAME -o $LIBRARY_FILE $LIBRARY_OBJS
+else
+  CC -G -h $LIBRARY_NAME -o $LIBRARY_FILE $LIBRARY_OBJS
+fi
+chmod a+x $LIBRARY_FILE
+rm -f $LIBRARY_BASE.$LIBRARY_MAJOR
+ln -s $LIBRARY_NAME.$LIBRARY_MAJOR.$LIBRARY_MINOR $LIBRARY_BASE.$LIBRARY_MAJOR
+rm -f $LIBRARY_BASE
+ln -s $LIBRARY_NAME.$LIBRARY_MAJOR $LIBRARY_BASE
+
+
+
+
diff --git a/src/gtk/setup/shared/sharedSunos4 b/src/gtk/setup/shared/sharedSunos4
new file mode 100755
index 0000000000..7544a00584
--- /dev/null
+++ b/src/gtk/setup/shared/sharedSunos4
@@ -0,0 +1,33 @@
+#! /bin/sh
+
+#LIBRARY_BASE=`echo $1 | sed 's/.a/.so/'`
+COMPILER=$1
+LIBRARY_BASE=$2
+LIBRARY_MAJOR=$3
+LIBRARY_MINOR=$4
+shift 3
+LIBRARY_OBJS=
+while (test $# -ne 1) do
+  shift;
+  LIBRARY_OBJS="$LIBRARY_OBJS $1sh";
+done
+
+LIBRARY_NAME=`basename $LIBRARY_BASE`
+LIBRARY_FILE=$LIBRARY_BASE.$LIBRARY_MAJOR.$LIBRARY_MINOR
+
+echo "Creating shared library: $LIBRARY_FILE"
+
+if test "x$COMPILER" = xgcc ; then
+  gcc -shared -o $LIBRARY_FILE $LIBRARY_OBJS
+else
+  CC -assert pure-text -o $LIBRARY_FILE $LIBRARY_OBJS
+fi
+chmod a+x $LIBRARY_FILE
+rm -f $LIBRARY_BASE.$LIBRARY_MAJOR
+ln -s $LIBRARY_NAME.$LIBRARY_MAJOR.$LIBRARY_MINOR $LIBRARY_BASE.$LIBRARY_MAJOR
+rm -f $LIBRARY_BASE
+ln -s $LIBRARY_NAME.$LIBRARY_MAJOR $LIBRARY_BASE
+
+
+
+
diff --git a/src/gtk/setup/shared/sharedSysV b/src/gtk/setup/shared/sharedSysV
new file mode 100755
index 0000000000..d2bfc2a1a2
--- /dev/null
+++ b/src/gtk/setup/shared/sharedSysV
@@ -0,0 +1,29 @@
+#! /bin/sh
+
+COMPILER=$1
+LIBRARY_BASE=$2
+LIBRARY_MAJOR=$3
+LIBRARY_MINOR=$4
+shift 3
+LIBRARY_OBJS=
+while (test $# -ne 1) do
+  shift;
+  LIBRARY_OBJS="$LIBRARY_OBJS $1sh";
+done
+
+LIBRARY_BASE=`echo $LIBRARY_BASE | sed 's/.so/.sl/'`
+LIBRARY_NAME=`basename $LIBRARY_BASE`
+LIBRARY_FILE=$LIBRARY_BASE
+
+echo "Creating shared library: $LIBRARY_FILE"
+
+if test "x$COMPILER" = xgcc ; then
+  gcc -shared -h $LIBRARY_NAME -o $LIBRARY_FILE $LIBRARY_OBJS
+else
+  CC -G -h $LIBRARY_NAME -o $LIBRARY_FILE $LIBRARY_OBJS
+fi
+chmod a+x $LIBRARY_FILE
+
+
+
+
diff --git a/src/gtk/setup/substit.in b/src/gtk/setup/substit.in
new file mode 100644
index 0000000000..8e907ed258
--- /dev/null
+++ b/src/gtk/setup/substit.in
@@ -0,0 +1,70 @@
+s|*OS*|@OS@|g
+s|*WXBASEDIR*|@WXBASEDIR@|g
+s|*PROFILE*|@PROFILE@|g
+s|*DEBUG*|@DEBUG@|g
+s|*OPTIMISE*|@OPTIMISE@|g
+s|*CC*|@CC@|g
+s|*CFLAGS*|@CFLAGS@|g
+s|*CPP*|@CPP@|g
+s|*CXX*|@CXX@|g
+s|*CXXFLAGS*|@CXXFLAGS@|g
+s|*CXXCPP*|@CXXCPP@|g
+s|*PICFLAGS*|@PICFLAGS@|g
+s|*CREATE_SHARED*|@CREATE_SHARED@|g
+s|*LEX*|@LEX@|g
+s|*LEXLIB*|@LEXLIB@|g
+s|*YACC*|@YACC@|g
+s|*RANLIB*|@RANLIB@|g
+s|*INSTALL*|@INSTALL@|g
+s|*INSTALL_PROGRAM*|@INSTALL_PROGRAM@|g
+s|*INSTALL_DATA*|@INSTALL_DATA@|g
+s|*AWK*|@AWK@|g
+s|*LN_S*|@LN_S@|g
+s|*prefix*|@prefix@|g
+s|*exec_prefix*|@exec_prefix@|g
+s|*bindir*|@bindir@|g
+s|*datadir*|@datadir@|g
+s|*infodir*|@infodir@|g
+s|*X_CFLAGS*|@X_CFLAGS@|g
+s|*X_LIBS*|@X_LIBS@|g
+s|*X_EXTRA_LIBS*|@X_EXTRA_LIBS@|g
+s|*X_PRE_LIBS*|@X_PRE_LIBS@|g
+s|*GUI_TK_INCLUDE*|@GUI_TK_INCLUDE@|g
+s|*GUI_TK_LIBRARY*|@GUI_TK_LIBRARY@|g
+s|*GUI_TK_LINK*|@GUI_TK_LINK@|g
+s|*OPENGL_INCLUDE*|@OPENGL_INCLUDE@|g
+s|*OPENGL_LIBRARY*|@OPENGL_LIBRARY@|g
+s|*OPENGL_LINK*|@OPENGL_LINK@|g
+s|*TOOLKIT*|@TOOLKIT@|g
+s|*TOOLKIT_DEF*|@TOOLKIT_DEF@|g
+s|*THREADS*|@THREADS@|g
+s|*THREADS_LINK*|@THREADS_LINK@|g
+s|*WXSTRING*|@WXSTRING@|g
+s|*TYPETREE*|@TYPETREE@|g
+s|*METAFILE*|@METAFILE@|g
+s|*POSTSCRIPTDC*|@POSTSCRIPTDC@|g
+s|*WXGRAPH*|@WXGRAPH@|g
+s|*WXTREE*|@WXTREE@|g
+s|*DOCVIEW*|@DOCVIEW@|g
+s|*FORM*|@FORM@|g
+s|*PRINTPREVIEW*|@PRINTPREVIEW@|g
+s|*IPC*|@IPC@|g
+s|*HELP*|@HELP@|g
+s|*CLIPBOARD*|@CLIPBOARD@|g
+s|*TIMEDATE*|@TIMEDATE@|g
+s|*FRACTION*|@FRACTION@|g
+s|*PROLOGIO*|@PROLOGIO@|g
+s|*PROLOGIOSRC*|@PROLOGIOSRC@|g
+s|*ENHDIALOGBOX*|@ENHDIALOGBOX@|g
+s|*GAUGE*|@GAUGE@|g
+s|*GLCANVAS*|@GLCANVAS@|g
+s|*LAYOUT*|@LAYOUT@|g
+s|*WXRESOURCES*|@WXRESOURCES@|g
+s|*XRESOURCES*|@XRESOURCES@|g
+s|*SCROLLBAR*|@SCROLLBAR@|g
+s|*STATICITEMS*|@STATICITEMS@|g
+s|*TOOLBAR*|@TOOLBAR@|g
+s|*CONSTRAINTS*|@CONSTRAINTS@|g
+s|*RPC*|@RPC@|g
+s|*VIRLISTBOX*|@VIRLISTBOX@|g
+
diff --git a/src/gtk/slider.cpp b/src/gtk/slider.cpp
new file mode 100644
index 0000000000..891fcf61f9
--- /dev/null
+++ b/src/gtk/slider.cpp
@@ -0,0 +1,247 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        slider.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "slider.h"
+#endif
+
+#include "wx/slider.h"
+#include "wx/utils.h"
+
+//-----------------------------------------------------------------------------
+// wxSlider
+//-----------------------------------------------------------------------------
+
+void gtk_slider_callback( GtkWidget *WXUNUSED(widget), wxSlider *win )
+{ 
+/*
+  printf( "OnScroll from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  if (!win->HasVMT()) return;
+    
+  float diff = win->m_adjust->value - win->m_oldPos;
+  if (fabs(diff) < 0.2) return;
+  
+  int command = 0;
+  
+  float line_step = win->m_adjust->step_increment;
+  float page_step = win->m_adjust->page_increment;
+  
+  if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN;
+  else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP;
+  else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN;
+  else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP;
+  else command = wxEVT_SCROLL_THUMBTRACK;
+
+  int value = (int)(win->m_adjust->value+0.5);
+      
+  int orient = wxHORIZONTAL;
+  if (win->GetWindowStyleFlag() & wxSB_VERTICAL == wxSB_VERTICAL) orient = wxHORIZONTAL;
+  
+  wxScrollEvent event( command, win->GetId(), value, orient );
+  event.SetEventObject( win );
+  win->ProcessEvent( event );
+  
+  wxCommandEvent cevent( wxEVT_COMMAND_SLIDER_UPDATED, win->GetId() );
+  cevent.SetEventObject( win );
+  win->ProcessEvent( cevent );
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxSlider,wxControl)
+
+wxSlider::wxSlider(void)
+{
+};
+
+wxSlider::wxSlider( wxWindow *parent, const wxWindowID id,
+        const int value, const int minValue, const int maxValue,
+        const wxPoint& pos, const wxSize& size,
+        const long style,
+/*      const wxValidator& validator = wxDefaultValidator, */
+        const wxString& name )
+{
+  Create( parent, id, value, minValue, maxValue,
+          pos, size, style, name );
+};
+
+wxSlider::~wxSlider(void)
+{
+};
+
+bool wxSlider::Create(wxWindow *parent, const wxWindowID id,
+        const int value, const int minValue, const int maxValue,
+        const wxPoint& pos, const wxSize& size,
+        const long style,
+/*      const wxValidator& validator = wxDefaultValidator, */
+        const wxString& name )
+{
+  m_needParent = TRUE;
+  
+  PreCreation( parent, id, pos, size, style, name );
+  
+  m_oldPos = 0.0;
+
+  if (style & wxSL_VERTICAL == wxSL_VERTICAL)
+    m_widget = gtk_hscale_new( NULL );
+  else
+    m_widget = gtk_vscale_new( NULL );
+    
+  m_adjust = gtk_range_get_adjustment( GTK_RANGE(m_widget) );
+  
+  gtk_signal_connect (GTK_OBJECT (m_adjust), "value_changed",
+		      (GtkSignalFunc) gtk_slider_callback, (gpointer) this );
+  SetRange( minValue, maxValue );
+  SetValue( value );
+  
+  PostCreation();
+  
+  Show( TRUE );
+    
+  return TRUE;
+};
+
+int wxSlider::GetValue(void) const
+{
+  return (int)(m_adjust->value+0.5);
+};
+
+void wxSlider::SetValue( const int value )
+{
+  float fpos = (float)value;
+  m_oldPos = fpos;
+  if (fabs(fpos-m_adjust->value) < 0.2) return;
+  m_adjust->value = fpos;
+  
+  gtk_signal_emit_by_name( GTK_OBJECT(m_adjust), "value_changed" );
+};
+
+void wxSlider::SetRange( const int minValue, const int maxValue )
+{
+  float fmin = (float)minValue;
+  float fmax = (float)maxValue;
+      
+  if ((fabs(fmin-m_adjust->lower) < 0.2) &&
+      (fabs(fmax-m_adjust->upper) < 0.2))
+      return;
+      
+  m_adjust->lower = fmin;
+  m_adjust->upper = fmax;
+
+  gtk_signal_emit_by_name( GTK_OBJECT(m_adjust), "changed" );
+};
+
+int wxSlider::GetMin(void) const
+{
+  return (int)(m_adjust->lower+0.5);
+};
+
+int wxSlider::GetMax(void) const
+{
+  return (int)(m_adjust->upper+0.5);
+};
+
+void wxSlider::SetPageSize( const int pageSize )
+{
+  float fpage = (float)pageSize;
+      
+  if (fabs(fpage-m_adjust->page_increment) < 0.2) return;
+      
+  m_adjust->page_increment = fpage;
+
+  gtk_signal_emit_by_name( GTK_OBJECT(m_adjust), "changed" );
+};
+
+int wxSlider::GetPageSize(void) const
+{
+  return (int)(m_adjust->page_increment+0.5);
+};
+
+void wxSlider::SetThumbLength( const int len )
+{
+  float flen = (float)len;
+      
+  if (fabs(flen-m_adjust->page_size) < 0.2) return;
+      
+  m_adjust->page_size = flen;
+
+  gtk_signal_emit_by_name( GTK_OBJECT(m_adjust), "changed" );
+};
+
+int wxSlider::GetThumbLength(void) const
+{
+  return (int)(m_adjust->page_size+0.5);
+};
+
+void wxSlider::SetLineSize( const int WXUNUSED(lineSize) )
+{
+};
+
+int wxSlider::GetLineSize(void) const
+{
+  return 0;
+};
+
+// not supported in wxGTK (and GTK)
+
+void wxSlider::GetSize( int *x, int *y ) const
+{
+  wxWindow::GetSize( x, y );
+};
+
+void wxSlider::SetSize( const int x, const int y, const int width, const int height, const int sizeFlags )
+{
+  wxWindow::SetSize( x, y, width, height, sizeFlags );
+};
+
+void wxSlider::GetPosition( int *x, int *y ) const
+{
+  wxWindow::GetPosition( x, y );
+};
+
+void wxSlider::SetTick( const int WXUNUSED(tickPos) )
+{
+};
+
+void wxSlider::SetTickFreq( const int WXUNUSED(n), const int WXUNUSED(pos) )
+{
+};
+
+int wxSlider::GetTickFreq(void) const
+{
+  return 0;
+};
+
+void wxSlider::ClearTicks(void)
+{
+};
+
+void wxSlider::SetSelection( const int WXUNUSED(minPos), const int WXUNUSED(maxPos) )
+{
+};
+
+int wxSlider::GetSelEnd(void) const
+{
+  return 0;
+};
+
+int wxSlider::GetSelStart(void) const
+{
+  return 0;
+};
+
+void wxSlider::ClearSel(void)
+{
+};
+
diff --git a/src/gtk/statbox.cpp b/src/gtk/statbox.cpp
new file mode 100644
index 0000000000..f07862fa34
--- /dev/null
+++ b/src/gtk/statbox.cpp
@@ -0,0 +1,49 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        statbox.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "statbox.h"
+#endif
+
+#include "wx/statbox.h"
+
+//-----------------------------------------------------------------------------
+// wxStaticBox
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxStaticBox,wxControl)
+
+wxStaticBox::wxStaticBox(void)
+{
+};
+
+wxStaticBox::wxStaticBox( wxWindow *parent, wxWindowID id, const wxString &label, 
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  Create( parent, id, label, pos, size, style, name );
+};
+
+bool wxStaticBox::Create( wxWindow *parent, wxWindowID id, const wxString &label, 
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  m_needParent = TRUE;
+  
+  PreCreation( parent, id, pos, size, style, name );
+
+  m_widget = gtk_frame_new( label );
+  
+  PostCreation();
+  
+  Show( TRUE );
+    
+  return TRUE;
+};
diff --git a/src/gtk/stattext.cpp b/src/gtk/stattext.cpp
new file mode 100644
index 0000000000..62340474fc
--- /dev/null
+++ b/src/gtk/stattext.cpp
@@ -0,0 +1,69 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        stattext.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "stattext.h"
+#endif
+
+#include "wx/stattext.h"
+
+//-----------------------------------------------------------------------------
+// wxStaticText
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxStaticText,wxControl)
+
+wxStaticText::wxStaticText(void)
+{
+};
+
+wxStaticText::wxStaticText( wxWindow *parent, wxWindowID id, const wxString &label, 
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  Create( parent, id, label, pos, size, style, name );
+};
+
+bool wxStaticText::Create( wxWindow *parent, wxWindowID id, const wxString &label, 
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  m_needParent = TRUE;
+  
+  wxSize newSize = size;
+  
+  PreCreation( parent, id, pos, size, style, name );
+  
+  m_widget = gtk_label_new( label );
+  
+  if (newSize.x == -1) newSize.x = gdk_string_measure( m_widget->style->font, label );
+  if (newSize.y == -1) newSize.y = 26;
+  SetSize( newSize.x, newSize.y );
+  
+  PostCreation();
+  
+  Show( TRUE );
+    
+  return TRUE;
+};
+
+wxString wxStaticText::GetLabel(void) const
+{
+  char *str = NULL;
+  gtk_label_get( GTK_LABEL(m_widget), &str );
+  wxString tmp( str );
+  return tmp;
+};
+
+void wxStaticText::SetLabel( const wxString &label )
+{
+  gtk_label_set( GTK_LABEL(m_widget), label );
+};
diff --git a/src/gtk/tbargtk.cpp b/src/gtk/tbargtk.cpp
new file mode 100644
index 0000000000..628b35c69d
--- /dev/null
+++ b/src/gtk/tbargtk.cpp
@@ -0,0 +1,207 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        tbargtk.cpp
+// Purpose:     GTK toolbar
+// Author:      Robert Roebling
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      
+// Copyright:   (c) Robert Roebling
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "tbargtk.h"
+#endif
+
+#include "wx/toolbar.h"
+
+//-----------------------------------------------------------------------------
+// wxToolBarTool
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxToolBarTool,wxObject)
+  
+wxToolBarTool::wxToolBarTool( wxToolBarGTK *owner, const int theIndex, 
+      const wxBitmap& bitmap1, const  wxBitmap& bitmap2, 
+      const bool toggle, wxObject *clientData,
+      const wxString& shortHelpString, const wxString& longHelpString )
+{
+  m_owner = owner;
+  m_index = theIndex;
+  m_bitmap1 = bitmap1;
+  m_bitmap2 = bitmap2;
+  m_isToggle = toggle;
+  m_enabled = TRUE;
+  m_toggleState = FALSE;
+  m_shortHelpString = shortHelpString;
+  m_longHelpString = longHelpString;
+  m_isMenuCommand = TRUE;
+  m_clientData = clientData;
+  m_deleteSecondBitmap = FALSE;
+};
+
+wxToolBarTool::~wxToolBarTool(void)
+{
+};
+
+//-----------------------------------------------------------------------------
+// wxToolBarGTK
+//-----------------------------------------------------------------------------
+
+static void gtk_toolbar_callback( GtkWidget *WXUNUSED(widget), wxToolBarTool *tool )
+{
+  if (!tool->m_enabled) return;
+  
+  if (tool->m_isToggle) tool->m_toggleState = !tool->m_toggleState;
+  
+  tool->m_owner->OnLeftClick( tool->m_index, tool->m_toggleState );
+};
+
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxToolBarGTK,wxControl)
+
+BEGIN_EVENT_TABLE(wxToolBarGTK, wxControl)
+END_EVENT_TABLE()
+
+wxToolBarGTK::wxToolBarGTK(void)
+{
+};
+
+wxToolBarGTK::wxToolBarGTK( wxWindow *parent, const wxWindowID id, 
+  const wxPoint& pos, const wxSize& size,
+  const long style, const wxString& name )
+{
+  Create( parent, id, pos, size, style, name );
+};
+
+wxToolBarGTK::~wxToolBarGTK(void)
+{
+};
+
+bool wxToolBarGTK::Create( wxWindow *parent, const wxWindowID id, 
+  const wxPoint& pos, const wxSize& size,
+  const long style, const wxString& name )
+{
+  m_needParent = TRUE;
+  
+  PreCreation( parent, id, pos, size, style, name );
+
+  m_tools.DeleteContents( TRUE );
+    
+  m_widget = gtk_handle_box_new();
+  
+  m_toolbar = GTK_TOOLBAR( gtk_toolbar_new( GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_ICONS ) );
+  
+  gtk_container_add( GTK_CONTAINER(m_widget), GTK_WIDGET(m_toolbar) );
+  
+  gtk_widget_show( GTK_WIDGET(m_toolbar) );
+  
+  PostCreation();
+  
+  Show( TRUE );
+    
+  return TRUE;
+};
+
+bool wxToolBarGTK::OnLeftClick( int toolIndex, bool toggleDown )
+{
+  wxCommandEvent event(wxEVT_COMMAND_TOOL_CLICKED, toolIndex);
+  event.SetEventObject(this);
+  event.SetExtraLong((long) toggleDown);
+
+  GetEventHandler()->ProcessEvent(event);
+
+  return TRUE;
+};
+
+void wxToolBarGTK::OnRightClick( int toolIndex, float WXUNUSED(x), float WXUNUSED(y) )
+{
+  wxCommandEvent event(wxEVT_COMMAND_TOOL_RCLICKED, toolIndex);
+  event.SetEventObject(this);
+
+  GetEventHandler()->ProcessEvent(event);
+};
+
+void wxToolBarGTK::OnMouseEnter( int toolIndex )
+{
+  wxCommandEvent event(wxEVT_COMMAND_TOOL_ENTER, toolIndex);
+  event.SetEventObject(this);
+
+  GetEventHandler()->ProcessEvent(event);
+};
+
+wxToolBarTool *wxToolBarGTK::AddTool( const int toolIndex, const wxBitmap& bitmap, 
+  const wxBitmap& pushedBitmap, const bool toggle, 
+  const float WXUNUSED(xPos), const float WXUNUSED(yPos), wxObject *clientData,  
+  const wxString& helpString1, const wxString& helpString2 )
+{
+  if (!bitmap.Ok()) return NULL;
+  
+  wxToolBarTool *tool = new wxToolBarTool( this, toolIndex, bitmap, pushedBitmap, toggle, 
+  clientData, helpString1, helpString2 );
+  
+  GdkPixmap *pixmap = bitmap.GetPixmap();
+  
+  GdkBitmap *mask = NULL;
+  if (bitmap.GetMask()) mask = bitmap.GetMask()->GetBitmap();
+  
+  GtkWidget *tool_pixmap = gtk_pixmap_new( pixmap, mask );
+  gtk_misc_set_alignment( GTK_MISC(tool_pixmap), 0.5, 0.5 );
+  
+  GtkToolbarChildType ctype = GTK_TOOLBAR_CHILD_BUTTON;
+  if (toggle) ctype = GTK_TOOLBAR_CHILD_TOGGLEBUTTON;
+  
+  gtk_toolbar_append_element( m_toolbar, 
+    ctype, NULL, NULL, helpString1, "", tool_pixmap, (GtkSignalFunc)gtk_toolbar_callback, (gpointer)tool );
+    
+  m_tools.Append( tool );    
+    
+  return tool;
+};
+
+void wxToolBarGTK::AddSeparator(void)
+{
+  gtk_toolbar_append_space( m_toolbar );
+};
+
+void wxToolBarGTK::ClearTools(void)
+{
+};
+
+void wxToolBarGTK::EnableTool(const int toolIndex, const bool enable)
+{
+};
+
+void wxToolBarGTK::ToggleTool(const int toolIndex, const bool toggle)
+{
+};
+
+void wxToolBarGTK::SetToggle(const int toolIndex, const bool toggle) 
+{
+};
+
+wxObject *wxToolBarGTK::GetToolClientData(const int index) const
+{
+};
+
+bool wxToolBarGTK::GetToolState(const int toolIndex) const
+{
+};
+
+bool wxToolBarGTK::GetToolEnabled(const int toolIndex) const
+{
+};
+
+void wxToolBarGTK::SetMargins(const int x, const int y)
+{
+};
+
+void wxToolBarGTK::SetToolPacking(const int packing)
+{
+};
+
+void wxToolBarGTK::SetToolSeparation(const int separation)
+{
+};
+
diff --git a/src/gtk/textctrl.cpp b/src/gtk/textctrl.cpp
new file mode 100644
index 0000000000..890393380a
--- /dev/null
+++ b/src/gtk/textctrl.cpp
@@ -0,0 +1,391 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        textctrl.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "textctrl.h"
+#endif
+
+#include "wx/textctrl.h"
+#include "wx/utils.h"
+
+//-----------------------------------------------------------------------------
+//  wxTextCtrl
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl,wxControl)
+
+
+BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
+//  EVT_CHAR(wxTextCtrl::OnChar)
+END_EVENT_TABLE()
+
+wxTextCtrl::wxTextCtrl(void) : streambuf()
+{
+};
+
+wxTextCtrl::wxTextCtrl( wxWindow *parent, const wxWindowID id, const wxString &value, 
+      const wxPoint &pos, const wxSize &size, 
+      const int style, const wxString &name ) : streambuf()
+{
+  Create( parent, id, value, pos, size, style, name );
+};
+
+bool wxTextCtrl::Create( wxWindow *parent, const wxWindowID id, const wxString &value,
+      const wxPoint &pos, const wxSize &size, 
+      const int style, const wxString &name )
+{
+  m_needParent = TRUE;
+  
+  PreCreation( parent, id, pos, size, style, name );
+  
+  if (style & wxTE_MULTILINE)
+    m_widget = gtk_text_new( NULL, NULL );
+  else
+    m_widget = gtk_entry_new();
+    
+  if (!value.IsNull())
+  {
+    gint tmp = 0;
+    gtk_editable_insert_text( GTK_EDITABLE(m_widget), value, value.Length(), &tmp );
+  };
+  
+  wxSize newSize = size;
+  if (newSize.x == -1) newSize.x = 80;
+  if (newSize.y == -1) newSize.y = 26;
+  SetSize( newSize.x, newSize.y );
+  
+  PostCreation();
+  
+  Show( TRUE );
+    
+  return TRUE;
+};
+
+wxString wxTextCtrl::GetValue(void) const
+{
+  wxString tmp;
+  if (m_windowStyle & wxTE_MULTILINE)
+  {
+    gint len = gtk_text_get_length( GTK_TEXT(m_widget) );
+    tmp = gtk_editable_get_chars( GTK_EDITABLE(m_widget), 0, len-1 );
+  }
+  else
+  {
+    tmp = gtk_entry_get_text( GTK_ENTRY(m_widget) );
+  };
+  return tmp;
+};
+
+void wxTextCtrl::SetValue( const wxString &value )
+{
+  wxString tmp = "";
+  if (!value.IsNull()) tmp = value;
+  if (m_windowStyle & wxTE_MULTILINE)
+  {
+    gint len = gtk_text_get_length( GTK_TEXT(m_widget) );
+    gtk_editable_delete_text( GTK_EDITABLE(m_widget), 0, len-1 );
+    len = 0;
+    gtk_editable_insert_text( GTK_EDITABLE(m_widget), tmp, tmp.Length(), &len );
+  }
+  else
+  {
+    gtk_entry_set_text( GTK_ENTRY(m_widget), tmp );
+  };
+};
+
+void wxTextCtrl::WriteText( const wxString &text )
+{
+  if (text.IsNull()) return;
+  if (m_windowStyle & wxTE_MULTILINE)
+  {
+    gint len = gtk_text_get_length( GTK_TEXT(m_widget) );
+    gtk_editable_insert_text( GTK_EDITABLE(m_widget), text, text.Length(), &len );
+  }
+  else
+  {
+    gtk_entry_append_text( GTK_ENTRY(m_widget), text );
+  };
+};
+
+/*
+wxString wxTextCtrl::GetLineText( const long lineNo ) const
+{
+};
+
+bool wxTextCtrl::LoadFile( const wxString &file )
+{
+};
+
+bool wxTextCtrl::SaveFile( const wxString &file )
+{
+};
+
+void wxTextCtrl::DiscardEdits(void)
+{
+};
+
+bool wxTextCtrl::IsModified(void)
+{
+};
+
+void wxTextCtrl::OnDropFiles( wxDropFilesEvent &event )
+{
+};
+
+long wxTextCtrl::PositionToXY( const long pos, long *x, long *y ) const
+{
+};
+
+long wxTextCtrl::XYToPosition( const long x, const long y )
+{
+};
+
+int wxTextCtrl::GetNumberOfLines(void)
+{
+};
+
+*/
+void wxTextCtrl::SetInsertionPoint( const long pos )
+{
+  int tmp = (int) pos;
+  if (m_windowStyle & wxTE_MULTILINE)
+    gtk_text_set_point( GTK_TEXT(m_widget), tmp );
+  else
+    gtk_entry_set_position( GTK_ENTRY(m_widget), tmp );
+};
+
+void wxTextCtrl::SetInsertionPointEnd(void)
+{
+  int pos = 0;
+  if (m_windowStyle & wxTE_MULTILINE)
+    pos = gtk_text_get_length( GTK_TEXT(m_widget) );
+  else
+    pos = GTK_ENTRY(m_widget)->text_length;
+  SetInsertionPoint( pos-1 );
+};
+
+void wxTextCtrl::SetEditable( const bool editable )
+{
+  if (m_windowStyle & wxTE_MULTILINE)
+    gtk_text_set_editable( GTK_TEXT(m_widget), editable );
+  else
+    gtk_entry_set_editable( GTK_ENTRY(m_widget), editable );
+};
+
+void wxTextCtrl::SetSelection( const long from, const long to )
+{
+  gtk_editable_select_region( GTK_EDITABLE(m_widget), (gint)from, (gint)to );
+};
+
+void wxTextCtrl::ShowPosition( const long WXUNUSED(pos) )
+{
+};
+
+long wxTextCtrl::GetInsertionPoint(void) const
+{
+  return (long) GTK_EDITABLE(m_widget)->current_pos;
+};
+
+long wxTextCtrl::GetLastPosition(void) const
+{
+  int pos = 0;
+  if (m_windowStyle & wxTE_MULTILINE)
+    pos = gtk_text_get_length( GTK_TEXT(m_widget) );
+  else
+    pos = GTK_ENTRY(m_widget)->text_length;
+  return (long)pos-1;
+};
+
+void wxTextCtrl::Remove( const long from, const long to )
+{
+  gtk_editable_delete_text( GTK_EDITABLE(m_widget), (gint)from, (gint)to );
+};
+
+void wxTextCtrl::Replace( const long from, const long to, const wxString &value )
+{
+  gtk_editable_delete_text( GTK_EDITABLE(m_widget), (gint)from, (gint)to );
+  if (value.IsNull()) return;
+  gint pos = (gint)to;
+  gtk_editable_insert_text( GTK_EDITABLE(m_widget), value, value.Length(), &pos );
+};
+
+void wxTextCtrl::Cut(void)
+{
+  gtk_editable_cut_clipboard( GTK_EDITABLE(m_widget), 0 );
+};
+
+void wxTextCtrl::Copy(void)
+{
+  gtk_editable_copy_clipboard( GTK_EDITABLE(m_widget), 0 );
+};
+
+void wxTextCtrl::Paste(void)
+{
+  gtk_editable_paste_clipboard( GTK_EDITABLE(m_widget), 0 );
+};
+
+void wxTextCtrl::Delete(void)
+{
+  SetValue( "" );
+};
+
+void wxTextCtrl::OnChar( wxKeyEvent &WXUNUSED(event) )
+{
+};
+
+int wxTextCtrl::overflow(int c)
+{
+  // Make sure there is a holding area
+  if ( allocate()==EOF )
+  {
+    wxError("Streambuf allocation failed","Internal error");
+    return EOF;
+  }
+  
+  // Verify that there are no characters in get area
+  if ( gptr() && gptr() < egptr() )
+  {
+     wxError("Who's trespassing my get area?","Internal error");
+     return EOF;
+  }
+
+  // Reset get area
+  setg(0,0,0);
+
+  // Make sure there is a put area
+  if ( ! pptr() )
+  {
+/* This doesn't seem to be fatal so comment out error message */
+//    wxError("Put area not opened","Internal error");
+    setp( base(), base() );
+  }
+
+  // Determine how many characters have been inserted but no consumed
+  int plen = pptr() - pbase();
+
+  // Now Jerry relies on the fact that the buffer is at least 2 chars
+  // long, but the holding area "may be as small as 1" ???
+  // And we need an additional \0, so let's keep this inefficient but
+  // safe copy.
+
+  // If c!=EOF, it is a character that must also be comsumed
+  int xtra = c==EOF? 0 : 1;
+
+  // Write temporary C-string to wxTextWindow
+  {
+  char *txt = new char[plen+xtra+1];
+  memcpy(txt, pbase(), plen);
+  txt[plen] = (char)c;     // append c
+  txt[plen+xtra] = '\0';   // append '\0' or overwrite c
+    // If the put area already contained \0, output will be truncated there
+  WriteText(txt);
+    delete[] txt;
+  }
+
+  // Reset put area
+  setp(pbase(), epptr());
+
+#if defined(__WATCOMC__)
+  return __NOT_EOF;
+#elif defined(zapeof)     // HP-UX (all cfront based?)
+  return zapeof(c);
+#else
+  return c!=EOF ? c : 0;  // this should make everybody happy
+#endif
+
+/* OLD CODE
+  int len = pptr() - pbase();
+  char *txt = new char[len+1];
+  strncpy(txt, pbase(), len);
+  txt[len] = '\0';
+  (*this) << txt;
+  setp(pbase(), epptr());
+  delete[] txt;
+  return EOF;
+*/
+};
+
+int wxTextCtrl::sync(void)
+{
+  // Verify that there are no characters in get area
+  if ( gptr() && gptr() < egptr() )
+  {
+     wxError("Who's trespassing my get area?","Internal error");
+     return EOF;
+  }
+
+  if ( pptr() && pptr() > pbase() ) return overflow(EOF);
+
+  return 0;
+/* OLD CODE
+  int len = pptr() - pbase();
+  char *txt = new char[len+1];
+  strncpy(txt, pbase(), len);
+  txt[len] = '\0';
+  (*this) << txt;
+  setp(pbase(), epptr());
+  delete[] txt;
+  return 0;
+*/
+};
+
+int wxTextCtrl::underflow(void)
+{
+  return EOF;
+};
+
+wxTextCtrl& wxTextCtrl::operator<<(const wxString& s)
+{
+  WriteText(s);
+  return *this;
+}
+
+wxTextCtrl& wxTextCtrl::operator<<(const float f)
+{
+  static char buf[100];
+  sprintf(buf, "%.2f", f);
+  WriteText(buf);
+  return *this;
+}
+
+wxTextCtrl& wxTextCtrl::operator<<(const double d)
+{
+  static char buf[100];
+  sprintf(buf, "%.2f", d);
+  WriteText(buf);
+  return *this;
+}
+
+wxTextCtrl& wxTextCtrl::operator<<(const int i)
+{
+  static char buf[100];
+  sprintf(buf, "%i", i);
+  WriteText(buf);
+  return *this;
+}
+
+wxTextCtrl& wxTextCtrl::operator<<(const long i)
+{
+  static char buf[100];
+  sprintf(buf, "%ld", i);
+  WriteText(buf);
+  return *this;
+}
+
+wxTextCtrl& wxTextCtrl::operator<<(const char c)
+{
+  char buf[2];
+
+  buf[0] = c;
+  buf[1] = 0;
+  WriteText(buf);
+  return *this;
+}
+
diff --git a/src/gtk/timer.cpp b/src/gtk/timer.cpp
new file mode 100644
index 0000000000..f87bffa62b
--- /dev/null
+++ b/src/gtk/timer.cpp
@@ -0,0 +1,71 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        timer.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "timer.h"
+#endif
+
+#include "wx/timer.h"
+
+//-----------------------------------------------------------------------------
+// wxTimer
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxTimer,wxObject)
+
+gint timeout_callback( gpointer data )
+{
+  wxTimer *timer = (wxTimer*)data;
+  timer->Notify();
+  if (timer->OneShot()) timer->Stop();
+  return TRUE;
+};
+
+wxTimer::wxTimer(void)
+{
+  m_tag = -1;
+  m_time = 1000;
+  m_oneShot = FALSE;
+};
+
+wxTimer::~wxTimer(void)
+{
+  Stop();
+};
+
+int wxTimer::Interval(void)
+{
+  return m_time;
+};
+
+bool wxTimer::OneShot(void)
+{
+  return m_oneShot;
+};
+
+void wxTimer::Notify(void)
+{
+};
+
+void wxTimer::Start( int millisecs, bool oneShot )
+{
+  if (millisecs != -1) m_time = millisecs;
+  m_oneShot = oneShot;
+  m_tag = gtk_timeout_add( millisecs, timeout_callback, this );
+};
+
+void wxTimer::Stop(void)
+{
+  if (m_tag != -1)
+    gtk_timeout_remove( m_tag );
+  m_tag = -1;
+};
+
diff --git a/src/gtk/utilsgtk.cpp b/src/gtk/utilsgtk.cpp
new file mode 100644
index 0000000000..3ff9803dd4
--- /dev/null
+++ b/src/gtk/utilsgtk.cpp
@@ -0,0 +1,406 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        utils.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+//#ifdef __GNUG__
+//#pragma implementation "utils.h"
+//#endif
+
+#include "wx/utils.h"
+#include "wx/string.h"
+
+#include <stdarg.h>
+#include <dirent.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <pwd.h>
+#include <errno.h>
+#include <netdb.h>
+
+#ifdef __SVR4__
+#include <sys/systeminfo.h>
+#endif
+
+//------------------------------------------------------------------------
+// misc.
+//------------------------------------------------------------------------
+
+void wxBell(void)
+{
+  gdk_beep();
+};
+
+//------------------------------------------------------------------------
+// user and home routines
+//------------------------------------------------------------------------
+
+char* wxGetHomeDir( char *dest )
+{
+  wxString tmp = wxGetUserHome( wxString() );
+  if (tmp.IsNull())
+    strcpy( wxBuffer, "/" );
+  else
+    strcpy( wxBuffer, tmp );
+  if (dest) strcpy( dest, WXSTRINGCAST tmp );
+  return wxBuffer;
+};
+
+char *wxGetUserHome( const wxString &user )
+{
+  struct passwd *who = NULL;
+
+  if (user.IsNull() || (user== "")) 
+  {
+	register char *ptr;
+
+	if ((ptr = getenv("HOME")) != NULL) 
+	    return ptr;
+	if ((ptr = getenv("USER")) != NULL
+	|| (ptr = getenv("LOGNAME")) != NULL) {
+	    who = getpwnam(ptr);
+	}
+	// We now make sure the the user exists!
+	if (who == NULL)
+	    who = getpwuid(getuid());
+  } 
+  else
+    who = getpwnam (user);
+    
+  return who ? who->pw_dir : (char*)NULL;
+};
+
+//------------------------------------------------------------------------
+// id routines
+//------------------------------------------------------------------------
+
+bool wxGetHostName(char *buf, int sz)
+{
+    *buf = '\0';
+#if defined(__SVR4__) && !defined(__sgi)
+    return (sysinfo(SI_HOSTNAME, buf, sz) != -1);
+#else /* BSD Sockets */
+    char name[255];
+    struct hostent *h;
+    // Get hostname
+    if (gethostname(name, sizeof(name)/sizeof(char)-1) == -1)
+	return FALSE;
+    // Get official full name of host
+    strncpy(buf, (h=gethostbyname(name))!=NULL ? h->h_name : name, sz-1);
+    return TRUE;
+#endif
+}
+
+bool wxGetUserId(char *buf, int sz)
+{
+    struct passwd *who;
+
+    *buf = '\0';
+    if ((who = getpwuid(getuid ())) != NULL) {
+	strncpy (buf, who->pw_name, sz-1);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+bool wxGetUserName(char *buf, int sz)
+{
+    struct passwd *who;
+
+    *buf = '\0';
+    if ((who = getpwuid (getuid ())) != NULL) {
+	strncpy (buf, who->pw_gecos, sz - 1);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+//------------------------------------------------------------------------
+// error and debug output routines
+//------------------------------------------------------------------------
+
+void wxDebugMsg( const char *format, ... )
+{
+  va_list ap;
+  va_start( ap, format );
+  vfprintf( stderr, format, ap ); 
+  fflush( stderr );
+  va_end(ap);
+};
+
+void wxError( const wxString &msg, const wxString &title )
+{
+  fprintf( stderr, "Error " );
+  if (!title.IsNull()) fprintf( stderr, "%s ", WXSTRINGCAST(title) );
+  if (!msg.IsNull()) fprintf( stderr, ": %s", WXSTRINGCAST(msg) );
+  fprintf( stderr, ".\n" );
+};
+
+void wxFatalError( const wxString &msg, const wxString &title )
+{
+  fprintf( stderr, "Error " );
+  if (!title.IsNull()) fprintf( stderr, "%s ", WXSTRINGCAST(title) );
+  if (!msg.IsNull()) fprintf( stderr, ": %s", WXSTRINGCAST(msg) );
+  fprintf( stderr, ".\n" );
+  exit(1);
+};
+
+//------------------------------------------------------------------------
+// directory routines
+//------------------------------------------------------------------------
+
+bool wxDirExists( const wxString& dir )
+{
+  char buf[500];
+  strcpy( buf, WXSTRINGCAST(dir) );
+  struct stat sbuf;
+  return ((stat(buf, &sbuf) != -1) && S_ISDIR(sbuf.st_mode) ? TRUE : FALSE);
+};
+
+//------------------------------------------------------------------------
+// wild character routines
+//------------------------------------------------------------------------
+
+bool wxIsWild( const wxString& pattern )
+{
+  wxString tmp = pattern;
+  char *pat = WXSTRINGCAST(tmp);
+    while (*pat) {
+	switch (*pat++) {
+	case '?': case '*': case '[': case '{':
+	    return TRUE;
+	case '\\':
+	    if (!*pat++)
+		return FALSE;
+	}
+    }
+    return FALSE;
+};
+
+
+bool wxMatchWild( const wxString& pat, const wxString& text, bool dot_special )
+{
+  wxString tmp1 = pat;
+  char *pattern = WXSTRINGCAST(tmp1);
+  wxString tmp2 = text;
+  char *str = WXSTRINGCAST(tmp2);
+    char c;
+    char *cp;
+    bool done = FALSE, ret_code, ok;
+    // Below is for vi fans
+    const char OB = '{', CB = '}';
+
+    // dot_special means '.' only matches '.'
+    if (dot_special && *str == '.' && *pattern != *str)
+	return FALSE;
+
+    while ((*pattern != '\0') && (!done)
+    && (((*str=='\0')&&((*pattern==OB)||(*pattern=='*')))||(*str!='\0'))) {
+	switch (*pattern) {
+	case '\\':
+	    pattern++;
+	    if (*pattern != '\0')
+		pattern++;
+	    break;
+	case '*':
+	    pattern++;
+	    ret_code = FALSE;
+	    while ((*str!='\0')
+	    && (!(ret_code=wxMatchWild(pattern, str++, FALSE))))
+		/*loop*/;
+	    if (ret_code) {
+		while (*str != '\0')
+		    str++;
+		while (*pattern != '\0')
+		    pattern++;
+	    }
+	    break;
+	case '[':
+	    pattern++;
+	  repeat:
+	    if ((*pattern == '\0') || (*pattern == ']')) {
+		done = TRUE;
+		break;
+	    }
+	    if (*pattern == '\\') {
+		pattern++;
+		if (*pattern == '\0') {
+		    done = TRUE;
+		    break;
+		}
+	    }
+	    if (*(pattern + 1) == '-') {
+		c = *pattern;
+		pattern += 2;
+		if (*pattern == ']') {
+		    done = TRUE;
+		    break;
+		}
+		if (*pattern == '\\') {
+		    pattern++;
+		    if (*pattern == '\0') {
+			done = TRUE;
+			break;
+		    }
+		}
+		if ((*str < c) || (*str > *pattern)) {
+		    pattern++;
+		    goto repeat;
+		}
+	    } else if (*pattern != *str) {
+		pattern++;
+		goto repeat;
+	    }
+	    pattern++;
+	    while ((*pattern != ']') && (*pattern != '\0')) {
+		if ((*pattern == '\\') && (*(pattern + 1) != '\0'))
+		    pattern++;
+		pattern++;
+	    }
+	    if (*pattern != '\0') {
+		pattern++, str++;
+	    }
+	    break;
+	case '?':
+	    pattern++;
+	    str++;
+	    break;
+	case OB:
+	    pattern++;
+	    while ((*pattern != CB) && (*pattern != '\0')) {
+		cp = str;
+		ok = TRUE;
+		while (ok && (*cp != '\0') && (*pattern != '\0')
+		&&  (*pattern != ',') && (*pattern != CB)) {
+		    if (*pattern == '\\')
+			pattern++;
+		    ok = (*pattern++ == *cp++);
+		}
+		if (*pattern == '\0') {
+		    ok = FALSE;
+		    done = TRUE;
+		    break;
+		} else if (ok) {
+		    str = cp;
+		    while ((*pattern != CB) && (*pattern != '\0')) {
+			if (*++pattern == '\\') {
+			    if (*++pattern == CB)
+				pattern++;
+			}
+		    }
+		} else {
+		    while (*pattern!=CB && *pattern!=',' && *pattern!='\0') {
+			if (*++pattern == '\\') {
+                            if (*++pattern == CB || *pattern == ',')
+				pattern++;
+			}
+		    }
+		}
+		if (*pattern != '\0')
+		    pattern++;
+	    }
+	    break;
+	default:
+	    if (*str == *pattern) {
+		str++, pattern++;
+	    } else {
+		done = TRUE;
+	    }
+	}
+    }
+    while (*pattern == '*')
+	pattern++;
+    return ((*str == '\0') && (*pattern == '\0'));
+};
+
+//------------------------------------------------------------------------
+// subprocess routines
+//------------------------------------------------------------------------
+
+long wxExecute( char **argv, bool Async )
+{
+    if (*argv == NULL)
+	return FALSE;
+
+    /* fork the process */
+#if defined(sun) || defined(__ultrix) || defined(__bsdi__)
+    pid_t pid = vfork();
+#else
+    pid_t pid = fork();
+#endif
+    if (pid == -1) {
+	perror ("fork failed");
+	return FALSE;
+    } else if (pid == 0) {
+	/* child */
+#ifdef _AIX
+	execvp ((const char *)*argv, (const char **)argv);
+#else
+	execvp (*argv, argv);
+#endif
+	if (errno == ENOENT)
+	    wxError("command not found", *argv);
+	else
+	    perror (*argv);
+	wxError("could not execute", *argv);
+	_exit (-1);
+    }
+
+    // Code below is NOT really acceptable!
+    // One should NEVER use wait under X
+    // Ideas? A Sleep idle callback?
+    // WARNING: WARNING: WARNING: WARNING:
+    // The CODE BELOW IS BAD BAD BAD BAD!
+    if (Async) {
+	int status;
+/*
+	wxSleep(2);		// Give a little time
+*/
+#if !defined(DG) && \
+    !defined(__AIX__) && \
+    !defined(__xlC__) && \
+    !defined(__SVR4__) && \
+    !defined(__SUN__) && \
+    !defined(__ALPHA__) && \
+    !defined(__SGI__) && \
+    !defined(__HPUX__) && \
+    !defined(__SUNPRO_CC) && \
+    !defined(__FreeBSD__)
+        while (wait((union wait*)&status) != pid)
+#else
+	while (wait(&status) != pid)
+#endif
+      {};
+/*
+	    wxSleep(3);	// 3 sec?
+*/
+    };
+    return TRUE;
+};
+
+long wxExecute( const wxString& command, bool Async )
+{
+    if (command.IsNull() || command == "") return FALSE;
+
+    int argc = 0;
+    char *argv[127];
+    char tmp[1024];
+    const char *IFS = " \t\n";
+
+    strncpy (tmp, command, sizeof(tmp) / sizeof(char) - 1);
+    tmp[sizeof (tmp) / sizeof (char) - 1] = '\0';
+    argv[argc++] = strtok (tmp, IFS);
+    while ((argv[argc++] = strtok(NULL, IFS)) != NULL)
+	/* loop */ ;
+    return wxExecute(argv, Async);
+};
+
diff --git a/src/gtk/utilsres.cpp b/src/gtk/utilsres.cpp
new file mode 100644
index 0000000000..24e7904c26
--- /dev/null
+++ b/src/gtk/utilsres.cpp
@@ -0,0 +1,332 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        utils.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+//#ifdef __GNUG__
+//#pragma implementation "utils.h"
+//#endif
+
+#include "wx/utils.h"
+#include "wx/string.h"
+#include "wx/list.h"
+
+#include <ctype.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef __SVR4__
+#include <sys/systeminfo.h>
+#endif
+
+#include "gdk/gdkx.h"        // GDK_DISPLAY
+#include "gdk/gdkprivate.h"  // gdk_progclass
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xresource.h>
+
+
+//-----------------------------------------------------------------------------
+// constants
+//-----------------------------------------------------------------------------
+
+// Yuck this is really BOTH site and platform dependent
+// so we should use some other strategy!
+#ifdef __SUN__
+    #define DEFAULT_XRESOURCE_DIR "/usr/openwin/lib/app-defaults"
+#else
+    #define DEFAULT_XRESOURCE_DIR "/usr/lib/X11/app-defaults"
+#endif
+
+//-----------------------------------------------------------------------------
+// glabal data (data.cpp)
+//-----------------------------------------------------------------------------
+
+extern wxList wxResourceCache;
+extern XrmDatabase wxResourceDatabase;
+
+//-----------------------------------------------------------------------------
+// utility functions for get/write resources
+//-----------------------------------------------------------------------------
+
+static char *GetResourcePath(char *buf, char *name, bool create)
+{
+    if (create && FileExists(name)) {
+	strcpy(buf, name);
+	return buf; // Exists so ...
+    }
+    if (*name == '/')
+	strcpy(buf, name);
+    else {
+	// Put in standard place for resource files if not absolute
+	strcpy(buf, DEFAULT_XRESOURCE_DIR);
+	strcat(buf, "/");
+	strcat(buf, FileNameFromPath(name));
+    }
+    if (create) {
+	// Touch the file to create it
+	FILE *fd = fopen(buf, "w");
+	if (fd) fclose(fd);
+    }
+    return buf;
+}
+
+// Read $HOME for what it says is home, if not
+// read $USER or $LOGNAME for user name else determine
+// the Real User, then determine the Real home dir.
+static char *GetIniFile(char *dest, const char *filename)
+{
+    char *home = NULL;
+    if (filename && wxIsAbsolutePath(filename)) 
+    {
+      strcpy(dest, filename);
+    } 
+    else
+    {
+      if ((home = wxGetUserHome(wxString())) != NULL) 
+      {
+	strcpy(dest, home);
+	if (dest[strlen(dest) - 1] != '/') strcat(dest, "/");
+	if (filename == NULL) 
+	{
+	  if ((filename = getenv("XENVIRONMENT")) == NULL) filename = ".Xdefaults";
+	} 
+	else 
+	  if (*filename != '.') strcat(dest, ".");
+	strcat(dest, filename);
+      }
+      else 
+      {
+        dest[0] = '\0';    
+      }
+    }
+    return dest;
+}
+
+static void wxXMergeDatabases(void)
+{
+    XrmDatabase homeDB, serverDB, applicationDB;
+    char filenamebuf[1024];
+
+    char *filename = &filenamebuf[0];
+    char *environment;
+    char *classname = gdk_progclass;               // Robert Roebling ??
+    char name[256];
+    (void)strcpy(name, "/usr/lib/X11/app-defaults/");
+    (void)strcat(name, classname ? classname : "wxWindows");
+
+    // Get application defaults file, if any 
+    if ((applicationDB = XrmGetFileDatabase(name)))
+	(void)XrmMergeDatabases(applicationDB, &wxResourceDatabase);
+
+    // Merge server defaults, created by xrdb, loaded as a property of the root
+    // window when the server initializes and loaded into the display
+    // structure on XOpenDisplay;
+    // if not defined, use .Xdefaults
+    if (XResourceManagerString(GDK_DISPLAY()) != NULL) {
+	serverDB = XrmGetStringDatabase(XResourceManagerString(GDK_DISPLAY()));
+    } else {
+	(void)GetIniFile(filename, NULL);
+	serverDB = XrmGetFileDatabase(filename);
+    }
+    if (serverDB)
+	XrmMergeDatabases(serverDB, &wxResourceDatabase);
+
+    // Open XENVIRONMENT file, or if not defined, the .Xdefaults,
+    // and merge into existing database
+
+    if ((environment = getenv("XENVIRONMENT")) == NULL) {
+	size_t len;
+	environment = GetIniFile(filename, NULL);
+	len = strlen(environment);
+#if !defined(SVR4) || defined(__sgi)
+	(void)gethostname(environment + len, 1024 - len);
+#else
+	(void)sysinfo(SI_HOSTNAME, environment + len, 1024 - len);
+#endif
+    }
+    if ((homeDB = XrmGetFileDatabase(environment)))
+	XrmMergeDatabases(homeDB, &wxResourceDatabase);
+}
+
+//-----------------------------------------------------------------------------
+// called on application exit
+//-----------------------------------------------------------------------------
+
+void wxFlushResources(void)
+{
+    char nameBuffer[512];
+
+    wxNode *node = wxResourceCache.First();
+    while (node) {
+	char *file = node->key.string;
+	// If file doesn't exist, create it first.
+	(void)GetResourcePath(nameBuffer, file, TRUE);
+
+	XrmDatabase database = (XrmDatabase)node->Data();
+	XrmPutFileDatabase(database, nameBuffer);
+	XrmDestroyDatabase(database);
+	wxNode *next = node->Next();
+	delete node;
+	node = next;
+    }
+}
+
+void wxDeleteResources(const char *file)
+{
+    char buffer[500];
+    (void)GetIniFile(buffer, file);
+
+    wxNode *node = wxResourceCache.Find(buffer);
+    if (node) {
+	XrmDatabase database = (XrmDatabase)node->Data();
+	XrmDestroyDatabase(database);
+	delete node;
+    }
+}
+
+//-----------------------------------------------------------------------------
+// resource functions
+//-----------------------------------------------------------------------------
+
+bool wxWriteResource(const wxString& section, const wxString& entry, const wxString& value, const wxString& file )
+{
+    char buffer[500];
+
+    if (!entry) return FALSE;
+
+    (void)GetIniFile(buffer, file);
+
+    XrmDatabase database;
+    wxNode *node = wxResourceCache.Find(buffer);
+    if (node)
+	database = (XrmDatabase)node->Data();
+    else {
+	database = XrmGetFileDatabase(buffer);
+	wxResourceCache.Append(buffer, (wxObject *)database);
+    }
+    char resName[300];
+    strcpy(resName, !section.IsNull() ? WXSTRINGCAST section : "wxWindows");
+    strcat(resName, ".");
+    strcat(resName, entry);
+    XrmPutStringResource(&database, resName, value);
+    return TRUE;
+};
+
+bool wxWriteResource(const wxString& section, const wxString& entry, float value, const wxString& file )
+{
+    char buf[50];
+    sprintf(buf, "%.4f", value);
+    return wxWriteResource(section, entry, buf, file);
+};
+
+bool wxWriteResource(const wxString& section, const wxString& entry, long value, const wxString& file )
+{
+    char buf[50];
+    sprintf(buf, "%ld", value);
+    return wxWriteResource(section, entry, buf, file);
+};
+
+bool wxWriteResource(const wxString& section, const wxString& entry, int value, const wxString& file )
+{
+    char buf[50];
+    sprintf(buf, "%d", value);
+    return wxWriteResource(section, entry, buf, file);
+};
+
+bool wxGetResource(const wxString& section, const wxString& entry, char **value, const wxString& file )
+{
+    if (!wxResourceDatabase)
+	wxXMergeDatabases();
+
+    XrmDatabase database;
+    if (file) {
+	char buffer[500];
+	// Is this right? Trying to get it to look in the user's
+	// home directory instead of current directory -- JACS
+	(void)GetIniFile(buffer, file);
+
+	wxNode *node = wxResourceCache.Find(buffer);
+	if (node)
+	    database = (XrmDatabase)node->Data();
+	else {
+	    database = XrmGetFileDatabase(buffer);
+	    wxResourceCache.Append(buffer, (wxObject *)database);
+	}
+    } else
+	database = wxResourceDatabase;
+
+    XrmValue xvalue;
+    char *str_type[20];
+    char buf[150];
+    strcpy(buf, section);
+    strcat(buf, ".");
+    strcat(buf, entry);
+
+    bool success = XrmGetResource(database, buf, "*", str_type, &xvalue);
+    // Try different combinations of upper/lower case, just in case...
+    if (!success) {
+	buf[0] = (isupper(buf[0]) ? tolower(buf[0]) : toupper(buf[0]));
+	success = XrmGetResource(database, buf, "*", str_type,	&xvalue);
+    }
+    if (success) {
+	if (*value)
+	    delete[] *value;
+	*value = new char[xvalue.size + 1];
+	strncpy(*value, xvalue.addr, (int)xvalue.size);
+	return TRUE;
+    }
+    return FALSE;
+};
+
+bool wxGetResource(const wxString& section, const wxString& entry, float *value, const wxString& file )
+{
+    char *s = NULL;
+    bool succ = wxGetResource(section, entry, &s, file);
+    if (succ) {
+	*value = (float)strtod(s, NULL);
+	delete[]s;
+	return TRUE;
+    } else
+	return FALSE;
+};
+
+bool wxGetResource(const wxString& section, const wxString& entry, long *value, const wxString& file )
+{
+    char *s = NULL;
+    bool succ = wxGetResource(section, entry, &s, file);
+    if (succ) {
+	*value = strtol(s, NULL, 10);
+	delete[]s;
+	return TRUE;
+    } else
+	return FALSE;
+};
+
+bool wxGetResource(const wxString& section, const wxString& entry, int *value, const wxString& file )
+{
+    char *s = NULL;
+    bool succ = wxGetResource(section, entry, &s, file);
+    if (succ) {
+	// Handle True, False here 
+	// True, Yes, Enables, Set or  Activated 
+	if (*s == 'T' || *s == 'Y' || *s == 'E' || *s == 'S' || *s == 'A')
+	    *value = TRUE;
+	// False, No, Disabled, Reset, Cleared, Deactivated
+	else if (*s == 'F' || *s == 'N' || *s == 'D' || *s == 'R' || *s == 'C')
+	    *value = FALSE;
+	// Handle as Integer
+	else
+	    *value = (int)strtol(s, NULL, 10);
+	delete[]s;
+	return TRUE;
+    } else
+	return FALSE;
+};
+
diff --git a/src/gtk/verti.xbm b/src/gtk/verti.xbm
new file mode 100644
index 0000000000..2dd9dc4c05
--- /dev/null
+++ b/src/gtk/verti.xbm
@@ -0,0 +1,6 @@
+#define verti_width 15
+#define verti_height 15
+static char verti_bits[] = {
+   0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10,
+   0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10,
+   0x84, 0x10, 0x84, 0x10, 0x84, 0x10};
diff --git a/src/gtk/win_gtk.c b/src/gtk/win_gtk.c
new file mode 100644
index 0000000000..5f6245a891
--- /dev/null
+++ b/src/gtk/win_gtk.c
@@ -0,0 +1,512 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        wx_gtk.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#include "wx/gtk/win_gtk.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+static void gtk_myfixed_class_init    (GtkMyFixedClass    *klass);
+static void gtk_myfixed_init          (GtkMyFixed         *myfixed);
+static void gtk_myfixed_map           (GtkWidget        *widget);
+static void gtk_myfixed_unmap         (GtkWidget        *widget);
+static void gtk_myfixed_realize       (GtkWidget        *widget);
+static void gtk_myfixed_size_request  (GtkWidget        *widget,
+				     GtkRequisition   *requisition);
+static void gtk_myfixed_size_allocate (GtkWidget        *widget,
+				     GtkAllocation    *allocation);
+static void gtk_myfixed_paint         (GtkWidget        *widget,
+				     GdkRectangle     *area);
+static void gtk_myfixed_draw          (GtkWidget        *widget,
+				     GdkRectangle     *area);
+static gint gtk_myfixed_expose        (GtkWidget        *widget,
+				     GdkEventExpose   *event);
+static void gtk_myfixed_add           (GtkContainer     *container,
+				     GtkWidget        *widget);
+static void gtk_myfixed_remove        (GtkContainer     *container,
+				     GtkWidget        *widget);
+static void gtk_myfixed_foreach       (GtkContainer     *container,
+				     GtkCallback      callback,
+				     gpointer         callback_data);
+
+
+static GtkContainerClass *parent_class = NULL;
+
+
+guint
+gtk_myfixed_get_type ()
+{
+  static guint myfixed_type = 0;
+
+  if (!myfixed_type)
+    {
+      GtkTypeInfo myfixed_info =
+      {
+	"GtkMyFixed",
+	sizeof (GtkMyFixed),
+	sizeof (GtkMyFixedClass),
+	(GtkClassInitFunc) gtk_myfixed_class_init,
+	(GtkObjectInitFunc) gtk_myfixed_init,
+	(GtkArgSetFunc) NULL,
+        (GtkArgGetFunc) NULL,
+      };
+
+      myfixed_type = gtk_type_unique (gtk_container_get_type (), &myfixed_info);
+    }
+
+  return myfixed_type;
+}
+
+static void
+gtk_myfixed_class_init (GtkMyFixedClass *klass)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+  GtkContainerClass *container_class;
+
+  object_class = (GtkObjectClass*) klass;
+  widget_class = (GtkWidgetClass*) klass;
+  container_class = (GtkContainerClass*) klass;
+
+  parent_class = gtk_type_class (gtk_container_get_type ());
+
+  widget_class->map = gtk_myfixed_map;
+  widget_class->unmap = gtk_myfixed_unmap;
+  widget_class->realize = gtk_myfixed_realize;
+  widget_class->size_request = gtk_myfixed_size_request;
+  widget_class->size_allocate = gtk_myfixed_size_allocate;
+  widget_class->draw = gtk_myfixed_draw;
+  widget_class->expose_event = gtk_myfixed_expose;
+
+  container_class->add = gtk_myfixed_add;
+  container_class->remove = gtk_myfixed_remove;
+  container_class->foreach = gtk_myfixed_foreach;
+}
+
+static void
+gtk_myfixed_init (GtkMyFixed *myfixed)
+{
+  GTK_WIDGET_UNSET_FLAGS (myfixed, GTK_NO_WINDOW);
+  GTK_WIDGET_SET_FLAGS (myfixed, GTK_BASIC);
+  
+  myfixed->children = NULL;
+}
+
+GtkWidget*
+gtk_myfixed_new ()
+{
+  GtkMyFixed *myfixed;
+
+  myfixed = gtk_type_new (gtk_myfixed_get_type ());
+  
+  myfixed->scroll_offset_x = 0;
+  myfixed->scroll_offset_y = 0;
+  
+  return GTK_WIDGET (myfixed);
+}
+
+void       
+gtk_myfixed_set_offset (GtkMyFixed     *myfixed,
+                        gint16         x,
+			gint16         y)
+{
+  GtkWidget *widget;
+ 
+  g_return_if_fail (myfixed != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED (myfixed));
+  
+  myfixed->scroll_offset_x = x;
+  myfixed->scroll_offset_y = y;
+  
+  widget = GTK_WIDGET( myfixed );
+  
+  if (GTK_WIDGET_REALIZED( GTK_WIDGET(myfixed) ))
+    gdk_window_move_resize (widget->window,
+			    widget->allocation.x + x, 
+			    widget->allocation.y + y,
+                            32000, 
+			    32000);
+}
+
+void
+gtk_myfixed_put (GtkMyFixed       *myfixed,
+               GtkWidget      *widget,
+               gint16         x,
+               gint16         y)
+{
+  GtkMyFixedChild *child_info;
+
+  g_return_if_fail (myfixed != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED (myfixed));
+  g_return_if_fail (widget != NULL);
+
+  child_info = g_new (GtkMyFixedChild, 1);
+  child_info->widget = widget;
+  child_info->x = x;
+  child_info->y = y;
+
+  gtk_widget_set_parent (widget, GTK_WIDGET (myfixed));
+
+  myfixed->children = g_list_append (myfixed->children, child_info); 
+
+  if (GTK_WIDGET_REALIZED (myfixed) && !GTK_WIDGET_REALIZED (widget))
+    gtk_widget_realize (widget);
+
+  if (GTK_WIDGET_MAPPED (myfixed) && !GTK_WIDGET_MAPPED (widget))
+    gtk_widget_map (widget);
+
+  if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (myfixed))
+    gtk_widget_queue_resize (GTK_WIDGET (myfixed));
+}
+
+void
+gtk_myfixed_move (GtkMyFixed       *myfixed,
+                GtkWidget      *widget,
+                gint16         x,
+                gint16         y)
+{
+  GtkMyFixedChild *child;
+  GList *children;
+
+  g_return_if_fail (myfixed != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED (myfixed));
+  g_return_if_fail (widget != NULL);
+
+  children = myfixed->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (child->widget == widget)
+        {
+          child->x = x;
+          child->y = y;
+
+          if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (myfixed))
+            gtk_widget_queue_resize (GTK_WIDGET (myfixed));
+
+          break;
+        }
+    }
+}
+
+static void
+gtk_myfixed_map (GtkWidget *widget)
+{
+  GtkMyFixed *myfixed;
+  GtkMyFixedChild *child;
+  GList *children;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
+  myfixed = GTK_MYFIXED (widget);
+
+  gdk_window_show (widget->window);
+
+  children = myfixed->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child->widget) &&
+	  !GTK_WIDGET_MAPPED (child->widget))
+	gtk_widget_map (child->widget);
+    }
+}
+
+static void
+gtk_myfixed_unmap (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED (widget));
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
+}
+
+static void
+gtk_myfixed_realize (GtkWidget *widget)
+{
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.x = widget->allocation.x;
+  attributes.y = widget->allocation.y;
+  attributes.width = 32000;
+  attributes.height = 32000;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+  attributes.event_mask = gtk_widget_get_events (widget);
+  attributes.event_mask |= 
+  GDK_EXPOSURE_MASK	|
+  GDK_POINTER_MOTION_MASK	|
+  GDK_BUTTON_MOTION_MASK	|
+  GDK_BUTTON1_MOTION_MASK	|
+  GDK_BUTTON2_MOTION_MASK	|
+  GDK_BUTTON3_MOTION_MASK	|
+  GDK_BUTTON_PRESS_MASK		|
+  GDK_BUTTON_RELEASE_MASK	|
+  GDK_KEY_PRESS_MASK		|
+  GDK_KEY_RELEASE_MASK		|
+  GDK_ENTER_NOTIFY_MASK		|
+  GDK_LEAVE_NOTIFY_MASK		|
+  GDK_FOCUS_CHANGE_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);
+    
+  widget->style = gtk_style_attach (widget->style, widget->window);
+  gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
+}
+
+static void
+gtk_myfixed_size_request (GtkWidget      *widget,
+			GtkRequisition *requisition)
+{
+  GtkMyFixed *myfixed;
+  GtkMyFixedChild *child;
+  GList *children;
+  
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED (widget));
+  g_return_if_fail (requisition != NULL);
+
+  myfixed = GTK_MYFIXED (widget);
+  
+  requisition->width = 0;
+  requisition->height = 0;
+
+  children = myfixed->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child->widget))
+	{
+          gtk_widget_size_request (child->widget, &child->widget->requisition);
+	}
+    }
+}
+
+static void
+gtk_myfixed_size_allocate (GtkWidget     *widget,
+			 GtkAllocation *allocation)
+{
+  GtkMyFixed *myfixed;
+  GtkMyFixedChild *child;
+  GtkAllocation child_allocation;
+  GList *children;
+  guint16 border_width;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED(widget));
+  g_return_if_fail (allocation != NULL);
+
+  myfixed = GTK_MYFIXED (widget);
+
+  widget->allocation = *allocation;
+  if (GTK_WIDGET_REALIZED (widget))
+    gdk_window_move_resize (widget->window,
+			    allocation->x + myfixed->scroll_offset_x, 
+			    allocation->y + myfixed->scroll_offset_y,
+			    32000, 
+			    32000
+			    );
+
+  border_width = GTK_CONTAINER (myfixed)->border_width;
+  
+  children = myfixed->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+      
+      if (GTK_WIDGET_VISIBLE (child->widget))
+	{
+	  child_allocation.x = child->x + border_width;
+	  child_allocation.y = child->y + border_width;
+	  child_allocation.width = child->widget->requisition.width;
+	  child_allocation.height = child->widget->requisition.height;
+	  gtk_widget_size_allocate (child->widget, &child_allocation);
+	}
+    }
+}
+
+static void
+gtk_myfixed_paint (GtkWidget    *widget,
+		 GdkRectangle *area)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+      gdk_window_clear_area (widget->window,
+			     area->x, area->y,
+			     area->width, area->height);
+}
+
+static void
+gtk_myfixed_draw (GtkWidget    *widget,
+		GdkRectangle *area)
+{
+  GtkMyFixed *myfixed;
+  GtkMyFixedChild *child;
+  GdkRectangle child_area;
+  GList *children;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED (widget));
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      myfixed = GTK_MYFIXED (widget);
+      gtk_myfixed_paint (widget, area);
+
+      children = myfixed->children;
+      while (children)
+	{
+	  child = children->data;
+	  children = children->next;
+
+	  if (gtk_widget_intersect (child->widget, area, &child_area))
+	    gtk_widget_draw (child->widget, &child_area);
+	}
+    }
+}
+
+static gint
+gtk_myfixed_expose (GtkWidget      *widget,
+		  GdkEventExpose *event)
+{
+  GtkMyFixed *myfixed;
+  GtkMyFixedChild *child;
+  GdkEventExpose child_event;
+  GList *children;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_MYFIXED (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      myfixed = GTK_MYFIXED (widget);
+
+      child_event = *event;
+
+      children = myfixed->children;
+      while (children)
+	{
+	  child = children->data;
+	  children = children->next;
+
+	  if (GTK_WIDGET_NO_WINDOW (child->widget) &&
+	      gtk_widget_intersect (child->widget, &event->area, 
+				    &child_event.area))
+	    gtk_widget_event (child->widget, (GdkEvent*) &child_event);
+	}
+    }
+
+  return FALSE;
+}
+
+static void
+gtk_myfixed_add (GtkContainer *container,
+	       GtkWidget    *widget)
+{
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED (container));
+  g_return_if_fail (widget != NULL);
+
+  gtk_myfixed_put (GTK_MYFIXED (container), widget, 0, 0);
+}
+
+static void
+gtk_myfixed_remove (GtkContainer *container,
+		  GtkWidget    *widget)
+{
+  GtkMyFixed *myfixed;
+  GtkMyFixedChild *child;
+  GList *children;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED (container));
+  g_return_if_fail (widget != NULL);
+
+  myfixed = GTK_MYFIXED (container);
+
+  children = myfixed->children;
+  while (children)
+    {
+      child = children->data;
+
+      if (child->widget == widget)
+	{
+	  gtk_widget_unparent (widget);
+
+	  myfixed->children = g_list_remove_link (myfixed->children, children);
+	  g_list_free (children);
+	  g_free (child);
+
+	  if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
+	    gtk_widget_queue_resize (GTK_WIDGET (container));
+
+	  break;
+	}
+
+      children = children->next;
+    }
+}
+
+static void
+gtk_myfixed_foreach (GtkContainer *container,
+		   GtkCallback   callback,
+		   gpointer      callback_data)
+{
+  GtkMyFixed *myfixed;
+  GtkMyFixedChild *child;
+  GList *children;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED (container));
+  g_return_if_fail (callback != NULL);
+
+  myfixed = GTK_MYFIXED (container);
+
+  children = myfixed->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      (* callback) (child->widget, callback_data);
+    }
+}
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp
new file mode 100644
index 0000000000..1811e8892b
--- /dev/null
+++ b/src/gtk/window.cpp
@@ -0,0 +1,2386 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        window.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "window.h"
+#endif
+
+#include "wx/defs.h"
+#include "wx/window.h"
+#include "wx/dc.h"
+#include "wx/frame.h"
+#include "wx/app.h"
+#include "wx/layout.h"
+#include "wx/utils.h"
+#include "wx/dialog.h"
+#include "wx/msgdlg.h"
+#include "wx/dcclient.h"
+#include "wx/dnd.h"
+#include "wx/mdi.h"
+#include "gdk/gdkkeysyms.h"
+#include <math.h>
+#include "wx/gtk/win_gtk.h"
+#include "gdk/gdkprivate.h"
+
+//-----------------------------------------------------------------------------
+// data
+//-----------------------------------------------------------------------------
+
+extern wxList wxPendingDelete;
+extern wxList wxTopLevelWindows;
+extern bool   g_blockEventsOnDrag;
+
+//-----------------------------------------------------------------------------
+// GTK callbacks for wxWindows event system
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// expose (of m_wxwindow, not of m_widget)
+
+void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExpose *gdk_event, wxWindow *win )
+{ 
+  if (!win->HasVMT()) return;
+  if (g_blockEventsOnDrag) return;
+  
+/*
+  printf( "OnExpose from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+  
+  printf( "x: %d \n", gdk_event->area.x );
+  printf( "y: %d \n", gdk_event->area.y );
+  printf( "w: %d \n", gdk_event->area.width );
+  printf( "h: %d \n", gdk_event->area.height );
+*/
+
+  win->m_updateRegion.Union( gdk_event->area.x,
+                             gdk_event->area.y,
+			     gdk_event->area.width,
+			     gdk_event->area.height );
+			     
+  if (gdk_event->count > 0) return;
+
+  wxPaintEvent event( win->GetId() );
+  event.SetEventObject( win );
+  win->ProcessEvent( event );
+  
+  win->m_updateRegion.Clear();
+};
+
+//-----------------------------------------------------------------------------
+// draw (of m_wxwindow, not of m_widget)
+
+void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget), GdkRectangle *rect, wxWindow *win )
+{ 
+  if (!win->HasVMT()) return;
+  if (g_blockEventsOnDrag) return;
+  
+/*
+  printf( "OnDraw from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+  
+  printf( "x: %d \n", rect->x );
+  printf( "y: %d \n", rect->y );
+  printf( "w: %d \n", rect->width );
+  printf( "h: %d \n", rect->height );
+*/
+
+  win->m_updateRegion.Union( rect->x, rect->y, rect->width, rect->height );
+			     
+  wxPaintEvent event( win->GetId() );
+  event.SetEventObject( win );
+  win->ProcessEvent( event );
+  
+  win->m_updateRegion.Clear();
+};
+
+//-----------------------------------------------------------------------------
+// size 
+//      I don't any longer intercept GTK's internal resize events (except frames)
+
+/*
+void gtk_window_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxWindow *win )
+{ 
+  if (!win->HasVMT()) return;
+  if (g_blockEventsOnDrag) return;
+  
+  return;
+
+  if ((win->m_x == alloc->x) &&
+      (win->m_y == alloc->y) &&
+      (win->m_width == alloc->width) &&
+      (win->m_height == alloc->height))
+  {
+    return;
+  };
+  
+  printf( "OnResize from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( " .\n" );
+    
+  printf( "  Old: X: %d  Y: %d ", win->m_x, win->m_y );
+  printf( "  W: %d  H: %d ", win->m_width, win->m_height );
+  printf( " .\n" );
+    
+  printf( "  New: X: %d  Y: %d ", alloc->x, alloc->y );
+  printf( "  W: %d  H: %d ", alloc->width, alloc->height );
+  printf( " .\n" );
+  
+  wxSizeEvent event( wxSize( alloc->width, alloc->height), win->GetId() );
+  event.SetEventObject( win );
+  win->ProcessEvent( event );
+};
+*/
+
+//-----------------------------------------------------------------------------
+// key_press
+
+gint gtk_window_key_press_callback( GtkWidget *WXUNUSED(widget), GdkEventKey *gdk_event, wxWindow *win )
+{ 
+  if (!win->HasVMT()) return FALSE;
+  if (g_blockEventsOnDrag) return FALSE;
+
+/*
+  printf( "OnKeyPress from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+
+  long key_code = 0;
+  switch (gdk_event->keyval)
+  {
+    case GDK_BackSpace:   key_code = WXK_BACK;     	break;
+    case GDK_Tab:         key_code = WXK_TAB;     	break;
+    case GDK_Linefeed:    key_code = WXK_RETURN;  	break;
+    case GDK_Clear:	  key_code = WXK_CLEAR;   	break;
+    case GDK_Return:	  key_code = WXK_RETURN;  	break;
+    case GDK_Pause:	  key_code = WXK_PAUSE;   	break;
+    case GDK_Scroll_Lock: key_code = WXK_SCROLL; 	break;
+    case GDK_Escape:	  key_code = WXK_ESCAPE;  	break;
+    case GDK_Delete:	  key_code = WXK_DELETE;  	break;
+    case GDK_Home: 	  key_code = WXK_HOME;    	break;
+    case GDK_Left:	  key_code = WXK_LEFT;    	break;
+    case GDK_Up:	  key_code = WXK_UP;      	break;
+    case GDK_Right:	  key_code = WXK_RIGHT;   	break;
+    case GDK_Down:	  key_code = WXK_DOWN;    	break;
+    case GDK_Prior:	  key_code = WXK_PRIOR;   	break;
+//  case GDK_Page_Up:	  key_code = WXK_PAGEUP;  	break;
+    case GDK_Next:	  key_code = WXK_NEXT;    	break;
+//  case GDK_Page_Down:   key_code = WXK_PAGEDOWN; 	break;
+    case GDK_End:	  key_code = WXK_END;     	break;
+    case GDK_Begin:	  key_code = WXK_HOME;    	break;
+    case GDK_Select:	  key_code = WXK_SELECT;  	break;
+    case GDK_Print:	  key_code = WXK_PRINT;   	break;
+    case GDK_Execute:	  key_code = WXK_EXECUTE; 	break;
+    case GDK_Insert:	  key_code = WXK_INSERT;  	break;
+    case GDK_Num_Lock:	  key_code = WXK_NUMLOCK; 	break;
+    case GDK_KP_Tab:	  key_code = WXK_TAB;     	break;
+    case GDK_KP_Enter:	  key_code = WXK_RETURN;  	break;
+    case GDK_KP_Home:	  key_code = WXK_HOME;    	break;
+    case GDK_KP_Left:	  key_code = WXK_LEFT;    	break;
+    case GDK_KP_Up:	  key_code = WXK_UP;      	break;
+    case GDK_KP_Right: 	  key_code = WXK_RIGHT;   	break;
+    case GDK_KP_Down:	  key_code = WXK_DOWN;    	break;
+    case GDK_KP_Prior:	  key_code = WXK_PRIOR;   	break;
+//  case GDK_KP_Page_Up:  key_code = WXK_PAGEUP; 	break;
+    case GDK_KP_Next:	  key_code = WXK_NEXT;    	break;
+//  case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; 	break;
+    case GDK_KP_End:	  key_code = WXK_END;     	break;
+    case GDK_KP_Begin:	  key_code = WXK_HOME;    	break;
+    case GDK_KP_Insert:	  key_code = WXK_INSERT;  	break;
+    case GDK_KP_Delete:	  key_code = WXK_DELETE;  	break;
+    case GDK_KP_Multiply: key_code = WXK_MULTIPLY; 	break;
+    case GDK_KP_Add:	  key_code = WXK_ADD;     	break;
+    case GDK_KP_Separator: key_code = WXK_SEPARATOR; 	break;
+    case GDK_KP_Subtract: key_code = WXK_SUBTRACT; 	break;
+    case GDK_KP_Decimal:  key_code = WXK_DECIMAL; 	break;
+    case GDK_KP_Divide:	  key_code = WXK_DIVIDE;  	break;
+    case GDK_KP_0:	  key_code = WXK_NUMPAD0; 	break;
+    case GDK_KP_1:	  key_code = WXK_NUMPAD1; 	break;
+    case GDK_KP_2:	  key_code = WXK_NUMPAD2; 	break;
+    case GDK_KP_3:	  key_code = WXK_NUMPAD3; 	break;
+    case GDK_KP_4:	  key_code = WXK_NUMPAD4; 	break;
+    case GDK_KP_5:	  key_code = WXK_NUMPAD5; 	break;
+    case GDK_KP_6:	  key_code = WXK_NUMPAD6; 	break;
+    case GDK_KP_7:	  key_code = WXK_NUMPAD7; 	break;
+    case GDK_KP_8:	  key_code = WXK_NUMPAD7; 	break;
+    case GDK_KP_9:	  key_code = WXK_NUMPAD9; 	break;
+    case GDK_F1:	  key_code = WXK_F1;		break;
+    case GDK_F2:	  key_code = WXK_F2;		break;
+    case GDK_F3:	  key_code = WXK_F3;		break;
+    case GDK_F4:	  key_code = WXK_F4;		break;
+    case GDK_F5:	  key_code = WXK_F5;		break;
+    case GDK_F6:	  key_code = WXK_F6;		break;
+    case GDK_F7:	  key_code = WXK_F7;		break;
+    case GDK_F8:	  key_code = WXK_F8;		break;
+    case GDK_F9:	  key_code = WXK_F9;		break;
+    case GDK_F10:	  key_code = WXK_F10;		break;
+    case GDK_F11:	  key_code = WXK_F11;		break;
+    case GDK_F12:	  key_code = WXK_F12;		break;
+    default:
+    {
+      if ((gdk_event->keyval >= 0x20) && (gdk_event->keyval <= 0xFF)) 
+        key_code = gdk_event->keyval;
+    };
+  };
+
+  if (!key_code) return FALSE;
+  
+  wxKeyEvent event( wxEVT_CHAR );
+  event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
+  event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
+  event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
+  event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
+  event.m_keyCode = key_code;
+  event.m_x = 0;
+  event.m_y = 0;
+  event.SetEventObject( win );
+  return win->ProcessEvent( event );
+};
+
+//-----------------------------------------------------------------------------
+// button_press
+
+gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxWindow *win )
+{ 
+  if (widget->window != gdk_event->window) return FALSE;
+  if (g_blockEventsOnDrag) return FALSE;
+
+  if (win->m_wxwindow)
+  {
+    if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow) && !GTK_WIDGET_HAS_FOCUS (win->m_wxwindow) )
+    {
+      gtk_widget_grab_focus (win->m_wxwindow);
+      
+/*
+      printf( "GrabFocus from " );
+      if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+        printf( win->GetClassInfo()->GetClassName() );
+      printf( ".\n" );
+*/
+      
+    };
+  };
+    
+  if (!win->HasVMT()) return FALSE;
+    
+/*
+  printf( "OnButtonPress from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  WXTYPE event_type = wxEVT_LEFT_DOWN;
+  
+  if (gdk_event->button == 1)
+  {
+    switch (gdk_event->type)
+    {
+      case GDK_BUTTON_PRESS: event_type = wxEVT_LEFT_DOWN; break;
+      case GDK_2BUTTON_PRESS: event_type = wxEVT_LEFT_DCLICK; break;
+      default:  break;
+    };
+  }
+  else if (gdk_event->button == 2)
+  {
+    switch (gdk_event->type)
+    {
+      case GDK_BUTTON_PRESS: event_type = wxEVT_MIDDLE_DOWN; break;
+      case GDK_2BUTTON_PRESS: event_type = wxEVT_MIDDLE_DCLICK; break;
+      default:  break;
+    };
+  }
+  else if (gdk_event->button == 3)
+  {
+    switch (gdk_event->type)
+    {
+      case GDK_BUTTON_PRESS: event_type = wxEVT_RIGHT_DOWN; break;
+      case GDK_2BUTTON_PRESS: event_type = wxEVT_RIGHT_DCLICK; break;
+      default:  break;
+    };
+  };
+  
+  wxMouseEvent event( event_type );
+  event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
+  event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
+  event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
+  event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
+  event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK);
+  event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK);
+  event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK);
+  
+  event.m_x = (long)gdk_event->x;
+  event.m_y = (long)gdk_event->y;
+  event.SetEventObject( win );
+  
+  win->ProcessEvent( event );
+  
+  return TRUE;
+};
+
+//-----------------------------------------------------------------------------
+// button_release
+
+gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxWindow *win )
+{ 
+  if (widget->window != gdk_event->window) return TRUE;
+
+  if (g_blockEventsOnDrag) return FALSE;
+
+  if (!win->HasVMT()) return FALSE;
+ 
+/*
+  printf( "OnButtonRelease from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  WXTYPE event_type = 0;
+  
+  switch (gdk_event->button)
+  {
+    case 1: event_type = wxEVT_LEFT_UP; break;
+    case 2: event_type = wxEVT_MIDDLE_UP; break;
+    case 3: event_type = wxEVT_RIGHT_UP; break;
+  };
+
+  wxMouseEvent event( event_type );
+  event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
+  event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
+  event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
+  event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
+  event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK);
+  event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK);
+  event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK);
+  event.m_x = (long)gdk_event->x;
+  event.m_y = (long)gdk_event->y;
+  event.SetEventObject( win );
+  
+  return win->ProcessEvent( event );
+};
+
+//-----------------------------------------------------------------------------
+// motion_notify
+
+gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event, wxWindow *win )
+{ 
+  if (widget->window != gdk_event->window) return TRUE;
+
+  if (g_blockEventsOnDrag) return FALSE;
+
+  if (!win->HasVMT()) return FALSE;
+  
+/*
+  printf( "OnMotion from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  wxMouseEvent event( wxEVT_MOTION );
+  event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
+  event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
+  event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
+  event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
+  event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK);
+  event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK);
+  event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK);
+  
+  event.m_x = (long)gdk_event->x;
+  event.m_y = (long)gdk_event->y;
+  event.SetEventObject( win );
+  
+  win->ProcessEvent( event );
+  
+  return FALSE;
+};
+
+//-----------------------------------------------------------------------------
+// focus_in
+
+void gtk_window_focus_in_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxWindow *win )
+{
+  if (g_blockEventsOnDrag) return;
+  if (win->m_wxwindow)
+  {
+    if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow))
+    {
+      GTK_WIDGET_SET_FLAGS (win->m_wxwindow, GTK_HAS_FOCUS);
+/*      
+      printf( "SetFocus flag from " );
+      if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+        printf( win->GetClassInfo()->GetClassName() );
+      printf( ".\n" );
+*/
+    };
+  };
+  
+  if (!win->HasVMT()) return;
+  
+/*
+  printf( "OnSetFocus from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( "   " );
+  printf( WXSTRINGCAST win->GetLabel() );
+  printf( ".\n" );
+*/
+  
+  wxFocusEvent event( wxEVT_SET_FOCUS, win->GetId() );
+  event.SetEventObject( win );
+  win->ProcessEvent( event );
+};
+
+//-----------------------------------------------------------------------------
+// focus out
+
+void gtk_window_focus_out_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxWindow *win )
+{
+  if (g_blockEventsOnDrag) return;
+  if (win->m_wxwindow)
+  {
+    if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow))
+      GTK_WIDGET_UNSET_FLAGS (win->m_wxwindow, GTK_HAS_FOCUS);
+  };
+  
+  if (!win->HasVMT()) return;
+  
+/*
+  printf( "OnKillFocus from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  wxFocusEvent event( wxEVT_KILL_FOCUS, win->GetId() );
+  event.SetEventObject( win );
+  win->ProcessEvent( event );
+};
+
+//-----------------------------------------------------------------------------
+// vertical scroll
+
+void gtk_window_vscroll_callback( GtkWidget *WXUNUSED(widget), wxWindow *win )
+{
+  if (g_blockEventsOnDrag) return;
+
+/*
+  printf( "OnVScroll from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  if (!win->HasVMT()) return;
+  
+  float diff = win->m_vAdjust->value - win->m_oldVerticalPos;
+  if (fabs(diff) < 0.2) return;
+  
+/*
+  int i = (int)(win->m_oldVerticalPos+0.5);
+  printf( "Old value: %d.\n", i );
+  i = (int)(win->m_vAdjust->value+0.5);
+  printf( "Sending new value: %d.\n", i );
+*/
+
+  int command = 0;
+  
+  float line_step = win->m_vAdjust->step_increment;
+  float page_step = win->m_vAdjust->page_increment;
+  
+  if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN;
+  else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP;
+  else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN;
+  else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP;
+  else command = wxEVT_SCROLL_THUMBTRACK;
+      
+  int value = (int)(win->m_vAdjust->value+0.5);
+
+  wxScrollEvent event( command, win->GetId(), value, wxVERTICAL );
+  event.SetEventObject( win );
+  win->ProcessEvent( event );
+};
+
+//-----------------------------------------------------------------------------
+// horizontal scroll
+
+void gtk_window_hscroll_callback( GtkWidget *WXUNUSED(widget), wxWindow *win )
+{ 
+  if (g_blockEventsOnDrag) return;
+  
+/*
+  printf( "OnHScroll from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  if (!win->HasVMT()) return;
+    
+  float diff = win->m_hAdjust->value - win->m_oldHorizontalPos;
+  if (fabs(diff) < 0.2) return;
+  
+/*
+  int i = (int)(win->m_oldHorizontalPos+0.5);
+  printf( "Old value: %d.\n", i );
+  i = (int)(win->m_hAdjust->value+0.5);
+  printf( "Sending new value: %d.\n", i );
+*/
+      
+  int command = 0;
+  
+  float line_step = win->m_hAdjust->step_increment;
+  float page_step = win->m_hAdjust->page_increment;
+  
+  if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN;
+  else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP;
+  else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN;
+  else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP;
+  else command = wxEVT_SCROLL_THUMBTRACK;
+
+  int value = (int)(win->m_hAdjust->value+0.5);
+      
+  wxScrollEvent event( command, win->GetId(), value, wxHORIZONTAL );
+  event.SetEventObject( win );
+  win->ProcessEvent( event );
+};
+
+//-----------------------------------------------------------------------------
+// vertical scroll change
+
+void gtk_window_vscroll_change_callback( GtkWidget *WXUNUSED(widget), wxWindow *win )
+{
+  if (g_blockEventsOnDrag) return;
+
+/*
+  printf( "OnVScroll change from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  if (!win->HasVMT()) return;
+  
+  int command = wxEVT_SCROLL_THUMBTRACK;
+  int value = (int)(win->m_vAdjust->value+0.5);
+
+  wxScrollEvent event( command, win->GetId(), value, wxVERTICAL );
+  event.SetEventObject( win );
+  win->ProcessEvent( event );
+};
+
+//-----------------------------------------------------------------------------
+// horizontal scroll change
+
+void gtk_window_hscroll_change_callback( GtkWidget *WXUNUSED(widget), wxWindow *win )
+{ 
+  if (g_blockEventsOnDrag) return;
+  
+/*
+  printf( "OnHScroll change from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  if (!win->HasVMT()) return;
+    
+  int command = wxEVT_SCROLL_THUMBTRACK;
+  int value = (int)(win->m_hAdjust->value+0.5);
+      
+  wxScrollEvent event( command, win->GetId(), value, wxHORIZONTAL );
+  event.SetEventObject( win );
+  win->ProcessEvent( event );
+};
+
+//-----------------------------------------------------------------------------
+// drop
+
+void gtk_window_drop_callback( GtkWidget *widget, GdkEvent *event, wxWindow *win )
+{
+  printf( "OnDrop.\n" );
+
+  if (win->GetDropTarget())
+  {
+    int x = 0;
+    int y = 0;
+    gdk_window_get_pointer( widget->window, &x, &y, NULL );
+    win->GetDropTarget()->Drop( event, x, y );
+  };
+  
+/*
+  g_free (event->dropdataavailable.data);
+  g_free (event->dropdataavailable.data_type);
+*/
+}
+
+//-----------------------------------------------------------------------------
+// destroy
+
+bool gtk_window_destroy_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxWindow *win )
+{ 
+  printf( "OnDestroy from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+  printf( "Goodbye.\n" );
+  printf( "     Robert Roebling.\n" );
+  
+  return FALSE;
+};
+
+//-----------------------------------------------------------------------------
+// enter
+
+bool gtk_window_enter_callback( GtkWidget *widget, GdkEvent *WXUNUSED(event), wxWindow *win )
+{
+  if (g_blockEventsOnDrag) return FALSE;
+  
+  if (widget->window)
+    gdk_window_set_cursor( widget->window, win->m_cursor->GetCursor() );
+    
+  return TRUE;
+};
+    
+//-----------------------------------------------------------------------------
+// leave
+
+bool gtk_window_leave_callback( GtkWidget *widget, GdkEvent *WXUNUSED(event), wxWindow *WXUNUSED(win) )
+{
+  if (g_blockEventsOnDrag) return FALSE;
+  
+  if (widget->window)
+    gdk_window_set_cursor( widget->window, wxSTANDARD_CURSOR->GetCursor() );
+    
+  return TRUE;
+};
+    
+//-----------------------------------------------------------------------------
+// wxWindow implementation
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxWindow,wxEvtHandler)
+
+BEGIN_EVENT_TABLE(wxWindow, wxEvtHandler)
+//  EVT_CHAR(wxWindow::OnChar)
+  EVT_SIZE(wxWindow::OnSize)
+//  EVT_ERASE_BACKGROUND(wxWindow::OnEraseBackground)
+  EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged)
+  EVT_INIT_DIALOG(wxWindow::OnInitDialog)
+//  EVT_IDLE(wxWindow::OnIdle)
+END_EVENT_TABLE()
+
+wxWindow::wxWindow()
+{
+  m_widget = NULL;
+  m_wxwindow = NULL;
+  m_parent = NULL;
+  m_children.DeleteContents( FALSE );
+  m_x = 0;
+  m_y = 0;
+  m_width = 0;
+  m_height = 0;
+  m_retCode = 0;
+  m_eventHandler = this;
+  m_windowValidator = NULL;
+  m_windowId = -1;
+  m_cursor = new wxCursor( wxCURSOR_ARROW );
+  m_font = *wxSWISS_FONT;
+  m_windowStyle = 0;
+  m_windowName = "noname";
+  m_constraints = NULL;
+  m_constraintsInvolvedIn = NULL;
+  m_windowSizer = NULL;
+  m_sizerParent = NULL;
+  m_autoLayout = FALSE;
+  m_sizeSet = FALSE;
+  m_hasVMT = FALSE;
+  m_needParent = TRUE;
+  m_hasScrolling = FALSE;
+  m_hAdjust = NULL;
+  m_vAdjust = NULL;
+  m_oldHorizontalPos = 0.0;
+  m_oldVerticalPos = 0.0;
+  m_isShown = FALSE;
+  m_isEnabled = TRUE;
+  m_drawingOffsetX = 0;
+  m_drawingOffsetY = 0;
+  m_pDropTarget = NULL;
+};
+
+wxWindow::wxWindow( wxWindow *parent, const wxWindowID id,
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  Create( parent, id, pos, size, style, name );
+};
+
+bool wxWindow::Create( wxWindow *parent, const wxWindowID id,
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  m_isShown = FALSE;
+  m_isEnabled = TRUE;
+  m_needParent = TRUE;
+  
+  PreCreation( parent, id, pos, size, style, name );
+  
+  m_widget = gtk_scrolled_window_new( NULL, NULL );
+  m_hasScrolling = TRUE;
+  
+  GtkScrolledWindow *s_window;
+  s_window = GTK_SCROLLED_WINDOW(m_widget);
+  
+  GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
+  scroll_class->scrollbar_spacing = 0;
+  
+  gtk_scrolled_window_set_policy( s_window, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
+    
+  m_oldHorizontalPos = 0.0;
+  m_oldVerticalPos = 0.0;
+ 
+  m_hAdjust = gtk_range_get_adjustment( GTK_RANGE(s_window->hscrollbar) );
+  m_vAdjust = gtk_range_get_adjustment( GTK_RANGE(s_window->vscrollbar) );
+  
+  gtk_signal_connect (GTK_OBJECT (m_hAdjust), "value_changed",
+		      (GtkSignalFunc) gtk_window_hscroll_callback, (gpointer) this );
+  gtk_signal_connect (GTK_OBJECT (m_vAdjust), "value_changed",
+		      (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this );
+		      
+  gtk_signal_connect (GTK_OBJECT (m_hAdjust), "changed",
+		      (GtkSignalFunc) gtk_window_hscroll_change_callback, (gpointer) this );
+  gtk_signal_connect (GTK_OBJECT (m_vAdjust), "changed",
+		      (GtkSignalFunc) gtk_window_vscroll_change_callback, (gpointer) this );
+  
+  GtkViewport *viewport;
+  viewport = GTK_VIEWPORT(s_window->viewport);
+  
+  if (m_windowStyle & wxRAISED_BORDER)
+  {
+    gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_OUT );
+  }
+  else if (m_windowStyle & wxSUNKEN_BORDER)
+  {
+    gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_IN );
+  }
+  else
+  {
+    gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_NONE );
+  };
+    
+  m_wxwindow = gtk_myfixed_new();
+  
+  if (m_windowStyle & wxTAB_TRAVERSAL == wxTAB_TRAVERSAL)
+    GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
+  else
+    GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
+
+  gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow );
+
+  // shut the viewport up
+  gtk_viewport_set_hadjustment( viewport, (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
+  gtk_viewport_set_vadjustment( viewport, (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
+  
+  // I _really_ don't want scrollbars in the beginning    
+  m_vAdjust->lower = 0.0;
+  m_vAdjust->upper = 1.0;
+  m_vAdjust->value = 0.0;
+  m_vAdjust->step_increment = 1.0;
+  m_vAdjust->page_increment = 1.0;
+  m_vAdjust->page_size = 5.0;
+  gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" );
+  m_hAdjust->lower = 0.0;
+  m_hAdjust->upper = 1.0;
+  m_hAdjust->value = 0.0;
+  m_hAdjust->step_increment = 1.0;
+  m_hAdjust->page_increment = 1.0;
+  m_hAdjust->page_size = 5.0;
+  gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" );
+  
+  gtk_widget_show( m_wxwindow );
+  
+  PostCreation();
+  
+  Show( TRUE );
+
+  return TRUE;  
+};
+
+wxWindow::~wxWindow(void)
+{
+  m_hasVMT = FALSE;
+  
+  if (m_pDropTarget) delete m_pDropTarget;
+  
+  if (m_parent) m_parent->RemoveChild( this );
+  if (m_widget) Show( FALSE );
+
+  DestroyChildren();
+  
+  if (m_wxwindow) gtk_widget_destroy( m_wxwindow );
+    
+  if (m_widget) gtk_widget_destroy( m_widget );
+  
+//  delete m_cursor;
+
+  DeleteRelatedConstraints();
+  if (m_constraints)
+  {
+    // This removes any dangling pointers to this window
+    // in other windows' constraintsInvolvedIn lists.
+    UnsetConstraints(m_constraints);
+    delete m_constraints;
+    m_constraints = NULL;
+  }
+  if (m_windowSizer)
+  {
+    delete m_windowSizer;
+    m_windowSizer = NULL;
+  }
+  // If this is a child of a sizer, remove self from parent
+  if (m_sizerParent)
+    m_sizerParent->RemoveChild((wxWindow *)this);
+
+  // Just in case the window has been Closed, but
+  // we're then deleting immediately: don't leave
+  // dangling pointers.
+  wxPendingDelete.DeleteObject(this);
+
+  // Just in case we've loaded a top-level window via
+  // wxWindow::LoadNativeDialog but we weren't a dialog
+  // class
+  wxTopLevelWindows.DeleteObject(this);
+    
+};
+
+void wxWindow::PreCreation( wxWindow *parent, const wxWindowID id,
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  if (m_needParent && (parent == NULL))
+    wxFatalError( "Need complete parent.", name );
+
+  m_widget = NULL;
+  m_hasVMT = FALSE;
+  m_parent = parent;
+  m_children.DeleteContents( FALSE );
+  m_x = (int)pos.x;
+  m_y = (int)pos.y;
+  m_width = size.x;
+  if (m_width == -1) m_width = 20;
+  m_height = size.y;
+  if (m_height == -1) m_height = 20;
+  m_retCode = 0;
+  m_eventHandler = this;
+  m_windowValidator = NULL;
+  m_windowId = id;
+  m_sizeSet = FALSE;
+  m_cursor = new wxCursor( wxCURSOR_ARROW );
+  m_font = *wxSWISS_FONT;
+  m_backgroundColour = wxWHITE;
+  m_foregroundColour = wxBLACK;
+  m_windowStyle = style;
+  m_windowName = name;
+  m_constraints = NULL;
+  m_constraintsInvolvedIn = NULL;
+  m_windowSizer = NULL;
+  m_sizerParent = NULL;
+  m_autoLayout = FALSE;
+  m_drawingOffsetX = 0;
+  m_drawingOffsetY = 0;
+  m_pDropTarget = NULL;
+}
+
+void wxWindow::PostCreation(void)
+{
+  if (m_parent) m_parent->AddChild( this );
+  
+//  GtkStyle *style = m_widget->style;
+//  style->font = m_font.GetInternalFont( 1.0 );          // destroy old font ?
+  
+  GtkWidget *connect_widget = m_widget;
+  if (m_wxwindow) connect_widget = m_wxwindow;
+ 
+  gtk_object_set_data (GTK_OBJECT (connect_widget), "MyWxWindow", (gpointer)this );
+  
+  if (m_wxwindow)
+  {
+    gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event", 
+      GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this );
+      
+    gtk_signal_connect( GTK_OBJECT(m_wxwindow), "draw", 
+      GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this );
+  };
+  
+/*
+  gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate", 
+    GTK_SIGNAL_FUNC(gtk_window_size_callback), (gpointer)this );
+*/
+
+  gtk_signal_connect( GTK_OBJECT(connect_widget), "key_press_event",
+    GTK_SIGNAL_FUNC(gtk_window_key_press_callback), (gpointer)this );
+
+  gtk_signal_connect( GTK_OBJECT(connect_widget), "button_press_event",
+    GTK_SIGNAL_FUNC(gtk_window_button_press_callback), (gpointer)this );
+    
+  gtk_signal_connect( GTK_OBJECT(connect_widget), "button_release_event",
+    GTK_SIGNAL_FUNC(gtk_window_button_release_callback), (gpointer)this );
+    
+  gtk_signal_connect( GTK_OBJECT(connect_widget), "motion_notify_event",
+    GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback), (gpointer)this );
+    
+  gtk_signal_connect( GTK_OBJECT(connect_widget), "focus_in_event", 
+    GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this );
+
+  gtk_signal_connect( GTK_OBJECT(connect_widget), "focus_out_event", 
+    GTK_SIGNAL_FUNC(gtk_window_focus_out_callback), (gpointer)this );
+
+  gtk_signal_connect( GTK_OBJECT(connect_widget), "drop_data_available_event",
+    GTK_SIGNAL_FUNC(gtk_window_drop_callback), (gpointer)this );
+      
+  // Only for cursor handling
+    
+  gtk_signal_connect( GTK_OBJECT(m_widget), "enter_notify_event", 
+    GTK_SIGNAL_FUNC(gtk_window_enter_callback), (gpointer)this );
+    
+  gtk_signal_connect( GTK_OBJECT(m_widget), "leave_notify_event", 
+    GTK_SIGNAL_FUNC(gtk_window_leave_callback), (gpointer)this );
+    
+  if (m_wxwindow)
+  {
+    gtk_signal_connect( GTK_OBJECT(m_wxwindow), "enter_notify_event", 
+      GTK_SIGNAL_FUNC(gtk_window_enter_callback), (gpointer)this );
+      
+    gtk_signal_connect( GTK_OBJECT(m_wxwindow), "leave_notify_event", 
+      GTK_SIGNAL_FUNC(gtk_window_leave_callback), (gpointer)this );
+  };
+  
+/*
+  // Does destroy ever get called ?
+
+  gtk_signal_connect( GTK_OBJECT(m_widget), "destroy_event", 
+    GTK_SIGNAL_FUNC(gtk_window_destroy_callback), (gpointer)this );
+    
+  if (m_wxwindow)
+  {
+    gtk_signal_connect( GTK_OBJECT(m_wxwindow), "destroy_event", 
+      GTK_SIGNAL_FUNC(gtk_window_destroy_callback), (gpointer)this );
+  };
+*/
+  
+  if (m_widget && m_parent) gtk_widget_realize( m_widget );
+  if (m_wxwindow) gtk_widget_realize( m_wxwindow );
+  
+  SetCursor( wxSTANDARD_CURSOR );
+  
+  m_hasVMT = TRUE;
+};
+
+bool wxWindow::HasVMT(void)
+{
+  return m_hasVMT;
+};
+
+bool wxWindow::Close( const bool force )
+{
+  wxCloseEvent event(wxEVT_CLOSE_WINDOW, m_windowId);
+  event.SetEventObject(this);
+  event.SetForce(force);
+
+  return GetEventHandler()->ProcessEvent(event);
+};
+
+bool wxWindow::Destroy(void)
+{
+  m_hasVMT = FALSE;
+  delete this;
+  return TRUE;
+};
+
+bool wxWindow::DestroyChildren(void)
+{
+  if (GetChildren()) 
+  {
+    wxNode *node;
+    while ((node = GetChildren()->First()) != (wxNode *)NULL) 
+    {
+      wxWindow *child;
+      if ((child = (wxWindow *)node->Data()) != (wxWindow *)NULL) 
+      {
+        delete child;
+	if (GetChildren()->Member(child)) delete node;
+      };
+    };
+  };
+  return TRUE;
+};
+
+void wxWindow::PrepareDC( wxDC &WXUNUSED(dc) )
+{
+  // are we to set fonts here ?
+};
+
+void wxWindow::ImplementSetSize(void)
+{ 
+  gtk_widget_set_usize( m_widget, m_width, m_height );
+};
+
+void wxWindow::ImplementSetPosition(void)
+{
+  if ((m_parent) && (m_parent->m_wxwindow))
+    gtk_myfixed_move( GTK_MYFIXED(m_parent->m_wxwindow), m_widget, m_x, m_y );
+  else
+    gtk_widget_set_uposition( m_widget, m_x, m_y );
+};
+
+void wxWindow::SetSize( const int x, const int y, const int width, const int height, const int sizeFlags )
+{
+  int newX = x;
+  int newY = y;
+  int newW = width;
+  int newH = height;
+  
+  if ((sizeFlags & wxSIZE_USE_EXISTING) == wxSIZE_USE_EXISTING)
+  {
+    if (newX == -1) newX = m_x;
+    if (newY == -1) newY = m_y;
+    if (newW == -1) newW = m_width;
+    if (newH == -1) newH = m_height;
+  };
+  
+  if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
+  {
+    if (newW == -1) newW = 80;
+  };
+  
+  if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
+  {
+    if (newH == -1) newH = 26;
+  };
+  
+  if ((m_x != newX) || (m_y != newY) || (!m_sizeSet))
+  {
+    m_x = newX;
+    m_y = newY;
+    ImplementSetPosition();
+  };
+  if ((m_width != newW) || (m_height != newH) || (!m_sizeSet))
+  {
+    m_width = newW;
+    m_height = newH;
+    ImplementSetSize();
+  };
+  m_sizeSet = TRUE;
+  
+  wxSizeEvent event( wxSize(m_width,m_height), GetId() );
+  event.SetEventObject( this );
+  ProcessEvent( event );
+};
+
+void wxWindow::SetSize( const int width, const int height )
+{
+  SetSize( -1, -1, width, height, wxSIZE_USE_EXISTING );
+};
+
+void wxWindow::Move( const int x, const int y )
+{
+  SetSize( x, y, -1, -1, wxSIZE_USE_EXISTING );
+};
+
+void wxWindow::GetSize( int *width, int *height ) const
+{
+  (*width) = m_width;
+  (*height) = m_height;
+};
+
+void wxWindow::SetClientSize( const int width, const int height )
+{
+  if (!m_wxwindow)
+  {
+    SetSize( width, height );
+  }
+  else
+  {
+    int dw = 0;
+    int dh = 0;
+    
+    if (!m_hasScrolling)
+    {
+/*
+      do we have sunken dialogs ?
+      
+      GtkStyleClass *window_class = m_wxwindow->style->klass;
+    
+      dw += 2 * window_class->xthickness;
+      dh += 2 * window_class->ythickness;
+*/
+    }
+    else
+    {
+      GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
+      GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
+    
+      GtkWidget *viewport = scroll_window->viewport;
+      GtkStyleClass *viewport_class = viewport->style->klass;
+    
+      GtkWidget *hscrollbar = scroll_window->hscrollbar;
+      GtkWidget *vscrollbar = scroll_window->vscrollbar;
+    
+      if ((m_windowStyle & wxRAISED_BORDER) ||
+          (m_windowStyle & wxSUNKEN_BORDER)
+	 )
+      {
+        dw += 2 * viewport_class->xthickness;
+        dh += 2 * viewport_class->ythickness;
+      };
+    
+      if (GTK_WIDGET_VISIBLE(vscrollbar))
+      {
+        dw += vscrollbar->allocation.width;
+        dw += scroll_class->scrollbar_spacing;
+      };
+    
+      if (GTK_WIDGET_VISIBLE(hscrollbar))
+      {
+        dh += hscrollbar->allocation.height;
+        dw += scroll_class->scrollbar_spacing;
+      };
+    };
+    
+    SetSize( width+dw, height+dh );
+  };
+};
+
+void wxWindow::GetClientSize( int *width, int *height ) const
+{
+  if (!m_wxwindow)
+  {
+    if (width) (*width) = m_width;
+    if (height) (*height) = m_height;
+  }
+  else
+  {
+    int dw = 0;
+    int dh = 0;
+    
+    if (!m_hasScrolling)
+    {
+/*
+      do we have sunken dialogs ?
+      
+      GtkStyleClass *window_class = m_wxwindow->style->klass;
+    
+      dw += 2 * window_class->xthickness;
+      dh += 2 * window_class->ythickness;
+*/
+    }
+    else
+    {
+      GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
+      GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
+    
+      GtkWidget *viewport = scroll_window->viewport;
+      GtkStyleClass *viewport_class = viewport->style->klass;
+    
+      GtkWidget *hscrollbar = scroll_window->hscrollbar;
+      GtkWidget *vscrollbar = scroll_window->vscrollbar;
+    
+      if ((m_windowStyle & wxRAISED_BORDER) ||
+          (m_windowStyle & wxSUNKEN_BORDER)
+	 )
+      {
+        dw += 2 * viewport_class->xthickness;
+        dh += 2 * viewport_class->ythickness;
+      };
+    
+      if (GTK_WIDGET_VISIBLE(vscrollbar))
+      {
+//        dw += vscrollbar->allocation.width;
+        dw += 15;                               // range.slider_width = 11 + 2*2pts edge
+        dw += scroll_class->scrollbar_spacing;
+      };
+    
+      if (GTK_WIDGET_VISIBLE(hscrollbar))
+      {
+//        dh += hscrollbar->allocation.height;
+        dh += 15;
+        dh += scroll_class->scrollbar_spacing;
+      };
+    };
+    
+    if (width) (*width) = m_width - dw;
+    if (height) (*height) = m_height - dh;
+  };
+};
+
+void wxWindow::GetPosition( int *x, int *y ) const
+{
+  if (x) (*x) = m_x;
+  if (y) (*y) = m_y;
+};
+
+void wxWindow::ClientToScreen( int *x, int *y )
+{
+  // Does this look simple ?
+
+  GdkWindow *source = NULL;
+  if (m_wxwindow)
+    source = m_wxwindow->window;
+  else
+    source = m_widget->window;
+    
+  int org_x = 0;
+  int org_y = 0;
+  gdk_window_get_origin( source, &org_x, &org_y );
+
+  if (!m_wxwindow)
+  {  
+    if (GTK_WIDGET_NO_WINDOW (m_widget))
+    {
+      org_x += m_widget->allocation.x;
+      org_y += m_widget->allocation.y;
+    };
+  };
+  
+  if (x) *x += org_x;  
+  if (y) *y += org_y;  
+};
+
+void wxWindow::ScreenToClient( int *x, int *y )
+{
+  GdkWindow *source = NULL;
+  if (m_wxwindow)
+    source = m_wxwindow->window;
+  else
+    source = m_widget->window;
+    
+  int org_x = 0;
+  int org_y = 0;
+  gdk_window_get_origin( source, &org_x, &org_y );
+
+  if (!m_wxwindow)
+  {  
+    if (GTK_WIDGET_NO_WINDOW (m_widget))
+    {
+      org_x += m_widget->allocation.x;
+      org_y += m_widget->allocation.y;
+    };
+  };
+  
+  if (x) *x -= org_x;  
+  if (y) *y -= org_y;  
+};
+
+void wxWindow::Centre( const int direction )
+{
+  int x = 0;
+  int y = 0;
+  GetPosition( &x, &y );
+  if (this->IsKindOf(CLASSINFO(wxDialog)) || this->IsKindOf(CLASSINFO(wxFrame)))
+  {
+    if (direction & wxHORIZONTAL == wxHORIZONTAL) x = (gdk_screen_width () - m_width) / 2;
+    if (direction & wxVERTICAL == wxVERTICAL) y = (gdk_screen_height () - m_height) / 2;
+    gtk_widget_set_uposition( m_widget, x, y );
+  }
+  else
+  {
+    if (m_parent)
+    {
+      int p_w = 0;
+      int p_h = 0;
+      m_parent->GetSize( &p_w, &p_h );
+      if (direction & wxHORIZONTAL == wxHORIZONTAL) x = (p_w - m_width) / 2;
+      if (direction & wxVERTICAL == wxVERTICAL) y = (p_h - m_height) / 2;
+      gtk_widget_set_uposition( m_widget, x, y );
+    };
+  }
+};
+
+void wxWindow::Fit(void)
+{
+	int maxX = 0;
+	int maxY = 0;
+	wxNode *node = GetChildren()->First();
+	while ( node )
+	{
+		wxWindow *win = (wxWindow *)node->Data();
+		int wx, wy, ww, wh;
+		win->GetPosition(&wx, &wy);
+		win->GetSize(&ww, &wh);
+		if ( wx + ww > maxX )
+			maxX = wx + ww;
+		if ( wy + wh > maxY )
+			maxY = wy + wh;
+
+		node = node->Next();
+	}
+	SetClientSize(maxX + 5, maxY + 5);
+};
+
+void wxWindow::OnSize( wxSizeEvent &WXUNUSED(event) )
+{
+  if (GetAutoLayout()) Layout();
+};
+
+bool wxWindow::Show( const bool show )
+{
+  if (show)
+    gtk_widget_show( m_widget );
+  else
+    gtk_widget_hide( m_widget );
+  m_isShown = show;  
+  return TRUE;
+};
+
+void wxWindow::Enable( const bool enable )
+{
+  m_isEnabled = enable;
+  gtk_widget_set_sensitive( m_widget, enable );
+  if (m_wxwindow) gtk_widget_set_sensitive( m_wxwindow, enable );
+};
+
+void wxWindow::MakeModal( const bool modal )
+{
+  return;
+  // Disable all other windows
+  if (this->IsKindOf(CLASSINFO(wxDialog)) || this->IsKindOf(CLASSINFO(wxFrame)))
+  {
+    wxNode *node = wxTopLevelWindows.First();
+    while (node)
+    {
+      wxWindow *win = (wxWindow *)node->Data();
+      if (win != this)
+        win->Enable(!modal);
+
+      node = node->Next();
+    }
+  }
+}
+
+void wxWindow::SetFocus(void)
+{
+  GtkWidget *connect_widget = m_widget;
+  if (m_wxwindow) connect_widget = m_wxwindow;
+  if (connect_widget)
+  {
+    if (GTK_WIDGET_CAN_FOCUS(connect_widget) && !GTK_WIDGET_HAS_FOCUS (connect_widget) )
+    {
+      gtk_widget_grab_focus (connect_widget);
+    };
+  };
+};
+
+bool wxWindow::OnClose(void)
+{
+  printf( "OnClose event.\n" );
+  return TRUE;
+};
+
+void wxWindow::AddChild( wxWindow *child )
+{
+  // Addchild is (often) called before the program
+  // has left the parents constructor so that no
+  // virtual tables work yet. The approach below
+  // practically imitates virtual tables, i.e. it
+  // implements a different AddChild() behaviour
+  // for wxFrame, wxDialog, wxWindow and 
+  // wxMDIParentFrame.
+
+  if (IsKindOf(CLASSINFO(wxMDIParentFrame)))
+  {
+    if (child->IsKindOf(CLASSINFO(wxMDIChildFrame)))
+    {
+      wxMDIClientWindow *client = ((wxMDIParentFrame*)this)->GetClientWindow();
+      if (client)
+      { 
+        client->AddChild( child );
+        return;
+      };
+    };
+  };
+  m_children.Append( child );
+  if (child->IsKindOf(CLASSINFO(wxFrame)) || child->IsKindOf(CLASSINFO(wxDialog)))
+  {
+    if ((child->m_x != -1) && (child->m_y != -1))
+      gtk_widget_set_uposition( child->m_widget, child->m_x, child->m_y );
+  }
+  else
+  {
+    if (m_wxwindow)
+      gtk_myfixed_put( GTK_MYFIXED(m_wxwindow), child->m_widget, child->m_x, child->m_y );
+  };
+  gtk_widget_set_usize( child->m_widget, child->m_width, child->m_height );
+};
+
+wxList *wxWindow::GetChildren(void)
+{
+  return (&m_children);
+};
+
+void wxWindow::RemoveChild( wxWindow *child )
+{
+  if (GetChildren())
+ GetChildren()->DeleteObject( child );
+  child->m_parent = NULL;
+};
+
+void wxWindow::SetReturnCode( int retCode )
+{
+  m_retCode = retCode;
+};
+
+int wxWindow::GetReturnCode(void)
+{
+  return m_retCode;
+};
+
+wxWindow *wxWindow::GetParent(void)
+{
+  return m_parent;
+};
+
+wxEvtHandler *wxWindow::GetEventHandler(void)
+{
+  return m_eventHandler;
+};
+
+void wxWindow::SetEventhandler( wxEvtHandler *handler )
+{
+  m_eventHandler = handler;
+};
+
+wxValidator *wxWindow::GetValidator(void)
+{
+  return m_windowValidator;
+};
+
+void wxWindow::SetValidator( wxValidator *validator )
+{
+  m_windowValidator = validator;
+};
+
+bool wxWindow::IsBeingDeleted(void)
+{
+  return FALSE;
+};
+
+void wxWindow::SetId( wxWindowID id )
+{
+  m_windowId = id;
+};
+
+wxWindowID wxWindow::GetId(void)
+{
+  return m_windowId;
+};
+
+void wxWindow::SetCursor( const wxCursor &cursor )
+{
+  if (*m_cursor == cursor) return;
+  (*m_cursor) = cursor;
+  if (m_widget->window)
+    gdk_window_set_cursor( m_widget->window, m_cursor->GetCursor() );
+  if (m_wxwindow && m_wxwindow->window)
+    gdk_window_set_cursor( m_wxwindow->window, m_cursor->GetCursor() );
+};
+
+void wxWindow::Refresh( const bool eraseBackground, const wxRect *rect )
+{
+  if (eraseBackground && m_wxwindow && m_wxwindow->window)
+  {
+    if (rect)
+      gdk_window_clear_area( m_wxwindow->window, 
+        rect->x, 
+	rect->y, 
+	rect->width, 
+	rect->height );
+    else
+      Clear();
+  };
+  if (!rect)
+  {
+    if (m_wxwindow)
+    {
+      wxClientDC dc(this);
+      PrepareDC(dc);
+      long x = 0;
+      long y = 0;
+      dc.GetInternalDeviceOrigin( &x, &y );
+      
+      int w = 0;
+      int h = 0;
+      GetClientSize( &w, &h );
+      
+      GdkRectangle gdk_rect;
+      gdk_rect.x = x;
+      gdk_rect.y = y;
+      gdk_rect.width = w;
+      gdk_rect.height = h;
+      gtk_widget_draw( m_wxwindow, &gdk_rect );
+    };
+  }
+  else
+  {
+    GdkRectangle gdk_rect;
+    gdk_rect.x = rect->x;
+    gdk_rect.y = rect->y;
+    gdk_rect.width = rect->width;
+    gdk_rect.height = rect->height;
+    if (m_wxwindow)
+      gtk_widget_draw( m_wxwindow, &gdk_rect );
+    else
+      gtk_widget_draw( m_widget, &gdk_rect );
+  };
+};
+
+bool wxWindow::IsExposed( const long x, const long y )
+{
+  return (m_updateRegion.Contains( x, y ) != wxOutRegion );
+};
+
+bool wxWindow::IsExposed( const long x, const long y, const long width, const long height )
+{
+  return (m_updateRegion.Contains( x, y, width, height ) != wxOutRegion );
+};
+
+void wxWindow::Clear(void)
+{
+  if (m_wxwindow && m_wxwindow->window) gdk_window_clear( m_wxwindow->window );
+};
+
+wxColour wxWindow::GetBackgroundColour(void) const
+{
+  return m_backgroundColour;
+};
+
+void wxWindow::SetBackgroundColour( const wxColour &colour )
+{
+  m_backgroundColour = colour;
+  if (m_wxwindow)
+  {
+    m_backgroundColour.CalcPixel( m_wxwindow->style->colormap );
+    gdk_window_set_background( m_wxwindow->window, m_backgroundColour.GetColor() );
+    gdk_window_clear( m_wxwindow->window );
+  };
+  // do something ?
+};
+
+bool wxWindow::Validate(void)
+{
+  wxNode *node = GetChildren()->First();
+  while (node)
+  {
+    wxWindow *child = (wxWindow *)node->Data();
+    if (child->GetValidator() && /* child->GetValidator()->Ok() && */ !child->GetValidator()->Validate(this)) 
+      { return FALSE; }
+    node = node->Next();
+  };
+  return TRUE;
+};
+
+bool wxWindow::TransferDataToWindow(void)
+{
+  wxNode *node = GetChildren()->First();
+  while (node)
+  {
+    wxWindow *child = (wxWindow *)node->Data();
+    if (child->GetValidator() && /* child->GetValidator()->Ok() && */
+	!child->GetValidator()->TransferToWindow() )
+    {
+      wxMessageBox( "Application Error", "Could not transfer data to window", wxOK|wxICON_EXCLAMATION );
+      return FALSE;
+    };
+    node = node->Next();
+  };
+  return TRUE;
+};
+
+bool wxWindow::TransferDataFromWindow(void)
+{
+  wxNode *node = GetChildren()->First();
+  while (node)
+  {
+    wxWindow *child = (wxWindow *)node->Data();
+    if ( child->GetValidator() && /* child->GetValidator()->Ok() && */ !child->GetValidator()->TransferFromWindow() )
+      { return FALSE; }
+   node = node->Next();
+  }
+  return TRUE;
+};
+
+void wxWindow::OnInitDialog( wxInitDialogEvent &WXUNUSED(event) )
+{
+  TransferDataToWindow();
+};
+
+void wxWindow::InitDialog(void)
+{
+  wxInitDialogEvent event(GetId());
+  event.SetEventObject( this );
+  GetEventHandler()->ProcessEvent(event);
+};
+
+void wxWindow::SetDropTarget( wxDropTarget *dropTarget )
+{
+  GtkWidget *connect_widget = m_widget;
+  if (m_wxwindow) connect_widget = m_wxwindow;
+  if (m_pDropTarget)
+  {
+    m_pDropTarget->UnregisterWidget( connect_widget );
+    delete m_pDropTarget;
+  };
+  m_pDropTarget = dropTarget;
+  if (m_pDropTarget)
+  {
+    m_pDropTarget->RegisterWidget( connect_widget );
+  };
+};
+
+wxDropTarget *wxWindow::GetDropTarget() const
+{
+  return m_pDropTarget;
+};
+
+void wxWindow::SetFont( const wxFont &font )
+{
+  m_font = font;
+/*
+  create new style
+  copy old style values to new one
+  set font in new style
+  -> takes to many resources
+  
+  GtkStyle *style = gtk_style_new();
+  ...
+*/
+};
+
+wxFont *wxWindow::GetFont(void)
+{
+  return &m_font;
+};
+
+void wxWindow::SetWindowStyleFlag( long flag )
+{
+  m_windowStyle = flag;
+};
+
+long wxWindow::GetWindowStyleFlag(void) const
+{
+  return m_windowStyle;
+};
+
+void wxWindow::CaptureMouse(void)
+{
+  GtkWidget *connect_widget = m_widget;
+  if (m_wxwindow) connect_widget = m_wxwindow;
+  gtk_grab_add( connect_widget );
+  gdk_pointer_grab ( connect_widget->window, FALSE,
+                    (GdkEventMask)
+		    (GDK_BUTTON_PRESS_MASK | 
+		    GDK_BUTTON_RELEASE_MASK |
+		    GDK_POINTER_MOTION_MASK), 
+		    NULL, NULL, GDK_CURRENT_TIME );
+};
+
+void wxWindow::ReleaseMouse(void)
+{
+  GtkWidget *connect_widget = m_widget;
+  if (m_wxwindow) connect_widget = m_wxwindow;
+  gtk_grab_remove( connect_widget );
+  gdk_pointer_ungrab ( GDK_CURRENT_TIME );
+};
+
+void wxWindow::SetTitle( const wxString &WXUNUSED(title) )
+{
+};
+
+wxString wxWindow::GetTitle(void) const
+{
+  return (wxString&)m_windowName;
+};
+
+wxString wxWindow::GetLabel(void) const
+{
+  return GetTitle();
+};
+
+void wxWindow::SetName( const wxString &name )
+{
+  m_windowName = name;
+};
+
+wxString wxWindow::GetName(void) const
+{
+  return (wxString&)m_windowName;
+};
+
+bool wxWindow::IsShown(void)
+{
+  return m_isShown;
+};
+
+bool wxWindow::IsRetained(void)
+{
+  return FALSE;
+};
+
+wxWindow *wxWindow::FindWindow( const long id )
+{
+  if (id == m_windowId) return this;
+  wxNode *node = m_children.First();
+  while (node)
+  {
+    wxWindow *child = (wxWindow*)node->Data();
+    wxWindow *res = child->FindWindow( id );
+    if (res) return res;
+    node = node->Next();
+  };
+  return NULL;
+};
+
+wxWindow *wxWindow::FindWindow( const wxString& name )
+{
+  if (name == m_windowName) return this;
+  wxNode *node = m_children.First();
+  while (node)
+  {
+    wxWindow *child = (wxWindow*)node->Data();
+    wxWindow *res = child->FindWindow( name );
+    if (res) return res;
+    node = node->Next();
+  };
+  return NULL;
+};
+
+void wxWindow::SetScrollbar( const int orient, const int pos, const int thumbVisible,
+      const int range, const bool WXUNUSED(refresh) )
+{
+  if (!m_wxwindow) return;
+
+  if (orient == wxHORIZONTAL)
+  {
+    float fpos = (float)pos;
+    m_oldHorizontalPos = fpos;
+    float frange = (float)range;
+    float fthumb = (float)thumbVisible;
+    
+    if ((fabs(fpos-m_hAdjust->value) < 0.2) &&
+        (fabs(frange-m_hAdjust->upper) < 0.2) &&
+	(fabs(fthumb-m_hAdjust->page_size) < 0.2))
+      return;
+      
+    m_hAdjust->lower = 0.0;
+    m_hAdjust->upper = frange;
+    m_hAdjust->value = fpos;
+    m_hAdjust->step_increment = 1.0;
+    m_hAdjust->page_increment = (float)(wxMax(fthumb-2,0));
+    m_hAdjust->page_size = fthumb;
+  }
+  else
+  {
+    float fpos = (float)pos;
+    m_oldVerticalPos = fpos;
+    float frange = (float)range;
+    float fthumb = (float)thumbVisible;
+    
+    if ((fabs(fpos-m_vAdjust->value) < 0.2) &&
+        (fabs(frange-m_vAdjust->upper) < 0.2) &&
+	(fabs(fthumb-m_vAdjust->page_size) < 0.2))
+      return;
+      
+    m_vAdjust->lower = 0.0;
+    m_vAdjust->upper = frange;
+    m_vAdjust->value = fpos;
+    m_vAdjust->step_increment = 1.0;
+    m_vAdjust->page_increment = (float)(wxMax(fthumb-2,0));
+    m_vAdjust->page_size = fthumb;
+  };
+ 
+  if (m_wxwindow->window)
+  {  
+    if (orient == wxHORIZONTAL)
+      gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" );
+    else  
+      gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" );
+      
+//    gtk_widget_set_usize( m_widget, m_width, m_height );
+  };
+};
+
+void wxWindow::SetScrollPos( const int orient, const int pos, const bool WXUNUSED(refresh) )
+{
+  if (!m_wxwindow) return;
+  
+  if (orient == wxHORIZONTAL)
+  {
+    float fpos = (float)pos;
+    m_oldHorizontalPos = fpos;
+
+    if (fabs(fpos-m_hAdjust->value) < 0.2) return;
+    m_hAdjust->value = fpos;
+  }
+  else
+  {
+    float fpos = (float)pos;
+    m_oldVerticalPos = fpos;
+    if (fabs(fpos-m_vAdjust->value) < 0.2) return;
+    m_vAdjust->value = fpos;
+  };
+  
+  if (m_wxwindow->window)
+  {  
+    if (orient == wxHORIZONTAL)
+      gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "value_changed" );
+    else  
+      gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "value_changed" );
+  };
+};
+
+int wxWindow::GetScrollThumb( const int orient ) const
+{
+  if (!m_wxwindow) return 0;
+
+  if (orient == wxHORIZONTAL)
+    return (int)(m_hAdjust->page_size+0.5);
+  else
+    return (int)(m_vAdjust->page_size+0.5);
+};
+
+int wxWindow::GetScrollPos( const int orient ) const
+{
+  if (!m_wxwindow) return 0;
+
+  if (orient == wxHORIZONTAL)
+    return (int)(m_hAdjust->value+0.5);
+  else
+    return (int)(m_vAdjust->value+0.5);
+};
+
+int wxWindow::GetScrollRange( const int orient ) const
+{
+  if (!m_wxwindow) return 0;
+
+  if (orient == wxHORIZONTAL)
+    return (int)(m_hAdjust->upper+0.5);
+  else
+    return (int)(m_vAdjust->upper+0.5);
+};
+
+void wxWindow::ScrollWindow( const int dx, const int dy, const wxRect* WXUNUSED(rect) )
+{
+  if (!m_wxwindow) return;
+  
+  m_drawingOffsetX += dx;
+  m_drawingOffsetY += dy;
+  
+//  printf( "X: %d  Y: %d  \n", (int)m_drawingOffsetX, (int)m_drawingOffsetY );
+  
+  gtk_myfixed_set_offset( GTK_MYFIXED(m_wxwindow), m_drawingOffsetX, m_drawingOffsetY );
+  
+/*
+    The code here is very nifty, but it doesn't work with
+    overlapping windows...
+
+    int cw = 0;
+    int ch = 0;
+    GetClientSize( &cw, &ch );
+    
+    int w = cw - abs(dx);
+    int h = ch - abs(dy);
+    if ((h < 0) || (w < 0))
+    {
+      Refresh();
+      return;
+    };
+    int s_x = 0;
+    int s_y = 0;
+    if (dx < 0) s_x = -dx;
+    if (dy < 0) s_y = -dy;
+    int d_x = 0;
+    int d_y = 0;
+    if (dx > 0) d_x = dx;
+    if (dy > 0) d_y = dy;
+    gdk_window_copy_area( m_wxwindow->window, m_wxwindow->style->fg_gc[0], d_x, d_y,
+      m_wxwindow->window, s_x, s_y, w, h );
+      
+    wxRect rect;
+    if (dx < 0) rect.x = cw+dx; else rect.x = 0;
+    if (dy < 0) rect.y = ch+dy; else rect.y = 0;
+    if (dy != 0) rect.width = cw; else rect.width = abs(dx);
+    if (dx != 0) rect.height = ch; else rect.height = abs(dy);
+  
+    Refresh( TRUE, &rect );
+*/
+};
+
+void wxWindow::GetDrawingOffset( long *x, long *y )
+{
+  if (x) *x = m_drawingOffsetX;
+  if (y) *y = m_drawingOffsetY;
+};
+
+//-------------------------------------------------------------------------------------
+//          Layout
+//-------------------------------------------------------------------------------------
+
+wxLayoutConstraints *wxWindow::GetConstraints(void) const
+{
+  return m_constraints;
+};
+
+void wxWindow::SetConstraints( wxLayoutConstraints *constraints )
+{
+  if (m_constraints)
+  {
+    UnsetConstraints(m_constraints);
+    delete m_constraints;
+  }
+  m_constraints = constraints;
+  if (m_constraints)
+  {
+    // Make sure other windows know they're part of a 'meaningful relationship'
+    if (m_constraints->left.GetOtherWindow() && (m_constraints->left.GetOtherWindow() != this))
+      m_constraints->left.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
+    if (m_constraints->top.GetOtherWindow() && (m_constraints->top.GetOtherWindow() != this))
+      m_constraints->top.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
+    if (m_constraints->right.GetOtherWindow() && (m_constraints->right.GetOtherWindow() != this))
+      m_constraints->right.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
+    if (m_constraints->bottom.GetOtherWindow() && (m_constraints->bottom.GetOtherWindow() != this))
+      m_constraints->bottom.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
+    if (m_constraints->width.GetOtherWindow() && (m_constraints->width.GetOtherWindow() != this))
+      m_constraints->width.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
+    if (m_constraints->height.GetOtherWindow() && (m_constraints->height.GetOtherWindow() != this))
+      m_constraints->height.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
+    if (m_constraints->centreX.GetOtherWindow() && (m_constraints->centreX.GetOtherWindow() != this))
+      m_constraints->centreX.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
+    if (m_constraints->centreY.GetOtherWindow() && (m_constraints->centreY.GetOtherWindow() != this))
+      m_constraints->centreY.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
+  }
+;
+}
+;
+
+void wxWindow::SetAutoLayout( const bool autoLayout )
+{
+  m_autoLayout = autoLayout;
+};
+
+bool wxWindow::GetAutoLayout(void) const
+{
+  return m_autoLayout;
+};
+
+wxSizer *wxWindow::GetSizer(void) const
+{
+  return m_windowSizer;
+};
+
+void wxWindow::SetSizerParent( wxWindow *win )
+{
+  m_sizerParent = win;
+};
+
+wxWindow *wxWindow::GetSizerParent(void) const
+{
+  return m_sizerParent;
+};
+
+// This removes any dangling pointers to this window
+// in other windows' constraintsInvolvedIn lists.
+void wxWindow::UnsetConstraints(wxLayoutConstraints *c)
+{
+  if (c)
+  {
+    if (c->left.GetOtherWindow() && (c->top.GetOtherWindow() != this))
+      c->left.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
+    if (c->top.GetOtherWindow() && (c->top.GetOtherWindow() != this))
+      c->top.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
+    if (c->right.GetOtherWindow() && (c->right.GetOtherWindow() != this))
+      c->right.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
+    if (c->bottom.GetOtherWindow() && (c->bottom.GetOtherWindow() != this))
+      c->bottom.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
+    if (c->width.GetOtherWindow() && (c->width.GetOtherWindow() != this))
+      c->width.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
+    if (c->height.GetOtherWindow() && (c->height.GetOtherWindow() != this))
+      c->height.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
+    if (c->centreX.GetOtherWindow() && (c->centreX.GetOtherWindow() != this))
+      c->centreX.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
+    if (c->centreY.GetOtherWindow() && (c->centreY.GetOtherWindow() != this))
+      c->centreY.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
+  }
+}
+
+// Back-pointer to other windows we're involved with, so if we delete
+// this window, we must delete any constraints we're involved with.
+void wxWindow::AddConstraintReference(wxWindow *otherWin)
+{
+  if (!m_constraintsInvolvedIn)
+    m_constraintsInvolvedIn = new wxList;
+  if (!m_constraintsInvolvedIn->Member(otherWin))
+    m_constraintsInvolvedIn->Append(otherWin);
+}
+
+// REMOVE back-pointer to other windows we're involved with.
+void wxWindow::RemoveConstraintReference(wxWindow *otherWin)
+{
+  if (m_constraintsInvolvedIn)
+    m_constraintsInvolvedIn->DeleteObject(otherWin);
+}
+
+// Reset any constraints that mention this window
+void wxWindow::DeleteRelatedConstraints(void)
+{
+  if (m_constraintsInvolvedIn)
+  {
+    wxNode *node = m_constraintsInvolvedIn->First();
+    while (node)
+    {
+      wxWindow *win = (wxWindow *)node->Data();
+      wxNode *next = node->Next();
+      wxLayoutConstraints *constr = win->GetConstraints();
+
+      // Reset any constraints involving this window
+      if (constr)
+      {
+        constr->left.ResetIfWin((wxWindow *)this);
+        constr->top.ResetIfWin((wxWindow *)this);
+        constr->right.ResetIfWin((wxWindow *)this);
+        constr->bottom.ResetIfWin((wxWindow *)this);
+        constr->width.ResetIfWin((wxWindow *)this);
+        constr->height.ResetIfWin((wxWindow *)this);
+        constr->centreX.ResetIfWin((wxWindow *)this);
+        constr->centreY.ResetIfWin((wxWindow *)this);
+      }
+      delete node;
+      node = next;
+    }
+    delete m_constraintsInvolvedIn;
+    m_constraintsInvolvedIn = NULL;
+  }
+}
+
+void wxWindow::SetSizer(wxSizer *sizer)
+{
+  m_windowSizer = sizer;
+  if (sizer)
+    sizer->SetSizerParent((wxWindow *)this);
+}
+
+/*
+ * New version
+ */
+
+bool wxWindow::Layout(void)
+{
+  if (GetConstraints())
+  {
+    int w, h;
+    GetClientSize(&w, &h);
+    GetConstraints()->width.SetValue(w);
+    GetConstraints()->height.SetValue(h);
+  }
+  
+  // If top level (one sizer), evaluate the sizer's constraints.
+  if (GetSizer())
+  {
+    int noChanges;
+    GetSizer()->ResetConstraints();   // Mark all constraints as unevaluated
+    GetSizer()->LayoutPhase1(&noChanges);
+    GetSizer()->LayoutPhase2(&noChanges);
+    GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
+    return TRUE;
+  }
+  else
+  {
+    // Otherwise, evaluate child constraints
+    ResetConstraints();   // Mark all constraints as unevaluated
+    DoPhase(1);           // Just one phase need if no sizers involved
+    DoPhase(2);
+    SetConstraintSizes(); // Recursively set the real window sizes
+  }
+  return TRUE;
+}
+
+
+// Do a phase of evaluating constraints:
+// the default behaviour. wxSizers may do a similar
+// thing, but also impose their own 'constraints'
+// and order the evaluation differently.
+bool wxWindow::LayoutPhase1(int *noChanges)
+{
+  wxLayoutConstraints *constr = GetConstraints();
+  if (constr)
+  {
+    return constr->SatisfyConstraints((wxWindow *)this, noChanges);
+  }
+  else
+    return TRUE;
+}
+
+bool wxWindow::LayoutPhase2(int *noChanges)
+{
+  *noChanges = 0;
+  
+  // Layout children
+  DoPhase(1);
+  DoPhase(2);
+  return TRUE;
+}
+
+// Do a phase of evaluating child constraints
+bool wxWindow::DoPhase(const int phase)
+{
+  int noIterations = 0;
+  int maxIterations = 500;
+  int noChanges = 1;
+  int noFailures = 0;
+  wxList succeeded;
+  while ((noChanges > 0) && (noIterations < maxIterations))
+  {
+    noChanges = 0;
+    noFailures = 0;
+    wxNode *node = GetChildren()->First();
+    while (node)
+    {
+      wxWindow *child = (wxWindow *)node->Data();
+      if (!child->IsKindOf(CLASSINFO(wxFrame)) && !child->IsKindOf(CLASSINFO(wxDialog)))
+      {
+        wxLayoutConstraints *constr = child->GetConstraints();
+        if (constr)
+        {
+          if (succeeded.Member(child))
+          {
+          }
+          else
+          {
+            int tempNoChanges = 0;
+            bool success = ( (phase == 1) ? child->LayoutPhase1(&tempNoChanges) : child->LayoutPhase2(&tempNoChanges) ) ;
+            noChanges += tempNoChanges;
+            if (success)
+            {
+              succeeded.Append(child);
+            }
+          }
+        }
+      }
+      node = node->Next();
+    }
+    noIterations ++;
+  }
+  return TRUE;
+}
+
+void wxWindow::ResetConstraints(void)
+{
+  wxLayoutConstraints *constr = GetConstraints();
+  if (constr)
+  {
+    constr->left.SetDone(FALSE);
+    constr->top.SetDone(FALSE);
+    constr->right.SetDone(FALSE);
+    constr->bottom.SetDone(FALSE);
+    constr->width.SetDone(FALSE);
+    constr->height.SetDone(FALSE);
+    constr->centreX.SetDone(FALSE);
+    constr->centreY.SetDone(FALSE);
+  }
+  wxNode *node = GetChildren()->First();
+  while (node)
+  {
+    wxWindow *win = (wxWindow *)node->Data();
+    if (!win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)))
+      win->ResetConstraints();
+    node = node->Next();
+  }
+}
+
+// Need to distinguish between setting the 'fake' size for
+// windows and sizers, and setting the real values.
+void wxWindow::SetConstraintSizes(const bool recurse)
+{
+  wxLayoutConstraints *constr = GetConstraints();
+  if (constr && constr->left.GetDone() && constr->right.GetDone() &&
+                constr->width.GetDone() && constr->height.GetDone())
+  {
+    int x = constr->left.GetValue();
+    int y = constr->top.GetValue();
+    int w = constr->width.GetValue();
+    int h = constr->height.GetValue();
+
+    // If we don't want to resize this window, just move it...
+    if ((constr->width.GetRelationship() != wxAsIs) ||
+        (constr->height.GetRelationship() != wxAsIs))
+    {
+      // Calls Layout() recursively. AAAGH. How can we stop that.
+      // Simply take Layout() out of non-top level OnSizes.
+      SizerSetSize(x, y, w, h);
+    }
+    else
+    {
+      SizerMove(x, y);
+    }
+  }
+  else if (constr)
+  {
+    char *windowClass = this->GetClassInfo()->GetClassName();
+
+    wxString winName;
+	if (GetName() == "")
+		winName = "unnamed";
+	else
+		winName = GetName();
+    wxDebugMsg("Constraint(s) not satisfied for window of type %s, name %s:\n", (const char *)windowClass, (const char *)winName);
+    if (!constr->left.GetDone())
+      wxDebugMsg("  unsatisfied 'left' constraint.\n");
+    if (!constr->right.GetDone())
+      wxDebugMsg("  unsatisfied 'right' constraint.\n");
+    if (!constr->width.GetDone())
+      wxDebugMsg("  unsatisfied 'width' constraint.\n");
+    if (!constr->height.GetDone())
+      wxDebugMsg("  unsatisfied 'height' constraint.\n");
+    wxDebugMsg("Please check constraints: try adding AsIs() constraints.\n");
+  }
+
+  if (recurse)
+  {
+    wxNode *node = GetChildren()->First();
+    while (node)
+    {
+      wxWindow *win = (wxWindow *)node->Data();
+      if (!win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)))
+        win->SetConstraintSizes();
+      node = node->Next();
+    }
+  }
+}
+
+// This assumes that all sizers are 'on' the same
+// window, i.e. the parent of this window.
+void wxWindow::TransformSizerToActual(int *x, int *y) const
+{
+  if (!m_sizerParent || m_sizerParent->IsKindOf(CLASSINFO(wxDialog)) ||
+  			 m_sizerParent->IsKindOf(CLASSINFO(wxFrame)) )
+    return;
+    
+  int xp, yp;
+  m_sizerParent->GetPosition(&xp, &yp);
+  m_sizerParent->TransformSizerToActual(&xp, &yp);
+  *x += xp;
+  *y += yp;
+}
+
+void wxWindow::SizerSetSize(const int x, const int y, const int w, const int h)
+{
+	int xx = x;
+	int yy = y;
+  TransformSizerToActual(&xx, &yy);
+  SetSize(xx, yy, w, h);
+}
+
+void wxWindow::SizerMove(const int x, const int y)
+{
+	int xx = x;
+	int yy = y;
+  TransformSizerToActual(&xx, &yy);
+  Move(xx, yy);
+}
+
+// Only set the size/position of the constraint (if any)
+void wxWindow::SetSizeConstraint(const int x, const int y, const int w, const int h)
+{
+  wxLayoutConstraints *constr = GetConstraints();
+  if (constr)
+  {
+    if (x != -1)
+    {
+      constr->left.SetValue(x);
+      constr->left.SetDone(TRUE);
+    }
+    if (y != -1)
+    {
+      constr->top.SetValue(y);
+      constr->top.SetDone(TRUE);
+    }
+    if (w != -1)
+    {
+      constr->width.SetValue(w);
+      constr->width.SetDone(TRUE);
+    }
+    if (h != -1)
+    {
+      constr->height.SetValue(h);
+      constr->height.SetDone(TRUE);
+    }
+  }
+}
+
+void wxWindow::MoveConstraint(const int x, const int y)
+{
+  wxLayoutConstraints *constr = GetConstraints();
+  if (constr)
+  {
+    if (x != -1)
+    {
+      constr->left.SetValue(x);
+      constr->left.SetDone(TRUE);
+    }
+    if (y != -1)
+    {
+      constr->top.SetValue(y);
+      constr->top.SetDone(TRUE);
+    }
+  }
+}
+
+void wxWindow::GetSizeConstraint(int *w, int *h) const
+{
+  wxLayoutConstraints *constr = GetConstraints();
+  if (constr)
+  {
+    *w = constr->width.GetValue();
+    *h = constr->height.GetValue();
+  }
+  else
+    GetSize(w, h);
+}
+
+void wxWindow::GetClientSizeConstraint(int *w, int *h) const
+{
+  wxLayoutConstraints *constr = GetConstraints();
+  if (constr)
+  {
+    *w = constr->width.GetValue();
+    *h = constr->height.GetValue();
+  }
+  else
+    GetClientSize(w, h);
+}
+
+void wxWindow::GetPositionConstraint(int *x, int *y) const
+{
+  wxLayoutConstraints *constr = GetConstraints();
+  if (constr)
+  {
+    *x = constr->left.GetValue();
+    *y = constr->top.GetValue();
+  }
+  else
+    GetPosition(x, y);
+}
+
diff --git a/src/gtk1/app.cpp b/src/gtk1/app.cpp
new file mode 100644
index 0000000000..47c1ee0a72
--- /dev/null
+++ b/src/gtk1/app.cpp
@@ -0,0 +1,279 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        app.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "app.h"
+#endif
+
+#include "wx/app.h"
+#include "wx/gdicmn.h"
+#include "wx/utils.h"
+#include "wx/postscrp.h"
+#include "wx/intl.h"
+#include "wx/log.h"
+
+#include "unistd.h"
+
+#ifdef USE_GDK_IMLIB
+#include "gdk_imlib.h"
+#endif
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+wxApp *wxTheApp = NULL;
+wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
+
+extern wxList wxPendingDelete;
+
+//-----------------------------------------------------------------------------
+// local functions
+//-----------------------------------------------------------------------------
+
+extern void wxFlushResources(void);
+
+//-----------------------------------------------------------------------------
+// global functions
+//-----------------------------------------------------------------------------
+
+void wxExit(void)
+{
+  gtk_main_quit();
+};
+
+bool wxYield(void)
+{
+  while (gtk_events_pending() > 0) gtk_main_iteration();
+  return TRUE;
+};
+
+//-----------------------------------------------------------------------------
+// wxApp
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxApp,wxEvtHandler)
+
+gint wxapp_idle_callback( gpointer WXUNUSED(data) )
+{
+  if (wxTheApp) wxTheApp->OnIdle();
+  usleep( 10000 );
+  return TRUE;
+};
+
+wxApp::wxApp()
+{
+  m_idleTag = 0;
+  m_topWindow = NULL;
+  m_exitOnFrameDelete = TRUE;
+};
+
+wxApp::~wxApp(void)
+{
+  gtk_idle_remove( m_idleTag );
+};
+
+bool wxApp::OnInit(void)
+{
+  return TRUE;
+};
+
+bool wxApp::OnInitGui(void)
+{ 
+  m_idleTag = gtk_idle_add( wxapp_idle_callback, NULL );
+  return TRUE; 
+};
+
+int wxApp::OnRun(void) 
+{ 
+  return MainLoop(); 
+};
+
+bool wxApp::OnIdle(void)
+{
+  DeletePendingObjects();
+  return FALSE;
+};
+
+int wxApp::OnExit(void)
+{
+  return 0;
+};
+
+int wxApp::MainLoop(void)
+{
+  gtk_main();
+  return 0;
+};
+
+void wxApp::ExitMainLoop(void)
+{
+  gtk_main_quit();
+};
+
+bool wxApp::Initialized(void)
+{
+  return m_initialized;
+};
+
+bool wxApp::Pending(void) 
+{
+  return FALSE;
+};
+
+void wxApp::Dispatch(void) 
+{
+};
+
+void wxApp::DeletePendingObjects(void)
+{
+  wxNode *node = wxPendingDelete.First();
+  while (node)
+  {
+    wxObject *obj = (wxObject *)node->Data();
+    
+    delete obj;
+
+    if (wxPendingDelete.Member(obj))
+      delete node;
+
+    node = wxPendingDelete.First();
+  };
+};
+
+wxWindow *wxApp::GetTopWindow(void)
+{
+  if (m_topWindow) return m_topWindow;
+  wxNode *node = wxTopLevelWindows.First();
+  if (!node) return NULL;
+  return (wxWindow*)node->Data();
+};
+
+void wxApp::SetTopWindow( wxWindow *win )
+{
+  m_topWindow = win;
+};
+
+void wxApp::CommonInit(void)
+{
+
+/*
+#if USE_RESOURCES
+  (void) wxGetResource("wxWindows", "OsVersion", &wxOsVersion);
+#endif
+*/
+
+  wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
+  wxTheColourDatabase->Initialize();
+  wxInitializeStockObjects();
+
+  // For PostScript printing
+#if USE_POSTSCRIPT
+  wxInitializePrintSetupData();
+  wxThePrintPaperDatabase = new wxPrintPaperDatabase;
+  wxThePrintPaperDatabase->CreateDatabase();
+#endif
+
+
+/*
+  wxBitmap::InitStandardHandlers();
+
+  g_globalCursor = new wxCursor;
+*/
+
+  wxInitializeStockObjects();
+};
+
+void wxApp::CommonCleanUp(void)
+{
+  wxDeleteStockObjects();
+  
+  wxFlushResources();
+};
+    
+wxLog *wxApp::CreateLogTarget()
+{
+  return new wxLogGui;
+}
+
+//-----------------------------------------------------------------------------
+// wxEntry
+//-----------------------------------------------------------------------------
+
+int wxEntry( int argc, char *argv[] )
+{
+  wxBuffer = new char[BUFSIZ + 512];
+
+  wxClassInfo::InitializeClasses();
+  
+  if (!wxTheApp)
+  {
+    if (!wxApp::GetInitializerFunction())
+    {
+      printf( "wxWindows error: No initializer - use IMPLEMENT_APP macro.\n" );
+      return 0;
+    };
+    
+    wxAppInitializerFunction app_ini = wxApp::GetInitializerFunction();
+    
+    wxObject *test_app = app_ini();
+    
+    wxTheApp = (wxApp*) test_app;
+    
+//    wxTheApp = (wxApp*)( app_ini() );
+  };
+  
+  if (!wxTheApp) 
+  {
+    printf( "wxWindows error: wxTheApp == NULL\n" );
+    return 0;
+  };
+
+//  printf( "Programmstart.\n" );
+  
+  wxTheApp->argc = argc;
+  wxTheApp->argv = argv;
+  
+  gtk_init( &argc, &argv );
+
+#ifdef USE_GDK_IMLIB
+
+  gdk_imlib_init();
+  
+  gtk_widget_push_visual(gdk_imlib_get_visual());
+  
+  gtk_widget_push_colormap(gdk_imlib_get_colormap());
+  
+#endif  
+    
+  wxApp::CommonInit();
+
+  wxTheApp->OnInitGui();
+
+  // Here frames insert themselves automatically
+  // into wxTopLevelWindows by getting created
+  // in OnInit().
+  
+  if (!wxTheApp->OnInit()) return 0;
+
+  wxTheApp->m_initialized = (wxTopLevelWindows.Number() > 0);
+  
+  int retValue = 0;
+  
+  if (wxTheApp->Initialized()) retValue = wxTheApp->OnRun();
+  
+  wxTheApp->DeletePendingObjects();  
+  
+  wxTheApp->OnExit();
+  
+  wxApp::CommonCleanUp();
+  
+  return retValue;
+};
diff --git a/src/gtk1/bdiag.xbm b/src/gtk1/bdiag.xbm
new file mode 100644
index 0000000000..9ff0a1822f
--- /dev/null
+++ b/src/gtk1/bdiag.xbm
@@ -0,0 +1,6 @@
+#define bdiag_width 16
+#define bdiag_height 16
+static char bdiag_bits[] = {
+   0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04,
+   0x02, 0x02, 0x01, 0x01, 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10,
+   0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x01, 0x01};
diff --git a/src/gtk1/bitmap.cpp b/src/gtk1/bitmap.cpp
new file mode 100644
index 0000000000..ebb2fe5d6a
--- /dev/null
+++ b/src/gtk1/bitmap.cpp
@@ -0,0 +1,293 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        bitmap.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "bitmap.h"
+#endif
+
+#include "wx/bitmap.h"
+#include "gdk/gdkprivate.h"
+
+#ifdef USE_GDK_IMLIB
+#include "gdk_imlib.h"
+#endif
+
+//-----------------------------------------------------------------------------
+// wxMask
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxMask,wxObject)
+
+wxMask::wxMask(void)
+{
+  m_bitmap = NULL;
+};
+
+wxMask::wxMask( const wxBitmap& WXUNUSED(bitmap), const wxColour& WXUNUSED(colour) )
+{
+};
+
+wxMask::wxMask( const wxBitmap& WXUNUSED(bitmap), const int WXUNUSED(paletteIndex) )
+{
+};
+
+wxMask::wxMask( const wxBitmap& WXUNUSED(bitmap) )
+{
+};
+
+wxMask::~wxMask(void)
+{
+#ifdef USE_GDK_IMLIB
+  // do not delete the mask, gdk_imlib does it for you
+#else
+  if (m_bitmap) gdk_bitmap_unref( m_bitmap );
+#endif  
+};
+
+GdkBitmap *wxMask::GetBitmap(void) const
+{
+  return m_bitmap;
+};
+  
+//-----------------------------------------------------------------------------
+// wxBitmap
+//-----------------------------------------------------------------------------
+
+class wxBitmapRefData: public wxObjectRefData
+{
+  public:
+  
+    wxBitmapRefData(void);
+    ~wxBitmapRefData(void);
+  
+    GdkPixmap      *m_pixmap;
+    wxMask         *m_mask;
+    int             m_width;
+    int             m_height;
+    int             m_bpp;
+    wxPalette      *m_palette;
+};
+
+wxBitmapRefData::wxBitmapRefData(void)
+{
+  m_pixmap = NULL;
+  m_mask = NULL;
+  m_width = 0;
+  m_height = 0;
+  m_bpp = 0;
+  m_palette = NULL;
+};
+
+wxBitmapRefData::~wxBitmapRefData(void)
+{
+#ifdef USE_GDK_IMLIB
+  if (m_pixmap) gdk_imlib_free_pixmap( m_pixmap );
+#else
+  if (m_pixmap) gdk_pixmap_unref( m_pixmap );
+#endif
+  if (m_mask) delete m_mask;
+  if (m_palette) delete m_palette;
+};
+
+//-----------------------------------------------------------------------------
+
+#define M_BMPDATA ((wxBitmapRefData *)m_refData)
+
+IMPLEMENT_DYNAMIC_CLASS(wxBitmap,wxGDIObject)
+
+wxBitmap::wxBitmap(void)
+{
+  if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
+};
+  
+wxBitmap::wxBitmap( const int width, const int height, const int depth )
+{
+  m_refData = new wxBitmapRefData();
+  M_BMPDATA->m_mask = NULL;
+  M_BMPDATA->m_pixmap = 
+    gdk_pixmap_new( (GdkWindow*) &gdk_root_parent, width, height, depth );
+  gdk_window_get_size( M_BMPDATA->m_pixmap, &(M_BMPDATA->m_width), &(M_BMPDATA->m_height) );
+  M_BMPDATA->m_bpp = depth;
+   
+  if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
+};
+
+wxBitmap::wxBitmap( char **bits )
+{
+  m_refData = new wxBitmapRefData();
+  
+  GdkBitmap *mask = NULL;
+
+#ifndef USE_GDK_IMLIB
+  M_BMPDATA->m_pixmap = 
+    gdk_pixmap_create_from_xpm_d( (GdkWindow*) &gdk_root_parent, &mask, NULL, (gchar **) bits );
+#else
+  M_BMPDATA->m_pixmap = NULL;
+  int res = gdk_imlib_data_to_pixmap( bits, &M_BMPDATA->m_pixmap, &mask );
+#endif
+  
+  if (mask)
+  {
+    M_BMPDATA->m_mask = new wxMask();
+    M_BMPDATA->m_mask->m_bitmap = mask;
+  };
+				  
+  gdk_window_get_size( M_BMPDATA->m_pixmap, &(M_BMPDATA->m_width), &(M_BMPDATA->m_height) );
+  M_BMPDATA->m_bpp = 24; // ?
+   
+  if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
+};
+  
+wxBitmap::wxBitmap( const wxBitmap& bmp )
+{
+  Ref( bmp );
+   
+  if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
+};
+  
+wxBitmap::wxBitmap( const wxBitmap* bmp )
+{
+  if (bmp) Ref( *bmp );
+   
+  if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this);
+};
+  
+wxBitmap::wxBitmap( const wxString &filename, const int type )
+{
+  LoadFile( filename, type );
+};
+
+wxBitmap::~wxBitmap(void)
+{
+  if (wxTheBitmapList) wxTheBitmapList->DeleteObject(this);
+};
+  
+wxBitmap& wxBitmap::operator = ( const wxBitmap& bmp )
+{
+  if (*this == bmp) return (*this); 
+  Ref( bmp ); 
+  return *this; 
+};
+  
+bool wxBitmap::operator == ( const wxBitmap& bmp )
+{
+  return m_refData == bmp.m_refData; 
+};
+  
+bool wxBitmap::operator != ( const wxBitmap& bmp )
+{
+  return m_refData != bmp.m_refData; 
+};
+  
+bool wxBitmap::Ok(void) const
+{
+  return m_refData != NULL;
+};
+  
+int wxBitmap::GetHeight(void) const
+{
+  if (!Ok()) return 0;
+  return M_BMPDATA->m_height;
+};
+
+int wxBitmap::GetWidth(void) const
+{
+  if (!Ok()) return 0;
+  return M_BMPDATA->m_width;
+};
+
+int wxBitmap::GetDepth(void) const
+{
+  if (!Ok()) return 0;
+  return M_BMPDATA->m_bpp;
+};
+
+void wxBitmap::SetHeight( const int height )
+{
+  if (!Ok()) return;
+  M_BMPDATA->m_height = height;
+};
+
+void wxBitmap::SetWidth( const int width )
+{
+  if (!Ok()) return;
+  M_BMPDATA->m_width = width;
+};
+
+void wxBitmap::SetDepth( const int depth )
+{
+  if (!Ok()) return;
+  M_BMPDATA->m_bpp = depth;
+};
+
+wxMask *wxBitmap::GetMask(void) const
+{
+  if (!Ok()) return NULL;
+  return M_BMPDATA->m_mask;
+};
+
+void wxBitmap::SetMask( wxMask *mask )
+{
+  if (!Ok()) return;
+  if (M_BMPDATA->m_mask) delete M_BMPDATA->m_mask;
+  M_BMPDATA->m_mask = mask;
+};
+
+bool wxBitmap::SaveFile( const wxString &WXUNUSED(name), const int WXUNUSED(type), 
+  wxPalette *WXUNUSED(palette) )
+{
+  return FALSE;
+};
+
+bool wxBitmap::LoadFile( const wxString &name, const int WXUNUSED(type) )
+{
+#ifdef USE_GDK_IMLIB
+
+  UnRef();
+  m_refData = new wxBitmapRefData();
+  M_BMPDATA->m_mask = NULL;
+
+  GdkBitmap *mask = NULL;
+  
+  int res = gdk_imlib_load_file_to_pixmap( WXSTRINGCAST name, &M_BMPDATA->m_pixmap, &mask );
+
+  if (res != 1)
+  {
+    UnRef();
+    return FALSE;
+  };
+
+  if (mask)
+  {
+    M_BMPDATA->m_mask = new wxMask();
+    M_BMPDATA->m_mask->m_bitmap = mask;
+  }
+				  
+  gdk_window_get_size( M_BMPDATA->m_pixmap, &(M_BMPDATA->m_width), &(M_BMPDATA->m_height) );
+  M_BMPDATA->m_bpp = 24; // ?
+  
+  return TRUE;
+#endif
+
+  return FALSE;
+};
+        
+wxPalette *wxBitmap::GetPalette(void) const
+{
+  if (!Ok()) return NULL;
+  return M_BMPDATA->m_palette;
+};
+
+GdkPixmap *wxBitmap::GetPixmap(void) const
+{
+  if (!Ok()) return NULL;
+  return M_BMPDATA->m_pixmap;
+};
+  
diff --git a/src/gtk1/brush.cpp b/src/gtk1/brush.cpp
new file mode 100644
index 0000000000..e8bfb06968
--- /dev/null
+++ b/src/gtk1/brush.cpp
@@ -0,0 +1,132 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        brush.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "brush.h"
+#endif
+
+#include "wx/brush.h"
+
+//-----------------------------------------------------------------------------
+// wxBrush
+//-----------------------------------------------------------------------------
+
+class wxBrushRefData: public wxObjectRefData
+{
+  public:
+  
+    wxBrushRefData(void);
+  
+    int        m_style;
+    wxBitmap   m_stipple;
+    wxColour   m_colour;
+};
+
+wxBrushRefData::wxBrushRefData(void)
+{
+  m_style = 0;
+};
+
+//-----------------------------------------------------------------------------
+
+#define M_BRUSHDATA ((wxBrushRefData *)m_refData)
+
+IMPLEMENT_DYNAMIC_CLASS(wxBrush,wxGDIObject)
+
+wxBrush::wxBrush(void)
+{
+  if (wxTheBrushList) wxTheBrushList->AddBrush( this );
+};
+
+wxBrush::wxBrush( const wxColour &colour, const int style )
+{
+  m_refData = new wxBrushRefData();
+  M_BRUSHDATA->m_style = style;
+  M_BRUSHDATA->m_colour = colour;
+  
+  if (wxTheBrushList) wxTheBrushList->AddBrush( this );
+};
+
+wxBrush::wxBrush( const wxString &colourName, const int style )
+{
+  m_refData = new wxBrushRefData();
+  M_BRUSHDATA->m_style = style;
+  M_BRUSHDATA->m_colour = colourName;
+  
+  if (wxTheBrushList) wxTheBrushList->AddBrush( this );
+};
+
+wxBrush::wxBrush( const wxBitmap &stippleBitmap )
+{
+  m_refData = new wxBrushRefData();
+  M_BRUSHDATA->m_style = wxSTIPPLE;
+  M_BRUSHDATA->m_colour = *wxBLACK;
+  M_BRUSHDATA->m_stipple = stippleBitmap;
+  
+  if (wxTheBrushList) wxTheBrushList->AddBrush( this );
+};
+
+wxBrush::wxBrush( const wxBrush &brush )
+{
+  Ref( brush );
+  
+  if (wxTheBrushList) wxTheBrushList->AddBrush( this );
+};
+
+wxBrush::wxBrush( const wxBrush *brush )
+{
+  if (brush) Ref( *brush );
+  
+  if (wxTheBrushList) wxTheBrushList->Append( this );
+};
+
+wxBrush::~wxBrush(void)
+{
+  if (wxTheBrushList) wxTheBrushList->RemoveBrush( this );
+};
+
+wxBrush& wxBrush::operator = ( const wxBrush& brush )
+{
+  if (*this == brush) return (*this); 
+  Ref( brush ); 
+  return *this; 
+};
+  
+bool wxBrush::operator == ( const wxBrush& brush )
+{
+  return m_refData == brush.m_refData; 
+};
+
+bool wxBrush::operator != ( const wxBrush& brush )
+{
+  return m_refData != brush.m_refData; 
+};
+
+bool wxBrush::Ok(void) const
+{
+  return ((m_refData) && M_BRUSHDATA->m_colour.Ok());
+};
+
+int wxBrush::GetStyle(void) const
+{
+  return M_BRUSHDATA->m_style;
+};
+
+wxColour &wxBrush::GetColour(void) const
+{
+  return M_BRUSHDATA->m_colour;
+};
+
+wxBitmap *wxBrush::GetStipple(void) const
+{
+  return &M_BRUSHDATA->m_stipple;
+};
+
+
diff --git a/src/gtk1/button.cpp b/src/gtk1/button.cpp
new file mode 100644
index 0000000000..d4361f37b8
--- /dev/null
+++ b/src/gtk1/button.cpp
@@ -0,0 +1,89 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        button.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "button.h"
+#endif
+
+#include "wx/button.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxButton;
+
+//-----------------------------------------------------------------------------
+// wxButton
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxButton,wxControl)
+
+void gtk_button_clicked_callback( GtkWidget *WXUNUSED(widget), gpointer data )
+{
+  wxButton *button = (wxButton*)data;
+  wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, button->GetId());
+  event.SetEventObject(button);
+  button->ProcessEvent(event);
+};
+
+//-----------------------------------------------------------------------------
+
+wxButton::wxButton(void)
+{
+};
+
+wxButton::wxButton( wxWindow *parent, wxWindowID id, const wxString &label,
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  Create( parent, id, label, pos, size, style, name );
+};
+
+bool wxButton::Create(  wxWindow *parent, wxWindowID id, const wxString &label,
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  m_needParent = TRUE;
+  
+  wxSize newSize = size;
+
+  PreCreation( parent, id, pos, newSize, style, name );
+  
+  m_label = label;
+  m_widget = gtk_button_new_with_label( label );
+  
+  if (newSize.x == -1) newSize.x = 15+gdk_string_measure( m_widget->style->font, label );
+  if (newSize.y == -1) newSize.y = 26;
+  SetSize( newSize.x, newSize.y );
+  
+  gtk_signal_connect( GTK_OBJECT(m_widget), "clicked", 
+    GTK_SIGNAL_FUNC(gtk_button_clicked_callback), (gpointer*)this );
+
+  PostCreation();
+  
+  Show( TRUE );
+    
+  return TRUE;
+};
+      
+void wxButton::SetDefault(void)
+{
+};
+
+void wxButton::SetLabel( const wxString &label )
+{
+  wxControl::SetLabel( label );
+};
+
+wxString wxButton::GetLabel(void) const
+{
+  return wxControl::GetLabel();
+};
diff --git a/src/gtk1/cdiag.xbm b/src/gtk1/cdiag.xbm
new file mode 100644
index 0000000000..15dc7ba86d
--- /dev/null
+++ b/src/gtk1/cdiag.xbm
@@ -0,0 +1,6 @@
+#define cdiag_width 16
+#define cdiag_height 16
+static char cdiag_bits[] = {
+   0x81, 0x81, 0x42, 0x42, 0x24, 0x24, 0x18, 0x18, 0x18, 0x18, 0x24, 0x24,
+   0x42, 0x42, 0x81, 0x81, 0x81, 0x81, 0x42, 0x42, 0x24, 0x24, 0x18, 0x18,
+   0x18, 0x18, 0x24, 0x24, 0x42, 0x42, 0x81, 0x81};
diff --git a/src/gtk1/checkbox.cpp b/src/gtk1/checkbox.cpp
new file mode 100644
index 0000000000..57c712db39
--- /dev/null
+++ b/src/gtk1/checkbox.cpp
@@ -0,0 +1,84 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        checkbox.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "checkbox.h"
+#endif
+
+#include "wx/checkbox.h"
+
+//-----------------------------------------------------------------------------
+// wxCheckBox
+//-----------------------------------------------------------------------------
+
+void gtk_checkbox_clicked_callback( GtkWidget *WXUNUSED(widget), gpointer data )
+{
+  wxCheckBox *cb = (wxCheckBox*)data;
+  wxCommandEvent event(wxEVT_COMMAND_CHECKBOX_CLICKED, cb->GetId());
+  event.SetInt( cb->GetValue() );
+  event.SetEventObject(cb);
+  cb->ProcessEvent(event);
+};
+
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxCheckBox,wxControl)
+
+wxCheckBox::wxCheckBox(void)
+{
+};
+
+wxCheckBox::wxCheckBox( wxWindow *parent, wxWindowID id, const wxString &label,
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  Create( parent, id, label, pos, size, style, name );
+};
+
+bool wxCheckBox::Create(  wxWindow *parent, wxWindowID id, const wxString &label,
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  m_needParent = TRUE;
+  
+  PreCreation( parent, id, pos, size, style, name );
+
+  m_widget = gtk_check_button_new_with_label( label );
+ 
+  wxSize newSize = size;
+  if (newSize.x == -1) newSize.x = 25+gdk_string_measure( m_widget->style->font, label );
+  if (newSize.y == -1) newSize.y = 26;
+  SetSize( newSize.x, newSize.y );
+   
+  gtk_signal_connect( GTK_OBJECT(m_widget), "clicked", 
+    GTK_SIGNAL_FUNC(gtk_checkbox_clicked_callback), (gpointer*)this );
+    
+  PostCreation();
+  
+  Show( TRUE );
+    
+  return TRUE;
+};
+
+void wxCheckBox::SetValue( const bool state )
+{
+  if (state)
+    gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(m_widget), GTK_STATE_ACTIVE );
+  else
+    gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(m_widget), GTK_STATE_NORMAL );
+};
+
+bool wxCheckBox::GetValue(void) const
+{
+  GtkToggleButton *tb = GTK_TOGGLE_BUTTON(m_widget);
+  return tb->active;
+};
+
diff --git a/src/gtk1/choice.cpp b/src/gtk1/choice.cpp
new file mode 100644
index 0000000000..a7c5ff028b
--- /dev/null
+++ b/src/gtk1/choice.cpp
@@ -0,0 +1,198 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        choice.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "choice.h"
+#endif
+
+#include "wx/choice.h"
+
+//-----------------------------------------------------------------------------
+// wxChoice
+//-----------------------------------------------------------------------------
+
+void gtk_choice_clicked_callback( GtkWidget *WXUNUSED(widget), gpointer data )
+{
+  wxChoice *choice = (wxChoice*)data;
+  wxCommandEvent event(wxEVT_COMMAND_CHOICE_SELECTED, choice->GetId());
+  event.SetInt( choice->GetSelection() );
+  wxString tmp( choice->GetStringSelection() );
+  event.SetString( WXSTRINGCAST(tmp) );
+  event.SetEventObject(choice);
+  choice->ProcessEvent(event);
+};
+
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxChoice,wxWindow)
+
+wxChoice::wxChoice(void)
+{
+};
+
+wxChoice::wxChoice( wxWindow *parent, const wxWindowID id,
+      const wxPoint &pos, const wxSize &size, 
+      const int n, const wxString choices[],
+      const long style, const wxString &name )
+{
+  Create( parent, id, pos, size, n, choices, style, name );
+};
+
+bool wxChoice::Create( wxWindow *parent, const wxWindowID id,
+      const wxPoint &pos, const wxSize &size, 
+      const int n, const wxString choices[],
+      const long style, const wxString &name )
+{
+  m_needParent = TRUE;
+  
+  PreCreation( parent, id, pos, size, style, name );
+  
+  m_widget = gtk_option_menu_new();
+  
+  wxSize newSize = size;
+  if (newSize.x == -1) newSize.x = 80;
+  if (newSize.y == -1) newSize.y = 26;
+  SetSize( newSize.x, newSize.y );
+  
+  GtkWidget *menu;
+  menu = gtk_menu_new();
+  
+  for (int i = 0; i < n; i++)
+  {
+    GtkWidget *item;
+    item = gtk_menu_item_new_with_label( choices[i] );
+    gtk_signal_connect( GTK_OBJECT( item ), "activate", 
+      GTK_SIGNAL_FUNC(gtk_choice_clicked_callback), (gpointer*)this );
+    gtk_menu_append( GTK_MENU(menu), item );
+    gtk_widget_show( item );
+  };
+  gtk_option_menu_set_menu( GTK_OPTION_MENU(m_widget), menu );
+  
+  PostCreation();
+  
+  Show( TRUE );
+    
+  return TRUE;
+};
+      
+void wxChoice::Append( const wxString &item )
+{
+  GtkWidget *menu = gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) );
+  GtkWidget *menu_item;
+  menu_item = gtk_menu_item_new_with_label( item );
+  gtk_signal_connect( GTK_OBJECT( menu_item ), "activate", 
+    GTK_SIGNAL_FUNC(gtk_choice_clicked_callback), (gpointer*)this );
+  gtk_menu_append( GTK_MENU(menu), menu_item );
+  gtk_widget_show( menu_item );
+};
+ 
+void wxChoice::Clear(void)
+{
+  gtk_option_menu_remove_menu( GTK_OPTION_MENU(m_widget) );
+  GtkWidget *menu = gtk_menu_new();
+  gtk_option_menu_set_menu( GTK_OPTION_MENU(m_widget), menu );
+};
+
+int wxChoice::FindString( const wxString &string ) const
+{
+  // If you read this code once and you think you undestand
+  // it, then you are very wrong. RR
+  
+  GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
+  int count = 0;
+  GList *child = menu_shell->children;
+  while (child)
+  {
+    GtkBin *bin = GTK_BIN( child->data );
+    GtkLabel *label = GTK_LABEL(bin->child);
+    if (!label) label = GTK_LABEL( GTK_BUTTON(m_widget)->child );
+    if (string == label->label) return count;
+    child = child->next;
+    count++;
+  };
+  return -1;
+};
+
+int wxChoice::GetColumns(void) const
+{
+  return 1;
+};
+
+int wxChoice::GetSelection(void)
+{
+  GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
+  int count = 0;
+  GList *child = menu_shell->children;
+  while (child)
+  {
+    GtkBin *bin = GTK_BIN( child->data );
+    if (!bin->child) return count;
+    child = child->next;
+    count++;
+  };
+  return -1;
+};
+
+wxString wxChoice::GetString( const int n ) const
+{
+  GtkMenuShell *menu_shell = GTK_MENU_SHELL( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
+  int count = 0;
+  GList *child = menu_shell->children;
+  while (child)
+  {
+    GtkBin *bin = GTK_BIN( child->data );
+    if (count == n)
+    {
+      GtkLabel *label = GTK_LABEL(bin->child);
+      if (!label) label = GTK_LABEL( GTK_BUTTON(m_widget)->child );
+      return label->label;
+    };
+    child = child->next;
+    count++;
+  };
+  return "";
+};
+
+wxString wxChoice::GetStringSelection(void) const
+{
+  GtkLabel *label = GTK_LABEL( GTK_BUTTON(m_widget)->child );
+  return label->label;
+};
+
+int wxChoice::Number(void) const
+{
+  GtkMenu *menu = GTK_MENU( gtk_option_menu_get_menu( GTK_OPTION_MENU(m_widget) ) );
+  int count = 0;
+  GList *child = menu->children;
+  while (child)
+  {
+    count++;
+    child = child->next;
+  };
+  return count;
+};
+
+void wxChoice::SetColumns( const int WXUNUSED(n) )
+{
+};
+
+void wxChoice::SetSelection( const int n )
+{
+  int tmp = n;
+  gtk_option_menu_set_history( GTK_OPTION_MENU(m_widget), (gint)tmp );
+};
+
+void wxChoice::SetStringSelection( const wxString &string )
+{
+  int n = FindString( string );
+  if (n != -1) SetSelection( n );
+};
+
diff --git a/src/gtk1/colour.cpp b/src/gtk1/colour.cpp
new file mode 100644
index 0000000000..ba970a79ba
--- /dev/null
+++ b/src/gtk1/colour.cpp
@@ -0,0 +1,225 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        colour.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "colour.h"
+#endif
+
+#include "wx/gdicmn.h"
+
+#ifdef USE_GDK_IMLIB
+#include "gdk_imlib.h"
+#endif
+
+//-----------------------------------------------------------------------------
+// wxColour
+//-----------------------------------------------------------------------------
+
+class wxColourRefData: public wxObjectRefData
+{
+  public:
+  
+    wxColourRefData(void);
+    ~wxColourRefData(void);
+    void FreeColour(void);
+  
+    GdkColor     m_color;
+    GdkColormap *m_colormap;
+    bool         m_hasPixel;
+    
+    friend wxColour;
+};
+
+wxColourRefData::wxColourRefData(void)
+{
+  m_color.red = 0;
+  m_color.green = 0;
+  m_color.blue = 0;
+  m_color.pixel = 0;
+  m_colormap = NULL;
+  m_hasPixel = FALSE;
+};
+
+wxColourRefData::~wxColourRefData(void)
+{
+  FreeColour();
+};
+
+void wxColourRefData::FreeColour(void)
+{
+//  if (m_hasPixel) gdk_colors_free( m_colormap, &m_color, 1, 0 );
+};
+
+//-----------------------------------------------------------------------------
+
+#define M_COLDATA ((wxColourRefData *)m_refData)
+
+#define SHIFT (8*(sizeof(short int)-sizeof(char)))
+
+IMPLEMENT_DYNAMIC_CLASS(wxColour,wxGDIObject)
+
+wxColour::wxColour(void)
+{
+};
+
+wxColour::wxColour( char red, char green, char blue )
+{
+  m_refData = new wxColourRefData();
+  M_COLDATA->m_color.red = ((unsigned short)red) << SHIFT;
+  M_COLDATA->m_color.green = ((unsigned short)green) << SHIFT;
+  M_COLDATA->m_color.blue = ((unsigned short)blue) << SHIFT;
+  M_COLDATA->m_color.pixel = 0;
+};
+  
+wxColour::wxColour( const wxString &colourName )
+{
+  wxNode *node = NULL;
+  if ( (wxTheColourDatabase) && (node = wxTheColourDatabase->Find(colourName)) ) 
+  {
+    wxColour *col = (wxColour*)node->Data();
+    UnRef();
+    if (col) Ref( *col );
+  } 
+  else 
+  {
+    m_refData = new wxColourRefData();
+    if (!gdk_color_parse( colourName, &M_COLDATA->m_color ))
+    {
+      delete m_refData;
+      m_refData = NULL;
+    };
+  };
+};
+
+wxColour::wxColour( const wxColour& col )
+{ 
+  Ref( col ); 
+};
+
+wxColour::wxColour( const wxColour* col ) 
+{ 
+  if (col) Ref( *col ); 
+};
+
+wxColour::~wxColour(void)
+{
+};
+
+wxColour& wxColour::operator = ( const wxColour& col ) 
+{ 
+  if (*this == col) return (*this); 
+  Ref( col ); 
+  return *this; 
+};
+
+wxColour& wxColour::operator = ( const wxString& colourName ) 
+{ 
+  UnRef();
+  wxNode *node = NULL;
+  if ((wxTheColourDatabase) && (node = wxTheColourDatabase->Find(colourName)) ) 
+  {
+    wxColour *col = (wxColour*)node->Data();
+    if (col) Ref( *col );
+  } 
+  else 
+  {
+    m_refData = new wxColourRefData();
+    if (!gdk_color_parse( colourName, &M_COLDATA->m_color ))
+    {
+      delete m_refData;
+      m_refData = NULL;
+    };
+  };
+  return *this; 
+};
+
+bool wxColour::operator == ( const wxColour& col ) 
+{ 
+  return m_refData == col.m_refData; 
+};
+
+bool wxColour::operator != ( const wxColour& col) 
+{ 
+  return m_refData != col.m_refData; 
+};
+
+void wxColour::Set( const unsigned char red, const unsigned char green, const unsigned char blue )
+{
+  UnRef();
+  m_refData = new wxColourRefData();
+  M_COLDATA->m_color.red = ((unsigned short)red) << SHIFT;
+  M_COLDATA->m_color.green = ((unsigned short)green) << SHIFT;
+  M_COLDATA->m_color.blue = ((unsigned short)blue) << SHIFT;
+  M_COLDATA->m_color.pixel = 0;
+};
+
+unsigned char wxColour::Red(void) const
+{
+  if (!Ok()) return 0;
+  return (unsigned char)(M_COLDATA->m_color.red >> SHIFT);
+};
+
+unsigned char wxColour::Green(void) const
+{
+  if (!Ok()) return 0;
+  return (unsigned char)(M_COLDATA->m_color.green >> SHIFT);
+};
+
+unsigned char wxColour::Blue(void) const
+{
+  if (!Ok()) return 0;
+  return (unsigned char)(M_COLDATA->m_color.blue >> SHIFT);
+};
+
+bool wxColour::Ok(void) const
+{
+  return (m_refData);
+};
+
+void wxColour::CalcPixel( GdkColormap *cmap )
+{
+  if (!Ok()) return;
+  
+  if ((M_COLDATA->m_hasPixel) && (M_COLDATA->m_colormap == cmap)) return;
+  M_COLDATA->FreeColour();
+  
+#ifdef USE_GDK_IMLIB
+
+  int r = M_COLDATA->m_color.red >> SHIFT;
+  int g = M_COLDATA->m_color.green >> SHIFT;
+  int b = M_COLDATA->m_color.blue >> SHIFT;
+  M_COLDATA->m_hasPixel = TRUE;
+  M_COLDATA->m_color.pixel = gdk_imlib_best_color_match( &r, &g, &b );
+
+#else
+
+  M_COLDATA->m_hasPixel = gdk_color_alloc( cmap, &M_COLDATA->m_color );
+  
+#endif
+  
+  M_COLDATA->m_colormap = cmap;
+};
+
+int wxColour::GetPixel(void)
+{
+  if (!Ok()) return 0;
+  
+  return M_COLDATA->m_color.pixel;
+};
+
+GdkColor *wxColour::GetColor(void)
+{
+  if (!Ok()) return NULL;
+  
+  return &M_COLDATA->m_color;
+};
+
+
diff --git a/src/gtk1/control.cpp b/src/gtk1/control.cpp
new file mode 100644
index 0000000000..510d88d0e9
--- /dev/null
+++ b/src/gtk1/control.cpp
@@ -0,0 +1,51 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        control.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "control.h"
+#endif
+
+#include "wx/control.h"
+
+//-----------------------------------------------------------------------------
+// wxControl
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxControl,wxWindow)
+
+wxControl::wxControl(void)
+{
+  m_label = "";
+  m_needParent = TRUE;
+};
+
+wxControl::wxControl( wxWindow *parent, wxWindowID id, 
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name ) :
+  wxWindow( parent, id, pos, size, style, name )
+{
+};
+
+void wxControl::Command( wxCommandEvent &WXUNUSED(event) )
+{
+};
+
+void wxControl::SetLabel( const wxString &label )
+{
+  m_label = label;
+};
+
+wxString wxControl::GetLabel(void) const
+{
+  return m_label;
+};
+
+
+
diff --git a/src/gtk1/cross.xbm b/src/gtk1/cross.xbm
new file mode 100644
index 0000000000..b07cbe7fcd
--- /dev/null
+++ b/src/gtk1/cross.xbm
@@ -0,0 +1,6 @@
+#define cross_width 15
+#define cross_height 15
+static char cross_bits[] = {
+   0x84, 0x10, 0x84, 0x10, 0xff, 0x7f, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10,
+   0x84, 0x10, 0xff, 0x7f, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10,
+   0xff, 0x7f, 0x84, 0x10, 0x84, 0x10};
diff --git a/src/gtk1/cursor.cpp b/src/gtk1/cursor.cpp
new file mode 100644
index 0000000000..bb0888bdcb
--- /dev/null
+++ b/src/gtk1/cursor.cpp
@@ -0,0 +1,173 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        cursor.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "cursor.h"
+#endif
+
+#include "wx/cursor.h"
+
+//-----------------------------------------------------------------------------
+// wxCursor
+//-----------------------------------------------------------------------------
+
+class wxCursorRefData: public wxObjectRefData
+{
+  public:
+  
+    wxCursorRefData(void);
+    ~wxCursorRefData(void);
+  
+    GdkCursor *m_cursor;
+};
+
+wxCursorRefData::wxCursorRefData(void)
+{
+  m_cursor = NULL;
+};
+
+wxCursorRefData::~wxCursorRefData(void)
+{
+  if (m_cursor) gdk_cursor_destroy( m_cursor );
+};
+
+//-----------------------------------------------------------------------------
+
+#define M_CURSORDATA ((wxCursorRefData *)m_refData)
+
+IMPLEMENT_DYNAMIC_CLASS(wxCursor,wxObject)
+
+wxCursor::wxCursor(void)
+{
+};
+
+wxCursor::wxCursor( const int cursorId )
+{
+  m_refData = new wxCursorRefData();
+  
+  GdkCursorType gdk_cur = GDK_LEFT_PTR;
+  switch (cursorId)
+  {
+    case wxCURSOR_HAND:       gdk_cur = GDK_HAND1; break;
+    case wxCURSOR_CROSS:      gdk_cur = GDK_CROSSHAIR; break;
+    case wxCURSOR_SIZEWE:     gdk_cur = GDK_SB_H_DOUBLE_ARROW; break;
+    case wxCURSOR_SIZENS:     gdk_cur = GDK_SB_V_DOUBLE_ARROW; break;
+    case wxCURSOR_WAIT:       gdk_cur = GDK_WATCH; break;
+    case wxCURSOR_WATCH:      gdk_cur = GDK_WATCH; break;
+    case wxCURSOR_SIZING:     gdk_cur = GDK_SIZING; break;
+    case wxCURSOR_SPRAYCAN:   gdk_cur = GDK_SPRAYCAN; break;
+    case wxCURSOR_IBEAM:      gdk_cur = GDK_XTERM; break;
+    case wxCURSOR_PENCIL:     gdk_cur = GDK_PENCIL; break;
+    case wxCURSOR_NO_ENTRY:   gdk_cur = GDK_PIRATE; break;
+  };
+  
+  M_CURSORDATA->m_cursor = gdk_cursor_new( gdk_cur );
+  
+/*
+  do that yourself
+   
+  wxCURSOR_BULLSEYE,
+  wxCURSOR_CHAR,
+  wxCURSOR_LEFT_BUTTON,
+  wxCURSOR_MAGNIFIER,
+  wxCURSOR_MIDDLE_BUTTON,
+  wxCURSOR_NO_ENTRY,
+  wxCURSOR_PAINT_BRUSH,
+  wxCURSOR_POINT_LEFT,
+  wxCURSOR_POINT_RIGHT,
+  wxCURSOR_QUESTION_ARROW,
+  wxCURSOR_RIGHT_BUTTON,
+  wxCURSOR_SIZENESW,
+  wxCURSOR_SIZENS,
+  wxCURSOR_SIZENWSE,
+  wxCURSOR_SIZEWE,
+  wxCURSOR_BLANK
+,
+  wxCURSOR_CROSS_REVERSE,
+  wxCURSOR_DOUBLE_ARROW,
+  wxCURSOR_BASED_ARROW_UP,
+  wxCURSOR_BASED_ARROW_DOWN
+*/
+   
+};
+
+wxCursor::wxCursor( const wxCursor &cursor )
+{
+  Ref( cursor );
+};
+
+wxCursor::wxCursor( const wxCursor *cursor )
+{
+  UnRef();
+  if (cursor) Ref( *cursor );
+};
+
+wxCursor::~wxCursor(void)
+{
+};
+
+wxCursor& wxCursor::operator = ( const wxCursor& cursor )
+{
+  if (*this == cursor) return (*this); 
+  Ref( cursor ); 
+  return *this; 
+};
+
+bool wxCursor::operator == ( const wxCursor& cursor )
+{
+  return m_refData == cursor.m_refData; 
+};
+
+bool wxCursor::operator != ( const wxCursor& cursor )
+{
+  return m_refData != cursor.m_refData; 
+};
+
+bool wxCursor::Ok(void) const
+{
+  return TRUE;
+};
+
+GdkCursor *wxCursor::GetCursor(void) const
+{
+  return M_CURSORDATA->m_cursor;
+};
+
+//-----------------------------------------------------------------------------
+// busy cursor routines
+//-----------------------------------------------------------------------------
+
+bool g_isBusy = FALSE;
+
+void wxEndBusyCursor(void)
+{
+  g_isBusy = FALSE;
+};
+
+void wxBeginBusyCursor( wxCursor *WXUNUSED(cursor) )
+{
+  g_isBusy = TRUE;
+};
+
+bool wxIsBusy(void)
+{
+  return g_isBusy;
+};
+
+void wxSetCursor( const wxCursor& cursor )
+{
+  extern wxCursor *g_globalCursor;
+  if (g_globalCursor) (*g_globalCursor) = cursor;
+
+  if (cursor.Ok()) {};
+};
+
+
diff --git a/src/gtk1/data.cpp b/src/gtk1/data.cpp
new file mode 100644
index 0000000000..cd3124b47f
--- /dev/null
+++ b/src/gtk1/data.cpp
@@ -0,0 +1,705 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        data.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+// #pragma implementation
+#endif
+
+#include "wx/wx.h"
+
+#define _MAXPATHLEN 500
+
+// Used for X resources
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xresource.h>
+
+wxList wxResourceCache(wxKEY_STRING);
+XrmDatabase wxResourceDatabase;
+
+// Useful buffer, initialized in wxCommonInit
+char *wxBuffer = NULL;
+
+// Windows List
+wxList wxTopLevelWindows;
+
+// List of windows pending deletion
+wxList wxPendingDelete;
+
+// Current cursor, in order to hang on to
+// cursor handle when setting the cursor globally
+wxCursor *g_globalCursor = NULL;
+
+// Don't allow event propagation during drag
+bool g_blockEventsOnDrag = FALSE;
+
+// Message Strings for Internationalization
+char **wx_msg_str = (char**)NULL;
+
+// Custom OS version, as optionally placed in wx.ini/.wxrc
+// Currently this can be Win95, Windows, Win32s, WinNT.
+// For some systems, you can't tell until run-time what services you
+// have. See wxGetOsVersion, which uses this string if present.
+char *wxOsVersion = NULL;
+
+// For printing several pages
+int wxPageNumber;
+wxPrintPaperDatabase* wxThePrintPaperDatabase = NULL;
+
+// GDI Object Lists
+wxBrushList      *wxTheBrushList = NULL;
+wxPenList        *wxThePenList = NULL;
+wxFontList       *wxTheFontList = NULL;
+wxColourDatabase *wxTheColourDatabase = NULL;
+wxBitmapList   *wxTheBitmapList = NULL;
+  
+
+// X only font names
+wxFontNameDirectory wxTheFontNameDirectory;
+
+// Stock objects
+wxFont *wxNORMAL_FONT;
+wxFont *wxSMALL_FONT;
+wxFont *wxITALIC_FONT;
+wxFont *wxSWISS_FONT;
+
+wxPen *wxRED_PEN;
+wxPen *wxCYAN_PEN;
+wxPen *wxGREEN_PEN;
+wxPen *wxBLACK_PEN;
+wxPen *wxWHITE_PEN;
+wxPen *wxTRANSPARENT_PEN;
+wxPen *wxBLACK_DASHED_PEN;
+wxPen *wxGREY_PEN;
+wxPen *wxMEDIUM_GREY_PEN;
+wxPen *wxLIGHT_GREY_PEN;
+
+wxBrush *wxBLUE_BRUSH;
+wxBrush *wxGREEN_BRUSH;
+wxBrush *wxWHITE_BRUSH;
+wxBrush *wxBLACK_BRUSH;
+wxBrush *wxTRANSPARENT_BRUSH;
+wxBrush *wxCYAN_BRUSH;
+wxBrush *wxRED_BRUSH;
+wxBrush *wxGREY_BRUSH;
+wxBrush *wxMEDIUM_GREY_BRUSH;
+wxBrush *wxLIGHT_GREY_BRUSH;
+
+wxColour *wxBLACK;
+wxColour *wxWHITE;
+wxColour *wxGREY;            // Robert Roebling
+wxColour *wxRED;
+wxColour *wxBLUE;
+wxColour *wxGREEN;
+wxColour *wxCYAN;
+wxColour *wxLIGHT_GREY;
+
+wxCursor *wxSTANDARD_CURSOR = NULL;
+wxCursor *wxHOURGLASS_CURSOR = NULL;
+wxCursor *wxCROSS_CURSOR = NULL;
+
+// 'Null' objects
+wxBitmap wxNullBitmap;
+wxIcon   wxNullIcon;  
+wxCursor wxNullCursor;
+wxPen    wxNullPen;
+wxBrush  wxNullBrush;
+wxFont   wxNullFont;
+wxColour wxNullColour;
+wxPalette wxNullPalette; 
+
+// Default window names
+const char *wxButtonNameStr = "button";
+const char *wxCanvasNameStr = "canvas";
+const char *wxCheckBoxNameStr = "check";
+const char *wxChoiceNameStr = "choice";
+const char *wxComboBoxNameStr = "comboBox";
+const char *wxDialogNameStr = "dialog";
+const char *wxFrameNameStr = "frame";
+const char *wxGaugeNameStr = "gauge";
+const char *wxStaticBoxNameStr = "groupBox";
+const char *wxListBoxNameStr = "listBox";
+const char *wxStaticTextNameStr = "message";
+const char *wxStaticBitmapNameStr = "message";
+const char *wxMultiTextNameStr = "multitext";
+const char *wxPanelNameStr = "panel";
+const char *wxRadioBoxNameStr = "radioBox";
+const char *wxRadioButtonNameStr = "radioButton";
+const char *wxBitmapRadioButtonNameStr = "radioButton";
+const char *wxScrollBarNameStr = "scrollBar";
+const char *wxSliderNameStr = "slider";
+const char *wxStaticNameStr = "static";
+const char *wxTextCtrlWindowNameStr = "textWindow";
+const char *wxTextCtrlNameStr = "text";
+const char *wxVirtListBoxNameStr = "virtListBox";
+const char *wxButtonBarNameStr = "buttonbar";
+const char *wxEnhDialogNameStr = "Shell";
+const char *wxToolBarNameStr = "toolbar";
+const char *wxStatusLineNameStr = "status_line";
+const char *wxEmptyString = "";
+const char *wxGetTextFromUserPromptStr = "Input Text";
+const char *wxMessageBoxCaptionStr = "Message";
+const char *wxFileSelectorPromptStr = "Select a file";
+const char *wxFileSelectorDefaultWildcardStr = "*.*";
+const char *wxInternalErrorStr = "wxWindows Internal Error";
+const char *wxFatalErrorStr = "wxWindows Fatal Error";
+
+// See wx/utils.h
+const char *wxFloatToStringStr = "%.2f";
+const char *wxDoubleToStringStr = "%.2f";
+
+#ifdef wx_msw
+const char *wxUserResourceStr = "TEXT";
+#endif
+
+
+#if USE_SHARED_LIBRARY
+/*
+ * For wxWindows to be made into a dynamic library (e.g. Sun),
+ * all IMPLEMENT_... macros must be in one place.
+ * But normally, the definitions are in the appropriate places.
+ */
+
+// Hand-coded IMPLEMENT... macro for wxObject (define static data)
+wxClassInfo wxObject::classwxObject("wxObject", NULL, NULL, sizeof(wxObject), NULL);
+wxClassInfo *wxClassInfo::first = NULL;
+
+#include "wx/button.h"
+#include "wx/bmpbuttn.h"
+IMPLEMENT_DYNAMIC_CLASS(wxButton, wxControl)
+IMPLEMENT_DYNAMIC_CLASS(wxBitmapButton, wxButton)
+
+#include "wx/checkbox.h"
+IMPLEMENT_DYNAMIC_CLASS(wxCheckBox, wxControl)
+IMPLEMENT_DYNAMIC_CLASS(wxBitmapCheckBox, wxCheckBox)
+
+#include "wx/choice.h"
+IMPLEMENT_DYNAMIC_CLASS(wxChoice, wxControl)
+
+#if USE_CLIPBOARD
+#include "wx/clipbrd.h"
+IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject)
+IMPLEMENT_ABSTRACT_CLASS(wxClipboardClient, wxObject)
+#endif
+
+#if USE_COMBOBOX
+#include "wx/combobox.h"
+IMPLEMENT_DYNAMIC_CLASS(wxComboBox, wxControl)
+#endif
+
+#include "wx/dc.h"
+#include "wx/dcmemory.h"
+#include "wx/dcclient.h"
+#include "wx/dcscreen.h"
+IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxDC)
+IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC)
+IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxDC)
+IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC, wxDC)
+IMPLEMENT_DYNAMIC_CLASS(wxScreenDC, wxWindowDC)
+
+#if defined(wx_msw)
+#include "wx/dcprint.h"
+IMPLEMENT_CLASS(wxPrinterDC, wxDC)
+#endif
+
+#include "wx/dialog.h"
+IMPLEMENT_DYNAMIC_CLASS(wxDialog, wxWindow)
+
+#include "wx/frame.h"
+IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow)
+
+#include "wx/mdi.h"
+IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame, wxFrame)
+IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame, wxFrame)
+IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxWindow)
+
+#include "wx/cmndata.h"
+IMPLEMENT_DYNAMIC_CLASS(wxColourData, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxFontData, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxPrintData, wxObject)
+
+#include "wx/colordlg.h"
+#include "wx/fontdlg.h"
+
+#if !defined(wx_msw) || USE_GENERIC_DIALOGS_IN_MSW
+#include "wx/generic/colordlg.h"
+#include "wx/generic/fontdlg.h"
+IMPLEMENT_DYNAMIC_CLASS(wxGenericColourDialog, wxDialog)
+IMPLEMENT_DYNAMIC_CLASS(wxGenericFontDialog, wxDialog)
+#endif
+
+// X defines wxColourDialog to be wxGenericColourDialog
+#ifndef wx_x
+IMPLEMENT_DYNAMIC_CLASS(wxColourDialog, wxDialog)
+IMPLEMENT_DYNAMIC_CLASS(wxFontDialog, wxDialog)
+#endif
+
+#include "wx/gdicmn.h"
+#include "wx/pen.h"
+#include "wx/brush.h"
+#include "wx/font.h"
+#include "wx/palette.h"
+#include "wx/icon.h"
+#include "wx/cursor.h"
+
+IMPLEMENT_DYNAMIC_CLASS(wxColour, wxObject)
+IMPLEMENT_CLASS(wxColourDatabase, wxList)
+IMPLEMENT_DYNAMIC_CLASS(wxFontList, wxList)
+IMPLEMENT_DYNAMIC_CLASS(wxPenList, wxList)
+IMPLEMENT_DYNAMIC_CLASS(wxBrushList, wxList)
+IMPLEMENT_DYNAMIC_CLASS(wxBitmapList, wxList)
+
+#if (!USE_TYPEDEFS)
+IMPLEMENT_DYNAMIC_CLASS(wxPoint, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxIntPoint, wxObject)
+#endif
+
+#if defined(wx_x) || (defined(wx_msw) && USE_PORTABLE_FONTS_IN_MSW)
+IMPLEMENT_DYNAMIC_CLASS(wxFontNameDirectory, wxObject)
+#endif
+
+#include "wx/hash.h"
+IMPLEMENT_DYNAMIC_CLASS(wxHashTable, wxObject)
+
+#include "wx/help.h"
+IMPLEMENT_DYNAMIC_CLASS(wxHelpInstance, wxClient)
+IMPLEMENT_CLASS(wxHelpConnection, wxConnection)
+
+#include "wx/list.h"
+IMPLEMENT_DYNAMIC_CLASS(wxNode, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxList, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxStringList, wxList)
+
+#if USE_PRINTING_ARCHITECTURE
+#include "wx/print.h"
+IMPLEMENT_DYNAMIC_CLASS(wxPrintDialog, wxDialog)
+IMPLEMENT_DYNAMIC_CLASS(wxPrinterBase, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxPostScriptPrinter, wxPrinterBase)
+IMPLEMENT_DYNAMIC_CLASS(wxWindowsPrinter, wxPrinterBase)
+IMPLEMENT_ABSTRACT_CLASS(wxPrintout, wxObject)
+IMPLEMENT_CLASS(wxPreviewCanvas, wxWindow)
+IMPLEMENT_CLASS(wxPreviewControlBar, wxWindow)
+IMPLEMENT_CLASS(wxPreviewFrame, wxFrame)
+IMPLEMENT_CLASS(wxPrintPreviewBase, wxObject)
+IMPLEMENT_CLASS(wxPostScriptPrintPreview, wxPrintPreviewBase)
+IMPLEMENT_CLASS(wxWindowsPrintPreview, wxPrintPreviewBase)
+IMPLEMENT_CLASS(wxGenericPrintDialog, wxDialog)
+IMPLEMENT_CLASS(wxGenericPrintSetupDialog, wxDialog)
+#endif
+
+#if USE_POSTSCRIPT
+#include "wx/postscrp.h"
+IMPLEMENT_DYNAMIC_CLASS(wxPostScriptDC, wxDC)
+IMPLEMENT_DYNAMIC_CLASS(wxPrintSetupData, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxPageSetupData, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxPrintPaperType, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxPrintPaperDatabase, wxList)
+#endif
+
+#if USE_WX_RESOURCES
+#include "wx/resource.h"
+IMPLEMENT_DYNAMIC_CLASS(wxItemResource, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxResourceTable, wxHashTable)
+#endif
+
+#include "wx/event.h"
+IMPLEMENT_DYNAMIC_CLASS(wxEvtHandler, wxObject)
+IMPLEMENT_ABSTRACT_CLASS(wxEvent, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxCommandEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxScrollEvent, wxCommandEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxMouseEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxKeyEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxSizeEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxPaintEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxEraseEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxMoveEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxFocusEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxCloseEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxMenuEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxJoystickEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxDropFilesEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxActivateEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxInitDialogEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxSysColourChangedEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxIdleEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxUpdateUIEvent, wxEvent)
+
+#include "wx/utils.h"
+IMPLEMENT_DYNAMIC_CLASS(wxPathList, wxList)
+
+IMPLEMENT_DYNAMIC_CLASS(wxRect, wxObject)
+
+#if USE_TIMEDATE
+#include "wx/date.h"
+IMPLEMENT_DYNAMIC_CLASS(wxDate, wxObject)
+#endif
+
+#if USE_DOC_VIEW_ARCHITECTURE
+#include "wx/docview.h"
+//IMPLEMENT_ABSTRACT_CLASS(wxDocItem, wxObject)
+IMPLEMENT_ABSTRACT_CLASS(wxDocument, wxEvtHandler)
+IMPLEMENT_ABSTRACT_CLASS(wxView, wxEvtHandler)
+IMPLEMENT_ABSTRACT_CLASS(wxDocTemplate, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxDocManager, wxEvtHandler)
+IMPLEMENT_CLASS(wxDocChildFrame, wxFrame)
+IMPLEMENT_CLASS(wxDocParentFrame, wxFrame)
+#if USE_PRINTING_ARCHITECTURE
+IMPLEMENT_DYNAMIC_CLASS(wxDocPrintout, wxPrintout)
+#endif
+IMPLEMENT_CLASS(wxCommand, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxCommandProcessor, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxFileHistory, wxObject)
+#endif
+
+#if USE_CONSTRAINTS
+#include "wx/layout.h"
+IMPLEMENT_DYNAMIC_CLASS(wxIndividualLayoutConstraint, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxLayoutConstraints, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxSizer, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxRowColSizer, wxSizer)
+#endif
+
+#if USE_TOOLBAR
+#include "wx/tbarbase.h"
+IMPLEMENT_DYNAMIC_CLASS(wxToolBarTool, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxToolBarBase, wxControl)
+
+#include "wx/tbarsmpl.h"
+IMPLEMENT_DYNAMIC_CLASS(wxToolBarSimple, wxToolBarBase)
+
+#ifdef wx_msw
+#include "wx/tbarmsw.h"
+IMPLEMENT_DYNAMIC_CLASS(wxToolBarMSW, wxToolBarBase)
+
+#include "wx/tbar95.h"
+IMPLEMENT_DYNAMIC_CLASS(wxToolBar95, wxToolBarBase)
+#endif
+
+#endif
+
+#include "wx/statusbr.h"
+
+IMPLEMENT_DYNAMIC_CLASS(wxStatusBar, wxWindow)
+
+BEGIN_EVENT_TABLE(wxStatusBar, wxWindow)
+	EVT_PAINT(wxStatusBar::OnPaint)
+    EVT_SYS_COLOUR_CHANGED(wxStatusBar::OnSysColourChanged)
+END_EVENT_TABLE()
+
+#if USE_TIMEDATE
+#include "wx/time.h"
+IMPLEMENT_DYNAMIC_CLASS(wxTime, wxObject)
+#endif
+
+#if !USE_GNU_WXSTRING
+#include "wx/string.h"
+IMPLEMENT_DYNAMIC_CLASS(wxString, wxObject)
+#endif
+
+#ifdef wx_motif
+IMPLEMENT_DYNAMIC_CLASS(wxXColormap, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxXFont, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxXCursor, wxObject)
+#endif
+IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
+IMPLEMENT_DYNAMIC_CLASS(wxPalette, wxGDIObject)
+IMPLEMENT_DYNAMIC_CLASS(wxPen, wxGDIObject)
+IMPLEMENT_DYNAMIC_CLASS(wxBrush, wxGDIObject)
+IMPLEMENT_DYNAMIC_CLASS(wxIcon, wxBitmap)
+IMPLEMENT_DYNAMIC_CLASS(wxCursor, wxBitmap)
+IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
+IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
+
+// This will presumably be implemented on other platforms too
+#ifdef wx_msw
+IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
+IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler)
+IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler, wxBitmapHandler)
+IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler, wxBitmapHandler)
+IMPLEMENT_DYNAMIC_CLASS(wxICOFileHandler, wxBitmapHandler)
+IMPLEMENT_DYNAMIC_CLASS(wxICOResourceHandler, wxBitmapHandler)
+#endif
+
+#include "wx/statbox.h"
+IMPLEMENT_DYNAMIC_CLASS(wxStaticBox, wxControl)
+
+#if USE_IPC
+#include "wx/dde.h"
+IMPLEMENT_ABSTRACT_CLASS(wxDDEObject, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxDDEServer, wxDDEObject)
+IMPLEMENT_DYNAMIC_CLASS(wxDDEClient, wxDDEObject)
+IMPLEMENT_CLASS(wxDDEConnection, wxObject)
+#endif
+
+IMPLEMENT_ABSTRACT_CLASS(wxControl, wxWindow)
+
+#include "wx/listbox.h"
+IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl)
+
+IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
+
+#include "wx/menu.h"
+IMPLEMENT_DYNAMIC_CLASS(wxMenu, wxWindow)
+IMPLEMENT_DYNAMIC_CLASS(wxMenuItem, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxMenuBar, wxWindow)
+
+#include "wx/stattext.h"
+#include "wx/statbmp.h"
+IMPLEMENT_DYNAMIC_CLASS(wxStaticText, wxControl)
+IMPLEMENT_DYNAMIC_CLASS(wxStaticBitmap, wxControl)
+
+#if USE_METAFILE
+#include "wx/metafile.h"
+IMPLEMENT_DYNAMIC_CLASS(wxMetaFile, wxObject)
+IMPLEMENT_ABSTRACT_CLASS(wxMetaFileDC, wxDC)
+#endif
+
+#include "wx/radiobox.h"
+#include "wx/radiobut.h"
+IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl)
+
+IMPLEMENT_DYNAMIC_CLASS(wxRadioButton, wxControl)
+// IMPLEMENT_DYNAMIC_CLASS(wxBitmapRadioButton, wxRadioButton)
+
+#include "wx/scrolbar.h"
+IMPLEMENT_DYNAMIC_CLASS(wxScrollBar, wxControl)
+
+#if WXWIN_COMPATIBILITY
+BEGIN_EVENT_TABLE(wxScrollBar, wxControl)
+  EVT_SCROLL(wxScrollBar::OnScroll)
+END_EVENT_TABLE()
+#endif
+
+#include "wx/slider.h"
+IMPLEMENT_DYNAMIC_CLASS(wxSlider, wxControl)
+
+#if WXWIN_COMPATIBILITY
+BEGIN_EVENT_TABLE(wxSlider, wxControl)
+  EVT_SCROLL(wxSlider::OnScroll)
+END_EVENT_TABLE()
+#endif
+
+#include "wx/timer.h"
+IMPLEMENT_ABSTRACT_CLASS(wxTimer, wxObject)
+
+#include "wx/textctrl.h"
+IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
+
+#include "wx/window.h"
+IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxEvtHandler)
+
+#include "wx/scrolwin.h"
+IMPLEMENT_DYNAMIC_CLASS(wxScrolledWindow, wxWindow)
+
+#include "wx/panel.h"
+IMPLEMENT_DYNAMIC_CLASS(wxPanel, wxWindow)
+
+#include "wx/msgbxdlg.h"
+#include "wx/textdlg.h"
+#include "wx/filedlg.h"
+#include "wx/dirdlg.h"
+#include "wx/choicdlg.h"
+
+#if !defined(wx_msw) || USE_GENERIC_DIALOGS_IN_MSW
+#include "wx/generic/msgdlgg.h"
+IMPLEMENT_CLASS(wxGenericMessageDialog, wxDialog)
+#endif
+
+IMPLEMENT_CLASS(wxTextEntryDialog, wxDialog)
+IMPLEMENT_CLASS(wxSingleChoiceDialog, wxDialog)
+IMPLEMENT_CLASS(wxFileDialog, wxDialog)
+IMPLEMENT_CLASS(wxDirDialog, wxDialog)
+
+#ifdef wx_msw
+IMPLEMENT_CLASS(wxMessageDialog)
+#endif
+
+#if USE_GAUGE
+#ifdef wx_motif
+#include "../../contrib/xmgauge/gauge.h"
+#endif
+#include "wx_gauge.h"
+IMPLEMENT_DYNAMIC_CLASS(wxGauge, wxControl)
+#endif
+
+#include "wx/grid.h"
+IMPLEMENT_DYNAMIC_CLASS(wxGenericGrid, wxPanel)
+
+///// Event tables (also must be in one, statically-linked file for shared libraries)
+
+// This is the base, wxEvtHandler 'bootstrap' code which is expanded manually here
+const wxEventTable *wxEvtHandler::GetEventTable() const { return &wxEvtHandler::sm_eventTable; }
+
+const wxEventTable wxEvtHandler::sm_eventTable =
+	{ NULL, &wxEvtHandler::sm_eventTableEntries[0] };
+
+const wxEventTableEntry wxEvtHandler::sm_eventTableEntries[] = { { 0, 0, 0, NULL } };
+
+BEGIN_EVENT_TABLE(wxFrame, wxWindow)
+	EVT_ACTIVATE(wxFrame::OnActivate)
+	EVT_SIZE(wxFrame::OnSize)
+	EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight)
+    EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged)
+    EVT_IDLE(wxFrame::OnIdle)
+    EVT_CLOSE(wxFrame::OnCloseWindow)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxDialog, wxPanel)
+  EVT_BUTTON(wxID_OK, wxDialog::OnOK)
+  EVT_BUTTON(wxID_APPLY, wxDialog::OnApply)
+  EVT_BUTTON(wxID_CANCEL, wxDialog::OnCancel)
+  EVT_CHAR_HOOK(wxDialog::OnCharHook)
+  EVT_SYS_COLOUR_CHANGED(wxDialog::OnSysColourChanged)
+  EVT_CLOSE(wxDialog::OnCloseWindow)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxWindow, wxEvtHandler)
+  EVT_CHAR(wxWindow::OnChar)
+  EVT_SIZE(wxWindow::Size)
+  EVT_ERASE_BACKGROUND(wxWindow::OnEraseBackground)
+  EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged)
+  EVT_INIT_DIALOG(wxWindow::OnInitDialog)
+  EVT_IDLE(wxWindow::OnIdle)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxScrolledWindow, wxWindow)
+  EVT_SCROLL(wxScrolledWindow::OnScroll)
+  EVT_SIZE(wxScrolledWindow::OnSize)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxPanel, wxWindow)
+  EVT_SYS_COLOUR_CHANGED(wxPanel::OnSysColourChanged)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
+	EVT_CHAR(wxTextCtrl::OnChar)
+	EVT_DROP_FILES(wxTextCtrl::OnDropFiles)
+	EVT_ERASE_BACKGROUND(wxTextCtrl::OnEraseBackground)
+END_EVENT_TABLE()
+
+#ifdef wx_msw
+BEGIN_EVENT_TABLE(wxMDIParentWindow, wxFrame)
+  EVT_SIZE(wxMDIParentWindow::OnSize)
+  EVT_ACTIVATE(wxMDIParentWindow::OnActivate)
+  EVT_SYS_COLOUR_CHANGED(wxMDIParentWindow::OnSysColourChanged)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxMDIClientWindow, wxWindow)
+  EVT_SCROLL(wxMDIClientWindow::OnScroll)
+END_EVENT_TABLE()
+#endif
+
+BEGIN_EVENT_TABLE(wxToolBarBase, wxControl)
+  EVT_SCROLL(wxToolBarBase::OnScroll)
+  EVT_SIZE(wxToolBarBase::OnSize)
+  EVT_IDLE(wxToolBarBase::OnIdle)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxToolBarSimple, wxToolBarBase)
+	EVT_SIZE(wxToolBarSimple::OnSize)
+	EVT_PAINT(wxToolBarSimple::OnPaint)
+	EVT_KILL_FOCUS(wxToolBarSimple::OnKillFocus)
+	EVT_MOUSE_EVENTS(wxToolBarSimple::OnMouseEvent)
+END_EVENT_TABLE()
+
+#ifdef wx_msw
+BEGIN_EVENT_TABLE(wxToolBarMSW, wxToolBarBase)
+	EVT_SIZE(wxToolBarMSW::OnSize)
+	EVT_PAINT(wxToolBarMSW::OnPaint)
+	EVT_MOUSE_EVENTS(wxToolBarMSW::OnMouseEvent)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxToolBar95, wxToolBarBase)
+	EVT_SIZE(wxToolBar95::OnSize)
+	EVT_PAINT(wxToolBar95::OnPaint)
+	EVT_KILL_FOCUS(wxToolBar95::OnKillFocus)
+	EVT_MOUSE_EVENTS(wxToolBar95::OnMouseEvent)
+    EVT_SYS_COLOUR_CHANGED(wxToolBar95::OnSysColourChanged)
+END_EVENT_TABLE()
+#endif
+
+BEGIN_EVENT_TABLE(wxGenericGrid, wxPanel)
+	EVT_SIZE(wxGenericGrid::OnSize)
+	EVT_PAINT(wxGenericGrid::OnPaint)
+	EVT_MOUSE_EVENTS(wxGenericGrid::OnMouseEvent)
+    EVT_TEXT(wxGRID_TEXT_CTRL, wxGenericGrid::OnText)
+    EVT_COMMAND_SCROLL(wxGRID_HSCROLL, wxGenericGrid::OnGridScroll)
+    EVT_COMMAND_SCROLL(wxGRID_VSCROLL, wxGenericGrid::OnGridScroll)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxControl, wxWindow)
+  EVT_ERASE_BACKGROUND(wxControl::OnEraseBackground)
+END_EVENT_TABLE()
+
+#if !defined(wx_msw) || USE_GENERIC_DIALOGS_IN_MSW
+BEGIN_EVENT_TABLE(wxGenericMessageDialog, wxDialog)
+	EVT_BUTTON(wxID_YES, wxGenericMessageDialog::OnYes)
+	EVT_BUTTON(wxID_NO, wxGenericMessageDialog::OnNo)
+	EVT_BUTTON(wxID_CANCEL, wxGenericMessageDialog::OnCancel)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxGenericColourDialog, wxDialog)
+	EVT_BUTTON(wxID_ADD_CUSTOM, wxGenericColourDialog::OnAddCustom)
+	EVT_SLIDER(wxID_RED_SLIDER, wxGenericColourDialog::OnRedSlider)
+	EVT_SLIDER(wxID_GREEN_SLIDER, wxGenericColourDialog::OnGreenSlider)
+	EVT_SLIDER(wxID_BLUE_SLIDER, wxGenericColourDialog::OnBlueSlider)
+	EVT_PAINT(wxGenericColourDialog::OnPaint)
+	EVT_MOUSE_EVENTS(wxGenericColourDialog::OnMouseEvent)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxGenericFontDialog, wxDialog)
+	EVT_CHECKBOX(wxID_FONT_UNDERLINE, wxGenericFontDialog::OnChangeFont)
+	EVT_CHOICE(wxID_FONT_STYLE, wxGenericFontDialog::OnChangeFont)
+	EVT_CHOICE(wxID_FONT_WEIGHT, wxGenericFontDialog::OnChangeFont)
+	EVT_CHOICE(wxID_FONT_FAMILY, wxGenericFontDialog::OnChangeFont)
+	EVT_CHOICE(wxID_FONT_COLOUR, wxGenericFontDialog::OnChangeFont)
+	EVT_CHOICE(wxID_FONT_SIZE, wxGenericFontDialog::OnChangeFont)
+	EVT_PAINT(wxGenericFontDialog::OnPaint)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxGenericPrintDialog, wxDialog)
+    EVT_BUTTON(wxID_OK, wxGenericPrintDialog::OnOK)
+    EVT_BUTTON(wxPRINTID_SETUP, wxGenericPrintDialog::OnSetup)
+    EVT_RADIOBOX(wxPRINTID_RANGE, wxGenericPrintDialog::OnRange)
+END_EVENT_TABLE()
+
+#endif
+
+BEGIN_EVENT_TABLE(wxTextEntryDialog, wxDialog)
+	EVT_BUTTON(wxID_OK, wxTextEntryDialog::OnOK)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxSingleChoiceDialog, wxDialog)
+	EVT_BUTTON(wxID_OK, wxSingleChoiceDialog::OnOK)
+END_EVENT_TABLE()
+
+#include "wx/prntbase.h"
+
+BEGIN_EVENT_TABLE(wxPrintAbortDialog, wxDialog)
+	EVT_BUTTON(wxID_CANCEL, wxPrintAbortDialog::OnCancel)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxPreviewControlBar, wxWindow)
+	EVT_BUTTON(wxID_PREVIEW_CLOSE, 		wxPreviewControlBar::OnClose)
+	EVT_BUTTON(wxID_PREVIEW_PRINT, 		wxPreviewControlBar::OnPrint)
+	EVT_BUTTON(wxID_PREVIEW_PREVIOUS, 	wxPreviewControlBar::OnPrevious)
+	EVT_BUTTON(wxID_PREVIEW_NEXT, 		wxPreviewControlBar::OnNext)
+	EVT_CHOICE(wxID_PREVIEW_ZOOM, 		wxPreviewControlBar::OnZoom)
+END_EVENT_TABLE()
+
+#endif
+
+
+const wxSize wxDefaultSize(-1, -1);
+const wxPoint wxDefaultPosition(-1, -1);
diff --git a/src/gtk1/dc.cpp b/src/gtk1/dc.cpp
new file mode 100644
index 0000000000..c53c2d26fd
--- /dev/null
+++ b/src/gtk1/dc.cpp
@@ -0,0 +1,370 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        dc.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "dc.h"
+#endif
+
+#include "wx/dc.h"
+
+//-----------------------------------------------------------------------------
+// constants
+//-----------------------------------------------------------------------------
+
+#define mm2inches		0.0393700787402
+#define inches2mm		25.4
+#define mm2twips		56.6929133859
+#define twips2mm		0.0176388888889
+#define mm2pt			2.83464566929
+#define pt2mm			0.352777777778
+
+//-----------------------------------------------------------------------------
+// wxDC
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_ABSTRACT_CLASS(wxDC,wxObject)
+
+wxDC::wxDC(void)
+{
+  m_ok = FALSE;
+  m_optimize = FALSE;
+  m_autoSetting = FALSE;
+  m_colour = TRUE;
+  m_clipping = FALSE;
+  
+  m_mm_to_pix_x = 1.0;
+  m_mm_to_pix_y = 1.0;
+  
+  m_logicalOriginX = 0;
+  m_logicalOriginY = 0;
+  m_deviceOriginX = 0;
+  m_deviceOriginY = 0;
+  m_internalDeviceOriginX = 0;
+  m_internalDeviceOriginY = 0;
+  m_externalDeviceOriginX = 0;
+  m_externalDeviceOriginY = 0;
+  
+  m_logicalScaleX = 1.0;
+  m_logicalScaleY = 1.0;
+  m_userScaleX = 1.0;
+  m_userScaleY = 1.0;
+  m_scaleX = 1.0;
+  m_scaleY = 1.0;
+  
+  m_mappingMode = MM_TEXT;
+  m_needComputeScaleX = FALSE;
+  m_needComputeScaleY = FALSE;
+  
+  m_signX = 1;  // default x-axis left to right
+  m_signY = 1;  // default y-axis top down
+
+  m_maxX = m_maxY = -100000;
+  m_minY = m_minY =  100000;
+
+  m_logicalFunction = wxCOPY;
+//  m_textAlignment = wxALIGN_TOP_LEFT;
+  m_backgroundMode = wxTRANSPARENT;
+  
+  m_textForegroundColour = *wxBLACK;
+  m_textBackgroundColour = *wxWHITE;
+  m_pen = *wxBLACK_PEN;
+  m_font = *wxNORMAL_FONT;
+  m_brush = *wxTRANSPARENT_BRUSH;
+  m_backgroundBrush = *wxWHITE_BRUSH;
+  
+//  m_palette = wxAPP_COLOURMAP;
+};
+
+wxDC::~wxDC(void)
+{
+};
+
+void wxDC::DrawArc( long WXUNUSED(x1), long WXUNUSED(y1), long WXUNUSED(x2), long WXUNUSED(y2), 
+  double WXUNUSED(xc), double WXUNUSED(yc) )
+{
+};
+
+void wxDC::DrawIcon( const wxIcon &WXUNUSED(icon), long WXUNUSED(x), long WXUNUSED(y), bool WXUNUSED(useMask) ) 
+{
+};
+
+void wxDC::DrawPoint( wxPoint& point ) 
+{ 
+  DrawPoint( point.x, point.y ); 
+};
+
+void wxDC::DrawPolygon( wxList *list, long xoffset, long yoffset, int fillStyle )
+{
+  int n = list->Number();
+  wxPoint *points = new wxPoint[n];
+
+  int i = 0;
+  for( wxNode *node = list->First(); node; node = node->Next() )
+  {
+    wxPoint *point = (wxPoint *)node->Data();
+    points[i].x = point->x;
+    points[i++].y = point->y;
+  };
+  DrawPolygon( n, points, xoffset, yoffset, fillStyle );
+  delete[] points;
+};
+
+void wxDC::DrawLines( wxList *list, long xoffset, long yoffset )
+{
+  int n = list->Number();
+  wxPoint *points = new wxPoint[n];
+
+  int i = 0;
+  for( wxNode *node = list->First(); node; node = node->Next() ) 
+  {
+    wxPoint *point = (wxPoint *)node->Data();
+    points[i].x = point->x;
+    points[i++].y = point->y;
+  };
+  DrawLines( n, points, xoffset, yoffset );
+  delete []points;
+};
+
+void wxDC::DrawSpline( long x1, long y1, long x2, long y2, long x3, long y3 )
+{
+  wxList list;
+  list.DeleteContents(TRUE);
+  list.Append( new wxPoint(x1, y1) );
+  list.Append( new wxPoint(x2, y2) );
+  list.Append( new wxPoint(x3, y3) );
+  DrawSpline(&list);
+};
+
+void wxDC::DrawSpline( wxList *points )
+{
+  DrawOpenSpline( points );
+};
+
+void wxDC::DrawSpline( int n, wxPoint points[] )
+{
+  wxList list;
+  for (int i = 0; i < n; i++) list.Append( (wxObject*)&points[i] );
+  DrawSpline( &list );
+};
+
+void wxDC::SetClippingRegion( long x, long y, long width, long height )
+{
+  m_clipping = TRUE;
+  m_clipX1 = x;
+  m_clipY1 = y;
+  m_clipX2 = x + width;
+  m_clipY2 = y + height;
+};
+
+void wxDC::DestroyClippingRegion(void)
+{
+  m_clipping = FALSE;
+};
+
+void wxDC::GetClippingBox( long *x, long *y, long *width, long *height ) const
+{
+  if (m_clipping)
+  {
+    if (x) *x = m_clipX1;
+    if (y) *y = m_clipY1;
+    if (width) *width = (m_clipX2 - m_clipX1);
+    if (height) *height = (m_clipY2 - m_clipY1);
+  }
+  else
+   *x = *y = *width = *height = 0;
+};
+
+void wxDC::GetSize( int* width, int* height ) const
+{
+  *width = m_maxX-m_minX;
+  *height = m_maxY-m_minY;
+};
+
+void wxDC::GetSizeMM( long* width, long* height ) const
+{
+  int w = 0;
+  int h = 0;
+  GetSize( &w, &h );
+  *width = long( double(w) / (m_scaleX*m_mm_to_pix_x) );
+  *height = long( double(h) / (m_scaleY*m_mm_to_pix_y) );
+};
+
+void wxDC::SetTextForeground( const wxColour &col )
+{
+  if (!Ok()) return;
+  m_textForegroundColour = col;
+};
+
+void wxDC::SetTextBackground( const wxColour &col )
+{
+  if (!Ok()) return;
+  m_textBackgroundColour = col;
+};
+
+void wxDC::SetMapMode( int mode )
+{
+  switch (mode) 
+  {
+    case MM_TWIPS:
+      SetLogicalScale( twips2mm*m_mm_to_pix_x, twips2mm*m_mm_to_pix_y );
+      break;
+    case MM_POINTS:
+      SetLogicalScale( pt2mm*m_mm_to_pix_x, pt2mm*m_mm_to_pix_y );
+      break;
+    case MM_METRIC:
+      SetLogicalScale( m_mm_to_pix_x, m_mm_to_pix_y );
+      break;
+    case MM_LOMETRIC:
+      SetLogicalScale( m_mm_to_pix_x/10.0, m_mm_to_pix_y/10.0 );
+      break;
+    default:
+    case MM_TEXT:
+      SetLogicalScale( 1.0, 1.0 );
+      break;
+  };
+  if (mode != MM_TEXT)
+  {
+    m_needComputeScaleX = TRUE;
+    m_needComputeScaleY = TRUE;
+  };
+};
+
+void wxDC::SetUserScale( double x, double y )
+{
+  // allow negative ? -> no
+  m_userScaleX = x;
+  m_userScaleY = y;
+  ComputeScaleAndOrigin();
+};
+
+void wxDC::GetUserScale( double *x, double *y )
+{
+  if (x) *x = m_userScaleX;
+  if (y) *y = m_userScaleY;
+};
+
+void wxDC::SetLogicalScale( double x, double y )
+{
+  // allow negative ?
+  m_logicalScaleX = x;
+  m_logicalScaleY = y;
+  ComputeScaleAndOrigin();
+};
+
+void wxDC::GetLogicalScale( double *x, double *y )
+{
+  if (x) *x = m_logicalScaleX;
+  if (y) *y = m_logicalScaleY;
+};
+
+void wxDC::SetLogicalOrigin( long x, long y )
+{
+  m_logicalOriginX = x * m_signX;   // is this still correct ?
+  m_logicalOriginY = y * m_signY;
+  ComputeScaleAndOrigin();
+};
+
+void wxDC::GetLogicalOrigin( long *x, long *y )
+{
+  if (x) *x = m_logicalOriginX;
+  if (y) *y = m_logicalOriginY;
+};
+
+void wxDC::SetDeviceOrigin( long x, long y )
+{
+  m_externalDeviceOriginX = x;
+  m_externalDeviceOriginY = y;
+  ComputeScaleAndOrigin();
+};
+
+void wxDC::GetDeviceOrigin( long *x, long *y )
+{
+  if (x) *x = m_externalDeviceOriginX;
+  if (y) *y = m_externalDeviceOriginY;
+};
+
+void wxDC::SetInternalDeviceOrigin( long x, long y )
+{
+  m_internalDeviceOriginX = x;
+  m_internalDeviceOriginY = y;
+  ComputeScaleAndOrigin();
+};
+
+void wxDC::GetInternalDeviceOrigin( long *x, long *y )
+{
+  if (x) *x = m_internalDeviceOriginX;
+  if (y) *y = m_internalDeviceOriginY;
+};
+
+void wxDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
+{
+  m_signX = (xLeftRight ?  1 : -1);
+  m_signY = (yBottomUp  ? -1 :  1);
+  ComputeScaleAndOrigin();
+};
+
+long wxDC::DeviceToLogicalX(long x) const
+{
+  return XDEV2LOG(x);
+};
+
+long wxDC::DeviceToLogicalY(long y) const
+{
+  return YDEV2LOG(y);
+};
+
+long wxDC::DeviceToLogicalXRel(long x) const
+{
+  return XDEV2LOGREL(x);
+};
+
+long wxDC::DeviceToLogicalYRel(long y) const
+{
+  return YDEV2LOGREL(y);
+};
+
+long wxDC::LogicalToDeviceX(long x) const
+{
+  return XLOG2DEV(x);
+};
+
+long wxDC::LogicalToDeviceY(long y) const
+{
+  return YLOG2DEV(y);
+};
+
+long wxDC::LogicalToDeviceXRel(long x) const
+{
+  return XLOG2DEVREL(x);
+};
+
+long wxDC::LogicalToDeviceYRel(long y) const
+{
+  return YLOG2DEVREL(y);
+};
+    
+void wxDC::CalcBoundingBox( long x, long y )
+{
+  if (x < m_minX) m_minX = x;
+  if (y < m_minY) m_minY = y;
+  if (x > m_maxX) m_maxX = x;
+  if (y > m_maxY) m_maxY = y;
+};
+
+void wxDC::ComputeScaleAndOrigin(void)
+{
+  m_scaleX = m_logicalScaleX * m_userScaleX;
+  m_scaleY = m_logicalScaleY * m_userScaleY;
+
+  m_deviceOriginX = m_internalDeviceOriginX + m_externalDeviceOriginX;
+  m_deviceOriginY = m_internalDeviceOriginY + m_externalDeviceOriginY;
+};
+
diff --git a/src/gtk1/dcclient.cpp b/src/gtk1/dcclient.cpp
new file mode 100644
index 0000000000..dbf2d639a1
--- /dev/null
+++ b/src/gtk1/dcclient.cpp
@@ -0,0 +1,773 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        dcclient.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "dcclient.h"
+#endif
+
+#include "wx/dcclient.h"
+
+//-----------------------------------------------------------------------------
+// local data
+//-----------------------------------------------------------------------------
+
+#include "bdiag.xbm"
+#include "fdiag.xbm"
+#include "cdiag.xbm"
+#include "horiz.xbm"
+#include "verti.xbm"
+#include "cross.xbm"
+#define  num_hatches 6
+
+static GdkPixmap  *hatches[num_hatches];
+static GdkPixmap **hatch_bitmap = NULL;
+
+//-----------------------------------------------------------------------------
+// constants
+//-----------------------------------------------------------------------------
+
+#define RAD2DEG 57.2957795131
+
+//-----------------------------------------------------------------------------
+// wxPaintDC
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxPaintDC,wxDC)
+
+wxPaintDC::wxPaintDC(void)
+{
+};
+
+wxPaintDC::wxPaintDC( wxWindow *window )
+{
+  if (!window) return;
+  GtkWidget *widget = window->m_wxwindow;
+  if (!widget) return;
+  m_window = widget->window;
+  if (!m_window) return;
+  if (window->m_wxwindow)
+    m_cmap = gtk_widget_get_colormap( window->m_wxwindow );
+  else
+    m_cmap = gtk_widget_get_colormap( window->m_widget );
+  SetUpDC();
+  
+  long x = 0;
+  long y = 0;
+  window->GetDrawingOffset( &x, &y );
+  SetInternalDeviceOrigin( -x, -y );
+};
+
+wxPaintDC::~wxPaintDC(void)
+{
+};
+
+void wxPaintDC::FloodFill( long WXUNUSED(x1), long WXUNUSED(y1), 
+  wxColour *WXUNUSED(col), int WXUNUSED(style) )
+{
+};
+
+bool wxPaintDC::GetPixel( long WXUNUSED(x1), long WXUNUSED(y1), wxColour *WXUNUSED(col) ) const
+{
+  return FALSE;
+};
+
+void wxPaintDC::DrawLine( long x1, long y1, long x2, long y2 )
+{
+  if (!Ok()) return;
+  
+  if (m_pen.GetStyle() != wxTRANSPARENT)
+  {
+    gdk_draw_line( m_window, m_penGC, 
+      XLOG2DEV(x1), YLOG2DEV(y1), XLOG2DEV(x2), YLOG2DEV(y2) );
+  };
+};
+
+void wxPaintDC::CrossHair( long x, long y )
+{
+  if (!Ok()) return;
+  
+  if (m_pen.GetStyle() != wxTRANSPARENT)
+  {
+    int w = 0;
+    int h = 0;
+    GetSize( &w, &h );
+    long xx = XLOG2DEV(x);
+    long yy = YLOG2DEV(y);
+    gdk_draw_line( m_window, m_penGC,
+      0, yy, XLOG2DEVREL(w), yy );
+    gdk_draw_line( m_window, m_penGC,
+      xx, 0, xx, YLOG2DEVREL(h) );
+  };
+};
+
+void wxPaintDC::DrawArc( long x1, long y1, long x2, long y2, double xc, double yc )
+{
+  if (!Ok()) return;
+  
+  long xx1 = XLOG2DEV(x1); 
+  long yy1 = YLOG2DEV(y1);
+  long xx2 = XLOG2DEV(x2); 
+  long yy2 = YLOG2DEV(y2);
+  long xxc = XLOG2DEV((long)xc); 
+  long yyc = YLOG2DEV((long)yc);
+  double dx = xx1 - xxc; 
+  double dy = yy1 - yyc;
+  double radius = sqrt(dx*dx+dy*dy);
+  long   r      = (long)radius;
+  double radius1, radius2;
+
+  if (xx1 == xx2 && yy1 == yy2) 
+  {
+    radius1 = 0.0;
+    radius2 = 360.0;
+  } 
+  else 
+  if (radius == 0.0) 
+  {
+    radius1 = radius2 = 0.0;
+  } 
+  else 
+  {
+    radius1 = (xx1 - xxc == 0) ?
+	    (yy1 - yyc < 0) ? 90.0 : -90.0 :
+	    -atan2(double(yy1-yyc), double(xx1-xxc)) * RAD2DEG;
+    radius2 = (xx2 - xxc == 0) ?
+	    (yy2 - yyc < 0) ? 90.0 : -90.0 :
+	    -atan2(double(yy2-yyc), double(xx2-xxc)) * RAD2DEG;
+  };
+  long alpha1 = long(radius1 * 64.0);
+  long alpha2 = long((radius2 - radius1) * 64.0);
+  while (alpha2 <= 0) alpha2 += 360*64;
+  while (alpha1 > 360*64) alpha1 -= 360*64;
+
+  if (m_brush.GetStyle() != wxTRANSPARENT)
+    gdk_draw_arc( m_window, m_brushGC, TRUE, xxc-r, yyc-r, 2*r,2*r, alpha1, alpha2 );
+    
+  if (m_pen.GetStyle() != wxTRANSPARENT)
+    gdk_draw_arc( m_window, m_penGC, FALSE, xxc-r, yyc-r, 2*r,2*r, alpha1, alpha2 );
+  
+};
+
+void wxPaintDC::DrawEllipticArc( long x, long y, long width, long height, double sa, double ea )
+{
+  if (!Ok()) return;
+  
+  if (width<0) { width=-width; x=x-width; }
+  if (height<0) { height=-height; y=y-height; }
+
+  long xx = XLOG2DEV(x);    
+  long yy = YLOG2DEV(y);
+  long ww = XLOG2DEVREL(width); 
+  long hh = YLOG2DEVREL(height);
+  
+  if (m_brush.GetStyle() != wxTRANSPARENT)
+    gdk_draw_arc( m_window, m_brushGC, TRUE, xx, yy, ww-1, hh-1, 0, long(sa*64) );
+  
+  if (m_pen.GetStyle() != wxTRANSPARENT)
+    gdk_draw_arc( m_window, m_penGC, FALSE, xx, yy, ww, hh, 0, long(ea*64) );
+};
+
+void wxPaintDC::DrawPoint( long x, long y )
+{
+  if (!Ok()) return;
+  
+  if (m_pen.GetStyle() != wxTRANSPARENT)
+    gdk_draw_point( m_window, m_penGC, XLOG2DEV(x), YLOG2DEV(y) );
+};
+
+void wxPaintDC::DrawLines( int n, wxPoint points[], long xoffset, long yoffset )
+{
+  if (!Ok()) return;
+  
+  if (m_pen.GetStyle() == wxTRANSPARENT) return;
+  
+  for (int i = 0; i < n-1; i++)
+  {
+    long x1 = XLOG2DEV(points[i].x + xoffset);
+    long x2 = XLOG2DEV(points[i+1].x + xoffset);
+    long y1 = YLOG2DEV(points[i].y + yoffset);     // oh, what a waste
+    long y2 = YLOG2DEV(points[i+1].y + yoffset);
+    gdk_draw_line( m_window, m_brushGC, x1, y1, x2, y2 );
+  };
+};
+
+void wxPaintDC::DrawLines( wxList *points, long xoffset, long yoffset )
+{
+  if (!Ok()) return;
+  
+  if (m_pen.GetStyle() == wxTRANSPARENT) return;
+  
+  wxNode *node = points->First();
+  while (node->Next())
+  {
+    wxPoint *point = (wxPoint*)node->Data();
+    wxPoint *npoint = (wxPoint*)node->Next()->Data();
+    long x1 = XLOG2DEV(point->x + xoffset);
+    long x2 = XLOG2DEV(npoint->x + xoffset);
+    long y1 = YLOG2DEV(point->y + yoffset);    // and again...
+    long y2 = YLOG2DEV(npoint->y + yoffset);
+    gdk_draw_line( m_window, m_brushGC, x1, y1, x2, y2 );
+    node = node->Next();
+  };
+};
+
+void wxPaintDC::DrawPolygon( int WXUNUSED(n), wxPoint WXUNUSED(points)[], 
+  long WXUNUSED(xoffset), long WXUNUSED(yoffset), int WXUNUSED(fillStyle) )
+{
+  if (!Ok()) return;
+};
+
+void wxPaintDC::DrawPolygon( wxList *WXUNUSED(lines), long WXUNUSED(xoffset), 
+                             long WXUNUSED(yoffset), int WXUNUSED(fillStyle) )
+{
+  if (!Ok()) return;
+};
+
+void wxPaintDC::DrawRectangle( long x, long y, long width, long height )
+{
+  if (!Ok()) return;
+
+  long xx = XLOG2DEV(x);
+  long yy = YLOG2DEV(y);
+  long ww = XLOG2DEVREL(width);
+  long hh = YLOG2DEVREL(height);
+    
+  if (m_brush.GetStyle() != wxTRANSPARENT)
+    gdk_draw_rectangle( m_window, m_brushGC, TRUE, xx, yy, ww, hh );
+    
+  if (m_pen.GetStyle() != wxTRANSPARENT)
+    gdk_draw_rectangle( m_window, m_penGC, FALSE, xx, yy, ww-1, hh-1 );
+};
+
+void wxPaintDC::DrawRoundedRectangle( long x, long y, long width, long height, double radius )
+{
+  if (!Ok()) return;
+  
+  if (width<0) { width=-width; x=x-width; }
+  if (height<0) { height=-height; y=y-height; }
+
+  if (radius < 0.0) radius = - radius * ((width < height) ? width : height);
+  
+  long xx = XLOG2DEV(x);    
+  long yy = YLOG2DEV(y);
+  long ww = XLOG2DEVREL(width); 
+  long hh = YLOG2DEVREL(height);
+  long rr = XLOG2DEVREL((long)radius);
+  long dd = 2 * rr;
+
+  if (m_brush.GetStyle() != wxTRANSPARENT)
+  {
+    gdk_draw_rectangle( m_window, m_brushGC, TRUE, xx+rr, yy, ww-dd, hh );
+    gdk_draw_rectangle( m_window, m_brushGC, TRUE, xx, yy+rr, ww, hh-dd );
+    gdk_draw_arc( m_window, m_brushGC, TRUE, xx, yy, dd, dd, 90*64, 90*64 );
+    gdk_draw_arc( m_window, m_brushGC, TRUE, xx+ww-dd, yy, dd, dd, 0, 90*64 );
+    gdk_draw_arc( m_window, m_brushGC, TRUE, xx+ww-dd, yy+hh-dd, dd, dd, 270*64, 90*64 );
+    gdk_draw_arc( m_window, m_brushGC, TRUE, xx, yy+hh-dd, dd, dd, 180*64, 90*64 );
+  };
+  
+  if (m_pen.GetStyle() != wxTRANSPARENT)
+  {
+    gdk_draw_line( m_window, m_penGC, xx+rr, yy, xx+ww-rr, yy );
+    gdk_draw_line( m_window, m_penGC, xx+rr, yy+hh, xx+ww-rr, yy+hh );
+    gdk_draw_line( m_window, m_penGC, xx, yy+rr, xx, yy+hh-rr );
+    gdk_draw_line( m_window, m_penGC, xx+ww, yy+rr, xx+ww, yy+hh-rr );
+    gdk_draw_arc( m_window, m_penGC, FALSE, xx, yy, dd, dd, 90*64, 90*64 );
+    gdk_draw_arc( m_window, m_penGC, FALSE, xx+ww-dd, yy, dd, dd, 0, 90*64 );
+    gdk_draw_arc( m_window, m_penGC, FALSE, xx+ww-dd, yy+hh-dd, dd, dd, 270*64, 90*64 );
+    gdk_draw_arc( m_window, m_penGC, FALSE, xx, yy+hh-dd, dd, dd, 180*64, 90*64 );
+  };
+};
+
+void wxPaintDC::DrawEllipse( long x, long y, long width, long height )
+{
+  if (!Ok()) return;
+  
+  if (width<0) { width=-width; x=x-width; }
+  if (height<0) { height=-height; y=y-height; }
+
+  long xx = XLOG2DEV(x);    
+  long yy = YLOG2DEV(y);
+  long ww = XLOG2DEVREL(width); 
+  long hh = YLOG2DEVREL(height);
+  
+  if (m_brush.GetStyle() != wxTRANSPARENT)
+    gdk_draw_arc( m_window, m_brushGC, TRUE, xx, yy, ww, hh, 0, 360*64 );
+  
+  if (m_pen.GetStyle() != wxTRANSPARENT)
+    gdk_draw_arc( m_window, m_penGC, FALSE, xx, yy, ww, hh, 0, 360*64 );
+};
+
+bool wxPaintDC::CanDrawBitmap(void) const
+{
+  return TRUE;
+};
+
+void wxPaintDC::DrawIcon( const wxIcon &icon, long x, long y, bool useMask )
+{
+  if (!Ok()) return;
+  
+  if (!icon.Ok()) return;
+  
+  int xx = XLOG2DEV(x);
+  int yy = YLOG2DEV(y);
+  
+  GdkBitmap *mask = NULL;
+  if (icon.GetMask()) mask = icon.GetMask()->GetBitmap();
+    
+  if (useMask && mask) 
+  {
+    gdk_gc_set_clip_mask( m_penGC, mask );
+    gdk_gc_set_clip_origin( m_penGC, xx, yy );
+  };
+  
+  GdkPixmap *pm = icon.GetPixmap();
+  gdk_draw_pixmap( m_window, m_penGC, pm, 0, 0, xx, yy, -1, -1 );
+  
+  if (useMask && mask) 
+  {
+    gdk_gc_set_clip_mask( m_penGC, NULL );
+    gdk_gc_set_clip_origin( m_penGC, 0, 0 );
+  };
+};
+
+bool wxPaintDC::Blit( long xdest, long ydest, long width, long height,
+       wxDC *source, long xsrc, long ysrc, int WXUNUSED(logical_func), bool WXUNUSED(useMask) )
+{
+  if (!Ok()) return FALSE;
+  
+  wxClientDC *csrc = (wxClientDC*)source;
+
+  gdk_window_copy_area ( m_window, m_penGC,
+    XLOG2DEV(xdest), YLOG2DEV(ydest),
+    csrc->GetWindow(),
+    source->DeviceToLogicalX(xsrc), source->DeviceToLogicalY(ysrc),
+    source->DeviceToLogicalXRel(width), source->DeviceToLogicalYRel(height) );
+
+/*    
+  gdk_window_copy_area ( m_window, m_penGC,
+    XLOG2DEV(xdest), YLOG2DEV(ydest),
+    csrc->GetWindow(),
+    xsrc, ysrc,
+    width, height );
+*/
+    
+  return TRUE;
+};
+
+void wxPaintDC::DrawText( const wxString &text, long x, long y, bool WXUNUSED(use16) )
+{
+  if (!Ok()) return;
+  
+  GdkFont *font = m_font.GetInternalFont( m_scaleY );
+  gdk_draw_string( m_window, font, m_textGC, 
+    XLOG2DEV(x), 
+    YLOG2DEV(y) + font->ascent, text );
+};
+
+bool wxPaintDC::CanGetTextExtent(void) const
+{
+  return TRUE;
+};
+
+void wxPaintDC::GetTextExtent( const wxString &string, long *width, long *height,
+                     long *WXUNUSED(descent), long *WXUNUSED(externalLeading),
+                     wxFont *WXUNUSED(theFont), bool WXUNUSED(use16) )
+{
+  if (!Ok()) return;
+  
+  GdkFont *font = m_font.GetInternalFont( m_scaleY );
+  if (width) (*width) = gdk_string_width( font, string );
+  if (height) (*height) = font->ascent + font->descent;
+};
+
+long wxPaintDC::GetCharWidth(void)
+{
+  if (!Ok()) return 0;
+  
+  GdkFont *font = m_font.GetInternalFont( m_scaleY );
+  return gdk_string_width( font, "H" );
+};
+
+long wxPaintDC::GetCharHeight(void)
+{
+  if (!Ok()) return 0;
+  
+  GdkFont *font = m_font.GetInternalFont( m_scaleY );
+  return font->ascent + font->descent;
+};
+
+void wxPaintDC::Clear(void)
+{
+  if (!Ok()) return;
+  
+  DestroyClippingRegion();
+  gdk_window_clear( m_window );
+};
+
+void wxPaintDC::SetFont( const wxFont &font )
+{
+  if (!Ok()) return;
+  
+  m_font = font;
+};
+
+void wxPaintDC::SetPen( const wxPen &pen )
+{
+  if (!Ok()) return;
+
+  if (m_pen == pen) return;
+  
+  m_pen = pen;
+  
+  if (!m_pen.Ok()) return;
+  
+  gint width = m_pen.GetWidth();
+  
+  GdkLineStyle lineStyle = GDK_LINE_SOLID;
+  switch (m_pen.GetStyle())
+  {
+    case wxSOLID:      { lineStyle = GDK_LINE_SOLID;       break; };
+    case wxDOT:        { lineStyle = GDK_LINE_ON_OFF_DASH; break; };
+    case wxLONG_DASH:  { lineStyle = GDK_LINE_ON_OFF_DASH; break; };
+    case wxSHORT_DASH: { lineStyle = GDK_LINE_ON_OFF_DASH; break; };
+    case wxDOT_DASH:   { lineStyle = GDK_LINE_DOUBLE_DASH; break; };
+  };
+  
+  GdkCapStyle capStyle = GDK_CAP_ROUND;
+  switch (m_pen.GetCap())
+  {
+    case wxCAP_ROUND:      { capStyle = GDK_CAP_ROUND;      break; };
+    case wxCAP_PROJECTING: { capStyle = GDK_CAP_PROJECTING; break; };
+    case wxCAP_BUTT:       { capStyle = GDK_CAP_BUTT;       break; };
+  };
+  
+  GdkJoinStyle joinStyle = GDK_JOIN_ROUND;
+  switch (m_pen.GetJoin())
+  {
+    case wxJOIN_BEVEL: { joinStyle = GDK_JOIN_BEVEL; break; };
+    case wxJOIN_ROUND: { joinStyle = GDK_JOIN_ROUND; break; };
+    case wxJOIN_MITER: { joinStyle = GDK_JOIN_MITER; break; };
+  };
+  
+  gdk_gc_set_line_attributes( m_penGC, width, lineStyle, capStyle, joinStyle );
+  
+  m_pen.GetColour().CalcPixel( m_cmap );
+  gdk_gc_set_foreground( m_penGC, m_pen.GetColour().GetColor() );
+};
+
+void wxPaintDC::SetBrush( const wxBrush &brush )
+{
+  if (!Ok()) return;
+  
+  if (m_brush == brush) return;
+  
+  m_brush = brush;
+  
+  if (!m_brush.Ok()) return;
+  
+  m_brush.GetColour().CalcPixel( m_cmap );
+  gdk_gc_set_foreground( m_brushGC, m_brush.GetColour().GetColor() );
+  
+  GdkFill fillStyle = GDK_SOLID;
+  switch (m_brush.GetStyle())
+  {
+    case wxSOLID:
+    case wxTRANSPARENT:
+      break;
+    default:
+      fillStyle = GDK_STIPPLED;
+  };
+ 
+  gdk_gc_set_fill( m_brushGC, fillStyle );
+  
+  if (m_brush.GetStyle() == wxSTIPPLE)
+  {
+    gdk_gc_set_stipple( m_brushGC, m_brush.GetStipple()->GetPixmap() );
+  };
+  
+  if (IS_HATCH(m_brush.GetStyle()))
+  {
+    int num = m_brush.GetStyle() - wxBDIAGONAL_HATCH;
+    gdk_gc_set_stipple( m_brushGC, hatches[num] );
+  };
+};
+
+void wxPaintDC::SetLogicalFunction( int function )
+{
+  if (m_logicalFunction == function) return;
+  GdkFunction mode = GDK_COPY;
+  switch (function)
+  {
+    case wxXOR:    mode = GDK_INVERT; break;
+    case wxINVERT: mode = GDK_INVERT; break;
+    default:       break;
+  };
+  m_logicalFunction = function;
+  gdk_gc_set_function( m_penGC, mode );
+  gdk_gc_set_function( m_brushGC, mode );
+};
+
+void wxPaintDC::SetTextForeground( const wxColour &col )
+{
+  if (!Ok()) return;
+  
+  if (m_textForegroundColour == col) return;
+  
+  m_textForegroundColour = col;
+  if (!m_textForegroundColour.Ok()) return;
+  
+  m_textForegroundColour.CalcPixel( m_cmap );
+  gdk_gc_set_foreground( m_textGC, m_textForegroundColour.GetColor() );
+};
+
+void wxPaintDC::SetTextBackground( const wxColour &col )
+{
+  if (!Ok()) return;
+  
+  if (m_textBackgroundColour == col) return;
+  
+  m_textBackgroundColour = col;
+  if (!m_textBackgroundColour.Ok()) return;
+  
+  m_textBackgroundColour.CalcPixel( m_cmap );
+  gdk_gc_set_background( m_textGC, m_textBackgroundColour.GetColor() );
+};
+
+void wxPaintDC::SetBackgroundMode( int WXUNUSED(mode) )
+{
+};
+
+void wxPaintDC::SetPalette( const wxPalette& WXUNUSED(palette) )
+{
+};
+
+void wxPaintDC::SetClippingRegion( long x, long y, long width, long height )
+{
+  wxDC::SetClippingRegion( x, y, width, height );
+  
+  GdkRectangle rect;
+  rect.x = XLOG2DEV(x);
+  rect.y = YLOG2DEV(y);
+  rect.width = XLOG2DEV(x+width);
+  rect.height = YLOG2DEV(y+height);
+  gdk_gc_set_clip_rectangle( m_penGC, &rect );
+  gdk_gc_set_clip_rectangle( m_brushGC, &rect );
+  gdk_gc_set_clip_rectangle( m_textGC, &rect );
+  gdk_gc_set_clip_rectangle( m_bgGC, &rect );
+  
+};
+
+void wxPaintDC::DestroyClippingRegion(void)
+{
+  wxDC::DestroyClippingRegion();
+  
+  gdk_gc_set_clip_rectangle( m_penGC, NULL );
+  gdk_gc_set_clip_rectangle( m_brushGC, NULL );
+  gdk_gc_set_clip_rectangle( m_textGC, NULL );
+  gdk_gc_set_clip_rectangle( m_bgGC, NULL );
+};
+
+void wxPaintDC::SetUpDC(void)
+{
+  m_ok = TRUE;
+  m_logicalFunction = wxCOPY;
+  m_penGC = gdk_gc_new( m_window );
+  m_brushGC = gdk_gc_new( m_window );
+  m_textGC = gdk_gc_new( m_window );
+  m_bgGC = gdk_gc_new( m_window );
+  SetTextForeground( m_textForegroundColour );
+  SetTextBackground( m_textBackgroundColour );
+  SetPen( m_pen );
+  SetFont( m_font );
+  SetBrush( m_brush );
+  
+  gdk_gc_set_background( m_penGC, wxWHITE->GetColor() );
+  
+  if (!hatch_bitmap) 
+  {
+    hatch_bitmap    = hatches;
+    hatch_bitmap[0] = gdk_bitmap_create_from_data( NULL, bdiag_bits, bdiag_width, bdiag_height );
+    hatch_bitmap[1] = gdk_bitmap_create_from_data( NULL, cdiag_bits, cdiag_width, cdiag_height );
+    hatch_bitmap[2] = gdk_bitmap_create_from_data( NULL, fdiag_bits, fdiag_width, fdiag_height );
+    hatch_bitmap[3] = gdk_bitmap_create_from_data( NULL, cross_bits, cross_width, cross_height );
+    hatch_bitmap[4] = gdk_bitmap_create_from_data( NULL, horiz_bits, horiz_width, horiz_height );
+    hatch_bitmap[5] = gdk_bitmap_create_from_data( NULL, verti_bits, verti_width, verti_height );
+  };
+};
+
+GdkWindow *wxPaintDC::GetWindow(void)
+{
+  return m_window;
+};
+
+// ----------------------------------- spline code ----------------------------------------
+
+void wx_quadratic_spline(double a1, double b1, double a2, double b2,
+                         double a3, double b3, double a4, double b4);
+void wx_clear_stack(void);
+int wx_spline_pop(double *x1, double *y1, double *x2, double *y2, double *x3,
+        double *y3, double *x4, double *y4);
+void wx_spline_push(double x1, double y1, double x2, double y2, double x3, double y3,
+          double x4, double y4);
+static bool wx_spline_add_point(double x, double y);
+static void wx_spline_draw_point_array(wxDC *dc);
+
+wxList wx_spline_point_list;
+
+#define		half(z1, z2)	((z1+z2)/2.0)
+#define		THRESHOLD	5
+
+/* iterative version */
+
+void wx_quadratic_spline(double a1, double b1, double a2, double b2, double a3, double b3, double a4,
+                 double b4)
+{
+    register double  xmid, ymid;
+    double           x1, y1, x2, y2, x3, y3, x4, y4;
+
+    wx_clear_stack();
+    wx_spline_push(a1, b1, a2, b2, a3, b3, a4, b4);
+
+    while (wx_spline_pop(&x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4)) {
+        xmid = (double)half(x2, x3);
+        ymid = (double)half(y2, y3);
+	if (fabs(x1 - xmid) < THRESHOLD && fabs(y1 - ymid) < THRESHOLD &&
+	    fabs(xmid - x4) < THRESHOLD && fabs(ymid - y4) < THRESHOLD) {
+            wx_spline_add_point( x1, y1 );
+            wx_spline_add_point( xmid, ymid );
+	} else {
+            wx_spline_push(xmid, ymid, (double)half(xmid, x3), (double)half(ymid, y3),
+                 (double)half(x3, x4), (double)half(y3, y4), x4, y4);
+            wx_spline_push(x1, y1, (double)half(x1, x2), (double)half(y1, y2),
+                 (double)half(x2, xmid), (double)half(y2, ymid), xmid, ymid);
+	}
+    }
+}
+
+/* utilities used by spline drawing routines */
+
+typedef struct wx_spline_stack_struct {
+    double           x1, y1, x2, y2, x3, y3, x4, y4;
+} Stack;
+
+#define         SPLINE_STACK_DEPTH             20
+static Stack    wx_spline_stack[SPLINE_STACK_DEPTH];
+static Stack   *wx_stack_top;
+static int      wx_stack_count;
+
+void wx_clear_stack(void)
+{
+    wx_stack_top = wx_spline_stack;
+    wx_stack_count = 0;
+}
+
+void wx_spline_push(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
+{
+    wx_stack_top->x1 = x1;
+    wx_stack_top->y1 = y1;
+    wx_stack_top->x2 = x2;
+    wx_stack_top->y2 = y2;
+    wx_stack_top->x3 = x3;
+    wx_stack_top->y3 = y3;
+    wx_stack_top->x4 = x4;
+    wx_stack_top->y4 = y4;
+    wx_stack_top++;
+    wx_stack_count++;
+}
+
+int wx_spline_pop(double *x1, double *y1, double *x2, double *y2,
+                  double *x3, double *y3, double *x4, double *y4)
+{
+    if (wx_stack_count == 0)
+	return (0);
+    wx_stack_top--;
+    wx_stack_count--;
+    *x1 = wx_stack_top->x1;
+    *y1 = wx_stack_top->y1;
+    *x2 = wx_stack_top->x2;
+    *y2 = wx_stack_top->y2;
+    *x3 = wx_stack_top->x3;
+    *y3 = wx_stack_top->y3;
+    *x4 = wx_stack_top->x4;
+    *y4 = wx_stack_top->y4;
+    return (1);
+}
+
+static bool wx_spline_add_point(double x, double y)
+{
+  wxPoint *point = new wxPoint ;
+  point->x = (int) x;
+  point->y = (int) y;
+  wx_spline_point_list.Append((wxObject*)point);
+  return TRUE;
+}
+
+static void wx_spline_draw_point_array(wxDC *dc)
+{
+  dc->DrawLines(&wx_spline_point_list, 0, 0 );
+  wxNode *node = wx_spline_point_list.First();
+  while (node)
+  {
+    wxPoint *point = (wxPoint *)node->Data();
+    delete point;
+    delete node;
+    node = wx_spline_point_list.First();
+  }
+}
+
+void wxPaintDC::DrawOpenSpline( wxList *points )
+{
+    wxPoint *p;
+    double           cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
+    double           x1, y1, x2, y2;
+
+    wxNode *node = points->First();
+    p = (wxPoint *)node->Data();
+
+    x1 = p->x;
+    y1 = p->y;
+
+    node = node->Next();
+    p = (wxPoint *)node->Data();
+
+    x2 = p->x;
+    y2 = p->y;
+    cx1 = (double)((x1 + x2) / 2);
+    cy1 = (double)((y1 + y2) / 2);
+    cx2 = (double)((cx1 + x2) / 2);
+    cy2 = (double)((cy1 + y2) / 2);
+
+    wx_spline_add_point(x1, y1);
+
+    while ((node = node->Next()) != NULL)
+    {
+        p = (wxPoint *)node->Data();
+	x1 = x2;
+	y1 = y2;
+	x2 = p->x;
+	y2 = p->y;
+        cx4 = (double)(x1 + x2) / 2;
+        cy4 = (double)(y1 + y2) / 2;
+        cx3 = (double)(x1 + cx4) / 2;
+        cy3 = (double)(y1 + cy4) / 2;
+
+        wx_quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
+
+	cx1 = cx4;
+	cy1 = cy4;
+        cx2 = (double)(cx1 + x2) / 2;
+        cy2 = (double)(cy1 + y2) / 2;
+    }
+
+    wx_spline_add_point( cx1, cy1 );
+    wx_spline_add_point( x2, y2 );
+
+    wx_spline_draw_point_array( this );
+};
diff --git a/src/gtk1/dcmemory.cpp b/src/gtk1/dcmemory.cpp
new file mode 100644
index 0000000000..804ba3e3a3
--- /dev/null
+++ b/src/gtk1/dcmemory.cpp
@@ -0,0 +1,68 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        dcmemory.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "dcmemory.h"
+#endif
+
+#include "wx/dcmemory.h"
+
+//-----------------------------------------------------------------------------
+// wxMemoryDC
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC,wxPaintDC)
+
+wxMemoryDC::wxMemoryDC(void)
+{
+  m_ok = FALSE;
+  m_cmap = gdk_colormap_get_system();
+};
+
+wxMemoryDC::wxMemoryDC( wxDC *WXUNUSED(dc) )
+{
+  m_ok = FALSE;
+  m_cmap = gdk_colormap_get_system();
+};
+
+wxMemoryDC::~wxMemoryDC(void)
+{
+};
+
+void wxMemoryDC::SelectObject( const wxBitmap& bitmap )
+{
+  m_selected = bitmap;
+  if (m_selected.Ok())
+  {
+    m_window = m_selected.GetPixmap();
+    SetUpDC();
+  }
+  else
+  {
+    m_ok = FALSE;
+    m_window = NULL;
+  };
+};
+
+void wxMemoryDC::GetSize( int *width, int *height )
+{
+  if (m_selected.Ok())
+  {
+    if (width) (*width) = m_selected.GetWidth();
+    if (height) (*height) = m_selected.GetHeight();
+  }
+  else
+  {
+    if (width) (*width) = 0;
+    if (height) (*height) = 0;
+  };
+};
+
+
diff --git a/src/gtk1/dcscreen.cpp b/src/gtk1/dcscreen.cpp
new file mode 100644
index 0000000000..9f5c0cacc6
--- /dev/null
+++ b/src/gtk1/dcscreen.cpp
@@ -0,0 +1,121 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        dcscreen.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "dcscreen.h"
+#endif
+
+#include "wx/dcscreen.h"
+#include "wx/window.h"
+#include "gdk/gdkx.h"
+
+//-----------------------------------------------------------------------------
+// wxScreenDC
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxScreenDC,wxPaintDC)
+
+wxScreenDC::wxScreenDC(void)
+{
+  m_ok = FALSE;
+  m_window = NULL;
+  m_cmap = gdk_colormap_get_system();
+  
+  m_window = GDK_ROOT_PARENT();
+  
+  SetUpDC();
+  
+  gdk_gc_set_subwindow( m_penGC, GDK_INCLUDE_INFERIORS );
+  gdk_gc_set_subwindow( m_brushGC, GDK_INCLUDE_INFERIORS );
+  gdk_gc_set_subwindow( m_textGC, GDK_INCLUDE_INFERIORS );
+  gdk_gc_set_subwindow( m_bgGC, GDK_INCLUDE_INFERIORS );
+};
+
+wxScreenDC::~wxScreenDC(void)
+{
+  EndDrawingOnTop();
+};
+
+bool wxScreenDC::StartDrawingOnTop( wxWindow *WXUNUSED(window) )
+{
+  return TRUE;
+/*
+  if (!window)
+  {
+    StartDrawingOnTop();
+    return;
+  };
+  wxRectangle rect;
+  rect.x = 0;
+  rect.y = 0;
+  window->GetPosition( &rect.x, &rect.y );
+  rect.width = 0;
+  rect.height = 0;
+  window->GetSize( &rect.width, &rect.height );
+  window->ClientToScreen( &rect.x, &rect.y );
+  StartDrawingOnTop( &rect );
+  return TRUE;
+*/
+};
+
+bool wxScreenDC::StartDrawingOnTop( wxRectangle *WXUNUSED(rect) )
+{
+  return TRUE;
+/*
+  int x = 0;
+  int y = 0;
+  int width = gdk_screen_width();
+  int height = gdk_screen_height();
+  if (rect)
+  {
+    x = rect->x;
+    y = rect->y;
+    width = rect->width;
+    height = rect->height;
+  };
+  
+  GTK cannot set transparent backgrounds. :-(
+
+  GdkWindowAttr attr;
+  attr.x = x;
+  attr.y = y;
+  attr.width = width;
+  attr.height = height;
+  attr.override_redirect = TRUE;
+  attr.wclass = GDK_INPUT_OUTPUT;
+  attr.event_mask = 0;
+  attr.window_type = GDK_WINDOW_TEMP;
+  m_window = gdk_window_new( NULL, &attr, GDK_WA_NOREDIR | GDK_WA_X | GDK_WA_Y );
+  
+  gdk_window_show( m_window );
+
+  m_window = GDK_ROOT_PARENT();
+  
+  SetUpDC();
+  
+  gdk_gc_set_subwindow( m_penGC, GDK_INCLUDE_INFERIORS );
+  gdk_gc_set_subwindow( m_brushGC, GDK_INCLUDE_INFERIORS );
+  gdk_gc_set_subwindow( m_textGC, GDK_INCLUDE_INFERIORS );
+  gdk_gc_set_subwindow( m_bgGC, GDK_INCLUDE_INFERIORS );
+
+  return TRUE;
+*/
+};
+
+bool wxScreenDC::EndDrawingOnTop(void)
+{
+  return TRUE;
+/*
+  if (m_window) gdk_window_destroy( m_window );
+  m_window = NULL;
+  m_isOk = FALSE;
+  return TRUE;
+*/
+};
diff --git a/src/gtk1/dialog.cpp b/src/gtk1/dialog.cpp
new file mode 100644
index 0000000000..0c63e39f11
--- /dev/null
+++ b/src/gtk1/dialog.cpp
@@ -0,0 +1,212 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        dialog.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "dialog.h"
+#endif
+
+#include "wx/dialog.h"
+#include "wx/frame.h"
+#include "wx/app.h"
+#include "wx/gtk/win_gtk.h"
+
+//-----------------------------------------------------------------------------
+// delete
+
+bool gtk_dialog_delete_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxDialog *win )
+{ 
+/*
+  printf( "OnDelete from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  win->Close();
+
+  return TRUE;
+};
+
+//-----------------------------------------------------------------------------
+// wxDialog
+//-----------------------------------------------------------------------------
+
+BEGIN_EVENT_TABLE(wxDialog,wxWindow)
+  EVT_BUTTON  (wxID_OK,       wxDialog::OnOk)
+  EVT_BUTTON  (wxID_CANCEL,   wxDialog::OnCancel)
+  EVT_BUTTON  (wxID_APPLY,    wxDialog::OnApply)
+  EVT_CLOSE   (wxDialog::OnCloseWindow)
+END_EVENT_TABLE()
+
+IMPLEMENT_DYNAMIC_CLASS(wxDialog,wxWindow)
+
+wxDialog::wxDialog(void)
+{
+  m_title = "";
+  m_modalShowing = TRUE;
+  wxTopLevelWindows.Insert( this );
+};
+
+wxDialog::wxDialog( wxWindow *parent, 
+      wxWindowID id, const wxString &title,
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  wxTopLevelWindows.Insert( this );
+  Create( parent, id, title, pos, size, style, name );
+};
+
+bool wxDialog::Create( wxWindow *parent,
+      wxWindowID id, const wxString &title,
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  m_needParent = FALSE;
+  
+  PreCreation( parent, id, pos, size, style, name );
+  
+  m_modalShowing = ((m_windowStyle & wxDIALOG_MODAL) == wxDIALOG_MODAL);
+  
+  m_widget = gtk_window_new( GTK_WINDOW_TOPLEVEL );
+  GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
+ 
+  gtk_widget_set( m_widget, "GtkWindow::allow_shrink", TRUE, NULL);
+  
+  gtk_signal_connect( GTK_OBJECT(m_widget), "delete_event", 
+    GTK_SIGNAL_FUNC(gtk_dialog_delete_callback), (gpointer)this );
+    
+  m_wxwindow = gtk_myfixed_new();
+  gtk_widget_show( m_wxwindow );
+  GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
+  
+  gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow );
+  
+  SetTitle( title );
+  
+  PostCreation();
+  
+  return TRUE;
+};
+
+wxDialog::~wxDialog(void)
+{
+  wxTopLevelWindows.DeleteObject( this );
+  if (wxTopLevelWindows.Number() == 0) wxTheApp->ExitMainLoop();
+};
+
+void wxDialog::SetTitle(const wxString& title )
+{
+  m_title = title;
+  gtk_window_set_title( GTK_WINDOW(m_widget), m_title );
+};
+
+wxString wxDialog::GetTitle(void) const
+{
+  return (wxString&)m_title;
+};
+
+void wxDialog::OnApply( wxCommandEvent &WXUNUSED(event) )
+{
+  if (Validate()) TransferDataFromWindow();
+};
+
+void wxDialog::OnCancel( wxCommandEvent &WXUNUSED(event) )
+{
+  if (IsModal())
+    EndModal(wxID_CANCEL);
+  else
+  {
+    SetReturnCode(wxID_CANCEL);
+    this->Show(FALSE);
+  };
+};
+
+void wxDialog::OnOk( wxCommandEvent &WXUNUSED(event) )
+{
+  if ( Validate() && TransferDataFromWindow())
+  {
+    if (IsModal()) 
+      EndModal(wxID_OK);
+    else
+    {
+      SetReturnCode(wxID_OK);
+      this->Show(FALSE);
+    };
+  };
+  EndModal( wxID_OK );
+};
+
+void wxDialog::OnPaint( wxPaintEvent& WXUNUSED(event) )
+{
+  // yes
+};
+
+bool wxDialog::OnClose(void)
+{
+  static wxList closing;
+
+  if (closing.Member(this)) return FALSE;   // no loops
+
+  closing.Append(this);
+
+  wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
+  cancelEvent.SetEventObject( this );
+  GetEventHandler()->ProcessEvent(cancelEvent);
+  closing.DeleteObject(this);
+  
+  return FALSE;
+}
+
+void wxDialog::OnCloseWindow(wxCloseEvent& event)
+{
+  if (GetEventHandler()->OnClose() || event.GetForce())
+  {
+    this->Destroy();
+  };
+};
+
+bool wxDialog::Show( const bool show )
+{
+  if (!show && m_modalShowing)
+  {
+    EndModal( wxID_CANCEL );
+  };
+
+  wxWindow::Show( show );
+  
+  if (show) InitDialog();
+  
+  if (show && m_modalShowing)
+  {
+    gtk_grab_add( m_widget );
+    gtk_main();
+    gtk_grab_remove( m_widget );
+  };
+  
+  return TRUE;
+};
+
+int wxDialog::ShowModal(void)
+{
+  Show( TRUE );
+  return GetReturnCode();
+};
+
+void wxDialog::EndModal( int retCode )
+{
+  gtk_main_quit();
+  SetReturnCode( retCode );
+};
+
+void wxDialog::InitDialog(void)
+{
+  wxWindow::InitDialog();
+};
+
diff --git a/src/gtk1/dnd.cpp b/src/gtk1/dnd.cpp
new file mode 100644
index 0000000000..cca46f3b87
--- /dev/null
+++ b/src/gtk1/dnd.cpp
@@ -0,0 +1,207 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        dnd.cpp
+// Purpose:     wxDropTarget class
+// Author:      Robert Roebling
+// Copyright:   Robert Roebling
+// Licence:     wxWindows license
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "dnd.h"
+#endif
+
+#include "wx/dnd.h"
+#include "wx/window.h"
+#include "wx/app.h"
+#include "wx/gdicmn.h"
+
+#include "gdk/gdkprivate.h"
+
+#include <X11/Xlib.h>
+
+// ----------------------------------------------------------------------------
+// global
+// ----------------------------------------------------------------------------
+
+extern bool g_blockEventsOnDrag;
+
+// ----------------------------------------------------------------------------
+// wxDropTarget
+// ----------------------------------------------------------------------------
+
+wxDropTarget::wxDropTarget()
+{
+};
+
+wxDropTarget::~wxDropTarget()
+{
+};
+
+void wxDropTarget::Drop( GdkEvent *event, int x, int y )
+{
+  printf( "Drop data is of type %s.\n", event->dropdataavailable.data_type );
+  
+  OnDrop( x, y, (char *)event->dropdataavailable.data);
+};
+
+void wxDropTarget::UnregisterWidget( GtkWidget *widget )
+{
+  gtk_widget_dnd_drop_set( widget, FALSE, NULL, 0, FALSE );
+};
+
+// ----------------------------------------------------------------------------
+// wxTextDropTarget
+// ----------------------------------------------------------------------------
+
+bool wxTextDropTarget::OnDrop( long x, long y, const void *pData )
+{
+  OnDropText( x, y, (const char*)pData );
+  return TRUE;
+};
+
+bool wxTextDropTarget::OnDropText( long x, long y, const char *psz )
+{
+  printf( "Got dropped text: %s.\n", psz );
+  printf( "At x: %d, y: %d.\n", (int)x, (int)y );
+  return TRUE;
+};
+
+void wxTextDropTarget::RegisterWidget( GtkWidget *widget )
+{
+  char *accepted_drop_types[] = { "text/plain" };
+  gtk_widget_dnd_drop_set( widget, TRUE, accepted_drop_types, 1, FALSE );
+};
+
+//-------------------------------------------------------------------------
+// wxDragSource
+//-------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// drag request
+
+void gtk_drag_callback( GtkWidget *widget, GdkEvent *event, wxDragSource *drag )
+{
+  printf( "OnDragRequest.\n" );
+  
+  gtk_widget_dnd_data_set( widget, event, drag->m_data, drag->m_size );
+};
+
+wxDragSource::wxDragSource( wxWindow *win )
+{
+  g_blockEventsOnDrag = TRUE;
+
+  m_window = win;
+  m_widget = win->m_widget;
+  if (win->m_wxwindow) m_widget = win->m_wxwindow;
+ 
+  m_data = NULL;
+  m_size = 0;
+  
+  m_defaultCursor = wxCursor( wxCURSOR_NO_ENTRY );
+  m_goaheadCursor = wxCursor( wxCURSOR_HAND );
+};
+
+wxDragSource::~wxDragSource(void)
+{
+  g_blockEventsOnDrag = FALSE;
+};
+   
+void wxDragSource::SetData( char *data, const long size )
+{
+  m_size = size;
+  m_data = data;
+};
+
+void wxDragSource::Start( int x, int y )
+{
+  if (gdk_dnd.dnd_grabbed) return;
+  if (gdk_dnd.drag_really) return;
+  if (m_size == 0) return;
+  if (!m_data) return;
+  
+  GdkWindowPrivate *wp = (GdkWindowPrivate*) m_widget->window;
+  
+  RegisterWindow();
+  ConnectWindow();
+  
+  gdk_dnd.drag_perhaps = TRUE;
+
+  gdk_dnd.dnd_drag_start.x = 5;
+  gdk_dnd.dnd_drag_start.y = 5;
+  gdk_dnd.real_sw = wp;
+	  
+  if (gdk_dnd.drag_startwindows)
+  {
+    g_free( gdk_dnd.drag_startwindows );
+    gdk_dnd.drag_startwindows = NULL;
+  };
+  gdk_dnd.drag_numwindows = gdk_dnd.drag_really = 0;
+  
+  XWindowAttributes dnd_winattr;
+  XGetWindowAttributes( gdk_display, wp->xwindow, &dnd_winattr );
+  wp->dnd_drag_savedeventmask = dnd_winattr.your_event_mask;
+  
+  gdk_dnd_drag_addwindow( m_widget->window );
+  
+  GdkEventDragBegin ev;
+  ev.type = GDK_DRAG_BEGIN;
+  ev.window = m_widget->window;
+  ev.u.allflags = 0;
+  ev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
+  
+  gdk_event_put( (GdkEvent*)&ev );
+  
+  XGrabPointer( gdk_display, wp->xwindow, False, 
+                ButtonMotionMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
+		GrabModeAsync, GrabModeAsync, gdk_root_window, None, CurrentTime );
+		
+  gdk_dnd_set_drag_cursors( m_defaultCursor.GetCursor(), m_goaheadCursor.GetCursor() );
+  
+  gdk_dnd.dnd_grabbed = TRUE;
+  gdk_dnd.drag_really = 1;
+  gdk_dnd_display_drag_cursor( x, y, FALSE, TRUE );
+  
+  while (gdk_dnd.drag_really || gdk_dnd.drag_perhaps) wxYield();
+  
+  UnconnectWindow();
+  UnregisterWindow();
+};
+
+void wxDragSource::ConnectWindow(void)
+{
+  gtk_signal_connect( GTK_OBJECT(m_widget), "drag_request_event",
+    GTK_SIGNAL_FUNC(gtk_drag_callback), (gpointer)this );
+};
+
+void wxDragSource::UnconnectWindow(void)
+{
+  if (!m_widget) return;
+  
+  gtk_signal_disconnect_by_data( GTK_OBJECT(m_widget), (gpointer)this );
+};
+
+void wxDragSource::UnregisterWindow(void)
+{
+  if (!m_widget) return;
+  
+  gtk_widget_dnd_drag_set( m_widget, FALSE, NULL, 0 );
+};
+  
+//-------------------------------------------------------------------------
+// wxTextDragSource
+//-------------------------------------------------------------------------
+
+void wxTextDragSource::SetTextData( const wxString &text )
+{
+  m_tmp = text;
+  SetData( WXSTRINGCAST(m_tmp), m_tmp.Length()+1 );
+};
+
+void wxTextDragSource::RegisterWindow(void)
+{
+  if (!m_widget) return;
+  
+  char *accepted_drop_types[] = { "text/plain" };
+  gtk_widget_dnd_drag_set( m_widget, TRUE, accepted_drop_types, 1 );
+};
+
diff --git a/src/gtk1/fdiag.xbm b/src/gtk1/fdiag.xbm
new file mode 100644
index 0000000000..67d3b4732a
--- /dev/null
+++ b/src/gtk1/fdiag.xbm
@@ -0,0 +1,6 @@
+#define fdiag_width 16
+#define fdiag_height 16
+static char fdiag_bits[] = {
+   0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20,
+   0x40, 0x40, 0x80, 0x80, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08,
+   0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80};
diff --git a/src/gtk1/filedlg.cpp b/src/gtk1/filedlg.cpp
new file mode 100644
index 0000000000..1f16d2d1cd
--- /dev/null
+++ b/src/gtk1/filedlg.cpp
@@ -0,0 +1,146 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        filedlg.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "filedlg.h"
+#endif
+
+#include "wx/filedlg.h"
+#include "wx/utils.h"
+#include "wx/intl.h"
+
+//-----------------------------------------------------------------------------
+// wxFileDialog
+//-----------------------------------------------------------------------------
+
+void gtk_filedialog_ok_callback( GtkWidget *WXUNUSED(widget), gpointer data )
+{
+  wxFileDialog *dialog = (wxFileDialog*)data;
+  wxCommandEvent event(0);
+  dialog->OnOk( event );
+};
+
+void gtk_filedialog_cancel_callback( GtkWidget *WXUNUSED(widget), gpointer data )
+{
+  wxFileDialog *dialog = (wxFileDialog*)data;
+  wxCommandEvent event(0);
+  dialog->OnCancel( event );
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxFileDialog,wxDialog)
+
+wxFileDialog::wxFileDialog(wxWindow *parent, const wxString& message,
+        const wxString& defaultDir, const wxString& defaultFileName, 
+	const wxString& wildCard,
+        long style, const wxPoint& pos )
+{
+  m_needParent = FALSE;
+  
+  PreCreation( parent, -1, pos, wxDefaultSize, style, "filedialog" );
+  m_message = message;
+  m_path = "";
+  m_fileName = defaultFileName;
+  m_dir = defaultDir;
+  m_wildCard = wildCard;
+  m_filterIndex = 1;
+  
+  m_widget = gtk_file_selection_new( "File selection" );
+  
+  GtkFileSelection *sel = GTK_FILE_SELECTION(m_widget);
+  
+  gtk_signal_connect( GTK_OBJECT(sel->ok_button), "clicked", 
+    GTK_SIGNAL_FUNC(gtk_filedialog_ok_callback), (gpointer*)this );
+
+  gtk_signal_connect( GTK_OBJECT(sel->cancel_button), "clicked", 
+    GTK_SIGNAL_FUNC(gtk_filedialog_cancel_callback), (gpointer*)this );
+};
+
+int wxFileDialog::ShowModal(void)
+{
+  int ret = wxDialog::ShowModal();
+  if (ret == wxID_OK)
+  {
+    m_fileName = gtk_file_selection_get_filename( GTK_FILE_SELECTION(m_widget) );
+    m_path = gtk_file_selection_get_filename( GTK_FILE_SELECTION(m_widget) );
+  };
+  return ret;
+};
+    
+
+char *wxFileSelector(const char *title,
+                     const char *defaultDir, const char *defaultFileName,
+                     const char *defaultExtension, const char *filter, int flags,
+                     wxWindow *parent, int x, int y)
+{
+	wxString filter2("");
+	if ( defaultExtension && !filter )
+		filter2 = wxString("*.") + wxString(defaultExtension) ;
+	else if ( filter )
+		filter2 = filter;
+
+	wxString defaultDirString;
+	if (defaultDir)
+		defaultDirString = defaultDir;
+	else
+		defaultDirString = "";
+
+	wxString defaultFilenameString;
+	if (defaultFileName)
+		defaultFilenameString = defaultFileName;
+	else
+		defaultFilenameString = "";
+
+	wxFileDialog fileDialog(parent, title, defaultDirString, defaultFilenameString, 
+	  filter2, flags, wxPoint(x, y));
+
+	if ( fileDialog.ShowModal() == wxID_OK )
+	{
+		strcpy(wxBuffer, (const char *)fileDialog.GetPath());
+		return wxBuffer;
+	}
+	else
+		return NULL;
+};
+
+char* wxLoadFileSelector(const char *what, const char *extension, const char *default_name, 
+         wxWindow *parent )
+{
+  char *ext = (char *)extension;
+  
+  char prompt[50];
+  wxString str = _("Load %s file");
+  sprintf(prompt, str, what);
+
+  if (*ext == '.') ext++;
+  char wild[60];
+  sprintf(wild, "*.%s", ext);
+
+  return wxFileSelector (prompt, NULL, default_name, ext, wild, 0, parent);
+};
+
+char* wxSaveFileSelector(const char *what, const char *extension, const char *default_name, 
+         wxWindow *parent )
+{
+  char *ext = (char *)extension;
+  
+  char prompt[50];
+  wxString str = _("Save %s file");
+  sprintf(prompt, str, what);
+
+  if (*ext == '.') ext++;
+  char wild[60];
+  sprintf(wild, "*.%s", ext);
+
+  return wxFileSelector (prompt, NULL, default_name, ext, wild, 0, parent);
+};
+
+
+
+
diff --git a/src/gtk1/font.cpp b/src/gtk1/font.cpp
new file mode 100644
index 0000000000..1418bc0661
--- /dev/null
+++ b/src/gtk1/font.cpp
@@ -0,0 +1,822 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        font.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "font.h"
+#endif
+
+#include "wx/font.h"
+#include "wx/utils.h"
+#include <strings.h>
+
+//-----------------------------------------------------------------------------
+// local data
+//-----------------------------------------------------------------------------
+
+static char *wx_font_family [] = {
+    "wxDEFAULT", "wxDECORATIVE", "wxMODERN", "wxROMAN", "wxSCRIPT",
+    "wxSWISS", "wxTELETYPE",
+};
+static char *wx_font_style [] = {
+    "wxDEFAULT", "wxNORMAL", "wxSLANT", "wxITALIC",
+};
+static char *wx_font_weight [] = {
+    "wxDEFAULT", "wxNORMAL", "wxBOLD", "wxLIGHT",
+};
+
+extern wxFontNameDirectory wxTheFontNameDirectory;
+
+//-----------------------------------------------------------------------------
+// wxFont
+//-----------------------------------------------------------------------------
+
+class wxFontRefData: public wxObjectRefData
+{
+  public:
+  
+    wxFontRefData(void);
+    ~wxFontRefData(void);
+ 
+    wxList   m_scaled_xfonts;
+    int      m_pointSize;
+    int      m_family, m_style, m_weight;
+    bool     m_underlined;
+    int      m_fontId;
+    char*    m_faceName;
+     
+    bool     m_byXFontName;
+    GdkFont *m_font;
+    
+    friend wxFont;
+};
+
+wxFontRefData::wxFontRefData(void) : m_scaled_xfonts(wxKEY_INTEGER)
+{
+  m_byXFontName = FALSE;
+  m_pointSize = -1;
+  m_family = -1;
+  m_style = -1;
+  m_weight = -1;
+  m_underlined = FALSE;
+  m_fontId = 0;
+  m_faceName = NULL;
+  m_font = NULL;
+};
+
+wxFontRefData::~wxFontRefData(void)
+{
+  wxNode *node = m_scaled_xfonts.First();
+  while (node) 
+  {
+    GdkFont *font = (GdkFont*)node->Data();
+    wxNode *next = node->Next();
+    gdk_font_unref( font );
+    node = next;
+  };
+  if (m_faceName) 
+  {
+    delete m_faceName;
+    m_faceName = NULL;
+  };
+  if (m_font) gdk_font_unref( m_font );
+};
+
+//-----------------------------------------------------------------------------
+
+#define M_FONTDATA ((wxFontRefData *)m_refData)
+
+IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
+
+wxFont::wxFont(void)
+{
+  if (wxTheFontList) wxTheFontList->Append( this );
+};
+
+wxFont::wxFont( char *xFontName )
+{
+  if (!xFontName) return;
+  
+  m_refData = new wxFontRefData();
+  
+  M_FONTDATA->m_byXFontName = TRUE;
+  M_FONTDATA->m_font = gdk_font_load( xFontName );
+};
+
+wxFont::wxFont(int PointSize, int FontIdOrFamily, int Style, int Weight,
+	       bool Underlined, const char* Face)
+{
+  m_refData = new wxFontRefData();
+  
+  if ((M_FONTDATA->m_faceName = (Face) ? copystring(Face) : (char*)NULL) ) 
+  {
+    M_FONTDATA->m_fontId = wxTheFontNameDirectory.FindOrCreateFontId( Face, FontIdOrFamily );
+    M_FONTDATA->m_family  = wxTheFontNameDirectory.GetFamily( FontIdOrFamily );
+  }
+  else 
+  {
+    M_FONTDATA->m_fontId = FontIdOrFamily;
+    M_FONTDATA->m_family  = wxTheFontNameDirectory.GetFamily( FontIdOrFamily );
+  };
+  M_FONTDATA->m_style = Style;
+  M_FONTDATA->m_weight = Weight;
+  M_FONTDATA->m_pointSize = PointSize;
+  M_FONTDATA->m_underlined = Underlined;
+
+  if (wxTheFontList) wxTheFontList->Append( this );
+};
+
+wxFont::wxFont(int PointSize, const char *Face, int Family, int Style, 
+	       int Weight, bool Underlined)
+{
+  m_refData = new wxFontRefData();
+
+  M_FONTDATA->m_fontId = wxTheFontNameDirectory.FindOrCreateFontId( Face, Family );
+  M_FONTDATA->m_faceName = (Face) ? copystring(Face) : (char*)NULL;
+  M_FONTDATA->m_family = wxTheFontNameDirectory.GetFamily( M_FONTDATA->m_fontId );
+  M_FONTDATA->m_style = Style;
+  M_FONTDATA->m_weight = Weight;
+  M_FONTDATA->m_pointSize = PointSize;
+  M_FONTDATA->m_underlined = Underlined;
+
+  if (wxTheFontList) wxTheFontList->Append( this );
+};
+
+wxFont::wxFont( const wxFont& font )
+{ 
+  Ref( font ); 
+};
+
+wxFont::wxFont( const wxFont* font ) 
+{ 
+  UnRef(); 
+  if (font) Ref( *font ); 
+};
+
+wxFont::~wxFont(void)
+{
+  if (wxTheFontList) wxTheFontList->DeleteObject( this );
+};
+
+wxFont& wxFont::operator = ( const wxFont& font ) 
+{ 
+  if (*this == font) return (*this); 
+  Ref( font ); 
+  return *this; 
+};
+
+bool wxFont::operator == ( const wxFont& font ) 
+{ 
+  return m_refData == font.m_refData; 
+};
+
+bool wxFont::operator != ( const wxFont& font ) 
+{ 
+  return m_refData != font.m_refData; 
+};
+
+bool wxFont::Ok()
+{
+  return (m_refData != NULL);
+};
+
+int wxFont::GetPointSize(void) const
+{
+  return M_FONTDATA->m_pointSize;
+};
+
+wxString wxFont::GetFaceString(void) const
+{
+  wxString s = wxTheFontNameDirectory.GetFontName( M_FONTDATA->m_fontId );
+  return s;
+};
+
+wxString wxFont::GetFaceName(void) const
+{
+  wxString s = wxTheFontNameDirectory.GetFontName( M_FONTDATA->m_fontId );
+  return s; 
+};
+
+int wxFont::GetFamily(void) const
+{
+  return M_FONTDATA->m_family;
+};
+
+wxString wxFont::GetFamilyString(void) const
+{
+  wxString s = wx_font_family[M_FONTDATA->m_family];
+  return s;
+};
+
+int wxFont::GetFontId(void) const
+{
+  return M_FONTDATA->m_fontId; // stub
+};
+
+int wxFont::GetStyle(void) const
+{
+  return M_FONTDATA->m_style;
+};
+
+wxString wxFont::GetStyleString(void) const
+{
+  wxString s =  wx_font_style[M_FONTDATA->m_style];
+  return s;
+};
+
+int wxFont::GetWeight(void) const
+{
+  return M_FONTDATA->m_weight;
+};
+
+wxString wxFont::GetWeightString(void) const
+{
+  wxString s = wx_font_weight[M_FONTDATA->m_weight];
+  return s;
+};
+
+bool wxFont::GetUnderlined(void) const
+{
+  return M_FONTDATA->m_underlined;
+};
+
+//-----------------------------------------------------------------------------
+// get internal representation of font
+//-----------------------------------------------------------------------------
+
+// local help function
+static GdkFont *wxLoadQueryNearestFont(int point_size, int fontid,
+					   int style, int weight, 
+					   bool underlined);
+
+GdkFont *wxFont::GetInternalFont(float scale)
+{
+  if (M_FONTDATA->m_byXFontName) return M_FONTDATA->m_font;
+   
+  long int_scale = long(scale * 100.0 + 0.5); // key for fontlist
+  int point_scale = (M_FONTDATA->m_pointSize * 10 * int_scale) / 100;
+  GdkFont *font = NULL;
+
+  wxNode *node = M_FONTDATA->m_scaled_xfonts.Find(int_scale);
+  if (node) 
+  {
+    font = (GdkFont*)node->Data(); 
+  } 
+  else 
+  {
+     font = wxLoadQueryNearestFont( point_scale, M_FONTDATA->m_fontId, M_FONTDATA->m_style,
+				    M_FONTDATA->m_weight, M_FONTDATA->m_underlined );
+     M_FONTDATA->m_scaled_xfonts.Append( int_scale, (wxObject*)font );
+  };
+  if (!font)
+	printf("could not load any font");
+//	wxError("could not load any font", "wxFont");
+  return font;
+};
+
+//-----------------------------------------------------------------------------
+// local utilities to find a X font
+//-----------------------------------------------------------------------------
+
+static GdkFont *wxLoadQueryFont(int point_size, int fontid, int style,
+				    int weight, bool WXUNUSED(underlined))
+{
+    char buffer[512];
+    char *name = wxTheFontNameDirectory.GetScreenName( fontid, weight, style );
+
+    if (!name)
+	name = "-*-*-*-*-*-*-*-%d-*-*-*-*-*-*";
+    sprintf(buffer, name, point_size);
+
+    return gdk_font_load( buffer );
+}
+
+static GdkFont *wxLoadQueryNearestFont(int point_size, int fontid,
+					   int style, int weight,
+					   bool underlined)
+{
+    GdkFont *font;
+
+    font = wxLoadQueryFont( point_size, fontid, style, weight, underlined );
+
+    if (!font) {
+	// search up and down by stepsize 10
+	int max_size = point_size + 20 * (1 + (point_size/180));
+	int min_size = point_size - 20 * (1 + (point_size/180));
+	int i;
+
+	// Search for smaller size (approx.)
+	for (i=point_size-10; !font && i >= 10 && i >= min_size; i -= 10)
+	    font = wxLoadQueryFont(i, fontid, style, weight, underlined);
+	// Search for larger size (approx.)
+	for (i=point_size+10; !font && i <= max_size; i += 10)
+	    font = wxLoadQueryFont(i, fontid, style, weight, underlined);
+	// Try default family
+	if (!font && fontid != wxDEFAULT)
+	    font = wxLoadQueryFont(point_size, wxDEFAULT, style, 
+				   weight, underlined);
+	// Bogus font
+	if (!font)
+	    font = wxLoadQueryFont(120, wxDEFAULT, wxNORMAL, wxNORMAL,
+				    underlined);
+    }
+    return font;
+}
+
+//-----------------------------------------------------------------------------
+// face names and index functions
+//-----------------------------------------------------------------------------
+
+static char *font_defaults[] = {
+    "FamilyDefault", "Default",
+    "FamilyRoman", "Roman",
+    "FamilyDecorative", "Decorative",
+    "FamilyModern", "Modern",
+    "FamilyTeletype", "Teletype",
+    "FamilySwiss", "Swiss",
+    "FamilyScript", "Script",
+
+    "AfmMedium", "",
+    "AfmBold", "Bo",
+    "AfmLight", "",
+    "AfmStraight", "",
+    "AfmItalic", "${AfmSlant}",
+    "AfmSlant", "O",
+    "AfmRoman", "Ro",
+    "AfmTimes", "Times",
+    "AfmHelvetica", "Helv",
+    "AfmCourier", "Cour",
+    
+    "Afm___", "${AfmTimes,$[weight],$[style]}",
+
+    "AfmTimes__", "${AfmTimes}${Afm$[weight]}${Afm$[style]}",
+    "AfmTimesMediumStraight", "${AfmTimes}${AfmRoman}",
+    "AfmTimesLightStraight", "${AfmTimes}${AfmRoman}",
+    "AfmTimes_Italic", "${AfmTimes}$[weight]${AfmItalic}",
+    "AfmTimes_Slant", "${AfmTimes}$[weight]${AfmItalic}",
+
+    "AfmSwiss__", "${AfmHelvetica}${Afm$[weight]}${Afm$[style]}",
+    "AfmModern__", "${AfmCourier}${Afm$[weight]}${Afm$[style]}",
+
+    "AfmTeletype__", "${AfmModern,$[weight],$[style]}",
+
+    "PostScriptMediumStraight", "",
+    "PostScriptMediumItalic", "-Oblique",
+    "PostScriptMediumSlant", "-Oblique",
+    "PostScriptLightStraight", "",
+    "PostScriptLightItalic", "-Oblique",
+    "PostScriptLightSlant", "-Oblique",
+    "PostScriptBoldStraight", "-Bold",
+    "PostScriptBoldItalic", "-BoldOblique",
+    "PostScriptBoldSlant", "-BoldOblique",
+    
+#if WX_NORMALIZED_PS_FONTS
+    "PostScript___", "${PostScriptTimes,$[weight],$[style]}",
+#else
+    "PostScriptRoman__", "${PostScriptTimes,$[weight],$[style]}",
+    "PostScript___", "LucidaSans${PostScript$[weight]$[style]}",
+#endif
+
+    "PostScriptTimesMedium", "",
+    "PostScriptTimesLight", "",
+    "PostScriptTimesBold", "Bold",
+
+    "PostScriptTimes__", "Times${PostScript$[weight]$[style]}",
+    "PostScriptTimesMediumStraight", "Times-Roman",
+    "PostScriptTimesLightStraight", "Times-Roman",
+    "PostScriptTimes_Slant", "Times-${PostScriptTimes$[weight]}Italic",
+    "PostScriptTimes_Italic", "Times-${PostScriptTimes$[weight]}Italic",
+
+    "PostScriptSwiss__", "Helvetica${PostScript$[weight]$[style]}",
+    "PostScriptModern__", "Courier${PostScript$[weight]$[style]}",
+
+    "PostScriptTeletype__", "${PostScriptModern,$[weight],$[style]}",
+
+#if !WX_NORMALIZED_PS_FONTS
+    "PostScriptScript__", "Zapf-Chancery-MediumItalic",
+#endif
+
+    "ScreenMedium", "medium",
+    "ScreenBold", "bold",
+    "ScreenLight", "light",
+    "ScreenStraight", "r",
+    "ScreenItalic", "i",
+    "ScreenSlant", "o",
+
+    "ScreenDefaultBase", "misc-fixed",
+    "ScreenRomanBase", "*-times",
+    "ScreenDecorativeBase", "*-helvetica",
+    "ScreenModernBase", "*-courier",
+    "ScreenTeletypeBase", "*-lucidatypewriter",
+    "ScreenSwissBase", "*-lucida",
+    "ScreenScriptBase", "*-zapfchancery",
+
+    "ScreenStdSuffix", "-${Screen$[weight]}-${Screen$[style]}"
+    "-normal-*-*-%d-*-*-*-*-*-*",
+
+    "Screen___",
+    "-${ScreenDefaultBase}${ScreenStdSuffix}",
+    "ScreenRoman__",
+    "-${ScreenRomanBase}${ScreenStdSuffix}",
+    "ScreenDecorative__",
+    "-${ScreenDecorativeBase}${ScreenStdSuffix}",
+    "ScreenModern__",
+    "-${ScreenModernBase}${ScreenStdSuffix}",
+    "ScreenTeletype__",
+    "-${ScreenTeletypeBase}${ScreenStdSuffix}",
+    "ScreenSwiss__",
+    "-${ScreenSwissBase}${ScreenStdSuffix}",
+    "ScreenScript__",
+    "-${ScreenScriptBase}${ScreenStdSuffix}",
+    NULL
+};
+
+enum {wxWEIGHT_NORMAL, wxWEIGHT_BOLD,  wxWEIGHT_LIGHT, wxNUM_WEIGHTS};
+enum {wxSTYLE_NORMAL,  wxSTYLE_ITALIC, wxSTYLE_SLANT,  wxNUM_STYLES};
+
+static int WCoordinate(int w)
+{
+    switch (w) {
+    case wxBOLD:   return wxWEIGHT_BOLD;
+    case wxLIGHT:  return wxWEIGHT_LIGHT;
+    case wxNORMAL:
+    default:       return wxWEIGHT_NORMAL;
+    }
+}
+
+static int SCoordinate(int s)
+{
+    switch (s) {
+    case wxITALIC: return wxSTYLE_ITALIC;
+    case wxSLANT:  return wxSTYLE_SLANT;
+    case wxNORMAL:
+    default:       return wxSTYLE_NORMAL;
+    }
+}
+
+//-----------------------------------------------------------------------------
+// wxSuffixMap
+//-----------------------------------------------------------------------------
+
+class wxSuffixMap {
+public:
+    ~wxSuffixMap(void);
+
+    inline char *GetName(int weight, int style)
+    {
+	return ( map [WCoordinate(weight)] [SCoordinate(style)] );
+    }
+
+    char *map[wxNUM_WEIGHTS][wxNUM_STYLES];
+    void Initialize(const char *, const char *);
+};
+
+//#if !USE_RESOURCES
+#define wxGetResource(a, b, c) 0
+//#endif
+
+static void SearchResource(const char *prefix, const char **names, int count, char **v)
+{
+    int k, i, j;
+    char resource[1024], **defaults, *internal;
+
+    k = 1 << count;
+    
+    *v = NULL;
+    internal = NULL;
+
+    for (i = 0; i < k; i++) {
+	strcpy(resource, prefix);
+	for (j = 0; j < count; j++) {
+	    if (!(i & (1 << j)))
+		strcat(resource, names[j]);
+	    else
+		strcat(resource, "_");
+	}
+	if (wxGetResource(wxAPP_CLASS, (char *)resource, v))
+	    return;
+	if (!internal) {
+	    defaults = font_defaults;
+	    while (*defaults) {
+		if (!strcmp(*defaults, resource)) {
+		    internal = defaults[1];
+		    break;
+		}
+		defaults += 2;
+	    }
+	}
+    }
+    if (internal)
+	*v = copystring(internal);
+}
+
+wxSuffixMap::~wxSuffixMap(void)
+{
+    int k, j;
+
+    for (k = 0; k < wxNUM_WEIGHTS; ++k)
+	for (j = 0; j < wxNUM_STYLES; ++j)
+	    if (map[k][j]) {
+		delete[] map[k][j];
+		map[k][j] = NULL;
+	    }
+}
+
+void wxSuffixMap::Initialize(const char *resname, const char *devresname)
+{
+    const char *weight, *style;
+    char *v;
+    int i, j, k;
+    const char *names[3];
+
+    for (k = 0; k < wxNUM_WEIGHTS; k++) {
+	switch (k) {
+	case wxWEIGHT_NORMAL: weight = "Medium"; break;
+	case wxWEIGHT_LIGHT:  weight = "Light"; break;
+	case wxWEIGHT_BOLD:
+	default:	      weight = "Bold";
+	}
+	for (j = 0; j < wxNUM_STYLES; j++) {
+	    switch (j) {
+	    case wxSTYLE_NORMAL: style = "Straight"; break;
+	    case wxSTYLE_ITALIC: style = "Italic"; break;
+	    case wxSTYLE_SLANT:
+	    default:		 style = "Slant";
+	    }
+	    names[0] = resname;
+	    names[1] = weight;
+	    names[2] = style;
+
+	    SearchResource(devresname, names, 3, &v);
+
+	    /* Expand macros in the found string: */
+	found:
+	    int len, closer = 0, startpos = 0;
+	    
+	    len = (v ? strlen(v) : 0);
+	    for (i = 0; i < len; i++) {
+		if (v[i] == '$' && ((v[i+1] == '[') || (v[i+1] == '{'))) {
+		    startpos = i;
+		    closer   = (v[i+1] == '[') ? ']' : '}';
+		    ++i;
+		} else if (v[i] == closer) {
+		    int newstrlen;
+		    const char *r = NULL; bool delete_r = FALSE;
+		    char *name;
+	  
+		    name = v + startpos + 2;
+		    v[i] = 0;
+
+		    if (closer == '}') {
+			int i, count, len;
+			char **names;
+
+			for (i = 0, count = 1; name[i]; i++)
+			    if (name[i] == ',')
+				count++;
+	    
+			len = i;
+
+			names = new char*[count];
+			names[0] = name;
+			for (i = 0, count = 1; i < len; i++)
+			    if (name[i] == ',') {
+				names[count++] = name + i + 1;
+				name[i] = 0;
+			    }
+
+			SearchResource("", (const char **)names, count, (char **)&r);
+			delete_r = (r != 0);
+			delete[] names;
+			
+			if (!r) {
+			    for (i = 0; i < len; i++)
+				if (!name[i])
+				    name[i] = ',';
+			    r = "";
+			    printf("Bad resource name \"%s\" in font lookup\n", name);
+			}
+		    } else if (!strcmp(name, "weight")) {
+			r = weight;
+		    } else if (!strcmp(name, "style")) {
+			r = style;
+		    } else if (!strcmp(name, "family")) {
+			r = resname;
+		    } else {
+			r = "";
+			printf("Bad font macro name \"%s\"\n", name);
+		    }
+
+		    // add r to v
+		    newstrlen = strlen(r);
+		    char *naya = new char[startpos + newstrlen + len - i];
+		    memcpy(naya, v, startpos);
+		    memcpy(naya + startpos, r, newstrlen);
+		    memcpy(naya + startpos + newstrlen, v + i + 1, len - i);
+		    if (delete_r)
+		      delete[] (char*)r;
+		    delete[] v;
+		    v = naya;
+		    
+		    goto found;
+		}
+	    }
+	    /* We have a final value: */
+	    map[k][j] = v;
+	}
+    }
+}
+
+//-----------------------------------------------------------------------------
+// wxFontNameItem
+//-----------------------------------------------------------------------------
+
+class wxFontNameItem : public wxObject {
+DECLARE_DYNAMIC_CLASS(wxFontNameItem)
+public:
+    wxFontNameItem(const char *name, int id, int family);
+    ~wxFontNameItem();
+
+    inline char* GetScreenName(int w, int s)     {return screen.GetName(w, s);}
+    inline char* GetPostScriptName(int w, int s) {return printing.GetName(w, s);}
+    inline char* GetAFMName(int w, int s)        {return afm.GetName(w, s);}
+    inline char* GetName(void)                   {return name;}
+    inline int   GetFamily(void)                 {return family;}
+    inline int   GetId(void)                     {return id;}
+    inline bool  IsRoman(void)                   {return isroman;}
+#if WXDEBUG
+    void Dump(ostream& str);
+#endif
+
+    int id;
+    int family;
+    char *name;
+    wxSuffixMap screen, printing, afm;
+    bool isroman;
+};
+
+IMPLEMENT_ABSTRACT_CLASS(wxFontNameItem, wxObject)
+
+wxFontNameItem::wxFontNameItem(const char *Name, int Id, int Family)
+{
+    name   = copystring(Name);
+    id     = Id;
+    family = Family;
+
+    screen.  Initialize(name, "Screen");
+    printing.Initialize(name, "PostScript");
+    afm.     Initialize(name, "Afm");
+}
+
+wxFontNameItem::~wxFontNameItem(void)
+{
+    if (name)
+	delete[] name;
+    name = NULL;
+}
+
+#if WXDEBUG
+void wxFontNameItem::Dump(ostream& str)
+{
+    str << "wxFontNameItem(" << name << ")";
+}
+#endif
+
+//-----------------------------------------------------------------------------
+// wxFontDirectory
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxFontNameDirectory, wxObject)
+
+wxFontNameDirectory::wxFontNameDirectory(void)
+{
+    table = new wxHashTable(wxKEY_INTEGER, 20);
+    nextFontId = -1;
+    Initialize();
+}
+
+wxFontNameDirectory::~wxFontNameDirectory()
+{
+    // Cleanup wxFontNameItems allocated
+    table->BeginFind();
+    wxNode *node = table->Next();
+    while (node) {
+	wxFontNameItem *item = (wxFontNameItem*)node->Data();
+	delete item;
+	node = table->Next();
+    }
+    delete table;
+}
+
+int wxFontNameDirectory::GetNewFontId(void)
+{
+    return (nextFontId--);
+}
+
+void wxFontNameDirectory::Initialize()
+{
+    Initialize(wxDEFAULT,    wxDEFAULT,    "Default");
+    Initialize(wxDECORATIVE, wxDECORATIVE, "Decorative");
+    Initialize(wxROMAN,      wxROMAN,      "Roman");
+    Initialize(wxMODERN,     wxMODERN,     "Modern");
+    Initialize(wxTELETYPE,   wxTELETYPE,   "Teletype");
+    Initialize(wxSWISS,      wxSWISS,      "Swiss");
+    Initialize(wxSCRIPT,     wxSCRIPT,     "Script");
+}
+
+void wxFontNameDirectory::Initialize(int fontid, int family, const char *resname)
+{
+    char *fam, resource[256];
+  
+    sprintf(resource, "Family%s", resname);
+    SearchResource((const char *)resource, NULL, 0, (char **)&fam);
+    if (fam) {
+	if      (!strcmp(fam, "Default"))	family = wxDEFAULT;
+	else if (!strcmp(fam, "Roman"))		family = wxROMAN;
+	else if (!strcmp(fam, "Decorative"))	family = wxDECORATIVE;
+	else if (!strcmp(fam, "Modern"))	family = wxMODERN;
+	else if (!strcmp(fam, "Teletype"))	family = wxTELETYPE;
+	else if (!strcmp(fam, "Swiss"))		family = wxSWISS;
+	else if (!strcmp(fam, "Script"))	family = wxSCRIPT;
+	delete[] fam; // free resource
+    }
+    table->Put(fontid, new wxFontNameItem(resname, fontid, family));
+}
+
+int wxFontNameDirectory::FindOrCreateFontId(const char *name, int family)
+{
+    int id;
+
+    // font exists -> return id
+    if ( (id = GetFontId(name)) ) return id;
+    // create new font
+    Initialize(id=GetNewFontId(), family, name);
+    return id;
+}
+
+char *wxFontNameDirectory::GetScreenName(int fontid, int weight, int style)
+{
+    wxFontNameItem *item = (wxFontNameItem*)table->Get(fontid); // find font
+    if (item)
+	return item->GetScreenName(weight, style);
+    // font does not exist
+    return NULL;
+}
+
+char *wxFontNameDirectory::GetPostScriptName(int fontid, int weight, int style)
+{
+    wxFontNameItem *item = (wxFontNameItem*)table->Get(fontid); // find font
+    if (item)
+	return item->GetPostScriptName(weight, style);
+    // font does not exist
+    return NULL;
+}
+
+char *wxFontNameDirectory::GetAFMName(int fontid, int weight, int style)
+{
+    wxFontNameItem *item = (wxFontNameItem *)table->Get(fontid); // find font
+    if (item)
+	return item->GetAFMName(weight, style);
+    // font does not exist
+    return NULL;
+}
+
+char *wxFontNameDirectory::GetFontName(int fontid)
+{
+    wxFontNameItem *item = (wxFontNameItem *)table->Get(fontid); // find font
+    if (item)
+	return item->GetName();
+    // font does not exist
+    return NULL;
+}
+
+int wxFontNameDirectory::GetFontId(const char *name)
+{
+    wxNode *node;
+
+    table->BeginFind();
+
+    while ( (node = table->Next()) ) {
+	wxFontNameItem *item = (wxFontNameItem*)node->Data();
+	if (!strcmp(name, item->name))
+	    return item->id;
+    }
+    // font does not exist
+    return 0;
+}
+
+int wxFontNameDirectory::GetFamily(int fontid)
+{
+    wxFontNameItem *item = (wxFontNameItem *)table->Get(fontid);
+  
+    if (item)
+	return item->family;
+    // font does not exist
+    return wxDEFAULT;
+}
diff --git a/src/gtk1/frame.cpp b/src/gtk1/frame.cpp
new file mode 100644
index 0000000000..f70d0b9f31
--- /dev/null
+++ b/src/gtk1/frame.cpp
@@ -0,0 +1,353 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        frame.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "frame.h"
+#endif
+
+#include "wx/frame.h"
+#include "wx/dialog.h"
+#include "wx/control.h"
+#include "wx/app.h"
+#include "wx/gtk/win_gtk.h"
+
+const wxMENU_HEIGHT    = 28;
+const wxSTATUS_HEIGHT  = 25;
+
+extern wxList wxTopLevelWindows;
+extern wxList wxPendingDelete;
+
+//-----------------------------------------------------------------------------
+// wxFrame
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// size
+
+void gtk_frame_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxFrame *win )
+{ 
+  if (!win->HasVMT()) return;
+
+/*
+  printf( "OnFrameResize from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  win->GtkOnSize( alloc->width, alloc->height );
+};
+
+//-----------------------------------------------------------------------------
+// delete
+
+bool gtk_frame_delete_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxFrame *win )
+{ 
+/*
+  printf( "OnDelete from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  win->Close();
+
+  return TRUE;
+};
+
+//-----------------------------------------------------------------------------
+
+BEGIN_EVENT_TABLE(wxFrame, wxWindow)
+  EVT_CLOSE(wxFrame::OnCloseWindow)
+  EVT_SIZE(wxFrame::OnSize)
+END_EVENT_TABLE()
+
+IMPLEMENT_DYNAMIC_CLASS(wxFrame,wxWindow)
+
+wxFrame::wxFrame(void)
+{
+  m_doingOnSize = FALSE;
+  m_frameMenuBar = NULL;
+  m_frameStatusBar = NULL;
+  m_sizeSet = FALSE;
+  wxTopLevelWindows.Insert( this );
+};
+
+wxFrame::wxFrame( wxWindow *parent, const wxWindowID id, const wxString &title, 
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  m_sizeSet = FALSE;
+  Create( parent, id, title, pos, size, style, name );
+  wxTopLevelWindows.Insert( this );
+};
+
+bool wxFrame::Create( wxWindow *parent, const wxWindowID id, const wxString &title,
+      const wxPoint &pos, const wxSize &size,
+      const long style, const wxString &name )
+{
+  m_needParent = FALSE;
+  m_mainWindow = NULL;
+  m_wxwindow = NULL;
+  
+  PreCreation( parent, id, pos, size, style, name );
+
+  m_doingOnSize = FALSE;
+  
+  m_title = title;
+  
+  m_widget = gtk_window_new( GTK_WINDOW_TOPLEVEL );
+  if ((size.x != -1) && (size.y != -1)) 
+    gtk_widget_set_usize( m_widget, m_width, m_height );
+  if ((pos.x != -1) && (pos.y != -1)) 
+    gtk_widget_set_uposition( m_widget, m_x, m_y );
+  
+  gtk_window_set_title( GTK_WINDOW(m_widget), title );
+  GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
+  
+  gtk_widget_set( m_widget, "GtkWindow::allow_shrink", TRUE, NULL);
+  
+  gtk_signal_connect( GTK_OBJECT(m_widget), "delete_event", 
+    GTK_SIGNAL_FUNC(gtk_frame_delete_callback), (gpointer)this );
+    
+  m_mainWindow = gtk_myfixed_new();
+  gtk_widget_show( m_mainWindow );
+  GTK_WIDGET_UNSET_FLAGS( m_mainWindow, GTK_CAN_FOCUS );
+  
+  gtk_container_add( GTK_CONTAINER(m_widget), m_mainWindow );
+  gtk_widget_set_uposition( m_mainWindow, 0, 0 );
+  
+  m_wxwindow = gtk_myfixed_new();
+  gtk_widget_show( m_wxwindow );
+  GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
+  
+  gtk_container_add( GTK_CONTAINER(m_mainWindow), m_wxwindow );
+  
+  m_frameMenuBar = NULL;
+  m_frameStatusBar = NULL;
+  
+  gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate", 
+    GTK_SIGNAL_FUNC(gtk_frame_size_callback), (gpointer)this );
+  
+  PostCreation();
+  
+  gtk_widget_realize( m_mainWindow );
+  
+  return TRUE;
+};
+
+wxFrame::~wxFrame(void)
+{
+  if (m_frameMenuBar) delete m_frameMenuBar;
+  if (m_frameStatusBar) delete m_frameStatusBar;
+  
+//  if (m_mainWindow) gtk_widget_destroy( m_mainWindow );
+
+  wxTopLevelWindows.DeleteObject( this );
+  if (wxTopLevelWindows.Number() == 0) wxTheApp->ExitMainLoop();
+};
+      
+bool wxFrame::Show( const bool show )
+{
+  if (show)
+  {
+    wxSizeEvent event( wxSize(m_width,m_height), GetId() );
+    m_sizeSet = FALSE;
+    ProcessEvent( event );
+  };
+  return wxWindow::Show( show );
+};
+
+void wxFrame::Enable( const bool enable )
+{
+  wxWindow::Enable( enable );
+  gtk_widget_set_sensitive( m_mainWindow, enable );
+};
+
+void wxFrame::OnCloseWindow( wxCloseEvent& WXUNUSED(event) )
+{
+  this->Destroy();
+};
+
+bool wxFrame::Destroy(void)
+{
+  if (!wxPendingDelete.Member(this))
+    wxPendingDelete.Append(this);
+    
+  return TRUE;
+}
+
+void wxFrame::GetClientSize( int *width, int *height ) const
+{
+  wxWindow::GetClientSize( width, height );
+  if (height)
+  {
+    if (m_frameMenuBar) (*height) -= wxMENU_HEIGHT;
+    if (m_frameStatusBar) (*height) -= wxSTATUS_HEIGHT;
+  };
+};
+
+void wxFrame::GtkOnSize( int width, int height )
+{
+  if ((m_height == height) && (m_width == width) &&
+      (m_sizeSet)) return;
+  if (!m_mainWindow) return;
+  if (!m_wxwindow) return;
+
+  m_width = width;
+  m_height = height;
+  
+  gtk_widget_set_usize( m_widget, width, height );
+  
+  int main_x = 0;
+  int main_y = 0;
+  int main_height = height;
+  int main_width = width;
+  
+  // This emulates Windows behaviour:
+  // The menu bar is part of the main window, but the status bar
+  // is on the implementation side in the client area. The
+  // function GetClientSize returns the size of the client area
+  // minus the status bar height. Under wxGTK, the main window
+  // is represented by m_mainWindow. The menubar is inserted
+  // into m_mainWindow whereas the statusbar is insertes into
+  // m_wxwindow just like any other window.
+  
+//  not really needed
+  gtk_widget_set_usize( m_mainWindow, width, height );
+    
+  if (m_frameMenuBar)
+  {
+    main_y = wxMENU_HEIGHT;
+    main_height -= wxMENU_HEIGHT;
+  };
+  
+  gtk_widget_set_uposition( GTK_WIDGET(m_wxwindow), main_x, main_y );
+  gtk_widget_set_usize( GTK_WIDGET(m_wxwindow), main_width, main_height );
+  
+  if (m_frameMenuBar)
+  {
+    gtk_widget_set_uposition( m_frameMenuBar->m_widget, 1, 1 );
+    gtk_widget_set_usize( m_frameMenuBar->m_widget, width-2, wxMENU_HEIGHT-2 );
+  };
+  
+  if (m_frameStatusBar)
+  {
+    m_frameStatusBar->SetSize( 0, main_height-wxSTATUS_HEIGHT, width, wxSTATUS_HEIGHT );
+  };
+
+  m_sizeSet = TRUE;
+  
+  wxSizeEvent event( wxSize(m_width,m_height), GetId() );
+  event.SetEventObject( this );
+  ProcessEvent( event );
+};
+
+void wxFrame::OnSize( wxSizeEvent &WXUNUSED(event) )
+{
+  wxWindow *child = NULL;
+  int noChildren = 0;
+  for(wxNode *node = GetChildren()->First(); node; node = node->Next())
+  {
+    wxWindow *win = (wxWindow *)node->Data();
+    if (!win->IsKindOf(CLASSINFO(wxFrame)) && 
+        !win->IsKindOf(CLASSINFO(wxDialog)) 
+/*      && (win != m_frameMenuBar) &&
+	(win != m_frameStatusBar)    not in m_children anyway */
+       )
+    {
+      child = win;
+      noChildren ++;
+    };
+  }
+;
+
+  if ((child) && (noChildren == 1))
+  {
+    int client_x, client_y;
+
+    GetClientSize(&client_x, &client_y);
+
+    child->SetSize( 1, 1, client_x-2, client_y);
+  }
+;
+};
+
+void SetInvokingWindow( wxMenu *menu, wxWindow *win )
+{
+  menu->SetInvokingWindow( win );
+  wxNode *node = menu->m_items.First();
+  while (node)
+  {
+    wxMenuItem *menuitem = (wxMenuItem*)node->Data();
+    if (menuitem->m_isSubMenu) SetInvokingWindow( menuitem->m_subMenu, win );
+    node = node->Next();
+  };
+};
+
+void wxFrame::SetMenuBar( wxMenuBar *menuBar )
+{
+  m_frameMenuBar = menuBar;
+  
+  wxNode *node = m_frameMenuBar->m_menus.First();
+  while (node)
+  {
+    wxMenu *menu = (wxMenu*)node->Data();
+    SetInvokingWindow( menu, this );   
+    node = node->Next();
+  };
+  
+  m_frameMenuBar->m_parent = this;
+  gtk_myfixed_put( GTK_MYFIXED(m_mainWindow), 
+    m_frameMenuBar->m_widget, m_frameMenuBar->m_x, m_frameMenuBar->m_y );
+};   
+
+bool wxFrame::CreateStatusBar( const int number )
+{
+  if (m_frameStatusBar)
+  delete m_frameStatusBar;
+  
+  m_frameStatusBar = new wxStatusBar( this, -1, wxPoint(0,0), wxSize(100,20) );
+
+  m_frameStatusBar->SetFieldsCount( number );
+  return TRUE;
+};
+
+void wxFrame::SetStatusText( const wxString &text, const int number )
+{
+  if (m_frameStatusBar) m_frameStatusBar->SetStatusText( text, number );
+};
+
+void wxFrame::SetStatusWidths( const int n, const int *width )
+{
+  if (m_frameStatusBar) m_frameStatusBar->SetStatusWidths( n, width );
+};
+
+wxStatusBar *wxFrame::GetStatusBar(void)
+{
+  return m_frameStatusBar;
+};
+
+wxMenuBar *wxFrame::GetMenuBar(void)
+{
+  return m_frameMenuBar;
+};
+
+void wxFrame::SetTitle( const wxString &title )
+{
+  m_title = title;
+  gtk_window_set_title( GTK_WINDOW(m_widget), title );
+};
+
+wxString wxFrame::GetTitle(void) const
+{
+  return (wxString&)m_title;
+};
+
diff --git a/src/gtk1/gdiobj.cpp b/src/gtk1/gdiobj.cpp
new file mode 100644
index 0000000000..8df2e5ff09
--- /dev/null
+++ b/src/gtk1/gdiobj.cpp
@@ -0,0 +1,21 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        gdiobj.cpp
+// Purpose:     wxGDIObject class
+// Author:      Julian Smart
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "gdiobj.h"
+#endif
+
+#include "wx/gdiobj.h"
+
+#if !USE_SHARED_LIBRARIES
+IMPLEMENT_DYNAMIC_CLASS(wxGDIObject, wxObject)
+#endif
+
diff --git a/src/gtk1/horiz.xbm b/src/gtk1/horiz.xbm
new file mode 100644
index 0000000000..ff3309bcc4
--- /dev/null
+++ b/src/gtk1/horiz.xbm
@@ -0,0 +1,6 @@
+#define horiz_width 15
+#define horiz_height 15
+static char horiz_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xff, 0x7f, 0x00, 0x00, 0x00, 0x00};
diff --git a/src/gtk1/icon.cpp b/src/gtk1/icon.cpp
new file mode 100644
index 0000000000..a65627746c
--- /dev/null
+++ b/src/gtk1/icon.cpp
@@ -0,0 +1,22 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        icon.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "icon.h"
+#endif
+
+#include "wx/icon.h"
+
+//-----------------------------------------------------------------------------
+// wxIcon
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxIcon,wxBitmap)
+
diff --git a/src/gtk1/listbox.cpp b/src/gtk1/listbox.cpp
new file mode 100644
index 0000000000..37dd67fef3
--- /dev/null
+++ b/src/gtk1/listbox.cpp
@@ -0,0 +1,266 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        listbox.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "listbox.h"
+#endif
+
+#include "wx/listbox.h"
+
+//-----------------------------------------------------------------------------
+// wxListBox
+//-----------------------------------------------------------------------------
+
+void gtk_listitem_select_callback( GtkWidget *widget, gpointer data )
+{
+  wxListBox *listbox = (wxListBox*)data;
+
+  wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, listbox->GetId() );
+  
+  event.SetInt( listbox->GetIndex( widget ) );
+  
+  GtkBin *bin = GTK_BIN( widget );
+  GtkLabel *label = GTK_LABEL( bin->child );
+  wxString tmp( label->label );
+  event.SetString( WXSTRINGCAST(tmp) );
+  
+  event.SetEventObject( listbox );
+  
+  listbox->ProcessEvent( event );
+};
+
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxListBox,wxControl)
+
+wxListBox::wxListBox(void)
+{
+  m_list = NULL;
+};
+
+wxListBox::wxListBox( wxWindow *parent, wxWindowID id, 
+      const wxPoint &pos, const wxSize &size, 
+      const int n, const wxString choices[],
+      const long style, const wxString &name )
+{
+  Create( parent, id, pos, size, n, choices, style, name );
+};
+
+bool wxListBox::Create( wxWindow *parent, wxWindowID id, 
+      const wxPoint &pos, const wxSize &size, 
+      const int n, const wxString choices[],
+      const long style, const wxString &name )
+{
+  m_needParent = TRUE;
+  
+  PreCreation( parent, id, pos, size, style, name );
+  
+  m_widget = gtk_scrolled_window_new( NULL, NULL );
+  gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(m_widget),
+    GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
+  
+  m_list = GTK_LIST( gtk_list_new() );
+  gtk_list_set_selection_mode( GTK_LIST(m_list), GTK_SELECTION_BROWSE );
+  
+  gtk_container_add (GTK_CONTAINER(m_widget), GTK_WIDGET(m_list) );
+  gtk_widget_show( GTK_WIDGET(m_list) );
+  
+  for (int i = 0; i < n; i++)
+  {
+    GtkWidget *list_item;
+    list_item = gtk_list_item_new_with_label( choices[i] ); 
+  
+    gtk_signal_connect( GTK_OBJECT(list_item), "select", 
+      GTK_SIGNAL_FUNC(gtk_listitem_select_callback), (gpointer)this );
+  
+    gtk_container_add( GTK_CONTAINER(m_list), list_item );
+    
+    gtk_widget_show( list_item );
+  };
+ 
+  PostCreation();
+  
+  Show( TRUE );
+  
+  return TRUE;
+};
+
+void wxListBox::Append( const wxString &item )
+{
+  GtkWidget *list_item;
+  list_item = gtk_list_item_new_with_label( item ); 
+  
+ gtk_signal_connect( GTK_OBJECT(list_item), "select", 
+    GTK_SIGNAL_FUNC(gtk_listitem_select_callback), (gpointer)this );
+  
+  gtk_container_add( GTK_CONTAINER(m_list), list_item );
+    
+  gtk_widget_show( list_item );
+};
+
+void wxListBox::Append( const wxString &WXUNUSED(item), char *WXUNUSED(clientData) )
+{
+};
+
+void wxListBox::Clear(void)
+{
+  gtk_list_clear_items( m_list, 0, Number() );
+};
+
+void wxListBox::Delete( int n )
+{
+  gtk_list_clear_items( m_list, n, n );
+};
+
+void wxListBox::Deselect( int n )
+{
+  gtk_list_unselect_item( m_list, n );
+};
+
+int wxListBox::FindString( const wxString &item ) const
+{
+  GList *child = m_list->children;
+  int count = 0;
+  while (child)
+  {
+    GtkBin *bin = GTK_BIN( child->data );
+    GtkLabel *label = GTK_LABEL( bin->child );
+    if (item == label->label) return count;
+    count++;
+    child = child->next;
+  };
+  return -1;
+};
+
+char *wxListBox::GetClientData( const int WXUNUSED(n) ) const
+{
+  return NULL;
+};
+
+int wxListBox::GetSelection(void) const
+{
+  GList *selection = m_list->selection;
+  if (selection)
+  {
+    GList *child = m_list->children;
+    int count = 0;
+    while (child)
+    {
+      if (child->data == selection->data) return count;
+      count++;
+      child = child->next;
+    };
+  };
+  return -1;
+};
+
+int wxListBox::GetSelections( int **WXUNUSED(selections) ) const
+{
+  return 0;
+};
+
+wxString wxListBox::GetString( int n ) const
+{
+  GList *child = g_list_nth( m_list->children, n );
+  if (child)
+  {
+    GtkBin *bin = GTK_BIN( child->data );
+    GtkLabel *label = GTK_LABEL( bin->child );
+    return label->label;
+  };
+  return "";
+};
+
+wxString wxListBox::GetStringSelection(void) const
+{
+  GList *selection = m_list->selection;
+  if (selection)
+  {
+    GtkBin *bin = GTK_BIN( selection->data );
+    wxString tmp = GTK_LABEL( bin->child )->label;
+    return tmp;
+  };
+  return "";
+};
+
+int wxListBox::Number(void)
+{
+  GList *child = m_list->children;
+  int count = 0;
+  while (child) { count++; child = child->next; };
+  return count;
+};
+
+bool wxListBox::Selected( const int n )
+{
+  GList *target = g_list_nth( m_list->children, n );
+  if (target)
+  {
+    GList *child = m_list->selection;
+    while (child)
+    {
+      if (child->data == target->data) return TRUE;
+      child = child->next;
+    };
+  };
+  return FALSE;
+};
+
+void wxListBox::Set( const int WXUNUSED(n), const wxString *WXUNUSED(choices) )
+{
+};
+
+void wxListBox::SetClientData( const int WXUNUSED(n), char *WXUNUSED(clientData) )
+{
+};
+
+void wxListBox::SetFirstItem( int WXUNUSED(n) )
+{
+};
+
+void wxListBox::SetFirstItem( const wxString &WXUNUSED(item) )
+{
+};
+
+void wxListBox::SetSelection( const int n, const bool select )
+{
+  if (select)
+    gtk_list_select_item( m_list, n );
+  else
+    gtk_list_unselect_item( m_list, n );
+};
+
+void wxListBox::SetString( const int WXUNUSED(n), const wxString &WXUNUSED(string) )
+{
+};
+
+void wxListBox::SetStringSelection( const wxString &string, const bool select )
+{
+  SetSelection( FindString(string), select );
+};
+
+int wxListBox::GetIndex( GtkWidget *item ) const
+{
+  if (item)
+  {
+    GList *child = m_list->children;
+    int count = 0;
+    while (child)
+    {
+      if (GTK_WIDGET(child->data) == item) return count;
+      count++;
+      child = child->next;
+    };
+  };
+  return -1;
+};
+
+
diff --git a/src/gtk1/mdi.cpp b/src/gtk1/mdi.cpp
new file mode 100644
index 0000000000..3ec3c31969
--- /dev/null
+++ b/src/gtk1/mdi.cpp
@@ -0,0 +1,198 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        mdi.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "mdi.h"
+#endif
+
+#include "wx/mdi.h"
+
+//-----------------------------------------------------------------------------
+// wxMDIParentFrame
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame,wxFrame)
+
+wxMDIParentFrame::wxMDIParentFrame(void)
+{
+  m_clientWindow = NULL;
+  m_currentChild = NULL;
+  m_parentFrameActive = TRUE;
+};
+
+wxMDIParentFrame::wxMDIParentFrame( wxWindow *parent,
+      const wxWindowID id, const wxString& title,
+      const wxPoint& pos, const wxSize& size,
+      const long style, const wxString& name )
+{
+  m_clientWindow = NULL;
+  m_currentChild = NULL;
+  m_parentFrameActive = TRUE;
+  Create( parent, id, title, pos, size, style, name );
+};
+
+wxMDIParentFrame::~wxMDIParentFrame(void)
+{
+};
+
+bool wxMDIParentFrame::Create( wxWindow *parent,
+      const wxWindowID id, const wxString& title,
+      const wxPoint& pos, const wxSize& size,
+      const long style, const wxString& name )
+{
+  wxFrame::Create( parent, id, title, pos, size, style, name );
+  
+  OnCreateClient();
+  
+  return TRUE;
+};
+
+void wxMDIParentFrame::OnSize( wxSizeEvent& event )
+{
+  wxFrame::OnSize( event );
+};
+
+void wxMDIParentFrame::OnActivate( wxActivateEvent& WXUNUSED(event) )
+{
+};
+
+void wxMDIParentFrame::SetMenuBar( wxMenuBar *menu_bar )
+{
+  wxFrame::SetMenuBar( menu_bar );
+};
+
+void wxMDIParentFrame::GetClientSize(int *width, int *height ) const
+{
+  wxFrame::GetClientSize( width, height );
+};
+
+wxMDIChildFrame *wxMDIParentFrame::GetActiveChild(void) const
+{
+  return m_currentChild;
+};
+
+wxMDIClientWindow *wxMDIParentFrame::GetClientWindow(void) const
+{
+  return m_clientWindow;
+};
+
+wxMDIClientWindow *wxMDIParentFrame::OnCreateClient(void)
+{
+  m_clientWindow = new wxMDIClientWindow( this );
+  return m_clientWindow;
+};
+
+void wxMDIParentFrame::ActivateNext(void)
+{
+};
+
+void wxMDIParentFrame::ActivatePrevious(void)
+{
+};
+
+void wxMDIParentFrame::OnSysColourChanged( wxSysColourChangedEvent& WXUNUSED(event) )
+{
+};
+
+//-----------------------------------------------------------------------------
+// wxMDIChildFrame
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame,wxPanel)
+  
+wxMDIChildFrame::wxMDIChildFrame(void)
+{
+};
+
+wxMDIChildFrame::wxMDIChildFrame( wxMDIParentFrame *parent,
+      const wxWindowID id, const wxString& title,
+      const wxPoint& pos, const wxSize& size,
+      const long style, const wxString& name )
+{
+  Create( parent, id, title, pos, size, style, name );
+};
+
+wxMDIChildFrame::~wxMDIChildFrame(void)
+{
+};
+
+bool wxMDIChildFrame::Create( wxMDIParentFrame *parent,
+      const wxWindowID id, const wxString& title,
+      const wxPoint& pos, const wxSize& size,
+      const long style, const wxString& name )
+{
+  m_title = title;
+  return wxPanel::Create( parent->GetClientWindow(), id, pos, size, style, name );
+};
+
+void wxMDIChildFrame::SetMenuBar( wxMenuBar *WXUNUSED(menu_bar) )
+{
+};
+
+void wxMDIChildFrame::Activate(void)
+{
+};
+
+//-----------------------------------------------------------------------------
+// wxMDIClientWindow
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow,wxWindow)
+
+wxMDIClientWindow::wxMDIClientWindow(void)
+{
+};
+
+wxMDIClientWindow::wxMDIClientWindow( wxMDIParentFrame *parent, const long style )
+{
+  CreateClient( parent, style );
+};
+
+wxMDIClientWindow::~wxMDIClientWindow(void)
+{
+};
+
+bool wxMDIClientWindow::CreateClient( wxMDIParentFrame *parent, const long style )
+{
+  m_needParent = TRUE;
+  
+  PreCreation( parent, -1, wxPoint(10,10), wxSize(100,100), style, "wxMDIClientWindow" );
+
+  m_widget = gtk_notebook_new();
+  
+  PostCreation();
+  
+  Show( TRUE );
+  
+  return TRUE;
+};
+
+void wxMDIClientWindow::AddChild( wxWindow *child )
+{
+  m_children.Append( child );
+  
+  wxString s;
+
+  if (child->IsKindOf(CLASSINFO(wxMDIChildFrame)))
+  {
+    wxMDIChildFrame* mdi_child = (wxMDIChildFrame*) child;
+    s = mdi_child->m_title;
+  };
+  
+  if (s.IsNull()) s = "MDI child";
+  
+  GtkWidget *label_widget;
+  label_widget = gtk_label_new( s );
+  gtk_misc_set_alignment( GTK_MISC(label_widget), 0.0, 0.5 );
+
+  gtk_notebook_append_page( GTK_NOTEBOOK(m_widget), child->m_widget, label_widget );
+};
+
+
diff --git a/src/gtk1/menu.cpp b/src/gtk1/menu.cpp
new file mode 100644
index 0000000000..5db3904638
--- /dev/null
+++ b/src/gtk1/menu.cpp
@@ -0,0 +1,293 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        menu.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "menu.h"
+#endif
+
+#include "wx/menu.h"
+
+//-----------------------------------------------------------------------------
+// wxMenuBar
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxMenuBar,wxWindow)
+
+wxMenuBar::wxMenuBar(void)
+{
+  m_needParent = FALSE; // hmmm
+  
+  PreCreation( NULL, -1, wxDefaultPosition, wxDefaultSize, 0, "menu" );
+
+  m_menus.DeleteContents( TRUE );
+  
+  m_widget = gtk_handle_box_new();
+  
+  m_menubar = gtk_menu_bar_new();
+  
+  gtk_container_add( GTK_CONTAINER(m_widget), m_menubar );
+  
+  gtk_widget_show( m_menubar );
+  
+  PostCreation();
+
+  Show( TRUE );
+};
+
+void wxMenuBar::Append( wxMenu *menu, const wxString &title )
+{
+  m_menus.Append( menu );
+  menu->m_title = title;    // ??????
+  
+  size_t pos;
+  do {
+    pos = menu->m_title.First( '&' );
+    if (pos != wxString::npos) menu->m_title.Remove( pos, 1 );
+  } while (pos != wxString::npos);
+  
+  GtkWidget *root_menu;
+  root_menu = gtk_menu_item_new_with_label( WXSTRINGCAST(menu->m_title) );
+  gtk_widget_show( root_menu );
+  gtk_menu_item_set_submenu( GTK_MENU_ITEM(root_menu), menu->m_menu );
+  
+  gtk_menu_bar_append( GTK_MENU_BAR(m_menubar), root_menu );
+};
+    
+int FindMenuItemRecursive( const wxMenu *menu, const wxString &menuString, const wxString &itemString )
+{
+  if (menu->m_title == menuString)
+  {
+    int res = menu->FindItem( itemString );
+    if (res != -1) return res;
+  };
+  wxNode *node = menu->m_items.First();
+  while (node)
+  {
+    wxMenuItem *item = (wxMenuItem*)node->Data();
+    if (item->m_subMenu) return FindMenuItemRecursive( item->m_subMenu, menuString, itemString );
+    node = node->Next();
+  };
+  return -1;
+};
+
+int wxMenuBar::FindMenuItem( const wxString &menuString, const wxString &itemString ) const
+{
+  wxNode *node = m_menus.First();
+  while (node)
+  {
+    wxMenu *menu = (wxMenu*)node->Data();
+    int res = FindMenuItemRecursive( menu, menuString, itemString);
+    if (res != -1) return res;
+    node = node->Next();
+  };
+  return -1;
+};
+
+    
+//-----------------------------------------------------------------------------
+// wxMenu
+//-----------------------------------------------------------------------------
+
+void gtk_menu_clicked_callback( GtkWidget *widget, gpointer data )
+{
+  wxMenu *menu = (wxMenu*)data;
+  int id = menu->FindMenuIdByMenuItem(widget);
+  
+  if (!menu->Enabled(id)) return;
+  
+  wxCommandEvent event( wxEVENT_TYPE_MENU_COMMAND, id );
+  event.SetEventObject( menu );
+  event.SetInt(id );
+  wxWindow *win = menu->GetInvokingWindow();
+  if (win) win->ProcessEvent( event );
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxMenuItem,wxObject)
+  
+wxMenuItem::wxMenuItem(void)
+{
+  m_id = 0;
+  m_text = "";
+  m_isCheckMenu = FALSE;
+  m_checked = FALSE;
+  m_isSubMenu = FALSE; 
+  m_subMenu = NULL;
+  m_helpStr = "";
+  m_menuItem = NULL;
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxMenu,wxEvtHandler)
+
+wxMenu::wxMenu( const wxString &title )
+{
+  m_title = title;
+  m_items.DeleteContents( TRUE );
+  m_invokingWindow = NULL;
+  m_menu = gtk_menu_new();  // Do not show!
+};
+
+void wxMenu::AppendSeparator(void)
+{
+  wxMenuItem *mitem = new wxMenuItem();
+  mitem->m_id = -1;
+  mitem->m_text = "";
+  mitem->m_helpStr = "";
+  mitem->m_isCheckMenu = FALSE;
+  mitem->m_isEnabled = TRUE;
+  mitem->m_menuItem = gtk_menu_item_new();
+  gtk_menu_append( GTK_MENU(m_menu), mitem->m_menuItem );
+  gtk_widget_show( mitem->m_menuItem );
+  m_items.Append( mitem );
+};
+
+void wxMenu::Append( const int id, const wxString &item, const wxString &helpStr, const bool checkable )
+{
+  wxMenuItem *mitem = new wxMenuItem();
+  mitem->m_id = id;
+  
+  mitem->m_text = item;
+  size_t pos;
+  do {
+    pos = mitem->m_text.First( '&' );
+    if (pos != wxString::npos) mitem->m_text.Remove( pos, 1 );
+  } while (pos != wxString::npos);
+  
+  mitem->m_helpStr = helpStr;
+  mitem->m_isCheckMenu = checkable;
+  mitem->m_isEnabled = TRUE;
+  if (checkable)
+    mitem->m_menuItem = gtk_check_menu_item_new_with_label( WXSTRINGCAST(mitem->m_text) );
+  else
+    mitem->m_menuItem = gtk_menu_item_new_with_label( WXSTRINGCAST(mitem->m_text) );
+    
+  gtk_signal_connect( GTK_OBJECT(mitem->m_menuItem), "activate", 
+    GTK_SIGNAL_FUNC(gtk_menu_clicked_callback), (gpointer*)this );
+  
+  gtk_menu_append( GTK_MENU(m_menu), mitem->m_menuItem );
+  gtk_widget_show( mitem->m_menuItem );
+  m_items.Append( mitem );
+};
+
+void wxMenu::Append( const int id, const wxString &item, wxMenu *subMenu, const wxString &helpStr )
+{
+  wxMenuItem *mitem = new wxMenuItem();
+  mitem->m_id = id;
+  mitem->m_text = item;
+  mitem->m_isEnabled = TRUE;
+  
+  size_t pos;
+  do {
+    pos = mitem->m_text.First( '&' );
+    if (pos != wxString::npos) mitem->m_text.Remove( pos, 1 );
+  } while (pos != wxString::npos);
+  
+  mitem->m_helpStr = helpStr;
+  mitem->m_menuItem = gtk_menu_item_new_with_label( WXSTRINGCAST(mitem->m_text) );
+  
+  mitem->m_subMenu = subMenu;
+  gtk_menu_item_set_submenu( GTK_MENU_ITEM(mitem->m_menuItem), subMenu->m_menu );
+  gtk_menu_append( GTK_MENU(m_menu), mitem->m_menuItem );
+  gtk_widget_show( mitem->m_menuItem );
+  m_items.Append( mitem );
+};
+
+int wxMenu::FindItem( const wxString itemString ) const
+{
+  wxString s( itemString );
+  
+  size_t pos;
+  do {
+    pos = s.First( '&' );
+    if (pos != wxString::npos) s.Remove( pos, 1 );
+  } while (pos != wxString::npos);
+  
+  wxNode *node = m_items.First();
+  while (node)
+  {
+    wxMenuItem *item = (wxMenuItem*)node->Data();
+    if (item->m_text == s) return item->m_id;
+    node = node->Next();
+  };
+  return -1;
+};
+
+void wxMenu::Enable( const int id, const bool enable )
+{
+  wxNode *node = m_items.First();
+  while (node)
+  {
+    wxMenuItem *item = (wxMenuItem*)node->Data();
+    if (item->m_id == id)
+    {
+      item->m_isEnabled = enable;
+      return;
+    };
+    node = node->Next();
+  };
+};
+
+bool wxMenu::Enabled( const int id ) const
+{
+  wxNode *node = m_items.First();
+  while (node)
+  {
+    wxMenuItem *item = (wxMenuItem*)node->Data();
+    if (item->m_id == id) return item->m_isEnabled;
+    node = node->Next();
+  };
+  return FALSE;
+};
+
+void wxMenu::SetLabel( const int id, const wxString &label )
+{
+  wxString s( label );
+  size_t pos;
+  do {
+    pos = s.First( '&' );
+    if (pos != wxString::npos) s.Remove( pos, 1 );
+  } while (pos != wxString::npos);
+  
+  wxNode *node = m_items.First();
+  while (node)
+  {
+    wxMenuItem *item = (wxMenuItem*)node->Data();
+    item->m_text = s;
+    if (item->m_id == id)
+    {
+      gtk_label_set( GTK_LABEL( GTK_BIN(item->m_menuItem)->child ), WXSTRINGCAST(s) );
+    };
+    node = node->Next();
+  };
+};
+
+int wxMenu::FindMenuIdByMenuItem( GtkWidget *menuItem ) const
+{
+  wxNode *node = m_items.First();
+  while (node)
+  {
+    wxMenuItem *item = (wxMenuItem*)node->Data();
+    if (item->m_menuItem == menuItem) return item->m_id;
+    node = node->Next();
+  };
+  return -1;
+};
+
+void wxMenu::SetInvokingWindow( wxWindow *win )
+{
+  m_invokingWindow = win;
+};
+
+wxWindow *wxMenu::GetInvokingWindow(void)
+{
+  return m_invokingWindow;
+};
+
+
diff --git a/src/gtk1/palette.cpp b/src/gtk1/palette.cpp
new file mode 100644
index 0000000000..162fb0effe
--- /dev/null
+++ b/src/gtk1/palette.cpp
@@ -0,0 +1,106 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        palette.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "palette.h"
+#endif
+
+#include "wx/palette.h"
+
+//-----------------------------------------------------------------------------
+// wxPalette
+//-----------------------------------------------------------------------------
+
+class wxPaletteRefData: public wxObjectRefData
+{
+  public:
+  
+    wxPaletteRefData(void);
+    ~wxPaletteRefData(void);
+  
+    GdkColormap  *m_colormap;
+};
+
+wxPaletteRefData::wxPaletteRefData(void)
+{
+  m_colormap = NULL;
+};
+
+wxPaletteRefData::~wxPaletteRefData(void)
+{
+  if (m_colormap) gdk_colormap_unref( m_colormap );
+};
+
+//-----------------------------------------------------------------------------
+
+#define M_PALETTEDATA ((wxPaletteRefData *)m_refData)
+
+IMPLEMENT_DYNAMIC_CLASS(wxPalette,wxGDIObject)
+
+wxPalette::wxPalette(void)
+{
+};
+
+wxPalette::wxPalette( const int n, const unsigned char *red, const unsigned char *green, const unsigned char *blue )
+{
+  m_refData = new wxPaletteRefData();
+  Create( n, red, green, blue );
+};
+
+wxPalette::wxPalette( const wxPalette& palette )
+{
+  Ref( palette );
+};
+
+wxPalette::wxPalette( const wxPalette* palette )
+{
+  UnRef();
+  if (palette) Ref( *palette ); 
+};
+
+wxPalette::~wxPalette(void)
+{
+};
+
+wxPalette& wxPalette::operator = ( const wxPalette& palette )
+{
+  if (*this == palette) return (*this); 
+  Ref( palette ); 
+  return *this; 
+};
+
+bool wxPalette::operator == ( const wxPalette& palette )
+{
+  return m_refData == palette.m_refData; 
+};
+
+bool wxPalette::operator != ( const wxPalette& palette )
+{
+  return m_refData != palette.m_refData; 
+};
+
+bool wxPalette::Ok(void) const
+{
+  return (m_refData);
+};
+
+bool wxPalette::Create( const int n, const unsigned char *red, const unsigned char *green, const unsigned char *blue)
+{
+};
+
+int wxPalette::GetPixel( const unsigned char red, const unsigned char green, const unsigned char blue ) const
+{
+};
+
+bool wxPalette::GetRGB( const int pixel, unsigned char *red, unsigned char *green, unsigned char *blue ) const
+{
+};
+
diff --git a/src/gtk1/pen.cpp b/src/gtk1/pen.cpp
new file mode 100644
index 0000000000..663f7ad3db
--- /dev/null
+++ b/src/gtk1/pen.cpp
@@ -0,0 +1,204 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        pen.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "pen.h"
+#endif
+
+#include "wx/pen.h"
+
+//-----------------------------------------------------------------------------
+// wxPen
+//-----------------------------------------------------------------------------
+
+class wxPenRefData: public wxObjectRefData
+{
+  public:
+  
+    wxPenRefData(void);
+  
+    int        m_width;
+    int        m_style;
+    int        m_joinStyle;
+    int        m_capStyle;
+    wxColour   m_colour;
+};
+
+wxPenRefData::wxPenRefData(void)
+{
+  m_width = 1;
+  m_style = wxSOLID;
+  m_joinStyle = wxJOIN_ROUND;
+  m_capStyle = wxCAP_ROUND;
+};
+
+//-----------------------------------------------------------------------------
+
+#define M_PENDATA ((wxPenRefData *)m_refData)
+
+IMPLEMENT_DYNAMIC_CLASS(wxPen,wxGDIObject)
+
+wxPen::wxPen(void)
+{
+  if (wxThePenList) wxThePenList->AddPen( this );
+};
+
+wxPen::wxPen( const wxColour &colour, int width, int style )
+{
+  m_refData = new wxPenRefData();
+  M_PENDATA->m_width = width;
+  M_PENDATA->m_style = style;
+  M_PENDATA->m_colour = colour;
+  if (wxThePenList) wxThePenList->AddPen( this );
+};
+
+wxPen::wxPen( const wxString &colourName, int width, int style )
+{
+  m_refData = new wxPenRefData();
+  M_PENDATA->m_width = width;
+  M_PENDATA->m_style = style;
+  M_PENDATA->m_colour = colourName;
+  if (wxThePenList) wxThePenList->AddPen( this );
+};
+
+wxPen::wxPen( const wxPen& pen )
+{
+  Ref( pen );
+  if (wxThePenList) wxThePenList->AddPen( this );
+};
+
+wxPen::wxPen( const wxPen* pen )
+{
+  UnRef();
+  if (pen) Ref( *pen ); 
+  if (wxThePenList) wxThePenList->AddPen( this );
+};
+
+wxPen::~wxPen(void)
+{
+  if (wxThePenList) wxThePenList->RemovePen( this );
+};
+
+wxPen& wxPen::operator = ( const wxPen& pen )
+{
+  if (*this == pen) return (*this); 
+  Ref( pen ); 
+  return *this; 
+};
+
+bool wxPen::operator == ( const wxPen& pen )
+{
+  return m_refData == pen.m_refData; 
+};
+
+bool wxPen::operator != ( const wxPen& pen )
+{
+  return m_refData != pen.m_refData; 
+};
+
+void wxPen::SetColour( const wxColour &colour )
+{
+  if (!m_refData)
+    m_refData = new wxPenRefData();
+
+  M_PENDATA->m_colour = colour;
+};
+
+void wxPen::SetColour( const wxString &colourName )
+{
+  if (!m_refData)
+    m_refData = new wxPenRefData();
+
+  M_PENDATA->m_colour = colourName;
+};
+
+void wxPen::SetColour( const int red, const int green, const int blue )
+{
+  if (!m_refData)
+    m_refData = new wxPenRefData();
+
+  M_PENDATA->m_colour.Set( red, green, blue );
+};
+
+void wxPen::SetCap( int capStyle )
+{
+  if (!m_refData)
+    m_refData = new wxPenRefData();
+
+  M_PENDATA->m_capStyle = capStyle;
+};
+
+void wxPen::SetJoin( int joinStyle )
+{
+  if (!m_refData)
+    m_refData = new wxPenRefData();
+
+  M_PENDATA->m_joinStyle = joinStyle;
+};
+
+void wxPen::SetStyle( int style )
+{
+  if (!m_refData)
+    m_refData = new wxPenRefData();
+
+  M_PENDATA->m_style = style;
+};
+
+void wxPen::SetWidth( int width )
+{
+  if (!m_refData)
+    m_refData = new wxPenRefData();
+
+  M_PENDATA->m_width = width;
+};
+
+int wxPen::GetCap(void) const
+{
+  return M_PENDATA->m_capStyle;
+};
+
+int wxPen::GetJoin(void) const
+{
+  if (!m_refData)
+    return 0;
+  else
+    return M_PENDATA->m_joinStyle;
+};
+
+int wxPen::GetStyle(void) const
+{
+  if (!m_refData)
+    return 0;
+  else
+    return M_PENDATA->m_style;
+};
+
+int wxPen::GetWidth(void) const
+{
+  if (!m_refData)
+    return 0;
+  else
+    return M_PENDATA->m_width;
+};
+
+wxColour &wxPen::GetColour(void) const
+{
+  if (!m_refData)
+    return wxNullColour;
+  else
+    return M_PENDATA->m_colour;
+};
+
+bool wxPen::Ok(void) const
+{
+  return (m_refData);
+};
+
diff --git a/src/gtk1/radiobox.cpp b/src/gtk1/radiobox.cpp
new file mode 100644
index 0000000000..5e83994194
--- /dev/null
+++ b/src/gtk1/radiobox.cpp
@@ -0,0 +1,229 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        radiobox.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "radiobox.h"
+#endif
+
+#include "wx/radiobox.h"
+#include "wx/dialog.h"
+#include "wx/frame.h"
+#include "wx/gtk/win_gtk.h"
+
+//-----------------------------------------------------------------------------
+// wxRadioBox
+//-----------------------------------------------------------------------------
+
+void gtk_radiobutton_clicked_callback( GtkWidget *WXUNUSED(widget), gpointer data )
+{
+  wxRadioBox *rb = (wxRadioBox*)data;
+  wxCommandEvent event( wxEVT_COMMAND_RADIOBOX_SELECTED, rb->GetId() );
+  event.SetInt( rb->GetSelection() );
+  wxString tmp( rb->GetStringSelection() );
+  event.SetString( WXSTRINGCAST(tmp) );
+  event.SetEventObject( rb );
+  rb->ProcessEvent(event);
+};
+
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxRadioBox,wxControl)
+
+wxRadioBox::wxRadioBox(void)
+{
+};
+
+wxRadioBox::wxRadioBox( wxWindow *parent, const wxWindowID id, const wxString& title,
+      const wxPoint &pos, const wxSize &size, 
+      const int n, const wxString choices[],
+      const int majorDim, const long style,
+      const wxString &name )
+{
+  Create( parent, id, title, pos, size, n, choices, majorDim, style, name );
+};
+
+bool wxRadioBox::Create( wxWindow *parent, const wxWindowID id, const wxString& title,
+      const wxPoint &pos, const wxSize &size, 
+      const int n, const wxString choices[],
+      const int WXUNUSED(majorDim), const long style,
+      const wxString &name )
+{
+  m_needParent = TRUE;
+  
+  PreCreation( parent, id, pos, size, style, name );
+
+  m_widget = gtk_frame_new( title );
+  
+  int x = m_x+5;
+  int y = m_y+15;
+  int maxLen = 0;
+  int height = 20;
+  
+//  if (((m_style & wxRA_VERTICAL) == wxRA_VERTICAL) && (n > 0))
+  if (n > 0)
+  {
+    GSList *radio_button_group = NULL;
+    for (int i = 0; i < n; i++)
+    {
+      if (i) radio_button_group = gtk_radio_button_group( GTK_RADIO_BUTTON(m_radio) );
+      m_radio = GTK_RADIO_BUTTON( gtk_radio_button_new_with_label( radio_button_group, choices[i] ) );
+      
+      if (!i) gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(m_radio), TRUE );
+      
+      gtk_signal_connect( GTK_OBJECT(m_radio), "clicked", 
+        GTK_SIGNAL_FUNC(gtk_radiobutton_clicked_callback), (gpointer*)this );
+       
+      gtk_myfixed_put( GTK_MYFIXED(m_parent->m_wxwindow), GTK_WIDGET(m_radio), x, y );
+      
+      int tmp = 22+gdk_string_measure( GTK_WIDGET(m_radio)->style->font, choices[i] );
+      if (tmp > maxLen) maxLen = tmp;
+      
+      int width = m_width-10;
+      if (size.x == -1) width = tmp;
+      gtk_widget_set_usize( GTK_WIDGET(m_radio), width, 20 );
+      
+      y += 20;
+      height += 20;
+      
+    };
+  };
+
+  wxSize newSize = size;
+  if (newSize.x == -1) newSize.x = maxLen+10;
+  if (newSize.y == -1) newSize.y = height;
+  SetSize( newSize.x, newSize.y );
+  
+  PostCreation();
+  
+  Show( TRUE );
+    
+  return TRUE;
+};
+
+bool wxRadioBox::Show( const bool show )
+{
+  wxWindow::Show( show );
+
+  GSList *item = gtk_radio_button_group( m_radio );
+  while (item)
+  {
+    GtkWidget *w = GTK_WIDGET( item->data );
+    if (show) gtk_widget_show( w ); else gtk_widget_hide( w );
+    item = item->next;
+  };
+
+  return TRUE;
+};
+
+int wxRadioBox::FindString( const wxString& WXUNUSED(s) ) const
+{
+  return 0;
+};
+
+void wxRadioBox::SetSelection( const int WXUNUSED(n) )
+{
+};
+
+int wxRadioBox::GetSelection(void) const
+{
+  GSList *item = gtk_radio_button_group( m_radio );
+  int count = 0;
+  while (item)
+  {
+    GtkButton *button = GTK_BUTTON( item->data );
+    if (GTK_TOGGLE_BUTTON(button)->active) return count;
+    count++;
+    item = item->next;
+  };
+  return -1;
+};
+
+wxString wxRadioBox::GetString( const int WXUNUSED(n) ) const
+{
+  return "";
+};
+
+wxString wxRadioBox::GetLabel(void) const
+{
+  return wxControl::GetLabel();
+};
+
+void wxRadioBox::SetLabel( const wxString& WXUNUSED(label) )
+{
+};
+
+void wxRadioBox::SetLabel( const int WXUNUSED(item), const wxString& WXUNUSED(label) )
+{
+};
+
+void wxRadioBox::SetLabel( const int WXUNUSED(item), wxBitmap *WXUNUSED(bitmap) )
+{
+};
+
+wxString wxRadioBox::GetLabel( const int WXUNUSED(item) ) const
+{
+  return "";
+};
+
+void wxRadioBox::Enable( const bool WXUNUSED(enable) )
+{
+};
+
+void wxRadioBox::Enable( const int WXUNUSED(item), const bool WXUNUSED(enable) )
+{
+};
+
+void wxRadioBox::Show( const int WXUNUSED(item), const bool WXUNUSED(show) )
+{
+};
+
+wxString wxRadioBox::GetStringSelection(void) const
+{
+  GSList *item = gtk_radio_button_group( m_radio );
+  while (item)
+  {
+    GtkButton *button = GTK_BUTTON( item->data );
+    if (GTK_TOGGLE_BUTTON(button)->active)
+    {
+      GtkLabel *label = GTK_LABEL( button->child );
+      return label->label;
+    };
+    item = item->next;
+  };
+  return "";
+};
+
+bool wxRadioBox::SetStringSelection( const wxString& WXUNUSED(s) )
+{
+  return TRUE;
+};
+
+int wxRadioBox::Number(void) const
+{
+  int count = 0;
+  GSList *item = gtk_radio_button_group( m_radio );
+  while (item)
+  {
+    item = item->next;
+    count++;
+  };
+  return count;
+};
+
+int wxRadioBox::GetNumberOfRowsOrCols(void) const
+{
+  return 1;
+};
+
+void wxRadioBox::SetNumberOfRowsOrCols( const int WXUNUSED(n) )
+{
+};
+
diff --git a/src/gtk1/radiobut.cpp b/src/gtk1/radiobut.cpp
new file mode 100644
index 0000000000..e474873991
--- /dev/null
+++ b/src/gtk1/radiobut.cpp
@@ -0,0 +1,17 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        radiobut.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "radiobut.h"
+#endif
+
+#include "wx/radiobut.h"
+
diff --git a/src/gtk1/region.cpp b/src/gtk1/region.cpp
new file mode 100644
index 0000000000..d7da03c61f
--- /dev/null
+++ b/src/gtk1/region.cpp
@@ -0,0 +1,253 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        region.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/98
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "region.h"
+#endif
+
+#include "wx/region.h"
+
+//-----------------------------------------------------------------------------
+// wxRegion
+//-----------------------------------------------------------------------------
+
+class wxRegionRefData: public wxObjectRefData
+{
+  public:
+  
+    wxRegionRefData(void);
+    ~wxRegionRefData(void);
+  
+  public:    
+
+    GdkRegion  *m_region;
+};
+
+wxRegionRefData::wxRegionRefData(void)
+{
+  m_region = NULL;
+};
+
+wxRegionRefData::~wxRegionRefData(void)
+{
+  if (m_region) gdk_region_destroy( m_region );
+};
+
+//-----------------------------------------------------------------------------
+
+#define M_REGIONDATA ((wxRegionRefData *)m_refData)
+
+IMPLEMENT_DYNAMIC_CLASS(wxRegion,wxGDIObject);
+  
+wxRegion::wxRegion( long x, long y, long w, long h )
+{
+  m_refData = new wxRegionRefData();
+  GdkRegion *reg = gdk_region_new();
+  GdkRectangle rect;
+  rect.x = x;
+  rect.y = y;
+  rect.width = w;
+  rect.height = h;
+  M_REGIONDATA->m_region = gdk_region_union_with_rect( reg, &rect );
+  gdk_region_destroy( reg );
+};
+
+wxRegion::wxRegion( const wxPoint& topLeft, const wxPoint& bottomRight )
+{
+  m_refData = new wxRegionRefData();
+  GdkRegion *reg = gdk_region_new();
+  GdkRectangle rect;
+  rect.x = topLeft.x;
+  rect.y = topLeft.y;
+  rect.width = bottomRight.x - rect.x;
+  rect.height = bottomRight.y - rect.y;
+  M_REGIONDATA->m_region = gdk_region_union_with_rect( reg, &rect );
+  gdk_region_destroy( reg );
+};
+
+wxRegion::wxRegion( const wxRect& rect )
+{
+  m_refData = new wxRegionRefData();
+  GdkRegion *reg = gdk_region_new();
+  GdkRectangle g_rect;
+  g_rect.x = rect.x;
+  g_rect.y = rect.y;
+  g_rect.width = rect.width;
+  g_rect.height = rect.height;
+  M_REGIONDATA->m_region = gdk_region_union_with_rect( reg, &g_rect );
+  gdk_region_destroy( reg );
+};
+
+wxRegion::wxRegion(void)
+{
+  m_refData = new wxRegionRefData();
+  M_REGIONDATA->m_region = gdk_region_new();
+};
+
+wxRegion::~wxRegion(void)
+{
+};
+
+void wxRegion::Clear(void)
+{
+  UnRef();
+  m_refData = new wxRegionRefData();
+  M_REGIONDATA->m_region = gdk_region_new();
+};
+
+bool wxRegion::Union( long x, long y, long width, long height )
+{
+  GdkRectangle rect;
+  rect.x = x;
+  rect.y = y;
+  rect.width = width;
+  rect.height = height;
+  GdkRegion *reg = gdk_region_union_with_rect( M_REGIONDATA->m_region, &rect );
+  gdk_region_destroy( M_REGIONDATA->m_region );
+  M_REGIONDATA->m_region = reg;
+  return TRUE;
+};
+
+bool wxRegion::Union( const wxRect& rect )
+{
+  GdkRectangle g_rect;
+  g_rect.x = rect.x;
+  g_rect.y = rect.y;
+  g_rect.width = rect.width;
+  g_rect.height = rect.height;
+  GdkRegion *reg = gdk_region_union_with_rect( M_REGIONDATA->m_region, &g_rect );
+  gdk_region_destroy( M_REGIONDATA->m_region );
+  M_REGIONDATA->m_region = reg;
+  return TRUE;
+};
+
+bool wxRegion::Union( const wxRegion& region )
+{
+  GdkRegion *reg = gdk_regions_union( M_REGIONDATA->m_region, region.GetRegion() );
+  gdk_region_destroy( M_REGIONDATA->m_region );
+  M_REGIONDATA->m_region = reg;
+  return TRUE;
+};
+
+bool wxRegion::Intersect( long x, long y, long width, long height )
+{
+  wxRegion reg( x, y, width, height );
+  Intersect( reg );
+  return TRUE;
+};
+
+bool wxRegion::Intersect( const wxRect& rect )
+{
+  wxRegion reg( rect );
+  Intersect( reg );
+  return TRUE;
+};
+
+bool wxRegion::Intersect( const wxRegion& region )
+{
+  GdkRegion *reg = gdk_regions_intersect( M_REGIONDATA->m_region, region.GetRegion() );
+  gdk_region_destroy( M_REGIONDATA->m_region );
+  M_REGIONDATA->m_region = reg;
+  return TRUE;
+};
+
+bool wxRegion::Subtract( long x, long y, long width, long height )
+{
+  wxRegion reg( x, y, width, height );
+  Subtract( reg );
+  return TRUE;
+};
+
+bool wxRegion::Subtract( const wxRect& rect )
+{
+  wxRegion reg( rect );
+  Subtract( reg );
+  return TRUE;
+};
+
+bool wxRegion::Subtract( const wxRegion& region )
+{
+  GdkRegion *reg = gdk_regions_subtract( M_REGIONDATA->m_region, region.GetRegion() );
+  gdk_region_destroy( M_REGIONDATA->m_region );
+  M_REGIONDATA->m_region = reg;
+  return TRUE;
+};
+
+bool wxRegion::Xor( long x, long y, long width, long height )
+{
+  wxRegion reg( x, y, width, height );
+  Xor( reg );
+  return TRUE;
+};
+
+bool wxRegion::Xor( const wxRect& rect )
+{
+  wxRegion reg( rect );
+  Xor( reg );
+  return TRUE;
+};
+
+bool wxRegion::Xor( const wxRegion& region )
+{
+  GdkRegion *reg = gdk_regions_xor( M_REGIONDATA->m_region, region.GetRegion() );
+  gdk_region_destroy( M_REGIONDATA->m_region );
+  M_REGIONDATA->m_region = reg;
+  return TRUE;
+};
+
+void wxRegion::GetBox( long& x, long& y, long&w, long &h ) const
+{
+  x = 0;
+  y = 0;
+  w = -1;
+  h = -1;
+};
+
+wxRect wxRegion::GetBox(void) const
+{
+  return wxRect( 0, 0, -1, -1 );
+};
+
+bool wxRegion::Empty(void) const
+{
+  return gdk_region_empty( M_REGIONDATA->m_region );
+};
+
+wxRegionContain wxRegion::Contains( long x, long y ) const
+{
+  if (gdk_region_point_in( M_REGIONDATA->m_region, x, y ))
+    return wxInRegion;
+  else
+    return wxOutRegion;
+};
+
+wxRegionContain wxRegion::Contains( long x, long y, long w, long h ) const
+{
+  GdkRectangle rect;
+  rect.x = x;
+  rect.y = y;
+  rect.width = w;
+  rect.height = h;
+  GdkOverlapType res = gdk_region_rect_in( M_REGIONDATA->m_region, &rect );
+  switch (res)
+  {
+   case GDK_OVERLAP_RECTANGLE_IN:   return wxInRegion;
+   case GDK_OVERLAP_RECTANGLE_OUT:  return wxOutRegion;
+   case GDK_OVERLAP_RECTANGLE_PART: return wxPartRegion;
+  };
+  return wxOutRegion;
+};
+
+GdkRegion *wxRegion::GetRegion(void) const
+{
+  return M_REGIONDATA->m_region;
+};
+
diff --git a/src/gtk1/scrolbar.cpp b/src/gtk1/scrolbar.cpp
new file mode 100644
index 0000000000..cb0d32c002
--- /dev/null
+++ b/src/gtk1/scrolbar.cpp
@@ -0,0 +1,216 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        scrolbar.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "scrolbar.h"
+#endif
+
+#include "wx/scrolbar.h"
+#include "wx/utils.h"
+
+//-----------------------------------------------------------------------------
+// wxScrollBar
+//-----------------------------------------------------------------------------
+
+void gtk_scrollbar_callback( GtkWidget *WXUNUSED(widget), wxScrollBar *win )
+{ 
+/*
+  printf( "OnScroll from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  if (!win->HasVMT()) return;
+    
+  float diff = win->m_adjust->value - win->m_oldPos;
+  if (fabs(diff) < 0.2) return;
+  
+  int command = 0;
+  
+  float line_step = win->m_adjust->step_increment;
+  float page_step = win->m_adjust->page_increment;
+  
+  if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN;
+  else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP;
+  else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN;
+  else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP;
+  else command = wxEVT_SCROLL_THUMBTRACK;
+
+  int value = (int)(win->m_adjust->value+0.5);
+      
+  int orient = wxHORIZONTAL;
+  if (win->GetWindowStyleFlag() & wxSB_VERTICAL == wxSB_VERTICAL) orient = wxHORIZONTAL;
+  
+  wxScrollEvent event( command, win->GetId(), value, orient );
+  event.SetEventObject( win );
+  win->ProcessEvent( event );
+  
+/*
+  wxCommandEvent cevent( wxEVT_COMMAND_SCROLLBAR_UPDATED, win->GetId() );
+  cevent.SetEventObject( win );
+  win->ProcessEvent( cevent );
+*/
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxScrollBar,wxControl)
+
+wxScrollBar::wxScrollBar(wxWindow *parent, const wxWindowID id,
+           const wxPoint& pos, const wxSize& size,
+           const long style, const wxString& name )
+{
+  Create( parent, id, pos, size, style, name );
+};
+
+wxScrollBar::~wxScrollBar(void)
+{
+};
+
+bool wxScrollBar::Create(wxWindow *parent, const wxWindowID id,
+           const wxPoint& pos, const wxSize& size,
+           const long style, const wxString& name )
+{
+  m_needParent = TRUE;
+  
+  PreCreation( parent, id, pos, size, style, name );
+  
+  m_oldPos = 0.0;
+
+  if (style & wxSB_VERTICAL == wxSB_VERTICAL)
+    m_widget = gtk_hscrollbar_new( NULL );
+  else
+    m_widget = gtk_vscrollbar_new( NULL );
+    
+  m_adjust = gtk_range_get_adjustment( GTK_RANGE(m_widget) );
+  
+  gtk_signal_connect (GTK_OBJECT (m_adjust), "value_changed",
+		      (GtkSignalFunc) gtk_scrollbar_callback, (gpointer) this );
+  
+  PostCreation();
+  
+  Show( TRUE );
+    
+  return TRUE;
+};
+
+int wxScrollBar::GetPosition(void) const
+{
+  return (int)(m_adjust->value+0.5);
+};
+
+int wxScrollBar::GetThumbSize() const
+{
+  return (int)(m_adjust->page_size+0.5);
+};
+
+int wxScrollBar::GetPageSize() const
+{
+  return (int)(m_adjust->page_increment+0.5);
+};
+
+int wxScrollBar::GetRange() const
+{
+  return (int)(m_adjust->upper+0.5);
+};
+
+void wxScrollBar::SetPosition( const int viewStart )
+{
+  float fpos = (float)viewStart;
+  m_oldPos = fpos;
+  if (fabs(fpos-m_adjust->value) < 0.2) return;
+  m_adjust->value = fpos;
+  
+  gtk_signal_emit_by_name( GTK_OBJECT(m_adjust), "value_changed" );
+};
+
+void wxScrollBar::SetScrollbar( const int position, const int thumbSize, const int range, const int pageSize,
+      const bool WXUNUSED(refresh) )
+{
+  float fpos = (float)position;
+  m_oldPos = fpos;
+  float frange = (float)range;
+  float fthumb = (float)thumbSize;
+  float fpage = (float)pageSize;
+      
+  if ((fabs(fpos-m_adjust->value) < 0.2) &&
+      (fabs(frange-m_adjust->upper) < 0.2) &&
+      (fabs(fthumb-m_adjust->page_size) < 0.2) &&
+      (fabs(fpage-m_adjust->page_increment) < 0.2))
+      return;
+      
+  m_adjust->lower = 0.0;
+  m_adjust->upper = frange;
+  m_adjust->value = fpos;
+  m_adjust->step_increment = 1.0;
+  m_adjust->page_increment = (float)(wxMax(fpage-2,0));
+  m_adjust->page_size = fthumb;
+
+  gtk_signal_emit_by_name( GTK_OBJECT(m_adjust), "changed" );
+};
+
+// Backward compatibility
+int wxScrollBar::GetValue(void) const
+{
+  return GetPosition();
+};
+
+void wxScrollBar::SetValue( const int viewStart )
+{
+  SetPosition( viewStart );
+};
+
+void wxScrollBar::GetValues( int *viewStart, int *viewLength, int *objectLength, int *pageLength ) const
+{
+  int pos = (int)(m_adjust->value+0.5);
+  int thumb = (int)(m_adjust->page_size+0.5);
+  int page = (int)(m_adjust->page_increment+0.5);
+  int range = (int)(m_adjust->upper+0.5);
+  
+  *viewStart = pos;
+  *viewLength = range;
+  *objectLength = thumb;
+  *pageLength = page;
+};
+
+int wxScrollBar::GetViewLength() const
+{
+  return (int)(m_adjust->upper+0.5);
+};
+
+int wxScrollBar::GetObjectLength() const
+{
+  return (int)(m_adjust->page_size+0.5);
+};
+
+void wxScrollBar::SetPageSize( const int pageLength )
+{
+  int pos = (int)(m_adjust->value+0.5);
+  int thumb = (int)(m_adjust->page_size+0.5);
+  int range = (int)(m_adjust->upper+0.5);
+  SetScrollbar( pos, thumb, range, pageLength );
+};
+
+void wxScrollBar::SetObjectLength( const int objectLength )
+{
+  int pos = (int)(m_adjust->value+0.5);
+  int page = (int)(m_adjust->page_increment+0.5);
+  int range = (int)(m_adjust->upper+0.5);
+  SetScrollbar( pos, objectLength, range, page );
+};
+
+void wxScrollBar::SetViewLength( const int viewLength )
+{
+  int pos = (int)(m_adjust->value+0.5);
+  int thumb = (int)(m_adjust->page_size+0.5);
+  int page = (int)(m_adjust->page_increment+0.5);
+  SetScrollbar( pos, thumb, viewLength, page );
+};
+
diff --git a/src/gtk1/settings.cpp b/src/gtk1/settings.cpp
new file mode 100644
index 0000000000..dfcf1d81db
--- /dev/null
+++ b/src/gtk1/settings.cpp
@@ -0,0 +1,183 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        settings.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "settings.h"
+#endif
+
+#include "wx/settings.h"
+
+/*
+#define wxSYS_COLOUR_SCROLLBAR         0
+#define wxSYS_COLOUR_BACKGROUND        1
+#define wxSYS_COLOUR_ACTIVECAPTION     2
+#define wxSYS_COLOUR_INACTIVECAPTION   3
+#define wxSYS_COLOUR_MENU              4
+#define wxSYS_COLOUR_WINDOW            5
+#define wxSYS_COLOUR_WINDOWFRAME       6
+#define wxSYS_COLOUR_MENUTEXT          7
+#define wxSYS_COLOUR_WINDOWTEXT        8
+#define wxSYS_COLOUR_CAPTIONTEXT       9
+#define wxSYS_COLOUR_ACTIVEBORDER      10
+#define wxSYS_COLOUR_INACTIVEBORDER    11
+#define wxSYS_COLOUR_APPWORKSPACE      12
+#define wxSYS_COLOUR_HIGHLIGHT         13
+#define wxSYS_COLOUR_HIGHLIGHTTEXT     14
+#define wxSYS_COLOUR_BTNFACE           15
+#define wxSYS_COLOUR_BTNSHADOW         16
+#define wxSYS_COLOUR_GRAYTEXT          17
+#define wxSYS_COLOUR_BTNTEXT           18
+#define wxSYS_COLOUR_INACTIVECAPTIONTEXT 19
+#define wxSYS_COLOUR_BTNHIGHLIGHT      20
+
+#define wxSYS_COLOUR_3DDKSHADOW        21
+#define wxSYS_COLOUR_3DLIGHT           22
+#define wxSYS_COLOUR_INFOTEXT          23
+#define wxSYS_COLOUR_INFOBK            24
+
+#define wxSYS_COLOUR_DESKTOP           wxSYS_COLOUR_BACKGROUND
+#define wxSYS_COLOUR_3DFACE            wxSYS_COLOUR_BTNFACE
+#define wxSYS_COLOUR_3DSHADOW          wxSYS_COLOUR_BTNSHADOW
+#define wxSYS_COLOUR_3DHIGHLIGHT       wxSYS_COLOUR_BTNHIGHLIGHT
+#define wxSYS_COLOUR_3DHILIGHT         wxSYS_COLOUR_BTNHIGHLIGHT
+#define wxSYS_COLOUR_BTNHILIGHT        wxSYS_COLOUR_BTNHIGHLIGHT
+*/
+
+#define SHIFT (8*(sizeof(short int)-sizeof(char)))
+
+wxColour *g_systemBtnFaceColour      = NULL;
+wxColour *g_systemBtnShadowColour    = NULL;
+wxColour *g_systemBtnHighlightColour = NULL;
+wxColour *g_systemHighlightColour    = NULL;
+
+wxColour wxSystemSettings::GetSystemColour( int index )
+{
+  switch (index)
+  {
+    case wxSYS_COLOUR_SCROLLBAR:
+    case wxSYS_COLOUR_BACKGROUND:
+    case wxSYS_COLOUR_ACTIVECAPTION:
+    case wxSYS_COLOUR_INACTIVECAPTION:
+    case wxSYS_COLOUR_MENU:
+    case wxSYS_COLOUR_WINDOW:
+    case wxSYS_COLOUR_WINDOWFRAME:
+    case wxSYS_COLOUR_ACTIVEBORDER:
+    case wxSYS_COLOUR_INACTIVEBORDER:
+    case wxSYS_COLOUR_BTNFACE:
+    {
+      GtkStyle *style = gtk_widget_get_default_style();
+      if (!g_systemBtnFaceColour)
+      {
+        g_systemBtnFaceColour = 
+	  new wxColour( style->bg[0].red >> SHIFT,
+	                style->bg[0].green >> SHIFT,
+			style->bg[0].blue >> SHIFT );
+      };
+      return *g_systemBtnFaceColour;
+    };
+    case wxSYS_COLOUR_BTNSHADOW:
+    {
+      GtkStyle *style = gtk_widget_get_default_style();
+      if (!g_systemBtnShadowColour)
+      {
+        g_systemBtnShadowColour = 
+	  new wxColour( style->dark[0].red >> SHIFT,
+	                style->dark[0].green >> SHIFT,
+			style->dark[0].blue >> SHIFT );
+      };
+      return *g_systemBtnShadowColour;
+    };
+    case wxSYS_COLOUR_GRAYTEXT:
+    case wxSYS_COLOUR_BTNHIGHLIGHT:
+    {
+      GtkStyle *style = gtk_widget_get_default_style();
+      if (!g_systemBtnHighlightColour)
+      {
+        g_systemBtnHighlightColour = 
+	  new wxColour( style->light[0].red >> SHIFT,
+	                style->light[0].green >> SHIFT,
+			style->light[0].blue >> SHIFT );
+      };
+      return *g_systemBtnHighlightColour;
+    };
+    case wxSYS_COLOUR_HIGHLIGHT:
+    {
+      GtkStyle *style = gtk_widget_get_default_style();
+      if (!g_systemHighlightColour)
+      {
+        g_systemHighlightColour = 
+	  new wxColour( style->bg[GTK_STATE_SELECTED].red >> SHIFT,
+	                style->bg[GTK_STATE_SELECTED].green >> SHIFT,
+			style->bg[GTK_STATE_SELECTED].blue >> SHIFT );
+      };
+      return *g_systemHighlightColour;
+    };
+    case wxSYS_COLOUR_MENUTEXT:
+    case wxSYS_COLOUR_WINDOWTEXT:
+    case wxSYS_COLOUR_CAPTIONTEXT:
+    case wxSYS_COLOUR_INACTIVECAPTIONTEXT:
+    case wxSYS_COLOUR_INFOTEXT:
+    {
+      return *wxBLACK;
+    };
+    case wxSYS_COLOUR_HIGHLIGHTTEXT:
+    {
+      return *wxWHITE;
+    };
+    case wxSYS_COLOUR_INFOBK:
+    case wxSYS_COLOUR_APPWORKSPACE:
+    {
+      return *wxWHITE;    // ?
+    };
+  };
+  return *wxWHITE;
+};
+
+wxFont *g_systemFont = NULL;
+
+wxFont wxSystemSettings::GetSystemFont( int index ) 
+{
+  switch (index)
+  {
+    case wxSYS_OEM_FIXED_FONT:
+    case wxSYS_ANSI_FIXED_FONT:
+    case wxSYS_SYSTEM_FIXED_FONT:
+    {
+      return *wxNORMAL_FONT;
+    };
+    case wxSYS_ANSI_VAR_FONT:
+    case wxSYS_SYSTEM_FONT:
+    case wxSYS_DEVICE_DEFAULT_FONT:
+    case wxSYS_DEFAULT_GUI_FONT:
+    {
+      if (!g_systemFont)
+        g_systemFont = new wxFont( "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*" );
+      return *g_systemFont;
+    };
+  };
+
+  return wxNullFont;
+}
+;
+
+int wxSystemSettings::GetSystemMetric( int index )
+{
+  switch (index)
+  {
+    case wxSYS_SCREEN_X:
+      return gdk_screen_width();
+    case wxSYS_SCREEN_Y:
+      return gdk_screen_height();
+  };
+  return 0;
+}
+;
+
diff --git a/src/gtk1/setup/general/createall b/src/gtk1/setup/general/createall
new file mode 100755
index 0000000000..e912a39315
--- /dev/null
+++ b/src/gtk1/setup/general/createall
@@ -0,0 +1,98 @@
+#! /bin/sh
+
+OS=$OSTYPE
+
+if test "x$OS" = x; then 
+  echo "please set the environment variable OSTYPE "
+  echo "to a value appropriate for your system."
+  echo "to do so type: setenv OSTYPE `uname`   for the csh, tcsh"
+  echo "               export OSTYPE=`uname`   for other shells"
+  exit 1
+fi
+
+TMP_CONT=`ls src`
+SRC_DIR=src
+for each in $TMP_CONT; do
+  if test -d src/$each ; then 
+    SRC_DIR="$SRC_DIR src/$each"
+  fi
+done
+
+TMP_CONT=`ls samples`
+SAMPLES_DIR=
+for each in $TMP_CONT; do
+  if test -d samples/$each ; then 
+    SAMPLES_DIR="$SAMPLES_DIR samples/$each"
+  fi
+done
+
+TMP_CONT=`ls utils`
+UTILS_DIR=
+for each in $TMP_CONT; do
+  if test -d utils/$each ; then 
+    UTILS_DIR="$UTILS_DIR utils/$each"
+  fi
+done
+
+TMP_CONT=`ls user`
+USER_DIR=
+for each in $TMP_CONT; do
+  if test -d user/$each ; then 
+    USER_DIR="$USER_DIR user/$each"
+  fi
+done
+
+ALL_DIR="$SRC_DIR $SAMPLES_DIR $UTILS_DIR $USER_DIR"
+
+echo Creating for: $OS
+
+# create defaults
+if test ! -d src/gtk/setup/$OS; then
+    mkdir src/gtk/setup/$OS
+fi
+
+SUBSTFILE=src/gtk/setup/$OS/substit
+
+# the substit file first
+if test -f src/gtk/setup/substit ; then
+  cat src/gtk/setup/substit | sed "s/*/@/g" > $SUBSTFILE;
+  rm -f src/gtk/setup/substit 
+fi
+# now the template file
+cat src/gtk/setup/maketmpl.in | sed -f $SUBSTFILE > src/gtk/setup/$OS/maketmpl
+
+# now the config header file
+#if test -f setup/wx_setup.h ; then
+#  cat setup/wx_setup.h > setup/$OS/wx_setup.h;
+#  rm -f setup/wx_setup.h
+#fi
+
+# create lib and bin directory
+if test ! -d lib; then
+  mkdir lib
+fi
+if test ! -d lib/$OS; then
+  mkdir lib/$OS
+fi
+if test ! -d bin; then
+  mkdir bin
+fi
+if test ! -d bin/$OS; then
+  mkdir bin/$OS
+fi
+
+# create makefiles
+for each in $ALL_DIR; do
+    DIR=$each/$OS
+    # create Makefile in directory
+    if test -r $each/Makefile.in ; then
+        # create directory
+        if test ! -d $DIR; then
+            echo "Creating Directory: $DIR..."
+	    mkdir $DIR
+        fi
+	echo "Creating: $DIR/Makefile..."
+	cat $each/Makefile.in | sed -f $SUBSTFILE > $DIR/Makefile
+	(cd $DIR; make subdirs > /dev/null;)
+    fi
+done
diff --git a/src/gtk1/setup/general/jointar b/src/gtk1/setup/general/jointar
new file mode 100755
index 0000000000..29949e1cf3
--- /dev/null
+++ b/src/gtk1/setup/general/jointar
@@ -0,0 +1,67 @@
+#! /bin/sh
+#
+# Written by Martin Sperl
+# (sperl@dsn.ast.univie.ac.at)
+#
+
+
+if test $# -lt 3 ; then
+  cat <<EOF
+Usage: `basename $0` <basedir> <SOURCE-FILES> <DESTINATION-FILS>
+  copies all files from the source-tar-files to the common
+  destination-tar-file with basedir as a common base directory.
+EOF
+  exit 0
+fi
+
+BaseDir="$1"
+shift
+
+Sourcefiles="$1"
+
+while test "$#" != 2 ; do
+  shift
+  Sourcefiles="$Sourcefiles $1"
+done
+
+shift
+Final=$1
+
+Destination=/tmp/join$$.tar
+
+touch $Destination
+
+curdir=`pwd`
+
+mkdir tmp$$
+mkdir tmp$$/$BaseDir
+
+#uncompress all files
+cd tmp$$/$BaseDir
+for each in $Sourcefiles ; do
+  ( \
+  if test `basename $each gz` != `basename $each` ; then \
+    gzip -dc ../../$each;\
+  else \
+    cat ../../$each;\
+  fi; \
+  ) | tar xf -
+done
+cd ..
+#now tar everything
+tar -cf $Destination *
+
+cd ..
+
+rm -fr tmp$$
+
+# goto old directory
+cd $curdir
+
+if test `basename $Final gz` != `basename $Final` ; then
+  gzip -c $Destination > $Final
+else
+  cat $Destination > $Final
+fi
+
+rm -f $Destination
diff --git a/src/gtk1/setup/general/makeapp b/src/gtk1/setup/general/makeapp
new file mode 100644
index 0000000000..a413749e5f
--- /dev/null
+++ b/src/gtk1/setup/general/makeapp
@@ -0,0 +1,73 @@
+SHELL=/bin/sh
+
+OS=$(OSTYPE)
+
+all::
+	-@if test "x$(OS)" = x; then \
+          echo "please set the environment variable OSTYPE ";\
+	  echo "to a value appropriate for your system.";\
+	  echo "to do so type: setenv OSTYPE `uname`   for the csh, tcsh";\
+          echo "               export OSTYPE=`uname`   for other shells";\
+        else \
+	  if test -f Makefile.in ; then \
+	    if test -f $(OS)/Makefile ; then \
+	      NEEDED=`(cd $(OS); ${MAKE} checkneeds;) | grep "needed to compile" `;\
+	      if test "x$$NEEDED" = x; then \
+	        (cd $(OS); ${MAKE} $@); \
+	      else \
+                (cd $(OS); ${MAKE} checkneeds); \
+	      fi ; \
+	    else \
+	      echo "Did you configure your system?";\
+	    fi; \
+	  fi; \
+	fi;
+
+distrib::
+	@if test ! -d ../../distrib ; then mkdir ../../distrib; fi;
+	@if test ! -f ../../system.list ; then \
+	 echo "dummy" > ../../system.list;\
+	fi
+	@(curr=`pwd`; direc=`basename $$curr`;\
+	 basedir=`dirname $$curr`;\
+         basedirname=`basename $$basedir`;\
+	 if test ! -d ../../distrib/$$basedirname ; then \
+	   mkdir ../../distrib/$$basedirname;\
+	 fi;\
+	 if test -d doc; then (cd doc; make clean;); fi;\
+	 (cd ..; \
+	  echo creating $$direc.tar from the current directory;\
+	  files="`\
+	       find $$direc -type f \
+	       | fgrep -vf ../system.list \
+	       | grep -v "~" \
+	       | grep -v "#" \
+	      ` $(DISTRIBUTE_ADDITIONAL)";\
+	  tar -cf /tmp/$$direc.tar $$files;\
+	  echo compressing $$direc.tar to $$direc.tgz;\
+	  gzip -c /tmp/$$direc.tar > ../distrib/$$basedirname/$$direc.tgz;\
+	  rm /tmp/$$direc.tar;\
+	 )\
+	)
+
+.DEFAULT:
+	-@if test "x$(OS)" = x; then \
+          echo "please set the environment variable OSTYPE ";\
+	  echo "to a value appropriate for your system.";\
+	  echo "to do so type: setenv OSTYPE `uname`   for the csh, tcsh";\
+          echo "               export OSTYPE=`uname`   for other shells";\
+        else \
+	  if test -f Makefile.in ; then \
+	    if test -f $(OS)/Makefile ; then \
+	      NEEDED=`(cd $(OS); ${MAKE} checkneeds) | grep "needed to compile" `;\
+	      if test "x$$NEEDED" = x; then \
+	        (cd $(OS); ${MAKE} $@); \
+	      else \
+                (cd $(OS); ${MAKE} checkneeds); \
+	      fi ; \
+	    else \
+	      echo "Did you configure your system?";\
+	    fi \
+	  fi \
+	fi
+
diff --git a/src/gtk1/setup/general/makedirs b/src/gtk1/setup/general/makedirs
new file mode 100644
index 0000000000..0e770242f1
--- /dev/null
+++ b/src/gtk1/setup/general/makedirs
@@ -0,0 +1,19 @@
+SHELL=/bin/sh
+
+DIRS=`find . -print | sed "s|\./||g" | grep -v "/" | grep -v "\." `
+
+all:
+	@for i in $(DIRS) xxx; do \
+	  if test -r $$i/Makefile ; then \
+	    echo "entering directory $$i building $@";\
+	    (cd $$i ; ${MAKE} $@); \
+	  fi; \
+	done
+
+.DEFAULT:
+	@for i in $(DIRS) xxx; do \
+	  if test -r $$i/Makefile ; then \
+	    echo "entering directory $$i building $@";\
+	    (cd $$i ; ${MAKE} $@); \
+	  fi; \
+	done
diff --git a/src/gtk1/setup/general/makedoc b/src/gtk1/setup/general/makedoc
new file mode 100644
index 0000000000..ca0ef855e5
--- /dev/null
+++ b/src/gtk1/setup/general/makedoc
@@ -0,0 +1,102 @@
+SHELL=/bin/sh
+
+FILE_BASE=$(TEX_BASE:.tex=)
+
+BMP_FILES=$(XPM_FILES:.xpm=.bmp)
+EPS_FILES=$(XPM_FILES:.xpm=.eps)
+GIF_FILES=$(XPM_FILES:.xpm=.gif)
+
+HTML_BUTTONS=back.gif forward.gif contents.gif up.gif
+
+all:: doc
+
+clean::
+	@ for each in $(DIRS) . ; do \
+	( cd $$each; \
+	  rm -f *.bmp *.eps *.gif *.aux *.dvi *.log  \
+	        *.ps  *.toc *~    *.idx *.hlp *.html \
+	        *.rtf *.ref *.xlp *.con *.win *.fts  \
+	        *.hpj *.HLP; \
+	); done 
+
+doc:: doc_ps doc_html doc_xlp doc_winhelp doc_rtf
+
+#############################################
+
+doc_ps:: $(FILE_BASE).ps
+
+$(FILE_BASE).ps: $(FILE_BASE).dvi
+	dvips $(FILE_BASE).dvi -o$@
+
+#############################################
+
+doc_dvi:: $(FILE_BASE).dvi
+
+$(FILE_BASE).dvi: $(FILE_BASE).tex $(TEX_ADDITIONAL) $(EPS_FILES)
+	latex $(FILE_BASE).tex
+	latex $(FILE_BASE).tex
+
+#############################################
+
+doc_xlp:: $(FILE_BASE).xlp
+
+$(FILE_BASE).xlp: $(FILE_BASE).tex $(TEX_ADDITIONAL)
+	../../../bin/$(OSTYPE)/tex2rtf $(FILE_BASE).tex $(FILE_BASE).xlp -twice -xlp
+
+#############################################
+
+doc_html:: $(FILE_BASE)_contents.html $(FILE_BASE).html
+
+$(FILE_BASE).html: 
+	@ln -s $(FILE_BASE)_contents.html $@
+
+$(FILE_BASE)_contents.html: $(FILE_BASE).tex $(TEX_ADDITIONAL) $(GIF_FILES) $(HTML_BUTTONS)
+	../../../bin/$(OSTYPE)/tex2rtf $(FILE_BASE).tex $(FILE_BASE) -twice -html
+
+#############################################
+
+doc_rtf:: $(FILE_BASE).rtf
+
+$(FILE_BASE).rtf: $(FILE_BASE).tex $(TEX_ADDITIONAL) $(BMP_FILES)
+	../../../bin/$(OSTYPE)/tex2rtf $(FILE_BASE).tex $(FILE_BASE).rtf -twice -rtf
+
+#############################################
+
+doc_winhelp:: $(FILE_BASE).win
+
+$(FILE_BASE).win: $(FILE_BASE).tex $(TEX_ADDITIONAL) $(BMP_FILES)
+	../../../bin/$(OSTYPE)/tex2rtf $(FILE_BASE).tex $(FILE_BASE).win -twice -winhelp
+	@echo final conversion still needs to be done by MSWin
+
+#############################################
+
+subst::
+	@if test "x$(OLD)" = x; then \
+	  echo "OLD not defined!"; exit -1; \
+	fi
+	@if test "x$(NEW)" = x; then \
+	  echo "NEW not defined!"; exit -1; \
+	fi
+	@for each in $(TEX_BASE) $(TEX_ADITIONAL) ; do \
+	  cat $$each | sed "s/$(OLD)/$(NEW)/g" > /tmp/subst; \
+	  rm $$each; cp /tmp/subst $$each; rm /tmp/subst; \
+	done
+
+#############################################
+
+.SUFFIXES:
+.SUFFIXES: .eps .xpm
+.SUFFIXES: .bmp .xpm
+.SUFFIXES: .gif .xpm
+
+.xpm.eps :
+	@$(RM) -f $@
+	xpmtoppm $< | ppmtogif | giftopnm | pnmtops -rle -center -noturn -scale 0.5 - > $@
+
+.xpm.bmp :
+	@$(RM) -f $@
+	xpmtoppm $< | ppmtobmp -windows - > $@
+
+.xpm.gif :
+	@$(RM) -f $@ 
+	xpmtoppm $< | ppmtogif -interlace - > $@
diff --git a/src/gtk1/setup/general/mygrep b/src/gtk1/setup/general/mygrep
new file mode 100755
index 0000000000..fcf54dcad9
--- /dev/null
+++ b/src/gtk1/setup/general/mygrep
@@ -0,0 +1,3 @@
+#! /bin/sh
+grep $@
+exit 0
diff --git a/src/gtk1/setup/general/needed b/src/gtk1/setup/general/needed
new file mode 100755
index 0000000000..286931a793
--- /dev/null
+++ b/src/gtk1/setup/general/needed
@@ -0,0 +1,10 @@
+#! /bin/sh
+
+for each in $@ ; do
+  LINE=`grep " $each " ../$OSTYPE/wx_setup.h | grep "#define" | grep 1`
+  if test "x$LINE" = x ; then
+    echo "$each needed to compile";
+    exit 1;
+  fi
+done
+
diff --git a/src/gtk1/setup/linux/maketmpl b/src/gtk1/setup/linux/maketmpl
new file mode 100644
index 0000000000..c4974f50d4
--- /dev/null
+++ b/src/gtk1/setup/linux/maketmpl
@@ -0,0 +1,123 @@
+# Makefile for Autoconf.
+# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+#### Start of system configuration section. ####
+
+GLOBAL_LIB_DIR = $(WXBASEDIR)/lib/$(OS)
+GLOBAL_BIN_DIR = $(WXBASEDIR)/bin/$(OS)
+
+# define toolkit to use
+TOOLKIT_DEF = -D__GTK__
+
+# general compiler stuff
+OPTIMISE = -O2 
+PROFILE = 
+DEBUG = 
+
+# c-compiler stuff
+CC = gcc
+CFLAGS =   -Wall $(OPTIMISE) $(PROFILE) $(DEBUG)
+CPP = gcc -E
+
+# c++-compiler stuff
+CXX = c++
+CXXFLAGS =   -Wall $(OPTIMISE) $(PROFILE) $(DEBUG)
+CXXCPP = c++ -E
+
+# shared compile stuff
+PICFLAGS = -fPIC
+CREATE_SHARED = sharedLinux
+
+# other stuff
+RM = rm -f
+LEX = flex
+LEXLIB = -lfl
+YACC = bison -y
+RANLIB = ranlib
+INSTALL = /usr/bin/install -c
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_DATA = ${INSTALL} -m 644
+AWK = mawk
+LN_S = ln -s
+CJPEG_PROG = 
+CONVERT_PATH = /usr/bin/X11
+CONVERT_PROG = /usr/bin/X11/convert
+DJPEG_PROG = 
+GIFTOPNM_PROG = 
+NETPBM_PATH = 
+
+prefix = /usr/local
+exec_prefix = ${prefix}
+
+# Directory in which to install scripts.
+#bindir = ${exec_prefix}/bin
+
+# Directory in which to install library files.
+datadir = ${prefix}/share
+acdatadir = $(datadir)/autoconf
+
+# Directory in which to install documentation info files.
+infodir = ${prefix}/info
+
+X_CFLAGS =  -I/usr/X11R6/include
+X_LIBS =  -L/usr/X11R6/lib
+X_EXTRA_LIBS = 
+X_PRE_LIBS =  -lSM -lICE
+
+GUI_TK_INCLUDE = -I/usr/local/lib/glib/include -I/usr/local/include -I/usr/X11R6/include
+GUI_TK_LIBRARY = -L/usr/local/lib -L/usr/X11R6/lib -lgtk -lgdk -lglib -lXext -lX11 -lm
+GUI_TK_LINK = 
+
+OPENGL_INCLUDE = 
+OPENGL_LIBRARY = 
+OPENGL_LINK = 
+
+THREADS_LINK = 
+
+# INCLUDES
+WX_INCLUDES = \
+$(TOOLKIT_DEF) \
+-I. \
+-I.. \
+-I$(WXBASEDIR)/include \
+-I$(WXBASEDIR)/src/png \
+-I$(WXBASEDIR)/src/zlib \
+-I$(WXBASEDIR)/src/gdk_imlib \
+$(GUI_TK_INCLUDE) \
+$(OPENGL_INCLUDE) \
+$(X_CFLAGS)
+
+WX_LIBS = -L$(GLOBAL_LIB_DIR) -lwx_gtk
+
+OPENGL_LIBS = $(OPENGL_LIBRARY) $(OPENGL_LINK)
+
+GUI_TK_LIBS = $(GUI_TK_LIBRARY) $(GUI_TK_LINK)
+
+LINK = $(CXX) -o $@
+LINK_LIBS= \
+  $(WX_LIBS) \
+  $(GUI_TK_LIBS) \
+  $(X_EXTRA_LIBS) \
+  $(X_PRE_LIBS)
+  
+#  $(X_LIBS) -lX11 -lXext -lm      gtk-config does this for me
+
+# Don't include $(OPENGL_LIBS) or $(THREADS_LINK) in LINK_LIBS; they
+# can be conveniently added to BIN_LINK in Makefile.in.
+
+#### End of system configuration section. ####
diff --git a/src/gtk1/setup/linux/substit b/src/gtk1/setup/linux/substit
new file mode 100644
index 0000000000..31f305ccb8
--- /dev/null
+++ b/src/gtk1/setup/linux/substit
@@ -0,0 +1,70 @@
+s|@OS@|linux|g
+s|@WXBASEDIR@|/home/karl/cvs/wxGTK|g
+s|@PROFILE@||g
+s|@DEBUG@||g
+s|@OPTIMISE@|-O2 |g
+s|@CC@|gcc|g
+s|@CFLAGS@|  -Wall|g
+s|@CPP@|gcc -E|g
+s|@CXX@|c++|g
+s|@CXXFLAGS@|  -Wall|g
+s|@CXXCPP@|c++ -E|g
+s|@PICFLAGS@|-fPIC|g
+s|@CREATE_SHARED@|sharedLinux|g
+s|@LEX@|flex|g
+s|@LEXLIB@|-lfl|g
+s|@YACC@|bison -y|g
+s|@RANLIB@|ranlib|g
+s|@INSTALL@|/usr/bin/install -c|g
+s|@INSTALL_PROGRAM@|${INSTALL}|g
+s|@INSTALL_DATA@|${INSTALL} -m 644|g
+s|@AWK@|mawk|g
+s|@LN_S@|ln -s|g
+s|@prefix@|/usr/local|g
+s|@exec_prefix@|${prefix}|g
+s|@bindir@|${exec_prefix}/bin|g
+s|@datadir@|${prefix}/share|g
+s|@infodir@|${prefix}/info|g
+s|@X_CFLAGS@| -I/usr/X11R6/include|g
+s|@X_LIBS@| -L/usr/X11R6/lib|g
+s|@X_EXTRA_LIBS@||g
+s|@X_PRE_LIBS@| -lSM -lICE|g
+s|@GUI_TK_INCLUDE@|-I/usr/local/lib/glib/include -I/usr/local/include -I/usr/X11R6/include|g
+s|@GUI_TK_LIBRARY@|-L/usr/local/lib -L/usr/X11R6/lib -lgtk -lgdk -lglib -lXext -lX11 -lm|g
+s|@GUI_TK_LINK@||g
+s|@OPENGL_INCLUDE@||g
+s|@OPENGL_LIBRARY@||g
+s|@OPENGL_LINK@||g
+s|@TOOLKIT@|GTK|g
+s|@TOOLKIT_DEF@|__GTK__|g
+s|@THREADS@|NONE|g
+s|@THREADS_LINK@||g
+s|@WXSTRING@|@WXSTRING@|g
+s|@TYPETREE@|NONE|g
+s|@METAFILE@|NONE|g
+s|@POSTSCRIPTDC@|POSTSCRIPTDC|g
+s|@WXGRAPH@|NONE|g
+s|@WXTREE@|NONE|g
+s|@DOCVIEW@|DOCVIEW|g
+s|@FORM@|NONE|g
+s|@PRINTPREVIEW@|PRINTPREVIEW|g
+s|@IPC@|IPC|g
+s|@HELP@|NONE|g
+s|@CLIPBOARD@|NONE|g
+s|@TIMEDATE@|TIMEDATE|g
+s|@FRACTION@|FRACTION|g
+s|@PROLOGIO@|NONE|g
+s|@PROLOGIOSRC@|NONE|g
+s|@ENHDIALOGBOX@|NONE|g
+s|@GAUGE@|GAUGE|g
+s|@GLCANVAS@|NONE|g
+s|@LAYOUT@|@LAYOUT@|g
+s|@WXRESOURCES@|WXRESOURCES|g
+s|@XRESOURCES@|XRESOURCES|g
+s|@SCROLLBAR@|SCROLLBAR|g
+s|@STATICITEMS@|@STATICITEMS@|g
+s|@TOOLBAR@|TOOLBAR|g
+s|@CONSTRAINTS@|CONSTRAINTS|g
+s|@RPC@|NONE|g
+s|@VIRLISTBOX@|NONE|g
+
diff --git a/src/gtk1/setup/maketmpl.in b/src/gtk1/setup/maketmpl.in
new file mode 100644
index 0000000000..961c31d281
--- /dev/null
+++ b/src/gtk1/setup/maketmpl.in
@@ -0,0 +1,123 @@
+# Makefile for Autoconf.
+# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+#### Start of system configuration section. ####
+
+GLOBAL_LIB_DIR = $(WXBASEDIR)/lib/$(OS)
+GLOBAL_BIN_DIR = $(WXBASEDIR)/bin/$(OS)
+
+# define toolkit to use
+TOOLKIT_DEF = -D@TOOLKIT_DEF@
+
+# general compiler stuff
+OPTIMISE = @OPTIMISE@
+PROFILE = @PROFILE@
+DEBUG = @DEBUG@
+
+# c-compiler stuff
+CC = @CC@
+CFLAGS = @CFLAGS@ $(OPTIMISE) $(PROFILE) $(DEBUG)
+CPP = @CPP@
+
+# c++-compiler stuff
+CXX = @CXX@
+CXXFLAGS = @CXXFLAGS@ $(OPTIMISE) $(PROFILE) $(DEBUG)
+CXXCPP = @CXXCPP@
+
+# shared compile stuff
+PICFLAGS = @PICFLAGS@
+CREATE_SHARED = @CREATE_SHARED@
+
+# other stuff
+RM = rm -f
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+YACC = @YACC@
+RANLIB = @RANLIB@
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+AWK = @AWK@
+LN_S = @LN_S@
+CJPEG_PROG = 
+CONVERT_PATH = /usr/bin/X11
+CONVERT_PROG = /usr/bin/X11/convert
+DJPEG_PROG = 
+GIFTOPNM_PROG = 
+NETPBM_PATH = 
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+# Directory in which to install scripts.
+#bindir = @bindir@
+
+# Directory in which to install library files.
+datadir = @datadir@
+acdatadir = $(datadir)/autoconf
+
+# Directory in which to install documentation info files.
+infodir = @infodir@
+
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+
+GUI_TK_INCLUDE = @GUI_TK_INCLUDE@
+GUI_TK_LIBRARY = @GUI_TK_LIBRARY@
+GUI_TK_LINK = @GUI_TK_LINK@
+
+OPENGL_INCLUDE = @OPENGL_INCLUDE@
+OPENGL_LIBRARY = @OPENGL_LIBRARY@
+OPENGL_LINK = @OPENGL_LINK@
+
+THREADS_LINK = @THREADS_LINK@
+
+# INCLUDES
+WX_INCLUDES = \
+$(TOOLKIT_DEF) \
+-I. \
+-I.. \
+-I$(WXBASEDIR)/include \
+-I$(WXBASEDIR)/src/png \
+-I$(WXBASEDIR)/src/zlib \
+-I$(WXBASEDIR)/src/gdk_imlib \
+$(GUI_TK_INCLUDE) \
+$(OPENGL_INCLUDE) \
+$(X_CFLAGS)
+
+WX_LIBS = -L$(GLOBAL_LIB_DIR) -lwx_gtk
+
+OPENGL_LIBS = $(OPENGL_LIBRARY) $(OPENGL_LINK)
+
+GUI_TK_LIBS = $(GUI_TK_LIBRARY) $(GUI_TK_LINK)
+
+LINK = $(CXX) -o $@
+LINK_LIBS= \
+  $(WX_LIBS) \
+  $(GUI_TK_LIBS) \
+  $(X_EXTRA_LIBS) \
+  $(X_PRE_LIBS)
+  
+#  $(X_LIBS) -lX11 -lXext -lm      gtk-config does this for me
+
+# Don't include $(OPENGL_LIBS) or $(THREADS_LINK) in LINK_LIBS; they
+# can be conveniently added to BIN_LINK in Makefile.in.
+
+#### End of system configuration section. ####
diff --git a/src/gtk1/setup/rules/bin b/src/gtk1/setup/rules/bin
new file mode 100644
index 0000000000..c179a1bbc3
--- /dev/null
+++ b/src/gtk1/setup/rules/bin
@@ -0,0 +1,13 @@
+# all that is to do
+all:: checkneeds binary
+clean:: clean_binary clean_obj
+
+# now include definite rules
+BIN_BASE_DIR=.
+
+# include rules to create library
+include $(RULES_GENERIC)/bin1
+# include rules to create objects
+include $(RULES_GENERIC)/obj
+# include rule to check for defines needed
+include $(RULES_GENERIC)/needed
diff --git a/src/gtk1/setup/rules/bin2 b/src/gtk1/setup/rules/bin2
new file mode 100644
index 0000000000..87c0ad8691
--- /dev/null
+++ b/src/gtk1/setup/rules/bin2
@@ -0,0 +1,14 @@
+# all that is to do
+all:: checkneeds binary
+clean:: clean_binary clean_obj
+
+# now include definite rules
+BIN_BASE_DIR=.
+
+# include rules to create library
+include $(RULES_GENERIC)/bin2
+# include rules to create objects
+include $(RULES_GENERIC)/obj
+# include rule to check for defines needed
+include $(RULES_GENERIC)/needed
+
diff --git a/src/gtk1/setup/rules/doc b/src/gtk1/setup/rules/doc
new file mode 100644
index 0000000000..78f0f204f9
--- /dev/null
+++ b/src/gtk1/setup/rules/doc
@@ -0,0 +1,90 @@
+SHELL=/bin/sh
+
+FILE_BASE=$(TEX_BASE:.tex=)
+
+BMP_FILES=$(XPM_FILES:.xpm=.bmp)
+EPS_FILES=$(XPM_FILES:.xpm=.eps)
+GIF_FILES=$(XPM_FILES:.xpm=.gif)
+
+TEX2RTF=$(WXBASEDIR)/bin/$(OSTYPE)/tex2rtf
+
+HTML_BUTTONS=back.gif forward.gif contents.gif up.gif
+
+all:: doc
+
+clean::
+	@ for each in $(DIRS) . ; do \
+	( cd $$each; \
+	  rm -f *.bmp *.eps *.gif *.aux *.dvi *.log  \
+	        *.ps  *.toc *~    *.idx *.hlp *.html \
+	        *.rtf *.ref *.xlp *.con *.win *.fts  \
+	        *.hpj *.HLP; \
+	); done 
+
+doc:: doc_ps doc_html doc_xlp doc_winhelp doc_rtf
+
+#############################################
+
+doc_ps:: $(FILE_BASE).ps
+
+$(FILE_BASE).ps: $(FILE_BASE).dvi
+	dvips $(FILE_BASE).dvi -o$@
+
+#############################################
+
+doc_dvi:: $(FILE_BASE).dvi
+
+$(FILE_BASE).dvi: $(FILE_BASE).tex $(TEX_ADDITIONAL) $(EPS_FILES)
+	latex $(FILE_BASE).tex
+	latex $(FILE_BASE).tex
+
+#############################################
+
+doc_xlp:: $(FILE_BASE).xlp
+
+$(FILE_BASE).xlp: $(FILE_BASE).tex $(TEX_ADDITIONAL)
+	$(TEX2RTF) $(FILE_BASE).tex $(FILE_BASE).xlp -twice -xlp
+
+#############################################
+
+doc_html:: $(FILE_BASE)_contents.html $(FILE_BASE).html
+
+$(FILE_BASE).html: 
+	@ln -s $(FILE_BASE)_contents.html $@
+
+$(FILE_BASE)_contents.html: $(FILE_BASE).tex $(TEX_ADDITIONAL) $(GIF_FILES) $(HTML_BUTTONS)
+	$(TEX2RTF) $(FILE_BASE).tex $(FILE_BASE) -twice -html
+
+#############################################
+
+doc_rtf:: $(FILE_BASE).rtf
+
+$(FILE_BASE).rtf: $(FILE_BASE).tex $(TEX_ADDITIONAL) $(BMP_FILES)
+	$(TEX2RTF) $(FILE_BASE).tex $(FILE_BASE).rtf -twice -rtf
+
+#############################################
+
+doc_winhelp:: $(FILE_BASE).win
+
+$(FILE_BASE).win: $(FILE_BASE).tex $(TEX_ADDITIONAL) $(BMP_FILES)
+	../../../bin/$(OSTYPE)/tex2rtf $(FILE_BASE).tex $(FILE_BASE).win -twice -winhelp
+	@echo final conversion still needs to be done by MSWin
+
+#############################################
+
+.SUFFIXES:
+.SUFFIXES: .eps .xpm
+.SUFFIXES: .bmp .xpm
+.SUFFIXES: .gif .xpm
+
+.xpm.eps :
+	@$(RM) -f $@
+	xpmtoppm $< | ppmtogif | giftopnm | pnmtops -rle -center -noturn -scale 0.5 - > $@
+
+.xpm.bmp :
+	@$(RM) -f $@
+	xpmtoppm $< | ppmtobmp -windows - > $@
+
+.xpm.gif :
+	@$(RM) -f $@ 
+	xpmtoppm $< | ppmtogif -interlace - > $@
diff --git a/src/gtk1/setup/rules/gbin b/src/gtk1/setup/rules/gbin
new file mode 100644
index 0000000000..1caea844d5
--- /dev/null
+++ b/src/gtk1/setup/rules/gbin
@@ -0,0 +1,14 @@
+# all that is to do
+all:: checkneeds binary
+clean:: clean_binary clean_obj
+
+# now include definite rules
+BIN_BASE_DIR=$(GLOBAL_BIN_DIR)
+
+# include rules to create library
+include $(RULES_GENERIC)/bin1
+# include rules to create objects
+include $(RULES_GENERIC)/obj
+# include rule to check for defines needed
+include $(RULES_GENERIC)/needed
+
diff --git a/src/gtk1/setup/rules/gbin2 b/src/gtk1/setup/rules/gbin2
new file mode 100644
index 0000000000..2d12986436
--- /dev/null
+++ b/src/gtk1/setup/rules/gbin2
@@ -0,0 +1,14 @@
+# all that is to do
+all:: checkneeds binary
+clean:: clean_binary clean_obj
+
+# now include definite rules
+BIN_BASE_DIR=$(GLOBAL_BIN_DIR)
+
+# include rules to create library
+include $(RULES_GENERIC)/bin2
+# include rules to create objects
+include $(RULES_GENERIC)/mkobj
+# include rule to check for defines needed
+include $(RULES_GENERIC)/needed
+
diff --git a/src/gtk1/setup/rules/generic/bin1 b/src/gtk1/setup/rules/generic/bin1
new file mode 100644
index 0000000000..d4c0bcdc64
--- /dev/null
+++ b/src/gtk1/setup/rules/generic/bin1
@@ -0,0 +1,8 @@
+binary:: binary1
+
+depend_binary:: depend_binary1
+
+clean_binary:: clean_binary1
+
+include $(RULES_GENERIC)/bin1gen
+
diff --git a/src/gtk1/setup/rules/generic/bin1gen b/src/gtk1/setup/rules/generic/bin1gen
new file mode 100644
index 0000000000..c11c5a3634
--- /dev/null
+++ b/src/gtk1/setup/rules/generic/bin1gen
@@ -0,0 +1,16 @@
+# create binary
+
+binary1:: $(BIN_BASE_DIR)/$(BIN_TARGET)
+
+$(BIN_BASE_DIR)/$(BIN_TARGET): $(BIN_OBJ)
+	@$(RM) -f $@
+	$(LINK) $(BIN_OBJ) -L. $(BIN_LINK) $(LINK_LIBS)
+
+# defining dependencies
+
+depend_binary1::
+
+# cleaning all files
+
+clean_binary1::
+	@$(RM) -f $(BIN_BASE_DIR)/$(BIN_TARGET)
diff --git a/src/gtk1/setup/rules/generic/bin2 b/src/gtk1/setup/rules/generic/bin2
new file mode 100644
index 0000000000..1394b8d050
--- /dev/null
+++ b/src/gtk1/setup/rules/generic/bin2
@@ -0,0 +1,9 @@
+binary:: binary1 binary2
+
+depend_binary:: depend_binary1 depend_binary2
+
+clean_binary:: clean_binary1 clean_binary2
+
+include $(RULES_GENERIC)/bin1gen
+include $(RULES_GENERIC)/bin2gen
+
diff --git a/src/gtk1/setup/rules/generic/bin2gen b/src/gtk1/setup/rules/generic/bin2gen
new file mode 100644
index 0000000000..b1ab3c4260
--- /dev/null
+++ b/src/gtk1/setup/rules/generic/bin2gen
@@ -0,0 +1,16 @@
+# create binary
+
+binary2:: $(BIN_BASE_DIR)/$(BIN2_TARGET)
+
+$(BIN_BASE_DIR)/$(BIN2_TARGET): $(BIN2_OBJ)
+	@$(RM) -f $@
+	$(LINK) $(BIN2_OBJ) -L. $(BIN2_LINK) $(LINK_LIBS)
+
+# defining dependencies
+
+depend_binary2::
+
+# cleaning all files
+
+clean_binary2::
+	@$(RM) -f $(BIN_BASE_DIR)/$(BIN2_TARGET)
diff --git a/src/gtk1/setup/rules/generic/depend b/src/gtk1/setup/rules/generic/depend
new file mode 100644
index 0000000000..0640db13c3
--- /dev/null
+++ b/src/gtk1/setup/rules/generic/depend
@@ -0,0 +1,18 @@
+depend::
+	@echo "$(CXX) -MM \
+	    $(WX_INCLUDES) \
+	    $(ADD_COMPILE) \
+	    $(LIB_SRC) $(BIN_SRC) $(BIN2_SRC)"
+	@(cd .. ;\
+	    $(CXX) -MM \
+	    $(WX_INCLUDES) \
+	    $(ADD_COMPILE) \
+	    $(LIB_SRC) $(BIN_SRC) $(BIN2_SRC)\
+	) > .depend
+	@cp Makefile Makefile.bak
+	@cat Makefile.bak | awk 'BEGIN { found=0;} { if ( $$0 == "# DO NOT DELETE") {found=1} ; { if ( found==0 ) { print $$0; } } }' > Makefile1
+	@echo "# DO NOT DELETE" >> Makefile1
+	@cat .depend >> Makefile1
+	@mv Makefile1 Makefile
+	@rm .depend
+
diff --git a/src/gtk1/setup/rules/generic/globals b/src/gtk1/setup/rules/generic/globals
new file mode 100644
index 0000000000..3b6413a923
--- /dev/null
+++ b/src/gtk1/setup/rules/generic/globals
@@ -0,0 +1,15 @@
+# creates subdirectories for object-files in case they are needed...
+
+subdirs::
+	@if test "x$(SRC_DIR)" != x ; then \
+	  echo -n "Creating necessary subdirs: "; \
+	  for each in $(SRC_DIR) xxx; do \
+	    if test "x$$each" != xxxx; then \
+	      echo -n "$$each "; \
+	      if test ! -d $$each ; then \
+	        mkdir $$each ; \
+	      fi; \
+	    fi; \
+	  done; \
+	  echo "";\
+	fi
diff --git a/src/gtk1/setup/rules/generic/lib b/src/gtk1/setup/rules/generic/lib
new file mode 100644
index 0000000000..589acc5822
--- /dev/null
+++ b/src/gtk1/setup/rules/generic/lib
@@ -0,0 +1,17 @@
+# create library
+
+library:: $(LIB_BASE_DIR)/lib$(LIB_TARGET).a
+
+$(LIB_BASE_DIR)/lib$(LIB_TARGET).a: $(LIB_OBJ)
+	@$(RM) -f $@
+	$(AR) rv $@ $(LIB_OBJ)
+
+# defining dependencies
+
+depend_library::
+
+# cleaning all files
+
+clean_library::
+	@$(RM) -f $(LIB_BASE_DIR)/lib$(LIB_TARGET).a
+
diff --git a/src/gtk1/setup/rules/generic/needed b/src/gtk1/setup/rules/generic/needed
new file mode 100644
index 0000000000..5cd5975729
--- /dev/null
+++ b/src/gtk1/setup/rules/generic/needed
@@ -0,0 +1,24 @@
+#SHELL=/bin/sh
+MYGREP=$(WXBASEDIR)/setup/general/mygrep
+checkneeds::
+	@if test "x$(NEEDED_DEFINES)" != x ; then \
+	  RESULT=0 ; \
+	  for each in $(NEEDED_DEFINES) xxx; do \
+	    if test "$$each" != xxx ; then \
+	      LINE=`cat $(SETUP_DIR)/wx_setup.h \
+	            | sed "s/ /,/g" \
+	            | $(MYGREP) ",$$each," \
+	            | $(MYGREP) "#define" \
+	            | $(MYGREP) "1" ` ; \
+	      if test "x$$LINE" = x ; then \
+	        (TMPVAR=`pwd`;\
+	         TMPVAR=`dirname $$TMPVAR`;\
+	         echo "$$each needed to compile "`basename $$TMPVAR`"...";\
+                );\
+	        RESULT=1 ; \
+	      fi; \
+	    fi; \
+	  done ;\
+	  exit $$RESULT; \
+	fi
+
diff --git a/src/gtk1/setup/rules/generic/obj b/src/gtk1/setup/rules/generic/obj
new file mode 100644
index 0000000000..92beab8180
--- /dev/null
+++ b/src/gtk1/setup/rules/generic/obj
@@ -0,0 +1,30 @@
+.SUFFIXES:
+.SUFFIXES: .o .c 
+.SUFFIXES: .o .cc 
+.SUFFIXES: .o .cpp
+
+VPATH= ..
+
+.c.o :
+	@$(RM) -f $@
+	$(CC) -c -o $@ $(CFLAGS) -I.. $(WX_INCLUDES) $(ADD_COMPILE) $(WX_DEFINES) $<
+
+.cc.o :
+	@$(RM) -f $@
+	$(CXX) -c -o $@ $(CXXFLAGS) -I.. $(WX_INCLUDES) $(ADD_COMPILE) $(WX_DEFINES) $<
+
+.cpp.o :
+	@$(RM) -f $@
+	$(CXX) -c -o $@ $(CXXFLAGS) -I.. $(WX_INCLUDES) $(ADD_COMPILE) $(WX_DEFINES) $<
+
+clean_obj::
+	@$(RM) *.o *.osh
+	@if test "x$(SRC_DIR)" != x ; then \
+	  for each in $(SRC_DIR) xxx; do \
+	    if test -d $$each ; then \
+              $(RM) $$each/*.o $$each/*.osh ; \
+	    fi; \
+	  done; \
+	fi;
+
+include $(RULES_GENERIC)/depend
diff --git a/src/gtk1/setup/rules/generic/slib b/src/gtk1/setup/rules/generic/slib
new file mode 100644
index 0000000000..87b331d322
--- /dev/null
+++ b/src/gtk1/setup/rules/generic/slib
@@ -0,0 +1,21 @@
+# create library
+
+library:: $(LIB_BASE_DIR)/lib$(LIB_TARGET).a
+
+$(LIB_BASE_DIR)/lib$(LIB_TARGET).a: $(LIB_OBJ)
+	@$(RM) -f $@ $(LIB_BASE_DIR)/lib$(LIB_TARGET).so $(LIB_BASE_DIR)/lib$(LIB_TARGET).so.*
+	@if test "x$(CREATE_SHARED)" != x; then\
+	  echo "$(SHARE_DIR)/$(CREATE_SHARED) $(CC) $(LIB_BASE_DIR)/lib$(LIB_TARGET).so $(LIB_MAJOR) $(LIB_MINOR) $(LIB_OBJ)"; \
+	  $(SHARE_DIR)/$(CREATE_SHARED) $(CC) $(LIB_BASE_DIR)/lib$(LIB_TARGET).so $(LIB_MAJOR) $(LIB_MINOR) $(LIB_OBJ); \
+	fi
+	$(AR) rv $@ $(LIB_OBJ)
+
+# defining dependencies
+
+depend_library::
+
+# cleaning all files
+
+clean_library::
+	@$(RM) -f $(LIB_BASE_DIR)/lib$(LIB_TARGET).a $(LIB_BASE_DIR)/lib$(LIB_TARGET).so.* $(LIB_BASE_DIR)/lib$(LIB_TARGET).so
+
diff --git a/src/gtk1/setup/rules/generic/sobj b/src/gtk1/setup/rules/generic/sobj
new file mode 100644
index 0000000000..b2d7c6aaba
--- /dev/null
+++ b/src/gtk1/setup/rules/generic/sobj
@@ -0,0 +1,42 @@
+.SUFFIXES:
+.SUFFIXES: .o .c 
+.SUFFIXES: .o .cc 
+.SUFFIXES: .o .cpp
+
+VPATH= ..
+
+.c.o :
+	@$(RM) -f $@ $@sh
+	@if test "x$(PICFLAGS)" != x; then \
+	  echo "$(CC) -c -o $@sh $(PICFLAGS) $(CFLAGS) -I.. $(WX_INCLUDES) $(ADD_COMPILE) $(WX_DEFINES) $<";\
+	  $(CC) -c -o $@sh $(PICFLAGS) $(CFLAGS) -I.. $(WX_INCLUDES) $(ADD_COMPILE) $(WX_DEFINES) $<;\
+	fi
+	$(CC) -c -o $@ $(CFLAGS) -I.. $(WX_INCLUDES) $(ADD_COMPILE) $(WX_DEFINES) $<
+
+.cc.o :
+	@$(RM) -f $@ $@sh
+	@if test "x$(PICFLAGS)" != x; then \
+	  echo "$(CXX) -c -o $@sh $(PICFLAGS) $(CXXFLAGS) -I.. $(WX_INCLUDES) $(ADD_COMPILE) $(WX_DEFINES) $<";\
+	  $(CXX) -c -o $@sh $(PICFLAGS) $(CXXFLAGS) -I.. $(WX_INCLUDES) $(ADD_COMPILE) $(WX_DEFINES) $<;\
+	fi
+	$(CXX) -c -o $@ $(CXXFLAGS) -I.. $(WX_INCLUDES) $(ADD_COMPILE) $(WX_DEFINES) $<
+
+.cpp.o :
+	@$(RM) -f $@ $@sh
+	@if test "x$(PICFLAGS)" != x; then \
+	  echo "$(CXX) -c -o $@sh $(PICFLAGS) $(CXXFLAGS) -I.. $(WX_INCLUDES) $(ADD_COMPILE) $(WX_DEFINES) $<";\
+	  $(CXX) -c -o $@sh $(PICFLAGS) $(CXXFLAGS) -I.. $(WX_INCLUDES) $(ADD_COMPILE) $(WX_DEFINES) $<;\
+	fi
+	$(CXX) -c -o $@ $(CXXFLAGS) -I.. $(WX_INCLUDES) $(ADD_COMPILE) $(WX_DEFINES) $<
+
+clean_obj::
+	@$(RM) *.o *.osh
+	@if test "x$(SRC_DIR)" != x ; then \
+	  for each in $(SRC_DIR) xxx; do \
+	    if test -d $$each ; then \
+              $(RM) $$each/*.o $$each/*.osh ; \
+	    fi; \
+	  done; \
+	fi;
+
+include $(RULES_GENERIC)/depend
diff --git a/src/gtk1/setup/rules/glib b/src/gtk1/setup/rules/glib
new file mode 100644
index 0000000000..b0e244789c
--- /dev/null
+++ b/src/gtk1/setup/rules/glib
@@ -0,0 +1,15 @@
+# all that is to do
+all:: checkneeds library
+clean:: clean_library clean_obj
+
+# now include definite rules
+LIB_BASE_DIR=$(GLOBAL_LIB_DIR)
+
+# include rules to create library
+include $(RULES_GENERIC)/lib
+# include rules to create objects
+include $(RULES_GENERIC)/obj
+# include rule to check for defines needed
+include $(RULES_GENERIC)/needed
+
+
diff --git a/src/gtk1/setup/rules/glibbin b/src/gtk1/setup/rules/glibbin
new file mode 100644
index 0000000000..edb0510517
--- /dev/null
+++ b/src/gtk1/setup/rules/glibbin
@@ -0,0 +1,17 @@
+# all that is to do
+all:: checkneeds library binary
+clean:: clean_library clean_obj clean_binary
+
+# now include definite rules
+LIB_BASE_DIR=$(GLOBAL_LIB_DIR)
+BIN_BASE_DIR=.
+
+# include rules to create library
+include $(RULES_GENERIC)/lib
+# include rules to create binary
+include $(RULES_GENERIC)/bin1
+# include rules to create objects
+include $(RULES_GENERIC)/obj
+# include rule to check for defines needed
+include $(RULES_GENERIC)/needed
+
diff --git a/src/gtk1/setup/rules/glibgbin b/src/gtk1/setup/rules/glibgbin
new file mode 100644
index 0000000000..ee7a4023e3
--- /dev/null
+++ b/src/gtk1/setup/rules/glibgbin
@@ -0,0 +1,18 @@
+# all that is to do
+all:: checkneeds library binary
+depend:: depend_library depend_binary 
+clean:: clean_library clean_obj clean_binary
+
+# now include definite rules
+LIB_BASE_DIR=$(GLOBAL_LIB_DIR)
+BIN_BASE_DIR=$(GLOBAL_BIN_DIR)
+
+# include rules to create library
+include $(RULES_GENERIC)/lib
+# include rules to create binary
+include $(RULES_GENERIC)/mkbin1
+# include rules to create objects
+include $(RULES_GENERIC)/obj
+# include rule to check for defines needed
+include $(RULES_GENERIC)/needed
+
diff --git a/src/gtk1/setup/rules/gslib b/src/gtk1/setup/rules/gslib
new file mode 100644
index 0000000000..794a2b0d23
--- /dev/null
+++ b/src/gtk1/setup/rules/gslib
@@ -0,0 +1,15 @@
+# all that is to do
+all:: checkneeds library
+clean:: clean_library clean_obj
+
+# now include definite rules
+LIB_BASE_DIR=$(GLOBAL_LIB_DIR)
+
+# include rules to create shared library
+include $(RULES_GENERIC)/slib
+# include rules to create shared objects
+include $(RULES_GENERIC)/sobj
+# include rule to check for defines needed
+include $(RULES_GENERIC)/needed
+
+
diff --git a/src/gtk1/setup/rules/lib b/src/gtk1/setup/rules/lib
new file mode 100644
index 0000000000..7831e41a4a
--- /dev/null
+++ b/src/gtk1/setup/rules/lib
@@ -0,0 +1,14 @@
+# all that is to do
+all:: checkneeds library
+clean:: clean_library clean_obj
+
+# now include definite rules
+LIB_BASE_DIR=.
+
+# include rules to create library
+include $(RULES_GENERIC)/lib
+# include rules to create objects
+include $(RULES_GENERIC)/obj
+# include rule to check for defines needed
+include $(RULES_GENERIC)/needed
+
diff --git a/src/gtk1/setup/rules/libbin b/src/gtk1/setup/rules/libbin
new file mode 100644
index 0000000000..97456c45f2
--- /dev/null
+++ b/src/gtk1/setup/rules/libbin
@@ -0,0 +1,17 @@
+# all that is to do
+all:: checkneeds library binary
+clean:: clean_library clean_obj clean_binary
+
+# now include definite rules
+LIB_BASE_DIR=.
+BIN_BASE_DIR=.
+
+# include rules to create library
+include $(RULES_GENERIC)/lib
+# include rules to create binary
+include $(RULES_GENERIC)/bin1
+# include rules to create objects
+include $(RULES_GENERIC)/obj
+# include rule to check for defines needed
+include $(RULES_GENERIC)/needed
+
diff --git a/src/gtk1/setup/rules/libgbin b/src/gtk1/setup/rules/libgbin
new file mode 100644
index 0000000000..dc2ab616a9
--- /dev/null
+++ b/src/gtk1/setup/rules/libgbin
@@ -0,0 +1,17 @@
+# all that is to do
+all:: checkneeds library binary
+clean:: clean_library clean_obj clean_binary
+
+# now include definite rules
+LIB_BASE_DIR=.
+BIN_BASE_DIR=$(GLOBAL_BIN_DIR)
+
+# include rules to create library
+include $(RULES_GENERIC)/lib
+# include rules to create binary
+include $(RULES_GENERIC)/mkbin1
+# include rules to create objects
+include $(RULES_GENERIC)/obj
+# include rule to check for defines needed
+include $(RULES_GENERIC)/needed
+
diff --git a/src/gtk1/setup/setup.hin b/src/gtk1/setup/setup.hin
new file mode 100644
index 0000000000..fe038e581a
--- /dev/null
+++ b/src/gtk1/setup/setup.hin
@@ -0,0 +1,533 @@
+/* wx_setup.h
+   This file is in the public domain.
+
+   Descriptive text for the C preprocessor macros that
+   the distributed Autoconf macros can define.
+   No software package will use all of them; autoheader copies the ones
+   your configure.in uses into your configuration header file templates.
+
+   The entries are in sort -df order: alphabetical, case insensitive,
+   ignoring punctuation (such as underscores).  Although this order
+   can split up related entries, it makes it easier to check whether
+   a given entry is in the file.
+
+   Leave the following blank line there!!  Autoheader needs it.  */
+
+#ifndef __GTKSETUPH__
+#define __GTKSETUPH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+/* define the system to compile */
+#undef __GTK__
+#undef __UNIX__
+#undef __LINUX__
+#undef __SGI__
+#undef __HPUX__
+#undef __SYSV__
+#undef __SVR4__
+#undef __AIX__
+#undef __SUN__
+#undef __SOLARIS__
+#undef __SUNOS__
+#undef __ALPHA__
+#undef __OSF__
+#undef __BSD__
+#undef __FREEBSD__
+#undef __VMS__
+#undef __ULTRIX__
+#undef __DATA_GENERAL__
+
+/*
+ * Use zlib
+ */
+#undef USE_ZLIB
+/*
+ * Use gdk_imlib
+ */
+#undef USE_GDK_IMLIB
+/*
+ * Use libpng
+ */
+#undef USE_LIBPNG
+/*
+ * Use Threads
+ */
+#undef USE_THREADS
+#undef USE_THREADS_POSIX
+#undef USE_THREADS_SGI
+/*
+ * Use storable classes
+ */
+#undef USE_STORABLE_CLASSES
+/*
+ * Use automatic translation via gettext() in wxTString
+ */
+#undef USE_AUTOTRANS
+/*
+ * Use font metric files in GetTextExtent for wxPostScriptDC
+ * Use consistent PostScript fonts for AFM and printing (!)
+ */
+#undef USE_AFM_FOR_POSTSCRIPT
+#undef WX_NORMALIZED_PS_FONTS
+/*
+ * Use clipboard
+ */
+#undef USE_CLIPBOARD
+/*
+ * Use wxWindows layout constraint system
+ */
+#undef USE_CONSTRAINTS
+/*
+ * Use the document/view architecture
+ */
+#undef USE_DOC_VIEW_ARCHITECTURE
+/*
+ * Use enhanced dialog
+ */
+#undef USE_ENHANCED_DIALOG
+/*
+ * Use Form panel item placement
+ */
+#undef USE_FORM
+/*
+ * Use fraction class
+ */
+#undef USE_FRACTION
+/*
+ * Use gauge item
+ */
+#undef USE_GAUGE
+/*
+ * Implement a GLCanvas class as an interface to OpenGL, using the GLX
+ * extension to the X11 protocol.  You can use the (free) Mesa library
+ * if you don't have a 'real' OpenGL.
+ */
+#undef USE_GLX
+/*
+ * Use wxWindows help facility (needs USE_IPC 1)
+ */
+#undef USE_HELP
+/*
+ * Use iostream.h rather than iostream
+ */
+#undef USE_IOSTREAMH
+/*
+ * Use Interprocess communication
+ */
+#undef USE_IPC
+/*
+ * Use Metafile and Metafile device context
+ */
+#undef USE_METAFILE
+/*
+ * Use PostScript device context
+ */
+#undef USE_POSTSCRIPT
+/*
+ * Use the print/preview architecture
+ */
+#undef USE_PRINTING_ARCHITECTURE
+/*
+ * Use Prolog IO
+ */
+#undef USE_PROLOGIO
+/*
+ * Use Remote Procedure Call (Needs USE_IPC and USE_PROLOGIO)
+ */
+#undef USE_RPC
+/*
+ * Use wxGetResource & wxWriteResource (change .Xdefaults)
+ */
+#undef USE_RESOURCES
+/*
+ * Use scrollbar item
+ */
+#undef USE_SCROLLBAR
+/*
+ * Use time and date classes
+ */
+#undef USE_TIMEDATE
+/*
+ * Use toolbar, use Xt port toolbar (3D look)
+ */
+#undef USE_TOOLBAR
+#undef USE_XT_TOOLBAR
+/*
+ * Enables old type checking mechanism (wxSubType)
+ */
+#undef USE_TYPETREE
+/*
+ * Use virtual list box item
+ */
+#undef USE_VLBOX
+/*
+ * Use wxWindows resource loading (.wxr-files) (Needs USE_PROLOGIO 1)
+ */
+#undef USE_WX_RESOURCES
+/*
+ * Use wxGraph
+ */
+#undef USE_WXGRAPH
+/*
+ * Use wxTree
+ */
+
+/********************** DO NOT CHANGE BELOW THIS POINT **********************/
+
+/**************************** DEBUGGING FEATURES ****************************/
+
+/* Compatibility with 1.66 API.
+   Level 0: no backward compatibility, all new features
+   Level 1: wxDC, OnSize (etc.) compatibility, but
+   some new features such as event tables */
+#define WXWIN_COMPATIBILITY  1
+/*
+ * Enables debugging: memory tracing, assert, etc.
+ */
+#undef DEBUG
+/*
+ * Enables debugging version of wxObject::new and wxObject::delete (IF DEBUG)
+ * WARNING: this code may not work with all architectures, especially
+ * if alignment is an issue.
+ */
+#undef USE_MEMORY_TRACING
+/*
+ * Enable debugging version of global memory operators new and delete
+ * Disable it, If this causes problems (e.g. link errors)
+ */
+#undef USE_GLOBAL_MEMORY_OPERATORS
+/*
+ * If WXDEBUG && USE_MEMORY_TRACING && USE_GLOBAL_MEMORY_OPERATORS
+ * used to debug the memory allocation of wxWindows Xt port code
+ */
+#define USE_INTERNAL_MEMORY_TRACING 0
+/*
+ * Matthews garbage collection (used for MrEd?)
+ */
+#define WXGARBAGE_COLLECTION_ON 0
+
+/**************************** COMPILER FEATURES *****************************/
+
+/*
+ * Disable this if your compiler can't cope
+ * with omission of prototype parameters.
+ */
+#define REMOVE_UNUSED_ARG 1
+/*
+ * The const keyword is being introduced more in wxWindows.
+ * You can use this setting to maintain backward compatibility.
+ * If 0:	will use const wherever possible.
+ * If 1:	will use const only where necessary
+ *              for precompiled headers to work.
+ * If 2:	will be totally backward compatible, but precompiled
+ *	headers may not work and program size will be larger.
+ */
+#define CONST_COMPATIBILITY 0
+
+/************************ WINDOWS 3.1 COMPATIBILITY *************************/
+
+/*
+ * Normalize X drawing code to behave exactly as MSW.
+ */
+#define WX_STANDARD_GRAPHICS 0
+
+/******************* other stuff **********************************/
+/*
+ * Support image loading for wxBitmap (wxImage is needed for this)
+ */
+#define USE_IMAGE_LOADING 0
+#define WXIMAGE_INCLUDE "../../utils/image/src/wx_image.h"
+/*
+ * Use splines
+ */
+#define USE_SPLINES 1
+
+/*
+ * USE_DYNAMIC_CLASSES is TRUE for the Xt port
+ */
+#define USE_DYNAMIC_CLASSES 1
+/*
+ * USE_EXTENDED_STATICS is FALSE for the Xt port
+*/
+#define USE_EXTENDED_STATICS 0
+
+/*************************** IMAKEFILE EVALUATIOS ***************************/
+
+#if USE_XPM
+	#define USE_XPM_IN_X 1
+#else
+	#define USE_XPM_IN_X 0
+#endif
+#if USE_IMAGE_LOADING
+	#define USE_IMAGE_LOADING_IN_X 1
+#else
+	#define USE_IMAGE_LOADING_IN_X 0
+#endif
+
+/* here comes the system-specific stuff */
+
+/* acconfig.h
+   This file is in the public domain.
+
+   Descriptive text for the C preprocessor macros that
+   the distributed Autoconf macros can define.
+   No software package will use all of them; autoheader copies the ones
+   your configure.in uses into your configuration header file templates.
+
+   The entries are in sort -df order: alphabetical, case insensitive,
+   ignoring punctuation (such as underscores).  Although this order
+   can split up related entries, it makes it easier to check whether
+   a given entry is in the file. */
+
+/* Define if on AIX 3.
+   System headers sometimes define this.
+   We just want to avoid a redefinition error message.  */
+#ifndef _ALL_SOURCE
+#undef _ALL_SOURCE
+#endif
+
+/* Define if using alloca.c.  */
+#undef C_ALLOCA
+
+/* Define if type char is unsigned and you are not using gcc.  */
+#ifndef __CHAR_UNSIGNED__
+#undef __CHAR_UNSIGNED__
+#endif
+
+/* Define if the closedir function returns void instead of int.  */
+#undef CLOSEDIR_VOID
+
+/* Define to empty if the keyword does not work.  */
+#undef const
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+   This function is required for alloca.c support on those systems.  */
+#undef CRAY_STACKSEG_END
+
+/* Define for DGUX with <sys/dg_sys_info.h>.  */
+#undef DGUX
+
+/* Define if you have <dirent.h>.  */
+#undef DIRENT
+
+/* Define to the type of elements in the array set by `getgroups'.
+   Usually this is either `int' or `gid_t'.  */
+#undef GETGROUPS_T
+
+/* Define if the `getloadavg' function needs to be run setuid or setgid.  */
+#undef GETLOADAVG_PRIVILEGED
+
+/* Define if the `getpgrp' function takes no argument.  */
+#undef GETPGRP_VOID
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+#undef gid_t
+
+/* Define if you have alloca, as a function or macro.  */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix).  */
+#undef HAVE_ALLOCA_H
+
+/* Define if you don't have vprintf but do have _doprnt.  */
+#undef HAVE_DOPRNT
+
+/* Define if your system has its own `getloadavg' function.  */
+#undef HAVE_GETLOADAVG
+
+/* Define if you have the getmntent function.  */
+#undef HAVE_GETMNTENT
+
+/* Define if the `long double' type works.  */
+#undef HAVE_LONG_DOUBLE
+
+/* Define if you support file names longer than 14 characters.  */
+#undef HAVE_LONG_FILE_NAMES
+
+/* Define if you have a working `mmap' system call.  */
+#undef HAVE_MMAP
+
+/* Define if system calls automatically restart after interruption
+   by a signal.  */
+#undef HAVE_RESTARTABLE_SYSCALLS
+
+/* Define if your struct stat has st_blksize.  */
+#undef HAVE_ST_BLKSIZE
+
+/* Define if your struct stat has st_blocks.  */
+#undef HAVE_ST_BLOCKS
+
+/* Define if you have the strcoll function and it is properly defined.  */
+#undef HAVE_STRCOLL
+
+/* Define if your struct stat has st_rdev.  */
+#undef HAVE_ST_RDEV
+
+/* Define if you have the strftime function.  */
+#undef HAVE_STRFTIME
+
+/* Define if you have <sys/wait.h> that is POSIX.1 compatible.  */
+#undef HAVE_SYS_WAIT_H
+
+/* Define if your struct tm has tm_zone.  */
+#undef HAVE_TM_ZONE
+
+/* Define if you don't have tm_zone but do have the external array
+   tzname.  */
+#undef HAVE_TZNAME
+
+/* Define if you have <unistd.h>.  */
+#undef HAVE_UNISTD_H
+
+/* Define if utime(file, NULL) sets file's timestamp to the present.  */
+#undef HAVE_UTIME_NULL
+
+/* Define if you have <vfork.h>.  */
+#undef HAVE_VFORK_H
+
+/* Define if you have the vprintf function.  */
+#undef HAVE_VPRINTF
+
+/* Define if you have the wait3 system call.  */
+#undef HAVE_WAIT3
+
+/* Define as __inline if that's what the C compiler calls it.  */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define if major, minor, and makedev are declared in <mkdev.h>.  */
+#undef MAJOR_IN_MKDEV
+
+/* Define if major, minor, and makedev are declared in <sysmacros.h>.  */
+#undef MAJOR_IN_SYSMACROS
+
+/* Define if on MINIX.  */
+#undef _MINIX
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+#undef mode_t
+
+/* Define if you don't have <dirent.h>, but have <ndir.h>.  */
+#undef NDIR
+
+/* Define if you have <memory.h>, and <string.h> doesn't declare the
+   mem* functions.  */
+#undef NEED_MEMORY_H
+
+/* Define if your struct nlist has an n_un member.  */
+#undef NLIST_NAME_UNION
+
+/* Define if you have <nlist.h>.  */
+#undef NLIST_STRUCT
+
+/* Define if your C compiler doesn't accept -c and -o together.  */
+#undef NO_MINUS_C_MINUS_O
+
+/* Define to `long' if <sys/types.h> doesn't define.  */
+#undef off_t
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+#undef pid_t
+
+/* Define if the system does not provide POSIX.1 features except
+   with this defined.  */
+#undef _POSIX_1_SOURCE
+
+/* Define if you need to in order for stat and other things to work.  */
+#undef _POSIX_SOURCE
+
+/* Define as the return type of signal handlers (int or void).  */
+#undef RETSIGTYPE
+
+/* Define if the setvbuf function takes the buffering type as its second
+   argument and the buffer pointer as the third, as on System V
+   before release 3.  */
+#undef SETVBUF_REVERSED
+
+/* Define SIZESOF for some Objects  */
+#undef SIZEOF_INT
+#undef SIZEOF_INT_P
+#undef SIZEOF_LONG
+
+/* Define to `unsigned' if <sys/types.h> doesn't define.  */
+#undef size_t
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at run-time.
+	STACK_DIRECTION > 0 => grows toward higher addresses
+	STACK_DIRECTION < 0 => grows toward lower addresses
+	STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
+/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly.  */
+#undef STAT_MACROS_BROKEN
+
+/* Define if you have the ANSI C header files.  */
+#undef STDC_HEADERS
+
+/* Define on System V Release 4.  */
+#undef SVR4
+
+/* Define on BSD  */
+#undef BSD
+
+/* Define on System V */
+#undef SYSV
+
+/* Define if you don't have <dirent.h>, but have <sys/dir.h>.  */
+#undef SYSDIR
+
+/* Define if you don't have <dirent.h>, but have <sys/ndir.h>.  */
+#undef SYSNDIR
+
+/* Define if `sys_siglist' is declared by <signal.h>.  */
+#undef SYS_SIGLIST_DECLARED
+
+/* Define if you can safely include both <sys/time.h> and <time.h>.  */
+#undef TIME_WITH_SYS_TIME
+
+/* Define if your <sys/time.h> declares struct tm.  */
+#undef TM_IN_SYS_TIME
+
+/* Define to `int' if <sys/types.h> doesn't define.  */
+#undef uid_t
+
+/* Define for Encore UMAX.  */
+#undef UMAX
+
+/* Define for Encore UMAX 4.3 that has <inq_status/cpustats.h>
+   instead of <sys/cpustats.h>.  */
+#undef UMAX4_3
+
+/* Define if you do not have <strings.h>, index, bzero, etc..  */
+#undef USG
+
+/* Define if the system is System V Release 4 */
+#undef SVR4
+
+/* Define vfork as fork if vfork does not work.  */
+#undef vfork
+
+/* Define if the closedir function returns void instead of int.  */
+#undef VOID_CLOSEDIR
+
+/* Define if your processor stores words with the most significant
+   byte first (like Motorola and SPARC, unlike Intel and VAX).  */
+#undef WORDS_BIGENDIAN
+
+/* Define if lex declares yytext as a char * by default, not a char[].  */
+#undef YYTEXT_POINTER
+
+#endif /* __GTKSETUPH__ */
+
+
+/* Leave that blank line there!!  Autoheader needs it.
+   If you're adding to this file, keep in mind:
+   The entries are in sort -df order: alphabetical, case insensitive,
+   ignoring punctuation (such as underscores).  */
diff --git a/src/gtk1/setup/shared/sharedAIX b/src/gtk1/setup/shared/sharedAIX
new file mode 100755
index 0000000000..cc9b6e164e
--- /dev/null
+++ b/src/gtk1/setup/shared/sharedAIX
@@ -0,0 +1,26 @@
+#! /bin/sh
+
+COMPILER=$1
+LIBRARY_BASE=$2
+LIBRARY_MAJOR=$3
+LIBRARY_MINOR=$4
+shift 3
+LIBRARY_OBJS=
+while (test $# -ne 1) do
+  shift;
+  LIBRARY_OBJS="$LIBRARY_OBJS $1sh";
+done
+
+LIBRARY_BASE=`echo $LIBRARY_BASE | sed 's/.so/.sa/'`
+LIBRARY_NAME=`basename $LIBRARY_BASE`
+LIBRARY_FILE=$LIBRARY_BASE
+
+echo "Creating shared library: $LIBRARY_FILE"
+
+ar cr $LIBRARY_FILE~ $LIBRARY_OBJS
+nm $LIBRARY_OBJS | awk  '/ [BD] /{print $$3}' | sort | uniq > ${LIBRARY_FILE}.syms
+ld -o shr.o $LIBRARY_FILE~ -lX11 -lXt -lc -lm -H512 -T512 -bE:${LIBRARY_FILE}.syms -bM:SRE
+rm -f $LIBRARY_FILE~
+ar ruv $LIBRARY_FILE shr.o
+chmod a+x $LIBRARY_FILE
+
diff --git a/src/gtk1/setup/shared/sharedBsd b/src/gtk1/setup/shared/sharedBsd
new file mode 100755
index 0000000000..4e6db1ccc7
--- /dev/null
+++ b/src/gtk1/setup/shared/sharedBsd
@@ -0,0 +1,33 @@
+#! /bin/sh
+
+#LIBRARY_BASE=`echo $1 | sed 's/.a/.so/'`
+COMPILER=$1
+LIBRARY_BASE=$2
+LIBRARY_MAJOR=$3
+LIBRARY_MINOR=$4
+shift 3
+LIBRARY_OBJS=
+while (test $# -ne 1) do
+  shift;
+  LIBRARY_OBJS="$LIBRARY_OBJS $1sh";
+done
+
+LIBRARY_NAME=`basename $LIBRARY_BASE`
+LIBRARY_FILE=$LIBRARY_BASE.$LIBRARY_MAJOR.$LIBRARY_MINOR
+
+echo "Creating shared library: $LIBRARY_FILE"
+
+if test "x$COMPILER" = xgcc ; then
+  gcc -shared -o $LIBRARY_FILE $LIBRARY_OBJS
+else
+  CC -Bshareable -Bforcearchive -o $LIBRARY_FILE $LIBRARY_OBJS
+fi
+chmod a+x $LIBRARY_FILE
+rm -f $LIBRARY_BASE.$LIBRARY_MAJOR
+ln -s $LIBRARY_NAME.$LIBRARY_MAJOR.$LIBRARY_MINOR $LIBRARY_BASE.$LIBRARY_MAJOR
+rm -f $LIBRARY_BASE
+ln -s $LIBRARY_NAME.$LIBRARY_MAJOR $LIBRARY_BASE
+
+
+
+
diff --git a/src/gtk1/setup/shared/sharedDgux b/src/gtk1/setup/shared/sharedDgux
new file mode 100755
index 0000000000..d2bfc2a1a2
--- /dev/null
+++ b/src/gtk1/setup/shared/sharedDgux
@@ -0,0 +1,29 @@
+#! /bin/sh
+
+COMPILER=$1
+LIBRARY_BASE=$2
+LIBRARY_MAJOR=$3
+LIBRARY_MINOR=$4
+shift 3
+LIBRARY_OBJS=
+while (test $# -ne 1) do
+  shift;
+  LIBRARY_OBJS="$LIBRARY_OBJS $1sh";
+done
+
+LIBRARY_BASE=`echo $LIBRARY_BASE | sed 's/.so/.sl/'`
+LIBRARY_NAME=`basename $LIBRARY_BASE`
+LIBRARY_FILE=$LIBRARY_BASE
+
+echo "Creating shared library: $LIBRARY_FILE"
+
+if test "x$COMPILER" = xgcc ; then
+  gcc -shared -h $LIBRARY_NAME -o $LIBRARY_FILE $LIBRARY_OBJS
+else
+  CC -G -h $LIBRARY_NAME -o $LIBRARY_FILE $LIBRARY_OBJS
+fi
+chmod a+x $LIBRARY_FILE
+
+
+
+
diff --git a/src/gtk1/setup/shared/sharedHpux b/src/gtk1/setup/shared/sharedHpux
new file mode 100755
index 0000000000..60c198d862
--- /dev/null
+++ b/src/gtk1/setup/shared/sharedHpux
@@ -0,0 +1,29 @@
+#! /bin/sh
+
+COMPILER=$1
+LIBRARY_BASE=$2
+LIBRARY_MAJOR=$3
+LIBRARY_MINOR=$4
+shift 3
+LIBRARY_OBJS=
+while (test $# -ne 1) do
+  shift;
+  LIBRARY_OBJS="$LIBRARY_OBJS $1sh";
+done
+
+LIBRARY_BASE=`echo $LIBRARY_BASE | sed 's/.so/.sl/'`
+LIBRARY_NAME=`basename $LIBRARY_BASE`
+LIBRARY_FILE=$LIBRARY_BASE
+
+echo "Creating shared library: $LIBRARY_FILE"
+
+if test "x$COMPILER" = xgcc ; then
+  gcc -shared -o $LIBRARY_FILE $LIBRARY_OBJS
+else
+  CC -Wl,+s -o $LIBRARY_FILE $LIBRARY_OBJS
+fi
+chmod a+x $LIBRARY_FILE
+
+
+
+
diff --git a/src/gtk1/setup/shared/sharedIrix b/src/gtk1/setup/shared/sharedIrix
new file mode 100755
index 0000000000..d2b5393c3d
--- /dev/null
+++ b/src/gtk1/setup/shared/sharedIrix
@@ -0,0 +1,45 @@
+#! /bin/sh
+# on Irix, position independent code is the default
+
+#LIBRARY_BASE=`echo $1 | sed 's/.a/.so/'`
+COMPILER=$1
+LIBRARY_BASE=$2
+LIBRARY_MAJOR=$3
+LIBRARY_MINOR=$4
+shift 3
+LIBRARY_OBJS=
+while (test $# -ne 1) do
+  shift;
+  LIBRARY_OBJS="$LIBRARY_OBJS $1";
+done
+
+LIBRARY_NAME=`basename $LIBRARY_BASE`
+LIBRARY_FILE=$LIBRARY_BASE.$LIBRARY_MAJOR.$LIBRARY_MINOR
+
+echo "Creating shared library: $LIBRARY_FILE"
+
+if test ! -f /tmp/so_locations; then
+  if test -f /usr/lib/so_locations; then
+    cp /usr/lib/so_locations /tmp
+  else
+    touch /tmp/so_locations
+  fi
+fi
+chmod u+w /tmp/so_locations
+
+if test "x$COMPILER" = xgcc ; then
+  gcc -shared -Wl,-update_registry,/tmp/so_locations \
+    -Wl,-soname,$LIBRARY_NAME.$LIBRARY_MAJOR -o $LIBRARY_FILE $LIBRARY_OBJS
+else
+  CC -shared -update_registry /tmp/so_locations \
+    -soname $LIBRARY_NAME.$LIBRARY_MAJOR -o $LIBRARY_FILE $LIBRARY_OBJS
+fi
+chmod a+x $LIBRARY_FILE
+rm -f $LIBRARY_BASE.$LIBRARY_MAJOR
+ln -s $LIBRARY_NAME.$LIBRARY_MAJOR.$LIBRARY_MINOR $LIBRARY_BASE.$LIBRARY_MAJOR
+rm -f $LIBRARY_BASE
+ln -s $LIBRARY_NAME.$LIBRARY_MAJOR $LIBRARY_BASE
+
+
+
+
diff --git a/src/gtk1/setup/shared/sharedLinux b/src/gtk1/setup/shared/sharedLinux
new file mode 100755
index 0000000000..c274903db1
--- /dev/null
+++ b/src/gtk1/setup/shared/sharedLinux
@@ -0,0 +1,34 @@
+#! /bin/sh
+
+#LIBRARY_BASE=`echo $1 | sed 's/.a/.so/'`
+COMPILER=$1
+LIBRARY_BASE=$2
+LIBRARY_MAJOR=$3
+LIBRARY_MINOR=$4
+shift 3
+LIBRARY_OBJS=
+while (test $# -ne 1) do
+  shift;
+  LIBRARY_OBJS="$LIBRARY_OBJS $1sh";
+done
+
+LIBRARY_NAME=`basename $LIBRARY_BASE`
+LIBRARY_FILE=$LIBRARY_BASE.$LIBRARY_MAJOR.$LIBRARY_MINOR
+
+echo "Creating shared library: $LIBRARY_FILE"
+
+case $COMPILER in gcc*|*gcc)
+  $COMPILER -shared -Wl,-soname,$LIBRARY_NAME.$LIBRARY_MAJOR -o $LIBRARY_FILE $LIBRARY_OBJS
+  ;;
+*)
+  $COMPILER -shared -soname $LIBRARY_NAME.$LIBRARY_MAJOR -o $LIBRARY_FILE $LIBRARY_OBJS
+esac
+chmod a+x $LIBRARY_FILE
+rm -f $LIBRARY_BASE.$LIBRARY_MAJOR
+ln -s $LIBRARY_NAME.$LIBRARY_MAJOR.$LIBRARY_MINOR $LIBRARY_BASE.$LIBRARY_MAJOR
+rm -f $LIBRARY_BASE
+ln -s $LIBRARY_NAME.$LIBRARY_MAJOR $LIBRARY_BASE
+
+
+
+
diff --git a/src/gtk1/setup/shared/sharedOSF b/src/gtk1/setup/shared/sharedOSF
new file mode 100755
index 0000000000..03ba07eca1
--- /dev/null
+++ b/src/gtk1/setup/shared/sharedOSF
@@ -0,0 +1,33 @@
+#! /bin/sh
+
+#LIBRARY_BASE=`echo $1 | sed 's/.a/.so/'`
+COMPILER=$1
+LIBRARY_BASE=$2
+LIBRARY_MAJOR=$3
+LIBRARY_MINOR=$4
+shift 3
+LIBRARY_OBJS=
+while (test $# -ne 1) do
+  shift;
+  LIBRARY_OBJS="$LIBRARY_OBJS $1sh";
+done
+
+LIBRARY_NAME=`basename $LIBRARY_BASE`
+LIBRARY_FILE=$LIBRARY_BASE.$LIBRARY_MAJOR.$LIBRARY_MINOR
+
+echo "Creating shared library: $LIBRARY_FILE"
+
+if test "x$COMPILER" = xgcc ; then
+  gcc -shared -Wl,-soname,$LIBRARY_NAME -o $LIBRARY_FILE $LIBRARY_OBJS
+else
+  $COMPILER -shared -soname $LIBRARY_NAME -o $LIBRARY_FILE $LIBRARY_OBJS
+fi
+chmod a+x $LIBRARY_FILE
+rm -f $LIBRARY_BASE.$LIBRARY_MAJOR
+ln -s $LIBRARY_NAME.$LIBRARY_MAJOR.$LIBRARY_MINOR $LIBRARY_BASE.$LIBRARY_MAJOR
+rm -f $LIBRARY_BASE
+ln -s $LIBRARY_NAME.$LIBRARY_MAJOR $LIBRARY_BASE
+
+
+
+
diff --git a/src/gtk1/setup/shared/sharedSolaris2 b/src/gtk1/setup/shared/sharedSolaris2
new file mode 100755
index 0000000000..52c9086ee2
--- /dev/null
+++ b/src/gtk1/setup/shared/sharedSolaris2
@@ -0,0 +1,33 @@
+#! /bin/sh
+
+#LIBRARY_BASE=`echo $1 | sed 's/.a/.so/'`
+COMPILER=$1
+LIBRARY_BASE=$2
+LIBRARY_MAJOR=$3
+LIBRARY_MINOR=$4
+shift 3
+LIBRARY_OBJS=
+while (test $# -ne 1) do
+  shift;
+  LIBRARY_OBJS="$LIBRARY_OBJS $1sh";
+done
+
+LIBRARY_NAME=`basename $LIBRARY_BASE`
+LIBRARY_FILE=$LIBRARY_BASE.$LIBRARY_MAJOR.$LIBRARY_MINOR
+
+echo "Creating shared library: $LIBRARY_FILE"
+
+if test "x$COMPILER" = xgcc ; then
+  gcc -shared -h $LIBRARY_NAME -o $LIBRARY_FILE $LIBRARY_OBJS
+else
+  CC -G -h $LIBRARY_NAME -o $LIBRARY_FILE $LIBRARY_OBJS
+fi
+chmod a+x $LIBRARY_FILE
+rm -f $LIBRARY_BASE.$LIBRARY_MAJOR
+ln -s $LIBRARY_NAME.$LIBRARY_MAJOR.$LIBRARY_MINOR $LIBRARY_BASE.$LIBRARY_MAJOR
+rm -f $LIBRARY_BASE
+ln -s $LIBRARY_NAME.$LIBRARY_MAJOR $LIBRARY_BASE
+
+
+
+
diff --git a/src/gtk1/setup/shared/sharedSunos4 b/src/gtk1/setup/shared/sharedSunos4
new file mode 100755
index 0000000000..7544a00584
--- /dev/null
+++ b/src/gtk1/setup/shared/sharedSunos4
@@ -0,0 +1,33 @@
+#! /bin/sh
+
+#LIBRARY_BASE=`echo $1 | sed 's/.a/.so/'`
+COMPILER=$1
+LIBRARY_BASE=$2
+LIBRARY_MAJOR=$3
+LIBRARY_MINOR=$4
+shift 3
+LIBRARY_OBJS=
+while (test $# -ne 1) do
+  shift;
+  LIBRARY_OBJS="$LIBRARY_OBJS $1sh";
+done
+
+LIBRARY_NAME=`basename $LIBRARY_BASE`
+LIBRARY_FILE=$LIBRARY_BASE.$LIBRARY_MAJOR.$LIBRARY_MINOR
+
+echo "Creating shared library: $LIBRARY_FILE"
+
+if test "x$COMPILER" = xgcc ; then
+  gcc -shared -o $LIBRARY_FILE $LIBRARY_OBJS
+else
+  CC -assert pure-text -o $LIBRARY_FILE $LIBRARY_OBJS
+fi
+chmod a+x $LIBRARY_FILE
+rm -f $LIBRARY_BASE.$LIBRARY_MAJOR
+ln -s $LIBRARY_NAME.$LIBRARY_MAJOR.$LIBRARY_MINOR $LIBRARY_BASE.$LIBRARY_MAJOR
+rm -f $LIBRARY_BASE
+ln -s $LIBRARY_NAME.$LIBRARY_MAJOR $LIBRARY_BASE
+
+
+
+
diff --git a/src/gtk1/setup/shared/sharedSysV b/src/gtk1/setup/shared/sharedSysV
new file mode 100755
index 0000000000..d2bfc2a1a2
--- /dev/null
+++ b/src/gtk1/setup/shared/sharedSysV
@@ -0,0 +1,29 @@
+#! /bin/sh
+
+COMPILER=$1
+LIBRARY_BASE=$2
+LIBRARY_MAJOR=$3
+LIBRARY_MINOR=$4
+shift 3
+LIBRARY_OBJS=
+while (test $# -ne 1) do
+  shift;
+  LIBRARY_OBJS="$LIBRARY_OBJS $1sh";
+done
+
+LIBRARY_BASE=`echo $LIBRARY_BASE | sed 's/.so/.sl/'`
+LIBRARY_NAME=`basename $LIBRARY_BASE`
+LIBRARY_FILE=$LIBRARY_BASE
+
+echo "Creating shared library: $LIBRARY_FILE"
+
+if test "x$COMPILER" = xgcc ; then
+  gcc -shared -h $LIBRARY_NAME -o $LIBRARY_FILE $LIBRARY_OBJS
+else
+  CC -G -h $LIBRARY_NAME -o $LIBRARY_FILE $LIBRARY_OBJS
+fi
+chmod a+x $LIBRARY_FILE
+
+
+
+
diff --git a/src/gtk1/setup/substit.in b/src/gtk1/setup/substit.in
new file mode 100644
index 0000000000..8e907ed258
--- /dev/null
+++ b/src/gtk1/setup/substit.in
@@ -0,0 +1,70 @@
+s|*OS*|@OS@|g
+s|*WXBASEDIR*|@WXBASEDIR@|g
+s|*PROFILE*|@PROFILE@|g
+s|*DEBUG*|@DEBUG@|g
+s|*OPTIMISE*|@OPTIMISE@|g
+s|*CC*|@CC@|g
+s|*CFLAGS*|@CFLAGS@|g
+s|*CPP*|@CPP@|g
+s|*CXX*|@CXX@|g
+s|*CXXFLAGS*|@CXXFLAGS@|g
+s|*CXXCPP*|@CXXCPP@|g
+s|*PICFLAGS*|@PICFLAGS@|g
+s|*CREATE_SHARED*|@CREATE_SHARED@|g
+s|*LEX*|@LEX@|g
+s|*LEXLIB*|@LEXLIB@|g
+s|*YACC*|@YACC@|g
+s|*RANLIB*|@RANLIB@|g
+s|*INSTALL*|@INSTALL@|g
+s|*INSTALL_PROGRAM*|@INSTALL_PROGRAM@|g
+s|*INSTALL_DATA*|@INSTALL_DATA@|g
+s|*AWK*|@AWK@|g
+s|*LN_S*|@LN_S@|g
+s|*prefix*|@prefix@|g
+s|*exec_prefix*|@exec_prefix@|g
+s|*bindir*|@bindir@|g
+s|*datadir*|@datadir@|g
+s|*infodir*|@infodir@|g
+s|*X_CFLAGS*|@X_CFLAGS@|g
+s|*X_LIBS*|@X_LIBS@|g
+s|*X_EXTRA_LIBS*|@X_EXTRA_LIBS@|g
+s|*X_PRE_LIBS*|@X_PRE_LIBS@|g
+s|*GUI_TK_INCLUDE*|@GUI_TK_INCLUDE@|g
+s|*GUI_TK_LIBRARY*|@GUI_TK_LIBRARY@|g
+s|*GUI_TK_LINK*|@GUI_TK_LINK@|g
+s|*OPENGL_INCLUDE*|@OPENGL_INCLUDE@|g
+s|*OPENGL_LIBRARY*|@OPENGL_LIBRARY@|g
+s|*OPENGL_LINK*|@OPENGL_LINK@|g
+s|*TOOLKIT*|@TOOLKIT@|g
+s|*TOOLKIT_DEF*|@TOOLKIT_DEF@|g
+s|*THREADS*|@THREADS@|g
+s|*THREADS_LINK*|@THREADS_LINK@|g
+s|*WXSTRING*|@WXSTRING@|g
+s|*TYPETREE*|@TYPETREE@|g
+s|*METAFILE*|@METAFILE@|g
+s|*POSTSCRIPTDC*|@POSTSCRIPTDC@|g
+s|*WXGRAPH*|@WXGRAPH@|g
+s|*WXTREE*|@WXTREE@|g
+s|*DOCVIEW*|@DOCVIEW@|g
+s|*FORM*|@FORM@|g
+s|*PRINTPREVIEW*|@PRINTPREVIEW@|g
+s|*IPC*|@IPC@|g
+s|*HELP*|@HELP@|g
+s|*CLIPBOARD*|@CLIPBOARD@|g
+s|*TIMEDATE*|@TIMEDATE@|g
+s|*FRACTION*|@FRACTION@|g
+s|*PROLOGIO*|@PROLOGIO@|g
+s|*PROLOGIOSRC*|@PROLOGIOSRC@|g
+s|*ENHDIALOGBOX*|@ENHDIALOGBOX@|g
+s|*GAUGE*|@GAUGE@|g
+s|*GLCANVAS*|@GLCANVAS@|g
+s|*LAYOUT*|@LAYOUT@|g
+s|*WXRESOURCES*|@WXRESOURCES@|g
+s|*XRESOURCES*|@XRESOURCES@|g
+s|*SCROLLBAR*|@SCROLLBAR@|g
+s|*STATICITEMS*|@STATICITEMS@|g
+s|*TOOLBAR*|@TOOLBAR@|g
+s|*CONSTRAINTS*|@CONSTRAINTS@|g
+s|*RPC*|@RPC@|g
+s|*VIRLISTBOX*|@VIRLISTBOX@|g
+
diff --git a/src/gtk1/slider.cpp b/src/gtk1/slider.cpp
new file mode 100644
index 0000000000..891fcf61f9
--- /dev/null
+++ b/src/gtk1/slider.cpp
@@ -0,0 +1,247 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        slider.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "slider.h"
+#endif
+
+#include "wx/slider.h"
+#include "wx/utils.h"
+
+//-----------------------------------------------------------------------------
+// wxSlider
+//-----------------------------------------------------------------------------
+
+void gtk_slider_callback( GtkWidget *WXUNUSED(widget), wxSlider *win )
+{ 
+/*
+  printf( "OnScroll from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  if (!win->HasVMT()) return;
+    
+  float diff = win->m_adjust->value - win->m_oldPos;
+  if (fabs(diff) < 0.2) return;
+  
+  int command = 0;
+  
+  float line_step = win->m_adjust->step_increment;
+  float page_step = win->m_adjust->page_increment;
+  
+  if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN;
+  else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP;
+  else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN;
+  else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP;
+  else command = wxEVT_SCROLL_THUMBTRACK;
+
+  int value = (int)(win->m_adjust->value+0.5);
+      
+  int orient = wxHORIZONTAL;
+  if (win->GetWindowStyleFlag() & wxSB_VERTICAL == wxSB_VERTICAL) orient = wxHORIZONTAL;
+  
+  wxScrollEvent event( command, win->GetId(), value, orient );
+  event.SetEventObject( win );
+  win->ProcessEvent( event );
+  
+  wxCommandEvent cevent( wxEVT_COMMAND_SLIDER_UPDATED, win->GetId() );
+  cevent.SetEventObject( win );
+  win->ProcessEvent( cevent );
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxSlider,wxControl)
+
+wxSlider::wxSlider(void)
+{
+};
+
+wxSlider::wxSlider( wxWindow *parent, const wxWindowID id,
+        const int value, const int minValue, const int maxValue,
+        const wxPoint& pos, const wxSize& size,
+        const long style,
+/*      const wxValidator& validator = wxDefaultValidator, */
+        const wxString& name )
+{
+  Create( parent, id, value, minValue, maxValue,
+          pos, size, style, name );
+};
+
+wxSlider::~wxSlider(void)
+{
+};
+
+bool wxSlider::Create(wxWindow *parent, const wxWindowID id,
+        const int value, const int minValue, const int maxValue,
+        const wxPoint& pos, const wxSize& size,
+        const long style,
+/*      const wxValidator& validator = wxDefaultValidator, */
+        const wxString& name )
+{
+  m_needParent = TRUE;
+  
+  PreCreation( parent, id, pos, size, style, name );
+  
+  m_oldPos = 0.0;
+
+  if (style & wxSL_VERTICAL == wxSL_VERTICAL)
+    m_widget = gtk_hscale_new( NULL );
+  else
+    m_widget = gtk_vscale_new( NULL );
+    
+  m_adjust = gtk_range_get_adjustment( GTK_RANGE(m_widget) );
+  
+  gtk_signal_connect (GTK_OBJECT (m_adjust), "value_changed",
+		      (GtkSignalFunc) gtk_slider_callback, (gpointer) this );
+  SetRange( minValue, maxValue );
+  SetValue( value );
+  
+  PostCreation();
+  
+  Show( TRUE );
+    
+  return TRUE;
+};
+
+int wxSlider::GetValue(void) const
+{
+  return (int)(m_adjust->value+0.5);
+};
+
+void wxSlider::SetValue( const int value )
+{
+  float fpos = (float)value;
+  m_oldPos = fpos;
+  if (fabs(fpos-m_adjust->value) < 0.2) return;
+  m_adjust->value = fpos;
+  
+  gtk_signal_emit_by_name( GTK_OBJECT(m_adjust), "value_changed" );
+};
+
+void wxSlider::SetRange( const int minValue, const int maxValue )
+{
+  float fmin = (float)minValue;
+  float fmax = (float)maxValue;
+      
+  if ((fabs(fmin-m_adjust->lower) < 0.2) &&
+      (fabs(fmax-m_adjust->upper) < 0.2))
+      return;
+      
+  m_adjust->lower = fmin;
+  m_adjust->upper = fmax;
+
+  gtk_signal_emit_by_name( GTK_OBJECT(m_adjust), "changed" );
+};
+
+int wxSlider::GetMin(void) const
+{
+  return (int)(m_adjust->lower+0.5);
+};
+
+int wxSlider::GetMax(void) const
+{
+  return (int)(m_adjust->upper+0.5);
+};
+
+void wxSlider::SetPageSize( const int pageSize )
+{
+  float fpage = (float)pageSize;
+      
+  if (fabs(fpage-m_adjust->page_increment) < 0.2) return;
+      
+  m_adjust->page_increment = fpage;
+
+  gtk_signal_emit_by_name( GTK_OBJECT(m_adjust), "changed" );
+};
+
+int wxSlider::GetPageSize(void) const
+{
+  return (int)(m_adjust->page_increment+0.5);
+};
+
+void wxSlider::SetThumbLength( const int len )
+{
+  float flen = (float)len;
+      
+  if (fabs(flen-m_adjust->page_size) < 0.2) return;
+      
+  m_adjust->page_size = flen;
+
+  gtk_signal_emit_by_name( GTK_OBJECT(m_adjust), "changed" );
+};
+
+int wxSlider::GetThumbLength(void) const
+{
+  return (int)(m_adjust->page_size+0.5);
+};
+
+void wxSlider::SetLineSize( const int WXUNUSED(lineSize) )
+{
+};
+
+int wxSlider::GetLineSize(void) const
+{
+  return 0;
+};
+
+// not supported in wxGTK (and GTK)
+
+void wxSlider::GetSize( int *x, int *y ) const
+{
+  wxWindow::GetSize( x, y );
+};
+
+void wxSlider::SetSize( const int x, const int y, const int width, const int height, const int sizeFlags )
+{
+  wxWindow::SetSize( x, y, width, height, sizeFlags );
+};
+
+void wxSlider::GetPosition( int *x, int *y ) const
+{
+  wxWindow::GetPosition( x, y );
+};
+
+void wxSlider::SetTick( const int WXUNUSED(tickPos) )
+{
+};
+
+void wxSlider::SetTickFreq( const int WXUNUSED(n), const int WXUNUSED(pos) )
+{
+};
+
+int wxSlider::GetTickFreq(void) const
+{
+  return 0;
+};
+
+void wxSlider::ClearTicks(void)
+{
+};
+
+void wxSlider::SetSelection( const int WXUNUSED(minPos), const int WXUNUSED(maxPos) )
+{
+};
+
+int wxSlider::GetSelEnd(void) const
+{
+  return 0;
+};
+
+int wxSlider::GetSelStart(void) const
+{
+  return 0;
+};
+
+void wxSlider::ClearSel(void)
+{
+};
+
diff --git a/src/gtk1/statbox.cpp b/src/gtk1/statbox.cpp
new file mode 100644
index 0000000000..f07862fa34
--- /dev/null
+++ b/src/gtk1/statbox.cpp
@@ -0,0 +1,49 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        statbox.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "statbox.h"
+#endif
+
+#include "wx/statbox.h"
+
+//-----------------------------------------------------------------------------
+// wxStaticBox
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxStaticBox,wxControl)
+
+wxStaticBox::wxStaticBox(void)
+{
+};
+
+wxStaticBox::wxStaticBox( wxWindow *parent, wxWindowID id, const wxString &label, 
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  Create( parent, id, label, pos, size, style, name );
+};
+
+bool wxStaticBox::Create( wxWindow *parent, wxWindowID id, const wxString &label, 
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  m_needParent = TRUE;
+  
+  PreCreation( parent, id, pos, size, style, name );
+
+  m_widget = gtk_frame_new( label );
+  
+  PostCreation();
+  
+  Show( TRUE );
+    
+  return TRUE;
+};
diff --git a/src/gtk1/stattext.cpp b/src/gtk1/stattext.cpp
new file mode 100644
index 0000000000..62340474fc
--- /dev/null
+++ b/src/gtk1/stattext.cpp
@@ -0,0 +1,69 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        stattext.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "stattext.h"
+#endif
+
+#include "wx/stattext.h"
+
+//-----------------------------------------------------------------------------
+// wxStaticText
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxStaticText,wxControl)
+
+wxStaticText::wxStaticText(void)
+{
+};
+
+wxStaticText::wxStaticText( wxWindow *parent, wxWindowID id, const wxString &label, 
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  Create( parent, id, label, pos, size, style, name );
+};
+
+bool wxStaticText::Create( wxWindow *parent, wxWindowID id, const wxString &label, 
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  m_needParent = TRUE;
+  
+  wxSize newSize = size;
+  
+  PreCreation( parent, id, pos, size, style, name );
+  
+  m_widget = gtk_label_new( label );
+  
+  if (newSize.x == -1) newSize.x = gdk_string_measure( m_widget->style->font, label );
+  if (newSize.y == -1) newSize.y = 26;
+  SetSize( newSize.x, newSize.y );
+  
+  PostCreation();
+  
+  Show( TRUE );
+    
+  return TRUE;
+};
+
+wxString wxStaticText::GetLabel(void) const
+{
+  char *str = NULL;
+  gtk_label_get( GTK_LABEL(m_widget), &str );
+  wxString tmp( str );
+  return tmp;
+};
+
+void wxStaticText::SetLabel( const wxString &label )
+{
+  gtk_label_set( GTK_LABEL(m_widget), label );
+};
diff --git a/src/gtk1/tbargtk.cpp b/src/gtk1/tbargtk.cpp
new file mode 100644
index 0000000000..628b35c69d
--- /dev/null
+++ b/src/gtk1/tbargtk.cpp
@@ -0,0 +1,207 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        tbargtk.cpp
+// Purpose:     GTK toolbar
+// Author:      Robert Roebling
+// Modified by:
+// Created:     01/02/97
+// RCS-ID:      
+// Copyright:   (c) Robert Roebling
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "tbargtk.h"
+#endif
+
+#include "wx/toolbar.h"
+
+//-----------------------------------------------------------------------------
+// wxToolBarTool
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxToolBarTool,wxObject)
+  
+wxToolBarTool::wxToolBarTool( wxToolBarGTK *owner, const int theIndex, 
+      const wxBitmap& bitmap1, const  wxBitmap& bitmap2, 
+      const bool toggle, wxObject *clientData,
+      const wxString& shortHelpString, const wxString& longHelpString )
+{
+  m_owner = owner;
+  m_index = theIndex;
+  m_bitmap1 = bitmap1;
+  m_bitmap2 = bitmap2;
+  m_isToggle = toggle;
+  m_enabled = TRUE;
+  m_toggleState = FALSE;
+  m_shortHelpString = shortHelpString;
+  m_longHelpString = longHelpString;
+  m_isMenuCommand = TRUE;
+  m_clientData = clientData;
+  m_deleteSecondBitmap = FALSE;
+};
+
+wxToolBarTool::~wxToolBarTool(void)
+{
+};
+
+//-----------------------------------------------------------------------------
+// wxToolBarGTK
+//-----------------------------------------------------------------------------
+
+static void gtk_toolbar_callback( GtkWidget *WXUNUSED(widget), wxToolBarTool *tool )
+{
+  if (!tool->m_enabled) return;
+  
+  if (tool->m_isToggle) tool->m_toggleState = !tool->m_toggleState;
+  
+  tool->m_owner->OnLeftClick( tool->m_index, tool->m_toggleState );
+};
+
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxToolBarGTK,wxControl)
+
+BEGIN_EVENT_TABLE(wxToolBarGTK, wxControl)
+END_EVENT_TABLE()
+
+wxToolBarGTK::wxToolBarGTK(void)
+{
+};
+
+wxToolBarGTK::wxToolBarGTK( wxWindow *parent, const wxWindowID id, 
+  const wxPoint& pos, const wxSize& size,
+  const long style, const wxString& name )
+{
+  Create( parent, id, pos, size, style, name );
+};
+
+wxToolBarGTK::~wxToolBarGTK(void)
+{
+};
+
+bool wxToolBarGTK::Create( wxWindow *parent, const wxWindowID id, 
+  const wxPoint& pos, const wxSize& size,
+  const long style, const wxString& name )
+{
+  m_needParent = TRUE;
+  
+  PreCreation( parent, id, pos, size, style, name );
+
+  m_tools.DeleteContents( TRUE );
+    
+  m_widget = gtk_handle_box_new();
+  
+  m_toolbar = GTK_TOOLBAR( gtk_toolbar_new( GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_ICONS ) );
+  
+  gtk_container_add( GTK_CONTAINER(m_widget), GTK_WIDGET(m_toolbar) );
+  
+  gtk_widget_show( GTK_WIDGET(m_toolbar) );
+  
+  PostCreation();
+  
+  Show( TRUE );
+    
+  return TRUE;
+};
+
+bool wxToolBarGTK::OnLeftClick( int toolIndex, bool toggleDown )
+{
+  wxCommandEvent event(wxEVT_COMMAND_TOOL_CLICKED, toolIndex);
+  event.SetEventObject(this);
+  event.SetExtraLong((long) toggleDown);
+
+  GetEventHandler()->ProcessEvent(event);
+
+  return TRUE;
+};
+
+void wxToolBarGTK::OnRightClick( int toolIndex, float WXUNUSED(x), float WXUNUSED(y) )
+{
+  wxCommandEvent event(wxEVT_COMMAND_TOOL_RCLICKED, toolIndex);
+  event.SetEventObject(this);
+
+  GetEventHandler()->ProcessEvent(event);
+};
+
+void wxToolBarGTK::OnMouseEnter( int toolIndex )
+{
+  wxCommandEvent event(wxEVT_COMMAND_TOOL_ENTER, toolIndex);
+  event.SetEventObject(this);
+
+  GetEventHandler()->ProcessEvent(event);
+};
+
+wxToolBarTool *wxToolBarGTK::AddTool( const int toolIndex, const wxBitmap& bitmap, 
+  const wxBitmap& pushedBitmap, const bool toggle, 
+  const float WXUNUSED(xPos), const float WXUNUSED(yPos), wxObject *clientData,  
+  const wxString& helpString1, const wxString& helpString2 )
+{
+  if (!bitmap.Ok()) return NULL;
+  
+  wxToolBarTool *tool = new wxToolBarTool( this, toolIndex, bitmap, pushedBitmap, toggle, 
+  clientData, helpString1, helpString2 );
+  
+  GdkPixmap *pixmap = bitmap.GetPixmap();
+  
+  GdkBitmap *mask = NULL;
+  if (bitmap.GetMask()) mask = bitmap.GetMask()->GetBitmap();
+  
+  GtkWidget *tool_pixmap = gtk_pixmap_new( pixmap, mask );
+  gtk_misc_set_alignment( GTK_MISC(tool_pixmap), 0.5, 0.5 );
+  
+  GtkToolbarChildType ctype = GTK_TOOLBAR_CHILD_BUTTON;
+  if (toggle) ctype = GTK_TOOLBAR_CHILD_TOGGLEBUTTON;
+  
+  gtk_toolbar_append_element( m_toolbar, 
+    ctype, NULL, NULL, helpString1, "", tool_pixmap, (GtkSignalFunc)gtk_toolbar_callback, (gpointer)tool );
+    
+  m_tools.Append( tool );    
+    
+  return tool;
+};
+
+void wxToolBarGTK::AddSeparator(void)
+{
+  gtk_toolbar_append_space( m_toolbar );
+};
+
+void wxToolBarGTK::ClearTools(void)
+{
+};
+
+void wxToolBarGTK::EnableTool(const int toolIndex, const bool enable)
+{
+};
+
+void wxToolBarGTK::ToggleTool(const int toolIndex, const bool toggle)
+{
+};
+
+void wxToolBarGTK::SetToggle(const int toolIndex, const bool toggle) 
+{
+};
+
+wxObject *wxToolBarGTK::GetToolClientData(const int index) const
+{
+};
+
+bool wxToolBarGTK::GetToolState(const int toolIndex) const
+{
+};
+
+bool wxToolBarGTK::GetToolEnabled(const int toolIndex) const
+{
+};
+
+void wxToolBarGTK::SetMargins(const int x, const int y)
+{
+};
+
+void wxToolBarGTK::SetToolPacking(const int packing)
+{
+};
+
+void wxToolBarGTK::SetToolSeparation(const int separation)
+{
+};
+
diff --git a/src/gtk1/textctrl.cpp b/src/gtk1/textctrl.cpp
new file mode 100644
index 0000000000..890393380a
--- /dev/null
+++ b/src/gtk1/textctrl.cpp
@@ -0,0 +1,391 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        textctrl.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "textctrl.h"
+#endif
+
+#include "wx/textctrl.h"
+#include "wx/utils.h"
+
+//-----------------------------------------------------------------------------
+//  wxTextCtrl
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl,wxControl)
+
+
+BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
+//  EVT_CHAR(wxTextCtrl::OnChar)
+END_EVENT_TABLE()
+
+wxTextCtrl::wxTextCtrl(void) : streambuf()
+{
+};
+
+wxTextCtrl::wxTextCtrl( wxWindow *parent, const wxWindowID id, const wxString &value, 
+      const wxPoint &pos, const wxSize &size, 
+      const int style, const wxString &name ) : streambuf()
+{
+  Create( parent, id, value, pos, size, style, name );
+};
+
+bool wxTextCtrl::Create( wxWindow *parent, const wxWindowID id, const wxString &value,
+      const wxPoint &pos, const wxSize &size, 
+      const int style, const wxString &name )
+{
+  m_needParent = TRUE;
+  
+  PreCreation( parent, id, pos, size, style, name );
+  
+  if (style & wxTE_MULTILINE)
+    m_widget = gtk_text_new( NULL, NULL );
+  else
+    m_widget = gtk_entry_new();
+    
+  if (!value.IsNull())
+  {
+    gint tmp = 0;
+    gtk_editable_insert_text( GTK_EDITABLE(m_widget), value, value.Length(), &tmp );
+  };
+  
+  wxSize newSize = size;
+  if (newSize.x == -1) newSize.x = 80;
+  if (newSize.y == -1) newSize.y = 26;
+  SetSize( newSize.x, newSize.y );
+  
+  PostCreation();
+  
+  Show( TRUE );
+    
+  return TRUE;
+};
+
+wxString wxTextCtrl::GetValue(void) const
+{
+  wxString tmp;
+  if (m_windowStyle & wxTE_MULTILINE)
+  {
+    gint len = gtk_text_get_length( GTK_TEXT(m_widget) );
+    tmp = gtk_editable_get_chars( GTK_EDITABLE(m_widget), 0, len-1 );
+  }
+  else
+  {
+    tmp = gtk_entry_get_text( GTK_ENTRY(m_widget) );
+  };
+  return tmp;
+};
+
+void wxTextCtrl::SetValue( const wxString &value )
+{
+  wxString tmp = "";
+  if (!value.IsNull()) tmp = value;
+  if (m_windowStyle & wxTE_MULTILINE)
+  {
+    gint len = gtk_text_get_length( GTK_TEXT(m_widget) );
+    gtk_editable_delete_text( GTK_EDITABLE(m_widget), 0, len-1 );
+    len = 0;
+    gtk_editable_insert_text( GTK_EDITABLE(m_widget), tmp, tmp.Length(), &len );
+  }
+  else
+  {
+    gtk_entry_set_text( GTK_ENTRY(m_widget), tmp );
+  };
+};
+
+void wxTextCtrl::WriteText( const wxString &text )
+{
+  if (text.IsNull()) return;
+  if (m_windowStyle & wxTE_MULTILINE)
+  {
+    gint len = gtk_text_get_length( GTK_TEXT(m_widget) );
+    gtk_editable_insert_text( GTK_EDITABLE(m_widget), text, text.Length(), &len );
+  }
+  else
+  {
+    gtk_entry_append_text( GTK_ENTRY(m_widget), text );
+  };
+};
+
+/*
+wxString wxTextCtrl::GetLineText( const long lineNo ) const
+{
+};
+
+bool wxTextCtrl::LoadFile( const wxString &file )
+{
+};
+
+bool wxTextCtrl::SaveFile( const wxString &file )
+{
+};
+
+void wxTextCtrl::DiscardEdits(void)
+{
+};
+
+bool wxTextCtrl::IsModified(void)
+{
+};
+
+void wxTextCtrl::OnDropFiles( wxDropFilesEvent &event )
+{
+};
+
+long wxTextCtrl::PositionToXY( const long pos, long *x, long *y ) const
+{
+};
+
+long wxTextCtrl::XYToPosition( const long x, const long y )
+{
+};
+
+int wxTextCtrl::GetNumberOfLines(void)
+{
+};
+
+*/
+void wxTextCtrl::SetInsertionPoint( const long pos )
+{
+  int tmp = (int) pos;
+  if (m_windowStyle & wxTE_MULTILINE)
+    gtk_text_set_point( GTK_TEXT(m_widget), tmp );
+  else
+    gtk_entry_set_position( GTK_ENTRY(m_widget), tmp );
+};
+
+void wxTextCtrl::SetInsertionPointEnd(void)
+{
+  int pos = 0;
+  if (m_windowStyle & wxTE_MULTILINE)
+    pos = gtk_text_get_length( GTK_TEXT(m_widget) );
+  else
+    pos = GTK_ENTRY(m_widget)->text_length;
+  SetInsertionPoint( pos-1 );
+};
+
+void wxTextCtrl::SetEditable( const bool editable )
+{
+  if (m_windowStyle & wxTE_MULTILINE)
+    gtk_text_set_editable( GTK_TEXT(m_widget), editable );
+  else
+    gtk_entry_set_editable( GTK_ENTRY(m_widget), editable );
+};
+
+void wxTextCtrl::SetSelection( const long from, const long to )
+{
+  gtk_editable_select_region( GTK_EDITABLE(m_widget), (gint)from, (gint)to );
+};
+
+void wxTextCtrl::ShowPosition( const long WXUNUSED(pos) )
+{
+};
+
+long wxTextCtrl::GetInsertionPoint(void) const
+{
+  return (long) GTK_EDITABLE(m_widget)->current_pos;
+};
+
+long wxTextCtrl::GetLastPosition(void) const
+{
+  int pos = 0;
+  if (m_windowStyle & wxTE_MULTILINE)
+    pos = gtk_text_get_length( GTK_TEXT(m_widget) );
+  else
+    pos = GTK_ENTRY(m_widget)->text_length;
+  return (long)pos-1;
+};
+
+void wxTextCtrl::Remove( const long from, const long to )
+{
+  gtk_editable_delete_text( GTK_EDITABLE(m_widget), (gint)from, (gint)to );
+};
+
+void wxTextCtrl::Replace( const long from, const long to, const wxString &value )
+{
+  gtk_editable_delete_text( GTK_EDITABLE(m_widget), (gint)from, (gint)to );
+  if (value.IsNull()) return;
+  gint pos = (gint)to;
+  gtk_editable_insert_text( GTK_EDITABLE(m_widget), value, value.Length(), &pos );
+};
+
+void wxTextCtrl::Cut(void)
+{
+  gtk_editable_cut_clipboard( GTK_EDITABLE(m_widget), 0 );
+};
+
+void wxTextCtrl::Copy(void)
+{
+  gtk_editable_copy_clipboard( GTK_EDITABLE(m_widget), 0 );
+};
+
+void wxTextCtrl::Paste(void)
+{
+  gtk_editable_paste_clipboard( GTK_EDITABLE(m_widget), 0 );
+};
+
+void wxTextCtrl::Delete(void)
+{
+  SetValue( "" );
+};
+
+void wxTextCtrl::OnChar( wxKeyEvent &WXUNUSED(event) )
+{
+};
+
+int wxTextCtrl::overflow(int c)
+{
+  // Make sure there is a holding area
+  if ( allocate()==EOF )
+  {
+    wxError("Streambuf allocation failed","Internal error");
+    return EOF;
+  }
+  
+  // Verify that there are no characters in get area
+  if ( gptr() && gptr() < egptr() )
+  {
+     wxError("Who's trespassing my get area?","Internal error");
+     return EOF;
+  }
+
+  // Reset get area
+  setg(0,0,0);
+
+  // Make sure there is a put area
+  if ( ! pptr() )
+  {
+/* This doesn't seem to be fatal so comment out error message */
+//    wxError("Put area not opened","Internal error");
+    setp( base(), base() );
+  }
+
+  // Determine how many characters have been inserted but no consumed
+  int plen = pptr() - pbase();
+
+  // Now Jerry relies on the fact that the buffer is at least 2 chars
+  // long, but the holding area "may be as small as 1" ???
+  // And we need an additional \0, so let's keep this inefficient but
+  // safe copy.
+
+  // If c!=EOF, it is a character that must also be comsumed
+  int xtra = c==EOF? 0 : 1;
+
+  // Write temporary C-string to wxTextWindow
+  {
+  char *txt = new char[plen+xtra+1];
+  memcpy(txt, pbase(), plen);
+  txt[plen] = (char)c;     // append c
+  txt[plen+xtra] = '\0';   // append '\0' or overwrite c
+    // If the put area already contained \0, output will be truncated there
+  WriteText(txt);
+    delete[] txt;
+  }
+
+  // Reset put area
+  setp(pbase(), epptr());
+
+#if defined(__WATCOMC__)
+  return __NOT_EOF;
+#elif defined(zapeof)     // HP-UX (all cfront based?)
+  return zapeof(c);
+#else
+  return c!=EOF ? c : 0;  // this should make everybody happy
+#endif
+
+/* OLD CODE
+  int len = pptr() - pbase();
+  char *txt = new char[len+1];
+  strncpy(txt, pbase(), len);
+  txt[len] = '\0';
+  (*this) << txt;
+  setp(pbase(), epptr());
+  delete[] txt;
+  return EOF;
+*/
+};
+
+int wxTextCtrl::sync(void)
+{
+  // Verify that there are no characters in get area
+  if ( gptr() && gptr() < egptr() )
+  {
+     wxError("Who's trespassing my get area?","Internal error");
+     return EOF;
+  }
+
+  if ( pptr() && pptr() > pbase() ) return overflow(EOF);
+
+  return 0;
+/* OLD CODE
+  int len = pptr() - pbase();
+  char *txt = new char[len+1];
+  strncpy(txt, pbase(), len);
+  txt[len] = '\0';
+  (*this) << txt;
+  setp(pbase(), epptr());
+  delete[] txt;
+  return 0;
+*/
+};
+
+int wxTextCtrl::underflow(void)
+{
+  return EOF;
+};
+
+wxTextCtrl& wxTextCtrl::operator<<(const wxString& s)
+{
+  WriteText(s);
+  return *this;
+}
+
+wxTextCtrl& wxTextCtrl::operator<<(const float f)
+{
+  static char buf[100];
+  sprintf(buf, "%.2f", f);
+  WriteText(buf);
+  return *this;
+}
+
+wxTextCtrl& wxTextCtrl::operator<<(const double d)
+{
+  static char buf[100];
+  sprintf(buf, "%.2f", d);
+  WriteText(buf);
+  return *this;
+}
+
+wxTextCtrl& wxTextCtrl::operator<<(const int i)
+{
+  static char buf[100];
+  sprintf(buf, "%i", i);
+  WriteText(buf);
+  return *this;
+}
+
+wxTextCtrl& wxTextCtrl::operator<<(const long i)
+{
+  static char buf[100];
+  sprintf(buf, "%ld", i);
+  WriteText(buf);
+  return *this;
+}
+
+wxTextCtrl& wxTextCtrl::operator<<(const char c)
+{
+  char buf[2];
+
+  buf[0] = c;
+  buf[1] = 0;
+  WriteText(buf);
+  return *this;
+}
+
diff --git a/src/gtk1/timer.cpp b/src/gtk1/timer.cpp
new file mode 100644
index 0000000000..f87bffa62b
--- /dev/null
+++ b/src/gtk1/timer.cpp
@@ -0,0 +1,71 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        timer.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "timer.h"
+#endif
+
+#include "wx/timer.h"
+
+//-----------------------------------------------------------------------------
+// wxTimer
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxTimer,wxObject)
+
+gint timeout_callback( gpointer data )
+{
+  wxTimer *timer = (wxTimer*)data;
+  timer->Notify();
+  if (timer->OneShot()) timer->Stop();
+  return TRUE;
+};
+
+wxTimer::wxTimer(void)
+{
+  m_tag = -1;
+  m_time = 1000;
+  m_oneShot = FALSE;
+};
+
+wxTimer::~wxTimer(void)
+{
+  Stop();
+};
+
+int wxTimer::Interval(void)
+{
+  return m_time;
+};
+
+bool wxTimer::OneShot(void)
+{
+  return m_oneShot;
+};
+
+void wxTimer::Notify(void)
+{
+};
+
+void wxTimer::Start( int millisecs, bool oneShot )
+{
+  if (millisecs != -1) m_time = millisecs;
+  m_oneShot = oneShot;
+  m_tag = gtk_timeout_add( millisecs, timeout_callback, this );
+};
+
+void wxTimer::Stop(void)
+{
+  if (m_tag != -1)
+    gtk_timeout_remove( m_tag );
+  m_tag = -1;
+};
+
diff --git a/src/gtk1/utilsgtk.cpp b/src/gtk1/utilsgtk.cpp
new file mode 100644
index 0000000000..3ff9803dd4
--- /dev/null
+++ b/src/gtk1/utilsgtk.cpp
@@ -0,0 +1,406 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        utils.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+//#ifdef __GNUG__
+//#pragma implementation "utils.h"
+//#endif
+
+#include "wx/utils.h"
+#include "wx/string.h"
+
+#include <stdarg.h>
+#include <dirent.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <pwd.h>
+#include <errno.h>
+#include <netdb.h>
+
+#ifdef __SVR4__
+#include <sys/systeminfo.h>
+#endif
+
+//------------------------------------------------------------------------
+// misc.
+//------------------------------------------------------------------------
+
+void wxBell(void)
+{
+  gdk_beep();
+};
+
+//------------------------------------------------------------------------
+// user and home routines
+//------------------------------------------------------------------------
+
+char* wxGetHomeDir( char *dest )
+{
+  wxString tmp = wxGetUserHome( wxString() );
+  if (tmp.IsNull())
+    strcpy( wxBuffer, "/" );
+  else
+    strcpy( wxBuffer, tmp );
+  if (dest) strcpy( dest, WXSTRINGCAST tmp );
+  return wxBuffer;
+};
+
+char *wxGetUserHome( const wxString &user )
+{
+  struct passwd *who = NULL;
+
+  if (user.IsNull() || (user== "")) 
+  {
+	register char *ptr;
+
+	if ((ptr = getenv("HOME")) != NULL) 
+	    return ptr;
+	if ((ptr = getenv("USER")) != NULL
+	|| (ptr = getenv("LOGNAME")) != NULL) {
+	    who = getpwnam(ptr);
+	}
+	// We now make sure the the user exists!
+	if (who == NULL)
+	    who = getpwuid(getuid());
+  } 
+  else
+    who = getpwnam (user);
+    
+  return who ? who->pw_dir : (char*)NULL;
+};
+
+//------------------------------------------------------------------------
+// id routines
+//------------------------------------------------------------------------
+
+bool wxGetHostName(char *buf, int sz)
+{
+    *buf = '\0';
+#if defined(__SVR4__) && !defined(__sgi)
+    return (sysinfo(SI_HOSTNAME, buf, sz) != -1);
+#else /* BSD Sockets */
+    char name[255];
+    struct hostent *h;
+    // Get hostname
+    if (gethostname(name, sizeof(name)/sizeof(char)-1) == -1)
+	return FALSE;
+    // Get official full name of host
+    strncpy(buf, (h=gethostbyname(name))!=NULL ? h->h_name : name, sz-1);
+    return TRUE;
+#endif
+}
+
+bool wxGetUserId(char *buf, int sz)
+{
+    struct passwd *who;
+
+    *buf = '\0';
+    if ((who = getpwuid(getuid ())) != NULL) {
+	strncpy (buf, who->pw_name, sz-1);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+bool wxGetUserName(char *buf, int sz)
+{
+    struct passwd *who;
+
+    *buf = '\0';
+    if ((who = getpwuid (getuid ())) != NULL) {
+	strncpy (buf, who->pw_gecos, sz - 1);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+//------------------------------------------------------------------------
+// error and debug output routines
+//------------------------------------------------------------------------
+
+void wxDebugMsg( const char *format, ... )
+{
+  va_list ap;
+  va_start( ap, format );
+  vfprintf( stderr, format, ap ); 
+  fflush( stderr );
+  va_end(ap);
+};
+
+void wxError( const wxString &msg, const wxString &title )
+{
+  fprintf( stderr, "Error " );
+  if (!title.IsNull()) fprintf( stderr, "%s ", WXSTRINGCAST(title) );
+  if (!msg.IsNull()) fprintf( stderr, ": %s", WXSTRINGCAST(msg) );
+  fprintf( stderr, ".\n" );
+};
+
+void wxFatalError( const wxString &msg, const wxString &title )
+{
+  fprintf( stderr, "Error " );
+  if (!title.IsNull()) fprintf( stderr, "%s ", WXSTRINGCAST(title) );
+  if (!msg.IsNull()) fprintf( stderr, ": %s", WXSTRINGCAST(msg) );
+  fprintf( stderr, ".\n" );
+  exit(1);
+};
+
+//------------------------------------------------------------------------
+// directory routines
+//------------------------------------------------------------------------
+
+bool wxDirExists( const wxString& dir )
+{
+  char buf[500];
+  strcpy( buf, WXSTRINGCAST(dir) );
+  struct stat sbuf;
+  return ((stat(buf, &sbuf) != -1) && S_ISDIR(sbuf.st_mode) ? TRUE : FALSE);
+};
+
+//------------------------------------------------------------------------
+// wild character routines
+//------------------------------------------------------------------------
+
+bool wxIsWild( const wxString& pattern )
+{
+  wxString tmp = pattern;
+  char *pat = WXSTRINGCAST(tmp);
+    while (*pat) {
+	switch (*pat++) {
+	case '?': case '*': case '[': case '{':
+	    return TRUE;
+	case '\\':
+	    if (!*pat++)
+		return FALSE;
+	}
+    }
+    return FALSE;
+};
+
+
+bool wxMatchWild( const wxString& pat, const wxString& text, bool dot_special )
+{
+  wxString tmp1 = pat;
+  char *pattern = WXSTRINGCAST(tmp1);
+  wxString tmp2 = text;
+  char *str = WXSTRINGCAST(tmp2);
+    char c;
+    char *cp;
+    bool done = FALSE, ret_code, ok;
+    // Below is for vi fans
+    const char OB = '{', CB = '}';
+
+    // dot_special means '.' only matches '.'
+    if (dot_special && *str == '.' && *pattern != *str)
+	return FALSE;
+
+    while ((*pattern != '\0') && (!done)
+    && (((*str=='\0')&&((*pattern==OB)||(*pattern=='*')))||(*str!='\0'))) {
+	switch (*pattern) {
+	case '\\':
+	    pattern++;
+	    if (*pattern != '\0')
+		pattern++;
+	    break;
+	case '*':
+	    pattern++;
+	    ret_code = FALSE;
+	    while ((*str!='\0')
+	    && (!(ret_code=wxMatchWild(pattern, str++, FALSE))))
+		/*loop*/;
+	    if (ret_code) {
+		while (*str != '\0')
+		    str++;
+		while (*pattern != '\0')
+		    pattern++;
+	    }
+	    break;
+	case '[':
+	    pattern++;
+	  repeat:
+	    if ((*pattern == '\0') || (*pattern == ']')) {
+		done = TRUE;
+		break;
+	    }
+	    if (*pattern == '\\') {
+		pattern++;
+		if (*pattern == '\0') {
+		    done = TRUE;
+		    break;
+		}
+	    }
+	    if (*(pattern + 1) == '-') {
+		c = *pattern;
+		pattern += 2;
+		if (*pattern == ']') {
+		    done = TRUE;
+		    break;
+		}
+		if (*pattern == '\\') {
+		    pattern++;
+		    if (*pattern == '\0') {
+			done = TRUE;
+			break;
+		    }
+		}
+		if ((*str < c) || (*str > *pattern)) {
+		    pattern++;
+		    goto repeat;
+		}
+	    } else if (*pattern != *str) {
+		pattern++;
+		goto repeat;
+	    }
+	    pattern++;
+	    while ((*pattern != ']') && (*pattern != '\0')) {
+		if ((*pattern == '\\') && (*(pattern + 1) != '\0'))
+		    pattern++;
+		pattern++;
+	    }
+	    if (*pattern != '\0') {
+		pattern++, str++;
+	    }
+	    break;
+	case '?':
+	    pattern++;
+	    str++;
+	    break;
+	case OB:
+	    pattern++;
+	    while ((*pattern != CB) && (*pattern != '\0')) {
+		cp = str;
+		ok = TRUE;
+		while (ok && (*cp != '\0') && (*pattern != '\0')
+		&&  (*pattern != ',') && (*pattern != CB)) {
+		    if (*pattern == '\\')
+			pattern++;
+		    ok = (*pattern++ == *cp++);
+		}
+		if (*pattern == '\0') {
+		    ok = FALSE;
+		    done = TRUE;
+		    break;
+		} else if (ok) {
+		    str = cp;
+		    while ((*pattern != CB) && (*pattern != '\0')) {
+			if (*++pattern == '\\') {
+			    if (*++pattern == CB)
+				pattern++;
+			}
+		    }
+		} else {
+		    while (*pattern!=CB && *pattern!=',' && *pattern!='\0') {
+			if (*++pattern == '\\') {
+                            if (*++pattern == CB || *pattern == ',')
+				pattern++;
+			}
+		    }
+		}
+		if (*pattern != '\0')
+		    pattern++;
+	    }
+	    break;
+	default:
+	    if (*str == *pattern) {
+		str++, pattern++;
+	    } else {
+		done = TRUE;
+	    }
+	}
+    }
+    while (*pattern == '*')
+	pattern++;
+    return ((*str == '\0') && (*pattern == '\0'));
+};
+
+//------------------------------------------------------------------------
+// subprocess routines
+//------------------------------------------------------------------------
+
+long wxExecute( char **argv, bool Async )
+{
+    if (*argv == NULL)
+	return FALSE;
+
+    /* fork the process */
+#if defined(sun) || defined(__ultrix) || defined(__bsdi__)
+    pid_t pid = vfork();
+#else
+    pid_t pid = fork();
+#endif
+    if (pid == -1) {
+	perror ("fork failed");
+	return FALSE;
+    } else if (pid == 0) {
+	/* child */
+#ifdef _AIX
+	execvp ((const char *)*argv, (const char **)argv);
+#else
+	execvp (*argv, argv);
+#endif
+	if (errno == ENOENT)
+	    wxError("command not found", *argv);
+	else
+	    perror (*argv);
+	wxError("could not execute", *argv);
+	_exit (-1);
+    }
+
+    // Code below is NOT really acceptable!
+    // One should NEVER use wait under X
+    // Ideas? A Sleep idle callback?
+    // WARNING: WARNING: WARNING: WARNING:
+    // The CODE BELOW IS BAD BAD BAD BAD!
+    if (Async) {
+	int status;
+/*
+	wxSleep(2);		// Give a little time
+*/
+#if !defined(DG) && \
+    !defined(__AIX__) && \
+    !defined(__xlC__) && \
+    !defined(__SVR4__) && \
+    !defined(__SUN__) && \
+    !defined(__ALPHA__) && \
+    !defined(__SGI__) && \
+    !defined(__HPUX__) && \
+    !defined(__SUNPRO_CC) && \
+    !defined(__FreeBSD__)
+        while (wait((union wait*)&status) != pid)
+#else
+	while (wait(&status) != pid)
+#endif
+      {};
+/*
+	    wxSleep(3);	// 3 sec?
+*/
+    };
+    return TRUE;
+};
+
+long wxExecute( const wxString& command, bool Async )
+{
+    if (command.IsNull() || command == "") return FALSE;
+
+    int argc = 0;
+    char *argv[127];
+    char tmp[1024];
+    const char *IFS = " \t\n";
+
+    strncpy (tmp, command, sizeof(tmp) / sizeof(char) - 1);
+    tmp[sizeof (tmp) / sizeof (char) - 1] = '\0';
+    argv[argc++] = strtok (tmp, IFS);
+    while ((argv[argc++] = strtok(NULL, IFS)) != NULL)
+	/* loop */ ;
+    return wxExecute(argv, Async);
+};
+
diff --git a/src/gtk1/utilsres.cpp b/src/gtk1/utilsres.cpp
new file mode 100644
index 0000000000..24e7904c26
--- /dev/null
+++ b/src/gtk1/utilsres.cpp
@@ -0,0 +1,332 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        utils.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+//#ifdef __GNUG__
+//#pragma implementation "utils.h"
+//#endif
+
+#include "wx/utils.h"
+#include "wx/string.h"
+#include "wx/list.h"
+
+#include <ctype.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef __SVR4__
+#include <sys/systeminfo.h>
+#endif
+
+#include "gdk/gdkx.h"        // GDK_DISPLAY
+#include "gdk/gdkprivate.h"  // gdk_progclass
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xresource.h>
+
+
+//-----------------------------------------------------------------------------
+// constants
+//-----------------------------------------------------------------------------
+
+// Yuck this is really BOTH site and platform dependent
+// so we should use some other strategy!
+#ifdef __SUN__
+    #define DEFAULT_XRESOURCE_DIR "/usr/openwin/lib/app-defaults"
+#else
+    #define DEFAULT_XRESOURCE_DIR "/usr/lib/X11/app-defaults"
+#endif
+
+//-----------------------------------------------------------------------------
+// glabal data (data.cpp)
+//-----------------------------------------------------------------------------
+
+extern wxList wxResourceCache;
+extern XrmDatabase wxResourceDatabase;
+
+//-----------------------------------------------------------------------------
+// utility functions for get/write resources
+//-----------------------------------------------------------------------------
+
+static char *GetResourcePath(char *buf, char *name, bool create)
+{
+    if (create && FileExists(name)) {
+	strcpy(buf, name);
+	return buf; // Exists so ...
+    }
+    if (*name == '/')
+	strcpy(buf, name);
+    else {
+	// Put in standard place for resource files if not absolute
+	strcpy(buf, DEFAULT_XRESOURCE_DIR);
+	strcat(buf, "/");
+	strcat(buf, FileNameFromPath(name));
+    }
+    if (create) {
+	// Touch the file to create it
+	FILE *fd = fopen(buf, "w");
+	if (fd) fclose(fd);
+    }
+    return buf;
+}
+
+// Read $HOME for what it says is home, if not
+// read $USER or $LOGNAME for user name else determine
+// the Real User, then determine the Real home dir.
+static char *GetIniFile(char *dest, const char *filename)
+{
+    char *home = NULL;
+    if (filename && wxIsAbsolutePath(filename)) 
+    {
+      strcpy(dest, filename);
+    } 
+    else
+    {
+      if ((home = wxGetUserHome(wxString())) != NULL) 
+      {
+	strcpy(dest, home);
+	if (dest[strlen(dest) - 1] != '/') strcat(dest, "/");
+	if (filename == NULL) 
+	{
+	  if ((filename = getenv("XENVIRONMENT")) == NULL) filename = ".Xdefaults";
+	} 
+	else 
+	  if (*filename != '.') strcat(dest, ".");
+	strcat(dest, filename);
+      }
+      else 
+      {
+        dest[0] = '\0';    
+      }
+    }
+    return dest;
+}
+
+static void wxXMergeDatabases(void)
+{
+    XrmDatabase homeDB, serverDB, applicationDB;
+    char filenamebuf[1024];
+
+    char *filename = &filenamebuf[0];
+    char *environment;
+    char *classname = gdk_progclass;               // Robert Roebling ??
+    char name[256];
+    (void)strcpy(name, "/usr/lib/X11/app-defaults/");
+    (void)strcat(name, classname ? classname : "wxWindows");
+
+    // Get application defaults file, if any 
+    if ((applicationDB = XrmGetFileDatabase(name)))
+	(void)XrmMergeDatabases(applicationDB, &wxResourceDatabase);
+
+    // Merge server defaults, created by xrdb, loaded as a property of the root
+    // window when the server initializes and loaded into the display
+    // structure on XOpenDisplay;
+    // if not defined, use .Xdefaults
+    if (XResourceManagerString(GDK_DISPLAY()) != NULL) {
+	serverDB = XrmGetStringDatabase(XResourceManagerString(GDK_DISPLAY()));
+    } else {
+	(void)GetIniFile(filename, NULL);
+	serverDB = XrmGetFileDatabase(filename);
+    }
+    if (serverDB)
+	XrmMergeDatabases(serverDB, &wxResourceDatabase);
+
+    // Open XENVIRONMENT file, or if not defined, the .Xdefaults,
+    // and merge into existing database
+
+    if ((environment = getenv("XENVIRONMENT")) == NULL) {
+	size_t len;
+	environment = GetIniFile(filename, NULL);
+	len = strlen(environment);
+#if !defined(SVR4) || defined(__sgi)
+	(void)gethostname(environment + len, 1024 - len);
+#else
+	(void)sysinfo(SI_HOSTNAME, environment + len, 1024 - len);
+#endif
+    }
+    if ((homeDB = XrmGetFileDatabase(environment)))
+	XrmMergeDatabases(homeDB, &wxResourceDatabase);
+}
+
+//-----------------------------------------------------------------------------
+// called on application exit
+//-----------------------------------------------------------------------------
+
+void wxFlushResources(void)
+{
+    char nameBuffer[512];
+
+    wxNode *node = wxResourceCache.First();
+    while (node) {
+	char *file = node->key.string;
+	// If file doesn't exist, create it first.
+	(void)GetResourcePath(nameBuffer, file, TRUE);
+
+	XrmDatabase database = (XrmDatabase)node->Data();
+	XrmPutFileDatabase(database, nameBuffer);
+	XrmDestroyDatabase(database);
+	wxNode *next = node->Next();
+	delete node;
+	node = next;
+    }
+}
+
+void wxDeleteResources(const char *file)
+{
+    char buffer[500];
+    (void)GetIniFile(buffer, file);
+
+    wxNode *node = wxResourceCache.Find(buffer);
+    if (node) {
+	XrmDatabase database = (XrmDatabase)node->Data();
+	XrmDestroyDatabase(database);
+	delete node;
+    }
+}
+
+//-----------------------------------------------------------------------------
+// resource functions
+//-----------------------------------------------------------------------------
+
+bool wxWriteResource(const wxString& section, const wxString& entry, const wxString& value, const wxString& file )
+{
+    char buffer[500];
+
+    if (!entry) return FALSE;
+
+    (void)GetIniFile(buffer, file);
+
+    XrmDatabase database;
+    wxNode *node = wxResourceCache.Find(buffer);
+    if (node)
+	database = (XrmDatabase)node->Data();
+    else {
+	database = XrmGetFileDatabase(buffer);
+	wxResourceCache.Append(buffer, (wxObject *)database);
+    }
+    char resName[300];
+    strcpy(resName, !section.IsNull() ? WXSTRINGCAST section : "wxWindows");
+    strcat(resName, ".");
+    strcat(resName, entry);
+    XrmPutStringResource(&database, resName, value);
+    return TRUE;
+};
+
+bool wxWriteResource(const wxString& section, const wxString& entry, float value, const wxString& file )
+{
+    char buf[50];
+    sprintf(buf, "%.4f", value);
+    return wxWriteResource(section, entry, buf, file);
+};
+
+bool wxWriteResource(const wxString& section, const wxString& entry, long value, const wxString& file )
+{
+    char buf[50];
+    sprintf(buf, "%ld", value);
+    return wxWriteResource(section, entry, buf, file);
+};
+
+bool wxWriteResource(const wxString& section, const wxString& entry, int value, const wxString& file )
+{
+    char buf[50];
+    sprintf(buf, "%d", value);
+    return wxWriteResource(section, entry, buf, file);
+};
+
+bool wxGetResource(const wxString& section, const wxString& entry, char **value, const wxString& file )
+{
+    if (!wxResourceDatabase)
+	wxXMergeDatabases();
+
+    XrmDatabase database;
+    if (file) {
+	char buffer[500];
+	// Is this right? Trying to get it to look in the user's
+	// home directory instead of current directory -- JACS
+	(void)GetIniFile(buffer, file);
+
+	wxNode *node = wxResourceCache.Find(buffer);
+	if (node)
+	    database = (XrmDatabase)node->Data();
+	else {
+	    database = XrmGetFileDatabase(buffer);
+	    wxResourceCache.Append(buffer, (wxObject *)database);
+	}
+    } else
+	database = wxResourceDatabase;
+
+    XrmValue xvalue;
+    char *str_type[20];
+    char buf[150];
+    strcpy(buf, section);
+    strcat(buf, ".");
+    strcat(buf, entry);
+
+    bool success = XrmGetResource(database, buf, "*", str_type, &xvalue);
+    // Try different combinations of upper/lower case, just in case...
+    if (!success) {
+	buf[0] = (isupper(buf[0]) ? tolower(buf[0]) : toupper(buf[0]));
+	success = XrmGetResource(database, buf, "*", str_type,	&xvalue);
+    }
+    if (success) {
+	if (*value)
+	    delete[] *value;
+	*value = new char[xvalue.size + 1];
+	strncpy(*value, xvalue.addr, (int)xvalue.size);
+	return TRUE;
+    }
+    return FALSE;
+};
+
+bool wxGetResource(const wxString& section, const wxString& entry, float *value, const wxString& file )
+{
+    char *s = NULL;
+    bool succ = wxGetResource(section, entry, &s, file);
+    if (succ) {
+	*value = (float)strtod(s, NULL);
+	delete[]s;
+	return TRUE;
+    } else
+	return FALSE;
+};
+
+bool wxGetResource(const wxString& section, const wxString& entry, long *value, const wxString& file )
+{
+    char *s = NULL;
+    bool succ = wxGetResource(section, entry, &s, file);
+    if (succ) {
+	*value = strtol(s, NULL, 10);
+	delete[]s;
+	return TRUE;
+    } else
+	return FALSE;
+};
+
+bool wxGetResource(const wxString& section, const wxString& entry, int *value, const wxString& file )
+{
+    char *s = NULL;
+    bool succ = wxGetResource(section, entry, &s, file);
+    if (succ) {
+	// Handle True, False here 
+	// True, Yes, Enables, Set or  Activated 
+	if (*s == 'T' || *s == 'Y' || *s == 'E' || *s == 'S' || *s == 'A')
+	    *value = TRUE;
+	// False, No, Disabled, Reset, Cleared, Deactivated
+	else if (*s == 'F' || *s == 'N' || *s == 'D' || *s == 'R' || *s == 'C')
+	    *value = FALSE;
+	// Handle as Integer
+	else
+	    *value = (int)strtol(s, NULL, 10);
+	delete[]s;
+	return TRUE;
+    } else
+	return FALSE;
+};
+
diff --git a/src/gtk1/verti.xbm b/src/gtk1/verti.xbm
new file mode 100644
index 0000000000..2dd9dc4c05
--- /dev/null
+++ b/src/gtk1/verti.xbm
@@ -0,0 +1,6 @@
+#define verti_width 15
+#define verti_height 15
+static char verti_bits[] = {
+   0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10,
+   0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10,
+   0x84, 0x10, 0x84, 0x10, 0x84, 0x10};
diff --git a/src/gtk1/win_gtk.c b/src/gtk1/win_gtk.c
new file mode 100644
index 0000000000..5f6245a891
--- /dev/null
+++ b/src/gtk1/win_gtk.c
@@ -0,0 +1,512 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        wx_gtk.h
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#include "wx/gtk/win_gtk.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+static void gtk_myfixed_class_init    (GtkMyFixedClass    *klass);
+static void gtk_myfixed_init          (GtkMyFixed         *myfixed);
+static void gtk_myfixed_map           (GtkWidget        *widget);
+static void gtk_myfixed_unmap         (GtkWidget        *widget);
+static void gtk_myfixed_realize       (GtkWidget        *widget);
+static void gtk_myfixed_size_request  (GtkWidget        *widget,
+				     GtkRequisition   *requisition);
+static void gtk_myfixed_size_allocate (GtkWidget        *widget,
+				     GtkAllocation    *allocation);
+static void gtk_myfixed_paint         (GtkWidget        *widget,
+				     GdkRectangle     *area);
+static void gtk_myfixed_draw          (GtkWidget        *widget,
+				     GdkRectangle     *area);
+static gint gtk_myfixed_expose        (GtkWidget        *widget,
+				     GdkEventExpose   *event);
+static void gtk_myfixed_add           (GtkContainer     *container,
+				     GtkWidget        *widget);
+static void gtk_myfixed_remove        (GtkContainer     *container,
+				     GtkWidget        *widget);
+static void gtk_myfixed_foreach       (GtkContainer     *container,
+				     GtkCallback      callback,
+				     gpointer         callback_data);
+
+
+static GtkContainerClass *parent_class = NULL;
+
+
+guint
+gtk_myfixed_get_type ()
+{
+  static guint myfixed_type = 0;
+
+  if (!myfixed_type)
+    {
+      GtkTypeInfo myfixed_info =
+      {
+	"GtkMyFixed",
+	sizeof (GtkMyFixed),
+	sizeof (GtkMyFixedClass),
+	(GtkClassInitFunc) gtk_myfixed_class_init,
+	(GtkObjectInitFunc) gtk_myfixed_init,
+	(GtkArgSetFunc) NULL,
+        (GtkArgGetFunc) NULL,
+      };
+
+      myfixed_type = gtk_type_unique (gtk_container_get_type (), &myfixed_info);
+    }
+
+  return myfixed_type;
+}
+
+static void
+gtk_myfixed_class_init (GtkMyFixedClass *klass)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+  GtkContainerClass *container_class;
+
+  object_class = (GtkObjectClass*) klass;
+  widget_class = (GtkWidgetClass*) klass;
+  container_class = (GtkContainerClass*) klass;
+
+  parent_class = gtk_type_class (gtk_container_get_type ());
+
+  widget_class->map = gtk_myfixed_map;
+  widget_class->unmap = gtk_myfixed_unmap;
+  widget_class->realize = gtk_myfixed_realize;
+  widget_class->size_request = gtk_myfixed_size_request;
+  widget_class->size_allocate = gtk_myfixed_size_allocate;
+  widget_class->draw = gtk_myfixed_draw;
+  widget_class->expose_event = gtk_myfixed_expose;
+
+  container_class->add = gtk_myfixed_add;
+  container_class->remove = gtk_myfixed_remove;
+  container_class->foreach = gtk_myfixed_foreach;
+}
+
+static void
+gtk_myfixed_init (GtkMyFixed *myfixed)
+{
+  GTK_WIDGET_UNSET_FLAGS (myfixed, GTK_NO_WINDOW);
+  GTK_WIDGET_SET_FLAGS (myfixed, GTK_BASIC);
+  
+  myfixed->children = NULL;
+}
+
+GtkWidget*
+gtk_myfixed_new ()
+{
+  GtkMyFixed *myfixed;
+
+  myfixed = gtk_type_new (gtk_myfixed_get_type ());
+  
+  myfixed->scroll_offset_x = 0;
+  myfixed->scroll_offset_y = 0;
+  
+  return GTK_WIDGET (myfixed);
+}
+
+void       
+gtk_myfixed_set_offset (GtkMyFixed     *myfixed,
+                        gint16         x,
+			gint16         y)
+{
+  GtkWidget *widget;
+ 
+  g_return_if_fail (myfixed != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED (myfixed));
+  
+  myfixed->scroll_offset_x = x;
+  myfixed->scroll_offset_y = y;
+  
+  widget = GTK_WIDGET( myfixed );
+  
+  if (GTK_WIDGET_REALIZED( GTK_WIDGET(myfixed) ))
+    gdk_window_move_resize (widget->window,
+			    widget->allocation.x + x, 
+			    widget->allocation.y + y,
+                            32000, 
+			    32000);
+}
+
+void
+gtk_myfixed_put (GtkMyFixed       *myfixed,
+               GtkWidget      *widget,
+               gint16         x,
+               gint16         y)
+{
+  GtkMyFixedChild *child_info;
+
+  g_return_if_fail (myfixed != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED (myfixed));
+  g_return_if_fail (widget != NULL);
+
+  child_info = g_new (GtkMyFixedChild, 1);
+  child_info->widget = widget;
+  child_info->x = x;
+  child_info->y = y;
+
+  gtk_widget_set_parent (widget, GTK_WIDGET (myfixed));
+
+  myfixed->children = g_list_append (myfixed->children, child_info); 
+
+  if (GTK_WIDGET_REALIZED (myfixed) && !GTK_WIDGET_REALIZED (widget))
+    gtk_widget_realize (widget);
+
+  if (GTK_WIDGET_MAPPED (myfixed) && !GTK_WIDGET_MAPPED (widget))
+    gtk_widget_map (widget);
+
+  if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (myfixed))
+    gtk_widget_queue_resize (GTK_WIDGET (myfixed));
+}
+
+void
+gtk_myfixed_move (GtkMyFixed       *myfixed,
+                GtkWidget      *widget,
+                gint16         x,
+                gint16         y)
+{
+  GtkMyFixedChild *child;
+  GList *children;
+
+  g_return_if_fail (myfixed != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED (myfixed));
+  g_return_if_fail (widget != NULL);
+
+  children = myfixed->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (child->widget == widget)
+        {
+          child->x = x;
+          child->y = y;
+
+          if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (myfixed))
+            gtk_widget_queue_resize (GTK_WIDGET (myfixed));
+
+          break;
+        }
+    }
+}
+
+static void
+gtk_myfixed_map (GtkWidget *widget)
+{
+  GtkMyFixed *myfixed;
+  GtkMyFixedChild *child;
+  GList *children;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
+  myfixed = GTK_MYFIXED (widget);
+
+  gdk_window_show (widget->window);
+
+  children = myfixed->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child->widget) &&
+	  !GTK_WIDGET_MAPPED (child->widget))
+	gtk_widget_map (child->widget);
+    }
+}
+
+static void
+gtk_myfixed_unmap (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED (widget));
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
+}
+
+static void
+gtk_myfixed_realize (GtkWidget *widget)
+{
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.x = widget->allocation.x;
+  attributes.y = widget->allocation.y;
+  attributes.width = 32000;
+  attributes.height = 32000;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+  attributes.event_mask = gtk_widget_get_events (widget);
+  attributes.event_mask |= 
+  GDK_EXPOSURE_MASK	|
+  GDK_POINTER_MOTION_MASK	|
+  GDK_BUTTON_MOTION_MASK	|
+  GDK_BUTTON1_MOTION_MASK	|
+  GDK_BUTTON2_MOTION_MASK	|
+  GDK_BUTTON3_MOTION_MASK	|
+  GDK_BUTTON_PRESS_MASK		|
+  GDK_BUTTON_RELEASE_MASK	|
+  GDK_KEY_PRESS_MASK		|
+  GDK_KEY_RELEASE_MASK		|
+  GDK_ENTER_NOTIFY_MASK		|
+  GDK_LEAVE_NOTIFY_MASK		|
+  GDK_FOCUS_CHANGE_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);
+    
+  widget->style = gtk_style_attach (widget->style, widget->window);
+  gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
+}
+
+static void
+gtk_myfixed_size_request (GtkWidget      *widget,
+			GtkRequisition *requisition)
+{
+  GtkMyFixed *myfixed;
+  GtkMyFixedChild *child;
+  GList *children;
+  
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED (widget));
+  g_return_if_fail (requisition != NULL);
+
+  myfixed = GTK_MYFIXED (widget);
+  
+  requisition->width = 0;
+  requisition->height = 0;
+
+  children = myfixed->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child->widget))
+	{
+          gtk_widget_size_request (child->widget, &child->widget->requisition);
+	}
+    }
+}
+
+static void
+gtk_myfixed_size_allocate (GtkWidget     *widget,
+			 GtkAllocation *allocation)
+{
+  GtkMyFixed *myfixed;
+  GtkMyFixedChild *child;
+  GtkAllocation child_allocation;
+  GList *children;
+  guint16 border_width;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED(widget));
+  g_return_if_fail (allocation != NULL);
+
+  myfixed = GTK_MYFIXED (widget);
+
+  widget->allocation = *allocation;
+  if (GTK_WIDGET_REALIZED (widget))
+    gdk_window_move_resize (widget->window,
+			    allocation->x + myfixed->scroll_offset_x, 
+			    allocation->y + myfixed->scroll_offset_y,
+			    32000, 
+			    32000
+			    );
+
+  border_width = GTK_CONTAINER (myfixed)->border_width;
+  
+  children = myfixed->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+      
+      if (GTK_WIDGET_VISIBLE (child->widget))
+	{
+	  child_allocation.x = child->x + border_width;
+	  child_allocation.y = child->y + border_width;
+	  child_allocation.width = child->widget->requisition.width;
+	  child_allocation.height = child->widget->requisition.height;
+	  gtk_widget_size_allocate (child->widget, &child_allocation);
+	}
+    }
+}
+
+static void
+gtk_myfixed_paint (GtkWidget    *widget,
+		 GdkRectangle *area)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+      gdk_window_clear_area (widget->window,
+			     area->x, area->y,
+			     area->width, area->height);
+}
+
+static void
+gtk_myfixed_draw (GtkWidget    *widget,
+		GdkRectangle *area)
+{
+  GtkMyFixed *myfixed;
+  GtkMyFixedChild *child;
+  GdkRectangle child_area;
+  GList *children;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED (widget));
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      myfixed = GTK_MYFIXED (widget);
+      gtk_myfixed_paint (widget, area);
+
+      children = myfixed->children;
+      while (children)
+	{
+	  child = children->data;
+	  children = children->next;
+
+	  if (gtk_widget_intersect (child->widget, area, &child_area))
+	    gtk_widget_draw (child->widget, &child_area);
+	}
+    }
+}
+
+static gint
+gtk_myfixed_expose (GtkWidget      *widget,
+		  GdkEventExpose *event)
+{
+  GtkMyFixed *myfixed;
+  GtkMyFixedChild *child;
+  GdkEventExpose child_event;
+  GList *children;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_MYFIXED (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      myfixed = GTK_MYFIXED (widget);
+
+      child_event = *event;
+
+      children = myfixed->children;
+      while (children)
+	{
+	  child = children->data;
+	  children = children->next;
+
+	  if (GTK_WIDGET_NO_WINDOW (child->widget) &&
+	      gtk_widget_intersect (child->widget, &event->area, 
+				    &child_event.area))
+	    gtk_widget_event (child->widget, (GdkEvent*) &child_event);
+	}
+    }
+
+  return FALSE;
+}
+
+static void
+gtk_myfixed_add (GtkContainer *container,
+	       GtkWidget    *widget)
+{
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED (container));
+  g_return_if_fail (widget != NULL);
+
+  gtk_myfixed_put (GTK_MYFIXED (container), widget, 0, 0);
+}
+
+static void
+gtk_myfixed_remove (GtkContainer *container,
+		  GtkWidget    *widget)
+{
+  GtkMyFixed *myfixed;
+  GtkMyFixedChild *child;
+  GList *children;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED (container));
+  g_return_if_fail (widget != NULL);
+
+  myfixed = GTK_MYFIXED (container);
+
+  children = myfixed->children;
+  while (children)
+    {
+      child = children->data;
+
+      if (child->widget == widget)
+	{
+	  gtk_widget_unparent (widget);
+
+	  myfixed->children = g_list_remove_link (myfixed->children, children);
+	  g_list_free (children);
+	  g_free (child);
+
+	  if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
+	    gtk_widget_queue_resize (GTK_WIDGET (container));
+
+	  break;
+	}
+
+      children = children->next;
+    }
+}
+
+static void
+gtk_myfixed_foreach (GtkContainer *container,
+		   GtkCallback   callback,
+		   gpointer      callback_data)
+{
+  GtkMyFixed *myfixed;
+  GtkMyFixedChild *child;
+  GList *children;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_MYFIXED (container));
+  g_return_if_fail (callback != NULL);
+
+  myfixed = GTK_MYFIXED (container);
+
+  children = myfixed->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      (* callback) (child->widget, callback_data);
+    }
+}
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
diff --git a/src/gtk1/window.cpp b/src/gtk1/window.cpp
new file mode 100644
index 0000000000..1811e8892b
--- /dev/null
+++ b/src/gtk1/window.cpp
@@ -0,0 +1,2386 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        window.cpp
+// Purpose:
+// Author:      Robert Roebling
+// Created:     01/02/97
+// Id:
+// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Licence:   	wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "window.h"
+#endif
+
+#include "wx/defs.h"
+#include "wx/window.h"
+#include "wx/dc.h"
+#include "wx/frame.h"
+#include "wx/app.h"
+#include "wx/layout.h"
+#include "wx/utils.h"
+#include "wx/dialog.h"
+#include "wx/msgdlg.h"
+#include "wx/dcclient.h"
+#include "wx/dnd.h"
+#include "wx/mdi.h"
+#include "gdk/gdkkeysyms.h"
+#include <math.h>
+#include "wx/gtk/win_gtk.h"
+#include "gdk/gdkprivate.h"
+
+//-----------------------------------------------------------------------------
+// data
+//-----------------------------------------------------------------------------
+
+extern wxList wxPendingDelete;
+extern wxList wxTopLevelWindows;
+extern bool   g_blockEventsOnDrag;
+
+//-----------------------------------------------------------------------------
+// GTK callbacks for wxWindows event system
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// expose (of m_wxwindow, not of m_widget)
+
+void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExpose *gdk_event, wxWindow *win )
+{ 
+  if (!win->HasVMT()) return;
+  if (g_blockEventsOnDrag) return;
+  
+/*
+  printf( "OnExpose from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+  
+  printf( "x: %d \n", gdk_event->area.x );
+  printf( "y: %d \n", gdk_event->area.y );
+  printf( "w: %d \n", gdk_event->area.width );
+  printf( "h: %d \n", gdk_event->area.height );
+*/
+
+  win->m_updateRegion.Union( gdk_event->area.x,
+                             gdk_event->area.y,
+			     gdk_event->area.width,
+			     gdk_event->area.height );
+			     
+  if (gdk_event->count > 0) return;
+
+  wxPaintEvent event( win->GetId() );
+  event.SetEventObject( win );
+  win->ProcessEvent( event );
+  
+  win->m_updateRegion.Clear();
+};
+
+//-----------------------------------------------------------------------------
+// draw (of m_wxwindow, not of m_widget)
+
+void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget), GdkRectangle *rect, wxWindow *win )
+{ 
+  if (!win->HasVMT()) return;
+  if (g_blockEventsOnDrag) return;
+  
+/*
+  printf( "OnDraw from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+  
+  printf( "x: %d \n", rect->x );
+  printf( "y: %d \n", rect->y );
+  printf( "w: %d \n", rect->width );
+  printf( "h: %d \n", rect->height );
+*/
+
+  win->m_updateRegion.Union( rect->x, rect->y, rect->width, rect->height );
+			     
+  wxPaintEvent event( win->GetId() );
+  event.SetEventObject( win );
+  win->ProcessEvent( event );
+  
+  win->m_updateRegion.Clear();
+};
+
+//-----------------------------------------------------------------------------
+// size 
+//      I don't any longer intercept GTK's internal resize events (except frames)
+
+/*
+void gtk_window_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxWindow *win )
+{ 
+  if (!win->HasVMT()) return;
+  if (g_blockEventsOnDrag) return;
+  
+  return;
+
+  if ((win->m_x == alloc->x) &&
+      (win->m_y == alloc->y) &&
+      (win->m_width == alloc->width) &&
+      (win->m_height == alloc->height))
+  {
+    return;
+  };
+  
+  printf( "OnResize from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( " .\n" );
+    
+  printf( "  Old: X: %d  Y: %d ", win->m_x, win->m_y );
+  printf( "  W: %d  H: %d ", win->m_width, win->m_height );
+  printf( " .\n" );
+    
+  printf( "  New: X: %d  Y: %d ", alloc->x, alloc->y );
+  printf( "  W: %d  H: %d ", alloc->width, alloc->height );
+  printf( " .\n" );
+  
+  wxSizeEvent event( wxSize( alloc->width, alloc->height), win->GetId() );
+  event.SetEventObject( win );
+  win->ProcessEvent( event );
+};
+*/
+
+//-----------------------------------------------------------------------------
+// key_press
+
+gint gtk_window_key_press_callback( GtkWidget *WXUNUSED(widget), GdkEventKey *gdk_event, wxWindow *win )
+{ 
+  if (!win->HasVMT()) return FALSE;
+  if (g_blockEventsOnDrag) return FALSE;
+
+/*
+  printf( "OnKeyPress from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+
+  long key_code = 0;
+  switch (gdk_event->keyval)
+  {
+    case GDK_BackSpace:   key_code = WXK_BACK;     	break;
+    case GDK_Tab:         key_code = WXK_TAB;     	break;
+    case GDK_Linefeed:    key_code = WXK_RETURN;  	break;
+    case GDK_Clear:	  key_code = WXK_CLEAR;   	break;
+    case GDK_Return:	  key_code = WXK_RETURN;  	break;
+    case GDK_Pause:	  key_code = WXK_PAUSE;   	break;
+    case GDK_Scroll_Lock: key_code = WXK_SCROLL; 	break;
+    case GDK_Escape:	  key_code = WXK_ESCAPE;  	break;
+    case GDK_Delete:	  key_code = WXK_DELETE;  	break;
+    case GDK_Home: 	  key_code = WXK_HOME;    	break;
+    case GDK_Left:	  key_code = WXK_LEFT;    	break;
+    case GDK_Up:	  key_code = WXK_UP;      	break;
+    case GDK_Right:	  key_code = WXK_RIGHT;   	break;
+    case GDK_Down:	  key_code = WXK_DOWN;    	break;
+    case GDK_Prior:	  key_code = WXK_PRIOR;   	break;
+//  case GDK_Page_Up:	  key_code = WXK_PAGEUP;  	break;
+    case GDK_Next:	  key_code = WXK_NEXT;    	break;
+//  case GDK_Page_Down:   key_code = WXK_PAGEDOWN; 	break;
+    case GDK_End:	  key_code = WXK_END;     	break;
+    case GDK_Begin:	  key_code = WXK_HOME;    	break;
+    case GDK_Select:	  key_code = WXK_SELECT;  	break;
+    case GDK_Print:	  key_code = WXK_PRINT;   	break;
+    case GDK_Execute:	  key_code = WXK_EXECUTE; 	break;
+    case GDK_Insert:	  key_code = WXK_INSERT;  	break;
+    case GDK_Num_Lock:	  key_code = WXK_NUMLOCK; 	break;
+    case GDK_KP_Tab:	  key_code = WXK_TAB;     	break;
+    case GDK_KP_Enter:	  key_code = WXK_RETURN;  	break;
+    case GDK_KP_Home:	  key_code = WXK_HOME;    	break;
+    case GDK_KP_Left:	  key_code = WXK_LEFT;    	break;
+    case GDK_KP_Up:	  key_code = WXK_UP;      	break;
+    case GDK_KP_Right: 	  key_code = WXK_RIGHT;   	break;
+    case GDK_KP_Down:	  key_code = WXK_DOWN;    	break;
+    case GDK_KP_Prior:	  key_code = WXK_PRIOR;   	break;
+//  case GDK_KP_Page_Up:  key_code = WXK_PAGEUP; 	break;
+    case GDK_KP_Next:	  key_code = WXK_NEXT;    	break;
+//  case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; 	break;
+    case GDK_KP_End:	  key_code = WXK_END;     	break;
+    case GDK_KP_Begin:	  key_code = WXK_HOME;    	break;
+    case GDK_KP_Insert:	  key_code = WXK_INSERT;  	break;
+    case GDK_KP_Delete:	  key_code = WXK_DELETE;  	break;
+    case GDK_KP_Multiply: key_code = WXK_MULTIPLY; 	break;
+    case GDK_KP_Add:	  key_code = WXK_ADD;     	break;
+    case GDK_KP_Separator: key_code = WXK_SEPARATOR; 	break;
+    case GDK_KP_Subtract: key_code = WXK_SUBTRACT; 	break;
+    case GDK_KP_Decimal:  key_code = WXK_DECIMAL; 	break;
+    case GDK_KP_Divide:	  key_code = WXK_DIVIDE;  	break;
+    case GDK_KP_0:	  key_code = WXK_NUMPAD0; 	break;
+    case GDK_KP_1:	  key_code = WXK_NUMPAD1; 	break;
+    case GDK_KP_2:	  key_code = WXK_NUMPAD2; 	break;
+    case GDK_KP_3:	  key_code = WXK_NUMPAD3; 	break;
+    case GDK_KP_4:	  key_code = WXK_NUMPAD4; 	break;
+    case GDK_KP_5:	  key_code = WXK_NUMPAD5; 	break;
+    case GDK_KP_6:	  key_code = WXK_NUMPAD6; 	break;
+    case GDK_KP_7:	  key_code = WXK_NUMPAD7; 	break;
+    case GDK_KP_8:	  key_code = WXK_NUMPAD7; 	break;
+    case GDK_KP_9:	  key_code = WXK_NUMPAD9; 	break;
+    case GDK_F1:	  key_code = WXK_F1;		break;
+    case GDK_F2:	  key_code = WXK_F2;		break;
+    case GDK_F3:	  key_code = WXK_F3;		break;
+    case GDK_F4:	  key_code = WXK_F4;		break;
+    case GDK_F5:	  key_code = WXK_F5;		break;
+    case GDK_F6:	  key_code = WXK_F6;		break;
+    case GDK_F7:	  key_code = WXK_F7;		break;
+    case GDK_F8:	  key_code = WXK_F8;		break;
+    case GDK_F9:	  key_code = WXK_F9;		break;
+    case GDK_F10:	  key_code = WXK_F10;		break;
+    case GDK_F11:	  key_code = WXK_F11;		break;
+    case GDK_F12:	  key_code = WXK_F12;		break;
+    default:
+    {
+      if ((gdk_event->keyval >= 0x20) && (gdk_event->keyval <= 0xFF)) 
+        key_code = gdk_event->keyval;
+    };
+  };
+
+  if (!key_code) return FALSE;
+  
+  wxKeyEvent event( wxEVT_CHAR );
+  event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
+  event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
+  event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
+  event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
+  event.m_keyCode = key_code;
+  event.m_x = 0;
+  event.m_y = 0;
+  event.SetEventObject( win );
+  return win->ProcessEvent( event );
+};
+
+//-----------------------------------------------------------------------------
+// button_press
+
+gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxWindow *win )
+{ 
+  if (widget->window != gdk_event->window) return FALSE;
+  if (g_blockEventsOnDrag) return FALSE;
+
+  if (win->m_wxwindow)
+  {
+    if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow) && !GTK_WIDGET_HAS_FOCUS (win->m_wxwindow) )
+    {
+      gtk_widget_grab_focus (win->m_wxwindow);
+      
+/*
+      printf( "GrabFocus from " );
+      if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+        printf( win->GetClassInfo()->GetClassName() );
+      printf( ".\n" );
+*/
+      
+    };
+  };
+    
+  if (!win->HasVMT()) return FALSE;
+    
+/*
+  printf( "OnButtonPress from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  WXTYPE event_type = wxEVT_LEFT_DOWN;
+  
+  if (gdk_event->button == 1)
+  {
+    switch (gdk_event->type)
+    {
+      case GDK_BUTTON_PRESS: event_type = wxEVT_LEFT_DOWN; break;
+      case GDK_2BUTTON_PRESS: event_type = wxEVT_LEFT_DCLICK; break;
+      default:  break;
+    };
+  }
+  else if (gdk_event->button == 2)
+  {
+    switch (gdk_event->type)
+    {
+      case GDK_BUTTON_PRESS: event_type = wxEVT_MIDDLE_DOWN; break;
+      case GDK_2BUTTON_PRESS: event_type = wxEVT_MIDDLE_DCLICK; break;
+      default:  break;
+    };
+  }
+  else if (gdk_event->button == 3)
+  {
+    switch (gdk_event->type)
+    {
+      case GDK_BUTTON_PRESS: event_type = wxEVT_RIGHT_DOWN; break;
+      case GDK_2BUTTON_PRESS: event_type = wxEVT_RIGHT_DCLICK; break;
+      default:  break;
+    };
+  };
+  
+  wxMouseEvent event( event_type );
+  event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
+  event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
+  event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
+  event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
+  event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK);
+  event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK);
+  event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK);
+  
+  event.m_x = (long)gdk_event->x;
+  event.m_y = (long)gdk_event->y;
+  event.SetEventObject( win );
+  
+  win->ProcessEvent( event );
+  
+  return TRUE;
+};
+
+//-----------------------------------------------------------------------------
+// button_release
+
+gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxWindow *win )
+{ 
+  if (widget->window != gdk_event->window) return TRUE;
+
+  if (g_blockEventsOnDrag) return FALSE;
+
+  if (!win->HasVMT()) return FALSE;
+ 
+/*
+  printf( "OnButtonRelease from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  WXTYPE event_type = 0;
+  
+  switch (gdk_event->button)
+  {
+    case 1: event_type = wxEVT_LEFT_UP; break;
+    case 2: event_type = wxEVT_MIDDLE_UP; break;
+    case 3: event_type = wxEVT_RIGHT_UP; break;
+  };
+
+  wxMouseEvent event( event_type );
+  event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
+  event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
+  event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
+  event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
+  event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK);
+  event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK);
+  event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK);
+  event.m_x = (long)gdk_event->x;
+  event.m_y = (long)gdk_event->y;
+  event.SetEventObject( win );
+  
+  return win->ProcessEvent( event );
+};
+
+//-----------------------------------------------------------------------------
+// motion_notify
+
+gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event, wxWindow *win )
+{ 
+  if (widget->window != gdk_event->window) return TRUE;
+
+  if (g_blockEventsOnDrag) return FALSE;
+
+  if (!win->HasVMT()) return FALSE;
+  
+/*
+  printf( "OnMotion from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  wxMouseEvent event( wxEVT_MOTION );
+  event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
+  event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
+  event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
+  event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
+  event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK);
+  event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK);
+  event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK);
+  
+  event.m_x = (long)gdk_event->x;
+  event.m_y = (long)gdk_event->y;
+  event.SetEventObject( win );
+  
+  win->ProcessEvent( event );
+  
+  return FALSE;
+};
+
+//-----------------------------------------------------------------------------
+// focus_in
+
+void gtk_window_focus_in_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxWindow *win )
+{
+  if (g_blockEventsOnDrag) return;
+  if (win->m_wxwindow)
+  {
+    if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow))
+    {
+      GTK_WIDGET_SET_FLAGS (win->m_wxwindow, GTK_HAS_FOCUS);
+/*      
+      printf( "SetFocus flag from " );
+      if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+        printf( win->GetClassInfo()->GetClassName() );
+      printf( ".\n" );
+*/
+    };
+  };
+  
+  if (!win->HasVMT()) return;
+  
+/*
+  printf( "OnSetFocus from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( "   " );
+  printf( WXSTRINGCAST win->GetLabel() );
+  printf( ".\n" );
+*/
+  
+  wxFocusEvent event( wxEVT_SET_FOCUS, win->GetId() );
+  event.SetEventObject( win );
+  win->ProcessEvent( event );
+};
+
+//-----------------------------------------------------------------------------
+// focus out
+
+void gtk_window_focus_out_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxWindow *win )
+{
+  if (g_blockEventsOnDrag) return;
+  if (win->m_wxwindow)
+  {
+    if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow))
+      GTK_WIDGET_UNSET_FLAGS (win->m_wxwindow, GTK_HAS_FOCUS);
+  };
+  
+  if (!win->HasVMT()) return;
+  
+/*
+  printf( "OnKillFocus from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  wxFocusEvent event( wxEVT_KILL_FOCUS, win->GetId() );
+  event.SetEventObject( win );
+  win->ProcessEvent( event );
+};
+
+//-----------------------------------------------------------------------------
+// vertical scroll
+
+void gtk_window_vscroll_callback( GtkWidget *WXUNUSED(widget), wxWindow *win )
+{
+  if (g_blockEventsOnDrag) return;
+
+/*
+  printf( "OnVScroll from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  if (!win->HasVMT()) return;
+  
+  float diff = win->m_vAdjust->value - win->m_oldVerticalPos;
+  if (fabs(diff) < 0.2) return;
+  
+/*
+  int i = (int)(win->m_oldVerticalPos+0.5);
+  printf( "Old value: %d.\n", i );
+  i = (int)(win->m_vAdjust->value+0.5);
+  printf( "Sending new value: %d.\n", i );
+*/
+
+  int command = 0;
+  
+  float line_step = win->m_vAdjust->step_increment;
+  float page_step = win->m_vAdjust->page_increment;
+  
+  if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN;
+  else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP;
+  else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN;
+  else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP;
+  else command = wxEVT_SCROLL_THUMBTRACK;
+      
+  int value = (int)(win->m_vAdjust->value+0.5);
+
+  wxScrollEvent event( command, win->GetId(), value, wxVERTICAL );
+  event.SetEventObject( win );
+  win->ProcessEvent( event );
+};
+
+//-----------------------------------------------------------------------------
+// horizontal scroll
+
+void gtk_window_hscroll_callback( GtkWidget *WXUNUSED(widget), wxWindow *win )
+{ 
+  if (g_blockEventsOnDrag) return;
+  
+/*
+  printf( "OnHScroll from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  if (!win->HasVMT()) return;
+    
+  float diff = win->m_hAdjust->value - win->m_oldHorizontalPos;
+  if (fabs(diff) < 0.2) return;
+  
+/*
+  int i = (int)(win->m_oldHorizontalPos+0.5);
+  printf( "Old value: %d.\n", i );
+  i = (int)(win->m_hAdjust->value+0.5);
+  printf( "Sending new value: %d.\n", i );
+*/
+      
+  int command = 0;
+  
+  float line_step = win->m_hAdjust->step_increment;
+  float page_step = win->m_hAdjust->page_increment;
+  
+  if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN;
+  else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP;
+  else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN;
+  else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP;
+  else command = wxEVT_SCROLL_THUMBTRACK;
+
+  int value = (int)(win->m_hAdjust->value+0.5);
+      
+  wxScrollEvent event( command, win->GetId(), value, wxHORIZONTAL );
+  event.SetEventObject( win );
+  win->ProcessEvent( event );
+};
+
+//-----------------------------------------------------------------------------
+// vertical scroll change
+
+void gtk_window_vscroll_change_callback( GtkWidget *WXUNUSED(widget), wxWindow *win )
+{
+  if (g_blockEventsOnDrag) return;
+
+/*
+  printf( "OnVScroll change from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  if (!win->HasVMT()) return;
+  
+  int command = wxEVT_SCROLL_THUMBTRACK;
+  int value = (int)(win->m_vAdjust->value+0.5);
+
+  wxScrollEvent event( command, win->GetId(), value, wxVERTICAL );
+  event.SetEventObject( win );
+  win->ProcessEvent( event );
+};
+
+//-----------------------------------------------------------------------------
+// horizontal scroll change
+
+void gtk_window_hscroll_change_callback( GtkWidget *WXUNUSED(widget), wxWindow *win )
+{ 
+  if (g_blockEventsOnDrag) return;
+  
+/*
+  printf( "OnHScroll change from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+*/
+  
+  if (!win->HasVMT()) return;
+    
+  int command = wxEVT_SCROLL_THUMBTRACK;
+  int value = (int)(win->m_hAdjust->value+0.5);
+      
+  wxScrollEvent event( command, win->GetId(), value, wxHORIZONTAL );
+  event.SetEventObject( win );
+  win->ProcessEvent( event );
+};
+
+//-----------------------------------------------------------------------------
+// drop
+
+void gtk_window_drop_callback( GtkWidget *widget, GdkEvent *event, wxWindow *win )
+{
+  printf( "OnDrop.\n" );
+
+  if (win->GetDropTarget())
+  {
+    int x = 0;
+    int y = 0;
+    gdk_window_get_pointer( widget->window, &x, &y, NULL );
+    win->GetDropTarget()->Drop( event, x, y );
+  };
+  
+/*
+  g_free (event->dropdataavailable.data);
+  g_free (event->dropdataavailable.data_type);
+*/
+}
+
+//-----------------------------------------------------------------------------
+// destroy
+
+bool gtk_window_destroy_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxWindow *win )
+{ 
+  printf( "OnDestroy from " );
+  if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+    printf( win->GetClassInfo()->GetClassName() );
+  printf( ".\n" );
+  printf( "Goodbye.\n" );
+  printf( "     Robert Roebling.\n" );
+  
+  return FALSE;
+};
+
+//-----------------------------------------------------------------------------
+// enter
+
+bool gtk_window_enter_callback( GtkWidget *widget, GdkEvent *WXUNUSED(event), wxWindow *win )
+{
+  if (g_blockEventsOnDrag) return FALSE;
+  
+  if (widget->window)
+    gdk_window_set_cursor( widget->window, win->m_cursor->GetCursor() );
+    
+  return TRUE;
+};
+    
+//-----------------------------------------------------------------------------
+// leave
+
+bool gtk_window_leave_callback( GtkWidget *widget, GdkEvent *WXUNUSED(event), wxWindow *WXUNUSED(win) )
+{
+  if (g_blockEventsOnDrag) return FALSE;
+  
+  if (widget->window)
+    gdk_window_set_cursor( widget->window, wxSTANDARD_CURSOR->GetCursor() );
+    
+  return TRUE;
+};
+    
+//-----------------------------------------------------------------------------
+// wxWindow implementation
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxWindow,wxEvtHandler)
+
+BEGIN_EVENT_TABLE(wxWindow, wxEvtHandler)
+//  EVT_CHAR(wxWindow::OnChar)
+  EVT_SIZE(wxWindow::OnSize)
+//  EVT_ERASE_BACKGROUND(wxWindow::OnEraseBackground)
+  EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged)
+  EVT_INIT_DIALOG(wxWindow::OnInitDialog)
+//  EVT_IDLE(wxWindow::OnIdle)
+END_EVENT_TABLE()
+
+wxWindow::wxWindow()
+{
+  m_widget = NULL;
+  m_wxwindow = NULL;
+  m_parent = NULL;
+  m_children.DeleteContents( FALSE );
+  m_x = 0;
+  m_y = 0;
+  m_width = 0;
+  m_height = 0;
+  m_retCode = 0;
+  m_eventHandler = this;
+  m_windowValidator = NULL;
+  m_windowId = -1;
+  m_cursor = new wxCursor( wxCURSOR_ARROW );
+  m_font = *wxSWISS_FONT;
+  m_windowStyle = 0;
+  m_windowName = "noname";
+  m_constraints = NULL;
+  m_constraintsInvolvedIn = NULL;
+  m_windowSizer = NULL;
+  m_sizerParent = NULL;
+  m_autoLayout = FALSE;
+  m_sizeSet = FALSE;
+  m_hasVMT = FALSE;
+  m_needParent = TRUE;
+  m_hasScrolling = FALSE;
+  m_hAdjust = NULL;
+  m_vAdjust = NULL;
+  m_oldHorizontalPos = 0.0;
+  m_oldVerticalPos = 0.0;
+  m_isShown = FALSE;
+  m_isEnabled = TRUE;
+  m_drawingOffsetX = 0;
+  m_drawingOffsetY = 0;
+  m_pDropTarget = NULL;
+};
+
+wxWindow::wxWindow( wxWindow *parent, const wxWindowID id,
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  Create( parent, id, pos, size, style, name );
+};
+
+bool wxWindow::Create( wxWindow *parent, const wxWindowID id,
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  m_isShown = FALSE;
+  m_isEnabled = TRUE;
+  m_needParent = TRUE;
+  
+  PreCreation( parent, id, pos, size, style, name );
+  
+  m_widget = gtk_scrolled_window_new( NULL, NULL );
+  m_hasScrolling = TRUE;
+  
+  GtkScrolledWindow *s_window;
+  s_window = GTK_SCROLLED_WINDOW(m_widget);
+  
+  GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
+  scroll_class->scrollbar_spacing = 0;
+  
+  gtk_scrolled_window_set_policy( s_window, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
+    
+  m_oldHorizontalPos = 0.0;
+  m_oldVerticalPos = 0.0;
+ 
+  m_hAdjust = gtk_range_get_adjustment( GTK_RANGE(s_window->hscrollbar) );
+  m_vAdjust = gtk_range_get_adjustment( GTK_RANGE(s_window->vscrollbar) );
+  
+  gtk_signal_connect (GTK_OBJECT (m_hAdjust), "value_changed",
+		      (GtkSignalFunc) gtk_window_hscroll_callback, (gpointer) this );
+  gtk_signal_connect (GTK_OBJECT (m_vAdjust), "value_changed",
+		      (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this );
+		      
+  gtk_signal_connect (GTK_OBJECT (m_hAdjust), "changed",
+		      (GtkSignalFunc) gtk_window_hscroll_change_callback, (gpointer) this );
+  gtk_signal_connect (GTK_OBJECT (m_vAdjust), "changed",
+		      (GtkSignalFunc) gtk_window_vscroll_change_callback, (gpointer) this );
+  
+  GtkViewport *viewport;
+  viewport = GTK_VIEWPORT(s_window->viewport);
+  
+  if (m_windowStyle & wxRAISED_BORDER)
+  {
+    gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_OUT );
+  }
+  else if (m_windowStyle & wxSUNKEN_BORDER)
+  {
+    gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_IN );
+  }
+  else
+  {
+    gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_NONE );
+  };
+    
+  m_wxwindow = gtk_myfixed_new();
+  
+  if (m_windowStyle & wxTAB_TRAVERSAL == wxTAB_TRAVERSAL)
+    GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
+  else
+    GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
+
+  gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow );
+
+  // shut the viewport up
+  gtk_viewport_set_hadjustment( viewport, (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
+  gtk_viewport_set_vadjustment( viewport, (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
+  
+  // I _really_ don't want scrollbars in the beginning    
+  m_vAdjust->lower = 0.0;
+  m_vAdjust->upper = 1.0;
+  m_vAdjust->value = 0.0;
+  m_vAdjust->step_increment = 1.0;
+  m_vAdjust->page_increment = 1.0;
+  m_vAdjust->page_size = 5.0;
+  gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" );
+  m_hAdjust->lower = 0.0;
+  m_hAdjust->upper = 1.0;
+  m_hAdjust->value = 0.0;
+  m_hAdjust->step_increment = 1.0;
+  m_hAdjust->page_increment = 1.0;
+  m_hAdjust->page_size = 5.0;
+  gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" );
+  
+  gtk_widget_show( m_wxwindow );
+  
+  PostCreation();
+  
+  Show( TRUE );
+
+  return TRUE;  
+};
+
+wxWindow::~wxWindow(void)
+{
+  m_hasVMT = FALSE;
+  
+  if (m_pDropTarget) delete m_pDropTarget;
+  
+  if (m_parent) m_parent->RemoveChild( this );
+  if (m_widget) Show( FALSE );
+
+  DestroyChildren();
+  
+  if (m_wxwindow) gtk_widget_destroy( m_wxwindow );
+    
+  if (m_widget) gtk_widget_destroy( m_widget );
+  
+//  delete m_cursor;
+
+  DeleteRelatedConstraints();
+  if (m_constraints)
+  {
+    // This removes any dangling pointers to this window
+    // in other windows' constraintsInvolvedIn lists.
+    UnsetConstraints(m_constraints);
+    delete m_constraints;
+    m_constraints = NULL;
+  }
+  if (m_windowSizer)
+  {
+    delete m_windowSizer;
+    m_windowSizer = NULL;
+  }
+  // If this is a child of a sizer, remove self from parent
+  if (m_sizerParent)
+    m_sizerParent->RemoveChild((wxWindow *)this);
+
+  // Just in case the window has been Closed, but
+  // we're then deleting immediately: don't leave
+  // dangling pointers.
+  wxPendingDelete.DeleteObject(this);
+
+  // Just in case we've loaded a top-level window via
+  // wxWindow::LoadNativeDialog but we weren't a dialog
+  // class
+  wxTopLevelWindows.DeleteObject(this);
+    
+};
+
+void wxWindow::PreCreation( wxWindow *parent, const wxWindowID id,
+      const wxPoint &pos, const wxSize &size, 
+      const long style, const wxString &name )
+{
+  if (m_needParent && (parent == NULL))
+    wxFatalError( "Need complete parent.", name );
+
+  m_widget = NULL;
+  m_hasVMT = FALSE;
+  m_parent = parent;
+  m_children.DeleteContents( FALSE );
+  m_x = (int)pos.x;
+  m_y = (int)pos.y;
+  m_width = size.x;
+  if (m_width == -1) m_width = 20;
+  m_height = size.y;
+  if (m_height == -1) m_height = 20;
+  m_retCode = 0;
+  m_eventHandler = this;
+  m_windowValidator = NULL;
+  m_windowId = id;
+  m_sizeSet = FALSE;
+  m_cursor = new wxCursor( wxCURSOR_ARROW );
+  m_font = *wxSWISS_FONT;
+  m_backgroundColour = wxWHITE;
+  m_foregroundColour = wxBLACK;
+  m_windowStyle = style;
+  m_windowName = name;
+  m_constraints = NULL;
+  m_constraintsInvolvedIn = NULL;
+  m_windowSizer = NULL;
+  m_sizerParent = NULL;
+  m_autoLayout = FALSE;
+  m_drawingOffsetX = 0;
+  m_drawingOffsetY = 0;
+  m_pDropTarget = NULL;
+}
+
+void wxWindow::PostCreation(void)
+{
+  if (m_parent) m_parent->AddChild( this );
+  
+//  GtkStyle *style = m_widget->style;
+//  style->font = m_font.GetInternalFont( 1.0 );          // destroy old font ?
+  
+  GtkWidget *connect_widget = m_widget;
+  if (m_wxwindow) connect_widget = m_wxwindow;
+ 
+  gtk_object_set_data (GTK_OBJECT (connect_widget), "MyWxWindow", (gpointer)this );
+  
+  if (m_wxwindow)
+  {
+    gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event", 
+      GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this );
+      
+    gtk_signal_connect( GTK_OBJECT(m_wxwindow), "draw", 
+      GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this );
+  };
+  
+/*
+  gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate", 
+    GTK_SIGNAL_FUNC(gtk_window_size_callback), (gpointer)this );
+*/
+
+  gtk_signal_connect( GTK_OBJECT(connect_widget), "key_press_event",
+    GTK_SIGNAL_FUNC(gtk_window_key_press_callback), (gpointer)this );
+
+  gtk_signal_connect( GTK_OBJECT(connect_widget), "button_press_event",
+    GTK_SIGNAL_FUNC(gtk_window_button_press_callback), (gpointer)this );
+    
+  gtk_signal_connect( GTK_OBJECT(connect_widget), "button_release_event",
+    GTK_SIGNAL_FUNC(gtk_window_button_release_callback), (gpointer)this );
+    
+  gtk_signal_connect( GTK_OBJECT(connect_widget), "motion_notify_event",
+    GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback), (gpointer)this );
+    
+  gtk_signal_connect( GTK_OBJECT(connect_widget), "focus_in_event", 
+    GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this );
+
+  gtk_signal_connect( GTK_OBJECT(connect_widget), "focus_out_event", 
+    GTK_SIGNAL_FUNC(gtk_window_focus_out_callback), (gpointer)this );
+
+  gtk_signal_connect( GTK_OBJECT(connect_widget), "drop_data_available_event",
+    GTK_SIGNAL_FUNC(gtk_window_drop_callback), (gpointer)this );
+      
+  // Only for cursor handling
+    
+  gtk_signal_connect( GTK_OBJECT(m_widget), "enter_notify_event", 
+    GTK_SIGNAL_FUNC(gtk_window_enter_callback), (gpointer)this );
+    
+  gtk_signal_connect( GTK_OBJECT(m_widget), "leave_notify_event", 
+    GTK_SIGNAL_FUNC(gtk_window_leave_callback), (gpointer)this );
+    
+  if (m_wxwindow)
+  {
+    gtk_signal_connect( GTK_OBJECT(m_wxwindow), "enter_notify_event", 
+      GTK_SIGNAL_FUNC(gtk_window_enter_callback), (gpointer)this );
+      
+    gtk_signal_connect( GTK_OBJECT(m_wxwindow), "leave_notify_event", 
+      GTK_SIGNAL_FUNC(gtk_window_leave_callback), (gpointer)this );
+  };
+  
+/*
+  // Does destroy ever get called ?
+
+  gtk_signal_connect( GTK_OBJECT(m_widget), "destroy_event", 
+    GTK_SIGNAL_FUNC(gtk_window_destroy_callback), (gpointer)this );
+    
+  if (m_wxwindow)
+  {
+    gtk_signal_connect( GTK_OBJECT(m_wxwindow), "destroy_event", 
+      GTK_SIGNAL_FUNC(gtk_window_destroy_callback), (gpointer)this );
+  };
+*/
+  
+  if (m_widget && m_parent) gtk_widget_realize( m_widget );
+  if (m_wxwindow) gtk_widget_realize( m_wxwindow );
+  
+  SetCursor( wxSTANDARD_CURSOR );
+  
+  m_hasVMT = TRUE;
+};
+
+bool wxWindow::HasVMT(void)
+{
+  return m_hasVMT;
+};
+
+bool wxWindow::Close( const bool force )
+{
+  wxCloseEvent event(wxEVT_CLOSE_WINDOW, m_windowId);
+  event.SetEventObject(this);
+  event.SetForce(force);
+
+  return GetEventHandler()->ProcessEvent(event);
+};
+
+bool wxWindow::Destroy(void)
+{
+  m_hasVMT = FALSE;
+  delete this;
+  return TRUE;
+};
+
+bool wxWindow::DestroyChildren(void)
+{
+  if (GetChildren()) 
+  {
+    wxNode *node;
+    while ((node = GetChildren()->First()) != (wxNode *)NULL) 
+    {
+      wxWindow *child;
+      if ((child = (wxWindow *)node->Data()) != (wxWindow *)NULL) 
+      {
+        delete child;
+	if (GetChildren()->Member(child)) delete node;
+      };
+    };
+  };
+  return TRUE;
+};
+
+void wxWindow::PrepareDC( wxDC &WXUNUSED(dc) )
+{
+  // are we to set fonts here ?
+};
+
+void wxWindow::ImplementSetSize(void)
+{ 
+  gtk_widget_set_usize( m_widget, m_width, m_height );
+};
+
+void wxWindow::ImplementSetPosition(void)
+{
+  if ((m_parent) && (m_parent->m_wxwindow))
+    gtk_myfixed_move( GTK_MYFIXED(m_parent->m_wxwindow), m_widget, m_x, m_y );
+  else
+    gtk_widget_set_uposition( m_widget, m_x, m_y );
+};
+
+void wxWindow::SetSize( const int x, const int y, const int width, const int height, const int sizeFlags )
+{
+  int newX = x;
+  int newY = y;
+  int newW = width;
+  int newH = height;
+  
+  if ((sizeFlags & wxSIZE_USE_EXISTING) == wxSIZE_USE_EXISTING)
+  {
+    if (newX == -1) newX = m_x;
+    if (newY == -1) newY = m_y;
+    if (newW == -1) newW = m_width;
+    if (newH == -1) newH = m_height;
+  };
+  
+  if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
+  {
+    if (newW == -1) newW = 80;
+  };
+  
+  if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
+  {
+    if (newH == -1) newH = 26;
+  };
+  
+  if ((m_x != newX) || (m_y != newY) || (!m_sizeSet))
+  {
+    m_x = newX;
+    m_y = newY;
+    ImplementSetPosition();
+  };
+  if ((m_width != newW) || (m_height != newH) || (!m_sizeSet))
+  {
+    m_width = newW;
+    m_height = newH;
+    ImplementSetSize();
+  };
+  m_sizeSet = TRUE;
+  
+  wxSizeEvent event( wxSize(m_width,m_height), GetId() );
+  event.SetEventObject( this );
+  ProcessEvent( event );
+};
+
+void wxWindow::SetSize( const int width, const int height )
+{
+  SetSize( -1, -1, width, height, wxSIZE_USE_EXISTING );
+};
+
+void wxWindow::Move( const int x, const int y )
+{
+  SetSize( x, y, -1, -1, wxSIZE_USE_EXISTING );
+};
+
+void wxWindow::GetSize( int *width, int *height ) const
+{
+  (*width) = m_width;
+  (*height) = m_height;
+};
+
+void wxWindow::SetClientSize( const int width, const int height )
+{
+  if (!m_wxwindow)
+  {
+    SetSize( width, height );
+  }
+  else
+  {
+    int dw = 0;
+    int dh = 0;
+    
+    if (!m_hasScrolling)
+    {
+/*
+      do we have sunken dialogs ?
+      
+      GtkStyleClass *window_class = m_wxwindow->style->klass;
+    
+      dw += 2 * window_class->xthickness;
+      dh += 2 * window_class->ythickness;
+*/
+    }
+    else
+    {
+      GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
+      GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
+    
+      GtkWidget *viewport = scroll_window->viewport;
+      GtkStyleClass *viewport_class = viewport->style->klass;
+    
+      GtkWidget *hscrollbar = scroll_window->hscrollbar;
+      GtkWidget *vscrollbar = scroll_window->vscrollbar;
+    
+      if ((m_windowStyle & wxRAISED_BORDER) ||
+          (m_windowStyle & wxSUNKEN_BORDER)
+	 )
+      {
+        dw += 2 * viewport_class->xthickness;
+        dh += 2 * viewport_class->ythickness;
+      };
+    
+      if (GTK_WIDGET_VISIBLE(vscrollbar))
+      {
+        dw += vscrollbar->allocation.width;
+        dw += scroll_class->scrollbar_spacing;
+      };
+    
+      if (GTK_WIDGET_VISIBLE(hscrollbar))
+      {
+        dh += hscrollbar->allocation.height;
+        dw += scroll_class->scrollbar_spacing;
+      };
+    };
+    
+    SetSize( width+dw, height+dh );
+  };
+};
+
+void wxWindow::GetClientSize( int *width, int *height ) const
+{
+  if (!m_wxwindow)
+  {
+    if (width) (*width) = m_width;
+    if (height) (*height) = m_height;
+  }
+  else
+  {
+    int dw = 0;
+    int dh = 0;
+    
+    if (!m_hasScrolling)
+    {
+/*
+      do we have sunken dialogs ?
+      
+      GtkStyleClass *window_class = m_wxwindow->style->klass;
+    
+      dw += 2 * window_class->xthickness;
+      dh += 2 * window_class->ythickness;
+*/
+    }
+    else
+    {
+      GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
+      GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
+    
+      GtkWidget *viewport = scroll_window->viewport;
+      GtkStyleClass *viewport_class = viewport->style->klass;
+    
+      GtkWidget *hscrollbar = scroll_window->hscrollbar;
+      GtkWidget *vscrollbar = scroll_window->vscrollbar;
+    
+      if ((m_windowStyle & wxRAISED_BORDER) ||
+          (m_windowStyle & wxSUNKEN_BORDER)
+	 )
+      {
+        dw += 2 * viewport_class->xthickness;
+        dh += 2 * viewport_class->ythickness;
+      };
+    
+      if (GTK_WIDGET_VISIBLE(vscrollbar))
+      {
+//        dw += vscrollbar->allocation.width;
+        dw += 15;                               // range.slider_width = 11 + 2*2pts edge
+        dw += scroll_class->scrollbar_spacing;
+      };
+    
+      if (GTK_WIDGET_VISIBLE(hscrollbar))
+      {
+//        dh += hscrollbar->allocation.height;
+        dh += 15;
+        dh += scroll_class->scrollbar_spacing;
+      };
+    };
+    
+    if (width) (*width) = m_width - dw;
+    if (height) (*height) = m_height - dh;
+  };
+};
+
+void wxWindow::GetPosition( int *x, int *y ) const
+{
+  if (x) (*x) = m_x;
+  if (y) (*y) = m_y;
+};
+
+void wxWindow::ClientToScreen( int *x, int *y )
+{
+  // Does this look simple ?
+
+  GdkWindow *source = NULL;
+  if (m_wxwindow)
+    source = m_wxwindow->window;
+  else
+    source = m_widget->window;
+    
+  int org_x = 0;
+  int org_y = 0;
+  gdk_window_get_origin( source, &org_x, &org_y );
+
+  if (!m_wxwindow)
+  {  
+    if (GTK_WIDGET_NO_WINDOW (m_widget))
+    {
+      org_x += m_widget->allocation.x;
+      org_y += m_widget->allocation.y;
+    };
+  };
+  
+  if (x) *x += org_x;  
+  if (y) *y += org_y;  
+};
+
+void wxWindow::ScreenToClient( int *x, int *y )
+{
+  GdkWindow *source = NULL;
+  if (m_wxwindow)
+    source = m_wxwindow->window;
+  else
+    source = m_widget->window;
+    
+  int org_x = 0;
+  int org_y = 0;
+  gdk_window_get_origin( source, &org_x, &org_y );
+
+  if (!m_wxwindow)
+  {  
+    if (GTK_WIDGET_NO_WINDOW (m_widget))
+    {
+      org_x += m_widget->allocation.x;
+      org_y += m_widget->allocation.y;
+    };
+  };
+  
+  if (x) *x -= org_x;  
+  if (y) *y -= org_y;  
+};
+
+void wxWindow::Centre( const int direction )
+{
+  int x = 0;
+  int y = 0;
+  GetPosition( &x, &y );
+  if (this->IsKindOf(CLASSINFO(wxDialog)) || this->IsKindOf(CLASSINFO(wxFrame)))
+  {
+    if (direction & wxHORIZONTAL == wxHORIZONTAL) x = (gdk_screen_width () - m_width) / 2;
+    if (direction & wxVERTICAL == wxVERTICAL) y = (gdk_screen_height () - m_height) / 2;
+    gtk_widget_set_uposition( m_widget, x, y );
+  }
+  else
+  {
+    if (m_parent)
+    {
+      int p_w = 0;
+      int p_h = 0;
+      m_parent->GetSize( &p_w, &p_h );
+      if (direction & wxHORIZONTAL == wxHORIZONTAL) x = (p_w - m_width) / 2;
+      if (direction & wxVERTICAL == wxVERTICAL) y = (p_h - m_height) / 2;
+      gtk_widget_set_uposition( m_widget, x, y );
+    };
+  }
+};
+
+void wxWindow::Fit(void)
+{
+	int maxX = 0;
+	int maxY = 0;
+	wxNode *node = GetChildren()->First();
+	while ( node )
+	{
+		wxWindow *win = (wxWindow *)node->Data();
+		int wx, wy, ww, wh;
+		win->GetPosition(&wx, &wy);
+		win->GetSize(&ww, &wh);
+		if ( wx + ww > maxX )
+			maxX = wx + ww;
+		if ( wy + wh > maxY )
+			maxY = wy + wh;
+
+		node = node->Next();
+	}
+	SetClientSize(maxX + 5, maxY + 5);
+};
+
+void wxWindow::OnSize( wxSizeEvent &WXUNUSED(event) )
+{
+  if (GetAutoLayout()) Layout();
+};
+
+bool wxWindow::Show( const bool show )
+{
+  if (show)
+    gtk_widget_show( m_widget );
+  else
+    gtk_widget_hide( m_widget );
+  m_isShown = show;  
+  return TRUE;
+};
+
+void wxWindow::Enable( const bool enable )
+{
+  m_isEnabled = enable;
+  gtk_widget_set_sensitive( m_widget, enable );
+  if (m_wxwindow) gtk_widget_set_sensitive( m_wxwindow, enable );
+};
+
+void wxWindow::MakeModal( const bool modal )
+{
+  return;
+  // Disable all other windows
+  if (this->IsKindOf(CLASSINFO(wxDialog)) || this->IsKindOf(CLASSINFO(wxFrame)))
+  {
+    wxNode *node = wxTopLevelWindows.First();
+    while (node)
+    {
+      wxWindow *win = (wxWindow *)node->Data();
+      if (win != this)
+        win->Enable(!modal);
+
+      node = node->Next();
+    }
+  }
+}
+
+void wxWindow::SetFocus(void)
+{
+  GtkWidget *connect_widget = m_widget;
+  if (m_wxwindow) connect_widget = m_wxwindow;
+  if (connect_widget)
+  {
+    if (GTK_WIDGET_CAN_FOCUS(connect_widget) && !GTK_WIDGET_HAS_FOCUS (connect_widget) )
+    {
+      gtk_widget_grab_focus (connect_widget);
+    };
+  };
+};
+
+bool wxWindow::OnClose(void)
+{
+  printf( "OnClose event.\n" );
+  return TRUE;
+};
+
+void wxWindow::AddChild( wxWindow *child )
+{
+  // Addchild is (often) called before the program
+  // has left the parents constructor so that no
+  // virtual tables work yet. The approach below
+  // practically imitates virtual tables, i.e. it
+  // implements a different AddChild() behaviour
+  // for wxFrame, wxDialog, wxWindow and 
+  // wxMDIParentFrame.
+
+  if (IsKindOf(CLASSINFO(wxMDIParentFrame)))
+  {
+    if (child->IsKindOf(CLASSINFO(wxMDIChildFrame)))
+    {
+      wxMDIClientWindow *client = ((wxMDIParentFrame*)this)->GetClientWindow();
+      if (client)
+      { 
+        client->AddChild( child );
+        return;
+      };
+    };
+  };
+  m_children.Append( child );
+  if (child->IsKindOf(CLASSINFO(wxFrame)) || child->IsKindOf(CLASSINFO(wxDialog)))
+  {
+    if ((child->m_x != -1) && (child->m_y != -1))
+      gtk_widget_set_uposition( child->m_widget, child->m_x, child->m_y );
+  }
+  else
+  {
+    if (m_wxwindow)
+      gtk_myfixed_put( GTK_MYFIXED(m_wxwindow), child->m_widget, child->m_x, child->m_y );
+  };
+  gtk_widget_set_usize( child->m_widget, child->m_width, child->m_height );
+};
+
+wxList *wxWindow::GetChildren(void)
+{
+  return (&m_children);
+};
+
+void wxWindow::RemoveChild( wxWindow *child )
+{
+  if (GetChildren())
+ GetChildren()->DeleteObject( child );
+  child->m_parent = NULL;
+};
+
+void wxWindow::SetReturnCode( int retCode )
+{
+  m_retCode = retCode;
+};
+
+int wxWindow::GetReturnCode(void)
+{
+  return m_retCode;
+};
+
+wxWindow *wxWindow::GetParent(void)
+{
+  return m_parent;
+};
+
+wxEvtHandler *wxWindow::GetEventHandler(void)
+{
+  return m_eventHandler;
+};
+
+void wxWindow::SetEventhandler( wxEvtHandler *handler )
+{
+  m_eventHandler = handler;
+};
+
+wxValidator *wxWindow::GetValidator(void)
+{
+  return m_windowValidator;
+};
+
+void wxWindow::SetValidator( wxValidator *validator )
+{
+  m_windowValidator = validator;
+};
+
+bool wxWindow::IsBeingDeleted(void)
+{
+  return FALSE;
+};
+
+void wxWindow::SetId( wxWindowID id )
+{
+  m_windowId = id;
+};
+
+wxWindowID wxWindow::GetId(void)
+{
+  return m_windowId;
+};
+
+void wxWindow::SetCursor( const wxCursor &cursor )
+{
+  if (*m_cursor == cursor) return;
+  (*m_cursor) = cursor;
+  if (m_widget->window)
+    gdk_window_set_cursor( m_widget->window, m_cursor->GetCursor() );
+  if (m_wxwindow && m_wxwindow->window)
+    gdk_window_set_cursor( m_wxwindow->window, m_cursor->GetCursor() );
+};
+
+void wxWindow::Refresh( const bool eraseBackground, const wxRect *rect )
+{
+  if (eraseBackground && m_wxwindow && m_wxwindow->window)
+  {
+    if (rect)
+      gdk_window_clear_area( m_wxwindow->window, 
+        rect->x, 
+	rect->y, 
+	rect->width, 
+	rect->height );
+    else
+      Clear();
+  };
+  if (!rect)
+  {
+    if (m_wxwindow)
+    {
+      wxClientDC dc(this);
+      PrepareDC(dc);
+      long x = 0;
+      long y = 0;
+      dc.GetInternalDeviceOrigin( &x, &y );
+      
+      int w = 0;
+      int h = 0;
+      GetClientSize( &w, &h );
+      
+      GdkRectangle gdk_rect;
+      gdk_rect.x = x;
+      gdk_rect.y = y;
+      gdk_rect.width = w;
+      gdk_rect.height = h;
+      gtk_widget_draw( m_wxwindow, &gdk_rect );
+    };
+  }
+  else
+  {
+    GdkRectangle gdk_rect;
+    gdk_rect.x = rect->x;
+    gdk_rect.y = rect->y;
+    gdk_rect.width = rect->width;
+    gdk_rect.height = rect->height;
+    if (m_wxwindow)
+      gtk_widget_draw( m_wxwindow, &gdk_rect );
+    else
+      gtk_widget_draw( m_widget, &gdk_rect );
+  };
+};
+
+bool wxWindow::IsExposed( const long x, const long y )
+{
+  return (m_updateRegion.Contains( x, y ) != wxOutRegion );
+};
+
+bool wxWindow::IsExposed( const long x, const long y, const long width, const long height )
+{
+  return (m_updateRegion.Contains( x, y, width, height ) != wxOutRegion );
+};
+
+void wxWindow::Clear(void)
+{
+  if (m_wxwindow && m_wxwindow->window) gdk_window_clear( m_wxwindow->window );
+};
+
+wxColour wxWindow::GetBackgroundColour(void) const
+{
+  return m_backgroundColour;
+};
+
+void wxWindow::SetBackgroundColour( const wxColour &colour )
+{
+  m_backgroundColour = colour;
+  if (m_wxwindow)
+  {
+    m_backgroundColour.CalcPixel( m_wxwindow->style->colormap );
+    gdk_window_set_background( m_wxwindow->window, m_backgroundColour.GetColor() );
+    gdk_window_clear( m_wxwindow->window );
+  };
+  // do something ?
+};
+
+bool wxWindow::Validate(void)
+{
+  wxNode *node = GetChildren()->First();
+  while (node)
+  {
+    wxWindow *child = (wxWindow *)node->Data();
+    if (child->GetValidator() && /* child->GetValidator()->Ok() && */ !child->GetValidator()->Validate(this)) 
+      { return FALSE; }
+    node = node->Next();
+  };
+  return TRUE;
+};
+
+bool wxWindow::TransferDataToWindow(void)
+{
+  wxNode *node = GetChildren()->First();
+  while (node)
+  {
+    wxWindow *child = (wxWindow *)node->Data();
+    if (child->GetValidator() && /* child->GetValidator()->Ok() && */
+	!child->GetValidator()->TransferToWindow() )
+    {
+      wxMessageBox( "Application Error", "Could not transfer data to window", wxOK|wxICON_EXCLAMATION );
+      return FALSE;
+    };
+    node = node->Next();
+  };
+  return TRUE;
+};
+
+bool wxWindow::TransferDataFromWindow(void)
+{
+  wxNode *node = GetChildren()->First();
+  while (node)
+  {
+    wxWindow *child = (wxWindow *)node->Data();
+    if ( child->GetValidator() && /* child->GetValidator()->Ok() && */ !child->GetValidator()->TransferFromWindow() )
+      { return FALSE; }
+   node = node->Next();
+  }
+  return TRUE;
+};
+
+void wxWindow::OnInitDialog( wxInitDialogEvent &WXUNUSED(event) )
+{
+  TransferDataToWindow();
+};
+
+void wxWindow::InitDialog(void)
+{
+  wxInitDialogEvent event(GetId());
+  event.SetEventObject( this );
+  GetEventHandler()->ProcessEvent(event);
+};
+
+void wxWindow::SetDropTarget( wxDropTarget *dropTarget )
+{
+  GtkWidget *connect_widget = m_widget;
+  if (m_wxwindow) connect_widget = m_wxwindow;
+  if (m_pDropTarget)
+  {
+    m_pDropTarget->UnregisterWidget( connect_widget );
+    delete m_pDropTarget;
+  };
+  m_pDropTarget = dropTarget;
+  if (m_pDropTarget)
+  {
+    m_pDropTarget->RegisterWidget( connect_widget );
+  };
+};
+
+wxDropTarget *wxWindow::GetDropTarget() const
+{
+  return m_pDropTarget;
+};
+
+void wxWindow::SetFont( const wxFont &font )
+{
+  m_font = font;
+/*
+  create new style
+  copy old style values to new one
+  set font in new style
+  -> takes to many resources
+  
+  GtkStyle *style = gtk_style_new();
+  ...
+*/
+};
+
+wxFont *wxWindow::GetFont(void)
+{
+  return &m_font;
+};
+
+void wxWindow::SetWindowStyleFlag( long flag )
+{
+  m_windowStyle = flag;
+};
+
+long wxWindow::GetWindowStyleFlag(void) const
+{
+  return m_windowStyle;
+};
+
+void wxWindow::CaptureMouse(void)
+{
+  GtkWidget *connect_widget = m_widget;
+  if (m_wxwindow) connect_widget = m_wxwindow;
+  gtk_grab_add( connect_widget );
+  gdk_pointer_grab ( connect_widget->window, FALSE,
+                    (GdkEventMask)
+		    (GDK_BUTTON_PRESS_MASK | 
+		    GDK_BUTTON_RELEASE_MASK |
+		    GDK_POINTER_MOTION_MASK), 
+		    NULL, NULL, GDK_CURRENT_TIME );
+};
+
+void wxWindow::ReleaseMouse(void)
+{
+  GtkWidget *connect_widget = m_widget;
+  if (m_wxwindow) connect_widget = m_wxwindow;
+  gtk_grab_remove( connect_widget );
+  gdk_pointer_ungrab ( GDK_CURRENT_TIME );
+};
+
+void wxWindow::SetTitle( const wxString &WXUNUSED(title) )
+{
+};
+
+wxString wxWindow::GetTitle(void) const
+{
+  return (wxString&)m_windowName;
+};
+
+wxString wxWindow::GetLabel(void) const
+{
+  return GetTitle();
+};
+
+void wxWindow::SetName( const wxString &name )
+{
+  m_windowName = name;
+};
+
+wxString wxWindow::GetName(void) const
+{
+  return (wxString&)m_windowName;
+};
+
+bool wxWindow::IsShown(void)
+{
+  return m_isShown;
+};
+
+bool wxWindow::IsRetained(void)
+{
+  return FALSE;
+};
+
+wxWindow *wxWindow::FindWindow( const long id )
+{
+  if (id == m_windowId) return this;
+  wxNode *node = m_children.First();
+  while (node)
+  {
+    wxWindow *child = (wxWindow*)node->Data();
+    wxWindow *res = child->FindWindow( id );
+    if (res) return res;
+    node = node->Next();
+  };
+  return NULL;
+};
+
+wxWindow *wxWindow::FindWindow( const wxString& name )
+{
+  if (name == m_windowName) return this;
+  wxNode *node = m_children.First();
+  while (node)
+  {
+    wxWindow *child = (wxWindow*)node->Data();
+    wxWindow *res = child->FindWindow( name );
+    if (res) return res;
+    node = node->Next();
+  };
+  return NULL;
+};
+
+void wxWindow::SetScrollbar( const int orient, const int pos, const int thumbVisible,
+      const int range, const bool WXUNUSED(refresh) )
+{
+  if (!m_wxwindow) return;
+
+  if (orient == wxHORIZONTAL)
+  {
+    float fpos = (float)pos;
+    m_oldHorizontalPos = fpos;
+    float frange = (float)range;
+    float fthumb = (float)thumbVisible;
+    
+    if ((fabs(fpos-m_hAdjust->value) < 0.2) &&
+        (fabs(frange-m_hAdjust->upper) < 0.2) &&
+	(fabs(fthumb-m_hAdjust->page_size) < 0.2))
+      return;
+      
+    m_hAdjust->lower = 0.0;
+    m_hAdjust->upper = frange;
+    m_hAdjust->value = fpos;
+    m_hAdjust->step_increment = 1.0;
+    m_hAdjust->page_increment = (float)(wxMax(fthumb-2,0));
+    m_hAdjust->page_size = fthumb;
+  }
+  else
+  {
+    float fpos = (float)pos;
+    m_oldVerticalPos = fpos;
+    float frange = (float)range;
+    float fthumb = (float)thumbVisible;
+    
+    if ((fabs(fpos-m_vAdjust->value) < 0.2) &&
+        (fabs(frange-m_vAdjust->upper) < 0.2) &&
+	(fabs(fthumb-m_vAdjust->page_size) < 0.2))
+      return;
+      
+    m_vAdjust->lower = 0.0;
+    m_vAdjust->upper = frange;
+    m_vAdjust->value = fpos;
+    m_vAdjust->step_increment = 1.0;
+    m_vAdjust->page_increment = (float)(wxMax(fthumb-2,0));
+    m_vAdjust->page_size = fthumb;
+  };
+ 
+  if (m_wxwindow->window)
+  {  
+    if (orient == wxHORIZONTAL)
+      gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" );
+    else  
+      gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" );
+      
+//    gtk_widget_set_usize( m_widget, m_width, m_height );
+  };
+};
+
+void wxWindow::SetScrollPos( const int orient, const int pos, const bool WXUNUSED(refresh) )
+{
+  if (!m_wxwindow) return;
+  
+  if (orient == wxHORIZONTAL)
+  {
+    float fpos = (float)pos;
+    m_oldHorizontalPos = fpos;
+
+    if (fabs(fpos-m_hAdjust->value) < 0.2) return;
+    m_hAdjust->value = fpos;
+  }
+  else
+  {
+    float fpos = (float)pos;
+    m_oldVerticalPos = fpos;
+    if (fabs(fpos-m_vAdjust->value) < 0.2) return;
+    m_vAdjust->value = fpos;
+  };
+  
+  if (m_wxwindow->window)
+  {  
+    if (orient == wxHORIZONTAL)
+      gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "value_changed" );
+    else  
+      gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "value_changed" );
+  };
+};
+
+int wxWindow::GetScrollThumb( const int orient ) const
+{
+  if (!m_wxwindow) return 0;
+
+  if (orient == wxHORIZONTAL)
+    return (int)(m_hAdjust->page_size+0.5);
+  else
+    return (int)(m_vAdjust->page_size+0.5);
+};
+
+int wxWindow::GetScrollPos( const int orient ) const
+{
+  if (!m_wxwindow) return 0;
+
+  if (orient == wxHORIZONTAL)
+    return (int)(m_hAdjust->value+0.5);
+  else
+    return (int)(m_vAdjust->value+0.5);
+};
+
+int wxWindow::GetScrollRange( const int orient ) const
+{
+  if (!m_wxwindow) return 0;
+
+  if (orient == wxHORIZONTAL)
+    return (int)(m_hAdjust->upper+0.5);
+  else
+    return (int)(m_vAdjust->upper+0.5);
+};
+
+void wxWindow::ScrollWindow( const int dx, const int dy, const wxRect* WXUNUSED(rect) )
+{
+  if (!m_wxwindow) return;
+  
+  m_drawingOffsetX += dx;
+  m_drawingOffsetY += dy;
+  
+//  printf( "X: %d  Y: %d  \n", (int)m_drawingOffsetX, (int)m_drawingOffsetY );
+  
+  gtk_myfixed_set_offset( GTK_MYFIXED(m_wxwindow), m_drawingOffsetX, m_drawingOffsetY );
+  
+/*
+    The code here is very nifty, but it doesn't work with
+    overlapping windows...
+
+    int cw = 0;
+    int ch = 0;
+    GetClientSize( &cw, &ch );
+    
+    int w = cw - abs(dx);
+    int h = ch - abs(dy);
+    if ((h < 0) || (w < 0))
+    {
+      Refresh();
+      return;
+    };
+    int s_x = 0;
+    int s_y = 0;
+    if (dx < 0) s_x = -dx;
+    if (dy < 0) s_y = -dy;
+    int d_x = 0;
+    int d_y = 0;
+    if (dx > 0) d_x = dx;
+    if (dy > 0) d_y = dy;
+    gdk_window_copy_area( m_wxwindow->window, m_wxwindow->style->fg_gc[0], d_x, d_y,
+      m_wxwindow->window, s_x, s_y, w, h );
+      
+    wxRect rect;
+    if (dx < 0) rect.x = cw+dx; else rect.x = 0;
+    if (dy < 0) rect.y = ch+dy; else rect.y = 0;
+    if (dy != 0) rect.width = cw; else rect.width = abs(dx);
+    if (dx != 0) rect.height = ch; else rect.height = abs(dy);
+  
+    Refresh( TRUE, &rect );
+*/
+};
+
+void wxWindow::GetDrawingOffset( long *x, long *y )
+{
+  if (x) *x = m_drawingOffsetX;
+  if (y) *y = m_drawingOffsetY;
+};
+
+//-------------------------------------------------------------------------------------
+//          Layout
+//-------------------------------------------------------------------------------------
+
+wxLayoutConstraints *wxWindow::GetConstraints(void) const
+{
+  return m_constraints;
+};
+
+void wxWindow::SetConstraints( wxLayoutConstraints *constraints )
+{
+  if (m_constraints)
+  {
+    UnsetConstraints(m_constraints);
+    delete m_constraints;
+  }
+  m_constraints = constraints;
+  if (m_constraints)
+  {
+    // Make sure other windows know they're part of a 'meaningful relationship'
+    if (m_constraints->left.GetOtherWindow() && (m_constraints->left.GetOtherWindow() != this))
+      m_constraints->left.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
+    if (m_constraints->top.GetOtherWindow() && (m_constraints->top.GetOtherWindow() != this))
+      m_constraints->top.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
+    if (m_constraints->right.GetOtherWindow() && (m_constraints->right.GetOtherWindow() != this))
+      m_constraints->right.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
+    if (m_constraints->bottom.GetOtherWindow() && (m_constraints->bottom.GetOtherWindow() != this))
+      m_constraints->bottom.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
+    if (m_constraints->width.GetOtherWindow() && (m_constraints->width.GetOtherWindow() != this))
+      m_constraints->width.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
+    if (m_constraints->height.GetOtherWindow() && (m_constraints->height.GetOtherWindow() != this))
+      m_constraints->height.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
+    if (m_constraints->centreX.GetOtherWindow() && (m_constraints->centreX.GetOtherWindow() != this))
+      m_constraints->centreX.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
+    if (m_constraints->centreY.GetOtherWindow() && (m_constraints->centreY.GetOtherWindow() != this))
+      m_constraints->centreY.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
+  }
+;
+}
+;
+
+void wxWindow::SetAutoLayout( const bool autoLayout )
+{
+  m_autoLayout = autoLayout;
+};
+
+bool wxWindow::GetAutoLayout(void) const
+{
+  return m_autoLayout;
+};
+
+wxSizer *wxWindow::GetSizer(void) const
+{
+  return m_windowSizer;
+};
+
+void wxWindow::SetSizerParent( wxWindow *win )
+{
+  m_sizerParent = win;
+};
+
+wxWindow *wxWindow::GetSizerParent(void) const
+{
+  return m_sizerParent;
+};
+
+// This removes any dangling pointers to this window
+// in other windows' constraintsInvolvedIn lists.
+void wxWindow::UnsetConstraints(wxLayoutConstraints *c)
+{
+  if (c)
+  {
+    if (c->left.GetOtherWindow() && (c->top.GetOtherWindow() != this))
+      c->left.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
+    if (c->top.GetOtherWindow() && (c->top.GetOtherWindow() != this))
+      c->top.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
+    if (c->right.GetOtherWindow() && (c->right.GetOtherWindow() != this))
+      c->right.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
+    if (c->bottom.GetOtherWindow() && (c->bottom.GetOtherWindow() != this))
+      c->bottom.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
+    if (c->width.GetOtherWindow() && (c->width.GetOtherWindow() != this))
+      c->width.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
+    if (c->height.GetOtherWindow() && (c->height.GetOtherWindow() != this))
+      c->height.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
+    if (c->centreX.GetOtherWindow() && (c->centreX.GetOtherWindow() != this))
+      c->centreX.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
+    if (c->centreY.GetOtherWindow() && (c->centreY.GetOtherWindow() != this))
+      c->centreY.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
+  }
+}
+
+// Back-pointer to other windows we're involved with, so if we delete
+// this window, we must delete any constraints we're involved with.
+void wxWindow::AddConstraintReference(wxWindow *otherWin)
+{
+  if (!m_constraintsInvolvedIn)
+    m_constraintsInvolvedIn = new wxList;
+  if (!m_constraintsInvolvedIn->Member(otherWin))
+    m_constraintsInvolvedIn->Append(otherWin);
+}
+
+// REMOVE back-pointer to other windows we're involved with.
+void wxWindow::RemoveConstraintReference(wxWindow *otherWin)
+{
+  if (m_constraintsInvolvedIn)
+    m_constraintsInvolvedIn->DeleteObject(otherWin);
+}
+
+// Reset any constraints that mention this window
+void wxWindow::DeleteRelatedConstraints(void)
+{
+  if (m_constraintsInvolvedIn)
+  {
+    wxNode *node = m_constraintsInvolvedIn->First();
+    while (node)
+    {
+      wxWindow *win = (wxWindow *)node->Data();
+      wxNode *next = node->Next();
+      wxLayoutConstraints *constr = win->GetConstraints();
+
+      // Reset any constraints involving this window
+      if (constr)
+      {
+        constr->left.ResetIfWin((wxWindow *)this);
+        constr->top.ResetIfWin((wxWindow *)this);
+        constr->right.ResetIfWin((wxWindow *)this);
+        constr->bottom.ResetIfWin((wxWindow *)this);
+        constr->width.ResetIfWin((wxWindow *)this);
+        constr->height.ResetIfWin((wxWindow *)this);
+        constr->centreX.ResetIfWin((wxWindow *)this);
+        constr->centreY.ResetIfWin((wxWindow *)this);
+      }
+      delete node;
+      node = next;
+    }
+    delete m_constraintsInvolvedIn;
+    m_constraintsInvolvedIn = NULL;
+  }
+}
+
+void wxWindow::SetSizer(wxSizer *sizer)
+{
+  m_windowSizer = sizer;
+  if (sizer)
+    sizer->SetSizerParent((wxWindow *)this);
+}
+
+/*
+ * New version
+ */
+
+bool wxWindow::Layout(void)
+{
+  if (GetConstraints())
+  {
+    int w, h;
+    GetClientSize(&w, &h);
+    GetConstraints()->width.SetValue(w);
+    GetConstraints()->height.SetValue(h);
+  }
+  
+  // If top level (one sizer), evaluate the sizer's constraints.
+  if (GetSizer())
+  {
+    int noChanges;
+    GetSizer()->ResetConstraints();   // Mark all constraints as unevaluated
+    GetSizer()->LayoutPhase1(&noChanges);
+    GetSizer()->LayoutPhase2(&noChanges);
+    GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
+    return TRUE;
+  }
+  else
+  {
+    // Otherwise, evaluate child constraints
+    ResetConstraints();   // Mark all constraints as unevaluated
+    DoPhase(1);           // Just one phase need if no sizers involved
+    DoPhase(2);
+    SetConstraintSizes(); // Recursively set the real window sizes
+  }
+  return TRUE;
+}
+
+
+// Do a phase of evaluating constraints:
+// the default behaviour. wxSizers may do a similar
+// thing, but also impose their own 'constraints'
+// and order the evaluation differently.
+bool wxWindow::LayoutPhase1(int *noChanges)
+{
+  wxLayoutConstraints *constr = GetConstraints();
+  if (constr)
+  {
+    return constr->SatisfyConstraints((wxWindow *)this, noChanges);
+  }
+  else
+    return TRUE;
+}
+
+bool wxWindow::LayoutPhase2(int *noChanges)
+{
+  *noChanges = 0;
+  
+  // Layout children
+  DoPhase(1);
+  DoPhase(2);
+  return TRUE;
+}
+
+// Do a phase of evaluating child constraints
+bool wxWindow::DoPhase(const int phase)
+{
+  int noIterations = 0;
+  int maxIterations = 500;
+  int noChanges = 1;
+  int noFailures = 0;
+  wxList succeeded;
+  while ((noChanges > 0) && (noIterations < maxIterations))
+  {
+    noChanges = 0;
+    noFailures = 0;
+    wxNode *node = GetChildren()->First();
+    while (node)
+    {
+      wxWindow *child = (wxWindow *)node->Data();
+      if (!child->IsKindOf(CLASSINFO(wxFrame)) && !child->IsKindOf(CLASSINFO(wxDialog)))
+      {
+        wxLayoutConstraints *constr = child->GetConstraints();
+        if (constr)
+        {
+          if (succeeded.Member(child))
+          {
+          }
+          else
+          {
+            int tempNoChanges = 0;
+            bool success = ( (phase == 1) ? child->LayoutPhase1(&tempNoChanges) : child->LayoutPhase2(&tempNoChanges) ) ;
+            noChanges += tempNoChanges;
+            if (success)
+            {
+              succeeded.Append(child);
+            }
+          }
+        }
+      }
+      node = node->Next();
+    }
+    noIterations ++;
+  }
+  return TRUE;
+}
+
+void wxWindow::ResetConstraints(void)
+{
+  wxLayoutConstraints *constr = GetConstraints();
+  if (constr)
+  {
+    constr->left.SetDone(FALSE);
+    constr->top.SetDone(FALSE);
+    constr->right.SetDone(FALSE);
+    constr->bottom.SetDone(FALSE);
+    constr->width.SetDone(FALSE);
+    constr->height.SetDone(FALSE);
+    constr->centreX.SetDone(FALSE);
+    constr->centreY.SetDone(FALSE);
+  }
+  wxNode *node = GetChildren()->First();
+  while (node)
+  {
+    wxWindow *win = (wxWindow *)node->Data();
+    if (!win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)))
+      win->ResetConstraints();
+    node = node->Next();
+  }
+}
+
+// Need to distinguish between setting the 'fake' size for
+// windows and sizers, and setting the real values.
+void wxWindow::SetConstraintSizes(const bool recurse)
+{
+  wxLayoutConstraints *constr = GetConstraints();
+  if (constr && constr->left.GetDone() && constr->right.GetDone() &&
+                constr->width.GetDone() && constr->height.GetDone())
+  {
+    int x = constr->left.GetValue();
+    int y = constr->top.GetValue();
+    int w = constr->width.GetValue();
+    int h = constr->height.GetValue();
+
+    // If we don't want to resize this window, just move it...
+    if ((constr->width.GetRelationship() != wxAsIs) ||
+        (constr->height.GetRelationship() != wxAsIs))
+    {
+      // Calls Layout() recursively. AAAGH. How can we stop that.
+      // Simply take Layout() out of non-top level OnSizes.
+      SizerSetSize(x, y, w, h);
+    }
+    else
+    {
+      SizerMove(x, y);
+    }
+  }
+  else if (constr)
+  {
+    char *windowClass = this->GetClassInfo()->GetClassName();
+
+    wxString winName;
+	if (GetName() == "")
+		winName = "unnamed";
+	else
+		winName = GetName();
+    wxDebugMsg("Constraint(s) not satisfied for window of type %s, name %s:\n", (const char *)windowClass, (const char *)winName);
+    if (!constr->left.GetDone())
+      wxDebugMsg("  unsatisfied 'left' constraint.\n");
+    if (!constr->right.GetDone())
+      wxDebugMsg("  unsatisfied 'right' constraint.\n");
+    if (!constr->width.GetDone())
+      wxDebugMsg("  unsatisfied 'width' constraint.\n");
+    if (!constr->height.GetDone())
+      wxDebugMsg("  unsatisfied 'height' constraint.\n");
+    wxDebugMsg("Please check constraints: try adding AsIs() constraints.\n");
+  }
+
+  if (recurse)
+  {
+    wxNode *node = GetChildren()->First();
+    while (node)
+    {
+      wxWindow *win = (wxWindow *)node->Data();
+      if (!win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)))
+        win->SetConstraintSizes();
+      node = node->Next();
+    }
+  }
+}
+
+// This assumes that all sizers are 'on' the same
+// window, i.e. the parent of this window.
+void wxWindow::TransformSizerToActual(int *x, int *y) const
+{
+  if (!m_sizerParent || m_sizerParent->IsKindOf(CLASSINFO(wxDialog)) ||
+  			 m_sizerParent->IsKindOf(CLASSINFO(wxFrame)) )
+    return;
+    
+  int xp, yp;
+  m_sizerParent->GetPosition(&xp, &yp);
+  m_sizerParent->TransformSizerToActual(&xp, &yp);
+  *x += xp;
+  *y += yp;
+}
+
+void wxWindow::SizerSetSize(const int x, const int y, const int w, const int h)
+{
+	int xx = x;
+	int yy = y;
+  TransformSizerToActual(&xx, &yy);
+  SetSize(xx, yy, w, h);
+}
+
+void wxWindow::SizerMove(const int x, const int y)
+{
+	int xx = x;
+	int yy = y;
+  TransformSizerToActual(&xx, &yy);
+  Move(xx, yy);
+}
+
+// Only set the size/position of the constraint (if any)
+void wxWindow::SetSizeConstraint(const int x, const int y, const int w, const int h)
+{
+  wxLayoutConstraints *constr = GetConstraints();
+  if (constr)
+  {
+    if (x != -1)
+    {
+      constr->left.SetValue(x);
+      constr->left.SetDone(TRUE);
+    }
+    if (y != -1)
+    {
+      constr->top.SetValue(y);
+      constr->top.SetDone(TRUE);
+    }
+    if (w != -1)
+    {
+      constr->width.SetValue(w);
+      constr->width.SetDone(TRUE);
+    }
+    if (h != -1)
+    {
+      constr->height.SetValue(h);
+      constr->height.SetDone(TRUE);
+    }
+  }
+}
+
+void wxWindow::MoveConstraint(const int x, const int y)
+{
+  wxLayoutConstraints *constr = GetConstraints();
+  if (constr)
+  {
+    if (x != -1)
+    {
+      constr->left.SetValue(x);
+      constr->left.SetDone(TRUE);
+    }
+    if (y != -1)
+    {
+      constr->top.SetValue(y);
+      constr->top.SetDone(TRUE);
+    }
+  }
+}
+
+void wxWindow::GetSizeConstraint(int *w, int *h) const
+{
+  wxLayoutConstraints *constr = GetConstraints();
+  if (constr)
+  {
+    *w = constr->width.GetValue();
+    *h = constr->height.GetValue();
+  }
+  else
+    GetSize(w, h);
+}
+
+void wxWindow::GetClientSizeConstraint(int *w, int *h) const
+{
+  wxLayoutConstraints *constr = GetConstraints();
+  if (constr)
+  {
+    *w = constr->width.GetValue();
+    *h = constr->height.GetValue();
+  }
+  else
+    GetClientSize(w, h);
+}
+
+void wxWindow::GetPositionConstraint(int *x, int *y) const
+{
+  wxLayoutConstraints *constr = GetConstraints();
+  if (constr)
+  {
+    *x = constr->left.GetValue();
+    *y = constr->top.GetValue();
+  }
+  else
+    GetPosition(x, y);
+}
+
diff --git a/src/mkdirs b/src/mkdirs
new file mode 100755
index 0000000000..c36a698965
--- /dev/null
+++ b/src/mkdirs
@@ -0,0 +1,32 @@
+#! /bin/sh
+
+# create "/gtk" if not present
+if test ! -d gtk; then
+    mkdir gtk
+fi
+
+# create "/common" if not present
+if test ! -d common; then
+    mkdir common
+fi
+
+# create "/generic" if not present
+if test ! -d generic; then
+    mkdir generic
+fi
+
+# create "/png" if not present
+if test ! -d png; then
+    mkdir png
+fi
+
+# create "/zlib" if not present
+if test ! -d zlib; then
+    mkdir zlib
+fi
+
+# create "/gdk_imlib" if not present
+if test ! -d gdk_imlib; then
+    mkdir gdk_imlib
+fi
+
diff --git a/src/png/CHANGES b/src/png/CHANGES
new file mode 100644
index 0000000000..9cb33a1e89
--- /dev/null
+++ b/src/png/CHANGES
@@ -0,0 +1,288 @@
+CHANGES - changes for libpng
+
+version 0.2
+   added reader into png.h
+   fixed small problems in stub file
+version 0.3
+   added pull reader
+   split up pngwrite.c to several files
+   added pnglib.txt
+   added example.c
+   cleaned up writer, adding a few new tranformations
+   fixed some bugs in writer
+   interfaced with zlib 0.5
+   added K&R support
+   added check for 64 KB blocks for 16 bit machines
+version 0.4
+   cleaned up code and commented code
+   simplified time handling into png_time
+   created png_color_16 and png_color_8 to handle color needs
+   cleaned up color type defines
+   fixed various bugs
+   made various names more consistant
+   interfaced with zlib 0.71
+   cleaned up zTXt reader and writer (using zlib's Reset functions)
+   split transformations into pngrtran.c and pngwtran.c
+version 0.5
+   interfaced with zlib 0.8
+   fixed many reading and writing bugs
+   saved using 3 spaces instead of tabs
+version 0.6
+   added png_large_malloc() and png_large_free()
+   added png_size_t
+   cleaned up some compiler warnings
+   added png_start_read_image()
+version 0.7
+   cleaned up lots of bugs
+   finished dithering and other stuff
+   added test program
+   changed name from pnglib to libpng
+version 0.71 [June, 1995]
+   changed pngtest.png for zlib 0.93
+   fixed error in libpng.txt and example.c
+version 0.8
+   cleaned up some bugs
+   added png_set_filler()
+   split up pngstub.c into pngmem.c, pngio.c, and pngerror.c
+   added #define's to remove unwanted code
+   moved png_info_init() to png.c
+   added old_size into png_realloc()
+   added functions to manually set filtering and compression info
+   changed compression parameters based on image type
+   optimized filter selection code
+   added version info
+   changed external functions passing floats to doubles (k&r problems?)
+   put all the configurable stuff in pngconf.h
+   enabled png_set_shift to work with paletted images on read
+   added png_read_update_info() - updates info structure with
+      transformations
+version 0.81 [August, 1995]
+   incorporated Tim Wegner's medium model code (thanks, Tim)
+version 0.82 [September, 1995]
+   [unspecified changes]
+version 0.85 [December, 1995]
+   added more medium model code (almost everything's a far)
+   added i/o, error, and memory callback functions
+   fixed some bugs (16 bit, 4 bit interlaced, etc.)
+   added first run progressive reader (barely tested)
+version 0.86 [January, 1996]
+   fixed bugs
+   improved documentation
+version 0.87 [January, 1996]
+   fixed medium model bugs
+   fixed other bugs introduced in 0.85 and 0.86
+   added some minor documentation
+version 0.88 [January, 1996]
+   fixed progressive bugs
+   replaced tabs with spaces
+   cleaned up documentation
+   added callbacks for read/write and warning/error functions
+version 0.89 [July, 1996]
+   added new initialization API to make libpng work better with shared libs
+      we now have png_create_read_struct(), png_create_write_struct(),
+      png_create_info_struct(), png_destroy_read_struct(), and
+      png_destroy_write_struct() instead of the separate calls to
+      malloc and png_read_init(), png_info_init(), and png_write_init()
+   changed warning/error callback functions to fix bug - this means you
+      should use the new initialization API if you were using the old
+      png_set_message_fn() calls, and that the old API no longer exists
+      so that people are aware that they need to change their code
+   changed filter selection API to allow selection of multiple filters
+      since it didn't work in previous versions of libpng anyways
+   optimized filter selection code    
+   fixed png_set_background() to allow using an arbitrary RGB color for
+      paletted images
+   fixed gamma and background correction for paletted images, so
+      png_correct_palette is not needed unless you are correcting an
+      external palette (you will need to #define PNG_CORRECT_PALETTE_SUPPORTED
+      in pngconf.h) - if nobody uses this, it may disappear in the future.
+   fixed bug with Borland 64K memory allocation (Alexander Lehmann)
+   fixed bug in interlace handling (Smarasderagd, I think)
+   added more error checking for writing and image to reduce invalid files
+   separated read and write functions so that they won't both be linked
+      into a binary when only reading or writing functionality is used
+   new pngtest image also has interlacing and zTXt
+   updated documentation to reflect new API
+version 0.90 [January, 1997]
+   made CRC errors/warnings on critical and ancillary chunks configurable
+   libpng will use the zlib CRC routines by (compile-time) default
+   changed DOS small/medium model memory support - needs zlib 1.04 (Tim Wegner)
+   added external C++ wrapper statements to png.h (Gilles Dauphin)
+   allow PNG file to be read when some or all of file signature has already
+      been read from the beginning of the stream.  ****This affects the size
+      of info_struct and invalidates all programs that use a shared libpng****
+   fixed png_filler() declarations
+   fixed? background color conversions
+   fixed order of error function pointers to match documentation
+   current chunk name is now available in png_struct to reduce the number
+      of nearly identical error messages (will simplify multi-lingual
+      support when available)
+   try to get ready for unknown-chunk callback functions:
+      - previously read critical chunks are flagged, so the chunk handling
+        routines can determine if the chunk is in the right place
+      - all chunk handling routines have the same prototypes, so we will
+        be able to handle all chunks via a callback mechanism
+   try to fix Linux "setjmp" buffer size problems
+version 0.95 [March, 1997]
+   fixed bug in pngwutil.c allocating "up_row" twice and "avg_row" never
+   fixed bug in PNG file signature compares when start != 0
+   changed parameter type of png_set_filler(...filler...) from png_byte
+      to png_uint_32
+   added test for MACOS to ensure that both math.h and fp.h are not #included
+   added macros for libpng to be compiled as a Windows DLL (Andreas Kupries)
+   added "packswap" transformation, which changes the endianness of
+      packed-pixel bytes (Kevin Bracey)
+   added "strip_alpha" transformation, which removes the alpha channel of
+      input images without using it (not neccesarily a good idea)
+   added "swap_alpha" transformation, which puts the alpha channel in front
+      of the color bytes instead of after
+   removed all implicit variable tests which assume NULL == 0 (I think)
+   changed several variables to "png_size_t" to show 16/32-bit limitations
+   added new pCAL chunk read/write support
+   added experimental filter selection weighting (Greg Roelofs)
+   removed old png_set_rgbx() and png_set_xrgb() functions that have been
+      obsolete for about 2 years now (use png_set_filler() instead)
+   added macros to read 16- and 32-bit ints directly from buffer, to be
+      used only on those systems that support it (namely PowerPC and 680x0)
+      With some testing, this may become the default for MACOS/PPC systems.
+   only calculate CRC on data if we are going to use it
+   added macros for zTXt compression type PNG_zTXt_COMPRESSION_???
+   added macros for simple libpng debugging output selectable at compile time
+   removed PNG_READ_END_MODE in progressive reader (Smarasderagd)
+   more description of info_struct in libpng.txt and png.h
+   more instructions in example.c
+   more chunk types tested in pngtest.c
+   renamed pngrcb.c to pngset.c, and all png_read_<chunk> functions to be
+      png_set_<chunk>.  We now have corresponding png_get_<chunk>
+      functions in pngget.c to get infomation in info_ptr.  This isolates
+      the application from the internal organization of png_info_struct
+      (good for shared library implementations).
+version 0.96 [May, 1997]
+   fixed serious bug with < 8bpp images introduced in 0.95
+   fixed 256-color transparency bug (Greg Roelofs)
+   fixed up documentation (Greg Roelofs, Laszlo Nyul)
+   fixed "error" in pngconf.h for Linux setjmp() behaviour
+   fixed DOS medium model support (Tim Wegner)
+   fixed png_check_keyword() for case with error in static string text
+   added read of CRC after IEND chunk for embedded PNGs (Laszlo Nyul)
+   added typecasts to quiet compiler errors
+   added more debugging info
+version 0.97 [January, 1998]
+   removed PNG_USE_OWN_CRC capability
+   relocated png_set_crc_action from pngrutil.c to pngrtran.c
+   fixed typecasts of "new_key", etc. (Andreas Dilger)
+   added RFC 1152 [sic] date support
+   fixed bug in gamma handling of 4-bit grayscale
+   added 2-bit grayscale gamma handling (Glenn R-P)
+   added more typecasts. 65536L becomes (png_uint_32)65536L, etc. (Glenn R-P)
+   minor corrections in libpng.txt
+   added simple sRGB support (Glenn R-P)
+   easier conditional compiling, e.g. define PNG_READ/WRITE_NOT_FULLY_SUPPORTED;
+      all configurable options can be selected from command-line instead
+      of having to edit pngconf.h (Glenn R-P)
+   fixed memory leak in pngwrite.c (free info_ptr->text) (Glenn R-P)
+   added more conditions for png_do_background, to avoid changing
+      black pixels to background when a background is supplied and
+      no pixels are transparent
+   repaired PNG_NO_STDIO behaviour
+   tested NODIV support and made it default behaviour (Greg Roelofs)
+   added "-m" option and PNGTEST_DEBUG_MEMORY to pngtest (John Bowler)
+   regularized version numbering scheme and bumped shared-library major
+      version number to 2 to avoid problems with libpng 0.89 apps (Greg Roelofs)
+version 0.98 [January, 1998]
+   cleaned up some typos in libpng.txt and in code documentation
+   fixed memory leaks in pCAL chunk processing (Glenn R-P and John Bowler)
+   cosmetic change "display_gamma" to "screen_gamma" in pngrtran.c
+   changed recommendation about file_gamma for PC images to .51 from .45,
+      in example.c and libpng.txt, added comments to distinguish between
+      screen_gamma, viewing_gamma, and display_gamma.
+   changed all references to RFC1152 to read RFC1123 and changed the
+      PNG_TIME_RFC1152_SUPPORTED macro to PNG_TIME_RFC1123_SUPPORTED
+   added png_invert_alpha capability (Glenn R-P -- suggestion by Jon Vincent)
+   changed srgb_intent from png_byte to int to avoid compiler bugs
+version 0.99 [January 30, 1998]
+   free info_ptr->text instead of end_info_ptr->text in pngread.c (John Bowler)
+   fixed a longstanding "packswap" bug in pngtrans.c
+   fixed some inconsistencies in pngconf.h that prevented compiling with
+      PNG_READ_GAMMA_SUPPORTED and PNG_READ_hIST_SUPPORTED undefined
+   fixed some typos and made other minor rearrangement of libpng.txt (Andreas)
+   changed recommendation about file_gamma for PC images to .50 from .51 in
+      example.c and libpng.txt, and changed file_gamma for sRGB images to .45
+   added a number of functions to access information from the png structure
+      png_get_image_height(), etc. (Glenn R-P, suggestion by Brad Pettit)
+   added TARGET_MACOS similar to zlib-1.0.8
+   define PNG_ALWAYS_EXTERN when __MWERKS__ && WIN32 are defined
+   added type casting to all png_malloc() function calls
+version 0.99a [January 31, 1998]
+   Added type casts and parentheses to all returns that return a value.(Tim W.)
+version 0.99b [February 4, 1998]
+   Added type cast png_uint_32 on malloc function calls where needed.
+   Changed type of num_hist from png_uint_32 to int (same as num_palette).
+   Added checks for rowbytes overflow, in case png_size_t is less than 32 bits.
+   Renamed makefile.elf to makefile.lnx.
+version 0.99c [February 7, 1998]
+   More type casting.  Removed erroneous overflow test in pngmem.c.
+   Added png_buffered_memcpy() and png_buffered_memset(), apply them to rowbytes.
+   Added UNIX manual pages libpng.3 (incorporating libpng.txt) and  png.5.
+version 0.99d [February 11, 1998]
+   Renamed "far_to_near()" "png_far_to_near()"
+   Revised libpng.3
+   Version 99c "buffered" operations didn't work as intended.  Replaced them
+     with png_memcpy_check() and png_memset_check().
+   Added many "if (png_ptr == NULL) return" to quell compiler warnings about
+     unused png_ptr, mostly in pngget.c and pngset.c.
+   Check for overlength tRNS chunk present when indexed-color PLTE is read.
+   Cleaned up spelling errors in libpng.3/libpng.txt
+   Corrected a problem with png_get_tRNS() which returned undefined trans array
+version 0.99e [February 28, 1998]
+   Corrected png_get_tRNS() again.
+   Add parentheses for easier reading of pngget.c, fixed "||" should be "&&".
+   Touched up example.c to make more of it compileable, although the entire
+     file still can't be compiled (Willem van Schaik)
+   Fixed a bug in png_do_shift() (Bryan Tsai)
+   Added a space in png.h prototype for png_write_chunk_start()
+   Replaced pngtest.png with one created with zlib 1.1.1
+   Changed pngtest to report PASS even when file size is different (Jean-loup G.)
+   Corrected some logic errors in png_do_invert_alpha() (Chris Patterson)
+version 0.99f [March 5, 1998]
+   Corrected a bug in pngpread() introduced in version 99c (Kevin Bracey)
+   Moved makefiles into a "scripts" directory, and added INSTALL instruction file
+   Added makefile.os2 and pngos2.def (A. Zabolotny) and makefile.s2x (W. Sebok)
+   Added pointers to "note on libpng versions" in makefile.lnx and README
+   Added row callback feature when reading and writing nonprogressive rows
+      and added a test of this feature in pngtest.c
+   Added user transform callbacks, with test of the feature in pngtest.c
+version 0.99g [March 6, 1998, morning]
+   Minor changes to pngtest.c to suppress compiler warnings.
+   Removed "beta" language from documentation.
+version 0.99h [March 6, 1998, evening]
+   Minor changes to previous minor changes to pngtest.c 
+   Changed PNG_READ_NOT_FULLY_SUPPORTED to PNG_READ_TRANSFORMS_NOT_SUPPORTED
+   and added PNG_PROGRESSIVE_READ_NOT_SUPPORTED macro
+version 1.00 [March 7, 1998]
+   Changed several typedefs in pngrutil.c
+   Added makefile.wat (Pawel Mrochen), updated makefile.tc3 (Willem van Schaik)
+   replaced "while(1)" with "for(;;)"
+   added PNGARG() to prototypes in pngtest.c and removed some prototypes
+   updated some of the makefiles (Tom Lane)
+   changed some typedefs (s_start, etc.) in pngrutil.c
+   fixed dimensions of "short_months" array in pngwrite.c
+   Replaced ansi2knr.c with the one from jpeg-v6
+version 1.0.0 [March 8, 1998]
+   Changed name from 1.00 to 1.0.0 (Adam Costello)
+   Added smakefile.ppc (with SCOPTIONS.ppc) for Amiga PPC (Andreas Kleinert)
+version 1.0.0a [March 9, 1998]
+   Fixed three bugs in pngrtran.c to make gamma+background handling consistent
+   (Greg Roelofs)
+   Changed format of the PNG_LIBPNG_VER integer to xyyzz instead of xyz
+   for major, minor, and bugfix releases.  This is 10001. (Adam Costello,
+   Tom Lane)
+   Make months range from 1-12 in png_convert_to_rfc1123
+version 1.0.0b [March 13, 1998]
+   Quieted compiler complaints about two empty "for" loops in pngrutil.c
+   Minor changes to makefile.s2x
+   Removed #ifdef/#endif around a png_free() in pngread.c
+version 1.0.1 [March 14, 1998]
+   Changes makefile.s2x to reduce security risk of using a relative pathname
+   Fixed some typos in the documentation (Greg).
+   Fixed a problem with value of "channels" returned by png_read_update_info()
diff --git a/src/png/INSTALL b/src/png/INSTALL
new file mode 100644
index 0000000000..4978740993
--- /dev/null
+++ b/src/png/INSTALL
@@ -0,0 +1,87 @@
+
+Installing libpng version 1.0.1 March 15, 1998
+
+Before installing libpng, you must first install zlib.  zlib
+can usually be found wherever you got libpng.  zlib can be
+placed in another directory, at the same level as libpng.
+Note that your system might already have a preinstalled
+zlib, but you will still need to have access to the 
+zlib.h and zconf.h include files that correspond to the
+version of zlib that's installed.
+
+You can rename the directories that you downloaded (they
+might be called "libpng-1.0.1 or "lpng100" and "zlib-1.1.1"
+or "zlib111") so that you have directories called "zlib" and "libpng".
+
+Your directory structure should look like this:
+
+   ..       (the parent directory)
+      libpng  (this directory)
+          INSTALL (this file)
+          README
+          *.h
+          *.c
+          scripts
+             makefile.*
+          pngtest.png
+          etc.
+      zlib
+          README
+          *.h
+          *.c
+          contrib
+          etc.
+
+First enter the zlib directory and follow the instructions
+in zlib/README.  Then come back here and choose the
+appropriate makefile.sys in the scripts directory.
+The files that are presently available in the scripts directory
+include
+
+      descrip.mms   =>  VMS makefile for MMS or MMK
+      makefile.std  =>  Generic UNIX makefile
+      makefile.knr  =>  Archaic UNIX Makefile that converts files with ansi2knr
+      makefile.dec  =>  DEC Alpha UNIX makefile
+      makefile.sgi  =>  Silicon Graphics IRIX makefile
+      makefile.sun  =>  Sun makefile
+      makefile.s2x  =>  Solaris 2.X makefile (gcc, creates libpng.so.2.1.0)
+      makefile.lnx  =>  Linux/ELF makefile (gcc, creates libpng.so.2.1.0)
+      makefile.mip  =>  MIPS makefile
+      makefile.aco  =>  Acorn makefile
+      makefile.ama  =>  Amiga makefile
+      smakefile.ppc =>  AMIGA smakefile for SAS C V6.58/7.00 PPC compiler
+                        (Requires SCOPTIONS, copied from scripts/SCOPTIONS.ppc)
+      makefile.atr  =>  Atari makefile
+      makefile.bor  =>  Borland makefile
+      build.bat     =>  MS-DOS batch file for Borland compiler
+      makefile.dj2  =>  DJGPP 2 makefile
+      makefile.msc  =>  Microsoft C makefile
+      makefile.tc3  =>  Turbo C 3.0 makefile
+      makefile.os2  =>  OS/2 Makefile (gcc and emx, requires pngos2.def)
+      pngos2.def    =>  OS/2 module definition file used by makefile.os2
+      makefile.wat  =>  Watcom 10a+ Makefile, 32-bit flat memory model
+      makevms.com   =>  VMS build script
+
+Copy the file (or files) that you need from the
+scripts directory into this directory, for example
+
+   MSDOS example: copy scripts\makefile.msd makefile
+   UNIX example:    cp scripts/makefile.std makefile
+
+Read the makefile to see if you need to change any source or
+target directories to match your preferences.
+
+Then read pngconf.h to see if you want to make any configuration
+changes.
+
+Then just run "make test" which will create the libpng library in
+this directory and run a quick test that reads the "pngtest.png"
+file and writes a "pngout.png" file that should be identical to it.
+
+Most of the makefiles will allow you to run "make install" to
+put the library in its final resting place (if you want to
+do that, run "make install" in the zlib directory first if necessary).
+
+Further information can be found in the README and libpng.txt
+files, in the individual makefiles, and in png.h, and the manual
+pages libpng.3 and png.5.
diff --git a/src/png/README b/src/png/README
new file mode 100644
index 0000000000..ea463cd9c5
--- /dev/null
+++ b/src/png/README
@@ -0,0 +1,194 @@
+README for libpng 1.0.1 (shared library 2.1)
+See the note about version numbers near the top of png.h
+
+See INSTALL for instructions on how to install libpng.
+
+This is the first official release of libpng.  Don't let the fact that
+it's the first release fool you.  The libpng library has been in
+extensive use and testing for about two and a half years.  However, it's
+finally gotten to the stage where there haven't been significant
+changes to the API in some time, and people have a bad feeling about
+libraries with versions < 1.0.
+
+****
+Note that some of the changes to the png_info structure render this
+version of the library binary incompatible with libpng-0.89 or
+earlier versions if you are using a shared library.  The type of the
+"filler" parameter for png_set_filler() has changed from png_byte to
+png_uint_32, which will affect shared-library applications that use
+this function.
+
+To avoid problems with changes to the internals of png_info_struct,
+new APIs have been made available in 0.95 to avoid direct application
+access to info_ptr.  These functions are the png_set_<chunk> and
+png_get_<chunk> functions.  These functions should be used when
+accessing/storing the info_struct data, rather than manipulating it
+directly, to avoid such problems in the future.
+
+It is important to note that the APIs do not make current programs
+that access the info struct directly incompatible with the new
+library.  However, it is strongly suggested that new programs use
+the new APIs (as shown in example.c), and older programs be converted
+to the new format, to facilitate upgrades in the future.
+****
+
+Additions since 0.90 include the ability to compile libpng as a
+Windows DLL, and new APIs for accessing data in the info struct.
+Experimental functions include the ability to set weighting and cost
+factors for row filter selection, direct reads of integers from buffers
+on big-endian processors that support misaligned data access, faster
+methods of doing alpha composition, and more accurate 16->8 bit color
+conversion.
+
+The additions since 0.89 include the ability to read from a PNG stream
+which has had some (or all) of the signature bytes read by the calling
+application.  This also allows the reading of embedded PNG streams that
+do not have the PNG file signature.  As well, it is now possible to set
+the library action on the detection of chunk CRC errors.  It is possible
+to set different actions based on whether the CRC error occurred in a
+critical or an ancillary chunk.
+
+The changes made to the library, and bugs fixed are based on discussions
+on the PNG implementation mailing list <png-implement@dworking.wustl.edu>
+and not on material submitted to Guy.
+
+For a detailed description on using libpng, read libpng.txt.  For
+examples of libpng in a program, see example.c and pngtest.c.  For usage
+information and restrictions (what little they are) on libpng, see
+png.h.  For a description on using zlib (the compression library used by
+libpng) and zlib's restrictions, see zlib.h
+
+I have included a general makefile, as well as several machine and
+compiler specific ones, but you may have to modify one for your own needs.
+
+You should use zlib 1.0.4 or later to run this, but it MAY work with
+versions as old as zlib 0.95.  Even so, there are bugs in older zlib
+versions which can cause the output of invalid compression streams for
+some images.  You will definitely need zlib 1.0.4 or later if you are
+taking advantage of the MS-DOS "far" structure allocation for the small
+and medium memory models.  You should also note that zlib is a
+compression library that is useful for more things than just PNG files.
+You can use zlib as a drop-in replacement for fread() and fwrite() if
+you are so inclined.
+
+zlib should be available at the same place that libpng is.
+If not, it should be at ftp.uu.net in /graphics/png
+Eventually, it will be at ftp.uu.net in /pub/archiving/zip/zlib
+
+You may also want a copy of the PNG specification.  It is available
+as an RFC and a W3C Recommendation.  Failing
+these resources you can try ftp.uu.net in the /graphics/png directory.
+
+This code is currently being archived at ftp.uu.net in the
+/graphics/png directory, and on CompuServe, Lib 20 (PNG SUPPORT)
+at GO GRAPHSUP.  If you can't find it in any of those places,
+e-mail me, and I'll help you find it.
+
+If you have any code changes, requests, problems, etc., please e-mail
+them to me.  Also, I'd appreciate any make files or project files,
+and any modifications you needed to make to get libpng to compile,
+along with a #define variable to tell what compiler/system you are on.
+If you needed to add transformations to libpng, or wish libpng would
+provide the image in a different way, drop me a note (and code, if
+possible), so I can consider supporting the transformation.
+Finally, if you get any warning messages when compiling libpng
+(note: not zlib), and they are easy to fix, I'd appreciate the
+fix.  Please mention "libpng" somewhere in the subject line.  Thanks.
+
+This release was created and will be supported by myself (of course
+based in a large way on Guy's and Andreas' earlier work), and the PNG group.
+
+randeg@alumni.rpi.edu
+png-implement@dworkin.wustl.edu
+
+You can't reach Guy, the original libpng author, at the addresses
+given in previous versions of this document.  He and Andreas will read mail
+addressed to the png-implement list, however.
+
+Please do not send general questions about PNG.  Send them to
+the address in the specification (png-group@w3.org).  At the same
+time, please do not send libpng questions to that address, send them to me
+or to png-implement@dworkin.wustl.edu.  I'll
+get them in the end anyway.  If you have a question about something
+in the PNG specification that is related to using libpng, send it
+to me.  Send me any questions that start with "I was using libpng,
+and ...".  If in doubt, send questions to me.  I'll bounce them
+to others, if necessary.
+
+Please do not send suggestions on how to change PNG.  We have
+been discussing PNG for three years now, and it is official and
+finished.  If you have suggestions for libpng, however, I'll
+gladly listen.  Even if your suggestion is not used for version
+1.0, it may be used later.
+
+Files in this distribution:
+
+      CHANGES       =>  Description of changes between libpng versions
+      README        =>  This file
+      TODO          =>  Things not implemented in the current library
+      ansi2knr.1    =>  Manual page for ansi2knr
+      ansi2knr.c    =>  Converts files to K&R style function declarations
+      build.bat     =>  MS-DOS batch file for Borland compiler
+      descrip.mms   =>  VMS project file
+      example.c     =>  Example code for using libpng functions
+      libpng.3      =>  manual page for libpng
+      libpng.txt    =>  Description of libpng and its functions
+      libpngpf.3    =>  manual page for libpng's private functions
+      png.5         =>  manual page for the PNG format
+      png.c         =>  Basic interface functions common to library
+      png.h         =>  Library function and interface declarations
+      pngconf.h     =>  System specific library configuration
+      pngerror.c    =>  Error/warning message I/O functions
+      pngget.c      =>  Functions for retrieving info from struct
+      pngmem.c      =>  Memory handling functions
+      pngpread.c    =>  Progressive reading functions
+      pngread.c     =>  Read data/helper high-level functions
+      pngrio.c      =>  Lowest-level data read I/O functions
+      pngrtran.c    =>  Read data transformation functions
+      pngrutil.c    =>  Read data utility functions
+      pngset.c      =>  Functions for storing data into the info_struct
+      pngtest.c     =>  Library test program
+      pngtest.png   =>  Library test sample image
+      pngtrans.c    =>  Common data transformation functions
+      pngwio.c      =>  Lowest-level write I/O functions
+      pngwrite.c    =>  High-level write functions
+      pngwtran.c    =>  Write data transformations
+      pngwutil.c    =>  Write utility functions
+      scripts       =>  Directory containing scripts for building libpng:
+        descrip.mms   =>  VMS makefile for MMS or MMK
+        makefile.std  =>  Generic UNIX makefile
+        makefile.knr  =>  Archaic UNIX Makefile that converts files with ansi2knr
+        makefile.dec  =>  DEC Alpha UNIX makefile
+        makefile.sgi  =>  Silicon Graphics IRIX makefile
+        makefile.sun  =>  Sun makefile
+        makefile.s2x  =>  Solaris 2.X makefile (gcc, creates libpng.so.2.1.0)
+        makefile.lnx  =>  Linux/ELF makefile (gcc, creates libpng.so.2.1.0)
+        makefile.mip  =>  MIPS makefile
+        makefile.aco  =>  Acorn makefile
+        makefile.ama  =>  Amiga makefile
+        smakefile.ppc =>  AMIGA smakefile for SAS C V6.58/7.00 PPC compiler
+                          (Requires SCOPTIONS, copied from scripts/SCOPTIONS.ppc)
+        makefile.atr  =>  Atari makefile
+        makefile.bor  =>  Borland makefile
+        build.bat     =>  MS-DOS batch file for Borland compiler
+        makefile.dj2  =>  DJGPP 2 makefile
+        makefile.msc  =>  Microsoft C makefile
+        makefile.tc3  =>  Turbo C 3.0 makefile
+        makefile.os2  =>  OS/2 Makefile (gcc and emx, requires pngos2.def)
+        makefile.wat  =>  Watcom 10a+ Makefile, 32-bit flat memory model
+        pngos2.def    =>  OS/2 module definition file used by makefile.os2
+        makevms.com   =>  VMS build script
+
+Good luck, and happy coding.
+
+-Glenn Randers-Pehrson
+ Internet: randeg@alumni.rpi.edu
+ Web: http://www.rpi.edu/~randeg/index.html
+
+-Andreas Eric Dilger
+ Internet: adilger@enel.ucalgary.ca
+ Web: http://www-mddsp.enel.ucalgary.ca/People/adilger/
+
+-Guy Eric Schalnat
+ (formerly of Group 42, Inc)
+ Internet: gschal@infinet.com
diff --git a/src/png/TODO b/src/png/TODO
new file mode 100644
index 0000000000..562859a22f
--- /dev/null
+++ b/src/png/TODO
@@ -0,0 +1,22 @@
+TODO - list of things to do for libpng
+
+fix problem with C++ and EXTERN "C"
+add "grayscale->palette" transformation and "palette->grayscale" detection
+add "grayscale" -> "grayscale+alpha" and "grayscale+FILLER" transformations
+improved dithering
+multi-lingual error and warning message support
+sPLT chunk handling
+cHRM transformation
+complete sRGB transformation (presently it simply uses gamma=0.45)
+man pages for function calls
+high-level API for reading images
+final bug fixes
+better documentation
+better filter selection
+   (counting huffman bits/precompression?  filter inertia?  filter costs?)
+optional palette creation
+histogram creation
+support for application-defined chunk handlers
+keep up with public chunks
+better C++ wrapper/full C++ implementation?
+text conversion between different code pages (Latin-1 -> Mac and DOS)
diff --git a/src/png/ansi2knr.1 b/src/png/ansi2knr.1
new file mode 100644
index 0000000000..f9ee5a631c
--- /dev/null
+++ b/src/png/ansi2knr.1
@@ -0,0 +1,36 @@
+.TH ANSI2KNR 1 "19 Jan 1996"
+.SH NAME
+ansi2knr \- convert ANSI C to Kernighan & Ritchie C
+.SH SYNOPSIS
+.I ansi2knr
+[--varargs] input_file [output_file]
+.SH DESCRIPTION
+If no output_file is supplied, output goes to stdout.
+.br
+There are no error messages.
+.sp
+.I ansi2knr
+recognizes function definitions by seeing a non-keyword identifier at the left
+margin, followed by a left parenthesis, with a right parenthesis as the last
+character on the line, and with a left brace as the first token on the
+following line (ignoring possible intervening comments).  It will recognize a
+multi-line header provided that no intervening line ends with a left or right
+brace or a semicolon.  These algorithms ignore whitespace and comments, except
+that the function name must be the first thing on the line.
+.sp
+The following constructs will confuse it:
+.br
+     - Any other construct that starts at the left margin and follows the
+above syntax (such as a macro or function call).
+.br
+     - Some macros that tinker with the syntax of the function header.
+.sp
+The --varargs switch is obsolete, and is recognized only for
+backwards compatibility.  The present version of
+.I ansi2knr
+will always attempt to convert a ... argument to va_alist and va_dcl.
+.SH AUTHOR
+L. Peter Deutsch <ghost@aladdin.com> wrote the original ansi2knr and
+continues to maintain the current version; most of the code in the current
+version is his work.  ansi2knr also includes contributions by Francois
+Pinard <pinard@iro.umontreal.ca> and Jim Avera <jima@netcom.com>.
diff --git a/src/png/ansi2knr.c b/src/png/ansi2knr.c
new file mode 100644
index 0000000000..4e05fc2d32
--- /dev/null
+++ b/src/png/ansi2knr.c
@@ -0,0 +1,693 @@
+/* ansi2knr.c */
+/* Convert ANSI C function definitions to K&R ("traditional C") syntax */
+
+/*
+ansi2knr is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY.  No author or distributor accepts responsibility to anyone for the
+consequences of using it or for whether it serves any particular purpose or
+works at all, unless he says so in writing.  Refer to the GNU General Public
+License (the "GPL") for full details.
+
+Everyone is granted permission to copy, modify and redistribute ansi2knr,
+but only under the conditions described in the GPL.  A copy of this license
+is supposed to have been given to you along with ansi2knr so you can know
+your rights and responsibilities.  It should be in a file named COPYLEFT.
+[In the IJG distribution, the GPL appears below, not in a separate file.]
+Among other things, the copyright notice and this notice must be preserved
+on all copies.
+
+We explicitly state here what we believe is already implied by the GPL: if
+the ansi2knr program is distributed as a separate set of sources and a
+separate executable file which are aggregated on a storage medium together
+with another program, this in itself does not bring the other program under
+the GPL, nor does the mere fact that such a program or the procedures for
+constructing it invoke the ansi2knr executable bring any other part of the
+program under the GPL.
+*/
+
+/*
+---------- Here is the GNU GPL file COPYLEFT, referred to above ----------
+----- These terms do NOT apply to the JPEG software itself; see README ------
+
+		    GHOSTSCRIPT GENERAL PUBLIC LICENSE
+		    (Clarified 11 Feb 1988)
+
+ Copyright (C) 1988 Richard M. Stallman
+ Everyone is permitted to copy and distribute verbatim copies of this
+ license, but changing it is not allowed.  You can also use this wording
+ to make the terms for other programs.
+
+  The license agreements of most software companies keep you at the
+mercy of those companies.  By contrast, our general public license is
+intended to give everyone the right to share Ghostscript.  To make sure
+that you get the rights we want you to have, we need to make
+restrictions that forbid anyone to deny you these rights or to ask you
+to surrender the rights.  Hence this license agreement.
+
+  Specifically, we want to make sure that you have the right to give
+away copies of Ghostscript, that you receive source code or else can get
+it if you want it, that you can change Ghostscript or use pieces of it
+in new free programs, and that you know you can do these things.
+
+  To make sure that everyone has such rights, we have to forbid you to
+deprive anyone else of these rights.  For example, if you distribute
+copies of Ghostscript, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must tell them their rights.
+
+  Also, for our own protection, we must make certain that everyone finds
+out that there is no warranty for Ghostscript.  If Ghostscript is
+modified by someone else and passed on, we want its recipients to know
+that what they have is not what we distributed, so that any problems
+introduced by others will not reflect on our reputation.
+
+  Therefore we (Richard M. Stallman and the Free Software Foundation,
+Inc.) make the following terms which say what you must do to be allowed
+to distribute or change Ghostscript.
+
+
+			COPYING POLICIES
+
+  1. You may copy and distribute verbatim copies of Ghostscript source
+code as you receive it, in any medium, provided that you conspicuously
+and appropriately publish on each copy a valid copyright and license
+notice "Copyright (C) 1989 Aladdin Enterprises.  All rights reserved.
+Distributed by Free Software Foundation, Inc." (or with whatever year is
+appropriate); keep intact the notices on all files that refer to this
+License Agreement and to the absence of any warranty; and give any other
+recipients of the Ghostscript program a copy of this License Agreement
+along with the program.  You may charge a distribution fee for the
+physical act of transferring a copy.
+
+  2. You may modify your copy or copies of Ghostscript or any portion of
+it, and copy and distribute such modifications under the terms of
+Paragraph 1 above, provided that you also do the following:
+
+    a) cause the modified files to carry prominent notices stating
+    that you changed the files and the date of any change; and
+
+    b) cause the whole of any work that you distribute or publish,
+    that in whole or in part contains or is a derivative of Ghostscript
+    or any part thereof, to be licensed at no charge to all third
+    parties on terms identical to those contained in this License
+    Agreement (except that you may choose to grant more extensive
+    warranty protection to some or all third parties, at your option).
+
+    c) You may charge a distribution fee for the physical act of
+    transferring a copy, and you may at your option offer warranty
+    protection in exchange for a fee.
+
+Mere aggregation of another unrelated program with this program (or its
+derivative) on a volume of a storage or distribution medium does not bring
+the other program under the scope of these terms.
+
+  3. You may copy and distribute Ghostscript (or a portion or derivative
+of it, under Paragraph 2) in object code or executable form under the
+terms of Paragraphs 1 and 2 above provided that you also do one of the
+following:
+
+    a) accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of
+    Paragraphs 1 and 2 above; or,
+
+    b) accompany it with a written offer, valid for at least three
+    years, to give any third party free (except for a nominal
+    shipping charge) a complete machine-readable copy of the
+    corresponding source code, to be distributed under the terms of
+    Paragraphs 1 and 2 above; or,
+
+    c) accompany it with the information you received as to where the
+    corresponding source code may be obtained.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form alone.)
+
+For an executable file, complete source code means all the source code for
+all modules it contains; but, as a special exception, it need not include
+source code for modules which are standard libraries that accompany the
+operating system on which the executable file runs.
+
+  4. You may not copy, sublicense, distribute or transfer Ghostscript
+except as expressly provided under this License Agreement.  Any attempt
+otherwise to copy, sublicense, distribute or transfer Ghostscript is
+void and your rights to use the program under this License agreement
+shall be automatically terminated.  However, parties who have received
+computer software programs from you with this License Agreement will not
+have their licenses terminated so long as such parties remain in full
+compliance.
+
+  5. If you wish to incorporate parts of Ghostscript into other free
+programs whose distribution conditions are different, write to the Free
+Software Foundation at 675 Mass Ave, Cambridge, MA 02139.  We have not
+yet worked out a simple rule that can be stated here, but we will often
+permit this.  We will be guided by the two goals of preserving the free
+status of all derivatives of our free software and of promoting the
+sharing and reuse of software.
+
+Your comments and suggestions about our licensing policies and our
+software are welcome!  Please contact the Free Software Foundation,
+Inc., 675 Mass Ave, Cambridge, MA 02139, or call (617) 876-3296.
+
+		       NO WARRANTY
+
+  BECAUSE GHOSTSCRIPT IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
+NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT
+WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, RICHARD
+M. STALLMAN, ALADDIN ENTERPRISES, L. PETER DEUTSCH, AND/OR OTHER PARTIES
+PROVIDE GHOSTSCRIPT "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
+EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE
+ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF GHOSTSCRIPT IS WITH
+YOU.  SHOULD GHOSTSCRIPT PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
+NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
+STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., L. PETER DEUTSCH, ALADDIN
+ENTERPRISES, AND/OR ANY OTHER PARTY WHO MAY MODIFY AND REDISTRIBUTE
+GHOSTSCRIPT AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING
+ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
+(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
+INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A FAILURE OF THE
+PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) GHOSTSCRIPT, EVEN IF YOU
+HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM
+BY ANY OTHER PARTY.
+
+-------------------- End of file COPYLEFT ------------------------------
+*/
+
+/*
+ * Usage:
+	ansi2knr input_file [output_file]
+ * If no output_file is supplied, output goes to stdout.
+ * There are no error messages.
+ *
+ * ansi2knr recognizes function definitions by seeing a non-keyword
+ * identifier at the left margin, followed by a left parenthesis,
+ * with a right parenthesis as the last character on the line,
+ * and with a left brace as the first token on the following line
+ * (ignoring possible intervening comments).
+ * It will recognize a multi-line header provided that no intervening
+ * line ends with a left or right brace or a semicolon.
+ * These algorithms ignore whitespace and comments, except that
+ * the function name must be the first thing on the line.
+ * The following constructs will confuse it:
+ *	- Any other construct that starts at the left margin and
+ *	    follows the above syntax (such as a macro or function call).
+ *	- Some macros that tinker with the syntax of the function header.
+ */
+
+/*
+ * The original and principal author of ansi2knr is L. Peter Deutsch
+ * <ghost@aladdin.com>.  Other authors are noted in the change history
+ * that follows (in reverse chronological order):
+	lpd 96-01-21 added code to cope with not HAVE_CONFIG_H and with
+		compilers that don't understand void, as suggested by
+		Tom Lane
+	lpd 96-01-15 changed to require that the first non-comment token
+		on the line following a function header be a left brace,
+		to reduce sensitivity to macros, as suggested by Tom Lane
+		<tgl@sss.pgh.pa.us>
+	lpd 95-06-22 removed #ifndefs whose sole purpose was to define
+		undefined preprocessor symbols as 0; changed all #ifdefs
+		for configuration symbols to #ifs
+	lpd 95-04-05 changed copyright notice to make it clear that
+		including ansi2knr in a program does not bring the entire
+		program under the GPL
+	lpd 94-12-18 added conditionals for systems where ctype macros
+		don't handle 8-bit characters properly, suggested by
+		Francois Pinard <pinard@iro.umontreal.ca>;
+		removed --varargs switch (this is now the default)
+	lpd 94-10-10 removed CONFIG_BROKETS conditional
+	lpd 94-07-16 added some conditionals to help GNU `configure',
+		suggested by Francois Pinard <pinard@iro.umontreal.ca>;
+		properly erase prototype args in function parameters,
+		contributed by Jim Avera <jima@netcom.com>;
+		correct error in writeblanks (it shouldn't erase EOLs)
+	lpd 89-xx-xx original version
+ */
+
+/* Most of the conditionals here are to make ansi2knr work with */
+/* or without the GNU configure machinery. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+
+#if HAVE_CONFIG_H
+
+/*
+   For properly autoconfiguring ansi2knr, use AC_CONFIG_HEADER(config.h).
+   This will define HAVE_CONFIG_H and so, activate the following lines.
+ */
+
+# if STDC_HEADERS || HAVE_STRING_H
+#  include <string.h>
+# else
+#  include <strings.h>
+# endif
+
+#else /* not HAVE_CONFIG_H */
+
+/* Otherwise do it the hard way */
+
+# ifdef BSD
+#  include <strings.h>
+# else
+#  ifdef VMS
+    extern int strlen(), strncmp();
+#  else
+#   include <string.h>
+#  endif
+# endif
+
+#endif /* not HAVE_CONFIG_H */
+
+#if STDC_HEADERS
+# include <stdlib.h>
+#else
+/*
+   malloc and free should be declared in stdlib.h,
+   but if you've got a K&R compiler, they probably aren't.
+ */
+# ifdef MSDOS
+#  include <malloc.h>
+# else
+#  ifdef VMS
+     extern char *malloc();
+     extern void free();
+#  else
+     extern char *malloc();
+     extern int free();
+#  endif
+# endif
+
+#endif
+
+/*
+ * The ctype macros don't always handle 8-bit characters correctly.
+ * Compensate for this here.
+ */
+#ifdef isascii
+#  undef HAVE_ISASCII		/* just in case */
+#  define HAVE_ISASCII 1
+#else
+#endif
+#if STDC_HEADERS || !HAVE_ISASCII
+#  define is_ascii(c) 1
+#else
+#  define is_ascii(c) isascii(c)
+#endif
+
+#define is_space(c) (is_ascii(c) && isspace(c))
+#define is_alpha(c) (is_ascii(c) && isalpha(c))
+#define is_alnum(c) (is_ascii(c) && isalnum(c))
+
+/* Scanning macros */
+#define isidchar(ch) (is_alnum(ch) || (ch) == '_')
+#define isidfirstchar(ch) (is_alpha(ch) || (ch) == '_')
+
+/* Forward references */
+char *skipspace();
+int writeblanks();
+int test1();
+int convert1();
+
+/* The main program */
+int
+main(argc, argv)
+    int argc;
+    char *argv[];
+{	FILE *in, *out;
+#define bufsize 5000			/* arbitrary size */
+	char *buf;
+	char *line;
+	char *more;
+	/*
+	 * In previous versions, ansi2knr recognized a --varargs switch.
+	 * If this switch was supplied, ansi2knr would attempt to convert
+	 * a ... argument to va_alist and va_dcl; if this switch was not
+	 * supplied, ansi2knr would simply drop any such arguments.
+	 * Now, ansi2knr always does this conversion, and we only
+	 * check for this switch for backward compatibility.
+	 */
+	int convert_varargs = 1;
+
+	if ( argc > 1 && argv[1][0] == '-' )
+	  {	if ( !strcmp(argv[1], "--varargs") )
+		  {	convert_varargs = 1;
+			argc--;
+			argv++;
+		  }
+		else
+		  {	fprintf(stderr, "Unrecognized switch: %s\n", argv[1]);
+			exit(1);
+		  }
+	  }
+	switch ( argc )
+	   {
+	default:
+		printf("Usage: ansi2knr input_file [output_file]\n");
+		exit(0);
+	case 2:
+		out = stdout;
+		break;
+	case 3:
+		out = fopen(argv[2], "w");
+		if ( out == NULL )
+		   {	fprintf(stderr, "Cannot open output file %s\n", argv[2]);
+			exit(1);
+		   }
+	   }
+	in = fopen(argv[1], "r");
+	if ( in == NULL )
+	   {	fprintf(stderr, "Cannot open input file %s\n", argv[1]);
+		exit(1);
+	   }
+	fprintf(out, "#line 1 \"%s\"\n", argv[1]);
+	buf = malloc(bufsize);
+	line = buf;
+	while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL )
+	   {
+test:		line += strlen(line);
+		switch ( test1(buf) )
+		   {
+		case 2:			/* a function header */
+			convert1(buf, out, 1, convert_varargs);
+			break;
+		case 1:			/* a function */
+			/* Check for a { at the start of the next line. */
+			more = ++line;
+f:			if ( line >= buf + (bufsize - 1) ) /* overflow check */
+			  goto wl;
+			if ( fgets(line, (unsigned)(buf + bufsize - line), in) == NULL )
+			  goto wl;
+			switch ( *skipspace(more, 1) )
+			  {
+			  case '{':
+			    /* Definitely a function header. */
+			    convert1(buf, out, 0, convert_varargs);
+			    fputs(more, out);
+			    break;
+			  case 0:
+			    /* The next line was blank or a comment: */
+			    /* keep scanning for a non-comment. */
+			    line += strlen(line);
+			    goto f;
+			  default:
+			    /* buf isn't a function header, but */
+			    /* more might be. */
+			    fputs(buf, out);
+			    strcpy(buf, more);
+			    line = buf;
+			    goto test;
+			  }
+			break;
+		case -1:		/* maybe the start of a function */
+			if ( line != buf + (bufsize - 1) ) /* overflow check */
+			  continue;
+			/* falls through */
+		default:		/* not a function */
+wl:			fputs(buf, out);
+			break;
+		   }
+		line = buf;
+	   }
+	if ( line != buf )
+	  fputs(buf, out);
+	free(buf);
+	fclose(out);
+	fclose(in);
+	return 0;
+}
+
+/* Skip over space and comments, in either direction. */
+char *
+skipspace(p, dir)
+    register char *p;
+    register int dir;			/* 1 for forward, -1 for backward */
+{	for ( ; ; )
+	   {	while ( is_space(*p) )
+		  p += dir;
+		if ( !(*p == '/' && p[dir] == '*') )
+		  break;
+		p += dir;  p += dir;
+		while ( !(*p == '*' && p[dir] == '/') )
+		   {	if ( *p == 0 )
+			  return p;	/* multi-line comment?? */
+			p += dir;
+		   }
+		p += dir;  p += dir;
+	   }
+	return p;
+}
+
+/*
+ * Write blanks over part of a string.
+ * Don't overwrite end-of-line characters.
+ */
+int
+writeblanks(start, end)
+    char *start;
+    char *end;
+{	char *p;
+	for ( p = start; p < end; p++ )
+	  if ( *p != '\r' && *p != '\n' )
+	    *p = ' ';
+	return 0;
+}
+
+/*
+ * Test whether the string in buf is a function definition.
+ * The string may contain and/or end with a newline.
+ * Return as follows:
+ *	0 - definitely not a function definition;
+ *	1 - definitely a function definition;
+ *	2 - definitely a function prototype (NOT USED);
+ *	-1 - may be the beginning of a function definition,
+ *		append another line and look again.
+ * The reason we don't attempt to convert function prototypes is that
+ * Ghostscript's declaration-generating macros look too much like
+ * prototypes, and confuse the algorithms.
+ */
+int
+test1(buf)
+    char *buf;
+{	register char *p = buf;
+	char *bend;
+	char *endfn;
+	int contin;
+
+	if ( !isidfirstchar(*p) )
+	  return 0;		/* no name at left margin */
+	bend = skipspace(buf + strlen(buf) - 1, -1);
+	switch ( *bend )
+	   {
+	   case ';': contin = 0 /*2*/; break;
+	   case ')': contin = 1; break;
+	   case '{': return 0;		/* not a function */
+	   case '}': return 0;		/* not a function */
+	   default: contin = -1;
+	   }
+	while ( isidchar(*p) )
+	  p++;
+	endfn = p;
+	p = skipspace(p, 1);
+	if ( *p++ != '(' )
+	  return 0;		/* not a function */
+	p = skipspace(p, 1);
+	if ( *p == ')' )
+	  return 0;		/* no parameters */
+	/* Check that the apparent function name isn't a keyword. */
+	/* We only need to check for keywords that could be followed */
+	/* by a left parenthesis (which, unfortunately, is most of them). */
+	   {	static char *words[] =
+		   {	"asm", "auto", "case", "char", "const", "double",
+			"extern", "float", "for", "if", "int", "long",
+			"register", "return", "short", "signed", "sizeof",
+			"static", "switch", "typedef", "unsigned",
+			"void", "volatile", "while", 0
+		   };
+		char **key = words;
+		char *kp;
+		int len = endfn - buf;
+
+		while ( (kp = *key) != 0 )
+		   {	if ( strlen(kp) == len && !strncmp(kp, buf, len) )
+			  return 0;	/* name is a keyword */
+			key++;
+		   }
+	   }
+	return contin;
+}
+
+/* Convert a recognized function definition or header to K&R syntax. */
+int
+convert1(buf, out, header, convert_varargs)
+    char *buf;
+    FILE *out;
+    int header;			/* Boolean */
+    int convert_varargs;	/* Boolean */
+{	char *endfn;
+	register char *p;
+	char **breaks;
+	unsigned num_breaks = 2;	/* for testing */
+	char **btop;
+	char **bp;
+	char **ap;
+	char *vararg = 0;
+
+	/* Pre-ANSI implementations don't agree on whether strchr */
+	/* is called strchr or index, so we open-code it here. */
+	for ( endfn = buf; *(endfn++) != '('; )
+	  ;
+top:	p = endfn;
+	breaks = (char **)malloc(sizeof(char *) * num_breaks * 2);
+	if ( breaks == 0 )
+	   {	/* Couldn't allocate break table, give up */
+		fprintf(stderr, "Unable to allocate break table!\n");
+		fputs(buf, out);
+		return -1;
+	   }
+	btop = breaks + num_breaks * 2 - 2;
+	bp = breaks;
+	/* Parse the argument list */
+	do
+	   {	int level = 0;
+		char *lp = NULL;
+		char *rp;
+		char *end = NULL;
+
+		if ( bp >= btop )
+		   {	/* Filled up break table. */
+			/* Allocate a bigger one and start over. */
+			free((char *)breaks);
+			num_breaks <<= 1;
+			goto top;
+		   }
+		*bp++ = p;
+		/* Find the end of the argument */
+		for ( ; end == NULL; p++ )
+		   {	switch(*p)
+			   {
+			   case ',':
+				if ( !level ) end = p;
+				break;
+			   case '(':
+				if ( !level ) lp = p;
+				level++;
+				break;
+			   case ')':
+				if ( --level < 0 ) end = p;
+				else rp = p;
+				break;
+			   case '/':
+				p = skipspace(p, 1) - 1;
+				break;
+			   default:
+				;
+			   }
+		   }
+		/* Erase any embedded prototype parameters. */
+		if ( lp )
+		  writeblanks(lp + 1, rp);
+		p--;			/* back up over terminator */
+		/* Find the name being declared. */
+		/* This is complicated because of procedure and */
+		/* array modifiers. */
+		for ( ; ; )
+		   {	p = skipspace(p - 1, -1);
+			switch ( *p )
+			   {
+			   case ']':	/* skip array dimension(s) */
+			   case ')':	/* skip procedure args OR name */
+			   {	int level = 1;
+				while ( level )
+				 switch ( *--p )
+				   {
+				   case ']': case ')': level++; break;
+				   case '[': case '(': level--; break;
+				   case '/': p = skipspace(p, -1) + 1; break;
+				   default: ;
+				   }
+			   }
+				if ( *p == '(' && *skipspace(p + 1, 1) == '*' )
+				   {	/* We found the name being declared */
+					while ( !isidfirstchar(*p) )
+					  p = skipspace(p, 1) + 1;
+					goto found;
+				   }
+				break;
+			   default:
+				goto found;
+			   }
+		   }
+found:		if ( *p == '.' && p[-1] == '.' && p[-2] == '.' )
+		  {	if ( convert_varargs )
+			  {	*bp++ = "va_alist";
+				vararg = p-2;
+			  }
+			else
+			  {	p++;
+				if ( bp == breaks + 1 )	/* sole argument */
+				  writeblanks(breaks[0], p);
+				else
+				  writeblanks(bp[-1] - 1, p);
+				bp--;
+			  }
+		   }
+		else
+		   {	while ( isidchar(*p) ) p--;
+			*bp++ = p+1;
+		   }
+		p = end;
+	   }
+	while ( *p++ == ',' );
+	*bp = p;
+	/* Make a special check for 'void' arglist */
+	if ( bp == breaks+2 )
+	   {	p = skipspace(breaks[0], 1);
+		if ( !strncmp(p, "void", 4) )
+		   {	p = skipspace(p+4, 1);
+			if ( p == breaks[2] - 1 )
+			   {	bp = breaks;	/* yup, pretend arglist is empty */
+				writeblanks(breaks[0], p + 1);
+			   }
+		   }
+	   }
+	/* Put out the function name and left parenthesis. */
+	p = buf;
+	while ( p != endfn ) putc(*p, out), p++;
+	/* Put out the declaration. */
+	if ( header )
+	  {	fputs(");", out);
+		for ( p = breaks[0]; *p; p++ )
+		  if ( *p == '\r' || *p == '\n' )
+		    putc(*p, out);
+	  }
+	else
+	  {	for ( ap = breaks+1; ap < bp; ap += 2 )
+		  {	p = *ap;
+			while ( isidchar(*p) )
+			  putc(*p, out), p++;
+			if ( ap < bp - 1 )
+			  fputs(", ", out);
+		  }
+		fputs(")  ", out);
+		/* Put out the argument declarations */
+		for ( ap = breaks+2; ap <= bp; ap += 2 )
+		  (*ap)[-1] = ';';
+		if ( vararg != 0 )
+		  {	*vararg = 0;
+			fputs(breaks[0], out);		/* any prior args */
+			fputs("va_dcl", out);		/* the final arg */
+			fputs(bp[0], out);
+		  }
+		else
+		  fputs(breaks[0], out);
+	  }
+	free((char *)breaks);
+	return 0;
+}
diff --git a/src/png/example.c b/src/png/example.c
new file mode 100644
index 0000000000..bc86aed6ea
--- /dev/null
+++ b/src/png/example.c
@@ -0,0 +1,688 @@
+
+/* example.c - an example of using libpng */
+
+/* This is an example of how to use libpng to read and write PNG files.
+ * The file libpng.txt is much more verbose then this.  If you have not
+ * read it, do so first.  This was designed to be a starting point of an
+ * implementation.  This is not officially part of libpng, and therefore
+ * does not require a copyright notice.
+ *
+ * This file does not currently compile, because it is missing certain
+ * parts, like allocating memory to hold an image.  You will have to
+ * supply these parts to get it to compile.  For an example of a minimal
+ * working PNG reader/writer, see pngtest.c, included in this distribution.
+ */
+
+#include "png.h"
+
+/* Check to see if a file is a PNG file using png_sig_cmp().  Returns
+ * non-zero if the image is a PNG, and 0 if it isn't a PNG.
+ *
+ * If this call is successful, and you are going to keep the file open,
+ * you should call png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK); once
+ * you have created the png_ptr, so that libpng knows your application
+ * has read that many bytes from the start of the file.  Make sure you
+ * don't call png_set_sig_bytes() with more than 8 bytes read or give it
+ * an incorrect number of bytes read, or you will either have read too
+ * many bytes (your fault), or you are telling libpng to read the wrong
+ * number of magic bytes (also your fault).
+ *
+ * Many applications already read the first 2 or 4 bytes from the start
+ * of the image to determine the file type, so it would be easiest just
+ * to pass the bytes to png_sig_cmp() or even skip that if you know
+ * you have a PNG file, and call png_set_sig_bytes().
+ */
+#define PNG_BYTES_TO_CHECK 4
+int check_if_png(char *file_name, FILE **fp)
+{
+   char buf[PNG_BYTES_TO_CHECK];
+
+   /* Open the prospective PNG file. */
+   if ((*fp = fopen(file_name, "rb")) != NULL);
+      return 0;
+
+   /* Read in the signature bytes */
+   if (fread(buf, 1, PNG_BYTES_TO_CHECK, *fp) != PNG_BYTES_TO_CHECK)
+      return 0;
+
+   /* Compare the first PNG_BYTES_TO_CHECK bytes of the signature. */
+   return(png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK));
+}
+
+/* Read a PNG file.  You may want to return an error code if the read
+ * fails (depending upon the failure).  There are two "prototypes" given
+ * here - one where we are given the filename, and we need to open the
+ * file, and the other where we are given an open file (possibly with
+ * some or all of the magic bytes read - see comments above).
+ */
+#ifdef open_file /* prototype 1 */
+void read_png(char *file_name)  /* We need to open the file */
+{
+   png_structp png_ptr;
+   png_infop info_ptr;
+   unsigned int sig_read = 0;
+   png_uint_32 width, height;
+   int bit_depth, color_type, interlace_type;
+   FILE *fp;
+
+   if ((fp = fopen(file_name, "rb")) == NULL)
+      return;
+#else no_open_file /* prototype 2 */
+void read_png(FILE *fp, unsigned int sig_read)  /* file is already open */
+{
+   png_structp png_ptr;
+   png_infop info_ptr;
+   png_uint_32 width, height;
+   int bit_depth, color_type, interlace_type;
+#endif no_open_file /* only use one prototype! */
+
+   /* Create and initialize the png_struct with the desired error handler
+    * functions.  If you want to use the default stderr and longjump method,
+    * you can supply NULL for the last three parameters.  We also supply the
+    * the compiler header file version, so that we know if the application
+    * was compiled with a compatible version of the library.  REQUIRED
+    */
+   png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
+      (void *)user_error_ptr, user_error_fn, user_warning_fn);
+
+   if (png_ptr == NULL)
+   {
+      fclose(fp);
+      return;
+   }
+
+   /* Allocate/initialize the memory for image information.  REQUIRED. */
+   info_ptr = png_create_info_struct(png_ptr);
+   if (info_ptr == NULL)
+   {
+      fclose(fp);
+      png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
+      return;
+   }
+
+   /* Set error handling if you are using the setjmp/longjmp method (this is
+    * the normal method of doing things with libpng).  REQUIRED unless you
+    * set up your own error handlers in the png_create_read_struct() earlier.
+    */
+   if (setjmp(png_ptr->jmpbuf))
+   {
+      /* Free all of the memory associated with the png_ptr and info_ptr */
+      png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
+      fclose(fp);
+      /* If we get here, we had a problem reading the file */
+      return;
+   }
+
+   /* One of the following I/O initialization methods is REQUIRED */
+#ifdef streams /* PNG file I/O method 1 */
+   /* Set up the input control if you are using standard C streams */
+   png_init_io(png_ptr, fp);
+
+#else no_streams /* PNG file I/O method 2 */
+   /* If you are using replacement read functions, instead of calling
+    * png_init_io() here you would call:
+    */
+   png_set_read_fn(png_ptr, (void *)user_io_ptr, user_read_fn);
+   /* where user_io_ptr is a structure you want available to the callbacks */
+#endif no_streams /* Use only one I/O method! */
+
+   /* If we have already read some of the signature */
+   png_set_sig_bytes(png_ptr, sig_read);
+
+   /* The call to png_read_info() gives us all of the information from the
+    * PNG file before the first IDAT (image data chunk).  REQUIRED
+    */
+   png_read_info(png_ptr, info_ptr);
+
+   png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
+       &interlace_type, NULL, NULL);
+
+/**** Set up the data transformations you want.  Note that these are all
+ **** optional.  Only call them if you want/need them.  Many of the
+ **** transformations only work on specific types of images, and many
+ **** are mutually exclusive.
+ ****/
+
+   /* tell libpng to strip 16 bit/color files down to 8 bits/color */
+   png_set_strip_16(png_ptr);
+
+   /* Strip alpha bytes from the input data without combining with th
+    * background (not recommended).
+    */
+   png_set_strip_alpha(png_ptr);
+
+   /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
+    * byte into separate bytes (useful for paletted and grayscale images).
+    */
+   png_set_packing(png_ptr);
+
+   /* Change the order of packed pixels to least significant bit first
+    * (not useful if you are using png_set_packing). */
+   png_set_packswap(png_ptr);
+
+   /* Expand paletted colors into true RGB triplets */
+   if (color_type == PNG_COLOR_TYPE_PALETTE)
+      png_set_expand(png_ptr);
+
+   /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */
+   if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
+      png_set_expand(png_ptr);
+
+   /* Expand paletted or RGB images with transparency to full alpha channels
+    * so the data will be available as RGBA quartets.
+    */
+   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
+      png_set_expand(png_ptr);
+
+   /* Set the background color to draw transparent and alpha images over.
+    * It is possible to set the red, green, and blue components directly
+    * for paletted images instead of supplying a palette index.  Note that
+    * even if the PNG file supplies a background, you are not required to
+    * use it - you should use the (solid) application background if it has one.
+    */
+
+   png_color_16 my_background, *image_background;
+
+   if (png_get_bKGD(png_ptr, info_ptr, &image_background))
+      png_set_background(png_ptr, image_background,
+                         PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
+   else
+      png_set_background(png_ptr, &my_background,
+                         PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+
+   /* Some suggestions as to how to get a screen gamma value */
+
+   /* Note that screen gamma is (display_gamma/viewing_gamma) */
+   if (/* We have a user-defined screen gamma value */)
+   {
+      screen_gamma = user-defined screen_gamma;
+   }
+   /* This is one way that applications share the same screen gamma value */
+   else if ((gamma_str = getenv("SCREEN_GAMMA")) != NULL)
+   {
+      screen_gamma = atof(gamma_str);
+   }
+   /* If we don't have another value */
+   else
+   {
+      screen_gamma = 2.2;  /* A good guess for a PC monitors in a dimly
+                              lit room */
+      screen_gamma = 1.7 or 1.0;  /* A good guess for Mac systems */
+   }
+
+   /* Tell libpng to handle the gamma conversion for you.  The second call
+    * is a good guess for PC generated images, but it should be configurable
+    * by the user at run time by the user.  It is strongly suggested that
+    * your application support gamma correction.
+    */
+
+   int intent;
+
+   if (png_get_sRGB(png_ptr, info_ptr, &intent))
+      png_set_sRGB(png_ptr, intent, 0);
+   else 
+      if (png_get_gAMA(png_ptr, info_ptr, &image_gamma))
+         png_set_gamma(png_ptr, screen_gamma, image_gamma);
+      else
+         png_set_gamma(png_ptr, screen_gamma, 0.50);
+
+   /* Dither RGB files down to 8 bit palette or reduce palettes
+    * to the number of colors available on your screen.
+    */
+   if (color_type & PNG_COLOR_MASK_COLOR)
+   {
+      png_uint_32 num_palette;
+      png_colorp palette;
+
+      /* This reduces the image to the application supplied palette */
+      if (/* we have our own palette */)
+      {
+         /* An array of colors to which the image should be dithered */
+         png_color std_color_cube[MAX_SCREEN_COLORS];
+
+         png_set_dither(png_ptr, std_color_cube, MAX_SCREEN_COLORS,
+            MAX_SCREEN_COLORS, NULL, 0);
+      }
+      /* This reduces the image to the palette supplied in the file */
+      else if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette))
+      {
+         png_color16p histogram;
+
+         png_get_hIST(png_ptr, info_ptr, &histogram);
+
+         png_set_dither(png_ptr, palette, num_palette,
+                        max_screen_colors, histogram, 0);
+      }
+   }
+
+   /* invert monocrome files to have 0 as white and 1 as black */
+   png_set_invert_mono(png_ptr);
+
+   /* If you want to shift the pixel values from the range [0,255] or
+    * [0,65535] to the original [0,7] or [0,31], or whatever range the
+    * colors were originally in:
+    */
+   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
+   {
+      png_color8p sig_bit;
+
+      png_get_sBIT(png_ptr, info_ptr, &sig_bit);
+      png_set_shift(png_ptr, sig_bit);
+   }
+
+   /* flip the RGB pixels to BGR (or RGBA to BGRA) */
+   png_set_bgr(png_ptr);
+
+   /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
+   png_set_swap_alpha(png_ptr);
+
+   /* swap bytes of 16 bit files to least significant byte first */
+   png_set_swap(png_ptr);
+
+   /* Add filler (or alpha) byte (before/after each RGB triplet) */
+   png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
+
+   /* Turn on interlace handling.  REQUIRED if you are not using
+    * png_read_image().  To see how to handle interlacing passes,
+    * see the png_read_row() method below:
+    */
+   number_passes = png_set_interlace_handling(png_ptr);
+
+   /* Optional call to gamma correct and add the background to the palette
+    * and update info structure.  REQUIRED if you are expecting libpng to
+    * update the palette for you (ie you selected such a transform above).
+    */
+   png_read_update_info(png_ptr, info_ptr);
+
+   /* Allocate the memory to hold the image using the fields of info_ptr. */
+
+   /* The easiest way to read the image: */
+   png_bytep row_pointers[height];
+
+   for (row = 0; row < height; row++)
+   {
+      row_pointers[row] = malloc(png_get_rowbytes(png_ptr, info_ptr));
+   }
+
+   /* Now it's time to read the image.  One of these methods is REQUIRED */
+#ifdef entire /* Read the entire image in one go */
+   png_read_image(png_ptr, row_pointers);
+
+#else no_entire /* Read the image one or more scanlines at a time */
+   /* The other way to read images - deal with interlacing: */
+
+   for (pass = 0; pass < number_passes; pass++)
+   {
+#ifdef single /* Read the image a single row at a time */
+      for (y = 0; y < height; y++)
+      {
+         png_bytep row_pointers = row[y];
+         png_read_rows(png_ptr, &row_pointers, NULL, 1);
+      }
+
+#else no_single /* Read the image several rows at a time */
+      for (y = 0; y < height; y += number_of_rows)
+      {
+#ifdef sparkle /* Read the image using the "sparkle" effect. */
+         png_read_rows(png_ptr, row_pointers, NULL, number_of_rows);
+        
+#else no_sparkle /* Read the image using the "rectangle" effect */
+         png_read_rows(png_ptr, NULL, row_pointers, number_of_rows);
+#endif no_sparkle /* use only one of these two methods */
+      }
+     
+      /* if you want to display the image after every pass, do
+         so here */
+#endif no_single /* use only one of these two methods */
+   }
+#endif no_entire /* use only one of these two methods */
+
+   /* read rest of file, and get additional chunks in info_ptr - REQUIRED */
+   png_read_end(png_ptr, info_ptr);
+
+   /* clean up after the read, and free any memory allocated - REQUIRED */
+   png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
+
+   /* close the file */
+   fclose(fp);
+
+   /* that's it */
+   return;
+}
+
+/* progressively read a file */
+
+int
+initialize_png_reader(png_structp *png_ptr, png_infop *info_ptr)
+{
+   /* Create and initialize the png_struct with the desired error handler
+    * functions.  If you want to use the default stderr and longjump method,
+    * you can supply NULL for the last three parameters.  We also check that
+    * the library version is compatible in case we are using dynamically
+    * linked libraries.
+    */
+   *png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
+       (void *)user_error_ptr, user_error_fn, user_warning_fn);
+
+   if (*png_ptr == NULL)
+   {
+      *info_ptr = NULL;
+      return ERROR;
+   }
+
+   *info_ptr = png_create_info_struct(png_ptr);
+
+   if (*info_ptr == NULL)
+   {
+      png_destroy_read_struct(png_ptr, info_ptr, (png_infopp)NULL);
+      return ERROR;
+   }
+
+   if (setjmp((*png_ptr)->jmpbuf))
+   {
+      png_destroy_read_struct(png_ptr, info_ptr, (png_infopp)NULL);
+      return ERROR;
+   }
+
+   /* this one's new.  You will need to provide all three
+    * function callbacks, even if you aren't using them all.
+    * These functions shouldn't be dependent on global or
+    * static variables if you are decoding several images
+    * simultaneously.  You should store stream specific data
+    * in a separate struct, given as the second parameter,
+    * and retrieve the pointer from inside the callbacks using
+    * the function png_get_progressive_ptr(png_ptr).
+    */
+   png_set_progressive_read_fn(*png_ptr, (void *)stream_data,
+      info_callback, row_callback, end_callback);
+
+   return OK;
+}
+
+int
+process_data(png_structp *png_ptr, png_infop *info_ptr,
+   png_bytep buffer, png_uint_32 length)
+{
+   if (setjmp((*png_ptr)->jmpbuf))
+   {
+      /* Free the png_ptr and info_ptr memory on error */
+      png_destroy_read_struct(png_ptr, info_ptr, (png_infopp)NULL);
+      return ERROR;
+   }
+
+   /* This one's new also.  Simply give it chunks of data as
+    * they arrive from the data stream (in order, of course).
+    * On Segmented machines, don't give it any more than 64K.
+    * The library seems to run fine with sizes of 4K, although
+    * you can give it much less if necessary (I assume you can
+    * give it chunks of 1 byte, but I haven't tried with less
+    * than 256 bytes yet).  When this function returns, you may
+    * want to display any rows that were generated in the row
+    * callback, if you aren't already displaying them there.
+    */
+   png_process_data(*png_ptr, *info_ptr, buffer, length);
+   return OK;
+}
+
+info_callback(png_structp png_ptr, png_infop info)
+{
+/* do any setup here, including setting any of the transformations
+ * mentioned in the Reading PNG files section.  For now, you _must_
+ * call either png_start_read_image() or png_read_update_info()
+ * after all the transformations are set (even if you don't set
+ * any).  You may start getting rows before png_process_data()
+ * returns, so this is your last chance to prepare for that.
+ */
+}
+
+row_callback(png_structp png_ptr, png_bytep new_row,
+   png_uint_32 row_num, int pass)
+{
+/* this function is called for every row in the image.  If the
+ * image is interlacing, and you turned on the interlace handler,
+ * this function will be called for every row in every pass.
+ * Some of these rows will not be changed from the previous pass.
+ * When the row is not changed, the new_row variable will be NULL.
+ * The rows and passes are called in order, so you don't really
+ * need the row_num and pass, but I'm supplying them because it
+ * may make your life easier.
+ *
+ * For the non-NULL rows of interlaced images, you must call
+ * png_progressive_combine_row() passing in the row and the
+ * old row.  You can call this function for NULL rows (it will
+ * just return) and for non-interlaced images (it just does the
+ * memcpy for you) if it will make the code easier.  Thus, you
+ * can just do this for all cases:
+ */
+
+   png_progressive_combine_row(png_ptr, old_row, new_row);
+
+/* where old_row is what was displayed for previous rows.  Note
+ * that the first pass (pass == 0 really) will completely cover
+ * the old row, so the rows do not have to be initialized.  After
+ * the first pass (and only for interlaced images), you will have
+ * to pass the current row, and the function will combine the
+ * old row and the new row.
+ */
+}
+
+end_callback(png_structp png_ptr, png_infop info)
+{
+/* this function is called when the whole image has been read,
+ * including any chunks after the image (up to and including
+ * the IEND).  You will usually have the same info chunk as you
+ * had in the header, although some data may have been added
+ * to the comments and time fields.
+ *
+ * Most people won't do much here, perhaps setting a flag that
+ * marks the image as finished.
+ */
+}
+
+/* write a png file */
+void write_png(char *file_name /* , ... other image information ... */)
+{
+   FILE *fp;
+   png_structp png_ptr;
+   png_infop info_ptr;
+
+   /* open the file */
+   fp = fopen(file_name, "wb");
+   if (fp == NULL)
+      return;
+
+   /* Create and initialize the png_struct with the desired error handler
+    * functions.  If you want to use the default stderr and longjump method,
+    * you can supply NULL for the last three parameters.  We also check that
+    * the library version is compatible with the one used at compile time,
+    * in case we are using dynamically linked libraries.  REQUIRED.
+    */
+   png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
+      (void *)user_error_ptr, user_error_fn, user_warning_fn);
+
+   if (png_ptr == NULL)
+   {
+      fclose(fp);
+      return;
+   }
+
+   /* Allocate/initialize the image information data.  REQUIRED */
+   info_ptr = png_create_info_struct(png_ptr);
+   if (info_ptr == NULL)
+   {
+      fclose(fp);
+      png_destroy_write_struct(&png_ptr,  (png_infopp)NULL);
+      return;
+   }
+
+   /* Set error handling.  REQUIRED if you aren't supplying your own
+    * error hadnling functions in the png_create_write_struct() call.
+    */
+   if (setjmp(png_ptr->jmpbuf))
+   {
+      /* If we get here, we had a problem reading the file */
+      fclose(fp);
+      png_destroy_write_struct(&png_ptr,  (png_infopp)NULL);
+      return;
+   }
+
+   /* One of the following I/O initialization functions is REQUIRED */
+#ifdef streams /* I/O initialization method 1 */
+   /* set up the output control if you are using standard C streams */
+   png_init_io(png_ptr, fp);
+#else no_streams /* I/O initialization method 2 */
+   /* If you are using replacement read functions, instead of calling
+    * png_init_io() here you would call */
+   png_set_write_fn(png_ptr, (void *)user_io_ptr, user_write_fn,
+      user_IO_flush_function);
+   /* where user_io_ptr is a structure you want available to the callbacks */
+#endif no_streams /* only use one initialization method */
+
+   /* Set the image information here.  Width and height are up to 2^31,
+    * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
+    * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
+    * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
+    * or PNG_COLOR_TYPE_RGB_ALPHA.  interlace is either PNG_INTERLACE_NONE or
+    * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
+    * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
+    */
+   png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, PNG_COLOR_TYPE_???,
+      PNG_INTERLACE_????, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+   /* set the palette if there is one.  REQUIRED for indexed-color images */
+   palette = (png_colorp)png_malloc(png_ptr, 256 * sizeof (png_color));
+   /* ... set palette colors ... */
+   png_set_PLTE(png_ptr, info_ptr, palette, 256);
+
+   /* optional significant bit chunk */
+   /* if we are dealing with a grayscale image then */
+   sig_bit.gray = true_bit_depth;
+   /* otherwise, if we are dealing with a color image then */
+   sig_bit.red = true_red_bit_depth;
+   sig_bit.green = true_green_bit_depth;
+   sig_bit.blue = true_blue_bit_depth;
+   /* if the image has an alpha channel then */
+   sig_bit.alpha = true_alpha_bit_depth;
+   png_set_sBIT(png_ptr, info_ptr, sig_bit);
+
+  
+   /* Optional gamma chunk is strongly suggested if you have any guess
+    * as to the correct gamma of the image.
+    */
+   png_set_gAMA(png_ptr, info_ptr, gamma);
+
+   /* Optionally write comments into the image */
+   text_ptr[0].key = "Title";
+   text_ptr[0].text = "Mona Lisa";
+   text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
+   text_ptr[1].key = "Author";
+   text_ptr[1].text = "Leonardo DaVinci";
+   text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE;
+   text_ptr[2].key = "Description";
+   text_ptr[2].text = "<long text>";
+   text_ptr[2].compression = PNG_TEXT_COMPRESSION_zTXt;
+   png_set_text(png_ptr, info_ptr, text_ptr, 2);
+
+   /* other optional chunks like cHRM, bKGD, tRNS, tIME, oFFs, pHYs, */
+   /* note that if sRGB is present the cHRM chunk must be ignored
+    * on read and must be written in accordance with the sRGB profile */
+
+   /* Write the file header information.  REQUIRED */
+   png_write_info(png_ptr, info_ptr);
+
+   /* Once we write out the header, the compression type on the text
+    * chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or
+    * PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again
+    * at the end.
+    */
+
+   /* set up the transformations you want.  Note that these are
+    * all optional.  Only call them if you want them.
+    */
+
+   /* invert monocrome pixels */
+   png_set_invert_mono(png_ptr);
+
+   /* Shift the pixels up to a legal bit depth and fill in
+    * as appropriate to correctly scale the image.
+    */
+   png_set_shift(png_ptr, &sig_bit);
+
+   /* pack pixels into bytes */
+   png_set_packing(png_ptr);
+
+   /* swap location of alpha bytes from ARGB to RGBA */
+   png_set_swap_alpha(png_ptr);
+
+   /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into
+    * RGB (4 channels -> 3 channels). The second parameter is not used.
+    */
+   png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
+
+   /* flip BGR pixels to RGB */
+   png_set_bgr(png_ptr);
+
+   /* swap bytes of 16-bit files to most significant byte first */
+   png_set_swap(png_ptr);
+
+   /* swap bits of 1, 2, 4 bit packed pixel formats */
+   png_set_packswap(png_ptr);
+
+   /* turn on interlace handling if you are not using png_write_image() */
+   if (interlacing)
+      number_passes = png_set_interlace_handling(png_ptr);
+   else
+      number_passes = 1;
+
+   /* The easiest way to write the image (you may have a different memory
+    * layout, however, so choose what fits your needs best).  You need to
+    * use the first method if you aren't handling interlacing yourself.
+    */
+   png_byte row_pointers[height][width];
+
+   /* One of the following output methods is REQUIRED */
+#ifdef entire /* write out the entire image data in one call */
+   png_write_image(png_ptr, row_pointers);
+
+   /* the other way to write the image - deal with interlacing */
+
+#else no_entire /* write out the image data by one or more scanlines */
+   /* The number of passes is either 1 for non-interlaced images,
+    * or 7 for interlaced images.
+    */
+   for (pass = 0; pass < number_passes; pass++)
+   {
+      /* Write a few rows at a time. */
+      png_write_rows(png_ptr, row_pointers, number_of_rows);
+
+      /* If you are only writing one row at a time, this works */
+      for (y = 0; y < height; y++)
+      {
+         png_bytep row_pointers = row[y];
+         png_write_rows(png_ptr, &row_pointers, 1);
+      }
+   }
+#endif no_entire /* use only one output method */
+
+   /* You can write optional chunks like tEXt, zTXt, and tIME at the end
+    * as well.
+    */
+
+   /* It is REQUIRED to call this to finish writing the rest of the file */
+   png_write_end(png_ptr, info_ptr);
+
+   /* if you malloced the palette, free it here */
+   free(info_ptr->palette);
+
+   /* if you allocated any text comments, free them here */
+
+   /* clean up after the write, and free any memory allocated */
+   png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
+
+   /* close the file */
+   fclose(fp);
+
+   /* that's it */
+   return;
+}
+
diff --git a/src/png/libpng.3 b/src/png/libpng.3
new file mode 100644
index 0000000000..88d8c9642c
--- /dev/null
+++ b/src/png/libpng.3
@@ -0,0 +1,2409 @@
+.TH LIBPNG 3 "March 15, 1998"
+.SH NAME
+libpng \- Portable Network Graphics (PNG) Reference Library
+.SH SYNOPSIS
+
+#include <png.h>
+
+int png_check_sig (png_bytep sig, int num);
+
+void png_chunk_error (png_structp png_ptr, png_const_charp
+error);
+
+void png_chunk_warning (png_structp png_ptr, png_const_charp
+message);
+
+void png_convert_from_struct_tm (png_timep ptime, struct tm FAR
+* ttime);
+
+void png_convert_from_time_t (png_timep ptime, time_t ttime);
+
+png_charp png_convert_to_rfc1123 (png_structp png_ptr,
+png_timep ptime);
+
+png_infop png_create_info_struct (png_structp png_ptr);
+
+png_structp png_create_read_struct (png_const_charp
+user_png_ver, voidp error_ptr, png_error_ptr error_fn,
+png_error_ptr warn_fn);
+
+png_structp png_create_write_struct (png_const_charp
+user_png_ver, voidp error_ptr, png_error_ptr error_fn,
+png_error_ptr warn_fn);
+
+void png_debug_free (png_structp png_ptr, png_voidp ptr);
+
+png_voidp png_debug_malloc (png_structp png_ptr, png_uint_32
+size);
+
+void png_destroy_info_struct (png_structp png_ptr, png_infopp
+info_ptr_ptr);
+
+void png_destroy_read_struct (png_structpp png_ptr_ptr,
+png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr);
+
+void png_destroy_write_struct (png_structpp png_ptr_ptr,
+png_infopp info_ptr_ptr);
+
+void png_error (png_structp png_ptr, png_const_charp error);
+
+void png_free (png_structp png_ptr, png_voidp ptr);
+
+png_byte png_get_bit_depth (png_structp png_ptr, png_infop
+info_ptr);
+
+png_uint_32 png_get_bKGD (png_structp png_ptr, png_infop
+info_ptr, png_color_16p *background);
+
+png_byte png_get_channels (png_structp png_ptr, png_infop
+info_ptr);
+
+png_uint_32 png_get_cHRM (png_structp png_ptr, png_infop
+info_ptr, double *white_x, double *white_y, double *red_x,
+double *red_y, double *green_x, double *green_y, double
+*blue_x, double *blue_y);
+
+png_byte png_get_color_type (png_structp png_ptr, png_infop
+info_ptr);
+
+png_byte png_get_compression_type (png_structp png_ptr,
+png_infop info_ptr);
+
+png_voidp png_get_error_ptr (png_structp png_ptr);
+
+png_byte png_get_filter_type (png_structp png_ptr, png_infop
+info_ptr);
+
+png_uint_32 png_get_gAMA (png_structp png_ptr, png_infop
+info_ptr, double *file_gamma);
+
+png_uint_32 png_get_hIST (png_structp png_ptr, png_infop
+info_ptr, png_uint_16p *hist);
+
+png_uint_32 png_get_image_height (png_structp png_ptr,
+png_infop info_ptr);
+
+png_uint_32 png_get_image_width (png_structp png_ptr, png_infop
+info_ptr);
+
+png_byte png_get_interlace_type (png_structp png_ptr, png_infop
+info_ptr);
+
+png_voidp png_get_io_ptr (png_structp png_ptr);
+
+png_uint_32 png_get_IHDR (png_structp png_ptr, png_infop
+info_ptr, png_uint_32 *width, png_uint_32 *height, int
+*bit_depth, int *color_type, int *interlace_type, int
+*compression_type, int *filter_type);
+
+png_uint_32 png_get_oFFs (png_structp png_ptr, png_infop
+info_ptr, png_uint_32 *offset_x, png_uint_32 *offset_y, int
+*unit_type);
+
+png_uint_32 png_get_pCAL (png_structp png_ptr, png_infop
+info_ptr, png_charp *purpose, png_int_32 *X0, png_int_32 *X1,
+int *type, int *nparams, png_charp *units, png_charpp *params);
+
+png_uint_32 png_get_pHYs (png_structp png_ptr, png_infop
+info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int
+*unit_type);
+
+float png_get_pixel_aspect_ratio (png_structp png_ptr,
+png_infop info_ptr);
+
+png_uint_32 png_get_pixels_per_meter (png_structp png_ptr,
+png_infop info_ptr);
+
+png_voidp png_get_progressive_ptr (png_structp png_ptr);
+
+png_uint_32 png_get_PLTE (png_structp png_ptr, png_infop
+info_ptr, png_colorp *palette, int *num_palette);
+
+png_uint_32 png_get_rowbytes (png_structp png_ptr, png_infop
+info_ptr);
+
+png_uint_32 png_get_sBIT (png_structp png_ptr, png_infop
+info_ptr, png_color_8p *sig_bit);
+
+png_bytep png_get_signature (png_structp png_ptr, png_infop
+info_ptr);
+
+png_uint_32 png_get_sRGB (png_structp png_ptr, png_infop
+info_ptr, int *intent);
+
+png_uint_32 png_get_text (png_structp png_ptr, png_infop
+info_ptr, png_textp *text_ptr, int *num_text);
+
+png_uint_32 png_get_tIME (png_structp png_ptr, png_infop
+info_ptr, png_timep *mod_time);
+
+png_uint_32 png_get_tRNS (png_structp png_ptr, png_infop
+info_ptr, png_bytep *trans, int *num_trans, png_color_16p
+*trans_values);
+
+png_uint_32 png_get_valid (png_structp png_ptr, png_infop
+info_ptr, png_uint_32 flag);
+
+png_uint_32 png_get_x_offset_microns (png_structp png_ptr,
+png_infop info_ptr);
+
+png_uint_32 png_get_x_offset_pixels (png_structp png_ptr,
+png_infop info_ptr);
+
+png_uint_32 png_get_x_pixels_per_meter (png_structp png_ptr,
+png_infop info_ptr);
+
+png_uint_32 png_get_y_offset_microns (png_structp png_ptr,
+png_infop info_ptr);
+
+png_uint_32 png_get_y_offset_pixels (png_structp png_ptr,
+png_infop info_ptr);
+
+png_uint_32 png_get_y_pixels_per_meter (png_structp png_ptr,
+png_infop info_ptr);
+
+void png_info_init (png_infop info_ptr);
+
+void png_init_io (png_structp png_ptr, FILE *fp);
+
+png_voidp png_malloc (png_structp png_ptr, png_uint_32 size);
+
+voidp png_memcpy (png_voidp s1, png_voidp s2, png_size_t size);
+
+png_voidp png_memcpy_check (png_structp png_ptr, png_voidp s1,
+png_voidp s2, png_uint_32 size);
+
+voidp png_memset (png_voidp s1, int value, png_size_t size);
+
+png_voidp png_memset_check (png_structp png_ptr, png_voidp
+s1, int value, png_uint_32 size);
+
+void png_process_data (png_structp png_ptr, png_infop info_ptr,
+png_bytep buffer, png_size_t buffer_size);
+
+void png_progressive_combine_row (png_structp png_ptr,
+png_bytep old_row, png_bytep new_row);
+
+void png_read_destroy (png_structp png_ptr, png_infop info_ptr,
+png_infop end_info_ptr);
+
+void png_read_end (png_structp png_ptr, png_infop info_ptr);
+
+void png_read_image (png_structp png_ptr, png_bytepp image);
+
+void png_read_info (png_structp png_ptr, png_infop info_ptr);
+
+void png_read_row (png_structp png_ptr, png_bytep row,
+png_bytep display_row);
+
+void png_read_rows (png_structp png_ptr, png_bytepp row,
+png_bytepp display_row, png_uint_32 num_rows);
+
+void png_read_update_info (png_structp png_ptr, png_infop
+info_ptr);
+
+void png_set_background (png_structp png_ptr, png_color_16p
+background_color, int background_gamma_code, int need_expand,
+double background_gamma);
+
+void png_set_bgr (png_structp png_ptr);
+
+void png_set_bKGD (png_structp png_ptr, png_infop info_ptr,
+png_color_16p background);
+
+void png_set_cHRM (png_structp png_ptr, png_infop info_ptr,
+double white_x, double white_y, double red_x, double red_y,
+double green_x, double green_y, double blue_x, double blue_y);
+
+void png_set_compression_level (png_structp png_ptr, int
+level);
+
+void png_set_compression_mem_level (png_structp png_ptr, int
+mem_level);
+
+void png_set_compression_method (png_structp png_ptr, int
+method);
+
+void png_set_compression_strategy (png_structp png_ptr, int
+strategy);
+
+void png_set_compression_window_bits (png_structp png_ptr, int
+window_bits);
+
+void png_set_crc_action (png_structp png_ptr, int crit_action,
+int ancil_action);
+
+void png_set_dither (png_structp png_ptr, png_colorp palette,
+int num_palette, int maximum_colors, png_uint_16p histogram,
+int full_dither);
+
+void png_set_error_fn (png_structp png_ptr, png_voidp
+error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn);
+
+void png_set_expand (png_structp png_ptr);
+
+void png_set_filler (png_structp png_ptr, png_uint_32 filler,
+int flags);
+
+void png_set_filter (png_structp png_ptr, int method, int
+filters);
+
+void png_set_filter_heuristics (png_structp png_ptr, int
+heuristic_method, int num_weights, png_doublep filter_weights,
+png_doublep filter_costs);
+
+void png_set_flush (png_structp png_ptr, int nrows);
+
+void png_set_gamma (png_structp png_ptr, double screen_gamma,
+double default_file_gamma);
+
+void png_set_gAMA (png_structp png_ptr, png_infop info_ptr,
+double file_gamma);
+
+void png_set_gray_to_rgb (png_structp png_ptr);
+
+void png_set_hIST (png_structp png_ptr, png_infop info_ptr,
+png_uint_16p hist);
+
+int png_set_interlace_handling (png_structp png_ptr);
+
+void png_set_invert_alpha (png_structp png_ptr);
+
+void png_set_invert_mono (png_structp png_ptr);
+
+void png_set_IHDR (png_structp png_ptr, png_infop info_ptr,
+png_uint_32 width, png_uint_32 height, int bit_depth, int
+color_type, int interlace_type, int compression_type, int
+filter_type);
+
+void png_set_oFFs (png_structp png_ptr, png_infop info_ptr,
+png_uint_32 offset_x, png_uint_32 offset_y, int unit_type);
+
+void png_set_packing (png_structp png_ptr);
+
+void png_set_packswap (png_structp png_ptr);
+
+void png_set_pCAL (png_structp png_ptr, png_infop info_ptr,
+png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int
+nparams, png_charp units, png_charpp params);
+
+void png_set_pHYs (png_structp png_ptr, png_infop info_ptr,
+png_uint_32 res_x, png_uint_32 res_y, int unit_type);
+
+void png_set_progressive_read_fn (png_structp png_ptr,
+png_voidp progressive_ptr, png_progressive_info_ptr info_fn,
+png_progressive_row_ptr row_fn, png_progressive_end_ptr
+end_fn);
+
+void png_set_PLTE (png_structp png_ptr, png_infop info_ptr,
+png_colorp palette, int num_palette);
+
+void png_set_read_fn (png_structp png_ptr, png_voidp io_ptr,
+png_rw_ptr read_data_fn);
+
+void png_set_read_status_fn (png_structp png_ptr, png_read_status_ptr
+   read_row_fn);
+
+void png_set_read_user_transform_fn (png_structp png_ptr,
+   png_user_transform_ptr read_user_transform_fn);
+
+void png_set_rgb_to_gray (png_structp png_ptr);
+
+void png_set_sBIT (png_structp png_ptr, png_infop info_ptr,
+png_color_8p sig_bit);
+
+void png_set_shift (png_structp png_ptr, png_color_8p
+true_bits);
+
+void png_set_sig_bytes (png_structp png_ptr, int num_bytes);
+
+void png_set_sRGB (png_structp png_ptr, png_infop info_ptr, int
+intent);
+
+void png_set_sRGB_gAMA_and_cHRM (png_structp png_ptr, png_infop
+info_ptr, int intent);
+
+void png_set_strip_16 (png_structp png_ptr);
+
+void png_set_strip_alpha (png_structp png_ptr);
+
+void png_set_swap (png_structp png_ptr);
+
+void png_set_swap_alpha (png_structp png_ptr);
+
+void png_set_text (png_structp png_ptr, png_infop info_ptr,
+png_textp text_ptr, int num_text);
+
+void png_set_tIME (png_structp png_ptr, png_infop info_ptr,
+png_timep mod_time);
+
+void png_set_tRNS (png_structp png_ptr, png_infop info_ptr,
+png_bytep trans, int num_trans, png_color_16p trans_values);
+
+void png_set_write_fn (png_structp png_ptr, png_voidp io_ptr,
+png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn);
+
+void png_set_write_status_fn (png_structp png_ptr, png_write_status_ptr
+   write_row_fn);
+
+void png_set_write_user_transform_fn (png_structp png_ptr,
+   png_user_transform_ptr write_user_transform_fn);
+
+int png_sig_cmp (png_bytep sig, png_size_t start, png_size_t
+num_to_check);
+
+void png_start_read_image (png_structp png_ptr);
+
+void png_warning (png_structp png_ptr, png_const_charp
+message);
+
+void png_write_chunk (png_structp png_ptr, png_bytep
+chunk_name, png_bytep data, png_size_t length);
+
+void png_write_chunk_data (png_structp png_ptr, png_bytep data,
+png_size_t length);
+
+void png_write_chunk_end (png_structp png_ptr);
+
+void png_write_chunk_start (png_structp png_ptr, png_bytep
+chunk_name, png_uint_32 length);
+
+void png_write_destroy (png_structp png_ptr);
+
+void png_write_destroy_info (png_infop info_ptr);
+
+void png_write_end (png_structp png_ptr, png_infop info_ptr);
+
+void png_write_flush (png_structp png_ptr);
+ 
+void png_write_image (png_structp png_ptr, png_bytepp image);
+
+void png_write_info (png_structp png_ptr, png_infop info_ptr);
+
+void png_write_row (png_structp png_ptr, png_bytep row);
+
+void png_write_rows (png_structp png_ptr, png_bytepp row,
+png_uint_32 num_rows);
+
+.SH DESCRIPTION
+The
+.I libpng
+library supports encoding, decoding, and various manipulations of
+the Portable Network Graphics (PNG) format image files.  It uses the
+.IR zlib(3)
+compression library.
+Following is a copy of the libpng.txt file that accompanies libpng.
+.SH LIBPNG.TXT
+libpng.txt - A description on how to use and modify libpng
+
+ libpng version 1.0.1 March 15, 1998
+ Updated and distributed by Glenn Randers-Pehrson
+ <randeg@alumni.rpi.edu>
+ Copyright (c) 1998, Glenn Randers-Pehrson
+ For conditions of distribution and use, see copyright
+ notice in png.h.
+
+ based on:
+
+ libpng 1.0 beta 6  version 0.96 May 28, 1997
+ Updated and distributed by Andreas Dilger 
+ Copyright (c) 1996, 1997 Andreas Dilger
+
+ libpng 1.0 beta 2 - version 0.88  January 26, 1996
+ For conditions of distribution and use, see copyright
+ notice in png.h. Copyright (c) 1995, 1996 Guy Eric
+ Schalnat, Group 42, Inc.
+
+ Updated/rewritten per request in the libpng FAQ
+ Copyright (c) 1995 Frank J. T. Wojcik
+ December 18, 1995 && January 20, 1996
+
+.SH I. Introduction
+
+This file describes how to use and modify the PNG reference library
+(known as libpng) for your own use.  There are five sections to this
+file: introduction, structures, reading, writing, and modification and
+configuration notes for various special platforms.  In addition to this
+file, example.c is a good starting point for using the library, as
+it is heavily commented and should include everything most people
+will need.  We assume that libpng is already installed; see the
+INSTALL file for instructions on how to install libpng.
+
+Libpng was written as a companion to the PNG specification, as a way
+of reducing the amount of time and effort it takes to support the PNG
+file format in application programs.  The PNG specification is available
+as RFC 2083 <ftp://ftp.uu.net/graphics/png/documents/> and as a
+W3C Recommendation <http://www.w3.org/TR/REC.png.html>. Some
+additional chunks are described in the special-purpose public chunks
+documents at <ftp://ftp.uu.net/graphics/png/documents/>.  Other information
+about PNG can be found at the PNG home page, <http://www.cdrom.com/pub/png/>.
+
+Most users will not have to modify the library significantly; advanced
+users may want to modify it more.  All attempts were made to make it as
+complete as possible, while keeping the code easy to understand.
+Currently, this library only supports C.  Support for other languages
+is being considered.
+
+Libpng has been designed to handle multiple sessions at one time,
+to be easily modifiable, to be portable to the vast majority of
+machines (ANSI, K&R, 16-, 32-, and 64-bit) available, and to be easy
+to use.  The ultimate goal of libpng is to promote the acceptance of
+the PNG file format in whatever way possible.  While there is still
+work to be done (see the TODO file), libpng should cover the
+majority of the needs of its users.
+
+Libpng uses zlib for its compression and decompression of PNG files.
+The zlib compression utility is a general purpose utility that is
+useful for more than PNG files, and can be used without libpng.
+See the documentation delivered with zlib for more details.
+You can usually find the source files for the zlib utility wherever you
+find the libpng source files.
+
+Libpng is thread safe, provided the threads are using different
+instances of the structures.  Each thread should have its own
+png_struct and png_info instances, and thus its own image.
+Libpng does not protect itself against two threads using the
+same instance of a structure.
+
+
+.SH II. Structures
+
+There are two main structures that are important to libpng, png_struct
+and png_info.  The first, png_struct, is an internal structure that
+will not, for the most part, be used by a user except as the first
+variable passed to every libpng function call.
+
+The png_info structure is designed to provide information about the
+PNG file.  At one time, the fields of png_info were intended to be
+directly accessible to the user.  However, this tended to cause problems
+with applications using dynamically loaded libraries, and as a result
+a set of interface functions for png_info was developed.  The fields
+of png_info are still available for older applications, but it is
+suggested that applications use the new interfaces if at all possible.
+
+The png.h header file is an invaluable reference for programming with libpng.
+And while I'm on the topic, make sure you include the libpng header file:
+
+#include <png.h>
+
+.SH III. Reading
+
+Reading PNG files:
+
+We'll now walk you through the possible functions to call when reading
+in a PNG file, briefly explaining the syntax and purpose of each one.
+See example.c and png.h for more detail.  While Progressive reading
+is covered in the next section, you will still need some of the
+functions discussed in this section to read a PNG file.
+
+You will want to do the I/O initialization(*) before you get into libpng,
+so if it doesn't work, you don't have much to undo.  Of course, you
+will also want to insure that you are, in fact, dealing with a PNG
+file.  Libpng provides a simple check to see if a file is a PNG file.
+To use it, pass in the first 1 to 8 bytes of the file, and it will
+return true or false (1 or 0) depending on whether the bytes could be
+part of a PNG file.  Of course, the more bytes you pass in, the
+greater the accuracy of the prediction.
+
+If you are intending to keep the file pointer open for use in libpng,
+you must ensure you don't read more than 8 bytes from the beginning
+of the file, and you also have to make a call to png_set_sig_bytes_read()
+with the number of bytes you read from the beginning.  Libpng will
+then only check the bytes (if any) that your program didn't read.
+
+(*): If you are not using the standard I/O functions, you will need
+to replace them with custom functions.  See the discussion under
+Customizing libpng.
+
+
+    FILE *fp = fopen(file_name, "rb");
+    if (!fp)
+    {
+        return;
+    }
+    fread(header, 1, number, fp);
+    is_png = png_check_sig(header, 0, number);
+    if (!is_png)
+    {
+        return;
+    }
+
+
+Next, png_struct and png_info need to be allocated and initialized.  In
+order to ensure that the size of these structures is correct even with a
+dynamically linked libpng, there are functions to initialize and
+allocate the structures.  We also pass the library version, optional
+pointers to error handling functions, and a pointer to a data struct for
+use by the error functions, if necessary (the pointer and functions can
+be NULL if the default error handlers are to be used).  See the section
+on Changes to Libpng below regarding the old initialization functions.
+
+    png_structp png_ptr = png_create_read_struct
+       (PNG_LIBPNG_VER_STRING, (void *)user_error_ptr,
+        user_error_fn, user_warning_fn);
+    if (!png_ptr)
+        return;
+
+    png_infop info_ptr = png_create_info_struct(png_ptr);
+    if (!info_ptr)
+    {
+        png_destroy_read_struct(&png_ptr,
+           (png_infopp)NULL, (png_infopp)NULL);
+        return;
+    }
+
+    png_infop end_info = png_create_info_struct(png_ptr);
+    if (!end_info)
+    {
+        png_destroy_read_struct(&png_ptr, &info_ptr,
+          (png_infopp)NULL);
+        return;
+    }
+
+
+The error handling routines passed to png_create_read_struct() are only
+necessary if you are not using the libpng supplied error handling
+functions.  When libpng encounters an error, it expects to longjmp back
+to your routine.  Therefore, you will need to call setjmp and pass the
+jmpbuf field of your png_struct.  If you read the file from different
+routines, you will need to update the jmpbuf field every time you enter
+a new routine that will call a png_ function.
+
+See your documentation of setjmp/longjmp for your compiler for more
+handling in the Customizing Libpng section below for more information on
+the libpng error handling.  If an error occurs, and libpng longjmp's
+back to your setjmp, you will want to call png_destroy_read_struct() to
+free any memory.
+
+    if (setjmp(png_ptr->jmpbuf))
+    {
+        png_destroy_read_struct(&png_ptr, &info_ptr,
+           &end_info);
+        fclose(fp);
+        return;
+    }
+
+Now you need to set up the input code.  The default for libpng is to
+use the C function fread().  If you use this, you will need to pass a
+valid FILE * in the function png_init_io().  Be sure that the file is
+opened in binary mode.  If you wish to handle reading data in another
+way, you need not call the png_init_io() function, but you must then
+implement the libpng I/O methods discussed in the Customizing Libpng
+section below.
+
+    png_init_io(png_ptr, fp);
+
+If you had previously opened the file and read any of the signature from
+the beginning in order to see if this was a PNG file, you need to let
+libpng know that there are some bytes missing from the start of the file.
+
+    png_set_sig_bytes(png_ptr, number);
+
+At this point, you can set up a callback function that will be
+called after each row has been read, which you can use to control
+a progress meter or the like.  It's demonstrated in pngtest.c.
+You must supply a function
+
+    void read_row_callback(png_ptr, png_uint_32 row, int pass);
+    {
+      /* put your code here */
+    }
+
+(You can give it another name that you like instead of "read_row_callback")
+
+To inform libpng about your function, use
+
+    png_set_read_status_fn(png_ptr, read_row_callback);
+
+In PNG files, the alpha channel in an image is the level of opacity.
+If you need the alpha channel in an image to be the level of transparency
+instead of opacity, you can invert the alpha channel (or the tRNS chunk
+data) after it's read, so that 0 is fully opaque and 255 (in 8-bit or
+paletted images) or 65535 (in 16-bit images) is fully transparent, with
+
+    png_set_invert_alpha(png_ptr);
+
+This has to appear here rather than later with the other transformations
+because the tRNS chunk data must be modified in the case of paletted images.
+If your image is not a paletted image, the tRNS data (which in such cases
+represents a single color to be rendered as transparent) won't be changed.
+
+Finally, you can write your own transformation function if none of
+the existing ones meets your needs.  This is done by setting a callback
+with
+
+    png_set_read_user_transform_fn(png_ptr,
+       read_transform_fn);
+
+You must supply the function
+
+    void read_transform_fn(png_ptr ptr, row_info_ptr
+       row_info, png_bytep data) 
+
+See pngtest.c for a working example.  Your function will be called
+after all of the other transformations have been processed.
+
+You are now ready to read all the file information up to the actual
+image data.  You do this with a call to png_read_info().
+
+    png_read_info(png_ptr, info_ptr);
+
+Functions are used to get the information from the info_ptr:
+
+    png_get_IHDR(png_ptr, info_ptr, &width, &height,
+       &bit_depth, &color_type, &interlace_type,
+       &compression_type, &filter_type);
+
+    width          - holds the width of the image
+                     in pixels (up to 2^31).
+    height         - holds the height of the image
+                     in pixels (up to 2^31).
+    bit_depth      - holds the bit depth of one of the
+                     image channels.  (valid values are
+                     1, 2, 4, 8, 16 and depend also on
+                     the color_type.  See also
+                     significant bits (sBIT) below).
+    color_type     - describes which color/alpha channels
+                         are present.
+                     PNG_COLOR_TYPE_GRAY
+                        (bit depths 1, 2, 4, 8, 16)
+                     PNG_COLOR_TYPE_GRAY_ALPHA  
+                        (bit depths 8, 16)
+                     PNG_COLOR_TYPE_PALETTE
+                        (bit depths 1, 2, 4, 8)
+                     PNG_COLOR_TYPE_RGB
+                        (bit_depths 8, 16)
+                     PNG_COLOR_TYPE_RGB_ALPHA
+                        (bit_depths 8, 16)
+
+                     PNG_COLOR_MASK_PALETTE
+                     PNG_COLOR_MASK_COLOR
+                     PNG_COLOR_MASK_ALPHA
+
+    filter_type    - (must be PNG_FILTER_TYPE_BASE
+                     for PNG 1.0)
+    compression_type - (must be PNG_COMPRESSION_TYPE_BASE
+                     for PNG 1.0)
+    interlace_type - (PNG_INTERLACE_NONE or
+                     PNG_INTERLACE_ADAM7)
+    Any or all of interlace_type, compression_type, of
+                     filter_type can be
+    NULL if you are not interested in their values.
+
+    channels = png_get_channels(png_ptr, info_ptr);
+    channels       - number of channels of info for the
+                     color type (valid values are 1 (GRAY,
+                     PALETTE), 2 (GRAY_ALPHA), 3 (RGB),
+                     4 (RGB_ALPHA or RGB + filler byte))
+    rowbytes = png_get_rowbytes(png_ptr, info_ptr);
+    rowbytes       - number of bytes needed to hold a row
+
+    signature = png_get_signature(png_ptr, info_ptr);
+    signature      - holds the signature read from the
+                     file (if any).  The data is kept in
+                     the same offset it would be if the
+                     whole signature were read (i.e. if an
+                     application had already read in 4
+                     bytes of signature before starting
+                     libpng, the remaining 4 bytes would
+                     be in signature[4] through signature[7]
+                     (see png_set_sig_bytes())).
+
+
+    width            = png_get_image_width(png_ptr,
+                         info_ptr);
+    height           = png_get_image_height(png_ptr,
+                         info_ptr);
+    bit_depth        = png_get_bit_depth(png_ptr,
+                         info_ptr);
+    color_type       = png_get_color_type(png_ptr,
+                         info_ptr);
+    filter_type      = png_get_filter_type(png_ptr,
+                         info_ptr);
+    compression_type = png_get_compression_type(png_ptr,
+                         info_ptr);
+    interlace_type   = png_get_interlace_type(png_ptr,
+                         info_ptr);
+
+
+These are also important, but their validity depends on whether the chunk
+has been read.  The png_get_valid(png_ptr, info_ptr, PNG_INFO_<chunk>) and
+png_get_<chunk>(png_ptr, info_ptr, ...) functions return non-zero if the
+data has been read, or zero if it is missing.  The parameters to the
+png_get_<chunk> are set directly if they are simple data types, or a pointer
+into the info_ptr is returned for any complex types.
+
+    png_get_PLTE(png_ptr, info_ptr, &palette,
+                     &num_palette);
+    palette        - the palette for the file
+                     (array of png_color)
+    num_palette    - number of entries in the palette
+
+    png_get_gAMA(png_ptr, info_ptr, &gamma);
+    gamma          - the gamma the file is written
+                     at (PNG_INFO_gAMA)
+
+    png_get_sRGB(png_ptr, info_ptr, &srgb_intent);
+    srgb_intent    - the rendering intent (PNG_INFO_sRGB)
+                     The presence of the sRGB chunk
+                     means that the pixel data is in the
+                     sRGB color space.  This chunk also
+                     implies specific values of gAMA and
+                     cHRM.
+
+    png_get_sBIT(png_ptr, info_ptr, &sig_bit);
+    sig_bit        - the number of significant bits for
+                     (PNG_INFO_sBIT) each of the gray,
+                     red, green, and blue channels,
+                     whichever are appropriate for the
+                     given color type (png_color_16)
+
+    png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans,
+                     &trans_values);
+    trans          - array of transparent entries for
+                     palette (PNG_INFO_tRNS)
+    trans_values   - transparent pixel for non-paletted
+                     images (PNG_INFO_tRNS)
+    num_trans      - number of transparent entries
+                     (PNG_INFO_tRNS)
+
+    png_get_hIST(png_ptr, info_ptr, &hist);
+                     (PNG_INFO_hIST)
+    hist           - histogram of palette (array of
+                     png_color_16)
+
+    png_get_tIME(png_ptr, info_ptr, &mod_time);
+    mod_time       - time image was last modified
+                    (PNG_VALID_tIME)
+
+    png_get_bKGD(png_ptr, info_ptr, &background);
+    background     - background color (PNG_VALID_bKGD)
+
+    num_text = png_get_text(png_ptr, info_ptr, &text_ptr);
+    text_ptr       - array of png_text holding image
+                     comments
+    text_ptr[i]->key   - keyword for comment.
+    text_ptr[i]->text  - text comments for current
+                         keyword.
+    text_ptr[i]->compression - type of compression used
+                     on "text" PNG_TEXT_COMPRESSION_NONE
+                     or PNG_TEXT_COMPRESSION_zTXt
+    num_text       - number of comments
+
+    png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y,
+                     &unit_type);
+    offset_x       - positive offset from the left edge
+                     of the screen
+    offset_y       - positive offset from the top edge
+                     of the screen
+    unit_type      - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER
+
+    png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y,
+                     &unit_type);
+    res_x          - pixels/unit physical resolution in
+                     x direction
+    res_y          - pixels/unit physical resolution in
+                     x direction
+    unit_type      - PNG_RESOLUTION_UNKNOWN,
+                     PNG_RESOLUTION_METER
+
+The data from the pHYs chunk can be retrieved in several convenient
+forms:
+
+    res_x = png_get_x_pixels_per_meter(png_ptr,
+                  info_ptr)
+    res_y = png_get_y_pixels_per_meter(png_ptr,
+                  info_ptr)
+    res_x_and_y = png_get_pixels_per_meter(png_ptr,
+                  info_ptr)
+    aspect_ratio = png_get_pixel_aspect_ratio(png_ptr,
+                  info_ptr)
+
+   (Each of these returns 0 [signifying "unknown"] if
+       the data is not present or if res_x is 0;
+       res_x_and_y is 0 if res_x != res_y)
+
+For more information, see the png_info definition in png.h and the
+PNG specification for chunk contents.  Be careful with trusting
+rowbytes, as some of the transformations could increase the space
+needed to hold a row (expand, filler, gray_to_rgb, etc.).
+See png_read_update_info(), below.
+
+A quick word about text_ptr and num_text.  PNG stores comments in
+keyword/text pairs, one pair per chunk, with no limit on the number
+of text chunks, and a 2^31 byte limit on their size.  While there are
+suggested keywords, there is no requirement to restrict the use to these
+strings.  It is strongly suggested that keywords and text be sensible
+to humans (that's the point), so don't use abbreviations.  Non-printing
+symbols are not allowed.  See the PNG specification for more details.
+There is also no requirement to have text after the keyword.
+
+Keywords should be limited to 79 Latin-1 characters without leading or
+trailing spaces, but non-consecutive spaces are allowed within the
+keyword.  It is possible to have the same keyword any number of times.
+The text_ptr is an array of png_text structures, each holding pointer
+to a keyword and a pointer to a text string.  Only the text string may
+be null.  The keyword/text pairs are put into the array in the order
+that they are received.  However, some or all of the text chunks may be
+after the image, so, to make sure you have read all the text chunks,
+don't mess with these until after you read the stuff after the image.
+This will be mentioned again below in the discussion that goes with
+png_read_end().
+
+After you've read the header information, you can set up the library
+to handle any special transformations of the image data.  The various
+ways to transform the data will be described in the order that they
+should occur.  This is important, as some of these change the color
+type and/or bit depth of the data, and some others only work on
+certain color types and bit depths.  Even though each transformation
+checks to see if it has data that it can do something with, you should
+make sure to only enable a transformation if it will be valid for the
+data.  For example, don't swap red and blue on grayscale data.
+
+The colors used for the background and transparency values should be
+supplied in the same format/depth as the current image data.  They
+are stored in the same format/depth as the image data in a bKGD or tRNS
+chunk, so this is what libpng expects for this data.  The colors are
+transformed to keep in sync with the image data when an application
+calls the png_read_update_info() routine (see below).
+
+Data will be decoded into the supplied row buffers packed into bytes
+unless the library has been told to transform it into another format.
+For example, 4 bit/pixel paletted or grayscale data will be returned
+2 pixels/byte with the leftmost pixel in the high-order bits of the
+byte, unless png_set_packing() is called.  8-bit RGB data will be stored
+in RGBRGBRGB format unless png_set_filler() is called to insert filler
+bytes, either before or after each RGB triplet.  16-bit RGB data will
+be returned RRGGBBRRGGBB, with the most significant byte of the color
+value first, unless png_set_strip_16() is called to transform it to
+regular RGBRGB triplets.
+
+The following code transforms grayscale images of less than 8 to 8 bits,
+changes paletted images to RGB, and adds a full alpha channel if there is
+transparency information in a tRNS chunk.  This is most useful on
+grayscale images with bit depths of 2 or 4 or if there is a multiple-image
+viewing application that wishes to treat all images in the same way.
+
+    if (color_type == PNG_COLOR_TYPE_PALETTE &&
+        bit_depth <= 8) png_set_expand(png_ptr);
+
+    if (color_type == PNG_COLOR_TYPE_GRAY &&
+        bit_depth < 8) png_set_expand(png_ptr);
+
+    if (png_get_valid(png_ptr, info_ptr,
+        PNG_INFO_tRNS)) png_set_expand(png_ptr);
+
+PNG can have files with 16 bits per channel.  If you only can handle
+8 bits per channel, this will strip the pixels down to 8 bit.
+
+    if (bit_depth == 16)
+        png_set_strip_16(png_ptr);
+
+The png_set_background() function tells libpng to composite images
+with alpha or simple transparency against the supplied background
+color.  If the PNG file contains a bKGD chunk (PNG_INFO_bKGD valid),
+you may use this color, or supply another color more suitable for
+the current display (e.g., the background color from a web page).  You
+need to tell libpng whether the color is in the gamma space of the
+display (PNG_BACKGROUND_GAMMA_SCREEN for colors you supply), the file
+(PNG_BACKGROUND_GAMMA_FILE for colors from the bKGD chunk), or one
+that is neither of these gammas (PNG_BACKGROUND_GAMMA_UNIQUE - I don't
+know why anyone would use this, but it's here).
+
+If, for some reason, you don't need the alpha channel on an image,
+and you want to remove it rather than combining it with the background
+(but the image author certainly had in mind that you *would* combine
+it with the background, so that's what you should probably do):
+
+    if (color_type & PNG_COLOR_MASK_ALPHA)
+        png_set_strip_alpha(png_ptr);
+
+PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as
+they can, resulting in, for example, 8 pixels per byte for 1 bit
+files.  This code expands to 1 pixel per byte without changing the
+values of the pixels:
+
+    if (bit_depth < 8)
+        png_set_packing(png_ptr);
+
+PNG files have possible bit depths of 1, 2, 4, 8, and 16.  All pixels
+stored in a PNG image have been "scaled" or "shifted" up to the next
+higher possible bit depth (e.g. from 5 bits/sample in the range [0,31] to
+8 bits/sample in the range [0, 255]).  However, it is also possible to
+convert the PNG pixel data back to the original bit depth of the image.
+This call reduces the pixels back down to the original bit depth:
+
+    png_color_16p sig_bit;
+
+    if (png_get_sBIT(png_ptr, info_ptr, &sig_bit))
+        png_set_shift(png_ptr, sig_bit);
+
+PNG files store 3-color pixels in red, green, blue order.  This code
+changes the storage of the pixels to blue, green, red:
+
+    if (color_type == PNG_COLOR_TYPE_RGB ||
+        color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+        png_set_bgr(png_ptr);
+
+PNG files store RGB pixels packed into 3 bytes. This code expands them
+into 4 bytes for windowing systems that need them in this format:
+
+    if (bit_depth == 8 && color_type ==
+        PNG_COLOR_TYPE_RGB) png_set_filler(png_ptr,
+        filler, PNG_FILLER_BEFORE);
+
+where "filler" is the number to fill with, and the location is
+either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending upon whether
+you want the filler before the RGB or after.  This transformation
+does not affect images that already have full alpha channels.
+
+If you are reading an image with an alpha channel, and you need the
+data as ARGB instead of the normal PNG format RGBA:
+
+    if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+        png_set_swap_alpha(png_ptr);
+
+For some uses, you may want a grayscale image to be represented as
+RGB.  This code will do that conversion:
+
+    if (color_type == PNG_COLOR_TYPE_GRAY ||
+        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+          png_set_gray_to_rgb(png_ptr);
+
+If you have a grayscale and you are using png_set_expand() to change to
+a higher bit-depth you must indicate if the supplied background gray
+is supplied in the original file bit depth (need_expand = 1) or in the
+expanded bit depth (need_expand = 0).  Similarly, if you are reading
+a paletted image, you must indicate if you have supplied the background
+as a palette index that needs to be expanded (need_expand = 1).  You can
+also specify an RGB triplet that isn't in the palette when setting your
+background for a paletted image.
+
+    png_color_16 my_background;
+    png_color_16p image_background;
+
+    if (png_get_bKGD(png_ptr, info_ptr,
+        &image_background))
+        png_set_background(png_ptr, image_background),
+        PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
+    else
+        png_set_background(png_ptr, &my_background,
+          PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+
+To properly display PNG images on any kind of system, the application needs
+to know what the display gamma is.  Ideally, the user will know this, and
+the application will allow them to set it.  One method of allowing the user
+to set the display gamma separately for each system is to check for the
+DISPLAY_GAMMA and VIEWING_GAMMA environment variables or for a SCREEN_GAMMA
+environment variable, which will hopefully be correctly set.
+
+Note that display_gamma is the gamma of your display, while screen_gamma is
+the overall gamma correction required to produce pleasing results,
+which depends on the lighting conditions in the surrounding environment.
+Screen_gamma is display_gamma/viewing_gamma, where viewing_gamma is
+the amount of additional gamma correction needed to compensate for
+a (viewing_gamma=1.25) environment.  In a dim or brightly lit room, no
+compensation other than the display_gamma is needed (viewing_gamma=1.0).
+
+   if (/* We have a user-defined screen
+       gamma value */)
+   {
+      screen_gamma = user_defined_screen_gamma;
+   }
+   /* One way that applications can share the same
+      screen gamma value */
+   else if ((gamma_str = getenv("SCREEN_GAMMA"))
+      != NULL)
+   {
+      screen_gamma = atof(gamma_str);
+   }
+   /* If we don't have another value */
+   else
+   {
+      screen_gamma = 2.2; /* A good guess for a
+           PC monitor in a bright office or a dim room */
+      screen_gamma = 2.0; /* A good guess for a
+           PC monitor in a dark room */
+      screen_gamma = 1.7 or 1.0;  /* A good
+           guess for Mac systems */
+   }
+
+The png_set_gamma() function handles gamma transformations of the data.
+Pass both the file gamma and the current screen_gamma.  If the file does
+not have a gamma value, you can pass one anyway if you have an idea what
+it is (usually 0.50 is a good guess for GIF images on PCs).  Note
+that file gammas are inverted from screen gammas.  See the discussions
+on gamma in the PNG specification for an excellent description of what
+gamma is, and why all applications should support it.  It is strongly
+recommended that PNG viewers support gamma correction.
+
+   if (png_get_gAMA(png_ptr, info_ptr, &gamma))
+      png_set_gamma(png_ptr, screen_gamma, gamma);
+   else
+      png_set_gamma(png_ptr, screen_gamma, 0.50);
+
+If you need to reduce an RGB file to a paletted file, or if a paletted
+file has more entries then will fit on your screen, png_set_dither()
+will do that.  Note that this is a simple match dither that merely
+finds the closest color available.  This should work fairly well with
+optimized palettes, and fairly badly with linear color cubes.  If you
+pass a palette that is larger then maximum_colors, the file will
+reduce the number of colors in the palette so it will fit into
+maximum_colors.  If there is a histogram, it will use it to make
+more intelligent choices when reducing the palette.  If there is no
+histogram, it may not do as good a job.
+
+   if (color_type & PNG_COLOR_MASK_COLOR)
+   {
+      if (png_get_valid(png_ptr, info_ptr,
+         PNG_INFO_PLTE))
+      {
+         png_color_16p histogram;
+
+         png_get_hIST(png_ptr, info_ptr,
+            &histogram);
+         png_set_dither(png_ptr, palette, num_palette,
+            max_screen_colors, histogram, 1);
+      }
+      else
+      {
+         png_color std_color_cube[MAX_SCREEN_COLORS] =
+            { ... colors ... };
+
+         png_set_dither(png_ptr, std_color_cube,
+            MAX_SCREEN_COLORS, MAX_SCREEN_COLORS,
+            NULL,0);
+      }
+   }
+
+PNG files describe monochrome as black being zero and white being one.
+The following code will reverse this (make black be one and white be
+zero):
+
+   if (bit_depth == 1 && color_type == PNG_COLOR_GRAY)
+      png_set_invert_mono(png_ptr);
+
+PNG files store 16 bit pixels in network byte order (big-endian,
+ie. most significant bits first).  This code changes the storage to the
+other way (little-endian, i.e. least significant bits first, the
+way PCs store them):
+
+    if (bit_depth == 16)
+        png_set_swap(png_ptr);
+
+If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you
+need to change the order the pixels are packed into bytes, you can use:
+
+    if (bit_depth < 8)
+       png_set_packswap(png_ptr);
+
+The last thing to handle is interlacing; this is covered in detail below,
+but you must call the function here if you want libpng to handle expansion
+of the interlaced image.
+
+    number_of_passes = png_set_interlace_handling(png_ptr);
+
+After setting the transformations, libpng can update your png_info
+structure to reflect any transformations you've requested with this
+call.  This is most useful to update the info structure's rowbytes
+field so you can use it to allocate your image memory.  This function
+will also update your palette with the correct screen_gamma and
+background if these have been given with the calls above.
+
+    png_read_update_info(png_ptr, info_ptr);
+
+After you call png_read_update_info(), you can allocate any
+memory you need to hold the image.  The row data is simply
+raw byte data for all forms of images.  As the actual allocation
+varies among applications, no example will be given.  If you
+are allocating one large chunk, you will need to build an
+array of pointers to each row, as it will be needed for some
+of the functions below.
+
+After you've allocated memory, you can read the image data.
+The simplest way to do this is in one function call.  If you are
+allocating enough memory to hold the whole image, you can just
+call png_read_image() and libpng will read in all the image data
+and put it in the memory area supplied.  You will need to pass in
+an array of pointers to each row.
+
+This function automatically handles interlacing, so you don't need
+to call png_set_interlace_handling() or call this function multiple
+times, or any of that other stuff necessary with png_read_rows().
+
+   png_read_image(png_ptr, row_pointers);
+
+where row_pointers is:
+
+   png_bytep row_pointers[height];
+
+You can point to void or char or whatever you use for pixels.
+
+If you don't want to read in the whole image at once, you can
+use png_read_rows() instead.  If there is no interlacing (check
+interlace_type == PNG_INTERLACE_NONE), this is simple:
+
+    png_read_rows(png_ptr, row_pointers, NULL,
+       number_of_rows);
+
+where row_pointers is the same as in the png_read_image() call.
+
+If you are doing this just one row at a time, you can do this with
+row_pointers:
+
+    png_bytep row_pointers = row;
+    png_read_row(png_ptr, &row_pointers, NULL);
+
+If the file is interlaced (info_ptr->interlace_type != 0), things get
+somewhat harder.  The only current (PNG Specification version 1.0)
+interlacing type for PNG is (interlace_type == PNG_INTERLACE_ADAM7)
+is a somewhat complicated 2D interlace scheme, known as Adam7, that
+breaks down an image into seven smaller images of varying size, based
+on an 8x8 grid.
+
+libpng can fill out those images or it can give them to you "as is".
+If you want them filled out, there are two ways to do that.  The one
+mentioned in the PNG specification is to expand each pixel to cover
+those pixels that have not been read yet (the "rectangle" method).
+This results in a blocky image for the first pass, which gradually
+smooths out as more pixels are read.  The other method is the "sparkle"
+method, where pixels are drawn only in their final locations, with the
+rest of the image remaining whatever colors they were initialized to
+before the start of the read.  The first method usually looks better,
+but tends to be slower, as there are more pixels to put in the rows.
+
+If you don't want libpng to handle the interlacing details, just call
+png_read_rows() seven times to read in all seven images.  Each of the
+images is a valid image by itself, or they can all be combined on an
+8x8 grid to form a single image (although if you intend to combine them
+you would be far better off using the libpng interlace handling).
+
+The first pass will return an image 1/8 as wide as the entire image
+(every 8th column starting in column 0) and 1/8 as high as the original
+(every 8th row starting in row 0), the second will be 1/8 as wide
+(starting in column 4) and 1/8 as high (also starting in row 0).  The
+third pass will be 1/4 as wide (every 4th pixel starting in column 0) and
+1/8 as high (every 8th row starting in row 4), and the fourth pass will
+be 1/4 as wide and 1/4 as high (every 4th column starting in column 2,
+and every 4th row starting in row 0).  The fifth pass will return an
+image 1/2 as wide, and 1/4 as high (starting at column 0 and row 2),
+while the sixth pass will be 1/2 as wide and 1/2 as high as the original
+(starting in column 1 and row 0).  The seventh and final pass will be as
+wide as the original, and 1/2 as high, containing all of the odd
+numbered scanlines.  Phew!
+
+If you want libpng to expand the images, call this before calling
+png_start_read_image() or png_read_update_info():
+
+    if (interlace_type == PNG_INTERLACE_ADAM7)
+        number_of_passes
+           = png_set_interlace_handling(png_ptr);
+
+This will return the number of passes needed.  Currently, this
+is seven, but may change if another interlace type is added.
+This function can be called even if the file is not interlaced,
+where it will return one pass.
+
+If you are not going to display the image after each pass, but are
+going to wait until the entire image is read in, use the sparkle
+effect.  This effect is faster and the end result of either method
+is exactly the same.  If you are planning on displaying the image
+after each pass, the "rectangle" effect is generally considered the
+better looking one.
+
+If you only want the "sparkle" effect, just call png_read_rows() as
+normal, with the third parameter NULL.  Make sure you make pass over
+the image number_of_passes times, and you don't change the data in the
+rows between calls.  You can change the locations of the data, just
+not the data.  Each pass only writes the pixels appropriate for that
+pass, and assumes the data from previous passes is still valid.
+
+    png_read_rows(png_ptr, row_pointers, NULL,
+       number_of_rows);
+
+If you only want the first effect (the rectangles), do the same as
+before except pass the row buffer in the third parameter, and leave
+the second parameter NULL.
+
+    png_read_rows(png_ptr, NULL, row_pointers,
+       number_of_rows);
+
+After you are finished reading the image, you can finish reading
+the file.  If you are interested in comments or time, which may be
+stored either before or after the image data, you should pass the
+separate png_info struct if you want to keep the comments from
+before and after the image separate.  If you are not interested, you
+can pass NULL.
+
+   png_read_end(png_ptr, end_info);
+
+When you are done, you can free all memory allocated by libpng like this:
+
+   png_destroy_read_struct(&png_ptr, &info_ptr,
+       &end_info);
+
+For a more compact example of reading a PNG image, see the file example.c.
+
+
+Reading PNG files progressively:
+
+The progressive reader is slightly different then the non-progressive
+reader.  Instead of calling png_read_info(), png_read_rows(), and
+png_read_end(), you make one call to png_process_data(), which calls
+callbacks when it has the info, a row, or the end of the image.  You
+set up these callbacks with png_set_progressive_read_fn().  You don't
+have to worry about the input/output functions of libpng, as you are
+giving the library the data directly in png_process_data().  I will
+assume that you have read the section on reading PNG files above,
+so I will only highlight the differences (although I will show
+all of the code).
+
+png_structp png_ptr;
+png_infop info_ptr;
+
+ /*  An example code fragment of how you would
+     initialize the progressive reader in your
+     application. */
+ int
+ initialize_png_reader()
+ {
+    png_ptr = png_create_read_struct
+        (PNG_LIBPNG_VER_STRING, (void *)user_error_ptr,
+         user_error_fn, user_warning_fn);
+    if (!png_ptr)
+        return -1;
+    info_ptr = png_create_info_struct(png_ptr);
+    if (!info_ptr)
+    {
+        png_destroy_read_struct(&png_ptr, (png_infopp)NULL,
+           (png_infopp)NULL);
+        return -1;
+    }
+
+    if (setjmp(png_ptr->jmpbuf))
+    {
+        png_destroy_read_struct(&png_ptr, &info_ptr,
+           (png_infopp)NULL);
+        return -1;
+    }
+
+    /* This one's new.  You can provide functions
+       to be called when the header info is valid,
+       when each row is completed, and when the image
+       is finished.  If you aren't using all functions,
+       you can specify a NULL parameter.  You can use
+       any struct as the user_ptr (cast to a void pointer
+       for the function call), and retrieve the pointer
+       from inside the callbacks using the function
+
+          png_get_progressive_ptr(png_ptr);
+
+       which will return a void pointer, which you have
+       to cast appropriately.
+     */
+    png_set_progressive_read_fn(png_ptr, (void *)user_ptr,
+        info_callback, row_callback, end_callback);
+
+    return 0;
+ }
+
+ /* A code fragment that you call as you receive blocks
+   of data */
+ int
+ process_data(png_bytep buffer, png_uint_32 length)
+ {
+    if (setjmp(png_ptr->jmpbuf))
+    {
+        png_destroy_read_struct(&png_ptr, &info_ptr,
+           (png_infopp)NULL);
+        return -1;
+    }
+
+    /* This one's new also.  Simply give it a chunk
+       of data from the file stream (in order, of
+       course).  On machines with segmented memory
+       models machines, don't give it any more than
+       64K.  The library seems to run fine with sizes 
+       of 4K. Although you can give it much less if
+       necessary (I assume you can give it chunks of
+       1 byte, I haven't tried less then 256 bytes
+       yet).  When this function returns, you may
+       want to display any rows that were generated
+       in the row callback if you don't already do
+       so there. 
+     */
+    png_process_data(png_ptr, info_ptr, buffer, length);
+    return 0;
+ }
+
+ /* This function is called (as set by
+    png_set_progressive_fn() above) when enough data
+    has been supplied so all of the header has been
+    read.
+ */
+ void
+ info_callback(png_structp png_ptr, png_infop info)
+ {
+    /* Do any setup here, including setting any of
+       the transformations mentioned in the Reading
+       PNG files section.  For now, you _must_ call
+       either png_start_read_image() or
+       png_read_update_info() after all the
+       transformations are set (even if you don't set
+       any).  You may start getting rows before
+       png_process_data() returns, so this is your
+       last chance to prepare for that.
+     */
+ }
+
+ /* This function is called when each row of image
+    data is complete */
+ void
+ row_callback(png_structp png_ptr, png_bytep new_row,
+    png_uint_32 row_num, int pass)
+ {
+    /* If the image is interlaced, and you turned
+       on the interlace handler, this function will
+       be called for every row in every pass.  Some
+       of these rows will not be changed from the
+       previous pass.  When the row is not changed,
+       the new_row variable will be NULL.  The rows
+       and passes are called in order, so you don't
+       really need the row_num and pass, but I'm
+       supplying them because it may make your life
+       easier.
+
+       For the non-NULL rows of interlaced images,
+       you must call png_progressive_combine_row()
+       passing in the row and the old row.  You can
+       call this function for NULL rows (it will just
+       return) and for non-interlaced images (it just
+       does the memcpy for you) if it will make the
+       code easier.  Thus, you can just do this for
+       all cases:
+     */
+
+        png_progressive_combine_row(png_ptr, old_row,
+          new_row);
+
+    /* where old_row is what was displayed for
+       previous rows.  Note that the first pass
+       (pass == 0, really) will completely cover
+       the old row, so the rows do not have to be
+       initialized.  After the first pass (and only
+       for interlaced images), you will have to pass
+       the current row, and the function will combine
+       the old row and the new row.
+    */  
+ }
+
+ void
+ end_callback(png_structp png_ptr, png_infop info)
+ {
+    /* This function is called after the whole image
+       has been read, including any chunks after the
+       image (up to and including the IEND).  You
+       will usually have the same info chunk as you
+       had in the header, although some data may have
+       been added to the comments and time fields.
+
+       Most people won't do much here, perhaps setting
+       a flag that marks the image as finished.
+     */
+ }
+
+.SH IV. Writing
+
+Much of this is very similar to reading.  However, everything of
+importance is repeated here, so you won't have to constantly look
+back up in the reading section to understand writing.
+
+You will want to do the I/O initialization before you get into libpng,
+so if it doesn't work, you don't have anything to undo. If you are not
+using the standard I/O functions, you will need to replace them with
+custom writing functions.  See the discussion under Customizing libpng.
+    
+    FILE *fp = fopen(file_name, "wb");
+    if (!fp)
+    {
+       return;
+    }
+
+Next, png_struct and png_info need to be allocated and initialized.
+As these can be both relatively large, you may not want to store these
+on the stack, unless you have stack space to spare.  Of course, you
+will want to check if they return NULL.  If you are also reading,
+you won't want to name your read structure and your write structure
+both "png_ptr"; you can call them anything you like, such as
+"read_ptr" and "write_ptr".  Look at pngtest.c, for example.
+
+    png_structp png_ptr = png_create_write_struct
+       (PNG_LIBPNG_VER_STRING, (void *)user_error_ptr,
+        user_error_fn, user_warning_fn);
+    if (!png_ptr)
+       return;
+
+    png_infop info_ptr = png_create_info_struct(png_ptr);
+    if (!info_ptr)
+    {
+       png_destroy_write_struct(&png_ptr,
+         (png_infopp)NULL);
+       return;
+    }
+
+After you have these structures, you will need to set up the
+error handling.  When libpng encounters an error, it expects to
+longjmp() back to your routine.  Therefore, you will need to call
+setjmp and pass the jmpbuf field of your png_struct.  If you
+write the file from different routines, you will need to update
+the jmpbuf field every time you enter a new routine that will
+call a png_ function.  See your documentation of setjmp/longjmp
+for your compiler for more information on setjmp/longjmp.  See
+the discussion on libpng error handling in the Customizing Libpng
+section below for more information on the libpng error handling.
+    
+    if (setjmp(png_ptr->jmpbuf))
+    {    
+        png_destroy_write_struct(&png_ptr, &info_ptr);
+        fclose(fp);
+        return;
+    }
+
+Now you need to set up the output code.  The default for libpng is to
+use the C function fwrite().  If you use this, you will need to pass a
+valid FILE * in the function png_init_io().  Be sure that the file is
+opened in binary mode.  Again, if you wish to handle writing data in
+another way, see the discussion on libpng I/O handling in the Customizing
+Libpng section below.
+
+    png_init_io(png_ptr, fp);
+
+At this point, you can set up a callback function that will be
+called after each row has been written, which you can use to control
+a progress meter or the like.  It's demonstrated in pngtest.c.
+You must supply a function
+
+    void write_row_callback(png_ptr, png_uint_32 row, int pass);
+    {
+      /* put your code here */
+    }
+
+(You can give it another name that you like instead of "write_row_callback")
+
+To inform libpng about your function, use
+
+    png_set_write_status_fn(png_ptr, write_row_callback);
+
+You now have the option of modifying how the compression library will
+run.  The following functions are mainly for testing, but may be useful
+in some cases, like if you need to write PNG files extremely fast and
+are willing to give up some compression, or if you want to get the
+maximum possible compression at the expense of slower writing.  If you
+have no special needs in this area, let the library do what it wants by
+not calling this function at all, as it has been tuned to deliver a good
+speed/compression ratio. The second parameter to png_set_filter() is
+the filter method, for which the only valid value is '0' (as of the
+October 1996 PNG specification, version 1.0).  The third parameter is a
+flag that indicates
+which filter type(s) are to be tested for each scanline.  See the
+Compression Library for details on the specific filter types.
+
+    
+    /* turn on or off filtering, and/or choose
+       specific filters */
+    png_set_filter(png_ptr, 0,
+       PNG_FILTER_NONE | PNG_FILTER_SUB |
+       PNG_FILTER_PAETH);
+
+The png_set_compression_???() functions interface to the zlib compression
+library, and should mostly be ignored unless you really know what you are
+doing.  The only generally useful call is png_set_compression_level()
+which changes how much time zlib spends on trying to compress the image
+data.  See the Compression Library for details on the compression levels.
+
+    /* set the zlib compression level */
+    png_set_compression_level(png_ptr,
+        Z_BEST_COMPRESSION);
+
+    /* set other zlib parameters */
+    png_set_compression_mem_level(png_ptr, 8);
+    png_set_compression_strategy(png_ptr,
+        Z_DEFAULT_STRATEGY);
+    png_set_compression_window_bits(png_ptr, 15);
+    png_set_compression_method(png_ptr, 8);
+
+You now need to fill in the png_info structure with all the data you
+wish to write before the actual image.  Note that the only thing you
+are allowed to write after the image is the text chunks and the time
+chunk (as of PNG Specification 1.0, anyway).  See png_write_end() and
+the latest PNG specification for more information on that.  If you
+wish to write them before the image, fill them in now, and flag that
+data as being valid.  If you want to wait until after the data, don't
+fill them until png_write_end().  For all the fields in png_info and
+their data types, see png.h.  For explanations of what the fields
+contain, see the PNG specification.
+
+Some of the more important parts of the png_info are:
+
+    png_set_IHDR(png_ptr, info_ptr, width, height,
+       bit_depth, color_type, interlace_type,
+       compression_type, filter_type)
+    width          - holds the width of the image
+                     in pixels (up to 2^31).
+    height         - holds the height of the image
+                     in pixels (up to 2^31).
+    bit_depth      - holds the bit depth of one of the
+                     image channels.
+                     (valid values are 1, 2, 4, 8, 16
+                     and depend also on the
+                     color_type.  See also significant
+                     bits (sBIT) below).
+    color_type     - describes which color/alpha
+                     channels are present.
+                     PNG_COLOR_TYPE_GRAY
+                        (bit depths 1, 2, 4, 8, 16)
+                     PNG_COLOR_TYPE_GRAY_ALPHA
+                        (bit depths 8, 16)
+                     PNG_COLOR_TYPE_PALETTE
+                        (bit depths 1, 2, 4, 8)
+                     PNG_COLOR_TYPE_RGB
+                        (bit_depths 8, 16)
+                     PNG_COLOR_TYPE_RGB_ALPHA
+                        (bit_depths 8, 16)
+
+                     PNG_COLOR_MASK_PALETTE
+                     PNG_COLOR_MASK_COLOR
+                     PNG_COLOR_MASK_ALPHA
+
+    interlace_type - PNG_INTERLACE_NONE or
+                     PNG_INTERLACE_ADAM7
+    compression_type - (must be
+                     PNG_COMPRESSION_TYPE_DEFAULT)
+    filter_type    - (must be PNG_FILTER_TYPE_DEFAULT)
+
+    png_set_PLTE(png_ptr, info_ptr, palette,
+       num_palette);
+    palette        - the palette for the file
+                     (array of png_color)
+    num_palette    - number of entries in the palette
+
+    png_set_gAMA(png_ptr, info_ptr, gamma);
+    gamma          - the gamma the image was created
+                     at (PNG_INFO_gAMA)
+
+    png_set_sRGB(png_ptr, info_ptr, srgb_intent);
+    srgb_intent    - the rendering intent
+                     (PNG_INFO_sRGB) The presence of
+                     the sRGB chunk means that the pixel
+                     data is in the sRGB color space.
+                     This chunk also implies specific
+                     values of gAMA and cHRM.  Rendering
+                     intent is the CSS-1 property that
+                     has been defined by the International
+                     Color Consortium
+                     (http://www.color.org).
+                     It can be one of
+                     PNG_SRGB_INTENT_SATURATION,
+                     PNG_SRGB_INTENT_PERCEPTUAL,
+                     PNG_SRGB_INTENT_ABSOLUTE, or
+                     PNG_SRGB_INTENT_RELATIVE.
+                        
+
+    png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr,
+       srgb_intent);
+    srgb_intent    - the rendering intent
+                     (PNG_INFO_sRGB) The presence of the
+                     sRGB chunk means that the pixel
+                     data is in the sRGB color space.
+                     This function also causes gAMA and
+                     cHRM chunks with the specific values
+                     that are consistent with sRGB to be
+                     written.
+
+    png_set_sBIT(png_ptr, info_ptr, sig_bit);
+    sig_bit        - the number of significant bits for
+                     (PNG_INFO_sBIT) each of the gray, red,
+                     green, and blue channels, whichever are
+                     appropriate for the given color type
+                     (png_color_16)
+
+    png_set_tRNS(png_ptr, info_ptr, trans, num_trans,
+       trans_values);
+    trans          - array of transparent entries for
+                     palette (PNG_INFO_tRNS)
+    trans_values   - transparent pixel for non-paletted
+                     images (PNG_INFO_tRNS)
+    num_trans      - number of transparent entries
+                     (PNG_INFO_tRNS)
+
+    png_set_hIST(png_ptr, info_ptr, hist);
+                    (PNG_INFO_hIST)
+    hist           - histogram of palette (array of
+                     png_color_16)
+
+    png_set_tIME(png_ptr, info_ptr, mod_time);
+    mod_time       - time image was last modified
+                     (PNG_VALID_tIME)
+
+    png_set_bKGD(png_ptr, info_ptr, background);
+    background     - background color (PNG_VALID_bKGD)
+
+    png_set_text(png_ptr, info_ptr, text_ptr, num_text);
+    text_ptr       - array of png_text holding image
+                     comments
+    text_ptr[i]->key   - keyword for comment.
+    text_ptr[i]->text  - text comments for current
+                         keyword.
+    text_ptr[i]->compression - type of compression used
+         on "text" PNG_TEXT_COMPRESSION_NONE or
+         PNG_TEXT_COMPRESSION_zTXt
+    num_text    - number of comments in text_ptr
+
+    png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y,
+        unit_type);
+    offset_x  - positive offset from the left
+                     edge of the screen
+    offset_y  - positive offset from the top
+                     edge of the screen
+    unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER
+
+    png_set_pHYs(png_ptr, info_ptr, res_x, res_y,
+        unit_type);
+    res_x       - pixels/unit physical resolution
+                  in x direction
+    res_y       - pixels/unit physical resolution
+                  in y direction
+    unit_type   - PNG_RESOLUTION_UNKNOWN,
+                  PNG_RESOLUTION_METER
+
+In PNG files, the alpha channel in an image is the level of opacity.
+If your data is supplied as a level of transparency, you can invert the
+alpha channel before you write it, so that 0 is fully transparent and 255
+(in 8-bit or paletted images) or 65535 (in 16-bit images) is fully opaque,
+with
+
+    png_set_invert_alpha(png_ptr);
+
+This must appear here instead of later with the other transformations
+because in the case of paletted images the tRNS chunk data has to
+be inverted before the tRNS chunk is written.  If your image is not a
+paletted image, the tRNS data (which in such cases represents a single
+color to be rendered as transparent) won't be changed.
+
+A quick word about text and num_text.  text is an array of png_text
+structures.  num_text is the number of valid structures in the array.
+If you want, you can use max_text to hold the size of the array, but
+libpng ignores it for writing (it does use it for reading).  Each
+png_text structure holds a keyword-text value, and a compression type.
+The compression types have the same valid numbers as the compression
+types of the image data.  Currently, the only valid number is zero.
+However, you can store text either compressed or uncompressed, unlike
+images which always have to be compressed.  So if you don't want the
+text compressed, set the compression type to PNG_TEXT_COMPRESSION_NONE.
+Until text gets around 1000 bytes, it is not worth compressing it.
+After the text has been written out to the file, the compression type
+is set to PNG_TEXT_COMPRESSION_NONE_WR or PNG_TEXT_COMPRESSION_zTXt_WR,
+so that it isn't written out again at the end (in case you are calling
+png_write_end() with the same struct.
+
+The keywords that are given in the PNG Specification are:
+
+    Title            Short (one line) title or
+                     caption for image
+    Author           Name of image's creator
+    Description      Description of image (possibly long)
+    Copyright        Copyright notice
+    Creation Time    Time of original image creation
+                     (usually RFC 1123 format, see below)
+    Software         Software used to create the image
+    Disclaimer       Legal disclaimer
+    Warning          Warning of nature of content
+    Source           Device used to create the image
+    Comment          Miscellaneous comment; conversion
+                     from other image format
+
+The keyword-text pairs work like this.  Keywords should be short
+simple descriptions of what the comment is about.  Some typical
+keywords are found in the PNG specification, as is some recommendations
+on keywords.  You can repeat keywords in a file.  You can even write
+some text before the image and some after.  For example, you may want
+to put a description of the image before the image, but leave the
+disclaimer until after, so viewers working over modem connections
+don't have to wait for the disclaimer to go over the modem before
+they start seeing the image.  Finally, keywords should be full
+words, not abbreviations.  Keywords and text are in the ISO 8859-1
+(Latin-1) character set (a superset of regular ASCII) and can not
+contain NUL characters, and should not contain control or other
+unprintable characters.  To make the comments widely readable, stick
+with basic ASCII, and avoid machine specific character set extensions
+like the IBM-PC character set.  The keyword must be present, but
+you can leave off the text string on non-compressed pairs.
+Compressed pairs must have a text string, as only the text string
+is compressed anyway, so the compression would be meaningless.
+
+PNG supports modification time via the png_time structure.  Two
+conversion routines are proved, png_convert_from_time_t() for
+time_t and png_convert_from_struct_tm() for struct tm.  The
+time_t routine uses gmtime().  You don't have to use either of
+these, but if you wish to fill in the png_time structure directly,
+you should provide the time in universal time (GMT) if possible
+instead of your local time.  Note that the year number is the full
+year (e.g. 1998, rather than 98 - PNG is year 2000 compliant!), and
+that months start with 1.
+
+If you want to store the time of the original image creation, you should
+use a plain tEXt chunk with the "Creation Time" keyword.  This is
+necessary because the "creation time" of a PNG image is somewhat vague,
+depending on whether you mean the PNG file, the time the image was
+created in a non-PNG format, a still photo from which the image was
+scanned, or possibly the subject matter itself.  In order to facilitate
+machine-readable dates, it is recommended that the "Creation Time"
+tEXt chunk use RFC 1123 format dates (e.g. 22 May 1997 18:07:10 GMT"),
+although this isn't a requirement.  Unlike the tIME chunk, the
+"Creation Time" tEXt chunk is not expected to be automatically changed
+by the software.  To facilitate the use of RFC 1123 dates, a function
+png_convert_to_rfc1123(png_timep) is provided to convert from PNG
+time to an RFC 1123 format string.
+
+You are now ready to write all the file information up to the actual
+image data.  You do this with a call to png_write_info().
+
+    png_write_info(png_ptr, info_ptr);
+
+After you've written the file information, you can set up the library
+to handle any special transformations of the image data.  The various
+ways to transform the data will be described in the order that they
+should occur.  This is important, as some of these change the color
+type and/or bit depth of the data, and some others only work on
+certain color types and bit depths.  Even though each transformation
+checks to see if it has data that it can do something with, you should
+make sure to only enable a transformation if it will be valid for the
+data.  For example, don't swap red and blue on grayscale data.
+
+PNG files store RGB pixels packed into 3 bytes.  This code tells
+the library to expect input data with 4 bytes per pixel
+
+    png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
+
+where the 0 is the value that will be put in the 4th byte, and the
+location is either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending
+upon whether the filler byte is stored XRGB or RGBX.
+
+PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as
+they can, resulting in, for example, 8 pixels per byte for 1 bit files.
+If the data is supplied at 1 pixel per byte, use this code, which will
+correctly pack the pixels into a single byte:
+
+    png_set_packing(png_ptr);
+
+PNG files reduce possible bit depths to 1, 2, 4, 8, and 16.  If your
+data is of another bit depth, you can write an sBIT chunk into the
+file so that decoders can get the original data if desired.
+    
+    /* Set the true bit depth of the image data */
+    if (color_type & PNG_COLOR_MASK_COLOR)
+    {
+        sig_bit.red = true_bit_depth;
+        sig_bit.green = true_bit_depth;
+        sig_bit.blue = true_bit_depth;
+    }
+    else
+    {
+        sig_bit.gray = true_bit_depth;
+    }
+    if (color_type & PNG_COLOR_MASK_ALPHA)
+    {
+        sig_bit.alpha = true_bit_depth;
+    }
+
+    png_set_sBIT(png_ptr, info_ptr, &sig_bit);
+
+If the data is stored in the row buffer in a bit depth other than
+one supported by PNG (e.g. 3 bit data in the range 0-7 for a 4-bit PNG),
+this will scale the values to appear to be the correct bit depth as
+is required by PNG.
+
+    png_set_shift(png_ptr, &sig_bit);
+
+PNG files store 16 bit pixels in network byte order (big-endian,
+ie. most significant bits first).  This code would be used if they are
+supplied the other way (little-endian, i.e. least significant bits
+first, the way PCs store them):
+
+    if (bit_depth > 8)
+       png_set_swap(png_ptr);
+
+If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you
+need to change the order the pixels are packed into bytes, you can use:
+
+    if (bit_depth < 8)
+       png_set_packswap(png_ptr);
+
+PNG files store 3 color pixels in red, green, blue order.  This code
+would be used if they are supplied as blue, green, red:
+
+    png_set_bgr(png_ptr);
+
+PNG files describe monochrome as black being zero and white being
+one. This code would be used if the pixels are supplied with this reversed
+(black being one and white being zero):
+
+    png_set_invert_mono(png_ptr);
+
+Finally, you can write your own transformation function if none of
+the existing ones meets your needs.  This is done by setting a callback
+with
+
+    png_set_write_user_transform_fn(png_ptr,
+       write_transform_fn);
+
+You must supply the function
+
+    void write_transform_fn(png_ptr ptr, row_info_ptr
+       row_info, png_bytep data) 
+
+See pngtest.c for a working example.  Your function will be called
+before any of the other transformations have been processed.
+
+It is possible to have libpng flush any pending output, either manually,
+or automatically after a certain number of lines have been written.  To
+flush the output stream a single time call:
+
+    png_write_flush(png_ptr);
+
+and to have libpng flush the output stream periodically after a certain
+number of scanlines have been written, call:
+
+    png_set_flush(png_ptr, nrows);
+
+Note that the distance between rows is from the last time png_write_flush()
+was called, or the first row of the image if it has never been called.
+So if you write 50 lines, and then png_set_flush 25, it will flush the
+output on the next scanline, and every 25 lines thereafter, unless
+png_write_flush() is called before 25 more lines have been written.
+If nrows is too small (less than about 10 lines for a 640 pixel wide
+RGB image) the image compression may decrease noticeably (although this
+may be acceptable for real-time applications).  Infrequent flushing will
+only degrade the compression performance by a few percent over images
+that do not use flushing.
+
+That's it for the transformations.  Now you can write the image data.
+The simplest way to do this is in one function call.  If have the
+whole image in memory, you can just call png_write_image() and libpng
+will write the image.  You will need to pass in an array of pointers to
+each row.  This function automatically handles interlacing, so you don't
+need to call png_set_interlace_handling() or call this function multiple
+times, or any of that other stuff necessary with png_write_rows().
+
+    png_write_image(png_ptr, row_pointers);
+
+where row_pointers is:
+
+    png_bytef *row_pointers[height];
+
+You can point to void or char or whatever you use for pixels.
+
+If you can't want to write the whole image at once, you can
+use png_write_rows() instead.  If the file is not interlaced,
+this is simple:
+
+    png_write_rows(png_ptr, row_pointers,
+       number_of_rows);
+
+row_pointers is the same as in the png_write_image() call.
+
+If you are just writing one row at a time, you can do this with
+row_pointers:
+
+    png_bytep row_pointer = row;
+
+    png_write_row(png_ptr, &row_pointer);
+
+When the file is interlaced, things can get a good deal more
+complicated.  The only currently (as of February 1998 -- PNG Specification
+version 1.0, dated October 1996) defined interlacing scheme for PNG files
+is the "Adam7" interlace scheme, that breaks down an
+image into seven smaller images of varying size.  libpng will build
+these images for you, or you can do them yourself.  If you want to
+build them yourself, see the PNG specification for details of which
+pixels to write when.
+
+If you don't want libpng to handle the interlacing details, just
+use png_set_interlace_handling() and call png_write_rows() the
+correct number of times to write all seven sub-images.
+
+If you want libpng to build the sub-images, call this before you start
+writing any rows:
+
+    number_of_passes =
+       png_set_interlace_handling(png_ptr);
+
+This will return the number of passes needed.  Currently, this
+is seven, but may change if another interlace type is added.
+
+Then write the complete image number_of_passes times.
+
+    png_write_rows(png_ptr, row_pointers,
+       number_of_rows);
+
+As some of these rows are not used, and thus return immediately,
+you may want to read about interlacing in the PNG specification,
+and only update the rows that are actually used.
+
+After you are finished writing the image, you should finish writing
+the file.  If you are interested in writing comments or time, you should
+pass an appropriately filled png_info pointer.  If you are not interested,
+you can pass NULL.
+
+    png_write_end(png_ptr, info_ptr);
+
+When you are done, you can free all memory used by libpng like this:
+
+    png_destroy_write_struct(&png_ptr, &info_ptr);
+
+You must free any data you allocated for info_ptr, such as comments,
+palette, or histogram, before the call to png_destroy_write_struct();
+
+For a more compact example of writing a PNG image, see the file example.c.
+
+
+.SH V. Modifying/Customizing libpng:
+
+There are two issues here.  The first is changing how libpng does
+standard things like memory allocation, input/output, and error handling.
+The second deals with more complicated things like adding new chunks,
+adding new transformations, and generally changing how libpng works.
+
+All of the memory allocation, input/output, and error handling in libpng
+goes through callbacks which are user settable.  The default routines are
+in pngmem.c, pngrio.c, pngwio.c, and pngerror.c respectively.  To change
+these functions, call the appropriate png_set_???_fn() function.
+
+Memory allocation is done through the functions png_large_malloc(),
+png_malloc(), png_realloc(), png_large_free(), and png_free().  These
+currently just call the standard C functions.  The large functions must
+handle exactly 64K, but they don't have to handle more than that.  If
+your pointers can't access more then 64K at a time, you will want to set
+MAXSEG_64K in zlib.h.  Since it is unlikely that the method of handling
+memory allocation on a platform will change between applications, these
+functions must be modified in the library at compile time.
+
+Input/Output in libpng is done through png_read() and png_write(),
+which currently just call fread() and fwrite().  The FILE * is stored in
+png_struct and is initialized via png_init_io().  If you wish to change
+the method of I/O, the library supplies callbacks that you can set
+through the function png_set_read_fn() and png_set_write_fn() at run
+time, instead of calling the png_init_io() function.  These functions
+also provide a void pointer that can be retrieved via the function
+png_get_io_ptr().  For example:
+
+    png_set_read_fn(png_structp png_ptr,
+        voidp io_ptr, png_rw_ptr read_data_fn)
+
+    png_set_write_fn(png_structp png_ptr,
+        voidp io_ptr, png_rw_ptr write_data_fn,
+        png_flush_ptr output_flush_fn);
+
+    voidp io_ptr = png_get_io_ptr(png_ptr);
+
+The replacement I/O functions should have prototypes as follows:
+
+    void user_read_data(png_structp png_ptr,
+        png_bytep data, png_uint_32 length);
+    void user_write_data(png_structp png_ptr,
+        png_bytep data, png_uint_32 length);
+    void user_flush_data(png_structp png_ptr);
+
+Supplying NULL for the read, write, or flush functions sets them back
+to using the default C stream functions.  It is an error to read from
+a write stream, and vice versa.
+
+Error handling in libpng is done through png_error() and png_warning().
+Errors handled through png_error() are fatal, meaning that png_error()
+should never return to its caller.  Currently, this is handled via
+setjmp() and longjmp(), but you could change this to do things like
+exit() if you should wish.  On non-fatal errors, png_warning() is called
+to print a warning message, and then control returns to the calling code.
+By default png_error() and png_warning() print a message on stderr via
+fprintf() unless the library is compiled with PNG_NO_STDIO defined.  If
+you wish to change the behavior of the error functions, you will need to
+set up your own message callbacks.  These functions are normally supplied
+at the time that the png_struct is created.  It is also possible to change
+these functions after png_create_???_struct() has been called by calling:
+
+    png_set_error_fn(png_structp png_ptr,
+        png_voidp error_ptr, png_error_ptr error_fn,
+        png_error_ptr warning_fn);
+
+    png_voidp error_ptr = png_get_error_ptr(png_ptr);
+
+If NULL is supplied for either error_fn or warning_fn, then the libpng
+default function will be used, calling fprintf() and/or longjmp() if a
+problem is encountered.  The replacement error functions should have
+parameters as follows:
+
+    void user_error_fn(png_structp png_ptr,
+        png_const_charp error_msg);
+    void user_warning_fn(png_structp png_ptr,
+        png_const_charp warning_msg);
+
+The motivation behind using setjmp() and longjmp() is the C++ throw and
+catch exception handling methods.  This makes the code much easier to write,
+as there is no need to check every return code of every function call.
+However, there are some uncertainties about the status of local variables
+after a longjmp, so the user may want to be careful about doing anything after
+setjmp returns non-zero besides returning itself.  Consult your compiler
+documentation for more details.
+
+If you need to read or write custom chunks, you will need to get deeper
+into the libpng code, as a mechanism has not yet been supplied for user
+callbacks with custom chunks.  First, read the PNG specification, and have
+a first level of understanding of how it works.  Pay particular attention
+to the sections that describe chunk names, and look at how other chunks
+were designed, so you can do things similarly.  Second, check out the
+sections of libpng that read and write chunks.  Try to find a chunk that
+is similar to yours and copy off of it.  More details can be found in the
+comments inside the code.  A way of handling unknown chunks in a generic
+method, potentially via callback functions, would be best.
+
+If you wish to write your own transformation for the data, look through
+the part of the code that does the transformations, and check out some of
+the simpler ones to get an idea of how they work.  Try to find a similar
+transformation to the one you want to add and copy off of it.  More details
+can be found in the comments inside the code itself.
+
+Configuring for 16 bit platforms:
+
+You may need to change the png_large_malloc() and png_large_free()
+routines in pngmem.c, as these are required to allocate 64K, although
+there is already support for many of the common DOS compilers.  Also,
+you will want to look into zconf.h to tell zlib (and thus libpng) that
+it cannot allocate more then 64K at a time.  Even if you can, the memory
+won't be accessible.  So limit zlib and libpng to 64K by defining MAXSEG_64K.
+
+Configuring for DOS:
+
+For DOS users which only have access to the lower 640K, you will
+have to limit zlib's memory usage via a png_set_compression_mem_level()
+call.  See zlib.h or zconf.h in the zlib library for more information.
+
+Configuring for Medium Model:
+
+Libpng's support for medium model has been tested on most of the popular
+compilers.  Make sure MAXSEG_64K gets defined, USE_FAR_KEYWORD gets
+defined, and FAR gets defined to far in pngconf.h, and you should be
+all set.  Everything in the library (except for zlib's structure) is
+expecting far data.  You must use the typedefs with the p or pp on
+the end for pointers (or at least look at them and be careful).  Make
+note that the row's of data are defined as png_bytepp which is a
+unsigned char far * far *.
+
+Configuring for gui/windowing platforms:
+
+You will need to write new error and warning functions that use the GUI
+interface, as described previously, and set them to be the error and
+warning functions at the time that png_create_???_struct() is called,
+in order to have them available during the structure initialization.
+They can be changed later via png_set_error_fn().  On some compilers,
+you may also have to change the memory allocators (png_malloc, etc.).
+
+Configuring for compiler xxx:
+
+All includes for libpng are in pngconf.h.  If you need to add/change/delete
+an include, this is the place to do it.  The includes that are not
+needed outside libpng are protected by the PNG_INTERNAL definition,
+which is only defined for those routines inside libpng itself.  The
+files in libpng proper only include png.h, which includes pngconf.h.
+
+Configuring zlib:
+
+There are special functions to configure the compression.  Perhaps the
+most useful one changes the compression level, which currently uses
+input compression values in the range 0 - 9.  The library normally
+uses the default compression level (Z_DEFAULT_COMPRESSION = 6).  Tests
+have shown that for a large majority of images, compression values in
+the range 3-6 compress nearly as well as higher levels, and do so much
+faster.  For online applications it may be desirable to have maximum speed
+(Z_BEST_SPEED = 1).  With versions of zlib after v0.99, you can also
+specify no compression (Z_NO_COMPRESSION = 0), but this would create
+files larger than just storing the raw bitmap.  You can specify the
+compression level by calling:
+
+    png_set_compression_level(png_ptr, level);
+
+Another useful one is to reduce the memory level used by the library.
+The memory level defaults to 8, but it can be lowered if you are
+short on memory (running DOS, for example, where you only have 640K).
+
+    png_set_compression_mem_level(png_ptr, level);
+
+The other functions are for configuring zlib.  They are not recommended
+for normal use and may result in writing an invalid PNG file.  See
+zlib.h for more information on what these mean.
+
+    png_set_compression_strategy(png_ptr,
+        strategy);
+    png_set_compression_window_bits(png_ptr,
+        window_bits);
+    png_set_compression_method(png_ptr, method);
+
+Controlling row filtering:
+
+If you want to control whether libpng uses filtering or not, which
+filters are used, and how it goes about picking row filters, you
+can call one of these functions.  The selection and configuration
+of row filters can have a significant impact on the size and
+encoding speed and a somewhat lesser impact on the decoding speed
+of an image.  Filtering is enabled by default for RGB and grayscale
+images (with and without alpha), and for 8-bit paletted images, but
+not for paletted images with bit depths less than 8 bits/pixel.
+
+The 'method' parameter sets the main filtering method, which is
+currently only '0' in the PNG 1.0 specification.  The 'filters'
+parameter sets which filter(s), if any, should be used for each
+scanline.  Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERS
+to turn filtering on and off, respectively.
+
+Individual filter types are PNG_FILTER_NONE, PNG_FILTER_SUB,
+PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, which can be bitwise
+ORed together '|' to specify one or more filters to use.  These
+filters are described in more detail in the PNG specification.  If
+you intend to change the filter type during the course of writing
+the image, you should start with flags set for all of the filters
+you intend to use so that libpng can initialize its internal
+structures appropriately for all of the filter types.
+
+    filters = PNG_FILTER_NONE | PNG_FILTER_SUB
+       | PNG_FILTER_UP;
+    png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE,
+       filters);
+
+It is also possible to influence how libpng chooses from among the
+available filters.  This is done in two ways - by telling it how
+important it is to keep the same filter for successive rows, and
+by telling it the relative computational costs of the filters.
+
+    double weights[3] = {1.5, 1.3, 1.1},
+       costs[PNG_FILTER_VALUE_LAST] =
+       {1.0, 1.3, 1.3, 1.5, 1.7};
+
+    png_set_filter_selection(png_ptr,
+       PNG_FILTER_SELECTION_WEIGHTED, 3,
+       weights, costs);
+
+The weights are multiplying factors which indicate to libpng that row
+should be the same for successive rows unless another row filter is that
+many times better than the previous filter.  In the above example, if
+the previous 3 filters were SUB, SUB, NONE, the SUB filter could have a
+"sum of absolute differences" 1.5 x 1.3 times higher than other filters
+and still be chosen, while the NONE filter could have a sum 1.1 times
+higher than other filters and still be chosen.  Unspecified weights are
+taken to be 1.0, and the specified weights should probably be declining
+like those above in order to emphasize recent filters over older filters.
+
+The filter costs specify for each filter type a relative decoding cost
+to be considered when selecting row filters.  This means that filters
+with higher costs are less likely to be chosen over filters with lower
+costs, unless their "sum of absolute differences" is that much smaller.
+The costs do not necessarily reflect the exact computational speeds of
+the various filters, since this would unduly influence the final image
+size.
+
+Note that the numbers above were invented purely for this example and
+are given only to help explain the function usage.  Little testing has
+been done to find optimum values for either the costs or the weights.
+
+Removing unwanted object code:
+
+There are a bunch of #define's in pngconf.h that control what parts of
+libpng are compiled.  All the defines end in _SUPPORTED.  If you are
+never going to use an ability, you can change the #define to #undef
+before recompiling libpng and save yourself code and data space.
+You can also turn a number of them off en masse with a compiler directive
+that defines PNG_READ[or WRITE]_TRANSFORMS_NOT_SUPPORTED, or
+PNG_READ[or WRITE]_ANCILLARY_CHUNKS_NOT_SUPPORTED, or all four,
+along with directives to turn on any of the capabilities that you do
+want.  The PNG_READ[or WRITE]_TRANSFORMS_NOT_SUPPORTED directives disable
+the extra transformations but still leave the library fully capable of reading
+and writing PNG files with all known public chunks [except for sPLT].
+Use of the PNG_READ[or WRITE]_ANCILLARY_CHUNKS_NOT_SUPPORTED directive
+produces a library that is incapable of reading or writing ancillary chunks.
+If you are not using the progressive reading capability, you can
+turn that off with PNG_PROGRESSIVE_READ_NOT_SUPPORTED (don't confuse
+this with the INTERLACING capability, which you'll still have).
+
+All the reading and writing specific code are in separate files, so the
+linker should only grab the files it needs.  However, if you want to
+make sure, or if you are building a stand alone library, all the
+reading files start with pngr and all the writing files start with
+pngw.  The files that don't match either (like png.c, pngtrans.c, etc.)
+are used for both reading and writing, and always need to be included.
+The progressive reader is in pngpread.c
+
+If you are creating or distributing a dynamically linked library (a .so
+or DLL file), you should not remove or disable any parts of the library,
+as this will cause applications linked with different versions of the
+library to fail if they call functions not available in your library.
+The size of the library itself should not be an issue, because only
+those sections which are actually used will be loaded into memory.
+
+
+Changes to Libpng from version 0.88
+
+It should be noted that versions of libpng later than 0.96 are not
+distributed by the original libpng author, Guy Schalnat, nor by
+Andreas Dilger, who had taken over from Guy during 1996 and 1997, and
+distributed versions 0.89 through 0.96, but rather by another member
+of the original PNG Group, Glenn Randers-Pehrson.  Guy and Andreas are
+still alive and well, but they have moved on to other things.
+
+The old libpng functions png_read_init(), png_write_init(),
+png_info_init(), png_read_destroy(), and png_write_destory() have been
+moved to PNG_INTERNAL in version 0.95 to discourage their use.  The
+preferred method of creating and initializing the libpng structures is
+via the png_create_read_struct(), png_create_write_struct(), and
+png_create_info_struct() because they isolate the size of the structures
+from the application, allow version error checking, and also allow the
+use of custom error handling routines during the initialization, which
+the old functions do not.  The functions png_read_destroy() and
+png_write_destroy() do not actually free the memory that libpng
+allocated for these structs, but just reset the data structures, so they
+can be used instead of png_destroy_read_struct() and
+png_destroy_write_struct() if you feel there is too much system overhead
+allocating and freeing the png_struct for each image read.
+
+Setting the error callbacks via png_set_message_fn() before
+png_read_init() as was suggested in libpng-0.88 is no longer supported
+because this caused applications which do not use custom error functions
+to fail if the png_ptr was not initialized to zero.  It is still possible
+to set the error callbacks AFTER png_read_init(), or to change them with
+png_set_error_fn(), which is essentially the same function, but with a
+new name to force compilation errors with applications that try to use
+the old method.
+
+.SH NOTE
+
+Note about libpng version numbers:
+
+Due to various miscommunications, unforeseen code incompatibilities
+and occasional factors outside the authors' control, version numbering
+on the library has not always been consistent and straightforward.
+The following table summarizes matters since version 0.89c, which was
+the first widely used release:
+
+   source     png.h   png.h   shared-lib
+   version    string    int   version
+   -------    ------  ------  ----------
+   0.89c      0.89        89  1.0.89
+   0.90       0.90        90  0.90  [should be 2.0.90]
+   0.95       0.95        95  0.95  [should be 2.0.95]
+   0.96       0.96        96  0.96  [should be 2.0.96]
+   0.97b      1.00.97     97  1.0.1 [should be 2.0.97]
+   0.97c      0.97        97  2.0.97
+   0.98       0.98        98  2.0.98
+   0.99       0.99        98  2.0.99
+   0.99a-m    0.99        99  2.0.99
+   1.00       1.00       100  2.1.0 [int should be 10000]
+   1.0.0      1.0.0      100  2.1.0 [int should be 10000]
+   1.0.1      1.0.1    10001  2.1.0
+
+Henceforth the source version will match the shared-library
+minor and patch numbers; the shared-library major version number will be
+used for changes in backward compatibility, as it is intended.
+The PNG_PNGLIB_VER macro, which is not used within libpng but
+is available for applications, is an unsigned integer of the form
+xyyzz corresponding to the source version x.y.z (leading zeros in y and z).
+ 
+.SH "SEE ALSO"
+libpngpf(3), png(5)
+.LP
+.IR libpng :
+.IP
+ftp://ftp.uu.net/graphics/png
+http://www.cdrom.com/pub/png
+
+.LP
+.IR zlib :
+.IP
+(generally) at the same location as
+.I libpng
+or at
+.br
+ftp://ftp.uu.net/pub/archiving/zip/zlib
+.br
+http://www.cdrom.com/pub/infozip/zlib
+
+.LP
+.IR PNG specification: RFC 2083
+.IP
+(generally) at the same location as
+.I libpng
+or at
+.br
+ftp://ds.internic.net/rfc/rfc2083.txt
+.br
+or (as a W3C Recommendation) at
+.br
+http://www.w3.org/TR/REC-png.html
+
+.LP
+In the case of any inconsistency between the PNG specification
+and this library, the specification takes precedence.
+
+.SH AUTHORS
+This man page: Glenn Randers-Pehrson
+<randeg@alumni.rpi.edu>
+  
+Contributing Authors: John Bowler, Kevin Bracey, Sam Bushell, Andreas Dilger,
+Magnus Holmgren, Tom Lane, Dave Martindale, Glenn Randers-Pehrson,
+Greg Roelofs, Guy Eric Schalnat, Paul Schmidt, Tom Tanner, Willem van
+Schaik, Tim Wegner.
+<png-implement@dworkin.wustl.edu>
+
+The contributing authors would like to thank all those who helped
+with testing, bug fixes, and patience.  This wouldn't have been
+possible without all of you.
+
+Thanks to Frank J. T. Wojcik for helping with the documentation.
+  
+Libpng version 1.0.1 March 15, 1998:
+Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc.
+Currently maintained by Glenn Randers-Pehrson (randeg@alumni.rpi.edu).
+
+Supported by the PNG development group
+.br
+(png-implement@dworkin.wustl.edu).
+
+.SH COPYRIGHT NOTICE:
+
+The PNG Reference Library (libpng) is supplied "AS IS".  The Contributing
+Authors and Group 42, Inc. disclaim all warranties, expressed or implied,
+including, without limitation, the warranties of merchantability and of
+fitness for any purpose.  The Contributing Authors and Group 42, Inc.
+assume no liability for direct, indirect, incidental, special, exemplary,
+or consequential damages, which may result from the use of the PNG
+Reference Library, even if advised of the possibility of such damage.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+source code, or portions hereof, for any purpose, without fee, subject
+to the following restrictions:
+
+ 1. The origin of this source code must not be
+    misrepresented.
+
+ 2. Altered versions must be plainly marked as such
+    and must not be misrepresented as being the
+    original source.
+
+ 3. This Copyright notice may not be removed or
+    altered from any source or altered source
+    distribution.
+
+The Contributing Authors and Group 42, Inc. specifically permit, without
+fee, and encourage the use of this source code as a component to
+supporting the PNG file format in commercial products.  If you use this
+source code in a product, acknowledgment is not required but would be
+appreciated.
+
+.\" end of man page
+
diff --git a/src/png/libpngpf.3 b/src/png/libpngpf.3
new file mode 100644
index 0000000000..7ba582ebe2
--- /dev/null
+++ b/src/png/libpngpf.3
@@ -0,0 +1,342 @@
+.TH LIBPNGPF 3 "March 15, 1998"
+.SH NAME
+libpng \- Portable Network Graphics (PNG) Reference Library
+(private functions)
+.SH SYNOPSIS
+#include <png.h>
+
+void png_build_gamma_table (png_structp png_ptr);
+
+void png_build_grayscale_palette (int bit_depth, png_colorp
+palette);
+
+void png_calculate_crc (png_structp png_ptr, png_bytep ptr,
+png_size_t length);
+void png_check_chunk_name (png_structp png_ptr, png_bytep
+chunk_name);
+
+png_size_t png_check_keyword (png_structp png_ptr, png_charp
+key, png_charpp new_key);
+
+void png_combine_row (png_structp png_ptr, png_bytep row, int
+mask);
+
+void png_correct_palette (png_structp png_ptr, png_colorp
+palette, int num_palette);
+
+int png_crc_error (png_structp png_ptr);
+
+int png_crc_finish (png_structp png_ptr, png_uint_32 skip);
+
+void png_crc_read (png_structp png_ptr, png_bytep buf,
+png_size_t length);
+
+png_voidp png_create_struct (int type);
+
+void png_destroy_struct (png_voidp struct_ptr);
+
+void png_do_background (png_row_infop row_info, png_bytep row,
+png_color_16p trans_values, png_color_16p background,
+png_color_16p background_1, png_bytep gamma_table, png_bytep
+gamma_from_1, png_bytep gamma_to_1, png_uint_16pp gamma_16,
+png_uint_16pp gamma_16_from_1, png_uint_16pp gamma_16_to_1, int
+gamma_shift);
+
+void png_do_bgr (png_row_infop row_info, png_bytep row);
+
+void png_do_chop (png_row_infop row_info, png_bytep row);
+
+void png_do_dither (png_row_infop row_info, png_bytep row,
+png_bytep palette_lookup, png_bytep dither_lookup);
+
+void png_do_expand (png_row_infop row_info, png_bytep row,
+png_color_16p trans_value);
+
+void png_do_expand_palette (png_row_infop row_info, png_bytep
+row, png_colorp palette, png_bytep trans, int num_trans);
+
+void png_do_gamma (png_row_infop row_info, png_bytep row,
+png_bytep gamma_table, png_uint_16pp gamma_16_table, int
+gamma_shift);
+
+void png_do_gray_to_rgb (png_row_infop row_info, png_bytep
+row);
+
+void png_do_invert (png_row_infop row_info, png_bytep row);
+
+void png_do_pack (png_row_infop row_info, png_bytep row,
+png_uint_32 bit_depth);
+
+void png_do_packswap (png_row_infop row_info, png_bytep row);
+
+void png_do_read_filler (png_row_infop row_info, png_bytep row,
+png_uint_32 filler, png_uint_32 flags);
+
+void png_do_read_interlace (png_row_infop row_info, png_bytep
+row, int pass, png_uint_32 transformations);
+
+void png_do_read_invert_alpha (png_row_infop row_info,
+png_bytep row);
+
+void png_do_read_swap_alpha (png_row_infop row_info, png_bytep
+row);
+
+void png_do_read_transformations (png_structp png_ptr);
+
+void png_do_rgb_to_gray (png_row_infop row_info, png_bytep
+row);
+
+void png_do_shift (png_row_infop row_info, png_bytep row,
+png_color_8p bit_depth);
+
+void png_do_strip_filler (png_row_infop row_info, png_bytep
+row, png_uint_32 flags);
+
+void png_do_swap (png_row_infop row_info, png_bytep row);
+
+void png_do_unpack (png_row_infop row_info, png_bytep row);
+
+void png_do_unshift (png_row_infop row_info, png_bytep row,
+png_color_8p sig_bits);
+
+void png_do_write_interlace (png_row_infop row_info, png_bytep
+row, int pass);
+
+void png_do_write_invert_alpha (png_row_infop row_info,
+png_bytep row);
+
+void png_do_write_swap_alpha (png_row_infop row_info, png_bytep
+row);
+
+void png_do_write_transformations (png_structp png_ptr);
+
+void *png_far_to_near (png_structp png_ptr,png_voidp ptr,
+int check);
+
+void png_flush (png_structp png_ptr);
+
+png_int_32 png_get_int_32 (png_bytep buf);
+
+png_uint_16 png_get_uint_16 (png_bytep buf);
+
+png_uint_32 png_get_uint_32 (png_bytep buf);
+
+void png_handle_bKGD (png_structp png_ptr, png_infop info_ptr,
+png_uint_32 length);
+
+void png_handle_cHRM (png_structp png_ptr, png_infop info_ptr,
+png_uint_32 length);
+
+void png_handle_gAMA (png_structp png_ptr, png_infop info_ptr,
+png_uint_32 length);
+
+void png_handle_hIST (png_structp png_ptr, png_infop info_ptr,
+png_uint_32 length);
+
+void png_handle_IEND (png_structp png_ptr, png_infop info_ptr,
+png_uint_32 length);
+
+void png_handle_IHDR (png_structp png_ptr, png_infop info_ptr,
+png_uint_32 length);
+
+void png_handle_oFFs (png_structp png_ptr, png_infop info_ptr,
+png_uint_32 length);
+
+void png_handle_pCAL (png_structp png_ptr, png_infop info_ptr,
+png_uint_32 length);
+
+void png_handle_pHYs (png_structp png_ptr, png_infop info_ptr,
+png_uint_32 length);
+
+void png_handle_PLTE (png_structp png_ptr, png_infop info_ptr,
+png_uint_32 length);
+
+void png_handle_sBIT (png_structp png_ptr, png_infop info_ptr,
+png_uint_32 length);
+
+void png_handle_sRGB (png_structp png_ptr, png_infop info_ptr,
+png_uint_32 length);
+
+void png_handle_tEXt (png_structp png_ptr, png_infop info_ptr,
+png_uint_32 length);
+
+void png_handle_tIME (png_structp png_ptr, png_infop info_ptr,
+png_uint_32 length);
+
+void png_handle_tRNS (png_structp png_ptr, png_infop info_ptr,
+png_uint_32 length);
+
+void png_handle_unknown (png_structp png_ptr, png_infop
+info_ptr, png_uint_32 length);
+
+void png_handle_zTXt (png_structp png_ptr, png_infop info_ptr,
+png_uint_32 length);
+
+void png_info_destroy (png_structp png_ptr, png_infop
+info_ptr);
+
+void png_init_read_transformations (png_structp png_ptr);
+
+void png_process_IDAT_data (png_structp png_ptr, png_bytep
+buffer, png_size_t buffer_length);
+
+void png_process_some_data (png_structp png_ptr, png_infop
+info_ptr);
+
+void png_push_check_crc (png_structp png_ptr);
+
+void png_push_crc_finish (png_structp png_ptr);
+
+void png_push_crc_skip (png_structp png_ptr, png_uint_32
+length);
+
+void png_push_fill_buffer (png_structp png_ptr, png_bytep
+buffer, png_size_t length);
+
+void png_push_handle_tEXt (png_structp png_ptr, png_infop
+info_ptr, png_uint_32 length);
+
+void png_push_handle_unknown (png_structp png_ptr, png_infop
+info_ptr, png_uint_32 length);
+
+void png_push_handle_zTXt (png_structp png_ptr, png_infop
+info_ptr, png_uint_32 length);
+
+void png_push_have_end (png_structp png_ptr, png_infop
+info_ptr);
+
+void png_push_have_info (png_structp png_ptr, png_infop
+info_ptr);
+
+void png_push_have_row (png_structp png_ptr, png_bytep row);
+
+void png_push_process_row (png_structp png_ptr);
+
+void png_push_read_chunk (png_structp png_ptr, png_infop
+info_ptr);
+
+void png_push_read_end (png_structp png_ptr, png_infop
+info_ptr);
+
+void png_push_read_IDAT (png_structp png_ptr);
+
+void png_push_read_sig (png_structp png_ptr, png_infop
+info_ptr);
+
+void png_push_read_tEXt (png_structp png_ptr, png_infop
+info_ptr);
+
+void png_push_read_zTXt (png_structp png_ptr, png_infop
+info_ptr);
+
+void png_push_restore_buffer (png_structp png_ptr, png_bytep
+buffer, png_size_t buffer_length);
+
+void png_push_save_buffer (png_structp png_ptr);
+
+void png_read_data (png_structp png_ptr, png_bytep data,
+png_size_t length);
+
+void png_read_filter_row (png_structp png_ptr, png_row_infop
+row_info, png_bytep row, png_bytep prev_row, int filter);
+
+void png_read_finish_row (png_structp png_ptr);
+
+void png_read_init (png_structp png_ptr);
+
+void png_read_push_finish_row (png_structp png_ptr);
+
+void png_read_start_row (png_structp png_ptr);
+
+void png_read_transform_info (png_structp png_ptr, png_infop
+info_ptr);
+
+void png_reset_crc (png_structp png_ptr);
+
+void png_save_int_32 (png_bytep buf, png_int_32 i);
+
+void png_save_uint_16 (png_bytep buf, unsigned int i);
+
+void png_save_uint_32 (png_bytep buf, png_uint_32 i);
+
+void png_write_bKGD (png_structp png_ptr, png_color_16p values,
+int color_type);
+
+void png_write_cHRM (png_structp png_ptr, double white_x,
+double white_y, double red_x, double red_y, double green_x,
+double green_y, double blue_x, double blue_y);
+
+void png_write_data (png_structp png_ptr, png_bytep data,
+png_size_t length);
+void png_write_filtered_row (png_structp png_ptr, png_bytep
+filtered_row);
+
+void png_write_find_filter (png_structp png_ptr, png_row_infop
+row_info);
+
+void png_write_finish_row (png_structp png_ptr);
+
+void png_write_gAMA (png_structp png_ptr, double file_gamma);
+
+void png_write_hIST (png_structp png_ptr, png_uint_16p hist,
+int num_hist);
+
+void png_write_init (png_structp png_ptr);
+
+void png_write_IDAT (png_structp png_ptr, png_bytep data,
+png_size_t length);
+
+void png_write_IEND (png_structp png_ptr);
+
+void png_write_IHDR (png_structp png_ptr, png_uint_32 width,
+png_uint_32 height, int bit_depth, int color_type, int
+compression_type, int filter_type, int interlace_type);
+
+void png_write_oFFs (png_structp png_ptr, png_uint_32 x_offset,
+png_uint_32 y_offset, int unit_type);
+
+void png_write_pCAL (png_structp png_ptr, png_charp purpose,
+png_int_32 X0, png_int_32 X1, int type, int nparams, png_charp
+units, png_charpp params);
+
+void png_write_pHYs (png_structp png_ptr, png_uint_32
+x_pixels_per_unit, png_uint_32 y_pixels_per_unit, int
+unit_type);
+
+void png_write_PLTE (png_structp png_ptr, png_colorp palette,
+png_uint_32 num_pal);
+
+void png_write_sBIT (png_structp png_ptr, png_color_8p sbit,
+int color_type);
+
+void png_write_sig (png_structp png_ptr);
+
+void png_write_sRGB (png_structp png_ptr, int intent);
+
+void png_write_start_row (png_structp png_ptr);
+
+void png_write_tEXt (png_structp png_ptr, png_charp key,
+png_charp text, png_size_t text_len);
+
+void png_write_tIME (png_structp png_ptr, png_timep mod_time);
+
+void png_write_tRNS (png_structp png_ptr, png_bytep trans,
+png_color_16p values, int number, int color_type);
+
+void png_write_zTXt (png_structp png_ptr, png_charp key,
+png_charp text, png_size_t text_len, int compression);
+
+voidpf png_zalloc (voidpf png_ptr, uInt items, uInt size);
+
+void png_zfree (voidpf png_ptr, voidpf ptr);
+
+.SH DESCRIPTION
+The functions listed above are used privately by libpng
+and are not recommended for use by applications.  They
+are listed alphabetically here as an aid to libpng maintainers.
+See png.h for more information on these functions.
+
+.SH SEE ALSO
+libpng(3), png(5)
+.SH AUTHOR
+Glenn Randers-Pehrson
diff --git a/src/png/makefile.bcc b/src/png/makefile.bcc
new file mode 100644
index 0000000000..e373ab64bb
--- /dev/null
+++ b/src/png/makefile.bcc
@@ -0,0 +1,107 @@
+# This file is special for Widows because setjmp 
+# is incompatible with the DOS version.
+# Alejandro Aguilar, 1995
+
+#
+# Borland C++ tools
+#
+IMPLIB  = Implib
+BCC     = Bcc +BccW16.cfg
+TLINK   = TLink
+TLIB    = TLib
+BRC     = Brc
+TASM    = Tasm
+
+
+#
+# Options
+#   
+IDE_LFLAGS =  -LC:\BC4\LIB
+IDE_RFLAGS =  -IC:\BC4\INCLUDE;..\zlib;
+LLATW16_winpngdlib =  -Twe
+RLATW16_winpngdlib =  -31
+BLATW16_winpngdlib = 
+LEAT_winpngdlib = $(LLATW16_winpngdlib)
+REAT_winpngdlib = $(RLATW16_winpngdlib)
+BEAT_winpngdlib = $(BLATW16_winpngdlib)
+ZLIB=..\..\..\lib\zlib.lib
+LOBJECTS = png.obj pngrcb.obj pngread.obj pngrtran.obj pngrutil.obj pngstub.obj\
+	pngtrans.obj pngwrite.obj pngwtran.obj pngwutil.obj
+
+#
+# Dependency List
+#
+Dep_winpng = \
+	..\..\..\lib\winpng.lib
+
+winpng : BccW16.cfg $(Dep_winpng)
+  echo MakeNode winpng
+
+Dep_winpngdlib = \
+	png.obj\
+	pngrcb.obj\
+	pngread.obj\
+	pngrtran.obj\
+	pngrutil.obj\
+	pngstub.obj\
+	pngtrans.obj\
+	pngwrite.obj\
+	pngwtran.obj\
+	pngwutil.obj
+
+$(ZLIB): 
+	cd ..\zlib
+	make -fmakefile.bcc
+	cd ..\png
+	
+winpng.lib : $(Dep_winpngdlib) $(ZLIB)  
+  copy /b $(ZLIB) winpng.lib
+  $(TLIB) $< $(IDE_BFLAGS) $(BEAT_winpngdlib) @&&|    
++$(LOBJECTS:.obj =.obj +)
+|
+
+png.obj :  png.c
+  $(BCC)   -P- -c $(CEAT_winpngdlib) -o$@ png.c
+
+pngrcb.obj :  pngrcb.c
+  $(BCC)   -P- -c $(CEAT_winpngdlib) -o$@ pngrcb.c
+
+pngread.obj :  pngread.c
+  $(BCC)   -P- -c $(CEAT_winpngdlib) -o$@ pngread.c
+
+pngrtran.obj :  pngrtran.c
+  $(BCC)   -P- -c $(CEAT_winpngdlib) -o$@ pngrtran.c
+
+pngrutil.obj :  pngrutil.c
+  $(BCC)   -P- -c $(CEAT_winpngdlib) -o$@ pngrutil.c
+
+pngstub.obj :  pngstub.c
+  $(BCC)   -P- -c $(CEAT_winpngdlib) -o$@ pngstub.c
+
+pngtrans.obj :  pngtrans.c
+  $(BCC)   -P- -c $(CEAT_winpngdlib) -o$@ pngtrans.c
+
+pngwrite.obj :  pngwrite.c
+  $(BCC)   -P- -c $(CEAT_winpngdlib) -o$@ pngwrite.c
+
+pngwtran.obj :  pngwtran.c
+  $(BCC)   -P- -c $(CEAT_winpngdlib) -o$@ pngwtran.c
+
+pngwutil.obj :  pngwutil.c
+  $(BCC)   -P- -c $(CEAT_winpngdlib) -o$@ pngwutil.c
+
+# Compiler configuration file
+BccW16.cfg :
+	Copy &&|
+-v
+-vi
+-X-
+-H
+-IC:\BC4\INCLUDE
+-H=winpng.csm
+-ml
+-WS
+-3
+-Ff
+| $@
+
diff --git a/src/png/makefile.dos b/src/png/makefile.dos
new file mode 100644
index 0000000000..514dc14c50
--- /dev/null
+++ b/src/png/makefile.dos
@@ -0,0 +1,76 @@
+#
+# File:		makefile.dos
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds winpng.lib library for Windows 3.1
+
+# Change WXDIR or WXWIN to wherever wxWindows is found
+WXDIR = $(WXWIN)
+WXLIB = $(WXDIR)\lib\wx.lib
+WXINC = $(WXDIR)\include
+
+WINPNGDIR = $(WXDIR)\utils\imatest\png
+WINPNGINC = $(WINPNGDIR)
+WINPNGLIB = ..\..\..\lib\winpng.lib
+
+INC = /I..\zlib
+
+LIBS=$(WXLIB) $(WINPNGLIB) libw llibcew commdlg ddeml shell # ctl3d
+
+# Set this to nothing if your compiler is MS C++ 7
+ZOPTION=
+
+!ifndef FINAL
+FINAL=0
+!endif
+
+PRECOMP=/YuWX.H 
+
+!if "$(FINAL)" == "0"
+OPT = /Od
+CPPFLAGS= /AL /W4 /Gt4 /Zi $(ZOPTION) /G2sw $(OPT) /Dwx_msw $(INC) # $(PRECOMP) /Fp$(WXDIR)\src\msw\wx.pch
+CFLAGS= /AL /W4 /Gt4 /Zi /G2sw /Od /Dwx_msw $(INC)
+LINKFLAGS=/NOD /CO /ONERROR:NOEXE
+!else
+# /Ox for real FINAL version
+OPT = /Ox
+CPPFLAGS= /AL /W4 /Gt4 /Zi /Os /G2sw $(OPT) /Dwx_msw $(INC) # $(PRECOMP) /Fp$(WXDIR)\src\msw\wx.pch
+CFLAGS= /AL /W4 /Gt4 /Zi /Os /G2sw /Dwx_msw $(INC)
+LINKFLAGS=/NOD /ONERROR:NOEXE
+!endif
+
+OBJECTS = png.obj pngrcb.obj pngread.obj pngrtran.obj pngrutil.obj pngstub.obj \
+ pngtrans.obj pngwrite.obj pngwtran.obj pngwutil.obj
+
+all:    $(WINPNGLIB)
+
+wx:
+        cd $(WXDIR)\src
+        nmake -f makefile.dos $(WXLIB) FINAL=$(FINAL)
+
+$(WINPNGLIB):      $(OBJECTS)
+        erase $(WINPNGLIB)
+        lib /PAGESIZE:128 @<<
+$(WINPNGLIB)
+y
+$(OBJECTS)
+nul
+;
+<<
+
+.c.obj:
+  cl $(CFLAGS) /c $*.c
+
+clean:
+        -erase *.obj
+        -erase *.exe
+        -erase *.lib
+        -erase *.sbr
+        -erase *.pdb
+
+cleanall:	clean
diff --git a/src/png/makefile.nt b/src/png/makefile.nt
new file mode 100644
index 0000000000..5e53a15a41
--- /dev/null
+++ b/src/png/makefile.nt
@@ -0,0 +1,64 @@
+#
+# File:		makefile.nt
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds winpng.lib library for Windows 3.1
+
+# Change WXDIR or WXWIN to wherever wxWindows is found
+WXDIR = $(WXWIN)
+WXLIB = $(WXDIR)\lib\wx.lib
+WXINC = $(WXDIR)\include
+
+WINPNGDIR = ..\png
+WINPNGINC = $(WINPNGDIR)
+WINPNGLIB = ..\..\..\lib\winpng.lib
+
+INC = /I..\zlib
+
+# Set this to nothing if your compiler is MS C++ 7
+ZOPTION=
+
+!ifndef FINAL
+FINAL=0
+!endif
+
+PRECOMP=/YuWX.H 
+
+!if "$(FINAL)" == "0"
+OPT = /Od
+CPPFLAGS= /W4 /Zi /MDd /GX $(ZOPTION) $(OPT) /Dwx_msw $(INC) # $(PRECOMP) /Fp$(WXDIR)\src\msw\wx.pch
+CFLAGS= /W4 /Zi /MDd /GX /Od /Dwx_msw $(INC)
+LINKFLAGS=/NOD /CO /ONERROR:NOEXE
+!else
+# /Ox for real FINAL version
+OPT = /O2
+CPPFLAGS= /W4 /MDd /GX /Dwx_msw $(INC) # $(PRECOMP) /Fp$(WXDIR)\src\msw\wx.pch
+CFLAGS= /W4 /MDd /GX /Dwx_msw $(INC)
+LINKFLAGS=/NOD /ONERROR:NOEXE
+!endif
+
+OBJECTS = png.obj pngread.obj pngrtran.obj pngrutil.obj \
+ pngpread.obj pngtrans.obj pngwrite.obj pngwtran.obj pngwutil.obj \
+ pngerror.obj pngmem.obj pngwio.obj pngrio.obj pngget.obj pngset.obj
+
+all:    $(WINPNGLIB)
+
+$(WINPNGLIB):      $(OBJECTS)
+        erase $(WINPNGLIB)
+        lib @<<
+-out:$(WINPNGLIB)
+$(OBJECTS)
+<<
+
+.c.obj:
+  cl -DWIN32 $(OPT) $(CFLAGS) /c $*.c
+
+clean:
+        erase *.obj *.exe *.lib
+
+cleanall:	clean
diff --git a/src/png/png.5 b/src/png/png.5
new file mode 100644
index 0000000000..30244aabb8
--- /dev/null
+++ b/src/png/png.5
@@ -0,0 +1,44 @@
+.TH PNG 5 "March 15, 1998"
+.SH NAME
+png \- Portable Network Graphics (PNG) format
+.SH DESCRIPTION
+PNG (Portable Network Graphics) is an extensible file format for the
+lossless, portable, well-compressed storage of raster images. PNG provides
+a patent-free replacement for GIF and can also replace many
+common uses of TIFF. Indexed-color, grayscale, and truecolor images are
+supported, plus an optional alpha channel. Sample depths range from
+1 to 16 bits. 
+.br
+
+PNG is designed to work well in online viewing applications, such as the
+World Wide Web, so it is fully streamable with a progressive display
+option. PNG is robust, providing both full file integrity checking and
+fast, simple detection of common transmission errors. Also, PNG can store
+gamma and chromaticity data for improved color matching on heterogeneous
+platforms. 
+
+.SH "SEE ALSO"
+.IR libpng(3), zlib(3), deflate(5), and zlib(5)
+.LP
+PNG specification:
+RFC 2083
+.IP
+.br
+ftp://ds.internic.net/rfc/rfc2083.txt
+.br
+or (as a W3C Recommendation) at
+.br
+http://www.w3.org/TR/REC-png.html
+.SH AUTHORS
+This man page: Glenn Randers-Pehrson
+.LP
+Portable Network Graphics (PNG) Specification Version 1.0 (October 1, 1996):
+Thomas Boutell and others (png-list@dworkin.wustl.edu).
+.LP
+
+.SH COPYRIGHT NOTICE
+The PNG specification is copyright (c) 1996 Massachussets Institute of
+Technology.  See the specification for conditions of use and distribution.
+.LP
+.\" end of man page
+
diff --git a/src/png/png.c b/src/png/png.c
new file mode 100644
index 0000000000..127b47b68f
--- /dev/null
+++ b/src/png/png.c
@@ -0,0 +1,304 @@
+
+/* png.c - location for general purpose libpng functions
+ *
+ * libpng 1.0.1
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Copyright (c) 1998, Glenn Randers-Pehrson
+ * March 15, 1998
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_EXTERN
+#include "png.h"
+
+/* Version information for C files.  This had better match the version
+ * string defined in png.h.
+ */
+char png_libpng_ver[12] = "1.0.1";
+
+/* Place to hold the signature string for a PNG file. */
+png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+
+/* Constant strings for known chunk types.  If you need to add a chunk,
+ * add a string holding the name here.  If you want to make the code
+ * portable to EBCDIC machines, use ASCII numbers, not characters.
+ */
+png_byte FARDATA png_IHDR[5] = { 73,  72,  68,  82, '\0'};
+png_byte FARDATA png_IDAT[5] = { 73,  68,  65,  84, '\0'};
+png_byte FARDATA png_IEND[5] = { 73,  69,  78,  68, '\0'};
+png_byte FARDATA png_PLTE[5] = { 80,  76,  84,  69, '\0'};
+png_byte FARDATA png_bKGD[5] = { 98,  75,  71,  68, '\0'};
+png_byte FARDATA png_cHRM[5] = { 99,  72,  82,  77, '\0'};
+png_byte FARDATA png_gAMA[5] = {103,  65,  77,  65, '\0'};
+png_byte FARDATA png_hIST[5] = {104,  73,  83,  84, '\0'};
+png_byte FARDATA png_oFFs[5] = {111,  70,  70, 115, '\0'};
+png_byte FARDATA png_pCAL[5] = {112,  67,  65,  76, '\0'};
+png_byte FARDATA png_pHYs[5] = {112,  72,  89, 115, '\0'};
+png_byte FARDATA png_sBIT[5] = {115,  66,  73,  84, '\0'};
+png_byte FARDATA png_sRGB[5] = {115,  82,  71,  66, '\0'};
+png_byte FARDATA png_tEXt[5] = {116,  69,  88, 116, '\0'};
+png_byte FARDATA png_tIME[5] = {116,  73,  77,  69, '\0'};
+png_byte FARDATA png_tRNS[5] = {116,  82,  78,  83, '\0'};
+png_byte FARDATA png_zTXt[5] = {122,  84,  88, 116, '\0'};
+
+/* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+/* start of interlace block */
+int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
+
+/* offset to next interlace block */
+int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
+
+/* start of interlace block in the y direction */
+int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
+
+/* offset to next interlace block in the y direction */
+int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
+
+/* Width of interlace block.  This is not currently used - if you need
+ * it, uncomment it here and in png.h
+int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1};
+*/
+
+/* Height of interlace block.  This is not currently used - if you need
+ * it, uncomment it here and in png.h
+int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
+*/
+
+/* Mask to determine which pixels are valid in a pass */
+int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
+
+/* Mask to determine which pixels to overwrite while displaying */
+int FARDATA png_pass_dsp_mask[] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
+
+
+/* Tells libpng that we have already handled the first "num_bytes" bytes
+ * of the PNG file signature.  If the PNG data is embedded into another
+ * stream we can set num_bytes = 8 so that libpng will not attempt to read
+ * or write any of the magic bytes before it starts on the IHDR.
+ */
+void
+png_set_sig_bytes(png_structp png_ptr, int num_bytes)
+{
+   png_debug(1, "in png_set_sig_bytes\n");
+   if (num_bytes > 8)
+      png_error(png_ptr, "Too many bytes for PNG signature.");
+
+   png_ptr->sig_bytes = num_bytes < 0 ? 0 : num_bytes;
+}
+
+/* Checks whether the supplied bytes match the PNG signature.  We allow
+ * checking less than the full 8-byte signature so that those apps that
+ * already read the first few bytes of a file to determine the file type
+ * can simply check the remaining bytes for extra assurance.  Returns
+ * an integer less than, equal to, or greater than zero if sig is found,
+ * respectively, to be less than, to match, or be greater than the correct
+ * PNG signature (this is the same behaviour as strcmp, memcmp, etc).
+ */
+int
+png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check)
+{
+   if (num_to_check > 8)
+      num_to_check = 8;
+   else if (num_to_check < 1)
+      return (0);
+
+   if (start > 7)
+      return (0);
+
+   if (start + num_to_check > 8)
+      num_to_check = 8 - start;
+
+   return ((int)(png_memcmp(&sig[start], &png_sig[start], num_to_check)));
+}
+
+/* (Obsolete) function to check signature bytes.  It does not allow one
+ * to check a partial signature.  This function will be removed in the
+ * future - use png_sig_cmp().
+ */
+int
+png_check_sig(png_bytep sig, int num)
+{
+  return ((int)!png_sig_cmp(sig, (png_size_t)0, (png_size_t)num));
+}
+
+/* Function to allocate memory for zlib. */
+voidpf
+png_zalloc(voidpf png_ptr, uInt items, uInt size)
+{
+   png_voidp ptr;
+   png_uint_32 num_bytes;
+
+   num_bytes = (png_uint_32)items * size;
+   ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes);
+   if (num_bytes > (png_uint_32)0x8000)
+   {
+      png_memset(ptr, 0, (png_size_t)0x8000L);
+      png_memset((png_bytep)ptr + (png_size_t)0x8000L, 0,
+         (png_size_t)(num_bytes - (png_uint_32)0x8000L));
+   }
+   else
+   {
+      png_memset(ptr, 0, (png_size_t)num_bytes);
+   }
+   return ((voidpf)ptr);
+}
+
+/* function to free memory for zlib */
+void
+png_zfree(voidpf png_ptr, voidpf ptr)
+{
+   png_free((png_structp)png_ptr, (png_voidp)ptr);
+}
+
+/* Reset the CRC variable to 32 bits of 1's.  Care must be taken
+ * in case CRC is > 32 bits to leave the top bits 0.
+ */
+void
+png_reset_crc(png_structp png_ptr)
+{
+   png_ptr->crc = crc32(0, Z_NULL, 0);
+}
+
+/* Calculate the CRC over a section of data.  We can only pass as
+ * much data to this routine as the largest single buffer size.  We
+ * also check that this data will actually be used before going to the
+ * trouble of calculating it.
+ */
+void
+png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length)
+{
+   int need_crc = 1;
+
+   if (png_ptr->chunk_name[0] & 0x20)                     /* ancillary */
+   {
+      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
+          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
+         need_crc = 0;
+   }
+   else                                                    /* critical */
+   {
+      if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
+         need_crc = 0;
+   }
+
+   if (need_crc)
+      png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length);
+}
+
+/* Allocate the memory for an info_struct for the application.  We don't
+ * really need the png_ptr, but it could potentially be useful in the
+ * future.  This should be used in favour of malloc(sizeof(png_info))
+ * and png_info_init() so that applications that want to use a shared
+ * libpng don't have to be recompiled if png_info changes size.
+ */
+png_infop
+png_create_info_struct(png_structp png_ptr)
+{
+   png_infop info_ptr;
+
+   png_debug(1, "in png_create_info_struct\n");
+   if(png_ptr == NULL) return (NULL);
+   if ((info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO)) != NULL)
+   {
+      png_info_init(info_ptr);
+   }
+
+   return (info_ptr);
+}
+
+/* This function frees the memory associated with a single info struct.
+ * Normally, one would use either png_destroy_read_struct() or
+ * png_destroy_write_struct() to free an info struct, but this may be
+ * useful for some applications.
+ */
+void
+png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)
+{
+   png_infop info_ptr = NULL;
+
+   png_debug(1, "in png_destroy_info_struct\n");
+   if (info_ptr_ptr != NULL)
+      info_ptr = *info_ptr_ptr;
+
+   if (info_ptr != NULL)
+   {
+      png_info_destroy(png_ptr, info_ptr);
+
+      png_destroy_struct((png_voidp)info_ptr);
+      *info_ptr_ptr = (png_infop)NULL;
+   }
+}
+
+/* Initialize the info structure.  This is now an internal function (0.89)
+ * and applications using it are urged to use png_create_info_struct()
+ * instead.
+ */
+void
+png_info_init(png_infop info_ptr)
+{
+   png_debug(1, "in png_info_init\n");
+   /* set everything to 0 */
+   png_memset(info_ptr, 0, sizeof (png_info));
+}
+
+/* This is an internal routine to free any memory that the info struct is
+ * pointing to before re-using it or freeing the struct itself.  Recall
+ * that png_free() checks for NULL pointers for us.
+ */
+void
+png_info_destroy(png_structp png_ptr, png_infop info_ptr)
+{
+#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
+   int i;
+
+   png_debug(1, "in png_info_destroy\n");
+   if (info_ptr->text != NULL)
+   {
+      for (i = 0; i < info_ptr->num_text; i++)
+      {
+         png_free(png_ptr, info_ptr->text[i].key);
+      }
+      png_free(png_ptr, info_ptr->text);
+   }
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+   png_free(png_ptr, info_ptr->pcal_purpose);
+   png_free(png_ptr, info_ptr->pcal_units);
+   if (info_ptr->pcal_params != NULL)
+   {
+      for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
+      {
+         png_free(png_ptr, info_ptr->pcal_params[i]);
+      }
+      png_free(png_ptr, info_ptr->pcal_params);
+   }
+#endif
+
+   png_info_init(info_ptr);
+}
+
+/* This function returns a pointer to the io_ptr associated with the user
+ * functions.  The application should free any memory associated with this
+ * pointer before png_write_destroy() or png_read_destroy() are called.
+ */
+png_voidp
+png_get_io_ptr(png_structp png_ptr)
+{
+   return (png_ptr->io_ptr);
+}
+
+#if !defined(PNG_NO_STDIO)
+/* Initialize the default input/output functions for the PNG file.  If you
+ * use your own read or write routines, you can call either png_set_read_fn()
+ * or png_set_write_fn() instead of png_init_io().
+ */
+void
+png_init_io(png_structp png_ptr, FILE *fp)
+{
+   png_debug(1, "in png_init_io\n");
+   png_ptr->io_ptr = (png_voidp)fp;
+}
+#endif
diff --git a/src/png/png.h b/src/png/png.h
new file mode 100644
index 0000000000..36541e916e
--- /dev/null
+++ b/src/png/png.h
@@ -0,0 +1,2063 @@
+
+/* png.h - header file for PNG reference library
+ *
+ * libpng 1.0.1
+ * For conditions of distribution and use, see the COPYRIGHT NOTICE below.
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Copyright (c) 1998 Glenn Randers-Pehrson
+ * March 15, 1998
+ *
+ * Note about libpng version numbers:
+ *
+ *    Due to various miscommunications, unforeseen code incompatibilities
+ *    and occasional factors outside the authors' control, version numbering
+ *    on the library has not always been consistent and straightforward.
+ *    The following table summarizes matters since version 0.89c, which was
+ *    the first widely used release:
+ *
+ *      source                    png.h   png.h   shared-lib
+ *      version                   string    int   version
+ *      -------                   ------  ------  ----------
+ *      0.89c ("1.0 beta 3")      0.89        89  1.0.89
+ *      0.90  ("1.0 beta 4")      0.90        90  0.90  [should have been 2.0.90]
+ *      0.95  ("1.0 beta 5")      0.95        95  0.95  [should have been 2.0.95]
+ *      0.96  ("1.0 beta 6")      0.96        96  0.96  [should have been 2.0.96]
+ *      0.97b ("1.00.97 beta 7")  1.00.97     97  1.0.1 [should have been 2.0.97]
+ *      0.97c                     0.97        97  2.0.97
+ *      0.98                      0.98        98  2.0.98
+ *      0.99                      0.99        98  2.0.99
+ *      0.99a-m                   0.99        99  2.0.99
+ *      1.00                      1.00       100  2.1.0 [int should be 10000]
+ *      1.0.0                     1.0.0      100  2.1.0 [int should be 10000]
+ *      1.0.1                     1.0.1    10001  2.1.0
+ *
+ *    Henceforth the source version will match the shared-library minor
+ *    and patch numbers; the shared-library major version number will be
+ *    used for changes in backward compatibility, as it is intended.
+ *    The PNG_PNGLIB_VER macro, which is not used within libpng but
+ *    is available for applications, is an unsigned integer of the form
+ *    xyyzz corresponding to the source version x.y.z (leading zeros in y and z).
+ *    
+ *
+ * See libpng.txt for more information.  The PNG specification is available
+ * as RFC 2083 <ftp://ftp.uu.net/graphics/png/documents/>
+ * and as a W3C Recommendation <http://www.w3.org/TR/REC.png.html>
+ *
+ * Contributing Authors:
+ *    John Bowler
+ *    Kevin Bracey
+ *    Sam Bushell
+ *    Andreas Dilger
+ *    Magnus Holmgren
+ *    Tom Lane
+ *    Dave Martindale
+ *    Glenn Randers-Pehrson
+ *    Greg Roelofs
+ *    Guy Eric Schalnat
+ *    Paul Schmidt
+ *    Tom Tanner
+ *    Willem van Schaik
+ *    Tim Wegner
+ *
+ * The contributing authors would like to thank all those who helped
+ * with testing, bug fixes, and patience.  This wouldn't have been
+ * possible without all of you.
+ *
+ * Thanks to Frank J. T. Wojcik for helping with the documentation.
+ *
+ * COPYRIGHT NOTICE:
+ *
+ * The PNG Reference Library is supplied "AS IS".  The Contributing Authors
+ * and Group 42, Inc. disclaim all warranties, expressed or implied,
+ * including, without limitation, the warranties of merchantability and of
+ * fitness for any purpose.  The Contributing Authors and Group 42, Inc.
+ * assume no liability for direct, indirect, incidental, special, exemplary,
+ * or consequential damages, which may result from the use of the PNG
+ * Reference Library, even if advised of the possibility of such damage.
+ *
+ * Permission is hereby granted to use, copy, modify, and distribute this
+ * source code, or portions hereof, for any purpose, without fee, subject
+ * to the following restrictions:
+ * 1. The origin of this source code must not be misrepresented.
+ * 2. Altered versions must be plainly marked as such and must not be
+ *    misrepresented as being the original source.
+ * 3. This Copyright notice may not be removed or altered from any source or
+ *    altered source distribution.
+ *
+ * The Contributing Authors and Group 42, Inc. specifically permit, without
+ * fee, and encourage the use of this source code as a component to
+ * supporting the PNG file format in commercial products.  If you use this
+ * source code in a product, acknowledgment is not required but would be
+ * appreciated.
+ */
+
+#ifndef _PNG_H
+#define _PNG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* This is not the place to learn how to use libpng.  The file libpng.txt
+ * describes how to use libpng, and the file example.c summarizes it
+ * with some code on which to build.  This file is useful for looking
+ * at the actual function definitions and structure components.
+ */
+
+/* include the compression library's header */
+#include "zlib.h"
+
+/* include all user configurable info */
+#include "pngconf.h"
+
+/* This file is arranged in several sections.  The first section contains
+ * structure and type definitions.  The second section contains the external
+ * library functions, while the third has the internal library functions,
+ * which applications aren't expected to use directly.
+ */
+
+/* Version information for png.h - this should match the version in png.c */
+#define PNG_LIBPNG_VER_STRING "1.0.1"
+
+/* Careful here.  At one time, Guy wanted to use 082, but that would be octal.
+ * We must not include leading zeros.
+ * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only
+ * version 1.0.0 was mis-numbered 100 instead of 10000).  From
+ * version 1.0.1 it's    xxyyzz, where x=major, y=minor, z=bugfix */
+#define PNG_LIBPNG_VER    10001  /* 1.0.1 */
+
+/* variables declared in png.c - only it needs to define PNG_NO_EXTERN */
+#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
+/* Version information for C files, stored in png.c.  This had better match
+ * the version above.
+ */
+extern char png_libpng_ver[12];   /* need room for 99.99.99aa */
+
+/* Structures to facilitate easy interlacing.  See png.c for more details */
+extern int FARDATA png_pass_start[7];
+extern int FARDATA png_pass_inc[7];
+extern int FARDATA png_pass_ystart[7];
+extern int FARDATA png_pass_yinc[7];
+extern int FARDATA png_pass_mask[7];
+extern int FARDATA png_pass_dsp_mask[7];
+/* These aren't currently used.  If you need them, see png.c for more details
+extern int FARDATA png_pass_width[7];
+extern int FARDATA png_pass_height[7];
+*/
+#endif /* PNG_NO_EXTERN */
+
+/* Three color definitions.  The order of the red, green, and blue, (and the
+ * exact size) is not important, although the size of the fields need to
+ * be png_byte or png_uint_16 (as defined below).
+ */
+typedef struct png_color_struct
+{
+   png_byte red;
+   png_byte green;
+   png_byte blue;
+} png_color;
+typedef png_color FAR * png_colorp;
+typedef png_color FAR * FAR * png_colorpp;
+
+typedef struct png_color_16_struct
+{
+   png_byte index;    /* used for palette files */
+   png_uint_16 red;   /* for use in red green blue files */
+   png_uint_16 green;
+   png_uint_16 blue;
+   png_uint_16 gray;  /* for use in grayscale files */
+} png_color_16;
+typedef png_color_16 FAR * png_color_16p;
+typedef png_color_16 FAR * FAR * png_color_16pp;
+
+typedef struct png_color_8_struct
+{
+   png_byte red;   /* for use in red green blue files */
+   png_byte green;
+   png_byte blue;
+   png_byte gray;  /* for use in grayscale files */
+   png_byte alpha; /* for alpha channel files */
+} png_color_8;
+typedef png_color_8 FAR * png_color_8p;
+typedef png_color_8 FAR * FAR * png_color_8pp;
+
+/* png_text holds the text in a PNG file, and whether they are compressed
+   in the PNG file or not.  The "text" field points to a regular C string. */
+typedef struct png_text_struct
+{
+   int compression;        /* compression value, see PNG_TEXT_COMPRESSION_ */
+   png_charp key;          /* keyword, 1-79 character description of "text" */
+   png_charp text;         /* comment, may be an empty string (ie "") */
+   png_size_t text_length; /* length of "text" field */
+} png_text;
+typedef png_text FAR * png_textp;
+typedef png_text FAR * FAR * png_textpp;
+
+/* Supported compression types for text in PNG files (tEXt, and zTXt).
+ * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */
+#define PNG_TEXT_COMPRESSION_NONE_WR -3
+#define PNG_TEXT_COMPRESSION_zTXt_WR -2
+#define PNG_TEXT_COMPRESSION_NONE    -1
+#define PNG_TEXT_COMPRESSION_zTXt     0
+#define PNG_TEXT_COMPRESSION_LAST     1  /* Not a valid value */
+
+/* png_time is a way to hold the time in an machine independent way.
+ * Two conversions are provided, both from time_t and struct tm.  There
+ * is no portable way to convert to either of these structures, as far
+ * as I know.  If you know of a portable way, send it to me.  As a side
+ * note - PNG is Year 2000 compliant!
+ */
+typedef struct png_time_struct
+{
+   png_uint_16 year; /* full year, as in, 1995 */
+   png_byte month;   /* month of year, 1 - 12 */
+   png_byte day;     /* day of month, 1 - 31 */
+   png_byte hour;    /* hour of day, 0 - 23 */
+   png_byte minute;  /* minute of hour, 0 - 59 */
+   png_byte second;  /* second of minute, 0 - 60 (for leap seconds) */
+} png_time;
+typedef png_time FAR * png_timep;
+typedef png_time FAR * FAR * png_timepp;
+
+/* png_info is a structure that holds the information in a PNG file so
+ * that the application can find out the characteristics of the image.
+ * If you are reading the file, this structure will tell you what is
+ * in the PNG file.  If you are writing the file, fill in the information
+ * you want to put into the PNG file, then call png_write_info().
+ * The names chosen should be very close to the PNG specification, so
+ * consult that document for information about the meaning of each field.
+ *
+ * With libpng < 0.95, it was only possible to directly set and read the
+ * the values in the png_info_struct, which meant that the contents and
+ * order of the values had to remain fixed.  With libpng 0.95 and later,
+ * however, * there are now functions which abstract the contents of
+ * png_info_struct from the application, so this makes it easier to use
+ * libpng with dynamic libraries, and even makes it possible to use
+ * libraries that don't have all of the libpng ancillary chunk-handing
+ * functionality.
+ *
+ * In any case, the order of the parameters in png_info_struct should NOT
+ * be changed for as long as possible to keep compatibility with applications
+ * that use the old direct-access method with png_info_struct.
+ */
+typedef struct png_info_struct
+{
+   /* the following are necessary for every PNG file */
+   png_uint_32 width;       /* width of image in pixels (from IHDR) */
+   png_uint_32 height;      /* height of image in pixels (from IHDR) */
+   png_uint_32 valid;       /* valid chunk data (see PNG_INFO_ below) */
+   png_uint_32 rowbytes;    /* bytes needed to hold an untransformed row */
+   png_colorp palette;      /* array of color values (valid & PNG_INFO_PLTE) */
+   png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */
+   png_uint_16 num_trans;   /* number of transparent palette color (tRNS) */
+   png_byte bit_depth;      /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */
+   png_byte color_type;     /* see PNG_COLOR_TYPE_ below (from IHDR) */
+   png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */
+   png_byte filter_type;    /* must be PNG_FILTER_TYPE_BASE (from IHDR) */
+   png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
+
+   /* The following is informational only on read, and not used on writes. */
+   png_byte channels;       /* number of data channels per pixel (1, 3, 4)*/
+   png_byte pixel_depth;    /* number of bits per pixel */
+   png_byte spare_byte;     /* to align the data, and for future use */
+   png_byte signature[8];   /* magic bytes read by libpng from start of file */
+
+   /* The rest of the data is optional.  If you are reading, check the
+    * valid field to see if the information in these are valid.  If you
+    * are writing, set the valid field to those chunks you want written,
+    * and initialize the appropriate fields below.
+    */
+
+#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED) || \
+    defined(PNG_READ_GAMMA_SUPPORTED)
+   /* The gAMA chunk describes the gamma characteristics of the system
+    * on which the image was created, normally in the range [1.0, 2.5].
+    * Data is valid if (valid & PNG_INFO_gAMA) is non-zero.
+    */
+   float gamma; /* gamma value of image, if (valid & PNG_INFO_gAMA) */
+#endif /* PNG_READ_gAMA_SUPPORTED || PNG_WRITE_gAMA_SUPPORTED */
+
+#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
+    /* GR-P, 0.96a */
+    /* Data valid if (valid & PNG_INFO_sRGB) non-zero. */
+   png_byte srgb_intent; /* sRGB rendering intent [0, 1, 2, or 3] */
+#endif /* PNG_READ_sRGB_SUPPORTED || PNG_WRITE_sRGB_SUPPORTED */
+
+#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
+    defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
+   /* The tEXt and zTXt chunks contain human-readable textual data in
+    * uncompressed and compressed forms, respectively.  The data in "text"
+    * is an array of pointers to uncompressed, null-terminated C strings.
+    * Each chunk has a keyword which describes the textual data contained
+    * in that chunk.  Keywords are not required to be unique, and the text
+    * string may be empty.  Any number of text chunks may be in an image.
+    */
+   int num_text; /* number of comments read/to write */
+   int max_text; /* current size of text array */
+   png_textp text; /* array of comments read/to write */
+#endif /* PNG_READ_tEXt/zTXt_SUPPORTED || PNG_WRITE_tEXt/zTXt_SUPPORTED */
+#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED)
+   /* The tIME chunk holds the last time the displayed image data was
+    * modified.  See the png_time struct for the contents of this struct.
+    */
+   png_time mod_time;
+#endif /* PNG_READ_tIME_SUPPORTED || PNG_WRITE_tIME_SUPPORTED */
+#if defined(PNG_READ_sBIT_SUPPORTED) || defined(PNG_WRITE_sBIT_SUPPORTED)
+   /* The sBIT chunk specifies the number of significant high-order bits
+    * in the pixel data.  Values are in the range [1, bit_depth], and are
+    * only specified for the channels in the pixel data.  The contents of
+    * the low-order bits is not specified.  Data is valid if
+    * (valid & PNG_INFO_sBIT) is non-zero.
+    */
+   png_color_8 sig_bit; /* significant bits in color channels */
+#endif /* PNG_READ_sBIT_SUPPORTED || PNG_WRITE_sBIT_SUPPORTED */
+#if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_WRITE_tRNS_SUPPORTED)
+   /* The tRNS chunk supplies transparency data for paletted images and
+    * other image types that don't need a full alpha channel.  There are
+    * "num_trans" transparency values for a paletted image, stored in the
+    * same order as the palette colors, starting from index 0.  Values
+    * for the data are in the range [0, 255], ranging from fully transparent
+    * to fully opaque, respectively.  For non-paletted images, there is a
+    * single color specified which should be treated as fully transparent.
+    * Data is valid if (valid & PNG_INFO_tRNS) is non-zero.
+    */
+   png_bytep trans; /* transparent values for paletted image */
+   png_color_16 trans_values; /* transparent color for non-palette image */
+#endif /* PNG_READ_tRNS_SUPPORTED || PNG_WRITE_tRNS_SUPPORTED */
+#if defined(PNG_READ_bKGD_SUPPORTED) || defined(PNG_WRITE_bKGD_SUPPORTED) || \
+    defined(PNG_READ_BACKGROUND_SUPPORTED)
+   /* The bKGD chunk gives the suggested image background color if the
+    * display program does not have its own background color and the image
+    * is needs to composited onto a background before display.  The colors
+    * in "background" are normally in the same color space/depth as the
+    * pixel data.  Data is valid if (valid & PNG_INFO_bKGD) is non-zero.
+    */
+   png_color_16 background;
+#endif /* PNG_READ_bKGD_SUPPORTED || PNG_WRITE_bKGD_SUPPORTED */
+#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
+   /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards
+    * and downwards from the top-left corner of the display, page, or other
+    * application-specific co-ordinate space.  See the PNG_OFFSET_ defines
+    * below for the unit types.  Valid if (valid & PNG_INFO_oFFs) non-zero.
+    */
+   png_uint_32 x_offset; /* x offset on page */
+   png_uint_32 y_offset; /* y offset on page */
+   png_byte offset_unit_type; /* offset units type */
+#endif /* PNG_READ_oFFs_SUPPORTED || PNG_WRITE_oFFs_SUPPORTED */
+#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
+   /* The pHYs chunk gives the physical pixel density of the image for
+    * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_
+    * defines below).  Data is valid if (valid & PNG_INFO_pHYs) is non-zero.
+    */
+   png_uint_32 x_pixels_per_unit; /* horizontal pixel density */
+   png_uint_32 y_pixels_per_unit; /* vertical pixel density */
+   png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
+#endif /* PNG_READ_pHYs_SUPPORTED || PNG_WRITE_pHYs_SUPPORTED */
+#if defined(PNG_READ_hIST_SUPPORTED) || defined(PNG_WRITE_hIST_SUPPORTED)
+   /* The hIST chunk contains the relative frequency or importance of the
+    * various palette entries, so that a viewer can intelligently select a
+    * reduced-color palette, if required.  Data is an array of "num_palette"
+    * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST)
+    * is non-zero.
+    */
+   png_uint_16p hist;
+#endif /* PNG_READ_hIST_SUPPORTED || PNG_WRITE_hIST_SUPPORTED */
+#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
+   /* The cHRM chunk describes the CIE color characteristics of the monitor
+    * on which the PNG was created.  This data allows the viewer to do gamut
+    * mapping of the input image to ensure that the viewer sees the same
+    * colors in the image as the creator.  Values are in the range
+    * [0.0, 0.8].  Data valid if (valid & PNG_INFO_cHRM) non-zero.
+    */
+   float x_white;
+   float y_white;
+   float x_red;
+   float y_red;
+   float x_green;
+   float y_green;
+   float x_blue;
+   float y_blue;
+#endif /* PNG_READ_cHRM_SUPPORTED || PNG_WRITE_cHRM_SUPPORTED */
+#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED)
+   /* The pCAL chunk describes a transformation between the stored pixel
+    * values and original physcical data values used to create the image.
+    * The integer range [0, 2^bit_depth - 1] maps to the floating-point
+    * range given by [pcal_X0, pcal_X1], and are further transformed by a
+    * (possibly non-linear) transformation function given by "pcal_type"
+    * and "pcal_params" into "pcal_units".  Please see the PNG_EQUATION_
+    * defines below, and the PNG-Group's Scientific Visualization extension
+    * chunks document png-scivis-19970203 for a complete description of the
+    * transformations and how they should be implemented, as well as the
+    * png-extensions document for a description of the ASCII parameter
+    * strings.  Data values are valid if (valid & PNG_INFO_pCAL) non-zero.
+    */
+   png_charp pcal_purpose;  /* pCAL chunk description string */
+   png_int_32 pcal_X0;      /* minimum value */
+   png_int_32 pcal_X1;      /* maximum value */
+   png_charp pcal_units;    /* Latin-1 string giving physical units */
+   png_charpp pcal_params;  /* ASCII strings containing parameter values */
+   png_byte pcal_type;      /* equation type (see PNG_EQUATION_ below) */
+   png_byte pcal_nparams;   /* number of parameters given in pcal_params */
+#endif /* PNG_READ_pCAL_SUPPORTED || PNG_WRITE_pCAL_SUPPORTED */
+} png_info;
+typedef png_info FAR * png_infop;
+typedef png_info FAR * FAR * png_infopp;
+
+/* These describe the color_type field in png_info. */
+/* color type masks */
+#define PNG_COLOR_MASK_PALETTE    1
+#define PNG_COLOR_MASK_COLOR      2
+#define PNG_COLOR_MASK_ALPHA      4
+
+/* color types.  Note that not all combinations are legal */
+#define PNG_COLOR_TYPE_GRAY 0
+#define PNG_COLOR_TYPE_PALETTE  (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
+#define PNG_COLOR_TYPE_RGB        (PNG_COLOR_MASK_COLOR)
+#define PNG_COLOR_TYPE_RGB_ALPHA  (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
+#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)
+
+/* This is for compression type. PNG 1.0 only defines the single type. */
+#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */
+#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE
+
+/* This is for filter type. PNG 1.0 only defines the single type. */
+#define PNG_FILTER_TYPE_BASE      0 /* Single row per-byte filtering */
+#define PNG_FILTER_TYPE_DEFAULT   PNG_FILTER_TYPE_BASE
+
+/* These are for the interlacing type.  These values should NOT be changed. */
+#define PNG_INTERLACE_NONE        0 /* Non-interlaced image */
+#define PNG_INTERLACE_ADAM7       1 /* Adam7 interlacing */
+#define PNG_INTERLACE_LAST        2 /* Not a valid value */
+
+/* These are for the oFFs chunk.  These values should NOT be changed. */
+#define PNG_OFFSET_PIXEL          0 /* Offset in pixels */
+#define PNG_OFFSET_MICROMETER     1 /* Offset in micrometers (1/10^6 meter) */
+#define PNG_OFFSET_LAST           2 /* Not a valid value */
+
+/* These are for the pCAL chunk.  These values should NOT be changed. */
+#define PNG_EQUATION_LINEAR       0 /* Linear transformation */
+#define PNG_EQUATION_BASE_E       1 /* Exponential base e transform */
+#define PNG_EQUATION_ARBITRARY    2 /* Arbitrary base exponential transform */
+#define PNG_EQUATION_HYPERBOLIC   3 /* Hyperbolic sine transformation */
+#define PNG_EQUATION_LAST         4 /* Not a valid value */
+
+/* These are for the pHYs chunk.  These values should NOT be changed. */
+#define PNG_RESOLUTION_UNKNOWN    0 /* pixels/unknown unit (aspect ratio) */
+#define PNG_RESOLUTION_METER      1 /* pixels/meter */
+#define PNG_RESOLUTION_LAST       2 /* Not a valid value */
+
+/* These are for the sRGB chunk.  These values should NOT be changed. */
+#define PNG_sRGB_INTENT_SATURATION 0
+#define PNG_sRGB_INTENT_PERCEPTUAL 1
+#define PNG_sRGB_INTENT_ABSOLUTE   2
+#define PNG_sRGB_INTENT_RELATIVE   3
+#define PNG_sRGB_INTENT_LAST       4 /* Not a valid value */
+                        
+
+
+/* These determine if an ancillary chunk's data has been successfully read
+ * from the PNG header, or if the application has filled in the corresponding
+ * data in the info_struct to be written into the output file.  The values
+ * of the PNG_INFO_<chunk> defines should NOT be changed.
+ */
+#define PNG_INFO_gAMA 0x0001
+#define PNG_INFO_sBIT 0x0002
+#define PNG_INFO_cHRM 0x0004
+#define PNG_INFO_PLTE 0x0008
+#define PNG_INFO_tRNS 0x0010
+#define PNG_INFO_bKGD 0x0020
+#define PNG_INFO_hIST 0x0040
+#define PNG_INFO_pHYs 0x0080
+#define PNG_INFO_oFFs 0x0100
+#define PNG_INFO_tIME 0x0200
+#define PNG_INFO_pCAL 0x0400
+#define PNG_INFO_sRGB 0x0800   /* GR-P, 0.96a */
+
+/* This is used for the transformation routines, as some of them
+ * change these values for the row.  It also should enable using
+ * the routines for other purposes.
+ */
+typedef struct png_row_info_struct
+{
+   png_uint_32 width; /* width of row */
+   png_uint_32 rowbytes; /* number of bytes in row */
+   png_byte color_type; /* color type of row */
+   png_byte bit_depth; /* bit depth of row */
+   png_byte channels; /* number of channels (1, 2, 3, or 4) */
+   png_byte pixel_depth; /* bits per pixel (depth * channels) */
+} png_row_info;
+
+typedef png_row_info FAR * png_row_infop;
+typedef png_row_info FAR * FAR * png_row_infopp;
+
+/* These are the function types for the I/O functions, and the functions which
+ * modify the default I/O functions to user I/O functions.  The png_error_ptr
+ * type should match that of user supplied warning and error functions, while
+ * the png_rw_ptr type should match that of the user read/write data functions.
+ */
+typedef struct png_struct_def png_struct;
+typedef png_struct FAR * png_structp;
+
+typedef void (*png_error_ptr) PNGARG((png_structp, png_const_charp));
+typedef void (*png_rw_ptr) PNGARG((png_structp, png_bytep, png_size_t));
+typedef void (*png_flush_ptr) PNGARG((png_structp));
+typedef void (*png_read_status_ptr) PNGARG((png_structp, png_uint_32, int));
+typedef void (*png_write_status_ptr) PNGARG((png_structp, png_uint_32, int));
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+typedef void (*png_progressive_info_ptr) PNGARG((png_structp, png_infop));
+typedef void (*png_progressive_end_ptr) PNGARG((png_structp, png_infop));
+typedef void (*png_progressive_row_ptr) PNGARG((png_structp, png_bytep,
+   png_uint_32, int));
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+typedef void (*png_user_transform_ptr) PNGARG((png_structp,
+    png_row_infop, png_bytep));
+#endif /* PNG_READ|WRITE_USER_TRANSFORM_SUPPORTED */
+
+/* The structure that holds the information to read and write PNG files.
+ * The only people who need to care about what is inside of this are the
+ * people who will be modifying the library for their own special needs.
+ * It should NOT be accessed directly by an application, except to store
+ * the jmp_buf.
+ */
+
+struct png_struct_def
+{
+   jmp_buf jmpbuf;            /* used in png_error */
+
+   png_error_ptr error_fn;    /* function for printing errors and aborting */
+   png_error_ptr warning_fn;  /* function for printing warnings */
+   png_voidp error_ptr;       /* user supplied struct for error functions */
+   png_rw_ptr write_data_fn;  /* function for writing output data */
+   png_rw_ptr read_data_fn;   /* function for reading input data */
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+   png_user_transform_ptr read_user_transform_fn; /* user read transform */
+   png_user_transform_ptr write_user_transform_fn; /* user write transform */
+#endif
+   png_voidp io_ptr;          /* ptr to application struct for I/O functions*/
+
+   png_uint_32 mode;          /* tells us where we are in the PNG file */
+   png_uint_32 flags;         /* flags indicating various things to libpng */
+   png_uint_32 transformations; /* which transformations to perform */
+
+   z_stream zstream;          /* pointer to decompression structure (below) */
+   png_bytep zbuf;            /* buffer for zlib */
+   png_size_t zbuf_size;      /* size of zbuf */
+   int zlib_level;            /* holds zlib compression level */
+   int zlib_method;           /* holds zlib compression method */
+   int zlib_window_bits;      /* holds zlib compression window bits */
+   int zlib_mem_level;        /* holds zlib compression memory level */
+   int zlib_strategy;         /* holds zlib compression strategy */
+
+   png_uint_32 width;         /* width of image in pixels */
+   png_uint_32 height;        /* height of image in pixels */
+   png_uint_32 num_rows;      /* number of rows in current pass */
+   png_uint_32 usr_width;     /* width of row at start of write */
+   png_uint_32 rowbytes;      /* size of row in bytes */
+   png_uint_32 irowbytes;     /* size of current interlaced row in bytes */
+   png_uint_32 iwidth;        /* width of current interlaced row in pixels */
+   png_uint_32 row_number;    /* current row in interlace pass */
+   png_bytep prev_row;        /* buffer to save previous (unfiltered) row */
+   png_bytep row_buf;         /* buffer to save current (unfiltered) row */
+   png_bytep sub_row;         /* buffer to save "sub" row when filtering */
+   png_bytep up_row;          /* buffer to save "up" row when filtering */
+   png_bytep avg_row;         /* buffer to save "avg" row when filtering */
+   png_bytep paeth_row;       /* buffer to save "Paeth" row when filtering */
+   png_row_info row_info;     /* used for transformation routines */
+
+   png_uint_32 idat_size;     /* current IDAT size for read */
+   png_uint_32 crc;           /* current chunk CRC value */
+   png_colorp palette;        /* palette from the input file */
+   png_uint_16 num_palette;   /* number of color entries in palette */
+   png_uint_16 num_trans;     /* number of transparency values */
+   png_byte chunk_name[5];    /* null-terminated name of current chunk */
+   png_byte compression;      /* file compression type (always 0) */
+   png_byte filter;           /* file filter type (always 0) */
+   png_byte interlaced;       /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
+   png_byte pass;             /* current interlace pass (0 - 6) */
+   png_byte do_filter;        /* row filter flags (see PNG_FILTER_ below ) */
+   png_byte color_type;       /* color type of file */
+   png_byte bit_depth;        /* bit depth of file */
+   png_byte usr_bit_depth;    /* bit depth of users row */
+   png_byte pixel_depth;      /* number of bits per pixel */
+   png_byte channels;         /* number of channels in file */
+   png_byte usr_channels;     /* channels at start of write */
+   png_byte sig_bytes;        /* magic bytes read/written from start of file */
+
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+   png_byte filler;           /* filler byte for 24->32-bit pixel expansion */
+#endif /* PNG_READ_FILLER_SUPPORTED */
+#if defined(PNG_READ_bKGD_SUPPORTED)
+   png_byte background_gamma_type;
+   float background_gamma;
+   png_color_16 background;   /* background color in screen gamma space */
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+   png_color_16 background_1; /* background normalized to gamma 1.0 */
+#endif /* PNG_READ_GAMMA && PNG_READ_bKGD_SUPPORTED */
+#endif /* PNG_READ_bKGD_SUPPORTED */
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+   png_flush_ptr output_flush_fn;/* Function for flushing output */
+   png_uint_32 flush_dist;    /* how many rows apart to flush, 0 - no flush */
+   png_uint_32 flush_rows;    /* number of rows written since last flush */
+#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+   int gamma_shift;      /* number of "insignificant" bits 16-bit gamma */
+   float gamma;          /* file gamma value */
+   float screen_gamma;   /* screen gamma value (display_gamma/viewing_gamma */
+#endif /* PNG_READ_GAMMA_SUPPORTED */
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+   png_bytep gamma_table;     /* gamma table for 8 bit depth files */
+   png_bytep gamma_from_1;    /* converts from 1.0 to screen */
+   png_bytep gamma_to_1;      /* converts from file to 1.0 */
+   png_uint_16pp gamma_16_table; /* gamma table for 16 bit depth files */
+   png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */
+   png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */
+#endif /* PNG_READ_GAMMA_SUPPORTED || PNG_WRITE_GAMMA_SUPPORTED */
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined (PNG_READ_sBIT_SUPPORTED)
+   png_color_8 sig_bit;       /* significant bits in each available channel */
+#endif /* PNG_READ_GAMMA_SUPPORTED || PNG_READ_sBIT_SUPPORTED */
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+   png_color_8 shift;         /* shift for significant bit tranformation */
+#endif /* PNG_READ_SHIFT_SUPPORTED || PNG_WRITE_SHIFT_SUPPORTED */
+#if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+   png_bytep trans;           /* transparency values for paletted files */
+   png_color_16 trans_values; /* transparency values for non-paletted files */
+#endif /* PNG_READ_tRNS_SUPPORTED || PNG_READ_BACKGROUND_SUPPORTED */
+   png_read_status_ptr read_row_fn;   /* called after each row is decoded */
+   png_write_status_ptr write_row_fn; /* called after each row is encoded */
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+   png_progressive_info_ptr info_fn; /* called after header data fully read */
+   png_progressive_row_ptr row_fn;   /* called after each prog. row is decoded */
+   png_progressive_end_ptr end_fn;   /* called after image is complete */
+   png_bytep save_buffer_ptr;        /* current location in save_buffer */
+   png_bytep save_buffer;            /* buffer for previously read data */
+   png_bytep current_buffer_ptr;     /* current location in current_buffer */
+   png_bytep current_buffer;         /* buffer for recently used data */
+   png_uint_32 push_length;          /* size of current input chunk */
+   png_uint_32 skip_length;          /* bytes to skip in input data */
+   png_size_t save_buffer_size;      /* amount of data now in save_buffer */
+   png_size_t save_buffer_max;       /* total size of save_buffer */
+   png_size_t buffer_size;           /* total amount of available input data */
+   png_size_t current_buffer_size;   /* amount of data now in current_buffer */
+   int process_mode;                 /* what push library is currently doing */
+   int cur_palette;                  /* current push library palette index */
+#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
+   png_size_t current_text_size;     /* current size of text input data */
+   png_size_t current_text_left;     /* how much text left to read in input */
+   png_charp current_text;           /* current text chunk buffer */
+   png_charp current_text_ptr;       /* current location in current_text */
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED && PNG_READ_tEXt/zTXt_SUPPORTED */
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
+/* for the Borland special 64K segment handler */
+   png_bytepp offset_table_ptr;
+   png_bytep offset_table;
+   png_uint_16 offset_table_number;
+   png_uint_16 offset_table_count;
+   png_uint_16 offset_table_count_free;
+#endif /* __TURBOC__&&!_Windows&&!__FLAT__ */
+#if defined(PNG_READ_DITHER_SUPPORTED)
+   png_bytep palette_lookup;         /* lookup table for dithering */
+   png_bytep dither_index;           /* index translation for palette files */
+#endif /* PNG_READ_DITHER_SUPPORTED */
+#if defined(PNG_READ_DITHER_SUPPORTED) || defined(PNG_READ_hIST_SUPPORTED)
+   png_uint_16p hist;                /* histogram */
+#endif
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+   png_byte heuristic_method;        /* heuristic for row filter selection */
+   png_byte num_prev_filters;        /* number of weights for previous rows */
+   png_bytep prev_filters;           /* filter type(s) of previous row(s) */
+   png_uint_16p filter_weights;      /* weight(s) for previous line(s) */
+   png_uint_16p inv_filter_weights;  /* 1/weight(s) for previous line(s) */
+   png_uint_16p filter_costs;        /* relative filter calculation cost */
+   png_uint_16p inv_filter_costs;    /* 1/relative filter calculation cost */
+#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+   png_charp time_buffer;            /* String to hold RFC 1123 time text */
+#endif /* PNG_TIME_RFC1123_SUPPORTED */
+};
+
+typedef png_struct FAR * FAR * png_structpp;
+
+/* Here are the function definitions most commonly used.  This is not
+ * the place to find out how to use libpng.  See libpng.txt for the
+ * full explanation, see example.c for the summary.  This just provides
+ * a simple one line of the use of each function.
+ */
+
+/* Tell lib we have already handled the first <num_bytes> magic bytes.
+ * Handling more than 8 bytes from the beginning of the file is an error.
+ */
+extern PNG_EXPORT(void,png_set_sig_bytes) PNGARG((png_structp png_ptr,
+   int num_bytes));
+
+/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a
+ * PNG file.  Returns zero if the supplied bytes match the 8-byte PNG
+ * signature, and non-zero otherwise.  Having num_to_check == 0 or
+ * start > 7 will always fail (ie return non-zero).
+ */
+extern PNG_EXPORT(int,png_sig_cmp) PNGARG((png_bytep sig, png_size_t start,
+   png_size_t num_to_check));
+
+/* Simple signature checking function.  This is the same as calling
+ * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n).
+ */
+extern PNG_EXPORT(int,png_check_sig) PNGARG((png_bytep sig, int num));
+
+/* Allocate and initialize png_ptr struct for reading, and any other memory. */
+extern PNG_EXPORT(png_structp,png_create_read_struct)
+   PNGARG((png_const_charp user_png_ver, voidp error_ptr,
+   png_error_ptr error_fn, png_error_ptr warn_fn));
+
+/* Allocate and initialize png_ptr struct for reading, and any other memory */
+extern PNG_EXPORT(png_structp,png_create_write_struct)
+   PNGARG((png_const_charp user_png_ver, voidp error_ptr,
+   png_error_ptr error_fn, png_error_ptr warn_fn));
+
+/* Write a PNG chunk - size, type, (optional) data, CRC. */
+extern PNG_EXPORT(void,png_write_chunk) PNGARG((png_structp png_ptr,
+   png_bytep chunk_name, png_bytep data, png_size_t length));
+
+/* Write the start of a PNG chunk - length and chunk name. */
+extern PNG_EXPORT(void,png_write_chunk_start) PNGARG((png_structp png_ptr,
+   png_bytep chunk_name, png_uint_32 length));
+
+/* Write the data of a PNG chunk started with png_write_chunk_start(). */
+extern PNG_EXPORT(void,png_write_chunk_data) PNGARG((png_structp png_ptr,
+   png_bytep data, png_size_t length));
+
+/* Finish a chunk started with png_write_chunk_start() (includes CRC). */
+extern PNG_EXPORT(void,png_write_chunk_end) PNGARG((png_structp png_ptr));
+
+/* Allocate and initialize the info structure */
+extern PNG_EXPORT(png_infop,png_create_info_struct)
+   PNGARG((png_structp png_ptr));
+
+/* Initialize the info structure (old interface - NOT DLL EXPORTED) */
+extern void png_info_init PNGARG((png_infop info_ptr));
+
+/* Writes all the PNG information before the image. */
+extern PNG_EXPORT(void,png_write_info) PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+
+/* read the information before the actual image data. */
+extern PNG_EXPORT(void,png_read_info) PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+extern PNG_EXPORT(png_charp,png_convert_to_rfc1123)
+   PNGARG((png_structp png_ptr, png_timep ptime));
+#endif /* PNG_TIME_RFC1123_SUPPORTED */
+
+#if defined(PNG_WRITE_tIME_SUPPORTED)
+/* convert from a struct tm to png_time */
+extern PNG_EXPORT(void,png_convert_from_struct_tm) PNGARG((png_timep ptime,
+   struct tm FAR * ttime));
+
+/* convert from time_t to png_time.  Uses gmtime() */
+extern PNG_EXPORT(void,png_convert_from_time_t) PNGARG((png_timep ptime,
+   time_t ttime));
+#endif /* PNG_WRITE_tIME_SUPPORTED */
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+/* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha if available. */
+extern PNG_EXPORT(void,png_set_expand) PNGARG((png_structp png_ptr));
+#endif /* PNG_READ_EXPAND_SUPPORTED */
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* Use blue, green, red order for pixels. */
+extern PNG_EXPORT(void,png_set_bgr) PNGARG((png_structp png_ptr));
+#endif /* PNG_READ_BGR_SUPPORTED || PNG_WRITE_BGR_SUPPORTED */
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+/* Expand the grayscale to 24 bit RGB if necessary. */
+extern PNG_EXPORT(void,png_set_gray_to_rgb) PNGARG((png_structp png_ptr));
+#endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED */
+
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+/* Reduce RGB to grayscale. (Not yet implemented) */
+extern PNG_EXPORT(void,png_set_rgb_to_gray) PNGARG((png_structp png_ptr));
+#endif /* PNG_READ_RGB_TO_GRAY_SUPPORTED */
+
+extern PNG_EXPORT(void,png_build_grayscale_palette) PNGARG((int bit_depth,
+   png_colorp palette));
+
+#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+extern PNG_EXPORT(void,png_set_strip_alpha) PNGARG((png_structp png_ptr));
+#endif /* PNG_READ_STRIP_ALPHA_SUPPORTED */
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
+    defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+extern PNG_EXPORT(void,png_set_swap_alpha) PNGARG((png_structp png_ptr));
+#endif /* PNG_READ_SWAP_ALPHA_SUPPORTED || PNG_WRITE_SWAP_ALPHA_SUPPORTED */
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
+    defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+extern PNG_EXPORT(void,png_set_invert_alpha) PNGARG((png_structp png_ptr));
+#endif /* PNG_READ_INVERT_ALPHA_SUPPORTED || PNG_WRITE_INVERT_ALPHA_SUPPORTED */
+
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+/* Add a filler byte to 24-bit RGB images. */
+extern PNG_EXPORT(void,png_set_filler) PNGARG((png_structp png_ptr,
+   png_uint_32 filler, int flags));
+
+/* The values of the PNG_FILLER_ defines should NOT be changed */
+#define PNG_FILLER_BEFORE 0
+#define PNG_FILLER_AFTER 1
+#endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* Swap bytes in 16 bit depth files. */
+extern PNG_EXPORT(void,png_set_swap) PNGARG((png_structp png_ptr));
+#endif /* PNG_READ_SWAP_SUPPORTED || PNG_WRITE_SWAP_SUPPORTED */
+
+#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
+/* Use 1 byte per pixel in 1, 2, or 4 bit depth files. */
+extern PNG_EXPORT(void,png_set_packing) PNGARG((png_structp png_ptr));
+#endif /* PNG_READ_PACK_SUPPORTED || PNG_WRITE_PACK_SUPPORTED */
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+/* Swap packing order of pixels in bytes. */
+extern PNG_EXPORT(void,png_set_packswap) PNGARG((png_structp png_ptr));
+#endif /* PNG_READ_PACKSWAP_SUPPORTED || PNG_WRITE_PACKSWAP_SUPPOR */
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+/* Converts files to legal bit depths. */
+extern PNG_EXPORT(void,png_set_shift) PNGARG((png_structp png_ptr,
+   png_color_8p true_bits));
+#endif /* PNG_READ_SHIFT_SUPPORTED || PNG_WRITE_SHIFT_SUPPORTED */
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
+    defined(PNG_WRITE_INTERLACING_SUPPORTED)
+/* Have the code handle the interlacing.  Returns the number of passes. */
+extern PNG_EXPORT(int,png_set_interlace_handling) PNGARG((png_structp png_ptr));
+#endif /* PNG_READ_INTERLACING_SUPPORTED || PNG_WRITE_INTERLACING_SUPPORTED */
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+/* Invert monocrome files */
+extern PNG_EXPORT(void,png_set_invert_mono) PNGARG((png_structp png_ptr));
+#endif /* PNG_READ_INVERT_SUPPORTED || PNG_WRITE_INVERT_SUPPORTED */
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+/* Handle alpha and tRNS by replacing with a background color. */
+extern PNG_EXPORT(void,png_set_background) PNGARG((png_structp png_ptr,
+   png_color_16p background_color, int background_gamma_code,
+   int need_expand, double background_gamma));
+#define PNG_BACKGROUND_GAMMA_UNKNOWN 0
+#define PNG_BACKGROUND_GAMMA_SCREEN  1
+#define PNG_BACKGROUND_GAMMA_FILE    2
+#define PNG_BACKGROUND_GAMMA_UNIQUE  3
+#endif /* PNG_READ_BACKGROUND_SUPPORTED */
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+/* strip the second byte of information from a 16 bit depth file. */
+extern PNG_EXPORT(void,png_set_strip_16) PNGARG((png_structp png_ptr));
+#endif /* PNG_READ_16_TO_8_SUPPORTED */
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+/* Turn on dithering, and reduce the palette to the number of colors available. */
+extern PNG_EXPORT(void,png_set_dither) PNGARG((png_structp png_ptr,
+   png_colorp palette, int num_palette, int maximum_colors,
+   png_uint_16p histogram, int full_dither));
+#endif /* PNG_READ_DITHER_SUPPORTED */
+
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+/* Handle gamma correction. Screen_gamma=(display_gamma/viewing_gamma) */
+extern PNG_EXPORT(void,png_set_gamma) PNGARG((png_structp png_ptr,
+   double screen_gamma, double default_file_gamma));
+#endif /* PNG_READ_GAMMA_SUPPORTED */
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+/* Set how many lines between output flushes - 0 for no flushing */
+extern PNG_EXPORT(void,png_set_flush) PNGARG((png_structp png_ptr, int nrows));
+
+/* Flush the current PNG output buffer */
+extern PNG_EXPORT(void,png_write_flush) PNGARG((png_structp png_ptr));
+#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+
+/* optional update palette with requested transformations */
+extern PNG_EXPORT(void,png_start_read_image) PNGARG((png_structp png_ptr));
+
+/* optional call to update the users info structure */
+extern PNG_EXPORT(void,png_read_update_info) PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+
+/* read a one or more rows of image data.*/
+extern PNG_EXPORT(void,png_read_rows) PNGARG((png_structp png_ptr,
+   png_bytepp row, png_bytepp display_row, png_uint_32 num_rows));
+
+/* read a row of data.*/
+extern PNG_EXPORT(void,png_read_row) PNGARG((png_structp png_ptr,
+   png_bytep row,
+   png_bytep display_row));
+
+/* read the whole image into memory at once. */
+extern PNG_EXPORT(void,png_read_image) PNGARG((png_structp png_ptr,
+   png_bytepp image));
+
+/* write a row of image data */
+extern PNG_EXPORT(void,png_write_row) PNGARG((png_structp png_ptr,
+   png_bytep row));
+
+/* write a few rows of image data */
+extern PNG_EXPORT(void,png_write_rows) PNGARG((png_structp png_ptr,
+   png_bytepp row, png_uint_32 num_rows));
+
+/* write the image data */
+extern PNG_EXPORT(void,png_write_image) PNGARG((png_structp png_ptr,
+   png_bytepp image));
+
+/* writes the end of the PNG file. */
+extern PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+
+/* read the end of the PNG file. */
+extern PNG_EXPORT(void,png_read_end) PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+
+/* free any memory associated with the png_info_struct */
+extern PNG_EXPORT(void,png_destroy_info_struct) PNGARG((png_structp png_ptr,
+   png_infopp info_ptr_ptr));
+
+/* free any memory associated with the png_struct and the png_info_structs */
+extern PNG_EXPORT(void,png_destroy_read_struct) PNGARG((png_structpp
+   png_ptr_ptr, png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr));
+
+/* free all memory used by the read (old method - NOT DLL EXPORTED) */
+extern void png_read_destroy PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_infop end_info_ptr));
+
+/* free any memory associated with the png_struct and the png_info_structs */
+extern PNG_EXPORT(void,png_destroy_write_struct)
+   PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr));
+
+/* free any memory used in info_ptr struct (old method - NOT DLL EXPORTED) */
+extern void png_write_destroy_info PNGARG((png_infop info_ptr));
+
+/* free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */
+extern void png_write_destroy PNGARG((png_structp png_ptr));
+
+/* set the libpng method of handling chunk CRC errors */
+extern PNG_EXPORT(void,png_set_crc_action) PNGARG((png_structp png_ptr,
+   int crit_action, int ancil_action));
+
+/* Values for png_set_crc_action() to say how to handle CRC errors in
+ * ancillary and critical chunks, and whether to use the data contained
+ * therein.  Note that it is impossible to "discard" data in a critical
+ * chunk.  For versions prior to 0.90, the action was always error/quit,
+ * whereas in version 0.90 and later, the action for CRC errors in ancillary
+ * chunks is warn/discard.  These values should NOT be changed.
+ *
+ *      value                       action:critical     action:ancillary
+ */
+#define PNG_CRC_DEFAULT       0  /* error/quit          warn/discard data */
+#define PNG_CRC_ERROR_QUIT    1  /* error/quit          error/quit        */
+#define PNG_CRC_WARN_DISCARD  2  /* (INVALID)           warn/discard data */
+#define PNG_CRC_WARN_USE      3  /* warn/use data       warn/use data     */
+#define PNG_CRC_QUIET_USE     4  /* quiet/use data      quiet/use data    */
+#define PNG_CRC_NO_CHANGE     5  /* use current value   use current value */
+
+/* These functions give the user control over the scan-line filtering in
+ * libpng and the compression methods used by zlib.  These functions are
+ * mainly useful for testing, as the defaults should work with most users.
+ * Those users who are tight on memory or want faster performance at the
+ * expense of compression can modify them.  See the compression library
+ * header file (zlib.h) for an explination of the compression functions.
+ */
+
+/* set the filtering method(s) used by libpng.  Currently, the only valid
+ * value for "method" is 0.
+ */
+extern PNG_EXPORT(void,png_set_filter) PNGARG((png_structp png_ptr, int method,
+   int filters));
+
+/* Flags for png_set_filter() to say which filters to use.  The flags
+ * are chosen so that they don't conflict with real filter types
+ * below, in case they are supplied instead of the #defined constants.
+ * These values should NOT be changed.
+ */
+#define PNG_NO_FILTERS     0x00
+#define PNG_FILTER_NONE    0x08
+#define PNG_FILTER_SUB     0x10
+#define PNG_FILTER_UP      0x20
+#define PNG_FILTER_AVG     0x40
+#define PNG_FILTER_PAETH   0x80
+#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \
+                         PNG_FILTER_AVG | PNG_FILTER_PAETH)
+
+/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now.
+ * These defines should NOT be changed.
+ */
+#define PNG_FILTER_VALUE_NONE  0
+#define PNG_FILTER_VALUE_SUB   1
+#define PNG_FILTER_VALUE_UP    2
+#define PNG_FILTER_VALUE_AVG   3
+#define PNG_FILTER_VALUE_PAETH 4
+#define PNG_FILTER_VALUE_LAST  5
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* EXPERIMENTAL */
+/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_
+ * defines, either the default (minimum-sum-of-absolute-differences), or
+ * the experimental method (weighted-minimum-sum-of-absolute-differences).
+ *
+ * Weights are factors >= 1.0, indicating how important it is to keep the
+ * filter type consistent between rows.  Larger numbers mean the current
+ * filter is that many times as likely to be the same as the "num_weights"
+ * previous filters.  This is cumulative for each previous row with a weight.
+ * There needs to be "num_weights" values in "filter_weights", or it can be
+ * NULL if the weights aren't being specified.  Weights have no influence on
+ * the selection of the first row filter.  Well chosen weights can (in theory)
+ * improve the compression for a given image.
+ *
+ * Costs are factors >= 1.0 indicating the relative decoding costs of a
+ * filter type.  Higher costs indicate more decoding expense, and are
+ * therefore less likely to be selected over a filter with lower computational
+ * costs.  There needs to be a value in "filter_costs" for each valid filter
+ * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't
+ * setting the costs.  Costs try to improve the speed of decompression without
+ * unduly increasing the compressed image size.
+ *
+ * A negative weight or cost indicates the default value is to be used, and
+ * values in the range [0.0, 1.0) indicate the value is to remain unchanged.
+ * The default values for both weights and costs are currently 1.0, but may
+ * change if good general weighting/cost heuristics can be found.  If both
+ * the weights and costs are set to 1.0, this degenerates the WEIGHTED method
+ * to the UNWEIGHTED method, but with added encoding time/computation.
+ */
+extern PNG_EXPORT(void,png_set_filter_heuristics) PNGARG((png_structp png_ptr,
+   int heuristic_method, int num_weights, png_doublep filter_weights,
+   png_doublep filter_costs));
+#endif /*  PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
+
+/* Heuristic used for row filter selection.  These defines should NOT be
+ * changed.
+ */
+#define PNG_FILTER_HEURISTIC_DEFAULT    0  /* Currently "UNWEIGHTED" */
+#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1  /* Used by libpng < 0.95 */
+#define PNG_FILTER_HEURISTIC_WEIGHTED   2  /* Experimental feature */
+#define PNG_FILTER_HEURISTIC_LAST       3  /* Not a valid value */
+
+/* Set the library compression level.  Currently, valid values range from
+ * 0 - 9, corresponding directly to the zlib compression levels 0 - 9
+ * (0 - no compression, 9 - "maximal" compression).  Note that tests have
+ * shown that zlib compression levels 3-6 usually perform as well as level 9
+ * for PNG images, and do considerably fewer caclulations.  In the future,
+ * these values may not correspond directly to the zlib compression levels.
+ */
+extern PNG_EXPORT(void,png_set_compression_level) PNGARG((png_structp png_ptr,
+   int level));
+
+extern PNG_EXPORT(void,png_set_compression_mem_level)
+   PNGARG((png_structp png_ptr, int mem_level));
+
+extern PNG_EXPORT(void,png_set_compression_strategy)
+   PNGARG((png_structp png_ptr, int strategy));
+
+extern PNG_EXPORT(void,png_set_compression_window_bits)
+   PNGARG((png_structp png_ptr, int window_bits));
+
+extern PNG_EXPORT(void,png_set_compression_method) PNGARG((png_structp png_ptr,
+   int method));
+
+/* These next functions are called for input/output, memory, and error
+ * handling.  They are in the file pngrio.c, pngwio.c, and pngerror.c,
+ * and call standard C I/O routines such as fread(), fwrite(), and
+ * fprintf().  These functions can be made to use other I/O routines
+ * at run time for those applications that need to handle I/O in a
+ * different manner by calling png_set_???_fn().  See libpng.txt for
+ * more information.
+ */
+
+#if !defined(PNG_NO_STDIO)
+/* Initialize the input/output for the PNG file to the default functions. */
+extern PNG_EXPORT(void,png_init_io) PNGARG((png_structp png_ptr, FILE *fp));
+#endif
+
+/* Replace the (error and abort), and warning functions with user
+ * supplied functions.  If no messages are to be printed you must still
+ * write and use replacement functions. The replacement error_fn should
+ * still do a longjmp to the last setjmp location if you are using this
+ * method of error handling.  If error_fn or warning_fn is NULL, the
+ * default function will be used.
+ */
+extern PNG_EXPORT(void,png_set_error_fn) PNGARG((png_structp png_ptr,
+   png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn));
+
+/* Return the user pointer associated with the error functions */
+extern PNG_EXPORT(png_voidp,png_get_error_ptr) PNGARG((png_structp png_ptr));
+
+/* Replace the default data output functions with a user supplied one(s).
+ * If buffered output is not used, then output_flush_fn can be set to NULL.
+ * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time
+ * output_flush_fn will be ignored (and thus can be NULL).
+ */
+extern PNG_EXPORT(void,png_set_write_fn) PNGARG((png_structp png_ptr,
+   png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn));
+
+/* Replace the default data input function with a user supplied one. */
+extern PNG_EXPORT(void,png_set_read_fn) PNGARG((png_structp png_ptr,
+   png_voidp io_ptr, png_rw_ptr read_data_fn));
+
+/* Return the user pointer associated with the I/O functions */
+extern PNG_EXPORT(png_voidp,png_get_io_ptr) PNGARG((png_structp png_ptr));
+
+extern PNG_EXPORT(void,png_set_read_status_fn) PNGARG((png_structp png_ptr,
+   png_read_status_ptr read_row_fn));
+
+extern PNG_EXPORT(void,png_set_write_status_fn) PNGARG((png_structp png_ptr,
+   png_write_status_ptr write_row_fn));
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+extern PNG_EXPORT(void,png_set_read_user_transform_fn) PNGARG((png_structp
+   png_ptr, png_user_transform_ptr read_user_transform_fn));
+#endif
+
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+extern PNG_EXPORT(void,png_set_write_user_transform_fn) PNGARG((png_structp
+   png_ptr, png_user_transform_ptr write_user_transform_fn));
+#endif
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+/* Sets the function callbacks for the push reader, and a pointer to a
+ * user-defined structure available to the callback functions.
+ */
+extern PNG_EXPORT(void,png_set_progressive_read_fn) PNGARG((png_structp png_ptr,
+   png_voidp progressive_ptr,
+   png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
+   png_progressive_end_ptr end_fn));
+
+/* returns the user pointer associated with the push read functions */
+extern PNG_EXPORT(png_voidp,png_get_progressive_ptr)
+   PNGARG((png_structp png_ptr));
+
+/* function to be called when data becomes available */
+extern PNG_EXPORT(void,png_process_data) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_bytep buffer, png_size_t buffer_size));
+
+/* function which combines rows.  Not very much different than the
+ * png_combine_row() call.  Is this even used?????
+ */
+extern PNG_EXPORT(void,png_progressive_combine_row) PNGARG((png_structp png_ptr,
+   png_bytep old_row, png_bytep new_row));
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+extern PNG_EXPORT(png_voidp,png_malloc) PNGARG((png_structp png_ptr,
+   png_uint_32 size));
+
+/* frees a pointer allocated by png_malloc() */
+extern PNG_EXPORT(void,png_free) PNGARG((png_structp png_ptr, png_voidp ptr));
+
+extern PNG_EXPORT(png_voidp,png_memcpy_check) PNGARG((png_structp png_ptr,
+   png_voidp s1, png_voidp s2, png_uint_32 size));
+
+extern PNG_EXPORT(png_voidp,png_memset_check) PNGARG((png_structp png_ptr,
+   png_voidp s1, int value, png_uint_32 size));
+
+#ifdef PNGTEST_MEMORY_DEBUG
+/* debugging versions of png_malloc() and png_free() */
+extern PNG_EXPORT(png_voidp,png_debug_malloc) PNGARG((png_structp png_ptr,
+   png_uint_32 size));
+extern PNG_EXPORT(void,png_debug_free) PNGARG((png_structp png_ptr,
+   png_voidp ptr));
+#endif
+#if defined(USE_FAR_KEYWORD)  /* memory model conversion function */
+extern void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr,
+   int check));
+#endif /* USE_FAR_KEYWORD */
+
+/* Fatal error in PNG image of libpng - can't continue */
+extern PNG_EXPORT(void,png_error) PNGARG((png_structp png_ptr,
+   png_const_charp error));
+
+/* The same, but the chunk name is prepended to the error string. */
+extern PNG_EXPORT(void,png_chunk_error) PNGARG((png_structp png_ptr,
+   png_const_charp error));
+
+/* Non-fatal error in libpng.  Can continue, but may have a problem. */
+extern PNG_EXPORT(void,png_warning) PNGARG((png_structp png_ptr,
+   png_const_charp message));
+
+/* Non-fatal error in libpng, chunk name is prepended to message. */
+extern PNG_EXPORT(void,png_chunk_warning) PNGARG((png_structp png_ptr,
+   png_const_charp message));
+
+/* The png_set_<chunk> functions are for storing values in the png_info_struct.
+ * Similarly, the png_get_<chunk> calls are used to read values from the
+ * png_info_struct, either storing the parameters in the passed variables, or
+ * setting pointers into the png_info_struct where the data is stored.  The
+ * png_get_<chunk> functions return a non-zero value if the data was available
+ * in info_ptr, or return zero and do not change any of the parameters if the
+ * data was not available.
+ *
+ * These functions should be used instead of directly accessing png_info
+ * to avoid problems with future changes in the size and internal layout of
+ * png_info_struct.
+ */
+/* Returns "flag" if chunk data is valid in info_ptr. */
+extern PNG_EXPORT(png_uint_32,png_get_valid) PNGARG((png_structp png_ptr,
+png_infop info_ptr, png_uint_32 flag));
+
+/* Returns number of bytes needed to hold a transformed row. */
+extern PNG_EXPORT(png_uint_32,png_get_rowbytes) PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+/* Returns number of color channels in image. */
+extern PNG_EXPORT(png_byte,png_get_channels) PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+#ifdef PNG_EASY_ACCESS_SUPPORTED
+/* Returns image width in pixels. */
+extern PNG_EXPORT(png_uint_32, png_get_image_width) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image height in pixels. */
+extern PNG_EXPORT(png_uint_32, png_get_image_height) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image bit_depth. */
+extern PNG_EXPORT(png_byte, png_get_bit_depth) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image color_type. */
+extern PNG_EXPORT(png_byte, png_get_color_type) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image filter_type. */
+extern PNG_EXPORT(png_byte, png_get_filter_type) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image interlace_type. */
+extern PNG_EXPORT(png_byte, png_get_interlace_type) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image compression_type. */
+extern PNG_EXPORT(png_byte, png_get_compression_type) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image resolution in pixels per meter, from pHYs chunk data. */
+extern PNG_EXPORT(png_uint_32, png_get_pixels_per_meter) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_uint_32, png_get_x_pixels_per_meter) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_uint_32, png_get_y_pixels_per_meter) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns pixel aspect ratio, computed from pHYs chunk data.  */
+extern PNG_EXPORT(float, png_get_pixel_aspect_ratio) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */
+extern PNG_EXPORT(png_uint_32, png_get_x_offset_pixels) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_uint_32, png_get_y_offset_pixels) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_uint_32, png_get_x_offset_microns) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_uint_32, png_get_y_offset_microns) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+#endif /* PNG_EASY_ACCESS_SUPPORTED */
+
+/* Returns pointer to signature string read from PNG header */
+extern PNG_EXPORT(png_bytep,png_get_signature) PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+#if defined(PNG_READ_bKGD_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_bKGD) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_color_16p *background));
+#endif /* PNG_READ_bKGD_SUPPORTED */
+
+#if defined(PNG_READ_bKGD_SUPPORTED) || defined(PNG_WRITE_bKGD_SUPPORTED)
+extern PNG_EXPORT(void,png_set_bKGD) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_color_16p background));
+#endif /* PNG_READ_bKGD_SUPPORTED || PNG_WRITE_bKGD_SUPPORTED */
+
+#if defined(PNG_READ_cHRM_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_cHRM) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, double *white_x, double *white_y, double *red_x,
+   double *red_y, double *green_x, double *green_y, double *blue_x,
+   double *blue_y));
+#endif /* PNG_READ_cHRM_SUPPORTED */
+
+#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
+extern PNG_EXPORT(void,png_set_cHRM) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, double white_x, double white_y, double red_x,
+   double red_y, double green_x, double green_y, double blue_x, double blue_y));
+#endif /* PNG_READ_cHRM_SUPPORTED || PNG_WRITE_cHRM_SUPPORTED */
+
+#if defined(PNG_READ_gAMA_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_gAMA) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, double *file_gamma));
+#endif /* PNG_READ_gAMA_SUPPORTED */
+
+#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED)
+extern PNG_EXPORT(void,png_set_gAMA) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, double file_gamma));
+#endif /* PNG_READ_gAMA_SUPPORTED || PNG_WRITE_gAMA_SUPPORTED */
+
+#if defined(PNG_READ_hIST_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_hIST) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_16p *hist));
+#endif /* PNG_READ_hIST_SUPPORTED */
+
+#if defined(PNG_READ_hIST_SUPPORTED) || defined(PNG_WRITE_hIST_SUPPORTED)
+extern PNG_EXPORT(void,png_set_hIST) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_16p hist));
+#endif /* PNG_READ_hIST_SUPPORTED || PNG_WRITE_hIST_SUPPORTED */
+
+extern PNG_EXPORT(png_uint_32,png_get_IHDR) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 *width, png_uint_32 *height,
+   int *bit_depth, int *color_type, int *interlace_type,
+   int *compression_type, int *filter_type));
+  
+extern PNG_EXPORT(void,png_set_IHDR) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth,
+   int color_type, int interlace_type, int compression_type, int filter_type));
+
+#if defined(PNG_READ_oFFs_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_oFFs) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 *offset_x, png_uint_32 *offset_y,
+   int *unit_type));
+#endif /* PNG_READ_oFFs_SUPPORTED */
+
+#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
+extern PNG_EXPORT(void,png_set_oFFs) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 offset_x, png_uint_32 offset_y,
+   int unit_type));
+#endif /* PNG_READ_oFFs_SUPPORTED || PNG_WRITE_oFFs_SUPPORTED */
+
+#if defined(PNG_READ_pCAL_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_pCAL) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_charp *purpose, png_int_32 *X0, png_int_32 *X1,
+   int *type, int *nparams, png_charp *units, png_charpp *params));
+#endif /* PNG_READ_pCAL_SUPPORTED */
+
+#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED)
+extern PNG_EXPORT(void,png_set_pCAL) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1,
+   int type, int nparams, png_charp units, png_charpp params));
+#endif /* PNG_READ_pCAL_SUPPORTED || PNG_WRITE_pCAL_SUPPORTED */
+
+#if defined(PNG_READ_pHYs_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_pHYs) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type));
+#endif /* PNG_READ_pHYs_SUPPORTED */
+
+#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
+extern PNG_EXPORT(void,png_set_pHYs) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type));
+#endif /* PNG_READ_pHYs_SUPPORTED || PNG_WRITE_pHYs_SUPPORTED */
+
+extern PNG_EXPORT(png_uint_32,png_get_PLTE) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_colorp *palette, int *num_palette));
+
+extern PNG_EXPORT(void,png_set_PLTE) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_colorp palette, int num_palette));
+
+#if defined(PNG_READ_sBIT_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_sBIT) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_color_8p *sig_bit));
+#endif /* PNG_READ_sBIT_SUPPORTED */
+
+#if defined(PNG_READ_sBIT_SUPPORTED) || defined(PNG_WRITE_sBIT_SUPPORTED)
+extern PNG_EXPORT(void,png_set_sBIT) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_color_8p sig_bit));
+#endif /* PNG_READ_sBIT_SUPPORTED || PNG_WRITE_sBIT_SUPPORTED */
+
+#if defined(PNG_READ_sRGB_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_sRGB) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int *intent));
+#endif /* PNG_READ_sRGB_SUPPORTED */
+
+#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
+extern PNG_EXPORT(void,png_set_sRGB) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int intent));
+extern PNG_EXPORT(void,png_set_sRGB_gAMA_and_cHRM) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int intent));
+#endif /* PNG_READ_sRGB_SUPPORTED || PNG_WRITE_sRGB_SUPPORTED */
+
+#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
+/* png_get_text also returns the number of text chunks in text_ptr */
+extern PNG_EXPORT(png_uint_32,png_get_text) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_textp *text_ptr, int *num_text));
+#endif /* PNG_READ_tEXt_SUPPORTED || PNG_READ_zTXt_SUPPORTED */
+
+#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
+    defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
+extern PNG_EXPORT(void,png_set_text) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_textp text_ptr, int num_text));
+#endif /* PNG_READ_tEXt_SUPPORTED || PNG_WRITE_tEXt_SUPPORTED ||
+          PNG_READ_zTXt_SUPPORTED || PNG_WRITE_zTXt_SUPPORTED */
+
+#if defined(PNG_READ_tIME_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_tIME) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_timep *mod_time));
+#endif /* PNG_READ_tIME_SUPPORTED */
+
+#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED)
+extern PNG_EXPORT(void,png_set_tIME) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_timep mod_time));
+#endif /* PNG_READ_tIME_SUPPORTED || PNG_WRITE_tIME_SUPPORTED */
+
+#if defined(PNG_READ_tRNS_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_tRNS) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_bytep *trans, int *num_trans,
+   png_color_16p *trans_values));
+#endif /* PNG_READ_tRNS_SUPPORTED */
+
+#if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_WRITE_tRNS_SUPPORTED)
+extern PNG_EXPORT(void,png_set_tRNS) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_bytep trans, int num_trans,
+   png_color_16p trans_values));
+#endif /* PNG_READ_tRNS_SUPPORTED || PNG_WRITE_tRNS_SUPPORTED */
+
+/* Define PNG_DEBUG at compile time for debugging information.  Higher
+ * numbers for PNG_DEBUG mean more debugging information.  This has
+ * only been added since version 0.95 so it is not implemented throughout
+ * libpng yet, but more support will be added as needed.
+ */
+#if (PNG_DEBUG > 0)
+#ifdef PNG_NO_STDIO
+#include <stdio.h>
+#endif
+#ifndef PNG_DEBUG_FILE
+#define PNG_DEBUG_FILE stderr
+#endif /* PNG_DEBUG_FILE */
+
+#define png_debug(l,m)        if (PNG_DEBUG > l) \
+                                 fprintf(PNG_DEBUG_FILE,"%s"m,(l==1 ? "\t" : \
+                                    (l==2 ? "\t\t":(l==3 ? "\t\t\t":""))))
+#define png_debug1(l,m,p1)    if (PNG_DEBUG > l) \
+                                 fprintf(PNG_DEBUG_FILE,"%s"m,(l==1 ? "\t" : \
+                                    (l==2 ? "\t\t":(l==3 ? "\t\t\t":""))),p1)
+#define png_debug2(l,m,p1,p2) if (PNG_DEBUG > l) \
+                                 fprintf(PNG_DEBUG_FILE,"%s"m,(l==1 ? "\t" : \
+                                    (l==2 ? "\t\t":(l==3 ? "\t\t\t":""))),p1,p2)
+#else
+#define png_debug(l, m)
+#define png_debug1(l, m, p1)
+#define png_debug2(l, m, p1, p2)
+#endif /* (PNG_DEBUG > 0) */
+
+/* These next functions are used internally in the code.  They generally
+ * shouldn't be used unless you are writing code to add or replace some
+ * functionality in libpng.  More information about most functions can
+ * be found in the files where the functions are located.
+ */
+
+#if defined(PNG_INTERNAL)
+
+/* Various modes of operation.  Note that after an init, mode is set to
+ * zero automatically when the structure is created.
+ */
+#define PNG_BEFORE_IHDR       0x00
+#define PNG_HAVE_IHDR         0x01
+#define PNG_HAVE_PLTE         0x02
+#define PNG_HAVE_IDAT         0x04
+#define PNG_AFTER_IDAT        0x08
+#define PNG_HAVE_IEND         0x10
+#define PNG_HAVE_gAMA         0x20
+#define PNG_HAVE_cHRM         0x40
+#define PNG_HAVE_sRGB         0x80
+
+/* push model modes */
+#define PNG_READ_SIG_MODE   0
+#define PNG_READ_CHUNK_MODE 1
+#define PNG_READ_IDAT_MODE  2
+#define PNG_SKIP_MODE       3
+#define PNG_READ_tEXt_MODE  4
+#define PNG_READ_zTXt_MODE  5
+#define PNG_READ_DONE_MODE  6
+#define PNG_ERROR_MODE      7
+
+/* flags for the transformations the PNG library does on the image data */
+#define PNG_BGR                0x0001
+#define PNG_INTERLACE          0x0002
+#define PNG_PACK               0x0004
+#define PNG_SHIFT              0x0008
+#define PNG_SWAP_BYTES         0x0010
+#define PNG_INVERT_MONO        0x0020
+#define PNG_DITHER             0x0040
+#define PNG_BACKGROUND         0x0080
+#define PNG_BACKGROUND_EXPAND  0x0100
+#define PNG_RGB_TO_GRAY        0x0200 /* Not currently implemented */
+#define PNG_16_TO_8            0x0400
+#define PNG_RGBA               0x0800
+#define PNG_EXPAND             0x1000
+#define PNG_GAMMA              0x2000
+#define PNG_GRAY_TO_RGB        0x4000
+#define PNG_FILLER             0x8000
+#define PNG_PACKSWAP          0x10000L
+#define PNG_SWAP_ALPHA        0x20000L
+#define PNG_STRIP_ALPHA       0x40000L
+#define PNG_INVERT_ALPHA      0x80000L
+#define PNG_USER_TRANSFORM   0x100000L
+
+/* flags for png_create_struct */
+#define PNG_STRUCT_PNG   0x0001
+#define PNG_STRUCT_INFO  0x0002
+
+/* Scaling factor for filter heuristic weighting calculations */
+#define PNG_WEIGHT_SHIFT 8
+#define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT))
+#define PNG_COST_SHIFT 3
+#define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT))
+
+/* flags for the png_ptr->flags rather than declaring a byte for each one */
+#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY     0x0001
+#define PNG_FLAG_ZLIB_CUSTOM_LEVEL        0x0002
+#define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL    0x0004
+#define PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS  0x0008
+#define PNG_FLAG_ZLIB_CUSTOM_METHOD       0x0010
+#define PNG_FLAG_ZLIB_FINISHED            0x0020
+#define PNG_FLAG_ROW_INIT                 0x0040
+#define PNG_FLAG_FILLER_AFTER             0x0080
+#define PNG_FLAG_CRC_ANCILLARY_USE        0x0100
+#define PNG_FLAG_CRC_ANCILLARY_NOWARN     0x0200
+#define PNG_FLAG_CRC_CRITICAL_USE         0x0400
+#define PNG_FLAG_CRC_CRITICAL_IGNORE      0x0800
+#define PNG_FLAG_FREE_PALETTE             0x1000
+#define PNG_FLAG_FREE_TRANS               0x2000
+#define PNG_FLAG_FREE_HIST                0x4000
+#define PNG_FLAG_HAVE_CHUNK_HEADER        0x8000L
+#define PNG_FLAG_WROTE_tIME              0x10000L
+
+#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
+                                     PNG_FLAG_CRC_ANCILLARY_NOWARN)
+
+#define PNG_FLAG_CRC_CRITICAL_MASK  (PNG_FLAG_CRC_CRITICAL_USE | \
+                                     PNG_FLAG_CRC_CRITICAL_IGNORE)
+
+#define PNG_FLAG_CRC_MASK           (PNG_FLAG_CRC_ANCILLARY_MASK | \
+                                     PNG_FLAG_CRC_CRITICAL_MASK)
+
+/* save typing and make code easier to understand */
+#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \
+   abs((int)((c1).green) - (int)((c2).green)) + \
+   abs((int)((c1).blue) - (int)((c2).blue)))
+
+/* variables declared in png.c - only it needs to define PNG_NO_EXTERN */
+#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
+/* place to hold the signature string for a PNG file. */
+extern png_byte FARDATA png_sig[8];
+
+/* Constant strings for known chunk types.  If you need to add a chunk,
+ * add a string holding the name here.  See png.c for more details.  We
+ * can't selectively include these, since we still check for chunk in the
+ * wrong locations with these labels.
+ */
+extern png_byte FARDATA png_IHDR[5];
+extern png_byte FARDATA png_IDAT[5];
+extern png_byte FARDATA png_IEND[5];
+extern png_byte FARDATA png_PLTE[5];
+extern png_byte FARDATA png_bKGD[5];
+extern png_byte FARDATA png_cHRM[5];
+extern png_byte FARDATA png_gAMA[5];
+extern png_byte FARDATA png_hIST[5];
+extern png_byte FARDATA png_oFFs[5];
+extern png_byte FARDATA png_pCAL[5];
+extern png_byte FARDATA png_pHYs[5];
+extern png_byte FARDATA png_sBIT[5];
+extern png_byte FARDATA png_sRGB[5];
+extern png_byte FARDATA png_tEXt[5];
+extern png_byte FARDATA png_tIME[5];
+extern png_byte FARDATA png_tRNS[5];
+extern png_byte FARDATA png_zTXt[5];
+
+#endif /* PNG_NO_EXTERN */
+
+/* Inline macros to do direct reads of bytes from the input buffer.  These
+ * require that you are using an architecture that uses PNG byte ordering
+ * (MSB first) and supports unaligned data storage.  I think that PowerPC
+ * in big-endian mode and 680x0 are the only ones that will support this.
+ * The x86 line of processors definitely do not.  The png_get_int_32()
+ * routine also assumes we are using two's complement format for negative
+ * values, which is almost certainly true.
+ */
+#if defined(PNG_READ_BIG_ENDIAN_SUPPORTED)
+#if defined(PNG_READ_pCAL_SUPPORTED)
+#define png_get_int_32(buf) ( *((png_int_32p) (buf)))
+#endif /* PNG_READ_pCAL_SUPPORTED */
+#define png_get_uint_32(buf) ( *((png_uint_32p) (buf)))
+#define png_get_uint_16(buf) ( *((png_uint_16p) (buf)))
+#else
+#if defined(PNG_READ_pCAL_SUPPORTED)
+PNG_EXTERN png_int_32 png_get_int_32 PNGARG((png_bytep buf));
+#endif /* PNG_READ_pCAL_SUPPORTED */
+PNG_EXTERN png_uint_32 png_get_uint_32 PNGARG((png_bytep buf));
+PNG_EXTERN png_uint_16 png_get_uint_16 PNGARG((png_bytep buf));
+#endif /* PNG_BIG_ENDIAN_GET_SUPPORTED */
+
+/* Initialize png_ptr struct for reading, and allocate any other memory.
+ * (old interface - NOT DLL EXPORTED).
+ */
+extern void png_read_init PNGARG((png_structp png_ptr));
+
+/* Initialize png_ptr struct for writing, and allocate any other memory.
+ * (old interface - NOT DLL EXPORTED).
+ */
+extern void png_write_init PNGARG((png_structp png_ptr));
+
+/* allocate memory for an internal libpng struct */
+PNG_EXTERN png_voidp png_create_struct PNGARG((int type));
+
+/* free memory from internal libpng struct */
+PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr));
+
+/* free any memory that info_ptr points to and reset struct. */
+PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+
+/* Function to allocate memory for zlib. */
+PNG_EXTERN voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items, uInt size));
+
+/* function to free memory for zlib */
+PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr));
+
+/* reset the CRC variable */
+PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr));
+
+/* Write the "data" buffer to whatever output you are using. */
+PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, png_bytep data,
+   png_size_t length));
+
+/* Read data from whatever input you are using into the "data" buffer */
+PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data,
+   png_size_t length));
+
+/* read bytes into buf, and update png_ptr->crc */
+PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf,
+   png_size_t length));
+
+/* read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */
+PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip));
+
+/* read the CRC from the file and compare it to the libpng calculated CRC */
+PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr));
+
+/* Calculate the CRC over a section of data.  Note that we are only
+ * passing a maximum of 64K on systems that have this as a memory limit,
+ * since this is the maximum buffer size we can specify.
+ */
+PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, png_bytep ptr,
+   png_size_t length));
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+PNG_EXTERN void png_flush PNGARG((png_structp png_ptr));
+#endif
+
+/* Place a 32-bit number into a buffer in PNG byte order (big-endian).
+ * The only currently known PNG chunk that uses signed numbers is
+ * the ancillary extension chunk, pCAL.
+ */
+PNG_EXTERN void png_save_uint_32 PNGARG((png_bytep buf, png_uint_32 i));
+
+#if defined(PNG_WRITE_pCAL_SUPPORTED)
+PNG_EXTERN void png_save_int_32 PNGARG((png_bytep buf, png_int_32 i));
+#endif
+
+/* Place a 16 bit number into a buffer in PNG byte order.
+ * The parameter is declared unsigned int, not png_uint_16,
+ * just to avoid potential problems on pre-ANSI C compilers.
+ */
+PNG_EXTERN void png_save_uint_16 PNGARG((png_bytep buf, unsigned int i));
+
+/* simple function to write the signature */
+PNG_EXTERN void png_write_sig PNGARG((png_structp png_ptr));
+
+/* write various chunks */
+
+/* Write the IHDR chunk, and update the png_struct with the necessary
+ * information.
+ */
+PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width,
+   png_uint_32 height,
+   int bit_depth, int color_type, int compression_type, int filter_type,
+   int interlace_type));
+
+PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, png_colorp palette,
+   png_uint_32 num_pal));
+
+PNG_EXTERN void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data,
+   png_size_t length));
+
+PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr));
+
+#if defined(PNG_WRITE_gAMA_SUPPORTED)
+PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma));
+#endif
+
+#if defined(PNG_WRITE_sBIT_SUPPORTED)
+PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, png_color_8p sbit,
+   int color_type));
+#endif
+
+#if defined(PNG_WRITE_cHRM_SUPPORTED)
+PNG_EXTERN void png_write_cHRM PNGARG((png_structp png_ptr,
+   double white_x, double white_y,
+   double red_x, double red_y, double green_x, double green_y,
+   double blue_x, double blue_y));
+#endif
+
+#if defined(PNG_WRITE_sRGB_SUPPORTED)
+PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr,
+   int intent));
+#endif
+
+#if defined(PNG_WRITE_tRNS_SUPPORTED)
+PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, png_bytep trans,
+   png_color_16p values, int number, int color_type));
+#endif
+
+#if defined(PNG_WRITE_bKGD_SUPPORTED)
+PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr,
+   png_color_16p values, int color_type));
+#endif
+
+#if defined(PNG_WRITE_hIST_SUPPORTED)
+PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, png_uint_16p hist,
+   int num_hist));
+#endif
+
+#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
+PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr,
+   png_charp key, png_charpp new_key));
+#endif
+
+#if defined(PNG_WRITE_tEXt_SUPPORTED)
+PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_charp key,
+   png_charp text, png_size_t text_len));
+#endif
+
+#if defined(PNG_WRITE_zTXt_SUPPORTED)
+PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_charp key,
+   png_charp text, png_size_t text_len, int compression));
+#endif
+
+#if defined(PNG_WRITE_oFFs_SUPPORTED)
+PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr,
+   png_uint_32 x_offset, png_uint_32 y_offset, int unit_type));
+#endif
+
+#if defined(PNG_WRITE_pCAL_SUPPORTED)
+PNG_EXTERN void png_write_pCAL PNGARG((png_structp png_ptr, png_charp purpose,
+   png_int_32 X0, png_int_32 X1, int type, int nparams,
+   png_charp units, png_charpp params));
+#endif
+
+#if defined(PNG_WRITE_pHYs_SUPPORTED)
+PNG_EXTERN void png_write_pHYs PNGARG((png_structp png_ptr,
+   png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit,
+   int unit_type));
+#endif
+
+#if defined(PNG_WRITE_tIME_SUPPORTED)
+PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr,
+   png_timep mod_time));
+#endif
+
+/* Called when finished processing a row of data */
+PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr));
+
+/* Internal use only.   Called before first row of data */
+PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr));
+
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr));
+#endif
+
+/* combine a row of data, dealing with alpha, etc. if requested */
+PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row,
+   int mask));
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED)
+/* expand an interlaced row */
+PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info,
+   png_bytep row, int pass, png_uint_32 transformations));
+#endif
+
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+/* grab pixels out of a row for an interlaced pass */
+PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info,
+   png_bytep row, int pass));
+#endif
+
+/* unfilter a row */
+PNG_EXTERN void png_read_filter_row PNGARG((png_structp png_ptr,
+   png_row_infop row_info, png_bytep row, png_bytep prev_row, int filter));
+
+/* Choose the best filter to use and filter the row data */
+PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr,
+   png_row_infop row_info));
+
+/* Write out the filtered row. */
+PNG_EXTERN void png_write_filtered_row PNGARG((png_structp png_ptr,
+   png_bytep filtered_row));
+/* finish a row while reading, dealing with interlacing passes, etc. */
+PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr));
+
+/* initialize the row buffers, etc. */
+PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr));
+/* optional call to update the users info structure */
+PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+
+/* these are the functions that do the transformations */
+#if defined(PNG_READ_FILLER_SUPPORTED)
+PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info,
+   png_bytep row, png_uint_32 filler, png_uint_32 flags));
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
+PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info,
+   png_bytep row));
+#endif
+
+#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info,
+   png_bytep row));
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
+PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info,
+   png_bytep row));
+#endif
+
+#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info,
+   png_bytep row));
+#endif
+
+#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
+    defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+PNG_EXTERN void png_do_strip_filler PNGARG((png_row_infop row_info,
+   png_bytep row, png_uint_32 flags));
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info, png_bytep row));
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info, png_bytep row));
+#endif
+
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+PNG_EXTERN void png_do_rgb_to_gray PNGARG((png_row_infop row_info,
+   png_bytep row));
+#endif
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info,
+   png_bytep row));
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED)
+PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info, png_bytep row));
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED)
+PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, png_bytep row,
+   png_color_8p sig_bits));
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info, png_bytep row));
+#endif
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info, png_bytep row));
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+PNG_EXTERN void png_do_dither PNGARG((png_row_infop row_info,
+   png_bytep row, png_bytep palette_lookup, png_bytep dither_lookup));
+
+#  if defined(PNG_CORRECT_PALETTE_SUPPORTED)
+PNG_EXTERN void png_correct_palette PNGARG((png_structp png_ptr,
+   png_colorp palette, int num_palette));
+#  endif
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info, png_bytep row));
+#endif
+
+#if defined(PNG_WRITE_PACK_SUPPORTED)
+PNG_EXTERN void png_do_pack PNGARG((png_row_infop row_info,
+   png_bytep row, png_uint_32 bit_depth));
+#endif
+
+#if defined(PNG_WRITE_SHIFT_SUPPORTED)
+PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, png_bytep row,
+   png_color_8p bit_depth));
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row,
+   png_color_16p trans_values, png_color_16p background,
+   png_color_16p background_1,
+   png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
+   png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
+   png_uint_16pp gamma_16_to_1, int gamma_shift));
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, png_bytep row,
+   png_bytep gamma_table, png_uint_16pp gamma_16_table,
+   int gamma_shift));
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info,
+   png_bytep row, png_colorp palette, png_bytep trans, int num_trans));
+PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info,
+   png_bytep row, png_color_16p trans_value));
+#endif
+
+/* The following decodes the appropriate chunks, and does error correction,
+ * then calls the appropriate callback for the chunk if it is valid.
+ */
+
+/* decode the IHDR chunk */
+PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+
+#if defined(PNG_READ_gAMA_SUPPORTED)
+PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_sBIT_SUPPORTED)
+PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_cHRM_SUPPORTED)
+PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_sRGB_SUPPORTED)
+PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_tRNS_SUPPORTED)
+PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_bKGD_SUPPORTED)
+PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_hIST_SUPPORTED)
+PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_oFFs_SUPPORTED)
+PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_pCAL_SUPPORTED)
+PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_pHYs_SUPPORTED)
+PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_tIME_SUPPORTED)
+PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_tEXt_SUPPORTED)
+PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_zTXt_SUPPORTED)
+PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
+PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 length));
+
+PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr,
+   png_bytep chunk_name));
+
+/* handle the transformations for reading and writing */
+PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr));
+
+PNG_EXTERN void png_init_read_transformations PNGARG((png_structp png_ptr));
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+PNG_EXTERN void png_push_read_chunk PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+PNG_EXTERN void png_push_read_sig PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr,
+   png_uint_32 length));
+PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_push_fill_buffer PNGARG((png_structp png_ptr,
+   png_bytep buffer, png_size_t length));
+PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr,
+   png_bytep buffer, png_size_t buffer_length));
+PNG_EXTERN void png_push_read_IDAT PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_process_IDAT_data PNGARG((png_structp png_ptr,
+   png_bytep buffer, png_size_t buffer_length));
+PNG_EXTERN void png_push_process_row PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_push_handle_unknown PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 length));
+PNG_EXTERN void png_push_have_info PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+PNG_EXTERN void png_push_have_end PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+PNG_EXTERN void png_push_have_row PNGARG((png_structp png_ptr, png_bytep row));
+PNG_EXTERN void png_push_read_end PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+PNG_EXTERN void png_process_some_data PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+PNG_EXTERN void png_read_push_finish_row PNGARG((png_structp png_ptr));
+#if defined(PNG_READ_tEXt_SUPPORTED)
+PNG_EXTERN void png_push_handle_tEXt PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 length));
+PNG_EXTERN void png_push_read_tEXt PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 length));
+PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+#endif
+
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+#endif /* PNG_INTERNAL */
+
+#ifdef __cplusplus
+}
+#endif
+
+/* do not put anything past this line */
+#endif /* _PNG_H */
diff --git a/src/png/pngconf.h b/src/png/pngconf.h
new file mode 100644
index 0000000000..675f292bab
--- /dev/null
+++ b/src/png/pngconf.h
@@ -0,0 +1,565 @@
+
+/* pngconf.h - machine configurable file for libpng
+ *
+ * libpng 1.0.1
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Copyright (c) 1998, Glenn Randers-Pehrson
+ * March 15, 1998
+ */
+
+/* Any machine specific code is near the front of this file, so if you
+ * are configuring libpng for a machine, you may want to read the section
+ * starting here down to where it starts to typedef png_color, png_text,
+ * and png_info.
+ */
+
+#ifndef PNGCONF_H
+#define PNGCONF_H
+
+/* This is the size of the compression buffer, and thus the size of
+ * an IDAT chunk.  Make this whatever size you feel is best for your
+ * machine.  One of these will be allocated per png_struct.  When this
+ * is full, it writes the data to the disk, and does some other
+ * calculations.  Making this an extremely small size will slow
+ * the library down, but you may want to experiment to determine
+ * where it becomes significant, if you are concerned with memory
+ * usage.  Note that zlib allocates at least 32Kb also.  For readers,
+ * this describes the size of the buffer available to read the data in.
+ * Unless this gets smaller than the size of a row (compressed),
+ * it should not make much difference how big this is.
+ */
+
+#ifndef PNG_ZBUF_SIZE
+#define PNG_ZBUF_SIZE 8192
+#endif
+
+/* If you are running on a machine where you cannot allocate more
+ * than 64K of memory at once, uncomment this.  While libpng will not
+ * normally need that much memory in a chunk (unless you load up a very
+ * large file), zlib needs to know how big of a chunk it can use, and
+ * libpng thus makes sure to check any memory allocation to verify it
+ * will fit into memory.
+#define PNG_MAX_MALLOC_64K
+ */
+#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
+#define PNG_MAX_MALLOC_64K
+#endif
+
+/* This protects us against compilers which run on a windowing system
+ * and thus don't have or would rather us not use the stdio types:
+ * stdin, stdout, and stderr.  The only one currently used is stderr
+ * in png_error() and png_warning().  #defining PNG_NO_STDIO will
+ * prevent these from being compiled and used.
+ * #define PNG_NO_STDIO
+ */
+
+#ifndef PNG_NO_STDIO 
+#include <stdio.h>
+#endif
+
+/* This macro protects us against machines that don't have function
+ * prototypes (ie K&R style headers).  If your compiler does not handle
+ * function prototypes, define this macro and use the included ansi2knr.
+ * I've always been able to use _NO_PROTO as the indicator, but you may
+ * need to drag the empty declaration out in front of here, or change the
+ * ifdef to suit your own needs.
+ */
+#ifndef PNGARG
+
+#ifdef OF /* zlib prototype munger */
+#define PNGARG(arglist) OF(arglist)
+#else
+
+#ifdef _NO_PROTO
+#define PNGARG(arglist) ()
+#else
+#define PNGARG(arglist) arglist
+#endif /* _NO_PROTO */
+
+#endif /* OF */
+
+#endif /* PNGARG */
+
+/* Try to determine if we are compiling on a Mac.  Note that testing for
+ * just __MWERKS__ is not good enough, because the Codewarrior is now used
+ * on non-Mac platforms.
+ */
+#ifndef MACOS
+#if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
+    defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
+#define MACOS
+#endif
+#endif
+
+/* enough people need this for various reasons to include it here */
+#if !defined(MACOS) && !defined(RISCOS)
+#include <sys/types.h>
+#endif
+
+/* This is an attempt to force a single setjmp behaviour on Linux.  If
+ * the X config stuff didn't define _BSD_SOURCE we wouldn't need this.
+ */
+#ifdef __linux__
+#ifdef _BSD_SOURCE
+#define _PNG_SAVE_BSD_SOURCE
+#undef _BSD_SOURCE
+#endif
+#ifdef _SETJMP_H
+__png.h__ already includes setjmp.h
+__dont__ include it again
+#endif
+#endif /* __linux__ */
+
+/* include setjmp.h for error handling */
+#include <setjmp.h>
+
+#ifdef __linux__
+#ifdef _PNG_SAVE_BSD_SOURCE
+#define _BSD_SOURCE
+#undef _PNG_SAVE_BSD_SOURCE
+#endif
+#endif /* __linux__ */
+
+#ifdef BSD
+#include <strings.h>
+#else
+#include <string.h>
+#endif
+
+/* Other defines for things like memory and the like can go here.  */
+#ifdef PNG_INTERNAL
+#include <stdlib.h>
+
+/* The functions exported by PNG_EXTERN are PNG_INTERNAL functions, which
+ * aren't usually used outside the library (as far as I know), so it is
+ * debatable if they should be exported at all.  In the future, when it is
+ * possible to have run-time registry of chunk-handling functions, some of
+ * these will be made available again.
+#define PNG_EXTERN extern
+ */
+#define PNG_EXTERN
+
+/* Other defines specific to compilers can go here.  Try to keep
+ * them inside an appropriate ifdef/endif pair for portability.
+ */
+
+#if defined(MACOS)
+/* We need to check that <math.h> hasn't already been included earlier
+ * as it seems it doesn't agree with <fp.h>, yet we should really use
+ * <fp.h> if possible.
+ */
+#if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
+#include <fp.h>
+#endif
+#else
+#include <math.h>
+#endif
+
+/* Codewarrior on NT has linking problems without this. */
+#if defined(__MWERKS__) && defined(WIN32)
+#define PNG_ALWAYS_EXTERN
+#endif
+
+/* For some reason, Borland C++ defines memcmp, etc. in mem.h, not
+ * stdlib.h like it should (I think).  Or perhaps this is a C++
+ * "feature"?
+ */
+#ifdef __TURBOC__
+#include <mem.h>
+#include "alloc.h"
+#endif
+
+#ifdef _MSC_VER
+#include <malloc.h>
+#endif
+
+/* This controls how fine the dithering gets.  As this allocates
+ * a largish chunk of memory (32K), those who are not as concerned
+ * with dithering quality can decrease some or all of these.
+ */
+#ifndef PNG_DITHER_RED_BITS
+#define PNG_DITHER_RED_BITS 5
+#endif
+#ifndef PNG_DITHER_GREEN_BITS
+#define PNG_DITHER_GREEN_BITS 5
+#endif
+#ifndef PNG_DITHER_BLUE_BITS
+#define PNG_DITHER_BLUE_BITS 5
+#endif
+
+/* This controls how fine the gamma correction becomes when you
+ * are only interested in 8 bits anyway.  Increasing this value
+ * results in more memory being used, and more pow() functions
+ * being called to fill in the gamma tables.  Don't set this value
+ * less then 8, and even that may not work (I haven't tested it).
+ */
+
+#ifndef PNG_MAX_GAMMA_8
+#define PNG_MAX_GAMMA_8 11
+#endif
+
+/* This controls how much a difference in gamma we can tolerate before
+ * we actually start doing gamma conversion.
+ */
+#ifndef PNG_GAMMA_THRESHOLD
+#define PNG_GAMMA_THRESHOLD 0.05
+#endif
+
+#endif /* PNG_INTERNAL */
+
+/* The following uses const char * instead of char * for error
+ * and warning message functions, so some compilers won't complain.
+ * If you do not want to use const, define PNG_NO_CONST here.
+ */
+
+#ifndef PNG_NO_CONST
+#  define PNG_CONST const
+#else
+#  define PNG_CONST
+#endif
+
+/* The following defines give you the ability to remove code from the
+ * library that you will not be using.  I wish I could figure out how to
+ * automate this, but I can't do that without making it seriously hard
+ * on the users.  So if you are not using an ability, change the #define
+ * to and #undef, and that part of the library will not be compiled.  If
+ * your linker can't find a function, you may want to make sure the
+ * ability is defined here.  Some of these depend upon some others being
+ * defined.  I haven't figured out all the interactions here, so you may
+ * have to experiment awhile to get everything to compile.  If you are
+ * creating or using a shared library, you probably shouldn't touch this,
+ * as it will affect the size of the structures, and this will cause bad
+ * things to happen if the library and/or application ever change.
+ */
+
+/* Any transformations you will not be using can be undef'ed here */
+
+/* GR-P, 0.96a: Set "*TRANSFORMS_SUPPORTED as default but allow user
+   to turn it off with "*TRANSFORMS_NOT_SUPPORTED" on the compile line,
+   then pick and choose which ones to define without having to edit
+   this file. It is safe to use the *TRANSFORMS_NOT_SUPPORTED if you
+   only want to have a png-compliant reader/writer but don't need
+   any of the extra transformations.  This saves about 80 kbytes in a
+   typical installation of the library.
+ */
+
+
+#ifndef PNG_READ_TRANSFORMS_NOT_SUPPORTED
+#define PNG_READ_TRANSFORMS_SUPPORTED
+#endif
+#ifndef PNG_WRITE_TRANSFORMS_NOT_SUPPORTED
+#define PNG_WRITE_TRANSFORMS_SUPPORTED
+#endif
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+#define PNG_READ_EXPAND_SUPPORTED
+#define PNG_READ_SHIFT_SUPPORTED
+#define PNG_READ_PACK_SUPPORTED
+#define PNG_READ_BGR_SUPPORTED
+#define PNG_READ_SWAP_SUPPORTED
+#define PNG_READ_PACKSWAP_SUPPORTED
+#define PNG_READ_INVERT_SUPPORTED
+#define PNG_READ_DITHER_SUPPORTED
+#define PNG_READ_BACKGROUND_SUPPORTED
+#define PNG_READ_16_TO_8_SUPPORTED
+#define PNG_READ_FILLER_SUPPORTED
+#define PNG_READ_GAMMA_SUPPORTED
+#define PNG_READ_GRAY_TO_RGB_SUPPORTED
+#define PNG_READ_SWAP_ALPHA_SUPPORTED
+#define PNG_READ_INVERT_ALPHA_SUPPORTED
+#define PNG_READ_STRIP_ALPHA_SUPPORTED
+#define PNG_READ_USER_TRANSFORM_SUPPORTED
+/* the following aren't implemented yet
+#define PNG_READ_RGB_TO_GRAY_SUPPORTED
+ */
+#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
+
+#ifndef PNG_PROGRESSIVE_READ_NOT_SUPPORTED   /* if you don't do progressive   */
+#define PNG_PROGRESSIVE_READ_SUPPORTED       /* reading.  This is not talking */
+#endif                               /* about interlacing capability!  You'll */
+              /* still have interlacing unless you change the following line: */
+#define PNG_READ_INTERLACING_SUPPORTED /* required for PNG-compliant decoders */
+#define PNG_READ_COMPOSITE_NODIV_SUPPORTED    /* well tested on Intel and SGI */
+
+#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
+#define PNG_WRITE_SHIFT_SUPPORTED
+#define PNG_WRITE_PACK_SUPPORTED
+#define PNG_WRITE_BGR_SUPPORTED
+#define PNG_WRITE_SWAP_SUPPORTED
+#define PNG_WRITE_PACKSWAP_SUPPORTED
+#define PNG_WRITE_INVERT_SUPPORTED
+#define PNG_WRITE_FILLER_SUPPORTED  /* This is the same as WRITE_STRIP_ALPHA */
+#define PNG_WRITE_FLUSH_SUPPORTED
+#define PNG_WRITE_SWAP_ALPHA_SUPPORTED
+#define PNG_WRITE_INVERT_ALPHA_SUPPORTED
+#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+#define PNG_WRITE_USER_TRANSFORM_SUPPORTED
+#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */
+
+#define PNG_WRITE_INTERLACING_SUPPORTED  /* not required for PNG-compliant
+                                            encoders, but can cause trouble
+                                            if left undefined */
+
+#if !defined(PNG_NO_STDIO)
+#define PNG_TIME_RFC1123_SUPPORTED
+#endif
+
+/* This adds extra functions in pngget.c for accessing data from the
+ * info pointer (added in version 0.99)
+ * png_get_image_width()
+ * png_get_image_height()
+ * png_get_bit_depth()
+ * png_get_color_type()
+ * png_get_compression_type()
+ * png_get_filter_type()
+ * png_get_interlace_type()
+ * png_get_pixel_aspect_ratio()
+ * png_get_pixels_per_meter()
+ * png_get_x_offset_pixels()
+ * png_get_y_offset_pixels()
+ * png_get_x_offset_microns()
+ * png_get_y_offset_microns()
+ */
+#if !defined(PNG_NO_EASY_ACCESS)
+#define PNG_EASY_ACCESS_SUPPORTED
+#endif
+
+/* These are currently experimental features, define them if you want */
+
+/* very little testing */
+/*
+#define PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
+*/
+
+/* This is only for PowerPC big-endian and 680x0 systems */
+/* some testing */
+/*
+#define PNG_READ_BIG_ENDIAN_SUPPORTED
+*/
+
+/* These functions are turned off by default, as they will be phased out. */
+/*
+#define  PNG_USELESS_TESTS_SUPPORTED
+#define  PNG_CORRECT_PALETTE_SUPPORTED
+*/
+
+/* Any chunks you are not interested in, you can undef here.  The
+ * ones that allocate memory may be expecially important (hIST,
+ * tEXt, zTXt, tRNS, pCAL).  Others will just save time and make png_info
+ * a bit smaller.
+ */
+
+#ifndef PNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED
+#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
+#endif
+#ifndef PNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED
+#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
+#endif
+
+#ifdef PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
+#define PNG_READ_bKGD_SUPPORTED
+#define PNG_READ_cHRM_SUPPORTED
+#define PNG_READ_gAMA_SUPPORTED
+#define PNG_READ_hIST_SUPPORTED
+#define PNG_READ_oFFs_SUPPORTED
+#define PNG_READ_pCAL_SUPPORTED
+#define PNG_READ_pHYs_SUPPORTED
+#define PNG_READ_sBIT_SUPPORTED
+#define PNG_READ_sRGB_SUPPORTED
+#define PNG_READ_tEXt_SUPPORTED
+#define PNG_READ_tIME_SUPPORTED
+#define PNG_READ_tRNS_SUPPORTED
+#define PNG_READ_zTXt_SUPPORTED
+#define PNG_READ_OPT_PLTE_SUPPORTED /* only affects support of the optional */
+                                    /* PLTE chunk in RGB and RGBA images */
+#endif /* PNG_READ_ANCILLARY_CHUNKS_SUPPORTED */
+
+#ifdef PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
+#define PNG_WRITE_bKGD_SUPPORTED
+#define PNG_WRITE_cHRM_SUPPORTED
+#define PNG_WRITE_gAMA_SUPPORTED
+#define PNG_WRITE_hIST_SUPPORTED
+#define PNG_WRITE_oFFs_SUPPORTED
+#define PNG_WRITE_pCAL_SUPPORTED
+#define PNG_WRITE_pHYs_SUPPORTED
+#define PNG_WRITE_sBIT_SUPPORTED
+#define PNG_WRITE_sRGB_SUPPORTED
+#define PNG_WRITE_tEXt_SUPPORTED
+#define PNG_WRITE_tIME_SUPPORTED
+#define PNG_WRITE_tRNS_SUPPORTED
+#define PNG_WRITE_zTXt_SUPPORTED
+#endif /* PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED */
+
+/* need the time information for reading tIME chunks */
+#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED)
+#include <time.h>
+#endif
+
+/* Some typedefs to get us started.  These should be safe on most of the
+ * common platforms.  The typedefs should be at least as large as the
+ * numbers suggest (a png_uint_32 must be at least 32 bits long), but they
+ * don't have to be exactly that size.  Some compilers dislike passing
+ * unsigned shorts as function parameters, so you may be better off using
+ * unsigned int for png_uint_16.  Likewise, for 64-bit systems, you may
+ * want to have unsigned int for png_uint_32 instead of unsigned long.
+ */
+
+typedef unsigned long png_uint_32;
+typedef long png_int_32;
+typedef unsigned short png_uint_16;
+typedef short png_int_16;
+typedef unsigned char png_byte;
+
+/* This is usually size_t.  It is typedef'ed just in case you need it to
+   change (I'm not sure if you will or not, so I thought I'd be safe) */
+typedef size_t png_size_t;
+
+/* The following is needed for medium model support.  It cannot be in the
+ * PNG_INTERNAL section.  Needs modification for other compilers besides
+ * MSC.  Model independent support declares all arrays and pointers to be
+ * large using the far keyword.  The zlib version used must also support
+ * model independent data.  As of version zlib 1.0.4, the necessary changes
+ * have been made in zlib.  The USE_FAR_KEYWORD define triggers other
+ * changes that are needed. (Tim Wegner)
+ */
+
+/* Separate compiler dependencies (problem here is that zlib.h always
+   defines FAR. (SJT) */
+#ifdef __BORLANDC__
+#if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__)
+#define LDATA 1
+#else
+#define LDATA 0
+#endif
+
+#if !defined(__WIN32__) && !defined(__FLAT__)
+#define PNG_MAX_MALLOC_64K
+#if (LDATA != 1)
+#ifndef FAR
+#define FAR __far
+#endif
+#define USE_FAR_KEYWORD
+#endif   /* LDATA != 1 */
+
+/* Possibly useful for moving data out of default segment.
+ * Uncomment it if you want. Could also define FARDATA as
+ * const if your compiler supports it. (SJT)
+#  define FARDATA FAR
+ */
+#endif  /* __WIN32__, __FLAT__ */
+
+#endif   /* __BORLANDC__ */
+
+
+/* Suggest testing for specific compiler first before testing for
+ * FAR.  The Watcom compiler defines both __MEDIUM__ and M_I86MM,
+ * making reliance oncertain keywords suspect. (SJT)
+ */
+
+/* MSC Medium model */
+#if defined(FAR)
+#  if defined(M_I86MM)
+#     define USE_FAR_KEYWORD
+#     define FARDATA FAR
+#     include <dos.h>
+#  endif
+#endif
+
+/* SJT: default case */
+#ifndef FAR
+#   define FAR
+#endif
+
+/* At this point FAR is always defined */
+#ifndef FARDATA
+#define FARDATA
+#endif
+
+/* Add typedefs for pointers */
+typedef void            FAR * png_voidp;
+typedef png_byte        FAR * png_bytep;
+typedef png_uint_32     FAR * png_uint_32p;
+typedef png_int_32      FAR * png_int_32p;
+typedef png_uint_16     FAR * png_uint_16p;
+typedef png_int_16      FAR * png_int_16p;
+typedef PNG_CONST char  FAR * png_const_charp;
+typedef char            FAR * png_charp;
+typedef double          FAR * png_doublep;
+
+/* Pointers to pointers; i.e. arrays */
+typedef png_byte        FAR * FAR * png_bytepp;
+typedef png_uint_32     FAR * FAR * png_uint_32pp;
+typedef png_int_32      FAR * FAR * png_int_32pp;
+typedef png_uint_16     FAR * FAR * png_uint_16pp;
+typedef png_int_16      FAR * FAR * png_int_16pp;
+typedef PNG_CONST char  FAR * FAR * png_const_charpp;
+typedef char            FAR * FAR * png_charpp;
+typedef double          FAR * FAR * png_doublepp;
+
+/* Pointers to pointers to pointers; i.e. pointer to array */
+typedef char            FAR * FAR * FAR * png_charppp;
+
+/* libpng typedefs for types in zlib. If zlib changes
+ * or another compression library is used, then change these.
+ * Eliminates need to change all the source files.
+ */
+typedef charf *         png_zcharp;
+typedef charf * FAR *   png_zcharpp;
+typedef z_stream FAR *  png_zstreamp; 
+
+/* allow for compilation as dll under MS Windows */
+#ifdef __WIN32DLL__
+#define PNG_EXPORT(type,symbol) __declspec(dllexport) type symbol
+#endif
+
+/* allow for compilation as dll with BORLAND C++ 5.0 */
+#if defined(__BORLANDC__) && defined(_Windows) && defined(__DLL__)
+#   define PNG_EXPORT(type,symbol) type _export symbol
+#endif
+
+/* allow for compilation as shared lib under BeOS */
+#ifdef __BEOSDLL__
+#define PNG_EXPORT(type,symbol) __declspec(export) type symbol
+#endif
+
+#ifndef PNG_EXPORT
+#define PNG_EXPORT(type,symbol) type symbol
+#endif
+
+
+/* User may want to use these so not in PNG_INTERNAL. Any library functions
+ * that are passed far data must be model independent.
+ */
+
+#if defined(USE_FAR_KEYWORD)  /* memory model independent fns */
+/* use this to make far-to-near assignments */
+#   define CHECK   1
+#   define NOCHECK 0
+#   define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK))
+#   define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK))
+#   define png_strlen _fstrlen
+#   define png_memcmp _fmemcmp      /* SJT: added */
+#   define png_memcpy _fmemcpy
+#   define png_memset _fmemset
+#else /* use the usual functions */
+#   define CVT_PTR(ptr)         (ptr)
+#   define CVT_PTR_NOCHECK(ptr) (ptr)
+#   define png_strlen strlen
+#   define png_memcmp memcmp     /* SJT: added */
+#   define png_memcpy memcpy
+#   define png_memset memset
+#endif
+/* End of memory model independent support */
+
+/* Just a double check that someone hasn't tried to define something
+ * contradictory. 
+ */
+#if (PNG_ZBUF_SIZE > 65536) && defined(PNG_MAX_MALLOC_64K)
+#undef PNG_ZBUF_SIZE
+#define PNG_ZBUF_SIZE 65536
+#endif
+
+#endif /* PNGCONF_H */
+
diff --git a/src/png/pngerror.c b/src/png/pngerror.c
new file mode 100644
index 0000000000..9bf58a4a5c
--- /dev/null
+++ b/src/png/pngerror.c
@@ -0,0 +1,174 @@
+
+/* pngerror.c - stub functions for i/o and memory allocation
+ *
+ * libpng 1.0.1
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Copyright (c) 1998, Glenn Randers-Pehrson
+ * March 15, 1998
+ *
+ * This file provides a location for all error handling.  Users which
+ * need special error handling are expected to write replacement functions
+ * and use png_set_error_fn() to use those functions.  See the instructions
+ * at each function.
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+static void png_default_error PNGARG((png_structp png_ptr,
+                                      png_const_charp message));
+static void png_default_warning PNGARG((png_structp png_ptr,
+                                        png_const_charp message));
+
+/* This function is called whenever there is a fatal error.  This function
+ * should not be changed.  If there is a need to handle errors differently,
+ * you should supply a replacement error function and use png_set_error_fn()
+ * to replace the error function at run-time.
+ */
+void
+png_error(png_structp png_ptr, png_const_charp message)
+{
+   if (png_ptr->error_fn != NULL)
+      (*(png_ptr->error_fn))(png_ptr, message);
+
+   /* if the following returns or doesn't exist, use the default function,
+      which will not return */
+   png_default_error(png_ptr, message);
+}
+
+/* This function is called whenever there is a non-fatal error.  This function
+ * should not be changed.  If there is a need to handle warnings differently,
+ * you should supply a replacement warning function and use
+ * png_set_error_fn() to replace the warning function at run-time.
+ */
+void
+png_warning(png_structp png_ptr, png_const_charp message)
+{
+   if (png_ptr->warning_fn != NULL)
+      (*(png_ptr->warning_fn))(png_ptr, message);
+   else
+      png_default_warning(png_ptr, message);
+}
+
+/* These utilities are used internally to build an error message which relates
+ * to the current chunk.  The chunk name comes from png_ptr->chunk_name,
+ * this is used to prefix the message.  The message is limited in length
+ * to 63 bytes, the name characters are output as hex digits wrapped in []
+ * if the character is invalid.
+ */
+#define isnonalpha(c) ((c) < 41 || (c) > 122 || ((c) > 90 && (c) < 97))
+static PNG_CONST char png_digit[16] = {
+   '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+};
+
+static void
+png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp message)
+{
+   int iout = 0, iin = 0;
+
+   while (iin < 4) {
+      int c = png_ptr->chunk_name[iin++];
+      if (isnonalpha(c)) {
+         buffer[iout++] = '[';
+         buffer[iout++] = png_digit[(c & 0xf0) >> 4];
+         buffer[iout++] = png_digit[c & 0xf];
+         buffer[iout++] = ']';
+      } else {
+         buffer[iout++] = c;
+      }
+   }
+
+   if (message == NULL)
+      buffer[iout] = 0;
+   else {
+      buffer[iout++] = ':';
+      buffer[iout++] = ' ';
+      png_memcpy(buffer+iout, message, 64);
+      buffer[iout+63] = 0;
+   }
+}
+
+void
+png_chunk_error(png_structp png_ptr, png_const_charp message)
+{
+   char msg[16+64];
+   png_format_buffer(png_ptr, msg, message);
+   png_error(png_ptr, msg);
+}
+
+void
+png_chunk_warning(png_structp png_ptr, png_const_charp message)
+{
+   char msg[16+64];
+   png_format_buffer(png_ptr, msg, message);
+   png_warning(png_ptr, msg);
+}
+
+/* This is the default error handling function.  Note that replacements for
+ * this function MUST NOT RETURN, or the program will likely crash.  This
+ * function is used by default, or if the program supplies NULL for the
+ * error function pointer in png_set_error_fn().
+ */
+static void
+png_default_error(png_structp png_ptr, png_const_charp message)
+{
+#ifndef PNG_NO_STDIO
+   fprintf(stderr, "libpng error: %s\n", message);
+#endif
+
+#ifdef USE_FAR_KEYWORD
+   {
+      jmp_buf jmpbuf;
+      png_memcpy(jmpbuf,png_ptr->jmpbuf,sizeof(jmp_buf));
+      longjmp(jmpbuf, 1);
+   }
+#else
+   longjmp(png_ptr->jmpbuf, 1);
+#endif
+}
+
+/* This function is called when there is a warning, but the library thinks
+ * it can continue anyway.  Replacement functions don't have to do anything
+ * here if you don't want to.  In the default configuration, png_ptr is
+ * not used, but it is passed in case it may be useful.
+ */
+static void
+png_default_warning(png_structp png_ptr, png_const_charp message)
+{
+   if (png_ptr == NULL)
+      return;
+
+#ifndef PNG_NO_STDIO
+   fprintf(stderr, "libpng warning: %s\n", message);
+#endif
+}
+
+/* This function is called when the application wants to use another method
+ * of handling errors and warnings.  Note that the error function MUST NOT
+ * return to the calling routine or serious problems will occur.  The return
+ * method used in the default routine calls longjmp(png_ptr->jmpbuf, 1)
+ */
+void
+png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
+   png_error_ptr error_fn, png_error_ptr warning_fn)
+{
+   png_ptr->error_ptr = error_ptr;
+   png_ptr->error_fn = error_fn;
+   png_ptr->warning_fn = warning_fn;
+}
+
+
+/* This function returns a pointer to the error_ptr associated with the user
+ * functions.  The application should free any memory associated with this
+ * pointer before png_write_destroy and png_read_destroy are called.
+ */
+png_voidp
+png_get_error_ptr(png_structp png_ptr)
+{
+   return ((png_voidp)png_ptr->error_ptr);
+}
+
+
+
diff --git a/src/png/pngget.c b/src/png/pngget.c
new file mode 100644
index 0000000000..eb2f64fade
--- /dev/null
+++ b/src/png/pngget.c
@@ -0,0 +1,644 @@
+
+/* pngget.c - retrieval of values from info struct
+ *
+ * libpng 1.0.1
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Copyright (c) 1998, Glenn Randers-Pehrson
+ * March 15, 1998
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+png_uint_32
+png_get_valid(png_structp png_ptr, png_infop info_ptr, png_uint_32 flag)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return(info_ptr->valid & flag);
+   else
+      return(0);
+}
+
+png_uint_32
+png_get_rowbytes(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return(info_ptr->rowbytes);
+   else
+      return(0);
+}
+
+#ifdef PNG_EASY_ACCESS_SUPPORTED
+/* easy access to info, added in libpng-0.99 */
+png_uint_32
+png_get_image_width(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+   {
+      return info_ptr->width;
+   }
+   return (0);
+}
+
+png_uint_32
+png_get_image_height(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+   {
+      return info_ptr->height;
+   }
+   return (0);
+}
+
+png_byte
+png_get_bit_depth(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+   {
+      return info_ptr->bit_depth;
+   }
+   return (0);
+}
+
+png_byte
+png_get_color_type(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+   {
+      return info_ptr->color_type;
+   }
+   return (0);
+}
+
+png_byte
+png_get_filter_type(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+   {
+      return info_ptr->filter_type;
+   }
+   return (0);
+}
+
+png_byte
+png_get_interlace_type(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+   {
+      return info_ptr->interlace_type;
+   }
+   return (0);
+}
+
+png_byte
+png_get_compression_type(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+   {
+      return info_ptr->compression_type;
+   }
+   return (0);
+}
+
+png_uint_32
+png_get_x_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
+{
+#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+   {
+      png_debug1(1, "in %s retrieval function\n", "png_get_x_pixels_per_meter");
+      if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
+          return (0);
+      else return (info_ptr->x_pixels_per_unit);
+   }
+   else
+#endif
+   return (0);
+}
+
+png_uint_32
+png_get_y_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
+{
+#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+   {
+      png_debug1(1, "in %s retrieval function\n", "png_get_y_pixels_per_meter");
+      if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
+          return (0);
+      else return (info_ptr->y_pixels_per_unit);
+   }
+   else
+#endif
+   return (0);
+}
+
+png_uint_32
+png_get_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
+{
+#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+   {
+      png_debug1(1, "in %s retrieval function\n", "png_get_pixels_per_meter");
+      if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER ||
+         info_ptr->x_pixels_per_unit != info_ptr->y_pixels_per_unit)
+          return (0);
+      else return (info_ptr->x_pixels_per_unit);
+   }
+   else
+#endif
+   return (0);
+}
+
+float
+png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr)
+   {
+#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+   {
+      png_debug1(1, "in %s retrieval function\n", "png_get_aspect_ratio");
+      if (info_ptr->x_pixels_per_unit == 0)
+         return ((float)0.0);
+      else
+         return ((float)info_ptr->y_pixels_per_unit
+            /(float)info_ptr->x_pixels_per_unit);
+   }
+   else
+#endif
+      return ((float)0.0);
+}
+
+png_uint_32
+png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr)
+{
+#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
+   {
+      png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns");
+      if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
+          return (0);
+      else return (info_ptr->x_offset);
+   }
+   else
+#endif
+   return (0);
+}
+
+png_uint_32
+png_get_y_offset_microns(png_structp png_ptr, png_infop info_ptr)
+{
+#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
+   {
+      png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns");
+      if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
+          return (0);
+      else return (info_ptr->y_offset);
+   }
+   else
+#endif
+   return (0);
+}
+
+png_uint_32
+png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr)
+{
+#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
+   {
+      png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns");
+      if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
+          return (0);
+      else return (info_ptr->x_offset);
+   }
+   else
+#endif
+   return (0);
+}
+
+png_uint_32
+png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr)
+{
+#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
+   {
+      png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns");
+      if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
+          return (0);
+      else return (info_ptr->y_offset);
+   }
+   else
+#endif
+   return (0);
+}
+
+#ifdef PNG_INCH_CONVERSIONS
+png_uint_32
+png_get_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
+{
+   return ((png_uint_32)((float)png_get_pixels_per_meter(png_ptr, info_ptr)
+     *.03937 +.5)
+}
+
+png_uint_32
+png_get_x_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
+{
+   return ((png_uint_32)((float)png_get_x_pixels_per_meter(png_ptr, info_ptr)
+     *.03937 +.5)
+}
+
+png_uint_32
+png_get_y_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
+{
+   return ((png_uint_32)((float)png_get_y_pixels_per_meter(png_ptr, info_ptr)
+     *.03937 +.5)
+}
+
+float
+png_get_x_offset_inches(png_structp png_ptr, png_infop info_ptr)
+{
+   return ((float)png_get_x_offset_microns(png_ptr, info_ptr)
+     *.03937/1000000. +.5)
+}
+
+float
+png_get_y_offset_inches(png_structp png_ptr, png_infop info_ptr)
+{
+   return ((float)png_get_y_offset_microns(png_ptr, info_ptr)
+     *.03937/1000000. +.5)
+}
+
+#if defined(PNG_READ_pHYs_SUPPORTED)
+png_uint_32
+png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
+{
+   png_uint_32 retval = 0;
+
+   if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_pHYs)
+   {
+      png_debug1(1, "in %s retrieval function\n", "pHYs");
+      if (res_x != NULL)
+      {
+         *res_x = info_ptr->x_pixels_per_unit;
+         retval |= PNG_INFO_pHYs;
+      }
+      if (res_y != NULL)
+      {
+         *res_y = info_ptr->y_pixels_per_unit;
+         retval |= PNG_INFO_pHYs;
+      }
+      if (unit_type != NULL)
+      {
+         *unit_type = (int)info_ptr->phys_unit_type;
+         retval |= PNG_INFO_pHYs;
+         if(unit_type == 1)
+         {
+            if (res_x != NULL) *res_x = (png_uint_32)(*res_x * 39.37 + .50);
+            if (res_y != NULL) *res_y = (png_uint_32)(*res_y * 39.37 + .50);
+         }
+      }
+   }
+   return (retval);
+}
+#endif
+
+#endif  /* PNG_INCH_CONVERSIONS */
+
+/* png_get_channels really belongs in here, too, but it's been around longer */
+#endif  /* PNG_EASY_ACCESS_SUPPORTED */
+
+png_byte
+png_get_channels(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return(info_ptr->channels);
+   else
+      return (0);
+}
+
+png_bytep
+png_get_signature(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr != NULL && info_ptr != NULL)
+      return(info_ptr->signature);
+   else
+      return (NULL);
+}
+
+#if defined(PNG_READ_bKGD_SUPPORTED)
+png_uint_32
+png_get_bKGD(png_structp png_ptr, png_infop info_ptr,
+   png_color_16p *background)
+{
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)
+      && background != NULL)
+   {
+      png_debug1(1, "in %s retrieval function\n", "bKGD");
+      *background = &(info_ptr->background);
+      return (PNG_INFO_bKGD);
+   }
+   return (0);
+}
+#endif
+
+#if defined(PNG_READ_cHRM_SUPPORTED)
+png_uint_32
+png_get_cHRM(png_structp png_ptr, png_infop info_ptr,
+   double *white_x, double *white_y, double *red_x, double *red_y,
+   double *green_x, double *green_y, double *blue_x, double *blue_y)
+{
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
+   {
+      png_debug1(1, "in %s retrieval function\n", "cHRM");
+      if (white_x != NULL)
+         *white_x = (double)info_ptr->x_white;
+      if (white_y != NULL)
+         *white_y = (double)info_ptr->y_white;
+      if (red_x != NULL)
+         *red_x = (double)info_ptr->x_red;
+      if (red_y != NULL)
+         *red_y = (double)info_ptr->y_red;
+      if (green_x != NULL)
+         *green_x = (double)info_ptr->x_green;
+      if (green_y != NULL)
+         *green_y = (double)info_ptr->y_green;
+      if (blue_x != NULL)
+         *blue_x = (double)info_ptr->x_blue;
+      if (blue_y != NULL)
+         *blue_y = (double)info_ptr->y_blue;
+      return (PNG_INFO_cHRM);
+   }
+   return (0);
+}
+#endif
+
+#if defined(PNG_READ_gAMA_SUPPORTED)
+png_uint_32
+png_get_gAMA(png_structp png_ptr, png_infop info_ptr, double *file_gamma)
+{
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
+      && file_gamma != NULL)
+   {
+      png_debug1(1, "in %s retrieval function\n", "gAMA");
+      *file_gamma = (double)info_ptr->gamma;
+      return (PNG_INFO_gAMA);
+   }
+   return (0);
+}
+#endif
+
+#if defined(PNG_READ_sRGB_SUPPORTED)
+png_uint_32
+png_get_sRGB(png_structp png_ptr, png_infop info_ptr, int *file_srgb_intent)
+{
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)
+      && file_srgb_intent != NULL)
+   {
+      png_debug1(1, "in %s retrieval function\n", "sRGB");
+      *file_srgb_intent = (int)info_ptr->srgb_intent;
+      return (PNG_INFO_sRGB);
+   }
+   return (0);
+}
+#endif
+
+#if defined(PNG_READ_hIST_SUPPORTED)
+png_uint_32
+png_get_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p *hist)
+{
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)
+      && hist != NULL)
+   {
+      png_debug1(1, "in %s retrieval function\n", "hIST");
+      *hist = info_ptr->hist;
+      return (PNG_INFO_hIST);
+   }
+   return (0);
+}
+#endif
+
+png_uint_32
+png_get_IHDR(png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 *width, png_uint_32 *height, int *bit_depth,
+   int *color_type, int *interlace_type, int *compression_type,
+   int *filter_type)
+   
+{
+   if (png_ptr != NULL && info_ptr != NULL && width != NULL && height != NULL &&
+      bit_depth != NULL && color_type != NULL)
+   {
+      int pixel_depth, channels;
+      png_uint_32 rowbytes_per_pixel;
+
+      png_debug1(1, "in %s retrieval function\n", "IHDR");
+      *width = info_ptr->width;
+      *height = info_ptr->height;
+      *bit_depth = info_ptr->bit_depth;
+      *color_type = info_ptr->color_type;
+      if (compression_type != NULL)
+         *compression_type = info_ptr->compression_type;
+      if (filter_type != NULL)
+         *filter_type = info_ptr->filter_type;
+      if (interlace_type != NULL)
+         *interlace_type = info_ptr->interlace_type;
+
+      /* check for potential overflow of rowbytes */
+      if (*color_type == PNG_COLOR_TYPE_PALETTE)
+         channels = 1;
+      else if (*color_type & PNG_COLOR_MASK_COLOR)
+         channels = 3;
+      else
+         channels = 1;
+      if (*color_type & PNG_COLOR_MASK_ALPHA)
+         channels++;
+      pixel_depth = *bit_depth * channels;
+      rowbytes_per_pixel = (pixel_depth + 7) >> 3;
+      if ((*width > (png_uint_32)2147483647L/rowbytes_per_pixel))
+      {
+         png_warning(png_ptr,
+            "Width too large for libpng to process image data.");
+      }
+      return (1);
+   }
+   return (0);
+}
+
+#if defined(PNG_READ_oFFs_SUPPORTED)
+png_uint_32
+png_get_oFFs(png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 *offset_x, png_uint_32 *offset_y, int *unit_type)
+{
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)
+      && offset_x != NULL && offset_y != NULL && unit_type != NULL)
+   {
+      png_debug1(1, "in %s retrieval function\n", "oFFs");
+      *offset_x = info_ptr->x_offset;
+      *offset_y = info_ptr->y_offset;
+      *unit_type = (int)info_ptr->offset_unit_type;
+      return (PNG_INFO_oFFs);
+   }
+   return (0);
+}
+#endif
+
+#if defined(PNG_READ_pCAL_SUPPORTED)
+png_uint_32
+png_get_pCAL(png_structp png_ptr, png_infop info_ptr,
+   png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
+   png_charp *units, png_charpp *params)
+{
+   if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_pCAL &&
+      purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
+      nparams != NULL && units != NULL && params != NULL)
+   {
+      png_debug1(1, "in %s retrieval function\n", "pCAL");
+      *purpose = info_ptr->pcal_purpose;
+      *X0 = info_ptr->pcal_X0;
+      *X1 = info_ptr->pcal_X1;
+      *type = (int)info_ptr->pcal_type;
+      *nparams = (int)info_ptr->pcal_nparams;
+      *units = info_ptr->pcal_units;
+      *params = info_ptr->pcal_params;
+      return (PNG_INFO_pCAL);
+   }
+   return (0);
+}
+#endif
+
+#if defined(PNG_READ_pHYs_SUPPORTED)
+png_uint_32
+png_get_pHYs(png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
+{
+   png_uint_32 retval = 0;
+
+   if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_pHYs)
+   {
+      png_debug1(1, "in %s retrieval function\n", "pHYs");
+      if (res_x != NULL)
+      {
+         *res_x = info_ptr->x_pixels_per_unit;
+         retval |= PNG_INFO_pHYs;
+      }
+      if (res_y != NULL)
+      {
+         *res_y = info_ptr->y_pixels_per_unit;
+         retval |= PNG_INFO_pHYs;
+      }
+      if (unit_type != NULL)
+      {
+         *unit_type = (int)info_ptr->phys_unit_type;
+         retval |= PNG_INFO_pHYs;
+      }
+   }
+   return (retval);
+}
+#endif
+
+png_uint_32
+png_get_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp *palette,
+   int *num_palette)
+{
+   if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_PLTE &&
+       palette != NULL)
+   {
+      png_debug1(1, "in %s retrieval function\n", "PLTE");
+      *palette = info_ptr->palette;
+      *num_palette = info_ptr->num_palette;
+      png_debug1(3, "num_palette = %d\n", *num_palette);
+      return (PNG_INFO_PLTE);
+   }
+   return (0);
+}
+
+#if defined(PNG_READ_sBIT_SUPPORTED)
+png_uint_32
+png_get_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit)
+{
+   if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_sBIT &&
+       sig_bit != NULL)
+   {
+      png_debug1(1, "in %s retrieval function\n", "sBIT");
+      *sig_bit = &(info_ptr->sig_bit);
+      return (PNG_INFO_sBIT);
+   }
+   return (0);
+}
+#endif
+
+#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
+png_uint_32
+png_get_text(png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr,
+   int *num_text)
+{
+   if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
+   {
+      png_debug1(1, "in %s retrieval function\n",
+         (png_ptr->chunk_name[0] == '\0' ? "text"
+             : (png_const_charp)png_ptr->chunk_name));
+      if (text_ptr != NULL)
+         *text_ptr = info_ptr->text;
+      if (num_text != NULL)
+         *num_text = info_ptr->num_text;
+      return ((png_uint_32)info_ptr->num_text);
+   }
+   return(0);
+}
+#endif
+
+#if defined(PNG_READ_tIME_SUPPORTED)
+png_uint_32
+png_get_tIME(png_structp png_ptr, png_infop info_ptr, png_timep *mod_time)
+{
+   if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_tIME &&
+       mod_time != NULL)
+   {
+      png_debug1(1, "in %s retrieval function\n", "tIME");
+      *mod_time = &(info_ptr->mod_time);
+      return (PNG_INFO_tIME);
+   }
+   return (0);
+}
+#endif
+
+#if defined(PNG_READ_tRNS_SUPPORTED)
+png_uint_32
+png_get_tRNS(png_structp png_ptr, png_infop info_ptr,
+   png_bytep *trans, int *num_trans, png_color_16p *trans_values)
+{
+   png_uint_32 retval = 0;
+   if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_tRNS)
+   {
+      png_debug1(1, "in %s retrieval function\n", "tRNS");
+      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+          if (trans != NULL)
+          {
+             *trans = info_ptr->trans;
+             retval |= PNG_INFO_tRNS;
+          }
+          if (trans_values != NULL)
+             *trans_values = &(info_ptr->trans_values);
+      }
+      else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */
+      {
+          if (trans_values != NULL)
+          {
+             *trans_values = &(info_ptr->trans_values);
+             retval |= PNG_INFO_tRNS;
+          }
+          if(trans != NULL)
+             *trans = NULL;
+      }
+      if(num_trans != NULL)
+      {
+         *num_trans = info_ptr->num_trans;
+         retval |= PNG_INFO_tRNS;
+      }
+   }
+   return (retval);
+}
+#endif
+
diff --git a/src/png/pngmem.c b/src/png/pngmem.c
new file mode 100644
index 0000000000..2fa3627dc4
--- /dev/null
+++ b/src/png/pngmem.c
@@ -0,0 +1,360 @@
+
+/* pngmem.c - stub functions for memory allocation
+ *
+ * libpng 1.0.1
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Copyright (c) 1998, Glenn Randers-Pehrson
+ * March 15, 1998
+ *
+ * This file provides a location for all memory allocation.  Users which
+ * need special memory handling are expected to modify the code in this file
+ * to meet their needs.  See the instructions at each function.
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+/* The following "hides" PNG_MALLOC and PNG_FREE thus allowing the pngtest
+   application to put a wrapper on top of them. */
+#ifdef PNGTEST_MEMORY_DEBUG
+#define PNG_MALLOC png_debug_malloc
+#define PNG_FREE   png_debug_free
+#else
+#define PNG_MALLOC png_malloc
+#define PNG_FREE   png_free
+#endif
+
+/* Borland DOS special memory handler */
+#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
+/* if you change this, be sure to change the one in png.h also */
+
+/* Allocate memory for a png_struct.  The malloc and memset can be replaced
+   by a single call to calloc() if this is thought to improve performance. */
+png_voidp
+png_create_struct(int type)
+{
+   png_size_t size;
+   png_voidp struct_ptr;
+
+   if (type == PNG_STRUCT_INFO)
+     size = sizeof(png_info);
+   else if (type == PNG_STRUCT_PNG)
+     size = sizeof(png_struct);
+   else
+     return ((png_voidp)NULL);
+
+   if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
+   {
+      png_memset(struct_ptr, 0, size);
+   }
+
+   return (struct_ptr);
+}
+
+
+/* Free memory allocated by a png_create_struct() call */
+void
+png_destroy_struct(png_voidp struct_ptr)
+{
+   if (struct_ptr != NULL)
+   {
+      farfree (struct_ptr);
+      struct_ptr = NULL;
+   }
+}
+
+/* Allocate memory.  For reasonable files, size should never exceed
+ * 64K.  However, zlib may allocate more then 64K if you don't tell
+ * it not to.  See zconf.h and png.h for more information. zlib does
+ * need to allocate exactly 64K, so whatever you call here must
+ * have the ability to do that.
+ *
+ * Borland seems to have a problem in DOS mode for exactly 64K.
+ * It gives you a segment with an offset of 8 (perhaps to store it's
+ * memory stuff).  zlib doesn't like this at all, so we have to
+ * detect and deal with it.  This code should not be needed in
+ * Windows or OS/2 modes, and only in 16 bit mode.  This code has
+ * been updated by Alexander Lehmann for version 0.89 to waste less
+ * memory.
+ *
+ * Note that we can't use png_size_t for the "size" declaration,
+ * since on some systems a png_size_t is a 16-bit quantity, and as a
+ * result, we would be truncating potentially larger memory requests
+ * (which should cause a fatal error) and introducing major problems.
+ */
+png_voidp
+PNG_MALLOC(png_structp png_ptr, png_uint_32 size)
+{
+   png_voidp ret;
+   if (png_ptr == NULL || size == 0)
+      return ((png_voidp)NULL);
+
+#ifdef PNG_MAX_MALLOC_64K
+   if (size > (png_uint_32)65536L)
+      png_error(png_ptr, "Cannot Allocate > 64K");
+#endif
+
+   if (size == (png_uint_32)65536L)
+   {
+      if (png_ptr->offset_table == NULL)
+      {
+         /* try to see if we need to do any of this fancy stuff */
+         ret = farmalloc(size);
+         if (ret == NULL || ((png_size_t)ret & 0xffff))
+         {
+            int num_blocks;
+            png_uint_32 total_size;
+            png_bytep table;
+            int i;
+            png_byte huge * hptr;
+
+            if (ret != NULL)
+            {
+               farfree(ret);
+               ret = NULL;
+            }
+
+            num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
+            if (num_blocks < 1)
+               num_blocks = 1;
+            if (png_ptr->zlib_mem_level >= 7)
+               num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
+            else
+               num_blocks++;
+
+            total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
+
+            table = farmalloc(total_size);
+
+            if (table == NULL)
+            {
+               png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */
+            }
+
+            if ((png_size_t)table & 0xfff0)
+            {
+               png_error(png_ptr, "Farmalloc didn't return normalized pointer");
+            }
+
+            png_ptr->offset_table = table;
+            png_ptr->offset_table_ptr = farmalloc(num_blocks *
+               sizeof (png_bytep));
+
+            if (png_ptr->offset_table_ptr == NULL)
+            {
+               png_error(png_ptr, "Out Of memory.");
+            }
+
+            hptr = (png_byte huge *)table;
+            if ((png_size_t)hptr & 0xf)
+            {
+               hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
+               hptr += 16L;
+            }
+            for (i = 0; i < num_blocks; i++)
+            {
+               png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
+               hptr += (png_uint_32)65536L;
+            }
+
+            png_ptr->offset_table_number = num_blocks;
+            png_ptr->offset_table_count = 0;
+            png_ptr->offset_table_count_free = 0;
+         }
+      }
+
+      if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
+         png_error(png_ptr, "Out of Memory.");
+
+      ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
+   }
+   else
+      ret = farmalloc(size);
+
+   if (ret == NULL)
+   {
+      png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
+   }
+
+   return (ret);
+}
+
+/* free a pointer allocated by PNG_MALLOC().  In the default
+   configuration, png_ptr is not used, but is passed in case it
+   is needed.  If ptr is NULL, return without taking any action. */
+void
+PNG_FREE(png_structp png_ptr, png_voidp ptr)
+{
+   if (png_ptr == NULL || ptr == NULL)
+      return;
+
+   if (png_ptr->offset_table != NULL)
+   {
+      int i;
+
+      for (i = 0; i < png_ptr->offset_table_count; i++)
+      {
+         if (ptr == png_ptr->offset_table_ptr[i])
+         {
+            ptr = NULL;
+            png_ptr->offset_table_count_free++;
+            break;
+         }
+      }
+      if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
+      {
+         farfree(png_ptr->offset_table);
+         farfree(png_ptr->offset_table_ptr);
+         png_ptr->offset_table = NULL;
+         png_ptr->offset_table_ptr = NULL;
+      }
+   }
+
+   if (ptr != NULL)
+   {
+      farfree(ptr);
+      ptr = NULL;
+   }
+}
+
+#else /* Not the Borland DOS special memory handler */
+
+/* Allocate memory for a png_struct or a png_info.  The malloc and
+   memset can be replaced by a single call to calloc() if this is thought
+   to improve performance noticably.*/
+png_voidp
+png_create_struct(int type)
+{
+   png_size_t size;
+   png_voidp struct_ptr;
+
+   if (type == PNG_STRUCT_INFO)
+      size = sizeof(png_info);
+   else if (type == PNG_STRUCT_PNG)
+      size = sizeof(png_struct);
+   else
+      return ((png_voidp)NULL);
+
+#if defined(__TURBOC__) && !defined(__FLAT__)
+   if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
+#else
+# if defined(_MSC_VER) && defined(MAXSEG_64K)
+   if ((struct_ptr = (png_voidp)halloc(size,1)) != NULL)
+# else
+   if ((struct_ptr = (png_voidp)malloc(size)) != NULL)
+# endif
+#endif
+   {
+      png_memset(struct_ptr, 0, size);
+   }
+
+   return (struct_ptr);
+}
+
+
+/* Free memory allocated by a png_create_struct() call */
+void
+png_destroy_struct(png_voidp struct_ptr)
+{
+   if (struct_ptr != NULL)
+   {
+#if defined(__TURBOC__) && !defined(__FLAT__)
+      farfree(struct_ptr);
+#else
+# if defined(_MSC_VER) && defined(MAXSEG_64K)
+      hfree(struct_ptr);
+# else
+      free(struct_ptr);
+# endif
+#endif
+   }
+}
+
+
+/* Allocate memory.  For reasonable files, size should never exceed
+   64K.  However, zlib may allocate more then 64K if you don't tell
+   it not to.  See zconf.h and png.h for more information.  zlib does
+   need to allocate exactly 64K, so whatever you call here must
+   have the ability to do that. */
+
+png_voidp
+PNG_MALLOC(png_structp png_ptr, png_uint_32 size)
+{
+   png_voidp ret;
+
+   if (png_ptr == NULL || size == 0)
+      return ((png_voidp)NULL);
+
+#ifdef PNG_MAX_MALLOC_64K
+   if (size > (png_uint_32)65536L)
+      png_error(png_ptr, "Cannot Allocate > 64K");
+#endif
+
+#if defined(__TURBOC__) && !defined(__FLAT__)
+   ret = farmalloc(size);
+#else
+# if defined(_MSC_VER) && defined(MAXSEG_64K)
+   ret = halloc(size, 1);
+# else
+   ret = malloc((size_t)size);
+# endif
+#endif
+
+   if (ret == NULL)
+   {
+      png_error(png_ptr, "Out of Memory");
+   }
+
+   return (ret);
+}
+
+/* Free a pointer allocated by PNG_MALLOC().  In the default
+  configuration, png_ptr is not used, but is passed in case it
+  is needed.  If ptr is NULL, return without taking any action. */
+void
+PNG_FREE(png_structp png_ptr, png_voidp ptr)
+{
+   if (png_ptr == NULL || ptr == NULL)
+      return;
+
+#if defined(__TURBOC__) && !defined(__FLAT__)
+   farfree(ptr);
+#else
+# if defined(_MSC_VER) && defined(MAXSEG_64K)
+   hfree(ptr);
+# else
+   free(ptr);
+# endif
+#endif
+}
+
+#endif /* Not Borland DOS special memory handler */
+
+png_voidp
+png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
+   png_uint_32 length)
+{
+   png_size_t size;
+
+   size = (png_size_t)length;
+   if ((png_uint_32)size != length)
+      png_error(png_ptr,"Overflow in png_memcpy_check.");
+  
+   return(png_memcpy (s1, s2, size));
+}
+
+png_voidp
+png_memset_check (png_structp png_ptr, png_voidp s1, int value,
+   png_uint_32 length)
+{
+   png_size_t size;
+
+   size = (png_size_t)length;
+   if ((png_uint_32)size != length)
+      png_error(png_ptr,"Overflow in png_memset_check.");
+
+   return (png_memset (s1, value, size));
+
+}
diff --git a/src/png/pngpread.c b/src/png/pngpread.c
new file mode 100644
index 0000000000..0f0d466fa2
--- /dev/null
+++ b/src/png/pngpread.c
@@ -0,0 +1,1143 @@
+
+/* pngpread.c - read a png file in push mode
+ *
+ * libpng 1.0.1
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Copyright (c) 1998, Glenn Randers-Pehrson
+ * March 15, 1998
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+
+void
+png_process_data(png_structp png_ptr, png_infop info_ptr,
+   png_bytep buffer, png_size_t buffer_size)
+{
+   png_push_restore_buffer(png_ptr, buffer, buffer_size);
+
+   while (png_ptr->buffer_size)
+   {
+      png_process_some_data(png_ptr, info_ptr);
+   }
+}
+
+/* What we do with the incoming data depends on what we were previously
+ * doing before we ran out of data...
+ */
+void
+png_process_some_data(png_structp png_ptr, png_infop info_ptr)
+{
+   switch (png_ptr->process_mode)
+   {
+      case PNG_READ_SIG_MODE:
+      {
+         png_push_read_sig(png_ptr, info_ptr);
+         break;
+      }
+      case PNG_READ_CHUNK_MODE:
+      {
+         png_push_read_chunk(png_ptr, info_ptr);
+         break;
+      }
+      case PNG_READ_IDAT_MODE:
+      {
+         png_push_read_IDAT(png_ptr);
+         break;
+      }
+#if defined(PNG_READ_tEXt_SUPPORTED)
+      case PNG_READ_tEXt_MODE:
+      {
+         png_push_read_tEXt(png_ptr, info_ptr);
+         break;
+      }
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+      case PNG_READ_zTXt_MODE:
+      {
+         png_push_read_zTXt(png_ptr, info_ptr);
+         break;
+      }
+#endif
+      case PNG_SKIP_MODE:
+      {
+         png_push_crc_finish(png_ptr);
+         break;
+      }
+      default:
+      {
+         png_ptr->buffer_size = 0;
+         break;
+      }
+   }
+}
+
+/* Read any remaining signature bytes from the stream and compare them with
+ * the correct PNG signature.  It is possible that this routine is called
+ * with bytes already read from the signature, whether because they have been
+ * checked by the calling application, or from multiple calls to this routine.
+ */
+void
+png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
+{
+   png_size_t num_checked = png_ptr->sig_bytes,
+             num_to_check = 8 - num_checked;
+
+   if (png_ptr->buffer_size < num_to_check)
+   {
+      num_to_check = png_ptr->buffer_size;
+   }
+
+   png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]), 
+      num_to_check);
+   png_ptr->sig_bytes += num_to_check;
+
+   if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
+   {
+      if (num_checked < 4 &&
+          png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
+         png_error(png_ptr, "Not a PNG file");
+      else
+         png_error(png_ptr, "PNG file corrupted by ASCII conversion");
+   }
+   else
+   {
+      if (png_ptr->sig_bytes >= 8)
+      {
+         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+      }
+   }
+}
+
+void
+png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
+{
+   /* First we make sure we have enough data for the 4 byte chunk name
+    * and the 4 byte chunk length before proceeding with decoding the
+    * chunk data.  To fully decode each of these chunks, we also make
+    * sure we have enough data in the buffer for the 4 byte CRC at the
+    * end of every chunk (except IDAT, which is handled separately).
+    */
+   if (!(png_ptr->flags & PNG_FLAG_HAVE_CHUNK_HEADER))
+   {
+      png_byte chunk_length[4];
+
+      if (png_ptr->buffer_size < 8)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_push_fill_buffer(png_ptr, chunk_length, 4);
+      png_ptr->push_length = png_get_uint_32(chunk_length);
+      png_reset_crc(png_ptr);
+      png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+      png_ptr->flags |= PNG_FLAG_HAVE_CHUNK_HEADER;
+   }
+
+   if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
+   }
+   else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
+   }
+   else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+   {
+      /* If we reach an IDAT chunk, this means we have read all of the
+       * header chunks, and we can start reading the image (or if this
+       * is called after the image has been read - we have an error).
+       */
+      if (png_ptr->mode & PNG_HAVE_IDAT)
+      {
+         if (png_ptr->push_length == 0)
+            return;
+
+         if (png_ptr->mode & PNG_AFTER_IDAT)
+            png_error(png_ptr, "Too many IDAT's found");
+      }
+
+      png_ptr->idat_size = png_ptr->push_length;
+      png_ptr->mode |= PNG_HAVE_IDAT;
+      png_ptr->process_mode = PNG_READ_IDAT_MODE;
+      png_push_have_info(png_ptr, info_ptr);
+      png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
+      png_ptr->zstream.next_out = png_ptr->row_buf;
+      return;
+   }
+   else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
+      png_ptr->process_mode = PNG_READ_DONE_MODE;
+      png_push_have_end(png_ptr, info_ptr);
+   }
+#if defined(PNG_READ_gAMA_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_bKGD_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
+   {
+      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
+   {
+      png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
+   {
+      png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
+   else
+   {
+      png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
+   }
+
+   png_ptr->flags &= ~PNG_FLAG_HAVE_CHUNK_HEADER;
+}
+
+void
+png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
+{
+   png_ptr->process_mode = PNG_SKIP_MODE;
+   png_ptr->skip_length = skip;
+}
+
+void
+png_push_crc_finish(png_structp png_ptr)
+{
+   if (png_ptr->skip_length && png_ptr->save_buffer_size)
+   {
+      png_size_t save_size;
+
+      if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
+         save_size = (png_size_t)png_ptr->skip_length;
+      else
+         save_size = png_ptr->save_buffer_size;
+
+      png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
+
+      png_ptr->skip_length -= save_size;
+      png_ptr->buffer_size -= save_size;
+      png_ptr->save_buffer_size -= save_size;
+      png_ptr->save_buffer_ptr += save_size;
+   }
+   if (png_ptr->skip_length && png_ptr->current_buffer_size)
+   {
+      png_size_t save_size;
+
+      if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
+         save_size = (png_size_t)png_ptr->skip_length;
+      else
+         save_size = png_ptr->current_buffer_size;
+
+      png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
+
+      png_ptr->skip_length -= save_size;
+      png_ptr->buffer_size -= save_size;
+      png_ptr->current_buffer_size -= save_size;
+      png_ptr->current_buffer_ptr += save_size;
+   }
+   if (!png_ptr->skip_length)
+   {
+      if (png_ptr->buffer_size < 4)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_crc_finish(png_ptr, 0);
+      png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+   }
+}
+
+void
+png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
+{
+   png_bytep ptr;
+
+   ptr = buffer;
+   if (png_ptr->save_buffer_size)
+   {
+      png_size_t save_size;
+
+      if (length < png_ptr->save_buffer_size)
+         save_size = length;
+      else
+         save_size = png_ptr->save_buffer_size;
+
+      png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
+      length -= save_size;
+      ptr += save_size;
+      png_ptr->buffer_size -= save_size;
+      png_ptr->save_buffer_size -= save_size;
+      png_ptr->save_buffer_ptr += save_size;
+   }
+   if (length && png_ptr->current_buffer_size)
+   {
+      png_size_t save_size;
+
+      if (length < png_ptr->current_buffer_size)
+         save_size = length;
+      else
+         save_size = png_ptr->current_buffer_size;
+
+      png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
+      png_ptr->buffer_size -= save_size;
+      png_ptr->current_buffer_size -= save_size;
+      png_ptr->current_buffer_ptr += save_size;
+   }
+}
+
+void
+png_push_save_buffer(png_structp png_ptr)
+{
+   if (png_ptr->save_buffer_size)
+   {
+      if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
+      {
+         png_size_t i;
+         png_bytep sp;
+         png_bytep dp;
+
+         for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
+            i < png_ptr->save_buffer_size;
+            i++, sp++, dp++)
+         {
+            *dp = *sp;
+         }
+      }
+   }
+   if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
+      png_ptr->save_buffer_max)
+   {
+      png_size_t new_max;
+      png_bytep old_buffer;
+
+      new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
+      old_buffer = png_ptr->save_buffer;
+      png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr, 
+         (png_uint_32)new_max);
+      png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
+      png_free(png_ptr, old_buffer);
+      png_ptr->save_buffer_max = new_max;
+   }
+   if (png_ptr->current_buffer_size)
+   {
+      png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
+         png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
+      png_ptr->save_buffer_size += png_ptr->current_buffer_size;
+      png_ptr->current_buffer_size = 0;
+   }
+   png_ptr->save_buffer_ptr = png_ptr->save_buffer;
+   png_ptr->buffer_size = 0;
+}
+
+void
+png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
+   png_size_t buffer_length)
+{
+   png_ptr->current_buffer = buffer;
+   png_ptr->current_buffer_size = buffer_length;
+   png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
+   png_ptr->current_buffer_ptr = png_ptr->current_buffer;
+}
+
+void
+png_push_read_IDAT(png_structp png_ptr)
+{
+   if (!(png_ptr->flags & PNG_FLAG_HAVE_CHUNK_HEADER))
+   {
+      png_byte chunk_length[4];
+
+      if (png_ptr->buffer_size < 8)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_push_fill_buffer(png_ptr, chunk_length, 4);
+      png_ptr->push_length = png_get_uint_32(chunk_length);
+
+      png_reset_crc(png_ptr);
+      png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+      png_ptr->flags |= PNG_FLAG_HAVE_CHUNK_HEADER;
+
+      if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+      {
+         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+         if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
+            png_error(png_ptr, "Not enough compressed data");
+         return;
+      }
+
+      png_ptr->idat_size = png_ptr->push_length;
+   }
+   if (png_ptr->idat_size && png_ptr->save_buffer_size)
+   {
+      png_size_t save_size;
+
+      if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
+      {
+         save_size = (png_size_t)png_ptr->idat_size;
+         /* check for overflow */
+         if((png_uint_32)save_size != png_ptr->idat_size)
+            png_error(png_ptr, "save_size overflowed in pngpread");
+      }
+      else
+         save_size = png_ptr->save_buffer_size;
+
+      png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
+      png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
+
+      png_ptr->idat_size -= save_size;
+      png_ptr->buffer_size -= save_size;
+      png_ptr->save_buffer_size -= save_size;
+      png_ptr->save_buffer_ptr += save_size;
+   }
+   if (png_ptr->idat_size && png_ptr->current_buffer_size)
+   {
+      png_size_t save_size;
+
+      if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size)
+      {
+         save_size = (png_size_t)png_ptr->idat_size;
+         /* check for overflow */
+         if((png_uint_32)save_size != png_ptr->idat_size)
+            png_error(png_ptr, "save_size overflowed in pngpread");
+      }
+      else
+         save_size = png_ptr->current_buffer_size;
+
+      png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
+      png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
+
+      png_ptr->idat_size -= save_size;
+      png_ptr->buffer_size -= save_size;
+      png_ptr->current_buffer_size -= save_size;
+      png_ptr->current_buffer_ptr += save_size;
+   }
+   if (!png_ptr->idat_size)
+   {
+      if (png_ptr->buffer_size < 4)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_crc_finish(png_ptr, 0);
+      png_ptr->flags &= ~PNG_FLAG_HAVE_CHUNK_HEADER;
+   }
+}
+
+void
+png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
+   png_size_t buffer_length)
+{
+   int ret;
+
+   if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length)
+      png_error(png_ptr, "Extra compression data");
+
+   png_ptr->zstream.next_in = buffer;
+   png_ptr->zstream.avail_in = (uInt)buffer_length;
+   for(;;)
+   {
+      ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+      if (ret == Z_STREAM_END)
+      {
+         if (png_ptr->zstream.avail_in)
+            png_error(png_ptr, "Extra compressed data");
+         if (!(png_ptr->zstream.avail_out))
+         {
+            png_push_process_row(png_ptr);
+         }
+
+         png_ptr->mode |= PNG_AFTER_IDAT;
+         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+         break;
+      }
+      else if (ret == Z_BUF_ERROR)
+         break;
+      else if (ret != Z_OK)
+         png_error(png_ptr, "Decompression Error");
+      if (!(png_ptr->zstream.avail_out))
+      {
+         png_push_process_row(png_ptr);
+         png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
+         png_ptr->zstream.next_out = png_ptr->row_buf;
+      }
+      else
+         break;
+   }
+}
+
+void
+png_push_process_row(png_structp png_ptr)
+{
+   png_ptr->row_info.color_type = png_ptr->color_type;
+   png_ptr->row_info.width = png_ptr->iwidth;
+   png_ptr->row_info.channels = png_ptr->channels;
+   png_ptr->row_info.bit_depth = png_ptr->bit_depth;
+   png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
+   
+   png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
+      (png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
+
+   png_read_filter_row(png_ptr, &(png_ptr->row_info),
+      png_ptr->row_buf + 1, png_ptr->prev_row + 1,
+      (int)(png_ptr->row_buf[0]));
+
+   png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
+      png_ptr->rowbytes + 1);
+
+   if (png_ptr->transformations)
+      png_do_read_transformations(png_ptr);
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED)
+   /* blow up interlaced rows to full size */
+   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
+   {
+      if (png_ptr->pass < 6)
+         png_do_read_interlace(&(png_ptr->row_info),
+            png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
+
+      switch (png_ptr->pass)
+      {
+         case 0:
+         {
+            int i;
+            for (i = 0; i < 8 && png_ptr->pass == 0; i++)
+            {
+               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+               png_read_push_finish_row(png_ptr);
+            }
+            break;
+         }
+         case 1:
+         {
+            int i;
+            for (i = 0; i < 8 && png_ptr->pass == 1; i++)
+            {
+               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+               png_read_push_finish_row(png_ptr);
+            }
+            if (png_ptr->pass == 2)
+            {
+               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+               {
+                  png_push_have_row(png_ptr, NULL);
+                  png_read_push_finish_row(png_ptr);
+               }
+            }
+            break;
+         }
+         case 2:
+         {
+            int i;
+            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+            {
+               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+               png_read_push_finish_row(png_ptr);
+            }
+            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+            {
+               png_push_have_row(png_ptr, NULL);
+               png_read_push_finish_row(png_ptr);
+            }
+            break;
+         }
+         case 3:
+         {
+            int i;
+            for (i = 0; i < 4 && png_ptr->pass == 3; i++)
+            {
+               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+               png_read_push_finish_row(png_ptr);
+            }
+            if (png_ptr->pass == 4)
+            {
+               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+               {
+                  png_push_have_row(png_ptr, NULL);
+                  png_read_push_finish_row(png_ptr);
+               }
+            }
+            break;
+         }
+         case 4:
+         {
+            int i;
+            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+            {
+               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+               png_read_push_finish_row(png_ptr);
+            }
+            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+            {
+               png_push_have_row(png_ptr, NULL);
+               png_read_push_finish_row(png_ptr);
+            }
+            break;
+         }
+         case 5:
+         {
+            int i;
+            for (i = 0; i < 2 && png_ptr->pass == 5; i++)
+            {
+               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+               png_read_push_finish_row(png_ptr);
+            }
+            if (png_ptr->pass == 6)
+            {
+               png_push_have_row(png_ptr, NULL);
+               png_read_push_finish_row(png_ptr);
+            }
+            break;
+         }
+         case 6:
+         {
+            png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+            png_read_push_finish_row(png_ptr);
+            if (png_ptr->pass != 6)
+               break;
+            png_push_have_row(png_ptr, NULL);
+            png_read_push_finish_row(png_ptr);
+         }
+      }
+   }
+   else
+#endif
+   {
+      png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+      png_read_push_finish_row(png_ptr);
+   }
+}
+
+void
+png_read_push_finish_row(png_structp png_ptr)
+{
+   png_ptr->row_number++;
+   if (png_ptr->row_number < png_ptr->num_rows)
+      return;
+
+   if (png_ptr->interlaced)
+   {
+      png_ptr->row_number = 0;
+      png_memset_check(png_ptr, png_ptr->prev_row, 0,
+         png_ptr->rowbytes + 1);
+      do
+      {
+         png_ptr->pass++;
+         if (png_ptr->pass >= 7)
+            break;
+         png_ptr->iwidth = (png_ptr->width +
+            png_pass_inc[png_ptr->pass] - 1 -
+            png_pass_start[png_ptr->pass]) /
+            png_pass_inc[png_ptr->pass];
+
+         png_ptr->irowbytes = ((png_ptr->iwidth *
+            png_ptr->pixel_depth + 7) >> 3) + 1;
+
+         if (!(png_ptr->transformations & PNG_INTERLACE))
+         {
+            png_ptr->num_rows = (png_ptr->height +
+               png_pass_yinc[png_ptr->pass] - 1 -
+               png_pass_ystart[png_ptr->pass]) /
+               png_pass_yinc[png_ptr->pass];
+            if (!(png_ptr->num_rows))
+               continue;
+         }
+         if (png_ptr->transformations & PNG_INTERLACE)
+            break;
+      } while (png_ptr->iwidth == 0);
+   }
+}
+
+#if defined(PNG_READ_tEXt_SUPPORTED)
+void
+png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   if (png_ptr->mode == PNG_BEFORE_IHDR || png_ptr->mode & PNG_HAVE_IEND)
+      {
+         png_error(png_ptr, "Out of place tEXt");
+         /* to quiet some compiler warnings */
+         if(info_ptr == NULL) return;
+      }
+
+#ifdef PNG_MAX_MALLOC_64K
+   png_ptr->skip_length = 0;  /* This may not be necessary */
+
+   if (length > (png_uint_32)65535L) /* Can't hold the entire string in memory */
+   {
+      png_warning(png_ptr, "tEXt chunk too large to fit in memory");
+      png_ptr->skip_length = length - (png_uint_32)65535L;
+      length = (png_uint_32)65535L;
+   }
+#endif
+
+   png_ptr->current_text = (png_charp)png_malloc(png_ptr, 
+         (png_uint_32)(length+1));
+   png_ptr->current_text[length] = '\0';
+   png_ptr->current_text_ptr = png_ptr->current_text;
+   png_ptr->current_text_size = (png_size_t)length;
+   png_ptr->current_text_left = (png_size_t)length;
+   png_ptr->process_mode = PNG_READ_tEXt_MODE;
+}
+
+void
+png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr->buffer_size && png_ptr->current_text_left)
+   {
+      png_size_t text_size;
+
+      if (png_ptr->buffer_size < png_ptr->current_text_left)
+         text_size = png_ptr->buffer_size;
+      else
+         text_size = png_ptr->current_text_left;
+      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
+      png_ptr->current_text_left -= text_size;
+      png_ptr->current_text_ptr += text_size;
+   }
+   if (!(png_ptr->current_text_left))
+   {
+      png_textp text_ptr;
+      png_charp text;
+      png_charp key;
+
+      if (png_ptr->buffer_size < 4)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_push_crc_finish(png_ptr);
+
+#if defined(PNG_MAX_MALLOC_64K)
+      if (png_ptr->skip_length)
+         return;
+#endif
+
+      key = png_ptr->current_text;
+      png_ptr->current_text = 0;
+
+      for (text = key; *text; text++)
+         /* empty loop */ ;
+
+      if (text != key + png_ptr->current_text_size)
+         text++;
+
+      text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
+      text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
+      text_ptr->key = key;
+      text_ptr->text = text;
+
+      png_set_text(png_ptr, info_ptr, text_ptr, 1);
+
+      png_free(png_ptr, text_ptr);
+   }
+}
+#endif
+
+#if defined(PNG_READ_zTXt_SUPPORTED)
+void
+png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   if (png_ptr->mode == PNG_BEFORE_IHDR || png_ptr->mode & PNG_HAVE_IEND)
+      {
+         png_error(png_ptr, "Out of place zTXt");
+         /* to quiet some compiler warnings */
+         if(info_ptr == NULL) return;
+      }
+
+#ifdef PNG_MAX_MALLOC_64K
+   /* We can't handle zTXt chunks > 64K, since we don't have enough space
+    * to be able to store the uncompressed data.  Actually, the threshold
+    * is probably around 32K, but it isn't as definite as 64K is.
+    */
+   if (length > (png_uint_32)65535L)
+   {
+      png_warning(png_ptr, "zTXt chunk too large to fit in memory");
+      png_push_crc_skip(png_ptr, length);
+      return;
+   }
+#endif
+
+   png_ptr->current_text = (png_charp)png_malloc(png_ptr,
+       (png_uint_32)(length+1));
+   png_ptr->current_text[length] = '\0';
+   png_ptr->current_text_ptr = png_ptr->current_text;
+   png_ptr->current_text_size = (png_size_t)length;
+   png_ptr->current_text_left = (png_size_t)length;
+   png_ptr->process_mode = PNG_READ_zTXt_MODE;
+}
+
+void
+png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr->buffer_size && png_ptr->current_text_left)
+   {
+      png_size_t text_size;
+
+      if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
+         text_size = png_ptr->buffer_size;
+      else
+         text_size = png_ptr->current_text_left;
+      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
+      png_ptr->current_text_left -= text_size;
+      png_ptr->current_text_ptr += text_size;
+   }
+   if (!(png_ptr->current_text_left))
+   {
+      png_textp text_ptr;
+      png_charp text;
+      png_charp key;
+      int ret;
+      png_size_t text_size, key_size;
+
+      if (png_ptr->buffer_size < 4)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_push_crc_finish(png_ptr);
+
+      key = png_ptr->current_text;
+      png_ptr->current_text = 0;
+
+      for (text = key; *text; text++)
+         /* empty loop */ ;
+
+      /* zTXt can't have zero text */
+      if (text == key + png_ptr->current_text_size)
+      {
+         png_free(png_ptr, key);
+         return;
+      }
+
+      text++;
+
+      if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */
+      {
+         png_free(png_ptr, key);
+         return;
+      }
+
+      text++;
+
+      png_ptr->zstream.next_in = (png_bytep )text;
+      png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
+         (text - key));
+      png_ptr->zstream.next_out = png_ptr->zbuf;
+      png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+      key_size = text - key;
+      text_size = 0;
+      text = NULL;
+      ret = Z_STREAM_END;
+
+      while (png_ptr->zstream.avail_in)
+      {
+         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+         if (ret != Z_OK && ret != Z_STREAM_END)
+         {
+            inflateReset(&png_ptr->zstream);
+            png_ptr->zstream.avail_in = 0;
+            png_free(png_ptr, key);
+            png_free(png_ptr, text);
+            return;
+         }
+         if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
+         {
+            if (text == NULL)
+            {
+               text = (png_charp)png_malloc(png_ptr,
+                  (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out +
+                     key_size + 1));
+               png_memcpy(text + key_size, png_ptr->zbuf,
+                  png_ptr->zbuf_size - png_ptr->zstream.avail_out);
+               png_memcpy(text, key, key_size);
+               text_size = key_size + png_ptr->zbuf_size -
+                  png_ptr->zstream.avail_out;
+               *(text + text_size) = '\0';
+            }
+            else
+            {
+               png_charp tmp;
+
+               tmp = text;
+               text = (png_charp)png_malloc(png_ptr, text_size +
+                  (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
+                   + 1));
+               png_memcpy(text, tmp, text_size);
+               png_free(png_ptr, tmp);
+               png_memcpy(text + text_size, png_ptr->zbuf,
+                  png_ptr->zbuf_size - png_ptr->zstream.avail_out);
+               text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
+               *(text + text_size) = '\0';
+            }
+            if (ret != Z_STREAM_END)
+            {
+               png_ptr->zstream.next_out = png_ptr->zbuf;
+               png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+            }
+         }
+         else
+         {
+            break;
+         }
+
+         if (ret == Z_STREAM_END)
+            break;
+      }
+
+      inflateReset(&png_ptr->zstream);
+      png_ptr->zstream.avail_in = 0;
+
+      if (ret != Z_STREAM_END)
+      {
+         png_free(png_ptr, key);
+         png_free(png_ptr, text);
+         return;
+      }
+
+      png_free(png_ptr, key);
+      key = text;
+      text += key_size;
+
+      text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
+      text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
+      text_ptr->key = key;
+      text_ptr->text = text;
+
+      png_set_text(png_ptr, info_ptr, text_ptr, 1);
+
+      png_free(png_ptr, text_ptr);
+   }
+}
+#endif
+
+/* This function is called when we haven't found a handler for this
+ * chunk.  In the future we will have code here which can handle
+ * user-defined callback functions for unknown chunks before they are
+ * ignored or cause an error.  If there isn't a problem with the
+ * chunk itself (ie a bad chunk name or a critical chunk), the chunk
+ * is (currently) silently ignored.
+ */
+void
+png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_check_chunk_name(png_ptr, png_ptr->chunk_name);
+
+   if (!(png_ptr->chunk_name[0] & 0x20))
+   {
+      png_chunk_error(png_ptr, "unknown critical chunk");
+      /* to quiet some compiler warnings */
+      if(info_ptr == NULL) return;
+   }
+
+   png_push_crc_skip(png_ptr, length);
+}
+
+void
+png_push_have_info(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr->info_fn != NULL)
+      (*(png_ptr->info_fn))(png_ptr, info_ptr);
+}
+
+void
+png_push_have_end(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr->end_fn != NULL)
+      (*(png_ptr->end_fn))(png_ptr, info_ptr);
+}
+
+void
+png_push_have_row(png_structp png_ptr, png_bytep row)
+{
+   if (png_ptr->row_fn != NULL)
+      (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
+         (int)png_ptr->pass);
+}
+
+void
+png_progressive_combine_row (png_structp png_ptr,
+   png_bytep old_row, png_bytep new_row)
+{
+   if (new_row != NULL)
+      png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
+}
+
+void
+png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
+   png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
+   png_progressive_end_ptr end_fn)
+{
+   png_ptr->info_fn = info_fn;
+   png_ptr->row_fn = row_fn;
+   png_ptr->end_fn = end_fn;
+
+   png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
+}
+
+png_voidp
+png_get_progressive_ptr(png_structp png_ptr)
+{
+   return png_ptr->io_ptr;
+}
+
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
diff --git a/src/png/pngread.c b/src/png/pngread.c
new file mode 100644
index 0000000000..1618b73095
--- /dev/null
+++ b/src/png/pngread.c
@@ -0,0 +1,787 @@
+
+/* pngread.c - read a PNG file
+ *
+ * libpng 1.0.1
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Copyright (c) 1998, Glenn Randers-Pehrson
+ * March 15, 1998
+ *
+ * This file contains routines that an application calls directly to
+ * read a PNG file or stream.
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+/* Create a PNG structure for reading, and allocate any memory needed. */
+png_structp
+png_create_read_struct(png_const_charp user_png_ver, voidp error_ptr,
+   png_error_ptr error_fn, png_error_ptr warn_fn)
+{
+   png_structp png_ptr;
+#ifdef USE_FAR_KEYWORD
+   jmp_buf jmpbuf;
+#endif
+   png_debug(1, "in png_create_read_struct\n");
+   if ((png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG)) == NULL)
+   {
+      return (png_structp)NULL;
+   }
+#ifdef USE_FAR_KEYWORD
+   if (setjmp(jmpbuf))
+#else
+   if (setjmp(png_ptr->jmpbuf))
+#endif
+   {
+      png_free(png_ptr, png_ptr->zbuf);
+      png_destroy_struct(png_ptr);
+      return (png_structp)NULL;
+   }
+#ifdef USE_FAR_KEYWORD
+   png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
+#endif
+   png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
+
+   /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
+    * we must recompile any applications that use any older library version.
+    * For versions after libpng 1.0, we will be compatible, so we need
+    * only check the first digit.
+    */
+   if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
+       (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
+   {
+      png_error(png_ptr,
+         "Incompatible libpng version in application and library");
+   }
+
+   /* initialize zbuf - compression buffer */
+   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
+   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
+     (png_uint_32)png_ptr->zbuf_size);
+   png_ptr->zstream.zalloc = png_zalloc;
+   png_ptr->zstream.zfree = png_zfree;
+   png_ptr->zstream.opaque = (voidpf)png_ptr;
+
+   switch (inflateInit(&png_ptr->zstream))
+   {
+     case Z_OK: /* Do nothing */ break;
+     case Z_MEM_ERROR:
+     case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error"); break;
+     case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error"); break;
+     default: png_error(png_ptr, "Unknown zlib error");
+   }
+
+   png_ptr->zstream.next_out = png_ptr->zbuf;
+   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+   png_set_read_fn(png_ptr, NULL, NULL);
+
+   return (png_ptr);
+}
+
+/* Initialize PNG structure for reading, and allocate any memory needed.
+   This interface is depreciated in favour of the png_create_read_struct(),
+   and it will eventually disappear. */
+void
+png_read_init(png_structp png_ptr)
+{
+   jmp_buf tmp_jmp;  /* to save current jump buffer */
+
+   png_debug(1, "in png_read_init\n");
+   /* save jump buffer and error functions */
+   png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
+
+   /* reset all variables to 0 */
+   png_memset(png_ptr, 0, sizeof (png_struct));
+
+   /* restore jump buffer */
+   png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
+
+   /* initialize zbuf - compression buffer */
+   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
+   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
+     (png_uint_32)png_ptr->zbuf_size);
+   png_ptr->zstream.zalloc = png_zalloc;
+   png_ptr->zstream.zfree = png_zfree;
+   png_ptr->zstream.opaque = (voidpf)png_ptr;
+
+   switch (inflateInit(&png_ptr->zstream))
+   {
+     case Z_OK: /* Do nothing */ break;
+     case Z_MEM_ERROR:
+     case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory"); break;
+     case Z_VERSION_ERROR: png_error(png_ptr, "zlib version"); break;
+     default: png_error(png_ptr, "Unknown zlib error");
+   }
+
+   png_ptr->zstream.next_out = png_ptr->zbuf;
+   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+   png_set_read_fn(png_ptr, NULL, NULL);
+}
+
+/* Read the information before the actual image data.  This has been
+ * changed in v0.90 to allow reading a file that already has the magic
+ * bytes read from the stream.  You can tell libpng how many bytes have
+ * been read from the beginning of the stream (up to the maxumum of 8)
+ * via png_set_sig_bytes(), and we will only check the remaining bytes
+ * here.  The application can then have access to the signature bytes we
+ * read if it is determined that this isn't a valid PNG file.
+ */
+void
+png_read_info(png_structp png_ptr, png_infop info_ptr)
+{
+   png_debug(1, "in png_read_info\n");
+   /* save jump buffer and error functions */
+   /* If we haven't checked all of the PNG signature bytes, do so now. */
+   if (png_ptr->sig_bytes < 8)
+   {
+      png_size_t num_checked = png_ptr->sig_bytes,
+                 num_to_check = 8 - num_checked;
+
+      png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
+      png_ptr->sig_bytes = 8;
+
+      if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
+      {
+         if (num_checked < 4 &&
+             png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
+            png_error(png_ptr, "Not a PNG file");
+         else
+            png_error(png_ptr, "PNG file corrupted by ASCII conversion");
+      }
+   }
+
+   for(;;)
+   {
+      png_byte chunk_length[4];
+      png_uint_32 length;
+
+      png_read_data(png_ptr, chunk_length, 4);
+      length = png_get_uint_32(chunk_length);
+
+      png_reset_crc(png_ptr);
+      png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+
+      png_debug1(0, "Reading %s chunk.\n", png_ptr->chunk_name);
+
+      /* This should be a binary subdivision search or a hash for
+       * matching the chunk name rather than a linear search.
+       */
+      if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
+         png_handle_IHDR(png_ptr, info_ptr, length);
+      else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+         png_handle_PLTE(png_ptr, info_ptr, length);
+      else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
+         png_handle_IEND(png_ptr, info_ptr, length);
+      else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+      {
+         if (!(png_ptr->mode & PNG_HAVE_IHDR))
+            png_error(png_ptr, "Missing IHDR before IDAT");
+         else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+                  !(png_ptr->mode & PNG_HAVE_PLTE))
+            png_error(png_ptr, "Missing PLTE before IDAT");
+
+         png_ptr->idat_size = length;
+         png_ptr->mode |= PNG_HAVE_IDAT;
+         break;
+      }
+#if defined(PNG_READ_bKGD_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
+         png_handle_bKGD(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
+         png_handle_cHRM(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_gAMA_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
+         png_handle_gAMA(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
+         png_handle_hIST(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
+         png_handle_oFFs(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
+         png_handle_pCAL(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
+         png_handle_pHYs(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
+         png_handle_sBIT(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
+         png_handle_sRGB(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
+         png_handle_tEXt(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
+         png_handle_tIME(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
+         png_handle_tRNS(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
+         png_handle_zTXt(png_ptr, info_ptr, length);
+#endif
+      else
+         png_handle_unknown(png_ptr, info_ptr, length);
+   }
+}
+
+/* optional call to update the users info_ptr structure */
+void
+png_read_update_info(png_structp png_ptr, png_infop info_ptr)
+{
+   png_debug(1, "in png_read_update_info\n");
+   /* save jump buffer and error functions */
+   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
+      png_read_start_row(png_ptr);
+   png_read_transform_info(png_ptr, info_ptr);
+}
+
+/* Initialize palette, background, etc, after transformations
+ * are set, but before any reading takes place.  This allows
+ * the user to obtail a gamma corrected palette, for example.
+ * If the user doesn't call this, we will do it ourselves.
+ */
+void
+png_start_read_image(png_structp png_ptr)
+{
+   png_debug(1, "in png_start_read_image\n");
+   /* save jump buffer and error functions */
+   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
+      png_read_start_row(png_ptr);
+}
+
+void
+png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
+{
+   int ret;
+   png_debug2(1, "in png_read_row (row %d, pass %d)\n",
+      png_ptr->row_number, png_ptr->pass);
+   /* save jump buffer and error functions */
+   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
+      png_read_start_row(png_ptr);
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED)
+   /* if interlaced and we do not need a new row, combine row and return */
+   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
+   {
+      switch (png_ptr->pass)
+      {
+         case 0:
+            if (png_ptr->row_number & 7)
+            {
+               if (dsp_row != NULL)
+                  png_combine_row(png_ptr, dsp_row,
+                     png_pass_dsp_mask[png_ptr->pass]);
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 1:
+            if ((png_ptr->row_number & 7) || png_ptr->width < 5)
+            {
+               if (dsp_row != NULL)
+                  png_combine_row(png_ptr, dsp_row,
+                     png_pass_dsp_mask[png_ptr->pass]);
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 2:
+            if ((png_ptr->row_number & 7) != 4)
+            {
+               if (dsp_row != NULL && (png_ptr->row_number & 4))
+                  png_combine_row(png_ptr, dsp_row,
+                     png_pass_dsp_mask[png_ptr->pass]);
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 3:
+            if ((png_ptr->row_number & 3) || png_ptr->width < 3)
+            {
+               if (dsp_row != NULL)
+                  png_combine_row(png_ptr, dsp_row,
+                     png_pass_dsp_mask[png_ptr->pass]);
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 4:
+            if ((png_ptr->row_number & 3) != 2)
+            {
+               if (dsp_row != NULL && (png_ptr->row_number & 2))
+                  png_combine_row(png_ptr, dsp_row,
+                     png_pass_dsp_mask[png_ptr->pass]);
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 5:
+            if ((png_ptr->row_number & 1) || png_ptr->width < 2)
+            {
+               if (dsp_row != NULL)
+                  png_combine_row(png_ptr, dsp_row,
+                     png_pass_dsp_mask[png_ptr->pass]);
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 6:
+            if (!(png_ptr->row_number & 1))
+            {
+               png_read_finish_row(png_ptr);
+               return;
+            }
+            break;
+      }
+   }
+#endif
+
+   if (!(png_ptr->mode & PNG_HAVE_IDAT))
+      png_error(png_ptr, "Invalid attempt to read row data");
+
+   png_ptr->zstream.next_out = png_ptr->row_buf;
+   png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
+   do
+   {
+      if (!(png_ptr->zstream.avail_in))
+      {
+         while (!png_ptr->idat_size)
+         {
+            png_byte chunk_length[4];
+
+            png_crc_finish(png_ptr, 0);
+
+            png_read_data(png_ptr, chunk_length, 4);
+            png_ptr->idat_size = png_get_uint_32(chunk_length);
+
+            png_reset_crc(png_ptr);
+            png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+            if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+               png_error(png_ptr, "Not enough image data");
+         }
+         png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
+         png_ptr->zstream.next_in = png_ptr->zbuf;
+         if (png_ptr->zbuf_size > png_ptr->idat_size)
+            png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
+         png_crc_read(png_ptr, png_ptr->zbuf,
+            (png_size_t)png_ptr->zstream.avail_in);
+         png_ptr->idat_size -= png_ptr->zstream.avail_in;
+      }
+      ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+      if (ret == Z_STREAM_END)
+      {
+         if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
+            png_ptr->idat_size)
+            png_error(png_ptr, "Extra compressed data");
+         png_ptr->mode |= PNG_AFTER_IDAT;
+         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+         break;
+      }
+      if (ret != Z_OK)
+         png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
+                   "Decompression error");
+
+   } while (png_ptr->zstream.avail_out);
+
+   png_ptr->row_info.color_type = png_ptr->color_type;
+   png_ptr->row_info.width = png_ptr->iwidth;
+   png_ptr->row_info.channels = png_ptr->channels;
+   png_ptr->row_info.bit_depth = png_ptr->bit_depth;
+   png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
+   {
+      png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
+         (png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
+   }
+
+   png_read_filter_row(png_ptr, &(png_ptr->row_info),
+      png_ptr->row_buf + 1, png_ptr->prev_row + 1,
+      (int)(png_ptr->row_buf[0]));
+
+   png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
+      png_ptr->rowbytes + 1);
+
+   if (png_ptr->transformations)
+      png_do_read_transformations(png_ptr);
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED)
+   /* blow up interlaced rows to full size */
+   if (png_ptr->interlaced &&
+      (png_ptr->transformations & PNG_INTERLACE))
+   {
+      if (png_ptr->pass < 6)
+         png_do_read_interlace(&(png_ptr->row_info),
+            png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
+
+      if (dsp_row != NULL)
+         png_combine_row(png_ptr, dsp_row,
+            png_pass_dsp_mask[png_ptr->pass]);
+      if (row != NULL)
+         png_combine_row(png_ptr, row,
+            png_pass_mask[png_ptr->pass]);
+   }
+   else
+#endif
+   {
+      if (row != NULL)
+         png_combine_row(png_ptr, row, 0xff);
+      if (dsp_row != NULL)
+         png_combine_row(png_ptr, dsp_row, 0xff);
+   }
+   png_read_finish_row(png_ptr);
+
+   if (png_ptr->read_row_fn != NULL)
+      (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
+}
+
+/* Read one or more rows of image data.  If the image is interlaced,
+ * and png_set_interlace_handling() has been called, the rows need to
+ * contain the contents of the rows from the previous pass.  If the
+ * image has alpha or transparency, and png_handle_alpha() has been
+ * called, the rows contents must be initialized to the contents of the
+ * screen.
+ * 
+ * "row" holds the actual image, and pixels are placed in it
+ * as they arrive.  If the image is displayed after each pass, it will
+ * appear to "sparkle" in.  "display_row" can be used to display a
+ * "chunky" progressive image, with finer detail added as it becomes
+ * available.  If you do not want this "chunky" display, you may pass
+ * NULL for display_row.  If you do not want the sparkle display, and
+ * you have not called png_handle_alpha(), you may pass NULL for rows.
+ * If you have called png_handle_alpha(), and the image has either an
+ * alpha channel or a transparency chunk, you must provide a buffer for
+ * rows.  In this case, you do not have to provide a display_row buffer
+ * also, but you may.  If the image is not interlaced, or if you have
+ * not called png_set_interlace_handling(), the display_row buffer will
+ * be ignored, so pass NULL to it.
+ */
+
+void
+png_read_rows(png_structp png_ptr, png_bytepp row,
+   png_bytepp display_row, png_uint_32 num_rows)
+{
+   png_uint_32 i;
+   png_bytepp rp;
+   png_bytepp dp;
+
+   png_debug(1, "in png_read_rows\n");
+   /* save jump buffer and error functions */
+   rp = row;
+   dp = display_row;
+   for (i = 0; i < num_rows; i++)
+   {
+      png_bytep rptr;
+      png_bytep dptr;
+
+      if (rp != NULL)
+         rptr = *rp;
+      else
+         rptr = NULL;
+      if (dp != NULL)
+         dptr = *dp;
+      else
+         dptr = NULL;
+      png_read_row(png_ptr, rptr, dptr);
+      if (row != NULL)
+         rp++;
+      if (display_row != NULL)
+         dp++;
+   }
+}
+
+/* Read the entire image.  If the image has an alpha channel or a tRNS
+ * chunk, and you have called png_handle_alpha(), you will need to
+ * initialize the image to the current image that PNG will be overlaying.
+ * We set the num_rows again here, in case it was incorrectly set in
+ * png_read_start_row() by a call to png_read_update_info() or
+ * png_start_read_image() if png_set_interlace_handling() wasn't called
+ * prior to either of these functions like it should have been.  You can
+ * only call this function once.  If you desire to have an image for
+ * each pass of a interlaced image, use png_read_rows() instead.
+ */
+void
+png_read_image(png_structp png_ptr, png_bytepp image)
+{
+   png_uint_32 i;
+   int pass, j;
+   png_bytepp rp;
+
+   png_debug(1, "in png_read_image\n");
+   /* save jump buffer and error functions */
+   pass = png_set_interlace_handling(png_ptr);
+
+   png_ptr->num_rows = png_ptr->height; /* Make sure this is set correctly */
+
+   for (j = 0; j < pass; j++)
+   {
+      rp = image;
+      for (i = 0; i < png_ptr->height; i++)
+      {
+         png_read_row(png_ptr, *rp, NULL);
+         rp++;
+      }
+   }
+}
+
+/* Read the end of the PNG file.  Will not read past the end of the
+ * file, will verify the end is accurate, and will read any comments
+ * or time information at the end of the file, if info is not NULL.
+ */
+void
+png_read_end(png_structp png_ptr, png_infop info_ptr)
+{
+   png_byte chunk_length[4];
+   png_uint_32 length;
+
+   png_debug(1, "in png_read_end\n");
+   /* save jump buffer and error functions */
+   png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
+
+   do
+   {
+      png_read_data(png_ptr, chunk_length, 4);
+      length = png_get_uint_32(chunk_length);
+
+      png_reset_crc(png_ptr);
+      png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+
+      png_debug1(0, "Reading %s chunk.\n", png_ptr->chunk_name);
+
+      if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
+         png_handle_IHDR(png_ptr, info_ptr, length);
+      else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+      {
+         /* Zero length IDATs are legal after the last IDAT has been
+          * read, but not after other chunks have been read.
+          */
+         if (length > 0 || png_ptr->mode & PNG_AFTER_IDAT)
+            png_error(png_ptr, "Too many IDAT's found");
+         else
+            png_crc_finish(png_ptr, 0);
+      }
+      else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+         png_handle_PLTE(png_ptr, info_ptr, length);
+      else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
+         png_handle_IEND(png_ptr, info_ptr, length);
+#if defined(PNG_READ_bKGD_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
+         png_handle_bKGD(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
+         png_handle_cHRM(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_gAMA_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
+         png_handle_gAMA(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
+         png_handle_hIST(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
+         png_handle_oFFs(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
+         png_handle_pCAL(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
+         png_handle_pHYs(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
+         png_handle_sBIT(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
+         png_handle_sRGB(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
+         png_handle_tEXt(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
+         png_handle_tIME(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
+         png_handle_tRNS(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
+         png_handle_zTXt(png_ptr, info_ptr, length);
+#endif
+      else
+         png_handle_unknown(png_ptr, info_ptr, length);
+   } while (!(png_ptr->mode & PNG_HAVE_IEND));
+}
+
+/* free all memory used by the read */
+void
+png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
+   png_infopp end_info_ptr_ptr)
+{
+   png_structp png_ptr = NULL;
+   png_infop info_ptr = NULL, end_info_ptr = NULL;
+
+   png_debug(1, "in png_destroy_read_struct\n");
+   /* save jump buffer and error functions */
+   if (png_ptr_ptr != NULL)
+      png_ptr = *png_ptr_ptr;
+
+   if (info_ptr_ptr != NULL)
+      info_ptr = *info_ptr_ptr;
+
+   if (end_info_ptr_ptr != NULL)
+      end_info_ptr = *end_info_ptr_ptr;
+
+   png_read_destroy(png_ptr, info_ptr, end_info_ptr);
+
+   if (info_ptr != NULL)
+   {
+#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
+      png_free(png_ptr, info_ptr->text);
+#endif
+      png_destroy_struct((png_voidp)info_ptr);
+      *info_ptr_ptr = (png_infop)NULL;
+   }
+
+   if (end_info_ptr != NULL)
+   {
+#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
+      png_free(png_ptr, end_info_ptr->text);
+#endif
+      png_destroy_struct((png_voidp)end_info_ptr);
+      *end_info_ptr_ptr = (png_infop)NULL;
+   }
+
+   if (png_ptr != NULL)
+   {
+      png_destroy_struct((png_voidp)png_ptr);
+      *png_ptr_ptr = (png_structp)NULL;
+   }
+}
+
+/* free all memory used by the read (old method) */
+void
+png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr)
+{
+   jmp_buf tmp_jmp;
+   png_error_ptr error_fn;
+   png_error_ptr warning_fn;
+   png_voidp error_ptr;
+
+   png_debug(1, "in png_read_destroy\n");
+   /* save jump buffer and error functions */
+   if (info_ptr != NULL)
+      png_info_destroy(png_ptr, info_ptr);
+
+   if (end_info_ptr != NULL)
+      png_info_destroy(png_ptr, end_info_ptr);
+
+   png_free(png_ptr, png_ptr->zbuf);
+   png_free(png_ptr, png_ptr->row_buf);
+   png_free(png_ptr, png_ptr->prev_row);
+#if defined(PNG_READ_DITHER_SUPPORTED)
+   png_free(png_ptr, png_ptr->palette_lookup);
+   png_free(png_ptr, png_ptr->dither_index);
+#endif
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+   png_free(png_ptr, png_ptr->gamma_table);
+#endif
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+   png_free(png_ptr, png_ptr->gamma_from_1);
+   png_free(png_ptr, png_ptr->gamma_to_1);
+#endif
+   if (png_ptr->flags & PNG_FLAG_FREE_PALETTE)
+      png_zfree(png_ptr, png_ptr->palette);
+   if (png_ptr->flags & PNG_FLAG_FREE_TRANS)
+      png_free(png_ptr, png_ptr->trans);
+#if defined(PNG_READ_hIST_SUPPORTED)
+   if (png_ptr->flags & PNG_FLAG_FREE_HIST)
+      png_free(png_ptr, png_ptr->hist);
+#endif
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+   if (png_ptr->gamma_16_table != NULL)
+   {
+      int i;
+      for (i = 0; i < (1 << (8 - png_ptr->gamma_shift)); i++)
+      {
+         png_free(png_ptr, png_ptr->gamma_16_table[i]);
+      }
+   }
+#endif
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+   png_free(png_ptr, png_ptr->gamma_16_table);
+   if (png_ptr->gamma_16_from_1 != NULL)
+   {
+      int i;
+      for (i = 0; i < (1 << (8 - png_ptr->gamma_shift)); i++)
+      {
+         png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
+      }
+   }
+   png_free(png_ptr, png_ptr->gamma_16_from_1);
+   if (png_ptr->gamma_16_to_1 != NULL)
+   {
+      int i;
+      for (i = 0; i < (1 << (8 - png_ptr->gamma_shift)); i++)
+      {
+         png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
+      }
+   }
+   png_free(png_ptr, png_ptr->gamma_16_to_1);
+#endif
+
+   inflateEnd(&png_ptr->zstream);
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+   png_free(png_ptr, png_ptr->save_buffer);
+#endif
+
+   /* Save the important info out of the png_struct, in case it is
+    * being used again.
+    */
+   png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
+
+   error_fn = png_ptr->error_fn;
+   warning_fn = png_ptr->warning_fn;
+   error_ptr = png_ptr->error_ptr;
+
+   png_memset(png_ptr, 0, sizeof (png_struct));
+
+   png_ptr->error_fn = error_fn;
+   png_ptr->warning_fn = warning_fn;
+   png_ptr->error_ptr = error_ptr;
+
+   png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
+}
+
+void
+png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
+{
+   png_ptr->read_row_fn = read_row_fn;
+}
diff --git a/src/png/pngrio.c b/src/png/pngrio.c
new file mode 100644
index 0000000000..7adb48f54c
--- /dev/null
+++ b/src/png/pngrio.c
@@ -0,0 +1,145 @@
+
+/* pngrio.c - functions for data input
+ *
+ * libpng 1.0.1
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Copyright (c) 1998, Glenn Randers-Pehrson
+ * March 15, 1998
+ *
+ * This file provides a location for all input.  Users which need
+ * special handling are expected to write a function which has the same
+ * arguments as this, and perform a similar function, but possibly has
+ * a different input method.  Note that you shouldn't change this
+ * function, but rather write a replacement function and then make
+ * libpng use it at run time with png_set_read_fn(...).
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+/* Read the data from whatever input you are using.  The default routine
+   reads from a file pointer.  Note that this routine sometimes gets called
+   with very small lengths, so you should implement some kind of simple
+   buffering if you are using unbuffered reads.  This should never be asked
+   to read more then 64K on a 16 bit machine. */
+void
+png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   png_debug1(4,"reading %d bytes\n", length);
+   if (png_ptr->read_data_fn != NULL)
+      (*(png_ptr->read_data_fn))(png_ptr, data, length);
+   else
+      png_error(png_ptr, "Call to NULL read function");
+}
+
+#if !defined(PNG_NO_STDIO)
+/* This is the function which does the actual reading of data.  If you are
+   not reading from a standard C stream, you should create a replacement
+   read_data function and use it at run time with png_set_read_fn(), rather
+   than changing the library. */
+#ifndef USE_FAR_KEYWORD
+static void
+png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   png_size_t check;
+
+   /* fread() returns 0 on error, so it is OK to store this in a png_size_t
+    * instead of an int, which is what fread() actually returns.
+    */
+   check = (png_size_t)fread(data, (png_size_t)1, length,
+      (FILE *)png_ptr->io_ptr);
+
+   if (check != length)
+   {
+      png_error(png_ptr, "Read Error");
+   }
+}
+#else
+/* this is the model-independent version. Since the standard I/O library
+   can't handle far buffers in the medium and small models, we have to copy
+   the data.
+*/
+ 
+#define NEAR_BUF_SIZE 1024
+#define MIN(a,b) (a <= b ? a : b)
+ 
+static void
+png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   int check;
+   png_byte *n_data;
+   FILE *io_ptr;
+
+   /* Check if data really is near. If so, use usual code. */
+   n_data = (png_byte *)CVT_PTR_NOCHECK(data);
+   io_ptr = (FILE *)CVT_PTR(png_ptr->io_ptr);
+   if ((png_bytep)n_data == data)
+   {
+      check = fread(n_data, 1, length, io_ptr);
+   }
+   else
+   {
+      png_byte buf[NEAR_BUF_SIZE];
+      png_size_t read, remaining, err;
+      check = 0;
+      remaining = length;
+      do
+      {
+         read = MIN(NEAR_BUF_SIZE, remaining);
+         err = fread(buf, (png_size_t)1, read, io_ptr);
+         png_memcpy(data, buf, read); /* copy far buffer to near buffer */
+         if(err != read)
+            break;
+         else
+            check += err;
+         data += read;
+         remaining -= read;
+      }
+      while (remaining != 0);
+   }
+   if ((png_uint_32)check != (png_uint_32)length)
+   {
+      png_error(png_ptr, "read Error");
+   }
+}
+#endif
+#endif
+
+/* This function allows the application to supply a new input function
+   for libpng if standard C streams aren't being used.
+
+   This function takes as its arguments:
+   png_ptr      - pointer to a png input data structure
+   io_ptr       - pointer to user supplied structure containing info about
+                  the input functions.  May be NULL.
+   read_data_fn - pointer to a new input function which takes as it's
+                  arguments a pointer to a png_struct, a pointer to
+                  a location where input data can be stored, and a 32-bit
+                  unsigned int which is the number of bytes to be read.
+                  To exit and output any fatal error messages the new write
+                  function should call png_error(png_ptr, "Error msg"). */
+void
+png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
+   png_rw_ptr read_data_fn)
+{
+   png_ptr->io_ptr = io_ptr;
+
+#if !defined(PNG_NO_STDIO)
+   if (read_data_fn != NULL)
+      png_ptr->read_data_fn = read_data_fn;
+   else
+      png_ptr->read_data_fn = png_default_read_data;
+#else
+   png_ptr->read_data_fn = read_data_fn;
+#endif
+
+   /* It is an error to write to a read device */
+   png_ptr->write_data_fn = NULL;
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+   png_ptr->output_flush_fn = NULL;
+#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+}
+
diff --git a/src/png/pngrtran.c b/src/png/pngrtran.c
new file mode 100644
index 0000000000..885af53905
--- /dev/null
+++ b/src/png/pngrtran.c
@@ -0,0 +1,3409 @@
+
+/* pngrtran.c - transforms the data in a row for PNG readers
+ *
+ * libpng 1.0.1
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Copyright (c) 1998, Glenn Randers-Pehrson
+ * March 15, 1998
+ *
+ * This file contains functions optionally called by an application 
+ * in order to tell libpng how to handle data when reading a PNG.
+ * Transformations which are used in both reading and writing are
+ * in pngtrans.c.
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED
+/* With these routines, we avoid an integer divide, which will be slower on
+ * many machines.  However, it does take more operations than the corresponding
+ * divide method, so it may be slower on some RISC systems.  There are two
+ * shifts (by 8 or 16 bits) and an addition, versus a single integer divide.
+ *
+ * Note that the rounding factors are NOT supposed to be the same!  128 and
+ * 32768 are correct for the NODIV code; 127 and 32767 are correct for the
+ * standard method.
+ *
+ * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ]
+ */
+
+   /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */
+#  define png_composite(composite, fg, alpha, bg) \
+     { png_uint_16 temp = ((png_uint_16)(fg) * (png_uint_16)(alpha) + \
+                        (png_uint_16)(bg)*(png_uint_16)(255 - \
+                        (png_uint_16)(alpha)) + (png_uint_16)128); \
+       (composite) = (png_byte)((temp + (temp >> 8)) >> 8); }
+#  define png_composite_16(composite, fg, alpha, bg) \
+     { png_uint_32 temp = ((png_uint_32)(fg) * (png_uint_32)(alpha) + \
+                        (png_uint_32)(bg)*(png_uint_32)(65535L - \
+                        (png_uint_32)(alpha)) + (png_uint_32)32768L); \
+       (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); }
+
+#else  /* standard method using integer division */
+
+   /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */
+#  define png_composite(composite, fg, alpha, bg) \
+     (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \
+       (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
+       (png_uint_16)127) / 255)
+#  define png_composite_16(composite, fg, alpha, bg) \
+     (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \
+       (png_uint_32)(bg)*(png_uint_32)(65535L - (png_uint_32)(alpha)) + \
+       (png_uint_32)32767) / (png_uint_32)65535L)
+
+#endif /* ?PNG_READ_COMPOSITE_NODIV_SUPPORTED */
+
+
+/* Set the action on getting a CRC error for an ancillary or critical chunk. */
+void
+png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)
+{
+   png_debug(1, "in png_set_crc_action\n");
+   /* Tell libpng how we react to CRC errors in critical chunks */
+   switch (crit_action)
+   {
+      case PNG_CRC_NO_CHANGE:                        /* leave setting as is */
+         break;
+      case PNG_CRC_WARN_USE:                               /* warn/use data */
+         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
+         break;
+      case PNG_CRC_QUIET_USE:                             /* quiet/use data */
+         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
+                           PNG_FLAG_CRC_CRITICAL_IGNORE;
+         break;
+      case PNG_CRC_WARN_DISCARD:    /* not a valid action for critical data */
+         png_warning(png_ptr, "Can't discard critical data on CRC error.");
+      case PNG_CRC_ERROR_QUIT:                                /* error/quit */
+      case PNG_CRC_DEFAULT:
+      default:
+         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+         break;
+   }
+
+   switch (ancil_action)
+   {
+      case PNG_CRC_NO_CHANGE:                       /* leave setting as is */
+         break;
+      case PNG_CRC_WARN_USE:                              /* warn/use data */
+         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
+         break;
+      case PNG_CRC_QUIET_USE:                            /* quiet/use data */
+         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
+                           PNG_FLAG_CRC_ANCILLARY_NOWARN;
+         break;
+      case PNG_CRC_ERROR_QUIT:                               /* error/quit */
+         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
+         break;
+      case PNG_CRC_WARN_DISCARD:                      /* warn/discard data */
+      case PNG_CRC_DEFAULT:
+      default:
+         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+         break;
+   }
+}
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+/* handle alpha and tRNS via a background color */
+void
+png_set_background(png_structp png_ptr,
+   png_color_16p background_color, int background_gamma_code,
+   int need_expand, double background_gamma)
+{
+   png_debug(1, "in png_set_background\n");
+   if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
+   {
+      png_warning(png_ptr, "Application must supply a known background gamma");
+      return;
+   }
+
+   png_ptr->transformations |= PNG_BACKGROUND;
+   png_memcpy(&(png_ptr->background), background_color,
+      sizeof(png_color_16));
+   png_ptr->background_gamma = (float)background_gamma;
+   png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
+   png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0);
+}
+#endif
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+/* strip 16 bit depth files to 8 bit depth */
+void
+png_set_strip_16(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_strip_16\n");
+   png_ptr->transformations |= PNG_16_TO_8;
+}
+#endif
+
+#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+void
+png_set_strip_alpha(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_strip_alpha\n");
+   png_ptr->transformations |= PNG_STRIP_ALPHA;
+}
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+/* Dither file to 8 bit.  Supply a palette, the current number
+ * of elements in the palette, the maximum number of elements
+ * allowed, and a histogram if possible.  If the current number
+ * of colors is greater then the maximum number, the palette will be
+ * modified to fit in the maximum number.  "full_dither" indicates
+ * whether we need a dithering cube set up for RGB images, or if we
+ * simply are reducing the number of colors in a paletted image.
+ */
+
+typedef struct png_dsort_struct
+{
+   struct png_dsort_struct FAR * next;
+   png_byte left;
+   png_byte right;
+} png_dsort;
+typedef png_dsort FAR *       png_dsortp;
+typedef png_dsort FAR * FAR * png_dsortpp;
+
+void
+png_set_dither(png_structp png_ptr, png_colorp palette,
+   int num_palette, int maximum_colors, png_uint_16p histogram,
+   int full_dither)
+{
+   png_debug(1, "in png_set_dither\n");
+   png_ptr->transformations |= PNG_DITHER;
+
+   if (!full_dither)
+   {
+      int i;
+
+      png_ptr->dither_index = (png_bytep)png_malloc(png_ptr,
+         (png_uint_32)(num_palette * sizeof (png_byte)));
+      for (i = 0; i < num_palette; i++)
+         png_ptr->dither_index[i] = (png_byte)i;
+   }
+
+   if (num_palette > maximum_colors)
+   {
+      if (histogram != NULL)
+      {
+         /* This is easy enough, just throw out the least used colors.
+            Perhaps not the best solution, but good enough. */
+
+         int i;
+         png_bytep sort;
+
+         /* initialize an array to sort colors */
+         sort = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_palette
+            * sizeof (png_byte)));
+
+         /* initialize the sort array */
+         for (i = 0; i < num_palette; i++)
+            sort[i] = (png_byte)i;
+
+         /* Find the least used palette entries by starting a
+            bubble sort, and running it until we have sorted
+            out enough colors.  Note that we don't care about
+            sorting all the colors, just finding which are
+            least used. */
+
+         for (i = num_palette - 1; i >= maximum_colors; i--)
+         {
+            int done; /* to stop early if the list is pre-sorted */
+            int j;
+
+            done = 1;
+            for (j = 0; j < i; j++)
+            {
+               if (histogram[sort[j]] < histogram[sort[j + 1]])
+               {
+                  png_byte t;
+
+                  t = sort[j];
+                  sort[j] = sort[j + 1];
+                  sort[j + 1] = t;
+                  done = 0;
+               }
+            }
+            if (done)
+               break;
+         }
+
+         /* swap the palette around, and set up a table, if necessary */
+         if (full_dither)
+         {
+            int j;
+
+            /* put all the useful colors within the max, but don't
+               move the others */
+            for (i = 0, j = num_palette; i < maximum_colors; i++)
+            {
+               if ((int)sort[i] >= maximum_colors)
+               {
+                  do
+                     j--;
+                  while ((int)sort[j] >= maximum_colors);
+                  palette[i] = palette[j];
+               }
+            }
+         }
+         else
+         {
+            int j;
+
+            /* move all the used colors inside the max limit, and
+               develop a translation table */
+            for (i = 0, j = num_palette; i < maximum_colors; i++)
+            {
+               /* only move the colors we need to */
+               if ((int)sort[i] >= maximum_colors)
+               {
+                  png_color tmp_color;
+
+                  do
+                     j--;
+                  while ((int)sort[j] >= maximum_colors);
+
+                  tmp_color = palette[j];
+                  palette[j] = palette[i];
+                  palette[i] = tmp_color;
+                  /* indicate where the color went */
+                  png_ptr->dither_index[j] = (png_byte)i;
+                  png_ptr->dither_index[i] = (png_byte)j;
+               }
+            }
+
+            /* find closest color for those colors we are not using */
+            for (i = 0; i < num_palette; i++)
+            {
+               if ((int)png_ptr->dither_index[i] >= maximum_colors)
+               {
+                  int min_d, k, min_k, d_index;
+
+                  /* find the closest color to one we threw out */
+                  d_index = png_ptr->dither_index[i];
+                  min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
+                  for (k = 1, min_k = 0; k < maximum_colors; k++)
+                  {
+                     int d;
+
+                     d = PNG_COLOR_DIST(palette[d_index], palette[k]);
+
+                     if (d < min_d)
+                     {
+                        min_d = d;
+                        min_k = k;
+                     }
+                  }
+                  /* point to closest color */
+                  png_ptr->dither_index[i] = (png_byte)min_k;
+               }
+            }
+         }
+         png_free(png_ptr, sort);
+      }
+      else
+      {
+         /* This is much harder to do simply (and quickly).  Perhaps
+            we need to go through a median cut routine, but those
+            don't always behave themselves with only a few colors
+            as input.  So we will just find the closest two colors,
+            and throw out one of them (chosen somewhat randomly).
+            [I don't understand this at all, so if someone wants to
+             work on improving it, be my guest - AED]
+            */
+         int i;
+         int max_d;
+         int num_new_palette;
+         png_dsortpp hash;
+         png_bytep index_to_palette;
+            /* where the original index currently is in the palette */
+         png_bytep palette_to_index;
+            /* which original index points to this palette color */
+
+         /* initialize palette index arrays */
+         index_to_palette = (png_bytep)png_malloc(png_ptr,
+            (png_uint_32)(num_palette * sizeof (png_byte)));
+         palette_to_index = (png_bytep)png_malloc(png_ptr,
+            (png_uint_32)(num_palette * sizeof (png_byte)));
+
+         /* initialize the sort array */
+         for (i = 0; i < num_palette; i++)
+         {
+            index_to_palette[i] = (png_byte)i;
+            palette_to_index[i] = (png_byte)i;
+         }
+
+         hash = (png_dsortpp)png_malloc(png_ptr, (png_uint_32)(769 * 
+            sizeof (png_dsortp)));
+         for (i = 0; i < 769; i++)
+            hash[i] = NULL;
+/*         png_memset(hash, 0, 769 * sizeof (png_dsortp)); */
+
+         num_new_palette = num_palette;
+
+         /* initial wild guess at how far apart the farthest pixel
+            pair we will be eliminating will be.  Larger
+            numbers mean more areas will be allocated, Smaller
+            numbers run the risk of not saving enough data, and
+            having to do this all over again.
+
+            I have not done extensive checking on this number.
+            */
+         max_d = 96;
+
+         while (num_new_palette > maximum_colors)
+         {
+            for (i = 0; i < num_new_palette - 1; i++)
+            {
+               int j;
+
+               for (j = i + 1; j < num_new_palette; j++)
+               {
+                  int d;
+
+                  d = PNG_COLOR_DIST(palette[i], palette[j]);
+
+                  if (d <= max_d)
+                  {
+                     png_dsortp t;
+
+                     t = (png_dsortp)png_malloc(png_ptr, (png_uint_32)(sizeof
+                         (png_dsort)));
+                     t->next = hash[d];
+                     t->left = (png_byte)i;
+                     t->right = (png_byte)j;
+                     hash[d] = t;
+                  }
+               }
+            }
+
+            for (i = 0; i <= max_d; i++)
+            {
+               if (hash[i] != NULL)
+               {
+                  png_dsortp p;
+
+                  for (p = hash[i]; p; p = p->next)
+                  {
+                     if ((int)index_to_palette[p->left] < num_new_palette &&
+                        (int)index_to_palette[p->right] < num_new_palette)
+                     {
+                        int j, next_j;
+
+                        if (num_new_palette & 1)
+                        {
+                           j = p->left;
+                           next_j = p->right;
+                        }
+                        else
+                        {
+                           j = p->right;
+                           next_j = p->left;
+                        }
+
+                        num_new_palette--;
+                        palette[index_to_palette[j]] = palette[num_new_palette];
+                        if (!full_dither)
+                        {
+                           int k;
+
+                           for (k = 0; k < num_palette; k++)
+                           {
+                              if (png_ptr->dither_index[k] ==
+                                 index_to_palette[j])
+                                 png_ptr->dither_index[k] =
+                                    index_to_palette[next_j];
+                              if ((int)png_ptr->dither_index[k] ==
+                                 num_new_palette)
+                                 png_ptr->dither_index[k] =
+                                    index_to_palette[j];
+                           }
+                        }
+
+                        index_to_palette[palette_to_index[num_new_palette]] =
+                           index_to_palette[j];
+                        palette_to_index[index_to_palette[j]] =
+                           palette_to_index[num_new_palette];
+
+                        index_to_palette[j] = (png_byte)num_new_palette;
+                        palette_to_index[num_new_palette] = (png_byte)j;
+                     }
+                     if (num_new_palette <= maximum_colors)
+                        break;
+                  }
+                  if (num_new_palette <= maximum_colors)
+                     break;
+               }
+            }
+
+            for (i = 0; i < 769; i++)
+            {
+               if (hash[i] != NULL)
+               {
+                  png_dsortp p;
+
+                  p = hash[i];
+                  while (p)
+                  {
+                     png_dsortp t;
+
+                     t = p->next;
+                     png_free(png_ptr, p);
+                     p = t;
+                  }
+               }
+               hash[i] = 0;
+            }
+            max_d += 96;
+         }
+         png_free(png_ptr, hash);
+         png_free(png_ptr, palette_to_index);
+         png_free(png_ptr, index_to_palette);
+      }
+      num_palette = maximum_colors;
+   }
+   if (png_ptr->palette == NULL)
+   {
+      png_ptr->palette = palette;
+   }
+   png_ptr->num_palette = (png_uint_16)num_palette;
+
+   if (full_dither)
+   {
+      int i;
+      int total_bits, num_red, num_green, num_blue;
+      png_size_t num_entries;
+      png_bytep distance;
+
+      total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
+         PNG_DITHER_BLUE_BITS;
+
+      num_red = (1 << PNG_DITHER_RED_BITS);
+      num_green = (1 << PNG_DITHER_GREEN_BITS);
+      num_blue = (1 << PNG_DITHER_BLUE_BITS);
+      num_entries = ((png_size_t)1 << total_bits);
+
+      png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr,
+         (png_uint_32)(num_entries * sizeof (png_byte)));
+
+      png_memset(png_ptr->palette_lookup, 0, num_entries * sizeof (png_byte));
+
+      distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
+         sizeof(png_byte)));
+
+      png_memset(distance, 0xff, num_entries * sizeof(png_byte));
+
+      for (i = 0; i < num_palette; i++)
+      {
+         int r, g, b, ir, ig, ib;
+
+         r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
+         g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
+         b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
+
+         for (ir = 0; ir < num_red; ir++)
+         {
+            int dr, index_r;
+
+            dr = abs(ir - r);
+            index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS));
+            for (ig = 0; ig < num_green; ig++)
+            {
+               int dg, dt, dm, index_g;
+
+               dg = abs(ig - g);
+               dt = dr + dg;
+               dm = ((dr > dg) ? dr : dg);
+               index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
+               for (ib = 0; ib < num_blue; ib++)
+               {
+                  int d_index, db, dmax, d;
+
+                  d_index = index_g | ib;
+                  db = abs(ib - b);
+                  dmax = ((dm > db) ? dm : db);
+                  d = dmax + dt + db;
+
+                  if (d < (int)distance[d_index])
+                  {
+                     distance[d_index] = (png_byte)d;
+                     png_ptr->palette_lookup[d_index] = (png_byte)i;
+                  }
+               }
+            }
+         }
+      }
+
+      png_free(png_ptr, distance);
+   }
+}
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+/* Transform the image from the file_gamma to the screen_gamma.  We
+ * only do transformations on images where the file_gamma and screen_gamma
+ * are not close reciprocals, otherwise it slows things down slightly, and
+ * also needlessly introduces small errors.
+ */
+void
+png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
+{
+   png_debug(1, "in png_set_gamma\n");
+   if (fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD)
+      png_ptr->transformations |= PNG_GAMMA;
+   png_ptr->gamma = (float)file_gamma;
+   png_ptr->screen_gamma = (float)scrn_gamma;
+}
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+/* Expand paletted images to rgb, expand grayscale images of
+ * less then 8 bit depth to 8 bit depth, and expand tRNS chunks
+ * to alpha channels.
+ */
+void
+png_set_expand(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_expand\n");
+   png_ptr->transformations |= PNG_EXPAND;
+}
+#endif
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+void
+png_set_gray_to_rgb(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_gray_to_rgb\n");
+   png_ptr->transformations |= PNG_GRAY_TO_RGB;
+}
+#endif
+
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+/* Convert a RGB image to a grayscale of the given width.  This would
+ * allow us, for example, to convert a 24 bpp RGB image into an 8 or
+ * 16 bpp grayscale image. (Not yet implemented.)
+ */
+void
+png_set_rgb_to_gray(png_structp png_ptr, int gray_bits)
+{
+   png_debug(1, "in png_set_rgb_to_gray\n");
+   png_ptr->transformations |= PNG_RGB_TO_GRAY;
+   /* Need to do something with gray_bits here. */
+   png_warning(png_ptr, "RGB to GRAY transformation is not yet implemented.");
+}
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+void
+png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
+   read_user_transform_fn)
+{
+   png_debug(1, "in png_set_read_user_transform_fn\n");
+   png_ptr->transformations |= PNG_USER_TRANSFORM;
+   png_ptr->read_user_transform_fn = read_user_transform_fn;
+}
+#endif
+
+/* Initialize everything needed for the read.  This includes modifying
+ * the palette.
+ */
+void
+png_init_read_transformations(png_structp png_ptr)
+{
+   int color_type;
+
+   png_debug(1, "in png_init_read_transformations\n");
+   color_type = png_ptr->color_type;
+
+#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
+   if (png_ptr->transformations & PNG_BACKGROUND_EXPAND)
+   {
+      if (color_type == PNG_COLOR_TYPE_GRAY)
+      {
+         /* expand background chunk. */
+         switch (png_ptr->bit_depth)
+         {
+            case 1:
+               png_ptr->background.gray *= (png_uint_16)0xff;
+               png_ptr->background.red = png_ptr->background.green =
+               png_ptr->background.blue = png_ptr->background.gray;
+               break;
+            case 2:
+               png_ptr->background.gray *= (png_uint_16)0x55;
+               png_ptr->background.red = png_ptr->background.green =
+               png_ptr->background.blue = png_ptr->background.gray;
+               break;
+            case 4:
+               png_ptr->background.gray *= (png_uint_16)0x11;
+               png_ptr->background.red = png_ptr->background.green =
+               png_ptr->background.blue = png_ptr->background.gray;
+               break;
+            case 8:
+            case 16:
+               png_ptr->background.red = png_ptr->background.green =
+               png_ptr->background.blue = png_ptr->background.gray;
+               break;
+         }
+      }
+      else if (color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         png_ptr->background.red   =
+            png_ptr->palette[png_ptr->background.index].red;
+         png_ptr->background.green =
+            png_ptr->palette[png_ptr->background.index].green;
+         png_ptr->background.blue  =
+            png_ptr->palette[png_ptr->background.index].blue;
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
+        if (png_ptr->transformations & PNG_INVERT_ALPHA)
+        {
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+           if (!(png_ptr->transformations & PNG_EXPAND))
+#endif
+           {
+           /* invert the alpha channel (in tRNS) unless the pixels are 
+              going to be expanded, in which case leave it for later */
+              int i;
+              for (i=0; i<(int)png_ptr->num_trans; i++)
+                 png_ptr->trans[i] = 255 - png_ptr->trans[i];
+           }
+        }
+#endif
+
+      }
+   }
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+   png_ptr->background_1 = png_ptr->background;
+#endif
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+   if (png_ptr->transformations & PNG_GAMMA)
+   {
+      png_build_gamma_table(png_ptr);
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+      if (png_ptr->transformations & PNG_BACKGROUND)
+      {
+         if (color_type == PNG_COLOR_TYPE_PALETTE)
+         {
+            int num_palette, i;
+            png_color back, back_1;
+            png_colorp palette;
+
+            palette = png_ptr->palette;
+            num_palette = png_ptr->num_palette;
+
+            if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
+            {
+               back.red = png_ptr->gamma_table[png_ptr->background.red];
+               back.green = png_ptr->gamma_table[png_ptr->background.green];
+               back.blue = png_ptr->gamma_table[png_ptr->background.blue];
+
+               back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
+               back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
+               back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
+            }
+            else
+            {
+               double g, gs;
+
+               switch (png_ptr->background_gamma_type)
+               {
+                  case PNG_BACKGROUND_GAMMA_SCREEN:
+                     g = (png_ptr->screen_gamma);
+                     gs = 1.0;
+                     break;
+                  case PNG_BACKGROUND_GAMMA_FILE:
+                     g = 1.0 / (png_ptr->gamma);
+                     gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
+                     break;
+                  case PNG_BACKGROUND_GAMMA_UNIQUE:
+                     g = 1.0 / (png_ptr->background_gamma);
+                     gs = 1.0 / (png_ptr->background_gamma *
+                                 png_ptr->screen_gamma);
+                     break;
+                  default:
+                     g = 1.0;    /* back_1 */
+                     gs = 1.0;   /* back */
+               }
+
+               if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD)
+               {
+                  back.red   = (png_byte)png_ptr->background.red;
+                  back.green = (png_byte)png_ptr->background.green;
+                  back.blue  = (png_byte)png_ptr->background.blue;
+               }
+               else
+               {
+                  back.red = (png_byte)(pow(
+                     (double)png_ptr->background.red/255, gs) * 255.0 + .5);
+                  back.green = (png_byte)(pow(
+                     (double)png_ptr->background.green/255, gs) * 255.0 + .5);
+                  back.blue = (png_byte)(pow(
+                     (double)png_ptr->background.blue/255, gs) * 255.0 + .5);
+               }
+
+               back_1.red = (png_byte)(pow(
+                  (double)png_ptr->background.red/255, g) * 255.0 + .5);
+               back_1.green = (png_byte)(pow(
+                  (double)png_ptr->background.green/255, g) * 255.0 + .5);
+               back_1.blue = (png_byte)(pow(
+                  (double)png_ptr->background.blue/255, g) * 255.0 + .5);
+            }
+
+            for (i = 0; i < num_palette; i++)
+            {
+               if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff)
+               {
+                  if (png_ptr->trans[i] == 0)
+                  {
+                     palette[i] = back;
+                  }
+                  else /* if (png_ptr->trans[i] != 0xff) */
+                  {
+                     png_byte v, w;
+
+                     v = png_ptr->gamma_to_1[palette[i].red];
+                     png_composite(w, v, png_ptr->trans[i], back_1.red);
+                     palette[i].red = png_ptr->gamma_from_1[w];
+
+                     v = png_ptr->gamma_to_1[palette[i].green];
+                     png_composite(w, v, png_ptr->trans[i], back_1.green);
+                     palette[i].green = png_ptr->gamma_from_1[w];
+
+                     v = png_ptr->gamma_to_1[palette[i].blue];
+                     png_composite(w, v, png_ptr->trans[i], back_1.blue);
+                     palette[i].blue = png_ptr->gamma_from_1[w];
+                  }
+               }
+               else
+               {
+                  palette[i].red = png_ptr->gamma_table[palette[i].red];
+                  palette[i].green = png_ptr->gamma_table[palette[i].green];
+                  palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+               }
+            }
+         }
+         /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN)*/
+         else
+         /* color_type != PNG_COLOR_TYPE_PALETTE */
+         {
+            double g, gs, m;
+
+            m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
+            g = 1.0;
+            gs = 1.0;
+
+            switch (png_ptr->background_gamma_type)
+            {
+               case PNG_BACKGROUND_GAMMA_SCREEN:
+                  g = (png_ptr->screen_gamma);
+                  gs = 1.0;
+                  break;
+               case PNG_BACKGROUND_GAMMA_FILE:
+                  g = 1.0 / (png_ptr->gamma);
+                  gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
+                  break;
+               case PNG_BACKGROUND_GAMMA_UNIQUE:
+                  g = 1.0 / (png_ptr->background_gamma);
+                  gs = 1.0 / (png_ptr->background_gamma *
+                     png_ptr->screen_gamma);
+                  break;
+            }
+
+            if (color_type & PNG_COLOR_MASK_COLOR)
+            {
+               /* RGB or RGBA */
+               png_ptr->background_1.red = (png_uint_16)(pow(
+                  (double)png_ptr->background.red / m, g) * m + .5);
+               png_ptr->background_1.green = (png_uint_16)(pow(
+                  (double)png_ptr->background.green / m, g) * m + .5);
+               png_ptr->background_1.blue = (png_uint_16)(pow(
+                  (double)png_ptr->background.blue / m, g) * m + .5);
+               png_ptr->background.red = (png_uint_16)(pow(
+                  (double)png_ptr->background.red / m, gs) * m + .5);
+               png_ptr->background.green = (png_uint_16)(pow(
+                  (double)png_ptr->background.green / m, gs) * m + .5);
+               png_ptr->background.blue = (png_uint_16)(pow(
+                  (double)png_ptr->background.blue / m, gs) * m + .5);
+            }
+            else
+            {
+               /* GRAY or GRAY ALPHA */
+               png_ptr->background_1.gray = (png_uint_16)(pow(
+                  (double)png_ptr->background.gray / m, g) * m + .5);
+               png_ptr->background.gray = (png_uint_16)(pow(
+                  (double)png_ptr->background.gray / m, gs) * m + .5);
+            }
+         }
+      }
+      else
+      /* transformation does not include PNG_BACKGROUND */
+#endif
+      if (color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         int num_palette, i;
+         png_colorp palette;
+
+         palette = png_ptr->palette;
+         num_palette = png_ptr->num_palette;
+
+         for (i = 0; i < num_palette; i++)
+         {
+            palette[i].red = png_ptr->gamma_table[palette[i].red];
+            palette[i].green = png_ptr->gamma_table[palette[i].green];
+            palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+         }
+      }
+   }
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+   else
+#endif
+#endif
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+   /* No GAMMA transformation */
+   if (png_ptr->transformations & PNG_BACKGROUND &&
+       color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      int i;
+      png_color back;
+      png_colorp palette;
+
+      palette = png_ptr->palette;
+      back.red   = (png_byte)png_ptr->background.red;
+      back.green = (png_byte)png_ptr->background.green;
+      back.blue  = (png_byte)png_ptr->background.blue;
+
+      for (i = 0; i < (int)png_ptr->num_trans; i++)
+      {
+         if (png_ptr->trans[i] == 0)
+         {
+            palette[i] = back;
+         }
+         else if (png_ptr->trans[i] != 0xff)
+         {
+            png_composite(palette[i].red, palette[i].red,
+               png_ptr->trans[i], back.red);
+            png_composite(palette[i].green, palette[i].green,
+               png_ptr->trans[i], back.green);
+            png_composite(palette[i].blue, palette[i].blue,
+               png_ptr->trans[i], back.blue);
+         }
+      }
+   }
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED)
+   if ((png_ptr->transformations & PNG_SHIFT) &&
+      color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      png_uint_16 i;
+      int sr, sg, sb;
+
+      sr = 8 - png_ptr->sig_bit.red;
+      if (sr < 0 || sr > 8)
+         sr = 0;
+      sg = 8 - png_ptr->sig_bit.green;
+      if (sg < 0 || sg > 8)
+         sg = 0;
+      sb = 8 - png_ptr->sig_bit.blue;
+      if (sb < 0 || sb > 8)
+         sb = 0;
+      for (i = 0; i < png_ptr->num_palette; i++)
+      {
+         png_ptr->palette[i].red >>= sr;
+         png_ptr->palette[i].green >>= sg;
+         png_ptr->palette[i].blue >>= sb;
+      }
+   }
+#endif
+}
+
+/* Modify the info structure to reflect the transformations.  The
+ * info should be updated so a PNG file could be written with it,
+ * assuming the transformations result in valid PNG data.
+ */
+void
+png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
+{
+   png_debug(1, "in png_read_transform_info\n");
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+   if (png_ptr->transformations & PNG_EXPAND)
+   {
+      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         if (png_ptr->num_trans)
+            info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+         else
+            info_ptr->color_type = PNG_COLOR_TYPE_RGB;
+         info_ptr->bit_depth = 8;
+         info_ptr->num_trans = 0;
+      }
+      else
+      {
+         if (png_ptr->num_trans)
+            info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
+         if (info_ptr->bit_depth < 8)
+            info_ptr->bit_depth = 8;
+         info_ptr->num_trans = 0;
+      }
+   }
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+   if (png_ptr->transformations & PNG_BACKGROUND)
+   {
+      info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
+      info_ptr->num_trans = 0;
+      info_ptr->background = png_ptr->background;
+   }
+#endif
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+   if ((png_ptr->transformations & PNG_16_TO_8) && info_ptr->bit_depth == 16)
+      info_ptr->bit_depth = 8;
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+   if (png_ptr->transformations & PNG_DITHER)
+   {
+      if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
+         (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
+         png_ptr->palette_lookup && info_ptr->bit_depth == 8)
+      {
+         info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
+      }
+   }
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED)
+   if ((png_ptr->transformations & PNG_PACK) && info_ptr->bit_depth < 8)
+      info_ptr->bit_depth = 8;
+#endif
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
+      info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
+#endif
+
+   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      info_ptr->channels = 1;
+   else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
+      info_ptr->channels = 3;
+   else
+      info_ptr->channels = 1;
+
+#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+   if (png_ptr->transformations & PNG_STRIP_ALPHA)
+      info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED)
+   if ((png_ptr->transformations & PNG_FILLER) &&
+       info_ptr->color_type & PNG_COLOR_TYPE_RGB &&
+       info_ptr->channels == 3)
+   {
+      info_ptr->channels = 4;
+   }
+#endif
+
+   if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
+      info_ptr->channels++;
+   info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
+      info_ptr->bit_depth);
+
+   info_ptr->rowbytes = ((info_ptr->width * info_ptr->pixel_depth + 7) >> 3);
+}
+
+/* Transform the row.  The order of transformations is significant,
+ * and is very touchy.  If you add a transformation, take care to
+ * decide how it fits in with the other transformations here.
+ */
+void
+png_do_read_transformations(png_structp png_ptr)
+{
+   png_debug(1, "in png_do_read_transformations\n");
+#if !defined(PNG_USELESS_TESTS_SUPPORTED)
+   if (png_ptr->row_buf == NULL)
+   {
+#if !defined(PNG_NO_STDIO)
+      char msg[50];
+
+      sprintf(msg, "NULL row buffer for row %ld, pass %d", png_ptr->row_number,
+         png_ptr->pass);
+      png_error(png_ptr, msg);
+#else
+      png_error(png_ptr, "NULL row buffer");
+#endif
+   }
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+   if (png_ptr->transformations & PNG_EXPAND)
+   {
+      if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
+            png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
+      }
+      else if (png_ptr->transformations & PNG_EXPAND)
+      {
+         if (png_ptr->num_trans)
+            png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
+               &(png_ptr->trans_values));
+         else
+            png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
+               NULL);
+      }
+   }
+#endif
+
+#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+   if (png_ptr->transformations & PNG_STRIP_ALPHA)
+      png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
+         PNG_FLAG_FILLER_AFTER);
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+   if ((png_ptr->transformations & PNG_BACKGROUND) &&
+      ((png_ptr->num_trans != 0 ) ||
+      (png_ptr->color_type & PNG_COLOR_MASK_ALPHA)))
+      png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
+         &(png_ptr->trans_values), &(png_ptr->background),
+         &(png_ptr->background_1),
+         png_ptr->gamma_table, png_ptr->gamma_from_1,
+         png_ptr->gamma_to_1, png_ptr->gamma_16_table,
+         png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
+         png_ptr->gamma_shift);
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+   if ((png_ptr->transformations & PNG_GAMMA) &&
+      !(png_ptr->transformations & PNG_BACKGROUND) &&
+      (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
+      png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
+         png_ptr->gamma_table, png_ptr->gamma_16_table,
+         png_ptr->gamma_shift);
+#endif
+
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+   if (png_ptr->transformations & PNG_RGB_TO_GRAY)
+      png_do_rgb_to_gray(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+   if (png_ptr->transformations & PNG_16_TO_8)
+      png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+   if (png_ptr->transformations & PNG_DITHER)
+   {
+      png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1,
+         png_ptr->palette_lookup, png_ptr->dither_index);
+      if(png_ptr->row_info.rowbytes == (png_uint_32)0)
+         png_error(png_ptr, "png_do_dither returned rowbytes=0");
+   }
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED)
+   if (png_ptr->transformations & PNG_INVERT_MONO)
+      png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED)
+   if (png_ptr->transformations & PNG_SHIFT)
+      png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1,
+         &(png_ptr->shift));
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED)
+   if (png_ptr->transformations & PNG_PACK)
+      png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED)
+   if (png_ptr->transformations & PNG_BGR)
+      png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+   if (png_ptr->transformations & PNG_PACKSWAP)
+      png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
+      png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED)
+   if (png_ptr->transformations & PNG_FILLER)
+      png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
+         (png_uint_32)png_ptr->filler, png_ptr->flags);
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
+   if (png_ptr->transformations & PNG_INVERT_ALPHA)
+      png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
+   if (png_ptr->transformations & PNG_SWAP_ALPHA)
+      png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED)
+   if (png_ptr->transformations & PNG_SWAP_BYTES)
+      png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+   if (png_ptr->transformations & PNG_USER_TRANSFORM)
+      if(png_ptr->read_user_transform_fn != NULL)
+        (*(png_ptr->read_user_transform_fn)) /* user read transform function */
+          (png_ptr,                    /* png_ptr */
+           &(png_ptr->row_info),       /* row_info:     */
+             /*  png_uint_32 width;          width of row */
+             /*  png_uint_32 rowbytes;       number of bytes in row */
+             /*  png_byte color_type;        color type of pixels */
+             /*  png_byte bit_depth;         bit depth of samples */
+             /*  png_byte channels;          number of channels (1-4) */
+             /*  png_byte pixel_depth;       bits per pixel (depth*channels) */
+           png_ptr->row_buf + 1);      /* start of pixel data for row */
+#endif
+
+}
+
+#if defined(PNG_READ_PACK_SUPPORTED)
+/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
+ * without changing the actual values.  Thus, if you had a row with
+ * a bit depth of 1, you would end up with bytes that only contained
+ * the numbers 0 or 1.  If you would rather they contain 0 and 255, use
+ * png_do_shift() after this.
+ */
+void
+png_do_unpack(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_unpack\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+   if (row != NULL && row_info != NULL && row_info->bit_depth < 8)
+#else
+   if (row_info->bit_depth < 8)
+#endif
+   {
+      png_uint_32 shift, i;
+      png_bytep sp, dp;
+
+      switch (row_info->bit_depth)
+      {
+         case 1:
+         {
+            sp = row + (png_size_t)((row_info->width - 1) >> 3);
+            dp = row + (png_size_t)row_info->width - 1;
+            shift = 7 - (int)((row_info->width + 7) & 7);
+            for (i = 0; i < row_info->width; i++)
+            {
+               *dp = (png_byte)((*sp >> shift) & 0x1);
+               if (shift == 7)
+               {
+                  shift = 0;
+                  sp--;
+               }
+               else
+                  shift++;
+
+               dp--;
+            }
+            break;
+         }
+         case 2:
+         {
+
+            sp = row + (png_size_t)((row_info->width - 1) >> 2);
+            dp = row + (png_size_t)row_info->width - 1;
+            shift = (int)((3 - ((row_info->width + 3) & 3)) << 1);
+            for (i = 0; i < row_info->width; i++)
+            {
+               *dp = (png_byte)((*sp >> shift) & 0x3);
+               if (shift == 6)
+               {
+                  shift = 0;
+                  sp--;
+               }
+               else
+                  shift += 2;
+
+               dp--;
+            }
+            break;
+         }
+         case 4:
+         {
+            sp = row + (png_size_t)((row_info->width - 1) >> 1);
+            dp = row + (png_size_t)row_info->width - 1;
+            shift = (int)((1 - ((row_info->width + 1) & 1)) << 2);
+            for (i = 0; i < row_info->width; i++)
+            {
+               *dp = (png_byte)((*sp >> shift) & 0xf);
+               if (shift == 4)
+               {
+                  shift = 0;
+                  sp--;
+               }
+               else
+                  shift = 4;
+
+               dp--;
+            }
+            break;
+         }
+      }
+      row_info->bit_depth = 8;
+      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
+      row_info->rowbytes = row_info->width * row_info->channels;
+   }
+}
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED)
+/* Reverse the effects of png_do_shift.  This routine merely shifts the
+ * pixels back to their significant bits values.  Thus, if you have
+ * a row of bit depth 8, but only 5 are significant, this will shift
+ * the values back to 0 through 31.
+ */
+void
+png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits)
+{
+   png_debug(1, "in png_do_unshift\n");
+   if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL && row_info != NULL && sig_bits != NULL &&
+#endif
+       row_info->color_type != PNG_COLOR_TYPE_PALETTE)
+   {
+      int shift[4];
+      int channels, c;
+      png_uint_16 value;
+
+      channels = 0;
+      if (row_info->color_type & PNG_COLOR_MASK_COLOR)
+      {
+         shift[channels++] = row_info->bit_depth - sig_bits->red;
+         shift[channels++] = row_info->bit_depth - sig_bits->green;
+         shift[channels++] = row_info->bit_depth - sig_bits->blue;
+      }
+      else
+      {
+         shift[channels++] = row_info->bit_depth - sig_bits->gray;
+      }
+      if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
+      {
+         shift[channels++] = row_info->bit_depth - sig_bits->alpha;
+      }
+
+      value = 0;
+
+      for (c = 0; c < channels; c++)
+      {
+         if (shift[c] <= 0)
+            shift[c] = 0;
+         else
+            value = 1;
+      }
+
+      if (!value)
+         return;
+
+      switch (row_info->bit_depth)
+      {
+         case 2:
+         {
+            png_bytep bp;
+            png_uint_32 i;
+
+            for (bp = row, i = 0; i < row_info->rowbytes; i++, bp++)
+            {
+               *bp >>= 1;
+               *bp &= 0x55;
+            }
+            break;
+         }
+         case 4:
+         {
+            png_bytep bp;
+            png_byte mask;
+            png_uint_32 i;
+
+            mask = (png_byte)(((int)0xf0 >> shift[0]) & (int)0xf0) |
+               (png_byte)((int)0xf >> shift[0]);
+            for (bp = row, i = 0; i < row_info->rowbytes; i++, bp++)
+            {
+               *bp >>= shift[0];
+               *bp &= mask;
+            }
+            break;
+         }
+         case 8:
+         {
+            png_bytep bp;
+            png_uint_32 i;
+
+            for (bp = row, i = 0; i < row_info->width; i++)
+            {
+               for (c = 0; c < (int)row_info->channels; c++, bp++)
+               {
+                  *bp >>= shift[c];
+               }
+            }
+            break;
+         }
+         case 16:
+         {
+            png_bytep bp;
+            png_size_t i;
+
+            for (bp = row, i = 0; i < row_info->width; i++)
+            {
+               for (c = 0; c < (int)row_info->channels; c++, bp += 2)
+               {
+                  value = (png_uint_16)((*bp << 8) + *(bp + 1));
+                  value >>= shift[c];
+                  *bp = (png_byte)(value >> 8);
+                  *(bp + 1) = (png_byte)(value & 0xff);
+               }
+            }
+            break;
+         }
+      }
+   }
+}
+#endif
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+/* chop rows of bit depth 16 down to 8 */
+void
+png_do_chop(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_chop\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+   if (row != NULL && row_info != NULL && row_info->bit_depth == 16)
+#else
+   if (row_info->bit_depth == 16)
+#endif
+   {
+      png_bytep sp, dp;
+      png_uint_32 i;
+
+      sp = row;
+      dp = row;
+      for (i = 0; i < row_info->width * row_info->channels; i++, sp += 2, dp++)
+      {
+#if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
+         /* This does a more accurate scaling of the 16-bit color
+          * value, rather than a simple low-byte truncation.
+          *
+          * What the ideal calculation should be:
+         *dp = (((((png_uint_32)(*sp) << 8) |
+                   (png_uint_32)(*(sp + 1))) * 255 + 127) / (png_uint_32)65535L;
+
+
+          * GRR: no, I think this is what it really should be:
+         *dp = (((((png_uint_32)(*sp) << 8) |
+                   (png_uint_32)(*(sp + 1))) + 128L) / (png_uint_32)257L;
+
+          * GRR: here's the exact calculation with shifts:
+         temp = (((png_uint_32)(*sp) << 8) | (png_uint_32)(*(sp + 1))) + 128L;
+         *dp = (temp - (temp >> 8)) >> 8;
+
+
+          * Approximate calculation with shift/add instead of multiply/divide:
+         *dp = ((((png_uint_32)(*sp) << 8) |
+                  (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
+
+          * What we actually do to avoid extra shifting and conversion: */
+         *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0);
+#else
+         *dp = *sp;
+#endif
+      }
+      row_info->bit_depth = 8;
+      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
+      row_info->rowbytes = row_info->width * row_info->channels;
+   }
+}
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
+void
+png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_read_swap_alpha\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+   if (row != NULL && row_info != NULL)
+#endif
+   {
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+      {
+         /* This converts from RGBA to ARGB */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp, dp;
+            png_byte save;
+            png_uint_32 i;
+
+            for (i = 0, sp = dp = row + row_info->rowbytes;
+               i < row_info->width; i++)
+            {
+               save = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = save;
+            }
+         }
+         /* This converts from RRGGBBAA to AARRGGBB */
+         else
+         {
+            png_bytep sp, dp;
+            png_byte save[2];
+            png_uint_32 i;
+
+            for (i = 0, sp = dp = row + row_info->rowbytes;
+               i < row_info->width; i++)
+            {
+               save[0] = *(--sp);
+               save[1] = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = save[0];
+               *(--dp) = save[1];
+            }
+         }
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      {
+         /* This converts from GA to AG */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp, dp;
+            png_byte save;
+            png_uint_32 i;
+
+            for (i = 0, sp = dp = row + row_info->rowbytes;
+               i < row_info->width; i++)
+            {
+               save = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = save;
+            }
+         }
+         /* This converts from GGAA to AAGG */
+         else
+         {
+            png_bytep sp, dp;
+            png_byte save[2];
+            png_uint_32 i;
+
+            for (i = 0, sp = dp = row + row_info->rowbytes;
+               i < row_info->width; i++)
+            {
+               save[0] = *(--sp);
+               save[1] = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = save[0];
+               *(--dp) = save[1];
+            }
+         }
+      }
+   }
+}
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
+void
+png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_read_invert_alpha\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+   if (row != NULL && row_info != NULL)
+#endif
+   {
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+      {
+         /* This inverts the alpha channel in RGBA */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp, dp;
+            png_uint_32 i;
+
+            for (i = 0, sp = dp = row + row_info->rowbytes;
+               i < row_info->width; i++)
+            {
+               *(--dp) = 255 - *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+            }
+         }
+         /* This inverts the alpha channel in RRGGBBAA */
+         else
+         {
+            png_bytep sp, dp;
+            png_uint_32 i;
+
+            for (i = 0, sp = dp = row + row_info->rowbytes;
+               i < row_info->width; i++)
+            {
+               *(--dp) = 255 - *(--sp);
+               *(--dp) = 255 - *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+            }
+         }
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      {
+         /* This inverts the alpha channel in GA */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp, dp;
+            png_uint_32 i;
+
+            for (i = 0, sp = dp = row + row_info->rowbytes;
+               i < row_info->width; i++)
+            {
+               *(--dp) = 255 - *(--sp);
+               *(--dp) = *(--sp);
+            }
+         }
+         /* This inverts the alpha channel in GGAA */
+         else
+         {
+            png_bytep sp, dp;
+            png_uint_32 i;
+
+            for (i = 0, sp = dp = row + row_info->rowbytes;
+               i < row_info->width; i++)
+            {
+               *(--dp) = 255 - *(--sp);
+               *(--dp) = 255 - *(--sp);
+               *(--dp) = *(--sp);
+               *(--dp) = *(--sp);
+            }
+         }
+      }
+   }
+}
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED)
+/* Add filler channel if we have RGB color */
+void
+png_do_read_filler(png_row_infop row_info, png_bytep row,
+   png_uint_32 filler, png_uint_32 flags)
+{
+   png_bytep sp, dp;
+   png_uint_32 i;
+
+   png_debug(1, "in png_do_read_filler\n");
+   if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL  && row_info != NULL &&
+#endif
+       row_info->color_type == PNG_COLOR_TYPE_RGB && row_info->bit_depth == 8)
+   {
+      /* This changes the data from RGB to RGBX */
+      if (flags & PNG_FLAG_FILLER_AFTER)
+      {
+         for (i = 1, sp = row + (png_size_t)row_info->width * 3,
+            dp = row + (png_size_t)row_info->width * 4;
+            i < row_info->width;
+            i++)
+         {
+            *(--dp) = (png_byte)filler;
+            *(--dp) = *(--sp);
+            *(--dp) = *(--sp);
+            *(--dp) = *(--sp);
+         }
+         *(--dp) = (png_byte)filler;
+         row_info->channels = 4;
+         row_info->pixel_depth = 32;
+         row_info->rowbytes = row_info->width * 4;
+      }
+      /* This changes the data from RGB to XRGB */
+      else
+      {
+         for (i = 0, sp = row + (png_size_t)row_info->width * 3,
+            dp = row + (png_size_t)row_info->width * 4;
+            i < row_info->width;
+            i++)
+         {
+            *(--dp) = *(--sp);
+            *(--dp) = *(--sp);
+            *(--dp) = *(--sp);
+            *(--dp) = (png_byte)filler;
+         }
+         row_info->channels = 4;
+         row_info->pixel_depth = 32;
+         row_info->rowbytes = row_info->width * 4;
+      }
+   }
+}
+#endif
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+/* expand grayscale files to RGB, with or without alpha */
+void
+png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
+{
+   png_bytep sp, dp;
+   png_uint_32 i;
+
+   png_debug(1, "in png_do_gray_to_rgb\n");
+   if (row_info->bit_depth >= 8 &&
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL && row_info != NULL &&
+#endif
+      !(row_info->color_type & PNG_COLOR_MASK_COLOR))
+   {
+      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+      {
+         if (row_info->bit_depth == 8)
+         {
+            for (i = 0, sp = row + (png_size_t)row_info->width - 1,
+               dp = row + (png_size_t)row_info->width * 3 - 1;
+               i < row_info->width;
+               i++)
+            {
+               *(dp--) = *sp;
+               *(dp--) = *sp;
+               *(dp--) = *sp;
+               sp--;
+            }
+         }
+         else
+         {
+            for (i = 0, sp = row + (png_size_t)row_info->width * 2 - 1,
+               dp = row + (png_size_t)row_info->width * 6 - 1;
+               i < row_info->width;
+               i++)
+            {
+               *(dp--) = *sp;
+               *(dp--) = *(sp - 1);
+               *(dp--) = *sp;
+               *(dp--) = *(sp - 1);
+               *(dp--) = *sp;
+               *(dp--) = *(sp - 1);
+               sp--;
+               sp--;
+            }
+         }
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      {
+         if (row_info->bit_depth == 8)
+         {
+            for (i = 0, sp = row + (png_size_t)row_info->width * 2 - 1,
+               dp = row + (png_size_t)row_info->width * 4 - 1;
+               i < row_info->width;
+               i++)
+            {
+               *(dp--) = *(sp--);
+               *(dp--) = *sp;
+               *(dp--) = *sp;
+               *(dp--) = *sp;
+               sp--;
+            }
+         }
+         else
+         {
+            for (i = 0, sp = row + (png_size_t)row_info->width * 4 - 1,
+               dp = row + (png_size_t)row_info->width * 8 - 1;
+               i < row_info->width;
+               i++)
+            {
+               *(dp--) = *(sp--);
+               *(dp--) = *(sp--);
+               *(dp--) = *sp;
+               *(dp--) = *(sp - 1);
+               *(dp--) = *sp;
+               *(dp--) = *(sp - 1);
+               *(dp--) = *sp;
+               *(dp--) = *(sp - 1);
+               sp--;
+               sp--;
+            }
+         }
+      }
+      row_info->channels += (png_byte)2;
+      row_info->color_type |= PNG_COLOR_MASK_COLOR;
+      row_info->pixel_depth = (png_byte)(row_info->channels *
+         row_info->bit_depth);
+      row_info->rowbytes = ((row_info->width *
+         row_info->pixel_depth + 7) >> 3);
+   }
+}
+#endif
+
+/* Build a grayscale palette.  Palette is assumed to be 1 << bit_depth
+ * large of png_color.  This lets grayscale images be treated as
+ * paletted.  Most useful for gamma correction and simplification
+ * of code.
+ */
+void
+png_build_grayscale_palette(int bit_depth, png_colorp palette)
+{
+   int num_palette;
+   int color_inc;
+   int i;
+   int v;
+
+   png_debug(1, "in png_do_build_grayscale_palette\n");
+   if (palette == NULL)
+      return;
+
+   switch (bit_depth)
+   {
+      case 1:
+         num_palette = 2;
+         color_inc = 0xff;
+         break;
+      case 2:
+         num_palette = 4;
+         color_inc = 0x55;
+         break;
+      case 4:
+         num_palette = 16;
+         color_inc = 0x11;
+         break;
+      case 8:
+         num_palette = 256;
+         color_inc = 1;
+         break;
+      default:
+         num_palette = 0;
+         color_inc = 0;
+         break;
+   }
+
+   for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
+   {
+      palette[i].red = (png_byte)v;
+      palette[i].green = (png_byte)v;
+      palette[i].blue = (png_byte)v;
+   }
+}
+
+/* This function is currently unused.  Do we really need it? */
+#if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
+void
+png_correct_palette(png_structp png_ptr, png_colorp palette,
+   int num_palette)
+{
+   png_debug(1, "in png_correct_palette\n");
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
+   if ((png_ptr->transformations & (PNG_GAMMA)) &&
+      (png_ptr->transformations & (PNG_BACKGROUND)))
+   {
+      png_color back, back_1;
+
+      if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
+      {
+         back.red = png_ptr->gamma_table[png_ptr->background.red];
+         back.green = png_ptr->gamma_table[png_ptr->background.green];
+         back.blue = png_ptr->gamma_table[png_ptr->background.blue];
+
+         back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
+         back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
+         back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
+      }
+      else
+      {
+         double g;
+
+         g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma);
+
+         if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN ||
+             fabs(g - 1.0) < PNG_GAMMA_THRESHOLD)
+         {
+            back.red = png_ptr->background.red;
+            back.green = png_ptr->background.green;
+            back.blue = png_ptr->background.blue;
+         }
+         else
+         {
+            back.red =
+               (png_byte)(pow((double)png_ptr->background.red/255, g) *
+                255.0 + 0.5);
+            back.green =
+               (png_byte)(pow((double)png_ptr->background.green/255, g) *
+                255.0 + 0.5);
+            back.blue =
+               (png_byte)(pow((double)png_ptr->background.blue/255, g) *
+                255.0 + 0.5);
+         }
+
+         g = 1.0 / png_ptr->background_gamma;
+
+         back_1.red =
+            (png_byte)(pow((double)png_ptr->background.red/255, g) *
+             255.0 + 0.5);
+         back_1.green =
+            (png_byte)(pow((double)png_ptr->background.green/255, g) *
+             255.0 + 0.5);
+         back_1.blue =
+            (png_byte)(pow((double)png_ptr->background.blue/255, g) *
+             255.0 + 0.5);
+      }
+
+      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         png_uint_32 i;
+
+         for (i = 0; i < (png_uint_32)num_palette; i++)
+         {
+            if (i < png_ptr->num_trans && png_ptr->trans[i] == 0)
+            {
+               palette[i] = back;
+            }
+            else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff)
+            {
+               png_byte v, w;
+
+               v = png_ptr->gamma_to_1[png_ptr->palette[i].red];
+               png_composite(w, v, png_ptr->trans[i], back_1.red);
+               palette[i].red = png_ptr->gamma_from_1[w];
+
+               v = png_ptr->gamma_to_1[png_ptr->palette[i].green];
+               png_composite(w, v, png_ptr->trans[i], back_1.green);
+               palette[i].green = png_ptr->gamma_from_1[w];
+
+               v = png_ptr->gamma_to_1[png_ptr->palette[i].blue];
+               png_composite(w, v, png_ptr->trans[i], back_1.blue);
+               palette[i].blue = png_ptr->gamma_from_1[w];
+            }
+            else
+            {
+               palette[i].red = png_ptr->gamma_table[palette[i].red];
+               palette[i].green = png_ptr->gamma_table[palette[i].green];
+               palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+            }
+         }
+      }
+      else
+      {
+         int i;
+
+         for (i = 0; i < num_palette; i++)
+         {
+            if (palette[i].red == (png_byte)png_ptr->trans_values.gray)
+            {
+               palette[i] = back;
+            }
+            else
+            {
+               palette[i].red = png_ptr->gamma_table[palette[i].red];
+               palette[i].green = png_ptr->gamma_table[palette[i].green];
+               palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+            }
+         }
+      }
+   }
+   else
+#endif
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+   if (png_ptr->transformations & PNG_GAMMA)
+   {
+      int i;
+
+      for (i = 0; i < num_palette; i++)
+      {
+         palette[i].red = png_ptr->gamma_table[palette[i].red];
+         palette[i].green = png_ptr->gamma_table[palette[i].green];
+         palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+      }
+   }
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+   else
+#endif
+#endif
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+   if (png_ptr->transformations & PNG_BACKGROUND)
+   {
+      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         png_color back;
+
+         back.red   = (png_byte)png_ptr->background.red;
+         back.green = (png_byte)png_ptr->background.green;
+         back.blue  = (png_byte)png_ptr->background.blue;
+
+         for (i = 0; i < (int)png_ptr->num_trans; i++)
+         {
+            if (png_ptr->trans[i] == 0)
+            {
+               palette[i].red = back.red;
+               palette[i].green = back.green;
+               palette[i].blue = back.blue;
+            }
+            else if (png_ptr->trans[i] != 0xff)
+            {
+               png_composite(palette[i].red, png_ptr->palette[i].red,
+                  png_ptr->trans[i], back.red);
+               png_composite(palette[i].green, png_ptr->palette[i].green,
+                  png_ptr->trans[i], back.green);
+               png_composite(palette[i].blue, png_ptr->palette[i].blue,
+                  png_ptr->trans[i], back.blue);
+            }
+         }
+      }
+      else /* assume grayscale palette (what else could it be?) */
+      {
+         int i;
+
+         for (i = 0; i < num_palette; i++)
+         {
+            if (i == (png_byte)png_ptr->trans_values.gray)
+            {
+               palette[i].red = (png_byte)png_ptr->background.red;
+               palette[i].green = (png_byte)png_ptr->background.green;
+               palette[i].blue = (png_byte)png_ptr->background.blue;
+            }
+         }
+      }
+   }
+#endif
+}
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+/* Replace any alpha or transparency with the supplied background color.
+ * "background" is already in the screen gamma, while "background_1" is
+ * at a gamma of 1.0.  Paletted files have already been taken care of.
+ */
+void
+png_do_background(png_row_infop row_info, png_bytep row,
+   png_color_16p trans_values, png_color_16p background,
+   png_color_16p background_1,
+   png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
+   png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
+   png_uint_16pp gamma_16_to_1, int gamma_shift)
+{
+   png_bytep sp, dp;
+   png_uint_32 i;
+   int shift;
+
+   png_debug(1, "in png_do_background\n");
+   if (background != NULL &&
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL && row_info != NULL &&
+#endif
+      (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
+      (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values)))
+   {
+      switch (row_info->color_type)
+      {
+         case PNG_COLOR_TYPE_GRAY:
+         {
+            switch (row_info->bit_depth)
+            {
+               case 1:
+               {
+                  sp = row;
+                  shift = 7;
+                  for (i = 0; i < row_info->width; i++)
+                  {
+                     if ((png_uint_16)((*sp >> shift) & 0x1)
+                        == trans_values->gray)
+                     {
+                        *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
+                        *sp |= (png_byte)(background->gray << shift);
+                     }
+                     if (!shift)
+                     {
+                        shift = 7;
+                        sp++;
+                     }
+                     else
+                        shift--;
+                  }
+                  break;
+               }
+               case 2:
+               {
+                  sp = row;
+                  shift = 6;
+                  for (i = 0; i < row_info->width; i++)
+                  {
+                     if ((png_uint_16)((*sp >> shift) & 0x3)
+                         == trans_values->gray)
+                     {
+                        *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
+                        *sp |= (png_byte)(background->gray << shift);
+                     }
+                     if (!shift)
+                     {
+                        shift = 6;
+                        sp++;
+                     }
+                     else
+                        shift -= 2;
+                  }
+                  break;
+               }
+               case 4:
+               {
+                  sp = row;
+                  shift = 4;
+                  for (i = 0; i < row_info->width; i++)
+                  {
+                     if ((png_uint_16)((*sp >> shift) & 0xf)
+                         == trans_values->gray)
+                     {
+                        *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
+                        *sp |= (png_byte)(background->gray << shift);
+                     }
+                     if (!shift)
+                     {
+                        shift = 4;
+                        sp++;
+                     }
+                     else
+                        shift -= 4;
+                  }
+                  break;
+               }
+               case 8:
+               {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+                  if (gamma_table != NULL)
+                  {
+                     for (i = 0, sp = row; i < row_info->width; i++, sp++)
+                     {
+                        if (*sp == trans_values->gray)
+                        {
+                           *sp = (png_byte)background->gray;
+                        }
+                        else
+                        {
+                           *sp = gamma_table[*sp];
+                        }
+                     }
+                  }
+                  else
+#endif
+                  {
+                     for (i = 0, sp = row; i < row_info->width; i++, sp++)
+                     {
+                        if (*sp == trans_values->gray)
+                        {
+                           *sp = (png_byte)background->gray;
+                        }
+                     }
+                  }
+                  break;
+               }
+               case 16:
+               {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+                  if (gamma_16 != NULL)
+                  {
+                     for (i = 0, sp = row; i < row_info->width; i++, sp += 2)
+                     {
+                        png_uint_16 v;
+
+                        v = ((png_uint_16)(*sp) << 8) + *(sp + 1);
+                        if (v == trans_values->gray)
+                        {
+                           /* background is already in screen gamma */
+                           *sp = (png_byte)((background->gray >> 8) & 0xff);
+                           *(sp + 1) = (png_byte)(background->gray & 0xff);
+                        }
+                        else
+                        {
+                           v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+                           *sp = (png_byte)((v >> 8) & 0xff);
+                           *(sp + 1) = (png_byte)(v & 0xff);
+                        }
+                     }
+                  }
+                  else
+#endif
+                  {
+                     for (i = 0, sp = row; i < row_info->width; i++, sp += 2)
+                     {
+                        png_uint_16 v;
+
+                        v = ((png_uint_16)(*sp) << 8) + *(sp + 1);
+                        if (v == trans_values->gray)
+                        {
+                           *sp = (png_byte)((background->gray >> 8) & 0xff);
+                           *(sp + 1) = (png_byte)(background->gray & 0xff);
+                        }
+                     }
+                  }
+                  break;
+               }
+            }
+            break;
+         }
+         case PNG_COLOR_TYPE_RGB:
+         {
+            if (row_info->bit_depth == 8)
+            {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+               if (gamma_table != NULL)
+               {
+                  for (i = 0, sp = row; i < row_info->width; i++, sp += 3)
+                  {
+                     if (*sp == trans_values->red &&
+                        *(sp + 1) == trans_values->green &&
+                        *(sp + 2) == trans_values->blue)
+                     {
+                        *sp = (png_byte)background->red;
+                        *(sp + 1) = (png_byte)background->green;
+                        *(sp + 2) = (png_byte)background->blue;
+                     }
+                     else
+                     {
+                        *sp = gamma_table[*sp];
+                        *(sp + 1) = gamma_table[*(sp + 1)];
+                        *(sp + 2) = gamma_table[*(sp + 2)];
+                     }
+                  }
+               }
+               else
+#endif
+               {
+                  for (i = 0, sp = row; i < row_info->width; i++, sp += 3)
+                  {
+                     if (*sp == trans_values->red &&
+                        *(sp + 1) == trans_values->green &&
+                        *(sp + 2) == trans_values->blue)
+                     {
+                        *sp = (png_byte)background->red;
+                        *(sp + 1) = (png_byte)background->green;
+                        *(sp + 2) = (png_byte)background->blue;
+                     }
+                  }
+               }
+            }
+            else /* if (row_info->bit_depth == 16) */
+            {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+               if (gamma_16 != NULL)
+               {
+                  for (i = 0, sp = row; i < row_info->width; i++, sp += 6)
+                  {
+                     png_uint_16 r, g, b;
+
+                     r = ((png_uint_16)(*sp) << 8) + *(sp + 1);
+                     g = ((png_uint_16)(*(sp + 2)) << 8) + *(sp + 3);
+                     b = ((png_uint_16)(*(sp + 4)) << 8) + *(sp + 5);
+                     if (r == trans_values->red && g == trans_values->green &&
+                        b == trans_values->blue)
+                     {
+                        /* background is already in screen gamma */
+                        *sp = (png_byte)((background->red >> 8) & 0xff);
+                        *(sp + 1) = (png_byte)(background->red & 0xff);
+                        *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
+                        *(sp + 3) = (png_byte)(background->green & 0xff);
+                        *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
+                        *(sp + 5) = (png_byte)(background->blue & 0xff);
+                     }
+                     else
+                     {
+                        png_uint_16 v;
+                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+                        *sp = (png_byte)((v >> 8) & 0xff);
+                        *(sp + 1) = (png_byte)(v & 0xff);
+                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
+                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);
+                        *(sp + 3) = (png_byte)(v & 0xff);
+                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
+                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);
+                        *(sp + 5) = (png_byte)(v & 0xff);
+                     }
+                  }
+               }
+               else
+#endif
+               {
+                  for (i = 0, sp = row; i < row_info->width; i++, sp += 6)
+                  {
+                     png_uint_16 r, g, b;
+
+                     r = ((png_uint_16)(*sp) << 8) + *(sp + 1);
+                     g = ((png_uint_16)(*(sp + 2)) << 8) + *(sp + 3);
+                     b = ((png_uint_16)(*(sp + 4)) << 8) + *(sp + 5);
+                     if (r == trans_values->red && g == trans_values->green &&
+                        b == trans_values->blue)
+                     {
+                        *sp = (png_byte)((background->red >> 8) & 0xff);
+                        *(sp + 1) = (png_byte)(background->red & 0xff);
+                        *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
+                        *(sp + 3) = (png_byte)(background->green & 0xff);
+                        *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
+                        *(sp + 5) = (png_byte)(background->blue & 0xff);
+                     }
+                  }
+               }
+            }
+            break;
+         }
+         case PNG_COLOR_TYPE_GRAY_ALPHA:
+         {
+            if (row_info->bit_depth == 8)
+            {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
+                   gamma_table != NULL)
+               {
+                  for (i = 0, sp = row, dp = row;
+                     i < row_info->width; i++, sp += 2, dp++)
+                  {
+                     png_uint_16 a;
+
+                     a = *(sp + 1);
+                     if (a == 0xff)
+                     {
+                        *dp = gamma_table[*sp];
+                     }
+                     else if (a == 0)
+                     {
+                        /* background is already in screen gamma */
+                        *dp = (png_byte)background->gray;
+                     }
+                     else
+                     {
+                        png_byte v, w;
+
+                        v = gamma_to_1[*sp];
+                        png_composite(w, v, a, background_1->gray);
+                        *dp = gamma_from_1[w];
+                     }
+                  }
+               }
+               else
+#endif
+               {
+                  for (i = 0, sp = row, dp = row;
+                     i < row_info->width; i++, sp += 2, dp++)
+                  {
+                     png_byte a;
+
+                     a = *(sp + 1);
+                     if (a == 0xff)
+                     {
+                        *dp = *sp;
+                     }
+                     else if (a == 0)
+                     {
+                        *dp = (png_byte)background->gray;
+                     }
+                     else
+                     {
+                        png_composite(*dp, *sp, a, background_1->gray);
+                     }
+                  }
+               }
+            }
+            else /* if (png_ptr->bit_depth == 16) */
+            {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
+                   gamma_16_to_1 != NULL)
+               {
+                  for (i = 0, sp = row, dp = row;
+                     i < row_info->width; i++, sp += 4, dp += 2)
+                  {
+                     png_uint_16 a;
+
+                     a = ((png_uint_16)(*(sp + 2)) << 8) + *(sp + 3);
+                     if (a == (png_uint_16)0xffff)
+                     {
+                        png_uint_16 v;
+
+                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+                        *dp = (png_byte)((v >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(v & 0xff);
+                     }
+                     else if (a == 0)
+                     {
+                        /* background is already in screen gamma */
+                        *dp = (png_byte)((background->gray >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(background->gray & 0xff);
+                     }
+                     else
+                     {
+                        png_uint_16 g, v, w;
+
+                        g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
+                        png_composite_16(v, g, a, background_1->gray);
+                        w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
+                        *dp = (png_byte)((w >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(w & 0xff);
+                     }
+                  }
+               }
+               else
+#endif
+               {
+                  for (i = 0, sp = row, dp = row;
+                     i < row_info->width; i++, sp += 4, dp += 2)
+                  {
+                     png_uint_16 a;
+
+                     a = ((png_uint_16)(*(sp + 2)) << 8) + *(sp + 3);
+                     if (a == (png_uint_16)0xffff)
+                     {
+                        png_memcpy(dp, sp, 2);
+                     }
+                     else if (a == 0)
+                     {
+                        *dp = (png_byte)((background->gray >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(background->gray & 0xff);
+                     }
+                     else
+                     {
+                        png_uint_16 g, v;
+
+                        g = ((png_uint_16)(*sp) << 8) + *(sp + 1);
+                        png_composite_16(v, g, a, background_1->gray);
+                        *dp = (png_byte)((v >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(v & 0xff);
+                     }
+                  }
+               }
+            }
+            break;
+         }
+         case PNG_COLOR_TYPE_RGB_ALPHA:
+         {
+            if (row_info->bit_depth == 8)
+            {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
+                   gamma_table != NULL)
+               {
+                  for (i = 0, sp = row, dp = row;
+                     i < row_info->width; i++, sp += 4, dp += 3)
+                  {
+                     png_byte a;
+
+                     a = *(sp + 3);
+                     if (a == 0xff)
+                     {
+                        *dp = gamma_table[*sp];
+                        *(dp + 1) = gamma_table[*(sp + 1)];
+                        *(dp + 2) = gamma_table[*(sp + 2)];
+                     }
+                     else if (a == 0)
+                     {
+                        /* background is already in screen gamma */
+                        *dp = (png_byte)background->red;
+                        *(dp + 1) = (png_byte)background->green;
+                        *(dp + 2) = (png_byte)background->blue;
+                     }
+                     else
+                     {
+                        png_byte v, w;
+
+                        v = gamma_to_1[*sp];
+                        png_composite(w, v, a, background_1->red);
+                        *dp = gamma_from_1[w];
+                        v = gamma_to_1[*(sp + 1)];
+                        png_composite(w, v, a, background_1->green);
+                        *(dp + 1) = gamma_from_1[w];
+                        v = gamma_to_1[*(sp + 2)];
+                        png_composite(w, v, a, background_1->blue);
+                        *(dp + 2) = gamma_from_1[w];
+                     }
+                  }
+               }
+               else
+#endif
+               {
+                  for (i = 0, sp = row, dp = row;
+                     i < row_info->width; i++, sp += 4, dp += 3)
+                  {
+                     png_byte a;
+
+                     a = *(sp + 3);
+                     if (a == 0xff)
+                     {
+                        *dp = *sp;
+                        *(dp + 1) = *(sp + 1);
+                        *(dp + 2) = *(sp + 2);
+                     }
+                     else if (a == 0)
+                     {
+                        *dp = (png_byte)background->red;
+                        *(dp + 1) = (png_byte)background->green;
+                        *(dp + 2) = (png_byte)background->blue;
+                     }
+                     else
+                     {
+                        png_composite(*dp, *sp, a, background->red);
+                        png_composite(*(dp + 1), *(sp + 1), a,
+                           background->green);
+                        png_composite(*(dp + 2), *(sp + 2), a,
+                           background->blue);
+                     }
+                  }
+               }
+            }
+            else /* if (row_info->bit_depth == 16) */
+            {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
+                   gamma_16_to_1 != NULL)
+               {
+                  for (i = 0, sp = row, dp = row;
+                     i < row_info->width; i++, sp += 8, dp += 6)
+                  {
+                     png_uint_16 a;
+
+                     a = (png_uint_16)(((png_uint_16)(*(sp + 6)) << 8) +
+                         (png_uint_16)(*(sp + 7)));
+                     if (a == (png_uint_16)0xffff)
+                     {
+                        png_uint_16 v;
+
+                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+                        *dp = (png_byte)((v >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(v & 0xff);
+                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
+                        *(dp + 2) = (png_byte)((v >> 8) & 0xff);
+                        *(dp + 3) = (png_byte)(v & 0xff);
+                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
+                        *(dp + 4) = (png_byte)((v >> 8) & 0xff);
+                        *(dp + 5) = (png_byte)(v & 0xff);
+                     }
+                     else if (a == 0)
+                     {
+                        /* background is already in screen gamma */
+                        *dp = (png_byte)((background->red >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(background->red & 0xff);
+                        *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
+                        *(dp + 3) = (png_byte)(background->green & 0xff);
+                        *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
+                        *(dp + 5) = (png_byte)(background->blue & 0xff);
+                     }
+                     else
+                     {
+                        png_uint_16 v, w, x;
+
+                        v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
+                        png_composite_16(w, v, a, background->red);
+                        x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
+                        *dp = (png_byte)((x >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(x & 0xff);
+                        v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
+                        png_composite_16(w, v, a, background->green);
+                        x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
+                        *(dp + 2) = (png_byte)((x >> 8) & 0xff);
+                        *(dp + 3) = (png_byte)(x & 0xff);
+                        v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
+                        png_composite_16(w, v, a, background->blue);
+                        x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8];
+                        *(dp + 4) = (png_byte)((x >> 8) & 0xff);
+                        *(dp + 5) = (png_byte)(x & 0xff);
+                     }
+                  }
+               }
+               else
+#endif
+               {
+                  for (i = 0, sp = row, dp = row;
+                     i < row_info->width; i++, sp += 8, dp += 6)
+                  {
+                     png_uint_16 a;
+
+                     a = (png_uint_16)(((png_uint_16)(*(sp + 6)) << 8) +
+                        (png_uint_16)(*(sp + 7)));
+                     if (a == (png_uint_16)0xffff)
+                     {
+                        png_memcpy(dp, sp, 6);
+                     }
+                     else if (a == 0)
+                     {
+                        *dp = (png_byte)((background->red >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(background->red & 0xff);
+                        *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
+                        *(dp + 3) = (png_byte)(background->green & 0xff);
+                        *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
+                        *(dp + 5) = (png_byte)(background->blue & 0xff);
+                     }
+                     else
+                     {
+                        png_uint_16 r, g, b, v;
+
+                        r = ((png_uint_16)(*sp) << 8) + *(sp + 1);
+                        g = ((png_uint_16)(*(sp + 2)) << 8) + *(sp + 3);
+                        b = ((png_uint_16)(*(sp + 4)) << 8) + *(sp + 5);
+
+                        png_composite_16(v, r, a, background->red);
+                        *dp = (png_byte)((v >> 8) & 0xff);
+                        *(dp + 1) = (png_byte)(v & 0xff);
+                        png_composite_16(v, g, a, background->green);
+                        *(dp + 2) = (png_byte)((v >> 8) & 0xff);
+                        *(dp + 3) = (png_byte)(v & 0xff);
+                        png_composite_16(v, b, a, background->blue);
+                        *(dp + 4) = (png_byte)((v >> 8) & 0xff);
+                        *(dp + 5) = (png_byte)(v & 0xff);
+                     }
+                  }
+               }
+            }
+            break;
+         }
+      }
+
+      if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
+      {
+         row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
+         row_info->channels--;
+         row_info->pixel_depth = (png_byte)(row_info->channels *
+            row_info->bit_depth);
+         row_info->rowbytes = ((row_info->width *
+            row_info->pixel_depth + 7) >> 3);
+      }
+   }
+}
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+/* Gamma correct the image, avoiding the alpha channel.  Make sure
+ * you do this after you deal with the trasparency issue on grayscale
+ * or rgb images. If your bit depth is 8, use gamma_table, if it
+ * is 16, use gamma_16_table and gamma_shift.  Build these with
+ * build_gamma_table().
+ */
+void
+png_do_gamma(png_row_infop row_info, png_bytep row,
+   png_bytep gamma_table, png_uint_16pp gamma_16_table,
+   int gamma_shift)
+{
+   png_bytep sp;
+   png_uint_32 i;
+
+   png_debug(1, "in png_do_gamma\n");
+   if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL && row_info != NULL &&
+#endif
+       ((row_info->bit_depth <= 8 && gamma_table != NULL) ||
+        (row_info->bit_depth == 16 && gamma_16_table != NULL)))
+   {
+      switch (row_info->color_type)
+      {
+         case PNG_COLOR_TYPE_RGB:
+         {
+            if (row_info->bit_depth == 8)
+            {
+               for (i = 0, sp = row; i < row_info->width; i++)
+               {
+                  *sp = gamma_table[*sp];
+                  sp++;
+                  *sp = gamma_table[*sp];
+                  sp++;
+                  *sp = gamma_table[*sp];
+                  sp++;
+               }
+            }
+            else /* if (row_info->bit_depth == 16) */
+            {
+               for (i = 0, sp = row; i < row_info->width; i++)
+               {
+                  png_uint_16 v;
+
+                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 2;
+                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 2;
+                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 2;
+               }
+            }
+            break;
+         }
+         case PNG_COLOR_TYPE_RGB_ALPHA:
+         {
+            if (row_info->bit_depth == 8)
+            {
+               for (i = 0, sp = row;
+                  i < row_info->width; i++)
+               {
+                  *sp = gamma_table[*sp];
+                  sp++;
+                  *sp = gamma_table[*sp];
+                  sp++;
+                  *sp = gamma_table[*sp];
+                  sp++;
+                  sp++;
+               }
+            }
+            else /* if (row_info->bit_depth == 16) */
+            {
+               for (i = 0, sp = row;
+                  i < row_info->width; i++)
+               {
+                  png_uint_16 v;
+
+                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 2;
+                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 2;
+                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 4;
+               }
+            }
+            break;
+         }
+         case PNG_COLOR_TYPE_GRAY_ALPHA:
+         {
+            if (row_info->bit_depth == 8)
+            {
+               for (i = 0, sp = row;
+                  i < row_info->width; i++)
+               {
+                  *sp = gamma_table[*sp];
+                  sp += 2;
+               }
+            }
+            else /* if (row_info->bit_depth == 16) */
+            {
+               for (i = 0, sp = row;
+                  i < row_info->width; i++)
+               {
+                  png_uint_16 v;
+
+                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 4;
+               }
+            }
+            break;
+         }
+         case PNG_COLOR_TYPE_GRAY:
+         {
+            if (row_info->bit_depth == 2)
+            {
+               for (i = 0, sp = row; i < row_info->width; i += 4)
+               {
+                  int a = *sp & 0xc0;
+                  int b = *sp & 0x30;
+                  int c = *sp & 0x0c;
+                  int d = *sp & 0x03;
+
+                  *sp = ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)])   ) & 0xc0)|
+                        ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
+                        ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
+                        ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6)       );
+                  sp++;
+               }
+            }
+            if (row_info->bit_depth == 4)
+            {
+               for (i = 0, sp = row; i < row_info->width; i += 2)
+               {
+                  int msb = *sp & 0xf0;
+                  int lsb = *sp & 0x0f;
+
+                  *sp = (((int)gamma_table[msb | (msb >> 4)]) & 0xf0) |
+                        (((int)gamma_table[(lsb << 4) | lsb]) >> 4);
+                  sp++;
+               }
+            }
+            else if (row_info->bit_depth == 8)
+            {
+               for (i = 0, sp = row; i < row_info->width; i++)
+               {
+                  *sp = gamma_table[*sp];
+                  sp++;
+               }
+            }
+            else if (row_info->bit_depth == 16)
+            {
+               for (i = 0, sp = row; i < row_info->width; i++)
+               {
+                  png_uint_16 v;
+
+                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+                  *sp = (png_byte)((v >> 8) & 0xff);
+                  *(sp + 1) = (png_byte)(v & 0xff);
+                  sp += 2;
+               }
+            }
+            break;
+         }
+      }
+   }
+}
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+/* Expands a palette row to an rgb or rgba row depending
+ * upon whether you supply trans and num_trans.
+ */
+void
+png_do_expand_palette(png_row_infop row_info, png_bytep row,
+   png_colorp palette, png_bytep trans, int num_trans)
+{
+   int shift, value;
+   png_bytep sp, dp;
+   png_uint_32 i;
+
+   png_debug(1, "in png_do_expand_palette\n");
+   if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL && row_info != NULL &&
+#endif
+       row_info->color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      if (row_info->bit_depth < 8)
+      {
+         switch (row_info->bit_depth)
+         {
+            case 1:
+            {
+               sp = row + (png_size_t)((row_info->width - 1) >> 3);
+               dp = row + (png_size_t)row_info->width - 1;
+               shift = 7 - (int)((row_info->width + 7) & 7);
+               for (i = 0; i < row_info->width; i++)
+               {
+                  if ((*sp >> shift) & 0x1)
+                     *dp = 1;
+                  else
+                     *dp = 0;
+                  if (shift == 7)
+                  {
+                     shift = 0;
+                     sp--;
+                  }
+                  else
+                     shift++;
+
+                  dp--;
+               }
+               break;
+            }
+            case 2:
+            {
+               sp = row + (png_size_t)((row_info->width - 1) >> 2);
+               dp = row + (png_size_t)row_info->width - 1;
+               shift = (int)((3 - ((row_info->width + 3) & 3)) << 1);
+               for (i = 0; i < row_info->width; i++)
+               {
+                  value = (*sp >> shift) & 0x3;
+                  *dp = (png_byte)value;
+                  if (shift == 6)
+                  {
+                     shift = 0;
+                     sp--;
+                  }
+                  else
+                     shift += 2;
+
+                  dp--;
+               }
+               break;
+            }
+            case 4:
+            {
+               sp = row + (png_size_t)((row_info->width - 1) >> 1);
+               dp = row + (png_size_t)row_info->width - 1;
+               shift = (int)((row_info->width & 1) << 2);
+               for (i = 0; i < row_info->width; i++)
+               {
+                  value = (*sp >> shift) & 0xf;
+                  *dp = (png_byte)value;
+                  if (shift == 4)
+                  {
+                     shift = 0;
+                     sp--;
+                  }
+                  else
+                     shift += 4;
+
+                  dp--;
+               }
+               break;
+            }
+         }
+         row_info->bit_depth = 8;
+         row_info->pixel_depth = 8;
+         row_info->rowbytes = row_info->width;
+      }
+      switch (row_info->bit_depth)
+      {
+         case 8:
+         {
+            if (trans != NULL)
+            {
+               sp = row + (png_size_t)row_info->width - 1;
+               dp = row + (png_size_t)(row_info->width << 2) - 1;
+
+               for (i = 0; i < row_info->width; i++)
+               {
+                  if ((int)(*sp) >= num_trans)
+                     *dp-- = 0xff;
+                  else
+                     *dp-- = trans[*sp];
+                  *dp-- = palette[*sp].blue;
+                  *dp-- = palette[*sp].green;
+                  *dp-- = palette[*sp].red;
+                  sp--;
+               }
+               row_info->bit_depth = 8;
+               row_info->pixel_depth = 32;
+               row_info->rowbytes = row_info->width * 4;
+               row_info->color_type = 6;
+               row_info->channels = 4;
+            }
+            else
+            {
+               sp = row + (png_size_t)row_info->width - 1;
+               dp = row + (png_size_t)(row_info->width * 3) - 1;
+
+               for (i = 0; i < row_info->width; i++)
+               {
+                  *dp-- = palette[*sp].blue;
+                  *dp-- = palette[*sp].green;
+                  *dp-- = palette[*sp].red;
+                  sp--;
+               }
+               row_info->bit_depth = 8;
+               row_info->pixel_depth = 24;
+               row_info->rowbytes = row_info->width * 3;
+               row_info->color_type = 2;
+               row_info->channels = 3;
+            }
+            break;
+         }
+      }
+   }
+}
+
+/* If the bit depth < 8, it is expanded to 8.  Also, if the
+ * transparency value is supplied, an alpha channel is built.
+ */
+void
+png_do_expand(png_row_infop row_info, png_bytep row,
+   png_color_16p trans_value)
+{
+   int shift, value;
+   png_bytep sp, dp;
+   png_uint_32 i;
+
+   png_debug(1, "in png_do_expand\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+   if (row != NULL && row_info != NULL)
+#endif
+   {
+      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+      {
+         png_uint_16 gray = trans_value ? trans_value->gray : 0;
+
+         if (row_info->bit_depth < 8)
+         {
+            switch (row_info->bit_depth)
+            {
+               case 1:
+               {
+                  gray *= 0xff;
+                  sp = row + (png_size_t)((row_info->width - 1) >> 3);
+                  dp = row + (png_size_t)row_info->width - 1;
+                  shift = 7 - (int)((row_info->width + 7) & 7);
+                  for (i = 0; i < row_info->width; i++)
+                  {
+                     if ((*sp >> shift) & 0x1)
+                        *dp = 0xff;
+                     else
+                        *dp = 0;
+                     if (shift == 7)
+                     {
+                        shift = 0;
+                        sp--;
+                     }
+                     else
+                        shift++;
+
+                     dp--;
+                  }
+                  break;
+               }
+               case 2:
+               {
+                  gray *= 0x55;
+                  sp = row + (png_size_t)((row_info->width - 1) >> 2);
+                  dp = row + (png_size_t)row_info->width - 1;
+                  shift = (int)((3 - ((row_info->width + 3) & 3)) << 1);
+                  for (i = 0; i < row_info->width; i++)
+                  {
+                     value = (*sp >> shift) & 0x3;
+                     *dp = (png_byte)(value | (value << 2) | (value << 4) |
+                        (value << 6));
+                     if (shift == 6)
+                     {
+                        shift = 0;
+                        sp--;
+                     }
+                     else
+                        shift += 2;
+
+                     dp--;
+                  }
+                  break;
+               }
+               case 4:
+               {
+                  gray *= 0x11;
+                  sp = row + (png_size_t)((row_info->width - 1) >> 1);
+                  dp = row + (png_size_t)row_info->width - 1;
+                  shift = (int)((1 - ((row_info->width + 1) & 1)) << 2);
+                  for (i = 0; i < row_info->width; i++)
+                  {
+                     value = (*sp >> shift) & 0xf;
+                     *dp = (png_byte)(value | (value << 4));
+                     if (shift == 4)
+                     {
+                        shift = 0;
+                        sp--;
+                     }
+                     else
+                        shift = 4;
+
+                     dp--;
+                  }
+                  break;
+               }
+            }
+            row_info->bit_depth = 8;
+            row_info->pixel_depth = 8;
+            row_info->rowbytes = row_info->width;
+         }
+
+         if (trans_value != NULL)
+         {
+            if (row_info->bit_depth == 8)
+            {
+               sp = row + (png_size_t)row_info->width - 1;
+               dp = row + (png_size_t)(row_info->width << 1) - 1;
+               for (i = 0; i < row_info->width; i++)
+               {
+                  if (*sp == gray)
+                     *dp-- = 0;
+                  else
+                     *dp-- = 0xff;
+                  *dp-- = *sp--;
+               }
+            }
+            else if (row_info->bit_depth == 16)
+            {
+               sp = row + row_info->rowbytes - 1;
+               dp = row + (row_info->rowbytes << 1) - 1;
+               for (i = 0; i < row_info->width; i++)
+               {
+                  if (((png_uint_16)*(sp) |
+                     ((png_uint_16)*(sp - 1) << 8)) == gray)
+                  {
+                     *dp-- = 0;
+                     *dp-- = 0;
+                  }
+                  else
+                  {
+                     *dp-- = 0xff;
+                     *dp-- = 0xff;
+                  }
+                  *dp-- = *sp--;
+                  *dp-- = *sp--;
+               }
+            }
+            row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
+            row_info->channels = 2;
+            row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
+            row_info->rowbytes =
+               ((row_info->width * row_info->pixel_depth) >> 3);
+         }
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
+      {
+         if (row_info->bit_depth == 8)
+         {
+            sp = row + (png_size_t)row_info->rowbytes - 1;
+            dp = row + (png_size_t)(row_info->width << 2) - 1;
+            for (i = 0; i < row_info->width; i++)
+            {
+               if (*(sp - 2) == trans_value->red &&
+                  *(sp - 1) == trans_value->green &&
+                  *(sp - 0) == trans_value->blue)
+                  *dp-- = 0;
+               else
+                  *dp-- = 0xff;
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+            }
+         }
+         else if (row_info->bit_depth == 16)
+         {
+            sp = row + row_info->rowbytes - 1;
+            dp = row + (png_size_t)(row_info->width << 3) - 1;
+            for (i = 0; i < row_info->width; i++)
+            {
+               if ((((png_uint_16)*(sp - 4) |
+                  ((png_uint_16)*(sp - 5) << 8)) == trans_value->red) &&
+                  (((png_uint_16)*(sp - 2) |
+                  ((png_uint_16)*(sp - 3) << 8)) == trans_value->green) &&
+                  (((png_uint_16)*(sp - 0) |
+                  ((png_uint_16)*(sp - 1) << 8)) == trans_value->blue))
+               {
+                  *dp-- = 0;
+                  *dp-- = 0;
+               }
+               else
+               {
+                  *dp-- = 0xff;
+                  *dp-- = 0xff;
+               }
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+               *dp-- = *sp--;
+            }
+         }
+         row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+         row_info->channels = 4;
+         row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
+         row_info->rowbytes =
+            ((row_info->width * row_info->pixel_depth) >> 3);
+      }
+   }
+}
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+void
+png_do_dither(png_row_infop row_info, png_bytep row,
+    png_bytep palette_lookup, png_bytep dither_lookup)
+{
+   png_bytep sp, dp;
+   png_uint_32 i;
+
+   png_debug(1, "in png_do_dither\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+   if (row != NULL && row_info != NULL)
+#endif
+   {
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
+         palette_lookup && row_info->bit_depth == 8)
+      {
+         int r, g, b, p;
+         sp = row;
+         dp = row;
+         for (i = 0; i < row_info->width; i++)
+         {
+            r = *sp++;
+            g = *sp++;
+            b = *sp++;
+
+            /* this looks real messy, but the compiler will reduce
+               it down to a reasonable formula.  For example, with
+               5 bits per color, we get:
+               p = (((r >> 3) & 0x1f) << 10) |
+                  (((g >> 3) & 0x1f) << 5) |
+                  ((b >> 3) & 0x1f);
+               */
+            p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
+               ((1 << PNG_DITHER_RED_BITS) - 1)) <<
+               (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
+               (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
+               ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
+               (PNG_DITHER_BLUE_BITS)) |
+               ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
+               ((1 << PNG_DITHER_BLUE_BITS) - 1));
+
+            *dp++ = palette_lookup[p];
+         }
+         row_info->color_type = PNG_COLOR_TYPE_PALETTE;
+         row_info->channels = 1;
+         row_info->pixel_depth = row_info->bit_depth;
+         row_info->rowbytes =
+             ((row_info->width * row_info->pixel_depth + 7) >> 3);
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
+         palette_lookup != NULL && row_info->bit_depth == 8)
+      {
+         int r, g, b, p;
+         sp = row;
+         dp = row;
+         for (i = 0; i < row_info->width; i++)
+         {
+            r = *sp++;
+            g = *sp++;
+            b = *sp++;
+            sp++;
+
+            p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
+               ((1 << PNG_DITHER_RED_BITS) - 1)) <<
+               (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
+               (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
+               ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
+               (PNG_DITHER_BLUE_BITS)) |
+               ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
+               ((1 << PNG_DITHER_BLUE_BITS) - 1));
+
+            *dp++ = palette_lookup[p];
+         }
+         row_info->color_type = PNG_COLOR_TYPE_PALETTE;
+         row_info->channels = 1;
+         row_info->pixel_depth = row_info->bit_depth;
+         row_info->rowbytes =
+            ((row_info->width * row_info->pixel_depth + 7) >> 3);
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
+         dither_lookup && row_info->bit_depth == 8)
+      {
+         sp = row;
+         for (i = 0; i < row_info->width; i++, sp++)
+         {
+            *sp = dither_lookup[*sp];
+         }
+      }
+   }
+}
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+static int png_gamma_shift[] =
+   {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0};
+
+/* We build the 8- or 16-bit gamma tables here.  Note that for 16-bit
+ * tables, we don't make a full table if we are reducing to 8-bit in
+ * the future.  Note also how the gamma_16 tables are segmented so that
+ * we don't need to allocate > 64K chunks for a full 16-bit table.
+ */
+void
+png_build_gamma_table(png_structp png_ptr)
+{
+   png_debug(1, "in png_build_gamma_table\n");
+   if (png_ptr->bit_depth <= 8)
+   {
+      int i;
+      double g;
+
+      g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
+
+      png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr,
+         (png_uint_32)256);
+
+      for (i = 0; i < 256; i++)
+      {
+         png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0,
+            g) * 255.0 + .5);
+      }
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+      if (png_ptr->transformations & PNG_BACKGROUND)
+      {
+         g = 1.0 / (png_ptr->gamma);
+
+         png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr,
+            (png_uint_32)256);
+
+         for (i = 0; i < 256; i++)
+         {
+            png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0,
+               g) * 255.0 + .5);
+         }
+
+         g = 1.0 / (png_ptr->screen_gamma);
+
+         png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr,
+            (png_uint_32)256);
+
+         for (i = 0; i < 256; i++)
+         {
+            png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0,
+               g) * 255.0 + .5);
+         }
+      }
+#endif /* PNG_BACKGROUND_SUPPORTED */
+   }
+   else
+   {
+      double g;
+      int i, j, shift, num;
+      int sig_bit;
+      png_uint_32 ig;
+
+      if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
+      {
+         sig_bit = (int)png_ptr->sig_bit.red;
+         if ((int)png_ptr->sig_bit.green > sig_bit)
+            sig_bit = png_ptr->sig_bit.green;
+         if ((int)png_ptr->sig_bit.blue > sig_bit)
+            sig_bit = png_ptr->sig_bit.blue;
+      }
+      else
+      {
+         sig_bit = (int)png_ptr->sig_bit.gray;
+      }
+
+      if (sig_bit > 0)
+         shift = 16 - sig_bit;
+      else
+         shift = 0;
+
+      if (png_ptr->transformations & PNG_16_TO_8)
+      {
+         if (shift < (16 - PNG_MAX_GAMMA_8))
+            shift = (16 - PNG_MAX_GAMMA_8);
+      }
+
+      if (shift > 8)
+         shift = 8;
+      if (shift < 0)
+         shift = 0;
+
+      png_ptr->gamma_shift = (png_byte)shift;
+
+      num = (1 << (8 - shift));
+
+      g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
+
+      png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr,
+         (png_uint_32)(num * sizeof (png_uint_16p)));
+
+      if ((png_ptr->transformations & PNG_16_TO_8) &&
+         !(png_ptr->transformations & PNG_BACKGROUND))
+      {
+         double fin, fout;
+         png_uint_32 last, max;
+
+         for (i = 0; i < num; i++)
+         {
+            png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
+               (png_uint_32)(256 * sizeof (png_uint_16)));
+         }
+
+         g = 1.0 / g;
+         last = 0;
+         for (i = 0; i < 256; i++)
+         {
+            fout = ((double)i + 0.5) / 256.0;
+            fin = pow(fout, g);
+            max = (png_uint_32)(fin * (double)((png_uint_32)num << 8));
+            while (last <= max)
+            {
+               png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
+                  [(int)(last >> (8 - shift))] = (png_uint_16)(
+                  (png_uint_16)i | ((png_uint_16)i << 8));
+               last++;
+            }
+         }
+         while (last < ((png_uint_32)num << 8))
+         {
+            png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
+               [(int)(last >> (8 - shift))] = (png_uint_16)65535L;
+            last++;
+         }
+      }
+      else
+      {
+         for (i = 0; i < num; i++)
+         {
+            png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
+               (png_uint_32)(256 * sizeof (png_uint_16)));
+
+            ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4);
+            for (j = 0; j < 256; j++)
+            {
+               png_ptr->gamma_16_table[i][j] =
+                  (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
+                     65535.0, g) * 65535.0 + .5);
+            }
+         }
+      }
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+      if (png_ptr->transformations & PNG_BACKGROUND)
+      {
+         g = 1.0 / (png_ptr->gamma);
+
+         png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr,
+            (png_uint_32)(num * sizeof (png_uint_16p )));
+
+         for (i = 0; i < num; i++)
+         {
+            png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr,
+               (png_uint_32)(256 * sizeof (png_uint_16)));
+
+            ig = (((png_uint_32)i *
+               (png_uint_32)png_gamma_shift[shift]) >> 4);
+            for (j = 0; j < 256; j++)
+            {
+               png_ptr->gamma_16_to_1[i][j] =
+                  (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
+                     65535.0, g) * 65535.0 + .5);
+            }
+         }
+         g = 1.0 / (png_ptr->screen_gamma);
+
+         png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr,
+            (png_uint_32)(num * sizeof (png_uint_16p)));
+
+         for (i = 0; i < num; i++)
+         {
+            png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr,
+               (png_uint_32)(256 * sizeof (png_uint_16)));
+
+            ig = (((png_uint_32)i *
+               (png_uint_32)png_gamma_shift[shift]) >> 4);
+            for (j = 0; j < 256; j++)
+            {
+               png_ptr->gamma_16_from_1[i][j] =
+                  (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
+                     65535.0, g) * 65535.0 + .5);
+            }
+         }
+      }
+#endif /* PNG_BACKGROUND_SUPPORTED */
+   }
+}
+#endif
+
diff --git a/src/png/pngrutil.c b/src/png/pngrutil.c
new file mode 100644
index 0000000000..1c37906939
--- /dev/null
+++ b/src/png/pngrutil.c
@@ -0,0 +1,2245 @@
+
+/* pngrutil.c - utilities to read a PNG file
+ *
+ * libpng 1.0.1
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Copyright (c) 1998, Glenn Randers-Pehrson
+ * March 15, 1998
+ *
+ * This file contains routines which are only called from within
+ * libpng itself during the course of reading an image.
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
+/* Grab an unsigned 32-bit integer from a buffer in big endian format. */
+png_uint_32
+png_get_uint_32(png_bytep buf)
+{
+   png_uint_32 i;
+
+   i = ((png_uint_32)(*buf) << 24) +
+      ((png_uint_32)(*(buf + 1)) << 16) +
+      ((png_uint_32)(*(buf + 2)) << 8) +
+      (png_uint_32)(*(buf + 3));
+
+   return (i);
+}
+
+#if defined(PNG_READ_pCAL_SUPPORTED)
+/* Grab a signed 32-bit integer from a buffer in big endian format.  The
+ * data is stored in the PNG file in two's complement format, and it is
+ * assumed that the machine format for signed integers is the same. */
+png_int_32
+png_get_int_32(png_bytep buf)
+{
+   png_int_32 i;
+
+   i = ((png_int_32)(*buf) << 24) +
+      ((png_int_32)(*(buf + 1)) << 16) +
+      ((png_int_32)(*(buf + 2)) << 8) +
+      (png_int_32)(*(buf + 3));
+
+   return (i);
+}
+#endif /* PNG_READ_pCAL_SUPPORTED */
+
+/* Grab an unsigned 16-bit integer from a buffer in big endian format. */
+png_uint_16
+png_get_uint_16(png_bytep buf)
+{
+   png_uint_16 i;
+
+   i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
+      (png_uint_16)(*(buf + 1)));
+
+   return (i);
+}
+#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
+
+/* Read data, and (optionally) run it through the CRC. */
+void
+png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
+{
+   png_read_data(png_ptr, buf, length);
+   png_calculate_crc(png_ptr, buf, length);
+}
+
+/* Optionally skip data and then check the CRC.  Depending on whether we
+   are reading a ancillary or critical chunk, and how the program has set
+   things up, we may calculate the CRC on the data and print a message.
+   Returns '1' if there was a CRC error, '0' otherwise. */
+int
+png_crc_finish(png_structp png_ptr, png_uint_32 skip)
+{
+   png_uint_32 i;
+
+   for (i = skip; i > (png_uint_32)png_ptr->zbuf_size; i -= png_ptr->zbuf_size)
+   {
+      png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
+   }
+   if (i)
+   {
+      png_crc_read(png_ptr, png_ptr->zbuf, (png_size_t)i);
+   }
+
+   if (png_crc_error(png_ptr))
+   {
+      if ((png_ptr->chunk_name[0] & 0x20 &&                /* Ancillary */
+           !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
+          (!(png_ptr->chunk_name[0] & 0x20) &&             /* Critical  */
+           png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))
+      {
+         png_chunk_warning(png_ptr, "CRC error");
+      }
+      else
+      {
+         png_chunk_error(png_ptr, "CRC error");
+      }
+      return (1);
+   }
+
+   return (0);
+}
+
+/* Compare the CRC stored in the PNG file with that calculated by libpng from
+   the data it has read thus far. */
+int
+png_crc_error(png_structp png_ptr)
+{
+   png_byte crc_bytes[4];
+   png_uint_32 crc;
+   int need_crc = 1;
+
+   if (png_ptr->chunk_name[0] & 0x20)                     /* ancillary */
+   {
+      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
+          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
+         need_crc = 0;
+   }
+   else                                                    /* critical */
+   {
+      if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
+         need_crc = 0;
+   }
+
+   png_read_data(png_ptr, crc_bytes, 4);
+
+   if (need_crc)
+   {
+      crc = png_get_uint_32(crc_bytes);
+      return ((int)(crc != png_ptr->crc));
+   }
+   else
+      return (0);
+}
+
+
+/* read and check the IDHR chunk */
+void
+png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_byte buf[13];
+   png_uint_32 width, height;
+   int bit_depth, color_type, compression_type, filter_type;
+   int interlace_type;
+
+   png_debug(1, "in png_handle_IHDR\n");
+
+   if (png_ptr->mode != PNG_BEFORE_IHDR)
+      png_error(png_ptr, "Out of place IHDR");
+
+   /* check the length */
+   if (length != 13)
+      png_error(png_ptr, "Invalid IHDR chunk");
+
+   png_ptr->mode |= PNG_HAVE_IHDR;
+
+   png_crc_read(png_ptr, buf, 13);
+   png_crc_finish(png_ptr, 0);
+
+   width = png_get_uint_32(buf);
+   height = png_get_uint_32(buf + 4);
+   bit_depth = buf[8];
+   color_type = buf[9];
+   compression_type = buf[10];
+   filter_type = buf[11];
+   interlace_type = buf[12];
+
+   /* check for width and height valid values */
+   if (width == 0 || width > (png_uint_32)2147483647L || height == 0 ||
+        height > (png_uint_32)2147483647L)
+      png_error(png_ptr, "Invalid image size in IHDR");
+
+   /* check other values */
+   if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
+      bit_depth != 8 && bit_depth != 16)
+      png_error(png_ptr, "Invalid bit depth in IHDR");
+
+   if (color_type < 0 || color_type == 1 ||
+      color_type == 5 || color_type > 6)
+      png_error(png_ptr, "Invalid color type in IHDR");
+
+   if ((color_type == PNG_COLOR_TYPE_PALETTE && bit_depth) > 8 ||
+       ((color_type == PNG_COLOR_TYPE_RGB ||
+         color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
+         color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
+      png_error(png_ptr, "Invalid color type/bit depth combination in IHDR");
+
+   if (interlace_type >= PNG_INTERLACE_LAST)
+      png_error(png_ptr, "Unknown interlace method in IHDR");
+
+   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+      png_error(png_ptr, "Unknown compression method in IHDR");
+
+   if (filter_type != PNG_FILTER_TYPE_BASE)
+      png_error(png_ptr, "Unknown filter method in IHDR");
+
+   /* set internal variables */
+   png_ptr->width = width;
+   png_ptr->height = height;
+   png_ptr->bit_depth = (png_byte)bit_depth;
+   png_ptr->interlaced = (png_byte)interlace_type;
+   png_ptr->color_type = (png_byte)color_type;
+
+   /* find number of channels */
+   switch (png_ptr->color_type)
+   {
+      case PNG_COLOR_TYPE_GRAY:
+      case PNG_COLOR_TYPE_PALETTE:
+         png_ptr->channels = 1;
+         break;
+      case PNG_COLOR_TYPE_RGB:
+         png_ptr->channels = 3;
+         break;
+      case PNG_COLOR_TYPE_GRAY_ALPHA:
+         png_ptr->channels = 2;
+         break;
+      case PNG_COLOR_TYPE_RGB_ALPHA:
+         png_ptr->channels = 4;
+         break;
+   }
+
+   /* set up other useful info */
+   png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
+   png_ptr->channels);
+   png_ptr->rowbytes = ((png_ptr->width *
+      (png_uint_32)png_ptr->pixel_depth + 7) >> 3);
+   png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth);
+   png_debug1(3,"channels = %d\n", png_ptr->channels);
+   png_debug1(3,"rowbytes = %d\n", png_ptr->rowbytes);
+   png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
+      color_type, interlace_type, compression_type, filter_type);
+}
+
+/* read and check the palette */
+void
+png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_colorp palette;
+   int num, i;
+
+   png_debug(1, "in png_handle_PLTE\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before PLTE");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid PLTE after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (png_ptr->mode & PNG_HAVE_PLTE)
+      png_error(png_ptr, "Duplicate PLTE chunk");
+
+   png_ptr->mode |= PNG_HAVE_PLTE;
+
+#if defined (PNG_READ_tRNS_SUPPORTED)
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      if (info_ptr != NULL && info_ptr->valid & PNG_INFO_tRNS)
+      {
+         if (png_ptr->num_trans > png_ptr->num_palette)
+         {
+            png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
+            png_ptr->num_trans = png_ptr->num_palette;
+         }
+      }
+   }
+#endif
+
+#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
+   if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
+   {
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+#endif
+
+   if (length % 3)
+   {
+      if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
+      {
+         png_warning(png_ptr, "Invalid palette chunk");
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+      else
+      {
+         png_error(png_ptr, "Invalid palette chunk");
+      }
+   }
+
+   num = (int)length / 3;
+   palette = (png_colorp)png_zalloc(png_ptr, (uInt)num, sizeof (png_color));
+   png_ptr->flags |= PNG_FLAG_FREE_PALETTE;
+   for (i = 0; i < num; i++)
+   {
+      png_byte buf[3];
+
+      png_crc_read(png_ptr, buf, 3);
+      /* don't depend upon png_color being any order */
+      palette[i].red = buf[0];
+      palette[i].green = buf[1];
+      palette[i].blue = buf[2];
+   }
+
+   /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
+      whatever the normal CRC configuration tells us.  However, if we
+      have an RGB image, the PLTE can be considered ancillary, so
+      we will act as though it is. */
+#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+#endif
+   {
+      png_crc_finish(png_ptr, 0);
+   }
+#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
+   else if (png_crc_error(png_ptr))  /* Only if we have a CRC error */
+   {
+      /* If we don't want to use the data from an ancillary chunk,
+         we have two options: an error abort, or a warning and we
+         ignore the data in this chunk (which should be OK, since
+         it's considered ancillary for a RGB or RGBA image). */
+      if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
+      {
+         if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
+         {
+            png_chunk_error(png_ptr, "CRC error");
+         }
+         else
+         {
+            png_chunk_warning(png_ptr, "CRC error");
+            png_ptr->flags &= ~PNG_FLAG_FREE_PALETTE;
+            png_zfree(png_ptr, palette);
+            return;
+         }
+      }
+      /* Otherwise, we (optionally) emit a warning and use the chunk. */
+      else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
+      {
+         png_chunk_warning(png_ptr, "CRC error");
+      }
+   }
+#endif
+   png_ptr->palette = palette;
+   png_ptr->num_palette = (png_uint_16)num;
+   png_set_PLTE(png_ptr, info_ptr, palette, num);
+}
+
+void
+png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_debug(1, "in png_handle_IEND\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
+   {
+      png_error(png_ptr, "No image in file");
+
+      /* to quiet compiler warnings about unused info_ptr */
+      if (info_ptr == NULL)
+         return;
+   }
+
+   png_ptr->mode |= PNG_AFTER_IDAT | PNG_HAVE_IEND;
+
+   if (length != 0)
+   {
+      png_warning(png_ptr, "Incorrect IEND chunk length");
+   }
+   png_crc_finish(png_ptr, length);
+}
+
+#if defined(PNG_READ_gAMA_SUPPORTED)
+void
+png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_uint_32 igamma;
+   float file_gamma;
+   png_byte buf[4];
+
+   png_debug(1, "in png_handle_gAMA\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before gAMA");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid gAMA after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (png_ptr->mode & PNG_HAVE_PLTE)
+      /* Should be an error, but we can cope with it */
+      png_warning(png_ptr, "Out of place gAMA chunk");
+
+   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_gAMA
+#if defined(PNG_READ_sRGB_SUPPORTED)
+      && !(info_ptr->valid & PNG_INFO_sRGB)
+#endif
+      )
+   {
+      png_warning(png_ptr, "Duplicate gAMA chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (length != 4)
+   {
+      png_warning(png_ptr, "Incorrect gAMA chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 4);
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   igamma = png_get_uint_32(buf);
+   /* check for zero gamma */
+   if (igamma == 0)
+      return;
+
+#if defined(PNG_READ_sRGB_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_sRGB)
+      if(igamma != (png_uint_32)45000L)
+      {
+         png_warning(png_ptr,
+           "Ignoring incorrect gAMA value when sRGB is also present");
+#ifndef PNG_NO_STDIO
+         fprintf(stderr, "igamma = %lu\n", igamma);
+#endif
+         return;
+      }
+#endif /* PNG_READ_sRGB_SUPPORTED */
+
+   file_gamma = (float)igamma / (float)100000.0;
+#ifdef PNG_READ_GAMMA_SUPPORTED
+   png_ptr->gamma = file_gamma;
+#endif
+   png_set_gAMA(png_ptr, info_ptr, file_gamma);
+}
+#endif
+
+#if defined(PNG_READ_sBIT_SUPPORTED)
+void
+png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_size_t truelen;
+   png_byte buf[4];
+
+   png_debug(1, "in png_handle_sBIT\n");
+
+   buf[0] = buf[1] = buf[2] = buf[3] = 0;
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before sBIT");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid sBIT after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (png_ptr->mode & PNG_HAVE_PLTE)
+   {
+      /* Should be an error, but we can cope with it */
+      png_warning(png_ptr, "Out of place sBIT chunk");
+   }
+   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_sBIT)
+   {
+      png_warning(png_ptr, "Duplicate sBIT chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      truelen = 3;
+   else
+      truelen = (png_size_t)png_ptr->channels;
+
+   if (length != truelen)
+   {
+      png_warning(png_ptr, "Incorrect sBIT chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, truelen);
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
+   {
+      png_ptr->sig_bit.red = buf[0];
+      png_ptr->sig_bit.green = buf[1];
+      png_ptr->sig_bit.blue = buf[2];
+      png_ptr->sig_bit.alpha = buf[3];
+   }
+   else
+   {
+      png_ptr->sig_bit.gray = buf[0];
+      png_ptr->sig_bit.alpha = buf[1];
+   }
+   png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
+}
+#endif
+
+#if defined(PNG_READ_cHRM_SUPPORTED)
+void
+png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_byte buf[4];
+   png_uint_32 val;
+   float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
+
+   png_debug(1, "in png_handle_cHRM\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before sBIT");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid cHRM after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (png_ptr->mode & PNG_HAVE_PLTE)
+      /* Should be an error, but we can cope with it */
+      png_warning(png_ptr, "Missing PLTE before cHRM");
+
+   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_cHRM
+#if defined(PNG_READ_sRGB_SUPPORTED)
+      && !(info_ptr->valid & PNG_INFO_sRGB)
+#endif
+      )
+   {
+      png_warning(png_ptr, "Duplicate cHRM chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (length != 32)
+   {
+      png_warning(png_ptr, "Incorrect cHRM chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 4);
+   val = png_get_uint_32(buf);
+   white_x = (float)val / (float)100000.0;
+
+   png_crc_read(png_ptr, buf, 4);
+   val = png_get_uint_32(buf);
+   white_y = (float)val / (float)100000.0;
+
+   if (white_x < 0 || white_x > 0.8 || white_y < 0 || white_y > 0.8 ||
+       white_x + white_y > 1.0)
+   {
+      png_warning(png_ptr, "Invalid cHRM white point");
+      png_crc_finish(png_ptr, 24);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 4);
+   val = png_get_uint_32(buf);
+   red_x = (float)val / (float)100000.0;
+
+   png_crc_read(png_ptr, buf, 4);
+   val = png_get_uint_32(buf);
+   red_y = (float)val / (float)100000.0;
+
+   if (red_x < 0 || red_x > 0.8 || red_y < 0 || red_y > 0.8 ||
+       red_x + red_y > 1.0)
+   {
+      png_warning(png_ptr, "Invalid cHRM red point");
+      png_crc_finish(png_ptr, 16);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 4);
+   val = png_get_uint_32(buf);
+   green_x = (float)val / (float)100000.0;
+
+   png_crc_read(png_ptr, buf, 4);
+   val = png_get_uint_32(buf);
+   green_y = (float)val / (float)100000.0;
+
+   if (green_x < 0 || green_x > 0.8 || green_y < 0 || green_y > 0.8 ||
+       green_x + green_y > 1.0)
+   {
+      png_warning(png_ptr, "Invalid cHRM green point");
+      png_crc_finish(png_ptr, 8);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 4);
+   val = png_get_uint_32(buf);
+   blue_x = (float)val / (float)100000.0;
+
+   png_crc_read(png_ptr, buf, 4);
+   val = png_get_uint_32(buf);
+   blue_y = (float)val / (float)100000.0;
+
+   if (blue_x < (float)0 || blue_x > (float)0.8 || blue_y < (float)0 ||
+       blue_y > (float)0.8 || blue_x + blue_y > (float)1.0)
+   {
+      png_warning(png_ptr, "Invalid cHRM blue point");
+      png_crc_finish(png_ptr, 0);
+      return;
+   }
+
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+#if defined(PNG_READ_sRGB_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_sRGB)
+      {
+      if (fabs(white_x - (float).3127) > (float).001 ||
+          fabs(white_y - (float).3290) > (float).001 ||
+          fabs(  red_x - (float).6400) > (float).001 ||
+          fabs(  red_y - (float).3300) > (float).001 ||
+          fabs(green_x - (float).3000) > (float).001 ||
+          fabs(green_y - (float).6000) > (float).001 ||
+          fabs( blue_x - (float).1500) > (float).001 ||
+          fabs( blue_y - (float).0600) > (float).001)
+         {
+
+            png_warning(png_ptr,
+              "Ignoring incorrect cHRM value when sRGB is also present");
+#ifndef PNG_NO_STDIO
+            fprintf(stderr,"wx=%f, wy=%f, rx=%f, ry=%f\n",
+               white_x, white_y, red_x, red_y);
+            fprintf(stderr,"gx=%f, gy=%f, bx=%f, by=%f\n",
+               green_x, green_y, blue_x, blue_y);
+#endif
+         }
+         return;
+      }
+#endif /* PNG_READ_sRGB_SUPPORTED */
+
+   png_set_cHRM(png_ptr, info_ptr,
+      white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
+}
+#endif
+
+#if defined(PNG_READ_sRGB_SUPPORTED)
+void
+png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   int intent;
+   png_byte buf[1];
+
+   png_debug(1, "in png_handle_sRGB\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before sRGB");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid sRGB after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (png_ptr->mode & PNG_HAVE_PLTE)
+      /* Should be an error, but we can cope with it */
+      png_warning(png_ptr, "Out of place sRGB chunk");
+
+   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_sRGB)
+   {
+      png_warning(png_ptr, "Duplicate sRGB chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (length != 1)
+   {
+      png_warning(png_ptr, "Incorrect sRGB chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 1);
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   intent = buf[0];
+   /* check for bad intent */
+   if (intent >= PNG_sRGB_INTENT_LAST)
+   {
+      png_warning(png_ptr, "Unknown sRGB intent");
+      return;
+   }
+
+#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
+   if ((info_ptr->valid & PNG_INFO_gAMA))
+      if((png_uint_32)(png_ptr->gamma*(float)100000.+.5) != (png_uint_32)45000L)
+      {
+         png_warning(png_ptr,
+           "Ignoring incorrect gAMA value when sRGB is also present");
+#ifndef PNG_NO_STDIO
+           fprintf(stderr,"gamma=%f\n",png_ptr->gamma);
+#endif
+      }
+#endif /* PNG_READ_gAMA_SUPPORTED */
+
+#ifdef PNG_READ_cHRM_SUPPORTED
+   if (info_ptr->valid & PNG_INFO_cHRM)
+      if (fabs(info_ptr->x_white - (float).3127) > (float).001 ||
+          fabs(info_ptr->y_white - (float).3290) > (float).001 ||
+          fabs(  info_ptr->x_red - (float).6400) > (float).001 ||
+          fabs(  info_ptr->y_red - (float).3300) > (float).001 ||
+          fabs(info_ptr->x_green - (float).3000) > (float).001 ||
+          fabs(info_ptr->y_green - (float).6000) > (float).001 ||
+          fabs( info_ptr->x_blue - (float).1500) > (float).001 ||
+          fabs( info_ptr->y_blue - (float).0600) > (float).001)
+         {
+            png_warning(png_ptr,
+              "Ignoring incorrect cHRM value when sRGB is also present");
+         }
+#endif /* PNG_READ_cHRM_SUPPORTED */
+
+   png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
+}
+#endif /* PNG_READ_sRGB_SUPPORTED */
+
+#if defined(PNG_READ_tRNS_SUPPORTED)
+void
+png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_debug(1, "in png_handle_tRNS\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before tRNS");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid tRNS after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_tRNS)
+   {
+      png_warning(png_ptr, "Duplicate tRNS chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      if (!(png_ptr->mode & PNG_HAVE_PLTE))
+      {
+         /* Should be an error, but we can cope with it */
+         png_warning(png_ptr, "Missing PLTE before tRNS");
+      }
+      else if (length > png_ptr->num_palette)
+      {
+         png_warning(png_ptr, "Incorrect tRNS chunk length");
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+
+      png_ptr->trans = (png_bytep)png_malloc(png_ptr, length);
+      png_ptr->flags |= PNG_FLAG_FREE_TRANS;
+      png_crc_read(png_ptr, png_ptr->trans, (png_size_t)length);
+      png_ptr->num_trans = (png_uint_16)length;
+   }
+   else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+   {
+      png_byte buf[6];
+
+      if (length != 6)
+      {
+         png_warning(png_ptr, "Incorrect tRNS chunk length");
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+
+      png_crc_read(png_ptr, buf, (png_size_t)length);
+      png_ptr->num_trans = 1;
+      png_ptr->trans_values.red = png_get_uint_16(buf);
+      png_ptr->trans_values.green = png_get_uint_16(buf + 2);
+      png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
+   }
+   else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+   {
+      png_byte buf[6];
+
+      if (length != 2)
+      {
+         png_warning(png_ptr, "Incorrect tRNS chunk length");
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+
+      png_crc_read(png_ptr, buf, 2);
+      png_ptr->num_trans = 1;
+      png_ptr->trans_values.gray = png_get_uint_16(buf);
+   }
+   else
+   {
+      png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   png_set_tRNS(png_ptr, info_ptr, png_ptr->trans, png_ptr->num_trans,
+      &(png_ptr->trans_values));
+}
+#endif
+
+#if defined(PNG_READ_bKGD_SUPPORTED)
+void
+png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_size_t truelen;
+   png_byte buf[6];
+
+   png_debug(1, "in png_handle_bKGD\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before bKGD");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid bKGD after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+            !(png_ptr->mode & PNG_HAVE_PLTE))
+   {
+      png_warning(png_ptr, "Missing PLTE before bKGD");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_bKGD)
+   {
+      png_warning(png_ptr, "Duplicate bKGD chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      truelen = 1;
+   else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
+      truelen = 6;
+   else
+      truelen = 2;
+
+   if (length != truelen)
+   {
+      png_warning(png_ptr, "Incorrect bKGD chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, truelen);
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   /* We convert the index value into RGB components so that we can allow
+    * arbitrary RGB values for background when we have transparency, and
+    * so it is easy to determine the RGB values of the background color
+    * from the info_ptr struct. */
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      png_ptr->background.index = buf[0];
+      png_ptr->background.red = (png_uint_16)png_ptr->palette[buf[0]].red;
+      png_ptr->background.green = (png_uint_16)png_ptr->palette[buf[0]].green;
+      png_ptr->background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue;
+   }
+   else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
+   {
+      png_ptr->background.red =
+      png_ptr->background.green =
+      png_ptr->background.blue =
+      png_ptr->background.gray = png_get_uint_16(buf);
+   }
+   else
+   {
+      png_ptr->background.red = png_get_uint_16(buf);
+      png_ptr->background.green = png_get_uint_16(buf + 2);
+      png_ptr->background.blue = png_get_uint_16(buf + 4);
+   }
+
+   png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
+}
+#endif
+
+#if defined(PNG_READ_hIST_SUPPORTED)
+void
+png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   int num, i;
+
+   png_debug(1, "in png_handle_hIST\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before hIST");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid hIST after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (!(png_ptr->mode & PNG_HAVE_PLTE))
+   {
+      png_warning(png_ptr, "Missing PLTE before hIST");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_hIST)
+   {
+      png_warning(png_ptr, "Duplicate hIST chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (length != (png_uint_32)(2 * png_ptr->num_palette))
+   {
+      png_warning(png_ptr, "Incorrect hIST chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   num = (int)length / 2;
+   png_ptr->hist = (png_uint_16p)png_malloc(png_ptr,
+      (png_uint_32)(num * sizeof (png_uint_16)));
+   png_ptr->flags |= PNG_FLAG_FREE_HIST;
+   for (i = 0; i < num; i++)
+   {
+      png_byte buf[2];
+
+      png_crc_read(png_ptr, buf, 2);
+      png_ptr->hist[i] = png_get_uint_16(buf);
+   }
+
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   png_set_hIST(png_ptr, info_ptr, png_ptr->hist);
+}
+#endif
+
+#if defined(PNG_READ_pHYs_SUPPORTED)
+void
+png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_byte buf[9];
+   png_uint_32 res_x, res_y;
+   int unit_type;
+
+   png_debug(1, "in png_handle_pHYs\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before pHYS");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid pHYS after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_pHYs)
+   {
+      png_warning(png_ptr, "Duplicate pHYS chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (length != 9)
+   {
+      png_warning(png_ptr, "Incorrect pHYs chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 9);
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   res_x = png_get_uint_32(buf);
+   res_y = png_get_uint_32(buf + 4);
+   unit_type = buf[8];
+   png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
+}
+#endif
+
+#if defined(PNG_READ_oFFs_SUPPORTED)
+void
+png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_byte buf[9];
+   png_uint_32 offset_x, offset_y;
+   int unit_type;
+
+   png_debug(1, "in png_handle_oFFs\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before oFFs");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid oFFs after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_oFFs)
+   {
+      png_warning(png_ptr, "Duplicate oFFs chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (length != 9)
+   {
+      png_warning(png_ptr, "Incorrect oFFs chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 9);
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   offset_x = png_get_uint_32(buf);
+   offset_y = png_get_uint_32(buf + 4);
+   unit_type = buf[8];
+   png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
+}
+#endif
+
+#if defined(PNG_READ_pCAL_SUPPORTED)
+/* read the pCAL chunk (png-scivis-19970203) */
+void
+png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_charp purpose;
+   png_int_32 X0, X1;
+   png_byte type, nparams;
+   png_charp buf, units, endptr;
+   png_charpp params;
+   png_size_t slength;
+   int i;
+
+   png_debug(1, "in png_handle_pCAL\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before pCAL");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid pCAL after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_pCAL)
+   {
+      png_warning(png_ptr, "Duplicate pCAL chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_debug1(2, "Allocating and reading pCAL chunk data (%d bytes)\n",
+      length + 1);
+   purpose = (png_charp)png_malloc(png_ptr, length + 1);
+   slength = (png_size_t)length;
+   png_crc_read(png_ptr, (png_bytep)purpose, slength);
+
+   if (png_crc_finish(png_ptr, 0))
+   {
+      png_free(png_ptr, purpose);
+      return;
+   }
+
+   purpose[slength] = 0x00; /* null terminate the last string */
+
+   png_debug(3, "Finding end of pCAL purpose string\n");
+   for (buf = purpose; *buf != '\0'; buf++)
+      /* empty loop */ ;
+
+   endptr = purpose + slength;
+
+   /* We need to have at least 12 bytes after the purpose string
+      in order to get the parameter information. */
+   if (endptr <= buf + 12)
+   {
+      png_warning(png_ptr, "Invalid pCAL data");
+      png_free(png_ptr, purpose);
+      return;
+   }
+
+   png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
+   X0 = png_get_int_32((png_bytep)buf+1);
+   X1 = png_get_int_32((png_bytep)buf+5);
+   type = buf[9];
+   nparams = buf[10];
+   units = buf + 11;
+
+   png_debug(3, "Checking pCAL equation type and number of parameters\n");
+   /* Check that we have the right number of parameters for known
+      equation types. */
+   if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
+       (type == PNG_EQUATION_BASE_E && nparams != 3) ||
+       (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
+       (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
+   {
+      png_warning(png_ptr, "Invalid pCAL parameters for equation type");
+      png_free(png_ptr, purpose);
+      return;
+   }
+   else if (type >= PNG_EQUATION_LAST)
+   {
+      png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
+   }
+
+   for (buf = units; *buf != 0x00; buf++)
+      /* Empty loop to move past the units string. */ ;
+
+   png_debug(3, "Allocating pCAL parameters array\n");
+   params = (png_charpp)png_malloc(png_ptr, (png_uint_32)(nparams
+      *sizeof(png_charp))) ;
+
+   /* Get pointers to the start of each parameter string. */
+   for (i = 0; i < (int)nparams; i++)
+   {
+      buf++; /* Skip the null string terminator from previous parameter. */
+
+      png_debug1(3, "Reading pCAL parameter %d\n", i);
+      for (params[i] = buf; *buf != 0x00 && buf <= endptr; buf++)
+         /* Empty loop to move past each parameter string */ ;
+
+      /* Make sure we haven't run out of data yet */
+      if (buf > endptr)
+      {
+         png_warning(png_ptr, "Invalid pCAL data");
+         png_free(png_ptr, purpose);
+         png_free(png_ptr, params);
+         return;
+      }
+   }
+
+   png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams,
+      units, params);
+
+   png_free(png_ptr, purpose);
+   png_free(png_ptr, params);
+}
+#endif
+
+#if defined(PNG_READ_tIME_SUPPORTED)
+void
+png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_byte buf[7];
+   png_time mod_time;
+
+   png_debug(1, "in png_handle_tIME\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Out of place tIME chunk");
+   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_tIME)
+   {
+      png_warning(png_ptr, "Duplicate tIME chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   if (png_ptr->mode & PNG_HAVE_IDAT)
+      png_ptr->mode |= PNG_AFTER_IDAT;
+
+   if (length != 7)
+   {
+      png_warning(png_ptr, "Incorrect tIME chunk length");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_crc_read(png_ptr, buf, 7);
+   if (png_crc_finish(png_ptr, 0))
+      return;
+
+   mod_time.second = buf[6];
+   mod_time.minute = buf[5];
+   mod_time.hour = buf[4];
+   mod_time.day = buf[3];
+   mod_time.month = buf[2];
+   mod_time.year = png_get_uint_16(buf);
+
+   png_set_tIME(png_ptr, info_ptr, &mod_time);
+}
+#endif
+
+#if defined(PNG_READ_tEXt_SUPPORTED)
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+void
+png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_textp text_ptr;
+   png_charp key;
+   png_charp text;
+   png_uint_32 skip = 0;
+   png_size_t slength;
+
+   png_debug(1, "in png_handle_tEXt\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before tEXt");
+
+   if (png_ptr->mode & PNG_HAVE_IDAT)
+      png_ptr->mode |= PNG_AFTER_IDAT;
+
+#ifdef PNG_MAX_MALLOC_64K
+   if (length > (png_uint_32)65535L)
+   {
+      png_warning(png_ptr, "tEXt chunk too large to fit in memory");
+      skip = length - (png_uint_32)65535L;
+      length = (png_uint_32)65535L;
+   }
+#endif
+
+   key = (png_charp)png_malloc(png_ptr, length + 1);
+   slength = (png_size_t)length;
+   png_crc_read(png_ptr, (png_bytep)key, slength);
+
+   if (png_crc_finish(png_ptr, skip))
+   {
+      png_free(png_ptr, key);
+      return;
+   }
+
+   key[slength] = 0x00;
+
+   for (text = key; *text; text++)
+      /* empty loop to find end of key */ ;
+
+   if (text != key + slength)
+      text++;
+
+   text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
+   text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
+   text_ptr->key = key;
+   text_ptr->text = text;
+
+   png_set_text(png_ptr, info_ptr, text_ptr, 1);
+
+   png_free(png_ptr, text_ptr);
+}
+#endif
+
+#if defined(PNG_READ_zTXt_SUPPORTED)
+/* note: this does not correctly handle chunks that are > 64K under DOS */
+void
+png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   static char msg[] = "Error decoding zTXt chunk";
+   png_textp text_ptr;
+   png_charp key;
+   png_charp text;
+   int comp_type = PNG_TEXT_COMPRESSION_NONE;
+   png_size_t slength;
+
+   png_debug(1, "in png_handle_zTXt\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before zTXt");
+
+   if (png_ptr->mode & PNG_HAVE_IDAT)
+      png_ptr->mode |= PNG_AFTER_IDAT;
+
+#ifdef PNG_MAX_MALLOC_64K
+   /* We will no doubt have problems with chunks even half this size, but
+      there is no hard and fast rule to tell us where to stop. */
+   if (length > (png_uint_32)65535L)
+   {
+     png_warning(png_ptr,"zTXt chunk too large to fit in memory");
+     png_crc_finish(png_ptr, length);
+     return;
+   }
+#endif
+
+   key = (png_charp)png_malloc(png_ptr, length + 1);
+   slength = (png_size_t)length;
+   png_crc_read(png_ptr, (png_bytep)key, slength);
+   if (png_crc_finish(png_ptr, 0))
+   {
+      png_free(png_ptr, key);
+      return;
+   }
+
+   key[slength] = 0x00;
+
+   for (text = key; *text; text++)
+      /* empty loop */ ;
+
+   /* zTXt must have some text after the keyword */
+   if (text == key + slength)
+   {
+      png_warning(png_ptr, "Zero length zTXt chunk");
+   }
+   else if ((comp_type = *(++text)) == PNG_TEXT_COMPRESSION_zTXt)
+   {
+      png_size_t text_size, key_size;
+      text++;
+
+      png_ptr->zstream.next_in = (png_bytep)text;
+      png_ptr->zstream.avail_in = (uInt)(length - (text - key));
+      png_ptr->zstream.next_out = png_ptr->zbuf;
+      png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+      key_size = (png_size_t)(text - key);
+      text_size = 0;
+      text = NULL;
+
+      while (png_ptr->zstream.avail_in)
+      {
+         int ret;
+
+         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+         if (ret != Z_OK && ret != Z_STREAM_END)
+         {
+            if (png_ptr->zstream.msg != NULL)
+               png_warning(png_ptr, png_ptr->zstream.msg);
+            else
+               png_warning(png_ptr, msg);
+            inflateReset(&png_ptr->zstream);
+            png_ptr->zstream.avail_in = 0;
+
+            if (text ==  NULL)
+            {
+               text_size = key_size + sizeof(msg) + 1;
+               text = (png_charp)png_malloc(png_ptr, (png_uint_32)text_size);
+               png_memcpy(text, key, key_size);
+            }
+
+            text[text_size - 1] = 0x00;
+
+            /* Copy what we can of the error message into the text chunk */
+            text_size = (png_size_t)(slength - (text - key) - 1);
+            text_size = sizeof(msg) > text_size ? text_size : sizeof(msg);
+            png_memcpy(text + key_size, msg, text_size + 1);
+            break;
+         }
+         if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
+         {
+            if (text == NULL)
+            {
+               text = (png_charp)png_malloc(png_ptr,
+                  (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
+                     + key_size + 1));
+               png_memcpy(text + key_size, png_ptr->zbuf,
+                  png_ptr->zbuf_size - png_ptr->zstream.avail_out);
+               png_memcpy(text, key, key_size);
+               text_size = key_size + png_ptr->zbuf_size -
+                  png_ptr->zstream.avail_out;
+               *(text + text_size) = 0x00;
+            }
+            else
+            {
+               png_charp tmp;
+
+               tmp = text;
+               text = (png_charp)png_malloc(png_ptr, (png_uint_32)(text_size +
+                  png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
+               png_memcpy(text, tmp, text_size);
+               png_free(png_ptr, tmp);
+               png_memcpy(text + text_size, png_ptr->zbuf,
+                  (png_ptr->zbuf_size - png_ptr->zstream.avail_out));
+               text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
+               *(text + text_size) = 0x00;
+            }
+            if (ret != Z_STREAM_END)
+            {
+               png_ptr->zstream.next_out = png_ptr->zbuf;
+               png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+            }
+            else
+            {
+               break;
+            }
+         }
+      }
+
+      inflateReset(&png_ptr->zstream);
+      png_ptr->zstream.avail_in = 0;
+
+      png_free(png_ptr, key);
+      key = text;
+      text += key_size;
+   }
+   else /* if (comp_type >= PNG_TEXT_COMPRESSION_LAST) */
+   {
+      png_size_t text_size;
+#if !defined(PNG_NO_STDIO)
+      char umsg[50];
+
+      sprintf(umsg, "Unknown zTXt compression type %d", comp_type);
+      png_warning(png_ptr, umsg);
+#else
+      png_warning(png_ptr, "Unknown zTXt compression type");
+#endif
+
+      /* Copy what we can of the error message into the text chunk */
+      text_size = (png_size_t)(slength - (text - key) - 1);
+      text_size = sizeof(msg) > text_size ? text_size : sizeof(msg);
+      png_memcpy(text, msg, text_size + 1);
+   }
+
+   text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
+   text_ptr->compression = comp_type;
+   text_ptr->key = key;
+   text_ptr->text = text;
+
+   png_set_text(png_ptr, info_ptr, text_ptr, 1);
+
+   png_free(png_ptr, text_ptr);
+}
+#endif
+
+/* This function is called when we haven't found a handler for a
+   chunk.  If there isn't a problem with the chunk itself (ie bad
+   chunk name, CRC, or a critical chunk), the chunk is silently ignored. */
+void
+png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_debug(1, "in png_handle_unknown\n");
+
+   /* In the future we can have code here that calls user-supplied
+    * callback functions for unknown chunks before they are ignored or
+    * cause an error.
+    */
+   png_check_chunk_name(png_ptr, png_ptr->chunk_name);
+
+   if (!(png_ptr->chunk_name[0] & 0x20))
+   {
+      png_chunk_error(png_ptr, "unknown critical chunk");
+
+      /* to quiet compiler warnings about unused info_ptr */
+      if (info_ptr == NULL)
+         return;
+   }
+
+   if (png_ptr->mode & PNG_HAVE_IDAT)
+      png_ptr->mode |= PNG_AFTER_IDAT;
+
+   png_crc_finish(png_ptr, length);
+
+}
+
+/* This function is called to verify that a chunk name is valid.
+   This function can't have the "critical chunk check" incorporated
+   into it, since in the future we will need to be able to call user
+   functions to handle unknown critical chunks after we check that
+   the chunk name itself is valid. */
+
+#define isnonalpha(c) ((c) < 41 || (c) > 122 || ((c) > 90 && (c) < 97))
+
+void
+png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
+{
+   png_debug(1, "in png_check_chunk_name\n");
+   if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
+       isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
+   {
+      png_chunk_error(png_ptr, "invalid chunk type");
+   }
+}
+
+/* Combines the row recently read in with the previous row.
+   This routine takes care of alpha and transparency if requested.
+   This routine also handles the two methods of progressive display
+   of interlaced images, depending on the mask value.
+   The mask value describes which pixels are to be combined with
+   the row.  The pattern always repeats every 8 pixels, so just 8
+   bits are needed.  A one indicates the pixels is to be combined,
+   a zero indicates the pixel is to be skipped.  This is in addition
+   to any alpha or transparency value associated with the pixel.  If
+   you want all pixels to be combined, pass 0xff (255) in mask.  */
+void
+png_combine_row(png_structp png_ptr, png_bytep row,
+   int mask)
+{
+   png_debug(1,"in png_combine_row\n");
+   if (mask == 0xff)
+   {
+      png_memcpy(row, png_ptr->row_buf + 1,
+         (png_size_t)((png_ptr->width *
+         png_ptr->row_info.pixel_depth + 7) >> 3));
+   }
+   else
+   {
+      switch (png_ptr->row_info.pixel_depth)
+      {
+         case 1:
+         {
+            png_bytep sp;
+            png_bytep dp;
+            int s_inc, s_start, s_end;
+            int m;
+            int shift;
+            png_uint_32 i;
+
+            sp = png_ptr->row_buf + 1;
+            dp = row;
+            m = 0x80;
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+            if (png_ptr->transformations & PNG_PACKSWAP)
+            {
+                s_start = 0;
+                s_end = 7;
+                s_inc = 1;
+            }
+            else
+#endif
+            {
+                s_start = 7;
+                s_end = 0;
+                s_inc = -1;
+            }
+
+            shift = s_start;
+
+            for (i = 0; i < png_ptr->width; i++)
+            {
+               if (m & mask)
+               {
+                  int value;
+
+                  value = (*sp >> shift) & 0x1;
+                  *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
+                  *dp |= (png_byte)(value << shift);
+               }
+
+               if (shift == s_end)
+               {
+                  shift = s_start;
+                  sp++;
+                  dp++;
+               }
+               else
+                  shift += s_inc;
+
+               if (m == 1)
+                  m = 0x80;
+               else
+                  m >>= 1;
+            }
+            break;
+         }
+         case 2:
+         {
+            png_bytep sp;
+            png_bytep dp;
+            int s_start, s_end, s_inc;
+            int m;
+            int shift;
+            png_uint_32 i;
+            int value;
+
+            sp = png_ptr->row_buf + 1;
+            dp = row;
+            m = 0x80;
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+            if (png_ptr->transformations & PNG_PACKSWAP)
+            {
+               s_start = 0;
+               s_end = 6;
+               s_inc = 2;
+            }
+            else
+#endif
+            {
+               s_start = 6;
+               s_end = 0;
+               s_inc = -2;
+            }
+
+            shift = s_start;
+
+            for (i = 0; i < png_ptr->width; i++)
+            {
+               if (m & mask)
+               {
+                  value = (*sp >> shift) & 0x3;
+                  *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
+                  *dp |= (png_byte)(value << shift);
+               }
+
+               if (shift == s_end)
+               {
+                  shift = s_start;
+                  sp++;
+                  dp++;
+               }
+               else
+                  shift += s_inc;
+               if (m == 1)
+                  m = 0x80;
+               else
+                  m >>= 1;
+            }
+            break;
+         }
+         case 4:
+         {
+            png_bytep sp;
+            png_bytep dp;
+            int s_start, s_end, s_inc;
+            int m;
+            int shift;
+            png_uint_32 i;
+            int value;
+
+            sp = png_ptr->row_buf + 1;
+            dp = row;
+            m = 0x80;
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+            if (png_ptr->transformations & PNG_PACKSWAP)
+            {
+               s_start = 0;
+               s_end = 4;
+               s_inc = 4;
+            }
+            else
+#endif
+            {
+               s_start = 4;
+               s_end = 0;
+               s_inc = -4;
+            }
+            shift = s_start;
+
+            for (i = 0; i < png_ptr->width; i++)
+            {
+               if (m & mask)
+               {
+                  value = (*sp >> shift) & 0xf;
+                  *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
+                  *dp |= (png_byte)(value << shift);
+               }
+
+               if (shift == s_end)
+               {
+                  shift = s_start;
+                  sp++;
+                  dp++;
+               }
+               else
+                  shift += s_inc;
+               if (m == 1)
+                  m = 0x80;
+               else
+                  m >>= 1;
+            }
+            break;
+         }
+         default:
+         {
+            png_bytep sp;
+            png_bytep dp;
+            png_size_t pixel_bytes;
+            png_uint_32 i;
+            png_byte m;
+
+            pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
+
+            sp = png_ptr->row_buf + 1;
+            dp = row;
+            m = 0x80;
+            for (i = 0; i < png_ptr->width; i++)
+            {
+               if (m & mask)
+               {
+                  png_memcpy(dp, sp, pixel_bytes);
+               }
+
+               sp += pixel_bytes;
+               dp += pixel_bytes;
+
+               if (m == 1)
+                  m = 0x80;
+               else
+                  m >>= 1;
+            }
+            break;
+         }
+      }
+   }
+}
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED)
+void
+png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
+   png_uint_32 transformations)
+{
+   png_debug(1,"in png_do_read_interlace\n");
+   if (row != NULL && row_info != NULL)
+   {
+      png_uint_32 final_width;
+
+      final_width = row_info->width * png_pass_inc[pass];
+
+      switch (row_info->pixel_depth)
+      {
+         case 1:
+         {
+            png_bytep sp, dp;
+            int sshift, dshift;
+            int s_start, s_end, s_inc;
+            png_byte v;
+            png_uint_32 i;
+            int j;
+
+            sp = row + (png_size_t)((row_info->width - 1) >> 3);
+            dp = row + (png_size_t)((final_width - 1) >> 3);
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+            if (transformations & PNG_PACKSWAP)
+            {
+                sshift = (int)((row_info->width + 7) & 7);
+                dshift = (int)((final_width + 7) & 7);
+                s_start = 7;
+                s_end = 0;
+                s_inc = -1;
+            }
+            else
+#endif
+            {
+                sshift = 7 - (int)((row_info->width + 7) & 7);
+                dshift = 7 - (int)((final_width + 7) & 7);
+                s_start = 0;
+                s_end = 7;
+                s_inc = 1;
+            }
+
+            for (i = row_info->width; i; i--)
+            {
+               v = (png_byte)((*sp >> sshift) & 0x1);
+               for (j = 0; j < png_pass_inc[pass]; j++)
+               {
+                  *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
+                  *dp |= (png_byte)(v << dshift);
+                  if (dshift == s_end)
+                  {
+                     dshift = s_start;
+                     dp--;
+                  }
+                  else
+                     dshift += s_inc;
+               }
+               if (sshift == s_end)
+               {
+                  sshift = s_start;
+                  sp--;
+               }
+               else
+                  sshift += s_inc;
+            }
+            break;
+         }
+         case 2:
+         {
+            png_bytep sp, dp;
+            int sshift, dshift;
+            int s_start, s_end, s_inc;
+            png_uint_32 i;
+
+            sp = row + (png_uint_32)((row_info->width - 1) >> 2);
+            dp = row + (png_uint_32)((final_width - 1) >> 2);
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+            if (transformations & PNG_PACKSWAP)
+            {
+               sshift = (int)(((row_info->width + 3) & 3) << 1);
+               dshift = (int)(((final_width + 3) & 3) << 1);
+               s_start = 6;
+               s_end = 0;
+               s_inc = -2;
+            }
+            else
+#endif
+            {
+               sshift = (int)((3 - ((row_info->width + 3) & 3)) << 1);
+               dshift = (int)((3 - ((final_width + 3) & 3)) << 1);
+               s_start = 0;
+               s_end = 6;
+               s_inc = 2;
+            }
+
+            for (i = row_info->width; i; i--)
+            {
+               png_byte v;
+               int j;
+
+               v = (png_byte)((*sp >> sshift) & 0x3);
+               for (j = 0; j < png_pass_inc[pass]; j++)
+               {
+                  *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
+                  *dp |= (png_byte)(v << dshift);
+                  if (dshift == s_end)
+                  {
+                     dshift = s_start;
+                     dp--;
+                  }
+                  else
+                     dshift += s_inc;
+               }
+               if (sshift == s_end)
+               {
+                  sshift = s_start;
+                  sp--;
+               }
+               else
+                  sshift += s_inc;
+            }
+            break;
+         }
+         case 4:
+         {
+            png_bytep sp, dp;
+            int sshift, dshift;
+            int s_start, s_end, s_inc;
+            png_uint_32 i;
+
+            sp = row + (png_size_t)((row_info->width - 1) >> 1);
+            dp = row + (png_size_t)((final_width - 1) >> 1);
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+            if (transformations & PNG_PACKSWAP)
+            {
+               sshift = (int)(((row_info->width + 1) & 1) << 2);
+               dshift = (int)(((final_width + 1) & 1) << 2);
+               s_start = 4;
+               s_end = 0;
+               s_inc = -4;
+            }
+            else
+#endif
+            {
+               sshift = (int)((1 - ((row_info->width + 1) & 1)) << 2);
+               dshift = (int)((1 - ((final_width + 1) & 1)) << 2);
+               s_start = 0;
+               s_end = 4;
+               s_inc = 4;
+            }
+
+            for (i = row_info->width; i; i--)
+            {
+               png_byte v;
+               int j;
+
+               v = (png_byte)((*sp >> sshift) & 0xf);
+               for (j = 0; j < png_pass_inc[pass]; j++)
+               {
+                  *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
+                  *dp |= (png_byte)(v << dshift);
+                  if (dshift == s_end)
+                  {
+                     dshift = s_start;
+                     dp--;
+                  }
+                  else
+                     dshift += s_inc;
+               }
+               if (sshift == s_end)
+               {
+                  sshift = s_start;
+                  sp--;
+               }
+               else
+                  sshift += s_inc;
+            }
+            break;
+         }
+         default:
+         {
+            png_bytep sp, dp;
+            png_uint_32 i;
+            png_size_t pixel_bytes;
+
+            pixel_bytes = (row_info->pixel_depth >> 3);
+
+            sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes;
+            dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
+            for (i = row_info->width; i; i--)
+            {
+               png_byte v[8];
+               int j;
+
+               png_memcpy(v, sp, pixel_bytes);
+               for (j = 0; j < png_pass_inc[pass]; j++)
+               {
+                  png_memcpy(dp, v, pixel_bytes);
+                  dp -= pixel_bytes;
+               }
+               sp -= pixel_bytes;
+            }
+            break;
+         }
+      }
+      row_info->width = final_width;
+      row_info->rowbytes = ((final_width *
+         (png_uint_32)row_info->pixel_depth + 7) >> 3);
+   }
+}
+#endif
+
+void
+png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
+   png_bytep prev_row, int filter)
+{
+   png_debug(1, "in png_read_filter_row\n");
+   png_debug2(2,"row = %d, filter = %d\n", png_ptr->row_number, filter);
+
+
+   switch (filter)
+   {
+      case PNG_FILTER_VALUE_NONE:
+         break;
+      case PNG_FILTER_VALUE_SUB:
+      {
+         png_uint_32 i;
+         int bpp;
+         png_bytep rp;
+         png_bytep lp;
+
+         bpp = (row_info->pixel_depth + 7) / 8;
+         for (i = (png_uint_32)bpp, rp = row + bpp, lp = row;
+            i < row_info->rowbytes; i++, rp++, lp++)
+         {
+            *rp = (png_byte)(((int)(*rp) + (int)(*lp)) & 0xff);
+         }
+         break;
+      }
+      case PNG_FILTER_VALUE_UP:
+      {
+         png_uint_32 i;
+         png_bytep rp;
+         png_bytep pp;
+
+         for (i = 0, rp = row, pp = prev_row;
+            i < row_info->rowbytes; i++, rp++, pp++)
+         {
+            *rp = (png_byte)(((int)(*rp) + (int)(*pp)) & 0xff);
+         }
+         break;
+      }
+      case PNG_FILTER_VALUE_AVG:
+      {
+         png_uint_32 i;
+         int bpp;
+         png_bytep rp;
+         png_bytep pp;
+         png_bytep lp;
+
+         bpp = (row_info->pixel_depth + 7) / 8;
+         for (i = 0, rp = row, pp = prev_row;
+            i < (png_uint_32)bpp; i++, rp++, pp++)
+         {
+            *rp = (png_byte)(((int)(*rp) +
+               ((int)(*pp) / 2)) & 0xff);
+         }
+         for (lp = row; i < row_info->rowbytes; i++, rp++, lp++, pp++)
+         {
+            *rp = (png_byte)(((int)(*rp) +
+               (int)(*pp + *lp) / 2) & 0xff);
+         }
+         break;
+      }
+      case PNG_FILTER_VALUE_PAETH:
+      {
+         int bpp;
+         png_uint_32 i;
+         png_bytep rp;
+         png_bytep pp;
+         png_bytep lp;
+         png_bytep cp;
+
+         bpp = (row_info->pixel_depth + 7) / 8;
+         for (i = 0, rp = row, pp = prev_row,
+            lp = row - bpp, cp = prev_row - bpp;
+            i < row_info->rowbytes; i++, rp++, pp++, lp++, cp++)
+         {
+            int a, b, c, pa, pb, pc, p;
+
+            b = *pp;
+            if (i >= (png_uint_32)bpp)
+            {
+               c = *cp;
+               a = *lp;
+            }
+            else
+            {
+               a = c = 0;
+            }
+            p = a + b - c;
+            pa = abs(p - a);
+            pb = abs(p - b);
+            pc = abs(p - c);
+
+            if (pa <= pb && pa <= pc)
+               p = a;
+            else if (pb <= pc)
+               p = b;
+            else
+               p = c;
+
+            *rp = (png_byte)(((int)(*rp) + p) & 0xff);
+         }
+         break;
+      }
+      default:
+         png_error(png_ptr, "Bad adaptive filter type");
+         break;
+   }
+}
+
+void
+png_read_finish_row(png_structp png_ptr)
+{
+   png_debug(1, "in png_read_finish_row\n");
+   png_ptr->row_number++;
+   if (png_ptr->row_number < png_ptr->num_rows)
+      return;
+
+   if (png_ptr->interlaced)
+   {
+      png_ptr->row_number = 0;
+      png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
+      do
+      {
+         png_ptr->pass++;
+         if (png_ptr->pass >= 7)
+            break;
+         png_ptr->iwidth = (png_ptr->width +
+            png_pass_inc[png_ptr->pass] - 1 -
+            png_pass_start[png_ptr->pass]) /
+            png_pass_inc[png_ptr->pass];
+            png_ptr->irowbytes = ((png_ptr->iwidth *
+               (png_uint_32)png_ptr->pixel_depth + 7) >> 3) +1;
+
+         if (!(png_ptr->transformations & PNG_INTERLACE))
+         {
+            png_ptr->num_rows = (png_ptr->height +
+               png_pass_yinc[png_ptr->pass] - 1 -
+               png_pass_ystart[png_ptr->pass]) /
+               png_pass_yinc[png_ptr->pass];
+            if (!(png_ptr->num_rows))
+               continue;
+         }
+         if (png_ptr->transformations & PNG_INTERLACE)
+            break;
+      } while (png_ptr->iwidth == 0);
+
+      if (png_ptr->pass < 7)
+         return;
+   }
+
+   if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
+   {
+      char extra;
+      int ret;
+
+      png_ptr->zstream.next_out = (Byte *)&extra;
+      png_ptr->zstream.avail_out = (uInt)1;
+      for(;;)
+      {
+         if (!(png_ptr->zstream.avail_in))
+         {
+            while (!png_ptr->idat_size)
+            {
+               png_byte chunk_length[4];
+
+               png_crc_finish(png_ptr, 0);
+
+               png_read_data(png_ptr, chunk_length, 4);
+               png_ptr->idat_size = png_get_uint_32(chunk_length);
+
+               png_reset_crc(png_ptr);
+               png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+               if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+                  png_error(png_ptr, "Not enough image data");
+
+            }
+            png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
+            png_ptr->zstream.next_in = png_ptr->zbuf;
+            if (png_ptr->zbuf_size > png_ptr->idat_size)
+               png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
+            png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
+            png_ptr->idat_size -= png_ptr->zstream.avail_in;
+         }
+         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+         if (ret == Z_STREAM_END)
+         {
+            if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
+               png_ptr->idat_size)
+               png_error(png_ptr, "Extra compressed data");
+            png_ptr->mode |= PNG_AFTER_IDAT;
+            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+            break;
+         }
+         if (ret != Z_OK)
+            png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
+                      "Decompression Error");
+
+         if (!(png_ptr->zstream.avail_out))
+            png_error(png_ptr, "Extra compressed data");
+
+      }
+      png_ptr->zstream.avail_out = 0;
+   }
+
+   if (png_ptr->idat_size || png_ptr->zstream.avail_in)
+      png_error(png_ptr, "Extra compression data");
+
+   inflateReset(&png_ptr->zstream);
+
+   png_ptr->mode |= PNG_AFTER_IDAT;
+}
+
+void
+png_read_start_row(png_structp png_ptr)
+{
+   int max_pixel_depth;
+   png_uint_32 rowbytes;
+
+   png_debug(1, "in png_read_start_row\n");
+   png_ptr->zstream.avail_in = 0;
+   png_init_read_transformations(png_ptr);
+   if (png_ptr->interlaced)
+   {
+      if (!(png_ptr->transformations & PNG_INTERLACE))
+         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
+            png_pass_ystart[0]) / png_pass_yinc[0];
+      else
+         png_ptr->num_rows = png_ptr->height;
+
+      png_ptr->iwidth = (png_ptr->width +
+         png_pass_inc[png_ptr->pass] - 1 -
+         png_pass_start[png_ptr->pass]) /
+         png_pass_inc[png_ptr->pass];
+
+         rowbytes = ((png_ptr->iwidth *
+            (png_uint_32)png_ptr->pixel_depth + 7) >> 3) +1;
+         png_ptr->irowbytes = (png_size_t)rowbytes;
+         if((png_uint_32)png_ptr->irowbytes != rowbytes)
+            png_error(png_ptr, "Rowbytes overflow in png_read_start_row");
+   }
+   else
+   {
+      png_ptr->num_rows = png_ptr->height;
+      png_ptr->iwidth = png_ptr->width;
+      png_ptr->irowbytes = png_ptr->rowbytes + 1;
+   }
+   max_pixel_depth = png_ptr->pixel_depth;
+
+#if defined(PNG_READ_PACK_SUPPORTED)
+   if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
+      max_pixel_depth = 8;
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+   if (png_ptr->transformations & PNG_EXPAND)
+   {
+      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         if (png_ptr->num_trans)
+            max_pixel_depth = 32;
+         else
+            max_pixel_depth = 24;
+      }
+      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+      {
+         if (max_pixel_depth < 8)
+            max_pixel_depth = 8;
+         if (png_ptr->num_trans)
+            max_pixel_depth *= 2;
+      }
+      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+      {
+         if (png_ptr->num_trans)
+         {
+            max_pixel_depth *= 4;
+            max_pixel_depth /= 3;
+         }
+      }
+   }
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED)
+   if (png_ptr->transformations & (PNG_FILLER))
+   {
+      if (max_pixel_depth < 32)
+         max_pixel_depth = 32;
+   }
+#endif
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
+   {
+      if ((png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
+         png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      {
+         if (max_pixel_depth <= 16)
+            max_pixel_depth = 32;
+         else if (max_pixel_depth <= 32)
+            max_pixel_depth = 64;
+      }
+      else
+      {
+         if (max_pixel_depth <= 8)
+            max_pixel_depth = 24;
+         else if (max_pixel_depth <= 16)
+            max_pixel_depth = 48;
+      }
+   }
+#endif
+
+   /* align the width on the next larger 8 pixels.  Mainly used
+      for interlacing */
+   rowbytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
+   /* calculate the maximum bytes needed, adding a byte and a pixel
+      for safety sake */
+   rowbytes = ((rowbytes * (png_uint_32)max_pixel_depth + 7) >> 3) +
+      1 + ((max_pixel_depth + 7) >> 3);
+#ifdef PNG_MAX_MALLOC_64K
+   if (rowbytes > (png_uint_32)65536L)
+      png_error(png_ptr, "This image requires a row greater than 64KB");
+#endif
+   png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, rowbytes);
+
+#ifdef PNG_MAX_MALLOC_64K
+   if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
+      png_error(png_ptr, "This image requires a row greater than 64KB");
+#endif
+   png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
+      png_ptr->rowbytes + 1));
+
+   png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
+
+   png_debug1(3, "width = %d,\n", png_ptr->width);
+   png_debug1(3, "height = %d,\n", png_ptr->height);
+   png_debug1(3, "iwidth = %d,\n", png_ptr->iwidth);
+   png_debug1(3, "num_rows = %d\n", png_ptr->num_rows);
+   png_debug1(3, "rowbytes = %d,\n", png_ptr->rowbytes);
+   png_debug1(3, "irowbytes = %d,\n", png_ptr->irowbytes);
+
+   png_ptr->flags |= PNG_FLAG_ROW_INIT;
+}
diff --git a/src/png/pngset.c b/src/png/pngset.c
new file mode 100644
index 0000000000..aa85f24b6f
--- /dev/null
+++ b/src/png/pngset.c
@@ -0,0 +1,380 @@
+
+/* pngset.c - storage of image information into info struct
+ *
+ * libpng 1.0.1
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Copyright (c) 1998, Glenn Randers-Pehrson
+ * March 15, 1998
+ *
+ * The functions here are used during reads to store data from the file
+ * into the info struct, and during writes to store application data
+ * into the info struct for writing into the file.  This abstracts the
+ * info struct and allows us to change the structure in the future.
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#if defined(PNG_READ_bKGD_SUPPORTED) || defined(PNG_WRITE_bKGD_SUPPORTED)
+void
+png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background)
+{
+   png_debug1(1, "in %s storage function\n", "bKGD");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   png_memcpy(&(info_ptr->background), background, sizeof(png_color_16));
+   info_ptr->valid |= PNG_INFO_bKGD;
+}
+#endif
+
+#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
+void
+png_set_cHRM(png_structp png_ptr, png_infop info_ptr,
+   double white_x, double white_y, double red_x, double red_y,
+   double green_x, double green_y, double blue_x, double blue_y)
+{
+   png_debug1(1, "in %s storage function\n", "cHRM");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->x_white = (float)white_x;
+   info_ptr->y_white = (float)white_y;
+   info_ptr->x_red   = (float)red_x;
+   info_ptr->y_red   = (float)red_y;
+   info_ptr->x_green = (float)green_x;
+   info_ptr->y_green = (float)green_y;
+   info_ptr->x_blue  = (float)blue_x;
+   info_ptr->y_blue  = (float)blue_y;
+   info_ptr->valid |= PNG_INFO_cHRM;
+}
+#endif
+
+#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED)
+void
+png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma)
+{
+   png_debug1(1, "in %s storage function\n", "gAMA");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->gamma = (float)file_gamma;
+   info_ptr->valid |= PNG_INFO_gAMA;
+}
+#endif
+
+#if defined(PNG_READ_hIST_SUPPORTED) || defined(PNG_WRITE_hIST_SUPPORTED)
+void
+png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist)
+{
+   png_debug1(1, "in %s storage function\n", "hIST");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->hist = hist;
+   info_ptr->valid |= PNG_INFO_hIST;
+}
+#endif
+
+void
+png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 width, png_uint_32 height, int bit_depth,
+   int color_type, int interlace_type, int compression_type,
+   int filter_type)
+{
+   int rowbytes_per_pixel;
+   png_debug1(1, "in %s storage function\n", "IHDR");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->width = width;
+   info_ptr->height = height;
+   info_ptr->bit_depth = (png_byte)bit_depth;
+   info_ptr->color_type =(png_byte) color_type;
+   info_ptr->compression_type = (png_byte)compression_type;
+   info_ptr->filter_type = (png_byte)filter_type;
+   info_ptr->interlace_type = (png_byte)interlace_type;
+   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      info_ptr->channels = 1;
+   else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
+      info_ptr->channels = 3;
+   else
+      info_ptr->channels = 1;
+   if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
+      info_ptr->channels++;
+   info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
+
+   /* check for overflow */
+   rowbytes_per_pixel = (info_ptr->pixel_depth + 7) >> 3;
+   info_ptr->rowbytes = info_ptr->width * rowbytes_per_pixel;
+   if (( width > (png_uint_32)2147483647L/rowbytes_per_pixel))
+   {
+      png_warning(png_ptr,
+         "Width too large to process image data; rowbytes will overflow.");
+      info_ptr->rowbytes = (png_size_t)0;
+   }
+}
+
+#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
+void
+png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 offset_x, png_uint_32 offset_y, int unit_type)
+{
+   png_debug1(1, "in %s storage function\n", "oFFs");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->x_offset = offset_x;
+   info_ptr->y_offset = offset_y;
+   info_ptr->offset_unit_type = (png_byte)unit_type;
+   info_ptr->valid |= PNG_INFO_oFFs;
+}
+#endif
+
+#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED)
+void
+png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
+   png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams,
+   png_charp units, png_charpp params)
+{
+   png_uint_32 length;
+   int i;
+
+   png_debug1(1, "in %s storage function\n", "pCAL");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   length = png_strlen(purpose) + 1;
+   png_debug1(3, "allocating purpose for info (%d bytes)\n", length);
+   info_ptr->pcal_purpose = (png_charp)png_malloc(png_ptr, length);
+   png_memcpy(info_ptr->pcal_purpose, purpose, (png_size_t)length);
+
+   png_debug(3, "storing X0, X1, type, and nparams in info\n");
+   info_ptr->pcal_X0 = X0;
+   info_ptr->pcal_X1 = X1;
+   info_ptr->pcal_type = (png_byte)type;
+   info_ptr->pcal_nparams = (png_byte)nparams;
+
+   length = png_strlen(units) + 1;
+   png_debug1(3, "allocating units for info (%d bytes)\n", length);
+   info_ptr->pcal_units = (png_charp)png_malloc(png_ptr, length);
+   png_memcpy(info_ptr->pcal_units, units, (png_size_t)length);
+
+   info_ptr->pcal_params = (png_charpp)png_malloc(png_ptr,
+      (png_uint_32)((nparams + 1) * sizeof(png_charp)));
+   info_ptr->pcal_params[nparams] = NULL;
+
+   for (i = 0; i < nparams; i++)
+   {
+      length = png_strlen(params[i]) + 1;
+      png_debug2(3, "allocating parameter %d for info (%d bytes)\n", i, length);
+      info_ptr->pcal_params[i] = (png_charp)png_malloc(png_ptr, length);
+      png_memcpy(info_ptr->pcal_params[i], params[i], (png_size_t)length);
+   }
+
+   info_ptr->valid |= PNG_INFO_pCAL;
+}
+#endif
+
+#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
+void
+png_set_pHYs(png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 res_x, png_uint_32 res_y, int unit_type)
+{
+   png_debug1(1, "in %s storage function\n", "pHYs");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->x_pixels_per_unit = res_x;
+   info_ptr->y_pixels_per_unit = res_y;
+   info_ptr->phys_unit_type = (png_byte)unit_type;
+   info_ptr->valid |= PNG_INFO_pHYs;
+}
+#endif
+
+void
+png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
+   png_colorp palette, int num_palette)
+{
+   png_debug1(1, "in %s storage function\n", "PLTE");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->palette = palette;
+   info_ptr->num_palette = (png_uint_16)num_palette;
+   info_ptr->valid |= PNG_INFO_PLTE;
+}
+
+#if defined(PNG_READ_sBIT_SUPPORTED) || defined(PNG_WRITE_sBIT_SUPPORTED)
+void
+png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
+   png_color_8p sig_bit)
+{
+   png_debug1(1, "in %s storage function\n", "sBIT");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   png_memcpy(&(info_ptr->sig_bit), sig_bit, sizeof (png_color_8));
+   info_ptr->valid |= PNG_INFO_sBIT;
+}
+#endif
+
+#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
+void
+png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent)
+{
+   png_debug1(1, "in %s storage function\n", "sRGB");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   info_ptr->srgb_intent = (png_byte)intent;
+   info_ptr->valid |= PNG_INFO_sRGB;
+}
+void
+png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
+   int intent)
+{
+#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED)
+   float file_gamma;
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
+   float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
+#endif
+   png_debug1(1, "in %s storage function\n", "sRGB_gAMA_and_cHRM");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   png_set_sRGB(png_ptr, info_ptr, intent);
+
+#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED)
+   file_gamma = (float).45;
+   png_set_gAMA(png_ptr, info_ptr, file_gamma);
+#endif
+
+#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
+   white_x = (float).3127;
+   white_y = (float).3290;
+   red_x   = (float).64;
+   red_y   = (float).33;
+   green_x = (float).30;
+   green_y = (float).60;
+   blue_x  = (float).15;
+   blue_y  = (float).06;
+
+   png_set_cHRM(png_ptr, info_ptr,
+      white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
+
+#endif
+}
+#endif
+
+#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
+    defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
+void
+png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
+   int num_text)
+{
+   int i;
+
+   png_debug1(1, "in %s storage function\n", (png_ptr->chunk_name[0] == '\0' ?
+      "text" : (png_const_charp)png_ptr->chunk_name));
+
+   if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
+      return;
+
+   /* Make sure we have enough space in the "text" array in info_struct
+    * to hold all of the incoming text_ptr objects.
+    */
+   if (info_ptr->num_text + num_text > info_ptr->max_text)
+   {
+      if (info_ptr->text != NULL)
+      {
+         png_textp old_text;
+         int old_max;
+
+         old_max = info_ptr->max_text;
+         info_ptr->max_text = info_ptr->num_text + num_text + 8;
+         old_text = info_ptr->text;
+         info_ptr->text = (png_textp)png_malloc(png_ptr,
+            (png_uint_32)(info_ptr->max_text * sizeof (png_text)));
+         png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max *
+            sizeof(png_text)));
+         png_free(png_ptr, old_text);
+      }
+      else
+      {
+         info_ptr->max_text = num_text + 8;
+         info_ptr->num_text = 0;
+         info_ptr->text = (png_textp)png_malloc(png_ptr,
+            (png_uint_32)(info_ptr->max_text * sizeof (png_text)));
+      }
+      png_debug1(3, "allocated %d entries for info_ptr->text\n",
+         info_ptr->max_text);
+   }
+
+   for (i = 0; i < num_text; i++)
+   {
+      png_textp textp = &(info_ptr->text[info_ptr->num_text]);
+
+      if (text_ptr[i].text == NULL)
+         text_ptr[i].text = (png_charp)"";
+
+      if (text_ptr[i].text[0] == '\0')
+      {
+         textp->text_length = 0;
+         textp->compression = PNG_TEXT_COMPRESSION_NONE;
+      }
+      else
+      {
+         textp->text_length = png_strlen(text_ptr[i].text);
+         textp->compression = text_ptr[i].compression;
+      }
+      textp->text = text_ptr[i].text;
+      textp->key = text_ptr[i].key;
+      info_ptr->num_text++;
+      png_debug1(3, "transferred text chunk %d\n", info_ptr->num_text);
+   }
+}
+#endif
+
+#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED)
+void
+png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time)
+{
+   png_debug1(1, "in %s storage function\n", "tIME");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   png_memcpy(&(info_ptr->mod_time), mod_time, sizeof (png_time));
+   info_ptr->valid |= PNG_INFO_tIME;
+}
+#endif
+
+#if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_WRITE_tRNS_SUPPORTED)
+void
+png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
+   png_bytep trans, int num_trans, png_color_16p trans_values)
+{
+   png_debug1(1, "in %s storage function\n", "tRNS");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   if (trans != NULL)
+   {
+      info_ptr->trans = trans;
+   }
+
+   if (trans_values != NULL)
+   {
+      png_memcpy(&(info_ptr->trans_values), trans_values,
+         sizeof(png_color_16));
+      if (num_trans == 0)
+        num_trans = 1;
+   }
+   info_ptr->num_trans = (png_uint_16)num_trans;
+   info_ptr->valid |= PNG_INFO_tRNS;
+}
+#endif
+
diff --git a/src/png/pngtest.c b/src/png/pngtest.c
new file mode 100644
index 0000000000..22cbcb3ea2
--- /dev/null
+++ b/src/png/pngtest.c
@@ -0,0 +1,1036 @@
+
+/* pngtest.c - a simple test program to test libpng
+ *
+ * libpng 1.0.1
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Copyright (c) 1998, Glenn Randers-Pehrson
+ * March 15, 1998
+ *
+ * This program reads in a PNG image, writes it out again, and then
+ * compares the two files.  If the files are identical, this shows that
+ * the basic chunk handling, filtering, and (de)compression code is working
+ * properly.  It does not currently test all of the transforms, although
+ * it probably should.
+ *
+ * The program will fail in certain legitimate cases:
+ * 1) when the compression level or filter selection method is changed.
+ * 2) when the chunk size is smaller than 8K.
+ * 3) unknown ancillary chunks exist in the input file.
+ * 4) others not listed here...
+ * In these cases, it is best to check with another tool such as "pngcheck"
+ * to see what the differences between the two images are.
+ *
+ * If a filename is given on the command-line, then this file is used
+ * for the input, rather than the default "pngtest.png".  This allows
+ * testing a wide variety of files easily.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/* Makes pngtest verbose so we can find problems (needs to be before png.h) */
+#ifndef PNG_DEBUG
+#define PNG_DEBUG 0
+#endif
+
+#include "png.h"
+
+int test_one_file PNGARG((PNG_CONST char *inname, PNG_CONST char *outname));
+
+#ifdef __TURBOC__
+#include <mem.h>
+#endif
+
+/* defined so I can write to a file on gui/windowing platforms */
+/*  #define STDERR stderr  */
+#define STDERR stdout   /* for DOS */
+
+/* example of using row callbacks to make a simple progress meter */
+static int status_pass=1;
+static int status_dots_requested=0;
+static int status_dots=1;
+
+void
+read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
+{
+    if(png_ptr == NULL || row_number > 0x3fffffffL) return;
+    if(status_pass != pass)
+    {
+       fprintf(stdout,"\n Pass %d: ",pass);
+       status_pass = pass;
+       status_dots = 30;
+    }
+    status_dots--;
+    if(status_dots == 0)
+    {
+       fprintf(stdout, "\n         ");
+       status_dots=30;
+    }
+    fprintf(stdout, "r");
+}
+
+void
+write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
+{
+    if(png_ptr == NULL || row_number > 0x3fffffffL || pass > 7) return;
+    fprintf(stdout, "w");
+}
+
+
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+/* example of using user transform callback (we don't transform anything,
+   but merely count the black pixels) */
+
+static png_uint_32 black_pixels;
+
+void
+count_black_pixels(png_structp png_ptr, png_row_infop row_info, png_bytep data)
+{
+   png_bytep dp = data;
+   if(png_ptr == NULL)return; 
+
+   /* contents of row_info:
+    *  png_uint_32 width      width of row
+    *  png_uint_32 rowbytes   number of bytes in row
+    *  png_byte color_type    color type of pixels
+    *  png_byte bit_depth     bit depth of samples
+    *  png_byte channels      number of channels (1-4)
+    *  png_byte pixel_depth   bits per pixel (depth*channels)
+    */
+
+    /* counts the number of black pixels (or zero pixels if color_type is 3 */
+
+    if(row_info->color_type == 0 || row_info->color_type == 3)
+    {
+       int pos=0;
+       png_uint_32 n;
+       for (n=0; n<row_info->width; n++)
+       {
+          if(row_info->bit_depth == 1)
+             if(((*dp << pos++ )& 0x80) == 0) black_pixels++;
+             if(pos == 8)
+             {
+                pos=0;
+                dp++;
+             }
+          if(row_info->bit_depth == 2)
+             if(((*dp << (pos+=2))& 0xc0) == 0) black_pixels++;
+             if(pos == 8)
+             {
+                pos=0;
+                dp++;
+             }
+          if(row_info->bit_depth == 4)
+             if(((*dp << (pos+=4))& 0xf0) == 0) black_pixels++;
+             if(pos == 8)
+             {
+                pos=0;
+                dp++;
+             }
+          if(row_info->bit_depth == 8)
+             if(*dp++ == 0) black_pixels++;
+          if(row_info->bit_depth == 16)
+          {
+             if((*dp | *(dp+1)) == 0) black_pixels++;
+             dp+=2;
+          }
+       }
+    }
+    else /* other color types */
+    {
+       png_uint_32 n;
+       int channel;
+       int color_channels = row_info->channels;
+       if(row_info->color_type > 3)color_channels--;
+
+       for (n=0; n<row_info->width; n++)
+       {
+          for (channel = 0; channel < color_channels; channel++)
+          {
+             if(row_info->bit_depth == 8)
+                if(*dp++ == 0) black_pixels++;
+             if(row_info->bit_depth == 16)
+             {
+                if((*dp | *(dp+1)) == 0) black_pixels++;
+                dp+=2;
+             }
+          }
+          if(row_info->color_type > 3)
+          {
+             dp++;
+             if(row_info->bit_depth == 16)dp++;
+          }
+       }
+    }
+}
+#endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */
+
+static int verbose = 0;
+static int wrote_question = 0;
+
+#if defined(PNG_NO_STDIO)
+/* START of code to validate stdio-free compilation */
+/* These copies of the default read/write functions come from pngrio.c and */
+/* pngwio.c.  They allow "don't include stdio" testing of the library. */
+/* This is the function which does the actual reading of data.  If you are
+   not reading from a standard C stream, you should create a replacement
+   read_data function and use it at run time with png_set_read_fn(), rather
+   than changing the library. */
+#ifndef USE_FAR_KEYWORD
+static void
+png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   png_size_t check;
+
+   /* fread() returns 0 on error, so it is OK to store this in a png_size_t
+    * instead of an int, which is what fread() actually returns.
+    */
+   check = (png_size_t)fread(data, (png_size_t)1, length,
+      (FILE *)png_ptr->io_ptr);
+
+   if (check != length)
+   {
+      png_error(png_ptr, "Read Error");
+   }
+}
+#else
+/* this is the model-independent version. Since the standard I/O library
+   can't handle far buffers in the medium and small models, we have to copy
+   the data.
+*/
+ 
+#define NEAR_BUF_SIZE 1024
+#define MIN(a,b) (a <= b ? a : b)
+ 
+static void
+png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   int check;
+   png_byte *n_data;
+   FILE *io_ptr;
+
+   /* Check if data really is near. If so, use usual code. */
+   n_data = (png_byte *)CVT_PTR_NOCHECK(data);
+   io_ptr = (FILE *)CVT_PTR(png_ptr->io_ptr);
+   if ((png_bytep)n_data == data)
+   {
+      check = fread(n_data, 1, length, io_ptr);
+   }
+   else
+   {
+      png_byte buf[NEAR_BUF_SIZE];
+      png_size_t read, remaining, err;
+      check = 0;
+      remaining = length;
+      do
+      {
+         read = MIN(NEAR_BUF_SIZE, remaining);
+         err = fread(buf, (png_size_t)1, read, io_ptr);
+         png_memcpy(data, buf, read); /* copy far buffer to near buffer */
+         if(err != read)
+            break;
+         else
+            check += err;
+         data += read;
+         remaining -= read;
+      }
+      while (remaining != 0);
+   }
+   if (check != length)
+   {
+      png_error(png_ptr, "read Error");
+   }
+}
+#endif /* USE_FAR_KEYWORD */
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+static void
+png_default_flush(png_structp png_ptr)
+{
+   FILE *io_ptr;
+   io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr));
+   if (io_ptr != NULL)
+      fflush(io_ptr);
+}
+#endif
+
+/* This is the function which does the actual writing of data.  If you are
+   not writing to a standard C stream, you should create a replacement
+   write_data function and use it at run time with png_set_write_fn(), rather
+   than changing the library. */
+#ifndef USE_FAR_KEYWORD
+static void
+png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   png_uint_32 check;
+
+   check = fwrite(data, 1, length, (FILE *)(png_ptr->io_ptr));
+   if (check != length)
+   {
+      png_error(png_ptr, "Write Error");
+   }
+}
+#else
+/* this is the model-independent version. Since the standard I/O library
+   can't handle far buffers in the medium and small models, we have to copy
+   the data.
+*/
+
+#define NEAR_BUF_SIZE 1024
+#define MIN(a,b) (a <= b ? a : b)
+
+static void
+png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   png_uint_32 check;
+   png_byte *near_data;  /* Needs to be "png_byte *" instead of "png_bytep" */
+   FILE *io_ptr;
+
+   /* Check if data really is near. If so, use usual code. */
+   near_data = (png_byte *)CVT_PTR_NOCHECK(data);
+   io_ptr = (FILE *)CVT_PTR(png_ptr->io_ptr);
+   if ((png_bytep)near_data == data)
+   {
+      check = fwrite(near_data, 1, length, io_ptr);
+   }
+   else
+   {
+      png_byte buf[NEAR_BUF_SIZE];
+      png_size_t written, remaining, err;
+      check = 0;
+      remaining = length;
+      do
+      {
+         written = MIN(NEAR_BUF_SIZE, remaining);
+         png_memcpy(buf, data, written); /* copy far buffer to near buffer */
+         err = fwrite(buf, 1, written, io_ptr);
+         if (err != written)
+            break;
+         else
+            check += err;
+         data += written;
+         remaining -= written;
+      }
+      while (remaining != 0);
+   }
+   if (check != length)
+   {
+      png_error(png_ptr, "Write Error");
+   }
+}
+
+#endif /* USE_FAR_KEYWORD */
+
+/* This function is called when there is a warning, but the library thinks
+ * it can continue anyway.  Replacement functions don't have to do anything
+ * here if you don't want to.  In the default configuration, png_ptr is
+ * not used, but it is passed in case it may be useful.
+ */
+static void
+png_default_warning(png_structp png_ptr, png_const_charp message)
+{
+   PNG_CONST char *name = "UNKNOWN (ERROR!)";
+   if (png_ptr != NULL && png_ptr->error_ptr != NULL)
+      name = png_ptr->error_ptr;
+   fprintf(STDERR, "%s: libpng warning: %s\n", name, message);
+}
+
+/* This is the default error handling function.  Note that replacements for
+ * this function MUST NOT RETURN, or the program will likely crash.  This
+ * function is used by default, or if the program supplies NULL for the
+ * error function pointer in png_set_error_fn().
+ */
+static void
+png_default_error(png_structp png_ptr, png_const_charp message)
+{
+   png_default_warning(png_ptr, message);
+   /* We can return because png_error calls the default handler which is
+    * actually ok in this case. */
+}
+#endif /* PNG_NO_STDIO */
+/* END of code to validate stdio-free compilation */
+
+/* START of code to validate memory allocation and deallocation */
+#ifdef PNGTEST_MEMORY_DEBUG
+/* Borland DOS special memory handler */
+#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
+ERROR - memory debugging is not supported on this platform
+#else
+
+/* Allocate memory.  For reasonable files, size should never exceed
+   64K.  However, zlib may allocate more then 64K if you don't tell
+   it not to.  See zconf.h and png.h for more information.  zlib does
+   need to allocate exactly 64K, so whatever you call here must
+   have the ability to do that.
+
+   This piece of code can be compiled to validate max 64K allocations
+   by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K. */
+typedef struct memory_information {
+   png_uint_32                    size;
+   png_voidp                      pointer;
+   struct memory_information FAR *next;
+} memory_information;
+typedef memory_information FAR *memory_infop;
+
+static memory_infop pinformation = NULL;
+static int current_allocation = 0;
+static int maximum_allocation = 0;
+
+extern PNG_EXPORT(png_voidp,png_debug_malloc) PNGARG((png_structp png_ptr,
+   png_uint_32 size));
+extern PNG_EXPORT(void,png_debug_free) PNGARG((png_structp png_ptr,
+   png_voidp ptr));
+
+png_voidp
+png_malloc(png_structp png_ptr, png_uint_32 size) {
+   if (png_ptr == NULL) {
+      fprintf(STDERR, "NULL pointer to memory allocator\n");
+      return (NULL);
+   }
+   if (size == 0)
+      return (png_voidp)(NULL);
+
+   /* This calls the library allocator twice, once to get the requested
+      buffer and once to get a new free list entry. */
+   {
+      memory_infop pinfo = png_debug_malloc(png_ptr, sizeof *pinfo);
+      pinfo->size = size;
+      current_allocation += size;
+      if (current_allocation > maximum_allocation)
+         maximum_allocation = current_allocation;
+      pinfo->pointer = png_debug_malloc(png_ptr, size);
+      pinfo->next = pinformation;
+      pinformation = pinfo;
+      /* Make sure the caller isn't assuming zeroed memory. */
+      png_memset(pinfo->pointer, 0xdd, pinfo->size);
+      return (png_voidp)(pinfo->pointer);
+   }
+}
+
+/* Free a pointer.  It is removed from the list at the same time. */
+void
+png_free(png_structp png_ptr, png_voidp ptr)
+{
+   if (png_ptr == NULL)
+      fprintf(STDERR, "NULL pointer to memory allocator\n");
+   if (ptr == 0) {
+#if 0 /* This happens all the time. */
+      fprintf(STDERR, "WARNING: freeing NULL pointer\n");
+#endif
+      return;
+   }
+
+   /* Unlink the element from the list. */
+   {
+      memory_infop FAR *ppinfo = &pinformation;
+      for (;;) {
+         memory_infop pinfo = *ppinfo;
+         if (pinfo->pointer == ptr) {
+            *ppinfo = pinfo->next;
+            current_allocation -= pinfo->size;
+            if (current_allocation < 0)
+               fprintf(STDERR, "Duplicate free of memory\n");
+            /* We must free the list element too, but first kill
+               the memory which is to be freed. */
+            memset(ptr, 0x55, pinfo->size);
+            png_debug_free(png_ptr, pinfo);
+            break;
+         }
+         if (pinfo->next == NULL) {
+            fprintf(STDERR, "Pointer %x not found\n", ptr);
+            break;
+         }
+         ppinfo = &pinfo->next;
+      }
+   }
+
+   /* Finally free the data. */
+   png_debug_free(png_ptr, ptr);
+}
+#endif /* Not Borland DOS special memory handler */
+#endif
+/* END of code to test memory allocation/deallocation */
+
+/* Test one file */
+int
+test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
+{
+   static FILE *fpin, *fpout;  /* "static" prevents setjmp corruption */
+   png_structp read_ptr, write_ptr;
+   png_infop read_info_ptr, write_info_ptr, end_info_ptr;
+   png_bytep row_buf;
+   png_uint_32 y;
+   png_uint_32 width, height;
+   int num_pass, pass;
+   int bit_depth, color_type;
+#ifdef USE_FAR_KEYWORD
+   jmp_buf jmpbuf;
+#endif   
+   
+   char inbuf[256], outbuf[256];
+
+   row_buf = (png_bytep)NULL;
+
+   if ((fpin = fopen(inname, "rb")) == NULL)
+   {
+      fprintf(STDERR, "Could not find input file %s\n", inname);
+      return (1);
+   }
+
+   if ((fpout = fopen(outname, "wb")) == NULL)
+   {
+      fprintf(STDERR, "Could not open output file %s\n", outname);
+      fclose(fpin);
+      return (1);
+   }
+
+   png_debug(0, "Allocating read and write structures\n");
+   read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
+      (png_error_ptr)NULL, (png_error_ptr)NULL);
+#if defined(PNG_NO_STDIO)
+   png_set_error_fn(read_ptr, (png_voidp)inname, png_default_error,
+       png_default_warning);
+#endif
+   write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
+      (png_error_ptr)NULL, (png_error_ptr)NULL);
+#if defined(PNG_NO_STDIO)
+   png_set_error_fn(write_ptr, (png_voidp)inname, png_default_error,
+       png_default_warning);
+#endif
+   png_debug(0, "Allocating read_info, write_info and end_info structures\n");
+   read_info_ptr = png_create_info_struct(read_ptr);
+   write_info_ptr = png_create_info_struct(write_ptr);
+   end_info_ptr = png_create_info_struct(read_ptr);
+
+   png_debug(0, "Setting jmpbuf for read struct\n");
+#ifdef USE_FAR_KEYWORD
+   if (setjmp(jmpbuf))
+#else
+   if (setjmp(read_ptr->jmpbuf))
+#endif
+   {
+      fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
+      png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
+      png_destroy_write_struct(&write_ptr, &write_info_ptr);
+      fclose(fpin);
+      fclose(fpout);
+      return (1);
+   }
+
+   png_debug(0, "Setting jmpbuf for write struct\n");
+#ifdef USE_FAR_KEYWORD
+   png_memcpy(read_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
+   if (setjmp(jmpbuf))
+#else
+   if (setjmp(write_ptr->jmpbuf))
+#endif
+   {
+      fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname);
+      png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
+      png_destroy_write_struct(&write_ptr, &write_info_ptr);
+      fclose(fpin);
+      fclose(fpout);
+      return (1);
+   }
+
+#ifdef USE_FAR_KEYWORD
+   png_memcpy(write_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
+#endif
+   png_debug(0, "Initializing input and output streams\n");
+#if !defined(PNG_NO_STDIO)
+   png_init_io(read_ptr, fpin);
+   png_init_io(write_ptr, fpout);
+#else
+   png_set_read_fn(read_ptr, (png_voidp)fpin, png_default_read_data);
+   png_set_write_fn(write_ptr, (png_voidp)fpout,  png_default_write_data,
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+      png_default_flush);
+#else
+      NULL);
+#endif
+#endif
+   if(status_dots_requested == 1)
+   {
+      png_set_write_status_fn(write_ptr, write_row_callback);
+      png_set_read_status_fn(read_ptr, read_row_callback);
+   }
+   else
+   {
+      png_set_write_status_fn(write_ptr, NULL);
+      png_set_read_status_fn(read_ptr, NULL);
+   }
+
+#  if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+     black_pixels=0;
+     png_set_write_user_transform_fn(write_ptr, count_black_pixels);
+#  endif
+
+   png_debug(0, "Reading info struct\n");
+   png_read_info(read_ptr, read_info_ptr);
+
+   png_debug(0, "Transferring info struct\n");
+   {
+      int interlace_type, compression_type, filter_type;
+
+      if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth,
+          &color_type, &interlace_type, &compression_type, &filter_type))
+      {
+         png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth,
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+            color_type, interlace_type, compression_type, filter_type);
+#else
+            color_type, PNG_INTERLACE_NONE, compression_type, filter_type);
+#endif
+      }
+   }
+#if defined(PNG_READ_bKGD_SUPPORTED) && defined(PNG_WRITE_bKGD_SUPPORTED)
+   {
+      png_color_16p background;
+
+      if (png_get_bKGD(read_ptr, read_info_ptr, &background))
+      {
+         png_set_bKGD(write_ptr, write_info_ptr, background);
+      }
+   }
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED) && defined(PNG_WRITE_cHRM_SUPPORTED)
+   {
+      double white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
+
+      if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
+         &red_y, &green_x, &green_y, &blue_x, &blue_y))
+      {
+         png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x,
+            red_y, green_x, green_y, blue_x, blue_y);
+      }
+   }
+#endif
+#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_WRITE_gAMA_SUPPORTED)
+   {
+      double gamma;
+
+      if (png_get_gAMA(read_ptr, read_info_ptr, &gamma))
+      {
+         png_set_gAMA(write_ptr, write_info_ptr, gamma);
+      }
+   }
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED) && defined(PNG_WRITE_sRGB_SUPPORTED)
+   {
+      int intent;
+
+      if (png_get_sRGB(read_ptr, read_info_ptr, &intent))
+      {
+         png_set_sRGB(write_ptr, write_info_ptr, intent);
+      }
+   }
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED) && defined(PNG_WRITE_hIST_SUPPORTED)
+   {
+      png_uint_16p hist;
+
+      if (png_get_hIST(read_ptr, read_info_ptr, &hist))
+      {
+         png_set_hIST(write_ptr, write_info_ptr, hist);
+      }
+   }
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED) && defined(PNG_WRITE_oFFs_SUPPORTED)
+   {
+      png_uint_32 offset_x, offset_y;
+      int unit_type;
+
+      if (png_get_oFFs(read_ptr, read_info_ptr,&offset_x,&offset_y,&unit_type))
+      {
+         png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type);
+      }
+   }
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED) && defined(PNG_WRITE_pCAL_SUPPORTED)
+   {
+      png_charp purpose, units;
+      png_charpp params;
+      png_int_32 X0, X1;
+      int type, nparams;
+
+      if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type,
+         &nparams, &units, &params))
+      {
+         png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type,
+            nparams, units, params);
+      }
+   }
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED) && defined(PNG_WRITE_pHYs_SUPPORTED)
+   {
+      png_uint_32 res_x, res_y;
+      int unit_type;
+
+      if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type))
+      {
+         png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type);
+      }
+   }
+#endif
+   {
+      png_colorp palette;
+      int num_palette;
+
+      if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette))
+      {
+         png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette);
+      }
+   }
+#if defined(PNG_READ_sBIT_SUPPORTED) && defined(PNG_WRITE_sBIT_SUPPORTED)
+   {
+      png_color_8p sig_bit;
+
+      if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit))
+      {
+         png_set_sBIT(write_ptr, write_info_ptr, sig_bit);
+      }
+   }
+#endif
+#if (defined(PNG_READ_tEXt_SUPPORTED) && defined(PNG_WRITE_tEXt_SUPPORTED)) || \
+    (defined(PNG_READ_zTXt_SUPPORTED) && defined(PNG_WRITE_zTXt_SUPPORTED))
+   {
+      png_textp text_ptr;
+      int num_text;
+
+      if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0)
+      {
+         png_debug1(0, "Handling %d tEXt/zTXt chunks\n", num_text);
+         png_set_text(write_ptr, write_info_ptr, text_ptr, num_text);
+      }
+   }
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED) && defined(PNG_WRITE_tIME_SUPPORTED)
+   {
+      png_timep mod_time;
+
+      if (png_get_tIME(read_ptr, read_info_ptr, &mod_time))
+      {
+         png_set_tIME(write_ptr, write_info_ptr, mod_time);
+      }
+   }
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED) && defined(PNG_WRITE_tRNS_SUPPORTED)
+   {
+      png_bytep trans;
+      int num_trans;
+      png_color_16p trans_values;
+
+      if (png_get_tRNS(read_ptr, read_info_ptr, &trans, &num_trans,
+         &trans_values))
+      {
+         png_set_tRNS(write_ptr, write_info_ptr, trans, num_trans,
+            trans_values);
+      }
+   }
+#endif
+
+   png_debug(0, "\nWriting info struct\n");
+   png_write_info(write_ptr, write_info_ptr);
+
+   png_debug(0, "\nAllocating row buffer \n");
+   row_buf = (png_bytep)png_malloc(read_ptr, 
+      png_get_rowbytes(read_ptr, read_info_ptr));
+   if (row_buf == NULL)
+   {
+      fprintf(STDERR, "No memory to allocate row buffer\n");
+      png_destroy_read_struct(&read_ptr, &read_info_ptr, (png_infopp)NULL);
+      png_destroy_write_struct(&write_ptr, &write_info_ptr);
+      fclose(fpin);
+      fclose(fpout);
+      return (1);
+   }
+   png_debug(0, "Writing row data\n");
+
+   num_pass = png_set_interlace_handling(read_ptr);
+   png_set_interlace_handling(write_ptr);
+
+   for (pass = 0; pass < num_pass; pass++)
+   {
+      png_debug1(0, "Writing row data for pass %d\n",pass);
+      for (y = 0; y < height; y++)
+      {
+         png_read_rows(read_ptr, (png_bytepp)&row_buf, (png_bytepp)NULL, 1);
+         png_write_rows(write_ptr, (png_bytepp)&row_buf, 1);
+      }
+   }
+
+   png_debug(0, "Reading and writing end_info data\n");
+   png_read_end(read_ptr, end_info_ptr);
+   png_write_end(write_ptr, end_info_ptr);
+ 
+#ifdef PNG_EASY_ACCESS_SUPPORTED
+   if(verbose)
+   {
+      png_uint_32 iwidth, iheight;
+      iwidth = png_get_image_width(write_ptr, write_info_ptr);
+      iheight = png_get_image_height(write_ptr, write_info_ptr);
+      fprintf(STDERR, "Image width = %lu, height = %lu\n",
+         iwidth, iheight);
+   }
+#endif
+
+   png_debug(0, "Destroying data structs\n");
+   png_free(read_ptr, row_buf);
+   png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
+   png_destroy_write_struct(&write_ptr, &write_info_ptr);
+
+   fclose(fpin);
+   fclose(fpout);
+
+   png_debug(0, "Opening files for comparison\n");
+   if ((fpin = fopen(inname, "rb")) == NULL)
+   {
+      fprintf(STDERR, "Could not find file %s\n", inname);
+      return (1);
+   }
+
+   if ((fpout = fopen(outname, "rb")) == NULL)
+   {
+      fprintf(STDERR, "Could not find file %s\n", outname);
+      fclose(fpin);
+      return (1);
+   }
+
+   for(;;)
+   {
+      png_size_t num_in, num_out;
+
+      num_in = fread(inbuf, 1, 1, fpin);
+      num_out = fread(outbuf, 1, 1, fpout);
+
+      if (num_in != num_out)
+      {
+         fprintf(STDERR, "Files %s and %s are of a different size\n",
+                 inname, outname);
+         if(wrote_question == 0)
+         {
+            fprintf(STDERR,
+              "   Was %s written with the same chunk size (8k),",inname);
+            fprintf(STDERR,
+              " filtering\n   heuristic (libpng default), compression");
+            fprintf(STDERR,
+              " level (zlib default)\n   and zlib version (%s)?\n\n",
+              ZLIB_VERSION);
+            wrote_question=1;
+         }
+         fclose(fpin);
+         fclose(fpout);
+         return (0);
+      }
+
+      if (!num_in)
+         break;
+
+      if (png_memcmp(inbuf, outbuf, num_in))
+      {
+         fprintf(STDERR, "Files %s and %s are different\n", inname, outname);
+         if(wrote_question == 0)
+         {
+            fprintf(STDERR,
+              "   Was %s written with the same chunk size (8k),",inname);
+            fprintf(STDERR,
+              " filtering\n   heuristic (libpng default), compression");
+            fprintf(STDERR,
+              " level (zlib default)\n   and zlib version (%s)?\n\n",
+              ZLIB_VERSION);
+            wrote_question=1;
+         }
+         fclose(fpin);
+         fclose(fpout);
+         return (0);
+      }
+   }
+
+   fclose(fpin);
+   fclose(fpout);
+
+   return (0);
+}
+
+/* input and output filenames */
+#ifdef RISCOS
+PNG_CONST char *inname = "pngtest/png";
+PNG_CONST char *outname = "pngout/png";
+#else
+static PNG_CONST char *inname = "pngtest.png";
+static PNG_CONST char *outname = "pngout.png";
+#endif
+
+int
+main(int argc, char *argv[])
+{
+   int multiple = 0;
+   int ierror = 0;
+
+   fprintf(STDERR, "Testing libpng version %s\n", PNG_LIBPNG_VER_STRING);
+   fprintf(STDERR, "   with zlib   version %s\n", ZLIB_VERSION);
+
+   /* Do some consistency checking on the memory allocation settings, I'm
+      not sure this matters, but it is nice to know, the first of these
+      tests should be impossible because of the way the macros are set
+      in pngconf.h */
+#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
+      fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n");
+#endif
+   /* I think the following can happen. */
+#if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K)
+      fprintf(STDERR, " NOTE: libpng compiled for max 64k, zlib not\n");
+#endif
+
+   if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING))
+   {
+      fprintf(STDERR,
+         "Warning: versions are different between png.h and png.c\n");
+      fprintf(STDERR, "  png.h version: %s\n", PNG_LIBPNG_VER_STRING);
+      fprintf(STDERR, "  png.c version: %s\n\n", png_libpng_ver);
+      ++ierror;
+   }
+
+   if (argc > 1)
+   {
+      if (strcmp(argv[1], "-m") == 0)
+      {
+         multiple = 1;
+         status_dots_requested = 0;
+      }
+      else if (strcmp(argv[1], "-mv") == 0 ||
+               strcmp(argv[1], "-vm") == 0 )
+      {
+         multiple = 1;
+         verbose = 1;
+         status_dots_requested = 1;
+      }
+      else if (strcmp(argv[1], "-v") == 0)
+      {
+         verbose = 1;
+         status_dots_requested = 1;
+         inname = argv[2];
+      }
+      else
+      {
+         inname = argv[1];
+         status_dots_requested = 0;
+      }
+   }
+
+   if (!multiple && argc == 3+verbose)
+     outname = argv[2+verbose];
+
+   if ((!multiple && argc > 3+verbose) || (multiple && argc < 2))
+   {
+     fprintf(STDERR,
+       "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
+        argv[0], argv[0]);
+     fprintf(STDERR,
+       "  reads/writes one PNG file (without -m) or multiple files (-m)\n");
+     fprintf(STDERR,
+       "  with -m %s is used as a temporary file\n", outname);
+     exit(1);
+   }
+
+   if (multiple)
+   {
+      int i;
+#ifdef PNGTEST_MEMORY_DEBUG
+      int allocation_now = current_allocation;
+#endif
+      for (i=2; i<argc; ++i)
+      {
+         int kerror;
+         fprintf(STDERR, "Testing %s:",argv[i]);
+         kerror = test_one_file(argv[i], outname);
+         if (kerror == 0) 
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+            fprintf(STDERR, " PASS (%lu black pixels)\n",black_pixels);
+#else
+            fprintf(STDERR, " PASS\n");
+#endif
+         else {
+            fprintf(STDERR, " FAIL\n");
+            ierror += kerror;
+            }
+#ifdef PNGTEST_MEMORY_DEBUG
+         if (allocation_now != current_allocation)
+            fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
+               current_allocation-allocation_now);
+         if (current_allocation != 0) {
+            memory_infop pinfo = pinformation;
+
+            fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
+               current_allocation);
+            while (pinfo != NULL) {
+               fprintf(STDERR, " %d bytes at %x\n", pinfo->size, pinfo->pointer);
+               pinfo = pinfo->next;
+               }
+         }
+#endif
+      }
+#ifdef PNGTEST_MEMORY_DEBUG
+         fprintf(STDERR, "Maximum memory allocation: %d bytes\n",
+            maximum_allocation);
+#endif
+   }
+   else
+   {
+      int i;
+      for (i=0; i<3; ++i) {
+         int kerror;
+#ifdef PNGTEST_MEMORY_DEBUG
+         int allocation_now = current_allocation;
+#endif
+         if (i == 1) status_dots_requested = 1;
+         else if(verbose == 0)status_dots_requested = 0;
+         if (i == 0 || verbose == 1 || ierror != 0)
+            fprintf(STDERR, "Testing %s:",inname);
+         kerror = test_one_file(inname, outname);
+         if(kerror == 0)
+         {
+            if(verbose == 1 || i == 2)
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+                fprintf(STDERR, " PASS (%lu black pixels)\n",black_pixels);
+#else
+                fprintf(STDERR, " PASS\n");
+#endif
+         }
+         else
+         {
+            if(verbose == 0 && i != 2)
+               fprintf(STDERR, "Testing %s:",inname);
+            fprintf(STDERR, " FAIL\n");
+            ierror += kerror;
+         }
+#ifdef PNGTEST_MEMORY_DEBUG
+         if (allocation_now != current_allocation)
+             fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
+               current_allocation-allocation_now);
+         if (current_allocation != 0) {
+             memory_infop pinfo = pinformation;
+   
+             fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
+                current_allocation);
+             while (pinfo != NULL) {
+                fprintf(STDERR, " %d bytes at %x\n", pinfo->size, pinfo->pointer);
+                pinfo = pinfo->next;
+             }
+          }
+#endif
+       }
+#ifdef PNGTEST_MEMORY_DEBUG
+       fprintf(STDERR, "Maximum memory allocation: %d bytes\n",
+          maximum_allocation);
+#endif
+   }
+
+   if (ierror == 0)
+      fprintf(STDERR, "libpng passes test\n");
+   else
+      fprintf(STDERR, "libpng FAILS test\n");
+   return (int)(ierror != 0);
+}
diff --git a/src/png/pngtrans.c b/src/png/pngtrans.c
new file mode 100644
index 0000000000..d38dbd19de
--- /dev/null
+++ b/src/png/pngtrans.c
@@ -0,0 +1,577 @@
+
+/* pngtrans.c - transforms the data in a row (used by both readers and writers)
+ *
+ * libpng 1.0.1
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Copyright (c) 1998, Glenn Randers-Pehrson
+ * March 15, 1998
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* turn on bgr to rgb mapping */
+void
+png_set_bgr(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_bgr\n");
+   png_ptr->transformations |= PNG_BGR;
+}
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* turn on 16 bit byte swapping */
+void
+png_set_swap(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_swap\n");
+   if (png_ptr->bit_depth == 16)
+      png_ptr->transformations |= PNG_SWAP_BYTES;
+}
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
+/* turn on pixel packing */
+void
+png_set_packing(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_packing\n");
+   if (png_ptr->bit_depth < 8)
+   {
+      png_ptr->transformations |= PNG_PACK;
+      png_ptr->usr_bit_depth = 8;
+   }
+}
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+/* turn on packed pixel swapping */
+void
+png_set_packswap(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_packswap\n");
+   if (png_ptr->bit_depth < 8)
+      png_ptr->transformations |= PNG_PACKSWAP;
+}
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+void
+png_set_shift(png_structp png_ptr, png_color_8p true_bits)
+{
+   png_debug(1, "in png_set_shift\n");
+   png_ptr->transformations |= PNG_SHIFT;
+   png_ptr->shift = *true_bits;
+}
+#endif
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
+    defined(PNG_WRITE_INTERLACING_SUPPORTED)
+int
+png_set_interlace_handling(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_interlace handling\n");
+   if (png_ptr->interlaced)
+   {
+      png_ptr->transformations |= PNG_INTERLACE;
+      return (7);
+   }
+
+   return (1);
+}
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+/* Add a filler byte on read, or remove a filler or alpha byte on write.
+ * The filler type has changed in v0.95 to allow future 2-byte fillers
+ * for 48-bit input data, as well as avoiding problems with some compilers
+ * which don't like bytes as parameters.
+ */
+void
+png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
+{
+   png_debug(1, "in png_set_filler\n");
+   png_ptr->transformations |= PNG_FILLER;
+   png_ptr->filler = (png_byte)filler;
+   if (filler_loc == PNG_FILLER_AFTER)
+      png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
+   else
+      png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
+
+   /* This should probably go in the "do_filler" routine */
+   if (png_ptr->color_type == PNG_COLOR_TYPE_RGB && png_ptr->bit_depth == 8)
+   {
+      png_ptr->usr_channels = 4;
+   }
+}
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
+    defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+void
+png_set_swap_alpha(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_swap_alpha\n");
+   png_ptr->transformations |= PNG_SWAP_ALPHA;
+}
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
+    defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+void
+png_set_invert_alpha(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_invert_alpha\n");
+   png_ptr->transformations |= PNG_INVERT_ALPHA;
+}
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+void
+png_set_invert_mono(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_invert_mono\n");
+   png_ptr->transformations |= PNG_INVERT_MONO;
+}
+
+/* invert monocrome grayscale data */
+void
+png_do_invert(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_invert\n");
+   if (row_info->bit_depth == 1 &&
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL && row_info != NULL &&
+#endif
+       row_info->color_type == PNG_COLOR_TYPE_GRAY)
+   {
+      png_bytep rp;
+      png_uint_32 i;
+
+      for (i = 0, rp = row; i < row_info->rowbytes; i++, rp++)
+      {
+         *rp = (png_byte)(~(*rp));
+      }
+   }
+}
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* swaps byte order on 16 bit depth images */
+void
+png_do_swap(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_swap\n");
+   if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL && row_info != NULL &&
+#endif
+       row_info->bit_depth == 16)
+   {
+      png_bytep rp;
+      png_byte t;
+      png_uint_32 i;
+
+      for (i = 0, rp = row;
+         i < row_info->width * row_info->channels;
+         i++, rp += 2)
+      {
+         t = *rp;
+         *rp = *(rp + 1);
+         *(rp + 1) = t;
+      }
+   }
+}
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+static png_byte onebppswaptable[256] = {
+   0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
+   0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
+   0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
+   0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
+   0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
+   0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
+   0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
+   0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
+   0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
+   0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
+   0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
+   0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
+   0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
+   0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
+   0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
+   0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
+   0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
+   0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
+   0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
+   0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
+   0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
+   0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
+   0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
+   0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
+   0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
+   0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
+   0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
+   0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
+   0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
+   0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
+   0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
+   0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
+};
+
+static png_byte twobppswaptable[256] = {
+   0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
+   0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
+   0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
+   0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
+   0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
+   0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
+   0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
+   0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
+   0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
+   0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
+   0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
+   0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
+   0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
+   0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
+   0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
+   0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
+   0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
+   0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
+   0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
+   0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
+   0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
+   0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
+   0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
+   0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
+   0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
+   0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
+   0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
+   0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
+   0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
+   0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
+   0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
+   0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
+};
+
+static png_byte fourbppswaptable[256] = {
+   0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
+   0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
+   0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
+   0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
+   0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
+   0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
+   0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
+   0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
+   0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
+   0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
+   0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
+   0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
+   0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
+   0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
+   0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
+   0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
+   0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
+   0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
+   0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
+   0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
+   0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
+   0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
+   0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
+   0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
+   0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
+   0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
+   0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
+   0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
+   0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
+   0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
+   0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
+   0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
+};
+
+/* swaps pixel packing order within bytes */
+void
+png_do_packswap(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_packswap\n");
+   if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL && row_info != NULL &&
+#endif
+       row_info->bit_depth < 8)
+   {
+      png_bytep rp, end, table;
+
+      end = row + row_info->rowbytes;
+
+      if (row_info->bit_depth == 1)
+         table = onebppswaptable;
+      else if (row_info->bit_depth == 2)
+         table = twobppswaptable;
+      else if (row_info->bit_depth == 4)
+         table = fourbppswaptable;
+      else
+         return;
+
+      for (rp = row; rp < end; rp++)
+         *rp = table[*rp];
+   }
+}
+#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
+
+#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
+    defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+/* remove filler or alpha byte(s) */
+void
+png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
+{
+   png_debug(1, "in png_do_strip_filler\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+   if (row != NULL && row_info != NULL)
+#endif
+   {
+/*
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB ||
+          row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+*/
+      if (row_info->channels == 4)
+      {
+         if (row_info->bit_depth == 8)
+         {
+            /* This converts from RGBX or RGBA to RGB */
+            if (flags & PNG_FLAG_FILLER_AFTER)
+            {
+               png_bytep sp, dp;
+               png_uint_32 i;
+
+               for (i = 1, sp = row + 4, dp = row + 3; i < row_info->width; i++)
+               {
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  sp++;
+               }
+            }
+            /* This converts from XRGB or ARGB to RGB */
+            else
+            {
+               png_bytep sp, dp;
+               png_uint_32 i;
+
+               for (i = 0, sp = row, dp = row; i < row_info->width; i++)
+               {
+                  sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+               }
+            }
+            row_info->pixel_depth = 24;
+            row_info->rowbytes = row_info->width * 3;
+         }
+         else /* if (row_info->bit_depth == 16) */
+         {
+            if (flags & PNG_FLAG_FILLER_AFTER)
+            {
+               png_bytep sp, dp;
+               png_uint_32 i;
+
+               /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
+               for (i = 1, sp = row + 8, dp = row + 6; i < row_info->width; i++)
+               {
+                  /* This could be (although memcpy is probably slower):
+                  png_memcpy(dp, sp, 6);
+                  sp += 8;
+                  dp += 6;
+                  */
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  sp += 2;
+               }
+            }
+            else
+            {
+               png_bytep sp, dp;
+               png_uint_32 i;
+
+               /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
+               for (i = 0, sp = row + 2, dp = row; i < row_info->width; i++)
+               {
+                  /* This could be (although memcpy is probably slower):
+                  png_memcpy(dp, sp, 6);
+                  sp += 8;
+                  dp += 6;
+                  */
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+               }
+            }
+            row_info->pixel_depth = 48;
+            row_info->rowbytes = row_info->width * 6;
+         }
+         row_info->channels = 3;
+      }
+/*
+      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY ||
+               row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+*/
+      else if (row_info->channels == 2)
+      {
+         if (row_info->bit_depth == 8)
+         {
+            /* This converts from GX or GA to G */
+            if (flags & PNG_FLAG_FILLER_AFTER)
+            {
+               png_bytep sp, dp;
+               png_uint_32 i;
+
+               for (i = 1, sp = row + 2, dp = row + 1; i < row_info->width; i++)
+               {
+                  *dp++ = *sp++;
+                  sp++;
+               }
+            }
+            /* This converts from XG or AG to G */
+            else
+            {
+               png_bytep sp, dp;
+               png_uint_32 i;
+
+               for (i = 0, sp = row, dp = row; i < row_info->width; i++)
+               {
+                  sp++;
+                  *dp++ = *sp++;
+               }
+            }
+            row_info->pixel_depth = 8;
+            row_info->rowbytes = row_info->width;
+         }
+         else /* if (row_info->bit_depth == 16) */
+         {
+            if (flags & PNG_FLAG_FILLER_AFTER)
+            {
+               png_bytep sp, dp;
+               png_uint_32 i;
+
+               /* This converts from GGXX or GGAA to GG */
+               for (i = 1, sp = row + 4, dp = row + 2; i < row_info->width; i++)
+               {
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+                  sp += 2;
+               }
+            }
+            else
+            {
+               png_bytep sp, dp;
+               png_uint_32 i;
+
+               /* This converts from XXGG or AAGG to GG */
+               for (i = 0, sp = row, dp = row; i < row_info->width; i++)
+               {
+                  sp += 2;
+                  *dp++ = *sp++;
+                  *dp++ = *sp++;
+               }
+            }
+            row_info->pixel_depth = 16;
+            row_info->rowbytes = row_info->width * 2;
+         }
+         row_info->channels = 1;
+      }
+   }
+}
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* swaps red and blue bytes within a pixel */
+void
+png_do_bgr(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_bgr\n");
+   if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL && row_info != NULL &&
+#endif
+       (row_info->color_type & PNG_COLOR_MASK_COLOR))
+   {
+      if (row_info->bit_depth == 8)
+      {
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+         {
+            png_bytep rp;
+            png_byte save;
+            png_uint_32 i;
+
+            for (i = 0, rp = row; i < row_info->width; i++, rp += 3)
+            {
+               save = *rp;
+               *rp = *(rp + 2);
+               *(rp + 2) = save;
+            }
+         }
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+         {
+            png_bytep rp;
+            png_byte save;
+            png_uint_32 i;
+
+            for (i = 0, rp = row; i < row_info->width; i++, rp += 4)
+            {
+               save = *rp;
+               *rp = *(rp + 2);
+               *(rp + 2) = save;
+            }
+         }
+      }
+      else if (row_info->bit_depth == 16)
+      {
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+         {
+            png_bytep rp;
+            png_byte save[2];
+            png_uint_32 i;
+
+            for (i = 0, rp = row; i < row_info->width; i++, rp += 6)
+            {
+               save[0] = *rp;
+               save[1] = *(rp + 1);
+               *rp = *(rp + 4);
+               *(rp + 1) = *(rp + 5);
+               *(rp + 4) = save[0];
+               *(rp + 5) = save[1];
+            }
+         }
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+         {
+            png_bytep rp;
+            png_byte save[2];
+            png_uint_32 i;
+
+            for (i = 0, rp = row; i < row_info->width; i++, rp += 8)
+            {
+               save[0] = *rp;
+               save[1] = *(rp + 1);
+               *rp = *(rp + 4);
+               *(rp + 1) = *(rp + 5);
+               *(rp + 4) = save[0];
+               *(rp + 5) = save[1];
+            }
+         }
+      }
+   }
+}
+#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
+
diff --git a/src/png/pngwio.c b/src/png/pngwio.c
new file mode 100644
index 0000000000..444a123b58
--- /dev/null
+++ b/src/png/pngwio.c
@@ -0,0 +1,207 @@
+
+/* pngwio.c - functions for data output
+ *
+ * libpng 1.0.1
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Copyright (c) 1998, Glenn Randers-Pehrson
+ * March 15, 1998
+ *
+ * This file provides a location for all output.  Users which need
+ * special handling are expected to write functions which have the same
+ * arguments as these, and perform similar functions, but possibly use
+ * different output methods.  Note that you shouldn't change these
+ * functions, but rather write replacement functions and then change
+ * them at run time with png_set_write_fn(...).
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+/* Write the data to whatever output you are using.  The default routine
+   writes to a file pointer.  Note that this routine sometimes gets called
+   with very small lengths, so you should implement some kind of simple
+   buffering if you are using unbuffered writes.  This should never be asked
+   to write more then 64K on a 16 bit machine.  */
+
+void
+png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   if (png_ptr->write_data_fn != NULL )
+      (*(png_ptr->write_data_fn))(png_ptr, data, length);
+   else
+      png_error(png_ptr, "Call to NULL write function");
+}
+
+#if !defined(PNG_NO_STDIO)
+/* This is the function which does the actual writing of data.  If you are
+   not writing to a standard C stream, you should create a replacement
+   write_data function and use it at run time with png_set_write_fn(), rather
+   than changing the library. */
+#ifndef USE_FAR_KEYWORD
+static void
+png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   png_uint_32 check;
+
+   check = fwrite(data, 1, length, (FILE *)(png_ptr->io_ptr));
+   if (check != length)
+   {
+      png_error(png_ptr, "Write Error");
+   }
+}
+#else
+/* this is the model-independent version. Since the standard I/O library
+   can't handle far buffers in the medium and small models, we have to copy
+   the data.
+*/
+
+#define NEAR_BUF_SIZE 1024
+#define MIN(a,b) (a <= b ? a : b)
+
+static void
+png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   png_uint_32 check;
+   png_byte *near_data;  /* Needs to be "png_byte *" instead of "png_bytep" */
+   FILE *io_ptr;
+
+   /* Check if data really is near. If so, use usual code. */
+   near_data = (png_byte *)CVT_PTR_NOCHECK(data);
+   io_ptr = (FILE *)CVT_PTR(png_ptr->io_ptr);
+   if ((png_bytep)near_data == data)
+   {
+      check = fwrite(near_data, 1, length, io_ptr);
+   }
+   else
+   {
+      png_byte buf[NEAR_BUF_SIZE];
+      png_size_t written, remaining, err;
+      check = 0;
+      remaining = length;
+      do
+      {
+         written = MIN(NEAR_BUF_SIZE, remaining);
+         png_memcpy(buf, data, written); /* copy far buffer to near buffer */
+         err = fwrite(buf, 1, written, io_ptr);
+         if (err != written)
+            break;
+         else
+            check += err;
+         data += written;
+         remaining -= written;
+      }
+      while (remaining != 0);
+   }
+   if (check != length)
+   {
+      png_error(png_ptr, "Write Error");
+   }
+}
+
+#endif
+#endif
+
+/* This function is called to output any data pending writing (normally
+   to disk).  After png_flush is called, there should be no data pending
+   writing in any buffers. */
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+void
+png_flush(png_structp png_ptr)
+{
+   if (png_ptr->output_flush_fn != NULL)
+      (*(png_ptr->output_flush_fn))(png_ptr);
+}
+
+#if !defined(PNG_NO_STDIO)
+static void
+png_default_flush(png_structp png_ptr)
+{
+   FILE *io_ptr;
+   io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr));
+   if (io_ptr != NULL)
+      fflush(io_ptr);
+}
+#endif
+#endif
+
+/* This function allows the application to supply new output functions for
+   libpng if standard C streams aren't being used.
+
+   This function takes as its arguments:
+   png_ptr       - pointer to a png output data structure
+   io_ptr        - pointer to user supplied structure containing info about
+                   the output functions.  May be NULL.
+   write_data_fn - pointer to a new output function which takes as its
+                   arguments a pointer to a png_struct, a pointer to
+                   data to be written, and a 32-bit unsigned int which is
+                   the number of bytes to be written.  The new write
+                   function should call png_error(png_ptr, "Error msg")
+                   to exit and output any fatal error messages.
+   flush_data_fn - pointer to a new flush function which takes as its
+                   arguments a pointer to a png_struct.  After a call to
+                   the flush function, there should be no data in any buffers
+                   or pending transmission.  If the output method doesn't do
+                   any buffering of ouput, a function prototype must still be
+                   supplied although it doesn't have to do anything.  If
+                   PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
+                   time, output_flush_fn will be ignored, although it must be
+                   supplied for compatibility. */
+void
+png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
+   png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
+{
+   png_ptr->io_ptr = io_ptr;
+
+#if !defined(PNG_NO_STDIO)
+   if (write_data_fn != NULL)
+      png_ptr->write_data_fn = write_data_fn;
+   else
+      png_ptr->write_data_fn = png_default_write_data;
+#else
+   png_ptr->write_data_fn = write_data_fn;
+#endif
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+#if !defined(PNG_NO_STDIO)
+   if (output_flush_fn != NULL)
+      png_ptr->output_flush_fn = output_flush_fn;
+   else
+      png_ptr->output_flush_fn = png_default_flush;
+#else
+   png_ptr->output_flush_fn = output_flush_fn;
+#endif
+#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+
+   /* It is an error to read while writing a png file */
+   png_ptr->read_data_fn = NULL;
+}
+
+#if defined(USE_FAR_KEYWORD) 
+#if defined(_MSC_VER)   
+void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check)
+{
+   void *near_ptr;   
+   void FAR *far_ptr;
+   FP_OFF(near_ptr) = FP_OFF(ptr);
+   far_ptr = (void FAR *)near_ptr;
+   if(check != 0)
+      if(FP_SEG(ptr) != FP_SEG(far_ptr))
+         png_error(png_ptr,"segment lost in conversion");
+   return(near_ptr);
+}
+#  else
+void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check)
+{
+   void *near_ptr;   
+   void FAR *far_ptr;
+   near_ptr = (void FAR *)ptr;
+   far_ptr = (void FAR *)near_ptr;
+   if(check != 0)
+      if(far_ptr != ptr)
+         png_error(png_ptr,"segment lost in conversion");
+   return(near_ptr);
+}
+#   endif
+#   endif
diff --git a/src/png/pngwrite.c b/src/png/pngwrite.c
new file mode 100644
index 0000000000..9980027e30
--- /dev/null
+++ b/src/png/pngwrite.c
@@ -0,0 +1,970 @@
+   
+/* pngwrite.c - general routines to write a PNG file
+ *
+ * libpng 1.0.1
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Copyright (c) 1998, Glenn Randers-Pehrson
+ * March 15, 1998
+ */
+
+/* get internal access to png.h */
+#define PNG_INTERNAL
+#include "png.h"
+
+/* Writes all the PNG information.  This is the suggested way to use the
+ * library.  If you have a new chunk to add, make a function to write it,
+ * and put it in the correct location here.  If you want the chunk written
+ * after the image data, put it in png_write_end().  I strongly encurage
+ * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing
+ * the chunk, as that will keep the code from breaking if you want to just
+ * write a plain PNG file.  If you have long comments, I suggest writing
+ * them in png_write_end(), and compressing them.
+ */
+void
+png_write_info(png_structp png_ptr, png_infop info_ptr)
+{
+#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
+   int i;
+#endif
+
+   png_debug(1, "in png_write_info\n");
+   png_write_sig(png_ptr); /* write PNG signature */
+   /* write IHDR information. */
+   png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,
+      info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type,
+      info_ptr->filter_type,
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+      info_ptr->interlace_type);
+#else
+      0);
+#endif
+   /* the rest of these check to see if the valid field has the appropriate
+      flag set, and if it does, writes the chunk. */
+#if defined(PNG_WRITE_gAMA_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_gAMA)
+      png_write_gAMA(png_ptr, info_ptr->gamma);
+#endif
+#if defined(PNG_WRITE_sRGB_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_sRGB)
+      png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent);
+#endif
+#if defined(PNG_WRITE_sBIT_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_sBIT)
+      png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type);
+#endif
+#if defined(PNG_WRITE_cHRM_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_cHRM)
+      png_write_cHRM(png_ptr,
+         info_ptr->x_white, info_ptr->y_white,
+         info_ptr->x_red, info_ptr->y_red,
+         info_ptr->x_green, info_ptr->y_green,
+         info_ptr->x_blue, info_ptr->y_blue);
+#endif
+   if (info_ptr->valid & PNG_INFO_PLTE)
+      png_write_PLTE(png_ptr, info_ptr->palette,
+         (png_uint_32)info_ptr->num_palette);
+   else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      png_error(png_ptr, "Valid palette required for paletted images\n");
+
+#if defined(PNG_WRITE_tRNS_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_tRNS)
+      {
+#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+         /* invert the alpha channel (in tRNS) */
+         if (png_ptr->transformations & PNG_INVERT_ALPHA &&
+            info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+         {
+            int j;
+            for (j=0; j<(int)info_ptr->num_trans; j++)
+               info_ptr->trans[j] = 255 - info_ptr->trans[j];
+         }
+#endif
+      png_write_tRNS(png_ptr, info_ptr->trans, &(info_ptr->trans_values),
+         info_ptr->num_trans, info_ptr->color_type);
+      }
+#endif
+#if defined(PNG_WRITE_bKGD_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_bKGD)
+      png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type);
+#endif
+#if defined(PNG_WRITE_hIST_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_hIST)
+      png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
+#endif
+#if defined(PNG_WRITE_oFFs_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_oFFs)
+      png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset,
+         info_ptr->offset_unit_type);
+#endif
+#if defined(PNG_WRITE_pCAL_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_pCAL)
+      png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0,
+         info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams,
+         info_ptr->pcal_units, info_ptr->pcal_params);
+#endif
+#if defined(PNG_WRITE_pHYs_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_pHYs)
+      png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit,
+         info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type);
+#endif
+#if defined(PNG_WRITE_tIME_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_tIME)
+   {
+      png_write_tIME(png_ptr, &(info_ptr->mod_time));
+      png_ptr->flags |= PNG_FLAG_WROTE_tIME;
+   }
+#endif
+#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
+   /* Check to see if we need to write text chunks */
+   for (i = 0; i < info_ptr->num_text; i++)
+   {
+      png_debug2(2, "Writing header text chunk %d, type %d\n", i,
+         info_ptr->text[i].compression);
+      /* If we want a compressed text chunk */
+      if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
+      {
+#if defined(PNG_WRITE_zTXt_SUPPORTED)
+         /* write compressed chunk */
+         png_write_zTXt(png_ptr, info_ptr->text[i].key,
+            info_ptr->text[i].text, info_ptr->text[i].text_length,
+            info_ptr->text[i].compression);
+#else
+         png_warning(png_ptr, "Unable to write compressed text\n");
+#endif
+         /* Mark this chunk as written */
+         info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
+      }
+      else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
+      {
+#if defined(PNG_WRITE_tEXt_SUPPORTED)
+         /* write uncompressed chunk */
+         png_write_tEXt(png_ptr, info_ptr->text[i].key,
+            info_ptr->text[i].text, info_ptr->text[i].text_length);
+#else
+         png_warning(png_ptr, "Unable to write uncompressed text\n");
+#endif
+         /* Mark this chunk as written */
+         info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+      }
+   }
+#endif
+}
+
+/* Writes the end of the PNG file.  If you don't want to write comments or
+ * time information, you can pass NULL for info.  If you already wrote these
+ * in png_write_info(), do not write them again here.  If you have long
+ * comments, I suggest writing them here, and compressing them.
+ */
+void
+png_write_end(png_structp png_ptr, png_infop info_ptr)
+{
+   png_debug(1, "in png_write_end\n");
+   if (!(png_ptr->mode & PNG_HAVE_IDAT))
+      png_error(png_ptr, "No IDATs written into file");
+
+   /* see if user wants us to write information chunks */
+   if (info_ptr != NULL)
+   {
+#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
+      int i; /* local index variable */
+#endif
+#if defined(PNG_WRITE_tIME_SUPPORTED)
+      /* check to see if user has supplied a time chunk */
+      if (info_ptr->valid & PNG_INFO_tIME &&
+         !(png_ptr->flags & PNG_FLAG_WROTE_tIME))
+         png_write_tIME(png_ptr, &(info_ptr->mod_time));
+#endif
+#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
+      /* loop through comment chunks */
+      for (i = 0; i < info_ptr->num_text; i++)
+      {
+         png_debug2(2, "Writing trailer text chunk %d, type %d\n", i,
+            info_ptr->text[i].compression);
+         if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
+         {
+#if defined(PNG_WRITE_zTXt_SUPPORTED)
+            /* write compressed chunk */
+            png_write_zTXt(png_ptr, info_ptr->text[i].key,
+               info_ptr->text[i].text, info_ptr->text[i].text_length,
+               info_ptr->text[i].compression);
+#else
+            png_warning(png_ptr, "Unable to write compressed text\n");
+#endif
+            /* Mark this chunk as written */
+            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
+         }
+         else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
+         {
+#if defined(PNG_WRITE_tEXt_SUPPORTED)
+            /* write uncompressed chunk */
+            png_write_tEXt(png_ptr, info_ptr->text[i].key,
+               info_ptr->text[i].text, info_ptr->text[i].text_length);
+#else
+            png_warning(png_ptr, "Unable to write uncompressed text\n");
+#endif
+
+            /* Mark this chunk as written */
+            info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+         }
+      }
+#endif
+   }
+
+   png_ptr->mode |= PNG_AFTER_IDAT;
+
+   /* write end of PNG file */
+   png_write_IEND(png_ptr);
+}
+
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+/* Convert the supplied time into an RFC 1123 string suitable for use in
+ * a "Creation Time" or other text-based time string.
+ */
+png_charp
+png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)
+{
+   static PNG_CONST char short_months[12][4] =
+	{"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+	 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+
+   if (png_ptr->time_buffer == NULL)
+   {
+      png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29*
+         sizeof(char)));
+   }
+
+#ifdef USE_FAR_KEYWORD
+   {
+      char near_time_buf[29];
+      sprintf(near_time_buf, "%d %s %d %02d:%02d:%02d +0000",
+               ptime->day % 31, short_months[ptime->month - 1],
+               ptime->year, ptime->hour % 24, ptime->minute % 60,
+               ptime->second % 61);
+      png_memcpy(png_ptr->time_buffer, near_time_buf,
+      29*sizeof(char));
+   }
+#else
+   sprintf(png_ptr->time_buffer, "%d %s %d %02d:%02d:%02d +0000",
+               ptime->day % 31, short_months[ptime->month - 1],
+               ptime->year, ptime->hour % 24, ptime->minute % 60,
+               ptime->second % 61);
+#endif
+   return ((png_charp)png_ptr->time_buffer);
+}
+#endif /* PNG_TIME_RFC1123_SUPPORTED */
+
+#if defined(PNG_WRITE_tIME_SUPPORTED)
+void
+png_convert_from_struct_tm(png_timep ptime, struct tm FAR * ttime)
+{
+   png_debug(1, "in png_convert_from_struct_tm\n");
+   ptime->year = (png_uint_16)(1900 + ttime->tm_year);
+   ptime->month = (png_byte)(ttime->tm_mon + 1);
+   ptime->day = (png_byte)ttime->tm_mday;
+   ptime->hour = (png_byte)ttime->tm_hour;
+   ptime->minute = (png_byte)ttime->tm_min;
+   ptime->second = (png_byte)ttime->tm_sec;
+}
+
+void
+png_convert_from_time_t(png_timep ptime, time_t ttime)
+{
+   struct tm *tbuf;
+
+   png_debug(1, "in png_convert_from_time_t\n");
+   tbuf = gmtime(&ttime);
+   png_convert_from_struct_tm(ptime, tbuf);
+}
+#endif
+
+/* Initialize png_ptr structure, and allocate any memory needed */
+png_structp
+png_create_write_struct(png_const_charp user_png_ver, voidp error_ptr,
+   png_error_ptr error_fn, png_error_ptr warn_fn)
+{
+   png_structp png_ptr;
+#ifdef USE_FAR_KEYWORD
+   jmp_buf jmpbuf;
+#endif
+   png_debug(1, "in png_create_write_struct\n");
+   if ((png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG)) == NULL)
+   {
+      return ((png_structp)NULL);
+   }
+#ifdef USE_FAR_KEYWORD
+   if (setjmp(jmpbuf))
+#else
+   if (setjmp(png_ptr->jmpbuf))
+#endif
+   {
+      png_free(png_ptr, png_ptr->zbuf);
+      png_destroy_struct(png_ptr);
+      return ((png_structp)NULL);
+   }
+#ifdef USE_FAR_KEYWORD
+   png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
+#endif
+   png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
+
+   /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
+    * we must recompile any applications that use any older library version.
+    * For versions after libpng 1.0, we will be compatible, so we need
+    * only check the first digit.
+    */
+   if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
+       (png_libpng_ver[0] == '0' && user_png_ver[2] < '9'))
+   {
+      png_error(png_ptr,
+         "Incompatible libpng version in application and library");
+   }
+
+   /* initialize zbuf - compression buffer */
+   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
+   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
+      (png_uint_32)png_ptr->zbuf_size);
+
+   png_set_write_fn(png_ptr, NULL, NULL, NULL);
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+   png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT,
+      1, NULL, NULL);
+#endif
+
+   return ((png_structp)png_ptr);
+}
+
+
+/* Initialize png_ptr structure, and allocate any memory needed */
+void
+png_write_init(png_structp png_ptr)
+{
+   jmp_buf tmp_jmp; /* to save current jump buffer */
+
+   png_debug(1, "in png_write_init\n");
+   /* save jump buffer and error functions */
+   png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
+
+   /* reset all variables to 0 */
+   png_memset(png_ptr, 0, sizeof (png_struct));
+
+   /* restore jump buffer */
+   png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
+
+   /* initialize zbuf - compression buffer */
+   png_ptr->zbuf_size = PNG_ZBUF_SIZE;
+   png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
+      (png_uint_32)png_ptr->zbuf_size);
+   png_set_write_fn(png_ptr, NULL, NULL, NULL);
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+   png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT,
+      1, NULL, NULL);
+#endif
+}
+
+/* Write a few rows of image data.  If the image is interlaced,
+ * either you will have to write the 7 sub images, or, if you
+ * have called png_set_interlace_handling(), you will have to
+ * "write" the image seven times.
+ */
+void
+png_write_rows(png_structp png_ptr, png_bytepp row,
+   png_uint_32 num_rows)
+{
+   png_uint_32 i; /* row counter */
+   png_bytepp rp; /* row pointer */
+
+   png_debug(1, "in png_write_rows\n");
+   /* loop through the rows */
+   for (i = 0, rp = row; i < num_rows; i++, rp++)
+   {
+      png_write_row(png_ptr, *rp);
+   }
+}
+
+/* Write the image.  You only need to call this function once, even
+ * if you are writing an interlaced image.
+ */
+void
+png_write_image(png_structp png_ptr, png_bytepp image)
+{
+   png_uint_32 i; /* row index */
+   int pass, num_pass; /* pass variables */
+   png_bytepp rp; /* points to current row */
+
+   png_debug(1, "in png_write_image\n");
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+   /* intialize interlace handling.  If image is not interlaced,
+      this will set pass to 1 */
+   num_pass = png_set_interlace_handling(png_ptr);
+#else
+   num_pass = 1;
+#endif
+   /* loop through passes */
+   for (pass = 0; pass < num_pass; pass++)
+   {
+      /* loop through image */
+      for (i = 0, rp = image; i < png_ptr->height; i++, rp++)
+      {
+         png_write_row(png_ptr, *rp);
+      }
+   }
+}
+
+/* called by user to write a row of image data */
+void
+png_write_row(png_structp png_ptr, png_bytep row)
+{
+   png_debug2(1, "in png_write_row (row %ld, pass %d)\n",
+      png_ptr->row_number, png_ptr->pass);
+   /* initialize transformations and other stuff if first time */
+   if (png_ptr->row_number == 0 && png_ptr->pass == 0)
+   {
+      png_write_start_row(png_ptr);
+   }
+
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+   /* if interlaced and not interested in row, return */
+   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
+   {
+      switch (png_ptr->pass)
+      {
+         case 0:
+            if (png_ptr->row_number & 7)
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 1:
+            if ((png_ptr->row_number & 7) || png_ptr->width < 5)
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 2:
+            if ((png_ptr->row_number & 7) != 4)
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 3:
+            if ((png_ptr->row_number & 3) || png_ptr->width < 3)
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 4:
+            if ((png_ptr->row_number & 3) != 2)
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 5:
+            if ((png_ptr->row_number & 1) || png_ptr->width < 2)
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+         case 6:
+            if (!(png_ptr->row_number & 1))
+            {
+               png_write_finish_row(png_ptr);
+               return;
+            }
+            break;
+      }
+   }
+#endif
+
+   /* set up row info for transformations */
+   png_ptr->row_info.color_type = png_ptr->color_type;
+   png_ptr->row_info.width = png_ptr->usr_width;
+   png_ptr->row_info.channels = png_ptr->usr_channels;
+   png_ptr->row_info.bit_depth = png_ptr->usr_bit_depth;
+   png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
+      png_ptr->row_info.channels);
+
+   png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
+      (png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
+
+   png_debug1(3, "row_info->color_type = %d\n", png_ptr->row_info.color_type);
+   png_debug1(3, "row_info->width = %d\n", png_ptr->row_info.width);
+   png_debug1(3, "row_info->channels = %d\n", png_ptr->row_info.channels);
+   png_debug1(3, "row_info->bit_depth = %d\n", png_ptr->row_info.bit_depth);
+   png_debug1(3, "row_info->pixel_depth = %d\n", png_ptr->row_info.pixel_depth);
+   png_debug1(3, "row_info->rowbytes = %d\n", png_ptr->row_info.rowbytes);
+
+   /* Copy user's row into buffer, leaving room for filter byte. */
+   png_memcpy_check(png_ptr, png_ptr->row_buf + 1, row,
+      png_ptr->row_info.rowbytes);
+
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+   /* handle interlacing */
+   if (png_ptr->interlaced && png_ptr->pass < 6 &&
+      (png_ptr->transformations & PNG_INTERLACE))
+   {
+      png_do_write_interlace(&(png_ptr->row_info),
+         png_ptr->row_buf + 1, png_ptr->pass);
+      /* this should always get caught above, but still ... */
+      if (!(png_ptr->row_info.width))
+      {
+         png_write_finish_row(png_ptr);
+         return;
+      }
+   }
+#endif
+
+   /* handle other transformations */
+   if (png_ptr->transformations)
+      png_do_write_transformations(png_ptr);
+
+   /* Find a filter if necessary, filter the row and write it out. */
+   png_write_find_filter(png_ptr, &(png_ptr->row_info));
+
+   if (png_ptr->write_row_fn != NULL)
+      (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
+}
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+/* Set the automatic flush interval or 0 to turn flushing off */
+void
+png_set_flush(png_structp png_ptr, int nrows)
+{
+   png_debug(1, "in png_set_flush\n");
+   png_ptr->flush_dist = (nrows < 0 ? 0 : nrows);
+}
+
+/* flush the current output buffers now */
+void
+png_write_flush(png_structp png_ptr)
+{
+   int wrote_IDAT;
+
+   png_debug(1, "in png_write_flush\n");
+   /* We have already written out all of the data */
+   if (png_ptr->row_number >= png_ptr->num_rows)
+     return;
+
+   do
+   {
+      int ret;
+
+      /* compress the data */
+      ret = deflate(&png_ptr->zstream, Z_SYNC_FLUSH);
+      wrote_IDAT = 0;
+
+      /* check for compression errors */
+      if (ret != Z_OK)
+      {
+         if (png_ptr->zstream.msg != NULL)
+            png_error(png_ptr, png_ptr->zstream.msg);
+         else
+            png_error(png_ptr, "zlib error");
+      }
+
+      if (!(png_ptr->zstream.avail_out))
+      {
+         /* write the IDAT and reset the zlib output buffer */
+         png_write_IDAT(png_ptr, png_ptr->zbuf,
+                        png_ptr->zbuf_size);
+         png_ptr->zstream.next_out = png_ptr->zbuf;
+         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+         wrote_IDAT = 1;
+      }
+   } while(wrote_IDAT == 1);
+
+   /* If there is any data left to be output, write it into a new IDAT */
+   if (png_ptr->zbuf_size != png_ptr->zstream.avail_out)
+   {
+      /* write the IDAT and reset the zlib output buffer */
+      png_write_IDAT(png_ptr, png_ptr->zbuf,
+                     png_ptr->zbuf_size - png_ptr->zstream.avail_out);
+      png_ptr->zstream.next_out = png_ptr->zbuf;
+      png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+   }
+   png_ptr->flush_rows = 0;
+   png_flush(png_ptr);
+}
+#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+
+/* free all memory used by the write */
+void
+png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)
+{
+   png_structp png_ptr = NULL;
+   png_infop info_ptr = NULL;
+
+   png_debug(1, "in png_destroy_write_struct\n");
+   if (png_ptr_ptr != NULL)
+      png_ptr = *png_ptr_ptr;
+
+   if (info_ptr_ptr != NULL)
+      info_ptr = *info_ptr_ptr;
+
+   if (info_ptr != NULL)
+   {
+#ifdef PNG_WRITE_tEXt_SUPPORTED
+      png_free(png_ptr, info_ptr->text);
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+      png_free(png_ptr, info_ptr->pcal_purpose);
+      png_free(png_ptr, info_ptr->pcal_units);
+      if (info_ptr->pcal_params != NULL)
+      {
+         int i;
+         for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
+         {
+            png_free(png_ptr, info_ptr->pcal_params[i]);
+         }
+         png_free(png_ptr, info_ptr->pcal_params);
+      }
+#endif
+      png_destroy_struct((png_voidp)info_ptr);
+      *info_ptr_ptr = (png_infop)NULL;
+   }
+
+   if (png_ptr != NULL)
+   {
+      png_write_destroy(png_ptr);
+      png_destroy_struct((png_voidp)png_ptr);
+      *png_ptr_ptr = (png_structp)NULL;
+   }
+}
+
+
+/* Free any memory used in png_ptr struct (old method) */
+void
+png_write_destroy(png_structp png_ptr)
+{
+   jmp_buf tmp_jmp; /* save jump buffer */
+   png_error_ptr error_fn;
+   png_error_ptr warning_fn;
+   png_voidp error_ptr;
+
+   png_debug(1, "in png_write_destroy\n");
+   /* free any memory zlib uses */
+   deflateEnd(&png_ptr->zstream);
+
+   /* free our memory.  png_free checks NULL for us. */
+   png_free(png_ptr, png_ptr->zbuf);
+   png_free(png_ptr, png_ptr->row_buf);
+   png_free(png_ptr, png_ptr->prev_row);
+   png_free(png_ptr, png_ptr->sub_row);
+   png_free(png_ptr, png_ptr->up_row);
+   png_free(png_ptr, png_ptr->avg_row);
+   png_free(png_ptr, png_ptr->paeth_row);
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+   png_free(png_ptr, png_ptr->time_buffer);
+#endif /* PNG_TIME_RFC1123_SUPPORTED */
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+   png_free(png_ptr, png_ptr->prev_filters);
+   png_free(png_ptr, png_ptr->filter_weights);
+   png_free(png_ptr, png_ptr->inv_filter_weights);
+   png_free(png_ptr, png_ptr->filter_costs);
+   png_free(png_ptr, png_ptr->inv_filter_costs);
+#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
+
+   /* reset structure */
+   png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
+
+   error_fn = png_ptr->error_fn;
+   warning_fn = png_ptr->warning_fn;
+   error_ptr = png_ptr->error_ptr;
+
+   png_memset(png_ptr, 0, sizeof (png_struct));
+
+   png_ptr->error_fn = error_fn;
+   png_ptr->warning_fn = warning_fn;
+   png_ptr->error_ptr = error_ptr;
+
+   png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
+}
+
+/* Allow the application to select one or more row filters to use. */
+void
+png_set_filter(png_structp png_ptr, int method, int filters)
+{
+   png_debug(1, "in png_set_filter\n");
+   /* We allow 'method' only for future expansion of the base filter method. */
+   if (method == PNG_FILTER_TYPE_BASE)
+   {
+      switch (filters & (PNG_ALL_FILTERS | 0x07))
+      {
+         case 5:
+         case 6:
+         case 7: png_warning(png_ptr, "Unknown row filter for method 0");
+         case PNG_FILTER_VALUE_NONE:  png_ptr->do_filter=PNG_FILTER_NONE; break;
+         case PNG_FILTER_VALUE_SUB:   png_ptr->do_filter=PNG_FILTER_SUB;  break;
+         case PNG_FILTER_VALUE_UP:    png_ptr->do_filter=PNG_FILTER_UP;   break;
+         case PNG_FILTER_VALUE_AVG:   png_ptr->do_filter=PNG_FILTER_AVG;  break;
+         case PNG_FILTER_VALUE_PAETH: png_ptr->do_filter=PNG_FILTER_PAETH;break;
+         default: png_ptr->do_filter = (png_byte)filters; break;
+      }
+
+      /* If we have allocated the row_buf, this means we have already started
+       * with the image and we should have allocated all of the filter buffers
+       * that have been selected.  If prev_row isn't already allocated, then
+       * it is too late to start using the filters that need it, since we
+       * will be missing the data in the previous row.  If an application
+       * wants to start and stop using particular filters during compression,
+       * it should start out with all of the filters, and then add and
+       * remove them after the start of compression.
+       */
+      if (png_ptr->row_buf != NULL)
+      {
+         if (png_ptr->do_filter & PNG_FILTER_SUB && png_ptr->sub_row == NULL)
+         {
+            png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
+              (png_ptr->rowbytes + 1));
+            png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
+         }
+
+         if (png_ptr->do_filter & PNG_FILTER_UP && png_ptr->up_row == NULL)
+         {
+            if (png_ptr->prev_row == NULL)
+            {
+               png_warning(png_ptr, "Can't add Up filter after starting");
+               png_ptr->do_filter &= ~PNG_FILTER_UP;
+            }
+            else
+            {
+               png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
+                  (png_ptr->rowbytes + 1));
+               png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
+            }
+         }
+
+         if (png_ptr->do_filter & PNG_FILTER_AVG && png_ptr->avg_row == NULL)
+         {
+            if (png_ptr->prev_row == NULL)
+            {
+               png_warning(png_ptr, "Can't add Average filter after starting");
+               png_ptr->do_filter &= ~PNG_FILTER_AVG;
+            }
+            else
+            {
+               png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
+                  (png_ptr->rowbytes + 1));
+               png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
+            }
+         }
+
+         if (png_ptr->do_filter & PNG_FILTER_PAETH &&
+             png_ptr->paeth_row == NULL)
+         {
+            if (png_ptr->prev_row == NULL)
+            {
+               png_warning(png_ptr, "Can't add Paeth filter after starting");
+               png_ptr->do_filter &= ~PNG_FILTER_PAETH;
+            }
+            else
+            {
+               png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
+                  (png_ptr->rowbytes + 1));
+               png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
+            }
+         }
+
+         if (png_ptr->do_filter == PNG_NO_FILTERS)
+            png_ptr->do_filter = PNG_FILTER_NONE;
+      }
+   }
+   else
+      png_error(png_ptr, "Unknown custom filter method");
+}
+
+/* This allows us to influence the way in which libpng chooses the "best"
+ * filter for the current scanline.  While the "minimum-sum-of-absolute-
+ * differences metric is relatively fast and effective, there is some
+ * question as to whether it can be improved upon by trying to keep the
+ * filtered data going to zlib more consistent, hopefully resulting in
+ * better compression.
+ */
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)      /* GRR 970116 */
+void
+png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
+   int num_weights, png_doublep filter_weights,
+   png_doublep filter_costs)
+{
+#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
+   int i;
+#endif
+
+   png_debug(1, "in png_set_filter_heuristics\n");
+   if (heuristic_method >= PNG_FILTER_HEURISTIC_LAST)
+   {
+      png_warning(png_ptr, "Unknown filter heuristic method");
+      return;
+   }
+
+   if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT)
+   {
+      heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED;
+   }
+
+   if (num_weights < 0 || filter_weights == NULL ||
+      heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED)
+   {
+      num_weights = 0;
+   }
+
+   png_ptr->num_prev_filters = num_weights;
+   png_ptr->heuristic_method = heuristic_method;
+
+   if (num_weights > 0)
+   {
+      if (png_ptr->prev_filters == NULL)
+      {
+         png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr,
+            (png_uint_32)(sizeof(png_byte) * num_weights));
+
+         /* To make sure that the weighting starts out fairly */
+         for (i = 0; i < num_weights; i++)
+         {
+            png_ptr->prev_filters[i] = 255;
+         }
+      }
+
+      if (png_ptr->filter_weights == NULL)
+      {
+         png_ptr->filter_weights = (png_uint_16p) png_malloc(png_ptr,
+            (png_uint_32)(sizeof(png_uint_16) * num_weights));
+
+         png_ptr->inv_filter_weights = (png_uint_16p) png_malloc(png_ptr,
+            (png_uint_32)(sizeof(png_uint_16) * num_weights));
+
+         for (i = 0; i < num_weights; i++)
+         {
+            png_ptr->inv_filter_weights[i] =
+            png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
+         }
+      }
+
+      for (i = 0; i < num_weights; i++)
+      {
+         if (filter_weights[i] < 0.0)
+         {
+            png_ptr->inv_filter_weights[i] =
+            png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
+         }
+         else
+         {
+            png_ptr->inv_filter_weights[i] =
+               (png_uint_16)((double)PNG_WEIGHT_FACTOR*filter_weights[i]+0.5);
+            png_ptr->filter_weights[i] =
+               (png_uint_16)((double)PNG_WEIGHT_FACTOR/filter_weights[i]+0.5);
+         }
+      }
+   }
+
+   /* If, in the future, there are other filter methods, this would
+    * need to be based on png_ptr->filter.
+    */
+   if (png_ptr->filter_costs == NULL)
+   {
+      png_ptr->filter_costs = (png_uint_16p) png_malloc(png_ptr,
+         (png_uint_32)(sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
+
+      png_ptr->inv_filter_costs = (png_uint_16p) png_malloc(png_ptr,
+         (png_uint_32)(sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
+
+      for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
+      {
+         png_ptr->inv_filter_costs[i] =
+         png_ptr->filter_costs[i] = PNG_COST_FACTOR;
+      }
+   }
+
+   /* Here is where we set the relative costs of the different filters.  We
+    * should take the desired compression level into account when setting
+    * the costs, so that Paeth, for instance, has a high relative cost at low
+    * compression levels, while it has a lower relative cost at higher
+    * compression settings.  The filter types are in order of increasing
+    * relative cost, so it would be possible to do this with an algorithm.
+    */
+   for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
+   {
+      if (filter_costs == NULL || filter_costs[i] < 0.0)
+      {
+         png_ptr->inv_filter_costs[i] =
+         png_ptr->filter_costs[i] = PNG_COST_FACTOR;
+      }
+      else if (filter_costs[i] >= 1.0)
+      {
+         png_ptr->inv_filter_costs[i] =
+            (png_uint_16)((double)PNG_COST_FACTOR / filter_costs[i] + 0.5);
+         png_ptr->filter_costs[i] =
+            (png_uint_16)((double)PNG_COST_FACTOR * filter_costs[i] + 0.5);
+      }
+   }
+}
+#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
+
+void
+png_set_compression_level(png_structp png_ptr, int level)
+{
+   png_debug(1, "in png_set_compression_level\n");
+   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL;
+   png_ptr->zlib_level = level;
+}
+
+void
+png_set_compression_mem_level(png_structp png_ptr, int mem_level)
+{
+   png_debug(1, "in png_set_compression_mem_level\n");
+   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL;
+   png_ptr->zlib_mem_level = mem_level;
+}
+
+void
+png_set_compression_strategy(png_structp png_ptr, int strategy)
+{
+   png_debug(1, "in png_set_compression_strategy\n");
+   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY;
+   png_ptr->zlib_strategy = strategy;
+}
+
+void
+png_set_compression_window_bits(png_structp png_ptr, int window_bits)
+{
+   if (window_bits > 15)
+      png_warning(png_ptr, "Only compression windows <= 32k supported by PNG");
+   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS;
+   png_ptr->zlib_window_bits = window_bits;
+}
+
+void
+png_set_compression_method(png_structp png_ptr, int method)
+{
+   png_debug(1, "in png_set_compression_method\n");
+   if (method != 8)
+      png_warning(png_ptr, "Only compression method 8 is supported by PNG");
+   png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD;
+   png_ptr->zlib_method = method;
+}
+
+void
+png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn)
+{
+   png_ptr->write_row_fn = write_row_fn;
+}
+
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+void
+png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
+   write_user_transform_fn)
+{
+   png_debug(1, "in png_set_write_user_transform_fn\n");
+   png_ptr->transformations |= PNG_USER_TRANSFORM;
+   png_ptr->write_user_transform_fn = write_user_transform_fn;
+}
+#endif
+
diff --git a/src/png/pngwtran.c b/src/png/pngwtran.c
new file mode 100644
index 0000000000..d85e01536e
--- /dev/null
+++ b/src/png/pngwtran.c
@@ -0,0 +1,495 @@
+
+/* pngwtran.c - transforms the data in a row for PNG writers
+ *
+ * libpng 1.0.1
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Copyright (c) 1998, Glenn Randers-Pehrson
+ * March 15, 1998
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+/* Transform the data according to the users wishes.  The order of
+ * transformations is significant.
+ */
+void
+png_do_write_transformations(png_structp png_ptr)
+{
+   png_debug(1, "in png_do_write_transformations\n");
+
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+   if (png_ptr->transformations & PNG_USER_TRANSFORM)
+      if(png_ptr->write_user_transform_fn != NULL)
+        (*(png_ptr->write_user_transform_fn)) /* user write transform function */
+          (png_ptr,                    /* png_ptr */
+           &(png_ptr->row_info),       /* row_info:     */
+             /*  png_uint_32 width;          width of row */
+             /*  png_uint_32 rowbytes;       number of bytes in row */
+             /*  png_byte color_type;        color type of pixels */
+             /*  png_byte bit_depth;         bit depth of samples */
+             /*  png_byte channels;          number of channels (1-4) */
+             /*  png_byte pixel_depth;       bits per pixel (depth*channels) */
+           png_ptr->row_buf + 1);      /* start of pixel data for row */
+#endif
+#if defined(PNG_WRITE_FILLER_SUPPORTED)
+   if (png_ptr->transformations & PNG_FILLER)
+      png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
+         png_ptr->flags);
+#endif
+#if defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+   if (png_ptr->transformations & PNG_PACKSWAP)
+      png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#if defined(PNG_WRITE_PACK_SUPPORTED)
+   if (png_ptr->transformations & PNG_PACK)
+      png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1,
+         (png_uint_32)png_ptr->bit_depth);
+#endif
+#if defined(PNG_WRITE_SHIFT_SUPPORTED)
+   if (png_ptr->transformations & PNG_SHIFT)
+      png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1,
+         &(png_ptr->shift));
+#endif
+#if defined(PNG_WRITE_SWAP_SUPPORTED)
+   if (png_ptr->transformations & PNG_SWAP_BYTES)
+      png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+   if (png_ptr->transformations & PNG_INVERT_ALPHA)
+      png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+   if (png_ptr->transformations & PNG_SWAP_ALPHA)
+      png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#if defined(PNG_WRITE_BGR_SUPPORTED)
+   if (png_ptr->transformations & PNG_BGR)
+      png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#if defined(PNG_WRITE_INVERT_SUPPORTED)
+   if (png_ptr->transformations & PNG_INVERT_MONO)
+      png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+}
+
+#if defined(PNG_WRITE_PACK_SUPPORTED)
+/* Pack pixels into bytes.  Pass the true bit depth in bit_depth.  The
+ * row_info bit depth should be 8 (one pixel per byte).  The channels
+ * should be 1 (this only happens on grayscale and paletted images).
+ */
+void
+png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
+{
+   png_debug(1, "in png_do_pack\n");
+   if (row_info->bit_depth == 8 &&
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+       row != NULL && row_info != NULL &&
+#endif
+      row_info->channels == 1)
+   {
+      switch ((int)bit_depth)
+      {
+         case 1:
+         {
+            png_bytep sp, dp;
+            int mask, v;
+            png_uint_32 i;
+
+            sp = row;
+            dp = row;
+            mask = 0x80;
+            v = 0;
+            for (i = 0; i < row_info->width; i++)
+            {
+               if (*sp != 0)
+                  v |= mask;
+               sp++;
+               if (mask > 1)
+                  mask >>= 1;
+               else
+               {
+                  mask = 0x80;
+                  *dp = (png_byte)v;
+                  dp++;
+                  v = 0;
+               }
+            }
+            if (mask != 0x80)
+               *dp = (png_byte)v;
+            break;
+         }
+         case 2:
+         {
+            png_bytep sp, dp;
+            int shift, v;
+            png_uint_32 i;
+
+            sp = row;
+            dp = row;
+            shift = 6;
+            v = 0;
+            for (i = 0; i < row_info->width; i++)
+            {
+               png_byte value;
+
+               value = (png_byte)(*sp & 0x3);
+               v |= (value << shift);
+               if (shift == 0)
+               {
+                  shift = 6;
+                  *dp = (png_byte)v;
+                  dp++;
+                  v = 0;
+               }
+               else
+                  shift -= 2;
+               sp++;
+            }
+            if (shift != 6)
+               *dp = (png_byte)v;
+            break;
+         }
+         case 4:
+         {
+            png_bytep sp, dp;
+            int shift, v;
+            png_uint_32 i;
+
+            sp = row;
+            dp = row;
+            shift = 4;
+            v = 0;
+            for (i = 0; i < row_info->width; i++)
+            {
+               png_byte value;
+
+               value = (png_byte)(*sp & 0xf);
+               v |= (value << shift);
+
+               if (shift == 0)
+               {
+                  shift = 4;
+                  *dp = (png_byte)v;
+                  dp++;
+                  v = 0;
+               }
+               else
+                  shift -= 4;
+
+               sp++;
+            }
+            if (shift != 4)
+               *dp = (png_byte)v;
+            break;
+         }
+      }
+      row_info->bit_depth = (png_byte)bit_depth;
+      row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
+      row_info->rowbytes =
+         ((row_info->width * row_info->pixel_depth + 7) >> 3);
+   }
+}
+#endif
+
+#if defined(PNG_WRITE_SHIFT_SUPPORTED)
+/* Shift pixel values to take advantage of whole range.  Pass the
+ * true number of bits in bit_depth.  The row should be packed
+ * according to row_info->bit_depth.  Thus, if you had a row of
+ * bit depth 4, but the pixels only had values from 0 to 7, you
+ * would pass 3 as bit_depth, and this routine would translate the
+ * data to 0 to 15.
+ */
+void
+png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
+{
+   png_debug(1, "in png_do_shift\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+   if (row != NULL && row_info != NULL &&
+#else
+   if (
+#endif
+      row_info->color_type != PNG_COLOR_TYPE_PALETTE)
+   {
+      int shift_start[4], shift_dec[4];
+      png_uint_32 channels;
+
+      channels = 0;
+      if (row_info->color_type & PNG_COLOR_MASK_COLOR)
+      {
+         shift_start[channels] = row_info->bit_depth - bit_depth->red;
+         shift_dec[channels] = bit_depth->red;
+         channels++;
+         shift_start[channels] = row_info->bit_depth - bit_depth->green;
+         shift_dec[channels] = bit_depth->green;
+         channels++;
+         shift_start[channels] = row_info->bit_depth - bit_depth->blue;
+         shift_dec[channels] = bit_depth->blue;
+         channels++;
+      }
+      else
+      {
+         shift_start[channels] = row_info->bit_depth - bit_depth->gray;
+         shift_dec[channels] = bit_depth->gray;
+         channels++;
+      }
+      if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
+      {
+         shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
+         shift_dec[channels] = bit_depth->alpha;
+         channels++;
+      }
+
+      /* with low row depths, could only be grayscale, so one channel */
+      if (row_info->bit_depth < 8)
+      {
+         png_bytep bp;
+         png_uint_32 i;
+         png_byte mask;
+
+         if (bit_depth->gray == 1 && row_info->bit_depth == 2)
+            mask = 0x55;
+         else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
+            mask = 0x11;
+         else
+            mask = 0xff;
+
+         for (bp = row, i = 0; i < row_info->rowbytes; i++, bp++)
+         {
+            png_uint_16 v;
+            int j;
+
+            v = *bp;
+            *bp = 0;
+            for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
+            {
+               if (j > 0)
+                  *bp |= (png_byte)((v << j) & 0xff);
+               else
+                  *bp |= (png_byte)((v >> (-j)) & mask);
+            }
+         }
+      }
+      else if (row_info->bit_depth == 8)
+      {
+         png_bytep bp;
+         png_uint_32 i;
+
+         for (bp = row, i = 0; i < row_info->width; i++)
+         {
+            png_uint_32 c;
+
+            for (c = 0; c < channels; c++, bp++)
+            {
+               png_uint_16 v;
+               int j;
+
+               v = *bp;
+               *bp = 0;
+               for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
+               {
+                  if (j > 0)
+                     *bp |= (png_byte)((v << j) & 0xff);
+                  else
+                     *bp |= (png_byte)((v >> (-j)) & 0xff);
+               }
+            }
+         }
+      }
+      else
+      {
+         png_bytep bp;
+         png_uint_32 i;
+
+         for (bp = row, i = 0; i < row_info->width * row_info->channels; i++)
+         {
+            png_uint_32 c;
+
+            for (c = 0; c < channels; c++, bp += 2)
+            {
+               png_uint_16 value, v;
+               int j;
+
+               v = ((png_uint_16)(*bp) << 8) + *(bp + 1);
+               value = 0;
+               for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
+               {
+                  if (j > 0)
+                     value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
+                  else
+                     value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
+               }
+               *bp = (png_byte)(value >> 8);
+               *(bp + 1) = (png_byte)(value & 0xff);
+            }
+         }
+      }
+   }
+}
+#endif
+
+#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+void
+png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_write_swap_alpha\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+   if (row != NULL && row_info != NULL)
+#endif
+   {
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+      {
+         /* This converts from ARGB to RGBA */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp, dp;
+            png_byte save;
+            png_uint_32 i;
+
+            for (i = 0, sp = dp = row; i < row_info->width; i++)
+            {
+               save = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = save;
+            }
+         }
+         /* This converts from AARRGGBB to RRGGBBAA */
+         else
+         {
+            png_bytep sp, dp;
+            png_byte save[2];
+            png_uint_32 i;
+
+            for (i = 0, sp = dp = row; i < row_info->width; i++)
+            {
+               save[0] = *(sp++);
+               save[1] = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = save[0];
+               *(dp++) = save[1];
+            }
+         }
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      {
+         /* This converts from AG to GA */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp, dp;
+            png_byte save;
+            png_uint_32 i;
+
+            for (i = 0, sp = dp = row; i < row_info->width; i++)
+            {
+               save = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = save;
+            }
+         }
+         /* This converts from AAGG to GGAA */
+         else
+         {
+            png_bytep sp, dp;
+            png_byte save[2];
+            png_uint_32 i;
+
+            for (i = 0, sp = dp = row; i < row_info->width; i++)
+            {
+               save[0] = *(sp++);
+               save[1] = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = save[0];
+               *(dp++) = save[1];
+            }
+         }
+      }
+   }
+}
+#endif
+
+#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+void
+png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_write_invert_alpha\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+   if (row != NULL && row_info != NULL)
+#endif
+   {
+      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+      {
+         /* This inverts the alpha channel in RGBA */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp, dp;
+            png_uint_32 i;
+
+            for (i = 0, sp = dp = row; i < row_info->width; i++)
+            {
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = 255 - *(sp++);
+            }
+         }
+         /* This inverts the alpha channel in RRGGBBAA */
+         else
+         {
+            png_bytep sp, dp;
+            png_uint_32 i;
+
+            for (i = 0, sp = dp = row; i < row_info->width; i++)
+            {
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = 255 - *(sp++);
+               *(dp++) = 255 - *(sp++);
+            }
+         }
+      }
+      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+      {
+         /* This inverts the alpha channel in GA */
+         if (row_info->bit_depth == 8)
+         {
+            png_bytep sp, dp;
+            png_uint_32 i;
+
+            for (i = 0, sp = dp = row; i < row_info->width; i++)
+            {
+               *(dp++) = *(sp++);
+               *(dp++) = 255 - *(sp++);
+            }
+         }
+         /* This inverts the alpha channel in GGAA */
+         else
+         {
+            png_bytep sp, dp;
+            png_uint_32 i;
+
+            for (i = 0, sp = dp = row; i < row_info->width; i++)
+            {
+               *(dp++) = *(sp++);
+               *(dp++) = *(sp++);
+               *(dp++) = 255 - *(sp++);
+               *(dp++) = 255 - *(sp++);
+            }
+         }
+      }
+   }
+}
+#endif
diff --git a/src/png/pngwutil.c b/src/png/pngwutil.c
new file mode 100644
index 0000000000..492bde7bb0
--- /dev/null
+++ b/src/png/pngwutil.c
@@ -0,0 +1,1934 @@
+
+/* pngwutil.c - utilities to write a PNG file
+ *
+ * libpng 1.0.1
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Copyright (c) 1998, Glenn Randers-Pehrson
+ * March 15, 1998
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+/* Place a 32-bit number into a buffer in PNG byte order.  We work
+ * with unsigned numbers for convenience, although one supported
+ * ancillary chunk uses signed (two's complement) numbers.
+ */
+void
+png_save_uint_32(png_bytep buf, png_uint_32 i)
+{
+   buf[0] = (png_byte)((i >> 24) & 0xff);
+   buf[1] = (png_byte)((i >> 16) & 0xff);
+   buf[2] = (png_byte)((i >> 8) & 0xff);
+   buf[3] = (png_byte)(i & 0xff);
+}
+
+#if defined(PNG_WRITE_pCAL_SUPPORTED)
+/* The png_save_int_32 function assumes integers are stored in two's
+ * complement format.  If this isn't the case, then this routine needs to
+ * be modified to write data in two's complement format.
+ */
+void
+png_save_int_32(png_bytep buf, png_int_32 i)
+{
+   buf[0] = (png_byte)((i >> 24) & 0xff);
+   buf[1] = (png_byte)((i >> 16) & 0xff);
+   buf[2] = (png_byte)((i >> 8) & 0xff);
+   buf[3] = (png_byte)(i & 0xff);
+}
+#endif
+
+/* Place a 16-bit number into a buffer in PNG byte order.
+ * The parameter is declared unsigned int, not png_uint_16,
+ * just to avoid potential problems on pre-ANSI C compilers.
+ */
+void
+png_save_uint_16(png_bytep buf, unsigned int i)
+{
+   buf[0] = (png_byte)((i >> 8) & 0xff);
+   buf[1] = (png_byte)(i & 0xff);
+}
+
+/* Write a PNG chunk all at once.  The type is an array of ASCII characters
+ * representing the chunk name.  The array must be at least 4 bytes in
+ * length, and does not need to be null terminated.  To be safe, pass the
+ * pre-defined chunk names here, and if you need a new one, define it
+ * where the others are defined.  The length is the length of the data.
+ * All the data must be present.  If that is not possible, use the
+ * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
+ * functions instead.
+ */
+void
+png_write_chunk(png_structp png_ptr, png_bytep chunk_name,
+   png_bytep data, png_size_t length)
+{
+   png_write_chunk_start(png_ptr, chunk_name, (png_uint_32)length);
+   png_write_chunk_data(png_ptr, data, length);
+   png_write_chunk_end(png_ptr);
+}
+
+/* Write the start of a PNG chunk.  The type is the chunk type.
+ * The total_length is the sum of the lengths of all the data you will be
+ * passing in png_write_chunk_data().
+ */
+void
+png_write_chunk_start(png_structp png_ptr, png_bytep chunk_name,
+   png_uint_32 length)
+{
+   png_byte buf[4];
+   png_debug2(0, "Writing %s chunk (%d bytes)\n", chunk_name, length);
+
+   /* write the length */
+   png_save_uint_32(buf, length);
+   png_write_data(png_ptr, buf, (png_size_t)4);
+
+   /* write the chunk name */
+   png_write_data(png_ptr, chunk_name, (png_size_t)4);
+   /* reset the crc and run it over the chunk name */
+   png_reset_crc(png_ptr);
+   png_calculate_crc(png_ptr, chunk_name, (png_size_t)4);
+}
+
+/* Write the data of a PNG chunk started with png_write_chunk_start().
+ * Note that multiple calls to this function are allowed, and that the
+ * sum of the lengths from these calls *must* add up to the total_length
+ * given to png_write_chunk_start().
+ */
+void
+png_write_chunk_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   /* write the data, and run the CRC over it */
+   if (data != NULL && length > 0)
+   {
+      png_calculate_crc(png_ptr, data, length);
+      png_write_data(png_ptr, data, length);
+   }
+}
+
+/* Finish a chunk started with png_write_chunk_start(). */
+void
+png_write_chunk_end(png_structp png_ptr)
+{
+   png_byte buf[4];
+
+   /* write the crc */
+   png_save_uint_32(buf, png_ptr->crc);
+
+   png_write_data(png_ptr, buf, (png_size_t)4);
+}
+
+/* Simple function to write the signature.  If we have already written
+ * the magic bytes of the signature, or more likely, the PNG stream is
+ * being embedded into another stream and doesn't need its own signature,
+ * we should call png_set_sig_bytes() to tell libpng how many of the
+ * bytes have already been written.
+ */
+void
+png_write_sig(png_structp png_ptr)
+{
+   /* write the rest of the 8 byte signature */
+   png_write_data(png_ptr, &png_sig[png_ptr->sig_bytes],
+      (png_size_t)8 - png_ptr->sig_bytes);
+}
+
+/* Write the IHDR chunk, and update the png_struct with the necessary
+ * information.  Note that the rest of this code depends upon this
+ * information being correct.
+ */
+void
+png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
+   int bit_depth, int color_type, int compression_type, int filter_type,
+   int interlace_type)
+{
+   png_byte buf[13]; /* buffer to store the IHDR info */
+
+   png_debug(1, "in png_write_IHDR\n");
+   /* Check that we have valid input data from the application info */
+   switch (color_type)
+   {
+      case PNG_COLOR_TYPE_GRAY:
+         switch (bit_depth)
+         {
+            case 1:
+            case 2:
+            case 4:
+            case 8:
+            case 16: png_ptr->channels = 1; break;
+            default: png_error(png_ptr,"Invalid bit depth for grayscale image");
+         }
+         break;
+      case PNG_COLOR_TYPE_RGB:
+         if (bit_depth != 8 && bit_depth != 16)
+            png_error(png_ptr, "Invalid bit depth for RGB image");
+         png_ptr->channels = 3;
+         break;
+      case PNG_COLOR_TYPE_PALETTE:
+         switch (bit_depth)
+         {
+            case 1:
+            case 2:
+            case 4:
+            case 8: png_ptr->channels = 1; break;
+            default: png_error(png_ptr, "Invalid bit depth for paletted image");
+         }
+         break;
+      case PNG_COLOR_TYPE_GRAY_ALPHA:
+         if (bit_depth != 8 && bit_depth != 16)
+            png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
+         png_ptr->channels = 2;
+         break;
+      case PNG_COLOR_TYPE_RGB_ALPHA:
+         if (bit_depth != 8 && bit_depth != 16)
+            png_error(png_ptr, "Invalid bit depth for RGBA image");
+         png_ptr->channels = 4;
+         break;
+      default:
+         png_error(png_ptr, "Invalid image color type specified");
+   }
+
+   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+   {
+      png_warning(png_ptr, "Invalid compression type specified");
+      compression_type = PNG_COMPRESSION_TYPE_BASE;
+   }
+
+   if (filter_type != PNG_FILTER_TYPE_BASE)
+   {
+      png_warning(png_ptr, "Invalid filter type specified");
+      filter_type = PNG_FILTER_TYPE_BASE;
+   }
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+   if (interlace_type != PNG_INTERLACE_NONE &&
+      interlace_type != PNG_INTERLACE_ADAM7)
+   {
+      png_warning(png_ptr, "Invalid interlace type specified");
+      interlace_type = PNG_INTERLACE_ADAM7;
+   }
+#else
+   interlace_type=PNG_INTERLACE_NONE;
+#endif
+
+   /* save off the relevent information */
+   png_ptr->bit_depth = (png_byte)bit_depth;
+   png_ptr->color_type = (png_byte)color_type;
+   png_ptr->interlaced = (png_byte)interlace_type;
+   png_ptr->width = width;
+   png_ptr->height = height;
+
+   png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);
+   png_ptr->rowbytes = ((width * (png_size_t)png_ptr->pixel_depth + 7) >> 3);
+   /* set the usr info, so any transformations can modify it */
+   png_ptr->usr_width = png_ptr->width;
+   png_ptr->usr_bit_depth = png_ptr->bit_depth;
+   png_ptr->usr_channels = png_ptr->channels;
+
+   /* pack the header information into the buffer */
+   png_save_uint_32(buf, width);
+   png_save_uint_32(buf + 4, height);
+   buf[8] = (png_byte)bit_depth;
+   buf[9] = (png_byte)color_type;
+   buf[10] = (png_byte)compression_type;
+   buf[11] = (png_byte)filter_type;
+   buf[12] = (png_byte)interlace_type;
+
+   /* write the chunk */
+   png_write_chunk(png_ptr, png_IHDR, buf, (png_size_t)13);
+
+   /* initialize zlib with PNG info */
+   png_ptr->zstream.zalloc = png_zalloc;
+   png_ptr->zstream.zfree = png_zfree;
+   png_ptr->zstream.opaque = (voidpf)png_ptr;
+   if (!(png_ptr->do_filter))
+   {
+      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
+         png_ptr->bit_depth < 8)
+         png_ptr->do_filter = PNG_FILTER_NONE;
+      else
+         png_ptr->do_filter = PNG_ALL_FILTERS;
+   }
+   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY))
+   {
+      if (png_ptr->do_filter != PNG_FILTER_NONE)
+         png_ptr->zlib_strategy = Z_FILTERED;
+      else
+         png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY;
+   }
+   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL))
+      png_ptr->zlib_level = Z_DEFAULT_COMPRESSION;
+   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL))
+      png_ptr->zlib_mem_level = 8;
+   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS))
+      png_ptr->zlib_window_bits = 15;
+   if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD))
+      png_ptr->zlib_method = 8;
+   deflateInit2(&png_ptr->zstream, png_ptr->zlib_level,
+      png_ptr->zlib_method, png_ptr->zlib_window_bits,
+      png_ptr->zlib_mem_level, png_ptr->zlib_strategy);
+   png_ptr->zstream.next_out = png_ptr->zbuf;
+   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+   png_ptr->mode = PNG_HAVE_IHDR;
+}
+
+/* write the palette.  We are careful not to trust png_color to be in the
+ * correct order for PNG, so people can redefine it to any convient
+ * structure.
+ */
+void
+png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal)
+{
+   png_uint_32 i;
+   png_colorp pal_ptr;
+   png_byte buf[3];
+
+   png_debug(1, "in png_write_PLTE\n");
+   if (num_pal == 0 || num_pal > 256)
+   {
+      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+      {
+         png_error(png_ptr, "Invalid number of colors in palette");
+      }
+      else
+      {
+         png_warning(png_ptr, "Invalid number of colors in palette");
+         return;
+      }
+   }
+
+   png_ptr->num_palette = (png_uint_16)num_pal;
+   png_debug1(3, "num_palette = %d\n", png_ptr->num_palette);
+
+   png_write_chunk_start(png_ptr, png_PLTE, num_pal * 3);
+   for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
+   {
+      buf[0] = pal_ptr->red;
+      buf[1] = pal_ptr->green;
+      buf[2] = pal_ptr->blue;
+      png_write_chunk_data(png_ptr, buf, (png_size_t)3);
+   }
+   png_write_chunk_end(png_ptr);
+   png_ptr->mode |= PNG_HAVE_PLTE;
+}
+
+/* write an IDAT chunk */
+void
+png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+   png_debug(1, "in png_write_IDAT\n");
+   png_write_chunk(png_ptr, png_IDAT, data, length);
+   png_ptr->mode |= PNG_HAVE_IDAT;
+}
+
+/* write an IEND chunk */
+void
+png_write_IEND(png_structp png_ptr)
+{
+   png_debug(1, "in png_write_IEND\n");
+   png_write_chunk(png_ptr, png_IEND, NULL, (png_size_t)0);
+   png_ptr->mode |= PNG_HAVE_IEND;
+}
+
+#if defined(PNG_WRITE_gAMA_SUPPORTED)
+/* write a gAMA chunk */
+void
+png_write_gAMA(png_structp png_ptr, double file_gamma)
+{
+   png_uint_32 igamma;
+   png_byte buf[4];
+
+   png_debug(1, "in png_write_gAMA\n");
+   /* file_gamma is saved in 1/1000000ths */
+   igamma = (png_uint_32)(file_gamma * 100000.0 + 0.5);
+   png_save_uint_32(buf, igamma);
+   png_write_chunk(png_ptr, png_gAMA, buf, (png_size_t)4);
+}
+#endif
+
+#if defined(PNG_WRITE_sRGB_SUPPORTED)
+/* write a sRGB chunk */
+void
+png_write_sRGB(png_structp png_ptr, int srgb_intent)
+{
+   png_byte buf[1];
+
+   png_debug(1, "in png_write_sRGB\n");
+   if(srgb_intent >= PNG_sRGB_INTENT_LAST)
+         png_warning(png_ptr,
+            "Invalid sRGB rendering intent specified");
+   buf[0]=(png_byte)srgb_intent;
+   png_write_chunk(png_ptr, png_sRGB, buf, (png_size_t)1);
+}
+#endif
+
+#if defined(PNG_WRITE_sBIT_SUPPORTED)
+/* write the sBIT chunk */
+void
+png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type)
+{
+   png_byte buf[4];
+   png_size_t size;
+
+   png_debug(1, "in png_write_sBIT\n");
+   /* make sure we don't depend upon the order of PNG_COLOR_8 */
+   if (color_type & PNG_COLOR_MASK_COLOR)
+   {
+      png_byte maxbits;
+
+      maxbits = color_type==PNG_COLOR_TYPE_PALETTE ? 8:png_ptr->usr_bit_depth;
+      if (sbit->red == 0 || sbit->red > maxbits || 
+          sbit->green == 0 || sbit->green > maxbits || 
+          sbit->blue == 0 || sbit->blue > maxbits)
+      {
+         png_warning(png_ptr, "Invalid sBIT depth specified");
+         return;
+      }
+      buf[0] = sbit->red;
+      buf[1] = sbit->green;
+      buf[2] = sbit->blue;
+      size = 3;
+   }
+   else
+   {
+      if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth)
+      {
+         png_warning(png_ptr, "Invalid sBIT depth specified");
+         return;
+      }
+      buf[0] = sbit->gray;
+      size = 1;
+   }
+
+   if (color_type & PNG_COLOR_MASK_ALPHA)
+   {
+      if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth)
+      {
+         png_warning(png_ptr, "Invalid sBIT depth specified");
+         return;
+      }
+      buf[size++] = sbit->alpha;
+   }
+
+   png_write_chunk(png_ptr, png_sBIT, buf, size);
+}
+#endif
+
+#if defined(PNG_WRITE_cHRM_SUPPORTED)
+/* write the cHRM chunk */
+void
+png_write_cHRM(png_structp png_ptr, double white_x, double white_y,
+   double red_x, double red_y, double green_x, double green_y,
+   double blue_x, double blue_y)
+{
+   png_uint_32 itemp;
+   png_byte buf[32];
+
+   png_debug(1, "in png_write_cHRM\n");
+   /* each value is saved int 1/1000000ths */
+   if (white_x < 0 || white_x > 0.8 || white_y < 0 || white_y > 0.8 ||
+       white_x + white_y > 1.0)
+   {
+      png_warning(png_ptr, "Invalid cHRM white point specified");
+      return;
+   }
+   itemp = (png_uint_32)(white_x * 100000.0 + 0.5);
+   png_save_uint_32(buf, itemp);
+   itemp = (png_uint_32)(white_y * 100000.0 + 0.5);
+   png_save_uint_32(buf + 4, itemp);
+
+   if (red_x < 0 || red_x > 0.8 || red_y < 0 || red_y > 0.8 ||
+       red_x + red_y > 1.0)
+   {
+      png_warning(png_ptr, "Invalid cHRM red point specified");
+      return;
+   }
+   itemp = (png_uint_32)(red_x * 100000.0 + 0.5);
+   png_save_uint_32(buf + 8, itemp);
+   itemp = (png_uint_32)(red_y * 100000.0 + 0.5);
+   png_save_uint_32(buf + 12, itemp);
+
+   if (green_x < 0 || green_x > 0.8 || green_y < 0 || green_y > 0.8 ||
+       green_x + green_y > 1.0)
+   {
+      png_warning(png_ptr, "Invalid cHRM green point specified");
+      return;
+   }
+   itemp = (png_uint_32)(green_x * 100000.0 + 0.5);
+   png_save_uint_32(buf + 16, itemp);
+   itemp = (png_uint_32)(green_y * 100000.0 + 0.5);
+   png_save_uint_32(buf + 20, itemp);
+
+   if (blue_x < 0 || blue_x > 0.8 || blue_y < 0 || blue_y > 0.8 ||
+       blue_x + blue_y > 1.0)
+   {
+      png_warning(png_ptr, "Invalid cHRM blue point specified");
+      return;
+   }
+   itemp = (png_uint_32)(blue_x * 100000.0 + 0.5);
+   png_save_uint_32(buf + 24, itemp);
+   itemp = (png_uint_32)(blue_y * 100000.0 + 0.5);
+   png_save_uint_32(buf + 28, itemp);
+
+   png_write_chunk(png_ptr, png_cHRM, buf, (png_size_t)32);
+}
+#endif
+
+#if defined(PNG_WRITE_tRNS_SUPPORTED)
+/* write the tRNS chunk */
+void
+png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran,
+   int num_trans, int color_type)
+{
+   png_byte buf[6];
+
+   png_debug(1, "in png_write_tRNS\n");
+   if (color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette)
+      {
+         png_warning(png_ptr,"Invalid number of transparent colors specified");
+         return;
+      }
+      /* write the chunk out as it is */
+      png_write_chunk(png_ptr, png_tRNS, trans, (png_size_t)num_trans);
+   }
+   else if (color_type == PNG_COLOR_TYPE_GRAY)
+   {
+      /* one 16 bit value */
+      png_save_uint_16(buf, tran->gray);
+      png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)2);
+   }
+   else if (color_type == PNG_COLOR_TYPE_RGB)
+   {
+      /* three 16 bit values */
+      png_save_uint_16(buf, tran->red);
+      png_save_uint_16(buf + 2, tran->green);
+      png_save_uint_16(buf + 4, tran->blue);
+      png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)6);
+   }
+   else
+   {
+      png_warning(png_ptr, "Can't write tRNS with an alpha channel");
+   }
+}
+#endif
+
+#if defined(PNG_WRITE_bKGD_SUPPORTED)
+/* write the background chunk */
+void
+png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type)
+{
+   png_byte buf[6];
+
+   png_debug(1, "in png_write_bKGD\n");
+   if (color_type == PNG_COLOR_TYPE_PALETTE)
+   {
+      if (back->index > png_ptr->num_palette)
+      {
+         png_warning(png_ptr, "Invalid background palette index");
+         return;
+      }
+      buf[0] = back->index;
+      png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)1);
+   }
+   else if (color_type & PNG_COLOR_MASK_COLOR)
+   {
+      png_save_uint_16(buf, back->red);
+      png_save_uint_16(buf + 2, back->green);
+      png_save_uint_16(buf + 4, back->blue);
+      png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)6);
+   }
+   else
+   {
+      png_save_uint_16(buf, back->gray);
+      png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)2);
+   }
+}
+#endif
+
+#if defined(PNG_WRITE_hIST_SUPPORTED)
+/* write the histogram */
+void
+png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist)
+{
+   int i;
+   png_byte buf[3];
+
+   png_debug(1, "in png_write_hIST\n");
+   if (num_hist > (int)png_ptr->num_palette)
+   {
+      png_debug2(3, "num_hist = %d, num_palette = %d\n", num_hist,
+         png_ptr->num_palette);
+      png_warning(png_ptr, "Invalid number of histogram entries specified");
+      return;
+   }
+
+   png_write_chunk_start(png_ptr, png_hIST, (png_uint_32)(num_hist * 2));
+   for (i = 0; i < num_hist; i++)
+   {
+      png_save_uint_16(buf, hist[i]);
+      png_write_chunk_data(png_ptr, buf, (png_size_t)2);
+   }
+   png_write_chunk_end(png_ptr);
+}
+#endif
+
+#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
+/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
+ * and if invalid, correct the keyword rather than discarding the entire
+ * chunk.  The PNG 1.0 specification requires keywords 1-79 characters in
+ * length, forbids leading or trailing whitespace, multiple internal spaces,
+ * and the non-break space (0x80) from ISO 8859-1.  Returns keyword length.
+ *
+ * The new_key is allocated to hold the corrected keyword and must be freed
+ * by the calling routine.  This avoids problems with trying to write to
+ * static keywords without having to have duplicate copies of the strings.
+ */
+png_size_t
+png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key)
+{
+   png_size_t key_len;
+   png_charp kp, dp;
+   int kflag;
+
+   png_debug(1, "in png_check_keyword\n");
+   *new_key = NULL;
+
+   if (key == NULL || (key_len = png_strlen(key)) == 0)
+   {
+      png_chunk_warning(png_ptr, "zero length keyword");
+      return ((png_size_t)0);
+   }
+
+   png_debug1(2, "Keyword to be checked is '%s'\n", key);
+
+   *new_key = (png_charp)png_malloc(png_ptr, (png_uint_32)(key_len + 1));
+
+   /* Replace non-printing characters with a blank and print a warning */
+   for (kp = key, dp = *new_key; *kp != '\0'; kp++, dp++)
+   {
+      if (*kp < 0x20 || (*kp > 0x7E && (png_byte)*kp < 0xA1))
+      {
+#if !defined(PNG_NO_STDIO)
+         char msg[40];
+
+         sprintf(msg, "invalid keyword character 0x%02X", *kp);
+         png_chunk_warning(png_ptr, msg);
+#else
+         png_chunk_warning(png_ptr, "invalid character in keyword");
+#endif
+         *dp = ' ';
+      }
+      else
+      {
+         *dp = *kp;
+      }
+   }
+   *dp = '\0';
+
+   /* Remove any trailing white space. */
+   kp = *new_key + key_len - 1;
+   if (*kp == ' ')
+   {
+      png_chunk_warning(png_ptr, "trailing spaces removed from keyword");
+
+      while (*kp == ' ')
+      {
+        *(kp--) = '\0';
+        key_len--;
+      }
+   }
+
+   /* Remove any leading white space. */
+   kp = *new_key;
+   if (*kp == ' ')
+   {
+      png_chunk_warning(png_ptr, "leading spaces removed from keyword");
+
+      while (*kp == ' ')
+      {
+        kp++;
+        key_len--;
+      }
+   }
+
+   png_debug1(2, "Checking for multiple internal spaces in '%s'\n", kp);
+
+   /* Remove multiple internal spaces. */
+   for (kflag = 0, dp = *new_key; *kp != '\0'; kp++)
+   {
+      if (*kp == ' ' && kflag == 0)
+      {
+         *(dp++) = *kp;
+         kflag = 1;
+      }
+      else if (*kp == ' ')
+      {
+         key_len--;
+      }
+      else
+      {
+         *(dp++) = *kp;
+         kflag = 0;
+      }
+   }
+   *dp = '\0';
+
+   if (key_len == 0)
+   {
+      png_chunk_warning(png_ptr, "zero length keyword");
+   }
+
+   if (key_len > 79)
+   {
+      png_chunk_warning(png_ptr, "keyword length must be 1 - 79 characters");
+      new_key[79] = '\0';
+      key_len = 79;
+   }
+
+   return (key_len);
+}
+#endif
+
+#if defined(PNG_WRITE_tEXt_SUPPORTED)
+/* write a tEXt chunk */
+void
+png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text,
+   png_size_t text_len)
+{
+   png_size_t key_len;
+   png_charp new_key;
+
+   png_debug(1, "in png_write_tEXt\n");
+   if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
+   {
+      png_warning(png_ptr, "Empty keyword in tEXt chunk");
+      return;
+   }
+
+   if (text == NULL || *text == '\0')
+      text_len = 0;
+
+   /* make sure we include the 0 after the key */
+   png_write_chunk_start(png_ptr, png_tEXt, (png_uint_32)key_len+text_len+1);
+   png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1);
+   if (text_len)
+      png_write_chunk_data(png_ptr, (png_bytep)text, text_len);
+
+   png_write_chunk_end(png_ptr);
+   png_free(png_ptr, new_key);
+}
+#endif
+
+#if defined(PNG_WRITE_zTXt_SUPPORTED)
+/* write a compressed text chunk */
+void
+png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text,
+   png_size_t text_len, int compression)
+{
+   png_size_t key_len;
+   char buf[1];
+   png_charp new_key;
+   int i, ret;
+   png_charpp output_ptr = NULL; /* array of pointers to output */
+   int num_output_ptr = 0; /* number of output pointers used */
+   int max_output_ptr = 0; /* size of output_ptr */
+
+   png_debug(1, "in png_write_zTXt\n");
+
+   if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
+   {
+      png_warning(png_ptr, "Empty keyword in zTXt chunk");
+      return;
+   }
+
+   if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE)
+   {
+      png_write_tEXt(png_ptr, new_key, text, (png_size_t)0);
+      png_free(png_ptr, new_key);
+      return;
+   }
+
+   png_free(png_ptr, new_key);
+
+   if (compression >= PNG_TEXT_COMPRESSION_LAST)
+   {
+#if !defined(PNG_NO_STDIO)
+      char msg[50];
+      sprintf(msg, "Unknown zTXt compression type %d", compression);
+      png_warning(png_ptr, msg);
+#else
+      png_warning(png_ptr, "Unknown zTXt compression type");
+#endif
+      compression = PNG_TEXT_COMPRESSION_zTXt;
+   }
+
+   /* We can't write the chunk until we find out how much data we have,
+    * which means we need to run the compressor first, and save the
+    * output.  This shouldn't be a problem, as the vast majority of
+    * comments should be reasonable, but we will set up an array of
+    * malloc'd pointers to be sure.
+    *
+    * If we knew the application was well behaved, we could simplify this
+    * greatly by assuming we can always malloc an output buffer large
+    * enough to hold the compressed text ((1001 * text_len / 1000) + 12)
+    * and malloc this directly.  The only time this would be a bad idea is
+    * if we can't malloc more than 64K and we have 64K of random input
+    * data, or if the input string is incredibly large (although this
+    * wouldn't cause a failure, just a slowdown due to swapping).
+    */
+
+   /* set up the compression buffers */
+   png_ptr->zstream.avail_in = (uInt)text_len;
+   png_ptr->zstream.next_in = (Bytef *)text;
+   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+   png_ptr->zstream.next_out = (Bytef *)png_ptr->zbuf;
+
+   /* this is the same compression loop as in png_write_row() */
+   do
+   {
+      /* compress the data */
+      ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
+      if (ret != Z_OK)
+      {
+         /* error */
+         if (png_ptr->zstream.msg != NULL)
+            png_error(png_ptr, png_ptr->zstream.msg);
+         else
+            png_error(png_ptr, "zlib error");
+      }
+      /* check to see if we need more room */
+      if (!png_ptr->zstream.avail_out && png_ptr->zstream.avail_in)
+      {
+         /* make sure the output array has room */
+         if (num_output_ptr >= max_output_ptr)
+         {
+            int old_max;
+
+            old_max = max_output_ptr;
+            max_output_ptr = num_output_ptr + 4;
+            if (output_ptr != NULL)
+            {
+               png_charpp old_ptr;
+
+               old_ptr = output_ptr;
+               output_ptr = (png_charpp)png_malloc(png_ptr,
+                  (png_uint_32)(max_output_ptr * sizeof (png_charpp)));
+               png_memcpy(output_ptr, old_ptr, old_max * sizeof (png_charp));
+               png_free(png_ptr, old_ptr);
+            }
+            else
+               output_ptr = (png_charpp)png_malloc(png_ptr,
+                  (png_uint_32)(max_output_ptr * sizeof (png_charp)));
+         }
+
+         /* save the data */
+         output_ptr[num_output_ptr] = (png_charp)png_malloc(png_ptr,
+            (png_uint_32)png_ptr->zbuf_size);
+         png_memcpy(output_ptr[num_output_ptr], png_ptr->zbuf,
+            png_ptr->zbuf_size);
+         num_output_ptr++;
+
+         /* and reset the buffer */
+         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+         png_ptr->zstream.next_out = png_ptr->zbuf;
+      }
+   /* continue until we don't have anymore to compress */
+   } while (png_ptr->zstream.avail_in);
+
+   /* finish the compression */
+   do
+   {
+      /* tell zlib we are finished */
+      ret = deflate(&png_ptr->zstream, Z_FINISH);
+      if (ret != Z_OK && ret != Z_STREAM_END)
+      {
+         /* we got an error */
+         if (png_ptr->zstream.msg != NULL)
+            png_error(png_ptr, png_ptr->zstream.msg);
+         else
+            png_error(png_ptr, "zlib error");
+      }
+
+      /* check to see if we need more room */
+      if (!(png_ptr->zstream.avail_out) && ret == Z_OK)
+      {
+         /* check to make sure our output array has room */
+         if (num_output_ptr >= max_output_ptr)
+         {
+            int old_max;
+
+            old_max = max_output_ptr;
+            max_output_ptr = num_output_ptr + 4;
+            if (output_ptr != NULL)
+            {
+               png_charpp old_ptr;
+
+               old_ptr = output_ptr;
+               /* This could be optimized to realloc() */
+               output_ptr = (png_charpp)png_malloc(png_ptr,
+                  (png_uint_32)(max_output_ptr * sizeof (png_charpp)));
+               png_memcpy(output_ptr, old_ptr, old_max * sizeof (png_charp));
+               png_free(png_ptr, old_ptr);
+            }
+            else
+               output_ptr = (png_charpp)png_malloc(png_ptr,
+                  (png_uint_32)(max_output_ptr * sizeof (png_charp)));
+         }
+
+         /* save off the data */
+         output_ptr[num_output_ptr] = (png_charp)png_malloc(png_ptr,
+            (png_uint_32)png_ptr->zbuf_size);
+         png_memcpy(output_ptr[num_output_ptr], png_ptr->zbuf,
+            png_ptr->zbuf_size);
+         num_output_ptr++;
+
+         /* and reset the buffer pointers */
+         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+         png_ptr->zstream.next_out = png_ptr->zbuf;
+      }
+   } while (ret != Z_STREAM_END);
+
+   /* text length is number of buffers plus last buffer */
+   text_len = png_ptr->zbuf_size * num_output_ptr;
+   if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
+      text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out;
+
+   /* write start of chunk */
+   png_write_chunk_start(png_ptr, png_zTXt, (png_uint_32)(key_len+text_len+2));
+   /* write key */
+   png_write_chunk_data(png_ptr, (png_bytep)key, key_len + 1);
+   buf[0] = (png_byte)compression;
+   /* write compression */
+   png_write_chunk_data(png_ptr, (png_bytep)buf, (png_size_t)1);
+
+   /* write saved output buffers, if any */
+   for (i = 0; i < num_output_ptr; i++)
+   {
+      png_write_chunk_data(png_ptr,(png_bytep)output_ptr[i],png_ptr->zbuf_size);
+      png_free(png_ptr, output_ptr[i]);
+   }
+   if (max_output_ptr != 0)
+      png_free(png_ptr, output_ptr);
+   /* write anything left in zbuf */
+   if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size)
+      png_write_chunk_data(png_ptr, png_ptr->zbuf,
+         png_ptr->zbuf_size - png_ptr->zstream.avail_out);
+   /* close the chunk */
+   png_write_chunk_end(png_ptr);
+
+   /* reset zlib for another zTXt or the image data */
+   deflateReset(&png_ptr->zstream);
+}
+#endif
+
+
+#if defined(PNG_WRITE_oFFs_SUPPORTED)
+/* write the oFFs chunk */
+void
+png_write_oFFs(png_structp png_ptr, png_uint_32 x_offset,
+   png_uint_32 y_offset,
+   int unit_type)
+{
+   png_byte buf[9];
+
+   png_debug(1, "in png_write_oFFs\n");
+   if (unit_type >= PNG_OFFSET_LAST)
+      png_warning(png_ptr, "Unrecognized unit type for oFFs chunk");
+
+   png_save_uint_32(buf, x_offset);
+   png_save_uint_32(buf + 4, y_offset);
+   buf[8] = (png_byte)unit_type;
+
+   png_write_chunk(png_ptr, png_oFFs, buf, (png_size_t)9);
+}
+#endif
+
+#if defined(PNG_WRITE_pCAL_SUPPORTED)
+/* write the pCAL chunk (png-scivis-19970203) */
+void
+png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
+   png_int_32 X1, int type, int nparams, png_charp units, png_charpp params)
+{
+   png_size_t purpose_len, units_len, total_len; 
+   png_uint_32p params_len;
+   png_byte buf[10];
+   png_charp new_purpose;
+   int i;
+
+   png_debug1(1, "in png_write_pCAL (%d parameters)\n", nparams);
+   if (type >= PNG_EQUATION_LAST)
+      png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
+
+   purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1;
+   png_debug1(3, "pCAL purpose length = %d\n", purpose_len);
+   units_len = png_strlen(units) + (nparams == 0 ? 0 : 1);
+   png_debug1(3, "pCAL units length = %d\n", units_len);
+   total_len = purpose_len + units_len + 10;
+
+   params_len = (png_uint_32p)png_malloc(png_ptr, (png_uint_32)(nparams
+      *sizeof(png_uint_32)));
+
+   /* Find the length of each parameter, making sure we don't count the
+      null terminator for the last parameter. */
+   for (i = 0; i < nparams; i++)
+   {
+      params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1);
+      png_debug2(3, "pCAL parameter %d length = %d\n", i, params_len[i]);
+      total_len += (png_size_t)params_len[i];
+   }
+
+   png_debug1(3, "pCAL total length = %d\n", total_len);
+   png_write_chunk_start(png_ptr, png_pCAL, (png_uint_32)total_len);
+   png_write_chunk_data(png_ptr, (png_bytep)new_purpose, purpose_len);
+   png_save_int_32(buf, X0);
+   png_save_int_32(buf + 4, X1);
+   buf[8] = (png_byte)type;
+   buf[9] = (png_byte)nparams;
+   png_write_chunk_data(png_ptr, buf, (png_size_t)10);
+   png_write_chunk_data(png_ptr, (png_bytep)units, (png_size_t)units_len);
+
+   png_free(png_ptr, new_purpose);
+
+   for (i = 0; i < nparams; i++)
+   {
+      png_write_chunk_data(png_ptr, (png_bytep)params[i],
+         (png_size_t)params_len[i]);
+   }
+
+   png_free(png_ptr, params_len);
+   png_write_chunk_end(png_ptr);
+}
+#endif
+
+#if defined(PNG_WRITE_pHYs_SUPPORTED)
+/* write the pHYs chunk */
+void
+png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
+   png_uint_32 y_pixels_per_unit,
+   int unit_type)
+{
+   png_byte buf[9];
+
+   png_debug(1, "in png_write_pHYs\n");
+   if (unit_type >= PNG_RESOLUTION_LAST)
+      png_warning(png_ptr, "Unrecognized unit type for pHYs chunk");
+
+   png_save_uint_32(buf, x_pixels_per_unit);
+   png_save_uint_32(buf + 4, y_pixels_per_unit);
+   buf[8] = (png_byte)unit_type;
+
+   png_write_chunk(png_ptr, png_pHYs, buf, (png_size_t)9);
+}
+#endif
+
+#if defined(PNG_WRITE_tIME_SUPPORTED)
+/* Write the tIME chunk.  Use either png_convert_from_struct_tm()
+ * or png_convert_from_time_t(), or fill in the structure yourself.
+ */
+void
+png_write_tIME(png_structp png_ptr, png_timep mod_time)
+{
+   png_byte buf[7];
+
+   png_debug(1, "in png_write_tIME\n");
+   if (mod_time->month  > 12 || mod_time->month  < 1 ||
+       mod_time->day    > 31 || mod_time->day    < 1 ||
+       mod_time->hour   > 23 || mod_time->second > 60)
+   {
+      png_warning(png_ptr, "Invalid time specified for tIME chunk");
+      return;
+   }
+
+   png_save_uint_16(buf, mod_time->year);
+   buf[2] = mod_time->month;
+   buf[3] = mod_time->day;
+   buf[4] = mod_time->hour;
+   buf[5] = mod_time->minute;
+   buf[6] = mod_time->second;
+
+   png_write_chunk(png_ptr, png_tIME, buf, (png_size_t)7);
+}
+#endif
+
+/* initializes the row writing capability of libpng */
+void
+png_write_start_row(png_structp png_ptr)
+{
+   png_size_t buf_size;
+
+   png_debug(1, "in png_write_start_row\n");
+   buf_size = (png_size_t)(((png_ptr->width * png_ptr->usr_channels *
+                            png_ptr->usr_bit_depth + 7) >> 3) + 1);
+
+   /* set up row buffer */
+   png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size);
+   png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;
+
+   /* set up filtering buffer, if using this filter */
+   if (png_ptr->do_filter & PNG_FILTER_SUB)
+   {
+      png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
+         (png_ptr->rowbytes + 1));
+      png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
+   }
+
+   /* We only need to keep the previous row if we are using one of these. */
+   if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH))
+   {
+     /* set up previous row buffer */
+      png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size);
+      png_memset(png_ptr->prev_row, 0, buf_size);
+
+      if (png_ptr->do_filter & PNG_FILTER_UP)
+      {
+         png_ptr->up_row = (png_bytep )png_malloc(png_ptr,
+            (png_ptr->rowbytes + 1));
+         png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
+      }
+
+      if (png_ptr->do_filter & PNG_FILTER_AVG)
+      {
+         png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
+            (png_ptr->rowbytes + 1));
+         png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
+      }
+
+      if (png_ptr->do_filter & PNG_FILTER_PAETH)
+      {
+         png_ptr->paeth_row = (png_bytep )png_malloc(png_ptr,
+            (png_ptr->rowbytes + 1));
+         png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
+      }
+   }
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+   /* if interlaced, we need to set up width and height of pass */
+   if (png_ptr->interlaced)
+   {
+      if (!(png_ptr->transformations & PNG_INTERLACE))
+      {
+         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
+            png_pass_ystart[0]) / png_pass_yinc[0];
+         png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 -
+            png_pass_start[0]) / png_pass_inc[0];
+      }
+      else
+      {
+         png_ptr->num_rows = png_ptr->height;
+         png_ptr->usr_width = png_ptr->width;
+      }
+   }
+   else
+#endif
+   {
+      png_ptr->num_rows = png_ptr->height;
+      png_ptr->usr_width = png_ptr->width;
+   }
+   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+   png_ptr->zstream.next_out = png_ptr->zbuf;
+}
+
+/* Internal use only.  Called when finished processing a row of data. */
+void
+png_write_finish_row(png_structp png_ptr)
+{
+   int ret;
+
+   png_debug(1, "in png_write_finish_row\n");
+   /* next row */
+   png_ptr->row_number++;
+
+   /* see if we are done */
+   if (png_ptr->row_number < png_ptr->num_rows)
+      return;
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+   /* if interlaced, go to next pass */
+   if (png_ptr->interlaced)
+   {
+      png_ptr->row_number = 0;
+      if (png_ptr->transformations & PNG_INTERLACE)
+      {
+         png_ptr->pass++;
+      }
+      else
+      {
+         /* loop until we find a non-zero width or height pass */
+         do
+         {
+            png_ptr->pass++;
+            if (png_ptr->pass >= 7)
+               break;
+            png_ptr->usr_width = (png_ptr->width +
+               png_pass_inc[png_ptr->pass] - 1 -
+               png_pass_start[png_ptr->pass]) /
+               png_pass_inc[png_ptr->pass];
+            png_ptr->num_rows = (png_ptr->height +
+               png_pass_yinc[png_ptr->pass] - 1 -
+               png_pass_ystart[png_ptr->pass]) /
+               png_pass_yinc[png_ptr->pass];
+            if (png_ptr->transformations & PNG_INTERLACE)
+               break;
+         } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);
+
+      }
+
+      /* reset the row above the image for the next pass */
+      if (png_ptr->pass < 7)
+      {
+         if (png_ptr->prev_row != NULL)
+            png_memset(png_ptr->prev_row, 0, 
+               (png_size_t) (((png_uint_32)png_ptr->usr_channels *
+               (png_uint_32)png_ptr->usr_bit_depth *
+               png_ptr->width + 7) >> 3) + 1);
+         return;
+      }
+   }
+#endif
+
+   /* if we get here, we've just written the last row, so we need
+      to flush the compressor */
+   do
+   {
+      /* tell the compressor we are done */
+      ret = deflate(&png_ptr->zstream, Z_FINISH);
+      /* check for an error */
+      if (ret != Z_OK && ret != Z_STREAM_END)
+      {
+         if (png_ptr->zstream.msg != NULL)
+            png_error(png_ptr, png_ptr->zstream.msg);
+         else
+            png_error(png_ptr, "zlib error");
+      }
+      /* check to see if we need more room */
+      if (!(png_ptr->zstream.avail_out) && ret == Z_OK)
+      {
+         png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
+         png_ptr->zstream.next_out = png_ptr->zbuf;
+         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+      }
+   } while (ret != Z_STREAM_END);
+
+   /* write any extra space */
+   if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
+   {
+      png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size -
+         png_ptr->zstream.avail_out);
+   }
+
+   deflateReset(&png_ptr->zstream);
+}
+
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+/* Pick out the correct pixels for the interlace pass.
+ * The basic idea here is to go through the row with a source
+ * pointer and a destination pointer (sp and dp), and copy the
+ * correct pixels for the pass.  As the row gets compacted,
+ * sp will always be >= dp, so we should never overwrite anything.
+ * See the default: case for the easiest code to understand.
+ */
+void
+png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
+{
+   png_debug(1, "in png_do_write_interlace\n");
+   /* we don't have to do anything on the last pass (6) */
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+   if (row != NULL && row_info != NULL && pass < 6)
+#else
+   if (pass < 6)
+#endif
+   {
+      /* each pixel depth is handled seperately */
+      switch (row_info->pixel_depth)
+      {
+         case 1:
+         {
+            png_bytep sp;
+            png_bytep dp;
+            int shift;
+            int d;
+            int value;
+            png_uint_32 i;
+
+            dp = row;
+            d = 0;
+            shift = 7;
+            for (i = png_pass_start[pass]; i < row_info->width;
+               i += png_pass_inc[pass])
+            {
+               sp = row + (png_size_t)(i >> 3);
+               value = (int)(*sp >> (7 - (int)(i & 7))) & 0x1;
+               d |= (value << shift);
+
+               if (shift == 0)
+               {
+                  shift = 7;
+                  *dp++ = (png_byte)d;
+                  d = 0;
+               }
+               else
+                  shift--;
+
+            }
+            if (shift != 7)
+               *dp = (png_byte)d;
+            break;
+         }
+         case 2:
+         {
+            png_bytep sp;
+            png_bytep dp;
+            int shift;
+            int d;
+            int value;
+            png_uint_32 i;
+
+            dp = row;
+            shift = 6;
+            d = 0;
+            for (i = png_pass_start[pass]; i < row_info->width;
+               i += png_pass_inc[pass])
+            {
+               sp = row + (png_size_t)(i >> 2);
+               value = (*sp >> ((3 - (int)(i & 3)) << 1)) & 0x3;
+               d |= (value << shift);
+
+               if (shift == 0)
+               {
+                  shift = 6;
+                  *dp++ = (png_byte)d;
+                  d = 0;
+               }
+               else
+                  shift -= 2;
+            }
+            if (shift != 6)
+                   *dp = (png_byte)d;
+            break;
+         }
+         case 4:
+         {
+            png_bytep sp;
+            png_bytep dp;
+            int shift;
+            int d;
+            int value;
+            png_uint_32 i;
+
+            dp = row;
+            shift = 4;
+            d = 0;
+            for (i = png_pass_start[pass]; i < row_info->width;
+               i += png_pass_inc[pass])
+            {
+               sp = row + (png_size_t)(i >> 1);
+               value = (*sp >> ((1 - (int)(i & 1)) << 2)) & 0xf;
+               d |= (value << shift);
+
+               if (shift == 0)
+               {
+                  shift = 4;
+                  *dp++ = (png_byte)d;
+                  d = 0;
+               }
+               else
+                  shift -= 4;
+            }
+            if (shift != 4)
+               *dp = (png_byte)d;
+            break;
+         }
+         default:
+         {
+            png_bytep sp;
+            png_bytep dp;
+            png_uint_32 i;
+            png_size_t pixel_bytes;
+
+            /* start at the beginning */
+            dp = row;
+            /* find out how many bytes each pixel takes up */
+            pixel_bytes = (row_info->pixel_depth >> 3);
+            /* loop through the row, only looking at the pixels that
+               matter */
+            for (i = png_pass_start[pass]; i < row_info->width;
+               i += png_pass_inc[pass])
+            {
+               /* find out where the original pixel is */
+               sp = row + (png_size_t)i * pixel_bytes;
+               /* move the pixel */
+               if (dp != sp)
+                  png_memcpy(dp, sp, pixel_bytes);
+               /* next pixel */
+               dp += pixel_bytes;
+            }
+            break;
+         }
+      }
+      /* set new row width */
+      row_info->width = (row_info->width +
+         png_pass_inc[pass] - 1 -
+         png_pass_start[pass]) /
+         png_pass_inc[pass];
+         row_info->rowbytes = ((row_info->width *
+            row_info->pixel_depth + 7) >> 3);
+   }
+}
+#endif
+
+/* This filters the row, chooses which filter to use, if it has not already
+ * been specified by the application, and then writes the row out with the
+ * chosen filter.
+ */
+#define PNG_MAXSUM (~((png_uint_32)0) >> 1)
+#define PNG_HISHIFT 10
+#define PNG_LOMASK ((png_uint_32)0xffffL)
+#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
+void
+png_write_find_filter(png_structp png_ptr, png_row_infop row_info)
+{
+   png_bytep prev_row, best_row, row_buf;
+   png_uint_32 mins, bpp;
+
+   png_debug(1, "in png_write_find_filter\n");
+   /* find out how many bytes offset each pixel is */
+   bpp = (row_info->pixel_depth + 7) / 8;
+
+   prev_row = png_ptr->prev_row;
+   best_row = row_buf = png_ptr->row_buf;
+   mins = PNG_MAXSUM;
+
+   /* The prediction method we use is to find which method provides the
+    * smallest value when summing the absolute values of the distances
+    * from zero using anything >= 128 as negative numbers.  This is known
+    * as the "minimum sum of absolute differences" heuristic.  Other
+    * heuristics are the "weighted minumum sum of absolute differences"
+    * (experimental and can in theory improve compression), and the "zlib
+    * predictive" method (not implemented in libpng 0.95), which does test
+    * compressions of lines using different filter methods, and then chooses
+    * the (series of) filter(s) which give minimum compressed data size (VERY
+    * computationally expensive).
+    */
+
+   /* We don't need to test the 'no filter' case if this is the only filter
+    * that has been chosen, as it doesn't actually do anything to the data.
+    */
+   if (png_ptr->do_filter & PNG_FILTER_NONE &&
+       png_ptr->do_filter != PNG_FILTER_NONE)
+   {
+      png_bytep rp;
+      png_uint_32 sum = 0;
+      png_uint_32 i;
+      int v;
+
+      for (i = 0, rp = row_buf + 1; i < row_info->rowbytes; i++, rp++)
+      {
+         v = *rp;
+         sum += (v < 128) ? v : 256 - v;
+      }
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         png_uint_32 sumhi, sumlo;
+         sumlo = sum & PNG_LOMASK;
+         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */
+
+         /* Reduce the sum if we match any of the previous rows */
+         for (i = 0; i < (png_uint_32)png_ptr->num_prev_filters; i++)
+         {
+            if (png_ptr->prev_filters[i] == PNG_FILTER_NONE)
+            {
+               sumlo = (sumlo * png_ptr->filter_weights[i]) >>
+                  PNG_WEIGHT_SHIFT;
+               sumhi = (sumhi * png_ptr->filter_weights[i]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         /* Factor in the cost of this filter (this is here for completeness,
+          * but it makes no sense to have a "cost" for the NONE filter, as
+          * it has the minimum possible computational cost - none).
+          */
+         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
+            PNG_COST_SHIFT;
+         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
+            PNG_COST_SHIFT;
+
+         if (sumhi > PNG_HIMASK)
+            sum = PNG_MAXSUM;
+         else
+            sum = (sumhi << PNG_HISHIFT) + sumlo;
+      }
+#endif
+      mins = sum;
+   }
+
+   /* sub filter */
+   if (png_ptr->do_filter & PNG_FILTER_SUB)
+   {
+      png_bytep rp, dp, lp;
+      png_uint_32 sum = 0, lmins = mins;
+      png_uint_32 i;
+      int v;
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+      /* We temporarily increase the "minumum sum" by the factor we
+       * would reduce the sum of this filter, so that we can do the
+       * early exit comparison without scaling the sum each time.
+       */
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         png_uint_32 lmhi, lmlo;
+         lmlo = lmins & PNG_LOMASK;
+         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (i = 0; i < (png_uint_32)png_ptr->num_prev_filters; i++)
+         {
+            if (png_ptr->prev_filters[i] == PNG_FILTER_VALUE_SUB)
+            {
+               lmlo = (lmlo * png_ptr->inv_filter_weights[i]) >>
+                  PNG_WEIGHT_SHIFT;
+               lmhi = (lmhi * png_ptr->inv_filter_weights[i]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+            PNG_COST_SHIFT;
+         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+            PNG_COST_SHIFT;
+
+         if (lmhi > PNG_HIMASK)
+            lmins = PNG_MAXSUM;
+         else
+            lmins = (lmhi << PNG_HISHIFT) + lmlo;
+      }
+#endif
+
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
+           i++, rp++, dp++)
+      {
+         v = *dp = *rp;
+
+         sum += (v < 128) ? v : 256 - v;
+      }
+      for (lp = row_buf + 1; i < row_info->rowbytes;
+         i++, rp++, lp++, dp++)
+      {
+         v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+
+         sum += (v < 128) ? v : 256 - v;
+
+         if (sum > lmins)  /* We are already worse, don't continue. */
+            break;
+      }
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         png_uint_32 sumhi, sumlo;
+         sumlo = sum & PNG_LOMASK;
+         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (i = 0; i < (png_uint_32)png_ptr->num_prev_filters; i++)
+         {
+            if (png_ptr->prev_filters[i] == PNG_FILTER_VALUE_SUB)
+            {
+               sumlo = (sumlo * png_ptr->inv_filter_weights[i]) >>
+                  PNG_WEIGHT_SHIFT;
+               sumhi = (sumhi * png_ptr->inv_filter_weights[i]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+            PNG_COST_SHIFT;
+         sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+            PNG_COST_SHIFT;
+
+         if (sumhi > PNG_HIMASK)
+            sum = PNG_MAXSUM;
+         else
+            sum = (sumhi << PNG_HISHIFT) + sumlo;
+      }
+#endif
+
+      if (sum < mins)
+      {
+         mins = sum;
+         best_row = png_ptr->sub_row;
+      }
+   }
+
+   /* up filter */
+   if (png_ptr->do_filter & PNG_FILTER_UP)
+   {
+      png_bytep rp, dp, pp;
+      png_uint_32 sum = 0, lmins = mins;
+      png_uint_32 i;
+      int v;
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         png_uint_32 lmhi, lmlo;
+         lmlo = lmins & PNG_LOMASK;
+         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (i = 0; i < (png_uint_32)png_ptr->num_prev_filters; i++)
+         {
+            if (png_ptr->prev_filters[i] == PNG_FILTER_VALUE_UP)
+            {
+               lmlo = (lmlo * png_ptr->inv_filter_weights[i]) >>
+                  PNG_WEIGHT_SHIFT;
+               lmhi = (lmhi * png_ptr->inv_filter_weights[i]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
+            PNG_COST_SHIFT;
+         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
+            PNG_COST_SHIFT;
+
+         if (lmhi > PNG_HIMASK)
+            lmins = PNG_MAXSUM;
+         else
+            lmins = (lmhi << PNG_HISHIFT) + lmlo;
+      }
+#endif
+
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
+           pp = prev_row + 1; i < row_info->rowbytes;
+           i++, rp++, pp++, dp++)
+      {
+         v = *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
+
+         sum += (v < 128) ? v : 256 - v;
+
+         if (sum > lmins)  /* We are already worse, don't continue. */
+            break;
+      }
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         png_uint_32 sumhi, sumlo;
+         sumlo = sum & PNG_LOMASK;
+         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (i = 0; i < (png_uint_32)png_ptr->num_prev_filters; i++)
+         {
+            if (png_ptr->prev_filters[i] == PNG_FILTER_UP)
+            {
+               sumlo = (sumlo * png_ptr->filter_weights[i]) >>
+                  PNG_WEIGHT_SHIFT;
+               sumhi = (sumhi * png_ptr->filter_weights[i]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
+            PNG_COST_SHIFT;
+         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
+            PNG_COST_SHIFT;
+
+         if (sumhi > PNG_HIMASK)
+            sum = PNG_MAXSUM;
+         else
+            sum = (sumhi << PNG_HISHIFT) + sumlo;
+      }
+#endif
+
+      if (sum < mins)
+      {
+         mins = sum;
+         best_row = png_ptr->up_row;
+      }
+   }
+
+   /* avg filter */
+   if (png_ptr->do_filter & PNG_FILTER_AVG)
+   {
+      png_bytep rp, dp, pp, lp;
+      png_uint_32 sum = 0, lmins = mins;
+      png_uint_32 i;
+      int v;
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         png_uint_32 lmhi, lmlo;
+         lmlo = lmins & PNG_LOMASK;
+         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (i = 0; i < (png_uint_32)png_ptr->num_prev_filters; i++)
+         {
+            if (png_ptr->prev_filters[i] == PNG_FILTER_VALUE_AVG)
+            {
+               lmlo = (lmlo * png_ptr->inv_filter_weights[i]) >>
+                  PNG_WEIGHT_SHIFT;
+               lmhi = (lmhi * png_ptr->inv_filter_weights[i]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
+            PNG_COST_SHIFT;
+         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
+            PNG_COST_SHIFT;
+
+         if (lmhi > PNG_HIMASK)
+            lmins = PNG_MAXSUM;
+         else
+            lmins = (lmhi << PNG_HISHIFT) + lmlo;
+      }
+#endif
+
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
+           pp = prev_row + 1; i < bpp; i++, rp++, pp++, dp++)
+      {
+         v = *dp = (png_byte)(((int)*rp - ((int)*pp / 2)) & 0xff);
+
+         sum += (v < 128) ? v : 256 - v;
+      }
+      for (lp = row_buf + 1; i < row_info->rowbytes;
+           i++, rp++, pp++, lp++, dp++)
+      {
+         v = *dp = (png_byte)(((int)*rp - (((int)*pp + (int)*lp) / 2)) & 0xff);
+
+         sum += (v < 128) ? v : 256 - v;
+
+         if (sum > lmins)  /* We are already worse, don't continue. */
+            break;
+      }
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         png_uint_32 sumhi, sumlo;
+         sumlo = sum & PNG_LOMASK;
+         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (i = 0; i < png_ptr->num_prev_filters; i++)
+         {
+            if (png_ptr->prev_filters[i] == PNG_FILTER_NONE)
+            {
+               sumlo = (sumlo * png_ptr->filter_weights[i]) >>
+                  PNG_WEIGHT_SHIFT;
+               sumhi = (sumhi * png_ptr->filter_weights[i]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
+            PNG_COST_SHIFT;
+         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
+            PNG_COST_SHIFT;
+
+         if (sumhi > PNG_HIMASK)
+            sum = PNG_MAXSUM;
+         else
+            sum = (sumhi << PNG_HISHIFT) + sumlo;
+      }
+#endif
+
+      if (sum < mins)
+      {
+         mins = sum;
+         best_row = png_ptr->avg_row;
+      }
+   }
+
+   /* Paeth filter */
+   if (png_ptr->do_filter & PNG_FILTER_PAETH)
+   {
+      png_bytep rp, dp, pp, cp, lp;
+      png_uint_32 sum = 0, lmins = mins;
+      png_uint_32 i;
+      int v;
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         png_uint_32 lmhi, lmlo;
+         lmlo = lmins & PNG_LOMASK;
+         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (i = 0; i < png_ptr->num_prev_filters; i++)
+         {
+            if (png_ptr->prev_filters[i] == PNG_FILTER_VALUE_PAETH)
+            {
+               lmlo = (lmlo * png_ptr->inv_filter_weights[i]) >>
+                  PNG_WEIGHT_SHIFT;
+               lmhi = (lmhi * png_ptr->inv_filter_weights[i]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+            PNG_COST_SHIFT;
+         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+            PNG_COST_SHIFT;
+
+         if (lmhi > PNG_HIMASK)
+            lmins = PNG_MAXSUM;
+         else
+            lmins = (lmhi << PNG_HISHIFT) + lmlo;
+      }
+#endif
+
+      for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
+           pp = prev_row + 1; (unsigned)i < bpp; i++, rp++, pp++, dp++)
+      {
+         v = *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
+
+         sum += (v < 128) ? v : 256 - v;
+      }
+      for (lp = row_buf + 1, cp = prev_row + 1; i < row_info->rowbytes;
+           i++, rp++, pp++, lp++, dp++, cp++)
+      {
+         int a, b, c, pa, pb, pc, p;
+
+         b = *pp;
+         c = *cp;
+         a = *lp;
+
+         p = a + b - c;
+         pa = abs(p - a);
+         pb = abs(p - b);
+         pc = abs(p - c);
+
+         if (pa <= pb && pa <= pc)
+            p = a;
+         else if (pb <= pc)
+            p = b;
+         else
+            p = c;
+
+         v = *dp = (png_byte)(((int)*rp - p) & 0xff);
+
+         sum += (v < 128) ? v : 256 - v;
+
+         if (sum > lmins)  /* We are already worse, don't continue. */
+            break;
+      }
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+      {
+         png_uint_32 sumhi, sumlo;
+         sumlo = sum & PNG_LOMASK;
+         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+         for (i = 0; i < png_ptr->num_prev_filters; i++)
+         {
+            if (png_ptr->prev_filters[i] == PNG_FILTER_PAETH)
+            {
+               sumlo = (sumlo * png_ptr->filter_weights[i]) >>
+                  PNG_WEIGHT_SHIFT;
+               sumhi = (sumhi * png_ptr->filter_weights[i]) >>
+                  PNG_WEIGHT_SHIFT;
+            }
+         }
+
+         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+            PNG_COST_SHIFT;
+         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+            PNG_COST_SHIFT;
+
+         if (sumhi > PNG_HIMASK)
+            sum = PNG_MAXSUM;
+         else
+            sum = (sumhi << PNG_HISHIFT) + sumlo;
+      }
+#endif
+
+      if (sum < mins)
+      {
+         best_row = png_ptr->paeth_row;
+      }
+   }
+
+   /* Do the actual writing of the filtered row data from the chosen filter. */
+   png_write_filtered_row(png_ptr, best_row);
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+   /* Save the type of filter we picked this time for future calculations */
+   if (png_ptr->num_prev_filters > 0)
+   {
+      int i;
+
+      for (i = 1; i < (int)png_ptr->num_prev_filters; i++)
+      {
+         png_ptr->prev_filters[i] = png_ptr->prev_filters[i - 1];
+      }
+      png_ptr->prev_filters[i] = best_row[0];
+   }
+#endif
+}
+
+
+/* Do the actual writing of a previously filtered row. */
+void
+png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row)
+{
+   png_debug(1, "in png_write_filtered_row\n");
+   png_debug1(2, "filter = %d\n", filtered_row[0]);
+   /* set up the zlib input buffer */
+   png_ptr->zstream.next_in = filtered_row;
+   png_ptr->zstream.avail_in = (uInt)png_ptr->row_info.rowbytes + 1;
+   /* repeat until we have compressed all the data */
+   do
+   {
+      int ret; /* return of zlib */
+
+      /* compress the data */
+      ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
+      /* check for compression errors */
+      if (ret != Z_OK)
+      {
+         if (png_ptr->zstream.msg != NULL)
+            png_error(png_ptr, png_ptr->zstream.msg);
+         else
+            png_error(png_ptr, "zlib error");
+      }
+
+      /* see if it is time to write another IDAT */
+      if (!(png_ptr->zstream.avail_out))
+      {
+         /* write the IDAT and reset the zlib output buffer */
+         png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
+         png_ptr->zstream.next_out = png_ptr->zbuf;
+         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+      }
+   /* repeat until all data has been compressed */
+   } while (png_ptr->zstream.avail_in);
+
+   /* swap the current and previous rows */
+   if (png_ptr->prev_row != NULL)
+   {
+      png_bytep tptr;
+
+      tptr = png_ptr->prev_row;
+      png_ptr->prev_row = png_ptr->row_buf;
+      png_ptr->row_buf = tptr;
+   }
+
+   /* finish row - updates counters and flushes zlib if last row */
+   png_write_finish_row(png_ptr);
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+   png_ptr->flush_rows++;
+
+   if (png_ptr->flush_dist > 0 &&
+       png_ptr->flush_rows >= png_ptr->flush_dist)
+   {
+      png_write_flush(png_ptr);
+   }
+#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+}
diff --git a/src/png/scripts/SCOPTIONS.ppc b/src/png/scripts/SCOPTIONS.ppc
new file mode 100644
index 0000000000..2c3503e9eb
--- /dev/null
+++ b/src/png/scripts/SCOPTIONS.ppc
@@ -0,0 +1,7 @@
+OPTIMIZE
+OPTPEEP
+OPTTIME
+OPTSCHED
+AUTOREGISTER
+PARMS=REGISTERS
+INCLUDEDIR=hlp:ppc/include
diff --git a/src/png/scripts/build.bat b/src/png/scripts/build.bat
new file mode 100644
index 0000000000..ec34b6f035
--- /dev/null
+++ b/src/png/scripts/build.bat
@@ -0,0 +1,2 @@
+make -fmakefile.bor -B -DMODEL=m %1 %2 %3 libpng >buildm.out
+make -fmakefile.bor -B -DMODEL=l %1 %2 %3 libpng >buildl.out
diff --git a/src/png/scripts/descrip.mms b/src/png/scripts/descrip.mms
new file mode 100644
index 0000000000..3584b0d782
--- /dev/null
+++ b/src/png/scripts/descrip.mms
@@ -0,0 +1,52 @@
+
+cc_defs = /inc=$(ZLIBSRC)
+c_deb = 
+
+.ifdef __DECC__
+pref = /prefix=all
+.endif
+
+
+
+OBJS = png.obj, pngset.obj, pngget.obj, pngrutil.obj, pngtrans.obj,\
+	pngwutil.obj, pngread.obj, pngmem.obj, pngwrite.obj, pngrtran.obj,\
+	pngwtran.obj, pngrio.obj, pngwio.obj, pngerror.obj, pngpread.obj
+
+
+CFLAGS= $(C_DEB) $(CC_DEFS) $(PREF)
+
+all : pngtest.exe libpng.olb
+		@ write sys$output " pngtest available"
+
+libpng.olb : libpng.olb($(OBJS))
+	@ write sys$output " Libpng available"
+
+
+pngtest.exe : pngtest.obj libpng.olb
+              link pngtest,libpng.olb/lib,$(ZLIBSRC)libz.olb/lib
+
+test : pngtest.exe
+   run pngtest
+
+clean :
+	delete *.obj;*,*.exe;*
+
+
+# Other dependencies.
+png.obj : png.h, pngconf.h
+pngpread.obj : png.h, pngconf.h
+pngset.obj : png.h, pngconf.h
+pngget.obj : png.h, pngconf.h
+pngread.obj : png.h, pngconf.h
+pngrtran.obj : png.h, pngconf.h
+pngrutil.obj : png.h, pngconf.h
+pngerror.obj : png.h, pngconf.h
+pngmem.obj : png.h, pngconf.h
+pngrio.obj : png.h, pngconf.h
+pngwio.obj : png.h, pngconf.h
+pngtest.obj : png.h, pngconf.h
+pngtrans.obj : png.h, pngconf.h
+pngwrite.obj : png.h, pngconf.h
+pngwtran.obj : png.h, pngconf.h
+pngwutil.obj : png.h, pngconf.h
+
diff --git a/src/png/scripts/makefile.aco b/src/png/scripts/makefile.aco
new file mode 100644
index 0000000000..2cb089879b
--- /dev/null
+++ b/src/png/scripts/makefile.aco
@@ -0,0 +1,221 @@
+# Project:   libpng
+
+
+# Toolflags:
+CCflags = -c -depend !Depend -IC:,Zlib: -g -throwback  -DRISCOS  -fnah 
+C++flags = -c -depend !Depend -IC: -throwback
+Linkflags = -aif -c++ -o $@
+ObjAsmflags = -throwback -NoCache -depend !Depend
+CMHGflags = 
+LibFileflags = -c -l -o $@ 
+Squeezeflags = -o $@
+
+
+# Final targets:
+@.libpng-lib:   @.o.png @.o.pngerror @.o.pngrio @.o.pngwio @.o.pngmem \
+        @.o.pngpread @.o.pngset @.o.pngget @.o.pngread @.o.pngrtran \
+        @.o.pngrutil @.o.pngtrans @.o.pngwrite @.o.pngwtran @.o.pngwutil 
+        LibFile $(LibFileflags) @.o.png @.o.pngerror @.o.pngrio @.o.pngrtran \
+        @.o.pngmem @.o.pngpread @.o.pngset @.o.pngget @.o.pngread @.o.pngwio \
+        @.o.pngrutil @.o.pngtrans  @.o.pngwrite @.o.pngwtran @.o.pngwutil 
+@.mm-libpng-lib:   @.mm.png @.mm.pngerror @.mm.pngrio @.mm.pngwio @.mm.pngmem \
+        @.mm.pngpread @.mm.pngset @.mm.pngget @.mm.pngread @.mm.pngrtran \
+        @.mm.pngrutil @.mm.pngtrans @.mm.pngwrite @.mm.pngwtran @.mm.pngwutil 
+        LibFile $(LibFileflags) @.mm.png @.mm.pngerror @.mm.pngrio \
+        @.mm.pngwio @.mm.pngmem @.mm.pngpread @.mm.pngset @.mm.pngget \
+        @.mm.pngread @.mm.pngrtran @.mm.pngrutil @.mm.pngtrans @.mm.pngwrite \
+        @.mm.pngwtran @.mm.pngwutil 
+
+
+# User-editable dependencies:
+# (C) Copyright 1997 Tom Tanner
+Test: @.pngtest 
+        <Prefix$Dir>.pngtest
+        @remove <Prefix$Dir>.pngtest
+
+#It would be nice if you could stop "make" listing from here on!
+@.pngtest:   @.o.pngtest @.libpng-lib C:o.Stubs Zlib:zlib_lib 
+        Link $(Linkflags) @.o.pngtest @.libpng-lib C:o.Stubs Zlib:zlib_lib 
+
+.SUFFIXES: .o .mm .c
+
+.c.mm:
+        MemCheck.CC cc $(ccflags) -o $@ LibPng:$<
+.c.o:
+        cc $(ccflags) -o $@ $<
+
+
+# Static dependencies:
+
+
+# Dynamic dependencies:
+o.pngtest:	c.pngtest
+o.pngtest:	h.png
+o.pngtest:	Zlib:h.zlib
+o.pngtest:	Zlib:h.zconf
+o.pngtest:	h.pngconf
+mm.png:		LibPng:c.png
+mm.png:		LibPng:h.png
+mm.png:		Zlib:h.zlib
+mm.png:		Zlib:h.zconf
+mm.png:		LibPng:h.pngconf
+mm.png:		MemCheck:ANSI.h.stdio
+mm.pngerror:	LibPng:c.pngerror
+mm.pngerror:	LibPng:h.png
+mm.pngerror:	Zlib:h.zlib
+mm.pngerror:	Zlib:h.zconf
+mm.pngerror:	LibPng:h.pngconf
+mm.pngerror:	MemCheck:ANSI.h.stdio
+mm.pngrio:	LibPng:c.pngrio
+mm.pngrio:	LibPng:h.png
+mm.pngrio:	Zlib:h.zlib
+mm.pngrio:	Zlib:h.zconf
+mm.pngrio:	LibPng:h.pngconf
+mm.pngrio:	MemCheck:ANSI.h.stdio
+mm.pngwio:	LibPng:c.pngwio
+mm.pngwio:	LibPng:h.png
+mm.pngwio:	Zlib:h.zlib
+mm.pngwio:	Zlib:h.zconf
+mm.pngwio:	LibPng:h.pngconf
+mm.pngwio:	MemCheck:ANSI.h.stdio
+mm.pngmem:	LibPng:c.pngmem
+mm.pngmem:	LibPng:h.png
+mm.pngmem:	Zlib:h.zlib
+mm.pngmem:	Zlib:h.zconf
+mm.pngmem:	LibPng:h.pngconf
+mm.pngmem:	MemCheck:ANSI.h.stdio
+mm.pngpread:	LibPng:c.pngpread
+mm.pngpread:	LibPng:h.png
+mm.pngpread:	Zlib:h.zlib
+mm.pngpread:	Zlib:h.zconf
+mm.pngpread:	LibPng:h.pngconf
+mm.pngpread:	MemCheck:ANSI.h.stdio
+mm.pngset:	LibPng:c.pngset
+mm.pngset:	LibPng:h.png
+mm.pngset:	Zlib:h.zlib
+mm.pngset:	Zlib:h.zconf
+mm.pngset:	LibPng:h.pngconf
+mm.pngset:	MemCheck:ANSI.h.stdio
+mm.pngget:	LibPng:c.pngget
+mm.pngget:	LibPng:h.png
+mm.pngget:	Zlib:h.zlib
+mm.pngget:	Zlib:h.zconf
+mm.pngget:	LibPng:h.pngconf
+mm.pngget:	MemCheck:ANSI.h.stdio
+mm.pngread:	LibPng:c.pngread
+mm.pngread:	LibPng:h.png
+mm.pngread:	Zlib:h.zlib
+mm.pngread:	Zlib:h.zconf
+mm.pngread:	LibPng:h.pngconf
+mm.pngread:	MemCheck:ANSI.h.stdio
+mm.pngrtran:	LibPng:c.pngrtran
+mm.pngrtran:	LibPng:h.png
+mm.pngrtran:	Zlib:h.zlib
+mm.pngrtran:	Zlib:h.zconf
+mm.pngrtran:	LibPng:h.pngconf
+mm.pngrtran:	MemCheck:ANSI.h.stdio
+mm.pngrutil:	LibPng:c.pngrutil
+mm.pngrutil:	LibPng:h.png
+mm.pngrutil:	Zlib:h.zlib
+mm.pngrutil:	Zlib:h.zconf
+mm.pngrutil:	LibPng:h.pngconf
+mm.pngrutil:	MemCheck:ANSI.h.stdio
+mm.pngtrans:	LibPng:c.pngtrans
+mm.pngtrans:	LibPng:h.png
+mm.pngtrans:	Zlib:h.zlib
+mm.pngtrans:	Zlib:h.zconf
+mm.pngtrans:	LibPng:h.pngconf
+mm.pngtrans:	MemCheck:ANSI.h.stdio
+mm.pngwrite:	LibPng:c.pngwrite
+mm.pngwrite:	LibPng:h.png
+mm.pngwrite:	Zlib:h.zlib
+mm.pngwrite:	Zlib:h.zconf
+mm.pngwrite:	LibPng:h.pngconf
+mm.pngwrite:	MemCheck:ANSI.h.stdio
+mm.pngwtran:	LibPng:c.pngwtran
+mm.pngwtran:	LibPng:h.png
+mm.pngwtran:	Zlib:h.zlib
+mm.pngwtran:	Zlib:h.zconf
+mm.pngwtran:	LibPng:h.pngconf
+mm.pngwtran:	MemCheck:ANSI.h.stdio
+mm.pngwutil:	LibPng:c.pngwutil
+mm.pngwutil:	LibPng:h.png
+mm.pngwutil:	Zlib:h.zlib
+mm.pngwutil:	Zlib:h.zconf
+mm.pngwutil:	LibPng:h.pngconf
+mm.pngwutil:	MemCheck:ANSI.h.stdio
+o.png:		c.png
+o.png:		h.png
+o.png:		Zlib:h.zlib
+o.png:		Zlib:h.zconf
+o.png:		h.pngconf
+o.pngerror:	c.pngerror
+o.pngerror:	h.png
+o.pngerror:	Zlib:h.zlib
+o.pngerror:	Zlib:h.zconf
+o.pngerror:	h.pngconf
+o.pngrio:	c.pngrio
+o.pngrio:	h.png
+o.pngrio:	Zlib:h.zlib
+o.pngrio:	Zlib:h.zconf
+o.pngrio:	h.pngconf
+o.pngwio:	c.pngwio
+o.pngwio:	h.png
+o.pngwio:	Zlib:h.zlib
+o.pngwio:	Zlib:h.zconf
+o.pngwio:	h.pngconf
+o.pngmem:	c.pngmem
+o.pngmem:	h.png
+o.pngmem:	Zlib:h.zlib
+o.pngmem:	Zlib:h.zconf
+o.pngmem:	h.pngconf
+o.pngpread:	c.pngpread
+o.pngpread:	h.png
+o.pngpread:	Zlib:h.zlib
+o.pngpread:	Zlib:h.zconf
+o.pngpread:	h.pngconf
+o.pngset:	c.pngset
+o.pngset:	h.png
+o.pngset:	Zlib:h.zlib
+o.pngset:	Zlib:h.zconf
+o.pngset:	h.pngconf
+o.pngget:	c.pngget
+o.pngget:	h.png
+o.pngget:	Zlib:h.zlib
+o.pngget:	Zlib:h.zconf
+o.pngget:	h.pngconf
+o.pngread:	c.pngread
+o.pngread:	h.png
+o.pngread:	Zlib:h.zlib
+o.pngread:	Zlib:h.zconf
+o.pngread:	h.pngconf
+o.pngrtran:	c.pngrtran
+o.pngrtran:	h.png
+o.pngrtran:	Zlib:h.zlib
+o.pngrtran:	Zlib:h.zconf
+o.pngrtran:	h.pngconf
+o.pngrutil:	c.pngrutil
+o.pngrutil:	h.png
+o.pngrutil:	Zlib:h.zlib
+o.pngrutil:	Zlib:h.zconf
+o.pngrutil:	h.pngconf
+o.pngtrans:	c.pngtrans
+o.pngtrans:	h.png
+o.pngtrans:	Zlib:h.zlib
+o.pngtrans:	Zlib:h.zconf
+o.pngtrans:	h.pngconf
+o.pngwrite:	c.pngwrite
+o.pngwrite:	h.png
+o.pngwrite:	Zlib:h.zlib
+o.pngwrite:	Zlib:h.zconf
+o.pngwrite:	h.pngconf
+o.pngwtran:	c.pngwtran
+o.pngwtran:	h.png
+o.pngwtran:	Zlib:h.zlib
+o.pngwtran:	Zlib:h.zconf
+o.pngwtran:	h.pngconf
+o.pngwutil:	c.pngwutil
+o.pngwutil:	h.png
+o.pngwutil:	Zlib:h.zlib
+o.pngwutil:	Zlib:h.zconf
+o.pngwutil:	h.pngconf
diff --git a/src/png/scripts/makefile.ama b/src/png/scripts/makefile.ama
new file mode 100644
index 0000000000..366524d5c8
--- /dev/null
+++ b/src/png/scripts/makefile.ama
@@ -0,0 +1,42 @@
+# Commodore Amiga Makefile
+# makefile for libpng and SAS C V6.55 compiler
+# Copyright (C) 1995 Wolf Faust
+
+#compiler
+CC=sc
+#compiler flags
+# WARNING: a bug in V6.51 causes bad code with OPTGO
+#          So use V6.55 or set NOOPTGO!!!!!!!!!
+CFLAGS= NOSTKCHK PARMS=REG OPTIMIZE OPTGO OPTPEEP OPTINLOCAL OPTINL\
+        OPTLOOP OPTRDEP=4 OPTDEP=4 OPTCOMP=4 DEFINE=PNG_INTERNAL
+#linker flags
+LDFLAGS= SD ND BATCH
+#link libs
+LDLIBS= libpng.lib libgz.lib LIB:scm.lib LIB:sc.lib Lib:amiga.lib
+# linker
+LN= slink
+# file deletion command
+RM= delete quiet
+# library (.lib) file creation command
+AR= oml
+# make directory command
+MKDIR= makedir
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o pngpread.o \
+pngread.o pngerror.o pngwrite.o pngrtran.o pngwtran.o pngrio.o pngwio.o pngmem.o
+
+all: libpng.lib pngtest
+
+libpng.lib: $(OBJS)
+-$(RM) libpng.lib
+$(AR) libpng.lib r $(OBJS)
+
+pngtest: pngtest.o libpng.lib
+$(LN) <WITH <
+$(LDFLAGS)
+TO pngtest
+FROM LIB:c.o pngtest.o
+LIB $(LDLIBS)
+<
+
+
diff --git a/src/png/scripts/makefile.atr b/src/png/scripts/makefile.atr
new file mode 100644
index 0000000000..d490ce1dd4
--- /dev/null
+++ b/src/png/scripts/makefile.atr
@@ -0,0 +1,31 @@
+# makefile for libpng
+# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
+# For conditions of distribution and use, see copyright notice in png.h
+# modified for LC56/ATARI assumes libz.lib is in same dir and uses default
+# rules for library management
+#
+CFLAGS=-I..\zlib -O
+LBR = png.lib
+LDFLAGS=-lpng -lz -lm
+
+# where make install puts libpng.a and png.h
+
+OBJS = $(LBR)(png.o) $(LBR)(pngset.o) $(LBR)(pngget.o) $(LBR)(pngrutil.o)\
+	$(LBR)(pngtrans.o) $(LBR)(pngwutil.o)\
+	$(LBR)(pngread.o) $(LBR)(pngerror.o) $(LBR)(pngwrite.o)\
+	$(LBR)(pngrtran.o) $(LBR)(pngwtran.o)\
+	$(LBR)(pngmem.o) $(LBR)(pngrio.o) $(LBR)(pngwio.o) $(LBR)(pngpread.o)
+
+all: $(LBR) pngtest.ttp
+
+$(LBR): $(OBJS)
+
+pngtest.ttp: pngtest.o $(LBR)
+	$(CC) $(CFLAGS) $(LDFLAGS) -o$@ pngtest.o
+
+install: libpng.a
+	-@mkdir $(prefix)/include
+	-@mkdir $(prefix)/lib
+	cp png.h $(prefix)/include
+	cp pngconf.h $(prefix)/include
+	chmod 644 $(prefix)/include/p
diff --git a/src/png/scripts/makefile.bor b/src/png/scripts/makefile.bor
new file mode 100644
index 0000000000..0b7c0e6112
--- /dev/null
+++ b/src/png/scripts/makefile.bor
@@ -0,0 +1,168 @@
+# Makefile for libpng
+# Borland C++ 4.5 (Note: All modules are compiled in C mode)
+# Will work with C++ 4.02 also
+# To build the library, do: 
+#       "make -fmakefile.bor -DMODEL=m"
+# or:   "make -fmakefile.bor -DMODEL=l"
+#
+# ------------- Borland C++ 4.5 -------------
+
+### Absolutely necessary for this makefile to work
+.AUTODEPEND
+
+## Useful user options
+
+# Usually defined in builtins.mak or the environment
+# Currently unused.
+!ifndef BCROOT
+BCROOT=N:\BC45
+!endif
+
+# Where zlib.h and zconf.h and zlib.lib are
+ZLIB_PATH=..\zlib
+
+!ifndef MODEL
+MODEL=l
+!endif
+
+#TARGET_CPU=3
+# 2 = 286, 3 = 386, etc.
+!ifndef TARGET_CPU
+TARGET_CPU=2
+!endif
+
+
+# Use this if you don't want Borland's fancy exception handling.
+NOEHLIB=noeh$(MODEL).lib
+
+!ifdef DEBUG
+CDEBUG=-v
+LDEBUG=-v
+!else
+CDEBUG=
+LDEBUG=
+!endif
+
+# STACKOFLOW=1
+!ifdef STACKOFLOW
+CDEBUG=$(CDEBUG) -N
+LDEBUG=$(LDEBUG) -N
+!endif
+
+
+## Compiler, linker, and lib stuff
+CC=bcc
+LD=bcc
+LIB=tlib
+
+MODELARG=-m$(MODEL)
+
+# -X- turns on dependency generation in the object file
+# -w  sets all warnings on
+# -O2 optimize for speed
+# -Z  global optimization
+CFLAGS=-O2 -Z -X- -w -I$(ZLIB_PATH) -$(TARGET_CPU) $(MODELARG) $(CDEBUG)
+
+# -M  generate map file
+LDFLAGS=-M $(LDEBUG)
+
+O=obj
+
+## variables
+OBJS = \
+ png.$(O) \
+ pngerror.$(O) \
+ pngmem.$(O) \
+ pngpread.$(O) \
+ pngset.$(O) \
+ pngget.$(O) \
+ pngread.$(O) \
+ pngrio.$(O) \
+ pngrtran.$(O) \
+ pngrutil.$(O) \
+ pngtrans.$(O) \
+ pngwrite.$(O) \
+ pngwtran.$(O) \
+ pngwio.$(O) \
+ pngwutil.$(O)
+
+LIBOBJS = \
+ +png.$(O) \
+ +pngerror.$(O) \
+ +pngmem.$(O) \
+ +pngpread.$(O) \
+ +pngread.$(O) \
+ +pngset.$(O) \
+ +pngget.$(O) \
+ +pngrio.$(O) \
+ +pngrtran.$(O) \
+ +pngrutil.$(O) \
+ +pngtrans.$(O) \
+ +pngwrite.$(O) \
+ +pngwtran.$(O) \
+ +pngwio.$(O)
+ +pngwutil.$(O)
+
+LIBNAME=libpng$(MODEL).lib
+
+
+## Implicit rules
+# Braces let make "batch" calls to the compiler,
+# 2 calls instead of 12; space is important.
+.c.obj:
+	$(CC) $(CFLAGS) -c {$*.c }
+
+.c.exe:
+	$(CC) $(CFLAGS) $(LDFLAGS) $*.c
+
+
+## Major targets
+libpng: $(LIBNAME)
+
+pngtest: pngtest$(MODEL).exe
+
+test:
+	pngtest$(MODEL)
+
+
+## Minor Targets
+
+png.obj: png.c
+pngset.obj: pngset.c
+pngget.obj: pngget.c
+pngread.obj: pngread.c
+pngpread.obj: pngpread.c
+pngrtran.obj: pngrtran.c
+pngrutil.obj: pngrutil.c
+pngerror.obj: pngerror.c
+pngmem.obj: pngmem.c
+pngrio.obj: pngrio.c
+pngwio.obj: pngwio.c
+pngtrans.obj: pngtrans.c
+pngwrite.obj: pngwrite.c
+pngwtran.obj: pngwtran.c
+pngwutil.obj: pngwutil.c
+
+
+$(LIBNAME): $(OBJS)
+	-del $(LIBNAME)
+        $(LIB) $(LIBNAME) @&&|
+$(LIBOBJS), libpng$(MODEL)
+|
+
+
+pngtest$(MODEL).obj: pngtest.c
+	$(CC) $(CFLAGS) -opngtest$(MODEL) -c pngtest.c
+
+pngtest$(MODEL).exe: pngtest$(MODEL).obj
+	$(CC) $(MODELARG) $(LDFLAGS) -L$(ZLIB_PATH) pngtest$(MODEL).obj $(LIBNAME) zlib$(MODEL).lib $(NOEHLIB)
+
+
+# Clean up anything else you want
+clean:
+	-del *.obj
+	-del *.lib
+	-del *.lst
+
+
+# End of makefile for libpng
diff --git a/src/png/scripts/makefile.dec b/src/png/scripts/makefile.dec
new file mode 100644
index 0000000000..328799a940
--- /dev/null
+++ b/src/png/scripts/makefile.dec
@@ -0,0 +1,68 @@
+# makefile for libpng on DEC Alpha Unix
+# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
+# For conditions of distribution and use, see copyright notice in png.h
+
+# Where the zlib library and include files are located
+#ZLIBLIB=/usr/local/lib
+#ZLIBINC=/usr/local/include
+ZLIBLIB=../zlib
+ZLIBINC=../zlib
+
+CC=cc
+CFLAGS=-std -w1 -I$(ZLIBINC) -O # -g -DPNG_DEBUG=1
+LDFLAGS=-L. -L$(ZLIBLIB) -lpng -lz -lm
+
+#RANLIB=echo
+RANLIB=ranlib
+
+# where make install puts libpng.a and png.h
+prefix=/usr/local
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+	pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+	pngwtran.o pngmem.o pngerror.o pngpread.o
+
+all: libpng.a pngtest
+
+libpng.a: $(OBJS)
+	ar rc $@  $(OBJS)
+	$(RANLIB) $@
+
+pngtest: pngtest.o libpng.a
+	$(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+
+test: pngtest
+	./pngtest
+
+install: libpng.a
+	-@mkdir $(prefix)/include
+	-@mkdir $(prefix)/lib
+	cp png.h $(prefix)/include
+	cp pngconf.h $(prefix)/include
+	chmod 644 $(prefix)/include/png.h
+	chmod 644 $(prefix)/include/pngconf.h
+	cp libpng.a $(prefix)/lib
+	chmod 644 $(prefix)/lib/libpng.a
+
+clean:
+	rm -f *.o libpng.a pngtest pngout.png
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o: png.h pngconf.h
+pngerror.o: png.h pngconf.h
+pngrio.o: png.h pngconf.h
+pngwio.o: png.h pngconf.h
+pngmem.o: png.h pngconf.h
+pngset.o: png.h pngconf.h
+pngget.o: png.h pngconf.h
+pngread.o: png.h pngconf.h
+pngrtran.o: png.h pngconf.h
+pngrutil.o: png.h pngconf.h
+pngtest.o: png.h pngconf.h
+pngtrans.o: png.h pngconf.h
+pngwrite.o: png.h pngconf.h
+pngwtran.o: png.h pngconf.h
+pngwutil.o: png.h pngconf.h
+pngpread.o: png.h pngconf.h
+
diff --git a/src/png/scripts/makefile.dj2 b/src/png/scripts/makefile.dj2
new file mode 100644
index 0000000000..e80f5cc0f9
--- /dev/null
+++ b/src/png/scripts/makefile.dj2
@@ -0,0 +1,52 @@
+# DJGPP (DOS gcc) makefile for libpng
+# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
+# For conditions of distribution and use, see copyright notice in png.h
+
+CC=gcc
+CFLAGS=-I../zlib -O
+LDFLAGS=-L. -L../zlib/ -lpng -lz -lm
+
+RANLIB=ranlib
+
+# where make install puts libpng.a and png.h
+#prefix=/usr/local
+prefix=.
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+	pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o pngwtran.o \
+	pngmem.o pngerror.o pngpread.o
+
+all: libpng.a pngtest
+
+libpng.a: $(OBJS)
+	ar rc $@  $(OBJS)
+	$(RANLIB) $@
+
+pngtest: pngtest.o libpng.a
+	$(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+	coff2exe pngtest
+
+test: pngtest
+	./pngtest
+clean:
+	rm -f *.o libpng.a pngtest pngout.png
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o: png.h pngconf.h
+pngerror.o: png.h pngconf.h
+pngrio.o: png.h pngconf.h
+pngwio.o: png.h pngconf.h
+pngmem.o: png.h pngconf.h
+pngset.o: png.h pngconf.h
+pngget.o: png.h pngconf.h
+pngread.o: png.h pngconf.h
+pngpread.o: png.h pngconf.h
+pngrtran.o: png.h pngconf.h
+pngrutil.o: png.h pngconf.h
+pngtest.o: png.h pngconf.h
+pngtrans.o: png.h pngconf.h
+pngwrite.o: png.h pngconf.h
+pngwtran.o: png.h pngconf.h
+pngwutil.o: png.h pngconf.h
+
diff --git a/src/png/scripts/makefile.knr b/src/png/scripts/makefile.knr
new file mode 100644
index 0000000000..81129aee61
--- /dev/null
+++ b/src/png/scripts/makefile.knr
@@ -0,0 +1,73 @@
+# makefile for libpng
+# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
+# For conditions of distribution and use, see copyright notice in png.h
+
+CC=cc
+CFLAGS=-I../zlib -O
+LDFLAGS=-L. -L../zlib/ -lpng -lz -lm
+# flags for ansi2knr
+ANSI2KNRFLAGS=
+
+RANLIB=ranlib
+#RANLIB=echo
+
+# where make install puts libpng.a and png.h
+prefix=/usr/local
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+	pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+	pngwtran.o pngmem.o pngerror.o pngpread.o
+
+all: ansi2knr libpng.a pngtest
+
+# general rule to allow ansi2knr to work
+.c.o:
+	./ansi2knr $*.c T$*.c
+	$(CC) $(CFLAGS) -c T$*.c
+	rm -f T$*.c $*.o
+	mv T$*.o $*.o
+
+ansi2knr: ansi2knr.c
+	$(CC) $(CFLAGS) $(ANSI2KNRFLAGS) -o ansi2knr ansi2knr.c
+
+libpng.a: ansi2knr $(OBJS)
+	ar rc $@  $(OBJS)
+	$(RANLIB) $@
+
+pngtest: pngtest.o libpng.a
+	$(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+
+test: pngtest
+	./pngtest
+
+install: libpng.a
+	-@mkdir $(prefix)/include
+	-@mkdir $(prefix)/lib
+	cp png.h $(prefix)/include
+	cp pngconf.h $(prefix)/include
+	chmod 644 $(prefix)/include/png.h
+	chmod 644 $(prefix)/include/pngconf.h
+	cp libpng.a $(prefix)/lib
+	chmod 644 $(prefix)/lib/libpng.a
+
+clean:
+	rm -f *.o libpng.a pngtest pngout.png ansi2knr
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o: png.h pngconf.h
+pngerror.o: png.h pngconf.h
+pngrio.o: png.h pngconf.h
+pngwio.o: png.h pngconf.h
+pngmem.o: png.h pngconf.h
+pngset.o: png.h pngconf.h
+pngget.o: png.h pngconf.h
+pngread.o: png.h pngconf.h
+pngpread.o: png.h pngconf.h
+pngrtran.o: png.h pngconf.h
+pngrutil.o: png.h pngconf.h
+pngtest.o: png.h pngconf.h
+pngtrans.o: png.h pngconf.h
+pngwrite.o: png.h pngconf.h
+pngwtran.o: png.h pngconf.h
+pngwutil.o: png.h pngconf.h
diff --git a/src/png/scripts/makefile.lnx b/src/png/scripts/makefile.lnx
new file mode 100644
index 0000000000..3d1a76a42e
--- /dev/null
+++ b/src/png/scripts/makefile.lnx
@@ -0,0 +1,99 @@
+# makefile for libpng on Linux ELF with gcc
+# Copyright (C) 1996, 1997 Andreas Dilger
+# Copyright (C) 1998 Greg Roelofs
+# For conditions of distribution and use, see copyright notice in png.h
+
+CC=gcc
+
+# Where the zlib library and include files are located
+#ZLIBLIB=/usr/local/lib
+#ZLIBINC=/usr/local/include
+ZLIBLIB=../zlib
+ZLIBINC=../zlib
+
+WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
+         -Wmissing-declarations -Wtraditional -Wcast-align \
+         -Wstrict-prototypes -Wmissing-prototypes #-Wconversion
+CFLAGS=-I$(ZLIBINC) -Wall -O3 -funroll-loops -malign-loops=2 \
+       -malign-functions=2 #$(WARNMORE) -g -DPNG_DEBUG=5
+LDFLAGS=-L. -Wl,-rpath,. -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) -lpng -lz -lm
+
+RANLIB=ranlib
+#RANLIB=echo
+
+# read libpng.txt or png.h to see why PNGMAJ is 2.  You should not
+# have to change it.
+PNGMAJ = 2
+PNGMIN = 1.0
+PNGVER = $(PNGMAJ).$(PNGMIN)
+
+# where make install puts libpng.a, libpng.so*, and png.h
+prefix=/usr/local
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+       pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+       pngwtran.o pngmem.o pngerror.o pngpread.o
+
+OBJSDLL = $(OBJS:.o=.pic.o)
+
+.SUFFIXES:      .c .o .pic.o
+
+.c.pic.o:
+	$(CC) -c $(CFLAGS) -fPIC -o $@ $*.c
+
+all: libpng.a libpng.so pngtest
+
+libpng.a: $(OBJS)
+	ar rc $@ $(OBJS)
+	$(RANLIB) $@
+
+libpng.so: libpng.so.$(PNGMAJ)
+	ln -sf libpng.so.$(PNGMAJ) libpng.so
+
+libpng.so.$(PNGMAJ): libpng.so.$(PNGVER)
+	ln -sf libpng.so.$(PNGVER) libpng.so.$(PNGMAJ)
+
+libpng.so.$(PNGVER): $(OBJSDLL)
+	$(CC) -shared -Wl,-soname,libpng.so.$(PNGMAJ) -o libpng.so.$(PNGVER) \
+	 $(OBJSDLL)
+
+pngtest: pngtest.o libpng.so
+	$(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+
+test: pngtest
+	./pngtest
+
+install: libpng.a libpng.so.$(PNGVER)
+	-@mkdir $(INCPATH) $(LIBPATH)
+	cp png.h pngconf.h $(INCPATH)
+	chmod 644 $(INCPATH)/png.h $(INCPATH)/pngconf.h
+	cp libpng.a libpng.so.$(PNGVER) $(LIBPATH)
+	chmod 755 $(LIBPATH)/libpng.so.$(PNGVER)
+	-@/bin/rm -f $(LIBPATH)/libpng.so.$(PNGMAJ) $(LIBPATH)/libpng.so
+	(cd $(LIBPATH); ln -sf libpng.so.$(PNGVER) libpng.so.$(PNGMAJ); \
+	 ln -sf libpng.so.$(PNGMAJ) libpng.so)
+
+clean:
+	/bin/rm -f *.o libpng.a libpng.so* pngtest pngout.png
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o png.pic.o: png.h pngconf.h
+pngerror.o pngerror.pic.o: png.h pngconf.h
+pngrio.o pngrio.pic.o: png.h pngconf.h
+pngwio.o pngwio.pic.o: png.h pngconf.h
+pngmem.o pngmem.pic.o: png.h pngconf.h
+pngset.o pngset.pic.o: png.h pngconf.h
+pngget.o pngget.pic.o: png.h pngconf.h
+pngread.o pngread.pic.o: png.h pngconf.h
+pngrtran.o pngrtran.pic.o: png.h pngconf.h
+pngrutil.o pngrutil.pic.o: png.h pngconf.h
+pngtrans.o pngtrans.pic.o: png.h pngconf.h
+pngwrite.o pngwrite.pic.o: png.h pngconf.h
+pngwtran.o pngwtran.pic.o: png.h pngconf.h
+pngwutil.o pngwutil.pic.o: png.h pngconf.h
+pngpread.o pngpread.pic.o: png.h pngconf.h
+
+pngtest.o: png.h pngconf.h
diff --git a/src/png/scripts/makefile.mip b/src/png/scripts/makefile.mip
new file mode 100644
index 0000000000..2b3cccdc9f
--- /dev/null
+++ b/src/png/scripts/makefile.mip
@@ -0,0 +1,62 @@
+# makefile for libpng
+# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
+# For conditions of distribution and use, see copyright notice in png.h
+
+CC=cc
+CFLAGS=-I../zlib -O -systype sysv -DSYSV -w -Dmips
+#CFLAGS=-O
+LDFLAGS=-L. -L../zlib/ -lpng -lz -lm
+
+#RANLIB=ranlib
+RANLIB=echo
+
+# where make install puts libpng.a and png.h
+prefix=/usr/local
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+	pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+	pngwtran.o pngmem.o pngerror.o pngpread.o
+
+all: libpng.a pngtest
+
+libpng.a: $(OBJS)
+	ar rc $@  $(OBJS)
+	$(RANLIB) $@
+
+pngtest: pngtest.o libpng.a
+	$(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+
+test: pngtest
+	./pngtest
+
+install: libpng.a
+	-@mkdir $(prefix)/include
+	-@mkdir $(prefix)/lib
+	cp png.h $(prefix)/include
+	cp pngconf.h $(prefix)/include
+	chmod 644 $(prefix)/include/png.h
+	chmod 644 $(prefix)/include/pngconf.h
+	cp libpng.a $(prefix)/lib
+	chmod 644 $(prefix)/lib/libpng.a
+
+clean:
+	rm -f *.o libpng.a pngtest pngout.png
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o: png.h pngconf.h
+pngerror.o: png.h pngconf.h
+pngrio.o: png.h pngconf.h
+pngwio.o: png.h pngconf.h
+pngmem.o: png.h pngconf.h
+pngset.o: png.h pngconf.h
+pngget.o: png.h pngconf.h
+pngread.o: png.h pngconf.h
+pngpread.o: png.h pngconf.h
+pngrtran.o: png.h pngconf.h
+pngrutil.o: png.h pngconf.h
+pngtest.o: png.h pngconf.h
+pngtrans.o: png.h pngconf.h
+pngwrite.o: png.h pngconf.h
+pngwtran.o: png.h pngconf.h
+pngwutil.o: png.h pngconf.h
diff --git a/src/png/scripts/makefile.msc b/src/png/scripts/makefile.msc
new file mode 100644
index 0000000000..742de4e99f
--- /dev/null
+++ b/src/png/scripts/makefile.msc
@@ -0,0 +1,86 @@
+# makefile for libpng
+# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
+# For conditions of distribution and use, see copyright notice in png.h
+# Assumes that zlib.lib, zconf.h, and zlib.h have been copied to ..\zlib
+
+# ------------- Microsoft C 5.1 and later -------------
+MODEL=-AL
+CFLAGS=-Oait -Gs -nologo -W3 $(MODEL) -I..\zlib
+#-Ox generates bad code with MSC 5.1
+CC=cl
+LD=link
+LDFLAGS=/e/st:0x1500/noe 
+O=.obj
+
+#uncomment next to put error messages in a file
+ERRFILE= >> pngerrs
+
+# variables
+OBJS1 = png$(O) pngset$(O) pngget$(O) pngrutil$(O) pngtrans$(O) pngwutil$(O)
+OBJS2 = pngmem$(O) pngpread$(O) pngread$(O) pngerror$(O) pngwrite$(O)
+OBJS3 = pngrtran$(O) pngwtran$(O) pngrio$(O) pngwio$(O)
+
+all: libpng.lib
+
+png$(O): png.h pngconf.h
+		  $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngset$(O): png.h pngconf.h
+        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngget$(O): png.h pngconf.h
+        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngread$(O): png.h pngconf.h
+        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngpread$(O): png.h pngconf.h
+		  $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngrtran$(O): png.h pngconf.h
+        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngrutil$(O): png.h pngconf.h
+        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngerror$(O): png.h pngconf.h
+        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngmem$(O): png.h pngconf.h
+        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngrio$(O): png.h pngconf.h
+        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngwio$(O): png.h pngconf.h
+        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngtest$(O): png.h pngconf.h
+        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngtrans$(O): png.h pngconf.h
+        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngwrite$(O): png.h pngconf.h
+        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngwtran$(O): png.h pngconf.h
+        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngwutil$(O): png.h pngconf.h
+        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+libpng.lib: $(OBJS1) $(OBJS2) $(OBJS3)
+        del libpng.lib
+	lib libpng $(OBJS1);
+	lib libpng $(OBJS2);
+	lib libpng $(OBJS3);
+
+pngtest.exe: pngtest.obj libpng.lib 
+	$(LD) $(LDFLAGS) pngtest.obj,,,libpng.lib ..\zlib\zlib.lib ;
+
+test: pngtest.exe
+	pngtest
+
+# End of makefile for libpng
+
diff --git a/src/png/scripts/makefile.os2 b/src/png/scripts/makefile.os2
new file mode 100644
index 0000000000..a3ff2dcac6
--- /dev/null
+++ b/src/png/scripts/makefile.os2
@@ -0,0 +1,69 @@
+# makefile for libpng on OS/2 with gcc
+# For conditions of distribution and use, see copyright notice in png.h
+
+# Related files: pngos2.def
+
+CC=gcc -Zomf -s
+
+# Where the zlib library and include files are located
+ZLIBLIB=../zlib
+ZLIBINC=../zlib
+
+WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
+         -Wmissing-declarations -Wtraditional -Wcast-align \
+         -Wstrict-prototypes -Wmissing-prototypes #-Wconversion
+CFLAGS=-I$(ZLIBINC) -Wall -O6 -funroll-loops -malign-loops=2 \
+       -malign-functions=2 #$(WARNMORE) -g -DPNG_DEBUG=5
+LDFLAGS=-L. -L$(ZLIBLIB) -lpng -lzdll -Zcrtdll
+AR=emxomfar
+
+PNGLIB=png.lib
+IMPLIB=emximp
+SHAREDLIB=png.dll
+SHAREDLIBIMP=pngdll.lib
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+       pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+       pngwtran.o pngmem.o pngerror.o pngpread.o
+
+.SUFFIXES:      .c .o
+
+all: $(PNGLIB) $(SHAREDLIB) $(SHAREDLIBIMP)
+
+$(PNGLIB): $(OBJS)
+	$(AR) rc $@ $(OBJS)
+
+$(SHAREDLIB): $(OBJS) pngos2.def
+	$(CC) $(LDFLAGS) -Zdll -o $@ $^
+
+$(SHAREDLIBIMP): pngos2.def
+	$(IMPLIB) -o $@ $^
+
+pngtest.exe: pngtest.o png.dll pngdll.lib
+	$(CC) -o $@ $(CFLAGS) $< $(LDFLAGS)
+
+test: pngtest.exe
+	./pngtest.exe
+
+clean:
+	rm -f *.o $(PNGLIB) png.dll pngdll.lib pngtest.exe pngout.png
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o png.pic.o: png.h pngconf.h
+pngerror.o pngerror.pic.o: png.h pngconf.h
+pngrio.o pngrio.pic.o: png.h pngconf.h
+pngwio.o pngwio.pic.o: png.h pngconf.h
+pngmem.o pngmem.pic.o: png.h pngconf.h
+pngset.o pngset.pic.o: png.h pngconf.h
+pngget.o pngget.pic.o: png.h pngconf.h
+pngread.o pngread.pic.o: png.h pngconf.h
+pngrtran.o pngrtran.pic.o: png.h pngconf.h
+pngrutil.o pngrutil.pic.o: png.h pngconf.h
+pngtrans.o pngtrans.pic.o: png.h pngconf.h
+pngwrite.o pngwrite.pic.o: png.h pngconf.h
+pngwtran.o pngwtran.pic.o: png.h pngconf.h
+pngwutil.o pngwutil.pic.o: png.h pngconf.h
+pngpread.o pngpread.pic.o: png.h pngconf.h
+
+pngtest.o: png.h pngconf.h
diff --git a/src/png/scripts/makefile.s2x b/src/png/scripts/makefile.s2x
new file mode 100644
index 0000000000..163f363826
--- /dev/null
+++ b/src/png/scripts/makefile.s2x
@@ -0,0 +1,104 @@
+# makefile for libpng on Solaris 2.x with gcc
+# Contributed by William L. Sebok, based on makefile.lnx
+# Copyright (C) 1996, 1997 Andreas Dilger
+# Copyright (C) 1998 Greg Roelofs
+# For conditions of distribution and use, see copyright notice in png.h
+
+CC=gcc
+
+# Where the zlib library and include files are located
+# Changing these to ../zlib poses a security risk.  If you want
+# to have zlib in an adjacent directory, specify the full path instead of "..".
+#ZLIBLIB=../zlib
+#ZLIBINC=../zlib
+
+ZLIBLIB=/usr/local/lib
+ZLIBINC=/usr/local/include
+
+
+WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
+         -Wmissing-declarations -Wtraditional -Wcast-align \
+         -Wstrict-prototypes -Wmissing-prototypes #-Wconversion
+CFLAGS=-I$(ZLIBINC) -Wall -O3 \
+      #$(WARNMORE) -g -DPNG_DEBUG=5
+LDFLAGS=-L. -R. -L$(ZLIBLIB) -R$(ZLIBLIB) -lpng -lz -lm
+
+#RANLIB=ranlib
+RANLIB=echo
+
+# read libpng.txt or png.h to see why PNGMAJ is 2.  You should not
+# have to change it.
+PNGMAJ = 2
+PNGMIN = 1.0
+PNGVER = $(PNGMAJ).$(PNGMIN)
+
+# where make install puts libpng.a, libpng.so*, and png.h
+prefix=/usr/local
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+       pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+       pngwtran.o pngmem.o pngerror.o pngpread.o
+
+OBJSDLL = $(OBJS:.o=.pic.o)
+
+.SUFFIXES:      .c .o .pic.o
+
+.c.pic.o:
+	$(CC) -c $(CFLAGS) -fPIC -o $@ $*.c
+
+all: libpng.a libpng.so pngtest
+
+libpng.a: $(OBJS)
+	ar rc $@ $(OBJS)
+	$(RANLIB) $@
+
+libpng.so: libpng.so.$(PNGMAJ)
+	ln -sf libpng.so.$(PNGMAJ) libpng.so
+
+libpng.so.$(PNGMAJ): libpng.so.$(PNGVER)
+	ln -sf libpng.so.$(PNGVER) libpng.so.$(PNGMAJ)
+
+libpng.so.$(PNGVER): $(OBJSDLL)
+	$(LD) -G -L$(ZLIBLIB) -R$(ZLIBLIB) -h libpng.so.$(PNGMAJ) \
+	 -o libpng.so.$(PNGVER) $(OBJSDLL) -lz
+
+pngtest: pngtest.o libpng.so
+	$(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+
+test: pngtest
+	./pngtest
+
+install: libpng.a libpng.so.$(PNGVER)
+	-@mkdir $(INCPATH) $(LIBPATH)
+	cp png.h pngconf.h $(INCPATH)
+	chmod 644 $(INCPATH)/png.h $(INCPATH)/pngconf.h
+	cp libpng.a libpng.so.$(PNGVER) $(LIBPATH)
+	chmod 755 $(LIBPATH)/libpng.so.$(PNGVER)
+	-@/bin/rm -f $(LIBPATH)/libpng.so.$(PNGMAJ) $(LIBPATH)/libpng.so
+	(cd $(LIBPATH); ln -sf libpng.so.$(PNGVER) libpng.so.$(PNGMAJ); \
+	 ln -sf libpng.so.$(PNGMAJ) libpng.so)
+
+clean:
+	/bin/rm -f *.o libpng.a libpng.so* pngtest pngout.png
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o png.pic.o: png.h pngconf.h
+pngerror.o pngerror.pic.o: png.h pngconf.h
+pngrio.o pngrio.pic.o: png.h pngconf.h
+pngwio.o pngwio.pic.o: png.h pngconf.h
+pngmem.o pngmem.pic.o: png.h pngconf.h
+pngset.o pngset.pic.o: png.h pngconf.h
+pngget.o pngget.pic.o: png.h pngconf.h
+pngread.o pngread.pic.o: png.h pngconf.h
+pngrtran.o pngrtran.pic.o: png.h pngconf.h
+pngrutil.o pngrutil.pic.o: png.h pngconf.h
+pngtrans.o pngtrans.pic.o: png.h pngconf.h
+pngwrite.o pngwrite.pic.o: png.h pngconf.h
+pngwtran.o pngwtran.pic.o: png.h pngconf.h
+pngwutil.o pngwutil.pic.o: png.h pngconf.h
+pngpread.o pngpread.pic.o: png.h pngconf.h
+
+pngtest.o: png.h pngconf.h
diff --git a/src/png/scripts/makefile.sgi b/src/png/scripts/makefile.sgi
new file mode 100644
index 0000000000..965cf91fd0
--- /dev/null
+++ b/src/png/scripts/makefile.sgi
@@ -0,0 +1,69 @@
+# makefile for libpng
+# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
+# For conditions of distribution and use, see copyright notice in png.h
+
+# Where the zlib library and include files are located
+#ZLIBLIB=/usr/local/lib
+#ZLIBINC=/usr/local/include
+ZLIBLIB=../zlib
+ZLIBINC=../zlib
+
+CC=cc
+
+CFLAGS=-I$(ZLIBINC) -O -fullwarn # -g -DPNG_DEBUG=1
+LDFLAGS=-L. -L$(ZLIBLIB) -lpng -lz -lm
+
+RANLIB=echo
+#RANLIB=ranlib
+
+# where make install puts libpng.a and png.h
+prefix=/usr/local
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+	pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+	pngwtran.o pngmem.o pngerror.o pngpread.o
+
+all: libpng.a pngtest
+
+libpng.a: $(OBJS)
+	ar rc $@  $(OBJS)
+	$(RANLIB) $@
+
+pngtest: pngtest.o libpng.a
+	$(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+
+test: pngtest
+	./pngtest
+
+install: libpng.a
+	-@mkdir $(prefix)/include
+	-@mkdir $(prefix)/lib
+	cp png.h $(prefix)/include
+	cp pngconf.h $(prefix)/include
+	chmod 644 $(prefix)/include/png.h
+	chmod 644 $(prefix)/include/pngconf.h
+	cp libpng.a $(prefix)/lib
+	chmod 644 $(prefix)/lib/libpng.a
+
+clean:
+	rm -f *.o libpng.a pngtest pngout.png
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o: png.h pngconf.h
+pngerror.o: png.h pngconf.h
+pngrio.o: png.h pngconf.h
+pngwio.o: png.h pngconf.h
+pngmem.o: png.h pngconf.h
+pngset.o: png.h pngconf.h
+pngget.o: png.h pngconf.h
+pngread.o: png.h pngconf.h
+pngrtran.o: png.h pngconf.h
+pngrutil.o: png.h pngconf.h
+pngtest.o: png.h pngconf.h
+pngtrans.o: png.h pngconf.h
+pngwrite.o: png.h pngconf.h
+pngwtran.o: png.h pngconf.h
+pngwutil.o: png.h pngconf.h
+pngpread.o: png.h pngconf.h
+
diff --git a/src/png/scripts/makefile.std b/src/png/scripts/makefile.std
new file mode 100644
index 0000000000..7cc605990a
--- /dev/null
+++ b/src/png/scripts/makefile.std
@@ -0,0 +1,68 @@
+# makefile for libpng
+# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
+# For conditions of distribution and use, see copyright notice in png.h
+
+# Where the zlib library and include files are located
+#ZLIBLIB=/usr/local/lib
+#ZLIBINC=/usr/local/include
+ZLIBLIB=../zlib
+ZLIBINC=../zlib
+
+CC=cc
+CFLAGS=-I$(ZLIBINC) -O # -g -DPNG_DEBUG=1
+LDFLAGS=-L. -L$(ZLIBLIB) -lpng -lz -lm
+
+#RANLIB=echo
+RANLIB=ranlib
+
+# where make install puts libpng.a and png.h
+prefix=/usr/local
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+	pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+	pngwtran.o pngmem.o pngerror.o pngpread.o
+
+all: libpng.a pngtest
+
+libpng.a: $(OBJS)
+	ar rc $@  $(OBJS)
+	$(RANLIB) $@
+
+pngtest: pngtest.o libpng.a
+	$(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+
+test: pngtest
+	./pngtest
+
+install: libpng.a
+	-@mkdir $(prefix)/include
+	-@mkdir $(prefix)/lib
+	cp png.h $(prefix)/include
+	cp pngconf.h $(prefix)/include
+	chmod 644 $(prefix)/include/png.h
+	chmod 644 $(prefix)/include/pngconf.h
+	cp libpng.a $(prefix)/lib
+	chmod 644 $(prefix)/lib/libpng.a
+
+clean:
+	rm -f *.o libpng.a pngtest pngout.png
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o: png.h pngconf.h
+pngerror.o: png.h pngconf.h
+pngrio.o: png.h pngconf.h
+pngwio.o: png.h pngconf.h
+pngmem.o: png.h pngconf.h
+pngset.o: png.h pngconf.h
+pngget.o: png.h pngconf.h
+pngread.o: png.h pngconf.h
+pngrtran.o: png.h pngconf.h
+pngrutil.o: png.h pngconf.h
+pngtest.o: png.h pngconf.h
+pngtrans.o: png.h pngconf.h
+pngwrite.o: png.h pngconf.h
+pngwtran.o: png.h pngconf.h
+pngwutil.o: png.h pngconf.h
+pngpread.o: png.h pngconf.h
+
diff --git a/src/png/scripts/makefile.sun b/src/png/scripts/makefile.sun
new file mode 100644
index 0000000000..975ca17232
--- /dev/null
+++ b/src/png/scripts/makefile.sun
@@ -0,0 +1,72 @@
+# makefile for libpng
+# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
+# For conditions of distribution and use, see copyright notice in png.h
+
+# Where the zlib library and include files are located
+#ZLIBLIB=/usr/local/lib
+#ZLIBINC=/usr/local/include
+ZLIBLIB=../zlib
+ZLIBINC=../zlib
+
+
+WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow -Wconversion \
+         -Wmissing-declarations -Wtraditional -Wcast-align \
+         -Wstrict-prototypes -Wmissing-prototypes
+CC=gcc
+CFLAGS=-I$(ZLIBINC) -O $(WARNMORE) -DPNG_DEBUG=4
+LDFLAGS=-L. -L$(ZLIBLIB) -lpng -lz -lm
+
+RANLIB=ranlib
+#RANLIB=echo
+
+# where make install puts libpng.a and png.h
+prefix=/usr/local
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+	pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+	pngwtran.o pngmem.o pngerror.o pngpread.o
+
+all: libpng.a pngtest
+
+libpng.a: $(OBJS)
+	ar rc $@  $(OBJS)
+	$(RANLIB) $@
+
+pngtest: pngtest.o libpng.a
+	$(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+
+test: pngtest
+	./pngtest
+
+install: libpng.a
+	-@mkdir $(prefix)/include
+	-@mkdir $(prefix)/lib
+	cp png.h $(prefix)/include
+	cp pngconf.h $(prefix)/include
+	chmod 644 $(prefix)/include/png.h
+	chmod 644 $(prefix)/include/pngconf.h
+	cp libpng.a $(prefix)/lib
+	chmod 644 $(prefix)/lib/libpng.a
+
+clean:
+	rm -f *.o libpng.a pngtest pngout.png
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o: png.h pngconf.h
+pngerror.o: png.h pngconf.h
+pngrio.o: png.h pngconf.h
+pngwio.o: png.h pngconf.h
+pngmem.o: png.h pngconf.h
+pngset.o: png.h pngconf.h
+pngget.o: png.h pngconf.h
+pngread.o: png.h pngconf.h
+pngrtran.o: png.h pngconf.h
+pngrutil.o: png.h pngconf.h
+pngtest.o: png.h pngconf.h
+pngtrans.o: png.h pngconf.h
+pngwrite.o: png.h pngconf.h
+pngwtran.o: png.h pngconf.h
+pngwutil.o: png.h pngconf.h
+pngpread.o: png.h pngconf.h
+
diff --git a/src/png/scripts/makefile.tc3 b/src/png/scripts/makefile.tc3
new file mode 100644
index 0000000000..6f8f36667f
--- /dev/null
+++ b/src/png/scripts/makefile.tc3
@@ -0,0 +1,82 @@
+# Makefile for libpng
+# TurboC++ 3.0 (Note: All modules are compiled in C mode)
+
+# To use, do "make -fmakefile.tc3"
+
+# ------------- Turbo C++ 3.0 -------------
+MODEL=-ml
+CFLAGS=-O2 -Z $(MODEL) -I..\zlib
+CC=tcc
+LD=tcc
+LIB=tlib
+LDFLAGS=$(MODEL) -L..\zlib
+O=.obj
+E=.exe
+
+# variables
+OBJS1 = png$(O) pngset$(O) pngget$(O) pngrutil$(O) pngtrans$(O) pngwutil$(O)
+OBJS2 = pngmem$(O) pngpread$(O) pngread$(O) pngerror$(O) pngwrite$(O)
+OBJS3 = pngrtran$(O) pngwtran$(O) pngrio$(O) pngwio$(O)
+OBJSL1 = +png$(O) +pngset$(O) +pngget$(O) +pngrutil$(O) +pngtrans$(O)
+OBJSL2 = +pngwutil$(O) +pngmem$(O) +pngpread$(O) +pngread$(O) +pngerror$(O)
+OBJSL3 = +pngwrite$(O) +pngrtran$(O) +pngwtran$(O) +pngrio$(O) +pngwio$(O)
+
+all: libpng.lib pngtest.exe
+
+png$(O): png.h pngconf.h
+		  $(CC) -c $(CFLAGS) $*.c
+
+pngset$(O): png.h pngconf.h
+		  $(CC) -c $(CFLAGS) $*.c
+
+pngget$(O): png.h pngconf.h
+		  $(CC) -c $(CFLAGS) $*.c
+
+pngread$(O): png.h pngconf.h
+		  $(CC) -c $(CFLAGS) $*.c
+
+pngpread$(O): png.h pngconf.h
+		  $(CC) -c $(CFLAGS) $*.c
+
+pngrtran$(O): png.h pngconf.h
+		  $(CC) -c $(CFLAGS) $*.c
+
+pngrutil$(O): png.h pngconf.h
+		  $(CC) -c $(CFLAGS) $*.c
+
+pngerror$(O): png.h pngconf.h
+        $(CC) -c $(CFLAGS) $*.c
+
+pngmem$(O): png.h pngconf.h
+        $(CC) -c $(CFLAGS) $*.c
+
+pngrio$(O): png.h pngconf.h
+        $(CC) -c $(CFLAGS) $*.c
+
+pngwio$(O): png.h pngconf.h
+        $(CC) -c $(CFLAGS) $*.c
+
+pngtest$(O): png.h pngconf.h
+        $(CC) -c $(CFLAGS) $*.c
+
+pngtrans$(O): png.h pngconf.h
+        $(CC) -c $(CFLAGS) $*.c
+
+pngwrite$(O): png.h pngconf.h
+        $(CC) -c $(CFLAGS) $*.c
+
+pngwtran$(O): png.h pngconf.h
+        $(CC) -c $(CFLAGS) $*.c
+
+pngwutil$(O): png.h pngconf.h
+        $(CC) -c $(CFLAGS) $*.c
+
+libpng.lib: $(OBJS1) $(OBJS2) $(OBJS3)
+        $(LIB) libpng +$(OBJSL1)
+        $(LIB) libpng +$(OBJSL2)
+        $(LIB) libpng +$(OBJSL3)
+
+pngtest$(E): pngtest$(O) libpng.lib
+        $(CC) $(LDFLAGS) pngtest.obj libpng.lib zlib.lib
+
+# End of makefile for libpng
diff --git a/src/png/scripts/makefile.wat b/src/png/scripts/makefile.wat
new file mode 100644
index 0000000000..a715acbcdc
--- /dev/null
+++ b/src/png/scripts/makefile.wat
@@ -0,0 +1,88 @@
+# Makefile for libpng
+# Watcom 10a and later 32-bit protected mode flat memory model
+
+# Adapted by Pawel Mrochen, based on makefile.msc
+# For conditions of distribution and use, see copyright notice in png.h
+# Assumes that zlib.lib, zconf.h, and zlib.h have been copied to ..\zlib
+
+# To use, do "wmake -f makefile.wat"
+
+# ------------- Watcom 10a and later -------------
+MODEL=-mf
+CFLAGS= $(MODEL) -fpi87 -fp5 -5r -oaeilmnrt -s -zp4 -i=..\zlib
+CC=wcc386
+LD=wcl386
+LIB=wlib -b -c
+LDFLAGS=
+O=.obj
+
+#uncomment next to put error messages in a file
+#ERRFILE= >> pngerrs
+
+# variables
+OBJS1 = png$(O) pngset$(O) pngget$(O) pngrutil$(O) pngtrans$(O) pngwutil$(O)
+OBJS2 = pngmem$(O) pngpread$(O) pngread$(O) pngerror$(O) pngwrite$(O)
+OBJS3 = pngrtran$(O) pngwtran$(O) pngrio$(O) pngwio$(O)
+
+all: test
+
+png$(O): png.h pngconf.h
+	$(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngset$(O): png.h pngconf.h
+	$(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngget$(O): png.h pngconf.h
+	$(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngread$(O): png.h pngconf.h
+	$(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngpread$(O): png.h pngconf.h
+	$(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngrtran$(O): png.h pngconf.h
+	$(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngrutil$(O): png.h pngconf.h
+	$(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngerror$(O): png.h pngconf.h
+	$(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngmem$(O): png.h pngconf.h
+	$(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngrio$(O): png.h pngconf.h
+	$(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngwio$(O): png.h pngconf.h
+	$(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngtest$(O): png.h pngconf.h
+	$(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngtrans$(O): png.h pngconf.h
+	$(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngwrite$(O): png.h pngconf.h
+	$(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngwtran$(O): png.h pngconf.h
+	$(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngwutil$(O): png.h pngconf.h
+	$(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+libpng.lib: $(OBJS1) $(OBJS2) $(OBJS3)
+	$(LIB) -n libpng.lib +$(OBJS1)
+	$(LIB) libpng.lib +$(OBJS2)
+	$(LIB) libpng.lib +$(OBJS3)
+
+pngtest.exe: pngtest.obj libpng.lib
+	$(LD) $(LDFLAGS) pngtest.obj libpng.lib ..\zlib\zlib.lib
+
+test: pngtest.exe
+	pngtest
+
+# End of makefile for libpng
diff --git a/src/png/scripts/makevms.com b/src/png/scripts/makevms.com
new file mode 100644
index 0000000000..15f305a606
--- /dev/null
+++ b/src/png/scripts/makevms.com
@@ -0,0 +1,125 @@
+$! make libpng under VMS
+$!
+$!
+$! Look for the compiler used
+$!
+$ zlibsrc = "[-.zlib]"
+$ ccopt="/include=''zlibsrc'"
+$ if f$getsyi("HW_MODEL").ge.1024
+$ then
+$  ccopt = "/prefix=all"+ccopt
+$  comp  = "__decc__=1"
+$  if f$trnlnm("SYS").eqs."" then define sys sys$library:
+$ else
+$  if f$search("SYS$SYSTEM:DECC$COMPILER.EXE").eqs.""
+$   then
+$    if f$trnlnm("SYS").eqs."" then define sys sys$library:
+$    if f$search("SYS$SYSTEM:VAXC.EXE").eqs.""
+$     then
+$      comp  = "__gcc__=1"
+$      CC :== GCC
+$     else
+$      comp = "__vaxc__=1"
+$     endif
+$   else
+$    if f$trnlnm("SYS").eqs."" then define sys decc$library_include:
+$    ccopt = "/decc/prefix=all"+ccopt
+$    comp  = "__decc__=1"
+$  endif
+$ endif
+$!
+$! Build the thing plain or with mms
+$!
+$ write sys$output "Compiling Libpng sources ..."
+$ if f$search("SYS$SYSTEM:MMS.EXE").eqs.""
+$  then
+$   dele pngtest.obj;*
+$   CALL MAKE png.OBJ "cc ''CCOPT' png" -
+                png.c png.h pngconf.h   
+$   CALL MAKE pngpread.OBJ "cc ''CCOPT' pngpread" -
+					 pngpread.c png.h pngconf.h
+$   CALL MAKE pngset.OBJ "cc ''CCOPT' pngset" -
+                pngset.c png.h pngconf.h
+$   CALL MAKE pngget.OBJ "cc ''CCOPT' pngget" -
+                pngget.c png.h pngconf.h
+$   CALL MAKE pngread.OBJ "cc ''CCOPT' pngread" -
+                pngread.c png.h pngconf.h
+$   CALL MAKE pngpread.OBJ "cc ''CCOPT' pngpread" -
+					 pngpread.c png.h pngconf.h
+$   CALL MAKE pngrtran.OBJ "cc ''CCOPT' pngrtran" -
+                pngrtran.c png.h pngconf.h
+$   CALL MAKE pngrutil.OBJ "cc ''CCOPT' pngrutil" -
+                pngrutil.c png.h pngconf.h
+$   CALL MAKE pngerror.OBJ "cc ''CCOPT' pngerror" -
+                pngerror.c png.h pngconf.h
+$   CALL MAKE pngmem.OBJ "cc ''CCOPT' pngmem" -
+                pngmem.c png.h pngconf.h
+$   CALL MAKE pngrio.OBJ "cc ''CCOPT' pngrio" -
+                pngrio.c png.h pngconf.h
+$   CALL MAKE pngwio.OBJ "cc ''CCOPT' pngwio" -
+                pngwio.c png.h pngconf.h
+$   CALL MAKE pngtrans.OBJ "cc ''CCOPT' pngtrans" -
+                pngtrans.c png.h pngconf.h
+$   CALL MAKE pngwrite.OBJ "cc ''CCOPT' pngwrite" -
+                pngwrite.c png.h pngconf.h
+$   CALL MAKE pngwtran.OBJ "cc ''CCOPT' pngwtran" -
+                pngwtran.c png.h pngconf.h
+$   CALL MAKE pngwutil.OBJ "cc ''CCOPT' pngwutil" -
+                pngwutil.c png.h pngconf.h
+$   write sys$output "Building Libpng ..."
+$   CALL MAKE libpng.OLB "lib/crea libpng.olb *.obj" *.OBJ
+$   write sys$output "Building pngtest..."
+$   CALL MAKE pngtest.OBJ "cc ''CCOPT' pngtest" -
+                pngtest.c png.h pngconf.h
+$   call make pngtest.exe - 
+                "LINK pngtest,libpng.olb/lib,''zlibsrc'libgz.olb/lib" - 
+                pngtest.obj libpng.olb
+$   write sys$output "Testing Libpng..."
+$   run pngtest
+$  else
+$   mms/macro=('comp',zlibsrc='zlibsrc')
+$  endif
+$ write sys$output "Libpng build completed"
+$ exit
+$!
+$!
+$MAKE: SUBROUTINE   !SUBROUTINE TO CHECK DEPENDENCIES
+$ V = 'F$Verify(0)
+$! P1 = What we are trying to make
+$! P2 = Command to make it
+$! P3 - P8  What it depends on
+$
+$ If F$Search(P1) .Eqs. "" Then Goto Makeit
+$ Time = F$CvTime(F$File(P1,"RDT"))
+$arg=3
+$Loop:
+$       Argument = P'arg
+$       If Argument .Eqs. "" Then Goto Exit
+$       El=0
+$Loop2:
+$       File = F$Element(El," ",Argument)
+$       If File .Eqs. " " Then Goto Endl
+$       AFile = ""
+$Loop3:
+$       OFile = AFile
+$       AFile = F$Search(File)
+$       If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl
+$       If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit
+$       Goto Loop3
+$NextEL:
+$       El = El + 1
+$       Goto Loop2
+$EndL:
+$ arg=arg+1
+$ If arg .Le. 8 Then Goto Loop
+$ Goto Exit
+$
+$Makeit:
+$ VV=F$VERIFY(0)
+$ write sys$output P2
+$ 'P2
+$ VV='F$Verify(VV)
+$Exit:
+$ If V Then Set Verify
+$ENDSUBROUTINE
+
diff --git a/src/png/scripts/pngos2.def b/src/png/scripts/pngos2.def
new file mode 100644
index 0000000000..ba2d3e3d38
--- /dev/null
+++ b/src/png/scripts/pngos2.def
@@ -0,0 +1,286 @@
+;----------------------------------------
+; PNGLIB module definition file for OS/2
+;----------------------------------------
+
+LIBRARY		PNG
+DESCRIPTION	"PNG image compression library for OS/2"
+CODE		PRELOAD MOVEABLE DISCARDABLE
+DATA		PRELOAD MOVEABLE MULTIPLE
+
+EXPORTS
+  png_set_sig_bytes
+  png_sig_cmp
+  png_check_sig
+  png_create_read_struct
+  png_create_write_struct
+  png_write_chunk
+  png_write_chunk_start
+  png_write_chunk_data
+  png_write_chunk_end
+  png_create_info_struct
+  png_info_init
+  png_write_info
+  png_read_info
+  png_convert_to_rfc1123
+  png_convert_from_struct_tm
+  png_convert_from_time_t
+  png_set_expand
+  png_set_bgr
+  png_set_gray_to_rgb
+; png_set_rgb_to_gray
+  png_build_grayscale_palette
+  png_set_strip_alpha
+  png_set_swap_alpha
+  png_set_invert_alpha
+  png_set_filler
+  png_set_swap
+  png_set_packing
+  png_set_packswap
+  png_set_shift
+  png_set_interlace_handling
+  png_set_invert_mono
+  png_set_background
+  png_set_strip_16
+  png_set_dither
+  png_set_gamma
+  png_set_flush
+  png_write_flush
+  png_start_read_image
+  png_read_update_info
+  png_read_rows
+  png_read_row
+  png_read_image
+  png_write_row
+  png_write_rows
+  png_write_image
+  png_write_end
+  png_read_end
+  png_destroy_info_struct
+  png_destroy_read_struct
+  png_read_destroy
+  png_destroy_write_struct
+; png_write_destroy_info
+  png_write_destroy
+  png_set_crc_action
+  png_set_filter
+  png_set_filter_heuristics
+  png_set_compression_level
+  png_set_compression_mem_level
+  png_set_compression_strategy
+  png_set_compression_window_bits
+  png_set_compression_method
+  png_init_io
+  png_set_error_fn
+  png_get_error_ptr
+  png_set_write_fn
+  png_set_read_fn
+  png_set_write_status_fn
+  png_set_read_status_fn
+  png_get_io_ptr
+  png_set_progressive_read_fn
+  png_set_read_status_fn
+  png_set_read_user_transform_fn
+  png_set_write_status_fn
+  png_set_write_user_transform_fn
+  png_get_progressive_ptr
+  png_process_data
+  png_progressive_combine_row
+  png_malloc
+  png_free
+  png_memcpy_check
+  png_memset_check
+; png_debug_malloc
+; png_debug_free
+; png_far_to_near
+  png_error
+  png_chunk_error
+  png_warning
+  png_chunk_warning
+  png_get_valid
+  png_get_rowbytes
+  png_get_channels
+  png_get_image_width
+  png_get_image_height
+  png_get_bit_depth
+  png_get_color_type
+  png_get_filter_type
+  png_get_interlace_type
+  png_get_compression_type
+  png_get_pixels_per_meter
+  png_get_pixel_aspect_ratio
+  png_get_x_offset_pixels
+  png_get_y_offset_pixels
+  png_get_x_offset_microns
+  png_get_y_offset_microns
+  png_get_signature
+  png_get_bKGD
+  png_set_bKGD
+  png_get_cHRM
+  png_set_cHRM
+  png_get_gAMA
+  png_set_gAMA
+  png_get_hIST
+  png_set_hIST
+  png_get_IHDR
+  png_set_IHDR
+  png_get_oFFs
+  png_set_oFFs
+  png_get_pCAL
+  png_set_pCAL
+  png_get_pHYs
+  png_set_pHYs
+  png_get_PLTE
+  png_set_PLTE
+  png_get_sBIT
+  png_set_sBIT
+  png_get_sRGB
+  png_set_sRGB
+  png_set_sRGB_gAMA_and_cHRM
+  png_get_text
+  png_set_text
+  png_get_tIME
+  png_set_tIME
+  png_get_tRNS
+  png_set_tRNS
+
+  png_create_struct
+  png_destroy_struct
+  png_info_destroy
+  png_zalloc
+  png_zfree
+  png_reset_crc
+  png_write_data
+  png_read_data
+  png_crc_read
+  png_crc_finish
+  png_crc_error
+  png_calculate_crc
+  png_flush
+  png_save_uint_32
+  png_save_int_32
+  png_save_uint_16
+  png_write_sig
+  png_write_IHDR
+  png_write_PLTE
+  png_write_IDAT
+  png_write_IEND
+  png_write_gAMA
+  png_write_sBIT
+  png_write_cHRM
+  png_write_sRGB
+  png_write_tRNS
+  png_write_bKGD
+  png_write_hIST
+  png_check_keyword
+  png_write_tEXt
+  png_write_zTXt
+  png_write_oFFs
+  png_write_pCAL
+  png_write_pHYs
+  png_write_tIME
+  png_write_finish_row
+  png_write_start_row
+  png_build_gamma_table
+  png_combine_row
+  png_do_read_interlace
+  png_do_write_interlace
+  png_read_filter_row
+  png_write_find_filter
+  png_write_filtered_row
+  png_read_finish_row
+  png_read_start_row
+  png_read_transform_info
+  png_do_read_filler
+  png_do_read_swap_alpha
+  png_do_write_swap_alpha
+  png_do_read_invert_alpha
+  png_do_write_invert_alpha
+  png_do_strip_filler
+  png_do_swap
+  png_do_packswap
+; png_do_rgb_to_gray
+  png_do_gray_to_rgb
+  png_do_unpack
+  png_do_unshift
+  png_do_invert
+  png_do_chop
+  png_do_dither
+; png_correct_palette
+  png_do_bgr
+  png_do_pack
+  png_do_shift
+  png_do_background
+  png_do_gamma
+  png_do_expand_palette
+  png_do_expand
+  png_handle_IHDR
+  png_handle_PLTE
+  png_handle_IEND
+  png_handle_gAMA
+  png_handle_sBIT
+  png_handle_cHRM
+  png_handle_sRGB
+  png_handle_tRNS
+  png_handle_bKGD
+  png_handle_hIST
+  png_handle_oFFs
+  png_handle_pCAL
+  png_handle_pHYs
+  png_handle_tIME
+  png_handle_tEXt
+  png_handle_zTXt
+  png_handle_unknown
+  png_check_chunk_name
+  png_do_read_transformations
+  png_do_write_transformations
+  png_init_read_transformations
+  png_push_read_chunk
+  png_push_read_sig
+; png_push_check_crc
+  png_push_crc_skip
+  png_push_crc_finish
+  png_push_fill_buffer
+  png_push_save_buffer
+  png_push_restore_buffer
+  png_push_read_IDAT
+  png_process_IDAT_data
+  png_push_process_row
+  png_push_handle_unknown
+  png_push_have_info
+  png_push_have_end
+  png_push_have_row
+; png_push_read_end
+  png_process_some_data
+  png_read_push_finish_row
+  png_push_handle_tEXt
+  png_push_read_tEXt
+  png_push_handle_zTXt
+  png_push_read_zTXt
+
+  png_libpng_ver
+  png_pass_start
+  png_pass_inc
+  png_pass_ystart
+  png_pass_yinc
+  png_pass_mask
+  png_pass_dsp_mask
+; png_pass_width
+; png_pass_height
+
+  png_IHDR
+  png_IDAT
+  png_IEND
+  png_PLTE
+  png_bKGD
+  png_cHRM
+  png_gAMA
+  png_hIST
+  png_oFFs
+  png_pCAL
+  png_pHYs
+  png_sBIT
+  png_sRGB
+  png_tEXt
+  png_tIME
+  png_tRNS
+  png_zTXt
diff --git a/src/png/scripts/smakefile.ppc b/src/png/scripts/smakefile.ppc
new file mode 100644
index 0000000000..fa3cad44b1
--- /dev/null
+++ b/src/png/scripts/smakefile.ppc
@@ -0,0 +1,29 @@
+# Amiga powerUP (TM) Makefile
+# makefile for libpng and SAS C V6.58/7.00 PPC compiler
+# Copyright (C) 1998 by Andreas R. Kleinert
+
+CC       = scppc
+CFLAGS   = NOSTKCHK NOSINT OPTIMIZE OPTGO OPTPEEP OPTINLOCAL OPTINL IDIR /zlib \
+           OPTLOOP OPTRDEP=8 OPTDEP=8 OPTCOMP=8
+LIBNAME  = libpng.a
+AR       = ppc-amigaos-ar
+AR_FLAGS = cr
+RANLIB   = ppc-amigaos-ranlib
+LDFLAGS  = -r -o
+LDLIBS   =  ../zlib/libzip.a LIB:scppc.a
+LN       = ppc-amigaos-ld
+RM       = delete quiet
+MKDIR    = makedir
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o pngread.o \
+pngerror.o pngpread.o pngwrite.o pngrtran.o pngwtran.o pngrio.o pngwio.o pngmem.o
+
+all: $(LIBNAME) pngtest
+
+$(LIBNAME): $(OBJS)
+            $(AR) $(AR_FLAGS) $@ $(OBJS)
+            $(RANLIB) $@
+
+pngtest: pngtest.o $(LIBNAME)
+        $(LN) $(LDFLAGS) pngtest LIB:c_ppc.o pngtest.o $(LIBNAME) $(LDLIBS) \
+LIB:end.o
diff --git a/src/zlib/ChangeLog b/src/zlib/ChangeLog
new file mode 100644
index 0000000000..ae49267ddc
--- /dev/null
+++ b/src/zlib/ChangeLog
@@ -0,0 +1,423 @@
+
+		ChangeLog file for zlib
+
+Changes in 1.1.2 (19 March 98)
+- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant)
+  See http://www.winimage.com/zLibDll/unzip.html
+- preinitialize the inflate tables for fixed codes, to make the code
+  completely thread safe (Mark)
+- some simplifications and slight speed-up to the inflate code (Mark)
+- fix gzeof on non-compressed files (Allan Schrum)
+- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs)
+- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn)
+- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny)
+- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori)
+- do not wrap extern "C" around system includes (Tom Lane)
+- mention zlib binding for TCL in README (Andreas Kupries)
+- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert)
+- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson)
+- allow "configure --prefix $HOME" (Tim Mooney)
+- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson)
+- move Makefile.sas to amiga/Makefile.sas
+
+Changes in 1.1.1 (27 Feb 98)
+- fix macros _tr_tally_* in deflate.h for debug mode  (Glenn Randers-Pehrson)
+- remove block truncation heuristic which had very marginal effect for zlib
+  (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the
+  compression ratio on some files. This also allows inlining _tr_tally for
+  matches in deflate_slow.
+- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier)
+
+Changes in 1.1.0 (24 Feb 98)
+- do not return STREAM_END prematurely in inflate (John Bowler)
+- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler)
+- compile with -DFASTEST to get compression code optimized for speed only
+- in minigzip, try mmap'ing the input file first (Miguel Albrecht)
+- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain
+  on Sun but significant on HP)
+
+- add a pointer to experimental unzip library in README (Gilles Vollant)
+- initialize variable gcc in configure (Chris Herborth)
+
+Changes in 1.0.9 (17 Feb 1998)
+- added gzputs and gzgets functions
+- do not clear eof flag in gzseek (Mark Diekhans)
+- fix gzseek for files in transparent mode (Mark Diekhans)
+- do not assume that vsprintf returns the number of bytes written (Jens Krinke)
+- replace EXPORT with ZEXPORT to avoid conflict with other programs
+- added compress2 in zconf.h, zlib.def, zlib.dnt
+- new asm code from Gilles Vollant in contrib/asm386
+- simplify the inflate code (Mark):
+ . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new()
+ . ZALLOC the length list in inflate_trees_fixed() instead of using stack
+ . ZALLOC the value area for huft_build() instead of using stack
+ . Simplify Z_FINISH check in inflate()
+
+- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8
+- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi)
+- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with
+  the declaration of FAR (Gilles VOllant)
+- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann)
+- read_buf buf parameter of type Bytef* instead of charf*
+- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout)
+- do not redeclare unlink in minigzip.c for WIN32 (John Bowler)
+- fix check for presence of directories in "make install" (Ian Willis)
+
+Changes in 1.0.8 (27 Jan 1998)
+- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant)
+- fix gzgetc and gzputc for big endian systems (Markus Oberhumer)
+- added compress2() to allow setting the compression level
+- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong)
+- use constant arrays for the static trees in trees.c instead of computing
+  them at run time (thanks to Ken Raeburn for this suggestion). To create
+  trees.h, compile with GEN_TREES_H and run "make test".
+- check return code of example in "make test" and display result
+- pass minigzip command line options to file_compress
+- simplifying code of inflateSync to avoid gcc 2.8 bug
+
+- support CC="gcc -Wall" in configure -s (QingLong)
+- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn)
+- fix test for shared library support to avoid compiler warnings
+- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant)
+- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit)
+- do not use fdopen for Metrowerks on Mac (Brad Pettit))
+- add checks for gzputc and gzputc in example.c
+- avoid warnings in gzio.c and deflate.c (Andreas Kleinert)
+- use const for the CRC table (Ken Raeburn)
+- fixed "make uninstall" for shared libraries
+- use Tracev instead of Trace in infblock.c
+- in example.c use correct compressed length for test_sync
+- suppress +vnocompatwarnings in configure for HPUX (not always supported)
+
+Changes in 1.0.7 (20 Jan 1998)
+- fix gzseek which was broken in write mode
+- return error for gzseek to negative absolute position
+- fix configure for Linux (Chun-Chung Chen)
+- increase stack space for MSC (Tim Wegner)
+- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant)
+- define EXPORTVA for gzprintf (Gilles Vollant)
+- added man page zlib.3 (Rick Rodgers)
+- for contrib/untgz, fix makedir() and improve Makefile
+
+- check gzseek in write mode in example.c
+- allocate extra buffer for seeks only if gzseek is actually called
+- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant)
+- add inflateSyncPoint in zconf.h
+- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def
+
+Changes in 1.0.6 (19 Jan 1998)
+- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and
+  gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)
+- Fix a deflate bug occuring only with compression level 0 (thanks to
+  Andy Buckler for finding this one).
+- In minigzip, pass transparently also the first byte for .Z files.
+- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()
+- check Z_FINISH in inflate (thanks to Marc Schluper)
+- Implement deflateCopy (thanks to Adam Costello)
+- make static libraries by default in configure, add --shared option.
+- move MSDOS or Windows specific files to directory msdos
+- suppress the notion of partial flush to simplify the interface
+  (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4)
+- suppress history buffer provided by application to simplify the interface
+  (this feature was not implemented anyway in 1.0.4)
+- next_in and avail_in must be initialized before calling inflateInit or
+  inflateInit2
+- add EXPORT in all exported functions (for Windows DLL)
+- added Makefile.nt (thanks to Stephen Williams)
+- added the unsupported "contrib" directory:
+   contrib/asm386/ by Gilles Vollant <info@winimage.com>
+	386 asm code replacing longest_match().
+   contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
+        A C++ I/O streams interface to the zlib gz* functions
+   contrib/iostream2/  by Tyge Løvset <Tyge.Lovset@cmr.no>
+	Another C++ I/O streams interface
+   contrib/untgz/  by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
+	A very simple tar.gz file extractor using zlib
+   contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
+        How to use compress(), uncompress() and the gz* functions from VB.
+- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression
+  level) in minigzip (thanks to Tom Lane)
+
+- use const for rommable constants in deflate
+- added test for gzseek and gztell in example.c
+- add undocumented function inflateSyncPoint() (hack for Paul Mackerras)
+- add undocumented function zError to convert error code to string
+  (for Tim Smithers)
+- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code.
+- Use default memcpy for Symantec MSDOS compiler.
+- Add EXPORT keyword for check_func (needed for Windows DLL)
+- add current directory to LD_LIBRARY_PATH for "make test"
+- create also a link for libz.so.1
+- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura)
+- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX)
+- added -soname for Linux in configure (Chun-Chung Chen,
+- assign numbers to the exported functions in zlib.def (for Windows DLL)
+- add advice in zlib.h for best usage of deflateSetDictionary
+- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn)
+- allow compilation with ANSI keywords only enabled for TurboC in large model
+- avoid "versionString"[0] (Borland bug)
+- add NEED_DUMMY_RETURN for Borland
+- use variable z_verbose for tracing in debug mode (L. Peter Deutsch).
+- allow compilation with CC
+- defined STDC for OS/2 (David Charlap)	
+- limit external names to 8 chars for MVS (Thomas Lund)
+- in minigzip.c, use static buffers only for 16-bit systems
+- fix suffix check for "minigzip -d foo.gz"
+- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee)
+- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)
+- added makelcc.bat for lcc-win32 (Tom St Denis)
+- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)
+- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
+- check for unistd.h in configure (for off_t)
+- remove useless check parameter in inflate_blocks_free
+- avoid useless assignment of s->check to itself in inflate_blocks_new
+- do not flush twice in gzclose (thanks to Ken Raeburn)
+- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h
+- use NO_ERRNO_H instead of enumeration of operating systems with errno.h
+- work around buggy fclose on pipes for HP/UX
+- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson)
+- fix configure if CC is already equal to gcc
+
+Changes in 1.0.5 (3 Jan 98)
+- Fix inflate to terminate gracefully when fed corrupted or invalid data
+- Use const for rommable constants in inflate
+- Eliminate memory leaks on error conditions in inflate
+- Removed some vestigial code in inflate
+- Update web address in README
+  
+Changes in 1.0.4 (24 Jul 96)
+- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
+  bit, so the decompressor could decompress all the correct data but went
+  on to attempt decompressing extra garbage data. This affected minigzip too.
+- zlibVersion and gzerror return const char* (needed for DLL)
+- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno)
+- use z_error only for DEBUG (avoid problem with DLLs)
+
+Changes in 1.0.3 (2 Jul 96)
+- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS
+  small and medium models; this makes the library incompatible with previous
+  versions for these models. (No effect in large model or on other systems.)
+- return OK instead of BUF_ERROR if previous deflate call returned with
+  avail_out as zero but there is nothing to do
+- added memcmp for non STDC compilers
+- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly)
+- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO)
+- better check for 16-bit mode MSC (avoids problem with Symantec)
+
+Changes in 1.0.2 (23 May 96)
+- added Windows DLL support
+- added a function zlibVersion (for the DLL support)
+- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model)
+- Bytef is define's instead of typedef'd only for Borland C
+- avoid reading uninitialized memory in example.c
+- mention in README that the zlib format is now RFC1950
+- updated Makefile.dj2
+- added algorithm.doc
+
+Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]
+- fix array overlay in deflate.c which sometimes caused bad compressed data
+- fix inflate bug with empty stored block
+- fix MSDOS medium model which was broken in 0.99
+- fix deflateParams() which could generated bad compressed data.
+- Bytef is define'd instead of typedef'ed (work around Borland bug)
+- added an INDEX file
+- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
+  Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas)
+- speed up adler32 for modern machines without auto-increment
+- added -ansi for IRIX in configure
+- static_init_done in trees.c is an int
+- define unlink as delete for VMS
+- fix configure for QNX
+- add configure branch for SCO and HPUX
+- avoid many warnings (unused variables, dead assignments, etc...)
+- no fdopen for BeOS
+- fix the Watcom fix for 32 bit mode (define FAR as empty)
+- removed redefinition of Byte for MKWERKS
+- work around an MWKERKS bug (incorrect merge of all .h files)
+
+Changes in 0.99 (27 Jan 96)
+- allow preset dictionary shared between compressor and decompressor
+- allow compression level 0 (no compression)
+- add deflateParams in zlib.h: allow dynamic change of compression level
+  and compression strategy.
+- test large buffers and deflateParams in example.c
+- add optional "configure" to build zlib as a shared library
+- suppress Makefile.qnx, use configure instead
+- fixed deflate for 64-bit systems (detected on Cray)
+- fixed inflate_blocks for 64-bit systems (detected on Alpha)
+- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2)
+- always return Z_BUF_ERROR when deflate() has nothing to do
+- deflateInit and inflateInit are now macros to allow version checking
+- prefix all global functions and types with z_ with -DZ_PREFIX
+- make falloc completely reentrant (inftrees.c)
+- fixed very unlikely race condition in ct_static_init
+- free in reverse order of allocation to help memory manager
+- use zlib-1.0/* instead of zlib/* inside the tar.gz
+- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith
+  -Wconversion -Wstrict-prototypes -Wmissing-prototypes"
+- allow gzread on concatenated .gz files
+- deflateEnd now returns Z_DATA_ERROR if it was premature
+- deflate is finally (?) fully deterministic (no matches beyond end of input)
+- Document Z_SYNC_FLUSH
+- add uninstall in Makefile
+- Check for __cpluplus in zlib.h
+- Better test in ct_align for partial flush
+- avoid harmless warnings for Borland C++
+- initialize hash_head in deflate.c
+- avoid warning on fdopen (gzio.c) for HP cc -Aa
+- include stdlib.h for STDC compilers
+- include errno.h for Cray
+- ignore error if ranlib doesn't exist
+- call ranlib twice for NeXTSTEP
+- use exec_prefix instead of prefix for libz.a
+- renamed ct_* as _tr_* to avoid conflict with applications
+- clear z->msg in inflateInit2 before any error return
+- initialize opaque in example.c, gzio.c, deflate.c and inflate.c
+- fixed typo in zconf.h (_GNUC__ => __GNUC__)
+- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode)
+- fix typo in Make_vms.com (f$trnlnm -> f$getsyi)
+- in fcalloc, normalize pointer if size > 65520 bytes
+- don't use special fcalloc for 32 bit Borland C++
+- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc...
+- use Z_BINARY instead of BINARY
+- document that gzclose after gzdopen will close the file
+- allow "a" as mode in gzopen.
+- fix error checking in gzread
+- allow skipping .gz extra-field on pipes
+- added reference to Perl interface in README
+- put the crc table in FAR data (I dislike more and more the medium model :)
+- added get_crc_table
+- added a dimension to all arrays (Borland C can't count).
+- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast
+- guard against multiple inclusion of *.h (for precompiled header on Mac)
+- Watcom C pretends to be Microsoft C small model even in 32 bit mode.
+- don't use unsized arrays to avoid silly warnings by Visual C++:
+     warning C4746: 'inflate_mask' : unsized array treated as  '__far'
+     (what's wrong with far data in far model?).
+- define enum out of inflate_blocks_state to allow compilation with C++
+
+Changes in 0.95 (16 Aug 95)
+- fix MSDOS small and medium model (now easier to adapt to any compiler)
+- inlined send_bits
+- fix the final (:-) bug for deflate with flush (output was correct but
+  not completely flushed in rare occasions).
+- default window size is same for compression and decompression
+  (it's now sufficient to set MAX_WBITS in zconf.h).
+- voidp -> voidpf and voidnp -> voidp (for consistency with other
+  typedefs and because voidnp was not near in large model).
+
+Changes in 0.94 (13 Aug 95)
+- support MSDOS medium model
+- fix deflate with flush (could sometimes generate bad output)
+- fix deflateReset (zlib header was incorrectly suppressed)
+- added support for VMS
+- allow a compression level in gzopen()
+- gzflush now calls fflush
+- For deflate with flush, flush even if no more input is provided.
+- rename libgz.a as libz.a
+- avoid complex expression in infcodes.c triggering Turbo C bug
+- work around a problem with gcc on Alpha (in INSERT_STRING)
+- don't use inline functions (problem with some gcc versions)
+- allow renaming of Byte, uInt, etc... with #define.
+- avoid warning about (unused) pointer before start of array in deflate.c
+- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c
+- avoid reserved word 'new' in trees.c
+
+Changes in 0.93 (25 June 95)
+- temporarily disable inline functions
+- make deflate deterministic
+- give enough lookahead for PARTIAL_FLUSH
+- Set binary mode for stdin/stdout in minigzip.c for OS/2
+- don't even use signed char in inflate (not portable enough)
+- fix inflate memory leak for segmented architectures
+
+Changes in 0.92 (3 May 95)
+- don't assume that char is signed (problem on SGI)
+- Clear bit buffer when starting a stored block
+- no memcpy on Pyramid
+- suppressed inftest.c
+- optimized fill_window, put longest_match inline for gcc
+- optimized inflate on stored blocks.
+- untabify all sources to simplify patches
+
+Changes in 0.91 (2 May 95)
+- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h
+- Document the memory requirements in zconf.h
+- added "make install"
+- fix sync search logic in inflateSync
+- deflate(Z_FULL_FLUSH) now works even if output buffer too short
+- after inflateSync, don't scare people with just "lo world"
+- added support for DJGPP
+
+Changes in 0.9 (1 May 95)
+- don't assume that zalloc clears the allocated memory (the TurboC bug
+  was Mark's bug after all :)
+- let again gzread copy uncompressed data unchanged (was working in 0.71)
+- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented
+- added a test of inflateSync in example.c
+- moved MAX_WBITS to zconf.h because users might want to change that.
+- document explicitly that zalloc(64K) on MSDOS must return a normalized
+  pointer (zero offset)
+- added Makefiles for Microsoft C, Turbo C, Borland C++
+- faster crc32()
+
+Changes in 0.8 (29 April 95)
+- added fast inflate (inffast.c)
+- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this
+  is incompatible with previous versions of zlib which returned Z_OK.
+- work around a TurboC compiler bug (bad code for b << 0, see infutil.h)
+  (actually that was not a compiler bug, see 0.81 above)
+- gzread no longer reads one extra byte in certain cases
+- In gzio destroy(), don't reference a freed structure
+- avoid many warnings for MSDOS
+- avoid the ERROR symbol which is used by MS Windows
+
+Changes in 0.71 (14 April 95)
+- Fixed more MSDOS compilation problems :( There is still a bug with
+  TurboC large model.
+
+Changes in 0.7 (14 April 95)
+- Added full inflate support.
+- Simplified the crc32() interface. The pre- and post-conditioning
+  (one's complement) is now done inside crc32(). WARNING: this is
+  incompatible with previous versions; see zlib.h for the new usage.
+
+Changes in 0.61 (12 April 95)
+- workaround for a bug in TurboC. example and minigzip now work on MSDOS.
+
+Changes in 0.6 (11 April 95)
+- added minigzip.c
+- added gzdopen to reopen a file descriptor as gzFile
+- added transparent reading of non-gziped files in gzread.
+- fixed bug in gzread (don't read crc as data)
+- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose).
+- don't allocate big arrays in the stack (for MSDOS)
+- fix some MSDOS compilation problems
+
+Changes in 0.5:
+- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but
+  not yet Z_FULL_FLUSH.
+- support decompression but only in a single step (forced Z_FINISH)
+- added opaque object for zalloc and zfree.
+- added deflateReset and inflateReset
+- added a variable zlib_version for consistency checking.
+- renamed the 'filter' parameter of deflateInit2 as 'strategy'.
+  Added Z_FILTERED and Z_HUFFMAN_ONLY constants.
+
+Changes in 0.4:
+- avoid "zip" everywhere, use zlib instead of ziplib.
+- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush
+  if compression method == 8.
+- added adler32 and crc32
+- renamed deflateOptions as deflateInit2, call one or the other but not both
+- added the method parameter for deflateInit2.
+- added inflateInit2
+- simplied considerably deflateInit and inflateInit by not supporting
+  user-provided history buffer. This is supported only in deflateInit2
+  and inflateInit2.
+
+Changes in 0.3:
+- prefix all macro names with Z_
+- use Z_FINISH instead of deflateEnd to finish compression.
+- added Z_HUFFMAN_ONLY
+- added gzerror()
diff --git a/src/zlib/INDEX b/src/zlib/INDEX
new file mode 100644
index 0000000000..c405328b49
--- /dev/null
+++ b/src/zlib/INDEX
@@ -0,0 +1,82 @@
+ChangeLog		history of changes
+INDEX			this file
+Make_vms.com		script for Vax/VMS
+Makefile		makefile for Unix (generated by configure)
+Makefile.in		makefile for Unix (template for configure)
+Makefile.msc		makefile for Microsoft C 16-bit
+Makefile.riscos 	makefile for RISCOS
+README			guess what
+algorithm.txt		description of the (de)compression algorithm
+configure		configure script for Unix
+descrip.mms		makefile for Vax/VMS
+zlib.3			mini man page for zlib (volunteers to write full
+			man pages from zlib.h welcome. write to jloup@gzip.org)
+
+amiga/Makefile.sas	makefile for Amiga SAS/C
+amiga/Makefile.pup      makefile for Amiga powerUP SAS/C PPC
+
+msdos/Makefile.w32      makefile for Microsoft Visual C++ 32-bit
+msdos/Makefile.b32	makefile for Borland C++   32-bit
+msdos/Makefile.bor	makefile for Borland C/C++ 16-bit
+msdos/Makefile.dj2	makefile for DJGPP 2.x
+msdos/Makefile.tc	makefile for Turbo C
+msdos/Makefile.wat	makefile for Watcom C
+msdos/zlib.def        	definition file for Windows DLL
+msdos/zlib.rc         	definition file for Windows DLL
+
+nt/Makefile.nt		makefile for Windows NT
+nt/zlib.dnt		definition file for Windows NT DLL
+
+
+		zlib public header files (must be kept):
+zconf.h
+zlib.h
+
+		private source files used to build the zlib library:
+adler32.c
+compress.c
+crc32.c
+deflate.c
+deflate.h
+gzio.c
+infblock.c
+infblock.h
+infcodes.c
+infcodes.h
+inffast.c
+inffast.h
+inflate.c
+inftrees.c
+inftrees.h
+infutil.c
+infutil.h
+maketree.c
+trees.c
+uncompr.c
+zutil.c
+zutil.h
+
+		source files for sample programs:
+example.c
+minigzip.c
+
+		unsupported contribution by third parties
+
+contrib/asm386/ by Gilles Vollant <info@winimage.com>
+	386 asm code replacing longest_match().
+
+contrib/minizip/ by Gilles Vollant <info@winimage.com>
+	Mini zip and unzip based on zlib
+        See http://www.winimage.com/zLibDll/unzip.html
+
+contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
+        A C++ I/O streams interface to the zlib gz* functions
+
+contrib/iostream2/  by Tyge Løvset <Tyge.Lovset@cmr.no>
+	Another C++ I/O streams interface
+
+contrib/untgz/  by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
+	A very simple tar.gz extractor using zlib
+
+contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
+        How to use compress(), uncompress() and the gz* functions from VB.
diff --git a/src/zlib/Make_vms.com b/src/zlib/Make_vms.com
new file mode 100644
index 0000000000..0008d00bb6
--- /dev/null
+++ b/src/zlib/Make_vms.com
@@ -0,0 +1,115 @@
+$! make libz under VMS
+$! written by Martin P.J. Zinser <m.zinser@gsi.de>
+$!
+$! Look for the compiler used
+$!
+$ ccopt = ""
+$ if f$getsyi("HW_MODEL").ge.1024
+$ then
+$  ccopt = "/prefix=all"+ccopt
+$  comp  = "__decc__=1"
+$  if f$trnlnm("SYS").eqs."" then define sys sys$library:
+$ else
+$  if f$search("SYS$SYSTEM:DECC$COMPILER.EXE").eqs.""
+$   then
+$    comp  = "__vaxc__=1"
+$    if f$trnlnm("SYS").eqs."" then define sys sys$library:
+$   else
+$    if f$trnlnm("SYS").eqs."" then define sys decc$library_include:
+$    ccopt = "/decc/prefix=all"+ccopt
+$    comp  = "__decc__=1"
+$  endif
+$ endif
+$!
+$! Build the thing plain or with mms
+$!
+$ write sys$output "Compiling Zlib sources ..."
+$ if f$search("SYS$SYSTEM:MMS.EXE").eqs.""
+$  then
+$   dele example.obj;*,minigzip.obj;*
+$   CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" -
+                adler32.c zutil.h zlib.h zconf.h
+$   CALL MAKE compress.OBJ "CC ''CCOPT' compress" -
+                compress.c zlib.h zconf.h
+$   CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" -
+                crc32.c zutil.h zlib.h zconf.h
+$   CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" -
+                deflatec.c deflate.h zutil.h zlib.h zconf.h
+$   CALL MAKE gzio.OBJ "CC ''CCOPT' gzio" -
+                gsio.c zutil.h zlib.h zconf.h
+$   CALL MAKE infblock.OBJ "CC ''CCOPT' infblock" -
+                infblock.c zutil.h zlib.h zconf.h infblock.h
+$   CALL MAKE infcodes.OBJ "CC ''CCOPT' infcodes" -
+                infcodes.c zutil.h zlib.h zconf.h inftrees.h
+$   CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" -
+                inffast.c zutil.h zlib.h zconf.h inffast.h
+$   CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" -
+                inflate.c zutil.h zlib.h zconf.h infblock.h
+$   CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" -
+                inftrees.c zutil.h zlib.h zconf.h inftrees.h
+$   CALL MAKE infutil.OBJ "CC ''CCOPT' infutil" -
+                infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h
+$   CALL MAKE trees.OBJ "CC ''CCOPT' trees" -
+                trees.c deflate.h zutil.h zlib.h zconf.h
+$   CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" -
+                uncompr.c zlib.h zconf.h
+$   CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" -
+                zutil.c zutil.h zlib.h zconf.h
+$   write sys$output "Building Zlib ..."
+$   CALL MAKE libz.OLB "lib/crea libz.olb *.obj" *.OBJ
+$   write sys$output "Building example..."
+$   CALL MAKE example.OBJ "CC ''CCOPT' example" -
+                example.c zlib.h zconf.h
+$   call make example.exe "LINK example,libz.olb/lib" example.obj libz.olb
+$   write sys$output "Building minigzip..."
+$   CALL MAKE minigzip.OBJ "CC ''CCOPT' minigzip" -
+                minigzip.c zlib.h zconf.h
+$   call make minigzip.exe - 
+                "LINK minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib" - 
+                minigzip.obj libz.olb
+$  else
+$   mms/macro=('comp')
+$  endif
+$ write sys$output "Zlib build completed"
+$ exit
+$!
+$!
+$MAKE: SUBROUTINE   !SUBROUTINE TO CHECK DEPENDENCIES
+$ V = 'F$Verify(0)
+$! P1 = What we are trying to make
+$! P2 = Command to make it
+$! P3 - P8  What it depends on
+$
+$ If F$Search(P1) .Eqs. "" Then Goto Makeit
+$ Time = F$CvTime(F$File(P1,"RDT"))
+$arg=3
+$Loop:
+$       Argument = P'arg
+$       If Argument .Eqs. "" Then Goto Exit
+$       El=0
+$Loop2:
+$       File = F$Element(El," ",Argument)
+$       If File .Eqs. " " Then Goto Endl
+$       AFile = ""
+$Loop3:
+$       OFile = AFile
+$       AFile = F$Search(File)
+$       If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl
+$       If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit
+$       Goto Loop3
+$NextEL:
+$       El = El + 1
+$       Goto Loop2
+$EndL:
+$ arg=arg+1
+$ If arg .Le. 8 Then Goto Loop
+$ Goto Exit
+$
+$Makeit:
+$ VV=F$VERIFY(0)
+$ write sys$output P2
+$ 'P2
+$ VV='F$Verify(VV)
+$Exit:
+$ If V Then Set Verify
+$ENDSUBROUTINE
diff --git a/src/zlib/Makefile.in2 b/src/zlib/Makefile.in2
new file mode 100644
index 0000000000..c8bb6e9578
--- /dev/null
+++ b/src/zlib/Makefile.in2
@@ -0,0 +1,160 @@
+# Makefile for zlib
+# Copyright (C) 1995-1998 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h 
+
+# To compile and test, type:
+#   ./configure; make test
+# The call of configure is optional if you don't have special requirements
+# If you wish to build zlib as a shared library, use: ./configure -s
+
+# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type:
+#    make install
+# To install in $HOME instead of /usr/local, use:
+#    make install prefix=$HOME
+
+CC=cc
+
+CFLAGS=-O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-g -DDEBUG
+#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+#           -Wstrict-prototypes -Wmissing-prototypes
+
+LDFLAGS=-L. -lz
+LDSHARED=$(CC)
+
+VER=1.1.2
+LIBS=libz.a
+SHAREDLIB=libz.so
+
+AR=ar rc
+RANLIB=ranlib
+TAR=tar
+SHELL=/bin/sh
+
+prefix = /usr/local
+exec_prefix = ${prefix}
+
+OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
+       zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o
+
+TEST_OBJS = example.o minigzip.o
+
+DISTFILES = README INDEX ChangeLog configure Make*[a-z0-9] *.[ch] descrip.mms \
+  algorithm.txt zlib.3 msdos/Make*[a-z0-9] msdos/zlib.def msdos/zlib.rc \
+  nt/Makefile.nt nt/zlib.dnt amiga/Make*.??? contrib/README.contrib \
+  contrib/*.txt contrib/asm386/*.asm contrib/asm386/*.c \
+  contrib/asm386/*.bat contrib/asm386/zlibvc.d?? contrib/iostream/*.cpp \
+  contrib/iostream/*.h  contrib/iostream2/*.h contrib/iostream2/*.cpp \
+  contrib/untgz/Makefile contrib/untgz/*.c contrib/untgz/*.w32 \
+  contrib/minizip/[CM]*[pe] contrib/minizip/*.[ch] contrib/minizip/*.[td]??
+
+
+all: example minigzip
+
+test: all
+	@LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
+	echo hello world | ./minigzip | ./minigzip -d || \
+	  echo '		*** minigzip test FAILED ***' ; \
+	if ./example; then \
+	  echo '		*** zlib test OK ***'; \
+	else \
+	  echo '		*** zlib test FAILED ***'; \
+	fi
+
+libz.a: $(OBJS)
+	$(AR) $@ $(OBJS)
+	-@ ($(RANLIB) $@ || true) >/dev/null 2>&1
+
+$(SHAREDLIB).$(VER): $(OBJS)
+	$(LDSHARED) -o $@ $(OBJS)
+	rm -f $(SHAREDLIB) $(SHAREDLIB).1
+	ln -s $@ $(SHAREDLIB)
+	ln -s $@ $(SHAREDLIB).1
+
+example: example.o $(LIBS)
+	$(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
+
+minigzip: minigzip.o $(LIBS)
+	$(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
+
+install: $(LIBS)
+	-@if [ ! -d $(prefix)/include  ]; then mkdir $(prefix)/include; fi
+	-@if [ ! -d $(exec_prefix)/lib ]; then mkdir $(exec_prefix)/lib; fi
+	cp zlib.h zconf.h $(prefix)/include
+	chmod 644 $(prefix)/include/zlib.h $(prefix)/include/zconf.h
+	cp $(LIBS) $(exec_prefix)/lib
+	cd $(exec_prefix)/lib; chmod 755 $(LIBS)
+	-@(cd $(exec_prefix)/lib; $(RANLIB) libz.a || true) >/dev/null 2>&1
+	cd $(exec_prefix)/lib; if test -f $(SHAREDLIB).$(VER); then \
+	  rm -f $(SHAREDLIB) $(SHAREDLIB).1; \
+	  ln -s $(SHAREDLIB).$(VER) $(SHAREDLIB); \
+	  ln -s $(SHAREDLIB).$(VER) $(SHAREDLIB).1; \
+	  (ldconfig || true)  >/dev/null 2>&1; \
+	fi
+# The ranlib in install is needed on NeXTSTEP which checks file times
+# ldconfig is for Linux
+
+uninstall:
+	cd $(prefix)/include; \
+	v=$(VER); \
+	if test -f zlib.h; then \
+	  v=`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`; \
+          rm -f zlib.h zconf.h; \
+	fi; \
+	cd $(exec_prefix)/lib; rm -f libz.a; \
+	if test -f $(SHAREDLIB).$$v; then \
+	  rm -f $(SHAREDLIB).$$v $(SHAREDLIB) $(SHAREDLIB).1; \
+	fi
+
+clean:
+	rm -f *.o *~ example minigzip libz.a libz.so* foo.gz
+
+distclean:	clean
+
+zip:
+	mv Makefile Makefile~; cp -p Makefile.in Makefile
+	rm -f test.c ztest*.c contrib/minizip/test.zip
+	v=`sed -n -e 's/\.//g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
+	zip -ul9 zlib$$v $(DISTFILES)
+	mv Makefile~ Makefile
+
+dist:
+	mv Makefile Makefile~; cp -p Makefile.in Makefile
+	rm -f test.c ztest*.c contrib/minizip/test.zip
+	d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
+	rm -f $$d.tar.gz; \
+	if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \
+	files=""; \
+	for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \
+	cd ..; \
+	GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \
+	if test ! -d $$d; then rm -f $$d; fi
+	mv Makefile~ Makefile
+
+tags:	
+	etags *.[ch]
+
+depend:
+	makedepend -- $(CFLAGS) -- *.[ch]
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+adler32.o: zlib.h zconf.h
+compress.o: zlib.h zconf.h
+crc32.o: zlib.h zconf.h
+deflate.o: deflate.h zutil.h zlib.h zconf.h
+example.o: zlib.h zconf.h
+gzio.o: zutil.h zlib.h zconf.h
+infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h
+infcodes.o: zutil.h zlib.h zconf.h
+infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.h
+inffast.o: infblock.h infcodes.h infutil.h inffast.h
+inflate.o: zutil.h zlib.h zconf.h infblock.h
+inftrees.o: zutil.h zlib.h zconf.h inftrees.h
+infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
+minigzip.o:  zlib.h zconf.h 
+trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
+uncompr.o: zlib.h zconf.h
+zutil.o: zutil.h zlib.h zconf.h  
diff --git a/src/zlib/Makefile.riscos b/src/zlib/Makefile.riscos
new file mode 100644
index 0000000000..0f10aa8918
--- /dev/null
+++ b/src/zlib/Makefile.riscos
@@ -0,0 +1,46 @@
+# Project:   zlib_1_03
+
+
+# Toolflags:
+CCflags = -c -depend !Depend -IC: -g -throwback  -DRISCOS  -fnah 
+C++flags = -c -depend !Depend -IC: -throwback
+Linkflags = -aif -c++ -o $@ 
+ObjAsmflags = -throwback -NoCache -depend !Depend
+CMHGflags = 
+LibFileflags = -c -l -o $@ 
+Squeezeflags = -o $@
+
+
+# Final targets:
+@.zlib_lib:   @.o.adler32 @.o.compress @.o.crc32 @.o.deflate @.o.gzio \
+        @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil @.o.trees \
+        @.o.uncompress @.o.zutil 
+        LibFile $(LibFileflags) @.o.adler32 @.o.compress @.o.crc32 @.o.deflate \
+        @.o.gzio @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil \
+        @.o.trees @.o.uncompress @.o.zutil 
+@.test:   @.tests.minigzip @.tests.example 
+        echo Please run "Test" in directory tests 
+@.tests.minigzip:   @.o.minigzip @.zlib_lib C:o.Stubs 
+        Link $(Linkflags) @.o.minigzip @.zlib_lib C:o.Stubs 
+@.tests.example:   @.o.example @.zlib_lib C:o.Stubs 
+        Link $(Linkflags) @.o.example @.zlib_lib C:o.Stubs 
+
+
+# User-editable dependencies:
+.c.o:
+        cc $(ccflags) -o $@ $<
+
+# Static dependencies:
+@.o.example:   @.tests.c.example
+        cc $(ccflags) -o @.o.example @.tests.c.example 
+@.o.minigzip:   @.tests.c.minigzip
+        cc $(ccflags) -o @.o.minigzip @.tests.c.minigzip 
+
+
+# Dynamic dependencies:
+o.minigzip:	tests.c.minigzip
+o.minigzip:	h.zlib
+o.minigzip:	h.zconf
+o.example:	tests.c.example
+o.example:	h.zlib
+o.example:	h.zconf
diff --git a/src/zlib/README b/src/zlib/README
new file mode 100644
index 0000000000..2471d5ca93
--- /dev/null
+++ b/src/zlib/README
@@ -0,0 +1,143 @@
+zlib 1.1.2 is a general purpose data compression library.  All the code
+is thread safe.  The data format used by the zlib library
+is described by RFCs (Request for Comments) 1950 to 1952 in the files 
+ftp://ds.internic.net/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate
+format) and rfc1952.txt (gzip format). These documents are also available in
+other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
+
+All functions of the compression library are documented in the file zlib.h
+(volunteer to write man pages welcome, contact jloup@gzip.org). A usage
+example of the library is given in the file example.c which also tests that
+the library is working correctly. Another example is given in the file
+minigzip.c. The compression library itself is composed of all source files
+except example.c and minigzip.c.
+
+To compile all files and run the test program, follow the instructions
+given at the top of Makefile. In short "make test; make install"
+should work for most machines.  For MSDOS, use one of the special
+makefiles such as Makefile.msc; for VMS, use Make_vms.com or descrip.mms.
+
+Questions about zlib should be sent to <zlib@quest.jpl.nasa.gov> or,
+if this fails, to the addresses given below in the Copyright section.
+The zlib home page is http://www.cdrom.com/pub/infozip/zlib/
+The official zlib ftp site is ftp://ftp.cdrom.com/pub/infozip/zlib/
+Mark Nelson <markn@tiny.com> wrote an article about zlib for the Jan. 1997
+issue of  Dr. Dobb's Journal; a copy of the article is available in
+http://web2.airmail.net/markn/articles/zlibtool/zlibtool.htm
+
+The changes made in version 1.1.2 are documented in the file ChangeLog.
+The main changes since 1.1.1 are:
+
+- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant)
+  See http://www.winimage.com/zLibDll/unzip.html
+- preinitialize the inflate tables for fixed codes, to make the code
+  completely thread safe (Mark)
+- some simplifications and slight speed-up to the inflate code (Mark)
+- fix gzeof on non-compressed files (Allan Schrum)
+- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs)
+- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn)
+- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny)
+- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori)
+- do not wrap extern "C" around system includes (Tom Lane)
+- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert)
+- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson)
+- allow "configure --prefix $HOME" (Tim Mooney)
+
+
+Unsupported third party contributions are provided in directory "contrib".
+
+A Java implementation of zlib is available in the Java Development Kit 1.1
+http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
+See the zlib home page http://www.cdrom.com/pub/infozip/zlib/ for details.
+
+A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk>
+is in the CPAN (Comprehensive Perl Archive Network) sites, such as:
+ftp://ftp.cis.ufl.edu/pub/perl/CPAN/modules/by-module/Compress/Compress-Zlib*
+
+A Python interface to zlib written by A.M. Kuchling <amk@magnet.com>
+is available from the Python Software Association sites, such as:
+ftp://ftp.python.org/pub/python/contrib/Encoding/zlib*.tar.gz
+
+A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com>
+is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html
+
+An experimental package to read and write files in .zip format,
+written on top of zlib by Gilles Vollant <info@winimage.com>, is
+available at http://www.winimage.com/zLibDll/unzip.html
+and also in the contrib/minizip directory of zlib.
+
+
+Notes for some targets:
+
+- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc
+  and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL
+  The zlib DLL support was initially done by Alessandro Iacopetti and is
+  now maintained by Gilles Vollant <info@winimage.com>. Check the zlib DLL
+  home page at http://www.winimage.com/zLibDll
+
+  From Visual Basic, you can call the DLL functions which do not take
+  a structure as argument: compress, uncompress and all gz* functions.
+  See contrib/visual-basic.txt for more information.
+  I don't know how to handle structures in Visual Basic, sorry.
+
+- For 64-bit Irix, deflate.c must be compiled without any optimization.
+  With -O, one libpng test fails. The test works in 32 bit mode (with
+  the -n32 compiler flag). The compiler bug has been reported to SGI.
+
+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1   
+  it works when compiled with cc.
+
+- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1
+  is necessary to get gzprintf working correctly. This is done by configure.
+
+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works
+  with other compilers. Use "make test" to check your compiler.
+
+- For shared memory multiprocessors, the decompression code assumes that
+  writes to pointers are atomic. Also the functions zalloc and zfree passed
+  to deflateInit must be multi-threaded in this case.
+
+- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
+
+- For Turbo C the small model is supported only with reduced performance to
+  avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
+
+
+Acknowledgments:
+
+  The deflate format used by zlib was defined by Phil Katz. The deflate
+  and zlib specifications were written by L. Peter Deutsch. Thanks to all the
+  people who reported problems and suggested various improvements in zlib;
+  they are too numerous to cite here.
+
+Copyright notice:
+
+ (C) 1995-1998 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup@gzip.org          madler@alumni.caltech.edu
+
+If you use the zlib library in a product, we would appreciate *not*
+receiving lengthy legal documents to sign. The sources are provided
+for free but without warranty of any kind.  The library has been
+entirely written by Jean-loup Gailly and Mark Adler; it does not
+include third-party code.
+
+If you redistribute modified sources, we would appreciate that you include
+in the file ChangeLog history information documenting your changes.
diff --git a/src/zlib/adler32.c b/src/zlib/adler32.c
new file mode 100644
index 0000000000..16cf9a703f
--- /dev/null
+++ b/src/zlib/adler32.c
@@ -0,0 +1,48 @@
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* @(#) $Id$ */
+
+#include "zlib.h"
+
+#define BASE 65521L /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
+#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf)   DO8(buf,0); DO8(buf,8);
+
+/* ========================================================================= */
+uLong ZEXPORT adler32(adler, buf, len)
+    uLong adler;
+    const Bytef *buf;
+    uInt len;
+{
+    unsigned long s1 = adler & 0xffff;
+    unsigned long s2 = (adler >> 16) & 0xffff;
+    int k;
+
+    if (buf == Z_NULL) return 1L;
+
+    while (len > 0) {
+        k = len < NMAX ? len : NMAX;
+        len -= k;
+        while (k >= 16) {
+            DO16(buf);
+	    buf += 16;
+            k -= 16;
+        }
+        if (k != 0) do {
+            s1 += *buf++;
+	    s2 += s1;
+        } while (--k);
+        s1 %= BASE;
+        s2 %= BASE;
+    }
+    return (s2 << 16) | s1;
+}
diff --git a/src/zlib/algorithm.txt b/src/zlib/algorithm.txt
new file mode 100644
index 0000000000..cdc830b5de
--- /dev/null
+++ b/src/zlib/algorithm.txt
@@ -0,0 +1,213 @@
+1. Compression algorithm (deflate)
+
+The deflation algorithm used by gzip (also zip and zlib) is a variation of
+LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in
+the input data.  The second occurrence of a string is replaced by a
+pointer to the previous string, in the form of a pair (distance,
+length).  Distances are limited to 32K bytes, and lengths are limited
+to 258 bytes. When a string does not occur anywhere in the previous
+32K bytes, it is emitted as a sequence of literal bytes.  (In this
+description, `string' must be taken as an arbitrary sequence of bytes,
+and is not restricted to printable characters.)
+
+Literals or match lengths are compressed with one Huffman tree, and
+match distances are compressed with another tree. The trees are stored
+in a compact form at the start of each block. The blocks can have any
+size (except that the compressed data for one block must fit in
+available memory). A block is terminated when deflate() determines that
+it would be useful to start another block with fresh trees. (This is
+somewhat similar to the behavior of LZW-based _compress_.)
+
+Duplicated strings are found using a hash table. All input strings of
+length 3 are inserted in the hash table. A hash index is computed for
+the next 3 bytes. If the hash chain for this index is not empty, all
+strings in the chain are compared with the current input string, and
+the longest match is selected.
+
+The hash chains are searched starting with the most recent strings, to
+favor small distances and thus take advantage of the Huffman encoding.
+The hash chains are singly linked. There are no deletions from the
+hash chains, the algorithm simply discards matches that are too old.
+
+To avoid a worst-case situation, very long hash chains are arbitrarily
+truncated at a certain length, determined by a runtime option (level
+parameter of deflateInit). So deflate() does not always find the longest
+possible match but generally finds a match which is long enough.
+
+deflate() also defers the selection of matches with a lazy evaluation
+mechanism. After a match of length N has been found, deflate() searches for
+a longer match at the next input byte. If a longer match is found, the
+previous match is truncated to a length of one (thus producing a single
+literal byte) and the process of lazy evaluation begins again. Otherwise,
+the original match is kept, and the next match search is attempted only N
+steps later.
+
+The lazy match evaluation is also subject to a runtime parameter. If
+the current match is long enough, deflate() reduces the search for a longer
+match, thus speeding up the whole process. If compression ratio is more
+important than speed, deflate() attempts a complete second search even if
+the first match is already long enough.
+
+The lazy match evaluation is not performed for the fastest compression
+modes (level parameter 1 to 3). For these fast modes, new strings
+are inserted in the hash table only when no match was found, or
+when the match is not too long. This degrades the compression ratio
+but saves time since there are both fewer insertions and fewer searches.
+
+
+2. Decompression algorithm (inflate)
+
+2.1 Introduction
+
+The real question is, given a Huffman tree, how to decode fast.  The most
+important realization is that shorter codes are much more common than
+longer codes, so pay attention to decoding the short codes fast, and let
+the long codes take longer to decode.
+
+inflate() sets up a first level table that covers some number of bits of
+input less than the length of longest code.  It gets that many bits from the
+stream, and looks it up in the table.  The table will tell if the next
+code is that many bits or less and how many, and if it is, it will tell
+the value, else it will point to the next level table for which inflate()
+grabs more bits and tries to decode a longer code.
+
+How many bits to make the first lookup is a tradeoff between the time it
+takes to decode and the time it takes to build the table.  If building the
+table took no time (and if you had infinite memory), then there would only
+be a first level table to cover all the way to the longest code.  However,
+building the table ends up taking a lot longer for more bits since short
+codes are replicated many times in such a table.  What inflate() does is
+simply to make the number of bits in the first table a variable, and set it
+for the maximum speed.
+
+inflate() sends new trees relatively often, so it is possibly set for a
+smaller first level table than an application that has only one tree for
+all the data.  For inflate, which has 286 possible codes for the
+literal/length tree, the size of the first table is nine bits.  Also the
+distance trees have 30 possible values, and the size of the first table is
+six bits.  Note that for each of those cases, the table ended up one bit
+longer than the ``average'' code length, i.e. the code length of an
+approximately flat code which would be a little more than eight bits for
+286 symbols and a little less than five bits for 30 symbols.  It would be
+interesting to see if optimizing the first level table for other
+applications gave values within a bit or two of the flat code size.
+
+
+2.2 More details on the inflate table lookup
+
+Ok, you want to know what this cleverly obfuscated inflate tree actually  
+looks like.  You are correct that it's not a Huffman tree.  It is simply a  
+lookup table for the first, let's say, nine bits of a Huffman symbol.  The  
+symbol could be as short as one bit or as long as 15 bits.  If a particular  
+symbol is shorter than nine bits, then that symbol's translation is duplicated
+in all those entries that start with that symbol's bits.  For example, if the  
+symbol is four bits, then it's duplicated 32 times in a nine-bit table.  If a  
+symbol is nine bits long, it appears in the table once.
+
+If the symbol is longer than nine bits, then that entry in the table points  
+to another similar table for the remaining bits.  Again, there are duplicated  
+entries as needed.  The idea is that most of the time the symbol will be short
+and there will only be one table look up.  (That's whole idea behind data  
+compression in the first place.)  For the less frequent long symbols, there  
+will be two lookups.  If you had a compression method with really long  
+symbols, you could have as many levels of lookups as is efficient.  For  
+inflate, two is enough.
+
+So a table entry either points to another table (in which case nine bits in  
+the above example are gobbled), or it contains the translation for the symbol  
+and the number of bits to gobble.  Then you start again with the next  
+ungobbled bit.
+
+You may wonder: why not just have one lookup table for how ever many bits the  
+longest symbol is?  The reason is that if you do that, you end up spending  
+more time filling in duplicate symbol entries than you do actually decoding.   
+At least for deflate's output that generates new trees every several 10's of  
+kbytes.  You can imagine that filling in a 2^15 entry table for a 15-bit code  
+would take too long if you're only decoding several thousand symbols.  At the  
+other extreme, you could make a new table for every bit in the code.  In fact,
+that's essentially a Huffman tree.  But then you spend two much time  
+traversing the tree while decoding, even for short symbols.
+
+So the number of bits for the first lookup table is a trade of the time to  
+fill out the table vs. the time spent looking at the second level and above of
+the table.
+
+Here is an example, scaled down:
+
+The code being decoded, with 10 symbols, from 1 to 6 bits long:
+
+A: 0
+B: 10
+C: 1100
+D: 11010
+E: 11011
+F: 11100
+G: 11101
+H: 11110
+I: 111110
+J: 111111
+
+Let's make the first table three bits long (eight entries):
+
+000: A,1
+001: A,1
+010: A,1
+011: A,1
+100: B,2
+101: B,2
+110: -> table X (gobble 3 bits)
+111: -> table Y (gobble 3 bits)
+
+Each entry is what the bits decode to and how many bits that is, i.e. how  
+many bits to gobble.  Or the entry points to another table, with the number of
+bits to gobble implicit in the size of the table.
+
+Table X is two bits long since the longest code starting with 110 is five bits
+long:
+
+00: C,1
+01: C,1
+10: D,2
+11: E,2
+
+Table Y is three bits long since the longest code starting with 111 is six  
+bits long:
+
+000: F,2
+001: F,2
+010: G,2
+011: G,2
+100: H,2
+101: H,2
+110: I,3
+111: J,3
+
+So what we have here are three tables with a total of 20 entries that had to  
+be constructed.  That's compared to 64 entries for a single table.  Or  
+compared to 16 entries for a Huffman tree (six two entry tables and one four  
+entry table).  Assuming that the code ideally represents the probability of  
+the symbols, it takes on the average 1.25 lookups per symbol.  That's compared
+to one lookup for the single table, or 1.66 lookups per symbol for the  
+Huffman tree.
+
+There, I think that gives you a picture of what's going on.  For inflate, the  
+meaning of a particular symbol is often more than just a letter.  It can be a  
+byte (a "literal"), or it can be either a length or a distance which  
+indicates a base value and a number of bits to fetch after the code that is  
+added to the base value.  Or it might be the special end-of-block code.  The  
+data structures created in inftrees.c try to encode all that information  
+compactly in the tables.
+
+
+Jean-loup Gailly        Mark Adler
+jloup@gzip.org          madler@alumni.caltech.edu
+
+
+References:
+
+[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data
+Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3,
+pp. 337-343.
+
+``DEFLATE Compressed Data Format Specification'' available in
+ftp://ds.internic.net/rfc/rfc1951.txt
diff --git a/src/zlib/compress.c b/src/zlib/compress.c
new file mode 100644
index 0000000000..1cee470913
--- /dev/null
+++ b/src/zlib/compress.c
@@ -0,0 +1,68 @@
+/* compress.c -- compress a memory buffer
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* @(#) $Id$ */
+
+#include "zlib.h"
+
+/* ===========================================================================
+     Compresses the source buffer into the destination buffer. The level
+   parameter has the same meaning as in deflateInit.  sourceLen is the byte
+   length of the source buffer. Upon entry, destLen is the total size of the
+   destination buffer, which must be at least 0.1% larger than sourceLen plus
+   12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+   Z_STREAM_ERROR if the level parameter is invalid.
+*/
+int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+    int level;
+{
+    z_stream stream;
+    int err;
+
+    stream.next_in = (Bytef*)source;
+    stream.avail_in = (uInt)sourceLen;
+#ifdef MAXSEG_64K
+    /* Check for source > 64K on 16-bit machine: */
+    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+#endif
+    stream.next_out = dest;
+    stream.avail_out = (uInt)*destLen;
+    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+    stream.zalloc = (alloc_func)0;
+    stream.zfree = (free_func)0;
+    stream.opaque = (voidpf)0;
+
+    err = deflateInit(&stream, level);
+    if (err != Z_OK) return err;
+
+    err = deflate(&stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        deflateEnd(&stream);
+        return err == Z_OK ? Z_BUF_ERROR : err;
+    }
+    *destLen = stream.total_out;
+
+    err = deflateEnd(&stream);
+    return err;
+}
+
+/* ===========================================================================
+ */
+int ZEXPORT compress (dest, destLen, source, sourceLen)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+{
+    return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
+}
diff --git a/src/zlib/configure b/src/zlib/configure
new file mode 100644
index 0000000000..d188e6f02d
--- /dev/null
+++ b/src/zlib/configure
@@ -0,0 +1,163 @@
+#!/bin/sh
+# configure script for zlib. This script is needed only if
+# you wish to build a shared library and your system supports them,
+# of if you need special compiler, flags or install directory.
+# Otherwise, you can just use directly "make test; make install"
+#
+# To create a shared library, use "configure --shared"; by default a static
+# library is created. If the primitive shared library support provided here
+# does not work, use ftp://prep.ai.mit.edu/pub/gnu/libtool-*.tar.gz
+#
+# To impose specific compiler or flags or install directory, use for example:
+#    prefix=$HOME CC=cc CFLAGS="-O4" ./configure
+# or for csh/tcsh users:
+#    (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure)
+# LDSHARED is the command to be used to create a shared library
+
+# Incorrect settings of CC or CFLAGS may prevent creating a shared library.
+# If you have problems, try without defining CC and CFLAGS before reporting
+# an error.
+
+LIBS=libz.a
+SHAREDLIB=libz.so
+VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`
+AR=${AR-"ar rc"}
+RANLIB=${RANLIB-"ranlib"}
+prefix=${prefix-/usr/local}
+shared_ext='.so'
+shared=0
+gcc=0
+old_cc="$CC"
+old_cflags="$CFLAGS"
+
+case "$1" in
+  -h* | --h*) echo 'syntax: configure [ --shared ] [--prefix PREFIX]'; exit 0;;
+  -p*=* | --p*=*) prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;;
+  -p* | --p*) prefix="$2"; shift; shift;;
+  -s* | --s*) shared=1; shift;;
+esac
+
+test=ztest$$
+cat > $test.c <<EOF
+extern int getchar();
+int hello() {return getchar();}
+EOF
+
+test -z "$CC" && echo Checking for gcc...
+cc=${CC-gcc}
+cflags=${CFLAGS-"-O3"}
+case "$cc" in
+  *gcc*) gcc=1;;
+esac
+
+if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) 2>/dev/null; then
+  CC="$cc"
+  SFLAGS=${CFLAGS-"-fPIC -O3"}
+  CFLAGS="$cflags"
+  case `(uname -s || echo unknown) 2>/dev/null` in
+  Linux | linux) LDSHARED=${LDSHARED-"gcc -shared -Wl,-soname,libz.so.1"};;
+  *)             LDSHARED=${LDSHARED-"gcc -shared"};;
+  esac
+else
+  # find system name and corresponding cc options
+  CC=${CC-cc}
+  case `(uname -sr || echo unknown) 2>/dev/null` in
+  HP-UX*)    SFLAGS=${CFLAGS-"-O +z"}
+	     CFLAGS=${CFLAGS-"-O"}
+#	     LDSHARED=${LDSHARED-"ld -b +vnocompatwarnings"}
+	     LDSHARED=${LDSHARED-"ld -b"}
+	     shared_ext='.sl'
+	     SHAREDLIB='libz.sl';;
+  IRIX*)     SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."}
+	     CFLAGS=${CFLAGS-"-ansi -O2"}
+	     LDSHARED=${LDSHARED-"cc -shared"};;
+  OSF1)      SFLAGS=${CFLAGS-"-O -std1"}
+	     CFLAGS=${CFLAGS-"-O -std1"}
+	     LDSHARED=${LDSHARED-"cc -shared"};;
+  QNX*)      SFLAGS=${CFLAGS-"-4 -O"}
+             CFLAGS=${CFLAGS-"-4 -O"}
+	     LDSHARED=${LDSHARED-"cc"}
+             RANLIB=${RANLIB-"true"}
+             AR="cc -A";;
+  SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "}
+	     CFLAGS=${CFLAGS-"-O3"}
+	     LDSHARED=${LDSHARED-"cc -dy -KPIC -G"};;
+  SunOS\ 5*) SFLAGS=${CFLAGS-"-fast -xcg89 -KPIC -R."}
+             CFLAGS=${CFLAGS-"-fast -xcg89"}
+	     LDSHARED=${LDSHARED-"cc -G"};;
+  SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"}
+	     CFLAGS=${CFLAGS-"-O2"}
+	     LDSHARED=${LDSHARED-"ld"};;
+  UNIX_System_V\ 4.2.0) 
+	     SFLAGS=${CFLAGS-"-KPIC -O"}
+	     CFLAGS=${CFLAGS-"-O"}
+	     LDSHARED=${LDSHARED-"cc -G"};;
+  UNIX_SV\ 4.2MP)
+	     SFLAGS=${CFLAGS-"-Kconform_pic -O"}
+	     CFLAGS=${CFLAGS-"-O"}
+	     LDSHARED=${LDSHARED-"cc -G"};;
+  # send working options for other systems to support@gzip.org
+  *)         SFLAGS=${CFLAGS-"-O"}
+	     CFLAGS=${CFLAGS-"-O"}
+	     LDSHARED=${LDSHARED-"cc -shared"};;
+  esac
+fi
+
+if test $shared -eq 1; then
+  echo Checking for shared library support...
+  # we must test in two steps (cc then ld), required at least on SunOS 4.x
+  if test "`($CC -c $SFLAGS $test.c) 2>&1`" = "" &&
+     test "`($LDSHARED -o $test$shared_ext $test.o) 2>&1`" = ""; then
+    CFLAGS="$SFLAGS"
+    LIBS="$SHAREDLIB.$VER"
+    echo Building shared library $SHAREDLIB.$VER with $CC.
+  elif test -z "$old_cc" -a -z "$old_cflags"; then
+    echo No shared library suppport.
+    shared=0;
+  else
+    echo 'No shared library suppport; try without defining CC and CFLAGS'
+    shared=0;
+  fi
+fi
+if test $shared -eq 0; then
+  LDSHARED="$CC"
+  echo Building static library $LIBS version $VER with $CC.
+fi
+
+if test -f /usr/include/unistd.h; then
+  CFLAGS="$CFLAGS -DHAVE_UNISTD_H"
+fi
+
+if test ! -f /usr/include/errno.h; then
+  CFLAGS="$CFLAGS -DNO_ERRNO_H"
+fi
+
+cat > $test.c <<EOF
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+caddr_t hello() {
+  return mmap((caddr_t)0, (off_t)0, PROT_READ, MAP_SHARED, 0, (off_t)0); 
+}
+EOF
+if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
+  CFLAGS="$CFLAGS -DUSE_MMAP"
+  echo Checking for mmap support... Yes.
+else
+  echo Checking for mmap support... No.
+fi
+
+rm -f $test.[co] $test$shared_ext
+
+# udpate Makefile
+sed < Makefile.in "
+/^CC *=/s%=.*%=$CC%
+/^CFLAGS *=/s%=.*%=$CFLAGS%
+/^LDSHARED *=/s%=.*%=$LDSHARED%
+/^LIBS *=/s%=.*%=$LIBS%
+/^SHAREDLIB *=/s%=.*%=$SHAREDLIB%
+/^AR *=/s%=.*%=$AR%
+/^RANLIB *=/s%=.*%=$RANLIB%
+/^VER *=/s%=.*%=$VER%
+/^prefix *=/s%=.*%=$prefix%
+" > Makefile
diff --git a/src/zlib/crc32.c b/src/zlib/crc32.c
new file mode 100644
index 0000000000..a91101a81c
--- /dev/null
+++ b/src/zlib/crc32.c
@@ -0,0 +1,162 @@
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* @(#) $Id$ */
+
+#include "zlib.h"
+
+#define local static
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local int crc_table_empty = 1;
+local uLongf crc_table[256];
+local void make_crc_table OF((void));
+
+/*
+  Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
+  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+  Polynomials over GF(2) are represented in binary, one bit per coefficient,
+  with the lowest powers in the most significant bit.  Then adding polynomials
+  is just exclusive-or, and multiplying a polynomial by x is a right shift by
+  one.  If we call the above polynomial p, and represent a byte as the
+  polynomial q, also with the lowest power in the most significant bit (so the
+  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+  where a mod b means the remainder after dividing a by b.
+
+  This calculation is done using the shift-register method of multiplying and
+  taking the remainder.  The register is initialized to zero, and for each
+  incoming bit, x^32 is added mod p to the register if the bit is a one (where
+  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+  x (which is shifting right by one and adding x^32 mod p if the bit shifted
+  out is a one).  We start with the highest power (least significant bit) of
+  q and repeat for all eight bits of q.
+
+  The table is simply the CRC of all possible eight bit values.  This is all
+  the information needed to generate CRC's on data a byte at a time for all
+  combinations of CRC register values and incoming bytes.
+*/
+local void make_crc_table()
+{
+  uLong c;
+  int n, k;
+  uLong poly;            /* polynomial exclusive-or pattern */
+  /* terms of polynomial defining this crc (except x^32): */
+  static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+  /* make exclusive-or pattern from polynomial (0xedb88320L) */
+  poly = 0L;
+  for (n = 0; n < sizeof(p)/sizeof(Byte); n++)
+    poly |= 1L << (31 - p[n]);
+ 
+  for (n = 0; n < 256; n++)
+  {
+    c = (uLong)n;
+    for (k = 0; k < 8; k++)
+      c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+    crc_table[n] = c;
+  }
+  crc_table_empty = 0;
+}
+#else
+/* ========================================================================
+ * Table of CRC-32's of all single-byte values (made by make_crc_table)
+ */
+local const uLongf crc_table[256] = {
+  0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
+  0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
+  0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
+  0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
+  0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
+  0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
+  0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
+  0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
+  0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
+  0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
+  0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
+  0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
+  0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
+  0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
+  0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
+  0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
+  0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
+  0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
+  0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
+  0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
+  0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
+  0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
+  0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
+  0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
+  0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
+  0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
+  0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
+  0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
+  0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
+  0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
+  0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
+  0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
+  0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
+  0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
+  0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
+  0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
+  0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
+  0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
+  0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
+  0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
+  0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
+  0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
+  0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
+  0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
+  0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
+  0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
+  0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
+  0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
+  0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
+  0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
+  0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
+  0x2d02ef8dL
+};
+#endif
+
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+const uLongf * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+  if (crc_table_empty) make_crc_table();
+#endif
+  return (const uLongf *)crc_table;
+}
+
+/* ========================================================================= */
+#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
+#define DO2(buf)  DO1(buf); DO1(buf);
+#define DO4(buf)  DO2(buf); DO2(buf);
+#define DO8(buf)  DO4(buf); DO4(buf);
+
+/* ========================================================================= */
+uLong ZEXPORT crc32(crc, buf, len)
+    uLong crc;
+    const Bytef *buf;
+    uInt len;
+{
+    if (buf == Z_NULL) return 0L;
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+      make_crc_table();
+#endif
+    crc = crc ^ 0xffffffffL;
+    while (len >= 8)
+    {
+      DO8(buf);
+      len -= 8;
+    }
+    if (len) do {
+      DO1(buf);
+    } while (--len);
+    return crc ^ 0xffffffffL;
+}
diff --git a/src/zlib/deflate.c b/src/zlib/deflate.c
new file mode 100644
index 0000000000..490813fe90
--- /dev/null
+++ b/src/zlib/deflate.c
@@ -0,0 +1,1348 @@
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process depends on being able to identify portions
+ *      of the input text which are identical to earlier input (within a
+ *      sliding window trailing behind the input currently being processed).
+ *
+ *      The most straightforward technique turns out to be the fastest for
+ *      most input files: try all possible matches and select the longest.
+ *      The key feature of this algorithm is that insertions into the string
+ *      dictionary are very simple and thus fast, and deletions are avoided
+ *      completely. Insertions are performed at each input character, whereas
+ *      string matches are performed only when the previous match ends. So it
+ *      is preferable to spend more time in matches to allow very fast string
+ *      insertions and avoid deletions. The matching algorithm for small
+ *      strings is inspired from that of Rabin & Karp. A brute force approach
+ *      is used to find longer strings when a small match has been found.
+ *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
+ *      (by Leonid Broukhis).
+ *         A previous version of this file used a more sophisticated algorithm
+ *      (by Fiala and Greene) which is guaranteed to run in linear amortized
+ *      time, but has a larger average cost, uses more memory and is patented.
+ *      However the F&G algorithm may be faster for some highly redundant
+ *      files if the parameter max_chain_length (described below) is too large.
+ *
+ *  ACKNOWLEDGEMENTS
+ *
+ *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
+ *      I found it in 'freeze' written by Leonid Broukhis.
+ *      Thanks to many people for bug reports and testing.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
+ *      Available in ftp://ds.internic.net/rfc/rfc1951.txt
+ *
+ *      A description of the Rabin and Karp algorithm is given in the book
+ *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
+ *
+ *      Fiala,E.R., and Greene,D.H.
+ *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
+ *
+ */
+
+/* @(#) $Id$ */
+
+#include "deflate.h"
+
+const char deflate_copyright[] =
+   " deflate 1.1.2 Copyright 1995-1998 Jean-loup Gailly ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+
+/* ===========================================================================
+ *  Function prototypes.
+ */
+typedef enum {
+    need_more,      /* block not completed, need more input or more output */
+    block_done,     /* block flush performed */
+    finish_started, /* finish started, need only more output at next deflate */
+    finish_done     /* finish done, accept no more input or output */
+} block_state;
+
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+/* Compression function. Returns the block state after the call. */
+
+local void fill_window    OF((deflate_state *s));
+local block_state deflate_stored OF((deflate_state *s, int flush));
+local block_state deflate_fast   OF((deflate_state *s, int flush));
+local block_state deflate_slow   OF((deflate_state *s, int flush));
+local void lm_init        OF((deflate_state *s));
+local void putShortMSB    OF((deflate_state *s, uInt b));
+local void flush_pending  OF((z_streamp strm));
+local int read_buf        OF((z_streamp strm, Bytef *buf, unsigned size));
+#ifdef ASMV
+      void match_init OF((void)); /* asm code initialization */
+      uInt longest_match  OF((deflate_state *s, IPos cur_match));
+#else
+local uInt longest_match  OF((deflate_state *s, IPos cur_match));
+#endif
+
+#ifdef DEBUG
+local  void check_match OF((deflate_state *s, IPos start, IPos match,
+                            int length));
+#endif
+
+/* ===========================================================================
+ * Local data
+ */
+
+#define NIL 0
+/* Tail of hash chains */
+
+#ifndef TOO_FAR
+#  define TOO_FAR 4096
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+typedef struct config_s {
+   ush good_length; /* reduce lazy search above this match length */
+   ush max_lazy;    /* do not perform lazy search above this match length */
+   ush nice_length; /* quit search above this match length */
+   ush max_chain;
+   compress_func func;
+} config;
+
+local const config configuration_table[10] = {
+/*      good lazy nice chain */
+/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
+/* 1 */ {4,    4,  8,    4, deflate_fast}, /* maximum speed, no lazy matches */
+/* 2 */ {4,    5, 16,    8, deflate_fast},
+/* 3 */ {4,    6, 32,   32, deflate_fast},
+
+/* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */
+/* 5 */ {8,   16, 32,   32, deflate_slow},
+/* 6 */ {8,   16, 128, 128, deflate_slow},
+/* 7 */ {8,   32, 128, 256, deflate_slow},
+/* 8 */ {32, 128, 258, 1024, deflate_slow},
+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
+
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
+ */
+
+#define EQUAL 0
+/* result of memcmp for equal strings */
+
+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
+ *    input characters, so that a running hash key can be computed from the
+ *    previous key instead of complete recalculation each time.
+ */
+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
+
+
+/* ===========================================================================
+ * Insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * If this file is compiled with -DFASTEST, the compression level is forced
+ * to 1, and no hash chains are maintained.
+ * IN  assertion: all calls to to INSERT_STRING are made with consecutive
+ *    input characters and the first MIN_MATCH bytes of str are valid
+ *    (except for the last MIN_MATCH-1 bytes of the input file).
+ */
+#ifdef FASTEST
+#define INSERT_STRING(s, str, match_head) \
+   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+    match_head = s->head[s->ins_h], \
+    s->head[s->ins_h] = (Pos)(str))
+#else
+#define INSERT_STRING(s, str, match_head) \
+   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+    s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
+    s->head[s->ins_h] = (Pos)(str))
+#endif
+
+/* ===========================================================================
+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
+ * prev[] will be initialized on the fly.
+ */
+#define CLEAR_HASH(s) \
+    s->head[s->hash_size-1] = NIL; \
+    zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+
+/* ========================================================================= */
+int ZEXPORT deflateInit_(strm, level, version, stream_size)
+    z_streamp strm;
+    int level;
+    const char *version;
+    int stream_size;
+{
+    return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
+			 Z_DEFAULT_STRATEGY, version, stream_size);
+    /* To do: ignore strm->next_in if we use it as window */
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+		  version, stream_size)
+    z_streamp strm;
+    int  level;
+    int  method;
+    int  windowBits;
+    int  memLevel;
+    int  strategy;
+    const char *version;
+    int stream_size;
+{
+    deflate_state *s;
+    int noheader = 0;
+    static const char* my_version = ZLIB_VERSION;
+
+    ushf *overlay;
+    /* We overlay pending_buf and d_buf+l_buf. This works since the average
+     * output size for (length,distance) codes is <= 24 bits.
+     */
+
+    if (version == Z_NULL || version[0] != my_version[0] ||
+        stream_size != sizeof(z_stream)) {
+	return Z_VERSION_ERROR;
+    }
+    if (strm == Z_NULL) return Z_STREAM_ERROR;
+
+    strm->msg = Z_NULL;
+    if (strm->zalloc == Z_NULL) {
+	strm->zalloc = zcalloc;
+	strm->opaque = (voidpf)0;
+    }
+    if (strm->zfree == Z_NULL) strm->zfree = zcfree;
+
+    if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#ifdef FASTEST
+    level = 1;
+#endif
+
+    if (windowBits < 0) { /* undocumented feature: suppress zlib header */
+        noheader = 1;
+        windowBits = -windowBits;
+    }
+    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
+        windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
+	strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
+        return Z_STREAM_ERROR;
+    }
+    s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
+    if (s == Z_NULL) return Z_MEM_ERROR;
+    strm->state = (struct internal_state FAR *)s;
+    s->strm = strm;
+
+    s->noheader = noheader;
+    s->w_bits = windowBits;
+    s->w_size = 1 << s->w_bits;
+    s->w_mask = s->w_size - 1;
+
+    s->hash_bits = memLevel + 7;
+    s->hash_size = 1 << s->hash_bits;
+    s->hash_mask = s->hash_size - 1;
+    s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
+
+    s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
+    s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos));
+    s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos));
+
+    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+    overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+    s->pending_buf = (uchf *) overlay;
+    s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+
+    if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
+        s->pending_buf == Z_NULL) {
+        strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
+        deflateEnd (strm);
+        return Z_MEM_ERROR;
+    }
+    s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+    s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+
+    s->level = level;
+    s->strategy = strategy;
+    s->method = (Byte)method;
+
+    return deflateReset(strm);
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
+    z_streamp strm;
+    const Bytef *dictionary;
+    uInt  dictLength;
+{
+    deflate_state *s;
+    uInt length = dictLength;
+    uInt n;
+    IPos hash_head = 0;
+
+    if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
+        strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
+
+    s = strm->state;
+    strm->adler = adler32(strm->adler, dictionary, dictLength);
+
+    if (length < MIN_MATCH) return Z_OK;
+    if (length > MAX_DIST(s)) {
+	length = MAX_DIST(s);
+#ifndef USE_DICT_HEAD
+	dictionary += dictLength - length; /* use the tail of the dictionary */
+#endif
+    }
+    zmemcpy(s->window, dictionary, length);
+    s->strstart = length;
+    s->block_start = (long)length;
+
+    /* Insert all strings in the hash table (except for the last two bytes).
+     * s->lookahead stays null, so s->ins_h will be recomputed at the next
+     * call of fill_window.
+     */
+    s->ins_h = s->window[0];
+    UPDATE_HASH(s, s->ins_h, s->window[1]);
+    for (n = 0; n <= length - MIN_MATCH; n++) {
+	INSERT_STRING(s, n, hash_head);
+    }
+    if (hash_head) hash_head = 0;  /* to make compiler happy */
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateReset (strm)
+    z_streamp strm;
+{
+    deflate_state *s;
+    
+    if (strm == Z_NULL || strm->state == Z_NULL ||
+        strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
+
+    strm->total_in = strm->total_out = 0;
+    strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
+    strm->data_type = Z_UNKNOWN;
+
+    s = (deflate_state *)strm->state;
+    s->pending = 0;
+    s->pending_out = s->pending_buf;
+
+    if (s->noheader < 0) {
+        s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
+    }
+    s->status = s->noheader ? BUSY_STATE : INIT_STATE;
+    strm->adler = 1;
+    s->last_flush = Z_NO_FLUSH;
+
+    _tr_init(s);
+    lm_init(s);
+
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateParams(strm, level, strategy)
+    z_streamp strm;
+    int level;
+    int strategy;
+{
+    deflate_state *s;
+    compress_func func;
+    int err = Z_OK;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = strm->state;
+
+    if (level == Z_DEFAULT_COMPRESSION) {
+	level = 6;
+    }
+    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
+	return Z_STREAM_ERROR;
+    }
+    func = configuration_table[s->level].func;
+
+    if (func != configuration_table[level].func && strm->total_in != 0) {
+	/* Flush the last buffer: */
+	err = deflate(strm, Z_PARTIAL_FLUSH);
+    }
+    if (s->level != level) {
+	s->level = level;
+	s->max_lazy_match   = configuration_table[level].max_lazy;
+	s->good_match       = configuration_table[level].good_length;
+	s->nice_match       = configuration_table[level].nice_length;
+	s->max_chain_length = configuration_table[level].max_chain;
+    }
+    s->strategy = strategy;
+    return err;
+}
+
+/* =========================================================================
+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
+ * IN assertion: the stream state is correct and there is enough room in
+ * pending_buf.
+ */
+local void putShortMSB (s, b)
+    deflate_state *s;
+    uInt b;
+{
+    put_byte(s, (Byte)(b >> 8));
+    put_byte(s, (Byte)(b & 0xff));
+}   
+
+/* =========================================================================
+ * Flush as much pending output as possible. All deflate() output goes
+ * through this function so some applications may wish to modify it
+ * to avoid allocating a large strm->next_out buffer and copying into it.
+ * (See also read_buf()).
+ */
+local void flush_pending(strm)
+    z_streamp strm;
+{
+    unsigned len = strm->state->pending;
+
+    if (len > strm->avail_out) len = strm->avail_out;
+    if (len == 0) return;
+
+    zmemcpy(strm->next_out, strm->state->pending_out, len);
+    strm->next_out  += len;
+    strm->state->pending_out  += len;
+    strm->total_out += len;
+    strm->avail_out  -= len;
+    strm->state->pending -= len;
+    if (strm->state->pending == 0) {
+        strm->state->pending_out = strm->state->pending_buf;
+    }
+}
+
+/* ========================================================================= */
+int ZEXPORT deflate (strm, flush)
+    z_streamp strm;
+    int flush;
+{
+    int old_flush; /* value of flush param for previous deflate call */
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL ||
+	flush > Z_FINISH || flush < 0) {
+        return Z_STREAM_ERROR;
+    }
+    s = strm->state;
+
+    if (strm->next_out == Z_NULL ||
+        (strm->next_in == Z_NULL && strm->avail_in != 0) ||
+	(s->status == FINISH_STATE && flush != Z_FINISH)) {
+        ERR_RETURN(strm, Z_STREAM_ERROR);
+    }
+    if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
+
+    s->strm = strm; /* just in case */
+    old_flush = s->last_flush;
+    s->last_flush = flush;
+
+    /* Write the zlib header */
+    if (s->status == INIT_STATE) {
+
+        uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+        uInt level_flags = (s->level-1) >> 1;
+
+        if (level_flags > 3) level_flags = 3;
+        header |= (level_flags << 6);
+	if (s->strstart != 0) header |= PRESET_DICT;
+        header += 31 - (header % 31);
+
+        s->status = BUSY_STATE;
+        putShortMSB(s, header);
+
+	/* Save the adler32 of the preset dictionary: */
+	if (s->strstart != 0) {
+	    putShortMSB(s, (uInt)(strm->adler >> 16));
+	    putShortMSB(s, (uInt)(strm->adler & 0xffff));
+	}
+	strm->adler = 1L;
+    }
+
+    /* Flush as much pending output as possible */
+    if (s->pending != 0) {
+        flush_pending(strm);
+        if (strm->avail_out == 0) {
+	    /* Since avail_out is 0, deflate will be called again with
+	     * more output space, but possibly with both pending and
+	     * avail_in equal to zero. There won't be anything to do,
+	     * but this is not an error situation so make sure we
+	     * return OK instead of BUF_ERROR at next call of deflate:
+             */
+	    s->last_flush = -1;
+	    return Z_OK;
+	}
+
+    /* Make sure there is something to do and avoid duplicate consecutive
+     * flushes. For repeated and useless calls with Z_FINISH, we keep
+     * returning Z_STREAM_END instead of Z_BUFF_ERROR.
+     */
+    } else if (strm->avail_in == 0 && flush <= old_flush &&
+	       flush != Z_FINISH) {
+        ERR_RETURN(strm, Z_BUF_ERROR);
+    }
+
+    /* User must not provide more input after the first FINISH: */
+    if (s->status == FINISH_STATE && strm->avail_in != 0) {
+        ERR_RETURN(strm, Z_BUF_ERROR);
+    }
+
+    /* Start a new block or continue the current one.
+     */
+    if (strm->avail_in != 0 || s->lookahead != 0 ||
+        (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
+        block_state bstate;
+
+	bstate = (*(configuration_table[s->level].func))(s, flush);
+
+        if (bstate == finish_started || bstate == finish_done) {
+            s->status = FINISH_STATE;
+        }
+        if (bstate == need_more || bstate == finish_started) {
+	    if (strm->avail_out == 0) {
+	        s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
+	    }
+	    return Z_OK;
+	    /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
+	     * of deflate should use the same flush parameter to make sure
+	     * that the flush is complete. So we don't have to output an
+	     * empty block here, this will be done at next call. This also
+	     * ensures that for a very small output buffer, we emit at most
+	     * one empty block.
+	     */
+	}
+        if (bstate == block_done) {
+            if (flush == Z_PARTIAL_FLUSH) {
+                _tr_align(s);
+            } else { /* FULL_FLUSH or SYNC_FLUSH */
+                _tr_stored_block(s, (char*)0, 0L, 0);
+                /* For a full flush, this empty block will be recognized
+                 * as a special marker by inflate_sync().
+                 */
+                if (flush == Z_FULL_FLUSH) {
+                    CLEAR_HASH(s);             /* forget history */
+                }
+            }
+            flush_pending(strm);
+	    if (strm->avail_out == 0) {
+	      s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+	      return Z_OK;
+	    }
+        }
+    }
+    Assert(strm->avail_out > 0, "bug2");
+
+    if (flush != Z_FINISH) return Z_OK;
+    if (s->noheader) return Z_STREAM_END;
+
+    /* Write the zlib trailer (adler32) */
+    putShortMSB(s, (uInt)(strm->adler >> 16));
+    putShortMSB(s, (uInt)(strm->adler & 0xffff));
+    flush_pending(strm);
+    /* If avail_out is zero, the application will call deflate again
+     * to flush the rest.
+     */
+    s->noheader = -1; /* write the trailer only once! */
+    return s->pending != 0 ? Z_OK : Z_STREAM_END;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateEnd (strm)
+    z_streamp strm;
+{
+    int status;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+
+    status = strm->state->status;
+    if (status != INIT_STATE && status != BUSY_STATE &&
+	status != FINISH_STATE) {
+      return Z_STREAM_ERROR;
+    }
+
+    /* Deallocate in reverse order of allocations: */
+    TRY_FREE(strm, strm->state->pending_buf);
+    TRY_FREE(strm, strm->state->head);
+    TRY_FREE(strm, strm->state->prev);
+    TRY_FREE(strm, strm->state->window);
+
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+
+    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+}
+
+/* =========================================================================
+ * Copy the source state to the destination state.
+ * To simplify the source, this is not supported for 16-bit MSDOS (which
+ * doesn't have enough memory anyway to duplicate compression states).
+ */
+int ZEXPORT deflateCopy (dest, source)
+    z_streamp dest;
+    z_streamp source;
+{
+#ifdef MAXSEG_64K
+    return Z_STREAM_ERROR;
+#else
+    deflate_state *ds;
+    deflate_state *ss;
+    ushf *overlay;
+
+    ss = source->state;
+
+    if (source == Z_NULL || dest == Z_NULL || ss == Z_NULL) {
+        return Z_STREAM_ERROR;
+    }
+    *dest = *source;
+
+    ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
+    if (ds == Z_NULL) return Z_MEM_ERROR;
+    dest->state = (struct internal_state FAR *) ds;
+    *ds = *ss;
+    ds->strm = dest;
+
+    ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
+    ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));
+    ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));
+    overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
+    ds->pending_buf = (uchf *) overlay;
+
+    if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
+        ds->pending_buf == Z_NULL) {
+        deflateEnd (dest);
+        return Z_MEM_ERROR;
+    }
+    /* following zmemcpy do not work for 16-bit MSDOS */
+    zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
+    zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
+    zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
+    zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
+
+    ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
+    ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
+    ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+
+    ds->l_desc.dyn_tree = ds->dyn_ltree;
+    ds->d_desc.dyn_tree = ds->dyn_dtree;
+    ds->bl_desc.dyn_tree = ds->bl_tree;
+
+    return Z_OK;
+#endif
+}
+
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read.  All deflate() input goes through
+ * this function so some applications may wish to modify it to avoid
+ * allocating a large strm->next_in buffer and copying from it.
+ * (See also flush_pending()).
+ */
+local int read_buf(strm, buf, size)
+    z_streamp strm;
+    Bytef *buf;
+    unsigned size;
+{
+    unsigned len = strm->avail_in;
+
+    if (len > size) len = size;
+    if (len == 0) return 0;
+
+    strm->avail_in  -= len;
+
+    if (!strm->state->noheader) {
+        strm->adler = adler32(strm->adler, strm->next_in, len);
+    }
+    zmemcpy(buf, strm->next_in, len);
+    strm->next_in  += len;
+    strm->total_in += len;
+
+    return (int)len;
+}
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init (s)
+    deflate_state *s;
+{
+    s->window_size = (ulg)2L*s->w_size;
+
+    CLEAR_HASH(s);
+
+    /* Set the default configuration parameters:
+     */
+    s->max_lazy_match   = configuration_table[s->level].max_lazy;
+    s->good_match       = configuration_table[s->level].good_length;
+    s->nice_match       = configuration_table[s->level].nice_length;
+    s->max_chain_length = configuration_table[s->level].max_chain;
+
+    s->strstart = 0;
+    s->block_start = 0L;
+    s->lookahead = 0;
+    s->match_length = s->prev_length = MIN_MATCH-1;
+    s->match_available = 0;
+    s->ins_h = 0;
+#ifdef ASMV
+    match_init(); /* initialize the asm code */
+#endif
+}
+
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ * OUT assertion: the match length is not greater than s->lookahead.
+ */
+#ifndef ASMV
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
+ * match.S. The code will be functionally equivalent.
+ */
+#ifndef FASTEST
+local uInt longest_match(s, cur_match)
+    deflate_state *s;
+    IPos cur_match;                             /* current match */
+{
+    unsigned chain_length = s->max_chain_length;/* max hash chain length */
+    register Bytef *scan = s->window + s->strstart; /* current string */
+    register Bytef *match;                       /* matched string */
+    register int len;                           /* length of current match */
+    int best_len = s->prev_length;              /* best match length so far */
+    int nice_match = s->nice_match;             /* stop if match long enough */
+    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+        s->strstart - (IPos)MAX_DIST(s) : NIL;
+    /* Stop when cur_match becomes <= limit. To simplify the code,
+     * we prevent matches with the string of window index 0.
+     */
+    Posf *prev = s->prev;
+    uInt wmask = s->w_mask;
+
+#ifdef UNALIGNED_OK
+    /* Compare two bytes at a time. Note: this is not always beneficial.
+     * Try with and without -DUNALIGNED_OK to check.
+     */
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
+    register ush scan_start = *(ushf*)scan;
+    register ush scan_end   = *(ushf*)(scan+best_len-1);
+#else
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+    register Byte scan_end1  = scan[best_len-1];
+    register Byte scan_end   = scan[best_len];
+#endif
+
+    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+     * It is easy to get rid of this optimization if necessary.
+     */
+    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+    /* Do not waste too much time if we already have a good match: */
+    if (s->prev_length >= s->good_match) {
+        chain_length >>= 2;
+    }
+    /* Do not look for matches beyond the end of the input. This is necessary
+     * to make deflate deterministic.
+     */
+    if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+    do {
+        Assert(cur_match < s->strstart, "no future");
+        match = s->window + cur_match;
+
+        /* Skip to next match if the match length cannot increase
+         * or if the match length is less than 2:
+         */
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+        /* This code assumes sizeof(unsigned short) == 2. Do not use
+         * UNALIGNED_OK if your compiler uses a different size.
+         */
+        if (*(ushf*)(match+best_len-1) != scan_end ||
+            *(ushf*)match != scan_start) continue;
+
+        /* It is not necessary to compare scan[2] and match[2] since they are
+         * always equal when the other bytes match, given that the hash keys
+         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
+         * strstart+3, +5, ... up to strstart+257. We check for insufficient
+         * lookahead only every 4th comparison; the 128th check will be made
+         * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
+         * necessary to put more guard bytes at the end of the window, or
+         * to check more often for insufficient lookahead.
+         */
+        Assert(scan[2] == match[2], "scan[2]?");
+        scan++, match++;
+        do {
+        } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 scan < strend);
+        /* The funny "do {}" generates better code on most compilers */
+
+        /* Here, scan <= window+strstart+257 */
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+        if (*scan == *match) scan++;
+
+        len = (MAX_MATCH - 1) - (int)(strend-scan);
+        scan = strend - (MAX_MATCH-1);
+
+#else /* UNALIGNED_OK */
+
+        if (match[best_len]   != scan_end  ||
+            match[best_len-1] != scan_end1 ||
+            *match            != *scan     ||
+            *++match          != scan[1])      continue;
+
+        /* The check at best_len-1 can be removed because it will be made
+         * again later. (This heuristic is not always a win.)
+         * It is not necessary to compare scan[2] and match[2] since they
+         * are always equal when the other bytes match, given that
+         * the hash keys are equal and that HASH_BITS >= 8.
+         */
+        scan += 2, match++;
+        Assert(*scan == *match, "match[2]?");
+
+        /* We check for insufficient lookahead only every 8th comparison;
+         * the 256th check will be made at strstart+258.
+         */
+        do {
+        } while (*++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 scan < strend);
+
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+        len = MAX_MATCH - (int)(strend - scan);
+        scan = strend - MAX_MATCH;
+
+#endif /* UNALIGNED_OK */
+
+        if (len > best_len) {
+            s->match_start = cur_match;
+            best_len = len;
+            if (len >= nice_match) break;
+#ifdef UNALIGNED_OK
+            scan_end = *(ushf*)(scan+best_len-1);
+#else
+            scan_end1  = scan[best_len-1];
+            scan_end   = scan[best_len];
+#endif
+        }
+    } while ((cur_match = prev[cur_match & wmask]) > limit
+             && --chain_length != 0);
+
+    if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+    return s->lookahead;
+}
+
+#else /* FASTEST */
+/* ---------------------------------------------------------------------------
+ * Optimized version for level == 1 only
+ */
+local uInt longest_match(s, cur_match)
+    deflate_state *s;
+    IPos cur_match;                             /* current match */
+{
+    register Bytef *scan = s->window + s->strstart; /* current string */
+    register Bytef *match;                       /* matched string */
+    register int len;                           /* length of current match */
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+
+    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+     * It is easy to get rid of this optimization if necessary.
+     */
+    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+    Assert(cur_match < s->strstart, "no future");
+
+    match = s->window + cur_match;
+
+    /* Return failure if the match length is less than 2:
+     */
+    if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
+
+    /* The check at best_len-1 can be removed because it will be made
+     * again later. (This heuristic is not always a win.)
+     * It is not necessary to compare scan[2] and match[2] since they
+     * are always equal when the other bytes match, given that
+     * the hash keys are equal and that HASH_BITS >= 8.
+     */
+    scan += 2, match += 2;
+    Assert(*scan == *match, "match[2]?");
+
+    /* We check for insufficient lookahead only every 8th comparison;
+     * the 256th check will be made at strstart+258.
+     */
+    do {
+    } while (*++scan == *++match && *++scan == *++match &&
+	     *++scan == *++match && *++scan == *++match &&
+	     *++scan == *++match && *++scan == *++match &&
+	     *++scan == *++match && *++scan == *++match &&
+	     scan < strend);
+
+    Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+    len = MAX_MATCH - (int)(strend - scan);
+
+    if (len < MIN_MATCH) return MIN_MATCH - 1;
+
+    s->match_start = cur_match;
+    return len <= s->lookahead ? len : s->lookahead;
+}
+#endif /* FASTEST */
+#endif /* ASMV */
+
+#ifdef DEBUG
+/* ===========================================================================
+ * Check that the match at match_start is indeed a match.
+ */
+local void check_match(s, start, match, length)
+    deflate_state *s;
+    IPos start, match;
+    int length;
+{
+    /* check that the match is indeed a match */
+    if (zmemcmp(s->window + match,
+                s->window + start, length) != EQUAL) {
+        fprintf(stderr, " start %u, match %u, length %d\n",
+		start, match, length);
+        do {
+	    fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
+	} while (--length != 0);
+        z_error("invalid match");
+    }
+    if (z_verbose > 1) {
+        fprintf(stderr,"\\[%d,%d]", start-match, length);
+        do { putc(s->window[start++], stderr); } while (--length != 0);
+    }
+}
+#else
+#  define check_match(s, start, match, length)
+#endif
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ *    At least one byte has been read, or avail_in == 0; reads are
+ *    performed for at least two bytes (required for the zip translate_eol
+ *    option -- not supported here).
+ */
+local void fill_window(s)
+    deflate_state *s;
+{
+    register unsigned n, m;
+    register Posf *p;
+    unsigned more;    /* Amount of free space at the end of the window. */
+    uInt wsize = s->w_size;
+
+    do {
+        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+        /* Deal with !@#$% 64K limit: */
+        if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+            more = wsize;
+
+        } else if (more == (unsigned)(-1)) {
+            /* Very unlikely, but possible on 16 bit machine if strstart == 0
+             * and lookahead == 1 (input done one byte at time)
+             */
+            more--;
+
+        /* If the window is almost full and there is insufficient lookahead,
+         * move the upper half to the lower one to make room in the upper half.
+         */
+        } else if (s->strstart >= wsize+MAX_DIST(s)) {
+
+            zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
+            s->match_start -= wsize;
+            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
+            s->block_start -= (long) wsize;
+
+            /* Slide the hash table (could be avoided with 32 bit values
+               at the expense of memory usage). We slide even when level == 0
+               to keep the hash table consistent if we switch back to level > 0
+               later. (Using level 0 permanently is not an optimal usage of
+               zlib, so we don't care about this pathological case.)
+             */
+	    n = s->hash_size;
+	    p = &s->head[n];
+	    do {
+		m = *--p;
+		*p = (Pos)(m >= wsize ? m-wsize : NIL);
+	    } while (--n);
+
+	    n = wsize;
+#ifndef FASTEST
+	    p = &s->prev[n];
+	    do {
+		m = *--p;
+		*p = (Pos)(m >= wsize ? m-wsize : NIL);
+		/* If n is not on any hash chain, prev[n] is garbage but
+		 * its value will never be used.
+		 */
+	    } while (--n);
+#endif
+            more += wsize;
+        }
+        if (s->strm->avail_in == 0) return;
+
+        /* If there was no sliding:
+         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+         *    more == window_size - lookahead - strstart
+         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+         * => more >= window_size - 2*WSIZE + 2
+         * In the BIG_MEM or MMAP case (not yet supported),
+         *   window_size == input_size + MIN_LOOKAHEAD  &&
+         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+         * Otherwise, window_size == 2*WSIZE so more >= 2.
+         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+         */
+        Assert(more >= 2, "more < 2");
+
+        n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
+        s->lookahead += n;
+
+        /* Initialize the hash value now that we have some input: */
+        if (s->lookahead >= MIN_MATCH) {
+            s->ins_h = s->window[s->strstart];
+            UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+            Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+        }
+        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+         * but this is not important since only literal bytes will be emitted.
+         */
+
+    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+}
+
+/* ===========================================================================
+ * Flush the current block, with given end-of-file flag.
+ * IN assertion: strstart is set to the end of the current match.
+ */
+#define FLUSH_BLOCK_ONLY(s, eof) { \
+   _tr_flush_block(s, (s->block_start >= 0L ? \
+                   (charf *)&s->window[(unsigned)s->block_start] : \
+                   (charf *)Z_NULL), \
+		(ulg)((long)s->strstart - s->block_start), \
+		(eof)); \
+   s->block_start = s->strstart; \
+   flush_pending(s->strm); \
+   Tracev((stderr,"[FLUSH]")); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, eof) { \
+   FLUSH_BLOCK_ONLY(s, eof); \
+   if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
+}
+
+/* ===========================================================================
+ * Copy without compression as much as possible from the input stream, return
+ * the current block state.
+ * This function does not insert new strings in the dictionary since
+ * uncompressible data is probably not useful. This function is used
+ * only for the level=0 compression option.
+ * NOTE: this function should be optimized to avoid extra copying from
+ * window to pending_buf.
+ */
+local block_state deflate_stored(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
+     * to pending_buf_size, and each stored block has a 5 byte header:
+     */
+    ulg max_block_size = 0xffff;
+    ulg max_start;
+
+    if (max_block_size > s->pending_buf_size - 5) {
+        max_block_size = s->pending_buf_size - 5;
+    }
+
+    /* Copy as much as possible from input to output: */
+    for (;;) {
+        /* Fill the window as much as possible: */
+        if (s->lookahead <= 1) {
+
+            Assert(s->strstart < s->w_size+MAX_DIST(s) ||
+		   s->block_start >= (long)s->w_size, "slide too late");
+
+            fill_window(s);
+            if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
+
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+	Assert(s->block_start >= 0L, "block gone");
+
+	s->strstart += s->lookahead;
+	s->lookahead = 0;
+
+	/* Emit a stored block if pending_buf will be full: */
+ 	max_start = s->block_start + max_block_size;
+        if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
+	    /* strstart == 0 is possible when wraparound on 16-bit machine */
+	    s->lookahead = (uInt)(s->strstart - max_start);
+	    s->strstart = (uInt)max_start;
+            FLUSH_BLOCK(s, 0);
+	}
+	/* Flush if we may have to slide, otherwise block_start may become
+         * negative and the data will be gone:
+         */
+        if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
+            FLUSH_BLOCK(s, 0);
+	}
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return the current
+ * block state.
+ * This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+local block_state deflate_fast(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head = NIL; /* head of the hash chain */
+    int bflush;           /* set if current block must be flushed */
+
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+	        return need_more;
+	    }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         * At this point we have always match_length < MIN_MATCH
+         */
+        if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            if (s->strategy != Z_HUFFMAN_ONLY) {
+                s->match_length = longest_match (s, hash_head);
+            }
+            /* longest_match() sets match_start */
+        }
+        if (s->match_length >= MIN_MATCH) {
+            check_match(s, s->strstart, s->match_start, s->match_length);
+
+            _tr_tally_dist(s, s->strstart - s->match_start,
+                           s->match_length - MIN_MATCH, bflush);
+
+            s->lookahead -= s->match_length;
+
+            /* Insert new strings in the hash table only if the match length
+             * is not too large. This saves time but degrades compression.
+             */
+#ifndef FASTEST
+            if (s->match_length <= s->max_insert_length &&
+                s->lookahead >= MIN_MATCH) {
+                s->match_length--; /* string at strstart already in hash table */
+                do {
+                    s->strstart++;
+                    INSERT_STRING(s, s->strstart, hash_head);
+                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+                     * always MIN_MATCH bytes ahead.
+                     */
+                } while (--s->match_length != 0);
+                s->strstart++; 
+            } else
+#endif
+	    {
+                s->strstart += s->match_length;
+                s->match_length = 0;
+                s->ins_h = s->window[s->strstart];
+                UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+                Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+                /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
+                 * matter since it will be recomputed at next deflate call.
+                 */
+            }
+        } else {
+            /* No match, output a literal byte */
+            Tracevv((stderr,"%c", s->window[s->strstart]));
+            _tr_tally_lit (s, s->window[s->strstart], bflush);
+            s->lookahead--;
+            s->strstart++; 
+        }
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ */
+local block_state deflate_slow(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head = NIL;    /* head of hash chain */
+    int bflush;              /* set if current block must be flushed */
+
+    /* Process the input block. */
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+	        return need_more;
+	    }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         */
+        s->prev_length = s->match_length, s->prev_match = s->match_start;
+        s->match_length = MIN_MATCH-1;
+
+        if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+            s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            if (s->strategy != Z_HUFFMAN_ONLY) {
+                s->match_length = longest_match (s, hash_head);
+            }
+            /* longest_match() sets match_start */
+
+            if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
+                 (s->match_length == MIN_MATCH &&
+                  s->strstart - s->match_start > TOO_FAR))) {
+
+                /* If prev_match is also MIN_MATCH, match_start is garbage
+                 * but we will ignore the current match anyway.
+                 */
+                s->match_length = MIN_MATCH-1;
+            }
+        }
+        /* If there was a match at the previous step and the current
+         * match is not better, output the previous match:
+         */
+        if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
+            uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
+            /* Do not insert strings in hash table beyond this. */
+
+            check_match(s, s->strstart-1, s->prev_match, s->prev_length);
+
+            _tr_tally_dist(s, s->strstart -1 - s->prev_match,
+			   s->prev_length - MIN_MATCH, bflush);
+
+            /* Insert in hash table all strings up to the end of the match.
+             * strstart-1 and strstart are already inserted. If there is not
+             * enough lookahead, the last two strings are not inserted in
+             * the hash table.
+             */
+            s->lookahead -= s->prev_length-1;
+            s->prev_length -= 2;
+            do {
+                if (++s->strstart <= max_insert) {
+                    INSERT_STRING(s, s->strstart, hash_head);
+                }
+            } while (--s->prev_length != 0);
+            s->match_available = 0;
+            s->match_length = MIN_MATCH-1;
+            s->strstart++;
+
+            if (bflush) FLUSH_BLOCK(s, 0);
+
+        } else if (s->match_available) {
+            /* If there was no match at the previous position, output a
+             * single literal. If there was a match but the current match
+             * is longer, truncate the previous match to a single literal.
+             */
+            Tracevv((stderr,"%c", s->window[s->strstart-1]));
+	    _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+	    if (bflush) {
+                FLUSH_BLOCK_ONLY(s, 0);
+            }
+            s->strstart++;
+            s->lookahead--;
+            if (s->strm->avail_out == 0) return need_more;
+        } else {
+            /* There is no previous match to compare with, wait for
+             * the next step to decide.
+             */
+            s->match_available = 1;
+            s->strstart++;
+            s->lookahead--;
+        }
+    }
+    Assert (flush != Z_NO_FLUSH, "no flush?");
+    if (s->match_available) {
+        Tracevv((stderr,"%c", s->window[s->strstart-1]));
+        _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+        s->match_available = 0;
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
diff --git a/src/zlib/deflate.h b/src/zlib/deflate.h
new file mode 100644
index 0000000000..04830164dd
--- /dev/null
+++ b/src/zlib/deflate.h
@@ -0,0 +1,318 @@
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995-1998 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef _DEFLATE_H
+#define _DEFLATE_H
+
+#include "zutil.h"
+
+/* ===========================================================================
+ * Internal compression state.
+ */
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS  256
+/* number of literal bytes 0..255 */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES   30
+/* number of distance codes */
+
+#define BL_CODES  19
+/* number of codes used to transfer the bit lengths */
+
+#define HEAP_SIZE (2*L_CODES+1)
+/* maximum heap size */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define INIT_STATE    42
+#define BUSY_STATE   113
+#define FINISH_STATE 666
+/* Stream status */
+
+
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data_s {
+    union {
+        ush  freq;       /* frequency count */
+        ush  code;       /* bit string */
+    } fc;
+    union {
+        ush  dad;        /* father node in Huffman tree */
+        ush  len;        /* length of bit string */
+    } dl;
+} FAR ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad  dl.dad
+#define Len  dl.len
+
+typedef struct static_tree_desc_s  static_tree_desc;
+
+typedef struct tree_desc_s {
+    ct_data *dyn_tree;           /* the dynamic tree */
+    int     max_code;            /* largest code with non zero frequency */
+    static_tree_desc *stat_desc; /* the corresponding static tree */
+} FAR tree_desc;
+
+typedef ush Pos;
+typedef Pos FAR Posf;
+typedef unsigned IPos;
+
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+typedef struct internal_state {
+    z_streamp strm;      /* pointer back to this zlib stream */
+    int   status;        /* as the name implies */
+    Bytef *pending_buf;  /* output still pending */
+    ulg   pending_buf_size; /* size of pending_buf */
+    Bytef *pending_out;  /* next pending byte to output to the stream */
+    int   pending;       /* nb of bytes in the pending buffer */
+    int   noheader;      /* suppress zlib header and adler32 */
+    Byte  data_type;     /* UNKNOWN, BINARY or ASCII */
+    Byte  method;        /* STORED (for zip only) or DEFLATED */
+    int   last_flush;    /* value of flush param for previous deflate call */
+
+                /* used by deflate.c: */
+
+    uInt  w_size;        /* LZ77 window size (32K by default) */
+    uInt  w_bits;        /* log2(w_size)  (8..16) */
+    uInt  w_mask;        /* w_size - 1 */
+
+    Bytef *window;
+    /* Sliding window. Input bytes are read into the second half of the window,
+     * and move to the first half later to keep a dictionary of at least wSize
+     * bytes. With this organization, matches are limited to a distance of
+     * wSize-MAX_MATCH bytes, but this ensures that IO is always
+     * performed with a length multiple of the block size. Also, it limits
+     * the window size to 64K, which is quite useful on MSDOS.
+     * To do: use the user input buffer as sliding window.
+     */
+
+    ulg window_size;
+    /* Actual size of window: 2*wSize, except when the user input buffer
+     * is directly used as sliding window.
+     */
+
+    Posf *prev;
+    /* Link to older string with same hash index. To limit the size of this
+     * array to 64K, this link is maintained only for the last 32K strings.
+     * An index in this array is thus a window index modulo 32K.
+     */
+
+    Posf *head; /* Heads of the hash chains or NIL. */
+
+    uInt  ins_h;          /* hash index of string to be inserted */
+    uInt  hash_size;      /* number of elements in hash table */
+    uInt  hash_bits;      /* log2(hash_size) */
+    uInt  hash_mask;      /* hash_size-1 */
+
+    uInt  hash_shift;
+    /* Number of bits by which ins_h must be shifted at each input
+     * step. It must be such that after MIN_MATCH steps, the oldest
+     * byte no longer takes part in the hash key, that is:
+     *   hash_shift * MIN_MATCH >= hash_bits
+     */
+
+    long block_start;
+    /* Window position at the beginning of the current output block. Gets
+     * negative when the window is moved backwards.
+     */
+
+    uInt match_length;           /* length of best match */
+    IPos prev_match;             /* previous match */
+    int match_available;         /* set if previous match exists */
+    uInt strstart;               /* start of string to insert */
+    uInt match_start;            /* start of matching string */
+    uInt lookahead;              /* number of valid bytes ahead in window */
+
+    uInt prev_length;
+    /* Length of the best match at previous step. Matches not greater than this
+     * are discarded. This is used in the lazy match evaluation.
+     */
+
+    uInt max_chain_length;
+    /* To speed up deflation, hash chains are never searched beyond this
+     * length.  A higher limit improves compression ratio but degrades the
+     * speed.
+     */
+
+    uInt max_lazy_match;
+    /* Attempt to find a better match only when the current match is strictly
+     * smaller than this value. This mechanism is used only for compression
+     * levels >= 4.
+     */
+#   define max_insert_length  max_lazy_match
+    /* Insert new strings in the hash table only if the match length is not
+     * greater than this length. This saves time but degrades compression.
+     * max_insert_length is used only for compression levels <= 3.
+     */
+
+    int level;    /* compression level (1..9) */
+    int strategy; /* favor or force Huffman coding*/
+
+    uInt good_match;
+    /* Use a faster search when the previous match is longer than this */
+
+    int nice_match; /* Stop searching when current match exceeds this */
+
+                /* used by trees.c: */
+    /* Didn't use ct_data typedef below to supress compiler warning */
+    struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
+    struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+    struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
+
+    struct tree_desc_s l_desc;               /* desc. for literal tree */
+    struct tree_desc_s d_desc;               /* desc. for distance tree */
+    struct tree_desc_s bl_desc;              /* desc. for bit length tree */
+
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
+    int heap_len;               /* number of elements in the heap */
+    int heap_max;               /* element of largest frequency */
+    /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+     * The same heap array is used to build all trees.
+     */
+
+    uch depth[2*L_CODES+1];
+    /* Depth of each subtree used as tie breaker for trees of equal frequency
+     */
+
+    uchf *l_buf;          /* buffer for literals or lengths */
+
+    uInt  lit_bufsize;
+    /* Size of match buffer for literals/lengths.  There are 4 reasons for
+     * limiting lit_bufsize to 64K:
+     *   - frequencies can be kept in 16 bit counters
+     *   - if compression is not successful for the first block, all input
+     *     data is still in the window so we can still emit a stored block even
+     *     when input comes from standard input.  (This can also be done for
+     *     all blocks if lit_bufsize is not greater than 32K.)
+     *   - if compression is not successful for a file smaller than 64K, we can
+     *     even emit a stored file instead of a stored block (saving 5 bytes).
+     *     This is applicable only for zip (not gzip or zlib).
+     *   - creating new Huffman trees less frequently may not provide fast
+     *     adaptation to changes in the input data statistics. (Take for
+     *     example a binary file with poorly compressible code followed by
+     *     a highly compressible string table.) Smaller buffer sizes give
+     *     fast adaptation but have of course the overhead of transmitting
+     *     trees more frequently.
+     *   - I can't count above 4
+     */
+
+    uInt last_lit;      /* running index in l_buf */
+
+    ushf *d_buf;
+    /* Buffer for distances. To simplify the code, d_buf and l_buf have
+     * the same number of elements. To use different lengths, an extra flag
+     * array would be necessary.
+     */
+
+    ulg opt_len;        /* bit length of current block with optimal trees */
+    ulg static_len;     /* bit length of current block with static trees */
+    ulg compressed_len; /* total bit length of compressed file */
+    uInt matches;       /* number of string matches in current block */
+    int last_eob_len;   /* bit length of EOB code for last block */
+
+#ifdef DEBUG
+    ulg bits_sent;      /* bit length of the compressed data */
+#endif
+
+    ush bi_buf;
+    /* Output buffer. bits are inserted starting at the bottom (least
+     * significant bits).
+     */
+    int bi_valid;
+    /* Number of valid bits in bi_buf.  All bits above the last valid bit
+     * are always zero.
+     */
+
+} FAR deflate_state;
+
+/* Output a byte on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
+
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST(s)  ((s)->w_size-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+        /* in trees.c */
+void _tr_init         OF((deflate_state *s));
+int  _tr_tally        OF((deflate_state *s, unsigned dist, unsigned lc));
+ulg  _tr_flush_block  OF((deflate_state *s, charf *buf, ulg stored_len,
+			  int eof));
+void _tr_align        OF((deflate_state *s));
+void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
+                          int eof));
+
+#define d_code(dist) \
+   ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
+ * used.
+ */
+
+#ifndef DEBUG
+/* Inline versions of _tr_tally for speed: */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+  extern uch _length_code[];
+  extern uch _dist_code[];
+#else
+  extern const uch _length_code[];
+  extern const uch _dist_code[];
+#endif
+
+# define _tr_tally_lit(s, c, flush) \
+  { uch cc = (c); \
+    s->d_buf[s->last_lit] = 0; \
+    s->l_buf[s->last_lit++] = cc; \
+    s->dyn_ltree[cc].Freq++; \
+    flush = (s->last_lit == s->lit_bufsize-1); \
+   }
+# define _tr_tally_dist(s, distance, length, flush) \
+  { uch len = (length); \
+    ush dist = (distance); \
+    s->d_buf[s->last_lit] = dist; \
+    s->l_buf[s->last_lit++] = len; \
+    dist--; \
+    s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
+    s->dyn_dtree[d_code(dist)].Freq++; \
+    flush = (s->last_lit == s->lit_bufsize-1); \
+  }
+#else
+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
+# define _tr_tally_dist(s, distance, length, flush) \
+              flush = _tr_tally(s, distance, length) 
+#endif
+
+#endif
diff --git a/src/zlib/descrip.mms b/src/zlib/descrip.mms
new file mode 100644
index 0000000000..9d364598a2
--- /dev/null
+++ b/src/zlib/descrip.mms
@@ -0,0 +1,48 @@
+# descrip.mms: MMS description file for building zlib on VMS
+# written by Martin P.J. Zinser <m.zinser@gsi.de>
+
+cc_defs = 
+c_deb = 
+
+.ifdef __DECC__
+pref = /prefix=all
+.endif
+
+OBJS = adler32.obj, compress.obj, crc32.obj, gzio.obj, uncompr.obj,\
+       deflate.obj, trees.obj, zutil.obj, inflate.obj, infblock.obj,\
+       inftrees.obj, infcodes.obj, infutil.obj, inffast.obj
+
+CFLAGS= $(C_DEB) $(CC_DEFS) $(PREF)
+
+all : example.exe minigzip.exe
+        @ write sys$output " Example applications available"
+libz.olb : libz.olb($(OBJS))
+	@ write sys$output " libz available"
+
+example.exe : example.obj libz.olb
+              link example,libz.olb/lib
+
+minigzip.exe : minigzip.obj libz.olb
+              link minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib
+
+clean : 
+	delete *.obj;*,libz.olb;*
+
+
+# Other dependencies.
+adler32.obj : zutil.h zlib.h zconf.h
+compress.obj : zlib.h zconf.h
+crc32.obj : zutil.h zlib.h zconf.h
+deflate.obj : deflate.h zutil.h zlib.h zconf.h
+example.obj : zlib.h zconf.h
+gzio.obj : zutil.h zlib.h zconf.h
+infblock.obj : zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
+infcodes.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h
+inffast.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
+inflate.obj : zutil.h zlib.h zconf.h infblock.h
+inftrees.obj : zutil.h zlib.h zconf.h inftrees.h
+infutil.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h
+minigzip.obj : zlib.h zconf.h
+trees.obj : deflate.h zutil.h zlib.h zconf.h
+uncompr.obj : zlib.h zconf.h
+zutil.obj : zutil.h zlib.h zconf.h
diff --git a/src/zlib/example.c b/src/zlib/example.c
new file mode 100644
index 0000000000..073ce76b33
--- /dev/null
+++ b/src/zlib/example.c
@@ -0,0 +1,550 @@
+/* example.c -- usage example of the zlib compression library
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* @(#) $Id$ */
+
+#include <stdio.h>
+#include "zlib.h"
+
+#ifdef STDC
+#  include <string.h>
+#  include <stdlib.h>
+#else
+   extern void exit  OF((int));
+#endif
+
+#define CHECK_ERR(err, msg) { \
+    if (err != Z_OK) { \
+        fprintf(stderr, "%s error: %d\n", msg, err); \
+        exit(1); \
+    } \
+}
+
+const char hello[] = "hello, hello!";
+/* "hello world" would be more standard, but the repeated "hello"
+ * stresses the compression code better, sorry...
+ */
+
+const char dictionary[] = "hello";
+uLong dictId; /* Adler32 value of the dictionary */
+
+void test_compress      OF((Byte *compr, uLong comprLen,
+		            Byte *uncompr, uLong uncomprLen));
+void test_gzio          OF((const char *out, const char *in, 
+		            Byte *uncompr, int uncomprLen));
+void test_deflate       OF((Byte *compr, uLong comprLen));
+void test_inflate       OF((Byte *compr, uLong comprLen,
+		            Byte *uncompr, uLong uncomprLen));
+void test_large_deflate OF((Byte *compr, uLong comprLen,
+		            Byte *uncompr, uLong uncomprLen));
+void test_large_inflate OF((Byte *compr, uLong comprLen,
+		            Byte *uncompr, uLong uncomprLen));
+void test_flush         OF((Byte *compr, uLong *comprLen));
+void test_sync          OF((Byte *compr, uLong comprLen,
+		            Byte *uncompr, uLong uncomprLen));
+void test_dict_deflate  OF((Byte *compr, uLong comprLen));
+void test_dict_inflate  OF((Byte *compr, uLong comprLen,
+		            Byte *uncompr, uLong uncomprLen));
+int  main               OF((int argc, char *argv[]));
+
+/* ===========================================================================
+ * Test compress() and uncompress()
+ */
+void test_compress(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    uLong len = strlen(hello)+1;
+
+    err = compress(compr, &comprLen, (const Bytef*)hello, len);
+    CHECK_ERR(err, "compress");
+
+    strcpy((char*)uncompr, "garbage");
+
+    err = uncompress(uncompr, &uncomprLen, compr, comprLen);
+    CHECK_ERR(err, "uncompress");
+
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad uncompress\n");
+	exit(1);
+    } else {
+        printf("uncompress(): %s\n", (char *)uncompr);
+    }
+}
+
+/* ===========================================================================
+ * Test read/write of .gz files
+ */
+void test_gzio(out, in, uncompr, uncomprLen)
+    const char *out; /* output file */
+    const char *in;  /* input file */
+    Byte *uncompr;
+    int  uncomprLen;
+{
+    int err;
+    int len = strlen(hello)+1;
+    gzFile file;
+    z_off_t pos;
+
+    file = gzopen(out, "wb");
+    if (file == NULL) {
+        fprintf(stderr, "gzopen error\n");
+        exit(1);
+    }
+    gzputc(file, 'h');
+    if (gzputs(file, "ello") != 4) {
+        fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
+	exit(1);
+    }
+    if (gzprintf(file, ", %s!", "hello") != 8) {
+        fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
+	exit(1);
+    }
+    gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
+    gzclose(file);
+
+    file = gzopen(in, "rb");
+    if (file == NULL) {
+        fprintf(stderr, "gzopen error\n");
+    }
+    strcpy((char*)uncompr, "garbage");
+
+    uncomprLen = gzread(file, uncompr, (unsigned)uncomprLen);
+    if (uncomprLen != len) {
+        fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
+	exit(1);
+    }
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
+	exit(1);
+    } else {
+        printf("gzread(): %s\n", (char *)uncompr);
+    }
+
+    pos = gzseek(file, -8L, SEEK_CUR);
+    if (pos != 6 || gztell(file) != pos) {
+	fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
+		(long)pos, (long)gztell(file));
+	exit(1);
+    }
+
+    if (gzgetc(file) != ' ') {
+	fprintf(stderr, "gzgetc error\n");
+	exit(1);
+    }
+
+    gzgets(file, (char*)uncompr, uncomprLen);
+    uncomprLen = strlen((char*)uncompr);
+    if (uncomprLen != 6) { /* "hello!" */
+        fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
+	exit(1);
+    }
+    if (strcmp((char*)uncompr, hello+7)) {
+        fprintf(stderr, "bad gzgets after gzseek\n");
+	exit(1);
+    } else {
+        printf("gzgets() after gzseek: %s\n", (char *)uncompr);
+    }
+
+    gzclose(file);
+}
+
+/* ===========================================================================
+ * Test deflate() with small buffers
+ */
+void test_deflate(compr, comprLen)
+    Byte *compr;
+    uLong comprLen;
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+    int len = strlen(hello)+1;
+
+    c_stream.zalloc = (alloc_func)0;
+    c_stream.zfree = (free_func)0;
+    c_stream.opaque = (voidpf)0;
+
+    err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+    CHECK_ERR(err, "deflateInit");
+
+    c_stream.next_in  = (Bytef*)hello;
+    c_stream.next_out = compr;
+
+    while (c_stream.total_in != (uLong)len && c_stream.total_out < comprLen) {
+        c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
+        err = deflate(&c_stream, Z_NO_FLUSH);
+        CHECK_ERR(err, "deflate");
+    }
+    /* Finish the stream, still forcing small buffers: */
+    for (;;) {
+        c_stream.avail_out = 1;
+        err = deflate(&c_stream, Z_FINISH);
+        if (err == Z_STREAM_END) break;
+        CHECK_ERR(err, "deflate");
+    }
+
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with small buffers
+ */
+void test_inflate(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = (alloc_func)0;
+    d_stream.zfree = (free_func)0;
+    d_stream.opaque = (voidpf)0;
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = 0;
+    d_stream.next_out = uncompr;
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
+        d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
+        err = inflate(&d_stream, Z_NO_FLUSH);
+        if (err == Z_STREAM_END) break;
+        CHECK_ERR(err, "inflate");
+    }
+
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad inflate\n");
+	exit(1);
+    } else {
+        printf("inflate(): %s\n", (char *)uncompr);
+    }
+}
+
+/* ===========================================================================
+ * Test deflate() with large buffers and dynamic change of compression level
+ */
+void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+
+    c_stream.zalloc = (alloc_func)0;
+    c_stream.zfree = (free_func)0;
+    c_stream.opaque = (voidpf)0;
+
+    err = deflateInit(&c_stream, Z_BEST_SPEED);
+    CHECK_ERR(err, "deflateInit");
+
+    c_stream.next_out = compr;
+    c_stream.avail_out = (uInt)comprLen;
+
+    /* At this point, uncompr is still mostly zeroes, so it should compress
+     * very well:
+     */
+    c_stream.next_in = uncompr;
+    c_stream.avail_in = (uInt)uncomprLen;
+    err = deflate(&c_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, "deflate");
+    if (c_stream.avail_in != 0) {
+        fprintf(stderr, "deflate not greedy\n");
+	exit(1);
+    }
+
+    /* Feed in already compressed data and switch to no compression: */
+    deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
+    c_stream.next_in = compr;
+    c_stream.avail_in = (uInt)comprLen/2;
+    err = deflate(&c_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, "deflate");
+
+    /* Switch back to compressing mode: */
+    deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
+    c_stream.next_in = uncompr;
+    c_stream.avail_in = (uInt)uncomprLen;
+    err = deflate(&c_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, "deflate");
+
+    err = deflate(&c_stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        fprintf(stderr, "deflate should report Z_STREAM_END\n");
+	exit(1);
+    }
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with large buffers
+ */
+void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = (alloc_func)0;
+    d_stream.zfree = (free_func)0;
+    d_stream.opaque = (voidpf)0;
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = (uInt)comprLen;
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    for (;;) {
+        d_stream.next_out = uncompr;            /* discard the output */
+	d_stream.avail_out = (uInt)uncomprLen;
+        err = inflate(&d_stream, Z_NO_FLUSH);
+        if (err == Z_STREAM_END) break;
+        CHECK_ERR(err, "large inflate");
+    }
+
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
+        fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
+	exit(1);
+    } else {
+        printf("large_inflate(): OK\n");
+    }
+}
+
+/* ===========================================================================
+ * Test deflate() with full flush
+ */
+void test_flush(compr, comprLen)
+    Byte *compr;
+    uLong *comprLen;
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+    int len = strlen(hello)+1;
+
+    c_stream.zalloc = (alloc_func)0;
+    c_stream.zfree = (free_func)0;
+    c_stream.opaque = (voidpf)0;
+
+    err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+    CHECK_ERR(err, "deflateInit");
+
+    c_stream.next_in  = (Bytef*)hello;
+    c_stream.next_out = compr;
+    c_stream.avail_in = 3;
+    c_stream.avail_out = (uInt)*comprLen;
+    err = deflate(&c_stream, Z_FULL_FLUSH);
+    CHECK_ERR(err, "deflate");
+
+    compr[3]++; /* force an error in first compressed block */
+    c_stream.avail_in = len - 3;
+
+    err = deflate(&c_stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        CHECK_ERR(err, "deflate");
+    }
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+
+    *comprLen = c_stream.total_out;
+}
+
+/* ===========================================================================
+ * Test inflateSync()
+ */
+void test_sync(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = (alloc_func)0;
+    d_stream.zfree = (free_func)0;
+    d_stream.opaque = (voidpf)0;
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = 2; /* just read the zlib header */
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    d_stream.next_out = uncompr;
+    d_stream.avail_out = (uInt)uncomprLen;
+
+    inflate(&d_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, "inflate");
+
+    d_stream.avail_in = (uInt)comprLen-2;   /* read all compressed data */
+    err = inflateSync(&d_stream);           /* but skip the damaged part */
+    CHECK_ERR(err, "inflateSync");
+
+    err = inflate(&d_stream, Z_FINISH);
+    if (err != Z_DATA_ERROR) {
+        fprintf(stderr, "inflate should report DATA_ERROR\n");
+        /* Because of incorrect adler32 */
+	exit(1);
+    }
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    printf("after inflateSync(): hel%s\n", (char *)uncompr);
+}
+
+/* ===========================================================================
+ * Test deflate() with preset dictionary
+ */
+void test_dict_deflate(compr, comprLen)
+    Byte *compr;
+    uLong comprLen;
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+
+    c_stream.zalloc = (alloc_func)0;
+    c_stream.zfree = (free_func)0;
+    c_stream.opaque = (voidpf)0;
+
+    err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
+    CHECK_ERR(err, "deflateInit");
+
+    err = deflateSetDictionary(&c_stream,
+			       (const Bytef*)dictionary, sizeof(dictionary));
+    CHECK_ERR(err, "deflateSetDictionary");
+
+    dictId = c_stream.adler;
+    c_stream.next_out = compr;
+    c_stream.avail_out = (uInt)comprLen;
+
+    c_stream.next_in = (Bytef*)hello;
+    c_stream.avail_in = (uInt)strlen(hello)+1;
+
+    err = deflate(&c_stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        fprintf(stderr, "deflate should report Z_STREAM_END\n");
+	exit(1);
+    }
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with a preset dictionary
+ */
+void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = (alloc_func)0;
+    d_stream.zfree = (free_func)0;
+    d_stream.opaque = (voidpf)0;
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = (uInt)comprLen;
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    d_stream.next_out = uncompr;
+    d_stream.avail_out = (uInt)uncomprLen;
+
+    for (;;) {
+        err = inflate(&d_stream, Z_NO_FLUSH);
+        if (err == Z_STREAM_END) break;
+	if (err == Z_NEED_DICT) {
+	    if (d_stream.adler != dictId) {
+		fprintf(stderr, "unexpected dictionary");
+		exit(1);
+	    }
+	    err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
+				       sizeof(dictionary));
+	}
+        CHECK_ERR(err, "inflate with dict");
+    }
+
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad inflate with dict\n");
+	exit(1);
+    } else {
+        printf("inflate with dictionary: %s\n", (char *)uncompr);
+    }
+}
+
+/* ===========================================================================
+ * Usage:  example [output.gz  [input.gz]]
+ */
+
+int main(argc, argv)
+    int argc;
+    char *argv[];
+{
+    Byte *compr, *uncompr;
+    uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
+    uLong uncomprLen = comprLen;
+    static const char* myVersion = ZLIB_VERSION;
+
+    if (zlibVersion()[0] != myVersion[0]) {
+        fprintf(stderr, "incompatible zlib version\n");
+        exit(1);
+
+    } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
+        fprintf(stderr, "warning: different zlib version\n");
+    }
+
+    compr    = (Byte*)calloc((uInt)comprLen, 1);
+    uncompr  = (Byte*)calloc((uInt)uncomprLen, 1);
+    /* compr and uncompr are cleared to avoid reading uninitialized
+     * data and to ensure that uncompr compresses well.
+     */
+    if (compr == Z_NULL || uncompr == Z_NULL) {
+        printf("out of memory\n");
+	exit(1);
+    }
+    test_compress(compr, comprLen, uncompr, uncomprLen);
+
+    test_gzio((argc > 1 ? argv[1] : "foo.gz"),
+              (argc > 2 ? argv[2] : "foo.gz"),
+	      uncompr, (int)uncomprLen);
+
+    test_deflate(compr, comprLen);
+    test_inflate(compr, comprLen, uncompr, uncomprLen);
+
+    test_large_deflate(compr, comprLen, uncompr, uncomprLen);
+    test_large_inflate(compr, comprLen, uncompr, uncomprLen);
+
+    test_flush(compr, &comprLen);
+    test_sync(compr, comprLen, uncompr, uncomprLen);
+    comprLen = uncomprLen;
+
+    test_dict_deflate(compr, comprLen);
+    test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
+
+    exit(0);
+    return 0; /* to avoid warning */
+}
diff --git a/src/zlib/gzio.c b/src/zlib/gzio.c
new file mode 100644
index 0000000000..e29198ac7a
--- /dev/null
+++ b/src/zlib/gzio.c
@@ -0,0 +1,869 @@
+/* gzio.c -- IO on .gz files
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Compile this file with -DNO_DEFLATE to avoid the compression code.
+ */
+
+/* @(#) $Id$ */
+
+#include <stdio.h>
+
+#include "zutil.h"
+
+struct internal_state {int dummy;}; /* for buggy compilers */
+
+#ifndef Z_BUFSIZE
+#  ifdef MAXSEG_64K
+#    define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
+#  else
+#    define Z_BUFSIZE 16384
+#  endif
+#endif
+#ifndef Z_PRINTF_BUFSIZE
+#  define Z_PRINTF_BUFSIZE 4096
+#endif
+
+#define ALLOC(size) malloc(size)
+#define TRYFREE(p) {if (p) free(p);}
+
+static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
+#define HEAD_CRC     0x02 /* bit 1 set: header CRC present */
+#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
+#define COMMENT      0x10 /* bit 4 set: file comment present */
+#define RESERVED     0xE0 /* bits 5..7: reserved */
+
+typedef struct gz_stream {
+    z_stream stream;
+    int      z_err;   /* error code for last stream operation */
+    int      z_eof;   /* set if end of input file */
+    FILE     *file;   /* .gz file */
+    Byte     *inbuf;  /* input buffer */
+    Byte     *outbuf; /* output buffer */
+    uLong    crc;     /* crc32 of uncompressed data */
+    char     *msg;    /* error message */
+    char     *path;   /* path name for debugging only */
+    int      transparent; /* 1 if input file is not a .gz file */
+    char     mode;    /* 'w' or 'r' */
+    long     startpos; /* start of compressed data in file (header skipped) */
+} gz_stream;
+
+
+local gzFile gz_open      OF((const char *path, const char *mode, int  fd));
+local int do_flush        OF((gzFile file, int flush));
+local int    get_byte     OF((gz_stream *s));
+local void   check_header OF((gz_stream *s));
+local int    destroy      OF((gz_stream *s));
+local void   putLong      OF((FILE *file, uLong x));
+local uLong  getLong      OF((gz_stream *s));
+
+/* ===========================================================================
+     Opens a gzip (.gz) file for reading or writing. The mode parameter
+   is as in fopen ("rb" or "wb"). The file is given either by file descriptor
+   or path name (if fd == -1).
+     gz_open return NULL if the file could not be opened or if there was
+   insufficient memory to allocate the (de)compression state; errno
+   can be checked to distinguish the two cases (if errno is zero, the
+   zlib error is Z_MEM_ERROR).
+*/
+local gzFile gz_open (path, mode, fd)
+    const char *path;
+    const char *mode;
+    int  fd;
+{
+    int err;
+    int level = Z_DEFAULT_COMPRESSION; /* compression level */
+    int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
+    char *p = (char*)mode;
+    gz_stream *s;
+    char fmode[80]; /* copy of mode, without the compression level */
+    char *m = fmode;
+
+    if (!path || !mode) return Z_NULL;
+
+    s = (gz_stream *)ALLOC(sizeof(gz_stream));
+    if (!s) return Z_NULL;
+
+    s->stream.zalloc = (alloc_func)0;
+    s->stream.zfree = (free_func)0;
+    s->stream.opaque = (voidpf)0;
+    s->stream.next_in = s->inbuf = Z_NULL;
+    s->stream.next_out = s->outbuf = Z_NULL;
+    s->stream.avail_in = s->stream.avail_out = 0;
+    s->file = NULL;
+    s->z_err = Z_OK;
+    s->z_eof = 0;
+    s->crc = crc32(0L, Z_NULL, 0);
+    s->msg = NULL;
+    s->transparent = 0;
+
+    s->path = (char*)ALLOC(strlen(path)+1);
+    if (s->path == NULL) {
+        return destroy(s), (gzFile)Z_NULL;
+    }
+    strcpy(s->path, path); /* do this early for debugging */
+
+    s->mode = '\0';
+    do {
+        if (*p == 'r') s->mode = 'r';
+        if (*p == 'w' || *p == 'a') s->mode = 'w';
+        if (*p >= '0' && *p <= '9') {
+	    level = *p - '0';
+	} else if (*p == 'f') {
+	  strategy = Z_FILTERED;
+	} else if (*p == 'h') {
+	  strategy = Z_HUFFMAN_ONLY;
+	} else {
+	    *m++ = *p; /* copy the mode */
+	}
+    } while (*p++ && m != fmode + sizeof(fmode));
+    if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
+    
+    if (s->mode == 'w') {
+#ifdef NO_DEFLATE
+        err = Z_STREAM_ERROR;
+#else
+        err = deflateInit2(&(s->stream), level,
+                           Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
+        /* windowBits is passed < 0 to suppress zlib header */
+
+        s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
+#endif
+        if (err != Z_OK || s->outbuf == Z_NULL) {
+            return destroy(s), (gzFile)Z_NULL;
+        }
+    } else {
+        s->stream.next_in  = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
+
+        err = inflateInit2(&(s->stream), -MAX_WBITS);
+        /* windowBits is passed < 0 to tell that there is no zlib header.
+         * Note that in this case inflate *requires* an extra "dummy" byte
+         * after the compressed stream in order to complete decompression and
+         * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
+         * present after the compressed stream.
+         */
+        if (err != Z_OK || s->inbuf == Z_NULL) {
+            return destroy(s), (gzFile)Z_NULL;
+        }
+    }
+    s->stream.avail_out = Z_BUFSIZE;
+
+    errno = 0;
+    s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
+
+    if (s->file == NULL) {
+        return destroy(s), (gzFile)Z_NULL;
+    }
+    if (s->mode == 'w') {
+        /* Write a very simple .gz header:
+         */
+        fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
+             Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
+	s->startpos = 10L;
+	/* We use 10L instead of ftell(s->file) to because ftell causes an
+         * fflush on some systems. This version of the library doesn't use
+         * startpos anyway in write mode, so this initialization is not
+         * necessary.
+         */
+    } else {
+	check_header(s); /* skip the .gz header */
+	s->startpos = (ftell(s->file) - s->stream.avail_in);
+    }
+    
+    return (gzFile)s;
+}
+
+/* ===========================================================================
+     Opens a gzip (.gz) file for reading or writing.
+*/
+gzFile ZEXPORT gzopen (path, mode)
+    const char *path;
+    const char *mode;
+{
+    return gz_open (path, mode, -1);
+}
+
+/* ===========================================================================
+     Associate a gzFile with the file descriptor fd. fd is not dup'ed here
+   to mimic the behavio(u)r of fdopen.
+*/
+gzFile ZEXPORT gzdopen (fd, mode)
+    int fd;
+    const char *mode;
+{
+    char name[20];
+
+    if (fd < 0) return (gzFile)Z_NULL;
+    sprintf(name, "<fd:%d>", fd); /* for debugging */
+
+    return gz_open (name, mode, fd);
+}
+
+/* ===========================================================================
+ * Update the compression level and strategy
+ */
+int ZEXPORT gzsetparams (file, level, strategy)
+    gzFile file;
+    int level;
+    int strategy;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+    /* Make room to allow flushing */
+    if (s->stream.avail_out == 0) {
+
+	s->stream.next_out = s->outbuf;
+	if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
+	    s->z_err = Z_ERRNO;
+	}
+	s->stream.avail_out = Z_BUFSIZE;
+    }
+
+    return deflateParams (&(s->stream), level, strategy);
+}
+
+/* ===========================================================================
+     Read a byte from a gz_stream; update next_in and avail_in. Return EOF
+   for end of file.
+   IN assertion: the stream s has been sucessfully opened for reading.
+*/
+local int get_byte(s)
+    gz_stream *s;
+{
+    if (s->z_eof) return EOF;
+    if (s->stream.avail_in == 0) {
+	errno = 0;
+	s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+	if (s->stream.avail_in == 0) {
+	    s->z_eof = 1;
+	    if (ferror(s->file)) s->z_err = Z_ERRNO;
+	    return EOF;
+	}
+	s->stream.next_in = s->inbuf;
+    }
+    s->stream.avail_in--;
+    return *(s->stream.next_in)++;
+}
+
+/* ===========================================================================
+      Check the gzip header of a gz_stream opened for reading. Set the stream
+    mode to transparent if the gzip magic header is not present; set s->err
+    to Z_DATA_ERROR if the magic header is present but the rest of the header
+    is incorrect.
+    IN assertion: the stream s has already been created sucessfully;
+       s->stream.avail_in is zero for the first time, but may be non-zero
+       for concatenated .gz files.
+*/
+local void check_header(s)
+    gz_stream *s;
+{
+    int method; /* method byte */
+    int flags;  /* flags byte */
+    uInt len;
+    int c;
+
+    /* Check the gzip magic header */
+    for (len = 0; len < 2; len++) {
+	c = get_byte(s);
+	if (c != gz_magic[len]) {
+	    if (len != 0) s->stream.avail_in++, s->stream.next_in--;
+	    if (c != EOF) {
+		s->stream.avail_in++, s->stream.next_in--;
+		s->transparent = 1;
+	    }
+	    s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END;
+	    return;
+	}
+    }
+    method = get_byte(s);
+    flags = get_byte(s);
+    if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
+	s->z_err = Z_DATA_ERROR;
+	return;
+    }
+
+    /* Discard time, xflags and OS code: */
+    for (len = 0; len < 6; len++) (void)get_byte(s);
+
+    if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
+	len  =  (uInt)get_byte(s);
+	len += ((uInt)get_byte(s))<<8;
+	/* len is garbage if EOF but the loop below will quit anyway */
+	while (len-- != 0 && get_byte(s) != EOF) ;
+    }
+    if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
+	while ((c = get_byte(s)) != 0 && c != EOF) ;
+    }
+    if ((flags & COMMENT) != 0) {   /* skip the .gz file comment */
+	while ((c = get_byte(s)) != 0 && c != EOF) ;
+    }
+    if ((flags & HEAD_CRC) != 0) {  /* skip the header crc */
+	for (len = 0; len < 2; len++) (void)get_byte(s);
+    }
+    s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
+}
+
+ /* ===========================================================================
+ * Cleanup then free the given gz_stream. Return a zlib error code.
+   Try freeing in the reverse order of allocations.
+ */
+local int destroy (s)
+    gz_stream *s;
+{
+    int err = Z_OK;
+
+    if (!s) return Z_STREAM_ERROR;
+
+    TRYFREE(s->msg);
+
+    if (s->stream.state != NULL) {
+	if (s->mode == 'w') {
+#ifdef NO_DEFLATE
+	    err = Z_STREAM_ERROR;
+#else
+	    err = deflateEnd(&(s->stream));
+#endif
+	} else if (s->mode == 'r') {
+	    err = inflateEnd(&(s->stream));
+	}
+    }
+    if (s->file != NULL && fclose(s->file)) {
+#ifdef ESPIPE
+	if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
+#endif
+	    err = Z_ERRNO;
+    }
+    if (s->z_err < 0) err = s->z_err;
+
+    TRYFREE(s->inbuf);
+    TRYFREE(s->outbuf);
+    TRYFREE(s->path);
+    TRYFREE(s);
+    return err;
+}
+
+/* ===========================================================================
+     Reads the given number of uncompressed bytes from the compressed file.
+   gzread returns the number of bytes actually read (0 for end of file).
+*/
+int ZEXPORT gzread (file, buf, len)
+    gzFile file;
+    voidp buf;
+    unsigned len;
+{
+    gz_stream *s = (gz_stream*)file;
+    Bytef *start = (Bytef*)buf; /* starting point for crc computation */
+    Byte  *next_out; /* == stream.next_out but not forced far (for MSDOS) */
+
+    if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
+
+    if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
+    if (s->z_err == Z_STREAM_END) return 0;  /* EOF */
+
+    next_out = (Byte*)buf;
+    s->stream.next_out = (Bytef*)buf;
+    s->stream.avail_out = len;
+
+    while (s->stream.avail_out != 0) {
+
+	if (s->transparent) {
+	    /* Copy first the lookahead bytes: */
+	    uInt n = s->stream.avail_in;
+	    if (n > s->stream.avail_out) n = s->stream.avail_out;
+	    if (n > 0) {
+		zmemcpy(s->stream.next_out, s->stream.next_in, n);
+		next_out += n;
+		s->stream.next_out = next_out;
+		s->stream.next_in   += n;
+		s->stream.avail_out -= n;
+		s->stream.avail_in  -= n;
+	    }
+	    if (s->stream.avail_out > 0) {
+		s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out,
+					     s->file);
+	    }
+	    len -= s->stream.avail_out;
+	    s->stream.total_in  += (uLong)len;
+	    s->stream.total_out += (uLong)len;
+            if (len == 0) s->z_eof = 1;
+	    return (int)len;
+	}
+        if (s->stream.avail_in == 0 && !s->z_eof) {
+
+            errno = 0;
+            s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+            if (s->stream.avail_in == 0) {
+                s->z_eof = 1;
+		if (ferror(s->file)) {
+		    s->z_err = Z_ERRNO;
+		    break;
+		}
+            }
+            s->stream.next_in = s->inbuf;
+        }
+        s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
+
+	if (s->z_err == Z_STREAM_END) {
+	    /* Check CRC and original size */
+	    s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
+	    start = s->stream.next_out;
+
+	    if (getLong(s) != s->crc || getLong(s) != s->stream.total_out) {
+		s->z_err = Z_DATA_ERROR;
+	    } else {
+		/* Check for concatenated .gz files: */
+		check_header(s);
+		if (s->z_err == Z_OK) {
+		    uLong total_in = s->stream.total_in;
+		    uLong total_out = s->stream.total_out;
+
+		    inflateReset(&(s->stream));
+		    s->stream.total_in = total_in;
+		    s->stream.total_out = total_out;
+		    s->crc = crc32(0L, Z_NULL, 0);
+		}
+	    }
+	}
+	if (s->z_err != Z_OK || s->z_eof) break;
+    }
+    s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
+
+    return (int)(len - s->stream.avail_out);
+}
+
+
+/* ===========================================================================
+      Reads one byte from the compressed file. gzgetc returns this byte
+   or -1 in case of end of file or error.
+*/
+int ZEXPORT gzgetc(file)
+    gzFile file;
+{
+    unsigned char c;
+
+    return gzread(file, &c, 1) == 1 ? c : -1;
+}
+
+
+/* ===========================================================================
+      Reads bytes from the compressed file until len-1 characters are
+   read, or a newline character is read and transferred to buf, or an
+   end-of-file condition is encountered.  The string is then terminated
+   with a null character.
+      gzgets returns buf, or Z_NULL in case of error.
+
+      The current implementation is not optimized at all.
+*/
+char * ZEXPORT gzgets(file, buf, len)
+    gzFile file;
+    char *buf;
+    int len;
+{
+    char *b = buf;
+    if (buf == Z_NULL || len <= 0) return Z_NULL;
+
+    while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
+    *buf = '\0';
+    return b == buf && len > 0 ? Z_NULL : b;
+}
+
+
+#ifndef NO_DEFLATE
+/* ===========================================================================
+     Writes the given number of uncompressed bytes into the compressed file.
+   gzwrite returns the number of bytes actually written (0 in case of error).
+*/
+int ZEXPORT gzwrite (file, buf, len)
+    gzFile file;
+    const voidp buf;
+    unsigned len;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+    s->stream.next_in = (Bytef*)buf;
+    s->stream.avail_in = len;
+
+    while (s->stream.avail_in != 0) {
+
+        if (s->stream.avail_out == 0) {
+
+            s->stream.next_out = s->outbuf;
+            if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
+                s->z_err = Z_ERRNO;
+                break;
+            }
+            s->stream.avail_out = Z_BUFSIZE;
+        }
+        s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
+        if (s->z_err != Z_OK) break;
+    }
+    s->crc = crc32(s->crc, (const Bytef *)buf, len);
+
+    return (int)(len - s->stream.avail_in);
+}
+
+/* ===========================================================================
+     Converts, formats, and writes the args to the compressed file under
+   control of the format string, as in fprintf. gzprintf returns the number of
+   uncompressed bytes actually written (0 in case of error).
+*/
+#ifdef STDC
+#include <stdarg.h>
+
+int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
+{
+    char buf[Z_PRINTF_BUFSIZE];
+    va_list va;
+    int len;
+
+    va_start(va, format);
+#ifdef HAS_vsnprintf
+    (void)vsnprintf(buf, sizeof(buf), format, va);
+#else
+    (void)vsprintf(buf, format, va);
+#endif
+    va_end(va);
+    len = strlen(buf); /* some *sprintf don't return the nb of bytes written */
+    if (len <= 0) return 0;
+
+    return gzwrite(file, buf, (unsigned)len);
+}
+#else /* not ANSI C */
+
+int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+	               a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
+    gzFile file;
+    const char *format;
+    int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+	a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
+{
+    char buf[Z_PRINTF_BUFSIZE];
+    int len;
+
+#ifdef HAS_snprintf
+    snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
+	     a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+#else
+    sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
+	    a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+#endif
+    len = strlen(buf); /* old sprintf doesn't return the nb of bytes written */
+    if (len <= 0) return 0;
+
+    return gzwrite(file, buf, len);
+}
+#endif
+
+/* ===========================================================================
+      Writes c, converted to an unsigned char, into the compressed file.
+   gzputc returns the value that was written, or -1 in case of error.
+*/
+int ZEXPORT gzputc(file, c)
+    gzFile file;
+    int c;
+{
+    unsigned char cc = (unsigned char) c; /* required for big endian systems */
+
+    return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
+}
+
+
+/* ===========================================================================
+      Writes the given null-terminated string to the compressed file, excluding
+   the terminating null character.
+      gzputs returns the number of characters written, or -1 in case of error.
+*/
+int ZEXPORT gzputs(file, s)
+    gzFile file;
+    const char *s;
+{
+    return gzwrite(file, (char*)s, (unsigned)strlen(s));
+}
+
+
+/* ===========================================================================
+     Flushes all pending output into the compressed file. The parameter
+   flush is as in the deflate() function.
+*/
+local int do_flush (file, flush)
+    gzFile file;
+    int flush;
+{
+    uInt len;
+    int done = 0;
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+    s->stream.avail_in = 0; /* should be zero already anyway */
+
+    for (;;) {
+        len = Z_BUFSIZE - s->stream.avail_out;
+
+        if (len != 0) {
+            if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
+                s->z_err = Z_ERRNO;
+                return Z_ERRNO;
+            }
+            s->stream.next_out = s->outbuf;
+            s->stream.avail_out = Z_BUFSIZE;
+        }
+        if (done) break;
+        s->z_err = deflate(&(s->stream), flush);
+
+	/* Ignore the second of two consecutive flushes: */
+	if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
+
+        /* deflate has finished flushing only when it hasn't used up
+         * all the available space in the output buffer: 
+         */
+        done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
+ 
+        if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
+    }
+    return  s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
+}
+
+int ZEXPORT gzflush (file, flush)
+     gzFile file;
+     int flush;
+{
+    gz_stream *s = (gz_stream*)file;
+    int err = do_flush (file, flush);
+
+    if (err) return err;
+    fflush(s->file);
+    return  s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
+}
+#endif /* NO_DEFLATE */
+
+/* ===========================================================================
+      Sets the starting position for the next gzread or gzwrite on the given
+   compressed file. The offset represents a number of bytes in the
+      gzseek returns the resulting offset location as measured in bytes from
+   the beginning of the uncompressed stream, or -1 in case of error.
+      SEEK_END is not implemented, returns error.
+      In this version of the library, gzseek can be extremely slow.
+*/
+z_off_t ZEXPORT gzseek (file, offset, whence)
+    gzFile file;
+    z_off_t offset;
+    int whence;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || whence == SEEK_END ||
+	s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
+	return -1L;
+    }
+    
+    if (s->mode == 'w') {
+#ifdef NO_DEFLATE
+	return -1L;
+#else
+	if (whence == SEEK_SET) {
+	    offset -= s->stream.total_out;
+	}
+	if (offset < 0) return -1L;
+
+	/* At this point, offset is the number of zero bytes to write. */
+	if (s->inbuf == Z_NULL) {
+	    s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
+	    zmemzero(s->inbuf, Z_BUFSIZE);
+	}
+	while (offset > 0)  {
+	    uInt size = Z_BUFSIZE;
+	    if (offset < Z_BUFSIZE) size = (uInt)offset;
+
+	    size = gzwrite(file, s->inbuf, size);
+	    if (size == 0) return -1L;
+
+	    offset -= size;
+	}
+	return (z_off_t)s->stream.total_in;
+#endif
+    }
+    /* Rest of function is for reading only */
+
+    /* compute absolute position */
+    if (whence == SEEK_CUR) {
+	offset += s->stream.total_out;
+    }
+    if (offset < 0) return -1L;
+
+    if (s->transparent) {
+	/* map to fseek */
+	s->stream.avail_in = 0;
+	s->stream.next_in = s->inbuf;
+        if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
+
+	s->stream.total_in = s->stream.total_out = (uLong)offset;
+	return offset;
+    }
+
+    /* For a negative seek, rewind and use positive seek */
+    if ((uLong)offset >= s->stream.total_out) {
+	offset -= s->stream.total_out;
+    } else if (gzrewind(file) < 0) {
+	return -1L;
+    }
+    /* offset is now the number of bytes to skip. */
+
+    if (offset != 0 && s->outbuf == Z_NULL) {
+	s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
+    }
+    while (offset > 0)  {
+	int size = Z_BUFSIZE;
+	if (offset < Z_BUFSIZE) size = (int)offset;
+
+	size = gzread(file, s->outbuf, (uInt)size);
+	if (size <= 0) return -1L;
+	offset -= size;
+    }
+    return (z_off_t)s->stream.total_out;
+}
+
+/* ===========================================================================
+     Rewinds input file. 
+*/
+int ZEXPORT gzrewind (file)
+    gzFile file;
+{
+    gz_stream *s = (gz_stream*)file;
+    
+    if (s == NULL || s->mode != 'r') return -1;
+
+    s->z_err = Z_OK;
+    s->z_eof = 0;
+    s->stream.avail_in = 0;
+    s->stream.next_in = s->inbuf;
+	
+    if (s->startpos == 0) { /* not a compressed file */
+	rewind(s->file);
+	return 0;
+    }
+
+    (void) inflateReset(&s->stream);
+    return fseek(s->file, s->startpos, SEEK_SET);
+}
+
+/* ===========================================================================
+     Returns the starting position for the next gzread or gzwrite on the
+   given compressed file. This position represents a number of bytes in the
+   uncompressed data stream.
+*/
+z_off_t ZEXPORT gztell (file)
+    gzFile file;
+{
+    return gzseek(file, 0L, SEEK_CUR);
+}
+
+/* ===========================================================================
+     Returns 1 when EOF has previously been detected reading the given
+   input stream, otherwise zero.
+*/
+int ZEXPORT gzeof (file)
+    gzFile file;
+{
+    gz_stream *s = (gz_stream*)file;
+    
+    return (s == NULL || s->mode != 'r') ? 0 : s->z_eof;
+}
+
+/* ===========================================================================
+   Outputs a long in LSB order to the given file
+*/
+local void putLong (file, x)
+    FILE *file;
+    uLong x;
+{
+    int n;
+    for (n = 0; n < 4; n++) {
+        fputc((int)(x & 0xff), file);
+        x >>= 8;
+    }
+}
+
+/* ===========================================================================
+   Reads a long in LSB order from the given gz_stream. Sets 
+*/
+local uLong getLong (s)
+    gz_stream *s;
+{
+    uLong x = (uLong)get_byte(s);
+    int c;
+
+    x += ((uLong)get_byte(s))<<8;
+    x += ((uLong)get_byte(s))<<16;
+    c = get_byte(s);
+    if (c == EOF) s->z_err = Z_DATA_ERROR;
+    x += ((uLong)c)<<24;
+    return x;
+}
+
+/* ===========================================================================
+     Flushes all pending output if necessary, closes the compressed file
+   and deallocates all the (de)compression state.
+*/
+int ZEXPORT gzclose (file)
+    gzFile file;
+{
+    int err;
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL) return Z_STREAM_ERROR;
+
+    if (s->mode == 'w') {
+#ifdef NO_DEFLATE
+	return Z_STREAM_ERROR;
+#else
+        err = do_flush (file, Z_FINISH);
+        if (err != Z_OK) return destroy((gz_stream*)file);
+
+        putLong (s->file, s->crc);
+        putLong (s->file, s->stream.total_in);
+#endif
+    }
+    return destroy((gz_stream*)file);
+}
+
+/* ===========================================================================
+     Returns the error message for the last error which occured on the
+   given compressed file. errnum is set to zlib error number. If an
+   error occured in the file system and not in the compression library,
+   errnum is set to Z_ERRNO and the application may consult errno
+   to get the exact error code.
+*/
+const char*  ZEXPORT gzerror (file, errnum)
+    gzFile file;
+    int *errnum;
+{
+    char *m;
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL) {
+        *errnum = Z_STREAM_ERROR;
+        return (const char*)ERR_MSG(Z_STREAM_ERROR);
+    }
+    *errnum = s->z_err;
+    if (*errnum == Z_OK) return (const char*)"";
+
+    m =  (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
+
+    if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
+
+    TRYFREE(s->msg);
+    s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
+    strcpy(s->msg, s->path);
+    strcat(s->msg, ": ");
+    strcat(s->msg, m);
+    return (const char*)s->msg;
+}
diff --git a/src/zlib/infblock.c b/src/zlib/infblock.c
new file mode 100644
index 0000000000..f8940c7fab
--- /dev/null
+++ b/src/zlib/infblock.c
@@ -0,0 +1,405 @@
+/* infblock.c -- interpret and process block types to last block
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include "zutil.h"
+#include "infblock.h"
+#include "inftrees.h"
+#include "infcodes.h"
+#include "infutil.h"
+
+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+/* Table for deflate from PKZIP's appnote.txt. */
+local const uInt border[] = { /* Order of the bit length code lengths */
+        16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+/*
+   Notes beyond the 1.93a appnote.txt:
+
+   1. Distance pointers never point before the beginning of the output
+      stream.
+   2. Distance pointers can point back across blocks, up to 32k away.
+   3. There is an implied maximum of 7 bits for the bit length table and
+      15 bits for the actual data.
+   4. If only one code exists, then it is encoded using one bit.  (Zero
+      would be more efficient, but perhaps a little confusing.)  If two
+      codes exist, they are coded using one bit each (0 and 1).
+   5. There is no way of sending zero distance codes--a dummy must be
+      sent if there are none.  (History: a pre 2.0 version of PKZIP would
+      store blocks with no distance codes, but this was discovered to be
+      too harsh a criterion.)  Valid only for 1.93a.  2.04c does allow
+      zero distance codes, which is sent as one code of zero bits in
+      length.
+   6. There are up to 286 literal/length codes.  Code 256 represents the
+      end-of-block.  Note however that the static length tree defines
+      288 codes just to fill out the Huffman codes.  Codes 286 and 287
+      cannot be used though, since there is no length base or extra bits
+      defined for them.  Similarily, there are up to 30 distance codes.
+      However, static trees define 32 codes (all 5 bits) to fill out the
+      Huffman codes, but the last two had better not show up in the data.
+   7. Unzip can check dynamic Huffman blocks for complete code sets.
+      The exception is that a single code would not be complete (see #4).
+   8. The five bits following the block type is really the number of
+      literal codes sent minus 257.
+   9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
+      (1+6+6).  Therefore, to output three times the length, you output
+      three codes (1+1+1), whereas to output four times the same length,
+      you only need two codes (1+3).  Hmm.
+  10. In the tree reconstruction algorithm, Code = Code + Increment
+      only if BitLength(i) is not zero.  (Pretty obvious.)
+  11. Correction: 4 Bits: # of Bit Length codes - 4     (4 - 19)
+  12. Note: length code 284 can represent 227-258, but length code 285
+      really is 258.  The last length deserves its own, short code
+      since it gets used a lot in very redundant files.  The length
+      258 is special since 258 - 3 (the min match length) is 255.
+  13. The literal/length and distance code bit lengths are read as a
+      single stream of lengths.  It is possible (and advantageous) for
+      a repeat code (16, 17, or 18) to go across the boundary between
+      the two sets of lengths.
+ */
+
+
+void inflate_blocks_reset(s, z, c)
+inflate_blocks_statef *s;
+z_streamp z;
+uLongf *c;
+{
+  if (c != Z_NULL)
+    *c = s->check;
+  if (s->mode == BTREE || s->mode == DTREE)
+    ZFREE(z, s->sub.trees.blens);
+  if (s->mode == CODES)
+    inflate_codes_free(s->sub.decode.codes, z);
+  s->mode = TYPE;
+  s->bitk = 0;
+  s->bitb = 0;
+  s->read = s->write = s->window;
+  if (s->checkfn != Z_NULL)
+    z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
+  Tracev((stderr, "inflate:   blocks reset\n"));
+}
+
+
+inflate_blocks_statef *inflate_blocks_new(z, c, w)
+z_streamp z;
+check_func c;
+uInt w;
+{
+  inflate_blocks_statef *s;
+
+  if ((s = (inflate_blocks_statef *)ZALLOC
+       (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
+    return s;
+  if ((s->hufts =
+       (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
+  {
+    ZFREE(z, s);
+    return Z_NULL;
+  }
+  if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
+  {
+    ZFREE(z, s->hufts);
+    ZFREE(z, s);
+    return Z_NULL;
+  }
+  s->end = s->window + w;
+  s->checkfn = c;
+  s->mode = TYPE;
+  Tracev((stderr, "inflate:   blocks allocated\n"));
+  inflate_blocks_reset(s, z, Z_NULL);
+  return s;
+}
+
+
+int inflate_blocks(s, z, r)
+inflate_blocks_statef *s;
+z_streamp z;
+int r;
+{
+  uInt t;               /* temporary storage */
+  uLong b;              /* bit buffer */
+  uInt k;               /* bits in bit buffer */
+  Bytef *p;             /* input data pointer */
+  uInt n;               /* bytes available there */
+  Bytef *q;             /* output window write pointer */
+  uInt m;               /* bytes to end of window or read pointer */
+
+  /* copy input/output information to locals (UPDATE macro restores) */
+  LOAD
+
+  /* process input based on current state */
+  while (1) switch (s->mode)
+  {
+    case TYPE:
+      NEEDBITS(3)
+      t = (uInt)b & 7;
+      s->last = t & 1;
+      switch (t >> 1)
+      {
+        case 0:                         /* stored */
+          Tracev((stderr, "inflate:     stored block%s\n",
+                 s->last ? " (last)" : ""));
+          DUMPBITS(3)
+          t = k & 7;                    /* go to byte boundary */
+          DUMPBITS(t)
+          s->mode = LENS;               /* get length of stored block */
+          break;
+        case 1:                         /* fixed */
+          Tracev((stderr, "inflate:     fixed codes block%s\n",
+                 s->last ? " (last)" : ""));
+          {
+            uInt bl, bd;
+            inflate_huft *tl, *td;
+
+            inflate_trees_fixed(&bl, &bd, &tl, &td, z);
+            s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
+            if (s->sub.decode.codes == Z_NULL)
+            {
+              r = Z_MEM_ERROR;
+              LEAVE
+            }
+          }
+          DUMPBITS(3)
+          s->mode = CODES;
+          break;
+        case 2:                         /* dynamic */
+          Tracev((stderr, "inflate:     dynamic codes block%s\n",
+                 s->last ? " (last)" : ""));
+          DUMPBITS(3)
+          s->mode = TABLE;
+          break;
+        case 3:                         /* illegal */
+          DUMPBITS(3)
+          s->mode = BAD;
+          z->msg = (char*)"invalid block type";
+          r = Z_DATA_ERROR;
+          LEAVE
+      }
+      break;
+    case LENS:
+      NEEDBITS(32)
+      if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
+      {
+        s->mode = BAD;
+        z->msg = (char*)"invalid stored block lengths";
+        r = Z_DATA_ERROR;
+        LEAVE
+      }
+      s->sub.left = (uInt)b & 0xffff;
+      b = k = 0;                      /* dump bits */
+      Tracev((stderr, "inflate:       stored length %u\n", s->sub.left));
+      s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
+      break;
+    case STORED:
+      if (n == 0)
+        LEAVE
+      NEEDOUT
+      t = s->sub.left;
+      if (t > n) t = n;
+      if (t > m) t = m;
+      zmemcpy(q, p, t);
+      p += t;  n -= t;
+      q += t;  m -= t;
+      if ((s->sub.left -= t) != 0)
+        break;
+      Tracev((stderr, "inflate:       stored end, %lu total out\n",
+              z->total_out + (q >= s->read ? q - s->read :
+              (s->end - s->read) + (q - s->window))));
+      s->mode = s->last ? DRY : TYPE;
+      break;
+    case TABLE:
+      NEEDBITS(14)
+      s->sub.trees.table = t = (uInt)b & 0x3fff;
+#ifndef PKZIP_BUG_WORKAROUND
+      if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
+      {
+        s->mode = BAD;
+        z->msg = (char*)"too many length or distance symbols";
+        r = Z_DATA_ERROR;
+        LEAVE
+      }
+#endif
+      t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
+      if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
+      {
+        r = Z_MEM_ERROR;
+        LEAVE
+      }
+      DUMPBITS(14)
+      s->sub.trees.index = 0;
+      Tracev((stderr, "inflate:       table sizes ok\n"));
+      s->mode = BTREE;
+    case BTREE:
+      while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
+      {
+        NEEDBITS(3)
+        s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
+        DUMPBITS(3)
+      }
+      while (s->sub.trees.index < 19)
+        s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
+      s->sub.trees.bb = 7;
+      t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
+                             &s->sub.trees.tb, s->hufts, z);
+      if (t != Z_OK)
+      {
+        ZFREE(z, s->sub.trees.blens);
+        r = t;
+        if (r == Z_DATA_ERROR)
+          s->mode = BAD;
+        LEAVE
+      }
+      s->sub.trees.index = 0;
+      Tracev((stderr, "inflate:       bits tree ok\n"));
+      s->mode = DTREE;
+    case DTREE:
+      while (t = s->sub.trees.table,
+             s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
+      {
+        inflate_huft *h;
+        uInt i, j, c;
+
+        t = s->sub.trees.bb;
+        NEEDBITS(t)
+        h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
+        t = h->bits;
+        c = h->base;
+        if (c < 16)
+        {
+          DUMPBITS(t)
+          s->sub.trees.blens[s->sub.trees.index++] = c;
+        }
+        else /* c == 16..18 */
+        {
+          i = c == 18 ? 7 : c - 14;
+          j = c == 18 ? 11 : 3;
+          NEEDBITS(t + i)
+          DUMPBITS(t)
+          j += (uInt)b & inflate_mask[i];
+          DUMPBITS(i)
+          i = s->sub.trees.index;
+          t = s->sub.trees.table;
+          if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
+              (c == 16 && i < 1))
+          {
+            ZFREE(z, s->sub.trees.blens);
+            s->mode = BAD;
+            z->msg = (char*)"invalid bit length repeat";
+            r = Z_DATA_ERROR;
+            LEAVE
+          }
+          c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
+          do {
+            s->sub.trees.blens[i++] = c;
+          } while (--j);
+          s->sub.trees.index = i;
+        }
+      }
+      s->sub.trees.tb = Z_NULL;
+      {
+        uInt bl, bd;
+        inflate_huft *tl, *td;
+        inflate_codes_statef *c;
+
+        bl = 9;         /* must be <= 9 for lookahead assumptions */
+        bd = 6;         /* must be <= 9 for lookahead assumptions */
+        t = s->sub.trees.table;
+        t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
+                                  s->sub.trees.blens, &bl, &bd, &tl, &td,
+                                  s->hufts, z);
+        ZFREE(z, s->sub.trees.blens);
+        if (t != Z_OK)
+        {
+          if (t == (uInt)Z_DATA_ERROR)
+            s->mode = BAD;
+          r = t;
+          LEAVE
+        }
+        Tracev((stderr, "inflate:       trees ok\n"));
+        if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
+        {
+          r = Z_MEM_ERROR;
+          LEAVE
+        }
+        s->sub.decode.codes = c;
+      }
+      s->mode = CODES;
+    case CODES:
+      UPDATE
+      if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
+        return inflate_flush(s, z, r);
+      r = Z_OK;
+      inflate_codes_free(s->sub.decode.codes, z);
+      LOAD
+      Tracev((stderr, "inflate:       codes end, %lu total out\n",
+              z->total_out + (q >= s->read ? q - s->read :
+              (s->end - s->read) + (q - s->window))));
+      if (!s->last)
+      {
+        s->mode = TYPE;
+        break;
+      }
+      if (k > 7)              /* return unused byte, if any */
+      {
+        Assert(k < 16, "inflate_codes grabbed too many bytes")
+        k -= 8;
+        n++;
+        p--;                    /* can always return one */
+      }
+      s->mode = DRY;
+    case DRY:
+      FLUSH
+      if (s->read != s->write)
+        LEAVE
+      s->mode = DONE;
+    case DONE:
+      r = Z_STREAM_END;
+      LEAVE
+    case BAD:
+      r = Z_DATA_ERROR;
+      LEAVE
+    default:
+      r = Z_STREAM_ERROR;
+      LEAVE
+  }
+}
+
+
+int inflate_blocks_free(s, z)
+inflate_blocks_statef *s;
+z_streamp z;
+{
+  inflate_blocks_reset(s, z, Z_NULL);
+  ZFREE(z, s->window);
+  ZFREE(z, s->hufts);
+  ZFREE(z, s);
+  Tracev((stderr, "inflate:   blocks freed\n"));
+  return Z_OK;
+}
+
+
+void inflate_set_dictionary(s, d, n)
+inflate_blocks_statef *s;
+const Bytef *d;
+uInt  n;
+{
+  zmemcpy(s->window, d, n);
+  s->read = s->write = s->window + n;
+}
+
+
+/* Returns true if inflate is currently at the end of a block generated
+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. 
+ * IN assertion: s != Z_NULL
+ */
+int inflate_blocks_sync_point(s)
+inflate_blocks_statef *s;
+{
+  return s->mode == LENS;
+}
diff --git a/src/zlib/infblock.h b/src/zlib/infblock.h
new file mode 100644
index 0000000000..bd25c80753
--- /dev/null
+++ b/src/zlib/infblock.h
@@ -0,0 +1,39 @@
+/* infblock.h -- header to use infblock.c
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+struct inflate_blocks_state;
+typedef struct inflate_blocks_state FAR inflate_blocks_statef;
+
+extern inflate_blocks_statef * inflate_blocks_new OF((
+    z_streamp z,
+    check_func c,               /* check function */
+    uInt w));                   /* window size */
+
+extern int inflate_blocks OF((
+    inflate_blocks_statef *,
+    z_streamp ,
+    int));                      /* initial return code */
+
+extern void inflate_blocks_reset OF((
+    inflate_blocks_statef *,
+    z_streamp ,
+    uLongf *));                  /* check value on output */
+
+extern int inflate_blocks_free OF((
+    inflate_blocks_statef *,
+    z_streamp));
+
+extern void inflate_set_dictionary OF((
+    inflate_blocks_statef *s,
+    const Bytef *d,  /* dictionary */
+    uInt  n));       /* dictionary length */
+
+extern int inflate_blocks_sync_point OF((
+    inflate_blocks_statef *s));
diff --git a/src/zlib/infcodes.c b/src/zlib/infcodes.c
new file mode 100644
index 0000000000..1d3baa92eb
--- /dev/null
+++ b/src/zlib/infcodes.c
@@ -0,0 +1,250 @@
+/* infcodes.c -- process literals and length/distance pairs
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "infblock.h"
+#include "infcodes.h"
+#include "infutil.h"
+#include "inffast.h"
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+typedef enum {        /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+      START,    /* x: set up for LEN */
+      LEN,      /* i: get length/literal/eob next */
+      LENEXT,   /* i: getting length extra (have base) */
+      DIST,     /* i: get distance next */
+      DISTEXT,  /* i: getting distance extra */
+      COPY,     /* o: copying bytes in window, waiting for space */
+      LIT,      /* o: got literal, waiting for output space */
+      WASH,     /* o: got eob, possibly still output waiting */
+      END,      /* x: got eob and all data flushed */
+      BADCODE}  /* x: got error */
+inflate_codes_mode;
+
+/* inflate codes private state */
+struct inflate_codes_state {
+
+  /* mode */
+  inflate_codes_mode mode;      /* current inflate_codes mode */
+
+  /* mode dependent information */
+  uInt len;
+  union {
+    struct {
+      inflate_huft *tree;       /* pointer into tree */
+      uInt need;                /* bits needed */
+    } code;             /* if LEN or DIST, where in tree */
+    uInt lit;           /* if LIT, literal */
+    struct {
+      uInt get;                 /* bits to get for extra */
+      uInt dist;                /* distance back to copy from */
+    } copy;             /* if EXT or COPY, where and how much */
+  } sub;                /* submode */
+
+  /* mode independent information */
+  Byte lbits;           /* ltree bits decoded per branch */
+  Byte dbits;           /* dtree bits decoder per branch */
+  inflate_huft *ltree;          /* literal/length/eob tree */
+  inflate_huft *dtree;          /* distance tree */
+
+};
+
+
+inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
+uInt bl, bd;
+inflate_huft *tl;
+inflate_huft *td; /* need separate declaration for Borland C++ */
+z_streamp z;
+{
+  inflate_codes_statef *c;
+
+  if ((c = (inflate_codes_statef *)
+       ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
+  {
+    c->mode = START;
+    c->lbits = (Byte)bl;
+    c->dbits = (Byte)bd;
+    c->ltree = tl;
+    c->dtree = td;
+    Tracev((stderr, "inflate:       codes new\n"));
+  }
+  return c;
+}
+
+
+int inflate_codes(s, z, r)
+inflate_blocks_statef *s;
+z_streamp z;
+int r;
+{
+  uInt j;               /* temporary storage */
+  inflate_huft *t;      /* temporary pointer */
+  uInt e;               /* extra bits or operation */
+  uLong b;              /* bit buffer */
+  uInt k;               /* bits in bit buffer */
+  Bytef *p;             /* input data pointer */
+  uInt n;               /* bytes available there */
+  Bytef *q;             /* output window write pointer */
+  uInt m;               /* bytes to end of window or read pointer */
+  Bytef *f;             /* pointer to copy strings from */
+  inflate_codes_statef *c = s->sub.decode.codes;  /* codes state */
+
+  /* copy input/output information to locals (UPDATE macro restores) */
+  LOAD
+
+  /* process input and output based on current state */
+  while (1) switch (c->mode)
+  {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+    case START:         /* x: set up for LEN */
+#ifndef SLOW
+      if (m >= 258 && n >= 10)
+      {
+        UPDATE
+        r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
+        LOAD
+        if (r != Z_OK)
+        {
+          c->mode = r == Z_STREAM_END ? WASH : BADCODE;
+          break;
+        }
+      }
+#endif /* !SLOW */
+      c->sub.code.need = c->lbits;
+      c->sub.code.tree = c->ltree;
+      c->mode = LEN;
+    case LEN:           /* i: get length/literal/eob next */
+      j = c->sub.code.need;
+      NEEDBITS(j)
+      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
+      DUMPBITS(t->bits)
+      e = (uInt)(t->exop);
+      if (e == 0)               /* literal */
+      {
+        c->sub.lit = t->base;
+        Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+                 "inflate:         literal '%c'\n" :
+                 "inflate:         literal 0x%02x\n", t->base));
+        c->mode = LIT;
+        break;
+      }
+      if (e & 16)               /* length */
+      {
+        c->sub.copy.get = e & 15;
+        c->len = t->base;
+        c->mode = LENEXT;
+        break;
+      }
+      if ((e & 64) == 0)        /* next table */
+      {
+        c->sub.code.need = e;
+        c->sub.code.tree = t + t->base;
+        break;
+      }
+      if (e & 32)               /* end of block */
+      {
+        Tracevv((stderr, "inflate:         end of block\n"));
+        c->mode = WASH;
+        break;
+      }
+      c->mode = BADCODE;        /* invalid code */
+      z->msg = (char*)"invalid literal/length code";
+      r = Z_DATA_ERROR;
+      LEAVE
+    case LENEXT:        /* i: getting length extra (have base) */
+      j = c->sub.copy.get;
+      NEEDBITS(j)
+      c->len += (uInt)b & inflate_mask[j];
+      DUMPBITS(j)
+      c->sub.code.need = c->dbits;
+      c->sub.code.tree = c->dtree;
+      Tracevv((stderr, "inflate:         length %u\n", c->len));
+      c->mode = DIST;
+    case DIST:          /* i: get distance next */
+      j = c->sub.code.need;
+      NEEDBITS(j)
+      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
+      DUMPBITS(t->bits)
+      e = (uInt)(t->exop);
+      if (e & 16)               /* distance */
+      {
+        c->sub.copy.get = e & 15;
+        c->sub.copy.dist = t->base;
+        c->mode = DISTEXT;
+        break;
+      }
+      if ((e & 64) == 0)        /* next table */
+      {
+        c->sub.code.need = e;
+        c->sub.code.tree = t + t->base;
+        break;
+      }
+      c->mode = BADCODE;        /* invalid code */
+      z->msg = (char*)"invalid distance code";
+      r = Z_DATA_ERROR;
+      LEAVE
+    case DISTEXT:       /* i: getting distance extra */
+      j = c->sub.copy.get;
+      NEEDBITS(j)
+      c->sub.copy.dist += (uInt)b & inflate_mask[j];
+      DUMPBITS(j)
+      Tracevv((stderr, "inflate:         distance %u\n", c->sub.copy.dist));
+      c->mode = COPY;
+    case COPY:          /* o: copying bytes in window, waiting for space */
+#ifndef __TURBOC__ /* Turbo C bug for following expression */
+      f = (uInt)(q - s->window) < c->sub.copy.dist ?
+          s->end - (c->sub.copy.dist - (q - s->window)) :
+          q - c->sub.copy.dist;
+#else
+      f = q - c->sub.copy.dist;
+      if ((uInt)(q - s->window) < c->sub.copy.dist)
+        f = s->end - (c->sub.copy.dist - (uInt)(q - s->window));
+#endif
+      while (c->len)
+      {
+        NEEDOUT
+        OUTBYTE(*f++)
+        if (f == s->end)
+          f = s->window;
+        c->len--;
+      }
+      c->mode = START;
+      break;
+    case LIT:           /* o: got literal, waiting for output space */
+      NEEDOUT
+      OUTBYTE(c->sub.lit)
+      c->mode = START;
+      break;
+    case WASH:          /* o: got eob, possibly more output */
+      FLUSH
+      if (s->read != s->write)
+        LEAVE
+      c->mode = END;
+    case END:
+      r = Z_STREAM_END;
+      LEAVE
+    case BADCODE:       /* x: got error */
+      r = Z_DATA_ERROR;
+      LEAVE
+    default:
+      r = Z_STREAM_ERROR;
+      LEAVE
+  }
+#ifdef NEED_DUMMY_RETURN
+  return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
+#endif
+}
+
+
+void inflate_codes_free(c, z)
+inflate_codes_statef *c;
+z_streamp z;
+{
+  ZFREE(z, c);
+  Tracev((stderr, "inflate:       codes free\n"));
+}
diff --git a/src/zlib/infcodes.h b/src/zlib/infcodes.h
new file mode 100644
index 0000000000..6c750d896f
--- /dev/null
+++ b/src/zlib/infcodes.h
@@ -0,0 +1,27 @@
+/* infcodes.h -- header to use infcodes.c
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+struct inflate_codes_state;
+typedef struct inflate_codes_state FAR inflate_codes_statef;
+
+extern inflate_codes_statef *inflate_codes_new OF((
+    uInt, uInt,
+    inflate_huft *, inflate_huft *,
+    z_streamp ));
+
+extern int inflate_codes OF((
+    inflate_blocks_statef *,
+    z_streamp ,
+    int));
+
+extern void inflate_codes_free OF((
+    inflate_codes_statef *,
+    z_streamp ));
+
diff --git a/src/zlib/inffast.c b/src/zlib/inffast.c
new file mode 100644
index 0000000000..61a78ee933
--- /dev/null
+++ b/src/zlib/inffast.c
@@ -0,0 +1,170 @@
+/* inffast.c -- process literals and length/distance pairs fast
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "infblock.h"
+#include "infcodes.h"
+#include "infutil.h"
+#include "inffast.h"
+
+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+/* macros for bit input with no checking and for returning unused bytes */
+#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
+#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
+
+/* Called with number of bytes left to write in window at least 258
+   (the maximum string length) and number of input bytes available
+   at least ten.  The ten bytes are six bytes for the longest length/
+   distance pair plus four bytes for overloading the bit buffer. */
+
+int inflate_fast(bl, bd, tl, td, s, z)
+uInt bl, bd;
+inflate_huft *tl;
+inflate_huft *td; /* need separate declaration for Borland C++ */
+inflate_blocks_statef *s;
+z_streamp z;
+{
+  inflate_huft *t;      /* temporary pointer */
+  uInt e;               /* extra bits or operation */
+  uLong b;              /* bit buffer */
+  uInt k;               /* bits in bit buffer */
+  Bytef *p;             /* input data pointer */
+  uInt n;               /* bytes available there */
+  Bytef *q;             /* output window write pointer */
+  uInt m;               /* bytes to end of window or read pointer */
+  uInt ml;              /* mask for literal/length tree */
+  uInt md;              /* mask for distance tree */
+  uInt c;               /* bytes to copy */
+  uInt d;               /* distance back to copy from */
+  Bytef *r;             /* copy source pointer */
+
+  /* load input, output, bit values */
+  LOAD
+
+  /* initialize masks */
+  ml = inflate_mask[bl];
+  md = inflate_mask[bd];
+
+  /* do until not enough input or output space for fast loop */
+  do {                          /* assume called with m >= 258 && n >= 10 */
+    /* get literal/length code */
+    GRABBITS(20)                /* max bits for literal/length code */
+    if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
+    {
+      DUMPBITS(t->bits)
+      Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+                "inflate:         * literal '%c'\n" :
+                "inflate:         * literal 0x%02x\n", t->base));
+      *q++ = (Byte)t->base;
+      m--;
+      continue;
+    }
+    do {
+      DUMPBITS(t->bits)
+      if (e & 16)
+      {
+        /* get extra bits for length */
+        e &= 15;
+        c = t->base + ((uInt)b & inflate_mask[e]);
+        DUMPBITS(e)
+        Tracevv((stderr, "inflate:         * length %u\n", c));
+
+        /* decode distance base of block to copy */
+        GRABBITS(15);           /* max bits for distance code */
+        e = (t = td + ((uInt)b & md))->exop;
+        do {
+          DUMPBITS(t->bits)
+          if (e & 16)
+          {
+            /* get extra bits to add to distance base */
+            e &= 15;
+            GRABBITS(e)         /* get extra bits (up to 13) */
+            d = t->base + ((uInt)b & inflate_mask[e]);
+            DUMPBITS(e)
+            Tracevv((stderr, "inflate:         * distance %u\n", d));
+
+            /* do the copy */
+            m -= c;
+            if ((uInt)(q - s->window) >= d)     /* offset before dest */
+            {                                   /*  just copy */
+              r = q - d;
+              *q++ = *r++;  c--;        /* minimum count is three, */
+              *q++ = *r++;  c--;        /*  so unroll loop a little */
+            }
+            else                        /* else offset after destination */
+            {
+              e = d - (uInt)(q - s->window); /* bytes from offset to end */
+              r = s->end - e;           /* pointer to offset */
+              if (c > e)                /* if source crosses, */
+              {
+                c -= e;                 /* copy to end of window */
+                do {
+                  *q++ = *r++;
+                } while (--e);
+                r = s->window;          /* copy rest from start of window */
+              }
+            }
+            do {                        /* copy all or what's left */
+              *q++ = *r++;
+            } while (--c);
+            break;
+          }
+          else if ((e & 64) == 0)
+          {
+            t += t->base;
+            e = (t += ((uInt)b & inflate_mask[e]))->exop;
+          }
+          else
+          {
+            z->msg = (char*)"invalid distance code";
+            UNGRAB
+            UPDATE
+            return Z_DATA_ERROR;
+          }
+        } while (1);
+        break;
+      }
+      if ((e & 64) == 0)
+      {
+        t += t->base;
+        if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
+        {
+          DUMPBITS(t->bits)
+          Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+                    "inflate:         * literal '%c'\n" :
+                    "inflate:         * literal 0x%02x\n", t->base));
+          *q++ = (Byte)t->base;
+          m--;
+          break;
+        }
+      }
+      else if (e & 32)
+      {
+        Tracevv((stderr, "inflate:         * end of block\n"));
+        UNGRAB
+        UPDATE
+        return Z_STREAM_END;
+      }
+      else
+      {
+        z->msg = (char*)"invalid literal/length code";
+        UNGRAB
+        UPDATE
+        return Z_DATA_ERROR;
+      }
+    } while (1);
+  } while (m >= 258 && n >= 10);
+
+  /* not enough input or output--restore pointers and return */
+  UNGRAB
+  UPDATE
+  return Z_OK;
+}
diff --git a/src/zlib/inffast.h b/src/zlib/inffast.h
new file mode 100644
index 0000000000..8facec5531
--- /dev/null
+++ b/src/zlib/inffast.h
@@ -0,0 +1,17 @@
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+extern int inflate_fast OF((
+    uInt,
+    uInt,
+    inflate_huft *,
+    inflate_huft *,
+    inflate_blocks_statef *,
+    z_streamp ));
diff --git a/src/zlib/inffixed.h b/src/zlib/inffixed.h
new file mode 100644
index 0000000000..644ef6cd4a
--- /dev/null
+++ b/src/zlib/inffixed.h
@@ -0,0 +1,125 @@
+/* inffixed.h -- table for decoding fixed codes
+ * Generated automatically by the maketree.c program
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+local uInt fixed_bl = 9;
+local uInt fixed_bd = 5;
+local inflate_huft fixed_tl[] = {
+    {{96,7},256}, {{0,8},80}, {{0,8},16}, {{84,8},115}, {{82,7},31},
+    {{0,8},112}, {{0,8},48}, {{0,9},192}, {{80,7},10}, {{0,8},96},
+    {{0,8},32}, {{0,9},160}, {{0,8},0}, {{0,8},128}, {{0,8},64},
+    {{0,9},224}, {{80,7},6}, {{0,8},88}, {{0,8},24}, {{0,9},144},
+    {{83,7},59}, {{0,8},120}, {{0,8},56}, {{0,9},208}, {{81,7},17},
+    {{0,8},104}, {{0,8},40}, {{0,9},176}, {{0,8},8}, {{0,8},136},
+    {{0,8},72}, {{0,9},240}, {{80,7},4}, {{0,8},84}, {{0,8},20},
+    {{85,8},227}, {{83,7},43}, {{0,8},116}, {{0,8},52}, {{0,9},200},
+    {{81,7},13}, {{0,8},100}, {{0,8},36}, {{0,9},168}, {{0,8},4},
+    {{0,8},132}, {{0,8},68}, {{0,9},232}, {{80,7},8}, {{0,8},92},
+    {{0,8},28}, {{0,9},152}, {{84,7},83}, {{0,8},124}, {{0,8},60},
+    {{0,9},216}, {{82,7},23}, {{0,8},108}, {{0,8},44}, {{0,9},184},
+    {{0,8},12}, {{0,8},140}, {{0,8},76}, {{0,9},248}, {{80,7},3},
+    {{0,8},82}, {{0,8},18}, {{85,8},163}, {{83,7},35}, {{0,8},114},
+    {{0,8},50}, {{0,9},196}, {{81,7},11}, {{0,8},98}, {{0,8},34},
+    {{0,9},164}, {{0,8},2}, {{0,8},130}, {{0,8},66}, {{0,9},228},
+    {{80,7},7}, {{0,8},90}, {{0,8},26}, {{0,9},148}, {{84,7},67},
+    {{0,8},122}, {{0,8},58}, {{0,9},212}, {{82,7},19}, {{0,8},106},
+    {{0,8},42}, {{0,9},180}, {{0,8},10}, {{0,8},138}, {{0,8},74},
+    {{0,9},244}, {{80,7},5}, {{0,8},86}, {{0,8},22}, {{192,8},0},
+    {{83,7},51}, {{0,8},118}, {{0,8},54}, {{0,9},204}, {{81,7},15},
+    {{0,8},102}, {{0,8},38}, {{0,9},172}, {{0,8},6}, {{0,8},134},
+    {{0,8},70}, {{0,9},236}, {{80,7},9}, {{0,8},94}, {{0,8},30},
+    {{0,9},156}, {{84,7},99}, {{0,8},126}, {{0,8},62}, {{0,9},220},
+    {{82,7},27}, {{0,8},110}, {{0,8},46}, {{0,9},188}, {{0,8},14},
+    {{0,8},142}, {{0,8},78}, {{0,9},252}, {{96,7},256}, {{0,8},81},
+    {{0,8},17}, {{85,8},131}, {{82,7},31}, {{0,8},113}, {{0,8},49},
+    {{0,9},194}, {{80,7},10}, {{0,8},97}, {{0,8},33}, {{0,9},162},
+    {{0,8},1}, {{0,8},129}, {{0,8},65}, {{0,9},226}, {{80,7},6},
+    {{0,8},89}, {{0,8},25}, {{0,9},146}, {{83,7},59}, {{0,8},121},
+    {{0,8},57}, {{0,9},210}, {{81,7},17}, {{0,8},105}, {{0,8},41},
+    {{0,9},178}, {{0,8},9}, {{0,8},137}, {{0,8},73}, {{0,9},242},
+    {{80,7},4}, {{0,8},85}, {{0,8},21}, {{80,8},258}, {{83,7},43},
+    {{0,8},117}, {{0,8},53}, {{0,9},202}, {{81,7},13}, {{0,8},101},
+    {{0,8},37}, {{0,9},170}, {{0,8},5}, {{0,8},133}, {{0,8},69},
+    {{0,9},234}, {{80,7},8}, {{0,8},93}, {{0,8},29}, {{0,9},154},
+    {{84,7},83}, {{0,8},125}, {{0,8},61}, {{0,9},218}, {{82,7},23},
+    {{0,8},109}, {{0,8},45}, {{0,9},186}, {{0,8},13}, {{0,8},141},
+    {{0,8},77}, {{0,9},250}, {{80,7},3}, {{0,8},83}, {{0,8},19},
+    {{85,8},195}, {{83,7},35}, {{0,8},115}, {{0,8},51}, {{0,9},198},
+    {{81,7},11}, {{0,8},99}, {{0,8},35}, {{0,9},166}, {{0,8},3},
+    {{0,8},131}, {{0,8},67}, {{0,9},230}, {{80,7},7}, {{0,8},91},
+    {{0,8},27}, {{0,9},150}, {{84,7},67}, {{0,8},123}, {{0,8},59},
+    {{0,9},214}, {{82,7},19}, {{0,8},107}, {{0,8},43}, {{0,9},182},
+    {{0,8},11}, {{0,8},139}, {{0,8},75}, {{0,9},246}, {{80,7},5},
+    {{0,8},87}, {{0,8},23}, {{192,8},0}, {{83,7},51}, {{0,8},119},
+    {{0,8},55}, {{0,9},206}, {{81,7},15}, {{0,8},103}, {{0,8},39},
+    {{0,9},174}, {{0,8},7}, {{0,8},135}, {{0,8},71}, {{0,9},238},
+    {{80,7},9}, {{0,8},95}, {{0,8},31}, {{0,9},158}, {{84,7},99},
+    {{0,8},127}, {{0,8},63}, {{0,9},222}, {{82,7},27}, {{0,8},111},
+    {{0,8},47}, {{0,9},190}, {{0,8},15}, {{0,8},143}, {{0,8},79},
+    {{0,9},254}, {{96,7},256}, {{0,8},80}, {{0,8},16}, {{84,8},115},
+    {{82,7},31}, {{0,8},112}, {{0,8},48}, {{0,9},193}, {{80,7},10},
+    {{0,8},96}, {{0,8},32}, {{0,9},161}, {{0,8},0}, {{0,8},128},
+    {{0,8},64}, {{0,9},225}, {{80,7},6}, {{0,8},88}, {{0,8},24},
+    {{0,9},145}, {{83,7},59}, {{0,8},120}, {{0,8},56}, {{0,9},209},
+    {{81,7},17}, {{0,8},104}, {{0,8},40}, {{0,9},177}, {{0,8},8},
+    {{0,8},136}, {{0,8},72}, {{0,9},241}, {{80,7},4}, {{0,8},84},
+    {{0,8},20}, {{85,8},227}, {{83,7},43}, {{0,8},116}, {{0,8},52},
+    {{0,9},201}, {{81,7},13}, {{0,8},100}, {{0,8},36}, {{0,9},169},
+    {{0,8},4}, {{0,8},132}, {{0,8},68}, {{0,9},233}, {{80,7},8},
+    {{0,8},92}, {{0,8},28}, {{0,9},153}, {{84,7},83}, {{0,8},124},
+    {{0,8},60}, {{0,9},217}, {{82,7},23}, {{0,8},108}, {{0,8},44},
+    {{0,9},185}, {{0,8},12}, {{0,8},140}, {{0,8},76}, {{0,9},249},
+    {{80,7},3}, {{0,8},82}, {{0,8},18}, {{85,8},163}, {{83,7},35},
+    {{0,8},114}, {{0,8},50}, {{0,9},197}, {{81,7},11}, {{0,8},98},
+    {{0,8},34}, {{0,9},165}, {{0,8},2}, {{0,8},130}, {{0,8},66},
+    {{0,9},229}, {{80,7},7}, {{0,8},90}, {{0,8},26}, {{0,9},149},
+    {{84,7},67}, {{0,8},122}, {{0,8},58}, {{0,9},213}, {{82,7},19},
+    {{0,8},106}, {{0,8},42}, {{0,9},181}, {{0,8},10}, {{0,8},138},
+    {{0,8},74}, {{0,9},245}, {{80,7},5}, {{0,8},86}, {{0,8},22},
+    {{192,8},0}, {{83,7},51}, {{0,8},118}, {{0,8},54}, {{0,9},205},
+    {{81,7},15}, {{0,8},102}, {{0,8},38}, {{0,9},173}, {{0,8},6},
+    {{0,8},134}, {{0,8},70}, {{0,9},237}, {{80,7},9}, {{0,8},94},
+    {{0,8},30}, {{0,9},157}, {{84,7},99}, {{0,8},126}, {{0,8},62},
+    {{0,9},221}, {{82,7},27}, {{0,8},110}, {{0,8},46}, {{0,9},189},
+    {{0,8},14}, {{0,8},142}, {{0,8},78}, {{0,9},253}, {{96,7},256},
+    {{0,8},81}, {{0,8},17}, {{85,8},131}, {{82,7},31}, {{0,8},113},
+    {{0,8},49}, {{0,9},195}, {{80,7},10}, {{0,8},97}, {{0,8},33},
+    {{0,9},163}, {{0,8},1}, {{0,8},129}, {{0,8},65}, {{0,9},227},
+    {{80,7},6}, {{0,8},89}, {{0,8},25}, {{0,9},147}, {{83,7},59},
+    {{0,8},121}, {{0,8},57}, {{0,9},211}, {{81,7},17}, {{0,8},105},
+    {{0,8},41}, {{0,9},179}, {{0,8},9}, {{0,8},137}, {{0,8},73},
+    {{0,9},243}, {{80,7},4}, {{0,8},85}, {{0,8},21}, {{80,8},258},
+    {{83,7},43}, {{0,8},117}, {{0,8},53}, {{0,9},203}, {{81,7},13},
+    {{0,8},101}, {{0,8},37}, {{0,9},171}, {{0,8},5}, {{0,8},133},
+    {{0,8},69}, {{0,9},235}, {{80,7},8}, {{0,8},93}, {{0,8},29},
+    {{0,9},155}, {{84,7},83}, {{0,8},125}, {{0,8},61}, {{0,9},219},
+    {{82,7},23}, {{0,8},109}, {{0,8},45}, {{0,9},187}, {{0,8},13},
+    {{0,8},141}, {{0,8},77}, {{0,9},251}, {{80,7},3}, {{0,8},83},
+    {{0,8},19}, {{85,8},195}, {{83,7},35}, {{0,8},115}, {{0,8},51},
+    {{0,9},199}, {{81,7},11}, {{0,8},99}, {{0,8},35}, {{0,9},167},
+    {{0,8},3}, {{0,8},131}, {{0,8},67}, {{0,9},231}, {{80,7},7},
+    {{0,8},91}, {{0,8},27}, {{0,9},151}, {{84,7},67}, {{0,8},123},
+    {{0,8},59}, {{0,9},215}, {{82,7},19}, {{0,8},107}, {{0,8},43},
+    {{0,9},183}, {{0,8},11}, {{0,8},139}, {{0,8},75}, {{0,9},247},
+    {{80,7},5}, {{0,8},87}, {{0,8},23}, {{192,8},0}, {{83,7},51},
+    {{0,8},119}, {{0,8},55}, {{0,9},207}, {{81,7},15}, {{0,8},103},
+    {{0,8},39}, {{0,9},175}, {{0,8},7}, {{0,8},135}, {{0,8},71},
+    {{0,9},239}, {{80,7},9}, {{0,8},95}, {{0,8},31}, {{0,9},159},
+    {{84,7},99}, {{0,8},127}, {{0,8},63}, {{0,9},223}, {{82,7},27},
+    {{0,8},111}, {{0,8},47}, {{0,9},191}, {{0,8},15}, {{0,8},143},
+    {{0,8},79}, {{0,9},255}
+  };
+local inflate_huft fixed_td[] = {
+    {{80,5},1}, {{87,5},257}, {{83,5},17}, {{91,5},4097}, {{81,5},5},
+    {{89,5},1025}, {{85,5},65}, {{93,5},16385}, {{80,5},3}, {{88,5},513},
+    {{84,5},33}, {{92,5},8193}, {{82,5},9}, {{90,5},2049}, {{86,5},129},
+    {{192,5},24577}, {{80,5},2}, {{87,5},385}, {{83,5},25}, {{91,5},6145},
+    {{81,5},7}, {{89,5},1537}, {{85,5},97}, {{93,5},24577}, {{80,5},4},
+    {{88,5},769}, {{84,5},49}, {{92,5},12289}, {{82,5},13}, {{90,5},3073},
+    {{86,5},193}, {{192,5},24577}
+  };
diff --git a/src/zlib/inflate.c b/src/zlib/inflate.c
new file mode 100644
index 0000000000..32e9b8de67
--- /dev/null
+++ b/src/zlib/inflate.c
@@ -0,0 +1,366 @@
+/* inflate.c -- zlib interface to inflate modules
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include "zutil.h"
+#include "infblock.h"
+
+struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
+
+typedef enum {
+      METHOD,   /* waiting for method byte */
+      FLAG,     /* waiting for flag byte */
+      DICT4,    /* four dictionary check bytes to go */
+      DICT3,    /* three dictionary check bytes to go */
+      DICT2,    /* two dictionary check bytes to go */
+      DICT1,    /* one dictionary check byte to go */
+      DICT0,    /* waiting for inflateSetDictionary */
+      BLOCKS,   /* decompressing blocks */
+      CHECK4,   /* four check bytes to go */
+      CHECK3,   /* three check bytes to go */
+      CHECK2,   /* two check bytes to go */
+      CHECK1,   /* one check byte to go */
+      DONE,     /* finished check, done */
+      BAD}      /* got an error--stay here */
+inflate_mode;
+
+/* inflate private state */
+struct internal_state {
+
+  /* mode */
+  inflate_mode  mode;   /* current inflate mode */
+
+  /* mode dependent information */
+  union {
+    uInt method;        /* if FLAGS, method byte */
+    struct {
+      uLong was;                /* computed check value */
+      uLong need;               /* stream check value */
+    } check;            /* if CHECK, check values to compare */
+    uInt marker;        /* if BAD, inflateSync's marker bytes count */
+  } sub;        /* submode */
+
+  /* mode independent information */
+  int  nowrap;          /* flag for no wrapper */
+  uInt wbits;           /* log2(window size)  (8..15, defaults to 15) */
+  inflate_blocks_statef 
+    *blocks;            /* current inflate_blocks state */
+
+};
+
+
+int ZEXPORT inflateReset(z)
+z_streamp z;
+{
+  if (z == Z_NULL || z->state == Z_NULL)
+    return Z_STREAM_ERROR;
+  z->total_in = z->total_out = 0;
+  z->msg = Z_NULL;
+  z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
+  inflate_blocks_reset(z->state->blocks, z, Z_NULL);
+  Tracev((stderr, "inflate: reset\n"));
+  return Z_OK;
+}
+
+
+int ZEXPORT inflateEnd(z)
+z_streamp z;
+{
+  if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
+    return Z_STREAM_ERROR;
+  if (z->state->blocks != Z_NULL)
+    inflate_blocks_free(z->state->blocks, z);
+  ZFREE(z, z->state);
+  z->state = Z_NULL;
+  Tracev((stderr, "inflate: end\n"));
+  return Z_OK;
+}
+
+
+int ZEXPORT inflateInit2_(z, w, version, stream_size)
+z_streamp z;
+int w;
+const char *version;
+int stream_size;
+{
+  if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+      stream_size != sizeof(z_stream))
+      return Z_VERSION_ERROR;
+
+  /* initialize state */
+  if (z == Z_NULL)
+    return Z_STREAM_ERROR;
+  z->msg = Z_NULL;
+  if (z->zalloc == Z_NULL)
+  {
+    z->zalloc = zcalloc;
+    z->opaque = (voidpf)0;
+  }
+  if (z->zfree == Z_NULL) z->zfree = zcfree;
+  if ((z->state = (struct internal_state FAR *)
+       ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
+    return Z_MEM_ERROR;
+  z->state->blocks = Z_NULL;
+
+  /* handle undocumented nowrap option (no zlib header or check) */
+  z->state->nowrap = 0;
+  if (w < 0)
+  {
+    w = - w;
+    z->state->nowrap = 1;
+  }
+
+  /* set window size */
+  if (w < 8 || w > 15)
+  {
+    inflateEnd(z);
+    return Z_STREAM_ERROR;
+  }
+  z->state->wbits = (uInt)w;
+
+  /* create inflate_blocks state */
+  if ((z->state->blocks =
+      inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
+      == Z_NULL)
+  {
+    inflateEnd(z);
+    return Z_MEM_ERROR;
+  }
+  Tracev((stderr, "inflate: allocated\n"));
+
+  /* reset state */
+  inflateReset(z);
+  return Z_OK;
+}
+
+
+int ZEXPORT inflateInit_(z, version, stream_size)
+z_streamp z;
+const char *version;
+int stream_size;
+{
+  return inflateInit2_(z, DEF_WBITS, version, stream_size);
+}
+
+
+#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
+#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
+
+int ZEXPORT inflate(z, f)
+z_streamp z;
+int f;
+{
+  int r;
+  uInt b;
+
+  if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
+    return Z_STREAM_ERROR;
+  f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
+  r = Z_BUF_ERROR;
+  while (1) switch (z->state->mode)
+  {
+    case METHOD:
+      NEEDBYTE
+      if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
+      {
+        z->state->mode = BAD;
+        z->msg = (char*)"unknown compression method";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
+      {
+        z->state->mode = BAD;
+        z->msg = (char*)"invalid window size";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      z->state->mode = FLAG;
+    case FLAG:
+      NEEDBYTE
+      b = NEXTBYTE;
+      if (((z->state->sub.method << 8) + b) % 31)
+      {
+        z->state->mode = BAD;
+        z->msg = (char*)"incorrect header check";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      Tracev((stderr, "inflate: zlib header ok\n"));
+      if (!(b & PRESET_DICT))
+      {
+        z->state->mode = BLOCKS;
+        break;
+      }
+      z->state->mode = DICT4;
+    case DICT4:
+      NEEDBYTE
+      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
+      z->state->mode = DICT3;
+    case DICT3:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
+      z->state->mode = DICT2;
+    case DICT2:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
+      z->state->mode = DICT1;
+    case DICT1:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE;
+      z->adler = z->state->sub.check.need;
+      z->state->mode = DICT0;
+      return Z_NEED_DICT;
+    case DICT0:
+      z->state->mode = BAD;
+      z->msg = (char*)"need dictionary";
+      z->state->sub.marker = 0;       /* can try inflateSync */
+      return Z_STREAM_ERROR;
+    case BLOCKS:
+      r = inflate_blocks(z->state->blocks, z, r);
+      if (r == Z_DATA_ERROR)
+      {
+        z->state->mode = BAD;
+        z->state->sub.marker = 0;       /* can try inflateSync */
+        break;
+      }
+      if (r == Z_OK)
+        r = f;
+      if (r != Z_STREAM_END)
+        return r;
+      r = f;
+      inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
+      if (z->state->nowrap)
+      {
+        z->state->mode = DONE;
+        break;
+      }
+      z->state->mode = CHECK4;
+    case CHECK4:
+      NEEDBYTE
+      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
+      z->state->mode = CHECK3;
+    case CHECK3:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
+      z->state->mode = CHECK2;
+    case CHECK2:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
+      z->state->mode = CHECK1;
+    case CHECK1:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE;
+
+      if (z->state->sub.check.was != z->state->sub.check.need)
+      {
+        z->state->mode = BAD;
+        z->msg = (char*)"incorrect data check";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      Tracev((stderr, "inflate: zlib check ok\n"));
+      z->state->mode = DONE;
+    case DONE:
+      return Z_STREAM_END;
+    case BAD:
+      return Z_DATA_ERROR;
+    default:
+      return Z_STREAM_ERROR;
+  }
+#ifdef NEED_DUMMY_RETURN
+  return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
+#endif
+}
+
+
+int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
+z_streamp z;
+const Bytef *dictionary;
+uInt  dictLength;
+{
+  uInt length = dictLength;
+
+  if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
+    return Z_STREAM_ERROR;
+
+  if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
+  z->adler = 1L;
+
+  if (length >= ((uInt)1<<z->state->wbits))
+  {
+    length = (1<<z->state->wbits)-1;
+    dictionary += dictLength - length;
+  }
+  inflate_set_dictionary(z->state->blocks, dictionary, length);
+  z->state->mode = BLOCKS;
+  return Z_OK;
+}
+
+
+int ZEXPORT inflateSync(z)
+z_streamp z;
+{
+  uInt n;       /* number of bytes to look at */
+  Bytef *p;     /* pointer to bytes */
+  uInt m;       /* number of marker bytes found in a row */
+  uLong r, w;   /* temporaries to save total_in and total_out */
+
+  /* set up */
+  if (z == Z_NULL || z->state == Z_NULL)
+    return Z_STREAM_ERROR;
+  if (z->state->mode != BAD)
+  {
+    z->state->mode = BAD;
+    z->state->sub.marker = 0;
+  }
+  if ((n = z->avail_in) == 0)
+    return Z_BUF_ERROR;
+  p = z->next_in;
+  m = z->state->sub.marker;
+
+  /* search */
+  while (n && m < 4)
+  {
+    static const Byte mark[4] = {0, 0, 0xff, 0xff};
+    if (*p == mark[m])
+      m++;
+    else if (*p)
+      m = 0;
+    else
+      m = 4 - m;
+    p++, n--;
+  }
+
+  /* restore */
+  z->total_in += p - z->next_in;
+  z->next_in = p;
+  z->avail_in = n;
+  z->state->sub.marker = m;
+
+  /* return no joy or set up to restart on a new block */
+  if (m != 4)
+    return Z_DATA_ERROR;
+  r = z->total_in;  w = z->total_out;
+  inflateReset(z);
+  z->total_in = r;  z->total_out = w;
+  z->state->mode = BLOCKS;
+  return Z_OK;
+}
+
+
+/* Returns true if inflate is currently at the end of a block generated
+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+ * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
+ * but removes the length bytes of the resulting empty stored block. When
+ * decompressing, PPP checks that at the end of input packet, inflate is
+ * waiting for these length bytes.
+ */
+int ZEXPORT inflateSyncPoint(z)
+z_streamp z;
+{
+  if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
+    return Z_STREAM_ERROR;
+  return inflate_blocks_sync_point(z->state->blocks);
+}
diff --git a/src/zlib/inftrees.c b/src/zlib/inftrees.c
new file mode 100644
index 0000000000..6876ab5a8d
--- /dev/null
+++ b/src/zlib/inftrees.c
@@ -0,0 +1,455 @@
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+
+#if !defined(BUILDFIXED) && !defined(STDC)
+#  define BUILDFIXED   /* non ANSI compilers may not accept inffixed.h */
+#endif
+
+const char inflate_copyright[] =
+   " inflate 1.1.2 Copyright 1995-1998 Mark Adler ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+struct internal_state  {int dummy;}; /* for buggy compilers */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+
+local int huft_build OF((
+    uIntf *,            /* code lengths in bits */
+    uInt,               /* number of codes */
+    uInt,               /* number of "simple" codes */
+    const uIntf *,      /* list of base values for non-simple codes */
+    const uIntf *,      /* list of extra bits for non-simple codes */
+    inflate_huft * FAR*,/* result: starting table */
+    uIntf *,            /* maximum lookup bits (returns actual) */
+    inflate_huft *,     /* space for trees */
+    uInt *,             /* hufts used in space */
+    uIntf * ));         /* space for values */
+
+/* Tables for deflate from PKZIP's appnote.txt. */
+local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
+        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+        /* see note #13 above about 258 */
+local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
+        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
+local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
+        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+        8193, 12289, 16385, 24577};
+local const uInt cpdext[30] = { /* Extra bits for distance codes */
+        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+        7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+        12, 12, 13, 13};
+
+/*
+   Huffman code decoding is performed using a multi-level table lookup.
+   The fastest way to decode is to simply build a lookup table whose
+   size is determined by the longest code.  However, the time it takes
+   to build this table can also be a factor if the data being decoded
+   is not very long.  The most common codes are necessarily the
+   shortest codes, so those codes dominate the decoding time, and hence
+   the speed.  The idea is you can have a shorter table that decodes the
+   shorter, more probable codes, and then point to subsidiary tables for
+   the longer codes.  The time it costs to decode the longer codes is
+   then traded against the time it takes to make longer tables.
+
+   This results of this trade are in the variables lbits and dbits
+   below.  lbits is the number of bits the first level table for literal/
+   length codes can decode in one step, and dbits is the same thing for
+   the distance codes.  Subsequent tables are also less than or equal to
+   those sizes.  These values may be adjusted either when all of the
+   codes are shorter than that, in which case the longest code length in
+   bits is used, or when the shortest code is *longer* than the requested
+   table size, in which case the length of the shortest code in bits is
+   used.
+
+   There are two different values for the two tables, since they code a
+   different number of possibilities each.  The literal/length table
+   codes 286 possible values, or in a flat code, a little over eight
+   bits.  The distance table codes 30 possible values, or a little less
+   than five bits, flat.  The optimum values for speed end up being
+   about one bit more than those, so lbits is 8+1 and dbits is 5+1.
+   The optimum values may differ though from machine to machine, and
+   possibly even between compilers.  Your mileage may vary.
+ */
+
+
+/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
+#define BMAX 15         /* maximum bit length of any code */
+
+local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
+uIntf *b;               /* code lengths in bits (all assumed <= BMAX) */
+uInt n;                 /* number of codes (assumed <= 288) */
+uInt s;                 /* number of simple-valued codes (0..s-1) */
+const uIntf *d;         /* list of base values for non-simple codes */
+const uIntf *e;         /* list of extra bits for non-simple codes */
+inflate_huft * FAR *t;  /* result: starting table */
+uIntf *m;               /* maximum lookup bits, returns actual */
+inflate_huft *hp;       /* space for trees */
+uInt *hn;               /* hufts used in space */
+uIntf *v;               /* working area: values in order of bit length */
+/* Given a list of code lengths and a maximum table size, make a set of
+   tables to decode that set of codes.  Return Z_OK on success, Z_BUF_ERROR
+   if the given code set is incomplete (the tables are still built in this
+   case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of
+   lengths), or Z_MEM_ERROR if not enough memory. */
+{
+
+  uInt a;                       /* counter for codes of length k */
+  uInt c[BMAX+1];               /* bit length count table */
+  uInt f;                       /* i repeats in table every f entries */
+  int g;                        /* maximum code length */
+  int h;                        /* table level */
+  register uInt i;              /* counter, current code */
+  register uInt j;              /* counter */
+  register int k;               /* number of bits in current code */
+  int l;                        /* bits per table (returned in m) */
+  uInt mask;                    /* (1 << w) - 1, to avoid cc -O bug on HP */
+  register uIntf *p;            /* pointer into c[], b[], or v[] */
+  inflate_huft *q;              /* points to current table */
+  struct inflate_huft_s r;      /* table entry for structure assignment */
+  inflate_huft *u[BMAX];        /* table stack */
+  register int w;               /* bits before this table == (l * h) */
+  uInt x[BMAX+1];               /* bit offsets, then code stack */
+  uIntf *xp;                    /* pointer into x */
+  int y;                        /* number of dummy codes added */
+  uInt z;                       /* number of entries in current table */
+
+
+  /* Generate counts for each bit length */
+  p = c;
+#define C0 *p++ = 0;
+#define C2 C0 C0 C0 C0
+#define C4 C2 C2 C2 C2
+  C4                            /* clear c[]--assume BMAX+1 is 16 */
+  p = b;  i = n;
+  do {
+    c[*p++]++;                  /* assume all entries <= BMAX */
+  } while (--i);
+  if (c[0] == n)                /* null input--all zero length codes */
+  {
+    *t = (inflate_huft *)Z_NULL;
+    *m = 0;
+    return Z_OK;
+  }
+
+
+  /* Find minimum and maximum length, bound *m by those */
+  l = *m;
+  for (j = 1; j <= BMAX; j++)
+    if (c[j])
+      break;
+  k = j;                        /* minimum code length */
+  if ((uInt)l < j)
+    l = j;
+  for (i = BMAX; i; i--)
+    if (c[i])
+      break;
+  g = i;                        /* maximum code length */
+  if ((uInt)l > i)
+    l = i;
+  *m = l;
+
+
+  /* Adjust last length count to fill out codes, if needed */
+  for (y = 1 << j; j < i; j++, y <<= 1)
+    if ((y -= c[j]) < 0)
+      return Z_DATA_ERROR;
+  if ((y -= c[i]) < 0)
+    return Z_DATA_ERROR;
+  c[i] += y;
+
+
+  /* Generate starting offsets into the value table for each length */
+  x[1] = j = 0;
+  p = c + 1;  xp = x + 2;
+  while (--i) {                 /* note that i == g from above */
+    *xp++ = (j += *p++);
+  }
+
+
+  /* Make a table of values in order of bit lengths */
+  p = b;  i = 0;
+  do {
+    if ((j = *p++) != 0)
+      v[x[j]++] = i;
+  } while (++i < n);
+  n = x[g];                     /* set n to length of v */
+
+
+  /* Generate the Huffman codes and for each, make the table entries */
+  x[0] = i = 0;                 /* first Huffman code is zero */
+  p = v;                        /* grab values in bit order */
+  h = -1;                       /* no tables yet--level -1 */
+  w = -l;                       /* bits decoded == (l * h) */
+  u[0] = (inflate_huft *)Z_NULL;        /* just to keep compilers happy */
+  q = (inflate_huft *)Z_NULL;   /* ditto */
+  z = 0;                        /* ditto */
+
+  /* go through the bit lengths (k already is bits in shortest code) */
+  for (; k <= g; k++)
+  {
+    a = c[k];
+    while (a--)
+    {
+      /* here i is the Huffman code of length k bits for value *p */
+      /* make tables up to required level */
+      while (k > w + l)
+      {
+        h++;
+        w += l;                 /* previous table always l bits */
+
+        /* compute minimum size table less than or equal to l bits */
+        z = g - w;
+        z = z > (uInt)l ? l : z;        /* table size upper limit */
+        if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */
+        {                       /* too few codes for k-w bit table */
+          f -= a + 1;           /* deduct codes from patterns left */
+          xp = c + k;
+          if (j < z)
+            while (++j < z)     /* try smaller tables up to z bits */
+            {
+              if ((f <<= 1) <= *++xp)
+                break;          /* enough codes to use up j bits */
+              f -= *xp;         /* else deduct codes from patterns */
+            }
+        }
+        z = 1 << j;             /* table entries for j-bit table */
+
+        /* allocate new table */
+        if (*hn + z > MANY)     /* (note: doesn't matter for fixed) */
+          return Z_MEM_ERROR;   /* not enough memory */
+        u[h] = q = hp + *hn;
+        *hn += z;
+
+        /* connect to last table, if there is one */
+        if (h)
+        {
+          x[h] = i;             /* save pattern for backing up */
+          r.bits = (Byte)l;     /* bits to dump before this table */
+          r.exop = (Byte)j;     /* bits in this table */
+          j = i >> (w - l);
+          r.base = (uInt)(q - u[h-1] - j);   /* offset to this table */
+          u[h-1][j] = r;        /* connect to last table */
+        }
+        else
+          *t = q;               /* first table is returned result */
+      }
+
+      /* set up table entry in r */
+      r.bits = (Byte)(k - w);
+      if (p >= v + n)
+        r.exop = 128 + 64;      /* out of values--invalid code */
+      else if (*p < s)
+      {
+        r.exop = (Byte)(*p < 256 ? 0 : 32 + 64);     /* 256 is end-of-block */
+        r.base = *p++;          /* simple code is just the value */
+      }
+      else
+      {
+        r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
+        r.base = d[*p++ - s];
+      }
+
+      /* fill code-like entries with r */
+      f = 1 << (k - w);
+      for (j = i >> w; j < z; j += f)
+        q[j] = r;
+
+      /* backwards increment the k-bit code i */
+      for (j = 1 << (k - 1); i & j; j >>= 1)
+        i ^= j;
+      i ^= j;
+
+      /* backup over finished tables */
+      mask = (1 << w) - 1;      /* needed on HP, cc -O bug */
+      while ((i & mask) != x[h])
+      {
+        h--;                    /* don't need to update q */
+        w -= l;
+        mask = (1 << w) - 1;
+      }
+    }
+  }
+
+
+  /* Return Z_BUF_ERROR if we were given an incomplete table */
+  return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
+}
+
+
+int inflate_trees_bits(c, bb, tb, hp, z)
+uIntf *c;               /* 19 code lengths */
+uIntf *bb;              /* bits tree desired/actual depth */
+inflate_huft * FAR *tb; /* bits tree result */
+inflate_huft *hp;       /* space for trees */
+z_streamp z;            /* for messages */
+{
+  int r;
+  uInt hn = 0;          /* hufts used in space */
+  uIntf *v;             /* work area for huft_build */
+
+  if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
+    return Z_MEM_ERROR;
+  r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
+                 tb, bb, hp, &hn, v);
+  if (r == Z_DATA_ERROR)
+    z->msg = (char*)"oversubscribed dynamic bit lengths tree";
+  else if (r == Z_BUF_ERROR || *bb == 0)
+  {
+    z->msg = (char*)"incomplete dynamic bit lengths tree";
+    r = Z_DATA_ERROR;
+  }
+  ZFREE(z, v);
+  return r;
+}
+
+
+int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
+uInt nl;                /* number of literal/length codes */
+uInt nd;                /* number of distance codes */
+uIntf *c;               /* that many (total) code lengths */
+uIntf *bl;              /* literal desired/actual bit depth */
+uIntf *bd;              /* distance desired/actual bit depth */
+inflate_huft * FAR *tl; /* literal/length tree result */
+inflate_huft * FAR *td; /* distance tree result */
+inflate_huft *hp;       /* space for trees */
+z_streamp z;            /* for messages */
+{
+  int r;
+  uInt hn = 0;          /* hufts used in space */
+  uIntf *v;             /* work area for huft_build */
+
+  /* allocate work area */
+  if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
+    return Z_MEM_ERROR;
+
+  /* build literal/length tree */
+  r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
+  if (r != Z_OK || *bl == 0)
+  {
+    if (r == Z_DATA_ERROR)
+      z->msg = (char*)"oversubscribed literal/length tree";
+    else if (r != Z_MEM_ERROR)
+    {
+      z->msg = (char*)"incomplete literal/length tree";
+      r = Z_DATA_ERROR;
+    }
+    ZFREE(z, v);
+    return r;
+  }
+
+  /* build distance tree */
+  r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
+  if (r != Z_OK || (*bd == 0 && nl > 257))
+  {
+    if (r == Z_DATA_ERROR)
+      z->msg = (char*)"oversubscribed distance tree";
+    else if (r == Z_BUF_ERROR) {
+#ifdef PKZIP_BUG_WORKAROUND
+      r = Z_OK;
+    }
+#else
+      z->msg = (char*)"incomplete distance tree";
+      r = Z_DATA_ERROR;
+    }
+    else if (r != Z_MEM_ERROR)
+    {
+      z->msg = (char*)"empty distance tree with lengths";
+      r = Z_DATA_ERROR;
+    }
+    ZFREE(z, v);
+    return r;
+#endif
+  }
+
+  /* done */
+  ZFREE(z, v);
+  return Z_OK;
+}
+
+
+/* build fixed tables only once--keep them here */
+#ifdef BUILDFIXED
+local int fixed_built = 0;
+#define FIXEDH 544      /* number of hufts used by fixed tables */
+local inflate_huft fixed_mem[FIXEDH];
+local uInt fixed_bl;
+local uInt fixed_bd;
+local inflate_huft *fixed_tl;
+local inflate_huft *fixed_td;
+#else
+#include "inffixed.h"
+#endif
+
+
+int inflate_trees_fixed(bl, bd, tl, td, z)
+uIntf *bl;               /* literal desired/actual bit depth */
+uIntf *bd;               /* distance desired/actual bit depth */
+inflate_huft * FAR *tl;  /* literal/length tree result */
+inflate_huft * FAR *td;  /* distance tree result */
+z_streamp z;             /* for memory allocation */
+{
+#ifdef BUILDFIXED
+  /* build fixed tables if not already */
+  if (!fixed_built)
+  {
+    int k;              /* temporary variable */
+    uInt f = 0;         /* number of hufts used in fixed_mem */
+    uIntf *c;           /* length list for huft_build */
+    uIntf *v;           /* work area for huft_build */
+
+    /* allocate memory */
+    if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
+      return Z_MEM_ERROR;
+    if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
+    {
+      ZFREE(z, c);
+      return Z_MEM_ERROR;
+    }
+
+    /* literal table */
+    for (k = 0; k < 144; k++)
+      c[k] = 8;
+    for (; k < 256; k++)
+      c[k] = 9;
+    for (; k < 280; k++)
+      c[k] = 7;
+    for (; k < 288; k++)
+      c[k] = 8;
+    fixed_bl = 9;
+    huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
+               fixed_mem, &f, v);
+
+    /* distance table */
+    for (k = 0; k < 30; k++)
+      c[k] = 5;
+    fixed_bd = 5;
+    huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
+               fixed_mem, &f, v);
+
+    /* done */
+    ZFREE(z, v);
+    ZFREE(z, c);
+    fixed_built = 1;
+  }
+#endif
+  *bl = fixed_bl;
+  *bd = fixed_bd;
+  *tl = fixed_tl;
+  *td = fixed_td;
+  return Z_OK;
+}
diff --git a/src/zlib/inftrees.h b/src/zlib/inftrees.h
new file mode 100644
index 0000000000..85853e097b
--- /dev/null
+++ b/src/zlib/inftrees.h
@@ -0,0 +1,58 @@
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* Huffman code lookup table entry--this entry is four bytes for machines
+   that have 16-bit pointers (e.g. PC's in the small or medium model). */
+
+typedef struct inflate_huft_s FAR inflate_huft;
+
+struct inflate_huft_s {
+  union {
+    struct {
+      Byte Exop;        /* number of extra bits or operation */
+      Byte Bits;        /* number of bits in this code or subcode */
+    } what;
+    uInt pad;           /* pad structure to a power of 2 (4 bytes for */
+  } word;               /*  16-bit, 8 bytes for 32-bit int's) */
+  uInt base;            /* literal, length base, distance base,
+                           or table offset */
+};
+
+/* Maximum size of dynamic tree.  The maximum found in a long but non-
+   exhaustive search was 1004 huft structures (850 for length/literals
+   and 154 for distances, the latter actually the result of an
+   exhaustive search).  The actual maximum is not known, but the
+   value below is more than safe. */
+#define MANY 1440
+
+extern int inflate_trees_bits OF((
+    uIntf *,                    /* 19 code lengths */
+    uIntf *,                    /* bits tree desired/actual depth */
+    inflate_huft * FAR *,       /* bits tree result */
+    inflate_huft *,             /* space for trees */
+    z_streamp));                /* for messages */
+
+extern int inflate_trees_dynamic OF((
+    uInt,                       /* number of literal/length codes */
+    uInt,                       /* number of distance codes */
+    uIntf *,                    /* that many (total) code lengths */
+    uIntf *,                    /* literal desired/actual bit depth */
+    uIntf *,                    /* distance desired/actual bit depth */
+    inflate_huft * FAR *,       /* literal/length tree result */
+    inflate_huft * FAR *,       /* distance tree result */
+    inflate_huft *,             /* space for trees */
+    z_streamp));                /* for messages */
+
+extern int inflate_trees_fixed OF((
+    uIntf *,                    /* literal desired/actual bit depth */
+    uIntf *,                    /* distance desired/actual bit depth */
+    inflate_huft * FAR *,       /* literal/length tree result */
+    inflate_huft * FAR *,       /* distance tree result */
+    z_streamp));                /* for memory allocation */
diff --git a/src/zlib/infutil.c b/src/zlib/infutil.c
new file mode 100644
index 0000000000..824dab5712
--- /dev/null
+++ b/src/zlib/infutil.c
@@ -0,0 +1,87 @@
+/* inflate_util.c -- data and routines common to blocks and codes
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include "zutil.h"
+#include "infblock.h"
+#include "inftrees.h"
+#include "infcodes.h"
+#include "infutil.h"
+
+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
+
+/* And'ing with mask[n] masks the lower n bits */
+uInt inflate_mask[17] = {
+    0x0000,
+    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
+    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
+};
+
+
+/* copy as much as possible from the sliding window to the output area */
+int inflate_flush(s, z, r)
+inflate_blocks_statef *s;
+z_streamp z;
+int r;
+{
+  uInt n;
+  Bytef *p;
+  Bytef *q;
+
+  /* local copies of source and destination pointers */
+  p = z->next_out;
+  q = s->read;
+
+  /* compute number of bytes to copy as far as end of window */
+  n = (uInt)((q <= s->write ? s->write : s->end) - q);
+  if (n > z->avail_out) n = z->avail_out;
+  if (n && r == Z_BUF_ERROR) r = Z_OK;
+
+  /* update counters */
+  z->avail_out -= n;
+  z->total_out += n;
+
+  /* update check information */
+  if (s->checkfn != Z_NULL)
+    z->adler = s->check = (*s->checkfn)(s->check, q, n);
+
+  /* copy as far as end of window */
+  zmemcpy(p, q, n);
+  p += n;
+  q += n;
+
+  /* see if more to copy at beginning of window */
+  if (q == s->end)
+  {
+    /* wrap pointers */
+    q = s->window;
+    if (s->write == s->end)
+      s->write = s->window;
+
+    /* compute bytes to copy */
+    n = (uInt)(s->write - q);
+    if (n > z->avail_out) n = z->avail_out;
+    if (n && r == Z_BUF_ERROR) r = Z_OK;
+
+    /* update counters */
+    z->avail_out -= n;
+    z->total_out += n;
+
+    /* update check information */
+    if (s->checkfn != Z_NULL)
+      z->adler = s->check = (*s->checkfn)(s->check, q, n);
+
+    /* copy */
+    zmemcpy(p, q, n);
+    p += n;
+    q += n;
+  }
+
+  /* update pointers */
+  z->next_out = p;
+  s->read = q;
+
+  /* done */
+  return r;
+}
diff --git a/src/zlib/infutil.h b/src/zlib/infutil.h
new file mode 100644
index 0000000000..99d1135d06
--- /dev/null
+++ b/src/zlib/infutil.h
@@ -0,0 +1,98 @@
+/* infutil.h -- types and macros common to blocks and codes
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+#ifndef _INFUTIL_H
+#define _INFUTIL_H
+
+typedef enum {
+      TYPE,     /* get type bits (3, including end bit) */
+      LENS,     /* get lengths for stored */
+      STORED,   /* processing stored block */
+      TABLE,    /* get table lengths */
+      BTREE,    /* get bit lengths tree for a dynamic block */
+      DTREE,    /* get length, distance trees for a dynamic block */
+      CODES,    /* processing fixed or dynamic block */
+      DRY,      /* output remaining window bytes */
+      DONE,     /* finished last block, done */
+      BAD}      /* got a data error--stuck here */
+inflate_block_mode;
+
+/* inflate blocks semi-private state */
+struct inflate_blocks_state {
+
+  /* mode */
+  inflate_block_mode  mode;     /* current inflate_block mode */
+
+  /* mode dependent information */
+  union {
+    uInt left;          /* if STORED, bytes left to copy */
+    struct {
+      uInt table;               /* table lengths (14 bits) */
+      uInt index;               /* index into blens (or border) */
+      uIntf *blens;             /* bit lengths of codes */
+      uInt bb;                  /* bit length tree depth */
+      inflate_huft *tb;         /* bit length decoding tree */
+    } trees;            /* if DTREE, decoding info for trees */
+    struct {
+      inflate_codes_statef 
+         *codes;
+    } decode;           /* if CODES, current state */
+  } sub;                /* submode */
+  uInt last;            /* true if this block is the last block */
+
+  /* mode independent information */
+  uInt bitk;            /* bits in bit buffer */
+  uLong bitb;           /* bit buffer */
+  inflate_huft *hufts;  /* single malloc for tree space */
+  Bytef *window;        /* sliding window */
+  Bytef *end;           /* one byte after sliding window */
+  Bytef *read;          /* window read pointer */
+  Bytef *write;         /* window write pointer */
+  check_func checkfn;   /* check function */
+  uLong check;          /* check on output */
+
+};
+
+
+/* defines for inflate input/output */
+/*   update pointers and return */
+#define UPDBITS {s->bitb=b;s->bitk=k;}
+#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
+#define UPDOUT {s->write=q;}
+#define UPDATE {UPDBITS UPDIN UPDOUT}
+#define LEAVE {UPDATE return inflate_flush(s,z,r);}
+/*   get bytes and bits */
+#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
+#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
+#define NEXTBYTE (n--,*p++)
+#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
+#define DUMPBITS(j) {b>>=(j);k-=(j);}
+/*   output bytes */
+#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
+#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
+#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
+#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
+#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
+#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
+/*   load local pointers */
+#define LOAD {LOADIN LOADOUT}
+
+/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
+extern uInt inflate_mask[17];
+
+/* copy as much as possible from the sliding window to the output area */
+extern int inflate_flush OF((
+    inflate_blocks_statef *,
+    z_streamp ,
+    int));
+
+struct internal_state      {int dummy;}; /* for buggy compilers */
+
+#endif
diff --git a/src/zlib/makefile.b32 b/src/zlib/makefile.b32
new file mode 100644
index 0000000000..bca4e90370
--- /dev/null
+++ b/src/zlib/makefile.b32
@@ -0,0 +1,107 @@
+# Makefile for zlib
+# Borland C++   
+
+# This version of the zlib makefile was adapted by Chris Young for use
+# with Borland C 4.5x with the Dos Power Pack for a 32-bit protected mode
+# flat memory model.  It was created for use with POV-Ray ray tracer and
+# you may choose to edit the CFLAGS to suit your needs but the
+# switches -WX and -DMSDOS are required.
+# -- Chris Young 76702.1655@compuserve.com
+
+# To use, do "make -fmakefile.b32"
+
+# See zconf.h for details about the memory requirements.
+
+# ------------- Borland C++ -------------
+MODEL=-WX 
+CFLAGS= $(MODEL) -P-C -K -N- -k- -d -3 -r- -v- -f -DMSDOS
+CC=bcc32
+LD=bcc32
+LIB=tlib
+LDFLAGS= $(MODEL)
+O=.obj
+
+LIBTARGET=..\..\..\lib\zlib.lib
+
+# variables
+OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \
+  trees$(O)
+OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\
+  trees$(O)
+OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \
+  infutil$(O) inffast$(O)
+OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\
+  infutil$(O)+inffast$(O)
+
+all: test
+
+adler32.obj: adler32.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+compress.obj: compress.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+crc32.obj: crc32.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+gzio.obj: gzio.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h\
+   infcodes.h infutil.h
+	$(CC) -c $(CFLAGS) $*.c
+
+infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h\
+   infcodes.h inffast.h
+	$(CC) -c $(CFLAGS) $*.c
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h
+	$(CC) -c $(CFLAGS) $*.c
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+	$(CC) -c $(CFLAGS) $*.c
+
+infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h
+	$(CC) -c $(CFLAGS) $*.c
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
+	$(CC) -c $(CFLAGS) $*.c
+
+trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+example.obj: example.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+minigzip.obj: minigzip.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+# we must cut the command line to fit in the MS/DOS 128 byte limit:
+$(LIBTARGET: $(OBJ1) $(OBJ2)
+	del $(LIBTARGET)
+	$(LIB) $(LIBTARGET) +$(OBJP1)
+	$(LIB) $(LIBTARGET) +$(OBJP2)
+
+example.exe: example.obj $(LIBTARGET)
+	$(LD) $(LDFLAGS) example.obj $(LIBTARGET)
+
+minigzip.exe: minigzip.obj $(LIBTARGET)
+	$(LD) $(LDFLAGS) minigzip.obj $(LIBTARGET)
+
+test: example.exe minigzip.exe
+	example
+	echo hello world | minigzip | minigzip -d 
+
+clean:
+	del *.obj
+	del *.exe
+        del $(LIBTARGET)
diff --git a/src/zlib/makefile.bcc b/src/zlib/makefile.bcc
new file mode 100644
index 0000000000..42d9d18e22
--- /dev/null
+++ b/src/zlib/makefile.bcc
@@ -0,0 +1,88 @@
+# Makefile for zlib
+# Borland C++   ************ UNTESTED ***********
+
+# To use, do "make -fmakefile.bor"
+
+# WARNING: the small model is supported but only for small values of
+# MAX_WBITS and MAX_MEM_LEVEL. If you wish to reduce the memory
+# requirements (default 256K for big objects plus a few K), you can add
+# to CFLAGS below: -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
+# See zconf.h for details about the memory requirements.
+
+# ------------- Turbo C++, Borland C++ -------------
+MODEL=-ml
+CFLAGS=-O2 -Z $(MODEL) -3 -Fs- 
+CC=bcc
+LD=bcc
+LIB=tlib
+#   replace bcc with tcc for Turbo C++ 1.0
+LDFLAGS=$(MODEL)
+O=.obj
+
+LIBTARGET=..\..\lib\zlib.lib
+
+# variables
+OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \
+  trees$(O)
+OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\
+  trees$(O)
+OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \
+  infutil$(O) inffast$(O)
+OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\
+  infutil$(O)+inffast$(O)
+
+all: $(LIBTARGET)
+
+adler32.obj: adler32.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+compress.obj: compress.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+crc32.obj: crc32.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+gzio.obj: gzio.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h\
+   infcodes.h infutil.h
+	$(CC) -c $(CFLAGS) $*.c
+
+infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h\
+   infcodes.h inffast.h
+	$(CC) -c $(CFLAGS) $*.c
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h
+	$(CC) -c $(CFLAGS) $*.c
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+	$(CC) -c $(CFLAGS) $*.c
+
+infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h
+	$(CC) -c $(CFLAGS) $*.c
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
+	$(CC) -c $(CFLAGS) $*.c
+
+trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+# we must cut the command line to fit in the MS/DOS 128 byte limit:
+$(LIBTARGET): $(OBJ1) $(OBJ2)
+	$(LIB) $(LIBTARGET) +$(OBJP1)
+	$(LIB) $(LIBTARGET) +$(OBJP2)
+
+clean:
+	-erase *.obj
+	-erase *.exe
+        -erase $(LIBTARGET)
diff --git a/src/zlib/makefile.nt b/src/zlib/makefile.nt
new file mode 100644
index 0000000000..207aaeb80f
--- /dev/null
+++ b/src/zlib/makefile.nt
@@ -0,0 +1,88 @@
+# Makefile for zlib
+# Borland C++   ************ UNTESTED ***********
+
+# To use, do "make -fmakefile.bor"
+
+# WARNING: the small model is supported but only for small values of
+# MAX_WBITS and MAX_MEM_LEVEL. If you wish to reduce the memory
+# requirements (default 256K for big objects plus a few K), you can add
+# to CFLAGS below: -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
+# See zconf.h for details about the memory requirements.
+
+# ------------- Turbo C++, Borland C++ -------------
+CFLAGS=-O2 /MDd /GX
+CC=cl
+LD=cl
+LIB=tlib
+#   replace bcc with tcc for Turbo C++ 1.0
+LDFLAGS=$(MODEL)
+O=.obj
+
+LIBTARGET=..\..\..\lib\zlib.lib
+
+# variables
+OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \
+  trees$(O) 
+OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \
+  infutil$(O) inffast$(O) 
+
+all: $(LIBTARGET)
+
+adler32.obj: adler32.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+compress.obj: compress.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+crc32.obj: crc32.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+gzio.obj: gzio.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h\
+   infcodes.h infutil.h
+	$(CC) -c $(CFLAGS) $*.c
+
+infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h\
+   infcodes.h inffast.h
+	$(CC) -c $(CFLAGS) $*.c
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h
+	$(CC) -c $(CFLAGS) $*.c
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+	$(CC) -c $(CFLAGS) $*.c
+
+infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h
+	$(CC) -c $(CFLAGS) $*.c
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
+	$(CC) -c $(CFLAGS) $*.c
+
+trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+LIBOBJECTS = $(OBJ1) $(OBJ2)
+
+$(LIBTARGET): $(LIBOBJECTS)
+        del $(LIBTARGET)
+        lib @<<
+-out:$(LIBTARGET)
+$(LIBOBJECTS)
+<<
+
+clean:
+	-erase *.obj
+	-erase *.exe
+        -erase *.sbr
+        -erase $(LIBTARGET)
diff --git a/src/zlib/makefile.unx b/src/zlib/makefile.unx
new file mode 100644
index 0000000000..7062ba8ec8
--- /dev/null
+++ b/src/zlib/makefile.unx
@@ -0,0 +1,133 @@
+#
+# File:		makefile.unx
+# Author:	Julian Smart
+# Created:	1993
+# Updated:	
+# Copyright:	(c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile for tree library and example (UNIX).
+# Change the WXDIR directory, and CPPFLAGS and LDFLAGS, for your system.
+
+WXDIR = ../..
+
+# All common UNIX compiler flags and options are now in
+# this central makefile.
+include $(WXDIR)/src/make.env
+
+ZLIBDIR = $(WXDIR)/utils/zlib
+ZLIBLIB = $(WXDIR)/lib/libzlib$(GUISUFFIX).a
+
+SOURCES =	adler32.c deflate.c infblock.c inflate.c zutil.c compress.c \
+		infcodes.c inftrees.c trees.c \
+		crc32.c gzio.c inffast.c infutil.c uncompr.c
+OBJECTS =	$(OBJDIR)/adler32.$(OBJSUFF) $(OBJDIR)/deflate.$(OBJSUFF) \
+		$(OBJDIR)/infblock.$(OBJSUFF) $(OBJDIR)/inflate.$(OBJSUFF) \
+		$(OBJDIR)/zutil.$(OBJSUFF) $(OBJDIR)/trees.$(OBJSUFF) \
+		$(OBJDIR)/compress.$(OBJSUFF) $(OBJDIR)/infcodes.$(OBJSUFF) \
+		$(OBJDIR)/inftrees.$(OBJSUFF) $(OBJDIR)/crc32.$(OBJSUFF) \
+		$(OBJDIR)/gzio.$(OBJSUFF) $(OBJDIR)/inffast.$(OBJSUFF) \
+		$(OBJDIR)/infutil.$(OBJSUFF) $(OBJDIR)/uncompr.$(OBJSUFF)
+
+# Default
+
+.SUFFIXES:
+
+all:	$(OBJDIR) $(ZLIBLIB)
+
+demo:
+
+$(ZLIBLIB): $(OBJECTS)
+	rm -f $@
+	ar $(AROPTIONS) $@ $(OBJECTS)
+	$(RANLIB) $@
+
+motif:
+	$(MAKE) -f makefile.unx GUISUFFIX=_motif GUI=-Dwx_motif GUISUFFIX=_motif DEBUG='$(DEBUG)' OPT='$(OPT)' LDLIBS='$(MOTIFLDLIBS)' XVIEW_LINK=
+
+xview:
+	$(MAKE) -f makefile.unx GUI=-Dwx_xview GUISUFFIX=_ol OPT='$(OPT)' DEBUG='$(DEBUG)'
+
+demo_motif:
+	$(MAKE) -f makefile.unx all test_motif GUI=-Dwx_motif GUISUFFIX=_motif DEBUG='$(DEBUG)' OPT='$(OPT)' LDLIBS='$(MOTIFLDLIBS)' XVIEW_LINK=
+
+demo_ol:
+	cd $(WXDIR)/src/x; $(MAKE) -f makefile.unx xview OPT='$(OPT)' DEBUG='$(DEBUG)'
+	$(MAKE) -f makefile.unx all test_ol GUI=-Dwx_xview OPT='$(OPT)' DEBUG='$(DEBUG)'
+
+hp:
+	$(MAKE) -f makefile.unx GUI=-Dwx_motif GUISUFFIX=_hp CC=CC DEBUG='$(DEBUG)' DEBUGFLAGS='-g' OPT='' WARN='-w' \
+           XINCLUDE='$(HPXINCLUDE)' XLIB='$(HPXLIB)' XVIEW_LINK='' CCLEX='cc' \
+           LDLIBS='$(HPLDLIBS)'
+
+demo_hp:
+	$(MAKE) -f makefile.unx all test_hp GUI=-Dwx_motif GUISUFFIX=_hp CC=CC DEBUG='$(DEBUG)' DEBUGFLAGS='-g' OPT='' WARN='-w' \
+           XINCLUDE='$(HPXINCLUDE)' XLIB='$(HPXLIB)' XVIEW_LINK='' CCLEX='cc' \
+           LDLIBS='$(HPLDLIBS)'
+
+$(OBJDIR):
+	mkdir $(OBJDIR)
+
+$(OBJDIR)/adler32.$(OBJSUFF):	adler32.c
+	$(CC) -c $(CPPFLAGS) -o $@ adler32.c
+
+$(OBJDIR)/deflate.$(OBJSUFF):	deflate.c
+	$(CC) -c $(CPPFLAGS) -o $@ deflate.c
+
+$(OBJDIR)/infblock.$(OBJSUFF):	infblock.c
+	$(CC) -c $(CPPFLAGS) -o $@ infblock.c
+
+$(OBJDIR)/inflate.$(OBJSUFF):	inflate.c
+	$(CC) -c $(CPPFLAGS) -o $@ inflate.c
+
+$(OBJDIR)/zutil.$(OBJSUFF):	zutil.c
+	$(CC) -c $(CPPFLAGS) -o $@ zutil.c
+
+$(OBJDIR)/compress.$(OBJSUFF):	compress.c
+	$(CC) -c $(CPPFLAGS) -o $@ compress.c
+
+$(OBJDIR)/infcodes.$(OBJSUFF):	infcodes.c
+	$(CC) -c $(CPPFLAGS) -o $@ infcodes.c
+
+$(OBJDIR)/inftrees.$(OBJSUFF):	inftrees.c
+	$(CC) -c $(CPPFLAGS) -o $@ inftrees.c
+
+$(OBJDIR)/trees.$(OBJSUFF):	trees.c
+	$(CC) -c $(CPPFLAGS) -o $@ trees.c
+
+$(OBJDIR)/crc32.$(OBJSUFF):	crc32.c
+	$(CC) -c $(CPPFLAGS) -o $@ crc32.c
+
+$(OBJDIR)/gzio.$(OBJSUFF):	gzio.c
+	$(CC) -c $(CPPFLAGS) -o $@ gzio.c
+
+$(OBJDIR)/inffast.$(OBJSUFF):	inffast.c
+	$(CC) -c $(CPPFLAGS) -o $@ inffast.c
+
+$(OBJDIR)/infutil.$(OBJSUFF):	infutil.c
+	$(CC) -c $(CPPFLAGS) -o $@ infutil.c
+
+$(OBJDIR)/uncompr.$(OBJSUFF):	uncompr.c
+	$(CC) -c $(CPPFLAGS) -o $@ uncompr.c
+
+clean_motif:
+	$(MAKE) -f makefile.unx GUISUFFIX=_motif cleanany
+
+clean_ol:
+	$(MAKE) -f makefile.unx GUISUFFIX=_ol cleanany
+
+clean_hp:
+	$(MAKE) -f makefile.unx GUISUFFIX=_hp cleanany
+
+cleanany:
+	rm -f $(OBJECTS) $(OBJDIR)/*.$(OBJSUFF) $(ZLIBLIB) core
+
+wxclean_ol:
+	cd $(WXDIR)/src/x; $(MAKE) -f makefile.unx clean_ol
+
+wxclean_motif:
+	cd $(WXDIR)/src/x; $(MAKE) -f makefile.unx clean_motif
+
+wxclean_hp:
+	cd $(WXDIR)/src/x; $(MAKE) -f makefile.unx clean_hp
diff --git a/src/zlib/makefile.wat b/src/zlib/makefile.wat
new file mode 100644
index 0000000000..0bce2f20b3
--- /dev/null
+++ b/src/zlib/makefile.wat
@@ -0,0 +1,105 @@
+# Makefile for zlib
+# Watcom 10a
+
+# This version of the zlib makefile was adapted by Chris Young for use
+# with Watcom 10a 32-bit protected mode flat memory model.  It was created 
+# for use with POV-Ray ray tracer and you may choose to edit the CFLAGS to 
+# suit your needs but the -DMSDOS is required.
+# -- Chris Young 76702.1655@compuserve.com
+
+# To use, do "wmake -f makefile.wat"
+
+# See zconf.h for details about the memory requirements.
+
+# ------------- Watcom 10a -------------
+MODEL=-mf 
+CFLAGS= $(MODEL) -fpi87 -fp5 -zp4 -5r -w5 -oneatx -DMSDOS
+CC=wcc386
+LD=wcl386
+LIB=wlib -b -c 
+LDFLAGS= 
+O=.obj
+LIBTARGET=..\..\..\lib\zlib.lib
+
+# variables
+OBJ1=adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) 
+OBJ2=trees$(O) zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) 
+OBJ3=infutil$(O) inffast$(O)
+OBJP1=adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)
+OBJP2=trees$(O)+zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)
+OBJP3=infutil$(O)+inffast$(O)
+
+all: test
+
+adler32.obj: adler32.c zutil.h zlib.h zconf.h
+	$(CC) $(CFLAGS) $*.c
+
+compress.obj: compress.c zlib.h zconf.h
+	$(CC) $(CFLAGS) $*.c
+
+crc32.obj: crc32.c zutil.h zlib.h zconf.h
+	$(CC) $(CFLAGS) $*.c
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+	$(CC) $(CFLAGS) $*.c
+
+gzio.obj: gzio.c zutil.h zlib.h zconf.h
+	$(CC) $(CFLAGS) $*.c
+
+infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h &
+  infcodes.h infutil.h
+	$(CC) $(CFLAGS) $*.c
+
+infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h &
+  infcodes.h inffast.h
+	$(CC) $(CFLAGS) $*.c
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h
+	$(CC) $(CFLAGS) $*.c
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+	$(CC) $(CFLAGS) $*.c
+
+infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h
+	$(CC) $(CFLAGS) $*.c
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
+	$(CC) $(CFLAGS) $*.c
+
+trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h
+	$(CC) $(CFLAGS) $*.c
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+	$(CC) $(CFLAGS) $*.c
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+	$(CC) $(CFLAGS) $*.c
+
+example.obj: example.c zlib.h zconf.h
+	$(CC) $(CFLAGS) $*.c
+
+minigzip.obj: minigzip.c zlib.h zconf.h
+	$(CC) $(CFLAGS) $*.c
+
+# we must cut the command line to fit in the MS/DOS 128 byte limit:
+$(LIBTARGET): $(OBJ1) $(OBJ2) $(OBJ3) 
+	del $(LIBTARGET)
+	$(LIB) $(LIBTARGET) +$(OBJP1)
+	$(LIB) $(LIBTARGET) +$(OBJP2)
+	$(LIB) $(LIBTARGET) +$(OBJP3)
+
+example.exe: example.obj $(LIBTARGET)
+	$(LD) $(LDFLAGS) example.obj $(LIBTARGET)
+
+minigzip.exe: minigzip.obj $(LIBTARGET)
+	$(LD) $(LDFLAGS) minigzip.obj $(LIBTARGET)
+
+test: minigzip.exe example.exe
+	example
+	echo hello world | minigzip | minigzip -d >test
+	type test
+
+clean:
+	-erase *.obj
+	-erase *.exe
+        -erase $(LIBTARGET)
diff --git a/src/zlib/maketree.c b/src/zlib/maketree.c
new file mode 100644
index 0000000000..66dd828318
--- /dev/null
+++ b/src/zlib/maketree.c
@@ -0,0 +1,119 @@
+/* maketree.c -- make inffixed.h table for decoding fixed codes
+ * Copyright (C) 1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* This program is included in the distribution for completeness.
+   You do not need to compile or run this program since inffixed.h
+   is already included in the distribution.  To use this program
+   you need to compile zlib with BUILDFIXED defined and then compile
+   and link this program with the zlib library.  Then the output of
+   this program can be piped to inffixed.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "zutil.h"
+#include "inftrees.h"
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+/* showtree is only used for debugging purposes */
+void showtree(uInt b, inflate_huft *t, int d)
+{
+  int i, e;
+  char p[2*d+1];
+
+  for (i = 0; i < 2*d; i++)
+    p[i] = ' ';
+  p[i] = 0;
+  printf("%s[%d]\n", p, 1<<b);
+  for (i = 0; i < (1<<b); i++)
+  {
+    e = t[i].exop;
+    if (e == 0)                 /* simple code */
+      printf("%s%d(%d): literal=%d\n", p, i, t[i].bits, t[i].base);
+    else if (e & 16)            /* length */
+      printf("%s%d(%d): length/distance=%d+(%d)\n",
+                p, i, t[i].bits, t[i].base, e & 15);
+    else if ((e & 64) == 0)     /* next table */
+    {
+      printf("%s%d(%d): *sub table*\n", p, i, t[i].bits);
+      showtree(e, t + t[i].base, d + 1);
+    }
+    else if (e & 32)            /* end of block */
+      printf("%s%d(%d): end of block\n", p, i, t[i].bits);
+    else                        /* bad code */
+      printf("%s%d: bad code\n", p, i);
+  }
+}
+
+/* generate initialization table for an inflate_huft structure array */
+void maketree(uInt b, inflate_huft *t)
+{
+  int i, e;
+
+  i = 0;
+  while (1)
+  {
+    e = t[i].exop;
+    if (e && (e & (16+64)) == 0)        /* table pointer */
+    {
+      fprintf(stderr, "maketree: cannot initialize sub-tables!\n");
+      exit(1);
+    }
+    if (i % 5 == 0)
+      printf("\n   ");
+    printf(" {{%u,%u},%u}", t[i].exop, t[i].bits, t[i].base);
+    if (++i == (1<<b))
+      break;
+    putchar(',');
+  }
+  puts("");
+}
+
+/* create the fixed tables in C initialization syntax */
+void main(void)
+{
+  int r;
+  uInt bl, bd;
+  inflate_huft *tl, *td;
+  z_stream z;
+
+  z.zalloc = zcalloc;
+  z.opaque = (voidpf)0;
+  z.zfree = zcfree;
+  r = inflate_trees_fixed(&bl, &bd, &tl, &td, &z);
+  if (r)
+  {
+    fprintf(stderr, "inflate_trees_fixed error %d\n", r);
+    return;
+  }
+  /* puts("Literal/Length Tree:");
+     showtree(bl, tl, 1);
+     puts("Distance Tree:");
+     showtree(bd, td, 1); */
+  puts("/* inffixed.h -- table for decoding fixed codes");
+  puts(" * Generated automatically by the maketree.c program");
+  puts(" */");
+  puts("");
+  puts("/* WARNING: this file should *not* be used by applications. It is");
+  puts("   part of the implementation of the compression library and is");
+  puts("   subject to change. Applications should only use zlib.h.");
+  puts(" */");
+  puts("");
+  printf("local uInt fixed_bl = %d;\n", bl);
+  printf("local uInt fixed_bd = %d;\n", bd);
+  printf("local inflate_huft fixed_tl[] = {");
+  maketree(bl, tl);
+  puts("  };");
+  printf("local inflate_huft fixed_td[] = {");
+  maketree(bd, td);
+  puts("  };");
+}
diff --git a/src/zlib/minigzip.c b/src/zlib/minigzip.c
new file mode 100644
index 0000000000..c05d0ea92f
--- /dev/null
+++ b/src/zlib/minigzip.c
@@ -0,0 +1,317 @@
+/* minigzip.c -- simulate gzip using the zlib compression library
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/*
+ * minigzip is a minimal implementation of the gzip utility. This is
+ * only an example of using zlib and isn't meant to replace the
+ * full-featured gzip. No attempt is made to deal with file systems
+ * limiting names to 14 or 8+3 characters, etc... Error checking is
+ * very limited. So use minigzip only for testing; use gzip for the
+ * real thing. On MSDOS, use only on file names without extension
+ * or in pipe mode.
+ */
+
+/* @(#) $Id$ */
+
+#include <stdio.h>
+#include "zlib.h"
+
+#ifdef STDC
+#  include <string.h>
+#  include <stdlib.h>
+#else
+   extern void exit  OF((int));
+#endif
+
+#ifdef USE_MMAP
+#  include <sys/types.h>
+#  include <sys/mman.h>
+#  include <sys/stat.h>
+#endif
+
+#if defined(MSDOS) || defined(OS2) || defined(WIN32)
+#  include <fcntl.h>
+#  include <io.h>
+#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+#else
+#  define SET_BINARY_MODE(file)
+#endif
+
+#ifdef VMS
+#  define unlink delete
+#  define GZ_SUFFIX "-gz"
+#endif
+#ifdef RISCOS
+#  define unlink remove
+#  define GZ_SUFFIX "-gz"
+#  define fileno(file) file->__file
+#endif
+
+#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
+  extern int unlink OF((const char *));
+#endif
+
+#ifndef GZ_SUFFIX
+#  define GZ_SUFFIX ".gz"
+#endif
+#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
+
+#define BUFLEN      16384
+#define MAX_NAME_LEN 1024
+
+#ifdef MAXSEG_64K
+#  define local static
+   /* Needed for systems with limitation on stack size. */
+#else
+#  define local
+#endif
+
+char *prog;
+
+void error            OF((const char *msg));
+void gz_compress      OF((FILE   *in, gzFile out));
+#ifdef USE_MMAP
+int  gz_compress_mmap OF((FILE   *in, gzFile out));
+#endif
+void gz_uncompress    OF((gzFile in, FILE   *out));
+void file_compress    OF((char  *file, char *mode));
+void file_uncompress  OF((char  *file));
+int  main             OF((int argc, char *argv[]));
+
+/* ===========================================================================
+ * Display error message and exit
+ */
+void error(msg)
+    const char *msg;
+{
+    fprintf(stderr, "%s: %s\n", prog, msg);
+    exit(1);
+}
+
+/* ===========================================================================
+ * Compress input to output then close both files.
+ */
+
+void gz_compress(in, out)
+    FILE   *in;
+    gzFile out;
+{
+    local char buf[BUFLEN];
+    int len;
+    int err;
+
+#ifdef USE_MMAP
+    /* Try first compressing with mmap. If mmap fails (minigzip used in a
+     * pipe), use the normal fread loop.
+     */
+    if (gz_compress_mmap(in, out) == Z_OK) return;
+#endif
+    for (;;) {
+        len = fread(buf, 1, sizeof(buf), in);
+        if (ferror(in)) {
+            perror("fread");
+            exit(1);
+        }
+        if (len == 0) break;
+
+        if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
+    }
+    fclose(in);
+    if (gzclose(out) != Z_OK) error("failed gzclose");
+}
+
+#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
+
+/* Try compressing the input file at once using mmap. Return Z_OK if
+ * if success, Z_ERRNO otherwise.
+ */
+int gz_compress_mmap(in, out)
+    FILE   *in;
+    gzFile out;
+{
+    int len;
+    int err;
+    int ifd = fileno(in);
+    caddr_t buf;    /* mmap'ed buffer for the entire input file */
+    off_t buf_len;  /* length of the input file */
+    struct stat sb;
+
+    /* Determine the size of the file, needed for mmap: */
+    if (fstat(ifd, &sb) < 0) return Z_ERRNO;
+    buf_len = sb.st_size;
+    if (buf_len <= 0) return Z_ERRNO;
+
+    /* Now do the actual mmap: */
+    buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); 
+    if (buf == (caddr_t)(-1)) return Z_ERRNO;
+
+    /* Compress the whole file at once: */
+    len = gzwrite(out, (char *)buf, (unsigned)buf_len);
+
+    if (len != (int)buf_len) error(gzerror(out, &err));
+
+    munmap(buf, buf_len);
+    fclose(in);
+    if (gzclose(out) != Z_OK) error("failed gzclose");
+    return Z_OK;
+}
+#endif /* USE_MMAP */
+
+/* ===========================================================================
+ * Uncompress input to output then close both files.
+ */
+void gz_uncompress(in, out)
+    gzFile in;
+    FILE   *out;
+{
+    local char buf[BUFLEN];
+    int len;
+    int err;
+
+    for (;;) {
+        len = gzread(in, buf, sizeof(buf));
+        if (len < 0) error (gzerror(in, &err));
+        if (len == 0) break;
+
+        if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
+	    error("failed fwrite");
+	}
+    }
+    if (fclose(out)) error("failed fclose");
+
+    if (gzclose(in) != Z_OK) error("failed gzclose");
+}
+
+
+/* ===========================================================================
+ * Compress the given file: create a corresponding .gz file and remove the
+ * original.
+ */
+void file_compress(file, mode)
+    char  *file;
+    char  *mode;
+{
+    local char outfile[MAX_NAME_LEN];
+    FILE  *in;
+    gzFile out;
+
+    strcpy(outfile, file);
+    strcat(outfile, GZ_SUFFIX);
+
+    in = fopen(file, "rb");
+    if (in == NULL) {
+        perror(file);
+        exit(1);
+    }
+    out = gzopen(outfile, mode);
+    if (out == NULL) {
+        fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
+        exit(1);
+    }
+    gz_compress(in, out);
+
+    unlink(file);
+}
+
+
+/* ===========================================================================
+ * Uncompress the given file and remove the original.
+ */
+void file_uncompress(file)
+    char  *file;
+{
+    local char buf[MAX_NAME_LEN];
+    char *infile, *outfile;
+    FILE  *out;
+    gzFile in;
+    int len = strlen(file);
+
+    strcpy(buf, file);
+
+    if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
+        infile = file;
+        outfile = buf;
+        outfile[len-3] = '\0';
+    } else {
+        outfile = file;
+        infile = buf;
+        strcat(infile, GZ_SUFFIX);
+    }
+    in = gzopen(infile, "rb");
+    if (in == NULL) {
+        fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
+        exit(1);
+    }
+    out = fopen(outfile, "wb");
+    if (out == NULL) {
+        perror(file);
+        exit(1);
+    }
+
+    gz_uncompress(in, out);
+
+    unlink(infile);
+}
+
+
+/* ===========================================================================
+ * Usage:  minigzip [-d] [-f] [-h] [-1 to -9] [files...]
+ *   -d : decompress
+ *   -f : compress with Z_FILTERED
+ *   -h : compress with Z_HUFFMAN_ONLY
+ *   -1 to -9 : compression level
+ */
+
+int main(argc, argv)
+    int argc;
+    char *argv[];
+{
+    int uncompr = 0;
+    gzFile file;
+    char outmode[20];
+
+    strcpy(outmode, "wb6 ");
+
+    prog = argv[0];
+    argc--, argv++;
+
+    while (argc > 0) {
+      if (strcmp(*argv, "-d") == 0)
+	uncompr = 1;
+      else if (strcmp(*argv, "-f") == 0)
+	outmode[3] = 'f';
+      else if (strcmp(*argv, "-h") == 0)
+	outmode[3] = 'h';
+      else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
+	       (*argv)[2] == 0)
+	outmode[2] = (*argv)[1];
+      else
+	break;
+      argc--, argv++;
+    }
+    if (argc == 0) {
+        SET_BINARY_MODE(stdin);
+        SET_BINARY_MODE(stdout);
+        if (uncompr) {
+            file = gzdopen(fileno(stdin), "rb");
+            if (file == NULL) error("can't gzdopen stdin");
+            gz_uncompress(file, stdout);
+        } else {
+            file = gzdopen(fileno(stdout), outmode);
+            if (file == NULL) error("can't gzdopen stdout");
+            gz_compress(stdin, file);
+        }
+    } else {
+        do {
+            if (uncompr) {
+                file_uncompress(*argv);
+            } else {
+                file_compress(*argv, outmode);
+            }
+        } while (argv++, --argc);
+    }
+    exit(0);
+    return 0; /* to avoid warning */
+}
diff --git a/src/zlib/trees.c b/src/zlib/trees.c
new file mode 100644
index 0000000000..ef31043764
--- /dev/null
+++ b/src/zlib/trees.c
@@ -0,0 +1,1216 @@
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995-1998 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process uses several Huffman trees. The more
+ *      common source values are represented by shorter bit sequences.
+ *
+ *      Each code tree is stored in a compressed form which is itself
+ * a Huffman encoding of the lengths of all the code strings (in
+ * ascending order by source values).  The actual code strings are
+ * reconstructed from the lengths in the inflate process, as described
+ * in the deflate specification.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
+ *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
+ *
+ *      Storer, James A.
+ *          Data Compression:  Methods and Theory, pp. 49-50.
+ *          Computer Science Press, 1988.  ISBN 0-7167-8156-5.
+ *
+ *      Sedgewick, R.
+ *          Algorithms, p290.
+ *          Addison-Wesley, 1983. ISBN 0-201-06672-6.
+ */
+
+/* @(#) $Id$ */
+
+/* #define GEN_TREES_H */
+
+#include "deflate.h"
+
+#ifdef DEBUG
+#  include <ctype.h>
+#endif
+
+/* ===========================================================================
+ * Constants
+ */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define REP_3_6      16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+#define REPZ_3_10    17
+/* repeat a zero length 3-10 times  (3 bits of repeat count) */
+
+#define REPZ_11_138  18
+/* repeat a zero length 11-138 times  (7 bits of repeat count) */
+
+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
+   = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
+
+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
+   = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+
+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
+   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+local const uch bl_order[BL_CODES]
+   = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+#define Buf_size (8 * 2*sizeof(char))
+/* Number of bits used within bi_buf. (bi_buf might be implemented on
+ * more than 16 bits on some systems.)
+ */
+
+/* ===========================================================================
+ * Local data. These are initialized only once.
+ */
+
+#define DIST_CODE_LEN  512 /* see definition of array dist_code below */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+/* non ANSI compilers may not accept trees.h */
+
+local ct_data static_ltree[L_CODES+2];
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
+ * below).
+ */
+
+local ct_data static_dtree[D_CODES];
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+uch _dist_code[DIST_CODE_LEN];
+/* Distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+uch _length_code[MAX_MATCH-MIN_MATCH+1];
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+local int base_length[LENGTH_CODES];
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+local int base_dist[D_CODES];
+/* First normalized distance for each code (0 = distance of 1) */
+
+#else
+#  include "trees.h"
+#endif /* GEN_TREES_H */
+
+struct static_tree_desc_s {
+    const ct_data *static_tree;  /* static tree or NULL */
+    const intf *extra_bits;      /* extra bits for each code or NULL */
+    int     extra_base;          /* base index for extra_bits */
+    int     elems;               /* max number of elements in the tree */
+    int     max_length;          /* max bit length for the codes */
+};
+
+local static_tree_desc  static_l_desc =
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
+
+local static_tree_desc  static_d_desc =
+{static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS};
+
+local static_tree_desc  static_bl_desc =
+{(const ct_data *)0, extra_blbits, 0,   BL_CODES, MAX_BL_BITS};
+
+/* ===========================================================================
+ * Local (static) routines in this file.
+ */
+
+local void tr_static_init OF((void));
+local void init_block     OF((deflate_state *s));
+local void pqdownheap     OF((deflate_state *s, ct_data *tree, int k));
+local void gen_bitlen     OF((deflate_state *s, tree_desc *desc));
+local void gen_codes      OF((ct_data *tree, int max_code, ushf *bl_count));
+local void build_tree     OF((deflate_state *s, tree_desc *desc));
+local void scan_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local void send_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local int  build_bl_tree  OF((deflate_state *s));
+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
+                              int blcodes));
+local void compress_block OF((deflate_state *s, ct_data *ltree,
+                              ct_data *dtree));
+local void set_data_type  OF((deflate_state *s));
+local unsigned bi_reverse OF((unsigned value, int length));
+local void bi_windup      OF((deflate_state *s));
+local void bi_flush       OF((deflate_state *s));
+local void copy_block     OF((deflate_state *s, charf *buf, unsigned len,
+                              int header));
+
+#ifdef GEN_TREES_H
+local void gen_trees_header OF((void));
+#endif
+
+#ifndef DEBUG
+#  define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
+   /* Send a code of the given tree. c and tree must not have side effects */
+
+#else /* DEBUG */
+#  define send_code(s, c, tree) \
+     { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
+       send_bits(s, tree[c].Code, tree[c].Len); }
+#endif
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+    put_byte(s, (uch)((w) & 0xff)); \
+    put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+#ifdef DEBUG
+local void send_bits      OF((deflate_state *s, int value, int length));
+
+local void send_bits(s, value, length)
+    deflate_state *s;
+    int value;  /* value to send */
+    int length; /* number of bits */
+{
+    Tracevv((stderr," l %2d v %4x ", length, value));
+    Assert(length > 0 && length <= 15, "invalid length");
+    s->bits_sent += (ulg)length;
+
+    /* If not enough room in bi_buf, use (valid) bits from bi_buf and
+     * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
+     * unused bits in value.
+     */
+    if (s->bi_valid > (int)Buf_size - length) {
+        s->bi_buf |= (value << s->bi_valid);
+        put_short(s, s->bi_buf);
+        s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
+        s->bi_valid += length - Buf_size;
+    } else {
+        s->bi_buf |= value << s->bi_valid;
+        s->bi_valid += length;
+    }
+}
+#else /* !DEBUG */
+
+#define send_bits(s, value, length) \
+{ int len = length;\
+  if (s->bi_valid > (int)Buf_size - len) {\
+    int val = value;\
+    s->bi_buf |= (val << s->bi_valid);\
+    put_short(s, s->bi_buf);\
+    s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
+    s->bi_valid += len - Buf_size;\
+  } else {\
+    s->bi_buf |= (value) << s->bi_valid;\
+    s->bi_valid += len;\
+  }\
+}
+#endif /* DEBUG */
+
+
+#define MAX(a,b) (a >= b ? a : b)
+/* the arguments must not have side effects */
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables.
+ */
+local void tr_static_init()
+{
+#if defined(GEN_TREES_H) || !defined(STDC)
+    static int static_init_done = 0;
+    int n;        /* iterates over tree elements */
+    int bits;     /* bit counter */
+    int length;   /* length value */
+    int code;     /* code value */
+    int dist;     /* distance index */
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    if (static_init_done) return;
+
+    /* Initialize the mapping length (0..255) -> length code (0..28) */
+    length = 0;
+    for (code = 0; code < LENGTH_CODES-1; code++) {
+        base_length[code] = length;
+        for (n = 0; n < (1<<extra_lbits[code]); n++) {
+            _length_code[length++] = (uch)code;
+        }
+    }
+    Assert (length == 256, "tr_static_init: length != 256");
+    /* Note that the length 255 (match length 258) can be represented
+     * in two different ways: code 284 + 5 bits or code 285, so we
+     * overwrite length_code[255] to use the best encoding:
+     */
+    _length_code[length-1] = (uch)code;
+
+    /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+    dist = 0;
+    for (code = 0 ; code < 16; code++) {
+        base_dist[code] = dist;
+        for (n = 0; n < (1<<extra_dbits[code]); n++) {
+            _dist_code[dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: dist != 256");
+    dist >>= 7; /* from now on, all distances are divided by 128 */
+    for ( ; code < D_CODES; code++) {
+        base_dist[code] = dist << 7;
+        for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
+            _dist_code[256 + dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+    /* Construct the codes of the static literal tree */
+    for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
+    n = 0;
+    while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
+    while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
+    while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
+    while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
+    /* Codes 286 and 287 do not exist, but we must include them in the
+     * tree construction to get a canonical Huffman tree (longest code
+     * all ones)
+     */
+    gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
+
+    /* The static distance tree is trivial: */
+    for (n = 0; n < D_CODES; n++) {
+        static_dtree[n].Len = 5;
+        static_dtree[n].Code = bi_reverse((unsigned)n, 5);
+    }
+    static_init_done = 1;
+
+#  ifdef GEN_TREES_H
+    gen_trees_header();
+#  endif
+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
+}
+
+/* ===========================================================================
+ * Genererate the file trees.h describing the static trees.
+ */
+#ifdef GEN_TREES_H
+#  ifndef DEBUG
+#    include <stdio.h>
+#  endif
+
+#  define SEPARATOR(i, last, width) \
+      ((i) == (last)? "\n};\n\n" :    \
+       ((i) % (width) == (width)-1 ? ",\n" : ", "))
+
+void gen_trees_header()
+{
+    FILE *header = fopen("trees.h", "w");
+    int i;
+
+    Assert (header != NULL, "Can't open trees.h");
+    fprintf(header,
+	    "/* header created automatically with -DGEN_TREES_H */\n\n");
+
+    fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
+    for (i = 0; i < L_CODES+2; i++) {
+	fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
+		static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
+    }
+
+    fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
+    for (i = 0; i < D_CODES; i++) {
+	fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
+		static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
+    }
+
+    fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
+    for (i = 0; i < DIST_CODE_LEN; i++) {
+	fprintf(header, "%2u%s", _dist_code[i],
+		SEPARATOR(i, DIST_CODE_LEN-1, 20));
+    }
+
+    fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
+    for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
+	fprintf(header, "%2u%s", _length_code[i],
+		SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
+    }
+
+    fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
+    for (i = 0; i < LENGTH_CODES; i++) {
+	fprintf(header, "%1u%s", base_length[i],
+		SEPARATOR(i, LENGTH_CODES-1, 20));
+    }
+
+    fprintf(header, "local const int base_dist[D_CODES] = {\n");
+    for (i = 0; i < D_CODES; i++) {
+	fprintf(header, "%5u%s", base_dist[i],
+		SEPARATOR(i, D_CODES-1, 10));
+    }
+
+    fclose(header);
+}
+#endif /* GEN_TREES_H */
+
+/* ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+void _tr_init(s)
+    deflate_state *s;
+{
+    tr_static_init();
+
+    s->compressed_len = 0L;
+
+    s->l_desc.dyn_tree = s->dyn_ltree;
+    s->l_desc.stat_desc = &static_l_desc;
+
+    s->d_desc.dyn_tree = s->dyn_dtree;
+    s->d_desc.stat_desc = &static_d_desc;
+
+    s->bl_desc.dyn_tree = s->bl_tree;
+    s->bl_desc.stat_desc = &static_bl_desc;
+
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+    s->last_eob_len = 8; /* enough lookahead for inflate */
+#ifdef DEBUG
+    s->bits_sent = 0L;
+#endif
+
+    /* Initialize the first block of the first file: */
+    init_block(s);
+}
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+local void init_block(s)
+    deflate_state *s;
+{
+    int n; /* iterates over tree elements */
+
+    /* Initialize the trees. */
+    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
+    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
+    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+    s->dyn_ltree[END_BLOCK].Freq = 1;
+    s->opt_len = s->static_len = 0L;
+    s->last_lit = s->matches = 0;
+}
+
+#define SMALLEST 1
+/* Index within the heap array of least frequent node in the Huffman tree */
+
+
+/* ===========================================================================
+ * Remove the smallest element from the heap and recreate the heap with
+ * one less element. Updates heap and heap_len.
+ */
+#define pqremove(s, tree, top) \
+{\
+    top = s->heap[SMALLEST]; \
+    s->heap[SMALLEST] = s->heap[s->heap_len--]; \
+    pqdownheap(s, tree, SMALLEST); \
+}
+
+/* ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length.
+ */
+#define smaller(tree, n, m, depth) \
+   (tree[n].Freq < tree[m].Freq || \
+   (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+local void pqdownheap(s, tree, k)
+    deflate_state *s;
+    ct_data *tree;  /* the tree to restore */
+    int k;               /* node to move down */
+{
+    int v = s->heap[k];
+    int j = k << 1;  /* left son of k */
+    while (j <= s->heap_len) {
+        /* Set j to the smallest of the two sons: */
+        if (j < s->heap_len &&
+            smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
+            j++;
+        }
+        /* Exit if v is smaller than both sons */
+        if (smaller(tree, v, s->heap[j], s->depth)) break;
+
+        /* Exchange v with the smallest son */
+        s->heap[k] = s->heap[j];  k = j;
+
+        /* And continue down the tree, setting j to the left son of k */
+        j <<= 1;
+    }
+    s->heap[k] = v;
+}
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ *    above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ *     array bl_count contains the frequencies for each bit length.
+ *     The length opt_len is updated; static_len is also updated if stree is
+ *     not null.
+ */
+local void gen_bitlen(s, desc)
+    deflate_state *s;
+    tree_desc *desc;    /* the tree descriptor */
+{
+    ct_data *tree        = desc->dyn_tree;
+    int max_code         = desc->max_code;
+    const ct_data *stree = desc->stat_desc->static_tree;
+    const intf *extra    = desc->stat_desc->extra_bits;
+    int base             = desc->stat_desc->extra_base;
+    int max_length       = desc->stat_desc->max_length;
+    int h;              /* heap index */
+    int n, m;           /* iterate over the tree elements */
+    int bits;           /* bit length */
+    int xbits;          /* extra bits */
+    ush f;              /* frequency */
+    int overflow = 0;   /* number of elements with bit length too large */
+
+    for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
+
+    /* In a first pass, compute the optimal bit lengths (which may
+     * overflow in the case of the bit length tree).
+     */
+    tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
+
+    for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
+        n = s->heap[h];
+        bits = tree[tree[n].Dad].Len + 1;
+        if (bits > max_length) bits = max_length, overflow++;
+        tree[n].Len = (ush)bits;
+        /* We overwrite tree[n].Dad which is no longer needed */
+
+        if (n > max_code) continue; /* not a leaf node */
+
+        s->bl_count[bits]++;
+        xbits = 0;
+        if (n >= base) xbits = extra[n-base];
+        f = tree[n].Freq;
+        s->opt_len += (ulg)f * (bits + xbits);
+        if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
+    }
+    if (overflow == 0) return;
+
+    Trace((stderr,"\nbit length overflow\n"));
+    /* This happens for example on obj2 and pic of the Calgary corpus */
+
+    /* Find the first bit length which could increase: */
+    do {
+        bits = max_length-1;
+        while (s->bl_count[bits] == 0) bits--;
+        s->bl_count[bits]--;      /* move one leaf down the tree */
+        s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
+        s->bl_count[max_length]--;
+        /* The brother of the overflow item also moves one step up,
+         * but this does not affect bl_count[max_length]
+         */
+        overflow -= 2;
+    } while (overflow > 0);
+
+    /* Now recompute all bit lengths, scanning in increasing frequency.
+     * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+     * lengths instead of fixing only the wrong ones. This idea is taken
+     * from 'ar' written by Haruhiko Okumura.)
+     */
+    for (bits = max_length; bits != 0; bits--) {
+        n = s->bl_count[bits];
+        while (n != 0) {
+            m = s->heap[--h];
+            if (m > max_code) continue;
+            if (tree[m].Len != (unsigned) bits) {
+                Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+                s->opt_len += ((long)bits - (long)tree[m].Len)
+                              *(long)tree[m].Freq;
+                tree[m].Len = (ush)bits;
+            }
+            n--;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ *     zero code length.
+ */
+local void gen_codes (tree, max_code, bl_count)
+    ct_data *tree;             /* the tree to decorate */
+    int max_code;              /* largest code with non zero frequency */
+    ushf *bl_count;            /* number of codes at each bit length */
+{
+    ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+    ush code = 0;              /* running code value */
+    int bits;                  /* bit index */
+    int n;                     /* code index */
+
+    /* The distribution counts are first used to generate the code values
+     * without bit reversal.
+     */
+    for (bits = 1; bits <= MAX_BITS; bits++) {
+        next_code[bits] = code = (code + bl_count[bits-1]) << 1;
+    }
+    /* Check that the bit counts in bl_count are consistent. The last code
+     * must be all ones.
+     */
+    Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+            "inconsistent bit counts");
+    Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+    for (n = 0;  n <= max_code; n++) {
+        int len = tree[n].Len;
+        if (len == 0) continue;
+        /* Now reverse the bits */
+        tree[n].Code = bi_reverse(next_code[len]++, len);
+
+        Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+             n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+    }
+}
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ *     and corresponding code. The length opt_len is updated; static_len is
+ *     also updated if stree is not null. The field max_code is set.
+ */
+local void build_tree(s, desc)
+    deflate_state *s;
+    tree_desc *desc; /* the tree descriptor */
+{
+    ct_data *tree         = desc->dyn_tree;
+    const ct_data *stree  = desc->stat_desc->static_tree;
+    int elems             = desc->stat_desc->elems;
+    int n, m;          /* iterate over heap elements */
+    int max_code = -1; /* largest code with non zero frequency */
+    int node;          /* new node being created */
+
+    /* Construct the initial heap, with least frequent element in
+     * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+     * heap[0] is not used.
+     */
+    s->heap_len = 0, s->heap_max = HEAP_SIZE;
+
+    for (n = 0; n < elems; n++) {
+        if (tree[n].Freq != 0) {
+            s->heap[++(s->heap_len)] = max_code = n;
+            s->depth[n] = 0;
+        } else {
+            tree[n].Len = 0;
+        }
+    }
+
+    /* The pkzip format requires that at least one distance code exists,
+     * and that at least one bit should be sent even if there is only one
+     * possible code. So to avoid special checks later on we force at least
+     * two codes of non zero frequency.
+     */
+    while (s->heap_len < 2) {
+        node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
+        tree[node].Freq = 1;
+        s->depth[node] = 0;
+        s->opt_len--; if (stree) s->static_len -= stree[node].Len;
+        /* node is 0 or 1 so it does not have extra bits */
+    }
+    desc->max_code = max_code;
+
+    /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+     * establish sub-heaps of increasing lengths:
+     */
+    for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
+
+    /* Construct the Huffman tree by repeatedly combining the least two
+     * frequent nodes.
+     */
+    node = elems;              /* next internal node of the tree */
+    do {
+        pqremove(s, tree, n);  /* n = node of least frequency */
+        m = s->heap[SMALLEST]; /* m = node of next least frequency */
+
+        s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
+        s->heap[--(s->heap_max)] = m;
+
+        /* Create a new node father of n and m */
+        tree[node].Freq = tree[n].Freq + tree[m].Freq;
+        s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
+        tree[n].Dad = tree[m].Dad = (ush)node;
+#ifdef DUMP_BL_TREE
+        if (tree == s->bl_tree) {
+            fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+                    node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+        }
+#endif
+        /* and insert the new node in the heap */
+        s->heap[SMALLEST] = node++;
+        pqdownheap(s, tree, SMALLEST);
+
+    } while (s->heap_len >= 2);
+
+    s->heap[--(s->heap_max)] = s->heap[SMALLEST];
+
+    /* At this point, the fields freq and dad are set. We can now
+     * generate the bit lengths.
+     */
+    gen_bitlen(s, (tree_desc *)desc);
+
+    /* The field len is now set, we can generate the bit codes */
+    gen_codes ((ct_data *)tree, max_code, s->bl_count);
+}
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree.
+ */
+local void scan_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree;   /* the tree to be scanned */
+    int max_code;    /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    if (nextlen == 0) max_count = 138, min_count = 3;
+    tree[max_code+1].Len = (ush)0xffff; /* guard */
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            s->bl_tree[curlen].Freq += count;
+        } else if (curlen != 0) {
+            if (curlen != prevlen) s->bl_tree[curlen].Freq++;
+            s->bl_tree[REP_3_6].Freq++;
+        } else if (count <= 10) {
+            s->bl_tree[REPZ_3_10].Freq++;
+        } else {
+            s->bl_tree[REPZ_11_138].Freq++;
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+local void send_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree; /* the tree to be scanned */
+    int max_code;       /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    /* tree[max_code+1].Len = -1; */  /* guard already set */
+    if (nextlen == 0) max_count = 138, min_count = 3;
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
+
+        } else if (curlen != 0) {
+            if (curlen != prevlen) {
+                send_code(s, curlen, s->bl_tree); count--;
+            }
+            Assert(count >= 3 && count <= 6, " 3_6?");
+            send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
+
+        } else if (count <= 10) {
+            send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
+
+        } else {
+            send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+local int build_bl_tree(s)
+    deflate_state *s;
+{
+    int max_blindex;  /* index of last bit length code of non zero freq */
+
+    /* Determine the bit length frequencies for literal and distance trees */
+    scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
+    scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
+
+    /* Build the bit length tree: */
+    build_tree(s, (tree_desc *)(&(s->bl_desc)));
+    /* opt_len now includes the length of the tree representations, except
+     * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+     */
+
+    /* Determine the number of bit length codes to send. The pkzip format
+     * requires that at least 4 bit length codes be sent. (appnote.txt says
+     * 3 but the actual value used is 4.)
+     */
+    for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
+        if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
+    }
+    /* Update opt_len to include the bit length tree and counts */
+    s->opt_len += 3*(max_blindex+1) + 5+5+4;
+    Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+            s->opt_len, s->static_len));
+
+    return max_blindex;
+}
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+local void send_all_trees(s, lcodes, dcodes, blcodes)
+    deflate_state *s;
+    int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+    int rank;                    /* index in bl_order */
+
+    Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+    Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+            "too many codes");
+    Tracev((stderr, "\nbl counts: "));
+    send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
+    send_bits(s, dcodes-1,   5);
+    send_bits(s, blcodes-4,  4); /* not -3 as stated in appnote.txt */
+    for (rank = 0; rank < blcodes; rank++) {
+        Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+        send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
+    }
+    Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
+    Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
+    Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+/* ===========================================================================
+ * Send a stored block
+ */
+void _tr_stored_block(s, buf, stored_len, eof)
+    deflate_state *s;
+    charf *buf;       /* input block */
+    ulg stored_len;   /* length of input block */
+    int eof;          /* true if this is the last block for a file */
+{
+    send_bits(s, (STORED_BLOCK<<1)+eof, 3);  /* send block type */
+    s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
+    s->compressed_len += (stored_len + 4) << 3;
+
+    copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
+}
+
+/* ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate.
+ * This takes 10 bits, of which 7 may remain in the bit buffer.
+ * The current inflate code requires 9 bits of lookahead. If the
+ * last two codes for the previous block (real code plus EOB) were coded
+ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
+ * the last real code. In this case we send two empty static blocks instead
+ * of one. (There are no problems if the previous block is stored or fixed.)
+ * To simplify the code, we assume the worst case of last real code encoded
+ * on one bit only.
+ */
+void _tr_align(s)
+    deflate_state *s;
+{
+    send_bits(s, STATIC_TREES<<1, 3);
+    send_code(s, END_BLOCK, static_ltree);
+    s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
+    bi_flush(s);
+    /* Of the 10 bits for the empty block, we have already sent
+     * (10 - bi_valid) bits. The lookahead for the last real code (before
+     * the EOB of the previous block) was thus at least one plus the length
+     * of the EOB plus what we have just sent of the empty static block.
+     */
+    if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
+        send_bits(s, STATIC_TREES<<1, 3);
+        send_code(s, END_BLOCK, static_ltree);
+        s->compressed_len += 10L;
+        bi_flush(s);
+    }
+    s->last_eob_len = 7;
+}
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and output the encoded block to the zip file. This function
+ * returns the total compressed length for the file so far.
+ */
+ulg _tr_flush_block(s, buf, stored_len, eof)
+    deflate_state *s;
+    charf *buf;       /* input block, or NULL if too old */
+    ulg stored_len;   /* length of input block */
+    int eof;          /* true if this is the last block for a file */
+{
+    ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
+    int max_blindex = 0;  /* index of last bit length code of non zero freq */
+
+    /* Build the Huffman trees unless a stored block is forced */
+    if (s->level > 0) {
+
+	 /* Check if the file is ascii or binary */
+	if (s->data_type == Z_UNKNOWN) set_data_type(s);
+
+	/* Construct the literal and distance trees */
+	build_tree(s, (tree_desc *)(&(s->l_desc)));
+	Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+		s->static_len));
+
+	build_tree(s, (tree_desc *)(&(s->d_desc)));
+	Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+		s->static_len));
+	/* At this point, opt_len and static_len are the total bit lengths of
+	 * the compressed block data, excluding the tree representations.
+	 */
+
+	/* Build the bit length tree for the above two trees, and get the index
+	 * in bl_order of the last bit length code to send.
+	 */
+	max_blindex = build_bl_tree(s);
+
+	/* Determine the best encoding. Compute first the block length in bytes*/
+	opt_lenb = (s->opt_len+3+7)>>3;
+	static_lenb = (s->static_len+3+7)>>3;
+
+	Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+		opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+		s->last_lit));
+
+	if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+
+    } else {
+        Assert(buf != (char*)0, "lost buf");
+	opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+    }
+
+    /* If compression failed and this is the first and last block,
+     * and if the .zip file can be seeked (to rewrite the local header),
+     * the whole file is transformed into a stored file:
+     */
+#ifdef STORED_FILE_OK
+#  ifdef FORCE_STORED_FILE
+    if (eof && s->compressed_len == 0L) { /* force stored file */
+#  else
+    if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) {
+#  endif
+        /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */
+        if (buf == (charf*)0) error ("block vanished");
+
+        copy_block(buf, (unsigned)stored_len, 0); /* without header */
+        s->compressed_len = stored_len << 3;
+        s->method = STORED;
+    } else
+#endif /* STORED_FILE_OK */
+
+#ifdef FORCE_STORED
+    if (buf != (char*)0) { /* force stored block */
+#else
+    if (stored_len+4 <= opt_lenb && buf != (char*)0) {
+                       /* 4: two words for the lengths */
+#endif
+        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+         * Otherwise we can't have processed more than WSIZE input bytes since
+         * the last block flush, because compression would have been
+         * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+         * transform a block into a stored block.
+         */
+        _tr_stored_block(s, buf, stored_len, eof);
+
+#ifdef FORCE_STATIC
+    } else if (static_lenb >= 0) { /* force static trees */
+#else
+    } else if (static_lenb == opt_lenb) {
+#endif
+        send_bits(s, (STATIC_TREES<<1)+eof, 3);
+        compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
+        s->compressed_len += 3 + s->static_len;
+    } else {
+        send_bits(s, (DYN_TREES<<1)+eof, 3);
+        send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
+                       max_blindex+1);
+        compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
+        s->compressed_len += 3 + s->opt_len;
+    }
+    Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+    init_block(s);
+
+    if (eof) {
+        bi_windup(s);
+        s->compressed_len += 7;  /* align on byte boundary */
+    }
+    Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+           s->compressed_len-7*eof));
+
+    return s->compressed_len >> 3;
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+int _tr_tally (s, dist, lc)
+    deflate_state *s;
+    unsigned dist;  /* distance of matched string */
+    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+    s->d_buf[s->last_lit] = (ush)dist;
+    s->l_buf[s->last_lit++] = (uch)lc;
+    if (dist == 0) {
+        /* lc is the unmatched char */
+        s->dyn_ltree[lc].Freq++;
+    } else {
+        s->matches++;
+        /* Here, lc is the match length - MIN_MATCH */
+        dist--;             /* dist = match distance - 1 */
+        Assert((ush)dist < (ush)MAX_DIST(s) &&
+               (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+               (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");
+
+        s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
+        s->dyn_dtree[d_code(dist)].Freq++;
+    }
+
+#ifdef TRUNCATE_BLOCK
+    /* Try to guess if it is profitable to stop the current block here */
+    if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
+        /* Compute an upper bound for the compressed length */
+        ulg out_length = (ulg)s->last_lit*8L;
+        ulg in_length = (ulg)((long)s->strstart - s->block_start);
+        int dcode;
+        for (dcode = 0; dcode < D_CODES; dcode++) {
+            out_length += (ulg)s->dyn_dtree[dcode].Freq *
+                (5L+extra_dbits[dcode]);
+        }
+        out_length >>= 3;
+        Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+               s->last_lit, in_length, out_length,
+               100L - out_length*100L/in_length));
+        if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
+    }
+#endif
+    return (s->last_lit == s->lit_bufsize-1);
+    /* We avoid equality with lit_bufsize because of wraparound at 64K
+     * on 16 bit machines and because stored blocks are restricted to
+     * 64K-1 bytes.
+     */
+}
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+local void compress_block(s, ltree, dtree)
+    deflate_state *s;
+    ct_data *ltree; /* literal tree */
+    ct_data *dtree; /* distance tree */
+{
+    unsigned dist;      /* distance of matched string */
+    int lc;             /* match length or unmatched char (if dist == 0) */
+    unsigned lx = 0;    /* running index in l_buf */
+    unsigned code;      /* the code to send */
+    int extra;          /* number of extra bits to send */
+
+    if (s->last_lit != 0) do {
+        dist = s->d_buf[lx];
+        lc = s->l_buf[lx++];
+        if (dist == 0) {
+            send_code(s, lc, ltree); /* send a literal byte */
+            Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+        } else {
+            /* Here, lc is the match length - MIN_MATCH */
+            code = _length_code[lc];
+            send_code(s, code+LITERALS+1, ltree); /* send the length code */
+            extra = extra_lbits[code];
+            if (extra != 0) {
+                lc -= base_length[code];
+                send_bits(s, lc, extra);       /* send the extra length bits */
+            }
+            dist--; /* dist is now the match distance - 1 */
+            code = d_code(dist);
+            Assert (code < D_CODES, "bad d_code");
+
+            send_code(s, code, dtree);       /* send the distance code */
+            extra = extra_dbits[code];
+            if (extra != 0) {
+                dist -= base_dist[code];
+                send_bits(s, dist, extra);   /* send the extra distance bits */
+            }
+        } /* literal or match pair ? */
+
+        /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+        Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
+
+    } while (lx < s->last_lit);
+
+    send_code(s, END_BLOCK, ltree);
+    s->last_eob_len = ltree[END_BLOCK].Len;
+}
+
+/* ===========================================================================
+ * Set the data type to ASCII or BINARY, using a crude approximation:
+ * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
+ * IN assertion: the fields freq of dyn_ltree are set and the total of all
+ * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
+ */
+local void set_data_type(s)
+    deflate_state *s;
+{
+    int n = 0;
+    unsigned ascii_freq = 0;
+    unsigned bin_freq = 0;
+    while (n < 7)        bin_freq += s->dyn_ltree[n++].Freq;
+    while (n < 128)    ascii_freq += s->dyn_ltree[n++].Freq;
+    while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
+    s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
+}
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+local unsigned bi_reverse(code, len)
+    unsigned code; /* the value to invert */
+    int len;       /* its bit length */
+{
+    register unsigned res = 0;
+    do {
+        res |= code & 1;
+        code >>= 1, res <<= 1;
+    } while (--len > 0);
+    return res >> 1;
+}
+
+/* ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+local void bi_flush(s)
+    deflate_state *s;
+{
+    if (s->bi_valid == 16) {
+        put_short(s, s->bi_buf);
+        s->bi_buf = 0;
+        s->bi_valid = 0;
+    } else if (s->bi_valid >= 8) {
+        put_byte(s, (Byte)s->bi_buf);
+        s->bi_buf >>= 8;
+        s->bi_valid -= 8;
+    }
+}
+
+/* ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+local void bi_windup(s)
+    deflate_state *s;
+{
+    if (s->bi_valid > 8) {
+        put_short(s, s->bi_buf);
+    } else if (s->bi_valid > 0) {
+        put_byte(s, (Byte)s->bi_buf);
+    }
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+#ifdef DEBUG
+    s->bits_sent = (s->bits_sent+7) & ~7;
+#endif
+}
+
+/* ===========================================================================
+ * Copy a stored block, storing first the length and its
+ * one's complement if requested.
+ */
+local void copy_block(s, buf, len, header)
+    deflate_state *s;
+    charf    *buf;    /* the input data */
+    unsigned len;     /* its length */
+    int      header;  /* true if block header must be written */
+{
+    bi_windup(s);        /* align on byte boundary */
+    s->last_eob_len = 8; /* enough lookahead for inflate */
+
+    if (header) {
+        put_short(s, (ush)len);   
+        put_short(s, (ush)~len);
+#ifdef DEBUG
+        s->bits_sent += 2*16;
+#endif
+    }
+#ifdef DEBUG
+    s->bits_sent += (ulg)len<<3;
+#endif
+    while (len--) {
+        put_byte(s, *buf++);
+    }
+}
diff --git a/src/zlib/trees.h b/src/zlib/trees.h
new file mode 100644
index 0000000000..72facf900f
--- /dev/null
+++ b/src/zlib/trees.h
@@ -0,0 +1,128 @@
+/* header created automatically with -DGEN_TREES_H */
+
+local const ct_data static_ltree[L_CODES+2] = {
+{{ 12},{  8}}, {{140},{  8}}, {{ 76},{  8}}, {{204},{  8}}, {{ 44},{  8}},
+{{172},{  8}}, {{108},{  8}}, {{236},{  8}}, {{ 28},{  8}}, {{156},{  8}},
+{{ 92},{  8}}, {{220},{  8}}, {{ 60},{  8}}, {{188},{  8}}, {{124},{  8}},
+{{252},{  8}}, {{  2},{  8}}, {{130},{  8}}, {{ 66},{  8}}, {{194},{  8}},
+{{ 34},{  8}}, {{162},{  8}}, {{ 98},{  8}}, {{226},{  8}}, {{ 18},{  8}},
+{{146},{  8}}, {{ 82},{  8}}, {{210},{  8}}, {{ 50},{  8}}, {{178},{  8}},
+{{114},{  8}}, {{242},{  8}}, {{ 10},{  8}}, {{138},{  8}}, {{ 74},{  8}},
+{{202},{  8}}, {{ 42},{  8}}, {{170},{  8}}, {{106},{  8}}, {{234},{  8}},
+{{ 26},{  8}}, {{154},{  8}}, {{ 90},{  8}}, {{218},{  8}}, {{ 58},{  8}},
+{{186},{  8}}, {{122},{  8}}, {{250},{  8}}, {{  6},{  8}}, {{134},{  8}},
+{{ 70},{  8}}, {{198},{  8}}, {{ 38},{  8}}, {{166},{  8}}, {{102},{  8}},
+{{230},{  8}}, {{ 22},{  8}}, {{150},{  8}}, {{ 86},{  8}}, {{214},{  8}},
+{{ 54},{  8}}, {{182},{  8}}, {{118},{  8}}, {{246},{  8}}, {{ 14},{  8}},
+{{142},{  8}}, {{ 78},{  8}}, {{206},{  8}}, {{ 46},{  8}}, {{174},{  8}},
+{{110},{  8}}, {{238},{  8}}, {{ 30},{  8}}, {{158},{  8}}, {{ 94},{  8}},
+{{222},{  8}}, {{ 62},{  8}}, {{190},{  8}}, {{126},{  8}}, {{254},{  8}},
+{{  1},{  8}}, {{129},{  8}}, {{ 65},{  8}}, {{193},{  8}}, {{ 33},{  8}},
+{{161},{  8}}, {{ 97},{  8}}, {{225},{  8}}, {{ 17},{  8}}, {{145},{  8}},
+{{ 81},{  8}}, {{209},{  8}}, {{ 49},{  8}}, {{177},{  8}}, {{113},{  8}},
+{{241},{  8}}, {{  9},{  8}}, {{137},{  8}}, {{ 73},{  8}}, {{201},{  8}},
+{{ 41},{  8}}, {{169},{  8}}, {{105},{  8}}, {{233},{  8}}, {{ 25},{  8}},
+{{153},{  8}}, {{ 89},{  8}}, {{217},{  8}}, {{ 57},{  8}}, {{185},{  8}},
+{{121},{  8}}, {{249},{  8}}, {{  5},{  8}}, {{133},{  8}}, {{ 69},{  8}},
+{{197},{  8}}, {{ 37},{  8}}, {{165},{  8}}, {{101},{  8}}, {{229},{  8}},
+{{ 21},{  8}}, {{149},{  8}}, {{ 85},{  8}}, {{213},{  8}}, {{ 53},{  8}},
+{{181},{  8}}, {{117},{  8}}, {{245},{  8}}, {{ 13},{  8}}, {{141},{  8}},
+{{ 77},{  8}}, {{205},{  8}}, {{ 45},{  8}}, {{173},{  8}}, {{109},{  8}},
+{{237},{  8}}, {{ 29},{  8}}, {{157},{  8}}, {{ 93},{  8}}, {{221},{  8}},
+{{ 61},{  8}}, {{189},{  8}}, {{125},{  8}}, {{253},{  8}}, {{ 19},{  9}},
+{{275},{  9}}, {{147},{  9}}, {{403},{  9}}, {{ 83},{  9}}, {{339},{  9}},
+{{211},{  9}}, {{467},{  9}}, {{ 51},{  9}}, {{307},{  9}}, {{179},{  9}},
+{{435},{  9}}, {{115},{  9}}, {{371},{  9}}, {{243},{  9}}, {{499},{  9}},
+{{ 11},{  9}}, {{267},{  9}}, {{139},{  9}}, {{395},{  9}}, {{ 75},{  9}},
+{{331},{  9}}, {{203},{  9}}, {{459},{  9}}, {{ 43},{  9}}, {{299},{  9}},
+{{171},{  9}}, {{427},{  9}}, {{107},{  9}}, {{363},{  9}}, {{235},{  9}},
+{{491},{  9}}, {{ 27},{  9}}, {{283},{  9}}, {{155},{  9}}, {{411},{  9}},
+{{ 91},{  9}}, {{347},{  9}}, {{219},{  9}}, {{475},{  9}}, {{ 59},{  9}},
+{{315},{  9}}, {{187},{  9}}, {{443},{  9}}, {{123},{  9}}, {{379},{  9}},
+{{251},{  9}}, {{507},{  9}}, {{  7},{  9}}, {{263},{  9}}, {{135},{  9}},
+{{391},{  9}}, {{ 71},{  9}}, {{327},{  9}}, {{199},{  9}}, {{455},{  9}},
+{{ 39},{  9}}, {{295},{  9}}, {{167},{  9}}, {{423},{  9}}, {{103},{  9}},
+{{359},{  9}}, {{231},{  9}}, {{487},{  9}}, {{ 23},{  9}}, {{279},{  9}},
+{{151},{  9}}, {{407},{  9}}, {{ 87},{  9}}, {{343},{  9}}, {{215},{  9}},
+{{471},{  9}}, {{ 55},{  9}}, {{311},{  9}}, {{183},{  9}}, {{439},{  9}},
+{{119},{  9}}, {{375},{  9}}, {{247},{  9}}, {{503},{  9}}, {{ 15},{  9}},
+{{271},{  9}}, {{143},{  9}}, {{399},{  9}}, {{ 79},{  9}}, {{335},{  9}},
+{{207},{  9}}, {{463},{  9}}, {{ 47},{  9}}, {{303},{  9}}, {{175},{  9}},
+{{431},{  9}}, {{111},{  9}}, {{367},{  9}}, {{239},{  9}}, {{495},{  9}},
+{{ 31},{  9}}, {{287},{  9}}, {{159},{  9}}, {{415},{  9}}, {{ 95},{  9}},
+{{351},{  9}}, {{223},{  9}}, {{479},{  9}}, {{ 63},{  9}}, {{319},{  9}},
+{{191},{  9}}, {{447},{  9}}, {{127},{  9}}, {{383},{  9}}, {{255},{  9}},
+{{511},{  9}}, {{  0},{  7}}, {{ 64},{  7}}, {{ 32},{  7}}, {{ 96},{  7}},
+{{ 16},{  7}}, {{ 80},{  7}}, {{ 48},{  7}}, {{112},{  7}}, {{  8},{  7}},
+{{ 72},{  7}}, {{ 40},{  7}}, {{104},{  7}}, {{ 24},{  7}}, {{ 88},{  7}},
+{{ 56},{  7}}, {{120},{  7}}, {{  4},{  7}}, {{ 68},{  7}}, {{ 36},{  7}},
+{{100},{  7}}, {{ 20},{  7}}, {{ 84},{  7}}, {{ 52},{  7}}, {{116},{  7}},
+{{  3},{  8}}, {{131},{  8}}, {{ 67},{  8}}, {{195},{  8}}, {{ 35},{  8}},
+{{163},{  8}}, {{ 99},{  8}}, {{227},{  8}}
+};
+
+local const ct_data static_dtree[D_CODES] = {
+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
+};
+
+const uch _dist_code[DIST_CODE_LEN] = {
+ 0,  1,  2,  3,  4,  4,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  8,
+ 8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 10, 10, 10,
+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  0,  0, 16, 17,
+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
+};
+
+const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
+ 0,  1,  2,  3,  4,  5,  6,  7,  8,  8,  9,  9, 10, 10, 11, 11, 12, 12, 12, 12,
+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
+};
+
+local const int base_length[LENGTH_CODES] = {
+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
+64, 80, 96, 112, 128, 160, 192, 224, 0
+};
+
+local const int base_dist[D_CODES] = {
+    0,     1,     2,     3,     4,     6,     8,    12,    16,    24,
+   32,    48,    64,    96,   128,   192,   256,   384,   512,   768,
+ 1024,  1536,  2048,  3072,  4096,  6144,  8192, 12288, 16384, 24576
+};
+
diff --git a/src/zlib/uncompr.c b/src/zlib/uncompr.c
new file mode 100644
index 0000000000..d103321378
--- /dev/null
+++ b/src/zlib/uncompr.c
@@ -0,0 +1,58 @@
+/* uncompr.c -- decompress a memory buffer
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* @(#) $Id$ */
+
+#include "zlib.h"
+
+/* ===========================================================================
+     Decompresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be large enough to hold the
+   entire uncompressed data. (The size of the uncompressed data must have
+   been saved previously by the compressor and transmitted to the decompressor
+   by some mechanism outside the scope of this compression library.)
+   Upon exit, destLen is the actual size of the compressed buffer.
+     This function can be used to decompress a whole file at once if the
+   input file is mmap'ed.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer, or Z_DATA_ERROR if the input data was corrupted.
+*/
+int ZEXPORT uncompress (dest, destLen, source, sourceLen)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+{
+    z_stream stream;
+    int err;
+
+    stream.next_in = (Bytef*)source;
+    stream.avail_in = (uInt)sourceLen;
+    /* Check for source > 64K on 16-bit machine: */
+    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+
+    stream.next_out = dest;
+    stream.avail_out = (uInt)*destLen;
+    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+    stream.zalloc = (alloc_func)0;
+    stream.zfree = (free_func)0;
+
+    err = inflateInit(&stream);
+    if (err != Z_OK) return err;
+
+    err = inflate(&stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        inflateEnd(&stream);
+        return err == Z_OK ? Z_BUF_ERROR : err;
+    }
+    *destLen = stream.total_out;
+
+    err = inflateEnd(&stream);
+    return err;
+}
diff --git a/src/zlib/zconf.h b/src/zlib/zconf.h
new file mode 100644
index 0000000000..89e1a16c0d
--- /dev/null
+++ b/src/zlib/zconf.h
@@ -0,0 +1,252 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* @(#) $Id$ */
+
+#ifndef _ZCONF_H
+#define _ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ */
+#ifdef Z_PREFIX
+#  define deflateInit_	z_deflateInit_
+#  define deflate	z_deflate
+#  define deflateEnd	z_deflateEnd
+#  define inflateInit_ 	z_inflateInit_
+#  define inflate	z_inflate
+#  define inflateEnd	z_inflateEnd
+#  define deflateInit2_	z_deflateInit2_
+#  define deflateSetDictionary z_deflateSetDictionary
+#  define deflateCopy	z_deflateCopy
+#  define deflateReset	z_deflateReset
+#  define deflateParams	z_deflateParams
+#  define inflateInit2_	z_inflateInit2_
+#  define inflateSetDictionary z_inflateSetDictionary
+#  define inflateSync	z_inflateSync
+#  define inflateSyncPoint z_inflateSyncPoint
+#  define inflateReset	z_inflateReset
+#  define compress	z_compress
+#  define compress2	z_compress2
+#  define uncompress	z_uncompress
+#  define adler32	z_adler32
+#  define crc32		z_crc32
+#  define get_crc_table z_get_crc_table
+
+#  define Byte		z_Byte
+#  define uInt		z_uInt
+#  define uLong		z_uLong
+#  define Bytef	        z_Bytef
+#  define charf		z_charf
+#  define intf		z_intf
+#  define uIntf		z_uIntf
+#  define uLongf	z_uLongf
+#  define voidpf	z_voidpf
+#  define voidp		z_voidp
+#endif
+
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
+#  define WIN32
+#endif
+#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
+#  ifndef __32BIT__
+#    define __32BIT__
+#  endif
+#endif
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#if defined(MSDOS) && !defined(__32BIT__)
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32))  && !defined(STDC)
+#  define STDC
+#endif
+#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
+#  ifndef STDC
+#    define STDC
+#  endif
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const
+#  endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
+#  define NO_DUMMY_DECL
+#endif
+
+/* Borland C incorrectly complains about missing returns: */
+#if defined(__BORLANDC__)
+#  define NEED_DUMMY_RETURN
+#endif
+
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
+   /* MSC small or medium model */
+#  define SMALL_MEDIUM
+#  ifdef _MSC_VER
+#    define FAR __far
+#  else
+#    define FAR far
+#  endif
+#endif
+#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
+#  ifndef __32BIT__
+#    define SMALL_MEDIUM
+#    define FAR __far
+#  endif
+#endif
+
+/* Compile with -DZLIB_DLL for Windows DLL support */
+#if (defined(_WINDOWS) || defined(WINDOWS)) && defined(ZLIB_DLL)
+#  ifdef FAR
+#    undef FAR
+#  endif
+#  include <windows.h>
+#  define ZEXPORT  WINAPI
+#  ifdef WIN32
+#    define ZEXPORTVA  WINAPIV
+#  else
+#    define ZEXPORTVA  FAR _cdecl _export
+#  endif
+#else
+#   if defined (__BORLANDC__) && defined (_Windows) && defined (__DLL__)
+#       define ZEXPORT _export
+#       define ZEXPORTVA _export
+#   else
+#       define ZEXPORT
+#       define ZEXPORTVA
+#   endif
+#endif
+
+#ifndef FAR
+#   define FAR
+#endif
+
+typedef unsigned char  Byte;  /* 8 bits */
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#if defined(__BORLANDC__) && defined(SMALL_MEDIUM)
+   /* Borland C/C++ ignores FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void FAR *voidpf;
+   typedef void     *voidp;
+#else
+   typedef Byte FAR *voidpf;
+   typedef Byte     *voidp;
+#endif
+
+#ifdef HAVE_UNISTD_H
+#  include <sys/types.h> /* for off_t */
+#  include <unistd.h>    /* for SEEK_* and off_t */
+#  define z_off_t  off_t
+#endif
+#ifndef SEEK_SET
+#  define SEEK_SET        0       /* Seek from beginning of file.  */
+#  define SEEK_CUR        1       /* Seek from current position.  */
+#endif
+#ifndef z_off_t
+#  define  z_off_t long
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+#   pragma map(deflateInit_,"DEIN")
+#   pragma map(deflateInit2_,"DEIN2")
+#   pragma map(deflateEnd,"DEEND")
+#   pragma map(inflateInit_,"ININ")
+#   pragma map(inflateInit2_,"ININ2")
+#   pragma map(inflateEnd,"INEND")
+#   pragma map(inflateSync,"INSY")
+#   pragma map(inflateSetDictionary,"INSEDI")
+#   pragma map(inflate_blocks,"INBL")
+#   pragma map(inflate_blocks_new,"INBLNE")
+#   pragma map(inflate_blocks_free,"INBLFR")
+#   pragma map(inflate_blocks_reset,"INBLRE")
+#   pragma map(inflate_codes_free,"INCOFR")
+#   pragma map(inflate_codes,"INCO")
+#   pragma map(inflate_fast,"INFA")
+#   pragma map(inflate_flush,"INFLU")
+#   pragma map(inflate_mask,"INMA")
+#   pragma map(inflate_set_dictionary,"INSEDI2")
+#   pragma map(inflate_copyright,"INCOPY")
+#   pragma map(inflate_trees_bits,"INTRBI")
+#   pragma map(inflate_trees_dynamic,"INTRDY")
+#   pragma map(inflate_trees_fixed,"INTRFI")
+#   pragma map(inflate_trees_free,"INTRFR")
+#endif
+
+#endif /* _ZCONF_H */
diff --git a/src/zlib/zlib.3 b/src/zlib/zlib.3
new file mode 100644
index 0000000000..d08d0e0d59
--- /dev/null
+++ b/src/zlib/zlib.3
@@ -0,0 +1,107 @@
+.TH ZLIB 3 "19 March 1998"
+.SH NAME
+zlib \- compression/decompression library
+.SH SYNOPSIS
+[see
+.I zlib.h
+for full description]
+.SH DESCRIPTION
+The
+.I zlib
+library is a general purpose data compression library.
+The code is thread safe.
+It provides in-memory compression and decompression functions,
+including integrity checks of the uncompressed data.
+This version of the library supports only one compression method (deflation)
+but other algorithms will be added later and will have the same stream interface.
+.LP
+Compression can be done in a single step if the buffers are large enough
+(for example if an input file is mmap'ed),
+or can be done by repeated calls of the compression function.
+In the latter case,
+the application must provide more input and/or consume the output
+(providing more output space) before each call.
+.LP
+The library also supports reading and writing files in
+.I gzip
+(.gz) format
+with an interface similar to that of stdio.
+.LP
+The library does not install any signal handler. The decoder checks
+the consistency of the compressed data, so the library should never
+crash even in case of corrupted input.
+.LP
+All functions of the compression library are documented in the file
+.IR zlib.h.
+The distribution source includes examples of use of the library
+the files
+.I example.c
+and
+.IR minigzip.c .
+.LP
+A Java implementation of
+.IR zlib
+is available in the Java Development Kit 1.1
+.IP
+http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
+.LP
+A Perl interface to
+.IR zlib ,
+written by Paul Marquess (pmarquess@bfsec.bt.co.uk)
+is available at CPAN (Comprehensive Perl Archive Network) sites,
+such as:
+.IP
+ftp://ftp.cis.ufl.edu/pub/perl/CPAN/modules/by-module/Compress/Compress-Zlib*
+.LP
+A Python interface to
+.IR zlib
+written by A.M. Kuchling <amk@magnet.com>
+is available from the Python Software Association sites, such as:
+.IP
+ftp://ftp.python.org/pub/python/contrib/Encoding/zlib*.tar.gz
+.SH "SEE ALSO"
+Questions about zlib should be sent to:
+.IP
+zlib@quest.jpl.nasa.gov
+or, if this fails, to the author addresses given below.
+The zlib home page is:
+.IP
+http://www.cdrom.com/pub/infozip/zlib/
+.LP
+The data format used by the zlib library is described by RFC
+(Request for Comments) 1950 to 1952 in the files: 
+.IP
+ftp://ds.internic.net/rfc/rfc1950.txt (zlib format)
+.br
+rfc1951.txt (deflate format)
+.br
+rfc1952.txt (gzip format)
+.LP
+These documents are also available in other formats from:
+.IP
+ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
+.SH AUTHORS
+Version 1.1.2
+Copyright (C) 1995-1998 Jean-loup Gailly (jloup@gzip.org)
+and Mark Adler (madler@alumni.caltech.edu).
+.LP
+This software is provided "as-is,"
+without any express or implied warranty.
+In no event will the authors be held liable for any damages
+arising from the use of this software.
+See the distribution directory with respect to requirements
+governing redistribution.
+The deflate format used by
+.I zlib
+was defined by Phil Katz.
+The deflate and
+.I zlib
+specifications were written by L. Peter Deutsch.
+Thanks to all the people who reported problems and suggested various
+improvements in
+.IR zlib ;
+who are too numerous to cite here.
+.LP
+UNIX manual page by R. P. C. Rodgers,
+U.S. National Library of Medicine (rodgers@nlm.nih.gov).
+.\" end of man page
diff --git a/src/zlib/zlib.h b/src/zlib/zlib.h
new file mode 100644
index 0000000000..787b5fd92a
--- /dev/null
+++ b/src/zlib/zlib.h
@@ -0,0 +1,888 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+  version 1.1.2, March 19th, 1998
+
+  Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup@gzip.org          madler@alumni.caltech.edu
+
+
+  The data format used by the zlib library is described by RFCs (Request for
+  Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
+  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+*/
+
+#ifndef _ZLIB_H
+#define _ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.1.2"
+
+/* 
+     The 'zlib' compression library provides in-memory compression and
+  decompression functions, including integrity checks of the uncompressed
+  data.  This version of the library supports only one compression method
+  (deflation) but other algorithms will be added later and will have the same
+  stream interface.
+
+     Compression can be done in a single step if the buffers are large
+  enough (for example if an input file is mmap'ed), or can be done by
+  repeated calls of the compression function.  In the latter case, the
+  application must provide more input and/or consume the output
+  (providing more output space) before each call.
+
+     The library also supports reading and writing files in gzip (.gz) format
+  with an interface similar to that of stdio.
+
+     The library does not install any signal handler. The decoder checks
+  the consistency of the compressed data, so the library should never
+  crash even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+    Bytef    *next_in;  /* next input byte */
+    uInt     avail_in;  /* number of bytes available at next_in */
+    uLong    total_in;  /* total nb of input bytes read so far */
+
+    Bytef    *next_out; /* next output byte should be put there */
+    uInt     avail_out; /* remaining free space at next_out */
+    uLong    total_out; /* total nb of bytes output so far */
+
+    char     *msg;      /* last error message, NULL if no error */
+    struct internal_state FAR *state; /* not visible by applications */
+
+    alloc_func zalloc;  /* used to allocate the internal state */
+    free_func  zfree;   /* used to free the internal state */
+    voidpf     opaque;  /* private data object passed to zalloc and zfree */
+
+    int     data_type;  /* best guess about the data type: ascii or binary */
+    uLong   adler;      /* adler32 value of the uncompressed data */
+    uLong   reserved;   /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+   The application must update next_in and avail_in when avail_in has
+   dropped to zero. It must update next_out and avail_out when avail_out
+   has dropped to zero. The application must initialize zalloc, zfree and
+   opaque before calling the init function. All other fields are set by the
+   compression library and must not be updated by the application.
+
+   The opaque value provided by the application will be passed as the first
+   parameter for calls of zalloc and zfree. This can be useful for custom
+   memory management. The compression library attaches no meaning to the
+   opaque value.
+
+   zalloc must return Z_NULL if there is not enough memory for the object.
+   If zlib is used in a multi-threaded application, zalloc and zfree must be
+   thread safe.
+
+   On 16-bit systems, the functions zalloc and zfree must be able to allocate
+   exactly 65536 bytes, but will not be required to allocate more than this
+   if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
+   pointers returned by zalloc for objects of exactly 65536 bytes *must*
+   have their offset normalized to zero. The default allocation function
+   provided by this library ensures this (see zutil.c). To reduce memory
+   requirements and avoid any allocation of 64K objects, at the expense of
+   compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
+
+   The fields total_in and total_out can be used for statistics or
+   progress reports. After compression, total_in holds the total size of
+   the uncompressed data and may be saved for use in the decompressor
+   (particularly if the decompressor wants to decompress everything in
+   a single step).
+*/
+
+                        /* constants */
+
+#define Z_NO_FLUSH      0
+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
+#define Z_SYNC_FLUSH    2
+#define Z_FULL_FLUSH    3
+#define Z_FINISH        4
+/* Allowed flush values; see deflate() below for details */
+
+#define Z_OK            0
+#define Z_STREAM_END    1
+#define Z_NEED_DICT     2
+#define Z_ERRNO        (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR   (-3)
+#define Z_MEM_ERROR    (-4)
+#define Z_BUF_ERROR    (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative
+ * values are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION         0
+#define Z_BEST_SPEED             1
+#define Z_BEST_COMPRESSION       9
+#define Z_DEFAULT_COMPRESSION  (-1)
+/* compression levels */
+
+#define Z_FILTERED            1
+#define Z_HUFFMAN_ONLY        2
+#define Z_DEFAULT_STRATEGY    0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY   0
+#define Z_ASCII    1
+#define Z_UNKNOWN  2
+/* Possible values of the data_type field */
+
+#define Z_DEFLATED   8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+                        /* basic functions */
+
+extern const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+   If the first character differs, the library code actually used is
+   not compatible with the zlib.h header file used by the application.
+   This check is automatically made by deflateInit and inflateInit.
+ */
+
+/* 
+extern int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+     Initializes the internal stream state for compression. The fields
+   zalloc, zfree and opaque must be initialized before by the caller.
+   If zalloc and zfree are set to Z_NULL, deflateInit updates them to
+   use default allocation functions.
+
+     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+   1 gives best speed, 9 gives best compression, 0 gives no compression at
+   all (the input data is simply copied a block at a time).
+   Z_DEFAULT_COMPRESSION requests a default compromise between speed and
+   compression (currently equivalent to level 6).
+
+     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if level is not a valid compression level,
+   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+   with the version assumed by the caller (ZLIB_VERSION).
+   msg is set to null if there is no error message.  deflateInit does not
+   perform any compression: this will be done by deflate().
+*/
+
+
+extern int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+    deflate compresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full. It may introduce some
+  output latency (reading input without producing any output) except when
+  forced to flush.
+
+    The detailed semantics are as follows. deflate performs one or both of the
+  following actions:
+
+  - Compress more input starting at next_in and update next_in and avail_in
+    accordingly. If not all input can be processed (because there is not
+    enough room in the output buffer), next_in and avail_in are updated and
+    processing will resume at this point for the next call of deflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly. This action is forced if the parameter flush is non zero.
+    Forcing flush frequently degrades the compression ratio, so this parameter
+    should be set only when necessary (in interactive applications).
+    Some output may be provided even if flush is not set.
+
+  Before the call of deflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming
+  more output, and updating avail_in or avail_out accordingly; avail_out
+  should never be zero before the call. The application can consume the
+  compressed output when it wants, for example when the output buffer is full
+  (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
+  and with zero avail_out, it must be called again after making room in the
+  output buffer because there might be more output pending.
+
+    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+  flushed to the output buffer and the output is aligned on a byte boundary, so
+  that the decompressor can get all input data available so far. (In particular
+  avail_in is zero after the call if enough output space has been provided
+  before the call.)  Flushing may degrade compression for some compression
+  algorithms and so it should be used only when necessary.
+
+    If flush is set to Z_FULL_FLUSH, all output is flushed as with
+  Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+  restart from this point if previous compressed data has been damaged or if
+  random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+  the compression.
+
+    If deflate returns with avail_out == 0, this function must be called again
+  with the same value of the flush parameter and more output space (updated
+  avail_out), until the flush is complete (deflate returns with non-zero
+  avail_out).
+
+    If the parameter flush is set to Z_FINISH, pending input is processed,
+  pending output is flushed and deflate returns with Z_STREAM_END if there
+  was enough output space; if deflate returns with Z_OK, this function must be
+  called again with Z_FINISH and more output space (updated avail_out) but no
+  more input data, until it returns with Z_STREAM_END or an error. After
+  deflate has returned Z_STREAM_END, the only possible operations on the
+  stream are deflateReset or deflateEnd.
+  
+    Z_FINISH can be used immediately after deflateInit if all the compression
+  is to be done in a single step. In this case, avail_out must be at least
+  0.1% larger than avail_in plus 12 bytes.  If deflate does not return
+  Z_STREAM_END, then it must be called again as described above.
+
+    deflate() sets strm->adler to the adler32 checksum of all input read
+  so far (that is, total_in bytes).
+
+    deflate() may update data_type if it can make a good guess about
+  the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
+  binary. This field is only for information purposes and does not affect
+  the compression algorithm in any manner.
+
+    deflate() returns Z_OK if some progress has been made (more input
+  processed or more output produced), Z_STREAM_END if all input has been
+  consumed and all output has been produced (only when flush is set to
+  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+  if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible.
+*/
+
+
+extern int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any
+   pending output.
+
+     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+   stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+   prematurely (some input or output was discarded). In the error case,
+   msg may be set but then points to a static string (which must not be
+   deallocated).
+*/
+
+
+/* 
+extern int ZEXPORT inflateInit OF((z_streamp strm));
+
+     Initializes the internal stream state for decompression. The fields
+   next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+   the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
+   value depends on the compression method), inflateInit determines the
+   compression method from the zlib header and allocates all data structures
+   accordingly; otherwise the allocation will be deferred to the first call of
+   inflate.  If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+   use default allocation functions.
+
+     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+   version assumed by the caller.  msg is set to null if there is no error
+   message. inflateInit does not perform any decompression apart from reading
+   the zlib header if present: this will be done by inflate().  (So next_in and
+   avail_in may be modified, but next_out and avail_out are unchanged.)
+*/
+
+
+extern int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+    inflate decompresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full. It may some
+  introduce some output latency (reading input without producing any output)
+  except when forced to flush.
+
+  The detailed semantics are as follows. inflate performs one or both of the
+  following actions:
+
+  - Decompress more input starting at next_in and update next_in and avail_in
+    accordingly. If not all input can be processed (because there is not
+    enough room in the output buffer), next_in is updated and processing
+    will resume at this point for the next call of inflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly.  inflate() provides as much output as possible, until there
+    is no more input data or no more space in the output buffer (see below
+    about the flush parameter).
+
+  Before the call of inflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming
+  more output, and updating the next_* and avail_* values accordingly.
+  The application can consume the uncompressed output when it wants, for
+  example when the output buffer is full (avail_out == 0), or after each
+  call of inflate(). If inflate returns Z_OK and with zero avail_out, it
+  must be called again after making room in the output buffer because there
+  might be more output pending.
+
+    If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
+  output as possible to the output buffer. The flushing behavior of inflate is
+  not specified for values of the flush parameter other than Z_SYNC_FLUSH
+  and Z_FINISH, but the current implementation actually flushes as much output
+  as possible anyway.
+
+    inflate() should normally be called until it returns Z_STREAM_END or an
+  error. However if all decompression is to be performed in a single step
+  (a single call of inflate), the parameter flush should be set to
+  Z_FINISH. In this case all pending input is processed and all pending
+  output is flushed; avail_out must be large enough to hold all the
+  uncompressed data. (The size of the uncompressed data may have been saved
+  by the compressor for this purpose.) The next operation on this stream must
+  be inflateEnd to deallocate the decompression state. The use of Z_FINISH
+  is never required, but can be used to inform inflate that a faster routine
+  may be used for the single inflate() call.
+
+     If a preset dictionary is needed at this point (see inflateSetDictionary
+  below), inflate sets strm-adler to the adler32 checksum of the
+  dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise 
+  it sets strm->adler to the adler32 checksum of all output produced
+  so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
+  an error code as described below. At the end of the stream, inflate()
+  checks that its computed adler32 checksum is equal to that saved by the
+  compressor and returns Z_STREAM_END only if the checksum is correct.
+
+    inflate() returns Z_OK if some progress has been made (more input processed
+  or more output produced), Z_STREAM_END if the end of the compressed data has
+  been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+  corrupted (input stream not conforming to the zlib format or incorrect
+  adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
+  (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
+  enough memory, Z_BUF_ERROR if no progress is possible or if there was not
+  enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
+  case, the application may then call inflateSync to look for a good
+  compression block.
+*/
+
+
+extern int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any
+   pending output.
+
+     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+   was inconsistent. In the error case, msg may be set but then points to a
+   static string (which must not be deallocated).
+*/
+
+                        /* Advanced functions */
+
+/*
+    The following functions are needed only in some special applications.
+*/
+
+/*   
+extern int ZEXPORT deflateInit2 OF((z_streamp strm,
+                                    int  level,
+                                    int  method,
+                                    int  windowBits,
+                                    int  memLevel,
+                                    int  strategy));
+
+     This is another version of deflateInit with more compression options. The
+   fields next_in, zalloc, zfree and opaque must be initialized before by
+   the caller.
+
+     The method parameter is the compression method. It must be Z_DEFLATED in
+   this version of the library.
+
+     The windowBits parameter is the base two logarithm of the window size
+   (the size of the history buffer).  It should be in the range 8..15 for this
+   version of the library. Larger values of this parameter result in better
+   compression at the expense of memory usage. The default value is 15 if
+   deflateInit is used instead.
+
+     The memLevel parameter specifies how much memory should be allocated
+   for the internal compression state. memLevel=1 uses minimum memory but
+   is slow and reduces compression ratio; memLevel=9 uses maximum memory
+   for optimal speed. The default value is 8. See zconf.h for total memory
+   usage as a function of windowBits and memLevel.
+
+     The strategy parameter is used to tune the compression algorithm. Use the
+   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+   filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
+   string match).  Filtered data consists mostly of small values with a
+   somewhat random distribution. In this case, the compression algorithm is
+   tuned to compress them better. The effect of Z_FILTERED is to force more
+   Huffman coding and less string matching; it is somewhat intermediate
+   between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
+   the compression ratio but not the correctness of the compressed output even
+   if it is not set appropriately.
+
+      deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
+   method). msg is set to null if there is no error message.  deflateInit2 does
+   not perform any compression: this will be done by deflate().
+*/
+                            
+extern int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+                                            const Bytef *dictionary,
+                                            uInt  dictLength));
+/*
+     Initializes the compression dictionary from the given byte sequence
+   without producing any compressed output. This function must be called
+   immediately after deflateInit or deflateInit2, before any call of
+   deflate. The compressor and decompressor must use exactly the same
+   dictionary (see inflateSetDictionary).
+
+     The dictionary should consist of strings (byte sequences) that are likely
+   to be encountered later in the data to be compressed, with the most commonly
+   used strings preferably put towards the end of the dictionary. Using a
+   dictionary is most useful when the data to be compressed is short and can be
+   predicted with good accuracy; the data can then be compressed better than
+   with the default empty dictionary.
+
+     Depending on the size of the compression data structures selected by
+   deflateInit or deflateInit2, a part of the dictionary may in effect be
+   discarded, for example if the dictionary is larger than the window size in
+   deflate or deflate2. Thus the strings most likely to be useful should be
+   put at the end of the dictionary, not at the front.
+
+     Upon return of this function, strm->adler is set to the Adler32 value
+   of the dictionary; the decompressor may later use this value to determine
+   which dictionary has been used by the compressor. (The Adler32 value
+   applies to the whole dictionary even if only a subset of the dictionary is
+   actually used by the compressor.)
+
+     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+   parameter is invalid (such as NULL dictionary) or the stream state is
+   inconsistent (for example if deflate has already been called for this stream
+   or if the compression method is bsort). deflateSetDictionary does not
+   perform any compression: this will be done by deflate().
+*/
+
+extern int ZEXPORT deflateCopy OF((z_streamp dest,
+                                   z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.
+
+     This function can be useful when several compression strategies will be
+   tried, for example when there are several ways of pre-processing the input
+   data with a filter. The streams that will be discarded should then be freed
+   by calling deflateEnd.  Note that deflateCopy duplicates the internal
+   compression state which can be quite large, so this strategy is slow and
+   can consume lots of memory.
+
+     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being NULL). msg is left unchanged in both source and
+   destination.
+*/
+
+extern int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to deflateEnd followed by deflateInit,
+   but does not free and reallocate all the internal compression state.
+   The stream will keep the same compression level and any other attributes
+   that may have been set by deflateInit2.
+
+      deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+extern int ZEXPORT deflateParams OF((z_streamp strm, int level, int strategy));
+/*
+     Dynamically update the compression level and compression strategy.  The
+   interpretation of level and strategy is as in deflateInit2.  This can be
+   used to switch between compression and straight copy of the input data, or
+   to switch to a different kind of input data requiring a different
+   strategy. If the compression level is changed, the input available so far
+   is compressed with the old level (and may be flushed); the new level will
+   take effect only at the next call of deflate().
+
+     Before the call of deflateParams, the stream state must be set as for
+   a call of deflate(), since the currently available input may have to
+   be compressed and flushed. In particular, strm->avail_out must be non-zero.
+
+     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
+   if strm->avail_out was zero.
+*/
+
+/*   
+extern int ZEXPORT inflateInit2 OF((z_streamp strm,
+                                    int  windowBits));
+
+     This is another version of inflateInit with an extra parameter. The
+   fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+   before by the caller.
+
+     The windowBits parameter is the base two logarithm of the maximum window
+   size (the size of the history buffer).  It should be in the range 8..15 for
+   this version of the library. The default value is 15 if inflateInit is used
+   instead. If a compressed stream with a larger window size is given as
+   input, inflate() will return with the error code Z_DATA_ERROR instead of
+   trying to allocate a larger window.
+
+      inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
+   memLevel). msg is set to null if there is no error message.  inflateInit2
+   does not perform any decompression apart from reading the zlib header if
+   present: this will be done by inflate(). (So next_in and avail_in may be
+   modified, but next_out and avail_out are unchanged.)
+*/
+
+extern int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+                                            const Bytef *dictionary,
+                                            uInt  dictLength));
+/*
+     Initializes the decompression dictionary from the given uncompressed byte
+   sequence. This function must be called immediately after a call of inflate
+   if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
+   can be determined from the Adler32 value returned by this call of
+   inflate. The compressor and decompressor must use exactly the same
+   dictionary (see deflateSetDictionary).
+
+     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+   parameter is invalid (such as NULL dictionary) or the stream state is
+   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+   expected one (incorrect Adler32 value). inflateSetDictionary does not
+   perform any decompression: this will be done by subsequent calls of
+   inflate().
+*/
+
+extern int ZEXPORT inflateSync OF((z_streamp strm));
+/* 
+    Skips invalid compressed data until a full flush point (see above the
+  description of deflate with Z_FULL_FLUSH) can be found, or until all
+  available input is skipped. No output is provided.
+
+    inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
+  if no more input was provided, Z_DATA_ERROR if no flush point has been found,
+  or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
+  case, the application may save the current current value of total_in which
+  indicates where valid compressed data was found. In the error case, the
+  application may repeatedly call inflateSync, providing more input each time,
+  until success or end of the input data.
+*/
+
+extern int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to inflateEnd followed by inflateInit,
+   but does not free and reallocate all the internal decompression state.
+   The stream will keep attributes that may have been set by inflateInit2.
+
+      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+
+                        /* utility functions */
+
+/*
+     The following utility functions are implemented on top of the
+   basic stream-oriented functions. To simplify the interface, some
+   default options are assumed (compression level and memory usage,
+   standard memory allocation functions). The source code of these
+   utility functions can easily be modified if you need special options.
+*/
+
+extern int ZEXPORT compress OF((Bytef *dest,   uLongf *destLen,
+                                const Bytef *source, uLong sourceLen));
+/*
+     Compresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be at least 0.1% larger than
+   sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
+   compressed buffer.
+     This function can be used to compress a whole file at once if the
+   input file is mmap'ed.
+     compress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer.
+*/
+
+extern int ZEXPORT compress2 OF((Bytef *dest,   uLongf *destLen,
+                                 const Bytef *source, uLong sourceLen,
+                                 int level));
+/*
+     Compresses the source buffer into the destination buffer. The level
+   parameter has the same meaning as in deflateInit.  sourceLen is the byte
+   length of the source buffer. Upon entry, destLen is the total size of the
+   destination buffer, which must be at least 0.1% larger than sourceLen plus
+   12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+   Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+extern int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
+                                  const Bytef *source, uLong sourceLen));
+/*
+     Decompresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be large enough to hold the
+   entire uncompressed data. (The size of the uncompressed data must have
+   been saved previously by the compressor and transmitted to the decompressor
+   by some mechanism outside the scope of this compression library.)
+   Upon exit, destLen is the actual size of the compressed buffer.
+     This function can be used to decompress a whole file at once if the
+   input file is mmap'ed.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer, or Z_DATA_ERROR if the input data was corrupted.
+*/
+
+
+typedef voidp gzFile;
+
+extern gzFile ZEXPORT gzopen  OF((const char *path, const char *mode));
+/*
+     Opens a gzip (.gz) file for reading or writing. The mode parameter
+   is as in fopen ("rb" or "wb") but can also include a compression level
+   ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
+   Huffman only compression as in "wb1h". (See the description
+   of deflateInit2 for more information about the strategy parameter.)
+
+     gzopen can be used to read a file which is not in gzip format; in this
+   case gzread will directly read from the file without decompression.
+
+     gzopen returns NULL if the file could not be opened or if there was
+   insufficient memory to allocate the (de)compression state; errno
+   can be checked to distinguish the two cases (if errno is zero, the
+   zlib error is Z_MEM_ERROR).  */
+
+extern gzFile ZEXPORT gzdopen  OF((int fd, const char *mode));
+/*
+     gzdopen() associates a gzFile with the file descriptor fd.  File
+   descriptors are obtained from calls like open, dup, creat, pipe or
+   fileno (in the file has been previously opened with fopen).
+   The mode parameter is as in gzopen.
+     The next call of gzclose on the returned gzFile will also close the
+   file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
+   descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
+     gzdopen returns NULL if there was insufficient memory to allocate
+   the (de)compression state.
+*/
+
+extern int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+     Dynamically update the compression level or strategy. See the description
+   of deflateInit2 for the meaning of these parameters.
+     gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+   opened for writing.
+*/
+
+extern int ZEXPORT    gzread  OF((gzFile file, voidp buf, unsigned len));
+/*
+     Reads the given number of uncompressed bytes from the compressed file.
+   If the input file was not in gzip format, gzread copies the given number
+   of bytes into the buffer.
+     gzread returns the number of uncompressed bytes actually read (0 for
+   end of file, -1 for error). */
+
+extern int ZEXPORT    gzwrite OF((gzFile file, const voidp buf, unsigned len));
+/*
+     Writes the given number of uncompressed bytes into the compressed file.
+   gzwrite returns the number of uncompressed bytes actually written
+   (0 in case of error).
+*/
+
+extern int ZEXPORTVA   gzprintf OF((gzFile file, const char *format, ...));
+/*
+     Converts, formats, and writes the args to the compressed file under
+   control of the format string, as in fprintf. gzprintf returns the number of
+   uncompressed bytes actually written (0 in case of error).
+*/
+
+extern int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+      Writes the given null-terminated string to the compressed file, excluding
+   the terminating null character.
+      gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+extern char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+      Reads bytes from the compressed file until len-1 characters are read, or
+   a newline character is read and transferred to buf, or an end-of-file
+   condition is encountered.  The string is then terminated with a null
+   character.
+      gzgets returns buf, or Z_NULL in case of error.
+*/
+
+extern int ZEXPORT    gzputc OF((gzFile file, int c));
+/*
+      Writes c, converted to an unsigned char, into the compressed file.
+   gzputc returns the value that was written, or -1 in case of error.
+*/
+
+extern int ZEXPORT    gzgetc OF((gzFile file));
+/*
+      Reads one byte from the compressed file. gzgetc returns this byte
+   or -1 in case of end of file or error.
+*/
+
+extern int ZEXPORT    gzflush OF((gzFile file, int flush));
+/*
+     Flushes all pending output into the compressed file. The parameter
+   flush is as in the deflate() function. The return value is the zlib
+   error number (see function gzerror below). gzflush returns Z_OK if
+   the flush parameter is Z_FINISH and all output could be flushed.
+     gzflush should be called only when strictly necessary because it can
+   degrade compression.
+*/
+
+extern z_off_t ZEXPORT    gzseek OF((gzFile file, z_off_t offset, int whence));
+/* 
+      Sets the starting position for the next gzread or gzwrite on the given
+   compressed file. The offset represents a number of bytes in the
+   uncompressed data stream. The whence parameter is defined as in lseek(2);
+   the value SEEK_END is not supported.
+     If the file is opened for reading, this function is emulated but can be
+   extremely slow. If the file is opened for writing, only forward seeks are
+   supported; gzseek then compresses a sequence of zeroes up to the new
+   starting position.
+
+      gzseek returns the resulting offset location as measured in bytes from
+   the beginning of the uncompressed stream, or -1 in case of error, in
+   particular if the file is opened for writing and the new starting position
+   would be before the current position.
+*/
+
+extern int ZEXPORT    gzrewind OF((gzFile file));
+/*
+     Rewinds the given file. This function is supported only for reading.
+
+   gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+extern z_off_t ZEXPORT    gztell OF((gzFile file));
+/*
+     Returns the starting position for the next gzread or gzwrite on the
+   given compressed file. This position represents a number of bytes in the
+   uncompressed data stream.
+
+   gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+extern int ZEXPORT gzeof OF((gzFile file));
+/*
+     Returns 1 when EOF has previously been detected reading the given
+   input stream, otherwise zero.
+*/
+
+extern int ZEXPORT    gzclose OF((gzFile file));
+/*
+     Flushes all pending output if necessary, closes the compressed file
+   and deallocates all the (de)compression state. The return value is the zlib
+   error number (see function gzerror below).
+*/
+
+extern const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+     Returns the error message for the last error which occurred on the
+   given compressed file. errnum is set to zlib error number. If an
+   error occurred in the file system and not in the compression library,
+   errnum is set to Z_ERRNO and the application may consult errno
+   to get the exact error code.
+*/
+
+                        /* checksum functions */
+
+/*
+     These functions are not related to compression but are exported
+   anyway because they might be useful in applications using the
+   compression library.
+*/
+
+extern uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+
+/*
+     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+   return the updated checksum. If buf is NULL, this function returns
+   the required initial value for the checksum.
+   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+   much faster. Usage example:
+
+     uLong adler = adler32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       adler = adler32(adler, buffer, length);
+     }
+     if (adler != original_adler) error();
+*/
+
+extern uLong ZEXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len));
+/*
+     Update a running crc with the bytes buf[0..len-1] and return the updated
+   crc. If buf is NULL, this function returns the required initial value
+   for the crc. Pre- and post-conditioning (one's complement) is performed
+   within this function so it shouldn't be done by the application.
+   Usage example:
+
+     uLong crc = crc32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       crc = crc32(crc, buffer, length);
+     }
+     if (crc != original_crc) error();
+*/
+
+
+                        /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+extern int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+                                    const char *version, int stream_size));
+extern int ZEXPORT inflateInit_ OF((z_streamp strm,
+                                    const char *version, int stream_size));
+extern int ZEXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method,
+                                     int windowBits, int memLevel,
+                                     int strategy, const char *version,
+                                     int stream_size));
+extern int ZEXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
+                                     const char *version, int stream_size));
+#define deflateInit(strm, level) \
+        deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit(strm) \
+        inflateInit_((strm),                ZLIB_VERSION, sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+        deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+                      (strategy),           ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+        inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+
+
+#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
+    struct internal_state {int dummy;}; /* hack for buggy compilers */
+#endif
+
+extern const char   * ZEXPORT zError           OF((int err));
+extern int            ZEXPORT inflateSyncPoint OF((z_streamp z));
+extern const uLongf * ZEXPORT get_crc_table    OF((void));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ZLIB_H */
diff --git a/src/zlib/zutil.c b/src/zlib/zutil.c
new file mode 100644
index 0000000000..5a3fe6e0a5
--- /dev/null
+++ b/src/zlib/zutil.c
@@ -0,0 +1,225 @@
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+
+struct internal_state      {int dummy;}; /* for buggy compilers */
+
+#ifndef STDC
+extern void exit OF((int));
+#endif
+
+const char *z_errmsg[10] = {
+"need dictionary",     /* Z_NEED_DICT       2  */
+"stream end",          /* Z_STREAM_END      1  */
+"",                    /* Z_OK              0  */
+"file error",          /* Z_ERRNO         (-1) */
+"stream error",        /* Z_STREAM_ERROR  (-2) */
+"data error",          /* Z_DATA_ERROR    (-3) */
+"insufficient memory", /* Z_MEM_ERROR     (-4) */
+"buffer error",        /* Z_BUF_ERROR     (-5) */
+"incompatible version",/* Z_VERSION_ERROR (-6) */
+""};
+
+
+const char * ZEXPORT zlibVersion()
+{
+    return ZLIB_VERSION;
+}
+
+#ifdef DEBUG
+
+#  ifndef verbose
+#    define verbose 0
+#  endif
+int z_verbose = verbose;
+
+void z_error (m)
+    char *m;
+{
+    fprintf(stderr, "%s\n", m);
+    exit(1);
+}
+#endif
+
+/* exported to allow conversion of error code to string for compress() and
+ * uncompress()
+ */
+const char * ZEXPORT zError(err)
+    int err;
+{
+    return ERR_MSG(err);
+}
+
+
+#ifndef HAVE_MEMCPY
+
+void zmemcpy(dest, source, len)
+    Bytef* dest;
+    Bytef* source;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = *source++; /* ??? to be unrolled */
+    } while (--len != 0);
+}
+
+int zmemcmp(s1, s2, len)
+    Bytef* s1;
+    Bytef* s2;
+    uInt  len;
+{
+    uInt j;
+
+    for (j = 0; j < len; j++) {
+        if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
+    }
+    return 0;
+}
+
+void zmemzero(dest, len)
+    Bytef* dest;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = 0;  /* ??? to be unrolled */
+    } while (--len != 0);
+}
+#endif
+
+#ifdef __TURBOC__
+#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
+/* Small and medium model in Turbo C are for now limited to near allocation
+ * with reduced MAX_WBITS and MAX_MEM_LEVEL
+ */
+#  define MY_ZCALLOC
+
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
+ * must fix the pointer. Warning: the pointer must be put back to its
+ * original form in order to free it, use zcfree().
+ */
+
+#define MAX_PTR 10
+/* 10*64K = 640K */
+
+local int next_ptr = 0;
+
+typedef struct ptr_table_s {
+    voidpf org_ptr;
+    voidpf new_ptr;
+} ptr_table;
+
+local ptr_table table[MAX_PTR];
+/* This table is used to remember the original form of pointers
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
+ * protected from concurrent access. This hack doesn't work anyway on
+ * a protected system like OS/2. Use Microsoft C instead.
+ */
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+    voidpf buf = opaque; /* just to make some compilers happy */
+    ulg bsize = (ulg)items*size;
+
+    /* If we allocate less than 65520 bytes, we assume that farmalloc
+     * will return a usable pointer which doesn't have to be normalized.
+     */
+    if (bsize < 65520L) {
+        buf = farmalloc(bsize);
+        if (*(ush*)&buf != 0) return buf;
+    } else {
+        buf = farmalloc(bsize + 16L);
+    }
+    if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
+    table[next_ptr].org_ptr = buf;
+
+    /* Normalize the pointer to seg:0 */
+    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
+    *(ush*)&buf = 0;
+    table[next_ptr++].new_ptr = buf;
+    return buf;
+}
+
+void  zcfree (voidpf opaque, voidpf ptr)
+{
+    int n;
+    if (*(ush*)&ptr != 0) { /* object < 64K */
+        farfree(ptr);
+        return;
+    }
+    /* Find the original pointer */
+    for (n = 0; n < next_ptr; n++) {
+        if (ptr != table[n].new_ptr) continue;
+
+        farfree(table[n].org_ptr);
+        while (++n < next_ptr) {
+            table[n-1] = table[n];
+        }
+        next_ptr--;
+        return;
+    }
+    ptr = opaque; /* just to make some compilers happy */
+    Assert(0, "zcfree: ptr not found");
+}
+#endif
+#endif /* __TURBOC__ */
+
+
+#if defined(M_I86) && !defined(__32BIT__)
+/* Microsoft C in 16-bit mode */
+
+#  define MY_ZCALLOC
+
+#if (!defined(_MSC_VER) || (_MSC_VER < 600))
+#  define _halloc  halloc
+#  define _hfree   hfree
+#endif
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+    if (opaque) opaque = 0; /* to make compiler happy */
+    return _halloc((long)items, size);
+}
+
+void  zcfree (voidpf opaque, voidpf ptr)
+{
+    if (opaque) opaque = 0; /* to make compiler happy */
+    _hfree(ptr);
+}
+
+#endif /* MSC */
+
+
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
+
+#ifndef STDC
+extern voidp  calloc OF((uInt items, uInt size));
+extern void   free   OF((voidpf ptr));
+#endif
+
+voidpf zcalloc (opaque, items, size)
+    voidpf opaque;
+    unsigned items;
+    unsigned size;
+{
+    if (opaque) items += size - size; /* make compiler happy */
+    return (voidpf)calloc(items, size);
+}
+
+void  zcfree (opaque, ptr)
+    voidpf opaque;
+    voidpf ptr;
+{
+    free(ptr);
+    if (opaque) return; /* make compiler happy */
+}
+
+#endif /* MY_ZCALLOC */
diff --git a/src/zlib/zutil.h b/src/zlib/zutil.h
new file mode 100644
index 0000000000..5e403d1d78
--- /dev/null
+++ b/src/zlib/zutil.h
@@ -0,0 +1,221 @@
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef _Z_UTIL_H
+#define _Z_UTIL_H
+
+#include "zlib.h"
+
+#ifdef STDC
+#  include <stddef.h>
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+    extern int errno;
+#else
+#   include <errno.h>
+#endif
+
+#ifndef local
+#  define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+typedef unsigned char  uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long  ulg;
+
+extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+  return (strm->msg = (char*)ERR_MSG(err), (err))
+/* To be used only when the state is known to be valid */
+
+        /* common constants */
+
+#ifndef DEF_WBITS
+#  define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+#  define DEF_MEM_LEVEL 8
+#else
+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES    2
+/* The three kinds of block type */
+
+#define MIN_MATCH  3
+#define MAX_MATCH  258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+        /* target dependencies */
+
+#ifdef MSDOS
+#  define OS_CODE  0x00
+#  ifdef __TURBOC__
+#    if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+       /* Allow compilation with ANSI keywords only enabled */
+       void _Cdecl farfree( void *block );
+       void *_Cdecl farmalloc( unsigned long nbytes );
+#    else
+#     include <alloc.h>
+#    endif
+#  else /* MSC or DJGPP */
+#    include <malloc.h>
+#  endif
+#endif
+
+#ifdef OS2
+#  define OS_CODE  0x06
+#endif
+
+#ifdef WIN32 /* Window 95 & Windows NT */
+#  define OS_CODE  0x0b
+#endif
+
+#if defined(VAXC) || defined(VMS)
+#  define OS_CODE  0x02
+#  define F_OPEN(name, mode) \
+     fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#ifdef AMIGA
+#  define OS_CODE  0x01
+#endif
+
+#if defined(ATARI) || defined(atarist)
+#  define OS_CODE  0x05
+#endif
+
+#if defined(MACOS) || defined(TARGET_OS_MAC)
+#  define OS_CODE  0x07
+#  ifndef fdopen
+#    define fdopen(fd,mode) NULL /* No fdopen() */
+#  endif
+#endif
+#if defined(__MWERKS__) && !defined(fdopen)
+#  if __dest_os != __be_os && __dest_os != __win32_os
+#    define fdopen(fd,mode) NULL
+#  endif
+#endif
+
+#ifdef __50SERIES /* Prime/PRIMOS */
+#  define OS_CODE  0x0F
+#endif
+
+#ifdef TOPS20
+#  define OS_CODE  0x0a
+#endif
+
+#if defined(_BEOS_) || defined(RISCOS)
+#  define fdopen(fd,mode) NULL /* No fdopen() */
+#endif
+
+#if (defined(_MSC_VER) && (_MSC_VER >= 600))
+#  define fdopen(fd,type)  _fdopen(fd,type)
+#endif
+
+
+        /* Common defaults */
+
+#ifndef OS_CODE
+#  define OS_CODE  0x03  /* assume Unix */
+#endif
+
+#ifndef F_OPEN
+#  define F_OPEN(name, mode) fopen((name), (mode))
+#endif
+
+         /* functions */
+
+#ifdef HAVE_STRERROR
+   extern char *strerror OF((int));
+#  define zstrerror(errnum) strerror(errnum)
+#else
+#  define zstrerror(errnum) ""
+#endif
+
+#if defined(pyr)
+#  define NO_MEMCPY
+#endif
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
+ /* Use our own functions for small and medium model with MSC <= 5.0.
+  * You may have to use the same strategy for Borland C (untested).
+  * The __SC__ check is for Symantec.
+  */
+#  define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+#  define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
+#  ifdef SMALL_MEDIUM /* MSDOS small or medium model */
+#    define zmemcpy _fmemcpy
+#    define zmemcmp _fmemcmp
+#    define zmemzero(dest, len) _fmemset(dest, 0, len)
+#  else
+#    define zmemcpy memcpy
+#    define zmemcmp memcmp
+#    define zmemzero(dest, len) memset(dest, 0, len)
+#  endif
+#else
+   extern void zmemcpy  OF((Bytef* dest, Bytef* source, uInt len));
+   extern int  zmemcmp  OF((Bytef* s1,   Bytef* s2, uInt len));
+   extern void zmemzero OF((Bytef* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+#ifdef DEBUG
+#  include <stdio.h>
+   extern int z_verbose;
+   extern void z_error    OF((char *m));
+#  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+#  define Trace(x) {if (z_verbose>=0) fprintf x ;}
+#  define Tracev(x) {if (z_verbose>0) fprintf x ;}
+#  define Tracevv(x) {if (z_verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+
+typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
+				       uInt len));
+voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
+void   zcfree  OF((voidpf opaque, voidpf ptr));
+
+#define ZALLOC(strm, items, size) \
+           (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+#endif /* _Z_UTIL_H */
diff --git a/template.mak b/template.mak
new file mode 100644
index 0000000000..18028c45ef
--- /dev/null
+++ b/template.mak
@@ -0,0 +1,35 @@
+#the calling Makefile MUST set OS and RULE
+#RULE can be one of the following:
+# bin      for                             one local  binary 
+# bin2     for                             two local  binaries
+# gbin     for                             one global binary
+# gbin2    for                             two global binaries
+# lib      for a local         library
+# libbin   for a local         library and one local  binary
+# libgbin  for a local         library and one global binary
+# glib     for a global        library
+# glibbin  for a global        library and one local  binary
+# glibgbin for a global        library and one global binary
+# gslib    for a global shared library
+
+# no need to edit below this line !!!!
+
+RULES_DIR=$(WXBASEDIR)/src/gtk/setup/rules
+RULES_GENERIC=$(RULES_DIR)/generic
+SETUP_DIR=$(WXBASEDIR)/src/gtk/setup/$(OS)
+SHARE_DIR=$(WXBASEDIR)/src/gtk/setup/shared
+
+SRCDIR=$(WXBASEDIR)/src
+UTILS=$(WXBASEDIR)/utils
+SAMPLES=$(WXBASEDIR)/samples
+OTHER=$(WXBASEDIR)/other
+
+# now include the global setting
+include $(SETUP_DIR)/maketmpl
+
+# now include the rule needed
+include $(RULES_DIR)/$(RULE)
+
+# now include the global objects
+include $(RULES_GENERIC)/globals
+
diff --git a/user/Makefile b/user/Makefile
new file mode 100644
index 0000000000..58aefc246f
--- /dev/null
+++ b/user/Makefile
@@ -0,0 +1 @@
+include ../src/gtk/setup/general/makedirs
diff --git a/user/wxConvert/Makefile b/user/wxConvert/Makefile
new file mode 100644
index 0000000000..027d82ae19
--- /dev/null
+++ b/user/wxConvert/Makefile
@@ -0,0 +1 @@
+include ../../src/gtk/setup/general/makeapp
diff --git a/user/wxConvert/Makefile.in b/user/wxConvert/Makefile.in
new file mode 100644
index 0000000000..5f781538f6
--- /dev/null
+++ b/user/wxConvert/Makefile.in
@@ -0,0 +1,26 @@
+# WXXT base directory
+WXBASEDIR=@WXBASEDIR@
+
+# set the OS type for compilation
+OS=@OS@
+# compile a library only
+RULE=bin
+
+# define library name
+BIN_TARGET=wxConvert
+# define library sources
+BIN_SRC=\
+wxConvert.cpp
+
+#define library objects
+BIN_OBJ=\
+wxConvert.o
+
+# additional things needed to link
+BIN_LINK=
+
+# additional things needed to compile
+ADD_COMPILE=
+
+# include the definitions now
+include ../../../template.mak
diff --git a/user/wxConvert/wxConvert.cpp b/user/wxConvert/wxConvert.cpp
new file mode 100644
index 0000000000..fb363927f4
--- /dev/null
+++ b/user/wxConvert/wxConvert.cpp
@@ -0,0 +1,175 @@
+/*
+ * Program: wxConvert
+ * 
+ * Author: Robert Roebling
+ *
+ * Copyright: (C) 1997, GNU (Robert Roebling)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * You may not use this program without clapping twice at every
+ * full hour.
+ *
+ */
+
+#ifdef __GNUG__
+#pragma implementation "wxConvert.h"
+#endif
+
+#include "wxConvert.h"
+#include "wx/textfile.h"
+
+//-----------------------------------------------------------------------------
+// main program
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_APP(MyApp)
+
+//-----------------------------------------------------------------------------
+// MyFrame
+//-----------------------------------------------------------------------------
+
+const  ID_QUIT         = 100;
+const  ID_2UNIX        = 101;
+const  ID_2DOS         = 102;
+const  ID_2MAC         = 103;
+
+IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame )
+
+BEGIN_EVENT_TABLE(MyFrame,wxFrame)
+  EVT_BUTTON      (ID_QUIT,    MyFrame::OnCommand)
+  EVT_BUTTON      (ID_2UNIX,   MyFrame::OnCommand)
+  EVT_BUTTON      (ID_2DOS,    MyFrame::OnCommand)
+  EVT_BUTTON      (ID_2MAC,    MyFrame::OnCommand)
+END_EVENT_TABLE()
+
+MyFrame::MyFrame(void) :
+  wxFrame( NULL, -1, "wxConvert", wxPoint(20,20), wxSize(400,160) )
+{
+  CreateStatusBar( 1 );
+  
+  SetStatusText( "wxConvert v0.1 by Robert Roebling." );
+ 
+  char buf[500];
+  wxGetWorkingDirectory( buf, 500 );
+  wxString s( "Dir: " );
+  s += buf;
+  
+  m_text = new wxStaticText( this, -1, s, wxPoint(10,50), wxSize(380,-1) );
+  
+  (void*)new wxButton( this, ID_QUIT, "Quit", wxPoint(10,100), wxSize(60,25) );
+  
+  (void*)new wxButton( this, ID_2UNIX, "To Unix", wxPoint(180,100), wxSize(60,25) );
+  
+  (void*)new wxButton( this, ID_2DOS, "To Dos", wxPoint(250,100), wxSize(60,25) );
+  
+  (void*)new wxButton( this, ID_2MAC, "To Mac", wxPoint(320,100), wxSize(60,25) );
+};
+
+void MyFrame::OnCommand( wxCommandEvent &event )
+{
+  switch (event.GetId())
+  {
+    case ID_QUIT:
+      Close( TRUE );
+      break;
+    case ID_2UNIX:
+    case ID_2DOS:
+    case ID_2MAC:
+      char buf[500];
+      wxGetWorkingDirectory( buf, 500 );
+      wxString s( buf );
+      Recurse( event.GetId(), s );
+      break;
+  };
+};
+
+void MyFrame::Convert( int id, const wxString &fname )
+{
+  wxTextFile text(fname );
+  text.Open();
+  return;
+  
+  switch (id)
+  {
+    case ID_2UNIX:
+      text.Write( wxTextFile::Type_Unix );
+      break;
+    case ID_2DOS:
+      text.Write( wxTextFile::Type_Dos );
+      break;
+    case ID_2MAC:
+      text.Write( wxTextFile::Type_Mac );
+      break;
+  };
+  
+};
+
+void MyFrame::Recurse( int id, const wxString &curdir )
+{
+  wxArrayString paths;
+  wxString search,path;
+  
+  search = curdir;
+  search += "/*";
+  
+  path = wxFindFirstFile( search, wxDIR );
+  while (!path.IsNull())
+  {
+    paths.Add( path );  // ref counting in action !
+    path = wxFindNextFile();
+  };
+  
+  
+  search = curdir;
+  search += "/*.cpp";
+  
+  path = wxFindFirstFile( search, wxFILE );
+  while (!path.IsNull())
+  {
+    m_text->SetLabel( path );
+    wxYield();
+    Convert( id, path );
+    path = wxFindNextFile();
+  };
+
+  for (int i = 0; i < paths.Count(); i++)
+  {
+    search = paths[i];
+    Recurse( id, search );
+  };
+};
+
+//-----------------------------------------------------------------------------
+// MyApp
+//-----------------------------------------------------------------------------
+
+MyApp::MyApp(void) : 
+  wxApp( )
+{
+};
+
+bool MyApp::OnInit(void)
+{
+  wxFrame *frame = new MyFrame();
+  frame->Show( TRUE );
+  
+  return TRUE;
+};
+
+
+
+
+
diff --git a/user/wxConvert/wxConvert.h b/user/wxConvert/wxConvert.h
new file mode 100644
index 0000000000..a6de4a46ac
--- /dev/null
+++ b/user/wxConvert/wxConvert.h
@@ -0,0 +1,71 @@
+/*
+ * Program: wxConvert
+ * 
+ * Author: Robert Roebling
+ *
+ * Copyright: (C) 1997, GNU (Robert Roebling)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __WXCONVERTH__
+#define __WXCONVERTH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/wx.h"
+
+//-----------------------------------------------------------------------------
+// derived classes
+//-----------------------------------------------------------------------------
+
+class MyFrame;
+class MyApp;
+
+//-----------------------------------------------------------------------------
+// MyFrame
+//-----------------------------------------------------------------------------
+
+class MyFrame: public wxFrame
+{
+  DECLARE_DYNAMIC_CLASS(MyFrame)
+
+  public:
+  
+    MyFrame(void);
+    void OnCommand( wxCommandEvent &event );
+    void Recurse( int id, const wxString &curdir );
+    void Convert( int id, const wxString &fname );
+    
+    wxStaticText          *m_text;
+    
+  DECLARE_EVENT_TABLE()
+};
+
+//-----------------------------------------------------------------------------
+// MyApp
+//-----------------------------------------------------------------------------
+
+class MyApp: public wxApp
+{
+  public:
+  
+    MyApp(void);
+    virtual bool OnInit(void);
+};
+
+#endif // __WXCONVERTH__
diff --git a/user/wxFile/Makefile b/user/wxFile/Makefile
new file mode 100644
index 0000000000..027d82ae19
--- /dev/null
+++ b/user/wxFile/Makefile
@@ -0,0 +1 @@
+include ../../src/gtk/setup/general/makeapp
diff --git a/user/wxFile/Makefile.in b/user/wxFile/Makefile.in
new file mode 100644
index 0000000000..278eb64145
--- /dev/null
+++ b/user/wxFile/Makefile.in
@@ -0,0 +1,26 @@
+# WXXT base directory
+WXBASEDIR=@WXBASEDIR@
+
+# set the OS type for compilation
+OS=@OS@
+# compile a library only
+RULE=bin
+
+# define library name
+BIN_TARGET=wxFile
+# define library sources
+BIN_SRC=\
+wxFile.cpp filectrl.cpp dirctrl.cpp
+
+#define library objects
+BIN_OBJ=\
+wxFile.o filectrl.o dirctrl.o
+
+# additional things needed to link
+BIN_LINK=
+
+# additional things needed to compile
+ADD_COMPILE=
+
+# include the definitions now
+include ../../../template.mak
diff --git a/user/wxFile/commanderview.xpm b/user/wxFile/commanderview.xpm
new file mode 100644
index 0000000000..1ed8d8d47d
--- /dev/null
+++ b/user/wxFile/commanderview.xpm
@@ -0,0 +1,31 @@
+/* XPM */
+static char * commanderview_xpm[] = {
+"22 22 3 1",
+" 	c None",
+".	c #000000000000",
+"X	c #FFFFFFFFFFFF",
+"                      ",
+"                      ",
+"                      ",
+"                      ",
+"                      ",
+"  .................   ",
+"  .XXXXXXX.XXXXXXX.   ",
+"  .XX...XX.XX...XX.   ",
+"  .XXXXXXX.XXXXXXX.   ",
+"  .XX...XX.XX..XXX.   ",
+"  .XXXXXXX.XXXXXXX.   ",
+"  .XX..XXX.XX...XX.   ",
+"  .XXXXXXX.XXXXXXX.   ",
+"  .XX...XX.XX...XX.   ",
+"  .XXXXXXX.XXXXXXX.   ",
+"  .XX...XX.XX...XX.   ",
+"  .XXXXXXX.XXXXXXX.   ",
+"  .................   ",
+"                      ",
+"                      ",
+"                      ",
+"                      "};
+
+
+
diff --git a/user/wxFile/delete.xpm b/user/wxFile/delete.xpm
new file mode 100644
index 0000000000..41d24d2778
--- /dev/null
+++ b/user/wxFile/delete.xpm
@@ -0,0 +1,31 @@
+/* XPM */
+static char * delete_xpm[] = {
+"22 22 6 1",
+" 	s None	c None",
+".	c black",
+"X	c red2",
+"o	c white",
+"O	c #DEF6DEF6DEF6",
+"+	c grey70",
+"                      ",
+"                      ",
+"                      ",
+"      ........        ",
+"  XXX .ooooooO.       ",
+"   XXXXOoooooOo.   X  ",
+"     XXXOoooo Oo. XX  ",
+"      .XXXOoo ...XX   ",
+"      .+XXXOo OOXX    ",
+"      .O++XXXOXXX.    ",
+"      .ooO+XXXXX+.    ",
+"      .oooOXXXX+o.    ",
+"      .ooXXXX+XXo.    ",
+"      .XXXX++OXXO.    ",
+"     XXXX++Ooo+XX.    ",
+"   XXXX++OooooO+XX    ",
+"  XXX .OoooooooOXX    ",
+"      .ooooooooo+XX   ",
+"      ...........XX   ",
+"                  X   ",
+"                      ",
+"                      "};
diff --git a/user/wxFile/dirctrl.cpp b/user/wxFile/dirctrl.cpp
new file mode 100644
index 0000000000..54cc5b683d
--- /dev/null
+++ b/user/wxFile/dirctrl.cpp
@@ -0,0 +1,220 @@
+/*
+ * Author: Robert Roebling
+ *
+ * Copyright: (C) 1997,1998 Robert Roebling
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the wxWindows Licence, which
+ * you have received with this library (see Licence.htm).
+ *
+ */
+
+#ifdef __GNUG__
+#pragma implementation "dirctrl.h"
+#endif
+
+#include "dirctrl.h"
+#include "wx/gdicmn.h"
+#include "wx/utils.h"
+
+//-----------------------------------------------------------------------------
+// wxDirInfo
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxDirInfo,wxObject)
+ 
+wxDirInfo::wxDirInfo( const wxString &path )
+{
+  m_showHidden = FALSE;
+  m_path = path;
+  if (m_path == "/") m_name ="The Computer";
+  else 
+  if (m_path == "/home")
+  {
+    m_name = "My Home";
+    m_path += "/";
+    char buf[300];
+    wxGetHomeDir( buf );
+    m_path = buf;
+  }
+  else
+  if (m_path == "/proc") m_name = "Info Filesystem";
+  else
+  if (m_path == "/mnt") m_name = "Mounted Devices";
+  else
+  if (m_path == "/usr/X11R6") m_name = "User X11";
+  else
+  if (m_path == "/usr") m_name = "User";
+  else
+  if (m_path == "/var") m_name = "Variables";
+  else
+  if (m_path == "/usr/local") m_name = "User local";
+  else
+  if (m_path == "/mnt") m_name = "Mounted Devices";
+  else 
+    m_name = wxFileNameFromPath( m_path ); 
+};
+
+wxString wxDirInfo::GetName(void) const
+{
+  return m_name;
+};
+
+wxString wxDirInfo::GetPath(void) const
+{
+  return m_path;
+};
+
+//-----------------------------------------------------------------------------
+// wxDirCtrl
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxDirCtrl,wxTreeCtrl)
+
+BEGIN_EVENT_TABLE(wxDirCtrl,wxTreeCtrl)
+  EVT_TREE_ITEM_EXPANDED      (-1, wxDirCtrl::OnExpandItem)
+  EVT_TREE_DELETE_ITEM        (-1, wxDirCtrl::OnDeleteItem)
+  EVT_MOUSE_EVENTS            (wxDirCtrl::OnMouse)
+END_EVENT_TABLE()
+
+wxDirCtrl::wxDirCtrl(void)
+{
+  m_showHidden = FALSE;
+};
+
+wxDirCtrl::wxDirCtrl(wxWindow *parent, const wxWindowID id, const wxString &dir,
+            const wxPoint& pos, const wxSize& size,
+            const long style, const wxString& name )
+ :
+  wxTreeCtrl( parent, id, pos, size, style, name )
+{
+  m_showHidden = FALSE;
+
+  wxTreeItem item;
+  item.m_mask = wxTREE_MASK_TEXT | wxTREE_MASK_CHILDREN | wxTREE_MASK_DATA;
+  item.m_text = "root.";
+  item.m_children = 1;
+  wxDirInfo *info = new wxDirInfo( dir );
+  item.m_data = (long)info;
+  
+  long root_id = InsertItem( 0, item );
+  
+  info = new wxDirInfo( "/" );
+  item.m_text = info->GetName();
+  item.m_data = (long)info;
+  InsertItem( root_id, item );
+  
+  info = new wxDirInfo( "/home" );
+  item.m_text = info->GetName();
+  item.m_data = (long)info;
+  InsertItem( root_id, item );
+  
+  info = new wxDirInfo( "/mnt" );
+  item.m_text = info->GetName();
+  item.m_data = (long)info;
+  InsertItem( root_id, item );
+  
+  info = new wxDirInfo( "/usr" );
+  item.m_text = info->GetName();
+  item.m_data = (long)info;
+  InsertItem( root_id, item );
+  
+  info = new wxDirInfo( "/usr/X11R6" );
+  item.m_text = info->GetName();
+  item.m_data = (long)info;
+  InsertItem( root_id, item );
+  
+  info = new wxDirInfo( "/usr/local" );
+  item.m_text = info->GetName();
+  item.m_data = (long)info;
+  InsertItem( root_id, item );
+  
+  info = new wxDirInfo( "/var" );
+  item.m_text = info->GetName();
+  item.m_data = (long)info;
+  InsertItem( root_id, item );
+  
+  info = new wxDirInfo( "/proc" );
+  item.m_text = info->GetName();
+  item.m_data = (long)info;
+  InsertItem( root_id, item );
+};
+
+void wxDirCtrl::OnExpandItem( const wxTreeEvent &event )
+{
+  wxDirInfo *info = (wxDirInfo *)event.m_item.m_data;
+  if (!info) return;
+  
+  wxArrayString slist;
+  wxString search,path,filename;
+  
+  search = info->GetPath();
+  search += "/*";
+  
+  path = wxFindFirstFile( search, wxDIR );
+  while (!path.IsNull())
+  {
+    filename = wxFileNameFromPath( path );
+    if (m_showHidden || (filename[0] != '.'))
+    {
+      if ((filename != ".") && 
+          (filename != "..") &&
+	  (path != "/home") &&
+	  (path != "/usr/X11R6") &&
+	  (path != "/usr/local") &&
+	  (path != "/usr") &&
+	  (path != "/var") &&
+	  (path != "/home") &&
+	  (path != "/proc") &&
+	  (path != "/mnt")
+	 )
+        slist.Add( path );  // ref counting in action !
+    };
+    path = wxFindNextFile();
+  };
+
+  for (int i = 0; i < slist.Count(); i++)
+  {
+    search = slist[i];
+    search += "/*";
+    path = wxFindFirstFile( search, wxDIR );
+    
+    wxDirInfo *child = new wxDirInfo( slist[i] );
+    wxTreeItem item;
+    item.m_mask = wxTREE_MASK_TEXT | wxTREE_MASK_CHILDREN | wxTREE_MASK_DATA;
+    item.m_text = child->GetName();
+    item.m_children = 0;
+    if (!path.IsNull()) item.m_children = 1;
+    item.m_data = (long)child;
+    InsertItem( event.m_item.m_itemId, item );
+  };
+};
+
+void wxDirCtrl::OnDeleteItem( const wxTreeEvent &event )
+{
+  wxDirInfo *info = (wxDirInfo *)event.m_item.m_data;
+  if (info) delete info;
+};
+
+void wxDirCtrl::OnMouse( wxMouseEvent &event )
+{
+  event.Skip(TRUE);
+  
+  if (event.LeftDown())
+  {
+    m_dragX = event.GetX();
+    m_dragY = event.GetY();
+    return;
+  };
+  
+  if (event.Dragging())
+  {
+    if ((abs(m_dragX-event.GetX()) < 2) &&
+        (abs(m_dragY-event.GetY()) < 2)) return;
+	
+    wxTextDragSource drag( this );
+    drag.SetTextData( "Oh, what a drag." );
+    drag.Start( event.GetX(), event.GetY() );
+  };
+};
+
diff --git a/user/wxFile/dirctrl.h b/user/wxFile/dirctrl.h
new file mode 100644
index 0000000000..514944865c
--- /dev/null
+++ b/user/wxFile/dirctrl.h
@@ -0,0 +1,74 @@
+/*
+ * File:	DirCtrl.h
+ * Purpose:	dir tree control
+ * Author:	Robert Roebling
+ * Created:	1997
+ * Updated:	
+ * Copyright:
+ */
+
+#ifndef __DIRCTRLH__
+#define __DIRCTRLH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/treectrl.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxDirInfo;
+class wxDirCtrl;
+
+//-----------------------------------------------------------------------------
+// wxDirInfo
+//-----------------------------------------------------------------------------
+
+class wxDirInfo: public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxDirInfo)
+
+ public:
+
+  wxString   m_name;
+  wxString   m_path;
+  bool       m_showHidden;
+  
+ 
+  wxDirInfo() {};
+  wxDirInfo( const wxString &path );
+  wxString GetName(void) const;
+  wxString GetPath(void) const;
+};
+
+//-----------------------------------------------------------------------------
+// wxDirCtrl
+//-----------------------------------------------------------------------------
+
+class wxDirCtrl: public wxTreeCtrl
+{
+  DECLARE_DYNAMIC_CLASS(wxDirCtrl)
+  
+  public:
+
+    bool   m_showHidden;
+    int    m_dragX,m_dragY;
+  
+    wxDirCtrl(void);
+    wxDirCtrl(wxWindow *parent, const wxWindowID id = -1, const wxString &dir = "/",
+            const wxPoint& pos = wxDefaultPosition,
+            const wxSize& size = wxDefaultSize,
+            const long style = wxTR_HAS_BUTTONS,
+            const wxString& name = "wxTreeCtrl" )
+;
+    void OnExpandItem( const wxTreeEvent &event );
+    void OnDeleteItem( const wxTreeEvent &event );
+    void OnMouse( wxMouseEvent &event );
+
+  DECLARE_EVENT_TABLE()
+};
+
+#endif
diff --git a/user/wxFile/exit.xpm b/user/wxFile/exit.xpm
new file mode 100644
index 0000000000..eecc0d3000
--- /dev/null
+++ b/user/wxFile/exit.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * exit_xpm[] = {
+"22 22 4 1",
+" 	c None",
+".	c #000000000000",
+"X	c #820782078207",
+"o	c #FFFFFFFFFFFF",
+"                      ",
+"                      ",
+"                      ",
+"                      ",
+"                      ",
+"             .        ",
+"     ..X    .o.X      ",
+"      ..X  .ooo.X     ",
+"       .o..oo ..XX    ",
+"        .oo  .XXXX    ",
+"         .o .XXX      ",
+"        .o  .XX       ",
+"       .o.X.o.X       ",
+"      .o.XX .o.X      ",
+"     .o.XX   ..X      ",
+"     ..XX     ..X     ",
+"     .XX       .X     ",
+"     XX        XX     ",
+"                      ",
+"                      ",
+"                      ",
+"                      "};
diff --git a/user/wxFile/filectrl.cpp b/user/wxFile/filectrl.cpp
new file mode 100644
index 0000000000..6320a655e1
--- /dev/null
+++ b/user/wxFile/filectrl.cpp
@@ -0,0 +1,541 @@
+/*
+ * Author: Robert Roebling
+ *
+ * Copyright: (C) 1997,1998 Robert Roebling
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the wxWindows Licence, which
+ * you have received with this library (see Licence.htm).
+ *
+ */
+
+
+#ifdef __GNUG__
+#pragma implementation "filectrl.h"
+#endif
+
+#include "filectrl.h"
+
+#include "wx/dnd.h"
+
+#include "sys/types.h"
+#include "sys/stat.h"
+#include "dirent.h"
+#include "pwd.h"
+#include "grp.h"
+#include "time.h"
+
+#include "folder.xpm"
+#include "txt.xpm"
+#include "list.xpm"
+#include "find.xpm"
+
+//-----------------------------------------------------------------------------
+//  wxFileData
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxFileData,wxObject);
+
+wxFileData::wxFileData( const wxString &name, const wxString &fname )
+{
+  m_name = name;
+  m_fileName = fname;
+
+  struct stat buff;
+  stat( m_fileName.GetData(), &buff );
+  struct stat lbuff;
+  lstat( m_fileName.GetData(), &lbuff );
+
+  struct tm *t = localtime( &lbuff.st_mtime );
+//  struct passwd *user = getpwuid( buff.st_uid );
+//  struct group *grp = getgrgid( buff.st_gid );
+
+  m_isDir = S_ISDIR( buff.st_mode );
+  m_isLink = S_ISLNK( lbuff.st_mode );
+  m_isExe = ((buff.st_mode & S_IXUSR ) == S_IXUSR );
+
+  m_size = buff.st_size;
+
+  m_hour = t->tm_hour;
+  m_minute = t->tm_min;
+  m_month = t->tm_mon+1;
+  m_day = t->tm_mday;
+  m_year = t->tm_year;
+
+  m_permissions.sprintf( "%c%c%c", 
+     ((( buff.st_mode & S_IRUSR ) == S_IRUSR ) ? 'r' : '-'),
+     ((( buff.st_mode & S_IWUSR ) == S_IWUSR ) ? 'w' : '-'),
+     ((( buff.st_mode & S_IXUSR ) == S_IXUSR ) ? 'x' : '-') );
+};
+
+wxString wxFileData::GetName(void) const
+{
+  return m_name;
+};
+
+wxString wxFileData::GetFullName(void) const
+{
+  return m_fileName;
+};
+
+wxString wxFileData::GetHint(void) const
+{
+  wxString s = m_fileName;
+  s += "  ";
+  if (m_isDir) s += "<DIR> ";
+  else if (m_isLink) s += "<LINK> ";
+  else
+  {
+    s += LongToString( m_size );
+    s += " bytes ";
+  };
+  s += IntToString( m_day );
+  s += ".";
+  s += IntToString( m_month );
+  s += ".";
+  s += IntToString( m_year );
+  s += "  ";
+  s += IntToString( m_hour );
+  s += ":";
+  s += IntToString( m_minute );
+  s += "  ";
+  s += m_permissions;
+  return s;
+};
+
+wxString wxFileData::GetEntry( const int num )
+{
+  wxString s;
+  switch (num)
+  {
+    case 0:
+      s = m_name;
+      break;
+    case 1:
+      if (m_isDir) s = "<DIR>";
+      else if (m_isLink) s = "<LINK>";
+      else s = LongToString( m_size );
+      break;
+    case 2:
+      if (m_day < 10) s = "0"; else s = "";
+      s += IntToString( m_day );
+      s += ".";
+      if (m_month < 10) s += "0"; 
+      s += IntToString( m_month );
+      s += ".";
+      if (m_year < 10) s += "0"; // this should happen real soon...
+      s += IntToString( m_year );
+      break;
+    case 3:
+      if (m_hour < 10) s = "0"; else s = "";
+      s += IntToString( m_hour );
+      s += ":";
+      if (m_minute < 10) s += "0";
+      s += IntToString( m_minute );
+      break;
+    case 4:
+      s = m_permissions;
+      break;
+    default:
+      s = "No entry";
+      break;
+  };
+  return s;
+};
+
+bool wxFileData::IsDir( void )
+{
+  return m_isDir;
+};
+
+bool wxFileData::IsExe( void )
+{
+  return m_isExe;
+};
+
+bool wxFileData::IsLink( void )
+{
+  return m_isLink;
+};
+
+long wxFileData::GetSize( void )
+{
+  return m_size;
+};
+
+bool wxFileData::NewNameIsLegal( const wxString &s )
+{
+  wxString fileName = wxPathOnly( m_fileName );
+  fileName += "/";
+  fileName += s;
+  return (!wxFileExists( fileName ));
+};
+
+bool wxFileData::Rename( const wxString &s )
+{
+  wxString fileName = wxPathOnly( m_fileName );
+  fileName += "/";
+  fileName += s;
+  bool ret = wxRenameFile( m_fileName, fileName );
+  if (ret)
+  {
+    m_fileName = fileName;
+    m_name = s;
+  };
+  return ret;
+};
+
+void wxFileData::MakeItem( wxListItem &item )
+{
+  item.m_text = m_name;
+  item.m_colour = wxBLACK;
+  if (IsExe()) item.m_colour = wxRED;
+  if (IsDir()) item.m_colour = wxBLUE;
+  if (IsLink())
+  {
+    wxColour *dg = wxTheColourDatabase->FindColour( "MEDIUM GREY" );
+    item.m_colour = dg;
+  };
+  item.m_data = (long)this;
+};
+  
+//-----------------------------------------------------------------------------
+//  wxFileCtrl
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxFileCtrl,wxListCtrl);
+
+BEGIN_EVENT_TABLE(wxFileCtrl,wxListCtrl)
+  EVT_SET_FOCUS   (wxFileCtrl::OnSetFocus)
+END_EVENT_TABLE()
+
+wxFileCtrl *wxFileCtrl::m_lastFocus = NULL;
+
+wxFileCtrl::wxFileCtrl( void )
+{
+  m_dirName = "/";
+  m_showHidden = FALSE;
+};
+
+wxFileCtrl::wxFileCtrl( wxWindow *win, const wxWindowID id, const wxString &dirName,
+      const wxPoint &pos, const wxSize &size,
+      const long style, const wxString &name ) :
+  wxListCtrl( win, id, pos, size, style, name )
+{
+  wxImageList *imageList = new wxImageList();
+  imageList->Add( wxBitmap( folder_xpm ) );
+  imageList->Add( wxBitmap( txt_xpm ) );
+  imageList->Add( wxBitmap( list_xpm ) );
+  imageList->Add( wxBitmap( find_xpm ) );
+  
+  SetImageList( imageList, wxIMAGE_LIST_NORMAL );
+  
+  m_dirName = dirName;
+  m_showHidden = FALSE;
+  Update();
+  
+  m_lastFocus = this;
+  
+  SetDropTarget( new wxTextDropTarget() );
+};
+
+void wxFileCtrl::ChangeToListMode()
+{
+  SetSingleStyle( wxLC_LIST );
+  Update();
+};
+
+void wxFileCtrl::ChangeToReportMode()
+{
+  SetSingleStyle( wxLC_REPORT );
+  Update();
+};
+
+void wxFileCtrl::ChangeToIconMode()
+{
+  SetSingleStyle( wxLC_ICON );
+  Update();
+};
+
+void wxFileCtrl::ShowHidden( bool show )
+{
+  m_showHidden = show;
+  Update();
+};
+
+int ListCompare( const long data1, const long data2, const long WXUNUSED(data) )
+{
+   wxFileData *fd1 = (wxFileData*)data1 ;
+   wxFileData *fd2 = (wxFileData*)data2 ;
+   if (fd1->IsDir() && !fd2->IsDir()) return -1;
+   if (fd2->IsDir() && !fd1->IsDir()) return 1;
+   return strcmp( fd1->GetName(), fd2->GetName() );
+};
+
+void wxFileCtrl::Update( void )
+{ 
+  DeleteAllItems();
+  for (int i = 0; i < 5; i++) DeleteColumn( 0 );
+  long my_style = GetWindowStyleFlag();
+  if (my_style & wxLC_REPORT)
+  {
+    InsertColumn( 0, "Name", wxLIST_FORMAT_LEFT, 110 );
+    InsertColumn( 1, "Size", wxLIST_FORMAT_LEFT, 60 );
+    InsertColumn( 2, "Date", wxLIST_FORMAT_LEFT, 55 );
+    InsertColumn( 3, "Time", wxLIST_FORMAT_LEFT, 50 );
+    InsertColumn( 4, "Permissions", wxLIST_FORMAT_LEFT, 120 );
+  };
+  wxFileData *fd = NULL;
+  wxListItem item;
+  item.m_mask = wxLIST_MASK_TEXT + wxLIST_MASK_DATA;
+  if (my_style & wxLC_ICON) item.m_mask += wxLIST_MASK_IMAGE;
+  item.m_itemId = 0;
+  item.m_col = 0;
+  wxString s;
+  wxString res = m_dirName + "/*";
+  char *f = wxFindFirstFile( res.GetData(), 0 );
+  while (f)   
+  {
+    res = wxFileNameFromPath( f );
+    fd = new wxFileData( res, f );
+    s = fd->GetName();
+    if (m_showHidden || (s[0] != '.'))
+    {
+      fd->MakeItem( item );
+      if (my_style & wxLC_REPORT)
+      {
+        InsertItem( item );
+        for (int i = 1; i < 5; i++) SetItem( item.m_itemId, i, fd->GetEntry( i) );
+      }
+      else if (my_style & wxLC_LIST)
+      {
+        InsertItem( item );
+      } 
+     else if (my_style & wxLC_ICON)
+      {
+        if (fd->IsDir()) item.m_image = 0; else item.m_image = 1;
+        InsertItem( item );
+      };
+      item.m_itemId++;
+    };
+    f = wxFindNextFile();
+  };
+  SortItems( ListCompare, 0 );
+  RealizeChanges();
+};
+
+
+int wxFileCtrl::FillList( wxStringList &list )
+{
+  long index = -1;
+  int count = 0;
+  wxString s;
+  for (;;)
+  {
+    index = GetNextItem( index, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
+    if (index == -1) break;
+    wxListItem item;
+    item.m_itemId = index;
+    GetItem( item );
+    wxFileData *fd = (wxFileData*)item.m_data;
+    list.Add( fd->GetFullName() );
+    index++;
+    count++;
+  };
+  if (count == 0)
+  {
+    index = GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_FOCUSED );
+    if (index == -1) return 0;
+    wxListItem item;
+    item.m_itemId = index;
+    GetItem( item );
+    wxFileData *fd = (wxFileData*)item.m_data;
+    list.Add( fd->GetFullName() );
+    count = 1;
+  };
+  return count;
+};
+
+void wxFileCtrl::DeleteFiles(void)
+{
+/*
+  wxStringList list;
+  int count = FillList( list );
+  if (count > 0)
+  { 
+    wxString s = "Delete ";
+    s += wxIntToString( count );
+    s += " selected file";
+    if (count > 1) s += "s";
+    s += " or director";
+    if (count > 1) s += "ies?"; else s+= "y?";
+    if (wxYES == wxMessageBox( s, "Delete", wxYES_NO ))
+      wxDeleteStatusDia( NULL, &list );
+  };
+*/
+};
+
+void wxFileCtrl::CopyFiles( char *WXUNUSED(dest) )
+{
+/*
+  wxStringList list;
+  int count = FillList( list );
+  wxString s = dest;
+  int ret = 0; // 0 = nix, 1 = copy, 2 = move
+  wxCopyMoveDia( (wxFrame*)GetParent(), count, &ret, &s );
+  if (ret == 1) 
+    wxCopyStatusDia( NULL, s, &list );
+*/
+};
+
+void wxFileCtrl::MoveFiles( char *WXUNUSED(dest) )
+{
+};
+
+void wxFileCtrl::RenameFile(void)
+{
+};
+
+void wxFileCtrl::MakeDir(void)
+{
+/*
+  wxString s = wxGetTextFromUser( "Enter new directory name:", "Make directory" );
+  if (s.IsNull()) return;
+  if (s == "") return;
+  if ((s == ".") || (s == ".."))
+  {
+    wxMessageBox( "This was obviously an invalid directory name.", "Go away." );
+    return;
+  };
+  wxString dir;
+  GetDir( dir );
+  dir += "/";
+  dir += s;
+  if (wxFileExists( dir ))
+  {
+    wxMessageBox( "Filename exists already. Cannot create directoy.", "Make directory" );
+    return;
+  };
+  wxMkdir( dir );
+  Update();
+*/
+};
+
+void wxFileCtrl::GoToParentDir(void)
+{
+  wxString s = m_dirName;
+  int pos = s.Last( '/' );  
+  if ((pos >= 0) && (s != "/"))
+  {
+    s.Remove( pos, s.Length()-pos );
+    if (s.Length() == 0) s = "/";
+    m_dirName = s;
+    Update();
+  };
+};
+
+void wxFileCtrl::GoToHomeDir(void)
+{
+  wxString s = wxGetUserHome( wxString() );
+  m_dirName = s;
+  Update();
+};
+
+void wxFileCtrl::GoToDir( const wxString &dir )
+{
+  m_dirName = dir;
+  Update();
+};
+
+void wxFileCtrl::GetDir( wxString &dir )
+{
+  dir = m_dirName;
+};
+
+/*
+void wxFileCtrl::OnDropFiles( int WXUNUSED(n), char **WXUNUSED(data), int WXUNUSED(x), int WXUNUSED(y) )
+{
+  wxString destDir;
+  wxPoint pt( x, y );
+  int flag = wxLIST_HITTEST_ONITEM;
+  long hit = HitTest( pt, flag );
+  if (hit > -1)
+  {
+    wxListItem li;
+    li.m_itemId = hit;
+    GetItem( li );
+    wxFileData *fd = (wxFileData*)li.m_data;
+    if (fd->IsDir()) fd->GetFullName( destDir );
+  };
+  if (destDir.IsNull()) destDir = m_dirName;
+  int ret = 0; // 0 = nix, 1 = copy, 2 = move
+  wxCopyMoveDia( (wxFrame*)GetParent(), n, &ret, &destDir );
+  if (ret == 1)
+  {  
+     wxStringList slist;
+     for (int i = 0; i < n; i++) slist.Add( data[i] );
+     wxCopyStatusDia( NULL, destDir.GetData(), &slist );
+     Update();
+  };
+};
+*/
+
+void wxFileCtrl::OnListDeleteItem( wxListEvent &event )
+{
+  wxFileData *fd = (wxFileData*)event.m_item.m_data;
+  delete fd;
+};
+
+void wxFileCtrl::OnListKeyDown( wxListEvent &event )
+{
+  wxFileData *fd = (wxFileData*)event.m_item.m_data;
+  if (fd->IsDir())
+  {
+    m_dirName = fd->GetFullName();
+    Update();
+    Refresh();
+    return;
+  };
+  if (fd->IsExe())
+  {
+    wxExecute( fd->GetFullName() );
+    return;
+  };
+};
+
+void wxFileCtrl::OnListEndLabelEdit( wxListEvent &event )
+{
+  wxFileData *fd = (wxFileData*)event.m_item.m_data;
+  wxString newName = event.m_item.m_text;
+  if (fd->NewNameIsLegal( newName ))
+  {
+    if (fd->Rename( newName ))
+    {
+      Update();
+    }
+    else
+    {
+      wxString s = "Could not rename file to ";
+      s += newName;
+      s += ".";
+      wxMessageBox( s, "FileMaker", wxOK );
+    };
+  }
+  else
+  {
+    wxString s = "File name ";
+    s += newName;
+    s += " exists already or is invalid.\n";
+    s += "Could not rename file.";
+    wxMessageBox( s, "FileMaker", wxOK );
+  };
+  return;
+};
+
+void wxFileCtrl::OnSetFocus( wxFocusEvent &event )
+{
+  m_lastFocus = this;
+  event.Skip();
+};
+
+
diff --git a/user/wxFile/filectrl.h b/user/wxFile/filectrl.h
new file mode 100644
index 0000000000..eb812f9a5a
--- /dev/null
+++ b/user/wxFile/filectrl.h
@@ -0,0 +1,112 @@
+/*
+ * Author: Robert Roebling
+ *
+ * Copyright: (C) 1997,1998 Robert Roebling
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the wxWindows Licence, which
+ * you have received with this library (see Licence.htm).
+ *
+ */
+
+#ifndef FileList_h
+#define FileList_h
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/wx.h"
+#include "wx/listctrl.h"
+
+//-----------------------------------------------------------------------------
+// derived classes
+//-----------------------------------------------------------------------------
+
+class wxFileData;
+class wxFileCtrl;
+
+//-----------------------------------------------------------------------------
+//  wxFileData
+//-----------------------------------------------------------------------------
+
+class wxFileData : public wxObject
+{
+  DECLARE_DYNAMIC_CLASS(wxFileData);
+
+  private:
+    wxString m_name;
+    wxString m_fileName;
+    long     m_size;
+    int      m_hour;
+    int      m_minute;
+    int      m_year;
+    int      m_month;
+    int      m_day;
+    wxString m_permissions;
+    bool     m_isDir;
+    bool     m_isLink;
+    bool     m_isExe;
+
+  public:
+    wxFileData( void ) {};
+    wxFileData( const wxString &name, const wxString &fname );
+    wxString GetName(void) const;
+    wxString GetFullName(void) const;
+    wxString GetHint(void) const;
+    wxString GetEntry( const int num );
+    bool IsDir( void );
+    bool IsLink( void );
+    bool IsExe( void );
+    long GetSize( void );
+    bool NewNameIsLegal( const wxString &s );
+    bool Rename( const wxString &s );
+    void MakeItem( wxListItem &item );
+};
+
+//-----------------------------------------------------------------------------
+//  wxFileCtrl
+//-----------------------------------------------------------------------------
+
+class wxFileCtrl : public wxListCtrl
+{
+  DECLARE_DYNAMIC_CLASS(wxFileCtrl);
+
+  public:
+  
+    static wxFileCtrl* m_lastFocus;
+      
+  private:
+    wxString      m_dirName;
+    bool          m_showHidden;
+
+  public:
+    wxFileCtrl( void );
+    wxFileCtrl( wxWindow *win, const wxWindowID id, const wxString &dirName,
+      const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, 
+      const long style = wxLC_LIST, const wxString &name = "filelist" );
+    void ChangeToListMode();
+    void ChangeToReportMode();
+    void ChangeToIconMode();
+    void ShowHidden( bool show = TRUE );
+    void Update( void );
+    virtual void StatusbarText( char *WXUNUSED(text) ) {};
+    int FillList( wxStringList &list );
+    void DeleteFiles(void);
+    void CopyFiles( char *dest );
+    void MoveFiles( char *dest );
+    void RenameFile(void);
+    void MakeDir(void);
+    void GoToParentDir(void);
+    void GoToHomeDir(void);
+    void GoToDir( const wxString &dir );
+    void GetDir( wxString &dir );
+    void OnListDeleteItem( wxListEvent &event );
+    void OnListKeyDown( wxListEvent &event );
+    void OnListEndLabelEdit( wxListEvent &event );
+    void OnSetFocus( wxFocusEvent &event );
+    
+  DECLARE_EVENT_TABLE()
+};
+
+#endif // FileList_h
diff --git a/user/wxFile/fileopen.xpm b/user/wxFile/fileopen.xpm
new file mode 100644
index 0000000000..dd384cadaf
--- /dev/null
+++ b/user/wxFile/fileopen.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static char * fileopen_xpm[] = {
+"22 22 5 1",
+" 	c None",
+".	c #000000000000",
+"X	c #D75CD75CD75C",
+"o	c #FFFFFFFFFFFF",
+"O	c #6DB66DB66DB6",
+"                      ",
+"                      ",
+"            ....      ",
+"               .. .   ",
+"                ...   ",
+"                ...   ",
+"               ....   ",
+"   ....               ",
+"   .XoX.......        ",
+"   .oXoXoXoXo.        ",
+"   .XoXoXoXoX.        ",
+"   .oXoXo ..........  ",
+"   .XoXo . O O O OO.  ",
+"   .oXo . O O OOOO.   ",
+"   .Xo .OO OOOOOO.    ",
+"   .o . O OOOOOO.     ",
+"   ... O OOOOOO.      ",
+"   ..OOOOOOOOO.       ",
+"   ...........        ",
+"                      ",
+"                      ",
+"                      "};
diff --git a/user/wxFile/find.xpm b/user/wxFile/find.xpm
new file mode 100644
index 0000000000..82e5ccbf61
--- /dev/null
+++ b/user/wxFile/find.xpm
@@ -0,0 +1,99 @@
+/* XPM */
+static char * find_xpm[] = {
+"32 32 64 1",
+" 	s background	c None",
+".	c black",
+"X	c #FFFFFBEEFFFF",
+"o	c #AEBAAAAAAEBA",
+"O	c #4924618579E7",
+"+	c #AEBA8A286185",
+"@	c #BEFB8A2871C6",
+"#	c #71C682078617",
+"$	c #4924410330C2",
+"%	c #492451446185",
+"&	c #49243CF338E3",
+"*	c #EFBEAAAA8E38",
+"=	c #AEBA71C66185",
+"-	c #9E79820769A6",
+";	c #5144410338E3",
+":	c #514434D338E3",
+">	c #D75CA28971C6",
+",	c #514430C230C2",
+"<	c #618541034103",
+"1	c #BEFB8A286185",
+"2	c #B6DA7DF75965",
+"3	c #410338E330C2",
+"4	c #514441034103",
+"5	c #AEBA9A696185",
+"6	c #9E7971C65144",
+"7	c #9E7971C66185",
+"8	c #DF7DAEBA9E79",
+"9	c #38E338E330C2",
+"0	c #410330C22081",
+"q	c #A69961855144",
+"w	c #618549244924",
+"e	c #30C230C22081",
+"r	c #38E32CB230C2",
+"t	c #8E3851445144",
+"y	c #28A228A230C2",
+"u	c #79E759654924",
+"i	c #A69969A65965",
+"p	c #8E3861855144",
+"a	c #71C661854103",
+"s	c #208120812081",
+"d	c #596538E330C2",
+"f	c #8E3871C65144",
+"g	c #71C651445144",
+"h	c #186118611861",
+"j	c #8E3861854103",
+"k	c #71C651444103",
+"l	c #71C641034103",
+"z	c #514451445144",
+"x	c #5144514430C2",
+"c	c #104010401040",
+"v	c #410330C230C2",
+"b	c #30C220812081",
+"n	c #618551444103",
+"m	c #79E779E779E7",
+"M	c #6185410330C2",
+"N	c #38E330C22081",
+"B	c #6185514430C2",
+"V	c #38E324922081",
+"C	c #514400000000",
+"Z	c #E79DD34CD75C",
+"A	c #C71BC71BBEFB",
+"S	c #8E387DF769A6",
+"D	c #208128A228A2",
+"F	c #30C238E34103",
+"       ........   XXXo          ",
+"     ..O......O..Xoo+@          ",
+"    .#..$.###%..&.@+*X=-        ",
+"   ...;;;.%$:;;;...XX>XXXo      ",
+"  ...$$,$+XXX.##<#..o111@2      ",
+" .&.34&+XXoo5.XX#%.$.@@5*X=6    ",
+" ..3378X+@@++@@++@@..XX>XXoo+2  ",
+".9.0qXXX2++12+XXX.X.w.XXo11@@1  ",
+"..erX66==66=11111.o1..1111*XX>>t",
+"..yuXi76678X+@2++@@+..:+XXX>+ppa",
+"..sdXpppXX=++@=++=8X..w+fqppupge",
+"..h<XajtX67==67=*XX*..&qqpjttak.",
+"..h<XkwlXfqqiXX*=66=..9qqjjtukd.",
+"..h0Xz<xXpppX*i6-==6..yfpppaak,.",
+".c.vXz4dXzguXi=&-=7.9.rputgawk.z",
+"X..bX,d<XwklX+2==66..rettakkln.m",
+"X.c.Xb0,XkM<X$i=q6.v.NjtulkllB. ",
+"X4..XbVvXz:hX==66...Nytaakknn<. ",
+"X<c...bnX,v0>=76.....pganknwBMz ",
+"XM.w.h..Xb0,*6..v..CC.kklkB<<;m ",
+"ZMzX#..;......9..N.rC...lBM<dem ",
+" =zXXsc........9eNN..CCC.<M:dVm ",
+" =oXA<.##hc$9vNryrye.VCCC.4de.z ",
+" SoXZMzXXyc;vrNttaVV..VCCC.V.z  ",
+" -Xk82zXXM.*qjjtukkbb..sCCC.z   ",
+" SXlA=oXZM.Xpptaakknss..VCCC.   ",
+"  ..z-oXA=zXatganknBx.D..FCCC.  ",
+"   zmSXk82zXtakllBB<.zDD..FCCC. ",
+"      Xl.SoXuknl<.zz   FF..%CCC.",
+"      ..z-oXakkn.zz     %%..OCC.",
+"         SXkn.zzz        %O..OO.",
+"          Xk.z            OO... "};
diff --git a/user/wxFile/folder.xpm b/user/wxFile/folder.xpm
new file mode 100644
index 0000000000..7a36fa27f1
--- /dev/null
+++ b/user/wxFile/folder.xpm
@@ -0,0 +1,48 @@
+/* XPM */
+static char * folder_xpm[] = {
+"33 33 12 1",
+" 	c None",
+".	c #D75CA69979E7",
+"X	c #208120812081",
+"o	c #FFFFFFFFFFFF",
+"O	c #B6DA79E74924",
+"+	c #596559655965",
+"@	c #410341034103",
+"#	c #514451445144",
+"$	c #000000000820",
+"%	c #8E38596530C2",
+"&	c #8E3886178617",
+"*	c #492479E769A6",
+"                                 ",
+"     ..   XXX                    ",
+"     .o.. X.XXX                  ",
+"     .ooo..OOOXXX                ",
+"     .ooooo..OOOXXX    ++        ",
+"XXX  .ooooooo..OOOXXX  @#++@     ",
+"XOX@X.ooooooooo...OOO@XX+X#+++   ",
+"X...@@$.oooooooooo...OOXXX@X@+   ",
+"O.....@XXOooooooooooo..OOOX@@X   ",
+"XO......@%X.ooooooooooo..%%OX@   ",
+".O........@XX.oooooooooo.X%XX    ",
+" %O.........@@$.oooooooo.XX%X    ",
+" %O...........@@$.oooooo.X%X#    ",
+" %O.............@@X.oooo.XX%&    ",
+" .@...............@XX.oo.@XX     ",
+"  %.................@X.o.XXX     ",
+"  OO................O%X..XX@     ",
+"  +OO.......O..OOOOOOO@..@X&     ",
+"  .%O....OOOOOOOOOOOOOX.+XX      ",
+"   XOOOOOOOOOOOOOOOOOOX+*XX      ",
+"   @OOOOO.OOOOOOOOOOOOX*+XX      ",
+"   .%OOOOOOOOOOOOOOO%OXX#XX      ",
+"    XOOOOOOOOOOO%O%O%%OX++&      ",
+"    @O%O%OO%O%%O%%%%%%%XXX       ",
+"     XXXO%%%%%%%%%%%%%%XXX       ",
+"      OXXX%%%%%%%%%%%%@XX#       ",
+"        OX@X%%%%%%%%%%%XXX       ",
+"          OXXX%%%O%%%%%XXX       ",
+"            OXXX%%%%%%%XX*       ",
+"              OX@X%%%%X%X&       ",
+"                OXXX%%%XX        ",
+"                  OXXX%%@        ",
+"                    OXXX         "};
diff --git a/user/wxFile/help.xpm b/user/wxFile/help.xpm
new file mode 100644
index 0000000000..9982a6dc19
--- /dev/null
+++ b/user/wxFile/help.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * help_xpm[] = {
+"22 22 4 1",
+" 	c None",
+".	c #000000000000",
+"X	c #000000008617",
+"o	c #861782078617",
+"                      ",
+"                      ",
+"                      ",
+"                      ",
+"   .        XXXXXo    ",
+"   ..      XX  oXXo   ",
+"   ...    XXo   XXX   ",
+"   ....   XXo   XXX   ",
+"   .....  oXX  oXXo   ",
+"   ......      XXo    ",
+"   .......    XX      ",
+"   ........  XXo      ",
+"   .....     XXo      ",
+"   .. ..              ",
+"   .   ..    XXX      ",
+"       ..    XXX      ",
+"        ..            ",
+"        ..            ",
+"                      ",
+"                      ",
+"                      ",
+"                      "};
diff --git a/user/wxFile/home.xpm b/user/wxFile/home.xpm
new file mode 100644
index 0000000000..13dd4ba122
--- /dev/null
+++ b/user/wxFile/home.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static char * home_xpm[] = {
+"22 22 3 1",
+" 	c None",
+".	c #000000000000",
+"X	c #FFFFFFFFFFFF",
+"                      ",
+"                      ",
+"                      ",
+"          ..          ",
+"     .   ....         ",
+"     .  .XX  .        ",
+"     . .XXXX  .       ",
+"     ..XXXXXX  .      ",
+"     .XXXXXXXX  .     ",
+"    .XXXXXXXXX   .    ",
+"   ...XXXXXXXX  ...   ",
+"     .XXXXXXXX  .     ",
+"     .XXX...XX  .     ",
+"     .XXX. .XX  .     ",
+"     .XXX. .XX  .     ",
+"     .XXX. .XX  .     ",
+"     .XXX. .XX  .     ",
+"     ..... ......     ",
+"                      ",
+"                      ",
+"                      ",
+"                      "};
diff --git a/user/wxFile/iconview.xpm b/user/wxFile/iconview.xpm
new file mode 100644
index 0000000000..09d219e351
--- /dev/null
+++ b/user/wxFile/iconview.xpm
@@ -0,0 +1,31 @@
+/* XPM */
+static char * iconview_xpm[] = {
+"22 22 3 1",
+" 	c None",
+".	c #000000000000",
+"X	c #FFFFFFFFFFFF",
+"                      ",
+"                      ",
+"                      ",
+"                      ",
+"                      ",
+"  .................   ",
+"  .XXXXXXXXXXXXXXX.   ",
+"  .XX...XXXXX...XX.   ",
+"  .XX...XXXXX...XX.   ",
+"  .XXXXXXXXXXXXXXX.   ",
+"  .X.....XXX.....X.   ",
+"  .XXXXXXXXXXXXXXX.   ",
+"  .XX...XXXXX...XX.   ",
+"  .XX...XXXXX...XX.   ",
+"  .XXXXXXXXXXXXXXX.   ",
+"  .X.....XXX.....X.   ",
+"  .XXXXXXXXXXXXXXX.   ",
+"  .................   ",
+"                      ",
+"                      ",
+"                      ",
+"                      "};
+
+
+
diff --git a/user/wxFile/list.xpm b/user/wxFile/list.xpm
new file mode 100644
index 0000000000..b0162e2b07
--- /dev/null
+++ b/user/wxFile/list.xpm
@@ -0,0 +1,45 @@
+/* XPM */
+static char * list_xpm[] = {
+"32 32 10 1",
+" 	c #DF7DDF7DDF7D",
+".	c #9E799E79A699",
+"X	c #AEBAAEBAAEBA",
+"o	c #FFFFFFFFFFFF",
+"O	c #514451445144",
+"+	c #410341034103",
+"@	c #596559655965",
+"#	c #000000000000",
+"$	c #BEFBBEFBBEFB",
+"%	c #208120812081",
+"                                ",
+"                .               ",
+"               Xo..             ",
+"              Xoooo.X           ",
+"             Xooooooo.X         ",
+"            XooooO+ooooXX       ",
+"           XoooooooO+ooo..      ",
+"          XooooOOoooo@@ooo..    ",
+"         XoooooooOOooooooooo.X  ",
+"        Xoooo@Ooooo+@oooO+oooo.X",
+"       Xooooooo@OoooooooooO+oooo",
+"      XooooooooooO@oooOOoooo@@oo",
+"     XooooO+ooooooooooooOOoooooo",
+"    XoooooooO+oooooo@Ooooo+@oooX",
+"   XooooOOoooo@@oooooo@OooooooOX",
+"  XoooooooOOooooooooooooO@oooOX#",
+" Xoooo@Ooooo+@oooO+oooooooooOX#X",
+"Xooooooo@OoooooooooO+ooooooOX#XX",
+"O@$oooooooO@oooOOoooo@@oooOX#XX ",
+"X#+@$ooooooooooooOOooooooOX#XX  ",
+" XX#O@ooooooo@Ooooo+@oooOX#XX   ",
+"   XX#OXooooooo@OooooooOX#X     ",
+"     XXO@XoooooooO@oooOX#X      ",
+"      XX#%@XoooooooooOX#X       ",
+"        XX#%@XooooooOX#X        ",
+"          XX#%@XoooOX#X         ",
+"            XX#%@XOX#X          ",
+"              XX#+X#X           ",
+"                XXXX            ",
+"                                ",
+"                                ",
+"                                "};
diff --git a/user/wxFile/listview.xpm b/user/wxFile/listview.xpm
new file mode 100644
index 0000000000..9979a4887b
--- /dev/null
+++ b/user/wxFile/listview.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static char * listview_xpm[] = {
+"22 22 3 1",
+" 	c None",
+".	c #000000000000",
+"X	c #FFFFFFFFFFFF",
+"                      ",
+"                      ",
+"                      ",
+"                      ",
+"                      ",
+"  .................   ",
+"  .XXXXXXXXXXXXXXX.   ",
+"  .XX.....XXX....X.   ",
+"  .XXXXXXXXXXXXXXX.   ",
+"  .XX...XXXXX..XXX.   ",
+"  .XXXXXXXXXXXXXXX.   ",
+"  .XX..XXXXXX...XX.   ",
+"  .XXXXXXXXXXXXXXX.   ",
+"  .XX.....XXX...XX.   ",
+"  .XXXXXXXXXXXXXXX.   ",
+"  .XX...XXXXXXXXXX.   ",
+"  .XXXXXXXXXXXXXXX.   ",
+"  .................   ",
+"                      ",
+"                      ",
+"                      ",
+"                      "};
+
+
diff --git a/user/wxFile/prev.xpm b/user/wxFile/prev.xpm
new file mode 100644
index 0000000000..be5ebfefe4
--- /dev/null
+++ b/user/wxFile/prev.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * prev_xpm[] = {
+"22 22 4 1",
+" 	c None",
+".	c #000000000000",
+"X	c #861782078617",
+"o	c #FFFFFFFFFFFF",
+"                      ",
+"                      ",
+"                      ",
+"                      ",
+"                      ",
+"   .......            ",
+"   .......            ",
+"             ......X  ",
+"   ........  .ooooo.  ",
+"             .o  o.   ",
+"   .....     .o   o.  ",
+"             .o    o. ",
+"   ........  . .   .  ",
+"   ........  .. . .   ",
+"                 .    ",
+"   ....               ",
+"                      ",
+"   ......             ",
+"                      ",
+"                      ",
+"                      ",
+"                      "};
diff --git a/user/wxFile/reportview.xpm b/user/wxFile/reportview.xpm
new file mode 100644
index 0000000000..61041214b3
--- /dev/null
+++ b/user/wxFile/reportview.xpm
@@ -0,0 +1,31 @@
+/* XPM */
+static char * reportview_xpm[] = {
+"22 22 3 1",
+" 	c None",
+".	c #000000000000",
+"X	c #FFFFFFFFFFFF",
+"                      ",
+"                      ",
+"                      ",
+"                      ",
+"                      ",
+"  .................   ",
+"  .XXXXXXXXXXXXXXX.   ",
+"  .................   ",
+"  .XXXXXXXXXXXXXXX.   ",
+"  .XX..XXXX.XX..XX.   ",
+"  .XXXXXXXXXXXXXXX.   ",
+"  .XX...XXX.XX..XX.   ",
+"  .XXXXXXXXXXXXXXX.   ",
+"  .XX...XXX.XX..XX.   ",
+"  .XXXXXXXXXXXXXXX.   ",
+"  .XX...XXX.XX..XX.   ",
+"  .XXXXXXXXXXXXXXX.   ",
+"  .................   ",
+"                      ",
+"                      ",
+"                      ",
+"                      "};
+
+
+
diff --git a/user/wxFile/save.xpm b/user/wxFile/save.xpm
new file mode 100644
index 0000000000..03468176c4
--- /dev/null
+++ b/user/wxFile/save.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static char * save_xpm[] = {
+"22 22 5 1",
+" 	c None",
+".	c #000000000000",
+"X	c #FFFFFFFFFFFF",
+"o	c #CB2BCB2BCB2B",
+"O	c #82077DF77DF7",
+"                      ",
+"                      ",
+"                      ",
+"                      ",
+"    ..............    ",
+"    . XXXXXXXXXo .O   ",
+"    . X.....XXXo .O   ",
+"    . XXXXXXXXXo .O   ",
+"    . X...XXXXXo .O   ",
+"    . XXXXXXXXXo .O   ",
+"    . XXXXXXXXXo .O   ",
+"    . oooooooooo .O   ",
+"    . OOOOOOOOOO .O   ",
+"    . OOOOOOOOOO .O   ",
+"    . OO     OOo .O   ",
+"    . OO  OO OOo .O   ",
+"    . OO  OO OOo .O   ",
+"    . OO     OOo .O   ",
+"    ..............O   ",
+"     OOOOOOOOOOOOOO   ",
+"                      ",
+"                      "};
diff --git a/user/wxFile/search.xpm b/user/wxFile/search.xpm
new file mode 100644
index 0000000000..6c57093086
--- /dev/null
+++ b/user/wxFile/search.xpm
@@ -0,0 +1,32 @@
+/* XPM */
+static char * search_xpm[] = {
+"22 22 4 1",
+" 	c None",
+".	c #000000000000",
+"X	c #FFFFFFFFFFFF",
+"o	c #CB2BCB2BCB2B",
+"                      ",
+"                      ",
+"                      ",
+"    o.......o         ",
+"  o..o     o..        ",
+"  o.        o .o      ",
+"  .o          ..      ",
+"  .o          o.o     ",
+"  o.o          ..     ",
+"   .o          ..     ",
+"   o.o        o..     ",
+"    o.o     o...      ",
+"      ........oo      ",
+"          ....oo      ",
+"            ...oo     ",
+"             ...oo    ",
+"              ...oo   ",
+"               ...oo  ",
+"                ...oo ",
+"                  oo  ",
+"                      ",
+"                      "};
+
+
+
diff --git a/user/wxFile/singleview.xpm b/user/wxFile/singleview.xpm
new file mode 100644
index 0000000000..6f6b8c7207
--- /dev/null
+++ b/user/wxFile/singleview.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static char * singleview_xpm[] = {
+"22 22 3 1",
+" 	c None",
+".	c #000000000000",
+"X	c #FFFFFFFFFFFF",
+"                      ",
+"                      ",
+"                      ",
+"                      ",
+"                      ",
+"  .................   ",
+"  .XXXXXXXXXXXXXXX.   ",
+"  .XX.....XXX....X.   ",
+"  .XXXXXXXXXXXXXXX.   ",
+"  .XX...XXXXX..XXX.   ",
+"  .XXXXXXXXXXXXXXX.   ",
+"  .XX..XXXXXX...XX.   ",
+"  .XXXXXXXXXXXXXXX.   ",
+"  .XX.....XXX...XX.   ",
+"  .XXXXXXXXXXXXXXX.   ",
+"  .XX...XXXXXXXXXX.   ",
+"  .XXXXXXXXXXXXXXX.   ",
+"  .................   ",
+"                      ",
+"                      ",
+"                      ",
+"                      "};
+
+
diff --git a/user/wxFile/trash.xpm b/user/wxFile/trash.xpm
new file mode 100644
index 0000000000..7bc5eb4b94
--- /dev/null
+++ b/user/wxFile/trash.xpm
@@ -0,0 +1,44 @@
+/* XPM */
+static char * trash_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"32 32 6 1",
+/* colors */
+" 	s background	c None",
+".	c black",
+"X	c white",
+"o	c grey",
+"O	c slate grey",
+"+	c dark slate grey",
+/* pixels */
+"             ......             ",
+"            .      .            ",
+"      ....................      ",
+"     .XXXXXXXXXXooooooOOOO.     ",
+"     .ooooOoOOO+O+++.+.....     ",
+"      .XXXXoXoOOOO+++++++.      ",
+"      .XXXXXXooooOO++++++.      ",
+"      .XXXoXooOoOO+O++..+.      ",
+"      .XXoXXXOOoo++O++.++.      ",
+"      .XXoXXoOooo+++O+..+.      ",
+"      .XXoXXXOOoo++O++.++.      ",
+"      .XXoXXoOooo+++O+..+.      ",
+"      .XXoXXXOOoo++O++.++.      ",
+"      .XXoXXoOooo+++O+..+.      ",
+"      .XXoXXXOOoo++OO+.++.      ",
+"      .XXoXXoOooo+++O+..+.      ",
+"      .XXoXXXOOoo++OO+.++.      ",
+"      .XXoXXoOooo+++O+..+.      ",
+"      .XXoXXXOOoo++OO+.++.      ",
+"      .XXoXXoOooo+++O+..+.      ",
+"      .XXoXXXOOoo++OO+.++.      ",
+"      .XXoXXoOooo+++O+..+.      ",
+"      .XXoXXXOOoo++OO+.++.      ",
+"      .XXoXXoOooo+++O+..+.      ",
+"      .XXoXXXOOoo++OO+.++.      ",
+"      .XXoXXoOooo+++O+..+.      ",
+"      .XXoXXXOOoo++OO+.++.      ",
+"      .XXoXXoOooO+++++..+.      ",
+"      .XXXoXXoOooO+OOO.++.      ",
+"      .XXXXXXoooOoOOOOO++.      ",
+"      .XXXXXooooooOOOOO++.      ",
+"      ....................      "};
diff --git a/user/wxFile/treeview.xpm b/user/wxFile/treeview.xpm
new file mode 100644
index 0000000000..4acf88e3df
--- /dev/null
+++ b/user/wxFile/treeview.xpm
@@ -0,0 +1,31 @@
+/* XPM */
+static char * treeview_xpm[] = {
+"22 22 3 1",
+" 	c None",
+".	c #000000000000",
+"X	c #FFFFFFFFFFFF",
+"                      ",
+"                      ",
+"                      ",
+"                      ",
+"                      ",
+"  .................   ",
+"  .XXXXXXXXXXXXXXX.   ",
+"  .XX.......XXXXXX.   ",
+"  .XXXX.XXXXXXXXXX.   ",
+"  .XXXX.....XXXXXX.   ",
+"  .XXXX.XXXXXXXXXX.   ",
+"  .XXXX.......XXXX.   ",
+"  .XXXX.XXX.XXXXXX.   ",
+"  .XXXX.XXX.....XX.   ",
+"  .XXXX.XXXXXXXXXX.   ",
+"  .XXXX.....XXXXXX.   ",
+"  .XXXXXXXXXXXXXXX.   ",
+"  .................   ",
+"                      ",
+"                      ",
+"                      ",
+"                      "};
+
+
+
diff --git a/user/wxFile/txt.xpm b/user/wxFile/txt.xpm
new file mode 100644
index 0000000000..a313814bb6
--- /dev/null
+++ b/user/wxFile/txt.xpm
@@ -0,0 +1,53 @@
+/* XPM */
+static char * txt_xpm[] = {
+"32 32 18 1",
+" 	c None",
+".	c #D75CA69979E7",
+"X	c #BEFBBEFBBEFB",
+"o	c #208120812081",
+"O	c #F7DE28A22081",
+"+	c #AEBAAEBAAEBA",
+"@	c #FFFFD75C0000",
+"#	c #8E38596530C2",
+"$	c #FFFFFFFFFFFF",
+"%	c #B6DA79E74924",
+"&	c #9E799E79A699",
+"*	c #514451445144",
+"=	c #492479E769A6",
+"-	c #410341034103",
+";	c #000000000000",
+":	c #596559655965",
+">	c #8E3886178617",
+",	c #410341038E38",
+"                                ",
+"                      .X        ",
+"                     Xoo.       ",
+"                     O.Xo       ",
+"             ++    +X@O#o       ",
+"            +$$++ +$$%%#o       ",
+"           +$$$$$+$$$@%#o&      ",
+"          +$$$$$+$$$$O%#o$&&    ",
+"         +$$$$$+$$$$$@##o$$$&+  ",
+"        +$$**$+$$$$$$%O#o$$$$$& ",
+"       +$$$$$+$$**$$+@%#o$$$$$$=",
+"      +$$**$+$$$$$*&$O%-o$$$$$-+",
+"     +$$$$$+$$**$$+$$@%o;+$$$*+;",
+"    +$$**$+$$$$$*+$$$O##o$+$*+;+",
+"   +$$$$$+$$**$$+$$$$@#oo$$++;+ ",
+"  +$$**$+$$$$$*+$$$$$%%#;$$$$++ ",
+" +$$$$$+$$**$$+$$*-$$%#oo$$$$$$*",
+"+$$$$$+$$$$$*+$$$$$*-O##;$$$$$-+",
+"*:X$$+oo+$$$+$$**$$$$%%;o$$$$*+;",
+"+;-:X$$+oo:&$$$$$**$$ooo;$$$*+;+",
+"  +;*:X$$*+$$**$$$$*-X%o$$$*+;+ ",
+"    +;**++$$$$$**$$$$.#o$$*+;+  ",
+"      +*+$$=:$$$$*-$$$##$>Xo+   ",
+"       +$$$$$:*$$$$-*$;X-+-+    ",
+"      *+$$$$$$$:*$$$$$;,+;&     ",
+"      +*:+$$$$$$$*:$$$=+;+      ",
+"       +;o:+$$$$$$$$$*+;+       ",
+"         +;o:+$$$$$$*+;+        ",
+"           +;o:+$$$*+;+         ",
+"             +;o:+*+;+          ",
+"               +;-+;+           ",
+"                 +;+            "};
diff --git a/user/wxFile/wxFile.cpp b/user/wxFile/wxFile.cpp
new file mode 100644
index 0000000000..33d19f26d3
--- /dev/null
+++ b/user/wxFile/wxFile.cpp
@@ -0,0 +1,393 @@
+/*
+ * Program: wxFile
+ * 
+ * Author: Robert Roebling
+ *
+ * Copyright: (C) 1997, GNU (Robert Roebling)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef __GNUG__
+#pragma implementation "wxFile.h"
+#endif
+
+#include "wxFile.h"
+#include "wx/dnd.h"
+
+#include "delete.xpm"
+#include "home.xpm"
+#include "prev.xpm"
+#include "fileopen.xpm"
+#include "exit.xpm"
+#include "listview.xpm"
+#include "iconview.xpm"
+#include "reportview.xpm"
+#include "treeview.xpm"
+#include "commanderview.xpm"
+#include "singleview.xpm"
+#include "save.xpm"
+#include "search.xpm"
+#include "help.xpm"
+
+//-----------------------------------------------------------------------------
+// main program
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_APP(MyApp)
+
+//-----------------------------------------------------------------------------
+// MyFrame
+//-----------------------------------------------------------------------------
+
+const  ID_FILECTRL   = 1000;
+const  ID_DIRCTRL    = 1001;
+const  ID_TOOLBAR    = 1002;
+
+const  ID_QUIT       = 100;
+const  ID_ABOUT      = 101;
+
+const  ID_LIST       = 200;
+const  ID_REPORT     = 201;
+const  ID_ICON       = 202;
+
+const  ID_SINGLE     = 203;
+const  ID_TREE       = 204;
+const  ID_COMMANDER  = 205;
+
+const  ID_HOME       = 400;
+const  ID_PARENT     = 401;
+const  ID_MOUNT      = 402;
+const  ID_SEARCH     = 403;
+
+const  ID_DELETE     = 501;
+const  ID_MD         = 502;
+
+
+IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame )
+
+BEGIN_EVENT_TABLE(MyFrame,wxFrame)
+  EVT_SIZE    (MyFrame::OnSize)
+  EVT_MENU    (ID_ABOUT,       MyFrame::OnAbout)
+  EVT_TOOL    (ID_ABOUT,       MyFrame::OnAbout)
+  EVT_MENU    (ID_QUIT,        MyFrame::OnCommand)
+  EVT_TOOL    (ID_QUIT,        MyFrame::OnCommand)
+  EVT_MENU    (ID_HOME,        MyFrame::OnCommand)
+  EVT_TOOL    (ID_HOME,        MyFrame::OnCommand)
+  EVT_MENU    (ID_PARENT,      MyFrame::OnCommand)
+  EVT_TOOL    (ID_PARENT,      MyFrame::OnCommand)
+  EVT_MENU    (ID_LIST,        MyFrame::OnView)
+  EVT_MENU    (ID_REPORT,      MyFrame::OnView)
+  EVT_MENU    (ID_ICON,        MyFrame::OnView)
+  EVT_TOOL    (ID_LIST,        MyFrame::OnView)
+  EVT_TOOL    (ID_REPORT,      MyFrame::OnView)
+  EVT_TOOL    (ID_ICON,        MyFrame::OnView)
+  EVT_TOOL    (ID_TREE,        MyFrame::OnView)
+  EVT_TOOL    (ID_SINGLE,      MyFrame::OnView)
+  EVT_TOOL    (ID_COMMANDER,   MyFrame::OnView)
+  EVT_LIST_KEY_DOWN        (ID_FILECTRL,  MyFrame::OnListKeyDown)
+  EVT_LIST_DELETE_ITEM     (ID_FILECTRL,  MyFrame::OnListDeleteItem)
+  EVT_LIST_END_LABEL_EDIT  (ID_FILECTRL,  MyFrame::OnListEndLabelEdit)
+  EVT_LIST_BEGIN_DRAG      (ID_FILECTRL,  MyFrame::OnListDrag)
+  EVT_TREE_KEY_DOWN        (ID_DIRCTRL,   MyFrame::OnTreeKeyDown)
+  EVT_TREE_SEL_CHANGED     (ID_DIRCTRL,   MyFrame::OnTreeSelected)
+END_EVENT_TABLE()
+
+MyFrame::MyFrame(void) :
+  wxFrame( NULL, -1, "wxFile", wxPoint(20,20), wxSize(470,360) )
+{
+  wxMenu *file_menu = new wxMenu( "Menu 1" );
+  file_menu->Append( ID_ABOUT, "About..");
+  file_menu->Append( ID_QUIT, "Exit");
+  
+  wxMenu *view_menu = new wxMenu( "Menu 2" );
+  view_menu->Append( ID_LIST, "List mode");
+  view_menu->Append( ID_REPORT, "Report mode");
+  view_menu->Append( ID_ICON, "Icon mode");
+  
+  wxMenuBar *menu_bar = new wxMenuBar();
+  menu_bar->Append(file_menu, "File" );
+  menu_bar->Append(view_menu, "View" );
+  menu_bar->Show( TRUE );
+  
+  SetMenuBar( menu_bar );
+  
+  CreateStatusBar( 2 );
+  
+  SetStatusText( "Welcome", 0 );
+  SetStatusText( "wxFile v0.2 by Robert Roebling.", 1 );
+  
+  m_tb = new wxToolBarGTK( this, ID_TOOLBAR, wxPoint(2,60), wxSize(300-4,26) );
+  m_tb->SetMargins( 2, 2 );
+  
+  wxBitmap *bm;
+  m_tb->AddSeparator();
+  
+  bm = new wxBitmap( exit_xpm );
+  m_tb->AddTool( ID_QUIT, *bm, wxNullBitmap, FALSE, -1, -1, NULL, "Exit wxFile" );
+  m_tb->AddSeparator();
+  
+  bm = new wxBitmap( prev_xpm );
+  m_tb->AddTool( ID_PARENT, *bm, wxNullBitmap, FALSE, -1, -1, NULL, "Go to parent directory" );
+  bm = new wxBitmap( home_xpm );
+  m_tb->AddTool( ID_HOME, *bm, wxNullBitmap, FALSE, -1, -1, NULL, "Go to home directory" );
+  m_tb->AddSeparator();
+  
+  bm = new wxBitmap( delete_xpm );
+  m_tb->AddTool( ID_DELETE, *bm, wxNullBitmap, FALSE, -1, -1, NULL, "Delete file" );
+  m_tb->AddSeparator();
+  
+  bm = new wxBitmap( fileopen_xpm );
+  m_tb->AddTool( ID_MD, *bm, wxNullBitmap, FALSE, -1, -1, NULL, "Create directory" );
+  m_tb->AddSeparator();
+  
+  bm = new wxBitmap( listview_xpm );
+  m_tb->AddTool( ID_LIST, *bm, wxNullBitmap, FALSE, -1, -1, NULL, "List view" );
+  bm = new wxBitmap( reportview_xpm );
+  m_tb->AddTool( ID_REPORT, *bm, wxNullBitmap, FALSE, -1, -1, NULL, "Report view" );
+  bm = new wxBitmap( iconview_xpm );
+  m_tb->AddTool( ID_ICON, *bm, wxNullBitmap, FALSE, -1, -1, NULL, "Icon view" );
+  m_tb->AddSeparator();
+  
+  bm = new wxBitmap( treeview_xpm );
+  m_tb->AddTool( ID_TREE, *bm, wxNullBitmap, FALSE, -1, -1, NULL, "Tree view" );
+  bm = new wxBitmap( commanderview_xpm );
+  m_tb->AddTool( ID_COMMANDER, *bm, wxNullBitmap, FALSE, -1, -1, NULL, "Commander view" );
+  bm = new wxBitmap( singleview_xpm );
+  m_tb->AddTool( ID_SINGLE, *bm, wxNullBitmap, FALSE, -1, -1, NULL, "Single view" );
+  m_tb->AddSeparator();
+  
+  bm = new wxBitmap( search_xpm );
+  m_tb->AddTool( ID_MOUNT, *bm, wxNullBitmap, FALSE, -1, -1, NULL, "Mount devices" );
+  m_tb->AddSeparator();
+
+  bm = new wxBitmap( save_xpm );
+  m_tb->AddTool( ID_SEARCH, *bm, wxNullBitmap, FALSE, -1, -1, NULL, "Find file(s)" );
+  m_tb->AddSeparator();
+
+  bm = new wxBitmap( help_xpm );
+  m_tb->AddTool( ID_ABOUT, *bm, wxNullBitmap, FALSE, -1, -1, NULL, "About wxFile" );
+  
+  m_tb->Layout();
+  
+  m_splitter = new wxSplitterWindow( this, -1, wxPoint(0,0), wxSize(400,300), wxSP_3D );
+  
+  m_leftFile = NULL;
+  m_dir = new wxDirCtrl( m_splitter, ID_DIRCTRL, "/", wxPoint(10,45), wxSize(200,330) );
+  
+  wxString homepath( "/home" );
+  char buf[300];
+  wxGetHomeDir( buf );
+  homepath = buf;
+  m_rightFile = new wxFileCtrl( m_splitter, ID_FILECTRL, homepath, wxPoint(220,5), wxSize(200,330) );
+   
+  m_leftFile = new wxFileCtrl( m_splitter, ID_FILECTRL, homepath, wxPoint(0,5), wxSize(200,330) );
+  m_leftFile->Show( FALSE );
+  
+  m_leftFile->m_lastFocus = m_rightFile;
+    
+  int x = 0;
+  GetClientSize( &x, NULL );
+  
+  m_splitter->SplitVertically( m_dir, m_rightFile, x / 3 );
+  m_splitter->SetMinimumPaneSize( 10 );
+};
+
+void MyFrame::OnSize( wxSizeEvent &WXUNUSED(event) )
+{
+  int x = 0;
+  int y = 0;
+  GetClientSize( &x, &y );
+  
+  m_tb->SetSize( 1, 0, x-2, 30 );
+  m_splitter->SetSize( 0, 31, x, y-31 );
+};
+
+void MyFrame::OnView( wxCommandEvent &event )
+{
+  int x = 0;
+  GetClientSize( &x, NULL );
+  switch (event.GetId())
+  {
+    case ID_LIST:
+      m_rightFile->ChangeToListMode();
+      if (m_splitter->IsSplit() && (m_splitter->GetWindow1() == m_leftFile))
+        m_leftFile->ChangeToListMode();
+      break;
+    case ID_REPORT:
+      m_rightFile->ChangeToReportMode();
+      if (m_splitter->IsSplit() && (m_splitter->GetWindow1() == m_leftFile))
+        m_leftFile->ChangeToReportMode();
+      break;
+    case ID_ICON:
+      m_rightFile->ChangeToIconMode();
+      if (m_splitter->IsSplit() && (m_splitter->GetWindow1() == m_leftFile))
+        m_leftFile->ChangeToIconMode();
+      break;
+    case ID_TREE:
+      if (m_splitter->IsSplit())
+      {
+        if (m_splitter->GetWindow1() != m_dir)
+	{
+	  m_splitter->Unsplit( m_leftFile );
+          m_dir->Show(TRUE);
+          m_splitter->SplitVertically( m_dir, m_rightFile, x/3 );
+	};
+      }
+      else
+      {
+        m_dir->Show(TRUE);
+        m_splitter->SplitVertically( m_dir, m_rightFile, x/3 );
+      };
+      break;
+    case ID_SINGLE:
+      if (m_splitter->IsSplit()) m_splitter->Unsplit( m_splitter->GetWindow1() );
+      break;
+    case ID_COMMANDER:
+      if (m_splitter->IsSplit())
+      {
+        if (m_splitter->GetWindow1() != m_leftFile)
+	{
+	  m_splitter->Unsplit( m_dir );
+	  m_leftFile->ChangeToListMode();
+	  m_rightFile->ChangeToListMode();
+          m_leftFile->Show(TRUE);
+          m_splitter->SplitVertically( m_leftFile, m_rightFile, x/2 );
+	};
+      }
+      else
+      {
+	m_leftFile->ChangeToListMode();
+	m_rightFile->ChangeToListMode();
+        m_leftFile->Show(TRUE);
+        m_splitter->SplitVertically( m_leftFile, m_rightFile, x/2 );
+      };
+      break;
+    default:
+      break;
+  };
+};
+
+void MyFrame::OnCommand( wxCommandEvent &event )
+{
+  switch (event.GetId())
+  {
+    case ID_QUIT:
+      Close( TRUE );
+      break;
+    case ID_HOME:
+      m_leftFile->m_lastFocus->GoToHomeDir();
+      break;
+    case ID_PARENT:
+      m_leftFile->m_lastFocus->GoToParentDir();
+      break;
+    default:
+      break;
+  };
+};
+
+void MyFrame::OnAbout( wxCommandEvent &WXUNUSED(event) )
+{
+  wxDialog dialog( this, -1, "About wxFile", wxPoint(100,100), wxSize(540,350), wxDIALOG_MODAL );
+  
+  int w = 0;
+  int h = 0;
+  dialog.GetSize( &w, &h );
+
+  int x = 30;
+  int y = 20;
+  int step = 20;
+
+  (void)new wxStaticBox( &dialog, -1, (const char*)NULL, wxPoint(10,10), wxSize(w-20,h-80) );
+  
+  (void)new wxStaticText( &dialog, -1, "wxFile v0.1", wxPoint(240,y) );
+  y += 2*step-10;
+  
+  (void)new wxStaticText( &dialog, -1, "Written by Robert Roebling, 1998.", wxPoint(x,y) );
+  y += 2*step;
+  
+  (void)new wxStaticText( &dialog, -1, 
+    "wxFile uses wxGTK, the GTK port of the wxWindows GUI-library.", wxPoint(x,y) );
+  y += step;
+  (void)new wxStaticText( &dialog, -1, "http://www.freiburg.linux.de/~wxxt", wxPoint(x+50,y) );
+  y += step;
+  (void)new wxStaticText( &dialog, -1, "http://web.ukonline.co.uk/julian.smart/wxwin", wxPoint(x+50,y) );
+  y += 2*step;
+
+  (void)new wxStaticText( &dialog, -1, "wxFile Copyright: GPL.", wxPoint(x,y) );
+  y += 2*step;
+  (void)new wxStaticText( &dialog, -1, "For questions concerning wxGTK, you may mail to:", wxPoint(x,y) );
+  y += step;
+  (void)new wxStaticText( &dialog, -1, "roebling@ruf.uni-freiburg.de", wxPoint(x+50,y) );
+  
+  (void) new wxButton( &dialog, wxID_OK, "Return", wxPoint(w/2-40,h-50), wxSize(80,30) );
+  
+  dialog.ShowModal();
+};
+
+void MyFrame::OnListKeyDown( wxListEvent &event )
+{
+  m_rightFile->m_lastFocus->OnListKeyDown( event );
+};
+
+void MyFrame::OnListDeleteItem( wxListEvent &event )
+{
+  m_rightFile->m_lastFocus->OnListDeleteItem( event );
+};
+
+void MyFrame::OnListEndLabelEdit( wxListEvent &event )
+{
+  m_rightFile->m_lastFocus->OnListEndLabelEdit( event );
+};
+
+void MyFrame::OnListDrag( wxListEvent &event )
+{
+  printf( "OnDrag.\n" );
+  return;
+};
+    
+void MyFrame::OnTreeSelected( wxTreeEvent &event )
+{
+  wxDirInfo *info = (wxDirInfo*) event.m_item.m_data;
+  SetStatusText( info->GetPath() );
+};
+
+void MyFrame::OnTreeKeyDown( wxTreeEvent &event )
+{
+  wxDirInfo *info = (wxDirInfo*) event.m_item.m_data;
+  m_rightFile->GoToDir( info->GetPath() );
+};
+
+//-----------------------------------------------------------------------------
+// MyApp
+//-----------------------------------------------------------------------------
+
+MyApp::MyApp(void) : 
+  wxApp( )
+{
+};
+
+bool MyApp::OnInit(void)
+{
+  wxFrame *frame = new MyFrame();
+  frame->Show( TRUE );
+  
+  return TRUE;
+};
+
+
+
+
+
diff --git a/user/wxFile/wxFile.h b/user/wxFile/wxFile.h
new file mode 100644
index 0000000000..3a86a15539
--- /dev/null
+++ b/user/wxFile/wxFile.h
@@ -0,0 +1,87 @@
+/*
+ * Program: wxFile
+ * 
+ * Author: Robert Roebling
+ *
+ * Copyright: (C) 1997, GNU (Robert Roebling)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __WXFILEH__
+#define __WXFILEH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/wx.h"
+#include "wx/dcscreen.h"
+#include "wx/splitter.h"
+#include "wx/toolbar.h"
+#include "filectrl.h"
+#include "dirctrl.h"
+
+//-----------------------------------------------------------------------------
+// derived classes
+//-----------------------------------------------------------------------------
+
+class MyFrame;
+class MyApp;
+
+//-----------------------------------------------------------------------------
+// MyFrame
+//-----------------------------------------------------------------------------
+
+class MyFrame: public wxFrame
+{
+  DECLARE_DYNAMIC_CLASS(MyFrame)
+
+  public:
+  
+    MyFrame(void);
+    void OnSize( wxSizeEvent &event );
+    void OnCommand( wxCommandEvent &event );
+    void OnAbout( wxCommandEvent &event );
+    void OnView( wxCommandEvent &event );
+    void OnListKeyDown( wxListEvent &event );
+    void OnListDeleteItem( wxListEvent &event );
+    void OnListEndLabelEdit( wxListEvent &event );
+    void OnListDrag( wxListEvent &event );
+    void OnTreeSelected( wxTreeEvent &event );
+    void OnTreeKeyDown( wxTreeEvent &event );
+    
+    wxToolBarGTK       *m_tb;
+    wxSplitterWindow   *m_splitter;
+    wxFileCtrl         *m_rightFile;
+    wxFileCtrl         *m_leftFile;
+    wxDirCtrl          *m_dir;
+    
+  DECLARE_EVENT_TABLE()
+};
+
+//-----------------------------------------------------------------------------
+// MyApp
+//-----------------------------------------------------------------------------
+
+class MyApp: public wxApp
+{
+  public:
+  
+    MyApp(void);
+    virtual bool OnInit(void);
+};
+
+#endif // __WXFILEH__
diff --git a/user/wxTest/Makefile b/user/wxTest/Makefile
new file mode 100644
index 0000000000..027d82ae19
--- /dev/null
+++ b/user/wxTest/Makefile
@@ -0,0 +1 @@
+include ../../src/gtk/setup/general/makeapp
diff --git a/user/wxTest/Makefile.in b/user/wxTest/Makefile.in
new file mode 100644
index 0000000000..a962e10290
--- /dev/null
+++ b/user/wxTest/Makefile.in
@@ -0,0 +1,26 @@
+# WXXT base directory
+WXBASEDIR=@WXBASEDIR@
+
+# set the OS type for compilation
+OS=@OS@
+# compile a library only
+RULE=bin
+
+# define library name
+BIN_TARGET=wxTest
+# define library sources
+BIN_SRC=\
+wxTest.cpp
+
+#define library objects
+BIN_OBJ=\
+wxTest.o
+
+# additional things needed to link
+BIN_LINK=
+
+# additional things needed to compile
+ADD_COMPILE=
+
+# include the definitions now
+include ../../../template.mak
diff --git a/user/wxTest/folder.xpm b/user/wxTest/folder.xpm
new file mode 100644
index 0000000000..7a36fa27f1
--- /dev/null
+++ b/user/wxTest/folder.xpm
@@ -0,0 +1,48 @@
+/* XPM */
+static char * folder_xpm[] = {
+"33 33 12 1",
+" 	c None",
+".	c #D75CA69979E7",
+"X	c #208120812081",
+"o	c #FFFFFFFFFFFF",
+"O	c #B6DA79E74924",
+"+	c #596559655965",
+"@	c #410341034103",
+"#	c #514451445144",
+"$	c #000000000820",
+"%	c #8E38596530C2",
+"&	c #8E3886178617",
+"*	c #492479E769A6",
+"                                 ",
+"     ..   XXX                    ",
+"     .o.. X.XXX                  ",
+"     .ooo..OOOXXX                ",
+"     .ooooo..OOOXXX    ++        ",
+"XXX  .ooooooo..OOOXXX  @#++@     ",
+"XOX@X.ooooooooo...OOO@XX+X#+++   ",
+"X...@@$.oooooooooo...OOXXX@X@+   ",
+"O.....@XXOooooooooooo..OOOX@@X   ",
+"XO......@%X.ooooooooooo..%%OX@   ",
+".O........@XX.oooooooooo.X%XX    ",
+" %O.........@@$.oooooooo.XX%X    ",
+" %O...........@@$.oooooo.X%X#    ",
+" %O.............@@X.oooo.XX%&    ",
+" .@...............@XX.oo.@XX     ",
+"  %.................@X.o.XXX     ",
+"  OO................O%X..XX@     ",
+"  +OO.......O..OOOOOOO@..@X&     ",
+"  .%O....OOOOOOOOOOOOOX.+XX      ",
+"   XOOOOOOOOOOOOOOOOOOX+*XX      ",
+"   @OOOOO.OOOOOOOOOOOOX*+XX      ",
+"   .%OOOOOOOOOOOOOOO%OXX#XX      ",
+"    XOOOOOOOOOOO%O%O%%OX++&      ",
+"    @O%O%OO%O%%O%%%%%%%XXX       ",
+"     XXXO%%%%%%%%%%%%%%XXX       ",
+"      OXXX%%%%%%%%%%%%@XX#       ",
+"        OX@X%%%%%%%%%%%XXX       ",
+"          OXXX%%%O%%%%%XXX       ",
+"            OXXX%%%%%%%XX*       ",
+"              OX@X%%%%X%X&       ",
+"                OXXX%%%XX        ",
+"                  OXXX%%@        ",
+"                    OXXX         "};
diff --git a/user/wxTest/horse.png b/user/wxTest/horse.png
new file mode 100644
index 0000000000000000000000000000000000000000..326b7c786787f25de36e3ac26f20ae09817e1437
GIT binary patch
literal 68850
zcmXtf2Qb_J|9>bIsUun=HA;M})E=!}q(-G^rL|I9ZDNa6Ge*s}X6;e5W{c38RYXyH
z#0s@b?7jW-z5o5*x!n8Sxx6oz_q|@v=VLwJKG)R*v4H>p07&bJ8j^he{l7Pm5&)pk
zSE4m1U);2Ms;LHO{@=?1KK7aX39Z``V^8w={~y^_{E`3wH$Y2G^`-BWc7t&hZ?_+x
zecATb{I@RRc3-okP!jIL!tjSDIKj7$dKJc>LRT!=(vR={aZR5qP;Ko8P_o^IBL4Gw
z%9M7$+9<{N<M9g7bt87WZdy_8?SBDovOF9Ki?+Fwn3jFc6HM?ihW~O%`I7ML*oOgB
z${S06%<utxebN=&YBq5hp8u_>F;hdYH$P{UDh=cLiel;Cm1;vyVtd}m6HfK+<z+dm
zxHm_=BR*5s@rM@mf)BHLb1(MAUR5j&T@pj`CO5Gk>=p05;uff>PblGJz1zDI%RZM_
zTr)kS8}Oi!-RD)bXHXM{qdtJwU_wk@WB`QwE|U9b`f`cY-0kD$43|Xydph&W^#c17
z|7I^_>Dw5q5*Eei8!kox?@*LrYiIe!sn@Z*Q$J*<g$*W2GGc}wWiKD}NmWbv-<B0o
zvo~1L`e5{TV{6N)Jx9^+_6c$RFZkDUx5h?KHK1zNK6mtNz;66l)?F5xvYn$}-hbUq
zKk08>ooMEoG?^lFIl8ESe$~(wh&3qlmT9@0*yTFgr1h$~tgJEj@}i`Y{WgBWZKr?k
z`roqSSlqC#05R7j_~E}!nfg1hpPiE{##4=oxf}5pr87%2l*x@Poe<^V<2O$813_o|
z)jc;avqxm?uo6dSIMm#HwVL4%`@LsjUk~?c2Dlyt8tt3VK5FhAP5Fn@sQAQcZT)4-
zI{?`0EJElMvR=*$eqJ-V+x+I2+_jkUm6+BCalAO5UZr>0L-OMjSWz-Kbj_=wW@P&q
z`PhPk`mWHg-`}2pb-WvqU09`jIr&W4+N6Kg^B3gtl&<R*0D%5`E4rt8DT`GdE$v|{
z1A2wE>UW-yN)T&k)2*|OMgT4Jzx4Lz`Uh=%*ZNBn?b%{hA!`l%RV;YddStEEfz2sY
zqPR3;*#i{n>Eo|&$U#vrEHjP*_?gXu&J?(Ub`H6D3y08EGAeNr{k0$RDm%QYg>Ugk
zENiDxzp5C|^6dB0ujx+VsKr!Iy*4gN?jht6{BzQ3YU-=nx$hk$tnR~tt}l<3&o`t1
zDycSE`^64eFdhP>!ixgfpdCMw|0Iv?Wmh$O`X8+<Et%=3RFV?6SIXaK3a=JWer^*p
zYm!w`S|<NYyadV#Rzzw5a655hS$Kd@91FtoV?|D@@7dmRnVIWvqoQ~<AhHW?ALjtJ
z)&}M$Qvy_g6aa{IQ8E$^>r6-9mM&P~Nz3Bk;(FF)^AB^ANP`G1Ev?oOm4itRIc!7w
ze+)BY!PaqL4|@OwH2@G27YcwN+(&@L&h4eGm#x9_^8T_p{VXFJ8;36?*&>L7&KL~`
z$Tl|~f`vdSg`uO4BfgK|KrozJ8lQe>o6kh(S@Fhkq}A-s811f!1xLPT`QVrHYRr$R
zKKQWAe7?QCebP%E7V)I%{9=BDHC%IhV}PICi37k4#aav;a#rAQ;M?goBlDj}9E%b(
zd#fu;<$+=7M&;bT-Pu_)W0p$Nf#y{J7v}~S-QM2Ov+ILrX2E{+jI}JUZcxC<|6Mr$
zbN7TMSIcK=^D3G0Z(ytO&xYn%>@K@*vZEj#WXnD-fQIJT)o$zMV(ukFuz!&E?yTm(
zY)kWdx|iN>fx{sA%EAXnO6h85deWW6LkKpC7~!Wp_5E@SSuYH)w~ikrpk~K5r`yBN
zvk$lv{Br~MBEBWx<aId*=5GhCzS6i+7Ef`2uH%?96-)E9nD1_W48uKcp3am&<4}oQ
z%2^475%oG__o#*Iv&7s=7V41K+j;B}K_AEFPF4uYrw6Mn5N)?c;*EFLLkvO6Z!a>-
zNIU~ZrkwXU@6)<NBCqEMW`#=EuDUI@^DZxyFMc!p+&@l8=~Lt?{!*_nbM1P4P_v1p
z_*_)}<wk1RWafyJy^B7}rCB|ZWMZ!Sb=6Oy%Y6pHLFldqsrll1ibvGhy67L|vz8m|
zk2U0XM1UzRIE7z1e2&<;%p2j74x0<u`B#%0eD!ZgNgH^&#nrTWUI})VUAN1;A7eGJ
zParWre-2{T(8CPQXHi%r@#^rDOgr#74C;;)hz2yz9v(hW{ZuMR2MydS*gi$q6O2Xd
z7<6?56VV2-x)=*ylZurJ={V$4gVFSq`;)0X6RsnFm#(%4P7TC5Fw)~=t;tF5^-6H2
zj%%z*-L%U<;uboUrtvY<;E__(cSX|Su&!7+Z)@=O?${V}u~}VtJ|!9i`~3dS*C}*q
zk2kTvs4%u>%*}0-wDp|hS;@$%SWZI%VboUf5tq*$N0$^&*hbZ(^UmFFw1M_nxY}=!
zl_iJ~ZuGn5wBlIY9>u7Be2<=EeK<rGdi}2*L)d>?8vYZiPeD(A{QlJ&clVEJGm_h^
z%GX(*v-i9%DidK;`IQlPdjEhcjmH3BXYj$CQg03JoxMcgO3i~bkm}a6tF?n8N%H}M
zLX@d?p)8u&FQ>Rd0|EWG+Soqi_G4yaTL}wfT(FG8F#?V1=cb9}vbEnVx+l}t$$PQB
z@v@3FLhjPT`>MFbS0S@6b$sg3zmM%Lcv2Y>-(?LO>>GP2v~#q<VcpP*VYp7b-sc)O
zmd)+9vJSNS*Px)TN6^vvmL2bj?H*a>N;~wIenKjKo78XRXIBA#hkx7J=o#pF&H~R%
z`9iuGyjeJBKH&Ew6(OHF$^WW6raV1fppyMh>Y}ia(U{k5WwF%oA#PntxK`O1kL>HF
zcede{f8>%H^5}VTuNNvJY*KAh!4@~lC1N{&c@sOWY%3n%lWkxrn7|p=<AUymy6Nqw
z*@k?sIC;2Rg&ZD2A(LP&`NNNzI}Gf|Z$em(gB6wI)ZYte6(mO&8kCJq5x21pY8S*(
zwQO|Bmny*`dJuZtP%q2&u5~<jwIf?a?RYY>;_zXjk<**GIp>Fv_RP#_Vz_T}4>KTS
z=hIl|??{OcNcwXH_XQzZSyvN6SA{`IDH~#@x*S)hKk3FVQGmGX^Z<`VmXzLoZgFk4
zx`G}?Z$h!A8I=z)$yOG6e+4Q&NoCH>8%#;!A=Vki6aZ<RaB%gwV+E}bIC30SB;w>K
z_DOGQ-CF?(8rUzVmmR^>FN&GBqAJn3t-drgssMnSX}ut*%RNql+-(41^jNTJv^Y;P
zrOFi1$92@UeBQ*&lvs-zBA(#A-#=_hxtXaGStvM+dgUay3e0yIrUn>24#9z;79t%n
z+zlpT30!f-N$OK<v$KD;lx4M1?)s8crqJY7z6ozrYj!>nyb+LsA_Dx_9w!Ne!iDp}
zdaSo6HjjK5auj{9{*L4ZH^|7BlFrum`XPW27lsCuf-F!GNc)w^dc$8Z;W6wk9tZ`!
zr~b)Jl{^Gt?Eew5zP=u7aJ%334whHNB1wcM{2uqxVVbLZBT;pb`ng}|Y4&!@@jPL>
zitrT1QN&wh1ay#wGr@szH)F>n=`8CBmFuM`b#KJ9KXe>ZidcSRmDRe9a0d@x@07H@
zxgN?>rdwbtsW`HIfrO`Ef%DuTXe|H`vld&D*jvm3U-ILl&d^>#gr()SqDv&Ud>UJ}
zgN~0M4L>nAi)SBtJ}{{~J2|OzwbyqybZeh=V2gi|bzm-2yM$>`r_Oh^doi$G?Z2J^
zz|B7;Qk415O!w#%8qc$7w&`R#&z6?*!8|*6`u}9gELN9GQ1&j%>Q1e$u0j~$4rSTS
z)twgaC;<}uaF2fD4;@IynJwPtt(}Dh(O&NyLyXM+nryC);iaC3hih=4LMVVOk75w=
z82FyFFn6{R;2@ASqrKP1W|XAH=xsUx+Q9^0U$)WvUEws{GlN#^bDOW{+Y6H({mevH
zH5<*wYdEyPBC3;-P8HuI9Zq}4oTb?+Se`~9qdtURHuG-2+3kFKv0HEcoWWL|r4#CO
z(%0wv&4_W`!1!oqert^si!oRH-rS8F&(_t<TnVpge!((1b{g?b<<%1oJH_n8Dzu>c
z?(x;%!g<|khM9)@sb!sct?fT7;zPzGgTT}-UFt;DDu??(k;u|%7ffTtC+7PWQ`yPj
z+mV(p3_`c>EJR1b;w1PjFm~_o_o`KMga+2M1wO967ff*A#&M3Oc<s_JW^z07>4}@o
zaNgUpF|I?o#EpUPp2!66%U}-834O1{A;j4~p%GyC+%dHi3u)N>f|z}|SoojFcihF^
zy4R!JnqSl!atU|%ugC|<P^?{cYYP-p5b_%V%T)@njf3qYAdN<q?}{njLaLw=ywV*M
zEr$>JoHA~zTE*=yOt^DYoH{l;*H7!~|5d);SI)I<UB~&Cc~5S6Wol4HGh*Ab?`a6W
zz2Wq8xwG$pUs<8~XUEp|G3ST4ZS-vLwK@k?)m&h4oT;nh6Fr5^r)ZXa-1~*~Bl#*R
z0$<MROMQJqT<EW7-EN~42CU_Dg?WxWg6<Fg+DJh=ZpUdBQiK_3g+i>)qc%UOA0Gvf
z0-1|K)86SSBa8nXPW$CJjRan_)kNB0SUr2)zfoMDFtn!YezbQss|;x0vamZ?>Ky5`
zwPwVIH0Y+=nRtwD9eiF?RU1Z!1wI!V7ms{fCM{fgvEac$#aZMI=6`lC*hO|C?KbF3
zxHuN_m+NXL3MaR3x*D5ihnEkX>wZ`;^CY#fo;9h!0{?D*M1f8r^Fg@~<`E84?^O7Y
zl;)~gsALVh<MHj!&GzsH$2@9O8IL)}pIH4RF+q1W$5aK_NbJ8n?;2HQWo7j?ea<nf
z;1{@kLaxHCM&(;u{HV~yr2m{k$5C40*C&bBvK!Gp!&5|s$w|2{h_~*8y8e^$RYLN2
zr;F)u_N#YiCzaf1J`wJ=ya_0!a&$bLv=b{s7~mlB_qY);ifK)$AL>6CIWE#vRF|XC
zXbpuoMWp@x7jR(MOVBHWyI((jv1z<Buv#N*ZVXT)C@U!a*CD6e+A(*1bsT)SygH)b
z<q56q&y@Txq^tAh17?`#gaarO5qP?X+itAs-t0X6s3!>w+dZ6Mvu9j^zfw&jRe$Lf
z-;sE?xVvdFC`LlL6Tiy4V8%&&{NlhszD<Q^X4)krv=~d+-QHN9#V}YW%saE#w%h@;
z(B7`}OU}GcX#|MhJM;$u-XZ;SqQI0$Lz~GpubbIhho|Hgn6v8F-%#p-#@>zr1G$B@
zM%?tu!D9QaL93hq9lJqRgUA-culIGI46pmO)C7wMo*!-YZTeNsp(?tjq^m2HT<f!s
zh7FEaRvc@Lv6iyg@wjoUM5@jT>#1bIVy6{jWInErM-A~2ucgO?Pj9HqEOyA?2ZpVA
z@n8o*luyMYy@?&}w<9D}0>wAJ-@D4*4tgn#W8H8Yrz<$J$H+`Gkq*x`4w{tziLjDN
ztt=rw(Dl=svnF#o{7JItLz?Cdul!_C*w1`$@cHyy(CMj|1l-$rFLF21;R`q<%)N*S
z`dU7_(m)7`1s7C0#cAm!W5GpCVWajWzkB%K$Jv+RrqJ~OhT|~7y*I7GX@vSTa3sMH
z(>$BA_^#6fHD=RDw2ha(c_TKKXIgopjSAvI6FzTWo3z^5-!D3!CBtW3Iw1*%c64`l
zml;+q$mZy-5YhFOMybrN+yQXN38Nhn7z&=+D?Kc=cYMU5D1W|}5owholJG3D19K@0
z*`$l{U=&d0IDg>ugnCPPB6lDyO0%n1eMJ`goGDVZe)<bS_3KkX(U=~0#f$kUuB)@y
zG=xJ@Ee-(qZX}#CoOKH>XdPJ74gLjC0dT{OoL;0df2A@4=BWc811qSFf53$FT$cQQ
ztR21rT8IC$HLZK~81cBDy+37}Ps5L?giOEh(%l?cdkM4_$r&){U3Qe1Gs=Tn!96Z!
z1Gby}4-r6BU>ih=3@8vVGD4Ca*cW+>1*5CH`?$Hs0Zt-R09Cq>2l)GMlO?lcAdN}8
zR<)jP3U@K`m)u^QG_C%J!~0FemPqo=+v?+Rgi^)Jb~fOlBkre~e%}WqcacV%1gvO0
z!?R`5S#e+*IW9sPL%CMr(>F^k=_r1J;ZAwU1_+_=@8M4iQ;>*)hFTkqt7S4;IoKf@
z47Vue&dmP#1aO}adg%X1B>8s2Ekn|pm7JNYEk3$wqIUSZ@KZhtYY_B|xm*MYBd_*p
z<M&7deVd9D<gW_xgE0Vtwy1m@<;KTXKTZZsW$CZs;!vv94;I^+!RLz&wU8n>7}TD7
zxxd<cbmc#*W;xAPYqIncIk)+W)8_+CixgecR{zeD(?D>qBZG3_3Ay1`P|p~V0Uyir
zg~wF1q1flv0I0MU3jPEjjRnA+MO1(Qd%!3d1z^rkf2t}zHqHa5sJ3ZKt3PzR{v;j$
zQrMA3-Au&JuYOwYjVFpZPCkL@?BwK$Ly+6|7pd%TA%~ZfJY3HRCnqPq4>KP}Gkya4
z1OF>3S_~8SFdYcGIAjgpYv0aozNF-dcpnayU_;V8wl9Bxhjh6Yy@R}n4Uu4h@?r;3
zY}TJxFpG_Yn&mLGSe5+dLw+~hM~wfFv&811zdJ{6PEIAEOj>78al5#kIN!E5?FnOk
zBr9uFVE}A^=wU^Q2KVPNLFbp3?ftFi#A8O02$YY1fAB?(^1Z~atfvF}w4ngUFj_1C
z01Pc;&a3QA=VrPAD32J2Ye(BpoUA0M><pcANo%`7<MfdC)9?gC>$zA`gO9zNkAG;M
zR3=lVx6jqeuM(#1jg2M0gm0Zx*!OodzK`6>RZ@Ofccd5<TU>6y6?D*_Su?OroV&!!
zm|q-iUyPriD{&NqsK?+>_;lF>#!z6sZevOEbHrmH#V?3O+L=3(P@(J#^-e0ok+nZ;
znjlY%jOXXv)fDi!`>#M#yUaiPf>eOx^EcM&f1?sgFh_;Q%0U-xGP#z7PTuD1IKt#Q
zan)Sm$F<QbthhQh%iI+2AfWxr+ko;3m?}B!6Z3eSLj?wdNs$f{DhwTZ!p>M9wrqPh
zGM_01K9fvGQSiMyMsg>R%DJWAx1F`-F6A(E>C9?It8r&-qy#Uh{g<pD_BCZ;&a=Z(
zG{QR-r-{?XA}dID>$v1<;itg-mmwA)z=FyBO1@P{!H|9J#8TotrL#`4APOk&1O>o?
zlC$e=!M~;1&yK08PtL*<hMj*H-OA@u4)O{L3c9{}3oa0p!cW*se{X3a66J0ew7GLA
z`_}Fg=g#?m;Zb)4zHw<(7zl~&9nS_^IqzPaz5w)fnP2}UOPUJcFG=SL0>>DWxr@fR
zs|ojt2gCVWCureh6VcW24DOv|7RU`?C=PGr{>F1?vnX4a9Ud;xSN*F{mm{+G^x~hz
z^}!(tonZw?+|Jb&C~KT{Xv|*V20l7Du`DYr>bE7WwGHj8uYmY_Zqfbh9Kmdhr6$$h
z$<A(V%FOEeQe!f^5too*`^L|2Dn`(HGM06~WX=Gm_Rg)p-iitf2H1xJB9#J;zOO6?
zKAILbq<Yb&u0K}O?S-+!)J$4vv&43W(=a@n3#1jncNkY0PPk`v4J3Xn75Bc`-ZFl_
z_u=vO9Ess(m01pmo{HdSFxz-M=-FP%q;BS9d@Mh-sHrLHl144m<7|g{w`>BO_oIjY
zcFz{1S0YH2uGJQ<4&)L|%rL0#*;(`pnes1FmzAS2TF_*KLiVhM@0$QaG#jkLeq#PX
z7chVBye;<AvP?PrH)Wn_nu%$)=6eQV*@?NdFq%;FrMqpvk7u}ndHFx{2vwq`rRbvW
zt=U2EwfW|uLIKU75c%egeYg6w*QX1+g*2#|22r15e+LBzqp{7psKR-V<~_yM>CH&X
z?`Bmv1Gt-+r!_Ow=zc^6ZtisUj+0C49LAL3&Vg{qD9$YR-P@UW4vd0EQ*u$<su)6Y
zTeJ_>u$;8Gh9W-vJ6q@1c_E-ON-<t)z~*~zxuAf&6}=WGKyZT5B8{}p9iWT8-PF3Y
z&YL;wa?uz?ARHe3bcRR_9sc8KdQz`^ty~ib^L_KiyX)iZoWcj>!}1y8objJ@G7Q_9
zZQRzz%Ve9KbPFiY&H4GeKhlpm4PBH?;Cfzk;x?LXM?%{{)b*J7Fc_H}*84><F+vXd
z|Cug0wZBdLmAWeD;~|q@dFO-{?p4$8@YlWgOSoYfGc;Nr=!XtGT4}gXB4c$yM0NS+
z()$U+r?0aOJH6yD{}m>pUAr!?zE=8vP)jp(&9u7XKibLr_DzgdOHZ{<Ql0<euJ5<3
zcmcw*SwE`014RT-JT-ufk91Ab;NuBS@e-DUl?a^K>PUB%=awHuNF@00={xz~sJFp8
zc3f2kcQpp{DX5G<3LIPNdJQHOfI6a2CUU{T-+j04w-e&aUwKdy?^~d16Pmvs1I|BI
zK67h9Q3BG+{7OcQtJ0#PXsTK+Oa#Z*4&tOWghbcTt=TD_A|R@cThY{0lyV&2m?IjN
zCkDy+&#0YDVs?Wsa)Wx^IfT65bz})aQ&#l|6lQ+`ptH-_HB!Agf9ie~l8sONpuMly
zU9kE3@6y5<j{PPkNxjcenGWWjiFi#y0v{P`n+`bPP{yf*INJW^pGr-wH{Rn00aVxz
z$Vow37Sh`3a;Er!l5+H`it^vDHtFHm<0!r1n6RJ!-J`u7^Jen5PV!%FuUO~9jcfr?
z?+oo5MV!K6-2Ru#a?t+M)6Bv}Vl`?jXCq%6Wv6Z?ndi1qQf6Z*-Ce!0x91_wwzaW&
z<`5ltK@xi;KyOn(X+(&}MuVUlg+udg5=CbE1eyB!Y;--EjS5Qjd~?g2R2(w+!~yIf
z=nYl*2^Sr^p9y>6HqxZjd{bU2z_Wz;bh0(@Xk(rr+V4uAxCJ`D5ku?#Z?^y4_hg~@
zAF3RDmdRN&0Y4$HTy05*)xxEPh5wBU0@s`y9<s?NunKTixO0?%p939Q=LDFb&btg(
z=d4NH*%nRZnX+qfk>@gmk<-@_nYLk>O-7G_rnjF`5ZE7P8>n<;dYh(sPdOe&y@}oM
zYRT7~U_TJ;uZ$Z)_Q)oDep=o1m4&S^oZF4V!}t3(O(m(p#+ZTTJp78D%B#j$-Ca6Y
z1fy|o2?4f^lTyGO!K46z#>RlbpTdh^dG9a$i|Pt%k5vfjF4EPhsUN>Qz0bDMxY_->
z*~}Gq5GR>_`_{Zy-3I8Uj>zKgC;(ew*x;*5nRA+e<lzP@#M`dKIpc~I<CY&kenfy#
zPtTe!gIZnV{LYVFIxWgR;{Sd8xUgafaDA2A#2%r?bfVeC@Ew59JCq-Rvp<fb%^3b8
zU=>6Fu3&=%T*%y3Fs4V)XxXN5`tCEksdoiT;g-Svm?-X-2&=HqBvF>KWe?6SJqR_J
z?aPGKH~ac&?@p@v`uaQlazzuAE^)BljQvQ7@ok0%;=QS9B@ONk?_;W{Mg<!6ehemo
z=JE~SrdJj#wRe_k^2QeDBj;n9_?PWNpTEf7DJWlVy;w@~wvhnkC<g~i%zbibm~;lJ
zCoBTdx(Qqc`ZyEO@IgN^yCNNCAg4yFEmPj<l#GzkiW^6@nF}}8onytg?W61)&!gUF
z!RpCWKR*O62OV`9_o?Z}G<><aSxKtnnhiiQdFQMeVphS%oe$uGI+TErp;3sFc(JTj
z!TgeFnG>1#ibJ@aQ+xReuF}j~?tzZC@vI|j$>8BlpBmvgqTIjHx7)Z6-viv;ALb@9
z*1>_QovCklwJ4z-$2s?G*uQ4oGFX(ohbIfsvoaZ|r!27?6z6LKxf|PCB5C^#!eA=Y
zdZeMg0mSLM?ai=5tLE;W#lq}{?$W>-V=<b-{L%4aMbS)Y9XZ!9aic2Mft;3Hm-Vu;
zr(F>k3;}z4?wHE3@~PsS7`YUOUxw>7j_`z@=gqN~+wNEY&h$vN`M4Sd2Npi4<Cn3m
zm-!q^mg1P1Db;8}6gC;wA>SyxJ5hzTs1-3~Ii;4|hsXxqYAJcy=8M~RO45p_1j7o^
zVtObOb92Wvvf<Xedmy~|oiyes=Xy`s-~H%F9|Hf<gLXYe2PW~-cGs-O4qRJe#Q#*6
zS2|(AUl2vfk3Z`-d?EQXnz9(D+Qdl=>}M2Lmi9nyK&gH^I@s2H#Esv2|8Q^V#7!~R
z_;bimsAi9q)D&l`jTR@9-_@i?<ol`DKF!7kxTKCROrNGVO-!s{%l-D(y@n;>mWdLP
znuUc8<waKNdSLj&Oc4Hi>3s{4&QF!44V5X#S5O#`5~`-3LMAd$_^TRV%;NXyc+EyV
z@a-F3Q@R%+^7LMTFAc^lCNzx<y)}T6_{jWic{4DT-srkd0NGfGK!U74Cj;BxfjQI}
z-<R*eIOk@mRiCd=W1oBIy_Sm+uFG>^gFi7PkQK^#F|0jXf<z=(t52N2;!|O~xIvLa
zNy<W!rl#>X+HYKu6o%C@kQtL_8Ii_$iekdC&JQzBTe#F2p-USFpb&AFt}IVHq-fMV
z%=yJ%8is@($s{=ZmaH`d8be#g4gkQPI5m5VxbVq3RUk_%o#4^i=XfK;%>3sn90%R>
z=uplx$DGH`i?UhTVw?iP9>yucF;=jYVM@xZVi)Z5_cG(Zbm}_Nr9lA~C+<0};&{m7
zkUf^+7?asBnF`Y}eP#WD_oHq}G8mYT^QoD1Zq`7+tm&+?z`x|A@J3GHo5}Ksp2fxR
z>BcgKM}cQM-QN~Z5bM2VFS_DC{g3avXR!*2vVHM=Aywg4GSavI>+nhI+&8?@Et>Gq
zWCZXn7~hW09E-2^nZBz5)I+58^5N4xMX{et9j8UdQFq{VEXAewVMQpR=nx!>wKU|Q
z$ML_{kFpbM6a}!g3VQ7%acxEoygh*i{}6Z=p(S(|t18Wr;By?A)J<hA&#^^bpq=hB
z==!qKUqoF33Mla&Nh{jU{VTehz+P0l_&sj7;aN_^#Q$Xh(4Su7jS5A=j1Wb*`7Av|
z1vT)4$joA4_-P>MtIo(z%D<5mJSwo7Nv6ViGY%TRZwHDraImHe)<S;_zPIKT7#OG`
z*f|)#XuzaiUym85oY_43{tgU<F<UF@OviS5C?o+?VEQBCSaIxcRER_<*j<#n77ULY
zGCXIT>JE(jMk6h+II$f+tifVz#wy27f3zP5rMf%fXAq$K%n9)A_kMW_9!27@)5@Y$
zIXc!wqs3Tb-zIaEY}UQ=VDFu7IW&ln!h_*GWG$8wP)9Rn&{;dqvt(o~-UjB0lh7E2
z$4gZ7Gzq4;FDU!&hzs4vXM~3b=(M;0UMvWG2Zk3t@9iv|zT2eK7!q>7sJFV|yJ8o_
z^<k`!0Dngt5q&J<&jrOw6yppK5_l7WNUw*J?Q~4ft0<1yI=axw95XN_SpimYiUmB+
zIKJ5|>yqY8%h=S=;(tuU^i~^Hr0MJDX3g~OXDqn=Fril6crKsYM{1D78|4|0cH8DF
zSN&vTcwl^Z-&;=+r|jmOMPAbf*F8!hV8BlZKv-hR$Vo6CXa%6ax=nWrP`$cEQQadw
z^-G-Y(aGP-+>52$Ph@onkLsmPTuk2Or@K+ag#AgW4s*=t*=GzXAlCqish~@PZ+uv1
z{gKVY>Eue>I4XGAxW?z44sKtzgT5v%)QuxTlhrUXPKAMdE*VEbS2fS53BX}qbO2g5
zTNoll@w|6z<7lhL-Mt-T&FtOsYY<((y|p!XR5bmwdVC>Rs*Y0Xgz)W+iqKckgTnX7
zpQv)?nFT3?lSqZSKJ3$|fPjF_5D-l^=i7~hUNhltvRea2y-oddYE1fz27&qFbX|)d
z{{mD65{5S$0uP6#J4)(&o<Qr;YsXvPR?J}u2A-+Ns}+s={LF?ZAX;$O)s=t$RPpW2
z#YXDLw(g;%<t8=|Lp;8c{k}sZF{or@@y|hn0z{+NPwC(G9gaxV^&cX&Z`K}$)ZLrj
zeCaYUAd(z>s~2TW_mw5ko2DhKhz_hF<WQUHZAy5+J|{B0c~4EWc**X1uY2=w)RR)A
z&AH)oX^%bmSpezJn=g6SUxiOQY+qeQmFXwEj}<H;%R=m;dz<TMoln#MzTFH!Q&Ff7
zp4LA-t#T7l%a9*L*~H;)-YVl0&tcz-)OKAW)h{Za%ri*w8%*L8e`RMkcl(+#;~ib)
zXJvWm!~Px}9mS^QZf?aFlU@k`7rbQ6|L4DaVT;Sh0pWB|{t0!UQ5j<a)&ee}rgA^@
zojMR6{dfEdRG-6P9Ty3{YrzPodSQ_t!T*Z2Wt)K^vi0gB?ftWxg;!pRRXsh&oJA+L
zHE|1hgl#0kgn^TjlUDC(86(f?DnXym?E^21J@Ea5bg-t@EojJZo+jev)ILW)J7U-8
z20H%+fV&n5b;6DJxO3P@pAkH@?{E3#d?qE)M0scTmB>)F4c;;jKJ9UbvD!fV0q`QS
z1dmx{2mE!LFvPQ{<BV<e+uXoZKt?PO5N**#8SxGTM{xRjHSJ%~3~(tuy8En>;w$(z
z07x}KNjqey0}bPJ3MHNO*aI2yPY_yyVPHv^0cowU>$t`Dw9Kb$vmx}QB;ul=2ju{Q
zdU0qXBsh+ec<&_&WY@}UY?jxQ3nFILygnrZ8N*Bg@wgB2;x6ZNXGdKC!}BO&Q&y+D
zQA+&c$%n^IB5FQQrRz#6$3u_=csv-1KqBIAf-P<V7Mc0pS)|u47?hdnGqd*PDWj^S
zsA$7JmG;iNmE6yibsPiL+<dl$=Ggcv7$c4cgR$IL{<s-k8UN$X@WR4u*?iZ5*1)q3
zXc1Z4Sk1jyND_}0<im!!FbqK+M_YriU@fvQDXu!b876^;*u!v3n+Airjb&r<x(mf$
zYU|2uBEh>ed4e%x9xn)eo13x+Q?7G4E16cZ8|0b+#XeUNbmM??o?OvvqXs)fc$ohu
zvAh0g(L!!$_FZ2EUsMr8NvH2_6ZRG3zLCxlsDb^uF`6Q;OtVA7b}J@;x<dEge>*|?
z?)}VPd8e7Oge=wq>n87V+Get;GEg4x?b$ZpzZp(}1=piQy4(Tc$sf2s5rY&VK0S^t
zH8q|Xh5o$<MS?MJL^H<x4|A_Zu01?G4Ovo#Q4SQ){EjcAv#ZPVOsgbbEl5P%19ImU
z#HL#nBtJp63icM1-n}zkDl9|`O6!f-rpfd!#tHZGYoYY@>OYKIN$i@i)=#?tEz8E-
zO(6J_lh@Bwn`;8LFRYqi4*?68h2-`t7lID{?y1nSJbVz@-b)e+;fVP>?qi4HPWg)z
z$1m6mje1mous|bK&Qaaz@lv0X#w;-<Hla#mQ*VXMF{`1NSKh|#u*_;o4Tw$cSBQlo
zIbin^GA-Dan9DI6yvn_a*W>uJ@-+IetxcS+a64!l6DvuWa_jF!Fx#j*{7iq?V^ju<
z=v|(<1t)kXCMM3dC~1Ok0H7+-=|1(Q4{T-}$Mh-6Q^Ic8e@Y%VigU}tlCinx&G+7d
zE^Pc*6(A1)0PWasielKVA3h<ILCKG%=5zFs&Fz;_xtDtfJAda7m*KSc<vu>^?e_J<
zG-m0p0NK}75SB!ypueNumm8BcGOn{=_|<iw1qVX0Yd0BboJyVlN+x3b?BBo7rKRV`
z+pZ5YH+^P7+pqR`ig?FSQNF<Zp}()|z89;mBZD8B>TI*L>oKJ7C|{djGhk(Vt6i+d
zZ{7uQvZ|_Joy93yxG;^x4{tN4%c^@!3DiEXh$w){ZA`65uVkW?vQ|Mu_kKBDxC-de
z-8n5$|LiTtX7L_MR{7EP^g5Kp>@*ks&E__XlfC8DOdT_WjTKufI#_R0Wv?uKZ`iHM
z;o8UI4kg*O*}fEK<MpjMbxD)2%bBG$*scA;XFEIPiXiY?d3;os+T2)&4DDh9O;n*~
zB3JG7+9k~~%Sfk33pmalZxUsj8BZDv5D-8<wRlhR$MVc<QU@P|&pkz<g+RXsFY)y)
zWYsurwKpnpi>&h9;%*JT{<~Hab-cB${N`vd#9!R8im)GW%n+XvBUO=%jFf0GsS0jy
zs{dp?{n6BQ1vqKIrmvp>zS^C;yb&pT5YD~BiJ;X07W_Px-_$irt?4c<6$+EMYUjF0
zc<DElpBc!e=9N7l(;2v(mz$Q9*s{BHb=h7pA!u5%X(1WFj^9~7oAM5?<s=eKODet+
zHZ8(pd0w!|ChW6ogW<QN@q_Mq^=WZk^#K9@Va2WExc{*67o}_S1KSMB)PeWtZZdEw
zH^{bj@5L{Inbbo`g`bwA-rp&5Ppy!M1X74*D9&YNx0+TO-kcCKYi??3ZtHOWGU9?k
zyNa69*iQc0b%uoN%J4F|OwOk+@L<8bc;IWDDk2oSWPG|u5c^M=EwMzu9atQGB@QeY
zb1Y2$(ad>$kQ>YcdHfET|9o~S>D2bem+xUM+vhEFWZ<zVLG@DW{&$gEW=l8&?wu(c
zC`xZ#wl8)yvE{OYfst3IFD~U$RUoE7q)`*7uD2vh&(CtlEwHwPxdf<yeX0J@Rg&QS
zW==C9lK^^AO5DC9CfocyW2Q3h!`#V9xU(_OEiW)trDnW7(M$oTgm_+`l#|7Axv-kc
z7GI7_Smfl)_BDIHBs?IaVO+T6|Ng%v=dmKQsuAgkMfkc(mpbr<vK!}yERbIFM*oj(
zf0cIKk{bZvWAn!~-3AFyKk!aw*w+QQM*p;JroTZGyr}T3q50Fa4uPbfQMcak3qqVR
zDcLj_8O6$y{VazJ7v`6#e4UWTcJkTi@svehNRnpawnN3`Z+5yyV7^GJ8^^-)xNr3B
z&k>ANW+j<mvPSd*)m6bll}8}yAxcKb2}%k6^gO2ju(iV{3|C7e<2s7xmUOsO_}9|=
z98n#X95=s_<g=vaj_V$MLD!GGjN`5+#{h*T@D3RkapIv`3KTy(v{Yd3N_32Q5E=^R
zg7-0?o2GH@`YGXUd6x0&07^*YeBdKiIImU{s-pIt<&vh}#3)_sd0P%{ia`+$ERv4l
zA$XIS0c2xyi#q2&*&7Bz-Nr8{oPh2UyjXcW0HIfw0_+a^Nn^w&giEzap|CI^xPNAk
z<ON<dz<e-Kz;;=B?pj1_`R}u4vO6dUf|N1-LiYS-pzS1w2P_x-y`GW-kgZ?B!ng-P
zkuAY~L3#unse$RvZL$lZ<~$mMcCA6zcd92XJ6Y&KIzUdJ!~IoDaT?Ko?8<c6_`X%e
z^Du#+7a>+^8O8Zb0cI8zE*ZAHnKa>gBhv5L)o8PIONhFxSN}AXk-N&w>M5*G31djd
zel`6ESq|1JB}AeI&#EGj(mF2uJr{qkzS#pfE%du%edF;KaeA6l2fd9(S1t%{cokL)
zlf%N1%;V230_U`Pb-L9U)rabYY431ZZ=44ir!G#Hk;A!O+t}x&U&)-vKnS*6r{q%M
zQa^1;F7b78(jY7C?$-~+Vq%_JCP%PYJ`wbgh<tS)+)*hxOzW0)(xIC1#lsW<N_np{
z0<j*JK5X`K3Zepl#U{}AfR^=XPr3=2DdSV#ibX}pU*4t{X~CyyL5=bXjT6of6CTHf
z70$P;s%wOc$Hh?~*}^ypyR`1%+~`u<A1JZZGVZ-a@x2?{Ya;?$S>>s{haQK2+ui^}
z|Du2qU=P#QFFzzc-@lJXkon3J*xg79jd$D}5tgO~Kq%obP<ewPvIl@L?b;PD0ESo8
zF3Tn?T6FO>2X#@t@${6-nMJ+kjJl1GcbMAr;#l{sTs%darrCVF@j5Q$oso5?#}D4<
z=h_jYcsSgigS<FD4hSIKZ`Dc+ClZOxZC7nie#=jnLjgLb5&5hU`F|CGCRpJMQtK5d
z;;fNGB8wlJDimO^zyTvCrr-NWw;~*E!Oqe@d-)b6xkpQ=xGw7oat(GIa>P}%sheS@
zXze0ZBy)+hKa}(=%El-ST+28HFkiiastO7US^KB2rC!ZO>J5rZ<q`#NBqnU*hVvHw
zpvrJ<>6EXNk&s2fm?`(KGv$T68wZWO%Q0ldItK~5;Vcb?d-B8F%5g~dxP11-`L6@M
zIHNy-bDGg#HPrN&A}#fj)%Elc&`>bE-x%z#x&(qQeCLZ0HAq>MMfM2BWE2}$7)(C~
zTz8sZMEoq#TcXYva^y?dz4*NkuY6D-9(_Z3PyB)Ux4I|HV;Uc)+`nxH0OtoiTRj#i
zGAr1|xJCYXHT@Fjruy%XN$&Ore`wks{&ayr26ow?sQ;Y2+j|5xSRP;&_nT1hN5@La
zCTPiZKP>_8rk}ft`E+7zZM@Ra1S`oL`x{EiS=x5``rj)Xy#sl)xqnrXgsjtVg9Ozi
zeugwmxN{OP42k5OiKJae-q;BI*1ZS6Z!KJHpoe%fCqO0DU#(+o7?0FozXhgSjJ_2r
z?(=5gP%(sC4{`eKPM3?an|gg6Sn$U8mt_T5@EtgTgk%5N_H`Tlx^^#cRQDW}U)HO2
zI(9bEJU=L~dpiB9u;Td#kyzeYxv9q0C>6<MyUsN8oUsS((&-6?T~V4$(<5bRE!)A{
zbHUeVwn!QHWW$JSr$fLGV~C6CI<A1FYinF44qOT<jk`P7H`VMT^fsp8C)sj`q-kn4
z=B$da#1^yYjPPo~VHKI>j*cO}CIc&y2gjel;`#Ab%1;ytUFj%pZmjo+n)@KB?ndjp
z_HB4F7SVfZH72cJKdm#}?eT*t>`oC=+5P^^2H1P)Y_t0L53~-_af@F|Gv+OxIetrL
z{UA|DPN5iD5Oo89!!FSpdbMU%Z`LaesoV0o-r0OnzFa1erq`O!qs{}OlBQ4l#xlSQ
zvSi(=czWxwQ6#Kj%<5xW6(_+nE03g+!$r`h3R2{t=Uk{{b%OS|Sp9-%hSv92Uwxfp
zKQfqvyWQ!^U-i>t>a(rcd>9I}FC^Ee54>6*$mGl-uEzNWAoZ6=CCuHl%bkP4dPX|y
z8%QOSm$B{MSBUB`3CGAY$zMO?C7*3Tik5izF|H_C^>2IYSy^i-v9*Lg6&ab#V$<A@
zAjCTMCnRpe$X27}f9siLPDA1%%&NZu+_?LhAGpDhZ5HA?ZwPLKn{g~P>nr|2r#{s>
zr&;?3!{kNo*OE{FZOW)GfVgy8)79A3yt_1hi&)SD`a0672((`C1tnQ7Sp)OOAV^pQ
znZYnqn+@w0AxVn2tg6NwX`ujsx*0ieBVKFpSmo#lbGM8FkaNvU9!P<@J$wb;sGBDK
zbk)24Jwa^jx@$CG^GWI_zo6p21kPn1#g`f}J%1ea^odHu8BXC;h-l~!NXQLJD&WTK
zZdl^4sPw3LPFLTyNk*a+afHZ+d>QHWCfPyC%;=@I90zSwiRSBjo;A;|uI3~bWsOR#
z59C~x?j@$N4y5)n+W-M>0RimRSn=1}lir-P(3zPTats{)Rp)4FiC5Lb|ERp&ZZ2@&
zbPi_Mws}dktTz`))sdp1uy;x%QY>nSm)^YY3wjLf4806)WI+BY*V6GuS1ePD#X`b7
zA4UL@w77ZbIyU<(*RM|x=gDcz$-YCKCpqHlB6U<b+2&@=z8b)@{oJcQ?U?60R0LFF
z;TY-}22(98CMFj3CHT9!XMbbmQy3JxUVOV?Da%uLb-zXn)Gkg|_N4IKSd<VT@2y@L
z4fLi)FH^p-x~bvfsL+Fi7XxzU!YrnQ_`*_lhl)NvLBNiq_j~oCjsUS(pYa?@0OB6(
zj+l8}T$=W8Rxz`SwZyr|cR8kys(K?WCA}^OIl+wHepX6>-?tg97A>+5x!I`JWG9PJ
zR;ZVhc5<tej`w(EIq2J{;qSCU?*wgJxL&Vio=>A&GSmUTWT7U%c)7Of<5=4#4lj*j
z$}NYI7aCyHHneSrwlen(lRpeExXEgd@M6D?!_#lOAu=1!w_^)@@28Xi@2JeSHNc7;
z*8OebtVcZ!Bz2L9*iNg~XCu;H#84zXv|LD@{snOUtFlM`GhN*V>sBIqx~?<$ygoSK
z>b8_Yo7%G}JALm`<~QHD=xG$<Vg3?FvvO3FWiixkMN-`m>4P=5uj0&*w@J&LYwLk>
z3Z6H?e{5^ijjO4`yr)nuwdf3w8oz%D&3|#8ZGy4fb^T@CM(pMBh|D^r^NY<iG39gT
zW>cY}7us<jlF1@^k5!H7aTomyq`o)hbM{75cDAr#*Vex*YHnua6Ic`Ghx3b6K61Xq
zsK*f}Ur}1Rod{W+boLAK@j1LWeHMK7qJQ%0t63FSu>+(8T12kZ31mY;xR=}=%bS~9
zTKfC!tm!TqThAMfE;DNejo<P7XB1cXQ2skrIqrY?qXXIAsJqq>YEeYUgq2^61*(cL
zBHbK(9n?CRT4a**CtE73y8Oq-K3my>2H5fW=J8zcwtkNYJN6xoHNv4KtD;{Q!jDD1
z{5oWB99dU^yGv@w>(&{;x-~T^R+0PzWa$fUS0CZowx{Z#91QK^be#NoE>E$c$Cah8
z5#6X(R0Tw&DKSewbJImXHg?|*_?|p3L7bhDAdd>+9am>$j~@LqZUg{CR?6Ht$n??q
z;Rq@>M<lJ+CRKL6^)$2fbn83{lHuObE<x3W_`z)iLS~DK9sV2p%Z=Tiv>NY!5hekb
zG6oMH&Cfr(-V0!QQLjK3wK%rC-&?a!^pAqxJ9B4C)-%{y*f<DmRYolWsFINVjp<fl
zFkc41P8+*ZIqk@&s70XCUu-_r)3!_`Pgb#mhiF{*EE?0h+~cRbrsvj11!Y3nN!;8&
zrMr`L`%`jlpEmmoroC0=^Yy(w=CDq5;iI4nGbU*&DLPZ-4QuI$*Ct@#H;I*n3rAdo
z*F%*Mxm9&&9A~_KHB;GGm}D)n!umj8L<^XIf1m;FJmq1)oY`mFs;oUCP4}37Lej8Z
zF4$4`h4!CM;&>Q7>ioQ+azOW4wp8%dh_~py<ryxx?9n1;6IWN8oRkjgBW#gbkQ;kD
zPW-OeEn)2MS<ipxm*{$<@jg1%1+Nz2TWxjcrc{6XR$W<RjW3o|wn3_b*0g*}cZ!*;
zsknPP6N)QxOtXD1w{nBekH^ne4XgfhGY>o^^DfNw8-i<){Q{ioZB0j`3NRBF3%Mk#
z1kJ~B-z*`YlKX!g`ine$ZwX%I*d+&S=ldsj#9A*2%T4I%hq3-127bZ8xnc^pcDc@T
zz_dNw*z<M@z~ANpEwR<W`swB0(O{mUgV`zqDY@YIp<z_eOPn@Y*iIimJM!t#In!pj
zrOF-G?i-R$3(Y7-j@wIdBuL<Y%2lw>H(h%jYXJ=&JW!3hWx^DZtZvMbv|ft1+E}f^
zG=@t&)&~3}D=_11sy-god02Mq^#+^T33TEt>C!SYKrHV4#z~Mpt!0Hb!Q0#P7Bu?!
z>S}~@HH-3Scd?63L}!Ew`X@fq`G-fQKSx&+QkOl<J@v!#%C0!wM>4Il(KFoYOk8}|
zO<mz~^Cp}Qcw0NnQy10;ahf(jXu&ANCF$=9l#QI#5YlR>X$C<rwkgYBy_GN%&ea)V
z$`T`$I?p}SxdHa-XM{8ICb5l^M1Hw*1R!oXH6!sqcB)!iU8n1Wg|P21qQ0@<;$$R3
zu4H<%Md1j*4+pY3*GvKc)k);eq^_sf7?>atG-KQr-?bJZk(zvb{vU`IkXP&T;-){c
z%Kx7=`oLPlQaj6Yb!ON15Ao3Xs%A<!%1vEQ1t<mCkqvB@gYjYCdFlecp~J)}0o)zN
zLm!Y?qaotFYPNPB6AW=BKI13p^u#t)FGMINY%kjFGvZ4!N_gN!*1av6IFF(dFvp_c
zGfZAGYU8ml$F-Y>hh**m!#Nsq6CWFOzA5g*4egIz?$(A$(LIja-5*dkuX3$X`Z%x(
zSzO!&0@4RoI|6c>4mAP*zIxB$SvVM<Q`}Gn5&?7{N5Y#tQ83#4BZ^PF*x&IVXY3^K
zuQ!CN^dhxAv_B`;jW1swzU&SM7gI?USyT|F$Rn5la9-!dOO^w!>-pn>N*4301s$bD
z;)JC?57s`zwsmf9j@&5c`qIi8<S(zzoiu)6XnD;IW5*mP85*Mw`@}cEa1^OP(5%`2
zOY%LM2k{R{GqPe<RI>qC)i@|ctC4|CcUdVd6bOYC*{n(RJcbQeQeBmi;gjq2h330q
z=>#aBlM6a|rObbUJQvt5{`$LQ(d&vnm3-v=!W_R4L(xymH$Er-g525reAvzQ&mlw7
z`vbD4IbYj65*#-K2&w)cAn<f`)OP=GxCW5--)-!(3K|5=?j_S7Y8sVNl3yh4dV>b=
zt^zdqb$3sUhwAHY35tH06NnsNRZe(eDg#wpRfGa9znh5eSL4&y8(<)ZitafpGYZ6-
zb>{DYIj#VFdi^YRzDw}sN}&hnw_N?Cvj<Fc`b%l)Ud)nA1@1>pu0S#)T=I|_@LSvE
z(GlLL-w!BJbaDfw7EkXepKNpYKf&*D^v=ftF%jNZXST%ns8cw?SOd_2egd?z|6%d8
zzt%^letTtq+1a3os^USc&qLkDpb6d5E=Uhj`^=(ZwU)13=}pitzaekVRmCEv0+eW)
zL_-v=AmN`y?KtEGY&j@+Da$;|+(z;a)Jv8l`uGw5zrX`1MRc{T*f#LN$7*5fv~k}G
znr$oK{J--Ju51ttZWoU1Ie*9VhwHbn+72yX$#k^GO6@W5v2y3q{?;uhU}xe%@0w_l
zkyAE62k_>6>r(aza1(neeq2^l$|O>l_Zh+J1z>zJ3A((z6tUyuZ&D~_@|}LD@v2CB
zr^9$bq}lf>@P|pz#Yy+jcX`tUYr>(EEZCY(txq<Afq_9rMuu!x^^@&5(>}0OKfXGv
z)%PkAIm1BYx;}}jBu&+27t>xZn_n$+U0>i5yZspe2ah_^;n6S(Cr)b<SVeLU|MDBa
zUw4aVLGr6z?!!|Z>5>Mt0Bu^8=sgACJS1rxk4oF+1=2nl3}E0sVO*nvssVl`TgY&n
zS*nr0D%mmm8gI#+K8oWwgHk-#-#gC?=zj`ui&p(Q`7CIU5ARho+xc&0KjNFgPME}x
z=_8mGm637(y?f(P?cap?3L`L<5DoI6W_nG*{mj32sFH`XYLAEhgLcTwU7Vh8EAv}`
zx)~`Y)b`Y-Y;rbfs3cZCElCK3?a=b|ezMbJngran&T$?b(e?As7RkdMy<K_?R80r?
zj=o;)jM>%e%Ry4!?|@Y7F6IHLOt=B_Q5c!%Pc^Y4`JU!Mr#}Q)8A#_4)t%>Gb{T?C
zO!Xh+Hj`oUPl$pmffN7$kmavP?gYj^b^;@xAGHLN6>33{U7NU|XnOLPY-uHFPycn)
z#6u9{>IGISk4|ibY>0}-C8jQG8ItQUp0BmvN3;-=$a*8hQ#9>!uED(4!|M(v+geGf
z2VinX!-z+QJnu<L1*$SqVlA|}f2NNSB;*0Nu+QUu{{ZJP036t1|AAdo!pdSNU4zd9
zc&Lh&%lZ0Ajg5_D8NJDO*Q${iczH<hHnlUW7k+B3?W2j2VSp9&_OkjVL##Iz7AB>2
zrZ-tsFTVOcM=Vbw03i*c5!lAdLv(AKY@e+ZSM4|(K&=`V)Zs|+`)N4YMsn}3$?a)e
zqcH;5ZtutnGyVD#u4wc7V^DAF{Sk6Z0~mDB%awMpdjkvy|GeY(FRL9wna-^Z;lYZB
zQBf9@cwIWY7?`@m)H9r)kJKbhmMbZ}y6CJ5YBsA1KAsMiyO#)rw%vk9*R&+-@9bVS
zGMEzlxX2s=)7Tf(nmA;rkDGICtQ7hb-R+<x5oxz?%hA<752lHAd!<hnat_Q`)fwUG
z`zU<M|78LAN4#%bja3C5mMCAYbuTNMsw6y@{G6Glm|G}((r5WHVKn#aOw&SQ;hkV#
z6`%?azyjFDAf*JQf~cIx%2F;csUi~b<S_&89uF&^d*r(p+T*-MF8YS#F`c6%@@)G$
z8C|W@QF?d=u>WVDu`)j&#G!90qpnBIfN9hflF`ARyLo%-rB-K;+1WkS8`J_Nv6buF
zbh5_!e9Q7C4xwH!6$sm~csf6P73Zeyz@dr9J_rRPa!%H`sz&e3WdA>!&O92*|9#^_
zLt{A^Qic>mmXR=a*~b!N%h+WfOUS;LElr3CY3w7Bq3qfBC5(L}A$)A1$xcYN{GRV0
zKj-+<;f&|G-|zdnU)Oc>C@@CN*eLuStlVe2_?uh2|M#GQH(B3+L8W>Mih`Mh(~8oB
zO51_7L2POgG&qL@26bWHLclxr;c#5_e7r+g@!xONvti4?5LIGDMVVn-cd$Y5d_K@O
z0PfL=kcIZB#)XdXV=Ktga^Dfr9N~yoi1~GLa&P0oTh$A|#^fcNGxx{Og9)x#iY)dd
zTHw>?r=bzE^<DvN5erBB1L=pCQJlpD-X5f&=ava`8g{$bHr>nSpH#=OX;%2XCq{`c
zpvOy>z;FU)_~bc^9|c0OIDXC~XLhhKJEB27Ah^B~!)2TLVg}#nAK?ng$jIiVx8mrS
zU4Ormf3wM0AL{<h>_ACX)6P^#-$wE*$LPGQ*-h?unJ7q0MX5*@<{fUtjS1|x`}(z@
zo3+>Mc8D^S8@{`=+_JnB8XRn%w(6u{FZPfcQ`7fmmG0k<L~)hyzbVT*U{Mr8o1@^x
zF00z8;O6BkM`IhS=Q@y~clOtv04c2zr1oScAJoaNo+RY|X=yLC0QcZC%#j&MDV7?7
zvc<soQ`zF-APBMx!oMS$U+eyGXWX@oCDxAE;qIo_GwoC-vhES`-+dlJbzVhfTk>e-
zTYDR&r$=)wvpF{?0&XtjwGpbpeJ>qUl1{320&I0W=cEnb38!&4Ku(IK01JOf;(E2b
zvf|Z(|9DPd1KuILsyHUr&P;|if&-qFpZmQL1Ft6ZHbMZz4+^t?$K&+8&+-}akF>fV
z3HP8rI{7J6Czwqip;Td7<f5U^00%>p22O=$sWEZT6>eemcp65AdmEhhRbtNnARnem
z2j^b&EnIvQ9#{{gNiAQWfsJR;Jg~vME!MZQvwH!!LUt-TE^yFC*+p+<Y^M~dhDN}b
z1ug~Kz(ZDs>$98YbX^Yob_3xeu;CT*t70e4k@1#g&aGtl@LMTX5EKNuO%wv&NOcsl
zS4e~20X<-5mc}+bhlA3RQ=kQh9ZXVhgZV)6<V>|IiWldvZQTr|YVHnMg(M(O7tWrY
zae)?X`m5<dpxveK{oRolf2fs}Q^4VMy3qU1$jG(ErCWE2P(OIlt@`g=_2N&*sH=gM
zF1G9V_?pY#@#5t35p~EO`=tngje;rSI&<XmE`bta#549O2Q7dQqC6SI<iy?5zM)M)
zpZy%knVp>_fWWZ#N;{mFqFJ56QXq%;D{!J(r#veol3oiQUIkKs|6Q%wpYpM*^CFpM
zq+;=E1o<}#J(oc-IGSjv0RE~bLqU|>J{*i^015XJ_&VbqG->+{>0RR9Ofi8{Oh`5=
zJ<PXS{`o5X+Via@GN4<Qw@-H#vc}l(<$h*X*HRUIXc9p5Jcs8e^*qf*UL_?qqCdT6
ztvvw>F8>j%xw)dW<Z<@QQ&r~WvMllJH>;0b1o!7!j*x<s-pG!=yof*3t~FuR;t)q1
zM4JG``=UGf!8E%Bb<}HN9owPt@zok?sa&3F)c)~A)ZZcdvz20T8fheFyc48CSQE_(
z`eoA-zq-j4O}OS_q$usvX;VyzkwyuVm>qTxo^872DLuA}*m)iztLczC#}jOA;5BRc
zp6rK%_P|O@Dh6j1itDb71yE*!=|Kg!fdWz7x4~$zhECkFBTSIov$nP-{Sh!p`w<7L
z`7}3=F2fUw-tMp{`kXsPfkB@EWxeCy$wp-Wg8nvb)It0}@d}h4qCU9jWF>yxz;<fX
z-o{#PlZ6EthF)7+w?Q|lK7JlI|5f#3ZEkKW-GPSYMqi&LGbm4rc;6f51bGvX1dT<$
z0No+|)@7F&rF#Si3ntUv1Y#tT52DhCdAX4^42{iqjm!;b&DjB`=w8nG-XazZdSIv#
zm@^U!t+f$TpyH}>HWW7mDPa}s06(Uns;vA9c?Fwsr`vXlLAJ(F1Jc$Ir*YY_M1;Zk
zGmxUu2%x@aQ4Tn$ro8G^a=c`Zg1Y?KZwq_iTeX<EUdr$Ahmxj+-0#xLb};XY!n!q;
zh?CIB$dg`+ypFI_k2-5OH-RhH0<~MsZuAHaaC)f?5^!mOU$(;nkI66;#Q0!`#x_ua
zo*uN4N=g2Vj0aG-d*yW3EJnrdAShyD>&??!EaQcYRuY5HS#WHgb9)lpEOSe~>;*Pr
z=A^Q?$ghKw6PqXFb4Lpc2j{;czRr|SwJhgnRCC4pH7tbfumXO==8wA*6BA3m{rBF$
zY=c(-#_}1I{mnON|Mo`|3Wu4&pSe2G>EF)5PwHoOj`CC@G64ikj3`$+-o*0r{L}}3
zGhJv4NSUEfGCIyyEk^Jmwj8v(^KhL=UqKaZ0$V(dub42&`UW)|4RQj(A7>Yd>X9w+
z4AJb^zs8HPAWdF%W=O9Ry?jyvG8<Gyd0B9_yY%MMEs+2BknwNWnA&RV8!>vN&nEx;
z{Q0kH2YwsXpNUD|tKVW%|7^v2sfwQY`Ha^QLJNNt70r~5`J9oFp-_r~I1USw5WOf#
z{Q|<~X1IdAG_-Gg{~Fnud&GZl^Sc3{kZzxxi1k>qlfG(0j*pG(6{#FUB-z1ZsEK8+
zSo_JUk<lmx6+iUms$hSi;PN-D7)XLjbVz`5^*syt_j@&QROP8mNtgBPQ3RTS-#l$%
zVBqBuWd;NSgU)yLp+!*9d{90PNgU-MyaOtY8%GAk5=#t8lH%n4&!^=VP1kL(Jp|qe
zQ3<6M8HaH^XYs(~96o88=JLYe+56gO0|pI^43Rx!#VgNNuBoW1CXZohp=cb0EbIa;
z0KLl+AC$}Mz)61#K-~8HSu^Dm#n<y=x!9A(1m})<FPr4&7wLDLXn)3nsqeTr&*K=X
zIsO5@T0eKI<9xe&yK(mMkrpDXOM;&e;1v<W?8qJNJ5K}EQa2hk#5pWPp4Lgm2E3Kw
z02KmaYc#mU8=?{eHUT4x*a6;G=<2gxa6nf}z7ePq%6XUU$Cvrdg(T!9$VkfzD~3Kl
znr~iIiWQFig}=*47S4)A{^fnKLb!)5H>1G7jtPDZb6c`;?K|+!ae3wSs;kimEi#*n
zBe5AUsXzI1wsLm%jlRuEQt%OeEiP9UyI^1gLNj&bLQ#aJnwo3yzabr`xfqd4duRl?
z2Y7CQPDySd(j(_;X3t5e#7y%01SBTG1ca|5Jn~i1teI7P$Dc4js|Ers%SRrsW&oGv
z<7MDP0o+<b`9tH~PmP4hDMJORm_kBXkix?Eose<qo)r>-xbL_b4)L0GWj+m6a=kRF
zAOv<R&Pp`4zT;Ugss$v6pzs4v+H#9NdJk5M_I--8k2o|-I^o5^8TZ3ZH|#G?&dxT+
zN2YKo`$JMLY02v7u#lrgTcWmH-st~6<HeSd?d87YApV8+2*45bk#KUbHZH*&QT*pL
zqMcDUzIG=TrY`oF1YyY6Zh_HieX&kle9ti2^zFlQ<WISdV@C2{;K!%mtyG&P!Fh3+
zoi?+HNHk(})FKnCuclv=@(m`FGldx(8VcAr07SC1`uY1-gpR+x;`J>fQ}$8Hd85E@
zR?KUN`rFOpZz0c8)8Do<KH=XocaH;jNuvv(cvdpQ+4N{6{ku_bMS8H>ZFWBjQ3}Tw
z&87xn(~+2%ancWPz54z#?;vVLobxth4BMdKx$o~Xs1S!Z$ybv_TNw|k$6yAxo`ihg
z#(b7g_hh63z3W>dF>u^8orGDR_34NxQS_&<@~K|=@^-yq|M+Zm=nnP1mo|^-9D9w`
zbKlRfr#?b5!>&>?AB+|j)Z)d&#A?l3<_ysa1}0{DlrS?hYtJ38w{5oUT1ki7J5%_C
zqO6_Zhh!bAYr9*s4WN(B6&FKM$EBmH7vVM2D=jk;+NbT}8y;cJ);@CNOh4|*%F5hV
zLvN-_EiBL>%f2bql4OJTlhzuL(h}=(^O|Wu7~KAoQ!N_S1&W8{tDY^{zeuUHYx|s8
zGVtF*MaSuh;``?fxA?asnBk0YO@Z8ihy}OXAW+Ju=QeYcB;iW4KX?~}#ItVS6aiJ`
zoQ{*tUXQw-+b<lj_^{_J&qZKH2qcOL(Ofb6Shi+*vp2D{vg6-9vM}z^>^<`LqjSKI
zoK6)2Mvh9Gmpx;Uf><Az#(&ZyfbG86ttQb;sBe2d&K(evd@6i)R4nDvWljT6|Ba6*
z;*>wXt?q#-wLG$q48Hf!m$I}T_-8^qa!{VpIBIWocFO0iqN)=c--Ed2IVZr@F}JV~
zyBO;TlszE!DSZG*>0fuYn{u%on($bCE~9<ykVc7kknVZQsOcp6y$gs9ge1j7al)3R
zya_K>Ks_U_5%Qa_%x1T?4-Q&IOMTjpufy3jV134SNUtdT@L0#)d6$Q9fDvbdADkWU
zPgUB7V8vZHFTqZbB<YW=SoWB{Alr-Ns6)@e2RhyR8F$ECAFgQW>IZUIxRutd&dn81
z7sN_@dv&&X$b?!x90?h^+9dzl?Cw<vk4k$>ONTpkq%gL!<9IxLn(fx9W5^Q~AL_)y
zMfU|0P1y077hXbpJg6_~q&Q0Wb|rZ0^tsIX*^fY^ed9Zr#(Z%~42y~pE9E`=@6_|E
zVt+|ZkPZVFkBv|A^FQ8ft?=aWnmQ6|Y_9N8nR`4r%iS_(x6qS0SpAj!NSOgHPemg<
z4Yr5kpeOA^>^2KWEIFq`Ly7Hq^*Oo8s-_1Lg7c>u4Sg_2KJRUnyBT^M`r3y`GH`?@
zAd{9Y*?YIPwu+7NB*<PhyH_}0)J~$awm%T*6q@*Pk*8ZBVW1&k6#S~=cwIa>PCYrU
zC<X+<eTh0rj)Idmuk?Y-{A}Z;Ztyw&{C&*46nOMbB9?fK5{3=D#q!%Ue{?Mb&03&j
zb2Zw5^uaag8rGM72`pj<1#!Z$3mfhp+1ik?qX_Stf1y}fV)b<Ro@I$vVM>9h0I8Pe
zAo%H4+r{6xi%THUgo4|J?|}HUdoL0T{tj4(b8?7jS`C)G)#$;8abF$_vNdMMe|@t$
zFyOydW-H2pUR%zW6V!j-m3cTP&;0%fsnu^~Y_avYzB4n;MUnaByv2z3g>DeBtC`J5
zHEOBNBd2L>_vZ;*iy6d4{{m_wmO-eRvm>!<KwysKmjTy1aSR1`LYg!2=d6na-pLmq
zeOz{aSQ#ZC-_dqln0BqzfuIh8>sTWwmds;Z6SW4$1Ca6G&YbF8WWTRy_YwK~;0&{g
z+O5KG0D$^w18D77cSKRU(>424i_x8(ZB|@nz`tV-Hx~iq%Nb^rFG+A`j>G=!Y>Vns
zC|V}d{XLH;8sXdh1?Zds#Umg<Iq4Ee0t>amLg1o9k_}Rlz|7++Zouk30|{3QiF33O
zGurWP06BQhg||xpg@~9}iCaYVgWm*|xQh%vfV>Sr1J^d%XfPZaBR3+d73b^B?ug&`
zpO?lOi#Ht5fG`dWRlg(DdhvtvMqD#fGE)P*Tc#~NOG{EQ=`IR6Bfs^t=Daf$G62I_
z4?+O_lEuzbhM8aBn>Eu$^FN;pY7|Afo2nWnKnf2H?N`->4BUpmd#qdLyjf8h92P(i
z_QZDTF2@gdL%lzH<I(_^00Uf;!)09B5P`xpMls$W+dDgMHCf0a!oI$sBR(-k58>nE
z1IKC2-May(sfUM$t~Jk~r2~cF+DQl;r?U&hK@d`)!%gj8R7?WwTp}3IAg$b8@zYyC
zQ4{501Nhsc5S89u|Bu?a7jwmvZm~zg8i~Cq&$ihuwE3;%r}3TP^X6vHk&%t|Oz?f>
z#z+Im{8oMU7iA?SXQs5Ve$kVmB!mWEwP?66@3TZ;Y&Ri7mzS7>U#u2}!N<RZ#9iWV
z6eF<{CEFLanBV~h&)K~3S8W*8k+Gm2SX)3nkjqgsejGk&bQv`FX;wt$n}M0mcH1ii
zlvcrQXjM|vtt@iyY<<E_9DXn^jax)?Q?iQ62dg{5Bh;<%v3qU_F;^2<Y2hc1o3F+v
zv!~0fM5*}K(Es)tkLC?MY|70MB&Bhs#*_wMv>$g%>wgG3X874^RBNh>u{j%@0B;@E
z`Y9qnGDT-8C{S%w^}*vD78X=Dx6`fb@Jy#~)^%P|2g=$IY!9afG<MM>0SwpXq}rsr
zRJ>*c5Ck-fio6(X+0=9YHn(f)g9Pe6{hPvXJ@P+edVUG><FA$rf!L_{MID94=4MMV
zYO$LT&VdZ$AOZs2V4U$FEtVZC5ga4&$|DAvR;>mh!|G=Z(0-pX72S~9cm}l9PewF+
zww^U6{TekUXign+C17Vm^<q?Y^tB2&6JtJQFkZ{6zN6ti48vk|a1SWp&%&V#vLoIN
zEiG+N`QG>^-&3p<#ZkI5+8PLaD1Oa(m~xWsI1oc2YQGP(e@nihq2E`sTv71_grg%C
z@VGk$lMbZ397lr9%*@mD5ww}G_Zb{i$g`G~*^xhv82;#&0ceOI7{wlNfh<bF3^y7A
z&#$T3VYuwj>e{g2mF}uJ?>NV338Z!cN<tgqgf^%NQ_PW5#Zzf;5B^4799;}4G|W|q
zi;dQ<d;9F1dP|UdqlrvIy#wJY7H9!z8W)nh|Aw*qca;S+C9^eqSiZz<^le+jzW=^&
z)PFl-;^IuY+dSSrK9$LR=dEq`6eH@acoy28#v#i@7+9e(>JSF?YW8ty1-Fc$uyJ#1
zqvsPya#0rRFht8s%1u9%r+)S_i5Y8y=8UKk6W%Bb86&|=0$DY6SYJql?J#Jifb?lt
zEp-eT7)_#-Zq+4ECosWt88PO4SdQ=*s8d&wuBQuNtNQGaU8Gcygn3*p$j$`USvabG
zgze002gF+E%<)rL_%QuO=q7fMZB+yZ60I9x=>{Qhobq>V9`92t?K@s{db*SyBDx%5
zv5q<jUv;60xjCErOl~d=pE!u2JMV*BOnfP<n%Zms8guG`nBR%GHA-ZqQa<SwnE?_k
z04m^-wo{JG>(!h^?hoEzu#Cvic(&W|aR3$SDfJRXOLVG!!4AEQdzT39LR~lg_(}0r
z;^%rV#RIY;6y=Ox?K*-!AqCDsK;inaewqxQ#QY44Kk^Utq75P&6mcK)bhBM$Ju_xU
zBDoo3<VPPf!%;D?)i*h@j@)US_uJ%O+d^KvD=rqoB(Ussl$Naj{-H$v_1w*r;F62M
znEVQ=ynhKKe0wNjv$-OGLE!!^bB@`O`Qv^Cj#sxcS%>`{lnhKJrNpl%R*RI4lS^PR
zEV}5W_lYV3^bGG{Y_trYd5uO2=+F{{>@mrd?=hcv-!ZVFVvu?aTSvCc$pjRnVx`ty
z50#H30|R^=gpQSZ{KsA#?~d}vjp>u6r{&>r1#PhU=MS2XoY|qD36hZ41;QE-Vg^N^
zw8)Q}CYq4n>(p+YOL47n=PIkKuD}dtL$2}{778b<Y-WODgpZC)&@?C=ge+N`Y6~&E
z0oOE67q@SB#xt5r{jB)|&v5a-r);2M%ub~i1IZ7qO&xkr1}i|5a>1AnXehhK>XIe#
zV<~K!(UXI8Ojn(LEVyM&1Tn(@+X{w<!okte4=@vFo10}jrz|`wmhaz(Km@IPWjJFb
z-kbWOubeubSG_{^MiV6Qx-q#SG|~4x=D8MRnaX9rg#<>(YveNoSMjY-5d8a=92_Sq
z|Fp4VcIOCo6~Zt05|aRZDY44?MryD7oeT$Y>dkty_xY}x0uzI?zQpMFVX*Ji5t2ON
zL8^OO^bB*dK2cia9y}XI_$q%B&KIO`iT4RltvTy`PZ`ilKR%K(9mczAUcyFyoWLiR
z!1wHaNn=S9QVo*Y8_-I?fhb6-e0HZqezh~~Bh-;`{#OiAlKH*tRZ^hrL;Bfg&{q?L
z@xt@H?+>p+`GCQ)Xzx2=y3eFUdhE<m8(=Kjo@)t#I#~HGzN~TVP-WNZQh1(1*c#4~
zej<QQK;l?OU2BTm>u0yVZvZ${)8gvmh9(9E0I<LH`2&#!E@#3CW{&}g@7`zmwZ@)!
zW6(>;vF1UMLoCH(mB_?E$0O>Ji5V7nJK_;Bwam^*15h0QRhOWm<GROAg&Upe_UE%C
z4APUlqc%ShFzhhsdYfCBvp(p1F~JFJAk}wqc=0!{td77&hCO@4b<L%qY#j`khxl*|
zF~VV$tO=R#z?VRsRu9>$Ki;7vZhukSz$bNeEjz}mAkBS~5PDh+ocv%tx22Jhwy|cf
z8|1Zcl^e0=pB6yuoLG3T<JZg-2wz68Q<LZrJzuI5SKI&>wM+<RXwA4RfyYkrtXv|M
z=MorLd%#ZdP<4IQ{LuRBYc5^jOA<&iAmHU4IQlRWBM43bIS@f9gttZR);_n$elei9
z6y6@x^=eTpnry|RVLXUJpLP73>WCIjh;d?$UG9ffW($&~-Jc_zVi*U?Eui$CW;!Z@
z8VC~p>5gN9`9riNW0$b~wM1_@t}O;ZsC9f_0m#gZzHi5yWg&9kF5$=KW+1HDPl=5S
zKt|g-40wl)%*6zw`_G&yxLvrx4EL#F5Wjv3>(AVs<_d3DVq*8F(E!V&zV~(4QMVHl
zpg)Pp5&{HXdbk$((^0TWUYg4i@o?T`5I+&u{jQGkm?>HvVwVmivFQ6IK(W~vMwOr0
zhZ4-k-mFcZ)PAE~%wyoppp;a1Phk>NV8;tm{{a@uOV<bCW3M+THB-8EFXj=x%KiFi
zp6bQ!oY%lmyYR`fitmHFq?Al2eZ+=hP*jIuCqJ&Vr20zx(~F>40#J;#aW|9s5yGD{
zebXh7<kg22{^nnz170D>jdOE{=eJG9q@_s7O@tDH^;@EyQj7GAN#w!2bt#+{Nsc?r
z_9HsnW)JK}YNsGkWCcwe=9Wf`1Q%Ab3x?He=en<j82Way6gs>g1*1}6o_DE4=TAoC
z<}j?ByQebWqXkA455n(96a92$RD-}<>R+U*-CbEi`jourOg0PP+@@&{#*Hs4TM3C?
zZ&k5E$NwkYc^+9@=US_Bi+tGqug1cn_u*cg&%fiEyw=Y)?WfyU57d0CAKi%g<@mjb
zoyp2rQzjaU(q}+_ba#D|MGVlgO0CZ-ayK7ssaS4RgWx`3F_ZToj<dD%Pbq$I1@bp8
zAx#;B=QZl3Fk1H36=E@%^~$8jh7+6t4ntjH^B0Q+alS!kxo6MRlbC&EH!`^gt{qiu
zfItFQVavLR@*s4|wf|1R`Oj0hZaO4DI+y*3WQi+co}25<6n*7<-<GEjtkv1&a&Btg
zDxeZbSSru<(fA`6Hclht>Hh9?DTmoK8FI13Vs8=jke!ahzg@{7TIq4HSaZ!p*es>(
zlX;7%?XYcXc$@)Z_1$KfEd=hm^|{G6B*YD$RWy*DQb~txwVd2P{tq^Hq)dL`xmA{}
zeLr3e>c*UmHBGOZG<m!G(BdxWm#@6#Mq)u@YwPgHaU@JqOD(AnYn$<g3kXlMV1(;G
z+-bWU?~3<o%0wv7^8}A6q@aL4D(iUD`PZw-d(ZoJ7CPjfGs4qckieC+rzMWR=*MA>
z1?GWF<O8fGH0(0V>DtNoCH;00j`#QY%5W+0+rY7t65t110bTXVH@!ouW|a0a!8E9T
zk2*#KAg<L#Hrd?cAp409RhN`>=PPn^Yre~sF*C!Ub8DJ}An<eyBnjz6<bdBUFZLrk
zTj?OwP?T636$gFpD{)ZZk3&@*K2c`Agacvm7a14l8L;=duev23;L^TMhIvVA)>dr5
zzB>682nHwxcAYM!BHMQav70B3i4XiKX)f;Nz0r3$s1l#%wtp%2Wb#~jF2hTA;u{6I
z<%A~&A+)sD{M(6nqI~f|CTytWxO^T{{g;x0g<sxSRm!!Dh>`yGl%-cM#<*=&)sta4
z$lIW=SJgSN!g^s(nytk+P`jBZ%6jg;^+vO|+m^1$XknS~642)vSeZ9jPY2y6;i1*g
zYWEw!1b^nK9P=fV#KyEv0^~MI_md4fd&=plOws4Cc!`*o3=~9#+C4R1r(J|*!Y7u<
zh8w|sk&~v0y{+EY8TIQj6`z+)Ld?Jn=noC!=UcT8RReRcAPf4j@65aBg3ktW{C_1;
zpgYRZe%uouCTQPpMRv?db;;wRnNY|ON)e$K`!2=5L(#*{f;#jc&5U;g*o3?$F9LF!
z6<sglilxBPb{^;CWKNbqL11=3<X)^T(K9tODauaji$J$-2x=>U!Po?bet{tBZwL2#
zuV%V*fGH8^qx&6-!t=krziJO*<ItE%S*<gwYSi43E&Ag}4=^ue>`DawL&eYeruK1d
zA1A!J7euW58E-W^e@x)y&n`C+fk&@u$PB1gen5zTPsi~C%37g;@*NXK5N`_PeQzQM
z$E3mzGaO(#q>`YUZ6iNI#1f02GAc#=Qz|x}Y!p&y&XuXLT5fw=#Ng;F&s~jY!QznH
zr?=pIp@aF+!jJHN4N>y9l0%NJl40tt3p?d?)hqL-(~s%ln@=6e?<S-MBwd{Nbo4iF
zNsDMpV2OTv`{M0j(89b*Ay~pSXJqE7_zO+QGhERC*G(E{qQA_Oa!kTOqs%fCaJfpv
zFyR$YqFRM%w@!*KjPU=@0<fYqA(wzy+A<{Nq$bgX<18{tdWLH`_cDH9V(oZh{|*F5
z36JoFKlil0Q!b<J3+wB3LOvX30T2V<*0!dbu}HEoBb+3v_Yx_R5QE{<`!u^n_IsR7
zw!VS=4b&)nz4dH&J8&(U<lH%zKZNmP4+aJp;NNCiZyKblZw4#E6Q&=l<cx4G|BX8J
zxp)bc%o*X;1gj&4O1xe7wc<bQT&8|@`V@Y<7_^xjalqh6v2?ffpSh7s?sC620_&T9
z_{K?7;x%RxMF>)Uj|Z3m&&SNH+U)$iuu@%PLy#JI#vL=?M*zm80&3yDr*rK)PniLo
zO(AD|uBalM8LmyL3))_rWC*go_M(4_83&~XV!DG{1|)Zi+;1Vmb&v(~eeM{FHVUH2
zJ1Tq|3^0W5U-dKaz{qQqZVd2k@v;AWLPwGgwXx8nm7&s_R1ib}*K5hh6C;FIc5FZr
z4Ka4ilFlJ@6}3ZN%&Gydy(pOAFLe=T4F;;Iua&hY9c%St1tAS8lrLHyW<q=LJ$a}7
zG|(@oOMnhh#O^%72-Q@_f{yK)>4fH%GBFNB)4Cq$Gu)Lpbsa>)VAwb?R)K3LOFW*H
z)a;nMIhm8g9Zn5?yzpvL8wBMDt(j*XM%?x1PlZ~W(@pv|%=V=4{jrfiTh7)4N0I5|
zOs~^YSw~CDbLeD{!CU30MRmcl4n3|0iAXcDXIcV=Sn+m^p@JugkWf^ikU!?A%t$V1
znLU)?N)aZtdb!~w2q|OjAKhH6F8d(0XF^H$5s$3W8>Skx)J<@d^|GY-$5&_ygN*|W
z8Q#Nc<SOl1lVn>iQ)5IqW195XYEnJ`94MQ~bs7Nnll6(bIMqd@rMcsgs9uSKhy^D2
zdNV!9wRRdtCEhH)g|bN}L9g}ttK`|+y#3SdR}%*7i_9)!<baI}2`qRw4B6Rvwk_<`
z1Sb_j6z;%xA^tJhzsCF;@@lnvxUL@HP&(HyQy3hexAVze_aCvRI&spbV9Z@EfgU{H
zPJY@=gu=Cb%Kyxhe<^4IbdW?A=9W^R1fLEo842}qOvo=lU9SNk5!a|Z7e-$A&U<J~
zfJa$#Q&X0l*Tk>{d0ArfD6ZZsvEV=@)}b18Lv0ZD2J`b}ru7Yw+H8GsF?DvUd4mN%
zh%)t3R8@USfdPW-{Fdyv^ld0ZuLAdtSQWj)eYJ}2rNuT5l+yYFK@u4QtD0a8TeE3w
znl~7P?Zg<(KljUYVgyB7&GCXrk2LsdGVb>L2lFhKA@3ZW&OLbr<zuIHF3=m7UR98V
z+{S+bVvCt*5?Om7P+kN*Bwo~dPzNCZUg<vF(C8Td2XfLuNT&@a_R^J?cmPKbEEG-y
zii<dUby4r`;d%Dy#-CGV^2ZX=q(~kI$u#yrvh&541i#N8%1Qy*<>T7VpC^tH<3X3j
zEFnn&_n0+|37iUp%OhoV-4dn%6E?bk#_ojQXc^#w(6n`!A>ZXsAskm7#0)bgK9@c!
zugeB<N;{!aB9`OBKO8FwK$QnNxC63{jSVxFszir$>8uddTfF)CfjOyuhVv#C&l<;`
z%QM&YHAdC|TQ@QIYF-eME+ndb*+HK6GCp{oAP{x@+r=#YbmTe;$Ry2T*Jmg&m2;t0
z-+)W$!ZlI8Q#T2>IMaYF7u*C)iK5}m`f>O?Wo7A0#L?W-ay;Q0Rf#OYY=T#zu}Bw)
zMwDKX5(I?j-qnwU>argBq`##XyKhcU?GVtbuab)5O>RR|>aA)IiN>FZmFv}6qt}T{
zAYM09_W=38zH_AIMs7<}yUMLA#X_a^?qy>ds%ICE+on>Tb^QfCkhj=63}al)UCk}t
zkEvaHPNQw^{L^vZRAq}r{2%Dfeia|=K)QacFclo&|Iu&m^5JfRH*cY4i3lIR<bO7m
z+3REPsa3Q?tr89fb0Cx$g1ksfRFR~|tK*;PQRLl-#q4uzD7*p(Vq&6xu42lP&#j+^
zLk@UCFb@#9lCdxx0WBi-S3X&xuepMd+T={mtkXsSW`n*pKy(I%D5Gkss(H6~I<DbS
zyOs7lc6M(`1OpS!_vJEZ1cES@E+0i?qP$=cqvE1NjzT6yC|S_(I*;Ck^NgrR8xK7v
z$1~CFleKAHdStYmz*6^A-;(t4Vj2eFveOojf4g>u`zUTN^hamx^2e_~$K!UWe)>p%
za_;{8W%A!AZN`|R2z!9YK80e@_y7k{D!4P{k3-`iLW4%9ABx!xBHi%J&BN+gKctUg
zvXdK;Hlj;SMSD2ju?6BBJl^|@kzt;qR8i8|Qg>h8`6dT*kNn@tygY)r840FA&M%Rn
zcETjhPsU9p+oLY>*|h~qCldl>4TLC;4YRdg$|K!NjSXopk^MP2JQ%bskifeVs-!?A
z`zhrbn)4`7k&XEw=-DuTO{PU6l~9%%$wlMfSXLoY9<-3$ErE<3SNfT$hoI45L`Wrc
z5U-NCos#+)LB5@Y>S5tVkL+02+U`BV5C4nE9FI?g=oAtG^@y@Mx22fhyD13eRgg2E
zojHhLO}*-DJ>BenmkNDDwK@A~f06a9w+v9N|E`@&MBFIWpjhcxO+3j?ANS*qdu(t?
zm?VLjfd!b=5HN$cSf2%9kgQ-odHJP{@n7u`r@=vOx`<pu<>}0hLgkUir}<MecfI-E
zR!rVIk)ZO)7muc}_wR-NGP+-0mveLE1Hyz>4FU)A6uciB3PYGns`c2&f3X7=!@OW`
za*J5F^F}2i%5C#x@7Ucc{mF!B?p@LfTe+;ZuE2LmBO3`47=9J0!1LR+#+z_<a=5?T
z9of+4nJtqsX6h?XB0N7Dm*&6bh<OC>w0>xohWztQ_2_)e(hALLV__Dg#N6ff&^;9~
z@7?fwZwaA&w%4bsq+HotGNPbJeKZjQqhD`&<hLbRG^(ISZab>=-5(@lO`)$RS^ac%
zhE|=n_JhY>YHqp16*TWFaci>2q+y(x;W+O$S@M^K#Q1TgLUzs?j6XGfz@Vsla`JX|
zr$UNaLHWv)w%;mj4||@5DBU_;`bE?bHhnGPUQy|DB!2ZeG?mj)=WD`;lH1(DO1E+Y
zX6Le-{ouIpNTqLP)Srz;eP2n5&9H%j6p=0~KAa8I|7T~}gaDPmW(+Yw2ifK=EWuvl
zG+WtrA_Vs?EL_?AUcD52lJ5Fa$1-8k`i4un_VBp0FDqwvi6nkm{?NJfu0W-SvJy{t
zCSf%(2M3+$FLIx$e>u>y+_-K{35)Vqh%1?#L?cL;qLStkSxXq-!^$b<19?hZw;n!g
z#WCL3fVF0J3kOZi`C!Kc?{~3DhntnC+{*Jmu$?ltvN5~H`Esnw_A}1hgafSmHKI`a
z=t(2T-<O|XwbOn25(SkZ7&1n`sY*b`GV$^;JS#BsYI)Vz)>7et90|aGl1RaP3wlog
znb-c9TrX*pO$!$L`pzDRx61yB6ySKH-jkV5#7zz#H@S0RYwPL>D^3s4R2$hGF}LvW
z&|MWpIXQzgOmqL>Sm}Ez&<HugoRb7_z`R=vdg)bw;YnWL*TPM0@vl!upXrjNsus_+
zy70e*_mxa$!*un5y+le_QBvyFWg^xwn)r-X=k^b$yFTmnC8DZ6Tm?|4iHe1}D3FRp
zd8SYw&fS_+_n<j{#Wx}X*uIi|57@y|Q5tNO?#HdC4!RYt$!-Z|l(`bu?OJ1u4&(7J
z+VajP*tqWe$8FNDfEY<jFQl8SPcN+Sr&w56c#Ss+=;R9!IwkxU4M<6sPI_ewx}Px?
z*RVtR=&5>x`|`ao0S=Tq`d%&U@1!$c+FFcN^AuiK^*eY(l4?_Bv!WCKf&I;>f<=(l
z?}vTM##xPRb`gJf9izBk3lx0zELU)w^VkpnzEe?ID?79q=Xmed(~s}i54wD0a|v82
zmqdvHn(xef(HxrV+_8JJQ++Ob3fMVQO*Q_q^NA}d4PJWAPZD69G5ho4L$^sigbaCi
zIMRgzTj7%zk9YJN&SZPztUCQ=Oj*sM%O(GXiU!x+1A!-zx~>Udd3x7cozV}8dW?sX
z#d`8rBgA?oMgtIGe*eDnu<nVfS)<h76SAoaT7Ulj{b5^GuX6Yl(F7&m)h($ZaP!@x
zzCr>C!03;0K1RjM?+8yKBPjxtb*nZaq$_bI_`TDejtd~L_tS!EDmRU-IFeja65Nv8
z!^Y{nle>6rZlRD-yURa)AT5;-Sf)W??RsP&j(=<5F{t}FdR`-SjgQslL}Z}B#F9h+
zDey{=X^wkqU%mY`;SmJ9h&&tG6IxGps4gWQ8r)+pRwv`TXTKZQy$y@)N@M6?SI1Xo
zUEAhs6L0(sb5a`ju{4{QNGrHD0gZW>T4(P0&}?Mr-wnR6kJIFjZWp2M>nmi~J++;h
zv|i)rgXzIzKDjNun3{?sNwDR;W`hQxQIK@K_?LBeZwj<Mt!%e&ThN@zjUrtVq$)9}
ze)+ytpoc*_a$|oZU3WAL3&q_nwto7a)r+3Zo$iEK1li^Q2npA0S&Iyan6$j)yNiTO
z7Y={=3&TQmJzMPT&C-;(?T7&`D)wF0dWZ@6VLXFoK6}k1rr>*7CC(ZCx1<CFbCaYt
zibl4yJ*rD1q}E-d{$5(r{hGjRyX4HO6V=!I`!&5LF5G_c7Ta?^7j#0I-k<y$UN)|+
z`>iV8O5{Mqq_C-#V_*zX1N}OHk|j(E<;hKs?^g@7ovLW@^FMfS16x+!7sf>%_XrZe
zS*F`TCW7v&`BD66FlaE?93z4}#tc@2-{%n5)F&er6gki@4Q9)yZmwCMR6+95>IGrI
zLJsgFf#bk?FONdxV)hp!3=thy*2K1xO*Oc%{**vQR=4;ogq{qs)Yk;|wU%G+US3n%
ziJQDf(y_ct7lt@iO1>I%osNL9n7ZLPBJro|sUU{D_+0T&V}XUe3CL7e7wM9}im^1|
zFBr?VeiZ!}NRD;y#v4z1V5VOKKL3pAONt%bfU4(Ec0I<V&eH7AJA_1dOI>3FbNob7
zZHk~*IRsq%^IIQ9=WZBL+})nHXIZKQCI#7w51|Bvdxx|Z)2<MlQY6_|RqmOfAKp%Z
z;Ek8EG0>PBSbwq~Q3Hb7btkf1R*PR&(knMFy%ywPDj?RCY%-eVKAVkP`tNh}?BEK9
zQIIOcxYYX!^<fa0S8jOUcl3`4dLECu4xgrus(#(61ajG^o4V(16&pD@H_$RGdv_~B
zW)qEt{DX}@7i0=?y`Ovn#8T{isMFTu(tPNtEBgAUX-0K43jc4)TF+K^Zjcf-7#LqG
zm;`jHj42s0sQ8M93pVzC^!w6ixUnW2hIMIiFRzb>nJ_3wy@e)@xhjp&sktLagH7Lp
z1g<eJ`(+yrNxF9jT%jZ@xX`DK0btlYs-yw`-oGYc1C!!S*!}fC3Kq<v6xP>3PEoDF
z{TQe=fTap7vpwU`1YdapcN&O(@p>_TEan;1hAz+lGqI|QE&OY?6jVUNFw==<MFH;A
z^;w6O1*ERVtl(C-6q>O5!{}Ul^0L@O`Vlo=49VE-{GMLmNxSbegYlKt=*7|?q1sdt
zMOAtZoGfW^Xn*NndsBP!Ycx*cp^1rA?VNY3y}T59#yf~f*zS)J@*Q9t5+Lm^Cy(wc
z1=+UD*_5~R-c{d7kjf{_JVx72#dR<3?R^5mXDjmT->ytcWV}^badWnNJCOCQGS^T@
zgzzChe>?l#Y+~k3m(s-0>m=WM90}uzHiN6T8XtApuEgsh#7~!{^IDTt*g2ryGl%Ga
zTC+Qauf;@PtP+o>Dvc1=D1=Yt$ZOYCM!QaRMSiA--=hS1nUBcCt?sgAd)T70imr0r
z>mx}2&N#p1^}3MI5gAciBwJ+dnjtkm2V8~{n21F$lO~#`t?x=z6VPZ*);ebeEJa60
z!QJt0VqOt~EJ{j3N(%PB&-!hIesLBLyBhzZHj<K{+G$eYoUFQL(b<$)v{jerE)HB~
z0r%-$4MeZ?NE2&k>T+i7>pLXL<qrg#&$REF9+(ff7@AGkY<XilmzTcOe*I;JsPY(+
z&TWrShMBleBg=SrRA&<`%*OLv0ZMFocJ>CQ%!svh2>r2QwlJQgW?SBB|2D5fxkHJN
zDu0>kN>O(e1w8;Ur9(dp+!@a?s-wTg$W9wL{`$`yvqBE4)5%x5$4$~NGfv(H(BW5c
zoYk^y(KJ<<D#GW?Mc%l`*VMgcTIjqYPb{sTSx(6vo2sotF17#!Z0?>ae~($qTJuPE
zLoucra}5PZ*yaZ4uBLZ|6V`pd=2BVnKL)uRD~(3|J*N@_@J$u8wta}M$POWyfm9mH
zle5+P<f@W7%srt%3Pb8xN2B%loel@d1EqgiBeG`X1Lm(@f6Z0)e&4nWMu=~W;QcVo
zmq1_l!jyaDJXBh3D0AXcC=mey#ym%m8W<2VTU(x-wVhQ`KV`Aw#GLrBq@+S5H^86b
zN5MhS?r>*_I=ZdV<=0cPm2IWJSh2}Y#DhTyTq9n(E{~e^ixtlRpoUs#y9sl|08E0s
zs`VkcM2L&WI8no3RIC5sH<#GhQN42eFE(4zDRJ%TjOTzgNak1Sl=#G&!1%S!9>(ir
z1q<4e8NQ-+9;Zg&!t;7#<jJ4a<K8sdp-o`@M^qXn3J9J&I@-}=K)wij%OLZyq-a{2
z#9r=Y5~88Homb2b7zrM%5D@%V?NAywn;QfEP%?=8sA{vC=`szSap^q%4GfKOhd<J|
zV`Z-9`AO*q#K=u?`2_*OKYf?IYI?1xSoZB-Yb!Cf>0#nieC~mKU-O)qUpp818y0=V
zB-p$wnGqO1|G2On9M|pmmby_|3Y_)R5(lT}dWf)WLF)CLHp~ft-|s6WFZ1F4dmJ3?
z&wUx#WYy+JVWI?x6)z9m70b{sw=^@W{~Fgl^l_n>ea5WK%13up&#nT+$Qk1zeA%SN
zU)P!4JOiE3qbH7v_K6r?140uxvAlXeE#)1Sew@La9M#ymUR+ZH6?WmTU!&p+4<zp-
z>Y-4Bo1vE3uB&Yqf3^}UW{a#WCM5-fTSiWI=1H4TXJ@CtCq@G9&GAg29`=)^mGrW@
z_O>=NH0K?_MX-@w{pv_>kQJU5gBzTz8|l4vfEcYW3HZ}DK7Y3>)4FVGL$9?p4PW@C
z88;!oGnNNW9iVGIL5R&S?p5yj{{!>!UdPqgH4uLAg<fV}2xmgD@~#<jd4k;_pt8rZ
z8_ngafFeBnhEU?*o%53#wHM&I<rBG|1EiwIFn*{6ftqvwoSq*}ltZ057N|sB%xd7h
zyF)RVCP~ESKoG7M#ofwvCpX0ga-~e#AUEJvUsixIW51qc0jw$7*>uWw#YdbrHlz9F
zTXm7wVhq1t9njh={;_z5q`(+A7q=RKz??;aP}bM-H$l-_Jr4*!(J$HaRYwe_T3d-d
z@<@7wh3eVv`JV4R?kkk0#bs~Lv~ONDPi&8}czE6>_3>YCx2r66m(Mjcb7`*NXRm!&
z`6%mfeI2cnuBX|LaWAjK#H{em*3+fLoe!M8X<f`ZP#NbOd#;<6$W1#RJDj&#q_^h#
z+OAP4v+{DEotfZT>*DX>_H4t9DDhk-5J_!7Nvj7VS+wlf+|&^ka)J0%WgRqY+ozy<
z>nX_F>*nVG$jjir{aU<kfnwi+TI?!;WaWTzf^Xzrmx9qd$WHTCwZ4j|lHdC7ng<#I
zaAj0G&$YJXPdbC!rhGOfJq?5X-v({L#fS`BvWY6EK^yC2lTs>GO6#kQSUiMkN*4(1
z&jck2a72HOMh-`}vcILF!8y6@89H=nB=F)+w#P&M>ny2(gmHBb4FNl9+Eux)fL?g~
zEUGAWw@zQN@l^pNZ3HQ$RhDeNzP9F=E!ZPWqDgNKQpS%|i=uV0T$(`b@7Y;z7VFPt
ziniYHsPSH%<@h73+o3EUzQ4!gLQ+M1xmfW~9HJYS`;n(TVl+X{>7WHk@i7icxQT(W
z)Vr?(m2LqWc6lr|o`funJ-wxoB@}XxF+w$+HfXNiKrZRckvd~JI|Ju$OhQPPf?N_{
zO2dC@_BKJsoqu$ezZo|b{EC<`vi41?2s@1O_4M>ycV{Mb8g*=tR6_4~8Z!JFRhdWG
z`mB~Nyq(Ltxz}+K`tWt@`G&t?Qy~#6#tP@-<Gs9cd-<YIH9RsBXgPlG?!v;o*S!pP
ze}@O^Jz77U+d3UNSznq>G(S8)zpQ2@iRC4IE1j^`jkw1+-#6kK5^{7UT3qkHol_W6
z!1AZk!N1T<la-b&pmxD~i0X``W@e1wyj20qf9Hw$(ou+Qpa3aXWh7jTF8`8oYkO6O
zVKghtxUpErAyUcp9Rf;u<|oX|dD&dTO^5iVwTu;mHZYNi@sQhiNJ%@&+J9FkN&=y+
zh3CpvUE5B*PI8Z?PhluNmtZw*GRh5V{GrIZw1g2}Xj)PN*f#c8HfB7q7?C-TIuALd
zE9Kk7#H(;mmgs(Y4(aUXMi$nY`;F%UX12H5^bDemDHk==*MBH9@&&Dr?(naq=0hdH
zfkJ$0jzpRj<`@yAvF1Q0Zy1kye^Hu&$;f`F{LKs(U?oSSSQ#YNh7mbBwA@g<=pU6i
z>+$TfK!$a8y&XdrOB@GQX8DCwZ#2s}q`%CH+B5r8WL@6KaiZ)eV*BVRxuEVa_-Rm7
zl>OAn(vp^^r+)83eJFlu!*$zel+`5=<tp6Q@hV<#^zWN@$9a)wamgz;luBD8WjOQ|
zsHx&nnYNMgoSMF3<>ejWk$->p-AAl9TL<LhjBVD69`bWUEL?1dbmUNvX|<D<<NK?2
z+w)9@_ct*j#pAoHLk)yMx{j^pBrwnzU=rrMYo-H(Y%9(0P*G7_W#vGP7?lzeVfWwb
z1RGe%kNY?t>h;@vP7$ldBoKbQ%Jg3%W~Bb>cD@i2>Q6x$`XobJd4(8bG0<I`Raap*
zs|b2#@H_q2tA$D874=TpDTw`U`!ka4@4y*xxH)nK*O_HHm<i;({o4Ypy@x{$r#lrP
zIf~_4E-k5612&8|!WW0%_^&=`3yxIbwl^>Rv;L&pg_F8>a+1viPb<#}!msYRi@S5_
zUsJ*!$BasNi=};Ar93$u79qum3vdXGLijK{zfFvfWf$zdF((S9xqMZ$WfBxi$M}>0
zXB$3RUU31}E=k_*&%hd}Lc&}sMqTbF`*5=T+q4&@EvMdde=e{@4e6m_HPawl5Y4f7
zh?m!vP3RM)Cp@oMF`1FvCQAN5CY6-AjDghXKCpdv$u}NpT1UV5h6f|6pJ0jB=}fz2
zbU*(UuzLtW*ORIT{Vi&LrBh)*=aR1&r%s8`%fwFD<;7^)B~cfFG*G7v8#dY!#z_yN
z<y|Jy6ifZ!j?V3{M$@R#bHmb8?Uzh6gUubuv;aVLjaLsDFwmF+Uvc-%oIZ~W(MNJ%
zpB3KD>%&qEALcOim{u(o%|ZtH{Nj<@N2Bvi8PtsClG@jaId#Tz4O4P*Q}ti*E|gCt
zcY44n)UZKOpZbR%zwHH{o%{{w66Eox5uDtRnSKDj?nke*_CO~%N6ny1KBXDyv}BWF
z!)A*l2Jm&-NN|!V6H1?4pi6ag`Lesr#;q}=RVPba{9mC+r8CSP<G}oP?*Z@Gx&Q1r
zVp$ecR8=Aah8_`G+gkc!`ZAQ$C5^_FMiGD;2eJ3(&&;s`?%gXs#xCy$em~irIe-uc
zT#wAP=EQw49c!H|^IxUAL$!_5mtuZ3i<zXyd~V_urA-MC<Ggx14{fYAW-Nh*mzV#N
zA~}Ny7(%K^Lg7=Rz9$Nz^k>ECdqymY^iDoYRrtT@`+o$d&k1sAi$Nw4M|-vncFHPI
z5r0n<imN<CJ{IP22#bO*egl~<b`Zg|eueO(rMYVT?k{f|?|=er<$!L#F)H+L5kZ75
z!^J!MWPN>5t3lL`u{Sf5x*EEf%VcH-L|K?Iu0b&(OO`N@&~?T%)dK-WF#MUHIq<TO
z*awVnlQJ=dCd+3=Gw$S`jnbk%n7H`GW1(mgK`Mv=B>7KQ<6qIi2=0Xr0x96!e{I%w
z3;O<Hk-JjwuYfBE=l8WM39hek*{{Yw5m3+g(+Wn;VOWZLcAra@IQz$vYU_>RXepXb
zdpkRFq(1U85Ayw^+4N{%dK9`hGrZ2}0ctmfAzy;bc?TsSmViM)%q4VR0RDxRo%y->
zIf+;}aDw3Y1gQFBz0v)g5Qi6gpD#=m^1j@F-{$QaK{57b^{bVszYYjfHt^7kO4U6W
zprH;)mQP)K9s_F+KgXg!$(BP!+{)HPGJ3!s{DkW&`o;f*(;m;n{^`Rb_m%u88VA;;
zhffXxMy+BasqZSEY5jb#h1Z;NctmzO$^9WuD~q}v#656TiXQmCa^?mkWe!B^x{Ki)
zxLN&LX4{{J04pxzSa>Ek4gv4Cs=+=S*YgInxMKLMU%oHZSVw(ixcBs>O8nD6#KMA;
zV#d%BD#7GLNsbAaPMHk%E$>Zr{5w2NKC*34ch-EIiW&cJ_gc>C<cy6ufPaF@N<4NV
zC__NOp_sgK$Ip0I_8a?T7ZC%*-kG&cm&xTAEZv@AK_kY3=3dP9!>BfrP?Qcuq3ZWZ
zWI>8P<coHN`A7)QwrtMH_CJr1i3lJ_S^j46F(LJ6-j7meOmaXA2z?p!r!cuj?_Zzk
zeY7f>ZHl&CS$dJuKPvqFg@j*hg!~H;qEY&OrpB{cj~j@dwa`$KL4Qy~*y;^=a&+y8
z{MDd|lpQqXg%oQzF+<_6Z$LnIlRS4)-|_(L>C>ki!(#_m|DOeLN<!8dGz@Ql<2l8u
zzN(qj2ClktF2#%bUmw%JGg6^aSl-*%vPa!=Iop7R7>I*nS)MmnaudI%q#U(cQ0tYW
zCq~z{kG3k8zAkC3U{C84SIH42novnZ;zEPVp9i`Ru@3dxF|k&GE^+-AACrmXTN%vE
z-^tAhp4~beF+)5u&=UIq|4S%<eum9Td*Rpi_7J#7_%zI`Wn8?$EU<AY4jLfRGM6@%
zE=7Yk8Yh@2a2xJR6Kp&lG6`x<1#w_RFCAxxe9RQFA!17&PEE;ew1l)wlr*(liT`_a
zN9JyEX8P&rL+rKXwLgEz*-v2fT%xp91bz@>7i<(n2k)TmO9{{ff3*<iL~FA}Y0!5G
zi2!9|ij#mD+g>eYV29X&pRc@0O;u-bjJ(+XSJGnV%7GP$$E%CEzZC+OrC*OOCd5Sw
z(tn*!F=qt!&B(^Cw2oWzBp16_rGFBw$tzw9l^=dHK4?CPW>B5BZ|nN_s6OKb6vKd^
zt2)?Qjynxeq!tI8dDYtv@64o~H$*)o`+dvPjPH#*J~iU`_nV`mI_-D|V9t}rjZ0l?
z^2=v&zV%0-6;i7@(H_Z%@m?ervn|x7P$hvFXmHeim^q^ZBA%prg*Y+8HE=D6pSa(>
zRApV4<^`d%Ocx+?hg)BtlCCqaV^3FS?qcjtJOVN-qf?#W@YIdcBQrCW<uzaVFGdpD
zW@ZBMJpqy9l$QH=KWGe6+p%{t=cmuVKN;v6!raK#q@|yHE705I<akCCt5v!4{0)ze
z8f+WBYMYwf1uNcSK{Gfw;IE?`98vxNIJK$sQ9c84oh>r|V=947-mb`_Npq&VMLLsu
zlnSTn>y{H_(ev{*_B-`KW<b$huKwG-R#@vjD+mN1ITBZG$c{xXI<|smgZ_`Ea}Q_w
z|NsA-O3URCa!3x7GC7~;oI}Z}8YAaZh~+qkoF#`PhX`{RQbuUxFk+Usgq(BQVvKSa
zIjkH)!teF@UDwy2b6vZx@!IqGINa~I`#SvB^0HSG&BGmNH;B?nlQX>qRleDVl0Via
z`}pu`s#|tuIq?)B<*QRR?Q<}nbQHAk#m3JlYIAt}!I`@szJ&Q}P`7q~(cHgZYk{W|
z^`fHjF)>Bq)Z*js)VR~xu;SCd^C#a=PV!NDyXL=us*(Ewldpy08K{(`u7|*u3S_{{
zX_oQhlAZwKJ?6`RkdP6G$4Fl29iCfA{MLh5ecIf7l?`xgfrLFlioKr;7M#ww{!!5N
zlr_0)#v%*#@_b~i!NL0M6S#YKd;14z!XdDA_`1ImSh+tIH}3^y1MwO@l+?WC*k7Yu
zi<raL+T3KF$J-HWFVp|6Q|gtXBurI?!4j2`SbBMYEFFS7*aAk*9|3^+lCv3fVn72V
zekCdWi}ipRRN~5S3BkqQf~0IyuiB}f{OLDq9O8vBpvC_PUvK{OEnWLqO1HNQx1WuR
zA7b;A9{iC6>J1k0mbz}xHsmXqy7>EZn_{o>nZX~u!4Ih^D5)eqL%HWZuZ++^rTKmE
z9QBaWYYi^-(35Airn0QiWE<@HcQO-rN95Eoks4WO$nM<g{@>}ZBmI$`*BN@ETvdy}
zU-jf~lnO^T;O$<SZd;w*-UmDh@%v?`-okU5@`mVKh~mxIha-h5J%V5xaoiWdqusTa
zN>`T*v|A7eXmx*WF3N-XW$J~qy_$>Z65=6U&F=n=)B#Nf=>CupH~8Xb08^&7dn}!_
z<h0_H<o4MZIIRmY+`4qxBt=UV=V4qfA9MaV-j-az9rLTadY!N7l~-KUeD3&_m1|c7
zE@%`_g|{}^PS2><hP!xs3gg$0PY!nfDO)|qZ)^b#Z`<5v!W$*TfRw;wZ%b`>lXI~d
zgNuX;Cj9i)$Qb~Eu79ccn#fy}0{W^t4AA+?;0~V*hZL9rZkpwUdbc9zSD7p!LCN3@
zTIw8Ix;s^MJ&Zp0sCGcO*l>sq)b)^Pp_lS5uPYH&)n1dE3&UYATwKDAPGCJm|32B}
z^I*UGLpiI~+bfre6`JejL7YYpd!qtAa8tdz*#zH!LgY_U%i>Q@j^|XfDyN_V$p3Zq
zn7+l`e~k+F4Z#yS#Wmx-v$T1!tnSuS0nqS=nx9rOD9t~vow1jCmH5AHgex6d$EU&0
zSA!GsQ!=6ScNquY>H6o#;!pm04*7(IF?2zIXh^NM)T(N*`5ezP@h*F&FEeO(BYD6!
zU&0K)Q=RF}k94W*DZ1KYXp0T7hogHRb{*<iLVH^RV2fRmZ*ud&+)uB;j4#H1X5P_J
z*a1o~iIA&3Q&YBPPhKRk_Fj4a<$iw;@@WJkAnDU5)KtM{Kr||%i59Lf8rzj)ZYZ6A
z3y{H2DV%QCpKLKs;!Z<;(OjLK@7V=w?G64o3NFAT{1@`fY&uu`=6?_##h$xn7jhhH
z?P~w5t&O!MpR;-y1p3g{2CSL^9u#!BDUYLc9o}mu^W?T70>SN>X@<PY%4{+5HZR}s
zGj~WD_FmgrdH@rX>uL2RYctW58%Wg6P6>e_C1Z&P>As~ttx36XYD-quogaVyrlG7J
zvEWUhW40b7U%i-)IhTlH%Ogzup1@{Jc1|!SjR?$o++b2?IW&s@2y`B_aXa~rg<bD`
z<u-C?ai4sXjwOvcsE?S?u?tZ}7meMpEQtrciO!ln-Cv^_kDRT&;$vfD<KsJJ2Qdn+
zG{d9Z<tJVvg}EMc`13399Hk<ixsHf>j@2E*vv{HLZFZ&cwYpXE^_ilI{E6tZ2@c3J
zcM<$_5Bq%VKtQX1QB>#rpvrg(R_R3!4x7+$XZ|$kG{94aMOL>nhUIFduM%)<p?*^+
zl+jU%(Zf)Y(o&bLtpK=e=LtqdjfE#~+@FfO|3`u3INpxz{l4n_^C(i})|o~=zC@IS
zSt1rS@O@GYe6{)ji9*Kh)w)J9;*T7+<+$t5`1^b~lO25ZJ$r8wxn)5JP=)ib*!qsC
zS`K`Wecq6tUT<x-6Vu}LYEjZlY^JP;ZZNl61F%J|EE=-#h1lm~Hb!7ZOY3`ojw3X}
z2t`$|(!=F-E{odEjSv?u2XBA&jvX#MlQ4f0-+9u_5Ct^mO$_~G<)p7=9jFn9VpL?*
zYLzc+qtCh%%NdWQ2WegI7zDY!dwqP~mff1oO^0sWJ0Q=B-|Nc~%Yy?B@JoI7kg-ac
z$Nfs_w?|CUo0A`$2ag}IcV%Dcz)u2{|M~sc_#CqyL5<?!aN_a5LsWV&kWvGf)v4X|
z^M=vopRDt4nZ!fcvVoxWAb+Y^(S?vYxY@lSF#scTC;q6+h&^kxQ=zb)qFr5EQ+*VN
zy{55C8r%G>I5$hvYTamI{5{#-8+@teKcR{hYPA@>!*%SdS7P-bKgsQng1(<KuLv^z
zJGSb61r*IDaju{L2`|nRT1B7mZfYYEj{r9@@T|PO9)(Pd3orLfju~z+#mV&YdjyXx
zi$JddRHM0om(N|pyj?ERlgX{MQ-8fqH?Y?WBJ8MfnqS903zifMdBP;b??AH_IY2k<
z;KE%Qa6=?is2iRG2mXuRAT|4v=(ETDcRbNj3Y<?zX-^%4gi{2^jsWoZ;Did~WYqQa
zMB{WPLUrYhNqTFue{UN;eIY%imv#%9+>pb>ckoQd6F;{Z-mN$r6d4ge!PPhFdZMYo
zyLewQxC``MF3Ri_Vt+K{$3KC6eg|p_&Ao7i@7J$iiX2asyoF=IzaMKh?}5SXk&%&6
zCxBxFvl#4ZHeIJNp&Fc0u_9vhzBc7zNnN-GTBjGF1?4ojo=lBClj#=hhG?F}B`ayM
z_OY_}EAx3?XXtuDaBzy6K|c&E@ecO#C8(OgtNIQ%zSWWBv$TFQO}s(3kq~q6ch!e0
z`J9Ax8hPeUnI4mYG_Ixw@Vx_v370A>jycb*_`FDXa54Y}(DRR&)4U81Pp_H_u$}^g
z`qz2xw~<IE^wWLU_llm6DE=-kqELc_2eF1&CpmM;({u}9<6fQC90A%7zX)E>Lb@->
z<y?OSp%->7>2P<Am(JV(U|fSoW?J^f2(?=IxgkouHi+&5Kn_WAxh<9NHRDh9b(r1e
zwd;4Fh5-$!s*9ajFtj-z8qGN7(*Gy&Lg9JDh~?r7BiU#7POPBE|3kL}O_Dlg$>n#m
zO9T{$JzQs9Wln8q{kH>P9~T$DA4v1h(){b|>Spqs@ecSsRj^^>(Gj(;el)RmqWana
znzOwQ>A$3znahn^LYrpVRQ)#Ybr^w-OnEo)Bns6oX<p8Qi|Nr$7^i*lk}leF0!k^t
zrEv$}Q>Td&U;6|*0iBYLXkb8{UQA2`ig-B3hy!ST1I6wIaM|1$VqNt9mNWEVZ(ShC
ziDD}>4AaroJw8}8@51@ohB=P%o^A_0lA0Cq7;>2A&fyL@4bifcgj#*o4U^#O+_oG@
zt~I_DuBn&0VCYm=*Fv5I_Q|`7>F8&1fCW%AMm8^H2B0O#F9YvyN1p{u&2+%pcc)t#
z=M;fNhRyE>xCjElJ#q>XOJ0A{Jt<)buSG?3px*xrkoGK5`lFK7S)zA(V12BvvxKZC
z4IM5T-EO@+?O~{}IRs&5tH@WRs3mHDi{5!OC$_a!Pa{RsvD5%<PYa91iJhk}u1Zzq
zri~%->oeibMA`H2$6G9M!-Eq_J)a78X{j%SSTsz2O3Q24W5D^Xo(*>DQpLcEF!?te
za7hBI1Sdpqs#lYJy>0DcL;T~%<1@x|wne3zz26(TP%iRTYo8_@@wV`Rjs6r^Wp2o`
zD-V?|n+|F_Ps)8a_x6g;^EH0{V1d%-I4icYiNG|S{vKo;{pNmoT`<WQH$68O9x?UJ
z;oZz%AN`}R_~MB*aee@#CnLy}dQB{)ud2T7;3$GJqEL0h=kYmFOrPY#0bn`OUD#W;
zwEk<HewW@dqOc@2fP2lqKKS~uc3(SQ#p0juPC`&}O=AljcmjSFS6*Ev0_MB)#Zaw1
ze=4)buO|tSHCCkkMNRJH3SVK|18NIUx^(aD5wbouW}qaJ*q3(1P0a57>yAGxUSA*n
zkrLn>c8SV$#4RAtEeO=xNvkjT%kPi4H`x<vXAZ~60P95?_j@I(iVzbSxgGbN8C+R2
z?o9c-^w)j9x!3l`Ag12o`WrdsM=itMKrxgWI2Tod;uB#4^nl><{GMejDpTmtBx2WN
z=s5i8({~H!y?cQ?u7aY<Epi5Y9HybLI5#I}D8V!pS(*x1ND*W+2_Vc7#v_3gOu<@D
zsH!$TQ!<4T$P=mv%doJp9bj5+XaODBsg*LHd%GDPD=bRr+N+!v`|u(Rx;)rDIJG%7
zF)^|8y^Z<~1*nf4L7F0Be^OI@KQ4E0SZ^Jj3}OP6mH;~a{PB07MFR+4W636tdnet*
z?%>mZ+ne?Ahn*mq)}_Vrsu-Td#IZe;oA~<7nKG)Cgw63e?zJ^fP`Y57O*~1;ml=GM
zD)@psjT}O7z~x@l$K~9bF>-d|n0C1SLD=eAtt_N6F{cEn+c;icoQ<ujsres_VYM;P
zPsjRm;Xn_+fmic88D7sv#Q~+x>@)|!-~VKO5-dCTIz1o$zd7~&{udsRaayx;uE46^
z^7#T7Cr<ZlR1-|$6?jjDwSKO1M!CU*p=Q5OUI=I3GqBH6pOaOFy;hXT8B4Rhg3pac
zU_RrpvYp7=s~hxf>r~UaZJ2<Y)b%dEH!M$|DD|6wc~DTO+{6{wd>tjA6qsSHriaKR
z4kD-$uWb^4H43UA)Fmn~7^BF3EYM2d4v`Ra6bxAyTzVkmyM@`T3)5?Vf3WJUajy@!
zMfT$e4)?&vhdVwX#hZl9cE`=$E(`~(;bU2Iql7VTS9Lg6U-7EouVeGTcPG<*WoN~}
zx$Pc^DYEU$I`fdhMopP%kC5IF=;q+y6D25)&uQ7|ty6pYi2V9=?nf}hBR@wC4DFIF
zXuQ~1T~nR=U*!D%_kWr|<oPr~-0%m9p3t^e@bPbcM56Ld$zQ2`^u^x??SY>(iuob!
z_9k?5*&lYNzna>8tGosT33V&5+)psd()#2+NvYBq|B&ZRF7tmOBN43(pxazKZ}Eo3
zP3fk=nJ>-C>A|?X+_WbN>9P8JyJm~W$0ghwCnvVPzqe<zp7PGReIHatAV?1Q)QOz5
z1?<Z@JU8~@R}%1Osac|24j!1WzZzq-IL7`x;CUrGxYTiN;|9AD*fXtPxI3Y%me@uJ
zC(ty-Qi6r6V4fGvn0;#NUYhCZ>FRcNfIOx6@RK^jVTjWy*HdLWkbU*S(7eX}UA2O_
zT=RPaZ$H*llv`c{0q^H{P72^gY#+^^X6w*FFY@hiPEcG?N_gYw%O!dhUC_zvLE1OG
zdL9C9)4lfg0ZPjXo!<NeBorA7J~uMlYeSdeQLY-SQ-=r3CwS$iVTL5m%Jxe~17&h7
zY7cl<$NBx7>-}E$Ll8o*854i}2LN2ZOumz*gzd8upN&MbHoN8V9k;vBn|9AGCP*n6
zaDJfHNu851?IF2VMoQy`1|O!k5j&X@Qi1PbQ3Ahzc&`j{bL;2NP_3Bbzio9$=9Gs!
zWhh$MWmw~0>>YDDeenE;g&6yPC(D!gVr<h`V;$1i7J-=0>it@9E}S?w5eJoG?>9oj
zL;mU@ehKvB`OJfEvxj|`;89AsDffU65d_=={kcvBEE2tuMXTvw2=9D_LE@|_ldc{6
z1E!G4NQUoVpM&;j(>p(evU*0ap7Z_wFz5NXxqB+vaEJ-oUC<0loy#l`&OIrvoDOK6
zjCqkcT6ja~lg{X*s1`l<5!3SbpqWSNN(XN)y(1{CRQmP?)3(&Z@X2?nn^B}`NoA?w
zxOhINkIJG67su9wvoDyfV9!ZBIS`+`r%ms0&Gn`s6Fl&BGEWN#YRylUNOzQ4`~d{!
zNMU*<#tT+rRl)HHkDD*N;KlwuNb`l-=QUMR&j<alYcg6sOoze;e1);aopHy2_dlid
zzUtBO&hHOC995Ao(j31!n9B(Cp8*cm(I!-8%fwp-25$C79FtT2fXuZhuro{)(YbJ3
zSGPVF5P?D=6fNG=`|WHU`#TfTgB|-92EBM%9u%poj4<(JjKQQlb8{ORN5LCHo`CzJ
z2B^&c&{X1X8dDK3&u1=v^Vevp=|D{?zRbVSCb%Cv-y-)ch?M4P0#Pe%;9ansFm*GL
z)+sFoI3JW^^`yH~QGzMKTG<DaHI6-ky}=gK0_lUQzSXbZTedD6f^r3Q<-p4#wKaJ;
zeXHiTYZ2Wr0jyDqZ-M#6kwb;DvJsc`8n5(o{k4F`&q#Wrd44mT(Mb#_md9O~5HSSI
ze~&u2U_S5!Qz%Ry{}aJs553C24hWIJGp3$-+>oT^c`=@yDAGl^G~VNCloGJAR0+BY
zY8ykayPq@XfL+Ule-`xM0DTc0*@5J}Z^?nHtgQID)VKaP1&qgb4x)U9ni{&gx?>)K
z<tE096|Dk15kzNz_##Mf36w#4vP=0GPnz+heGyv3QV=G}hzV6(L3#`NRj$)T4C<U-
zj*lT?8v8O=1k|tk<lH$9l4~NDgL!Pe^*HvWPh#l`Pr}^Xtc@+por<qLn##TE#a8SA
z>9%GUhYZt(z2z!QVZ%EdSg#@IO<V;z?Yz2`5fC)mgdg&o${BJutNuJB*pw$H<%l$s
z$l)>_kx064Hp3_*@JzbE#gKTZey$6qS7vSuJkd!cuOm1c1TF2VmMq9qjj~n8&*IPt
zcKi*3d2rPIib+FhBtN9i7VH~97s&#gq(I+Fkx25=)O5|CPSwQQ7CYs0dqdUUSEvd&
z-R^&fuMZ4|wg+<Q<~zOMO9d<P!P)y;hf~JwN5-NRD!6lC8ar3g8;NuINex!lKnC=S
zP_|??FMjkgKXN2C{#{L_v)Tykx9e%E>ji89{M~w**<Hgo)#^xUzPuW|6)FYAtFQZ0
z!eBj>{v8nx*Lw^1t=LP=FD6!DL#&**o9vmCZ#1b_!v}C~P$<2_rM|Z22Xh5q`VEU4
z59|0^$x9-)>oswLFZ&YHB@EpGRgt+2M~Hm+x)$Ec;t7fzh9}G5q*(<L@4c0gIuB@@
z4Z-mK0b9NiU}ywza^Q|uL!MC&(<fQa`l}=5g9-(3lZxq$ZZ&?^6oL)5?oLgP{9CpR
zYPyoo6Z$8-k{GSCEM-hVKKX-%io+l*H8H(u;C`YltH9m6%Elwjc%fgxS`yop)o&Mp
zxCcGiD>{{VJ)bJRe$hGRY=P6HJd@Nds=?XPO+2rp<vySpw0O*Tk@ThdH#dK%q`}8c
zq$O~<W|I!1G~d{`yX+@dlMNXp@{Aym+@MvUZhML8Mf3M=ZgXgu|D9`BZ<iLOan=MY
z82cIKnu4<YTF&d1$R^$PFRDy3=4dxy6KH6_zT}3pFNs)#p*@wpAT#+ii_JS#ygqc{
z)U>dgboN%&%8-%l$1|$KJ4@V6xd>v7QP5x`$fzhfq$?y7ov0+gRG1xSTLDt-oour;
zv-e;1f^*&CEc_po!P54=jfSA-JAaSY#OLQETB!IdrWDvM%f>MSHc_<{fjK^qx20Ti
zX?~$93vh3}cF})$giT=jQQ$;F^xl;*SOLFxVg>~JKiid{M=kyx`=g^?E`anO2;R7D
z&cSp3xdfvH4`dMLn=7T*<qgABGMy<c{<@sU--8xJOjB={K2fw)?0M`xtegq|?Udjo
zhbJWd_Of3kl?!M5=}7r*ylw@fH&;ZK61N;K*_#EM7trn5`%iw0od!>yYOwM7ZkhKK
zSB`-V*(aKJWABKv0qVlYQs(KRoXH?(HPx63grD)1hDGdX4p*gj?|rG-g+axk9X_)g
zBUh?v;JSwb4#-%bR1FK8m~5<DuNFHwSQG=iU@OLH8@(Y(7FKT-zbOp<IKJRHbUT1d
zS>Llt(=yrBvzlm@HBWbe-XL6H#w&Jvb%V3L9R}{3I7kdCU&q<juKfM`_h*zN0x_bL
zv|#3RQN!}({>hLm3lqpG0bbK+i9nFap?|T@BSlSJRBjG<+nAX511S570@NQRZ8}_r
zO)+Iip7^m16qNFxAn&VHJ2|Pb$0okzxy(<}l^!Ic+;VP9HIog4CHT4%r~81Fi&Sqe
znD2q%$(7{FihE{bGb^<>t%63zuFK#|tCREUg`^%cm;f{$d8QISLhS~U%pa!QI#c!;
zb?x{nPKuD#m<vhH|CID%Hqi*s0H%wj!+6JVcZ)NiY^!vKr?8jcXZPTAtdS}DOEOWB
zkfCH~`WXwCzxG9oS%KE)4*bGN#`7Capr$swmFn#549q6+wsLN9j~@%4#<$QO!2;y^
zFYdbE0YOa7w63YtZpp2mp5o#jB5SD#m?=bvB}KPw|EXjUBri<XvXZagjrINa?(Joy
zb6wKE&Go=n7Yx}Yl+2NCO`+aaP(@FF`yNbt%qdOeD#FhZiGSkf_Is$SaPj3^877!v
z-@rSi-dvXm&y5*_&^8y48*x5A^5plic5!|q>I8_1eEt^GczHnVqD?ddv!2@Xt+llk
zI5-8*AXzz{6IhHZ{)-byWlF`W1QfD|)U{pw?{(ViS2amVuWo(@1AclTBhxm(o@6GE
z{#g)>sRQ4Boh6}+T8F&8UNd~qAI!Q}!JdRyTO%yZL`x}`x_NoCwhry5q77o-a@uS>
zK^I`5Rny8ljj|&w35rN4VGmJWn3xptv?d??x@0;i5tvY7(f|HX8Te1_PAkzLo$bbc
zke+u{L$ozACsa$B+)61&#~(emNVNvFq@}4Jk?iLTKC$rrmKWk~s6*BRq8FrVzSkUB
zrL6LIXldeNm^0!#AQu>o{|kIfjq6kNBLIy_!u$nr=zlh;8hN@xl%i(|U(V`tYbCoN
zM_{A-k7UjfmOJ*^mtz+Vw0S1m>uZa1zi4KzYa!P!Uq3M56oH3|rYIfPpMHz*E-CKy
z)v+XcX>Kn2rpfhm_!nnnr%E{FHXek&#ZBc;y9WgXWnZqVEu%-e1YqF%?y8DfHy?O}
zC5%|68!r{;3O#GC1uMVDRndqmw4;D4#b0avD7_rB4Qf9x`zcUcOv+NYby4iBUn_2}
z&s{`dcO;CvS6bzY%bs<qrE+8*>%x?!ul7DvosTSS^>?Iet4KaE!`R+a`=DvbVm$<F
zt?3Fzk3`$0i6`*#@B?bT`P1Jghr!gApCV7_wl^yFQ!Fy7dG6KDT;gublIZP%QHt&_
z^g9v~d_gZlAskDuVB&1gu{U`MeICv}t3PzPx_39J6b$9%&SaD?!h(-4MzQi!i~L~Y
zF3lvDeZK=#!p=P%>=6KZWq?k9rYo7ieZy>miK=fZrRy_cPs4DfV|PzZKFU5H9yekK
zZZNcKXPk=LR^Of{h7APRvNpADIew(3HXi;NTiSJD?1yx^TAKkl%D_Mcz??@PEsH;9
zoDRS!<bum*M>is5l-TH+DXX!@T@KL!j{cToJUpR~lWsStzuEsu;?kQojicI*kt@v3
zPA0y-Y_FyIQo`_oE#&5`-E1_Y#*!7ds=+MYw*cd+Qt$WW2kLU&if@1JMIodKayXl+
zOm-V>?JGYDV%Y2Qy}h_zH8>^-^(n!44o{BheMft7t~N?3U6G*{RCV4q!NM=q2J0j;
zt!TH7+TtSLn__ZTS<#B$!(s$Bs6BF+3s1j&)LeI6OP_;RS=_^Vja0WkRk~fK|9fX=
zN8&;1*tH#zk1iN2N-naL?qzQ<oo<aVA!y%G`U@n{{cOq0vE=MOQkqt-l=Bv>i4v)&
z9ksk0Y;>Y7|Ip94`V!?`u|JsVOW$edzGpg?^8WPT;P7qX&!&f|J4D$h(1+0s@Nkn*
z6+&^nT~OwyNZF{hS$XY!wl@m@rv>0{=PW|`;w5>n+p;~qRc?eQJp%UIn#v5Bw}gwv
zyImt7tBHbM=^1h(xn<9Vn1-k&kmaX}N(3dNZ_SE+{XsTA3krV>?tgccGc4-Tos324
zch1|5e`ahUKjAU|1%n+&lM)h^U>~xDjDD4VKuU5m^NhJPsvEN2S$Z_Vb(_D&(5tUo
zF@<|%O^yOL>mRf=KQB?C#A)r<b6`gxkc+`Get5Zz+x|EBi7jVxbR$C?E<b*CBL-T@
z#w44N)_Ht#(Nm<4x7;y*Gn}|zIRZ=UsH+Y25JyN~dQ{tzHuSAVoZQDMhL&b!6zC8$
zibKUcjNjqwc5KPQo-whpgy5!qm*!UT$J5PgAg3)%rPQHnuk}MCWJrGdqsTT4U*D)=
z#9`p}tC`ku4u^uF1u_KeLGdO%hA!`Ta+dcBmZ0MQ{%!Fe^ddUzGcbdDjQG>Dsk%(|
zVS>z2^x=C2XompOem;^R^LqTojqH0BHLq)ALh0uW3Z4}@B`W?3O*8JVR~*g3@qXd%
zHe$OI6=<+ffbA1}Ih7p!l*3@Pupq^`XI%5-_2x%d{Jvu$eq1aC;2KqFDt9Zg{(Shv
zE&jx_x%?(l;|noFEIUGe<Hri5F~F`uy~I%XPqs3ICU5RL^+D>1X`Uk+XmgzZNx`C3
z@HAH(CW=I2L5DL<jz-UKZ|GWsjD@d>L0Yep?4Pdi2}=@kqUT%GF#ak+-wocNwXC|p
zgg@(H)ol$sBFxI!%AS$|UFPX>SGQ@D3&>K3<&L%GkmHl%#gMj#3cv=Xsqc3b>4K*j
zPzK(#WTQJVcJ@MQnU|cmX=R-qNsnsgLW&umqO>w-M?n0dhPe>?qhK#*)QEjlEV=Qz
zBdPmcjsEFLgwHjlGYmtdhsy}aL!)~@nfM+mwOw}!^H>9u?0wl8<9Vr!g*Vc};Im@V
zchzKxXS*n%ML!CJ_&fVtHw>w}Uz^GfvUISY0g}AQ4$$HJ-)MB(g?ko{BEOcV$`ci9
zP&X=;oc!7Xk-ty;JQ6b#QSvxdY^Bk{ocNS#hJ1>r&>iCyf5PT#FbHdO^bP$r`gy-6
z8(li-MWqt1f*lf4%r7Lef2++QqTqZ6Vx(d``YayII@zDkQ`nzekRm~@*@<nNuQv)!
zBh^601s5?GyX&q2W$Vg5uY>eRd#}ClUh)L>Rpz<!oP!h_8!cw@h<G6E-E(^;vTZ+W
z|0qigK-9<47!)NoR)B*Le|mh$t#eME!O#bwa%E@252%d5D%8Qj!Q)OR)CjF_-gQ)=
zYUi#MW*v*dgAIp*A42fW<cp4L2F6StV)pFiLheJ_fp;W9vs+>WKG{9iYvHB_GT<6#
z+ns`jnGx|Qx=4dq%J<MHp*~*bsTqt{1IkUhacxj_bH*4!$vTW8HW&fPYu}fbrHs!e
zQK&tNoS<KNGXcaj=@-(>kcMjzYK&ciky&10$9}*4Yp*9RAx-wrQ7P9Op!Q^kR%|Pl
zYw9ip4l<H6hvLYRty(<6G&f5zPu11C2<oigeBSTaG|>A3T;pyX^DA*?Y0F3acVGO~
z%p6OVpHedj9WqAyYW66mFG726vj$M6J~aZoQSqP=+?24BPDu*j+U`9Jj6cq%n7v)?
z=b0=*;+<7LPptjh{;OX3Bz9Hr1s8hg(`+<xp1xlOEI3CUP-tN7g>%shoKWrfSVE)G
zzO5aPlrb1|%v!5{>`~U~K^A!?YahT`>F0ZSjygZMj@w=F&@6Giqu@gim(0c1I;So0
zszfthF-dX-vrBB~?2-NOQk*qlj+zhh_T_I(k{39=oQ$q>gjhU%t`v8;y&M{K?}^tm
z_t?>y2f%QESvM(>vi$e%PSzQ}W*6=~35|z-@gDAH?i#XRElorJk$hDNYt-5H^jvY%
z5m{N~wU!9U(i@xp+N_sb`RKEcbi)%_@8Ji>i|zvtp7V3M`81}f^R9VQx)<bpT3f0;
z{38d=p_g9XGBz}*a5`$?hiH+`+@zDrJ|)%ET;@l=Z8>HE$Vd21chUd$!<NS*IJh6k
zN6fr{oSYm5;t7n?gAetLNM!3~%N{%$`FuAHiJzM3jM2?_iA2z&k2_`^ld1lPzmK;M
zgB5Tv(P!n8e@}L1ij|3cDL_Su(rRt}bNb)u@ySWk<jmeE?dU~HtAa($zFxK8!uP#@
zKMdLR!jk>%Pyg<pjw(BXyEQW>LOC~#AEfjs&&+I-2jvf}+*s0PfS$@!)yh|=#E@Nt
zc>Ux{LTa*uoY~U5HuZ$w^yZ31cSko^D26Fm%hFmnk%UI`uVhHWD8_&GSng7a@@H+D
z)Rekz-L;t>c8bxA9Oe4(fcFO5RZcXYp<yV&mf!e4hbwfB0Wf;i(}LC~couZ{)Y8a|
z<8uN;J+;9(bpvbNLoSj(imMh7x$|=WquR9Dnlq&X*xs;x?N>}!7v++`sX~H)SNt7|
zKOr3LHpRi9?$yHU-+MPK?YfB-aI?1i>!E^m_rH}X?2FCM1Cok|2p-)Ai>mv|3j6+T
zLt+%_5q*!kyg7)W><n@nK8`-r8l}>siLOWVqnRR2yTa+SE-g-jYQ17rztjIKZP>5-
zapQQjtgNi{NYPj<r&<HZPLkl%OF}RCZLY`K=kEbRfr(JPvQbZA?0E>BoU`Ni>s!+j
zkx+IqO?KI`Y64SVFCk@&Z5?a}h(oHD<K?X@*l5@t(1ZN?vuArU??E$UR%CHYVU8Pl
zq<tPuoNDHxA_t_g?s?=vMJ|WedlSjK8*_h>F7v3sAZL%T=Ftp-99KJcn)K_*@ym>#
zBbi3O`rF(}yhjehoznyQ0n2+5H<o%UeZ8GVCq{BY5+#<bjO8(dnwhjF^ird+j!Ihr
z@;B|d!RF<JqHpP+SYDydc-KiJQ80EO8992GBSj6vZ&84_0X%dKxf@P^AEjH--w~*0
z|7315sXg3{1Mq|=Bz(y<AgJ?w0LGchVcNX!v4+;Pzsos2+CKRhd;E8g+NuzL68p9-
zZx{o{MYDQ=GogWP0*Fn@;NSVvJx}LtZe0~^{eMTD$F8`#HoQ_)2#0}0QY4hntR_IO
z*~$KbQ>{=vNLmT!dcB?lq-WRfN0wSr4y2)+Uc-DTq&W5!L<ye~U1zkGFpl4xYz!75
z+0lP}wQ82{;#}3KKijpnkcG=Fm~xp_wlM3z=?4=)NQGvyM4I_-%QJH)M*p%3!mLgE
zCD%CY<eS$`_=@z6wH@1;Q^JOEeBSz*p6vaAk3q|_9#5Il!eE&|W0!6O0RhSisTHeR
z1kVaF25EV%TjsyFMB*rpJsUZW8rkTJEf{dWG_bb24KzC@i27FT0e@#ytvG=xAuT)l
zo8IAOc;soMnt6jib==@;xQ8A6hC%&gw`ytX_t|1u^TU510+D45oHisRd<}`Gn17r<
zIXM=i0O^rFa+~3fn6@Wpt{RH-NbQ=9`<?##@boSEAE5X6pHAhHt=Q^L(=c^I_aP;W
z#M|!l7g!iqThNkCzx=o4^a6SA`%mo4n#w7e6%!nhw);IN#Hl%V{IM2v7d`-JO+)Pp
zyWI;!Z&-1M0X4x?++XhX7>=gjO1R40#Le%DDhWy4_&UwWsz3Dnr|A0@hD*0hmPzK(
z)+VeVlJ9LCq2-+phc2r|rlb<t!T-%(T&I0oP7Y2dU1F15AnyI2o60hF-%Ec{SGXb6
zS>Te5HV^PoaeS%nza$=utyv8H%Yj!PN0DfOWrO+8q6DOI!~$P%<hr1{slxanBmVdu
zflOPWcF0~<J)<xFI-Ch~#`rVX*?CpQxgykmfsDt@7`}2hb^f>M!c&ai#Xl<6!XUdG
z9ymthUBccL`*tb4%F6sF4O;lNJRDg3t~Or=r;aeWq|S@nNsujBi9X__e37*FYo02?
zc->%F3-Tyw(y@cfGsOH^(99S4OdfPppyL+a=7(9r$Zy3fqJ;g-0m%5#_kwmx%et0|
zr^p+W`&`RWtn)TGI{xU7vL!%yZuvul>@J5u+jtwAeEYZ5Yyom`R5YNUh>gDSIr3v+
z78ug<ahlXTwpspo1>1IV?zK^nj4bm|uT(}CSJySktY_*7drFvnz7v@|aIEKAUxsrq
zsj$UWzgRR$_5*kqXzlaeFbzw(q)q+$F#9bTw_GdG&7gd6;Ev9n3DwM}`=x^Dw{p*S
z#z6MsoDwA?_1%g~WcpDEX;yFfjDZpdx><H`FK#Y>D(1V3Rh6KmBvXP~KPjIaItT`R
zJzRJiDbf16b$p95T`B`gNTWt=UiK8cT;<TrckX1v)fK!N{rVa^B;UzA-yxdub^yej
zHeUYRUet~Dz;PwgWw1zJPd@&y>;Ha6>5to7Y4I*E-06CX=01u%pk1hyLZEAvZ-~1_
zaR~s<Ii7KlWcB9q7~DAFNeWlmbXnIKZ9{lpT>+j@J)V2MhvB69L2pUFrW=HGHvq`r
z#X&E~Mtg9Wy0M6;B(3XSxVOH1Fl{tDllcLaIej~Iwlxe-Q=ld1lDTuh_aiC>UJ7a7
zhr$Q8`YcL9M%1MqcpIt<mtL;4i_qFo&04z)O`gtJTzm13U>UExG<VSujYZL5^)mQy
z!*gTOyo((HBgw4_^FX!Ym%6_{y1&0axSZe0!CPjfQ1ucyj_Yrf#qZ_Rf?u>5y)iOg
zGcM>j5Bi3{v1sPf9M=iEG`56-?0(-TVLcs)mBRN$T8b}kneg-tWiFO~{%;7p7f$qd
zwCx{f%4XuZ>tM~Ss&`3R<3FleAT<l<m{Z+XGg|PNe3N1nr|ez?+v<80(Rt^vJvQ>_
z@3xn!O!UZMNSoZ?9Pg$2fz|QUrk~|VH_uuJq&QgOMZ}qVWCz4fyLYXE+$7-5*1n^+
zF~!d#?vYMA$$^8|P1|M7G3|Bho8c;49?#=(d@mKavvV#%RHCm|y@pZzkBlD}X8q^A
zS(L&prg$7Il<NL|4rU}2#X!=AV*i6oWR)GEhyG)W#t!ieYn@xy$qb-8GyPSKs1-3{
z{|I={pd#1-z|$l^Pvj~mr(xk{6QQMyL)(ihfHGq6a2JeDCmKfw(Tb9>Do_~x%h^7O
zbe?RAQ>#C5ehbZEFkYT-YnIJfvpQM*3a!v4X~TGfy1~klx-f0<rW?}}eY&mncpn9%
z^|_cdZZ%dK{0EsMb3e^8h9g}mPN9zZ03J>i=bmoR?2oJ+=eL0ttXbDe?R$+VJqq3>
z{BhU`DT`((ah3|+6H6EteOnM*RLRZ!CWX6ZcYW{g;i2y*8{;eQ1DmJ48vdje%3a-~
znLI@tUu<aczwSkJ((4U=kh<Q!(!um!d%)fkqnZ2@_pAL&Bo(88Z{~~6e-aAXBgU4t
z{P6fGAO=WKa^Za)3W_5bMrwpNY}Z}nZTZFZ^n39#IJ!4ojK?r&1F;ZSY`Ha*>CBjW
z_J!ISNV_&6=!@q$Y^4P6nq?MVW{&u#HsWA?OUu%S@n(_R(}5C093g~;1c+Frh*feM
zKPUl=Zx#G^{lFyibwpHgYsZiyBlC}8v7=`;+Sr0KN;37WDHG}Wq9$7zccJh8Hj4J#
zv|kAEEJk2g38+wXTwDF+9UH=#-fpagP(a-@ReJd7`f>i9s$iWgUv&N&==0>ZNbf=_
z1=GsyRP;%a1MkNGYF!r<P|wmEPvZ_}1sH~0)V3?mlLM*tTvrYfu`=aMFt{vjIq^^&
zT|*1NjE>$JR3_hihTeHpx$*f`&CWmH^D-$$+l!st9sX=g2DRhG<e3Z`)5#4VbEwq$
z?B^0flHHJe%gRxO2~AF=NEN<T7eD*0R;pYe+t|=sBMT-_2Y?}l;&vh%FP=oTO=p-w
zBhUVUwB&jWExQXQ`i93u9_9ZqHHL_j6qT&OG{+1nW>PcOyxN(N{Mp!<9{~@l&(PqR
zwhd(>L|1ahu*<)#VWkv14$Ao)EwnFh#!>wQyyq_|UkcMHtz2+YoSm{(3{G;;Qqi^|
z|AsWD2G)vj*)mFO(7*Tg)B<<*qDU0&*NQ6l_<SJ{M3lk^jN8O5;j4@+sy24GEp-W;
zb?@h5kOwE!D*j~9^<=kd{_9vHEk5qwn~3R67IvQdQ|y#z^M^W!vGC6MXvPy~v;Hdd
ze^(_P{HM_{+^$x~Oya3dJ$YJ}Sg|qnOwyQ7NcPTV$874&?(YssANG-zLmql->+Rn(
zvK9pwxdHT|ra+=ts=Gxn$C&+-u(r5I)R4~kR(~YEz^-^F=C0@;%H**0o2m(bGnJLa
zMQv&AaF3iW&3FoG<Xsp-l5Mlj^((O$)N-6~Z16ix5A502Vf=?388f@x#$Zd(hb8Y{
z9MO&HU!(Oam#`D^c<9dsP0$5t9z$@&!}E#2Qd)Oq2~TJl)<9tu+jI?>9=+}f{lK|3
zVD!8xK5oU`qIX3!1=y_OTgtc*_9n(fG7#}%P4Plaacu!lK~D=Jl5byvWHGVs8?_fu
z!`2!}q6L&uu0zsPc~NVmXinpR_rE?pstsCKza-bkx*rpm$pTX^1JaT<KLXsYwNS$(
zUmfbLk8|<_0Oq95YbETjfwcD~-fofhS&Cv2jymn$>Jo(HF9KM@*pFKQ{(=Q0&(rOw
z@C|FNjP8C|r|eEv*(nek+)Bj}Zb^+u&+w=vIln*be-)BColXh-_5!bZsigmNdy4zx
z$Vk}GYJ^B_Zi_!#D9bAvLW_GWns_KEk_xB;Kh6i5`(6gM*Vy-?LFLu=6439fik=VK
z0*NFyM>%;eS4Z$X1I?;t(su+x$|IPhtPPsFKl)RT<AC{f+nm|lBOZR=Tq%Y1Wc2Gx
z{@GoP3GTkepAEo2bZ0J-fgS;g1eddzG9YvBIQaMx<pj>J$W7<$eqJK?@zeclgIM#E
ze}{2A{x~`r9CU6BMz27;H27K`&2V(y>}7m?T@^V0u}5&QeUFCem>OqSWyQd^X$r_2
zpQ&Lk`OC}8JuTJslv-0H{@X3<O%kPmWG^Xpg<TR=6s86eqzv;#aIsh$9Xz_+1;hOC
zEgCTrcC07$17Sx8M_JTO@5`Xq!czP^{1wXpw^2z6zjwae;bbr1)>!7O|LC*5grP@-
zqA5(i-=qG)XJ7PBPJ%lX2-2(aAc2_NI^)YqtunY>a!06--)O1QhQH9(Qwe&-r>40B
zrb`!?a#$+h)DC=WTaT(1-6N=NX(q%UsFi@Lxuky@m|xTf)>loOyW8SltHxpg-h5xH
z*m7-rp}*Ck1-Jhn3CSK@&|8;-+KSW`)gH9Rh4I`7RJooz`@If)#g>6Jx|c9@NX)u%
zt~k^)tEys62W#btl)_jN0&%jDx7ouN8N*lFXV=#cH#djF!}IQXA;%q&8@f%GIzS0I
zlAmk`=*x5J$}TRnC<bALcKyPAji=HyMh<=iW?VuCR2<Y6n1HLxkM;F+)zaa6fmAcO
zkWPhlEqdeoiJe1M5I(T1?1O*L7d{}I@;w-(S5_rYRIwXr+kYrtL*Sg?D>;u-H6V!2
zMh7mpnRq!~kBN>hw(4iU58{5QU2>MlurfXwjjwBY(7(hT>5O==BUnJ(ABz_27Chc^
zF};}4(Rz;3l5Z<@Gl^C>r^=b~>GEyNU6WV00}%$zEgf^M4#@sm2?j*jwQh$_2$T{B
zhP^<itN;Xj7h=5lc_3S)z#R{{t&hCmf|wwQ$_X3f9C<cc;0ch_Yl)zDoI@uTrL!~3
zJfw^;dk=d=;A$Tg`*>3`Bs|MhUPef;t{Tw#&*ZfOU{@4-c7gp-i{l&UULC<3A!~v?
z!d5nADJ9*dcu_At+L#rkys$6dry-{g??@y8fi4GRhw8R{hwE>(zHX5;q74^q1=W8u
zPXENm9&T?gFN677@v{LtSq#R!zTVbOGJA~p)w3Y{6g*_4M^^ZS;?*k_Lqi+S9#RK9
ztHwxJSJ#nx{B3-gOC5xH0rbZc{FcC<yrRS0h*}bnYzLA8ZW_<Ecsct#6|^>^X(K`)
ziNCxL9;GWKJ;*aIv;%!6RZqhLaJdWC)S?Vm*}<)U;MDND>1^Q!+C-%wYSk_$G;lqp
z6N5#v!(||b>)FnlC8Yg{HL3P*=Jk%*GtW$mn#ZI3xf~4;Q)&1f&U60JjeNY9{2@2F
zw>O?o(nN!@-J`zTHK&g0nB;MylQ@}Dayf3!oRu{RnYKZo?$<k-1z<mgnsuqDui@GA
z{i)<Ilg|<*;UPJi)Z6-<rO}L~$If(4zvbr$d5I4@k%m_#m&BpkLBPIkq-jo+?!+$7
z+FGmX&HGlk%2&9rf&6c=Pv2q6fv{v7auzrL@i-Fu8g=(4cCfLo(wa%{h5J4A(P}~+
zb;hAK8TeY^z}<?ORTFEtB|vYbOveXM9gM!t<&L&FAlDt`oAzQAelN%96(>C<qzyK1
zn9p$%b#7__@7k6NH%B6#-eQnEFUQWbOkLcvsHbt}t82b`|Fpy!nRoVZZfp3Shod+m
zn=A~~ylD;bs&Ju>`*hEzAFPuYhGh&4brWvZkm1QwO=u>Uy?p1_AlC|9U^^xaDijB~
zwoQjKT;kuDKM?G?B6r4l?<I^hI)2pTgl@6SksUPN<oFi{?h78T>AY3VqsjCv83yUy
ze6EpoL+pYUefIPus}nowBXHa}i}4Q_RspMMhl3J0jo2kLO;%&|Zxco8VOJ+UrV75)
z4h?Z}btO(>fouQhWU-#=VB;&|0>?((V!K?mi_t%gM$i5YY0IB6MIZ;IH0+jwo8CsC
z!ej~LB7e<c;}P0FMON=?Gg0~j4}-(b){(;`KDoa)pQIns90=#GLNxnetw+bU$OiJ1
z5cqD$Xj=f4K<MmQ>Q%~!Yu+sC{y`hisx2wg&<D%dAnsjjkM<GW%XlaWv3ZC$#P|`f
za;>9?K@zMUKV{&X5liv}^Ss8^wD54QuJ-P0b9}sxNJ7!8z<Iokqn<R&*|}gl)8v-x
z#mtZkGJ-cygU>g=ik__D)$X}_Ke+JK%TfCQuAmYnym%<31T2v;R5iL2lILe!P=NTa
z*WXy9)^U>=h1iIsfuS$r_}Kx`l_#M^m6C9WbO!uY#FweF;d;rd*5HJb@Y+q=kP(=G
zF}WOat|q*nw7z$;e=ijdBwyH4$$xDJ&VXKUSwB|Qvq)PUgyjyw=(fajUj@xQ1XE`6
z;Vll92{XEpUp&~yxc`JX>j!EiII_EAbJX@A-mRQN0fJ|)K~4|WxgfWeR;b&@NArlI
z!S%IWc8RlQ!ETM@auIJrpG;nu)acoD^!?u9?Pf7F`ACOhKmDn{VJa|ECdthxgxD9|
z_6MDtWl|d#lLh-v=u=q5!eXw@rK7hkMn<bargFHTUV5N*E^~(uV;ZJ>ORTt_=bW3m
zuaCD#%BsjYX6@OCU$-g#N*L80q)3W^F`+f`<2=QryiYKe9nWuU68fjam{``Wi97of
z{5pfXR|y!7zS*-{ZC@fAm$MXUyl%E_pQI7N!VL$%)Hf~tOAbP#fD8lY8J*F=MxGFc
z8io*-&l&#1h#fSdr4pTPS-<qyY|~9=a=oSmjC9*Hw=$;9*RzWlZa81Aaw4yLO|N(f
zp3yG9x!3qKY-mk%&bZYg=Kka9ZXc$#8?|0DgqaA=mn7%&NoQ5P>I1<$-?O8y%=$PU
zl++!Xe!lsv`Njs1@5b=A*+p?2cQ(5ou}X~FOW|1aL+bE39@yE7Du#yPx~whc&W`Gd
zulCc?#xETCeb?2W_vZdkyz-iox&cZtHNIlPFXOh8Y2+4i*Rf7c?1Gvvn(OgU^e9MK
zp%?j8^)vUUH66{Y!HxjOYI~+XC203w>YhS<4g0^o!ZSa+E&A+uU4zhdAfyf~96VtY
zQb$-~%x7?4C)r&W!GF>gb(7RA9677c@y>=YNjkCuIIP!@X_T-q$ZG_}pC%2g^s?kI
z)Me)T=}z7pHInl}2@mYLw)Q)Pzlw&4+}V)#!>d6nCvIi!L==RGegA3D!qIdadRcxp
zUh|>euZW|Gl&81)?ji~4F<&rxVt>0wztAdTxf!I*NwM+EcYN(gKJ@-*Ov+=ezIxy~
zQMg9$S+!nonf5;qEZco8S`Kfsc5}-?SrQ~4c!#k63W?IqvQAS<`&oKyykQ|o9~+Mv
z!M8XKRL*2@D~)Otf1aAjAf_!8;?4u+mBV<;oXcaj9|yV@!1%W5NVIR+MP8%yv4h$j
zppIW5|7q+>d?~X}BbXuqzCWh1qoYIcotsjekMP+R3t_|e9Pj&tdDif6ZN|tow{Ly*
z#cr*;xJ`46U8P+m?>kk9weCo_mA=HFS?Rd2JL%}p7U*%}y-yKzx6eKl-)Ob#HL^9A
z>0D)*i@#m*%Wl0wN|c`ql6=ozmGpD6r!{wa$1hn+T%i9KteXF%5LVm?1p(<?-?Xb6
z*ZedE*mY4xNfR)@)g|Xf$t3N+ki7|pXpOq$=)NTI|9Grrxv05h%Ou|8UeMducb4Z~
z7mfHkDE56CGj|6wd8PoC^aKV`&6BB<_|{!yQbG3S5FvJ*DXL%huKIGMm^qOx#I&%p
z*zQlx+Wgcv^zcj&=%Vt|>Qj-3fvx9bOLE^-RHUa*9r8Nx@n5}-EAsG;IQWkIi!@>E
zD2(D%5ynlhzl0_`;KF>5--ZnxL^;|X?Z>h^Y&`2aL!|vya%%eOXLO0kI=a~T##kE+
zJrc}E#7{qJN$rjM`Sy2K#(?CdlkecvZzf{lX$J={A0@9z_!yG*qyE8faZL$GKrX!`
zko~A2Db~`MG$lo%7nMwq9}NF6D`x!IF__=?vl95WMu~>I*TetQ0x+)gWK=<W`agsX
zcE}BSB&vf#JMlzqSemKbrUY}-e%!wDV-E6+Qgp-M!{kgk&dYN22E3PF>0sj$UUX0x
zjfKB2+W4^W$L&&OkX{*Me>B#)%JvA#>q4N<-mUViY@?RF<x8SP4?5~b$-~8y$x(S&
zCStV~VI)CXhETpLDq}okFet%9WkuY}?Wzn3cNeYOtO;l4Bq-1M81KD@H><WQh@7ev
z#lIiqx|Psvw8CYYzxwuYV^Kue2K0)+`^o4bh&#Jq<uJBi^(I6o2MSVT$h~)#U(d9h
zn1mT59exa;f<cxh?R8!)uEMYN$;k+Q8x*as75n3hgw@0q2xZ;>d+N+y$Fh^ynJ=IL
zE<)jgNLV#~Du>N2S_galHtN}1LO@Klq|!8j<g%3?xnYjJZytys`^VY*7e^N}twmU{
z49Wm`o}Dw{c8p{F(<Tw)rS4B7<CN?>>0bh8|6P_+KBp}?!~7WX0K%A6ip0=v<UM<o
z$HTM7qce0pjr(%b;j92^Z2dCNW&0Zwe;f{OV}`d#x<2HyB4bF6xR@6^St=3OD@TGC
zO*yOb-c)G+?TQa$Qx}@>0Y@I)a5O`WOm{WTKa5R51r$|IM2ZIh%ObI|yu$dS<MT~o
zDVinLXeZ=HxgCe5IUC}~tEE2M+&8bxhqQePD;Qb)1%a&V-0B={G54+cGh!*M*b7)E
z!DE!7z*h6@*EOwF|4y^1x?iPD7MhC&@<Y)^#w}s{=NoUg;OAPdRt}v>Fb#h;DH3Nr
z)0%)@-P@b`v~wI6U%GIa?Y9Kc!*2VFzP5n_%H8{}37anos(3+J1hkl)CmSd7;!Q?l
zmbAycuFPb%a=|y`6l3t+=+<tZ&80E(8TLoFK8f~xFnP5Ys}H7rKiCPfRHs&wi_neL
z4<Yuio6X;MZ*fH}>=b&Yf^8f*fB0=uZ3})YeM1<_agNZN7MC<-ejSHTZ!23at|N~&
zTk8W|uZpdOigwVY0&%(WM}h9%tjug{-)iz_8T)(cu1w;T8DbQM-3T-H^bG-yZ2fS-
zb62l2*YFo4jN0O4TZ?O-B)!@g7B%^4=nRi)%DiRFez|E=B7}YS#oh3WW1D`_7?IlO
zE9ANDL^QydBy8xd?8K})J0hzlo)gqY5kSS6>+CqFYJ&c<p}y(n^<M7_cRB3_D@p$<
zJsKS~>vlBp@h^vi=<$NecBrbC?d@;p^Wm}rg0i9ij>>g?=HsuZoi`s%?&xV^3DunG
zt%7iH`6qYVZB>WOxvTRvQ#~IAAf&9V?nN%#A0sZrs!r6BuLL5(;^M2gV=*FUx8Qxj
zpi1|GkV6*ThWUpXoZl(jiCF<ub%Sa(ZB9LpU%_HFIx)0Ow`ZnE-2S_-HqmDNu#3K?
zzyFIn^3)dM@pCjECWM2SAyed;6VXavvwoHrh#z=0;{gA4(z>TPkC@6{ABX4uorXqq
zq2u*iB~j>nVQl0qny!ADg-^fS{%CkhL!aA@i0X6$_g$FQe=<X4TM+yCpby$yFM7e=
z)@0_~5zB{oj>Jq<3}5LVSe9udpU<dRzuqS!)29}eYtx&@hyG&bYQIeD`=S*My7|D5
z1n%&g*WvSK9%<Y~FD)+qKbp=np3V2|!?8+JpBhE28fmGRHH+G-6}4iN*wjo>)SjjG
zsy$1M*r7&Z)BdOxMVm^HqN=E(O6*Y2{eSTUue|YzE7yHp=lMO4Beo8g{pIH$a$ZpY
z8svyA6Sj18ZHnY@E31KCufQO}w(JlN6K(%#Osb*2tJ;X_%y`>~(<n|)nI>J2(Jj@I
z3glq1pcc>`+0polWp?7`HG6tp)E4QBd9dM}1Uy945?-kFZyP^gW6_im92{s)l^);j
ziD$0yR4#XLNmE!kJ&#z%?u14D?N8diF+cR|^!OM5v7v`S^mlWej#N&=L{fl+|9h?J
z>6A4!N-z)4{H9V6cP8t8(({Dh3CwA6PVC3hjcV^NZad#P`REiL!HZvA3HigzuTV0#
zV2>l+RbLvS!m38$qP)-}zx!$Cl5#RL_629%_dj7bdD6OH^d8ofaV0y=W0%6Y6KUe-
zu{(<RjCju1(j&h<6BjxqI==uNSZybq0)0KgtHsTH%(A<nt#~}b`*;=FCho-e!i*WL
zrhKzdsahKKxz`bZpD&NzA<_fm8FAK$4*pBqT2u!c3k6AGPh^)BYaTqz@>yH->*7zX
z6WVxo+4C@keg`N3&4$%|nY+L?{5o~K^&G1t$?r5??I=;kpEpm{#Gkz$#Jzp_Cv!0_
zfl?Zp>Gm^3eRLt`W85l0-_u!JVfXt5YN+3zmu?%}rfSR)xXQ{B_z^Loc5U}d@jzc1
zl<{*dTY>~GOse~-+vI}ccwesYz!4U$1ddYvNS6CE^R`ZIM|gAcDJ7<itAn@zipk=A
zW&6OyS9RLp_KTV)%r1;-4PM+3S?oX_Ca}JrhzPi;X?~l;Y+7$~Qv<^CV!PkqL*|l@
z8yggZK^%6)B|Nh^rLuaw?8wO)Q);xjSy~9Rx6uzfvD&nS^Q|9TK2SVLlt$#9VU~T!
ze(trKye^cJ6Dwlx4HgYckg3jlNdd24Z1s*e*-c#{;zR{w;J*F&K9)KealxNk%{~w)
z*fnp7{(3N0l&ev?sL6%q-5b4MhT&!u10-cdmTa`S7}Y=f82jQjbyBr6<Q+rITkI0v
z!i0{cka?#7E7~Bskb%EsOuKNtdafcG;^Xz~?xfx<4!e#Z1P(0v3M*`?CRQ&6+`1#2
z|C2XMm`OF)@_F=wx&__Wb1c%`FFCzF9aB^{Cby~Tt}#1}_hZt=@H$YV4<)sp!Vn8)
z(j%0W1uEDg8QMQEP^`Fi5j7aM!}&wbaP_%NMImCVZxUm<c_OD5fW1Rl2r6$0;-1<d
z4;aIm#-yZLAkI8y4M~nd^i=OXxd-}MS7e4guCc9ObIAbJ;>THk@U_y8y?8=(FvsPr
zMU#ohA^dbYL4)Rcv2GP}iLXn^puhkAd1h4++_YRFZQg69ptd{`$Q&liIb&Z-h+=yR
z@_09qRSWthUAUwTtz6Tw)MW|zUUj8l>t%@Qovux$t?W_hu&M2bi1W3^x0LVBVy72m
z7ZUcCv=c<gw5dBjX@T}5{ZTb^#$f;UM-Hv$pX-loJK_FlRG<*7(%X7{>(CMzD9P;C
z_#^VMr%L(shljgW40dW8goU=Kg#kX+r00!R*M5RwXmr~uhf3H@Q(Xj_3tq|qm*`o;
zVI}l3c@nIU(@F*3bhIC5*lA=hC|C$OmrTa)%kUWXg-=6KPKAA$3=iYJP1gdHDJf3|
zbRMGJdpi$q-kX)Zewt7A%KUY2SUrU0VQU|gF)zO{nas9UNSYhu=i1>Eyr4Q#Px-Tv
zyh|>~X!5!>Bz1z9)>b))ET5-mdP7iexPJ|ZHfwe8>#mSLv?YI%>Xm-@AG_!1vx%N#
zv^YI(Nl8yY_+~7PlgU^K7K<e?Lq|SP6lnqX&XSny*)6kAO1?@rA<R31)tvNhPyBI_
zB{jgl2b}H|Zz6KMC2G9VXceBc9@$$Z4lj**2PhHC)g^J?jPUb7g)cSu$Ko6+Vkv5A
zgDL22-`_t&N4Zjlbi=CC+jJ*MIb&0Bqab$q<E=jaQnRf8&R-Yqp4G{=5(vFN(NPft
zgM*iISk%|P=Jw-n2+dc(rS*d)Td-GKvI9f_#2Y>8@CRQNt=8l5z&qjhg7-fZeU$i@
zU#3tV4#&B?Jk8NZdy2#KL1E`htKR1_ztw)9xi?Ja#J_kK#-d@t{5;xND||Mv?`;zG
zwn$v-lGlz-+3SMtt`OT-8FNkN3s`V}l0uA;I4%X}?~s2AOnL4`7qL;9X1%|AxkD=O
z4C`K$Bw?9bH^#og=3zeINY0DXgQNX@;QLE2A<P$DpAxVg(Lt!iw)r$BDLxbw-kqnQ
z<&&k`s^~So7IkC9Z)v*N;~v@=-Q`YTi*Ww^7?bONYK!Pq`;QjloYtQa_Sk>BX3ZAa
z&-Km2n+il5Tvo8P`9cOu$S2;S-Q&jNrtC~H{~R5xB7KIhC#@8ixh@CIR9wFqVz5EK
z`Mq3Rjlc8qG@qZg>ETk-H2ogerAh`dYcZ-mB_kw=ZI`}kogpew|I|f|f$98BRA>$)
z?A3_-Hu!fGv?)yN{FiZHu*lxn7Ya5nGjrOTWP1{+Y%D#}hfXQ}ak|ynvikQ&BCg8X
z2jX~B;uS~$=YKzDL;>w!KRC>3v88rnl3v6tBQ#E8O?l(7(+3~JG#ZG_=YDZlJFm38
zE#h)vkqEQqt}7|1I1YV(gfrO|>D=_irDY2A+vP5p#l>Ta#+lyy&efOZES~&!C1%M*
z^7Hh5Os#B@1H}Zd9oV_C{H|#RZyyaVA;_T2cb06Y;{WSIhH}Q&503xVhI!}a$f1$V
z>1BfeB#ob8Nu9qb^5=Q!VU*GZ#95Sa@U?f+qb$DZ!W0mh@3+d%3xN#=Q1}*UA<Raq
zfNSP<&yr&iZY{u2o9-|4y68J}Hz8vTnvTjPdH*{l|2O$z)Uy~+&>I8!)}or^u{D+5
z=UKPKWY<Gg*Z(9%D8B)AJ-M<;{hOahe){k_Bz?<ByMIb@7`)V^_rFR{UXc_ce!rcQ
z(|kphy8s`xsA;OCc(TeyMd`COn17Zy`7LA=%6Vhik;+DG?xFJNVx(S4nbe+C@IhDT
zU}<;sCo`a0G*&kF)q7g-w@5-+<EBI9ca~e3<I_^J$5n+73T1<S95ek&zC2u1<E9I_
zJ{zv^BqGYFtj;dsD}$RinnvM{Uq)2KhHW)rD$S6z{O>4O7w{l^r&5h!IyU771_q|c
z=Kuh&z;4=)`yU|7yIhls=K5cZcM$k2o}Vtht}TpZXFAf)+<(8Hv1nv*aen^JR)KMd
zC>1SZOmMaSL!P}}IgY&jW6i(YRuUzC<;`yRMkY?=?4jW^mf<c|H#VTz5IL|gvlt#U
zbqJiHBr$<kgv8zj{k%|oOn-ANiR<BnBIMPlp7J;j5HAP!bnqI3`E<`ydXYo9jQ1Pc
z<nz_R($BZkR4*ygOmsq<SBzi#fsbz9y{Ns(rUNli_K*eC1&F$YyRo?qVDrRBNhy@V
zM=W%pFq@)zS)$R?w$HTvt1`h^;M~E8P}RXmryqb%k`(I-8}F85%t$tT?ao;v<?scF
zFAYRpaJz`hN1q>4D3o4l0L;dgUb)B%X+pUN)%^5P>|(i8S5pfkS+}4uuKkJ3b9<XA
zBg4kB;pVfzV0I`eA}#9pL6+V#(h{X<Qkc143{rPQnCOvrlc{+va%lf%lrxLLzifH=
zT9$0L?*?@{rAq9aznpj*G}qlad~C2D_D8IIRD3#X{SkarNv(KzW9l-=YTErw>G{8G
z_e+d81tlZ<^E=e%L%{mQhTtrJ?YR=mZk+w9j*8K(!h82C!Gh9%?%rVOV7HaKv3Kur
zjtTN_Xn$1Hz_pcoj2i`>oY~~30|J--d@phNQ1kDr7kKC7tBb|2Q|o1u9x>ME#%f><
zzLoq$pP&3AUu-0LJ48~BD2l@EU;7t*)T5g@-a8+RGJHrFJ=%o|WhKy}F$l8D)tJc{
z*^Rztv^*K<>c#<v>e_4zCjhpkr>UHfFTDr$=@6{9F8eoGb#hl5M|zo3@Mz5R9qsgj
z3-NsaSB=r=*6X*|wP6#~yHfX0JVeXKIistqYv)cU6Qka{fWn5`qm`2$4xeqn?aCf5
zf&`4^s#Y6~xg0LLAs||M*t(()t<EnMnFs6zL;`7YJL^I*eksY*3cFRo<Klt_lEKqb
zN*mGVtBJ{NBb;DGKz`(o_GA@obK=5cJsAy=CH@NCuBUse{J?I8k=V7CpA2}j5xSVh
znB$y=CQ7u7e0O=cJ@$ZJ0|zGrrb`>ueo)*--~6n{cu+TORGY(<)*za#{7_ii0hn=K
ziQo$-l4j-H8<NxrzxZ6%t5Vdz;AJ@uTTtWDFO}!0MsHk}{+F@%YC~YJ<>Lt%8m*>!
z>C$z^u7A0@Q)IUxwYbKQ`5It)@(@QoIItf;8~Ls)$c+|4AOLEZjMv-BdEc1B(blHU
zj6$7+p5UR=wfKKP&-qP_CvOfDZ>%x2b*OY}bo3!|Cqj+CtQc^`b-aAcb5!WSW#WD~
z(>nO{TLt;_{47lEB#qt-Xo@$r&$>^`+CGR_BFh;9KVTqrzSD?$+WQ3hksu!Q2n|fv
zEtQ<M?z>nV2!K0;Yf6#G@uZ(+($%-ktvVu_i^@{>+^N1*u|0^vI~Yx7(eIew^7tL_
z{ZvThJl0-qwe%A4is}W3daVj^e`<kW*MeT>+moxu?fZ2DNz9&!y=)d#%)0Ds8ZWJ=
zG_KBI55U>)CK%(BcC-uiP|`(7Ny#N0OM<?U0~>y}qxir6Y8RW!m;X&2$(U3SzYtLe
zOTNTI|L%y3BMvPuZ-8VR)O%=8B_4mu>GF4cW?{+IPUgWCy3JcuHlH98LT6R?1WZaa
z>yi|*;9HW1R|J+wH%JC{Y@!b=9@+htPFGdz<j`ai1(K1nH`+K|U<y)9lMw2prEY;+
z&%$HIcPj;^Ygf1qqqx!MW&y_rfrl-N%K-~vYPqB1C;ThP?vGb)iXTL)z>T9XFDYSo
zA*Hre+nI}PmaHsmo|#3q#4i^Wtz4fXFN3*Cq&@3!ZdETECM2-!-P25&jCUHKA3Wrk
z#o0t<jZXl)hs{$|UnJL1^hKj(kNf$BX_N>OR_~NFwk1>t;@W(`m+%PGV|ir;%=R|o
zeqI3DHb4?5)Bk2LGJNr3b6On;8t)&F<GR%Ii|<U&c_h{Wzh;%%kgi3*tShZx@`k_4
z_|$=y>=0nE9RNn=t_pVSNCM17z666QYvk?vd@T(ON2`qNMmB&395o#-_(7Qo)U<7c
z!-fK>teOj~XH2QIFv3W03G4cv$Xo;x9Vf3#J<_2GX~Hzs^h_!76wlo78!!A(igayW
zAGm*Z&)gUAo|T^2cl=SEQP9}>cM#EKr9R{M?{mkrjrP%K<)H(A{h<%_0MIf0^Y724
z&4H3ldLMnFFEAvw=N;sz)AUH(A+u976*eW)-lLjw#VVeeK~x(W2o;(#E3MHDs*zE1
zNR*9@3Jco|&IE-hzo{!r*vcM0eNrJWcrv4KfnTjHR|Aeh<gHFTg`$hRIGGz%i9T8?
zml`FXDjQyn(Ryy42OsI42~2;~P~$mPpQbW9v2>p`S{(Wfpfg3NZRmjBSJzd3Uc#<C
zP%wJ`&R$AMs_p&tPk(|Ky#W6r19!T@Qs+`9fmUh0lF&JF5lp|8$$#GO_BU#P0_u$h
zMX5Q`9;>XX|LcuDC#&110(y%?vy=X+v*!(e%8Qs#2LsOD0hJxBbyhDSTBsPRqAkN#
z`yvS_TttnbgZc({uAAQ!d5On6PbQn$237%HD#0$s&s3YkMag|(y*5aew?9?Po_;C7
zy(1Yq>snsh$Q^O|x7qGDg><dgvTghF*4$Lov)wx!)xKnT3=^x$tB;2Rovm!7#2q)8
z68Rm&=E6}w4(0R{jyFcNp=B;js5IxZ%Jf6~WTB_Tz+StpQW_I-sev2d@Vx}2wgdc4
z>AuitNN+*-d}}UmeIqIAxyzil%lXkEf3^HEajoCzuRXn=dX~50QY8OTW=6pkOU6lC
zADrgJEl$TCb&HrS2pjWN&)##_-;2Lglf<|alHRg0TYdt6WbmYu;#G9~@V<H%!5{2A
zDeVbfoa&_5F$j;GkbDRG!DnlypOwsD*^KP&LyDzEx$-X`-J8^V<{ck-N@{WVVO!&Q
zc1Gz0`XB~^jV1UYrLGaLMpGM?JIV)6mvib?5blI6MSIGC%Uhw0Zt)~bBr=W0WawV{
zY9RnMyiJRizmci!ER(2BqTPBXF)oT?Q%s-opeA56(0OPtZmIDeosY@^io8dZe(Be6
z7K8gbj1_by#4Qgjij>%FTZa1tecmW?tn+in#K+}3{q_G;wSpYDbyNKl`RdW-6qaEG
z>2J8eZ+?z;{zma=&MUiMPEhvw^G00;51oMvy&84UQ;;yV4k+7GLsr16Z*NUd+Z5(W
z>qu)=uL61}Zm{Nzrc%%gj}I!V4dI^5BR{@~T0ZXYWI_bjl^*&L`JF}U=E8|VFY6fb
zR<JJwwuTLyD`$ddk*Qc?S}TVJ*J^RiwF-bLSn%G>B@KH^wqOz==0sDF1|=Y_n)2Lm
z0W$l^rVW^*mA?@ICX!$Jub#fSO6)jeHGm=-vECho-neD)MyfgB=Km07QY17*bjqkl
z-01KdQgmpE`_~yw=^VV+@jZUM-q2Rbu=POl4*s!uQX@R*fgb-)OMa{*zm+73*kU9<
zAszRA6~Tp0x74f9W8Nv!GiLyU*uCP5E22DBIxjJT48h#yCoZ?6=^vsQdcPaPXqxNo
z-gbOv+k!rA&YRsy#hAAqI`ro3Tq;sm1qjmmrrAxG+?lu3k(o4V9GSa52Vm7D7AvB|
zLQipn=eQyKZ9&_FEnpDXugo7d+>~2Z5SrY|riBWMynGiOaeD9#YX=Q1+aRCHT-Qd+
zrL_~9y*~=J-3Y6ZSK9!mJ$^fUX=fA9ZEB3~_<Y`32L(NX4h%$5&JK?~xznY42O>jM
zc=?W+%?xapGJFeGVqv>Sk%P;LSPAyDK!W_j2|T2D^_~&Fbn?h48dPpFZV~UFtpA~F
zG)L_jLP6<MBvmg_^IH`YVhiz|X3xo`;8H_!?zuSKB`|B8Vn@CWk+SfjnPGVi>Y#l&
zro=|YL^fopmaF8TyAi|6naX7qXWL+*d=e-_N0VP<AY6%}zM;9s>SAuy{rfw+R?;;f
zIb&z7VL?fJb4&oRe_*jvmxCP}x-0AHKfTjhA4u^|mIjPJO$T}gyG(Y$xuB-iJ(=li
z=isE7AT2{l7?k#nne{rAU#>!*cQ4>6lw`n3jf8aDzPjEco=WH;RI-Vp{F4g|vMbSm
ze%t$I@yykqLEW~-wPd*z%a{$%WNG5WNLSRxU^@>?pBf@-4v|UW61`?<y?^T!{#8c>
zxGmMLXupX?LkwhFFmT_RQwD#<P5QQMbw|RIRV}e6wz`9`aN>A>C=;9kar^ip*yC^W
zbx)Ht&|}i)+v~fp=^f)qh7*jzaD^iHp?5Ovu@NFWVEFOm56C3uclaN0juwhpE|#P0
z;CD0rEyUs_n7g<=#^S&5^`4V^yL=E+!I9!*=9-q}4%6M;-Ki4z4;A~~@BO;F+#9@=
zd@VqRzFyi34FFvmBZVq2obG~Nat3}y^y8I2#lDlmTOqv>EpN8Yf?Uidgll(uo43+F
z|F@>4ThY282l4#6pr&$!YZJ$HB(L~SNwcHa1d0&w@fTZJk~#Nor_dq{R%~uqs&4~@
zhpV8a??sgHYby`t>X@lCSD8AQp4tD@VsR68<VasKq-gA`KvBNOP|m6*c`>K#ftG&a
z(yxb>dv-fIU6+-aPgX`9j#bbYv!`b<UwtEg?mXM$Uq(?_en$QLwg9V8^^S%+`|EuS
z<!UC{E&nMG+cKOw#ch$~(#a~2CtJClHJ*`wqXw6g4OKQ|n8Hj^`R4xrwxa)y`Z`1%
zE<LzgRQIc&?wvGvDfqu0u94J2-ptiN#0WU4pxj}yL)TmaG73yOw-++sx}FFJz^Kkw
zp4^C77tEwyHpc&#_Mr-6DTWXEjxZ2cS}XM(upKF8O2TTyc4lr+PGd+LiC*EwT!g~F
z%?wY{r>opArd12RUIA&@*2hZM%o@7x5VGp3&F@qF_L|FFwoCli^*aAXM9B%ZTl3=n
zz0JkVZ&QgP%+VekgS!>Gp$Eb3IR2YWCGo>Yw-oTQp!YEO0zckQrs2MkF8mIB!QRJR
z>K-x0t16Oy`r~!Q+TQ0XnRa-AU!fTUk>%sZa>lsAb#mw($Sy$OWZk*bum%^YQIa!4
z>VFq>Yjs0;SBaABQMnksZEct0|H)wVMc4-~|9R)wComsT06ZuG!TU+hQ0IolR6VHH
zRbMAJzfT+|C*h~B^u+Cj!s|i5rD)rwaY0nC84C1BQs=V|j-QnX{`uvM@Mv-5#K!lj
zZ%W9N&_qLs4Q+C5OreGNeVaF*G{R}zE={hl(6mXZe2!LBJs+}s<}&uo0sAJKDQ=9O
zFhkG!Lv?L`fO76P-33c=N$Xxm1c>{UwnP_4pPu8U|Eq6sr8ln?1j16&Rh?JB1*5fu
zVEJ0Oh@y92L4&%X87!5+JzMit7qt@BpN2n-Py^Suc$Z+kO}1?63YQ3}0IpLjaUfAH
zS#!lLaM*V3lLMM$bJv>lhfxl^$5s+}eiAj|&^$OoJ1ukq-zL63rLNObO8wd%v&5&P
zE7JWL1Tyyxc>TlXWHJ3_{HqwSZxshM$d}jr2ld-m*MXr`g|YC3W1zbHa2Uu=0!)h4
zO^Mp@sJRKt3Q@IpzyG+<xYdL;YNYspIb=Z%ne8j8&uozF2J~q5EMZ}xz>F+?X{bj3
zf2k?E8I9B$o15vUlK%}HU#%ojj#e!);sc--RiEqg$$@2~U5rDAoXYNKFrj`Rm3%Mb
zwy7uS9g@;#@|o7L!|jUDpGZRc?I91-R+%~p&cp?g#F{v_;u`YdGxSc65tl^s9ZY_%
zPRcK|e0DMd>0Nv!?=P<1>X(8cnLMqIyEd-mAXz{@6{XwVSieczzg2o{U)g1}b4qlG
zW~Ya_4D(d}JuEh}0DroOJGsqnwzvdiRwhTbX6ew_R_J%%cTMa!+P+`IC@L|*D<_<E
z^Y_ZkZqNf{e}K>6vbw4&Fy!uP9d$9=^IqB^d(Bl+=`Q37+ks}^!b{P`_jK`ZF_y17
z#aN@Qs1|7&_>&kfUtg8*9YT8(J1c1A2<lTM$Di<v9Bq)wKyH=}d$X=;%_}i*4v?d{
z(#C(HBXBNg?Wh0G0zeIMed-;+q-?obKWF*}x<<o>c<{AWvfG2zkDJCKcf?{J$(Xdr
zm~R9pHCRpn+TK1UL-K`a;YO&nGoEe37K+I&hG!oOk2H07lHSZQT>w~*l8<q(J9?Ud
z<43q^3UAw1&(I10UsT$N_3eK&0G7b37#i4efLwL3z1BsGEl8j7T(7E$3R@~GB2#?B
zi@W|?SDV2}`#zNomNrf=I=sn$yL`DFywd!z9NKX>|IHvK??gs?!SY~#f4^PJllNyE
zmpeIy|7@kS(=6N=y7xda;M~WkCLI%06Xv<EK|R~E*v;sW7JZ)H@sA2skd-upbXox&
zj@t~8JW^`kKH3zLf^VFXJW2WAj<pj40DOsG*=@n(E?@o6){&M4*>F@ue_3~I=Z7Ns
z>L?fPlvztOki3W863z2ML(v)R`4~&=@-4zq%*jbq^P%0G`Jba}Am$Fse6Q@7t0?p3
z-QYz&4LeEgaUI$Zok8xMCSJQ2KFbD@cUY#)<QDYHr%?H&W)o0Uc7rAgBM&Q4m$TwA
z<=ka>QSz8gEIIu%mcMEL2^tTpczWL}POz&PxmH6u+!-3O_l$~ms5y0RYvc1bEU1W`
za2EgkVkExbV;)xFSC~1v_59X`(ll^u;`(fbM1$Xpj&K*qe|>R#<(c=V{>$-17XNnl
zMWeY}ecf8|{=&3n1VnoUWw%@Y#OCEC!*15MH;+YxcrlN*4X8}shOjFydf2YsqtSpu
zQHq~#q8yLkMTg8?9^l+7dJK#>Z@@nH9KRDmRd*<pwvWTn=&qr0hcv&!n)wCldpHQ3
zyS}vj+1-BM(g3x&|D9tWoZ9?&E}3Yd5qcHe#TYjOsf#6qb&_Psn=cSQAilB314vyu
zeI@q*^~G=DVltbVibD%MoCzs)Ec!?&&pwtFa^}dCxcKkgwGW()LTk0liHW1lo;&}(
z^OdQ9Fm@+f4wuSCfE4d+0H|t`jn&m<R#c{eL_o4<CsTR!nLD!B6E=8pf!o@m6f7?}
z^NwzM8M>garO$o+9a^^bmc|1Fq)zkBB6{c6T))L|v8**$3VnW>YVJ^xb+?Ygatr~b
z#hH7tEGXL`O}NnVj`P=FK-sg@m>tx+3Pn0%UcJ|_{`O=7e)^whTCW`sw>#t8SUB9i
z(gNXX2ROrCG7>1+6Dm`6dD4hy_RlyD&U<xpf6gTBM{uvMspP@em6lXoz%1W>ch$?M
zyvIFG5M?ClTj5q;Siq8vfdDb@!@V(&^C}>m{PwMXJe~qeHmV1`_CN*-xS+ue-c9o}
zV@xQXuQlb}^vPEKp08{w<(AUo1lCZV-vGYKzXM}+{_D2{0Jrc>2mJ3DPBhCqW%tqm
z$`D`yDF6=6K&oZEw3(Rm?rp7SSmXsj+*+-Qj+&1?JGd5mwq`u-5FLGShzG(i4$Dg!
zLM<OEVMWZvi;~}NIC^}P^`%j0w2{JmLL%9+Vj7*HVp4x=GHq=34`K0VOs?*Xt`9Vh
zDR}e^$~zSSNd_^+N@i0o^Oz)Cmrs+|Z9NvIsJ_l9R+Z9*+1woQYkGhGnQ_RHp4;<%
z6U&l2Y~2Ol_hnwfSWTCAhgl8%|AHLL+#6oYrb->leRK`IG3AA}DBOO`tx5gR)0*{j
zTgWzLU<;vh%Z2wY6*RxJ{ikv=zMZfT+F4BUdHm{A^pOwM{)*$vY#&~R*On|)G6J3G
z%Y)NXspwNY4tGPFE5V>XRiQ8X?}b{&8zIr8NfQG@yqv0<+W9$odhmST3|0C?#&Br!
z#XyF;c{fRQ`|S0^A#Qh^lLlO_jwx5WaDWVlUj&^4W%z%GTga4nC#ddXbWaL<tmRmn
zjm}IbCF}k%|8U7e+Z6;6oQVm`S@lVkMdiwfiSMsWRAB~(KWT?mB|a<I*CRN(q5nRN
zyd%c(XvT5&%Ju*WsOpFs#>mg*7f}X|1*>zH90rrWzE$7$ouc^h)^grNW2CuXf3(o$
z)xqS?X=;3hS?kceHCREoK(l%7#XANsE-3+WbULUI1o`Ikh)1fU!4*)v<4XgH&@nT#
zIM2x1dIsZI;*e&9FYV#n*&#n|<1xc0eqEVhJcpoHH*FrZH#1A`8zjjwt-%~-?OYs?
zQ5VzAdKb0%_jyQ!a_RI2P+<oEpsu_CVe?`Y??l965Z-U$&LZBVKW7Od035owW}H&9
zOZiSxcr{x4Z^dsJ>y1xvh&qLi@Vf9dOV=t-liR9Gud(Pi9H|1;xbLnUN!OoVy&Z!l
zApSfI-KoUd$YwgF*1ao9<(4e~A776n{ko0$$#44Mx0`M67nwW@n8fOXJZLQ)*K184
zHxaW!G1*u*KqH>ugvdv+$q;Z3nbP1VR_kikGq<zPbzpmXU-=S4i|}hI&kA=MUTSN<
z!ex*86>SWsAs)Dt&Sd0$=~z*K-L?ev2^koDsfEFjX{Nj(yNk94P(8jMOad~Hl(!UY
z;uVnPga`_hDsG>Y@`X9}+J_dKJ1$9L8h-Yh@gkq5<_g^^^OM#?ji7c@+9~l@seXm1
z4DdVXMpd&NP!<7i2~AVRp+RZx6=ar(VSs3S%}2t2(uCTLBZtewXgR}&I+t6~7iXm9
z!GA}`zIZl+gpzsgf@iy9iFq$US6>%y2Ti^DmflF<LZaXeaM4#ayTqUIjD7(&c{GA%
zUs!j%dmeYTX1P)Y4@O@4RNxS2*EDGL9BDskJhgj*Y<^|XM05hD%W@PHE-f1?J=wB@
z(P@gw<vDWJ<o^CmG%@*GjS$m*b65Y?lO=hE>s{2EY4gg(8zL!D6^8%?|1WrUGsNlj
zEeMMRI;*?78kFJz@p+x6_f@Ek+M*tD>+w4TvR=jf#~NGmnAI#6trOe=+NA&QzePTi
zCgIe&rVc&xJ7Qqeyr_3t(2}BW(=2hXl2Hy=Fv<xj#B1%h+YHH|@1w1yM&!-&D7A8-
z@$4*M6rgz*GvZq0pFDEKd)wjPX#spfPND$kTK2=x+=x~w4<W|m&gXCjbh^l7{N4YJ
zc@<-I(Nnec9QhAJ%iO&`{dO_445gKRLX80jcL`Eh>$Q?%bw5NcUmoC%M+!ZQmn2)@
z@1IgZU_J1ZW4`q7q0U+?Yx)<T*?;s7l{_o7bYZR2cx=o5)~``dp`c5AB-F)lwXb!`
zUh)ab9FHw8S5IG6{7A=HXTD-!v(rI9I2kF8yy(wpJlB&JA=H)5>LHPNve-E|(xR^J
zYjG-dALD8;REp|})xHXg{x2Ymqe8Jf?t{ZV32|6kVZ6nZW!-9KM-`hl!OEO~no2hM
zt14~}T!A4#{HM5LO7H*hG4Z_e)tjWMs;;84oo<TCg_Bq6uL+9#ogGO~YZ%S#mI1Gh
z{h`A%N`V<PxvSb-NB$o0VPk`Ma2q$JT{ryIb968LRQ=zoI<N||eQgZNYO{(`C4ng-
z!`r|dZNXr<(Jq1%Dmq;6-QWI!l8}@+3LNE+9WIZAHpJz?Xf$G8>Qw|e;xbEJRSKZ1
zOJy2srF9VOB@0$J6(#VhS<lIiO64t6-2=OplA*~!+4Y6;;tJ&*`pd_kz)Z3x)GY=f
z3t?q8FA{<Z6$>9M#WTl%T_+6mhQE`TxvQEm0q8@S>oy1ecsaxaTH2cL_fy%5H(amH
zF6@SXW>0a}+Q;U>4e?>CPt#>LO5vJMU7k&CO=-8eE9lQx_?l6RN^fLySeeY)#N3pn
zk-427nqlTcn!%#Gg9U)W5ZXjhIoJ?d(A7;uD6iPdg0aGTXl3S!sITwP-U&8*TTpwZ
z!n0@5r*=lpkbH2U!f58iTVquR5;eK<f@(c`>z+jSfRb+?U?E9dTv;JY4XUWCcP`>u
z2LFYr@Hs5&>1+p0+Yyy`evTSI!FYcahkz-JKfa@Y3`p5NSRYJq6BU=wj0gKB@iK-6
zFkMb_jER%iAH3v~P`VqReL8JSI~OyGfFXBOmz(4fhp1Sh9&MO+@6CYWn$6t*vWZLo
zaYsM-M^qL{l}3SbnSItApIAQu1TvfJtg;U_3TMJW&RS)oraFD*UK5)Y%LYLahVm{7
z9(AljGj&AM6y_MYw_}%eY*g`tw2>0YCp7*QkL%$p|D|YFST-T}70l9j&64$lG>N$6
zqL*SaL|eBqx2w~TNhO*u5-$1$=K0X#bZ)`h9i?jCCOpDM<_s35V=x+sHLdSs64ux_
zvK`;#;_*#g{bJK$aWE-Dw~{xHl}bYLl=TJ}FHd~d56z32QLgP+I$R3B{QGz2c(JFZ
z&g5FBHzoSK{1V_uofiDhDRjBhxs3grjc~57yau@{%P|v;s1f=IZ-l#+*2*(I287`i
zJ21`-Txg24sRgV`Aus8gMP0`gip*QBs^Qdu+_vGmfT>!%sg`vI`S|y9fVQwp`JeeU
zap+~z(sJhLs`N-*-eMDt8n>*pfS9mwT`OxtgS=Oj$%7qn2pr+8zp*j_E-uybqb{!1
z!nuOp1{S1Eh%BDG4$!OVm`wU5zAoB%;f3tdd<5v>$2g0!^5l(7xXhovnMFt$7<sbz
zIzSys6Bh7BE-%TfCyi8V{c=I#Oz;#smXA_Plo2IBCb<_PSMuXGcF<LmJ+FC0Kvq90
zFYw>q-b|n!zJ7Fcv>6G`gU!=>P`>x4*FU-|Mnp>syBg{gkX1gpqo8tzQ+b^J!dH51
zuY3;S40t}34~)v~juLT)cc{RX$~QSer{+CsbH6McL{?$!;^IcvPJ%u!@Le}1$f0JQ
z-=b<GsNJ3DuIV@v5**u)5lVmL34R+d685CWqio~T0aAO`SEalV7~C8LtQG3&08as)
z!s*X&s*lx<R<R1M{2hD0GE?hrNBBI=#EH22qbc33?YKqJhd}@2h1oM=_|&mNYQ-5J
z+jIUr%tr>;*R}q~ngjkw@cs13$c`)pvG+Wsy@sRLO&#0i8}up@fJ$4Bkv$zt5tF?Z
zkM#MK-y-iJXT;_$z)V2ok@k7F#7ZjtpA9A76>Qka1s3qyRgKLayQ#CZ%LJTYx;Xar
z9W+1T_W`h=%=Odqf13pW?1`T*%&#y>y3A;Fm0|+Rl6YnLG~L||#TZ)yR{Efl=La+w
zOdpNEm46-3Z%<z|B-F1esf4P|C0r@wj2XW4wClb1cfv9T9w1bg>jKv@Rj{Pe=qaL4
zX5R)RpwsG?=XhgvPc#7YItC8YK+egRLbzNv_jYF1`MMxN_t@mB^CXOG7k&IG0qNl#
z?|s*BvP~Ry=k%RvYXnF3U*S>JktB$Guh5i%nGo1b$qD}Vl{2^2m}{15=baw!cVk#^
z&azeG+OOT<-tZ9D2NCxNqXKV#CL*?qQRFw;iOc+S*5eP{%gdv}P7e;w&zZR&>JV1~
zixRQm#M;Qe_D*+9K6KVKS-s3$<#l<SRb(*5r74T7iVJ=t4}7Uu5pkQqsbp~QI`QOe
zhc{wyw>)mQq(-n3tK`AHw7hH}OnYzSO@<5X%f1veFE{%gQWUQ^Fp7dGq8>|>?)y`M
zPuF?e(xrhX&nCyqVSa_k-kMeZ%jX}{8?!f}I!Tehi16uYH=r~r9smx4-L}odt##*p
z&7}*bXu-<Y@>ubP+?0T{Iy6gK0bLcxF<X(p7kY_u5yb?mtJ_kp=*ooyDI5yrfvM0H
zPYonm2BRObLL!kiUu4Ud9}jpI8w0hBzP?;;;F|KJ_24y)XcnD+;?fodOBctxhxlky
ze&58d_@1dSE4vb5UG3h(K9Xhck#a>FAz?`S5-0V)RXx7WVCDZdw1_qW`+m3@)4CM=
zzJbGVmf2KNNV1iq!;&BHo44))HFB8Y26^q`P$eTEC24H**sti446p&YwV3@gzRAcG
zj@djOK33=|xhmAEYmWMf5Z;LGqw_CfHHAK6SI|x=ZQnbqc`wM4EQ0<MXS3Vy=Y{Th
zt>BRs8Wj~48Y-h#KD9e^uWxWL)%%|4jNY6k?W5Sk<t;@8XLO<3JrFs#%b?M*BN!`h
z$s%-x)$z_p;IjRDoYS>QhGWg_8Hu2zZJw`KtpYVPY%H+aaD6Umg-m>THn2-6<0AR=
z*iNI|H0*ywbXStGp4za~w>vyf1KW8}xvb0EME{2O$)X3h3~25a6~mzJ+BcNZi|I~H
zrT7s}s!1@5zG?pxB6F5j`3+zpKnF9me^cJ%o{`r`++W?6b)VbC>m>@*>`Sl1!OcaR
zrpR&dQ<t>I;9*See}|OW*JcByRh-fKFTSrgMMz;SVQ9Sq46II7RxGEp3S{L1!&oL7
zRak=4UZ%_{`3-ED!Tjv~r-X#Bm~+3hl+E-k*1<TZWsTU5<v7?c2lp<nJpV;0O9Ix?
z(cu<AFAkgL&RdNlxqTxaoKDfQtBKbVXA`B7*=Rgwq-3)BQ4nTQazw<NIfhQ%Cf~Je
z6d3+@4nqd@zWI!*wuLtX1EU`$4aIDrv$kEVnszmzeb;wed@r|JE;sx01Uj3y<V0QM
zo=oHhKp7lSQ_I4tr=}=6XTCL^AhdV!$p0=je!Rn9(4O2HwojBtQkH?gyviS-d0zV>
z&f}7VI}8J$v|AFL`))U=EugMV&f|$wn@4X`1#^C8G{7sLgZ-y~31>88HReyRWkYPp
z_SmhLNw8?+VUo)8YSPKS+-17Q6K$p4DXsnA;sjq|=L79(G4>pOOzrT$Ewx)~{zVNT
zTDO<Scx1wT;6N3zx}Q>hNnWmg*lj-zjL$}>6~KF%PaR!aujc&W`W$^{=Noc(?TD=f
zG7mP!3)RHefwD2+JZ}=v{9RD+h(m~lrca7n@(&9&IZ^LiQlc*($VdgW5o&Uw1*?FN
zJFtv?{{7rrA&<6Ub7z>-p^yahP1Km0=vF9o2dq;q38bDcBGv6}BbYJ{gGtUbZ&eGn
z6QWwIoZoAiV+h8^nbD^>K=fhX)7*PH-8=xRvuZOVym~GP`F{6jDVg`Cn`E1#RHO8}
zrfXgR)Va2{_9AL@a#c|h_my_5RNI`)Ti}{yE*t73lQrIdu1cA1DMfrfS>~ObIn|Sk
zQL{qNZoUYMj&^n9pTv_Zc8{T`P{eX>ZVL635Q;Qt<q2L`bc2Ap>;e3&Z{pAjV2=E;
z!{x%8pt*hYbhi;BUWjR$^f_@@^w8@>VE#Q+&SyFZP0n|0#>q(eagPR|oYUHjc7u!!
zR{^Hb&`{j5B~NaT*j)i3anx715U0upKwf9w?P=bnxMuu!J6<mky&UUaZ&?-i3!vbX
z%6^gk<ag$iQEQIJ@KiNcH<<<+l1^sS5B_(5*~o3{Tk0AnpW1@&8{z>nd~w|{C%9gs
z+S3xI<XcvD9eCrWqyLdN0Qa0uq5DJ;b0of)Go9Ij3M$lK&hmGq0w{g82PupwN|3RC
zZjJ5%Ok{v4s`DP}ITSS*9x``KF+u`-j2Bv>TmndRc^MCqKgpx)BgZ5zH1Dsqe&!Bk
z;Hn*TO}TV=dAWrsMurVH+BVtUT|toVahMk+gKoa3o1w%QlJsNJ6ej4`X!!W3S%!t&
zKkC?S{dm@h8Rom`cBJ+dwmi_k-g0PvB$4s&ScN3<aaZjfS#Rj9%#il2Iw#!{$5KGO
zEC|59BRWhG^yntXuS!HGPPjje$`6Wq^rJDxYlE!o_NB%%Uq}qa`Fl;7Ig6TY3-Z1>
z*T3K1RfWxS1t@6UMPfRVOEMmnIk{M}on^XN=;Q|6O6+EH<`CTlf2z)1z~-U-j6wm7
z*~&~Z->=Qnznf$;kAuJvDS015kEu|5w<1M_)OEXMnswZvcM9$vBhinU!h-akNEY<e
zE*|4t><EkY;43R`Cf7Y8jnEg?R&WGO0rCY^)qc?XPG8_5AC)f6cfA*Q^5~EA0<-O|
zoB{PWAo<F*5q3X-TiI?2R;>DCm_<TcZq-R`;>hk<^KvH!06@YKh4b_mCmm*);f{g*
z*YWoZP%p47J?kpdN-O~^Ejd=H9kl+peRubR-u*G$i2jO-eC_q6U+Cl$8Jtv<VxE%*
z?$G0+8-5yIOs{iYP%fRmn$v{==<W^n@jlg7F~seKlx}p94v)EF!GvdjYwT2YiAjIp
zzzEA5BZ61a{m!TQN=-{P^#a-A$LHq}ioB%(yTmHnUc`K82Gq4C!X{w0Bf$n;WR1+9
zsx>ZOz}Dv$ktut@Kjy=cs$+kZ7~?e9kjgh-!Y59#o6KMRZ?y~o^-E6pL{WnNNaM_}
znHM^SQ(OWlf4Ap5&ECb$mIVd|Yx?VOcN$ryp*q9Oppnq83I0V%hIr*IWx=Bx#zF;7
zeUp1{q!kSDhYed_SwodGYRU8SGuQ{aXeJ|MKPjG>QKS1h;EH2u^(@A=*Y#<}*X7j+
zTe*}<Uzy8Tt;1+l*Wr84YwB_r>%d5SsH{+zZ^@tNOU)p^7Pg)oktJrnryv41n(Tjd
zLP%<I4xR)5dvNge_)XxM@G)9vyL5Ty?Bd_O>C}4<O9MvcX6;(DI}%3my)icMA~+1#
zCGc`e?$~ncGnG?c>Gw-@%wNJL&U;BaW##H0g$Da?0og3H>uc7WeF)>aC$}~OoSY^g
zXFN@>!&hsNw%YfWi2}s-0Nt7)Il>}kf#A8w{24g9Mtbn`Q3|GwLC;nAic;a{f9HHB
zFR|drWrO=c|H~Y&p32Cf!@@k9$O$Zv3BD>q2rocavuz=UW}tHII*p;XGFu98rl9`W
z2YEl_gir?fIiI^<vSO?*SAi{?wqW<zdysT(1A%<AFJnZ+VWLiVw)R5q!~(T=EEPNR
znz;~THzLt{_02T|oeLWaRrVXS$|#0atk<ySc<XDp@857sf@<$d;*FZZBFA<uy8Ly6
zY=bvCM9h-XUESx!4F^G!7;l@GdVngXyqSpWn%vy<%>Mb@k**0~n4JwgS@c2u7Gr%=
zbMhvMJ^vf=i?kH3V+Hj^c{!ig4=)I|(6O}9=3Q$y@c?D`Xa5oUuEqEn!L#}%AfYI@
z-yyzzhE;4s-ceFM-fd%C0bQUrNJ#OBAdbKv|E=&2n0jkD#?Cg8)4G@MqaYYxv0e(i
zU%P`_@O&(?X;vClQsQNu@5=4lI`h85+c~WkudgSY+-LtopzRLo``(@(@fej$UXz(7
z!aay|?hlY9!q2_DVD-5oBA1GG0m*{28y1r7qUL~|S|T1U`r-aaEK~7S6ZZPziqE*F
z8hw<NY>Sb>f8!i@dWiFs4cl5I-(<hxIz5is)=u;eGN({hTS8vUvL}`RRF4H;$@BNr
zOnkJm5jDm|+)6YVQbd2$PkKxJ5=MDBDO9k!*XJFW#DH;{poUu^U1PT>_Q;*m`5Irr
z_~macIKzERbIeahyMhW}_sdY4?Yy6?eH&yl!i_R(W_+9O`pUck>zKsAmPs~&N$Umo
zE`_oOC_7{>Km_g)%n5$xZ^c7*fuJ+5?dw_3V%jJ}X!4D3hH%S{w#ePSV{;4GQweD(
zM8p+kJ{`cp<c`YqxK|p-TnzuMA|)-X|2U6+2=QP}KcNZ!ODg&wKQ22){yAES3oIz2
zqfo<wA(B@CGbEk^WWdIfTwy+e8iBv8cq^(jI*}uz#A)u)q?<4PqfX(#s_+`?%^Y~2
z@x!I-1p3V%i&wQlSANdwK56<ODkdB^!Np$cSsJWY08i2lqGxc#_>Fj(Ye^pxs5SIG
z>jH~vEM{HPUKo)6SV!H1Ao72yp1_73n@ES@r_|_KVO3{0FpQ@*H+z22n=~UAAJTUn
z-U0d^#$9wdb!X+<HoBECTFS-wvJh-BWU*0P|5}iBC*19dTaSHe8CO=ol`2&bBQexE
z``sdY@#v_)&3D@ly8k($<$ciQU-*3V4!>MQ5I7%`j+hdSbq@Upz^-WwMHVT6Wvq~}
z<x*o}$zulHKH*>NfKgivoKy&*dbo>j_wGcxq>(#@J&nkfV9t*dV(3|)&KrN4Fh_fP
zrcn8e)l<c<6DZrf25>rDcthDR_3?es9nVNXwsEbgYK3B{8_#&&VZA$-eUGbhUxn}P
z^>)zeeM|z!6tejEQ&s-33z_5RW1?WM#yrLdyu0!W_Gr6wM+-lujr1<NxfvWEsbAqQ
z^ud+zR=+>tI*tzLt`U?`fw8?%(?jm1zU&%;ZXkob{n+V?#fIA~RA~4_`ipAQZasCC
z14H~IdH>%(HAAyf2n)J-y!GdI(qeN9#x_xQjWu@bn-R$f%8r;(@QrOKUKLi(sW7+C
zvyJ~@R|L<_cbH+bt|*^=;xa7CDOK>nN(fwpux9)KhhZdj+_b;kpL>G*l-9N?H=^kK
zlRn9>XTYw5AOz$IhJ|Q(xU1yvSDbE=Q>E7d(emBO@8|%@THOjX-4D1KwIl8+yvff#
z39m98^DPj26+QcIlC8j>OV8An#ni6-aQLNc(tjaw%C22m2JTyk>RQcVc#hn0(%4%<
z$ThHcFW>_|2YP}&owu8REDAKbrcc~Q6RhBTE!rfkr2)vfKX~t3c9t#{^M)N-cd;U%
zav-F~#km$*c-sca^R+Qd6S*3D&HI-Y%rj+ArD-c-KGm$@OPwdW*0YOCJ0WseRXsXe
z>0sBO3|~28wPsma4swQ#D;HrnHlaLKTF;ZjZ5}IW19gd|-htiDpD#U2n-nyfOzAdq
zlDCI&`1Wh|$VlZk0P1CV*_hl{W}w-SCat6Y>n6q$RXFB>PV<9bV)?A6TE8j@zq$6&
z$~kQ{@SPDoGFLYpvE9pt0A^n+c8cwG3xwWGKioi6#SucwZdYPCUP{vf1^zs`F_w~a
zcza;8_o8Ak^EWv|=UiUdzaY@H7=0a0b2@`bSRCBM-};Any;u9f08MP*f)xr}$vX9l
zmhXv6-WR=_H1EeO3Om5_oUZRVU5aZqk9!w=0I^pHYw8OvT3zY@5xMsh4{G^4Ojv2n
zbHpGUysJ&<y#Y@W2$8H%%5IxTKK|?ck(-6M9k$l*%Pl2PO5kQMD25|Gys-B7&E9i7
zpZJGE8n#W{n^Bo2ZYiN;jA%?-Eg!h|+PNf+Ddhz~^pJfPJ-O!fkIAgu54Q~rp;FyC
zsMekTa5&u1kTzcK%OfBX(E6b%H}4966O+P-6_h6X%X7s8nN3^C+O5ML@f_y0r-iJ2
zruk{dsn_QLbwEU_*<j{_oCYJE1pyY+ofr(ugB6`>w*LNGE@_mD0p#L6@zr~YGf>o>
zPBh_n(@n5H6y@1R{-88|3!~Qy6eUbfQc~cs5s}0?6C%REI@cdofmx5^YIwKf6`%LI
z$x=60t6(4ggSxH|ZFwiN`TeUl5QkdY!N(-)vFkc0Hs%<%JS;5S_aj*E_robAy=_W{
z-{KJ~xh7v<dZIha?HMlgwXxH+!MW#CB(D!4yKCtDl2Nf>o<zS@fCA;OR*n)M=G10j
zZ42wRWn_^@n@L+&kqDk~IyHne*f2_un{Rwe^QlmZq-f=h4&bd!N`rq;GDGr>sxS_1
z9vJDsH1Y8;wVI*|#NB;MHoS(CWUSjb#CCmUN7ufEh<3=bG*2Me+<VHRrjKS9&C^P1
z%F1nnZI*^u*W{*1Ya&&z`|;jI3cGa>CPq9vNn9@Lp;*H1Sq)Gf+3R#?Ynts{{8JzM
z1(PdU%c~)Q^Y3ng?Me9j3cpShvrWUoo>I|ZZzm;gMW@RyEDF}#+)d`gwJ{C}BxQm6
zrj#ln8m4$yN`@tD%{E=yj(D{WdzGjExVxF_u}8=8l2u6nhjcnG+x*$M^a8<ozX?{9
zd+kHGR2l#NR#1^h_w#t)rd;Z$TzBtlUpZYz<w8F75<DgmBWQUL*hF1r8|4In%+Dk@
z0YJsTGIy7>7&;_>E#?`V_%+T6xD@(#j{!F9{R#Z{QnOzQUK6UV&Q(<7d#p#Rde@e$
zVEf>7X$Csb*H0hIuX<?;iv$9ttPOH#QO<FcwZCl}L066M^M`Sr#lSZKPQ?3mM33~<
zJHHKQCX{^b)l@s|ULPiDnIYfQoJOb_yDac#{fUb!Q1X3FRDGi<Q;{wWvh|{3UBUQh
ziA5gYV^jj1AyqV#ft)b$pQ5Oz2C8|*>C*p+<|})q`z>*MZ$T6U$2Y(C6Gy%x3`i61
zcM^>e9bjDEhzjb?MdkLcx{l9c3ClP~h-@wiqF_*gKsK+fhptyUhq|~TO{Iv}AZqIB
zVxLeWwj5ci6_q|WlNjEO$f43uxw&`+daAFXT(nc=>-wHP#Ur7M3GXq~S)CcM*#)fO
zR)6Qz;wkATqBE1KLjis}FBbT(-|+OG!e}uxZxsjnKb73Cu(Xn|!^jAVu0DGwED0=G
z!=(0aB~!Xc9^_8X#HY_zi@U)XOC(*E7HuO&Xad$Az*)+at~t!yXBh<CgS$P!4G<=e
zDGb}k4z)W|jXZ{5CvtL}$CX~f@@5uhjx&==e^^1es!U7)j=8SwHFy~eDoD#OmomVp
zgmN`l%rFq`k$HIxyAr?aEn=}E+g#=zY%&(v&>3-b-}yIpafkQsV&Rb8y#F{0Jd2%e
zy(Bsrvc(xaufPFyb6z&Eh2TaCo%o98yWg^LLBc}ja6jS5TMrTWA!?0&|E2SG&i`Vl
z4S(=2mccjnMQAK)M8KIC7`dG4kZbjy6>`|t;<biSoB7p`-~)mqmv_@1K}7K3u<Jsl
zGKMfxj82ek*WyhOG%`irir8vG$HSmgkEBqq!o)t6DvGBxNuYGh{WIXcHJ%drQ{6)q
z4!Qw4L|12l2E~ke%Y0?K`WFv;J92QyVk^m8Tcr_Nh<P4i>z3z+O0~H^F+h;ay0##c
zb2MPWz({_h>pHRV$z!^=;U)Tj3j5W-t_$Ml6r{OMV}HcVXi5p4hY@zS@G9EScl|Ue
z|D+;9pQdBBdnYW5TQ~$54WRDv@&EfN%6-QJ=xIFgrF$TODmA*ha+9lSp;-_@t82~(
zbS>mEs=g7DOpsionlEn3^!nJ$spmg*f{c+nTnonQAnMH`4M^7?5T;=tqP*cX^SE})
zmfjchOk=Mg<#n^Ls&S=Jw$57(=Xb0N6A+S^@BI%Emr}F>xv#F}hj7hHFaNqis{wmS
z5b5@6E4&R!K-5DZty*ijS0HW;jQYr-6c{w7$xxnl_-UFOhv|)qhP=uX$~U&3kJA{z
z>`E;q+^+`1ZCu_Fl2VZW7gz<S`pwpQ>$Eh*a<7(}mBy4~(7{;Ib5o^atk>Eo&7$QL
zzlm+t2tZ1Mu?iKJn23rdBZH80w(DAHZ0_>g>~7bE;Dx4^v*@{LiyYtl!`1~ul7D4&
z@?mCUWYYk(<`^rYwpIgJStS`MgE9*o4hO;0<o((bq~+g`Z@S;#wC6cXr@87KZkMh+
zWU}Xx`B@fH-tT1UX`03ueLY^4Qcge@;$@m^tw!mG$H(jSI?q$B)j8*_GfI2w<n>5_
zthrRZx@Cf@#u(EYL<Ck;SH>TMq@bIo>EtIVr6^^Nr?<9k<+TKG+Mrcdp2&?wcu#<C
z8h;x|y}-8fJj>PrK^tRsyCwv&V4Q2Mvi?#iZ}++ijYH7P5aV1*3BfhNK0iM{KJ80p
zY4~c*r4$B21tA0(jJ&s^F3CBHmy1&1oM{?=%UNDen1t=FJVGwO%AnR7y%qoCGSA~Y
z|6rXTf>SD#Qe-~eW^K84w(Z>dUWFhBtCW&UGREw7ZP#@Sd77r-I@Mae7qS!FOhGg>
zt+&?7)MlNQR&=Wh(!zg;J-P?tq)KfyO#X_@ZVZ;elnh3zhyLOD`MK75Ih|M4o?eY5
zq+}wZSmxi@s<J(}8MfR~9`7R|pyU;41!IiS-ilr7Gzv;VO1Z8^VXa*2O78^56vH=}
z?U!XKnQlv2txycyQ7J@?f&~cXSxRB3+Mom~ixoRVG#1*{Ypsa{o93KzPNIdXr4TcR
z5Q25a=x*owZl@GTCBDzq-K0L!5zq5{GgpFp*OvQKB6$o-O-gI6v29yI5Ynu3-sn}t
zAk&rb6t+)LHqFB@NH1iqZJJj4wwuo2d%lF$##*h-N`pnkmBi#dF;r`9+lHoTV$8Kx
zvl&6j3zKiEwWbPUjjz?}vU1PwCZaV{jagRvamnAM`e>{{(NZ(Qmj5fm-Q{xm`t|EL
zj;mXj)>09r2a=BGo``&JK=mOM0|07G0P5x_QAJpbh{P%7Ii_fg2~Fp{XLhBO81-$p
zy+=e*6_4W(m$EhWvI$;sf33zeFUvv-AZQ{GVQtf_J7Xe{fSRo8t!G$ww}`Qn!mPAr
zMANoy-^svV$MG7|vK_3=2niJ!rEj?`eDj|s21Zo;-9c`(QX(b>0_1x;AbIAk^Uk@(
zhm9__`sb`OM;0Bu1nkHXMO>Lh?dP0DY^^nN&^2lKbhPnJ(>Q0uv|>AUqJj~;eZSwY
zHb%ynEf7|)N(4i+y4V<lLi9mIfsmwZ-e-N4B9gkgJy^zAtxc|Z^&KnabUF#a_xScM
zqyDCw*w{|@7E|}~tZfChC6>z(X8@(Z7+I1O;wZ9qahP?^T5Ch_lF~s$udh*XI5FR0
zt~tA$J<~c)ZyROdEuvH62FnaN7cn%;IeQ-jfs+SRKtd6edZ(<_02|koYOU7zrfHf+
zAkDO7sU3?zL^<nCyddqYxS5HKk90qxySi7W2>`3LfV8euNfKO5Y1_7K+tw&81E6eH
zq;74CosC-{&wQ=*d_KxpCgaWux#U$9kz>jcfDl{jR*Xq#IVF?)Ljpnk|KlI3QcE7y
z9RL6TIdnx>bW?9;ba!ELWdJ}ZBPmI3VP|DcVP|P$YalZ&I4&|EIX5pbGcPeUAY*cA
zb98w?WOZ<FZgehVZ*3KJ6$$_V04j7vSaefqXKrD1b#i3@Vlg&iGB!D6F*rFlVKXpc
zVKg*jGch=0H92K7WMO1CTcgL|0000jbVXQnLvL+uWo~o;ARtL?aBp&SWn>^`a&K)Q
oM^ZsVK~zakP9SM*VP|DJAZK!6c}+yRm;e9(07*qoM6N<$g7p#~%K!iX

literal 0
HcmV?d00001

diff --git a/user/wxTest/list.xpm b/user/wxTest/list.xpm
new file mode 100644
index 0000000000..b0162e2b07
--- /dev/null
+++ b/user/wxTest/list.xpm
@@ -0,0 +1,45 @@
+/* XPM */
+static char * list_xpm[] = {
+"32 32 10 1",
+" 	c #DF7DDF7DDF7D",
+".	c #9E799E79A699",
+"X	c #AEBAAEBAAEBA",
+"o	c #FFFFFFFFFFFF",
+"O	c #514451445144",
+"+	c #410341034103",
+"@	c #596559655965",
+"#	c #000000000000",
+"$	c #BEFBBEFBBEFB",
+"%	c #208120812081",
+"                                ",
+"                .               ",
+"               Xo..             ",
+"              Xoooo.X           ",
+"             Xooooooo.X         ",
+"            XooooO+ooooXX       ",
+"           XoooooooO+ooo..      ",
+"          XooooOOoooo@@ooo..    ",
+"         XoooooooOOooooooooo.X  ",
+"        Xoooo@Ooooo+@oooO+oooo.X",
+"       Xooooooo@OoooooooooO+oooo",
+"      XooooooooooO@oooOOoooo@@oo",
+"     XooooO+ooooooooooooOOoooooo",
+"    XoooooooO+oooooo@Ooooo+@oooX",
+"   XooooOOoooo@@oooooo@OooooooOX",
+"  XoooooooOOooooooooooooO@oooOX#",
+" Xoooo@Ooooo+@oooO+oooooooooOX#X",
+"Xooooooo@OoooooooooO+ooooooOX#XX",
+"O@$oooooooO@oooOOoooo@@oooOX#XX ",
+"X#+@$ooooooooooooOOooooooOX#XX  ",
+" XX#O@ooooooo@Ooooo+@oooOX#XX   ",
+"   XX#OXooooooo@OooooooOX#X     ",
+"     XXO@XoooooooO@oooOX#X      ",
+"      XX#%@XoooooooooOX#X       ",
+"        XX#%@XooooooOX#X        ",
+"          XX#%@XoooOX#X         ",
+"            XX#%@XOX#X          ",
+"              XX#+X#X           ",
+"                XXXX            ",
+"                                ",
+"                                ",
+"                                "};
diff --git a/user/wxTest/wxTest.cpp b/user/wxTest/wxTest.cpp
new file mode 100644
index 0000000000..c9d48c2045
--- /dev/null
+++ b/user/wxTest/wxTest.cpp
@@ -0,0 +1,594 @@
+/*
+ * Program: wxTest
+ * 
+ * Author: Robert Roebling
+ *
+ * Copyright: (C) 1997, GNU (Robert Roebling)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef __GNUG__
+#pragma implementation "wxTest.h"
+#endif
+
+#include "wxTest.h"
+
+#include "folder.xpm"
+#include "list.xpm"
+
+//-----------------------------------------------------------------------------
+// main program
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_APP(MyApp)
+
+//-----------------------------------------------------------------------------
+// MyDialog
+//-----------------------------------------------------------------------------
+
+const  ID_RETURN            = 100;
+const  ID_HELLO             = 101;
+
+const  ID_CHECKBOX          = 110;
+const  ID_CHECKBOX_CHECK    = 110;
+const  ID_CHECKBOX_UNCHECK  = 112;
+
+const  ID_TEXTCTRL          = 115;
+const  ID_TEXTCTRL_SET      = 116;
+const  ID_TEXTCTRL_DEL      = 117;
+
+const  ID_CHOICE            = 120;
+const  ID_CHOICE_SEL_NUM    = 121;
+const  ID_CHOICE_SEL_STR    = 122;
+const  ID_CHOICE_CLEAR      = 123;
+const  ID_CHOICE_APPEND     = 124;
+
+const  ID_LISTBOX           = 130;
+const  ID_LISTBOX_SEL_NUM   = 131;
+const  ID_LISTBOX_SEL_STR   = 132;
+const  ID_LISTBOX_CLEAR     = 133;
+const  ID_LISTBOX_APPEND    = 134;
+
+const  ID_RADIOBOX          = 130;
+const  ID_RADIOBOX_SEL_NUM  = 131;
+const  ID_RADIOBOX_SEL_STR  = 132;
+
+BEGIN_EVENT_TABLE(MyDialog,wxDialog)
+  EVT_BUTTON    (ID_RETURN,             MyDialog::OnReturnButton)
+  EVT_BUTTON    (ID_HELLO,              MyDialog::OnHelloButton)
+  EVT_CHECKBOX  (ID_CHECKBOX,           MyDialog::OnCheckBox)
+  EVT_BUTTON    (ID_CHECKBOX_CHECK,     MyDialog::OnCheckBoxButtons)
+  EVT_BUTTON    (ID_CHECKBOX_UNCHECK,   MyDialog::OnCheckBoxButtons)
+  EVT_TEXT      (ID_TEXTCTRL,           MyDialog::OnTextCtrl)
+  EVT_BUTTON    (ID_TEXTCTRL_SET,       MyDialog::OnTextCtrlButtons)
+  EVT_BUTTON    (ID_TEXTCTRL_DEL,       MyDialog::OnTextCtrlButtons)
+  EVT_CHOICE    (ID_CHOICE,             MyDialog::OnChoice)
+  EVT_BUTTON    (ID_CHOICE_SEL_NUM,     MyDialog::OnChoiceButtons)
+  EVT_BUTTON    (ID_CHOICE_SEL_STR,     MyDialog::OnChoiceButtons)
+  EVT_BUTTON    (ID_CHOICE_CLEAR,       MyDialog::OnChoiceButtons)
+  EVT_BUTTON    (ID_CHOICE_APPEND,      MyDialog::OnChoiceButtons)
+  EVT_LISTBOX   (ID_LISTBOX,            MyDialog::OnListBox)
+  EVT_BUTTON    (ID_LISTBOX_SEL_NUM,    MyDialog::OnListBoxButtons)
+  EVT_BUTTON    (ID_LISTBOX_SEL_STR,    MyDialog::OnListBoxButtons)
+  EVT_BUTTON    (ID_LISTBOX_CLEAR,      MyDialog::OnListBoxButtons)
+  EVT_BUTTON    (ID_LISTBOX_APPEND,     MyDialog::OnListBoxButtons)
+  EVT_RADIOBOX  (ID_RADIOBOX,           MyDialog::OnRadioBox)
+  EVT_BUTTON    (ID_RADIOBOX_SEL_NUM,   MyDialog::OnRadioBoxButtons)
+  EVT_BUTTON    (ID_RADIOBOX_SEL_STR,   MyDialog::OnRadioBoxButtons)
+END_EVENT_TABLE()
+
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(MyDialog, wxDialog)
+
+MyDialog::MyDialog( wxWindow *parent ) :
+  wxDialog( parent, -1, "TestDialog", wxPoint(20,100), wxSize(700,400), wxDIALOG_MODAL )
+{
+  m_text1 = NULL;
+  m_text2 = NULL;
+
+  (void)new wxStaticBox( this, -1, "CheckBox group", wxPoint(20,10), wxSize(140,180) );
+  m_checkbox = new wxCheckBox( this, ID_CHECKBOX, "CheckBox", wxPoint(40,35), wxSize(100,30) );
+  (void)new wxButton( this, ID_CHECKBOX_CHECK, "Check", wxPoint(40,85), wxSize(100,30) );
+  (void)new wxButton( this, ID_CHECKBOX_UNCHECK, "Uncheck", wxPoint(40,135), wxSize(100,30) );
+  
+  (void)new wxStaticBox( this, -1, "TextCtrl group", wxPoint(20,200), wxSize(140,180) );
+  m_textctrl = new wxTextCtrl( this, ID_TEXTCTRL, "TextCtrl", wxPoint(40,35+190), wxSize(100,30) );
+  (void)new wxButton( this, ID_TEXTCTRL_SET, "Set 'Hi!'", wxPoint(40,85+190), wxSize(100,30) );
+  (void)new wxButton( this, ID_TEXTCTRL_DEL, "Delete", wxPoint(40,135+190), wxSize(100,30) );
+  
+  wxString choices[4] =
+  {
+    "This",
+    "is",
+    "a",
+    "wonderfull example."
+  };
+  
+  (void)new wxStaticBox( this, -1, "Choice group", wxPoint(180,10), wxSize(140,330) );
+  m_choice = new wxChoice( this, ID_CHOICE, wxPoint(200,35), wxSize(100,30), 4, choices );
+  (void)new wxButton( this, ID_CHOICE_SEL_NUM, "Select #2", wxPoint(200,130), wxSize(100,30) );
+  (void)new wxButton( this, ID_CHOICE_SEL_STR, "Select 'This'", wxPoint(200,180), wxSize(100,30) );
+  (void)new wxButton( this, ID_CHOICE_CLEAR, "Clear", wxPoint(200,230), wxSize(100,30) );
+  (void)new wxButton( this, ID_CHOICE_APPEND, "Append 'Hi!'", wxPoint(200,280), wxSize(100,30) );
+
+  (void)new wxStaticBox( this, 100, "ListBox group", wxPoint(340,10), wxSize(140,330) );
+  m_listbox = new wxListBox( this, ID_LISTBOX, wxPoint(360,35), wxSize(100,70), 4, choices );
+  (void)new wxButton( this, ID_LISTBOX_SEL_NUM, "Select #2", wxPoint(360,130), wxSize(100,30) );
+  (void)new wxButton( this, ID_LISTBOX_SEL_STR, "Select 'This'", wxPoint(360,180), wxSize(100,30) );
+  (void)new wxButton( this, ID_LISTBOX_CLEAR, "Clear", wxPoint(360,230), wxSize(100,30) );
+  (void)new wxButton( this, ID_LISTBOX_APPEND, "Append 'Hi!'", wxPoint(360,280), wxSize(100,30) );
+      
+  (void)new wxStaticBox( this, -1, "RadioBox group", wxPoint(500,10), wxSize(180,230) );
+  m_radiobox = new wxRadioBox( this, ID_RADIOBOX, "Test", wxPoint(520,35), wxSize(-1,-1), 4, choices,
+    1, wxRA_VERTICAL );
+  
+  (void)new wxButton( this, ID_HELLO, "wxScreenDC", wxPoint(540,280), wxSize(120,40) );
+  (void)new wxButton( this, ID_RETURN, "Return", wxPoint(540,340), wxSize(120,40) );
+  
+  m_text1 = new wxStaticText( this, -1, "No event.", wxPoint(170,350), wxSize(300,-1) );
+  m_text2 = new wxStaticText( this, -1, "No information.", wxPoint(170,370), wxSize(300,-1) );
+  
+  InitDialog();
+};
+
+void MyDialog::OnTextCtrl( wxCommandEvent &WXUNUSED(event) )
+{
+};
+
+void MyDialog::OnTextCtrlButtons( wxCommandEvent &event )
+{
+  switch (event.GetId())
+  {
+    case ID_TEXTCTRL_SET:
+    {
+      m_textctrl->SetValue( "Hi!" );
+      break;
+    };
+    case ID_TEXTCTRL_DEL:
+    {
+      m_textctrl->Delete();
+      break;
+    };
+  };
+};
+
+void MyDialog::OnRadioBox( wxCommandEvent &event )
+{
+  if (!m_text1) return;
+  m_text1->SetLabel( "RadioBox Event:");
+  wxString tmp = "RadioBox selection string is: ";
+  tmp += event.GetString();
+  m_text2->SetLabel( tmp );
+};
+
+void MyDialog::OnRadioBoxButtons( wxCommandEvent &WXUNUSED(event) )
+{
+};
+    
+void MyDialog::OnListBox( wxCommandEvent &event )
+{
+  if (!m_text1) return;
+  m_text1->SetLabel( "ListBox Event:");
+  wxString tmp = "ListBox selection string is: ";
+  tmp += event.GetString();
+  m_text2->SetLabel( tmp );
+};
+
+void MyDialog::OnListBoxButtons( wxCommandEvent &event )
+{
+  switch (event.GetId())
+  {
+    case ID_LISTBOX_SEL_NUM:
+    {
+      m_listbox->SetSelection( 2 );
+      break;
+    };
+    case ID_LISTBOX_SEL_STR:
+    {
+      m_listbox->SetStringSelection( "This" );
+      break;
+    };
+    case ID_LISTBOX_CLEAR:
+    {
+      m_listbox->Clear();
+      break;
+    };
+    case ID_LISTBOX_APPEND:
+    {
+      m_listbox->Append( "Hi!" );
+      break;
+    };
+  };
+};
+
+void MyDialog::OnCheckBox( wxCommandEvent &event )
+{
+  if (!m_text1) return;
+  m_text1->SetLabel( "CheckBox Event:");
+  wxString tmp = "Checkbox is ";
+  if (event.Checked()) 
+    tmp += "checked.";
+  else
+    tmp += "unchecked.";
+  m_text2->SetLabel( tmp );
+};
+
+void MyDialog::OnCheckBoxButtons( wxCommandEvent &event )
+{
+  switch (event.GetId())
+  {
+    case ID_CHECKBOX_CHECK:
+    {
+      m_checkbox->SetValue( TRUE );
+      break;
+    };
+    case ID_CHECKBOX_UNCHECK:
+    {
+      m_checkbox->SetValue( FALSE );
+      break;
+    };
+  };
+};
+
+void MyDialog::OnChoice( wxCommandEvent &event )
+{
+  if (!m_text1) return;
+  m_text1->SetLabel( "Choice Event:");
+  wxString tmp = "Choice selection string is: ";
+  tmp += event.GetString();
+  m_text2->SetLabel( tmp );
+};
+
+void MyDialog::OnChoiceButtons( wxCommandEvent &event )
+{
+  switch (event.GetId())
+  {
+    case ID_CHOICE_SEL_NUM:
+    {
+      m_choice->SetSelection( 2 );
+      break;
+    };
+    case ID_CHOICE_SEL_STR:
+    {
+      m_choice->SetStringSelection( "This" );
+      break;
+    };
+    case ID_CHOICE_CLEAR:
+    {
+      m_choice->Clear();
+      break;
+    };
+    case ID_CHOICE_APPEND:
+    {
+      m_choice->Append( "Hi!" );
+      break;
+    };
+  };
+};
+
+void MyDialog::OnReturnButton( wxCommandEvent &WXUNUSED(event) )
+{
+  EndModal( 1 );
+};
+
+void MyDialog::OnHelloButton( wxCommandEvent &WXUNUSED(event) )
+{
+  wxMessageDialog *dialog;
+  dialog = new wxMessageDialog( this, "Now, I will paint on Screen.", "wxGTK" );
+  dialog->ShowModal();
+  delete dialog;
+  
+  wxScreenDC dc;
+  dc.StartDrawingOnTop();
+  
+  int w = wxSystemSettings::GetSystemMetric( wxSYS_SCREEN_X );
+  int h = wxSystemSettings::GetSystemMetric( wxSYS_SCREEN_Y );
+  
+  dc.SetPen( *wxWHITE_PEN );
+  dc.SetBrush( *wxTRANSPARENT_BRUSH );
+  for (int i = 0; i < h; i += 3) dc.DrawLine( 0, i, w, i );
+  
+  dialog = new wxMessageDialog( this, "Now, the stripes will disappear.", "wxGTK" );
+  dialog->ShowModal();
+  delete dialog;
+  
+  dc.EndDrawingOnTop();
+};
+
+//-----------------------------------------------------------------------------
+// MyCanvas
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(MyCanvas, wxScrolledWindow)
+
+BEGIN_EVENT_TABLE(MyCanvas,wxScrolledWindow)
+  EVT_BUTTON  (100,  MyDialog::OnReturnButton)
+  EVT_PAINT  (MyCanvas::OnPaint)
+END_EVENT_TABLE()
+
+MyCanvas::MyCanvas( wxWindow *parent, const wxWindowID id, const wxPoint &pos, const wxSize &size ) 
+  : wxScrolledWindow( parent, id, pos, size, wxSUNKEN_BORDER ) 
+{
+  my_bitmap = new wxBitmap( folder_xpm );
+  my_horse = new wxBitmap();
+  my_horse->LoadFile( "horse.png", 0 );
+  my_backstore = new wxBitmap( 150, 150 );
+  my_font = new wxFont( 20, wxROMAN, wxNORMAL, wxNORMAL );
+  m_isCreated = FALSE;
+  
+  SetBackgroundColour( wxColour("Wheat") );
+};
+
+MyCanvas::~MyCanvas(void)
+{
+  delete my_bitmap;
+  delete my_backstore;
+  delete my_horse;
+  delete my_font;
+};
+
+void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) )
+{
+  wxPaintDC dc( this );
+  PrepareDC( dc );
+
+  wxMemoryDC memDC;
+  memDC.SelectObject( *my_backstore );
+  memDC.SetBrush( *wxBLACK_BRUSH );
+  memDC.SetPen( *wxWHITE_PEN );
+  memDC.DrawRectangle( 0, 0, 150, 150 );
+  memDC.SetTextForeground( *wxWHITE );
+  memDC.DrawText( "This is a memory dc.", 10, 10 );
+  
+  int vx = 0;
+  int vy = 0;
+  GetVirtualSize( &vx, &vy );
+  dc.DrawLine( 5, 5, vx-10, vy-10 );
+  dc.DrawLine( 10, 20, 100, 10 );
+  dc.DrawLine( 10, 20, 100, 50 );
+  dc.DrawLine( 10, 20, 100, 100 );
+  
+  dc.SetPen( *wxWHITE_PEN );
+  dc.DrawLine( 80, 50, 180, 50 );
+
+  dc.SetFont( *my_font );
+  
+  long x = 0;
+  long y = 0;
+  dc.GetTextExtent( "Hej, ho, hej, ho.", &x, &y );
+  
+  dc.SetBrush( *wxTRANSPARENT_BRUSH );
+  dc.DrawRectangle( 80, 40, x, y );
+  
+  dc.SetTextForeground( *wxGREEN );
+  dc.DrawText( "Hej, ho, hej, ho.", 80, 40 );
+  
+  dc.SetTextForeground( *wxBLACK );
+  dc.SetFont( *wxNORMAL_FONT );
+  dc.DrawText( "Hej, ho, hej, ho. (NormalFont)", 80, 60 );
+  dc.SetFont( *wxSMALL_FONT );
+  dc.DrawText( "Hej, ho, hej, ho. (SmallFont)", 80, 80 );
+  dc.SetFont( *wxITALIC_FONT );
+  dc.DrawText( "Hej, ho, hej, ho. (ItalicFont)", 80, 100 );
+  
+  dc.DrawBitmap( *my_bitmap, 30, 80, TRUE );
+  dc.DrawBitmap( *my_horse, 30, 120 );
+  
+  dc.Blit( 200, 200, 150, 150, &memDC, 0, 0, 0 );
+  
+  memDC.SelectObject( wxNullBitmap );
+  
+/*
+  dc.SetBrush( *wxBLACK_BRUSH );
+  dc.DrawRectangle( 50, 50, 50, 50 );
+  dc.SetPen( *wxWHITE_PEN );
+  dc.DrawRectangle( 101, 50, 50, 50 );
+  dc.DrawRectangle( 50, 101, 50, 50 );
+  
+  dc.SetBrush( *wxWHITE_BRUSH );
+  
+  dc.SetPen( *wxWHITE_PEN );
+  dc.DrawRectangle( 70, 70, 2, 2 );
+  
+  dc.SetPen( *wxRED_PEN );
+  dc.DrawRectangle( 72, 70, 2, 2 );
+  dc.DrawRectangle( 70, 72, 2, 2 );
+  
+  
+  dc.SetPen( *wxRED_PEN );
+  dc.DrawRectangle( 82, 80, 2, 2 );
+  dc.DrawRectangle( 80, 82, 2, 2 );
+  
+  dc.SetPen( *wxWHITE_PEN );
+  dc.DrawRectangle( 80, 80, 2, 2 );
+*/
+};
+
+//-----------------------------------------------------------------------------
+// MyFrame
+//-----------------------------------------------------------------------------
+
+const  ID_OPEN  = 101;
+const  ID_SAVE  = 102;
+const  ID_MSG   = 103;
+const  ID_FONT  = 104;
+const  ID_DLG   = 105;
+const  ID_QUIT  = 108;
+const  ID_ABOUT = 109;
+
+IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame )
+
+BEGIN_EVENT_TABLE(MyFrame,wxFrame)
+  EVT_SIZE    (MyFrame::OnSize)
+  EVT_MENU    (ID_OPEN,  MyFrame::OnOpenDialog)
+  EVT_MENU    (ID_FONT,  MyFrame::OnFontDialog)
+  EVT_MENU    (ID_MSG,   MyFrame::OnMsg)
+  EVT_MENU    (ID_DLG,   MyFrame::OnDialog)
+  EVT_MENU    (ID_ABOUT, MyFrame::OnAbout)
+  EVT_MENU    (ID_QUIT,  MyFrame::OnQuit)
+END_EVENT_TABLE()
+
+MyFrame::MyFrame(void) :
+  wxFrame( NULL, -1, "Robert's Test application", wxPoint(20,20), wxSize(470,360) )
+{
+  wxMenu *file_menu = new wxMenu( "Test" );
+  file_menu->Append( ID_OPEN, "Open..");
+  file_menu->Append( ID_MSG,  "MessageBox..");
+  file_menu->Append( ID_FONT, "FontDialog..");
+  file_menu->AppendSeparator();
+  file_menu->Append( ID_DLG,  "TestDialog..");
+  file_menu->AppendSeparator();
+  file_menu->Append( ID_ABOUT, "About..");
+  file_menu->Append( ID_QUIT, "Exit");
+  
+  wxMenuBar *menu_bar = new wxMenuBar();
+  menu_bar->Append(file_menu, "File");
+  menu_bar->Show( TRUE );
+  
+  SetMenuBar( menu_bar );
+  
+  CreateStatusBar( 2 );
+  
+  SetStatusText( "wxGTK v0.12", 0 );
+  SetStatusText( "Copyright 1998 Robert Roebling.", 1 );
+  
+  m_canvas = new MyCanvas( this, -1, wxPoint(2,62), wxSize(300-4,120-4) );
+  m_canvas->SetScrollbars( 10, 10, 50, 50 );
+  
+  m_tb = new wxToolBarGTK( this, -1, wxPoint(2,60), wxSize(300-4,26) );
+  m_tb->SetMargins( 2, 2 );
+  
+  wxBitmap *bm = new wxBitmap( list_xpm );
+  m_tb->AddTool( 0, *bm, wxNullBitmap, FALSE, -1, -1, NULL, "This is a button" );
+  bm = new wxBitmap( folder_xpm );
+  m_tb->AddTool( 0, *bm, wxNullBitmap, TRUE, -1, -1, NULL, "This is a toggle" );
+  
+  m_tb->Layout();
+  m_tb->Show( TRUE );
+  
+//  m_timer.Start( 1000, TRUE );
+};
+
+void MyFrame::OnSize( wxSizeEvent &WXUNUSED(event) )
+{
+  int x = 0;
+  int y = 0;
+  GetClientSize( &x, &y );
+  
+  m_tb->SetSize( 1, 0, x-2, 42 );
+  m_canvas-> SetSize( 0, 42, x, y-42 ); 
+};
+
+void MyFrame::OnDialog( wxCommandEvent &WXUNUSED(event) )
+{
+  MyDialog dialog( this );
+  dialog.ShowModal();
+};
+
+void MyFrame::OnFontDialog( wxCommandEvent &WXUNUSED(event) )
+{
+  wxFontData data;
+  data.SetInitialFont( wxSMALL_FONT );
+  data.SetColour( wxRED );
+  wxGenericFontDialog dialog( this, &data );
+  if (dialog.ShowModal() == wxID_OK)
+  {
+    wxFontData retData = dialog.GetFontData();
+    // do something
+  };
+};
+
+void MyFrame::OnOpenDialog( wxCommandEvent &WXUNUSED(event) )
+{
+  wxFileDialog dialog(this, "Testing open file dialog", "", "", "*.txt", 0);
+  if (dialog.ShowModal() == wxID_OK)
+  {
+    wxMessageDialog dialog2(this, dialog.GetPath(), "Selected path");
+    dialog2.ShowModal();
+  };
+};
+
+void MyFrame::OnMsg( wxCommandEvent &WXUNUSED(event) )
+{
+  wxMessageBox( "There once was a lady from Riga.", "TestBox.", wxYES_NO );
+};
+
+void MyFrame::OnQuit( wxCommandEvent &WXUNUSED(event) )
+{
+  Close( TRUE );
+};
+
+void MyFrame::OnAbout( wxCommandEvent &WXUNUSED(event) )
+{
+  wxDialog dialog( this, -1, "About wxGTK", wxPoint(100,100), wxSize(540,350), wxDIALOG_MODAL );
+  
+  int w = 0;
+  int h = 0;
+  dialog.GetSize( &w, &h );
+
+  int x = 30;
+  int y = 20;
+  int step = 20;
+
+  (void)new wxStaticBox( &dialog, -1, (const char*)NULL, wxPoint(10,10), wxSize(w-20,h-80) );
+  
+  (void)new wxStaticText( &dialog, -1, "wxGTK v0.12", wxPoint(240,y) );
+  y += 2*step-10;
+  
+  (void)new wxStaticText( &dialog, -1, "Written by Robert Roebling, 1998. More information at:", wxPoint(x,y) );
+  y += step;
+  (void)new wxStaticText( &dialog, -1, "http://www.freiburg.linux.de/~wxxt", wxPoint(x+50,y) );
+  y += 2*step;
+  
+  (void)new wxStaticText( &dialog, -1, 
+    "wxGTK is based on the wxWindows GUI-library written mainly by Julian Smart. See:", wxPoint(x,y) );
+  y += step;
+  (void)new wxStaticText( &dialog, -1, "http://web.ukonline.co.uk/julian.smart/wxwin", wxPoint(x+50,y) );
+  y += 2*step;
+
+  (void)new wxStaticText( &dialog, -1, "wxWindows Copyright: Less restrictive version of LGPL.", wxPoint(x,y) );
+  y += 2*step;
+  (void)new wxStaticText( &dialog, -1, "For questions concerning wxGTK, you may mail to:", wxPoint(x,y) );
+  y += step;
+  (void)new wxStaticText( &dialog, -1, "roebling@ruf.uni-freiburg.de", wxPoint(x+50,y) );
+  
+  (void) new wxButton( &dialog, wxID_OK, "Return", wxPoint(w/2-40,h-50), wxSize(80,30) );
+  
+  dialog.ShowModal();
+};
+
+//-----------------------------------------------------------------------------
+// MyApp
+//-----------------------------------------------------------------------------
+
+MyApp::MyApp(void) : 
+  wxApp( )
+{
+};
+
+bool MyApp::OnInit(void)
+{
+  wxFrame *frame = new MyFrame();
+  frame->Show( TRUE );
+  
+  return TRUE;
+};
+
+
+
+
+
diff --git a/user/wxTest/wxTest.h b/user/wxTest/wxTest.h
new file mode 100644
index 0000000000..125e2f8ecf
--- /dev/null
+++ b/user/wxTest/wxTest.h
@@ -0,0 +1,164 @@
+/*
+ * Program: wxTest
+ * 
+ * Author: Robert Roebling
+ *
+ * Copyright: (C) 1997, GNU (Robert Roebling)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __TESTH__
+#define __TESTH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/wx.h"
+#include "wx/dcscreen.h"
+#include "wx/splitter.h"
+#include "wx/toolbar.h"
+#include "wx/fontdlg.h"
+
+//-----------------------------------------------------------------------------
+// derived classes
+//-----------------------------------------------------------------------------
+
+class MyDialog;
+class MyFrame;
+class MyApp;
+
+//-----------------------------------------------------------------------------
+// MyTimer
+//-----------------------------------------------------------------------------
+
+class MyTimer: public wxTimer
+{
+  public:
+  
+    MyTimer(void) {};
+    void Notify(void)
+    {
+      printf( "OnTimer.\n" );
+    };
+};
+
+//-----------------------------------------------------------------------------
+// MyDialog
+//-----------------------------------------------------------------------------
+
+class MyDialog: public wxDialog
+{
+  DECLARE_DYNAMIC_CLASS(MyDialog)
+  
+  public:
+  
+    MyDialog(void) {};
+    MyDialog( wxWindow *parent );
+    
+    void OnReturnButton( wxCommandEvent &event );
+    void OnHelloButton( wxCommandEvent &event );
+    
+    void OnCheckBox( wxCommandEvent &event );
+    void OnCheckBoxButtons( wxCommandEvent &event );
+    
+    void OnTextCtrl( wxCommandEvent &event );
+    void OnTextCtrlButtons( wxCommandEvent &event );
+    
+    void OnChoice( wxCommandEvent &event );
+    void OnChoiceButtons( wxCommandEvent &event );
+    
+    void OnListBox( wxCommandEvent &event );
+    void OnListBoxButtons( wxCommandEvent &event );
+    
+    void OnRadioBox( wxCommandEvent &event );
+    void OnRadioBoxButtons( wxCommandEvent &event );
+    
+    wxCheckBox    *m_checkbox;
+    wxTextCtrl    *m_textctrl;
+    wxChoice      *m_choice;
+    wxListBox     *m_listbox;
+    wxRadioBox    *m_radiobox;
+    wxStaticText  *m_text1;
+    wxStaticText  *m_text2;
+
+  DECLARE_EVENT_TABLE()
+};
+
+//-----------------------------------------------------------------------------
+// MyCanvas
+//-----------------------------------------------------------------------------
+
+class MyCanvas: public wxScrolledWindow
+{
+  DECLARE_DYNAMIC_CLASS(MyCanvas)
+  
+  public:
+  
+    MyCanvas(void) {};
+    MyCanvas( wxWindow *parent, wxWindowID, const wxPoint &pos, const wxSize &size );
+    ~MyCanvas(void);
+    void OnPaint( wxPaintEvent &event );
+    
+    wxBitmap  *my_bitmap;
+    wxBitmap  *my_horse;
+    wxBitmap  *my_backstore;
+    wxFont    *my_font;
+    bool       m_isCreated;
+    
+  DECLARE_EVENT_TABLE()
+};
+
+//-----------------------------------------------------------------------------
+// MyFrame
+//-----------------------------------------------------------------------------
+
+class MyFrame: public wxFrame
+{
+  DECLARE_DYNAMIC_CLASS(MyFrame)
+
+  public:
+  
+    MyFrame(void);
+    void OnSize( wxSizeEvent &event );
+    void OnOpenDialog( wxCommandEvent &event );
+    void OnFontDialog( wxCommandEvent &event );
+    void OnMsg( wxCommandEvent &event );
+    void OnDialog( wxCommandEvent &event );
+    void OnAbout( wxCommandEvent &event );
+    void OnQuit( wxCommandEvent &event );
+    
+    wxToolBarGTK     *m_tb;
+    MyCanvas         *m_canvas;
+    
+    MyTimer m_timer;
+    
+  DECLARE_EVENT_TABLE()
+};
+
+//-----------------------------------------------------------------------------
+// MyApp
+//-----------------------------------------------------------------------------
+
+class MyApp: public wxApp
+{
+  public:
+  
+    MyApp(void);
+    virtual bool OnInit(void);
+};
+
+#endif // wxGTK_h
diff --git a/utils/Makefile b/utils/Makefile
new file mode 100644
index 0000000000..58aefc246f
--- /dev/null
+++ b/utils/Makefile
@@ -0,0 +1 @@
+include ../src/gtk/setup/general/makedirs
-- 
2.50.0

